From 85e59d6f462772fbcb36a62fb6c204c85302e9c5 Mon Sep 17 00:00:00 2001 From: NawfalMotii79 Date: Mon, 16 Mar 2026 22:25:10 +0000 Subject: [PATCH 1/2] Added missing classes and functions --- 9_Firmware/9_3_GUI/GUI_V6.py | 1143 +++++++++++++++++++++++++++++++++- 1 file changed, 1126 insertions(+), 17 deletions(-) diff --git a/9_Firmware/9_3_GUI/GUI_V6.py b/9_Firmware/9_3_GUI/GUI_V6.py index e8cf8f7..f789462 100644 --- a/9_Firmware/9_3_GUI/GUI_V6.py +++ b/9_Firmware/9_3_GUI/GUI_V6.py @@ -88,8 +88,163 @@ class GPSData: timestamp: float class MapGenerator: - # [MapGenerator class remains the same as before] - pass + def __init__(self): + self.map_html_template = """ + + + + Radar Map + + + + + +
+ + + + + + + """ + pass class FT601Interface: """ @@ -361,18 +516,496 @@ class FT601Interface: except Exception as e: logging.error(f"Error closing FT601 device: {e}") +class STM32USBInterface: + def __init__(self): + self.device = None + self.is_open = False + self.ep_in = None + self.ep_out = None + + def list_devices(self): + """List available STM32 USB CDC devices""" + if not USB_AVAILABLE: + logging.warning("USB not available - please install pyusb") + return [] + + try: + devices = [] + # STM32 USB CDC devices typically use these vendor/product IDs + stm32_vid_pids = [ + (0x0483, 0x5740), # STM32 Virtual COM Port + (0x0483, 0x3748), # STM32 Discovery + (0x0483, 0x374B), # STM32 CDC + (0x0483, 0x374D), # STM32 CDC + (0x0483, 0x374E), # STM32 CDC + (0x0483, 0x3752), # STM32 CDC + ] + + for vid, pid in stm32_vid_pids: + found_devices = usb.core.find(find_all=True, idVendor=vid, idProduct=pid) + for dev in found_devices: + try: + product = usb.util.get_string(dev, dev.iProduct) if dev.iProduct else "STM32 CDC" + serial = usb.util.get_string(dev, dev.iSerialNumber) if dev.iSerialNumber else "Unknown" + devices.append({ + 'description': f"{product} ({serial})", + 'vendor_id': vid, + 'product_id': pid, + 'device': dev + }) + except: + devices.append({ + 'description': f"STM32 CDC (VID:{vid:04X}, PID:{pid:04X})", + 'vendor_id': vid, + 'product_id': pid, + 'device': dev + }) + + return devices + except Exception as e: + logging.error(f"Error listing USB devices: {e}") + # Return mock devices for testing + return [{'description': 'STM32 Virtual COM Port', 'vendor_id': 0x0483, 'product_id': 0x5740}] + + def open_device(self, device_info): + """Open STM32 USB CDC device""" + if not USB_AVAILABLE: + logging.error("USB not available - cannot open device") + return False + + try: + self.device = device_info['device'] + + # Detach kernel driver if active + if self.device.is_kernel_driver_active(0): + self.device.detach_kernel_driver(0) + + # Set configuration + self.device.set_configuration() + + # Get CDC endpoints + cfg = self.device.get_active_configuration() + intf = cfg[(0,0)] + + # Find bulk endpoints (CDC data interface) + self.ep_out = usb.util.find_descriptor( + intf, + custom_match=lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT + ) + + self.ep_in = usb.util.find_descriptor( + intf, + custom_match=lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN + ) + + if self.ep_out is None or self.ep_in is None: + logging.error("Could not find CDC endpoints") + return False + + self.is_open = True + logging.info(f"STM32 USB device opened: {device_info['description']}") + return True + + except Exception as e: + logging.error(f"Error opening USB device: {e}") + return False + + def send_start_flag(self): + """Step 12: Send start flag to STM32 via USB""" + start_packet = bytes([23, 46, 158, 237]) + logging.info("Sending start flag to STM32 via USB...") + return self._send_data(start_packet) + + def send_settings(self, settings): + """Step 13: Send radar settings to STM32 via USB""" + try: + packet = self._create_settings_packet(settings) + logging.info("Sending radar settings to STM32 via USB...") + return self._send_data(packet) + except Exception as e: + logging.error(f"Error sending settings via USB: {e}") + return False + + def read_data(self, size=64, timeout=1000): + """Read data from STM32 via USB""" + if not self.is_open or self.ep_in is None: + return None + + try: + data = self.ep_in.read(size, timeout=timeout) + return bytes(data) + except usb.core.USBError as e: + if e.errno == 110: # Timeout + return None + logging.error(f"USB read error: {e}") + return None + except Exception as e: + logging.error(f"Error reading from USB: {e}") + return None + + def _send_data(self, data): + """Send data to STM32 via USB""" + if not self.is_open or self.ep_out is None: + return False + + try: + # USB CDC typically uses 64-byte packets + packet_size = 64 + for i in range(0, len(data), packet_size): + chunk = data[i:i + packet_size] + # Pad to packet size if needed + if len(chunk) < packet_size: + chunk += b'\x00' * (packet_size - len(chunk)) + self.ep_out.write(chunk) + + return True + except Exception as e: + logging.error(f"Error sending data via USB: {e}") + return False + + def _create_settings_packet(self, settings): + """Create binary settings packet for USB transmission""" + packet = b'SET' + packet += struct.pack('>d', settings.system_frequency) + packet += struct.pack('>d', settings.chirp_duration_1) + packet += struct.pack('>d', settings.chirp_duration_2) + packet += struct.pack('>I', settings.chirps_per_position) + packet += struct.pack('>d', settings.freq_min) + packet += struct.pack('>d', settings.freq_max) + packet += struct.pack('>d', settings.prf1) + packet += struct.pack('>d', settings.prf2) + packet += struct.pack('>d', settings.max_distance) + packet += struct.pack('>d', settings.map_size) + packet += b'END' + return packet + + def close(self): + """Close USB device""" + if self.device and self.is_open: + try: + usb.util.dispose_resources(self.device) + self.is_open = False + except Exception as e: + logging.error(f"Error closing USB device: {e}") + + # [RadarProcessor class remains the same] class RadarProcessor: - # ... (same as before) - pass + def __init__(self): + self.range_doppler_map = np.zeros((1024, 32)) + self.detected_targets = [] + self.track_id_counter = 0 + self.tracks = {} + self.frame_count = 0 + + def dual_cpi_fusion(self, range_profiles_1, range_profiles_2): + """Dual-CPI fusion for better detection""" + fused_profile = np.mean(range_profiles_1, axis=0) + np.mean(range_profiles_2, axis=0) + return fused_profile + + def multi_prf_unwrap(self, doppler_measurements, prf1, prf2): + """Multi-PRF velocity unwrapping""" + lambda_wavelength = 3e8 / 10e9 + v_max1 = prf1 * lambda_wavelength / 2 + v_max2 = prf2 * lambda_wavelength / 2 + + unwrapped_velocities = [] + for doppler in doppler_measurements: + v1 = doppler * lambda_wavelength / 2 + v2 = doppler * lambda_wavelength / 2 + + velocity = self._solve_chinese_remainder(v1, v2, v_max1, v_max2) + unwrapped_velocities.append(velocity) + + return unwrapped_velocities + + def _solve_chinese_remainder(self, v1, v2, max1, max2): + for k in range(-5, 6): + candidate = v1 + k * max1 + if abs(candidate - v2) < max2 / 2: + return candidate + return v1 + + def clustering(self, detections, eps=100, min_samples=2): + """DBSCAN clustering of detections""" + if len(detections) == 0: + return [] + + points = np.array([[d.range, d.velocity] for d in detections]) + clustering = DBSCAN(eps=eps, min_samples=min_samples).fit(points) + + clusters = [] + for label in set(clustering.labels_): + if label != -1: + cluster_points = points[clustering.labels_ == label] + clusters.append({ + 'center': np.mean(cluster_points, axis=0), + 'points': cluster_points, + 'size': len(cluster_points) + }) + + return clusters + + def association(self, detections, clusters): + """Association of detections to tracks""" + associated_detections = [] + + for detection in detections: + best_track = None + min_distance = float('inf') + + for track_id, track in self.tracks.items(): + distance = np.sqrt( + (detection.range - track['state'][0])**2 + + (detection.velocity - track['state'][2])**2 + ) + + if distance < min_distance and distance < 500: + min_distance = distance + best_track = track_id + + if best_track is not None: + detection.track_id = best_track + associated_detections.append(detection) + else: + detection.track_id = self.track_id_counter + self.track_id_counter += 1 + associated_detections.append(detection) + + return associated_detections + + def tracking(self, associated_detections): + """Kalman filter tracking""" + current_time = time.time() + + for detection in associated_detections: + if detection.track_id not in self.tracks: + kf = KalmanFilter(dim_x=4, dim_z=2) + kf.x = np.array([detection.range, 0, detection.velocity, 0]) + kf.F = np.array([[1, 1, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 1], + [0, 0, 0, 1]]) + kf.H = np.array([[1, 0, 0, 0], + [0, 0, 1, 0]]) + kf.P *= 1000 + kf.R = np.diag([10, 1]) + kf.Q = np.eye(4) * 0.1 + + self.tracks[detection.track_id] = { + 'filter': kf, + 'state': kf.x, + 'last_update': current_time, + 'hits': 1 + } + else: + track = self.tracks[detection.track_id] + track['filter'].predict() + track['filter'].update([detection.range, detection.velocity]) + track['state'] = track['filter'].x + track['last_update'] = current_time + track['hits'] += 1 + + stale_tracks = [tid for tid, track in self.tracks.items() + if current_time - track['last_update'] > 5.0] + for tid in stale_tracks: + del self.tracks[tid] class USBPacketParser: - # ... (same as before) - pass + def __init__(self): + self.crc16_func = crcmod.mkCrcFun(0x11021, rev=False, initCrc=0xFFFF, xorOut=0x0000) + + def parse_gps_data(self, data): + """Parse GPS data from STM32 USB CDC with pitch angle""" + if not data: + return None + + try: + # Try text format first: "GPS:lat,lon,alt,pitch\r\n" + text_data = data.decode('utf-8', errors='ignore').strip() + if text_data.startswith('GPS:'): + parts = text_data.split(':')[1].split(',') + if len(parts) == 4: # Now expecting 4 values + lat = float(parts[0]) + lon = float(parts[1]) + alt = float(parts[2]) + pitch = float(parts[3]) # Pitch angle in degrees + return GPSData(latitude=lat, longitude=lon, altitude=alt, pitch=pitch, timestamp=time.time()) + + # Try binary format (30 bytes with pitch) + if len(data) >= 30 and data[0:4] == b'GPSB': + return self._parse_binary_gps_with_pitch(data) + + except Exception as e: + logging.error(f"Error parsing GPS data: {e}") + + return None + + def _parse_binary_gps_with_pitch(self, data): + """Parse binary GPS format with pitch angle (30 bytes)""" + try: + # Binary format: [Header 4][Latitude 8][Longitude 8][Altitude 4][Pitch 4][CRC 2] + if len(data) < 30: + return None + + # Verify CRC (simple checksum) + crc_received = (data[28] << 8) | data[29] + crc_calculated = sum(data[0:28]) & 0xFFFF + + if crc_received != crc_calculated: + logging.warning("GPS CRC mismatch") + return None + + # Parse latitude (double, big-endian) + lat_bits = 0 + for i in range(8): + lat_bits = (lat_bits << 8) | data[4 + i] + latitude = struct.unpack('>d', struct.pack('>Q', lat_bits))[0] + + # Parse longitude (double, big-endian) + lon_bits = 0 + for i in range(8): + lon_bits = (lon_bits << 8) | data[12 + i] + longitude = struct.unpack('>d', struct.pack('>Q', lon_bits))[0] + + # Parse altitude (float, big-endian) + alt_bits = 0 + for i in range(4): + alt_bits = (alt_bits << 8) | data[20 + i] + altitude = struct.unpack('>f', struct.pack('>I', alt_bits))[0] + + # Parse pitch angle (float, big-endian) + pitch_bits = 0 + for i in range(4): + pitch_bits = (pitch_bits << 8) | data[24 + i] + pitch = struct.unpack('>f', struct.pack('>I', pitch_bits))[0] + + return GPSData( + latitude=latitude, + longitude=longitude, + altitude=altitude, + pitch=pitch, + timestamp=time.time() + ) + + except Exception as e: + logging.error(f"Error parsing binary GPS with pitch: {e}") + return None class RadarPacketParser: - # ... (same as before) - pass + def __init__(self): + self.sync_pattern = b'\xA5\xC3' + self.crc16_func = crcmod.mkCrcFun(0x11021, rev=False, initCrc=0xFFFF, xorOut=0x0000) + + def parse_packet(self, data): + if len(data) < 6: + return None + + sync_index = data.find(self.sync_pattern) + if sync_index == -1: + return None + + packet = data[sync_index:] + + if len(packet) < 6: + return None + + sync = packet[0:2] + packet_type = packet[2] + length = packet[3] + + if len(packet) < (4 + length + 2): + return None + + payload = packet[4:4+length] + crc_received = struct.unpack('I', payload[0:4])[0] + elevation = payload[4] & 0x1F + azimuth = payload[5] & 0x3F + chirp_counter = payload[6] & 0x1F + + return { + 'type': 'range', + 'range': range_value, + 'elevation': elevation, + 'azimuth': azimuth, + 'chirp': chirp_counter, + 'timestamp': time.time() + } + except Exception as e: + logging.error(f"Error parsing range packet: {e}") + return None + + def parse_doppler_packet(self, payload): + if len(payload) < 12: + return None + + try: + doppler_real = struct.unpack('>h', payload[0:2])[0] + doppler_imag = struct.unpack('>h', payload[2:4])[0] + elevation = payload[4] & 0x1F + azimuth = payload[5] & 0x3F + chirp_counter = payload[6] & 0x1F + + return { + 'type': 'doppler', + 'doppler_real': doppler_real, + 'doppler_imag': doppler_imag, + 'elevation': elevation, + 'azimuth': azimuth, + 'chirp': chirp_counter, + 'timestamp': time.time() + } + except Exception as e: + logging.error(f"Error parsing Doppler packet: {e}") + return None + + def parse_detection_packet(self, payload): + if len(payload) < 8: + return None + + try: + detection_flag = (payload[0] & 0x01) != 0 + elevation = payload[1] & 0x1F + azimuth = payload[2] & 0x3F + chirp_counter = payload[3] & 0x1F + + return { + 'type': 'detection', + 'detected': detection_flag, + 'elevation': elevation, + 'azimuth': azimuth, + 'chirp': chirp_counter, + 'timestamp': time.time() + } + except Exception as e: + logging.error(f"Error parsing detection packet: {e}") + return None + class RadarGUI: def __init__(self, root): @@ -417,12 +1050,105 @@ class RadarGUI: self.start_background_threads() def configure_dark_theme(self): - # ... (same as before) - pass + """Configure ttk style for dark mercury theme""" + self.style.configure('.', + background=DARK_BG, + foreground=DARK_FG, + fieldbackground=DARK_ACCENT, + selectbackground=DARK_HIGHLIGHT, + selectforeground=DARK_FG, + troughcolor=DARK_ACCENT, + borderwidth=1, + focuscolor=DARK_BORDER) + + # Configure specific widgets + self.style.configure('TFrame', background=DARK_BG) + self.style.configure('TLabel', background=DARK_BG, foreground=DARK_FG) + self.style.configure('TButton', + background=DARK_BUTTON, + foreground=DARK_FG, + borderwidth=1, + focuscolor=DARK_BORDER) + self.style.map('TButton', + background=[('active', DARK_BUTTON_HOVER), + ('pressed', DARK_HIGHLIGHT)]) + + self.style.configure('TCombobox', + fieldbackground=DARK_ACCENT, + background=DARK_BG, + foreground=DARK_FG, + arrowcolor=DARK_FG) + self.style.map('TCombobox', + fieldbackground=[('readonly', DARK_ACCENT)], + selectbackground=[('readonly', DARK_HIGHLIGHT)], + selectforeground=[('readonly', DARK_FG)]) + + self.style.configure('TNotebook', background=DARK_BG, borderwidth=0) + self.style.configure('TNotebook.Tab', + background=DARK_ACCENT, + foreground=DARK_FG, + padding=[10, 5]) + self.style.map('TNotebook.Tab', + background=[('selected', DARK_HIGHLIGHT), + ('active', DARK_BUTTON_HOVER)]) + + self.style.configure('Treeview', + background=DARK_TREEVIEW, + foreground=DARK_FG, + fieldbackground=DARK_TREEVIEW, + borderwidth=0) + self.style.map('Treeview', + background=[('selected', DARK_HIGHLIGHT)]) + + self.style.configure('Treeview.Heading', + background=DARK_ACCENT, + foreground=DARK_FG, + relief='flat') + self.style.map('Treeview.Heading', + background=[('active', DARK_BUTTON_HOVER)]) + + self.style.configure('TEntry', + fieldbackground=DARK_ACCENT, + foreground=DARK_FG, + insertcolor=DARK_FG) + + self.style.configure('Vertical.TScrollbar', + background=DARK_ACCENT, + troughcolor=DARK_BG, + borderwidth=0, + arrowsize=12) + self.style.configure('Horizontal.TScrollbar', + background=DARK_ACCENT, + troughcolor=DARK_BG, + borderwidth=0, + arrowsize=12) + + self.style.configure('TLabelFrame', + background=DARK_BG, + foreground=DARK_FG, + bordercolor=DARK_BORDER) + self.style.configure('TLabelFrame.Label', + background=DARK_BG, + foreground=DARK_FG) def create_gui(self): - # ... (same as before, update device label) - pass + """Create the main GUI with tabs""" + self.notebook = ttk.Notebook(self.root) + self.notebook.pack(fill='both', expand=True, padx=10, pady=10) + + self.tab_main = ttk.Frame(self.notebook) + self.tab_map = ttk.Frame(self.notebook) + self.tab_diagnostics = ttk.Frame(self.notebook) + self.tab_settings = ttk.Frame(self.notebook) + + self.notebook.add(self.tab_main, text='Main View') + self.notebook.add(self.tab_map, text='Map View') + self.notebook.add(self.tab_diagnostics, text='Diagnostics') + self.notebook.add(self.tab_settings, text='Settings') + + self.setup_main_tab() + self.setup_map_tab() + self.setup_settings_tab() def setup_main_tab(self): """Setup the main radar display tab""" @@ -469,8 +1195,58 @@ class RadarGUI: text="Status: Ready - FT601 USB 3.0") self.status_label.grid(row=1, column=6, columnspan=2, sticky='e', padx=5, pady=2) - # [Rest of setup_main_tab remains the same] - # ... + # Main display area + display_frame = ttk.Frame(self.tab_main) + display_frame.pack(fill='both', expand=True, padx=10, pady=5) + + # Range-Doppler Map with dark theme + plt.style.use('dark_background') + fig = Figure(figsize=(10, 6), facecolor=DARK_BG) + self.range_doppler_ax = fig.add_subplot(111, facecolor=DARK_ACCENT) + self.range_doppler_plot = self.range_doppler_ax.imshow( + np.random.rand(1024, 32), aspect='auto', cmap='hot', + extent=[0, 32, 0, 1024]) + self.range_doppler_ax.set_title('Range-Doppler Map (Pitch Corrected)', color=DARK_FG) + self.range_doppler_ax.set_xlabel('Doppler Bin', color=DARK_FG) + self.range_doppler_ax.set_ylabel('Range Bin', color=DARK_FG) + self.range_doppler_ax.tick_params(colors=DARK_FG) + self.range_doppler_ax.spines['bottom'].set_color(DARK_FG) + self.range_doppler_ax.spines['top'].set_color(DARK_FG) + self.range_doppler_ax.spines['left'].set_color(DARK_FG) + self.range_doppler_ax.spines['right'].set_color(DARK_FG) + + self.canvas = FigureCanvasTkAgg(fig, display_frame) + self.canvas.draw() + self.canvas.get_tk_widget().pack(side='left', fill='both', expand=True) + + # Targets list with corrected elevation + targets_frame = ttk.LabelFrame(display_frame, text="Detected Targets (Pitch Corrected)") + targets_frame.pack(side='right', fill='y', padx=5) + + self.targets_tree = ttk.Treeview(targets_frame, + columns=('ID', 'Range', 'Velocity', 'Azimuth', 'Elevation', 'Corrected Elev', 'SNR'), + show='headings', height=20) + self.targets_tree.heading('ID', text='Track ID') + self.targets_tree.heading('Range', text='Range (m)') + self.targets_tree.heading('Velocity', text='Velocity (m/s)') + self.targets_tree.heading('Azimuth', text='Azimuth') + self.targets_tree.heading('Elevation', text='Raw Elev') + self.targets_tree.heading('Corrected Elev', text='Corr Elev') + self.targets_tree.heading('SNR', text='SNR (dB)') + + self.targets_tree.column('ID', width=70) + self.targets_tree.column('Range', width=90) + self.targets_tree.column('Velocity', width=90) + self.targets_tree.column('Azimuth', width=70) + self.targets_tree.column('Elevation', width=70) + self.targets_tree.column('Corrected Elev', width=70) + self.targets_tree.column('SNR', width=70) + + # Add scrollbar to targets tree + tree_scroll = ttk.Scrollbar(targets_frame, orient="vertical", command=self.targets_tree.yview) + self.targets_tree.configure(yscrollcommand=tree_scroll.set) + self.targets_tree.pack(side='left', fill='both', expand=True, padx=5, pady=5) + tree_scroll.pack(side='right', fill='y', padx=(0, 5), pady=5) def refresh_devices(self): """Refresh available USB devices""" @@ -599,8 +1375,342 @@ class RadarGUI: # This should match your packet structure return 64 # Example: 64-byte packets - # [Rest of the methods remain the same] - # ... + def process_gps_data(self): + """Step 16/17: Process GPS data from STM32 via USB CDC""" + while True: + if self.running and self.stm32_usb_interface.is_open: + try: + # Read data from STM32 USB + data = self.stm32_usb_interface.read_data(64, timeout=100) + if data: + gps_data = self.usb_packet_parser.parse_gps_data(data) + if gps_data: + self.gps_data_queue.put(gps_data) + logging.info(f"GPS Data received via USB: Lat {gps_data.latitude:.6f}, Lon {gps_data.longitude:.6f}, Alt {gps_data.altitude:.1f}m, Pitch {gps_data.pitch:.1f}°") + except Exception as e: + logging.error(f"Error processing GPS data via USB: {e}") + time.sleep(0.1) + + def process_radar_packet(self, packet): + """Step 40: Process radar data and apply pitch correction""" + try: + if packet['type'] == 'range': + range_meters = packet['range'] * 0.1 + + # Apply pitch correction to elevation + raw_elevation = packet['elevation'] + corrected_elevation = self.apply_pitch_correction(raw_elevation, self.current_gps.pitch) + + # Store correction for display + self.corrected_elevations.append({ + 'raw': raw_elevation, + 'corrected': corrected_elevation, + 'pitch': self.current_gps.pitch, + 'timestamp': packet['timestamp'] + }) + + # Keep only recent corrections + if len(self.corrected_elevations) > 100: + self.corrected_elevations = self.corrected_elevations[-100:] + + target = RadarTarget( + id=packet['chirp'], + range=range_meters, + velocity=0, + azimuth=packet['azimuth'], + elevation=corrected_elevation, # Use corrected elevation + snr=20.0, + timestamp=packet['timestamp'] + ) + + self.update_range_doppler_map(target) + + elif packet['type'] == 'doppler': + lambda_wavelength = 3e8 / self.settings.system_frequency + velocity = (packet['doppler_real'] / 32767.0) * (self.settings.prf1 * lambda_wavelength / 2) + self.update_target_velocity(packet, velocity) + + elif packet['type'] == 'detection': + if packet['detected']: + # Apply pitch correction to detection elevation + raw_elevation = packet['elevation'] + corrected_elevation = self.apply_pitch_correction(raw_elevation, self.current_gps.pitch) + + logging.info(f"CFAR Detection: Raw Elev {raw_elevation}°, Corrected Elev {corrected_elevation:.1f}°, Pitch {self.current_gps.pitch:.1f}°") + + except Exception as e: + logging.error(f"Error processing radar packet: {e}") + + def update_range_doppler_map(self, target): + """Update range-Doppler map with new target""" + range_bin = min(int(target.range / 50), 1023) + doppler_bin = min(abs(int(target.velocity)), 31) + + self.radar_processor.range_doppler_map[range_bin, doppler_bin] += 1 + + self.radar_processor.detected_targets.append(target) + + if len(self.radar_processor.detected_targets) > 100: + self.radar_processor.detected_targets = self.radar_processor.detected_targets[-100:] + + def update_target_velocity(self, packet, velocity): + """Update target velocity information""" + for target in self.radar_processor.detected_targets: + if (target.azimuth == packet['azimuth'] and + target.elevation == packet['elevation'] and + target.id == packet['chirp']): + target.velocity = velocity + break + + def setup_map_tab(self): + """Setup the map display tab with Google Maps""" + map_frame = ttk.Frame(self.tab_map) + map_frame.pack(fill='both', expand=True, padx=10, pady=10) + + # Map controls + controls_frame = ttk.Frame(map_frame) + controls_frame.pack(fill='x', pady=5) + + ttk.Button(controls_frame, text="Open Map in Browser", + command=self.open_map_in_browser).pack(side='left', padx=5) + + ttk.Button(controls_frame, text="Refresh Map", + command=self.refresh_map).pack(side='left', padx=5) + + self.map_status_label = ttk.Label(controls_frame, text="Map: Ready to generate") + self.map_status_label.pack(side='left', padx=20) + + # Map info display + info_frame = ttk.Frame(map_frame) + info_frame.pack(fill='x', pady=5) + + self.map_info_label = ttk.Label(info_frame, text="No GPS data received yet", font=('Arial', 10)) + self.map_info_label.pack() + + def open_map_in_browser(self): + """Open the generated map in the default web browser""" + if self.map_file_path and os.path.exists(self.map_file_path): + webbrowser.open('file://' + os.path.abspath(self.map_file_path)) + else: + messagebox.showwarning("Warning", "No map file available. Generate map first by receiving GPS data.") + + def refresh_map(self): + """Refresh the map with current data""" + self.generate_map() + + def generate_map(self): + """Generate Google Maps HTML file with current targets""" + if self.current_gps.latitude == 0 and self.current_gps.longitude == 0: + self.map_status_label.config(text="Map: Waiting for GPS data") + return + + try: + # Create temporary HTML file + with tempfile.NamedTemporaryFile(mode='w', suffix='.html', delete=False, encoding='utf-8') as f: + map_html = self.map_generator.generate_map( + self.current_gps, + self.radar_processor.detected_targets, + self.settings.map_size, + self.google_maps_api_key + ) + f.write(map_html) + self.map_file_path = f.name + + self.map_status_label.config(text=f"Map: Generated at {self.map_file_path}") + self.map_info_label.config( + text=f"Radar: {self.current_gps.latitude:.6f}, {self.current_gps.longitude:.6f} | " + f"Targets: {len(self.radar_processor.detected_targets)} | " + f"Coverage: {self.settings.map_size/1000:.1f}km" + ) + logging.info(f"Map generated: {self.map_file_path}") + + except Exception as e: + logging.error(f"Error generating map: {e}") + self.map_status_label.config(text=f"Map: Error - {str(e)}") + + def update_gps_display(self): + """Step 18: Update GPS and pitch display""" + try: + while not self.gps_data_queue.empty(): + gps_data = self.gps_data_queue.get_nowait() + self.current_gps = gps_data + + # Update GPS label + self.gps_label.config( + text=f"GPS: Lat {gps_data.latitude:.6f}, Lon {gps_data.longitude:.6f}, Alt {gps_data.altitude:.1f}m") + + # Update pitch label with color coding + pitch_text = f"Pitch: {gps_data.pitch:+.1f}°" + self.pitch_label.config(text=pitch_text) + + # Color code based on pitch magnitude + if abs(gps_data.pitch) > 10: + self.pitch_label.config(foreground='red') # High pitch warning + elif abs(gps_data.pitch) > 5: + self.pitch_label.config(foreground='orange') # Medium pitch + else: + self.pitch_label.config(foreground='green') # Normal pitch + + # Generate/update map when new GPS data arrives + self.generate_map() + + except queue.Empty: + pass + + def setup_settings_tab(self): + """Setup the settings tab with additional chirp durations and map size""" + settings_frame = ttk.Frame(self.tab_settings) + settings_frame.pack(fill='both', expand=True, padx=10, pady=10) + + entries = [ + ('System Frequency (Hz):', 'system_frequency', 10e9), + ('Chirp Duration 1 - Long (s):', 'chirp_duration_1', 30e-6), + ('Chirp Duration 2 - Short (s):', 'chirp_duration_2', 0.5e-6), + ('Chirps per Position:', 'chirps_per_position', 32), + ('Frequency Min (Hz):', 'freq_min', 10e6), + ('Frequency Max (Hz):', 'freq_max', 30e6), + ('PRF1 (Hz):', 'prf1', 1000), + ('PRF2 (Hz):', 'prf2', 2000), + ('Max Distance (m):', 'max_distance', 50000), + ('Map Size (m):', 'map_size', 50000), + ('Google Maps API Key:', 'google_maps_api_key', 'YOUR_GOOGLE_MAPS_API_KEY') + ] + + self.settings_vars = {} + + for i, (label, attr, default) in enumerate(entries): + ttk.Label(settings_frame, text=label).grid(row=i, column=0, sticky='w', padx=5, pady=5) + var = tk.StringVar(value=str(default)) + entry = ttk.Entry(settings_frame, textvariable=var, width=25) + entry.grid(row=i, column=1, padx=5, pady=5) + self.settings_vars[attr] = var + + ttk.Button(settings_frame, text="Apply Settings", + command=self.apply_settings).grid(row=len(entries), column=0, columnspan=2, pady=10) + + def apply_settings(self): + """Step 13: Apply and send radar settings via USB""" + try: + self.settings.system_frequency = float(self.settings_vars['system_frequency'].get()) + self.settings.chirp_duration_1 = float(self.settings_vars['chirp_duration_1'].get()) + self.settings.chirp_duration_2 = float(self.settings_vars['chirp_duration_2'].get()) + self.settings.chirps_per_position = int(self.settings_vars['chirps_per_position'].get()) + self.settings.freq_min = float(self.settings_vars['freq_min'].get()) + self.settings.freq_max = float(self.settings_vars['freq_max'].get()) + self.settings.prf1 = float(self.settings_vars['prf1'].get()) + self.settings.prf2 = float(self.settings_vars['prf2'].get()) + self.settings.max_distance = float(self.settings_vars['max_distance'].get()) + self.settings.map_size = float(self.settings_vars['map_size'].get()) + self.google_maps_api_key = self.settings_vars['google_maps_api_key'].get() + + if self.stm32_usb_interface.is_open: + self.stm32_usb_interface.send_settings(self.settings) + + messagebox.showinfo("Success", "Settings applied and sent to STM32 via USB") + logging.info("Radar settings applied via USB") + + except ValueError as e: + messagebox.showerror("Error", f"Invalid setting value: {e}") + + def update_targets_list(self): + """Update the targets list display with corrected elevations""" + for item in self.targets_tree.get_children(): + self.targets_tree.delete(item) + + for target in self.radar_processor.detected_targets[-20:]: + # Find the corresponding raw elevation if available + raw_elevation = "N/A" + for correction in self.corrected_elevations[-20:]: + if abs(correction['corrected'] - target.elevation) < 0.1: # Fuzzy match + raw_elevation = f"{correction['raw']}" + break + + self.targets_tree.insert('', 'end', values=( + target.track_id, + f"{target.range:.1f}", + f"{target.velocity:.1f}", + target.azimuth, + raw_elevation, # Show raw elevation + f"{target.elevation:.1f}", # Show corrected elevation + f"{target.snr:.1f}" + )) + + def start_background_threads(self): + """Start background data processing threads""" + self.radar_thread = threading.Thread(target=self.process_radar_data, daemon=True) + self.radar_thread.start() + + self.gps_thread = threading.Thread(target=self.process_gps_data, daemon=True) + self.gps_thread.start() + + self.root.after(100, self.update_gui) + + def process_radar_data(self): + """Step 39: Process incoming radar data from FTDI""" + buffer = b'' + while True: + if self.running and self.ftdi_interface.is_open: + try: + data = self.ftdi_interface.read_data(4096) + if data: + buffer += data + + while len(buffer) >= 6: + packet = self.radar_packet_parser.parse_packet(buffer) + if packet: + self.process_radar_packet(packet) + packet_length = 4 + len(packet.get('payload', b'')) + 2 + buffer = buffer[packet_length:] + self.received_packets += 1 + else: + break + + except Exception as e: + logging.error(f"Error processing radar data: {e}") + time.sleep(0.1) + else: + time.sleep(0.1) + + def process_gps_data(self): + """Step 16/17: Process GPS data from STM32 via USB CDC""" + while True: + if self.running and self.stm32_usb_interface.is_open: + try: + # Read data from STM32 USB + data = self.stm32_usb_interface.read_data(64, timeout=100) + if data: + gps_data = self.usb_packet_parser.parse_gps_data(data) + if gps_data: + self.gps_data_queue.put(gps_data) + logging.info(f"GPS Data received via USB: Lat {gps_data.latitude:.6f}, Lon {gps_data.longitude:.6f}, Alt {gps_data.altitude:.1f}m, Pitch {gps_data.pitch:.1f}°") + except Exception as e: + logging.error(f"Error processing GPS data via USB: {e}") + time.sleep(0.1) + + def update_gui(self): + """Step 40: Update all GUI displays""" + try: + # Update status with pitch information + if self.running: + self.status_label.config( + text=f"Status: Running - Packets: {self.received_packets} - Pitch: {self.current_gps.pitch:+.1f}°") + + # Update range-Doppler map + if hasattr(self, 'range_doppler_plot'): + display_data = np.log10(self.radar_processor.range_doppler_map + 1) + self.range_doppler_plot.set_array(display_data) + self.canvas.draw_idle() + + # Update targets list + self.update_targets_list() + + # Update GPS and pitch display + self.update_gps_display() + + except Exception as e: + logging.error(f"Error updating GUI: {e}") + + self.root.after(100, self.update_gui) def main(): """Main application entry point""" @@ -613,5 +1723,4 @@ def main(): messagebox.showerror("Fatal Error", f"Application failed to start: {e}") if __name__ == "__main__": - main() From 91b9286d1bbe0f075703be2d41bb3cf3469defcb Mon Sep 17 00:00:00 2001 From: NawfalMotii79 Date: Mon, 16 Mar 2026 22:31:18 +0000 Subject: [PATCH 2/2] Add files via upload --- .../4_6_Schematics/Antennas/Waveguide/DFSWA.dwg | Bin 0 -> 96190 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Waveguide/DFSWA.dwg diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Waveguide/DFSWA.dwg b/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Waveguide/DFSWA.dwg new file mode 100644 index 0000000000000000000000000000000000000000..fe9d6f6e6cb15f63d124fd42a8d5483e6a4c5f26 GIT binary patch literal 96190 zcmeFYd3+Q_w>MrrOC^(al1U&dOeT{i1OnOE37iuqO~60~2*{FzKqk$WO$dsQ1Sb%h zEzzK1Q$)nj0)m2sMMaDX4Jd@DsG!KA*dl_Wq9_7+t0&;&@80MA-22|&``*9q%%^&~ z>YO@ts?Jj1>P~P-a#BhkqJ6ye%?6Hi_U=U3#nZwrR<8Zd&3-PJ*u|d^U3=62mFsl) z{pM2%dwvZ2()XvI-u&+S^YRx17x@iZcjkqkzy3XIf6T~hul31zbA{}$pI9|xq`h@x?1CY0o%+D4f^(&Qrruemhq+?Ch$Xke?eTPHUZYC~2Q@zzen( z+sfx!R&@US$Codi|6Q1ASUo4;OoyJ+rk}bwe0b}F(;s$@^CDA6yYPEfK44|my|Si& z^gKD~7HHG|x5Y?Yq?nYj?>}kUV!ZqFEOMYOj`Zx>$Mbvc!mC>I|F6$=rr-Nar)8sD z_y8-Kj#}ZC^lS)U#PftZ`B>-JJLmdtojiZ~{*k4rlXZGBm5d3U&Jpf{{^pf8g7-W# z#9=t@3-!aHuo;-0iOCr47cgSX%*Ggs^{#Ms=@sEL4@-eUe*$uw`RR-k*k#qB+lObdiSgC$?x9Og>4gp($%NZFrc3)h* zwT6Dr8N3=x^ahic-A9&Te2CXp-JZ*512cA=Y<5xN>#P51_=SIT+%dH9w$EoTR;2qJ z8N3Y_p32O5t<%%D9Nt_K_-$+SqdWf5N8kGLoZrPF(hpqo{Ji!JUTS8Or{0DPze4vs zo%cfP(qLm&aDIk<)D!u}hAb}<$SlPble=w$-);>Ji%uW}yIdz`tCbiG9CL!K(N*4L zd8*#KPOp2Cd#aj@AEkwYZs|M&$<%EkNfVcD{cXt43;a54N~o&8{rpD(y2nC#481t} z1#72}-;asEbUPhX{Z89mozB3y&BQN>n7C51mFq#aHLkl#&XNn9nKYAAtXv>RNfYPI zh2@JNAA(@Pt$m&B#KgN+rQrIstPJtv1HKvl35+9<=BvoVyH`C^0 zOR#NAUk<%}Vtr;4Tf%&f45U`xDp*CUY*nmk42|JqhR1BPsWHoAhsP$wyq`Ecac24z zpZ>#Ruh_QPmfPO<@$srz`R>ll0Ixy6=C4Ysxo}n&b7b7cMQeucdg}Pb%BG53D_hF{ z-cMKv2_ocpTU#3&*WceiA|fI_KE7A4UPFcqaXOv(`T4VE4Io8$iV`x)(4P06>)qSs zr8$Zx3096_ZegCsF|$;*=YkUNMkC?MNfDV#N?DdDBb8(hv63kc9WlAs%^22L$-Xlf zX&NKtv1pw_=9CbxJZ69j_I=N%BDf%w_|5N_uM3=KBq0Qg98>!{XBR&_qxcc#luUFb zDQBib;$RX}n30o6FGmOO(afm5Ne_0-bJ^%zCcAm=Juxdlb&&W z_`6x|;Z8$srdB*vDNC4Atj&pW-WqIYJ6~&X2r!s|-nG7rQEGrSoY*()CTQEgTzWW}$UKq}w>3%j>fiO8WR>Ma8f(u{?|ERX+RC8XH^x zbYdfYi7mG;ZS0)kOIjUQl8U?@8q+n8)0MDHWB^@WXcjkvY^v>F5JvO|B1`hKC!CFB z(x;HT(YZDGD+ZO9r;y&+{d8JLB$id=l02QEKT{@!^q&wyD!3VuWZ4*!AL-8Sn8)Q4 z(>$;FV+>>FmX=PL{b*iaAHp;k#D*GxkXwjcvZ&%`L5VIT`=LYCA9PvlNUjb$cTd18f^ z(<^&GNu-lA=1iSgTvR!SB;Pb7ll~=#^PRnlqg{;!1wqf^A`9zSkQ|h9;CB9~Yh$Y} z&-Whxt$t<(Yt73YWF(q5ljnPnpsiK<30b=F#HBypEw5LeaeRVLe@QklgY!i9~ovauPP(y**7>F8A>MX-RcakCF?_b9N?C|HUDvA zZgFWv$&||CnxLi+@}g{M!DAOqDgS;lvufvDL*5cww0U7|#6)gga4t80&)LWG-pQpU zeQ4H{GFM6Q9JYMjL-Im(#bg+9G(iXwUg8gY?gi?K-q|LCftvU>dw$Ke#0#;m1tb29NqhI@3op%iWKjIY$BNRnt_+@UpERt=7TxjV z+OP>+qC17jE751Cm-KN*l9av~b1%kDzq@eMv}HH=-;;^lu;t~A?|dD3eb%I)+Giep zHL#)QBMVlVv%2kHzNYToo-?~kxu0r@BSX(F_dd*MT9Ub6_2iZNmH+s+zQBuYoan-r zC%AA0D=%yJtc0Ikf2{wRqTSj+=6i`{7&ETOOzdDWQOQa+Grs1{glJrmr?Y-J?lWk_ z8@o-_y$YSXyMQR(7329==DN zN*?v}D`VIDiSVDJPVpqr5+=Qf_0f{7=FnDlo&7KQ+c~u?J?EbMe=VU0oAu=jt4AGf zdCjrq?cXjBSp1yhMV1d31Y(lQncj2Rh?UH>+gErt%l&^Jzl_zi-N4H77z@3>G;dGg zT8ou!1Ahxf#ygwobT1%1eeNZbzw8iC=CNd-M!I^aR>oh;m-Fw(E@7*p*+8>4 z3;26-l3AZrrnT0K1wXs~zy9o;ULeRW98 z`>Vq*e$_D|VcLK*kKY{lW{da6F{iJ6RCoA@rr&=YKMWlFPyBeI_kSNh7ZyMN^B+0W z%`dO?Cf&O1KJx%KkVUH&Jr&IJwD{9vU1V`mdCwEIJ^wM*qG3~!?f$(OPm%|}imcv` z-D&>Rn^6*(r%h!o8m3KRbqx@uu$B~tXs0rdb1_;Klcw$8_s7(7kn29K_~*`k&+i8@ zTKgG~ZQGt0xgQaljGli<`PULPz1l}}G0n8hrsX0n0}Nt1X}b0HXsRJ^4YK93wp12V z9x%f0dwa(C_kI84kyF?zF`V=-=5s$={v9@I8126@KW&tL|8kUno2C9M(zR9iKV3a7 zBWYIG*09%qa`pac#rys@h{f^$P7-mO5wx9m(=*O~58SB}8_$z0br~O=~9W@<{ zCbEn)m+i}1wtdi(?OZGeKf-dHb~t_1lk19EuCjWtjfMj5oeNpc``fvYNn-~?CQrjD zd4FZgJSJT`#J1-ycJ}gQcn$ru;|Y!aZ)bJCMZ*gk0@O0(|L63`+RKRN{OB3WbAt5X zpgcC4*^K(H=6ZjTId&tCc(S{mIZXQ*{XXSC^IMVOMREie4$oj1f|Uo@y;i0i$bL9( zXWarqx_Dh@4`qV6AYBl5?3fp~{n${>mkZ$D;dBw)-4&EuA_-h;E#>YuaonOK$gMZ% zmS=D=+?T+ext+=FWTa)a0=Gq?#^a|lxdT5MxiizaLq|Dd{Xy(=?2}Axo6Zp8wQ4rE zVhOdl-2!)b1vS1E5OK0F?cGdn<#CSt;6>!Rach3cno_?^Biu8f#bOz+?FK*_tY|KXz=Df4>QR_xQS7F%=)+X z3IRLzP_Fe7;U;k#dvK9`-l!kSb>McKGzJ{=<6_zO<_dvb;|`N9CB{4h8UOjSw8L|3 zkzUtx3!SFb9l1X_Zm*Ghc^LOK8dSDCKlbKUJ;H4@adl^j;nj7>Ep6qDzdnUQKRv{K zzCzG_@5{ZllyZx*xP{TaKV)zp|Cs6Z^iM`Efjf0Dlj~u8{#H3z252yHZ3HiN0csUAj$2PN0OM&8y!R&+iGkgR!alP?a1yeR|(UMwdU!p zz5LqSI#zNXzK*xqllimlZCoQstMPPCV=*0@dylhwJ7?r=GVrRWXEOxiscqw#kSlS-*u^}>%`P`>r&SpPhHpMj3a@^Q&W$NsmIr)9zULXye+kjq_(A| zwuz~2>r&f}r?$0;6Vp<~(TVHC32|+?N#i0!F)x@qE?yt$MGg;V&-}C4xrLPvw0l-& zMbDXYv~zQ!mfhG38@5-pXV3mDYinn(N_IBW&c51-dz!YvlHXZj&+}NWbTG=ldp^l{ zwcPu^c|6H-td`}`liUCO`TBqMtpB@v7BkiV>7Heb*KkJH*n>3}OFn&Nbp0^T>$KfF z*}H*7%y0ZydElN8X?_IR13z(Qy;r3{CeMd+a@O{{|K6+M_b>HkuK|~^*MRox4|tK| zIWBYtu>F^n57@m{7Iqs^(=X_q&q??98RGIM>3#%eLYASw607!~yu84V^zw7V7RaJ7 z_>!&j{6|=WKY=T-)L^p%KY9Kk)+c~q9@`0QicPY;?H)~ue;~naOFQp*V!V#@cjFay zTVo>8W|EP>WT#J#xfM;`;>_-hnHk;&n1+^@dg>WK&bK;evi+g!k|z115DV@z+h5={DbZ z%fB_(Z-fbQ{H?~qT#g2A^kEEr7blna>K0#d2iXt!8ZH>j#zNzDhYw9MfT7-)WF!tV zXExUBT;VLYzY|L429b?MYQoY|o#-Tjz@%xA5AxiCiY(cTO6p(?|@7 zJMFq8riZI2#>x4=9x);-$~Tw2p&HGe93hkKaBhs!TRc6Tow*IhN?I8!i|Nb2z85VnhWz{DdKWr`_Ah^kgp? z*&x}&VqL{L^UheqIHuU7SJt_`|Ad;;!Hb;{P zh-{85p`>dkFxA8xAmdP?3x>F28e<)a4v1^CU5d5G9D;&QCZe9J;f`|kx_JG<4hzFFlKY(ZBe6bi!A0xM zI`668)2{2-!&>Gsj-KAEV|ZUS=uxf-qKVf|Zi{}QfpzM%sq>JC_2hLuQ*el#I?1dOs&Q^pP4Hy<&lX#8pV{l}99K*h zIw7}@K8zjKE6T^krSG0UjGOJEOj(`5P`!?f!ssmT0=xh6W!{ZTy>%RGd}fRHIQ#lO z%e*hK290a|7Vm=CgcY+B=h&b1b{H1s*~Uk3aipSRTx_EGp~N{2vDDaLSh&_5M#4&i z6SGXYc3O1ZPWmw`N!f~XpDvAS;99e`dNp#j+KX#lyv|j}8G5}MGv%Gh6}ywnekCU2 zmC^QIhZx=0%(jnRqJr6M=+4}Q%i|g|LmG0<9OY`D*}s7^W-zDIo_QCM471y|(@cWH zn>+>}JG(`I_z%W6oXZfd3%Xa#i|y87ju+|Siwd~@c7Qzah~PVZn6O39EQ z2q)pq;VdIX#)g;;QEp3fxH}vzg<$qhqE0VD&0gRI4xQ0TFBpQtxSe1o(XE`n!0?lH z9@oysmF&$$CJTdUEVSkj{IEH)IhqA^7(_GaL57MPyVJ`G!3HMEh;ok^c-^ZI&DQz> z-iGV6kQN%^vbcuqc->AWp_Npy1ru?Hzo~RiN>9>}?6JB+9WhjtBa; z1+ENS7x=n4FedOjb70rNW9Gnh=D?Naz(>uDdNFX9Iq=E#uUsQ>8SVvkn&Grj_r@$A zo%^V_=p@`UWr2JCNn-Xo>h1SADh)0 zpP^@e9uZdP?UQFDVSY@MpWaQTxUKOKdTWXfoFNok26tot+TS%TAZ6pF}OF{jgV{fX$Q|mY*i|l6U=1}Q9_2C zZH^`xvzsGI^1M1SPY7?0YW8*8jz*fo-CfDNnE3RzilXzbf%-<8(VAeea!2$&x`io+ z^&9(c)+a3PZ+JL!ShF?ukiP!(z&gEuc3=JU^tR#GTk`sPyB}?&ne_=q>sY6=k`t#X zk3VMjIvP?khs*L?=o~$VgS^=WgZrr8(F|irx!z(;@wetqFVklw=GI4Sv09H&zxo^F z%k&!ZpG_*iPCre(lF9V+%js>xuy4nwagR6BA=W{ssnzcG;d})$W$8;cr^WtjP}!hm zK8ac7zKruT|4&JDhI_u9*5_`?`HU@W-_ZdndTVI4&nc^Yv);g8=#U=eMT1C%cY52S zDOV;uG~d<`Y1Nmp44YP=H>9vfb0nN3tqpRYx5ky|`#B@hoAh42$UJLSdfS%RFJ}#C zq%eK9ZC&v#A?cemT z(OdJ;%lv!ar0p^3wo?K8>ojI)1gMc3{qu z{YYAxueEz?l!0ckcy)nsqX{Oog9}_;>+Q%B63|-Pc zp>cMf@LMD8zTqx9WaHQUx5p-3>a1I|F}}afs=L(LYA+1c`)V&x%VKL{tpVQQ`lIP> z6W%^vQO3Dwrqk+wkq)=^xj;GJ9P)5%NDtfh-P!9jtMN|f#5v{T-n!^a^IG7d8D<-E zx#_l&uGWz3r~!@s*0{4_oM|*Ej?GHYdEVv4cJDcOsZZd%7`B9$&YaVN$UUEB(bn<( z1~-TGt4v7TsMie~IB*KF%}b1p?vZP?*ZOpeN=sj+51%u8-^E|&_2n9=P;b>Q)pIO} z7ALx6V{e3%TuiLh$2KQed(`QJ5?<|NC6B}o=r^4`Ke*b*UeiDQTfLENvH5m8oc5b* z5XaJXX7wY~>U}zl>q}^ub=UrOAKURL|#zFuR9%{)k7$+G-(GI*ChdiH>tZ)0ov=^nS!Ax>Lu zx4i3C|MlUvs{`4i+4!lwYxQxbyIAA8rzh^m^zOc1(adsN(%aH|TyR$Es~Raf?Y4%& z1FXJD_UOvK*32(sO}4dNblMw9v3xsw;ku3}G9g23l>d8MebS`gUDgr1N$#L}}YU&36pLl{pMy zX9P2V8Wfv5BOnMm5C*Ipn%M!M-rzJ^N07oH;mw9b`}yf1T$U@@<~_|2#<}$I5es9F z=9AD`hi>^0wzrRT7@QdgGZcqD&!L|z_2^9Eu-U!bPDzG^WqMo4FxwUvG5dobvAN^B z9qo4hnlX?>WAlTTD1mG@btiduJMXAB=lhQ@F?a)Y_qA^6cD_yy8e??NY8>Z7=syC< z;TmI!PlJ*8+%@(fBm7|Qw(4At;pr{xTv5X{vyJd5H~)c*X0FE8FqZi0cDv)P33LD* zkkG$v!R|$2pDfnSnD#274 zrYbO1g(3EetgklMb zWhhplSOt-S$b%?=D1s<~D1)egsKPV}rpYi(foUqtSD}hR6%SPcREhAo438`DxC(9x zZXVnMxJ7VF;FiIyfLn!X3e`MR3s5aWwFK2NR4Y)e!a@oQc~~gGLJ<~9uuz7D3M^D% z5rsuOED~Um2#X|GB*P*F7O7A}p@xSV0cu33k)TF~8U<=pSWICt4~qp@EW%<57R#_$ zfyF9F6eIy85hMvD86*WH6_!v~!ov~)mWZ%Kf+aF6QDBJ*ODQbnVW|L1MOZ4qQW=&i zuvCR*6qfO@On_w~ER$fF49gT)rowUx%XwHXz;Y3mOR!vqg(oRI$-|QZJSoDH57y$JOZ)XPw>K)nhpDXipS zr2s2MSSi6u8CEK=QiZ1|JjKIP0z4(cQxZHS!&3@8rNYw`p620c0iKrNX&IhY;As^a zC^YcUAV7l%4H7iS(4atr3acor;$f8lt3+5O!73S6DX>a~)f86quv&oCBCM8RwG68j zSgpbu3Tt>+BfuIF)=02MhBXSTQDH5GwLGj9V66yiC0HxNS_Rgsu#Uny9@Yu4PK0$5 ztdn7#0_#+GhKFYact(V0BzQ)KXB2owg=Z-|%fqt*JS)Pp5npc~~#N zdJ)!3uwI7s3anS*ISSA5@SFh8iSV2R&&lwd0?(lFTnF6JTJlXGCZ%q^D1nlu#tz20&EmvqXZij*r>t_6kg!r1p!_V;ROj^kl_Ud zUQl5Zg-twc5@3@Enrx|VY39AW!S91W))-#G7qu#=|xN zwu!J!f^9NvQ(&74FH?A#hnEF-S%jA*cv*&*6?j>N?F_~7uw8)dB5apnyA0bE*sj73 z3Ojh%A;1n1c1W;8h8+sLLg5u2UJ>9G5nhqt6&YRu&+EJP{QlRqK!sN+yvoC?0=z21 zs}j5_!>bCss=`hRJ9*eCz)lf%O0ZLgoeJz!VHbs6JnRx+mk7Hg*d@a*1$L?M8im(* zcuj!UM0ibt*JOB2f!9>nO<^|=y9L-S!fpw6%dlI4-6}LuXyTzsfF==|WN1>LNrgQW z_VBPrfITAYkzkJudlcBC!d?n{dDtt!UJ>?6uvdn?3hY&3ABBB9>=R(02>T@1C&NAk z_NlO+!hRn13$R~={Sxe#VZQ?VRd}7k>pZ+J!0RHsF2U@TLTB%J8NFZ>n&B!T}x*2yj4z0}>pN;eY}MRCtTRTRgla zz*{1`CBa)VyrsZfDjcM6kcWc;92DW81P5g}sK7xL-lp(24{rXcnMZgk}kvWoTBQS%r5fyu-sg0=y%_I}*Gj!#gUxOW|D}-WA|o5#E*HT^Zh0 z;9V8oqwpRN?+Ngp2=7Voo(%6P@SX~XC>-M9kN}57I3&R#84f9MNQJ``4)btWfWsmj zmf)}qhZQ)ifk45-c zf{$hRSb>jKI7Q(U52pk;CBi8QPRVdefm14cLg5o0J`vy(5k8UN69qm|;Zq8q^6;qu zpNjCQ1fR@EL{Ac=$|!&qVl4g3o05Oo7i-I8EU+52pnT$WGXk6u;fw@lWH_V185KUK@Hr2k3-GxJpG)w$44*6Txe8xU_=1No1o%RPFC_Rv zhA$NOLWQ#w&hl_pgtHQymEo)cXI1!;!k0XJDZrN^d?~?~GJL7Pmnxj2aE^y_0-O`! zoCN1&IH$ll70y#Q&%=2E&Wmtfg7Y$*SKzz~7bsld;er4cM7SWq1sN_Va6yHO6fW{` zQGkmgT$JFV3>Ou+sKQqizT)940lpI9D+#`m;VT8cQsHX~U-R&_0AGvnwFF5?qzxssdM4xJKa`57z{^Cc-rduE}ssfom%KK;Z`-eh}aX5q^;12N`}) z;0G0cr0^pTKML@p2tP{jqYOVP@S_UXDO~5_x&YTjxGuqU8LlgEU4@@0{KUgg0{kSx zPZInj!%qtQq{7b>e&*q40e%+YX9<3m;b#SYR^b;4zwq#j0KbUviv+*O@QVV!sBnYA z4IXX?a6^O}65NpCh5|QK_?5!1Jp3xauOj>^!LKs>s=%)*{6^t79)1(xHxYi5;5Qk5 zQ{XohZc@0(!%YEhif~hcn=;%~;HC<{Q}~^S-v#(xgx@9jU54Kk_+5oRDEz_09|HU# z!XFa+A;TXE{Gq}v3b%N;CBQ8aZb@)UhFc2UQsGYufAa9B0Dp?`rv!h>@TUTQs&Jda zZ60n5a9f1i65N*IwgR_RxI^I%4|fE(Bf=dC?#OUQfjcVPrEr&ry8_%5;jRRCWw@)r zT@~6WwDHg;K${3{612(Cra+sDgd*XQ2uMUE5)v7Sf<#4*BF7^qASWUxAtxiJAg7{^ zqK-$MfI1O%66$2sDX3FXPf^dKUO>HwdI|M1>J`+hXrO4|(IB8fM1zC|84U^=R5VgF z@@N#$D56n9ql`ucjVe-#lt(Hc6_H9vWuyvH6}>2W@#rO>mxx{xddcXepqGl?6uo)$ z7SLNnZwb9+^j6SYMH596k0t?4BAO&L$!Jp0q@oW+A0B-K^byfVLLV7@6!cNim!dC^ zz5@D+=qsVGjJ^u`s^~}2k4HZN{Y3PW&`(A`1^ra?r|8e4zkvQC`b+39qrZawDh5yt z;4whJ01*Qu43IHE!2lHlDF*TwC}5z7ff5GF7^q;Nie`#t9?b%pMKnujmeH)BS;ZiV zK|BTt7$jnlgh4U}DHx<;FvVaVg9Qv0F<8Q28G{uJR?$My!lOk%i-;BpEizgZw5S+D zF@(nu0YgL#kuXHY5Cub245b*#W2k_kB8EyBDr2aEp(=Ku*n!6m0(KCwgM=Mq?4V!= z6+2Sw$YVzVJBrv*!j3X_RIsCpVHCr73==R+#4riNWDHXVkD1|0!E4$DPg3HkqSnt7)3FP$0z}#M2wO! zO2#M!qg0Hh7|mm}fYBmGOBgLHc@?`*?80Lg0lSFUMZzvJc2Tg4it!ZVd5jk@ zUc`6_<7JFjFkZ#36ua`+Rlu$yc9pQJj9nG%s$v4g1RfIvOb{_a!UP!;6iiUD8^vxs zb`!9hh}|UYCSx}RyQ$cnVs{?93)o%6?h3dv4?~`WbC0}4;6b-?8#$K0egzrQ^KAy_EfN^ib)iccuW#7NyH=xlVnU% zFiFK^ipe}C3z#fovV_SpCM%e%VhY6+9#aHN5iv!=6d6+#Oi?kFVk(cR0;Yo5$V)_7<_X zguP|#tzd5z`%vt|V;=$gh}cKMJ~H-Eu#bv;DfZ>DuYi3;>?>hk8T%^OSH*r5`|;RM zze-Zmj*k8u}3ielV0L1}34iIpFhyx@XAmac92dFrZ z;y@k;3OG>2ff5dsaiD?&RZORt&SScO=^~~}m@Z?wg6S#_qBw}hK>`jEagch;N%usO%#UVTn5palzLnIs`;}8XhsOX^R;L#zVLqvy!4jCN^I#kT0 zn8{}|ED5t@%u+B*#bFeO@iLjK9I0Xs#T*`U1k4dJN5UK#a}>-`(a9cy^XL@N zDWX$Cr;JVoohpu^IEu$n0*(@Kl!T*X9HrnW6-QGX&EseRM~gUG!qGC0R&cb6VwdG7#YVXI7Y=>in%=I3YaTmu7tTV<|>%0;#i7fc^oU?SP{ocI9A573XWBA z9K~@wjuUX4h~p$2C*wE;$Eo-r#RqwOP{0R8d{Dv%WqeS<2UQ$TaXgRX1spHpcnQbL zI9|c=Do&s{fyW5~P7rZ|gcD?(px^`*CsLfq<3s@`ia1fii84-9aH5KnC{E&Wl7N#$ zoFw5S87Cxr35#SbQm{xx z7eyD3E&*L4x+HYT=u*(7Vll;H9*YGm7O_~uVi}7SELKsZDDo%@D2gabD9R`*D5^M( z;xrzo2{=u}X%bG8ahihDRGdz6I*-!@oG#*Y38%|AUBT%p&Y(Dh#~A|75OIctGi02h z;0zUKQk==-OaW(#I8(xzGR{Tzk) zT_!`#sb`EAA5C6hx;dlD^gR2+2p`dJ;u|0Kt(+c`6TYa!E3a*ulrVU6%`+V9|Ht+^ z(>HmR5)(JDa=Na@+hlyG+?m($2qV4q<^t2kxO1kEk$D!w9;}!gefU6`W#z3}lPk5v z!ZC5i8gGN~yTUE2-+ywXC3i+(uL@YR~*|$J$&Cr6P zl7sDhyBZkZGacJygnplI8ONxW%EET)4vji=aFwZvNtr^9zWdb5Q%gfOS3pYArk0!w zyW6=|onl-KU$n~zY0S55Zpm52wbNE=w5~B#raer;+$UO#PCOj4)Kajxs4475OOF0T zJJ&x#7}sRAU4kV)-||~a&I3c*X%B0(`pH$My-dQ)sNap=6LXgacYJEeATFaNr(vAN zRcb0oxoaBd-7X-wL%t=mCFkO$cGAR@Hq-Y%$HhJuvah6z|AOUh%8)?~OFM6R`=|P& zn-kW5JFYhR#@vv7uJ~y_wuUVY-g~bvd%GsY6~EpzE#%~8Tf^mXAx{je2`Py$_8F8C z;B($tW!hg7?>8shYuZ6w)0U3a+Z8-><%BagF0tc&SA4mNHf>1?2(gc>wYcIpm^!-i zE!R#sW9qi;FX>WlVm%mfT~n3ibvB=AOM1rtuHM+vq5ta_KX`xOiH+vE0j#~ubmc}e zHCF#zYtcNWL%)2>pq7o}k7yGrF=an8Nj8JCUUCG$iq_wMIc{$&5?nKVKc4E1S^+>vF7#>w+IlzPz2Z`N}J>9e= zxcEEAgcT_*IgW1HP^G3dDR)e(7 zw8ikqjV(c)?oRt+PEAYB)VwMSBb1sRW5%tz-ae0@=zNRRl9TXJ`#c`G!4!OLm_5^c zkQukkf7O$d^Fp>nE-EhitksyZ{#zUSi-yI{gPL(62g-A_NQ zia%HqFZ$$#BnS9Be!j}|HnZ>4XWvSC#+rMy!!on{W467;DIa2~g_+l$do(FDq$2Li zsJAuyc37Hk;ai-_RBc9@agqXjdbd=WnwdV2m>Pfj)zEM>G$Zca83X^ZDSksj@_=^5 zy&IT;e+g@!R4C?Ks#-Rdyr5O@8F)j&k!@9`ci6(rT66sAo|jJ@wfvd#%`f)jCvt|x z?FeCnGSk&lDYp%5X<221$#N^-($bRCHMllfb2Qc=`Ho?1mFZn3qR@CFcjk$ZqrpwU zRfR^h=x{FI(xD~i#{{kFG09!i z>T3JpV1?Oab|Mcnxc6L-nh)XBp~FI!uwvbrYfaj z?YNN1;Z^a9<|X+zk^_wMYN|{}n3ssPZ0oY6T@D$x?8OeRG_^QQb?silr(I48FzV{H z+6GfdR=#EL3FnNsPdXmamX`HM@;5r_jvi&RdMqL%uRE>0Y|(8{>eu+3*!W^xX>Tz;?8j8<)+MuNxc7 zx3%O%_*PjMq15zIiqXfrE}Gr5?Q2fHWygt}j_tx*wD{}sRaNu{Ou)PvwpHy8x!f^P ziQy;TZpqm^p?#QrA&jdvLaVTZ*gfBJwP#Vm3s(rbaLx1?# zu?0q-$T?DXgteEM-pozDV|pa6E|b+Zm_o1RTgD#G;YSQ+RgZ!1n1;mpXPsaornuQQ z^=!lCke4nLrX)3<$hj0()rAqtOwTv4k)9hZITtfuV~UWpOBA!uxf z6t|=2$r9#9tSfV)?P)aJCy|6Oy!1z@X;i{_C&Nau*A9~4zMM;EpoPUjfn(;*^}FTj zrTW#JN-NU><=Rj_hsuHd)s8- zo?cV{Io-=lqmVgg%x#mA7G`w|3cIl>U;H%g+KAgOC*#uhin@8`s{^H`h`1A(x0C1V z&RISYs-m?!1L3|qw5_S8%<{>oT9ejb_;l~GIZ}3+Nk6*EbceMVxfd4|II=>v6(m1j zR%=R`uhUm#bqftYTWWf^?!3lf&}T;7{POF@Qf9avHctx)`tHyxdrC@8V%&()cRg}d z1}B%Km72Wb{3mHGMs7D#ewg94{Nz94s``7FsGDgYalF)2TvzI8(2r%RUuq~bIlipQ zY}4eB7^d*vyfV|158JEEZCAS(JAXGfG;HVG3~}|y#%ZfdS9Xp4WO$n^zDM^$myao@ z=^34P;j@(tgh8BtkG7Jo{Pui%?PSBgN4nf3<+)<0@NQYxYEsg*9hiDC+-BT-Ve!hW zKUkMr_JCB4w%)|L=wIuQ8LO_bpD1+N7YNnFrFCK0lwnzKL*yr49=r1n>r!q%7s$C{b&?v{ysKK}S+RaxdvmqA^sETH!b|qilckZouJ?$-pHKG=j zjGv)Vy{6)#*BnW%u8jYq^=wyZ*RSnFj}8MMv}eBLo!u1jVWPv0>b_UyT+KFz1+s|LplwOU_eIRGFyO(E~MmmTE*#zh7E% zf;YAI^B~OyQUB~W^h8dqUF=isrR6{kVH&)uEUe<`$iQcOy2e{-n#f2iN5vL|YMlJ~ z{Mexd_mJf#Iyc1oZ^*LE<*EM#Eysr3viImz?cEM8{eAk_%Q|bd_8I@!;{5u_x$z#< zp@B;OkcaI*#8k7oM}sRZ&dWM&vD#6kf5_MNL7CNmtyjO6jnzI?79VZa9ys~aqkqkM zK+8ss*J|Y^hCV&p$VTtEF2>8x?-tvoJIi1V4uUxBbVDh?N{yZO5{& z+GIRECQg_S1FKRQfh`>44b7ZlU!4&3C(D0b%S?SM?KP?TDcPG0BZo3h>Dww(09%N5 zu?-n@T{^|B3SlkxPl!wJYKz`3sUhQuE|1L8RFtRbTQhXrwbwee>+cE2hw7>smG#{de>eRk-I87_-|v^CcIrZ>;)OYXXw;=bQC%@r8R+&05 z=l1A+wZ(bpLOay+oc96`2Wd6W@ISOTcX$r7W$d`ee4?9wh~BRBukLtX{q&ZNM_;e9 zu(~HSjmDC=&55k$>D{+w}NDG3(cmO4gUIu zU;XdIUF#QKlE{a|*pFw=_p?9oz@fcWeZucY=c)(NVmn3j{g(BLxEGr~UpqGGP7Y1K z$z0Ule{M-cduZ;7*<~w8@VQhR`bnIBuZa7xnHR73xwOgPqr{aCacZ;nv2ED)+N6X5oASzX=6wCn*kn61XQF{*T`oW{^QZbY@&ZS>`ynpn&3zj0$cEcU*7_kP>i- z!6nB`y$T3!IYy?YrG^GBDCUN?I7H^IgG*{zYMYu`mX%tX;QxKjxwFvc`+L3qug}Xq zyw5q$bI)C#=bZCw6Y5nleENhIM=-NqBvy~LkV_^cS)sbKc9)@U+YFNwOxH;Ec|385 zr^ziXu)Ic+3R!7XhW=Y4PSQ!5*0hg_q&=2io)eBJ9F%f@Idl%~WfEy2iCQ3bN08Sv z?c2omLL0`IN~G^>$q2-$H`j<)H*$$$E99I+3K;1J4sn*DW@LT{rGzZjs%j0pCsW8t z|HO%IkQB_inKT|E`VK&h_>n{0Z)lyLA4-WKjIHW7f6_H&4PY{7thmE3k*iUweW z18T(J$&x0_xlG2VLkfXBq%dX0S49WHJcRJ28P0E67Q)0NDI(mtMA}G2JOID)U59zL zZBBS*L@ul@hF?vPv@eM|0uAiyzc|d_k}RWv&Ki=4{s7&OIZ`wlIDN00lKUU<=f##t zORDR6K}JhYNgCq0MmASkGts~&FUw&nxgSSda`-`O=iHebj@G4rCPlRMki(f&@u7js zVS^vLZc)uS?-&&KIDAj2A$eNXHQFu9q4LyY|3M21!?_q92!$AK&1pJD>TZ<9Fgze< z|FiJ)RvXrW%IK8CO1~{i<=hz^AcyVRN^LNh-)tr1@Y1eqeaArDq`X8z3@`24qKfYU zF}y*JjgFATa1X@r89w$wq#`!LEr!n^vXvb$HpH+sH$TGp7}Ffaensa2WjXxK7#Ji) zx0Antu?}OTq3yDKV3#1?T}s7)&g(#^>cb_*zg0PgT=C9K`uO=8iA}XaRn~NwflR$v z^i6xl3u0K_HZlCi)rQAmoeh!}ty~PL(5hQ$e!$>lQZydz{FZASVmCwE-T7!>a#*YS z#J018JgYqmOB~`0hHhK(f#roUD8~6fDntKvhzo4dtdB|J z0&=-iCzf-C3qI)rj%i==}JG^~Mj7 zMD%$`;^-Bl+tJV0WeD9q(yEK%CtO(+lNX`IDT*Ip$pzq-hK=(*lBCCQw=AaFs-k64 zyi;TTd#q%Prt{{a=&vg^Jbo`9Eu2BTqa@4F^eAnht742=eM1V4ktYv9-BL;?@7}O> zjj?8;yX~3V#ZhW0qKk(tPUsG?L4z!d`=4!5 zRrD9;&S>B6VCb7iX&)2B_x-(|&AH`2l{{+I)hUYDueP>bcwOq=)hUW?ZAC{Ria`?S zFpOA!d&TUBH)>&El=A>+FEImPn<=kH4qnfc3i<|#c z>lm~_ci~H~qzle*$lzR385Bzoj(p_Z4Hy}9&HcIHK$v2kY1ni$zZ-pYSP94A3R~>P zW8_g1nwTntDkYTMYfy8I1#h*8u{>x%W=P2L^C<|Vt3aVh3e|E z!-m}3GvAeZqm|EW_g|U^`?E2#c;Xnu#?td5yca0kI!}kus~@{(2akpNu%zkXVrdtr z*o=T|TD1@&F=II$F3+k;9M#b+MQ~Q6X+I>^l%B2ub}^WcEMUff`74T>NWq>1?ivbm`!Q&gu z1DNr6TsSCI>tCS=r{1yr-euG~W?hL|6n63d*RcO7S>Y`GknSJkedvJ(^&k8*`+XCS z`X~5z=5_o7zVSTk*Y)3@T`F|uo)vHYX137xAbXLj=1NT; zvP+{#AGH+9RE6(x6#Q(-nul*K(Duo?p=r_-UaLg*N$$$ks@K{yWf%=t40b@is=FI@ z!OI3Vr;Nm6>;wOp`oE4A75~7pbw97O>f&5VMngX^?jQ>|#yXsboUSc-U()n-d0y0caH+XGFSP%QCtPzd-;3HFP0@c{FUQT77fPCV zu6tm06__zW_PrFYOE-RUi;{8Ud{xQq1J+Co{vSIbPR%;Yk5-+D-k@+`>1v;oJv&e%VLloK@8Pnmlo{2Ej&4!?P#IgXB^CR0H8TYcONzEM z?3dZze}dEbI*B`9v2l-n?EiO+)V-f2at6xIbNgSeA1rg9^lFP{s;m5*rY~lq6IV>~ z?Y_F5c0|?g&MVR z;Kq`zQI!TQ<94vs;j{;aR_dVLN0;s5S-INn2k4<2vZVh-k1;vQPBohNSC=XW;zru~drc`##c6Vs>{{W_T2#O7KgO(JGo-$nbp zMob$^FCp*zAMK<7c5irSp$reb%=_5Rzht+h83+#bJ+#b9wrKz#hkZw#s?^GPP!BD$ zk~RH?_p(E|;zda_2wduWXkjl)Ci)D4eFwW;Vg1Jg|hwqqD>rFaPe!HQpDH>dAVYKeqZ|+0+#!-^y z1?L_F2D7IxcpS=g&9Ar)<*=3o&Y<&k`e2j3lr+Pf3cjbK8{17X?id#SSZmwv%L%Ey9hMz3C~a@E&w5=-Z~40wk1i$;ry`eH}v9}+C$SF#`8AgaQe7$ zG`|`BoAJFyQZz87#XVF!TA7x6VScW7{Z0OjQEA0eqfz(GA>3^CyD#klHw@ptdgtRYk+j0>lY%{!YJd=s`aXb~>+9Ev|5p!d{lH?bJ@vjAD#egZO6<199Tg8u6?7 zoD>IwTGbF@Yk^MoJhs+|2Ukhj6iUeiGPlw_U7WsOAdxLuCzHbgsq)8Zr*^W&wjHA> z9W#@~)Ja+(dPVDi1c&$msSN|>qWA{c7zx0xIIu=M@|qMp#(5stm5uWNP}{R@!e4XR z$6mN!?>w+Z?L6JG<3Nh;G>Pp$))^TwZ?m;E0KZw-$0ly2!pBYn59!JK$vjyY?V+%c zDF;iMak4aqXZA(^jS%-O!|D3-dX%4Y%Dw-uD_yI?6OQ=P`^n;pxQUvdN4 zTjY@m!};!VFC?(x*=+sOYu2PxrwC?7cr`p*u5Kuh*?qg)Bu$#jK$g|MBhJ4Wh_G=> zU`JKCy5LU?J;LG(IA55@iitinjXp)33R2tuW~>_{Y17%0#2q<|4Q(5Nm<&Gbec$Ly zDieSyHIC)wM-YhhK|-z=aF~V^K&Bvr*c>X=)4v;=8eTD0OHxb|7&B@gdkG;}U*J&C zfIMoBRxX0nKBm5Neve`ISnnxPFxvUlp45mx_u}uDxsXQ1N}3FLUa*h7^dax#=CL#E zyI^)TW*)mo*7U((**-RjR3^V9lQR3*ev&d24eU%_tI8m;?SS}YVIRBuffUVpnGEV| zCtj9mKd2FBW=mQ?**^9?i5(8aDPbO4(wqw~JCm2#E=-gOVa8thyQBq_Ww3IBd&01d zZ6s?3qLZJcT#fB9O!120>3llk0b zBXv5Fnosr+La%I03=Q&u{HLID_3OSDU>w7Nyw;cY$wH`fJoYyqm%2}J3t?&a!In7> z(c~0D=1x9vGut=eB~W4{_aIe1ELVDS>sWK*pN8T5cBysj^6G5;hmWOpQ=LKx^VsFp zmz%1)H+s+PraH*kyG8)v0BJ$Wfq2B{*HbroG)x+M~SuREA%?yJLm`>@K43^pw0T><3VzH!k z-1M@r6=P+?*w^GyM|AURA|CMTLMeKNQw)Pox-JR3*g^Pioa-QY1}Vh2dQy0o6g8gd zA%-*OTXn$BJt@TSuRBu2Os8S&9a1X-@Jqum)|%YczbY?<%m_UNrY$tEslzfheF48^ zZWs&D4Zr8U>-d_IAN(ZEEPB_>M!jITYwECyh4rV%ErrUa)=Z48CxsLLwCb!bG2EkN z$m2MAhgh?%9%48}3xPp{EQSYema8k~tGHck;&ym9OpMM z-eL43WHhi#64#Q*9>DB9Ku~)WEn~g1AijXb^L0)Q(b_c;A-;VLmZ9TeAwx4?4-w<5 zP+$F`+OT&0ptmIv?O;Z2+Fl6oo#bZ`_3&5l(b$nPqqcacxna|$1?MI0T<6qqE}Zu_ zeUY*x_CaWlJS|A6NG`X*P%*50H-pLljiMAc+V-Ew?>vZCu04OhpRV3>b$w~OoA)Y1r1;BDZ#V^OC zXdp)Vca6B{ea@A6iY}7M9t)h5{SmcQ76b@u--hjlJ`oEVZyqWIqk+*vOxsVUwC?Wt zw;+!TL61XXP6&vOnJ*E?(uJ83nZAt0!3S|0oSQqgEln>m1xpbNoonL8Ws)Y(DUA21 zJ!r=zx-80>qRr@tdBd!_0{1;c*xqp7gS<8_BxMl=9zxmpO$gp1 zr%-w?-c_#t;rE^uTiS2h{`h;^#bk1$zgMJnM|a}rw#Y4$OS)o%I^t`o`yyE;c^K8; z`TNql|EdRVq0?SHWW_#Zu3_W$Q7{}7ItB6&gltO3Ed2{)P3uBtvEHzKiI2K;H1io* zBhbd~oC@w+sTOS+iJV!)?A3Ifs^tq9S5A_;6*(UvY&t1%p(Jf1TI5GqWo#B9y$#Gb z!K#y{Jx9_OF7_Dk@^VQFOqD9+Yey7foP0_xy?-IKh3;Vrm2bC4hE3bUMfrq;p*z1q zbW_ANi?%BvQw!t-lS=DwnTToT^zOnYcV5d#+&yJO2NxqXAl3=MjKyE{4z`v_!Ebo5 zu)pfQgF$pa_m62qt|onyVNA~{9rsmQHI|W-%7=hk^3R5 zXmiQxib11wUGitQUQrgN>+Y0S^MpYDt!L_}01r;lb%%$;mg5v?yZHg}r;0U)RDxdJaVmqZS74k+?b8L`6pOGdOX z4!!B!>?OClyy@amB~EH!%>;JeNt@BSkN>r{e$zu{-xoda1MyIi8?Cxx*L_q)crAx; zp@A=?DhQma$;&w%tF|5aoOU=@(aDef^Uk{6yt#fuR1nxwETV5Y7f~MMn2_x|a~>$) za>{F~QTx2M7}joYub0|jEWhOgVadi`53}?Vx!>(ACagFC-CH7e=Y1hb8gFRMV&Oc^$ zoV0bOfD^-elx9pN6+<$lXnlO63c#)jO%3%u*7D<0P5V?>JlKG=;M1s9sw2cY6<;@T^`@e z@2$FbsboPm@s=T*zGO}AyX>20Z{2*&RshIn@GD(SkA7*50Eu&o<_kDByeA7MWOobV zG2WxM@7&yGjF5uSz&RkTCG0wXIc#$~6|tcksm zI9tEz2dUlrF0oWK?1SZTI*DzGHl~jDhb0=RfyV-`23tj`^r{whf<&(L(9+|m*Y_cb zEiIu>M}atD1o+yGW#n>8v@lLD(q*(2Nqn0Pk)`%UTOuHx5~Q;HB0PYlT`l5k#A@E` zddv#dj8>_b|4{gc(F$f5TQLLv=%YFFwFt2A9D3L90EXTm8|R^w-|7=cMej{xq;XqZ zEbU?=QnVhJ&Fo+L>E@86W9|V};vb8snTd122{KK)l3bqufd_|h;&=wkI8aNh_Qp$6 zu;+j>a0KQoHd7WhQrV%@gN2zmS^_f`AJ733Njm2_U^hv$0CN_9(h)z9l;|=Siz@N9 zR!RhBEFKjO%Fzxg15RD*u_;OE)bY87(lO}A@(C|0QILL z?7B+KSqf1_lf3+_-o9c`if%8Fx^83350%7&=BS}o9k7S2PKB&(bA9M`a~wJL2{50_ zUAnc6Bf)=c_Yl_aN!cM_HkV)MfKw!8{&x3dadefg0dp3;u$XH9v_(_NL!H)$0QXiRMtdCa;v-DqK@4Cz5AbO>6pDKQLTT9=gSRc8} z?t#qKVZ9nc^v!m;g|>1tWcvZB++5*&g7ACT$(m$f*BSHz30?}!9^hCkv&+I~OVMa> zDpX@na{Z0noB_n}!)srQESjZcwN_GUNZ>E z@EEIZweT*+29l!851lisqY;ab!hqQsv{p5bIP^elUjN`T6-OcN5Dm_GiErbOu*XTx zj+$`=(nPelMid}E1emd4HlZt@bE}lRQf85~o_n1fkc{&ciQNw@n}s4&QZNvsF2Mwh zL&%!3XmGJdYTBHAPV&F0B$;i!(cl`8NUR~ij00pjUHi*LDcU`tO5D?hWytccdm#0e zBwgC?v=QC=N9N zNu&!Z!UH-;5eHn~w%uGy^f{GIA%$aPQkJBx%=Cz&+CUQbqk-MU9muHh38@`g>Ap?# zEdAXs2c6F$o}Nz!A?FD#@`I=}zfUgj0A?(D(FgU6I99m_REbjuSu+oL-btGj-4bGb z8)>n!5FU&ezTNXqu&%yFYFi$1-APr1qCZ3mxv}!PT6t-os^TLbNa@U7w8JH(IXl`~ z`h4URQj6a~!=^nAjBpnf{+RXLePyM@Fip&xYnXKlw?tDwm=hK-9ViKP$Pk)O8{m-&{Z(x@!jnIx_= z8=e#lm9C(fG#LDtSX+DwKYRUb+3r-lKG3)8jjmkHI|pE>2~CwOKs;kMhQ6{LWKCPN zaCf`vfPS;rVKAznHJeWdmXI~W(Uq&2_Yhvj2}CLaLbwDnXBSZ+2w5UUqh*=~$+k$~ z4d^EQU`Hs+|0K`8Gg?>J)T*=7?IBB^Jy>$$1pfpk>1ggOc8C79D!VInc8tl|8i}<3 zNu3RKm@{pCkb=uoXZ?LgkT?;Lr_P4gn9p|S8LLRPMN;H)lGO7v+*tkG*@ZPFzotl9 zbmVGS>g<_MsW2iH5UI0s9VIoka`a8pAlY{HSo?#o$gPgmU{XJI_LKt$;ahvr;Y^*4 zO9bGlvuBX(V=D)w4>%fWwd&Z2wvsnCx0r1S(R~%w7i7aNFdl4XUfsp-QfJObx z*%J=&fNdh$Y36LL<~OotHUQ#QkUD#$MqHaL^=6%G(23RhC>YewoNbIGEq#6?bmVHJ z1IVoWlf=#h!Ye`Qtkxmk()S$2dSA!47|^~BS&_%^iTvNWvl5B?=otM-T)DF&onMKZ zJ6m{2G9Qz3XZ;&t4_1s!+W+Lv?sb^Ykn2N{ggZ?`lV|;PA;gvq2>HdnWIz1L3nb%l z`jT1pY@>hReLR6%tDipG$WdYLg;@In@$^~Wnv$18BqK1=^jZF_zpjb| zZ#@Y<_48-PIYbk&4@XC?<~KYd)lic490>0TDYP#-#5=@xm-QltwobKbk`#RkOzP** ze&`UNlN2jDNEXIA`o5=GHKyFUFjtmSuZkaYgLo5 zcXwbxIUJ+m>7_j3#6aHJPLd|lo@-Ht!!fEAv~WhxAZ>o?XkyDnJ6Ge(tp4@Lj|{6X zw{=WKGnTHyFB4P;*#%2v0;HPOzPtG?!`R~BuJUNhqyV~!FBSm|MRAg^QeN94L5?UcDarfcD# zu(aj}No@}_F{NFr+DvXO1OhvIOgE~Ezay82pQqh#AD|Cb-!2G<(-+bHuSn$Ute>gs zXQc9LAV!`?yNmU&cfCN#QRbjlHB7%F8K~{qsPNaKX?25lQgj~|nJ;+g=NDcvRJ29| zb?#6Ny)H#Jl91$!vWoUsFV$Zd0>r049A+)qSaH#*nge|Qa7g8VYz84U=J{!o=1VFo zOf~zSB*8IXT8yuCu*b}=DS0%NZjWSjJcyMLVRQ=|B?m}Z_9d4(u6p1rNLpZiRfj`7 zu2+l)rdk-XbB09=Guo35aR;#)FVns|mvGO2l8v2#IAstmJ`uM7m}_4%u>=D!%GM5X z3bC24P)dgml>Ykl?SVL@rAD+yN{PT+=@ygP#Q=EYV{RWbt08g?2&#jj;f3&B}uaZX#XcyBf z%ffEN`rZt$?Q}<<-<*-3>uPwG=FFC>efcPnOh3w3c_Zw4YzISamqb$08g03nGi7r&xg+1e zJV(h<5}OB@i+!o#+1UFJ2HFw<`L$2ih&PW&(X1PKuvXqGDjK2m2HM@Ov_0D~H&ML=FU$^`o=0it_P=*`vw3`__;$2B^C2oC#}{pbcmGyt4#QXL)=QrRswQGIF2}i061Zj z8ZqoC-{oMZS*Nj_mNfTeLMX}pI&S=BYVfUVP=n}nsloRCx(6gN_db2U{T|}|B1UNj zDz*H^Uodu;7_pmNPx;NI1fP&dD-gfzq^&- z0Ae`>$cZ(MlFP(02v{z};vFyLK9Hy0&{2}EU!M+$_{Ldyx0qQAQei;@ryft!zY=?~ z0oXs*sjj~*8UK)}p&lEXKep(E)~PHD zMEIR&i~Py5Mc7XCknWC>=gCqvL6bs|=8=`LK=T*5rV*6QI?`G%wJbSyHRF+?uxYY( z;gqbqLj!hcb}Y{gSw9;|BdPdB!}`0^;q-v*dox#SrwJZ(|M%&rJ2+pfkQ_{lRU~V# zUXwHr`F0g2?2+_@-61Gf+e<5tN5L2zu{B5#mWx%K?n8V2vw?-{G`)Aff&6=8wO}F; ztNX~ggGCZhx;B&r2{Vmdr@9nR#|pmAB6qCpi7QErrdPhi@)ZTI`j!bB-F05tm7C}d zXU1dajuy{Cg*;1|^PfC!2n%cCmI<$=bl>@Gf#sF&<@>>wmWD1P(~@TVCmZ*&8gc(M zOnfJ2O&aG(lICxA8EkH0|4`AiN#tN8zkfb~a+EC-->}Td)LiZTiSl)@yM_HjLlY-? z3Pw7L7vZ_pH%`Rj!B}pKlI9=!*)iip)D6y;R`ZIY&&{T!4YGpKj-Pr9uS8e%-giDQq|4+ljldD$UQ;&`BB`d?OeeY;p zv%x%fC>2G$)a^E4e*ZO07;DTQqju82?(J_ExCWhui7T)GF{h^F-n$gahKZ^NJBLvCAG^f48ZqY(3g=KBY)7nN zT9Ml&uuK%N=n}RP)Tx40j6;391gdt0td=x&RB2GV#5pV%0NgIoyhe=ugYVU`Gp^Xi{;P56&lqM1Xq7c4MkAzw!_SKlxOX<_(Mu`C34wf$SADaYm0LJC+f+gG13 ztZYi*e=HKH+%?D$(4xTGxxD;H$$+>`Vtb7^;;9r3ESs?M4V{7tye-B#VL>rUR@y5} ziiSshz<5>(huI|RR8yIMo$Y&3|EI#RsdGUCI#0IUUib<9_W0VCf~p?0*N66EyIrSQ z|COW#VzlNO@mp5#hwrvEcMLVn=ul3(tw!{IThijm$fdl(7tsg6C=tna=MhEnX1g1! zR&+QgMYxFTx^(koR)X%gg zs5|BH(~Gi;0k(}BJa@CMOE+(NNvwm=&$J|{JDF27{MN3(&-p-N9AXgm{lK#Mp}p-} z0QNv)9pXYdP1XtHL!GMGuTr$Xle7@Vi|Z|Y2?;_I)5mqH;Z5ba*kcw`b)0#CKTuX; z@z7jsz5_t+Ha?8jt+{U11$Zdonm?S!Q`z=l#ZE9l-gyV8AFs8xZsgpWp`c<73c@*c zufK1q;dX36BYA7q)?r?1XdPM5h(2X*eCT56)UP1Wc>{B6N+!ffMqpX(o(*=rC#YoI z35r}=cg|0|<_$Ywovjg@P35=7l!U}l#L~YgSH9kxlLa4;a7M(`fUxYZGA7x`EIH1gy{iscP&v3hu1^& zJ>ifBHgmpPltCPWLy}Wv`s?Nhth(FGtY?vCXQ$0hPDHcnvuu#zO z6Wb0zSqUzwbX^cRWY41b1z9n}J8$9Lwgw^epqHHO>q;@qhbBB;6wx{}qV3Hn!?Bn* z!+wrMLT^~McGWM|)@Y{nV-2cwFEk>jm#8N`*?@YsnBcLPOty4qlveMt(Il1Mhl;H_Zo2;3%-&y;CqI)*##hC(~PMRi@HeK zQ2MNx{q-ENwF2U#)K&IcQxa=t{mlAsG=^?U7%d!SFfb!-D2!4w75HjTYdKKcOHttq zsrePQg`$#Ll9a$|*T@dCg*TmI0u>mZlf1HI^>eaC7vi|B$hQ(P0w0sSF=%F>{ zi;ZcSV5e*B6e)`4#cPhmz%v&1K++nVDlowJ5zV!hr@zoq5<+5w&?{RWW*C~jRshJR z50BW7MBjqYUYH(K*ClN`N=Z$yhint^ zHz$OT>lm?y0n2;IF*99nSBo7nQlZ+@K4y8C5)DxS>w*af8S=LC<};Re{YR>z&fc<2e%e1B2q9QoB4i+dB1H=N2d}D z(0%*^DVQs047XJuq94$S5;G-u`J@yK#3|veYDhMQ0CUU3azY{j7$p?s`ZH2+XG+Pu zRf$Da0GtrXe7|&*6_yT$tdX|c=woznP_-gueWNHHb5Ko$jTDFz!ZGy?xix|Hvfbd5 z#Zoj7BZZ1=ZkIICl$04?4Ti@{3II7RQu($Leo=OqZ}OJw8KKnGXmYDp45ehY*N%j| z1l0Cuj7EUG(H28FYt?r=YA08Filx81 z#?qjj#C5NcvYB1kZDZs34GY@oYSD%eeJWa=V_DEn;<{BRmyK4w8c-*bxD>tww8&@k z%&t;&EaPR5!Pz`b+YA*s&>*v^5^d}($m!Xs{0uqP&vU>=Wbb#AIpAQPrkzg8ENF0X zm>dT$6B;}=gDJYEq^w0ZkIi7-`&NW}<7-DGDV__BBsJWAyP!LZ7oiWzZq6Z==D>U^ zMjCzAh{P@gk$fe)xtQFK@4-aI9ur1`P2c@g8sEb`74yA&OeM1I5*$xokk~?W%X`A* z`z38p`9|j8MvSv;BCzW|?)9bL55N35y5+rbiE?xG@7^P6ddc*s>4QkJl>p)Iq@{g-$G)? zyGK-skKj`6BeR%F2Rws23=OUszQL-Fa}IDvZN>tJZeCD(&16X%ClgoG>o>LC0(Q|p zy5+w6W|Vnz5gI8umx1sRG4dkJ(2D#M(+s z?wOd^B}ztM&H)~(X%pz1l=qN7RY{tD@{Rb=C-Jo{7}&{NTtuYdz?^sjz0(fl@?6gm zOG)MY{xXO0bihaCaw!^IPvT*Y)Ek(y*o`U|U()MyJt`9G@BuRMc6#|}I4aTLB922o z2rwr`21>ft?@7H6F$z@;5@ZfYKtYC*Vc>}Zw76~|8LnAi&SG?p*f52Di1Hab3UR=j3sS{)PoK8>HxDLe>msys_70QC>8px$N>S zLS8{TXMUZBH0K&y=%rvj8fR`6A3&p;w_cvOgU*CM)o9$e>|ymZj*=o!4n^K=M!_3Ji=#002!rMdk~C$Qd$*~?S`5f0 zfLMTSYYTV2Q#NyeT=Nx2gGRS)s)QcPG5p6{%Rj_ zyntR#d)gt6gXcDx(z4BFFWUnEM(U^$r~fS(Ss!!w8}Ta|K%5eet}t7^=+vm^k4eD* zj1YdV9mFylknJ_=RFywFKLdLV43_tZ|7&JSNPnGR8nL|&0K%#m%M4WachpJ2W{Yta zxp_9KRx^|6i_y)m2~XD-WQ}dOQ;lA^DFp+ti^9{@oJ5*gA3b+(9^<|ytdnp1u;L@K z$A2xU7(7D0sD4J3_{lUnSl)2Hp@QZ_uczh=JKp5u!&co$Pu=DOg_2y>n zH2eyIuVM>67`LxWZz~z)-fj*gk#hmr#4Bseebc4jQO^CQzwe8rVgMk&XSlk$!wQi? zr-u!vTKz7modm>a8zS`X1<45LjF}41-DkOAoEWypcZt3AXiCg>obAb)4}cgkJYD;3 z7g--OOLiwxM<7lKPuEIBCysF{%5Fr;0APf0b*Zr#1(XloBTFR_h*QGKXeaiU#xf0b zv=(`!ts_>yCuz~ZsPRiUtCmw?f`Ve*!4b=BJJ8F?hruBH|c^_65Ru;#N$Rf zC8i_gd@h!F!fW#Ah;6}(`~uKpD`>KDFX*w~N!d;`a~;W}qE1yCicZcXX)mK47lV>~ zlO`KaG(br%CH^D$a41QZZJcaxj^Rhh#>uJ9>E8&u-s>WGWAGR>VrLEy=F46ebM_$_ z3vYg_EgH@2KE4hc-Ro(o#WG(N+v9}&u1{*v?N=Q~Q$h^0TUtRJ7^MF25coYk9< zH5Gs^i{uxmkNUEc7-q-C%;F^LNBsW55OgwHL`3=7N`T}*fEp6__CzNk0-~@3O#;r< zT%aef-wBxx#3m}x-mH_I#*dOmw=${HV-Fmb$L_ZLOs*p9H1TJpU;svmh$uS= z&Srho;e&DpFK0QgiHNB9b5bxc_w(E$_tO9vAp%pU!y?W4=z07aag5J)62kUqf*uBz z736Vjo`D!8LZVI+M+er)PUN}NFgXdd>;=0FlVgZ_z$8xvdClm2$ILD{TKC0i31vvQ zUDDroK5Txppa{EV`~pig+1Ls-NOBQk%ANL2$g!iWCzmSZRU0PE235jbv z#d!mWiaJLsdIHN@vci@Nz~+yz(>xM~DkCl>>91Q&YCoOoB!>Mlsb~(MtRxrMdIK<8 z#6+DSaT{45Q<7I~6JK%CAtY)xtPsF_GpQi<7yw3y1N#(meHoy9C~prD%5hR6p<^tn{roI8@n;-o}O)J{_S9!` zvOabyA7tB~>m-B)vO}H}4J=zH-(ZQ+j1VPnH|sS4tdAYa!^wSV8Ytb8PYi6;d7#&h&R&A070`rN4(vwy&i7cJPj$(9#-JFH905F?K zI2~|Le^qI9PsIEUNs0&NEEdv~u~*3b1owza^BlORff_3B+P+sy+%%TqfE znDaPAhoGGLW6u$3wg-TW#TnWkhqLc%9vpr|>>x1b(1wnn;{m;%B|26TqCs3Ho0Bx61nx z_PoW3?I~moj?nHisP!_}#lSAUPd1*PYcWcJs%24)=@oo*pA0JS9PxzM+5;EkyhtDD<0aC`g&r)P>YffLKm+ITA?0DR zz2P}x5ea@5n6W6Q{a1+nl{^m?LBvu9%sC*}HBCE)MDFk$v4Z%22h3QoT-OrZd%g#Y zE~FwKn6nr|S^P#e&UBBc65m`XS%4Xf5p+NVNt#pOVo@c&x<=9ha~7NF2py@dc8{>* z9Alv)7>f_+fS<_yf<+!I<|j)=V5ne?T&0H<711q=@+K9FX%APw%V{OJZK>hXv){?q z=ZkJNSvn<0(`0EBRlqZDjfGO3irE*kOF;qKXel^amglPNH8i@0-o3I1Ln}$#6twbr zUkkg@tM9d3?X&=?w{s|J6&x0K2m8(}v`LV*DDX&9&&Rp`po3P9w%6|-P_uuPUSgfN|1VC}Pv z&LU)#;n$J(OZLLJ1k4%Cg_IcwVsS)^OkZh!f)MNF@@+`;M#mF-HX5+GNBR`3A9k^V zBz=k&&g3i|GgseYI2*&~DfS?>UEYwHoI@ajtprHkqb{>m0dQifSdFJZj27n|h`$p5 z#VcguV9I?7@{Q2o8n9hIt}ifWk;C+2n)HU}h?hv(B%91)8e&d}ttlXnTs=?XasfCs zv}&5sK;qV+#l`IK40Z7Os(vzo12C zaL~MUzqDeNd>8)oHmgbSKWK1XLHv_A`T=tmsq{^J{IiE(Rf!RgCC%G1hY7T3oPS?H z*}t@YxZ6NNRjDzHY)nVDi@mS@Zs*l9bp^dXeq5qC8e9XC$@LS!{Q9)khjs&zqCH2f z!lrkP%mP16_LNAQ0A+VmxGfQYQ&TN!{0Qz7w7B?N$@Rx;WolMaptPZ6L4!P?N(}vg z9opF|K(!B=(_`WFKx9d{PAcDcN9KTXA0O+ljslcDPdOy%cOa@^<$8pymYTs{E0MTZ z+QT%gmyOoDy^M`0!9uZ)UEXIcRj(*Lh{4y1?J!!Q$)R4C(qgx@XK~se2CFz59CjEs z5Cw`4N*H|0b_F0^3H@4ThR!S_!A;P{mWOXJZcRdtw(a#f z?qRA{SWPFLf%-rj=SNj%{ugjKz3ZBzUED&XS-^}Db2;sTaIyhxUUt}rA`5{z3+8j0 zK+!SO|MAw7);X$64_Z90%cWO2dK^ zS-8p3z5#umSSpcmnGvFlPbB zQ<^pzr~3EZR}tsh9sn{9r)mFIeZGSAyF5>C!T^sJ&I39$UF+p-Eh%wL!;Zstk^z`8 zq5db7necDH2FTO+2}=zyXTkhW-xJ%R%^uU}Ly~R*GZs@R3m<)G1J41c@K%613#Lf_ zfL(Em$1DbuxF}%8f_kB}2Z_Cu4RAe-q+P(A1@l9_gR|HN96?e zIUowN0QUGcQgq*vl(nTE-^Qzb4EVv3df&!C5@#;;_%>c7jy}MACd><^)wh^k=J9pt zai#!fGhtq+e{FNh+%q+QPl79fIR}6GZK(A_CT?{-j!LtNIIO^o19e4dk-M>n4PcL> zN~|n1+^5w+I1lEG+5|)LHuqJ;*NNpSFyk?v@|aDockmpr0zXU&%vmt4dKlB#?wW>O z+zrz?Fk=CiRJyieyOhWV$Zy4;1V;jM7H~Dp&Qr0AU< zvsh}g12PUU%F-=xh0fi7SoD`Vu#AR+oh+kaVcGxYM*OmW>$m1L4TPMxGW#jM#P4e0 z-z$!+ey;%Ut!(U-xp&8>LKOdC4m9YBtcV-DM!_32_Nk)^A^H#TyZ5_Tg#wz{fYQ$LPY(Qr810Jx zEmH7}T&h{yN93nV8ezp^`)R3Wma?&j`U+^wF|AT?ofT`IpR3JGkjHbsmx|VEMz%(B z;z5Ly??(7={agU}z|zIF-6@S6ZZL<%sqiudaDm}`JCOIXpwks?B+ZB5Qol+86nwh2 z&qh9uS$oHhrhw-HFjrVt7VF5i*3VVL{vek3_xwLH0p{Jc>h^dTeOL8$8U$Go>S*1> zuRIa~CO(ohd;cdB0BK;4*SLdG1AJdZP?<9k06Ab+Zqw;GBT`2+JZk16rP-RgL&5;S5-e>TUeyawQnl&jWz#3>65P zp@ZiE^vb6@IGzW9EZRLEQVu*;bz82aIS2;zixa?qcF1-D?K}!0pZ(H1&jR=YNwH@+ zJ@uYFJ0ochfxdoi0{GE>PU6#KDF9!v3T8Y5010C!`tm+zBu?*%ZT3h1&jf%~MYlil zv=vuPb$%Lh4C_-{Im(r=5LSQR@wPc1|4;Zo0{kZhNqs(cy43=7&9eEYLBs#yRvR>p z&c_-4zZ|tjKfx{4uSuY(DH-%0pEe8UI`t+6Jp3QtwTDM2qyhKrhgc6>mo%S(NBw#P z<7>owTR9KrWSd9q;TVM%gYf^f8u9dH?pJ6vc@89w% zGMjShL`hQx4*yB_su9CksFrM7ZV4j=M)6t%BWuLsll(?tT&`11+9YW{1B?2l2oUYR zBAQ=_<=w8tP6wlSB?4sS?jpyU0Ly7y+LlsqwPzle{QDSkfq(i_vdTl0TSw}5qfz_4 z5S#E)Yue;;yQ%P781!d~lC`h0tTU`Q*om*CA^R`)3GW*vJdiY>v+?k|Az(~{-@}l9 zfoarW%89OF;D4R{t_ApiZIbyzQPVUz_wQQFdrW)y1-_Pl*TQ&lxTHD4_*4HI9nXK) z0+Vlk%*me@B}i|czl*lW3feDBW+#^<_}-TP1?^<|xdWmnf%pQ;6z|uoI4#t2t?F%3 z5rJ;Dyut~Wt}Xad(jKMM%nA2>F-#tSbmJvgBp9tr8b^i9RWat?$4;4()$xb_Saqxx zNGeUtI@tx6leb(@w5{=*0M7V?0N)L@6tSzr{gyLQ(j0ec;Q-%ER&jvO9NxDYgtenr z_P*V=9ROgI3u;Q1d?N*)ppb}fw_KtqNk^6 zMmV`f445lvPSY-$3!q^6kem!&x9v6jax@CImIU{~I7W87M*P7?(w?DYRIQG*xMvB4 z*|2~@+2tnS(iq6-;BtGNZ0vcKb~0`HbRD!QAb*{*%k6lR(m$;cXFb*EarUDiu8@S$ zx^4}uI)_V-{(;>m5T7@4Y~Qq9b2!zfzwSJ-w*X`_KotVSPY2ex^=AZroD-1K!rzvP z9V4*pZ`*5I3&2PN93^^kJ@y! z4WB6xr-Z7Tj1vj#Wihaco26(VMv4LiEyqZjOOzD;wr48u&*sI_Ul}Vvli)MFD(1=B z(OoC|;m5-=+TA@`PAlN~pvJo}Q&8mPDAe8=S&bVxhD6Q^$nH3N)2slsGjevCMi7Lr z{0R*=~_$G#I&Hluigskaz*&-oYdlSX3T~bDmezM%P|2p8Jk?Tbe&PyR#19Y z_Tp~7_8%5Dy%{x4BOZ7+#@lOLK%w8PsK`u3%yFS}y4CMWR_6(%PmkQ@$)#Ov3ZyH= zT)Ek~emxoQo(r0TMdxYsr@>=7DbHOg^t;(P+pl>}m*c|6i>-cN-R#`!xG*VR+K9h2 zo~0KIRk?eTDQ&Lir-Uw@lzU&`q(62A>E>9g-`9+EU5d3c{t}e`oBz8zpOaVmfn3{> zlkb0qyS`uKcNNsfgf1j)JpTH>64AT|N@3{A)hxaQ@;Bb&UgS9^}JYjKc7*imZO$vdL=tSXbh&s7-S(cIR`u*%8b`zU8BT z3c~2`T3P+BG3JfPngsk+&os5b-le^KR}VqCrU$1ya1)e2O}6@7XV;0lAf@B4dTxUS z_5mk2<&wjo+&ZPm?^f8Xg>8Rrk?ps57s$`|wEEp((v}Gzow3g9 z_dO%+vDDfbf3?jCRnYR0pnB#Gk%(DLzkuj z=9Pth0Dj_%F7}ox+qR#6?cD2x@J(5V@YoJN zPFNZ#XjORyKjj$wlkUBj)#BIoU4_7hKc>9cX&kxH(yw~D(zkD;KbJ1a$ZRO+6{f)% z&4oro!`k#}*hxt8GtDZ`AEhv>qP8ncib6%TVzuI=V!mQnf>H=8RIE^}R_@P>2x;%# zYjLmgUJE~4A1$==&C6SO&twkN^;0SQ6e>j^#z*1*GZi|;;C=z-VJacsjK7Bo5#9x= z1eIdetTuwhuR0;(O`%5vLHI&24HLYZJvIeEVS}BB@8ExLj(^478)yjMhdfpmxNp)6aSrw|Mnki3d(C~YHn&JG|USY zf`t}&VHqubS}y5%Wr5Jb-;_6O)tV5kN%&qB=>2_ypnTB4Vr z5LHH?Dr1;JqZ^ViSkU24PAW==4e;Kh2wEx#%I)j&LR2bKf3vAoUV`9T9V|3A1q&@r zE%E}_?&_dWe&4`kY9=(!@cG)iz#sr6?)bzHrUIK{)|}S9=f!`zUTId=z^?zCy7}IbRsz zbL9FApQ*(@$|$^~o2k?Ce1s6)nlFSG0!?#^V?#n`WkmUwD0|LwRj>rLBd_I&W!LPej>Ur$#y7-HHiHLtOuv~>fONgbs&sf$(BNo^jO+9``w=T#+xI|x40l_f24^-)bf6tWwe z@^ac2cSyHYKkN|nY`#fovL{}*yTRtUmu5Gru9(~1>-?@)pO!X{Oc?cV=-v1dLGV%u zr%P7*HSqoFgXwX;hvFA!n+3(h)!wGbe#)J%{*$jt(5f=>OoHI;Ge_w=ILs$MWK=%6 z6cQU4Won?nQaEmDmJry~-01he{(V;1F0YpmmDgQ}!GC+=zbQimbN|)4gi*Q-!6$zH zpHGDh%rNOg<(B+y_hrPUa>Wx@mz&)v*=^5mFh+VI-T%VseP>R!UjJdm1)V?%=UWa z@&S+M_fiH7_$U9UN%t(L0WKLbE1#?$oEUr7+i#H}uU(!ouW4Qjp=Dl5&u6a)f&O2_ z3gO!7yrNR?p$!F7b)YG*y0Oqu=qLE)`3Zg|zv^MiLbaf2R^2$SS+%Y@u!+yhK9hdB z;3tIp=8eDUT^y)1s{}7|u0iMt-L&|oH&$bHjDb z1obS4?KCK#Xkox8Ata%p-V#x4GFz6dp#d9E<=dx zZ5==V$_F(zccS}_YQ=V!3)*a=hl__2ii@epv-h$E`64-P{`P5>)QlXgo?$#Yb zxp*_utoJS7oEH%}IC7vVKK_GuX0$Mbv@KRdWHc>lAt?JkuYFP}^al605*r()J%5-H zr3x=@<)@mCm#xYWGzuY5tyGu~2#Ov(Y^&b9hYuwnAUyMfr(1U@gpFMS2fwMr*Pd6~ ztyECp`hg}N<)WomBkIEDH1qlX$8JO8F&|7iY(?N4FOy?I^LI;2hY2m)zx~8}5Y*Q+ z;bkb`9HD$$hHt|W4Tl#ue1F}r`9k^tAuk!vzu4ey+7UJ?S>+e#_3!iNb<@HHA;kK! zGPU_wl~+H7!enllsEnHFEhyG{2b!{C zLI$P}D9(FfRH6=&6QBR{JYh7h^FqS9kamKyux&S`G9z$Tn+AUz7%8-9Vj5`h4x8On z5DdGT`aFsEZa7@u_v8Yx+VEME0Iz=%`Y5V}`0or)8wWJp;3fElAWUs^!hm5Z4MLVIY^c-=ZTnYGxV$!ho%tB{!@)vEVBUcE)f-z2o%&bj zO)K>#&l@X*{82ud7DBKvJ*ODG>*ALB4F1a$N~N#g>pm?f`*@v4bBpG4eWn}MG#Kin=QR<8En}xG$q|%G=cpBmFlCpQHJa5XRi{}( zr?bMG-QGfKUS2g+kT6o0DMXtB#tBOc8wg!}@)nsspBlF9YNJ#CoW4DNdfB3q1#RvG zO&mGrX`2X0`mMr{J;0F z_QhYR4SWOgG$DR@4XRZo>Jn9m_pgG|r^LV7Z+uFwd`A zB_u3Wl>}t?SF22!!9wd0pBNwIbmcnbV8uGcQdMw{GxH zyt4AnwMPB-o@+Zc%;$;9RNPgqHf1OUvrYl!9B6u^%oE!6%Lrc=Hmwm>c@okzIzchZ z=iMNMVLldyAqsC(rnkw+Zzf6 z&oY%qGfK9EZHYK4^ymsD&~C((TLS5yCuMr~3pC`F4E9y#o%9LQb@IxdbbLWx-q=xs zN@#G>$8X{D=RXJ`5x&ZTkf;Dbu~-N%)HX8xf9$pB4P!*BEp^cect=W zeV^aG_kBOV_x^P^pV^(6ojr5P%-K1!GbbpD3t^tniU6rp2Nang0zhdH42^(;2%Nz- zCNQi}NM%r)9NwjfVq9s2p-04zacOupO`sqpkD`?fwgy3Gi0ee7NFzR_%D3Q25$0Mj zQxbpyVnxJ-dL%56M707@UJh06RPJJK%dzj4GJcn%4D}!Jd7U9?{!`(6>Eo4BJ`{a0MS7YmNw5$S0Ha0hJ}?db&U6r2nWL= zI!3EdAivpc3|I(QtII46m*qVWk^os=3XpkH3^*FI;GoQOSE&1;78J@-6bth43Odk7 zu(c6ER8kNlo~g69)r7UnH@TL%)7O?=?o04NoDeR;Oz;H+2iPQi2(f66GbE2WY5pS`lnhXUuYW(|QaC`!FKrqISsnn-*CU^mVnrFTid2|CjhHkQ zwvDm=6C>sm7d=h*l917-SfNM~iWafpU`-m(0mUtrz$OR@r35ZP4XH+O;@<5z)boIW zTjC}xEe=&4m;f8x3ZH{Bffdfo<;dFLc0doe0y;numj}u~(Y_syyNuui7VwT0%rghp zKprUg&`?J>98`#s1B%Kx0lv5Jylyxe^eE>9dX#&#JdNo^HYnrV11jo603#0htU`v! zJkW;@Eg?x^s9=YCnTTA^E+I_&#pOr_Yn59sQpKzf0VG7z8w3D95Dv$O zHt@`bn%fds_~lsu3m*bG9cEbpM_^w?B>4hgU<677tDivAl3`A9quei*H_kyR6LS7J z`Q3e?NT@QNGE6oFwY4>*+CbMDlnUPkWMPrs1cK&f5a_6$%$_~9wY%Fb2tpEkLHUHD z7E(NNmrnq*G&muSlZav{AX)gtGy8%|eF%irQWhi;IW*eBH^#zKR$eM&gP@4X2=G!I zLIFpa85|%VP2u^GVE6D-uprkr5T*aImry`p5CF6;c_a~uL69d1&>@06N1X^IB?a?( zc1SV!I({>FWPzU!>{wxkNUMDdhWu2=rB(;#p(G2bQmNFvH&zFN5b(K^lTx z-GX2tGM<}*n+_B z$A9YzX9jdBNFZW^V5}#w-@sQFLgfH&;0b?=pzu6EAWZqdtD6EYFBx@U$|7Zv0tS^` z1GE!~%x|Hk%5y3~O~P%Tsf)alW>8p8gW9vEIcOpd|vKLEdn;dcOjLxi{Ccr%7y0r*86 zKZoIeF#H~l-@)*k0B;lF%{YDq!!L^Pa~wL*#_@Y1{0@%a#PDkXZx-QKaQqU$&x!Cq zBK#(fU&HVgfL{^emoU5m;J+{`fHiCt;S&I#0{Bf4ehtT4F#IaOFX4CthSvjJ4Dcd= zPhj{IhIat`nh0;f@v9hqNrX4xcs+)TF}w)FCvbcU$2%~*9pEh@{3?!L26%%Aug7sQ zjvvJFA{?I(;Zq`9EW$f*yd8rBL;R`;zl`DM0bVb{4~p>L0Ph5NhX`-SaS?_$0{k+L zpU3bs02c!MH->j&_$`39i*ON+H)8l@5q=)W&tSL^!++y=Cyw93@aq5(7zsHd$i|`vb z-iG1L+yoGT;pf!M*qCDnYZS|>#+FxO(FIs!EEd7V!r53T1qrt2aiD+$YzFR_ z|JoD7;FJe|rUWhzM?5|VKmbid#S}1_NFJkMRE!SfF=jPJpknekUBo=8z>%Wj3K$(z z0J88&8lZ>5DMx7_jnnb)ZbeZmiUVjkSZk@3+}ltzZ~y~9n>n5c=7`_~N@%ENpE|$) zPB1(L4{U{|Y=3WX-~0obA#!rhG(#veEBX8SLk6~Si{=+m3e-a?2KqEYD(`XkhpKN~ zKq-*Bw@rQTlf6NqTBY#Qf!v;%Gqq&5-g(m7uO1RKzZehi-KU0B3=GWYX^Pe1vIv^2 zAGI%DUTzzXQnc=sL)=JkCI=OmA>VXcmNOIA&Si=s#}=n?CHucRnN*F zTAzGg+9TkeYPk|-W2&h7T0Su#Egahty*MDRtcoumFtf%k&SvA!<8$TCl{Mxe*DOz; zlh-ye&h0tZwN*ESuxEDOpWtH)?Ni6>58QlNx+L`7*%2gn{IZE&Ht9g&ErqD<>Kj{R zl3c=DXN*7$em_xu^DBqH?2;|z`GTRP>me0701JZij%ou>D*0AmkQF5#Qr|&TSkZef zv3{d4-*UW6Z~1aIsY_l;pG*ahA|Jn&Rj!-pFFQDW>_&Kai(&qm=pF&wmeE~N$Wng1 ztMh4WRqFcdUpoRXmZkUZJf7N@+vg@-TJ2T0o@;C{ z5-bz=g|&~`_jbd+V(GBZ8v$q6U)sNB_G#Q;O*F3+$1OFVOAk87S2*Xn{Hsm{ zscV1DSmm?FClVZN0ygA-AKPSnoLR@RqH@ zee=)N8BJo=3o`#4-}j(7>mq%RvYF3D0L+29SFc&;1a%)z#}~fS+i`TU0&7;3Seojb<8a;oQF*py!{(sZtjnPf zR~0@Ua5@!wxL?2IL*`;#ilcms7TUfb)k>79Y_Z;xa*&#n)_P6Avr@`GR{OHOi*ft7 zsgI9QhHrlrYmr#rb%Rs2{q@&M$9?7|l&sV#p+N3GJFuqlW_rBQihA9drgGZ!iOYJ= zOA?iK`P9+Ao;h{$K=PX0=YykrFXcZd+@bbc=XPwPC?zX%)M3y=^=l#ZHPO%FAP#^b z20uiIDq>T%g2ZI|HerX9?xn@UX&?Qk#Me?~tejt{bA7JG!RmTnjorxKFq`rG<)f#D zUt$wq%)c>)Xcr8zbe`K~?d0vq`6ZOy5|lH0L+e?kkzqcq&~#1J+!uW(AKJz7US}q^ zP5s$jyo$Zjwq{KePgd%%`Z2RmDUBtsu!+$?cC&uuw$&46)pBx!8BK#SI0lF~4rmzU zvnXK)Q0`jbThzIL?la$4p{Q)DuY8d#l~<%te8=~$&%%X1JRfmsao7A_d_U~%tiZJ| z>kCLOq}5d;*XAdhsg#Oiu8@8cdgZ+r?=jbOanTJ42)#Jy5GCvLq;=DUduv*!RLAXO67aw?oBv_`Ob)MOJYaUz1&VH}6fW=Lt0FkS@9K8#hs6N?Q)B}?-M@C zw+_yz{u7bU>QjC69IlH`7&g6Ow#0EpO^I{$(Xel~n0MWt9kld%O)T|Kl6gsgL4*u= zZhWWf)JOY8O~j`?FK5K8&%Un}wf9AJarKI$b*5kBAMTR%y{p%GJpY||cFAIoF2hrk zdzu+iq#N`%MkfrJ>$8#);+BnG`&P5zaa!^V|B(xcHOuwGcyF^!wticsl#Ndo%DfBZ zeb@ncP7{d$E%plv$$mydITv*4_~}4|JtorI}70a$a}f{bjVP*#1bO<_+(3ecMl07mhT%+ZC9Q>!)q_ z8v-BDmz7=Z&wPlawZ8s!d(T>{5aQeOb!ykK`-Ve9hqdbbSEzigz|Ezr+ib3%LUx3d zwb+%eRtdB>+%Ai2hfQ;Jn%m};r5*LKSoyUeOm^wl*ULDS!I6}g>v6pS^?==__sn)} zxsZ7^as7C}=?8JD<|>yf6lJ{n7sSVtKP2gea$bTpcS&+a!nwwU%Y&=s&zyoEdWtHv19CGmqyiKZn@HVrLP9!yAL{JWT5xa7x?M|6w=v`IZm6 ziayo#ZXTRHwjx@L2#>$W*edjYGJjmxJ(9sj&s z30gL$Z|sI*ePG5HWZ2IPp)f=!G&z>v(@17JDOyQebfsn#8+r%e|1yd1ep zcA57=$F+WoLDGxrq{_gu)I^ooN6lj8N(;5MAX1Yy{C&yTr(RSK0)At?q%qgjbk)RE zvwQNj1rY(m#_y3w25xH6`8_jBt`N@t<>vbWl%+>XOu8~&Wy^Q~>Fx8mX9 z%R?!QeFocmn9W|wN9+pC?sekfHw_}M-d$h!`)&Bx(t|oj1E*5Hz5XR%wM|aBIG6Tx z%jf5BCzksz53oFc+4=0Lb+uC|`}TgS{*)QC&-d9!MsL9aZw>#u_A%LIpLDm3uKQ-# zbNEAg+(UHN@`m?L`8RhK?|H$Qzf`IqvdtsKwlVCy)W^c&c}eLbg<9(B@rWIN^Dz7C?F*WZ%zoHSo-JilgIn1QB{xUkgbQw z&mOr%DrfYb3i)*Br|J0mOPw2%XZ2i_U6ByJxJN%g^O<_9%Sh;oYa6yOLQH8Tb$oz|~VP78)-Cn)HP9gC0wIrKmzs4L&ruTdg zGJbGy-3WIS8#^s<<|Mt{s%Cd1LCPuEXtC_mJC_@#-vn2l{Sx;uDfE^RYh;)He*Is} zHFjZ`=C@JRf&=-dQ|5MlD!8kCTvy4rEoRXcj;06ydX~BDd|LL3TIkqB4_v-b^M3Lj!@1mmw#^Am4I0nZ zZoBmP&!6BSnJI*KSizkrl;P>eaN!kpTD#-$wr__AieZ1)RZtSX$F0_8vF$Hp4$H3KvBih4%OZrtn{%l4w@NI_ zqqn>Yed>OFnc~&FEMAPq;^C7%M_)bHNOiX9v2VNjv?%>Zl9OE~{aeb2@O{CJ{J`_P zp#{Pn&9;hPCY$#Zt@1juB4RSx%=_f?5#Lok$tzM}oH{iCJb!OLJ<_}%IK z$gDLtU^!FuEa&FBs}o({V_FJ^S2r&vy&``5^1J`WK*G9Sg2;aFZguETcVzqMCFi%Q z4SQQv7Y5wlw(84vCF-!#<@CM^(6{x%+(*%#2R(n=CbT_ryY)QDQJnLns)q4$?Y@1)oj0$n9dBLvcw(?z zufQnMJGqt0pC{C)H*r@F|ItjCzkGJ})g4|ln{uZ2Q(`uj9}F3~*heg{aJ?(FGrhab zwbe#9(Hk|^^HXYAoI3J--^vG{T$>o}-LnT?J+|4pbk(yn2E(!S#%ZzNl8R4oT@+px zcjDo{@)R73=c%v%+#9<;u3Y%J_IS#E(FY>6r^%}+lmFqdc~8TO&kC7u42P=q_iSH% zX<~Qv9GhF`qIcg+1ZSELcgLwms;X{1o4#3%x>JDN=jlf8;-K-=g9oS1=544xmf(*w z;#!l$N3V*_c#H}M5=#B$E7GzvI z)NuA@S(%MPzt+Erb$^LQs8q`>-F~J2BO|@s_x_`KyA!tRTxgd47AR!I_GM1D8mQUp zy?4|b&(q5apksQM4D2UoGNUw%FmpNSCWMJFzU>8kB4STcbzUzV45q0b@uXTnkyw>?(K&y4?y8Ns2A8M)dsK++X zYw)n$aK~Kz>J{3`In~++KE&I8%PV|)W$;^O8#ntwI9ATfh(Uj+q|I>QtVh|<29RY? ze-fpj9X9ZkUjbRgY%n(jreH*IKqw~8ayzy+I05BuBrk0DmYzW7(?%Bwk7OH%wHTBd zg`WSCJX^E-LOUzL9jC-3RMTOk|a&Pu56EN>O3DPrFj^VJ8kqy=BB$P0SZI67Lz zTT9-UpiAXTk9hH2-(=pPD1Ui6)4|sDOVLrWw{G|^CTx_C2zP^$8_T3$r_0rmD0Z(; z5TDBrjCN0GCnN~YytRBB`{|GJkIn_TGgE!ve5_PApX(bRbIJc$;aHSIx4ozAW9QQ) zjTOaiH=A7ax)(%)h3(RD-s5@fbqn71>^jw#x$xMl^4%w#w!NuixpXRotgcRT7%1K} zRKulqHL6{m_s*BYkRDmO;>WVRaDo8a3>+N1I6FIl;~Fnzfg;<~&Ah;)L4jlno6ro1 ztcBRaoQ9Y?xwptOM3`ZUyLmS-zvR+DNA&>?)bu{PC@XRpLCy`P<{8e-bTZIOwe2k` zHg8AFdmS#wnr_tlBi~y-vscUOWpBx#3B$fY7KM;qF@}PVy?HEZUT#&dhS+SxfhVJ{ zfhGS>8(~UA5v{r*S^M}mLtaMYUS0}E%gWmww#EysI5CgrUIFTsij-% z=LVQ_)taqjHmyF_8!dVCzFh-mf~(cXr2CjV&A6gY$Yr2kr3^T3geR50xc5GNd`3eb zz10=61}-#!btCXQA~7(FB(IFh%iSYR>YobHvpg9Bh%^yg=OL0z65V@hsUA@?+{UK`H+J^xRXor%jq_%o~w&C6ht9KS*=S6qiC=MT_-o-rI?j+bW z#40~wf97##snWT)Lr|6vT?^yR$Mr>jnE7?3fy%o3?_b>BNEEGKJa8b#x#5d(xlC}` zN7CW1J3C_p+v=_v^(p+3RXZ~VrweBA+;^lc*XED!UljPo`i&+2vz2f?c*BC5KX#Pf z{=6x=;6iiQl6UvZe1`sOBu)6iZLFVPOw!J8waAV968$SIzqnO(z?t8aq>y;Xn)wNjTh|PYE0v72vS}Fgy^GQbO z&KnQ%Jd^g09Gr2_Zk^0;kH+~k`>%*uT~>-NEcj6*p17L?*w*LCE4ITkTTraOb&O=r4oHs{~4NZI$Lm~gH>APp28@cNWaR-Wg z9(p?Tuy{|5eE%!=u>JQhTu?Y~{XNXVN$HzPwyJ;1dCQig9Yy)=2I1Gl7Zs*AnmR2b zOivt&(!p)(Lr@zxVFww0qM~L0&|kY)=y|GfTg5Jaqk0Yl_)n~LTycNn-Kk3s>3ti5 z-%psV{`|~xXo*&--L`CXdy9fKo~c7K>IF@c&@N}i{MtuD%{Cgo-tsUkzv|`6o=e|y zZ`@k8a+6>5&cJljEBo#kj8tqtaZ0LWXXt*>u^_t@ALg`s>^7}k^zb*crxXLMGaBF<()Jm|SE!rsqS}pKvs6Ub zKL3|D4>ZQDsrFRcPSCj%SGq*^#qI5SNr%^rxZl}`X$=p`U(8SZ<*ajoJ;1vif9&4E z3-3+@DlFO=_FZcI57*vx^Bt)QTRlET7e;Q|^J{r=QqVbJe*R=cU{^PB-{E}`P_S+C zF*;QTj>L4XNPA-b>6m^@_Kxe)Q*kmHxwq@i7zTSa7F#cIP_jEXu1+?YgD9jK z{WL?N5Z+U1gQ;vo4gtRXWQQQ-?WXENK!>RTp11M+hxhlcaZ-*OlpP}$tk^;HYj|mAq)%mEIum(Vdgf`n zwFMs^Um)Fh(!GuFoOHYeoWsE4{*kQGZ%=isyVC{(rq@4;`uX;?)$y^G zEu`Vg4$DspW2}~%*O8Y$UR?QgVvWJ^Blo{uoq6h{!tq;ITXf`3kIkx!P%~(Rt*zE2 zKd65AtJcJhcWc%*%HKLP-@1RXv-`E%BOlf=?I0xiui=-S8~emRb+};G}@h zoBD?yCaJ`%b1E&lW#87{eDrns!>r>6c33u7-1Ju)h8PUz$wZ9&NgaxP@+j={^Y!5$ z-4hERMLvJ!@tPE^*y`0~{9uXGBjuDmWw-hQ_6lfYF>{6*^P{p~G+vAmoOTM9{Sk1= zBS`~*qk*UK~6b9COutpBwB?Ay!a_J#uw z=c6CDXOuZywPz&ucT?N_A|GFIzVWl&%RXSd_SkbJ$== zNw4eB3c1V~$4?!Za;kGd%MDtty0}kX+>)%O@TbH7#*)_G6C*hR0>ZPYD=rNYA70k7 z-vB3%=)BJj+$Ck7gUj0*=LqMyKrZxH*NrSa9PILDUaUgJe9Z7-N~Bo?tSzf{*>kJu;CGG z30+!U`c#r^ zEixaUjm%<!>JLr%H3%4wFY&E-l!-J<}cKhX@Iq4Dh zE1vq@R*bSaQ&l;1w1mW?`x{+TH#iY;VuuvFHY8YJc_PF{@18|%$ZH$xnvh=}5jXU! zLqPOEH8lAy4fX$2YVJZOV|RvhFS+@#GoiL~)iT4GN>jOr*&@aE{GES9n?p5In$qie z^LnYXZY*4U=B(rTsI5x)y7J8nlo1sT1J@|Q?3TH2TEFZgeTlSdC2AX-yrcHfYxnGr z?@Ytaob%Pjw+7D4=BPdG)UK^N2;YuogPg^#_mvIqJ8a}UTs_adbrj7@~@Ycd{vZX1(r4 zTIJ^L?hFb?$GIk?gqi9K&H%dp$;FNxXrsxjDED?#bH2O7KQ@}!l+8BLb7#2LglzP9 zImJ+~4k29&XYx*E*yx6sPnb@{E7$Y!7ta}`oignef7s3 zmj#s6hx284X4@8fx9R>UtNH5GThSWX9r^M8k%_pmJ^LxTrB6QE>Wcg04^?HA=82Ee zy?LLKnsyTges_I-@om1gjnl*XmjjV}`DlH!Lp0vmYmfH-F`GAW{n=F+$2Id>dS9HK zQtJLDz0=Wa|NCbgDiX#KZtj2F@5d}RAUxFmz33odz)?1|ZyN71tYIX>xk1wzUb`j6 zORHYHpS3WE0NZ76$wOl;d!~ioVYwL_^-e-Y;#4-yGqwv=D={mu5~@O5z}D3e-XP~9 ztX3;!!|}y>4FTo}W*5}7+@Kwkg7{+h^#f-c)tl9;TjmBm_mmI zbr6GiDrA$M{89#~9AT)R4ACD7V-TUS!hyyL134Aq4y)}_ml!HyyL!wd7aA%l+2+`c zhHPe6j{`%)40B`1L3@DSlASgKn7{?-p;2Tv0*+w>5r)anpeV{y52}7sQM#)cs@Fj# zL!*UyFkEY729FL65!WmoQg3!LJ%4* z3-oY46&g7h6_bTV4E!uDS|SBa9zS_mK;sZmI?Sdq1)&U(WpRn{J#9t99N=Ja>EAo2 zaLT8R2arMgl4#dEAgWeljS1eIb?IW2iqYz@RQKwJsLVj!M|kifJxn2rI{m0(&7reOlYhM*xV_%JLz zEvZLx#8_KbT3d^)t*0f`!ccpBmeAGMy2v7WB9o)%kA!&)KM5Ew)nVhPcL_h7{kHUte}!H1_M1WD5HsEmmb z$HYua=!4b5RApsMr8uT?T0$}SfH*;dA%zfY2n-?(pM+>ZJYdBT zHUvE_5s{=cybaUvn1&LAjD+;TYGFz|JuMO7U-3(@_$yI~JpT$wg4AEWOT_z^l@c8P zaz`TVzXVHA{!4>I_FMctd3if_>^OAjP+eW!)vH%;-MZD&(=$9g{OQxDf1dsK?fP%-S%o#<0U(|6 z=C}r?_kZ9ItR1kRy_}w&_3YxvG9^9st(6bjFMO>(XHXl>Z3I3sik z?ZeC8X&1-NOs4))ySMIM+>gOanVViK?J|tqKdQa^@k_rU)rQy9I_fi*baC*K8?&E( zCkUpLH16Cn+xFSy;=iXdizCH6~_(ntdNyV1d)_dec!3wJt z*DlfyCTM_@;-S%p6 zo8PbV4BnhpSHj!udbPX8R%DGvx@z=>eWV;(%2#y;@I_G5>4k_&{I4v^zxqG}g zAX#A6zS?-h$JyC0Y#)4lEI5(AO0M}s{@AZ_s;lM5#Oku4kaa@mYio!+wgk&#zd*4;_%mWC;r=CxVE zYt=ul`KeoO4QnsA#(vM$ol(G?FTUWmm!`hSezr@V)v`msP96SZn-REY@bH(L@4XxC z@4T7Wm?qfkrft9VyJ=i@Zp&?&?)uEwJB>@Y?RsTC@wrPx$2XNI8nvxjk+uKe?hj@| ztf(yC-?}z!Cx(tEr#Z8qZ-}(1DO1eQ3-N9k^t72?+~2ZA+pzY=nvJp3vAO=XGl-l+ zFI0NAYP{Kb_w+IM-Gpk2oz|gRrn~O?4LNT!d+vpm7CKb@N_22bea?!V%2~L4%U6S+ zmf%=<^$B6?OU>~WAqqu%)}59spOuzXCeJmwRJgmiZC1Q#USQATtifu%ma(7bJd=(x z6okdkr8-xg9a6nBvE|3-yD!c+rUjT{@vKK0TZSSVZ=7u^{%SaW&a?K7blc<0#qCoG z^v=Omtfoi5Rul(nRnLknWzo{|c;87bBa?2dMSEPj*9S(}e|<9Vog690zTjC?S^cSB zDj$B-`q_tO%u-iuPGJ3UoQ%<|sh($C9ChV>(}gmDho-d7nyIqGmA43|Z2V8(PlOo< zlcrW`-YQHmu=W2)EjeF?%Y|gCfA=YOa$@$49-I4H=Fz!Xy5mbpV~dJcu09{_uK8xu z-NA?4;mJaSL)#0k6zAG6ZVXeCX()M$wlrk1<3H(-XL<~lxzh*zHwtyv$6d=?c{xM2 zxy6Jrz^%FOJ06l))ztX-{g^$z--YCHZ-aE!CjTs-uOEH3j24C&vPj+~ndL7<$7`P( zY|_S8<>RyZxuRX3_IQ}wFO&V@(d~gY4~x%qjmrK=_`vO%Wvh7U%Z}fN3rvOHM%&Qv zu=5Y^`YC&bou9+ZSP^!f)j7s4X^u~0ygqH~e}D8s*@?CJPE(}{0yoy9Ci8_12fd7i z?J}ymSsO0@dH4JrCrKl2GU>PO{+4<)&AO}b#M(Kl(z3sNGL-$DH}G_jK6qn*+mTpx zBqaNGL9v};lI9!bn||to0L?c(<8x;oD@vdFbK{eg0q*iOQ+1r#i?6?XrRaUJ>@L-X zTXk*4)S!3O;o=nk*E(E^s^gSOZY(QQx;dT|DwDO6725X8Y!qAf<>&BCoh^r+&l}%K z61>;>u#cFfK)5o#fao$lt()thp0(v7d7azO5Il^Wg?yhketpJJ{Lfz)&C^3m-EYjuVh@`=+D+%JNRz)){m!K{>)?VUVi!jukW2+`PQm&yYYaU zm8RwI>^ip2$zC*fto+5K{;Ra!sld5jnKn^+<%6Xo}}`0DoSrI%TGOEl%sx|I>eu1EpSMa2mc)?t4YMQeij&IaKkg2U?BtOp+=_(>4qHYAaKH`e(Bcg?Fh%WLJL;5B?ka~D) zOOYp1oku3^A3%^(B3GnuIkKw~B|RnB7eIiuC{bBzXA-hCpR9!Ap2+pBWKxr?#yx>e zn+H;H07V{rb45&$-Jd*=@n0n5^E_mh!k1qNI<(yld4(aj5#&~mC(=koAoMW=d4V8* za>&SAh{*>JB*!1QumGu1K`sU$wcE%@$7c^@)CaldgFG)L)A9YD$mJq3qo>#t8Q)4K z_WL3EM8p6wN2>EZk?mW^M7Y(cUrqX$JF-;kygZ@lf~V}M^JJuJ7$6~t&>YdUzf$Uj z%s{5zO34;%b3<70_hYLkJnLTvh6yA-5rp>dCC}IonRJ zC5}M$jM*VO(~ufzr1%LSp00F7ZXQ8N4I{1!H%1Votcr`iqasZOWMmT;$(c$0=!QHT z^N@P=K?=f&ZybxobR0fTWSc-^2`g~xnh46`dfLNf< z00X=^gjg}adkYF9DoUQbA{?mX(TCrlrm;#SyDq7*5_;8pvmh`e%}h~(^+gXWnJc3f zPJnOB2Nuwq0f_@7)iX#9fT2_l0##vL={ zj_-iFUG>fbDS{TFB^M10cdKsggPX8ypjQYho(yT$CO|!_dU!O74v5elI|*;m-s)fj|cUNGm`zsrx8_GHaz@01ky2Uh{gb}Mb_jy83oqwtKr%zYkNZfNejk}RSr)RY5G8jx? zxbv?Nx2Pi{%lk1$3T{#SdyG&55jgA6Sga484V?x=s|>WZ9dY?I=Pp+=_~;Ss8V7?34DbFGuDSN=#CqWV1j)P#^8bO*{tc~= zv;S+vEA_(YTI7p!K%{Fo8Gs15ViK-904wIstC5m}5lI511VHrV(~$;*nDWmQQ39o$ zgur`b9~2eA5>kAG_iPtpMZ+7@LHFf)P>73hp`cLC6eCxS|0TzP1nnSt@{* zfrP5b`A~v@v}+`1*=$}?^xC-SG(G_xf`w!;G*t7qk2)ft1Hf11601R?ERsp0E+Wx* zNG2HNsqWWA8#VdLeA@&~K=X`Ch~`AE_K8b|D6WJ)XQJUAUURS-M8f%^DvlZ19n1!N zxSK6GiY${1V^Od~0{oGJ)Om`0WC6hEVaPuCw{-M%B#@vDB557p0Vu%*RS=dF+-;o#85ajxxE!WkK`KnI zf}5dT0SCIj(M2s`9Zn}z_=*t75{Q)=|2iL%%RkE}C1@i4(QCOy{@v~#%Pgq|ua6|AteMU!C*KUlbuM>C~l_~odZgi(RcS@=OaUvgI_A()E> zfhdC5gm23y1sTiChM+x@qN4*=M?^+%xnMEH z3j|-N;VBk@eJbXSNI_G^LsDRL;_8Hml<0f~OW>FgzDSvofG^qOw*B=Yl_ zGv#xNG?pTjih)SR`6t=@);Gvt7kP}L^G`G@M6e|rxhF&>;q{|8am4idr zP~S`oVc(hZK_s1wz(G;CNf!_oAVN}x6e{Vy6Fiz&2KvGS0E2L##seZ4p!z}}Dt~+_ zf3+8%j{aYC7y4Is!JXMcHvp*c%Amnp|CES4|OHz{KKe)p| zWYY<&2^6^3y#u`j_qz)Tm=76{*#rxiSxpcSgs4Fd$O8o+7l!Q|6xdXQ?ce~|2Xa6a zI1B1vb`hum)u7-wZV9`n72NYa8}@x&xMENq=;C$&IzECwD;RV~88iU}r(rUHr%$2@ zXhOK(e#i&zhQpyV5sb2)f~uhmR361q0m?^#JR8N(bQovAZO5f3^8jdvj(l!|8_;cu z1fzO@VS2<~&;~}phz|*9j)2XQP5MlzsSIGfPPjcj8)Cz_g;N+*hV+n(PzI+Iro-*k zJOVq=MW9I(K`p695ctihAXNB}kP4KUGheL$w0k%`;Gnco=o{r3^g|=@Lh~7%Oh5oJ z?=aBAb#Y^OHpC4912+PuxJd%SAgGg*DkFs6Ve;-eY_!5PvLgmnuEv&7av^&P!7<39 zvr(}9tRoc^EJ3A((2+`PpbVWMafJe14xkiN7_pG+feIJ|V^Y4bz#kwIF9VK{0*Ma+ zi6bc|+>WzOMmJt0&5#ku2q_F{+!w*!gK&ya0#~tO36MDkxzh%EA(wJ$Af61|05Eap zD1!nS&pC|@NeiWel^I?Hp$t~9j!=gv0uDJuM?lHh>mQ2>IID;hxDlOAD7_t^wnxAt z=0HXlf+_}`OG20w1}*9&l_H=C={Oyiczcm!c$^dpf)PMjrslm!;CrINHK=0&!bW)^ zL>!ebgdz&Q+nlh5SO>No#-XKf93ZB^2%^LSY$ze<7z@&7*n1byV}(>efoM{J3`P-B zL^3cXEusjeap@rnCLKx?Fi110^GcV(p>IDJ0{f!Qz!w~(a~Mkh0Su!s{sf-8dWa*i z$vy+UvC+K#jAkV7IAC*)2)a;U1|T?2_hd7J)<_NR>xhiy5?05?lSJr@3fP{{3YMeI zuyyZ?h_7c5Foo*n-qC>Hm~oXR&44QnahgyLP~t04+_O=LW;CHcQ7*cg<)|QH5a_hL zpcPC91t2Z)0-+0L&0D2H`1{y(jV*(4#4(FD9OZsNV)3 z-H(le&#|FsAp^>cNmVhznMS1wGA6Kw>H zf$MwwQu{5VU8;q!&nZ&2!?t!3l28chxCRUv4MirqNKB9s(1&C(CPR@<7s=wX0vVjf zknGx`2}7dO(NYgFdtRgv4Zll4<)iK~(4DGV3}O{&Oen9}(2>GyNRbt8#Y|VELVB#B z)GTo;*q4QVUAPR!jbmylAUJG~!SSNN#|%=9BBL@PhgG0XdIgPJFg#aA$3Xfx0lH9c-&6otXmW02@WGyw&Q2a6_QvOab;*#k?cahS3Chtw!6mKtoe z%w9F+!0fqC- z@<3UE5Gz5eAj|eJ2;M3zi)soW$pDFtg~As=24S!Zi=dw-$fi;iGJ`hsSN}fXWlZGZ zC{t_@P*{!1`=YBkznRfmtGzcn_z)PxxrVvr696^BZD0$xhpj`mgF%7t;L=>Coz@VQ zkFaeR3^dhHW5> zdVoO)m5VP;K`RItigCU$iw)CRHD-GJujFH(6g0!Iot2|<05CB#q#5>Zrjr&bX%Cy2 zfqDoNDq=X^X7U>Kte7$apI1Nzhl&-aU=rEW1+*bq4E6w_q!UweDp>bTxxNEGxnV&u z#30lG$~)cX4fCreKv{BWQb}QRyyh&Hn(e}(3e_yUQ&|ac3 zFGGJZ{|gIoJedq`rA51{!Ek3S43aAhKLyDxCQ(ju0GUpMTdFB=p#9G<#sJ8|Pyfga zIE>~43K2w;$jF(QlC8$1lYoZ67aIW}f6e4sM)nB^L1HX_r&dxd1!y_6F$6>e0Q{lWO41ak5)2)}n4$xYvYyfg^gAVJ@Gl!b+jMz&H z60O4t1n96XQY97vP?$g7UQs-M#hpVGQ?b%{m_UR9$SY~mOq#53Kzx-h*|juE9iD78 zc=Fy>n1Bv_l#yy{YlW*&0zL_c0W4sH&F^@?1C3Qr{&G!Qp;knQ+7#6VoB+?x(av%6 zjvJ+v_jBR^4hMDsFs`nztxb`I{xsRS>I5cM8y{cG19X;C^cT~Uv0c)MiHc*=H8#0$ zR?iyzF+Y4{hHN#4_$|<1bWy*QkxPDu5T&XT2t;WqJ(*+2uwdnyNFqSwvk_VM@inMp zIwAwUy41SnbbI)n)!s3|B|;Zv0OJ+9!J*zs=*x~nNzHRR#A8>vM5U0WhFuD@AjxD3 zaREVqr=ygO&@rSGS238AyD%?|RL+&+DFSLVn3{HJ=~7XfX$&3M8IA*a1_Ka@u(1HH ze@ga;u6G^-_!Z&>fXn;;= z)B>URD$oFxNjIVl@4(3eL>~GEq`Bmih`(^)ALAEqJlPp3J3xMB`PW^X4HnkGJuMT0dp+TF=rihP_ayyMx0T{fQn_# zIp5vPyyv`g!h6p7*7@#T_pZ}xRa0G6RPEaJ?5EOy|Nh!C`u`_cTROa9xe4?>vl-Kz zp2u2H+)Qhx6BED~hFBO3D#j+5&IzXXh5__$6zRNRI@X&0re|)ZWh!B61kuHt(*c=@ z%v5%e-dgXk-`IYJ?;{`U5scnHn`PP(9jD`Uf=<%OI;AeD%hl~#ccWgZJHw}|kAL0M z0bK(IwSQ#YrmN2*{YL!^{b_4!&7==^{hh|y+Kf7RCn&G-x~lGp-Yb7t*m?Wh@~mBB zqja<$|Mz~}UCiyP`s;5G+KiJ3BaBZ&zd!TJU^;Fddc9g=fAC|SYh+OJh*T3TrmEnN zn+cmvtf?)q;i?$cx+b08k`8U?(7LO}{2W9_M;YcvdK%hvIW;+JVCqGDnOanLJt_?=i%Ql7)S2J+o9C%ogaOk~0Y3jwqSjUIPvspEwRlC#)T~t2wu3BSZWDA&HE)L}?-*&oajgdZsiMPp8 zEpt^D=(DY&eS0;r%+r{k!i^j`GCrTNLi)tXFtSaXE(Rt#ebkWtLz4$)BpQ;ll9?i6 z8$BY8-tnj6$Uh!TJRuh0X#H4$jcn6pXlmNnS7Cs1}5)5?EKz_OrKrsqbAzXTLexMNR9B9zk-mIT{oT-5fB9Hqecv)wR7!f10)+cQa@7UtYiS+~Ox%U5IMAdIdS&#{ zEofvB6R2Ba%W#KoF!VZUdWES|u&D#EF$``q6=?dsF?BI&e7Cu3>e3n;yVBdgdP|A4 zyvd1+Mst<7!W?2OGnnXC`f|4f#$~*g(WjE(Z2wZmsvW&4|5Gg&^I26bmh(G&EzK(4 zpEc{`^y%*EKXr25^i(F7?by_XYU-$1P51|zIHRS_UnOzz);51t#Kq7KRR578&gdHB zYWdG{xOfknzpCM4yy;f{UJMsqmu}_nwQxp1#^FEI!o>wQ6M6;|3$cFRql0>T3PQXS zYZkyo1ylJOrDy)Bev5BOSN`|nx45?D&5V{zjej70>({+maqrH>#R(n1$MbQ)La{M` zHS67Cy7sIs6vw#IAHw(O?s1lM4nuzwfA86|yjhI5d8PlZ#;xbTX613o#pRK4-=h-} zx(hM(u_521lBuRGE|^XY_}(wIxLKbdx`J5O?{Vq0kiqd5jQZbJu^BVdCr8&!&59qH zG|=dmkq|Q`y=Q#=)XvcplG?>I$_VN?xx86i*YaYc>mb+f-+K?FtkK|fPsZ>6qaH2W zzG<{gf!drx_WqCb?0=+Z|06y7zg>C;v@xIhAMx4$tKzdDEmPy~H_Ds&o8atS z)T)fFJD9T`jq4T-2`pm&M{xF^6`WN>>b!&7>KxxN`Y$cnS}|D_?l zdVJC_fl(PP{A?RdQ>C+`=9zutZ%;c`VT%i)k=Y?=XF;OH(6X$Rz8mQc#%w)^0YLJ zj-vW5I-J=}eM;%??mHtY3wF8pXPEwj&7I$qejm^xXpVE%eKR@F?cXBj9j>?JK+`ip z)E~o!c7?y!{OuZeSUafS1@=Yg=MQJ(lQmA2zo6ZDPOtpX>cg(*P9wHlb8F^*@ZFO7 zKLkZ;+pLpHlMc`HJ>#L@V;H=>Tk~Ei8%mm;*><{jO6NI`n;rh#M94w+ho2VM-d_0W zeaOtS-9LO@Gi>bF<(_kcZ%q2Svvy$S$~ouGPk8ilgr}Wezt*DY&fJMc;r`}2qlWp` zi8^X?`P+%p%_glklbD|5@7_J}C)3fBo^|#+KlCHH_e5jIjaszr*>Z8#z*7{)4rD$RSvYdpkLA5{KmH)&<7W#g#)wmnT(Ouz4py8y~*!u zc3oS-&Ku_QtEPZ%@6C1lWrqj7$xNBOyhH8Q*)3rCmhbImbUjcjKTLDt+Qg;3qMKGO zzo5G}Yhd=W(&G(YckNDwxOqJ~d@m6`Qml_ zy|GH8HGg^C9W^DsMci(KSNgqgJEPyrq34HhwK-Jh!A$>C z7e|b45o|YMT5g5fE&o_%TF?7WFUoZW+)sJXti=(VJ`aL4!xvoGd$X~j-Ipgfemm-0xYqVAP>mQf2ygyn~93EA^ZsDG^(X*yJJro|owth6{>VmtP_Dy&1xgj>t&3`z$ z=K;U@f&5Qn_D*&mA=oZna6M{6<3`1k9aSIJ&OMmiwD|1F{#)84?Eki;@SF#Cv}pDk z!EcUBgA(hB;!szg=%1I`(-J%x7T&IX`|{w9w-+Cpxvtl{@_Y5l2X)dPyX`Z&S;r39 z%a$)YFreAE@~gLI9~vM$Qyz}Jr8tM~zw>h3#0g!{=~QOZII9EAfB5MGUo|{w)U7r% z?N(2%I6ZDn@X&y%$9K;X@8)*v+Ow?5U8lKie(k|`TQNa+zhCJiR!yFe^|;OYPkKYO z!h;F9wyf{{TT%Tc*0|)`;DL6of6=H(P2?8)YCSph>-O4xw-#s3SY3bGv}b9tRbj1m zhZGK)o4F{+v83W!UC*PRgIj+2^y$v-4t5D^t_>ZWy-@q+*y5|TD(gHdZrFR`l;gu6 z8oRvo-ysDSup38J?b#PQwz+U6-SWw!Nu%w9_w1kUIKn-4rYZ5ujo3EY{qGkqPQL%S zWN+{NAFhubIJQP;&uvHEc$(gx-<)>Wwd2F4ZJ^v^U%Thg&$ngYuNt=evcaxu!niHZ zQqyzX<9A$48Xf5St@zUDDGzU+yQS^HS9E@}%>MhGS?%nLlaGvjJc;RJKU4Gld}87K zuc@PRf0G+q1r6m$ug8n3N@$dSb?~rYveE;**5r?Bw`5487stC!?>g(!+8%8!y$-6E z+kEr+`S#35^Scc@bXC>HzvcR(4r520%TI41U$GzL`!vS=z3che-+sHkfBBZln;UNT z+ulAX)NlHj*nF2y_4<8jKZVb6UlbgEYx0OlC_GmAq;1ZF@cPpmH%uHnb->e|#{93e z4ytlW7p-@CHh6hvw^I%twi}j5iLHBeeHeE^-uPQ;czo%mOLG&wd(J_6n(T-jK#&<`#Kgx z23#N1;2E^DOKWjw(fP(s89xnKJ0tMo{SNL=$Fq+%(mFVK`^@i?H>;(4_3EFq`r6;N zO|96Nsd;Rj0U4K)^Vj_7V7=Am<{54C6)itlUXC0ZhJzLR?NO<3*UvwEcX{F+-yV1R zum9}j*5f{ZxozDVhbt_M_3huNg(Lfh_8C)WOZ#;dS8w*%8sECO{Qa|GoX!2#v0lr{ zg#o`s?R-7!Zrr@g5<7|wjqVs)*Y1r$_e*h;ontP4dmNB?e&mR4UGE5ki`AKC;l1r{KUg7SKAl*eYVse2-VRO3EKjS^3&?jqUu> zOX_A94_O?ZIBdbN1#gZycY#cb>?gs|FPGxs>*;#i`Ml^3tPA0 z`t=-Eu)aT5tB!W>=QoELwEF#t=SSCUyyiY8HYuo8<&-0_SC{r3ylMC0+|V~4)v-zA z_uRhkyrSci&WCr>IyfJzF6-GRb%)3A0jhy#c=wPbhc*qS=hR!Xt$&?>A&EF7u<~t%gla4w+)C>PNA$my-mNqmbZx5g^=Sw;DzoO@L>qOys9m`aq ztIPd$e^1V{YRW{J(RtNG@c-Y?c{$&XQ+l4qh5rgV&)2=B^{ZtoojRHr=AYPk>Oa|e z;SNvZSRrJ9YM9A@lw=#$)7f7Fo7On!6TC!x95xUD{r`qPN+ zD|_Flu|S_v%)k1zljmN$xHS%Md!=Ka-5)>9Z$718w~!+h>n0{A)cV@}TGakK^B0af zyG|({q=Y~Ixc+W%$w7N2|8(1)_40mQ(Yj`o@_eJ);uaOJHqD>B{kY%30S`+8Z0?+& zP`va-JGr$}yx)(B!zXsLJxj0OH~0SjLv%GlPi10M*(KKhgxIIoqOh6Pr+9cWtH zq8iEP{U?&IqEg`bk@b}l|Y00qGmoBUV-71$yei8=FWh=gc4AKOa35T1Oo-~ zsmgTfH8u7Drjx1%glVIvKbm-3F*O|++z4UnI&0VdXB=Mt>TN_`P#27`{jXj}a=IyzNlxHA)O_Bsmrdt1)G8TD2> zbN(v_q`!LSuG-OY<)fHQ51F9PKYO;HX@uCPPltSiX|Vfd)!QRs#V~8yi=W5D{YTch zf{O8tm(1be3wkeow)!4BC(pwApAB@?TGFSi&@w5!FH`I9EOd)o+L_HvshwH1Cuy~v znVZ=ZHMfd3!}&}IWP4U)GvjC5D%r&1UMlG{*Yt#Hwb!2?OPU1M_;TR)Spy4qfP z*N)M)ieH7T+5&uQPMaw-lbKh8r`V>^Da_R)TXnvoH@%Jx2;!mge*;n~Yy=#=c$)r(lP@~t_e;2E9ZZTRDV zE*{yc_qC=I*4;8s(5MFYHS9meMK-->(Q8Vd2j)CoJT6I~=_&qR0g6m~H!`^$cG zN`Ckss|}*%Ef`NH_>QPv3v-GVx88yXnt)p@8D;yB{*x+&miOoux=gKH-$`x{s{)_6 zu?a1k|2By{T3bEdL+b1M%jK_-h9~Lb*@i`qD8tfBmCoZLBqY9>*?Y(O#j#h*Y01s;QD@adeS(iA)7G!Nymxg zY4zy(#yfonIzMe1(~zm1Fk1?AruN$m41$yDHf1=b49CkpN}ELalmj&YH$e$ZBhax* zuf{Pyvqu|JJ&?wonaMgboi;-0Nj0=k16Sqy2wGSJ%W~gG$LK7w8!=?M`xMc_7CJvL z+0$B%{=-9@n&tWD$}jNR}a4f&K*gbI_lM{sQzDp}z$EW$3R!3V{?3 zQg}!aAVq`}2~uQ8Q6QDtk8+U8L#hC&BBV-?DnqIQX#~D=?A3L=GnMFj0WX5=@q1vH~VTFO0y%gGm6B z2quX-b%9BN90EBU6euv0z)TKi@-S0?nIg=TV5ST+6_`a}76-F{Hg*+4rP$)v71cfpbDlmt@91iC2Fh_tn zBFvFsjtp}Ym`h+T2XlFtE5KY4=1MSEhPevNBQTGHc|6P$VV(r@WSFNw5rHBOig+jz zph$!w35sMWQeZxT`5esWVZH$KMVK$ad>Q5|uzi#)6iZMnL$Lyj zIatiYVgVM5uvmh{GAveL34tXXEa72^082zzBEb?FmME~4z)}vD@~~8Zr6MeqV5tmC z6<9`K83)UFSSG+S5td1?Oon9&EGMv>gXKId7ht&v%OzMY!*T^y5Lm&%3LaJnutJ0t z60DG6g#s%HtmI%N4=V*&DZ)w_Rw}THz$y+_@vusORU)jCV3iE36j)7QH3zGCSS`S6 z5mrmET87mMtRb+5gEc&?5nzo7Yb01B!x{zF5?IT@S{~L4uvUb%60DVBtpe)^tm9xE z59fh2>ZzHMSv|LY>{9KXv~fBUwl#(*h*k42U~gAD!^6|wo0&7hOG*0Be0EwZ9Hrf zV4DcrB-kdyHU+j5*v`Rr9<~dxU4-otY?ooX0y_xo;9v(2I|SGv!VU>`$go3!odkAr zu#<-8}3TV7CanCD<*)ZUy!b z*u%jd9`*>ZM}$2R?2%!Q0(%MU@z##&MI5@<^Aps7Fa7cnfG8|IiFoDAy9OmJ$ z0Eb05EWu$J4lD38fuA|}nTMYR_*sOXCHPr}pA{&jcfTBz@=z*3sR*SKl*&-5z!3sR zI5@(?5dn^fa72P53LGVHl!K!@92MZG2uCG2D#K9)juAM@b8wu8;{qHP;kX3HWjL;YOhD#9=0O%f7D1LkmO)nF z1c4JAoZ#Vv04GE^A;Ae5PAG7az)22H@^DgwlMa<2~Npy zN`cb^PIGXYhtmR_7U8r6r)4;;z!?H(I5@+@83E3Sa7KbNGMrJMoIp7T=iodK=LI+~ z!g&eK%Wz(S3j{83aDj&l0$dQ`f&>?2xS+sA0v9>B$iqbeE{bqbf{QX-RNxl^zi{vi z55EZTiwM6+@QVz;C~%3uB@Qm}a7lnmB3zQ-k_?v=s31_mK?M&L0#t}lAwh)<6$)G? zaG8V4JX{vwvIv)DxU9gh1b*e5$a8xOw;@S6y~N${Ht zzbSBqz!eUz@Nh+dD@Vf%n30&vkx&YTjxGuqU8LlgEgTM_AZt!qJ zfEyy*kl=<4Hx#%@;3fw*dAKRSO%ZNNa8rhx3fv-ai-TJ{+!ElH2)87-CBrQRDhX6_ zP{~830F@$CN>C|7r2@AJ+~(jm54Q!lEy8UHZp(06fjb25aBzo*I|AGh;f@4%WVoZi zT>^JGxXZ&`0q%-$SAx4T+*P28Kotj7JX8r#B|?=1RWej5aF4(}4({=APk?(O+>_v* z4EGdJ2q+vVJSYMvA}A6lGAIh%CvcyG`#jti;Jyg=CAcrceFYv6c)-B}9v%qrK!gVp zJdojm0uKp14+VHA!b1rj%J5KuM+6>m@Q8;;0z4Aokpz!qc%;B%0*^U(%)?^= z9*gi;g2ysER^SPNCmcNC;fVlGM0g^>6B(W;@RYz)4xaMxRDh=_ zFA2Ql;3W?)1$ZgKO9@`e@KS+S1YU9QiicMMyb|G+1g~UxrNC%cq73Z8Qv)HmcUyM-tzEPfVU#NmEf%mZxwh);2j6=cz7qk zI}zSV@J@zz3cM%qo`d&1ycgiT2=66$FT;BUJ`ni8!3Q2b2=GCK4-$Nk;e!Gn34G+> zBM%=1_$b0h2|mj3QGrhcK5_7ghfe~065*2spJe!?z-I!VIrz-OX8}Ho@L7V-GJICx z3xO{jeBt4X0AED-BEc6Kz9{gOz*i2w^6*uFuOfVv;HwN@75GNr8wcNb_$I(N5xzN4f((ZYkBoqfh>V1cj0~kc5o9@Jd1M7-MPwyp zWn>jp5ma%g;!!1_N<@`}Dj8J@S`f70(1J$`0WCzdkkCR#3kB5#)f}pMR12sUQ7xfb zMzw+(f*KArJZc2gh^UcJBcnz^LXdDscq9T65s8FEMxvl4K}!xTd9)PJQbbD$EoHP+ z(2AfHhgLjV31}svm4sF@S}9nAU=0py@K{5@8Y0$^u!f8^6tpI2&7n1q)&g3KXf2_& zjMfU;5VYaYhDRF#ZA7$@&_+fZ1#Jo1a%jt=t$?;7+Dd3EqpgB=1noGqUcytiZK|}`$9b|M+P)ktDp_WIjfLal? z5^81CQbZI%M-Cl%bQI80L`R82qtH=7CxT8KI`QZvpp%GB5<1D~q@XiFXAYftbQaKA zL}v+|Wpq~1g`f+EEhf8M0AtTO-45b-3hvL=+2|NfbJr?OXx16yMnY2od<^= zJbDP|A)<$b9x{3;=t+=b!aaHP6wp&dPYFF`^i;4G!CD;F;<1*1wM48XVJ#VJDd)|dW+~Sp|_0Q3f3lAo5R{X))ug~h_xlGEn{s3 z>kzENVI3ap2v|qNIuh2Av5tZ|f;tX$Jn970iKvrMC!Bk0GWACGj_v-#Cj6e zld+zH^$FJJus)CV1*|V(eF^K!SYN>g1RHSJfX4;`HW0CagbieDprAiNe-8b5^cT=y zM1KkWW%O6DA;E?mHsrCPfDJ`#C}Bex8!Fg{U?UD2@z_YfMj|$nu#t?76bv93z+nK7 z0Rjey7$9MQi~$M;5)9-pkjFp)14Rs!Fi^%o1sfA=%wc058w=Q2#Ksafma(ydK?H+1 z4B|0Jz#tKWBn*-Ib*qmT<4x97XT)^fcHkYuu zjLj8nL9hjfEqH7pU<(mjNZ3Ng77Df`*pkDRJhl|DrHCyhY$;<)1zQnp#bGNRTM5`o z#8wivlChP7tqHc~ur-gZ1#B&1YYAJ+*jm9h1lw@fhQ~Gnwh^(7gl%MOqhMQtZ8>bq zV_N~+ir7}dwlcO=upPm69Jb@Joq+8`Y$stm8QUq?o?v?p+w<67!1f}xm$1Ez?G@}m zumgu3cW=RP6Rt~*ontZ0(KIylZ2gQ?4)1_!4M8ZcnlFRM8psYLu3q5&_K|@ zp@Bz(fCdo_5*lPQC>TmGl*3RSLj?>KF;v1(8ABE13Gy8BJn{naBJvXQGV%&`CfJ$7 z&OCM&u(ODrCG0F?X9dFuhH)6iW0-(pB8EvACS#a_T?lsJunUh}1neSW7YVz_*hRsv z1iNzBmB+3Eb``O!gk5Fqs$e&Q-8k&VV>bc2iP%lTZZdXLFq~jGhv7Vi3m7h9xP;*{ zhAS9BFoMGf9wP*d5HUi+2pJ=&aRb5b9CqiiyMWzA>@Hz<8M`akgJ2I1d+^vpz#by@ zkg$i0Jrpz&G;(O<(I}u%M5Ba88I1}?5{%?9lE+8^BSnmqFjB@y1$z?g$ze|(dkWZ7 z#GVrNl(DCRQ3RtnjN&m$z$g);B#e?VO2KG?(Hute7%gD5h|v;8%NVU-FM_=|?8Rd* z0egwqOTu0<_ENAn!QLG9=CQYcy+!OTVQ(3GE7*r%9}fHQ*hj!VBKDE6kBog3j3F4q zVGNHk0>+3KBVmk;F$%^KjO8$v$5;VlMU0g&R>oKb;|Rua7{_CrfN>(mNf;+%oPvD` z_T{iIk9`H~D`H;>`^wl?!FYo49LDn)FJQcg@e;<%7_VRg!2}KycuWv5LBs?J6J$(K zuphyG9QNa}pMd>D>?dJA8T%=iNHCGZL>?0bOcXIu!bBMp6-*+S#9ZA1^W~1&tZQa`wQ4##QqZYm$AQsDFjnEOyMy_z!VWv zButSpMZr{psT`*Am?~hZh^Z2$%9yHP8o@LU(|Al1FipfX3DaauQ&1o%a47I72q=gs zNGQlCC^&%N01gN6I6%MwA`XynfQ$naOedJmVLFfL0;Y?YE@8Ti=?V@cIFQ4EJPs6a zpojw{94O;J1qTrv#Ni+w2MIVx#6c1cl5voNg9#4ia4?U91sp8mURKlS$4pnd% z!C@Q@<8hdP!$ce=;V>D8DVRwxlfz6NGX=~PF;l`!88a0ePH;Gf!+9Jo;BXO#D>y>I zkpxF_IFiSa0*(}Mq=X}79I0Ry!7L85c+3(oOT;lEj+cD>eG?yl(=mq(t2En~NsiE^ ziufH_>*#kpr^+v4u|!#ftXgVorG}|7ss1%p zGeX|^W)-XKLq6n`b#h5E=|>#4Qm3n|!<^JPx~v?(qOeeHkU?#Jc@aC-hH{TwjSkOW zfBy1=Z#C@1)#Sl=ntHWnjGYQ|pS!piqFqv$j@|5ZjM059eLutu7}NOW%UEVp)+O7wzuBfQKVfd*_0vz>9*{TBR}Mf-Bq#IQcwH) zN9Xue=$bdrvSHXfGh3*d#Y4Ya)4uP$x(NH;M(^3@dQjIeFPrghzyzvGP5D)(YxE7^ z@a0WEF6bScUgzPcn(o_1byCZFrjN<1Sj-mYel9X}%(o5@Yzk6SZR{qmtBCG@sLcCQKu`)=z8GY!mZr2UycpOz2A``@Z{rv?58V zx~6q53^#t{0WXxaGZeSL>wpKI2p$&IG*5m4#)F2Ucj-|btVQ8Kdi}uM_sZA=ALxl>2HU7_~0V)vPV6X0`Ms zoR;-vgXws?z_OwioW2~HwIdgoT z9W09EOc~m@jt)1M_G0Q;mgc@*waeE2hR5B;#c4x$lQPcW{3wdcS!!X?_FVD64iU2~ zQurdLY|C;Bb<(u@(wXv>d3g8oJ+k*Ynj}^i*ea<(Zv*hnIVoYS`wrN zqEo-H3?h|g>5PUUFNn|epBZ}%)x(e^b!7*up4xsrwF!5$b>g&jdTQ$=HeNK5$<&1U zr}|ZD$+#~|`Zp_H1I7I!ew^ofTiY}05W`Fv%gU_dVc$v@hE<=VjhnVwHUHs^5*u@I zrL(7Rsn%Be_G62(0nK<*_~7(~Vz5`cX*!MJCJ*ym%i7F$&7p6;T{l@2IV}Y`)8J}BBiNx^ zg3l`Lr*Z?ic>mRqY3GEQ%sgqsAd^p7UB-3O$Tu}vKN2zG>#FVN&#f4fakBf+k#96% zJu6jKlvI0#MsX&MWm7bx(ikn(k^0lxrvrz-{v=2K($epwHqHIu+}D<7Z_HBT2J1z= zPA!hHwrE7da@Wmi*0SN^j+oS}6buXUUq>gTJh{E`}2x{FPm>QrkI`RZFezT!iIZ|_xKQ=3%JSbwEK zJ4YQo_5Ei)jjB7mH3(`$7^@Cxc(o<%zZOgfI&L1;4B7Q%!SJ=eP-ogzW&6rDd^lcu z{Y~Qi^Lu7Yv1gJPrmG*Nv8qibrrt{1cBMv_SpPK@q;^t$>qheYGtq$lkQ8M1iaKhOF~!Vpvv&ID3IP*vDyr0tBq=y{o*BE zNpqEvWArd5tLYq<7eq%^()J%@32IR5G$s|J4kD#ALr^W8SrMmBQ&V-BmPVD9T^p*p zU|{Xd;`F5RvWQ(oCswfA=mck^EGYwJ;TV`M28w}$lNZ#puwsD?V&f@2p4GAK*dXv_v@UEI>)3r%^#*T7n_8;YY6{gaD9r`bq3!7Im#{^t9o1S& z7fNDGVczO(ba%_yateYhXC1MdJ5A4_?FJfDwq`o+u<9&5f*Hs3HiIBTA{i&pme!=- z&ZW*KEx4Fmq2>_QQK#}Ct&5Y5-TF;qw}pAD!fEYQ2`cMo%7W}f>nN0oqV*J;TFrti zqbx}E1$t=Gqiskb(UMYiUGwSM$VNu`hN^L7LW zR`!MZf;!ek+u6dX(e3ciyy$F2>!&lFhs8aEVWwpftqijk@g#d7$~J zi672b&``MuwHYlvLavO9i5AG@!h}Uzm^|p7IbS))1{*ad=w%h8F==#aqdG~$gj!S@ zRO(Xo3$;$Y(p)JN1nEaXkXjLG-| z1W7`o=%$=$O@#hLIgr{vIFPC!x}Q}k>Avhfih`_UZNh0x$5IqzB8~9w$%Cla=}#17 z21P-#h4fS#|FeZj-8`HH{-BYiAjoWbjn#^RAd_@zTia?5q@@#h(Af6|50imWgO^F0 zSE%k=LieUKL#tayA&@SMQ=#(z z2B~(W$IP4YG72mWI}bAqlJ1p<$(H5C4Y3_lc>Oy*@RH@b(SQQOk^>i}_@`M+?O6Hk%teFFuL|b4O8=X-> zv{c6yO~>8+Ueu1aiN2|B$F`ygqg{km>K`mftxuKCwpOY6LXBoOI@B_Gq_P(7rM1B^ z*l(q~pUz!xbSI!TY8V>Nl}XvEN_CK?(2Rm~H=`hpw2@{p>D4I61oem>njs7ybj4ER z!f1h}7v@hCq=k!#wqT&3S*v8@M12OgFNfyFLUt)z6cJU>{n=VpznO!G7bm+jyV!04 zG+S4S>QLHdJ2RnO>CZXSjFbx5lU81YPTi&E+Qu8LG>m>UXGvjgL>H1@X$cg9s5W0p zl1!q%#|?}b|4{^=eRU&eMDy=l*!YhW2H6Umd1VltN^707UM~zEjFY%Oc#wAUCWJDhDG!nc|0s1Plg@-1LGP|tIWknt=o4Izb!KWp z`Y08cGbyhrb`b?o$ug?U6m?z30=-WlGMSy}sfqVVb&0o&x726X)o-e+ zGM`1VeNyWZbLvW_KgLzL+;XK<^i&;5qseP9(}>YQnDtQFRsxx9dS(q}I;DE6Qt1Xq z4BNRUln#7~Q0v3E|@FP}50Is0Hf-Q&ZHMBkt6tsx5Vo&w_oq8r zcKRt_va^VrIIz2KorH=rU&?X~ZJq6=TYLV#rD^bDUYTB;SpVQA-b}qlpwdX%p-TGhOp