diff --git a/NINJA CODERS/.env b/NINJA CODERS/.env new file mode 100644 index 000000000..db41e6067 --- /dev/null +++ b/NINJA CODERS/.env @@ -0,0 +1,2 @@ +GOOGLE_API_KEY = "AIzaSyAbUsuvTBUugpPGe1t0gyrNrbdnqa7bEJg" +HUGGINGFACE_API_TOKEN = "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" diff --git a/NINJA CODERS/Pitch Deck - Languito.ai.pdf b/NINJA CODERS/Pitch Deck - Languito.ai.pdf new file mode 100644 index 000000000..e0df0b080 Binary files /dev/null and b/NINJA CODERS/Pitch Deck - Languito.ai.pdf differ diff --git a/NINJA CODERS/app/app.py b/NINJA CODERS/app/app.py new file mode 100644 index 000000000..26077cbdd --- /dev/null +++ b/NINJA CODERS/app/app.py @@ -0,0 +1,19 @@ +import streamlit as st + + +pages = { + "Principal": [ + st.Page("pages/home/main.py", title="๐Ÿ  Home "), + ], + "Activities": [ + st.Page("pages/features/quiz.py", title="๐Ÿ“ Quiz "), + st.Page("pages/features/block_quiz.py", title="๐Ÿ“ Block Quiz"), + st.Page("pages/features/languito_chat.py", title="๐Ÿ’ฌ Chat"), + st.Page("pages/features/languito_translator.py", title="๐ŸŒ Translator"), + st.Page("pages/features/text2speech.py", title="๐Ÿ—ฃ Prononciation"), + st.Page("pages/features/languito_dictionnary.py", title="๐Ÿ“™ Dictionnary"), + ], +} + +pg = st.navigation(pages) +pg.run() \ No newline at end of file diff --git a/NINJA CODERS/app/images/banner.png b/NINJA CODERS/app/images/banner.png new file mode 100644 index 000000000..c36dd1fee Binary files /dev/null and b/NINJA CODERS/app/images/banner.png differ diff --git a/NINJA CODERS/app/images/logo.png b/NINJA CODERS/app/images/logo.png new file mode 100644 index 000000000..ede5d2c99 Binary files /dev/null and b/NINJA CODERS/app/images/logo.png differ diff --git a/NINJA CODERS/app/images/workflow.png b/NINJA CODERS/app/images/workflow.png new file mode 100644 index 000000000..e9cb7bf36 Binary files /dev/null and b/NINJA CODERS/app/images/workflow.png differ diff --git a/NINJA CODERS/app/pages/dataset/Multimodal RAG.pdf b/NINJA CODERS/app/pages/dataset/Multimodal RAG.pdf new file mode 100644 index 000000000..d27418e3a Binary files /dev/null and b/NINJA CODERS/app/pages/dataset/Multimodal RAG.pdf differ diff --git a/NINJA CODERS/app/pages/dataset/imagenet_b_darija.pdf b/NINJA CODERS/app/pages/dataset/imagenet_b_darija.pdf new file mode 100644 index 000000000..b4b437029 Binary files /dev/null and b/NINJA CODERS/app/pages/dataset/imagenet_b_darija.pdf differ diff --git a/NINJA CODERS/app/pages/dataset/valid_1.pdf b/NINJA CODERS/app/pages/dataset/valid_1.pdf new file mode 100644 index 000000000..7d107a52b Binary files /dev/null and b/NINJA CODERS/app/pages/dataset/valid_1.pdf differ diff --git a/NINJA CODERS/app/pages/features/block_quiz.py b/NINJA CODERS/app/pages/features/block_quiz.py new file mode 100644 index 000000000..8bf603da1 --- /dev/null +++ b/NINJA CODERS/app/pages/features/block_quiz.py @@ -0,0 +1,103 @@ +import streamlit as st +import random +from gtts import gTTS +from io import BytesIO + +# Simple sentence generator +def generate_sentence(): + templates = [ + "The {adjective} {noun} {verb} {adverb}.", + "{subject} {verb} {object} {adverb}.", + "In the {place}, {subject} {verb} {object}.", + "{timeframe}, {subject} will {verb} {object}.", + "{subject} {verb} {object} because {reason}." + ] + + words = { + "adjective": ["happy", "sad", "excited", "curious", "friendly", "brave"], + "noun": ["cat", "dog", "bird", "child", "teacher", "student"], + "verb": ["runs", "jumps", "sings", "reads", "writes", "plays"], + "adverb": ["quickly", "slowly", "loudly", "quietly", "carefully", "happily"], + "subject": ["The boy", "The girl", "The teacher", "The dog", "My friend", "The student"], + "object": ["the ball", "a book", "the guitar", "homework", "a game", "the puzzle"], + "place": ["park", "school", "library", "garden", "playground", "museum"], + "timeframe": ["Tomorrow", "Next week", "In the future", "Soon", "Later today"], + "reason": ["it's fun", "it's important", "they enjoy it", "it's a hobby", "it's challenging"] + } + + template = random.choice(templates) + sentence = template.format(**{k: random.choice(v) for k, v in words.items()}) + return sentence + +# Function to scramble a sentence into words and add tricky words +def scramble_sentence(sentence): + words = sentence.lower().split() + scrambled = words.copy() + random.shuffle(scrambled) + + # Add tricky words + tricky_words = ["however", "although", "nevertheless", "suddenly", "meanwhile"] + scrambled.extend(random.sample(tricky_words, 2)) + random.shuffle(scrambled) + + return words, scrambled + +# Function to generate audio for the sentence +def text_to_speech_quiz(sentence): + tts = gTTS(text=sentence, lang="en", slow=False) + buf = BytesIO() + tts.write_to_fp(buf) + buf.seek(0) + return buf + +# Streamlit setup +st.title("๐ŸŽค๏ธ Languito Block Quiz!") +st.markdown("**Listen to the audio and arrange the blocks in the correct order. Watch out for tricky words!**") + +# Generate or retrieve a sentence +if "original_sentence" not in st.session_state: + st.session_state.original_sentence = generate_sentence() + +# Generate or retrieve scrambled words +if "correct_words" not in st.session_state or "scrambled_words" not in st.session_state: + st.session_state.correct_words, st.session_state.scrambled_words = scramble_sentence(st.session_state.original_sentence) + +# Play the audio +audio_bytes = text_to_speech_quiz(st.session_state.original_sentence) +st.audio(audio_bytes, format="audio/mp3") + +# Display scrambled words as buttons +st.write("### Arrange the words:") +selected_order = st.empty() + +selected_words = st.session_state.get("selected_words", []) + +# Show buttons for scrambled words +cols = st.columns(4) +for i, word in enumerate(st.session_state.scrambled_words): + if word not in selected_words: + if cols[i % 4].button(word, key=word): + selected_words.append(word) + st.session_state.selected_words = selected_words + +# Display selected words +st.write("### Your sentence:") +st.write(" ".join(selected_words)) + +# Check the answer +if len(selected_words) == len(st.session_state.correct_words): + if selected_words == st.session_state.correct_words: + st.success("๐ŸŽ‰ Correct! Great job!") + else: + st.error("โŒ Incorrect. The correct sentence was: " + " ".join(st.session_state.correct_words)) + + if st.button("New Quiz"): + st.session_state.original_sentence = generate_sentence() + st.session_state.correct_words, st.session_state.scrambled_words = scramble_sentence(st.session_state.original_sentence) + st.session_state.selected_words = [] + +# Reset state when user wants a new quiz +if st.button("Reset Quiz"): + st.session_state.original_sentence = generate_sentence() + st.session_state.correct_words, st.session_state.scrambled_words = scramble_sentence(st.session_state.original_sentence) + st.session_state.selected_words = [] \ No newline at end of file diff --git a/NINJA CODERS/app/pages/features/languito_chat.py b/NINJA CODERS/app/pages/features/languito_chat.py new file mode 100644 index 000000000..669ece22c --- /dev/null +++ b/NINJA CODERS/app/pages/features/languito_chat.py @@ -0,0 +1,239 @@ +from dotenv import load_dotenv +import streamlit as st +import os +import logging +import json +from datetime import datetime +from langchain import PromptTemplate +from langchain_google_genai import ChatGoogleGenerativeAI +from langchain.memory import ConversationBufferMemory +from langchain.chains import ConversationChain +import warnings + +warnings.filterwarnings("ignore") + +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +class GeminiChat: + def __init__(self): + load_dotenv() + # self.api_key = os.getenv("GOOGLE_API_KEY") + try: + self.api_key = os.getenv("GOOGLE_API_KEY") or st.secrets["GOOGLE_API_KEY"] + except KeyError: + st.error("Google API Key is not set. Please provide it as an environment variable or in Streamlit secrets.") + + if not self.api_key: + raise ValueError("GOOGLE_API_KEY not found in environment variables") + + self.setup_chat() + + def setup_chat(self) -> None: + """Initialize the ChatGoogleGenerativeAI with memory""" + try: + self.llm = ChatGoogleGenerativeAI( + model="gemini-pro", + google_api_key=self.api_key, + temperature=0.7 + ) + + # Initialize conversation memory + self.memory = ConversationBufferMemory() + + # Create conversation chain with memory + self.conversation = ConversationChain( + llm=self.llm, + memory=self.memory, + verbose=False + ) + + self.template = """ + You are a multilingual language teacher specializing in teaching and translating various languages. + your name is Languito. + When answering questions: + 1. If the user asks for translations, provide accurate translations for the requested languages. + 2. If the user asks for grammar rules or language tips, explain them clearly and concisely. + 3. If the user asks for examples, provide them with practical, everyday scenarios. + 4. If the user asks for a quiz, create a brief, fun language quiz with answers. + + Previous conversation: + {history} + + Current Question: {question} + if it is no question answer as human + Response: + """ + self.prompt_template = PromptTemplate( + template=self.template, + input_variables=["history", "question"] + ) + except Exception as e: + logger.error(f"Error setting up Chat: {str(e)}") + raise + + def get_response(self, question: str, chat_history: list) -> str: + """Get response from ChatGoogleGenerativeAI with conversation history""" + try: + # Format chat history + history_text = "\n".join([f"{role}: {msg}" for role, msg in chat_history]) + + # Get response using the conversation chain + response = self.conversation.predict( + input=self.prompt_template.format( + history=history_text, + question=question + ) + ) + return response + except Exception as e: + logger.error(f"Error getting response: {str(e)}") + raise + +class StreamlitApp: + def __init__(self): + self.setup_page() + self.initialize_session_state() + self.load_chat_history() + self.gemini = GeminiChat() + + def setup_page(self) -> None: + """Configure Streamlit page settings""" + st.set_page_config( + page_title="Language Teacher", + page_icon="๐Ÿค–", + layout="wide" + ) + + def initialize_session_state(self) -> None: + """Initialize session state variables""" + if 'chats' not in st.session_state: + st.session_state['chats'] = {} + if 'current_chat_id' not in st.session_state: + st.session_state['current_chat_id'] = None + if 'chat_history' not in st.session_state: + st.session_state['chat_history'] = [] + + def save_chat_history(self) -> None: + """Save chat history to a JSON file""" + try: + data = { + 'chats': st.session_state['chats'], + 'current_chat_id': st.session_state['current_chat_id'] + } + with open('chat_history.json', 'w') as f: + json.dump(data, f) + except Exception as e: + logger.error(f"Error saving chat history: {str(e)}") + + def load_chat_history(self) -> None: + """Load chat history from JSON file""" + try: + if os.path.exists('chat_history.json'): + with open('chat_history.json', 'r') as f: + data = json.load(f) + st.session_state['chats'] = data.get('chats', {}) + st.session_state['current_chat_id'] = data.get('current_chat_id') + if st.session_state['current_chat_id']: + st.session_state['chat_history'] = st.session_state['chats'][st.session_state['current_chat_id']]['messages'] + except Exception as e: + logger.error(f"Error loading chat history: {str(e)}") + + def create_new_chat(self) -> None: + """Create a new chat session""" + if st.session_state['current_chat_id']: + current_chat = st.session_state['chats'][st.session_state['current_chat_id']] + if not current_chat['messages']: + st.warning("The current chat is empty. Use it before creating a new one.") + return + + chat_id = datetime.now().strftime("%Y%m%d_%H%M%S") + st.session_state['chats'][chat_id] = { + 'name': f"Chat {len(st.session_state['chats']) + 1}", + 'messages': [] + } + st.session_state['current_chat_id'] = chat_id + st.session_state['chat_history'] = [] + self.save_chat_history() + + def switch_chat(self, chat_id: str) -> None: + """Switch to a different chat session""" + st.session_state['current_chat_id'] = chat_id + st.session_state['chat_history'] = st.session_state['chats'][chat_id]['messages'] + self.save_chat_history() + + def display_chat_selector(self) -> None: + """Display chat selection sidebar""" + with st.sidebar: + st.title("Chats") + + if st.button("New Chat", type="secondary", key="new_chat", use_container_width=True): + self.create_new_chat() + st.rerun() + + for chat_id, chat_data in list(st.session_state['chats'].items()): + cols = st.columns([5, 1]) + + if cols[0].button( + chat_data['name'], + key=f"chat_{chat_id}", + type="secondary" if chat_id != st.session_state['current_chat_id'] else "primary", + use_container_width=True + ): + self.switch_chat(chat_id) + st.rerun() + + if cols[1].button("๐Ÿ—‘๏ธ", key=f"delete_{chat_id}"): + del st.session_state['chats'][chat_id] + + if st.session_state['current_chat_id'] == chat_id: + st.session_state['current_chat_id'] = None + st.session_state['chat_history'] = [] + + self.save_chat_history() + st.rerun() + + def display_chat_messages(self) -> None: + """Display chat messages""" + for role, text in st.session_state['chat_history']: + with st.chat_message("user" if role == "You" else "assistant"): + st.write(text) + + def main(self) -> None: + """Main application logic""" + if not st.session_state['chats']: + self.create_new_chat() + + self.display_chat_selector() + + st.title("๐Ÿ’ฌ Languito Chat!") + + self.display_chat_messages() + if prompt := st.chat_input("Type your message here..."): + try: + with st.chat_message("user"): + st.write(prompt) + st.session_state['chat_history'].append(("You", prompt)) + + with st.chat_message("assistant"): + with st.spinner("Thinking..."): + response = self.gemini.get_response(prompt, st.session_state['chat_history']) + st.write(response) + + st.session_state['chat_history'].append(("Bot", response)) + + if st.session_state['current_chat_id']: + st.session_state['chats'][st.session_state['current_chat_id']]['messages'] = st.session_state['chat_history'] + self.save_chat_history() + + except Exception as e: + st.error(f"An error occurred: {str(e)}") + logger.error(f"Error in main loop: {str(e)}") + +try: + app = StreamlitApp() + app.main() +except Exception as e: + st.error(f"Application failed to start: {str(e)}") + logger.error(f"Application error: {str(e)}") diff --git a/NINJA CODERS/app/pages/features/languito_dictionnary.py b/NINJA CODERS/app/pages/features/languito_dictionnary.py new file mode 100644 index 000000000..c782586f5 --- /dev/null +++ b/NINJA CODERS/app/pages/features/languito_dictionnary.py @@ -0,0 +1,314 @@ +import streamlit as st +import google.generativeai as genai +from dotenv import load_dotenv +import os +import warnings +import json +from gtts import gTTS +import base64 +from io import BytesIO + +# Load environment variables +load_dotenv() +GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY") + +# Configure Gemini API +genai.configure(api_key=GOOGLE_API_KEY) + +# Suppress warnings +warnings.filterwarnings("ignore") + +# Streamlit app configuration +st.set_page_config(page_title="Languito Dictionnary", page_icon="๐Ÿ“–", layout="wide") + +# Language mapping for gTTS +LANGUAGE_CODES = { + "English": "en", + "French": "fr", + "Spanish": "es", + "German": "de", + "Italian": "it", + "Portuguese": "pt", + "Chinese": "zh-CN", + "Arabic": "ar", + "Russian": "ru", + "Darija (Moroccan)": "ar" # Using Arabic code as closest approximation +} + +# Title +st.markdown(""" +
+

๐Ÿ“– Word Context Explorer

+

Discover Meanings and Usages with AI

+
+""", unsafe_allow_html=True) + +# Language selection for input (word language) +input_language = st.selectbox( + "Select Language for Word Input:", + list(LANGUAGE_CODES.keys()) +) + +# Language selection for output (contextual explanation language) +output_language = st.selectbox( + "Select Language for Output:", + list(LANGUAGE_CODES.keys()) +) + +def text_to_speech(text, lang_code): + """ + Convert text to speech using gTTS + """ + try: + # Ensure text is not empty + if not text or not text.strip(): + return None + + tts = gTTS(text=text, lang=lang_code, slow=False) + buf = BytesIO() + tts.write_to_fp(buf) + buf.seek(0) + return buf + except Exception as e: + st.error(f"Audio generation error for '{text}': {str(e)}") + return None + +def get_audio_player(audio_bytes, key=None): + """ + Create an HTML5 audio player for the generated speech + """ + if audio_bytes is None: + return "" + + b64 = base64.b64encode(audio_bytes.getvalue()).decode() + # Add unique key to prevent audio player conflicts + unique_key = f'key="{key}"' if key else '' + return f'' + +def generate_audio_for_content(content, lang_code): + """ + Generate audio for different content types + """ + audio_dict = {} + + # Check if content is a list or string + if isinstance(content, list): + for i, item in enumerate(content): + if item and item.strip(): + audio = text_to_speech(item, lang_code) + if audio: + audio_dict[f"item_{i}"] = audio + elif isinstance(content, str) and content.strip(): + audio = text_to_speech(content, lang_code) + if audio: + audio_dict["main"] = audio + + return audio_dict + +def get_word_context(word, input_language, output_language): + """ + Retrieve contextual information for a given word using Gemini API + """ + prompt = f""" + Provide a comprehensive linguistic analysis of the word "{word}" in {input_language}, and return the explanation in {output_language}. Include: + 1. Definition + 2. Parts of Speech + 3. Etymology + 4. 3-4 Example Sentences + 5. Synonyms + 6. Related Words or Nuanced Meanings + + Return the response as a valid JSON string with these keys: + {{ + "definition": "", + "parts_of_speech": "", + "etymology": "", + "examples": [], + "synonyms": [], + "related_words": [] + }} + """ + + try: + model = genai.GenerativeModel('gemini-pro') + response = model.generate_content(prompt) + + import re + json_match = re.search(r'\{.*\}', response.text, re.DOTALL) + + if json_match: + json_str = json_match.group(0) + return json_str + else: + return json.dumps({ + "definition": "Unable to extract structured context.", + "parts_of_speech": "Unknown", + "etymology": "Not available", + "examples": ["No examples could be generated."], + "synonyms": [], + "related_words": [] + }) + + except Exception as e: + return json.dumps({ + "definition": f"Error retrieving context: {str(e)}", + "parts_of_speech": "Unknown", + "etymology": "Not available", + "examples": ["No examples could be generated."], + "synonyms": [], + "related_words": [] + }) + +# Word input +col1, col2 = st.columns([3, 1]) + +with col1: + word_input = st.text_input("Enter a word to explore:", placeholder="Type a word...") + +with col2: + st.write("") # Spacer + st.write("") # Spacer + context_button = st.button("๐Ÿ” Explore", type="primary") + +# Context display +if context_button and word_input: + with st.spinner('Fetching word context...'): + context_result_str = get_word_context(word_input, input_language, output_language) + + try: + context_result = json.loads(context_result_str) + except json.JSONDecodeError: + context_result = { + "definition": context_result_str, + "parts_of_speech": "Unknown", + "etymology": "Not available", + "examples": ["No examples could be generated."], + "synonyms": [], + "related_words": [] + } + + # Determine language code for audio generation from the output language + audio_lang_code = LANGUAGE_CODES.get(output_language, 'en') + + # Generate audio for various content + audio_contents = { + "word": generate_audio_for_content(word_input, audio_lang_code), + "definition": generate_audio_for_content(context_result.get('definition', ''), audio_lang_code), + "parts_of_speech": generate_audio_for_content(context_result.get('parts_of_speech', ''), audio_lang_code), + "etymology": generate_audio_for_content(context_result.get('etymology', ''), audio_lang_code), + "examples": generate_audio_for_content(context_result.get('examples', []), audio_lang_code), + "synonyms": generate_audio_for_content(context_result.get('synonyms', []), audio_lang_code), + "related_words": generate_audio_for_content(context_result.get('related_words', []), audio_lang_code) + } + + # Display word with audio in the same line but with added space + st.markdown(f""" + ### ๐Ÿ”ค Word: + + {word_input} + + {get_audio_player(audio_contents['word'].get('main'), 'word') if audio_contents['word'] else ''} + + + """, unsafe_allow_html=True) + + # Display the results in card layout + st.markdown("
", unsafe_allow_html=True) + + # Definition Card + st.markdown(f""" +
+

๐Ÿ“˜ Definition

+

{context_result.get('definition', 'No definition found.')}

+
+ {get_audio_player(next(iter(audio_contents['definition'].values()), None), 'definition') if audio_contents['definition'] else ''} +
+
+ """, unsafe_allow_html=True) + + # Parts of Speech Card + st.markdown(f""" +
+

๐Ÿ“ Parts of Speech

+

{context_result.get('parts_of_speech', 'Unknown')}

+
+ {get_audio_player(next(iter(audio_contents['parts_of_speech'].values()), None), 'parts_of_speech') if audio_contents['parts_of_speech'] else ''} +
+
+ """, unsafe_allow_html=True) + + # Example Sentences Card + st.markdown(""" +
+

๐Ÿ—ฃ๏ธ Example Usage

+
", unsafe_allow_html=True) + + # Etymology Card + st.markdown(f""" +
+

๐Ÿ•ฐ๏ธ Etymology

+

{context_result.get('etymology', 'Etymology not found.')}

+
+ {get_audio_player(next(iter(audio_contents['etymology'].values()), None), 'etymology') if audio_contents['etymology'] else ''} +
+
+ """, unsafe_allow_html=True) + + # Synonyms Card + synonyms = context_result.get('synonyms', []) + if synonyms: + st.markdown(""" +
+

๐Ÿ“š Synonyms

+

+ """, unsafe_allow_html=True) + + for i, synonym in enumerate(synonyms): + st.markdown(f""" + + {synonym} + + {get_audio_player(audio_contents['synonyms'].get(f'item_{i}'), f'synonym_{i}') if audio_contents['synonyms'] else ''} + + + """, unsafe_allow_html=True) + + st.markdown("

", unsafe_allow_html=True) + + # Related Words Card + related_words = context_result.get('related_words', []) + if related_words: + st.markdown(""" +
+

๐Ÿ” Related Words

+

+ """, unsafe_allow_html=True) + + for i, related_word in enumerate(related_words): + st.markdown(f""" + + {related_word} + + {get_audio_player(audio_contents['related_words'].get(f'item_{i}'), f'related_{i}') if audio_contents['related_words'] else ''} + + + """, unsafe_allow_html=True) + + st.markdown("

", unsafe_allow_html=True) + + st.markdown("
", unsafe_allow_html=True) + diff --git a/NINJA CODERS/app/pages/features/languito_translator.py b/NINJA CODERS/app/pages/features/languito_translator.py new file mode 100644 index 000000000..067537aa6 --- /dev/null +++ b/NINJA CODERS/app/pages/features/languito_translator.py @@ -0,0 +1,169 @@ +import streamlit as st +import requests +import os +from dotenv import load_dotenv +from gtts import gTTS +import base64 +from io import BytesIO + +# Load environment variables +load_dotenv() + +# Hugging Face API setup +API_URL = "https://api-inference.huggingface.co/models/Helsinki-NLP/opus-mt-{}-{}" +try: + API_TOKEN = os.getenv("HUGGINGFACE_API_TOKEN") or st.secrets["HUGGINGFACE_API_TOKEN"] +except KeyError: + st.error("Google API Key is not set. Please provide it as an environment variable or in Streamlit secrets.") + +headers = {"Authorization": f"Bearer {API_TOKEN}"} + +def translate(text, source_lang, target_lang): + model_url = API_URL.format(source_lang, target_lang) + payload = {"inputs": text} + response = requests.post(model_url, headers=headers, json=payload) + if response.status_code == 200: + return response.json()[0]['translation_text'] + else: + st.error(f"Translation failed. Status code: {response.status_code}") + return None + +def text_to_speech(text, lang): + try: + tts = gTTS(text=text, lang=lang, slow=False) + buf = BytesIO() + tts.write_to_fp(buf) + buf.seek(0) + return buf + except Exception as e: + st.error(f"An error occurred during speech synthesis: {str(e)}") + return None + +def get_audio_player(audio_bytes): + b64 = base64.b64encode(audio_bytes.getvalue()).decode() + return f'' + +# Initialize session state for audio containers +if 'audio_container_input' not in st.session_state: + st.session_state.audio_container_input = None +if 'audio_container_output' not in st.session_state: + st.session_state.audio_container_output = None + +# Streamlit app +st.set_page_config(page_title="Languito Translator", page_icon="๐ŸŒ", layout="wide") + +# Title section +st.markdown(""" +
+

๐ŸŒ Languito Translator

+

Your Advanced Language Translation Platform

+
+""", unsafe_allow_html=True) + +# Language selection +languages = { + "en": "English", + "fr": "French", + "es": "Spanish", + "de": "German", + "it": "Italian", + "ja": "Japanese", + "zh": "Chinese", + "ru": "Russian", + "ar": "Arabic", + "hi": "Hindi", + "pt": "Portuguese", + "nl": "Dutch", + "ko": "Korean", + "tr": "Turkish", + "pl": "Polish", + "sv": "Swedish" +} + +col1, col2 = st.columns(2) + +with col1: + source_lang = st.selectbox("Translate from:", list(languages.values()), index=0, key="source") + source_code = [code for code, lang in languages.items() if lang == source_lang][0] + +with col2: + target_lang = st.selectbox("Translate to:", list(languages.values()), index=1, key="target") + target_code = [code for code, lang in languages.items() if lang == target_lang][0] + +# Input and output areas side by side +col_input, col_output = st.columns(2) + +with col_input: + st.markdown(f"### Enter {source_lang} text:") + col1, col2 = st.columns([0.9, 0.1]) + with col1: + input_text = st.text_area("", height=200, key="input", placeholder="Type or paste your text here...", help="Enter the text you want to translate", max_chars=5000) + with col2: + # Create a container for the audio player + audio_container_input = st.empty() + if st.button("๐Ÿ”Š", key="input_speech", help="Listen to text", kwargs={"className": "speech-button"}): + if input_text: + audio_bytes = text_to_speech(input_text, source_code) + if audio_bytes: + audio_container_input.markdown(get_audio_player(audio_bytes), unsafe_allow_html=True) + char_count = len(input_text) + word_count = len(input_text.split()) + st.text(f"Character count: {char_count} | Word count: {word_count}") + +with col_output: + st.markdown(f"### Translated {target_lang} text:") + if 'translated_text' not in st.session_state: + st.session_state.translated_text = "" + + col3, col4 = st.columns([0.9, 0.1]) + with col3: + output_placeholder = st.empty() + output_char_count = st.empty() + with col4: + # Create a container for the audio player + audio_container_output = st.empty() + if st.button("๐Ÿ”Š", key="output_speech", help="Listen to translation", kwargs={"className": "speech-button"}): + if st.session_state.translated_text: + audio_bytes = text_to_speech(st.session_state.translated_text, target_code) + if audio_bytes: + audio_container_output.markdown(get_audio_player(audio_bytes), unsafe_allow_html=True) + +# Translate button +if st.button("๐Ÿ”„ Translate", type="primary"): + if input_text: + try: + with st.spinner("Translating..."): + translated_text = translate(input_text, source_code, target_code) + if translated_text: + st.session_state.translated_text = translated_text + output_placeholder.markdown(f'
{translated_text}
', unsafe_allow_html=True) + output_char_count.text(f"Character count: {len(translated_text)} | Word count: {len(translated_text.split())}") + except Exception as e: + st.error(f"An error occurred: {str(e)}") + else: + st.warning("Please enter some text to translate.") + +# Additional features +st.markdown("---") +col3, col4 = st.columns(2) + +with col3: + st.markdown("### Recent Updates") + st.info(""" + - Added text-to-speech functionality for input and output text + - Added support for more language pairs + - Improved error handling + - Enhanced UI with custom styling + - Added character and word count for both input and output + """) + +with col4: + st.markdown("### Usage Tips") + st.success(""" + - For best results, enter clear and complete sentences + - Maximum recommended length: 5000 characters per translation + - Supports multiple paragraphs + - Use the language selection dropdowns to choose your desired languages + - Click on the speaker icon to hear the text spoken + """) + diff --git a/NINJA CODERS/app/pages/features/quiz.py b/NINJA CODERS/app/pages/features/quiz.py new file mode 100644 index 000000000..fdedd7d03 --- /dev/null +++ b/NINJA CODERS/app/pages/features/quiz.py @@ -0,0 +1,401 @@ + +from dotenv import load_dotenv +import streamlit as st +import os +import google.generativeai as genai +from typing import Iterator, Dict, List +import logging +import json +import random +import hashlib + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +class GeminiQuiz: + def __init__(self): + load_dotenv() + # self.api_key = os.getenv("GOOGLE_API_KEY") + try: + self.api_key = os.getenv("GOOGLE_API_KEY") or st.secrets["GOOGLE_API_KEY"] + except KeyError: + st.error("Google API Key is not set. Please provide it as an environment variable or in Streamlit secrets.") + + + + if not self.api_key: + raise ValueError("GOOGLE_API_KEY not found in environment variables") + + self.setup_genai() + self.max_retries = 5 + + # Initialize question history in session state if not exists + if 'question_history' not in st.session_state: + st.session_state.question_history = set() + + # Track used difficulties to ensure variety + if 'used_difficulties' not in st.session_state: + st.session_state.used_difficulties = [] + + def setup_genai(self) -> None: + try: + genai.configure(api_key=self.api_key) + self.model = genai.GenerativeModel("gemini-pro") + except Exception as e: + logger.error(f"Error setting up Gemini: {str(e)}") + raise + + def get_balanced_difficulty(self) -> str: + """Ensure a balanced distribution of difficulty levels""" + difficulties = ["beginner", "intermediate", "advanced"] + + if len(st.session_state.used_difficulties) >= 10: # Reset after 10 questions + st.session_state.used_difficulties = [] + + # Count current difficulty distribution + difficulty_counts = {diff: st.session_state.used_difficulties.count(diff) for diff in difficulties} + + # Filter out overused difficulties (more than 1/3 of total questions) + available_difficulties = [ + diff for diff in difficulties + if difficulty_counts[diff] < (len(st.session_state.used_difficulties) + 1) / 3 + ] + + # If all difficulties are equally distributed, allow any + if not available_difficulties: + available_difficulties = difficulties + + selected_difficulty = random.choice(available_difficulties) + st.session_state.used_difficulties.append(selected_difficulty) + return selected_difficulty + + def get_language_prompt(self, user_language: str, target_language: str, category: str) -> str: + """Generate appropriate prompt based on languages and category""" + difficulty_levels = { + "beginner": "basic vocabulary and simple structures", + "intermediate": "moderate complexity and common usage patterns", + "advanced": "complex language features and nuanced usage" + } + + base_difficulty = self.get_balanced_difficulty() + + # Add specific constraints to ensure uniqueness + base_constraints = f""" + Constraints for generating unique questions: + - Use diverse question formats (fill-in-blank, scenario-based, translation, etc.) + - Include practical, real-world contexts + - Vary the topics within the category + - Ensure cultural relevance to {target_language}-speaking regions + - Don't repeat common textbook examples + """ + + prompts = { + "Grammar": f""" + Generate a {base_difficulty}-level multiple-choice question for language learning. + Context: Question about {target_language} grammar, written in {user_language}. + Focus Area: {difficulty_levels[base_difficulty]} + {base_constraints} + Additional Grammar-specific requirements: + - Include varied sentence structures + - Focus on practical usage rather than technical terms + - Incorporate common language patterns + + Return strictly in this JSON format: + {{ + "question": "Clear, well-formulated question", + "options": ["Option 1", "Option 2", "Option 3", "Option 4"], + "correct_answer": "The correct option exactly as written in options", + "explanation": "Detailed explanation of why the answer is correct", + "difficulty": "{base_difficulty}", + "topic": "Specific grammar topic covered" + }} + """, + "Vocabulary": f""" + Generate a {base_difficulty}-level vocabulary question for language learning. + Context: Question about {target_language} vocabulary, written in {user_language}. + Focus Area: {difficulty_levels[base_difficulty]} + {base_constraints} + Additional Vocabulary-specific requirements: + - Use words in context-rich situations + - Include collocations and common word pairs + - Focus on frequency-based vocabulary selection + + Return strictly in this JSON format: + {{ + "question": "Clear, well-formulated question", + "options": ["Option 1", "Option 2", "Option 3", "Option 4"], + "correct_answer": "The correct option exactly as written in options", + "explanation": "Detailed explanation including usage examples", + "difficulty": "{base_difficulty}", + "topic": "Specific vocabulary theme" + }} + """, + "Common Phrases": f""" + Generate a {base_difficulty}-level question about common phrases. + Context: Question about {target_language} expressions, written in {user_language}. + Focus Area: {difficulty_levels[base_difficulty]} + {base_constraints} + Additional Phrase-specific requirements: + - Include contemporary expressions + - Focus on situational appropriateness + - Cover various social contexts + + Return strictly in this JSON format: + {{ + "question": "Clear, well-formulated question", + "options": ["Option 1", "Option 2", "Option 3", "Option 4"], + "correct_answer": "The correct option exactly as written in options", + "explanation": "Detailed explanation with cultural context", + "difficulty": "{base_difficulty}", + "topic": "Specific phrase category or situation" + }} + """ + } + + return prompts[category] + "\nProvide only the JSON response without any additional text." + + def calculate_question_hash(self, question_data: Dict) -> str: + """Calculate a unique hash for a question based on its content""" + # Create a string combining multiple aspects of the question + question_string = ( + f"{question_data['question'].lower()}" + f"{','.join(sorted(opt.lower() for opt in question_data['options']))}" + f"{question_data['correct_answer'].lower()}" + f"{question_data.get('topic', '').lower()}" + ) + return hashlib.md5(question_string.encode()).hexdigest() + + def is_question_unique(self, question_data: Dict) -> bool: + """Check if a question is unique based on its content""" + question_hash = self.calculate_question_hash(question_data) + if question_hash in st.session_state.question_history: + return False + st.session_state.question_history.add(question_hash) + return True + + def generate_question(self, user_language: str, target_language: str, category: str) -> Dict: + for attempt in range(self.max_retries): + try: + prompt = self.get_language_prompt(user_language, target_language, category) + response = self.model.generate_content(prompt) + + # Clean and parse response + response_text = response.text.strip() + if "```json" in response_text: + response_text = response_text.split("```json")[1].split("```")[0] + elif "```" in response_text: + response_text = response_text.split("```")[1] + + response_text = ( + response_text.strip() + .replace('\n', '') + .replace('\r', '') + .replace('\t', '') + ) + + question_data = json.loads(response_text) + + # Validate question format + required_fields = ["question", "options", "correct_answer", "explanation", "difficulty"] + if not all(field in question_data for field in required_fields): + logger.warning("Missing required fields, retrying...") + continue + + if not isinstance(question_data["options"], list) or len(question_data["options"]) != 4: + logger.warning("Invalid options format, retrying...") + continue + + if question_data["correct_answer"] not in question_data["options"]: + logger.warning("Correct answer not in options, retrying...") + continue + + if self.is_question_unique(question_data): + return question_data + + logger.info(f"Duplicate question on attempt {attempt + 1}, retrying...") + + except Exception as e: + logger.error(f"Error on attempt {attempt + 1}: {str(e)}") + continue + + raise ValueError("Failed to generate a valid unique question after maximum retries") + +class QuizApp: + def __init__(self): + self.setup_page() + self.initialize_session_state() + self.quiz = GeminiQuiz() + self.available_languages = { + "English": "๐Ÿ‡ฌ๐Ÿ‡ง", + "Spanish": "๐Ÿ‡ช๐Ÿ‡ธ", + "French": "๐Ÿ‡ซ๐Ÿ‡ท", + "German": "๐Ÿ‡ฉ๐Ÿ‡ช", + "Italian": "๐Ÿ‡ฎ๐Ÿ‡น", + "Portuguese": "๐Ÿ‡ต๐Ÿ‡น", + "Chinese": "๐Ÿ‡จ๐Ÿ‡ณ", + "Japanese": "๐Ÿ‡ฏ๐Ÿ‡ต", + "Korean": "๐Ÿ‡ฐ๐Ÿ‡ท" + } + self.categories = ["Grammar", "Vocabulary", "Common Phrases"] + self.num_questions = 10 + + def setup_page(self) -> None: + st.set_page_config( + page_title="Languito Quiz", + page_icon="๐ŸŒ", + layout="wide" + ) + + def initialize_session_state(self) -> None: + if 'quiz_started' not in st.session_state: + st.session_state['quiz_started'] = False + if 'current_questions' not in st.session_state: + st.session_state['current_questions'] = [] + if 'current_question_idx' not in st.session_state: + st.session_state['current_question_idx'] = 0 + if 'score' not in st.session_state: + st.session_state['score'] = 0 + if 'user_answers' not in st.session_state: + st.session_state['user_answers'] = {} + if 'quiz_completed' not in st.session_state: + st.session_state['quiz_completed'] = False + + def generate_quiz_questions(self, user_language: str, target_language: str, category: str) -> List[Dict]: + questions = [] + for _ in range(self.num_questions): + try: + question = self.quiz.generate_question(user_language, target_language, category) + questions.append(question) + except Exception as e: + logger.error(f"Error generating question: {str(e)}") + continue + return questions + + def display_progress(self) -> None: + progress = (st.session_state['current_question_idx'] + 1) / self.num_questions + st.progress(progress) + st.write(f"Question {st.session_state['current_question_idx'] + 1} of {self.num_questions}") + + def display_final_results(self) -> None: + st.title("Quiz Complete! ๐ŸŽ‰") + final_score = st.session_state['score'] + percentage = (final_score / self.num_questions) * 100 + + st.header(f"Your Score: {final_score}/{self.num_questions} ({percentage:.1f}%)") + + if percentage >= 90: + st.balloons() + st.success("Outstanding! You're a language master! ๐ŸŒŸ") + elif percentage >= 70: + st.success("Great job! Keep up the good work! ๐Ÿ‘") + elif percentage >= 50: + st.info("Good effort! Keep practicing! ๐Ÿ’ช") + else: + st.warning("Keep studying! You'll improve! ๐Ÿ“š") + + # Display question review + st.subheader("Review Your Answers") + for idx, question in enumerate(st.session_state['current_questions']): + with st.expander(f"Question {idx + 1}: {question['question']}"): + user_answer = st.session_state['user_answers'].get(idx, "Not answered") + st.write(f"Your answer: {user_answer}") + st.write(f"Correct answer: {question['correct_answer']}") + if user_answer == question['correct_answer']: + st.success("Correct! โœ…") + else: + st.error("Incorrect โŒ") + st.info(f"Explanation: {question['explanation']}") + + def main(self) -> None: + st.title("๐ŸŒ Languito Quiz") + + # Sidebar selections + with st.sidebar: + st.title("Quiz Settings") + user_language = st.selectbox( + "Select your language:", + list(self.available_languages.keys()), + format_func=lambda x: f"{self.available_languages[x]} {x}", + key="user_language" + ) + + target_language = st.selectbox( + "Select language to learn:", + [lang for lang in self.available_languages.keys() if lang != user_language], + format_func=lambda x: f"{self.available_languages[x]} {x}", + key="target_language" + ) + + selected_category = st.selectbox( + "Select a category:", + self.categories, + help="Grammar: Learn language rules\nVocabulary: Learn new words\nCommon Phrases: Learn expressions" + ) + + if not st.session_state['quiz_started']: + if st.button("Start Quiz"): + st.session_state['current_questions'] = self.generate_quiz_questions( + user_language, target_language, selected_category + ) + st.session_state['quiz_started'] = True + st.session_state['current_question_idx'] = 0 + st.session_state['score'] = 0 + st.session_state['user_answers'] = {} + st.session_state['quiz_completed'] = False + st.rerun() + + st.divider() + st.metric("Current Score", f"{st.session_state['score']}/{self.num_questions}") + + # Main content area + if st.session_state['quiz_started'] and not st.session_state['quiz_completed']: + self.display_progress() + + current_q = st.session_state['current_questions'][st.session_state['current_question_idx']] + + st.subheader(current_q["question"]) + + user_answer = st.radio( + "Choose your answer:", + current_q["options"], + key=f"q_{st.session_state['current_question_idx']}" + ) + + col1, col2 = st.columns(2) + + with col1: + if st.button("Submit Answer"): + st.session_state['user_answers'][st.session_state['current_question_idx']] = user_answer + if user_answer == current_q["correct_answer"]: + st.session_state['score'] += 1 + + if st.session_state['current_question_idx'] < self.num_questions - 1: + st.session_state['current_question_idx'] += 1 + else: + st.session_state['quiz_completed'] = True + st.rerun() + + with col2: + if st.session_state['current_question_idx'] > 0: + if st.button("Previous Question"): + st.session_state['current_question_idx'] -= 1 + st.rerun() + + elif st.session_state['quiz_completed']: + self.display_final_results() + + if st.button("Start New Quiz"): + st.session_state['quiz_started'] = False + st.session_state['current_questions'] = [] + st.session_state['current_question_idx'] = 0 + st.session_state['score'] = 0 + st.session_state['user_answers'] = {} + st.session_state['quiz_completed'] = False + st.rerun() + +try: + app = QuizApp() + app.main() +except Exception as e: + st.error(f"Application failed to start: {str(e)}") + logger.error(f"Application error: {str(e)}") diff --git a/NINJA CODERS/app/pages/features/text2speech.py b/NINJA CODERS/app/pages/features/text2speech.py new file mode 100644 index 000000000..f478345c9 --- /dev/null +++ b/NINJA CODERS/app/pages/features/text2speech.py @@ -0,0 +1,108 @@ +import streamlit as st +import os +from gtts import gTTS +import base64 +from io import BytesIO + +# Streamlit page configuration +st.set_page_config(page_title="PolyGlot Speech", page_icon="๐ŸŽ™", layout="wide") + +# Load the CSS +# with open("pages/styles/style.css") as f: +# st.markdown(f"", unsafe_allow_html=True) + +# Main app container +# Title section +st.markdown(""" +
+

๐ŸŒ Languito Speech

+

Your Advanced Multi-Language Text-to-Speech Platform

+
+""", unsafe_allow_html=True) + +# Language selection +languages = { + 'en': 'English', + 'fr': 'French', + 'es': 'Spanish', + 'de': 'German', + 'it': 'Italian', + 'ja': 'Japanese', + 'ko': 'Korean', + 'pt': 'Portuguese', + 'nl': 'Dutch', + 'zh-CN': 'Chinese (Simplified)' +} + +selected_lang = st.selectbox("Select Language:", list(languages.values()), index=0) +lang_code = [code for code, lang in languages.items() if lang == selected_lang][0] + +# Text input +st.markdown(f"### Enter {selected_lang} text:") +input_text = st.text_area("", height=150, max_chars=500, help="Enter the text you want to convert to speech") + +# Character and word count +char_count = len(input_text) +word_count = len(input_text.split()) if input_text.strip() else 0 +st.text(f"Character count: {char_count} | Word count: {word_count}") + +def text_to_speech(text, lang): + try: + tts = gTTS(text=text, lang=lang, slow=False) + buf = BytesIO() + tts.write_to_fp(buf) + buf.seek(0) + return buf + except Exception as e: + st.error(f"An error occurred during speech synthesis: {str(e)}") + return None + +def get_audio_player(audio_bytes): + b64 = base64.b64encode(audio_bytes.getvalue()).decode() + return f'' + +# Generate speech button +if st.button("๐ŸŽ™ Generate Speech", type="primary"): + if input_text.strip(): + with st.spinner("Generating speech..."): + audio_bytes = text_to_speech(input_text, lang_code) + if audio_bytes: + st.markdown("### Generated Speech:") + st.markdown(get_audio_player(audio_bytes), unsafe_allow_html=True) + + # Download button + st.download_button( + label="Download Audio", + data=audio_bytes, + file_name=f"speech_{lang_code}.mp3", + mime="audio/mp3" + ) + else: + st.warning("Please enter some text to convert to speech.") + +# Additional features +st.markdown("---") +col1, col2 = st.columns(2) + +with col1: + st.markdown("### Features") + st.info(""" + - High-quality speech synthesis + - Support for 10 languages + - Download audio files + - Real-time character and word counting + - Modern, user-friendly interface + """) + +with col2: + st.markdown("### Usage Tips") + st.success(""" + - For best results, use proper punctuation + - Keep texts under 500 characters for optimal performance + - Try different languages to hear the variations + - Use the download feature to save audio for offline use + """) + +# Footer +st.markdown("---") +st.markdown("Created with โค using Streamlit and gTTS") \ No newline at end of file diff --git a/NINJA CODERS/app/pages/home/main.py b/NINJA CODERS/app/pages/home/main.py new file mode 100644 index 000000000..6d97bd32d --- /dev/null +++ b/NINJA CODERS/app/pages/home/main.py @@ -0,0 +1,145 @@ +import streamlit as st + +# Page configuration +st.set_page_config( + page_title="LanguitoAI - Your Advanced Language Assistant", + layout="wide", + initial_sidebar_state="collapsed" +) + +# Add logo at the top of sidebar +import os + +# Get the absolute path to the image +# image_path = os.path.join(os.getcwd(), 'images', 'logo.png') +image_path = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AABhg0lEQVR4nO3deZwdVZk38N/znFNVd+k1W6ezQgigERENbogkkU0cddSZMK+OyrDYiIrKMO5Lk9FxGRdUZIuioowzgs6MIiBrwio4wVEHImCALJ10FpL0eu+tqnPO8/5RdTvdnc4KIQ2c7/vpeaW7b926nb5Pn+U5zwN4nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nvcCQAf7BjzPO3g6O8GLMU8DwMqVK+3p18Ee7HvaHR+wPO8FqLMTfMKmaYcr4/5KmI4mcQrGrgPrFXFQuueUK57YQoAc7PsczQcsz3uBEYBuPXPqCSWqfaOI2tGWdAARkBMxjMEaFf5HqPxtSvnmRVevqR3s+x3OByzPe4G58dy58xrM1h8VpXosAQQBQA4OOvsPAWooPJVAX+qCxotPXvpE78G+5zofsDzvBeTGM6dOLrG9tOhqf0MkzDDIYtTOoSCBqlSo+WKXmC+fes2mwYNwuzvhg30Dnuc9O+67YEax5OIPl23/W1gMkxOQCNwYwxYSQYik1Oh6PhAW7Fs7O8dHrBgXN+F53oF17WIo+1Tl9CLVPuiIC5YUtCQQYsiwMCAiEBE4IjgARK5VuaRjYXf7hIN39zv4gOV5z3MC0OSmttcTJ58XUCsJQHAwTEhJQYvF6A1BEgdC9gGil8YSHHFw7n4kH7A873nu5jNmH8nWfFkjOTRbrXIgcRAQ2KVwEAgcBBYgl30AoPz/BWIatcOcg/wyAPiA5XnPays65gcBVc8LpfYqIU1a3IivE2QXyVYCB4aAkCIAlHo2bnePfMDyvOex+dsfdBp2HeC2AyKWacwARQIwaOiDiMAAGBaBMz3OJaue7Xsfiz7YN+B53jPnvgtmFCt97iRAasqE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" +# Display the image in the sidebar +st.sidebar.image(image_path, width=300) + +# Custom CSS +st.markdown(""" + +""", unsafe_allow_html=True) + + + +# Header +# banner_path = os.path.join(os.getcwd(), 'images', 'banner.png') + + +st.image("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA5MAAADECAYAAAACjHVbAABDDUlEQVR4nO3debiVV302/nut9Qx7Hs4MHOCEeYYAIQlJLKhtjbW+vipprU0bjaJG0Trb1gFTh6rRtI1GX5yi/mxtcKpaNTEJKEIGDhAIQwjTAQ6c+Zw9D8+w1u+PAxECISQhEuP9uS6uXGQ/+9nrWeePfW6+a30XQERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERELxjiYg+AiIiIXvg6Vy6y02Os6EBB+ktvvb96scdDRETPHsMkERERPac637logmhu+1StNLgsGksdU9HkV/39D69dvOZg/mKPjYiInjmGSSIiInrOdK4c01QI8D9WX89SOw6EIVCtA+6keT+Xuv7mq7+49/jFHiMRET0zDJNERET0nNh+fWu83Nj4De/g7usSjU5oIAUgAB2a6rCn/Ka2dVFZee3SrxeGL/ZYiYjo6ZMXewBERET0wrNuGSxcMv0fK4/tvi6edbWAVFpICUAaoUSk0dXo713utEx/97plsC72eImI6OljmCQiIqILygAie9VVr+nt/M17ko22NlIgEBLKhDAwALQUABIp6FLfwZdjVnPkYo+ZiIiePoZJIiIiuqC2rGxqO7p54ydSCURtyzIwkMIE0KNBEhBm9I8EvGrZTQaButhjJiKip49hkoiIiJ41A4jOldm0WQ0J2PnGKdO35crwvFpVQUAbjDZqUBBQEJBCIKhAJhrH7S16I/WLPX4iInr6GCaJiIjoWdv+8T991VAl3vlI7DUfA6J2amDv37bNu/KvikgcrA/XpDKhFqNlSQBCm1pdVi11yNX44PI7ULvY4ycioqeP3VyJiIjoWelcNWXyUH/vz7LV0ow8gPjkS++LyPqq/Ud27+1o7miuq8htwYFHX5tssiAsS5vAl0PDYb5pxsLrF92y9acXe/xERPTMsDJJREREz9iGv0lnq3XvK0mvNEM0OWFD1tH68LYXDx3a/dups5e/1y1Wi9F635tSC67+f+WhoGb8wNSHw7Bx9hW3FDq3/uJij5+IiJ45hkkiIiJ6RtbdgIg7bspncfzIS610RENLZYSSbiai0zFkBx9a9xlv7CXf9sK46iv+9l3x+Vd9ru9QoPSEqZuqheNfWr4ewcV+BiIieua4zJWIiIieNrMa8uHg6lUjW3/7+USzJaSQwCn/SC2F0EYHKA2FUkyYcY8rin+t/EpgWua+H7Xc9y67ZcfOizd6IiK6EBgmiYiI6Gnb9r4Fy0b2PvyDZFo1wLK0hJbmxK8VAgCEAACthUEw6EnTMeunTm3kjYvG9gxjNcz6ZVADzTDXrUV4ER+DiIieBYZJIiIielq2rxrXPjI4cndMV2bKaFQLhFJDQMBAiNN/tTBQWogQI311NCy48rP5jfd/ZNky6J3OX7wlFO5k7+ijtyy5fXfvRXoUIiJ6FqyLPQAiIiL6w7HthkymGNjfUtXKTJlxQiBUo2dImrNeL6AlhKVdp45aOd+SnAbx4L6GRNW7a1U4EMyUl7TN3LSi/bVL13ZXf79PQkREzxYb8BAREdF56VwJ24yZdrN/tOvFsbSlAahTX39iVRIwMAJae1VpIqo/HpQ/sXgN/GjH9Dda9aAjOwZaFHovcVB2fn9PQUREFwrDJBERET0lAwi3delf5bY/9KZk1tJajtYiBUZD5JlBEqOvGiNzeR2mZr5ozbymw4e3vqGtuXBkx1siCURLFYSJqUt+iOxI5ff8OEREdAEwTBIREdFT2v7uKbMG9zzwiVQaUSgFYYSUQpxstHMGAwENqb1SHU5b+4NB98NfWL8e0pow5Z1hodwOAYRR+5Ap9H9x8Rr4v+fHISKiC4BhkoiIiM5p042phnI+f7sLPRERRwNGnr0SeRqtA08WPfQmU9n3LV4zko/PmjymsPeB18aTSOQLKKcnzv+Py1q6+n8fz0BERBcewyQRERE9qc6VY2JWdtIt4cDAi5yUrQXE+QRJABqVkTBsnnflj53Dj2zZuQKOlc6+X9eDSSYAREvLVjNy4P8Tq6Gf84cgIqLnBMMkERERnZUBhN0y5e8Lex5+fbzR0tKop34TDIyQWlc9qbPZPcFQz8fnrIXnT1gwv7i38xWxGJx8GcOZ5smfWrRmpPCcPwQRET1nGCaJiIjorLa/Z9aC4V0b/imTgQOhYGDO4/cGqREGslhGqbH9kn9ccntX77obEKmH9Q8JgQmVMvzkpDnfK/Tev17gSc4TISKiPwgMk0RERHSGB/9uXGNppP/foxbaheNqnPfvDBrVnI/kjEt/Yu3fejcANLRdtqx8cM81EQfKi8Z2o9x/8/I7UHsOh09ERL8HDJNERER0mn2r4Mrm5k9hcPAaO2E/ZZB8vLwojA7rnvTi8X0oFz40Zy28ravamiuDhz6cjKA5X4LXeMmln738a/1sukNE9AJgXewBEBER/bHbedOsBMa0LwlDoJzfff/SW7urF+re+1ZNceuNjpmzerd3PtcbQOxoXHZ9afP6NyQabf34YZLnIGBgYGmjPVkoodC6YO5H5tz8QPe6ZbBkeuoqr2vDIqEQxifP/l44ePDHXN5KRPTCwMokERHRRbTtho5M2bW/PtR59739m+/+lXI7/nndsgvzj707V8xyis2TPxU4k2/pXDkmdl7jec/seUOP/OZj8bSwpTQIhTyv3xUkAtRHAiRnXPqj4p7unwjAZC+dNX1k94a/lS4iYTT2iOWVP7h4TU/l2T0VERE9XzBMEhERPcfWrV5mrVu97IyAuG4ZrLCl+cO1R7e/NpFFGE9DVg9vfoU9qSl6IT635PRGKrvufnnv3T99s2iY9Jdm9bm/9zfd2N5QLedviwjdLl1bayipTisiGohT/jxOCF2vejJIxvaoWv6jS9d2V7fdkMlUg+CjtsZEr4pyZtLiWy67vavvQjwXERE9PzBMEhERPUfuXAG1/QOLpzfGGj6ZiTX+29YPXDr21NftSU3R6tChl8QzkEZFQktBO7Ho01oCagDR+d5pTVtXXzOrc+Wk9Kmv6UjMsqRVz2QRqVWG/nbHgdYnDanrbuiIxMaO/7h/vPsaN+lqGEhx2hrXJxuW0Ah8VMooNEyY9d7F/3HwiFkNKcfP/7v6ocdepgOEsemXfjMc2PcjLm8lInphYZgkIiJ6Dqy7oSMyecY1b+s70HnPyMYffmD4vh+8vTAy9M11K5oTJ68xrm9Jr2oLBcAYEYSQWsVCq66fYpfiaIhcd1NzYvuHr/q/pd6eewo7NmypK/3Dre+79EpzIgFGjIj4OnCkAyAoj6lm/Cc9KLKhY/yrhrbf/3fxrAX9NH49ENAojmiZmXflt+W+znsBYHPf1I6RRze+3VJIBS0t9wfVoY9yeSsR0QsPwyQREdEFZlZDpseMfcPI5g2fzkTQHm90w2yr0MHAkYWJpsS4k9fZvuuEuu48Hh01oNy4DlxpzGrIzpXZ9LrVZ+6ffOD1DakdH7rqRtezf5nfvfG7aV2cn05Kxx7oevHwoUe+tW3VtHkAEMaTraFvsoEGrFhjuRoqfbbxbn/H9EuG9275aCKGlJCWljqUACDE6MBODu+MhCuE9oqeFC1jHrSGDv7LnLXwtt2QyYQKn5S1YFpJYiDVMP4D13z5yMizmlAiInpeYpgkIiK6wB7u7ZiQ27fpg+kmJIQbDYWxhDEKdlQESv7ufEURicZMGLoCgDCQAkA8nihnxk2bsV3++adLfnpHo3zJG+9cgccrig+/ddo4k2m7Y/CRjV91S8evSqbsiIlGQq1cY2eiflIFU72gvrpzZTbtptJXCY1Gv47QTTXfmwwG6k8c66Yb2xsqSn3RrVZmqkhEA5BGPDE2mjOCpBHQ8OqyqHEknc6+bf5X+vrXLYMlx81+U+3Qvv/ja5Sbp1/54YOHt3RewKklIqLnER4NQkREdAGtWwZLtk28yT7eNVGkbG1glIHRXjWQYsyUw97Q8ONVuoiSTs03CraAMBBu1EE4uP+yYqVyj66GKeEB1XTsb8cmm/4LGCw+/Nb2cSUv/98Y6rsq26x0KOxQCSgASsBoaC1V0tVe8fClqctf95bigQevsy3YVYUjZnjftxevgX/qWDtXwo6Mnfb+/s33/Xmq6dTzJAXOyJOn08Jo5HMmbFuy7LY9j6zfAQCZRQsuHdm1cZXUiCbmLvpCX3ngW9etRXiBp5iIiJ4nWJkkIiK6gBrGt7rVcu4KuNAwMAYiDMMaSmWUU8nmz1z+3eEiAOxbBddunbZEGmQAAWMMDADP9+K2DFOROKADaCfdtCVTHKx3rsym68r5jhjuuyre5IZaWtIv12w9uiRVj572KIUFSNeJjB/u/MEnzPDBS70a/MzUpWvCStexJ47VbllyTf+2+1YmspaCkAAMhACE+F2fHPHEnjlm9HUvF8j4tFk/rHdv/+p1axFufcf4sdWRY7eqCibo9vG/qnUPfOLlt+0/oxJKREQvHAyTREREF1C5ZmsYOaArkDoIhClX1XC/ls1LXvy1YOD+nwnAbPmHqTNrDX/yxZFDD90WTag4lAUjIA0EZFBHtQiMlFGNz1nwA9W//eaBAWi3be4/lA4fvDraaIXaGBH43nBi4bVbiz48E9RORD4htREQENKGZ1eGIWNTpv3Uzz962xOrkg/d1NE20t31uYiLBmXbWgghR0PkyfBozgiSBgJSCO1VfVmLJXZZXvEfFq8ZyW+/vjXuOdlbqkcHrvIb3R1x27nxmv/kPkkiohc6hkkiIqILaOna7qoAbvHSqUPDBQMv1nKk/UXXvj88vuefFq1BsO2Dl/+ffNe+u4vbfv0mtzqShmU93hTHhFr7kWw+teild46Zf/XLZbHvhnlfzo9kZ7S3Fg7c/9eZDGwtLO2VPambpncGA12vTlxy5feGeyEReKd8pxvt1RE6U+f+HJ739ituGy6cOsbt17fG7XTzp8RQ/0I7HtGAloDGWVrsnEbAaBN6slzCSGbi9FULv3j0eOfKbNqMnfru6o4dfyUiGEi2zr1pye0Hjl7YWSUioucj7pkkIiK6wJbcsu2BLe+dtiQ0lzR41ZGBOd4v8mIN9LoVzQm79+AHkwrtMiVCIy0hjBhtZmNCWS0G9YarXvTx3O6NX7v6G4NFYPSIEWvC5BuDB7s70GRrEYYq8FDLtnT8YPY//vLII28r/0Pzn7ysWNn967e6IlBQKjT1mgpSY/algupb5t/e1Xvq2HaugKOnzLmhf9O9r29os7XA6CpZA3HmklaMLnPVUJBGayCU+SFTa5x3xepi7/7O7e9ZeEXNr32stOO3fxoq5LIzrvjAga4HHvj9zDIREV1srEwSERFdYAIwaU8XQ+MPZgcTZbEaGgCS2UDV/HK0UAYqNaON5YRGAEYABgZaoWZyfdtOBkkASDp5tzrQ/bJIBBFhpDG+L5FNDnrHdv1MAGbel4+M1I8/8rHoJfO3VCs+NIz2QsCOJUaQK56x1HRgALperWaMBsKqLwMABkafLUgaACc7u1pCo5gPkZo55856dehnKtb8tmOPbP1vc2T3ywDohnmX3ep2PfCfbLhDRPTHg2GSiIjoAut8/6LJg9Gm75cG+g+VpjV87bdvnJ4EgOLYkXLz9KWfyC558eebLn/V69z2+Z1+uT7a+cYYwEGAWmn41HtZMp7wBvY1We7o38M6EB07a78nyqWT1yhfVw3E8GjuM1KHgIqmc0U7PO17/uerprjJadMypcK+f2+77PKXVeNtm72BitRhKAFxcrmtFgJaCKGFEBqAFjIMK7VAuk3ND0daOu7VWsyI2uJ/x1+1/OOFIkrutHk/0Pmh2+ashfecTSoRET3vMEwSERFdQJtubG8oDxz5Zn3XA6/IBIOpkc2/faXd3PSX65bBWr4awTxzz48uvfm+9w/t+u3d9UrR1+ZERdBoKNvyqrr6eDXRAEI1jF1garpJKAkYI4IQfiTR9LC2Yo831IlYgdTlkaytABgz2gU2ltleiGceD3frVsOaMH7eu3JGbmnsuPraSvXYA/Fo5JXu3Gu+mx8MqrpekxAIAfmEGqU0OgiV54vuzOzl365VC81WLdi44Nbdu4Qd1Wb8uIPKCd69eM3B/HM9t0RE9PzCMElERHSBmNWQkZaOv8DAwKWxZqVFxA7dGBw7Gp3pNrfbACBWQwvAWHEtdLUQdxUgDTQMABWtW365dvJ+u1bAFrHMXBEiASgARmrAA0RPcxB5vHGPJyOp+tCRxkAJaKNFAJTgl+869WiOhsHp4/u3//LNbu+jE7o3/uhOlZzxVV8rrYb2r2xesmxlwVPdfr6ujNAQRmC0GY8wxgQiP6LzTYuv/ZIOqmUnEl+sYlp0vnPWhN7eoy9tnTDtb5Z8bvdp+zKJiOiPAxvwEBERnadN726PplrmXmmEO1YPHrx7/i07+k99fX1Xh9MwKbLQdhCFkDAGSgr4SuF4Ct2n7SV0VUpWKmVXSUAIAWMAEUl5VqCCk9cMxCFbBVoUoEaXoRppBIyUEt3FQACjFUfbmvXK0vG7xkTTljbVQFptY3v93q7tJ++z/frWuO+4nxHlyqRocySMBjVR3nrP603z2BnxbMubH9u1/r8mts54qFoe+n/O4MAyp9EKhVFCwKA8FMjUpDnfHtm3Y41qavuwd/iRVzfMeWmqr/ux3oa4+6kF/7Ju93M970RE9PzEyiQREdF52H59azwS7bh14MFf3D2y4cffyVeq31x3U3Pi1GuSTl2a0B8XitEyIoyBUKiH1VLX7NkITr02rNQteBXnxDex1CHgRtKV0JXmd/cbI7XRdgiY0U2VQtuAa6Sa0RwrWwCQLM+ZWDq68622K+I2jMlVUEuPnXt78bGeHADcuQIKk2e+Lr93xyuSGUvCSBHaMRlvcbVTOr5o8OD2u6fNWPa2eP+jXQnHWhF2zPpVqT9QxoRhvegp2TL2N6IydPPSr3cPi1A8MDRcHz6+Z3NjNJK8ZeHntzFIEhH9EWOYJCIiegoGEH7HrBuHtv32TdkURLwZWvftm5cWicZTr7OrWhivlh1thCMBEwASdVktHDnZ0fXxax0nqevlmDjRLVVqQLnRalj5XZiMjPQEsN1+DWgYoyCEiUSlPfTohheblumLd35k6WWhwe0YOjZHxdywVAxVZELHA/rA3m8tXz8aXie3z7pkcO+DH0imETXC1oCWlg4hjJF2MqqzCTT1bV1/W3X28q8Ebt2L1npWuFMXfHfkSGBXlDociTS+ZfGankEAiB3e/OPGjkmXW3bsZVf+29Y9z/G0ExHR8xyXuRIRET2FLSvHRMNi91+nUlDajvgIPdtytdZ+7bReNUU7lBGvnFJytI2NBmAsVfPqlaEn3lPY0YQJYQlndHciAEjLqZ+WOJubHRjVeuL1EIDQEVvHvaH24b2//bGtoRSQcNKRUJdrqiZUd1Mi/Z4FX9yeA4BNKxA1lvVxp1KdKhqjGgbyd0eACCgTSO3EdWNzHcXOdW+IzFoUL4ZHbmysD6/y5sxHMpO5a/+eX+87OZzRbq0Hj1ygaSUioj9wDJNERPRHbd1qWNGhKbFosmWCSmbmQlgJL9+3cf/+B/eePDMxKNctAT9uKQDwYbSGVlEPQOXUe0WsUJpaMWIpQELrUEMpN1m3K7naqdcZQOxpaJuMw48mICxACAgAJvTSXtxTALDjbROyZsz0vxva+rPXxWOwdRBA2VJDCwPLQRxhWpkQoWXrarGmCiGOtc9e+o65csN2YLQZ0A5c8xcjWza8It5g65MZ0uB34dVAQphAamnpRLPS5T1brovNWOijNLgqXtv+hkslwoVrT6+oEhERncQwSUREf5Q6V8JGetHcoGbdWCsfWF7p299qBUgEPpyaJbsvmXXNO8zqDT8Vq6FdW8uq7yslAGEsIAwhE+k6TM0/9Z5eGFdekIskTmwiMSHgppP1crV6WvOdXStga9gvc4CYEQowRlhRC7WeR9uTHYv/5JF/HnvUg/UPxS2/elU8hrgPlQ+0DEXeS0djQkEpGBMg8ID8sGestrYt48ZN/eCjezasn3ci/G3JTWyt5/f8oxtDCsrWwuhTqpInCYzGy1AaaelUk6u7t2x9RdPMOd9b+mX87DmbfCIiekFgmCQioj86m25sbwjTYz9Y3v/QG5VBUyQGSFcCUQkpoK180F6v5t+1fqT5XmCg5MdiSX+kP+OOfmtKaMBJZCqR6tBpIdFydTzIFV0hAUABOoB0k9WMOX05rBk/uTX/2P1/6kaFFDAaEDDK1q72mvJ7fn0HNGA0EskY5HABfa2Lr/mQ9uu7q+XSewtHH3mRNIFl2cLT2fHdjdOnfd8MH/3uvJs39MwfTYb4+Sq4VmLce+v7N81VLVENo+XvguNpIznxXwlhDGr5usxMHb8u1Ec3PhfzTkRELywMk0RE9EflwXdMvMSv+F8Ldz/04niDglFWKLXWkJYCjAwFoCKBVl5pTNyJW8AA3Hi62Rs4HoMzWnIMNBCNZfJh/8hp6cyNpdO1geOujgooIaQBoCLxCmoDj1+z/frWuB9tXY3CgQ5k7dAAo+eCGCONUIhEdAqhgfY0BnIYHLNk+adKu/b999K13dXOldmVkUmXXSKisawKakPFarE77B0pLl6z97QKaXtiycKBXZtel2yQ9okjRU5b3noWOizXZDkS25p17Xct/o/8yIWbcSIieqFimCQioj8am981fXp5oOc/rVphYbTFCUMT6kqxLl0FZScsCGNghIASkAbCqLoe7csaTY6RGjaEHA1kGpCR+MgZmwllNGE0HAExGt80oKxoMFCJB8AAOleOiZkJC9478uAv/jaehawVfLgRwHIsGKG0MBpaa1nNG1Rs67HWxUtv9o8/+qOla3uqALB4zUge2PywAYQ4s8wIYHSvZak8sjoiMVZYjjYGUgAQZ936aGCM0tqryryHg63Tpr5rwWe2s8EOERGdF4ZJIiL6g7dv1RS32NjaaEFETKnQN/+WHeUnXtP5zkkTSvnh/7TrhYVOJuaHvmeXSuFw09wr/1FEE03Fh3/1QSvqZCWk8TTg2C5CKzQAIJzkOG3gnDjGQxgDCBU9Pqyijy9zNash9zjNU02IqBAC0gCWI1DJd09paG+auP0DqbKJNd48/NAv/j6ZgKwi0t36kr++u2/Lz68O+vqn2G4gpUYYAMPOJfN+2WIFn1wgf/OoWHNmCnyyIGlWQz4iJ72+unn9NelGWxsjpYDBmXslT1wPqUNdlSM5jLQuuuqjj+3ZeP8z/BEQEdEfIYZJIiL6g7bp3bMaitkJ/1w++OCb/GopkZh6xbc2vbv97Utv7a6evGb79a3xqhW/zcodXOg0REOEvsrngrB16bVrhu/6xbfSc8a3+FKusgMvCzsKYQBjR8IwVzPrVsOCHZ0igBOHeBipDXwpxeGk0/V4mNxyfFpDmOh5g+UgGkqltYCCG4EaOdyRKw/dKzwvapd2ZFJJyIEc8mMvf9Hn6g/84utOY0NzYvzMN+swWGLbse2ojnx3pHdwz9I7umpnfeBz2J5vH5Pvf+imROrkmZJnD5En6FCHyA2ilp13xedzRzb+4GT3WiIiovPBMElEROdt+/vmxUV23IuMUZZf3P2bxZ85mP99fbZZDSlWn16lW3dDJqON+ErhwV+uiGUB1wbyWze8KjNn8X8B3b8CgDtXQImps15f3LzuZdlmWxsIlIu+TMxZcl/hyK7PL1+PoHOebdnKWFoIKABaA1YiW9e5HJLHxzhmYtgBABDQxhgJwAiBysGR0fH89o1NSWvsxH8sd/7q6kij1MIYIww0ECBUjopU8uOEBIwLDBXR17bwmn/Fvu1fn/+dvjLQV+5c+ejqktehoknLSYSOHih3+Xia9q2COxIdu1qVu6errKsFtDx7lBxtxKONQWXYl+mZ874ROXbo3y7/Dp52eCUioj9u8mIPgIiI/jDsXAHHs+IfO77xFz8eePBnP6mU7K9turG94bn+3DtXQO24efmiXYkVH97xkeWLzIk+Mutu6IhkJ8z+aH3vrhXJZksLxw2l4+hoBPFIIjlz3bLRfzCdlB2THe7aflM6CUcrZYxfVaHrjCR0+A/XfPnICABYFiI6GI1ewhiYALBi6eGIFQlrQUrp0EuKU7rXKAFlVHTehLYp8U3vbm9ITFzw8ZHOX62KZKH8kpa67qsQEhrSKO1DSKHLBaCg3YNtC/7k3T25DV8eDZKjFq+Bn3SkG2+f/zdm4oy7pi99/cd3fGhu9unMUzV9xTXl3Q+9JppSEicWtp5tiauAgRZSV0c8qcZP+nGskvvwqWMhIiI6XwyTRER0Xirx5obc/vv/sjELJ90odenA3leq7Ngb71wB9Vx95rplsCZNWboyv23d/w7eu/bjwwc2rdn01tZmAEg1JmfnHtn4V6kmiVApABDGGKkFtDCiumw9QrMa0m2f+Vo5NDwFUUeL0IhqySAz70/v8UaOHzj5OcZONYUBlBKAMUYIA9iO21NwC2GyIactGbqjVwpASG0lLFV+9J5XxMZN+6wrkj/KbbvnHfEUbK+O4w2X/99bq4lxW8u9NVRzdVUcCZArm3x0+pJvpMbNuHbvnl/f+fLbUD/1OR9+9/zZVegfDW74wZfLD/xwac//fvcfa0j/889XTXHPZ5623ZDJVAaP3mzbyGrL0YCR8iwNdwSAUBjt56vSzzb9JgL9tnknAjUREdHTxWWuRER0XlTT+FmqMNAkLEtrqUwqXndcV81NtMECnt1eu5PVxic2lonM6Ggv7N30nkwUrcjaYWGwPi02pnn+9uuxqeqHH7IExgrb1kJLaYTWMBoa8Hy/fEwAZvuB1li9ped620VcGBGK0FOBY/WpfN+nF6zpqQCjlU8Vb5hmQiQEJPRoIA1Nvba7u7vbmzJhZnule2+7dIATzV6FUpZGbaQ9/9DP32LbQCIOFHIYabr8pV/yH9l0m+PYrnv5S/8uDIKXuInEXl0p/ne1dGDnqfs4T9r69ksm5voPfcuuFhYlmxxthAobnKodDh9a1lCuusDpwfOJOlfCVhMvf0/l/ruWpJtsLUwoNRTMiR/JaCUSgJEwMNove7Iq7UezjS1vW/j53b3P5udGRER/3BgmiYjoKRlA7Ew3zVZA1gghBYzWBiEs93D0kWcXJHd8aG52d+ucvwVkeee+bXfOuX13CRjdI7lTj7s87OtqFBFbA0LZFjxh6aoaN2FW5dHNlyVSQhsAQpyowhkNOKigMLAPAMK0k672PDYm5gLSCF33jYqPmdBTKx98vCp5adsUy3PiUy2DiIDUAoHUQCEYOnzPxJZxGSRbP1I7sGdiKqM0ABhjRo/9sJSJp40fVEM7l0epefGLbx46uP8rmNwXNPZNcGrF3h9EquJb0u4vz/+X3d7Znn3dDYj4scSnxdFDi5wmNxyNqlpVNRCNp4peUD9nBx0AcFQ6Mbj17r+Kx6EgVWiMOXEMiDjxsxMwkIgKTxfqWpaqONI6a+7b5/3r1j3P5udGRETEZa5ERPSUtqyEBYEZQkBBiBDGSAOUdL308LL1Ty9MmtWQnSvHxDpXjok9sGpe+9BQ4RsDd//Xf3Tf9d2vlJLZf9m0oj0KAOu7OhwrEr1ECsRHv64MjIWSmxjboiOx10UkWgJtpDa/y1tGGygnWglr1dG9kE0TFqhq2AilYGBk4APRhgk9iVA9vga0HubtyvDRKy0LgFQmMAbRmBoSkZSIjZt3XWnr+hWRGJxqMZQmqCsYDaED6XmBqgyFdk7EdzXMv+YGv+e+L0XTIh3zrvlCTzG3M9975N6wuelFs7E7eLK5SDZO6ygeemR5NAMtjBaBkID2EVbg2cnm7/sTBs+oZD6RF+ZL2XnX/GeuCN/Ua+p3B0oanCz0KqN1xdeyOGIKLfOX/vO8yNb1T3a8CBER0flimCQioqdU9DqU75UvkRKAEIAJoSVKupY79HRCyYa3TchuV9e+3aRa7zORyE6pBze7xcOvireqMN0Iu9Ld+QrVYmIA0BBWldG6FYBjAEBrROIu7PEzlteO7lwBC268ff6I0zC+bvzR5qdGA1YkFTrKDu9cASWczFVaIyGEhBEQtgEsJzYyUIn/LuA1TbusvP/h+XZMAgLCEgpIt6ZluukL/Q//8hO2jZRsnrwpe/krv1KsicPF4cAUR3St7jvH3NlXfqm5dfwrFn5yww+01dHol+p3lHdsWNWgC2OjtcLU4e5Hbl7f1ZE621wYQDip9mvsGhqFsBBCQRrP1PJa6taWB7yuA99bvhpPGkQB4OerprgqNmNcfXDnra0LrvjbXAmH/WJdCqG1EQZaCAhoHRofuSFTbVpwxWfjuU1rn9gVl4iI6JngMlciInpKSacu68XBtH2y1Y7W0Las1wq589pzZ1ZDbqsvubw00POp/IO/WOZGAWMDSgB2zNUAhJQhlO1C+VoAgEpqoUO/VUoAMDAQsNxYc+XYvlcFlaFWIeXRRMeCbxT2P3CjH+oJtg2jQwDx5rpXquhL26ZYdRG0CwEpAEgYaAuo5/umx+KROIDaI++ZPD7fc+jWhI0GoUbPZVTK0rpWaB65//vNKQEMG3GoKRp7Z3X/T3ZkJy+eg2Trnykp8sFw9725np6jy+/oqv32jU3JUNi36v6ulyWb3NBAwrU8UcsNjk2Nb5wAIPfEORGA2VouHqwEqEa9ICVlgGoeCNOpB9PJ7MrL/n3v0DnnFBA7x854VdeGX31x/OVXv8Paee+PslMWHsj1Hvh6MJif7zQqPdpQCBgZ0DI7f/HXrKOH/m3qd869B5OIiOh8MUwSEdF5qNl+rpqOWAAgNDSUE0lWIlb4lEdK3LkCakd4zYqR3RtujVloUy1OCIhQGqOMEKM5D0ILDSg7XndkJQSAWhAoq1JsMxIABCCV1l7Vre+5a6zSkNaE6dvKx3b+qDpw9HpLjRZMtQZi6cbBsuXrYn9dNBvjC2C0dioEnKhC/ejWuYnZL/nnPf96yaH8wYdvFLme+TLhaPP4ah0DpQMNC3Iwh3zb4qUfWSA3bhNroIHObXeuwI4Vs2HE50are3eugMpMnPeKkc33vSLaZMOMlm6lEQqWDrN245gXmdV7d56tGqhz3fen51/546FH73+NG7GC+MxLfxYW8x+87N/3Hnuqed34xukJq+fAm9Ky3jSw+d6vNS/68+mFga1fiEaSL5atl3yxsufh18UzIYoVIDV19n/Vcv0fu4xHgBAR0QXEZa5ERPSUpKPispbPjG5dFDAh4CYyXi1Q51wuaQAxY+aL/rpn+4bbMjG0WZmobwwECnXHq3sKQjz+PWQ0YEWTvhdKDQCOSsqwMpySvzt4RAIGlm1Jz0PecTLflrBT1VrFllIBRghhoN1Iqj+SK4TN5Zi23HhgAA2hARhppIWI41qlbfe8e+jBX/yHKvXMd5KO1gLy5A5DI5TWXk0O5zHctPCqD4a9G+88NQhetxbhqX+flB3j1gv9b5QRJJSwtBGQBgJCGG1JqDD0r1zf1eGcbX4Wr+mp1Pt63tI4bdaUyNhpk+Jd5Tcu/cpjTxkkASDZPu4VpUN7roi0WjoVR6L713d9IBZpvzV0pIkO9Lw5c8W1HyoUkVet4x/0wvq7ruERIEREdIExTBIR0VMSbus445sEpACElkEAINGSy0TEOfdLbn/P/AXDOzf8a1McTSYaCUXoqVrRK8k5yx52Wqf1mrqngdGqYhgCMpopBu7oPb3QV0G14FqnfFMZCCODEMZVw2Hl6ENhUAlUCBujmdRoDWOguotjezxvghkz+NhDy1UUEpBawmhhhDYwcOJuGM24oRCAX/ekGd1TqY2ADrUnCyLaO/aya95esjZ+ffEa+OecnEi0qXJs52Q7JmGMgjC+NkLACAvSAurFkYnNsfKTrgRa1tHl6VqyElcZa2B25by+lx+6afL44UPb/jkbR0KUAxmkWn88/uqlr6wNPXZtUPXXec3jpwXH9n6lcfZlV0UT6RUvum3/wPncl4iI6OlgmCQionMygLBSzfNMONrIRhiIUAN2oqG74LpP2sl1x9smZKvV3G1RYdpF1A21CVR+ODSp+S/+rMp1LXcbL/lAqaSrRoeAgTEGsJMNfdqKjYa3SDQW1IqRU7+pBAyqnkG0fcajpXytAKESAogIAUBoIW2htJe3G6uLZtar5a+qoWPTXCCs5n34gS9hQhijDYK68kfq8JKt+xvnvnRf4IU1GANhNLx8UGibcc1nh7uO/vipGuCY1ZCR5omvMTWMU8qBFgGghVTwIIyB5QBBvi9TCwJ1tvfvXDHLeVj9+Y1+uWtbX9fmo4lgwhfX3dScONdnPnTTrDYTSX7NKo3M1rZCoSK6bTvxTl0YOSr9IIiVe+b37+z8iU41XLbgM5t3LfnCzqPnuh8REdEzxTBJRETntGUlLOG4cyWgBIQ2gNSAdpTc65S7zxq2zGpIMWbajd6Rw0tk0tGh0cIrBIhNn/8rHDj4pUv/rStXz/U8Ji3kYUIARgQacJRzJNXdHQKAZUUaw3oYMfKUfrHGKM+D70bTd171jcEShBVTBo6BAIRANO7qysGNb8h1bVlvDR/5Uz9EQU26/JOZS//0c6UyDleGfFSGfeSros+ddeUXmma89N2BHd9pav7o2SMwMlQo+JXhh5bf0VV7yrk5PiZSyfW+3HHgaITQwipG51y7o26cqjEGQgGmOpzWsabGM+YIEHpm67XDD971SVHum5SxfWd4629eEbfHzXyyz3vopo42EXW/U9v/8J+lMkIXh8Nqw6zLPwQnZucGD38zYurjgxB+ctIlD5j+nm3n9QMmIiJ6htiAh4iIzsmLt1uilJspLABCGKNDGKAe1ku7Fq05e+Xu/qPtmSDcckM0CdsIFYqgqipK9rVIvG/BHV05AFCxdJvWiAshAKMlJDwTVPfMXntiWWkk0aJCxEb7sALCCB2GnkRUDdSG+u4VgNlugkoo4GtoCGMhBKCgE1HX0pV8ANMy7qFK77F/d9SDxeyMxT+UbmqJEsL3hobuMkbHCj1731Pd3/myaNq1DGBMGMLYwgtL59elVjpWptLz2ORIRACBDxHNPBbmjn8QkLdD12bAktC+TkaybXMN9p12jMqO61tjQX3kHVEXzXbc9Y0OlBMJ45Zrn/UokU0r2qO+ivw/f8+2l2bblF8eCe1ox5TbS0eO/9xqin/OqVau8h3ASzf9xoF8++XfPnbObrBERETPFiuTRER0TvFBX4aFnqxUgIGE1CGkg7I/0vvY2c6YNKshEx3TV+jBkWkmYgEIUasADVOX7Kh4QweB0Q6odiQ9XRgkIaQGDIxE1SsN7hKAMash7XjjNK2ROLEfEgYGYc0gOmbWUa+WzwGAyeeP+iGqIgw0zCgNoasjgTTZxk1RN7Fy6de7hxevgb/gk50PPfrIfV+eFd77Vdh1u3D0wOdreztvjKatqBASQggBbSCjyXo1GBh+qnkxqyHtlhmvDCvhOCmt0HiASLb0BIMHt2qpijAaQqhQaCSteMvy9Td0uKe+v5rxVVAcbrIcaANIo0MJBzVRGzpyts9zsmVHFo5NjWWg/Wpo12OpDTosfjbW3vqq+v49f+MmgFKII4nsuPdc9ZUD/U/7B01ERPQ0MUwSEdE5+VHP8kr5qK0AA6G1MVB2rGzVCmetfO040Br1SkN/rSKwhRAhtFZBCM+JRG5femt3FQBmAUoozLAFpBDSGK1hWbKsy/ljALDxSFO8XBpcYRQcAWgAEsbIugcdz475mT9hsAoAolA+Zo+dtaXYD6mrdVUv1FV+wA/NJXN+Gotl/vryL+49dOrYrluLcHt10dKRrv3fj9cHX2ZFAAFLmxOZ2ISAFW8oZYVz7qY7AO7Pt7t+tfAa24YjhNSVAHCSrYftqhNYUpjAAMJIbUnI0K/Ojiat0zq6uiolg3rJgoQUgIYGpB0phLXqWbuuSt91/KAOGMiREg4nmsa8OZHqmJTbvflT0UZEi3mUsjOu+rfS1u2PPPVPlYiI6NljmCQionNzE01BJZ/UFiCgpQgBkWou+tqrn+3ysmO71eP72pwIAAiYIIBMJ3rNsaObTl5Ty46xagOHpysHgBBaGA0tHY1atXLnCqjk5MVvrezefIWbtLSGRGikDnUIz0ZvdeDw2pONceZ/p6+cFOFb44uXf7eW7ThuTb1iY9MVf/YGHfT9zZLbD5zReGbbBy9bmtu37ZtJ6c/zgYHorGX3w40XdeDDGGOCAIikxxw9V2OhxxUQLR7bOdGOAFobpUP4fmn4h8MqGgo3I6ABAQHbAkpDR5uDcu60Km61FsTDWv5kgyEJDah4YzFw697ZPs40jJ0g635DeQS6YfrCD3j13MjQkR23JBJogQ9tjRnfWRs6esfy9eduGkRERHShMEwSEdE5OdmOOQiQPbnc1A8AmWzutavOWUOL29gyTZTLTVCj14c+EG2+ZERHwt+FpEi0qXL80fYTtTpplIKNIBabdOlfzb702o+OdP7yo9EEbBkE0owebhkGlRCxxvH7S/7waecwLvzi3uND+aM3ZlPJOYl84WULgrv/a/ntA6Unjmvb+y9bkOva8a2UraeUqvCik5f8k6mU3l4tFvpgtASMCANoJxLb+WSNhU6VGDf5JbpQngjb0cYEUjjIm0ru0eZyTFuJRi1CIBRSGguQpb5MpmPupO0fmNf+wKqGFADEopEM/DAilXp8Xp10c380Z58RZNethmVnml5UHjCtyVnzv1Qv9W8Uxr3NqVWvVDZkoYxcLDvxM1d/+UjuqcZNRER0obABDxERPanOlbClE1uoNOJCjK5zDULoRCR5YFhFzwg9ZjXkI7JpXtmMHiMCANoAbiJbqg4d0wCwcwUc0TLtbaUjB8ehwQJghJC2thyRHtn68/9ACJmMIawIlYewtChU0wawSwUMNE0a+zXvoQfP6LL68tv21wGctVIKANtu6MiUcse/FAnrU6ohwtiUed/uKT/0nXHxhVcFJb/NzVqADqUHlPxa6cGnOlvy56vgBgivdxQcCePrUEsrO6YSuIHntnlCJ8ZW/RAwCIW0LYRhbWw1f+y+of2PZRqnXfqzO1cMvzowtis1YkKI0bkLATuS6ik3Deonfl7y+BjHzw79pdWauB+l3Kcj6dYbR7ZuuS6aBIYGUY51TP2fwoG9vz3bHlYiIqLnCsMkERE9KW+k3VJt5amQUBAihDEKGgUZhtvQ1XVG9W7LcShnAlqgIeWJWONIwC/nI0JHbQOIR2YsXZTbuf518TiEMTI0gBDQACCcmBWaIJDDOQy3zl/ydkjRXSzkPmwgxralmr9UfXT/95/uMs47V0DpiZPfLzvvvcJJA1Wn+bCoFT5SGkCA+Y03WAIpARWasK5U1Cr4w4NPuedwTDETLZQemRqLAMII1OtAfMrUQX/4eJCv79exyIyjWgMCAIQFqT076HmsocEFygNdcya2jMvYqewlnkYakJAGSmj4QtkHTh6NciqdzqZy3QectllLPhR4wZ8eve83H2mc2XAkNnHhTyL1+vdV92Od89cOlJ/OvBARET1bDJNERPSk4hFf1krD7ZY68T+MhlYo6vLInmXrcfZ9hcb4J/dQCECIqAW/d+cliSlLr9v58eml/KGH32uhNj40kCIIICwrBAwEhAjrgZ0rord5/tJPdxc2/eTlt6HeuXLMiqIVyH2P7qpet/ZJPvMc2lPtae/gplfHUpDlKgrZmYs+Oyv8Zb8MJiVrAwfnOy4AIVAPgFjrhAEdjuSf6p5W+/QlateD7UgrAEYFAcJ4IvvDHbt/U57RNCGlIomqMYDUWkIqSAAyEgvLIxUVbZ5wv6kd9ZUTW4ATZ3cCRhqgKrTuGpgNjbWnf55rLN04bclnTDQ5buDI5rdMfs1rPxj2PfafwwiGl396A/dIEhHRRcEwSURET8qPelaY701bNgBAGx0q2KIcVIcOnW1J5aI1CHZ8uHAgAEqAbgCkkcLWjuVnRh7Z8Hlo6FgEEU/ACxNjD/n53iZV9hphQfo1+GEssrtx/qU3954IkgCweE1P5ZmO3wDikXFTrs1t7x5rJwC3qflYvmvnWvF16B0fykwZObAtE48CGhBBHX4sO/En+tjB6rnuue6Gjohxk38PICGEDEUYqkjUGjC1oY3Tpy6eaaLZ9w3tuOe1btoZTdMGgITWXkVVXfdIrFb+mGfFfKPDaUYCEMZAGwiFukKYO/Wztl/fGlcds6bUvEKXXey9zzP6suYJ41fMLn+/V9yCM5bDEhER/T4xTBIR0ZMKdCwZlnsTtgVIIxCEgBNPV2RQLZztegGYbYN9nVAomVBnjA0AGhIKsYR0hQlMtahVkMxuSrgNb3A7xoypVasfFdprTmfavh9Wer69yL7/mLhtNCjduQLqmVQjT9q/aopjHGepkoiHAeAkGvwwGAh23tScqBr5IWVMu1BWKAJP+QrdevDot55qv2TSybvFozunuxFAQAhIhWjcTld6D91R6D2WcUOknSQgbVcbAwkBbQJf1rUzMm7mkpVzPrbhQOfKMbEw5TVBACEEAI0QQhihwuUfG13Gu/2tk1t025R/Ovjru25qf9FLPnds+PDN195yz6+5L5KIiJ4vGCaJiOhJRRqbOqrDx+LCkQAgdQCoRFsh4g09acCrDgV9zsQ5D3h7dl6n2oRW0NBQkIEn8zkDnW3clM40vXnxv+88YICD629qfrVdM8J46dqSNQd8YLSi+PCHrpgomib+3SOzB388d/W9O57J+LuLgUilKpYEYLkSYa47E79kyWu1X5lb2fPgXySSCloIVIc1svMu+1nx+MCxs93nzhVQswBVamuIRJoWvLyy475xIi5hDAAIHQaBo8vHJiaigLDsUBgtjB7dDQoAMBpSyFzt2P4tABCxAunXa6468TKEhBRB1lj2n29/6+TNOtMwsVwq3lLdfNfVSYkwKOe9Cb37DYMkERE9nzBMEhHRWa1bBsuKNy6wQqSFVAAgtAYiycbeWl/+SZdYLl3bXX3gTZH3ltvGj1O9R6+yXEDDBxTy8ZmL/8eulD+68N/3HAZGK5l4/BiPwdEQ+Q8d6e0N0/+sfHTXR/MbH5jduGTJxJ+vmnLTiY6tT8tAuctPm7adlTo8JyNcgfqY3LZ1XxISkUjaCRVMWCn4di2d2Zwo9H5y+R1HH+8Ua1ZD3n+0PRMfP2kBpDXPq5VniHzv3MLedXMiCTsBIR6fA2NMKGwLJgyUV/SVr+EnklDCOvE1Ky34Jb8h3j5mMdDzy8KAGzpxzzdmNDhDCESSjio/eu8bpZv6i/qBA9kIkHVtwGvI/MYuHPvSnLU46/mTREREFwvDJBERnVX7XKgKzEwhEDECWsBIhNCO6+w3Iz3nbPpyxdf2d29/67xXi6vnXycllkDIrnpl+H8KR7t3Lb+j67SjPe5cAdUc77DjDYnm7enWl/v9B68vbrlrUSKKSLoZoSV8FS0G4sk+61yuW4vwoRsOrA3i1g3ecLDQTgkZT8DWAFDz1HAeSjc0PNSYbLxh4Rf3HT/5vnXLYG2tXvXqanX3B+o7fjPD0YgLBUgLcB0AQmgDQAshpQ7hVwKEVcCPIB+bOPt/GtpnbK7173+L17Vjjh1zIKTQlkDaxLOvWLca96R2dYe+PTZXDQFlNAABI6CVVHFdGZkUc4BiEZCppo2pTOZNi2/bP/hMnp+IiOi5xDBJRERnNdDbLt1Yfoq0AQljjDHQQEV74Y45sxE8sePoE83/yo7+fasqX83H0t8JKnlTLQZee9Iy2983L16UdSl9ZUek26bi8fm6VlpW7nvspdVDOztiLmQ6Y+lQICwXg2oEcu2yO7qedlXypCV3DPRufv/idxb6e76gcsdmG0ApC56JxnOpufN+rgv9n1p0+76jp72puTmSP7b3nW5+ZFGkUWoIpSGEwYl+OoCQgIEyIYJ6oHV2XFdqzowfhJXh7zoHt+0Ja/2OaJk9PaibWXbMSAChsoHa8JHLkuUxzuy1PdUdH43eXa7g5ZFEaBmlQhgIAwMTAP1FeOlps39g++X3LL5tf+8zfXYiIqLnEsMkERGdVb25rmTuWMa2ACMkhA4AC/mwOLhT3Pq7TqJ3roC6tG2KNWDVZKqeUgUXTtR1UgpuYyUSbXZDnXKcaCaWQUsx9FqCWqnRqlab/WqhpVjONUV8ZLRC3I0AyNihgPQ0tKr1+yrS3vEru697/bPdK3jZ5zo3bnjbhJclJ75kgXRjEwO/0h309+yMHMgPz1l74Izlo80Y8Ipjrvh1oWdwkevrCJQBtIGwrdEcCQAwuloKZGza0p/FaoV37Nl57/GTzYLM6oHgYe0/oIHrYUwaQsJ2gHL/gVa3eUKLALo2DBz6XmTcuL/MdR+71o1r6BCoaXiRlraH26bP/JJ3cPuPl3x3+KyNjoiIiJ4PntGyISIieuF74E0trX55eH3MCmZoJxIKr6aqVmpPKtHyZ8PFYDCZki1OtLFDxuJzg9Cf6ZfzY/xKLqMrubTya3ETBG6g4QoDWwkoAyihYEkBpSQcISClUtDSCiFOdGw12go9X+ZHAGf8+J9GdP3NV3ytv+9CPpdZDSlWP/WxGhveNiGrEm23VA5ufY2jQh/JRhMXtUwYeLYUgNABhnO61jJ36fXzP7Hp+098f+eqKZOLvfvXp6JyrFB2qKFVecQvpWYu+fsFn37ofwRgHrqpow2NHe+CV71C2LFDUlo/rR879usrv757hM12iIjo+Y6VSSIiOisnmmnzhvujxgGEEQLSQjQSTakxk1bHre6x1aHDs8o9BzNOCBcSykgoR0EKBUABsBUiQsIIqbUQJ/71UhhAaGNMCKONMVqExigZeKpWB/wqfBOPPJaeN++b4eDxr13x9f7hC/1c5xMkAeCaLx8Z6Vzpr4p0TL0Z3khFxsa3FEe61zpez0zjOmGotXIjGPYLvQ+d7f12rtirGic8Wuo50p7O+vA9Let1FEy12ncyKC65vav3zhVdH060TbFa6oFetGbLOY8lISIiej5hmCQiojMYQDycap6jjz6WhZCQJoRRUuv6SFtuy903uhYQcwDELEDIcPTMChEag9AA8sRNBIyW0KGE0TBaIwwBo6FCDR2GCIVBXVooGzcxYrWOeSyWaPpfUer+2f6DD/U9m/MlL5TFa3oqQM9hANj6nsaxeqgnKeMCBgKBB6imiT2ByeXO9t553+mrbH3Pwo8MWv3j/P7aFBFVXal5i7+Q7+vbdup1o8+5/6I/KxER0dPFMElERGdYvwyqwXbmK4OUgYIxQsIYLYRALGn5gbChtZFChyo0vgoCA4RQOgR0CD8U8CAQQKEmJeqw3LpwYmU3Ec9ZkcSwsmI9yrGOiFAc1F7hoMyPHM2X/OIVTfd74l/Pr3L4+7RzBZx6qvltIkS7UZYWJhSeB51tmnC/tXtD7WzvEYAxX9j64NZ3L3wlkpmZfnX40Wr0wUPL78A5O+ESERH9oWCYJCKiM3XACmrlDiGBUNg+TCANhEDgKR0YpWuBrhnUjUAJrpWTsYZhK5YesiKpnojjHgVMj9bhQOh5fdKrDAdCl/zAK0dLdW+4Xguby4/q3UC4Yi30H8LewJGmdFwc3XWVigCAMNpoBY2+oDT03wvOcf6jAAxu3bofwP7f22CJiIh+TxgmiYjoDM1l6EI96PYrgB2t2LU6EAYoaVcMWJn2o7H21t1Jy3nYeJVdKBaPBOVczrJKQb8wYTSxP1wGaKyG+UMIiucj1TDt6tyuzROimROdXIMQIhPrq1aO7bq4IyMiIrp4GCaJiOgMc9bC+/Wbhm7z21rmFOvFWbGOGZuibuzHYWHw/lw+198wssWfPRuB+PTzb0nqhWYAsSUQyXoZkVjKAAo6rEDFps08IEeO14H8xR4iERHRRcGjQYiI6En99gPTk5HQuJ6ulK+8tbv2Qqk0Pl0PvL4h5adbv1ndv+dV6QTkcBGF1sVXXX/ppzf+9I91ToiIiBgmiYiIzsMDr5+SsqdNurHae+TvVTJzf6Hn0Pv+/Dt95Ys9LiIioouFYZKIiOg8mdWQO0rzorF6JZh62/76xR4PEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREdEL0v8PAQUojcAhtw4AAAAASUVORK5CYII=", use_container_width=True) + + +st.markdown(""" +
+

๐ŸŒ Welcome to LanguitoAI

+

Learn, play, and grow: Language fun for kids!

+
+""", unsafe_allow_html=True) + +# Feature sections +st.markdown(""" +
+

Features

+ +
+ +""", unsafe_allow_html=True) + +# workflow +st.markdown(""" +

Workflow

+""", unsafe_allow_html=True) +# st.image("images/workflow.png") +# workflow_path = os.path.join(os.getcwd(), 'images', 'workflow.png') +workflow_path = "data:image/png;base64,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" +st.image(workflow_path) + + +# Call to action +st.markdown(""" +
+

Ready to Get Started?

+

Choose a feature from the sidebar to begin your learning journey!

+
+""", unsafe_allow_html=True) diff --git a/NINJA CODERS/app/pages/styles/style.css b/NINJA CODERS/app/pages/styles/style.css new file mode 100644 index 000000000..3c3d08fcb --- /dev/null +++ b/NINJA CODERS/app/pages/styles/style.css @@ -0,0 +1,139 @@ +@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;700&display=swap'); + +body { + font-family: 'Nunito', sans-serif; + background: linear-gradient(135deg, #f0f9ff, #cbebff); + color: #333; +} + +.main .block-container { + background-color: white; + border-radius: 20px; + padding: 2rem; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); +} + +h1 { + font-size: 2.5em !important; + color: #0077be; + text-shadow: 2px 2px 0 #ffd700; + margin-bottom: 20px; +} + +h2, h3 { + color: #0077be; +} + +.stButton > button { + background: linear-gradient(45deg, #0077be, #00a86b); + color: white; + border: none; + border-radius: 10px; + padding: 10px 20px; + font-size: 1.2em; + font-weight: bold; + transition: all 0.3s; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +.stButton > button:hover { + transform: translateY(-2px); + box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15); +} + +.stRadio > div { + background: #f0f9ff; + padding: 15px; + border-radius: 10px; + border: 2px solid #0077be; + margin: 10px 0; + transition: all 0.3s; +} + +.stRadio > div:hover { + transform: scale(1.02); + background: #e1f1ff; +} + +.stSelectbox > div > div { + background: white; + border: 2px solid #00a86b; + border-radius: 10px; + transition: all 0.3s; +} + +.stSelectbox > div > div:hover { + border-color: #0077be; +} + +.stMetric { + background: linear-gradient(135deg, #f0f9ff, #e1f1ff); + border-radius: 10px; + padding: 10px; + border: 2px solid #0077be; +} + +.stSuccess, .stError, .stInfo, .stWarning { + border-radius: 10px; + padding: 15px; + font-size: 1.1em; +} + +.stSuccess { + background: #e6ffe6; + border: 2px solid #00a86b; +} + +.stError { + background: #ffe6e6; + border: 2px solid #ff6b6b; +} + +.stInfo { + background: #e6f2ff; + border: 2px solid #0077be; +} + +.stWarning { + background: #fff9e6; + border: 2px solid #ffd700; +} + +.streamlit-expanderHeader { + background: #f0f9ff; + border-radius: 10px; + border: 2px solid #0077be; + padding: 10px; + transition: all 0.3s; +} + +.streamlit-expanderHeader:hover { + background: #e1f1ff; +} + +.css-1d391kg, .css-12oz5g7 { + background: linear-gradient(170deg, #f0f9ff 0%, #e1f1ff 100%); + border-right: 2px solid #0077be; +} + +/* Emoji for younger kids */ +.emoji-icon { + font-size: 1.5em; + margin-right: 5px; +} + +/* Progress bar for older kids */ +.progress-bar { + width: 100%; + height: 20px; + background-color: #f0f9ff; + border-radius: 10px; + overflow: hidden; +} + +.progress-bar-fill { + height: 100%; + background-color: #0077be; + transition: width 0.5s ease-in-out; +} + diff --git a/NINJA CODERS/app/requirements.txt b/NINJA CODERS/app/requirements.txt new file mode 100644 index 000000000..2a82f93b5 --- /dev/null +++ b/NINJA CODERS/app/requirements.txt @@ -0,0 +1,7 @@ +python-dotenv==1.0.0 +streamlit==1.40.2 +google-generativeai +typing-extensions==4.9.0 +langchain +langchain_google_genai +gtts diff --git a/README.md b/README.md index 92ec67790..8c0d49bca 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,61 @@ -# About The Hackathon -The MoroccoAI InnovAI Hackathon is a unique opportunity for AI enthusiasts, professionals, and innovators to collaborate and create transformative AI-based solutions addressing real-life challenges in Morocco and across Africa. As part of the annual MoroccoAI Annual Conference, this hackathon is set under the theme โ€œDriving the Future of Innovation Through AIโ€, inspiring participants to harness AIโ€™s capabilities to make a meaningful societal impact. Participants will join teams to develop Proof of Concepts (PoCs) using applications or APIs that address challenges in various domains. Education, Healthcare, Environment, Finance or Customer Services . - -In line with MoroccoAIโ€™s mission, this hackathon centers around โ€œDriving the Future of Innovation Through AIโ€. AI has the power to redefine industries, address community needs, and propel sustainable growth. Through this event, participants will dive into AIโ€™s potential by developing impactful solutions that address challenges unique to Morocco and Africa in fields such as agriculture, education, health, and finance, fostering innovation in response to real-world needs. - -# The Challenge -Connect with the MoroccoAI community, join teams and brainstorm ideas then come up with a project that leverages AI in 5 areas of focus: -* Innovation -* Healthcare -* Environment -* Finance -* CustomerServices - -# Mentorship -Join the Hackathon server on discord and meet the mentors to learn more about their proposed projects. - -# Why should you participate in this Hackathon? -* Hands-on experience in AI project development that targets relevant issues in Morocco and Africa. -* Mentorship and networking opportunities with experts and peers in the AI community. -* Showcase their solutions to a jury of AI specialists at the awards ceremony, creating visibility and opportunities for further development. -* Win great prizes offered by MoroccoAI's sponsors -* Obtain your MoroccoAI certificate of recognition - -# For more information -https://morocco.ai/events/conferences/MoroccoAI-Conference-2024/pages/hackathon.html +
+ +
+ + +# Languito.ai ๐ŸŒ๐Ÿ“š + +Languito.ai is an innovative AI-powered language learning platform designed to transform language education for Moroccan children. Our mission is to make language learning engaging, interactive, and culturally relevant. + + + +## ๐Ÿ“Š Problem Statement + +40% of students struggle with language learning due to: +- Intimidating traditional classroom environments. +- Lack of interactive and engaging learning tools. +- Difficulty connecting classroom learning to real-life contexts. +- Fear of making mistakes. + +## ๐Ÿ’ก Solution + +Our solution is to provide an all-in-one platform that enhances language learning through an interactive AI chat assistant for real-time, judgment-free practice and instant feedback. We offer a comprehensive Darija dictionary with contextual explanations, pronunciation guides, and real-life examples. Additionally, our gamified language quizzes adapt to your skill level, track performance, and make learning fun. Finally, a personalized learning space ensures customized content, progress monitoring, and a tailored experience for effective skill development. + + + +## ๐Ÿ”— Links : +* ๐Ÿ”ด Demo : [Languito.ai](https://languito-ai.streamlit.app/) +* ๐ŸŽฅ Video Demo : [Link](https://www.youtube.com/watch?v=BnsCVRAObdo&ab_channel=NinjaCoders) +* ๐ŸŽฅ Pitch Deck (video) : [Link](https://www.youtube.com/watch?v=whh51FjzBlo) +* ๐Ÿ“„ Pitch : [Link](https://drive.google.com/file/d/1I0eP3mn7s8vPLR1jSQjHMyTL92T8jH5V/view) + +## ๐Ÿ‘ฅ Team + +Languito.ai was founded by a passionate team of software engineering students from FSTT: + +- *Mohamed Amine Bahassou* + 2nd Year Software Engineering Student @FSTT + +- *Zakariae Azarkan* + 2nd Year Software Engineering Student @FSTT + +- *Hodaifa Echffani* + 2nd Year Software Engineering Student @FSTT + +## ๐Ÿ›  Installation + +### Prerequisites +- Python 3.12+ +- pip + +### Setup Instructions +```bash +# Clone the repository +git clone https://github.com/Medamine-Bahassou/languito-ai.git +cd NINJA CODERS/app + +# Install dependencies +pip install -r requirements.txt + +# Run the application +streamlit run app.py