awacke1 commited on
Commit
32960ac
·
verified ·
1 Parent(s): ba8ed62

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +495 -18
index.html CHANGED
@@ -1,19 +1,496 @@
1
- <!doctype html>
2
  <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
  <html>
3
+ <head>
4
+ <title>SVG Transcript Time Series with Teleprompter</title>
5
+ <style>
6
+ body {
7
+ margin: 0;
8
+ padding: 20px;
9
+ font-family: Arial, sans-serif;
10
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
11
+ color: white;
12
+ overflow-x: hidden;
13
+ }
14
+
15
+ .container {
16
+ max-width: 1200px;
17
+ margin: 0 auto;
18
+ }
19
+
20
+ .teleprompter {
21
+ background: rgba(0,0,0,0.8);
22
+ border-radius: 15px;
23
+ padding: 30px;
24
+ margin-bottom: 30px;
25
+ backdrop-filter: blur(10px);
26
+ border: 2px solid rgba(255,255,255,0.1);
27
+ }
28
+
29
+ .teleprompter-text {
30
+ font-size: 24px;
31
+ line-height: 1.6;
32
+ text-align: center;
33
+ min-height: 120px;
34
+ display: flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ }
38
+
39
+ .timestamp {
40
+ color: #ff6b6b;
41
+ font-weight: bold;
42
+ font-size: 28px;
43
+ margin-bottom: 10px;
44
+ }
45
+
46
+ .current-text {
47
+ opacity: 1;
48
+ transition: opacity 0.5s ease;
49
+ }
50
+
51
+ .highlighted-word {
52
+ background: linear-gradient(45deg, #ff6b6b, #ffa500);
53
+ padding: 2px 6px;
54
+ border-radius: 4px;
55
+ animation: pulse 1s infinite;
56
+ }
57
+
58
+ @keyframes pulse {
59
+ 0%, 100% { transform: scale(1); }
60
+ 50% { transform: scale(1.05); }
61
+ }
62
+
63
+ .chart-container {
64
+ background: rgba(255,255,255,0.95);
65
+ border-radius: 15px;
66
+ padding: 30px;
67
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
68
+ }
69
+
70
+ .cluster-legend {
71
+ display: flex;
72
+ justify-content: center;
73
+ gap: 30px;
74
+ margin-bottom: 20px;
75
+ flex-wrap: wrap;
76
+ }
77
+
78
+ .legend-item {
79
+ display: flex;
80
+ align-items: center;
81
+ gap: 8px;
82
+ font-weight: bold;
83
+ color: #333;
84
+ }
85
+
86
+ .legend-color {
87
+ width: 20px;
88
+ height: 20px;
89
+ border-radius: 50%;
90
+ }
91
+
92
+ .controls {
93
+ text-align: center;
94
+ margin: 20px 0;
95
+ }
96
+
97
+ button {
98
+ background: linear-gradient(45deg, #667eea, #764ba2);
99
+ border: none;
100
+ color: white;
101
+ padding: 12px 24px;
102
+ margin: 0 10px;
103
+ border-radius: 25px;
104
+ cursor: pointer;
105
+ font-size: 16px;
106
+ transition: transform 0.2s;
107
+ }
108
+
109
+ button:hover {
110
+ transform: translateY(-2px);
111
+ }
112
+
113
+ button:disabled {
114
+ opacity: 0.5;
115
+ cursor: not-allowed;
116
+ transform: none;
117
+ }
118
+
119
+ .progress-bar {
120
+ width: 100%;
121
+ height: 6px;
122
+ background: rgba(255,255,255,0.3);
123
+ border-radius: 3px;
124
+ margin: 20px 0;
125
+ overflow: hidden;
126
+ }
127
+
128
+ .progress-fill {
129
+ height: 100%;
130
+ background: linear-gradient(90deg, #ff6b6b, #ffa500);
131
+ width: 0%;
132
+ transition: width 0.3s ease;
133
+ border-radius: 3px;
134
+ }
135
+ </style>
136
+ </head>
137
+ <body>
138
+ <div class="container">
139
+ <div class="teleprompter">
140
+ <div class="timestamp" id="timestamp">5:48</div>
141
+ <div class="teleprompter-text">
142
+ <div class="current-text" id="current-text">
143
+ It's a very good way of understanding how we communicate <span class="highlighted-word">linguistically</span>.
144
+ </div>
145
+ </div>
146
+ <div class="progress-bar">
147
+ <div class="progress-fill" id="progress-fill"></div>
148
+ </div>
149
+ </div>
150
+
151
+ <div class="controls">
152
+ <button onclick="togglePlayPause()" id="playButton">⏸️ Pause</button>
153
+ <button onclick="restart()">🔄 Restart</button>
154
+ <button onclick="changeSpeed(-0.5)">🐌 Slower</button>
155
+ <button onclick="changeSpeed(0.5)">🐰 Faster</button>
156
+ </div>
157
+
158
+ <div class="chart-container">
159
+ <div class="cluster-legend">
160
+ <div class="legend-item">
161
+ <div class="legend-color" style="background: #ff4757;"></div>
162
+ <span>👁️ Vision/Perception</span>
163
+ </div>
164
+ <div class="legend-item">
165
+ <div class="legend-color" style="background: #2ed573;"></div>
166
+ <span>💪 Action</span>
167
+ </div>
168
+ <div class="legend-item">
169
+ <div class="legend-color" style="background: #3742fa;"></div>
170
+ <span>🤔 Thought</span>
171
+ </div>
172
+ <div class="legend-item">
173
+ <div class="legend-color" style="background: #ffa502;"></div>
174
+ <span>🌍 Context</span>
175
+ </div>
176
+ </div>
177
+
178
+ <svg id="chart" width="100%" height="400" viewBox="0 0 800 400">
179
+ <!-- Background grid -->
180
+ <defs>
181
+ <pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
182
+ <path d="M 40 0 L 0 0 0 40" fill="none" stroke="#e0e0e0" stroke-width="1"/>
183
+ </pattern>
184
+
185
+ <!-- Gradients for lines -->
186
+ <linearGradient id="visionGradient" x1="0%" y1="0%" x2="100%" y2="0%">
187
+ <stop offset="0%" style="stop-color:#ff4757;stop-opacity:0.3" />
188
+ <stop offset="100%" style="stop-color:#ff4757;stop-opacity:1" />
189
+ </linearGradient>
190
+ <linearGradient id="actionGradient" x1="0%" y1="0%" x2="100%" y2="0%">
191
+ <stop offset="0%" style="stop-color:#2ed573;stop-opacity:0.3" />
192
+ <stop offset="100%" style="stop-color:#2ed573;stop-opacity:1" />
193
+ </linearGradient>
194
+ <linearGradient id="thoughtGradient" x1="0%" y1="0%" x2="100%" y2="0%">
195
+ <stop offset="0%" style="stop-color:#3742fa;stop-opacity:0.3" />
196
+ <stop offset="100%" style="stop-color:#3742fa;stop-opacity:1" />
197
+ </linearGradient>
198
+ <linearGradient id="contextGradient" x1="0%" y1="0%" x2="100%" y2="0%">
199
+ <stop offset="0%" style="stop-color:#ffa502;stop-opacity:0.3" />
200
+ <stop offset="100%" style="stop-color:#ffa502;stop-opacity:1" />
201
+ </linearGradient>
202
+ </defs>
203
+
204
+ <rect width="800" height="400" fill="url(#grid)" opacity="0.5"/>
205
+
206
+ <!-- Axes -->
207
+ <line x1="80" y1="50" x2="80" y2="350" stroke="#333" stroke-width="2"/>
208
+ <line x1="80" y1="350" x2="720" y2="350" stroke="#333" stroke-width="2"/>
209
+
210
+ <!-- Y-axis labels -->
211
+ <text x="70" y="350" text-anchor="end" font-size="12" fill="#666">0</text>
212
+ <text x="70" y="290" text-anchor="end" font-size="12" fill="#666">1</text>
213
+ <text x="70" y="230" text-anchor="end" font-size="12" fill="#666">2</text>
214
+ <text x="70" y="170" text-anchor="end" font-size="12" fill="#666">3</text>
215
+ <text x="70" y="110" text-anchor="end" font-size="12" fill="#666">4</text>
216
+ <text x="70" y="50" text-anchor="end" font-size="12" fill="#666">5</text>
217
+
218
+ <!-- Axis labels -->
219
+ <text x="400" y="390" text-anchor="middle" font-size="14" font-weight="bold" fill="#333">Time (MM:SS)</text>
220
+ <text x="30" y="200" text-anchor="middle" font-size="14" font-weight="bold" fill="#333" transform="rotate(-90 30 200)">Word Frequency</text>
221
+
222
+ <!-- Time markers will be added by JavaScript -->
223
+ <g id="time-markers"></g>
224
+
225
+ <!-- Chart lines -->
226
+ <g id="chart-lines"></g>
227
+
228
+ <!-- Peak labels -->
229
+ <g id="peak-labels"></g>
230
+
231
+ <!-- Current time indicator -->
232
+ <line id="time-indicator" x1="80" y1="50" x2="80" y2="350" stroke="#ff6b6b" stroke-width="3" opacity="0.8">
233
+ <animate attributeName="opacity" values="0.5;1;0.5" dur="2s" repeatCount="indefinite"/>
234
+ </line>
235
+ </svg>
236
+ </div>
237
+ </div>
238
+
239
+ <script>
240
+ // Transcript data with enhanced parsing
241
+ const transcriptData = [
242
+ { time: "5:48", seconds: 348, text: "It's a very good way of understanding how we communicate 🗣️linguistically🗣️." },
243
+ { time: "5:55", seconds: 355, text: "So if the words 🌊spring🌊 to the 👁️visual👁️, full 👁️visual👁️ 🌈complexity🌈 and then that can then 🌟transform🌟 itself into 💪action💪." },
244
+ { time: "6:02", seconds: 362, text: "Well those are both relevant and it's an important thing to understand because the classic empiricists make the 🤔presumption🤔," },
245
+ { time: "6:10", seconds: 370, text: "and it's an erroneous 🤔presumption🤔, that 👁️perception👁️ is a value free enterprise." },
246
+ { time: "6:16", seconds: 376, text: "And they 🌫️assume🌫️ that partly because they 🤔think🤔 of 👁️perception👁️ as something passive. You know, you just turn your head" },
247
+ { time: "6:21", seconds: 381, text: "and you 👀look👀 at the 🌍world🌍 and there it is. It's like 👁️perception👁️ is not passive. There is no 👁️perception👁️ without 💪action💪, ever, ever." },
248
+ { time: "6:29", seconds: 389, text: "And that's a weird thing to understand because even when you're 👀looking👀 at something like your 👁️eyes👁️ are moving back and forth, if they ever stop moving" },
249
+ { time: "6:35", seconds: 395, text: "for a 10th of a second, you stop being able to 👀see👀. So your 👁️eyes👁️ are jiggling back and forth, just to keep them active." },
250
+ { time: "6:41", seconds: 401, text: "And then there's involuntary movements of your 👁️eyes👁️, and then there's voluntary movements of your 👁️eyes👁️. Like what you're doing with your 👁️eyes👁️ is very much like" },
251
+ { time: "6:48", seconds: 408, text: "what a blind person would do if they were feeling out the contours of a object. You're 🌟sampling🌟 and you're only 🌟sampling🌟" },
252
+ { time: "6:56", seconds: 416, text: "a small element of the space that's in front of you. And the element that you 🌟choose🌟" },
253
+ { time: "7:01", seconds: 421, text: "to 🌟sample🌟 is dependent on your 🎯aims🎯 and your 🎯goals🎯. So it's value saturated. And so all your 👁️perceptions👁️ are 💪action💪 predicated." },
254
+ { time: "7:09", seconds: 429, text: "And partly what you're doing when you're 🗣️communicating🗣️ is therefore not only changing people's 💪actions💪, let's say, but you're also changing the strategy" },
255
+ { time: "7:18", seconds: 438, text: "that they use to 👁️perceive👁️. And so you change the way the 🌍world🌍 reveals itself for them. See, this is why it's such a profound experience" },
256
+ { time: "7:25", seconds: 445, text: "to read a particularly deep 🤔thinker🤔 because you could also 🤔think🤔 of your 👁️perceptions👁️" },
257
+ { time: "7:30", seconds: 450, text: "as the axioms of your 🤔thought🤔. That's a good way of 🤔thinking🤔 about it. A 👁️perception👁️ is like a, what would you say?" },
258
+ { time: "7:36", seconds: 456, text: "It's a 🤔thought🤔 that's so set in concrete that you now 👀see👀 it rather than conceptualize it." },
259
+ { time: "7:42", seconds: 462, text: "A really profound 🤔thinker🤔 changes the way you 👁️perceive👁️ the 🌍world🌍. That's way deeper than just how you 🤔think🤔 about it" },
260
+ { time: "7:47", seconds: 467, text: "or how you feel about it. What about not just profound 🤔thinkers🤔, but 🤔thinkers🤔 that deliver a powerful 💡idea💡?" }
261
+ ];
262
+
263
+ // Enhanced word extraction from emoji-marked text
264
+ function extractWords(text) {
265
+ const emojiPatterns = {
266
+ vision: /👁️([^👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]+)👁️/g,
267
+ action: /💪([^👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]+)💪/g,
268
+ thought: /🤔([^👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]+)🤔/g,
269
+ context: /(?:🗣️([^👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]+)🗣️|🌊([^👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]+)🌊|🌈([^👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]+)🌈|🌟([^👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]+)🌟|🎯([^👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]+)🎯|🌍([^👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]+)🌍|💡([^👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]+)💡|🌫️([^👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]+)🌫️|👀([^👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]+)👀)/g
270
+ };
271
+
272
+ const words = { vision: [], action: [], thought: [], context: [] };
273
+
274
+ Object.keys(emojiPatterns).forEach(category => {
275
+ let match;
276
+ while ((match = emojiPatterns[category].exec(text)) !== null) {
277
+ const word = match.slice(1).filter(Boolean)[0];
278
+ if (word) {
279
+ words[category].push(word.trim());
280
+ }
281
+ }
282
+ });
283
+
284
+ return words;
285
+ }
286
+
287
+ // Process transcript data
288
+ const processedData = transcriptData.map(entry => {
289
+ const words = extractWords(entry.text);
290
+ return {
291
+ ...entry,
292
+ words,
293
+ wordCounts: {
294
+ vision: words.vision.length,
295
+ action: words.action.length,
296
+ thought: words.thought.length,
297
+ context: words.context.length
298
+ }
299
+ };
300
+ });
301
+
302
+ // Create time series data
303
+ const timePoints = processedData.map(d => d.seconds);
304
+ const minTime = Math.min(...timePoints);
305
+ const maxTime = Math.max(...timePoints);
306
+
307
+ // Chart configuration
308
+ const chartWidth = 640;
309
+ const chartHeight = 300;
310
+ const chartLeft = 80;
311
+ const chartTop = 50;
312
+
313
+ const colors = {
314
+ vision: '#ff4757',
315
+ action: '#2ed573',
316
+ thought: '#3742fa',
317
+ context: '#ffa502'
318
+ };
319
+
320
+ // Animation state
321
+ let currentIndex = 0;
322
+ let isPlaying = true;
323
+ let animationSpeed = 1.0;
324
+ let animationTimer;
325
+
326
+ function timeToX(seconds) {
327
+ return chartLeft + ((seconds - minTime) / (maxTime - minTime)) * chartWidth;
328
+ }
329
+
330
+ function countToY(count) {
331
+ return chartTop + chartHeight - (count * 60); // Scale factor of 60 pixels per count
332
+ }
333
+
334
+ function createTimeSeries() {
335
+ const svg = document.getElementById('chart');
336
+ const timeMarkers = document.getElementById('time-markers');
337
+ const chartLines = document.getElementById('chart-lines');
338
+ const peakLabels = document.getElementById('peak-labels');
339
+
340
+ // Add time markers
341
+ processedData.forEach((entry, index) => {
342
+ if (index % 3 === 0) { // Show every 3rd timestamp to avoid crowding
343
+ const x = timeToX(entry.seconds);
344
+
345
+ // Tick mark
346
+ const tick = document.createElementNS('http://www.w3.org/2000/svg', 'line');
347
+ tick.setAttribute('x1', x);
348
+ tick.setAttribute('y1', chartTop + chartHeight);
349
+ tick.setAttribute('x2', x);
350
+ tick.setAttribute('y2', chartTop + chartHeight + 5);
351
+ tick.setAttribute('stroke', '#666');
352
+ tick.setAttribute('stroke-width', '1');
353
+ timeMarkers.appendChild(tick);
354
+
355
+ // Label
356
+ const label = document.createElementNS('http://www.w3.org/2000/svg', 'text');
357
+ label.setAttribute('x', x);
358
+ label.setAttribute('y', chartTop + chartHeight + 20);
359
+ label.setAttribute('text-anchor', 'middle');
360
+ label.setAttribute('font-size', '10');
361
+ label.setAttribute('fill', '#666');
362
+ label.textContent = entry.time;
363
+ timeMarkers.appendChild(label);
364
+ }
365
+ });
366
+
367
+ // Create lines for each category
368
+ Object.keys(colors).forEach(category => {
369
+ const line = document.createElementNS('http://www.w3.org/2000/svg', 'polyline');
370
+ line.setAttribute('fill', 'none');
371
+ line.setAttribute('stroke', colors[category]);
372
+ line.setAttribute('stroke-width', '3');
373
+ line.setAttribute('stroke-linecap', 'round');
374
+ line.setAttribute('stroke-linejoin', 'round');
375
+ line.setAttribute('id', `line-${category}`);
376
+ line.style.filter = 'drop-shadow(2px 2px 4px rgba(0,0,0,0.3))';
377
+ chartLines.appendChild(line);
378
+
379
+ // Area under curve
380
+ const area = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
381
+ area.setAttribute('fill', `url(#${category}Gradient)`);
382
+ area.setAttribute('opacity', '0.3');
383
+ area.setAttribute('id', `area-${category}`);
384
+ chartLines.insertBefore(area, line);
385
+ });
386
+ }
387
+
388
+ function updateChart() {
389
+ if (currentIndex >= processedData.length) return;
390
+
391
+ const currentData = processedData.slice(0, currentIndex + 1);
392
+
393
+ Object.keys(colors).forEach(category => {
394
+ const line = document.getElementById(`line-${category}`);
395
+ const area = document.getElementById(`area-${category}`);
396
+
397
+ const points = currentData.map(d => `${timeToX(d.seconds)},${countToY(d.wordCounts[category])}`).join(' ');
398
+ line.setAttribute('points', points);
399
+
400
+ // Create area points
401
+ if (currentData.length > 0) {
402
+ const areaPoints = [];
403
+ areaPoints.push(`${timeToX(currentData[0].seconds)},${chartTop + chartHeight}`);
404
+ currentData.forEach(d => {
405
+ areaPoints.push(`${timeToX(d.seconds)},${countToY(d.wordCounts[category])}`);
406
+ });
407
+ areaPoints.push(`${timeToX(currentData[currentData.length - 1].seconds)},${chartTop + chartHeight}`);
408
+ area.setAttribute('points', areaPoints.join(' '));
409
+ }
410
+ });
411
+
412
+ // Update time indicator
413
+ const timeIndicator = document.getElementById('time-indicator');
414
+ const currentX = timeToX(processedData[currentIndex].seconds);
415
+ timeIndicator.setAttribute('x1', currentX);
416
+ timeIndicator.setAttribute('x2', currentX);
417
+ }
418
+
419
+ function updateTeleprompter() {
420
+ if (currentIndex >= processedData.length) return;
421
+
422
+ const current = processedData[currentIndex];
423
+ document.getElementById('timestamp').textContent = current.time;
424
+
425
+ // Highlight keywords in text
426
+ let highlightedText = current.text;
427
+
428
+ // Remove emojis and highlight the words that were between them
429
+ const allWords = [...current.words.vision, ...current.words.action, ...current.words.thought, ...current.words.context];
430
+
431
+ allWords.forEach(word => {
432
+ const regex = new RegExp(`\\b${word}\\b`, 'gi');
433
+ highlightedText = highlightedText.replace(regex, `<span class="highlighted-word">${word}</span>`);
434
+ });
435
+
436
+ // Remove emoji markers
437
+ highlightedText = highlightedText.replace(/[👁️🗣️💪🤔🌊🌈🌟🎯🌍💡🌫️👀]/g, '');
438
+
439
+ document.getElementById('current-text').innerHTML = highlightedText;
440
+
441
+ // Update progress bar
442
+ const progress = ((currentIndex + 1) / processedData.length) * 100;
443
+ document.getElementById('progress-fill').style.width = `${progress}%`;
444
+ }
445
+
446
+ function animate() {
447
+ if (!isPlaying) return;
448
+
449
+ updateChart();
450
+ updateTeleprompter();
451
+
452
+ currentIndex++;
453
+
454
+ if (currentIndex < processedData.length) {
455
+ animationTimer = setTimeout(animate, 2000 / animationSpeed); // 2 second intervals
456
+ } else {
457
+ document.getElementById('playButton').textContent = '🔄 Restart';
458
+ document.getElementById('playButton').onclick = restart;
459
+ }
460
+ }
461
+
462
+ function togglePlayPause() {
463
+ isPlaying = !isPlaying;
464
+ const button = document.getElementById('playButton');
465
+
466
+ if (isPlaying) {
467
+ button.textContent = '⏸️ Pause';
468
+ if (currentIndex < processedData.length) {
469
+ animate();
470
+ }
471
+ } else {
472
+ button.textContent = '▶️ Play';
473
+ clearTimeout(animationTimer);
474
+ }
475
+ }
476
+
477
+ function restart() {
478
+ currentIndex = 0;
479
+ isPlaying = true;
480
+ clearTimeout(animationTimer);
481
+ document.getElementById('playButton').textContent = '⏸️ Pause';
482
+ document.getElementById('playButton').onclick = togglePlayPause;
483
+ animate();
484
+ }
485
+
486
+ function changeSpeed(delta) {
487
+ animationSpeed = Math.max(0.5, Math.min(3.0, animationSpeed + delta));
488
+ }
489
+
490
+ // Initialize
491
+ createTimeSeries();
492
+ animate();
493
+
494
+ </script>
495
+ </body>
496
+ </html>