testrro commited on
Commit
b87e400
·
verified ·
1 Parent(s): eecab6f

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +594 -0
  2. requirements.txt +6 -0
app.py ADDED
@@ -0,0 +1,594 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import pandas as pd
4
+ from datetime import datetime
5
+ import random
6
+ from collections import defaultdict
7
+ import math
8
+ import os
9
+ import traceback
10
+ import json
11
+ from fastapi import FastAPI, Request
12
+ from gradio.routes import App
13
+
14
+ # ==================== কনফিগারেশন ====================
15
+ CONFIG = {
16
+ "HISTORY_LIMIT": 1000,
17
+ "PINK_THRESHOLD": 3.0,
18
+ "BIG_PINK_THRESHOLD": 5.0,
19
+ "MAX_PREDICTION": 10000.0, # সর্বোচ্চ প্রেডিকশন সীমা (খুব বড় করা হয়েছে)
20
+ }
21
+
22
+ # ==================== ডেটা লোড ও টাইম-ভিত্তিক পরিসংখ্যান ====================
23
+ TIME_STATS = None
24
+
25
+ def load_time_statistics():
26
+ global TIME_STATS
27
+ try:
28
+ # ডেটা ফাইলের পাথ
29
+ data_path = 'data/aviator_Rounds_history_scrp.xlsx'
30
+ if os.path.exists(data_path):
31
+ df = pd.read_excel(data_path, sheet_name='scraping rounds crash')
32
+ df = df[['ROUNDS', 'TIME ROUND']].dropna()
33
+ df['multiplier'] = pd.to_numeric(df['ROUNDS'], errors='coerce')
34
+ df = df.dropna()
35
+ df['hour'] = pd.to_datetime(df['TIME ROUND'], format='%H:%M').dt.hour
36
+
37
+ stats = df.groupby('hour')['multiplier'].agg(['mean', 'std', 'count']).to_dict('index')
38
+ for h in range(24):
39
+ if h not in stats:
40
+ stats[h] = {'mean': 1.8, 'std': 1.0, 'count': 0}
41
+ TIME_STATS = stats
42
+ print(f"✅ সময় পরিসংখ্যান লোড হয়েছে। মোট রেকর্ড: {len(df)}")
43
+ else:
44
+ print("⚠️ এক্সেল ফাইল পাওয়া যায়নি। ডিফল্ট পরিসংখ্যান ব্যবহার করা হবে।")
45
+ TIME_STATS = {h: {'mean': 1.8, 'std': 1.0, 'count': 100} for h in range(24)}
46
+ except Exception as e:
47
+ print(f"ডেটা লোড করতে সমস্যা: {e}")
48
+ TIME_STATS = {h: {'mean': 1.8, 'std': 1.0, 'count': 100} for h in range(24)}
49
+
50
+ load_time_statistics()
51
+
52
+ # ==================== স্ট্যাটিস্টিক্যাল মডেল V1-V5 ====================
53
+
54
+ class StatisticalModelV1:
55
+ """V1: বেসিক স্ট্যাটিস্টিক্যাল + আউটলায়ার রিমুভাল"""
56
+ def predict(self, history):
57
+ recent = history[:15]
58
+ if len(recent) < 3:
59
+ return {'prediction': 1.5, 'confidence': 0.3}
60
+
61
+ # আউটলায়ার রিমুভাল (IQR)
62
+ q1, q3 = np.percentile(recent, [25, 75])
63
+ iqr = q3 - q1
64
+ filtered = [x for x in recent if (q1 - 1.5*iqr) <= x <= (q3 + 1.5*iqr)]
65
+ if len(filtered) < 3:
66
+ filtered = recent
67
+
68
+ # ওয়েটেড ট্রেন্ড
69
+ x = np.arange(len(filtered))
70
+ weights = np.linspace(1.5, 0.5, len(filtered))
71
+ weights /= weights.sum()
72
+
73
+ weighted_mean_x = np.average(x, weights=weights)
74
+ weighted_mean_y = np.average(filtered, weights=weights)
75
+
76
+ numerator = np.sum(weights * (x - weighted_mean_x) * (filtered - weighted_mean_y))
77
+ denominator = np.sum(weights * (x - weighted_mean_x)**2)
78
+ trend = numerator / denominator if denominator != 0 else 0
79
+
80
+ prediction = np.median(filtered) + trend * 1.5
81
+
82
+ # কনফিডেন্স
83
+ cv = np.std(filtered) / (np.mean(filtered) + 0.1)
84
+ confidence = min(0.85, 0.5 + len(filtered)/len(recent)*0.3 - cv*0.2)
85
+
86
+ return {'prediction': float(prediction), 'confidence': float(confidence)}
87
+
88
+ class StatisticalModelV2:
89
+ """V2: মাল্টি-টাইমফ্রেম"""
90
+ def predict(self, history):
91
+ timeframes = {'short': history[:5], 'medium': history[:10], 'long': history[:20]}
92
+ preds, confs = [], []
93
+
94
+ for name, data in timeframes.items():
95
+ if len(data) < 3:
96
+ continue
97
+
98
+ ma_3 = np.mean(data[:3]) if len(data)>=3 else np.mean(data)
99
+ ma_5 = np.mean(data[:5]) if len(data)>=5 else ma_3
100
+
101
+ ema = data[0]
102
+ alpha = 0.3
103
+ for v in data[1:]:
104
+ ema = alpha*v + (1-alpha)*ema
105
+
106
+ x = np.arange(len(data))
107
+ trend = np.polyfit(x, data, 1)[0]
108
+
109
+ base = np.mean([ma_3, ma_5, ema])
110
+ preds.append(base + trend * len(data) / 10)
111
+ confs.append(min(0.9, 0.5 + len(data)/40))
112
+
113
+ if not preds:
114
+ return {'prediction': 1.5, 'confidence': 0.3}
115
+
116
+ weights = {'short':0.5, 'medium':0.3, 'long':0.2}
117
+ final_pred = 0
118
+ total_weight = 0
119
+
120
+ for i, name in enumerate(timeframes.keys()):
121
+ if i < len(preds):
122
+ w = weights.get(name, 0.2) * confs[i]
123
+ final_pred += preds[i] * w
124
+ total_weight += w
125
+
126
+ final_pred /= total_weight if total_weight else 1
127
+ confidence = np.mean(confs) * 0.9
128
+
129
+ return {'prediction': float(final_pred), 'confidence': float(confidence)}
130
+
131
+ class StatisticalModelV3:
132
+ """V3: সাইকেল ডিটেকশন"""
133
+ def detect_cycles(self, history):
134
+ if len(history) < 10:
135
+ return None
136
+
137
+ cycles = []
138
+ for period in range(3, 7):
139
+ corrs = []
140
+ for i in range(len(history) - period*2):
141
+ seg1 = history[i:i+period]
142
+ seg2 = history[i+period:i+period*2]
143
+ if len(seg1) == len(seg2):
144
+ corr = np.corrcoef(seg1, seg2)[0,1]
145
+ if not np.isnan(corr):
146
+ corrs.append(abs(corr))
147
+ if corrs and np.mean(corrs) > 0.6:
148
+ cycles.append({'period': period, 'strength': float(np.mean(corrs))})
149
+
150
+ return cycles if cycles else None
151
+
152
+ def predict(self, history):
153
+ recent = history[:20]
154
+ cycles = self.detect_cycles(recent)
155
+ cycle_pred = None
156
+
157
+ if cycles:
158
+ best = max(cycles, key=lambda x: x['strength'])
159
+ period = best['period']
160
+ if len(recent) > period:
161
+ next_val = recent[period:period+1]
162
+ if next_val:
163
+ cycle_pred = next_val[0] * (1 + best['strength'] * 0.1)
164
+
165
+ base_pred = np.median(recent)
166
+ if cycle_pred:
167
+ base_pred = (base_pred + cycle_pred) / 2
168
+
169
+ # ক্যাপ সরিয়ে দেওয়া হয়েছে - এখন যেকোনো মান হতে পারে
170
+ prediction = max(1.05, base_pred)
171
+
172
+ confidence = min(0.9, 0.5 + len(recent)/40 + (0.15 if cycles else 0))
173
+
174
+ return {'prediction': float(prediction), 'confidence': float(confidence)}
175
+
176
+ class StatisticalModelV4:
177
+ """V4: এডাপটিভ লার্নিং"""
178
+ def __init__(self):
179
+ self.performance = []
180
+ self.bias = 0
181
+ self.volatility_regime = 'normal'
182
+
183
+ def detect_volatility(self, history):
184
+ if len(history) < 10:
185
+ return 'normal'
186
+ recent_vol = np.std(history[:5])
187
+ long_vol = np.std(history[:20]) if len(history)>=20 else recent_vol
188
+
189
+ if recent_vol > long_vol * 1.5:
190
+ return 'high'
191
+ elif recent_vol < long_vol * 0.5:
192
+ return 'low'
193
+ else:
194
+ return 'normal'
195
+
196
+ def predict(self, history):
197
+ recent = history[:15]
198
+ self.volatility_regime = self.detect_volatility(history)
199
+
200
+ mean_val, median_val = np.mean(recent), np.median(recent)
201
+
202
+ x = np.arange(len(recent))
203
+ weights = np.exp(-0.2 * x)
204
+ weights /= weights.sum()
205
+
206
+ weighted_mean_x = np.average(x, weights=weights)
207
+ weighted_mean_y = np.average(recent, weights=weights)
208
+
209
+ numerator = np.sum(weights * (x - weighted_mean_x) * (recent - weighted_mean_y))
210
+ denominator = np.sum(weights * (x - weighted_mean_x)**2)
211
+ trend = numerator / denominator if denominator != 0 else 0
212
+
213
+ preds = {'mean': mean_val, 'median': median_val, 'trend': median_val + trend * len(recent) * 0.5}
214
+ w = {'mean': 0.3, 'median': 0.4, 'trend': 0.3}
215
+
216
+ if self.volatility_regime == 'high':
217
+ w['median'] *= 1.5
218
+ elif self.volatility_regime == 'low':
219
+ w['trend'] *= 1.3
220
+
221
+ total = sum(w.values())
222
+ for k in w:
223
+ w[k] /= total
224
+
225
+ prediction = sum(preds[k] * w[k] for k in preds) + self.bias
226
+
227
+ confidence = 0.5 + len(recent)/30
228
+ if self.volatility_regime == 'high':
229
+ confidence *= 0.8
230
+ elif self.volatility_regime == 'low':
231
+ confidence *= 1.2
232
+
233
+ if self.performance:
234
+ recent_perf = np.mean(self.performance[-10:]) if len(self.performance)>=10 else np.mean(self.performance)
235
+ confidence *= (1 + recent_perf * 0.1)
236
+
237
+ confidence = min(0.9, confidence)
238
+
239
+ # ক্যাপ সরিয়ে দেওয়া হয়েছে - এখন যেকোনো মান হতে পারে
240
+ return {'prediction': float(max(1.05, prediction)), 'confidence': float(confidence)}
241
+
242
+ def update(self, actual, predicted):
243
+ error = abs(actual - predicted) / actual
244
+ acc = max(0, 1 - error)
245
+ self.performance.append(acc)
246
+ if len(self.performance) > 100:
247
+ self.performance = self.performance[-100:]
248
+ self.bias += (actual - predicted) * 0.01
249
+
250
+ class StatisticalModelV5:
251
+ """V5: র‍্যান্ডম ফরেস্ট সিমুলেশন"""
252
+ def __init__(self):
253
+ self.n_estimators = 10
254
+
255
+ def predict(self, history):
256
+ if len(history) < 10:
257
+ return {'prediction': 1.5, 'confidence': 0.5}
258
+
259
+ recent = history[:10]
260
+ trees = []
261
+
262
+ for _ in range(self.n_estimators):
263
+ idx = np.random.choice(len(recent), size=len(recent), replace=True)
264
+ sample = [recent[i] for i in idx]
265
+ if np.random.random() > 0.5:
266
+ trees.append(np.mean(sample))
267
+ else:
268
+ trees.append(np.median(sample))
269
+
270
+ pred = float(np.mean(trees))
271
+ return {'prediction': pred, 'confidence': 0.7}
272
+
273
+ # ==================== V6 মডেল (টাইম-ভিত্তিক) ====================
274
+
275
+ class StatisticalModelV6:
276
+ """V6: টাইম-অফ-ডে অ্যাডজাস্টমেন্ট"""
277
+ def __init__(self, time_stats):
278
+ self.time_stats = time_stats
279
+
280
+ def predict(self, history, current_hour=None):
281
+ if current_hour is None:
282
+ current_hour = datetime.now().hour
283
+
284
+ stats = self.time_stats.get(current_hour, {'mean': 1.8, 'std': 1.0})
285
+ base_pred = np.median(history[:5]) if len(history)>=5 else 1.5
286
+
287
+ alpha = 0.3
288
+ prediction = base_pred * (1 - alpha) + stats['mean'] * alpha
289
+ confidence = min(0.85, 0.5 + stats.get('count', 100) / 500)
290
+
291
+ return {'prediction': float(prediction), 'confidence': float(confidence), 'hour': current_hour}
292
+
293
+ # ==================== এনসেম্বল প্রেডিক্টর ====================
294
+
295
+ class EnsemblePredictorV6:
296
+ def __init__(self, time_stats):
297
+ self.models = {
298
+ 'v1': StatisticalModelV1(),
299
+ 'v2': StatisticalModelV2(),
300
+ 'v3': StatisticalModelV3(),
301
+ 'v4': StatisticalModelV4(),
302
+ 'v5': StatisticalModelV5(),
303
+ 'v6': StatisticalModelV6(time_stats)
304
+ }
305
+ self.ensemble_weights = {'v1':0.2, 'v2':0.2, 'v3':0.15, 'v4':0.15, 'v5':0.15, 'v6':0.15}
306
+ self.performance = defaultdict(list)
307
+
308
+ def predict(self, history):
309
+ if len(history) < 5:
310
+ return self._default_prediction(f"মাত্র {len(history)}টি রাউন্ড, ৫টি প্রয়োজন")
311
+
312
+ current_hour = datetime.now().hour
313
+ preds = {}
314
+ confs = {}
315
+
316
+ for name, model in self.models.items():
317
+ try:
318
+ if name == 'v6':
319
+ res = model.predict(history, current_hour)
320
+ else:
321
+ res = model.predict(history)
322
+ preds[name] = res['prediction']
323
+ confs[name] = res.get('confidence', 0.5)
324
+ except Exception as e:
325
+ print(f"মডেল {name} এ সমস্যা: {e}")
326
+ preds[name] = 1.5
327
+ confs[name] = 0.3
328
+
329
+ # ওয়েট আপডেট
330
+ for name in self.ensemble_weights:
331
+ if name in self.performance and self.performance[name]:
332
+ recent_acc = np.mean(self.performance[name][-20:]) if len(self.performance[name])>=20 else np.mean(self.performance[name])
333
+ self.ensemble_weights[name] = 0.1 + recent_acc * 0.8
334
+
335
+ total = sum(self.ensemble_weights.values())
336
+ for name in self.ensemble_weights:
337
+ self.ensemble_weights[name] /= total
338
+
339
+ final_pred = 0
340
+ total_weight = 0
341
+ for name, pred in preds.items():
342
+ weight = self.ensemble_weights.get(name, 0.2) * confs[name]
343
+ final_pred += pred * weight
344
+ total_weight += weight
345
+
346
+ final_pred /= total_weight if total_weight else 1
347
+
348
+ # মার্কেট স্টেট
349
+ recent = history[:10]
350
+ vol = np.std(recent) / (np.mean(recent)+0.1)
351
+ if vol > 0.5:
352
+ state = "অস্থির 🌪️"
353
+ elif vol < 0.2:
354
+ state = "স্থিতিশীল ✨"
355
+ else:
356
+ state = "সাধারণ ➡️"
357
+
358
+ confidence = np.mean(list(confs.values())) * 0.9
359
+ if vol < 0.2:
360
+ confidence *= 1.1
361
+ elif vol > 0.5:
362
+ confidence *= 0.9
363
+ confidence = min(0.95, confidence)
364
+
365
+ # প্রেডিকশন ইন্টারভ্যাল
366
+ all_preds = list(preds.values())
367
+ std = np.std(all_preds) if len(all_preds)>1 else 0.2
368
+ spread = std * (2 - confidence)
369
+ spread = max(0.1, min(1.5, spread))
370
+ interval = (max(1.01, final_pred - spread/2), final_pred + spread/2)
371
+
372
+ # ডিসিশন
373
+ if final_pred > 3.0:
374
+ decision = "বড় 🚀"
375
+ elif final_pred > 1.8:
376
+ decision = "মাঝারি 💪"
377
+ else:
378
+ decision = "ছোট 🎯"
379
+
380
+ hour_stats = TIME_STATS.get(current_hour, {'mean':1.8, 'count':0})
381
+ time_info = f"বর্তমান ঘণ্টা: {current_hour}:00 – ঐতিহাসিক গড়: {hour_stats['mean']:.2f}x (ডাটা: {hour_stats['count']}টি)"
382
+
383
+ summary = (
384
+ f"🎯 **প্রেডিকশন ইন্টারভ্যাল**: {interval[0]:.2f}x – {interval[1]:.2f}x\n"
385
+ f"📊 **এক্সপেক্টেড মাল্টিপ্লায়ার**: {final_pred:.2f}x\n"
386
+ f"📈 **কনফিডেন্স**: {confidence*100:.1f}%\n"
387
+ f"⚡ **মার্কেট স্টেট**: {state}\n"
388
+ f"🎲 **ডিসিশন**: {decision}\n"
389
+ f"⏰ **টাইম ফিচার**: {time_info}\n"
390
+ f"📌 **ডাটা পয়েন্ট**: {len(history)}টি রাউন্ড"
391
+ )
392
+
393
+ return {
394
+ 'summary': summary,
395
+ 'prediction': final_pred,
396
+ 'interval': interval,
397
+ 'confidence': confidence,
398
+ 'decision': decision,
399
+ 'analysis': state,
400
+ 'hour': current_hour
401
+ }
402
+
403
+ def _default_prediction(self, msg):
404
+ return {
405
+ 'summary': f"⚠️ {msg}\n\n📊 ডিফল্ট প্রেডিকশন: 1.50x (কনফিডেন্স 30%)",
406
+ 'prediction': 1.5,
407
+ 'interval': (1.3, 1.7),
408
+ 'confidence': 0.3,
409
+ 'decision': 'ছোট 🎯',
410
+ 'analysis': 'অপ্রতুল ডাটা'
411
+ }
412
+
413
+ # ==================== অ্যাপ্লিকেশন ক্লাস ====================
414
+
415
+ class AviatorPredictorApp:
416
+ def __init__(self):
417
+ self.history = []
418
+ self.model = EnsemblePredictorV6(TIME_STATS)
419
+
420
+ def add_round(self, multiplier):
421
+ try:
422
+ # ইনপুট ভ্যালিডেশন
423
+ if multiplier is None:
424
+ return self.get_all_outputs(error="মাল্টিপ্লায়ার দেওয়া হয়নি")
425
+
426
+ # সংখ্যায় রূপান্তর
427
+ val = float(multiplier)
428
+
429
+ if val <= 0:
430
+ return self.get_all_outputs(error="ইনভ্যালিড মাল্টিপ্লায়ার (১.০ এর বেশি দিন)")
431
+
432
+ # ইতিহাসে যোগ করুন
433
+ self.history.insert(0, val)
434
+ if len(self.history) > CONFIG["HISTORY_LIMIT"]:
435
+ self.history = self.history[:CONFIG["HISTORY_LIMIT"]]
436
+
437
+ return self.get_all_outputs()
438
+
439
+ except ValueError:
440
+ return self.get_all_outputs(error=f"ইনভ্যালিড সংখ্যা: {multiplier}")
441
+ except Exception as e:
442
+ traceback.print_exc() # Hugging Face লগে প্রিন্ট হবে
443
+ return self.get_all_outputs(error=f"⚠️ ত্রুটি: {str(e)}")
444
+
445
+ def reset(self):
446
+ self.history = []
447
+ for _ in range(20):
448
+ self.history.append(round(random.uniform(1.0, 3.5), 2))
449
+ self.history.sort(reverse=True)
450
+ return self.get_all_outputs()
451
+
452
+ def get_all_outputs(self, error=None):
453
+ if error:
454
+ table = [[i+1, "?.??x"] for i in range(min(20, len(self.history)))] or [[1, "1.00x"]]
455
+ return [table, f"⚠️ {error}"]
456
+
457
+ try:
458
+ pred_result = self.model.predict(self.history)
459
+ table = [[i+1, f"{val:.2f}x"] for i, val in enumerate(self.history[:50])]
460
+ return [table, pred_result['summary']]
461
+ except Exception as e:
462
+ traceback.print_exc()
463
+ table = [[i+1, f"{val:.2f}x"] for i, val in enumerate(self.history[:50])]
464
+ return [table, f"⚠️ প্রেডিকশনে সমস্যা: {str(e)}"]
465
+
466
+ # ==================== কাস্টম CSS ====================
467
+
468
+ CUSTOM_CSS = """
469
+ .gradio-container {
470
+ background: #0a0a0f !important;
471
+ color: #ffffff !important;
472
+ font-family: 'Inter', sans-serif !important;
473
+ }
474
+ footer {visibility: hidden}
475
+ h1 {
476
+ color: #00d4ff !important;
477
+ text-align: center;
478
+ margin-bottom: 20px;
479
+ text-shadow: 0 0 10px #00d4ff;
480
+ }
481
+ .gr-box {
482
+ border: 1px solid #333 !important;
483
+ background: rgba(255,255,255,0.05) !important;
484
+ }
485
+ .gr-button-primary {
486
+ background: linear-gradient(135deg, #00d4ff, #0088ff) !important;
487
+ border: none !important;
488
+ }
489
+ .gr-button-secondary {
490
+ background: rgba(255,255,255,0.1) !important;
491
+ border: 1px solid #00d4ff !important;
492
+ margin-top: 20px !important;
493
+ }
494
+ .gr-dataframe {
495
+ background: rgba(255,255,255,0.05) !important;
496
+ }
497
+ """
498
+
499
+ # ==================== গ্র্যাডিও ইন্টারফেস ====================
500
+
501
+ predictor_app = AviatorPredictorApp()
502
+ predictor_app.reset()
503
+
504
+ with gr.Blocks(css=CUSTOM_CSS, theme='dark', title="AVOLD V6 Predictor") as demo:
505
+ gr.HTML("""
506
+ <div style="text-align: center; margin-bottom: 20px;">
507
+ <h1 style="color: #00d4ff; font-size: 48px; margin: 0;">✈️ AVOLD V6</h1>
508
+ <p style="color: #888; font-size: 14px;">সময়-ভিত্তিক এভিয়েটর প্রেডিক্টর – ৬টি মডেলের এনসেম্বল</p>
509
+ </div>
510
+ """)
511
+
512
+ with gr.Row():
513
+ inp = gr.Number(label="নতুন মাল্টিপ্লায়ার", value=1.0, step=0.1, minimum=1.0, maximum=None)
514
+ add_btn = gr.Button("➕ যোগ করুন", variant="primary")
515
+
516
+ prediction_box = gr.Textbox(label="🧠 প্রেডিকশন রিপোর্ট", lines=10, interactive=False)
517
+ rounds_table = gr.Dataframe(label="📜 শেষ ৫০ রাউন্ড", headers=["রাউন্ড", "মাল্টিপ্লায়ার"], row_count=10)
518
+ reset_btn = gr.Button("🔄 রিসেট ডাটা", variant="secondary")
519
+
520
+ add_btn.click(
521
+ fn=predictor_app.add_round,
522
+ inputs=inp,
523
+ outputs=[rounds_table, prediction_box]
524
+ )
525
+
526
+ reset_btn.click(
527
+ fn=predictor_app.reset,
528
+ outputs=[rounds_table, prediction_box]
529
+ )
530
+
531
+ demo.load(
532
+ fn=predictor_app.get_all_outputs,
533
+ outputs=[rounds_table, prediction_box]
534
+ )
535
+
536
+ # ==================== API এন্ডপয়েন্ট (ShareX-এর জন্য) ====================
537
+
538
+ @app.post("/api/add_crash")
539
+ async def add_crash_api(request: Request):
540
+ """
541
+ ShareX থেকে JSON ডাটা গ্রহণ করে ইতিহাসে যোগ করে
542
+ """
543
+ try:
544
+ data = await request.json()
545
+ crash_value = data.get("crash_value")
546
+
547
+ if crash_value is None:
548
+ # বিকল্প হিসেবে "value" বা "multiplier" চেক করা
549
+ crash_value = data.get("value") or data.get("multiplier")
550
+
551
+ if crash_value is None:
552
+ return {"status": "error", "message": "crash_value, value, অথবা multiplier প্রদান করুন"}
553
+
554
+ # OCR থেকে আনা টেক্সট ক্লিন করা (যেমন "2.45x" থেকে "2.45")
555
+ if isinstance(crash_value, str):
556
+ # শুধু সংখ্যা ও ডট রাখা
557
+ import re
558
+ crash_value = re.sub(r'[^\d.]', '', crash_value)
559
+
560
+ # সংখ্যায় রূপান্তর
561
+ val = float(crash_value)
562
+
563
+ if val <= 1.0:
564
+ return {"status": "error", "message": f"মাল্টিপ্লায়ার ১.০ এর বেশি হতে হবে (পাওয়া গেছে: {val})"}
565
+
566
+ # ইতিহাসে যোগ করা
567
+ result = predictor_app.add_round(val)
568
+
569
+ # API রেসপন্স
570
+ return {
571
+ "status": "success",
572
+ "message": f"ক্র্যাশ ভ্যালু {val:.2f}x যোগ করা হয়েছে",
573
+ "total_rounds": len(predictor_app.history)
574
+ }
575
+
576
+ except ValueError as e:
577
+ return {"status": "error", "message": f"ইনভ্যালিড সংখ্যা: {crash_value}"}
578
+ except Exception as e:
579
+ traceback.print_exc()
580
+ return {"status": "error", "message": f"সার্ভার ত্রুটি: {str(e)}"}
581
+
582
+ @app.get("/api/status")
583
+ async def api_status():
584
+ """
585
+ API স্ট্যাটাস চেক করার জন্য
586
+ """
587
+ return {
588
+ "status": "active",
589
+ "total_rounds": len(predictor_app.history),
590
+ "last_10_rounds": [f"{x:.2f}" for x in predictor_app.history[:10]]
591
+ }
592
+
593
+ if __name__ == "__main__":
594
+ demo.launch(server_name="0.0.0.0", server_port=7860)
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ gradio>=6.7.0
2
+ numpy>=1.24.0
3
+ pandas>=2.0.0
4
+ openpyxl>=3.1.0
5
+ fastapi>=0.104.0
6
+ uvicorn>=0.24.0