From d900c04aba827a0952de50e94616a30ee38adf9e Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Mon, 7 Oct 2024 16:02:38 -0700 Subject: [PATCH 01/19] Starting to add speech to text --- codeaide/ui/chat_window.py | 105 ++++++++++++++++++++++++++++++++++++- requirements.txt | 3 ++ 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index 5916f16..c7e3a33 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -1,5 +1,5 @@ import signal -from PyQt5.QtCore import Qt, QTimer +from PyQt5.QtCore import Qt, QTimer, QThread, pyqtSignal from PyQt5.QtGui import QColor from PyQt5.QtWidgets import ( QApplication, @@ -12,6 +12,7 @@ QWidget, QComboBox, QLabel, + QProgressDialog, ) from codeaide.ui.code_popup import CodePopup from codeaide.ui.example_selection_dialog import show_example_dialog @@ -33,6 +34,37 @@ ) from codeaide.utils.logging_config import get_logger from codeaide.ui.traceback_dialog import TracebackDialog +import sounddevice as sd +import numpy as np +from scipy.io import wavfile +import whisper +import os + + +class VoiceRecorderThread(QThread): + finished = pyqtSignal(str) + + def __init__(self, filename): + super().__init__() + self.filename = filename + self.is_recording = False + + def run(self): + RATE = 44100 + self.is_recording = True + with sd.InputStream(samplerate=RATE, channels=1) as stream: + frames = [] + while self.is_recording: + data, overflowed = stream.read(RATE) + if not overflowed: + frames.append(data) + + audio_data = np.concatenate(frames, axis=0) + wavfile.write(self.filename, RATE, audio_data) + self.finished.emit(self.filename) + + def stop(self): + self.is_recording = False class ChatWindow(QMainWindow): @@ -66,6 +98,9 @@ def __init__(self, chat_handler): self.logger.info("Chat window initialized") + # Setup voice recording after UI initialization + self.setup_voice_recording() + def setup_ui(self): central_widget = QWidget(self) self.setCentralWidget(central_widget) @@ -118,7 +153,15 @@ def setup_ui(self): self.input_text.setFixedHeight(100) self.input_text.textChanged.connect(self.on_modify) self.input_text.installEventFilter(self) - main_layout.addWidget(self.input_text, stretch=1) + + # Add microphone button to input area + input_layout = QHBoxLayout() + self.mic_button = QPushButton("Record", self) + self.mic_button.clicked.connect(self.toggle_voice_recording) + input_layout.addWidget(self.mic_button) + input_layout.addWidget(self.input_text) + + main_layout.addLayout(input_layout) # Buttons button_layout = QHBoxLayout() @@ -445,3 +488,61 @@ def show_traceback_dialog(self, traceback_text): def update_submit_button_state(self): self.submit_button.setEnabled(bool(self.input_text.toPlainText().strip())) + + def setup_voice_recording(self): + self.logger.info("Setting up voice recording...") + self.is_recording = False + self.recorder_thread = None + + progress_dialog = QProgressDialog("Loading Whisper model...", None, 0, 0, self) + progress_dialog.setWindowModality(Qt.WindowModal) + progress_dialog.setMinimumDuration(0) + progress_dialog.setValue(0) + progress_dialog.show() + + QApplication.processEvents() # Ensure the dialog is displayed + + self.logger.info("Loading Whisper model...") + self.whisper_model = whisper.load_model("tiny") + self.logger.info("Whisper model loaded successfully") + + progress_dialog.close() + + def toggle_voice_recording(self): + if not self.is_recording: + self.start_voice_recording() + else: + self.stop_voice_recording() + + def start_voice_recording(self): + self.is_recording = True + self.mic_button.setStyleSheet("background-color: red;") + + filename = os.path.join( + self.chat_handler.file_handler.session_dir, "temp_audio.wav" + ) + self.recorder_thread = VoiceRecorderThread(filename) + self.recorder_thread.finished.connect(self.on_recording_finished) + self.recorder_thread.start() + + def stop_voice_recording(self): + if self.recorder_thread: + self.recorder_thread.stop() + self.is_recording = False + self.mic_button.setStyleSheet("") + + def on_recording_finished(self, filename): + # Transcribe the audio + result = self.whisper_model.transcribe(filename) + transcribed_text = result["text"] + + # Insert the transcribed text into the input box + current_text = self.input_text.toPlainText() + if current_text: + new_text = current_text + " " + transcribed_text + else: + new_text = transcribed_text + self.input_text.setPlainText(new_text) + + # Clean up the temporary audio file + os.remove(filename) diff --git a/requirements.txt b/requirements.txt index 348e3f2..be66259 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,3 +14,6 @@ pygments flake8 flake8-unused-arguments autoflake +openai-whisper +sounddevice +scipy From 006a7e0440cc2db8e4ae6f4254dbd23e48c97283 Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Mon, 7 Oct 2024 17:04:18 -0700 Subject: [PATCH 02/19] Transcription is working, just need to clean it up --- audio_recorder_test.py | 222 ++++++++++++++++++++++++++++++++ codeaide/ui/chat_window.py | 252 +++++++++++++++++++++++++++++-------- requirements.txt | 1 + 3 files changed, 420 insertions(+), 55 deletions(-) create mode 100644 audio_recorder_test.py diff --git a/audio_recorder_test.py b/audio_recorder_test.py new file mode 100644 index 0000000..dd4f39e --- /dev/null +++ b/audio_recorder_test.py @@ -0,0 +1,222 @@ +import sys +import os +import time +import sounddevice as sd +import numpy as np +from scipy.io import wavfile +import whisper +from PyQt5.QtWidgets import ( + QApplication, + QWidget, + QPushButton, + QVBoxLayout, + QTextEdit, + QProgressDialog, +) +from PyQt5.QtCore import QThread, pyqtSignal, Qt + + +class AudioRecorder(QThread): + finished = pyqtSignal(str, float) + + def __init__(self, filename): + super().__init__() + self.filename = filename + self.is_recording = False + self.start_time = None + + def run(self): + RATE = 16000 # 16kHz to match Whisper's expected input + self.is_recording = True + self.start_time = time.time() + with sd.InputStream(samplerate=RATE, channels=1) as stream: + frames = [] + while self.is_recording: + data, overflowed = stream.read(RATE) + if not overflowed: + frames.append(data) + + audio_data = np.concatenate(frames, axis=0) + print(f"Raw audio data shape: {audio_data.shape}") + print(f"Raw audio data range: {audio_data.min()} to {audio_data.max()}") + + # Ensure audio data is in the correct range for int16 + audio_data = np.clip(audio_data * 32768, -32768, 32767).astype(np.int16) + + wavfile.write(self.filename, RATE, audio_data) + end_time = time.time() + self.finished.emit(self.filename, end_time - self.start_time) + + def stop(self): + self.is_recording = False + + +class AudioRecorderApp(QWidget): + def __init__(self): + super().__init__() + self.initUI() + self.recorder = None + self.is_recording = False + print("Loading Whisper model...") + self.whisper_model = whisper.load_model("tiny") + print("Whisper model loaded.") + + def initUI(self): + layout = QVBoxLayout() + + # Record button + self.record_button = QPushButton("Record", self) + self.record_button.clicked.connect(self.toggle_recording) + self.record_button.setStyleSheet( + """ + QPushButton { + background-color: #4CAF50; + color: white; + border: none; + padding: 10px 20px; + text-align: center; + text-decoration: none; + font-size: 16px; + margin: 4px 2px; + border-radius: 12px; + } + QPushButton:hover { + background-color: #45a049; + } + """ + ) + layout.addWidget(self.record_button) + + # Text entry field + self.text_entry = QTextEdit(self) + self.text_entry.setPlaceholderText("Transcribed text will appear here...") + layout.addWidget(self.text_entry) + + self.setLayout(layout) + self.setGeometry(300, 300, 300, 200) + self.setWindowTitle("Audio Recorder") + self.show() + + def toggle_recording(self): + if not self.is_recording: + self.start_recording() + else: + self.stop_recording() + + def start_recording(self): + self.is_recording = True + self.record_button.setText("Stop Recording") + self.record_button.setStyleSheet( + """ + QPushButton { + background-color: #f44336; + color: white; + border: none; + padding: 10px 20px; + text-align: center; + text-decoration: none; + font-size: 16px; + margin: 4px 2px; + border-radius: 12px; + } + QPushButton:hover { + background-color: #d32f2f; + } + """ + ) + filename = os.path.expanduser("~/recorded_audio.wav") + self.recorder = AudioRecorder(filename) + self.recorder.finished.connect(self.on_recording_finished) + self.recorder.start() + + def stop_recording(self): + if self.recorder: + print(f"Stop recording clicked at: {time.time():.2f}") + self.recorder.stop() + self.is_recording = False + self.record_button.setText("Record") + self.record_button.setStyleSheet( + """ + QPushButton { + background-color: #4CAF50; + color: white; + border: none; + padding: 10px 20px; + text-align: center; + text-decoration: none; + font-size: 16px; + margin: 4px 2px; + border-radius: 12px; + } + QPushButton:hover { + background-color: #45a049; + } + """ + ) + + def on_recording_finished(self, filename, recording_duration): + print(f"Recording saved to: {filename}") + print(f"Total recording time: {recording_duration:.2f} seconds") + transcription_start = time.time() + self.transcribe_audio(filename) + transcription_end = time.time() + print( + f"Total time from recording stop to transcription complete: {transcription_end - transcription_start:.2f} seconds" + ) + + def transcribe_audio(self, filename): + progress = QProgressDialog("Transcribing audio...", None, 0, 0, self) + progress.setWindowModality(Qt.WindowModal) + progress.setWindowTitle("Please Wait") + progress.setCancelButton(None) + progress.setMinimumDuration(0) + progress.show() + + QApplication.processEvents() + + print("Transcribing audio...") + read_start = time.time() + # Read the WAV file + sample_rate, audio_data = wavfile.read(filename) + read_end = time.time() + print(f"Time to read WAV file: {read_end - read_start:.2f} seconds") + + print(f"Audio shape: {audio_data.shape}, Sample rate: {sample_rate}") + print(f"Audio duration: {len(audio_data) / sample_rate:.2f} seconds") + + # Convert to float32 and normalize + audio_data = audio_data.astype(np.float32) / 32768.0 + + print(f"Audio data range: {audio_data.min()} to {audio_data.max()}") + + # Transcribe + transcribe_start = time.time() + result = self.whisper_model.transcribe(audio_data) + transcribe_end = time.time() + transcribed_text = result["text"].strip() # Remove leading/trailing whitespace + print(f"Transcription: {transcribed_text}") + print( + f"Time for Whisper to transcribe: {transcribe_end - transcribe_start:.2f} seconds" + ) + print("Transcription complete.") + + # Insert transcribed text into the text entry field + current_text = self.text_entry.toPlainText() + if current_text: + new_text = current_text + " " + transcribed_text + else: + new_text = transcribed_text + self.text_entry.setPlainText(new_text) + + # Move cursor to the end of the text + cursor = self.text_entry.textCursor() + cursor.movePosition(cursor.End) + self.text_entry.setTextCursor(cursor) + + progress.close() + + +if __name__ == "__main__": + app = QApplication(sys.argv) + ex = AudioRecorderApp() + sys.exit(app.exec_()) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index c7e3a33..4a8339a 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -1,5 +1,12 @@ import signal -from PyQt5.QtCore import Qt, QTimer, QThread, pyqtSignal +from PyQt5.QtCore import ( + Qt, + QTimer, + QThread, + pyqtSignal, + QPropertyAnimation, + QEasingCurve, +) from PyQt5.QtGui import QColor from PyQt5.QtWidgets import ( QApplication, @@ -12,7 +19,8 @@ QWidget, QComboBox, QLabel, - QProgressDialog, + QProgressBar, + QDialog, ) from codeaide.ui.code_popup import CodePopup from codeaide.ui.example_selection_dialog import show_example_dialog @@ -34,24 +42,27 @@ ) from codeaide.utils.logging_config import get_logger from codeaide.ui.traceback_dialog import TracebackDialog +import os +import time import sounddevice as sd import numpy as np from scipy.io import wavfile import whisper -import os -class VoiceRecorderThread(QThread): - finished = pyqtSignal(str) +class AudioRecorder(QThread): + finished = pyqtSignal(str, float) def __init__(self, filename): super().__init__() self.filename = filename self.is_recording = False + self.start_time = None def run(self): - RATE = 44100 + RATE = 16000 # 16kHz to match Whisper's expected input self.is_recording = True + self.start_time = time.time() with sd.InputStream(samplerate=RATE, channels=1) as stream: frames = [] while self.is_recording: @@ -60,13 +71,87 @@ def run(self): frames.append(data) audio_data = np.concatenate(frames, axis=0) + print(f"Raw audio data shape: {audio_data.shape}") + print(f"Raw audio data range: {audio_data.min()} to {audio_data.max()}") + + # Ensure audio data is in the correct range for int16 + audio_data = np.clip(audio_data * 32768, -32768, 32767).astype(np.int16) + wavfile.write(self.filename, RATE, audio_data) - self.finished.emit(self.filename) + end_time = time.time() + self.finished.emit(self.filename, end_time - self.start_time) def stop(self): self.is_recording = False +class TranscriptionThread(QThread): + finished = pyqtSignal(str) + + def __init__(self, whisper_model, filename): + super().__init__() + self.whisper_model = whisper_model + self.filename = filename + + def run(self): + print("Transcribing audio...") + read_start = time.time() + # Read the WAV file + sample_rate, audio_data = wavfile.read(self.filename) + read_end = time.time() + print(f"Time to read WAV file: {read_end - read_start:.2f} seconds") + + print(f"Audio shape: {audio_data.shape}, Sample rate: {sample_rate}") + print(f"Audio duration: {len(audio_data) / sample_rate:.2f} seconds") + + # Convert to float32 and normalize + audio_data = audio_data.astype(np.float32) / 32768.0 + + print(f"Audio data range: {audio_data.min()} to {audio_data.max()}") + + # Transcribe + transcribe_start = time.time() + result = self.whisper_model.transcribe(audio_data) + transcribe_end = time.time() + transcribed_text = result["text"].strip() + print(f"Transcription: {transcribed_text}") + print( + f"Time for Whisper to transcribe: {transcribe_end - transcribe_start:.2f} seconds" + ) + print("Transcription complete.") + + self.finished.emit(transcribed_text) + + +class AnimatedProgressDialog(QDialog): + def __init__(self, parent=None): + super().__init__(parent) + self.setWindowTitle("Transcribing Audio") + self.setFixedSize(300, 100) + layout = QVBoxLayout(self) + + self.label = QLabel("Transcribing audio...") + layout.addWidget(self.label) + + self.progress_bar = QProgressBar(self) + self.progress_bar.setRange(0, 100) + self.progress_bar.setValue(0) + layout.addWidget(self.progress_bar) + + self.animation = QPropertyAnimation(self.progress_bar, b"value") + self.animation.setDuration(1000) # 1 second for a full cycle + self.animation.setStartValue(0) + self.animation.setEndValue(100) + self.animation.setEasingCurve(QEasingCurve.Linear) + self.animation.finished.connect(self.restart_animation) + + self.animation.start() + + def restart_animation(self): + self.progress_bar.setValue(0) + self.animation.start() + + class ChatWindow(QMainWindow): def __init__(self, chat_handler): super().__init__() @@ -82,6 +167,11 @@ def __init__(self, chat_handler): self.setup_input_placeholder() self.update_submit_button_state() + # Initialize Whisper model + print("Loading Whisper model...") + self.whisper_model = whisper.load_model("tiny") + print("Whisper model loaded.") + # Check API key status if not self.chat_handler.api_key_valid: self.waiting_for_api_key = True @@ -98,9 +188,6 @@ def __init__(self, chat_handler): self.logger.info("Chat window initialized") - # Setup voice recording after UI initialization - self.setup_voice_recording() - def setup_ui(self): central_widget = QWidget(self) self.setCentralWidget(central_widget) @@ -154,13 +241,32 @@ def setup_ui(self): self.input_text.textChanged.connect(self.on_modify) self.input_text.installEventFilter(self) - # Add microphone button to input area + # Add record button + self.record_button = QPushButton("Record", self) + self.record_button.clicked.connect(self.toggle_recording) + self.record_button.setStyleSheet( + """ + QPushButton { + background-color: #4CAF50; + color: white; + border: none; + padding: 5px 10px; + text-align: center; + text-decoration: none; + font-size: 14px; + margin: 4px 2px; + border-radius: 12px; + } + QPushButton:hover { + background-color: #45a049; + } + """ + ) + + # Modify the input layout to include the record button input_layout = QHBoxLayout() - self.mic_button = QPushButton("Record", self) - self.mic_button.clicked.connect(self.toggle_voice_recording) - input_layout.addWidget(self.mic_button) + input_layout.addWidget(self.record_button) input_layout.addWidget(self.input_text) - main_layout.addLayout(input_layout) # Buttons @@ -489,54 +595,88 @@ def show_traceback_dialog(self, traceback_text): def update_submit_button_state(self): self.submit_button.setEnabled(bool(self.input_text.toPlainText().strip())) - def setup_voice_recording(self): - self.logger.info("Setting up voice recording...") - self.is_recording = False - self.recorder_thread = None - - progress_dialog = QProgressDialog("Loading Whisper model...", None, 0, 0, self) - progress_dialog.setWindowModality(Qt.WindowModal) - progress_dialog.setMinimumDuration(0) - progress_dialog.setValue(0) - progress_dialog.show() - - QApplication.processEvents() # Ensure the dialog is displayed - - self.logger.info("Loading Whisper model...") - self.whisper_model = whisper.load_model("tiny") - self.logger.info("Whisper model loaded successfully") - - progress_dialog.close() + def toggle_recording(self): + if not hasattr(self, "is_recording"): + self.is_recording = False - def toggle_voice_recording(self): if not self.is_recording: - self.start_voice_recording() + self.start_recording() else: - self.stop_voice_recording() + self.stop_recording() - def start_voice_recording(self): + def start_recording(self): self.is_recording = True - self.mic_button.setStyleSheet("background-color: red;") + self.record_button.setText("Stop Recording") + self.record_button.setStyleSheet( + """ + QPushButton { + background-color: #f44336; + color: white; + border: none; + padding: 5px 10px; + text-align: center; + text-decoration: none; + font-size: 14px; + margin: 4px 2px; + border-radius: 12px; + } + QPushButton:hover { + background-color: #d32f2f; + } + """ + ) + filename = os.path.expanduser("~/recorded_audio.wav") + self.recorder = AudioRecorder(filename) + self.recorder.finished.connect(self.on_recording_finished) + self.recorder.start() + + def stop_recording(self): + if self.recorder: + print(f"Stop recording clicked at: {time.time():.2f}") + self.recorder.stop() + self.is_recording = False + self.record_button.setText("Record") + self.record_button.setStyleSheet( + """ + QPushButton { + background-color: #4CAF50; + color: white; + border: none; + padding: 5px 10px; + text-align: center; + text-decoration: none; + font-size: 14px; + margin: 4px 2px; + border-radius: 12px; + } + QPushButton:hover { + background-color: #45a049; + } + """ + ) - filename = os.path.join( - self.chat_handler.file_handler.session_dir, "temp_audio.wav" + def on_recording_finished(self, filename, recording_duration): + print(f"Recording saved to: {filename}") + print(f"Total recording time: {recording_duration:.2f} seconds") + transcription_start = time.time() + self.transcribe_audio(filename) + transcription_end = time.time() + print( + f"Total time from recording stop to transcription complete: {transcription_end - transcription_start:.2f} seconds" ) - self.recorder_thread = VoiceRecorderThread(filename) - self.recorder_thread.finished.connect(self.on_recording_finished) - self.recorder_thread.start() - def stop_voice_recording(self): - if self.recorder_thread: - self.recorder_thread.stop() - self.is_recording = False - self.mic_button.setStyleSheet("") + def transcribe_audio(self, filename): + progress_dialog = AnimatedProgressDialog(self) + progress_dialog.setWindowModality(Qt.WindowModal) + progress_dialog.show() - def on_recording_finished(self, filename): - # Transcribe the audio - result = self.whisper_model.transcribe(filename) - transcribed_text = result["text"] + self.transcription_thread = TranscriptionThread(self.whisper_model, filename) + self.transcription_thread.finished.connect(self.on_transcription_finished) + self.transcription_thread.finished.connect(progress_dialog.close) + self.transcription_thread.start() - # Insert the transcribed text into the input box + def on_transcription_finished(self, transcribed_text): + # Insert transcribed text into the input text field current_text = self.input_text.toPlainText() if current_text: new_text = current_text + " " + transcribed_text @@ -544,5 +684,7 @@ def on_recording_finished(self, filename): new_text = transcribed_text self.input_text.setPlainText(new_text) - # Clean up the temporary audio file - os.remove(filename) + # Move cursor to the end of the text + cursor = self.input_text.textCursor() + cursor.movePosition(cursor.End) + self.input_text.setTextCursor(cursor) diff --git a/requirements.txt b/requirements.txt index be66259..883cb12 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,3 +17,4 @@ autoflake openai-whisper sounddevice scipy +ffmpeg-python From 4afb42bd064165cd18a0d130caef78d4a9cf7d52 Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Mon, 7 Oct 2024 17:17:17 -0700 Subject: [PATCH 03/19] Cleaned up progressbar --- codeaide/ui/chat_window.py | 42 ++++++++------------------------------ 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index 4a8339a..68f83a8 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -4,8 +4,6 @@ QTimer, QThread, pyqtSignal, - QPropertyAnimation, - QEasingCurve, ) from PyQt5.QtGui import QColor from PyQt5.QtWidgets import ( @@ -19,8 +17,7 @@ QWidget, QComboBox, QLabel, - QProgressBar, - QDialog, + QProgressDialog, ) from codeaide.ui.code_popup import CodePopup from codeaide.ui.example_selection_dialog import show_example_dialog @@ -123,35 +120,6 @@ def run(self): self.finished.emit(transcribed_text) -class AnimatedProgressDialog(QDialog): - def __init__(self, parent=None): - super().__init__(parent) - self.setWindowTitle("Transcribing Audio") - self.setFixedSize(300, 100) - layout = QVBoxLayout(self) - - self.label = QLabel("Transcribing audio...") - layout.addWidget(self.label) - - self.progress_bar = QProgressBar(self) - self.progress_bar.setRange(0, 100) - self.progress_bar.setValue(0) - layout.addWidget(self.progress_bar) - - self.animation = QPropertyAnimation(self.progress_bar, b"value") - self.animation.setDuration(1000) # 1 second for a full cycle - self.animation.setStartValue(0) - self.animation.setEndValue(100) - self.animation.setEasingCurve(QEasingCurve.Linear) - self.animation.finished.connect(self.restart_animation) - - self.animation.start() - - def restart_animation(self): - self.progress_bar.setValue(0) - self.animation.start() - - class ChatWindow(QMainWindow): def __init__(self, chat_handler): super().__init__() @@ -666,8 +634,14 @@ def on_recording_finished(self, filename, recording_duration): ) def transcribe_audio(self, filename): - progress_dialog = AnimatedProgressDialog(self) + progress_dialog = QProgressDialog("Transcribing audio...", None, 0, 0, self) + progress_dialog.setWindowTitle("Please Wait") progress_dialog.setWindowModality(Qt.WindowModal) + progress_dialog.setAutoClose(True) + progress_dialog.setAutoReset(True) + progress_dialog.setMinimumDuration(0) + progress_dialog.setValue(0) + progress_dialog.setMaximum(0) # This makes it an indeterminate progress dialog progress_dialog.show() self.transcription_thread = TranscriptionThread(self.whisper_model, filename) From 64b66477499ccffc310537be2410a2fb30c30674 Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Mon, 7 Oct 2024 17:18:32 -0700 Subject: [PATCH 04/19] Removed prototype file --- audio_recorder_test.py | 222 ----------------------------------------- 1 file changed, 222 deletions(-) delete mode 100644 audio_recorder_test.py diff --git a/audio_recorder_test.py b/audio_recorder_test.py deleted file mode 100644 index dd4f39e..0000000 --- a/audio_recorder_test.py +++ /dev/null @@ -1,222 +0,0 @@ -import sys -import os -import time -import sounddevice as sd -import numpy as np -from scipy.io import wavfile -import whisper -from PyQt5.QtWidgets import ( - QApplication, - QWidget, - QPushButton, - QVBoxLayout, - QTextEdit, - QProgressDialog, -) -from PyQt5.QtCore import QThread, pyqtSignal, Qt - - -class AudioRecorder(QThread): - finished = pyqtSignal(str, float) - - def __init__(self, filename): - super().__init__() - self.filename = filename - self.is_recording = False - self.start_time = None - - def run(self): - RATE = 16000 # 16kHz to match Whisper's expected input - self.is_recording = True - self.start_time = time.time() - with sd.InputStream(samplerate=RATE, channels=1) as stream: - frames = [] - while self.is_recording: - data, overflowed = stream.read(RATE) - if not overflowed: - frames.append(data) - - audio_data = np.concatenate(frames, axis=0) - print(f"Raw audio data shape: {audio_data.shape}") - print(f"Raw audio data range: {audio_data.min()} to {audio_data.max()}") - - # Ensure audio data is in the correct range for int16 - audio_data = np.clip(audio_data * 32768, -32768, 32767).astype(np.int16) - - wavfile.write(self.filename, RATE, audio_data) - end_time = time.time() - self.finished.emit(self.filename, end_time - self.start_time) - - def stop(self): - self.is_recording = False - - -class AudioRecorderApp(QWidget): - def __init__(self): - super().__init__() - self.initUI() - self.recorder = None - self.is_recording = False - print("Loading Whisper model...") - self.whisper_model = whisper.load_model("tiny") - print("Whisper model loaded.") - - def initUI(self): - layout = QVBoxLayout() - - # Record button - self.record_button = QPushButton("Record", self) - self.record_button.clicked.connect(self.toggle_recording) - self.record_button.setStyleSheet( - """ - QPushButton { - background-color: #4CAF50; - color: white; - border: none; - padding: 10px 20px; - text-align: center; - text-decoration: none; - font-size: 16px; - margin: 4px 2px; - border-radius: 12px; - } - QPushButton:hover { - background-color: #45a049; - } - """ - ) - layout.addWidget(self.record_button) - - # Text entry field - self.text_entry = QTextEdit(self) - self.text_entry.setPlaceholderText("Transcribed text will appear here...") - layout.addWidget(self.text_entry) - - self.setLayout(layout) - self.setGeometry(300, 300, 300, 200) - self.setWindowTitle("Audio Recorder") - self.show() - - def toggle_recording(self): - if not self.is_recording: - self.start_recording() - else: - self.stop_recording() - - def start_recording(self): - self.is_recording = True - self.record_button.setText("Stop Recording") - self.record_button.setStyleSheet( - """ - QPushButton { - background-color: #f44336; - color: white; - border: none; - padding: 10px 20px; - text-align: center; - text-decoration: none; - font-size: 16px; - margin: 4px 2px; - border-radius: 12px; - } - QPushButton:hover { - background-color: #d32f2f; - } - """ - ) - filename = os.path.expanduser("~/recorded_audio.wav") - self.recorder = AudioRecorder(filename) - self.recorder.finished.connect(self.on_recording_finished) - self.recorder.start() - - def stop_recording(self): - if self.recorder: - print(f"Stop recording clicked at: {time.time():.2f}") - self.recorder.stop() - self.is_recording = False - self.record_button.setText("Record") - self.record_button.setStyleSheet( - """ - QPushButton { - background-color: #4CAF50; - color: white; - border: none; - padding: 10px 20px; - text-align: center; - text-decoration: none; - font-size: 16px; - margin: 4px 2px; - border-radius: 12px; - } - QPushButton:hover { - background-color: #45a049; - } - """ - ) - - def on_recording_finished(self, filename, recording_duration): - print(f"Recording saved to: {filename}") - print(f"Total recording time: {recording_duration:.2f} seconds") - transcription_start = time.time() - self.transcribe_audio(filename) - transcription_end = time.time() - print( - f"Total time from recording stop to transcription complete: {transcription_end - transcription_start:.2f} seconds" - ) - - def transcribe_audio(self, filename): - progress = QProgressDialog("Transcribing audio...", None, 0, 0, self) - progress.setWindowModality(Qt.WindowModal) - progress.setWindowTitle("Please Wait") - progress.setCancelButton(None) - progress.setMinimumDuration(0) - progress.show() - - QApplication.processEvents() - - print("Transcribing audio...") - read_start = time.time() - # Read the WAV file - sample_rate, audio_data = wavfile.read(filename) - read_end = time.time() - print(f"Time to read WAV file: {read_end - read_start:.2f} seconds") - - print(f"Audio shape: {audio_data.shape}, Sample rate: {sample_rate}") - print(f"Audio duration: {len(audio_data) / sample_rate:.2f} seconds") - - # Convert to float32 and normalize - audio_data = audio_data.astype(np.float32) / 32768.0 - - print(f"Audio data range: {audio_data.min()} to {audio_data.max()}") - - # Transcribe - transcribe_start = time.time() - result = self.whisper_model.transcribe(audio_data) - transcribe_end = time.time() - transcribed_text = result["text"].strip() # Remove leading/trailing whitespace - print(f"Transcription: {transcribed_text}") - print( - f"Time for Whisper to transcribe: {transcribe_end - transcribe_start:.2f} seconds" - ) - print("Transcription complete.") - - # Insert transcribed text into the text entry field - current_text = self.text_entry.toPlainText() - if current_text: - new_text = current_text + " " + transcribed_text - else: - new_text = transcribed_text - self.text_entry.setPlainText(new_text) - - # Move cursor to the end of the text - cursor = self.text_entry.textCursor() - cursor.movePosition(cursor.End) - self.text_entry.setTextCursor(cursor) - - progress.close() - - -if __name__ == "__main__": - app = QApplication(sys.argv) - ex = AudioRecorderApp() - sys.exit(app.exec_()) From e3a1c1d371e09d949f9952fd60720f225ef3e16f Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 11:46:05 -0700 Subject: [PATCH 05/19] Updated constants --- codeaide/ui/chat_window.py | 221 +----------------------------------- codeaide/utils/constants.py | 14 ++- 2 files changed, 12 insertions(+), 223 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index 68f83a8..5916f16 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -1,10 +1,5 @@ import signal -from PyQt5.QtCore import ( - Qt, - QTimer, - QThread, - pyqtSignal, -) +from PyQt5.QtCore import Qt, QTimer from PyQt5.QtGui import QColor from PyQt5.QtWidgets import ( QApplication, @@ -17,7 +12,6 @@ QWidget, QComboBox, QLabel, - QProgressDialog, ) from codeaide.ui.code_popup import CodePopup from codeaide.ui.example_selection_dialog import show_example_dialog @@ -39,85 +33,6 @@ ) from codeaide.utils.logging_config import get_logger from codeaide.ui.traceback_dialog import TracebackDialog -import os -import time -import sounddevice as sd -import numpy as np -from scipy.io import wavfile -import whisper - - -class AudioRecorder(QThread): - finished = pyqtSignal(str, float) - - def __init__(self, filename): - super().__init__() - self.filename = filename - self.is_recording = False - self.start_time = None - - def run(self): - RATE = 16000 # 16kHz to match Whisper's expected input - self.is_recording = True - self.start_time = time.time() - with sd.InputStream(samplerate=RATE, channels=1) as stream: - frames = [] - while self.is_recording: - data, overflowed = stream.read(RATE) - if not overflowed: - frames.append(data) - - audio_data = np.concatenate(frames, axis=0) - print(f"Raw audio data shape: {audio_data.shape}") - print(f"Raw audio data range: {audio_data.min()} to {audio_data.max()}") - - # Ensure audio data is in the correct range for int16 - audio_data = np.clip(audio_data * 32768, -32768, 32767).astype(np.int16) - - wavfile.write(self.filename, RATE, audio_data) - end_time = time.time() - self.finished.emit(self.filename, end_time - self.start_time) - - def stop(self): - self.is_recording = False - - -class TranscriptionThread(QThread): - finished = pyqtSignal(str) - - def __init__(self, whisper_model, filename): - super().__init__() - self.whisper_model = whisper_model - self.filename = filename - - def run(self): - print("Transcribing audio...") - read_start = time.time() - # Read the WAV file - sample_rate, audio_data = wavfile.read(self.filename) - read_end = time.time() - print(f"Time to read WAV file: {read_end - read_start:.2f} seconds") - - print(f"Audio shape: {audio_data.shape}, Sample rate: {sample_rate}") - print(f"Audio duration: {len(audio_data) / sample_rate:.2f} seconds") - - # Convert to float32 and normalize - audio_data = audio_data.astype(np.float32) / 32768.0 - - print(f"Audio data range: {audio_data.min()} to {audio_data.max()}") - - # Transcribe - transcribe_start = time.time() - result = self.whisper_model.transcribe(audio_data) - transcribe_end = time.time() - transcribed_text = result["text"].strip() - print(f"Transcription: {transcribed_text}") - print( - f"Time for Whisper to transcribe: {transcribe_end - transcribe_start:.2f} seconds" - ) - print("Transcription complete.") - - self.finished.emit(transcribed_text) class ChatWindow(QMainWindow): @@ -135,11 +50,6 @@ def __init__(self, chat_handler): self.setup_input_placeholder() self.update_submit_button_state() - # Initialize Whisper model - print("Loading Whisper model...") - self.whisper_model = whisper.load_model("tiny") - print("Whisper model loaded.") - # Check API key status if not self.chat_handler.api_key_valid: self.waiting_for_api_key = True @@ -208,34 +118,7 @@ def setup_ui(self): self.input_text.setFixedHeight(100) self.input_text.textChanged.connect(self.on_modify) self.input_text.installEventFilter(self) - - # Add record button - self.record_button = QPushButton("Record", self) - self.record_button.clicked.connect(self.toggle_recording) - self.record_button.setStyleSheet( - """ - QPushButton { - background-color: #4CAF50; - color: white; - border: none; - padding: 5px 10px; - text-align: center; - text-decoration: none; - font-size: 14px; - margin: 4px 2px; - border-radius: 12px; - } - QPushButton:hover { - background-color: #45a049; - } - """ - ) - - # Modify the input layout to include the record button - input_layout = QHBoxLayout() - input_layout.addWidget(self.record_button) - input_layout.addWidget(self.input_text) - main_layout.addLayout(input_layout) + main_layout.addWidget(self.input_text, stretch=1) # Buttons button_layout = QHBoxLayout() @@ -562,103 +445,3 @@ def show_traceback_dialog(self, traceback_text): def update_submit_button_state(self): self.submit_button.setEnabled(bool(self.input_text.toPlainText().strip())) - - def toggle_recording(self): - if not hasattr(self, "is_recording"): - self.is_recording = False - - if not self.is_recording: - self.start_recording() - else: - self.stop_recording() - - def start_recording(self): - self.is_recording = True - self.record_button.setText("Stop Recording") - self.record_button.setStyleSheet( - """ - QPushButton { - background-color: #f44336; - color: white; - border: none; - padding: 5px 10px; - text-align: center; - text-decoration: none; - font-size: 14px; - margin: 4px 2px; - border-radius: 12px; - } - QPushButton:hover { - background-color: #d32f2f; - } - """ - ) - filename = os.path.expanduser("~/recorded_audio.wav") - self.recorder = AudioRecorder(filename) - self.recorder.finished.connect(self.on_recording_finished) - self.recorder.start() - - def stop_recording(self): - if self.recorder: - print(f"Stop recording clicked at: {time.time():.2f}") - self.recorder.stop() - self.is_recording = False - self.record_button.setText("Record") - self.record_button.setStyleSheet( - """ - QPushButton { - background-color: #4CAF50; - color: white; - border: none; - padding: 5px 10px; - text-align: center; - text-decoration: none; - font-size: 14px; - margin: 4px 2px; - border-radius: 12px; - } - QPushButton:hover { - background-color: #45a049; - } - """ - ) - - def on_recording_finished(self, filename, recording_duration): - print(f"Recording saved to: {filename}") - print(f"Total recording time: {recording_duration:.2f} seconds") - transcription_start = time.time() - self.transcribe_audio(filename) - transcription_end = time.time() - print( - f"Total time from recording stop to transcription complete: {transcription_end - transcription_start:.2f} seconds" - ) - - def transcribe_audio(self, filename): - progress_dialog = QProgressDialog("Transcribing audio...", None, 0, 0, self) - progress_dialog.setWindowTitle("Please Wait") - progress_dialog.setWindowModality(Qt.WindowModal) - progress_dialog.setAutoClose(True) - progress_dialog.setAutoReset(True) - progress_dialog.setMinimumDuration(0) - progress_dialog.setValue(0) - progress_dialog.setMaximum(0) # This makes it an indeterminate progress dialog - progress_dialog.show() - - self.transcription_thread = TranscriptionThread(self.whisper_model, filename) - self.transcription_thread.finished.connect(self.on_transcription_finished) - self.transcription_thread.finished.connect(progress_dialog.close) - self.transcription_thread.start() - - def on_transcription_finished(self, transcribed_text): - # Insert transcribed text into the input text field - current_text = self.input_text.toPlainText() - if current_text: - new_text = current_text + " " + transcribed_text - else: - new_text = transcribed_text - self.input_text.setPlainText(new_text) - - # Move cursor to the end of the text - cursor = self.input_text.textCursor() - cursor.movePosition(cursor.End) - self.input_text.setTextCursor(cursor) diff --git a/codeaide/utils/constants.py b/codeaide/utils/constants.py index 13ee9af..a4816db 100644 --- a/codeaide/utils/constants.py +++ b/codeaide/utils/constants.py @@ -29,7 +29,13 @@ # UI Configuration CHAT_WINDOW_WIDTH = 800 CHAT_WINDOW_HEIGHT = 600 -INITIAL_MESSAGE = "I'm a code writing assistant. I can generate and run code for you. What would you like to do?\n\nThe more details you provide, the better I can help you. But I'll make some assumptions and ask for more information if needed." +INITIAL_MESSAGE = """ +I'm a code writing assistant. I can generate and run code for you. What would you like to do? + +The more details you provide, the better I can help you. But I'll make some assumptions and ask for more information if needed. + +Either click the microphone button to record your request or type your request in the text box below. +""" # Chat window styling CHAT_WINDOW_WIDTH = 800 @@ -61,7 +67,7 @@ SYSTEM_PROMPT = """ You are an AI assistant specialized in providing coding advice and solutions. Your primary goal is to offer practical, working code examples while balancing the need for clarification with the ability to make reasonable assumptions. Follow these guidelines: * Prioritize providing functional code: When asked for code solutions, aim to deliver complete, runnable Python code whenever possible. -* Always return complete, fully functional code. Never use ellipses (...) or comments like "other methods remain unchanged" to indicate omitted parts. Every method, function, and class must be fully implemented in each response. +* Always return complete, fully functional code. Never use ellipses (...) or comments like "other methods remain unchanged" to indicate omitted parts. Every method, function, and class must be fully implemented in each response. * Never assume that a necessary support file exists unless explicitly stated in the user's query. If you need to create additional files (such as .wav files for game sound effects), include code that generates and saves them to the appropriate location within the response. * If you do create support files, save them in a temporary location and include code to clean them up after use. Always use absolute paths when saving or referencing files. * Ensure that all necessary imports are included: If the code requires specific libraries or modules, include the necessary import statements. @@ -100,10 +106,10 @@ * All code must be contained within a single file. If the code requires multiple classes or functions, include them all in the same code block. Remember, the goal is to provide valuable, working code solutions while maintaining a balance between making reasonable assumptions and seeking clarification when truly necessary. -Format your responses as a JSON object with six keys: +Format your responses as a JSON object with six keys: * 'text': a string that contains any natural language explanations or comments that you think are helpful for the user. This should never be null or incomplete. If you mention providing a list or explanation, ensure it is fully included here. If you have no text response, provide a brief explanation of the code or the assumptions made. * 'questions': an array of strings that pose necessary follow-up questions to the user -* 'code': a string with the properly formatted, complete code block. This must include all necessary components for the code to run, including any previously implemented methods or classes. This should be null only if you have questions or text responses but no code to provide. +* 'code': a string with the properly formatted, complete code block. This must include all necessary components for the code to run, including any previously implemented methods or classes. This should be null only if you have questions or text responses but no code to provide. * 'code_version': a string that represents the version of the code. Start at 1.0 and increment for each new version of the code you provide. Use your judgement on whether to increment the minor or major component of the version. It is critical that version numbers never be reused during a chat and that the numbers always increment upward. This field should be null if you have no code to provide. * 'version_description': a very short string that describes the purpose of the code and/or changes made in this version of the code since the last version. This should be null if you have questions or text responses but no code to provide. * 'requirements': an array of strings listing any required Python packages or modules that are necessary to run the code. This should be null if no additional requirements are needed beyond the standard Python libraries. From 5bd57a032014b96658370658c30c39cd8422f582 Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 11:46:24 -0700 Subject: [PATCH 06/19] Added mic icons to assets --- codeaide/assets/green_mic.png | Bin 0 -> 74536 bytes codeaide/assets/red_mic.png | Bin 0 -> 126309 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 codeaide/assets/green_mic.png create mode 100644 codeaide/assets/red_mic.png diff --git a/codeaide/assets/green_mic.png b/codeaide/assets/green_mic.png new file mode 100644 index 0000000000000000000000000000000000000000..7256af4570bc840e2419b7baf740a039a380ac05 GIT binary patch literal 74536 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 literal 0 HcmV?d00001 diff --git a/codeaide/assets/red_mic.png b/codeaide/assets/red_mic.png new file mode 100644 index 0000000000000000000000000000000000000000..e09514723e71b1fa4b9b33f3800bdf47e197acdd GIT binary patch literal 126309 zcmZU(19&A-vnaZEY}*q|G_jpbY))+3wr$&-Xku$(CzDKUd&kDh{O82>dUwC{p18`G(?HnA-3( zSicG?Nh1kScnr-H&wPYLg*33?UH4_-j@oOz?YiwQULW#UKDeANCc4}J3Id~;Q4NZS z07sFh#B_bXq1Iw!s0#deAf~FB{^p!w$g~VL#cmJ_iIEuY@ z1rRJGk=sAKawOr00q72*OJ4&?#@ufzo(yqAG0mm*{ZSZ_x1Awt61P<#H)vZTq6~!B z!2ID-##4&H^IajYqrr5!=M_$amLvzTBLNC#f@eudN#kLhkcRl?WTEP%(=u;Dly7#K z6~dX?w$CW46Qa5*V8I?c))%)QEQB8&d&bhxKI(l^lkvd=BL@gKt~|6HGNBbH50Oe_ zq+b>SAA{lwZOof5*>tcW`MH(_f}n)IR5cwn z4TcHQFbd4zJH&t`3eSPbU?{cC5Qgb5GAJAJKR6n%SSZ6VB7N_0K2;>LXc$F}43ney z*$mCp!Xpt1J8w_84qqZ)_33zPczrps&msi}B8lfw_hR6Qv*GnnP|DMJ7U)n0hiP2+ z!*AY&EKbzw>Ly!};*aW)owUg`+b}?1hR^@ARbw z*!MyK{ei{5N&~gyVS{bD5W6nrX3-&91;PFV063{K`cNaTiBLO-0>58Uih#v)uukc1 z&;lUiKez{IYLG}|H?&BI6CiWHXM_J1WbaHH6ORb(r0}PVM}6<-!B!=T=D=6g_~0n)oL(y^m69JlT=S9Xv1*t%2TO}1r@ zXLdK$^EKq0G041k3R6A}W{%|=_uHc=3L__J?k-GdLsA1gpdJ*pb9eVu^L<^=S*yqC z<^$0CGSJ)Gn*h>2f(6{S^`HAa@|g7p=OO(7Oc5VQQb58XrRl(2(iI@NW%4sZ9rQv? z4db=~8MdIogs8$H97teg0%y&7UFdZ;!9V$Sdb#{i+ z496;xo?$a*Ylp8EmoG@0!8eC~20I@HltvyKmZpOb4J@gXr$(0;pjor4M*h(Mt4_E8 zk$1yZ1%5inzax?z%VH1R8Yq0}o*gFNXSN%4nPJ5^}KiB+UZ)Jhc!%N35=`#;B6Ql^a& z>nWC#2qX`Z%97F&TN1NI(nfXmrZHqA*#@)F#7B!KimD3c6{i#~lsC$M{>-fKEElVU z`*HZQMsdB;Q@2U^j_gO2rMQVQr9#O(#r*kv(mc;R2P@uWHb{mjHP**1+oS4 z{E=m>B>`La3PF=plV?+_mho&=tV?*>G0S)icLx|%Lf-}7FG&fG*6ibi?ZgHor!$-eQ4hhx}>wp zZK@|{r{?MBHmcW4*UO4Zb_mf~46avII>XnVCT z+HYL`*?tMzWD`L=M=(M#!?9(uW;^3xW`|=(!>?xJwwbr8vN|)%w&?ux*y<1myFM^1 zVqX7eFL=}`6e(zM#I(wwk?~muQC3){q%=!*RYo97BWo}VGvl1eOJ9!3EVC@5mer0O z)WBGWW5qOAxUf@0v7Bg;VbHd6oxSfxYgH*y38{*xy1wAKKydo~RP*$OofTg%i<TV;RIXqh*NNy!YA?HnX*J>T{a8*YQi(Xq;7M%S#n&bI!9prc$OB#plGJ zV{%#A9d2o{y|4quq0&}soEPhA;I*@KdfMAMB-c*XJlE*fl-DZP?3kJ|6ek8JZipa| z{o=TY#QFF=+dU4vE*@UT$NOlRsz}pLw37Uy+}B%)IK&>g1vHfqlRdpiO{gz*WF07%@}^ zWC`?Ns5{6GsA(8}-0v{3@ESypQAPvX4wjrg1s4Sk-?e_18`K$`{w4}p4UztxHB@LM zJY0k0CGea1JH{*uEGbt4Eh({xhPZ45H=1m8Y-CNeFCGhxsp&+Uy64&6QcfLc=XE!A zXg#VWB5jC+vYb*zqFmBF4<}wdcZtb%uT^80o&uK~HVH3DaujxSHSuK_I#!RZ+bZxh zI1!eEQd2&g{pvS)kmPbwtgLF@M2?J`JY;S>g zDc`tWEd_e_)Po$=+=ZNroNm%C%6^U_(jv7HtQz$0F@({z^e28=W-G4+L07~3T!NJB zpp-ibYO0P1}woU2W2f^c^mfzsdZP>Bd?_i5yI|OnUh5BP~)k#XS-{@ZNAV z@cc5e>7M$T2duM=3&*Z=*s^}AI4X~;2;NY3VmC5#88@b`Q-+f(y!aV8+#MdVPuV+M zI!-}{7wO^|X>6be(z3$q!j>EKLk>)Q%xOB`SLsWJCJIZ6#6&IlPAqHfa0U!|Yb{pK z*%i@EsizX`@$500vF>jNbls1q<$8;++`q_eBv+MMO7K%r(;`yWwJ$on#oJ6h44!r| zjnw9AjjO)tJh}ee`+-fPO~YPOT9sOJp^n~N>QFtnVq(=(HLmVf^ry#BKE>c~;m?QD zr_);7%T59aHCG#~e%H`;fV*-maLwCn6m^tYGc3`rzj*77b!WZw-*XV_ z6P5Frd;B^S}*5zWr19T(K;I7N*o#0Wo zow!=^th%@$+|%*yTRvG`{a*jFKSWEUmbo(ANZfPcbvNJSZ)H~NRHN69>QMA%`Z~GV z@^$T`b+TvOhw^2rvIEjhU^B}r&%Wn2U??auEEKu&XUm z?-e;{G_7W*tg#GpS|<0eGmjhbIqXT>wfE~y4fYOpo|p9d{AeyD-_zUQ6^@$P z)0Dlxy{ChAx0}{}r`OGG0zW^tJF?yKHq(4(K7Q?z-R!o>N95)DHOCSo)`*%{``mb3GVq||3?}qm=FFx_|_*6AfzlT zDfu}n8#$Vo*gBcpIe)>?DETD7+Dm9S0RUJO{{SedM1J{cf5AdU-C12$hTF)_hTg!~ z&d`M3-Nyc(9RRO8_a|y&;%q?TZewlh#O=;U`X34IPy8R5ft2JwBF>3!_xj6HYlKz|Me~$k; zPZM{G|DDO!>A&6jbdcd6hk=Qnk>P)Af2#8SqjD=)xSLpOh*;Qs#_V$repXIK-v7w| z|2Y3UOUV|BLhg)%@XP;wWrq^Est6|No}zzo-4bng6ZG%kaG*UOqW^K&UI+5m*GFpkXD`OnpJnH zR%`$tlOPX?%?eP0GMf$y}^ z%Kv1Ymoeyd{$oi2zFFk|LpGY|6u`DR?&s1Nbejd2!6*Q!tP1}S&r)gBAdN@$4{@{kH2YZdcDo;yM)xTS>ra80{E75-G=G})Ui5vw9vsK|6ou$bgrcv2 ze11#GV%Dutp+C+@OSGUkb)lZt8g17byBXuPv;Al4pc%wddYb}~nF5iJQngs(Ta{Av zQNrIa@o>=iY28k)qkC6MM>1c78lW-C-Ia^ntaRtcH~sCVo9o}XXU)}s%9S8LwX;$n z;{O@&W0-H4+qkavw+yfc{9(B13)zTLw@~RT&j;N_L!)zNGFRI2!ycDdd||BFMH7_S z9|hEe3kLe9ps19Bq_@Ifr1C3y)L#~<7tbe_g$`5*Kwi1b*FLIUTY#H}xtyT>?Q5lX zmO-T0P*?0R@7!Owp!CXr~31sPZg=&Q7K86!Q4NhbVp(P81582O~Hg1+5-{; zl{mVBba>s?X>@)i%BiBGsGF+AOYxzplV#;#luPC(@X(k+p!9-4NaZU-51g>+CxpQj z(bZ@H3kIuG1ts#E7(csh%;_-!0Pe}L#eKI_lUkH#tx!o7^#^BOE5|r`Cxjg6xRLrN zHsZ-v!?Vssvvq>vyv+2OXo=z>E@tkR;zKFp^aGDKIp@{$a&QpY9ja|zOt9x^e`S4+ zg>dcOl;5)S^ znir2oZC+a@sc<*Ka2fy|DYEPEr+@mI%1$f<0to8cKqk3aS(w9A*8{*;7wwe>*8CN+ zs#nr;y&AOPSVd`4x*4R*YY)qaE|@@_!UCxFmdV9iQ};~dP{N2qjfb%8i{=PNa=EfZ z^sfX4c0ssjOQcZtxBxLufAtIcK;7RGSW!Y~x{c*mTViZ562HKaq}OUKWSG5t12MKS zG&_^3%>_;ulQx)f-v4P!3v0-3tK)57`?oM0wJzyA1rVaB;#&y@wbRK<2F;N@Q+X&f zxG>$zDHOSM?veA!!<~VRzEsR#H=^K055FpdB?jyI!)yWa$t8ZZl**#qsB->Z_}++x zUBupk^5(%=&wj|Ayn10jao`|cgUVRACY6$@F$92vXo}P(CpmzU#!Zu6a2_ozsP;v`k+7@Ug<2n1|@^plf5>h6SBi*e=qO=LY4WgvkoP zaJn7>f`jun4T-81z}ec-=`F!Cx+W{~#GU19=~pAmyUcX;hOa-*DwDE_t-w-a%2~yi z<3vJUI+7dApI8O4QQHdn8DN`JaJIAY0*a@l1tFj_R-)K<-Jk@VoMgN-rswS&Q3aU) zl!z5ij-H$DEHsu78*8zb93BveE;L-|-5*@@YhK$MZ@e8dPK1RKSS!kf8p;FvFWEKb8{n~5OLwH z8&NJ1M=cZxJG{A!@pHwQNo^`5{v2I);_K?Ckw%O!H6w)$&m{Jw;&=)i?Ot#A3A!7$rOWb=PtBJJV8E5$tC4u8WA77v z%lYe~2i-eVw?<>wB1GllQ{%V}+*t*fLmP=^J-cQaDFSh_)O0YdTrZ-Vc-#gC4q|52 zTd-^$FxPfOR8R`oHg3^|Wn|g%M+ocb0j&dK(Omnz%!<)$N0Ac`xSVN-`JJ^yB7;j-Y;~+7GR>NLk#S#%xmoXUF!G~`6qmX zJnRg@Jzus4i(#C*Xes=w8(krK>*{F5!ZOQcPbEjpIpWG`ibNcv(c107**$eD!+Kmt z=C2Ub$)+v)(_du=8NJn{SHZc4B-iXFfKY4erVbY{XZQ0~NUR&41n^a7-I`Zo7)Cf_q)pmTL+@_u8gr^x0 z>c3A_$g<;t7Pqa69yb0qdO6-OV4EcksA7z~WlF);97LD~BOz@$&(YJj$n(XjWovD2 zq-A#6S^FlOmRg?%o%U~&*7e2j-j_n*#CluQli3Q?$Bv<2L#Wc}AroLfk~`~#zcm0L zjn(qQ^>Ggi!f^Rdw=J7b$_&bkELc4=Ei$Yg2R3G$(0dJz0t;NujB2^ z{?CrC32N~MU7jISl42((weujr+xts)&I`%j*df~=(JstJ@Ij)uY~}B1o;dF*s#Ej0 zAoJ-wEX}H~^$5s;1W;HQE~1VPAH)vlkJI^lxL0m&)TKMZ2byrgD)IK)$UZBEeA-|q z^rb`)vlp<>?|Tq8M}fSV5l>4mg?h2|ak{{o-JkOzTIt>l&hOIW)Bz;>7JCU=dni+h zW(|v?6j4u|Ab&E9)MtW+3a7L;()QsHdXj0~nmX{Am?|B@BK(Enlk-)>w;CO$z;f-? zPHIc5S^QX85q+7f4J7=SoRgey3*omvXyO4m0`HYz>DL>jJ3N?$KJCLVY29jLs_##9 z|7ymb5V4*avM`=8M~_gRKbL&D4BRRFR%4c~VsC3$+Y3ttf4+0D1xk!GwLNLP?l6Y- zzOe!Oxd9725hYkmZue@_L+^PX%&}d+II!aK!WF-DNA&N8LQO07m;6=fRi3CGjR-Kl z79SKKObcme!9Nkc9-)Ob?(c1JJ_~VD0_*5&+o^xCt{UB`A2P;5E zCxN7M3v^gm@%TnOnro$lXP)bt?%=Q9#69G89(~8r#lhbFFqFR6+HULPT=%sFAhTd4ecJ zbxDKuLa$f#iJn%D`;Wa0_q$_a!?h*iq~toGajK64Q!|$QnTn=hnjKUBgi}Ll1yTSU z&HNSb79|OHwHykb^VQny9LW2t%WI#V8y6_!?UGB>Z43Ic9w{;>;}Go?jReV8D|}xw zbxRwd@94Ij-P5%Ji1$vi*f_*!pV-aLA|#HAAmlMTmE{;N#kUQoThzuzbPknt6MW$= zZ~cLbb1OQpHY;Y=FN)nAtuuDL8ogC!e(i>T+8{Z8qqNgjIuGUB`s!qFNUi4aEAU?o z;MfoLv0N$uM+A%8dp@qe3~%sc#8yN?_>sCasjxL~>RLJDHuX44#T5U{^+9xJ=)KeE z`kowf-p=KTA08#BOM6rT+b!YoFToyW`YUmu&X!JAAiCR!c_{<(2xJ3e*VN{mS!*ar z2mrA@8u?P%cqxf2vV=J|{m0&ia0ED0X=A%0zRc76!2l{~8cIv9h0(5jGo{z&eT?TM zs$AbgBT=(AJbXNOdKPiQ8d%9@`Y7)Oc5 zrg}jdoPU2wo>v@+xzq$ijs$(#-{D0Y1EkB}-{EoC9r!PDcu~vrys34)&!A_0P5dCB zV!03T)V(R&%m^@0*JzyQHO933d6Z;SiYEk zXef#297;8B%VlA8TW7S81F)rBYKqu5CL~jAb%ep$tR0ZWijeWXWtvw=Ya0W9XepPs zaqPrZN+0Ddg-o@2)9dxW>?$)gIY>K}E&GnsF*)|%smF6L3hI*=#1Epj?#?n*Z8?rK zh8x=NJpS^gyh@LJN(9#_Xu4UpxRgq3P1g(2BNr&%oc9`Q-1(RMNRDHChD&Wm9z99O z7By|!3u<3%ua|hFp>=j`f*o5-rWPUj(}D*pkQc?hz|Gv!$F7+n9tuHTRvb0=F?o(n zGJj>Pyxf?Dy^eE4dy4s6Bldys(dL@8&wGa7lQmYr{?zMvkC3gcG(f_`F+p^U0<&l8 z;&fam>1BMH$}+|2g%-SUYvO84@!Bu4@*t6Hs)oHSHn(>7^^Bis>C9(0)3bfz^bgkG z0o-Q5m?-DY!2w;}acP#}xvYJVm#df!xNnG2cw_kQ^VDf5FpHJ}!m-rEM*kP>L-Mkx zzr5de@okV6GaNO9lD5offQ&8uS(h!J2`^CGG*5s`$JAbX8l%2O(32)1M?vJ4Svk!U zqXdx+v1en2O;tEuDiCPAc!oJP0F)o8KC@`F$G(y2zSZ2756|<@Rak;prZhAe7#G zgzSG98Doxwoe?cehj8xVVjvjoVB_P|q#5=@D!thd!UH6#_4lDVkfh z|A+yy58P#Mko#KO!_MxrmAYhq<5g5=gYFx=+gVFcplC!D>>XIy@MHeXg)zIFWuB^# zyGTKYoYLN^MWv+=_+VyS3}>P_`*{zv7tOl4hNA_X83NSzZY+qfvvQ~j`%TIZlcHGe zb@DWDtGm36KuPjL8%RUT)mfTlz2qZ<$BTRxdGl$f8Crm|=x(_Jp{9?y`i1{*# zlk~@~^sN;6yMZtJN4=&G|THL471mj3Ghvd z+JCxhD^2?wgpki|df%6aMWfK6vuQsfdEav@hrP5Oebr$@>o4xTo}U@f5Yf#C%sA0k z>1fXc{g4#QKdR)fibP`4@^H$X5H`7#6a;T4_y1C>pI8=!8Cdj!AQnjc1sR1572HEJ zG??o=2O;b+hViY_JIxdXwe?hpZ4OwpET|@cfm48 z-oPD@ms?*WK`;G54J0}D$=pH=fNWuEuv;^lu-Mxz2F1VyJ6*%Lu4`Yk^VQ)%^G?v%N+iHmKCUjJY%%17<}n9=_j#IbtXlVj`YT*bZCrp6A)y_3L(I`8J6Gnd$f#lqtQ&{!y81VT0} zqF*vGepfA!uTY>#ij1**V*!S~$!#$@B+`9c%lr(%PEF);%oVb&cMmi1s@|G$l+;v1 z1p+axe7lqLyzWz8qZ_85#yv5osV&vk^j@dhMtED}zc4J)r73m>97a|K>MQ=faXY8*vJH)VKcFI-l)LLrDgoVEl;Acc?}!5Adej zA^rLxly18^@Gy(7*j2QUjzJXtq9TfMzQs?d)wHkV0PYdmfRv+qaS^54&~2MaDc=$7 zc5Lu^1*VlSJ;&8^o3P65BS7C+0DCv}6`Fk-->8tLPAmL_Yt*=OUfMC^z-`2}z6j|l z$g{ZUHA;EB6b+DOlS}I{EB{lAp%610yYH0qfXs7(LZGQQzLz17Gg#hV5~v*!Kr)1>O}^J&1+L5HtPM( z3&qIeJ>Tf)g{7rT zAuQs0J9>-c4n`eW=MjmRM0t1TW!)A_PCiJ0evd-V*rJXOSm6~U)>50R)k&vUv1UZ< zCwNLKmaeQ4oK2PsBZc$#bubxG_mS81flcK}0eJm7v}YS4xgtd7zzD7--W>_%8DeUu zU?axtvVOPBX*{FIbnp$AxUypUz-rI23BAf3S)n6UWNh`ykpn9|TNOaod3j zQlF3xD6)Qs^%s?Xq<+OQ^UVW|;PAq$yPKJBTExC6R~p{La17oNzqm(hd-2^w4g)$9 zj+j^mjCf6z4)2|cExh0NI@+oPJ#z_2bUFYv5P1Bp<>GY@*%c$4ocE3igVOzJlhq>o^%aGQ;x>b1gER_%Lct8^vVZh%D|F9YM+@kiA52 z6i&VptgrX#HC!wx8DuT=;{p1x{>?L(a=4dMyw0%M(Ia4ECcl*s%E^9yNAp$gb|;2Z zF6-!}g5llywOC#$PO5@wctPOg`rvz5xAf3OJTQNzT@|A6^$W`32^M*JZo1!ISQ?=9 z7WGJ(8uO(D{*a*fKpK333p>=e*?dvsy7*Gd{+f>a>bC^T!g(9J?eiX`(OxNjk2%WG;=f>pYG>?w68X@eu0013ddJc*46P!P(B zDE(ai9E}PE1AbI0rJhW=oO)X-?CeXAlM0Z~(urV2@I2&6#qqoaJPC;RiSYXCc7ek7 zN#V-qSvavYw2J1e27mqtR|;?Gnj1E{H|q%}e&1Cy1ntHRH>p!B3X8BAKK-RYv1KdC z3H}8U{`6Y%O2^eJZBfGFk-UP1x_j^^xfSZhXV@r~!QP*WyV4aD!H2v-j1THY&+DtM zlNh$0>q}}K(l0ZY=>4#M+V9Nk{z>f_{~9}(%I)nSq)(lQD-+a}7CA2cP>PWDR3^v@ zhv~LAws*@br@f{Rf}}{}txv)&oUc~0mFvp$Ul7)u_2-C;ZM0aboBz@Z&1a!GgrT`; zKi?Zv5T_^+c8&EQF-@=Z7iVH8L9u)$PKDZ-kG_Wi;GfF?jE{4sPy%`mZkQnv^UO4n zzzlvVszOOja$!M%>+G!~{!4A6v!-Qf4|&4F4UIh9H%t^~*7GC*!Su||jMgk~bUw&1 zsiBr*ixhq`VnJ;I(L}rVk=s_B3_4(V(6LRdk)>6b&reRFwos^EldA}|dzIfY%a*r3 z3`uf$Z)g`NL%$IIF}vAJQS*M}tumI-cvl^^LqW&9^{+endf>^tU>Bo0GHrB)ES^LdO~ z_q#;r>m*2wfE&kaXt)T-N&jt%e3MOFLlgp5z{h-?HXKk$#~ob8kSYb}REN*;TA$H$ z{?1KlfT1*;ifhID|$1(WA|5S&w-p%(Dy>cr${X2A|^X%;+o=n9q ze)H-k>Ss|-6wv9Jhhwi?#Fv=zasZf+k%pKnhn!5+K2cH%3rHvRKM&jX zt44IOW<6ID*^lpYOfE;}GE8T(JFQj<%GJgVoY#0xQ*9+}@W#JKLiT$^!*KZB3U<9Y z{Pd<}v8m2-dVxr8g*RQL=f>l!+gAR%gtjv&M{+FgE{w6?ei!8B2f3*?9zVZ;B5a7; zS;X$OlfGZI7}#+?V#LbIkY8qI*bXk?XvYEs$Nc8Dah>sBwO0^LX!tei9{$YimuPLw z1gz!ZLq6-kUrcvpXWMM?H-sMCK}Wzl2I%x58(RzYAo_R1=HtyTFu%xcimcC3dMd6M z9kJXSg0EX>o+HQNvLiR4Dj~~DGNTeSI4vX*VFF~t5?%*xAJ#wzAT&T2-jNi6E(`=k zzK3V*sd_Y+HW^9)(&P^@frK*Ta=Iy5@zbWDt3NHoQE9|ax>ZoGHDtAQPld7*Shtcs zg$dbbJ9`LU{zCRrw9}T`J<@eu?NmVYHmn}4#X8^r;0KqbJ1l!F9ZZz$ah{Nx=qu<@ zb;yhTsp1ZYO21$ezV7Bn#lGg`#_9?xbdn$BuXM~T-@7S`9RwTy*_?FIfp5jGi>Yk2DDLzYilgQCBf3h1xNA1T96Xe8 z6;p6N%rW|2PP(OZ>}o3H)@kZ9LePkg6mI<_M^1Bg{P9w{IhGXh^uYz^@;}5<6zky+ z7k&4eIIoM$cA))kLY8_}s@P<#v}DyEP{leFlYK*5!iFWH@+ot|Ri;zJHxr)MoRJi> zz1kji;+;l;SakKT{J3>E{*7|&^qah!gYSCKgDX_epWj_x0m%h52r~7;pGzm}&TEi| zQ=y4^We?g1U~@AmdBK%$GSSP~^MNkiw>wTmypOH9?=e=8YuU?QPGg>O)ON3Bc5L~T zjYYQuJIE(oj~Ryo{n+0Z*`S>@i=dCVUWWJzWmOJPg5z={r=%GMt$KXfk-9rMSSD9k)>0P&OJ%b}PIFh9`4-Ms&`)bN&?{>@0!-i+6loS*ThA5OqOP5M(I34R z4H&-xXRzA7R{**V^>|&6gNnJ#%ik??IM)qurNFG&8NH(cuIFhF!?U1Q65nfNy$H6} zwkjbJMnNExIEhdI3y6ZDC41`qN48Jb%YRr*{;e(=|Mv%5VO;VtepkO)D&CTEj+t&>DLr_#0 zbxqF-L|b?HI9K-|E)a>G_a^GB5p5OtTKUT#zr;M5Ia`fyQmN8ujip)>Sfm&fZ;bqU zl{ds$hkF-kj$Ue=y)U0*my;e*5YXp)nEE{#aq6?`5W!PB$bW?4x50ryH~31ciX3b3 z#ncPpYfiABdT=>E3$}RATafz&s0S~p%*-%xs}voecO3@yxW|yK3zb7&;spLP?b0c& zVQ*ZT0?^%kKW@X27bFF~jnj&vQe(S||xR*$SC2OA6pI%f?Z3IvW{+Lgp<8L7yf;Ur>a4q}>D-V0jwcKLUkXaCe1D1*Gb~`NZ9K>a+ZL`RGMiv@>U`i%(7aMZAn>D=i>1E5f6E zQ>{HM0A-Q+ZWV}Pe5|?-)Ibx5SK234XgASthxd|MVi=S-0@NOTH0S^&0m1s(eKk;+ zRYi^x;}jMXDrYyf9QSJNi5It8DJoX#SBWKVy|AW$V5BSEcsY5XFW;-0xJJBHU?*9_ z4FJDJ$LnE`W%E_8^ZCe#>G#>^!*1I|u5(+tE7nw#AC zfP4%uv!&_$4}65q@Np`?WsExJOU#$? zpY()7^!=OKM<$r1&c^?zCxWE<*AsC(ieD<9xy+XCE%ezvvG#;|WspG%RliN#3H41A z{#CpUiQ()WSzK?XbM-#!UV1)`69xF!E4~rQk^1KV8LavGt^P9Blw(WJ`@grAhI5)ax=sGBOaU=o&X^?aJgHCeaRa$Iq9w8Bxp zhc`W($L0B+XVrm5iACRzwwK^YVs6;e{r_OdS$7`eEVwB!SjrQXb~ zyg{s8${8|kJa2(BIlP1wHk*R)a9D$RoErt^0Mz~UXF*Z`0@m}C4NT&E_nM^P4t3Af z>b7zg?t8_+mRzqdx=%wbJC|{O1TM*aS+Gs~Qr$$JLJ_)eS!M zs0tW9=#FNR>=?W70SZVnFmsyzY{qT-poAV3TUkz*n&>ZMObZ4C1#@vSLqZokB4*X+ z8>nut$7V&6Bq5egm<^&^_l@?29COsaVv6&_sbTQG3CZ1f>+uOZOr-2^WH8V^HBJCc zM}-gf2Y|mbU;`s?aPz&`ij#A5eGyLZ&i0N>nf`WpGU~oAxb1`t=Z157vo0{wRE6vvjHQn|`Hl(Pj)xzdjcTzihU7r>)dT5#z zCpH&AhkysL!cIS6npHdq@T<8S#y>l;vljbAP8OFC*bMGzk^qpzcvQ} zSR{?sz+`eK8V5OWpZj)SJwL3YfIgB0`luXrZoe*)uLcrC=a*^41Vz+=%_(K`g1jp@ zy)NFpJ@i0ao6~fNof{KT%6E<8-DQrQ)C;J5c+b{9w6($BTn=ZhmOjowL({lx!@zzQ zfGJWtyqc9kGsXp-xy23_ zju*M=zzo(yRwN?`9IuXcLs*AWZt3)7M~ep8Z#oFBwIw~#UU|X3GNXJ2 zLe6MMsDN#qT8Z+UP;GvnT5F1jRm=L;2MIH_R~&^DNKU@&&_26Ich2d3q9_-s zPBCZHUl5|ODk-tja5%9xxlLum8vOZhCstSEweQNjS0M~Tf5Xcb4et1x{D>9DuGaCb zhDZf7=EDJ9&!XebF?eq@r~W?ZHS*9mkkLdKIZ(0u=d8#iKizUT^1+@~TGmlHJ`M%q z7KRW#=uA&JQGy@^1AaZ~faMdP!BGIGL){e5_WB1MA`|!r()Wy2t=11qnHtje>mvwBzsSLz}QP;m@)1P5%c6tkIm}-sscaK>ra+6CMn&^e_ z0_E1+t+XG^KA5mtY$LA%aH{r~$N@BPtEONEpBI@1{VpS@8i_BzAR(CB zt)p*wktXzMUW++umEcI=W<^*J(e(S}@zI3L@Q>XjMW#of$QO@F6xTOI$u^QLnTza% zRUB=}B1R90-V})^4YOSLHj{VL7j3x+TD29au7X*;?6^!F--Z%atrI65AEfoHftEcl z&*s5=iD{VuGRePOcIxH*!86+l%;=K8y)4A8G5 zasuo5Y+^QF9bJ_wvoIht9g>ym9vaPb;1_1gy28(~b`;#okR%LMBIfwr8Rh)WX&p|q z^rFy3+#HBNc-dU5fP9BPVvoOuq;7;wQ5x5>$<;X`B@cN)PUE+$Rsq}h4Bd116)~jS z7TnJ;SW^`p7tz&u&xE%D91wC86Mi{@0}!u*%@~XrZ28UrwmMu90Y&UX0Kzn!t_1+o zGFVYabc;)v;m=ROij2wnVuf1MH!Y~UJBZXX$ayZuE<$JDD3#(_(E(AL_-C+~va=lk>0<%P$o96o z%8B%AP6?XR39ceCSDL!5eRTc0oUWgf_J`Srn@VkWrXZTgW~m>IN5TX!_ z2F(Eq2Dr9`JghF;Lt|9+GU;efIYA2zHmqy`@SkPcoR!PC84jbiYFUPsEePZ{Y8q6g1mt ziXQ3cCd42W-N(}HM7(vq?*|``(>@}8tP#bqQ6dj=PE{lF#}lhK6a^G6Zh{r)e*9bV zc9&UQleXvpFA1bM8E77auB!IqgVr~_53N#fo2d7brbn1q3cr3L0H@e|a3f>F5W`<$ z*l*t3U{crlo#b_b>EPEgB!*L9TYnrYkKIby#?j2zBE8UpFU#rC#;Bav18OR5SaVxD zof+NFeD+qa`WgJVN=;3T*gO`lh)#h5%mWCCvY3jkLnH#?J&Y$Y0kSMxD?#3gchvXq zWASIvICnk^{f;M(zy&I|+%1xJm>&YpcAbX;?`20!F$(##tv%mgn~Ko@HX-A(U?e0d z02Gb~q?q%iEPni47C5FdEk`?TPiqRZ1Hs0yB-2T>64?9KoIr|8Ft$)R zXS~sh&?&oXGUTBtzXv)aT+S(tnag-x__Pw3{aEjh=wNlBv~N@N2rh zHhZ5aGuz?nri}UhPd6wUiik-wW}NV4Zik@P6Jv|)KIjn4pNWNF+exWMn zVa-jx>S@Bva4)mcAySMlpFYv*xGi$C_`k|l`rWvJ&#%U^a*uWRW4$wpr2wp)eS%Pm zA!t$F(NJGI=5b*TP&>D!t$xc@S|Aw6P|8VtHQFS#zm*?W{?ry=|C0Ov_1b2sA+~Fd@B|xy?5Zv8@1q<#H z+}+(7zJJZEnKdu{dRFzR>Z-2Vdp8LMH)Y^oki5|AIZbF1&Eh3SNo5WpNX}UP?$&#GAsN&6$_ zga#I4?a^Zb9w2#r^4)|?d0ucKco|0AWV~1~ZEJ)}VnzVzNC^OEy*L42B9Zl(2A|DB z6=8y{yES|s(mu=@*tS1_+6Xi&=(~(zJk7WBz$bt6_H#;cIZc4mrv6i27+O-x^h|OsI@7nS0$76D8KtJ<=PU_HhQ@&rnHyod5JXp_B2*St*<{K( zdR-Roc^KYmQbDGP4UhYhIJbYS`O%6L>g1O5$z<>4Zon=3WyN~cn>yLlSgkAA))pMj zT9NjSJe6XUz%f;(!h+C&C`^k1h8pwz!IXCD6&?x(c>Vk0?h%x`uGGA*R-&aY^!YEG zaB%}!vDyAF>660#kzdHLVK@ueM#gFGSi04N!zdad-T8JXVp%2qRiFyK13q0>{ArY!ajn%JSr#y5H{E)rIIRadSs3j>BR3xU+&sDGt`)+mU!jDtu&g$LpM z3VK!!sO7+A@i~cPVGMzQP%H<6r9%KRr;}w{1AfQkt~yHs9{=^XEYGu zA>L^y223B+$ky*r)ax^Gy<9`aXhemhNvl8dd<);4mC9x3Y=%$}Ol3xGIE{4u_AyN@ z$i!7dTkTYq&nMwcKlmrakm_N+1ZqLi=wz*H137o;@_^!KHC6ygCdoVn9HeS(CzuFo z9wyM8z+h>L`GnP#2W){L^{>z9l`89PQ>=e@?N#eoVxS2GRrQgk61@!oDY*NWKDS)1 zZf&ThWh=;?bII}2-SxE}NImR1EI|oEX%q6NW5lb4mbOgi%rHm3NxGiic=)nczFiNP z9nRgocUDDNAnM(^ljSje%`$KUR+o1XNkdF!V2QsBV9g=Sh#`X9X{zlXNB2x8{1vFZ zP|cPJ<5|dYT(Z!yj+oRW{%$U*5`Ow)LY1JOqqeKRIOcuyQ~X5ljjm36k1y?6PFU0$`TQ4srSK43coJu8Y)}+5j3Uvm0Li~WI~(2YZDpV@Q}e8 z^u1Hhm0!P$Pl1s-^_HtU%$4J6dhLOA^GtHmf1_m~w89GcnH$dVnM5UbRR>+A*Lk4M z+lCNAR3{@IN9zdiJ94hm=sZZt#Ri|GB1G(@)y#iPI_z_C_%FeH)Eidz zORX7f&LS7w{Hs540c33c7Ya_>2lQqltLJ7Rh}lwv239>iAn9tU1a*+<-YI-aio5iy z>Djll5op;EbG`Lu>c8DdqtFo9gX<&57J=0#+3c8_rLPgw;Xjcv zrmS5!3sLfr4s8%onfnB3tbc<~?RC9znM(F2ih{ERiDYe?d%PGI)9AZ$E)|3Kl&DJG z4SLK#-m-glOo6DeVmHCoWUJY|8{54i*{AWy{8U$fIPoI`NKmoj`6dZL+VS5NK z>kyndSFa~=7m52f+|&1;^)X8Ngp{sUUmTXq?tchaB)i)=7VPwZMsDvhqpVV^hOZp{JlP9qW!%dwdCxY(q# zyst3nZNWBV8Wd2c6-4(&l#%1Yv+}$BlhvfM)1~m!hR<)`lDo{J;>#JmVpuEyi2;Hk zdIg3MEngq^oFGjsqBrw2o`&1`zulQmpS>y9)6tuv5tSPgq<%!#fqxPNE5Fc%!mTPm zhvpT(BZ`-P?wYZzk$3|Y4j9q8O z_VfYR&|!~_UMM6{fGd)D&T9;n`o8}V#_}(@mX3`d2Xmj;j8}7*NKXxN-mIB9?mXKE zpP+riJFl3-J1qCI7QlCzlfUsZ*Rn|2iGZSuTPJKaJ=;$&h;Rt+kRT@M^{9pk&Ur5Q zRKL8RzQ2Fsz(GoyCY-!#7Gv>@8V1AcF&+wB)<6BeZ!(GwUVAa*R;4(TdYiW!znGk% z_AZMwmD{-~Qv76fDwIAlmcbUc>d*3BS_WRGg)az&g2)!ppbN`aaT08*so3%M;%!2jBJEWx{vPGH8MNWP`#{F9>D>svNQ75VY9lM_zGO=|T@f;N<+7H`p zeA(PBO!3CB{Uxsxc7-}oyiVWk$ztq6JLu(2&75d|KNiSWP*2!;Ml?Fke5f6>{%1H9 ze&knS?Fk3i?{}yMCys%ywO#H1>Vo>lO4g`u>@SqJ^qK~E?pE>hfgI8AgJPIYUYHXw zT$4_RKB?VjYTjyy5Z@5KpUt-LdG9C77LNMyFxQn#ePn%cc}t}??yZwe z>g=Jt_oJC3jnSv^ZahJJ*R|1Ds*xMeGBiWCdk@ypeoi77b80Y z!1*{n%2kYn#0B;q&|!Y=dD~bU*e4|qe++fwh)J5&Acy2^%tSNKOcF&g(MfxN5Dd~- zK(OP*0K}oZo`tG`xt4d7A?Kflucck5GXTASQ(DNZCgsJ9cGGbC=r1E5E>uJOosAn9)U@6&v#jOCp@w|lt{ zkc*4iI#-HlQK~@oZy8rhRtP>1Z%-s2ev9CgA;NaxeIyB-=)X=e)o^#^C8S(%j>_dE zeM;x{%^26e|0oi(-{dI9 z6tMW*%zkKJZ__Gq^D?9@y}2izVBz9yV(+lGjm?*0@6W9!UHma1YprS0*9c61gc=A5 z`y|(3) zb&3CVWZV>5evuKO1_Tft1G?LWCGjknL%=Z{c{RmPm%E->(L25DCm;T=UeC8SpjNKw zE)0*{C?|0+F8N#%NPPys@@66~lWw|fee~}s@n&+s1zVoi(`Zez4eDkk7Sg)xs~jXR z3UDO_|AmamtvM#S9P?v`!ljLe8gszD! z$;ha^s|F*dI#+}6`HkLGi)H=muQFbIT_i7bpGE}#jQlP_^J_MZZx$zX0pxfzL0rGnyD}|+C0Wj|H5zMi?zrcPwAjk|yi zAQ7y!3Cbrs=G&BfyEKx$>JZBJxY@O)j@|r`AT_I5o*h|88yF%eSY*n7E;y=)n?uBJ zHn2bc86NmBqWshEv}NIG-|T`ZKEvk;z1PywXn;4CQf9y&IxR~)f?;59riHr>dUK|0 zQ$zSdRwQT6f|Xt`DyX*pVApL$f4MET)(Odl3vCuISP#c10(}gSv8f%_Q0HF6!?@VsR*ln>-^r8+R@#knuno6 zoI&*iKLV(9+4&qB(ILGVMy@y~FJW5`osUQSw~1El{v*{$c&%vRf4T|}k+>x8=i@Uw z$h&5cS2EdojYUR?a5ouR7c)0yOv zD{qG?d0tlylVlRvG9caW16BoUEmREO-b8?Eboiz&-5Gsl(_@BUp5&xn=>|hz0mFwm z>Wjr`75W+vB&M(H`P#vT^ZU*p4ObekmAErHV~3xMVu4&LzIuoHL$db_vlg5)KA2F^ zEp^cj!ib~fePUIHvR04hy<H_(boUugN@?zetxU3%5#jo+m;Q2h5Q`b}1pQftEE z#I4J~@?&LUN%q+2~i)eCi~`SOdB5h3dvRHtq@QuK^tM7F(ho5GuP zBf6jWyzRZk3?>fb2U>H$0*6c!k|@g4t_*+U7~^q>!z`He0PyFiy?*XmPzp`VuUPah z0-4osL6!@#iF@2|fkLmxZ;>@^U#T_btS^yC%4$P)ZDv@&5usxq9W5YK!M|lhq9{5! z@$Z-=JGSe`p>F;M7Cd(E&4_(60fHk>$7#tn*+R(Y`UP>6N zg4(}H<6NY-E>-4gj8c>(x_{wXuqRH`-zj)+)3FsKv3{2YX4+QKv-Ocu?PehS*9C`W zFo;1Cg%+#<*NVaq?^hFE3f<^j^DGDf%0(g~995tW$vE?P#eFzQ@`1rBl)GyS69^nj zCI-LqiE=8sY+UJ+kbPy056;B}!v)pX$CLn)BT=ufGgXV>)+l^hq)t^Aaxy^T~rV%5gys?%|h3lWp`l0XL%yIjbiQ=dwgkBi$&_xa-AFe42mIc z&guWrh8Y;uN~`+wC$5e;&97b@Fe{5GjPcbFfreT$P=>WY7@$e^-#$-6Gks_7AN5Es;o4jeGQmLv_~ z_en(wW3;$AU2(dCzLQOCX}>wq@!_x}xM>Ye(tZ>FW|#yzhu9c@qDXl?$G8p3DdA5F zFu4DU2*Gzuk21XId6Y01*Wi#&{vG@zE?MOYRC{;}?gl*8-T%XX6;&2}Ft;CgF~(X^ zfTq19${7}_jXXL}+ ze^c>wfQcrFv5^IwSY9IY(ECJPMOl$S$r-E{rJyzxaZsMota|x{{wdH!d>dhst`O7? zTf`SMtK(|hp!1h>t;dOZq@PWLyf|))vZAki<6=YX(Td~oRS(e~;Lf)z=aq%i0`m{4 zYGLAu*I-x?Y@56%N};##-YV+%0ly&8k?$8FUy-Dl334BC6!OwZ7>Mt_r0f=sNtOSz zM|RxgOI5!mf^{z?)`e%*q#_jIR!2HUG689Hwh{_D?a?C1?nk76Z$jErLQykzbm|t_zgc&v!wLRHfso9Qy@ThyCS@a z&;fbd4kDd=XuezV_p{m^Sm_skjF6qKGp!KeoBtx%&O~v@OvphoSP%YDO2TY?PhE>o zE1oQU^;>;w3wn<-Jzs!gj6^PK>LRf)NQ=F_e0@X_oCZaajtz}?ie zK*`#UkcLvNf6CFeCl(Ejr``D%RCB8-gvD-?i&Crc(wofrbqW$nAQDu9!(&@ui@Bqs zj(~{>lA91mlJR)v#EUO0Z;IiABR*)I2t_+hQPU{*VxF0@C?TL4_VE%;1haZ6}dmZq4)6xfe9!dRaiA&R?`C?GX6!L zLhf-*w$~}0l0qWNu2Qy~RV69TxZI%;TmZ+J*r$y+ke=Cgj8Y_+5L=gM1ytt~=v#sg zZ|2u9+D?CG9ymxjcevBPAd+E^sbkFCsmh)*C0h>5UF96mqw>o^(=!)<5Ns#MNZx4+ z3JzC=WD~0s$XeVooT%jYjBb-JJTVL1@S-mjvRnVg-y}2qPw`r@6_s z?+EkV6ffdsCyR>t(!w%HUK_vKz6}3ayJRt53uVS?nhtDx{|J3fV||G#Cd%i$ocSIR zLe}$jVamD2(^!`5d#Pwl`szk^;aDY1C0NKp*P#P;-3X$nGxM$3WO;l-n*|$Ssye!4 zPS+qg=Cc9zU!Yr3@r#f+A$Hqc?=1SVf;s-)tz+;}4;!9bX`Jq-_T2Hy)aI!JA;fB; zfbCa%Y%*%r-QEaVOn#?;zHi+($j9<%=TN9Fazzgah=3cpc&Mh)WH7Wnr#xpaN37q$ z(FJpzSnJbW-&hT%D-XYP59y{Ttn>%b^T~BGddgJ}1U?W2?4!f5Mk9nJhn>=lnvKp6 zfwMKw{2n@?IhiDXaHCW3$cco)*(Jc%;P`%D)@+5`H}WQUzPAL?^4oW>X%w`P@pdWU z&aVU0Fgv6@Ujl@p%2c`sV>ZdSB*?l|WKG>XbPe?)yOL4&2QB2UDpm8LQBso*dr(Yi z(orDJr7dGb@EeLPejyAj1^}4s^sIVntY7IOOU0LYZsTZvp_>F7qH?2>*-D_MFxeXF zR0s!NB-cfb;s9Y&E)*TOXVvS{O@4>B+_Pds@P7vzai=6jHo&mzAPoHz-IO7MA^b(d zz84r>yu=UYzkR*gi^#nFT;3De7-%<=6;k0byjit2ZrwyAf$~s+a9pbA|L1?wF9MBB z0LO$3^591d*KQXtaeVywq+e(QX1xUcQ^m1LeWH0qB;V8*199(f1Kz&o)%f^iqzaL$ zOGO{NJkL9Am#sxxeQEN@D)`W(qTI)Cy2p@Ck_n*$O4bx&hk=OKQq2_ytX`-PlHq?m zIhs93#8U69XIG|llG6AX7^Ze&x|&-$5rNO1P`cSYpQo38^E58IXzRP38F19v>DAMx zeWBvYDIW1DuG`iYRCeeh-x!e)XQTKTBxX;?%FN+A)3ciYu`3`YK^_g9rqxOVn1{^7 zu91&sJ-Q_$+KWd-jdu{RJ)e#D)yQ_j-`}u9*iE7Qk&kI{984u^n2GeWHOQJ+W}-&o41b*7yjj4e5R;oT9&w6*2O6Lf&7g?#rxV9VnlkL7>=Dn?{uC-%Z#t#?5jjx z4bz3}7wfU(CDc(v=T^_xitLo8-USFqLZew5gU>TIJmEMlVM#Lfs&ui_#jamH-wf`0 zXHe&ZjrZqb$NPrS1L$LoPb$bgQ6V3fEyybM0Arp$f_?2@lVX}q8WB?G3b7wV(RFd3 zi4b9O4Fp)NlGgDT;6>bYcyF^8xI_PbC@x?aJ9l)Dx*8fItqCk~Al`YdTnZLKbK?!c z{m{%ai#Y^)nSoQ9#RW2b|`f{IVLvnAn~L=eR=Rp#9;*G{y1~7F2#{Z6$0{6ia#ei&mz*R~dP* zFkOO>Uv%ZLRP`Ir_4isJmY57)6s4w4Hpk}|c(d(CQcwD>Zc+iF0kS8# z=kv1;oU)qNN)x&%@87sGF*D^=Oz9t*35N_Py~)Hij(K##9{WxC@!Yu(Y!}WSz~S3x zB};IMm?5T^D;^2ffcboaovN6D0aH5P!0g=`w%zFydnM}(GRG5+R}9UTF1eEFYYS5b zx)5@`6z}x8T}|%@H^o_+tx4VS zvf^{_!R3`)xL+gx5gF?pXQxNm913;Vc`RQ(@td!?LeH%#P4eV0BFLalb;98#w{jt@ z^RsAx6$C}&M@D;Fe!$I7f4y?5U4RpaR8VNb*<-6`1D$_l>3N6(<*XN}UqNZDc5DPr z*hF7l2n|?n?Y!M;*Syu7_5D1+-sh`*Rf$Rqq~QWtw68${{G)`Mhj}_OUMMy=Yd&eE zNhzy5EC5XRiW@+)VO5WIZlb|op&FP3w+H;e%r+4y1$u! zzw@ypR9SppjeQzoilK!&fb(6X_Gr8xh|^#n1J}&h)i%*Pjj1ZGHgFigpG_K<#G=YD#aMA4A^b zaa(&c-Us5scld82v9J3F3tfwyN;kp$5|Ylo*Y>mO>pVY0f#TQx>b?Bv;;~6)5I8OF zva;>hFit<$^L2e!CDb#~NdAf#S6C;xaif!qJ+<*ZnU)-Ji@V3>uf-?Bi2SuTf8nz8fA%fCB1OLK@zVAt>vb4ih#$WSPP_f(;z z?`rM(#QHAK(z#T3K|4dSq&3KPXZ>pro*MItQUSP8h3f7|5wH~W)QDOe+Y-4KJqP)r z30pQqo@&l#S`2U}1oka5hC?EKoeJyP%js-R77y>8LCzBw4&Vn3-a5#QphAKIca9nZ zzz?|aeSYqIz2kp~vNGjbU+8tITj~=WDVi?w)A%DN*o6Y22RdQLco@Sbl4t?eE2Y)g z6xJF1s1EO3k4w>lXqxD$o&gS~Xji-aaqqz*R$lv9&89V?^s_hixz(d^_iv{s-`X!Y z`(qER{L%26#rnUvyP>vrdzn34uo3?I&JQbS+SC|hOXng-3F}R%I$Bh_&49gebf|;rB{+0vZ6HCZYk7h7CIck&2?%iBR zrK|G=o$B#ct4cvZs**aq>+g+ruqh0x=ZW#}>wWai*{>pai32LVwmK!6M6&>!<*TWb z>Pwyh|I-}{#ceBG*oT%Dr1Y|Z*<2%4ryo|sJBXf+@&baUZQlB*eg@f(Hzd9P@N$n? z@5WWb4&QlSS7SnEEC9dr=qXLB2kIc~fQ=^17s;-JwS|F?_5z{*O7|rZ_MLyu4W?WaeyU1@(ad}&A)7B5 zc~^>#2=YtJht8JMlEJa{=8~wuUbe}i{YH{>>Il5!Vb=n^oPCkLSLf{P;R~N9zk|(# zwk5WkAJ{Occ;Bt`08Udx{OM@DZgk^6O=QNUTUN3()^4si|4h3w=((T!^&DeGvY)M^ zm%%J9)*QywhwD}3K1dD2Z27HsNee;#UrA#pWz6RC&uFj^OhAm&;mph;gI^?%6@p=P zGjRJ2**OuI+`#^oCdc?VJx(2tP&$?UbA?m36)IP(p*7hHEnM!t_hSph&k-gOQ8n!M>{{(tkBMco%YH9{D#GY5m?ZS7@pr}0~rfh z>O9>^1K^D$KW3_vPgx-LI2|l;IPoF^o9C$}rWS#7JxAmFEmrmR%c;mlNJWP;i;-`i z@OmalqO-$wJy9?RvQC9Dwxw9kz45cNGLa)9K2K&l`3v)Jzl?CJYF?6l_Q}BXMW-Vc zryHvPHd|(hA&2E^JoUwK&sq%ryBx&NqCHcV;Bz>LBT6eV=Jxt(^mciE?POG!Hbmuo z^qLOROgJZx8^e9zob0k+h3Z=xV25Nq1e^J~gTa%-OvTG)+$!|3-Hw>Azara{U90DT z$K9bo9P-nLc!WC_;0=AD1-2zb(__>lc5&lKY3{wG)e#}X+;;^4g&K&ufSP~xyy2U* zc=fc=qpk4Uoe|aYL|IMz<)lFV5$@u1*XxJ(gVXYj#Q-Z|S&PoXQ4~5V09VN1_b31I z9H;_d<2f|Gd0=fNMnGsKiOY8Ug^O6B=Ncy_L z5)FvPHygFL8)i-HEuy?@?&|h$3oDZgb)-g}bjSoJQQDmkIwZb_X$Y?VNl7q3P2dRq?XX%B^fd=mq47kc88@m=la(U={Ueu@ zq0K$?Pkg)?<{t;XEa%>!@88t(m4B=Rza!iho_4AVH5(c^Z4U>HoFRL58%O7<^}~ z2Kw;7lrzKkI$wFH1jGnO6N^mqk39CHkbGH6+a#@u3g$3WslzJ|aeRKPxhKQbv7s2T zg_TSyolk%4#>nEm34*#}0E#tr#Fgy=*xMb*V!_FKu9IwYRULx7e;z8V{LlXKXct*A zinWnB;rB$^Jx7A`$FA2Iog0Zhs>$mNAg+GvL{?*bvJ?oD|LfzpaH--X9^YLqXEWUyl+?E+27OB+kEkaGtXaZSVzA|7y!&+VHf= zKd(+Ra5OHz>hi-D4CS4WR500+?WZy!v)OjAe>xvVXq0ryHU*;DT0hnDmR~eF!+vZX zbJ3(3jCg56dfM;CSRmC&<-E?K(*AuGk#^gm0VsxI0M)!f{vi#JyVsq!$P`dl&2*8O z(C!PF{HEe#0m5%Zm$ziLNz9Y)9}Lak|nk=BE#$uX?@^kbu94J4|8N z1Ce-7`S*!rpk8j~@_=z4)A0dOv^@{fWaO@c^T|}d%ZU3|?T(T1e68|6k4g!cJW;qP z9*7F80*g*66sh$W-r7r&J@x`)7zqN}Tl0oJc}FOAR)(4JR>TS2U$88gg8>?;-W=`N zXpVSfr~HDQ*vlTcCdXAWYkW=vPx(%x%3bLE(#%;q0!j6r0?4T@ooXs!9%&?QbMRE` z()2)m46OJPox=f4fILu7yUKZ>22>;8&6`XKm>BCYgvLbtlU2k!39&^vP6`S=tiDv--k4P$`5WhMfzu1~#wwRk+{!Gv8ylwb! zXpIT3U?LyiM(ewcp#(Kl<3N+5O7RXyUj0(R_Y75K=p zxEncc6+}q=fS!PXAn;KU5qKyrFFAh>cp3J57=FV^1P4PI!viDSU!d0Y?tGSnRO z*s@_4biXJ!AAFGbwe8jP$iGYrG}cYFjCm?MZwAZ5u{@4GRc+{~VdXJ^pH)%-ge>^Y zo|#WK#4_=!&R;(NPa|E_W@Tx|6QhXHtCH&K{M%nM{!g?TcimZ)F4(P>- z>h1#HVuS6*viNy~GJF3_Vv2(t6~!lV4mWkKfHmf&%|o7=9q6XMTa|!>oLnIW_<%N} zc8n_1gO$6PxXtY-pDiY-f1^@h8_uiZxUsmLAx0_%Voik$v_l-8Uce4Qj3p}w_uX^7 z`7dmfHNg|1FY=CZQo8yNEA)SAIv=2jGpY>_0gvP8O!Q^+`xVj~7H#P!#IOOb1ewH3 zl-#PZ&j>s2S-Yz4Z*uDcgCT<%ta7rPJC=r5bf~eQv!BOge*GY| zA4NYE19(49%W3BYn&d{G@r@?NnVy`K>*BV3A@FV6*z|CSJM6U{Ar-`8^S{|h^?#of zc^o5r62L#&sGr-k$#O<>^Cf~v9cS+M?xNb%8;);A|3;OvkV9X*cZ=zD`t3llTaX#6p|ba8B&<8A8<;7 z#j9yoaxi!}T=!lgYwfOkIS{@8?Z~d-dZ+*Dk};vvshpxUwkun^9V@bo%m=x$^UiI@14jqiGEe6@getbWD@g9y_25mJYQtT*o11`^z=T= zm+FaNH|{|9wkUuO?(tW>e0wT!0pJ z4DDRc+%lA8nxR#EehTdH9Su^9P+F;SgLJDCTiYrf&|{y%lLN&iB|buQ*H|;by1AIJ zyYc76?cd^z3(-Yun~9`;Fhj>{w@(CDbE5N?z0fo|Y8VAlNxr`@W;$QEAyC-lgNAxjX6( z^gMjiQml6T>SoTYj5T%0u(@y9yJ{!;)TX*tPt@7T1NI--nqTvz@xT67)gO~@XNolp zZs$XWFQL!YSI6T+HK`(;`$t7;^}U)8BB3me`VK%+&x+sr8MYO|7|mhn%xqc>&1W`y zuM7MzMm~IIwpwZ=8GJ}4RwsCp=AVIS`B7zLoTP~^3+CiT(Z^5Ic3So7hlSwg>;{j6 z{a(+bZy3~^WG|kE&i*TDNB>)#R-IC`uz-zffF6}%-Eh&>!pZQ=DUV;prJ}~s&%X7c zf8jwjuV`PfoNYydD#GmCbHhia_whm5zS{8nULkHB^#Hxj{ER z?^;|kDY#BtOxRGQ-_V~PN%GnwpuVTVvXhddTtT{582y{gMUWBqa8i)*n;*u%@7sn? zWck<2j(0E%QS*Px9;pZ8%`&dnhm#sq0kPioSS`)oAy&9}*tx5P0gb^vx8_#%fLpph z3w)JJ*qR@831@c-s(e`ty`B$*oAAFA&;J>wlBtG-7mai_L_(~xD`1P}g07}lb>T;3 z*2h}I`=PRl!3gI&gk+B-hx^Bd=rAmkhmRTzhyGl_*=tl33k&T+jVm{~Iw~}KkIAU2 zl+o=VpS>DWZQ!rdJT-{Mpa&Y)7_O_=_3)I6-a0Sg_uUsn<7wJG#UcItFY5AVeUsqi z?gBm^?fQTcYD+R9ecDtxzyK?BDA`?m#V4}?3fLQOeO{nnn1*7%vN%_*! zr=we(Bo1P>#w~!_3$_Qu zmeAR;9i2nSCZy<+Ets?niEIOt>?$NYlwPJB?TeH%P|2(IQ@ohcAK#w!S43?|+WzJ9 zz!8`l?kWzfiwf4kem>F+LdYN?H>2x=u6YV<%k%1SJdgPna!YQ48h6(FVdPRrj4S)k zf(l5dl3-;(fB7Q}Uh|ZOAQ>h8!WN+>KgUg!p<=6ybvYtCB2R-kxCv z9cGvrWenK4ay-meKm^AvhPizX)Aj85*#;iWSMgzg5mzl|zoU?*=7MtMLn=9v#--w+y>+P*`4Wi=~N_` z_e3k6U(#9FmxKMU4vz%PgjpHMhMWBG`XzQ=c@8!WS5BD=n#t#6XR;iEfqlwnpN zX2?Mhj7Nfhgiu+m7+R_s4~leaH1Lo&3pl=PjnkCbev^jij=$epJ8s_U?pBSQ^{syH zY9}S7?U4TVph57)g4q|59&%NvI8C!@AUzpLTjdgZLO=PJJvVYZR<2k!>r5l95|jml zCYoeuR6E_W_l4*|>kf5~?m5FyB}N90hDu=kR`(>Kzd-K>TaM4{pYx8S5q z=;T##E`ac8gT z;J*X?{R^Xi#(WXnIr`gyuvgC;&N+iT9;Cj&R0{MLf|K;4lZbBO%BazRtFLlIk+{uu ziFrFkW@lAKk#PaH+y&}Z(D11Q*OW`9czc9QN5Jvqe%u z{B>UeJ5&@ej^mzK(~EO|tpANPS*Z#=e;C(i;sDpQSS@xl61V0=Z!LTko}-tU-b3K2 z^vbShR=T|)ZVwK)oWw48#SA%Nd!om_de}rV_z5(3b@70}foQG2(%I+$rZJEf1Tu*c zdXqh?2aZ7vGqLtb-vAdbpZ5m^0RDJ6D9_UJ2z~24!0P$v$VX{+m8a$!rq%C2;Xq zK%NU7yD?9sRFQ+k#9L5~UGO*F)OQVUwG=vlmEBnh(9a2GJ=l#xhV+kn_o7+0;Z9}j ze>r3#RB1$Q+JT8ZjhfTOmWCSp;!5dPT`%G4f1lKgnfHON%_sjYme_1G-$Qm_k*B#8 z@E-`<+7=VT?)iEWdD+W9KqU_o--NWUDd(UGsc;KoHVChw`@oYMBmnh+L|d*~*k9L+ zHmdOx;~&kHoWAKcKpnfhG}*~!+9K3Xq4}@I1ZLJ;LYudPealnjejC2s*^mW<7^8GS zaSCpps5rKS29#6I%V8S3Apk2bv6g?u8(6#d{~2YuF?91M<@nQxJ)m5poG-&W$(20I zA53X2W4IlWTs@PIC_B1q`i)NsgXQoEhwtghY$sFCjK`+pl33eGCsy8I$Yko*iO<1} zH8~-*7Qr0sJp#R8$qYzh%co*P)!5-%17U^gKylFLVX;2tf0>F&Ndbj5+S%o*h5a2X zQke)47a(WOG_$(M=8E8AfVTH~OliJ9@?8m_z+<8k^=SP4P06_(Sc*MBF?iS9&(cZG z#D_QDg=QiNmJS%vDWveEWqbcU#@FwDCk}5gHHwc8;1Y7ZlzZ!Rvq2NQA=Q4&SGZIJ zeZCI+V0!%hLkVA*cue5}KVmSkuh^^^n!o>#H5S6Ux|tJ;9&RLf*8X*t_&=|0AyT+K-@ar-eRI?y zK$JwJ77FZZXf#*7Hf-W>e5$Lm8bRmPBo@Tp8t)`wds`opeQNK#7T^#KogslkzLgrq zXGBbVx=8k-<8zfhx836hh(-39*$^=64muPDydSJU>^}VF>+>+; zZM&uK=YgjHx&w3$>+cvsi21Fd$eAk%-t%^_jY*c!2{NFjoVo0p=1mq}FmsXGd+?Qj zyd_b@fCK#2*nA=sC+mOW%nqy7@Mf+k^5Xpax`(_k(wDMTK>2cXtC^HQwAI*BGXZ6U zQt(L4OlOJ2E_t5KOh@`B#4_$oG5kDTag6g*pNTdI%jm%TI|prh^fio4g$#zB&?g(W zE9|&_0F$f*B(J?WFdwNGD>%k+7{7m;SInHg!%)KCMu&M5VEB5*A+9=^)LxgA^1;=H zvkMlk^1p+Af_BCC0{F~pcE~{Q+F$+-#7eAn`PAiWmBb~z^Gen7!tSk@P`-}xX^OX5 zSg>)0M1ibL$lI|anIWPvRnVIT?QOG<;PEE*?-o`=VHy2l5+g};krPk18=cBWs3AI6 z>vKRuq$##<8&3sD&4@M$$b_iTuYV%LkEV?504RZ9#ivy`QMg{P78B`WxWODRTdNvWMh0? zo`4Y-+&DD+?=Quj3DjLdr88n^V7wtgurLi3{f)m5I_8b1$5H3wwN3Ef+CpNxf8Q}j$| z@~nX>kLlIc0o$ zvn5KQ?s7FH@5XLz#=T)8%l6|VdvOlFxmdoOGrL&6Cf3Xq@dG*B0Zi%OeYc0P*+>8J zf!zll?7)}r5#7E4-&mF4{-0#DXSFA79c*7V!rTNjyKyZh#-afsEH(#J&tQJFp@baE&cKH@;GV=}Bz+bW~cK%R%Fde-S(URX8vI8VFt<&o(f7oOMl z?L5x=&$_@c(dN}Q%A8?BO=E+JvJD6T4Qq)Da0m^Y>vvtbm|?Ez8|)g5uQb#!E^Q1w zEy287RsMghx&YXfY$16tPjy-{$gyK|k`!;k_SLviEaFgRLV*l|i_&SsN@ZqG0rww} zzOjJ_{`PrT3Wpl`3K>3s6^o|*6|*??FG(k>q*!@YflwG$4a9sI` zLdGM0|My~x#w<1FX5IkbOCPLT@-&%{|MEPSx0`k20%EaKhVzcOJN9W{`7aqsrT^d5 znrMOz`2h7<-THL^=bJ=f2b4J6y%KatB73tF7BNcKb7d|hUQW_Q0nYSxeUSh82;c0^ zMJO+T$dCMqCFmu7_lM_(u3~i~)aR3G`Mx;;-{)NnD^!#8;7KpsG#+hu%S_eXK=gG+ z>W|}Hf_jY70`G6U4)L?*huNR)Lu(v4Vbu5%X#Hz&bXdN)87QIkWvOZZAn^LXxOxk> zsM;@VbPtUn-7T#k-HkNT2qGZe-5mo;w{(LbT?0sWcXu~KgLI#Hf8Temb6w{@m}mCd z&)Rpab?c&^E#X(TTuARAdu=Pf-gqZ09)HS~V@8E^aC9Un9l7_hvUkl8+iX0wBS-K1 zZQ55lIM~2#oUH)uj}TZ)(K1c)^nL^~xXBOi8)7hfhb6k3S=U5`4`Bt%?#|KIV;xDG zGeyW2HV1!vpUAvS-wsW`(fTwiowfaNahz80k(^*}9~vIzhrk>TzMB3bd!~*LrDQq` z=D3VR{yLxV2qZ}6bU_n!3G6-!@S=k!h=46T@VJjPT-@T*vx3`zgP(^LqX6`mo!v+un*GlTT5>oz@RvSvq)S%I zW4SlssCR5_Ue2GB`$`1uA{5>2Bc76?_;6`(vdN--+x=KD;>TH)>FUK@oKCboL99Dp zaIj61)Lebrh7CP4#mO>*EbBVC5PNWJRM7_mS4rmM?(aNZgLekIT|5tLJGmqXkfbiA zYpoHi?M*M6hIgs*sM>RKGylZj_0|469r^T zO37H*0fTTWe(#}UAp`4A;@^#{=_DG;qI|l8Ybw~`a*ps@xL^>Y(;9Y2au+#X^Y|Mh zuFesrlOg}m#A?QQ4zNcGnOB}K?7FzcNLgQnIMKiokVYtkqW|2!weo1e7bkh_1*`GS zt@0RoI|J+JE0|qL)k8Z93LS>m&FPy_W%kjx!BdER=$%qI+siu}Wz7*E867;~IAJ6* zN4DBxy`f4NU)Q};?Vo+?TgiEvWn+iQDaI&;-s6DHyDNVo{J*!iedr3c@z8`U9iILq z|2y8v>JRW8{J=zsQ`3^iY2=aR@~Gt6dP~#niFUr_4^k4qg7;nN6z6|O#6Spxu+wZ2m3Zg=9Omha_jIaZB4b1_;$y^P=!4=YUbLF9h=_2@U%R_ z@C)Vs(6)uEyC13xEm@h^#xZYu`@h%=N@^z4edED3;en( zMadA)c;Y(Z)l<_s=`N$J5ylzgZrjlyNa+}V`}KSZR<1~u|L5*pVJ@?fb+{q$RE?qU zu+&JLMR8El?{0J9v>b$|g>IqSeFPW_stMsDds3$VAgnGh{`D@rk4u`xzOshr)g#n- z{l^N#T%#JA-%>>WsBFW}7P)n*&Ez9Kf|T6=aGon)N`Rb$W8rK&=5L$7(GzTC;INnD z=Fl5lt1CL-1TAzZB#ZyGl}t)xzKdfJ;2R%}E6T}|Ii@Se_v&8S3TW6Rjp;2xK2t>1 zJOW&I^I9+ZUN6@3?5oLq6Pl0rZ5a5+EEgFMjm@X9IgMT^ z!u@<}GkuMgo^ph6(^C;n{&e0-TylL@^kS6rgLPh1iv;ile_5%_=XmxXrNe#Ar=d~n zKFm%g3UgWpB#(K5YmqV8{&a^jG5v4EOl-gMYA`_#=j2g=qk&RRHj&idfn^@KdWvFW zONniAwiWO_9O6>C606L4mh>sqOaCY{eSJ6vVu$dE=N8TOJ9BhR&)@_ysloAUhm zvzQ0T_d{p?SlLfc^Qtd4`d2vG^MhwzldKqyWw7<`lQ2#2FYKSFQA=)Qd4NNL<&kr- zva9HSZy6Uo(;KhT^Yw>ynT`~m{}Bg0>4@z}N9r+i7;P#1Qh9;vOw{urLh|tIi)nDI zlvoFW;g?JU4NL>R5dRg}@Gc6x?9s1IE!RiIpTAb|gN_`XG|N_-MWb78%*ec)%@crj z45#CdCs2jrV{1u|kb)k# zy}K55K;Ga*AtjF~b{EMhS+Q2V-{FiL`$H=|{yx}QKz%a?{${$?9Cb09_gO}A;}5(X zvQ~dk0V>!9=W{&B?Ac+hT@etnpV$5OR$5^otta^#&<7(moTIiicD@iY@})s>Te_h+ zXQYic9`<)BsTpVlq(+6_>Y+NaprNnp?q8Xw5Y0!ci(-`fu3%0}y-2n{&mq69oqlzz|BRwLCvvVsGP44qtfjDaQFO10qtREz+nYR0}0FxS^#Pk~y=Zw3z?i3~74e zCOpq$1+9+%t%nc&`F0F05U-*~Ru!NPdnfI}dh6DoWG{>pan|-x8`;1iv|%@svR~%) z39o`rCNHGU1=OJ)y2*$M^7=*VQ1%-@VM)f$Bz!kyf2aSFbwnb0%z%TCC$Em2vPz~1 zj67_%z+O;~wTi|aQUtM+6z#9v9t}xscmq`kpW59&!qMBpgzuU0^mGU-&LYYA!m5S!FPoj;5k9nEUUJHyd>Wzo{_-NZj8Q<$ zS>VE2*Bq(Q0q$+zl#U&oNm0Jrh6NdI^13*+P>F;D1g=$2FnYASjQp;22M{fPe?r7m zwopH!wZf+b+|EBVtUpzYA6_cxa+4G_jR*BIxxjP>pG;)+;p}W?82b>w$w7}#P z5l)i8eMJnTuA1AxT>sr4)^XFfSLz$j+r8A6~z{54VW#(MiH!Y6k?`xB4g3 zs}-J}Td}`y=tK3`Bfd6nO8mJfuAQQiRk~0mu|e6Y>Yn@IDYNHdXAGos44w+;Ib)(# z;p;PuhDBuheYf%2Xw&kYU#*&yQYEE~!mT_D9bfb1EHLytp^4|?SC2=SZ2i$a0td!N zr=qV*c3eW%yk=XSWp@ea?yb;rqih;|y?VCL`H2!qrMLf%>W&*YUlF%jIm@m;S$VEV zy8VwVk>#-qg;CxUs>v`z_`8WP+3*&UcTM*dq+qN(6zR`)Y}&?0M06j3F0NC$zo%=^ z*6k#%OX%}t+pabaDb||X&KGpiTWPYD3+W7EicjtHI6uG&3Q;nw9bB?TlV8TWFE74z z_v7s|dQuZ0p1P?m)Wg>rZ86(GXwM;{%@N5hW@Ag_$MBxU7yWnlkaclgD{a~8Dw5BY zh_ix(m5~pOn>Nq~k-Ob-G%vF{SCdj0V&!r5Fk#iAT>88YQrysuyAi z9zJUnw7bV#@ApL#6E9aHmDA|Vxx#XI=M$)TQ~4-E4Y+Y)A+=fYtBaEn4C=P36_w!DzmkL zRw?QEYOYEqs`wp;%(tOHXk!-R_ZD0Cg^9ly3nswA3C{tp#Lpr9lu!BIr3WYF^!gQm z*KI=4wE6i)w-yy_nUV&iG;Kcl!|1-3w#FHqo;b4K2YeVKbdn>QWO2x0P`0ML@V|2$ zF}7Ob{h$b%-BhBX@!lct`rebD_4q~UlT!f;&9@%tt&)dD`}$$P6M^H1+k&2WYZe%u z57qDC?%>J>+qt}rNGty0hdRV0QvLE%mh>P<=YEtH&IZ1+Q)uJ<4^z7Z<_CCH|GpGuB@Fh9aN#)O{ZLGvUO-Z71d?_C) z2daS-BDN;!ar3zpIKYD>O(2YPq(j&pcA-C=LEu>7-f?%P5VQ{h(*ud}ro`UP{L24* za|w|<6Z>R_|Aa@;aPiZ6r}kunTs0A{R2QCD4>ruzf<|^r%0+I_wxl$*&Oa|2Pu6+8 z55tya11<$Gx^y6qgM>7p=UU>?qP=T)fk?}xAQkCoElPwI`K=pf^bw*RX9h(ie>o1f z`r1IQDz+S~oKDJAV^k%({05x$RK#^BfxtmP^sxbNl7`gIPf{gS)qA%u$Bz{zA2`CKPU1#w>k=Qx6^Qmc0W3K%F}n(zH|o^jv&cO3m+8r zeqfCj7&w@|CXpEVdho;ap3xIx9`1VM_ABjV+AW zsA>4WNVx1s20QXYqJlJ72PL{koh@5kQZ1tcyRpj2mATdLv#$629OIe;xq#@FL5Oni z8bfyUX8l?O4+npJvZJe^}RpScrC}r(>0PKN7rxRoq71+>G3nX#AOlMp*+G3or<|j03W^LC9U^kXC`l(%ZJWIoW@%_qlyOQ)Np@Vk$@QY|O92>pBKzHpB z5Gkjq90>3FX+Ei=LQ~ks{c6Qa7zy*u7Ycr*gP~;Oapmkt5Ye_8b4RAw3K=%V`zDFH zUQg~K6b?G9G7Q-PIA<+~ORy4oPEcqk7q*XOd|-L$*nId_>}2hSOn z>N+8>$b}ZO*GASrWk;QN_`;enveCZii%<#7vJ9LGkq9oK+SkMin5960j>D=&0+ojF zqwose_XVj+gWdlo_6}x#q4Sd1%&5}?`#uu7uwotIWXmWN1fYhGQXqX7G7 zg$;@L@lRImG~iCE^>Vkqxc)LbLaczX|BFKDI?Tyf?0|(U67o)5z_jF!z{NK(5~IDE zjaD^O0a-wREDQA0Qr9qedD3&$36^^!`s}(h|8bg+YdxOcoS8lGZ8#am$$?SPg z223!G!bf$?MI42G#5O75>$ibxME~t-KMBo!KhNVHO9m=TN$F~pwuUU~HGxJjmTWkJ z-ZN9@GekN57MDI(W5ITANo}G|r|{>~_Qq;5%%QRO!>W8fFP!A%A%7+kdw^&%{o6D2 z3DcNjB(LbauMO*yn0#;-VnkpnP1EeTd?@V&qB)^cRkLUzz zcA0cSp(!2u74iYuUTuQGpQlw3pOStFn|5dW3p>%i+MK*Q8lDK_dwMzouP>|eIetI_ zW%V}wt?e3fpq{f(MY0$u4ZOztN+LOjgJoj`|FP-eagih7E0)6V@)P*0tCTVL33|f; z2pkhYOK94I`jnWe? zw=agG$^1)!o&s3&J)b}w1RdQ3Z@P@4Z5`uG7uOQ1v*sPFnDq{|>pD(_z$BvIvI}q~F`WW$(gRcYgqHuQ4&;mfQyo6r*|EI` zsi4?6ltr$aP(katUB4+jHJXINR7CAG%U;UeyEU8P>BFUSXC0sIw~!}@_ivA3B$d#z zaTr;BH}csLFH_&pgX_)Rxhs4Qd1%|*SrL_;8+8+bfdhWmu)NLJZ+zxH%r-a{y|+qi zW17qHVQJu;s9-4qwx2}%g2QP~h#*n;)dK!GHn4EBorcZBl7!=Exw|A&U&uo$gt7hB z@7VJsib&AqrzEoR&*NER?1uq3gVgHA1qN_7`WHyu$SuA1fSR?b@QevKy02H~KU0SO z{}{@LU+KH-u^F{co-LhMo|neXVwPdmj0Dxx0T+^qv~6F~Ma2^EB0_YR`GWmwouCo- z;M+GkbH=+pv%64O=DVj%%T0WCFGrOnKb7T!*H>Bng!@dtkK~~h1wLtASVjS~#^H!s ztDhBgmj)qkxz&|Zi73IeO!%Sr{eq~F^sG*xYrpO$D?$5}R+Y3Hiln2-5+V5V&^+ls z?K(LZ&}obmaVq1@`2F4_WAXEWyhBTb^I`!7^(TcY6^U2#-|(H|>SjiKXZI}Q_Xx(M zutqe4O?aaGUs(?Q2mZwMooY518cfkB0rB2pS|fq`eO^~M-Qf6HEYI=^LpAtJunhJO z1_zvq>zi0U7sZt;^L)s93-(vSl=bsLzWWuli>H`Z_6Jbv>`CTi^mPM%+|1AXhFM2i zF#bmTNvfD3S)V3|I3kmr{qyfHQu??_X^s3K1FIrE&!*O@0HhLRW*k!^rypaZ+k2Bp9PdoAJ{Y}3xpmdde;Jfx6We#9}Wv< z^lHz_{Ikv$vm&XpykFv<%|(|q6lr8hazyX`cg&{$draq~K0T}v`YK!@e4M~bi%1Kt z@6DhN&1dMjF*W<=@}7i$r$l73ci ztl1}P{t)-b{DX&c<7k4*nS2wW(8iu&k8|M~KF<-!flTzbXnwoq(b6W)6;*|WM5;re zEk2PNjB91K){44hLBC&o6KzrGwH*9-)-!mox0LW)@$cev;d&*)@n4?uZ)DLfmYWl) zE4zIQv!uA!H$H>VU(wm@>pKpaR7&xxdj!)k@(N1*pARZW;(ubT@8T$1(Q&rH?*q^e zxRLjb834&Q4iHgF1(_Trvcbh#QRKUxQOiiw-t@{SI!xOL{CeFO$6Q`|H(#uN|7Y!l zwR^@P^WZ!*>BP&Fh6HH-%8#+C&*wi>>2Kr^g1Yv&KBm%T=O~TigEgwSdcR2A&QE+D zs@46;^*3h8aM;7DKGw=AW8TnDU$>cu2Yam!g~_EN22L7xS~cL}BsYH#5+fQWv}yYT za1^AnlNRY-HfgRoyytU5O4e>tbjlG_O41(ws25_53y=pzH2+SbUc96Fg zsyEe}-n52yqwVD!S{EMku#b;zdvtg=QHc8E@cBb+CnIKD(I>oMA=Vg=O!x_fDgz@J zRL3R=jOhpoj=709d!v%MbBS;aabJB{aDgoWZsv|S$z&RrCO*0hn_r8h$v%z#cPDF< zD_o`EJdD-c&rWJP$go zCOftf`(>Q9By@=uz~+uHm~bXKTT6+}c#^`aUh=Wi~f`dJ|#+OJTyK{cis)jdYj zuLlSwCh1)c#nHJz_0n=FUtv$-ZCb#$qbmJD68zNu23{pc@=WXbo>9yd%80WTTc66-iQ9L*G!JUm$#pr3Kkq$B(>PTu`PETTAOPFG)l)nu zE%4gO46M&51FaoT7j(HZh3L8h9uO}WupumE@PFhBcAHJT3iop@Yvw4YRwzTG*G!0d zSCGV}`(c1WEwdEHBhSTuT6BfbB^z@tSE&GK`nBNivQ4DHiT8gBOjgx04^*&X(m zPc3+eHUDY?L^byX{U+yvuWGVaq+Erqc1fDYQbM?(r zOMePerSt3`_6K!o`+ zs=u-0LvwOSS4U|5um90_UR0EvVa=CS)6q8KB`_FP*SoMnj$0*uVUU<5+VMs;blPkj0jbOeMO@~yf6Wlo=kh0c{6netTl6bFkhQ$2Um!{j zBUAlSDIU9TXE*C3wY2i_{+u$_pjvQw#Ev)O=NM8%bzv}Rc_**Ash4>ZXyR1b!9#T_+m=jta7uH^FUGl!Ia|ej&`Oorw=;MhL^DC@iHTKi?`#Pg=ExVR%xCZA33E{3hu7J_(XKixS~l)MAABrk8apL60;ak(oFiE>?FL8n z9WO&a6Q{My(!wn$sbJpYj%?YcyJu|4n~9tcJ@1IgDS+t;kvL-uS=I4{V2be>P2A&B z==(dOJ^H&wO^YCDY*#QoS%Dz%WiXQe_ONPF$nscuEWvnY8)mafhlpXW)eCDQ%jSgt zy}xQc>*<_d3rEe!Tpo{J z$f`?07pHQ;ej1Uy)PUQ#-}`aG@9yZwwU>F8$q>~zl_L1oY4Wb^;?Qx-*Z>PL5_#u2dv69^5^EJf!saM5W{ zfCJg+&f!GwVhp<-k;q+n=jN4OXlI(t3{u#cCH|Em@b)_{V-L?xCFU68LQxnd<)Q(R z%p=|&?wR@T!R!T57MRLkUL3x*JeD#T8=b8YbqqF+Z>#;T;Z#3$w4)fP{WC-U-lzLJh&t4-vqTG@re>Le-CLkh|pGMrjp{^nb?g%OiH zmI}rKDFHPZ3qMO!gS2AZCaHcM`iz|2YiI?KmVM;j5b`Ghpt@?S4yPFcw+vCn+#O@{ z&g zW$%J#9eixr@xoDe;`vYJV4>V9eWrtchlB^l0>$Y<%8HJ~K@a+flFeZ-*PXsU7P9~S z7Z;UjSGq;HL&kk|?|Vz8sCxV)zAuv}_Zc`!pH2cQ2<zK?8OE|R=7i(#0CXtu*~!ktx3?_Gk|3groIG)vHIC>^r-55xN&ND4+qeBwa{ zKT_X-+s2a=cvG&My!9A?G`!jBlwvOW{?EL;Cyp~V@%B0?q?W1vj_K&jy>(3^sHZIg z>(B<19;fzNlhM&N0Z-k72$F4Trh0{<2!Hi1RM8CKWXiU*-D-r6zWAQ6^RQvLSnQ&f zVi!v)cT=sYRgurey;M68vO}~2`_#tyvbsbhj3Yy)&eM;0;hPRVy}-yucF?lK-+l#~ z&~NA&-vV6IdQU#UDbXrr+z1GNyAsQKe*%762yjPP>4qmKv{ zmz7a@Otq%?gG3ArgjBKn_*NY;7uUwGaA1?BJJsi#fgFzL;UUXN6!rX2eP7mZ5wBds zI~hmtY8Vus56Upw?ySCGQYc6b3xZg`X{N)EJ$~3QGy3rjV4-6&_?0R{WU2xGenRK9w`gj$u2cDxW%epBQ)a2S z%x?S07Wq4S{JfRihVAJ(nnrrQciQ9{W3yYw;Z9S)SyN6QDoL0+mky7*4@(W6p`@M zCZ@xQ8N*L%$?LdFw>w4rHbCF{hIIDb&7ACN+cWEiu$Ur`Y$`&2r8%=BG}PJa;_6T| zvL>z6yk*#bDT-3=8+fGbi%VXMJW#%ohAHYzCe=m2*y^qx@+t$wY)%-lW^{pkx+EljQvcv~dF{LhESsSt^j*V%Ox`OUmu zM(6ymt$#JhF+D_dC}v|BeGOkCDmqWKYOU!0pnAQ3YK!!o$Mg&!hiS8GJA3Ls7hKrd zouP`jfPkj{rjsd;)PGekbYdpaWdICXsH^%)#MblG9Oan!mI93{rp&7PG;-8J6)P&2%U5=d^?vU}YYQ zc~^(8rP)jaTZVztJ!zSimND@y*`(00YaRP&4R^b!r@u#P0q09$xR4kGxR5m;R;#z`OwMkK}<^(HHY{OOWH8W61%RsZtB0&nAUa{nZg zJ*_`z9w#!RubvpC%A+wOl$U)PGfjCM4S^3adYVxgQBtHwEuWaiCWrTh_^du?`Ccl< zweKwrbl$i!Sq1$3V!cAR!lu2gGawn4Z^U}Yq+5XkB#3xV&xPVKvV%%Qra)AQr8R7A zem<>-`GnaI&~3h+9b#(1fx7@-p>HY)@psi72)|;#rsUvroU@p-&0#k$`adeh>9h*< z@!9E^^FBHnZ}iil)KO7vKMs*y_6^rMqXLbDcp)5siMJ8>D=#20JC+%&>k5~=4&=ro zIEIS;GXIt%z~^e^c`kOIhsTQ>N{bNM5puA8Q8A_^_p`qM`7E-|)f#GjWki$bcr|El z^eT8JR=Ld3XuFK);2e7uh>iF#&b0vB4aY?wSn<0}unV63N zGFW%FjqQ(b*5hy4S*}@T8M!)#U!XJX_IGvb{`z=lR4q{)N!JHqw1H=f7usa>rJs*b zj9ASN5U>RJBd)znCBk>ADSU4eu$**DUs-%Cb;BxQ752ev3_qZzAA#lom-*vjH#6r} zsI=Wi8q|I`P*YXkV#h9TyaX#6qAU{DTG>L;57QV4P(pfFQUzo!Mid`R;H+P({~j6b z!sbb${{d1%2t@qq;&7##H#3u;TreN&u`afKwsG30cEbU&Yi`?>yBY;Jh7=LCCg%J= zuJ~!Z_zG+y|JX9B@xC@fy->TuHn+=}f)~xEK{Rk-Q!cS&u{wBF5*g9Ot~rw<2veQI z!FnV&mX&?WjMQ!$fxmABv`JwG_1!b$4WLd&poQ6uHrmCmM6>He0#1%S< zw=wc+=Q&+`lk;hxYRG|sX?#N8MF9?OTFBCZZ_qJ14^3A&H;0>#zrI{A@^A8x9dueL zj`wUd`-R%eqv$G6@Nla$3ErXvin?!bv8ojycsF*D-C6Yo2~bZnUsBo8)qGMRasBK1 zCNG*S;;J_iU!vFLBx?2tov5O zKPr??*!;bbz6qr->;k2GjM=#~(=Q%hId;qc^^&y*t0Z7?yFU+;mg%2^m3hUSnB3q{ z=pjR2eW3SbiS6<>J-U1^slD1CW$Gm(7kn>V33sw|fX_eusRFwvy%gVZW~5Q%d03%V zK>0Vz!uN_msGtyzL}d#J<;zwwd*fq#15#$UJlaO=_GlT^gGa6j_+;NGA?)8IpYk~A3ZUQ+YZvWe{lWxvjHJZ622ax% zYeWrZjgsx5I7=CWanb6=9ytg!q9{B+EtmL+1}%65vy*}Y?C;0wRm4&JLM!>Olv`Rk z^XF4q|Z6S0shhPiZ;t}R(K&< zcojrW<{v1nn^e$Be`LF!?zw17gp9@s+v8c(dhlT=GhUM%CBjR;Z|ku4a&30lus23s-2)qKqrruG5$GI_ZAaIQb(vp zd*tS4yQNM8Mh+&a%wga<_w%bo%u|)5&XsVPLsmRnT0FYJ8o!);=V)vA$C{{LqPl+^ga$6rNg*b+$@zxUsbi{*@u*308=mHAR_oM|Ui)vyo%& z+<@GVolN?5yUNAsQKp9)j|&lIA1?%etoaDGEArQPLK+0Yc1o`;95$u+cs7O^=0Hcd zR_ub%MzI7pfjmRzrtKgpc(ksUE(()|foo8H-@vZ`l5Nt>)=#oe=2=po+UIxjj&lvHWR9|wNwwY zF~88w7AgDHgP^nipXzSL8ka##T!_vc+2O7IGWwxMIZW!{OlQkB4?&DkjWNtW>~dQ`F=xy zYf5>5RsPV9oYKZ~8aL!$ScuU*u6_g$j&|L7LP=?+X$=2>fmis&ptx$8)34$~Rp!gw z!OdSNK7TpIh!fmv4f4gqDt_JrNNz}!GwUN=587Dnf>?yh2L6Yy80yHzaEN!Vuw2z) z$_0v`qdABubEI}FvYyXJk;iMaNlpRr8-f5_v=4rM+Um=yIY%+6A%Enm)Rw&bc!Mvx z24|3_XRiNneU>F7U@{K0&ApY0VE$2;W;bO2JiHqFiw^2v02LhL-uYSuwm@ zx!D*UZRK`bc(JM89&N0}vuq&v8CX@4JjDR845ONZ`(!UXxW^WBq>xg^WSh0Wt@cWy z4~B4^44)F#n(Ti@-qU8$LLQKyV()MU*sgI4A(ip+-Rc~DmWT^u9AXr*&Q~G4FKfyA z(LVr#m-t&_ZeXFaPLrs*Z^-4x`K9G7J{fI)OPX2NvH4RIY=LKU+v{1L@$$(Xyc2cF zj$ur){Y3ks?l#OA!XgOR5Q!ZJ^gSMDT{iY8_V1*CR&H8jM?vAba5W_~>)8u_%Fm(W)Pb3|a|Td5Z=a3UgO z=x5miv%POpYP4_wJ@4OZJaELHk654eWKq5#n2%&a0_A4LTpWiO1NjuMN9CQ+*57~; z8E=^t9IST35x@~I=zyg7G9acCdll63AOaE9i>K(}rvgyGehk3x?S`~fgRA;zPtzWBtthjeA?`u)^5)WyGuS_^^#5E%6MqC zUg!DKTS5_%ylw)>Yt=Z7la`1N2?gZ9IcDsWardY@6QtznnjHlf_G2l%WML|U9a}lI zdFmV#3q`oSZr`@>%DS(#WB1UAK4tTZWCxmB=Xd8K$hS?dyfj8TaRf_#JQMssjn<<)H*CiA^4? zp$AQ0KtjjH&%ETKlm^imm{m5++@ILsJhWrr!AfS&(=(!VY?C8g@e*J8qQ?#yPe|y> zH3QD;NZVdyncH6kQr4%gHmVc$1lzq>=x>jscEP5sMj3UsO23#}t5bJ^d)-k38+pM_ zyfq8&*_4;)0WZmyb+Ut#a$0Z_aLmv3FX4Q0yM-HB5LR z1<=FIDkUwTaM1y^j~cirW&}uZEM@9I;HDO`Ua`40H+9{|ul~g3K+a`RpU2nY``;K7 zo=Mjf_HDm+hd^RyEc8DBi-*fOejxV678h`D!3_aAQ~?M4IV0j602*~Xo*@=4HK*+= zhG#*aLK`32QHmGvDg-Y^eKqaY|FN<2e2@;5qyLaSj}Fv?rGAbP@ZGA|QsJ}z(qyN0 z4v(;W3H33V5|T90;RjcZ(F#OY*hF&O_%7Q;zV-iS;8LcQc2)8>E{yN$Y8dhw#QWRf zpNoxbS>>lW{KF>>0sbD#-fWN$!ry`|>o_a-1Ot??&Kkvuj~sr8b5~T`&YCR0^79k~ z@RT;tt-#yx>E6IIp=yAa z{v(wKdW2X1VHD(s^_7ENOaLcY0jT=kdfIzf$vVIK6$udFfQ#Z4<}`Jp0OHZ;0KVrT zK}SB&#v>{)c`i;wg3jj6K^kU&O}2?ns6*c;1iTE+8+jUmO@anVKgX`lz!|tn`*o)8 zD2x`-1142w`>Ar_B%Qq5R!CyKB;GX$=~n%Uw5UO*-}tDhdjq+=$O>*wm~HI&+Y*^V z&ly)*!jKU$v*Wuj7SSqu29_yhhBtGe)Eowgrwoir#^G{2z3{_aX0{4RELU#iPqH#g zIQzB1ArCr~25*584w_5E^$m=utS|v8dPT&@@6HN!Ze*3_7R#0kL$$$?Q9ZxcTm@gU z>Lm@kONzRQLiGJ3P-4Cso85M5_58hZQW{Ei_M;zx-K8mOU18}vBeBb*|?VMG3{s;D&KcMaUwP3 z!s7ukujiC`=HoJuvhQn|pqwm_28B)Cf@IZA@-BupE-=+z$_oO&p7H{W@HT}!k)s>D zgn9jZBkdlIpMcoYojtc=iK#w+G{6vBa4nif^sdkospy|>92b1Y6_+~}Ao`O!I)_7; zkOtW3`9MSkG>`x`?|A-(i~homdc5bQ>GTGvT-uXp>M17VP{pRu;g$zse&q(7MqMAt zZsy@+*)i3Um=-0;&r1yxg@1StI6Xbh3Hj*bRji94VT~Xa{y$WGg;rg`w&mvF7Tn$4 zA-G#`CpZLm3$6!u2u^T!_n?R1?!khG;2zwXd*ACGqd%c`RjoB^?J2T5^H#=@FLhl6 zFJ*LQIA%Iv8tj=(2}*!Y%J$5UjMW{|5{Eb+H&Nka74)F*|A_*d^*WiF-FqioQX?fIa0KF8u7dt<-F1_7fBiX&P#flc5=c5cHo;p^Bh^Q8DlV;zuap{!q4o7|>+X>u1+} z9~WUGh++UOLwMg4`K7jYBOy7!79mi-+vhtkG)Lf*rl^$LpXOCr=lX*am?=Z^`IxS4 zy{Y3fmDCqD{Xh-s#eomFSK)YfXuucGFqexJPm$v-4atPcr%Y+19r8)JApmM$=ZDQ| zP|$(ut;92+J^hZzEZxz=kSW{oP=OW>bCVw!8E7AanxO|mw$}hiQv4J!POL^++B(;$ zH^kTYT>Adlgg>8d?D*DEsZ7{tR(BG4mq+~*y0>%V%AUCpUN9d^OUl644HwRO4#xlJ zUs)9=t#{9{lvJ8Ob(Q0hds%66zwxLhXFdn{rp^~hN(z^S(;TWU)I6@`A)D|jyY=w) z?VzWk^V_w;IKrMAISKLvV%oSDwq2AcuE&`NRN&zBfcPu>oHk_oo5DHZ{sli}UiU_F z0uoCUd_JGKD&gBc+{HV$%h7#z=lqAdvP^I^!~n8$Nq8&`ywlpgU8AU8XmI5QnRuj0 z5w$DkOyhhZLSdhTBG@{I+KPyRswAtqaAtx6;{^P1Ar^g_yqF_4a}DPI-C}8G|C}oz z27L1^_`8fFn1n=qz1sz@eS{A12?NO6@UT>Hf631-U24)30_OQwLJw9ZU|%T6JU~ur z2q8+AW1Ol?RbE#l?M?N-IjH7Ax5tdwk6NrUy=m*kC3-#S97QrHM2Lr;Izzng^8Znm zyqqPJzwb1#2@-Sshim>G9}0EE{|gQn1Hpt5zi^`h@pJl;LN9_9>kT*h39^Fmdo?+l z9)g_Mbm(lJ&lj={-x0DL4d@ijoJPkebH{6h&Z-EBGSF|GaL}v2Xt6@GcChSmTVBj? zsg=UP(}e@c*>&FO%>SNe?l&C+%wp>g&&#ZLT+SlC1gPnR_3bvunjLm4HY+FDdO*-4tn5*i8=KELd8U{It$o?S|{}TdI?`d&@1Go2%>3mv&|Iuf&!GPL8;@ zFk)|wSDF4*?Y{xB^HO9(`%h-w&VYRmJfsOihtTMQ#MTM*ekn5c)sEh#VIgF%_!#&7 zI%C55T#qOKU%%b=h{*0jq&`{r%a3wA+spr|OS%9V^cu)q59X{Wj*e1dgzY@)P{A#t zU@!MZ8~ZWld#Mxe9@Xxije{*kgN1yC5|i4}z!y(r=SV_0aTqnBFRiRopkyb{*t70O ziuLgKPWh8S2oK_U~;qP6ZPd0Y{-oo9{Zs)z$rv1CLIxL7qyL7=xIfc-ZOKiE4M(Y_J2?)!WRg$hG=J^eM7 zl#sr-uSs0bD%{g@4j1r;WpjBx?tq~8M|~LbpNtisFTir6={GwGA|rTP7-3Q&#Am;0 z2BDaxJ-fyk*V!qkR!+M6o<8944w{V|1Pxx#3&2-!Hf(HyfpGeB`hEZ^ksurlSV7)f z?se<JF@08mfCJWq0@CcRg{u9jP~aG_TW8L=utrfui5-RXksG zm4aX`tK9_}leQd%^ycD^6)PZ9msXqzyo0z{L@2+{jP(&lfG(4&n4%ape{{E(?j+@g z<15?ko7u!$X2Mqic+fhR+$jx}WXK$Q2{?d_ zvsDd2Le$34#dm(oQpyV#O7RbYSETmPc9f6Axla({Xpdh6w+hLbthhkUa{<{F0dYY( z6!_RJ$nEnr&G1xT^uD1bvcBzLPw~!e|iYQLS)UL(`VrU8Jh+1pPR^Z<~n$EyW+(;A`y(x zIV8|UtSTH!p>Ui6rO0bv{IV6uq~uxyY+i|pCx^hJJaN6!-8H;JkOqwS#Sny^v~Qj7 z+N_w?)bSa~cr4O~FT`&*RcddMbE#n4yjZl$wy72k0pY`_oUYNP1o-0Y>npu>YrXWE zcbvcvpbrv}L~$Sk*oB0^@?Y%vwcs~UenA*dhh%Dqw$V+EyY1oq;Ou?_=#3s4A_A!1 zh)40;Jo^X9tpZ~6-&zW|G9}@?uz?dXw$2Bq9z4T@4cTUNG+_z#wT14rQ;)aL?{-8N zjId%a4bSQ1`ZMr=g(AP$%-a00e=weE2?{dvHZzJMjlUi|t{_V-EI>Ow9{^&{ri_^i z8lBCcQn*5mWMgW@kZW+{fh%Apy4%L{9C-b_8F{6KX|{vb4%)02>C!JN9Rj|X+8{sv z{UU62wU802+!apG6f;In--oW>h%TtWqTGL?Sg$uwZ+fa*R%LTrv&-?GK+oYl#qJBo ztJ?g0<}mC2G%4l9ywexTbCo>3vu;&?OZj?B*?4!I6;Qh-MKED%?M30SN~ zzL%+x4L1uFLwMoWIDd$;&#P-oJ}z`hnq} z{{f{)G6p>WFcHZ~iEA42YqrIzqf2QOZmwc4v0jd9!lZ-4{k9k0wU>Av)3A>3lyfa4 za1;~ZHq`&oE0sLsu$dFk)X*7XFZeK#NlcE19%LP=S1?owF&Nkpgwe^C2sI2zzUJ9{ zfZKL39H}rjFW6cb(C^$?c{>gqAkY7SA}K|-qkldC5sY6sgX#f!ZC-AL(kUIu z#4&%cqE2YwJz|Pm8iIl1b9K}vuold>3di}riL#SS&^?KKpk_4vq+`s{@?F*&FJI-qsP46c(fgf85 z=t6>G59va=Z9L?9L#-q_WD9N-1XBuwC#cHPtp_V6zFalT8$e@#`NGzw> zck-XzKb8))w-K>X8G>1SE9i$|X3<+v*0;PA=Gtg2v%)yM(BHvMB*uztXE}JN zrAza@h}SPd#ib|Dn)sJYmlq|e31<+W+JW~?v-hyFb~fMFy&rb!v`Skch*txb-n_Bj zqQ#sFL2sT>mX(1gNqH?T;CsqF3%+=!0A!Q&H!Wb43Y7Der7p!TZ<|!@u#ew&ERFWE9N6Iq&wcPZA@A6sUvQMFIfSEv3 z`x|2T+{amYQ#*``g?xU$Fj-7?xP(tR?tVgA}O7z!NIv@>d z0^1V>nn%8v)|bVj?B8R5C{Aa~bn?pxnne}>ZAlZ1dNwKgG8 zeCueTjh%^~Ob#^()l$|ovQ0Vei;T*Oar)A`P)GEy*Z))+x*w1^6K-WHe@a6l3{Jw0 zRcXcnh4s+rgI`DHiXvZz%*Cue*qsBf{!1I~L^m3>{iq-Xj#^eKwqDY_?pv7@XZOP` zVpx15-T;4G@pRo5D34L6*j;4Sj!vC+1J7b?Fxu7_u-LyMqnmGX;2Bpk;bNPyy~aK= z@dYkdN{;u#QUSExJ(k64IYuzpUT4>%M19+mLj?^I#X zslf8A1N6z%6Vx0X)X4PT^>C84jktAdYKaMX%=XbD3ogs%Vdgj~GPD8MMzM zD%&GD!B6W(#d70psA3f;@H-cF2y?ahzTkAW#Z67#-kJE~3461jAj4RY!0ypn($1T< zWQp^8MZDY zs!&ywPY9}yZx+bbQJ4L0*G25TNUVHC2he6Kjmuu=!VUL5f>gb^)vUX_I`5+1Dk(2T zzYaE^OSL9U6QV+|pwG!f_j>t;mhWy4`UOEUmzvfI7!oA)3cG=!xN#is8kXey&41AL zzhjIqkDa#8+mM-~HK~R6T$AJStX`Cx1mVvBZQ*Ci=Hk#4CAu zrJZ3IO`)_)GlIkfD)3|TH6FTCPR|OamRoQk-9TLgR+64b$u<1S8kpvbgqfJQ>b4`KKU#t#VQYq16@=I8)*`G@x zxrO~5i=bZ>?A<+ev?J`GE-0{ow6ReP)uN7r#XN#5$8gywP^S*Z2ao@~c%h@VG?p{B z4Vt`RM~~FGqF|bcw+Wsf-3kEjQZv(gx(~t~wKzWhhFglQ5~$29Usv5tc=W9<<%vXXJ;sn z{r)M}q~O0O4psexu;sgv%kwdhyRA+lK{P&gf1rNyr$p@;`tHP$yNTqS zlX>MuQxk9me~anmHBsm^&j^k<)o4zGB}BLSqu^TgrHV!Qi%VChUmD!~!zv6UMws=z zHP}L-V_>$NcNT2uakT;yw2A|hfmyX30m?URtteP% zaR>OMeq!J*VHRPFvh5Vkg{bxW|GUAe*SDVMt3IVZaUeu?beYdwzL*hiIQpCQ?zWPeQS4JU4&@X*h)!{k7IG`|Q2Hel@7<@A!=qN5i&7Tak# z1Y3r$EgiD{ENF;e=q!jMW&VF%0m29_ysrOZj+7St^YPgxpS{QqCkA4(tXUGM#@v0A zrW2-OxLsmP*8k`Aev>?ANgbVQfxpPjAUgy)ylkSn^+dU{c_{U zbX^inCSX^9QfQ_yQG9P8{o<|_~Kq)dj4y1#>l%+2rmT46?z z9)m7Dk#LjA?v8PpGo^QzZQSJcpWpAJ+8`d~riRFnuemT)bY)h6#en@zY~9OW$%cd4 ztU_x!rFhQEDfot`{b?!p^MZrQiJhaLi-|)$3KnEy){oC}x}@Z^$H}_1>_x((7f>@R ztm3oPoSZuBLNChbZfYtk7l?|+2DpLt`eqK%5Io;c?^qh=9ZSz!61u*AFZ}eS8OM?r z^RKBV3{FDUQC+JV1* zzdqV5kNCnmh@Q1ZGk?&)(9(xXgCGY^Z<+8oBx3lirFpmc-ueFfSoq)0hXj@e>f@fz zERO!+&b;lJ7?gd|@y_-kHtSw*Fn{{hetJ1vSnuQi#|N&c@mz;E;P2k@%kL(RNQH4z z&W;J?yaG)cN6PkYYkm%*n3a53k(!BGTsip`bEqcfO3KTrf#zl;UdZ&3BS;A&-11Mv zmgW*{gx4+>u!&&m9k4gnzMU9hHYka<<%^JS`n}cqp*HV@Ib3udD+EM;>NE_QjpH-w zQ=N-8$V2*wSPf*T(xPNWC`-m0Xu{hO7}NSe4?S<_SWuZhi!_J_RB5wgWwPCJcYfP_ z*R4qSI2CMugt{;V@?FYmdb7}PMi0nw-Af*>OwsB$&ewoj}jALu`Z!~)ldBHT{$Wnl+s)Q$|6CCHLu1f8Dx72zm)wy1VZtyxj zJyGg94>EH(_`bCJhsjAAg@h_jcvQOL-@*}+=13B^H9mhq$>PGz(V2OWcC-d*?YH2{ zemzp4kewQN0zeNRd18M4&`q4L33FmOhD}lEU;*9_wa28}KOQ-1L^AIEMQY|Nmw2-w zd%2Q4J#Z00CWA*{=~HjswkyjQvB746CH2fg_3Gn)>Q>KirIF}rnc)%( zFkKm-xVs2^5htc5(SQRlD+i(haZ;-Mfvmve%IJ5f{Eq6_Wb-a+hV|FL+o>nHXs+(v zX+@P>rFux?A97X7DC(qdp?nX@B?5W$;w;=sTew&=I1@ zL#bU?5l$MvczC*A>_6RlLzt|T^ZKHFoj-u^-rtfzeI2(x z(L872Bct?iVl5*?hURUNNb>S)<&M7jZ_RNK`3WAxy7%4KzkXb;&=kRzwsr=WUv5Xp z^8@0>XPSe|=#0NHtb)b4V>*7PjK}^ioh%e>yuT#R`KZS)Raobgud`F>Ei(y73YI|+ zL%=tDt6P=j52-m8pHboyPyAgSt?54m2sz6pne8cnebzsRrJgh4GhR#XVpiW2ZIgM! z{Z>!zQDc8HbKCr$&OKL8sQ8tRDFxV<0!a}f0U6L>QSb3H5`NP|IXQ4Ini#9G|b zKL6YOD)TYdh+1HX5s~Sly>c~rydo@`u!Xt~drj+*NxV_f;;3us3tA#jmcRSc-Od4) z<^=C#CA_UI!XNJhPFnGt_-R@Gv!gy+0o%BBY3_Dbr(o{suLBuTiHzo-R*~{BCKAhj zIc{6Q{4iSvd3)$!7Lb^@!s0g`K?Q6Rwd%|)ZOB1j$Fd>;^2HI zVQ=G@!T39I{v2?E}FVN;QJy{9ot>Gv8@p`OQsv8`n zlm_@9#FN0rtkE`#^x*M)lf0|SjwM~&>K>Rd{|`9rvGdZc5-LZGx^!b=7{tk+Ow~+; zevTzKi%(GaTYhG3LiP33qf;8+WeOtOSpRvG<#9X0Az^r?s~^vKTYgHy$A5sWcz_CT zdW(tA)Af8ClHT74SQ_(BS)rsZ zO+Kf_Dk4m)>JmM}yX9g!}G&5i2+m_Y?Nzq!lI^e-+ui%JzeW~ZlYU}eQ}2st0;739>Fb>xIP*wQH>Xe za4E;17CKC?T?f8-`XM~Tb#2N(A)YS4KK-eAqo&}sS}z}R7`WqcM$(L|s-o(v@YBRK z(??m<^1^sVno^J_rg+kr6eXMLp)Pk39L2U_L*j$&g1bl>*74v?a6wogJeC~#KHj?4 zL-z9RSL(lugOXw#%aCWh^wW9cE~}C(PX~Tp2f|28-OeHWvB+VZp)#a-#?Zt+zDzYL zVv8784xaXYM#>$S!Tk3aJ6#t^8F;Hemf#@;ppO9Vm~hv6!qg)Fd?DA6uL* zZWss3q)fPme7Mrd7Om-Y>3)_%3J@#(Z){=Ic5X5)rY0^(?nbKzV=Ib^6Is1fBiPs?sss zhQl)2u6b@d;}l9c0vP9rQcjivxB_=7e#jLV&Dif#%M$jww%^Y4enUcl;#;EQg)u<} zslK~hdx@)(YVBV**Z0l#Ipj(IWGom%3U^4UucPC9WAa!%Cqj5C$Mv0x$+kh#eu{_-Ax38*f@U^{I{Q^Ch`UBuq1dV!`4jm*iKI8IiD1`F@0CvD+n6 zr|(s4oY4>4Q5(I_JKSo0VT4d?wxJ)^{MegF;022fD()JC8U>2B-Q(2|#NK4p;VGM; zT>Jb(-Y?xa!2ZqLuQQ8TAL*-FldIg90LJfVkdI)^GJJ5;1ICg1P%Ce2w*xvumD!TE z{#UO&mcU1bm{yE^UOvnDVbKP*x0rS*P9^~gxq@H;By$0E#LqoOdj}-8p8iVDT#8iIL6l_6%_RTSfu`*#q!)_6z^nPJ;MK18cp_2ge!drwS(z!NolYJ6cE#3aBB) z9v=!El}isMS`P`fJR!KJtELzyURpo(;Y3B8mfoK5DQGkx#WEqTzal(vPW&sk%P@6q zDpI}dX*6s^y^ZY1&c|e}ah=F7lQxTAFdlxV5ia;uM*ry?+`*MW$nRA5=q`$E!@z zOUy_LXY(>-CvNI z@+K81EpAe~y^K6pr`W$ATrzIk=#TjJjQi;C%NF2Z{QO6BqG&{%L`x{hD&1Lf2Zjg4 zZ~Cl?=WqNG-VNutjOM8it44J5v5aHvc0_;zkOW+{ghsLdvuQf;w5*%Bhh=c)nv_N) z3ypjqvHun>xt2Fzh-nUxdgKka=8tRl)K6-k_$QL@-~44cXud-K(cSwn0H>1M@;wOZ z7)&jk(va}YqG0ZlAYEN%f)r3M&{SglVhlr_RK38Vq^ba&jopMSz5T*)ZJDkX7pS_hlgrHf7ecP9(L{u!ii^T?yf1<2iU65`J77(tyJvf^A5isBv7asq zgJX`)3&zl4t3jn>7h-~Ln4e(*r2^KC%*^`LIq6o@P35(EUp!%;aw1FK4|_t)GA5Vyr;OP6%clzs*2WV@M4+7Wwo&r$ zRkcd1EbeseNf3sVXu0{oVDU=V<>} zp-iH=SWGU|=R{CnF74FY?73`!)0FE|=vUmAZmhVGhs!1pE6F>CXEzwc}!+F?k8qxs;~p z#YDQ5zuZY#LLCkRyA@x&Q_1&{zHrsH<|Ws|h=l$8bb6CR)-i)rUG>2U!`>%zO`TyJ zuc1SH(JNT0#d?kuTY;OSFktJ5r}eNUou$*J$UDX+D?Yiz?=(E;X%S=Gu-77{0je^y z>C0Ue?>8BXYcuAH_ELHJx^5PQvStnRCQM?>3}xjhGzN4r&%7lS zc|A@$R|}&Rn}9%(*%Gcfxxzyt)&yaTL8@-YHs|&6&JTy~k(1Y>`CQwK%GPZ@{-MVn zL(j@~caN>Nb(&!Q-rdIwFidUwiDu6c&7z1Ay6$WyIcMhU=oO2`*}*4)x6zM3D5?~k zXZeLA+U-PpE08Se(ddlC-z`@e>bV)^Kk(}vXA*NnL(~tda+rl3{nA&+v9}E}pg8*hi_)U`IsM!goQS)%D-!)6vLvFu z0p3kfahm;W+!CjABndP1<;O}sLC%4P#UNuSca0-+5CS4Im%TA#4OZ_3NOq=S%}aRD ziW`w}3VCuFJFe_A?4ZZWn{!4=;#TFSulyU{kdIW5^9pEq`@_DFPemjHH;c@k4|a@- zf%eJ9##AHxPV0Vs+?d5oX44+#yUg+>GB;_Bk^fWJtGITA*Pkk&CUn|;@l-;wR z&5BBfs82?`` z&@E8o@akph5p(9)l=BbKa%7CE%rco!&1ObroX#&)=6Z$e_VF#}YO_6ejA1!1iI5$n zoeucopVBz3u}sdz0mX;72jzniv?Bf<2Yiy%!+rSN-qA}?6ysyLmZV$-)?42%{($V( zlf5s==Ecf~4E|Y=_73Qvkp3T_Lj+v&C}+tVMp&ZlamxN0*}D#fzuhK4S`T( z0C`j$!bR~7|6#=bn3*cLW#3X4C> zV?A)$W2o7fq3zrmcFQO@PV`C|tvokSYQB?<-VmCr`BHCx!bVF3SEF{TDwb8*^6^TG zlQw&*rSs)eV}Emxo7$FnqoyoSnGL-5X-K1>&yFyjcxp? z7zS`&8U?Wbm=X@yV}d1&!vys(^CMvJ;lYwkfFiV51;ln!2l69vqPRwtl>?f=WY>0| zLThjVh1ge5$TIY_ny!lx`P1b-Jdv+DxmqeyY#rQ<3Dq5bo-CRY zMo30sr86pFLWMn!_b~s4!YylqQXO&qzuU<_x2$5PEV?Cukg4vs0xc&r9ZP1}*|6Xi zu2=5exx4C%byx^v!Y-i7->p8GmE%Wac%^o|X6wPcx$#H=^mdz#?-? z!=*4Vk+oFp8Ok=?+h;Z)aA@shWsC`(e9So?BMajN7<%g|t%Ri%(1BGPD^;yr5_ zA2JX@KV>j-TcOjeX*g(uz%Mk@;g>1zQeKm%x95n^6t}FUMdfgKEkor1)BOa0>oE8` zM9W+Hu)W!E^@gwH%DUKo(;3Ok4Mf3VAb5o&1H#6^?ZQ`L3F4|Jz(r@+Pp$3rzK=rx(^ncNIkb@BqNhF7r{^+Jsy)Y% z)mdY%&?Tuv39MMEFvm%DL*fFa>M=W{`ZRM!Y+gawE#$OG$2y)RG^l%r+;nuX5@<&J zTShk_5KH|HsOTtc&1i(OM13R$xl*NuiyvW2od83n~>VD4<5&O8CenCMWc>e z;jQiDWSv%sKID2U;OS{<8Oo5ZER25jIPTZ@$T4Gu?8O58tO+Ntl`U)^%Sijpa*a_v z-xO9uhz*oa?J*eNv0$``QHU>cGpO~QMR&T96PWwjR;(i~Jn%zJOkM*ggWlGOn87&| zIG8Jhg`C&B&-PROY8pAxOkvd+t~)Q{`WWy~Ni%{qRY}ObRb!^FnbQNa_Demfg2{d? z0Bf0ISG_?J5c%s*0=nQpTfp*XhB4s+QeMX=e~U>V0r=udr)8^A$H*waXL7Ygs1%>; zBXwnle=rEK1wDVi!L2nqz|fc3!`QfR&VO0gH>!`TJ8SxLyKg|V&zPh|W^odsY+TPr zt_W&tE|wiRW-KEQt6(w!tz{E4BN;PX=PEe#|4jqi>K6AjYXp|~yyqmIb{v7qkdoYR z8B{<1z^vpe`NWcVO1)6>CE=U06<`_rd!wc9q(!UKQ+L*m* z1k9Y!K5oEdv$xyAGaemIa!WgVqz9ua9n1Ssq7l-x9fFDwFrKT=uci8OSTc7%` z)jv(IZLCnYSVDaiF5m^D!aPqmg!5KmInLFaXaGrOB~qw6Gl!dIG+}AMsXZEX=I*F+ zuE}_j25|(2Y!T}plM*y7xVVSR2B}D1OS|PeXMSu+=Lr<)fm-qW{nZ}pp5r=2aQ0f% zU+Bj$WaH&iH09NQsYJhmP@9ke`8^!X@$%g>WLrN!tI3YAR4w(LD7(tgO6IR-O&a-+ zaO0M3OPR+J|LJoI?`RYtzm9(?uiaM!Uw{w zcoO^_P@-zsR1CYOJoH=qV}xIh#1(|vW>e!UKdiSUa#@{jJj7^|_?vSq>~sG+l+vrd z<_mKxvE{g`Ji=8&OAu1k`YS_nFa#B^X|T5>-*L?){H)1)KQ0jPF--jr_qCdAC8rq^ zrzp(oMrCTNys*%%W7~4{pf=gG?%@?q=hq`<@hM)Gs1CLS*KC&(^OLXouznDo%63{7 z>^b$%kuk`2i6hK6Yk`~o2Z(RT5Ip8QXD*hW%yMWeY*(ar_n2(}8DWo<%!T>OSByVZ6? z)qVX(Blt2k?Epn-M3={uBu?Sv%A5Pgy2AeSlT|R8=9kTAhLlVOxfnjdv=mu#-+qST zPnJJ(w)Wu-o5GVP45Ep7p8sT2RCOTtEy4bk1CyQ`T6V+V=}h548}~j3mfjQ33SKz<8lXOv!&NPIBW#_K@Jk&&jsq z;P=tuWnc=`gzNbCbG3v2b-hKK@bM1xwPeUgx2vvopYwM2zcI_t&MBWvlfZ+-{oYAQ zZCZV!OO&&1t=h<7IYt7F8PWeEz-B2i5sJerF&36VApS3^TF?fy#``;K?RU0)!X72%t1M z822QbpggUAO>IplG;&`d2NOhmYSI9DOjb^A^}hO(KuliGfDyK|&UQP4ua(QYjV|rC zN3a1#-d`??u%wKhCsrK;EOIhb8KsP|8|W0SRh?{WDT)1&te4Pu>~Ws z9@&_Etwm`uq+zJ*4U=PvkM;2mJcZt2ARK@##C`08eb3j+YFEIRipExtM-_p$wlW#` zY(*sE@p}$LPWJ;&Gv!w*n;EjE1>TAM9h6MckTl!tsj=En04iM`-;Y=EV?p1k+Ly=T z)U%tl$9UFvj;n-$;SUKtBE0lXw$GfY;o^+=5RIBHPI9cBXTpGv=w-ZmH405>(ke)$ z*WvTWSmXOk)$y+eGf|3JlUq@wtQen^WJc{oU*GqvmrP545ShMC1!KNSG;m3tit1PX zOz?t{P1mYOP%w-#v}9|Jr8WbLTz=*r(roo?>vaySSY^5C-9L?;`%fDG{hA9ydhf)t z0KI?+V8Oj#OPwxF!zPh698AV%@yrcuy913%}d-mATB0&aJ(`$n14 z@3pcE61*(xFXVM%4Eo)ejrG0i)oBO7kscmhAjkjqJ}nj(%ZJ-)5vZXp(iAF48m|d_ z#LK!rNGTbjv!|F_#@=QnZ52#y2n==k1#H^c|eN6IQ~q4UoV10gpw!h z?iZ0riet|5jt6L;AQn;8pZFo6JFQJ5y z3E3J0QubHcj0@K8SjVLD z`9Ps}xiIv>%9u0)lh)iaMUgp?FH9fbNs#u|yr$aGvyq%!m~u187oiT^gd15hPiMBq z4r5CEV=&PI=1 zPH))r6dBgZe4jq`5iD)%!H(#C>E^pQv*XBcl6LCE@Xt2>+re;aGc~U9iQ`Jm8m|z- zrV;0nZSaFK&HwL|&fUYbOivqArP_Agr|$-Ty022sUtBl32i*3`8dw6Yd*&I%u*kV?Wg9 zmXitLMzq?;Y}c$6`roUjT>mIfDR*eX;LmM}h#;j;tsuB__*FD{-le`7NpQR}rO{-7 z?ag*wF|rSbW-!T9WVHJzA;P#&pxn7v9oR6zg|mA+lw*X zX1N(#Z;vy1Nz1@nGY?YHyxCv3y2}FRR+`IBr-KAHPbrus)3(M6(<1)RtM;FA0=`Uh z1a#zIo*D4R&rX=VM};}BYc(9I^y2>5LoS+O6t9krHKibwexglH%k8mV`n0ftMA&qv zCv6=CEj?|2VbdYQyT3c4p}#ZZzZsvK<1}Paf)dwOxLPh9^_WtyguBFD9@D}iX6JD9 zwf;j*^&0xV{{vd#-7Qh!m@pE{fxsrLlJ~S`9KZkQB=lC@2e1h}`9eG``BE%lphiRW zO0@sm4Ux-%FPhBWK!eWbv*>cS;oMbo;$zmKnMJY~o;G8m@o8aRS9Im;0dwMjgYSIp zdk>NQ@MaAM$oD*qCoCo~TZci^aLABMYZPFSoL#&dsbTTH2IfL5KNqtX`D#urM?mX( z0STxUvlb4++(M*Q>lIk|HIZ(Xau<@lX7od7DvW#`85yp8{;>R*n^DF%P_Sc& z&eS{c5$H*_QFRtQQnlwT`fbaxOzgeUA}z@0^Bcd~hM6Di${}Z1!_{H}7RaCSI|hvR zUnUfu9hm!WPfo6Z`{T0$Z$Jp^!#9GazWiE_{4Cge4!&AgXNS7C2jjtph`iXK(NP`L zHg^y?(c#!|aLn|3PV)wK>f}E4g1P@6K zV}ZVR0-qk5+V%7NGwogaJ^h*SUt&*+k%Ao;D+lL9&Z{Uh+_*8oDCl}f{LDrt91-k| z9sjRTWrLu~se?6|DP8LN&uDpflkmn`BTszqrKMY3+#vezUGk;Y?TbHNYv8II22cRM zhgbASKh#)i$29`6LYHM_0?Lg|drt#sOLotvnr(Q>?Z1mw9Dh3P+8{mspG6nFFB%#! zKcV~fz4B*jOIhJ>jp$b&;oMizw>?yED`gwlljwegl9?p$) zKodfbDLZO_3a}9`B3%5-&Ak!n*AQBZiVpox9xx&$kw<>?bb_`8MQ4$xw6pb8N!S1Z z);C*oV3>BHo1oM)N4_4tiEA{T=*O+(GF4&)KK6%^%hO@Y zFCkB6Yj*+YWppyT!7;qUT5apt>-$cT&mgZ#v$EZp7qsCu6=9t9$dQ=C*|`NT=6Ag? zlry0>3LiM__ntZG%}4Ok1fJG<0oEUbvGiRmF&O+iTJ{AP^Ts=K*5LlRg=7K|mS za=qW9^}r0j)p1%Czve)FgU}!F8#MLex?iE~(R?;{KQ+ih97(&Za{BKsAJM#gG+u!c z-Q0(|SX$SxA^{|z!Tr@Z8MC)NIQKmhNL>JH5xk^08??$9LM|i2rkdy_3AA|Uh#1Qk z*m%A$9Ir#Gvq<;6tQOEdBN$Giq#8wk?)Ymjiou^ok$MoaD!FoVeKc&^0r3t=EFo^A zw*AZF=0NU}Q9^+`(@xTHU98r=Q|z;tlj8Y0Sp-?2h)k|O|B);j1*QIy0Qr1mtt*42 z-aN=gkA~W17ft(E9T&&@8=tARmsHFsyaliJvZT#)I&I(7ZFq`)X}G9P2VSgfc5f1F zs8uDQuhSSeJ$09vP4Bw{Uy-goinO_?p zwQh6be3k9g>ke2Wcb&gVSe2glEc2b{5fA|~xl{C)Eb#XeLU*<&Z@)ZuM)d23IO&Ui zx^$#-xx>!tMJprC`;&!k8;3A0hA7qQ;Z%wG)77%)MN0 >H|5>LRIe2bYoIZivCUF{iyp>wdQ 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 Vp%?S{a{#c Date: Tue, 8 Oct 2024 11:51:57 -0700 Subject: [PATCH 07/19] resetting chat_window.py to last good version --- codeaide/ui/chat_window.py | 221 ++++++++++++++++++++++++++++++++++++- 1 file changed, 219 insertions(+), 2 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index 5916f16..68f83a8 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -1,5 +1,10 @@ import signal -from PyQt5.QtCore import Qt, QTimer +from PyQt5.QtCore import ( + Qt, + QTimer, + QThread, + pyqtSignal, +) from PyQt5.QtGui import QColor from PyQt5.QtWidgets import ( QApplication, @@ -12,6 +17,7 @@ QWidget, QComboBox, QLabel, + QProgressDialog, ) from codeaide.ui.code_popup import CodePopup from codeaide.ui.example_selection_dialog import show_example_dialog @@ -33,6 +39,85 @@ ) from codeaide.utils.logging_config import get_logger from codeaide.ui.traceback_dialog import TracebackDialog +import os +import time +import sounddevice as sd +import numpy as np +from scipy.io import wavfile +import whisper + + +class AudioRecorder(QThread): + finished = pyqtSignal(str, float) + + def __init__(self, filename): + super().__init__() + self.filename = filename + self.is_recording = False + self.start_time = None + + def run(self): + RATE = 16000 # 16kHz to match Whisper's expected input + self.is_recording = True + self.start_time = time.time() + with sd.InputStream(samplerate=RATE, channels=1) as stream: + frames = [] + while self.is_recording: + data, overflowed = stream.read(RATE) + if not overflowed: + frames.append(data) + + audio_data = np.concatenate(frames, axis=0) + print(f"Raw audio data shape: {audio_data.shape}") + print(f"Raw audio data range: {audio_data.min()} to {audio_data.max()}") + + # Ensure audio data is in the correct range for int16 + audio_data = np.clip(audio_data * 32768, -32768, 32767).astype(np.int16) + + wavfile.write(self.filename, RATE, audio_data) + end_time = time.time() + self.finished.emit(self.filename, end_time - self.start_time) + + def stop(self): + self.is_recording = False + + +class TranscriptionThread(QThread): + finished = pyqtSignal(str) + + def __init__(self, whisper_model, filename): + super().__init__() + self.whisper_model = whisper_model + self.filename = filename + + def run(self): + print("Transcribing audio...") + read_start = time.time() + # Read the WAV file + sample_rate, audio_data = wavfile.read(self.filename) + read_end = time.time() + print(f"Time to read WAV file: {read_end - read_start:.2f} seconds") + + print(f"Audio shape: {audio_data.shape}, Sample rate: {sample_rate}") + print(f"Audio duration: {len(audio_data) / sample_rate:.2f} seconds") + + # Convert to float32 and normalize + audio_data = audio_data.astype(np.float32) / 32768.0 + + print(f"Audio data range: {audio_data.min()} to {audio_data.max()}") + + # Transcribe + transcribe_start = time.time() + result = self.whisper_model.transcribe(audio_data) + transcribe_end = time.time() + transcribed_text = result["text"].strip() + print(f"Transcription: {transcribed_text}") + print( + f"Time for Whisper to transcribe: {transcribe_end - transcribe_start:.2f} seconds" + ) + print("Transcription complete.") + + self.finished.emit(transcribed_text) class ChatWindow(QMainWindow): @@ -50,6 +135,11 @@ def __init__(self, chat_handler): self.setup_input_placeholder() self.update_submit_button_state() + # Initialize Whisper model + print("Loading Whisper model...") + self.whisper_model = whisper.load_model("tiny") + print("Whisper model loaded.") + # Check API key status if not self.chat_handler.api_key_valid: self.waiting_for_api_key = True @@ -118,7 +208,34 @@ def setup_ui(self): self.input_text.setFixedHeight(100) self.input_text.textChanged.connect(self.on_modify) self.input_text.installEventFilter(self) - main_layout.addWidget(self.input_text, stretch=1) + + # Add record button + self.record_button = QPushButton("Record", self) + self.record_button.clicked.connect(self.toggle_recording) + self.record_button.setStyleSheet( + """ + QPushButton { + background-color: #4CAF50; + color: white; + border: none; + padding: 5px 10px; + text-align: center; + text-decoration: none; + font-size: 14px; + margin: 4px 2px; + border-radius: 12px; + } + QPushButton:hover { + background-color: #45a049; + } + """ + ) + + # Modify the input layout to include the record button + input_layout = QHBoxLayout() + input_layout.addWidget(self.record_button) + input_layout.addWidget(self.input_text) + main_layout.addLayout(input_layout) # Buttons button_layout = QHBoxLayout() @@ -445,3 +562,103 @@ def show_traceback_dialog(self, traceback_text): def update_submit_button_state(self): self.submit_button.setEnabled(bool(self.input_text.toPlainText().strip())) + + def toggle_recording(self): + if not hasattr(self, "is_recording"): + self.is_recording = False + + if not self.is_recording: + self.start_recording() + else: + self.stop_recording() + + def start_recording(self): + self.is_recording = True + self.record_button.setText("Stop Recording") + self.record_button.setStyleSheet( + """ + QPushButton { + background-color: #f44336; + color: white; + border: none; + padding: 5px 10px; + text-align: center; + text-decoration: none; + font-size: 14px; + margin: 4px 2px; + border-radius: 12px; + } + QPushButton:hover { + background-color: #d32f2f; + } + """ + ) + filename = os.path.expanduser("~/recorded_audio.wav") + self.recorder = AudioRecorder(filename) + self.recorder.finished.connect(self.on_recording_finished) + self.recorder.start() + + def stop_recording(self): + if self.recorder: + print(f"Stop recording clicked at: {time.time():.2f}") + self.recorder.stop() + self.is_recording = False + self.record_button.setText("Record") + self.record_button.setStyleSheet( + """ + QPushButton { + background-color: #4CAF50; + color: white; + border: none; + padding: 5px 10px; + text-align: center; + text-decoration: none; + font-size: 14px; + margin: 4px 2px; + border-radius: 12px; + } + QPushButton:hover { + background-color: #45a049; + } + """ + ) + + def on_recording_finished(self, filename, recording_duration): + print(f"Recording saved to: {filename}") + print(f"Total recording time: {recording_duration:.2f} seconds") + transcription_start = time.time() + self.transcribe_audio(filename) + transcription_end = time.time() + print( + f"Total time from recording stop to transcription complete: {transcription_end - transcription_start:.2f} seconds" + ) + + def transcribe_audio(self, filename): + progress_dialog = QProgressDialog("Transcribing audio...", None, 0, 0, self) + progress_dialog.setWindowTitle("Please Wait") + progress_dialog.setWindowModality(Qt.WindowModal) + progress_dialog.setAutoClose(True) + progress_dialog.setAutoReset(True) + progress_dialog.setMinimumDuration(0) + progress_dialog.setValue(0) + progress_dialog.setMaximum(0) # This makes it an indeterminate progress dialog + progress_dialog.show() + + self.transcription_thread = TranscriptionThread(self.whisper_model, filename) + self.transcription_thread.finished.connect(self.on_transcription_finished) + self.transcription_thread.finished.connect(progress_dialog.close) + self.transcription_thread.start() + + def on_transcription_finished(self, transcribed_text): + # Insert transcribed text into the input text field + current_text = self.input_text.toPlainText() + if current_text: + new_text = current_text + " " + transcribed_text + else: + new_text = transcribed_text + self.input_text.setPlainText(new_text) + + # Move cursor to the end of the text + cursor = self.input_text.textCursor() + cursor.movePosition(cursor.End) + self.input_text.setTextCursor(cursor) From d5876bfa40f1be9abbabf1f22b9a75a73822fee1 Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 12:02:12 -0700 Subject: [PATCH 08/19] Updated to include mic icon --- codeaide/ui/chat_window.py | 76 +++++++++++++------------------------- 1 file changed, 26 insertions(+), 50 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index 68f83a8..6dc4573 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -4,8 +4,9 @@ QTimer, QThread, pyqtSignal, + QSize, # Add QSize here ) -from PyQt5.QtGui import QColor +from PyQt5.QtGui import QColor, QIcon from PyQt5.QtWidgets import ( QApplication, QHBoxLayout, @@ -131,6 +132,15 @@ def __init__(self, chat_handler): self.code_popup = None self.waiting_for_api_key = False self.chat_contents = [] + + # Load microphone icons + self.green_mic_icon = QIcon( + general_utils.get_resource_path("codeaide/assets/green_mic.png") + ) + self.red_mic_icon = QIcon( + general_utils.get_resource_path("codeaide/assets/red_mic.png") + ) + self.setup_ui() self.setup_input_placeholder() self.update_submit_button_state() @@ -210,26 +220,23 @@ def setup_ui(self): self.input_text.installEventFilter(self) # Add record button - self.record_button = QPushButton("Record", self) - self.record_button.clicked.connect(self.toggle_recording) + self.record_button = QPushButton() + self.record_button.setIcon(self.green_mic_icon) + self.record_button.setIconSize(QSize(50, 100)) # Adjust size as needed + self.record_button.setFixedSize(60, 110) # Adjust size as needed self.record_button.setStyleSheet( """ QPushButton { - background-color: #4CAF50; - color: white; + background-color: transparent; border: none; - padding: 5px 10px; - text-align: center; - text-decoration: none; - font-size: 14px; - margin: 4px 2px; - border-radius: 12px; + border-radius: 25px; } QPushButton:hover { - background-color: #45a049; + background-color: rgba(200, 200, 200, 50); } """ ) + self.record_button.clicked.connect(self.toggle_recording) # Modify the input layout to include the record button input_layout = QHBoxLayout() @@ -574,25 +581,7 @@ def toggle_recording(self): def start_recording(self): self.is_recording = True - self.record_button.setText("Stop Recording") - self.record_button.setStyleSheet( - """ - QPushButton { - background-color: #f44336; - color: white; - border: none; - padding: 5px 10px; - text-align: center; - text-decoration: none; - font-size: 14px; - margin: 4px 2px; - border-radius: 12px; - } - QPushButton:hover { - background-color: #d32f2f; - } - """ - ) + self.set_record_button_style(True) filename = os.path.expanduser("~/recorded_audio.wav") self.recorder = AudioRecorder(filename) self.recorder.finished.connect(self.on_recording_finished) @@ -600,27 +589,14 @@ def start_recording(self): def stop_recording(self): if self.recorder: - print(f"Stop recording clicked at: {time.time():.2f}") + self.logger.info(f"Stop recording clicked at: {time.time():.2f}") self.recorder.stop() self.is_recording = False - self.record_button.setText("Record") - self.record_button.setStyleSheet( - """ - QPushButton { - background-color: #4CAF50; - color: white; - border: none; - padding: 5px 10px; - text-align: center; - text-decoration: none; - font-size: 14px; - margin: 4px 2px; - border-radius: 12px; - } - QPushButton:hover { - background-color: #45a049; - } - """ + self.set_record_button_style(False) + + def set_record_button_style(self, is_recording): + self.record_button.setIcon( + self.red_mic_icon if is_recording else self.green_mic_icon ) def on_recording_finished(self, filename, recording_duration): From c1b7c839415984baf8944aee4c8efaf6332f3585 Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 12:05:00 -0700 Subject: [PATCH 09/19] Disable buttons during audio recording --- codeaide/ui/chat_window.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index 6dc4573..67ed1a4 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -266,6 +266,16 @@ def setup_ui(self): self.logger.info("Chat window UI initialized") + # After creating all buttons and dropdowns, add them to the list + self.widgets_to_disable_when_recording = [ + self.submit_button, + self.example_button, + self.new_session_button, + self.provider_dropdown, + self.model_dropdown, + self.input_text, # Disable the input text area as well + ] + def setup_input_placeholder(self): self.placeholder_text = "Enter text here..." self.input_text.setPlaceholderText(self.placeholder_text) @@ -582,6 +592,11 @@ def toggle_recording(self): def start_recording(self): self.is_recording = True self.set_record_button_style(True) + + # Disable widgets + for widget in self.widgets_to_disable_when_recording: + widget.setEnabled(False) + filename = os.path.expanduser("~/recorded_audio.wav") self.recorder = AudioRecorder(filename) self.recorder.finished.connect(self.on_recording_finished) @@ -594,6 +609,10 @@ def stop_recording(self): self.is_recording = False self.set_record_button_style(False) + # Re-enable widgets + for widget in self.widgets_to_disable_when_recording: + widget.setEnabled(True) + def set_record_button_style(self, is_recording): self.record_button.setIcon( self.red_mic_icon if is_recording else self.green_mic_icon From 540b8d9aeb07b66cdf6183303cc6f24339e4a129 Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 12:17:07 -0700 Subject: [PATCH 10/19] Add text to indicate recording --- codeaide/ui/chat_window.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index 67ed1a4..447208a 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -597,6 +597,15 @@ def start_recording(self): for widget in self.widgets_to_disable_when_recording: widget.setEnabled(False) + # Add "Recording" text to the input box + current_text = self.input_text.toPlainText() + if current_text: + new_text = current_text + " Recording... " + else: + new_text = "Recording... " + self.input_text.setPlainText(new_text) + self.input_text.setReadOnly(True) + filename = os.path.expanduser("~/recorded_audio.wav") self.recorder = AudioRecorder(filename) self.recorder.finished.connect(self.on_recording_finished) @@ -609,6 +618,11 @@ def stop_recording(self): self.is_recording = False self.set_record_button_style(False) + # Remove "Recording" text and add "Transcribing..." + current_text = self.input_text.toPlainText() + new_text = current_text.replace("Recording... ", "Transcribing... ") + self.input_text.setPlainText(new_text) + # Re-enable widgets for widget in self.widgets_to_disable_when_recording: widget.setEnabled(True) @@ -645,13 +659,17 @@ def transcribe_audio(self, filename): self.transcription_thread.start() def on_transcription_finished(self, transcribed_text): - # Insert transcribed text into the input text field + # Remove "Transcribing..." text current_text = self.input_text.toPlainText() + current_text = current_text.replace("Transcribing...", "").strip() + + # Insert transcribed text into the input text field if current_text: new_text = current_text + " " + transcribed_text else: new_text = transcribed_text self.input_text.setPlainText(new_text) + self.input_text.setReadOnly(False) # Move cursor to the end of the text cursor = self.input_text.textCursor() From 62dc95016d8689bcbde082029270365e8b92c353 Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 12:18:51 -0700 Subject: [PATCH 11/19] Cleaned up text generation --- codeaide/ui/chat_window.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index 447208a..35f1f9a 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -597,12 +597,12 @@ def start_recording(self): for widget in self.widgets_to_disable_when_recording: widget.setEnabled(False) - # Add "Recording" text to the input box + # Add "Recording..." text to the input box current_text = self.input_text.toPlainText() if current_text: - new_text = current_text + " Recording... " + new_text = current_text + " Recording..." else: - new_text = "Recording... " + new_text = "Recording..." self.input_text.setPlainText(new_text) self.input_text.setReadOnly(True) @@ -618,9 +618,9 @@ def stop_recording(self): self.is_recording = False self.set_record_button_style(False) - # Remove "Recording" text and add "Transcribing..." + # Replace "Recording..." text with "Transcribing..." current_text = self.input_text.toPlainText() - new_text = current_text.replace("Recording... ", "Transcribing... ") + new_text = current_text.replace("Recording...", "Transcribing...") self.input_text.setPlainText(new_text) # Re-enable widgets From 8324fe2bf30583021a187cb862a49559cf7e86ab Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 12:46:54 -0700 Subject: [PATCH 12/19] Added some text formatting --- codeaide/ui/chat_window.py | 94 +++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 36 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index 35f1f9a..bc5fa09 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -51,11 +51,12 @@ class AudioRecorder(QThread): finished = pyqtSignal(str, float) - def __init__(self, filename): + def __init__(self, filename, logger): super().__init__() self.filename = filename self.is_recording = False self.start_time = None + self.logger = logger def run(self): RATE = 16000 # 16kHz to match Whisper's expected input @@ -69,8 +70,10 @@ def run(self): frames.append(data) audio_data = np.concatenate(frames, axis=0) - print(f"Raw audio data shape: {audio_data.shape}") - print(f"Raw audio data range: {audio_data.min()} to {audio_data.max()}") + self.logger.info(f"Raw audio data shape: {audio_data.shape}") + self.logger.info( + f"Raw audio data range: {audio_data.min()} to {audio_data.max()}" + ) # Ensure audio data is in the correct range for int16 audio_data = np.clip(audio_data * 32768, -32768, 32767).astype(np.int16) @@ -86,38 +89,39 @@ def stop(self): class TranscriptionThread(QThread): finished = pyqtSignal(str) - def __init__(self, whisper_model, filename): + def __init__(self, whisper_model, filename, logger): super().__init__() self.whisper_model = whisper_model self.filename = filename + self.logger = logger def run(self): - print("Transcribing audio...") + self.logger.info("Transcribing audio...") read_start = time.time() # Read the WAV file sample_rate, audio_data = wavfile.read(self.filename) read_end = time.time() - print(f"Time to read WAV file: {read_end - read_start:.2f} seconds") + self.logger.info(f"Time to read WAV file: {read_end - read_start:.2f} seconds") - print(f"Audio shape: {audio_data.shape}, Sample rate: {sample_rate}") - print(f"Audio duration: {len(audio_data) / sample_rate:.2f} seconds") + self.logger.info(f"Audio shape: {audio_data.shape}, Sample rate: {sample_rate}") + self.logger.info(f"Audio duration: {len(audio_data) / sample_rate:.2f} seconds") # Convert to float32 and normalize audio_data = audio_data.astype(np.float32) / 32768.0 - print(f"Audio data range: {audio_data.min()} to {audio_data.max()}") + self.logger.info(f"Audio data range: {audio_data.min()} to {audio_data.max()}") # Transcribe transcribe_start = time.time() result = self.whisper_model.transcribe(audio_data) transcribe_end = time.time() transcribed_text = result["text"].strip() - print(f"Transcription: {transcribed_text}") - print( + self.logger.info(f"Transcription: {transcribed_text}") + self.logger.info( f"Time for Whisper to transcribe: {transcribe_end - transcribe_start:.2f} seconds" ) - print("Transcription complete.") - + self.logger.info("Transcription complete.") + self.logger.info(f"Emitting finished signal with text: {transcribed_text}") self.finished.emit(transcribed_text) @@ -132,6 +136,7 @@ def __init__(self, chat_handler): self.code_popup = None self.waiting_for_api_key = False self.chat_contents = [] + self.original_text = "" # Add this line to store the original text # Load microphone icons self.green_mic_icon = QIcon( @@ -597,19 +602,20 @@ def start_recording(self): for widget in self.widgets_to_disable_when_recording: widget.setEnabled(False) - # Add "Recording..." text to the input box - current_text = self.input_text.toPlainText() - if current_text: - new_text = current_text + " Recording..." - else: - new_text = "Recording..." - self.input_text.setPlainText(new_text) + # Save the original text + self.original_text = self.input_text.toPlainText().strip() + self.logger.info(f"Original text saved: {self.original_text}") + + # Add "Recording..." text + new_html = f'{self.original_text} Recording...' + self.input_text.setHtml(new_html) self.input_text.setReadOnly(True) filename = os.path.expanduser("~/recorded_audio.wav") - self.recorder = AudioRecorder(filename) + self.recorder = AudioRecorder(filename, self.logger) self.recorder.finished.connect(self.on_recording_finished) self.recorder.start() + self.logger.info("Recording started") def stop_recording(self): if self.recorder: @@ -619,13 +625,14 @@ def stop_recording(self): self.set_record_button_style(False) # Replace "Recording..." text with "Transcribing..." - current_text = self.input_text.toPlainText() - new_text = current_text.replace("Recording...", "Transcribing...") - self.input_text.setPlainText(new_text) + current_html = self.input_text.toHtml() + new_html = current_html.replace("Recording...", "Transcribing...") + self.input_text.setHtml(new_html) # Re-enable widgets for widget in self.widgets_to_disable_when_recording: widget.setEnabled(True) + self.logger.info("Recording stopped") def set_record_button_style(self, is_recording): self.record_button.setIcon( @@ -633,16 +640,17 @@ def set_record_button_style(self, is_recording): ) def on_recording_finished(self, filename, recording_duration): - print(f"Recording saved to: {filename}") - print(f"Total recording time: {recording_duration:.2f} seconds") + self.logger.info(f"Recording saved to: {filename}") + self.logger.info(f"Total recording time: {recording_duration:.2f} seconds") transcription_start = time.time() self.transcribe_audio(filename) transcription_end = time.time() - print( + self.logger.info( f"Total time from recording stop to transcription complete: {transcription_end - transcription_start:.2f} seconds" ) def transcribe_audio(self, filename): + self.logger.info("transcribe_audio method called") progress_dialog = QProgressDialog("Transcribing audio...", None, 0, 0, self) progress_dialog.setWindowTitle("Please Wait") progress_dialog.setWindowModality(Qt.WindowModal) @@ -653,25 +661,39 @@ def transcribe_audio(self, filename): progress_dialog.setMaximum(0) # This makes it an indeterminate progress dialog progress_dialog.show() - self.transcription_thread = TranscriptionThread(self.whisper_model, filename) + self.transcription_thread = TranscriptionThread( + self.whisper_model, filename, self.logger + ) self.transcription_thread.finished.connect(self.on_transcription_finished) self.transcription_thread.finished.connect(progress_dialog.close) self.transcription_thread.start() + self.logger.info("Transcription thread started") def on_transcription_finished(self, transcribed_text): - # Remove "Transcribing..." text - current_text = self.input_text.toPlainText() - current_text = current_text.replace("Transcribing...", "").strip() + self.logger.info("on_transcription_finished method called") + self.logger.info(f"Transcribed text: {transcribed_text}") - # Insert transcribed text into the input text field - if current_text: - new_text = current_text + " " + transcribed_text + # Combine the original text with the transcribed text + if self.original_text: + new_text = f"{self.original_text} {transcribed_text}".strip() else: - new_text = transcribed_text - self.input_text.setPlainText(new_text) + new_text = transcribed_text.strip() + self.logger.info(f"New text to be set: {new_text}") + + # Set the new text, wrapped in a white span + new_html = f'{new_text}' + self.input_text.setHtml(new_html) self.input_text.setReadOnly(False) # Move cursor to the end of the text cursor = self.input_text.textCursor() cursor.movePosition(cursor.End) self.input_text.setTextCursor(cursor) + + self.logger.info(f"Final HTML set in input_text: {self.input_text.toHtml()}") + self.logger.info( + f"Final plain text in input_text: {self.input_text.toPlainText()}" + ) + + # Clear the original text + self.original_text = "" From 3eeaeabef10c846e558b4bf56a6416f4fd68213d Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 13:28:56 -0700 Subject: [PATCH 13/19] Almost working text formatting --- codeaide/ui/chat_window.py | 43 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index bc5fa09..caf6794 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -602,12 +602,14 @@ def start_recording(self): for widget in self.widgets_to_disable_when_recording: widget.setEnabled(False) - # Save the original text - self.original_text = self.input_text.toPlainText().strip() + # Save the original text content + self.original_text = self.input_text.toPlainText().rstrip() self.logger.info(f"Original text saved: {self.original_text}") - # Add "Recording..." text - new_html = f'{self.original_text} Recording...' + # Change existing text to light gray and add "Recording..." in white + gray_text = f'{self.original_text}' + space = " " if self.original_text else "" + new_html = f'{gray_text}{space}Recording...' self.input_text.setHtml(new_html) self.input_text.setReadOnly(True) @@ -629,6 +631,9 @@ def stop_recording(self): new_html = current_html.replace("Recording...", "Transcribing...") self.input_text.setHtml(new_html) + # Scroll to the bottom + self.scroll_to_bottom() + # Re-enable widgets for widget in self.widgets_to_disable_when_recording: widget.setEnabled(True) @@ -673,27 +678,23 @@ def on_transcription_finished(self, transcribed_text): self.logger.info("on_transcription_finished method called") self.logger.info(f"Transcribed text: {transcribed_text}") - # Combine the original text with the transcribed text - if self.original_text: - new_text = f"{self.original_text} {transcribed_text}".strip() - else: - new_text = transcribed_text.strip() - self.logger.info(f"New text to be set: {new_text}") - - # Set the new text, wrapped in a white span - new_html = f'{new_text}' - self.input_text.setHtml(new_html) + # Restore the original text (in black) and append the transcribed text + space = " " if self.original_text else "" + new_text = f"{self.original_text}{space}{transcribed_text}" + self.input_text.setPlainText(new_text) self.input_text.setReadOnly(False) + self.logger.info(f"Final text in input_text: {self.input_text.toPlainText()}") + + # Clear the original text + self.original_text = "" + + def scroll_to_bottom(self): # Move cursor to the end of the text cursor = self.input_text.textCursor() cursor.movePosition(cursor.End) self.input_text.setTextCursor(cursor) - self.logger.info(f"Final HTML set in input_text: {self.input_text.toHtml()}") - self.logger.info( - f"Final plain text in input_text: {self.input_text.toPlainText()}" - ) - - # Clear the original text - self.original_text = "" + # Scroll to the bottom + scrollbar = self.input_text.verticalScrollBar() + scrollbar.setValue(scrollbar.maximum()) From d154255723cdcd28558ad5360db41fe4c32e8f7f Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 13:56:46 -0700 Subject: [PATCH 14/19] Still struggling with formatting, but committing current version --- codeaide/ui/chat_window.py | 65 +++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index caf6794..f7ac5cf 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -602,17 +602,31 @@ def start_recording(self): for widget in self.widgets_to_disable_when_recording: widget.setEnabled(False) - # Save the original text content - self.original_text = self.input_text.toPlainText().rstrip() - self.logger.info(f"Original text saved: {self.original_text}") - - # Change existing text to light gray and add "Recording..." in white - gray_text = f'{self.original_text}' - space = " " if self.original_text else "" - new_html = f'{gray_text}{space}Recording...' - self.input_text.setHtml(new_html) + # Save the original HTML content + self.original_html = self.input_text.toHtml() + self.logger.info(f"Original HTML saved: {self.original_html}") + + # Change text color to light gray while preserving formatting + modified_html = self.original_html.replace("color:#000000;", "color:#808080;") + + # If there's no color specified, add it + if "color:#808080;" not in modified_html: + modified_html = modified_html.replace( + '", f"{recording_html}" + ) + + self.input_text.setHtml(modified_html) self.input_text.setReadOnly(True) + # Scroll to show the "Recording..." text + self.scroll_to_bottom() + filename = os.path.expanduser("~/recorded_audio.wav") self.recorder = AudioRecorder(filename, self.logger) self.recorder.finished.connect(self.on_recording_finished) @@ -626,12 +640,15 @@ def stop_recording(self): self.is_recording = False self.set_record_button_style(False) - # Replace "Recording..." text with "Transcribing..." + # Replace "Recording..." text with "Transcribing..." without adding a line break current_html = self.input_text.toHtml() - new_html = current_html.replace("Recording...", "Transcribing...") + new_html = current_html.replace( + 'Recording...', + 'Transcribing...', + ) self.input_text.setHtml(new_html) - # Scroll to the bottom + # Scroll to ensure the "Transcribing..." text is visible self.scroll_to_bottom() # Re-enable widgets @@ -678,16 +695,26 @@ def on_transcription_finished(self, transcribed_text): self.logger.info("on_transcription_finished method called") self.logger.info(f"Transcribed text: {transcribed_text}") - # Restore the original text (in black) and append the transcribed text - space = " " if self.original_text else "" - new_text = f"{self.original_text}{space}{transcribed_text}" - self.input_text.setPlainText(new_text) + # Restore the original HTML + self.input_text.setHtml(self.original_html) + + # Move cursor to the end and insert transcribed text + cursor = self.input_text.textCursor() + cursor.movePosition(cursor.End) + cursor.insertText(transcribed_text) + self.input_text.setReadOnly(False) - self.logger.info(f"Final text in input_text: {self.input_text.toPlainText()}") + # Scroll to show the new content + self.scroll_to_bottom() + + self.logger.info(f"Final HTML set in input_text: {self.input_text.toHtml()}") + self.logger.info( + f"Final plain text in input_text: {self.input_text.toPlainText()}" + ) - # Clear the original text - self.original_text = "" + # Clear the original HTML + self.original_html = "" def scroll_to_bottom(self): # Move cursor to the end of the text From ffcbda0eeb238efaa0999810e18fe11cc73650d3 Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 14:54:44 -0700 Subject: [PATCH 15/19] An almost acceptable version of text formatting --- codeaide/ui/chat_window.py | 53 ++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index f7ac5cf..b04ae41 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -604,24 +604,37 @@ def start_recording(self): # Save the original HTML content self.original_html = self.input_text.toHtml() - self.logger.info(f"Original HTML saved: {self.original_html}") - # Change text color to light gray while preserving formatting - modified_html = self.original_html.replace("color:#000000;", "color:#808080;") + # Check if the text box is empty or contains only placeholder text + if ( + self.input_text.toPlainText().strip() == "" + or self.input_text.toPlainText() == self.placeholder_text + ): + # If empty, set HTML directly without any paragraph tags + self.input_text.setHtml('Recording...') + else: + # Change text color to light gray while preserving formatting + modified_html = self.original_html.replace( + "color:#000000;", "color:#808080;" + ) + modified_html = modified_html.replace("color:#ffffff;", "color:#808080;") + + # If there's no color specified, add it + if "color:#808080;" not in modified_html: + modified_html = modified_html.replace( + '", f"

{recording_html}

" ) - # Add "Recording..." in white at the end, without extra line break - recording_html = 'Recording...' - modified_html = modified_html.replace( - "", f"{recording_html}" - ) + self.input_text.setHtml(modified_html) - self.input_text.setHtml(modified_html) self.input_text.setReadOnly(True) # Scroll to show the "Recording..." text @@ -695,13 +708,15 @@ def on_transcription_finished(self, transcribed_text): self.logger.info("on_transcription_finished method called") self.logger.info(f"Transcribed text: {transcribed_text}") - # Restore the original HTML - self.input_text.setHtml(self.original_html) - - # Move cursor to the end and insert transcribed text - cursor = self.input_text.textCursor() - cursor.movePosition(cursor.End) - cursor.insertText(transcribed_text) + if self.original_html.strip() == "": + # If the original text was empty, just set the transcribed text + self.input_text.setPlainText(transcribed_text) + else: + # Restore the original HTML and append the transcribed text + self.input_text.setHtml(self.original_html) + cursor = self.input_text.textCursor() + cursor.movePosition(cursor.End) + cursor.insertText(transcribed_text) self.input_text.setReadOnly(False) From f7a3f674395d309733e0cd4ab2a2a2ba6884f6d7 Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 15:17:01 -0700 Subject: [PATCH 16/19] Almost there... --- codeaide/ui/chat_window.py | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index b04ae41..cb80e8a 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -604,15 +604,18 @@ def start_recording(self): # Save the original HTML content self.original_html = self.input_text.toHtml() + self.logger.info(f"Original HTML: {self.original_html}") # Check if the text box is empty or contains only placeholder text if ( self.input_text.toPlainText().strip() == "" or self.input_text.toPlainText() == self.placeholder_text ): + self.logger.info("Text box is empty or contains only placeholder text") # If empty, set HTML directly without any paragraph tags self.input_text.setHtml('Recording...') else: + self.logger.info("Text box contains content") # Change text color to light gray while preserving formatting modified_html = self.original_html.replace( "color:#000000;", "color:#808080;" @@ -628,11 +631,12 @@ def start_recording(self): # Add "Recording..." in white at the end, without extra line break recording_html = 'Recording...' - # Always add a new paragraph with the recording text at the end + # Always add the recording text at the end modified_html = modified_html.replace( - "", f"

{recording_html}

" + "", f"{recording_html}" ) + self.logger.info(f"Modified HTML before setting: {modified_html}") self.input_text.setHtml(modified_html) self.input_text.setReadOnly(True) @@ -640,6 +644,8 @@ def start_recording(self): # Scroll to show the "Recording..." text self.scroll_to_bottom() + self.logger.info(f"Final HTML after setting: {self.input_text.toHtml()}") + filename = os.path.expanduser("~/recorded_audio.wav") self.recorder = AudioRecorder(filename, self.logger) self.recorder.finished.connect(self.on_recording_finished) @@ -707,26 +713,35 @@ def transcribe_audio(self, filename): def on_transcription_finished(self, transcribed_text): self.logger.info("on_transcription_finished method called") self.logger.info(f"Transcribed text: {transcribed_text}") + self.logger.info(f"Original HTML: {self.original_html}") + + transcribed_text = ( + transcribed_text.strip() + ) # Remove any leading/trailing whitespace - if self.original_html.strip() == "": - # If the original text was empty, just set the transcribed text + if not self.original_html.strip(): + self.logger.info("No original text, setting transcribed text directly") self.input_text.setPlainText(transcribed_text) else: - # Restore the original HTML and append the transcribed text + self.logger.info("Original text exists, appending transcribed text") self.input_text.setHtml(self.original_html) cursor = self.input_text.textCursor() cursor.movePosition(cursor.End) + + existing_text = self.input_text.toPlainText() + self.logger.info(f"Existing text: '{existing_text}'") + + if existing_text and not existing_text.endswith((" ", "\n")): + self.logger.info("Adding space before transcribed text") + cursor.insertText(" ") + cursor.insertText(transcribed_text) self.input_text.setReadOnly(False) - - # Scroll to show the new content self.scroll_to_bottom() - self.logger.info(f"Final HTML set in input_text: {self.input_text.toHtml()}") - self.logger.info( - f"Final plain text in input_text: {self.input_text.toPlainText()}" - ) + final_text = self.input_text.toPlainText() + self.logger.info(f"Final text: '{final_text}'") # Clear the original HTML self.original_html = "" From ab4febb63735f3e2d826e56b1c9767fb3aae0e71 Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 15:30:36 -0700 Subject: [PATCH 17/19] Good enough. Still don't love it --- codeaide/ui/chat_window.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index cb80e8a..bf938ce 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -659,15 +659,8 @@ def stop_recording(self): self.is_recording = False self.set_record_button_style(False) - # Replace "Recording..." text with "Transcribing..." without adding a line break - current_html = self.input_text.toHtml() - new_html = current_html.replace( - 'Recording...', - 'Transcribing...', - ) - self.input_text.setHtml(new_html) + self.input_text.toHtml() - # Scroll to ensure the "Transcribing..." text is visible self.scroll_to_bottom() # Re-enable widgets From b3b4554ef3b4873043f1b790d3c7197fa6a083ad Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 15:31:15 -0700 Subject: [PATCH 18/19] Removed unusued line --- codeaide/ui/chat_window.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index bf938ce..925be51 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -659,8 +659,6 @@ def stop_recording(self): self.is_recording = False self.set_record_button_style(False) - self.input_text.toHtml() - self.scroll_to_bottom() # Re-enable widgets From ac871b7a4505f8759bd66aeedfdd2ff7bbf6e98b Mon Sep 17 00:00:00 2001 From: dougollerenshaw Date: Tue, 8 Oct 2024 16:08:13 -0700 Subject: [PATCH 19/19] Saving wav as temp file --- codeaide/ui/chat_window.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/codeaide/ui/chat_window.py b/codeaide/ui/chat_window.py index 925be51..6a10798 100644 --- a/codeaide/ui/chat_window.py +++ b/codeaide/ui/chat_window.py @@ -40,12 +40,12 @@ ) from codeaide.utils.logging_config import get_logger from codeaide.ui.traceback_dialog import TracebackDialog -import os import time import sounddevice as sd import numpy as np from scipy.io import wavfile import whisper +import tempfile class AudioRecorder(QThread): @@ -646,7 +646,8 @@ def start_recording(self): self.logger.info(f"Final HTML after setting: {self.input_text.toHtml()}") - filename = os.path.expanduser("~/recorded_audio.wav") + with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as temp_file: + filename = temp_file.name self.recorder = AudioRecorder(filename, self.logger) self.recorder.finished.connect(self.on_recording_finished) self.recorder.start()