FillMyBlank.ai / app.py
Rizzhi's picture
Update app.py
76840ea verified
import streamlit as st
import json
import os
import pandas as pd
from datetime import datetime
from sqlalchemy import create_engine, Column, Integer, String, Text, DateTime, Boolean, Enum, func
from sqlalchemy.orm import sessionmaker, declarative_base
from sqlalchemy.exc import IntegrityError
import hashlib
import uuid
import bcrypt
import requests
import random
import enum
# Removed: AI-specific imports to temporarily disable AI features for full app functionality
# from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
# Removed: import torch
# Removed: AI Model Setup and caching
# Removed: tokenizer_ai, model_ai = load_summarizer_components()
class GameType(enum.Enum):
IDIOM_GUESSER = "IdiomGuesser"
STORY_STARTER = "StoryStarter"
# --- Configuration ---
if os.environ.get("DATABASE_URL"):
DATABASE_URL = os.environ.get("DATABASE_URL")
else:
DATABASE_URL = "sqlite:///fillmyblank.db"
# --- Database Setup (SQLAlchemy) ---
Base = declarative_base()
@st.cache_resource
def get_engine(_db_url):
try:
engine = create_engine(_db_url)
with engine.connect() as connection:
pass
return engine
except Exception as e:
st.error(f"FATAL ERROR: Could not connect to database on startup: {e}")
return None
@st.cache_resource
def get_session_local(_engine):
if _engine:
return sessionmaker(autocommit=False, autoflush=False, bind=_engine)
return None
Engine = get_engine(DATABASE_URL)
SessionLocal = get_session_local(Engine)
# --- Database Models ---
class User(Base):
__tablename__ = "users"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
username = Column(String, unique=True, nullable=False)
hashed_password = Column(String, nullable=False)
created_at = Column(DateTime, default=datetime.now)
def set_password(self, password):
self.hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
def check_password(self, password):
return bcrypt.checkpw(password.encode('utf-8'), self.hashed_password.encode('utf-8'))
class LoreEntry(Base):
__tablename__ = "lore_entries"
id = Column(Integer, primary_key=True, index=True)
text = Column(Text, nullable=False)
language = Column(String, nullable=False)
type = Column(String, nullable=False)
nickname = Column(String, default="Anonymous")
user_id = Column(String, nullable=True)
timestamp = Column(DateTime, default=datetime.now)
city = Column(String, nullable=True)
state = Column(String, nullable=True)
country = Column(String, nullable=True)
ip_address = Column(String, nullable=True)
class GameResponse(Base):
__tablename__ = "game_responses"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(String, nullable=False)
game_type = Column(Enum(GameType), nullable=False)
question_text = Column(Text, nullable=False) # E.g., idiom / story starter
user_response = Column(Text, nullable=False) # E.g., user's situation / story continuation
is_correct = Column(Boolean, nullable=True) # For guess-based games (will be None for story/situation games)
score = Column(Integer, default=0) # Points awarded
user_explanation = Column(Text, nullable=True) # Used for idiom definition or situations now
language = Column(String, nullable=False)
timestamp = Column(DateTime, default=datetime.now)
# Create tables if they don't exist
Base.metadata.create_all(bind=Engine)
# --- Session State Initialization ---
if 'user_id' not in st.session_state: st.session_state.user_id = None
if 'username' not in st.session_state: st.session_state.username = None
if 'register_username_input_value' not in st.session_state: st.session_state.register_username_input_value = ""
if 'register_password_input_value' not in st.session_state: st.session_state.register_password_input_value = ""
# Game specific session state
if 'current_idiom' not in st.session_state: st.session_state.current_idiom = None
if 'game_score' not in st.session_state: st.session_state.game_score = 0
if 'idiom_game_state' not in st.session_state: st.session_state.idiom_game_state = "initial"
if 'current_story_starter' not in st.session_state: st.session_state.current_story_starter = None
if 'story_game_state' not in st.session_state: st.session_state.story_game_state = "initial"
if 'user_app_language' not in st.session_state: st.session_state.user_app_language = "English"
# Lore Contribution Form Session State
if "lore_text_input_value" not in st.session_state: st.session_state.lore_text_input_value = ""
if "language_select_value" not in st.session_state: st.session_state.language_select_value = "Select Language"
if "region_select_value" not in st.session_state: st.session_state.region_select_value = "Select State"
if "lore_type_select_value" not in st.session_state: st.session_state.lore_type_select_value = "Select Type"
if "nickname_input_value" not in st.session_state: st.session_state.nickname_input_value = ""
if "agree_to_location_checkbox_value" not in st.session_state: st.session_state.agree_to_location_checkbox_value = False
# Idiom Game Specific Widget Keys
if 'idiom_guess_input' not in st.session_state: st.session_state.idiom_guess_input = ""
if 'idiom_situations_input' not in st.session_state: st.session_state.idiom_situations_input = ""
if 'idiom_hint_shown' not in st.session_state: st.session_state.idiom_hint_shown = False
if 'idiom_explanation_input' not in st.session_state: st.session_state.idiom_explanation_input = ""
if 'explanation_language_select' not in st.session_state: st.session_state.explanation_language_select = "English"
# Story Game Specific Widget Keys
if 'story_continuation_input' not in st.session_state: st.session_state.story_continuation_input = ""
# --- Helper Functions ---
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
def create_user(username, password):
db = next(get_db())
existing_user = db.query(User).filter(User.username == username).first()
if existing_user:
return None
new_user = User(username=username)
new_user.set_password(password)
db.add(new_user)
try:
db.commit()
db.refresh(new_user)
return new_user
except IntegrityError:
db.rollback()
return None
except Exception as e:
db.rollback()
st.error(f"An error occurred during registration: {e}")
return None
def authenticate_user(username, password):
db = next(get_db())
user = db.query(User).filter(User.username == username).first()
if not user:
return None
if user.check_password(password):
return user
else:
return None
def save_lore_data_to_db(entry_data):
db = next(get_db())
new_lore = LoreEntry(**entry_data)
db.add(new_lore)
db.commit()
db.refresh(new_lore)
return new_lore
def load_lore_data_from_db(limit=10):
db = next(get_db())
return db.query(LoreEntry).order_by(LoreEntry.timestamp.desc()).limit(limit).all()
def load_user_lore_from_db(user_id, limit=10):
db = next(get_db())
return db.query(LoreEntry).filter(LoreEntry.user_id == user_id).order_by(LoreEntry.timestamp.desc()).limit(limit).all()
def save_game_response_to_db(response_data):
db = next(get_db())
new_response = GameResponse(**response_data)
db.add(new_response)
db.commit()
db.refresh(new_response)
return new_response
def load_leaderboard_data(limit=10):
db = next(get_db())
leaderboard = db.query(
User.username,
func.sum(GameResponse.score).label('total_score')
).join(GameResponse, User.id == GameResponse.user_id) \
.group_by(User.username).order_by(func.sum(GameResponse.score).desc()).limit(limit).all()
return leaderboard
# --- Language Options ---
APP_LANGUAGES = ["English", "Hindi", "Telugu", "Marathi", "Tamil", "Kannada", "Malayalam", "Bengali", "Gujarati", "Punjabi", "Odia", "Assamese", "Urdu"]
# --- MULTILINGUAL IDIOM DATA (AI HINT GENERATION DISABLED) ---
IDIOMS_DATA = {
"Telugu": [
{"idiom": "కళ్లు కాయలు కాసేలా చూడటం", "clue": "చాలా కాలం వేచి ఉండటం, కళ్ళు కాయలు కాసేంత వరకు.", "meaning_for_ai": "చాలా కాలం వేచి ఉండటం, కళ్ళు కాయలు కాసేంత వరకు చూడటం, అనగా ఒక విషయం కోసం చాలా ఆసక్తిగా ఎదురుచూడటం."},
{"idiom": "గోరు చుట్టుపై రోకలి పోటు", "clue": "ఇప్పటికే ఉన్న సమస్యను మరింత దిగజార్చడం, పరిస్థితిని మరింత దారుణంగా మార్చడం.", "meaning_for_ai": "ఇప్పటికే ఉన్న సమస్యను మరింత దిగజార్చడం, పరిస్థితిని మరింత దారుణంగా మార్చడం, ఒక చిన్న కష్టానికి పెద్ద ఆపదను జోడించడం."},
{"idiom": "మానవుడు తానొకటి తలిస్తే దైవం వేరొకటి తలచును", "clue": "మనిషి ఒకటి అనుకుంటే దేవుడు ఇంకొకటి తలస్తాడు.", "meaning_for_ai": "మనిషి ఒకటి అనుకుంటే దేవుడు ఇంకొకటి తలస్తాడు. మనం ప్రణాళిక వేసుకున్నవి ఎల్లప్పుడూ జరగవు, దైవ సంకల్పం వేరుగా ఉండవచ్చు."},
{"idiom": "నక్కకు నాగలోకం చూపించడం", "clue": "ఎవరికైనా అసాధ్యమైనదాన్ని లేదా వారి స్థాయికి మించినదాన్ని చూపించడం; అవాస్తవంగా గొప్పలు చెప్పుకోవడం.", "meaning_for_ai": "ఎవరికైనా అసాధ్యమైనదాన్ని లేదా వారి స్థాయికి మించినదాన్ని చూపించడం; అవాస్తవంగా గొప్పలు చెప్పుకోవడం. ఒక చిన్న జంతువుకు పెద్ద లోకాన్ని చూపించడం వంటిది."},
{"idiom": "అంట్లు కడిగినా సుఖం లేదు", "clue": "కష్టపడి పని చేసినా ఫలితం లేకపోవడం, కృతజ్ఞత లేని పని.", "meaning_for_ai": "కష్టపడి పని చేసినా ఫలితం లేకపోవడం, కృతజ్ఞత లేని పని. ఎంత కష్టపడినా సంతోషం లేదా గుర్తింపు లేకపోవడం."},
],
"Hindi": [
{"idiom": "हाथी के दांत खाने के और, दिखाने के और", "clue": "जो दिखता है, वह होता नहीं.", "meaning_for_ai": "जो चीज़ दिखती है, वह असलियत में नहीं होती; कथनी और करनी में अंतर होना, पाखंड करना."},
{"idiom": "ऊंट के मुंह में जीरा", "clue": "ज़रूरत से बहुत कम वस्तु का मिलना.", "meaning_for_ai": "बहुत बड़ी ज़रूरत के लिए बहुत कम वस्तु का मिलना, जिसका कोई खास असर न पड़े."},
{"idiom": "आसमान से गिरा खजूर पर अटका", "clue": "एक मुश्किल से निकलकर दूसरी मुश्किल में फंस जाना.", "meaning_for_ai": "एक समस्या से बचने के बाद तुरंत दूसरी नई समस्या में फंस जाना."},
{"idiom": "नाच न जाने आंगन टेढ़ा", "clue": "अपनी अयोग्यता को छिपाने के लिए दूसरों में दोष निकालना.", "meaning_for_ai": "अपनी कमी या अक्षमता को स्वीकार न करके, दूसरों या परिस्थितियों को दोष देना."},
{"idiom": "जल में रहकर मगर से बैर", "clue": "जिसके अधीन रहना हो, उसी से दुश्मनी करना.", "meaning_for_ai": "जिसके आश्रय में या जिसके साथ रहना हो, उसी से दुश्मनी मोल लेना, जो घातक हो सकता है।"},
],
"English": [
{"idiom": "Break a leg", "clue": "To wish someone good luck.", "meaning_for_ai": "An idiomatic expression used in theater and other performing arts to wish a performer good luck."},
{"idiom": "Bite the bullet", "clue": "To endure a difficult situation.", "meaning_for_ai": "To face a difficult and unpleasant situation with courage and fortitude, rather than avoiding it."},
{"idiom": "Cost an arm and a leg", "clue": "To be very expensive.", "meaning_for_ai": "To be extremely expensive, costing a large amount of money."},
{"idiom": "Hit the road", "clue": "To leave a place.", "meaning_for_ai": "To begin a journey or to depart from a particular location."},
{"idiom": "The ball is in your court", "clue": "It's up to you to make the next decision or step.", "meaning_for_ai": "It's your turn to act."},
]
}
# NEW: MULTILINGUAL STORY STARTERS DATA
STORY_STARTERS_DATA = {
"Telugu": [
{"starter": "పురాతన పల్లెటూరిలో, ఒక వృద్ధురాలు అరణ్యంలో ఒక వింత కాంతిని చూసింది...", "meaning_for_ai": "In an ancient village, an old woman saw a strange light in the forest..."},
{"starter": "ఆ పర్వతాల మధ్య, ఒకప్పుడు అదృశ్యమైన గుడి ఉంది, దానికి దాని స్వంత రహస్యం ఉంది.", "meaning_for_ai": "Amidst those mountains, there was once a forgotten temple, holding its own secret."},
{"starter": "రాత్రిపూట, నగర వీధులు నిశ్శబ్దంగా ఉన్నప్పుడు, ఒక పాత రేడియో అకస్మాత్తుగా ప్లే అవ్వడం ప్రారంభించింది...", "meaning_for_ai": "In the dead of night, when city streets were silent, an old radio suddenly began to play..."},
{"starter": "నేను మొదటిసారి రైలు ఎక్కినప్పుడు, నా పక్కన కూర్చున్న వ్యక్తి ఒక విచిత్రమైన సూట్కేస్ కలిగి ఉన్నాడు.", "meaning_for_ai": "When I first boarded the train, the person sitting next to me had a strange suitcase."},
{"starter": "పాత మామిడి చెట్టు క్రింద, తరాల నాటి కథలు నిద్రిస్తున్నాయి. ఈ రోజు, వాటిలో ఒకటి మేల్కొంది.", "meaning_for_ai": "Under the old mango tree, stories of generations lie dormant. Today, one of them awoke."},
],
"Hindi": [
{"starter": "पुराने गाँव में, एक बूढ़ी औरत ने जंगल में एक अजीब रोशनी देखी...", "meaning_for_ai": "In an ancient village, an old woman saw a strange light in the forest..."},
{"starter": "उन पहाड़ों के बीच, एक समय एक भूला हुआ मंदिर था, जिसका अपना रहस्य था।", "meaning_for_ai": "Amidst those mountains, there was once a forgotten temple, holding its own secret."},
{"starter": "रात के सन्नाटे में, जब शहर की सड़कें खामोश थीं, एक पुराना रेडियो अचानक बजने लगा...", "meaning_for_ai": "In the dead of night, when city streets were silent, an old radio suddenly began to play..."},
{"starter": "जब मैं पहली बार ट्रेन में चढ़ा, तो मेरे बगल में बैठे व्यक्ति के पास एक अजीब सूटकेस था।", "meaning_for_ai": "When I first boarded the train, the person sitting next to me had a strange suitcase."},
{"starter": "पुराने आम के पेड़ के नीचे, पीढ़ियों की कहानियाँ सोई हुई हैं। आज, उनमें से एक जाग उठी।", "meaning_for_ai": "Under the old mango tree, stories of generations lie dormant. Today, one of them awoke."},
],
"English": [
{"starter": "The old woman found a peculiar, glowing stone at the bottom of the ancient well...", "meaning_for_ai": "A fantasy/mystery starter."},
{"starter": "It was the day the monsoons arrived early, bringing with them a secret that had been buried for years.", "meaning_for_ai": "A mystery/drama starter."},
{"starter": "I never believed in magic until the stray dog I rescued started whispering forgotten lullabies.", "meaning_for_ai": "A whimsical/fantasy starter."},
{"starter": "The aroma of spices filled the narrow alleyway, leading me to a door that wasn't there yesterday.", "meaning_for_ai": "A mystery/adventure starter."},
{"starter": "The last letter from my grandmother contained not words, but a single, dried marigold petal.", "meaning_for_ai": "A poignant/mystery starter."},
]
}
def get_random_story_starter(lang):
if lang in STORY_STARTERS_DATA and STORY_STARTERS_DATA[lang]:
return random.choice(STORY_STARTERS_DATA[lang])
return None
# Removed AI clue generation function, as AI is temporarily disabled
# Replaced with a simple function that returns the hardcoded clue
def get_idiom_clue_simple(idiom_data):
return idiom_data["clue"] # Use the hardcoded 'clue' field
def get_random_idiom_for_guesser(lang):
if lang in IDIOMS_DATA and IDIOMS_DATA[lang]:
chosen_idiom_data = random.choice(IDIOMS_DATA[lang])
chosen_idiom_data["generated_hint"] = get_idiom_clue_simple(chosen_idiom_data) # Use simple clue
return chosen_idiom_data
return None
def get_location_from_ip():
"""Fetches approximate location based on IP address."""
try:
response = requests.get("http://ip-api.com/json")
response.raise_for_status()
data = response.json()
if data.get("status") == "success":
return {
"city": data.get("city"),
"state": data.get("regionName"),
"country": data.get("country"),
"ip_address": data.get("query")
}
else:
st.warning(f"IP lookup failed: {data.get('message', 'Unknown error')}")
return None
except requests.exceptions.RequestException as e:
st.warning(f"Could not retrieve location from IP: {e}. Please try again later.")
return None
# --- UI Strings Dictionary ---
UI_STRINGS = {
"English": {
"user_account_title": "User Account",
"logged_in_as": "Logged in as",
"logout_button": "Logout",
"login_register_subheader": "Login / Register",
"login_tab": "Login",
"register_tab": "Register",
"username_label": "Username",
"password_label": "Password",
"login_button": "Login",
"invalid_credentials_error": "Invalid username or password.",
"new_username_label": "New Username",
"new_password_label": "New Password",
"register_button": "Register",
"empty_credentials_error": "Username and password cannot be empty.",
"user_registered_success": "User ",
"please_login_msg": " registered successfully! Please login.",
"username_exists_error": "Username already exists. Please choose a different one.",
"registration_error": "An error occurred during registration",
"choose_language_label": "Choose your language for the app experience:",
"intro_text": "Hey gang! Help us build an AI that understands India's incredible linguistic and cultural vibes. Your contributions will help us train AI models to get the nuances of Indian languages!",
"contribute_lore_tab": "Contribute Lore",
"play_game_tab": "Play a Game",
"leaderboard_tab": "Leaderboard",
"lore_contribute_subheader": "Contribute Your Lore:",
"lore_text_label": "Your Lore/Proverb:",
"lore_text_placeholder": "E.g., 'The quick brown fox jumps over the lazy dog.' or 'Good morning, how are you?'",
"language_label": "Language:",
"state_ut_label": "State/Union Territory:",
"type_of_lore_label": "Type of Lore:",
"nickname_label": "Your Nickname (Optional, defaults to your username if logged in):",
"location_optional_text": "**Optional: Add Location Data**",
"agree_to_location_text": "Allow app to automatically detect my approximate location (via IP address)?",
"location_info_text": "Your location will be approximated from the server's IP address where the app is running. This is usually city/state level, not precise GPS. **This feature relies on an external API (ip-api.com) and may have usage limits or occasional failures.**",
"submit_lore_button": "Submit Lore!",
"empty_lore_error": "🚨 Lore/Proverb field cannot be empty. Spill the tea!",
"select_language_error": "🚨 Please select a Language.",
"select_state_error": "🚨 Please select a State/Union Territory.",
"select_type_error": "🚨 Please select a Type of Lore.",
"lore_submitted_success": "✅ Lore submitted successfully to the database! Thanks for contributing, legend!",
"recent_contributions_subheader": "Your Recent Contributions:",
"no_user_contributions": "You haven't contributed any lore yet! Drop some knowledge above. 🚀",
"recent_all_lore_subheader": "Recently Collected Lore (from Database):",
"no_lore_collected": "No lore collected yet! Be the first to drop some knowledge. 🚀",
"built_with_love": "💖 Built with ❤️ for FillMyBlank.ai",
"game_play_subheader": "Choose a Game!",
"idiom_guesser_game_tab": "Idiom Guesser",
"story_completion_game_tab": "Story Completion",
"idiom_game_current_score": "Your Idiom Score:",
"start_new_idiom_game_button": "Start New Idiom Game",
"idiom_text_label": "**Idiom:**",
"get_hint_button": "Get a Hint",
"ai_hint_text": "**Hint:**", # Changed from AI Hint
"your_situations_label": "Write a few situations where this idiom would fit:",
"submit_situations_button": "Submit Situations",
"situations_empty_error": "🚨 Please write some situations for the idiom. Get creative!",
"idiom_submitted_success": "✅ Situations submitted! Thanks for your valuable contribution!",
"no_idioms_for_lang": "No idioms available for the selected language. Please select another language or contribute more idioms!",
"lore_msg_text": "**💬 Lore:**",
"lang_msg_text": "**🌐 Lang:**",
"location_msg_text": "**📍 Location:**",
"type_msg_text": "**🏷️ Type:**",
"on_msg_text": "**⏰ On:**",
"by_msg_text": "**👤 By:**",
"contributor_you": "(You)",
"contributor_logged_in": "(Logged-in User)",
"dialog_placeholder": "Dialogue, quote, or local saying",
"logged_out_success": "Logged out successfully!",
"welcome_back": "Welcome back",
"could_not_detect_location_warning": "Could not automatically detect location. Proceeding without location data.",
"leaderboard_subheader": "Top Idiom Guessers!",
"leaderboard_username_col": "Username",
"leaderboard_score_col": "Total Score",
"no_scores_yet": "No scores recorded yet! Be the first to play and get on the leaderboard. 🚀",
"story_play_subheader": "Play: Story Completion!",
"story_starter_text": "**Story Starter:**",
"your_story_continuation_label": "Your Story Continuation:",
"submit_story_button": "Submit Story",
"story_submitted_success": "✅ Story submitted! Thanks for your creative contribution!",
"no_starters_for_lang": "No story starters available for the selected language. Please select another language or contribute more stories!",
"story_empty_error": "🚨 Your story continuation cannot be empty. Get creative!"
},
"Telugu": {
"user_account_title": "వినియోగదారు ఖాతా",
"logged_in_as": "లాగిన్ అయ్యారు",
"logout_button": "లాగ్ అవుట్",
"login_register_subheader": "లాగిన్ / నమోదు",
"login_tab": "లాగిన్",
"register_tab": "నమోదు",
"username_label": "వినియోగదారు పేరు",
"password_label": "పాస్‌వర్డ్",
"login_button": "లాగిన్",
"invalid_credentials_error": "చెల్లని వినియోగదారు పేరు లేదా పాస్‌వర్డ్.",
"new_username_label": "కొత్త వినియోగదారు పేరు",
"new_password_label": "కొత్త పాస్‌వర్డ్",
"register_button": "నమోదు",
"empty_credentials_error": "వినియోగదారు పేరు మరియు పాస్‌వర్డ్ ఖాళీగా ఉండకూడదు.",
"user_registered_success": "వినియోగదారు ",
"please_login_msg": " విజయవంతంగా నమోదు చేయబడింది! దయచేసి లాగిన్ చేయండి.",
"username_exists_error": "వినియోగదారు పేరు ఇప్పటికే ఉంది. దయచేసి మరొకటి ఎంచుకోండి.",
"registration_error": "నమోదు సమయంలో లోపం సంభవించింది",
"choose_language_label": "యాప్ అనుభవం కోసం మీ భాషను ఎంచుకోండి:",
"intro_text": "భారతదేశం యొక్క అద్భుతమైన భాషా మరియు సాంస్కృతిక వైవిధ్యాన్ని అర్థం చేసుకునే AIని రూపొందించడంలో మాకు సహాయం చేయండి. మీ సహకారం భారతీయ భాషల సూక్ష్మ నైపుణ్యాలను అర్థం చేసుకోవడానికి AI నమూనాలకు సహాయపడుతుంది!",
"contribute_lore_tab": "మీ కథనాన్ని అందించండి",
"play_game_tab": "ఆట ఆడండి",
"leaderboard_tab": "లీడర్‌బోర్డ్",
"lore_contribute_subheader": "మీ కథనాన్ని అందించండి:",
"lore_text_label": "మీ కథనం/సామెత:",
"lore_text_placeholder": "ఉదా: 'అతి సర్వత్ర వర్జయేత్.' (ఎక్కువగా ఏదైనా చెడ్డది.)",
"language_label": "భాష:",
"state_ut_label": "రాష్ట్రం/కేంద్ర పాలిత ప్రాంతం:",
"type_of_lore_label": "కథనం రకం:",
"nickname_label": "మీ మారుపేరు (ఐచ్ఛికం, లాగిన్ అయితే మీ వినియోగదారు పేరుకి డిఫాల్ట్ అవుతుంది):",
"location_optional_text": "**ఐచ్ఛికం: స్థాన డేటాను జోడించండి**",
"agree_to_location_text": "అప్లికేషన్ నా సుమారు స్థానాన్ని స్వయంచాలకంగా గుర్తించడానికి అనుమతించాలా (IP చిరునామా ద్వారా)?",
"location_info_text": "మీ స్థానం అప్లికేషన్ నడుస్తున్న సర్వర్ IP చిరునామా నుండి అంచనా వేయబడుతుంది. ఇది సాధారణంగా నగరం/రాష్ట్ర స్థాయి, ఖచ్చితమైన GPS కాదు. **ఈ ఫీచర్ బాహ్య API (ip-api.com)పై ఆధారపడి ఉంటుంది మరియు వినియోగ పరిమితులు లేదా అప్పుడప్పుడు వైఫల్యాలు ఉండవచ్చు.**",
"submit_lore_button": "కథనాన్ని సమర్పించండి!",
"empty_lore_error": "🚨 కథనం/సామెత ఖాళీగా ఉండకూడదు.",
"select_language_error": "🚨 దయచేసి ఒక భాషను ఎంచుకోండి.",
"select_state_error": "🚨 దయచేసి ఒక రాష్ట్రాన్ని/కేంద్ర పాలిత ప్రాంతాన్ని ఎంచుకోండి.",
"select_type_error": "🚨 దయచేసి ఒక రకాన్ని ఎంచుకోండి.",
"lore_submitted_success": "✅ కథనం డేటాబేస్‌లో విజయవంతంగా సమర్పించబడింది! సహకరించినందుకు ధన్యవాదాలు, లెజెండ్!",
"recent_contributions_subheader": "మీ ఇటీవలి సహకారాలు:",
"no_user_contributions": "మీరు ఇంకా ఎటువంటి కథనాన్ని అందించలేదు!",
"recent_all_lore_subheader": "ఇటీవలి సేకరించిన కథనం (డేటాబేస్ నుండి):",
"no_lore_collected": "ఇంకా కథనం సేకరించబడలేదు!",
"built_with_love": "💖 FillMyBlank.ai కోసం ప్రేమతో రూపొందించబడింది",
"game_play_subheader": "ఆటను ఎంచుకోండి!",
"idiom_guesser_game_tab": "ఇడియమ్ గెసర్",
"story_completion_game_tab": "కథనం పూర్తి",
"idiom_game_current_score": "మీ ఇడియమ్ స్కోర్:",
"start_new_idiom_game_button": "కొత్త ఇడియమ్ ఆట ప్రారంభించండి",
"idiom_text_label": "**జాతీయం:**",
"get_hint_button": "సూచన పొందండి",
"ai_hint_text": "**సూచన:**",
"your_situations_label": "ఈ జాతీయం సరిపోయే కొన్ని సందర్భాలను వ్రాయండి:",
"submit_situations_button": "సందర్భాలను సమర్పించండి",
"situations_empty_error": "🚨 దయచేసి జాతీయం కోసం కొన్ని సందర్భాలను వ్రాయండి. సృజనాత్మకంగా ఉండండి!",
"idiom_submitted_success": "✅ సందర్భాలు సమర్పించబడ్డాయి! మీ విలువైన సహకారానికి ధన్యవాదాలు!",
"no_idioms_for_lang": "ఎంచుకున్న భాషకు జాతీయాలు అందుబాటులో లేవు. దయచేసి మరొక భాషను ఎంచుకోండి లేదా మరిన్ని జాతీయాలను అందించండి!",
"lore_msg_text": "**💬 కథనం:**",
"lang_msg_text": "**🌐 భాష:**",
"location_msg_text": "**📍 స్థానం:**",
"type_msg_text": "**🏷️ రకం:**",
"on_msg_text": "**⏰ సమయం:**",
"by_msg_text": "**👤 ద్వారా:**",
"contributor_you": "(మీరు)",
"contributor_logged_in": "(లాగిన్ అయిన వినియోగదారు)",
"dialog_placeholder": "సంభాషణ, కోట్ లేదా స్థానిక సామెత",
"logged_out_success": "విజయవంతంగా లాగ్ అవుట్ అయ్యారు!",
"welcome_back": "తిరిగి స్వాగతం",
"could_not_detect_location_warning": "స్థానాన్ని స్వయంచాలకంగా గుర్తించలేకపోయింది. స్థాన డేటా లేకుండా కొనసాగుతోంది.",
"leaderboard_subheader": "టాప్ ఇడియమ్ గెసర్లు!",
"leaderboard_username_col": "వినియోగదారు పేరు",
"leaderboard_score_col": "మొత్తం స్కోర్",
"no_scores_yet": "ఇంకా స్కోర్‌లు నమోదు కాలేదు! లీడర్‌బోర్డ్‌లో చేరడానికి మొదట ఆట ఆడండి. 🚀",
"story_play_subheader": "ఆడండి: కథనం పూర్తి!",
"story_starter_text": "**కథనం ప్రారంభం:**",
"your_story_continuation_label": "మీ కథనం కొనసాగింపు:",
"submit_story_button": "కథనాన్ని సమర్పించండి",
"story_submitted_success": "✅ కథనం సమర్పించబడింది! మీ సృజనాత్మక సహకారానికి ధన్యవాదాలు!",
"no_starters_for_lang": "ఎంచుకున్న భాషకు కథనం ప్రారంభాలు అందుబాటులో లేవు. దయచేసి మరొక భాషను ఎంచుకోండి లేదా మరిన్ని కథనాలను అందించండి!",
"story_empty_error": "🚨 మీ కథనం కొనసాగింపు ఖాళీగా ఉండకూడదు. సృజనాత్మకంగా ఉండండి!"
},
"Hindi": {
"user_account_title": "उपयोगकर्ता खाता",
"logged_in_as": "के रूप में लॉग इन किया गया",
"logout_button": "लॉग आउट",
"login_register_subheader": "लॉगिन / रजिस्टर",
"login_tab": "लॉगिन",
"register_tab": "रजिस्टर",
"username_label": "उपयोगकर्ता नाम",
"password_label": "पासवर्ड",
"login_button": "लॉगिन",
"invalid_credentials_error": "अमान्य उपयोगकर्ता नाम या पासवर्ड।",
"new_username_label": "नया उपयोगकर्ता नाम",
"new_password_label": "नया पासवर्ड",
"register_button": "रजिस्टर",
"empty_credentials_error": "उपयोगकर्ता नाम और पासवर्ड खाली नहीं हो सकते।",
"user_registered_success": "उपयोगकर्ता ",
"please_login_msg": " सफलतापूर्वक पंजीकृत! कृपया लॉगिन करें।",
"username_exists_error": "उपयोगकर्ता नाम पहले से मौजूद है। कृपया कोई दूसरा चुनें।",
"registration_error": "पंजीकरण के दौरान एक त्रुटि हुई",
"choose_language_label": "ऐप अनुभव के लिए अपनी भाषा चुनें:",
"intro_text": "नमस्ते गैंग! भारत की अविश्वसनीय भाषाई और सांस्कृतिक विविधता को समझने वाले एक AI के निर्माण में हमारी मदद करें। आपका योगदान AI मॉडल को भारतीय भाषाओं की बारीकियों को समझने में मदद करेगा!",
"contribute_lore_tab": "ज्ञान योगदान करें",
"play_game_tab": "खेल खेलें",
"leaderboard_tab": "लीडरबोर्ड",
"lore_contribute_subheader": "अपना ज्ञान योगदान करें:",
"lore_text_label": "आपका ज्ञान/मुहावरा:",
"lore_text_placeholder": "उदाहरण: 'हाथी के दांत खाने के और, दिखाने के और'",
"language_label": "भाषा:",
"state_ut_label": "राज्य/केंद्र शासित प्रदेश:",
"type_of_lore_label": "ज्ञान का प्रकार:",
"nickname_label": "आपका उपनाम (वैकल्पिक, लॉगिन होने पर आपके उपयोगकर्ता नाम पर डिफ़ॉल्ट होगा):",
"location_optional_text": "**वैकल्पिक: स्थान डेटा जोड़ें**",
"agree_to_location_text": "क्या ऐप को मेरी अनुमानित स्थिति (IP पते के माध्यम से) स्वचालित रूप से पता लगाने की अनुमति दें?",
"location_info_text": "आपकी स्थिति का अनुमान उस सर्वर के IP पते से लगाया जाएगा जहां ऐप चल रहा है। यह आमतौर पर शहर/राज्य स्तर का होता है, सटीक GPS नहीं। **यह सुविधा बाहरी API (ip-api.com) पर निर्भर करती है और इसमें उपयोग सीमाएं या कभी-कभी विफलताएं हो सकती हैं।**",
"submit_lore_button": "ज्ञान सबमिट करें!",
"empty_lore_error": "🚨 ज्ञान/मुहावरा खाली नहीं हो सकता।",
"select_language_error": "🚨 कृपया एक भाषा चुनें।",
"select_state_error": "🚨 कृपया एक राज्य/केंद्र शासित प्रदेश चुनें।",
"select_type_error": "🚨 कृपया एक प्रकार चुनें।",
"lore_submitted_success": "✅ ज्ञान डेटाबेस में सफलतापूर्वक सबमिट किया गया! योगदान के लिए धन्यवाद, लीजेंड!",
"recent_contributions_subheader": "आपके हालिया योगदान:",
"no_user_contributions": "आपने अभी तक कोई ज्ञान योगदान नहीं किया है!",
"recent_all_lore_subheader": "हाल ही में एकत्र किया गया ज्ञान (डेटाबेस से):",
"no_lore_collected": "अभी तक कोई ज्ञान एकत्र नहीं किया गया है!",
"built_with_love": "💖 FillMyBlank.ai के लिए प्यार से बनाया गया",
"game_play_subheader": "एक खेल चुनें!",
"idiom_guesser_game_tab": "मुहावरा पहचानें",
"story_completion_game_tab": "कहानी पूरी करें",
"idiom_game_current_score": "आपका मुहावरा स्कोर:",
"start_new_idiom_game_button": "नया मुहावरा खेल शुरू करें",
"idiom_text_label": "**मुहावरा:**",
"get_hint_button": "एक संकेत प्राप्त करें",
"ai_hint_text": "**संकेत:**",
"your_situations_label": "कुछ ऐसी स्थितियाँ लिखें जहाँ यह मुहावरा उपयुक्त हो:",
"submit_situations_button": "स्थितियाँ सबमिट करें",
"situations_empty_error": "🚨 कृपया मुहावरे के लिए कुछ स्थितियाँ लिखें। रचनात्मक बनें!",
"idiom_submitted_success": "✅ स्थितियाँ सबमिट की गईं! आपके बहुमूल्य योगदान के लिए धन्यवाद!",
"no_idioms_for_lang": "चयनित भाषा के लिए कोई मुहावरे उपलब्ध नहीं हैं। कृपया कोई अन्य भाषा चुनें या और कहानियाँ योगदान करें!",
"lore_msg_text": "**💬 ज्ञान:**",
"lang_msg_text": "**🌐 भाषा:**",
"location_msg_text": "**📍 स्थान:**",
"type_msg_text": "**🏷️ प्रकार:**",
"on_msg_text": "**⏰ समय:**",
"by_msg_text": "**👤 द्वारा:**",
"contributor_you": "(आप)",
"contributor_logged_in": "(लॉगिन किया हुआ उपयोगकर्ता)",
"dialog_placeholder": "संवाद, उद्धरण या स्थानीय कहावत",
"logged_out_success": "सफलतापूर्वक लॉग आउट हो गए!",
"welcome_back": "आपका स्वागत है",
"could_not_detect_location_warning": "स्थान का स्वचालित रूप से पता नहीं चल सका। स्थान डेटा के बिना आगे बढ़ रहा है।",
"leaderboard_subheader": "शीर्ष मुहावरा पहचानने वाले!",
"leaderboard_username_col": "उपयोगकर्ता नाम",
"leaderboard_score_col": "कुल स्कोर",
"no_scores_yet": "अभी तक कोई स्कोर दर्ज नहीं किया गया है! लीडरबोर्ड पर आने के लिए सबसे पहले खेलें।",
"story_play_subheader": "खेलें: कहानी पूरी करें!",
"story_starter_text": "**कहानी की शुरुआत:**",
"your_story_continuation_label": "आपकी कहानी जारी रखें:",
"submit_story_button": "कहानी सबमिट करें",
"story_submitted_success": "✅ कहानी सबमिट की गई! आपके रचनात्मक योगदान के लिए धन्यवाद!",
"no_starters_for_lang": "चयनित भाषा के लिए कोई कहानी शुरुआती उपलब्ध नहीं हैं। कृपया कोई अन्य भाषा चुनें या और कहानियाँ योगदान करें!",
"story_empty_error": "🚨 आपकी कहानी जारी नहीं रह सकती। रचनात्मक बनें!"
}
}