nicolaydef commited on
Commit
3c6cfdb
·
verified ·
1 Parent(s): 385f6c4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -185
app.py CHANGED
@@ -7,23 +7,21 @@ import json
7
  import os
8
  from filelock import FileLock
9
 
10
- # --- КОНФИГУРАЦИЯ СИСТЕМЫ ---
11
  TOTAL_ROUNDS = 3
12
  POLLINATIONS_URL = "https://text.pollinations.ai/"
13
  DB_FILE = "game_db.json"
14
  LOCK_FILE = f"{DB_FILE}.lock"
15
- MAX_CHARS = 150 # Лимит символов
16
-
17
- # --- СИСТЕМА ХРАНЕНИЯ ДАННЫХ ---
18
 
 
19
  def load_db():
20
  if not os.path.exists(DB_FILE): return {}
21
  lock = FileLock(LOCK_FILE)
22
  with lock:
23
  try:
24
  with open(DB_FILE, "r", encoding="utf-8") as f:
25
- content = f.read()
26
- return json.loads(content) if content else {}
27
  except: return {}
28
 
29
  def save_db(data):
@@ -32,256 +30,169 @@ def save_db(data):
32
  with open(DB_FILE, "w", encoding="utf-8") as f:
33
  json.dump(data, f, ensure_ascii=False, indent=2)
34
 
35
- # --- AI LOGIC (С ЖЕСТКИМ КОНТЕКСТОМ) ---
36
-
37
  def ask_ai_judge(event, player_action):
38
  system_prompt = (
39
- "Roleplay: Ты безжалостный рассказчик в игре на выживание.\n"
40
- f"ТЕКУЩАЯ КАТАСТРОФА: {event}\n"
41
- f"ДЕЙСТВИЕ ИГРОКА: {player_action}\n\n"
42
- "ЗАДАЧА: Напиши историю из 3 актов о том, как игрок пытается спастись ИМЕННО ОТ ЭТОЙ КАТАСТРОФЫ.\n"
43
- "ПРАВИЛА:\n"
44
- "1. В Акте 1 и 2 ОБЯЗАТЕЛЬНО описывай взаимодействие с {event}.\n"
45
- "2. Используй разделитель '---' между актами.\n"
46
- "3. В конце Акта 3 поставь вердикт: [Survived] или [Not_Survived].\n\n"
47
- "СТРУКТУРА:\n"
48
- "АКТ 1 (Начало): Игрок сталкивается с {event}...\n"
49
- "---\n"
50
- "АКТ 2 (Напряжение): Проблемы и хаос...\n"
51
- "---\n"
52
- "АКТ 3 (Финал): Итог. Тег в конце."
53
  )
54
-
55
  try:
56
- response = requests.post(POLLINATIONS_URL, data=system_prompt.encode('utf-8'))
57
- if response.status_code == 200:
58
- return response.text
59
- return f"Акт 1: {event} пришло.\n---\nАкт 2: Сбой ИИ...\n---\nАкт 3: Выжил. [Survived]"
60
- except Exception as e:
61
- print(f"AI Error: {e}")
62
- return "Связь потеряна.\n---\nИИ молчит.\n---\nВыжил. [Survived]"
63
 
64
- def ask_ai_congrats(winner_name, score):
65
- prompt = f"Поздравь игрока {winner_name} (счет {score}) с победой в апокалипсисе. Эпично и коротко."
66
  try:
67
- return requests.get(f"{POLLINATIONS_URL}{prompt}").text
68
- except:
69
- return f"Поздравляем {winner_name}!"
70
-
71
- # --- ИГРОВАЯ ЛОГИКА ---
72
 
 
73
  def generate_code():
74
  return ''.join(random.choices(string.ascii_uppercase + string.digits, k=4))
75
 
76
- def add_log(room_data, message):
77
- timestamp = time.strftime("%H:%M:%S")
78
- room_data["logs"].append(f"[{timestamp}] {message}")
79
 
80
- def format_lore(raw_text):
81
- if not raw_text: return ""
82
- parts = raw_text.split("---")
83
- if len(parts) < 3: return f"**История:**\n{raw_text}"
84
- return (
85
- f"### 🎬 АКТ 1\n{parts[0].strip()}\n\n"
86
- f"### ⚡ АКТ 2\n{parts[1].strip()}\n\n"
87
- f"### 🏁 ФИНАЛ\n{parts[2].strip()}"
88
- )
89
 
90
- def create_room_logic(player_name):
91
- if not player_name: return None, "⚠️ Введи имя!", gr.update(), gr.update()
 
92
  db, code = load_db(), generate_code()
93
-
94
  db[code] = {
95
- "host_name": player_name,
96
- "phase": "LOBBY",
97
- "round": 1,
98
- "event": "",
99
- "logs": [],
100
- "winner_msg": "",
101
- "players": {player_name: {"name": player_name, "score": 0, "action": None, "result": "", "is_host": True}}
102
  }
103
  add_log(db[code], f"Комната {code} создана.")
104
  save_db(db)
105
  return code, "", gr.update(visible=False), gr.update(visible=True)
106
 
107
- def join_room_logic(player_name, code):
108
- if not player_name or not code: return None, "⚠️ Данные?", gr.update(), gr.update()
109
  code = code.upper().strip()
110
  db = load_db()
 
111
 
112
- if code not in db: return None, "⚠️ Нет комнаты!", gr.update(), gr.update()
113
  room = db[code]
114
-
115
- if player_name not in room["players"]:
116
- if room["phase"] != "LOBBY": return None, "⚠️ Поздно!", gr.update(), gr.update()
117
- room["players"][player_name] = {"name": player_name, "score": 0, "action": None, "result": "", "is_host": False}
118
- add_log(room, f"{player_name} вошел.")
119
  save_db(db)
120
-
121
  return code, "", gr.update(visible=False), gr.update(visible=True)
122
 
123
- def refresh_ui(room_code, player_name):
124
- if not room_code: return (gr.update(visible=True), gr.update(visible=False), "", "", "", gr.update(), gr.update(), "")
125
  db = load_db()
126
- if room_code not in db: return (gr.update(visible=True), gr.update(visible=False), "Закрыто", "", "", gr.update(), gr.update(), "")
127
 
128
- room = db[room_code]
129
- player = room["players"].get(player_name)
130
- if not player: return (gr.update(visible=True), gr.update(visible=False), "Ошибка", "", "", gr.update(), gr.update(), "")
131
 
132
- # Список игроков
133
- players_md = "| Статус | Игрок | Очки |\n| :--- | :--- | :--- |\n"
134
  for p in room["players"].values():
135
  icon = "👑" if p["is_host"] else "👤"
136
- if "[Survived]" in p["result"]: s = ""
137
- elif "[Not_Survived]" in p["result"]: s = "💀"
138
- elif p["action"]: s = "📩"
139
- else: s = ""
140
- if room["phase"] == "INPUT" and not room["event"]: s = "💤"
141
- players_md += f"| {s} {icon} | **{p['name']}** | {p['score']} |\n"
142
-
143
- # Логи и Лор
144
- log_txt = "\n".join(room["logs"][-15:])
145
- lore_display = format_lore(player["result"]) if player["result"] else "Ждем..."
146
-
147
- # Управление
148
  ph = room["phase"]
149
  inp, btn, hdr = gr.update(visible=False), gr.update(visible=False), ""
150
-
151
  if ph == "LOBBY":
152
  hdr = "## ⏳ ОЖИДАНИЕ"
153
- if player["is_host"]: btn = gr.update(visible=True, value="🚀 СТАРТ", variant="primary")
154
  elif ph == "INPUT":
155
  if not room["event"]:
156
  hdr = f"## 🎬 РАУНД {room['round']}"
157
- if player["is_host"]:
158
- inp = gr.update(visible=True, label="Катастрофа", placeholder="Зомби-апокалипсис...")
159
  btn = gr.update(visible=True, value="📢 ЗАДАТЬ", variant="stop")
160
  else: hdr += "\nХост выбирает угрозу..."
161
  else:
162
  hdr = f"## ⚠️ УГРОЗА: {room['event']}"
163
- if not player["action"]:
164
- inp = gr.update(visible=True, label=f"Спасение (макс {MAX_CHARS})", placeholder="Я бегу...")
165
  btn = gr.update(visible=True, value="✅ ОТПРАВИТЬ", variant="primary")
166
  else: hdr += "\n\n**Принято.**"
167
- elif ph == "PROCESSING": hdr = "## 🤖 ИИ ГЕНЕРИРУЕТ..."
168
  elif ph == "RESULTS":
169
  hdr = f"## 🏁 ИТОГИ {room['round']}"
170
- if player["is_host"]:
171
  txt = "➡️ СЛЕД. РАУНД" if room["round"] < TOTAL_ROUNDS else "🏆 ФИНАЛ"
172
  btn = gr.update(visible=True, value=txt, variant="secondary")
173
  elif ph == "GAMEOVER":
174
  hdr = f"## 🏆 КОНЕЦ\n\n{room['winner_msg']}"
175
- if player["is_host"]: btn = gr.update(visible=True, value="🔄 РЕСТАРТ", variant="primary")
176
 
177
- return (gr.update(visible=False), gr.update(visible=True), log_txt, players_md, hdr, inp, btn, lore_display)
 
 
178
 
179
- def handle_action(room_code, player_name, text_input):
180
- if not room_code: return
181
  db = load_db()
182
- if room_code not in db: return
183
- room = db[room_code]
184
- player = room["players"][player_name]
 
185
 
186
- if text_input and len(text_input) > MAX_CHARS: text_input = text_input[:MAX_CHARS]
187
  save = False
188
-
189
- if room["phase"] == "LOBBY" and player["is_host"]:
190
- room["phase"] = "INPUT"
191
- add_log(room, "СТАРТ ИГРЫ")
192
- save = True
193
-
194
  elif room["phase"] == "INPUT":
195
- if not room["event"] and player["is_host"] and text_input:
196
- room["event"] = text_input
197
- add_log(room, f"⚠️ СОБЫТИЕ: {text_input}")
198
  for p in room["players"].values(): p["action"], p["result"] = None, ""
199
  save = True
200
- elif room["event"] and text_input and not player["action"]:
201
- player["action"] = text_input
202
- save = True
203
  if all(p["action"] for p in room["players"].values()):
204
- room["phase"] = "PROCESSING"
205
- save_db(db)
206
- process_turn_sync(room_code)
207
- return
208
-
209
- elif room["phase"] == "RESULTS" and player["is_host"]:
210
  if room["round"] < TOTAL_ROUNDS:
211
- room["round"] += 1; room["event"] = ""; room["phase"] = "INPUT"
212
- add_log(room, f"Раунд {room['round']}")
213
  else:
214
- room["phase"] = "GAMEOVER"
215
- w = max(room["players"].values(), key=lambda x: x["score"])
216
- room["winner_msg"] = ask_ai_congrats(w["name"], w["score"])
217
- add_log(room, f"Победил {w['name']}")
218
  save = True
219
-
220
- elif room["phase"] == "GAMEOVER" and player["is_host"]:
221
- room["phase"] = "LOBBY"; room["round"] = 1; room["event"] = ""
222
- room["logs"] = ["Рестарт."]; room["winner_msg"] = ""
223
  for p in room["players"].values(): p["score"], p["action"], p["result"] = 0, None, ""
224
  save = True
225
-
226
  if save: save_db(db)
227
 
228
- def process_turn_sync(room_code):
229
  db = load_db()
230
- room = db[room_code]
231
  add_log(room, "🤖 ИИ работает...")
232
  save_db(db)
233
-
234
- for p_name, p_data in room["players"].items():
235
- lore = ask_ai_judge(room["event"], p_data["action"])
236
- p_data["result"] = lore
237
- if "[Survived]" in lore:
238
- p_data["score"] += 2
239
- add_log(room, f"✅ {p_name} жив")
240
  else: add_log(room, f"💀 {p_name} мертв")
241
-
242
  room["phase"] = "RESULTS"
243
  save_db(db)
244
 
245
- # --- ЗАПУСК ДЛЯ DOCKER ---
246
- custom_css = """
247
  body { background: #0b0f19; color: #fff; }
248
- #lore_box { background: #1a202c; padding: 10px; border-left: 4px solid #805ad5; }
249
- """
250
-
251
- with gr.Blocks(theme=gr.themes.Monochrome(), css=custom_css, title="AI Survival Docker") as demo:
252
- s_code, s_name = gr.State(""), gr.State("")
253
- gr.Markdown("# 💀 SURVIVAL AI: DOCKER EDITION")
254
-
255
- with gr.Group() as g_login:
256
- with gr.Row():
257
- n_in = gr.Textbox(label="Ник")
258
- b_crt = gr.Button("Создать", variant="primary")
259
- c_in = gr.Textbox(label="Код")
260
- b_join = gr.Button("Войти")
261
- err = gr.Markdown("", color="red")
262
-
263
- with gr.Group(visible=False) as g_game:
264
- with gr.Row():
265
- with gr.Column(scale=1):
266
- md_rm = gr.Markdown("Комната: ---")
267
- md_pl = gr.Markdown("Игроки...")
268
- logs = gr.TextArea(label="Лог", interactive=False, lines=10)
269
- with gr.Column(scale=2):
270
- md_st = gr.Markdown("...")
271
- md_lore = gr.Markdown("История...", elem_id="lore_box")
272
- t_in = gr.Textbox(visible=False)
273
- b_act = gr.Button(visible=False)
274
-
275
- tmr = gr.Timer(1)
276
- tmr.tick(refresh_ui, [s_code, s_name], [g_login, g_game, logs, md_pl, md_st, t_in, b_act, md_lore])
277
-
278
- b_crt.click(create_room_logic, [n_in], [s_code, err, g_login, g_game]).then(lambda c: f"## 🏠 {c}", [s_code], [md_rm])
279
- b_join.click(join_room_logic, [n_in, c_in], [s_code, err, g_login, g_game]).then(lambda c: f"## 🏠 {c}", [s_code], [md_rm])
280
- b_act.click(handle_action, [s_code, s_name, t_in], None).then(lambda: "", None, [t_in])
281
-
282
- if __name__ == "__main__":
283
- if not os.path.exists(DB_FILE):
284
- with open(DB_FILE, "w") as f: f.write("{}")
285
-
286
- # ВАЖНО: Запуск на 0.0.0.0 и порт 7860 для Docker
287
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
7
  import os
8
  from filelock import FileLock
9
 
10
+ # --- КОНФИГУРАЦИЯ ---
11
  TOTAL_ROUNDS = 3
12
  POLLINATIONS_URL = "https://text.pollinations.ai/"
13
  DB_FILE = "game_db.json"
14
  LOCK_FILE = f"{DB_FILE}.lock"
15
+ MAX_CHARS = 150
 
 
16
 
17
+ # --- БАЗА ДАННЫХ ---
18
  def load_db():
19
  if not os.path.exists(DB_FILE): return {}
20
  lock = FileLock(LOCK_FILE)
21
  with lock:
22
  try:
23
  with open(DB_FILE, "r", encoding="utf-8") as f:
24
+ return json.loads(f.read()) or {}
 
25
  except: return {}
26
 
27
  def save_db(data):
 
30
  with open(DB_FILE, "w", encoding="utf-8") as f:
31
  json.dump(data, f, ensure_ascii=False, indent=2)
32
 
33
+ # --- ЛОГИКА ИИ ---
 
34
  def ask_ai_judge(event, player_action):
35
  system_prompt = (
36
+ "Roleplay: Ты рассказчик в игре на выживание.\n"
37
+ f"КАТАСТРОФА: {event}\n"
38
+ f"ДЕЙСТВИЕ: {player_action}\n\n"
39
+ "ЗАДАЧА: Напиши историю из 3 актов (разделитель '---').\n"
40
+ "В Акте 1 и 2 описывай влияние катастрофы.\n"
41
+ конце Акта 3 поставь тег: [Survived] или [Not_Survived].\n"
 
 
 
 
 
 
 
 
42
  )
 
43
  try:
44
+ resp = requests.post(POLLINATIONS_URL, data=system_prompt.encode('utf-8'))
45
+ return resp.text if resp.status_code == 200 else "Ошибка ИИ.\n---\n---\n[Survived]"
46
+ except: return "Связь потеряна.\n---\n---\n[Survived]"
 
 
 
 
47
 
48
+ def ask_ai_congrats(winner, score):
 
49
  try:
50
+ return requests.get(f"{POLLINATIONS_URL}Поздравь победителя {winner} ({score} очков) эпично.").text
51
+ except: return f"Поздравляем {winner}!"
 
 
 
52
 
53
+ # --- ИГРОВАЯ МЕХАНИКА ---
54
  def generate_code():
55
  return ''.join(random.choices(string.ascii_uppercase + string.digits, k=4))
56
 
57
+ def add_log(room, msg):
58
+ room["logs"].append(f"[{time.strftime('%H:%M:%S')}] {msg}")
 
59
 
60
+ def format_lore(text):
61
+ if not text: return ""
62
+ parts = text.split("---")
63
+ if len(parts) < 3: return f"**История:**\n{text}"
64
+ return f"### 🎬 АКТ 1\n{parts[0].strip()}\n\n### ⚡ АКТ 2\n{parts[1].strip()}\n\n### 🏁 ФИНАЛ\n{parts[2].strip()}"
 
 
 
 
65
 
66
+ # --- ЛОГИКА UI ---
67
+ def create_room(name):
68
+ if not name: return None, "<span style='color:red'>⚠️ Введите имя!</span>", gr.update(), gr.update()
69
  db, code = load_db(), generate_code()
 
70
  db[code] = {
71
+ "host": name, "phase": "LOBBY", "round": 1, "event": "", "logs": [], "winner_msg": "",
72
+ "players": {name: {"name": name, "score": 0, "action": None, "result": "", "is_host": True}}
 
 
 
 
 
73
  }
74
  add_log(db[code], f"Комната {code} создана.")
75
  save_db(db)
76
  return code, "", gr.update(visible=False), gr.update(visible=True)
77
 
78
+ def join_room(name, code):
79
+ if not name or not code: return None, "<span style='color:red'>⚠️ Введите данные!</span>", gr.update(), gr.update()
80
  code = code.upper().strip()
81
  db = load_db()
82
+ if code not in db: return None, "<span style='color:red'>⚠️ Нет комнаты!</span>", gr.update(), gr.update()
83
 
 
84
  room = db[code]
85
+ if name not in room["players"]:
86
+ if room["phase"] != "LOBBY": return None, "<span style='color:red'>⚠️ Игра идет!</span>", gr.update(), gr.update()
87
+ room["players"][name] = {"name": name, "score": 0, "action": None, "result": "", "is_host": False}
88
+ add_log(room, f"{name} вошел.")
 
89
  save_db(db)
 
90
  return code, "", gr.update(visible=False), gr.update(visible=True)
91
 
92
+ def refresh(code, name):
93
+ if not code: return (gr.update(visible=True), gr.update(visible=False), "", "", "", gr.update(), gr.update(), "")
94
  db = load_db()
95
+ if code not in db: return (gr.update(visible=True), gr.update(visible=False), "Закрыто", "", "", gr.update(), gr.update(), "")
96
 
97
+ room = db[code]
98
+ me = room["players"].get(name)
99
+ if not me: return (gr.update(visible=True), gr.update(visible=False), "Ошибка", "", "", gr.update(), gr.update(), "")
100
 
101
+ # Список
102
+ pl_md = "| Статус | Игрок | Очки |\n|---|---|---|\n"
103
  for p in room["players"].values():
104
  icon = "👑" if p["is_host"] else "👤"
105
+ stat = ""
106
+ if "[Survived]" in p["result"]: stat = ""
107
+ elif "[Not_Survived]" in p["result"]: stat = "💀"
108
+ elif p["action"]: stat = "📩"
109
+ if room["phase"] == "INPUT" and not room["event"]: stat = "💤"
110
+ pl_md += f"| {stat} {icon} | **{p['name']}** | {p['score']} |\n"
111
+
112
+ # UI State
 
 
 
 
113
  ph = room["phase"]
114
  inp, btn, hdr = gr.update(visible=False), gr.update(visible=False), ""
115
+
116
  if ph == "LOBBY":
117
  hdr = "## ⏳ ОЖИДАНИЕ"
118
+ if me["is_host"]: btn = gr.update(visible=True, value="🚀 СТАРТ", variant="primary")
119
  elif ph == "INPUT":
120
  if not room["event"]:
121
  hdr = f"## 🎬 РАУНД {room['round']}"
122
+ if me["is_host"]:
123
+ inp = gr.update(visible=True, label="Катастрофа", placeholder="Например: Зомби")
124
  btn = gr.update(visible=True, value="📢 ЗАДАТЬ", variant="stop")
125
  else: hdr += "\nХост выбирает угрозу..."
126
  else:
127
  hdr = f"## ⚠️ УГРОЗА: {room['event']}"
128
+ if not me["action"]:
129
+ inp = gr.update(visible=True, label="Действие", placeholder="Я бегу...")
130
  btn = gr.update(visible=True, value="✅ ОТПРАВИТЬ", variant="primary")
131
  else: hdr += "\n\n**Принято.**"
132
+ elif ph == "PROCESSING": hdr = "## 🤖 ИИ ДУМАЕТ..."
133
  elif ph == "RESULTS":
134
  hdr = f"## 🏁 ИТОГИ {room['round']}"
135
+ if me["is_host"]:
136
  txt = "➡️ СЛЕД. РАУНД" if room["round"] < TOTAL_ROUNDS else "🏆 ФИНАЛ"
137
  btn = gr.update(visible=True, value=txt, variant="secondary")
138
  elif ph == "GAMEOVER":
139
  hdr = f"## 🏆 КОНЕЦ\n\n{room['winner_msg']}"
140
+ if me["is_host"]: btn = gr.update(visible=True, value="🔄 РЕСТАРТ", variant="primary")
141
 
142
+ lore = format_lore(me["result"])
143
+ logs = "\n".join(room["logs"][-15:])
144
+ return (gr.update(visible=False), gr.update(visible=True), logs, pl_md, hdr, inp, btn, lore)
145
 
146
+ def act(code, name, txt):
147
+ if not code: return
148
  db = load_db()
149
+ if code not in db: return
150
+ room = db[code]
151
+ me = room["players"][name]
152
+ if txt and len(txt) > MAX_CHARS: txt = txt[:MAX_CHARS]
153
 
 
154
  save = False
155
+ if room["phase"] == "LOBBY" and me["is_host"]:
156
+ room["phase"] = "INPUT"; add_log(room, "СТАРТ"); save = True
 
 
 
 
157
  elif room["phase"] == "INPUT":
158
+ if not room["event"] and me["is_host"] and txt:
159
+ room["event"] = txt; add_log(room, f"⚠️ {txt}");
 
160
  for p in room["players"].values(): p["action"], p["result"] = None, ""
161
  save = True
162
+ elif room["event"] and txt and not me["action"]:
163
+ me["action"] = txt; save = True
 
164
  if all(p["action"] for p in room["players"].values()):
165
+ room["phase"] = "PROCESSING"; save_db(db); process_ai(code); return
166
+ elif room["phase"] == "RESULTS" and me["is_host"]:
 
 
 
 
167
  if room["round"] < TOTAL_ROUNDS:
168
+ room["round"] += 1; room["event"] = ""; room["phase"] = "INPUT"; add_log(room, f"Раунд {room['round']}")
 
169
  else:
170
+ room["phase"] = "GAMEOVER"; w = max(room["players"].values(), key=lambda x: x["score"])
171
+ room["winner_msg"] = ask_ai_congrats(w["name"], w["score"]); add_log(room, f"Победил {w['name']}")
 
 
172
  save = True
173
+ elif room["phase"] == "GAMEOVER" and me["is_host"]:
174
+ room["phase"] = "LOBBY"; room["round"] = 1; room["event"] = ""; room["logs"] = ["Рестарт"]
 
 
175
  for p in room["players"].values(): p["score"], p["action"], p["result"] = 0, None, ""
176
  save = True
177
+
178
  if save: save_db(db)
179
 
180
+ def process_ai(code):
181
  db = load_db()
182
+ room = db[code]
183
  add_log(room, "🤖 ИИ работает...")
184
  save_db(db)
185
+ for p_name, p in room["players"].items():
186
+ lore = ask_ai_judge(room["event"], p["action"])
187
+ p["result"] = lore
188
+ if "[Survived]" in lore: p["score"] += 2; add_log(room, f"✅ {p_name} жив")
 
 
 
189
  else: add_log(room, f"💀 {p_name} мертв")
 
190
  room["phase"] = "RESULTS"
191
  save_db(db)
192
 
193
+ # --- ЗАПУСК ---
194
+ css = """
195
  body { background: #0b0f19; color: #fff; }
196
+ #lore_box { background: #1a202c; padding: 10px; border-left: 4px solid #805ad5; margin-top: 10px; }
197
+ .gradio-container { max-width: 900px !important; }
198
+ """