Reaperxxxx commited on
Commit
e839a8a
·
verified ·
1 Parent(s): dd29746

Update strikes.html

Browse files
Files changed (1) hide show
  1. strikes.html +665 -57
strikes.html CHANGED
@@ -2,84 +2,692 @@
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
- <title>Strike Leaderboard</title>
 
6
  <style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  body {
8
- font-family: Arial, sans-serif;
9
- background: #f4f4f4;
10
- padding: 20px;
11
- color: #333;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  }
13
- h1, h2 {
 
 
14
  text-align: center;
 
 
15
  }
16
- table {
17
- width: 100%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  max-width: 600px;
19
- margin: 20px auto;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  border-collapse: collapse;
21
- background: #fff;
22
- box-shadow: 0 2px 6px rgba(0,0,0,0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  }
24
- th, td {
25
- padding: 12px;
26
- border: 1px solid #ddd;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  text-align: center;
 
 
 
 
 
 
 
 
28
  }
29
- th {
30
- background-color: #4CAF50;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  color: white;
32
  }
33
- tr:nth-child(even) {
34
- background-color: #f9f9f9;
 
 
35
  }
36
  </style>
37
  </head>
38
  <body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
- <h1>🚨 Strike Leaderboard</h1>
41
- <h2 id="group-info">Loading...</h2>
42
-
43
- <table>
44
- <thead>
45
- <tr>
46
- <th>#</th>
47
- <th>User ID</th>
48
- <th>Username</th>
49
- <th>Strikes</th>
50
- </tr>
51
- </thead>
52
- <tbody id="user-table">
53
- <!-- User rows will go here -->
54
- </tbody>
55
- </table>
 
 
 
 
 
 
 
 
 
 
56
 
57
  <script>
58
- const params = new URLSearchParams(window.location.search);
59
- const group = params.get("group") || "Unknown Group";
60
- const chatId = params.get("chat_id") || "N/A";
61
- document.getElementById("group-info").textContent = `${group} (Chat ID: ${chatId})`;
62
-
63
- const usersRaw = window.location.href.split("users=")[1];
64
- if (usersRaw) {
65
- const users = decodeURIComponent(usersRaw).split("&");
66
-
67
- const tbody = document.getElementById("user-table");
68
- users.forEach((entry, index) => {
69
- const [id, username, strikes] = entry.split("?");
70
- const row = document.createElement("tr");
71
-
72
- row.innerHTML = `
73
- <td>${index + 1}</td>
74
- <td>${id}</td>
75
- <td>${username}</td>
76
- <td>${strikes}</td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  `;
78
-
79
- tbody.appendChild(row);
80
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
82
  </script>
83
-
84
  </body>
85
  </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>Strike Leaderboard - ANTI NSFW Bot</title>
7
  <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ :root {
15
+ --primary-purple: #8b5cf6;
16
+ --dark-purple: #5b21b6;
17
+ --light-purple: #c4b5fd;
18
+ --accent-pink: #ec4899;
19
+ --warning-orange: #f59e0b;
20
+ --danger-red: #ef4444;
21
+ --success-green: #10b981;
22
+ --dark-bg: #0f0f23;
23
+ --card-bg: rgba(139, 92, 246, 0.08);
24
+ --glass-bg: rgba(255, 255, 255, 0.05);
25
+ --text-primary: #f8fafc;
26
+ --text-secondary: #cbd5e1;
27
+ --text-muted: #94a3b8;
28
+ --border-glow: rgba(139, 92, 246, 0.3);
29
+ --table-row-hover: rgba(139, 92, 246, 0.1);
30
+ }
31
+
32
  body {
33
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
34
+ background: var(--dark-bg);
35
+ color: var(--text-primary);
36
+ line-height: 1.6;
37
+ min-height: 100vh;
38
+ overflow-x: hidden;
39
+ }
40
+
41
+ /* Animated background */
42
+ body::before {
43
+ content: '';
44
+ position: fixed;
45
+ top: 0;
46
+ left: 0;
47
+ width: 100%;
48
+ height: 100%;
49
+ background:
50
+ radial-gradient(circle at 20% 80%, rgba(139, 92, 246, 0.1) 0%, transparent 50%),
51
+ radial-gradient(circle at 80% 20%, rgba(236, 72, 153, 0.1) 0%, transparent 50%),
52
+ radial-gradient(circle at 40% 40%, rgba(91, 33, 182, 0.05) 0%, transparent 50%);
53
+ z-index: -1;
54
+ animation: backgroundPulse 8s ease-in-out infinite;
55
+ }
56
+
57
+ @keyframes backgroundPulse {
58
+ 0%, 100% { opacity: 1; }
59
+ 50% { opacity: 0.8; }
60
+ }
61
+
62
+ .container {
63
+ max-width: 1200px;
64
+ margin: 0 auto;
65
+ padding: 40px 20px;
66
  }
67
+
68
+ /* Header Section */
69
+ .header {
70
  text-align: center;
71
+ margin-bottom: 50px;
72
+ position: relative;
73
  }
74
+
75
+ .header::before {
76
+ content: '';
77
+ position: absolute;
78
+ top: -20px;
79
+ left: 50%;
80
+ transform: translateX(-50%);
81
+ width: 200px;
82
+ height: 200px;
83
+ background: conic-gradient(from 0deg, transparent, var(--primary-purple), transparent);
84
+ border-radius: 50%;
85
+ opacity: 0.1;
86
+ animation: rotate 15s linear infinite;
87
+ }
88
+
89
+ @keyframes rotate {
90
+ to { transform: translateX(-50%) rotate(360deg); }
91
+ }
92
+
93
+ .warning-badge {
94
+ display: inline-block;
95
+ background: linear-gradient(135deg, rgba(239, 68, 68, 0.2), rgba(245, 158, 11, 0.2));
96
+ backdrop-filter: blur(10px);
97
+ border: 1px solid rgba(239, 68, 68, 0.3);
98
+ padding: 8px 20px;
99
+ border-radius: 50px;
100
+ font-size: 0.9rem;
101
+ font-weight: 500;
102
+ margin-bottom: 20px;
103
+ color: #fca5a5;
104
+ animation: float 3s ease-in-out infinite;
105
+ }
106
+
107
+ @keyframes float {
108
+ 0%, 100% { transform: translateY(0px); }
109
+ 50% { transform: translateY(-8px); }
110
+ }
111
+
112
+ h1 {
113
+ font-size: clamp(2.5rem, 6vw, 4rem);
114
+ font-weight: 800;
115
+ background: linear-gradient(135deg, var(--danger-red), var(--warning-orange), var(--accent-pink));
116
+ -webkit-background-clip: text;
117
+ -webkit-text-fill-color: transparent;
118
+ background-clip: text;
119
+ margin-bottom: 15px;
120
+ letter-spacing: -0.02em;
121
+ animation: titleGlow 3s ease-in-out infinite alternate;
122
+ }
123
+
124
+ @keyframes titleGlow {
125
+ from { filter: drop-shadow(0 0 20px rgba(239, 68, 68, 0.5)); }
126
+ to { filter: drop-shadow(0 0 40px rgba(239, 68, 68, 0.8)); }
127
+ }
128
+
129
+ .group-info {
130
+ background: var(--glass-bg);
131
+ backdrop-filter: blur(20px);
132
+ border: 1px solid var(--border-glow);
133
+ padding: 20px 30px;
134
+ border-radius: 16px;
135
+ margin: 30px auto;
136
  max-width: 600px;
137
+ font-size: 1.1rem;
138
+ color: var(--text-secondary);
139
+ display: flex;
140
+ align-items: center;
141
+ justify-content: center;
142
+ gap: 12px;
143
+ position: relative;
144
+ overflow: hidden;
145
+ }
146
+
147
+ .group-info::before {
148
+ content: '';
149
+ position: absolute;
150
+ top: 0;
151
+ left: 0;
152
+ right: 0;
153
+ height: 1px;
154
+ background: linear-gradient(90deg, transparent, var(--primary-purple), transparent);
155
+ }
156
+
157
+ .group-icon {
158
+ font-size: 1.5rem;
159
+ filter: drop-shadow(0 0 10px currentColor);
160
+ }
161
+
162
+ /* Enhanced Table Container */
163
+ .table-container {
164
+ background: var(--glass-bg);
165
+ backdrop-filter: blur(20px);
166
+ border: 1px solid var(--border-glow);
167
+ border-radius: 24px;
168
+ overflow: hidden;
169
+ box-shadow:
170
+ 0 20px 60px rgba(139, 92, 246, 0.2),
171
+ inset 0 1px 0 rgba(255, 255, 255, 0.1);
172
+ position: relative;
173
+ }
174
+
175
+ .table-container::before {
176
+ content: '';
177
+ position: absolute;
178
+ top: 0;
179
+ left: 0;
180
+ right: 0;
181
+ height: 2px;
182
+ background: linear-gradient(90deg, var(--danger-red), var(--warning-orange), var(--accent-pink));
183
+ }
184
+
185
+ .table-header {
186
+ padding: 30px;
187
+ text-align: center;
188
+ border-bottom: 1px solid var(--border-glow);
189
+ background: rgba(139, 92, 246, 0.05);
190
+ }
191
+
192
+ .table-title {
193
+ font-size: 1.5rem;
194
+ font-weight: 600;
195
+ color: var(--text-primary);
196
+ margin-bottom: 8px;
197
+ }
198
+
199
+ .table-subtitle {
200
+ color: var(--text-muted);
201
+ font-size: 0.95rem;
202
+ }
203
+
204
+ /* Enhanced Table */
205
+ .leaderboard-table {
206
+ width: 100%;
207
  border-collapse: collapse;
208
+ background: transparent;
209
+ }
210
+
211
+ .table-head {
212
+ background: linear-gradient(135deg, var(--primary-purple), var(--dark-purple));
213
+ }
214
+
215
+ .table-head th {
216
+ padding: 20px 15px;
217
+ text-align: center;
218
+ color: white;
219
+ font-weight: 600;
220
+ font-size: 0.95rem;
221
+ text-transform: uppercase;
222
+ letter-spacing: 0.5px;
223
+ border: none;
224
+ position: relative;
225
+ }
226
+
227
+ .table-head th:not(:last-child)::after {
228
+ content: '';
229
+ position: absolute;
230
+ right: 0;
231
+ top: 25%;
232
+ height: 50%;
233
+ width: 1px;
234
+ background: rgba(255, 255, 255, 0.2);
235
+ }
236
+
237
+ .user-row {
238
+ border: none;
239
+ transition: all 0.3s ease;
240
+ position: relative;
241
+ }
242
+
243
+ .user-row:hover {
244
+ background: var(--table-row-hover);
245
+ transform: translateX(5px);
246
+ }
247
+
248
+ .user-row td {
249
+ padding: 18px 15px;
250
+ border: none;
251
+ border-bottom: 1px solid rgba(139, 92, 246, 0.1);
252
+ text-align: center;
253
+ vertical-align: middle;
254
+ }
255
+
256
+ .user-row:last-child td {
257
+ border-bottom: none;
258
  }
259
+
260
+ /* Rank styling */
261
+ .rank {
262
+ font-weight: 700;
263
+ font-size: 1.1rem;
264
+ display: flex;
265
+ align-items: center;
266
+ justify-content: center;
267
+ gap: 8px;
268
+ }
269
+
270
+ .rank-1 { color: #ffd700; }
271
+ .rank-2 { color: #c0c0c0; }
272
+ .rank-3 { color: #cd7f32; }
273
+
274
+ .rank-badge {
275
+ width: 32px;
276
+ height: 32px;
277
+ border-radius: 50%;
278
+ display: flex;
279
+ align-items: center;
280
+ justify-content: center;
281
+ font-weight: bold;
282
+ font-size: 0.9rem;
283
+ }
284
+
285
+ .rank-1 .rank-badge {
286
+ background: linear-gradient(135deg, #ffd700, #ffed4e);
287
+ color: #92400e;
288
+ box-shadow: 0 4px 15px rgba(255, 215, 0, 0.4);
289
+ }
290
+
291
+ .rank-2 .rank-badge {
292
+ background: linear-gradient(135deg, #c0c0c0, #e5e7eb);
293
+ color: #374151;
294
+ box-shadow: 0 4px 15px rgba(192, 192, 192, 0.4);
295
+ }
296
+
297
+ .rank-3 .rank-badge {
298
+ background: linear-gradient(135deg, #cd7f32, #d97706);
299
+ color: white;
300
+ box-shadow: 0 4px 15px rgba(205, 127, 50, 0.4);
301
+ }
302
+
303
+ .rank-other .rank-badge {
304
+ background: linear-gradient(135deg, var(--card-bg), rgba(139, 92, 246, 0.2));
305
+ color: var(--text-secondary);
306
+ border: 1px solid var(--border-glow);
307
+ }
308
+
309
+ /* User ID styling */
310
+ .user-id {
311
+ font-family: 'JetBrains Mono', 'Courier New', monospace;
312
+ color: var(--text-muted);
313
+ font-size: 0.9rem;
314
+ background: rgba(139, 92, 246, 0.1);
315
+ padding: 4px 8px;
316
+ border-radius: 6px;
317
+ border: 1px solid rgba(139, 92, 246, 0.2);
318
+ }
319
+
320
+ /* Username styling */
321
+ .username {
322
+ font-weight: 500;
323
+ color: var(--text-primary);
324
+ display: flex;
325
+ align-items: center;
326
+ justify-content: center;
327
+ gap: 6px;
328
+ }
329
+
330
+ .username::before {
331
+ content: '@';
332
+ color: var(--primary-purple);
333
+ font-weight: 600;
334
+ }
335
+
336
+ /* Strike count styling */
337
+ .strikes {
338
+ font-weight: 700;
339
+ font-size: 1.1rem;
340
+ display: flex;
341
+ align-items: center;
342
+ justify-content: center;
343
+ gap: 8px;
344
+ }
345
+
346
+ .strike-count {
347
+ padding: 8px 12px;
348
+ border-radius: 20px;
349
+ font-weight: 600;
350
+ min-width: 50px;
351
+ }
352
+
353
+ .strikes-low {
354
+ background: rgba(16, 185, 129, 0.2);
355
+ color: #6ee7b7;
356
+ border: 1px solid rgba(16, 185, 129, 0.3);
357
+ }
358
+
359
+ .strikes-medium {
360
+ background: rgba(245, 158, 11, 0.2);
361
+ color: #fbbf24;
362
+ border: 1px solid rgba(245, 158, 11, 0.3);
363
+ }
364
+
365
+ .strikes-high {
366
+ background: rgba(239, 68, 68, 0.2);
367
+ color: #fca5a5;
368
+ border: 1px solid rgba(239, 68, 68, 0.3);
369
+ animation: pulse 2s infinite;
370
+ }
371
+
372
+ /* Empty state */
373
+ .empty-state {
374
  text-align: center;
375
+ padding: 60px 20px;
376
+ color: var(--text-muted);
377
+ }
378
+
379
+ .empty-icon {
380
+ font-size: 4rem;
381
+ margin-bottom: 20px;
382
+ opacity: 0.5;
383
  }
384
+
385
+ .empty-message {
386
+ font-size: 1.2rem;
387
+ margin-bottom: 10px;
388
+ }
389
+
390
+ .empty-subtitle {
391
+ font-size: 0.95rem;
392
+ opacity: 0.7;
393
+ }
394
+
395
+ /* Loading animation */
396
+ .loading {
397
+ display: flex;
398
+ align-items: center;
399
+ justify-content: center;
400
+ gap: 12px;
401
+ padding: 40px;
402
+ color: var(--text-secondary);
403
+ }
404
+
405
+ .loading-spinner {
406
+ width: 24px;
407
+ height: 24px;
408
+ border: 3px solid rgba(139, 92, 246, 0.2);
409
+ border-top: 3px solid var(--primary-purple);
410
+ border-radius: 50%;
411
+ animation: spin 1s linear infinite;
412
+ }
413
+
414
+ @keyframes spin {
415
+ to { transform: rotate(360deg); }
416
+ }
417
+
418
+ /* Statistics cards */
419
+ .stats-container {
420
+ display: grid;
421
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
422
+ gap: 20px;
423
+ margin-bottom: 40px;
424
+ }
425
+
426
+ .stat-card {
427
+ background: var(--glass-bg);
428
+ backdrop-filter: blur(10px);
429
+ border: 1px solid var(--border-glow);
430
+ border-radius: 16px;
431
+ padding: 25px;
432
+ text-align: center;
433
+ transition: all 0.3s ease;
434
+ }
435
+
436
+ .stat-card:hover {
437
+ transform: translateY(-5px);
438
+ box-shadow: 0 15px 40px rgba(139, 92, 246, 0.2);
439
+ }
440
+
441
+ .stat-value {
442
+ font-size: 2rem;
443
+ font-weight: 700;
444
+ color: var(--primary-purple);
445
+ margin-bottom: 5px;
446
+ }
447
+
448
+ .stat-label {
449
+ color: var(--text-secondary);
450
+ font-size: 0.9rem;
451
+ text-transform: uppercase;
452
+ letter-spacing: 0.5px;
453
+ }
454
+
455
+ /* Responsive design */
456
+ @media (max-width: 768px) {
457
+ .container { padding: 20px 15px; }
458
+ h1 { font-size: 2.5rem; }
459
+ .table-container { border-radius: 16px; }
460
+ .table-header { padding: 20px; }
461
+ .table-head th { padding: 15px 10px; font-size: 0.85rem; }
462
+ .user-row td { padding: 15px 10px; }
463
+ .group-info {
464
+ flex-direction: column;
465
+ gap: 8px;
466
+ text-align: center;
467
+ }
468
+ .stats-container { grid-template-columns: 1fr; gap: 15px; }
469
+ }
470
+
471
+ /* Selection styling */
472
+ ::selection {
473
+ background: var(--primary-purple);
474
  color: white;
475
  }
476
+
477
+ /* Smooth scrolling */
478
+ html {
479
+ scroll-behavior: smooth;
480
  }
481
  </style>
482
  </head>
483
  <body>
484
+ <div class="container">
485
+ <div class="header">
486
+ <div class="warning-badge">⚠️ Violation Tracking</div>
487
+ <h1>🚨 Strike Leaderboard</h1>
488
+ </div>
489
+
490
+ <div class="group-info" id="group-info">
491
+ <span class="group-icon">🏢</span>
492
+ <div class="loading">
493
+ <div class="loading-spinner"></div>
494
+ <span>Loading group information...</span>
495
+ </div>
496
+ </div>
497
+
498
+ <div class="stats-container" id="stats-container" style="display: none;">
499
+ <div class="stat-card">
500
+ <div class="stat-value" id="total-users">0</div>
501
+ <div class="stat-label">Total Users</div>
502
+ </div>
503
+ <div class="stat-card">
504
+ <div class="stat-value" id="total-strikes">0</div>
505
+ <div class="stat-label">Total Strikes</div>
506
+ </div>
507
+ <div class="stat-card">
508
+ <div class="stat-value" id="avg-strikes">0</div>
509
+ <div class="stat-label">Avg Strikes</div>
510
+ </div>
511
+ </div>
512
 
513
+ <div class="table-container">
514
+ <div class="table-header">
515
+ <div class="table-title">User Violation Rankings</div>
516
+ <div class="table-subtitle">Users with the highest number of content policy violations</div>
517
+ </div>
518
+
519
+ <table class="leaderboard-table">
520
+ <thead class="table-head">
521
+ <tr>
522
+ <th>Rank</th>
523
+ <th>User ID</th>
524
+ <th>Username</th>
525
+ <th>Strike Count</th>
526
+ </tr>
527
+ </thead>
528
+ <tbody id="user-table">
529
+ <tr>
530
+ <td colspan="4" class="loading">
531
+ <div class="loading-spinner"></div>
532
+ <span>Loading user data...</span>
533
+ </td>
534
+ </tr>
535
+ </tbody>
536
+ </table>
537
+ </div>
538
+ </div>
539
 
540
  <script>
541
+ function initializeLeaderboard() {
542
+ const params = new URLSearchParams(window.location.search);
543
+ const group = params.get("group") || "Unknown Group";
544
+ const chatId = params.get("chat_id") || "N/A";
545
+
546
+ // Update group info
547
+ const groupInfo = document.getElementById("group-info");
548
+ groupInfo.innerHTML = `
549
+ <span class="group-icon">🏢</span>
550
+ <div>
551
+ <strong>${group}</strong><br>
552
+ <small>Chat ID: ${chatId}</small>
553
+ </div>
554
+ `;
555
+
556
+ // Parse users data
557
+ const usersRaw = window.location.href.split("users=")[1];
558
+
559
+ if (usersRaw) {
560
+ const users = decodeURIComponent(usersRaw).split("&");
561
+ const tbody = document.getElementById("user-table");
562
+ const statsContainer = document.getElementById("stats-container");
563
+
564
+ if (users.length === 0 || (users.length === 1 && users[0] === "")) {
565
+ // Show empty state
566
+ tbody.innerHTML = `
567
+ <tr>
568
+ <td colspan="4" class="empty-state">
569
+ <div class="empty-icon">🎉</div>
570
+ <div class="empty-message">No violations found!</div>
571
+ <div class="empty-subtitle">Your community is maintaining excellent standards</div>
572
+ </td>
573
+ </tr>
574
+ `;
575
+ return;
576
+ }
577
+
578
+ // Clear loading state
579
+ tbody.innerHTML = "";
580
+
581
+ // Calculate statistics
582
+ let totalStrikes = 0;
583
+ const validUsers = users.filter(entry => entry.trim() !== "");
584
+
585
+ // Sort users by strike count (descending)
586
+ const sortedUsers = validUsers
587
+ .map(entry => {
588
+ const [id, username, strikes] = entry.split("?");
589
+ const strikeCount = parseInt(strikes) || 0;
590
+ totalStrikes += strikeCount;
591
+ return { id, username, strikes: strikeCount };
592
+ })
593
+ .sort((a, b) => b.strikes - a.strikes);
594
+
595
+ const avgStrikes = validUsers.length > 0 ? (totalStrikes / validUsers.length).toFixed(1) : 0;
596
+
597
+ // Update statistics
598
+ document.getElementById("total-users").textContent = validUsers.length;
599
+ document.getElementById("total-strikes").textContent = totalStrikes;
600
+ document.getElementById("avg-strikes").textContent = avgStrikes;
601
+ statsContainer.style.display = "grid";
602
+
603
+ // Populate table
604
+ sortedUsers.forEach((user, index) => {
605
+ const rank = index + 1;
606
+ const row = document.createElement("tr");
607
+ row.className = "user-row";
608
+
609
+ // Determine rank class and strike severity
610
+ let rankClass = "rank-other";
611
+ if (rank === 1) rankClass = "rank-1";
612
+ else if (rank === 2) rankClass = "rank-2";
613
+ else if (rank === 3) rankClass = "rank-3";
614
+
615
+ let strikeClass = "strikes-low";
616
+ if (user.strikes >= 5) strikeClass = "strikes-high";
617
+ else if (user.strikes >= 3) strikeClass = "strikes-medium";
618
+
619
+ // Add trophy emoji for top 3
620
+ let rankDisplay = rank;
621
+ if (rank === 1) rankDisplay = "🥇";
622
+ else if (rank === 2) rankDisplay = "🥈";
623
+ else if (rank === 3) rankDisplay = "🥉";
624
+
625
+ row.innerHTML = `
626
+ <td>
627
+ <div class="rank ${rankClass}">
628
+ <div class="rank-badge">${rankDisplay}</div>
629
+ </div>
630
+ </td>
631
+ <td>
632
+ <div class="user-id">${user.id}</div>
633
+ </td>
634
+ <td>
635
+ <div class="username">${user.username || 'N/A'}</div>
636
+ </td>
637
+ <td>
638
+ <div class="strikes">
639
+ <div class="strike-count ${strikeClass}">${user.strikes}</div>
640
+ </div>
641
+ </td>
642
+ `;
643
+
644
+ // Add stagger animation
645
+ row.style.animationDelay = `${index * 0.1}s`;
646
+ row.style.animation = "slideIn 0.6s ease-out forwards";
647
+
648
+ tbody.appendChild(row);
649
+ });
650
+
651
+ } else {
652
+ // No data provided
653
+ const tbody = document.getElementById("user-table");
654
+ tbody.innerHTML = `
655
+ <tr>
656
+ <td colspan="4" class="empty-state">
657
+ <div class="empty-icon">📊</div>
658
+ <div class="empty-message">No data available</div>
659
+ <div class="empty-subtitle">Strike data could not be loaded</div>
660
+ </td>
661
+ </tr>
662
  `;
663
+ }
664
+ }
665
+
666
+ // Add slide-in animation
667
+ const style = document.createElement('style');
668
+ style.textContent = `
669
+ @keyframes slideIn {
670
+ from {
671
+ opacity: 0;
672
+ transform: translateY(20px);
673
+ }
674
+ to {
675
+ opacity: 1;
676
+ transform: translateY(0);
677
+ }
678
+ }
679
+ `;
680
+ document.head.appendChild(style);
681
+
682
+ // Initialize when DOM is loaded
683
+ document.addEventListener('DOMContentLoaded', initializeLeaderboard);
684
+
685
+ // Fallback initialization
686
+ if (document.readyState === 'loading') {
687
+ document.addEventListener('DOMContentLoaded', initializeLeaderboard);
688
+ } else {
689
+ initializeLeaderboard();
690
  }
691
  </script>
 
692
  </body>
693
  </html>