andreaschandra commited on
Commit
78ba5af
·
verified ·
1 Parent(s): b13d89c

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +6 -4
  2. index.html +361 -19
  3. prompts.txt +1 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Type Racer
3
- emoji: 😻
4
  colorFrom: green
5
- colorTo: yellow
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: type-racer
3
+ emoji: 🐳
4
  colorFrom: green
5
+ colorTo: green
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,361 @@
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 lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Typing Speed Test</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .typing-text {
11
+ background-color: rgba(243, 244, 246, 0.5);
12
+ border-radius: 0.5rem;
13
+ padding: 1.5rem;
14
+ font-size: 1.25rem;
15
+ line-height: 1.75rem;
16
+ min-height: 150px;
17
+ position: relative;
18
+ }
19
+ .typing-text span {
20
+ position: relative;
21
+ }
22
+ .typing-text span.active {
23
+ background-color: #3b82f6;
24
+ color: white;
25
+ border-radius: 0.25rem;
26
+ }
27
+ .typing-text span.correct {
28
+ color: #10b981;
29
+ }
30
+ .typing-text span.incorrect {
31
+ color: #ef4444;
32
+ text-decoration: underline;
33
+ }
34
+ .timer-progress {
35
+ height: 8px;
36
+ transition: width 0.1s linear;
37
+ }
38
+ .result-card {
39
+ transform: scale(0.95);
40
+ opacity: 0;
41
+ transition: all 0.3s ease-out;
42
+ }
43
+ .result-card.show {
44
+ transform: scale(1);
45
+ opacity: 1;
46
+ }
47
+ .typing-input {
48
+ opacity: 0;
49
+ position: absolute;
50
+ left: -9999px;
51
+ }
52
+ </style>
53
+ </head>
54
+ <body class="bg-gray-100 min-h-screen flex flex-col items-center justify-center p-4">
55
+ <div class="w-full max-w-3xl mx-auto">
56
+ <h1 class="text-4xl font-bold text-center text-blue-600 mb-2">
57
+ <i class="fas fa-keyboard mr-2"></i>Typing Speed Test
58
+ </h1>
59
+ <p class="text-center text-gray-600 mb-8">Test your typing speed in different time intervals</p>
60
+
61
+ <div class="bg-white rounded-xl shadow-lg p-6 mb-6">
62
+ <div class="flex flex-wrap justify-center gap-4 mb-6">
63
+ <button id="30s" class="time-btn px-6 py-2 rounded-full bg-blue-100 text-blue-600 font-medium hover:bg-blue-200 transition">
64
+ <i class="far fa-clock mr-2"></i>30 Seconds
65
+ </button>
66
+ <button id="45s" class="time-btn px-6 py-2 rounded-full bg-blue-100 text-blue-600 font-medium hover:bg-blue-200 transition">
67
+ <i class="far fa-clock mr-2"></i>45 Seconds
68
+ </button>
69
+ <button id="60s" class="time-btn px-6 py-2 rounded-full bg-blue-100 text-blue-600 font-medium hover:bg-blue-200 transition">
70
+ <i class="far fa-clock mr-2"></i>60 Seconds
71
+ </button>
72
+ </div>
73
+
74
+ <div class="mb-4 flex justify-between items-center">
75
+ <div class="text-gray-600">
76
+ <span id="timer" class="text-2xl font-bold text-blue-600">00:00</span>
77
+ </div>
78
+ <div class="text-gray-600">
79
+ <span id="wpm" class="text-2xl font-bold text-blue-600">0</span> WPM
80
+ </div>
81
+ </div>
82
+
83
+ <div class="timer-progress bg-gray-200 rounded-full mb-6">
84
+ <div id="progress-bar" class="bg-blue-500 rounded-full h-full" style="width: 100%"></div>
85
+ </div>
86
+
87
+ <div class="typing-text mb-6" id="typingText">
88
+ Click on a time option above to start the test. The text will appear here when you begin.
89
+ </div>
90
+
91
+ <input type="text" id="typingInput" class="typing-input" autocomplete="off">
92
+
93
+ <div class="text-center">
94
+ <button id="startBtn" class="px-8 py-3 bg-blue-600 text-white font-bold rounded-lg hover:bg-blue-700 transition">
95
+ <i class="fas fa-play mr-2"></i>Start Test
96
+ </button>
97
+ <button id="retryBtn" class="px-8 py-3 bg-gray-200 text-gray-700 font-bold rounded-lg hover:bg-gray-300 transition ml-4 hidden">
98
+ <i class="fas fa-redo mr-2"></i>Try Again
99
+ </button>
100
+ </div>
101
+ </div>
102
+
103
+ <div id="resultCard" class="result-card bg-white rounded-xl shadow-lg p-6 w-full max-w-3xl mx-auto">
104
+ <h2 class="text-2xl font-bold text-center text-blue-600 mb-4">Your Results</h2>
105
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
106
+ <div class="bg-blue-50 p-4 rounded-lg text-center">
107
+ <div class="text-4xl font-bold text-blue-600 mb-2" id="resultWPM">0</div>
108
+ <div class="text-gray-600">Words Per Minute</div>
109
+ </div>
110
+ <div class="bg-green-50 p-4 rounded-lg text-center">
111
+ <div class="text-4xl font-bold text-green-600 mb-2" id="resultAccuracy">0%</div>
112
+ <div class="text-gray-600">Accuracy</div>
113
+ </div>
114
+ <div class="bg-purple-50 p-4 rounded-lg text-center">
115
+ <div class="text-4xl font-bold text-purple-600 mb-2" id="resultChars">0</div>
116
+ <div class="text-gray-600">Characters Typed</div>
117
+ </div>
118
+ </div>
119
+ <div class="mt-6 text-center">
120
+ <button id="shareBtn" class="px-6 py-2 bg-blue-100 text-blue-600 font-medium rounded-full hover:bg-blue-200 transition">
121
+ <i class="fas fa-share-alt mr-2"></i>Share Your Score
122
+ </button>
123
+ </div>
124
+ </div>
125
+ </div>
126
+
127
+ <script>
128
+ // Sample texts for typing test
129
+ const sampleTexts = [
130
+ "The quick brown fox jumps over the lazy dog. This sentence contains all the letters in the English alphabet. Typing is an essential skill in today's digital world.",
131
+ "Programming is the process of creating a set of instructions that tell a computer how to perform a task. It requires logical thinking and problem-solving skills.",
132
+ "The best way to predict the future is to invent it. Technology has transformed our lives in countless ways, making communication faster and more efficient.",
133
+ "Practice makes perfect. Regular typing practice can significantly improve your speed and accuracy over time. Consistency is key to mastering any skill.",
134
+ "The internet has revolutionized how we access information. With just a few keystrokes, we can find answers to almost any question imaginable."
135
+ ];
136
+
137
+ // DOM elements
138
+ const typingText = document.getElementById('typingText');
139
+ const typingInput = document.getElementById('typingInput');
140
+ const timer = document.getElementById('timer');
141
+ const wpmDisplay = document.getElementById('wpm');
142
+ const progressBar = document.getElementById('progressBar');
143
+ const startBtn = document.getElementById('startBtn');
144
+ const retryBtn = document.getElementById('retryBtn');
145
+ const timeButtons = document.querySelectorAll('.time-btn');
146
+ const resultCard = document.getElementById('resultCard');
147
+ const resultWPM = document.getElementById('resultWPM');
148
+ const resultAccuracy = document.getElementById('resultAccuracy');
149
+ const resultChars = document.getElementById('resultChars');
150
+ const shareBtn = document.getElementById('shareBtn');
151
+
152
+ // Variables
153
+ let timeLeft = 0;
154
+ let timerInterval;
155
+ let totalTime = 0;
156
+ let isTyping = false;
157
+ let correctChars = 0;
158
+ let totalTyped = 0;
159
+ let currentText = '';
160
+ let currentIndex = 0;
161
+ let startTime;
162
+ let wpm = 0;
163
+
164
+ // Initialize
165
+ function init() {
166
+ typingInput.value = '';
167
+ typingInput.focus();
168
+ currentIndex = 0;
169
+ correctChars = 0;
170
+ totalTyped = 0;
171
+ wpm = 0;
172
+ updateWPM();
173
+
174
+ // Generate random text
175
+ currentText = sampleTexts[Math.floor(Math.random() * sampleTexts.length)];
176
+
177
+ // Display text with spans
178
+ typingText.innerHTML = '';
179
+ currentText.split('').forEach((char, index) => {
180
+ const span = document.createElement('span');
181
+ span.textContent = char;
182
+ span.id = `char-${index}`;
183
+ typingText.appendChild(span);
184
+ });
185
+
186
+ // Highlight first character
187
+ document.getElementById(`char-0`).classList.add('active');
188
+ }
189
+
190
+ // Start test
191
+ function startTest(seconds) {
192
+ if (isTyping) return;
193
+
194
+ totalTime = seconds;
195
+ timeLeft = seconds;
196
+ isTyping = true;
197
+ startTime = new Date().getTime();
198
+
199
+ init();
200
+
201
+ // Update timer display
202
+ updateTimer();
203
+
204
+ // Start timer
205
+ timerInterval = setInterval(() => {
206
+ timeLeft--;
207
+ updateTimer();
208
+
209
+ if (timeLeft <= 0) {
210
+ endTest();
211
+ }
212
+ }, 1000);
213
+
214
+ // UI changes
215
+ startBtn.classList.add('hidden');
216
+ retryBtn.classList.remove('hidden');
217
+ resultCard.classList.remove('show');
218
+ typingInput.focus();
219
+ }
220
+
221
+ // Update timer display
222
+ function updateTimer() {
223
+ const minutes = Math.floor(timeLeft / 60);
224
+ const seconds = timeLeft % 60;
225
+ timer.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
226
+
227
+ // Update progress bar
228
+ const progressPercent = (timeLeft / totalTime) * 100;
229
+ progressBar.style.width = `${progressPercent}%`;
230
+
231
+ // Change color when time is running out
232
+ if (progressPercent < 30) {
233
+ progressBar.classList.remove('bg-blue-500');
234
+ progressBar.classList.add('bg-red-500');
235
+ } else {
236
+ progressBar.classList.remove('bg-red-500');
237
+ progressBar.classList.add('bg-blue-500');
238
+ }
239
+ }
240
+
241
+ // Update WPM display
242
+ function updateWPM() {
243
+ wpmDisplay.textContent = Math.round(wpm);
244
+ }
245
+
246
+ // Calculate WPM
247
+ function calculateWPM() {
248
+ if (!startTime) return 0;
249
+
250
+ const now = new Date().getTime();
251
+ const timeElapsed = (now - startTime) / 1000 / 60; // in minutes
252
+ const wordsTyped = correctChars / 5; // standard word length
253
+
254
+ return wordsTyped / timeElapsed || 0;
255
+ }
256
+
257
+ // Handle typing input
258
+ typingInput.addEventListener('input', (e) => {
259
+ if (!isTyping) return;
260
+
261
+ const inputChar = typingInput.value;
262
+ const currentChar = currentText[currentIndex];
263
+
264
+ // Remove active class from previous character
265
+ document.getElementById(`char-${currentIndex}`).classList.remove('active');
266
+
267
+ // Check if character is correct
268
+ if (inputChar === currentChar) {
269
+ document.getElementById(`char-${currentIndex}`).classList.add('correct');
270
+ correctChars++;
271
+ } else {
272
+ document.getElementById(`char-${currentIndex}`).classList.add('incorrect');
273
+ }
274
+
275
+ totalTyped++;
276
+ currentIndex++;
277
+ typingInput.value = '';
278
+
279
+ // Add active class to next character
280
+ if (currentIndex < currentText.length) {
281
+ document.getElementById(`char-${currentIndex}`).classList.add('active');
282
+ } else {
283
+ // If reached end of text, generate new text
284
+ currentText = sampleTexts[Math.floor(Math.random() * sampleTexts.length)];
285
+ typingText.innerHTML = '';
286
+ currentText.split('').forEach((char, index) => {
287
+ const span = document.createElement('span');
288
+ span.textContent = char;
289
+ span.id = `char-${index + currentIndex}`;
290
+ typingText.appendChild(span);
291
+ });
292
+ document.getElementById(`char-${currentIndex}`).classList.add('active');
293
+ }
294
+
295
+ // Calculate and update WPM
296
+ wpm = calculateWPM();
297
+ updateWPM();
298
+ });
299
+
300
+ // End test
301
+ function endTest() {
302
+ clearInterval(timerInterval);
303
+ isTyping = false;
304
+
305
+ // Calculate final results
306
+ const accuracy = Math.round((correctChars / totalTyped) * 100) || 0;
307
+
308
+ // Display results
309
+ resultWPM.textContent = Math.round(wpm);
310
+ resultAccuracy.textContent = `${accuracy}%`;
311
+ resultChars.textContent = totalTyped;
312
+
313
+ // Show result card
314
+ resultCard.classList.add('show');
315
+
316
+ // UI changes
317
+ typingInput.blur();
318
+ }
319
+
320
+ // Event listeners
321
+ startBtn.addEventListener('click', () => {
322
+ // Default to 60s if no time selected
323
+ const selectedTime = document.querySelector('.time-btn.active');
324
+ const time = selectedTime ? parseInt(selectedTime.id) : 60;
325
+ startTest(time);
326
+ });
327
+
328
+ retryBtn.addEventListener('click', () => {
329
+ const selectedTime = document.querySelector('.time-btn.active');
330
+ const time = selectedTime ? parseInt(selectedTime.id) : 60;
331
+ startTest(time);
332
+ });
333
+
334
+ timeButtons.forEach(button => {
335
+ button.addEventListener('click', () => {
336
+ timeButtons.forEach(btn => btn.classList.remove('bg-blue-600', 'text-white'));
337
+ button.classList.add('bg-blue-600', 'text-white');
338
+ });
339
+ });
340
+
341
+ shareBtn.addEventListener('click', () => {
342
+ if (navigator.share) {
343
+ navigator.share({
344
+ title: 'My Typing Test Results',
345
+ text: `I typed at ${resultWPM.textContent} WPM with ${resultAccuracy.textContent} accuracy! Can you beat my score?`,
346
+ url: window.location.href
347
+ }).catch(err => {
348
+ console.log('Error sharing:', err);
349
+ });
350
+ } else {
351
+ // Fallback for browsers that don't support Web Share API
352
+ const shareText = `I typed at ${resultWPM.textContent} WPM with ${resultAccuracy.textContent} accuracy! Try it yourself: ${window.location.href}`;
353
+ alert(shareText);
354
+ }
355
+ });
356
+
357
+ // Set default active time button
358
+ document.getElementById('60s').classList.add('bg-blue-600', 'text-white');
359
+ </script>
360
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=andreaschandra/type-racer" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
361
+ </html>
prompts.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ create a typing test with options 30 seconds, 45 seconds, 60 seconds. Show the speed wpm