From d1583d73285308a67915fbcccc9519e06e434ae2 Mon Sep 17 00:00:00 2001 From: Martina Barreiro Guerra <martina.barreiro@fing.edu.uy> Date: Tue, 5 Jul 2022 11:09:07 -0300 Subject: [PATCH] =?UTF-8?q?Deleted=20IMPETOM-Cl=C3=ADnico/Arduino.py,=20IM?= =?UTF-8?q?PETOM-Cl=C3=ADnico/ImpetomC.py,=20IMPETOM-Cl=C3=ADnico/ImpetomC?= =?UTF-8?q?ElectrodeError.py,=20IMPETOM-Cl=C3=ADnico/ImpetomCError.py,=20I?= =?UTF-8?q?MPETOM-Cl=C3=ADnico/Interfaz.py,=20IMPETOM-Cl=C3=ADnico/fondo?= =?UTF-8?q?=5FImpetom.png,=20IMPETOM-Cl=C3=ADnico/homo=5Fpy.txt,=20IMPETOM?= =?UTF-8?q?-Cl=C3=ADnico/imagenInicial.jpg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "IMPETOM-Cl\303\255nico/Arduino.py" | 188 --- "IMPETOM-Cl\303\255nico/ImpetomC.py" | 394 ------ .../ImpetomCElectrodeError.py" | 16 - "IMPETOM-Cl\303\255nico/ImpetomCError.py" | 15 - "IMPETOM-Cl\303\255nico/Interfaz.py" | 1162 ----------------- "IMPETOM-Cl\303\255nico/fondo_Impetom.png" | Bin 32044 -> 0 bytes "IMPETOM-Cl\303\255nico/homo_py.txt" | 208 --- "IMPETOM-Cl\303\255nico/imagenInicial.jpg" | Bin 18883 -> 0 bytes 8 files changed, 1983 deletions(-) delete mode 100644 "IMPETOM-Cl\303\255nico/Arduino.py" delete mode 100644 "IMPETOM-Cl\303\255nico/ImpetomC.py" delete mode 100644 "IMPETOM-Cl\303\255nico/ImpetomCElectrodeError.py" delete mode 100644 "IMPETOM-Cl\303\255nico/ImpetomCError.py" delete mode 100644 "IMPETOM-Cl\303\255nico/Interfaz.py" delete mode 100644 "IMPETOM-Cl\303\255nico/fondo_Impetom.png" delete mode 100644 "IMPETOM-Cl\303\255nico/homo_py.txt" delete mode 100644 "IMPETOM-Cl\303\255nico/imagenInicial.jpg" diff --git "a/IMPETOM-Cl\303\255nico/Arduino.py" "b/IMPETOM-Cl\303\255nico/Arduino.py" deleted file mode 100644 index 595e07c..0000000 --- "a/IMPETOM-Cl\303\255nico/Arduino.py" +++ /dev/null @@ -1,188 +0,0 @@ -import time - -import numpy as np -import serial -import serial.tools.list_ports -import array as arr -from ImpetomCError import ImpetomCError -from Archivos import Archivos - -class Arduino: - """ - Esta clase permite la creación y manejo del objeto Arduino. - - """ - - - def __init__(self,baudrate, timeout,vThreshold): - """ - Método constructor para la clase Arduino. Permite la creación del objeto arduino. En caso de existir un Arduino conectado a la PC, lo detecta y guarda en este objeto el puerto COM y abre el canal serial. - - :param baudrate: Es la frecuencia del canal serial - :param timeout: Es el valor máximo de tiempo antes de que el canal se cierre sin que se haya recibido ningun dato. Se recomienda no poner timeout menor a 0.1 ya que si no da la conexión da problemas. - :param vThreshold: Es el valor de voltaje a partir del cual se considera que el electrodo esta mal conectado (debe ser un float) - - :exception ImpetomCError: Devuelve una excepción indicando que no se detecto ningun arduino conectado a la pc - """ - - self.puerto = self.__buscarPuertoCom() - self.baudrate = baudrate - self.modo = 0 # Modo Setup por defecto, modo Reconstrucción = 1 - self.timeout = timeout - self.frecuenciaDDS = "30000" - self.ard = serial.Serial(port=self.puerto,baudrate=self.baudrate,timeout=self.timeout) - self.vThreshold = vThreshold - self.__establecerComunicacion() - self.modoColocacionPares = False - self.datos = np.zeros(208) - - - def __buscarPuertoCom(self): - """ - Esta función permite buscar al arduino dentro de los puertos COM conectados al PC - - :exception ImpetomCError: Tira un error en caso de no encontrar ningún arduino conectado al sistema - - """ - - ports = list(serial.tools.list_ports.comports()) - ArduinoPort = '' - - for p in ports: - if "CH340" in p.description or "USB" in p.description or "COM3" in p.description:# Windows reconoce asà al arduino - ArduinoPort = p.name - if ArduinoPort == '': - raise ImpetomCError ("Error: No se encontró ningún dispositivo Arduino conectado.") - - else: - return ArduinoPort - - - def __establecerComunicacion (self): - """ - Esta función establece la comunicación entre la pc y el arduino de impetomC. - - :exception ImpetomCError: Devuelve una excepción indicando que el Arduino conectado no es el arduino de Impetom ClÃnico. - """ - - data = "" - intento = 0 - while data == "" and intento < 20: - self.ard.write(bytes("1", 'utf-8')) - time.sleep(0.05) - data = self.ard.readline().decode('utf-8').rstrip() - intento += 1 - if intento == 20 or data != "ImpetomC": - raise ImpetomCError("Error: No se encontró el dispositivo de ImpetomC.") - time.sleep(0.05) - - - def obtenerMedidas(self): - """ - Esta función obtiene las 208 medidas de tensión realizadas por el arduino ImpetomC para la reconstrucción tomográfica. - - :returns: **datos** - Devuelve el vector con las 208 medidas realizadas. - - **voltajesElevados** - Devuelve la cantidad de voltajes por encima de vThreshold. - - **frecuenciaArd** - Retorna el valor de la frecuencia a la que esta operando el dispositivo Impetom. - - **voltajesElevadosSeguidos** - Retorna la cantidad de voltajes elevados consecutivos (> vThreshold) que fueron detectados. Este dato se utiliza para verificar si hay electrodos desconectados en el dispositivo fÃsico. - - **tiraMedidaElevada** - Retorna el valor del electrodo que se detectó esta desconectado en el dispositivo fÃsico. - - :exception ImpetomCError: En caso de que el Arduino ImpetomC se haya desconectado durante la adquisición de datos devuelve una excepción. - """ - - modo = str(self.modo) - try: - self.ard.write(bytes(modo, 'utf-8'))# Indico al Arduino ImpetomC en que modo debe operar (0 - Setup ; 1 - Reconstrucción) - self.ard.write(bytes(self.frecuenciaDDS,'utf-8')) # Indico al Arduino ImpetomC a que frecuencia debe operar - i=0 - j=0 - tiraMedida = 0 - tiraMedidaElevada = np.zeros(16) - ele_seguidos=0 - voltajesElevadosSeguidos=0 - voltajesElevados=0 - while i < 208: - data = self.ard.readline().decode('utf-8').rstrip() - if data != "": # Esto es para asegurarme que cada vez que le pido un dato al equipo, lo recibo sin problemas. A veces sucede que no da la velocidad del canal - num = float(int(data) * 5 / 1023) - self.datos[i]= num - i += 1 - if i % 13 == 0: # Cada par de electrodos de corriente tiene 13 medidas de tensión asosciadas, con esto identifico los electrodos de corriente - tiraMedida += 1 - if num > self.vThreshold : - ele_seguidos +=1 - voltajesElevados += 1 - voltajesElevadosSeguidos = max(voltajesElevadosSeguidos, ele_seguidos) - if ele_seguidos % 13 == 0: # Registro tira de 13 voltajes elevados - if j<16 and tiraMedidaElevada[j] != tiraMedida: - tiraMedidaElevada[j] = tiraMedida - j += 1 - else: ele_seguidos = 0 - frecuenciaArd = self.ard.readline().decode('utf-8').rstrip() - except serial.SerialException:#Manejo del error de si el dispositivo se desconecta durante la adquisición de datos - raise ImpetomCError("El Hardware se desconectó durante la adquisición.") - self.datos=np.float32(self.datos) - return [self.datos,voltajesElevados,frecuenciaArd,voltajesElevadosSeguidos,tiraMedidaElevada] - - - def cambiarModoDeOperacion(self,mode): - """ - Esta función permite realizar el cambio de modo del Arduino ImpetomC. - - :param mode: String que debe indicar : "Reconstrucción" o "Setup". - - :exception ImpetomCError: Tira una excepción en caso de que mode sea distinto a los valores aceptados. - """ - - if (mode == "Reconstruccion"): - self.modo = 1 - elif (mode == "Setup"): - self.modo = 0 - else: - raise ImpetomCError("Error: Modo de operación incorrecto. Debe ser \"Reconstruccion\" o \"Setup\"") - - def cambiarFrecuenciaDDS(self,frecuenciaDDS): - """ - Función que permite cambiar el valor de la frecuencia del DDS del dispositvo ImpetomC. - - :param frecuenciaDDS: Valor de la nueva frecuencia del DDS. - - """ - - if(type(frecuenciaDDS) != str): - raise ImpetomCError("Error: La frecuencia del DDS debe estar en formato String") - self.frecuenciaDDS=str(frecuenciaDDS) - - def abrirPuertoSerie(self): - """ - Permite abrir el puerto serie. - Por defecto cuando se crea el objeto el puerto queda abierto, por lo que solo se debe usar si el puerto se - cerró en algun momento. - - :except ImpetomCError: En caso de utilizarse con el puerto ya abierto devuelve una excepción. - """ - - try: - self.ard.open() - self.__establecerComunicacion() - except serial.SerialException as se: # En caso de que se haya desconectado el dispositivo - if (str(se) == "El puerto ya está siendo utilizado"): # En caso de que el puerto ya esté abierto - raise ImpetomCError(str(se)) - else: # En caso de que el error sea por una desconexión - self.puerto=self.__buscarPuertoCom() - self.ard = serial.Serial(port=self.puerto,baudrate=self.baudrate,timeout=self.timeout) - self.__establecerComunicacion() - - - - def cerrarPuertoSerie(self): - """ - Permite cerrar el puerto serie. - """ - - self.ard.close() - diff --git "a/IMPETOM-Cl\303\255nico/ImpetomC.py" "b/IMPETOM-Cl\303\255nico/ImpetomC.py" deleted file mode 100644 index 4d7873c..0000000 --- "a/IMPETOM-Cl\303\255nico/ImpetomC.py" +++ /dev/null @@ -1,394 +0,0 @@ -import threading -import time -from datetime import date, datetime -import numpy as np -import re -from pyeit.eit import jac -from pyeit.eit.interp2d import sim2pts - -from Archivos import Archivos -from Arduino import Arduino -from ImagenesDicom import ImagenesDicom -import os -from ImpetomCError import ImpetomCError -from ImpetomCElectrodeError import ImpetomCElectrodeError -import matplotlib.pyplot as plt - -#modulos de pyeit -import pyeit.mesh as mesh -from pyeit.eit.fem import Forward -from pyeit.eit.utils import eit_scan_lines -from pyeit.mesh.shape import thorax,circle - -flag_InstanceStudy = True - -class ImpetomC: - """ - Permite manejar todas las funcionalidades de la aplicación ImpetomC - - - Generación y guardado de la imagen tomográfica en formato dicom - - Conexión del arduino ImpetomC al puerto serie - - """ - - #Parametros para las imagenes reconstruidas - cmap=plt.cm.RdYlBu # color para las imagenes generadas - shape = "thorax" - lamb=0.01 - - #vectores de datos - datos = np.zeros(208) # Variable para el manejo de los datos de entrada desde Arduino ImpetomC - archiVH = Archivos("homo_py.txt")# vector homogéneo por defecto. Puede cambiarse utilizando la función actualizarVectorDeDatosHomogeneo - vHomogeneo = archiVH.leerArchivo() - - #Variables para el manejo del dispositivo ImpetomC - ard = None # se actualiza con startUp() o __arduinoConnect() - arduinoComunicationError = None # Variable para manejar el error de que se desconecte el Arduino de la pc mientras adquiere datos - - # Variables globales utilizadas para el manejo de problemas asosciados a los electrodos - voltajesElevados = 0 - voltajesElevadosSeguidos = 0 - tiraMedidaElevada = 0 - - #Parámetros del sistema - rootDir=os.path.dirname(os.path.abspath("ImpetomC.py")).replace("ImpetomC.py","") #Ubicación del directorio donde se guardaran las imágenes generadas - today = date.today().strftime("%b-%d-%Y") - - #Establecimiento de los parámetros de la imagen dicom - imgDicom = ImagenesDicom(p=0.3,lamb=lamb,file_path_jpg= os.path.join(rootDir, "IMG.jpg"),today=today,rootDir=rootDir, shape=shape) - - - @classmethod - def startUp(cls): - """ - Esta función permite hacer el start up de la aplicación. Utilizarla para dar inicio a la aplicación - - :exception ImpetomCError: Devuelve una excepción en caso de encontrar problemas con la conexión a el dispositivo Arduino - """ - - cls.__arduinoConnect() - - @classmethod - def __arduinoConnect(cls): - """ - Permite establecer la conexión con el Arduino con el software de ImpetomC - - :exception ImpetomCError: Devuelve una excepción con el mensaje correspondiente - """ - - cls.ard = Arduino(baudrate = 9600, timeout = 0.1,vThreshold = 4.0) #para cambiar el valor del threshold de voltaje cambiar vThreshold - cls.arduinoComunicationError = None - - - @classmethod - def reset(cls): - """ - Este método permite realizar el reseteo de la aplicacion, devolviendo la aplicacion a sus valores por defecto - """ - - cls.datos = np.zeros(208) - cls.ard.cerrarPuertoSerie() - archiVH = Archivos("homo_py.txt") # vector homogéneo por defecto. Puede cambiarse utilizando la función actualizarVectorDeDatosHomogeneo - cls.vHomogeneo = archiVH.leerArchivo() - cls.startUp() - - @classmethod - def actualizarVectorDeDatosHomogeneo(cls): - """ - Permite volver a cargar el vector de datos homogeneo en modo reconstrucción para un mejor detalle del vector - """ - - cls.ard.cambiarModoDeOperacion("Reconstruccion") - datosRecalibrados, ve, fa, vS, ta = cls.ard.obtenerMedidas() - archiCalibrar = Archivos("datos_calibrar.txt") - archiCalibrar.escribirArchivo(datosRecalibrados) - cls.vHomogeneo = archiCalibrar.leerArchivo() - - - @classmethod - def __verificarParametrosParaImagen(cls,mode,shape,vmax,vmin,screenWidth,p,sclEnable): - """ - Permite verificar que los parámetros de entrada para la reconstrucción tomográfica sean correctos - - :param mode: Tipo string, debe contener la palabra "reconstruccion" o "setup" - :param shape: Tipo String, debe contener la palabra "thorax" o "circle" - :param vmax: Tipo float, máximo valor para la escala de la imagen - :param vmin: Tipo float, mÃnimo valor para la escala de la imagen - :param screenWidth: Tipo Int, ancho de la pantalla del usuario - :param p: Parámetro para la reconstrucción con JAC, se recomienda que el valor esté en 0.1 y 0.9 - :param SclEnable: Debe ser un booleano. True para utilizar los valores vmax y vmin y false para no utilizarlos - - :returns: **meshDensity** - Retorna la densidad de mesh a utilizar, esto depende de el modo de trabajo de la aplicación y el shape utilizado - - **retShape** - Retorna un shape reconocible por las funcionalidades de pyEIT - - :exception ImpetomCError: Devuelve una excepción con el mensaje de error correspondiente - """ - - mode=mode.lower() - if mode == "reconstruccion": # Determino el mesh density - meshDensity= 0.045 - elif mode == "setup": - if shape == "thorax": # Determino mesh de setup según modelo - meshDensity = 0.07 - - elif shape == "circle": - meshDensity = 0.1 - else: - raise ImpetomCError("Forma para la reconstrucción inválida, debe ser \"Thorax\" o \"Circle\"") - else: - raise ImpetomCError("Modo de reconstrucción inválido. Debe ser \"Reconstruccion\" o \"Setup\"") - - shape=shape.lower() - if shape == "thorax": # Determino la forma de la reconstrucción - retShape=thorax - - elif shape == "circle": - retShape = circle - - else: - raise ImpetomCError("Forma para la reconstrucción inválida, debe ser \"Thorax\" o \"Circle\"") - - if type(vmax) != float or type(vmin) != float or type(screenWidth) != int or type(p) != float or type(sclEnable) != bool: - raise ImpetomCError("vmax, vmin, p deben ser floats , screenWidth debe ser un int y sclEnable un bool") - elif screenWidth <= 0 or p <=0 : - raise ImpetomCError("screenWidth y p deben ser mayores que 0") - return [meshDensity,retShape] - - @classmethod - def __obtenerimagen(cls,vectorDatos,SclEnable,vmax,vmin,shape,mode,p,screenWidth): - """ - Pemite generar una imágen tomográfica a partir de un vector de datos, entre otros parámetros - - :param vectorDatos: Vector de 208 valores de tensión para reconstruir la imágen tomográfica - :param SclEnable: Debe ser un booleano. True para utilizar los valores vmax y vmin y false para no utilizarlos - :param vmax: Máximo valor para la escala de la imagen - :param vmin: MÃnimo valor para la escala de la imagen - :param shape: Forma de la reconstrucción "thorax" o "circle" - :param mode: Modo en el que fueron tomadas las medidas de vectorDatos ("reconstruccion" o "setup") - :param p: Parámetro para la reconstrucción con JAC, se recomienda que el valor esté entre 0.1 y 0.9 - :param screenWidth: Ancho de la pantalla del usuario - - :exception ImpetomCError: Devuelve una excepción con el mensaje de error correspondiente - """ - - meshDensity, correctShape = cls.__verificarParametrosParaImagen(sclEnable=SclEnable,vmax=vmax,vmin=vmin,shape=shape,mode=mode,p=p,screenWidth=screenWidth) - mesh_obj, el_pos = mesh.create(16, h0=meshDensity, fd=correctShape) - pts = mesh_obj["node"] - tri = mesh_obj["element"] - x, y = pts[:, 0], pts[:, 1] - - if shape == "circle": - el_pos = el_pos + 12 # Electrodo 1 en las "6" del reloj - for i in range(4, 16): - el_pos[i] = el_pos[i] - 16 - - el_dist, step = 1, 1 - ex_mat = eit_scan_lines(16, el_dist) - eit = jac.JAC(mesh_obj, el_pos, ex_mat=ex_mat, step=step, perm=1.0, parser="fmmu") - eit.setup(p=p, lamb=cls.lamb, method="kotre") - - ds_n = eit.solve(vectorDatos, cls.vHomogeneo, normalize=True) - ds = sim2pts(pts, tri, np.real(ds_n)) - - fig, ax = plt.subplots(1, 1, constrained_layout=True) - fig.set_size_inches(7, 5) - - if (SclEnable): - im = ax.tripcolor(x, y, tri, ds, shading="flat", cmap= cls.cmap, vmax=vmax, vmin=vmin) - else: - im = ax.tripcolor(x, y, tri, ds, shading="flat", cmap=cls.cmap) - - if shape == "thorax": # Electrodos Thorax - for i, e in enumerate(el_pos): - if i <= 4: - ax.annotate(str(i + 1), xy=(x[e] - 0.05, y[e] - 0.05), color="w") - elif i <= 7: - ax.annotate(str(i + 1), xy=(x[e] - 0.04, y[e]), color="w") - else: - if i <= 11: - ax.annotate(str(i + 1), xy=(x[e], y[e]), color="w") - else: - ax.annotate(str(i + 1), xy=(x[e], y[e] - 0.05), color="w") - elif shape == "circle": # Electrodos Circle - for i, e in enumerate(el_pos): - if 1 <= i <= 7: - if i <= 3: - ax.annotate(str(i + 1), xy=(x[e] - 0.05, y[e] - 0.05), color="w") - else: - ax.annotate(str(i + 1), xy=(x[e] - 0.05, y[e]), color="w") - elif i >= 14: - ax.annotate(str(i + 1), xy=(x[e] + 0.04, y[e] - 0.05), color="w") - elif i == 0: - ax.annotate(str(i + 1), xy=(x[e], y[e] - 0.05), color="w") - else: - ax.annotate(str(i + 1), xy=(x[e], y[e]), color="w") - - ax.axis("off") - cbar = fig.colorbar(im) - cbar_yticks = plt.getp(cbar.ax.axes, 'yticklabels') - plt.setp(cbar_yticks, color='w') - ax.set_aspect("equal") - fig.patch.set_facecolor('black') - fig.savefig('IMG.jpg', dpi=(100/1200)*screenWidth) - plt.close(fig) - - @classmethod - def generarImagenTomografica(cls,mode,shape,screenWidth,sclEnable,vmax,vmin,p,frecuenciaDDS): - """ - Permite generar la imagen tomográfica y la guarda en la raÃz del proyecto como IMG.jpg - - :param mode: Modo en el que debe operar el dispositivo ImpetomC - :param shape: Forma de la reconstrucción "thorax" o "circle" - :param screenWidth: Ancho de la pantalla del usuario - :param SclEnable: Debe ser un booleano. True para utilizar los valores vmax y vmin y false para no utilizarlos - :param vmax: Máximo valor para la escala de la imagen - :param vmin: MÃnimo valor para la escala de la imagen - :param p: Parámetro para la reconstrucción con JAC, se recomienda que el valor este en 0.1 y 0.9 - :param frecuenciaDDS: Valor de frecuencia a la que debera operar el DDS del dispositvo ImpetomC - - :exception ImpetomCElectrodeError: Devuelve una excepción con una mensaje que indica el problema detectado con los electrodos - :exception ImpetomCError: Devuelve una excepción con un mensaje de error por errores distintos al anterior - """ - - global voltajesElevados, voltajesElevadosSeguidos, tiraMedidaElevada - if(type(frecuenciaDDS) != str): - raise ImpetomCError("La frecuencia del dds debe ser un String") - if cls.datos[0] == 0: #Verifico si es la primera vez que se ejecuta la aplicación o si el dispositivo se desconectó - cls.__tomarMedidasParaImagen(mode, frecuenciaDDS) - threading.Thread(target=cls.__tomarMedidasParaImagen(mode,frecuenciaDDS)).start() - cls.__obtenerimagen(vectorDatos=cls.datos,screenWidth=screenWidth,SclEnable=sclEnable,vmax=vmax,vmin=vmin,p=p,shape=shape,mode=mode) - - if voltajesElevados >= 26 and voltajesElevadosSeguidos >= 13: - if tiraMedidaElevada[0] != 0: - imprimir_ele = [] - for dato in tiraMedidaElevada: - if dato != 0: - imprimir_ele.append(int(dato)) - raise ImpetomCElectrodeError("Se detectó un falso contacto en al menos un electrodo. Revise los electrodos " + str(imprimir_ele)) - elif voltajesElevados > 64: - raise ImpetomCElectrodeError("Se detectaron varios electrodos con tensiones elevadas, se recomienda regular la ganancia del dispositivo.",regularGanancia=True) - elif voltajesElevados <= 13: - raise ImpetomCElectrodeError("Se detectaron varios electrodos con tensiones bajas, se recomienda regular la ganancia del dispositivo.", regularGanancia=True) - elif cls.arduinoComunicationError == None: # verifico que no se haya desconectado el dispositivo durante la adquisición - threading.Thread(target=cls.__tomarMedidasParaImagen(mode,frecuenciaDDS)).start() - tiImagen=time.time() - cls.__obtenerimagen(vectorDatos=cls.datos,screenWidth=screenWidth,SclEnable=sclEnable,vmax=vmax,vmin=vmin,p=p,shape=shape,mode=mode) - tfImagen=time.time() - if voltajesElevados >= 26 and voltajesElevadosSeguidos >= 13: - if tiraMedidaElevada[0] != 0: - imprimir_ele = [] - for dato in tiraMedidaElevada: - if dato != 0: - imprimir_ele.append(int(dato)) - raise ImpetomCElectrodeError("Se detectó un falso contacto en al menos un electrodo. Revise los electrodos " + str(imprimir_ele)) - elif voltajesElevados > 64: - raise ImpetomCElectrodeError(msg="Se detectaron varios electrodos con tensiones elevadas, se recomienda regular la ganancia del dispositivo.",regularGanancia=True) - elif voltajesElevados <= 13: - raise ImpetomCElectrodeError(msg="Se detectaron varios electrodos con tensiones bajas, se recomienda regular la ganancia del dispositivo.",regularGanancia=True) - elif cls.arduinoComunicationError != None:# Si se desconectó el dispositivo durante la adquisición - cls.datos= np.zeros(208) #Reinicio el vector de datos - cls.ard.datos=np.zeros(208) - raise ImpetomCError(cls.arduinoComunicationError) - - @classmethod - def __tomarMedidasParaImagen(cls,mode,frecuenciaDDS): - """ - Utiliza al objeto arduino generado para comunicarse con este y obtener las medidas de tension necesarias para realizar la reconstruccion tomográfica del paciente. - Las medidas obtenidos son guardadas en la variable datos - - :param mode: Modo de operación para el dispositvo ImpetomC - :param frecuenciaDDS: Frecuencia de operación para el dispositvo DDS - - """ - - global arduinoComunicationError,voltajesElevados, voltajesElevadosSeguidos,tiraMedidaElevada - cls.ard.cambiarModoDeOperacion(mode) - cls.ard.cambiarFrecuenciaDDS(frecuenciaDDS) - try: - tidatos = time.time() - cls.datos,voltajesElevados,frecuenciaArd,voltajesElevadosSeguidos,tiraMedidaElevada= cls.ard.obtenerMedidas() - archi = Archivos("img.txt") - archi.escribirArchivo(cls.datos) - tfdatos = time.time() - cls.arduinoComunicationError = None - except ImpetomCError as e:# Escribo el msj de error en arduinoComunicationError - cls.arduinoComunicationError = str(e) - - @classmethod - def __verificarParametrosParaHistoriaClinica(cls,pacientName,pacientCi,p,birthDate,sex,medida,medidaZ,shape,mode): - """ - Permite verificar que los parámetros de entrada para la reconstrucción tomográfica sean correctos - - :parameter pacientName: Tipo string, no debe estar vacÃo - :param pacientCi: Tipo String, no debe estar vacÃo y ser una cadena de números - :param p: Tipo float, debe ser mayor que 0 - :param birthDate: Debe ser un String válido a convertir a fecha en el formato dd-mm-yyyy - :param sex: Tipo String, debe ser "M", "F" o "Otro" - :param medida: Medida de la circunferencia del thorax del paciente - :param medidaZ: Altura aproximada donde está colocado el cinturón de electrodos. El cero se marca desde la apófisis del esternón - :param shape: Forma de la reconstrucción "thorax" o "circle" - - :exception ImpetomCError: Devuelve una excepción con el mensaje de error correspondiente - """ - - if(type(pacientName) != str or len(pacientName) <=1 ): - raise ImpetomCError("El nombre debe ser un string y no debe estar vacÃo") - if(type(pacientCi) != str or not re.match('^[0-9]*$',pacientCi)): - raise ImpetomCError("La CI solo puede contener números") - if (type(p)!=float or p <= 0): - raise ImpetomCError("p debe ser un float y mayor que 0") - if (type(medida) != str or not re.match('^[0-9]*$', medida)): - if type(medida) == int and int(medida) < 0 :# explcitamente me fijo si el numero es positivo - raise ImpetomCError("La medida de la circuferencia del tórax solo puede contener números positivos") - elif type(medida )!= int: - raise ImpetomCError("La medida de la circuferencia del tórax solo puede contener números") - if (type(medidaZ) != str or not re.match('^[0-9]*$', medidaZ.strip("-"))): - if type(medidaZ) != int: - raise ImpetomCError("La medida de la altura de colocación del cinturón debe ser un número entero") - - mode=mode.lower() - if type(mode) != str: - raise ImpetomCError("El atributo Mode debe ser un string") - elif mode != "reconstruccion" and mode != "setup": - raise ImpetomCError("Modo de reconstrucción inválido. Debe ser \"Reconstruccion\" o \"Setup\"") - shape=shape.lower() - if shape != "thorax" and shape != "circle": - raise ImpetomCError("Forma para la reconstrucción inválida, debe ser \"Thorax\" o \"Circle\"") - try: - patBirthDate = datetime.strptime(birthDate, "%Y%m%d") - except ValueError: - raise ImpetomCError("La fecha de nacimiento no es válida") - sex=sex.lower() - if (sex != "m" and sex != "f" and sex!="otro"): - raise ImpetomCError ("El sexo del paciente debe ser M, F u Otro") - - @classmethod - def guardarImagenEnHistoriaClinica(cls,pacientName,pacientCi,p,pacBirthDate,pacSex, medida, shape, medidaZ,mode): - """ - Permite el guardado de las imágenes obtenidas en la carpeta correspondiente a la historia clónica del paciente, solamente cuando el dispositivo se encuentra en modo Reconstrucción - - :param pacientName: Nombre del paciente - :param pacientCi: Ci del paciente - :param p: valor de p utilizado durante la reconstrucción - :param birthDate: Fecha de nacimiento del paciente - :param pacSex: Sexo biologico del paciente - :param medida: Medida de la circunferencia del thorax del paciente - :param shape: Forma de la reconstrucción "thorax" o "circle" - :param medidaZ: Altura aproximada donde está colocado el cinturón de electrodos. El cero se marca desde la apófisis del esternón - :param mode: Modo de trabajo del dispositivo. Puede ser "Reconstruccion" o "Setup". Solo guarda imágenes con formato Dicom en caso de estar en modo "Reconstruccion" - """ - - cls.__verificarParametrosParaHistoriaClinica(pacientName,pacientCi,p,pacBirthDate,pacSex,medida,medidaZ,shape,mode) - medida=int(medida) - medidaZ=int(medidaZ) - dir_dcm = "\\Pacients_Data\\" + pacientName.strip('\n') + "_" + pacientCi.strip('\n') + "\\" + cls.today - - try: # intento crear la capeta donde se guardaran las imágenes tomográficas del paciente - os.makedirs(cls.rootDir + dir_dcm) - except OSError: # en caso de que el directorio exista no importa - pass - finally: # guardo la imagen en la carpeta del paciente con un nombre que depende de la hora, minutos y segundos - mode = mode.lower() - if mode == "reconstruccion": - cls.imgDicom.generarImagenDicom(pacientName, pacientCi, pacSex, pacBirthDate, p, cls.lamb, cls.today, medida, shape, medidaZ) diff --git "a/IMPETOM-Cl\303\255nico/ImpetomCElectrodeError.py" "b/IMPETOM-Cl\303\255nico/ImpetomCElectrodeError.py" deleted file mode 100644 index d5cbe13..0000000 --- "a/IMPETOM-Cl\303\255nico/ImpetomCElectrodeError.py" +++ /dev/null @@ -1,16 +0,0 @@ - -class ImpetomCElectrodeError(Exception): - """ - Utilizar esta clase para levantar errores o excepciones con los electrodos - """ - def __init__(self,msg,regularGanancia=False): - """ - Constructor de la clase ImpetomCElectrodeError - - :param msg: Mesaje de error a desplegar con la excepción - :param regularGanancia: Booleano que debe indicar True en caso de que sea un error para regular la ganancia de los electrodos. False se trata de un error de al menos un electrodo desconectado. El valor por defecto de este parámetro es False - - """ - self.regularGanancia=regularGanancia - super().__init__(msg) - diff --git "a/IMPETOM-Cl\303\255nico/ImpetomCError.py" "b/IMPETOM-Cl\303\255nico/ImpetomCError.py" deleted file mode 100644 index 6462d06..0000000 --- "a/IMPETOM-Cl\303\255nico/ImpetomCError.py" +++ /dev/null @@ -1,15 +0,0 @@ - -class ImpetomCError(Exception): - """ - Utilizar esta clase para levantar errores o excepciones que no son referentes a los electrodos del dispositivo. - Por ejemplo, esta clase es utilizada cuando se detecta una desconexión del dispositivo Impetom durante la adquisición de datos - - """ - - def __init__(self,msg): - """ - Constructor de la clase ImpetomCError - - :param msg: Mesaje de error a desplegar con la excepción - """ - super().__init__(msg) diff --git "a/IMPETOM-Cl\303\255nico/Interfaz.py" "b/IMPETOM-Cl\303\255nico/Interfaz.py" deleted file mode 100644 index 15d7e02..0000000 --- "a/IMPETOM-Cl\303\255nico/Interfaz.py" +++ /dev/null @@ -1,1162 +0,0 @@ -import threading -import time -import tkinter.ttk -from tkinter import * -from tkinter import messagebox -from PIL import Image, ImageTk -from _datetime import date -import re -from ImpetomC import ImpetomC -from ImpetomCError import ImpetomCError -from ImpetomCElectrodeError import ImpetomCElectrodeError -from datetime import datetime -import winsound - -""" -Clase que genera la interfaz gráfica de la aplicación -""" - -""" -Variables globales de la aplicación -""" - -arduinoImpetom = 0 # 0 indica arduinoImpetom desconectado, 1 indica que esta conectado -Reconstruir = False -mode = "Setup" -img = Image.open('imagenInicial.jpg') -sclRangeEnable = False - -""" -Funciones para validación de datos de entrada -""" - -def validateName(): - """ - Funcion que valida el nombre del paciente ingresado - :return: 0 si existe algun error, 1 si el nombre es correcto (el campo lblNameError no esta vacio) - """ - - ret=0 - patName = txtName.get("1.0", END) - if len(patName) <=1 : - lblNameError.config(text="Este campo no puede estar vacÃo") - else: - ret=1 - lblNameError.config(text="") - return ret - -def validateCI(): - """ - Funcion que valida la CI del paciente ingresado - :return: 0 si existe algun error, 1 si la CI es correcta (el campo lblNameError no esta vacio) - """ - - ret = 0 - patCi = txtCi.get("1.0", END).strip("\n") - lenCI=len(patCi) - if not re.match('^[0-9]*$',patCi): - lblCiError.config(text="La CI solo puede contener números") - elif lenCI <= 6 or lenCI > 8: - lblCiError.config(text="CI inválida") - else: - ret = 1 - lblCiError.config(text="") - return ret - -def arduinoImpetomConected(): - """ - Funcion que verifica que el dispositivoImpetomC esta conectado - :return: 0 si existe algun error, 1 si no - """ - - ret = 1 - global arduinoImpetom - if arduinoImpetom == 0: - try: # Verifico que haya un arduino conectado al equipo al iniciar y si es el arduino de ImpetomC - ImpetomC.startUp() - arduinoImpetom = 1 # indicador que arduino Impetom está conectado - lblError.config(text="", bg='white') - except ImpetomCError as e: - lblError.config(text=str(e), bg='white') - arduinoImpetom = 0 - ret = 0 - return ret - -def validateSexoBiologico(): - """ - Funcion que valida el sexp biologico del paciente ingresado - :return: 0 si existe algun error, 1 si no - """ - - ret = 0 - patSex = cmbBioSex.get().lower() - if patSex == "seleccionar": - lblBioSexError.config(text="Seleccione una opción válida") - else: - lblBioSexError.config(text="") - ret = 1 - return ret - -def validateBirthDate(): - """ - Funcion que valida la fecha de nacimiento del paciente ingresado - :return: 0 si existe algun error, 1 si no - """ - - ret = 0 - txtBDate = str(txtBirthDate.get("1.0", 'end-1c')) - try: - datetime.strptime(txtBDate, "%d-%m-%Y") - lblBirthDateError.config(text="") - ret = 1 - except ValueError: - lblBirthDateError.config(text="La fecha debe ser dd-mm-yyyy") - finally: - return ret - -def validateMedida(): - """ - Función que valida la entrada de los datos de medida de circunferencia del tórax, - El dato debe ser un número entre 100 y 2000mm - """ - - ret = 0 - fantomaMed = txtMedida.get("1.0", END).strip("\n") - lenFantomaMed = len(fantomaMed) - if not re.match('^[0-9]*$', fantomaMed): - lblMedidaError.config(text="Este campo solo puede contener números positivos") - elif lenFantomaMed <= 2: # Verifico que el número sea mayor que 100 mm - lblMedidaError.config(text="El perÃmetro debe ser mayor o igual a 100 mm") - elif lenFantomaMed >= 5: - lblMedidaError.config(text="El perÃmetro es demasiado grande") - else: - ret = 1 - lblMedidaError.config(text="") - if lenFantomaMed == 4: - intFantomaMed = int(fantomaMed) - if intFantomaMed >= 2000: - lblMedidaError.config(text="El perÃmetro es demasiado grande") - ret = 0 - - return ret - -def validateMedidaZ(): - """ - Función que valida la altura de colocación del cinturon, debe estar entre 10 mm y 999mm - """ - - ret = 0 - fantomaMedZ = txtMedidaZ.get("1.0", END).strip("\n") - fantomaMedZ = fantomaMedZ.strip("-") # Para validar ints > 0 y < 0 con la misma regExp - lenFantomaMedZ = len(fantomaMedZ) - lblMedidaZError.place(x=(265 / 1200) * screenWidth, y=(560 / 750) * screenHeight) - if not re.match('^[0-9]*$', fantomaMedZ): - lblMedidaZError.config( - text="La altura de colocación del cinturón debe ser un número entero medido desde la apófisis del esternón") - elif lenFantomaMedZ < 1 or lenFantomaMedZ > 3: # - lblMedidaZError.config(text="La referencia de altura no es válida") - else: - ret = 1 - lblMedidaZError.config(text="") - return ret - -""" -Eventos para botones Start y Stop -""" - -def btnStartClicked(): - """ - Evento del botón start - """ - - global Reconstruir, arduinoImpetom - if validateName() +validateCI() + arduinoImpetomConected() + validateSexoBiologico() + validateBirthDate() + validateMedida() + validateMedidaZ() == 7: - Reconstruir = True - txtMedida.config(state='disable') - txtMedidaZ.config(state='disable') - txtName.config(state='disable') - txtCi.config(state='disable') - btnIncTime.config(state='disable') - btnIncTime2.config(state='disable') - btnDecTime.config(state='disable') - btnDecTime2.config(state='disable') - btnStart.config(state='disable') - lblTimeError.config(text="Presione Stop para cambiar esta opción") - btnReconstruccion.config(state='disable') - btnSetup.config(state='disable') - cmbModel.config(state='disable') - lblModeMessage.config(text='Presione Stop para cambiar esta opción') - btnCalibrar.config(state='disable') - btnReset.config(state='disable') - threading.Thread(target=reloadImage).start() - - -def btnStopClicked(): - """ - Evento del botón Stop - """ - - global Reconstruir - Reconstruir = False - time.sleep(4) - txtMedida.config(state='normal') - txtMedidaZ.config(state='normal') - txtName.config(state='normal') - txtCi.config(state='normal') - btnIncTime.config(state='normal') - btnIncTime2.config(state='normal') - btnDecTime.config(state='normal') - btnDecTime2.config(state='normal') - btnStart.config(state='normal') - btnStop.config(state='disable') - lblTimeError.config(text="") - lblModeMessage.config(text='') - btnCalibrar.config(state='normal') - btnReset.config(state='normal') - if mode == "Setup": - btnReconstruccion.config(state='normal') - else: - btnSetup.config(state='normal') - cmbModel.config(state='readonly') - -def btnResetClicked(): - """ - Evento para el botón reset - """ - - global img, photo - lblDate.config(text="Fecha: " + str(date.today().strftime("%b-%d-%Y"))) - btnReset.config(state='disable') - ImpetomC.reset() - img = Image.open('imagenInicial.jpg') - photo = ImageTk.PhotoImage(img) - lblImg.config(text="", image=photo, width=(700 / 1200) * screenWidth, height=(500 / 750) * screenHeight) - cmbModel.current(0) - lblpRangeValue.config(text=initialPValue) - lblGananciaValue.config(text=initialGValue) - lblVmaxValue.config(text=initialVmaxValue) - lblVminValue.config(text=initialVminValue) - lblSaveTimeValue.config(text=initialSaveTimeValue) - lblError.config(text="", bg="white") - btnSetupClicked() - rbtnSclOptionsDisable.select() - if tkinter.messagebox.askyesno("Reset", "Desea también eliminar los datos del paciente?"): - txtName.delete("1.0", "end") - txtCi.delete("1.0", "end") - txtMedida.delete("1.0", "end") - txtMedidaZ.delete("1.0", "end") - txtBirthDate.delete("1.0", "end") - cmbBioSex.current(0) - -""" -Esta función se encarga de actualizar las imágenes en lblImg -""" - -def reloadImage(): - """ - Esta funcion es la encargada de actualizar las imagenes en la etiqueta lblImg - """ - - global img, photo, arduinoImpetom, Reconstruir, bpWeight, screenWidth, sclRangeEnable, mode - ti = time.time() - while Reconstruir: - try: - medida = txtMedida.get("1.0", END).strip("\n") - medidaZ = txtMedidaZ.get("1.0", END).strip("\n") - vmax = float(lblVmaxValue.cget("text")) - vmin = float(lblVminValue.cget("text")) - pvalue = round(float(lblpRangeValue.cget("text")), 2) - frecValue = str(30000 - int(lblGananciaValue.cget("text")) * 100) - shape = cmbModel.get().lower() - pacBDate = str(datetime.strptime(txtBirthDate.get("1.0", 'end-1c'), "%d-%m-%Y").strftime("%Y%m%d")) - pacSex = cmbBioSex.get() - ImpetomC.generarImagenTomografica(vmax=vmax, screenWidth=screenWidth, sclEnable=sclRangeEnable, vmin=vmin, - mode=mode, shape=shape, p=pvalue, frecuenciaDDS=frecValue) - tf = time.time() - elapsedTime = int(tf - ti) - img = Image.open('IMG.jpg') - photo = ImageTk.PhotoImage(img) - lblImg.config(text="", image=photo) - lblError.config(text="", bg='#2b70e4') - if elapsedTime > int(float(lblSaveTimeValue.cget('text')) * 60): # Conversión de minutos a segundos - ImpetomC.guardarImagenEnHistoriaClinica(pacientName=txtName.get("1.0", END), - pacientCi=txtCi.get("1.0", END), p=pvalue, pacSex=pacSex, - pacBirthDate=pacBDate, medida=medida, shape=shape, - medidaZ=medidaZ, mode=mode) - ti = time.time() - if Reconstruir: - btnStop.config(state='normal') - except ImpetomCError as e: # errores por problemas de conexion del dispositivo Arduino - lblError.config(text=str(e) + " Por favor verifique la conexión y presione start nuevamente", bg='white') - winsound.Beep(440, 500) - Reconstruir = False - arduinoImpetom = 0 # arduino ImpetomC no está conectado - btnStopClicked() - ImpetomC.guardarImagenEnHistoriaClinica(pacientName=txtName.get("1.0", END), - pacientCi=txtCi.get("1.0", END), p=pvalue, pacSex=pacSex, - pacBirthDate=pacBDate, medida=medida, shape=shape, medidaZ=medidaZ, - mode=mode) - except ImpetomCElectrodeError as e: # Errores detectados sobre los electrodos - lblError.config(text=str(e), bg='white', fg='#f00') - tf = time.time() - elapsedTime = int(tf - ti) - img = Image.open('IMG.jpg') - photo = ImageTk.PhotoImage(img) - lblImg.config(text="", image=photo) - if e.regularGanancia and elapsedTime > int(float(lblSaveTimeValue.cget( - 'text')) * 60): # Para errores de regular ganancia se guarda la imágen, si son errores de falso contacto no se guarda la imágen - ImpetomC.guardarImagenEnHistoriaClinica(pacientName=txtName.get("1.0", END), - pacientCi=txtCi.get("1.0", END), p=pvalue, pacSex=pacSex, - pacBirthDate=pacBDate, medida=medida, shape=shape, - medidaZ=medidaZ, mode=mode) - ti = time.time() - elif not e.regularGanancia: - winsound.Beep(440, 500) - if Reconstruir: - btnStop.config(state='normal') - except RuntimeError: # Se esta recontruyendo la imagen y se presiona el botón de salir - time.sleep(5) - root.destroy() - -""" -Funciones botones p del jac -""" -maxPValue = 0.9 -minPValue = 0.05 -def incPRange(): - """ - Evento del boton ">" de p - """ - - enableDecpRange() - pRangeValue = float(lblpRangeValue.cget("text")) - pRangeValue += 0.01 - if pRangeValue >= maxPValue: - pRangeValue = maxPValue - disbleIncpRange() - lblpRangeValue.config(text=str(round(pRangeValue,2))) - -def incPRange2(): - """ - Evento del boton ">>" de p - """ - - enableDecpRange() - pRangeValue = float(lblpRangeValue.cget("text")) - pRangeValue += 0.1 - if pRangeValue >= maxPValue: - pRangeValue = maxPValue - disbleIncpRange() - lblpRangeValue.config(text=str(round(pRangeValue,2))) - -def decPRange(): - """ - Evento del boton "<" de p - """ - - enableIncpRange() - pRangeValue = float(lblpRangeValue.cget("text")) - pRangeValue -= 0.01 - if pRangeValue <= minPValue: - pRangeValue = minPValue - disableDecpRange() - lblpRangeValue.config(text=str(round(pRangeValue,2))) - -def decPRange2(): - """ - Evento del boton "<<" de p - """ - - enableIncpRange() - pRangeValue = float(lblpRangeValue.cget("text")) - pRangeValue -= 0.1 - if pRangeValue <= minPValue: - pRangeValue = minPValue - disableDecpRange() - lblpRangeValue.config(text=str(round(pRangeValue,2))) - -def enableIncpRange(): - """ - Permite habilitar los botones ">>" y ">" de p - """ - - btnIncpRange.config(state="normal") - btnIncpRange2.config(state="normal") - -def enableDecpRange(): - """ - Permite habilitar los botones "<" y "<<" de p - """ - - btnDecpRange.config(state="normal") - btnDecpRange2.config(state="normal") - -def disbleIncpRange(): - """ - Permite deshabilitar los botones ">>" y ">" de p - """ - - btnIncpRange.config(state="disable") - btnIncpRange2.config(state="disable") - -def disableDecpRange(): - """ - Permite deshabilitar los botones "<" y "<<" de p - """ - - btnDecpRange.config(state="disable") - btnDecpRange2.config(state="disable") - -""" -Eventos de los botones para el manejo de la ganancia -""" - -maxGananciaValue = 5 -minGananciaValue = -20 - -def incGanancia(): - """ - Evento del boton ">" de la ganancia del sistema - """ - - enableDecGanancia() - gananciaValue = int(lblGananciaValue.cget("text")) - gananciaValue += 1 - if gananciaValue >= maxGananciaValue: - gananciaValue = maxGananciaValue - disableIncGanancia() - lblGananciaValue.config(text=gananciaValue) - -def incGanancia2(): - """ - Evento del boton ">>" de la ganancia del sistema - """ - - enableDecGanancia() - gananciaValue = int(lblGananciaValue.cget("text")) - gananciaValue += 5 - if gananciaValue >= maxGananciaValue: - gananciaValue = maxGananciaValue - disableIncGanancia() - lblGananciaValue.config(text=gananciaValue) - -def decGanancia(): - """ - Evento del boton "<" de la ganancia del sistema - """ - - enableIncGanancia() - gananciaValue = int(lblGananciaValue.cget("text")) - gananciaValue -= 1 - if gananciaValue <= minGananciaValue: - gananciaValue =minGananciaValue - disableDecGanancia() - lblGananciaValue.config(text=gananciaValue) - -def decGanancia2(): - """ - Evento del boton "<<" de la ganancia del sistema - """ - - enableIncGanancia() - gananciaValue = int(lblGananciaValue.cget("text")) - gananciaValue -= 5 - if gananciaValue <= minGananciaValue: - gananciaValue = minGananciaValue - disableDecGanancia() - lblGananciaValue.config(text=gananciaValue) - -def enableIncGanancia(): - """ - Permite habilitar los botones ">>" y ">" de ganancia - """ - - btnIncGanancia.config(state="normal") - btnIncGanancia2.config(state="normal") - -def enableDecGanancia(): - """ - Permite habilitar los botones "<<" y "<" de ganancia - """ - - btnDecGanancia.config(state="normal") - btnDecGanancia2.config(state="normal") - -def disableIncGanancia(): - """ - Permite deshabilitar los botones ">>" y ">" de ganancia - """ - - btnIncGanancia.config(state="disable") - btnIncGanancia2.config(state="disable") - -def disableDecGanancia(): - """ - Permite deshabilitar los botones "<<" y "<" de ganancia - """ - - btnDecGanancia.config(state="disable") - btnDecGanancia2.config(state="disable") - -""" -Funciones botones para el valor de Vmax -""" - -maxVMAXvalue = 5 -minVMAXvalue = -20 - -def incVmax(): - """ - Evento del boton ">" de vmax - """ - - enableDecVmax() - vmaxValue = float(lblVmaxValue.cget("text")) - vmaxValue += 0.1 - if vmaxValue >= maxVMAXvalue: - vmaxValue = maxVMAXvalue - disableIncVmax() - lblVmaxValue.config(text=str(round(vmaxValue,1))) - -def incVmax2(): - """ - Evento del boton ">>" de vmax - """ - - enableDecVmax() - vmaxValue = float(lblVmaxValue.cget("text")) - vmaxValue += 1 - if vmaxValue >= maxVMAXvalue: - vmaxValue = maxVMAXvalue - disableIncVmax() - lblVmaxValue.config(text=str(round(vmaxValue,1))) - -def decVmax(): - """ - Evento del boton "<" de vmax - """ - enableIncVmax() - vmaxValue = float(lblVmaxValue.cget("text")) - vmaxValue -= 0.1 - if vmaxValue <= minVMAXvalue: - vmaxValue = minVMAXvalue - disableDecVmax() - if vmaxValue > float(lblVminValue.cget("text")): - lblVmaxValue.config(text=str(round(vmaxValue,1))) - -def decVmax2(): - """ - Evento del boton "<<" de vmax - """ - - enableIncVmax() - vmaxValue = float(lblVmaxValue.cget("text")) - vmaxValue -= 1 - if vmaxValue <= minVMAXvalue: - vmaxValue = minVMAXvalue - disableDecVmax() - if vmaxValue > float(lblVminValue.cget("text")): - lblVmaxValue.config(text=str(round(vmaxValue,1))) - -def enableIncVmax(): - """ - Permite habilitar los botones ">>" y ">" de vmax - """ - - btnIncVmax.config(state="normal") - btnIncVmax2.config(state="normal") - -def enableDecVmax(): - """ - Permite habilitar los botones "<<" y "<" de vmax - """ - - btnDecVmax.config(state="normal") - btnDecVmax2.config(state="normal") - -def disableIncVmax(): - """ - Permite deshabilitar los botones ">>" y ">" de vmax - """ - - btnIncVmax.config(state="disable") - btnIncVmax2.config(state="disable") - -def disableDecVmax(): - """ - Permite deshabilitar los botones "<<" y "<" de vmax - """ - - btnDecVmax.config(state="disable") - btnDecVmax2.config(state="disable") - -""" -Funciones botones para el valor de Vmin -""" - -maxVMINValue = 0 -minVMINValue = -40 - -def incVmin(): - """ - Evento del boton ">" de vmin - """ - - enableDecVmin() - VminValue = float(lblVminValue.cget("text")) - VminValue += 0.1 - if VminValue >= maxVMINValue: - VminValue = maxVMINValue - disableIncVmin() - if VminValue < float(lblVmaxValue.cget("text")): - lblVminValue.config(text=str(round(VminValue,1))) - -def incVmin2(): - """ - Evento del boton ">>" de vmin - """ - - enableDecVmin() - VminValue = float(lblVminValue.cget("text")) - VminValue += 1 - if VminValue >= maxVMINValue: - VminValue = maxVMINValue - disableIncVmin() - if VminValue < float(lblVmaxValue.cget("text")): - lblVminValue.config(text=str(round(VminValue,1))) - -def decVmin(): - """ - Evento del boton "<" de vmin - """ - - enableIncVmin() - VminValue = float(lblVminValue.cget("text")) - VminValue -= 0.1 - if VminValue <= minVMINValue: - VminValue = minVMINValue - disableDecVmin() - lblVminValue.config(text=str(round(VminValue,1))) - -def decVmin2(): - """ - Evento del boton "<<" de vmin - """ - - enableIncVmin() - VminValue = float(lblVminValue.cget("text")) - VminValue -= 1 - if VminValue <= minVMINValue: - VminValue = minVMINValue - disableDecVmin() - lblVminValue.config(text=str(round(VminValue,1))) - -def enableIncVmin(): - """ - Permite habilitar los botones ">>" y ">" de vmin - """ - - btnIncVmin.config(state="normal") - btnIncVmin2.config(state="normal") - -def enableDecVmin(): - """ - Permite habilitar los botones "<<" y "<" de vmin - """ - - btnDecVmin.config(state="normal") - btnDecVmin2.config(state="normal") - -def disableIncVmin(): - """ - Permite deshabilitar los botones ">>" y ">" de vmin - """ - - btnIncVmin.config(state="disable") - btnIncVmin2.config(state="disable") - -def disableDecVmin(): - """ - Permite deshabilitar los botones "<<" y "<" de vmin - """ - - btnDecVmin.config(state="disable") - btnDecVmin2.config(state="disable") - - -""" -Funciones para actualizar el modo (Reconstruction o Setup) en pantalla -""" - -def btnReconstruccionClicked(): - """ - Evento del boton modo Reconstruccion - """ - - global mode - mode = "Reconstruccion" - lblModeValue.config(text="Reconstrucción") - btnReconstruccion.config(state='disabled') - btnSetup.config(state='normal') - -def btnSetupClicked(): - """ - Evento del boton modo Setup - """ - global mode - mode = "Setup" - lblModeValue.config(text=mode) - btnReconstruccion.config(state='normal') - btnSetup.config(state='disabled') - -""" -Funciones para obtener el vector de datos homogéneo -""" - -def calibrar(): - """ - Evento del boton calibrar - """ - ImpetomC.actualizarVectorDeDatosHomogeneo() - btnReset.config(state="normal") - -""" -Funciones botones Saved Timed -""" - -maxTimeValue= 120 -minTimeValue = 0.5 -def incTime(): - """ - Evento del boton ">" de tiempo entre imagenes guardadas - """ - - enableDecTime() - timeValue = float(lblSaveTimeValue.cget("text")) - if timeValue == minTimeValue: - timeValue = 1 - else: - timeValue += 1 - if timeValue >= maxTimeValue: - timeValue = maxTimeValue - disbleIncTime() - lblSaveTimeValue.config(text=str(round(timeValue))) - -def incTime2(): - """ - Evento del boton ">>" de tiempo entre imagenes guardadas - """ - - enableDecTime() - timeValue = float(lblSaveTimeValue.cget("text")) - if timeValue == minTimeValue: - timeValue = 5 - else: - timeValue += 5 - if timeValue >= maxTimeValue: - timeValue = maxTimeValue - disbleIncTime() - lblSaveTimeValue.config(text=str(round(timeValue))) - -def decTime(): - """ - Evento del boton "<" de tiempo entre imagenes guardadas - """ - - enableIncTime() - timeValue = float(lblSaveTimeValue.cget("text")) - timeValue -= 1 - if timeValue < minTimeValue: - timeValue = minTimeValue - lblSaveTimeValue.config(text=str(round(timeValue,1))) - disableDecTime() - else: - lblSaveTimeValue.config(text=str(round(timeValue))) - -def decTime2(): - """ - Evento del boton "<<" de tiempo entre imagenes guardadas - """ - - enableIncTime() - timeValue = float(lblSaveTimeValue.cget("text")) - timeValue -= 5 - if timeValue < minTimeValue: - timeValue = minTimeValue - lblSaveTimeValue.config(text=str(round(timeValue,1)))#redondea para colocar 0.5 en pantalla - disableDecTime() - else: - lblSaveTimeValue.config(text=str(round(timeValue))) - -def enableIncTime(): - """ - Permite habilitar los botones ">>" y ">" del tiempo entre imagenes guardadas - """ - - btnIncTime.config(state="normal") - btnIncTime2.config(state="normal") - -def enableDecTime(): - """ - Permite habilitar los botones "<<" y "<" del tiempo entre imagenes guardadas - """ - - btnDecTime.config(state="normal") - btnDecTime2.config(state="normal") - -def disbleIncTime(): - """ - Permite deshabilitar los botones ">>" y ">" del tiempo entre imagenes guardadas - """ - btnIncTime.config(state="disable") - btnIncTime2.config(state="disable") - -def disableDecTime(): - """ - Permite deshabilitar los botones "<<" y "<" del tiempo entre imagenes guardadas - """ - - btnDecTime.config(state="disable") - btnDecTime2.config(state="disable") - - -""" -Funciones de los radioButtons de BP -""" - -def enableScaleOptions(): - """ - Evento del radio button para habilitar las opciones del rango de escala - """ - - global sclRangeEnable - sclRangeEnable = True - enableIncVmin() - enableIncVmax() - enableDecVmin() - enableDecVmax() - - -def disableScaleOptions(): - """ - Evento del radio button para deshabilitar las opciones del rango de escala - """ - - global sclRangeEnable - sclRangeEnable = False - disableDecVmin() - disableDecVmax() - disableIncVmax() - disableIncVmin() - -""" -Función para el control del evento de cierre de la aplicación -""" - -def onClose(): - """ - Evento de cierre de la aplicacion - """ - if tkinter.messagebox.askyesno("Salir","Está seguro que desea salir?"): - global Reconstruir - if Reconstruir: - Reconstruir=False - time.sleep(5)# esto es para que pueda finalizar el programa sin tirar error. Es por si se cierra el programa, con el programa updeteando la imagen - root.destroy() - -""" -Armado de la interfaz -Como nota general, se uso para la escala de la pantalla 1200 (width) y 750 (height), por eso se ven esos números en todo el código de aquà en más. -Esto es porque para la versión incial de la interfaz se utilizó una con ese tamaño y se logró colocar todos los widgets quedando la interfaz agradable a la vista -""" - -if __name__ == '__main__': - - root = Tk() - root.title("Impetom-C app") - screenWidth = root.winfo_screenwidth() - screenHeight = root.winfo_screenheight() - rootSize = str(screenWidth) + "x" + str(screenHeight) - root.geometry(rootSize) - - root.protocol("WM_DELETE_WINDOW", onClose) # manejo del evento de cierre por la cruz de la interfaz - root.resizable(width=False, height=False) # el usuario no puede cambiar el tamaño de la ventana - - """ - Info Impetom + logo fing - """ - - # Se agrega imagen de fondo de la app - bg = PhotoImage(file="fondo_Impetom.png") # color azul fondo #2b70e4 amarillo #eccc6e - # Create Canvas - canvas1 = Canvas(root, width=screenWidth, height=screenHeight) - canvas1.place(x=0, y=0) - canvas1.create_image((0 / 1200) * screenWidth, 0, image=bg, anchor="nw") - - """ - Datos del paciente - #f00 es el color rojo para cualquier SO - """ - lblPatient = Label(root, text="Datos del paciente", bg='#2b70e4', fg='white', font=("Helvetica", 12, "bold")) - lblPatient.place(x=(30 / 1200) * screenWidth, y=(20 / 750) * screenHeight) - - lblDate = Label(root, text="Fecha: " + str(date.today().strftime("%b-%d-%Y")), bg='#2b70e4', fg='white', - font=("Helvetica", 10, "bold")) - lblDate.place(x=(330 / 1200) * screenWidth, y=(20 / 750) * screenHeight) - - lblName = Label(root, text="Nombre:", bg='#2b70e4', fg='white', font=("Helvetica", 10, "bold")) - lblName.place(x=(50 / 1200) * screenWidth, y=(50 / 750) * screenHeight) - txtName = Text(root, width=30, height=1) - txtName.place(x=(105 / 1200) * screenWidth, y=(50 / 750) * screenHeight) - lblNameError = Label(root, fg='red', text="Este campo es obligatorio", bg='#2b70e4', font=("Helvetica", 8, "bold")) - lblNameError.place(x=(100 / 1200) * screenWidth, y=(75 / 750) * screenHeight) - - lblCi = Label(root, text="CI:", bg='#2b70e4', fg='white', font=("Helvetica", 10, "bold")) - lblCi.place(x=(50 / 1200) * screenWidth, y=(100 / 750) * screenHeight) - txtCi = Text(root, width=15, height=1) - txtCi.place(x=(100 / 1200) * screenWidth, y=(100 / 750) * screenHeight) - lblCiError = Label(root, fg='red', text="Este campo es obligatorio", bg='#2b70e4', font=("Helvetica", 8, "bold")) - lblCiError.place(x=(100 / 1200) * screenWidth, y=(125 / 750) * screenHeight) - - lblSexoBiologico = Label(root, text="Sexo:", bg='#2b70e4', fg='white', font=("Helvetica", 10, "bold")) - lblSexoBiologico.place(x=(310 / 1200) * screenWidth, y=(50 / 750) * screenHeight) - cmbBioSex = tkinter.ttk.Combobox(root, values=['Seleccionar', 'M', 'F', 'Otro'], state='readonly', width=10) - cmbBioSex.place(x=(350 / 1200) * screenWidth, y=(50 / 750) * screenHeight) - lblBioSexError = Label(root, text="Este campo es obligatorio", fg='red', bg='#2b70e4', font=("Helvetica", 8, "bold")) - lblBioSexError.place(x=(315 / 1200) * screenWidth, y=(75 / 750) * screenHeight) - cmbBioSex.current(0) - - lblBirthDate = Label(root, text="Fecha de nacimiento:", bg='#2b70e4', fg='white', font=("Helvetica", 10, "bold")) - lblBirthDate.place(x=(215 / 1200) * screenWidth, y=(100 / 750) * screenHeight) - txtBirthDate = Text(root, width=10, height=1) - txtBirthDate.place(x=(350 / 1200) * screenWidth, y=(100 / 750) * screenHeight) - lblBirthDateError = Label(root, text="Formato : dd-mm-yyyy", fg='red', bg='#2b70e4', font=("Helvetica", 8, "bold")) - lblBirthDateError.place(x=(315 / 1200) * screenWidth, y=(125 / 750) * screenHeight) - - """ - Imagen inicial en la app - """ - - photo = ImageTk.PhotoImage(img) - lblImg = Label(root, image=photo, width=(700 / 1200) * screenWidth, height=(500 / 750) * screenHeight) - lblImg.place(x=(445 / 1200) * screenWidth, y=(175 / 750) * screenHeight) - - """ - botones Start, Stop, Calibrar y Reset - """ - - btnStart = Button(root, text="Start", padx=15, pady=2, command=btnStartClicked) - btnStart.place(x=(1030 / 1200) * screenWidth, y=(690 / 750) * screenHeight) - - btnStop = Button(root, text="Stop", padx=10, pady=2, command=btnStopClicked, state='disable') - btnStop.place(x=(1090 / 1200) * screenWidth, y=(690 / 750) * screenHeight) - - btnCalibrar = Button(root, text="Calibrar", command=calibrar) - btnCalibrar.place(x=(400 / 1200) * screenWidth, y=(690 / 750) * screenHeight) - - btnReset = Button(root, text="Reset", command=btnResetClicked, state='disable') - btnReset.place(x=(1100 / 1200) * screenWidth, y=(145 / 750) * screenHeight) - - """ - Control de modo de cambio de modo - """ - - lblMode = Label(root, text="Modo: ", bg='#2b70e4', font=("Helvetica", 12, "bold")) - lblMode.place(x=(140 / 1200) * screenWidth, y=(170 / 750) * screenHeight) - lblModeValue = Label(root, text=mode, bg='#2b70e4', font=("Helvetica", 12)) - lblModeValue.place(x=(190 / 1200) * screenWidth, y=(170 / 750) * screenHeight) - - btnReconstruccion = Button(root, text="Reconstrucción", command=btnReconstruccionClicked, - font=("Helvetica", 10, "bold")) - btnReconstruccion.place(x=(110 / 1200) * screenWidth, y=(195 / 750) * screenHeight) - - btnSetup = Button(root, text="Setup", padx=10, command=btnSetupClicked, state='disable', font=("Helvetica", 10, "bold")) - btnSetup.place(x=(210 / 1200) * screenWidth, y=(195 / 750) * screenHeight) - - lblModeMessage = Label(root, fg='#f00', bg='white') - lblModeMessage.place(x=(80 / 1200) * screenWidth, y=(225 / 750) * screenHeight) - - """ - Opciones para la reconstrucción - Primero el valor p - """ - lblImgOptions = Label(root, text="Opciones de imagen", font=("Helvetica", 10, "bold"), bg='white') - lblImgOptions.place(x=(130 / 1200) * screenWidth, y=(245 / 750) * screenHeight) - - lblp = Label(root, text="p", bg='white') - lblp.place(x=(177 / 1200) * screenWidth, y=(270 / 750) * screenHeight) - initialPValue = "0.2" - lblpRangeValue = Label(root, text=initialPValue, bg='white') # p=0.25 para setup - lblpRangeValue.place(x=(175 / 1200) * screenWidth, y=(295 / 750) * screenHeight) - - btnIncpRange = Button(root, text=">", command=incPRange) - btnIncpRange.place(x=(250 / 1200) * screenWidth, y=(295 / 750) * screenHeight) - - btnIncpRange2 = Button(root, text=">>", command=incPRange2) - btnIncpRange2.place(x=(275 / 1200) * screenWidth, y=(295 / 750) * screenHeight) - - btnDecpRange = Button(root, text="<", command=decPRange) - btnDecpRange.place(x=(100 / 1200) * screenWidth, y=(295 / 750) * screenHeight) - - btnDecpRange2 = Button(root, text="<<", command=decPRange2) - btnDecpRange2.place(x=(67 / 1200) * screenWidth, y=(295 / 750) * screenHeight) - - """ - Control para la frecuencia (ganancia) - """ - lblGanancia = Label(root, text="Ganancia", bg='white') - lblGanancia.place(x=(160 / 1200) * screenWidth, y=(330 / 750) * screenHeight) - initialGValue = "-10" - lblGananciaValue = Label(root, text=initialGValue, bg='white') - lblGananciaValue.place(x=(175 / 1200) * screenWidth, y=(355 / 750) * screenHeight) - - btnIncGanancia = Button(root, text=">", command=incGanancia) - btnIncGanancia.place(x=(250 / 1200) * screenWidth, y=(355 / 750) * screenHeight) - - btnIncGanancia2 = Button(root, text=">>", command=incGanancia2) - btnIncGanancia2.place(x=(275 / 1200) * screenWidth, y=(355 / 750) * screenHeight) - - btnDecGanancia = Button(root, text="<", command=decGanancia) - btnDecGanancia.place(x=(100 / 1200) * screenWidth, y=(355 / 750) * screenHeight) - - btnDecGanancia2 = Button(root, text="<<", command=decGanancia2) - btnDecGanancia2.place(x=(67 / 1200) * screenWidth, y=(355 / 750) * screenHeight) - - """ - Control del rango de escala - """ - - lblSclRangeOptions = Label(root, text="Control de rango de escala", font=("Helvetica", 10, "bold"), bg='white') - lblSclRangeOptions.place(x=(110 / 1200) * screenWidth, y=(400 / 750) * screenHeight) - - rbtnSclOptionsEnable = Radiobutton(root, text="On", variable=0, value=1, command=enableScaleOptions, bg='white') - rbtnSclOptionsEnable.place(x=(280 / 1200) * screenWidth, y=(400 / 750) * screenHeight) - - rbtnSclOptionsDisable = Radiobutton(root, text="Off", variable=0, value=2, command=disableScaleOptions, bg='white') - rbtnSclOptionsDisable.place(x=(320 / 1200) * screenWidth, y=(400 / 750) * screenHeight) - rbtnSclOptionsDisable.select() - """ - Control Vmax - """ - - lblVmax = Label(root, text=" Valor máximo", bg='white') - lblVmax.place(x=(145 / 1200) * screenWidth, y=(425 / 750) * screenHeight) - initialVmaxValue = "0.5" - lblVmaxValue = Label(root, text=initialVmaxValue, bg='white') - lblVmaxValue.place(x=(175 / 1200) * screenWidth, y=(450 / 750) * screenHeight) - - btnIncVmax = Button(root, text=">", command=incVmax) - btnIncVmax.place(x=(250 / 1200) * screenWidth, y=(450 / 750) * screenHeight) - - btnIncVmax2 = Button(root, text=">>", command=incVmax2) - btnIncVmax2.place(x=(275 / 1200) * screenWidth, y=(450 / 750) * screenHeight) - - btnDecVmax = Button(root, text="<", command=decVmax) - btnDecVmax.place(x=(100 / 1200) * screenWidth, y=(450 / 750) * screenHeight) - - btnDecVmax2 = Button(root, text="<<", command=decVmax2) - btnDecVmax2.place(x=(67 / 1200) * screenWidth, y=(450 / 750) * screenHeight) - - """ - Control Vmin - """ - - lblVmin = Label(root, text=" Valor mÃnimo", bg='white') - lblVmin.place(x=(145 / 1200) * screenWidth, y=(480 / 750) * screenHeight) - initialVminValue = "-5.5" - lblVminValue = Label(root, text=initialVminValue, bg='white') - lblVminValue.place(x=(175 / 1200) * screenWidth, y=(510 / 750) * screenHeight) - - btnIncVmin = Button(root, text=">", command=incVmin) - btnIncVmin.place(x=(250 / 1200) * screenWidth, y=(510 / 750) * screenHeight) - - btnIncVmin2 = Button(root, text=">>", command=incVmin2) - btnIncVmin2.place(x=(275 / 1200) * screenWidth, y=(510 / 750) * screenHeight) - - btnDecVmin = Button(root, text="<", command=decVmin) - btnDecVmin.place(x=(100 / 1200) * screenWidth, y=(510 / 750) * screenHeight) - - btnDecVmin2 = Button(root, text="<<", command=decVmin2) - btnDecVmin2.place(x=(67 / 1200) * screenWidth, y=(510 / 750) * screenHeight) - - """ - Control del Modelo - """ - - lblContorno = Label(root, text="Especificaciones de contorno", font=("Helvetica", 10, "bold"), bg='white') - lblContorno.place(x=(110 / 1200) * screenWidth, y=(550 / 750) * screenHeight) - - lblModel = Label(root, text="Forma", bg='white') - lblModel.place(x=(160 / 1200) * screenWidth, y=(575 / 750) * screenHeight) - - cmbModel = tkinter.ttk.Combobox(root, values=['Thorax', 'Circle'], state='readonly') - cmbModel.place(x=(120 / 1200) * screenWidth, y=(600 / 750) * screenHeight) - cmbModel.current(0) # el valor inicial de comboBox es Thorax - - """ - Control de Medida - """ - - lblMedida = Label(root, text="PerÃmetro (mm)", bg='white') - lblMedida.place(x=(260 / 1200) * screenWidth, y=(575 / 750) * screenHeight) - - txtMedida = Text(root, width=4, height=1) - txtMedida.place(x=(280 / 1200) * screenWidth, y=(600 / 750) * screenHeight) - - lblMedidaError = Label(root, text="Campo obligatorio", fg='#f00', bg='white') - lblMedidaError.place(x=(265 / 1200) * screenWidth, y=(620 / 750) * screenHeight) - - """ - Control de Medida_Z - """ - - lblMedidaZ = Label(root, text="Altura (mm)", bg='white') - lblMedidaZ.place(x=(350 / 1200) * screenWidth, y=(575 / 750) * screenHeight) - - txtMedidaZ = Text(root, width=4, height=1) - txtMedidaZ.place(x=(360 / 1200) * screenWidth, y=(600 / 750) * screenHeight) - - lblMedidaZError = Label(root, text="Campo obligatorio", fg='#f00', bg='white') - lblMedidaZError.place(x=(345 / 1200) * screenWidth, y=(550 / 750) * screenHeight) - - """ - Control de tiempos para guardado de imágenes para historia clÃnica - """ - - lblSaveTime = Label(root, text="Tiempo de guardado (min)", font=("Helvetica", 10, "bold"), bg='white') - lblSaveTime.place(x=(100 / 1200) * screenWidth, y=(635 / 750) * screenHeight) - initialSaveTimeValue = "5" - lblSaveTimeValue = Label(root, text=initialSaveTimeValue, bg='white') - lblSaveTimeValue.place(x=(175 / 1200) * screenWidth, y=(665 / 750) * screenHeight) - - btnIncTime = Button(root, text=">", command=incTime) - btnIncTime.place(x=(250 / 1200) * screenWidth, y=(665 / 750) * screenHeight) - - btnIncTime2 = Button(root, text=">>", command=incTime2) - btnIncTime2.place(x=(275 / 1200) * screenWidth, y=(665 / 750) * screenHeight) - - btnDecTime = Button(root, text="<", command=decTime) - btnDecTime.place(x=(100 / 1200) * screenWidth, y=(665 / 750) * screenHeight) - - btnDecTime2 = Button(root, text="<<", command=decTime2) - btnDecTime2.place(x=(67 / 1200) * screenWidth, y=(665 / 750) * screenHeight) - - lblTimeError = Label(root, text="", fg='#f00', bg='white') - lblTimeError.place(x=(100 / 1200) * screenWidth, y=(700 / 750) * screenHeight) - - """ - Por problemas con Arduino al inicio de la aplicación - #2b70e4es el color azul de la imagen del banner - """ - - lblError = Label(root, text="", bg='#2b70e4', font=("Helvetica", 10, "bold"), fg="red") - lblError.place(x=(440 / 1200) * screenWidth, y=(150 / 750) * screenHeight) - disableScaleOptions() # Comienzo el programa con la escala deshabilitada - try: - ImpetomC.startUp() - arduinoImpetom = 1 # Indicador que arduinoImpetom esta conectado - except ImpetomCError as e: - lblError.config(text=str(e) + " Revise la conexión al dispositivo y presione Start", bg='white') - arduinoImpetom = 0 - - root.mainloop() diff --git "a/IMPETOM-Cl\303\255nico/fondo_Impetom.png" "b/IMPETOM-Cl\303\255nico/fondo_Impetom.png" deleted file mode 100644 index 56f7765d708e79a2da51fa72aab4a69e26ff3646..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32044 zcmbq)cT`kM@Ft3Y5=D@l1O=2Vafl)UB3W`~fB}chkmINzAW<a8QIH@x=RClWQIMRo zgdyj+7xnqxZ_oa*XP0x{dEPsHyQ{0JtE;~L`n`&hECDVRE(Qh$f!y<FFEKE%G%+wR zF>Yc5Z~DYVn}Ppbb9^cL6eGWvW(9b-W&d2q5d(v;<?6p{(QJg&7#KI)pz7LA+KLLo zrgk=*U^6=t2&bEkJ<u8hLsY`e9&Bm_abhrmSU_#XST<`KSQwyYVk}zxirk9!Qjk~B z=N>SKnun6QsfU#*$c#lo99Ps$80f$T;sj=Jv$3{y6m}D1`PHv5@b9bFTr5B%n3=io z%V#owngCB?EU%oL?1j0wTwPr`U3od}U>00FAP|U)`!Uz!#~eTl4o7!eC$Jlbts@iA z11`g_KAu4wO<_=bC#an*!&RSP6FX-oF%}kFhCf|PIyu3hCVzXkb>sy9dgFZc2`4aV zF0h#+7Y`@*l~@c6qQBb<OPV=eJ^mg<4dU?Y;rEj@^w&uCV3;FB-Q6A{#_|&4Xy*(w zh5YK_>Z3oMNWmarCy1H&V{Tvu+<Y95c}2PYx1X-Y`1b>8Hzzru`D1e)0d77a4im7c zDF+`!2+RR8<1^zh;TGfr@pJPEne*`d?dbO>|Fatz6QCFV$NY~4_(42;Jc1y8A@08) z{QB{KwpX`vHhpz974gS^oBjLlS6fl8EA3iCe=FtJ!ym2u{o=REemDG&S^n=$WoG)< zO!m$&>t8NlX37PzhS)%Covw_;^T$YLrov88Cu_*RCX%#v`ky8Od{5XKY-=IL;>KYH zF$X(aJF$qH+u54g8Ohn$L!9hv{tr|7(~BtAe+Kyfn2`N{-1^G#eyy%6mjiwPX2bhu zHo%jxq_fj2JD9j480G}E1v5Ma!(b37%#K0U83KcWMX$d2rw!owzx4nAq+?)d{#Ek- z5XlW}|DRO=G!y>iy>>8lJ3DJ}DX^^zAjSXw`u`}(Z|Q)=4J>o6zrg@__!~|jwm=Ml z0l`8~)CLG!3>b3HB-P!L)+b$)^quQ2w}(LkF6I^%p2~e0cb;S2d5R}?JK@=f3`R!A zPoGSV-RtJ+V0D4yB7v_NKRHE*{ZM&&^Mi~>L1J;8GGh1C^y6f5@@PzXO~>i6+ZKa} z=Tf(8FNn9Jc6s;QE7a6>9DEPx=+~dYNnf9Z!?E0ow-`S03eHl&Et7+NhG&2NPHKu7 zaU3(*)bB=A#+w@8YD)k4q1qAE8XxyU_1PENx(9)O{+z%|+T^^b>JtwN#{NE5?YqRk z|5p5<Z8;j!&xBtVKKe6k|NE+efro6cy?yRyU+DjR|M6`X*uKl!$cRYl*~vq!oIlMO zAL=`1$I=v}k`T)&ZW8|UmUh8S(N?Hyd>DB<!bhPg`;Q#YaVokGW);<}85xrYMEw4F zD*}-wTvAfrTmuI_m&i2M_%oF+$s(M+E$SwWjFaES|7qNA2+Si6G&FeC^|dE|yS{0h zux+V99Fd~(cPiJrlT(y*BGL*1?lEHez18?LY0#?sfP!s2dJPz^9V7McaA6*TNsA9q zIdRXPc_?jC{Fw?&ovo+Hu?IR;Pv;+q&;3`?3t2AXH1wP`-+##=^H&a<GG;=@$DYMC zzefG=@2HmEn{(aubZ-OkRsPcnpJ#F6dt}m;jVV8o<_7&%NxLd)k-O3+EL%g`?DFA1 z=88z`<<InZ*i*C**v1S)?e9coqiG5{2rS%B0rNg?{7?H%juLOT0n+z@?Qg!<{LywG z4S#144WOE-E6JH&|3|_J2M6Yi{@cW$n|qr7SW@;K;9lJ{YpYk<B7XYsJhv5i4f7r` z!V3SoQv}o0#L7z4UC@=A!EUJjD<7X-LI)tq)ht2H|7kx)u6+1$UgHKMBTnqpKW1MD zjGpH|o`e2!e9-lOr^7V#dphvI_NGi%vVY9U7=0HMCt@&|%?Nw-pT7HP$t_GC9p8?S zdS=J<k1<=~K|`(GMfq38q-pwB-^8ta^FRlT0U!TWN9upvM^@;s$HQ8-GU6v5j}Kp| zFYQ0-GnufD0an5sAu(ugPl@Tzkg|ULG$O-EOXw^8ss2ZQ#I}j^NQmGsT}A!tw3t&Z zU?p>9mqWnD3#|WoCwA?oLDJ~36fkDUUl}RC0WEnQ;!3WZO_uVnjE{}0Xs|1KRLimh zX?*^An^|M^k~&v9sQlOL-~BuL*HQEQRkQ4NS8F@$<-hHpR71*%>=IH5h*zjR4*%#o z;#y{IdlO*jU)Buz*F4vj!-9EvqAdfT)A#Fr_~UK(tp8cAX-WS|&i&hc`iK7`29K+U zFhn}+O1!{-TT;|QnSroz<@C=m{+;5J-|9{Uf+PL9w;0AR@gk&Jxo28bJMbp>uuO7C z$dsxl&6`UjIPsab53>DPsa<3V$11UxM_GI1E`-W6L=_Ai*FTAcwMX1XS;77+^5<;7 z2Z24AQ1b1k(d(SH$qBkG?56XB7{zD&3_K^%;W{J(y`}5TmwEwx_BnamH_6OX(aSc{ z{zvNP2W=TaH@hnQw*rJE3<;@4ozx8b(QFj~RdZ88U&b4J!om}Kd!AR?D7we#(PfKo zvGn%>y3~i8%k-lKCA52La<1d-7d;Cjy^55@)RT6sjIg-hZXJR77~&U+W2-=zkHL8g z!LsU#%(?zxqw=#7-KC~avkmUh9PCgt!$3f+t_#`_K~Y;W(PuOToh!-vjOo!m?=O5j zHu@gCoFjjBcJyBNI{4irqxaW;Z5eUnkL6F=LwGvWeqbp{Foz<HBBf+>52K+jB)us= zm%8UCM1>39dm81kl+#mYjYI7Z`9UKG=9N5nK8G(biRwp3PLtoaOS)cdLY6>yIRE3U z5#o<copg<eK2L+}J|=qB$3^~_FBQqSW|Xqnx+YM$`?cCoV&i?9KKnS8+33(w9~alo z?!~H<7N{1gd>;aVIh*c%5X)$P!ta<H9B;ZW9Tm7I@sGH#0Wl_2ER2ZKj3|>V<{JvS zH=MJ^u3}NQ5y?U*<ic>$ZmJVwSCg)u48ITF-@J<`r71^|P-gw{LHgfL9Dz(_?P_a9 zdET+rD-vrt<Cnx>#&_YiNC^1;fDkZmwm$`Z9?@3#yB@yM(jGJ?Td`xut(6e^b%p`c zmy;Cp^8}J93DeKgBpe8jzJPnb+?}1)->{h9xH-k=8yv1|0qnt8@dDSu!9AXgwe`6c z(LqeO=<bA>rIC9|J6_ByoFs5o8AY{_L6K&!N`c0YJsn~aeTfU^uj-TMtf>!3t$dON zM|(zI%AOrr<MF_4xS@&bPLU-n)$x22a&qOg2owXUfAtcDRi_lYHo4jC$-=4RbW%Xd z$(WA#MDLHUmJq3s%q791bjGJ12~Cu!YLJcBYS6Tv#i<8vuA$f4fYj~<lASHR&}Syw z5=PvEJ)e?V!d2kO!_OG3XJL&xsH%AWd-b8<C+>=V6)~so&P5Vm#hPwGIGKr*35Sey z`kN23e`w^eL{-J{w6#{gWYJk+<_wTjV`$r`X0>whbGNEOa72sgapcd}ClS8d(_7Dd zUuZ2KC>V46)i!AVl@Vh=|Gygu<3mc+M7fl~$W>-z*3biNLEq;zA_GL+*Aw64@z>Qn zYNQPx+M2J@(HH88v?O284Ta6q=ZqNA&H{0$YSqlHGpJ2$Up4<yO5<sv(|J7Qgg7d; zaFX80ZXx-ukI!zjeo*nt`-zP>IldDY&z(C5mx7C}&z6@<gvugS3hK&4kY@{Dbv3Q6 z^cvTQ1Q%SWZo2HX;Pg!F>yMYZ#A4beMt0m~ad&W0V=RIy`(65!hbar($IkV3pz~-> zG~c@Ddtv`Y=t0d|s@FyA-5&xh*xs)CNgc6DhZz&o$F69wp2m$#TC!=iguT<~aiqS3 zo%C8Cyn#akg0;OpJw56{3&ak(0a+I8{n$$*tQ9Ep<@q~n?8S`w6taAxolu;do8@{a z^Z`gbUxJqjI<6iZt4KM!z=G&AH&Z=y=Gh&_t~y0HTaQJa9346teZDDL^C=!!xWml` z{T4t-EjY_6?7~_nWbS$!^LotT`DLNcE;Dl|J&;&^u+7>pxeDNW@!wksec;}<nP9pn za^*lYNJdT$FWB!t{E8HP-K;?EYLqyDHtkLL(B^H_wZ^B8CFGtIY~&3RTy(p1kOhZ7 z)p*VGfDi~z*D~oHXX?}k46wuDC9kcN(c<dw+@#US>2}kNkPWTx8^OEZzAwz?M}2<O zk|QJHpN-J~FME^mWcAyoeVI<>ju{uxMBFem3wQe>PY_W7SBvKopF$eh_HL?X;c`2M z1hd$2&G;2B_(au>#tsl_C4cOlw(CPJi@%=2XT+KDFR2aSP`|rkr)e|N{I-=1$dvjC z>ZINSb9|0?*jw(<oV7uIKc2g#sVZ_}($=-xShjOz5FPr^;lsEu(JD*0qr;Gc&6}%$ zH$4p7c7GY5K;RSnDky%yg=FK{L@8F%R{5-N5EMfFqh_Tr<C;WD;vkx51(=komgK8! z=@g8!d%=pH%@5(Rkq&O+tNI?PnX;0HcX<cY%6)!z^7zu8?ct4%cpR&Xa{3zSCq~{5 z+}Ny_As4A!4(>2|97toC4syu{aX3p?w|_Tjtyc7^wRQ%!>*`N*zcTUu<!maG+S06d z_!S)wSlomO;2y=33$wjZb&4Wms<exFi$3cDLhzt~^}U7Up5%?ip1!%yQyQ6WYW``v zn%GC9CC=;l!E>d^p5+J1+b$vmfKU0>q~y#S(N`3@sRc%&(jCs)7r3{Nm34J99SX+i z;B+VgXV_9vhep9Z2anJGOU$nF8y$Ob`aU0HcQfx}BLqn5y}``G7v;s{rv2p0V8n#d z+i!7Lo~y!$1kWz1!7u4QyT-o3+)jOaji}9zhi<FMR=-Rcc8YEKX@ZmE@`doN+VRqH z{D>M&OhpWi+gTm6WkM>DTvkHL!)LMH)1!fqNv^QJ1uRLiF)bUlDANGpDjOy9esZF# zltX;1Rd(&=A^I+e^jD&#RaV+wJV;$Qs*s^XF)%C@LHaxKc#g2d*Vgyhq<geFFR2ZY ziYh=vPIwk)jxQcpbKy-GkT33d9+q;p?X`<2*6tx0^=WaRW`;SLP;A$G(qhWL_9qJ# zq057!n<#@C3k)rdhi(Wm;gVc_^=>PIPVCd<1wT5Tkm<zO*iXOsg4;9tkdAtWMR~9s zy8#1XoBLTvMB=Ni(~dohw2pv_E3pb)_U?xzZXs9LvPOQeAl9hi-PUC}+FWepSGG5Y zUsrJO*u^dkNiI+OPKFSO+Pc@bq(0^Z&!fIrG-dbMaGNT??rx7IgX{N~SBDUS8)1bR zqTOAW1>Df_`7V9YZAr)Q!!od|pFx=_UG>8%i=FijI;<Snhyu-$nG5+QHKVNWfe~Aa zaQ<u7bN}B7*oxZj@C{ul;n&K7*l!j-<!6qkgQ^ScJvP!>?ryja%IFkwe)xemh~{JM zDN>!JFm-Z(sSM48J4{k`m_ASE9*_ZNgo^Fg8BsuX3Kvw^seD~E?<+^ZcX{ER(4(th z?)<)C041cpd~d)MHXJ>gEWQz*k_GY9z$>cnlRX?Cpch~{tF`xLfE2E-HkDQNwSYOh zNfR6DM30l~@<O&YvN6P6O@s_4Dc1Ju#dXQQfL=vxyr@M+5eH;i<lSsM<eX|qX#o=Z z#DC^Pn`w<BqVuLUb9}!gCTQXAfJmZkJy-6FGVOs+`qa}x6&6j8o|F$y6d3dO#p?Iy z43Ns}bc~Mf{>=Ya!PP6}xu2{s=_*2ybl}Es|EP-6ymMJogFgL)TcgB<#<MW8=s+gh zk<iKGeB#X5xpVx`!pL(qRqpPv*w-86Ad27V`dcqzN{Zj^*RIM!Do2PZk_cIbQ3xS% zGW!sMHkSwU3g0cb&C}`ZOM{ocBb@IF#V(DECNbg%xG9f!DZfyzJ}1A-UjFWyNH}&x zSkdbtubZ57=v!5wUhpnO{cSJ}Yb<i69E6#syN`Sza?>wWn~ZcZo!7^VGqG!Jq%w_= zX;9DsN5@5mN)1K6f8sOkwq;|eQ~d7Sjct?*n>$-5^0dK)86vF{uq-J}$n+;4{?W0` ztTpXS<{^M(lB}u5IZ88EQNXu%<S@Lke%vgL9;|3-Un%_b0To@1TQpC);k}x0dZ>R2 z(GxcMY1zw1)FAJWM1Tn-3$~FMDuW}Zoii6-O04orc73{yao*9AY31036}?i+8a{pD zOt62rCL4x7oV1$GXJM=^Tca=V$Wr&YyyLe!H%WqZa>q51{WcnLUp?$-p2a|B9fc0r zv~BSHzCv-GP9Sql<`~BuwyCSck7QZ@5k4NsNqF(@oSKBuM|rG5rM*M2;UU-!@A{ID zz@zhzkIbZY-il|2$j{f3;uTC>Zr%*N$j6k>3sL~fOW%hM9)|GwdLiT>QYJGRno$$u zy!GMdc+N!XifU177b=4*n}X=~;cF#%k_p!}J71r!s@2xk|3KVUpvDGjMO4<@4|-@d zt|iXf-bYTd=|A`Jw(8`I<HkM{tpaJLt=FgQ0q;<D1#uT3ReamM5Nz*AZy*8NYu`=) zs+@{~fbXWDcw5-xNk612qo;*r=@C<|o>6k;stWmzqu9ctI|esCW>;|`d$7Mh!yvy; zDo-$eL1e8ykxR{}tq7sJ8yllo+HasEOxS{Uc_~}1|9H8X%$gY}Jg}L9KVCv>O9aMr z(G~UvuS-~%{nJff&?E_Uwl?p-pIvn>sZHX3RP}M^u)xJ=Qn-2~qBQGUfE8wU!iShr zbOl%Uf<#J|4Z2J?^;_=*Wyipr-di&HQ`T4bvT~H-uB7-V@;4`)lpRe$f;}@GcH~<_ zFbTa!j0@&*3X~f!+<O@eDfJC`3)wV>qXND{U*xN&@D3t*=><x>^u~{qKts{6reZ}; z<hR}f=h;%Hl%(nIgq<UojB6Er9W61bANG-DlL)B@OouLO`l-?%8b8h>rs=_hZ7-NZ z*;1{uh!T6geCBBnz^gcX#UtMJ_G@IYuCGQ{@hj-9-R;!mZTlFvK&s%@_RbgcA!-3- zwrq^&0lz~9Xf+P|tf3FG?JHmMGC!uikGktD5AL%!neoN=?o7Dg(stjwp4{oXZD_tY z{-$K%g)tJamW|%X@TiG`k;E`+<RuHRGXlBVR;P&smsfvt&+>8mi%p6U_c*@p)*$pf zFS<x5lYZq(Qa*7Ys7GA;z<aTXmf=iVx+l?UB2P%2B>3?7DDz{sP2-cjBcQ<C^)hO< zQ4$fo$nzqz!F{PipLQP=v*UqzbojA+O>nSYpU`dY;JWxE#g}|gTcsqS{~`<gnKiDq z=q}i?AI*p(uM^>0H4xcAy4pvj_q0|3&P&fZ*>RYUPy%nfd6(k6e{IUg6;DHh!;@S- z<Z{t0fq8#l($EV+o0%dSRU84r5qBd7z4|9^<>aUg(ia2!a(Qcbj5Xo*;bCIcYE%o+ zB_Z`ga^=;ZT3mxb<gR<<Tx=;gn>#-@`1NyOD_ih69}b7lfi>-+7f(Q#RVsdO36D_0 zZleRbmz$_=a0GpH;yboPQE{1`fMeH*L{Bt8^TTTgT56-;YzWd|&?OJI0EJ6Dw-66U zMZEn}oz<!0)7m4b{L^Td#VKsWxb0{D;r=fChx1sb#)5I>{G3Af8?{{A#xSwaiM@9n z3RG%=92)ViT+h;Y#Px~-vO8ny+%4x$5nzgEsbqL$F_E!r_t@Cnv5^ssRKeTZ{*zI6 z%_9&i;Nzhe6G}LvE1W}{`KBj7O)y*r1&YdwBUaLa-Qmulcky&nMkSF2-BjUV3cgZ5 zH@khpoyQaG<GQyRk0h(QY1Epf><SuVmlh`Eq&f~VzAq4M|E$R=if1NQrdBe{2pEpF zSzMp@-&r^-yTPdHzhusB)yzP1P_Fq9Z+O$Bzwo*~A@zQbq@iAQv<Liy!vj!~Q1#7B zZ{t0@7);*Asp?;lDWSfG)bKr3K5SQUgG3cD?$$1RXdB2|>U8&*?z}^Y>7hi}?jY-d z+O39G*0X?Pf0tf)XpU(AtclzX*I^!0qx1$&Z|Xhy3ct$L;k(HPSZD<y+y;-YZ;a|y zrqA0jfjV$IR6=9hfk^jZ>ERg*$JtTG80M4~gSEr5nzQJooO}VD(HBAUFlQb|>)}}+ zIG=;{y#}`<Q`?gQxSEc)aY01&3C6f9-&<lLRW%-b-zVJ7{-OLhd)nS<%SKVssbmEl zqitcU%qB$?^!bym7US8kaQ%;`Om}tk=-?NL2Yg#&{dpLommSP+XKx;gHUvhGXBV*t zOElDdgy?0v+i8Fh*13(`_zFk{n$YcG_nc#UG^hFGF;Q~_>tWpmC0n`Hz)zx`-fY<0 zSyp&*MUcw<&dEM_XG%5M2K=0tvugQ4vu7s!##7>p`S;<vD7DdV&A|xURM73E<;#<( z>H6BJSIQnw+h6|ysl$XD+|yI0>-wLlF@Ws#Yk0edFSJ{`g3sg{O4yGU@%HtPb8rpM zN*^qqA3|Rh9if`ZIIBE~lzWv^WF~1!k2<}hy^4!=r!p1av=Bl1;1kX14I@YrdOp|c z7oOd37ssET{oE|`S~-la!?imN-mhWQhaJ+@U%C+>tnrE0O(wqp1umU;#rxn3S3x48 z51kWJS<oPdb8n5aExR)I@jI)0KZyJ|rnHxq<r{JqWZ?yhqbHv;PqXdbZ~r(m=R9wv zOF4hefwAz7r^l^q^@*ttnU$dCcFrcEDcn}{edzdF;JS^Ajj{2QIk?O?oR*T}hoIk0 zY$mzSmf7eWtMi9;o6{bLiz$$@@hR>(`0;h;o@*QKU}CGTLvM#4E)44#9mxoZ2)K9g z`)m&hcznf2u5Ox8tObt&ii9;LE+)ejy|~3$D+|R>Q}mzeANcj5?+?t+?cMUN-1Cd@ zM12zo<3fmsWj1(UL*jXzq0jlXV_GNsxSE$8xZ!A})bA9=DoM$`!+qjmvUZ>Vh#uRh zS^-yj7`7!A!xj9BV|J0iKw`_a=~D9`QOdj6;1LfVom*OjM8jmeAAq@d{{~~4tqV5l zDOWntV4tH3UHr6|SuB^J5^J|fW*)o*OrCNrX^&Ebq9>#N;pq#Y=tv8uJ(^%v#j~VJ zv(67x8Hl0@+Q<rn4Ldpm&;TtGZ#~KkMK3~Hlw}oG<fB#D)mR~s9FYIabZduE0)Vwl zD_T9dm)sN|PcTPhN&8Nl=t2C%_6_KlRs85eH?xhjTxxo>HVan2k8FD8y*V{ptL|F^ z3X2&nuKir{Tu5u?LBkOgZ-vtr0HuoSn3WPG<=aiPZ2SNL^Md2hoAp%ZJT5~ro(3H3 z#SOrzN@gyrwCPWuUT%DB^3(RNgKs}*GNwpc`0#r{P$5(QMP{36nwz@|Y&l2v9fYYo zR(49S&;-vp!Xz@{`Va!xdNnP4mO4PW$pVK%?!GY|w|Y!f^ivV*r;k{J3w-0z9rTI| zj(}kfKRAU?6cHRw-;qbuH=nK6b|1Z;IxoAG+)&?Vw3IiuQ1l>#wfhEMHZ`VoelF9% zni)l*hbMuA$BvYb*Xa8Nw}DEpwpUYzMad1dB?$v<v9PA7S-CX(5k)0>qt0yFGV7^< zMm>bh@`jbt-1gyc|HSNg1C1S(&I;$F)w3uw7Or+yS+akUJzUxOrkRW4TsNU=Xx|$w zRSg23Y$}h2)sv;5c2(lH(y68S`tVXKLR}oE9=dGr_j@sdJqt0T^&5ignQgI)#5ZLM z#|f~>kGb(#AGUw`!oak6z@or9t0w_Z#_Dn@&uQla60UGm)1ImPRwaql(m)0wvt^Sh z7ds1CFisI&xL8r@?rk0dOuU@6=RaN?8O2f`ICY;s@<bM~evgypCT*>+xCcPfu-=x> z_#Hhn#h0G%M`^FCR17G|g~gs;oKxamEC&sBPDP?(U}&f*55Y}olMwb!z-k%cj~MTS z7Qtls5h6t)pN}blXb2=E&PMyI4dPSnNne@VJeq`oU25^8ry<aiXDv=rfhwk9lTu}J zCbRlp<0t)h*|M0w6$PvjnD*q=vBhTNy3#8hGPt)7XjX-^>-D@0Irn+x9qaO5)8~lc zj!Pd;vP<V_uPN<9N@QRKe&Op?Y>8+BAAgsdnl=KF;|*@2hT*=aDcXME#u>=~&X6fV zkAc^HeH7A;47Gx{`E_%wIM~E3k*~G!%hmY{t81}y^REx3XyuM6Mw((T?i9RB)Gn*@ z@3~8m#0zE30M9s#^5Dk_i6TTKB$5}$v){OVvK&*uN6xeqKYg^O$J)7rF#{XXE`<_B zXh%7ugJ_I2pWFH;0{d@Y9#KP=uV8YAXHMtwt4Yr5vlK{NuQ>lV;}8@#e!l@>icVq5 zq%((^`#_vP@du*eb(2vst;qNdv*Yqd8(tpw8Y-8}EE6$BAKPKAxeW2FjWn616V*;N z^?Uw37+EL;4&i_^LCl&2yQeyI53nfXGTwCABKc~Fi0~W-j%Nu5Zpkou6~2;PLtm)) zK@tyCKA@Y>3L#KYsEci!NCdF&dCHgbTE9AwgmcOSTxQnLgwQ7qoH(8?VWKZ-LUnF1 z5)VZUza=iPEvv@YuCYkKCRd_vYM)cEOnjRpTpu-yrE>#GY%A`{NT??of)Ft!9gro* z+)5unsU}4eHf}?tL#U$$#tIHTlE@U+J(^;xW*G2An!`}iY7|-tNUr?k_bBKx^)el* zzb9IVmKjCZfm$rwo&>2qcN{tDan2+TYiYL^p%7$^H5Tg3BUiZJx7@}@z)Zw8bLqX| zhFc=)b)Gc86~LGz;By<&sxxAPxf_hRLi?{<jd;!1;_Dw=tGKSlhUAVD%@2IS`ht&& zX=D)BlNSHcjzgbo?~F);TkxmvLlo}b?z9<I(IqTItt*8O*v%GUBgf5H^UwPn@7$Cn zvSfQbq%!zA-t@)M#yhn*zFG`DqPHfm3sOLDIz1#V&)hH@Je?``FWmGJF)35WAr`BF z&3@zkNiJ;!opMK2xk7lai&Jxl#!Kori|cHnQ<1ojDK$S-J{j}7=Z>L3J9<D-5=NU; z*i+=0d7w;h&^<kEB=2mB2j~R3=rFe{q*qZQS;s8%4;NrmL5WK3`V(9KnnPtxY|%d< zrzJZpd}nlMf$n43L$Y^wh$E1uW9@Gwq)#qbVhcUg?#5t|_fWOEvv@+S31`Bc8tgwq zS}PaFptW^w)TfqDIE>L@RF775DO8hMKTY84b5cj|b6AgQ^o4cGFpBAXwv{ler1iR- zgL>_r$>qJV6}mGY8CpY;fRKZR#rAkoji?T^Kb(I7y(Obv=t7Rd@BGZllAP;A?y4^u zt%i!-$&;Oe?1xctA8_fHu?GWc<M_-?mzjLl?Szk+aCYwz^*IHF5Uu%Is)`1I&xDf5 z3e?7iRQE0T`e#-UB{Z)B>nZUgs<RPA-{xE=>x`y@Z0uB?!a~;G7byB5mFYW-lMoh( z0Vxe%1bzicEONn-B}R3are)3LrRsD@58uPy0}~1r!+~dpGE|%a$^J37fhbr$EX{6S z1a_q*xVR1E&)Cb5QgPHy0y6+{Z=l#Pga1@vCTP8L{b$ck!fP%yP<9O;0Zze)T?~ZB z+k~gWQ0y)e1I`cvrK)W(6UlKI-g|{xiDhgjQ6x_HY={p#3p&xm=tBQ3>Llecew=uA zpp`OhtjdFN8vJe4u-4YQ__T)|N){IhFvBw^lFSgc^m0(67#I6oSa8P6sK|O(32c_I zM{_4SsI5uV)byqg#_aPDiTZ8IyZb)6Pl=T%blPK;==*STTz7zEo>DVT4(cK-*q3s% z(P&Di;|mxoNzCE-n)p@Ho}S2dT)@@+s?G+m!UlYvSKoy?EvUG1Wn%uQ*JwKJzKAbh zW-@iJu>Yafrdd<9!4E;4Dw|%jDWkf`T^6EwK%v`XAM<i2b-JoZ0(NSKW3Jn``89PX z^8{Ub!LChL+2hXREbnZl>%F?^cRcrXzH+T996&?3a~n}7lg<-xBqavBc1<v9N)Kt5 zFG7%sEQjN~I3f7Yf~~C+Z3Msw^Dx@D=p28riW<G~K$tG<vDgoOYzoae<7rEEv0l>9 z-puieX;f3v$#et|LIAmD3lo0`VA+o;igMz_(~*Zyd2q%+z&iH(Urno)N*!8E$R3QY z)E>~smR@kuyzjpgWK4yvmBg12Fs0j(kj#IoRfPL2&Hg-hJA^h0nFminWu>y~HWM=w z_RXKh(jW@Yd&kUWNU`<cwuF8FXhG1er_sx?tn`IJq&`r?k+r+BpQhgZ!pzp^CoSNj z*4fr`y<HaEKK7hNajjPJ74}U(W*1KT-7GIW6b2gU!!T4fiHdXTvEV{aRW*exdQ;ka zi0Y6@Uy-A_qa)P@Hjb~ymKeA=#=1Lc2Sv}(yFi(u&F;g^-ZjUf?Cl4p@G8#>f-;fl z(X}`JhE&3Ifnz*<?m-}Yr%AM#ZVEUAnvcD22fNJj5g~EM#CO=INP$GunEdbqa<+Jd z?gebDx2xG%Qhe&uF0Ax;8a}u^;fiNZ_{}hf<KiY)LruhU_WBQl9~kKg6z_=})RN=` zD1R*#@|8>%Ul)ixNnk**bFi2{&@6gec33WuCcE?)Y<6)?0tfl}iBP8+eg6FU;380X z_C(DdCuwW8j2SrlF@7gBl{4cd0G8GOP<i%t!upe#O@kaqbO&EU&^@7tZ2F<oqiC2t zkdIi8sL7TKh6+lIEBQ)v|4e1C=d<$aJoTw|ATpJAjN_?}LjlLsXvd6F%{ki<0~BIf z=RJ_OGxc1HX|*#lc;VtfRbjv#Z-2i{cFkpAoruT%*|n|;jZCkQp1b=Kr*n694i41$ zU*1@dFIV3g<Yg|ssI_w_Iks~7xa_!lOqq6MyswlI#`@eHPAT*YYiL*P0Q(yGJPi2W zx}Bn*c<`)pf7bF{Hlu9dSEi&1XAObVAtQHlNnX6+hqY@~0QP^ha@Qs&LE^xW1Y!Hb z9Ykd_MKW9Dnpk<!{btmnm|<ATe^~DR9V9wPmQ7LdUQ9tY!;mjrUVCWDxcEl^n4()8 zD)c>uwXeR&#m+e`y3oe+9o7oYvYhsZrP5hv(EPbPL00ae+J_aex*S<oxw;GGNjk89 zKkS)XAriceFZ;fgoeJ}w{{o~iqt@U1*6xM+gswKQ3idf9`)ORPGdfzp$NG+)6ptr* zTWrSBm(i_yqotW)l2wM9n_08jk*JqZv=W8{9QS+<)}LNDplH14$SJVN6)2T-RLSB! z$-fk{2jgWBE-yGd$emD?GTZD3k>NPtcYChv$n9v&Q@}M&22Xi-G(jk^{&kUNOqcY? zmpJ9piI>0UTFUt=F%5!i^)5p<MA0Y6&VM}k#dI}83BP)B#pA|9`kc=oAZ?C+-~M^Y zf%585D-Qcvsy$HNh?ab+DhP1?vFncS;{x&0*fgft@T%4n`w$L;d!$9+Wq7c5QfYfL zb99-kZD9ANh~pQar0?HpEw3n8z33h5+o?Kk(z3W+!hW&cCT!xFIZBV~Pi&;q2~;M_ z5N>xj@f?>Q9}G!}$aAR96{uC8D5@<Rc~JOE`ggq<Fh|k{ao?A~WVaWg^*Y|$KAW-I z6`4vy%?Im{5paMF4XWQQON@4l4JUQ4Ci9zBCX*hC=Ak?gOHbmemly~WJBB(v>K(tE z)k2kk1n^C|-Xjo~2rZ^>2NF-nuAlp2uMOA7)1Ve*m(r(b=ubVseN}i+sda-Q{jYQL z^>syV7R<->>x)kn1^~6monRd^cl{9hD5N8v;I}(LrD31H(_imuEN0IKLD)-tPH0v* zSxT7kfkI^n_PrGB_mr5fVP79uzSFhEA>o4Svp|jO;br~h@;6CJmbQkVTuT;+*}@6e z$+$QyL1y%Z&la`->KTCFgkrEyQ<=0L*wcqU$9Unmezp>djX`EdSX8dRy!dJuz!4B| z{MvW9KzdwU(zexh*2At_m6*eo^t#V;=G<gJjIbVl4qzfPqr=0u(Hh916o)Z|4E!z> zI6Pp~Hj^Ou=+QyU-GVy?4LLEH<hg04@^1yU#|bclO8VtoLGAn1h3piDw+l4IpiVqw z+qcIS3(I=xeuhDxfHMMQm-13sMUpS8VA%86%PIpjGl&|29klGUh1;8O5iSH_<Co9J zwRJF@HJ4$>A-^VlhaHNHaL)JPBX9R>Rx#SQGkCJ^CxX=cRR>6oWfe(E+G2N5!?7fQ zlT4?hcvBgIMU8aVwClZ2+<eY=Ue<4a8waYHzIOvMg?ZT#F~)u(2%UBv6d`!5ozXmu zV`;WR%b~g5Qijz0W9&)>AX&x5uA}Hy8%+ER1@IKQm`Fo;EXM42yy);T^M#<K2%DS< z!~pAgphLHf$R5vA07pAX{(S5*#ucSINRgHga<?@|KpLyqnxuDyt+KwcKSKy%#WMqE zP7o<~MN&BHHsXnRg`}kUoKH5j>5mLIg+O>5g~7V9+Z%w7ai6Lr%QmFQ#4|A4|Holb z;{83(8(RVFomQz2E9|(CHY#zWH9;x)2R0Ncnr0SepD}??$b73~SgpE{04U)jn!MsR zbx`zr>9w@CJp0OsYt(9zb7savfF*M1$b}Z5h(Wj!Cis%oSdORcHdP<IeAv!MDbX%h zKHLHo%(4k8Dq(KUrUjcMPjC!650C)#C*iuwgVmc&r16?A)pE8n<3$y(Lp={MRpOvb z$mFAy%JX`{Jz;dmImg`jha4)CWV#aYvCBHzg`{K-EiN3n#@}(kY~(ne&FClGpqJ_4 z(R)zG=`x(|)3blzjzMZMP9fMX=~DfE()`=EJErmwzp}+-BUABk$v0g44$98wL|lcD zmfv?{KD724CUu2*cyRcoZCiaR2MwWPP3pw_l|&RM=Dyq?SMneK^uVmBMxb-Y=AN#H zP|mEek+Q5Wj&1iEIi8LVS?LXr1J{{zWe#)n5*4S2Cq9cJonH^1+sw*?iPPb5&pk*U zL`NZ6y}R`5gAp6%l5qN_ILU1R%KcEu4etfh6b~EcmvD{OD=bmmj{U~AwPr61Qs^6r zE(8$7SmHq?13dVcHP9Jnk+_P~q+_eDc!A<THf5?FF)q&LD|E4uj{v9`y5c@sr<}TB ze$SHTGoLM_OyaBdTgN9Ss=c7}-SN`rv$>%|$KuQ(*~oAw^pNBH1Vloi`C&ATM_2Rg zD2}#fDkrT_Qpjo87@#TE13x}J3#lSAAgLzk$rx`zqo<7iqS>((dqT=OyE!9%`U z%NrBOFF!4vR<<}r_u|>rDyqq2yq24nbvSb{^{gWT?Wq@Cv3Sq>eFYa)KTaM%D{GlM zqZ_iH<My=?z_vyNNyzOh4=SSBM`^Clsa*gBipZ@~;P9%Ig_i6E$TL;s^Co@crXh6Z zjUW|?ts`jWgx6c&9VR@w@)g;jEZ~2H?%K~Y9m!<qYHO%BiYrAsH*D7H&W4yyPB=qc zD#o2F?83W%k9aH3zVxCR(u6yKWN5nuM==?j=gN_Vi`hqBQqI<CT)Q~%QM0-^V3_SV zlze(I+3sDy?^I*p;IadXYhZ2<B~mZD@G8u&JK#)Mnw2l94S6UxDVx`1x4k+?2H<yZ zf=*gca?X=`Eq>!&B6XLw(bsIfD}`5(my0avj%&yDLx?n<xTEBqA%tDSH&oKs_rQUd zkrq&$9XX1BTPqbjw8Pb|t<8EjU8}F`E3y4v)XUNEDJywUW0Xjz$VTd*m{I2}z$H;x zw&)w$UO1boxcw6i8V9HVO@h?!*+|p<C3k&+No1^2A3z6O4R;H@7Q9Txw>y&<`lI5$ zp((k-_EuU~@yn@AfGu(KecDP7-n$o9yXD&)6&w#Q<!sm53~z`bM3sFbEz~aOZ;=qU zTmo2XQJY#~V*UUTz*f8ug{3AYq(;+hPkK>T`p&4~$2aKh`o5<6lrU^ehkH3y7U2)r zm<SSk7%0Lbme$YknhpwL{SGIUQf$rrgE#eEufMVPTb|ZMJl3Byf=I`E9ezL5Lq$a_ z&E&ILzy=?h2DX@ZZTLmt_x8<<lPk>nmMyO5LT5c=6&4#(blUaU%6D4_+KAt`QGAST zDlpV<*2oO`T>M>mrqtBF${N_48>1V1q9J-Yg@xSQLZ_AYzSMY3$(DM*8r?oPxD3Ap z@tC34#ZSu>&){?OPGmkA&TeWyDW+V`K<@aM%hfSczq!kpPoZI<(*}qxXL#0nNe}{H zF$1paOcjQ9JbTUpuj5BtommXfA0UXnOYNd3F3a@&7o5+P8zrj*e2%IVdXpEHVgj;1 zKFz@dQ*2vS%wiel$Hn);CG=3c^oN^t!8kB9$l880))64C<#nOGY<=0xGaP}uyh2pJ z2en3oHWAOHk8C^S>{!@<57GCdKvA{OZBqf$kYKiryiX1i1p}$<)TnR;gNLrOe0|_s z%|QS~%*~dJF0%<>R;~_u571yY)N{s0qMQxTu@UB5i#mqAiR)KV=?oyDM=W74CN^)S z=|7Yjte;WjjRUo{cJpwGk5bHugsUHB!RpfFkV$73IaOxPI}nl<qb|n`4<YB;#Depp zk9Wsk(l=b#ixE7-w7JLDReXd>wECLAOA_343l(j@^j@lJJ(nlxv9tZlM)I4|ZhOaf zYqw{~Qj0d&@~(Lqk`Ehs(AaTJyzriHIu!wX=-jiQ7x5eCN}AAxLcy~xWAS|K^c6s6 zWy>_ZoRNJGIHm$st_zqeQgmm1WDld)d15Lb*U)Fwb(bX^Kz@MCHK<tZ3&^IDMj&6z zhQ>A895^gcyts)cxX#R0x7L7j_`Z#ON>8VEL{f(olD@mrCgx^9C_@U_o=HT^x`5(@ z_`;z~!ES3MHc?9+lzIusm>_Jj+{xBxz_q^9&!O*%jJ#A0pES3h%QDHp=Q7@25-Yut zb_I5=wqd~GaDs{y`ht^v9H!c0Gv3$~6&W>#?i_gm$BU?0A+&(ukr|T(t)QQ^U0;eX zje&<C>IJZse<4z&Sz5@?ft{>x!;f2&Y^4Uh6)-PMZOH)gl1sxjfHP7~xJn&<w)9k! z5jt+*qOY!Zg%bKAyzeEdp$;#J9-Vrk&jDuEq<=QrT_5{!`ol1EaJI<_{nfCZdzT@P zeKNp*Vf47o{R%m5c{d=MjQx%z0OYx!08$Z5nU^1Zk;Znp|85-^_yBMnU@W?-hZ)(f z<=&?Ul(fD>7js7uN&ppcB8mgI`XfMl@6oCz)EM8bBDmNZ6zw<o%9U{8Bu2mo<kv;x zmNOT??&BY0?l8LoNrI2v+$kC0#&7T1=Jqk8Lq#pJoC!L6@kpF5L6bnH6fTLQn(m{% zDA35XDNvlG=RauK$<sJ9os~(zB*sS?Pxk8Cp6`l^8#W}`-}j%iEe5KUSM2^hd|6p` zON-Kp54#mm+ypV!`HkjOE$qQhgqp8T%F;ITGalZ~U>N90MA&3j^Ry$T4JCC{nF&4n z3{4|mg}7?kTDaQa#XtZe2Ubp()lEOf+A<Ry0pvm=+$S8soi_8QIudr=q|cXvuv3m- z(SEj%lBmC+1djVU{F>aO%skz<dhYV!Alaw%J8GlHuVvZpIZii7Sb0xmO6a2yQ`#K| ztJwVmG+xD@-x6tVE_^@KEU~t_yP=-G&X{F#b%y{uZZvYzI%j9QMynce;LQy%N9X(q z-#qPpD?0@>X&S?zi)|{)gmBxK>3y)I+S+$~eAMPU7+|JApNCg$Y_P1s4y03^Yz5-2 zUEc`nq?uIR7LsMeM{l=)1%<qyQaNU_VB7G@)Cld4@J;E`jchtxtfpgIGe<3q2w9}! zAZpG_MUI-%<Gl)nzd^>|SdjC%j-EPiXGrPI-l}Uj2&0`_NQHKA5KI}-&a^7)jTn$a z>{F7t5GhSrbLEcnu*Oh})1!-d{^Si$S?9e^xv)!QAEc=6QS(_@z{b)3lCa`pbgPe{ zA!&i7K#1FTSXdroZ}QL4&DC){wWPEIPT?u!rjgjzVdCBKX5bXiX4&a^O0s7|lKkmt z5x_2KW~UbM7+H3k<7Qb_c3_#jSiK{0X*l*&t<hvog~dpW4YQ&I?X2|y3PX-kp4kzF zkM4cvELWG&y{v5@+|wO#g(Jp|=eV_+PdOSFW|cVO=4Rh1dm3V0rVrHJ@_u)XN|*g& zOBd71)t@5DYI$kbi?qUu=wl)nb}YB@FejL3c;D&1C86%wG~WKiZfpJN^)f-Fl$V{z zK5zd?AbiS)t+@!h$y7%o;A?z7CW7wJDSz=qx{bm_eV4hLF}7a;Y-|#!08m?{-EN!T zwL_ls$?%b3vIEGEUn&ni@)L;Sb8R_RCek0Gvz~2p&%9NS`dRAtIy|FRU)37$PSa{K zaQf&5?@{vco`jx?O&y>fPA@O*nZBsnjSs&mEmCjPa!Fj|;7Usk6fBnn7NrM@b$czv zLyzXd&=?pAm|&l?AJ=V#m$k)pD-zkv%^$nUP&T;v5F>0Sko}(dN|rbb#o_t*z-<Id zds|Tv-@LmKhTd-CD$B}p7lmHaRs?6;`{i`Gn|Zif%|t;INy7)%&RSHVBZ`50J}#CO zKv}m9Ft8`>ZtBCH?i^iCPg}V`iW>Hp-PthJhfn}s*zz?Fk(lE1q{;G>=i*`z`{KB+ z+3zA>YG+-6cICyY=lE1t@VUXoh5brT*<sa62ddVzp|dsdX>C<^U$6vwDnki64gkHK z(|7Z$UxoL1Ygsd&O~*P`EeYPu3pSv&uB%c~8wJv|Ne!Ff>C+rceeTxCLI%|oyG!Od zTHcWe6<TYZttAVe-joqC&E9wq`?uWi5fex0ah@rCV(|F}HwkvdgPa)Yf{bFLggNK) z?ziSXCr$=yeOJrN%rQ`6ItgH5KVbQ?8w?-JJbTJS^WZb=pyfL!!0b@~o15%ga^u&% zN_1-+eu_Gs_NWi1?o;w=sCM%3D7dhFzCY!&hSXpmBi*DvTWP!9Rql7Re251%vKMr; z)_qy%AykmbGzi>q&=(MMdvfh!cFtMkc!+<%!xiDgGJV;Jk70OjJn)%9GhAQD=7yE) z&@7SkD<i=*7^rYGWat~uSBNCJ7=DrqwNg!$tLt`s=9<eO>^vT&k~BZLS)_~BMCjIj z{TRIA6LDE@f}IYcq_}^e!H@52eE&tlq(7AE2Osv)t_Yh>rH^2&BA2fVo<S>lRM6#R zJl2{J)ah31sNs}>M(-j^sQKJCFMuF&w$%?^Fx$I~=kIs@4R*cW8{jfiGbCBrpL=m? z)nB;qY0Ze%!`DA;YsykW3(<dYt$Fcv5<V|fGSwFhtk~g{7y!swrM(C6eu%JPb>=V2 zETz5K@2O8Nb8YhN0MYGEMzIpD!<P7rCVz|D33BNRx7m)pMQqawh-5N^Los=#TW@x= zIAPy-ZKW)BwNh-)9G3M102O+TayqOk9(k4~CX++PgvAc|6;%xlqr7ZI<`sD>H?7?D z-R-2qHwUQ2>XbY!SD$M=&B86TkjNx5`tf<kdGUa|&*w+dZ9js}G9KXCN^7ErU~ib0 zEz>>rM?FP6<x*A=6<RkuYIj5%qezEGm>y=cN=)5013p8Q;yKhovD4&f9(v~4j**zF z7x{W)xv|8wW`Zi{;cAVk)jSD%Q~lAt-W*p@$QAwl-j=9sAW0&nkz1a~u{iJNJ9p;> zXM%;3)_U#|3!rcDR#&2rq8IKTS_>r&4@9iz!+&g_9pdtwy3aSKTOHhf-zG0m@_2wk zHDS<Z@X-^=lz_|H6*I;n3Vx1j3do;lKG;s{9N$NqmFiSK#4D-B1VEW^h0N^<kK=9i z1*jWN`oAhrBuOP8ft=(SI40nU(9`==NIrb*MUStRTO>DSfx1u9K<#!7^uxUKZZclx zoWp2)mpuu42yE;~(yJIM2(Mo6HVo~-u+ETFRQvG!M=Fqz1-=Cc@&LFExQV(z%Vk)X zk}H5D@W-ZTw*jfsixOUns6<IM?ryf=3IMmg*PX%_)zHuo^Av#-0Nv>gf&ughy+>56 zy*n>8=#7D>Nh87+KIz<JonvXXe_+{0)WIY%&~qdikpJK#4dox_TPSR@E9hHHStjb6 z6TymqPoJ8`Gopr|S(-RC5j(sT;SsfZ1-h}A-7-$nO_M0R=e1s!G4vson+=39q8nW; zT=d|T>ga9xtdzYBN;iF(g6oKU>#xs!)|<QYspSpbVas(-x~v!j__fh1Wm-|uUOm?1 zo)co6zHG`HwQn<PjGgUMLN|>*#_zZS8;IxK-0M+h<42QPj>lQS(6Q5;%wecSe&XU{ zP~_b5H20hskH{Ee)j9E22@4B0cvth}*v<Pky!}O-F#J1T-!&XCz+$|*fYmwO%I*eS zKB1RTP24$5mU9k8XDOYJO}!+RyQz6NDWOrg>JXnhK{q#YZ<{O1i_X^}J<QLA6>k_P zaxBeh`ANaMu(#k54QhzJ?YM(Ih@lI(?&I4z9k#iKAtC~mwMW}Mawyd+s-J&^4mkA? z{&)pA+tKqmpue6PExKjt#I$ChorP$ai?XDJ?wGpCF;BWGhIVz^Zx19YFUAiK7uKa- z8^E45-kCOqa*C+6-R-A&btzod-e*5wz6np72R1+FP73iU?WVEhvWd$Rn7~Fpl3RhD zt!<_j|Ak{Mg=X!GJ&Q8>lA3(Vf`KOB1dEw8?Bj;h6-g$>I&71v_HaBT4&rbe@;E#3 z%nRLZ+R?XOEhZzY6cEbGjK3s-I0@Y26LA+86io4E$KVX;sNjridC=e%@eqku30r!_ zdD1H1t*4_TbZ4<++#(VH>V4%i9ro=md$^3W6{O@p<S0`jzs}3wl1UZa*{}o{S2S;) zhv3-7wf5&l13BF>aBj<uPobC46^<}$beyicon!DW=eflnuLJ7ft&9gg#=!M~v!BJe z$ekl-SPLqw?PXsep8q`xaX!h_i=8jpW)Da=&LW?3w{G?mnG{kzFS=AWUFSMD9J8YT z^5iUGR7)DDz+k6Iz2y41(l52>=-9ue3^+(7hdkP7t=&Mjp!q(AK|JLJ0^GJjr<A!Q z+<_hAxriO)wLPD>cl~*)>9WGk70&HPr0QcdOk--}9;fofwV)_JzbMROx4LUT0RRos z`L(g)c!W8?v)SRpIH28;dIVkK>Urn<<E)LQE|x*(yBlAaWE{V}<($Gi9RQM@qjNTb z?)X)?SJVRt3ja5PlO3G|8UX#!KjwtnQ^zDRdUnpgi`k{BXNHj;e%9fR^Y};aVe<0) z0Uoo%snPUuaAw$SIUaM_1?RwgYH?Fv!VVQct6CsF&K)t7l4s~{PgMZuzWX9;?b}sC z<|>?@+w1Fd9Rx+U$d;98Isu~`T3Kg?a4oKECMiR_@qoj6A@p{AK0tFIEv|#sUQQ!e zs7l&jxbj?DAS{p@!Y_*JjzqT)b5&bMy^cz{Mhk1g*u#TU*N<Wy=@L7FB`O1*MXWk{ zo-+v|6(c3O<xGPdK=VeWz<w%(3TMZd@g!FsNY&`)Fu1zO{+Qv+^DBKU(-b1VF8@0D z&th8bim~Z3P#ndxQJXL8$q5^eKW2Xd7*>RG;e#ob_<Nk~3d-^q25FZw(bi7*dkl1Y z`&vK^b}XgY?BFue2n`R&@J0)A4e!2-H<TfJ;6w9s1GFy)cguT&Gi`mpnEsju3Oeq& znwB@1xS5ZC{{~pRqAB;5t)bCS&5N0Xr^H#7*3?-8=A{SzJpi{FU}giwxz{3*hS-#a z+BZffj%_N(k>`{n=^m5L2i3qm7~tAHP$7)zx_DiD+4I94ZB0C7A>elZhYL`@%;U6E z>v81san(DsWEda?yziSNOOj62e42hX3&1r_J(9ryd$P|!%lvR(Mc8>Ks!7P2*`+2_ zRmzbEf8?cMUwQKWGmiE?7hkMn5MB9tF4LViwYhwqY;#}XhGB`TV;D@>7X1@<QuBHI zddy#{(Kjw~cl5wYOqH29V?!meDE%0T@$thRc3CX8;W9_vrLmWP9f^vD9S-ukuh;S8 zv$cO=9ruOk0HwR=!G@(KI_n-1ZM+y}scBR2Is1Dbz<~fx^_2xRxouShW&>NduG6cs z$uN*Ez9$-b?5J={5aCF(0zJKi7}WPE))(Z3`hzL*>XdjVY>Z9-WYttYl3a9c-R1T7 z2R6ge!^uK2iBOdU>VlZw7n_%LKIxmku2x1|n+GW3>8xETrFWdPUTWwpWorLqo{klL zP+Bz^uwhX4-7k7v5z~KRe6*B>=Ru+f6L9rkDJj+aMA=1k(0(g&5U}ooa<cmByEJs0 zA<5^-F(Ql**3wLTe@EW#FWEV(8QPte73cgJ_m6!w-4%zS^TU_wt*J^Gw=%P}MMe&m z#{l?FQM<j3+Zf0ufa`WgQamY_Uu;fJLcT+9p~<UDfJ;u)^v`J<os&|NUZhRWt--VB zIxhRBl4Uy#25((ns&C5okCI%!ck5a+-NEbP_D8-9Gmjr{5Qe3t@-~NvcmF&FA$e1? zvRFma81vcR=1Tf!u_MWDCR$(nSa{=3F<0G};nj`oY5HiV{uQNu!If`1h6RqID0MB3 z>64)fsS|@k&&}2}&-K8m=@X9>+wQUCnQ2F3X&Rodr`rYWY-6ce!dZ+YEVSyQ=<*or zdMmQ+Ldm)UL>2$N_2Y`-?L#eq<v3m;E}T2w22(qH7;efEd+09b|Bg+hI!`RA<JmfI zIiI0>&GO=TU60JvNS^^S36HC)XRfUQxh*Qswd#DFO{C(L!FZk+xd7jn>?{<HPH5h7 z*5>>Uo4kiR!Mtot?&!CSQ*>;K1iO;(D+3yDM|atzb96c}5BKswzVTRO&-VBE?D?5( z?@Q0a<h?qh-Vhvw7aQz2kn4Z7_nm)DW?S3wI3wrSn27Xt1SyKZAkw6bBV`;w29X+y zfE0lcBb@}$VN@hQL<LmZ0D{s&lO%MdB=m@s0HH`CMOp|Y0YZ6pV4mOe7rdWdKXTvM z`(AtPb**)+YbQ66Yq1-jzHwXU^6_EtE6x&i%(jhnN!6Bb<V8VjW0|7KiIVtA%Msnz zjw1{Twi{EPd!+RYH!)62sGn?!h|=sa4BQLzvx@vGBYaFqi!_cpnQ)jR3gzgnn3%uP zySTgY#Shv4(L*+?le{uAO<W13v~U_CevcQaSg#~m8iYCBOipc?3N?_l=155z8yl<L z>3S-1(@My)zTxaiF|CViu`#HUIE=ALux&ZV#}o||qLM~it9p|tt!mFhF^^pXV%a@T zT@E*e`ItH~4IAU<oYjAE^Cm?06!Af3jZM8<4EOFC6Edo_-V*NKUFsd9&R<aarbF{- zChx8%WM(t06@p#&O5P~acT9t$GgJHxd<8-_ulJ5Sgzb*+5~BQlecH+C#$#7IpBCn9 zthL8@Touk32psECa9wPCb?0%sDu%zYXeOc{ZG?C}r>v!k<T9^Y{$MyI9Yv`hR{tS- zs`!l64W}^62BZfZ%^-~sSC+OEEz*}hy_(oy`OFXZM^q8<>MGl<aX#$<w8KNx)gX_- zr5~b)7lZX1*ern~azB2n>d`K)AP2AoOp{x@EhQzg^n>rBmtST^OG`9H8y{bs>3lZB zsTf2er1ku}p4V@WqQ4=0bHZZWGIgs8VPCPa_SKiEjF{~8sTHWD|Jh{&143}~PSDnE zKgz@PWFb@ZPRv!0X8q{Q@Z1uL-T8ivb-g39esT0j(;(~{kH><cup?(=+$SR{Z3wBW zcf8k1XmhfJ$P%0Y^r42WrGAL}_VP1p`Wzx%=s8Es_TMX38@Jr;Er1R-eF({n*UHUR z7p`t22L`5)Jt)d?u}vcd@I^`FCj(hJv6&sKkm)L6Z2YRtNdDq0^B1YfM)>->;X7Tz zLgdWa6N%>X0-NS7pOY<E4FdA53`+f&YN_1w_LlPJWD?dO()~h--;>uJ6(WZB?n>aP zZL?idvfwUX;;`=dj<{UeR7?z80?K6?pu6+-UTLH0?}ktdpX{Azr@W;M&Zy{Jz3EAH zC!L3sUA+S~TDa5!s^xO2hHBxjxwhO{!WsyC6oi407hR<qH&@<;eQ8ZmRBmt4F|}#k zNE+L7=zrE7iV-3h_MV=Rrt1GYYGY_l#Ku|zOSyxIt1z!)#&!hMnwT1Oy&S{0j}`D| z{2>&*IUOLrv(=5&Y*m$>jeJDCV}0IzyDedFrJ_boI(5u8)=I0}CvI>1H;%>?RfAgj zlWFz<4C6w1t*>0Xe=srH-t8@c&9AOl9>?UE%ZEt2NIWhcE=NUH3cV+r9n*9^yvJJm z$jbK6YB)q%MR+kdSWWnVwwA*BXf5~KwA7WUF>W$BBQ^esp&|8@+5BY>EVLCl-aq#> z_y>iAb5A-A%fFf3E+rO4RjTK?I)0Mco2jv3F^-w6{rl#Q+?3wf3!P&$Ms_NUq0fg) z%eHY5LrzZgw?vQEZIVlw>A6}Bq9ddir%iclC$f^1bt!BKt5LY~SjA`abgilx?Heho z)l=p98!b;_YU)El(u8U`>s?+#Wy`%DSyA)+)ge7R%o9syPt8P-76!H9zf(k!*zWNP zei)wZWY68WB4~{KLacDf-Rf5VJf20%@`)?W?Atk<*J+@smzdsvI#9TZJbR{<MPTBV z%8foWs}e$X_8w?wg$Pzodou=KS+J5q-%2y!=bpD4S;@O&)ikVZ9Z$oDolXmS<`m{! zVvAS{6s5r!_piw^j!ElW2oblDw4^wmLZ~`RJ}2{IoN#5s1EU0AkN&a_ZN|p6@>}h5 z_QaszuYsG2O3H~niB5Hw8#UQL9FnM+m<`*kO15&maeB(QwRb!TW1Tprv=oVUX>7=^ zCmjdgMxymtbI)GtgkICziEuLsLE+R>`Za}d=qKiv2vw%efs=>hJ=ZOe)V@{sl_57) zUZc)g_V{9k14jz4&;;VPIUMEbjoutdW)-O>ER+}YKblsak2N&tlbG@U`T5$r`cBPo z2aYP!bqp^0AQc43`?s$dqbI!Z4Kp9&0<yg$B{QIgJ7&%DWINj%LrIYyzJ;2*Tk=@t zMd&>$;a)IK>Bi`$k##yM$VQ^UjzdMSd=wlT+@*bzw7i5^Um6g{S=2NPve8akkGq*b z>}pSQnJFeJR(3c08jVzQzWTvgZAvA`rbA;`W{Z^^YqJm4BXnKO{f}OGte;T}Wv`;f z((I3IX7S+0c*Z&lAw8=Dt2TU-{x)s3(y(-iwaR`_Fu+RV6JvBwMW$KQahK`Z?lD<0 z1E2!ZZh3{v_wB53Vq*gn3&-g{;c1`f8w&+#(GyuiT?>or-LOGu<K_g3_~pe?<qW@w zofuy{Z9^@qmZ%@ay(Qf=mp&*(2%eVlY8Vmol=~(Z1rlPn{;nmZD(F~dByu%Af8#^{ zT)_N^)YGl<SI2WkdWdkZNj;Hwt9R_~4d|ahZe=Ia#!PI<l4>|IoEtAK#Ep05WK+M) zHHl>@NULYh<3TkXW*|{aolETTK!(-5iT~(RkM6XIaupH?s^>e+=x<`ktw=65As?T( zv38BG#UoItRnoFS2)>ws{6w5Y&UaDWo8Dbv?O0~~q#&)QLONNJxbm4^;=&XRxyg%w zs}YkW{@dL3DpoV)_{4%-LF#U{<|8{{GK+5wF7PKz8WESZlQ(mrcMoL-znLn$emTbP zDtr+-K}6bgISi5KD+uL@PA!Hz_dK_k`<gxG8X|R1_GS7enjwbKYoj;J=5-l<jj)0F zh^Ms57lF(PTxr4{ry7bJYUwV8YNOmx3mP@=$#SjCzviU_;*qj(3;~6cBik8#pD?SH ztc_88Kz2P*k)A~<d=kCcU1*?B=3<NISPeU0a9hN6R_25GXjMrX++sS0oJs;Q5}8OW z2nc(lw#kf_9&?uVl<S@0EVXV96KCy;w%-5Hl4Fy>8eB<y`Lpj>X@aV98)+^D9WPQB zY5W2vg@|LWRXDXwzrVf8%JZ{p+2cM=($@@}?|xR(v(ZGc3o6mA*Uz%l#f;=TIR#r@ zMXw^dAEDpANI6aZ^o*{(^XWfePX#phAVUw~uF{(j$XO!iVG5Cs+v*-KEvYZt?A@yl zu-RTu@W-A=lR2szVz~7?481#}L^s^~#8sUEeihz{@Z9c1*tV)8Zljz9?gslA<m(Se zNN??a-slUYQAuZmEvh#bEUCID>*E{c(y)(R0um@YLB>3Kpgbbt<KbAbX-_Ov2T4(* zA>10CzF8s%(-#l<du@HR2+`B(jdPKjXsB0lfqh2lg$E-|(Oh=TMy<38h8*$g%*OT2 zB><!k#Sgf<k?WO)ob(@~wqA5-`%oGLzg1%Abow}xsi-}N$l1J10tYX(I_T3r%>eG* zATj+Ix&*{-`p6#!(#TE8byj=U1uQB{)oHgeyT|FwyQtOtk&Um|RPyJohP_*qA@Jh} z^7Puo>rPmqtlb88fj7xmOagK|G?kPW{SLDr#BL|pg^(t8d>qixjyopQ4CfnEQR-;z zWrOAVys@Rq`V33mBAB;kYw@P;bhPUI4A}JFnDHpS6fPfRDC$MBk-3P?sTd`UOqOa( z>1L;H#0gy54Xf8r^i74xUpjKyreth2rX$AUy-=VMmCwXJdslEiz7cm$_?T^o|2+$P zd=H>)Ly=*~o2lM8z}3JSb~s<)EXF*)ta9hmT#n+oI3J((RvyFNl=swqe#XXFEyNyq zys*v44`q-t5K5|uFnoJ>@e9in+1Hwj|Hf&Xk$ny0vILBWj)snLf4QV7Y_P1i@F9{h zdv2$3`!I|G-c0vFMS*7ZQjS>VNL$@m(L0=1qOW-w^9-Kbpri1n!eVL_icn_85>oir zehYDmx=yeJr3vLcUuWof5sFE@@PvJR4}SYga!QJc(V1e$rVy@N@xQ=}HEH!q`2%FY z7;<aSG@Jan!U`h$QEg5^IM=b~u`}iGD+A@sajwx->&otrc#lE*AHf(rs>-687!g4U zPT}?qspZl!S(~*YH`K$@qNIn?Nu>Oj>Y>+<OV&jqE>ss)0wx3j8Ab7Y+{=*mmqUJQ z_<9Hd7Zp6Jv(wOqCm{NmhtsTWZ-_AsrrTcX-P!(y|Dnsji@=x<CmBQSQ^-YO)01mI zLoV>13|Y|j>VadvQ5+8oiiCko#hZEaqw{)i|Mb6{Zr%FN!8p%r&fZRe%((|rN6Ih) zwuc~)`;tAu{2HV>Pszjj$8QPC@2_1q-QUzerM4vC@5hH0ntneL!F#|^k0I`I$L|-B zV^<TL35&Y;vxyl_(9*h$gtx8~d3{%;RSU(y@FII6_tNe<p@`mYN83WR(ORUMF^rL8 zrp72R<py)AJm(Cdor{&Um3V7W5U+z7A<StAdCC|>(f@vj=xBAe)IzXUjf}Rt-ICRO ze?yM0*jvBHb0$U}GIet<njBYI+FBiKn6_|0EtL%PzQS%QU8WaMM`UUf6z~~=H*FT` zVb?~t?X5334v0db8p*G;Lw$oU;1*-KE<R(k9@dFgbJa(5E33pEGQz{Ae&PRd=trJ! z{F5;~QXu#*A{nv?z18_lP=CXn?u|bsE=`iYmep{}=wZ~aE3vWKj87es^2Jh>i0}oS zoS#UEuWw34M+Efg+FFWPpGr;FI=j1U-)CD-dPa{m>k&V-niA|EY`@cgEylg$uL|N! zY4?tptzqQnFCa&J#u*|O{l;HZ&5S=9cNrEH-sY^}z6?*C@4U!L;O9>m2JFu?R4ZuA z!2K?gXUt0-0{pp~#*|22re9el7i=$*{y@;mIa72t8&WIcCJ4E|*zsp_2CMe57~?+D z6UoR;NQ?duLf;jJF}}vYa_iNl`5P-(_wh<Kz7dhfOU@^@*QSzwe0w~?v|*;N)SCf5 znDbtnUMySW-Z*B)P-2RoN_A@VO+z;(#bD?JeofLCOoU*am=t)T23DIi(CSS+zV^p` z=lHUtkPn(#0Y*p(;F&ImektW)G~l3@M@CkWWC4rvyWPi|a?C-mPypWTM@@ZCo;Mru z2#@3pKjgJ_z>1dQ%|$hDD-?CnTgpY$X6n^OU!`(yzwOIA)qrSdBYbV*MVus7Q>w^- z44InYm#bbEnx`A&-5vJ9%hErlI?@>m$KyIy%tu$v%?L9%6-rCEb&<#RJGwowLVXEc zcuwp!wR>7Z{f%~_;om<uv%!#@68)U&k{N$W@6|YZGgIvJ)xwLcStWQ<C#R0`rNbP( zwsA$RFkjoND<FXvXv_5-^oKxYn4>oZFL=s9qq(>%YRI5#bu~o&U7}#+P0OqsqShQ` ztl)_ZWM6!~3$wC-F=U5rxbZSP+{t=VK6lb3*Nk50QJC{aQJ^o=KhZ5F&V4kNPTXr9 zeCPLj?dVSO!(rUiIjN{>jitKV<`O^S-qRxU%@r|y`8Q1*uC-LIR<LH)y`rv5!NeY$ zD<(8HBqhwnnFAhg6ZCaOZLxhi%;U~vy`pM@Hn*+Ne&8i$FJnM#Z|ChJMdieePv!Fg zu!*v{oQ<~HB9Ge^$gXsn7^jiAG#{yB5~)v>kr_w%cuG`<I$WxnX1t=(+)3$6m9E@- zxQ~fnYd}oZ71)$heO?_7o7oWOgWQKNJq4-y+h#L8$<C3{c5TY4YWiL`R?<*$d@n<; zyh2S_t`!QDl42SoGg@8zgz~%$Wy7kKH^P0ZQkhjXA?PJ_vfz9iGwNR0CHz-LqQcQ6 z)?bIu)8j1pnIR6d6Ovkr2An>@^7jquq?1bDwp@5&#iPfyUYidr>%H%$qc%UkY|N46 zVTOw_CBIRd-yPmAcz&dH)6hvs$xis!2?GzanuJ<Vr$P<;^h1^!P48^aHCb6%+lWxe zmLmO(mBs7<V_w1W7=3M4XBdGFu3NU%<T+hwsSs-?tQC^roi#R?Ff$w3!DY+)f2qKp zzyxA(b6cz59^0B2J8(LEv_d7gebDC}^qDMa(PTf;a<)g2heM<{_@Vu&N?{eVlST95 zS~+*?#$BqHoVMtqF^nd4Uzy73yhwUWY-OT<0w${JBG8BgP8P>vD7Yu6EX0%N`~~sP zG-$g~^uIo`D2<L#buU8e-*Gv_wQV=n=ReuFSjVwWI277^M6eaHcjqRxdaajH#A`z3 z;B|eefhEOn%1l`O>l92M9~tCTG8OSIA+{mIuPnDc<SS!EcaCSR&Znz~Le3Z;)(1I0 zMACH8S<00=R;WF*lE<QN`}g1Uq}M+d^hyi~GTA0~SFxnEs3B=;H4UPbG?`Q^?%!fo z_J|5a0X2{7eqUFhG3PHLhsj4--;^31MZLGF&p<J}%JYG6Nws+p5^l<yqr6Z}IN9@6 zSnxGe`d+gqt4n+s1Sf8|__4(W%r%eSd0=MjOgM;XQGDVYR%sr;4b()NG~$W5exu?v ziEk4IKVR}KyojW@!svZ=%2>pxJ*_Hn!ErBa>x+n1j<!@<pHNnHL^v8SsG(4Qj%bQ- z`bBN_aLHL9{OLE`?T*`M(om`~o@jVoV;Rnirhbhn`n*;@>20Z_6heg=`y_Wz-_AAB zBYJC#@3D!egM1X{mIr!8p_7qsDo&WKDhXyM*&u0D6Y_gAQcJRMJa~6oNJ}WQ7#rKf zjhGbGU~PR)+!#vk++PN#{*%~S2`A``MadjnPeH;SI#HjiVzBvq3OUxCVC5pl+KUXc zM@-y%&ZgC0;sGVArf_*&6F<$!CEJldqEZ5OKl-grIdMO~(ohS|S_unr(d40mmF!v) z-&&P{?6I;zj=X5fcZt-Y-ZH)95dzcuxpPJ2gDyGV1_BvZ<1`MP;;(nw$m8UjrqQ2b zlUoCtk5*2Dc%yj<c}-;8`^|HKfTDb|roO<W3f*P^RG05b<*9*oqYl;h>)+_0ZpY`m z&}ilpY+ZTegkBz+!;z;~9*Vw%LQiyWf<`THySYF^4gE(8Ww-9~Tv{M&weeDmgQ;z+ zc;`{KP(VAru0C|gcGb(3pT6LW6_<uD)ST9nalaGkO(pIv9=?i-uT~U5&bCz855L5e zPL!R$d=E;gOG<cMm=ln8K~kq+`Emo2QD{H@6a(l631FIG&2$KL*Z`m#9DS=ft)dc- z48IB=We@a5qWNkJDVBS6HGa)SGZRjN)*MlBVEX!|HaoR&#e4yzfV%2B*#@nWpA54y zQWF^b?_zg2Lls}Nifa@f*_0mpG9dU$#Mb#VLRqz|r~9_d%4RI3G4!sHQU6V$B~;TP zK_pjT-s{1xn~62hi1Kl2k{ShiCqc{0Qw`?^8z?!>pr>dE4}^bRg+@opiswE)O-`j0 zKM7^JLMw&VcCR!&(hS8J8`UwF3jxVh+3oJI@BKr>)eNr*^vA+^%KlESFVg1d8#`np zhbIZe_u-a+WZo*et-AtEdh(fW9yEP)UOz=hI4Zk4psaFxq)Y(XTj!P0LpL8$ZN%1n z7UEUbPzx0-k4Fr(3no!Yj}`f)ioPqj5O-DKMX)|DJDdS6mV<4Kcm$5n%hv~U(h0?~ zD%DXo=%x3swHaj{VH40~R&u2;4;^gc4=9f#Hn#yka5ui{9aOCKmvK>zrH+Jy_34c2 zSivId*qz}csWg6Pfuq9I64V0S=G(j*o2@5V9XoX*!`Us^ERm5Srbb-W*Fx8WMwg&n zJg%2}4!51P)n?R^N|87vt($$h=W@mQOq4pU>ix&1W{k(p?wSop5SGvAOEV05&60;B zXlnT4m3URJc*)b<iDiQOkCUxy?ApAcrO_H!W%_DiT#il}lU>Q~5{I+;{ouU~(|G_r zF_HtIFD0^fNyO#&kB9Y7-xB^WV7p~DLdCPO(3lSQxrQm$^6TMue$*YOvYb7SZdp|V z>7n=WL=R3;EXvjA3Fx*x2LEK+58KBYt)>dQPj(`_8P5$Jq@WM)+Sz1YlcHpTPi(h6 zBW_TYJSGbh!zfn-ky8`cSRh;1P~57r<)n*XtL4<$&qIMm$P4xkBF)$MY(i=$K$orN z^&3*6-ZETo)A!7hR4u~I%g3vp3t)LCJ?xh8Hbq^z-oVoJf@7uI&=Wq}mcxFUe~1}Y zoRv>-5LV-^Y6tYJY&iu5nSj`K07*M1TSt0e>XmjF`pj&=wTP~eX^&vD?Ar}%A(}FU zwK+2|KNng8_7VxZ_ZFN_vL#`sFn+qZ<yG9rhZH3K=&kyXt%axj$qajuzGovnIDWnm zaYqT`S55xo2@k*Qa1;{&VRCnfoYd22eP}|}67kX4sV19@a^}!8ZGU$MJ&u>AjLh!t z*N?2~K3_Vo(xi~nwt@hSSQz2jlKHR&abu5!_yKdwNary}+f7DaH_$jLHYU9vk-Mtl zYWMCUCG;9D*%GFCoK$n~2R|Tuyz#T3Jjp$VoU6@}kb*C60)78c*h<x}kk?iJ6$h=C z_PrYpbu%A+z3HS2t6E-X1HP;bniMImz0TP%PdCl+dROCk+_^+dRQ*LMbb-coy)v1G z<?)YdUfrr=jXQ6xSPOOjXhgSIx}Rk9FUIK2uGfHg2AfCYbx7C?+pFO_!;!o;!~p3& zd1`Luv-yjZ+jJ7f#Mr3CaM$1X5`Nla%QcN5%fuy4xawV&im28AitH)t!L%R6pnwpP zw9%!L$aQbimK{}m3lS=ZY<pc6_OT#_k=clE(T|2FKIg~9^2F8ax^LuUDm_!DCOGb9 zXmGB<ngoP`{_eB=O&U}|>JR9=rPNX<a-m4t^=BEAfzyB&{5q@`{JW>!{cTWpa;x;E zLk$K_OB>)X2kgwf3|kq%1LuSvcL)sMZH&I_gWe{0K6jlVjk1lbw|CCPFr=?bN^lol z#CTqe{N3|?@K*++)P7JS?NUye)S~oma8Q?XzZChp$_4E5hvGrp)4hFFsPJsm7FO1S zo#US#Y-Ce9QTbk5fUrIPGAt;>&s@Uh)Z^>mU0f;X?eK1SuQXi~XrwMRDtvE_xGm63 z7j~5p<yEGEDPvY<%=w&pS^78XF~h4M^=+X7FNP_2>aMUBY4dai;dl|y;OOe4*&PCS z4G1qjhpP?^J}vAC1ikb0FRVNkyQ62LL)Fd%-gJEl^bRjCW?$eDxYr%OPSOyZ&%D1M z6%%Z|45V2@3;1`6-7SrEjb$d^MqX9;Ip5nU3|r0{<aJ~l%jE++B#!Qw2kIFR?l$rW zI%wP!Vd~vqcx93EGE@Bo;&t!o#>g@?(sAWPN`|I3NZA)%fPQbd&8UIsM*N1P5-}H{ za>l*uGgYa{uHm7PdfWH>j+dy!0ooX+b``_W4Go$&u^XLv=ZPN^COMV&Ds0cnMlHbT z8hXiF38Yt*M>fL74tHACykYcIPHAF}xm(632B$PO+O@I|6=z&@nK6N|7X;Y^*+1@y z<k1n(Z-j+k(fp>(9yr7}%4CdmzcVS;*_|g(Nsrq|^Vg4x)$%JPuIAf<3f{9Z!n8Gp zp@K@9X|7_gSCNw%O7w(0NnSgNT<Wz+>J;{>Rv!NHd9Ns6%LoWm<NZww1n(J7Mq_|O zXxHBSV2zJY4;jf#B?Ah5+VG;=4FUura*p>u0%~fbni0a#hws9v0Mk5b0;>8uct<NW zim>GUMwR?db!KFYa)~?@+HZ>Tb~{|k3wpWW3_xc}W5YX-st4~k97_*`VIHIfeD?(O zmeTE$HM5J`(@gMhQ_^g2oGvHFKJ)SI42Df0|C>;JE-u@~xcm)nMsEDv?-*IOgu^L| zlFgFW?ONzRtax50q=XvHn4Gi%OpbSmvzi(jRPv;{oC|b;_-VXyw6mNslwq1|<ZP{C zs}ZoRKVQli5^gTUxc_EjRadPSxj3X;KGQ~5JlE0EWFwj6%!Ea;`#&OC!y2q;L;=Q7 zZ}7B$NwSe2p2KOZy964#XZAN}q84f4hCr~0`zUB!ert+Ed9eGm-6&q%MMAPVIIRp0 z+#t5l#s=h=5E=ZQSKm!|BGS-@M{a^cYR>2o3pD$txWggZqdY*(A(~GqGr8(^Lr;$m zA)Nye6gdOP7DjYm*1104)vUzeW{DYmYKDaT>UE&ulzgM$Te_+>EB>{W1#&D<aQanh z>s9X2$PIBHt{d$ORw2HtfViH(Y62nYeg?0J2OnF*HM~9Jn`RFCaSQv;6>waHY;|7e zNkj@V`_tF{b;nYZT)a8VlaikQv@az&lL!Gtge1XFs(%663AvT3<`<<IkTHCTXV$+C zL@BfC4inp74F4JMJKS0YSM%15r!#%|XHejLmpoWD%=o}Uo$7Spn-bZBr=I2Axq5KN z0W1yw;=sZR|Jy(Mp92C2aA4kW+tHy@|2z(e6oS7TJ-9K|{W>e*j->`aSgd61{=lE0 zcIHLcd^`}>4i8<~SJxm`Lv3?&-*|r8-w=pB<B_SD$9P2|Z>fj(Er$#OHS~W4GRVH+ z_t!x)E!39<7oBy3&~)~nc<ZnsvD3u%L;k+}1`)SE5M(33a{b8%qg<RgPr>>U_Qg0z zMABj#z{OD8(b<fB`^xs4zQdJ{d=VlaLVnv{_|RX730vXelfV^Y2NS22y}_yD>Kl=~ ziM<ad?k2Ju1^_4mdDl$;xz+~yJ{p16c2x1DTCK(YY_k|X7yks%&K&_yfOJmDG#Hk+ z9Na1DWWG-lT$lq}c)C>ijxcYNAzQxVpA(5oXT%*o;tI<(gzYR5vH$kl-<`A7(=NQr zbHW@AQX$F7=)j-XK=iO;YUg-M(Dk1z>>=(>2CEM~<i*H+BjB+ouL9w>f2@6`#Kd9o z>|nnO$9Q24fqki<@vg_sOmvYzBCHuZP$&Hl@gBlJ^+l-co!Nh|KhK&T1W!`fP8*gY z{4>7I#I`KZZ@!J39ICaprE#z&O2D}xE>y#Qkz;nj|990n1m*no-eLWte;aDxr|H5R zI9k&4pAp@#5vZ1)udLG0t8ID%$;W?eLqUE&zJ4(zZe>1t2fqjx3^@YkBdzlzwwh1v zkNaEtQq>gWD6s7MWJm3MZi#+lJNLjNJGa5tL;yHKczg5kpXF(y4F4GyIggJ3!%i-s z`nEJzoenm`^q&(|9tMvAMk1FPU5TjdIq+gsNOD5)t;c<XNmwOj!0hVIKbLK3FEB+* z-%x)aIx@ZvWL}WHA{!bHBJ0HH<;r&8p%|V@<T^@yxyBO^0c^$FrhwIlXpKd0wTwLc zMph*E*ZM*8B7ieEUC{$@)|{-8TZFxz<gqs(HJ@-+D=`4u%rj0F1dzc!SQ+(y?+s{9 z(Rq0KbFnvm7_R0KLKD)rJ&0ry@8}7fp>hKlAMmN2f?h=d2Oz#B4kGa%fECa14w6Tn zv6Z9h_8+%=l1J?F4QUsFB{DhX!SkuJ2e2GJvk$m3{f*Yhgz`e<v5;cNgB-Se(&7KW zSNr}UD4<)9#R*&C2gnHh6wD9O#*xp-p;S{CcaS1+5bfhvh7-|FQICOl|Ess>g`XI_ ztg;E@8}8H-UWm@thId|eFYT2B3m?j>!@tqrDthd-vRNnioQD<2DSMuKz_;X*_6>(T zJwPzzx3l|k3psmgA5)N12RMd2*|!FuV&CJCUu5=o<oj^o!tbtwd=DEC2j3wB(#rRA z@jX@Y$kX>S@x4TTXBRw%_5U3`*xd_Ru;;D(*3-sy5w<XRFC*mVC%m2tybR@lU7EY| z_&ns+sr_~e@_e6jLteI==Ux49_JDfIm+w>5??b=4>3c|gN6z;w0r{R0|6do5d`P=X W>5A%qad2KGx@LUc2>0u)KmP}r8fvKk diff --git "a/IMPETOM-Cl\303\255nico/homo_py.txt" "b/IMPETOM-Cl\303\255nico/homo_py.txt" deleted file mode 100644 index 75716c6..0000000 --- "a/IMPETOM-Cl\303\255nico/homo_py.txt" +++ /dev/null @@ -1,208 +0,0 @@ -3.7732160312805476 -2.1896383186705766 -1.2805474095796676 -1.3880742913000979 -0.9188660801564027 -0.7526881720430108 -0.9530791788856305 -0.8015640273704789 -1.2072336265884653 -0.8113391984359726 -1.0117302052785924 -1.3734115347018572 -2.7614858260019552 -3.260019550342131 -3.0254154447702835 -1.76930596285435 -1.050830889540567 -0.967741935483871 -1.6177908113391983 -0.9628543499511242 -1.3782991202346042 -0.9042033235581622 -0.884652981427175 -1.0019550342130987 -1.0410557184750733 -3.260019550342131 -3.7732160312805476 -2.5219941348973607 -1.4711632453567938 -0.8699902248289345 -0.9970674486803519 -1.2903225806451613 -1.3734115347018572 -0.8113391984359726 -0.9237536656891495 -1.2121212121212122 -0.8602150537634409 -1.2854349951124144 -2.5464320625610948 -2.9912023460410557 -2.409579667644184 -1.4027370478983383 -1.8132942326490713 -1.0654936461388074 -1.490713587487781 -0.9139784946236559 -1.0899315738025415 -1.2463343108504399 -1.1925708699902249 -1.3440860215053763 -1.632453567937439 -2.952101661779081 -3.3040078201368526 -2.2434017595307916 -1.3098729227761485 -0.7771260997067448 -1.3636363636363635 -0.8064516129032258 -1.0312805474095796 -0.6842619745845552 -0.7820136852394917 -1.2512218963831867 -1.6764418377321604 -1.1974584555229717 -3.3528836754643208 -3.4408602150537635 -3.479960899315738 -2.018572825024438 -1.1779081133919844 -0.8651026392961877 -0.7673509286412512 -0.9824046920821115 -0.9530791788856305 -0.7820136852394917 -1.8084066471163245 -1.0703812316715542 -1.7497556207233627 -2.6930596285434993 -2.952101661779081 -2.2434017595307916 -1.3098729227761485 -0.9433040078201369 -0.8455522971652004 -1.0019550342130987 -1.383186705767351 -0.8602150537634409 -0.9481915933528837 -1.4418377321603129 -1.4711632453567938 -1.383186705767351 -3.4457478005865103 -3.313782991202346 -2.697947214076246 -1.5689149560117301 -0.9237536656891495 -0.6891495601173021 -0.7380254154447703 -0.6500488758553274 -1.3685239491691104 -0.8211143695014663 -1.2854349951124144 -0.8651026392961877 -1.3978494623655915 -2.849462365591398 -3.509286412512219 -2.4682306940371457 -1.4320625610948192 -0.9286412512218963 -1.3929618768328447 -0.8260019550342131 -1.4222873900293256 -0.8699902248289345 -1.490713587487781 -0.9188660801564027 -0.9824046920821115 -1.4222873900293256 -3.0205278592375366 -3.225806451612903 -3.318670576735093 -1.9403714565004888 -1.1388074291300099 -1.35386119257087 -1.632453567937439 -0.9726295210166178 -1.1094819159335287 -0.9872922776148583 -0.9188660801564027 -1.2805474095796676 -1.1388074291300099 -3.0791788856304985 -3.005865102639296 -2.2140762463343107 -1.295210166177908 -1.3147605083088953 -0.7917888563049853 -1.2218963831867058 -0.7478005865102639 -0.8699902248289345 -0.9042033235581622 -1.217008797653959 -1.1827956989247312 -1.4173998044965788 -3.2160312805474094 -3.5777126099706744 -3.455522971652004 -2.018572825024438 -1.1827956989247312 -0.7966764418377321 -1.4565004887585533 -0.8895405669599218 -0.6647116324535679 -1.2512218963831867 -0.855327468230694 -0.967741935483871 -1.412512218963832 -3.294232649071359 -3.450635386119257 -2.297165200391007 -1.3440860215053763 -0.83088954056696 -1.520039100684262 -1.5493646138807429 -0.9237536656891495 -1.050830889540567 -1.2463343108504399 -0.7917888563049853 -1.2805474095796676 -1.3196480938416422 -3.0303030303030303 -3.4946236559139785 -3.1573802541544476 -1.8377321603128054 -1.0801564027370478 -1.2365591397849462 -0.7331378299120235 -1.0068426197458455 -0.6744868035190615 -1.2903225806451613 -1.4613880742913001 -0.8797653958944281 -1.300097751710655 -3.2844574780058653 -2.844574780058651 -2.7614858260019552 -1.6080156402737047 -0.9775171065493646 -0.8993157380254154 -0.9384164222873901 -1.2121212121212122 -1.0899315738025415 -1.2463343108504399 -0.7917888563049853 -0.8504398826979472 -1.3440860215053763 -3.064516129032258 -3.0009775171065494 -3.4164222873900294 -1.9745845552297165 -1.1583577712609971 -0.7575757575757576 -0.7526881720430108 -0.7526881720430108 -1.2218963831867058 -0.7380254154447703 -0.8015640273704789 -1.270772238514174 -1.2805474095796676 -3.2355816226783967 diff --git "a/IMPETOM-Cl\303\255nico/imagenInicial.jpg" "b/IMPETOM-Cl\303\255nico/imagenInicial.jpg" deleted file mode 100644 index 9f6367a3fd25999ac745ec5975fc55378dfebda0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18883 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 Z^TM^PEwp;(yr2I&l=r`7E(dn({{d$|O&<UN -- GitLab