AnesKAM commited on
Commit
bf8d887
·
verified ·
1 Parent(s): ed10f86

Rename indexer.py to index.html

Browse files
Files changed (2) hide show
  1. index.html +796 -0
  2. indexer.py +0 -119
index.html ADDED
@@ -0,0 +1,796 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ar" dir="rtl">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>SurfGO! — محرك بحث AnesNT</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@300;400;500;700;800;900&family=Space+Grotesk:wght@400;500;700&display=swap" rel="stylesheet">
9
+ <style>
10
+ :root {
11
+ --bg: #07090f;
12
+ --bg2: #0d1017;
13
+ --bg3: #131720;
14
+ --bg4: #1a1f2e;
15
+ --cyan: #00e5ff;
16
+ --cyan2: #00bcd4;
17
+ --orange: #ff6b00;
18
+ --orange2: #ff9a3c;
19
+ --purple: #7c3aed;
20
+ --text: #e8eeff;
21
+ --text2: #8899bb;
22
+ --text3: #4a5a7a;
23
+ --border: rgba(0,229,255,0.12);
24
+ --border2: rgba(0,229,255,0.25);
25
+ --glow: 0 0 30px rgba(0,229,255,0.2);
26
+ --r: 14px;
27
+ }
28
+ * { margin:0; padding:0; box-sizing:border-box; }
29
+
30
+ body {
31
+ background: var(--bg);
32
+ color: var(--text);
33
+ font-family: 'Tajawal', sans-serif;
34
+ min-height: 100vh;
35
+ position: relative;
36
+ overflow-x: hidden;
37
+ }
38
+
39
+ /* Grid background */
40
+ body::before {
41
+ content:'';
42
+ position:fixed;
43
+ inset:0;
44
+ background:
45
+ linear-gradient(rgba(0,229,255,0.025) 1px, transparent 1px),
46
+ linear-gradient(90deg, rgba(0,229,255,0.025) 1px, transparent 1px);
47
+ background-size: 50px 50px;
48
+ pointer-events:none;
49
+ z-index:0;
50
+ }
51
+
52
+ /* Glow blob */
53
+ .blob {
54
+ position:fixed;
55
+ border-radius:50%;
56
+ filter:blur(80px);
57
+ pointer-events:none;
58
+ z-index:0;
59
+ opacity:0.4;
60
+ }
61
+ .blob1 { width:500px; height:500px; background:radial-gradient(circle, #00e5ff22, transparent); top:-100px; right:-100px; animation:drift1 12s ease-in-out infinite; }
62
+ .blob2 { width:400px; height:400px; background:radial-gradient(circle, #ff6b0015, transparent); bottom:-100px; left:-100px; animation:drift2 15s ease-in-out infinite; }
63
+
64
+ @keyframes drift1 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(-40px,40px)} }
65
+ @keyframes drift2 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(40px,-30px)} }
66
+
67
+ /* HEADER */
68
+ header {
69
+ position:relative;
70
+ z-index:10;
71
+ padding: 16px 24px;
72
+ display:flex;
73
+ align-items:center;
74
+ justify-content:space-between;
75
+ border-bottom: 1px solid var(--border);
76
+ background: rgba(7,9,15,0.8);
77
+ backdrop-filter: blur(12px);
78
+ }
79
+
80
+ .logo {
81
+ display:flex;
82
+ align-items:center;
83
+ gap:10px;
84
+ text-decoration:none;
85
+ }
86
+
87
+ .logo-icon {
88
+ width:38px; height:38px;
89
+ background: linear-gradient(135deg, var(--cyan), var(--purple));
90
+ border-radius:10px;
91
+ display:flex;
92
+ align-items:center;
93
+ justify-content:center;
94
+ font-size:18px;
95
+ box-shadow: 0 0 20px rgba(0,229,255,0.4);
96
+ }
97
+
98
+ .logo-text {
99
+ font-family:'Space Grotesk', sans-serif;
100
+ font-size:22px;
101
+ font-weight:700;
102
+ color:var(--cyan);
103
+ letter-spacing:-0.5px;
104
+ }
105
+ .logo-text span { color:var(--orange); }
106
+
107
+ .logo-by {
108
+ font-size:11px;
109
+ color:var(--text3);
110
+ letter-spacing:1px;
111
+ }
112
+
113
+ .header-search {
114
+ display:flex;
115
+ align-items:center;
116
+ gap:10px;
117
+ flex:1;
118
+ max-width:500px;
119
+ margin: 0 24px;
120
+ }
121
+
122
+ .header-search input {
123
+ flex:1;
124
+ background: var(--bg3);
125
+ border: 1px solid var(--border);
126
+ border-radius:10px;
127
+ padding: 9px 16px;
128
+ color: var(--text);
129
+ font-family:'Tajawal',sans-serif;
130
+ font-size:15px;
131
+ outline:none;
132
+ transition:border-color 0.2s, box-shadow 0.2s;
133
+ }
134
+ .header-search input:focus {
135
+ border-color: var(--cyan2);
136
+ box-shadow: 0 0 12px rgba(0,229,255,0.15);
137
+ }
138
+ .header-search button {
139
+ background: linear-gradient(135deg, var(--cyan), var(--cyan2));
140
+ border:none; border-radius:10px;
141
+ padding:9px 18px;
142
+ color:#000; font-weight:700;
143
+ font-family:'Tajawal',sans-serif;
144
+ font-size:14px;
145
+ cursor:pointer;
146
+ transition:opacity 0.2s, transform 0.1s;
147
+ white-space:nowrap;
148
+ }
149
+ .header-search button:hover { opacity:0.85; transform:scale(0.98); }
150
+
151
+ .nav-links {
152
+ display:flex;
153
+ gap:6px;
154
+ }
155
+ .nav-links a {
156
+ color:var(--text2);
157
+ text-decoration:none;
158
+ font-size:13px;
159
+ padding:6px 12px;
160
+ border-radius:8px;
161
+ transition:background 0.2s, color 0.2s;
162
+ cursor:pointer;
163
+ }
164
+ .nav-links a:hover, .nav-links a.active { background:var(--bg3); color:var(--cyan); }
165
+
166
+ /* HERO */
167
+ #hero {
168
+ position:relative;
169
+ z-index:10;
170
+ display:flex;
171
+ flex-direction:column;
172
+ align-items:center;
173
+ justify-content:center;
174
+ min-height: calc(100vh - 71px);
175
+ padding: 40px 24px;
176
+ text-align:center;
177
+ transition: opacity 0.3s, transform 0.3s;
178
+ }
179
+
180
+ .hero-badge {
181
+ display:inline-flex;
182
+ align-items:center;
183
+ gap:8px;
184
+ background: rgba(0,229,255,0.08);
185
+ border: 1px solid var(--border2);
186
+ border-radius:100px;
187
+ padding:7px 16px;
188
+ font-size:13px;
189
+ color:var(--cyan);
190
+ margin-bottom:28px;
191
+ animation: fadeUp 0.6s ease both;
192
+ }
193
+ .hero-badge::before { content:'✦'; font-size:10px; }
194
+
195
+ .hero-title {
196
+ font-size:clamp(52px, 10vw, 90px);
197
+ font-weight:900;
198
+ line-height:1;
199
+ margin-bottom:12px;
200
+ animation: fadeUp 0.6s 0.1s ease both;
201
+ }
202
+ .hero-title .surf { color: var(--cyan); text-shadow: 0 0 40px rgba(0,229,255,0.5); }
203
+ .hero-title .go { color: var(--orange); }
204
+ .hero-title .bang { color: var(--text3); }
205
+
206
+ .hero-sub {
207
+ font-size:18px;
208
+ color:var(--text2);
209
+ margin-bottom:40px;
210
+ font-weight:300;
211
+ animation: fadeUp 0.6s 0.2s ease both;
212
+ }
213
+
214
+ .search-box {
215
+ width:100%;
216
+ max-width:680px;
217
+ animation: fadeUp 0.6s 0.3s ease both;
218
+ }
219
+
220
+ .search-wrap {
221
+ display:flex;
222
+ align-items:center;
223
+ background: var(--bg3);
224
+ border: 1.5px solid var(--border2);
225
+ border-radius:18px;
226
+ padding:8px 8px 8px 20px;
227
+ gap:10px;
228
+ transition: border-color 0.3s, box-shadow 0.3s;
229
+ box-shadow: var(--glow);
230
+ }
231
+ .search-wrap:focus-within {
232
+ border-color: var(--cyan);
233
+ box-shadow: 0 0 40px rgba(0,229,255,0.25);
234
+ }
235
+
236
+ .search-icon { color:var(--text3); font-size:18px; flex-shrink:0; }
237
+
238
+ .search-wrap input {
239
+ flex:1;
240
+ background:transparent;
241
+ border:none;
242
+ outline:none;
243
+ color:var(--text);
244
+ font-family:'Tajawal',sans-serif;
245
+ font-size:18px;
246
+ direction:rtl;
247
+ }
248
+ .search-wrap input::placeholder { color:var(--text3); }
249
+
250
+ .search-btn {
251
+ background: linear-gradient(135deg, var(--cyan), var(--cyan2));
252
+ border:none;
253
+ border-radius:12px;
254
+ padding:13px 28px;
255
+ color:#000;
256
+ font-family:'Tajawal',sans-serif;
257
+ font-size:16px;
258
+ font-weight:700;
259
+ cursor:pointer;
260
+ transition:transform 0.15s, opacity 0.2s;
261
+ white-space:nowrap;
262
+ display:flex;
263
+ align-items:center;
264
+ gap:8px;
265
+ }
266
+ .search-btn:hover { transform:scale(0.97); opacity:0.9; }
267
+ .search-btn.loading { opacity:0.7; cursor:wait; }
268
+
269
+ .search-tags {
270
+ display:flex;
271
+ flex-wrap:wrap;
272
+ gap:8px;
273
+ justify-content:center;
274
+ margin-top:20px;
275
+ animation: fadeUp 0.6s 0.4s ease both;
276
+ }
277
+ .tag {
278
+ background: var(--bg3);
279
+ border: 1px solid var(--border);
280
+ border-radius:100px;
281
+ padding:6px 14px;
282
+ font-size:13px;
283
+ color:var(--text2);
284
+ cursor:pointer;
285
+ transition:all 0.2s;
286
+ }
287
+ .tag:hover { border-color:var(--cyan2); color:var(--cyan); background:rgba(0,229,255,0.05); }
288
+
289
+ .hero-stats {
290
+ display:flex;
291
+ gap:32px;
292
+ margin-top:48px;
293
+ animation: fadeUp 0.6s 0.5s ease both;
294
+ }
295
+ .stat { text-align:center; }
296
+ .stat-num { font-size:24px; font-weight:700; color:var(--cyan); }
297
+ .stat-label { font-size:12px; color:var(--text3); margin-top:2px; }
298
+
299
+ @keyframes fadeUp { from{opacity:0;transform:translateY(20px)} to{opacity:1;transform:translateY(0)} }
300
+
301
+ /* RESULTS PAGE */
302
+ #results-page {
303
+ position:relative;
304
+ z-index:10;
305
+ display:none;
306
+ padding:24px;
307
+ max-width:1100px;
308
+ margin:0 auto;
309
+ }
310
+
311
+ .results-meta {
312
+ font-size:13px;
313
+ color:var(--text3);
314
+ margin-bottom:20px;
315
+ padding-bottom:16px;
316
+ border-bottom: 1px solid var(--border);
317
+ display:flex;
318
+ align-items:center;
319
+ gap:8px;
320
+ }
321
+ .results-meta .count { color:var(--cyan); font-weight:600; }
322
+
323
+ .results-grid {
324
+ display:grid;
325
+ grid-template-columns: 1fr 320px;
326
+ gap:24px;
327
+ }
328
+
329
+ .results-main { display:flex; flex-direction:column; gap:16px; }
330
+
331
+ /* AI Answer */
332
+ .ai-answer {
333
+ background: linear-gradient(135deg, rgba(0,229,255,0.05), rgba(124,58,237,0.05));
334
+ border: 1px solid var(--border2);
335
+ border-radius:var(--r);
336
+ padding:20px;
337
+ margin-bottom:8px;
338
+ }
339
+ .ai-answer-header {
340
+ display:flex;
341
+ align-items:center;
342
+ gap:10px;
343
+ margin-bottom:12px;
344
+ }
345
+ .ai-badge {
346
+ background: linear-gradient(135deg, var(--cyan), var(--purple));
347
+ border-radius:8px;
348
+ padding:4px 10px;
349
+ font-size:12px;
350
+ font-weight:700;
351
+ color:#fff;
352
+ font-family:'Space Grotesk',sans-serif;
353
+ }
354
+ .ai-answer p {
355
+ font-size:15px;
356
+ line-height:1.7;
357
+ color:var(--text2);
358
+ }
359
+
360
+ /* Result Card */
361
+ .result-card {
362
+ background: var(--bg2);
363
+ border: 1px solid var(--border);
364
+ border-radius:var(--r);
365
+ padding:18px 20px;
366
+ transition: border-color 0.2s, transform 0.2s, box-shadow 0.2s;
367
+ animation: fadeUp 0.4s ease both;
368
+ cursor:pointer;
369
+ }
370
+ .result-card:hover {
371
+ border-color: var(--border2);
372
+ transform:translateY(-2px);
373
+ box-shadow: 0 8px 24px rgba(0,0,0,0.3);
374
+ }
375
+
376
+ .result-source {
377
+ display:flex;
378
+ align-items:center;
379
+ gap:8px;
380
+ margin-bottom:8px;
381
+ }
382
+ .favicon {
383
+ width:16px; height:16px;
384
+ border-radius:3px;
385
+ object-fit:cover;
386
+ background:var(--bg4);
387
+ }
388
+ .source-domain {
389
+ font-size:12px;
390
+ color:var(--text3);
391
+ }
392
+ .result-score {
393
+ margin-right:auto;
394
+ font-size:11px;
395
+ background:rgba(0,229,255,0.08);
396
+ color:var(--cyan2);
397
+ border-radius:100px;
398
+ padding:2px 8px;
399
+ font-family:'Space Grotesk',sans-serif;
400
+ }
401
+
402
+ .result-title {
403
+ font-size:17px;
404
+ font-weight:600;
405
+ color:var(--text);
406
+ margin-bottom:6px;
407
+ line-height:1.4;
408
+ text-decoration:none;
409
+ display:block;
410
+ transition:color 0.2s;
411
+ }
412
+ .result-title:hover { color:var(--cyan); }
413
+
414
+ .result-snippet {
415
+ font-size:14px;
416
+ color:var(--text2);
417
+ line-height:1.6;
418
+ }
419
+
420
+ .result-date {
421
+ font-size:12px;
422
+ color:var(--text3);
423
+ margin-top:8px;
424
+ }
425
+
426
+ /* Sidebar */
427
+ .results-sidebar { display:flex; flex-direction:column; gap:16px; }
428
+
429
+ .sidebar-card {
430
+ background: var(--bg2);
431
+ border: 1px solid var(--border);
432
+ border-radius:var(--r);
433
+ padding:18px;
434
+ }
435
+ .sidebar-title {
436
+ font-size:13px;
437
+ font-weight:700;
438
+ color:var(--text3);
439
+ text-transform:uppercase;
440
+ letter-spacing:1px;
441
+ margin-bottom:14px;
442
+ display:flex;
443
+ align-items:center;
444
+ gap:8px;
445
+ }
446
+ .sidebar-title::before { content:''; width:3px; height:14px; background:var(--cyan); border-radius:2px; display:inline-block; }
447
+
448
+ /* Images grid */
449
+ .images-grid {
450
+ display:grid;
451
+ grid-template-columns:1fr 1fr;
452
+ gap:8px;
453
+ }
454
+ .img-thumb {
455
+ border-radius:8px;
456
+ overflow:hidden;
457
+ aspect-ratio:16/9;
458
+ background:var(--bg4);
459
+ }
460
+ .img-thumb img {
461
+ width:100%; height:100%;
462
+ object-fit:cover;
463
+ transition:transform 0.3s;
464
+ cursor:pointer;
465
+ }
466
+ .img-thumb img:hover { transform:scale(1.05); }
467
+
468
+ /* Related searches */
469
+ .related-item {
470
+ display:flex;
471
+ align-items:center;
472
+ gap:8px;
473
+ padding:8px 0;
474
+ border-bottom:1px solid var(--border);
475
+ cursor:pointer;
476
+ color:var(--text2);
477
+ font-size:14px;
478
+ transition:color 0.2s;
479
+ }
480
+ .related-item:last-child { border-bottom:none; }
481
+ .related-item:hover { color:var(--cyan); }
482
+ .related-item::before { content:'↗'; font-size:12px; color:var(--text3); }
483
+
484
+ /* Loading spinner */
485
+ .spinner {
486
+ display:flex;
487
+ align-items:center;
488
+ justify-content:center;
489
+ padding:60px;
490
+ flex-direction:column;
491
+ gap:16px;
492
+ }
493
+ .spin {
494
+ width:40px; height:40px;
495
+ border:3px solid var(--border);
496
+ border-top-color:var(--cyan);
497
+ border-radius:50%;
498
+ animation:spin 0.8s linear infinite;
499
+ }
500
+ @keyframes spin { to{transform:rotate(360deg)} }
501
+ .spin-text { color:var(--text3); font-size:14px; }
502
+
503
+ /* Footer */
504
+ footer {
505
+ position:relative;
506
+ z-index:10;
507
+ text-align:center;
508
+ padding:24px;
509
+ color:var(--text3);
510
+ font-size:13px;
511
+ border-top:1px solid var(--border);
512
+ margin-top:40px;
513
+ }
514
+ footer span { color:var(--cyan); }
515
+
516
+ /* Error */
517
+ .error-box {
518
+ background: rgba(255,107,0,0.08);
519
+ border:1px solid rgba(255,107,0,0.2);
520
+ border-radius:var(--r);
521
+ padding:20px;
522
+ text-align:center;
523
+ color:var(--orange2);
524
+ }
525
+
526
+ /* Responsive */
527
+ @media(max-width:768px) {
528
+ .results-grid { grid-template-columns:1fr; }
529
+ .results-sidebar { display:none; }
530
+ .header-search { display:none; }
531
+ .hero-stats { gap:20px; }
532
+ }
533
+ </style>
534
+ </head>
535
+ <body>
536
+
537
+ <div class="blob blob1"></div>
538
+ <div class="blob blob2"></div>
539
+
540
+ <!-- HEADER -->
541
+ <header id="site-header">
542
+ <a class="logo" href="#" onclick="showHero()">
543
+ <div class="logo-icon">🏄</div>
544
+ <div>
545
+ <div class="logo-text">Surf<span>GO</span>!</div>
546
+ <div class="logo-by">by AnesNT</div>
547
+ </div>
548
+ </a>
549
+
550
+ <div class="header-search" id="header-search" style="display:none">
551
+ <input type="text" id="header-input" placeholder="ابحث في SurfGO..." onkeydown="if(event.key==='Enter')doSearch(this.value)">
552
+ <button onclick="doSearch(document.getElementById('header-input').value)">🔍 بحث</button>
553
+ </div>
554
+
555
+ <nav class="nav-links">
556
+ <a class="active" onclick="setFilter('all')">كل شيء</a>
557
+ <a onclick="setFilter('news')">أخبار</a>
558
+ <a onclick="setFilter('images')">صور</a>
559
+ <a onclick="setFilter('web')">ويب</a>
560
+ </nav>
561
+ </header>
562
+
563
+ <!-- HERO -->
564
+ <section id="hero">
565
+ <div class="hero-badge">محرك البحث الذكي من AnesNT</div>
566
+
567
+ <h1 class="hero-title">
568
+ <span class="surf">Surf</span><span class="go">GO</span><span class="bang">!</span>
569
+ </h1>
570
+ <p class="hero-sub">ابحث بذكاء · اكتشف أسرع · انطلق أبعد</p>
571
+
572
+ <div class="search-box">
573
+ <div class="search-wrap">
574
+ <span class="search-icon">🔍</span>
575
+ <input type="text" id="hero-input" placeholder="عمّ تبحث اليوم؟" autofocus
576
+ onkeydown="if(event.key==='Enter')doSearch(this.value)">
577
+ <button class="search-btn" id="search-btn" onclick="doSearch(document.getElementById('hero-input').value)">
578
+ <span>ابحث</span>
579
+ <span>→</span>
580
+ </button>
581
+ </div>
582
+
583
+ <div class="search-tags">
584
+ <span class="tag" onclick="quickSearch('ذكاء اصطناعي 2025')">🤖 ذكاء اصطناعي</span>
585
+ <span class="tag" onclick="quickSearch('برمجة Python')">💻 برمجة</span>
586
+ <span class="tag" onclick="quickSearch('أخبار التقنية')">📡 تقنية</span>
587
+ <span class="tag" onclick="quickSearch('تعلم الآلة')">🧠 تعلم الآلة</span>
588
+ <span class="tag" onclick="quickSearch('HuggingFace Spaces')">🤗 HuggingFace</span>
589
+ </div>
590
+ </div>
591
+
592
+ <div class="hero-stats">
593
+ <div class="stat">
594
+ <div class="stat-num">20+</div>
595
+ <div class="stat-label">نتيجة لكل بحث</div>
596
+ </div>
597
+ <div class="stat">
598
+ <div class="stat-num">AI</div>
599
+ <div class="stat-label">إجابة ذكية</div>
600
+ </div>
601
+ <div class="stat">
602
+ <div class="stat-num">⚡</div>
603
+ <div class="stat-label">نتائج فورية</div>
604
+ </div>
605
+ </div>
606
+ </section>
607
+
608
+ <!-- RESULTS PAGE -->
609
+ <div id="results-page">
610
+ <div class="results-meta">
611
+ <span>نتائج بحث عن:</span>
612
+ <strong id="query-display" style="color:var(--text)"></strong>
613
+ <span>·</span>
614
+ <span class="count" id="results-count">0</span>
615
+ <span>نتيجة</span>
616
+ <span>·</span>
617
+ <span id="results-time"></span>
618
+ </div>
619
+ <div id="results-content"></div>
620
+ </div>
621
+
622
+ <footer>
623
+ <p>SurfGO! &copy; 2025 — صُنع بـ ❤️ بواسطة <span>AnesNT</span> · مدعوم بـ Tavily AI</p>
624
+ </footer>
625
+
626
+ <script>
627
+ const TAVILY_KEY = "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";
628
+ let currentFilter = 'all';
629
+ let lastQuery = '';
630
+
631
+ function setFilter(f) {
632
+ currentFilter = f;
633
+ document.querySelectorAll('.nav-links a').forEach(a => a.classList.remove('active'));
634
+ event.target.classList.add('active');
635
+ if (lastQuery) doSearch(lastQuery);
636
+ }
637
+
638
+ function quickSearch(q) {
639
+ document.getElementById('hero-input').value = q;
640
+ doSearch(q);
641
+ }
642
+
643
+ function showHero() {
644
+ document.getElementById('hero').style.display = 'flex';
645
+ document.getElementById('results-page').style.display = 'none';
646
+ document.getElementById('header-search').style.display = 'none';
647
+ }
648
+
649
+ async function doSearch(query) {
650
+ query = query.trim();
651
+ if (!query) return;
652
+
653
+ lastQuery = query;
654
+
655
+ // Switch to results view
656
+ document.getElementById('hero').style.display = 'none';
657
+ document.getElementById('results-page').style.display = 'block';
658
+ document.getElementById('header-search').style.display = 'flex';
659
+ document.getElementById('header-input').value = query;
660
+ document.getElementById('query-display').textContent = query;
661
+
662
+ const startTime = Date.now();
663
+
664
+ document.getElementById('results-content').innerHTML = `
665
+ <div class="spinner">
666
+ <div class="spin"></div>
667
+ <div class="spin-text">يبحث SurfGO في الويب...</div>
668
+ </div>`;
669
+
670
+ try {
671
+ const response = await fetch('https://api.tavily.com/search', {
672
+ method: 'POST',
673
+ headers: { 'Content-Type': 'application/json' },
674
+ body: JSON.stringify({
675
+ api_key: TAVILY_KEY,
676
+ query: query,
677
+ include_answer: "basic",
678
+ search_depth: "advanced",
679
+ max_results: 20,
680
+ time_range: currentFilter === 'news' ? 'day' : null,
681
+ include_images: true,
682
+ include_image_descriptions: true,
683
+ include_favicon: true
684
+ })
685
+ });
686
+
687
+ const data = await response.json();
688
+ const elapsed = ((Date.now() - startTime) / 1000).toFixed(2);
689
+
690
+ renderResults(data, elapsed);
691
+ } catch (err) {
692
+ document.getElementById('results-content').innerHTML = `
693
+ <div class="error-box">
694
+ <p>⚠️ حدث خطأ أثناء البحث. تحقق من مفتاح API أو اتصالك بالإنترنت.</p>
695
+ <p style="margin-top:8px;font-size:13px;opacity:0.7">${err.message}</p>
696
+ </div>`;
697
+ }
698
+ }
699
+
700
+ function renderResults(data, elapsed) {
701
+ const results = data.results || [];
702
+ const images = data.images || [];
703
+ const answer = data.answer || '';
704
+
705
+ document.getElementById('results-count').textContent = results.length;
706
+ document.getElementById('results-time').textContent = `${elapsed} ثانية`;
707
+
708
+ // Related suggestions
709
+ const relatedTerms = generateRelated(lastQuery);
710
+
711
+ document.getElementById('results-content').innerHTML = `
712
+ <div class="results-grid">
713
+ <div class="results-main">
714
+ ${answer ? `
715
+ <div class="ai-answer">
716
+ <div class="ai-answer-header">
717
+ <div class="ai-badge">✦ AI Answer</div>
718
+ <span style="font-size:13px;color:var(--text3)">إجابة ذكية</span>
719
+ </div>
720
+ <p>${answer}</p>
721
+ </div>` : ''}
722
+
723
+ ${results.length === 0 ? `<div class="error-box"><p>لا توجد نتائج لهذا البحث.</p></div>` : ''}
724
+
725
+ ${results.map((r, i) => `
726
+ <div class="result-card" style="animation-delay:${i * 0.04}s" onclick="window.open('${r.url}','_blank')">
727
+ <div class="result-source">
728
+ ${r.favicon ? `<img class="favicon" src="${r.favicon}" onerror="this.style.display='none'">` : ''}
729
+ <span class="source-domain">${getDomain(r.url)}</span>
730
+ ${r.score ? `<span class="result-score">${(r.score * 100).toFixed(0)}%</span>` : ''}
731
+ </div>
732
+ <a class="result-title" href="${r.url}" target="_blank" onclick="event.stopPropagation()">${r.title || 'بدون عنوان'}</a>
733
+ <p class="result-snippet">${(r.content || '').slice(0, 200)}${r.content && r.content.length > 200 ? '...' : ''}</p>
734
+ ${r.published_date ? `<div class="result-date">📅 ${r.published_date}</div>` : ''}
735
+ </div>`).join('')}
736
+ </div>
737
+
738
+ <div class="results-sidebar">
739
+ ${images.length > 0 ? `
740
+ <div class="sidebar-card">
741
+ <div class="sidebar-title">صور</div>
742
+ <div class="images-grid">
743
+ ${images.slice(0,4).map(img => `
744
+ <div class="img-thumb">
745
+ <img src="${typeof img === 'string' ? img : img.url}"
746
+ alt="${typeof img === 'object' ? (img.description || '') : ''}"
747
+ loading="lazy"
748
+ onerror="this.parentElement.style.display='none'"
749
+ onclick="window.open('${typeof img === 'string' ? img : img.url}','_blank')">
750
+ </div>`).join('')}
751
+ </div>
752
+ </div>` : ''}
753
+
754
+ <div class="sidebar-card">
755
+ <div class="sidebar-title">بحث مقترح</div>
756
+ ${relatedTerms.map(t => `
757
+ <div class="related-item" onclick="quickSearch('${t}')">${t}</div>`).join('')}
758
+ </div>
759
+
760
+ <div class="sidebar-card" style="background:linear-gradient(135deg,rgba(0,229,255,0.05),rgba(124,58,237,0.05));border-color:rgba(0,229,255,0.2)">
761
+ <div class="sidebar-title">SurfGO! Stats</div>
762
+ <div style="display:flex;flex-direction:column;gap:10px">
763
+ <div style="display:flex;justify-content:space-between;align-items:center">
764
+ <span style="font-size:13px;color:var(--text2)">نتائج البحث</span>
765
+ <span style="color:var(--cyan);font-weight:700">${results.length}</span>
766
+ </div>
767
+ <div style="display:flex;justify-content:space-between;align-items:center">
768
+ <span style="font-size:13px;color:var(--text2)">الصور</span>
769
+ <span style="color:var(--cyan);font-weight:700">${images.length}</span>
770
+ </div>
771
+ <div style="display:flex;justify-content:space-between;align-items:center">
772
+ <span style="font-size:13px;color:var(--text2)">وقت البحث</span>
773
+ <span style="color:var(--cyan);font-weight:700">${elapsed}s</span>
774
+ </div>
775
+ </div>
776
+ </div>
777
+ </div>
778
+ </div>`;
779
+ }
780
+
781
+ function getDomain(url) {
782
+ try { return new URL(url).hostname.replace('www.',''); } catch { return url; }
783
+ }
784
+
785
+ function generateRelated(q) {
786
+ return [
787
+ q + ' 2025',
788
+ q + ' شرح بالعربي',
789
+ 'أفضل ' + q,
790
+ 'كيف ' + q,
791
+ q + ' مجاناً',
792
+ ];
793
+ }
794
+ </script>
795
+ </body>
796
+ </html>
indexer.py DELETED
@@ -1,119 +0,0 @@
1
- import sqlite3
2
- import hashlib
3
- from datetime import datetime
4
-
5
- def create_database():
6
- """إنشاء قاعدة البيانات وجداولها"""
7
- conn = sqlite3.connect('news_database.db')
8
- cursor = conn.cursor()
9
-
10
- # جدول الأخبار
11
- cursor.execute('''
12
- CREATE TABLE IF NOT EXISTS news (
13
- id TEXT PRIMARY KEY,
14
- title TEXT NOT NULL,
15
- link TEXT UNIQUE,
16
- summary TEXT,
17
- source TEXT,
18
- date TEXT,
19
- search_terms TEXT
20
- )
21
- ''')
22
-
23
- # جدول للصور
24
- cursor.execute('''
25
- CREATE TABLE IF NOT EXISTS images (
26
- id TEXT PRIMARY KEY,
27
- title TEXT,
28
- image_url TEXT,
29
- source_url TEXT,
30
- thumbnail TEXT,
31
- date TEXT,
32
- search_terms TEXT
33
- )
34
- ''')
35
-
36
- # جدول للفيديوهات
37
- cursor.execute('''
38
- CREATE TABLE IF NOT EXISTS videos (
39
- id TEXT PRIMARY KEY,
40
- title TEXT,
41
- video_url TEXT,
42
- thumbnail TEXT,
43
- duration TEXT,
44
- source TEXT,
45
- date TEXT,
46
- search_terms TEXT
47
- )
48
- ''')
49
-
50
- conn.commit()
51
- conn.close()
52
- print("✅ تم إنشاء قاعدة البيانات بنجاح")
53
-
54
- def save_news_to_db(news_list):
55
- """حفظ الأخبار في قاعدة البيانات"""
56
- conn = sqlite3.connect('news_database.db')
57
- cursor = conn.cursor()
58
- count = 0
59
-
60
- for news in news_list:
61
- # إنشاء معرف فريد للخبر
62
- news_id = hashlib.md5(news['link'].encode()).hexdigest()
63
-
64
- # تحضير كلمات البحث
65
- search_terms = ' '.join([news['title'], news['summary'], news['source']]).lower()
66
-
67
- try:
68
- cursor.execute('''
69
- INSERT OR REPLACE INTO news
70
- (id, title, link, summary, source, date, search_terms)
71
- VALUES (?, ?, ?, ?, ?, ?, ?)
72
- ''', (news_id, news['title'], news['link'], news['summary'],
73
- news['source'], news['date'], search_terms))
74
- count += 1
75
- except Exception as e:
76
- print(f"خطأ في حفظ الخبر: {e}")
77
-
78
- conn.commit()
79
- conn.close()
80
- print(f"✅ تم حفظ {count} خبر في قاعدة البيانات")
81
- return count
82
-
83
- def save_sample_images():
84
- """حفظ صور تجريبية"""
85
- conn = sqlite3.connect('news_database.db')
86
- cursor = conn.cursor()
87
-
88
- sample_images = [
89
- {
90
- 'title': 'صورة تجريبية 1',
91
- 'image_url': 'https://picsum.photos/id/1/200/150',
92
- 'thumbnail': 'https://picsum.photos/id/1/100/75',
93
- 'source_url': '#'
94
- },
95
- {
96
- 'title': 'صورة تجريبية 2',
97
- 'image_url': 'https://picsum.photos/id/2/200/150',
98
- 'thumbnail': 'https://picsum.photos/id/2/100/75',
99
- 'source_url': '#'
100
- }
101
- ]
102
-
103
- for img in sample_images:
104
- img_id = hashlib.md5(img['image_url'].encode()).hexdigest()
105
- search_terms = img['title'].lower()
106
-
107
- cursor.execute('''
108
- INSERT OR IGNORE INTO images
109
- (id, title, image_url, thumbnail, source_url, date, search_terms)
110
- VALUES (?, ?, ?, ?, ?, ?, ?)
111
- ''', (img_id, img['title'], img['image_url'], img['thumbnail'],
112
- img['source_url'], datetime.now().strftime('%Y-%m-%d'), search_terms))
113
-
114
- conn.commit()
115
- conn.close()
116
- print("✅ تم حفظ صور تجريبية")
117
-
118
- if __name__ == '__main__':
119
- create_database()