diff --git a/DeetoMaison.py b/DeetoMaison.py new file mode 100644 index 0000000..21a14ac --- /dev/null +++ b/DeetoMaison.py @@ -0,0 +1,374 @@ +# -*-coding:utf-8 -* + +#Import of Usefull Libraries +import struct, time, re, os, json, subprocess +from PyQt4 import QtGui, QtCore, uic, Qt +import pdb +from numpy import * +from math import sqrt + +from soma import aims + +from brainvisa import anatomist +from brainvisa.data.writediskitem import ReadDiskItem, WriteDiskItem + +from referentialconverter import ReferentialConverter +from collections import Counter + + +import matplotlib.pyplot as plt +from scipy import signal, stats +from locateContacts import * +import copy + +#Main Class +class DeetoMaison(QtGui.QDialog): + + def __init__(self, locateData=None): + # UI init + QtGui.QWidget.__init__(self) + self.ui = uic.loadUi("DeetoMaison.ui", self) + self.setWindowTitle('Automatic electrodes localization') + self.locaData =locateData #Data from locatesElectrode.py + self.a=self.locaData.a #Anatomist Object + self.dicMeshes={} + self.CT=True + + model= QtGui.QStandardItemModel(len(self.locaData.electrodes), 1) + for i,area in enumerate([self.locaData.electrodes[i]['name'] for i in range(len(self.locaData.electrodes))]): + item = QtGui.QStandardItem(area) + item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + model.setItem(i+1, 0, item) + self.listViewElectrodes.setModel(model) + + self.connect(self.pushButtonOk, QtCore.SIGNAL('clicked()'), self.verifSelec) + self.connect(self.pushButtonCheckElec, QtCore.SIGNAL('clicked()'), self.check) + self.connect(self.pushButtonUncheckElec, QtCore.SIGNAL('clicked()'), self.uncheck) + self.connect(self.pushButtonElecAppear, QtCore.SIGNAL('clicked()'), self.printElec) + self.connect(self.pushButtonRemoveElec, QtCore.SIGNAL('clicked()'), self.removeElec) + + + + def verifSelec(self): + serpentin=False + if self.checkBoxSerpentins.checkState()==QtCore.Qt.Checked: + serpentin=True + + #dans une sous fonction appelé par un connect + Model=self.listViewElectrodes.model() + #boucle for sur les index Item =Model.item(index) + index=1 + elecSelec=[] + while index + + Form + + + + 0 + 0 + 802 + 349 + + + + Form + + + + + -1 + 9 + 801 + 291 + + + + + + + Deeto Maison + + + Qt::AlignCenter + + + + + + + + + + + Electrode List + + + + + + + + + + + + + + Ok + + + + + + + Print Electrodes + + + + + + + Remove Electrode + + + + + + + + + + + + + 198 + 310 + 151 + 27 + + + + Check all electrodes + + + + + + 380 + 310 + 171 + 27 + + + + Uncheck all electrodes + + + + + + 671 + 310 + 101 + 20 + + + + Serpentins? + + + + + + diff --git a/Image Import.xpyqt b/Image Import.xpyqt new file mode 100644 index 0000000..a96ed8a --- /dev/null +++ b/Image Import.xpyqt @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ImageImport.py b/ImageImport.py new file mode 100644 index 0000000..cb05c70 --- /dev/null +++ b/ImageImport.py @@ -0,0 +1,36 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# Import and register images in the database +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# + + +import sys + +# import PyQt4 QtCore and QtGui modules +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +from ImageImportWindow import ImageImportWindow + +if __name__ == '__main__': + + # create application + app = QApplication(sys.argv) + app.setApplicationName('Image Import') + + # create widget + w = ImageImportWindow() + w.setWindowTitle('Image Import - NOT FOR MEDICAL USAGE') + w.show() + + # connection + QObject.connect(app, SIGNAL('lastWindowClosed()'), app, SLOT('quit()')) + # Debug -> evite un pb entre ipython, pdb et qt + pyqtRemoveInputHook() + # execute application + sys.exit(app.exec_()) diff --git a/ImageImport.sh b/ImageImport.sh new file mode 100644 index 0000000..15793d8 --- /dev/null +++ b/ImageImport.sh @@ -0,0 +1,8 @@ +#!/bin/bash +cd /Users/admin/Softwares/BrainVISA-4.5/bin/ +. /Users/admin/Softwares/BrainVISA-4.5/bin/bv_env.sh /Users/admin/Softwares/BrainVISA-4.5 +cd /Users/admin/Documents/GIT/IntrAnatElectrodes/epilepsie/ +echo "#############################################################################" >> intranat-imageImport-`whoami`.log +date >> intranat-imageImport-`whoami`.log +python ImageImport.py >> intranat-imageImport-`whoami`.log + diff --git a/ImageImportWindow.py b/ImageImportWindow.py new file mode 100644 index 0000000..9513af6 --- /dev/null +++ b/ImageImportWindow.py @@ -0,0 +1,3375 @@ +# -*- coding: utf-8 -*- +# +# Importation of data in the database + image registration and normalization +#(c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# +# +#TODO +# +# Tester et finaliser l'import depuis un PACS +# +# Verifier qu'on ne convertit pas une image déjà récupérée (surtout DICOM-> Nifti !) +# +# Améliorer le choix de l'image pre/post dans BrainVisa : afficher des aperçus avec Anatomist après l'import DICOM ? +# Ou coder en C++ un créateur d'aperçu DICOM avec la lib dcmtk, ou utiliser http://sourceforge.net/projects/qdcws/ +# +#Optimisation : on peut supposer que le nombre de slices +# (SliceNumberMR) quand on ouvre un fichier permet de +# sauter les SliceNumberMR-1 suivants car ce sont les +# autres slices de la même image +# +# Onglet registration : mettre en vert les images qui ont déjà un recalage vers la T1pre, en gras l'image normalisée vers le template SPM +# FIXME La version suivante de BrainVisa (post 4.3) devrait corriger un bug dans l'insertion des items dans la base (en insérant les répertoires qui les contiennent) +# Il faudra alors virer la fonction createItemDirs que j'ai créé pour résoudre ce pb. D'autre part pour résoudre le pb pour les fichiers registration +# j'ai ajouté l'insertion des répertoires dans data/neuroDiskItems.py (fonction createParentDirectory) mais ça ne marche pas (import circulaires !) +# Donc à chaque ajout de référentiel ou de transfo, j'ai ajouté une ligne neuroHierarchy.databases.createDiskItemFromFileName A SUPPRIMER quand BrainVisa sera corrigé (après BV 4.3) + #dirItem=neuroHierarchy.databases.createDiskItemFromFileName(d, None) +# import pdb;pdb.set_trace() -> pour lancer le debugger quand on arrive sur cette ligne (sorte de breakpoint) +# ipython -q4thread locateElectrodes.py # Pour avoir ipython et Qt actifs en même temps au cours du debug + + +from PyQt4 import uic, QtGui, QtCore +import os, subprocess, re, pickle, shutil, tempfile, scipy.io, json, numpy +from scipy import ndimage + +from brainvisa import axon, processes + +from soma import aims +from soma.wip.application.api import Application +from brainvisa.data.writediskitem import ReadDiskItem, WriteDiskItem +from brainvisa.data import neuroHierarchy +#import anatomist.direct.api as anatomist +from brainvisa import anatomist +import registration + +from externalprocesses import * +from dicomutilities import * +import seegprocessing, patientinfo, pathologypatientinfo +from checkSpmVersion import * +from freesurfer.brainvisaFreesurfer import * +from TimerMessageBox import * + +import pdb + +# Matlab code : coregister file1 to file2 +def matlab_cellstr(listOfStrings): + """ Converts a list of filenames as a matlab-suitable cell table of strings and adds ',1' at the end of each string (for spm file lists) """ + return "{'"+",1' '".join([str(stri) for stri in listOfStrings])+",1'}" + +# SPM coregistration onto file1 ({'/home/manik/data/epilepsie/IRM-testOD/Pre/3DT1.img,1'}) of file 2 ({'/home/manik/data/epilepsie/IRM-testOD/Post/SagT2.img,1'}) +#spm_coregister = "try, spm('defaults', 'FMRI');spm_jobman('initcfg');\ +#matlabbatch{1}.spm.spatial.coreg.estimate.ref = %s;\ +#matlabbatch{1}.spm.spatial.coreg.estimate.source = %s;\ +#matlabbatch{1}.spm.spatial.coreg.estimate.other = {''};\ +#matlabbatch{1}.spm.spatial.coreg.estimate.eoptions.cost_fun = 'nmi';\ +#matlabbatch{1}.spm.spatial.coreg.estimate.eoptions.sep = [4 2];\ +#matlabbatch{1}.spm.spatial.coreg.estimate.eoptions.tol = [0.02 0.02 0.02 0.001 0.001 0.001 0.01 0.01 0.01 0.001 0.001 0.001];\ +#matlabbatch{1}.spm.spatial.coreg.estimate.eoptions.fwhm = [7 7];\ +#spm_jobman('run',matlabbatch); catch, disp 'AN ERROR OCCURED'; end;quit;" + +# Coregister two files and saves the matrix in an ASCII file (space-separated) +spm_coregister = """try,addpath(genpath(%s));VF=spm_vol(%s);VG=spm_vol(%s); +centermatF = eye(4); +center_F = %s; +F_orient = %s; +F_orient = reshape(F_orient,4,4)'; +centermatF(:,4) = F_orient*[center_F 1]'; +centermatG = eye(4); +center_G = %s; +G_orient = %s; +G_orient = reshape(G_orient,4,4)'; +centermatG(:,4) = G_orient*[center_G 1]'; +centeredmatF = inv(centermatF)*VF.private.mat; +centeredmatG = inv(centermatG)*VG.private.mat; +VF.mat = centeredmatF; +VF.private.mat = centeredmatF; +VF.private.mat0 = centeredmatF; +VG.mat = centeredmatG; +VG.private.mat = centeredmatG; +VG.private.mat0 = centeredmatG; +x = spm_coreg(VF,VG); +matCoreg = spm_matrix(x(:)'); +trm = centermatG*matCoreg*inv(centermatF); +trm = [trm(1:3,4)';trm(1:3,1:3)]; +dlmwrite(%s,trm, 'delimiter',' ','precision',16); \n +catch, disp 'AN ERROR OCCURED'; end;quit;""" + + +# SPM coregistration onto file1 ({'/home/manik/data/epilepsie/IRM-testOD/Pre/3DT1.img,1'}) of file 2 ({'/home/manik/data/epilepsie/IRM-testOD/Post/SagT2.img,1'}) with reslicing +spm_coregisterReslice = "try,addpath(genpath(%s)); spm('defaults', 'FMRI');spm_jobman('initcfg');\ +matlabbatch{1}.spm.spatial.coreg.estwrite.ref == %s;\ +matlabbatch{1}.spm.spatial.coreg.estwrite.source = %s;\ +matlabbatch{1}.spm.spatial.coreg.estwrite.other = {''};\ +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.cost_fun = 'nmi';\ +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.sep = [4 2];\ +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.tol = [0.02 0.02 0.02 0.001 0.001 0.001 0.01 0.01 0.01 0.001 0.001 0.001];\ +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.fwhm = [7 7];\ +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.interp = 1;\ +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.wrap = [0 0 0];\ +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.mask = 0;\ +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.prefix = 'r';\ +spm_jobman('run',matlabbatch); catch, disp 'AN ERROR OCCURED'; end;quit;" + + +# SPM normalisation of file 1 ({'/home/manik/data/epilepsie/IRM-testOD/Pre/3DT1.img,1'}) onto template +#spm_template_t1 = "{'/home/manik/prog/implantation/matlab/spm8/templates/T1.nii,1'}" +#spm_template_t1 = "{'/matlab_prog/spm8_5236/templates/T1.nii,1'}" +#spm8_normalise = """try, addpath(genpath(%s)); spm('defaults', 'FMRI');spm_jobman('initcfg'); +#matlabbatch{1}.spm.spatial.normalise.est.subj.source = %s; +#matlabbatch{1}.spm.spatial.normalise.est.subj.wtsrc = ''; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.template = %s; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.weight = ''; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.smosrc = 8; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.smoref = 0; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.regtype = 'mni'; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.cutoff = 25; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.nits = 16; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.reg = 1; +#spm_jobman('run',matlabbatch); catch, disp 'AN ERROR OCCURED'; end;quit;""" + +spm8_normalise = """try, addpath(genpath(%s)); spm('defaults', 'FMRI');spm_jobman('initcfg'); +matlabbatch{1}.spm.spatial.normalise.estwrite.subj.source = %s; +matlabbatch{1}.spm.spatial.normalise.estwrite.subj.wtsrc = ''; +matlabbatch{1}.spm.spatial.normalise.estwrite.subj.resample = %s; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.template = %s; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.weight = ''; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.smosrc = 8; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.smoref = 0; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.regtype = 'mni'; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.cutoff = 25; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.nits = 16; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.reg = 1; +matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.preserve = 0; +matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.bb = [-78 -112 -50 + 78 76 85]; +matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.vox = [1 1 1]; +matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.interp = 1; +matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.wrap = [0 0 0]; +matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.prefix = 'w'; +spm_jobman('run',matlabbatch); catch, disp 'AN ERROR OCCURED'; end;quit;""" + +spm12_normalise = """try, addpath(genpath(%s)); spm('defaults', 'FMRI');spm_jobman('initcfg'); +matlabbatch{1}.spm.spatial.normalise.estwrite.subj.vol = %s; +matlabbatch{1}.spm.spatial.normalise.estwrite.subj.resample = %s; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.biasreg = 0.0001; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.biasfwhm = 60; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.tpm = {%s}; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.affreg = 'mni'; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.reg = [0 0.001 0.5 0.05 0.2]; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.fwhm = 0; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.samp = 3; +matlabbatch{1}.spm.spatial.normalise.estwrite.woptions.bb = [-78 -112 -70 + 78 76 85]; +matlabbatch{1}.spm.spatial.normalise.estwrite.woptions.vox = [1 1 1]; +matlabbatch{1}.spm.spatial.normalise.estwrite.woptions.interp = 4; +spm_jobman('run',matlabbatch); catch, disp 'AN ERROR OCCURED'; end;quit;""" + +matlab_removeGado = """try, addpath(genpath(%s)); spm('defaults', 'FMRI');spm_jobman('initcfg'); +matlabbatch{1}.spm.spatial.preproc.channel.vols = {%s}; +matlabbatch{1}.spm.spatial.preproc.channel.biasreg = 0.001; +matlabbatch{1}.spm.spatial.preproc.channel.biasfwhm = 60; +matlabbatch{1}.spm.spatial.preproc.channel.write = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(1).tpm = {%s}; +matlabbatch{1}.spm.spatial.preproc.tissue(1).ngaus = 1; +matlabbatch{1}.spm.spatial.preproc.tissue(1).native = [1 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(1).warped = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(2).tpm = {%s}; +matlabbatch{1}.spm.spatial.preproc.tissue(2).ngaus = 1; +matlabbatch{1}.spm.spatial.preproc.tissue(2).native = [1 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(2).warped = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(3).tpm = {%s}; +matlabbatch{1}.spm.spatial.preproc.tissue(3).ngaus = 2; +matlabbatch{1}.spm.spatial.preproc.tissue(3).native = [1 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(3).warped = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(4).tpm = {%s}; +matlabbatch{1}.spm.spatial.preproc.tissue(4).ngaus = 3; +matlabbatch{1}.spm.spatial.preproc.tissue(4).native = [1 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(4).warped = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(5).tpm = {%s}; +matlabbatch{1}.spm.spatial.preproc.tissue(5).ngaus = 4; +matlabbatch{1}.spm.spatial.preproc.tissue(5).native = [1 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(5).warped = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(6).tpm = {%s}; +matlabbatch{1}.spm.spatial.preproc.tissue(6).ngaus = 2; +matlabbatch{1}.spm.spatial.preproc.tissue(6).native = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(6).warped = [0 0]; +matlabbatch{1}.spm.spatial.preproc.warp.mrf = 1; +matlabbatch{1}.spm.spatial.preproc.warp.cleanup = 1; +matlabbatch{1}.spm.spatial.preproc.warp.reg = [0 0.001 0.5 0.05 0.2]; +matlabbatch{1}.spm.spatial.preproc.warp.affreg = 'mni'; +matlabbatch{1}.spm.spatial.preproc.warp.fwhm = 0; +matlabbatch{1}.spm.spatial.preproc.warp.samp = 2; +matlabbatch{1}.spm.spatial.preproc.warp.write = [0 0]; +spm_jobman('run',matlabbatch); +c1 = spm_vol(%s); +c2 = spm_vol(%s); +c3 = spm_vol(%s); +c4 = spm_vol(%s); +Yc1 = spm_read_vols(c1); +Yc2 = spm_read_vols(c2); +Yc3 = spm_read_vols(c3); +Yc4 = spm_read_vols(c4); +keepC1 = find(Yc1 ~= 0); +keepC2 = find(Yc2 ~= 0); +keepC3 = find(Yc3 ~= 0); +keepC4 = find(Yc4 ~= 0); +all_keep = unique([keepC1; keepC2]); +fullImage = spm_vol(%s); +YfullImage = spm_read_vols(fullImage); +all_remove = [1:1:size(YfullImage(:))]; +all_remove(all_keep)=[]; +YfullImage(all_remove)=0; +fullImage.fname=%s; +spm_write_vol(fullImage,YfullImage); +catch, disp 'AN ERROR OCCURED'; end;quit;""" + +spm_inverse_y_field12 = """try,addpath(genpath(%s));spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.def = {%s}; +matlabbatch{1}.spm.util.defs.comp{1}.inv.space = {%s}; +matlabbatch{1}.spm.util.defs.out{1}.savedef.ofname = %s; +matlabbatch{1}.spm.util.defs.out{1}.savedef.savedir.saveusr = {%s}; +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + +spm_MNItoScannerBased = """try,addpath(genpath(%s));spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +matlabbatch{1}.spm.spatial.normalise.write.subj.def = {%s}; +matlabbatch{1}.spm.spatial.normalise.write.subj.resample = {%s}; +matlabbatch{1}.spm.spatial.normalise.write.woptions.bb = [-150 -150 -150 + 150 150 150]; +matlabbatch{1}.spm.spatial.normalise.write.woptions.vox = [1 1 1]; +matlabbatch{1}.spm.spatial.normalise.write.woptions.interp = 4; +matlabbatch{1}.spm.spatial.normalise.write.woptions.prefix = 'tmpMNItoScannerBased'; +matlabbatch{2}.spm.spatial.realign.write.data = { + %s + %s + }; +matlabbatch{2}.spm.spatial.realign.write.roptions.which = [2 1]; +matlabbatch{2}.spm.spatial.realign.write.roptions.interp = 4; +matlabbatch{2}.spm.spatial.realign.write.roptions.wrap = [0 0 0]; +matlabbatch{2}.spm.spatial.realign.write.roptions.mask = 1; +matlabbatch{2}.spm.spatial.realign.write.roptions.prefix = ''; +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + + +(Ui_ImageImportWindow, QDialog) = uic.loadUiType('ImageImportWindow.ui') + + +class ImageImportWindow (QDialog): + """ImageImportWindow is the main dialog class of the Image Importer software""" + + def __init__ (self, parent = None): + QDialog.__init__(self, parent) + #self.setWindowTitle('Image Import Window- NOT FOR MEDICAL USAGE') + self.ui = Ui_ImageImportWindow() + self.seriesUIDbyName = {} + self.studiesUIDbyName = {} + self.ui.setupUi(self) + self.currentProtocol = None + self.currentSubject = None + self.AcPc = {} + self.brainCenter = None + self.defaultAcqDate = QtCore.QDate(1900,1,1) + self.ui.acqDate.setDate(self.defaultAcqDate) + self.modas = {'t1mri':'Raw T1 MRI', 't2mri':'T2 MRI', 'ct': 'CT', 'pet': 'PET','fmri_epile':'fMRI-epile', 'statistic_data':'Statistic-Data', 'flair': 'FLAIR', 'freesurfer_atlas':'FreesurferAtlas', 'fgatir':'FGATIR', 'hippofreesurfer_atlas':'HippoFreesurferAtlas'} + + ## Init brainvisa to access the DB + axon.initializeProcesses() + # Allow calling brainvisa processes + from neuroProcesses import defaultContext + self.brainvisaContext = defaultContext() + + # Get Transformation Manager + self.transfoManager = registration.getTransformationManager() + + # Load anatomist + self.a = anatomist.Anatomist('-b') + + layout = QtGui.QVBoxLayout( self.ui.windowContainer1 ) + layout2 = QtGui.QHBoxLayout( ) + layout3 = QtGui.QHBoxLayout( ) + self.axWindow = self.a.createWindow( 'Axial' )#, no_decoration=True ) + self.axWindow2 = self.a.createWindow( 'Sagittal' )#, no_decoration=True ) + self.axWindow3 = self.a.createWindow( 'Axial' )#, no_decoration=True ) + self.axWindow4 = self.a.createWindow( 'Sagittal' )#, no_decoration=True ) + self.wins = [self.axWindow, self.axWindow2, self.axWindow3, self.axWindow4] + self.axWindow.setParent(self.ui.windowContainer1) + self.axWindow2.setParent(self.ui.windowContainer1) + self.axWindow3.setParent(self.ui.windowContainer1) + self.axWindow4.setParent(self.ui.windowContainer1) + layout2.addWidget( self.axWindow.getInternalRep() ) + layout2.addWidget( self.axWindow2.getInternalRep() ) + layout3.addWidget( self.axWindow3.getInternalRep() ) + layout3.addWidget( self.axWindow4.getInternalRep() ) + layout.addLayout(layout2) + layout.addLayout(layout3) + + self.dispObj = [] + + self.initialize() + + self.ui.dicomOutputPathEdit.setText(self.dicomOutputPath) + self.ui.niftiOutputPathEdit.setText(self.niftiOutputPath) + + self.threads = [] + self.waitingForThreads={} + # Init the patient informations tab + self.patientInfo = patientinfo.buildUI(self.ui.patGroupBox) + cdate = self.patientInfo['currentDate'].date() + bdate = self.patientInfo['patientBirthday'].date() + page = bdate.daysTo(cdate)/365 + self.patientInfo['patientAge'].setText(str(page)) + + self.patientInfo['comoraucune'].stateChanged.connect(self.checkbox_comor) + + self.patientInfo['patientBirthday'].dateChanged.connect(self.update_patientAge) + #self.pathologypatientInfo = pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol) + + # Recharge la BDD BrainVisa à chaque changement d'onglet + self.connect(self.ui.tabWidget, QtCore.SIGNAL('currentChanged(int)'), self.analyseBrainvisaDB) + self.connect(self.ui.tabWidget, QtCore.SIGNAL('currentChanged(int)'), self.setTabGuide) + # Brainvisa database tab + self.connect(self.ui.bvProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.bvSubjectCombo)) + self.connect(self.ui.bvSubjectCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.selectBvSubject) + self.connect(self.ui.bvSubjectCombo, QtCore.SIGNAL('activated(QString)'), self.setCurrentSubject) + self.connect(self.ui.bvImageList, QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem*)'), self.selectBvImage) + self.connect(self.ui.bvDeleteImageButton, QtCore.SIGNAL('clicked()'), self.deleteBvImage) + self.connect(self.ui.bvDeleteSubjectButton, QtCore.SIGNAL('clicked()'), self.deleteBvSubject) + # Add Subject tab + self.connect(self.ui.subjectSiteCombo, QtCore.SIGNAL('activated(QString)'), self.updatePatientCode) + self.connect(self.ui.subjectSiteCombo, QtCore.SIGNAL('editTextChanged(QString)'), self.updatePatientCode) + self.connect(self.ui.subjectYearSpinbox, QtCore.SIGNAL('valueChanged(int)'), self.updatePatientCode) + self.connect(self.ui.subjectPatientName, QtCore.SIGNAL('textChanged(QString)'), self.updatePatientCode) + self.connect(self.ui.subjectPatientFirstName, QtCore.SIGNAL('textChanged(QString)'), self.updatePatientCode) + self.connect(self.ui.subjectAddSubjectButton, QtCore.SIGNAL('clicked()'), self.storePatientInDB) + # DICOM tab + self.connect(self.ui.chooseDirButton, QtCore.SIGNAL('clicked()'), self.openDicomDir) + self.connect(self.ui.dirImportButton, QtCore.SIGNAL('clicked()'), self.importDataDir) + self.connect(self.ui.dicomOutputButton, QtCore.SIGNAL('clicked()'), lambda :self.selectOutput('Dicom')) + self.connect(self.ui.niftiOutputButton, QtCore.SIGNAL('clicked()'), lambda :self.selectOutput('Nifti')) + # PACS tab + self.connect(self.ui.pacsSearchButton, QtCore.SIGNAL('clicked()'), self.searchPacs) + + self.connect(self.ui.dirPatientList, QtCore.SIGNAL('itemSelectionChanged()'), lambda :self.patientSelectionChanged('dir')) + self.connect(self.ui.pacsPatientList, QtCore.SIGNAL('itemSelectionChanged()'), lambda :self.patientSelectionChanged('pacs')) + self.connect(self.ui.dirStudiesList, QtCore.SIGNAL('itemSelectionChanged()'), lambda :self.studiesSelectionChanged('dir')) + self.connect(self.ui.pacsStudiesList, QtCore.SIGNAL('itemSelectionChanged()'), lambda :self.studiesSelectionChanged('pacs')) + self.connect(self.ui.chooseNiftiButton, QtCore.SIGNAL('clicked()'), self.chooseNifti) + self.connect(self.ui.pacsImportButton, QtCore.SIGNAL('clicked()'), self.downloadPacs) + # Import to BrainVisa for DICOM/NIFTI/PACS + #NIFTI + self.connect(self.ui.niftiImportButton, QtCore.SIGNAL('clicked()'), self.importNifti) + self.connect(self.ui.niftiSetBraincenterButton, QtCore.SIGNAL('clicked()'), self.setBrainCenter) + self.connect(self.ui.ImportFSoutputspushButton, QtCore.SIGNAL('clicked()'),self.importFSoutput) + #PACS + self.connect(self.ui.pacsImportBVButton, QtCore.SIGNAL('clicked()'), self.importPacs) + #DICOM + self.connect(self.ui.dirImportBVButton, QtCore.SIGNAL('clicked()'), self.importDir) + # NIFTI + self.connect(self.ui.niftiProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.niftiSubjectCombo)) + self.connect(self.ui.niftiSubjectCombo, QtCore.SIGNAL('activated(QString)'), self.setCurrentSubject) + self.connect(self.ui.niftiSeqType, QtCore.SIGNAL('currentIndexChanged(QString)'),self.enable_disable_gadooption) + # Registration tab + self.connect(self.ui.regProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.regSubjectCombo)) + self.connect(self.ui.regSubjectCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.selectRegSubject) + self.connect(self.ui.regSubjectCombo, QtCore.SIGNAL('activated(QString)'), self.setCurrentSubject) + self.connect(self.ui.regImageList, QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem*)'), self.selectRegImage) + self.connect(self.ui.regImageList2, QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem*)'), self.selectRegImage2) + self.connect(self.ui.registerNormalizeSubjectButton, QtCore.SIGNAL('clicked()'), self.registerNormalizeSubject) + self.connect(self.ui.segmentationHIPHOPbutton,QtCore.SIGNAL('clicked()'),self.segmentationHIPHOP) + self.connect(self.ui.FreeSurferReconAllpushButton,QtCore.SIGNAL('clicked()'),self.runFreesurferReconAll) + self.connect(self.ui.runMarsAtlasFreesurferButton,QtCore.SIGNAL('clicked()'),self.runMarsAtlasFreesurfer) + + self.warningMEDIC() + + def setDictValue(d, k, v,button): + d[k]=v + button.setStyleSheet("background-color: rgb(90, 255, 95);") + self.connect(self.ui.regAcButton, QtCore.SIGNAL('clicked()'), lambda:setDictValue(self.AcPc,'AC',list(self.a.linkCursorLastClickedPosition()),self.ui.regAcButton)) + self.connect(self.ui.regPcButton, QtCore.SIGNAL('clicked()'), lambda:setDictValue(self.AcPc,'PC',list(self.a.linkCursorLastClickedPosition()),self.ui.regPcButton)) + self.connect(self.ui.regIhButton, QtCore.SIGNAL('clicked()'), lambda:setDictValue(self.AcPc,'IH',list(self.a.linkCursorLastClickedPosition()),self.ui.regIhButton)) + self.connect(self.ui.regLhButton, QtCore.SIGNAL('clicked()'), lambda:setDictValue(self.AcPc,'LH',list(self.a.linkCursorLastClickedPosition()),self.ui.regLhButton)) + self.connect(self.ui.regAcPcValidateButton, QtCore.SIGNAL('clicked()'), self.validateAcPc) + # Implantation tab (surgery drawings) + self.connect(self.ui.implProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.implSubjectCombo)) + self.connect(self.ui.implSubjectCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.selectImplSubject) + self.connect(self.ui.implSubjectCombo, QtCore.SIGNAL('activated(QString)'), self.setCurrentSubject) + self.connect(self.ui.implCoroOpenButton, QtCore.SIGNAL('clicked()'), self.openImplCoro) + self.connect(self.ui.implCoroImportButton, QtCore.SIGNAL('clicked()'), self.importImplCoro) + self.connect(self.ui.implSagOpenButton, QtCore.SIGNAL('clicked()'), self.openImplSag) + self.connect(self.ui.implSagImportButton, QtCore.SIGNAL('clicked()'), self.importImplSag) + self.connect(self.ui.implPptOpenButton, QtCore.SIGNAL('clicked()'), self.openImplPpt) + self.connect(self.ui.implPptImportButton, QtCore.SIGNAL('clicked()'), self.importImplPpt) + self.connect(self.ui.implPdfOpenButton, QtCore.SIGNAL('clicked()'), self.openImplPdf) + self.connect(self.ui.implPdfImportButton, QtCore.SIGNAL('clicked()'), self.importImplPdf) + self.connect(self.ui.implPdfOpenButton2, QtCore.SIGNAL('clicked()'), self.openImplPdf2) + self.connect(self.ui.implPdfImportButton2, QtCore.SIGNAL('clicked()'), self.importImplPdf2) + self.connect(self.ui.implElListPdfOpenButton, QtCore.SIGNAL('clicked()'), self.openImplElListPdf) + self.connect(self.ui.implElListPdfImportButton, QtCore.SIGNAL('clicked()'), self.importImplElListPdf) + # Infos patient tab + self.connect(self.ui.patProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.patSubjectCombo)) + #self._pathologyinfo = lambda :pathologypatientinfo.buildUI() + self.connect(self.ui.patProtocolCombo, QtCore.SIGNAL('activated(QString)'),lambda :pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol)) #lambda :pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol)) self._pathologyinfo(self.ui.patpatGroupBox,self.currentProtocol) + self.connect(self.ui.patSubjectCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.selectPatSubject) + self.connect(self.ui.patSubjectCombo, QtCore.SIGNAL('activated(QString)'), self.setCurrentSubject) + self.connect(self.ui.patInfoValidate,QtCore.SIGNAL('clicked()'),self.ValidatePatInfo) + + # Importation SEEG tab + self.connect(self.ui.seegProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.seegSubjectCombo)) + self.connect(self.ui.seegSubjectCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.selectSeegSubject) + self.connect(self.ui.seegSubjectCombo, QtCore.SIGNAL('activated(QString)'), self.setCurrentSubject) + self.connect(self.ui.seegManipsBaseCombo, QtCore.SIGNAL('activated(QString)'), self.manipSelected) + self.connect(self.ui.chooseSeegButton, QtCore.SIGNAL('clicked()'), self.chooseSeeg) + self.connect(self.ui.seegImportButton, QtCore.SIGNAL('clicked()'), self.seegImport) + + #Preference tab + self.connect(self.ui.prefSpmTemplateButton, QtCore.SIGNAL('clicked()'), self.setSpmTemplatePath) + self.connect(self.ui.prefANTsButton, QtCore.SIGNAL('clicked()'), self.setANTsPath) + self.connect(self.ui.prefSpmStandaloneButton, QtCore.SIGNAL('clicked()'), self.setSpmStandalonePath) + self.connect(self.ui.prefFreesurferButton, QtCore.SIGNAL('clicked()'), self.setFreesurferPath) + self.connect(self.ui.prefNoDBFileLocationButton, QtCore.SIGNAL('clicked()'),self.setNoDBFilePath) + self.connect(self.ui.prefANTScheckbox, QtCore.SIGNAL('clicked()'), lambda: self.setPrefCoregister('ANTS')) + self.connect(self.ui.prefSPMcheckbox, QtCore.SIGNAL('clicked()'), lambda: self.setPrefCoregister('SPM')) + self.connect(self.ui.prefAimscheckbox, QtCore.SIGNAL('clicked()'), lambda: self.setPrefCoregister('Aims')) + self.ui.radioButtonProject_4.toggled.connect(self.switchProjectButton) + self.ui.radioButtonProject_3.toggled.connect(self.switchProjectButton) + self.ui.radioButtonProject_2.toggled.connect(self.switchProjectButton) + self.ui.radioButtonProject.toggled.connect(self.switchProjectButton) + self.ui.radioButtonProject_4.toggled.connect(self.updatePatientCode) + self.ui.radioButtonProject_3.toggled.connect(self.updatePatientCode) + self.ui.radioButtonProject_2.toggled.connect(self.updatePatientCode) + self.ui.radioButtonProject.toggled.connect(self.updatePatientCode) + self.ui.SavePreferencespushButton.clicked.connect(self.savePreferences) + + #self.connect(self.ui.radioButtonProject_3, QtCore.SIGNAL('clicked()'), lambda: self.switchProjectButton) + #self.connect(self.ui.radioButtonProject_2, QtCore.SIGNAL('clicked()'), lambda: self.switchProjectButton) + #self.connect(self.ui.radioButtonProject, QtCore.SIGNAL('clicked()'), lambda: self.switchProjectButton) + #self.connect(self.ui.radioButtonProject_3, QtCore.SIGNAL('clicked()'), lambda: self.updatePatientCode) + #self.connect(self.ui.radioButtonProject_2, QtCore.SIGNAL('clicked()'), lambda: self.updatePatientCode) + #self.connect(self.ui.radioButtonProject, QtCore.SIGNAL('clicked()'), lambda: self.updatePatientCode) + + # Finds the available protocols in brainvisa database and fills the comboboxes + self.analyseBrainvisaDB() + self.setGuide("Choose on of the tabs to import data in the BrainVisa database") + self.enableACPCButtons(False) + # Disable work-in-progress tabs + #self.ui.tabWidget.setTabEnabled(6, False) + self.ui.tabWidget.setTabEnabled(7, False) + self.ui.tabWidget.setTabEnabled(8, False) + self.ui.tabWidget.setTabEnabled(9, False) + + + + def __del__ (self): + self.ui = None + + def closeEvent(self, event): + QtGui.QFrame.closeEvent(self, event) + self.savePreferences() + # Kill all processes that may still be running (stuck) or better, wait for them to complete + maxTimeToCompletion = 1000*60*20 # 20min in ms -> maximum duration for any thread (it will be killed after that) + qthr = [t for t in self.threads if isinstance(t, QtCore.QThread)] + thr = [t for t in self.threads if not isinstance(t, QtCore.QThread)] + print "Closing all qthreads" + unfinished = [t for t in qthr if not t.wait(maxTimeToCompletion)] + print "Killing %i QThreads still running"%len(unfinished) + [t.terminate() for t in unfinished] + def checkKill(p, timeout): + """ This function checks if the thread is still running. + If so, it waits until timeout (in ms), then kills it if it is still running""" + try: + print "Trying to kill "+repr(p) + t = 0 + while(p.poll() is None and t < timeout): + time.sleep(5) + t = t + 5000 + if p.poll() is None: + p.kill() + except: + pass + + print "Closing all threads" + finished = [checkKill(t, maxTimeToCompletion) for t in thr] + print "Quitting BrainVisa" + axon.processes.cleanup() + print "Quit !" + QtGui.qApp.quit() + + def initialize(self): + """Reads the preference file, checks the available patients and sequences""" + #Localisation du fichier de preference + prefpath = os.path.join(os.path.expanduser('~'), '.imageimport') + + # Chargement du fichier et stockage dans self.prefs + # Basic prefs + self.prefs = {'dicomOutputPath':os.path.join(os.path.expanduser('~'), 'dicomOut'),'niftiOutputPath':os.path.join(os.path.expanduser('~'), 'niftiOut'), 'sites':['Gre',]} + try: + if (os.path.exists(prefpath)): + filein = open(prefpath, 'rb') + #self.prefs = pickle.load(filein) + #fout.write(json.dumps({'mars_atlas':resection_mars_atlas_info})) + try: + self.prefs = json.loads(filein.read()) + except: + filein.close() + filein = open(prefpath, 'rb') + self.prefs = pickle.load(filein) + + filein.close() + except: + pass + + self.dicomOutputPath = self.prefs['dicomOutputPath'] + self.niftiOutputPath = self.prefs['niftiOutputPath'] + + if 'currentProtocol' in self.prefs: + self.currentProtocol = self.prefs['currentProtocol'] + if 'currentSubject' in self.prefs: + self.currentSubject = self.prefs['currentSubject'] + # Grenoble/Lyon/Other sites... + if 'sites' in self.prefs: + self.ui.subjectSiteCombo.clear() + self.ui.subjectSiteCombo.addItems(self.prefs['sites']) + + #check what spm path has been precised in BrainVisa + configuration = Application().configuration + brainvisa_spm12_path = configuration.SPM.spm12_path + brainvisa_spm12_standalone_path = configuration.SPM.spm12_standalone_path + brainvisa_freesurfer_home_path = configuration.freesurfer._freesurfer_home_path + + if 'spm' in self.prefs: + if brainvisa_spm12_path != self.prefs['spm']: + QtGui.QMessageBox.warning(self, u"SPM", u"SPM path different between IntrAnat and BrainVisa, strange, you should check that, by default keep the one precised in IntrAnat") + if os.path.isfile(self.prefs['spm']+os.sep+'Contents.m'): + op_cont = open(self.prefs['spm']+os.sep+'Contents.m') + line = op_cont.readline() + line = op_cont.readline() + spm_version = line.split(' ')[3] + if spm_version == '(SPM12)': + self.setSpmTemplatePath(self.prefs['spm']) #+os.sep+'toolbox/OldNorm/T1.nii') + elif spm_version == '(SPM8)': + QtGui.QMessageBox.warning(self, u"SPM", u"SPM version not supported anymore") + #self.setSpmTemplatePath(self.prefs['spm']) #+os.sep+'templates/T1.nii') + else: + QtGui.QMessageBox.warning(self, u"SPM", u"SPM version unknown") + else: + QtGui.QMessageBox.warning(self, u"SPM", u"SPM path is not defined in tab 'Préférences'\n Normalization and SPM coregistration won't work !") + else: + if len(configuration.SPM.spm12_path)>0: + print("used brainvisa spm path") + self.setSpmTemplatePath(brainvisa_spm12_path) + self.prefs['spm']=brainvisa_spm12_path + else: + QtGui.QMessageBox.warning(self, u"SPM", u"SPM path is not defined (or wrong) in tab 'Préférences'\n Normalization and SPM coregistration won't work !") + + if 'spm_standalone' in self.prefs: + if brainvisa_spm12_standalone_path != self.prefs['spm_standalone']: + QtGui.QMessageBox.warning(self, u"SPM standalone", u"SPM standalone path different between IntrAnat and BrainVisa, strange, you should check that, by default keep the one precised in IntrAnat") + self.setSpmStandalonePath(self.prefs['spm_standalone']) + else: + self.setSpmStandalonePath(brainvisa_spm12_standalone_path) + + if 'freesurfer' in self.prefs: + if brainvisa_freesurfer_home_path != self.prefs['freesurfer']: + QtGui.QMessageBox.warning(self, u"Freesurfer", u"Freesurfer path different between IntrAnat and BrainVisa, strange, you should check that, by default keep the one precised in IntrAnat") + self.setFreesurferPath(self.prefs['freesurfer']) + else: + self.setFreesurferPath(brainvisa_freesurfer_home_path) + + if 'FileNoDBPath' in self.prefs: + self.setNoDBFilePath(self.prefs['FileNoDBPath']) + + + #self.prefs['freesurfer'] = str(self.ui.prefFreesurferEdit.text()) + + if 'ants' in self.prefs: + self.setANTsPath(self.prefs['ants']) + + if 'coregisterMethod' in self.prefs: + self.coregMethod = self.prefs['coregisterMethod'] + + if self.coregMethod == 'ANTs': + self.ui.prefSPMcheckbox.setCheckState(False) + self.ui.prefANTScheckbox.setCheckState(True) + self.ui.prefAimscheckbox.setCheckState(False) + if self.coregMethod == 'spm': + self.ui.prefSPMcheckbox.setCheckState(True) + self.ui.prefANTScheckbox.setCheckState(False) + self.ui.prefAimscheckbox.setCheckState(False) + if self.coregMethod == 'Aims': + self.ui.prefSPMcheckbox.setCheckState(False) + self.ui.prefANTScheckbox.setCheckState(False) + self.ui.prefAimscheckbox.setCheckState(True) + + if 'projectSelected' in self.prefs: + if self.prefs['projectSelected'] != []: + projects= [self.ui.radioButtonProject,self.ui.radioButtonProject_2,self.ui.radioButtonProject_3,self.ui.radioButtonProject_4] + projects[self.prefs['projectSelected'][0]].setChecked(True) + + + + # Test if matlab is available + if 'matlabOk' not in self.prefs or self.prefs['matlabOk'] == False: + if matlabIsPresent(): + self.prefs['matlabOk'] = True + else: + QtGui.QMessageBox.warning(self, u"Matlab", u"The command 'matlab' doesn't work !\nSPM coregistration and normalization won't work") + self.prefs['matlabOk'] = False + # Scanner les dossiers et séquences déjà importées, en faire un dictionnaire : + self.dicomOutContent = self.analyzeDicomOutput(self.dicomOutputPath) + self.niftiOutContent = self.analyzeNiftiOutput(self.niftiOutputPath) + + def warningMEDIC(self): + + shortwarning = TimerMessageBox(5,self) + shortwarning.exec_() + + + def savePreferences(self): + + prefpath = os.path.join(os.path.expanduser('~'), '.imageimport') + + self.prefs['dicomOutputPath'] = self.dicomOutputPath + self.prefs['niftiOutputPath'] = self.niftiOutputPath + self.prefs['currentProtocol'] = self.currentProtocol + self.prefs['currentSubject'] = self.currentSubject + self.prefs['sites'] = [str(self.ui.subjectSiteCombo.itemText(item)) for item in range(self.ui.subjectSiteCombo.count())] + if len(str(self.ui.prefSpmTemplateEdit.text()))>0: + self.prefs['spm'] = str(self.ui.prefSpmTemplateEdit.text()) + else: + self.prefs.pop('spm',None) + if len(str(self.ui.prefANTsEdit.text()))>0: + self.prefs['ants']=str(self.ui.prefANTsEdit.text()) + else: + self.prefs.pop('ants',None) + if len(str(self.ui.prefSpmStandaloneEdit.text()))>0: + self.prefs['spm_standalone'] = str(self.ui.prefSpmStandaloneEdit.text()) + else: + self.prefs.pop('spm_standalone',None) + if len(str(self.ui.prefFreesurferEdit.text()))>0: + self.prefs['freesurfer'] = str(self.ui.prefFreesurferEdit.text()) + else: + self.prefs.pop('freesurfer',None) + + if len(str(self.ui.prefNoDBFileLocationEdit.text()))>0: + self.prefs['FileNoDBPath'] = str(self.ui.prefNoDBFileLocationEdit.text()) + else: + self.prefs.pop('FileNoDBPath',None) + + if self.ui.prefANTScheckbox.isChecked(): + self.prefs['coregisterMethod'] = 'ANTs' + elif self.ui.prefSPMcheckbox.isChecked(): + self.prefs['coregisterMethod'] = 'spm' + elif self.ui.prefAimscheckbox.isChecked(): + self.prefs['coregisterMethod'] = 'Aims' + else: + self.prefs['coregisterMethod'] = 'spm' + + self.coregMethod = self.prefs['coregisterMethod'] + + projects= [self.ui.radioButtonProject.isChecked(),self.ui.radioButtonProject_2.isChecked(),self.ui.radioButtonProject_3.isChecked(),self.ui.radioButtonProject_4.isChecked()] + project_selected = [x for x in range(len(projects)) if projects[x]==True] + + self.prefs['projectSelected'] = project_selected + + fileout = open(prefpath, 'wb') + + pickle.dump(self.prefs, fileout) + #to modify to json + + fileout.close() + + def createItemDirs(self, item): + """ Create the directories containing the provided WriteDiskItem and insert them in the BrainVisa database """ + # Copied from brainvisa.processes, in ExecutionContext._processExecution() + dirname = os.path.dirname( item.fullPath() ) + dir=dirname + dirs = [] + while not os.path.exists( dir ): + dirs.append(dir) + dir=os.path.dirname(dir) + if dirs: + try: + os.makedirs( dirname ) + except OSError, e: + if not e.errno == errno.EEXIST: + # filter out 'File exists' exception, if the same dir has + # been created concurrently by another instance of BrainVisa + # or another thread + raise + for d in dirs: + dirItem=neuroHierarchy.databases.createDiskItemFromFileName(d, None) + + + def analyzeDicomOutput(self, root): + """ Structure of the dicom output directory is supposed to be + root/patient/sequence/dicomfiles. + This returns the dictionary of patients and sequences already imported in there""" + if not os.path.isdir(root): + return {} + return dict([(f, os.listdir(os.path.join(root, f))) for f in os.listdir(root) if os.path.isdir(os.path.join(root, f))]) + + def analyzeNiftiOutput(self, root): + """ Structure of the nifti output directory is supposed to be + root/patient/sequence.nii. + This returns the dictionary of patients and sequences already imported in there""" + if not os.path.isdir(root): + return {} + return dict([(f, [seq.split('.nii')[0] for seq in os.listdir(os.path.join(root, f))]) for f in os.listdir(root) if os.path.isdir(os.path.join(root, f))]) + + def storeImageReferentialsAndTransforms(self, image): + """Stores referential and transformation files for an image from its headers -> native, scanner-based, coregistered to""" + + # Notes : on prend le header de l'image, on crée un objet referentiel pour le référentiel natif, + # puis un pour chaque transformation définie dans le header + # On stocke les transfos entre le natif et chacun de ces référentiels à partir des infos du header. + # Comment alors faire pour lier le 'coregistered to blabla' au 'scanner based' d'une autre image ? Stocker une transfo identité ou utiliser copyReferential ? + # Et est-ce que copyReferential met à jour toutes les transfos stockées qui utilisaient le référentiel écrasé ? + # D'autre part, comment repérer le référentiel Scanner-based d'une image en particulier ? Pour créer la transfo t1post vers t1pre à partir du recalage SPM... + + + att = image.attributes() + refName = att['modality']+'_'+att['acquisition'] + print "Storing refs/transfos for "+str(refName) + + # Create a Referential object in the database to represent the native referential of the image + moda = self.modas[att['modality']] + nativeRef = self.transfoManager.referential(image) + if nativeRef is None: + print '...Creating native ref' + nativeRef = self.transfoManager.createNewReferentialFor(image, name = refName+'native', description = 'Native Anatomist Referential for ' + refName + ' image', referentialType='Referential of '+moda) + try: + neuroHierarchy.databases.createDiskItemFromFileName(os.path.dirname( nativeRef.fullPath() )) + except: + pass + + # Create the scanner-based referential + #wdiScan = WriteDiskItem( 'Scanner Based Referential', 'Referential', exactType=True ) + #refScan = wdiScan.findValue( image ) + refScan = self.transfoManager.findOrCreateReferential('Scanner Based Referential', image, name = refName+'_Scanner-Based', description = 'Scanner-Based referential for ' + refName + ' image') + try: + neuroHierarchy.databases.createDiskItemFromFileName(os.path.dirname( refScan.fullPath() )) + except: + pass + + if refScan is None: + print '...Creating scanner-based ref' + refScan = self.transfoManager.createNewReferentialFor(wdiScan, name = refName+'_Scanner-Based', description = 'Scanner-Based referential for ' + refName + ' image', referentialType='Scanner Based Referential') + try: + neuroHierarchy.databases.createDiskItemFromFileName(os.path.dirname( refScan.fullPath() )) + except: + pass + + # Find where to store the scanner-base transformation + wdiTransformScan = WriteDiskItem( 'Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True ) + transformScan = wdiTransformScan.findValue(image) + + # Read the header of the image and read all transformations available + f = aims.Finder() + f.check(image.fileName()) + trs = list(f.header()['transformations']) + refs = list(f.header()['referentials']) + #print "ATTRIBUTES : "+repr(att) + trm_to_scannerBased = None + + if ("Scanner-based anatomical coordinates" in refs ): + + trm_to_scannerBased = trs[refs.index("Scanner-based anatomical coordinates")] + + if trm_to_scannerBased is None: + print "No Scanner-based transfo in image header, using first available transfo instead." + try: + trm_to_scannerBased = trs[0] + except: + pass + + if transformScan is None: + print "Cannot find path for Scanner-based transform in database -> transformation not stored !" + elif trm_to_scannerBased is None: + print "Cannot find Scanner-based transformation in header !" + else: + print '...storing scanner-based transfo' + #Store information into the trm file + mot = aims.Motion( trm_to_scannerBased ) + image.setMinf('SB_Transform',str(trm_to_scannerBased)) + aims.write( mot, transformScan.fullPath() ) + try: + neuroHierarchy.databases.createDiskItemFromFileName(os.path.dirname( transformScan.fullPath() )) + except: + pass + #set and update database + print ".... setting transfo info : from %s to %s for %s"%(repr(nativeRef), repr(refScan), repr(transformScan)) + self.transfoManager.setNewTransformationInfo( transformScan, source_referential=nativeRef, destination_referential= refScan) + + + def analyseBrainvisaDB(self, tab=None): + """ Analyze the BrainVisa Database to fill the data for the brainvisa and registration tab (provide the tab number to update only the chosen one, 0 or 4) """ + rdi = ReadDiskItem( 'Center', 'Directory' )#, requiredAttributes={'center':'Epilepsy'} ) + protocols = list( rdi._findValues( {}, None, False ) ) + protocols = sorted([str(p.attributes()['center']) for p in protocols]) + if len(protocols) == 0: + rep = QtGui.QMessageBox.warning(self, "Center (former protocol)", u"No center/protocole defined in BrainVisa Database !") + text, ok = QtGui.QInputDialog.getText(self, 'Input Dialog', 'Enter the name of the center/protocole:') + + if (ok & bool(text)): + wdi = WriteDiskItem('Center', 'Directory' ) #'gz compressed NIFTI-1 image' ) + di = wdi.findValue({'center' : str(text)}) + os.mkdir(di.fullPath()) + neuroHierarchy.databases.insertDiskItem( di, update=True ) + + if self.currentProtocol in protocols: + currentIndex = protocols.index(self.currentProtocol) + else: + currentIndex = 0 + + def selectSubj(subjCombo): + " Subfunction to select the current subject " + if self.currentSubject is None: + return + idx = subjCombo.findText(self.currentSubject) + print "search current subj" + if idx != -1: + print "found at "+repr(idx) + subjCombo.setCurrentIndex(idx) + + if tab == 0 or tab is None: # Tab 0 is BrainVisa database tab + self.ui.bvProtocolCombo.clear() + self.ui.bvProtocolCombo.addItems(protocols) + self.ui.bvProtocolCombo.setCurrentIndex(currentIndex) + selectSubj(self.ui.bvSubjectCombo) + if tab == 1 or tab is None: # Tab 1 is Create Subject tab + self.ui.subjectProtocolCombo.clear() + self.ui.subjectProtocolCombo.addItems(protocols) + self.ui.subjectProtocolCombo.setCurrentIndex(currentIndex) + if tab == 3 or tab is None: # Tab 3 is Import Nifti tab + self.ui.niftiProtocolCombo.clear() + self.ui.niftiProtocolCombo.addItems(protocols) + self.ui.niftiProtocolCombo.setCurrentIndex(currentIndex) + selectSubj(self.ui.niftiSubjectCombo) + if tab == 7 or tab is None: # Tab 7 is Implantation tab + self.ui.implProtocolCombo.clear() + self.ui.implProtocolCombo.addItems(protocols) + self.ui.implProtocolCombo.setCurrentIndex(currentIndex) + selectSubj(self.ui.implSubjectCombo) + if tab == 4 or tab is None: # Tab 4 is Registration tab + self.ui.regProtocolCombo.clear() + self.ui.regProtocolCombo.addItems(protocols) + self.ui.regProtocolCombo.setCurrentIndex(currentIndex) + selectSubj(self.ui.regSubjectCombo) + if tab == 2 or tab is None: # Tab 2 is Patient Information tab + #pdb.set_trace() + #self.ui.patProtocolCombo.currentIndexChanged.disconnect(self._pathologyinfo) + self.ui.patProtocolCombo.clear() + self.ui.patProtocolCombo.addItems(protocols) + #self.connect(self.ui.patProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.patSubjectCombo)) + #self._pathologyinfo = pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol) + #self.connect(self.ui.patProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'),self._pathologyinfo) #lambda :pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol)) + self.ui.patProtocolCombo.setCurrentIndex(currentIndex) + self.pathologypatientInfo = pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol) + selectSubj(self.ui.patSubjectCombo) + #pdb.set_trace() + #self.pathologypatientInfo = pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol) + if tab == 6 or tab is None: # Tab 6 is SEEG tab + self.ui.seegProtocolCombo.clear() + self.ui.seegProtocolCombo.addItems(protocols) + self.ui.seegProtocolCombo.setCurrentIndex (currentIndex) + selectSubj(self.ui.seegSubjectCombo) + + + def selectProtocol(self, proto, comboToFillWithSubjects): + """ A BrainVisa protocol was selected : query the database to get the list of subjects and put them in the provided QComboBox""" + self.currentProtocol = str(proto) + rdi = ReadDiskItem( 'Subject', 'Directory', requiredAttributes={'center':str(proto)} ) + subjects = list( rdi._findValues( {}, None, False ) ) + comboToFillWithSubjects.clear()#self.ui.bvSubjectCombo.clear() + comboToFillWithSubjects.addItems(sorted([s.attributes()['subject'] for s in subjects])) + + #if self.ui.tabWidget.currentIndex() ==2: + # self.pathologypatientInfo = pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol) + + def setCurrentSubject(self, subj): + if not subj: # ignore empty values + return + print "current subj : "+str(subj) + self.currentSubject = str(subj) + + + def findAllImagesForSubject(self, protocol, subj): + """ Returns all images for a subject from the brainvisa database. + @return an array of ReadDiskItem + """ + rdi = ReadDiskItem( 'Raw T1 MRI', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images = list( rdi._findValues( {}, None, False ) ) + images = [x for x in images if "skull_stripped" not in x.fullName()] + rdi = ReadDiskItem( 'T2 MRI', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'CT', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'PET', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'fMRI-epile', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'Statistic-Data', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'FLAIR', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'FreesurferAtlas', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'FGATIR', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'HippoFreesurferAtlas', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + + return images + + def selectBvSubject(self, subj): + """ A BrainVisa subject was selected : query the database to get the list of images""" + # Display "Date : XXXX-XX-XX - Seq: T1 - Acq : T1Pre + self.ui.bvImageList.clear() + images = self.findAllImagesForSubject(self.ui.bvProtocolCombo.currentText(), subj) + #name = modality + acquisition + subacquisition if exist subacquisition key else modality + acquisition + self.ui.bvImageList.addItems(sorted([i.attributes()['modality'] + ' - '+ i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition'] if 'subacquisition' in i.attributes().keys()\ + #i.attributes()['modality'] if 'acquisition' not in i.attributes().keys()\ + else i.attributes()['modality'] + ' - '+ i.attributes()['acquisition'] for i in images ])) + + dict_temporaire = {} + for i in images: + if 'subacquisition' in i.attributes().keys(): + dict_temporaire.update({i.attributes()['modality'] + ' - ' + i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition']:i.fileName()}) + else: + dict_temporaire.update({i.attributes()['modality'] + ' - ' + i.attributes()['acquisition']:i.fileName()}) + #self.bvImagePaths = dict((i.attributes()['modality'] + ' - ' + i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition'], i.fileName() if 'subacquisition' in i.attributes().keys()\ + #else i.attributes()['modality'] + ' - ' + i.attributes()['acquisition'], i.fileName() for i in images)) + self.bvImagePaths = dict_temporaire + + + def selectBvImage(self, item): + """ A BrainVisa image was double-clicked : display it !""" + self.clearAnatomist() + path = self.bvImagePaths[str(item.text())] + mri = self.a.loadObject(path) + self.a.addObjects(mri, self.wins) + self.dispObj.append(mri) + + def removeFromDB(self, file, db=None): + """ + If the file is a directory, recursive call to remove all its content before removing the directory. + Corresponding diskitem is removed from the database if it exists. + Taken from brainvisa-4.3.0/python/brainvisa/data/qt4gui/hierarchyBrowser.py + """ + if db is None: + try: + db=neuroHierarchy.databases.database(neuroHierarchy.databases.getDiskItemFromFileName(file).get("_database")) + except: + pass + + if os.path.isdir(file): + for f in os.listdir(file): + self.removeFromDB(os.path.join(file, f), db) + os.rmdir(file) + else: + os.remove(file) + if db: + diskItem=db.getDiskItemFromFileName(file, None) + if diskItem: + db.removeDiskItem(diskItem) + + def deleteBvSubject(self): + protocol = str(self.ui.bvProtocolCombo.currentText()) + subj = str(self.ui.bvSubjectCombo.currentText()) + rep = QtGui.QMessageBox.warning(self, u'Confirmation', u"ATTENTION
you are gonna Erase ALL subject datas
DELETE THE SUBJECT%s ?
"%subj, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) + if rep == QtGui.QMessageBox.Yes: + print "Deleting subject %s"%subj + rdi = ReadDiskItem( 'Subject', 'Directory', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + di = list( rdi._findValues( {}, None, False ) ) + if len(di) != 1: + print "%s subject(s) found ! Cannot delete if there is more than 1 !"%repr(len(di)) + return + self.removeFromDB(di[0].fullPath(), neuroHierarchy.databases.database(di[0].get("_database"))) + self.setStatus(u"Subject %s deleted from the database"%subj) + # Reset the list of subjects : + self.selectProtocol(str(self.ui.bvProtocolCombo.currentText()),self.ui.bvSubjectCombo) + + + def deleteBvImage(self): + #Delete the current acquisition (including transforms and segmentations : the full acquisition directory + imageName = None + try: + imageName = str(self.ui.bvImageList.currentItem().text()) + except: # Probably no image available or no image selected + return + rep = QtGui.QMessageBox.warning(self, u'Confirmation', u"ATTENTION
You are gonna delete the selected image and all linked data
DELETE THE IMAGE%s ?
"%imageName, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) + if rep == QtGui.QMessageBox.Yes: + + path = self.bvImagePaths[imageName] # Gives the path of the image + di = neuroHierarchy.databases.getDiskItemFromFileName(path) + acqPath = os.path.dirname(path) + if str(os.path.basename(acqPath)) != str(di.attributes()['acquisition']): + print "CANNOT REMOVE IMAGE : acquisition path does not match acquisition name !" + return + + if "subacquisition" in di.attributes().keys(): + self.removeDiskItems(di,eraseFiles=True) + else: + self.removeFromDB(acqPath) + self.setStatus(u"Image %s deleted from the database"%imageName) + self.selectBvSubject(str(self.ui.bvSubjectCombo.currentText())) + + + def clearAnatomist(self, windows=None): + """ If "windows" is provided, just empties the provided windows. + If not, all loaded objects are closed and all windows are emptied """ + if windows is not None: + self.a.removeObjects(self.a.getObjects(), windows) + return + self.dispObj = [] + self.a.removeObjects(self.a.getObjects(), self.wins) + self.a.deleteObjects(self.a.getObjects()) + + def displayAnatomist(self, win1Path=None, win2Path=None): + self.clearAnatomist() + if win1Path: + im1 = self.a.loadObject(win1Path) + self.a.addObjects(im1, self.wins[0]) + self.dispObj.append(win1Path) + if win2Path: + im2 = self.a.loadObject(win2Path) + self.a.addObjects(im2, self.wins[1]) + self.dispObj.append(win2Path) + + def setStatus(self, text): + """ Sets the status text displayed at the bottom of the dialog""" + self.ui.statusCombo.insertItem(0,QtCore.QTime.currentTime().toString("H:m:s") + ': ' + text) + self.ui.statusCombo.setCurrentIndex(0) + + def setGuide(self, text): + """ Set the text of the User Guide on the top of the window""" + self.ui.guideLabel.setText(text) + + def setTabGuide(self, tabId): + helpTab = [u'Look for images in BrainVisa database. Double click to load an images in anatomist windows on the side',\ + u'Add a new patient in the Database (perform an anonymization as well)',\ + u'Precise patient information (general and pathology specific)',\ + u'Import images (format: Nifti/GIS/Analyse/(mgz in some case). Select the file and fill information needed',\ + u'Coregister all images to the 3DT1 before electrode implantation. Normalize this 3DTI to the MNI, perform grey/white matter segmentation, mesh of the cortex, and MarsAtlas parcellation',\ + u'Set software preferences',\ + u'Import SEEG data' ,\ + u'Importez des images depuis un dossier DICOM : Sélectionnez une image, importez et convertissez en Nifti, puis importez-là dans la base',\ + u'Importez des images depuis un PACS. Sélectionnez une image, importez et convertissez en Nifti, puis importez-là dans la base',\ + u'Importez les schémas d\'implantation scannés',\ + ] + self.setGuide(helpTab[tabId]) + + def patientSelectionChanged(self, t): + """ Update the studies selected when the patient selection changes. t is the list, 'pacs' or 'dir' in the UI""" + + print 'patientSelectionChanged('+t+')' + list = None + if t == 'pacs': + list = self.ui.pacsPatientList + out = self.ui.pacsStudiesList + studies = self.pacsStudies + elif t == 'dir': + list = self.ui.dirPatientList + out = self.ui.dirStudiesList + studies = self.dirStudies + + # Unselect all studies + for s in out.selectedItems(): + out.setItemSelected(s, False) + + # Select all studies that match the selected patients + names = [str(p.text()) for p in list.selectedItems()] + outItems = [out.item(i) for i in xrange(out.count())] + for s in outItems: + if studies[self.studiesUIDbyName[str(s.text())]]['PatientsName'] in names: + out.setItemSelected(s, True) + + + def studiesSelectionChanged(self, t): + """ Update the series selected when the studies selection changes. t is the list, 'pacs' or 'dir' in the UI""" + list = None + if t == 'pacs': + list = self.ui.pacsStudiesList + out = self.ui.pacsSeriesList + series = self.pacsStudies + elif t == 'dir': + list = self.ui.dirStudiesList + out = self.ui.dirSeriesList + series = self.dirSeries + + # Unselect all studies + for s in out.selectedItems(): + out.setItemSelected(s, False) + + # Select all series that match the selected studies + names = [self.studiesUIDbyName[str(s.text())] for s in list.selectedItems()] + outItems = [out.item(i) for i in xrange(out.count())] + for s in outItems: + if series[self.seriesUIDbyName[str(s.text())]]['StudyInstanceUID'] in names: + out.setItemSelected(s, True) + + def selectOutput(self, t): + """ Select the output directories for t='Dicom' or t='Nifti' images""" + if t=='Dicom': + self.dicomOutputPath = str(QtGui.QFileDialog.getExistingDirectory(self, u"Choix d'un répertoire de sortie pour les fichiers DICOM",self.dicomOutputPath )) + self.ui.dicomOutputPathEdit.setText(self.dicomOutputPath) + elif t == 'Nifti': + self.niftiOutputPath = str(QtGui.QFileDialog.getExistingDirectory(self, u"Choix d'un répertoire de sortie pour les fichiers Nifti",self.niftiOutputPath )) + self.ui.niftiOutputPathEdit.setText(self.niftiOutputPath) + + def openDicomDir(self, direc=None, updateUI = True): + """Loads a DICOM directory (direc), organize the files and update the UI""" + if direc is None: + direc = QtGui.QFileDialog.getExistingDirectory(self, u"Choix d'un répertoire de fichiers DICOM")#,"/default/Path") + direc = str(direc) + if not os.path.exists(direc) or not os.path.isdir(direc): + print "OpenDicomDir : %s does not exist or is not a directory"%repr(direc) + return + files = os.listdir(direc) + files = [os.path.join(direc,f) for f in files if os.path.isfile(os.path.join(direc,f))] + self.setStatus('Chargement de '+str(len(files))+" fichiers DICOM...") + # Create executor object, connect the output function to it, then start it + organize = lambda :organizeDicomFiles(files, True) + thread = PythonExecutor(organize) + self.threads.append(thread) + self.connect(thread, QtCore.SIGNAL('dicomFilesOutput(PyQt_PyObject)'), lambda x: self.finishOpenDicomDir(updateUI, x)) + thread.start() + + def finishOpenDicomDir(self, updateUI, dicomFiles): + self.setStatus(u'Fichiers DICOM chargés') + print "dicomFiles ok" + if updateUI: + self.ui.dirSeriesList.clear() + self.ui.dirStudiesList.clear() + self.ui.dirPatientList.clear() + + series = getSeries(dicomFiles) + print "*** Found %d series"%len(series) + + self.dirSeries = series + #Afficher la liste des series + if updateUI: + self.seriesUIDbyName = dict((series[uid]['SeriesDate']+' '+series[uid]['SeriesTime']+' '+series[uid]['SeriesDescription'] , uid) for uid in series if 'SeriesTime' in series[uid] and 'SeriesDate' in series[uid] and 'SeriesDescription' in series[uid]) + self.ui.dirSeriesList.addItems(self.seriesUIDbyName.keys()) + self.ui.dirSeriesList.sortItems() + # Colorer les séries déjà importées: + try: + for i in xrange(self.ui.dirSeriesList.count()): + self.ui.dirSeriesList.item(i).setBackgroundColor(QColor.fromRgb(255,0,0)) + s = self.seriesUIDbyName[str(self.ui.dirSeriesList.item(i).text())] + if patientNameDecode(s['PatientsName']) in niftiOutContent: + if serie2filename(s) in niftiOutContent[patientNameDecode(s['PatientsName'])]: + self.ui.dirSeriesList.item(i).setBackgroundColor(QColor.fromRgb(0,255,0)) + except: + pass + + self.dirStudies = getStudies(dicomFiles) + studies = self.dirStudies + print "Studies : "+repr(studies) + #Afficher la liste des studies + if updateUI: + self.studiesUIDbyName = dict((studies[uid]['name'], uid) for uid in studies.keys()) + self.ui.dirStudiesList.addItems(self.studiesUIDbyName.keys()) + self.ui.dirStudiesList.sortItems() + + self.dirPatients = getPatients(series) + print "Patients : "+repr(studies) + if updateUI: + self.ui.dirPatientList.addItems(self.dirPatients) + self.ui.dirPatientList.sortItems() + + + ## DCMTK retrieve example : + # # get list of studies for patient "John Doe" + #findscu --study -k 0008,0052=STUDY -k 0010,0010="Doe^John" -k 0020,000D server 104 + #now get list of CT series within a certain study identified by a UID returned by the last call to findscu + #findscu --study -k 0008,0052=SERIES -k 0020,000D=1.2.276.1.2.3.4.5 -k 0008,0060=CT -k 0020,000E server 104 + #retrieve a series found by findscu. Note that we need to specify both Study and Series Instance UID. + #movescu --study -k 0008,0052=SERIES -k 0020,000D=1.2.276.1.2.3.4.5 -k 0020,000E=1.2.276.9.8.7.6.5 server 104 + def searchPacs(self): + """ Search the PACS for the patient Name provided""" + # Get the list of patients'names if the provided name is llong enough (2 chars minimum) + name = str(self.ui.patientSearchName.text())+'*' + name.rstrip()#replace(' ', '^') --> spaces are allowed inside names, ^separates first/last/middle names + # Remove wildcards to avoid large matches + name.replace('?', '') + name.replace('*', '') + server = str(self.ui.pacsServerEdit.text()) + port = str(self.ui.pacsPortSpin.value()) + # We want study mode, with tag 0008,0052 set to study, tag 0010,0010 matching the patient, and listing all 0020,000 (studies) + cmd = ['findscu','--study', '-k','0008,0052=STUDY', '-k' , '0010,0010="'+name+'"', '-k','0020,000D', server, port ] + + lines = runCmd(cmd) + print lines + # List of studies + studies = [] + # In all studies get the patient's name and add it to the list + patientsList = [] + + # Maximum number of patients : 10 + patientsList =patientsList[:10] + + # For each study that matches a patient from the list, get all series + for s in studies: + cmd = ['findscu','--study', '-k','0008,0052=SERIES', '-k' , '0010,0010="'+name+'"',\ + '-k', '0020,000D='+s, '-k', '0020,000E', server, port ] + lines = runCmd(cmd) + # Store the results + + + def importDataPacs(self): + """ Get the selected series from the pacs to a local directory and convert to Nifti """ + # Regarder la sélection patient et series + # importer avec findscu dans un répertoire temporaire + # getscu ou movescu + cmd = ['getscu', '--study', '-k', '0008,0052=SERIES', '-k', '0020,000D='+studyId, '-k', '0020,000E='+serieId, server, port] + # puis lancer self.openDicomDir(tmpDir) + + + def importDataDir(self): + # Find selected series + selectedSeries = dict((self.seriesUIDbyName [str(item.text())], self.dirSeries[self.seriesUIDbyName [str(item.text())]]) for item in self.ui.dirSeriesList.selectedItems()) + + # If nothing is selected + if not selectedSeries: + return + + # Copy the dicom series to a directory + copySeriesTo(selectedSeries, self.dicomOutputPath) + + # Convert to Nifti + th = convertSeriesToNifti(selectedSeries, self.niftiOutputPath) + self.threads.extend(th) + + print "Series importees : " + repr(selectedSeries.keys()) + # Regarder la sélection patient et series + # importer avec findscu dans un répertoire temporaire + # puis lancer copySeriesTo(series, dicomOutputPath) + + def chooseNifti(self): + self.ui.niftiFileLabel.setText('') + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open MRI Image", "", "Images (*.nii *.nii.gz *.ima *.img *.ima.gz *.img.gz *.img.bz2 *ima.bz2 *.nii.bz2 *.mgz)")) + if not path: + return + self.ui.niftiFileLabel.setText(path) + # Display the image and remove others + self.clearAnatomist() + print "Loading %s"%path + split_path = os.path.splitext(path) + if split_path[-1] == ".mgz": + try: + tmp_nii_path = "/tmp/tmp_mgz_nii.nii" + #on reslice par rapport au t1 pre + #pdb.set_trace() + di = ReadDiskItem( 'Raw T1 MRI', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.currentSubject } ) + allT1 = list(di.findValues({},None,False)) + idxT1pre = [i for i in range(len(allT1)) if 'pre' in str(allT1[i])] + if len(idxT1pre)==0: + print "to import freesurfer images, the T1pre has to be imported because a reslicing is necessary" + return + + #mri_convert -rl /data/brainvisa/Epilepsy/Gre_2015_BESk/t1mri/T1pre_2015-1-1/Gre_2015_BESk.nii /home/b67-belledone/freesurfer/subjects/Gre_2015_BESk/mri/aparc.a2009s+aseg.mgz /home/b67-belledone/freesurfer/subjects/Gre_2015_BESk/mri/test.nii -rt nearest -ncD + #remplacer par launchFreesurferCommand + context = brainvisa.processes.defaultContext() + context.write("mri_convert from freesurfer") + + launchFreesurferCommand(context, None, 'mri_convert', '-i',path,'-o',tmp_nii_path,'-rl',str(allT1[idxT1pre[0]].fullPath()),'-rt','nearest','-nc') + #mriconvert_call ='mri_convert -i {} -o {} -rl {} -rt nearest -nc'.format(path,tmp_nii_path,str(allT1[idxT1pre[0]].fullPath())) + #mriconvert_call ='mri_convert -i {} -o {}'.format(path,tmp_nii_path) + #runCmd(mriconvert_call.split()) + mri = self.a.loadObject(tmp_nii_path) + except: + print "conversion mgz to nii didn't work" + return + else: + mri = self.a.loadObject(path) + + self.a.addObjects(mri, self.wins) + self.dispObj.append(mri) + + self.brainCenter = None + self.ui.brainCenterLabel.setText('') + self.ui.niftiFileLabel.setText(tmp_nii_path) + + def setBrainCenter(self): + brainCenterCoord = list(self.a.linkCursorLastClickedPosition()) + self.ui.brainCenterLabel.setText("%.1f, %.1f, %.1f"%tuple([float(x) for x in brainCenterCoord][:3])) + self.brainCenter = brainCenterCoord + + def importNifti(self, path = None, patient = None, proto=None, modality = None, acq = None): + """ Imports a Nifti file in the BrainVisa database. + path is the input image, patient is e.g. Dupont_Jean, acq is the acquisition name e.g. 'T1pre_2000-01-01' + If the parameters are empty, the data is taken from the Nifti Tab in the UI""" + + if self.brainCenter == None: + print "brain center not set" + QtGui.QMessageBox.warning(self, "Error",u"You haven't selected the BrainCenter !") + return + + if self.ui.acqDate.date() == self.defaultAcqDate: + QtGui.QMessageBox.warning(self, "Error",u"Acquisition date is not valid!") + return + if path is None: + path = str(self.ui.niftiFileLabel.text()) + if not path: + QtGui.QMessageBox.warning(self, "Error", u"Choose a file to import !") + return + filename = os.path.split(path)[1] + if patient is None: + patient = str(self.ui.niftiSubjectCombo.currentText()) + if proto is None: + proto = str(self.ui.niftiProtocolCombo.currentText()) + if acq is None: + d = self.ui.acqDate.date() + acq = str(self.ui.niftiSeqType.currentText() + self.ui.niftiAcqType.currentText() + '_'+str(d.year()) + '-' + str(d.month()) + '-' + str(d.day())) + if modality is None: + # Determines the BrainVisa file type (depends on the imaging modality) + modality = str(self.ui.niftiSeqType.currentText()) # T1 / T2 / CT / PET /fMRI + + filetype = {'T1':'Raw T1 MRI', 'T2':'T2 MRI', 'CT':'CT', 'TEP':'PET', 'PET':'PET', 'fMRI':'fMRI-epile', 'Statistics':'Statistic-Data', 'FLAIR':'FLAIR', 'FreesurferAtlas':'FreesurferAtlas', 'FGATIR':'FGATIR','HippoFreesurferAtlas':'HippoFreesurferAtlas'}[modality] + + write_filters = { 'center': proto, 'acquisition': str(acq), 'subject' : str(patient) } + + if filetype == 'fMRI-epile' or filetype == 'Statistic-Data': + text, ok = QtGui.QInputDialog.getText(self, 'Input Dialog', 'Enter the name of the test:') + + if (ok & bool(text)): + write_filters.update({'subacquisition':str(text)}) + + + wdi = WriteDiskItem(filetype, 'NIFTI-1 image' )#'gz compressed NIFTI-1 image' ) + print "Finding BV path for acquisition %s and patient %s"%(acq, patient) + di = wdi.findValue(write_filters) + + if di is None: + QtGui.QMessageBox.warning(self, "Error", u"Impossible to find a valid path to import the Image in Brainvisa database (%s, %s)"%(patient, acq)) + return + # Copy the file : lancer l'importation standard de T1 MRI pour la conversion de format et + destination = di.fileName() + if os.path.exists(destination): + reply = QtGui.QMessageBox.question(self, 'Overwrite', u"This image already exists.\nOverwrite the file ?", QtGui.QMessageBox.Yes | + QtGui.QMessageBox.No, QtGui.QMessageBox.No) + if reply == QtGui.QMessageBox.No: + return + print "Importing file as "+destination + + #current images loaded for this patient: + self.selectBvSubject(str(patient)) + + if filetype != 'fMRI-epile' and filetype != 'Statistic-Data' and filetype != 'FreesurferAtlas': + + if len(self.bvImagePaths) > 0: + ImAlreadyHere = [i for i in range(len(self.bvImagePaths)) if str(self.ui.niftiSeqType.currentText() + self.ui.niftiAcqType.currentText()+'_') in self.bvImagePaths.keys()[i]] + if len(ImAlreadyHere): + QtGui.QMessageBox.warning(self, 'WARNING', u"There is already a %s image, delete it before if you want to import another one"%str(self.ui.niftiSeqType.currentText() + self.ui.niftiAcqType.currentText())) + self.setStatus(u"Sequence %s importation not performed (already one equivalent)"%acq) + return + + # Create directories that do not exist yet + self.createItemDirs(di) + + #we check that there is a Scanner based transformation, if not and if both transformations are equal, we rename one as scanner based transformation + temp_nii = aims.read(path) + refs_nii = temp_nii.header()['referentials'] + if len(refs_nii)>1: + isScannerBased = 0 + sum_transfo = numpy.zeros(16,dtype='float32') + for ii in range(len(refs_nii)): + if refs_nii[ii] == 'Scanner-based anatomical coordinates': + isScannerBased = 1 + sum_transfo = sum_transfo + temp_nii.header()['transformations'][ii] + + mean_transfo = sum_transfo/len(refs_nii) + if isScannerBased == 0: + diff = mean_transfo - temp_nii.header()['transformations'][0] + if numpy.absolute(diff).round(2).sum() <= 0.03: + temp_nii.header()['referentials'][0] = 'Scanner-based anatomical coordinates' + + + else: + if refs_nii[0] == 'Coordinates aligned to another file or to anatomical truth': + temp_nii.header()['referentials'][0] = 'Scanner-based anatomical coordinates' + + aims.write(temp_nii,destination) + + #pdb.set_trace() + if (filetype != 'fMRI-epile') & (filetype != 'PET') & (filetype != 'Statistic-Data'): # or filetype != 'MTT' + ret = subprocess.call(['AimsFileConvert', '-i', str(destination), '-o', str(destination), '-t', 'S16']) + if ret < 0: + print "Importation error" + QtGui.QMessageBox.warning(self, "Error", "Importation error : BrainVisa / AimsFileConvert") + return + elif filetype == 'PET': + #pdb.set_trace() + print "conversion PET float to S16" + ret = subprocess.call(['AimsFileConvert', '-i', str(destination), '-o', str(destination), '-t', 'S16', '-r', 'True']) + if ret < 0: + print "Importation error" + QtGui.QMessageBox.warning(self, "Error", "Importation error : BrainVisa / AimsFileConvert") + return + di.setMinf('ColorPalette','Blue-Red-fusion') + else: + print "no conversion to grayscale" + ret = subprocess.call(['AimsFileConvert', '-i', str(destination), '-o', str(destination)]) + if ret < 0: + print "Importation error" + QtGui.QMessageBox.warning(self, "Error", "Importation error : BrainVisa / AimsFileConvert") + return + + if str(self.ui.niftiSeqType.currentText()) == 'T1': + if self.ui.radioButtonGado.isChecked(): + di.setMinf('Gado',True) + if self.ui.radioButtonNoGado.isChecked(): + di.setMinf('Gado',False) + neuroHierarchy.databases.insertDiskItem( di, update=True ) + + + di.setMinf('brainCenter', self.brainCenter) + + if filetype == 'Statistic-Data': + + textMNI, okMNI = QtGui.QInputDialog.getItem(self,'MNI or not','Is the statistic image generated in the MNI',['True','False']) + if (okMNI & bool(textMNI)): + di.setMinf('MNI',str(textMNI)) + di.setMinf('ColorPalette','Yellow-Red-White-Blue-Green') + + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Sequence %s importation done"%acq) + + if filetype == 'Statistic-Data': + try: + self.StatisticDataMNItoScannerBased(proto, patient, acq) + except: + pass + + if filetype == 'FreesurferAtlas': + self.generateAmygdalaHippoMesh(proto, patient, acq, di) + # Appeler le process SPMnormalizationPipeline.py de la toolbox t1, et ajouter sur ce modèle un process coregister + + def importFSoutput(self,subject=None): + + if subject == None: + subject = self.currentSubject + + #find T1pre of the subject + rT1BV = ReadDiskItem('Raw T1 MRI', 'BrainVISA volume formats',requiredAttributes={'subject':subject}) + allT1 = list(rT1BV.findValues({},None,False)) + idxT1pre = [i for i in range(len(allT1)) if 'pre' in str(allT1[i])] + diT1pre = allT1[idxT1pre[0]] + + acq = str(diT1pre.attributes()['acquisition']).replace('T1','FreesurferAtlas') + write_filters = { 'center': str(self.ui.niftiProtocolCombo.currentText()), 'acquisition': str(acq), 'subject' : subject } + + FreesurferNu = ReadDiskItem('Nu FreesurferAnat', 'FreesurferMGZ',requiredAttributes={'subject':subject,'_ontology':'freesurfer'}) + + Nufound = list(FreesurferNu.findValues({},None,False)) + Nufound = [x for x in Nufound if '.mgz' in str(x)][0] + + FreesurferRibbon = ReadDiskItem('Ribbon Freesurfer','FreesurferMGZ',requiredAttributes={'subject':subject,'_ontology':'freesurfer'}) + + Ribbonfound = list(FreesurferRibbon.findValues({},None,False)) + Ribbonfound = [x for x in Ribbonfound if '.mgz' in str(x)][0] + + FreesurferPial = ReadDiskItem('Any Type','FreesurferPial',requiredAttributes={'subject':subject,'_ontology':'freesurfer'}) + + Pialfound = list(FreesurferPial.findValues({},None,False)) + PialLeft = [x for x in Pialfound if '/lh.' in str(x)][0] + PialRight = [x for x in Pialfound if '/rh.' in str(x)][0] + + PialMeshBV = WriteDiskItem('Pial','aims mesh formats') + diPialMeshBV = PialMeshBV.findValue(write_filters) + + FreesurferWhite = ReadDiskItem('Any Type','FreesurferWhite',requiredAttributes={'subject':subject,'_ontology':'freesurfer'}) + + Whitefound = list(FreesurferWhite.findValues({},None,False)) + WhiteLeft = [x for x in Whitefound if '/lh.' in str(x)][0] + WhitelRight = [x for x in Whitefound if '/rh.' in str(x)][0] + + right_grey_white_output=WriteDiskItem('Right Grey White Mask','Aims writable volume formats') + diright_grey_white = right_grey_white_output.findValue(write_filters) + left_grey_white_output=WriteDiskItem('Left Grey White Mask','Aims writable volume formats') + dileft_grey_white = left_grey_white_output.findValue(write_filters) + + WhiteMeshBV = WriteDiskItem('White','aims mesh formats') + diWhiteMeshBV = WhiteMeshBV.findValue(write_filters) + #diWhiteLeftMeshBV = [x for x in diWhiteMeshBV + + FreesurferThickness = ReadDiskItem('Any Type','FreesurferThickness',requiredAttributes={'subject':subject,'_ontology':'freesurfer'}) + + Thicknessfound = list(FreesurferThickness.findValues({},None,False)) + ThickLeft = [x for x in Thicknessfound if '/lh.' in str(x)][0] + ThickRight = [x for x in Thicknessfound if '/rh.' in str(x)][0] + + FreesurferDestrieux = ReadDiskItem('Freesurfer Cortical Parcellation using Destrieux Atlas','FreesurferMGZ',requiredAttributes={'subject':subject,'_ontology':'freesurfer'}) + + Destrieuxfound = list(FreesurferDestrieux.findValues({},None,False)) + + pdb.set_trace() + #generer tous les writediskitem + context = brainvisa.processes.defaultContext() + context.write("convert output from freesurfer") + launchFreesurferCommand(context, None, 'mri_convert', '-i',str(Nufound),'-o',os.path.join(os.path.dirname(str(Nufound)),'nu.nii'),'-rl',str(diT1pre.fullPath())) + launchFreesurferCommand(context, None, 'mri_convert', '-i',str(Ribbonfound),'-o',os.path.join(os.path.dirname(str(Ribbonfound)),'ribbon.nii'),'-rl',str(diT1pre.fullPath()),'-rt','nearest','-nc') + + + wdi = WriteDiskItem('FreesurferAtlas', 'NIFTI-1 image' ) + diFSDestrieux = wdi.findValue(write_filters) + #create the folder if doesn't exist + if not os.path.isfile(os.path.dirname(str(diFSDestrieux.fullPath()))): + try: + os.makedirs(os.sep.join(os.path.dirname(str(diFSDestrieux.fullPath())).split(os.sep)[:-1])) + except: + #already exist probably + pass + try: + os.makedirs(os.path.dirname(str(diFSDestrieux.fullPath()))) + except: + #already exist probably + pass + + launchFreesurferCommand(context, None, 'mri_convert', '-i',str(Destrieuxfound[0]),'-o',str(diFSDestrieux.fullPath()),'-rl',str(diT1pre.fullPath()),'-rt','nearest','-nc') + ret = subprocess.call(['AimsFileConvert', '-i', str(diFSDestrieux.fullPath()), '-o', str(diFSDestrieux.fullPath()), '-t', 'S16']) + #pour destrieux + self.generateAmygdalaHippoMesh(str(self.ui.niftiProtocolCombo.currentText()), subject, acq, diFSDestrieux) + + launchFreesurferCommand(context, None, 'mris_convert', '--to-scanner', WhiteLeft, str(diWhiteleft.fullPath())) + launchFreesurferCommand(context, None, 'mris_convert', '--to-scanner', WhiteRight, str(diWhiteright.fullPath())) + launchFreesurferCommand(context, None, 'mris_convert', '--to-scanner', PialLeft, str(diPialleft.fullPath())) + launchFreesurferCommand(context, None, 'mris_convert', '--to-scanner', PialRight, str(diPialright.fullPath())) + launchFreesurferCommand(context, None, 'mris_convert', '--to-scanner', ThickLeft, str(diPialright.fullPath())) + launchFreesurferCommand(context, None, 'mris_convert', '--to-scanner', ThickRight, str(diPialright.fullPath())) + + #loading the object to get its referential and assign it + self.a.loadObject(diT1pre) + refes=self.a.getReferentials() + for element in refes: + if 'T1pre' in str(element.getInfos()): + ref=element + whiteL=self.a.loadObject(diWhiteleft) + whiteL.assignReferential(ref) + whiteR=self.a.loadObject(diWhiteright) + whiteR.assignReferential(ref) + pialL=self.a.loadObject(diPialleft) + pialL.assignReferential(ref) + pialR=self.a.loadObject(diPialright) + pialR.assignReferential(ref) + + + def importPacs(self): + """ Import the selected images from the pacs to BrainVisa (after the Nifti importation) TODO does not work """ + + #self.importNifti(path, patient, modality, acq) + selectedSeries = dict((self.seriesUIDbyName [str(item.text())], self.pacsSeries[self.seriesUIDbyName [str(item.text())]]) for item in self.ui.pacsSeriesList.selectedItems()) + self.importBV(selectedSeries) + + + def importDir(self): + """ Import the selected image from dicom directory to BrainVisa (after Nifti importation) """ + # Find selected series + selectedSeries = dict((self.seriesUIDbyName [str(item.text())], self.dirSeries[self.seriesUIDbyName [str(item.text())]]) for item in self.ui.dirSeriesList.selectedItems()) + self.importBV(selectedSeries) + + def importBV(self, selectedSeries): + if len(selectedSeries) != 1: + QtGui.QMessageBox.warning(self, "Error", u"Select one (and only one ! ) sequence !") + return + serie = None + for k in selectedSeries: + serie = selectedSeries[k] + + if 'niftiPath' not in serie: + QtGui.QMessageBox.warning(self, "Error", u"You have to convert the sequence in Nifti format before importing in Brainvisa") + return + + acq = str(self.ui.dirSeqType.currentText() + self.ui.dirAcqType.currentText() + '_' + dateDecode(serie['SeriesDate'])) + patient = patientNameDecode(serie['PatientsName']) + self.importNifti(serie['niftiPath'], patient, str(self.ui.dirSeqType.currentText()), acq) + + + #******************************** Add New Subject + # ANONYMIZATION TAKES PLACE HERE + def updatePatientCode(self): + # __ + if self.prefs['projectSelected'][0] == 1 or self.prefs['projectSelected'][0] == 2: + print "neuropsynov or classique" + self.ui.subjectPatientCode.setText(self.ui.subjectSiteCombo.currentText() + '_' + str(self.ui.subjectYearSpinbox.value()) + '_' + str(self.ui.subjectPatientName.text())[:3].upper() + str(self.ui.subjectPatientFirstName.text())[:1].lower()) + if self.prefs['projectSelected'][0] == 0: + print "f-Tract" + self.ui.subjectPatientCode.setText(str(self.ui.subjectPatientName.text()).upper() + str(self.ui.subjectSiteCombo.currentText()).upper()) + if self.prefs['projectSelected'][0] == 3: + print "other" + self.ui.subjectPatientCode.setText(self.ui.subjectSiteCombo.currentText() + '_' + str(self.ui.subjectYearSpinbox.value()) + '_' + str(self.ui.subjectPatientName.text())[:3].upper() + str(self.ui.subjectPatientFirstName.text())[:1].lower()) + + def storePatientInDB(self): + + anon = str(self.ui.subjectPatientCode.text()) + if self.prefs['projectSelected'][0] == 1 or self.prefs['projectSelected'][0] == 2: + if len(anon) < 10: + QtGui.QMessageBox.warning(self, u"Subject adding", u"Impossible to add the subject, subject identifier is too short and doesn't match the subject identifier model chosen in preferences") + return + if self.prefs['projectSelected'][0] == 0: + if len(anon) < 16: + QtGui.QMessageBox.warning(self, u"Subject adding", u"Impossible to add the subject, subject identifier is too short and doesn't match the subject identifier model chosen in preferences") + return + elif len(anon) > 16: + QtGui.QMessageBox.warning(self, u"Subject adding", u"Impossible to add the subject, subject identifier is too long and doesn't match the subject identifier model chosen in preferences") + return + else: + if not (anon[0:4].isdigit() and not anon[4:8].isdigit() and anon[8:].isdigit() and anon[7] == '_'): + QtGui.QMessageBox.warning(self, u"Subject adding", u"Impossible to add the subject, subject identifier doesn't match the subject identifier model chosen in preferences: ex: 0001GRE_yyyymmdd") + return + else: + if not int(anon[8:12]) > 1950 and not int(anon[8:12]) < 2100 and not int(anon[12:14]) >0 and not int(anon[12:14]) < 13 and not int(anon[14:16]) > 0 and not int(anon[14:16]) < 32: + QtGui.QMessageBox.warning(self, u"Subject adding", u"Impossible to add the subject, subject identifier doesn't match the subject identifier model chosen in preferences: ex: 0001GRE_yyyymmdd") + return + + + wdi = WriteDiskItem( 'Subject', 'Directory' ) + di = wdi.findValue( { 'center': str(self.ui.subjectProtocolCombo.currentText()), 'subject' : anon } ) + if di is None: + QtGui.QMessageBox.warning(self, u"Error", u"Impossible to find a valid path for the patient") + self.setStatus(u"Subject add failed : the path is not valid") + return + # Create directories that do not exist yet + self.createItemDirs(di) + try: + os.mkdir(di.fileName()) + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Subject %s added to the database"%anon) + self.currentSubject = anon + except: + self.setStatus(u"Subject adding failed : impossible to create subject folder") + + self.ui.tabWidget.setCurrentIndex(2) + + + + # ******************************* Implantation + + def selectImplSubject(self, subj): + """ A BrainVisa subject was selected : query the database to get the available images""" + rdi = ReadDiskItem( 'Electrode Implantation Coronal Image', 'BrainVISA image formats', requiredAttributes={'center':str(self.ui.implProtocolCombo.currentText()), 'subject':str(subj)} ) + coros = list( rdi._findValues( {}, None, False ) ) + coro = None + if len(coros) == 0: + self.ui.implCoroLabel.setText("no image") + elif len(coros) > 1: + QtGui.QMessageBox.warning(self, "Erreur", "Ce sujet a plusieurs implantations enregistrees ! Cette situation n'est pas geree par ce logiciel") + print repr(coros) + else: + self.ui.implCoroLabel.setText(str(coros[0].fullPath())) + coro = coros[0].fullPath() + + rdi = ReadDiskItem( 'Electrode Implantation Sagittal Image', 'BrainVISA image formats', requiredAttributes={'center':str(self.ui.implProtocolCombo.currentText()), 'subject':str(subj)} ) + sags = list( rdi._findValues( {}, None, False ) ) + sag = None + if len(sags) == 0: + self.ui.implSagLabel.setText("no image") + elif len(sags) > 1: + QtGui.QMessageBox.warning(self, "Erreur", "Ce sujet a plusieurs implantations enregistrees ! Cette situation n'est pas geree par ce logiciel") + print repr(sags) + else: + self.ui.implSagLabel.setText(str(sags[0].fullPath())) + sag = sags[0].fullPath() + self.displayAnatomist(coro, sag) + + def openImplCoro(self): + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open Coronal 2D Image", "", "Images (*.gif *.jpg *.jpeg *.png)")) + if not path: + return + self.ui.implCoroLabel.setText(path) + sag = str(self.ui.implSagLabel.text()) + if sag == "": + sag = None + self.displayAnatomist(path, sag) + + def importImplCoro(self): + wdi = WriteDiskItem('Electrode Implantation Coronal Image', 'JPEG image' )#'gz compressed NIFTI-1 image' ) + di = wdi.findValue( { 'center': str(self.ui.implProtocolCombo.currentText()), 'subject' : str(self.ui.implSubjectCombo.currentText()) } ) + if di is None: + QtGui.QMessageBox.warning(self, "Erreur", "Impossible de trouver un chemin valide pour importer l'image coro dans BrainVisa") + return + # Copy the file : lancer l'importation standard de T1 MRI pour la conversion de format et + destination = di.fileName() + print "Importing file as "+destination + # Create directories that do not exist yet + self.createItemDirs(di) + # + ret = subprocess.call(['AimsFileConvert', '-i', str(self.ui.implCoroLabel.text()), '-o', str(destination)]) + if ret < 0: + print "Erreur d'importation" + QtGui.QMessageBox.warning(self, "Erreur", "Erreur d'importation BrainVisa / AimsFileConvert") + return + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Rapport d'implantation coronal importé") + + + def openImplSag(self): + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open Sagittal 2D Image", "", "Images (*.gif *.jpg *.jpeg *.png)")) + if not path: + return + self.ui.implSagLabel.setText(path) + coro = str(self.ui.implCoroLabel.text()) + if coro == "": + coro = None + self.displayAnatomist(coro, path) + + + def importImplSag(self): + wdi = WriteDiskItem('Electrode Implantation Sagittal Image', 'JPEG image' )#'gz compressed NIFTI-1 image' ) + di = wdi.findValue( { 'center': str(self.ui.implProtocolCombo.currentText()), 'subject' : str(self.ui.implSubjectCombo.currentText()) } ) + if di is None: + QtGui.QMessageBox.warning(self, "Erreur", "Impossible de trouver un chemin valide pour importer l'image sagittale dans BrainVisa") + return + # Copy the file : lancer l'importation standard de T1 MRI pour la conversion de format et + destination = di.fileName() + print "Importing file as "+destination + # Create directories that do not exist yet + self.createItemDirs(di) + # + ret = subprocess.call(['AimsFileConvert', '-i', str(self.ui.implCoroLabel.text()), '-o', str(destination)]) + if ret < 0: + print "Erreur d'importation" + QtGui.QMessageBox.warning(self, "Erreur", "Erreur d'importation BrainVisa / AimsFileConvert") + return + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Rapport d'implantation Sagittal importé") + + def openImplPpt(self): + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open PPT implantation schema", "", "Powerpoint file (*.ppt *.pptx)")) + if not path: + return + self.ui.implPptLabel.setText(path) + + + def importImplPpt(self): + wdi = WriteDiskItem('Electrode Implantation Powerpoint report', 'Powerpoint file' ) + di = wdi.findValue( { 'center': str(self.ui.implProtocolCombo.currentText()), 'subject' : str(self.ui.implSubjectCombo.currentText()) } ) + if di is None: + QtGui.QMessageBox.warning(self, "Erreur", "Impossible de trouver un chemin valide pour importer le rapport Powerpoint dans BrainVisa") + return + # Copy the file + destination = di.fileName() + print "Importing file as "+destination + # Create directories that do not exist yet + self.createItemDirs(di) + shutil.copyfile(str(self.ui.implPptLabel.text()), str(destination)) + if ret < 0: + print "Erreur d'importation" + QtGui.QMessageBox.warning(self, "Erreur", "Erreur lors de la copie du fichier") + return + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Rapport d'implantation Powerpoint importé") + + def openImplPdf(self): + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open PDF implantation schema", "", "PDF file (*.pdf)")) + print "Chemin du PDF %s"%path + if not path: + return + self.ui.implPdfLabel.setText(path) + + def openImplPdf2(self): + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open PDF implantation schema", "", "PDF file (*.pdf)")) + print "Chemin du PDF %s"%path + if not path: + return + self.ui.implPdfLabel2.setText(path) + + def openImplElListPdf(self): + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open PDF Electrode List", "", "PDF file (*.pdf)")) + print "Chemin du PDF %s"%path + if not path: + return + self.ui.implElListPdfLabel.setText(path) + + + def importImplPdf(self): + wdi = WriteDiskItem('Electrode Implantation PDF report', 'PDF file' ) + di = wdi.findValue( { 'center': str(self.ui.implProtocolCombo.currentText()), 'subject' : str(self.ui.implSubjectCombo.currentText()), 'planning' : 'True' } ) + if di is None: + QtGui.QMessageBox.warning(self, "Erreur", "Impossible de trouver un chemin valide pour importer le rapport PDF dans BrainVisa") + return + # Copy the file + destination = di.fileName() + print "Importing file as "+destination + # Create directories that do not exist yet + self.createItemDirs(di) + try: + shutil.copyfile(str(self.ui.implPdfLabel.text()), str(destination)) + except: + print "Erreur d'importation" + QtGui.QMessageBox.warning(self, "Erreur", "Erreur lors de la copie du fichier PDF") + return + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Rapport d'implantation PDF importé") + + def importImplPdf2(self): + wdi = WriteDiskItem('Electrode Implantation PDF report', 'PDF file' ) + di = wdi.findValue( { 'center': str(self.ui.implProtocolCombo.currentText()), 'subject' : str(self.ui.implSubjectCombo.currentText()), 'planning' : 'False' } ) + if di is None: + QtGui.QMessageBox.warning(self, "Erreur", "Impossible de trouver un chemin valide pour importer le rapport PDF dans BrainVisa") + return + # Copy the file + destination = di.fileName() + print "Importing file as "+destination + # Create directories that do not exist yet + self.createItemDirs(di) + try: + shutil.copyfile(str(self.ui.implPdfLabel2.text()), str(destination)) + except: + print "Erreur d'importation" + QtGui.QMessageBox.warning(self, "Erreur", "Erreur lors de la copie du fichier PDF") + return + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Rapport d'implantation PDF importé") + + def importImplElListPdf(self): + wdi = WriteDiskItem('Electrode List PDF', 'PDF file' ) + di = wdi.findValue( { 'center': str(self.ui.implProtocolCombo.currentText()), 'subject' : str(self.ui.implSubjectCombo.currentText()), 'planning' : 'False' } ) + if di is None: + QtGui.QMessageBox.warning(self, "Erreur", "Impossible de trouver un chemin valide pour importer la liste PDF dans BrainVisa") + return + # Copy the file + destination = di.fileName() + print "Importing file as "+destination + # Create directories that do not exist yet + self.createItemDirs(di) + try: + shutil.copyfile(str(self.ui.implElListPdfLabel.text()), str(destination)) + except: + print "Erreur d'importation" + QtGui.QMessageBox.warning(self, "Erreur", "Erreur lors de la copie du fichier PDF") + return + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Rapport d'implantation PDF importé") + + # ******************************* Registration + + def selectRegSubject(self, subj): + """ A BrainVisa subject was selected : query the database to get the list of images""" + # Display "Date : XXXX-XX-XX - Seq: T1 - Acq : T1Pre + self.ui.regImageList.clear() + self.ui.regImageList2.clear() + images = self.findAllImagesForSubject(self.ui.regProtocolCombo.currentText(), subj) + #name = modality + acquisition + subacquisition if exist subacquisition key else modality + acquisition + + dict_temporaire1 = {} + for i in images: + if 'subacquisition' in i.attributes().keys(): + dict_temporaire1.update({i.attributes()['modality'] + ' - ' + i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition']:i.fileName()}) + else: + dict_temporaire1.update({i.attributes()['modality'] + ' - ' + i.attributes()['acquisition']:i.fileName()}) + + dict_temporaire2 = {} + for i in images: + if 'subacquisition' in i.attributes().keys(): + dict_temporaire2.update({i.attributes()['modality'] + ' - ' + i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition']:i}) + else: + dict_temporaire2.update({i.attributes()['modality'] + ' - ' + i.attributes()['acquisition']:i}) + + self.ui.regImageList.addItems(sorted([i.attributes()['modality'] + ' - '+ i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition'] if 'subacquisition' in i.attributes().keys()\ + else i.attributes()['modality'] + ' - '+ i.attributes()['acquisition'] for i in images ])) + self.ui.regImageList2.addItems(sorted([i.attributes()['modality'] + ' - '+ i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition'] if 'subacquisition' in i.attributes().keys()\ + else i.attributes()['modality'] + ' - '+ i.attributes()['acquisition'] for i in images ])) + + + self.regImagePaths = dict_temporaire1 + self.regImages = dict_temporaire2 + + + def selectRegImage(self, item): + """ A BrainVisa image was double-clicked : display it !""" + self.clearAnatomist() + image = self.regImages[str(item.text())] + mri = self.a.loadObject(image) + self.a.addObjects(mri, self.wins[:2]) + self.dispObj.append(mri) + + def selectRegImage2(self, item): + """ A BrainVisa image was double-clicked in the second list: display it !""" + self.clearAnatomist(self.wins[2:]) + #path = self.regImagePaths[str(item.text())] + image = self.regImages[str(item.text())] + mri = self.a.loadObject(image) + self.a.addObjects(mri, self.wins[2:]) + self.dispObj.append(mri) + + def registerNormalizeSubject(self): + """ Registers all images of the subject with SPM, then store the transforms in BrainVisa database, and launch T1pre morphologist analysis (brain segmentation) """ + proto = str(self.ui.regProtocolCombo.currentText()) + subj = str(self.ui.regSubjectCombo.currentText()) + images = self.findAllImagesForSubject(proto, subj) + # Find all images, normalize the T1s, find the T1pre if there is one, read image headers, store their referentials and transformations in the DB + t1preImage = None + for image in images: + patient = image.attributes()['subject'] + acq = image.attributes()['acquisition'] + # Store Scanner-based referential and referential files in the DB + if not image.attributes()['modality'] == 'statistic_data' and not image.attributes()['modality'] == 'freesurfer_atlas' and not image.attributes()['modality'] == 'hippofreesurfer_atlas': + print "do the coregistration" + self.storeImageReferentialsAndTransforms(image) + # If this is a T1, normalize it to MNI (pre or post). If the pre is badly normalized, "using the post" should be stored in the DB + if acq.startswith('T1'): + self.setStatus("Normalization of %s to MNI referential in progress ..."%acq) + self.spmNormalize(image.fileName(), proto, patient, acq) + # If there is a T1pre, remember the image + if acq.find('T1pre') == 0: + t1preImage = image + + # No T1pre : nothing else to do + if t1preImage is None: + return + + for image in images: + # A T1pre is there, coregister all images to it + if image == t1preImage: + continue + elif image.attributes()['modality'] == 'statistic_data' or image.attributes()['modality'] == 'freesurfer_atlas' or image.attributes()['modality'] == 'hippofreesurfer_atlas': + #pdb.set_trace() + print "attribute T1pre referential to this modality {}".format(image.attributes()['modality']) + self.transfoManager.setReferentialTo(image, t1preImage.attributes()['referential'] ) + continue + acq = image.attributes()['acquisition'] + patient = image.attributes()['subject'] + + if self.coregMethod == 'ANTs': + print("ANTs coregistration used") + temp_folder_ants = tempfile.mkdtemp('ANTs_IntrAnat') +'/' + + ants_call = '{}/antsRegistrationSyN.sh -d 3 -f {} -m {} -o {} -t r'.format(self.prefs['ants'],str(t1preImage.fullPath()),str(image.fullPath()),temp_folder_ants) + thr = Executor(ants_call.split()) + thr.finished.connect(lambda:self.taskfinished(u"ANTs Coregister done", thr)) + thr.finished.connect(lambda im = image, tmp_folder=temp_folder_ants:self.setANTstrm_database(im, tmp_folder)) + self.threads.append(thr) + thr.start() + + #to mettre dans la database + #thr.finished.connect(lambda im=image, trm=tmpOutput:self.insertTransformationToT1pre(trm,im)) + + elif self.coregMethod == 'spm': + print("spm coregistration used") + if self.ui.regResampleCheck.isChecked(): + self.setStatus('Coregistration of the image: '+ acq + u" with resampling") + self.spmCoregisterResample(image, t1preImage) + else: + self.setStatus('Coregistration of the image: '+ acq) + self.spmCoregister(image, t1preImage) + + elif self.coregMethod == 'Aims': + print("Aims coregistration used") + pdb.set_trace() + #ret = subprocess.call(['AimsMIRegister', '-r', str(t1preImage.fullPath()), '-t', str(image.fullPath()), '--dir', tmp_trm_path, '--inv',tmp_trm_path2]) + #if ret < 0: + # print "coregistration error: "+ str(image.fullPath())#terminal + # QtGui.QMessageBox.warning(self, "Error", u"The coregistration didn't work") #utilisateur + # return + #self.insertTransformationToT1pre(tmp_trm_path,image) + + + self.mriAcPc = t1preImage # Store the mri for Morphologist + self.runBVMorphologist(t1preImage) + # Check the registrations with anatomist when threads are done + + def segmentationHIPHOP(self): + + proto = str(self.ui.regProtocolCombo.currentText()) + subj = str(self.ui.regSubjectCombo.currentText()) + images = self.findAllImagesForSubject(proto, subj) + # Find all images, normalize the T1s, find the T1pre if there is one, read image headers, store their referentials and transformations in the DB + t1preImage = None + for image in images: + patient = image.attributes()['subject'] + acq = image.attributes()['acquisition'] + # Store Scanner-based referential and referential files in the DB + if acq.startswith('T1'): + # If there is a T1pre, remember the image + if acq.find('T1pre') == 0: + t1preImage = image + + # No T1pre : nothing else to do + if t1preImage is None: + return + + self.mriAcPc = t1preImage + self.runBVMorphologist(t1preImage) + + + def setANTstrm_database(self,im, tmp_folder): + + file_to_open = tmp_folder + '0GenericAffine.mat' + tmp_trm_path = getTmpFilePath('txt') + ants_call ='{}/ConvertTransformFile 3 {} {} --RAS --homogeneousMatrix'.format(self.prefs['ants'],file_to_open,tmp_trm_path) + runCmd(ants_call.split()) + info_mat = numpy.loadtxt(tmp_trm_path) + info_mat = numpy.linalg.inv(info_mat) + rot_mat = info_mat[:3,:3] + tr_mat = info_mat[:3,3] + result_mat = numpy.vstack((tr_mat,rot_mat)) + #info_mat = scipy.io.loadmat(file_to_open) + #matrix_unshaped = info_mat['AffineTransform_double_3_3'] + #matrix_shaped = matrix_unshaped.reshape(4,3) + #matrix_shaped = numpy.roll(matrix_shaped,3) + + numpy.savetxt(tmp_trm_path,result_mat,delimiter =' ',fmt='%8.8f') + self.insertTransformationToT1pre(tmp_trm_path,im) + if 'ANTs_IntrAnat' in tmp_folder: + shutil.rmtree(tmp_folder) + + + + def enableACPCButtons(self, trueorfalse): + """ Enables or disables all buttons for entering AC/PC reference points """ + self.ui.regAcButton.setEnabled(trueorfalse) + self.ui.regPcButton.setEnabled(trueorfalse) + self.ui.regIhButton.setEnabled(trueorfalse) + self.ui.regLhButton.setEnabled(trueorfalse) + self.ui.regACPCLabel.setEnabled(trueorfalse) + self.ui.regAcPcValidateButton.setEnabled(trueorfalse) + + def runBVMorphologist(self, image): + """ Runs the morphologist analysis to get segmented brain and hemispheres. + Just activates the buttons to enter AC/PC. The validate button will run the + analysis itself""" + + # Display + self.clearAnatomist() + mri = self.a.loadObject(image.fileName()) + self.dispObj.append(mri) + self.a.addObjects(mri, self.wins) + self.enableACPCButtons(True) + # Ask the user to provide AC/PC information to launch MRI segmentation + QtGui.QMessageBox.information(self, "AC/PC", "Enter AC, PC, IH, LH then validate to segment the brain", QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) + + return None + + def validateAcPc(self, ): + if not all(k in self.AcPc for k in ('AC','PC','IH','LH')): + # Some values are missing + QtGui.QMessageBox.warning(self, 'Missing points', u"You have entered the following points %s, You have to enter AC, PC, IH and LH"%repr(self.AcPc.keys())) + return + + + # reset buttons color + self.ui.regAcButton.setStyleSheet("") + self.ui.regPcButton.setStyleSheet("") + self.ui.regIhButton.setStyleSheet("") + self.ui.regLhButton.setStyleSheet("") + + + #morphologist = processes.getProcessInstance('morphologist') + #morphologist.executionNode().PrepareSubject.setSelected(False) + #morphologist.executionoNode().BiasCorrection.setSelected(False) + #self.brainvisaContext.runInteractiveProcess(lambda x='':self.hiphopStart() , morphologist, t1mri = self.mriAcPc, perform_normalization = False, anterior_commissure = self.AcPc['AC'],\ + # posterior_commissure = self.AcPc['PC'], interhemispheric_point = self.AcPc['IH'], left_hemisphere_point = self.AcPc['LH'], perform_sulci_recognition = True) + + + if 'Gado' in self.mriAcPc.attributes().keys(): + if not self.mriAcPc.attributes()['Gado']: + self.brainvisaContext.runInteractiveProcess(lambda x='':self.hiphopStart() , 'Morphologist 2015', t1mri = self.mriAcPc, perform_normalization = False, anterior_commissure = self.AcPc['AC'],\ + posterior_commissure = self.AcPc['PC'], interhemispheric_point = self.AcPc['IH'], left_hemisphere_point = self.AcPc['LH'], perform_sulci_recognition = True) + self.setStatus(u"Starting segmentation BrainVisa/Morphologist2015 of the image T1 pre-implantation") + # Close the display, disable the buttons and forget AcPc coordinates (they could be mistakenly used for another subject !) + self.clearAnatomist() + self.enableACPCButtons(False) + self.AcPc = {} + + if not 'Gado' in self.mriAcPc.attributes().keys(): + self.brainvisaContext.runInteractiveProcess(lambda x='':self.hiphopStart() , 'Morphologist 2015', t1mri = self.mriAcPc, perform_normalization = False, anterior_commissure = self.AcPc['AC'],\ + posterior_commissure = self.AcPc['PC'], interhemispheric_point = self.AcPc['IH'], left_hemisphere_point = self.AcPc['LH'], perform_sulci_recognition = True) + self.setStatus(u"Starting segmentation BrainVisa/Morphologist2015 of the image T1 pre-implantation") + # Close the display, disable the buttons and forget AcPc coordinates (they could be mistakenly used for another subject !) + self.clearAnatomist() + self.enableACPCButtons(False) + self.AcPc = {} + + if 'Gado' in self.mriAcPc.attributes().keys(): + if self.mriAcPc.attributes()['Gado']: + morphologist = processes.getProcessInstance('morphologist') + morphologist.executionNode().PrepareSubject.setSelected(True) + morphologist.executionNode().BiasCorrection.setSelected(True) + morphologist.executionNode().HistoAnalysis.setSelected(False) + morphologist.executionNode().BrainSegmentation.setSelected(False) + morphologist.executionNode().Renorm.setSelected(False) + morphologist.executionNode().SplitBrain.setSelected(False) + morphologist.executionNode().TalairachTransformation.setSelected(False) + morphologist.executionNode().HeadMesh.setSelected(False) + morphologist.executionNode().HemispheresProcessing.setSelected(False) + morphologist.executionNode().SulcalMorphometry.setSelected(False) + + self.brainvisaContext.runInteractiveProcess(lambda x='':self.run2ndpartMorphologist() , morphologist, t1mri = self.mriAcPc, perform_normalization = False, anterior_commissure = self.AcPc['AC'],\ + posterior_commissure = self.AcPc['PC'], interhemispheric_point = self.AcPc['IH'], left_hemisphere_point = self.AcPc['LH'], perform_sulci_recognition = True) + #def spmRegisterPatient(self, protocol, patient, acq): + ## Comment choisir le moment pour recaler les post avec les pre, si l'import est fait dans l'ordre post puis pre ? + ## Solution : + ## - a chaque importation, on regarde les acquisitions existantes pour le patient concerné + #images = self.findAllImagesForSubject(protocol, patient) + #nameAcq=[t.attributes()['acquisition'] for t in images] + #na = [n.split('_')[0] for n in nameAcq] # same without the acquisition date e.g. 'T1pre' instead of 'T1pre_2001_01_01' + #current = [t for t in images if str(t.attributes()['acquisition']) == str(acq)][0] + + #thrs = [] + + ## - si on est en train d'importer la T1pre, on recale toutes les autres vers cette dernière + #if acq.split('_')[0] == 'T1pre': + #thrs.append(self.spmCoregister([t.fileName() for t in images if t != current], current.fileName())) + + ## - si on a une T1pre existante, on recale la nouvelle image vers la T1pre + #if 'T1pre' in na and acq.split('_')[0] != 'T1pre': + #thrs.append(self.spmCoregister([current.fileName(),], images[na.index('T1pre')].fileName())) + + ## - si on a une T1, on la recale vers MNI (que ce soit pre ou post) et on marque dans la base de données le recalage MNI actif + #if acq.startswith('T1'): + #self.setStatus("Normalisation de %s vers le referentiel MNI en cours..."%acq) + #thrs.append(self.spmNormalize(current.fileName(), protocol, patient, acq)) + + #return thrs + + def run2ndpartMorphologist(self): + + print "run segmentation to remove Gado on T1 no bias" + nobiasRDI = ReadDiskItem("T1 MRI Bias Corrected", 'BrainVISA volume formats',requiredAttributes={"center":self.currentProtocol,"subject":self.currentSubject}) + nobiasimages = list( nobiasRDI._findValues( {}, None, False ) ) + id_pre = [x for x in range(len(nobiasimages)) if 'pre' in str(nobiasimages[x])] + #je change le .nii par le segmenté et je le rechange à la fin ? c'est moche ... + pathTPMseg = os.path.join(str(self.prefs['spm']),'tpm','TPM.nii') + import copy + splittedName = str(nobiasimages[id_pre[0]]).split('/') + c1Name = copy.deepcopy(splittedName) + c2Name = copy.deepcopy(splittedName) + c3Name = copy.deepcopy(splittedName) + c4Name = copy.deepcopy(splittedName) + c1Name[-1] = str("c1")+c1Name[-1] + c1Name = '/'.join(c1Name) + c2Name[-1] = str("c2")+c2Name[-1] + c2Name = '/'.join(c2Name) + c3Name[-1] = str("c3")+c3Name[-1] + c3Name = '/'.join(c3Name) + c4Name[-1] = str("c4")+c4Name[-1] + c4Name = '/'.join(c4Name) + splittedName[-1]=str("WithoutGado.nii") + splittedName = '/'.join(splittedName) + call = matlab_removeGado%("'"+str(self.prefs['spm'])+"'","'"+str( str(nobiasimages[id_pre[0]]))+",1'","'"+str(pathTPMseg)+",1'","'"+str(pathTPMseg)+",2'","'"+str(pathTPMseg)+",3'","'"+str(pathTPMseg)+",4'","'"+str(pathTPMseg)+",5'","'"+str(pathTPMseg)+",6'",\ + "'"+c1Name+"'","'"+c2Name+"'","'"+c3Name+"'","'"+c4Name+"'","'"+str(nobiasimages[id_pre[0]])+"'","'"+str(splittedName)+"'") + matlabRun(call) + print "segmentation gado done" + + cmd1 = ['mv', str(nobiasimages[id_pre[0]]), os.path.join('/tmp',self.currentSubject+'backup.nii')] + cmd2 = ['cp',str(splittedName), str(nobiasimages[id_pre[0]])] + line1 = runCmd(cmd1) + line2 = runCmd(cmd2) + morphologist = processes.getProcessInstance('morphologist') + morphologist.executionNode().PrepareSubject.setSelected(False) + morphologist.executionNode().BiasCorrection.setSelected(False) + morphologist.executionNode().HistoAnalysis.setSelected(True) + morphologist.executionNode().BrainSegmentation.setSelected(True) + morphologist.executionNode().Renorm.setSelected(True) + morphologist.executionNode().SplitBrain.setSelected(True) + morphologist.executionNode().TalairachTransformation.setSelected(False) + morphologist.executionNode().HeadMesh.setSelected(True) + morphologist.executionNode().HemispheresProcessing.setSelected(True) + morphologist.executionNode().SulcalMorphometry.setSelected(True) + + self.brainvisaContext.runInteractiveProcess(lambda x='':self.hiphopStart() , morphologist, t1mri = self.mriAcPc, perform_normalization = False, anterior_commissure = self.AcPc['AC'],\ + posterior_commissure = self.AcPc['PC'], interhemispheric_point = self.AcPc['IH'], left_hemisphere_point = self.AcPc['LH'], perform_sulci_recognition = True) + + def hiphopStart(self): + + if 'Gado' in self.mriAcPc.attributes().keys(): + if self.mriAcPc.attributes()['Gado']: + print "gado has been removed" + nobiasRDI = ReadDiskItem("T1 MRI Bias Corrected", 'BrainVISA volume formats',requiredAttributes={"center":self.currentProtocol,"subject":self.currentSubject}) + nobiasimages = list( nobiasRDI._findValues( {}, None, False ) ) + id_pre = [x for x in range(len(nobiasimages)) if 'pre' in str(nobiasimages[x])] + cmd = ['mv',os.path.join('/tmp',self.currentSubject+'backup.nii'),str(nobiasimages[id_pre[0]])] + line1 = runCmd(cmd) + + self.taskfinished(u'Segmentation et maillages BrainVisa') + self.setStatus(u"Starting of HIP/HOP") + attr = self.mriAcPc.attributes() + #pdb.set_trace() + Lrdi = ReadDiskItem('Labelled Cortical folds graph', 'Graph and data',requiredAttributes={ 'side': 'left','subject':attr['subject'] , 'center':attr['center']}) + Rrdi = ReadDiskItem('Labelled Cortical folds graph', 'Graph and data',requiredAttributes={ 'side': 'right' ,'subject':attr['subject'] , 'center':attr['center']}) + Lrdi = list( Lrdi._findValues( {}, None, False ) ) + + if len(Lrdi) == 0: + print('no left sulci label found, CANNOT RUN HIP HOP') + return + + Rrdi = list( Rrdi._findValues( {}, None, False ) ) + if len(Rrdi) == 0: + print('no right sulci label found, CANNOT RUN HIP HOP') + return + + self.brainvisaContext.runInteractiveProcess(lambda x='':self.taskfinished(u'hip hop done'),'Hip-Hop Cortical Parameterization', Lgraph = Lrdi[0], Rgraph = Rrdi[0], sulcus_identification ='label') + + + def spmCoregister(self, image, target): + """ Coregisters an image (ReadDiskItem) to a target image (filepath) - rigid registration""" + # Temporary txt file to store the trm transformation + tmpOutput = getTmpFilePath('txt') + #pdb.set_trace() + #truc = subprocess.call(['AimsFileInfo', '-i', str(image.fileName())]) + #someinfo_keys = image._minfAttributes.keys() + #IndexDataType = someinfo_keys.index('data_type') + #someinfo_values = image._minfAttributes.values() + imageFileName = image.fileName() + if image.attributes()['data_type'] == 'RGB': + print "it is RGB" + imageFileName = getTmpFilePath('nii') + ret = subprocess.call(['AimsFileConvert', '-i', str(image.fileName()), '-o', str(imageFileName), '-t', 'S16']) + if ret < 0: + print "Conversion to S16 error: "+repr(registeredPath) #terminal + QtGui.QMessageBox.warning(self, "Error", u"The conversion into S16 didn't worked!") #utilisateur + return + + if 'brainCenter' not in image.attributes() or 'brainCenter' not in target.attributes(): + call = spm_coregister%("'"+str(self.prefs['spm'])+"'","'"+str(imageFileName)+",1'", "'"+str(target)+",1'", str([0, 0 ,0]), str([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]), str([0, 0, 0]), str([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),"'"+tmpOutput+"'") + else: + #pdb.set_trace() + call = spm_coregister%("'"+str(self.prefs['spm'])+"'","'"+str(imageFileName)+",1'", "'"+str(target)+",1'", str(image.attributes()['brainCenter']), str(image.attributes()['SB_Transform']), str(target.attributes()['brainCenter']), str(target.attributes()['SB_Transform']), "'"+tmpOutput+"'") + + + # TODO CHECK REGISTRATION AT THE END ! + thr = matlabRunNB(call)#, lambda: self.taskfinished("spm coregister")) #matlabRunNB(call) + thr.finished.connect(lambda:self.taskfinished(u"SPM Coregister done", thr)) + #pdb.set_trace() + thr.finished.connect(lambda im=image, trm=tmpOutput:self.insertTransformationToT1pre(trm,im)) + if image.attributes()['data_type'] == 'RGB': + thr.finished.connect(lambda im=imageFileName:os.remove(im) and os.remove(im+'.minf')) + self.threads.append(thr) + thr.start() + return thr + + + def spmCoregisterResample(self, image, target): + """ Coregisters an image (ReadDiskItem) to a target image (filepath) - rigid registration + !!! Replaces the original image with the resampled image in the database !!! + If the registration is faulty, the image must be imported again. + """ + #pdb.set_trace() + call = spm_coregisterReslice%("'"+str(self.prefs['spm'])+"'","{'"+str(target)+",1'}", "{'"+str(image.fileName())+",1'}") + spl = os.path.split(image.fileName()) + registeredPath = os.path.join(spl[0], 'r'+spl[1]) + thr = matlabRunNB(call)#, lambda: self.taskfinished("spm coregister")) #matlabRunNB(call) + thr.finished.connect(lambda:self.taskfinished(u"SPM Coregister-Resampling done", thr)) + thr.finished.connect(lambda im=image, resamp = registeredPath:self.setResampledToT1pre(im, resamp)) + self.threads.append(thr) + thr.start() + return thr + + def spm_template_t1(self): + #pdb.set_trace() + spm_version = checkSpmVersion(str(self.prefs['spm'])) + if spm_version == '(SPM12)': + return "{'"+str(self.ui.prefSpmTemplateEdit.text())+os.sep+'tpm/TPM.nii'+",1'}" #ou tpm/TPM.nii' parce que pour la normalisation dartel c'est tpm.nii /'toolbox/OldNorm/T1.nii' + elif spm_version == '(SPM8)': + return "{'"+str(self.ui.prefSpmTemplateEdit.text())+os.sep+'templates/T1.nii'+",1'}" + #return "{'"+str(self.ui.prefSpmTemplateEdit.text())+",1'}" + + def spmNormalize(self, image, protocol, patient, acq): + """ Normalize one image (filepath of nifti file) to the T1 template MNI referential""" + spm_version = checkSpmVersion(str(self.prefs['spm'])) + #pdb.set_trace() + if spm_version == '(SPM12)': + print 'SPM12 used' + call = spm12_normalise%("'"+str(self.prefs['spm'])+"'","{'"+str(image)+",1'}", "{'"+str(image)+",1'}", self.spm_template_t1()) + elif spm_version == '(SPM8)': + print 'SPM8 used' + call = spm8_normalise%("'"+str(self.prefs['spm'])+"'","{'"+str(image)+",1'}", "{'"+str(image)+",1'}", self.spm_template_t1()) + #TODO CHECK REGISTRATION AT THE END + #pdb.set_trace() + thr = matlabRunNB(call)#, lambda: self.taskfinished("spm normalize")) #matlabRunNB(call) + # Try to connect the thread signals to a function here that will notice when it finishes + thr.finished.connect(lambda:self.taskfinished(u"SPM Normalize done", thr)) + thr.finished.connect(lambda pr=protocol, pat=patient, a=acq:self.insertSPMdeformationFile(pr, pat, a)) + thr.finished.connect(lambda pr=protocol, pat=patient, a=acq:self.StatisticDataMNItoScannerBased(pr, pat, a)) + self.threads.append(thr) + thr.start() + return thr + + def getScannerBasedRef(self, imageDiskItem): + rdi = ReadDiskItem('Scanner Based Referential', 'Referential') + return rdi.findValue(imageDiskItem) + + def getT1preScannerBasedRef(self, protocol, patient): + rdi = ReadDiskItem('Scanner Based Referential', 'Referential', requiredAttributes={'modality':'t1mri', 'subject':patient, 'center':protocol}) + allT1s = list (rdi._findValues( {}, None, False ) ) + for t1 in allT1s: + if t1.attributes()['acquisition'].startswith(u'T1pre'): + return t1 + return None + + def getT1preNativeRef(self, protocol, patient): + rdi = ReadDiskItem('Referential of Raw T1 MRI', 'Referential', requiredAttributes={'subject':patient, 'center':protocol}) + allT1s = list (rdi._findValues( {}, None, False ) ) + for t1 in allT1s: + if t1.attributes()['acquisition'].startswith(u'T1pre'): + return t1 + return None + + def setResampledToT1pre(self, image, registeredPath): + ret = subprocess.call(['AimsFileConvert', '-i', str(registeredPath), '-o', str(image.fileName()), '-t', 'S16']) + if ret < 0: + print "Importation error of the image resampled by SPM : "+repr(registeredPath) + QtGui.QMessageBox.warning(self, "Error", u"the image has not been resampled by SPM !") + return + # TODO # Should destroy existing referentials for this image + # The referential of this image is the same as the T1 pre + #pdb.set_trace() + self.transfoManager.setReferentialTo(image, self.getT1preNativeRef(image.attributes()['center'], image.attributes()['subject'])) #replace self.getT1preNativeRef(image.attributes()['center'], image.attributes()['subject']) by talairachMNIReferentialId + os.remove(registeredPath) + + def insertTransformationToT1pre(self, trmpath, image): + """Inserts a TRM file in the DB as the transformation between image and the T1pre scanner-based ref from the same subject""" + if not os.path.exists(trmpath): + print "Error : file %s does not exist : cannot insert it as a TRM for image %s"%(trmpath, image.fileName()) + return + # Copy the transformation to the right place and declare it to Brainvisa + t1preRef = self.getT1preScannerBasedRef(image.attributes()['center'],image.attributes()['subject']) + + imageRef = self.getScannerBasedRef(image) + + # + if t1preRef is None or imageRef is None: + print "Cannot find referentials to declare coregister transform : %s %s"%(t1preRef,imageRef) + wdiTransformT1 = WriteDiskItem( 'Transform '+ self.modas[image.attributes()['modality']] +' to another image', 'Transformation matrix', exactType=True, requiredAttributes = {'modalityTarget':t1preRef.attributes()['modality'], 'acquisitionTarget':t1preRef.attributes()['acquisition']} ) + transformT1 = wdiTransformT1.findValue(image) + if transformT1 is None: + print "Cannot find path for T1pre transform in database for %s-> transformation NOT stored !"%(image.fileName()) + else: + #Move the trm file, but remove the old one first + if os.path.exists(transformT1.fullPath()): + os.remove(transformT1.fullPath()) + shutil.move(trmpath, transformT1.fullPath() ) + try: + neuroHierarchy.databases.createDiskItemFromFileName(os.path.dirname( transformT1.fullPath() )) + except: + pass + #set and update database + print ".... setting transfo info : from %s to %s for %s"%(repr(imageRef), repr(t1preRef), repr(transformT1)) + self.transfoManager.setNewTransformationInfo( transformT1, source_referential=imageRef, destination_referential= t1preRef) + self.setStatus(u'Coregister done for '+str(image.attributes()['acquisition'])) + + + def insertSPMdeformationFile(self, protocol, patient, acq): + """ Should be called when a _sn file (SPM normalization transformation file) was created to update it in the database """ + spm_version = checkSpmVersion(str(self.prefs['spm'])) + #pdb.set_trace() + if spm_version == '(SPM8)': + print 'SPM8 used' + wdi = WriteDiskItem('SPM2 normalization matrix', 'Matlab file')#'gz compressed NIFTI-1 image' ) + di = wdi.findValue( { 'center': protocol, 'subject' : patient, 'acquisition':acq } ) + elif spm_version == '(SPM12)': + print 'SPM12 used' + wdi = WriteDiskItem('SPM normalization deformation field', 'NIFTI-1 image' ) + di = wdi.findValue( { 'center': protocol, 'subject' : patient, 'acquisition':acq } ) + if di is None: + QtGui.QMessageBox.warning(self, "Error", "Impossible to find a valid path to import SPM normalization into BrainVisa") + return + + wdi_write = WriteDiskItem('T1 SPM resampled in MNI','NIFTI-1 image') + di_write = wdi_write.findValue({'center': protocol, 'subject' : patient, 'acquisition':acq}) + if not os.path.isfile(di_write.fileName()): + QtGui.QMessageBox.warning(self, "Error", "Impossible dto find a valid path for the T1 coregistered into the MNI") + else: + print "Declaring T1 registered MNI in BrainVisa DB" + di_write.fileName() + neuroHierarchy.databases.insertDiskItem(di_write, update = True) + self.setNormalizedToT1pre(di_write,di_write.fileName()) + + # The file should already be there : if it is not, abort with an error, otherwise declare it in the DB + #pdb.set_trace() + if os.path.isfile(di.fileName()): + print "Declaring SPM normalization in BrainVisa DB : "+di.fileName() + neuroHierarchy.databases.insertDiskItem( di, update=True ) + # Compute deformation fields + #wdi = WriteDiskItem('SPM normalization inverse deformation field','aims readable volume formats') + #di2 = wdi.findValue(di) + #neuroHierarchy.databases.insertDiskItem( di2, update=True ) + + + else: + print "No SPM normalization file found ! The normalization probably failed..." + QtGui.QMessageBox.warning(self, "Error", u"SPM normalization file %s unfound ! \n Normalization probably failed !"%di.fileName()) + return + + def StatisticDataMNItoScannerBased(self, protocol, patient, acq): + + #is there any statistic data to convert to the Scanner-Based space + rdi = ReadDiskItem('Statistic-Data', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(patient) }) + di=list(rdi.findValues({}, None, False)) + StatToConvert = [i for i in range(len(di)) if eval(di[i].attributes()['MNI'])] + + if len(StatToConvert)>0: + + diT1 = ReadDiskItem( 'Raw T1 MRI', 'BrainVISA volume formats', requiredAttributes={'center':protocol, 'subject':patient } ) + allT1 = list(diT1.findValues({},None,False)) + idxT1pre = [i for i in range(len(allT1)) if 'pre' in str(allT1[i])] + self.mriAcPc = allT1[idxT1pre[0]] + + spm_version = checkSpmVersion(str(self.prefs['spm'])) + for i_stat2conv in range(len(StatToConvert)): + + self.setStatus(u"Start MNI to ScannerBased conversion of %s "%str(di[StatToConvert[i_stat2conv]].fileName())) + + #check if inverse deformation field exist. + rdi_defField_read = ReadDiskItem('SPM normalization inverse deformation field','NIFTI-1 image',requiredAttributes={'center':str(protocol), 'subject':str(patient),'acquisition':self.mriAcPc.attributes()['acquisition']}) + di_defField_read=list(rdi_defField_read.findValues({}, None, False)) + + + tempNameMNI2SB = str(di[StatToConvert[i_stat2conv]].fileName()).split('/') + tempNameMNI2SB[-1]= "tmpMNItoScannerBased"+tempNameMNI2SB[-1] + tempNameMNI2SB = "/".join(tempNameMNI2SB) + + if len(di_defField_read) > 0: + print "inverse deformation field found and used" + matlabRun(spm_MNItoScannerBased%("'"+str(self.prefs['spm'])+"'","'"+str(di_defField_read[0].fileName())+"'","'"+str(di[StatToConvert[i_stat2conv]].fileName())+",1'","'"+str(self.mriAcPc)+",1'","'"+tempNameMNI2SB+",1'")) + + cmd1 = ['mv', str(di[StatToConvert[i_stat2conv]].fileName()), di[StatToConvert[i_stat2conv]].fileName()[:-4]+"_MNI.nii.backup"] + line1 = runCmd(cmd1) + + rname = tempNameMNI2SB.split('/') + rname[-1]="r"+rname[-1] + rname = "/".join(rname) + cmd2 = ['cp',rname, str(di[StatToConvert[i_stat2conv]].fileName())] + line2 = runCmd(cmd2) + + os.remove(tempNameMNI2SB) + os.remove(rname) + os.remove(str(di[StatToConvert[i_stat2conv]].fileName())+".minf") + + write_filters = { 'center': protocol, 'acquisition': str(di[StatToConvert[i_stat2conv]].attributes()['acquisition']), 'subject' : str(patient) } + wdi_new = WriteDiskItem('Statistic-Data', 'NIFTI-1 image' )#'gz compressed NIFTI-1 image' ) + write_filters.update({'subacquisition':di[StatToConvert[0]].attributes()['subacquisition']}) + + di_new = wdi_new.findValue(write_filters) + + ret = subprocess.call(['AimsFileConvert', '-i', str(di[StatToConvert[i_stat2conv]].fileName()), '-o', str(di[StatToConvert[i_stat2conv]].fileName())]) + di[StatToConvert[i_stat2conv]].setMinf('MNI','False') + di[StatToConvert[i_stat2conv]].setMinf('ColorPalette','Yellow-Red-White-Blue-Green') + neuroHierarchy.databases.insertDiskItem( di_new, update=True ) + self.transfoManager.setReferentialTo(di_new, self.mriAcPc) + + else: + #look for a y_file second + rdi_y = ReadDiskItem('SPM normalization deformation field','NIFTI-1 image',requiredAttributes={'center':str(protocol), 'subject':str(patient),'acquisition':self.mriAcPc.attributes()['acquisition'] }) + di_y = list(rdi_y.findValues({}, None, False)) + + if len(di_y) == 0: + print "No deformation field found in database" + self.setStatus(u"MNI to ScannerBased conversion of %s not performed, no deformation field found"%str(di[StatToConvert[i_stat2conv]].fileName())) + return + else: + print "deformation field found and used" + wdi_inverse = WriteDiskItem('SPM normalization inverse deformation field','NIFTI-1 image') + dir_yinv_split = str(di_y[0].fileName()).split('/') + name_yinverse = dir_yinv_split.pop()[2:] + #name_yinverse.replace('.nii','_inverse.nii') + dir_yinverse = "/".join(dir_yinv_split) + di_inverse = wdi_inverse.findValue(di_y[0]) + #on fait l'inversion de la deformation + #pour le moment ce bout de code ne marche qu'avec spm12 + if spm_version == '(SPM12)': + print 'SPM12 used' + matlabRun(spm_inverse_y_field12%("'"+str(self.prefs['spm'])+"'","'"+str(di_y[0].fileName())+"'","'"+str(self.mriAcPc)+"'","'"+name_yinverse.replace('.nii','_inverse.nii')+"'","'"+dir_yinverse+"'")) + neuroHierarchy.databases.insertDiskItem( di_inverse, update=True ) + matlabRun(spm_MNItoScannerBased%("'"+str(self.prefs['spm'])+"'","'"+str(di_inverse)+"'","'"+str(di[StatToConvert[i_stat2conv]].fileName())+",1'","'"+str(self.mriAcPc)+",1'","'"+tempNameMNI2SB+",1'")) + + cmd1 = ['mv', str(di[StatToConvert[i_stat2conv]].fileName()), di[StatToConvert[i_stat2conv]].fileName()[:-4]+"_MNI.nii"] + line1 = runCmd(cmd1) + + rname = tempNameMNI2SB.split('/') + rname[-1]="r"+rname[-1] + rname = "/".join(rname) + cmd2 = ['cp',rname, str(di[StatToConvert[i_stat2conv]].fileName())] + line2 = runCmd(cmd2) + + os.remove(tempNameMNI2SB) + os.remove(rname) + os.remove(str(di[StatToConvert[i_stat2conv]].fileName())+".minf") + + write_filters = { 'center': protocol, 'acquisition': str(di[StatToConvert[i_stat2conv]].attributes()['acquisition']), 'subject' : str(patient) } + wdi_new = WriteDiskItem('Statistic-Data', 'NIFTI-1 image' )#'gz compressed NIFTI-1 image' ) + write_filters.update({'subacquisition':di[StatToConvert[i_stat2conv]].attributes()['subacquisition']}) + + di_new = wdi_new.findValue(write_filters) + + ret = subprocess.call(['AimsFileConvert', '-i', str(di[StatToConvert[i_stat2conv]].fileName()), '-o', str(di[StatToConvert[i_stat2conv]].fileName())]) + di[StatToConvert[i_stat2conv]].setMinf('MNI','False') + di[StatToConvert[i_stat2conv]].setMinf('ColorPalette','Yellow-Red-White-Blue-Green') + neuroHierarchy.databases.insertDiskItem( di[StatToConvert[i_stat2conv]], update=True ) + self.transfoManager.setReferentialTo(di[StatToConvert[i_stat2conv]], self.mriAcPc) + + else: + print "doesn't work with SPM8" + return + + self.setStatus(u"MNI to ScannerBased conversion of %s done"%str(di[StatToConvert[i_stat2conv]].fileName())) + + else: + print "no statistic data to convert from MNI to Scanner-Based" + + + + def generateAmygdalaHippoMesh(self, protocol, patient, acq, diFS): + + print("start generation of amygdala and hippocampus meshes") + #attention ça merde quand l'irm est trop haute résolution + + volDestrieux = aims.read(diFS.fullPath()) + npDestrieux = volDestrieux.arraydata() + + lefthippopx = numpy.where(npDestrieux==17) + notlefthippopx = numpy.where(npDestrieux!=17) + lefthippoposition = [[lefthippopx[1][i]*volDestrieux.getVoxelSize()[2],lefthippopx[2][i]*volDestrieux.getVoxelSize()[1],lefthippopx[3][i]*volDestrieux.getVoxelSize()[0]] for i in range(len(lefthippopx[1]))] + righthippopx = numpy.where(npDestrieux==53) + notrighthippopx = numpy.where(npDestrieux!=53) + righthippoposition = [[righthippopx[1][i]*volDestrieux.getVoxelSize()[2],righthippopx[2][i]*volDestrieux.getVoxelSize()[1],righthippopx[3][i]*volDestrieux.getVoxelSize()[0]] for i in range(len(righthippopx[1]))] + + leftamygdalapx = numpy.where(npDestrieux == 18) + notleftamygdalapx = numpy.where(npDestrieux != 18) + rightamygdalapx = numpy.where(npDestrieux == 54) + notrightamygdalapx = numpy.where(npDestrieux != 54) + + #add here a verification of number of pixel per parcels. if not enough, no point to generate a mesh + AmygdalaLeft = True + AmygdalaRight = True + HippoLeft = True + HippoRight = True + + if len(leftamygdalapx[0]) < 50: + AmygdalaLeft = False + if len(rightamygdalapx[0]) < 50: + AmygdalaRight = False + + if len(lefthippopx[0]) < 50: + HippoLeft = False + if len(righthippopx[0]) < 50: + HippoRight = False + + di = ReadDiskItem( 'Raw T1 MRI', 'BrainVISA volume formats', requiredAttributes={'center':protocol, 'subject':patient } ) + allT1 = list(di.findValues({},None,False)) + idxT1pre = [i for i in range(len(allT1)) if 'pre' in str(allT1[i])] + self.storeImageReferentialsAndTransforms(allT1[idxT1pre[0]]) + constraints = { 'center': protocol, 'subject' :patient, 'acquisition':allT1[idxT1pre[0]].attributes()['acquisition'] } + + #il faudrait mettre le referentiel à freesurferatlas la aussi ça serait fait comme ça. + self.transfoManager.setReferentialTo(diFS, allT1[idxT1pre[0]].attributes()['referential'] ) + + if AmygdalaRight: + for ii in range(len(notrightamygdalapx[0])): + volDestrieux.setValue(0,notrightamygdalapx[3][ii],notrightamygdalapx[2][ii],notrightamygdalapx[1][ii]) + + aims.write(volDestrieux,'/tmp/rightamygdala.nii') + volDestrieux = aims.read(diFS.fullPath()) + wdirightamygdala = WriteDiskItem('rightAmygdala', 'GIFTI file' ) + dirightamygdala = wdirightamygdala.findValue(constraints) + if dirightamygdala is None: + print "mesh export : could not find valid path" + else: + if not os.path.isdir(os.path.dirname(dirightamygdala.fullPath())): + os.makedirs(os.path.dirname(dirightamygdala.fullPath())) + ret = subprocess.call(['AimsMeshBrain', '-i', '/tmp/rightamygdala.nii', '-o', dirightamygdala.fullPath()]) + neuroHierarchy.databases.insertDiskItem(dirightamygdala, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dirightamygdala, allT1[idxT1pre[0]].attributes()['referential'] ) + + if AmygdalaLeft: + for ii in range(len(notleftamygdalapx[0])): + volDestrieux.setValue(0,notleftamygdalapx[3][ii],notleftamygdalapx[2][ii],notleftamygdalapx[1][ii]) + + aims.write(volDestrieux,'/tmp/leftamygdala.nii') + volDestrieux = aims.read(diFS.fullPath()) + wdileftamygdala = WriteDiskItem('leftAmygdala', 'GIFTI file' ) + dileftamygdala = wdileftamygdala.findValue(constraints) + if dileftamygdala is None: + print "mesh export : could not find valid path" + else: + if not os.path.isdir(os.path.dirname(dileftamygdala.fullPath())): + os.makedirs(os.path.dirname(dileftamygdala.fullPath())) + ret = subprocess.call(['AimsMeshBrain', '-i', '/tmp/leftamygdala.nii', '-o', dileftamygdala.fullPath()]) + neuroHierarchy.databases.insertDiskItem(dileftamygdala, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dileftamygdala, allT1[idxT1pre[0]].attributes()['referential'] ) + + #pour pouvoir decouper les hippocampes en deux + if isinstance(allT1[idxT1pre[0]].attributes()['SB_Transform'],basestring): + import ast + m = aims.Motion(ast.literal_eval(allT1[idxT1pre[0]].attributes()['SB_Transform'])) + else: + m = aims.Motion(allT1[idxT1pre[0]].attributes()['SB_Transform']) + + if HippoRight: + for ii in range(len(notrighthippopx[0])): + volDestrieux.setValue(0,notrighthippopx[3][ii],notrighthippopx[2][ii],notrighthippopx[1][ii]) + + aims.write(volDestrieux,'/tmp/righthippo.nii') + volDestrieux = aims.read(diFS.fullPath()) + wdirighthippo = WriteDiskItem('rightHippo', 'GIFTI file' ) + dirightHippo = wdirighthippo.findValue(constraints) + if dirightHippo is None: + print "mesh export : could not find valid path" + else: + if not os.path.isdir(os.path.dirname(dirightHippo.fullPath())): + os.makedirs(os.path.dirname(dirightHippo.fullPath())) + ret = subprocess.call(['AimsMeshBrain', '-i', '/tmp/righthippo.nii', '-o', dirightHippo.fullPath()]) + neuroHierarchy.databases.insertDiskItem(dirightHippo, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dirightHippo, allT1[idxT1pre[0]].attributes()['referential'] ) + + wdirighthippoantero = WriteDiskItem('rightanteroHippocampus', 'GIFTI file' ) + wdirighthippopostero = WriteDiskItem('rightposteroHippocampus', 'GIFTI file' ) + dirighthippoantero = wdirighthippoantero.findValue(constraints) + dirighthippopostero = wdirighthippopostero.findValue(constraints) + + UU, ss, rotation, center = self.fitvolumebyellipse(righthippoposition) + + #comment deviner automatiquement quel bout est antero et quel bout est postero... + + mesh = aims.read(str(dirightHippo.fullPath())) + testhippocut = aims.AimsSurfaceTriangle() + testhippocut2 = aims.AimsSurfaceTriangle() + border = aims.AimsTimeSurface(2) + border2 = aims.AimsTimeSurface(2) + aims.SurfaceManip.cutMesh(mesh, [rotation[2,2], rotation[2,1], rotation[2,0], -numpy.inner(rotation[2,:],center)], testhippocut, border) + aims.SurfaceManip.cutMesh(mesh, [-rotation[2,2], -rotation[2,1], -rotation[2,0], numpy.inner(rotation[2,:],center)], testhippocut2, border2) + planmesh = aims.SurfaceManip.meshPlanarPolygon([rotation[2,2], rotation[2,1], rotation[2,0], -numpy.inner(rotation[2,:],center)], border) + planmesh2 = aims.SurfaceManip.meshPlanarPolygon([-rotation[2,2], -rotation[2,1], -rotation[2,0], numpy.inner(rotation[2,:],center)], border2) + + aims.SurfaceManip.meshMerge(testhippocut,planmesh) + aims.SurfaceManip.meshMerge(testhippocut2,planmesh2) + aims.write(testhippocut,'/tmp/testhippocut.gii') + aims.write(testhippocut2,'/tmp/testhippocut2.gii') + + #ret = subprocess.call(['AimsMeshCut', '-i', str(dirightHippo.fullPath()), '-o', '/tmp/testhippocut.gii', '-a',str(rotation[2,2]),'-b',str(rotation[2,1]),'-c',str(rotation[2,0]),'-d',str(-numpy.inner(rotation[2,:],center)),'-p','/tmp/testplan.nii']) + #ret = subprocess.call(['AimsMeshCut', '-i', str(dirightHippo.fullPath()), '-o', '/tmp/testhippocut2.gii', '-a',str(-rotation[2,2]),'-b',str(-rotation[2,1]),'-c',str(-rotation[2,0]),'-d',str(numpy.inner(rotation[2,:],center)),'-p','/tmp/testplan2.nii']) + + #equivalent à : test = aims.read(-numpy.inner(rotation[2,:],center)) truc = aims.AimsTimeSurface_2() bidule=aims.AimsTimeSurface() aims.SurfaceManip.cutMesh(test1,[rotation[2,2],rotation[2,1],rotation[2,0],-numpy.inner(rotation[2,:],center)],bidule,truc) aims.write(bidule,'/tmp/bidule.gii') + hippogii = aims.read('/tmp/testhippocut.gii') + hippovertex = numpy.array(hippogii.vertex().list()) + centerhippo = numpy.average(hippovertex,axis=0) + + hippogii2 = aims.read('/tmp/testhippocut2.gii') + hippovertex2 = numpy.array(hippogii2.vertex().list()) + centerhippo2 = numpy.average(hippovertex2,axis=0) + + coords1 = m.transform(centerhippo) + coords2 = m.transform(centerhippo2) + + if coords2[1] > coords1[1]: + #2 est l'antero; 1 est posterieur + if dirighthippoantero is None or dirighthippopostero is None: + print "mesh export : could not find valid path" + else: + cmd1 = ['mv', '/tmp/testhippocut2.gii', str(dirighthippoantero.fullPath())] + cmd2 = ['mv', '/tmp/testhippocut.gii', str(dirighthippopostero.fullPath())] + line1 = runCmd(cmd1) + line2 = runCmd(cmd2) + neuroHierarchy.databases.insertDiskItem(dirighthippoantero, update = True) + neuroHierarchy.databases.insertDiskItem(dirighthippopostero, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dirighthippoantero, allT1[idxT1pre[0]].attributes()['referential'] ) + self.transfoManager.setReferentialTo(dirighthippopostero, allT1[idxT1pre[0]].attributes()['referential'] ) + elif coords2[1] < coords1[1]: + #1 est l'antero; 2 est le posterieur + if dirighthippoantero is None or dirighthippopostero is None: + print "mesh export : could not find valid path" + else: + cmd1 = ['mv', '/tmp/testhippocut.gii', str(dirighthippoantero.fullPath())] + cmd2 = ['mv', '/tmp/testhippocut2.gii', str(dirighthippopostero.fullPath())] + line1 = runCmd(cmd1) + line2 = runCmd(cmd2) + neuroHierarchy.databases.insertDiskItem(dirighthippoantero, update = True) + neuroHierarchy.databases.insertDiskItem(dirighthippopostero, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dirighthippoantero, allT1[idxT1pre[0]].attributes()['referential'] ) + self.transfoManager.setReferentialTo(dirighthippopostero, allT1[idxT1pre[0]].attributes()['referential'] ) + + # aims.TimeTexture() puis AimsMeshParcellation2VolumeParcellation + if dirighthippoantero is not None and dirighthippopostero is not None: + #we read it, estimate the number of vertex, and attribute the good value to the good number of vertex + #nb vertex of right antero + voxel_size_T1 = [allT1[idxT1pre[0]].attributes()['voxel_size'][0], allT1[idxT1pre[0]].attributes()['voxel_size'][1], allT1[idxT1pre[0]].attributes()['voxel_size'][2], 1.0] + + hippo_vol_antero=aims.Volume(*allT1[idxT1pre[0]].attributes()['volume_dimension'][:3],dtype='S16') + hippo_vol_postero=aims.Volume(*allT1[idxT1pre[0]].attributes()['volume_dimension'][:3],dtype='S16') + hippo_vol_full=aims.Volume(*allT1[idxT1pre[0]].attributes()['volume_dimension'][:3],dtype='S16') + hippo_vol_antero.header()['voxel_size']= voxel_size_T1 + hippo_vol_postero.header()['voxel_size']= voxel_size_T1 + hippo_vol_full.header()['voxel_size']= voxel_size_T1 + + wdirighthippoNII = WriteDiskItem('rightHippocampusNII', 'NIFTI-1 image' ) + dirightHippoNII = wdirighthippoNII.findValue(constraints) + + meshantero = aims.read(dirighthippoantero.fullName()) + meshpostero = aims.read(dirighthippopostero.fullName()) + aims.SurfaceManip.rasterizeMesh(meshantero,hippo_vol_antero,1) + aims.SurfaceManip.rasterizeMesh(meshpostero,hippo_vol_postero,1) + #fill the insides voxel + from scipy import ndimage + for zslices in range(hippo_vol_antero.arraydata().shape[1]): + hippo_vol_antero.arraydata()[0,zslices,:,:] = ndimage.morphology.binary_fill_holes(hippo_vol_antero.arraydata()[0,zslices,:,:]).astype(int) + + for zslices in range(hippo_vol_postero.arraydata().shape[1]): + hippo_vol_postero.arraydata()[0,zslices,:,:] = ndimage.morphology.binary_fill_holes(hippo_vol_postero.arraydata()[0,zslices,:,:]).astype(int) + + hippo_vol_antero *=5301 + hippo_vol_postero *= 5302 + hippo_vol_full = hippo_vol_antero + hippo_vol_postero + for z in xrange(hippo_vol_full.getSizeZ()): + for y in xrange(hippo_vol_full.getSizeY()): + for x in xrange(hippo_vol_full.getSizeX()): + if hippo_vol_full.value(x, y, z) >5302: + hippo_vol_full.setValue(5302, x, y, z) + + aims.write(hippo_vol_full,str(dirightHippoNII.fullPath())) + neuroHierarchy.databases.insertDiskItem(dirightHippoNII, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dirightHippoNII, allT1[idxT1pre[0]].attributes()['referential'] ) + + + if HippoLeft: + for ii in range(len(notlefthippopx[0])): + volDestrieux.setValue(0,notlefthippopx[3][ii],notlefthippopx[2][ii],notlefthippopx[1][ii]) + + aims.write(volDestrieux,'/tmp/lefthippo.nii') + wdilefthippo = WriteDiskItem('leftHippo', 'GIFTI file' ) + dileftHippo = wdilefthippo.findValue(constraints) + if dileftHippo is None: + print "mesh export : could not find valid path" + else: + if not os.path.isdir(os.path.dirname(dileftHippo.fullPath())): + os.makedirs(os.path.dirname(dileftHippo.fullPath())) + ret = subprocess.call(['AimsMeshBrain', '-i', '/tmp/lefthippo.nii', '-o', dileftHippo.fullPath()]) + neuroHierarchy.databases.insertDiskItem(dileftHippo, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dileftHippo, allT1[idxT1pre[0]].attributes()['referential'] ) + + wdilefthippoantero = WriteDiskItem('leftanteroHippocampus', 'GIFTI file' ) + wdilefthippopostero = WriteDiskItem('leftposteroHippocampus', 'GIFTI file' ) + dilefthippoantero = wdilefthippoantero.findValue(constraints) + dilefthippopostero = wdilefthippopostero.findValue(constraints) + + UU, ss, rotation, center = self.fitvolumebyellipse(lefthippoposition) + + #comment deviner automatiquement quel bout est antero et quel bout est postero... + mesh = aims.read(str(dileftHippo.fullPath())) + testhippocut = aims.AimsSurfaceTriangle() + testhippocut2 = aims.AimsSurfaceTriangle() + border = aims.AimsTimeSurface(2) + border2 = aims.AimsTimeSurface(2) + aims.SurfaceManip.cutMesh(mesh, [rotation[2,2], rotation[2,1], rotation[2,0], -numpy.inner(rotation[2,:],center)], testhippocut, border) + aims.SurfaceManip.cutMesh(mesh, [-rotation[2,2], -rotation[2,1], -rotation[2,0], numpy.inner(rotation[2,:],center)], testhippocut2, border2) + planmesh = aims.SurfaceManip.meshPlanarPolygon([rotation[2,2], rotation[2,1], rotation[2,0], -numpy.inner(rotation[2,:],center)], border) + planmesh2 = aims.SurfaceManip.meshPlanarPolygon([-rotation[2,2], -rotation[2,1], -rotation[2,0], numpy.inner(rotation[2,:],center)], border2) + + aims.SurfaceManip.meshMerge(testhippocut,planmesh) + aims.SurfaceManip.meshMerge(testhippocut2,planmesh2) + aims.write(testhippocut,'/tmp/testhippocut.gii') + aims.write(testhippocut2,'/tmp/testhippocut2.gii') + #ret = subprocess.call(['AimsMeshCut', '-i', str(dileftHippo.fullPath()), '-o', '/tmp/testhippocut.gii', '-a',str(rotation[2,2]),'-b',str(rotation[2,1]),'-c',str(rotation[2,0]),'-d',str(-numpy.inner(rotation[2,:],center))]) + #ret = subprocess.call(['AimsMeshCut', '-i', str(dileftHippo.fullPath()), '-o', '/tmp/testhippocut2.gii', '-a',str(-rotation[2,2]),'-b',str(-rotation[2,1]),'-c',str(-rotation[2,0]),'-d',str(numpy.inner(rotation[2,:],center))]) + + hippogii = aims.read('/tmp/testhippocut.gii') + hippovertex = numpy.array(hippogii.vertex().list()) + centerhippo = numpy.average(hippovertex,axis=0) + + hippogii2 = aims.read('/tmp/testhippocut2.gii') + hippovertex2 = numpy.array(hippogii2.vertex().list()) + centerhippo2 = numpy.average(hippovertex2,axis=0) + + coords1 = m.transform(centerhippo) + coords2 = m.transform(centerhippo2) + + if coords2[1] > coords1[1]: + #2 est l'antero; 1 est posterieur + if dilefthippoantero is None or dilefthippopostero is None: + print "mesh export : could not find valid path" + else: + cmd1 = ['mv', '/tmp/testhippocut2.gii', str(dilefthippoantero.fullPath())] + cmd2 = ['mv', '/tmp/testhippocut.gii', str(dilefthippopostero.fullPath())] + line1 = runCmd(cmd1) + line2 = runCmd(cmd2) + neuroHierarchy.databases.insertDiskItem(dilefthippoantero, update = True) + neuroHierarchy.databases.insertDiskItem(dilefthippopostero, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dilefthippoantero, allT1[idxT1pre[0]].attributes()['referential'] ) + self.transfoManager.setReferentialTo(dilefthippopostero, allT1[idxT1pre[0]].attributes()['referential'] ) + elif coords2[1] < coords1[1]: + #1 est l'antero; 2 est le posterieur + if dilefthippoantero is None or dilefthippopostero is None: + print "mesh export : could not find valid path" + else: + cmd1 = ['mv', '/tmp/testhippocut.gii', str(dilefthippoantero.fullPath())] + cmd2 = ['mv', '/tmp/testhippocut2.gii', str(dilefthippopostero.fullPath())] + line1 = runCmd(cmd1) + line2 = runCmd(cmd2) + neuroHierarchy.databases.insertDiskItem(dilefthippoantero, update = True) + neuroHierarchy.databases.insertDiskItem(dilefthippopostero, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dilefthippoantero, allT1[idxT1pre[0]].attributes()['referential'] ) + self.transfoManager.setReferentialTo(dilefthippopostero, allT1[idxT1pre[0]].attributes()['referential'] ) + + if dilefthippoantero is not None and dilefthippopostero is not None: + #we read it, estimate the number of vertex, and attribute the good value to the good number of vertex + #nb vertex of right antero + voxel_size_T1 = [allT1[idxT1pre[0]].attributes()['voxel_size'][0], allT1[idxT1pre[0]].attributes()['voxel_size'][1], allT1[idxT1pre[0]].attributes()['voxel_size'][2], 1.0] + + hippo_vol_antero=aims.Volume(*allT1[idxT1pre[0]].attributes()['volume_dimension'][:3],dtype='S16') + hippo_vol_postero=aims.Volume(*allT1[idxT1pre[0]].attributes()['volume_dimension'][:3],dtype='S16') + hippo_vol_full=aims.Volume(*allT1[idxT1pre[0]].attributes()['volume_dimension'][:3],dtype='S16') + hippo_vol_antero.header()['voxel_size']= voxel_size_T1 + hippo_vol_postero.header()['voxel_size']= voxel_size_T1 + hippo_vol_full.header()['voxel_size']= voxel_size_T1 + + wdilefthippoNII = WriteDiskItem('leftHippocampusNII', 'NIFTI-1 image' ) + dileftHippoNII = wdilefthippoNII.findValue(constraints) + + meshantero = aims.read(dilefthippoantero.fullName()) + meshpostero = aims.read(dilefthippopostero.fullName()) + aims.SurfaceManip.rasterizeMesh(meshantero,hippo_vol_antero,1) + aims.SurfaceManip.rasterizeMesh(meshpostero,hippo_vol_postero,1) + #fill the insides voxel + from scipy import ndimage + for zslices in range(hippo_vol_antero.arraydata().shape[1]): + hippo_vol_antero.arraydata()[0,zslices,:,:] = ndimage.morphology.binary_fill_holes(hippo_vol_antero.arraydata()[0,zslices,:,:]).astype(int) + + for zslices in range(hippo_vol_postero.arraydata().shape[1]): + hippo_vol_postero.arraydata()[0,zslices,:,:] = ndimage.morphology.binary_fill_holes(hippo_vol_postero.arraydata()[0,zslices,:,:]).astype(int) + + hippo_vol_antero *=1701 + hippo_vol_postero *= 1702 + hippo_vol_full = hippo_vol_antero + hippo_vol_postero + for z in xrange(hippo_vol_full.getSizeZ()): + for y in xrange(hippo_vol_full.getSizeY()): + for x in xrange(hippo_vol_full.getSizeX()): + if hippo_vol_full.value(x, y, z) >1702: + hippo_vol_full.setValue(1702, x, y, z) + + aims.write(hippo_vol_full,str(dileftHippoNII.fullPath())) + neuroHierarchy.databases.insertDiskItem(dileftHippoNII, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dileftHippoNII, allT1[idxT1pre[0]].attributes()['referential'] ) + + + print "generation of amygdala and hippocamp meshes done" + self.setStatus(u"generation of amygdala and hippocamp meshes done") + + + def runFreesurferReconAll(self): + + proto = str(self.ui.regProtocolCombo.currentText()) + subj = str(self.ui.regSubjectCombo.currentText()) + images = self.findAllImagesForSubject(proto, subj) + # Find all images, normalize the T1s, find the T1pre if there is one, read image headers, store their referentials and transformations in the DB + t1preImage = None + FlairpreImage = None + T2preImage = None + FreesurferMethod = 0 + for image in images: + patient = image.attributes()['subject'] + acq = image.attributes()['acquisition'] + # Store Scanner-based referential and referential files in the DB + if acq.startswith('T1'): + # If there is a T1pre, remember the image + if acq.find('T1pre') == 0: + t1preImage = image + + elif acq.startswith('FLAIR'): + if acq.find('FLAIRpre') == 0: + FlairpreImage = image + + elif acq.startswith('T2'): + if acq.find('T2pre') == 0: + T2preImage = image + + # No T1pre : nothing else to do + if t1preImage is None: + print('no T1pre image') + return + + context = brainvisa.processes.defaultContext() + context.write("recon-all from freesurfer") + + if t1preImage and FlairpreImage: + FreesurferMethod = 1 + elif t1preImage and T2preImage: + FreesurferMethod = 2 + elif t1preImage: + FreesurferMethod = 0 + + #prevenir que freesurfer demarre dans la bare de tache + #il faut rajouter le test si le sujet exist déjà dans freesurfer il faut d'abord le supprimer pour pouvoir le relancer. + + if FreesurferMethod == 0: + try: + launchFreesurferCommand(context, None, 'recon-all', '-all', '-subjid', subj ,'-i',str(t1preImage.fullPath())) + except: + launchFreesurferCommand(context, None, 'recon-all', '-all', '-subjid', subj) + elif FreesurferMethod == 1: + try: + launchFreesurferCommand(context, None, 'recon-all', '-all', '-subjid', subj ,'-i',str(t1preImage.fullPath()),'-FLAIRpial', '-FLAIR', str(FlairpreImage.fullPath())) + except: + shutil.rmtree(os.path.join(configuration.freesurfer._get_subjects_dir_path(),subj)) + launchFreesurferCommand(context, None, 'recon-all', '-all', '-subjid', subj ,'-i',str(t1preImage.fullPath()),'-FLAIRpial', '-FLAIR', str(FlairpreImage.fullPath())) + elif FreesurferMethod == 2: + try: + launchFreesurferCommand(context, None, 'recon-all', '-all', '-subjid', subj ,'-i',str(t1preImage.fullPath()),'-T2pial', '-T2',str(T2preImage.fullPath())) + except: + shutil.rmtree(os.path.join(configuration.freesurfer._get_subjects_dir_path(),subj)) + launchFreesurferCommand(context, None, 'recon-all', '-all', '-subjid', subj ,'-i',str(t1preImage.fullPath()),'-T2pial', '-T2',str(T2preImage.fullPath())) + + self.importFSoutput(subject=subj) + + def runMarsAtlasFreesurfer(self): + + print("not finished") + return + pdb.set_trace() + + def fitvolumebyellipse(self,volumeposition): + + #cut the hippocampus in two: + # from https://github.com/minillinim/ellipsoid/blob/master/ellipsoid.py + tolerance = 0.015 + if len(volumeposition)>16000: + volumeposition = [volumeposition[x] for x in range(len(volumeposition)) if x & 1 ==0] + + volumeposition=numpy.array(volumeposition) + (N, dd) = numpy.shape(volumeposition) + dd = float(dd) + + # Q will be our working array + Q = numpy.vstack([numpy.copy(volumeposition.T), numpy.ones(N)]) + QT = Q.T + + # initializations + err = 1.0 + tolerance + u = (1.0 / N) * numpy.ones(N) + + # Khachiyan Algorithm + while err > tolerance: + V = numpy.dot(Q, numpy.dot(numpy.diag(u), QT)) + M = numpy.diag(numpy.dot(QT , numpy.dot(numpy.linalg.inv(V), Q))) # M the diagonal vector of an NxN matrix + j = numpy.argmax(M) + maximum = M[j] + step_size = (maximum - dd - 1.0) / ((dd + 1.0) * (maximum - 1.0)) + new_u = (1.0 - step_size) * u + new_u[j] += step_size + err = numpy.linalg.norm(new_u - u) + u = new_u + + # center of the ellipse + center = numpy.dot(volumeposition.T, u) + + # the A matrix for the ellipse + AA = numpy.linalg.inv(numpy.dot(volumeposition.T, numpy.dot(numpy.diag(u), volumeposition)) - numpy.array([[a * b for b in center] for a in center])) / dd + + # Get the values we'd like to return + UU, ss, rotation = numpy.linalg.svd(AA) + radii = 1.0/numpy.sqrt(ss) + + return UU, ss, rotation, center + + def setNormalizedToT1pre(self, image, registeredPath): + + ret = subprocess.call(['AimsFileConvert', '-i', str(registeredPath), '-o', str(image.fileName()), '-t', 'S16']) + if ret < 0: + print "Importation Error of the SPM resampled image : "+repr(registeredPath) + QtGui.QMessageBox.warning(self, "Error", u"The image has not been resampled by SPM !") + return + # TODO # Should destroy existing referentials for this image + # The referential of this image is the same as the T1 pre + self.transfoManager.setReferentialTo(image, registration.talairachMNIReferentialId) #replace self.getT1preNativeRef(image.attributes()['center'], image.attributes()['subject']) by talairachMNIReferentialId + #os.remove(registeredPath) + + + def taskfinished(self, message, threadObj=None): + """ When a task (thread) is finished, display the message and launch the waiting callbacks""" + self.setStatus(u"Task done : "+message) #+' : '+repr(threadObj) + if threadObj is None: + return + # Looking for callback functions waiting + #print "****** WAITING FOR THREADS *******\n"+repr(self.waitingForThreads) # DEBUG + toDelete = [] # Store the dictionary keys to delete (cannot be done while iterating on it) + for callback in self.waitingForThreads: + for thr in self.waitingForThreads[callback]: # All threads this callback is waiting for + if thr not in self.threads: # This one does not exist, it was probably deleted before the callback was set, so just remove it from the list + self.waitingForThreads[callback].remove(thr) + if threadObj in self.waitingForThreads[callback]: # This thread was in the list + self.waitingForThreads[callback].remove(threadObj) # So remove it ! + if self.waitingForThreads[callback] == []: # If there is no thread left + callback() # Call the function ! + toDelete.append(callback) + for tD in toDelete: + del self.waitingForThreads[tD] + + idx = self.threads.remove(threadObj) # Now remove the thread + + + def downloadPacs(self): + """ Import the selected images from the pacs to the Nifti output directory """ + pass + # Preference tab : set the SPM T1 template path + def setSpmTemplatePath(self, path=None): + if path is None: + path = QtGui.QFileDialog.getExistingDirectory(self, u"Select SPM path") + if path is not None: + self.ui.prefSpmTemplateEdit.setText(path) + + def setANTsPath(self, path=None): + if path is None: + path = QtGui.QFileDialog.getExistingDirectory(self, u"Select ANTs path") + if path is not None: + self.ui.prefANTsEdit.setText(path) + + def setFreesurferPath(self, path=None): + if path is None: + path = QtGui.QFileDialog.getExistingDirectory(self, u"Select FREESURFER path") + if path is not None: + self.ui.prefFreesurferEdit.setText(path) + + def setNoDBFilePath(self, path=None): + if path is None: + path = QtGui.QFileDialog.getExistingDirectory(self, u"Select path for file export not include in database") + if path is not None: + self.ui.prefNoDBFileLocationEdit.setText(path) + + def setSpmStandalonePath(self, path=None): + if path is None: + path = QtGui.QFileDialog.getExistingDirectory(self, u"Select SpmStandalone path") + if path is not None: + self.ui.prefSpmStandaloneEdit.setText(path) + + def setPrefCoregister(self,key): + + if key == 'ANTS': + if self.ui.prefANTScheckbox.isChecked(): + self.ui.prefSPMcheckbox.setCheckState(False) + self.ui.prefAimscheckbox.setCheckState(False) + + elif key == 'SPM': + if self.ui.prefSPMcheckbox.isChecked(): + self.ui.prefANTScheckbox.setCheckState(False) + self.ui.prefAimscheckbox.setCheckState(False) + + elif key == 'Aims': + if self.ui.prefAimscheckbox.isChecked(): + self.ui.prefANTScheckbox.setCheckState(False) + self.ui.prefSPMcheckbox.setCheckState(False) + + + def switchProjectButton(self): + projects= [self.ui.radioButtonProject.isChecked(),self.ui.radioButtonProject_2.isChecked(),self.ui.radioButtonProject_3.isChecked(),self.ui.radioButtonProject_4.isChecked()] + project_selected = [x for x in range(len(projects)) if projects[x]==True] + + self.prefs['projectSelected'] = project_selected + + ################################## Patient Information Tab ##################################### + def selectPatSubject(self, subj): + pass + + + ################################## SEEG Import Tab ##################################### + def selectSeegSubject(self, subj): + # Fill this from the database ReadDiskItems : {"MANIP_20-09-2012-2":ReadDiskItem, ...} + self.seegManips = {} + # Update the list of manips + self.ui.seegManipsBaseCombo.clear() + self.ui.seegManipsBaseCombo.addItems(self.seegManips.keys()) + + def manipSelected(self, manip): + self.ui.seegAvailableProcessingCombo.clear() + methods = seegprocessing.getProcessingMethods(seegprocessing.getManipNameFromDirName(str(manip))) + self.ui.seegAvailableProcessingCombo.addItems([method[0] + ' - '+method[1] for method in methods]) + + def chooseSeeg(self): + """Choose a SEEG file to import""" + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open SEEG File", "", "TRC SEEG file (*.trc)")) + print "Path of the TRC/EEG %s"%path + if not path: + return + self.ui.seegFileLabel.setText(path) + + def seegImport(self, subj = None, proto = None): + """Import a TRC file in the database, anonymize it and convert using ELAN""" + #QtGui.QMessageBox.warning(self, u'Erreur', u"L'importation de fichier SEEG n'est pas encore implémenté !") + path = str(self.ui.seegFileLabel.text()) + if not os.path.isfile(path): + print path + " is not a valid file !" + return + date = self.ui.seegAcqDate.date() + manip = str(self.ui.seegManipName.currentText()) + submanip = str(self.ui.seegSubmanipName.currentText()) + acq = str(self.ui.seegAcqCombo.currentText()) + + if proto is None: + proto = str(self.ui.seegProtocolCombo.currentText()) + if subj is None: + subj = str(self.ui.seegSubjectCombo.currentText()) + # Find the path in the DB + wdi = WriteDiskItem('Raw SEEG recording', 'EEG TRC format' ) + constraints = { 'center': proto, 'experiment': str(manip), 'subject' :subj } + + if len(submanip) > 0: + constraints['subexperiment'] = submanip + if len(acq) > 0: + constraints['expId'] = acq + di = wdi.findValue(constraints) + if di is None: + print "TRC import : could not find valid path" + + # Copy the file + #generate path + + #first I have to anonymize. + + if not os.path.exists(os.path.dirname(di.fullPath())): + try: + os.makedirs(os.path.dirname(di.fullPath())) + except: + print "can't generate folder" + + shutil.copyfile(path, di.fullPath()) + + # Anonymize in-place IL FAUDRAIT REDEMANDER LE NOM ET LE PRENOM DU PATIENT ? + self.anonymizeTRC_Sys98_t4(di.fullPath(),firstname=subj, lastname=subj) + + #anonymizeTRC.anonymizeTRC(di.fullPath(), lastname = subj) #firstname = str(self.ui.firstnameToRemove.text()), lastname = str(self.ui.lastnameToRemove.text()) + neuroHierarchy.databases.insertDiskItem(di, update=True ) + + def checkbox_comor(self): + if self.patientInfo['comoraucune'].isChecked(): + self.patientInfo['comorpsy'].setEnabled(False) + self.patientInfo['comorautre'].setEnabled(False) + self.patientInfo['comorneuro'].setEnabled(False) + else: + self.patientInfo['comorpsy'].setEnabled(True) + self.patientInfo['comorautre'].setEnabled(True) + self.patientInfo['comorneuro'].setEnabled(True) + + def update_patientAge(self): + patAge = self.patientInfo['patientBirthday'].date().daysTo( self.patientInfo['currentDate'].date())/365 + self.patientInfo['patientAge'].setText(str(patAge)) + + def ValidatePatInfo(self): + + patListToCheck = ['previousHistory','previousFamilyHistory','causaleDisease','mriLesion','comorneuro','comorpsy','comorautre'] + patpatListToCheck = {'Epilepsy':['Aura','TraitementTried','TraitementNow']} + + #read choice2 list from intersubject database + write_filters = { 'center': self.currentProtocol, 'subject' : self.currentSubject } + #pdb.set_trace() + wdi_global = ReadDiskItem('PatientInfoTemplate','Patient Template format') + di_global = list(wdi_global.findValues({}, None, False)) + + if len(di_global): + if os.path.isfile(str(di_global[0])): + print "read previous patienttemplate json" + from codecs import open as opencodecs + fin = opencodecs(str(di_global[0]),'r','latin1') + info_dicti = json.loads(fin.read().decode('latin1')) + fin.close() + + previous_lists_not_path = info_dicti['notPathoSpecific'] + previous_lists_path_full = info_dicti['PathoSpecific'] + previous_lists_path_protocol = info_dicti['PathoSpecific'][self.currentProtocol] + + else: + previous_lists_not_path = {} + previous_lists_path_full = {} + previous_lists_path_protocol = {} + + #register non pathology specific patient Info + PatInfo = {} + for kk, vv in self.patientInfo.iteritems(): + if isinstance(vv,QtGui.QDateEdit): + PatInfo.update({kk:unicode(vv.date().toPyDate())}) + if vv.date() == self.defaultAcqDate: + QtGui.QMessageBox.warning(self, "Error",u"The acquisition date is not valid ! " + kk) + return + elif isinstance(vv,QtGui.QComboBox): + #faire deux conditions lorsque c'est une liste checkable et lorsque non + if vv.model().item(1).isCheckable(): + item_checked = [unicode(vv.itemText(x)) for x in range(1,vv.count()) if vv.model().item(x).checkState()] + if len(item_checked) > 1: + if 'Inconnu' in item_checked or 'Aucun' in item_checked or 'Aucune' in item_checked: + QtGui.QMessageBox.warning(self, "Error",u"You can't have 'Inconnu' or 'Aucune' selected whith another choice, it doesn't make sens" + kk) + return + #c est une combo box editable du coup il faut verifier si il faut updater la liste des choix possibles + + else: + item_checked = unicode(vv.currentText()) + PatInfo.update({kk:item_checked}) + elif isinstance(vv,QtGui.QDialogButtonBox): + item_selected = [unicode(vv.children()[i].text()) for i in range(1,len(vv.children())) if vv.children()[i].isChecked()] + PatInfo.update({kk:item_selected}) + elif isinstance(vv,QtGui.QLineEdit): + PatInfo.update({kk:unicode(vv.text())}) + elif isinstance(vv,QtGui.QCheckBox): + PatInfo.update({kk:vv.isChecked()}) + else: + print "qtgui format not recognized" + #pdb.set_trace() + + patPatInfo = {} + for kk, vv in self.pathologypatientInfo.iteritems(): + if isinstance(vv,QtGui.QDateEdit): + patPatInfo.update({kk:unicode(vv.date().toPyDate())}) + if vv.date() == self.defaultAcqDate: + QtGui.QMessageBox.warning(self, "Error",u"The acquisition date is not valid ! " + kk) + return + elif isinstance(vv,QtGui.QComboBox): + #faire deux conditions lorsque c'est une liste checkable et lorsque non + if vv.model().item(1).isCheckable(): + item_checked = [unicode(vv.itemText(x)) for x in range(1,vv.count()) if vv.model().item(x).checkState()] + if len(item_checked) > 1: + if 'Inconnu' in item_checked or 'Aucun' in item_checked or 'Aucune' in item_checked: + QtGui.QMessageBox.warning(self, "Error",u"You can't have 'Inconnu' or 'Aucune' selected whith another choice, it doesn't make sens"+ kk) + return + else: + item_checked = unicode(vv.currentText()) + patPatInfo.update({kk:item_checked}) + elif isinstance(vv,QtGui.QDialogButtonBox): + item_selected = [unicode(vv.children()[i].text()) for i in range(1,len(vv.children())) if vv.children()[i].isChecked()] + patPatInfo.update({kk:item_selected}) + elif isinstance(vv,QtGui.QLineEdit): + patPatInfo.update({kk:unicode(vv.text())}) + elif isinstance(vv,QtGui.QCheckBox): + patPatInfo.update({kk:vv.isChecked()}) + else: + print "qtgui format not recognized" + #pdb.set_trace() + + + wdi = WriteDiskItem('SubjectInfo','Subject Information format') + di = wdi.findValue(write_filters) + if di is None: + print('Can t generate files') + return + + #pdb.set_trace() + full_dictio = {'notPathoSpecific':PatInfo,'PathoSpecific':patPatInfo} + fout = open(di.fullPath(),'w') + fout.write(json.dumps(full_dictio, ensure_ascii=False)) + #fout.write(json.dumps({'PathoSpecific':patPatInfo})) + fout.close() + + neuroHierarchy.databases.insertDiskItem(di, update=True ) + + #update patientinfo list si une nouvelle entree a ete ajoutée dans les choices list + wdi_global = WriteDiskItem('PatientInfoTemplate','Patient Template format') + di_global = wdi_global.findValue(write_filters) + + for ii in range(len(patListToCheck)): + if len(PatInfo[patListToCheck[ii]])>0: + previous_lists_not_path.update({patListToCheck[ii]:PatInfo[patListToCheck[ii]]}) + + for jj in range(len(patpatListToCheck[self.currentProtocol])): + if len(patPatInfo[patpatListToCheck[self.currentProtocol][jj]])>0: + previous_lists_path_protocol.update({patpatListToCheck[self.currentProtocol][jj]:patPatInfo[patpatListToCheck[self.currentProtocol][jj]]}) + + previous_lists_path_full.update({self.currentProtocol:previous_lists_path_protocol}) + full_dictio_inter = {'notPathoSpecific':previous_lists_not_path,'PathoSpecific':previous_lists_path_full} + + fout = open(di_global.fullPath(),'w') + fout.write(json.dumps(full_dictio_inter,ensure_ascii=False)) + fout.close() + neuroHierarchy.databases.insertDiskItem(di_global, update=True ) + + + def enable_disable_gadooption(self): + + if str(self.ui.niftiSeqType.currentText()) == 'T1': + self.ui.radioButtonGado.setEnabled(True) + self.ui.radioButtonNoGado.setEnabled(True) + else: + self.ui.radioButtonGado.setEnabled(False) + self.ui.radioButtonNoGado.setEnabled(False) + + + + def anonymizeTRC_Sys98_t4(filepath, firstname="No", lastname="Name", nowrite=False, overwriteMontage=True, overwriteUndocumentedElectrode = True): # Anonymize Micromed's System 98 type 4 TRC files + """ Anonymize Micromed's System 98 type 4 TRC files """ + fo=open(filepath, "r+b") # Open read-write binary mode + # should check for a TRC header ! + fo.seek(2) + headerTitle = fo.read(26) + fo.seek(175) + headerType = fo.read(1) + trcVersion = struct.unpack('B',headerType)[0] + if headerTitle != "MICROMED Brain-Quick file" or (trcVersion != 4 and trcVersion != 3): + print "Not a MICROMED System 98 Type 3/4 TRC file -> ignoring" + fo.close() + return False + fo.seek(64) # go to patient data offset in header + # get a 22-char string, padding with spaces, convert to integers and pack as 22 unsigned chars in little endian + if nowrite: + fo.close() + return True + fo.write(struct.pack('<22B',*[ord(a) for a in lastname[:22].ljust(22,' ')])) + # Same with 20 chars + fo.write(struct.pack('<20B',*[ord(a) for a in firstname[:20].ljust(20,' ')])) + # Same with date (3 unsigned chars, for example [10, 05, 72] for october 5th 1972 + fo.seek(107) + fo.write(struct.pack(' 128* 4-bytes values (the sample where themontage was changed when viewing) + # We can skip that, then MAX_HISTORY = 128 "specific montage" structures which are identical to the montages above. + # Description string starts at offset 264 of each montage structure and is 64 bytes long,, just like above. + for i in range(30): + newMontageName = "Montage History "+str(i) + fo.seek(historyOffs + 128*4 + sizeMontage*i+264) + desc = fo.read(64) + # To print description string : desc = f.read(64); print desc[:desc.find('\x00')] + if "".join(["\x00" for j in range(64)]) != desc: + fo.seek(historyOffs + 128*4 + sizeMontage*i+264) + fo.write(struct.pack('<64B',*[ord(a) for a in newMontageName.ljust(64,'\x00')])) + + # undocumented string in place of the last electrode in name in HISTORY : find history offset, + fo.seek(192) + if fo.read(8) != 'LABCOD ': + raise Exception ("Incorrect LABCOD header") + elecOffs = struct.unpack('I', fo.read(4))[0] + # There should be 640 electrode structures of 128 bytes. But the last one is not an electrode structure. It seems to be a 32 bits integer and a 64 bytes string that contains a montage name... + if overwriteUndocumentedElectrode: + fo.seek(elecOffs + 639*128 + 4) + fo.write(struct.pack('<64B',*[ord(a) for a in "undocumented montage".ljust(64,'\x00')])) + except: + print "Could not overwrite Montage name" + + fo.close() + return True + + + +if __name__ == "__main__": + print "!!!!!!!!please run ImageImport.py !!!!!!!!!" diff --git a/ImageImportWindow.ui b/ImageImportWindow.ui new file mode 100644 index 0000000..9076a27 --- /dev/null +++ b/ImageImportWindow.ui @@ -0,0 +1,2222 @@ + + + Dialog + + + + 0 + 0 + 809 + 736 + + + + Importation d'images pour BrainVisa + + + + + + + 0 + 0 + + + + + + + + + + + Qt::Horizontal + + + + true + + + + 0 + 0 + + + + + false + + + + 4 + + + + BrainVisa + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + Images existing in the BrainVISA database + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + Protocol + + + + + + + + + + Subjet + + + + + + + + + + + + + + + Delete selected image + + + + + + + Delete selected subject + + + + + + + + Add Patient + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + Site (Grenoble, Lyon,...) + + + + + + + Patient entrance in the service + + + + + + + Patient Lastname + + + + + + + Patient Firstname + + + + + + + + + + + + + + 0 + 0 + + + + true + + + + Gre + + + + + + + + Qt::Horizontal + + + QSizePolicy::MinimumExpanding + + + + 40 + 20 + + + + + + + + + + + + 1900 + + + 10000 + + + 2013 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 139 + + + + + + + + + + Protocol + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Name in the Database + + + + + + + + 0 + 0 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 172 + + + + + + + + Add subject (in the local Database) + + + false + + + + + + + Add subject to distant database (F-Tract ou Neuropsynov database) + + + + + frame + subjectAddSubjectButton + verticalSpacer_4 + verticalSpacer_5 + subjectAddProjectDatabase + + + + Infos Patient + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + Protocol + + + + + + + + + + Subjet + + + + + + + + + + + + + 0 + 0 + + + + Information générale: + + + + + + + Information spécifique pathologie: + + + + + + + Validate Patient Information + + + + + + + + Importation NIFTI + + + + + + + 10 + 75 + true + + + + Import a NIFTI image or a MGZ image + + + + + + + Choose a file + + + + + + + Import Freesurfer outputs + + + + + + + + 0 + 0 + + + + + + + + + + + + + Protocol + + + + + + + + + + + + + + Patient + + + + + + + + + + + + + + Acquisition Date + + + + + + + + 1790 + 9 + 14 + + + + dd/MM/yyyy + + + + 1950 + 1 + 1 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + T1 + + + + + T2 + + + + + CT + + + + + PET + + + + + fMRI + + + + + Statistics + + + + + FLAIR + + + + + FGATIR + + + + + FreesurferAtlas + + + + + HippoFreesurferAtlas + + + + + DTI - volume + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + pre + + + + + post + + + + + postOp + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + NoGado + + + true + + + + + + + WithGado + + + + + + + + + + + Cliquer sur le centre du cerveau dans l'image puis cliquer sur ce bouton + + + Position Brain Center + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 30 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Import in BrainVisa database + + + + + + + Qt::Vertical + + + + 20 + 366 + + + + + + + + + Coregistration and Normalization + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + Protocol + + + + + + + + + + Subjet + + + + + + + + + + + + + + + + + + Resample images (original images will be lost) + + + + + + + true + + + Coregister subject images and normalize the T1 + + + + + + + Run only Segmentation and Hip Hop + + + + + + + Run Freesurfer Recon-All (can take up to 24 hours) + + + + + + + Run Hip Hop on Freesurfer Mesh + + + + + + + + + + + Cliquez sur la commissure antérieure, puis sur ce bouton + + + AC + + + + + + + Cliquez sur un point interhémisphérique au-dessus de CA-CP, puis sur ce bouton + + + IH + + + + + + + Cliquez sur la commissure postérieure, puis sur ce bouton + + + PC + + + + + + + Cliquez dans l'hémisphère gauche (droite de l'image si l'importation a bien fonctionné), puis sur ce bouton + + + LH + + + + + + + + + + + true + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Si AC, PC, IH et LH ont été entrés, lance la segmentation du cerveau + + + Validate + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + false + + + Choisir cette image pour la normalisation vers le template MNI + + + + + + + + Preferences... + + + + + + + + + + + ... + + + + + + + + + + Path spm12 standalone + + + + + + + + + + ... + + + + + + + Nifti folder: + + + + + + + true + + + + + + + ... + + + + + + + ... + + + + + + + ANTs + + + true + + + + + + + Path spm12 + + + + + + + spm + + + + + + + Coregister Method + + + + + + + + + + Path ANTs + + + + + + + true + + + + + + + Dicom folder: + + + + + + + ... + + + + + + + Project + + + + + + + F-Tract + + + + + + + NeuroPsynov + + + + + + + Classic + + + + + + + Other + + + + + + + Aims + + + + + + + + + + Path FreeSurfer + + + + + + + ... + + + + + + + Not databased file location + + + + + + + ... + + + + + + + + + + + + Save Preferences + + + + + + + Qt::Vertical + + + + 20 + 516 + + + + + + + + + Importation SEEG + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + Protocole + + + + + + + + + + Sujet + + + + + + + + + + + + Choisir un fichier SEEG (TRC ou EEG)... + + + + + + + + 0 + 0 + + + + + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + + Date de manip + + + + + + + + 1790 + 9 + 14 + + + + dd/MM/yyyy + + + + 1950 + 1 + 1 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Nom de manip : + + + + + + + true + + + + LEC1 + + + + + VISU + + + + + + + + Acquisition (n°, "postcrise"...) + + + + + + + Nom de sous-manip + + + + + + + true + + + + + + + true + + + + + + + + + Importer dans BrainVisa + + + + + + + Qt::Vertical + + + + 20 + 180 + + + + + + + + + + Manips déjà importées + + + + + + + + + + + + Traitements disponibles: + + + + + + + + + + Lancer le traitement + + + + + + + Lancer tous les traitements pour la manip sélectionnée + + + + + + + Lancer tous les traitements pour toutes les manips + + + + + + + + Implantation + + + + + + + 10 + 75 + true + + + + Importation des scans du schéma d'implantation + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + Protocole + + + + + + + + + + Sujet + + + + + + + + + + + + + + + 75 + true + + + + Image Coronale : + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Absente + + + + + + + Ouvrir une image... + + + + + + + Importer + + + + + + + + 75 + true + + + + Image sagittale : + + + + + + + + 0 + 0 + + + + Absente + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ouvrir une image... + + + + + + + Importer + + + + + + + + 75 + true + + + + Rapport Powerpoint + + + + + + + + 75 + true + + + + Schéma d'implantation sans le nom des électrodes (issu des médecins) + + + Schéma PDF + + + + + + + + 0 + 0 + + + + Absent + + + + + + + + 0 + 0 + + + + Absent + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ouvrir un ppt... + + + + + + + Ouvrir un PDF... + + + + + + + Importer + + + + + + + Importer + + + + + + + Absent + + + + + + + + 75 + true + + + + Schéma d'implantation avec le nom des électrodes + + + Schéma Impl. PDF + + + + + + + + 75 + true + + + + Liste Electrodes PDF + + + + + + + Absent + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ouvrir un PDF... + + + + + + + Importer + + + + + + + Ouvrir un PDF... + + + + + + + Importer + + + + + + + + + Qt::Vertical + + + + 20 + 403 + + + + + + + + + Importation dossier DICOM + + + + + + + 10 + 75 + true + + + + Importation d'images depuis un dossier DICOM + + + + + + + Choisir un dossier... + + + + + + + Sélection du Patient + + + + + + + QAbstractItemView::MultiSelection + + + + + + + Sélection de l'examen (study) + + + + + + + QAbstractItemView::MultiSelection + + + + + + + Sélection de la séquence (serie) + + + + + + + QAbstractItemView::MultiSelection + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + T1 + + + + + T2 + + + + + CT-scanner + + + + + TEP + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + pre + + + + + post + + + + + postOp + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 1. Importer et convertir en NIFTI + + + + + + + 2. Importer dans BrainVisa + + + + + + + + Importation PACS + + + + + + + 10 + 75 + true + + + + Importation d'images depuis un serveur d'image PACS + + + + + + + + + Serveur + + + + + + + + + + + + + + Port + + + + + + + 65535 + + + 5000 + + + + + + + + + + + AETitle + + + + + + + + + + + + + + Nom du patient + + + + + + + + + + + + Rechercher + + + + + + + Sélection du Patient + + + + + + + QAbstractItemView::MultiSelection + + + + + + + Sélection de l'examen (study) + + + + + + + QAbstractItemView::MultiSelection + + + + + + + Sélection de la séquence (serie) + + + + + + + QAbstractItemView::MultiSelection + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + T1 + + + + + T2 + + + + + CT-scanner + + + + + TEP + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + pre + + + + + post + + + + + postOp + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 1. Importer et convertir en NIFTI + + + + + + + 2. Importer dans BrainVisa + + + + + + + + + + 0 + 0 + + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + + + + + + diff --git a/ImportTheoreticalImplentation.py b/ImportTheoreticalImplentation.py new file mode 100644 index 0000000..b033ea4 --- /dev/null +++ b/ImportTheoreticalImplentation.py @@ -0,0 +1,87 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import sys, os, pickle,numpy, re, string, json, csv, pdb + + +from PyQt4 import QtGui, QtCore, uic, Qt + + + +#self.connect(self.ImportTheoriticalImplantation,QtCore.SIGNAL('clicked()'),self.importRosaImplantation) + + +def importRosaImplantation(locate_env): + fichierRosa = QtGui.QFileDialog.getOpenFileName(locate_env, "Select a file containing electrode coordinates: ", "", "(*.ros )") + electrodes = ecritureCSVetJSON(fichierRosa) + + return electrodes + + +def ecritureCSVetJSON(fichier): + target=[] + nomElec=[] + entry=[] + electrodes={} + kv="" + i=0 + j=0 + + a=open(fichier,"rU") + fjson=open("electrodes.json","w") + + line=a.readlines() + pdb.set_trace() + line0=[nb for nb in line if len(nb)>50] + line1=[nb for nb in line0 if (re.findall("([a-z])",nb[0].lower())!=None) and (nb[2]==" " or nb[1]==" ")] + + + while j c #F05C17", +", c #F05C16", +"' c #F48D59", +") c #EE5004", +"! c #EE4900", +"~ c #F59565", +"{ c #EF530B", +"] c #EE4800", +"^ c #F9BFA2", +"/ c #EE4A00", +"( c #F9C2A6", +"_ c #EE4C00", +": c #EE4B00", +"< c #F8B796", +"[ c #F4844C", +"} c #F05910", +"| c #FDE9DE", +"1 c #FBD5C0", +"2 c #F69B6F", +"3 c #FDEFE6", +"4 c #FCDAC9", +"5 c #EF5003", +"6 c #F4844D", +"7 c #FCE4D6", +"8 c #FDE6D9", +"9 c #FDEDE4", +"0 c #FBCFB8", +"a c #FEF6F2", +"b c #EE4500", +"c c #EF5209", +"d c #F6A279", +"e c #FEEEE5", +"f c #EF5A13", +"g c #F8AC86", +"h c #F4854E", +"i c #FEF9F6", +"j c #F05E19", +"k c #EF5207", +"l c #FEFAF6", +"m c #F05F18", +"n c #EF4E02", +"o c #FBD1BB", +"p c #FFFEFD", +"q c #FBD9C7", +"r c #FCDBC7", +"s c #FBBE99", +"t c #FEF2EA", +"u c #FEFCF9", +"v c #F8B999", +"w c #F8B695", +"x c #F3793E", +"y c #FBD6C4", +"z c #F7A880", +"A c #EF5811", +"B c #F0601C", +"C c #F26C2D", +"D c #EE4F04", +"E c #F4834C", +"F c #F8A673", +"G c #FAB184", +"H c #FBC29E", +"I c #F26F2E", +"J c #EE4F05", +"K c #FCDFD0", +"L c #EE4D01", +"M c #F7A378", +"N c #FACBB5", +"O c #F06320", +"P c #EF5208", +"Q c #FCD4BC", +"R c #FAB78E", +"S c #FEEDE2", +"T c #F48149", +"U c #F58D5B", +"V c #F9BFA3", +"W c #F5905F", +"X c #F8B797", +"Y c #FEF1EA", +"Z c #FCDCCB", +"` c #F26E2F", +" . c #F8AD87", +".. c #FEFFFF", +"+. c #FCE4D8", +"@. c #FEF4EF", +"#. c #FCE2D4", +"$. c #F69B6E", +"%. c #EF5108", +"&. c #F05D19", +"*. c #EF540B", +"=. c #F48954", +"-. c #F9C1A4", +";. c #F8B28F", +">. c #FEF6F0", +",. c #FEFAF8", +"'. c #FBBD95", +"). c #FCBD95", +"!. c #FEF8F3", +"~. c #FCDBC9", +"{. c #FDEADF", +"]. c #F8A67E", +"^. c #EE4E02", +"/. c #EF530A", +"(. c #F05D16", +"_. c #FEF7F1", +":. c #EF5107", +"<. c #F06422", +"[. c #F16523", +"}. c #FFFDFA", +"|. c #F16E2E", +"1. c #EF550D", +"2. c #EF5913", +"3. c #EE4E01", +"4. c #FDE7DB", +"5. c #F5996B", +"6. c #F59463", +"7. c #FEECE0", +"8. c #FBB991", +"9. c #FCBC95", +"0. c #FEE8DA", +"a. c #F8AF8A", +"b. c #EE4C01", +"c. c #FBD2BC", +"d. c #FDEBE1", +"e. c #F16422", +"f. c #F05D18", +"g. c #F4824A", +"h. c #EF540A", +"i. c #F06321", +"j. c #EE4F03", +"k. c #FBCFBA", +"l. c #F69F73", +"m. c #F59161", +"n. c #FDE4D3", +"o. c #FDE2D0", +"p. c #F37A3F", +"q. c #FACEB7", +"r. c #EF560E", +"s. c #F0611E", +"t. c #F26D2B", +"u. c #F8B18D", +"v. c #EE4D02", +"w. c #F05B15", +"x. c #EE5005", +"y. c #F79E72", +"z. c #FAC7AF", +"A. c #F05F1B", +"B. c #F37C42", +"C. c #F7A379", +"D. c #F69566", +"E. c #FEF4ED", +"F. c #F59A6D", +"G. c #F59465", +"H. c #FDE6DA", +"I. c #F0621F", +"J. c #F6A57B", +"K. c #F7A77F", +"L. c #F05911", +"M. c #F05A14", +"N. c #FDEBE0", +"O. c #F16A28", +"P. c #F3773C", +"Q. c #FFFCFA", +"R. c #F7A57D", +"S. c #F6A076", +"T. c #FDEBDF", +"U. c #FDEEE5", +"V. c #FDE6D6", +"W. c #FDDECB", +"X. c #FFFBF8", +"Y. c #EF5309", +"Z. c #F05D17", +"`. c #FDE5D9", +" + c #F27437", +".+ c #F0621C", +"++ c #FCE1D1", +"@+ c #FCE5D7", +"#+ c #FFFDFB", +"$+ c #F69E72", +"%+ c #F58E5C", +"&+ c #FBD9C6", +"*+ c #F05B16", +"=+ c #F2793D", +"-+ c #FEFCFA", +";+ c #F8AE80", +">+ c #F9A97A", +",+ c #F9AA7B", +"'+ c #FAB891", +")+ c #FDDFCC", +"!+ c #FAB385", +"~+ c #FAB58C", +"{+ c #FCCAAA", +"]+ c #FFFFFE", +"^+ c #FEF4EE", +"/+ c #F8B18E", +"(+ c #EF5912", +"_+ c #F59363", +":+ c #F16926", +"<+ c #F27538", +"[+ c #F0560E", +"}+ c #FBC5A4", +"|+ c #F8AC7D", +"1+ c #FAB287", +"2+ c #FAB288", +"3+ c #F9AE81", +"4+ c #FCD8C0", +"5+ c #FAB68A", +"6+ c #FCC19D", +"7+ c #FCCBAC", +"8+ c #FCC8A6", +"9+ c #FDE4D4", +"0+ c #FEFAF7", +"a+ c #F9BEA1", +"b+ c #EF5710", +"c+ c #F6986B", +"d+ c #F16927", +"e+ c #EF5105", +"f+ c #F9B694", +"g+ c #F6986A", +"h+ c #EF560F", +"i+ c #F7AD88", +"j+ c #F05F1A", +"k+ c #F16C2C", +"l+ c #FABB95", +"m+ c #FAB289", +"n+ c #F9B185", +"o+ c #FBCEB1", +"p+ c #FCCDAE", +"q+ c #FEF7F2", +"r+ c #FCC9A8", +"s+ c #FCC9A7", +"t+ c #FDE1CE", +"u+ c #F16825", +"v+ c #EE4E03", +"w+ c #F48853", +"x+ c #F05F19", +"y+ c #EF570F", +"z+ c #F2773C", +"A+ c #F06421", +"B+ c #FDE5D7", +"C+ c #F2773A", +"D+ c #F48E5A", +"E+ c #F37639", +"F+ c #F15F18", +"G+ c #FBD7C4", +"H+ c #EF550C", +"I+ c #EF5006", +"J+ c #F05E18", +"K+ c #FCE1D0", +"L+ c #F7A572", +"M+ c #F9AF83", +"N+ c #F9B084", +"O+ c #F9A978", +"P+ c #FEF1E9", +"Q+ c #FEFBF9", +"R+ c #FDEEE3", +"S+ c #F9BA9A", +"T+ c #F8B492", +"U+ c #FEFBF8", +"V+ c #FCDAC8", +"W+ c #F7A780", +"X+ c #EF5810", +"Y+ c #F8B491", +"Z+ c #F7A37A", +"`+ c #EF5106", +" @ c #F06220", +".@ c #FFFAF5", +"+@ c #FDE3D2", +"@@ c #FABD98", +"#@ c #FAC19E", +"$@ c #FEEDE4", +"%@ c #FBDBCA", +"&@ c #F8B08C", +"*@ c #F37E44", +"=@ c #F26D2C", +"-@ c #F05207", +";@ c #FFDECD", +">@ c #FF9C63", +",@ c #FF691D", +"'@ c #FF6A1E", +")@ c #FFAA77", +"!@ c #FFD7BD", +"~@ c #FF5E12", +"{@ c #FC6924", +"]@ c #F96824", +"^@ c #F56623", +"/@ c #EF5005", +"(@ c #FBDCCA", +"_@ c #FFFCFB", +":@ c #F9C2A7", +"<@ c #FCDDCD", +"[@ c #FFF1E7", +"}@ c #FD641B", +"|@ c #FF6920", +"1@ c #FFA879", +"2@ c #E6F3F9", +"3@ c #B5B4B4", +"4@ c #8B8A89", +"5@ c #6D6C6C", +"6@ c #484645", +"7@ c #323030", +"8@ c #28292A", +"9@ c #111B21", +"0@ c #080C0F", +"a@ c #000609", +"b@ c #00090E", +"c@ c #111010", +"d@ c #1B1A1A", +"e@ c #2D2D2C", +"f@ c #3B3C3D", +"g@ c #5B473D", +"h@ c #6F290A", +"i@ c #984016", +"j@ c #B94D1C", +"k@ c #E45D1F", +"l@ c #FF6E24", +"m@ c #FEE4D7", +"n@ c #FCD2B8", +"o@ c #FAB486", +"p@ c #FAB48A", +"q@ c #FCC5A2", +"r@ c #FDCEB0", +"s@ c #FEE7D8", +"t@ c #FEFFFE", +"u@ c #EF4F03", +"v@ c #F58C59", +"w@ c #FFFEFC", +"x@ c #FACDB6", +"y@ c #E2E5E8", +"z@ c #979C9E", +"A@ c #4E2E1F", +"B@ c #0F0805", +"C@ c #000000", +"D@ c #1A1919", +"E@ c #575555", +"F@ c #969595", +"G@ c #DCE9EE", +"H@ c #FF732B", +"I@ c #FF6A20", +"J@ c #FF6B25", +"K@ c #F76723", +"L@ c #FDE1D3", +"M@ c #FEF3EC", +"N@ c #FDEEE4", +"O@ c #FDE5D6", +"P@ c #FAB286", +"Q@ c #FABD94", +"R@ c #FABC96", +"S@ c #FBB990", +"T@ c #FCD1B6", +"U@ c #FCBD96", +"V@ c #FCC7A4", +"W@ c #FCC09A", +"X@ c #FFFAF7", +"Y@ c #FDEADE", +"Z@ c #FCD3B6", +"`@ c #FDE0CB", +" # c #F2763B", +".# c #FEEFE7", +"+# c #F9C2A8", +"@# c #FDE7DA", +"## c #F37C41", +"$# c #EF5812", +"%# c #F15F1B", +"&# c #FB6219", +"*# c #AAA8A8", +"=# c #4B4A4A", +"-# c #301408", +";# c #7F3513", +"># c #D3581F", +",# c #FF6516", +"'# c #FFD1B3", +")# c #F9B58C", +"!# c #F8A16E", +"~# c #F8A573", +"{# c #F8AA7B", +"]# c #E7E6E7", +"^# c #FCD3BA", +"/# c #FBBD94", +"(# c #FABC97", +"_# c #FCC4A1", +":# c #FEFCFB", +"<# c #FCBE96", +"[# c #FCC5A0", +"}# c #FCC19C", +"|# c #FFFEFE", +"1# c #FDDECA", +"2# c #FCD5BB", +"3# c #F6A278", +"4# c #F16724", +"5# c #FAC6AC", +"6# c #F16A29", +"7# c #FBD4C0", +"8# c #F9C0A3", +"9# c #F7A479", +"0# c #FB9766", +"a# c #FF7834", +"b# c #FF935A", +"c# c #AD9E95", +"d# c #3A3D3F", +"e# c #020101", +"f# c #2B1106", +"g# c #57230A", +"h# c #81888B", +"i# c #9E9FA0", +"j# c #B4B2B1", +"k# c #D6D6D6", +"l# c #D9D7D6", +"m# c #E6E3E3", +"n# c #E8E9EA", +"o# c #E9F1F6", +"p# c #DEE8ED", +"q# c #D8DEE1", +"r# c #C8C8C8", +"s# c #AAA8A7", +"t# c #6D6B6A", +"u# c #4D4C4C", +"v# c #1F1D1D", +"w# c #594E4A", +"x# c #C3C3C3", +"y# c #FCD0B6", +"z# c #F8A372", +"A# c #F8AB7E", +"B# c #F8AA7C", +"C# c #171515", +"D# c #444242", +"E# c #FEEDE3", +"F# c #FAB083", +"G# c #FABC93", +"H# c #FABC95", +"I# c #FBB78D", +"J# c #FDD9C2", +"K# c #FEFDFC", +"L# c #FDE8D9", +"M# c #F0601D", +"N# c #F05F1C", +"O# c #F05B14", +"P# c #F2FCFF", +"Q# c #677379", +"R# c #000001", +"S# c #3A3939", +"T# c #868586", +"U# c #CAD2D6", +"V# c #FA7333", +"W# c #FF6D23", +"X# c #FF6E26", +"Y# c #FF7632", +"Z# c #FFF3EA", +"`# c #FB9F71", +" $ c #FB9562", +".$ c #FFCBAF", +"+$ c #FEFDFD", +"@$ c #C2C1C0", +"#$ c #838181", +"$$ c #403F3E", +"%$ c #595757", +"&$ c #D1D6DA", +"*$ c #FFD8B3", +"=$ c #FFB280", +"-$ c #FCAE80", +";$ c #F8AD80", +">$ c #F9AB7B", +",$ c #C1BFBF", +"'$ c #FDE3D4", +")$ c #FBBC93", +"!$ c #FAB991", +"~$ c #FCD5BC", +"{$ c #FEF6F1", +"]$ c #F9B999", +"^$ c #F58F5C", +"/$ c #FEF2EB", +"($ c #D8D7D6", +"_$ c #373535", +":$ c #110703", +"<$ c #777D7E", +"[$ c #D7DEE1", +"}$ c #FFBA97", +"|$ c #F25912", +"1$ c #F7AB85", +"2$ c #FCDECE", +"3$ c #F58E5B", +"4$ c #EEEDED", +"5$ c #989797", +"6$ c #41403F", +"7$ c #030000", +"8$ c #825942", +"9$ c #FFB082", +"0$ c #FFBE8D", +"a$ c #FFAE7E", +"b$ c #FABF9B", +"c$ c #474545", +"d$ c #F7AF8B", +"e$ c #F1631E", +"f$ c #F05E1A", +"g$ c #F0611D", +"h$ c #F4570D", +"i$ c #DEDFDF", +"j$ c #282726", +"k$ c #00060B", +"l$ c #6E3115", +"m$ c #DF5D20", +"n$ c #FF671E", +"o$ c #FFD0B6", +"p$ c #F58E5D", +"q$ c #F26C2B", +"r$ c #FDE5D8", +"s$ c #F9BC9E", +"t$ c #C6C4C4", +"u$ c #5F5E5E", +"v$ c #493124", +"w$ c #D99E7C", +"x$ c #796860", +"y$ c #FFFBEC", +"z$ c #FDE1CF", +"A$ c #FDDAC3", +"B$ c #FEF0E6", +"C$ c #FDD7C0", +"D$ c #FEF3EB", +"E$ c #F26E2E", +"F$ c #F04F03", +"G$ c #FF7A36", +"H$ c #FADFD1", +"I$ c #3F4446", +"J$ c #2A2827", +"K$ c #BBC1C5", +"L$ c #FFDCBF", +"M$ c #FF6116", +"N$ c #F66723", +"O$ c #FDE8DD", +"P$ c #F7A47B", +"Q$ c #F69E73", +"R$ c #F9C3A8", +"S$ c #FAC9AF", +"T$ c #F05810", +"U$ c #C9C8C7", +"V$ c #514F4F", +"W$ c #252525", +"X$ c #C5C4C3", +"Y$ c #999A9B", +"Z$ c #F3A97C", +"`$ c #FFD4B8", +" % c #FBC39D", +".% c #FCC09B", +"+% c #FCC29F", +"@% c #FCBE97", +"#% c #FEE5D5", +"$% c #FDEDE1", +"%% c #FCD0B4", +"&% c #FCCFB1", +"*% c #7D888D", +"=% c #3D3C3B", +"-% c #E3E2E2", +";% c #F47B40", +">% c #F16C2B", +",% c #F27030", +"'% c #9C9B9A", +")% c #151413", +"!% c #18191A", +"~% c #DEC2B2", +"{% c #2A1A12", +"]% c #2D201A", +"^% c #FFC692", +"/% c #FDE8DB", +"(% c #FBBE97", +"_% c #FDC5A3", +":% c #FDC6A4", +"<% c #FDC6A3", +"[% c #FCC6A3", +"}% c #FCCEB0", +"|% c #FCD3B7", +"1% c #FFFCF9", +"2% c #FBD7C3", +"3% c #F37F45", +"4% c #FBCFB9", +"5% c #DCDADA", +"6% c #060606", +"7% c #333739", +"8% c #E8E9E9", +"9% c #F6996B", +"0% c #F37B40", +"a% c #F59668", +"b% c #EF4D00", +"c% c #F58C58", +"d% c #EF5004", +"e% c #D5D4D3", +"f% c #3D3C3C", +"g% c #0F0907", +"h% c #B67E5E", +"i% c #FFFFFB", +"j% c #FDEADD", +"k% c #FBBD96", +"l% c #FDE7D8", +"m% c #FEFEFC", +"n% c #FEEFE4", +"o% c #FBD6C3", +"p% c #FACAB0", +"q% c #FBD6C2", +"r% c #FDF0E8", +"s% c #6F6D6C", +"t% c #0A1418", +"u% c #C8A18E", +"v% c #FFECD6", +"w% c #F9C2A5", +"x% c #FDECE2", +"y% c #F6996C", +"z% c #F48B58", +"A% c #FCE4D7", +"B% c #F0580F", +"C% c #FAB48D", +"D% c #F89862", +"E% c #F89A65", +"F% c #F89E6A", +"G% c #FDE3D3", +"H% c #686666", +"I% c #FBC7A4", +"J% c #FCBF99", +"K% c #FCC29E", +"L% c #FEEBDF", +"M% c #FCDAC2", +"N% c #FCDCC6", +"O% c #FDEFE4", +"P% c #FAC7AD", +"Q% c #F05A13", +"R% c #EE4D00", +"S% c #FFCAAD", +"T% c #131211", +"U% c #857D79", +"V% c #FF7E39", +"W% c #F95F16", +"X% c #FBD5C2", +"Y% c #F7A87F", +"Z% c #F0570E", +"`% c #FACBB3", +" & c #F0621E", +".& c #F7AA84", +"+& c #FABA94", +"@& c #F89A66", +"#& c #F8A373", +"$& c #F9A474", +"%& c #F8A474", +"&& c #F79964", +"*& c #898888", +"=& c #706F6F", +"-& c #3C3939", +";& c #6E6C6D", +">& c #FDE1D0", +",& c #FDE5D5", +"'& c #FCDEC9", +")& c #FCDCC4", +"!& c #FFFAF6", +"~& c #FACDB5", +"{& c #FEFAF5", +"]& c #F0621D", +"^& c #FF671C", +"/& c #C19782", +"(& c #191717", +"_& c #F5FFFF", +":& c #FF8C50", +"<& c #F15E1A", +"[& c #EF5308", +"}& c #FEF0E7", +"|& c #F9BD9E", +"1& c #F3834D", +"2& c #F4834E", +"3& c #F9BEA0", +"4& c #F59769", +"5& c #F0631F", +"6& c #F16826", +"7& c #F8B592", +"8& c #F89863", +"9& c #F8A171", +"0& c #F9A575", +"a& c #F9A675", +"b& c #F8A170", +"c& c #FBCAAE", +"d& c #3A3839", +"e& c #F0DDD3", +"f& c #FFB98B", +"g& c #FAB78F", +"h& c #FBB88E", +"i& c #FBBA91", +"j& c #FFFDFD", +"k& c #FDDDC9", +"l& c #FEEEE4", +"m& c #FCE0D0", +"n& c #F26F2F", +"o& c #F05A15", +"p& c #F05912", +"q& c #FF6F24", +"r& c #7A7878", +"s& c #FBD1BC", +"t& c #EF540C", +"u& c #F37F46", +"v& c #FEF9F5", +"w& c #FDEEE6", +"x& c #F89964", +"y& c #F8A16F", +"z& c #FBCCB1", +"A& c #313539", +"B& c #23150E", +"C& c #FFD5A7", +"D& c #FBBD97", +"E& c #FCBE98", +"F& c #FBBA92", +"G& c #FCD5BA", +"H& c #FCCCAD", +"I& c #FCC6A4", +"J& c #FCD8BF", +"K& c #FEEEE3", +"L& c #F16625", +"M& c #FFFBF6", +"N& c #FFE0C3", +"O& c #4C2E1F", +"P& c #D3D1D1", +"Q& c #EF560D", +"R& c #FCE1D3", +"S& c #FAC6AB", +"T& c #FAC8AF", +"U& c #F3763A", +"V& c #FBD1BA", +"W& c #FAC1A0", +"X& c #FCD5BD", +"Y& c #FBAA7B", +"Z& c #F7AB7E", +"`& c #704B37", +" * c #8F8078", +".* c #A6A9AB", +"+* c #A4A2A2", +"@* c #545252", +"#* c #0C0A0A", +"$* c #AE8268", +"%* c #FFC79E", +"&* c #FBBC95", +"** c #FCCEAF", +"=* c #FDF1E8", +"-* c #FCC39F", +";* c #FDCBAA", +">* c #FDCCAD", +",* c #FDCCAE", +"'* c #FCC8A7", +")* c #FDE8DA", +"!* c #FCD6BC", +"~* c #FCDAC1", +"{* c #2A3032", +"]* c #141313", +"^* c #F6A075", +"/* c #F26D2D", +"(* c #FDEDE3", +"_* c #F05C14", +":* c #F59362", +"<* c #F59263", +"[* c #F59566", +"}* c #F1621D", +"|* c #FCE0D2", +"1* c #FBC2A2", +"2* c #F89A64", +"3* c #F89962", +"4* c #F9A777", +"5* c #FEECE2", +"6* c #F8A06D", +"7* c #F8AA7D", +"8* c #FCB082", +"9* c #FFB889", +"0* c #FFB381", +"a* c #F9F8F8", +"b* c #959494", +"c* c #1D1B1B", +"d* c #FFCCA4", +"e* c #FEBE97", +"f* c #FBB589", +"g* c #FCC39E", +"h* c #FCD4B8", +"i* c #FCD5B9", +"j* c #181616", +"k* c #3E3D3C", +"l* c #F05C15", +"m* c #F48753", +"n* c #F8B493", +"o* c #F8A677", +"p* c #F8A97C", +"q* c #F9AB7E", +"r* c #F9AD81", +"s* c #F8AB7C", +"t* c #FBCEB2", +"u* c #DDDBDC", +"v* c #454343", +"w* c #543B2D", +"x* c #FFD3AC", +"y* c #FDD1B6", +"z* c #FCC5A1", +"A* c #FEFEFD", +"B* c #0F0D0D", +"C* c #656262", +"D* c #FCDCCC", +"E* c #F16D2F", +"F* c #F8AC7E", +"G* c #FACAAB", +"H* c #FBFAFA", +"I* c #494A4C", +"J* c #E0E5E9", +"K* c #FEECE1", +"L* c #FEF5EF", +"M* c #FDEFE5", +"N* c #FDEDE0", +"O* c #FEFEFE", +"P* c #F16421", +"Q* c #F59464", +"R* c #F38049", +"S* c #FCBC9C", +"T* c #7F7E7D", +"U* c #FBD2BE", +"V* c #FAC3A6", +"W* c #FBC1A0", +"X* c #F99C69", +"Y* c #FAB48E", +"Z* c #F8AD81", +"`* c #F8A472", +" = c #FDD0B4", +".= c #FDDFCB", +"+= c #FFF9F6", +"@= c #FCE2CE", +"#= c #FCE6D3", +"$= c #FDF3EA", +"%= c #FACFB8", +"&= c #F2601B", +"*= c #1F0C04", +"== c #848282", +"-= c #FCDBCA", +";= c #F16623", +">= c #F4854F", +",= c #F16725", +"'= c #FDE8DC", +")= c #F89C6A", +"!= c #F8945D", +"~= c #F89B68", +"{= c #F89A67", +"]= c #F8945C", +"^= c #F9B890", +"/= c #F8A06E", +"(= c #F8A674", +"_= c #F8A371", +":= c #FCD8C2", +"<= c #FCD4BB", +"[= c #FABB91", +"}= c #FABB94", +"|= c #FDD6BE", +"1= c #FBC09B", +"2= c #FCC4A0", +"3= c #FCCFB0", +"4= c #FEF2E9", +"5= c #FDEADC", +"6= c #FCE9D7", +"7= c #F8B08E", +"8= c #FCDECF", +"9= c #FF7228", +"0= c #371608", +"a= c #858383", +"b= c #F37B41", +"c= c #FCE6DA", +"d= c #FBD5C1", +"e= c #F69A6C", +"f= c #FEF2EC", +"g= c #FBCFB5", +"h= c #F8925A", +"i= c #F99C68", +"j= c #F99D6B", +"k= c #F99E6B", +"l= c #F99F6E", +"m= c #F89C69", +"n= c #FDEDE2", +"o= c #FCD8C3", +"p= c #FDE9DC", +"q= c #FBC19D", +"r= c #FAB58B", +"s= c #FBB88F", +"t= c #FCC7A6", +"u= c #FBBE98", +"v= c #FCC29B", +"w= c #FFF7F3", +"x= c #FCC9A9", +"y= c #FCCFB3", +"z= c #FCD1B5", +"A= c #F48048", +"B= c #FF7127", +"C= c #5F280E", +"D= c #716F6E", +"E= c #FBD3BE", +"F= c #F1631F", +"G= c #FEF5F0", +"H= c #F9BC9D", +"I= c #F27133", +"J= c #F48B57", +"K= c #FAB58E", +"L= c #F89661", +"M= c #F89E6D", +"N= c #F89E6B", +"O= c #F9B68C", +"P= c #F9A979", +"Q= c #F9AD7E", +"R= c #FABA92", +"S= c #FBBA94", +"T= c #FBB68B", +"U= c #FCC19A", +"V= c #FFF9F5", +"W= c #FCCFB2", +"X= c #FDD1B7", +"Y= c #FDD4B9", +"Z= c #FCD2B6", +"`= c #FDE8D8", +" - c #FDECDF", +".- c #FAC9B0", +"+- c #F16522", +"@- c #FF681D", +"#- c #953C14", +"$- c #535151", +"%- c #F5905E", +"&- c #FACAB2", +"*- c #FAC09F", +"=- c #F8955F", +"-- c #F89D6B", +";- c #F9A677", +">- c #FBCEB3", +",- c #F9B081", +"'- c #FCD1B7", +")- c #FEEADD", +"!- c #FAB387", +"~- c #FBC5A2", +"{- c #FCBF9B", +"]- c #FDD9C0", +"^- c #FCCEB1", +"/- c #FDEBDD", +"(- c #FDF0E6", +"_- c #FCDCC8", +":- c #FCDFCA", +"<- c #D9D0CC", +"[- c #292727", +"}- c #FCE3D6", +"|- c #F0611C", +"1- c #F88C52", +"2- c #F8935B", +"3- c #FDDBC8", +"4- c #F8AF81", +"5- c #F9B487", +"6- c #FAB992", +"7- c #FCBC96", +"8- c #FCCDB0", +"9- c #FDD6BC", +"0- c #FCDAC0", +"a- c #FCDCC7", +"b- c #FCE0CD", +"c- c #F38149", +"d- c #EF560C", +"e- c #F69D71", +"f- c #FBD6C5", +"g- c #F27031", +"h- c #F59666", +"i- c #F89762", +"j- c #FCD0B7", +"k- c #FAC19F", +"l- c #F89C67", +"m- c #F89B65", +"n- c #FBCEB4", +"o- c #FAC09D", +"p- c #F8AD7F", +"q- c #F9B285", +"r- c #FBC6A7", +"s- c #FAB388", +"t- c #FAB78B", +"u- c #FAB68D", +"v- c #FBB78C", +"w- c #FEF0E8", +"x- c #FEF1E8", +"y- c #FDEBDE", +"z- c #F69769", +"A- c #F7AC88", +"B- c #FDE4D7", +"C- c #FAF8F8", +"D- c #F27335", +"E- c #FFF9F4", +"F- c #F59160", +"G- c #F9B188", +"H- c #F89C68", +"I- c #F8A575", +"J- c #F8A676", +"K- c #FBC9AB", +"L- c #FEF5EE", +"M- c #F9B186", +"N- c #F9AB7A", +"O- c #FDEBDC", +"P- c #FCEADB", +"Q- c #FAC8AD", +"R- c #FBCEB9", +"S- c #F05B13", +"T- c #FFE7D0", +"U- c #7A7F82", +"V- c #C2C0C0", +"W- c #F8AF89", +"X- c #F05A12", +"Y- c #F2763A", +"Z- c #FACCB3", +"`- c #FDF2EA", +" ; c #F7884D", +".; c #F78B50", +"+; c #F78C51", +"@; c #FAB28A", +"#; c #F89660", +"$; c #F9A778", +"%; c #F8A778", +"&; c #F89F6A", +"*; c #FBC6A5", +"=; c #FAB890", +"-; c #FBC8A8", +";; c #FDE9DB", +">; c #FCC5A3", +",; c #FCCDAF", +"'; c #FCE8D7", +"); c #FDF6EF", +"!; c #F37537", +"~; c #EF570E", +"{; c #F96621", +"]; c #D15E28", +"^; c #696867", +"/; c #FACCB4", +"(; c #F06524", +"_; c #FCE0D1", +":; c #F7884C", +"<; c #F79058", +"[; c #F7945F", +"}; c #F79762", +"|; c #F7935C", +"1; c #FDDCC7", +"2; c #F8A16D", +"3; c #FBC5A3", +"4; c #FAB589", +"5; c #FBBC96", +"6; c #FCC19B", +"7; c #FDCBAC", +"8; c #FCCBAB", +"9; c #FDF5EE", +"0; c #FAC8AE", +"a; c #F6A67E", +"b; c #F26523", +"c; c #FF6F26", +"d; c #121211", +"e; c #FBD8C4", +"f; c #F69768", +"g; c #F1621E", +"h; c #F78F56", +"i; c #F8945F", +"j; c #F89965", +"k; c #F7925C", +"l; c #FAC5A6", +"m; c #F9AD7F", +"n; c #FAB58A", +"o; c #FAB88E", +"p; c #FAB88F", +"q; c #FAB185", +"r; c #FCC6A2", +"s; c #FDCBAB", +"t; c #FDCDAF", +"u; c #FCC7A7", +"v; c #FDF9F6", +"w; c #FDDBC5", +"x; c #FCD3B8", +"y; c #FCD6BD", +"z; c #F9BA9C", +"A; c #F4844F", +"B; c #EF4E01", +"C; c #FF6D24", +"D; c #5C260E", +"E; c #F9FEFF", +"F; c #FBCCB5", +"G; c #FACAB1", +"H; c #F16A2A", +"I; c #F5874B", +"J; c #F8935D", +"K; c #F79763", +"L; c #F8A272", +"M; c #FAB38C", +"N; c #F8A473", +"O; c #F89D69", +"P; c #FBCBAD", +"Q; c #FBD5BD", +"R; c #F9B085", +"S; c #FBB98F", +"T; c #FABA93", +"U; c #FAB88D", +"V; c #FDE6D8", +"W; c #FCC4A2", +"X; c #FBC09A", +"Y; c #FCC29C", +"Z; c #FDCAAA", +"`; c #FCC8A8", +" > c #FDDBC4", +".> c #FCD7BE", +"+> c #FC7F42", +"@> c #D0612D", +"#> c #8E411D", +"$> c #FF651B", +"%> c #EF5911", +"&> c #F7A176", +"*> c #F48D5A", +"=> c #F9C4A9", +"-> c #F69C70", +";> c #F27234", +">> c #F27639", +",> c #F58649", +"'> c #F8A271", +")> c #FBC4A4", +"!> c #F89A63", +"~> c #FCD2BA", +"{> c #FBCFB4", +"]> c #FBBA93", +"^> c #FAB386", +"/> c #FDE2D1", +"(> c #FBB88C", +"_> c #FBBF9A", +":> c #FBC29D", +"<> c #FBC19C", +"[> c #FCC7A5", +"}> c #FCD1B4", +"|> c #FDD5BC", +"1> c #FDD7BF", +"2> c #FCD7BD", +"3> c #F4834B", +"4> c #0A1419", +"5> c #200E05", +"6> c #FF7126", +"7> c #FCE3D5", +"8> c #F16928", +"9> c #F8A679", +"0> c #F78F57", +"a> c #F7935D", +"b> c #FAC2A2", +"c> c #FCDBC6", +"d> c #F8A879", +"e> c #FBD1B5", +"f> c #F9AB7C", +"g> c #FBB78E", +"h> c #FBC9A8", +"i> c #FBBB92", +"j> c #FBC099", +"k> c #FCC09D", +"l> c #FBC4A1", +"m> c #FCD3B9", +"n> c #FCD7BF", +"o> c #888686", +"p> c #E96122", +"q> c #F37E45", +"r> c #F7F7F8", +"s> c #8F8D8E", +"t> c #5F5D5E", +"u> c #514E4F", +"v> c #535050", +"w> c #5B595A", +"x> c #D1D3D5", +"y> c #FFFCF6", +"z> c #F68648", +"A> c #F7915A", +"B> c #F7945D", +"C> c #F7945E", +"D> c #FCD1B8", +"E> c #F89F69", +"F> c #F8A87B", +"G> c #F8A675", +"H> c #FABF9C", +"I> c #FAAD7F", +"J> c #FAB285", +"K> c #FBB58A", +"L> c #FDC29E", +"M> c #FDD8C1", +"N> c #FDDAC4", +"O> c #FCD2B7", +"P> c #FEF1E7", +"Q> c #FCE4D1", +"R> c #FCE0CA", +"S> c #774D37", +"T> c #FF681F", +"U> c #F59262", +"V> c #F9C3A7", +"W> c #FBD8C7", +"X> c #A2A1A2", +"Y> c #050102", +"Z> c #140F10", +"`> c #191516", +" , c #1B1718", +"., c #070203", +"+, c #BBBCBC", +"@, c #F89D6A", +"#, c #F7874C", +"$, c #F78C52", +"%, c #F78B4F", +"&, c #F9AA7D", +"*, c #FABA95", +"=, c #F89864", +"-, c #F89E69", +";, c #F8A97A", +">, c #F9A97D", +",, c #FBC3A0", +"', c #FCDCC5", +"), c #FCE2CF", +"!, c #FDF4ED", +"~, c #F37B3F", +"{, c #FCE3D4", +"], c #484745", +"^, c #F05308", +"/, c #FBD8C5", +"(, c #FBD0BA", +"_, c #F38048", +":, c #D0D0D0", +"<, c #020000", +"[, c #221D1E", +"}, c #231F20", +"|, c #211D1E", +"1, c #201C1D", +"2, c #0D0809", +"3, c #D5D4D5", +"4, c #F8925B", +"5, c #F89763", +"6, c #F89761", +"7, c #FABD9A", +"8, c #FDDFCD", +"9, c #FEEFE6", +"0, c #FBBB93", +"a, c #FCE1CC", +"b, c #F8B897", +"c, c #FACFBB", +"d, c #F6570C", +"e, c #DBA991", +"f, c #FBD6C1", +"g, c #F16827", +"h, c #F69D6F", +"i, c #F4824B", +"j, c #444243", +"k, c #1C1718", +"l, c #171314", +"m, c #141011", +"n, c #221E1F", +"o, c #E7E7E7", +"p, c #F9A779", +"q, c #F9A271", +"r, c #FDE4D5", +"s, c #F89D68", +"t, c #FAB488", +"u, c #FAB389", +"v, c #FAB78C", +"w, c #FEEFE5", +"x, c #F3793D", +"y, c #FF7025", +"z, c #250700", +"A, c #292827", +"B, c #FBD2BD", +"C, c #FCDFCF", +"D, c #F69D70", +"E, c #F1601B", +"F, c #090506", +"G, c #6B686A", +"H, c #FEFEFF", +"I, c #F88E55", +"J, c #F99B68", +"K, c #FFA471", +"L, c #FFAB76", +"M, c #FFA771", +"N, c #FFC9A4", +"O, c #FBC5A6", +"P, c #F8A878", +"Q, c #F9B58D", +"R, c #FAB78D", +"S, c #FABC92", +"T, c #FDE0CD", +"U, c #FCC39D", +"V, c #FCD4B9", +"W, c #FDEFE3", +"X, c #FDF0E9", +"Y, c #FACFB9", +"Z, c #FA6824", +"`, c #BE4E1C", +" ' c #E6E5E5", +".' c #FEFAF9", +"+' c #0B0708", +"@' c #100C0D", +"#' c #F88F56", +"$' c #FFA470", +"%' c #A77559", +"&' c #6A5042", +"*' c #715343", +"=' c #6A5349", +"-' c #B2B4B6", +";' c #FBCAAD", +">' c #FAC09C", +",' c #FDC7A4", +"'' c #FDCAA9", +")' c #FDCAAB", +"!' c #FCD6BB", +"~' c #B8B8B9", +"{' c #6A686A", +"]' c #737172", +"^' c #6C6A6C", +"/' c #A3A2A4", +"(' c #FCECDF", +"_' c #FCEDE0", +":' c #FCEDE2", +"<' c #F1621F", +"[' c #180904", +"}' c #494747", +"|' c #F58C57", +"1' c #F58D5A", +"2' c #CFCECE", +"3' c #0E0A0B", +"4' c #1E1A1B", +"5' c #333031", +"6' c #F89560", +"7' c #FFA773", +"8' c #725343", +"9' c #0D1016", +"0' c #18181B", +"a' c #0B090C", +"b' c #7F7F7E", +"c' c #FDF3EC", +"d' c #FAAE80", +"e' c #FDD5BB", +"f' c #FDD8BF", +"g' c #8B8A8B", +"h' c #0A0506", +"i' c #181314", +"j' c #0D090A", +"k' c #686667", +"l' c #FDF0E4", +"m' c #F95A0E", +"n' c #B24716", +"o' c #FAC1A6", +"p' c #F3773B", +"q' c #CCCBCD", +"r' c #0F0A0B", +"s' c #343132", +"t' c #FCD7C2", +"u' c #F88E54", +"v' c #785745", +"w' c #17171B", +"x' c #161213", +"y' c #858584", +"z' c #FAB990", +"A' c #FCC49F", +"B' c #FEEBDE", +"C' c #FCD4BA", +"D' c #919091", +"E' c #151011", +"F' c #181415", +"G' c #6F6D6E", +"H' c #1B1614", +"I' c #545353", +"J' c #F48A55", +"K' c #F7A983", +"L' c #FEF0E9", +"M' c #CDCCCD", +"N' c #FCD1BA", +"O' c #F8955E", +"P' c #FFA068", +"Q' c #785440", +"R' c #FDE6D7", +"S' c #FAC19D", +"T' c #F9BA93", +"U' c #FEFDFB", +"V' c #FECFB2", +"W' c #FAB68B", +"X' c #FBCFB2", +"Y' c #FFE9DA", +"Z' c #FFF4E8", +"`' c #FDEFE8", +" ) c #F9B391", +".) c #C9C8C8", +"+) c #EF4E03", +"@) c #F3844F", +"#) c #F38047", +"$) c #DEDEDF", +"%) c #383536", +"&) c #FFF9E9", +"*) c #FFFFEC", +"=) c #857C78", +"-) c #171416", +";) c #919090", +">) c #FACAAC", +",) c #F9A16E", +"') c #FFBA86", +")) c #FFBB89", +"!) c #FFBB87", +"~) c #FFB983", +"{) c #FFF9F2", +"]) c #EFF0F0", +"^) c #C4C3C4", +"/) c #C7C7C8", +"() c #F8FEFF", +"_) c #E1E1E2", +":) c #C5C4C4", +"<) c #D0CFD0", +"[) c #FBFBFB", +"}) c #F8FCFE", +"|) c #CED0D2", +"1) c #CBCBCB", +"2) c #F8F9F9", +"3) c #9D9D9E", +"4) c #787677", +"5) c #F2783D", +"6) c #2A2928", +"7) c #4F4D4D", +"8) c #F48D5B", +"9) c #F7AC86", +"0) c #EF4D01", +"a) c #F7AC87", +"b) c #676565", +"c) c #191415", +"d) c #242021", +"e) c #747273", +"f) c #202023", +"g) c #232427", +"h) c #221F21", +"i) c #161518", +"j) c #FFF8EF", +"k) c #FAA16D", +"l) c #FFB385", +"m) c #14171D", +"n) c #201D1E", +"o) c #211E1F", +"p) c #0C0D11", +"q) c #F7B790", +"r) c #F3F9FD", +"s) c #3B383A", +"t) c #070304", +"u) c #0F0B0C", +"v) c #8F8F92", +"w) c #FFFCF3", +"x) c #4F4D4E", +"y) c #0F0B0D", +"z) c #0E090A", +"A) c #C3C1C1", +"B) c #9E9D9E", +"C) c #2F2C2D", +"D) c #0A0507", +"E) c #312E2F", +"F) c #A7A6A6", +"G) c #2D2B2B", +"H) c #0C0709", +"I) c #FDFFFF", +"J) c #FCDCCA", +"K) c #E2E1E1", +"L) c #ECEAE9", +"M) c #FEFBF7", +"N) c #666463", +"O) c #151112", +"P) c #727071", +"Q) c #140F11", +"R) c #1F1A1B", +"S) c #131418", +"T) c #FFDDC4", +"U) c #FBA777", +"V) c #FFB586", +"W) c #11151C", +"X) c #1F1C1D", +"Y) c #0E1015", +"Z) c #DEA07C", +"`) c #0E0F13", +" ! c #1B1618", +".! c #141417", +"+! c #97735E", +"@! c #FFBC8D", +"#! c #FCB589", +"$! c #FFC59B", +"%! c #555558", +"&! c #080405", +"*! c #1B1617", +"=! c #1D191A", +"-! c #050306", +";! c #7E6354", +">! c #FFF9E6", +",! c #EAE5E2", +"'! c #0C0809", +")! c #383638", +"!! c #FFF1DE", +"~! c #2D2727", +"{! c #1C181A", +"]! c #F69668", +"^! c #EF580E", +"/! c #4C4B4A", +"(! c #384044", +"_! c #F7A881", +":! c #F8BA9B", +"~ c #E6DBD4", +",~ c #453731", +"'~ c #181618", +")~ c #1B181A", +"!~ c #4B3D37", +"~~ c #FFFAEA", +"{~ c #1E1A1C", +"]~ c #0F0E11", +"^~ c #3D3534", +"/~ c #A4A3A4", +"(~ c #C0BFC0", +"_~ c #9E9C9E", +":~ c #0C0A0D", +"<~ c #DECABC", +"[~ c #FFF6DD", +"}~ c #61534C", +"|~ c #575455", +"1~ c #5D5A5B", +"2~ c #3E3B3C", +"3~ c #353233", +"4~ c #5F5D5F", +"5~ c #595758", +"6~ c #494546", +"7~ c #F8B290", +"8~ c #EF4F05", +"9~ c #EE4700", +"0~ c #7A4125", +"a~ c #120703", +"b~ c #FF6415", +"c~ c #FACBB2", +"d~ c #F7AE8B", +"e~ c #F7B08E", +"f~ c #F8B898", +"g~ c #F8B594", +"h~ c #F0611B", +"i~ c #DADADB", +"j~ c #373435", +"k~ c #FABE9D", +"l~ c #FFA972", +"m~ c #FFB37A", +"n~ c #805C49", +"o~ c #8E8E8D", +"p~ c #FFEADE", +"q~ c #FFAD79", +"r~ c #13161C", +"s~ c #767576", +"t~ c #FFFFF9", +"u~ c #FFBA89", +"v~ c #FFBF94", +"w~ c #FCBE95", +"x~ c #FFC699", +"y~ c #9A9695", +"z~ c #FFD6AB", +"A~ c #2C2828", +"B~ c #929192", +"C~ c #0C0C0F", +"D~ c #947E72", +"E~ c #434042", +"F~ c #D8D8D9", +"G~ c #FEF4EC", +"H~ c #9A9A9B", +"I~ c #181416", +"J~ c #767170", +"K~ c #F69F74", +"L~ c #963F16", +"M~ c #FC6017", +"N~ c #F6A781", +"O~ c #F8B08F", +"P~ c #F16420", +"Q~ c #FACEB8", +"R~ c #FFB286", +"S~ c #130F11", +"T~ c #221E1E", +"U~ c #4C4A4B", +"V~ c #FCC09C", +"W~ c #856C5E", +"X~ c #171518", +"Y~ c #F8F9FB", +"Z~ c #252123", +"`~ c #181517", +" { c #6D5B52", +".{ c #FFEDD0", +"+{ c #181516", +"@{ c #6F6663", +"#{ c #FFFAE9", +"${ c #FCEEE3", +"%{ c #BEBCBC", +"&{ c #F04E01", +"*{ c #FAC3A8", +"={ c #14171C", +"-{ c #B77A59", +";{ c #FF9F69", +">{ c #130E10", +",{ c #100B0C", +"'{ c #CBCBCC", +"){ c #FAB68C", +"!{ c #FAFAFB", +"~{ c #B9B9B9", +"{{ c #8C8A8B", +"]{ c #6F6E6F", +"^{ c #5E5B5C", +"/{ c #5A5758", +"({ c #605F61", +"_{ c #3A393B", +":{ c #F1F2F3", +"<{ c #F4F5F5", +"[{ c #0A0607", +"}{ c #0C080A", +"|{ c #F7F3EF", +"1{ c #6F6765", +"2{ c #3A3937", +"3{ c #5A250C", +"4{ c #FF7C39", +"5{ c #FBC9B0", +"6{ c #F27334", +"7{ c #080304", +"8{ c #0E0D10", +"9{ c #B99E90", +"0{ c #FF985E", +"a{ c #F99C6A", +"b{ c #FFFDFC", +"c{ c #FFEEE5", +"d{ c #F5F5F4", +"e{ c #CFD0D1", +"f{ c #3F3C3D", +"g{ c #1A1517", +"h{ c #F2F3F4", +"i{ c #D3D3D4", +"j{ c #242122", +"k{ c #E3E7EA", +"l{ c #FFFBF9", +"m{ c #F8A982", +"n{ c #090405", +"o{ c #B9C2C8", +"p{ c #FFCBAA", +"q{ c #F89057", +"r{ c #FFA670", +"s{ c #785644", +"t{ c #FBCDB1", +"u{ c #F9A371", +"v{ c #F3F3F3", +"w{ c #F9AF80", +"x{ c #F9AD80", +"y{ c #8F8E8F", +"z{ c #040000", +"A{ c #1C1819", +"B{ c #151417", +"C{ c #101014", +"D{ c #0B080A", +"E{ c #CDD0D1", +"F{ c #302E2F", +"G{ c #EF5910", +"H{ c #FBD8C6", +"I{ c #8D8C8B", +"J{ c #151313", +"K{ c #F9BC9F", +"L{ c #F1641F", +"M{ c #F7A981", +"N{ c #F37A40", +"O{ c #F8B390", +"P{ c #F26A29", +"Q{ c #464343", +"R{ c #575454", +"S{ c #4A4747", +"T{ c #CBCACB", +"U{ c #FAB38B", +"V{ c #785A4A", +"W{ c #17161A", +"X{ c #FCD5BF", +"Y{ c #FAAB7E", +"Z{ c #FFB485", +"`{ c #F3F4F5", +" ] c #F9B589", +".] c #FFCFAE", +"+] c #D4DADF", +"@] c #292527", +"#] c #8E7262", +"$] c #C69C82", +"%] c #E3B497", +"&] c #EDB898", +"*] c #FFFFFD", +"=] c #494748", +"-] c #FFEADA", +";] c #E2B99F", +">] c #0B0B0F", +",] c #181818", +"'] c #918F90", +")] c #FCDECD", +"!] c #F69C6F", +"~] c #F8AF8C", +"{] c #F27435", +"]] c #F48C5A", +"^] c #7C7D80", +"/] c #888787", +"(] c #F4F7FA", +"_] c #FFD8BF", +":] c #F9B083", +"<] c #FFC396", +"[] c #5D5E60", +"}] c #191517", +"|] c #626468", +"1] c #FFF3D9", +"2] c #FFC8A0", +"3] c #FFC9A3", +"4] c #FFC7A3", +"5] c #FFC6A2", +"6] c #FFEBCC", +"7] c #36383D", +"8] c #F2F4F6", +"9] c #FFF7EF", +"0] c #FEC7A6", +"a] c #FFDCBD", +"b] c #111115", +"c] c #B5B5B5", +"d] c #FCE1CD", +"e] c #919192", +"f] c #716F70", +"g] c #F26A28", +"h] c #F4550A", +"i] c #E9E5E4", +"j] c #F16521", +"k] c #FCD3BD", +"l] c #F9AC81", +"m] c #FAB894", +"n] c #7A7879", +"o] c #757375", +"p] c #FBAB7B", +"q] c #FFDBC3", +"r] c #FFC89B", +"s] c #37373A", +"t] c #1D1A1B", +"u] c #D6DBE0", +"v] c #FFD4B4", +"w] c #FFC8A5", +"x] c #FFD1B1", +"y] c #F2F6F8", +"z] c #FFE8D8", +"A] c #FCCAAB", +"B] c #FFDEBE", +"C] c #5C504B", +"D] c #191619", +"E] c #FBFCFC", +"F] c #FFF4ED", +"G] c #FDD5BA", +"H] c #FEDCC3", +"I] c #FFE4C9", +"J] c #8F837C", +"K] c #151113", +"L] c #5D5B5C", +"M] c #F0560D", +"N] c #F37335", +"O] c #FF7835", +"P] c #7D878B", +"Q] c #333130", +"R] c #F4814A", +"S] c #F27336", +"T] c #F78A50", +"U] c #F7955E", +"V] c #F78B51", +"W] c #FBCDB3", +"X] c #161112", +"Y] c #F0F8FD", +"Z] c #FFCCA3", +"`] c #FFB37F", +" ^ c #F1A77B", +".^ c #FFE6CA", +"+^ c #3C3E42", +"@^ c #646568", +"#^ c #FFFFF5", +"$^ c #FFCDA7", +"%^ c #FFD2AB", +"&^ c #FFD7B2", +"*^ c #4A3F3B", +"=^ c #1A181A", +"-^ c #FFF8F1", +";^ c #FCC6A5", +">^ c #FFD2B4", +",^ c #E6BFA6", +"'^ c #06070B", +")^ c #1E191A", +"!^ c #B4B3B5", +"~^ c #FFF1D9", +"{^ c #FFE9D0", +"]^ c #B39F93", +"^^ c #080609", +"/^ c #5E5B5D", +"(^ c #998C82", +"_^ c #141012", +":^ c #E2E2E3", +"<^ c #F9F9FA", +"[^ c #FCFCFD", +"}^ c #EF550E", +"|^ c #F37538", +"1^ c #0F1112", +"2^ c #A4A8AB", +"3^ c #FFFFFC", +"4^ c #FBDAC8", +"5^ c #F8AF8B", +"6^ c #F78D53", +"7^ c #F79966", +"8^ c #AEADAF", +"9^ c #0E0A0C", +"0^ c #212124", +"a^ c #1D1D20", +"b^ c #020C15", +"c^ c #FFB182", +"d^ c #FFB07F", +"e^ c #F3F3F2", +"f^ c #F9AE80", +"g^ c #7C7B7C", +"h^ c #34363A", +"i^ c #836C5F", +"j^ c #896F60", +"k^ c #6D5A50", +"l^ c #161416", +"m^ c #1C1719", +"n^ c #FFDCB9", +"o^ c #8B7C74", +"p^ c #0A0709", +"q^ c #120F10", +"r^ c #222124", +"s^ c #110F11", +"t^ c #716F71", +"u^ c #C6C6C7", +"v^ c #F27436", +"w^ c #E7EAEB", +"x^ c #F2560B", +"y^ c #F37C43", +"z^ c #F68649", +"A^ c #F79A67", +"B^ c #FAB996", +"C^ c #15161B", +"D^ c #FFB789", +"E^ c #FCB185", +"F^ c #FFDFC6", +"G^ c #131318", +"H^ c #120E10", +"I^ c #1B1717", +"J^ c #191719", +"K^ c #211D1F", +"L^ c #7E7C7D", +"M^ c #1A1516", +"N^ c #7B797A", +"O^ c #060103", +"P^ c #BEBDBE", +"Q^ c #7E7C7C", +"R^ c #373F42", +"S^ c #FFBF98", +"T^ c #EF5A14", +"U^ c #C7C6C8", +"V^ c #F7864B", +"W^ c #F99763", +"X^ c #F9AD83", +"Y^ c #B1B0B1", +"Z^ c #1A1618", +"`^ c #050203", +" / c #100B0D", +"./ c #F1F0F0", +"+/ c #F5F5F5", +"@/ c #2F2B2D", +"#/ c #242022", +"$/ c #7B7979", +"%/ c #040001", +"&/ c #100F12", +"*/ c #EFE5E0", +"=/ c #C6C5C6", +"-/ c #292627", +";/ c #0A0608", +">/ c #2F2D30", +",/ c #CDCFD2", +"'/ c #C6C6C6", +")/ c #191818", +"!/ c #A1A9AD", +"~/ c #FFAE84", +"{/ c #F16F2F", +"]/ c #F48C58", +"^/ c #F48650", +"// c #F2F5F7", +"(/ c #BDC5CA", +"_/ c #C3CCD2", +":/ c #C2CBD1", +"( c #FFFEFF", +",( c #FCDAC4", +"'( c #FDFAF6", +")( c #EAEAEB", +"!( c #211E20", +"~( c #120E0F", +"{( c #252122", +"]( c #241F21", +"^( c #CECECE", +"/( c #FEF9F3", +"(( c #F9BDA0", +"_( c #F16624", +":( c #F69C6E", +"<( c #F47835", +"[( c #F5884E", +"}( c #F68A4F", +"|( c #F68B52", +"1( c #F68C53", +"2( c #F58D54", +"3( c #F68B51", +"4( c #F6884C", +"5( c #FDECE1", +"6( c #FBC4A5", +"7( c #FBD0B8", +"8( c #F89760", +"9( c #F9A171", +"0( c #F8A576", +"a( c #F8A574", +"b( c #F8B084", +"c( c #F9B184", +"d( c #FAB284", +"e( c #FBB78B", +"f( c #FCCAA9", +"g( c #050103", +"h( c #EDEDEE", +"i( c #F9B695", +"j( c #F26F30", +"k( c #FBC9AE", +"l( c #F57E3F", +"m( c #F6894F", +"n( c #F78E54", +"o( c #F68345", +"p( c #FBCEB5", +"q( c #F9A678", +"r( c #FBC8A9", +"s( c #F8B184", +"t( c #F9B48A", +"u( c #FEE6D8", +"v( c #FBBB91", +"w( c #FDCFB2", +"x( c #F48955", +"y( c #939293", +"z( c #6B696A", +"A( c #F9B898", +"B( c #F58041", +"C( c #F68549", +"D( c #FCDAC6", +"E( c #FCCFB5", +"F( c #F9B489", +"G( c #FAB487", +"H( c #FCBD97", +"I( c #FBB98E", +"J( c #F59567", +"K( c #F7A67E", +"L( c #F15E18", +"M( c #605E5F", +"N( c #9B9A9A", +"O( c #F9C5AA", +"P( c #F7AA86", +"Q( c #F8B494", +"R( c #FCDDCB", +"S( c #F57A39", +"T( c #F78D54", +"U( c #F57F3F", +"V( c #FAB691", +"W( c #F9A574", +"X( c #F8A777", +"Y( c #F8AD7E", +"Z( c #FAB085", +"`( c #F9AA7A", +" _ c #FBBF98", +"._ c #F8BC9E", +"+_ c #FBDFD0", +"@_ c #696768", +"#_ c #090707", +"$_ c #6F6D6D", +"%_ c #E0DFDE", +"&_ c #F7AA83", +"*_ c #F68E55", +"=_ c #F58246", +"-_ c #F58C53", +";_ c #F68447", +">_ c #F8AB80", +",_ c #FABF9E", +"'_ c #F78F58", +")_ c #F7894D", +"!_ c #FBCBB0", +"~_ c #F9B289", +"{_ c #F89963", +"]_ c #FBD1B8", +"^_ c #FAC3A1", +"/_ c #F26826", +"(_ c #0E0D0D", +"__ c #F3824B", +":_ c #F59768", +"<_ c #FACCB5", +"[_ c #F58F5D", +"}_ c #F7A982", +"|_ c #F6945E", +"1_ c #F47C3B", +"2_ c #F58346", +"3_ c #F58347", +"4_ c #F47E3E", +"5_ c #F8A779", +"6_ c #FCD6C0", +"7_ c #F58448", +"8_ c #FDD8C0", +"9_ c #514F50", +"0_ c #201C1C", +"a_ c #393537", +"b_ c #353333", +"c_ c #565454", +"d_ c #F76D2A", +"e_ c #F69D72", +"f_ c #FAC7AA", +"g_ c #FBCAAF", +"h_ c #F79864", +"i_ c #F69059", +"j_ c #F8945E", +"k_ c #F79560", +"l_ c #F8A97E", +"m_ c #FDC9A9", +"n_ c #FDD3B8", +"o_ c #FDE0CC", +"p_ c #151012", +"q_ c #AB4F23", +"r_ c #421907", +"s_ c #403028", +"t_ c #DD5617", +"u_ c #FEEBE1", +"v_ c #F06420", +"w_ c #F6925C", +"x_ c #FBC39F", +"y_ c #FDC3A0", +"z_ c #FC702D", +"A_ c #FF6B21", +"B_ c #FE6A25", +"C_ c #8D3B15", +"D_ c #0B0301", +"E_ c #411B0A", +"F_ c #EB6222", +"G_ c #FF6E25", +"H_ c #F2621F", +"I_ c #F8B391", +"J_ c #F16320", +"K_ c #F6905A", +"L_ c #F79660", +"M_ c #F8A678", +"N_ c #FCD9C5", +"O_ c #F9A06E", +"P_ c #F8965F", +"Q_ c #FCD9C3", +"R_ c #FEF6F3", +"S_ c #FCBF98", +"T_ c #F9BA9B", +"U_ c #FD631A", +"V_ c #FF600F", +"W_ c #C4BAB4", +"X_ c #252627", +"Y_ c #622910", +"Z_ c #FF661C", +"`_ c #FF9864", +" : c #F0550B", +".: c #F8B693", +"+: c #F5864B", +"@: c #FCDBC8", +"#: c #FCD2B9", +"$: c #F89E6C", +"%: c #F9A270", +"&: c #F8A070", +"*: c #F9B288", +"=: c #FAC3A2", +"-: c #F9B790", +";: c #FAAF81", +">: c #FAB183", +",: c #F3804A", +"': c #F48A56", +"): c #D9D7D7", +"!: c #A5958D", +"~: c #FAC7AC", +"{: c #F59667", +"]: c #FAC4A9", +"^: c #F8AF85", +"/: c #F7864A", +"(: c #F79057", +"_: c #F7925A", +":: c #FABE9C", +"<: c #FCDECA", +"[: c #FBD1B6", +"}: c #FBCBAB", +"|: c #FCBF9A", +"1: c #FEE9DB", +"2: c #F7AF8C", +"3: c #CAC9C8", +"4: c #121110", +"5: c #201E1E", +"6: c #F3F2F1", +"7: c #FAC5AA", +"8: c #F6A379", +"9: c #FDE1D2", +"0: c #F9B38B", +"a: c #F9A77C", +"b: c #FAB791", +"c: c #FEF7F4", +"d: c #F99E6E", +"e: c #FBD5BE", +"f: c #F8AF82", +"g: c #FBCAAB", +"h: c #F9BD9F", +"i: c #F3793F", +"j: c #F69667", +"k: c #FCD9C7", +"l: c #A2A0A0", +"m: c #817F7F", +"n: c #F58A56", +"o: c #F37D44", +"p: c #F8935C", +"q: c #F89B66", +"r: c #F8AF83", +"s: c #F8A978", +"t: c #FAAF82", +"u: c #FEF3ED", +"v: c #F9BFA1", +"w: c #F05E17", +"x: c #5D5B5A", +"y: c #F3F2F2", +"z: c #F48854", +"A: c #F2793F", +"B: c #F69E74", +"C: c #FBC8AB", +"D: c #F89F6D", +"E: c #F9A97B", +"F: c #F9BC94", +"G: c #FCD9C4", +"H: c #FCD9C2", +"I: c #FDE9DF", +"J: c #FDF1E9", +"K: c #E0ECF2", +"L: c #0A161D", +"M: c #959493", +"N: c #FAC0A3", +"O: c #F8AC85", +"P: c #FCE1D4", +"Q: c #FBD4BF", +"R: c #FBCCB0", +"S: c #FAB690", +"T: c #FAC7A8", +"U: c #F8A877", +"V: c #F7A57B", +"W: c #F48E5E", +"X: c #F96E2B", +"Y: c #FF8B4B", +"Z: c #70442E", +"`: c #302E2D", +" < c #F3783B", +".< c #FCDECB", +"+< c #F8B08B", +"@< c #FF6417", +"#< c #E0C4B6", +"$< c #020507", +"%< c #D4DEE2", +"&< c #F26927", +"*< c #FEA579", +"=< c #545352", +"-< c #7E7A78", +";< c #FFA46D", +">< c #F25A13", +",< c #F9B998", +"'< c #FACDB7", +")< c #FBCBB2", +"!< c #F3783C", +"~< c #B8BBBC", +"{< c #2E383E", +"]< c #FAC2A8", +"^< c #EF570D", +"/< c #FFF4E7", +"(< c #F68651", +"_< c #150400", +":< c #F37F47", +"<< c #F5621D", +"[< c #5A250E", +"}< c #AAA9A9", +"|< c #F7AB86", +"1< c #F6A178", +"2< c #A54A20", +"3< c #653F2D", +"4< c #FFAE7B", +"5< c #F2773B", +"6< c #F6A57F", +"7< c #FCE2D5", +"8< c #F16622", +"9< c #F9BB9C", +"0< c #F8B08D", +"a< c #FF8143", +"b< c #F0FCFF", +"c< c #000408", +"d< c #260500", +"e< c #FF6419", +"f< c #FBD0B9", +"g< c #FFB184", +"h< c #270800", +"i< c #EFAC8B", +"j< c #EF580F", +"k< c #F68149", +"l< c #FF6C20", +"m< c #61280F", +"n< c #C9C7C7", +"o< c #FAC1A5", +"p< c #FAD1BB", +"q< c #F05913", +"r< c #9E4218", +"s< c #916D5D", +"t< c #FF600E", +"u< c #F7AC85", +"v< c #FCE5D9", +"w< c #D24D10", +"x< c #55230D", +"y< c #F46623", +"z< c #F59261", +"A< c #F9C7AF", +"B< c #F3834C", +"C< c #FCE2D3", +"D< c #FFBF9C", +"E< c #090909", +"F< c #240F06", +"G< c #FF6D25", +"H< c #F7631D", +"I< c #F16F31", +"J< c #332E2B", +"K< c #EC5D1C", +"L< c #FF8549", +"M< c #F5915F", +"N< c #FFFCF8", +"O< c #F37E46", +"P< c #FFFFF8", +"Q< c #631500", +"R< c #CDA795", +"S< c #F7AE88", +"T< c #ECEBEB", +"U< c #FFE8D0", +"V< c #9E4116", +"W< c #979494", +"X< c #FCD7C4", +"Y< c #F26E2D", +"Z< c #1B1919", +"`< c #2A2D2E", +" [ c #FCD5C1", +".[ c #EF5206", +"+[ c #D8D2CF", +"@[ c #596267", +"#[ c #F4601A", +"$[ c #F48B56", +"%[ c #F48A57", +"&[ c #F68751", +"*[ c #B3B3B4", +"=[ c #D0B5A8", +"-[ c #EF5A11", +";[ c #F9C0A4", +">[ c #F7AD87", +",[ c #FEF7F0", +"'[ c #060404", +")[ c #1C0600", +"![ c #FA6924", +"~[ c #474748", +"{[ c #110704", +"][ c #FF6213", +"^[ c #333231", +"/[ c #D95A20", +"([ c #FF6C25", +"_[ c #FFF7F2", +":[ c #D6D6D7", +"<[ c #943E17", +"[[ c #FD6A24", +"}[ c #F7A47A", +"|[ c #F16D2C", +"1[ c #F1611C", +"2[ c #F26C2A", +"3[ c #71767A", +"4[ c #993F16", +"5[ c #FF6D20", +"6[ c #FBBD9E", +"7[ c #F27439", +"8[ c #F65E17", +"9[ c #FF6A1C", +"0[ c #6F7477", +"a[ c #FF6C27", +"b[ c #F36523", +"c[ c #FFD7B8", +"d[ c #B7B8B8", +"e[ c #4A5358", +"f[ c #F15F19", +"g[ c #F56420", +"h[ c #E86123", +"i[ c #0E0501", +"j[ c #4B1C08", +"k[ c #F7A57C", +"l[ c #FBCFB7", +"m[ c #F9C5AB", +"n[ c #FDF0E7", +"o[ c #F0E8E3", +"p[ c #000102", +"q[ c #020201", +"r[ c #E8E6E6", +"s[ c #FF7227", +"t[ c #E55E20", +"u[ c #652A11", +"v[ c #B46139", +"w[ c #F8560A", +"x[ c #FD9C6C", +"y[ c #3B3939", +"z[ c #F6A177", +"A[ c #B3B4B5", +"B[ c #2A1E1A", +"C[ c #F27235", +"D[ c #F3824C", +"E[ c #96877F", +"F[ c #E7E6E6", +"G[ c #2B2A2A", +"H[ c #302E2E", +"I[ c #F27032", +"J[ c #EE4600", +"K[ c #F8AD88", +"L[ c #FAC3A7", +"M[ c #FAC2A5", +"N[ c #FDEAE0", +"O[ c #FF5D0F", +"P[ c #E35F21", +"Q[ c #0D0502", +"R[ c #585756", +"S[ c #4A4949", +"T[ c #787474", +"U[ c #7E7D7D", +"V[ c #F7A67D", +"W[ c #F0601A", +"X[ c #FDE8DE", +"Y[ c #F8B28E", +"Z[ c #702E11", +"`[ c #686665", +" } c #AE6B4A", +".} c #1A0100", +"+} c #765747", +"@} c #B7B6B4", +"#} c #BEBDBD", +"$} c #F48953", +"%} c #F16B29", +"&} c #F3824A", +"*} c #FF691F", +"=} c #E6804F", +"-} c #1E272C", +";} c #2D2C2C", +">} c #91999D", +",} c #CA5C29", +"'} c #EE5B18", +")} c #EF6322", +"!} c #AD4211", +"~} c #222221", +"{} c #0E0502", +"]} c #0B0402", +"^} c #EBE6E5", +"/} c #F27132", +"(} c #FFD9C4", +"_} c #AD400D", +":} c #F6996A", +"<} c #F47F46", +"[} c #F7A277", +"}} c #FB5E13", +"|} c #FF6F25", +"1} c #A94619", +"2} c #210D05", +"3} c #596063", +"4} c #FF5C08", +"5} c #FAC5AB", +"6} c #FDEDE5", +"7} c #FDE4D8", +"8} c #FA6018", +"9} c #FF5F0E", +"0} c #ED8959", +"a} c #90989D", +"b} c #474747", +"c} c #190A03", +"d} c #0A0000", +"e} c #2D0000", +"f} c #807975", +"g} c #FAFAFA", +"h} c #FFF6E3", +"i} c #F4F3F3", +"j} c #EE4E00", +"k} c #FAD2BD", +"l} c #F69F75", +"m} c #FFBF95", +"n} c #FFAC7B", +"o} c #FFF0DD", +"p} c #858484", +"q} c #363434", +"r} c #F05D15", +"s} c #FBDAC9", +"t} c #FBDCCC", +"u} c #FCD8C6", +"v} c #F26C2C", +"w} c #F3773A", +"x} c #EF4B00", +"y} c #FACDB4", +"z} c #F8AE89", +"A} c #FDF1EB", +"B} c #F69869", +"C} c #F9B897", +"D} c #F16C2D", +"E} c #F9BFA0", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ # $ . . . . . . . . . . % & . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * = - . . . . . . . ; > , ' . . . . . . . . . . ) ! - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ~ { ] . . . . . . . ^ / / ( . . . . . . . . . . _ : < . . . . . . . . . . . [ } | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 3 . . . . . 4 5 6 . . . . . . . . 7 8 . . . . . . . . . . . 9 0 . . . . . . . . . . . a b c d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e : f } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . g h i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 : j k . . . . . . . . . . . . . . . . . . . . l m n o . . . . . . . . . . p q . . . . . . . . . . . . . . . . . . . . r s t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . u v p . . . . . w x y . . . . . . . . . . . . . . . . . . . . z A B C . . . . . . . . . i k D E . . . . . . . . . . . . . . . . . . . F G H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I J x . . . . . . . . . . . . . . . . . . . . . . . . . . . . K ! L M . . . . . . . . . N c O P . . . . . . . . . . . . . . . . . . . Q R S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T ] U . . . . . . . . . . . . . . . . . . . . V W X . . . . . . Y Z . . . . . . . . . . . ` ] .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +.. . . . . . . . . @.#.. . . . . . . . . $.%.&.*.=.. . . . . . . . . -.;.>.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,.'.).!.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ~.{.. . . . . . . . . . . . . . . . ].^./.(._.. . . . . . . :.<.[.<.D }.. . . . . . . |.1.2.3.4.. . . . . . . . . . . . . . . . 5.6.. . . . . . . . . . . . . . . . . . . . 7.8.9.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a.b./ c.. . . . . . . . . . . . . . d.^.<.e.f.g.. . . . . . . h.i.[.<.j.. . . . . . . k.*.e.[.j 6 . . . . . . . . . . . . . . . l.*.1.m.. . . . . . . . . . . . . . . . . . . . n.o.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p.j 2.$.. . . . . . . . . . . . . . q.r.[.[.s.t.. . . . . . . u.v.w.x.y.. . . . . . . z.r.[.[.A.B.. . . . . . . . . . . . . . . C.c *.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Z @ m E.. . . . >.F.G.H.. . . . . . . k A.I.*.J.. . . . . . . . q K.o . . . . . . . . . L.M.&._ o . . . . . . N.O.D P.Q.. . . . . R.S.. . . . . T.U.. . . . . . . V.W.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X.Y.w.Z._ `.. . . . . . 8 +.+l.. . . . . . . . . . . . . . . ++@+. . . . #+$+%+&+. . . . . . . , A.<.*+=+. . . . . . . . . . -+;+>+,+'+. . . . . )+!+~+{+. . . . . . . . . . . . . . ]+^+. . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . /+(+[.[.f._+. . . . . . . . . . . . . . _.. . . . . . . . . :+c :.<+. . . . . . . . . . . . . U.:.e.[.i.[+. . . . . . . . . . }+|+1+2+3+4+. . . . Q 5+'+6+. . . . . . . . . . . . . . 7+8+9+. . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0+a+. . . . . . . . . . . . < b+[.[.*+c+. . . . . . . . . . . . % d+k e+f+. . . . . . g+2.<.<.h+i+. . . . . . . . . . . . . # I.[.j+k+. . . . . . . . . . l+;+1+m+n+o+. . . . . p+}+q+. . . . . . . . . . . . . . r+s+t+. . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . u+v+w+. . . . . . . . . . . . x+y+(+k ^+. . . . . . . . . . . . z+f.<.A+v.B+. . . . . C+B [.[.j D+. . . . | E+F+G.. . . . . G+H+I+J+3 . . . . . . . . . . K+L+M+N+O+P+. . . . . . . . . . . . . . . . . . . . . . Q+R+. . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E+! G.. . . . . . . . . . . . . S+T+U+. . . . V+W+( . . . . . . X+i.[.[.f Y+. . . . . Z+h+e.<./.X . . . ]+`+A. @b+; . . . . . . .@. . . . . . . . . . . . . +@@@#@$@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . %@. . . . . . . . . . . . . . . . . . . . &@v+w.*.*@. . . . . =@A.[.e.-@;@. . . . . . >@,@'@)@. . . . !@~@{@]@^@/@. . . . . . (@P+. . . . . . . . . . . . . . . . . . . . . . . _@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -+:@Z . . . . . . . . . . . . . . H+i.[.e.:.<@. . . . [@}@|@'@1@2@3@4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@i@j@k@l@. . . . m@h.1.v+l.. . . . . . . . . . . . . . . . . . . . n@o@p@q@. . . . . . . 9+r@s@. . . . . . . . . . . . . t@. . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 u@X+I+v@. . . . . . . . . . . . w@:.<.[.[.r.x@. . . . y@z@A@B@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@D@E@F@G@H@I@J@K@u@L@. . . . . . M@N@. . . . . . . . . . O@P@Q@R@S@T@. . . . . _.U@V@W@X@. . . . . . . . . . . Y@Z@`@. . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . #A.[.<.D H.. . . . .#+#@#. . . . . ##$#I.%#&#. . *#=#C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@-#;#>#,#'#. . . . . )#!#~#{#% . . ]#. . . . . ^#R /#(#9._#. . . . . :#<#[#}#|#. . . . . . . . . . . 1#2#2#. . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3#4#5#. . . . . . . . 6#s.[.[.H+7#. . . 8#L A v+9#. . . . . 0#a#b#c#d#C@C@C@C@C@C@C@C@C@e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#F@t#u#v#C@C@C@C@C@C@C@C@C@C@C@w#x#. . . y#z#A#3+B#R . C#C@D#. . . . E#F#G#H#I#J#. . . . . . a t+% . . . . . . . . . . . . K#L#!.. . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K L M#3.. . . . . . . . u.I+N#, O#. . . . k i.[.<.v.Y . . . . P#Q#R#C@C@C@C@C@C@C@S#T#U#V#W#X#|@Y#. . . . . Z#`# $.$. . . . . . . +$@$#$$$C@C@C@C@C@C@C@C@C@%$&$*$=$-$3+;$>$. C@C@C@,$. . . . '$)$!$~$. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . {$: y+j+. . . . . . . . . ]$B.^$i . . . /$:.e.[.[.1.y . . ($_$C@C@C@C@C@C@:$<$[$. . . }$|$[.[.[.A 1$. . . 2$L > j c 3$. . . . . . . . . . . 4$5$6$C@C@C@C@C@C@C@7$8$9$0$a$b$. c$C@C@C@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H.d$0+. . . . . . . . . . . . . . . . . e$f$<.g$h$. i$j$C@C@C@C@C@k$l$m$l@n$o$. . . p$j [.[.[.A.6 . . . q$g$[.[.<.D r$. . . . q+s$5#. . . . . . . t$u$C@C@C@C@C@C@C@v$w$. . . C@C@C@x$y$. . . . . . . . . . . z$A$B$. . . . . . . . o.C$D$. . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y E$F$G$H$I$C@C@C@C@C@J$K$L$M$N$[.O ^.O$. . P$f [.[.[.w.Q$. . . `+<.[.[.[.$#R$. . . S$^.(+y+T$Y . . . . . . . . U$V$C@C@C@C@C@C@W$X$. Y$C@C@C@Z$`$. . . . . . . . . %.%+%@%#%. . . . . . $%{+%%&%. . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . *%C@C@C@C@C@=%-%. . ;%B [.[.[.*+P$. . . L.w.B , # Q.. . . >%g$[.[.[.D r$. . . e+i.[.[.A.,%. . . . . . . . . . . '%)%C@C@C@C@C@!%~%{%C@C@]%^%Q.. . . . . . . /%(%_%:%<%[%. . . . . . M@r+}%|%. . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1%2%]+. . . . . . 3%/.x+4%. . . . 5%6%C@C@C@C@7%8%. . . . p.B [.[.[.w.R.. . . Q.9%0%a%0+. . . . <@b%> f$Y.c%. . . c.h+[.[.[.<.d%. . . . . -+/$. . . . . . e%f%C@C@C@C@C@g%C@C@C@h%i%. . . . . . . j%k%_%:%_%V@. . . . . . . M@l%m%. . . . . . . . . . E.n%. . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . | o%. . . . . . . p%n 1./@q%. . . . E f <.I._ r%. . s%C@C@C@C@t%u%v%. . . . . w%I+<.[.O v.x%. . . . . . . . . . . . . x%y%z%w%. . . . A%P e.[.[.i.B%. . . . C%D%E%F%G%. . . . . . . H%C@C@C@C@C@C@C@C@. . . . . . . . . I%J%K%<#L%. . . . . . . . . . . . . . . . . . . 0+M%N%O%. . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . >.: / P%. . . . . . Y.O [.I.Q%. . . . R%<.[.[.(+S%..T%C@C@C@C@U%V%W%y+k X%. . . . Y%`+c Z%`%. . . . . . . . . . . . . . . . . . . . . . . <+(+I. &:..&. . . +&@&#&$&%&&&/$. . . . . *&=&-&C@C@C@C@C@C@C@;&. -+>&,&. . . . . 0.z$_.. . . . . . . . . . . . . . . . . . . . ..'&)&!.. . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . !&_ ! ~&. . . . . {&v+[.[.<.j.. . . . ]&s.[.[.^&/&C@C@C@C@(&_&:&<&e.[.O [&. . . . . . }&. . . . . . . . |&1&2&3&. . . . . . . . . . . . . . 4&5&6&7&. . . . 8&9&$&0&a&b&c&. . . . d&C@C@C@C@C@C@C@C@C@C@C@e&f&g&h&i&j&. . . . . . . . V.k&l&. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . Y m&. . . . . . . n&o&I.(+0%. . . . q L p&q&;#C@C@C@C@r&. . *.<.[.[.[.r.s&. . . . . . . . . . . . . *@t&A.A.t&u&. . . . . . . v&w&. . . . . . . . . . . . x&b&$&0&a&y&z&. . . . A&C@C@C@C@C@C@C@C@C@C@C@B&C&D&E&F&G&. . . . . . . H&[%r+I&o.. . . . . . . . -+J&G&K&. . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p w+L&U . . . . . . M&N&O&C@C@C@C@P&. . . Q&i.[.[.[.c R&. . . . . o :@x%. . . . S&{ [.[.[.e./.T&. . . . p U&k Y.(.V&. . . . . . . . . . W&8&#&$&z#E%!.. . X&Y&Z&`& *.*+**&@*#*C@C@C@C@C@$*%*E&&***. . . . . . =*-*;*>*,*'*. . . . . . . . )*!*~*J&. . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . {*C@C@C@]*. . . . . ^**.O i.w./*. . . . (*_*1.(+/@:*. . . <*j [.[.[.[.f.[*. . . . }*&.<.<. @R%|*. . . . . . . . . . 1*2*3*4*5*. . ^#6*7*8*9*0*. . . . . a*b*c*C@C@C@d*e*f*j%. . . . . . /$g*;*>*,*r+. . . . . . . . % h*i*l%. . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . j*C@C@C@k*. . . . . . . R.l*Z%m*. . . . . l*M#[.[.<.{ n*. . 4&f.[.[.[.[.Z.F.. . . x@1.[.[.[.[.j+6 . . . . . . . . . . . . ... . . . o*p*q*3+r*s*t*. . . . . . . u*v*C@w*x*,&. . . . . . . . y*z*'*q@L#. . . . . . . . . A*0+. . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B*C@C@C@C*. . . . . . . . . . . . . . . . s&1.[.[.[.[. &d+. . q D <.[.[.<.v+D*. . . /+M.[.[.[.[.s.E*. . . . . . . . . . . . . . . . . #&B#q*3+r*F*G*. . . . . . . . . H*I*J*. . . . . . . . . . K*n.L*. . . . . . . . . . . . . . . . . . . . . M*N*O*. . . . . . . ", +". . . . . . . . . . . . . . . . . . . . |&7#. . . . . . R&P*# u&. . . . . . i Q*R*S*. C#C@C@C@T*. . U*& . . . . . . . . . . . . . V*$#[.[.[.[.O (.. . . P$v+w.w.v+z . . . . k.t&[.[.[.[.j w+. . . . W*X*x&Y*q+. . . . . . . . #@%&q*3+Z*`*L%. . . . . . . . . . . . . . . . O*J# =.=. . . . . . . . . . . . . . . . . . . . . . . . . +=@=#=$=. . . . . . . ", +". . . . . . . . . . . . . . . . . . . c%c : %=. . . . . # M#A+(+=.. . . . . B%*+&=,#*=C@C@C@==. -=h.r./.;=u . . . . . . . . . . . r%d%<.[.[.[.j >=. . . . @#1$1$O$. . . . . . ,=, <.e.s.^.'=. . . )=!=~=)={=]=L*. . . . . . . . ^=/=(=_=:=. . . . . . . . . <=[=}=|=. . . . 1=6+2=6+3=. . . . . . . 4=k&t+i . . . . . . . . . . . . . . 5=6=-+. . . . . . . ", +". . . . . . . . . . . . . . . . . . . n&Z.t&7=. . . . 8=*.[.[.O O#. . . . :@y+[.9=0=C@C@C@a=. . Y.I.[.[.f.b=. . . . . c=( d=. . . . e=c g$I.f.@ f=. . . . . . . . . . . . . . . E k I+;=(@. . . g=h=i=j=k=l=m=m+. . . . . . . . . q+n=. . . )*o=p=. . . . q=r=G#l+s=t=. . )*u=_%:%:%v=w=. . . . . E#x=y=z=&%Q+. . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . #.6#A=. . . . . p D O e.f.p.. . . . R$h+B=C=C@C@C@D=. . E=r.[.[.[.<.e+. . . . h `+(+t&F=G=. . . H=I=<.J=^+. . . . . . . . . . . . . . . . . . 1%. . . . . K=L=i=j=k=l=M=N=. . . . . . . . . . . . . O=P=r*Q=R=. . t G S=/#(#E&T=L*. Y@D&_%:%:%U=V=. . . . . i*W=X=Y=Z=`=. . . . . . -V.0+. . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . .-Y.I++->.. . . . . @-#-C@C@C@$-. . . 2$/.e.[.[.A+# . . . 3#h+<.[.[.j+:+. . . . . . . . . . . . . . . . . |&%-Q*&-. . . . . . . . . . . *-=-i=j=k=l=--;-. . . . . . . . . . . . >-{#1+m+r=,-'-. )-!-S=/#(#E&s=R+. . ~-{--*W@Y=. . . . . . ]-^-X=Y=z=/-. . . . . (-~*_-:-. . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M@. . . . . . . <-C@C@C@[-. . . . . u+, A+i.H+$.. . . O#O [.[.[.e.c }-. . . . . . . . . . . . . . 1%|-y+j &.*. +. . . . . . . . . . !.1-@&j=k=M=2-3-. . . ,.. . . . . . . . )#4-1+m+r=5-l+. ..G 6-/#(#7-I#. . . . z$C$0.. . . . . . . i H&8-&%9-... . . . . 4=0-a-b-. . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C@C@C@e#. . . . . . . c-d-L.e-. . . . r.A+[.[.[.[.r.f-. . . . . . l d.. . . . . . g-f$[.[.[.[.(+h-. . . . . . . . . . $ i-h=!=!=j-. . k-l-m-6*n-. . . . . . o-p-1+m+r=q-r-. . l&s-t-u-v-w-. . . . . . . . . . . . . . . ..R+P+. . . . . . . . x-y-K#. . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . z-_+. . . . . . . . . . . . . . . A-S.B-. . v#C@C@C@C-. . . . . . . . . . . . . . . D-B [.[.[.<.:.#+. . . . E-x P *.Y.F-. . . | %.e.[.[.[.[.<./@. . . . . . M@. . . . . N@{.. . . G-H-%&I-J-F%K-. . . . . L-F 3+M-n+N->.. . . . Y@Y@. . . . . . . . . . . . K#. . . . . . . . . . . . . . . . . . . . . . . . . . O-P-0+. . . ", +". . . . . . . . . . . . . . U*: b.Q-. . . . . R-( . . . . . . S-(+, L T-U-C@C@C@V-. . . . . . . . . . . . . . . . 8 u@f$I.M#x.W-. . . . . X-j <.[.<.2.Y-. . Z-A [.[.[.[.[.[.*.`-. . !.%& ;.;+;@;. . . . . . . U.#;$&0&a&$;%;&;]+. . . . . {$*;=;-;* . . . . . . . . . . . . . . . . . ;;[%>;,;% . . . . . . . . . . . . . . . . . . . . . . . Q.';P-);. . . ", +". . . . . . . . . . . . . . . =@6&Q+. . . . !;/.y+~;^+. . . u.A [.[.{;];C@C@C@^;. . . . . . d=/;. . . . . . . . . . N.E (; +S$. . . . . ^*M.[.[.[.[.e.*./;. _;/.[.[.[.[.[.<.D . . 0+:;<;[;i-};|;};. . . . . . 1;@&$&0&a&$;$;2;.#. . . . . . . . . . v&3;4;5;G%. . . . . . . . . . . L*6;{+7;7+8;. . . . . . . ... . . . . . . . . . . . . . . . % 9;. . . . ", +". . . . . . . . . . . . . . . . . . . . . 0;*.[.[., W . . . a;w.[.b;c;C@C@C@d;. . . . . * j+H+y+P e;. . . . . . . . . . . . . . . . . . C s.[.[.[.[.[.f.f;. . g;g$[.[.[.[.> E . . 7*h;=-i;i-D%j;k;l;. . . . . 3 =-$&0&a&$;%;&;]+. . . . . . . . . K#m;n;o;p;q;)+. . . . . . . . . . n.r;s;>*t;u;v;. . . . O*w;x;y;t . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . z;A [.[.f$A;. . . U.B;A.C;D;C@C@C@E;. . . . . D-j [.[. @P . . . . F;F-%-G;. . . . . . . . . . H; &[.[.[.[.[.f.G.. . x%Y.*+g$M#(+B . . . I;J;=-i;i-D%j;K;L;. . . . . . M;H-N;0&J-O;P;. . . . . . . . . . Q;R;s=S;F&T;U;. . . V;W;X;%%X@. . x-Y;Z;>*>*`;. . . . . >x;|=.>h*U+. . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . -+[&Z.j+L q.. . . . 2$+>@>C@C@C@#>$>%>&>. . . v+<.[.[.[.r.q%. . *>P j j c =.. . . . . . . . . f;> [.[.[.[.[.1.=>. . . U+->;>>>.&. . . . ,>J;=-i;i-D%j;K;'>. . . . . . . )>F%!>'>~>. . . . . . . . . . . {>M-s=S;F&]>^>. . />(>_>:><>E&A*. . 1#-*I&[>x-. . . . . }>|>1>1>2>M*. . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . r%*>3>~&. . . . . . . 4>C@C@5>6>P*i.*.3#. . /@<.[.[.[.P 7>. s&%.e.[.[.e.c G;. . . . . . . . l Y.M#e.[.<.> 8>. . . . . . . . . . . . . 9>0>=-i;i-D%j;a>b>. . . . . . . . . . . . c>B#z#d>e>. . . . . . T.f>g>S;F&R h>. . i>j>k>-*l>6+W.. . . -+E.... . . . . . A$m>|=n>h*,.. . . . . . >.:#. . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o>C@C@C@p>N$[.[.i.# . . $+*.O i.o&n&. . 4&f.[.[.[.[.j m.. . . . . . . . . (*d+c h+`+q>. . . . . . . r>s>t>u>v>w>x>y>z>A>i;i-};B>C>. . . . . . . . . . . . D>E>F>7*7*G>H>. . . . . . Q;I>^>J>R@. . . K>U=k>-*l>L>M>. . . . . . . . . . . . A*N>O>2#P>. . . . . . Q>:-R>Q+. . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C@C@C@S>T>[.[.[.<./@. . . Z+(.X-=.. . . 9%f.[.[.[.[.&.U>. . . . v&V>3&4.. . . | W>M@. . . . . . . X>Y>Z>`> , ,.,+,. M@@,#,$,%,&,m%. A**,@&=,0&o=. . . . . -,;,>,q*q*3+z#Y . . . . . . 0+/%t . . . . 8;'.k>-*,,U@l&. . . . . . . . . . . . . . . . . . . . . . . ',),b-!,. . . . . . . . . . ", +". . . . . . . . . 0+Z . . . . . ~,k ;.. . . . . . . . . {,. . ],C@C@R#. ^, @[.[., T . . . . . . . . . . /,/@e.[.[.e.:.(,. . . 1$`+A (+:._,. . . . . . . . . . . :,<,[,},},|,1,2,3,. . . l N.#+. . v&4,5,)=M=--6,7,. . . P+F%,+>,q*q*3+%;8,. . . . . . . . P+9,. . . . :>8.(%0,1;. . . . . . . . . . . . . . . . . . . . . . . . x-a,L#. . . . . . . . . . . ", +". . . . . . . . . Q&! b,. . . c,:.I.P . . . . . . . 0 P *.d,e,C@C@C@,$. f,@ r.Y.g,]+. . . . . . . . . . . h,J > > I+6.. . . 3&:.<.[.[.<.f i,. . . . . . . . . . j,k,},},l,m,n,C@o,. . . . . . . . p,8&j=k=l=l=q,#;r,. . |#s,;,>,q*q*3+N;9 . . . . . . M@t,P@u,v,t . . . r%;;0+. . . w;z*I&1;. . . . . . . . q+;;w,. . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . x._ &@. . . % `+:.x,. . . . . . . [& @[.y,z,C@C@A,. . . . B,C,. . . . . . . . . . . . . . D*$+D,2%. . . . E, @[.[.[.[.<.:.d.. . . . . . . . . F,n,},l,G,. . . H,. . . . . . . p I,J,j=k=l=K,L,M,N,. . . O,2;p*q*A#P,Q,. . . . . . . q;R,F&S=S,r=. . . . . . . . T,U,r+{+I&z$. . . . . . K&W=<=V,',. . . . . . . . . . . . . . . % W,% . . ", +". . . . . . . . . X,p%. . . . . 0+Y,. . . . . . . r$/.[.Z,`,C@C@C@ '. . . . . . . . . . 8 S&H.. . . . . . . . . . . . . . .'P <.[.[.[.[.[.(+w%. . . . . . . . o,+'},[,@'. . . . . . . . . . . . % #'J,j=k=$'%'&'*'='-'. . . ;'y&y&y&>'. . . . . . . (*F#S;F&S=/#u-L%. . . . . . . 8;,'''s;)'^-. . . . . . |%|>1>1>!'/$. . . . . . . . ~'{']'^'/'. ('_':'. . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . h.<'B=['C@C@}'. . . . . . . . . . |'I+A /@1'. . . . v@X-%>3>v&. . . . . /.<.[.[.[.[.[.y+q.. . . . . . . . 2'3'},4'5'. . . . . . . . . . . . . 6'{=j=k=7'8'9'0'a'b'. . . . . E.. . . . . . . . . c'd'S;F&S=/#r=x-. . . . . . . e'z*''s;r+f'. . . . . . O>|>1>1>!*`-. . . . . . . . g'h'i'j'k'. v&l'v&. . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . o%m'n'C@C@C@a*. . . . . . . . . o'Y.<.[.<.Y.8#. . &*+i.i.f.%>. . . . . p'A.[.[.[.[.i.Y.. . . . . . . . . q'r'},4's'. . . . . . . . . . . . . t'u')=k=7'v'w'},x'y'. . . . . . . . . . . . . . . . s !-z'T;U;b$. . . . . . . . j&V@A'q@x=:#. . . . . . B'W=<=C'M%. . . . . . . . . D'E'},F'G'. . . . . . ", +". . . . . . . . . . . . . . . . . . . . C,v&. . . . . . H'C@C@I'. . H.3%4#J'a . . . =.f$[.[.[.j v@. |&y+[.[.[.[.2.K'. . . . L'@ f$A+<.s.D 3&. . . . . . . . . M'r'},4's'. . . . . . . . . . . . . . N'h=O'P'Q'w'},x'y'. . . . . . R'S'T't*U'. . . . . . V'W'R,X'. . . . . . . . . . . }&}&. . . . . . . . . L*Y'Z'. . . . . . . . . . D'E'},F'G'. . . . . . ", +". . . . . . . . . . . . . . . . . . `'O#/.u@ ). . . . .)C@C@C@a*. N.+)j+I.f.Q&. . . 4&> [.[.[.> z-. z-f.[.[.[.[.A.@). . . . . /$#)y+d-k+(,. . . . . . . . . . $)r'},4'%). . . . . . . . . . . . . . . . &)*)=)-)},x';). . . . . >),)')))!)~){). . ])^)/)(). . . . . . . _):):)<)[). . . . . . . . . . . . . . })|)^)1)2). . . . . . . 3)E'},F'4). . . . . . ", +". . . . . . . . . . . . . . . . . . 5)j [.A+u@G=. . . 6)C@C@7). . 8)f.[.[.[.2.9). . 9 b%M#i.M#0)x%. a)M.[.[.[.[.> y%. . . . . . . . . . . . . . . . . . b)c)n,},|,},n,|,d)|,l,e). . . . . . . . . . . -)f)g)h)|,},|,n,},|,1,i)j)k)l)m)n)o)p)q)r)s)t)u)C@v)w)w,. . 1)x)y)+'u)u)z)F,%)A). . . . . . . . . . B)C)D)3'u)3'D)E)F). . G)4'},n,|,},[,|,},|,|,H)I). ", +". . . . . . . . . . . y.H+D,. . . . j @[.[.*.J). . K)C@C@C@L). . B.B [.[.[.f.a%. . . 2$/*L.` <@. . M)`+I.[.[.O n x%. . . . . . . . . . . . . . . . . . N)x'1,|,},},},n,1,1,O)P). . . . . . . . . . . Q)4'1,|,},},},|,1,1,R)S)T)U)V)W)X)n)Y)Z)`) !n,},.!+!@!#!$!%!&!*!|,n,1,|,n,n,=!-!;!>!. . . . . . ,!},u)4'n,},},},n,4''!)!!!~!{!1,|,},},},[,1,1,1,&!. . ", +". . . . . . . . . . G=: O : t . . . ]!r.I.j+^!. . . /!C@C@(!. . . _!X+[.[.e./.S&. . . . . . . . . . . C,l**.H+Z%4%. . . . . . . . 2$S.~ :!. . . . . . . 7!8!9!V)0!n,},a!b!c!6!i'd!e!f!g!$!h!i!n,j!u)k!4'}!l!m!},n,n!o!p!. . . . o,q!=!},n,r!s![!m,t!},u!v!w!x!l,}!4'},},},6!}!}!}!7$. . ", +". . . . y!d%+-. . . . O#*.z!. . . . . A!B!C!d.. . D!C@C@C@E!. . . . =@t&O#P [ . . . . . . . . . . . . . . F!}-. . . . . . . . . G!I+> f.A O#H!. . . . . I!J!K!L!|!},|,M!N!O!P!Q!. . . . . . . . . % R!S!T!U!V!5!},6!W!X!O!Y!Z!. `! ~0!n,},},a!Z>.~+~@~#~$~%~&~*~=~-~s);~. . . >~,~'~},)~!~~~. . . . {~=!},n,]~^~/~(~_~6!O):~<~[~}~|~1~2~4'},6!3~4~5~O!6~... ", +". . . . 7~8~9~}&. . . w@5#:#. . . . . . . . . . . 0~C@C@a~b~/+. . . . c~d~1 . . . . . . . . . . . . . . . . E=e~f~{$. . . . . g~{ <.[.[.[.B h~. . . . . . . . i~r'},4'j~. . . . . . . . . . . . . k~#;M,l~m~n~w'},x'o~. . . . . p~q~r~n,},n,@'s~. . t~u~v~F&S=w~x~y~. . . . . . z~A~u!|,k!. . . . B~[!},n,C~D~[~. . . . E~F~. G~. . . H~E'},I~J~. . . . . . ", +". . . . . K~S+. . . . . . . . . . . . . . . . . . C@C@C@L~M~N~. . . . . . . . . . . . L*n*O~F!. . . . . q+F=1.w.2./@;.. . . . P~I.[.[.[.[.[.1.Q~. . . . . . . M'r'},4's'. . . . . . . . . . . . . R~=,j=k=7'v'w'},x'y'. . . . . . . S~T~}, ,U~. . . . s !-z'T;U;V~. . . . . . . . W~X~},F,Y~. . . Z~6!},`~ {.{#+. . . . . . . . . . . D'E'},+{@{#{${. . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . %{C@C@C@T>&{| . . . . (*w@. . . . . *{j.f M./@Q*. . . . ]&A.[.[.[.<.8~(,. . . Z%<.[.[.[.[.[.M.;.. . . . . . . M'r'},4's'. . . . . r'd)d)d)d)d)d)={-{;{j=k=7'v'w'},x'y'. . . . . . . >{T~},,{'{. . . . . ^-){R,W=. . !{~{{{]{^{/{({_{6!},+':{. . <{[{n,n,}{|{. . . . . . . . . . . . . D'E'},+{1{#{q+. . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . 2{C@C@3{4{G+. . . ~.(.c `+:*. . . L*L A+[.[.<.P S&. . 5{r.[.[.[.[.[.M#6{. . . (.O [.[.[.[.[.X+R$. . . . . . . M'r'},4's'. . . . . 7{6!1,1,1,1,1,8{9{0{a{k=7'v'w'},x'y'. . . b{$ c{. S~T~},+'d{. . . L-Q+. . . . e{f{F,@'O)F'g{}!}!6!},},+'h{. . i{z)},1,j{. . . . . . . . . . . . . . D'E'},F']{. . . . . . ", +". . . . . . . . . . . . . . . . . . . Y@. . . . C@C@C@k{. . . . l{/@I.[.<.t&m{. . u.M.[.[.[.[.A._,. . W+, [.[.[.[.[.i.S-. . . 2 2.[.[.[.[.i.Y.. . . . . . . . M'r'},4's'. . . . . 7$}!*!*!*!*!*!n{o{p{q{@&r{s{w'},x'y'. . t{&;9&u{V)r~n,},+'v{. R'w{x{d',,. . y{z{A{n,u!B{C{7!p)D{=!},},+'h{. . E{3'},6!F{. . . . . . . . . . . . . . D'E'},F'G'. . . . . . ", +". . . . . . . . . . . . . . . . . }-G{P H+H{. I{C@C@J{. . . . . K{A [.[.[.I.L{. . M{w.[.[.[.[.B N{. . O{M.[.[.[.[.[. @g$. . . . P{b+g$I.j u@4%. . . . . . . . M'r'},4's'. . . . . Q{R{|~|~|~|~|~S{T{. O@U{q~V{W{},x'y'. X{s,;,>,Y{Z{0!n,},+'`{E-P= ]Q,s=t,.]+]7$n,},x'@]#]$]%]&]*]=]=!},+'h{. -];]>]n,|,s!. . . . . Q+. . . . . . . . D'E'},F'G'. . . . . . ", +". . . . . . . . . . . . . . . . . <'M#[. &} . ,]C@C@']. . . . . s$%>[.[.[.I.L{. . )]/@e.[.[.[.A 1$. . M@D <.[.[.[.[.f !]. . . . . ~]{]O.]]| . . . . . . . . . M'r'},4's'. . . . . . . . . . . . . . . . . . ^]l,},x'/]. 4*J-,+>,Y{V)0!n,},+'(]_]:]5+Q,s=s=<][]}]},`>|]1]2]3]4]5]6]7]4'},+'8]9]0]a]b]|,},@'c]. . ..4+i*d]. . . . . . . e]E'},F'f]. . . . . . ", +". . . . . . . . . o%g]h-. . . . . Y.<.[.e.h]i]C@C@C@. . . . . . U+/@I.[.<.t&M{. . . %-c A.B A 6&. . . . a./@M#i. @f j]. . . . . . . . . . . . . . . . . . . . M'r'},4's'. . . . . . . . k]l]$&m]9,. . . . . n]l,},F'o]. y&4*p]&,Y{V)0!n,},+'(]q]M+5+Q,s=s=r]s]t]},,{u]v]s -*l>w]x]7!n,},+'y]z]A]B]C]D]},1,F'E]. F]G]H]I]K). . . . . . J]K]},}!L]. . . . . . ", +". . . . . . . . . M]A./@x@. . . . N]*+i.f.O]P]C@C@Q]. . . . . . . -=l*c `+:*. . . . . V>R]B.a). . . . . . 0 S]O#|-e-. . . . . . . . . . . . . . . . . . . . . M'r'},4's'. . . . . . . H-T]|;U]B>V]W]. . . . a=X]},|,F'Y]Z]`] ^&,Y{V)0!n,},+'`{*],+5-)#g>J>.^+^=!},`>@^#^%*$^%^&^*^=^},},+'8]-^;^>^,^'^n,},)^F'!^. ~^{^]^^^/^. . . . . (^_^},n,@':^. . <^[^. ", +". . 3&;=G+. . . . ,%}^/ A%. . . . Q.N{X+|^. 1^C@C@2^3^->m.4^. . . . . H!u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5^]]U>q.. . . . . . . M'r'},4's'. . . . . . C%6^i;i-D%j;7^1-(*. . . 8^@'},},1,9^0^a^b^c^Y&d^0!n,},+'e^. D$z'f^J>T@. g^Z>},},E'h^i^j^k^4!l^m^n,},+'h{. j%H&n^o^p^n,},1,[!q^r^B{s^|,3't^. . . . u^j'},},|,3'1,6!C@I). ", +". . ^,h+v^. . . . p ;.V+. . . . . . . . . w^C@C@C@3^x^w.f.R%/;. . . . . . . . . . . . . . . . . . . . . . . . . _;y^Z.I.Q*. . . . . U.B%(+f$j /.u&. . . . . . M'r'},4's'. . . . . . z^C>i;i-D%j;A^#;B^. . . . 7{|,},},n,n)X)C^D^E^F^G^T~},+'e^. . . . . . . . H^I^},},4'X~i)J^}!K^L^M^},+'8]. . . . . N^O^4'n,},[,1,|,},n,=!C@P^. . . . 9^6!},},n,1,1,[{. . ", +". . H=j]d=. . . . . . . . . . . . . . . . Q^C@C@R^S^T^[.[.M#;>. . . . . #+1%. . . . . . . . V>g~7 . . . . . . &-^.A.O @, L.Q+. . . E,M#[.[.[.e.h+K.. . . . . U^C@@'+'j{. . . . . i V^O'i;i-D%j;A^W^X^. . . . Y^z{_^Z^ ,}!x'`^. . . C@r' /C@./. . . . . . . . +/@/[{l,}! ,F''!#/. $/%/&/C@*/. . . . . . =/-/[{O)}! ,g{O);/>/,/. . . . . '/Y>s!`> ,*!F'C@... ", +". . . . . . . . . . . . . . . . . . . . . )/C@C@!/~/w.[.[.g${/. . . . q>`+I+p'. . . . . ++h.X+M.I+]/. . . . . h.i.[.[.[.[.f.^/. . E=H+[.[.[.[.[.O _*. . . . . //(/_/:/i;i-D%j;A^=-}/. . . . . |/1/2/3/4/5/6/. . . 7/8/8/9/I). . . . . . . . . . 0/a/b/c/d/e/. . f/g/h/i/j/k/l&. . . . . . l/m/n/o/w>p/q/r/s/. . . . . . <^s>t/J!u/v//~. . ", +". . . . . . . . . . . . . . . . . . . . C-C@C@C@. w/j.j A.v+^ . . . B.M.<.<.> n&. . . . h.I.[.[.<.*.x/. . . &-y+[.[.[.[.[.<.H+. . b,f [.[.[.[.[.e.H+}.. . . . y/z/A/B/C/% . . . . . D/[/i;i-D%j;E/F/* . . . . . G/H/I/J/K/. . . . . . . . L/M/Y@. . . . . . . . X.N/. . . . . . . . j)O/P/Q/,*'*... . . . . . . . . . . R/S/T/0+. . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . a=C@C@U/. . H.V/y^S&. . . U+W/<.[.[.e.:.3 . . X/y+[.[.[.[.g$Y/. . . Z/2.[.[.[.[.[.<.:.. . ~&r.[.[.[.[.[.i.p&. . . . `/ (.(+(@(I;#(d.. . . . . $(V^<;%(&(*({,. . . . . =(@&z#%&N;E%r . . . . . . ;'~#-(;(r=>(. . . . . ,(!-h&f*z$. . . . . . n.r;s;>*t;u;'(. . . . . . . . . . . . j%P>. . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . )(!(~({(](},^(. . . . . . . . /(/@e.[.[.e.c N.. . (((+[.[.[.[.I._(. . . K c e.[.[.[.[. @E,. . . X-I.[.[.[.[.(+:(. . . U'<([(}(|(1(2(3(4(. . . . . . 5(6(*,7(. . . . . . '$8(9($&0&a&0('>. . . . . '$a(b(1+m+c(l>. . . . {$d(R@E&E&e(l{. . . . . q+6;f(7;7+H&. . . . . . U'L#D$. . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . s!A{},},},t!g(h(. . . . . . . . I=f.<.<.j++-. . . U.^.<.[.[.[., F-. . . . ;>f.e.[.[.<.Y.i(. . . K :., B B r.j(. . . . k(l(m(}(|(1(2(n(o(r$. . . . . . . . . . . . . . . p(l-9($&0&a&q(l-K#. . . . r(F*s(1+m+t(Q=. . . . u(t-(#E&E&v((*. . . . . . 5(8+I&w(i . . . . . . 2#m>z=E.. . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . x(P*X%. . . y(k!},},},},},l,z(. . . . . . . . 0+q$P c ;={$. . . . !]:.B s.w.L.-+. . . . . =@*.w.M./@D,. . . . . !.2 x,q>A(. . . . . *-B(m(}(|(1(2(n(C(D(. . . . . . . . . . . . . . . 8,D%9($&0&a&J-/=. . . . . E({#s(1+m+F(G(. . . . j&!+l+H(k%I(. . . . . . . . . ... . . . . . . . z=~$O>(-. . . . . . . . . . . . . . . . . . . . ", +". . . J(K(. . . . . *{P j+L(. . . M(`>},},},},},|,n)N(4$. . . . . . . . d.{.. . . . . . . O(N{I y%w@. . . . . . . c.P(Q({$. . . . . . . . . . . . . . . . R(S(m(}(|(1(2(T(U(q+. . . }&W*V(D/@.. . . . . . . . '>)=#&W(a(H-'-. . . . . :#X(Y(Z(R;`(z$. . . . . w,}=v- _M@. . . . . . . . . . . . . . . . . . >.k&L#. . . . . . . . . . . . . . . . . . . . . ", +". . ._v+! +_. . . . R&: *.p.. . . @_F'},},},},},d)+{C@C@#_$_%_. . . . . . . . . . . . . . . . . . . . . . . . . . . . l &_g+( . . . . . . . . . . . . . . . *_=_m(|(1(-_;_>_. . . ,_;_*('_<;)_!_. . . . . . . . ~_{_E%-,]_. . . . . . . i ^_q;+&R'. . . . . . . . ... . . . . . . . . . . . ..O@p=. . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . ^+p&/_. . . . . . 2$Z/. . . . (~&!n,},},},},1,C@C@C@C@C@C@(_I{. . . . . a)__:_c'. . . . . . L'3&o . . . . . . . <_u@w.f.1.=@. . . . . . Z-[_>=}_]+. . . . |_1_2_3_4_5_. . . 6_7_J;=-i;i-};}('$. . . . . . . . |#G=. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8_`;'*9+. . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . 9_2,0_n,1,~(a_5$b_C@C@C@C@C@C@C@c_]). d_b+A.> u@3 . . . . &@n (+t&4#. . . . . . k i.[.[.[.(+e_. . . . #)/.j A.T^h.8 . . . . 8 f_g_w-. . . . h_i_j_=-i;i-D%k_l_. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ~$m_M>... . . . n_A]{+o_. . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . {{A{u)p_f]. . . . q_r_C@C@C@C@C@C@s_t_c;^@[.j ; . . . u_L <.[.[.o&%-. . . . G;b+[.[.[.[.I.v_. . . }_r.[.[.[.[.s.O#. . . . . . . . . . . . I;w_j_=-i;i-D%};j;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . x_X;y_6+Z;. . . . u M>1;... . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . z_A_B_C_D_C@C@C@C@C@E_F_G_H_O.. . . I_M.[.[.[.I.J_. . . . 0;b+[.[.[.[.I. &. . . B! @[.[.[.[.[.r./;. . . . . . . . . . . U]K_j_=-i;i-D%L_M_. . . . N_O_P_~=)>. . . . . . . . . . . . . . . . . j&N>Q_0+. . . . . R_i>l>_%:%S_X@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . '=->#.. . . . . . . . . . . T_W/&=U_V_W_X_C@C@C@C@C@Y_Z_`_. . . =>h+[.[.[.g$` . . . . }./@A+[.[.[.M.a%. . . :<.[.[.[.[.[.M..:. . . . . . . . . . . n-+:J;=-i;i-};+;@:. . . #:h=$:%:&:H-*:. . . . . :#=:N+-:O@. . . . . ,.;:!-n;>:^+. . . . |#S@,,_%_%J%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . `+T^3.#+. . . . . . . . . . . V>,:':| . . ):j$C@C@C@C@C@!:. . . . Z.Z.i.s.v+~:. . . . . - ^.Z.f$b+P~. . . . J+O [.[.[.[.[.y+T&. . . S${:G.]:. . . . . ^:/:(:A>_:[/::. . . . =-$:l=q,9($&2*$ . . . . N;X(F*A#`*<:. . . . [:s-S;F&p;}:. . . . . 9+0,|:H(1:. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . #+_ j+: L*. . . . U*2:7>. . . . . . . . . . . . 3:4:C@C@C@C@5:6:. . Q.6 p&6&7:. * *{7#. . . B-9%J=I_. . . . . 8:X+[.[.[.[.I.B%. . . g-t&f.f.r.,=. . . . . 9:0:a:b:/%. . . . c:h=d:l=q,9($&N=e:. . . D>%&q*3+r*f:p-. . . . [:!-S;F&p;g:. . . . . . :#w,K#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . h:9). . . . . 5#i:- . . . . j:I+M.L -.. . . . . . . D*k:. . . . l:C@C@C@C@C@m:. . . . . . - +)A *.;=]+. . . . . . . . . . . <+1.A.B *+`+K . . n:T^[.[.[.[.> o:. . . . . . . . . . . . . . p:M=l=q,9($&q:O@. . . r(o*q*3+r*r:s:. . . . ,.t:!-n;G u:. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . B+] v.v:. . . . . . . . . . v&W/<.[.I.w:. . . . . . |.c { P~. . . . . x:C@C@C@C@T%y:. . . G=^.A+[.[.*+z:. . . . . Y,7:q+. . . . ^ A;A:B:v&. . w@x.<.[.[.[.[.e.8~{$. . . . . . . . . . . . . C:J;D:q,9&N=E:. . . . r,6*A#3+r*F*F:. . . . . K#G:H:v&. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . %>B;I:. . . . . . . . . . J:I+<.[.O X-. . . . . _!b+[.[.T^{:. . . . . K:L:C@C@C@C@M:. . N:$#[.[.[.O _*. . . <@Q&r.A W/O:. . . . . . . . . . P:1.[.[.[.[.[.[.y+Q:. . . . L*'=. . . . . . . . R:6,8(6,S:. . . . . . T:6*U:I-;+-+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . p.r.j :.V:. . . . . W:j [.[.B A:. . . . 9)X:Y:Z:C@C@C@C@`:. q]1.[.[.[.I.P*. . ]+P I.[.[.<.x.Q~. . . . . . . . . _.I+<.[.[.[.[.e.P x%. . . V . . . . . . T_c <.<.1.K.. . . +<%.I.g;@<#<$y^. . . . . . . . . . . . . . . . f;k :.x(. . . . k+s.[.[.> *<. =. . b,d%b+1.B%2$. . . . 3#;>g-e_]+. . . ]<(+[.[.[.[.I.L{. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . q>*@. . . . . . . . . . ^. . . . . . . . . R&L M.A l*. . . /<(<_ L.p . G++)<.[.[.I.Y.]+. . . . . . . . . . . R&%.e.[.[.[.A.b=. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . 0+a%a.. . . r$Y.[.[.i.r.. . . . . . . . . . P+1$i(. . . U.R%<ru.. . . . . . . }*X+$>w <.<.2.E . . Z<`<. . . . . . J:9)9<. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . [! ! x%. ( .[j(. . . 7>x@. . . `-L A.s.c J.. . . . . . . . +[C@C@C@C@@[)@#[[.[.[.f$$[. . . . I_%[R.p . . . . . . . ]+x,:.:.&[. *[C@C@=[. . . . . )]L M.y+B!. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H{7 . . -[s.*.;[. . . . . . . >[M.[.[.I.g;. . . . ,[. . . . +$'[C@C@C@)[J@![[.[.j D+. . . q$y+f$T^Q&X.. . . . . . . . w@. . ~[C@C@{[][Y<. . . . C!B [.[.X+O{. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ]//@: x%. . G+. . . . < b+[.[.s.6#. . Y B!/@Q&-=. . . . ^[C@C@C@C@/[([i.^.o%. . |&r.[.[.[., z<. . . . 5#[ G._[. :[C@C@C@C@<[[[A }[. . . :+s.[.[.*+d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B,u:. . |[/ f;. . . . 1[A , _ Q~. . 2[f$[.I.Q&. . . . . 3[C@C@C@C@4[5[6[. . . !]> [.[.[.M#7[. . . T+D j+8[9[0[C@C@C@C@C@a[b[A.E . . . K(/. @s.R%@+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e$v.%+. . Z K.1%T+1<}-. . . *.A+[.[.:.N@. . . 9 z<. . . f[g[G_h[i[C@C@C@C@C@j[G<<.*.;.. . . . k[x+6#l[. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . u m[. . n[/ $#x+. . . . . . <+> <.N#l*. . v&y+X+A n$o[p[C@C@C@q[r[. . . d+b+f$w.Y.!&. . . s[t[u[C@C@C@C@C@C@C@v[w[8~J=. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m&L A.u@. . . . . . U+S]D ;={.. . j:*+[.[., x[. y[C@C@C@C@==. . . ~]x(z[#+. . . A[B[C@C@C@C@C@C@C@C@C@. *]*]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z C[Q:. . . .#. . . . . . . . . m*f$[.[.A.D[. . E[C@C@C@C@4:F[. . . . . . . G[C@C@C@C@C@C@C@C@C@C@H[. . . &@!<[_U+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I[J[K[. . . . . . . . L[8~ @ @8~M[. N[O[P[Q[C@C@C@C@R[. . . . . . C@C@C@C@S[T[C@C@C@C@C@U[. . V[P B w.W[. . . /(. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H+:.*>. . . . X[. . . . Y[w:w:/+. . c%f.K@B=Z[C@C@C@C@C@`[H*. . . }.}+}. @}C@C@C@C@C@C@#}. . e$I.[.[./.<@. $}! %}. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 5^. . . Q.Q&_ 3$. . . . . . . . . &}A.[.[.*}=}-}C@C@C@C@C@;}>},}'})}!}~}C@C@C@{}]}C@C@^}. . /}B [.<.u@}&. _ <.J & . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A>. . . r%x}: w&. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . y}J A.M]. . . . z}e$8=. . 9 _ _ z[. . := self.expectedBytes:# -> is it what we expect + newData = self.tcpSocket.read(self.expectedBytes) # QByteArray + self.expectedBytes = 0 + if self.expectedDatatype == 0: # trcHeader + self.decodeTrcHeader(newData) + elif self.expectedDatatype == 1: + self.analyzeRawData(newData) + else: + print('Received unknow datatype' + repr(self.expectedDatatype)) + else: + print("Waiting for more data : expecting %s, got %s"%(str(self.expectedBytes), str(bytesAvailable))) + + def decodeTrcHeader(self, data): + self.trcHeader = {} + print('Got Trc Header !') + + def analyzeRawData(self, data): + #Separate data from each electrode ? + # Signal filtering + # We have displayable data ! + # Should we send a signal to refresh the display (max 30fps) ? + print('Got raw data') + + def closeSocket(self, message="no reason given"): + print ('Closing socket : '+message) + self.tcpSocket.abort() + self.expectedBytes = 0 + self.expectedDatatype = -1 diff --git a/TimerMessageBox.py b/TimerMessageBox.py new file mode 100644 index 0000000..206f665 --- /dev/null +++ b/TimerMessageBox.py @@ -0,0 +1,57 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +from PyQt4 import QtCore +from PyQt4 import QtGui + + +class TimerMessageBox(QtGui.QMessageBox): + def __init__(self, timeout=3, parent=None): + super(TimerMessageBox, self).__init__(parent) + self.setWindowTitle("NOT FOR MEDICAL USAGE") + self.time_to_wait = timeout + self.changeContent() + #self.setText("wait (closing automatically in {0} secondes.)".format(timeout)) + self.setStandardButtons(QtGui.QMessageBox.NoButton) + self.timer = QtCore.QTimer(self) + self.timer.setInterval(1000) + self.connect(self.timer, QtCore.SIGNAL("timeout()"), self.changeContent) + self.timer.start() + + def changeContent(self): + self.setText("NOT FOR MEDICAL USAGE (closing automatically in {0} secondes.)".format(self.time_to_wait)) + + if self.time_to_wait <= 0: + self.close() + + self.time_to_wait -= 1 + + def closeEvent(self, event): + self.timer.stop() + event.accept() + + +class Example(QtGui.QWidget): + def __init__(self): + super(Example, self).__init__() + btn = QtGui.QPushButton('Button', self) + btn.resize(btn.sizeHint()) + btn.move(50, 50) + self.setWindowTitle('Example') + self.connect(btn, QtCore.SIGNAL("clicked()"), self.warning) + + def warning(self): + messagebox = TimerMessageBox(5, self) + messagebox.exec_() + + +def main(): + app = QtGui.QApplication(sys.argv) + ex = Example() + ex.show() + sys.exit(app.exec_()) + + +if __name__ == '__main__': + main() diff --git a/anonymizeTRC.py b/anonymizeTRC.py new file mode 100644 index 0000000..d07423c --- /dev/null +++ b/anonymizeTRC.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +""" Function to anonymize patient data in TRC files + (c) 2014 - INSERM U836 - Manik Bhattacharjee + License GNU GPL v3 +""" +import struct + +def anonymizeTRC(filepath, firstname="No", lastname="Name", nowrite=False, overwriteMontage=False): + """ Anonymize patient data in TRC files """ + + f=open(filepath, "r+b") # Open read-write binary mode + # should check for a TRC header ! + try: + f.seek(2) + headerTitle = f.read(8) + f.seek(175) + version = struct.unpack('B', f.read(1))[0] + if headerTitle != "MICROMED" or version != 4: + print "Not a MICROMED TRC System 98 v4 file -> ignoring" + f.close() + return False + except: + # Could not read header info -> wrong file type + f.close() + return False + f.seek(64) # go to patient data offset in header + # get a 22-char string, padding with spaces, convert to integers and pack as 22 unsigned chars in little endian + if nowrite: + f.close() + return True + f.write(struct.pack('<22B',*[ord(a) for a in lastname[:22].ljust(22,' ')])) + # Same with 20 chars + f.write(struct.pack('<20B',*[ord(a) for a in firstname[:20].ljust(20,' ')])) + # Same with date (3 unsigned chars, for example [10, 05, 72] for october 5th 1972 + f.write(struct.pack('<3B',1,1,1)) + + if overwriteMontage: + try: + # Read unsigned short int number of montages + f.seek(152) + nbMontages = struct.unpack('H',f.read(2))[0] + # Reading Montage header to get offset of montage data + f.seek(288) + if f.read(8) != 'MONTAGE ': + raise Exception("Incorrect MONTAGE header") + montageOffs = struct.unpack('I', f.read(4))[0] + + for i in range(nbMontages): + newMontageName = "Montage "+str(i) + f.seek(montageOffs + 4096*i+264) + # To print description string : desc = f.read(64); print desc[:desc.find('\x00')] + f.write(struct.pack('<64B',*[ord(a) for a in newMontageName.ljust(64,'\x00')])) + except: + print "Could not overwrite Montage name" + + f.close() + + return True + diff --git a/anonymizer.py b/anonymizer.py new file mode 100644 index 0000000..222d09e --- /dev/null +++ b/anonymizer.py @@ -0,0 +1,718 @@ +# -*- coding: utf-8 -*- +# +# This software and supporting documentation are distributed by +# Institut des Neurosciences de Grenoble - INSERM U836 +# France +# +# License : GNU General Public License version 3 +# +# Upload/anonymizing easy-to-use software for F-TRACT DB +# Anonymizer functions +# + +import os, tempfile, shutil, struct, datetime +import traceback +from struct import pack, unpack +import codecs + +############################### DICOM ############################################### + +import dicom +from anonymizeDicom import anonymize as anonymizePyDicomFile +from dicom.filereader import InvalidDicomError + +def anonymizeDicomFile(path, outputPath, newName="anonymous"): + oldsize = os.path.getsize(path) + try: + anonymizePyDicomFile(path, outputPath, new_person_name=newName, new_patient_id=newName) + except InvalidDicomError: # Not dicom file -> just copy the file + print "Not a dicom file, no anonymization done." + shutil.copy(path, outputPath) + if os.path.exists(outputPath): + newsize = os.path.getsize(outputPath) + if newsize != oldsize: + print('ERROR non-DICOM file copy failed ! '+repr(outputPath)) + raise Exception('ERROR non-DICOM file copy failed ! '+repr(outputPath)) + else: + print('ERROR non-DICOM file copy failed (not created) ! '+repr(outputPath)) + raise Exception('ERROR non-DICOM file copy failed (not created) ! '+repr(outputPath)) + + + except Exception, err: + print ("Other error while anonymizing DICOM file %s : %s"%(path, repr(err))) + traceback.print_exc() + newsize = os.path.getsize(outputPath) + if oldsize > 0 and newsize == 0: + print('ERROR : Dicom file size is 0 after anonymization' + repr(path)) + raise Exception('DICOM anonymization failed : file size is 0 : ' + repr(path)) + return outputPath + + +def anonymizeDicomDir(path,newName="anonymous", outputPath=None): + """Anonymizes a directory containing dicom files. + Non-Dicom files are copied along with the dicom files. + Warning ! This creates a directory that must be erased after use (if outputPath is empty, of course) ! + @return Path of the temporary directory that contains an anonymous copy of the directory + """ + if not os.path.isdir(path): + print "AnonymizeDicom : %s is not a valid directory"%path + return None + if outputPath is None: + tmp = tempfile.mkdtemp(prefix='ftract') + else: + tmp = outputPath + print ('AnonymizeDicomDir will use output directory '+repr(tmp)) + for r,d,s in os.walk(path): + dOut = os.path.relpath(r, path) + if dOut != '.': + print('AnonymizeDicomDir newSubdir') + try: + os.mkdir(os.path.join(tmp, dOut)) + print('Making directory '+repr(os.path.join(tmp, dOut))) + except: + print('Failed to create directory '+repr(os.path.join(tmp, dOut))) + for fileIn in s: + print('Anonymizing file '+repr(os.path.join(r, fileIn)) + ' into '+ os.path.join(tmp, dOut, fileIn) + ' with name = '+newName) + anonymizeDicomFile(os.path.join(r, fileIn), os.path.join(tmp, dOut, fileIn), newName) + + return tmp + +def anonymizeDicomPaths(paths, newName="anonymous"): + out = {} + for p in paths: + if os.path.isdir(p): + print('Anonymizing dicom dir '+repr(p)) + out[p]=tempfile.mkdtemp(prefix='ftract') + anonymizeDicomDir(p, newName, out[p]) + print('Got '+repr(out[p]) + ' from anonymizeDicomDir') + elif os.path.isfile(p): + print('Anonymizing dicom file '+repr(p)) + out[p] = tempfile.mkstemp(prefix='ftract')[1] + anonymizeDicomFile(p, out[p], newName) + print('Got '+repr(out[p]) + ' from anonymizeDicomFile') + + return out + + +############################### SEEG ############################################### + +def anonymizeSeeg(path, newName = "anonymous", filetype = "Micromed"): + if filetype == "Micromed": + return anonymizeTrcPaths(path, newName) + elif filetype == "Nihon Kohden": + return anonymizeNihonKohdenPaths(path, newName) + elif filetype == "EDF": + return anonymizeEdfPaths(path, newName) + elif filetype == "Nicolet": + return anonymizeNicoletEPaths(path, newName) + elif filetype == "xltek" or filetype == "Deltamed": + print "ANONYMIZATION DOES NOT WORK FOR XLTEK/DELTAMED SEEG DATA !" + return dict([(p,p) for p in path]) + else: + print "UNKNOWN FORMAT (should be Micromed, xltek, Nicolet (EDF), or Nihon Kohden)" + return dict([(p, p) for p in path]) + +def anonPaths(paths, newName="anonymous", dirAnonymizer=None, fileAnonymizer = None): + """ A function to anonymize files and dirs in a list of paths using fileAnonymizer and dirAnonymizer functions""" + out = {} + if type(paths) == str: + paths = [paths,] + if dirAnonymizer is None: + dirAnonymizer = lambda p,n:anonDir(path=p, newName = n, fileAnonymizer = fileAnonymizer) + if fileAnonymizer is None: + print "No anonymizer !!!!" + return None + for p in paths: + if os.path.isdir(p): + out[p] = dirAnonymizer(p, newName) + elif os.path.isfile(p): + fileout = tempfile.mkstemp(prefix='ftract')[1] + shutil.copy (p, fileout) + fileAnonymizer(fileout, newName) + out[p] = fileout + + return out + +def anonDir(path, newName = "anonymous", fileAnonymizer = None): + """ A function to anonymize a full directory by running fileAnonymizer on each file on a copy of the directory""" + if not os.path.isdir(path): + print "AnonymizeDir : %s is not a valid directory"%path + return None + tmp = tempfile.mkdtemp(prefix='ftract') + # + for r,d,s in os.walk(path): + dOut = os.path.relpath(r, path) + if dOut != '.': + os.mkdir(os.path.join(tmp, dOut)) + for fileIn in s: + fileout = os.path.join(tmp, dOut, fileIn) + shutil.copy(os.path.join(r, fileIn), fileout) + fileAnonymizer(fileout, newName) + return tmp + +##########################################" Nihon Kohden format + + +anonymizeNihonKohdenPaths = lambda paths, newName="anonymous":anonPaths(paths, newName, None, anonymizeNihonKohdenFile) + + +def anonymizeNihonKohdenFile(filepath, newName = "anonymous"): + nihonKohdenAnon = {'CND':anonNihonKohdenDeviceBlock, + 'CN2':anonNihonKohdenDeviceBlock, + 'PNT':anonNihonKohdenPnt, + 'LOG':anonNihonKohdenDeviceBlock, + 'EEG':anonNihonKohdenDeviceBlock, + 'EGF': anonNihonKohdenEGF, + 'CMT':anonNihonKohdenDeviceBlock,} + # Ignore other files without patient info (.21E, .11D, .REG...) + # Check this is a Nihon Kohden file + extension = os.path.splitext(filepath)[1][1:].upper() + if extension not in nihonKohdenAnon.keys(): + print "Not a Nihon Kohden file with patient name (extension unknown - not anonymized) : "+extension + return filepath + # Better expensive checks : read some headers and anonymize using the appropriate function + nihonKohdenAnon[extension](filepath, newName) + return filepath + + +def anonNihonKohdenDeviceBlock(filepath, newName): + print "Anon Nihon Device block for "+filepath + f = codecs.open(filepath, "r+b", encoding='cp1252') # Open read-write binary mode + # should check for a header ! + deviceType = f.read(16) + filePrev = f.read(16) + fileNext = f.read(16) + name = os.path.splitext(os.path.basename(filepath))[0] + prev = os.path.splitext("".join([a for a in filePrev if a!='\x00']))[0] + next = os.path.splitext("".join([a for a in fileNext if a!='\x00']))[0] + if (prev != '' and prev != name) or (next != '' and next != name) or not deviceType.startswith('EEG-'): + print "Invalid previous/next file name in header or device type is not EEG :\n %s\n %s\n %s"%(repr(filePrev), repr(fileNext), repr(deviceType)) + return + + idNumber = f.read(16) + dateTime = f.read(14) + charType = chr(struct.unpack('B',f.read(1))[0]) # Should be '0' (48) for ascii, '1' (49) for japanese + if charType not in ['0','1'] or len([a for a in dateTime if not a.isdigit()]) != 0: + print "Nihon Kohden -> invalid char type" + return + patientName = f.read(32) + reserved = f.read(12) # Should be all 0x00 + additionalVersion = f.read(5) + if len([r for r in reserved if r != '\x00']) != 0 or [a for a in idNumber if not a.isdigit() and a != '\x00']: + print "reserved should be all 0x00" + return + # Overwrite patient name + f.seek(79) + f.write(newName.ljust(32,'\x00')[:32]) + f.close() + +def anonNihonKohdenPnt(filepath, newName): + print "Anon PNT "+filepath + # First anonymize the device block + anonNihonKohdenDeviceBlock(filepath, newName) + # Go for specific patient block + f=codecs.open(filepath, "r+b", encoding='cp1252') + f.seek(146) + val = struct.unpack(' offset in not 1024 !" + f.seek(val) + if f.read(1) != '\x03': + #print "Invalid value at offset 1024" + return + device = f.read(16) # -> device model "EEG-1100A V01.00" + if f.read(1) != '\x7b': + return + # Information about the rest of the header : [[name length, value length, value type, unit],...[]] - 4 bytes, 123=0x7b times + datainfo = [struct.unpack('BBBB',f.read(4)) for j in xrange(123)] + # Read the data according to the datainfo + data = {} + for i in xrange(len(datainfo)): + k = f.read(datainfo[i][0]).replace('\x00','').lower() + data[k] = (f.tell(), f.read(datainfo[i][1]).replace('\x00',''), datainfo[i][1]) # length of the name of the data type + # Did we find a name ? Overwrite it + if 'name' in data: + f.seek(data['name'][0]) + f.write(newName.ljust(data['name'][2],'\x00')[:data['name'][2]]) + # Did we find a date of birth ? Overwrite it + if 'date of birth' in data: + f.seek(data['date of birth'][0] + 8) # 8 because we leave as is the first 8 chars "YYYY/MM/" and just set the day to 01 + f.write('01') + f.close() + + +def anonNihonKohdenEGF(filepath, newName): + print "Anon EGF "+filepath + #PATNAME=Dupont Jean + #BIRTHD=2003/01/01 + f = codecs.open(filepath,'rb', encoding='cp1252') + lines = f.read().split(u"\r\n") + f.close() + updateNeeded = False + for i in xrange(len(lines)): + if lines[i].startswith('PATNAME='): + lines[i] = 'PATNAME='+newName + updateNeeded = True + elif lines[i].startswith('BIRTHD='): + lines[i] = lines[i][:15]+'01'#Just sets the day to 01 : BIRTHD=2010/05/18 -> BIRTHD=2010/05/01 + updateNeeded = True + if updateNeeded: + import pdb; pdb.set_trace() + f = codecs.open(filepath, 'wb', encoding='cp1252') + f.write(u"\r\n".join(lines)) + f.close() + + +############### Nicolet One .e files ############ EDF files ############ +class NicoletFile: + LABELSIZE = 32 + TSLABELSIZE = 64 + UNITSIZE = 16 + ITEMNAMESIZE = 64 + tagnames = {'ExtraDataTags': 'ExtraDataTags', + 'SegmentStream': 'SegmentStream', + 'DataStream': 'DataStream', + 'InfoChangeStream': 'InfoChangeStream', + 'InfoGuids': 'InfoGuids', + '{A271CCCB-515D-4590-B6A1-DC170C8D6EE2}': 'TSGUID', + '{8A19AA48-BEA0-40D5-B89F-667FC578D635}': 'DERIVATIONGUID', + '{F824D60C-995E-4D94-9578-893C755ECB99}': 'FILTERGUID', + '{02950361-35BB-4A22-9F0B-C78AAA5DB094}': 'DISPLAYGUID', + '{8E94EF21-70F5-11D3-8F72-00105A9AFD56}': 'FILEINFOGUID', + '{E4138BC0-7733-11D3-8685-0050044DAAB1}': 'SRINFOGUID', + '{C728E565-E5A0-4419-93D2-F6CFC69F3B8F}': 'EVENTTYPEINFOGUID', + '{D01B34A0-9DBD-11D3-93D3-00500400C148}': 'AUDIOINFOGUID', + '{BF7C95EF-6C3B-4E70-9E11-779BFFF58EA7}': 'CHANNELGUID', + '{2DEB82A1-D15F-4770-A4A4-CF03815F52DE}': 'INPUTGUID', + '{5B036022-2EDC-465F-86EC-C0A4AB1A7A91}': 'INPUTSETTINGSGUID', + '{99A636F2-51F7-4B9D-9569-C7D45058431A}': 'PHOTICGUID', + '{55C5E044-5541-4594-9E35-5B3004EF7647}': 'ERRORGUID', + '{223A3CA0-B5AC-43FB-B0A8-74CF8752BDBE}': 'VIDEOGUID', + '{0623B545-38BE-4939-B9D0-55F5E241278D}': 'DETECTIONPARAMSGUID', + '{CE06297D-D9D6-4E4B-8EAC-305EA1243EAB}': 'PAGEGUID', + '{782B34E8-8E51-4BB9-9701-3227BB882A23}': 'ACCINFOGUID', + '{3A6E8546-D144-4B55-A2C7-40DF579ED11E}': 'RECCTRLGUID', + '{D046F2B0-5130-41B1-ABD7-38C12B32FAC3}': 'GUID TRENDINFOGUID', + '{CBEBA8E6-1CDA-4509-B6C2-6AC2EA7DB8F8}': 'HWINFOGUID', + '{E11C4CBA-0753-4655-A1E9-2B2309D1545B}': 'VIDEOSYNCGUID', + '{B9344241-7AC1-42B5-BE9B-B7AFA16CBFA5}': 'SLEEPSCOREINFOGUID', + '{15B41C32-0294-440E-ADFF-DD8B61C8B5AE}': 'FOURIERSETTINGSGUID', + '{024FA81F-6A83-43C8-8C82-241A5501F0A1}': 'SPECTRUMGUID', + '{8032E68A-EA3E-42E8-893E-6E93C59ED515}': 'SIGNALINFOGUID', + '{30950D98-C39C-4352-AF3E-CB17D5B93DED}': 'SENSORINFOGUID', + '{F5D39CD3-A340-4172-A1A3-78B2CDBCCB9F}': 'DERIVEDSIGNALINFOGUID', + '{969FBB89-EE8E-4501-AD40-FB5A448BC4F9}': 'ARTIFACTINFOGUID', + '{02948284-17EC-4538-A7FA-8E18BD65E167}': 'STUDYINFOGUID', + '{D0B3FD0B-49D9-4BF0-8929-296DE5A55910}': 'PATIENTINFOGUID', + '{7842FEF5-A686-459D-8196-769FC0AD99B3}': 'DOCUMENTINFOGUID', + '{BCDAEE87-2496-4DF4-B07C-8B4E31E3C495}': 'USERSINFOGUID', + '{B799F680-72A4-11D3-93D3-00500400C148}': 'EVENTGUID', + '{AF2B3281-7FCE-11D2-B2DE-00104B6FC652}': 'SHORTSAMPLESGUID', + '{89A091B3-972E-4DA2-9266-261B186302A9}': 'DELAYLINESAMPLESGUID', + '{291E2381-B3B4-44D1-BB77-8CF5C24420D7}': 'GENERALSAMPLESGUID', + '{5F11C628-FCCC-4FDD-B429-5EC94CB3AFEB}': 'FILTERSAMPLESGUID', + '{728087F8-73E1-44D1-8882-C770976478A2}': 'DATEXDATAGUID', + '{35F356D9-0F1C-4DFE-8286-D3DB3346FD75}': 'TESTINFOGUID'} + def __init__(self, filename, anonymizeName=None): + self.fileName = filename + self.patientInfo = None + self.segments = None + self.sections = None + self.index = None + self.sigInfo = None + self.tsInfo = None + self.chInfo = None + self.notchFreq = None + self.Qi = None + self.Qii = None + self.allIndexIDs = None + self.useTSinfoIdx = 1 + + if os.path.splitext(filename)[1][1:].lower() != "e": + print "ERROR : File extension must be .e. Filename is :"+str(filename) + return + self.filename = os.path.realpath(filename) + filename = self.filename + h = open(filename,'r+b') + #Get init + misc1 = unpack('<5I', h.read(20))#ok + unknown =unpack(' + indexIdx = unpack(' convert to seconds and remove duration until 1/1/1970 (unix base time) + #thetime = datetime.datetime.fromtimestamp(unix_time) # This can crash, and we don't care about dates anyway + #self.segments[i]['dateStr'] = thetime.strftime('%Y-%m-%d %H:%M:%S') + #datestr(unix_time/86400 + datenum(1970,1,1)); + #value = [thetime.day, thetime.month, thetime.year] # Day month year + value = unix_time + if id in [23,24]: + value = unpack('") + value = "".join(map (chr, unpack('<'+str( strSetup[i+1] + 1)+'H', h.read(2*(strSetup[i+1] + 1))))).rstrip(' \t\r\n\0') + info[infoProps[id]] = value; + print " "+str(value) + self.patientInfo = info; + # Close and reopen for write, because writing directly fails in windows XP with no error message... + h.close() + print("Reopening Nicolet file to write inside") + h = open(filename,'r+b') + for offset in toWrite: + h.seek(offset) + h.write(toWrite[offset]) + print("Writing at " + str(offset)) + h.close() + + +def anonymizeNicoletE(filepath, newName = "anonymous"): + """Anonymizes a .e file (from Nicolet) + WARNING overwrites the file ! """ + try: + nf = NicoletFile(filepath, anonymizeName = newName) + except Exception as e: + print "Could not anonymize "+ filepath+" : NicoletFile exception when reading file !"+str(e) + raise + + + +def anonymizeNicoletEPaths(paths, newName="anonymous"): + out = {} + for p in paths: + if os.path.isdir(p): + out[p] = anonymizeNicoletEDir(p, newName) + elif os.path.isfile(p): + fileout = tempfile.mkstemp(prefix='ftract')[1] + shutil.copy (p, fileout) + anonymizeNicoletE(fileout, newName) + out[p] = fileout + return out + +def anonymizeNicoletEDir(path, newName = "anonymous"): + """Anonymizes a directory containing TRC files. + Non-TRC files are copied along with the TRC files. + Warning ! This creates a directory that must be erased after use ! + @return Path of the temporary directory that contains an anonymous copy of the directory + """ + if not os.path.isdir(path): + print "AnonymizeNicoletE : %s is not a valid directory"%path + return None + tmp = tempfile.mkdtemp(prefix='ftract') + # + for r,d,s in os.walk(path): + dOut = os.path.relpath(r, path) + if dOut != '.': + os.mkdir(os.path.join(tmp, dOut)) + for fileIn in s: + fileout = os.path.join(tmp, dOut, fileIn) + shutil.copy(os.path.join(r, fileIn), fileout) + anonymizeNicoletE(fileout, newName) + return tmp + + +############### EDF files ############ +def anonymizeEdf(filepath, newName = "anonymous"): + """Anonymizes a EDF file (from Nicolet One) + WARNING overwrites the file ! + """ + f = open(filepath, 'r+b') + f.seek(88) + if f.read(9) != 'Startdate': + print "No Startdate in file : probably not EDF -> no anonymization !" + return + # reserved header : if it starts with EDF+ this is an EDF+ file + f.seek(192) + isEdfPlus = False + if f.read(4) == 'EDF+': + isEdfPlus = True + # Go to the patient data and overwrite it using EDF+ format (space separated subfields, X for no value) + # patient code (no spaces, use _ instead), sex (F or M), dd-MMM-yyyy birthdate, patient name + f.seek(8) + patientInfo = f.read(80) + if isEdfPlus: + patientInfo = patientInfo.split(u' ') + patId = patientInfo[0] + patId = newName.replace(u' ', u'_')[:30] + patSex = patientInfo[1] + patBirthdate = patientInfo[2] + patName = patientInfo[3] + patName = newName.replace(u' ', u'_')[:30] + if len(patBirthdate) >10: # Should be 21-AUG-2015 + patBirthdate ='01'+patBirthdate[2:] + patientInfo = ' '.join([patId, patSex, patBirthdate, patName]) + else: # EDF + patientInfo = ' '.join([newName.replace(u' ', u'_')[:30], u'X', u'X', newName.replace(u' ', u'_')[:30]]) + f.seek(8) + f.write(patientInfo[:80].ljust(80,' ')) + f.close() + +def anonymizeEdfPaths(paths, newName=u"anonymous"): + out = {} + for p in paths: + if os.path.isdir(p): + out[p] = anonymizeEdfDir(p, newName) + elif os.path.isfile(p): + fileout = tempfile.mkstemp(prefix='ftract')[1] + shutil.copy (p, fileout) + anonymizeEdf(fileout, newName) + out[p] = fileout + return out + +def anonymizeEdfDir(path, newName = u"anonymous"): + """Anonymizes a directory containing TRC files. + Non-TRC files are copied along with the TRC files. + Warning ! This creates a directory that must be erased after use ! + @return Path of the temporary directory that contains an anonymous copy of the directory + """ + if not os.path.isdir(path): + print "AnonymizeEDF : %s is not a valid directory"%path + return None + tmp = tempfile.mkdtemp(prefix='ftract') + # + for r,d,s in os.walk(path): + dOut = os.path.relpath(r, path) + if dOut != '.': + os.mkdir(os.path.join(tmp, dOut)) + for fileIn in s: + fileout = os.path.join(tmp, dOut, fileIn) + shutil.copy(os.path.join(r, fileIn), fileout) + anonymizeEdf(fileout, newName) + return tmp + +#################### MICROMED TRC FORMAT System 98 type 4 +def anonymizeTrcDir(path, newName = "anonymous"): + """Anonymizes a directory containing TRC files. + Non-TRC files are copied along with the TRC files. + Warning ! This creates a directory that must be erased after use ! + @return Path of the temporary directory that contains an anonymous copy of the directory + """ + if not os.path.isdir(path): + print "AnonymizeTRC : %s is not a valid directory"%path + return None + tmp = tempfile.mkdtemp(prefix='ftract') + # + for r,d,s in os.walk(path): + dOut = os.path.relpath(r, path) + if dOut != '.': + os.mkdir(os.path.join(tmp, dOut)) + for fileIn in s: + fileout = os.path.join(tmp, dOut, fileIn) + shutil.copy(os.path.join(r, fileIn), fileout) + anonymizeTRC_Sys98_t4(fileout, newName, newName) + return tmp + +def anonymizeTrcPaths(paths, newName="anonymous"): + out = {} + for p in paths: + if os.path.isdir(p): + out[p] = anonymizeTrcDir(p, newName) + elif os.path.isfile(p): + fileout = tempfile.mkstemp(prefix='ftract')[1] + shutil.copy (p, fileout) + anonymizeTRC_Sys98_t4(fileout, firstname=newName, lastname=newName) + out[p] = fileout + return out + +def anonymizeTRC_Sys98_t4(filepath, firstname="No", lastname="Name", nowrite=False, overwriteMontage=True, overwriteUndocumentedElectrode = True): # Anonymize Micromed's System 98 type 4 TRC files + """ Anonymize Micromed's System 98 type 4 TRC files """ + f=open(filepath, "r+b") # Open read-write binary mode + # should check for a TRC header ! + f.seek(2) + headerTitle = f.read(26) + f.seek(175) + headerType = f.read(1) + trcVersion = struct.unpack('B',headerType)[0] + if headerTitle != "MICROMED Brain-Quick file" or (trcVersion != 4 and trcVersion != 3): + print "Not a MICROMED System 98 Type 3/4 TRC file -> ignoring" + f.close() + return False + f.seek(64) # go to patient data offset in header + # get a 22-char string, padding with spaces, convert to integers and pack as 22 unsigned chars in little endian + if nowrite: + f.close() + return True + f.write(struct.pack('<22B',*[ord(a) for a in lastname[:22].ljust(22,' ')])) + # Same with 20 chars + f.write(struct.pack('<20B',*[ord(a) for a in firstname[:20].ljust(20,' ')])) + # Same with date (3 unsigned chars, for example [10, 05, 72] for october 5th 1972 + f.seek(107) + f.write(struct.pack(' 128* 4-bytes values (the sample where themontage was changed when viewing) + # We can skip that, then MAX_HISTORY = 128 "specific montage" structures which are identical to the montages above. + # Description string starts at offset 264 of each montage structure and is 64 bytes long,, just like above. + for i in range(30): + newMontageName = "Montage History "+str(i) + f.seek(historyOffs + 128*4 + sizeMontage*i+264) + desc = f.read(64) + # To print description string : desc = f.read(64); print desc[:desc.find('\x00')] + if "".join(["\x00" for j in range(64)]) != desc: + f.seek(historyOffs + 128*4 + sizeMontage*i+264) + f.write(struct.pack('<64B',*[ord(a) for a in newMontageName.ljust(64,'\x00')])) + + # undocumented string in place of the last electrode in name in HISTORY : find history offset, + f.seek(192) + if f.read(8) != 'LABCOD ': + raise Exception ("Incorrect LABCOD header") + elecOffs = struct.unpack('I', f.read(4))[0] + # There should be 640 electrode structures of 128 bytes. But the last one is not an electrode structure. It seems to be a 32 bits integer and a 64 bytes string that contains a montage name... + if overwriteUndocumentedElectrode: + f.seek(elecOffs + 639*128 + 4) + f.write(struct.pack('<64B',*[ord(a) for a in "undocumented montage".ljust(64,'\x00')])) + + except: + print "Could not overwrite Montage name" + + f.close() + return True diff --git a/autoImportScript.py b/autoImportScript.py new file mode 100644 index 0000000..f036f66 --- /dev/null +++ b/autoImportScript.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# +# (c) INSERM U836 - Manik Bhattacharjee +# Script to import old databases of patients into new BrainVisa hierarchy + +import os, json,sys +from PyQt4 import QtGui, QtCore + +#Init PyQt4 +app=QtGui.QApplication(sys.argv) + +# Dossier +#root = '/home/lnppeeg/data/LOCA_DATABASE' +root = '/media/My Passport/epiBaseDo/LyonNuit/LOCA_DATABASE' +rootEpi = '/media/My Passport/epiBaseDo/EpiG' + +# readPrefs +pr={} +try: + prfile = open(os.path.join(os.path.expanduser('~'), '.autoImportBrainVisa'),'r') + pr = json.load(prfile) + prfile.close() +except: + pass + +###################### LOCA_DATABASE -> un dossier avec les IRM et schémas d'implantation (MRI_2010), un dossier avec la SEEG (2010). +# Dans chaque dossier, un dossier par sujet +dirs = os.listdir(root) +subjects = [] +if 'oldsubjects' in pr: + subjects = pr['oldsubjects'] +else: + for d in dirs: + if os.path.isdir(os.path.join(root,d)): + subjects.extend([f for f in os.listdir(os.path.join(root, d)) if os.path.isdir(os.path.join(root,d,f))]) + + # Unique subjects, sorted + subjects = sorted(list(set(subjects))) + + pr['oldsubjects'] = subjects + + +# Build a correspondance oldnames -> newNames +newNames={} +if "newNames" in pr: + newNames = pr["newNames"] + +widgets={} + +def updateNewNames(): + for s in subjects: + newNames[s] = str(widgets[s].text()) + pr["newNames"] = newNames + +dialog = QtGui.QDialog() +lay = QtGui.QVBoxLayout(dialog) +#dialog.setLayout( +button=QtGui.QPushButton("Save", dialog) + +for s in subjects: + lay2 = QtGui.QHBoxLayout() + lay2.addWidget(QtGui.QLabel(s)) + widgets[s] = QtGui.QLineEdit() + if s in newNames: + widgets[s].setText(newNames[s]) + lay2.addWidget(widgets[s]) + lay.addLayout(lay2) + +lay.addWidget(button) + +dialog.show() +#fin de l'application lorsque toutes les fenêtres sont fermées +app.connect(app,QtCore.SIGNAL("lastWindowClosed()"),app,QtCore.SLOT("quit()")) +#fin de l'application lorsque l'utilisateur clique sur le bouton +app.connect(button, QtCore.SIGNAL("clicked()"),updateNewNames) +#boucle principale de traitement des évènements +app.exec_() + +output = None +output2 = None + +if 'oldnifti' in pr: # not in pr to use the cache ! + import subprocess + output = subprocess.Popen(['find',root, '-iname', '*.img', '-o', '-iname', '*.pts','-o', '-iname', '*.nii', '-o', '-iname', 'electrode.txt', '-o', '-iname', 'electrodes.txt','-o', '-iname', 'DICOM', '-o', '-iname', '*.jpg', '-o', '-iname', '*.jpeg', '-o', '-iname', '*.pdf', '-o', '-iname', '*.trc'], + stdout=subprocess.PIPE).communicate()[0].split('\n') + #output.extend(subprocess.Popen(['find',rootEpi, '-iname', '*.img', '-o', '-iname', '*.pts','-o', '-iname', '*.nii', '-o', '-iname', 'electrode.txt', '-o', '-iname', 'electrodes.txt','-o', '-iname', 'DICOM'], + # stdout=subprocess.PIPE).communicate()[0].split('\n')) + + ## Trier les .nii et .img + images = [ o for o in output if o[-4:].lower()=='.img'] + [ o for o in output if o[-4:].lower()=='.nii'] + pr['oldnifti'] = images + # Trier les dossiers DICOM et les étiqueter + pr['dicom'] = [ o for o in output if o[-5:].upper()=='DICOM'] + ## Trier les PTS et les electrode(s).txt + pr['oldpts'] = [ o for o in output if o[-4:].lower()=='.pts'] + + pr['oldelectrodestxt'] = [ o for o in output if o[-13:].lower()=='electrode.txt'] + [ o for o in output if o[-14:].lower()=='electrodes.txt'] + pr['impl'] = [ o for o in output if os.path.splitext(o)[1].lower()=='.jpg'] + [ o for o in output if os.path.splitext(o)[1].lower()=='.jpeg'] + pr['trc'] = [ o for o in output if os.path.splitext(o)[1].lower()=='.trc'] + +# What do we have for each subject ? +subjData=dict([(s,{'dicom':[], 'nifti':[], 'pts':[], 'electrodestxt':[]}) for s in subjects]) + +for s in subjects: + subjData[s]['nifti']=[{'path':i,'type':None, 'acq':None} for i in pr['oldnifti'] if i.split(root)[1].split('/')[2] == s and i.split(root)[1].split('/')[3].lower().find('seeg') == -1 and os.path.split(i)[1].find('y_inverse') == -1 ] + # if os.path.split(i)[1].startswith('r') -> image registered, 'w' pour les images normalizée, s pour smooth + subjData[s]['dicom']=[{'path':i,'type':None, 'acq':None} for i in pr['dicom'] if i.split(root)[1].split('/')[2] == s] + subjData[s]['pts']=[{'path':i,'type':None, 'acq':None} for i in pr['oldpts'] if i.split(root)[1].split('/')[2] == s] + subjData[s]['electrodestxt']=[{'path':i,'type':None, 'acq':None} for i in pr['oldelectrodestxt'] if i.split(root)[1].split('/')[2] == s] + subjData[s]['impl']=[{'path':i,'type':None, 'acq':None} for i in pr['impl'] if i.split(root)[1].split('/')[2] == s] + subjData[s]['trc']=[{'path':i,'type':None, 'acq':None} for i in pr['trc'] if i.split(root)[1].split('/')[2] == s] + subjData[s]['comment'] = "Has %d nifti, %d dicom dirs, %d pts, %d electrodes.txt and %d implantation scans"%(len(subjData[s]['nifti']), len(subjData[s]['dicom']), len(subjData[s]['pts']), len(subjData[s]['electrodestxt']), len(subjData[s]['impl'])) + # If not defined, try to extract name of subject from TRC + if len(newNames[s]) < 10 and len(subjData[s]['trc']) > 0: + output = subprocess.Popen(['getTRCpatientData', subjData[s]['trc'][0]['path']], stdout=subprocess.PIPE).communicate()[0].split('\n') + print "Auto name : %s --> oldname %s --> newName %s"%(s, newNames[s], str(output[2])+'+++') + newNames[s] = str(output[2])+'+++' + +# On veut -> trouver le nouveau nom, trouver une T1pre, une T1post, une T2pre/post si dispo, une CT..., tous les TRC et les localizers déjà faits et insérer tout ça dans la db. + + +##### Save preferences + +prfile = open(os.path.join(os.path.expanduser('~'), '.autoImportBrainVisa'),'w') +json.dump(pr, prfile) +prfile.close() +#################### EpiG ############################ \ No newline at end of file diff --git a/bipoleLabelsDisplay.ui b/bipoleLabelsDisplay.ui new file mode 100644 index 0000000..582974c --- /dev/null +++ b/bipoleLabelsDisplay.ui @@ -0,0 +1,146 @@ + + + Form + + + + 0 + 0 + 703 + 364 + + + + Form + + + + + 10 + 30 + 681 + 24 + + + + + 13 + 75 + false + true + true + false + + + + clinical observation labels from bipoles - NOT FOR MEDICAL USAGE + + + Qt::AlignCenter + + + + + + 10 + 60 + 681 + 291 + + + + + QLayout::SetFixedSize + + + + + + + + 11 + + + + 1 Hz + + + true + + + stim_selection_group + + + + + + + 50 Hz + + + stim_selection_group + + + + + + + Both + + + stim_selection_group + + + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + FontColor (Physiological or Seizure Type) + + + true + + + excelcolor_selection_group + + + + + + + BackColor (je sais pas comment appeler ça) + + + excelcolor_selection_group + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + diff --git a/bipoleSEEGColors.py b/bipoleSEEGColors.py new file mode 100644 index 0000000..83b108f --- /dev/null +++ b/bipoleSEEGColors.py @@ -0,0 +1,267 @@ +# -*-coding:utf-8 -* + +import sys, os, pickle, glob, numpy, re, string, time, subprocess, json, copy, csv + +from PyQt4 import QtGui, QtCore, uic, Qt + +from numpy import * +from math import sqrt +from collections import OrderedDict + +from soma import aims +from brainvisa import axon + +#from soma.aims.spmnormalizationreader import readSpmNormalization +from brainvisa import anatomist +from brainvisa.data import neuroHierarchy +import registration + +from externalprocesses import * +from referentialconverter import ReferentialConverter + + + +import pdb + + +#Main Class +class bipoleSEEGColors(QtGui.QDialog): + + def __init__(self,locateData = None,indv_pat=True,group_subsample=None): + + QtGui.QWidget.__init__(self) + self.ui = uic.loadUi("bipoleLabelsDisplay.ui", self) + self.setWindowTitle('Stimulation Observation - NOT FOR MEDICAL USAGE') + self.locaData =locateData #Data from locatesElectrode.py + self.a=self.locaData.a #Anatomist Object + + self.ui.lowHz_radiobutton.toggled.connect(self.updateBipoleDisplay) + self.ui.highHz_radiobutton.toggled.connect(self.updateBipoleDisplay) + self.ui.bothHz_radiobutton.toggled.connect(self.updateBipoleDisplay) + + self.ui.fontColor_radiobutton.toggled.connect(self.updateBipoleDisplay) + self.ui.backColor_radiobutton.toggled.connect(self.updateBipoleDisplay) + + by_default_list = [u'Motor',u'Sensitive',u'Sensory',u'Vegetative',u'Emotional',u'Experiencial','Superior functions'] + self.final_list_color = by_default_list #detect differencies ? but how because there is other column that should not be taken + model= QtGui.QStandardItemModel(len(self.final_list_color), 1) + for index,i_list in enumerate(self.final_list_color): + item = QtGui.QStandardItem(i_list) + item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + model.setItem(index+1, 0, item) + self.ui.list_backColor_Condition.setModel(model) + + self.ui.list_backColor_Condition.setEnabled(False) + self.ui.list_backColor_Condition.clicked.connect(self.updateBipoleDisplay) + + self.mode_indv = indv_pat + self.subsample_group = group_subsample + self.updateBipoleDisplay() + + + def updateBipoleDisplay(self): + + + infoHztoshow = [self.ui.lowHz_radiobutton.isChecked(),self.ui.highHz_radiobutton.isChecked(),self.ui.bothHz_radiobutton.isChecked()] + infoHzselected = [x for x in range(len(infoHztoshow)) if infoHztoshow[x] == True] + colortoshow = [self.ui.fontColor_radiobutton.isChecked(),self.ui.backColor_radiobutton.isChecked()] + colorselected = [x for x in range(len(colortoshow)) if colortoshow[x] == True] + + if self.mode_indv: + bipoleObjects= dict([(self.locaData.bipoles[x]['name'],self.locaData.bipoles[x]['elecModel'].getAnatomistObjects()[0]) for x in range(len(self.locaData.bipoles))]) + dataSEEG = self.locaData.bipoleLabels['contacts'] + else: + bipoleObjects = self.locaData.bipolesmeshes + dataSEEG = {} + datatomodify = {} + for index_subsample in self.subsample_group: + (subject,bipole) = index_subsample.split(' : ') + if subject not in datatomodify.keys(): + datatomodify.update({subject:[]}) + datatomodify[subject].append(bipole) + for subj in datatomodify.keys(): + #if subj not in dataSEEG.keys(): + #dataSEEG.update({subj:{}}) + for index_bipole in datatomodify[subj]: + matches_bipoles = [x for x in range(len(self.locaData.testDataSubjects[subj]['seeg_label_all'])) if self.locaData.testDataSubjects[subj]['seeg_label_all'][x][0] == index_bipole] + #new_name = subj + ' : ' + self.locaData.testDataSubjects[subj]['seeg_label_all'][index_cont][0] + if len(matches_bipoles)>0: + for index_matches_bipoles in matches_bipoles: + new_name = subj + ' : ' + self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][0] + if new_name not in dataSEEG.keys(): + dataSEEG.update({new_name:{'cell':{}}}) + dataSEEG[new_name]['cell'].update({self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][1]:{}}) + for x in self.final_list_color: + if x in self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][3]: + dataSEEG[new_name]['cell'][self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][1]].update({x:{'value':'something'}}) + else: + dataSEEG[new_name]['cell'][self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][1]].update({x:{'value':0}}) + + if self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][2] == u'no response': + dataSEEG[new_name]['cell'][self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][1]].update({u'Type of response':{'fontcolor':[255,0,0,0]}}) + elif self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][2] == u'seizure sensation': + dataSEEG[new_name]['cell'][self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][1]].update({u'Type of response':{'fontcolor':[255,255,0,0]}}) + elif self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][2] == u'pathological': + dataSEEG[new_name]['cell'][self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][1]].update({u'Type of response':{'fontcolor':[255,0,0,255]}}) + + + if colorselected[0] == 1: + self.ui.list_backColor_Condition.setEnabled(True) + default_backColor = {'Sensory': [255, 0, 176, 80], 'Sensitive': [255, 0, 112, 192], 'Superior functions': [255, 148, 82, 0], 'Motor': [255, 255, 0, 0], 'Emotional': [255, 112, 48, 160], 'Vegetative': [255, 255, 192, 0], 'Experiencial': [255, 255, 133, 255]} + backColor = {} + Model = self.ui.list_backColor_Condition.model() + for index in range(Model.rowCount()-1): + Item = Model.item(index+1) + if Item.checkState(): + if self.mode_indv: + backColor.update({str(Item.text()):self.locaData.bipoleLabels['title'][str(Item.text())]['title_backcolor'][:]}) + else: + backColor.update({str(Item.text()):default_backColor[str(Item.text())]}) + else: + backColor.update({str(Item.text()):[255,150,150,150]}) + + for index_contacts in range(len(dataSEEG.keys())): + + #if self.locaData.bipoleLabels['contacts'].keys()[index_contacts] == u'R02 - R01': + + if (u'1 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 0):#(self.locaData.bipoleLabels['contacts'][self.locaData.bipoleLabels['contacts'].keys()[index_contacts]]['cell'].keys()[0] == u'1 Hz' ) and (infoHzselected[0] == 0 or infoHzselected[0] == 2): + + #enComp = [self.locaData.bipoleLabels['contacts'][self.locaData.bipoleLabels['contacts'].keys()[index_contacts]]['cell']['1 Hz'][x]['value'] for x in self.final_list_color] + enComp = [True if dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['1 Hz'][x]['value'] != 0 else False for x in self.final_list_color] + try: + indexTrue = enComp.index(True) + indexesTrue = [i for i,j in enumerate(enComp) if j == True] + selected_color = [kk for kk,vv in backColor.items() if vv != [255,150,150,150]] + valueselectedcolor = [self.final_list_color.index(selected_color[i]) for i in range(len(selected_color))] + commonSelect = list(set(indexesTrue) & set(valueselectedcolor)) + if len(commonSelect)>1: + colorn = QtGui.QColor.fromRgb(255,255,255,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + else: + colorn = QtGui.QColor.fromRgb(backColor[self.final_list_color[commonSelect[0]]][1],backColor[self.final_list_color[commonSelect[0]]][2],backColor[self.final_list_color[commonSelect[0]]][3],backColor[self.final_list_color[commonSelect[0]]][0]) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + except: + #no response after stimulation + colorn = QtGui.QColor.fromRgb(0,0,0,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + elif (u'1 Hz' not in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 0): + colorn = QtGui.QColor.fromRgb(150,150,150,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + elif (u'50 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 1): + enComp = [True if dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['50 Hz'][x]['value'] != 0 else False for x in self.final_list_color] + try: + indexTrue = enComp.index(True) + indexesTrue = [i for i,j in enumerate(enComp) if j == True] + selected_color = [kk for kk,vv in backColor.items() if vv != [255,150,150,150]] + valueselectedcolor = [self.final_list_color.index(selected_color[i]) for i in range(len(selected_color))] + commonSelect = list(set(indexesTrue) & set(valueselectedcolor)) + if len(commonSelect)>1: + colorn = QtGui.QColor.fromRgb(255,255,255,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + else: + colorn = QtGui.QColor.fromRgb(backColor[self.final_list_color[commonSelect[0]]][1],backColor[self.final_list_color[commonSelect[0]]][2],backColor[self.final_list_color[commonSelect[0]]][3],backColor[self.final_list_color[commonSelect[0]]][0]) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + except: + #no response after stimulation + colorn = QtGui.QColor.fromRgb(0,0,0,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + elif (u'50 Hz' not in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 1): + colorn = QtGui.QColor.fromRgb(150,150,150,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + elif infoHzselected[0] == 2: + if u'1 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys(): + enComp1Hz = [True if dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['1 Hz'][x]['value'] != 0 else False for x in self.final_list_color] + else: + enComp1Hz = [False for i in range(len(self.final_list_color))] + + if u'50 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys(): + enComp50Hz = [True if dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['50 Hz'][x]['value'] != 0 else False for x in self.final_list_color] + else: + enComp50Hz = [False for i in range(len(self.final_list_color))] + + enCompBoth = numpy.logical_or(enComp1Hz,enComp50Hz).tolist() + try: + indexTrue = enCompBoth.index(True) + indexesTrue = [i for i,j in enumerate(enCompBoth) if j == True] + selected_color = [kk for kk,vv in backColor.items() if vv != [255,150,150,150]] + valueselectedcolor = [self.final_list_color.index(selected_color[i]) for i in range(len(selected_color))] + commonSelect = list(set(indexesTrue) & set(valueselectedcolor)) + if len(commonSelect)>1: + colorn = QtGui.QColor.fromRgb(255,255,255,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + else: + colorn = QtGui.QColor.fromRgb(backColor[self.final_list_color[commonSelect[0]]][1],backColor[self.final_list_color[commonSelect[0]]][2],backColor[self.final_list_color[commonSelect[0]]][3],backColor[self.final_list_color[commonSelect[0]]][0]) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + except: + #no response after stimulation + colorn = QtGui.QColor.fromRgb(0,0,0,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + #pdb.set_trace() #color = QtGui.QColor.fromRgb(250,0,0,100) r g b alpha + #self.a.setMaterial(newCyl, diffuse=[color.redF(), color.greenF(), color.blueF(), color.alphaF()]) newCyl + + else: + self.ui.list_backColor_Condition.setEnabled(False) + for index_contacts in range(len(dataSEEG.keys())): + #self.locaData.bipoleLabels['contacts'][self.locaData.bipoleLabels['contacts'].keys()[1]]['line']['fontcolor'] + if (u'1 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 0): + fontColorLine = dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['1 Hz'][u'Type of response']['fontcolor'] + if fontColorLine[1] == 0 and fontColorLine[2] == 0 and fontColorLine[3]==0: + fontColorLine = [255,0,0,0] + colorn = QtGui.QColor.fromRgb(fontColorLine[1],fontColorLine[2],fontColorLine[3],fontColorLine[0]) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + elif (u'1 Hz' not in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 0): + colorn = QtGui.QColor.fromRgb(150,150,150,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + elif (u'50 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 1): + fontColorLine = dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['50 Hz'][u'Type of response']['fontcolor'] + if fontColorLine[1] == 0 and fontColorLine[2] == 0 and fontColorLine[3]==0: + fontColorLine = [255,0,0,0] + colorn = QtGui.QColor.fromRgb(fontColorLine[1],fontColorLine[2],fontColorLine[3],fontColorLine[0]) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + elif (u'50 Hz' not in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 1): + colorn = QtGui.QColor.fromRgb(150,150,150,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + if infoHzselected[0]==2: + if (u'1 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()): + fontColorLine1 = dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['1 Hz'][u'Type of response']['fontcolor'] + if fontColorLine1[1] == 0 and fontColorLine1[2] == 0 and fontColorLine1[3]==0: + fontColorLine1 = [255,0,0,0] + else: + fontColorLine1 = [0,0,0,0] + + if (u'50 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()): + fontColorLine50 = dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['50 Hz'][u'Type of response']['fontcolor'] + if fontColorLine50[1] == 0 and fontColorLine50[2] == 0 and fontColorLine50[3]==0: + fontColorLine50 = [255,0,0,0] + else: + fontColorLine50 = [0,0,0,0] + + fontColorBoth =numpy.minimum((numpy.array(fontColorLine50) + numpy.array(fontColorLine1)),255).tolist() + colorn = QtGui.QColor.fromRgb(fontColorBoth[1],fontColorBoth[2],fontColorBoth[3],fontColorBoth[0]) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + + def closeEvent(self, event): + self.quit(event) + + def quit(self, event=None): + reply = QtGui.QMessageBox.question(self, 'Quit',"Quit bipole colors editor ?", QtGui.QMessageBox.Yes |QtGui.QMessageBox.No, QtGui.QMessageBox.No) + if reply == QtGui.QMessageBox.Yes: + if event is None: + self.a.quit() + else: + event.accept() + else: + event.ignore() + + +if __name__=="__main__": + a=QtGui.QApplication(sys.argv) \ No newline at end of file diff --git a/checkSpmVersion.py b/checkSpmVersion.py new file mode 100644 index 0000000..2eb200c --- /dev/null +++ b/checkSpmVersion.py @@ -0,0 +1,7 @@ +def checkSpmVersion(spm_path): + import os + op_cont = open(spm_path+os.sep+'Contents.m') + line = op_cont.readline() + line = op_cont.readline() + spm_version = line.split(' ')[3] + return spm_version diff --git a/control_ftract.py b/control_ftract.py new file mode 100644 index 0000000..5ed3414 --- /dev/null +++ b/control_ftract.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# This software and supporting documentation are distributed by +# Institut Federatif de Recherche 49 +# CEA/NeuroSpin, Batiment 145, +# 91191 Gif-sur-Yvette cedex +# France +# +# This software is governed by the CeCILL license version 2 under +# French law and abiding by the rules of distribution of free software. +# You can use, modify and/or redistribute the software under the +# terms of the CeCILL license version 2 as circulated by CEA, CNRS +# and INRIA at the following URL "http://www.cecill.info". +# +# As a counterpart to the access to the source code and rights to copy, +# modify and redistribute granted by the license, users are provided only +# with a limited warranty and the software's author, the holder of the +# economic rights, and the successive licensors have only limited +# liability. +# +# In this respect, the user's attention is drawn to the risks associated +# with loading, using, modifying and/or developing or reproducing the +# software by the user in light of its specific status of free software, +# that may mean that it is complicated to manipulate, and that also +# therefore means that it is reserved for developers and experienced +# professionals having in-depth computer knowledge. Users are therefore +# encouraged to load and test the software's suitability as regards their +# requirements in conditions enabling the security of their systems and/or +# data to be ensured and, more generally, to use and operate it in the +# same conditions as regards security. +# +# The fact that you are presently reading this means that you have had +# knowledge of the CeCILL license version 2 and that you accept its terms. +# -*- coding: utf-8 -*- +import anatomist.direct.api as anatomist +from soma import aims +from soma.aims import colormaphints +import sys, os, math +import pdb +from PyQt4 import QtCore, QtGui + +sys.path.insert( 0, '.' ) + + +# determine wheter we are using Qt4 or Qt3, and hack a little bit accordingly +# the boolean qt4 gloabl variable will tell it for later usage +#qt4 = False +#if sys.modules.has_key( 'PyQt4'): + #qt4 = True + # + #qt = QtGui + #from PyQt4.uic import loadUi +#else: + #import qt, qtui + #loadUi = qtui.QWidgetFactory.create + +## do we have to run QApplication ? +#if qt.qApp.startingUp(): + #qapp = qt.QApplication( sys.argv ) + #runqt = True +#else: + #runqt = False + + +class fTract_Action( anatomist.cpp.Action ): + def name( self ): + return 'fTract_Action' + + def resetRadius( self ): + print 'reset radius to 1' + s.setRadius( 1. ) + + def startMoveRadius( self, x, y, globx, globy ): + print 'start move radius', x, y + self._initial = ( x, y ) + self._radius = s.radius() + + def endMoveRadius( self, x, y, globx, globy ): + print 'end move radius', x, y + + def moveRadius( self, x, y, globx, globy ): + print 'move radius', x, y + s.setRadius( math.exp( 0.01 * ( self._initial[1] - y ) ) * self._radius ) + + def takePolygon( self, x, y, globx, globy ): + #print 'takePolygon', x, y + + print 'coucou', x,y + + #w = self.view().aWindow() + #obj = w.objectAtCursorPosition( x, y ) + ##print 'object:', obj + #if obj is not None: + #print 'object:', obj, obj.name() + #poly = w.polygonAtCursorPosition( x, y, obj ) + ##print 'polygon:', poly + #mesh = anatomist.cpp.AObjectConverter.aims( obj ) + ##print 'mesh:', mesh + #ppoly = mesh.polygon()[poly] + #vert = mesh.vertex() + ##print ppoly[0], ppoly[1], ppoly[2] + ##print vert[ppoly[0]], vert[ppoly[1]], vert[ppoly[2]] + #global selmesh, selanamesh + #if selmesh is None: + #selmesh = aims.AimsSurfaceTriangle() + #selmesh.vertex().assign( [ vert[ppoly[0]], vert[ppoly[1]], vert[ppoly[2]] ] ) + #selmesh.polygon().assign( [ aims.AimsVector_U32_3( 0, 1, 2 ) ] ) + #if selanamesh is None: + #selanamesh = anatomist.cpp.AObjectConverter.anatomist( selmesh ) + #a = anatomist.Anatomist() + #a.execute( 'SetMaterial', objects=[selanamesh], diffuse=[0,0,1.,1.] ) + #a.execute( 'AddObject', objects=[selanamesh], windows=[w] ) + #selanamesh.setChanged() + #selanamesh.notifyObservers() + +class ftract_control( anatomist.cpp.Control ): + def __init__( self, prio = 25 ): + anatomist.cpp.Control.__init__( self, prio, 'ftract_control' ) + + def eventAutoSubscription( self, pool ): + + key = QtCore.Qt + NoModifier = key.NoModifier + ShiftModifier = key.ShiftModifier + ControlModifier = key.ControlModifier + AltModifier = key.AltModifier + + pdb.set_trace() + self.keyPressEventSubscribe( key.Key_C, NoModifier, + pool.action( 'fTract_Action' ).resetRadius ) + self.mouseLongEventSubscribe( key.LeftButton, NoModifier, + pool.action( 'fTract_Action' ).startMoveRadius, + pool.action( 'fTract_Action' ).moveRadius, + pool.action( 'fTract_Action' ).endMoveRadius, + False ) + self.mousePressButtonEventSubscribe(key.RightButton, NoModifier, + pool.action( 'fTract_Action' ).takePolygon ) + +#a = anatomist.Anatomist() +#pix = qt.QPixmap('/home/b67-belledone/Desktop/epilepsie-manik/Logo-F-TRACT.xpm' ) +#anatomist.cpp.IconDictionary.instance().addIcon( 'ftract_control', pix ) +#ad = anatomist.cpp.ActionDictionary.instance() +#ad.addAction( 'fTract_Action', lambda: fTract_Action() ) +#cd = anatomist.cpp.ControlDictionary.instance() +#cd.addControl( 'ftract_control', lambda: ftract_control(), 25 ) +#cm = anatomist.cpp.ControlManager.instance() +#cm.addControl( 'QAGLWidget3D', '', 'ftract_control' ) + +#s = aims.SurfaceGenerator.sphere(aims.Point3df(10, 10, 10), 4, 32) +##a.registerObject( s ) +#aw = a.createWindow( '3D' ) +#a.addObjects( [ s ], [ aw ] ) + +## run Qt +#if runqt: + #if qt4: + #qapp.exec_() + #else: + #qapp.exec_loop() \ No newline at end of file diff --git a/control_ftract2.py b/control_ftract2.py new file mode 100644 index 0000000..2a3d23f --- /dev/null +++ b/control_ftract2.py @@ -0,0 +1,40 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +from anatomist import cpp as ana +from PyQt4 import QtGui, QtCore, uic +import pdb + +class ControlFtract(ana.Control): + + def __init__(self, prio = 25): + ana.Control.__init__(self,prio,'ControlFtract') + + def eventAutoSubscription(self,pool): #declare actions dispo et comment + + key = QtCore.Qt + NoModifier = key.NoModifier + ShiftModifier = key.ShiftModifier + ControlModifier = key.ControlModifier + AltModifier = key.AltModifier + + self.mousePressButtonEventSubscribe(key.LeftButton,NoModifier,pool.action('fTract_Action').show) + + +class StimulateResults(ana.Action): + + def show(self,x,y,globx,globy): + + print "Toto" + ww = self.view().aWindow() + obj = ww.objectAtCursorPosition( x, y ) + poly = ww.polygonAtCursorPosition( x, y, obj ) + pdb.set_trace() + if isinstance(obj,ana.MObject): #obj.size() == 2: + vertexselected = obj[0].surface().polygon()[poly] + #obj[1].texture1d()[0][2289] + #obj[1].texture1d()[2289] + #obj[1].texture1d()[0] + #http://brainvisa.info/pyanatomist-4.5/sphinx/pyanatomist_examples.html + + otherwindow = [x for x in ana.Anatomist().getWindows() if x is not ww and x.parent() == ww.parent()] \ No newline at end of file diff --git a/cutmeshwidget.ui b/cutmeshwidget.ui new file mode 100644 index 0000000..8537635 --- /dev/null +++ b/cutmeshwidget.ui @@ -0,0 +1,234 @@ + + + Form + + + + 0 + 0 + 306 + 300 + + + + Form + + + + + + center + + + + + + + Qt::Horizontal + + + + 83 + 20 + + + + + + + + orthogonal + + + true + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + -180 + + + 180 + + + 180 + + + Qt::Vertical + + + + + + + -180 + + + 180 + + + Qt::Vertical + + + + + + + -180 + + + 180 + + + Qt::Vertical + + + + + + + + + + true + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + false + + + -180 + + + 180 + + + Qt::Vertical + + + + + + + false + + + -180 + + + 180 + + + 180 + + + Qt::Vertical + + + + + + + false + + + -180 + + + 180 + + + Qt::Vertical + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + false + + + -180 + + + 180 + + + Qt::Vertical + + + + + + + false + + + -180 + + + 180 + + + Qt::Vertical + + + + + + + false + + + -180 + + + 180 + + + 180 + + + Qt::Vertical + + + + + + + + + + + diff --git a/dicomutilities.py b/dicomutilities.py new file mode 100644 index 0000000..3757679 --- /dev/null +++ b/dicomutilities.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- + +# Group of functions to read, organize, and convert DICOM files +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# + +import re, shutil +from PyQt4 import QtCore +from externalprocesses import * + + +# Matlab code : convert DICOM files to a NIFTI file with SPM +spm_convert_dicom = "spm_get_defaults; cd('%s'); hdr = spm_dicom_headers(%s);name = '%s';a=spm_dicom_convert(hdr, 'all', 'flat', 'nii');if length(a.files)<1 || isempty(a.files{1}); quit; end;for i=1:length(a.files) if i==1 movefile(a.files{i}, [name '.nii']);else movefile(a.files{i}, [name '_' num2str(i) '.nii']);end;end;quit; " + + +# Construction de la liste des codes: +# - dcmdump d'un fichier DICOM +# - suppression des lignes sans intéret +# -recherche et remplace avec kwrite mode regexp +# (\([\da-f]+,[\da-f]+\)).*#[^a-zA-Z]+(\w+) remplacé par '\1':'\2',\\ + +# The DICOM codes that will be extracted from each image. +keepCodes = {\ +# '(0008,0012)':'InstanceCreationDate',\ +# '(0008,0013)':'InstanceCreationTime',\ +# '(0008,0014)':'InstanceCreatorUID',\ +# '(0008,0016)':'SOPClassUID',\ +# '(0008,0018)':'SOPInstanceUID',\ + '(0008,0020)':'StudyDate',\ + '(0008,0021)':'SeriesDate',\ + '(0008,0022)':'AcquisitionDate',\ +# '(0008,0023)':'ContentDate',\ + '(0008,0030)':'StudyTime',\ + '(0008,0031)':'SeriesTime',\ + '(0008,0032)':'AcquisitionTime',\ +# '(0008,0033)':'ContentTime',\ + '(0008,0050)':'AccessionNumber',\ +# '(0008,0060)':'Modality',\ +# '(0008,0070)':'Manufacturer',\ +# '(0008,0080)':'InstitutionName',\ +# '(0008,1010)':'StationName',\ + '(0008,1030)':'StudyDescription',\ + '(0008,103e)':'SeriesDescription',\ +# '(0008,1040)':'InstitutionalDepartmentName',\ + '(0010,0010)':'PatientsName',\ +# '(0010,0020)':'PatientID',\ + '(0010,0030)':'PatientsBirthDate',\ + '(0010,0040)':'PatientsSex',\ +# '(0018,0015)':'BodyPartExamined',\ +# '(0018,0020)':'ScanningSequence',\ + '(0018,0023)':'MRAcquisitionType',\ + '(0018,0050)':'SliceThickness',\ +# '(0018,0080)':'RepetitionTime',\ +# '(0018,0081)':'EchoTime',\ +# '(0018,0083)':'NumberOfAverages',\ +# '(0018,0087)':'MagneticFieldStrength',\ + '(0018,0088)':'SpacingBetweenSlices',\ + '(0018,1030)':'ProtocolName',\ +# '(0018,1250)':'ReceiveCoilName',\ +# '(0018,1310)':'AcquisitionMatrix',\ + '(0018,9073)':'AcquisitionDuration',\ + '(0020,000d)':'StudyInstanceUID',\ + '(0020,000e)':'SeriesInstanceUID',\ + '(0020,0010)':'StudyID',\ +# '(0020,0011)':'SeriesNumber',\ +# '(0020,0012)':'AcquisitionNumber',\ +# '(0020,0013)':'InstanceNumber',\ +# '(0020,0032)':'ImagePositionPatient',\ +# '(0020,0037)':'ImageOrientationPatient',\ +# '(0020,0052)':'FrameOfReferenceUID',\ +# '(0028,0010)':'Rows',\ +# '(0028,0011)':'Columns',\ +# '(0028,0030)':'PixelSpacing',\ +# '(0028,0100)':'BitsAllocated',\ +# '(0028,0101)':'BitsStored',\ +# '(0032,1033)':'RequestingService',\ +# '(0032,1060)':'RequestedProcedureDescription',\ +# '(0040,0241)':'PerformedStationAETitle',\ +# '(0040,0244)':'PerformedProcedureStepStartDate',\ +# '(0040,0245)':'PerformedProcedureStepStartTime',\ +# '(0040,0250)':'PerformedProcedureStepEndDate',\ +# '(0040,0251)':'PerformedProcedureStepEndTime',\ +# '(0040,0253)':'PerformedProcedureStepID',\ +# '(0040,0254)':'PerformedProcedureStepDescription',\ + '(2001,100a)':'SliceNumberMR',\ + '(2001,100b)':'SliceOrientation'} + +# Regular expression to recognize a dicom tag from a text line +dcmCodeRE = re.compile(r'^\([\da-f]+,[\da-f]+\)') +# Regular expression to get the content of a DICOM tag +dcmValueRE = re.compile(r'\([\da-f]+,[\da-f]+\)\s+\w+\s+\[?([^\]#]*)\]?') + + +def getDcmValue(line): + """Gets the value of a DICOM tag from a text line + If there is no such value, this will throw an exception + """ + m = dcmValueRE.search(line) + if m is None: + print 'No value in DCM line **'+line + return m.group(1) + + +def organizeDicomFiles(files, thread = False): + """ Creates a dictionary of all files provided with DICOM tag data extracted by dcmdump (of DCMTK) + :param thread : If true, a Qt signal 'dicomFilesOutput(PyQt_PyObject)' will be emitted on completion with the result dictionary + Type of result : dcm={'DCM0001':{'StudyDate':'20140101','SeriesDate':'20140101',...}, 'DCM0002':{'StudyDate':'20140101','SeriesDate':'20140101',...},... } + """ + dcm = {} + goodkeys = [] + for k in keepCodes.keys(): + goodkeys.extend(['+P',k[1:-1]]) + + for f in files: + print 'Processing '+f + dcm[f] = {} + # Get dcmdump info for the current file f + lines = runCmd(['dcmdump','-M']+goodkeys+[f, ]) + + # Python 2.7 -> subprocess.check_output(['dcmdump', f]) + for line in lines: + k = line[:11] # Get the key from the line + if k in keepCodes: + dcm[f][keepCodes[k]] = getDcmValue(line) + if thread: + print "emitting signal" + QtCore.QThread.currentThread ().emit(QtCore.SIGNAL('dicomFilesOutput(PyQt_PyObject)'), dcm) + return dcm + +def patientNameDecode(p): + """ Converts DICOM-style patient name LastName^FirstName^SecondName to LastName_FirstName_SecondName""" + return p.replace('^', '_').rstrip('_').replace(' ','-') + +def datetimeDecode(d,t): + """ Decodes DICOM datetime format 20140101, 120531 to human-readable 'Date: 2014-01-01, heure: 12:05:31'""" + if len(d) < 8 or len(t)<6: + print "DICOM Datetime is invalid !" + return '' + return str('Date: '+d[:4] +'-'+d[4:6]+'-'+ d[6:] +', heure: '+ t[:2] + ':'+t[2:4]+':'+t[4:]) + +def dateDecode(d): + """ Decodes DICOM date format 20140101, to human-readable '2014-01-01' """ + if len(d)<8: + print "DICOM Datetime is invalid !" + return '' + return d[:4] +'-'+d[4:6]+'-'+ d[6:] + +def getSeries(dcmFiles): + """ From organizeDicomFiles(f) output, returns a dictionnary of series with the most important DICOM tag values and list of files""" + series={} + + for d,dcm in dcmFiles.iteritems(): + dc = lambda x:dcm[x] if x in dcm else '' + if dcm['SeriesInstanceUID'] in series: + series[dcm['SeriesInstanceUID']]['files'].append(d) + else: + + series[dcm['SeriesInstanceUID']] = {'files':[d,],\ + 'SeriesDescription':dc('SeriesDescription'),\ + 'SeriesDate':dc('SeriesDate'),\ + 'SeriesTime':dc('SeriesTime'),\ + 'StudyDescription':dc('StudyDescription'),\ + 'PatientsName':str(dc('PatientsName')),\ + 'PatientsBirthDate':dc('PatientsBirthDate'),\ + #'SliceThickness':dcm['SliceThickness'],\ + #'PixelSpacing':dcm['PixelSpacing'],\ + 'StudyInstanceUID':str(dc('StudyInstanceUID')) + } + return series + +def serie2filename(s): + """ Generate the filename for the provided serie dictionary""" + seriesName = s['SeriesDate']+'_'+s['SeriesTime']+'_'+s['SeriesDescription'] + return seriesName.replace(' ', '_') + +def getStudies(dcmFiles): + """ Returns a dictionnary of studies available in organizeDicomFiles(f) output""" + studies={} + for dcm in dcmFiles.itervalues(): + if dcm['StudyInstanceUID'] not in studies: + studies[dcm['StudyInstanceUID']]={'name':datetimeDecode(dcm['StudyDate'],dcm['StudyTime']), 'PatientsName':dcm['PatientsName']} + return studies + +def getPatients(series): + """ Returns a list of patients available in organizeDicomFiles(f) output""" + patients = [] + for s in series.itervalues(): + if str(s['PatientsName']) not in patients: + patients.append(str(s['PatientsName'])) + return patients + +def copySeriesTo(series, path, move = False, nifti = False): + """ Copy the series listed as a dictionary to a directory (path) and organize them in a patientName/Serie/ hierarchy + :param series : the series to copy/move + :param path the base directory that will contain the patientName/Serie/ hierarchy + :param move If true, files will be move. If false (default), they will be copied. + :param nifti : if nifti is true, the nifti files listed in the series parameter will be copied/moved. If not, the dicom files will be copied/moved. + """ + for s in series.itervalues(): + try: + patientPath = os.path.join(path, patientNameDecode(s['PatientsName'])) + os.mkdir(patientPath) + except OSError, e: + pass + #if e.errno != os.errno.EEXIST: # DEPEND DE LA VERSION PYTHON + # raise + + seriesName = serie2filename(s) + + try: + seriesPath = os.path.join(patientPath, seriesName) + os.mkdir(seriesPath) + except OSError, e: + #if e.errno != os.errno.EEXIST: + print 'ERREUR : impossible de creer le dossier '+seriesPath+': '+e.strerror + # On oublie cette série ou on écrase ? + #continue + try: + if nifti is False: + files = s['files'] + else: + if 'nifti' not in s: + print "Cannot move unavailable Nifti files : use convertSeriesToNifti first !" + continue + files = s['nifti'] + + if move == False: + for f in files: + shutil.copyfile(f, seriesPath) + else: + for f in files: + shutil.move(f, seriesPath) + + except OSError, e: + print 'ERREUR : impossible de copier/déplacer '+f+' vers '+seriesPath+': '+e.strerror + except IOError, e: + print 'Erreur IO : impossible de copier/déplacer '+f+' vers '+seriesPath+': '+e.strerror + + + +def convertSeriesToNifti(series, path): + """Convert the series of dicom files to nifti files. Files are named by the serie name and in patientName directories. + The conversion is done with matlab/SPM and the returned QThread objects must be kept until completion of the conversion.""" + threads = [] + for i, s in series.iteritems(): + try: + patientPath = os.path.join(path, patientNameDecode(s['PatientsName'])) + os.mkdir(patientPath) + except OSError, e: + pass + #if e.errno != os.errno.EEXIST: # DEPEND DE LA VERSION DE PYTHON + # raise + + seriesName = s['SeriesDate']+'_'+s['SeriesTime']+'_'+s['SeriesDescription'] + seriesName = seriesName.replace(' ', '_') + niftiPath = os.path.join(patientPath, seriesName) # without the '.nii', it will be added in matlab + series[i]['niftiPath'] = niftiPath + '.nii' + print "Creating nifti at "+niftiPath + # spm needs a list of filenames where ALL FILENAMES ARE THE SAME LENGTH (stupid matlab string behaviour grrr) + # So let's make a stupid array with same-length filenames (add spaces at the end) + matfiles = s['files'] + maxcars = max([len(s) for s in matfiles]) + matfiles = [s.ljust(maxcars) for s in matfiles] + mtlb = matlabRunNB(spm_convert_dicom%(patientPath, repr(matfiles).replace(',', ';'), niftiPath)) + mtlb.start() + threads.append(mtlb) + + return threads diff --git a/editor.py b/editor.py new file mode 100644 index 0000000..4dab048 --- /dev/null +++ b/editor.py @@ -0,0 +1,373 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# + + +import sys, os, pickle +from PyQt4 import QtGui, QtCore, uic + +import anatomist.direct.api as anatomist +from soma import aims + +import pdb + + +# Small dialog to create a 3D electrode template for use in BrainVisa/Anatomist +# +# Each electrode is a group of cylinders. +# This software should provide an easy way to create new models of electrodes with realtime visualization +# +# It can also be used from another program that needs electrode models : it can load electrod models and +# create the necessary objects in Anatomist to display them along other objects. +# In that use case, you should : +# dialog = ElectrodeEditorDialog(theCurrentAnatomist) +# dialog.open() +# dialog.setDisplayReferential(electrodeReferential) +# cylinders = dialog.getDisplayed() +# meshes = dialog.getAnatomistObjects() +# +class ElectrodeEditorDialog(QtGui.QWidget): + + def __init__(self, anato = None, app=None): + + # UI init + QtGui.QWidget.__init__(self) + self.ui = uic.loadUi("electrodeEditor.ui", self) + self.setWindowTitle('Electrode editor') + + # Init of variables + self.app = app + self.cylinders = {} + self.displayed = {} + #self.elementIndex = 1 + self.currentColorHue = 0 + self.typeColors = {} + + # Linking UI elements to functions + self.connect(self.exitButton, QtCore.SIGNAL('clicked()'), self.quit) + self.connect(self.openButton, QtCore.SIGNAL('clicked()'), self.open) + self.connect(self.saveButton, QtCore.SIGNAL('clicked()'), self.save) + self.connect(self.addButton, QtCore.SIGNAL('clicked()'), self.addCylinder) + self.connect(self.updateButton, QtCore.SIGNAL('clicked()'), self.updateCylinder) + self.connect(self.deleteButton, QtCore.SIGNAL('clicked()'), self.deleteCylinder) + self.connect(self.axisCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.axisChanged) + #self.connect(self.typeCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.updateName) + + self.cylinderList.sortItems(QtCore.Qt.AscendingOrder) + self.connect(self.cylinderList, QtCore.SIGNAL("currentItemChanged(QListWidgetItem*,QListWidgetItem*)"), self.cylinderListClick) #itemClicked + + # Anatomist windows + if anato is None: + self.a = anatomist.Anatomist('-b' ) + else: + self.a = anato + layout = QtGui.QHBoxLayout( self.anatomistBox ) + self.axWindow = self.a.createWindow( 'Axial', no_decoration=True ) + self.sagWindow = self.a.createWindow( 'Sagittal', no_decoration=True ) + self.corWindow = self.a.createWindow( 'Coronal', no_decoration=True ) + self.wins = [self.axWindow, self.sagWindow, self.corWindow] + [w.setHasCursor(0) for w in self.wins] + self.sagWindow.setParent( self.anatomistBox ) + self.axWindow.setParent( self.anatomistBox ) + self.corWindow.setParent( self.anatomistBox ) + layout.addWidget( self.sagWindow.getInternalRep() ) + layout.addWidget( self.axWindow.getInternalRep() ) + layout.addWidget( self.corWindow.getInternalRep() ) + + + # Enable or disable axis values widgets if the axisCombo changes + def axisChanged(self, value): + value = str(value) + if value == "Custom...": + self.xValue.setEnabled(True) + self.yValue.setEnabled(True) + self.zValue.setEnabled(True) + else: + self.xValue.setEnabled(False) + self.yValue.setEnabled(False) + self.zValue.setEnabled(False) + + + # Load an Electrode Definition file + def open(self, model=None): + if model is not None: + if not os.path.isfile(model): + path = '/home/manik/prog/electrophysiology/epilepsie/'+str(model) + else: + path = model + else: + path = QtGui.QFileDialog.getOpenFileName(self, "Open Electrode Definition File", "", "Electrode Definition files (*.elecdef)") + if not os.path.exists(path): + print 'No electrode model at '+str(path) + return + + filein = open(path, 'rb') + self.cylinders = pickle.load(filein) + filein.close() + # Reset colors + self.currentColorHue = 0 + self.typeColors = {} + # If shape is not defined, it's a cylinder + for name in self.cylinders: + if 'shape' not in self.cylinders[name]: + self.cylinders[name]['shape']='cylinder' + # If center of elements was not saved, compute it + if 'center' not in self.cylinders[name]: + pos = self.cylinders[name]['position'] + v = self.cylinders[name]['length'] + vec = self.cylinders[name]['vector'] + self.cylinders[name]['center'] = [pos[0] + v*vec[0]/2.0, self.posYValue.value()+v*vec[1]/2.0, self.posZValue.value()+v*vec[2]/2.0] + # Display the cylinders + self.updateCylinderList() + self.updateDisplay() + + # Save an Electrode Definition file + def save(self): + path = QtGui.QFileDialog.getSaveFileName(self, "Save Electrode Definition File", "", "Electrode Definition files (*.elecdef)") + if path is None or str(path) == "": + return + fileout = open(path, 'wb') + pickle.dump(self.cylinders, fileout) + fileout.close() + + # Get the real orientation vector from the UI + def getAxisVector(self): + # Valeur réelle de l'axe + ax = str(self.axisCombo.currentText()) + if ax == "Custom...": + vec = [self.xValue.value(),self.yValue.value(), self.zValue.value()] + elif ax == "Axe X": + vec = [1.0,0.0,0.0] + elif ax == "Axe Y": + vec = [0.0,1.0,0.0] + elif ax == "Axe Z": + vec = [0.0,0.0,1.0] + else: + QtGui.QMessageBox.warning(self, "Erreur", "L'axe ("+ax+") est inconnu !") + return None + return ax, vec + + + # Add a new cylinder to the current electrode + def addCylinder(self): + # Safety check to avoid overwriting a cylinder + name = str(self.nameEdit.text()) + if name in self.cylinders: + QtGui.QMessageBox.warning(self, "Erreur", "Un élément avec ce nom existe déjà ! Changez le nom !") + return + + # Store the cylinder + (ax, vec) = self.getAxisVector() + v = self.lengthValue.value() + self.cylinders[name] = {'axis':ax, + 'vector':vec, + 'position':[self.posXValue.value(), self.posYValue.value(), self.posZValue.value()], + 'diameter': self.diameterValue.value(), + 'length': v, + 'center': [self.posXValue.value()+v*vec[0]/2.0, self.posYValue.value()+v*vec[1]/2.0, self.posZValue.value()+v*vec[2]/2.0], + 'type': str(self.typeCombo.currentText()), + 'shape':'cylinder'} + + # add an item to the cylinderList + item = QtGui.QListWidgetItem(name,self.cylinderList) + + # Display the cylinder + self.displayCylinder(name) + + # Prepare for the next cylinder + self.posXValue.setValue(self.posXValue.value() + vec[0]*self.lengthValue.value()) + self.posYValue.setValue(self.posYValue.value() + vec[1]*self.lengthValue.value()) + self.posZValue.setValue(self.posZValue.value() + vec[2]*self.lengthValue.value()) + + ## Set an element name that is not used yet + #while ("Element "+str(self.elementIndex)) in self.cylinders: + #self.elementIndex += 1 + #self.nameEdit.setText("Element "+str(self.elementIndex)) + + if self.typeCombo.currentIndex()==0: + self.typeCombo.setCurrentIndex(1) + elif self.typeCombo.currentIndex()==1: + self.typeCombo.setCurrentIndex(0) + + self.updateName() + + # Update the currently selected cylinder + def updateCylinder(self): + # TODO if the name changes ? + name = str(self.cylinderList.currentItem().text()) + (ax, vec) = self.getAxisVector() + v = self.lengthValue.value() + self.cylinders[name] = {'axis':ax, + 'vector':vec, + 'position':[self.posXValue.value(), self.posYValue.value(), self.posZValue.value()], + 'diameter': self.diameterValue.value(), + 'length': v, + 'center': [self.posXValue.value()+v*vec[0]/2.0, self.posYValue.value()+v*vec[1]/2.0, self.posZValue.value()+v*vec[2]/2.0], + 'type': str(self.typeCombo.currentText()), + 'shape':'cylinder'} + self.displayCylinder(name) + + # Display a cylinder selected from the list + def selectCylinder(self, name): + cyl = self.cylinders[name] + self.axisCombo.setCurrentIndex(self.axisCombo.findText(cyl['axis'])) + v = cyl['vector'] + self.xValue.setValue(v[0]) + self.yValue.setValue(v[1]) + self.zValue.setValue(v[2]) + v = cyl['position'] + self.posXValue.setValue(v[0]) + self.posYValue.setValue(v[1]) + self.posZValue.setValue(v[2]) + + self.diameterValue.setValue(cyl['diameter']) + self.lengthValue.setValue(cyl['length']) + self.typeCombo.setCurrentIndex(self.typeCombo.findText(cyl['type'])) + + self.displaySelect(name) + + # Delete the selected + def deleteCylinder(self): + item = self.cylinderList.takeItem(self.cylinderList.currentRow()) + self.undisplayCylinder(str(item.text())) + del self.cylinders[str(item.text())] + item = None + + # Refills the cylinderlist from the stored data + def updateCylinderList(self): + self.cylinderList.clear() + item = None + for name in sorted(self.cylinders): + item = QtGui.QListWidgetItem(name,self.cylinderList) + self.cylinderList.setCurrentItem(item) + + + # Click on an item and column in the list + def cylinderListClick(self, item,prevItem=None): + name = str(item.text()) + self.selectCylinder(name) + + def closeEvent(self, event): + self.quit() + + def quit(self): + reply = QtGui.QMessageBox.question(self, 'Message', + "Are you sure to quit?", QtGui.QMessageBox.Yes | + QtGui.QMessageBox.No, QtGui.QMessageBox.No) + + if reply == QtGui.QMessageBox.Yes: + self.app.quit() + else: + pass + + # Display functions + def displayCylinder(self, name): + # If it is already there, remove it + self.undisplayCylinder(name) + self.displayed[name] = None + t = self.cylinders[name]['type'] + p = self.cylinders[name]['position'] + v = self.cylinders[name]['vector'] + r = self.cylinders[name]['diameter']/2.0 + pEnd = p[0] + v[0]*self.cylinders[name]['length'], p[1] + v[1]*self.cylinders[name]['length'], p[2] + v[2]*self.cylinders[name]['length'] + #print "New cylinder mesh at %.2f, %.2f, %.2f, radius=%.2f" % (p[0], p[1], p[2], r) + newCyl = self.a.toAObject(aims.SurfaceGenerator.cylinder(aims.Point3df(p[0], p[1], p[2]), aims.Point3df(pEnd), r, r, 24, True, True)) + + # Couleur automatique par catégorie + if t not in self.typeColors: + self.currentColorHue = (self.currentColorHue + 40) % 256 + self.typeColors[t] = QtGui.QColor.fromHsv(self.currentColorHue, 245, 220, 255); + color = self.typeColors[t] + self.a.setMaterial(newCyl, diffuse=[color.redF(), color.greenF(), color.blueF(), color.alphaF()]) + self.a.addObjects(newCyl, self.wins) + self.displayed[name] = {'mesh':newCyl, 'type':t} + + def undisplayCylinder(self, name): + if name in self.displayed: + self.a.removeObjects(self.displayed[name]['mesh'], self.wins) + self.a.deleteObjects(self.displayed[name]['mesh']) + + def updateDisplay(self): + self.clearDisplay() + # Add the new ones + for name in self.cylinders: + self.displayCylinder(name) + + def updateDisplayCylinder(self, name): + # Modify + self.a.deleteObjects([self.displayed[name]['mesh'],]) + self.displayCylinder(name) + + def clearDisplay(self): + # Destroy all anatomist objects and reset "displayed" list + if len(self.displayed) != 0: + meshes = [self.displayed[name]['mesh'] for name in self.displayed] + self.a.removeObjects(meshes, self.wins) + self.a.deleteObjects(meshes) + self.displayed={} + + def getDisplayed(self): + return self.displayed + + def getCylinders(self): + return self.cylinders + + def getAnatomistObjects(self): + return [self.displayed[n]['mesh'] for n in self.displayed] + + def plotMeshes(self): + return [self.displayed[n]['mesh'] for n in self.displayed if self.displayed[n]['type'] == 'Plot'] + + def setDisplayReferential(self, referential): + for name in self.displayed: + self.a.assignReferential(referential, self.displayed[name]['mesh']) + + def displaySelect(self, name): + g = self.a.getDefaultWindowsGroup() + if name in self.displayed: + g.setSelection(self.displayed[name]['mesh']) + else: + print "Cannot find %s in self.displayed -> cannot light up selection"%name + + def updateName(self): + + element_number = 1 + last_length = 0 + if self.typeCombo.currentIndex()==0: + for i_index in range(len(self.cylinders.keys())): + if self.cylinders[self.cylinders.keys()[i_index]]['type'] == 'Plot': + element_number += 1 + element_name = 'Plot'+str(element_number) + if 'Plot'+str(element_number-1) in self.cylinders.keys(): + last_length = self.cylinders['Plot'+str(element_number-1)]['length'] + elif self.typeCombo.currentIndex()==1: + for i_index in range(len(self.cylinders.keys())): + if self.cylinders[self.cylinders.keys()[i_index]]['type'] == 'Tube': + element_number += 1 + element_name = 'Element '+str(element_number) + if 'Element '+str(element_number-1) in self.cylinders.keys(): + last_length = self.cylinders['Element '+str(element_number-1)]['length'] + #while ("Element "+str(self.elementIndex)) in self.cylinders: + #self.elementIndex += 1 + self.nameEdit.setText(element_name) + if last_length !=0: + self.lengthValue.setValue(last_length) + + +# Fonction principale qui lance l'interface +def main(noapp=0): + app = None + if noapp == 0: + app = QtGui.QApplication(sys.argv) + window = ElectrodeEditorDialog(app = app) + window.show() + if noapp == 0: + sys.exit(app.exec_()) + +if __name__ == "__main__": + main() + diff --git a/electrode.py b/electrode.py new file mode 100644 index 0000000..b532622 --- /dev/null +++ b/electrode.py @@ -0,0 +1,209 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# (c) Inserm U836 2013 - Manik Bhattacharjee +# +# License GNU GPL v3 + +import os, pickle +from soma import aims +from PyQt4 import QtGui +import pdb + +# TODO : should use JSON, not pickle, but Brainvisa-4.3.0 pack does not contain json module for python + +# Each electrode is a group of cylinders. +# +# This can load electrode models and create the necessary objects in Anatomist to display them +# In that use case, you should : +# el = ElectrodeModel(theCurrentAnatomist) +# el.open('fileOdModel.elecdef') +# el.setDisplayReferential(electrodeReferential) +# cylinders = el.getDisplayed() +# meshes = el.getAnatomistObjects() +class ElectrodeModel: + + def __init__(self, anato = None, typeColors = {}, modelPath=None, dispMode = None, dispParams=None): + # Init of variables -> typeColors is a dict {'Plot':QColor(r,g,b), 'Other':QColor(R,G,B),...} + self.cylinders = {} + self.dispMode = 'real' + self.dispParams = {} + self.displayed = {} + self.typeColors = typeColors + self.a = anato + if modelPath is not None: + self.open(modelPath, dispMode, dispParams) + + # Load an Electrode Definition file + def open(self, path=None, dispMode = None, dispParams=None,bipole=None): + if path is None or not os.path.isfile(path): + print 'No electrode model at '+repr(path) + return False + + filein = open(path, 'rb') + self.cylinders = pickle.load(filein) + filein.close() + + # Reset colors + self.currentColorHue = 0 + self.typeColors = {} + # If shape is not defined, it's a cylinder + for name in self.cylinders: + if 'shape' not in self.cylinders[name]: + self.cylinders[name]['shape']='cylinder' + # If center of elements was not saved, compute it + if 'center' not in self.cylinders[name]: + pos = self.cylinders[name]['position'] + v = self.cylinders[name]['length'] + vec = self.cylinders[name]['vector'] + self.cylinders[name]['center'] = [pos[0] + v*vec[0]/2.0, pos[1]+v*vec[1]/2.0, pos[2]+v*vec[2]/2.0] + # Create the meshes + if dispMode: + self.dispMode = dispMode + if dispParams: + self.dispParams = dispParams + self.updateDisplay() + return True + + # Save an Electrode Definition file + def save(self, path = None): + if path is None or not os.path.isfile(path): + print "Cannot write electrode definition : invalid file path " + repr(path) + return False + fileout = open(path, 'wb') + pickle.dump(self.cylinders, fileout) + fileout.close() + return True + + + # Display functions + + def setDisplayMode(self, mode='real', parameters={}): + """ Mode display : 'real', 'sphere', 'off'... parameters is {'diameter: 2mm} for the sphere mode""" + self.dispMode = mode + self.dispParams = parameters + + + def displayCylinder(self, name): + # If it is already there, remove it + self.undisplayCylinder(name) + self.displayed[name] = None + t = self.cylinders[name]['type'] + p = self.cylinders[name]['position'] + v = self.cylinders[name]['vector'] + r = self.cylinders[name]['diameter']/2.0 + newCyl = None + + if self.dispMode == 'off': + self.displayed[name] = {'mesh':None, 'type':t} + return + if self.dispMode not in ['real', 'sphere', 'bipole']: + print "Unknown dispMode %s for electrode ! Using 'real'..."%repr(self.dispMode) + self.dispMode = 'real' + + if self.dispMode == 'real': + pEnd = p[0] + v[0]*self.cylinders[name]['length'], p[1] + v[1]*self.cylinders[name]['length'], p[2] + v[2]*self.cylinders[name]['length'] + newCyl = self.a.toAObject(aims.SurfaceGenerator.cylinder(aims.Point3df(p[0], p[1], p[2]), aims.Point3df(pEnd), r, r, 24, True, True)) + self.a.releaseObject(newCyl) + elif self.dispMode == 'sphere': + diam = 2.0 + if self.dispParams.has_key('diameter'): + diam = float(self.dispParams['diameter']) + if t == 'Plot': # Ignore the other parts + pCenter = (p[0] + v[0]*self.cylinders[name]['length']/2.0, p[1] + v[1]*self.cylinders[name]['length']/2.0, p[2] + v[2]*self.cylinders[name]['length']/2.0) + newCyl = self.a.toAObject(aims.SurfaceGenerator.sphere(aims.Point3df(pCenter[0], pCenter[1], pCenter[2]), diam, 32)) + self.a.releaseObject(newCyl) + #newCyl = self.a.toAObject(aims.SurfaceGenerator.cube(aims.Point3df(pCenter[0], pCenter[1], pCenter[2]), 2.0)) + elif self.dispMode == 'bipole': + #pCenter = (p[0] + v[0]*self.cylinders[name]['length']/2.0, p[1] + v[1]*self.cylinders[name]['length']/2.0, p[2] + v[2]*self.cylinders[name]['length']/2.0) + #to change one day + newCyl = self.a.toAObject(aims.SurfaceGenerator.ellipse(aims.Point3df(p[0],p[1],p[2]),2.5,1.5,50)) + self.a.releaseObject(newCyl) + #aims.SurfaceGenerator.ellipse() + + # Automatic color for an unknown type + if t not in self.typeColors: + self.currentColorHue = (self.currentColorHue + 40) % 256 + self.typeColors[t] = QtGui.QColor.fromHsv(self.currentColorHue, 245, 220, 255); + color = self.typeColors[t] + if newCyl is not None: + self.a.setMaterial(newCyl, diffuse=[color.redF(), color.greenF(), color.blueF(), color.alphaF()]) + self.displayed[name] = {'mesh':newCyl, 'type':t} + #print "Adding %s mesh for %s : %s"%(t,name,repr(newCyl)) + + def undisplayCylinder(self, name): + if name in self.displayed: + print "electrode : undisplay cylinder "+name + if self.displayed[name]['mesh'] is not None: + self.a.deleteObjects(self.displayed[name]['mesh']) + print "UNDISPLAY cylinder : DELETED %s"%name + self.displayed[name]['mesh'] = None # CURRENT + + def updateDisplay(self): + self.clearDisplay() + for name in self.cylinders: + self.displayCylinder(name) + + def updateDisplayCylinder(self, name): + self.undisplayCylinder(name) + self.displayCylinder(name) + + def clearDisplay(self): + # Destroy all anatomist objects and reset "displayed" list + if len(self.displayed) != 0: + meshes = [self.displayed[name]['mesh'] for name in self.displayed if self.displayed[name]['mesh'] is not None] + print "electrode : Removing all meshes" + #traceback.print_stack(limit=4) + try: + self.a.deleteObjects(meshes) # Does not work from locateElectrodes.py... CURRENT + except: + pass + for n in self.displayed: + self.displayed[n]['mesh']=None + self.displayed={} + + def getDisplayed(self): + return self.displayed + + def getCylinder(self, name): + return self.cylinders[name] + + def getCylinders(self): + return self.cylinders + + def getPlots(self): + return dict([(k,p) for k,p in self.cylinders.iteritems() if p['type'] == 'Plot']) + + def countPlots(self): + return len(self.getPlots()) + + def countCylinders(self): + return len(self.cylinders) + + def getAnatomistObjects(self): + return [self.displayed[n]['mesh'] for n in self.displayed if self.displayed[n]['mesh'] is not None] + + def plotMeshes(self): + return [self.displayed[n]['mesh'] for n in self.displayed if self.displayed[n]['type'] == 'Plot' and self.displayed[n]['mesh'] is not None] + + def setDisplayReferential(self, referential): + for name in self.displayed: + if self.displayed[name]['mesh'] is not None: + self.a.assignReferential(referential, self.displayed[name]['mesh']) + + def setTypeColors(self, typeColors): + self.typeColors = typeColors + # Automatic color for an unknown type + for name in self.cylinders: + t = self.cylinders[name]['type'] + if t not in self.typeColors: + self.currentColorHue = (self.currentColorHue + 40) % 256 + self.typeColors[t] = QtGui.QColor.fromHsv(self.currentColorHue, 245, 220, 255); + color = self.typeColors[t] + pdb.set_trace() + self.a.setMaterial(newCyl, diffuse=[color.redF(), color.greenF(), color.blueF(), color.alphaF()]) + + def displaySelect(self, name): + g = self.a.getDefaultWindowsGroup() + g.setSelection(self.displayed[name]['mesh']) + + diff --git a/electrodeEditor.ui b/electrodeEditor.ui new file mode 100644 index 0000000..b7a2511 --- /dev/null +++ b/electrodeEditor.ui @@ -0,0 +1,374 @@ + + + Form + + + + 0 + 0 + 705 + 837 + + + + Form + + + + + + + + Ouvrir... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Enregistrer sous... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Quitter + + + + + + + + + Orientation + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">L'axe oriente le cylindre : </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- <span style=" font-weight:600;">axe Z</span> : vertical (dorso-ventral) et orienté vers le bas</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- <span style=" font-weight:600;">axe Y</span> : rostro-caudal, orienté vers l'avant (le nez)</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- <span style=" font-weight:600;">axe X</span> : médian-latéral, orienté de la gauche vers la droite</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- <span style=" font-weight:600;">Custom</span> permet de choisir un axe arbitraire (<span style=" font-weight:600;">attention</span>, le vecteur choisi doit être de norme 1 !)</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Axe Z + + + + + Axe Y + + + + + Axe X + + + + + Custom... + + + + + + + + false + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + X + + + + + + + + false + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + Y + + + + + + + + false + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + Z + + + + + + + + + + Position + + + + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + X + + + + + + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + Y + + + + + + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + Z + + + + + + + + + + + + + + Diamètre (mm) + + + + + + + + + + Longueur (mm) + + + + + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + + + + + Plot1 + + + + + + + + Plot + + + + + Tube + + + + + + + + + + + + + + Supprimer + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Appliquer les changements + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ajouter + + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Sagittal - Axial - Coronal + + + Qt::AlignCenter + + + + + + + + diff --git a/electrodedisplaywidget.py b/electrodedisplaywidget.py new file mode 100644 index 0000000..d1ae2f8 --- /dev/null +++ b/electrodedisplaywidget.py @@ -0,0 +1,1301 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# Widget to select and display electrode plots on a common referential/template +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# +# +from PyQt4 import QtGui, QtCore, uic + +import sys, pickle, shutil, traceback, os, json, re, numpy, csv + + +from brainvisa import axon +from brainvisa import anatomist +from soma import aims +import registration + +from locateElectrodes import createElectrode, getPlotsCenters, getPlots, getPlotsNames, createBipole +from referentialconverter import ReferentialConverter +from templatewidget import TemplateMRI, TemplateMNI +from brainvisa.data.readdiskitem import ReadDiskItem +from brainvisa.data.writediskitem import WriteDiskItem +from brainvisa.data import neuroHierarchy +from readSulcusLabelTranslationFile import * +from readFreesurferLabelFile import * +from externalprocesses import PythonExecutor +from checkSpmVersion import * +from readFunctionalTractography import * +from scipy import spatial as sc_sp +#from numpy.matlib import repmat +from collections import OrderedDict +import control_ftract +from locateElectrodes import natural_keys + +from bipoleSEEGColors import bipoleSEEGColors +from control_ftract2 import * + +import pdb + +def loadElectrodeModels(): + """Load electrode models from the database""" + models = {} + rdiEM = ReadDiskItem('Electrode Model', 'Electrode Model format') + result = list (rdiEM._findValues( {}, None, False ) ) + for e in result: + #WARNING if a model is available from multiple protocols, it will use only one + models[str(e.attributes()['model_name'])] = e + return models + + +class ElectrodeDisplayWidget(QtGui.QWidget): + def __init__(self, app=None, ana = None,dataSubjects = None): + QtGui.QWidget.__init__(self) + uic.loadUi("groupPlots.ui", self) + self.subjects = [] + self.subjItems = [] + self.implantations = {} + self.plotsData = {} + self.testDataSubjects = dataSubjects + self.taskCounter = 0 + self.tasks = [] + self.meshes = {} + self.bipolesmeshes = {} + self.dispMode = 'off'#'sphere' + self.dispParams = {'diameter':2.0} + self.transfoManager = registration.getTransformationManager() + # Get ReferentialConverter (for Talairach, AC-PC...) + self.refConv = ReferentialConverter() + + self.electrodeModels = loadElectrodeModels() + self.addSelectionButton.clicked.connect(self.addSelection) + self.removeSelectionButton.clicked.connect(self.removeSelection) + self.removePlotsNotTRC.clicked.connect(self.removeNotTRC) + self.removePlotsLeftSide.clicked.connect(lambda :self.removePlotsLeftRight('Left')) + self.removePlotsRightSide.clicked.connect(lambda :self.removePlotsLeftRight('Right')) + self.addAroundButton.clicked.connect(self.selectAround) + #self.normalizeButton.clicked.connect(self.normalizeCoords) + #self.saveNormalizedButton.clicked.connect(self.saveNormalizedCoords) + self.selectionList.itemDoubleClicked.connect(self.updatePlotSelected) + self.generateStatsButton.clicked.connect(self.generateStatisticsContacts) + + #fill the combo possibility. + loca = ['*'] + parcels_namesMA= readSulcusLabelTranslationFile('parcels_label_name.txt') + loca.extend(parcels_namesMA.values()) + loca.sort() + self.AddMAparcels2SelectioncomboBox.clear() + self.AddMAparcels2SelectioncomboBox.addItems(loca) + self.AddMAparcels2SelectioncomboBox.currentIndexChanged.connect(self.AddMAparcels2selection) + + self.radioButtonbothHemi.toggled.connect(self.changeBothRightDisplay) + #self.radioButtonAllRight.toggled.connect(self.changeBothRightDisplay) + + self.radioButtonContactDisplay.toggled.connect(self.contactSEEGDisplay) + #self.radioButtonsEEGResults.toggled.connect(self.contactSEEGDisplay) + + pix = QtGui.QPixmap('/home/b67-belledone/Desktop/epilepsie-manik/Logo-F-TRACT.xpm' ) + anatomist.anatomist.cpp.IconDictionary.instance().addIcon('ftract_control', pix) + ad = anatomist.anatomist.cpp.ActionDictionary.instance() + #control = ensemble d'action + ad.addAction( 'fTract_Action', StimulateResults ) + cd = anatomist.anatomist.cpp.ControlDictionary.instance() + cd.addControl( 'ftract_control', ControlFtract, 25 ) + cm = anatomist.anatomist.cpp.ControlManager.instance() + cm.addControl('QAGLWidget3D','','ftract_control') + + + + # Anatomist windows and objects + if ana == None: + self.a = anatomist.Anatomist('-b' ) + else: + self.a = ana + + layout = QtGui.QHBoxLayout( self.viewWidget ) + self.axWindow = self.a.createWindow( 'Axial' )#, no_decoration=True ) + self.axWindow.setParent(self.viewWidget) + layout.addWidget( self.axWindow.getInternalRep() ) + + self.sagWindow = self.a.createWindow( 'Sagittal' )#, no_decoration=True ) + self.sagWindow.setParent(self.viewWidget) + layout.addWidget( self.sagWindow.getInternalRep() ) + + + self.axWindow.internalRep.otherwindow = self.sagWindow + self.windows = [self.axWindow, self.sagWindow] + #pdb.set_trace() + #self.axWindow.connect() + + + + self.templates = {'MNI':TemplateMNI(self.a)} + #self.templateCombo.clear() + #self.templateCombo.addItems(sorted(self.templates.keys())) + self.setTemplate(self.templates['MNI']) + self.templReferential = None + #self.templateCombo.currentIndexChanged.connect(self.templateChanged) + + self.subjectList.itemSelectionChanged.connect(self.subjectSelectionChanged) + self.electrodeList.itemSelectionChanged.connect(self.electrodeSelectionChanged) + self.selectionList.itemSelectionChanged.connect(self.selectedSelectionChanged) + self.addDisplayButton.clicked.connect(self.displayImage) + self.addMNIImageToDisplayList.clicked.connect(self.addMNIImagetoList) + self.addMNIMeshTextToDisplayList.clicked.connect(self.addMNIMeshTexttoList) + + + def setStatus(self, text): + self.statusLabel.setText(str(text)) + + def incTaskCounter(self): + self.taskCounter = self.taskCounter + 1 + self.setStatus(u"Tasks in progress : "+str(self.taskCounter)) + return self.taskCounter + + def decTaskCounter(self): + self.taskCounter = self.taskCounter - 1 + self.setStatus(u"Tasks in progress : "+str(self.taskCounter)) + return self.taskCounter + + def startTask(self, taskFunction): + pe = PythonExecutor(taskFunction) + self.tasks.append(pe) + # Remove it from the list of threads when finished + pe.finished.connect(lambda th=pe:self.taskFinished(th)) + self.incTaskCounter() + pe.start() + + def taskFinished(self, thread): + self.tasks.remove(thread) + self.decTaskCounter() + + def setTemplate(self, templ): + """Set the template used as a common referential""" + # Un nom, des données (IRM ?) un identifiant de référentiel pour le refconv ? + self.template = templ + if self.template.referentialAnatomist: + self.a.assignReferential(self.template.referentialAnatomist, self.windows) + if self.template.volumes: + self.displayCombo.clear() + #self.displayCombo.addItems(["Image "+str(i) for i in range(len(self.template.volumes))]) + self.displayCombo.addItems([os.path.split(im.fullPath())[1] for im in self.template.volumes]) + + #def templateChanged(self, tpl): + #"""The combo box to select the template was changed""" + ## Read combo, setTemplate, remove selection or reset display (no spheres, no images)... + #pass + + def displayImage(self): + try: + #try: + #self.a.removeObjects([self.currentImage,],self.windows) #self.axWindow.removeObjects(self.currentImage) + ##self.sagWindow.removeObjects(self.currentImage) + #except: + #pass + self.currentImage = self.a.loadObject(self.template.volumes[self.displayCombo.currentIndex()]) + self.a.addObjects([self.currentImage], self.windows) + except: + print "Could not add selected image" + pdb.set_trace() + + def subjectSelectionChanged(self): + """Subject selection changed, update electrode list selection""" + selected = [str(item.text()) for item in self.subjectList.selectedItems()] + for i in xrange(self.electrodeList.count()): + selec = False + for s in selected: + if str(self.electrodeList.item(i).text()).startswith(s): + selec = True + break + self.electrodeList.item(i).setSelected(selec) + + def electrodeSelectionChanged(self): + """Electrode selection changed, update plot list selection""" + selected = [str(item.text()) for item in self.electrodeList.selectedItems()] + for i in xrange(self.plotList.count()): + selec = False + for s in selected: + if str(self.plotList.item(i).text()).startswith(s): + selec = True + break + self.plotList.item(i).setSelected(selec) + + #def plotSelectionChanged(self): + # pass + + def selectedSelectionChanged(self): + """In the selected plots list, the selected items changed -> update the view""" + # Update Anatomist selection -> select all meshes for the selected plots + g = self.a.getDefaultWindowsGroup() + g.setSelection([self.meshes[str(item.text())] for item in self.selectionList.selectedItems()]) + + def plotDataFromFullName(self, name): + """Get the data from a plot using its full name (e.g. Gre_2014_DUPj : A 2)""" + (sub, elec, plot) = self.plotNameFromFullPlotName(name) + return self.plotsData[sub][elec][plot] + + def fullPlotName(self, subj, elec, plot): + """Compute fully qualified plot name from subject, electrode, plot names""" + return subj + ' : ' + elec + ' ' + plot + + def plotNameFromFullPlotName(self, name): + """Get subject, electrode, plot names from the displayed name Subject : Electrode Plot (e.g. Gre_2014_DUPj : A 2)""" + (sub, elecplot) = name.split(' : ') + (elec, plot) = elecplot.split() + return (sub, elec, plot) + + #def normalizeCoords(self): + #"""Get plot coordinates in the selected template referential and store these coordinates in self.plotData""" + + #def miniFunc(myself, coordsSB, s): + #"""Internal mini function to launch in a thread""" + #refId = myself.implantations[s]['ReferentialUuid'] + #normCoords = myself.template.normalizeCoordinates([coordsSB[s][el][p] for el in coordsSB[s] for p in coordsSB[s][el]], refId) + ##pdb.set_trace() + #idx = 0 + #if normCoords is None: + #print "normCoords is None for subject %s : could not convert coordinates to template referential"%s + #return + ##import pdb; pdb.set_trace() + #for el in coordsSB[s]: + #for p in coordsSB[s][el]: + #myself.plotsData[s][el][p][myself.template.name] = normCoords[idx] + #idx = idx + 1 + ##fin de la fonction miniFunc + + #print "go back to locateElectrode for now, we don't manage call to normalisation from locateElectrode for now" + #return + #coordsSB = {} + #for s in self.subjects: + #coordsSB[s] = {} + #for elec, plots in self.plotsData[s].iteritems(): + #sb = dict([(p,plots[p]['Scanner-based']) for p in plots if self.template.name not in plots[p].keys()]) + #if len(sb) > 0: + #coordsSB[s][elec] = sb + ## Compute template coords for this subject + #self.startTask(lambda myself=self, cSB=coordsSB, suj=s:miniFunc(myself, cSB, suj)) + + + #def saveNormalizedCoords(self): + #"""Should save all computed coordinates of plots in elecimplant file for all subject + #with the timestamp of the original data, to avoid recomputation""" + #for s,rdi in zip(self.subjects, self.subjItems): + #self.saveImplantation(s, rdi) + #return + + def selectAround(self): + """Find in the list of selected plots the ones near the linked cursor""" + # Get linked cursor coords (in template referential) + pTempl = self.a.linkCursorLastClickedPosition(self.template.referentialAnatomist).items()[:3] + # Get accepted radius + r2 = self.radiusSpin.value()**2 + meshes = [] + # Compute distance to all selected plots + pdb.set_trace() #need to check if need to take absolute value in x in mni + for i in xrange(self.selectionList.count()): + fullname = str(self.selectionList.item(i).text()) + (sub, elec, plot) = self.plotNameFromFullPlotName(fullname) + coords = self.plotsData[sub][elec][plot][self.template.name][:3] + dist2 = (coords[0]-pTempl[0])**2 + (coords[1]-pTempl[1])**2 + (coords[2]-pTempl[2])**2 + # Select item if in range, deselect if not + self.selectionList.item(i).setSelected(dist2 <= r2) + if fullname in self.meshes and dist2 <= r2: + meshes.append(self.meshes[fullname]) + # Select them in Anatomist + g = self.a.getDefaultWindowsGroup() + g.setSelection(meshes) + + def setSubjects(self, names, diskitems): + """Sets the list of subjects (and corresponding readdiskitems in the database) for the widget""" + self.subjects = sorted(names) + self.subjItems = diskitems + self.loadImplantations() + self.plotsData = dict([(s, self.getPlotDataFromImplantation(s)) for s in self.subjects]) + #remove NonType from plotsData + pat_to_remove = [] + for jj,kk in self.plotsData.iteritems(): + if kk is None: + #self.plotsData.pop(jj,None) + pat_to_remove.append(jj) + + for ii in range(len(pat_to_remove)): + self.plotsData.pop(pat_to_remove[ii],None) + + if len(self.plotsData.keys()) == 0: + print "No data to show" + return + self.updateUIplots() + + def addSelection(self): + """Add the selected plots/subjects/electrodes to the selection """ + current = [str(self.selectionList.item(i).text()) for i in xrange(self.selectionList.count())] # FIXME pas juste les selected ! Tous les items + new = [str(s.text()) for s in self.plotList.selectedItems() if str(s.text()) not in current] + + # Display the new ones + meshes = [] + invalid = set() + for n in new: + if self.template.name in self.plotDataFromFullName(n): + mesh = self.displaySphereAt(self.plotDataFromFullName(n)[self.template.name], self.plotDiameter(), self.template.referentialAnatomist, color=(0.0,0.9,0.1,1.0),name = n) + self.meshes[n] = mesh + meshes.append(mesh) + else: + invalid.add(n) # If there, coordinates are not available in the right template referential + if len(invalid) > 0: + print "Some plots were not added to the selection, because normalized coordinates were not available for them" + new = list(set(new) - invalid) + self.selectionList.addItems(new) + self.a.addObjects(meshes, self.windows) + + def plotDiameter(self): + """Returns the diameter of the spheres used to display plots""" + return 2.0 + + def displaySphereAt(self, center, diameter, referential, color, name = None): + """Returns a spherical mesh (anatomist object) with color = [1.0,0.0,0.0,1.0] for a red, not transparent sphere""" + mesh = self.a.toAObject(aims.SurfaceGenerator.sphere(aims.Point3df(center[0], center[1], center[2]), diameter, 54)) + if name is not None: + mesh.setName(name) + self.a.setMaterial(mesh, diffuse=color)#[color.redF(), color.greenF(), color.blueF(), color.alphaF()] #sortir le setMaterial(diffuse=color) et le mettre à la fin de la boucle for des fonctions qui l'appelle ? + self.a.assignReferential(referential, mesh) + return mesh + + def removeSelection(self): + """Remove plots from the selected list""" + removable = [str(s.text()) for s in self.selectionList.selectedItems()] + meshes = [self.meshes[r] for r in removable if r in self.meshes] + for r in removable: + if r in self.meshes: + del self.meshes[r] + self.a.removeObjects(meshes, self.windows) + self.a.deleteObjects(meshes) + # Reverse loop to remove from the bottom (avoids messing up the index) + for idx in reversed(range(self.selectionList.count())): + if str(self.selectionList.item(idx).text()) in removable: + self.selectionList.takeItem(idx) + + def removeNotTRC(self): + """Remove plots which are not registered in the TRC""" + all_items=[str(self.selectionList.item(i).text()) for i in range(self.selectionList.count())] + #on remplace les ' par des p dans all_items + all_items = [all_items[x].replace("'","p") for x in range(len(all_items))] + full_list_trc=[] + for subj in self.subjects: + #check if exist TRC in DB for this subject + rdi = ReadDiskItem('Raw SEEG recording', 'EEG TRC format' ) + di = rdi.findValue({'subject':subj}) + if di is not None: + data_micromed = neo.MicromedIO(filename = str(di)).read_segment() #all data + taille=len(data_micromed.analogsignals) + ##Normalisation name (between analogsignals' name and plots' name) + number=['01', '02', '03', '04', '05', '06', '07', '08', '09'] + noms=[] + for i in range(taille): + name=data_micromed.analogsignals[i].name + name=name.upper() + if name[len(name)-2:] in number: + name=name[:len(name)-2]+name[len(name)-1:] + setattr(data_micromed.analogsignals[i],'name',name) + noms+=[data_micromed.analogsignals[i].name] + + #re.sub(noms[16],re.findall('\d+',noms[16])[0],subj + " : " + "Plot"+re.findall('\d+',noms[16])[0]) + #noms_remade= [subj + " : " + re.findall('\S+(? 0] + #on remplace les ' par des p dans noms_remade + [full_list_trc.append(noms_remade[x].replace("'","p")) for x in range(len(noms_remade))] + + + to_keep=[all_items[x] for x in range(len(all_items)) for y in range(len(full_list_trc)) if all_items[x]==full_list_trc[y]] + to_remove=list(set(all_items)-set(to_keep)) + + meshes = [self.meshes[r] for r in to_remove if r in self.meshes] + for r in to_remove: + if r in self.meshes: + del self.meshes[r] + self.a.removeObjects(meshes, self.windows) + self.a.deleteObjects(meshes) + # Reverse loop to remove from the bottom (avoids messing up the index) + for idx in reversed(range(self.selectionList.count())): + if str(self.selectionList.item(idx).text()) in to_remove: + self.selectionList.takeItem(idx) + + + + def removePlotsLeftRight(self, side): + + + all_items=[str(self.selectionList.item(i).text()) for i in range(self.selectionList.count())] + + to_remove = [] + for ii in all_items: + MNI_pos = self.plotDataFromFullName(ii)['MNI'] + + if side == 'Left': + if MNI_pos[0] >= 0: + to_remove.append(ii) + elif side == 'Right': + if MNI_pos[0] <=0: + to_remove.append(ii) + + meshes = [self.meshes[r] for r in to_remove if r in self.meshes] + for r in to_remove: + if r in self.meshes: + del self.meshes[r] + + self.a.removeObjects(meshes,self.windows) + self.a.deleteObjects(meshes) + + for idx in reversed(range(self.selectionList.count())): + if str(self.selectionList.item(idx).text()) in to_remove: + self.selectionList.takeItem(idx) + + + + def updateUIplots(self): + self.subjectList.clear() + self.subjectList.addItems(self.subjects) + allElecs = sorted([s + ' : ' + el for s in self.plotsData.keys() for el in self.plotsData[s].keys()]) + self.electrodeList.clear() + self.electrodeList.addItems(allElecs) + allPlots = sorted([self.fullPlotName(s, el, pl) for s in self.plotsData.keys() for el in self.plotsData[s].keys() for pl in self.plotsData[s][el].keys() ]) + self.plotList.clear() + self.plotList.addItems(allPlots) + + def t1pre2ScannerBased(self, subject): + """ Returns a triplet of Anatomist objects (native T1pre referential, scanner-base T1pre referential, Transformation from T1pre referential to T1pre Scanner-Based referential) """ + rdi = ReadDiskItem('Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True,\ + requiredAttributes={'modality':'t1mri', 'subject':subject}) + allTransf = list (rdi._findValues( {}, None, False ) ) + for trsf in allTransf: + if trsf.attributes()['acquisition'].startswith(u'T1pre'): + print repr(trsf.attributes()) + srcrDiskItem = self.transfoManager.referential( trsf.attributes()['source_referential'] ) + srcr = self.a.createReferential(srcrDiskItem) + dstrDiskItem = self.transfoManager.referential(trsf.attributes()['destination_referential']) + self.t1pre2ScannerBasedId = trsf.attributes()['destination_referential'] + dstr = self.a.createReferential(dstrDiskItem) + return (srcr, dstr, self.a.loadTransformation(trsf.fullPath(), srcr, dstr)) + return None + + def loadImplantations(self): + self.implantations = dict([(s,self.loadImplantation(rdi)) for s,rdi in zip(self.subjects, self.subjItems)]) + + def loadImplantation(self, rdiSuj): + rdi = ReadDiskItem( 'Electrode implantation', 'Electrode Implantation format') + impl = rdi.findValue(rdiSuj) + + if not impl: + print "Cannot find implantation for %s"%rdiSuj.attributes()['subject'] + return {} + if (os.path.exists(str(impl))): + filein = open(str(impl), 'rb') + try: + dic = json.loads(filein.read()) + except: + filein.close() + filein = open(str(impl), 'rb') + dic = pickle.load(filein) + + filein.close() + + #we load eleclabel now if exist + rdi_eleclabel = ReadDiskItem('Electrodes Labels','Electrode Label Format') + impl_label = rdi_eleclabel.findValue(rdiSuj) + + if not impl_label: + print("Cannot find implantation label for %s"%rdiSuj.attributes()['subject']) + pass + else: + if (os.path.exists(str(impl_label))): + filein = open(str(impl_label),"rb") + try: + dic2 = json.loads(filein.read()) + except: + filein.close() + filein.open(str(impl_label),"rb") + dic2 = pickle.load(filein) + + filein.close() + dic.update({'label':dic2['plots_label']}) + + return dic + + #print "Exception while reading implantation file for %s"%rdiSuj.attributes()['subject'] + #return {} + + def saveImplantation(self, subj, rdiSubj): + wdi = WriteDiskItem( 'Electrode implantation', 'Electrode Implantation format') + impl = wdi.findValue(rdiSubj) + if impl is None: + print "Could not find electrode implantation file to save to (%s) !"%subj + return + try: + #import pdb; pdb.set_trace() + fileout = open(impl.fullPath()+'.temporary', 'wb') + content = self.implantations[subj] + content['plotsData-timestamp'] = content['timestamp'] + content['plotsData'] = self.plotsData[subj] + fileout.write(json.dumps(content)) + #pickle.dump(content, fileout) + fileout.close() + #to modify to json + shutil.move(impl.fullPath()+'.temporary', impl.fullPath()) + neuroHierarchy.databases.insertDiskItem( impl, update=True ) + except: + print "Exception while writing implantation file for %s"%subj + traceback.print_exc(file=sys.stdout) + return + + + + def getPlotDataFromImplantation(self, subj): + els = self.subjectElectrodes(subj) + #self.addElectrode(e['name'], e['model'], e['target'], e['entry'], refId) + if 'plotsData' in self.implantations[subj]: + if self.implantations[subj]['plotsData-timestamp'] == self.implantations[subj]['timestamp']: + print "Using pre-recorded plots coordinates for %s"%subj + return self.implantations[subj]['plotsData'] + else: + print "PlotsData timestamp was invalid for %s"%subj + res = {} + for e in els: + res[e['name']] = self.getPlotsFromElectrode(e, subj) + + print(subj) + if "plotsMNI" in self.implantations[subj].keys(): + info_plotsMNI = dict(self.implantations[subj]['plotsMNI']) + for kk,vv in res.iteritems(): + for ll,ww in res[kk].iteritems(): + ww.update({"MNI":info_plotsMNI[kk+"%02d"%int(ll[4:])]}) + if "label" in self.implantations[subj].keys(): + try: + ww.update({"label":self.implantations[subj]["label"][kk+"%02d"%int(ll[4:])]}) + except: + pdb.set_trace() + else: + print "Error MNI Coordinates" + QtGui.QMessageBox.warning(self, "Error", "MNI coordinates haven't been generated for electrode contacts of Subject: {}\nThey have to be generated using locateElectrodes".format(subj)) + return + + return res + + def getPlotsFromElectrode(self, el, subj): + print "Creating electrode model for %s"%subj + traceback.print_exc(file=sys.stdout) + (nativeRef, sbRef, t1pre2ScannerBased) = self.t1pre2ScannerBased(subj) + (newRef, transf, elecModel) = createElectrode(el['target'], el['entry'], nativeRef, ana=self.a, model = self.electrodeModels[str(el['model'])].fullPath(), dispMode = self.dispMode, dispParams = self.dispParams) + plots = getPlots(elecModel) + pNames = getPlotsNames(elecModel) + return dict([(n, {'internal':plots[n]['center'], 'native':list(transf.transform(plots[n]['center'])), 'Scanner-based':list(t1pre2ScannerBased.transform(transf.transform(plots[n]['center'])))}) for n in pNames]) + + def getSubjectImplantation(self, subj): + """Returns electrode implantation data for the subject (dictionary from the elecimplant file)""" + return self.implantations[subj] + + def subjectElectrodes(self, subj): + """Returns the list available electrodes for the subject""" + impl = self.getSubjectImplantation(subj) + if 'electrodes' in impl: + return impl['electrodes'] + return [] + + def subjectElectrodesNames(self, subj): + """Returns the list of names of available electrodes for the subject""" + return [el['name'] for el in self.subjectElectrodes()] + + def subjectPlot(self, subj, electrode): + """Returns the list of plots of the chosen electrode for the subject""" + impl = self.getSubjectImplantation(subj) + if 'electrodes' in impl: + els = [e for e in impl['electrodes'] if e['name'] == electrode] + if len(els) > 0: + els[0] # (e['name'], e['model'], e['target'], e['entry'], refId) + return None + + def getPlotsCoordinates(self, subj, referential = None, electrode = None, plot = None): + """Returns the coordinates of the centers of all plots of the subject, or only for the given electrodes/plots + If referential is None, coordinates are returned in the native referential (T1pre of the subject) + """ + return None + + def updatePlotSelected(self, item = None): + try: + if item is not None: + xyz = self.plotDataFromFullName(str(item.text()))[self.template.name] + # setLinkedCursor uses window referential : must apply transform before setting the position + self.windows[0].moveLinkedCursor(xyz) + else: + print "Error moving the cursor to the contact2" + except Exception as e: + print "Error moving the cursor to the contact" + #pdb.set_trace() + + def addMNIImagetoList(self,path_fichier = None): + + if path_fichier is None or path_fichier is False: + fichier = QtGui.QFileDialog.getOpenFileName(self, "Opening file: ", "", "(*.nii *.gii *.img *.nii.gz)") + elif not os.path.isfile(path_fichier): + fichier = QtGui.QFileDialog.getOpenFileName(self, "Opening file: ", "", "(*.nii *.gii *.img *.nii.gz)") + else: + fichier = path_fichier + + image_mni_ref = self.a.loadObject(self.template.volumes[0]) + #image_mni_ref.loadReferentialFromHeader() + #try: + #self.a.removeObjects([self.currentImage,],self.windows) + #except: + #pass + self.currentImage = self.a.loadObject(str(fichier)) + #self.currentImage.loadReferentialFromHeader() + self.a.execute('LoadReferentialFromHeader', objects=[image_mni_ref,self.currentImage]) + all_trans = self.a.getTransformations() + trans_from_vols = [] + tm=registration.getTransformationManager() + tm.referential(registration.talairachMNIReferentialId) + for vol in (self.currentImage, image_mni_ref): + trans_from_vol = [t for t in all_trans if t.source() == vol.referential and not t.isGenerated()] + # hope trans_from_vol1 contains just one transform + # but if there are several, try to select the one going to + # scanner-based + if len(trans_from_vol) > 1: + trans_from_vol_filt = [t for t in trans_from_vol if t.destination().header()['name'].startswith('Scanner-based anatomical coordinates')] + if len(trans_from_vol_filt) == 1: + trans_from_vol = trans_from_vol_filt + if len(trans_from_vol) == 0: + raise RuntimeError('could not find a non-ambiguous transform') + elif len(trans_from_vol) > 1: + print "There is more than one available transformation ... we take the first one and pray" + trans_from_vol[0] = trans_from_vol_filt[0] + trans_from_vols.append(trans_from_vol) + + #pdb.set_traceI() + trans_from_vol1, trans_from_vol2 = trans_from_vols + self.template.volumes.append(str(fichier)) + self.a.execute('LoadTransformation',origin=trans_from_vol1[0].destination(),destination=trans_from_vol2[0].destination(),matrix=[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + self.a.addObjects([self.currentImage,], self.windows) + self.displayCombo.addItems([os.path.split(str(fichier))[1]]) + + def addMNIMeshTexttoList(self): + + #fichierMesh = QtGui.QFileDialog.getOpenFileName(self, "Opening mesh (surface corresponding to the texture): ", "", "(*.gii)") + + ##check if the file exist + #if not os.path.isfile(fichierMesh): + #print("the file doesn't exist") + #return + + #self.addMNIImagetoList(fichierMesh) + + #ask for a texture gii or a functionalTractography file + texture_info = QtGui.QMessageBox(self) + texture_info.setText("Choose the type of texture format (gii or csv to generate the gii)") + texture_info.setWindowTitle("texture format") + gii_button = texture_info.addButton(QtGui.QPushButton('.gii'),QtGui.QMessageBox.AcceptRole) + csvfuncTract_button =texture_info.addButton(QtGui.QPushButton('.csv functionalTractography'),QtGui.QMessageBox.AcceptRole) + #center_seg.setWindowModality(QtCore.Qt.NonModal) + texture_info.show() + texture_info.exec_() + #reply = texture_info.buttonRole(texture_info.clickedButton()) + if str(texture_info.clickedButton().text())=='.gii': + print("texture already gii generated") + fichierTexture = QtGui.QFileDialog.getOpenFileName(self, "Opening texture (corresponding to the mesh): ", "", "(*.gii)") + pdb.set_trace() + elif str(texture_info.clickedButton().text())=='.csv functionalTractography': + print("have to generate the gii texture from the csv data, functionalTractography csv model") + fichierCSV = QtGui.QFileDialog.getOpenFileName(self, "Opening functional tractography data: ", "", "(*.csv)") + if not os.path.isfile(fichierCSV): + print("the file doesn't exist") + full_data = readFunctionalTractography(fichierCSV) + + #ask where to save the data + path_to_save = QtGui.QFileDialog.getExistingDirectory(self,'Directory to save the mesh') + + BrodmannParcels = aims.read('MNI_Atlases/rbrodmann.nii') + BrodmannParcelsArrayData = BrodmannParcels.arraydata() + left_white = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/Gre_2016_MNI1_Lwhite.gii') + right_white = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/Gre_2016_MNI1_Rwhite.gii') + + list_remove = set(['Patient', 'Atlas']) + list_condi_max = set(['ValueNb','PeakDelayMed','PeakDelaySTD','Probability']) + list_condi_present = set(full_data.keys()) + + #condi_intersect = list(list_condi_max & list_condi_present) + condi_intersect = sorted(list(list_condi_present-list_remove), key=lambda s: s.lower()) + nb_time = len(condi_intersect) + + orderTexture = dict([(i,condi_intersect[i]) for i in range(len(condi_intersect))]) #{0:'ValueNb',1:'PeakDelayMed',2:'PeakDelaySTD',3:'Probability'} + + if full_data['Atlas'] == 'MarsAtlas': + #read the marsAtlas parcellation + left_MA = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/surface_analysis/Gre_2016_MNI1_Lwhite_parcels_marsAtlas.gii') + right_MA = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/surface_analysis/Gre_2016_MNI1_Rwhite_parcels_marsAtlas.gii') + + #for i in range(len(condi_intersect)): + # left_white.vertex(i).assign(left_white.vertex(0)) + # left_white.normal(i).assign(left_white.normal(0)) + # left_white.polygon(i).assign(left_white.polygon(0)) + # right_white.vertex(i).assign(right_white.vertex(0)) + # right_white.normal(i).assign(right_white.normal(0)) + # right_white.polygon(i).assign(right_white.polygon(0)) + + aims.write(left_white,str(path_to_save) + os.path.sep + 'left_white.gii') + aims.write(right_white,str(path_to_save) + os.path.sep + 'right_white.gii') + + try: + os.mkdir(str(path_to_save)+os.path.sep+'Texture') + except: + pass + + #faire un test si all au lieu des noms de parcels. + for i_parcels_stimulated in full_data[orderTexture[0]].keys(): + + if len( full_data[orderTexture[0]][i_parcels_stimulated]) > 0: + new_TimeSurfTextLeft = aims.TimeTexture('FLOAT') + new_TimeSurfTextRight = aims.TimeTexture('FLOAT') + + for i in range(nb_time): #assign the value + textnowLeft = new_TimeSurfTextLeft[i] + textnowRight = new_TimeSurfTextRight[i] + + textnowLeft.reserve(len(left_white.vertex(0))) #left_white.vertex(0))) + textnowRight.reserve(len(right_white.vertex(0))) + marsatlas_label = readSulcusLabelTranslationFile('parcels_label_name.txt') + + #gauche #control lateral lorsqu'étude contro/ipsi + for iter_vert in range(len(left_white.vertex(0))): + #marsatlas_label[left_MA[0].arraydata()[iter_vert]] + #if isinstance(full_data[orderTexture[i]]['L_VCcm'][marsatlas_label[left_MA[0].arraydata()[iter_vert]]], (str, unicode)): + + #join right and left or not + #for now we assume that we are using marsatlas + actual_marsatlas_parcels = [] + + if i_parcels_stimulated.startswith('L_') or i_parcels_stimulated.startswith('R_'): + try: + actual_marsatlas_parcels = [marsatlas_label[left_MA[0].arraydata()[iter_vert]]] + except: + pass #faudrait mieux mettre si c'est == 0 alors c'est un vertex qui n'a pas de correspondance marsatlas. + elif i_parcels_stimulated == 'All': + try: + actual_marsatlas_parcels = [marsatlas_label[left_MA[0].arraydata()[iter_vert]]] + except: + pass #faudrait mieux mettre si c'est == 0 alors c'est un vertex qui n'a pas de correspondance marsatlas. + else: + try: + actual_marsatlas_parcels = [[marsatlas_label[left_MA[0].arraydata()[iter_vert]]][0][2:]] + except: + pass + + try: + if left_MA[0].arraydata()[iter_vert] == 0: + textnowLeft.append(-4) + else: + if full_data[orderTexture[i]][i_parcels_stimulated].keys()[0].startswith('i_') or full_data[orderTexture[i]][i_parcels_stimulated].keys()[0].startswith('c_'): + if full_data[orderTexture[i]][i_parcels_stimulated]['c_'+actual_marsatlas_parcels[0]] == 'NaN': + textnowLeft.append(-4) + else: + textnowLeft.append(float(full_data[orderTexture[i]][i_parcels_stimulated]['c_'+actual_marsatlas_parcels[0]])) + else: + if full_data[orderTexture[i]][i_parcels_stimulated][actual_marsatlas_parcels[0]] == 'NaN': + textnowLeft.append(-4) + else: + textnowLeft.append(float(full_data[orderTexture[i]][i_parcels_stimulated][actual_marsatlas_parcels[0]])) + except: + textnowLeft.append(-4) + #pdb.set_trace() + + #puis droite #ipsi lateral lorsqu'étude contro_ipsi + for iter_vert in range(len(right_white.vertex(0))): + + actual_marsatlas_parcels = [] + + if i_parcels_stimulated.startswith('L_') or i_parcels_stimulated.startswith('R_'): + try: + actual_marsatlas_parcels = [marsatlas_label[right_MA[0].arraydata()[iter_vert]]] + except: + pass + elif i_parcels_stimulated == 'All': + try: + actual_marsatlas_parcels = [marsatlas_label[right_MA[0].arraydata()[iter_vert]]] + except: + pass #faudrait mieux mettre si c'est == 0 alors c'est un vertex qui n'a pas de correspondance marsatlas. + else: + try: + actual_marsatlas_parcels = [[marsatlas_label[right_MA[0].arraydata()[iter_vert]]][0][2:]] + except: + pass + + try: + if right_MA[0].arraydata()[iter_vert] == 0: + textnowRight.append(-4) + else: + if full_data[orderTexture[i]][i_parcels_stimulated].keys()[0].startswith('i_') or full_data[orderTexture[i]][i_parcels_stimulated].keys()[0].startswith('c_'): + if full_data[orderTexture[i]][i_parcels_stimulated]['i_'+actual_marsatlas_parcels[0]] == 'NaN': + textnowRight.append(-4) + else: + textnowRight.append(float(full_data[orderTexture[i]][i_parcels_stimulated]['i_'+actual_marsatlas_parcels[0]])) + else: + if full_data[orderTexture[i]][i_parcels_stimulated][actual_marsatlas_parcels[0]] == 'NaN': + textnowRight.append(-4) + else: + textnowRight.append(float(full_data[orderTexture[i]][i_parcels_stimulated][actual_marsatlas_parcels[0]])) + + except: + textnowRight.append(-4) + #pdb.set_trace() + + + aims.write(new_TimeSurfTextLeft,str(path_to_save) + os.path.sep + 'Texture' + os.path.sep + ('%s_left.gii')%i_parcels_stimulated) + aims.write(new_TimeSurfTextRight,str(path_to_save) + os.path.sep + 'Texture' + os.path.sep + ('%s_right.gii')%i_parcels_stimulated) + + else: + print(('No Data for %s')%i_parcels_stimulated) + + obj1 = self.a.loadObject('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/Gre_2016_MNI1_Lwhite.gii') + obj2 = self.a.loadObject('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/surface_analysis/Gre_2016_MNI1_Lwhite_parcels_marsAtlas.gii') + obj1.loadReferentialFromHeader() + obj2.setPalette(palette = 'marsatlas') + MarsAtlas_fusion_obj = self.a.fusionObjects([obj1, obj2], method='FusionTexSurfMethod') + self.a.addObjects(MarsAtlas_fusion_obj,self.axWindow) + self.currentImage = [obj1,obj2] + + + if full_data['Atlas'] == 'Brodmann': + voxel_size_T1 = [BrodmannParcels.getVoxelSize()[0], BrodmannParcels.getVoxelSize()[1], BrodmannParcels.getVoxelSize()[2], 1.0] + sizeOutputnii = BrodmannParcels.getSize().list() + sizeOutputnii[-1] = len(orderTexture.keys()) + + for i_parcels_stimulated in full_data[orderTexture[0]].keys(): + #di.setMinf('ColorPalette','Blue-Red-fusion') + volToGenerate = aims.Volume(*sizeOutputnii,dtype = 'float') + volToGenerate.header()['voxel_size']=voxel_size_T1 + volToGenerate.fill(-4) + + for i_texture in orderTexture.keys(): + + for i_parcels_result in full_data[orderTexture[i_texture]][i_parcels_stimulated].keys(): + #fait chier le droite gauche + if full_data[orderTexture[0]][i_parcels_stimulated][i_parcels_result]=='NaN': + volToGenerate.arraydata()[numpy.where(BrodmannParcelsArrayData==float(i_parcels_result))]=-4 + else: + volToGenerate.arraydata()[numpy.where(BrodmannParcelsArrayData==float(i_parcels_result))]=full_data[orderTexture[i_texture]][i_parcels_stimulated][i_parcels_result] + + aims.write(volToGenerate,str(path_to_save)+os.path.sep+'%s.nii'%(str(int(float(i_parcels_stimulated))))) + + + print("done") + pdb.set_trace() + #try: + # self.a.removeObjects([self.currentImage,],self.windows) + #except: + # pass + + + ##self.displayCombo.addItems([os.path.split(str(fichier))[1]]) + #obj3 = self.a.loadObject(str(path_to_save) + os.path.sep + 'left_white_multipletime.gii') + #obj4 = self.a.loadObject(str(path_to_save) + os.path.sep + 'Texture' + os.path.sep + ('%s_left.gii')%i_parcels_stimulated) + #obj3.loadReferentialFromHeader() + #obj4.setPalette(palette = 'Blue-Red-fusion') + #FunctioTracto_fusion_obj = self.a.fusionObjects([obj3,obj4],method='FusionTexSurfMethod') + #self.a.addObjects(FunctioTracto_fusion_obj,self.sagWindow) + + + + + #pdb.set_trace() + #self.displayCombo.addItems([os.path.split(str(fichier))[1]]) + + #textureContacts = aims.TimeTexture() + + def doubleClickedFunctionalTractography(self): + + pdb.set_trace() + + + def generateStatisticsContacts(self): + + #get selected contacts + current = [str(self.selectionList.item(i).text()) for i in xrange(self.selectionList.count())] + + #il me faut un dictionnaire avec toutes les parcels mars atlas et un dictionnaire avec toutes les parcels freesurfer possible. + dict_marsatlas = {} + dict_freesurfer = {} + dict_dispersion_MA = {} + dict_dispersion_FS = {} + parcels_names = readSulcusLabelTranslationFile('parcels_label_name.txt') + freesurfer_parcel_names = readFreesurferLabelFile('freesurfer_label.txt') + missing_marsatlas = [] + missing_freesurfer = [] + all_patients = [] + dict_MNI_PatientName = {} + + for ii in parcels_names.values(): + dict_marsatlas.update({ii:[]}) + dict_dispersion_MA.update({ii:{}}) + + + for ii in freesurfer_parcel_names.values(): + dict_freesurfer.update({ii[0]:[]}) + dict_dispersion_FS.update({ii[0]:{}}) + + #je parcours toutes les "current", je regarde leur parcels et j'ajoute la position mni à la list de cette parcels. + for ii in current: + (sub, elec, plot) = self.plotNameFromFullPlotName(ii) + dataplot = self.plotDataFromFullName(ii) + if 'MarsAtlas' in dataplot['label'].keys(): + if dataplot['label']['MarsAtlas'][1] != u'not in a mars atlas parcel': + dict_marsatlas[dataplot['label']['MarsAtlas'][1]].append(dataplot['MNI']) + else: + #signaler que certains patients n'ont pas marsatlas de généré et que ça va "fausser" les résultats + #print("plot %s without marsAtlas parcellation estimated"%(ii)) + if sub not in missing_marsatlas: + missing_marsatlas.append(sub) + if 'Freesurfer' in dataplot['label'].keys(): + if dataplot['label']['Freesurfer'][1] != u'not in a freesurfer parcel': + try: + dict_freesurfer[dataplot['label']['Freesurfer'][1]].append(dataplot['MNI']) + except: + print sub + print "probleme avec ce patient" + pass + else: + #signaler que certains patient n'ont pas freesurfer de généré et que ça va "fausser" les résultats + #print("plot %s without FreeSurfer parcellation estimated"%(ii)) + if sub not in missing_freesurfer: + missing_freesurfer.append(sub) + if sub not in all_patients: + all_patients.append(sub) + dict_MNI_PatientName.update({str(dataplot['MNI']):sub}) + + #now I calculate the dispersion per parcels: (and I'ld like to normalized it but don't know how) + for iter_MA in dict_marsatlas.keys(): + points_array = numpy.array(dict_marsatlas[iter_MA]) + #array_median = repmat(numpy.median(points_array,axis=0),len(points_array),1) + #diff = points_array - array_median + #list_dist_median = sc_sp.distance.cdist([numpy.median(points_array,axis=0)],points_array) + if len(points_array)>1: + dict_dispersion_MA[iter_MA].update({'nb contact':len(dict_marsatlas[iter_MA]),'average point':numpy.mean(points_array,axis=0),'median point':numpy.median(points_array,axis=0)}) + found_outlier = self.is_outlier(points_array,thresh = 3) + pos_outlier = numpy.where(found_outlier==True) + if len(pos_outlier[0]) == 0: + dict_dispersion_MA[iter_MA].update({'outlier position':None}) + else: + #[dict_MNI_PatientName[str(points_array[pos_outlier[0]][i].tolist())] for i in range(len(points_array[pos_outlier[0]]))] + dict_dispersion_MA[iter_MA].update({'outlier position':points_array[pos_outlier[0]]}) + dict_dispersion_MA[iter_MA].update({'outlier name':[dict_MNI_PatientName[str(points_array[pos_outlier[0]][i].tolist())] for i in range(len(points_array[pos_outlier[0]]))]}) + elif len(points_array)==1: + dict_dispersion_MA[iter_MA].update({'nb contact': 1,'average point':numpy.mean(points_array,axis=0),'median point':numpy.median(points_array,axis=0)}) + else: + dict_dispersion_MA[iter_MA].update({'nb contact': 0}) + + + for iter_FS in dict_freesurfer.keys(): + points_array = numpy.array(dict_freesurfer[iter_FS]) + #array_median = repmat(numpy.median(points_array,axis=0),len(points_array),1) + #diff = points_array - array_median + #list_dist_median = sc_sp.distance.cdist([numpy.median(points_array,axis=0)],points_array) + if len(points_array)>1: + dict_dispersion_FS[iter_FS].update({'nb contact':len(dict_freesurfer[iter_FS]),'average point':numpy.mean(points_array,axis=0),'median point':numpy.median(points_array,axis=0)}) + found_outlier = self.is_outlier(points_array,thresh = 3) + pos_outlier = numpy.where(found_outlier==True) + if len(pos_outlier[0]) == 0: + dict_dispersion_FS[iter_FS].update({'outlier position':None}) + else: + dict_dispersion_FS[iter_FS].update({'outlier position':points_array[pos_outlier[0]]}) + dict_dispersion_FS[iter_FS].update({'outlier name':[dict_MNI_PatientName[str(points_array[pos_outlier[0]][i].tolist())] for i in range(len(points_array[pos_outlier[0]]))]}) + elif len(points_array)==1: + dict_dispersion_FS[iter_FS].update({'nb contact':1,'average point':numpy.mean(points_array,axis=0),'median point':numpy.median(points_array,axis=0)}) + else: + dict_dispersion_FS[iter_FS].update({'nb contact':0}) + + #ecrire le tout dans un csv + fileName = QtGui.QFileDialog.getSaveFileName(self, 'Dialog Title', '/', '*.csv') #str(QtGui.QFileDialog.getExistingDirectory(self, "Select Directory")) + fileName=str(fileName) + testcsv = fileName.split('.') + if len(testcsv)>0: + if testcsv[1] != 'csv': + print("error, the extension should be .csv") + return + else: + fileName = fileName + '.csv' + + with open(fileName, 'w') as csvfile: + writer = csv.writer(csvfile, delimiter='\t') + writer.writerow([u'Group Analysis']) + listwrite_allpatients = [u'Patients'] + for ii in all_patients: + listwrite_allpatients.append(ii) + writer.writerow(listwrite_allpatients) #writer.writerow([u'Patients',all_patients]) + listwrite_missingMA = [u'missing marsAtlas info for the following patients (analysis done without their data):'] + for ii in missing_marsatlas: + listwrite_missingMA.append(ii) + writer.writerow(listwrite_missingMA)#writer.writerow([u'missing marsAtlas info for the following patients (analysis done without their data):',missing_marsatlas]) + listwrite_missingFS = [u'missing FreeSurfer info for the following patients (analysis done without their data):'] + for ii in missing_freesurfer: + listwrite_missingFS.append(ii) + writer.writerow(listwrite_missingFS) + #writer.writerow([u'missing FreeSurfer info for the following patients (analysis done without their data):',missing_freesurfer]) + writer.writerow([u'MarsAtlas parcellation analysis']) + writer.writerow([u'parcel name',u'nb contact', u'average point', u'median point', u'outliers positions',u'patient names of the outliers']) + + dictMA_sorted_tmp = OrderedDict(sorted(dict_dispersion_MA.items())) + for kk,vv in dictMA_sorted_tmp.iteritems(): + if vv['nb contact']>0: + listwrite = [kk] + listwrite.append(vv['nb contact']) + if 'average point' in vv.keys(): + listwrite.append([float(format(vv['average point'][i],'.3f')) for i in range(3)]) + listwrite.append([float(format(vv['median point'][i],'.3f')) for i in range(3)]) + if 'outlier position' in vv.keys(): + if vv['outlier position'] is not None: + listwrite.append(vv['outlier position']) + listwrite.append(vv['outlier name']) + writer.writerow(listwrite) + + #writer.writerow(dict_dispersion_MA) + writer.writerow([]) + writer.writerow([u'Freesurfer parcellation analysis']) + writer.writerow([u'parcel name',u'nb contact', u'average point', u'median point', u'outliers positions',u'patient names of the outliers']) + dictFS_sorted_tmp = OrderedDict(sorted(dict_dispersion_FS.items())) + for kk,vv in dictFS_sorted_tmp.iteritems(): + if vv['nb contact']>0: + listwrite = [kk] + listwrite.append(vv['nb contact']) + if 'average point' in vv.keys(): + listwrite.append([float(format(vv['average point'][i],'.3f')) for i in range(3)]) + listwrite.append([float(format(vv['median point'][i],'.3f')) for i in range(3)]) + if 'outlier position' in vv.keys(): + if vv['outlier position'] is not None: + listwrite.append(vv['outlier position']) + listwrite.append(vv['outlier name']) + writer.writerow(listwrite) + + print("csv done") + + def is_outlier(self,list_points, thresh=3): + + #to be changed to the MAD + if len(list_points.shape) == 1: + list_points = list_points[:,None] + median = numpy.median(list_points, axis=0) + diff = numpy.sum((list_points - median)**2, axis=-1) + diff = numpy.sqrt(diff) + med_abs_deviation = numpy.median(diff) + + modified_z_score = 0.6745 * diff / med_abs_deviation + + return modified_z_score > thresh + + def AddMAparcels2selection(self): + + print "select contacts according to marsatlas parcels" + fullPlot_List = [str(self.plotList.item(idx).text()) for idx in range(self.plotList.count())] + + parcels_names = readSulcusLabelTranslationFile('parcels_label_name.txt') + + dict_plotMA = {} + for ii in parcels_names.values(): + dict_plotMA.update({ii:[]}) + + for ii in fullPlot_List: + (sub, elec, plot) = self.plotNameFromFullPlotName(ii) + dataplot = self.plotDataFromFullName(ii) + if 'MarsAtlas' in dataplot['label'].keys(): + if dataplot['label']['MarsAtlas'][1] != u'not in a mars atlas parcel': + dict_plotMA[dataplot['label']['MarsAtlas'][1]].append(ii) + + if str(self.AddMAparcels2SelectioncomboBox.currentText()) =='*': + print('unselect all') + for i in xrange(self.plotList.count()): + selec = False + self.plotList.item(i).setSelected(selec) + else: + list_plot2select= dict_plotMA[str(self.AddMAparcels2SelectioncomboBox.currentText())] + for i in xrange(self.plotList.count()): + selec = False + if str(self.plotList.item(i).text()) in list_plot2select: + selec = True + self.plotList.item(i).setSelected(selec) + + + def changeBothRightDisplay(self): + + all_items=[str(self.selectionList.item(i).text()) for i in range(self.selectionList.count())] + refBothHemi = self.template.referentialAnatomist + newRef = self.a.createReferential() + + transf = self.a.createTransformation([0,0,0,-1,0,0,0,1,0,0,0,1], origin = newRef, destination = refBothHemi) + meshesLeft = [] + for ii in all_items: + MNI_pos = self.plotDataFromFullName(ii)['MNI'] + + if MNI_pos[0] >=0: + #on fait classique + pass + elif MNI_pos[0] < 0: + + if self.radioButtonbothHemi.isChecked(): + meshesLeft.append(ii) + self.a.assignReferential(refBothHemi,self.meshes[ii]) + + + elif self.radioButtonAllRight.isChecked(): + meshesLeft.append(ii) + pdb.set_trace() + self.a.assignReferential(newRef,self.meshes[ii]) + + #self.a.assignReferential(newRef,meshesLeft) + + + #to_remove = [] + #for ii in all_items: + #MNI_pos = self.plotDataFromFullName(ii)['MNI'] + + #if side == 'Left': + #if MNI_pos[0] >= 0: + #to_remove.append(ii) + #elif side == 'Right': + #if MNI_pos[0] <=0: + #to_remove.append(ii) + + #meshes = [self.meshes[r] for r in to_remove if r in self.meshes] + #for r in to_remove: + #if r in self.meshes: + #del self.meshes[r] + + #self.a.removeObjects(meshes,self.windows) + #self.a.deleteObjects(meshes) + + + def contactSEEGDisplay(self): + + if self.radioButtonContactDisplay.isChecked(): + pdb.set_trace() + try: + self.bipoleSEEGColors.close() + except: + pass + self.a.removeObjects([self.bipolesmeshes[x] for x in self.bipolesmeshes.keys()],self.windows) + #current = [str(self.selectionList.item(i).text()) for i in xrange(self.selectionList.count())] # FIXME pas juste les selected ! Tous les items + #new = [str(s.text()) for s in self.plotList.selectedItems() if str(s.text()) not in current] + + ## Display the new ones + #meshes = [] + #invalid = set() + #for n in new: + #if self.template.name in self.plotDataFromFullName(n): + #mesh = self.displaySphereAt(self.plotDataFromFullName(n)[self.template.name], self.plotDiameter(), self.template.referentialAnatomist, color=(0.0,0.9,0.1,1.0),name = n) + #self.meshes[n] = mesh + #meshes.append(mesh) + #else: + #invalid.add(n) # If there, coordinates are not available in the right template referential + #if len(invalid) > 0: + #print "Some plots were not added to the selection, because normalized coordinates were not available for them" + #new = list(set(new) - invalid) + #self.selectionList.addItems(new) + + self.a.addObjects([self.meshes[x] for x in self.meshes.keys()], self.windows) + + + elif self.radioButtonsEEGResults.isChecked(): + + meshes = [self.meshes[x] for x in self.meshes.keys()] + + #for ind_mesh in self.meshes.keys(): + #del self.meshes[ind_mesh] + self.a.removeObjects(meshes,self.windows) + #self.a.deleteObjects(meshes) + + + #il faut générer les bipoles + current = [str(self.selectionList.item(i).text()) for i in xrange(self.selectionList.count())] + info_contact={} + for pindex in range(0,len(current)): + (sub, elec, plot) = self.plotNameFromFullPlotName(current[pindex]) + try: + if sub not in info_contact.keys(): + info_contact.update({sub:[]}) + info_contact[sub].append(elec+"%02d"%int(plot.split('Plot')[1])) + else: + info_contact[sub].append(elec+"%02d"%int(plot.split('Plot')[1])) + except: + pdb.set_trace() + info_bipole = {} + for subj in info_contact.keys(): + + contacts_sorted = sorted(info_contact[subj],key=natural_keys) + if subj not in info_bipole.keys(): + info_bipole.update({subj:{}}) + for contact_index in range(1,len(contacts_sorted)): + previous_contact = "".join([i for i in contacts_sorted[contact_index-1] if not i.isdigit()]) + previous_number = "".join([i for i in contacts_sorted[contact_index-1] if i.isdigit()]) + current_contact = "".join([i for i in contacts_sorted[contact_index] if not i.isdigit()]) + current_number = "".join([i for i in contacts_sorted[contact_index] if i.isdigit()]) + + if previous_contact == current_contact: + if int(current_number) - int(previous_number) == 1: + bipole = contacts_sorted[contact_index] + ' - ' + contacts_sorted[contact_index-1] + mni_bipole = ((numpy.array(self.plotsData[subj][current_contact]['Plot'+str(int(current_number))]['MNI']) + numpy.array(self.plotsData[subj][current_contact]['Plot'+str(int(previous_number))]['MNI']))/2).tolist() + info_bipole[subj].update({bipole:mni_bipole}) + else: + #find previous contact + previous_number = int(current_number)-1 + next_number = int(current_number)+1 + bipole_with_previous = contacts_sorted[contact_index] + ' - ' + "%s%02d"%(current_contact,int(previous_number)) + bipole_wiht_next = "%s%02d"%(current_contact,int(next_number)) + ' - ' + contacts_sorted[contact_index] + if 'Plot'+str(previous_number) in self.plotsData[subj][current_contact].keys(): + if bipole_with_previous not in info_bipole[subj].keys(): + mni_bipole = ((numpy.array(self.plotsData[subj][current_contact]['Plot'+str(int(current_number))]['MNI']) + numpy.array(self.plotsData[subj][current_contact]['Plot'+str(int(previous_number))]['MNI']))/2).tolist() + info_bipole[subj].update({bipole_with_previous:mni_bipole}) + + if 'Plot'+str(next_number) in self.plotsData[subj][current_contact].keys(): + if bipole_wiht_next not in self.plotsData[subj][current_contact].keys(): + mni_bipole = ((numpy.array(self.plotsData[subj][current_contact]['Plot'+str(int(current_number))]['MNI']) + numpy.array(self.plotsData[subj][current_contact]['Plot'+str(int(next_number))]['MNI']))/2).tolist() + info_bipole[subj].update({bipole_wiht_next:mni_bipole}) + + + list_to_show = [] + for subj in info_bipole.keys(): + if 'seeg_label_all' in self.testDataSubjects[subj].keys(): + + for index_bip in info_bipole[subj].keys(): + + rdiEM = ReadDiskItem('Electrode Model', 'Electrode Model format') + listEM = list(rdiEM.findValues({},None,False)) + matches = filter((lambda x: u"bipole" in str(x)), listEM) + if subj + ' : ' + index_bip not in self.bipolesmeshes.keys(): + #la faudrait que je vérifie si le bipole existe vraiment parce que sinon je crée énormément de mesh pour rien ... + mesh = self.displaySphereAt(info_bipole[subj][index_bip],self.plotDiameter(), self.template.referentialAnatomist, color=(0.0,0.0,0.0,0.0),name = subj + ' : ' + index_bip) #je devrais sortir le color de la ? + mesh.setMaterial(front_face='counterclockwise') + self.bipolesmeshes.update({subj + ' : ' + index_bip:mesh}) + list_to_show.append(subj + ' : ' + index_bip) + + #else: + #print "No SEEG stim results" + #QtGui.QMessageBox.warning(self, "Error", "Stim report has not been generated for the subject: {}".format(subj)) + + + self.a.addObjects([self.bipolesmeshes[x] for x in list_to_show], self.windows) + + self.bipoleSEEGColors=bipoleSEEGColors(self,indv_pat = False, group_subsample = list_to_show) + self.bipoleSEEGColors.show() + #removable = [str(s.text()) for s in self.selectionList.selectedItems()] + #meshes = [self.meshes[r] for r in removable if r in self.meshes] + #for r in removable: + #if r in self.meshes: + #del self.meshes[r] + #self.a.removeObjects(meshes, self.windows) + #self.a.deleteObjects(meshes) + + +if __name__ == "__main__": + app = QtGui.QApplication(sys.argv) + axon.initializeProcesses() + from brainvisa.data.readdiskitem import ReadDiskItem + from brainvisa.data.writediskitem import WriteDiskItem + window = ElectrodeDisplayWidget() + window.show() + sys.exit(app.exec_()) diff --git a/epilepsie-electrodes.ui b/epilepsie-electrodes.ui new file mode 100644 index 0000000..4bc2b61 --- /dev/null +++ b/epilepsie-electrodes.ui @@ -0,0 +1,759 @@ + + + EpilepsieElectrodes + + + + 0 + 0 + 1167 + 888 + + + + + 0 + 0 + + + + Dialog + + + + + + Qt::Horizontal + + + + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + Load Patient + + + false + + + + + + + Change Patient + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Image Manipulation + + + + QLayout::SetMinimumSize + + + + + make the fusion of both displayed images and shows it on the right window + + + Fusion displayed images + + + + + + + + + Generate Resection Image + + + + + + + convert ROI to Resection + + + + + + + + + + + Delete MarsAtlas + + + + + + + Generate SEEG Projection Mesh + + + + + + + + + + + + + 0 + 0 + + + + + 50 + false + + + + Electrodes + + + + QLayout::SetMinimumSize + + + + + Import theoritical implantation (rosa) + + + + + + + Apply DEETO + + + + + + + + + + 0 + 0 + + + + + 20 + 100 + + + + Ajouter une électrode + + + + + + + false + + + + + + + + 0 + 0 + + + + + 20 + 100 + + + + Supprimer l'électrode courante + + + - + + + false + + + + + + + + 0 + 0 + + + + Name (no digit in the name): + + + + + + + + 0 + 0 + + + + + + + + + + + + + 0 + 0 + + + + Type + + + + + + + + + + + + + + ArrowCursor + + + Fixer la position de l'extrémité de l'électrode courante + + + Target + + + false + + + + + + + Fixer la position du point d'entrée de l'électrode courante + + + Entrance + + + false + + + + + + + + + + 0 + 2 + + + + Liste des électrodes + + + + + + + + 0 + 4 + + + + Liste des contacts + + + QAbstractItemView::SingleSelection + + + + + + + + 75 + true + + + + Enregistrer l'implantation du patient dans la base de données + + + Save + + + false + + + + + + + QLayout::SetMinimumSize + + + + + Importer une implantation (format PTS, elecimplant...) + + + Import + + + false + + + + + + + Exporter les coordonnées des plots au format PTS et TXT dans le référentiel T1 et MNI + + + Normalize/Export + + + false + + + + + + + + Generate All Dictionaries + + + + + Mars Atlas Contact Position + + + + + Mars Atlas Resection Position + + + + + Export to csv file + + + + + Generate mapping contact - hemi mesh + + + + + Generate Bipole Stimulation excel file + + + + + Generate screenshot + + + + + Generate MP4 + + + + + Compute parcel metrics + + + + + Generate Fiber Contact Distance + + + + + + + + + + + + + + 50 + false + + + + + + + + + + + + false + + + + 10 + true + + + + sEEG Colors + + + false + + + + + + + + 0 + 0 + + + + Mode d'affichage des électrodes + + + + Realistic Display + + + + + 1 mm sphere Display + + + + + 2 mm sphere Display + + + + + 5 mm sphere Display + + + + + Hide Electrodes + + + + + show SEEG Results + + + + + + + + true + + + afficher seulement les élements à +/- 5 mm de la slice actuelle + + + Clipping + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Electrode Referential + + + + + + + -180 + + + 180 + + + true + + + Qt::Horizontal + + + false + + + + + + + + + + + + + + Référentiel utilisé pour les coordonnées affichées ci-contre + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + IRM pre + + + + + IRM pre + hemisphere droit + + + + + IRM pre + hemisphere gauche + + + + + IRM pre + hemispheres + + + + + IRM post + + + + + IRM post-op + + + + + + + + + 0 + 0 + + + + + + + + + + QLayout::SetMaximumSize + + + + + + 0 + 0 + + + + + IRM pre + + + + + IRM pre + hemisphere droit + + + + + IRM pre + hemisphere gauche + + + + + IRM pre + hemispheres + + + + + IRM post + + + + + IRM post-op + + + + + + + + + 0 + 0 + + + + + + + + + + + + + patientList + addElectrodeButton + removeElectrodeButton + nameEdit + typeComboBox + targetButton + entryButton + electrodeList + contactList + electrodeSaveButton + electrodeLoadButton + colorConfigButton + dispModeCombo + electrodeRefCheck + electrodeRefRotationSlider + referentialCombo + windowCombo1 + windowCombo2 + + + + diff --git a/externalprocesses.py b/externalprocesses.py new file mode 100644 index 0000000..d9e9e62 --- /dev/null +++ b/externalprocesses.py @@ -0,0 +1,186 @@ +# -*- coding: utf-8 -*- +# +# +# Library for running matlab commands and external shell commands in blocking and non-blocking ways. +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# License GNU GPL v3 +# + +# TODO : redo using QRunnable instead of QThread with QThreadPool.globalInstancer().start(myRunnable) + +import subprocess, os, types, tempfile, time, random, string,sys +from PyQt4 import QtCore +import pdb + + +# Set the environment for external commands without BrainVisa interference (remove brainvisa-specific paths) +myEnv = os.environ.copy() +for var in myEnv.keys(): + if var.find('BRAINVISA_UNENV_') >= 0: + realvar = var.split('BRAINVISA_UNENV_')[1] + print "On remplace %s par %s"%(realvar, var) + myEnv[realvar] = myEnv[var] + del myEnv[var] + +# Base call for matlab +matlabCall = ['matlab', '-nosplash', '-nodisplay','-r'] #essayer sans le -nojvm + + +def getTmpFilePath(extension='txt'): + """ + Generate a random file name in a temp directory + + file extension (txt by default) can be given as argument + Usage : filepath = getTmpFilePath('jpg') + """ + tmpdir = tempfile.gettempdir() + tmpCmd = ''.join(random.choice(string.letters) for i in xrange(15)) + tmpfile = tmpCmd + '.' + extension + #print "TMPdir : %s, filename : %s"%(repr(tmpdir), repr(tmpfile)) + fullpath = os.path.join(tmpdir, tmpfile) + return fullpath + +class Executor(QtCore.QThread): + """ This class executes a shell command in a thread. + The Executor object must NOT be destroyed until the execution is complete. + Parameters include : + :param commandList (for example ['cat', '/tmp/file1', '/tmp/file2'] + :param parent a parent for the QThread (None by default) + :param objectsToKeep : objets to keep in the Executor object until the end of execution + :param exitFunc : a callback function that will be called at the end of the command execution + + As this is a QThread object, the object is created, then the non-blocking start() function must be called to start the thread. + Do NOT call directly the run() function + """ + def __init__(self, commandList, parent=None, objectsToKeep=None, exitFunc=None): + QtCore.QThread.__init__(self,parent) + self.commandList = commandList + self.objectsToKeep = objectsToKeep + self.exitFunc = exitFunc + + def run(self): + """ + Reimplementation of the run function of the QThread. + This SHOULD NOT BE CALLED DIRECTLY as it would run in the current thread. + Run self.start() to start the execution in a separate thread + """ + #pdb.set_trace() + #self.emit(QtCore.SIGNAL("Started( QString )"),'Command started') + print "######## Calling process in a QThread ####"+' '.join(self.commandList)+"\n\n\n" + try: + lines = subprocess.Popen(self.commandList, stdout=subprocess.PIPE, env = myEnv).communicate()[0].splitlines() + except: + print "Erreur lors de l'exécution de la commande : ", sys.exc_info()[0] + #pdb.set_trace() + if self.exitFunc: + self.exitFunc() + print "QThread finished" + print "*****************LINES"+repr(lines)+"\n\n\n" + #self.emit(QtCore.SIGNAL("Finished( QStringList )"),lines) + + +class PythonExecutor(QtCore.QThread): + """ This class executes a python function with no arguments (can be created with 'lambda(x=myXvalue,y=myYvalue) : myFunc(x,y)') in a thread. + The object must NOT be destroyed until the execution is complete. + After creation, call the start() function to start the execution in a separate thread. + """ + def __init__(self, func, toKeep = None, parent=None): + """:param func : The function that will be run in a separate thread + :param parent : a parent object for the QThread (default is None) + :param toKeep : object or dictionnary or list of objects to keep a reference to. + """ + QtCore.QThread.__init__(self,parent) + self.func = func + self.out = None + self.toKeep = toKeep + + def output(self): + """ Returns the output value of the function when execution is terminated""" + return self.out + + def kept(self): + return self.toKeep + + def run(self): + """ + Reimplementation of the run function of the QThread. + This SHOULD NOT BE CALLED DIRECTLY as it would run in the current thread. + Run self.start() to start the execution in a separate thread + """ + #self.emit(QtCore.SIGNAL("Started( QString )"),'Command started') + self.out = self.func() + #print "*****************OUTPUT"+repr(out)+"\n\n\n" + +def matlabIsPresent(): + """ + Check if the 'matlab' command is available in the path, by running a very small matlab command + Returns True or False + """ + try: + result = subprocess.Popen(matlabCall+['quit;',], stdout=subprocess.PIPE, env = myEnv).communicate()[0].splitlines() + except OSError: + print "matlab is not present : OSError" + return False + except: + print "matlab is not present or fails !" + return False + return True + +def matlabRun(cmd): + """ + Runs the provided matlab code and returns the stdoutput + The call is blocking until command completion. + Use matlabRunNB to get non-blocking command execution + """ + if not isinstance(cmd, types.ListType): + cmd = [cmd,] + # Because the command may be too long for a command line, let's put it in a temp file and run the file + tmpdir = tempfile.gettempdir() + tmpCmd = ''.join(random.choice(string.letters) for i in xrange(15)) + tmpfile = tmpCmd + '.m' + #print "TMPdir : %s, filename : %s"%(repr(tmpdir), repr(tmpfile)) + fullpath = os.path.join(tmpdir, tmpfile) + # os.path.join(tempfile.tempdir,''.join(random.choice(string.letters) for i in xrange(15))+'.m') + f = open(fullpath, 'w') + f.write(' '.join(cmd) + "\n\n") + f.close() + print "Calling matlab in "+tmpdir+" with file "+tmpfile+ " and matlab command : "+repr(matlabCall) + cmd = ["cd '%s';%s"%(tmpdir,tmpCmd),] + result = subprocess.Popen(matlabCall+cmd, stdout=subprocess.PIPE, env = myEnv).communicate()[0].splitlines() + #pdb.set_trace() + os.remove(fullpath) + return result + +def matlabRunNB(cmd, callback = None): + """ Returns a QThread object that can launch the matlab command by calling its start() function. + This allows to run a matlab command without blocking the rest of the program. + A "Finished( QStringList )" Qt signal is emitted when matlab exits. + :param callback is a callback function that will be called at the end of the execution + """ + cmd = [cmd,] + # Because the command may be too long for a command line, let's put it in a temp file and run the file + tmpdir = tempfile.gettempdir() + tmpCmd = ''.join(random.choice(string.letters) for i in xrange(15)) + tmpfile = tmpCmd + '.m' + #print "TMPdir : %s, filename : %s"%(repr(tmpdir), repr(tmpfile)) + fullpath = os.path.join(tmpdir, tmpfile) + # os.path.join(tempfile.tempdir,''.join(random.choice(string.letters) for i in xrange(15))+'.m') + f = open(fullpath, 'w') + f.write(' '.join(cmd) + "\n\n") + f.close() + print "Calling matlab in "+tmpdir+" with file "+tmpfile+ " and matlab command : "+repr(matlabCall) + cmd = ["cd '%s';%s"%(tmpdir,tmpCmd),] + # Create callback function : destroy temporary file and call the provided callback function + if callback is None: + cb = lambda:os.remove(fullpath) + else: + def cb(): + os.remove(fullpath) + callback() + #pdb.set_trace() + return Executor(matlabCall+cmd, objectsToKeep=f, exitFunc = cb) + +def runCmd(cmd): + """ Executes a command and returns the output as an array of strings (the output lines)""" + return subprocess.Popen(cmd, stdout=subprocess.PIPE, env = myEnv).communicate()[0].splitlines() diff --git a/freesurfer_label.txt b/freesurfer_label.txt new file mode 100644 index 0000000..1e8813b --- /dev/null +++ b/freesurfer_label.txt @@ -0,0 +1,1294 @@ +0 Unknown 0 0 0 0 +1 Left-Cerebral-Exterior 70 130 180 0 +2 Left-Cerebral-White-Matter 245 245 245 0 +3 Left-Cerebral-Cortex 205 62 78 0 +4 Left-Lateral-Ventricle 120 18 134 0 +5 Left-Inf-Lat-Vent 196 58 250 0 +6 Left-Cerebellum-Exterior 0 148 0 0 +7 Left-Cerebellum-White-Matter 220 248 164 0 +8 Left-Cerebellum-Cortex 230 148 34 0 +9 Left-Thalamus 0 118 14 0 +10 Left-Thalamus-Proper 0 118 14 0 +11 Left-Caudate 122 186 220 0 +12 Left-Putamen 236 13 176 0 +13 Left-Pallidum 12 48 255 0 +14 3rd-Ventricle 204 182 142 0 +15 4th-Ventricle 42 204 164 0 +16 Brain-Stem 119 159 176 0 +17 Left-Hippocampus 220 216 20 0 +18 Left-Amygdala 103 255 255 0 +19 Left-Insula 80 196 98 0 +20 Left-Operculum 60 58 210 0 +21 Line-1 60 58 210 0 +22 Line-2 60 58 210 0 +23 Line-3 60 58 210 0 +24 CSF 60 60 60 0 +25 Left-Lesion 255 165 0 0 +26 Left-Accumbens-area 255 165 0 0 +27 Left-Substancia-Nigra 0 255 127 0 +28 Left-VentralDC 165 42 42 0 +29 Left-undetermined 135 206 235 0 +30 Left-vessel 160 32 240 0 +31 Left-choroid-plexus 0 200 200 0 +32 Left-F3orb 100 50 100 0 +33 Left-lOg 135 50 74 0 +34 Left-aOg 122 135 50 0 +35 Left-mOg 51 50 135 0 +36 Left-pOg 74 155 60 0 +37 Left-Stellate 120 62 43 0 +38 Left-Porg 74 155 60 0 +39 Left-Aorg 122 135 50 0 +40 Right-Cerebral-Exterior 70 130 180 0 +41 Right-Cerebral-White-Matter 245 245 245 0 +42 Right-Cerebral-Cortex 205 62 78 0 +43 Right-Lateral-Ventricle 120 18 134 0 +44 Right-Inf-Lat-Vent 196 58 250 0 +45 Right-Cerebellum-Exterior 0 148 0 0 +46 Right-Cerebellum-White-Matter 220 248 164 0 +47 Right-Cerebellum-Cortex 230 148 34 0 +48 Right-Thalamus 0 118 14 0 +49 Right-Thalamus-Proper 0 118 14 0 +50 Right-Caudate 122 186 220 0 +51 Right-Putamen 236 13 176 0 +52 Right-Pallidum 13 48 255 0 +53 Right-Hippocampus 220 216 20 0 +54 Right-Amygdala 103 255 255 0 +55 Right-Insula 80 196 98 0 +56 Right-Operculum 60 58 210 0 +57 Right-Lesion 255 165 0 0 +58 Right-Accumbens-area 255 165 0 0 +59 Right-Substancia-Nigra 0 255 127 0 +60 Right-VentralDC 165 42 42 0 +61 Right-undetermined 135 206 235 0 +62 Right-vessel 160 32 240 0 +63 Right-choroid-plexus 0 200 221 0 +64 Right-F3orb 100 50 100 0 +65 Right-lOg 135 50 74 0 +66 Right-aOg 122 135 50 0 +67 Right-mOg 51 50 135 0 +68 Right-pOg 74 155 60 0 +69 Right-Stellate 120 62 43 0 +70 Right-Porg 74 155 60 0 +71 Right-Aorg 122 135 50 0 +72 5th-Ventricle 120 190 150 0 +73 Left-Interior 122 135 50 0 +74 Right-Interior 122 135 50 0 +77 WM-hypointensities 200 70 255 0 +78 Left-WM-hypointensities 255 148 10 0 +79 Right-WM-hypointensities 255 148 10 0 +80 non-WM-hypointensities 164 108 226 0 +81 Left-non-WM-hypointensities 164 108 226 0 +82 Right-non-WM-hypointensities 164 108 226 0 +83 Left-F1 255 218 185 0 +84 Right-F1 255 218 185 0 +85 Optic-Chiasm 234 169 30 0 +192 Corpus_Callosum 250 255 50 0 +86 Left_future_WMSA 200 120 255 0 +87 Right_future_WMSA 200 121 255 0 +88 future_WMSA 200 122 255 0 +96 Left-Amygdala-Anterior 205 10 125 0 +97 Right-Amygdala-Anterior 205 10 125 0 +98 Dura 160 32 240 0 +100 Left-wm-intensity-abnormality 124 140 178 0 +101 Left-caudate-intensity-abnormality 125 140 178 0 +102 Left-putamen-intensity-abnormality 126 140 178 0 +103 Left-accumbens-intensity-abnormality 127 140 178 0 +104 Left-pallidum-intensity-abnormality 124 141 178 0 +105 Left-amygdala-intensity-abnormality 124 142 178 0 +106 Left-hippocampus-intensity-abnormality 124 143 178 0 +107 Left-thalamus-intensity-abnormality 124 144 178 0 +108 Left-VDC-intensity-abnormality 124 140 179 0 +109 Right-wm-intensity-abnormality 124 140 178 0 +110 Right-caudate-intensity-abnormality 125 140 178 0 +111 Right-putamen-intensity-abnormality 126 140 178 0 +112 Right-accumbens-intensity-abnormality 127 140 178 0 +113 Right-pallidum-intensity-abnormality 124 141 178 0 +114 Right-amygdala-intensity-abnormality 124 142 178 0 +115 Right-hippocampus-intensity-abnormality 124 143 178 0 +116 Right-thalamus-intensity-abnormality 124 144 178 0 +117 Right-VDC-intensity-abnormality 124 140 179 0 +118 Epidermis 255 20 147 0 +119 Conn-Tissue 205 179 139 0 +120 SC-Fat-Muscle 238 238 209 0 +121 Cranium 200 200 200 0 +122 CSF-SA 74 255 74 0 +123 Muscle 238 0 0 0 +124 Ear 0 0 139 0 +125 Adipose 173 255 47 0 +126 Spinal-Cord 133 203 229 0 +127 Soft-Tissue 26 237 57 0 +128 Nerve 34 139 34 0 +129 Bone 30 144 255 0 +130 Air 147 19 173 0 +131 Orbital-Fat 238 59 59 0 +132 Tongue 221 39 200 0 +133 Nasal-Structures 238 174 238 0 +134 Globe 255 0 0 0 +135 Teeth 72 61 139 0 +136 Left-Caudate-Putamen 21 39 132 0 +137 Right-Caudate-Putamen 21 39 132 0 +138 Left-Claustrum 65 135 20 0 +139 Right-Claustrum 65 135 20 0 +140 Cornea 134 4 160 0 +142 Diploe 221 226 68 0 +143 Vitreous-Humor 255 255 254 0 +144 Lens 52 209 226 0 +145 Aqueous-Humor 239 160 223 0 +146 Outer-Table 70 130 180 0 +147 Inner-Table 70 130 181 0 +148 Periosteum 139 121 94 0 +149 Endosteum 224 224 224 0 +150 R-C-S 255 0 0 0 +151 Iris 205 205 0 0 +152 SC-Adipose-Muscle 238 238 209 0 +153 SC-Tissue 139 121 94 0 +154 Orbital-Adipose 238 59 59 0 +155 Left-IntCapsule-Ant 238 59 59 0 +156 Right-IntCapsule-Ant 238 59 59 0 +157 Left-IntCapsule-Pos 62 10 205 0 +158 Right-IntCapsule-Pos 62 10 205 0 +159 Left-Cerebral-WM-unmyelinated 0 118 14 0 +160 Right-Cerebral-WM-unmyelinated 0 118 14 0 +161 Left-Cerebral-WM-myelinated 220 216 21 0 +162 Right-Cerebral-WM-myelinated 220 216 21 0 +163 Left-Subcortical-Gray-Matter 122 186 220 0 +164 Right-Subcortical-Gray-Matter 122 186 220 0 +165 Skull 120 120 120 0 +166 Posterior-fossa 14 48 255 0 +167 Scalp 166 42 42 0 +168 Hematoma 121 18 134 0 +169 Left-Basal-Ganglia 236 13 127 0 +176 Right-Basal-Ganglia 236 13 126 0 +170 brainstem 119 159 176 0 +171 DCG 119 0 176 0 +172 Vermis 119 100 176 0 +173 Midbrain 242 104 76 0 +174 Pons 206 195 58 0 +175 Medulla 119 159 176 0 +177 Vermis-White-Matter 119 50 176 0 +178 SCP 142 182 0 0 +179 Floculus 19 100 176 0 +180 Left-Cortical-Dysplasia 73 61 139 0 +181 Right-Cortical-Dysplasia 73 62 139 0 +182 CblumNodulus 10 100 176 0 +193 Left-hippocampal_fissure 0 196 255 0 +194 Left-CADG-head 255 164 164 0 +195 Left-subiculum 196 196 0 0 +196 Left-fimbria 0 100 255 0 +197 Right-hippocampal_fissure 128 196 164 0 +198 Right-CADG-head 0 126 75 0 +199 Right-subiculum 128 96 64 0 +200 Right-fimbria 0 50 128 0 +201 alveus 255 204 153 0 +202 perforant_pathway 255 128 128 0 +203 parasubiculum 255 255 0 0 +204 presubiculum 64 0 64 0 +205 subiculum 0 0 255 0 +206 CA1 255 0 0 0 +207 CA2 128 128 255 0 +208 CA3 0 128 0 0 +209 CA4 196 160 128 0 +210 GC-DG 32 200 255 0 +211 HATA 128 255 128 0 +212 fimbria 204 153 204 0 +213 lateral_ventricle 121 17 136 0 +214 molecular_layer_HP 128 0 0 0 +215 hippocampal_fissure 128 32 255 0 +216 entorhinal_cortex 255 204 102 0 +217 molecular_layer_subiculum 128 128 128 0 +218 Amygdala 104 255 255 0 +219 Cerebral_White_Matter 0 226 0 0 +220 Cerebral_Cortex 205 63 78 0 +221 Inf_Lat_Vent 197 58 250 0 +222 Perirhinal 33 150 250 0 +223 Cerebral_White_Matter_Edge 226 0 0 0 +224 Background 100 100 100 0 +225 Ectorhinal 197 150 250 0 +226 HP_tail 170 170 255 0 +250 Fornix 255 0 0 0 +251 CC_Posterior 0 0 64 0 +252 CC_Mid_Posterior 0 0 112 0 +253 CC_Central 0 0 160 0 +254 CC_Mid_Anterior 0 0 208 0 +255 CC_Anterior 0 0 255 0 +257 CSF-ExtraCerebral 60 60 60 0 +258 Head-ExtraCerebral 150 150 200 0 +259 SkullApprox 120 120 120 0 +260 BoneOrAir 119 159 176 0 +261 PossibleFluid 120 18 134 0 +262 Sinus 119 159 176 0 +263 Left-Eustachian 119 159 176 0 +264 Right-Eustachian 119 159 176 0 +331 Aorta 255 0 0 0 +332 Left-Common-IliacA 255 80 0 0 +333 Right-Common-IliacA 255 160 0 0 +334 Left-External-IliacA 255 255 0 0 +335 Right-External-IliacA 0 255 0 0 +336 Left-Internal-IliacA 255 0 160 0 +337 Right-Internal-IliacA 255 0 255 0 +338 Left-Lateral-SacralA 255 50 80 0 +339 Right-Lateral-SacralA 80 255 50 0 +340 Left-ObturatorA 160 255 50 0 +341 Right-ObturatorA 160 200 255 0 +342 Left-Internal-PudendalA 0 255 160 0 +343 Right-Internal-PudendalA 0 0 255 0 +344 Left-UmbilicalA 80 50 255 0 +345 Right-UmbilicalA 160 0 255 0 +346 Left-Inf-RectalA 255 210 0 0 +347 Right-Inf-RectalA 0 160 255 0 +348 Left-Common-IliacV 255 200 80 0 +349 Right-Common-IliacV 255 200 160 0 +350 Left-External-IliacV 255 80 200 0 +351 Right-External-IliacV 255 160 200 0 +352 Left-Internal-IliacV 30 255 80 0 +353 Right-Internal-IliacV 80 200 255 0 +354 Left-ObturatorV 80 255 200 0 +355 Right-ObturatorV 195 255 200 0 +356 Left-Internal-PudendalV 120 200 20 0 +357 Right-Internal-PudendalV 170 10 200 0 +358 Pos-Lymph 20 130 180 0 +359 Neg-Lymph 20 180 130 0 +400 V1 206 62 78 0 +401 V2 121 18 134 0 +402 BA44 199 58 250 0 +403 BA45 1 148 0 0 +404 BA4a 221 248 164 0 +405 BA4p 231 148 34 0 +406 BA6 1 118 14 0 +407 BA2 120 118 14 0 +408 BA1_old 123 186 221 0 +409 BAun2 238 13 177 0 +410 BA1 123 186 220 0 +411 BA2b 138 13 206 0 +412 BA3a 238 130 176 0 +413 BA3b 218 230 76 0 +414 MT 38 213 176 0 +415 AIPS_AIP_l 1 225 176 0 +416 AIPS_AIP_r 1 225 176 0 +417 AIPS_VIP_l 200 2 100 0 +418 AIPS_VIP_r 200 2 100 0 +419 IPL_PFcm_l 5 200 90 0 +420 IPL_PFcm_r 5 200 90 0 +421 IPL_PF_l 100 5 200 0 +422 IPL_PFm_l 25 255 100 0 +423 IPL_PFm_r 25 255 100 0 +424 IPL_PFop_l 230 7 100 0 +425 IPL_PFop_r 230 7 100 0 +426 IPL_PF_r 100 5 200 0 +427 IPL_PFt_l 150 10 200 0 +428 IPL_PFt_r 150 10 200 0 +429 IPL_PGa_l 175 10 176 0 +430 IPL_PGa_r 175 10 176 0 +431 IPL_PGp_l 10 100 255 0 +432 IPL_PGp_r 10 100 255 0 +433 Visual_V3d_l 150 45 70 0 +434 Visual_V3d_r 150 45 70 0 +435 Visual_V4_l 45 200 15 0 +436 Visual_V4_r 45 200 15 0 +437 Visual_V5_b 227 45 100 0 +438 Visual_VP_l 227 45 100 0 +439 Visual_VP_r 227 45 100 0 +498 wmsa 143 188 143 0 +499 other_wmsa 255 248 220 0 +500 right_CA2_3 17 85 136 0 +501 right_alveus 119 187 102 0 +502 right_CA1 204 68 34 0 +503 right_fimbria 204 0 255 0 +504 right_presubiculum 221 187 17 0 +505 right_hippocampal_fissure 153 221 238 0 +506 right_CA4_DG 51 17 17 0 +507 right_subiculum 0 119 85 0 +508 right_fornix 20 100 200 0 +550 left_CA2_3 17 85 137 0 +551 left_alveus 119 187 103 0 +552 left_CA1 204 68 35 0 +553 left_fimbria 204 0 254 0 +554 left_presubiculum 221 187 16 0 +555 left_hippocampal_fissure 153 221 239 0 +556 left_CA4_DG 51 17 18 0 +557 left_subiculum 0 119 86 0 +558 left_fornix 20 100 201 0 +600 Tumor 254 254 254 0 +601 Cbm_Left_I_IV 70 130 180 0 +602 Cbm_Right_I_IV 245 245 245 0 +603 Cbm_Left_V 205 62 78 0 +604 Cbm_Right_V 120 18 134 0 +605 Cbm_Left_VI 196 58 250 0 +606 Cbm_Vermis_VI 0 148 0 0 +607 Cbm_Right_VI 220 248 164 0 +608 Cbm_Left_CrusI 230 148 34 0 +609 Cbm_Vermis_CrusI 0 118 14 0 +610 Cbm_Right_CrusI 0 118 14 0 +611 Cbm_Left_CrusII 122 186 220 0 +612 Cbm_Vermis_CrusII 236 13 176 0 +613 Cbm_Right_CrusII 12 48 255 0 +614 Cbm_Left_VIIb 204 182 142 0 +615 Cbm_Vermis_VIIb 42 204 164 0 +616 Cbm_Right_VIIb 119 159 176 0 +617 Cbm_Left_VIIIa 220 216 20 0 +618 Cbm_Vermis_VIIIa 103 255 255 0 +619 Cbm_Right_VIIIa 80 196 98 0 +620 Cbm_Left_VIIIb 60 58 210 0 +621 Cbm_Vermis_VIIIb 60 58 210 0 +622 Cbm_Right_VIIIb 60 58 210 0 +623 Cbm_Left_IX 60 58 210 0 +624 Cbm_Vermis_IX 60 60 60 0 +625 Cbm_Right_IX 255 165 0 0 +626 Cbm_Left_X 255 165 0 0 +627 Cbm_Vermis_X 0 255 127 0 +628 Cbm_Right_X 165 42 42 0 +640 Cbm_Right_I_V_med 204 0 0 0 +641 Cbm_Right_I_V_mid 255 0 0 0 +642 Cbm_Right_VI_med 0 0 255 0 +643 Cbm_Right_VI_mid 30 144 255 0 +644 Cbm_Right_VI_lat 100 212 237 0 +645 Cbm_Right_CrusI_med 218 165 32 0 +646 Cbm_Right_CrusI_mid 255 215 0 0 +647 Cbm_Right_CrusI_lat 255 255 166 0 +648 Cbm_Right_CrusII_med 153 0 204 0 +649 Cbm_Right_CrusII_mid 153 141 209 0 +650 Cbm_Right_CrusII_lat 204 204 255 0 +651 Cbm_Right_7med 31 212 194 0 +652 Cbm_Right_7mid 3 255 237 0 +653 Cbm_Right_7lat 204 255 255 0 +654 Cbm_Right_8med 86 74 147 0 +655 Cbm_Right_8mid 114 114 190 0 +656 Cbm_Right_8lat 184 178 255 0 +657 Cbm_Right_PUNs 126 138 37 0 +658 Cbm_Right_TONs 189 197 117 0 +659 Cbm_Right_FLOs 240 230 140 0 +660 Cbm_Left_I_V_med 204 0 0 0 +661 Cbm_Left_I_V_mid 255 0 0 0 +662 Cbm_Left_VI_med 0 0 255 0 +663 Cbm_Left_VI_mid 30 144 255 0 +664 Cbm_Left_VI_lat 100 212 237 0 +665 Cbm_Left_CrusI_med 218 165 32 0 +666 Cbm_Left_CrusI_mid 255 215 0 0 +667 Cbm_Left_CrusI_lat 255 255 166 0 +668 Cbm_Left_CrusII_med 153 0 204 0 +669 Cbm_Left_CrusII_mid 153 141 209 0 +670 Cbm_Left_CrusII_lat 204 204 255 0 +671 Cbm_Left_7med 31 212 194 0 +672 Cbm_Left_7mid 3 255 237 0 +673 Cbm_Left_7lat 204 255 255 0 +674 Cbm_Left_8med 86 74 147 0 +675 Cbm_Left_8mid 114 114 190 0 +676 Cbm_Left_8lat 184 178 255 0 +677 Cbm_Left_PUNs 126 138 37 0 +678 Cbm_Left_TONs 189 197 117 0 +679 Cbm_Left_FLOs 240 230 140 0 +690 CbmWM_Gyri_Left 122 135 50 0 +691 CbmWM_Gyri_Right 122 135 50 0 +701 CSF-FSL-FAST 120 18 134 0 +702 GrayMatter-FSL-FAST 205 62 78 0 +703 WhiteMatter-FSL-FAST 0 225 0 0 +1000 ctx-lh-unknown 25 5 25 0 +1001 ctx-lh-bankssts 25 100 40 0 +1002 ctx-lh-caudalanteriorcingulate 125 100 160 0 +1003 ctx-lh-caudalmiddlefrontal 100 25 0 0 +1004 ctx-lh-corpuscallosum 120 70 50 0 +1005 ctx-lh-cuneus 220 20 100 0 +1006 ctx-lh-entorhinal 220 20 10 0 +1007 ctx-lh-fusiform 180 220 140 0 +1008 ctx-lh-inferiorparietal 220 60 220 0 +1009 ctx-lh-inferiortemporal 180 40 120 0 +1010 ctx-lh-isthmuscingulate 140 20 140 0 +1011 ctx-lh-lateraloccipital 20 30 140 0 +1012 ctx-lh-lateralorbitofrontal 35 75 50 0 +1013 ctx-lh-lingual 225 140 140 0 +1014 ctx-lh-medialorbitofrontal 200 35 75 0 +1015 ctx-lh-middletemporal 160 100 50 0 +1016 ctx-lh-parahippocampal 20 220 60 0 +1017 ctx-lh-paracentral 60 220 60 0 +1018 ctx-lh-parsopercularis 220 180 140 0 +1019 ctx-lh-parsorbitalis 20 100 50 0 +1020 ctx-lh-parstriangularis 220 60 20 0 +1021 ctx-lh-pericalcarine 120 100 60 0 +1022 ctx-lh-postcentral 220 20 20 0 +1023 ctx-lh-posteriorcingulate 220 180 220 0 +1024 ctx-lh-precentral 60 20 220 0 +1025 ctx-lh-precuneus 160 140 180 0 +1026 ctx-lh-rostralanteriorcingulate 80 20 140 0 +1027 ctx-lh-rostralmiddlefrontal 75 50 125 0 +1028 ctx-lh-superiorfrontal 20 220 160 0 +1029 ctx-lh-superiorparietal 20 180 140 0 +1030 ctx-lh-superiortemporal 140 220 220 0 +1031 ctx-lh-supramarginal 80 160 20 0 +1032 ctx-lh-frontalpole 100 0 100 0 +1033 ctx-lh-temporalpole 70 70 70 0 +1034 ctx-lh-transversetemporal 150 150 200 0 +1035 ctx-lh-insula 255 192 32 0 +2000 ctx-rh-unknown 25 5 25 0 +2001 ctx-rh-bankssts 25 100 40 0 +2002 ctx-rh-caudalanteriorcingulate 125 100 160 0 +2003 ctx-rh-caudalmiddlefrontal 100 25 0 0 +2004 ctx-rh-corpuscallosum 120 70 50 0 +2005 ctx-rh-cuneus 220 20 100 0 +2006 ctx-rh-entorhinal 220 20 10 0 +2007 ctx-rh-fusiform 180 220 140 0 +2008 ctx-rh-inferiorparietal 220 60 220 0 +2009 ctx-rh-inferiortemporal 180 40 120 0 +2010 ctx-rh-isthmuscingulate 140 20 140 0 +2011 ctx-rh-lateraloccipital 20 30 140 0 +2012 ctx-rh-lateralorbitofrontal 35 75 50 0 +2013 ctx-rh-lingual 225 140 140 0 +2014 ctx-rh-medialorbitofrontal 200 35 75 0 +2015 ctx-rh-middletemporal 160 100 50 0 +2016 ctx-rh-parahippocampal 20 220 60 0 +2017 ctx-rh-paracentral 60 220 60 0 +2018 ctx-rh-parsopercularis 220 180 140 0 +2019 ctx-rh-parsorbitalis 20 100 50 0 +2020 ctx-rh-parstriangularis 220 60 20 0 +2021 ctx-rh-pericalcarine 120 100 60 0 +2022 ctx-rh-postcentral 220 20 20 0 +2023 ctx-rh-posteriorcingulate 220 180 220 0 +2024 ctx-rh-precentral 60 20 220 0 +2025 ctx-rh-precuneus 160 140 180 0 +2026 ctx-rh-rostralanteriorcingulate 80 20 140 0 +2027 ctx-rh-rostralmiddlefrontal 75 50 125 0 +2028 ctx-rh-superiorfrontal 20 220 160 0 +2029 ctx-rh-superiorparietal 20 180 140 0 +2030 ctx-rh-superiortemporal 140 220 220 0 +2031 ctx-rh-supramarginal 80 160 20 0 +2032 ctx-rh-frontalpole 100 0 100 0 +2033 ctx-rh-temporalpole 70 70 70 0 +2034 ctx-rh-transversetemporal 150 150 200 0 +2035 ctx-rh-insula 255 192 32 0 +3000 wm-lh-unknown 230 250 230 0 +3001 wm-lh-bankssts 230 155 215 0 +3002 wm-lh-caudalanteriorcingulate 130 155 95 0 +3003 wm-lh-caudalmiddlefrontal 155 230 255 0 +3004 wm-lh-corpuscallosum 135 185 205 0 +3005 wm-lh-cuneus 35 235 155 0 +3006 wm-lh-entorhinal 35 235 245 0 +3007 wm-lh-fusiform 75 35 115 0 +3008 wm-lh-inferiorparietal 35 195 35 0 +3009 wm-lh-inferiortemporal 75 215 135 0 +3010 wm-lh-isthmuscingulate 115 235 115 0 +3011 wm-lh-lateraloccipital 235 225 115 0 +3012 wm-lh-lateralorbitofrontal 220 180 205 0 +3013 wm-lh-lingual 30 115 115 0 +3014 wm-lh-medialorbitofrontal 55 220 180 0 +3015 wm-lh-middletemporal 95 155 205 0 +3016 wm-lh-parahippocampal 235 35 195 0 +3017 wm-lh-paracentral 195 35 195 0 +3018 wm-lh-parsopercularis 35 75 115 0 +3019 wm-lh-parsorbitalis 235 155 205 0 +3020 wm-lh-parstriangularis 35 195 235 0 +3021 wm-lh-pericalcarine 135 155 195 0 +3022 wm-lh-postcentral 35 235 235 0 +3023 wm-lh-posteriorcingulate 35 75 35 0 +3024 wm-lh-precentral 195 235 35 0 +3025 wm-lh-precuneus 95 115 75 0 +3026 wm-lh-rostralanteriorcingulate 175 235 115 0 +3027 wm-lh-rostralmiddlefrontal 180 205 130 0 +3028 wm-lh-superiorfrontal 235 35 95 0 +3029 wm-lh-superiorparietal 235 75 115 0 +3030 wm-lh-superiortemporal 115 35 35 0 +3031 wm-lh-supramarginal 175 95 235 0 +3032 wm-lh-frontalpole 155 255 155 0 +3033 wm-lh-temporalpole 185 185 185 0 +3034 wm-lh-transversetemporal 105 105 55 0 +3035 wm-lh-insula 20 220 160 0 +4000 wm-rh-unknown 230 250 230 0 +4001 wm-rh-bankssts 230 155 215 0 +4002 wm-rh-caudalanteriorcingulate 130 155 95 0 +4003 wm-rh-caudalmiddlefrontal 155 230 255 0 +4004 wm-rh-corpuscallosum 135 185 205 0 +4005 wm-rh-cuneus 35 235 155 0 +4006 wm-rh-entorhinal 35 235 245 0 +4007 wm-rh-fusiform 75 35 115 0 +4008 wm-rh-inferiorparietal 35 195 35 0 +4009 wm-rh-inferiortemporal 75 215 135 0 +4010 wm-rh-isthmuscingulate 115 235 115 0 +4011 wm-rh-lateraloccipital 235 225 115 0 +4012 wm-rh-lateralorbitofrontal 220 180 205 0 +4013 wm-rh-lingual 30 115 115 0 +4014 wm-rh-medialorbitofrontal 55 220 180 0 +4015 wm-rh-middletemporal 95 155 205 0 +4016 wm-rh-parahippocampal 235 35 195 0 +4017 wm-rh-paracentral 195 35 195 0 +4018 wm-rh-parsopercularis 35 75 115 0 +4019 wm-rh-parsorbitalis 235 155 205 0 +4020 wm-rh-parstriangularis 35 195 235 0 +4021 wm-rh-pericalcarine 135 155 195 0 +4022 wm-rh-postcentral 35 235 235 0 +4023 wm-rh-posteriorcingulate 35 75 35 0 +4024 wm-rh-precentral 195 235 35 0 +4025 wm-rh-precuneus 95 115 75 0 +4026 wm-rh-rostralanteriorcingulate 175 235 115 0 +4027 wm-rh-rostralmiddlefrontal 180 205 130 0 +4028 wm-rh-superiorfrontal 235 35 95 0 +4029 wm-rh-superiorparietal 235 75 115 0 +4030 wm-rh-superiortemporal 115 35 35 0 +4031 wm-rh-supramarginal 175 95 235 0 +4032 wm-rh-frontalpole 155 255 155 0 +4033 wm-rh-temporalpole 185 185 185 0 +4034 wm-rh-transversetemporal 105 105 55 0 +4035 wm-rh-insula 20 220 160 0 +3201 wm-lh-frontal-lobe 235 35 95 0 +3203 wm-lh-cingulate-lobe 35 75 35 0 +3204 wm-lh-occiptal-lobe 135 155 195 0 +3205 wm-lh-temporal-lobe 115 35 35 0 +3206 wm-lh-parietal-lobe 35 195 35 0 +3207 wm-lh-insula-lobe 20 220 160 0 +4201 wm-rh-frontal-lobe 235 35 95 0 +4203 wm-rh-cingulate-lobe 35 75 35 0 +4204 wm-rh-occiptal-lobe 135 155 195 0 +4205 wm-rh-temporal-lobe 115 35 35 0 +4206 wm-rh-parietal-lobe 35 195 35 0 +4207 wm-rh-insula-lobe 20 220 160 0 +1100 ctx-lh-Unknown 0 0 0 0 +1101 ctx-lh-Corpus_callosum 50 50 50 0 +1102 ctx-lh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 0 +1103 ctx-lh-G_cingulate-Isthmus 60 25 25 0 +1104 ctx-lh-G_cingulate-Main_part 25 60 60 0 +1200 ctx-lh-G_cingulate-caudal_ACC 25 60 61 0 +1201 ctx-lh-G_cingulate-rostral_ACC 25 90 60 0 +1202 ctx-lh-G_cingulate-posterior 25 120 60 0 +1205 ctx-lh-S_cingulate-caudal_ACC 25 150 60 0 +1206 ctx-lh-S_cingulate-rostral_ACC 25 180 60 0 +1207 ctx-lh-S_cingulate-posterior 25 210 60 0 +1210 ctx-lh-S_pericallosal-caudal 25 150 90 0 +1211 ctx-lh-S_pericallosal-rostral 25 180 90 0 +1212 ctx-lh-S_pericallosal-posterior 25 210 90 0 +1105 ctx-lh-G_cuneus 180 20 20 0 +1106 ctx-lh-G_frontal_inf-Opercular_part 220 20 100 0 +1107 ctx-lh-G_frontal_inf-Orbital_part 140 60 60 0 +1108 ctx-lh-G_frontal_inf-Triangular_part 180 220 140 0 +1109 ctx-lh-G_frontal_middle 140 100 180 0 +1110 ctx-lh-G_frontal_superior 180 20 140 0 +1111 ctx-lh-G_frontomarginal 140 20 140 0 +1112 ctx-lh-G_insular_long 21 10 10 0 +1113 ctx-lh-G_insular_short 225 140 140 0 +1114 ctx-lh-G_and_S_occipital_inferior 23 60 180 0 +1115 ctx-lh-G_occipital_middle 180 60 180 0 +1116 ctx-lh-G_occipital_superior 20 220 60 0 +1117 ctx-lh-G_occipit-temp_lat-Or_fusiform 60 20 140 0 +1118 ctx-lh-G_occipit-temp_med-Lingual_part 220 180 140 0 +1119 ctx-lh-G_occipit-temp_med-Parahippocampal_part 65 100 20 0 +1120 ctx-lh-G_orbital 220 60 20 0 +1121 ctx-lh-G_paracentral 60 100 60 0 +1122 ctx-lh-G_parietal_inferior-Angular_part 20 60 220 0 +1123 ctx-lh-G_parietal_inferior-Supramarginal_part 100 100 60 0 +1124 ctx-lh-G_parietal_superior 220 180 220 0 +1125 ctx-lh-G_postcentral 20 180 140 0 +1126 ctx-lh-G_precentral 60 140 180 0 +1127 ctx-lh-G_precuneus 25 20 140 0 +1128 ctx-lh-G_rectus 20 60 100 0 +1129 ctx-lh-G_subcallosal 60 220 20 0 +1130 ctx-lh-G_subcentral 60 20 220 0 +1131 ctx-lh-G_temporal_inferior 220 220 100 0 +1132 ctx-lh-G_temporal_middle 180 60 60 0 +1133 ctx-lh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 0 +1134 ctx-lh-G_temp_sup-Lateral_aspect 220 60 220 0 +1135 ctx-lh-G_temp_sup-Planum_polare 65 220 60 0 +1136 ctx-lh-G_temp_sup-Planum_tempolare 25 140 20 0 +1137 ctx-lh-G_and_S_transverse_frontopolar 13 0 250 0 +1138 ctx-lh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 0 +1139 ctx-lh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 0 +1140 ctx-lh-Lat_Fissure-post_sgt 61 60 100 0 +1141 ctx-lh-Medial_wall 25 25 25 0 +1142 ctx-lh-Pole_occipital 140 20 60 0 +1143 ctx-lh-Pole_temporal 220 180 20 0 +1144 ctx-lh-S_calcarine 63 180 180 0 +1145 ctx-lh-S_central 221 20 10 0 +1146 ctx-lh-S_central_insula 21 220 20 0 +1147 ctx-lh-S_cingulate-Main_part_and_Intracingulate 183 100 20 0 +1148 ctx-lh-S_cingulate-Marginalis_part 221 20 100 0 +1149 ctx-lh-S_circular_insula_anterior 221 60 140 0 +1150 ctx-lh-S_circular_insula_inferior 221 20 220 0 +1151 ctx-lh-S_circular_insula_superior 61 220 220 0 +1152 ctx-lh-S_collateral_transverse_ant 100 200 200 0 +1153 ctx-lh-S_collateral_transverse_post 10 200 200 0 +1154 ctx-lh-S_frontal_inferior 221 220 20 0 +1155 ctx-lh-S_frontal_middle 141 20 100 0 +1156 ctx-lh-S_frontal_superior 61 220 100 0 +1157 ctx-lh-S_frontomarginal 21 220 60 0 +1158 ctx-lh-S_intermedius_primus-Jensen 141 60 20 0 +1159 ctx-lh-S_intraparietal-and_Parietal_transverse 143 20 220 0 +1160 ctx-lh-S_occipital_anterior 61 20 180 0 +1161 ctx-lh-S_occipital_middle_and_Lunatus 101 60 220 0 +1162 ctx-lh-S_occipital_superior_and_transversalis 21 20 140 0 +1163 ctx-lh-S_occipito-temporal_lateral 221 140 20 0 +1164 ctx-lh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 0 +1165 ctx-lh-S_orbital-H_shapped 101 20 20 0 +1166 ctx-lh-S_orbital_lateral 221 100 20 0 +1167 ctx-lh-S_orbital_medial-Or_olfactory 181 200 20 0 +1168 ctx-lh-S_paracentral 21 180 140 0 +1169 ctx-lh-S_parieto_occipital 101 100 180 0 +1170 ctx-lh-S_pericallosal 181 220 20 0 +1171 ctx-lh-S_postcentral 21 140 200 0 +1172 ctx-lh-S_precentral-Inferior-part 21 20 240 0 +1173 ctx-lh-S_precentral-Superior-part 21 20 200 0 +1174 ctx-lh-S_subcentral_ant 61 180 60 0 +1175 ctx-lh-S_subcentral_post 61 180 250 0 +1176 ctx-lh-S_suborbital 21 20 60 0 +1177 ctx-lh-S_subparietal 101 60 60 0 +1178 ctx-lh-S_supracingulate 21 220 220 0 +1179 ctx-lh-S_temporal_inferior 21 180 180 0 +1180 ctx-lh-S_temporal_superior 223 220 60 0 +1181 ctx-lh-S_temporal_transverse 221 60 60 0 +2100 ctx-rh-Unknown 0 0 0 0 +2101 ctx-rh-Corpus_callosum 50 50 50 0 +2102 ctx-rh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 0 +2103 ctx-rh-G_cingulate-Isthmus 60 25 25 0 +2104 ctx-rh-G_cingulate-Main_part 25 60 60 0 +2105 ctx-rh-G_cuneus 180 20 20 0 +2106 ctx-rh-G_frontal_inf-Opercular_part 220 20 100 0 +2107 ctx-rh-G_frontal_inf-Orbital_part 140 60 60 0 +2108 ctx-rh-G_frontal_inf-Triangular_part 180 220 140 0 +2109 ctx-rh-G_frontal_middle 140 100 180 0 +2110 ctx-rh-G_frontal_superior 180 20 140 0 +2111 ctx-rh-G_frontomarginal 140 20 140 0 +2112 ctx-rh-G_insular_long 21 10 10 0 +2113 ctx-rh-G_insular_short 225 140 140 0 +2114 ctx-rh-G_and_S_occipital_inferior 23 60 180 0 +2115 ctx-rh-G_occipital_middle 180 60 180 0 +2116 ctx-rh-G_occipital_superior 20 220 60 0 +2117 ctx-rh-G_occipit-temp_lat-Or_fusiform 60 20 140 0 +2118 ctx-rh-G_occipit-temp_med-Lingual_part 220 180 140 0 +2119 ctx-rh-G_occipit-temp_med-Parahippocampal_part 65 100 20 0 +2120 ctx-rh-G_orbital 220 60 20 0 +2121 ctx-rh-G_paracentral 60 100 60 0 +2122 ctx-rh-G_parietal_inferior-Angular_part 20 60 220 0 +2123 ctx-rh-G_parietal_inferior-Supramarginal_part 100 100 60 0 +2124 ctx-rh-G_parietal_superior 220 180 220 0 +2125 ctx-rh-G_postcentral 20 180 140 0 +2126 ctx-rh-G_precentral 60 140 180 0 +2127 ctx-rh-G_precuneus 25 20 140 0 +2128 ctx-rh-G_rectus 20 60 100 0 +2129 ctx-rh-G_subcallosal 60 220 20 0 +2130 ctx-rh-G_subcentral 60 20 220 0 +2131 ctx-rh-G_temporal_inferior 220 220 100 0 +2132 ctx-rh-G_temporal_middle 180 60 60 0 +2133 ctx-rh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 0 +2134 ctx-rh-G_temp_sup-Lateral_aspect 220 60 220 0 +2135 ctx-rh-G_temp_sup-Planum_polare 65 220 60 0 +2136 ctx-rh-G_temp_sup-Planum_tempolare 25 140 20 0 +2137 ctx-rh-G_and_S_transverse_frontopolar 13 0 250 0 +2138 ctx-rh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 0 +2139 ctx-rh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 0 +2140 ctx-rh-Lat_Fissure-post_sgt 61 60 100 0 +2141 ctx-rh-Medial_wall 25 25 25 0 +2142 ctx-rh-Pole_occipital 140 20 60 0 +2143 ctx-rh-Pole_temporal 220 180 20 0 +2144 ctx-rh-S_calcarine 63 180 180 0 +2145 ctx-rh-S_central 221 20 10 0 +2146 ctx-rh-S_central_insula 21 220 20 0 +2147 ctx-rh-S_cingulate-Main_part_and_Intracingulate 183 100 20 0 +2148 ctx-rh-S_cingulate-Marginalis_part 221 20 100 0 +2149 ctx-rh-S_circular_insula_anterior 221 60 140 0 +2150 ctx-rh-S_circular_insula_inferior 221 20 220 0 +2151 ctx-rh-S_circular_insula_superior 61 220 220 0 +2152 ctx-rh-S_collateral_transverse_ant 100 200 200 0 +2153 ctx-rh-S_collateral_transverse_post 10 200 200 0 +2154 ctx-rh-S_frontal_inferior 221 220 20 0 +2155 ctx-rh-S_frontal_middle 141 20 100 0 +2156 ctx-rh-S_frontal_superior 61 220 100 0 +2157 ctx-rh-S_frontomarginal 21 220 60 0 +2158 ctx-rh-S_intermedius_primus-Jensen 141 60 20 0 +2159 ctx-rh-S_intraparietal-and_Parietal_transverse 143 20 220 0 +2160 ctx-rh-S_occipital_anterior 61 20 180 0 +2161 ctx-rh-S_occipital_middle_and_Lunatus 101 60 220 0 +2162 ctx-rh-S_occipital_superior_and_transversalis 21 20 140 0 +2163 ctx-rh-S_occipito-temporal_lateral 221 140 20 0 +2164 ctx-rh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 0 +2165 ctx-rh-S_orbital-H_shapped 101 20 20 0 +2166 ctx-rh-S_orbital_lateral 221 100 20 0 +2167 ctx-rh-S_orbital_medial-Or_olfactory 181 200 20 0 +2168 ctx-rh-S_paracentral 21 180 140 0 +2169 ctx-rh-S_parieto_occipital 101 100 180 0 +2170 ctx-rh-S_pericallosal 181 220 20 0 +2171 ctx-rh-S_postcentral 21 140 200 0 +2172 ctx-rh-S_precentral-Inferior-part 21 20 240 0 +2173 ctx-rh-S_precentral-Superior-part 21 20 200 0 +2174 ctx-rh-S_subcentral_ant 61 180 60 0 +2175 ctx-rh-S_subcentral_post 61 180 250 0 +2176 ctx-rh-S_suborbital 21 20 60 0 +2177 ctx-rh-S_subparietal 101 60 60 0 +2178 ctx-rh-S_supracingulate 21 220 220 0 +2179 ctx-rh-S_temporal_inferior 21 180 180 0 +2180 ctx-rh-S_temporal_superior 223 220 60 0 +2181 ctx-rh-S_temporal_transverse 221 60 60 0 +2200 ctx-rh-G_cingulate-caudal_ACC 25 60 61 0 +2201 ctx-rh-G_cingulate-rostral_ACC 25 90 60 0 +2202 ctx-rh-G_cingulate-posterior 25 120 60 0 +2205 ctx-rh-S_cingulate-caudal_ACC 25 150 60 0 +2206 ctx-rh-S_cingulate-rostral_ACC 25 180 60 0 +2207 ctx-rh-S_cingulate-posterior 25 210 60 0 +2210 ctx-rh-S_pericallosal-caudal 25 150 90 0 +2211 ctx-rh-S_pericallosal-rostral 25 180 90 0 +2212 ctx-rh-S_pericallosal-posterior 25 210 90 0 +3100 wm-lh-Unknown 0 0 0 0 +3101 wm-lh-Corpus_callosum 50 50 50 0 +3102 wm-lh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 0 +3103 wm-lh-G_cingulate-Isthmus 60 25 25 0 +3104 wm-lh-G_cingulate-Main_part 25 60 60 0 +3105 wm-lh-G_cuneus 180 20 20 0 +3106 wm-lh-G_frontal_inf-Opercular_part 220 20 100 0 +3107 wm-lh-G_frontal_inf-Orbital_part 140 60 60 0 +3108 wm-lh-G_frontal_inf-Triangular_part 180 220 140 0 +3109 wm-lh-G_frontal_middle 140 100 180 0 +3110 wm-lh-G_frontal_superior 180 20 140 0 +3111 wm-lh-G_frontomarginal 140 20 140 0 +3112 wm-lh-G_insular_long 21 10 10 0 +3113 wm-lh-G_insular_short 225 140 140 0 +3114 wm-lh-G_and_S_occipital_inferior 23 60 180 0 +3115 wm-lh-G_occipital_middle 180 60 180 0 +3116 wm-lh-G_occipital_superior 20 220 60 0 +3117 wm-lh-G_occipit-temp_lat-Or_fusiform 60 20 140 0 +3118 wm-lh-G_occipit-temp_med-Lingual_part 220 180 140 0 +3119 wm-lh-G_occipit-temp_med-Parahippocampal_part 65 100 20 0 +3120 wm-lh-G_orbital 220 60 20 0 +3121 wm-lh-G_paracentral 60 100 60 0 +3122 wm-lh-G_parietal_inferior-Angular_part 20 60 220 0 +3123 wm-lh-G_parietal_inferior-Supramarginal_part 100 100 60 0 +3124 wm-lh-G_parietal_superior 220 180 220 0 +3125 wm-lh-G_postcentral 20 180 140 0 +3126 wm-lh-G_precentral 60 140 180 0 +3127 wm-lh-G_precuneus 25 20 140 0 +3128 wm-lh-G_rectus 20 60 100 0 +3129 wm-lh-G_subcallosal 60 220 20 0 +3130 wm-lh-G_subcentral 60 20 220 0 +3131 wm-lh-G_temporal_inferior 220 220 100 0 +3132 wm-lh-G_temporal_middle 180 60 60 0 +3133 wm-lh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 0 +3134 wm-lh-G_temp_sup-Lateral_aspect 220 60 220 0 +3135 wm-lh-G_temp_sup-Planum_polare 65 220 60 0 +3136 wm-lh-G_temp_sup-Planum_tempolare 25 140 20 0 +3137 wm-lh-G_and_S_transverse_frontopolar 13 0 250 0 +3138 wm-lh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 0 +3139 wm-lh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 0 +3140 wm-lh-Lat_Fissure-post_sgt 61 60 100 0 +3141 wm-lh-Medial_wall 25 25 25 0 +3142 wm-lh-Pole_occipital 140 20 60 0 +3143 wm-lh-Pole_temporal 220 180 20 0 +3144 wm-lh-S_calcarine 63 180 180 0 +3145 wm-lh-S_central 221 20 10 0 +3146 wm-lh-S_central_insula 21 220 20 0 +3147 wm-lh-S_cingulate-Main_part_and_Intracingulate 183 100 20 0 +3148 wm-lh-S_cingulate-Marginalis_part 221 20 100 0 +3149 wm-lh-S_circular_insula_anterior 221 60 140 0 +3150 wm-lh-S_circular_insula_inferior 221 20 220 0 +3151 wm-lh-S_circular_insula_superior 61 220 220 0 +3152 wm-lh-S_collateral_transverse_ant 100 200 200 0 +3153 wm-lh-S_collateral_transverse_post 10 200 200 0 +3154 wm-lh-S_frontal_inferior 221 220 20 0 +3155 wm-lh-S_frontal_middle 141 20 100 0 +3156 wm-lh-S_frontal_superior 61 220 100 0 +3157 wm-lh-S_frontomarginal 21 220 60 0 +3158 wm-lh-S_intermedius_primus-Jensen 141 60 20 0 +3159 wm-lh-S_intraparietal-and_Parietal_transverse 143 20 220 0 +3160 wm-lh-S_occipital_anterior 61 20 180 0 +3161 wm-lh-S_occipital_middle_and_Lunatus 101 60 220 0 +3162 wm-lh-S_occipital_superior_and_transversalis 21 20 140 0 +3163 wm-lh-S_occipito-temporal_lateral 221 140 20 0 +3164 wm-lh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 0 +3165 wm-lh-S_orbital-H_shapped 101 20 20 0 +3166 wm-lh-S_orbital_lateral 221 100 20 0 +3167 wm-lh-S_orbital_medial-Or_olfactory 181 200 20 0 +3168 wm-lh-S_paracentral 21 180 140 0 +3169 wm-lh-S_parieto_occipital 101 100 180 0 +3170 wm-lh-S_pericallosal 181 220 20 0 +3171 wm-lh-S_postcentral 21 140 200 0 +3172 wm-lh-S_precentral-Inferior-part 21 20 240 0 +3173 wm-lh-S_precentral-Superior-part 21 20 200 0 +3174 wm-lh-S_subcentral_ant 61 180 60 0 +3175 wm-lh-S_subcentral_post 61 180 250 0 +3176 wm-lh-S_suborbital 21 20 60 0 +3177 wm-lh-S_subparietal 101 60 60 0 +3178 wm-lh-S_supracingulate 21 220 220 0 +3179 wm-lh-S_temporal_inferior 21 180 180 0 +3180 wm-lh-S_temporal_superior 223 220 60 0 +3181 wm-lh-S_temporal_transverse 221 60 60 0 +4100 wm-rh-Unknown 0 0 0 0 +4101 wm-rh-Corpus_callosum 50 50 50 0 +4102 wm-rh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 0 +4103 wm-rh-G_cingulate-Isthmus 60 25 25 0 +4104 wm-rh-G_cingulate-Main_part 25 60 60 0 +4105 wm-rh-G_cuneus 180 20 20 0 +4106 wm-rh-G_frontal_inf-Opercular_part 220 20 100 0 +4107 wm-rh-G_frontal_inf-Orbital_part 140 60 60 0 +4108 wm-rh-G_frontal_inf-Triangular_part 180 220 140 0 +4109 wm-rh-G_frontal_middle 140 100 180 0 +4110 wm-rh-G_frontal_superior 180 20 140 0 +4111 wm-rh-G_frontomarginal 140 20 140 0 +4112 wm-rh-G_insular_long 21 10 10 0 +4113 wm-rh-G_insular_short 225 140 140 0 +4114 wm-rh-G_and_S_occipital_inferior 23 60 180 0 +4115 wm-rh-G_occipital_middle 180 60 180 0 +4116 wm-rh-G_occipital_superior 20 220 60 0 +4117 wm-rh-G_occipit-temp_lat-Or_fusiform 60 20 140 0 +4118 wm-rh-G_occipit-temp_med-Lingual_part 220 180 140 0 +4119 wm-rh-G_occipit-temp_med-Parahippocampal_part 65 100 20 0 +4120 wm-rh-G_orbital 220 60 20 0 +4121 wm-rh-G_paracentral 60 100 60 0 +4122 wm-rh-G_parietal_inferior-Angular_part 20 60 220 0 +4123 wm-rh-G_parietal_inferior-Supramarginal_part 100 100 60 0 +4124 wm-rh-G_parietal_superior 220 180 220 0 +4125 wm-rh-G_postcentral 20 180 140 0 +4126 wm-rh-G_precentral 60 140 180 0 +4127 wm-rh-G_precuneus 25 20 140 0 +4128 wm-rh-G_rectus 20 60 100 0 +4129 wm-rh-G_subcallosal 60 220 20 0 +4130 wm-rh-G_subcentral 60 20 220 0 +4131 wm-rh-G_temporal_inferior 220 220 100 0 +4132 wm-rh-G_temporal_middle 180 60 60 0 +4133 wm-rh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 0 +4134 wm-rh-G_temp_sup-Lateral_aspect 220 60 220 0 +4135 wm-rh-G_temp_sup-Planum_polare 65 220 60 0 +4136 wm-rh-G_temp_sup-Planum_tempolare 25 140 20 0 +4137 wm-rh-G_and_S_transverse_frontopolar 13 0 250 0 +4138 wm-rh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 0 +4139 wm-rh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 0 +4140 wm-rh-Lat_Fissure-post_sgt 61 60 100 0 +4141 wm-rh-Medial_wall 25 25 25 0 +4142 wm-rh-Pole_occipital 140 20 60 0 +4143 wm-rh-Pole_temporal 220 180 20 0 +4144 wm-rh-S_calcarine 63 180 180 0 +4145 wm-rh-S_central 221 20 10 0 +4146 wm-rh-S_central_insula 21 220 20 0 +4147 wm-rh-S_cingulate-Main_part_and_Intracingulate 183 100 20 0 +4148 wm-rh-S_cingulate-Marginalis_part 221 20 100 0 +4149 wm-rh-S_circular_insula_anterior 221 60 140 0 +4150 wm-rh-S_circular_insula_inferior 221 20 220 0 +4151 wm-rh-S_circular_insula_superior 61 220 220 0 +4152 wm-rh-S_collateral_transverse_ant 100 200 200 0 +4153 wm-rh-S_collateral_transverse_post 10 200 200 0 +4154 wm-rh-S_frontal_inferior 221 220 20 0 +4155 wm-rh-S_frontal_middle 141 20 100 0 +4156 wm-rh-S_frontal_superior 61 220 100 0 +4157 wm-rh-S_frontomarginal 21 220 60 0 +4158 wm-rh-S_intermedius_primus-Jensen 141 60 20 0 +4159 wm-rh-S_intraparietal-and_Parietal_transverse 143 20 220 0 +4160 wm-rh-S_occipital_anterior 61 20 180 0 +4161 wm-rh-S_occipital_middle_and_Lunatus 101 60 220 0 +4162 wm-rh-S_occipital_superior_and_transversalis 21 20 140 0 +4163 wm-rh-S_occipito-temporal_lateral 221 140 20 0 +4164 wm-rh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 0 +4165 wm-rh-S_orbital-H_shapped 101 20 20 0 +4166 wm-rh-S_orbital_lateral 221 100 20 0 +4167 wm-rh-S_orbital_medial-Or_olfactory 181 200 20 0 +4168 wm-rh-S_paracentral 21 180 140 0 +4169 wm-rh-S_parieto_occipital 101 100 180 0 +4170 wm-rh-S_pericallosal 181 220 20 0 +4171 wm-rh-S_postcentral 21 140 200 0 +4172 wm-rh-S_precentral-Inferior-part 21 20 240 0 +4173 wm-rh-S_precentral-Superior-part 21 20 200 0 +4174 wm-rh-S_subcentral_ant 61 180 60 0 +4175 wm-rh-S_subcentral_post 61 180 250 0 +4176 wm-rh-S_suborbital 21 20 60 0 +4177 wm-rh-S_subparietal 101 60 60 0 +4178 wm-rh-S_supracingulate 21 220 220 0 +4179 wm-rh-S_temporal_inferior 21 180 180 0 +4180 wm-rh-S_temporal_superior 223 220 60 0 +4181 wm-rh-S_temporal_transverse 221 60 60 0 +5001 Left-UnsegmentedWhiteMatter 20 30 40 0 +5002 Right-UnsegmentedWhiteMatter 20 30 40 0 +5100 fmajor 204 102 102 0 +5101 fminor 204 102 102 0 +5102 lh.atr 255 255 102 0 +5103 lh.cab 153 204 0 0 +5104 lh.ccg 0 153 153 0 +5105 lh.cst 204 153 255 0 +5106 lh.ilf 255 153 51 0 +5107 lh.slfp 204 204 204 0 +5108 lh.slft 153 255 255 0 +5109 lh.unc 102 153 255 0 +5110 rh.atr 255 255 102 0 +5111 rh.cab 153 204 0 0 +5112 rh.ccg 0 153 153 0 +5113 rh.cst 204 153 255 0 +5114 rh.ilf 255 153 51 0 +5115 rh.slfp 204 204 204 0 +5116 rh.slft 153 255 255 0 +5117 rh.unc 102 153 255 0 +5200 CC-ForcepsMajor 204 102 102 0 +5201 CC-ForcepsMinor 204 102 102 0 +5202 LAntThalRadiation 255 255 102 0 +5203 LCingulumAngBundle 153 204 0 0 +5204 LCingulumCingGyrus 0 153 153 0 +5205 LCorticospinalTract 204 153 255 0 +5206 LInfLongFas 255 153 51 0 +5207 LSupLongFasParietal 204 204 204 0 +5208 LSupLongFasTemporal 153 255 255 0 +5209 LUncinateFas 102 153 255 0 +5210 RAntThalRadiation 255 255 102 0 +5211 RCingulumAngBundle 153 204 0 0 +5212 RCingulumCingGyrus 0 153 153 0 +5213 RCorticospinalTract 204 153 255 0 +5214 RInfLongFas 255 153 51 0 +5215 RSupLongFasParietal 204 204 204 0 +5216 RSupLongFasTemporal 153 255 255 0 +5217 RUncinateFas 102 153 255 0 +6000 CST-orig 0 255 0 0 +6001 CST-hammer 255 255 0 0 +6002 CST-CVS 0 255 255 0 +6003 CST-flirt 0 0 255 0 +6010 Left-SLF1 236 16 231 0 +6020 Right-SLF1 237 18 232 0 +6030 Left-SLF3 236 13 227 0 +6040 Right-SLF3 236 17 228 0 +6050 Left-CST 1 255 1 0 +6060 Right-CST 2 255 1 0 +6070 Left-SLF2 236 14 230 0 +6080 Right-SLF2 237 14 230 0 +7001 Lateral-nucleus 72 132 181 0 +7002 Basolateral-nucleus 243 243 243 0 +7003 Basal-nucleus 207 63 79 0 +7004 Centromedial-nucleus 121 20 135 0 +7005 Central-nucleus 197 60 248 0 +7006 Medial-nucleus 2 149 2 0 +7007 Cortical-nucleus 221 249 166 0 +7008 Accessory-Basal-nucleus 232 146 35 0 +7009 Corticoamygdaloid-transitio 20 60 120 0 +7010 Anterior-amygdaloid-area-AAA 250 250 0 0 +7011 Fusion-amygdala-HP-FAH 122 187 222 0 +7012 Hippocampal-amygdala-transition-HATA 237 12 177 0 +7013 Endopiriform-nucleus 10 49 255 0 +7014 Lateral-nucleus-olfactory-tract 205 184 144 0 +7015 Paralaminar-nucleus 45 205 165 0 +7016 Intercalated-nucleus 117 160 175 0 +7017 Prepiriform-cortex 221 217 21 0 +7018 Periamygdaloid-cortex 20 60 120 0 +7019 Envelope-Amygdala 141 21 100 0 +7020 Extranuclear-Amydala 225 140 141 0 +7100 Brainstem-inferior-colliculus 42 201 168 0 +7101 Brainstem-cochlear-nucleus 168 104 162 0 +8001 Thalamus-Anterior 74 130 181 0 +8002 Thalamus-Ventral-anterior 242 241 240 0 +8003 Thalamus-Lateral-dorsal 206 65 78 0 +8004 Thalamus-Lateral-posterior 120 21 133 0 +8005 Thalamus-Ventral-lateral 195 61 246 0 +8006 Thalamus-Ventral-posterior-medial 3 147 6 0 +8007 Thalamus-Ventral-posterior-lateral 220 251 163 0 +8008 Thalamus-intralaminar 232 146 33 0 +8009 Thalamus-centromedian 4 114 14 0 +8010 Thalamus-mediodorsal 121 184 220 0 +8011 Thalamus-medial 235 11 175 0 +8012 Thalamus-pulvinar 12 46 250 0 +8013 Thalamus-lateral-geniculate 203 182 143 0 +8014 Thalamus-medial-geniculate 42 204 167 0 +9000 ctx-lh-prefrontal 50 100 30 0 +9001 ctx-lh-primary-motor 30 100 45 0 +9002 ctx-lh-premotor 130 100 165 0 +9003 ctx-lh-temporal 105 25 5 0 +9004 ctx-lh-posterior-parietal 125 70 55 0 +9005 ctx-lh-prim-sec-somatosensory 225 20 105 0 +9006 ctx-lh-occipital 225 20 15 0 +9500 ctx-rh-prefrontal 50 200 30 0 +9501 ctx-rh-primary-motor 30 150 45 0 +9502 ctx-rh-premotor 130 150 165 0 +9503 ctx-rh-temporal 105 75 5 0 +9504 ctx-rh-posterior-parietal 125 120 55 0 +9505 ctx-rh-prim-sec-somatosensory 225 70 105 0 +9506 ctx-rh-occipital 225 70 15 0 +11100 ctx_lh_Unknown 0 0 0 0 +11101 ctx_lh_G_and_S_frontomargin 23 220 60 0 +11102 ctx_lh_G_and_S_occipital_inf 23 60 180 0 +11103 ctx_lh_G_and_S_paracentral 63 100 60 0 +11104 ctx_lh_G_and_S_subcentral 63 20 220 0 +11105 ctx_lh_G_and_S_transv_frontopol 13 0 250 0 +11106 ctx_lh_G_and_S_cingul-Ant 26 60 0 0 +11107 ctx_lh_G_and_S_cingul-Mid-Ant 26 60 75 0 +11108 ctx_lh_G_and_S_cingul-Mid-Post 26 60 150 0 +11109 ctx_lh_G_cingul-Post-dorsal 25 60 250 0 +11110 ctx_lh_G_cingul-Post-ventral 60 25 25 0 +11111 ctx_lh_G_cuneus 180 20 20 0 +11112 ctx_lh_G_front_inf-Opercular 220 20 100 0 +11113 ctx_lh_G_front_inf-Orbital 140 60 60 0 +11114 ctx_lh_G_front_inf-Triangul 180 220 140 0 +11115 ctx_lh_G_front_middle 140 100 180 0 +11116 ctx_lh_G_front_sup 180 20 140 0 +11117 ctx_lh_G_Ins_lg_and_S_cent_ins 23 10 10 0 +11118 ctx_lh_G_insular_short 225 140 140 0 +11119 ctx_lh_G_occipital_middle 180 60 180 0 +11120 ctx_lh_G_occipital_sup 20 220 60 0 +11121 ctx_lh_G_oc-temp_lat-fusifor 60 20 140 0 +11122 ctx_lh_G_oc-temp_med-Lingual 220 180 140 0 +11123 ctx_lh_G_oc-temp_med-Parahip 65 100 20 0 +11124 ctx_lh_G_orbital 220 60 20 0 +11125 ctx_lh_G_pariet_inf-Angular 20 60 220 0 +11126 ctx_lh_G_pariet_inf-Supramar 100 100 60 0 +11127 ctx_lh_G_parietal_sup 220 180 220 0 +11128 ctx_lh_G_postcentral 20 180 140 0 +11129 ctx_lh_G_precentral 60 140 180 0 +11130 ctx_lh_G_precuneus 25 20 140 0 +11131 ctx_lh_G_rectus 20 60 100 0 +11132 ctx_lh_G_subcallosal 60 220 20 0 +11133 ctx_lh_G_temp_sup-G_T_transv 60 60 220 0 +11134 ctx_lh_G_temp_sup-Lateral 220 60 220 0 +11135 ctx_lh_G_temp_sup-Plan_polar 65 220 60 0 +11136 ctx_lh_G_temp_sup-Plan_tempo 25 140 20 0 +11137 ctx_lh_G_temporal_inf 220 220 100 0 +11138 ctx_lh_G_temporal_middle 180 60 60 0 +11139 ctx_lh_Lat_Fis-ant-Horizont 61 20 220 0 +11140 ctx_lh_Lat_Fis-ant-Vertical 61 20 60 0 +11141 ctx_lh_Lat_Fis-post 61 60 100 0 +11142 ctx_lh_Medial_wall 25 25 25 0 +11143 ctx_lh_Pole_occipital 140 20 60 0 +11144 ctx_lh_Pole_temporal 220 180 20 0 +11145 ctx_lh_S_calcarine 63 180 180 0 +11146 ctx_lh_S_central 221 20 10 0 +11147 ctx_lh_S_cingul-Marginalis 221 20 100 0 +11148 ctx_lh_S_circular_insula_ant 221 60 140 0 +11149 ctx_lh_S_circular_insula_inf 221 20 220 0 +11150 ctx_lh_S_circular_insula_sup 61 220 220 0 +11151 ctx_lh_S_collat_transv_ant 100 200 200 0 +11152 ctx_lh_S_collat_transv_post 10 200 200 0 +11153 ctx_lh_S_front_inf 221 220 20 0 +11154 ctx_lh_S_front_middle 141 20 100 0 +11155 ctx_lh_S_front_sup 61 220 100 0 +11156 ctx_lh_S_interm_prim-Jensen 141 60 20 0 +11157 ctx_lh_S_intrapariet_and_P_trans 143 20 220 0 +11158 ctx_lh_S_oc_middle_and_Lunatus 101 60 220 0 +11159 ctx_lh_S_oc_sup_and_transversal 21 20 140 0 +11160 ctx_lh_S_occipital_ant 61 20 180 0 +11161 ctx_lh_S_oc-temp_lat 221 140 20 0 +11162 ctx_lh_S_oc-temp_med_and_Lingual 141 100 220 0 +11163 ctx_lh_S_orbital_lateral 221 100 20 0 +11164 ctx_lh_S_orbital_med-olfact 181 200 20 0 +11165 ctx_lh_S_orbital-H_Shaped 101 20 20 0 +11166 ctx_lh_S_parieto_occipital 101 100 180 0 +11167 ctx_lh_S_pericallosal 181 220 20 0 +11168 ctx_lh_S_postcentral 21 140 200 0 +11169 ctx_lh_S_precentral-inf-part 21 20 240 0 +11170 ctx_lh_S_precentral-sup-part 21 20 200 0 +11171 ctx_lh_S_suborbital 21 20 60 0 +11172 ctx_lh_S_subparietal 101 60 60 0 +11173 ctx_lh_S_temporal_inf 21 180 180 0 +11174 ctx_lh_S_temporal_sup 223 220 60 0 +11175 ctx_lh_S_temporal_transverse 221 60 60 0 +12100 ctx_rh_Unknown 0 0 0 0 +12101 ctx_rh_G_and_S_frontomargin 23 220 60 0 +12102 ctx_rh_G_and_S_occipital_inf 23 60 180 0 +12103 ctx_rh_G_and_S_paracentral 63 100 60 0 +12104 ctx_rh_G_and_S_subcentral 63 20 220 0 +12105 ctx_rh_G_and_S_transv_frontopol 13 0 250 0 +12106 ctx_rh_G_and_S_cingul-Ant 26 60 0 0 +12107 ctx_rh_G_and_S_cingul-Mid-Ant 26 60 75 0 +12108 ctx_rh_G_and_S_cingul-Mid-Post 26 60 150 0 +12109 ctx_rh_G_cingul-Post-dorsal 25 60 250 0 +12110 ctx_rh_G_cingul-Post-ventral 60 25 25 0 +12111 ctx_rh_G_cuneus 180 20 20 0 +12112 ctx_rh_G_front_inf-Opercular 220 20 100 0 +12113 ctx_rh_G_front_inf-Orbital 140 60 60 0 +12114 ctx_rh_G_front_inf-Triangul 180 220 140 0 +12115 ctx_rh_G_front_middle 140 100 180 0 +12116 ctx_rh_G_front_sup 180 20 140 0 +12117 ctx_rh_G_Ins_lg_and_S_cent_ins 23 10 10 0 +12118 ctx_rh_G_insular_short 225 140 140 0 +12119 ctx_rh_G_occipital_middle 180 60 180 0 +12120 ctx_rh_G_occipital_sup 20 220 60 0 +12121 ctx_rh_G_oc-temp_lat-fusifor 60 20 140 0 +12122 ctx_rh_G_oc-temp_med-Lingual 220 180 140 0 +12123 ctx_rh_G_oc-temp_med-Parahip 65 100 20 0 +12124 ctx_rh_G_orbital 220 60 20 0 +12125 ctx_rh_G_pariet_inf-Angular 20 60 220 0 +12126 ctx_rh_G_pariet_inf-Supramar 100 100 60 0 +12127 ctx_rh_G_parietal_sup 220 180 220 0 +12128 ctx_rh_G_postcentral 20 180 140 0 +12129 ctx_rh_G_precentral 60 140 180 0 +12130 ctx_rh_G_precuneus 25 20 140 0 +12131 ctx_rh_G_rectus 20 60 100 0 +12132 ctx_rh_G_subcallosal 60 220 20 0 +12133 ctx_rh_G_temp_sup-G_T_transv 60 60 220 0 +12134 ctx_rh_G_temp_sup-Lateral 220 60 220 0 +12135 ctx_rh_G_temp_sup-Plan_polar 65 220 60 0 +12136 ctx_rh_G_temp_sup-Plan_tempo 25 140 20 0 +12137 ctx_rh_G_temporal_inf 220 220 100 0 +12138 ctx_rh_G_temporal_middle 180 60 60 0 +12139 ctx_rh_Lat_Fis-ant-Horizont 61 20 220 0 +12140 ctx_rh_Lat_Fis-ant-Vertical 61 20 60 0 +12141 ctx_rh_Lat_Fis-post 61 60 100 0 +12142 ctx_rh_Medial_wall 25 25 25 0 +12143 ctx_rh_Pole_occipital 140 20 60 0 +12144 ctx_rh_Pole_temporal 220 180 20 0 +12145 ctx_rh_S_calcarine 63 180 180 0 +12146 ctx_rh_S_central 221 20 10 0 +12147 ctx_rh_S_cingul-Marginalis 221 20 100 0 +12148 ctx_rh_S_circular_insula_ant 221 60 140 0 +12149 ctx_rh_S_circular_insula_inf 221 20 220 0 +12150 ctx_rh_S_circular_insula_sup 61 220 220 0 +12151 ctx_rh_S_collat_transv_ant 100 200 200 0 +12152 ctx_rh_S_collat_transv_post 10 200 200 0 +12153 ctx_rh_S_front_inf 221 220 20 0 +12154 ctx_rh_S_front_middle 141 20 100 0 +12155 ctx_rh_S_front_sup 61 220 100 0 +12156 ctx_rh_S_interm_prim-Jensen 141 60 20 0 +12157 ctx_rh_S_intrapariet_and_P_trans 143 20 220 0 +12158 ctx_rh_S_oc_middle_and_Lunatus 101 60 220 0 +12159 ctx_rh_S_oc_sup_and_transversal 21 20 140 0 +12160 ctx_rh_S_occipital_ant 61 20 180 0 +12161 ctx_rh_S_oc-temp_lat 221 140 20 0 +12162 ctx_rh_S_oc-temp_med_and_Lingual 141 100 220 0 +12163 ctx_rh_S_orbital_lateral 221 100 20 0 +12164 ctx_rh_S_orbital_med-olfact 181 200 20 0 +12165 ctx_rh_S_orbital-H_Shaped 101 20 20 0 +12166 ctx_rh_S_parieto_occipital 101 100 180 0 +12167 ctx_rh_S_pericallosal 181 220 20 0 +12168 ctx_rh_S_postcentral 21 140 200 0 +12169 ctx_rh_S_precentral-inf-part 21 20 240 0 +12170 ctx_rh_S_precentral-sup-part 21 20 200 0 +12171 ctx_rh_S_suborbital 21 20 60 0 +12172 ctx_rh_S_subparietal 101 60 60 0 +12173 ctx_rh_S_temporal_inf 21 180 180 0 +12174 ctx_rh_S_temporal_sup 223 220 60 0 +12175 ctx_rh_S_temporal_transverse 221 60 60 0 +13100 wm_lh_Unknown 0 0 0 0 +13101 wm_lh_G_and_S_frontomargin 23 220 60 0 +13102 wm_lh_G_and_S_occipital_inf 23 60 180 0 +13103 wm_lh_G_and_S_paracentral 63 100 60 0 +13104 wm_lh_G_and_S_subcentral 63 20 220 0 +13105 wm_lh_G_and_S_transv_frontopol 13 0 250 0 +13106 wm_lh_G_and_S_cingul-Ant 26 60 0 0 +13107 wm_lh_G_and_S_cingul-Mid-Ant 26 60 75 0 +13108 wm_lh_G_and_S_cingul-Mid-Post 26 60 150 0 +13109 wm_lh_G_cingul-Post-dorsal 25 60 250 0 +13110 wm_lh_G_cingul-Post-ventral 60 25 25 0 +13111 wm_lh_G_cuneus 180 20 20 0 +13112 wm_lh_G_front_inf-Opercular 220 20 100 0 +13113 wm_lh_G_front_inf-Orbital 140 60 60 0 +13114 wm_lh_G_front_inf-Triangul 180 220 140 0 +13115 wm_lh_G_front_middle 140 100 180 0 +13116 wm_lh_G_front_sup 180 20 140 0 +13117 wm_lh_G_Ins_lg_and_S_cent_ins 23 10 10 0 +13118 wm_lh_G_insular_short 225 140 140 0 +13119 wm_lh_G_occipital_middle 180 60 180 0 +13120 wm_lh_G_occipital_sup 20 220 60 0 +13121 wm_lh_G_oc-temp_lat-fusifor 60 20 140 0 +13122 wm_lh_G_oc-temp_med-Lingual 220 180 140 0 +13123 wm_lh_G_oc-temp_med-Parahip 65 100 20 0 +13124 wm_lh_G_orbital 220 60 20 0 +13125 wm_lh_G_pariet_inf-Angular 20 60 220 0 +13126 wm_lh_G_pariet_inf-Supramar 100 100 60 0 +13127 wm_lh_G_parietal_sup 220 180 220 0 +13128 wm_lh_G_postcentral 20 180 140 0 +13129 wm_lh_G_precentral 60 140 180 0 +13130 wm_lh_G_precuneus 25 20 140 0 +13131 wm_lh_G_rectus 20 60 100 0 +13132 wm_lh_G_subcallosal 60 220 20 0 +13133 wm_lh_G_temp_sup-G_T_transv 60 60 220 0 +13134 wm_lh_G_temp_sup-Lateral 220 60 220 0 +13135 wm_lh_G_temp_sup-Plan_polar 65 220 60 0 +13136 wm_lh_G_temp_sup-Plan_tempo 25 140 20 0 +13137 wm_lh_G_temporal_inf 220 220 100 0 +13138 wm_lh_G_temporal_middle 180 60 60 0 +13139 wm_lh_Lat_Fis-ant-Horizont 61 20 220 0 +13140 wm_lh_Lat_Fis-ant-Vertical 61 20 60 0 +13141 wm_lh_Lat_Fis-post 61 60 100 0 +13142 wm_lh_Medial_wall 25 25 25 0 +13143 wm_lh_Pole_occipital 140 20 60 0 +13144 wm_lh_Pole_temporal 220 180 20 0 +13145 wm_lh_S_calcarine 63 180 180 0 +13146 wm_lh_S_central 221 20 10 0 +13147 wm_lh_S_cingul-Marginalis 221 20 100 0 +13148 wm_lh_S_circular_insula_ant 221 60 140 0 +13149 wm_lh_S_circular_insula_inf 221 20 220 0 +13150 wm_lh_S_circular_insula_sup 61 220 220 0 +13151 wm_lh_S_collat_transv_ant 100 200 200 0 +13152 wm_lh_S_collat_transv_post 10 200 200 0 +13153 wm_lh_S_front_inf 221 220 20 0 +13154 wm_lh_S_front_middle 141 20 100 0 +13155 wm_lh_S_front_sup 61 220 100 0 +13156 wm_lh_S_interm_prim-Jensen 141 60 20 0 +13157 wm_lh_S_intrapariet_and_P_trans 143 20 220 0 +13158 wm_lh_S_oc_middle_and_Lunatus 101 60 220 0 +13159 wm_lh_S_oc_sup_and_transversal 21 20 140 0 +13160 wm_lh_S_occipital_ant 61 20 180 0 +13161 wm_lh_S_oc-temp_lat 221 140 20 0 +13162 wm_lh_S_oc-temp_med_and_Lingual 141 100 220 0 +13163 wm_lh_S_orbital_lateral 221 100 20 0 +13164 wm_lh_S_orbital_med-olfact 181 200 20 0 +13165 wm_lh_S_orbital-H_Shaped 101 20 20 0 +13166 wm_lh_S_parieto_occipital 101 100 180 0 +13167 wm_lh_S_pericallosal 181 220 20 0 +13168 wm_lh_S_postcentral 21 140 200 0 +13169 wm_lh_S_precentral-inf-part 21 20 240 0 +13170 wm_lh_S_precentral-sup-part 21 20 200 0 +13171 wm_lh_S_suborbital 21 20 60 0 +13172 wm_lh_S_subparietal 101 60 60 0 +13173 wm_lh_S_temporal_inf 21 180 180 0 +13174 wm_lh_S_temporal_sup 223 220 60 0 +13175 wm_lh_S_temporal_transverse 221 60 60 0 +14100 wm_rh_Unknown 0 0 0 0 +14101 wm_rh_G_and_S_frontomargin 23 220 60 0 +14102 wm_rh_G_and_S_occipital_inf 23 60 180 0 +14103 wm_rh_G_and_S_paracentral 63 100 60 0 +14104 wm_rh_G_and_S_subcentral 63 20 220 0 +14105 wm_rh_G_and_S_transv_frontopol 13 0 250 0 +14106 wm_rh_G_and_S_cingul-Ant 26 60 0 0 +14107 wm_rh_G_and_S_cingul-Mid-Ant 26 60 75 0 +14108 wm_rh_G_and_S_cingul-Mid-Post 26 60 150 0 +14109 wm_rh_G_cingul-Post-dorsal 25 60 250 0 +14110 wm_rh_G_cingul-Post-ventral 60 25 25 0 +14111 wm_rh_G_cuneus 180 20 20 0 +14112 wm_rh_G_front_inf-Opercular 220 20 100 0 +14113 wm_rh_G_front_inf-Orbital 140 60 60 0 +14114 wm_rh_G_front_inf-Triangul 180 220 140 0 +14115 wm_rh_G_front_middle 140 100 180 0 +14116 wm_rh_G_front_sup 180 20 140 0 +14117 wm_rh_G_Ins_lg_and_S_cent_ins 23 10 10 0 +14118 wm_rh_G_insular_short 225 140 140 0 +14119 wm_rh_G_occipital_middle 180 60 180 0 +14120 wm_rh_G_occipital_sup 20 220 60 0 +14121 wm_rh_G_oc-temp_lat-fusifor 60 20 140 0 +14122 wm_rh_G_oc-temp_med-Lingual 220 180 140 0 +14123 wm_rh_G_oc-temp_med-Parahip 65 100 20 0 +14124 wm_rh_G_orbital 220 60 20 0 +14125 wm_rh_G_pariet_inf-Angular 20 60 220 0 +14126 wm_rh_G_pariet_inf-Supramar 100 100 60 0 +14127 wm_rh_G_parietal_sup 220 180 220 0 +14128 wm_rh_G_postcentral 20 180 140 0 +14129 wm_rh_G_precentral 60 140 180 0 +14130 wm_rh_G_precuneus 25 20 140 0 +14131 wm_rh_G_rectus 20 60 100 0 +14132 wm_rh_G_subcallosal 60 220 20 0 +14133 wm_rh_G_temp_sup-G_T_transv 60 60 220 0 +14134 wm_rh_G_temp_sup-Lateral 220 60 220 0 +14135 wm_rh_G_temp_sup-Plan_polar 65 220 60 0 +14136 wm_rh_G_temp_sup-Plan_tempo 25 140 20 0 +14137 wm_rh_G_temporal_inf 220 220 100 0 +14138 wm_rh_G_temporal_middle 180 60 60 0 +14139 wm_rh_Lat_Fis-ant-Horizont 61 20 220 0 +14140 wm_rh_Lat_Fis-ant-Vertical 61 20 60 0 +14141 wm_rh_Lat_Fis-post 61 60 100 0 +14142 wm_rh_Medial_wall 25 25 25 0 +14143 wm_rh_Pole_occipital 140 20 60 0 +14144 wm_rh_Pole_temporal 220 180 20 0 +14145 wm_rh_S_calcarine 63 180 180 0 +14146 wm_rh_S_central 221 20 10 0 +14147 wm_rh_S_cingul-Marginalis 221 20 100 0 +14148 wm_rh_S_circular_insula_ant 221 60 140 0 +14149 wm_rh_S_circular_insula_inf 221 20 220 0 +14150 wm_rh_S_circular_insula_sup 61 220 220 0 +14151 wm_rh_S_collat_transv_ant 100 200 200 0 +14152 wm_rh_S_collat_transv_post 10 200 200 0 +14153 wm_rh_S_front_inf 221 220 20 0 +14154 wm_rh_S_front_middle 141 20 100 0 +14155 wm_rh_S_front_sup 61 220 100 0 +14156 wm_rh_S_interm_prim-Jensen 141 60 20 0 +14157 wm_rh_S_intrapariet_and_P_trans 143 20 220 0 +14158 wm_rh_S_oc_middle_and_Lunatus 101 60 220 0 +14159 wm_rh_S_oc_sup_and_transversal 21 20 140 0 +14160 wm_rh_S_occipital_ant 61 20 180 0 +14161 wm_rh_S_oc-temp_lat 221 140 20 0 +14162 wm_rh_S_oc-temp_med_and_Lingual 141 100 220 0 +14163 wm_rh_S_orbital_lateral 221 100 20 0 +14164 wm_rh_S_orbital_med-olfact 181 200 20 0 +14165 wm_rh_S_orbital-H_Shaped 101 20 20 0 +14166 wm_rh_S_parieto_occipital 101 100 180 0 +14167 wm_rh_S_pericallosal 181 220 20 0 +14168 wm_rh_S_postcentral 21 140 200 0 +14169 wm_rh_S_precentral-inf-part 21 20 240 0 +14170 wm_rh_S_precentral-sup-part 21 20 200 0 +14171 wm_rh_S_suborbital 21 20 60 0 +14172 wm_rh_S_subparietal 101 60 60 0 +14173 wm_rh_S_temporal_inf 21 180 180 0 +14174 wm_rh_S_temporal_sup 223 220 60 0 +14175 wm_rh_S_temporal_transverse 221 60 60 0 +1701 ctx_lh_AnteroHippocampus 0 0 0 0 +1702 ctx_lh_PosteroHippocampus 0 0 0 0 +5301 ctx_rh_AnteroHippocampus 0 0 0 0 +5302 ctx_rh_PosteroHippocampus 0 0 0 0 diff --git a/generate_boundaries.py b/generate_boundaries.py new file mode 100644 index 0000000..10d869e --- /dev/null +++ b/generate_boundaries.py @@ -0,0 +1,12 @@ +from soma import aims +import pdb + +mesh_filename = '/home/b67-belledone/Desktop/epilepsie-manik/MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/inflatedGre_2016_MNI1_Lwhite.gii' +regions_texture_filename = '/home/b67-belledone/Desktop/epilepsie-manik/MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/surface_analysis/Gre_2016_MNI1_Lwhite_parcels_marsAtlas.gii' +boundaries_filename = '/tmp/inflated_marsatlas_boundariesL.mesh' + +mesh = aims.read(mesh_filename) +regions_texture = aims.read(regions_texture_filename) +boundaries = aims.SurfaceManip.meshTextureBoundary(mesh, regions_texture, -1) +boundaries.header()['material'] = { 'diffuse': [1., 0., 0., 1.], 'line_width': 6} +aims.write(boundaries, boundaries_filename) \ No newline at end of file diff --git a/generate_contact_colors.py b/generate_contact_colors.py new file mode 100644 index 0000000..350cb44 --- /dev/null +++ b/generate_contact_colors.py @@ -0,0 +1,97 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import openpyxl, json, os +import pdb +import difflib #to get closest match + + + +class generate_contact_colors: + """to present results of cognition/stimulation""" + + def __init__(self): + + self.output = {} + + def from_excel_files(self,filename,save=False): + + excel_data = openpyxl.load_workbook(filename) + + worksheet_names = excel_data.get_sheet_names() + + output_info = {worksheet_names[x]:{} for x in range(len(worksheet_names))} + + #pour les fréquences + freq_possible = ['1 Hz', '50 Hz'] + amplitude_possible = [] + + for worksheet_index in worksheet_names: + datasheeti = excel_data[worksheet_index] + + #always assume first line is "title condition" and first column is "contact or bipole" as written in the IntrAnat Electrodes software + title_condi={} + contact_labels = {} + for i_row in range(1,datasheeti.max_row+1): + skip_this_line = 0 + for i_column in range(1,datasheeti.max_column+1): + + + #print(i_row,i_column) + actual_cell = datasheeti.cell(row=i_row, column = i_column) + backcolor = actual_cell.fill.start_color.index + fontcolor = actual_cell.font.color.rgb + if i_row == 1: + title_condi.update({actual_cell.value:{}}) + title_condi[actual_cell.value].update({'title_backcolor':self.hexa2irgbtupple(backcolor),'title_fontcolor':self.hexa2irgbtupple(fontcolor)}) + else: + second_label = datasheeti.cell(row=i_row, column = 2) + if i_column == 1: + if actual_cell.value not in contact_labels.keys(): + contact_labels.update({actual_cell.value:{'cell':{},'line':{'backcolor':self.hexa2irgbtupple(backcolor),'fontcolor':self.hexa2irgbtupple(fontcolor)}}}) #second_label.value:{} + else: + #find row and column title + row_title_cell = datasheeti.cell(row = i_row, column = 1) + column_title_cell = datasheeti.cell(row = 1, column = i_column) + row_title = row_title_cell.value + column_title = column_title_cell.value + + if i_column == 2: + if actual_cell.value in contact_labels[row_title]['cell'].keys(): + if 'Type of response' in contact_labels[row_title]['cell'][actual_cell.value].keys(): + #bipole already stimulated with this "frequency/task", data overwrite only if there was a clinical response + #should check the mA ? + if (contact_labels[row_title]['cell'][actual_cell.value]['Type of response']['value'] != u'Absent') and (contact_labels[row_title]['cell'][actual_cell.value]['Type of response'] != 0): + skip_this_line = 1 + continue + else: + contact_labels[row_title]['cell'][actual_cell.value].update({}) + else: + pdb.set_trace() + else: + contact_labels[row_title]['cell'].update({actual_cell.value:{}}) + #[second_label.value].update({column_title:{'value':actual_cell.value,'backcolor':self.hexa2irgbtupple(backcolor),'fontcolor':self.hexa2irgbtupple(fontcolor)}}) + else: + if skip_this_line == 0: + contact_labels[row_title]['cell'][second_label.value].update({column_title:{'value':actual_cell.value,'backcolor':self.hexa2irgbtupple(backcolor),'fontcolor':self.hexa2irgbtupple(fontcolor)}}) + + if save: + path_to_save = os.path.dirname(filename) + filename_wh_ext = os.path.basename(filename).split('.')[0] + new_filename = path_to_save + os.path.sep + filename_wh_ext + '.json' + fout = open(new_filename,'w') + fout.write(json.dumps({'title':title_condi,'contacts':contact_labels})) + fout.close() + + else: + return (title_condi,contact_labels) + + def hexa2irgbtupple(self,string_hexa): + + try: + rgbtupple = (int(string_hexa[0:2],16),int(string_hexa[2:4],16),int(string_hexa[4:6],16),int(string_hexa[6:8],16)) + except: + rgbtupple = (255,0,0,0) #default is black + + return rgbtupple + \ No newline at end of file diff --git a/getTRCpatientData.c b/getTRCpatientData.c new file mode 100644 index 0000000..498835a --- /dev/null +++ b/getTRCpatientData.c @@ -0,0 +1,74 @@ +#include +#include +/** + * ANONYMIZATION Of patient data in Micromed TRC files + * + * (c) Inserm U836 2014 - Manik Bhattacharjee + * + * License GNU GPL v3 +*/ + +/** + From TRC format description "System 98 - Type "4" EEG FILE STRUCTURE DESCRIPTION (Micromed) + Offset of patient data, offset of acquisition date/time +*/ +#define PATIENT_DATA_OFFSET 64 +#define PATIENT_DATA_NAME_SIZE 22 +#define PATIENT_DATA_FIRSTNAME_SIZE 20 +#define PATIENT_BIRTH_DATE_SIZE 3 +#define DATE_OFFSET 128 +#define TIME_OFFSET 131 +#define SPACE_CHAR 32 //Ascii code + +int main(int argc, char **argv){ + int length, remains, i; + char name[PATIENT_DATA_NAME_SIZE +1 ] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + char firstname[PATIENT_DATA_FIRSTNAME_SIZE +1 ] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + unsigned char month, day, year, hours, minutes, seconds; + if (argc != 2){ + printf("Usage : getTRCpatientData file.trc\n"); + return -1; + } + // Opening file read binary mode + FILE *const fp = fopen(argv[1], "rb"); + if (!fp){ + printf("Cannot open TRC file\n"); + return -1; + } + if (fseek(fp, PATIENT_DATA_OFFSET, SEEK_SET) != 0){ + printf("Cannot go to Patient data section in TRC file !\n"); + return -1; + } + // Patient Last name + fread (name, 1, PATIENT_DATA_NAME_SIZE, fp); + + //Patient First name + fread (name, 1, PATIENT_DATA_FIRSTNAME_SIZE, fp); + + //Patient birth date + month = fgetc(fp); + day = fgetc(fp); + year = fgetc(fp); + printf("Subject : %s %s, born %d/%d/%d\n", firstname, name, day, month, year/100 > 0?2000+year%100:1900+year); + + if (fseek(fp, DATE_OFFSET, SEEK_SET) != 0){ + printf("Cannot go to Date data section in TRC file !\n"); + return -1; + } + day = fgetc(fp); + month = fgetc(fp); + year = fgetc(fp); + + if (fseek(fp, TIME_OFFSET, SEEK_SET) != 0){ + printf("Cannot go to Time data section in TRC file !\n"); + return -1; + } + hours = fgetc(fp); + minutes = fgetc(fp); + seconds = fgetc(fp); + + printf("Acquisition : %d/%d/%d %d:%d:%d\n", day, month, year/100 > 0?2000+year%100:1900+year, hours, minutes, seconds); + printf("GRE_%d_%c%c%c%c\n", year/100 > 0?2000+year%100:1900+year, name[0], name[1], name[2], firstname[0]); + + fclose(fp); +} diff --git a/greendot.png b/greendot.png new file mode 100644 index 0000000..733432d Binary files /dev/null and b/greendot.png differ diff --git a/groupDisplay.py b/groupDisplay.py new file mode 100644 index 0000000..b4ef55e --- /dev/null +++ b/groupDisplay.py @@ -0,0 +1,54 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# Application to view multi-subject data +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# +# +from PyQt4 import QtGui, QtCore, uic + +import sys, pdb + + +from brainvisa import axon +from electrodedisplaywidget import ElectrodeDisplayWidget +from templatewidget import TemplateWidget +from patientdatafilterwidget import PatientDataFilterWidget + + +class GroupDisplayWidget(QtGui.QTabWidget): + def __init__(self, app=None): + QtGui.QTabWidget.__init__(self) + # Load patient selection panel + self.patientsPanel = PatientDataFilterWidget() + # Load template panel (choose the common referential - MNI/Dartel custom template...) + self.templatePanel = TemplateWidget() #Create a widget from uic.loadUi("groupPlots.ui", self) + # Load plots panel + self.plotsPanel = ElectrodeDisplayWidget(dataSubjects=self.patientsPanel.subjects) #Create a widget from uic.loadUi("groupPlots.ui", self) + # Add them to the tabwidget itself + self.addTab(self.patientsPanel, u"Subjects") + self.addTab(self.templatePanel, u"Template") + self.addTab(self.plotsPanel, u"Plots") + self.setTabEnabled(1,False) + # Connect tab change event to update the list of patients + self.currentChanged.connect(self.tabSelected) + + def tabSelected(self, id): + if id == 2: + self.plotsPanel.setSubjects(self.patientsPanel.getSelectedPatientsNames(), self.patientsPanel.getSelectedPatients()) + + + + +if __name__ == "__main__": + app = QtGui.QApplication(sys.argv) + axon.initializeProcesses() + from brainvisa.data.readdiskitem import ReadDiskItem + from brainvisa.data.writediskitem import WriteDiskItem + QtCore.pyqtRemoveInputHook() + window = GroupDisplayWidget() + window.show() + sys.exit(app.exec_()) diff --git a/groupDisplay.sh b/groupDisplay.sh new file mode 100644 index 0000000..86f4cab --- /dev/null +++ b/groupDisplay.sh @@ -0,0 +1,8 @@ +#!/bin/bash +cd /home/lnppeeg/software/brainvisa-4.3.0/bin/ +. /home/lnppeeg/software/brainvisa-4.3.0/bin/bv_env.sh +cd /home/lnppeeg/prog/electrophysiology/epilepsie/ +echo "#############################################################################" >> intranat-locateElectrodes-`whoami`.log +date >> intranat-locateElectrodes-`whoami`.log +python groupDisplay.py >> intranat-locateElectrodes-`whoami`.log + diff --git a/groupPlots.ui b/groupPlots.ui new file mode 100644 index 0000000..ea65965 --- /dev/null +++ b/groupPlots.ui @@ -0,0 +1,442 @@ + + + Widget + + + + 0 + 0 + 869 + 862 + + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Patients + + + + + + + + 0 + 0 + + + + QAbstractItemView::MultiSelection + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Electrodes + + + + + + + + 0 + 0 + + + + QAbstractItemView::MultiSelection + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Plots + + + + + + + + 0 + 0 + + + + QAbstractItemView::MultiSelection + + + + + + + Implantation Statistics: + + + + + + Generate Stats with Selection + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + Ajouter les plots choisis à la sélection + + + -> + + + + + + + + 0 + 0 + + + + Supprimer de la sélection + + + <- + + + + + + + MarsAtlas Parcels + + + + + + + + + + FreeSurfer Parcels + + + + + + + + + + Broadmann Parcels + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Selection + + + + + + + + 0 + 0 + + + + QAbstractItemView::MultiSelection + + + + + + + + + Rm Left Plots + + + + + + + Rm Right Plots + + + + + + + + + Remove Plots not in TRC + + + + + + + + + both Hemi + + + true + + + buttonGroupBothOrRightHemi + + + + + + + All contacts to Right + + + buttonGroupBothOrRightHemi + + + + + + + + + + + Contact Display + + + true + + + buttonGroupContactOrsEEG + + + + + + + sEEG Results Display + + + buttonGroupContactOrsEEG + + + + + + + + + Select around the cursor + + + + + + + + + + + + + + + + + radius : + + + + + + + mm + + + 1 + + + 20.000000000000000 + + + + + + + + + + 0 + 0 + + + + Display + + + + + + + 0 + 0 + + + + + + + + Add + + + + + + + Add Image (in MNI) to List + + + + + + + Add mesh/texture (in MNI) to List + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + diff --git a/identity.trm b/identity.trm new file mode 100644 index 0000000..9dc071a --- /dev/null +++ b/identity.trm @@ -0,0 +1,5 @@ +0 0 0 +1 0 0 +0 1 0 +0 0 1 + diff --git a/locateContacts.py b/locateContacts.py new file mode 100644 index 0000000..508d7cd --- /dev/null +++ b/locateContacts.py @@ -0,0 +1,572 @@ +import math +import pdb +from scipy import ndimage +from numpy import * +from soma import aims + + + +def norme3D(vect): + return math.sqrt(vect[0]**2+vect[1]**2+vect[2]**2) + +def vecteur(a,b): + return (b[0]-a[0],b[1]-a[1],b[2]-a[2]) + +def findMoyMax(npCT,sizex,sizey,sizez,volCT,entry,d,s1n,coteRegionX,coteRegionY,coteRegionZ,CT): + #initialization of variables + maxi=0 + inc=0 + if CT==True: + compX1=s1n[0]/sizex-coteRegionX + compX2=s1n[0]/sizex+coteRegionX + compY1=s1n[1]/sizey-coteRegionY + compY2=s1n[1]/sizey+coteRegionY + compZ1=s1n[2]/sizez-coteRegionZ + compZ2=s1n[2]/sizez+coteRegionZ + if compZ1 <=0: + compZ1=0 + if compY1 <=0: + compY1=0 + if compX1 <=0: + compX1=0 + if compX2>= len(npCT[0][0])-1: + compX2= len(npCT[0][0])-1 + if compY2>= len(npCT[0][0])-1: + compY2= len(npCT[0][0])-1 + if compZ2>= len(npCT[0][0])-1: + compZ2= len(npCT[0][0])-1 + else: + compX1=s1n[0]-coteRegionX + compX2=s1n[0]+coteRegionX + compY1=s1n[1]-coteRegionY + compY2=s1n[1]+coteRegionY + compZ1=s1n[2]-coteRegionZ + compZ2=s1n[2]+coteRegionZ + if compZ1 <=0: + compZ1=0 + if compY1 <=0: + compY1=0 + if compX1 <=0: + compX1=0 + if compX2>= len(npCT[0][0])-1: + compX2= len(npCT[0][0])-1 + if compY2>= len(npCT[0][0])-1: + compY2= len(npCT[0][0])-1 + if compZ2>= len(npCT[0][0])-1: + compZ2= len(npCT[0][0])-1 + + print "compX1",compX1,"compX2",compX2,"compY1",compY1,"compY2",compY2,"compZ1",compZ1,"compZ2",compZ2 + + #we will do the computation until we find a value higher than 1500 + while maxi==0 and inc<1000: + #print "compX1",compX1,"compX2",compX2,"compY1",compY1,"compY2",compY2,"compZ1",compZ1,"compZ2",compZ2 + #computation in a CT + if CT==True: + #we take out any values less than 2500 + newnpCT=npCT[0,round(compZ1):round(compZ2),round(compY1):round(compY2),round(compX1):round(compX2)] + newnpCT=newnpCT.clip(1500) + newnpCT[newnpCT==1500]=0 + #We make an opening + CTopened=ndimage.grey_opening(newnpCT, size=(int(round(1.4/sizez)),int(round(1.4/sizey)),int(round(1.4/sizex)))) #en mm ca soit isotropic + newnpCT=npCT[0,round(compZ1):round(compZ2),round(compY1):round(compY2),round(compX1):round(compX2)] + newnpCT=newnpCT.clip(1500) + newnpCT[newnpCT==1500]=0 + else: + #we take out any values above 50 + newnpCT=npCT[0,round(compZ1):round(compZ2),round(compY1):round(compY2),round(compX1):round(compX2)] + newnpCT=newnpCT.clip(0,50) + newnpCT[newnpCT==50]=0 + #We make an opening + CTopened=ndimage.grey_opening(newnpCT, size=(int(round(1.4/sizez)),int(round(1.4/sizey)),int(round(1.4/sizex)))) #en mm ca soit isotropic + newnpCT=npCT[0,round(compZ1):round(compZ2),round(compY1):round(compY2),round(compX1):round(compX2)] + newnpCT=newnpCT.clip(0,100) + newnpCT[newnpCT==100]=0 + try: + maxi=CTopened.max() + except: + pdb.set_trace() + #if the opening was too strong and didn't keep any values but the original array had value>1500 we keep the newnpCT (original one) + if maxi==0 and newnpCT.max()!=0: + CTopened=newnpCT + maxi=newnpCT.max() + #if there is nothing near we open the ROI + if (maxi<2500 and CT==True) or (CT==False and maxi>50 ) or maxi==0: + compX1-=sizex + if compX1<= 0: + compX1= 0 + + compX2+=sizex + if compX2>= len(npCT[0][0][0])-1: + compX2= len(npCT[0][0][0])-1 + + compY1-=sizey + if compY1<= 0: + compY1= 0 + + compY2+=sizey + if compY2>= len(npCT[0][0])-1: + compY2= len(npCT[0][0])-1 + + compZ1-=sizez + if compZ1<= 0: + compZ1= 0 + + compZ2+=sizez + if compZ2>= len(npCT[0])-1: + compZ2= len(npCT[0])-1 + + maxi=0 + + inc+=1 + + #calculation of the center of mass + (lbl,numfeatures)=ndimage.label(CTopened) + centre=ndimage.measurements.center_of_mass(CTopened,lbl,range(1,numfeatures+1)) + #if there is one center + if numfeatures==1: + moy = ndimage.measurements.center_of_mass(CTopened) + #if there are more than 5 centers of mass we put moy to none + elif numfeatures>5: + print "trop de centres de masse" + moy=None + #if there are between 3 and 5 centers of mass we take the 2 bigger ones + elif numfeatures>2 and numfeatures<6: + p=1 + to={} + suppr=[] + #we determine the size of each centers + while p<=lbl.max(): + val=where(lbl==p) + tailleVal={p:len(val[0])} + to.update(tailleVal) + p+=1 + #sort the sizes and only keep the 2 biggest ones + tailles=[x for x in to.values()] + tailles.sort() + del tailles[-2:] + + #then we know wich centers to suppress... + for el in tailles: + for cle, valeur in tailleVal.items(): + if valeur==el: + suppr.append(cle) + #...and suppress them + for el in suppr: + lbl[lbl==el]=0 + #we then compute the centers of mass, since we do not know on wich axis they are, we first try with [0,1], if one of the centers is (nan,nan,nan) we try with [1,2] + centre=ndimage.measurements.center_of_mass(CTopened,lbl,[0,1]) + if isnan(centre[0][0])==True: + centre=ndimage.measurements.center_of_mass(CTopened,lbl,[1,2]) + + #we calculate the coordinates in the CT native space in order to calculate the distance with the first approximation + centre0=(centre[0][2]+compX1*sizex,centre[0][1]+compY1*sizey,centre[0][0]+compZ1*sizez) + centre1=(centre[1][2]+compX1*sizex,centre[1][1]+compY1*sizey,centre[1][0]+compZ1*sizez) + entCentre0=vecteur(entry,centre0) + dist0=norme3D(entCentre0) + entCentre1=vecteur(entry,centre1) + dist1=norme3D(entCentre1) + #we only take the one that is nearest to the point we first approximated + if dist0>dist1: + moy=centre[1] + else: + moy=centre[0] + #here is the case where nothing goes wrong + else: + centre0=(centre[0][2]+compX1*sizex,centre[0][1]+compY1*sizey,centre[0][0]+compZ1*sizez) + centre1=(centre[1][2]+compX1*sizex,centre[1][1]+compY1*sizey,centre[1][0]+compZ1*sizez) + entCentre0=vecteur(entry,centre0) + dist0=norme3D(entCentre0) + entCentre1=vecteur(entry,centre1) + dist1=norme3D(entCentre1) + if dist0>dist1: + moy=centre[1] + else: + moy=centre[0] + #if we have a center we will also calculate its distance with the previous plot + if moy is not None: + moyverif=((moy[2]+compX1)*sizex,(moy[1]+compY1)*sizey,(moy[0]+compZ1)*sizez) + verif=norme3D(vecteur(entry,moyverif)) + emVect=vecteur(entry,moyverif) + #if the plot found is too far we put moy to none + if d!=0 and verif>d*1.3: + moy=None + print "too far" + #this is the case where we approximate the target, we want it at most 2mm far from the theoretical target + elif d==0 and verif>2: + moy=None + print "verif:" ,verif + #if the plot is too close + elif d!=0 and verif0.04 and ite<10000: + #initialization of variables + npCTtempo=None + aa=0 + + #We launch the approximation a first time in order to know if moy is none + if j==0: + moy=findMoyMax(npCT,sizex,sizey,sizez,volCT,entry,d,s1n,coteRegionX,coteRegionY,coteRegionZ,CT) + else: + moy=findMoyMax(npCT,sizex,sizey,sizez,volCT,entry,d,replace,coteRegionX,coteRegionY,coteRegionZ,CT) + + #print "moy",moy + #if moy is none we want to get out of the while + if moy is None: + error=0 + else: + error=abs(norme3D(moyt)-norme3D(moy)) + replace=(moy[2]*sizex,moy[1]*sizey,moy[0]*sizez) + moyt=moy + ite+=1 + j+=1 + #we lauch the approximation of the center of mass once + if moy is None: + if s1n==point: + moy=findMoyMax(npCT,sizex,sizey,sizez,volCT,point,0,s1n,coteRegionX,coteRegionY,coteRegionZ,CT) + else: + moy=findMoyMax(npCT,sizex,sizey,sizez,volCT,point,0.2,s1n,coteRegionX,coteRegionY,coteRegionZ,CT) + #if the computations fail at this point, we will give it the first approximation + if moy is None: + appPointret=s1n + + #transformation of the center of mass found to the CT natif space + else: + appPointret=(moy[2]*sizex,moy[1]*sizey,moy[0]*sizez) + else: + appPointret=(moy[2]*sizex,moy[1]*sizey,moy[0]*sizez) + #print "appPointret: ",appPointret + return appPointret + + +def locateContacts(target,entry,npCT,volCT,nbContacts,sizex,sizey,sizez,do,transfo_pre_to_postopInv,brainMask,sizeT1,dicPoints,serpentin,transfo_pre_to_postop,CT): + #entry et target dans le repere CT natif + #variables' initialization + targetH=target + entryH=entry + contacts={} + i=0 + theta=0 + signex={} + signey={} + signez={} + angles={} + theta=0 + #counts the number of times moy is returned none + compteurMoy=0 + + #Approximation for each contacts, we start at the theoretical target, wich will also be approximated + #it has to be noted that the entry is after the first iteration the current approximated plot, and target the previous one + while i1: + aa=1.0005 + b=0.9994 + enS1=vecteur(entry,s1n) + enS1Norm=norme3D(enS1) + while enS1Norm<(do[i]-0.4) or enS1Norm>(do[i]+0.4): + if enS1Norm1: + prepre=target + target=entry + #print "target 312 : ", target + if i>0: + entry=appPoint + #print "entry 315: ",entry + vect11=vecteur(target,entry) + #Calculation of the angle between the two vectors joining 3 consecutive points, last one being the current approximated point. + if i>1: + try: + theta=math.acos(vdot(vect11,vect12)/(norme3D(vect11)*norme3D(vect12))) + #print theta + #if it can't be done it is often because the vectors are identical, so we instanciate theta to 0 + except: + theta=0 + + + #We store the angles in order to be able to reduce deviations + if i>1: + signex.update({i:((appPoint[0]-target[0])/abs(appPoint[0]-target[0]))}) + signey.update({i:((appPoint[1]-target[1])/abs(appPoint[1]-target[1]))}) + signez.update({i:((appPoint[2]-target[2])/abs(appPoint[2]-target[2]))}) + angle={i:theta} + angles.update(angle) + + #target becomes the approximated one + if i==0: + target=appPoint + #print "target 338: ", target + if i>0: + vect12=vect11 + entry=appPoint + #print "entry 342: ",entry + + #print entry + #Transformation of the found plot to the T1 natif referential + appPointtemp=(appPoint[0],appPoint[1],appPoint[2]) + appPointtemp=list(appPointtemp) + appPointtemp.append(1) + appPointtemp=array(appPointtemp) + appPointT1nat=transfo_pre_to_postopInv.dot(appPointtemp.T) + point=list(appPointT1nat) + del point[-1] + appPointT1nat=tuple(point) + contact={i:appPointT1nat} + contacts.update(contact) + + if serpentin==True: + if i>2: + if (signex[i-1]-signex[i]!=0 or signey[i-1]-signey[i]!=0 or signey[i-1]-signey[i]!=0) and angles[i]>0.05 and angles[i-1]>0.05: + prepreNorm=norme3D(vecteur(prepre,entry)) + coef=do[i-1]/prepreNorm + target=((entry[0]-prepre[0])*coef+prepre[0],(entry[1]-prepre[1])*coef+prepre[1],(entry[2]-prepre[2])*coef+prepre[2]) + #print "target 363 : ", target + appPointtemp=(target[0],target[1],target[2]) + appPointtemp=list(appPointtemp) + appPointtemp.append(1) + appPointtemp=array(appPointtemp) + appPointT1nat=transfo_pre_to_postopInv.dot(appPointtemp.T) + point=list(appPointT1nat) + del point[-1] + appPointT1nat=tuple(point) + contacts[i-1]=appPointT1nat + print "modif 410" + + else: + if appPoint==s1n: + #increases the number of times moy is none + compteurMoy+=1 + if compteurMoy>1: + print "trop de moy=None" + moy=findMoyMax(npCT,sizex,sizey,sizez,volCT,dicPoints[i+1],0.2,dicPoints[i+1],coteRegionX,coteRegionY,coteRegionZ,CT) + if moy is not None: + appPoint=(moy[2]*sizex,moy[1]*sizey,moy[0]*sizez) + print "appPoint: ", appPoint + #print "entry 383: ", entry + else: + appPoint=dicPoints[i+1] + #print "entry 386 :",entry + compteurMoy=0 + #Transformation of the found plot to the T1 natif referential + appPointtemp=(appPoint[0],appPoint[1],appPoint[2]) + appPointtemp=list(appPointtemp) + appPointtemp.append(1) + appPointtemp=array(appPointtemp) + appPointT1nat=transfo_pre_to_postopInv.dot(appPointtemp.T) + point=list(appPointT1nat) + del point[-1] + appPointT1nat=tuple(point) + contacts[i]=appPointT1nat + print "modif 437" + try: + coef1=(do[i-1]+do[i-2])/norme3D(vecteur(contacts[i-3],contacts[i])) + contacts[i-1]=(coef1*(appPointT1nat[0]-contacts[i-3][0])+contacts[i-3][0],coef1*(appPointT1nat[1]-contacts[i-3][1])+contacts[i-3][1],coef1*(appPointT1nat[2]-contacts[i-3][2])+contacts[i-3][2]) + coef2=do[i-2]/norme3D(vecteur(contacts[i-3],contacts[i])) + contacts[i-2]=(coef2*(appPointT1nat[0]-contacts[i-3][0])+contacts[i-3][0],coef2*(appPointT1nat[1]-contacts[i-3][1])+contacts[i-3][1],coef2*(appPointT1nat[2]-contacts[i-3][2])+contacts[i-3][2]) + except: + try: + coef2=do[i-1]/norme3D(vecteur(contacts[i-2],contacts[i])) + contacts[i-1]=(coef2*(appPointT1nat[0]-contacts[i-2][0])+contacts[i-2][0],coef2*(appPointT1nat[1]-contacts[i-2][1])+contacts[i-2][1],coef2*(appPointT1nat[2]-contacts[i-2][2])+contacts[i-2][2]) + except: + print "modif 450" + #print "a" + entry=appPoint + #print "entry 408: ", entry + #Transformation of the found plot to the T1 natif referential + appPointtemp=(contacts[i-1][0],contacts[i-1][1],contacts[i-1][2]) + appPointtemp=list(appPointtemp) + appPointtemp.append(1) + appPointtemp=array(appPointtemp) + appPointT1nat=transfo_pre_to_postop.dot(appPointtemp.T) + point=list(appPointT1nat) + del point[-1] + target=tuple(point) + appPointT1nat=contacts[i] + #print "target 418: ", target + + #we make shure that the new point isn't at an angle>10 degrees + if i>=nbContacts-2: + v0=vecteur(contacts[i-2],contacts[i-1]) + v1=vecteur(contacts[i-1],contacts[i]) + try: + theta=math.acos(vdot(v0,v1)/(norme3D(v0)*norme3D(v1))) + except: + theta=0 + if theta> 0.174533: + #we lauch the approximation of the center of mass once + moy=findMoyMax(npCT,sizex,sizey,sizez,volCT,entry,do[i],dicPoints[i+1],coteRegionX/1.1,coteRegionY/1.1,coteRegionZ/1.1,CT) + #if the computations fail at this point, we will give it the first approximation + if moy is None: + appPoint=dicPoints[i+1] + else: + appPoint=(moy[2]*sizex,moy[1]*sizey,moy[0]*sizez) + #Transformation of the approximated contact to the T1 natif referential + appPointtemp=list(appPoint) + appPointtemp.append(1) + appPointtemp=array(appPointtemp) + appPointT1nat=transfo_pre_to_postopInv.dot(appPointtemp.T) + point=list(appPointT1nat) + del point[-1] + contacts[i]=tuple(point) + print "modif 490" + v0=vecteur(contacts[i-2],contacts[i-1]) + v1=vecteur(contacts[i-1],contacts[i]) + try: + theta=math.acos(vdot(v0,v1)/(norme3D(v0)*norme3D(v1))) + except: + theta=0 + if theta> 0.174533: + appPoint=dicPoints[i+1] + c#Transformation of the approximated contact to the T1 natif referential + appPointtemp=list(appPoint) + appPointtemp.append(1) + appPointtemp=array(appPointtemp) + appPointT1nat=transfo_pre_to_postopInv.dot(appPointtemp.T) + point=list(appPointT1nat) + del point[-1] + contacts[i]=tuple(point) + print "modif 507" + #print "theta sup 0.17" + + #print "target 445: ", target + #print "entry :", entry + #Suppression of the located contact so it doesn't interfear with the approximation of the next one + #Calculation of the size of the npCT matrix we are going to remove + if i==0: + a=round(appPoint[2]/sizez-do[i+1]/(2.2*sizez)) + b=round(appPoint[2]/sizez+do[i+1]/(2.2*sizez)) + c=round(appPoint[1]/sizey-do[i+1]/(2.2*sizey)) + d=round(appPoint[1]/sizey+do[i+1]/(2.2*sizey)) + e=round(appPoint[0]/sizex-do[i+1]/(2.2*sizex)) + f=round(appPoint[0]/sizex+do[i+1]/(2.2*sizex)) + else: + a=round(appPoint[2]/sizez-do[i]/(2.2*sizez)) + b=round(appPoint[2]/sizez+do[i]/(2.2*sizez)) + c=round(appPoint[1]/sizey-do[i]/(2.2*sizey)) + d=round(appPoint[1]/sizey+do[i]/(2.2*sizey)) + e=round(appPoint[0]/sizex-do[i]/(2.2*sizex)) + f=round(appPoint[0]/sizex+do[i]/(2.2*sizex)) + #Removal of the contact + try: + npCT[0,a:b,c:d,e:f]=zeros(npCT[0,a:b,c:d,e:f].shape) + except: + pdb.set_trace() + print "contacts : ", contacts + + #approximation of the contacts with only the first approximation :newS1=(a*(entry[0]-target[0])+entry[0],a*(entry[1]-target[1])+entry[1],a*(entry[2]-target[2])+entry[2]) if the contact is near the bone + #Only starts running after the nb of contacts/2-th- contact + if i>nbContacts/2: + #if no brainMask is found, this computation doesn't take place + if brainMask is None: + pass + else: + #We see if we still are in the brain: the value will be !=0 + if brainMask[0,appPointT1nat[2],appPointT1nat[1],appPointT1nat[0]]!=0: + pass + else: + #if we weren't in brain, we are going to look around if we find some + if brainMask[0,appPointT1nat[2]-(do[i]/sizeT1[2]):appPointT1nat[2]+(do[i]/sizeT1[2]),appPointT1nat[1]-(do[i]/sizeT1[1]):appPointT1nat[1]+(do[i]/sizeT1[1]),appPointT1nat[0]-(do[i]/sizeT1[0]):appPointT1nat[0]+(do[i]/sizeT1[0])].max()!=0: + pass + else: + #no brain is found, the contact will then be approximated in the continuation of the 2 contacts that come before + i+=1 + while i problème de référentiel ? +# En normalisant et exportant : si un fichier va être écrasé, demander confirmation ! +# RemoveElectrode : remove also the label objects +# Exportation : classer les plots pour que l'exportation comporte A0 A1 A2 B1 B3 et pas B3 A1 B1 A0... +# AimsMIRegister -> utilisation des fichiers TRM ou utilisation du recalage SPM ? +# Valider les templates d'electrodes avant de les utiliser : un plot doit TOUJOURS se nommer "Plot152" et pas "Element 21" ou "Plot 152" -> modifier l'éditeur de template + + +# for DTI : ./AimsMeshDistance --help + + +import sys, os, pickle, glob, numpy, re, string, time, subprocess, json, copy, csv, gc #gc.get_referrers pour trouver où est encore déclarer une variable (pour problem quand variable déclarer en python et en c++) +import openpyxl + +from PyQt4 import QtGui, QtCore, uic, Qt +from PyQt4.QtGui import QVBoxLayout + +from numpy import * +from math import sqrt, cos, sin +from collections import OrderedDict + +from soma import aims +from brainvisa import axon + +#from soma.aims.spmnormalizationreader import readSpmNormalization +from brainvisa import anatomist +from brainvisa.data import neuroHierarchy +import registration + +from externalprocesses import * +from MicromedListener import MicromedListener as ML +from referentialconverter import ReferentialConverter +from checkSpmVersion import * +from readSulcusLabelTranslationFile import * +from readFreesurferLabelFile import * +from neuroProcesses import defaultContext +from TimerMessageBox import * +from generate_contact_colors import * +from bipoleSEEGColors import bipoleSEEGColors +from DeetoMaison import DeetoMaison +#from neuroProcesses import * + +import ImportTheoreticalImplentation +from scipy import ndimage +from brainvisa.processes import * +from PIL import Image + +import pdb + +#import objgraph #if not install in a terminal : pip install objgraph --prefix /brainvisa_4.50/ + +#name = 'Anatomist Show MarsAtlas Parcels Texture' +#roles = ('viewer',) +#userLevel = 0 + +#def validation(): +# anatomist.validation() + +#signature = Signature( +# 'texture_marsAtlas_parcels', ReadDiskItem('hemisphere marsAtlas parcellation texture', 'aims Texture formats', requiredAttributes={ 'regularized': 'false' }), +# 'white_mesh',ReadDiskItem( 'Hemisphere White Mesh', 'aims mesh formats' ), +#) + + +########## SPM calls +# Convert SPM normalization _sn.mat to vector field +spm_SnToField8 = """try, addpath(genpath(%s));spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +FileNameSN = '%s'; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.matname{1}=FileNameSN; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.vox=[NaN NaN NaN]; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.bb=NaN*ones(2,3); +matlabbatch{1}.spm.util.defs.comp{1}.inv.space{1}=['%s' ',1']; +matlabbatch{1}.spm.util.defs.ofname='%s'; +matlabbatch{1}.spm.util.defs.fnames=''; +matlabbatch{1}.spm.util.defs.savedir.saveusr{1}=spm_str_manip(FileNameSN,'h'); +matlabbatch{1}.spm.util.defs.interp=1; +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" # %(FileNameSN, FileSource, ofname) -> '_sn.mat' file and source image FileSource (normalized with the _sn). For the Database, we want y__inverse.nii, so we need ofname = '_inverse' --> Maybe should provide also the output dir ? Right now, same as _sn.mat + +# API changed in SPM12... +spm_SnToField12 = """try, addpath(genpath(%s));spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +FileNameSN = '%s'; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.matname{1}=FileNameSN; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.vox=[NaN NaN NaN]; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.bb=NaN*ones(2,3); +matlabbatch{1}.spm.util.defs.comp{1}.inv.space = {'%s'}; +matlabbatch{1}.spm.util.defs.out{1}.savedef.ofname = '%s'; +matlabbatch{1}.spm.util.defs.out{1}.savedef.savedir.saveusr{1}=spm_str_manip(FileNameSN,'h'); +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + +#spm_SnToField = spm_SnToField12 + +spm_inverse_y_field12 = """try,addpath(genpath(%s));spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.def = {%s}; +matlabbatch{1}.spm.util.defs.comp{1}.inv.space = {%s}; +matlabbatch{1}.spm.util.defs.out{1}.savedef.ofname = %s; +matlabbatch{1}.spm.util.defs.out{1}.savedef.savedir.saveusr = {%s}; +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + +spm_inverse_y_field8 ="""try,addpath(genpath(%s));spm('defaults', 'FMRI');spm_jobman('initcfg'); + +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + +# Read deformation field y__inverse.nii, apply the vector field to scanner-based coordinates of electrodes +spm_normalizePoints = """ +try, addpath(genpath(%s));P='%s'; +P1=spm_vol([P ',1,1']); +P2=spm_vol([P ',1,2']); +P3=spm_vol([P ',1,3']); +[V1,XYZ]=spm_read_vols(P1); +V2=spm_read_vols(P2); +V3=spm_read_vols(P3); + +%% Apply tranformation to electrodes +PosElectrode = dlmread('%s'); +wPosElectrode=PosElectrode; +for i1=1:size(PosElectrode,1) +D=(XYZ(1,:)-PosElectrode(i1,1)).^2+(XYZ(2,:)-PosElectrode(i1,2)).^2+(XYZ(3,:)-PosElectrode(i1,3)).^2; +[tmp,order]=sort(D); +tmp=tmp(1:18); %% cubic neighborhood +order=order(1:18); +W=1./tmp; %% weight inverse to distance +if sum(isinf(W))>0 +W=[1 zeros(1,length(W)-1)]; +end +wPosElectrode(i1,:)=[sum(V1(order).*W)./sum(W) sum(V2(order).*W)./sum(W) sum(V3(order).*W)./sum(W)]; +end +dlmwrite('%s',wPosElectrode,'precision',18); +catch, disp 'AN ERROR OCCURED'; end;quit; +""" + + +#coregister and reslice and segmentation (for resection estimation) +spm_resection_estimation = """try, addpath(genpath(%s)); spm('defaults', 'FMRI'); spm_jobman('initcfg'); +clear matlabbatch; + +final_directory = %s; +if isdir(final_directory) == 0 + mkdir(final_directory) +end +matlabbatch{1}.spm.spatial.coreg.estwrite.ref = %s; +matlabbatch{1}.spm.spatial.coreg.estwrite.source = %s; +matlabbatch{1}.spm.spatial.coreg.estwrite.other = {''}; +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.cost_fun = 'nmi'; +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.sep = [4 2]; +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.tol = [0.02 0.02 0.02 0.001 0.001 0.001 0.01 0.01 0.01 0.001 0.001 0.001]; +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.fwhm = [7 7]; +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.interp = 4; +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.wrap = [0 0 0]; +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.mask = 0; +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.prefix = 'r'; +matlabbatch{2}.spm.spatial.preproc.channel.vols = %s; +matlabbatch{2}.spm.spatial.preproc.channel.biasreg = 0.001; +matlabbatch{2}.spm.spatial.preproc.channel.biasfwhm = 60; +matlabbatch{2}.spm.spatial.preproc.channel.write = [0 0]; +matlabbatch{2}.spm.spatial.preproc.tissue(1).tpm = %s; +matlabbatch{2}.spm.spatial.preproc.tissue(1).ngaus = 2; +matlabbatch{2}.spm.spatial.preproc.tissue(1).native = [1 0]; +matlabbatch{2}.spm.spatial.preproc.tissue(1).warped = [0 0]; +matlabbatch{2}.spm.spatial.preproc.warp.mrf = 1; +matlabbatch{2}.spm.spatial.preproc.warp.cleanup = 1; +matlabbatch{2}.spm.spatial.preproc.warp.reg = [0 0.001 0.5 0.05 0.2]; +matlabbatch{2}.spm.spatial.preproc.warp.affreg = 'mni'; +matlabbatch{2}.spm.spatial.preproc.warp.fwhm = 0; +matlabbatch{2}.spm.spatial.preproc.warp.samp = 3; +matlabbatch{2}.spm.spatial.preproc.warp.write = [0 0]; +matlabbatch{3}.spm.spatial.preproc.channel.vols = %s; +matlabbatch{3}.spm.spatial.preproc.channel.biasreg = 0.001; +matlabbatch{3}.spm.spatial.preproc.channel.biasfwhm = 60; +matlabbatch{3}.spm.spatial.preproc.channel.write = [0 0]; +matlabbatch{3}.spm.spatial.preproc.tissue(1).tpm = %s; +matlabbatch{3}.spm.spatial.preproc.tissue(1).ngaus = 2; +matlabbatch{3}.spm.spatial.preproc.tissue(1).native = [1 0]; +matlabbatch{3}.spm.spatial.preproc.tissue(1).warped = [0 0]; +matlabbatch{3}.spm.spatial.preproc.warp.mrf = 1; +matlabbatch{3}.spm.spatial.preproc.warp.cleanup = 1; +matlabbatch{3}.spm.spatial.preproc.warp.reg = [0 0.001 0.5 0.05 0.2]; +matlabbatch{3}.spm.spatial.preproc.warp.affreg = 'mni'; +matlabbatch{3}.spm.spatial.preproc.warp.fwhm = 0; +matlabbatch{3}.spm.spatial.preproc.warp.samp = 3; +matlabbatch{3}.spm.spatial.preproc.warp.write = [0 0]; +matlabbatch{4}.spm.util.imcalc.input = { + %s + %s + }; +matlabbatch{4}.spm.util.imcalc.output = %s; +matlabbatch{4}.spm.util.imcalc.outdir = %s; +matlabbatch{4}.spm.util.imcalc.expression = 'i1-i2'; +matlabbatch{4}.spm.util.imcalc.var = struct('name', {}, 'value', {}); +matlabbatch{4}.spm.util.imcalc.options.dmtx = 0; +matlabbatch{4}.spm.util.imcalc.options.mask = 0; +matlabbatch{4}.spm.util.imcalc.options.interp = 1; +matlabbatch{4}.spm.util.imcalc.options.dtype = 4; +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + + +region_grow="""try,addpath(genpath(%s)); +imgresec = %s; +iSeed = %s; +reseccenter = %s; +f_orient = %s; +f_orient = reshape(f_orient,4,4)'; +centermatF = eye(4); +centermatF(:,4) = f_orient*[reseccenter 1]'; +VF = spm_vol(imgresec); +reseccenter_pix = inv(VF.mat)*centermatF(:,4); +mat_to_grow=spm_read_vols(VF); +new_image = regiongrowing(mat_to_grow,iSeed,reseccenter_pix(1:3)); +VF.fname = %s; +VF.private.mat0 = VF.mat; +spm_write_vol(VF,new_image); +catch, disp 'AN ERROR OCCURED'; end;quit;""" + +def viewFile(filepath): + """ Launches an external app to display the provided file (windows/linux/mac-specific methods) """ + if sys.platform.startswith('darwin'): + subprocess.call(('open', filepath)) + elif os.name == 'nt': + os.startfile(filepath) + elif os.name == 'posix': + subprocess.call(('xdg-open', filepath)) + + +# Functions to sort the contacts A1,A2...,A10 and not A1, A10, A2.. +def atoi(text): + return int(text) if text.isdigit() else text +def natural_keys(text): + """alist.sort(key=natural_keys) sorts in human order""" + return [ atoi(c) for c in re.split('(\d+)', text) ] + +##################### Electrode functions (to be exported in another file FIXME needs natural_keys function ################################## + +from electrode import ElectrodeModel + +def moveElectrode(target, entry, referential, newRef, a, meshes): + # a is anatomist object + if entry is None or target is None: + print("entry or target is None") + return + + + #print "entry : "+repr(entry)+"target : "+repr(target) + + if newRef is None: + newRef = a.createReferential() + transl = target#[-target[0], -target[1], -target[2]] + i = array([[1,0,0]]) + z = array([target,]) - array([entry,]) + if z[0][1] < 0.001 and z[0][2] < 0.001:# si i est colinéaire avec z, changer i car on n'obtiendra pas un vecteur perpendiculaire aux deux + i = array([[0,1,0]]) + if linalg.norm(z) == 0: + return + z = -z / linalg.norm(z) + #print "z = "+repr(z) + y = cross (i,z) + y = -y/linalg.norm(y) + #print "y = "+repr(y) + x = cross(y,z) + #print "x = "+repr(x) + #m = [x[0][0], x[0][1], x[0][2], y[0][0],y[0][1], y[0][2], z[0][0], z[0][1], z[0][2]] + m = [x[0][0], y[0][0], z[0][0], x[0][1],y[0][1], z[0][1], x[0][2], y[0][2], z[0][2]] + try: + transf = a.createTransformation(transl+m, origin = newRef, destination = referential) + except: + print("problem transformation") + return + pdb.set_trace() + a.assignReferential(newRef, meshes) + #print " Electrode moved : target = "+repr(target) + ", entry = "+repr(entry) + " and Matrix "+repr(transl+m) + #pdb.set_trace() + return (newRef, transf) + +def createElectrode(target, entry, referential, ana=None, windows=None, model = None, dispMode=None, dispParams=None): + elecModel = ElectrodeModel(ana) + elecModel.open(model,dispMode, dispParams) + #elecModel.setDisplayReferential(newRef) + meshes = elecModel.getAnatomistObjects() + (newRef, transf) = moveElectrode(target, entry, referential, None, ana, meshes) + #pdb.set_trace() + if windows is not None: + ana.addObjects(meshes, windows) + return (newRef, transf, elecModel) + +def createBipole(target, entry, referential, ana=None, windows=None, model = None, dispMode=None, dispParams=None): + + elecModel = ElectrodeModel(ana) + elecModel.open(str(model),dispMode, dispParams) + #elecModel.setDisplayReferential(newRef) + + meshes = elecModel.getAnatomistObjects() + #mesh = self.a.toAObject(aims.SurfaceGenerator.cylinder(aims.Point3df(p[0], p[1], p[2]), aims.Point3df(pEnd), r, r, 24, True, True)) + (newRef, transf) = moveElectrode(target, entry, referential, None, ana, meshes) + + if windows is not None: + ana.addObjects(meshes, windows) + return (newRef, transf, elecModel) + + +# Récupération des plots dans l'ordre plot1 -> plot n +def getPlots(elecModel): + cyls = elecModel.getCylinders() + return dict((name,cyls[name]) for name in cyls if cyls[name]['type'] == 'Plot') + +def getPlotsNames(elecModel): + cyls = elecModel.getCylinders() + plots = [n for n in cyls if cyls[n]['type'] == 'Plot'] + return sorted(plots, key=natural_keys) + + +# Récupération des coordonnées des centres des plots dans le référentiel électrode +def getPlotsCenters(elecModel): + plots = getPlots(elecModel) + return dict((p, plots[p]['center']) for p in plots) + + +############### 3D text annotations from anagraphannotate.py #############" + + +byvertex = False +# This intermediate class is only here because I cannot (yet) make SIP +# generate a non-abstract class for TextObject binding. One day, I'll find out! +class TObj ( anatomist.anatomist.cpp.TextObject ): + def __init__( self, message='', pos=[0,0,0] ): + anatomist.anatomist.cpp.TextObject.__init__( self, message, pos ) + +class Props( object ): + def __init__( self ): + self.lvert = [] + self.lpoly = [] + self.usespheres = True + self.colorlabels = True + self.center = aims.Point3df() + +def makelabel( a, label, gc, pos, ref, color, props ): + """ Create a text label designating gc at position pos, using anatomist instance a, a color and stores the generated elements in props""" + objects = [] + # create a text object + to = TObj( label ) + to.setScale( 0.1 ) + to.setName( 'label: ' + label ) + a.releaseObject(to) + + # If we want to show a sphere at the target point + if props.usespheres: + sph = aims.SurfaceGenerator.icosphere( gc, 2, 50 ) + asph = a.toAObject( sph ) + asph.setMaterial( diffuse=color ) + asph.setName( 'gc: ' + label ) + a.registerObject( asph, False ) + a.releaseObject(asph) #registerObject le "dérelease" + objects.append( asph ) + # Choose the color of the label text + if props.colorlabels: + to.GetMaterial().set( { 'diffuse': color } ) + # texto is the label (2D texture on a rectangle), but defined to always face the camera + texto = anatomist.anatomist.cpp.TransformedObject( [ to ], False, True, pos ) + texto.setDynamicOffsetFromPoint( props.center ) + texto.setName( 'annot: ' + label ) + objects.append( texto ) + # Add to the polygons a line (to link the label and the target position) + props.lpoly.append( aims.AimsVector_U32_2( ( len( props.lvert ), + len( props.lvert ) + 1 ) ) ) + props.lvert += [ gc, pos ] + a.registerObject( texto, False ) + a.assignReferential(ref, objects) + a.releaseObject(texto) + + return objects + +############################### Useful functions + +def createItemDirs(item): + """ Create the directories containing the provided WriteDiskItem and insert them in the BrainVisa database """ + # Copied from brainvisa.processes, in ExecutionContext._processExecution() + dirname = os.path.dirname( item.fullPath() ) + dir=dirname + dirs = [] + while not os.path.exists( dir ): + dirs.append(dir) + dir=os.path.dirname(dir) + if dirs: + try: + os.makedirs( dirname ) + except OSError, e: + if not e.errno == errno.EEXIST: + # filter out 'File exists' exception, if the same dir has + # been created concurrently by another instance of BrainVisa + # or another thread + raise + for d in dirs: + dirItem=neuroHierarchy.databases.createDiskItemFromFileName(d, None) + + + +######################### FENETRE PRINCIPALE ############################ + +class LocateElectrodes(QtGui.QDialog): + + def __init__(self, app=None, loadAll = True): + + # UI init + if loadAll == True: + QtGui.QWidget.__init__(self) + self.ui = uic.loadUi("epilepsie-electrodes.ui", self) + self.setWindowTitle('Epilepsie - localisation des electrodes - NOT FOR MEDICAL USAGE') + # Widget 0 (buttons panel) will be at minimum size (stretch factor 0), the windows will fill up the rest + self.splitter_2.setStretchFactor(0,0) + self.splitter_2.setStretchFactor(1,1) + # Equal size for both views + self.splitter.setStretchFactor(0,1) + self.splitter.setStretchFactor(1,1) + + + self.nameEdit.setText('A') + + # Load the list of protocols, patients and electrode models from BrainVisa + if loadAll == True: + self.modalities = ['Raw T1 MRI', 'T2 MRI', 'CT', 'PET', 'Electrode Implantation Coronal Image', 'Electrode Implantation Sagittal Image','fMRI-epile', 'Statistic-Data','FLAIR', 'resection', 'FreesurferAtlas', 'FGATIR','HippoFreesurferAtlas'] + # Electrode models + self.elecModelList = [] + self.elecModelListByName = [] + self.loadFromBrainVisa() + + + + # Init of variables + self.app = app + self.dispObj = {} # All displayable objects "t1mri-pre", "t2"... + self.objtokeep = {} #all object we must keep alive for anatomist but not in other variables + self.diskItems = {} # For each dispObj, a list of dictionnaries {'refName', 'refObj', 'refId', 'transf'} + # Coordinates displayed using referential : 'Natif' par defaut + self.coordsDisplayRef = 'Natif' + self.referentialCombo.clear() + self.referentialCombo.addItems(['Natif',]) + self.dispMode = 'real' + self.dispParams = None + self.t1preMniFieldPath = None + self.t1pre2ScannerBasedId = None + self.electrodes = []# {Les objets electrodes avec les coordonnées, les meshes + self.bipoles = [] #{Les objects bipoles} + self.electrodeTemplateStubs = [] # Un objet electrode par template disponible dans la base de données (chargé à la demande par getElectrodeTemplates) + self.contacts = [] # {name:n, number:2, electrode: e, mesh:m} + self.transfs = [] # identity transforms (must be stored) + self.currentWindowRef = None # Referential used by windows (because pyanatomist AWindow.getReferential is not implemented yet) + self.linkedRefs = [] # Referentials linked by a identity transform + self.transf2Mni = {} # Transformation from T1 pre referential to MNI referential + self.threads = [] # List of running threads + self.t1pre2ScannerBasedTransform = None #Transfo from T1pre native to scanner-based referential (Anatomist Transformation object) + self.brainvisaPatientAttributes = None # Attributes of a BrainVisa ReadDiskItem MRI of the loaded patient + self.spmpath = None + + #self.MicromedListener = ML() + + # list of objects to display in window for each scenario (MNI, pre, post, etc) + self.windowContent = { 'IRM pre':['T1pre','electrodes',],\ + 'IRM pre T2':['T2pre','electrodes',],\ + 'IRM pre + hemisphere droit':['T1pre','T1pre-rightHemi','electrodes',],\ + 'IRM pre + MARS ATLAS droit':['T1pre','right MARS ATLAS BIDULE','electrodes',],\ + 'IRM pre + hemisphere gauche':['T1pre','T1pre-leftHemi','electrodes',],\ + 'IRM pre + MARS ATLAS gauche':['T1pre','left MARS ATLAS BIDULE','electrodes',],\ + 'IRM pre + hemispheres':['T1pre','T1pre-rightHemi','T1pre-leftHemi','electrodes',],\ + 'IRM pre + hemispheres + tete':['T1pre','T1pre-rightHemi','T1pre-leftHemi', 'T1pre-head','electrodes',],\ + 'IRM post':['T1post','electrodes',],\ + 'IRM post T2':['T2post','electrodes',],\ + 'CT post':['CTpost','electrodes',],\ + 'PET pre':['PETpre','electrodes',],\ + 'FLAIR pre':['FLAIRpre','electrodes',],\ + 'FGATIR pre':['FGATIRpre','electrodes',],\ + 'fMRI pre':['fMRIpre','electrodes'],\ + 'Statistic Data':['Statisticspre','electrodes'],\ + 'IRM post-op':['T1postOp','electrodes',],\ + 'Resection':['Resection','electrodes',],\ + 'FreeSurferAtlas':['FreesurferAtlaspre','electrodes',],\ + 'HippoFreeSurferAtlas':['HippoFreesurferAtlaspre','electrodes',],\ + } + self.windowCombo1.clear() + self.windowCombo1.addItems(sorted(self.windowContent.keys())) + self.windowCombo2.clear() + self.windowCombo2.addItems(sorted(self.windowContent.keys())) + + # Anatomist windows + if loadAll == True: + self.wins=[] + self.a = anatomist.Anatomist('-b') #Batch mode (hide Anatomist window) + self.a.onCursorNotifier.add(self.clickHandler) + + layoutAx = QtGui.QHBoxLayout( self.windowContainer1 ) + self.axWindow = self.a.createWindow( 'Axial' )#, no_decoration=True ) + self.axWindow.setParent(self.windowContainer1) + layoutAx.addWidget( self.axWindow.getInternalRep() ) + + layoutSag = QtGui.QHBoxLayout( self.windowContainer2 ) + self.sagWindow = self.a.createWindow( 'Axial' )#, no_decoration=True ) + self.sagWindow.setParent(self.windowContainer2) + layoutSag.addWidget( self.sagWindow.getInternalRep() ) + + self.wins = [self.axWindow, self.sagWindow] + + # Get Transformation Manager + self.transfoManager = registration.getTransformationManager() + # Get ReferentialConverter (for Talairach, AC-PC...) + self.refConv = ReferentialConverter() + + if loadAll == True: + # Linking UI elements to functions + self.connect(self.loadPatientButton, QtCore.SIGNAL('clicked()'), self.loadPatient) + self.connect(self.changePatientButton, QtCore.SIGNAL('clicked()'), self.changePatient) + self.connect(self.patientList, QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem*)'), lambda x:self.loadPatient()) + self.connect(self.protocolCombo, QtCore.SIGNAL('currentIndexChanged(int)'), self.updateBrainvisaProtocol) + self.connect(self.filterSiteCombo, QtCore.SIGNAL('currentIndexChanged(int)'), self.filterSubjects) + self.connect(self.filterYearCombo, QtCore.SIGNAL('currentIndexChanged(int)'), self.filterSubjects) + self.connect(self.addElectrodeButton, QtCore.SIGNAL('clicked()'), self.addElectrode) + self.connect(self.removeElectrodeButton, QtCore.SIGNAL('clicked()'), self.removeElectrode) + self.connect(self.nameEdit, QtCore.SIGNAL('editingFinished()'), self.editElectrodeName) + self.connect(self.targetButton, QtCore.SIGNAL('clicked()'), self.updateTarget) + self.connect(self.entryButton, QtCore.SIGNAL('clicked()'), self.updateEntry) + self.connect(self.electrodeList, QtCore.SIGNAL("currentRowChanged(int)"), self.electrodeSelect) + self.connect(self.electrodeList, QtCore.SIGNAL("itemDoubleClicked(QListWidgetItem*)"), self.electrodeGo) + self.connect(self.contactList, QtCore.SIGNAL("itemClicked(QListWidgetItem*)"), self.contactSelect) + self.connect(self.contactList, QtCore.SIGNAL("itemDoubleClicked(QListWidgetItem*)"), self.contactGo) + self.connect(self.typeComboBox, QtCore.SIGNAL('currentIndexChanged(QString)'), self.updateElectrodeModel) + # itemClicked(QListWidgetItem*) , currentItemChanged ( QListWidgetItem * current, QListWidgetItem * previous ), currentRowChanged ( int currentRow ) + self.connect(self.electrodeLoadButton, QtCore.SIGNAL('clicked()'), self.loadElectrodes) + self.connect(self.electrodeSaveButton, QtCore.SIGNAL('clicked()'), self.saveElectrodes) + self.connect(self.normalizeExportButton, QtCore.SIGNAL('clicked()'), self.normalizeExportElectrodes) + #self.connect(self.marsatlasExportButton, QtCore.SIGNAL('clicked()'),self.parcelsExportElectrodes) + self.connect(self.colorConfigButton, QtCore.SIGNAL('clicked()'), self.configureColors) + self.connect(self.dispModeCombo, QtCore.SIGNAL('currentIndexChanged(int)'), self.updateDispMode) + self.connect(self.windowCombo1, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s: self.windowUpdate(0,s)) + self.connect(self.windowCombo2, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s: self.windowUpdate(1,s)) + self.connect(self.referentialCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.updateCoordsDisplay) + self.connect(self.electrodeRefCheck, QtCore.SIGNAL('stateChanged(int)'), self.updateElectrodeView) + self.connect(self.electrodeRefRotationSlider, QtCore.SIGNAL('valueChanged(int)'), self.updateElectrodeViewRotation) + + self.connect(self.Clipping_checkbox,QtCore.SIGNAL('clicked()'),self.clippingUpdate) + self.connect(self.makefusionButton,QtCore.SIGNAL('clicked()'),self.makeFusion) + self.connect(self.generateResectionArray,QtCore.SIGNAL('clicked()'),self.generateResection) + self.connect(self.validateROIresection,QtCore.SIGNAL('clicked()'),self.ROIResectiontoNiftiResection) + self.connect(self.deleteMarsAtlasfiles,QtCore.SIGNAL('clicked()'),self.DeleteMarsAtlasFiles) + self.connect(self.generateDictionariesComboBox,QtCore.SIGNAL('activated(QString)'),self.generateDictionaries) + self.connect(self.ImportTheoriticalImplantation,QtCore.SIGNAL('clicked()'),self.importRosaImplantation) + self.connect(self.approximateButton,QtCore.SIGNAL('clicked()'),self.approximateElectrode) + + prefpath_imageimport = os.path.join(os.path.expanduser('~'), '.imageimport') + try: + if (os.path.exists(prefpath_imageimport)): + filein = open(prefpath_imageimport, 'rb') + prefs_imageimport = pickle.load(filein) + self.spmpath = prefs_imageimport['spm'] + self.fileNoDBpath = prefs_imageimport['FileNoDBPath'] + filein.close() + except: + print 'NO SPM path found, will be unable to export MNI position' + pass + + self.warningMEDIC() + + # Reload options, check brainvisa and matlab/SPM + + def closeEvent(self, event): + self.quit(event) + + def quit(self, event=None): + reply = QtGui.QMessageBox.question(self, 'Message', + "Quit the software without saving ?", QtGui.QMessageBox.Yes | + QtGui.QMessageBox.No, QtGui.QMessageBox.No) + #if self.brainvisaPatientAttributes is not None: + #self.saveElectrodes() + # Remove the vector field to MNI if it was computed + #self.clearT1preMniTransform() + if reply == QtGui.QMessageBox.Yes: + axon.processes.cleanup() + if event is None: + self.app.quit() + else: + event.accept() + else: + event.ignore() + + + def warningMEDIC(self): + + shortwarning = TimerMessageBox(5,self) + shortwarning.exec_() + + #messagebox = QtGui.QMessageBox(self) + #messagebox.setWindowTitle("NOT FOR MEDICAL USAGE") + #messagebox.setText("NOT FOR MEDICAL USAGE\n (closing automatically in {0} secondes.)".format(3)) + #messagebox.setStandardButtons(messagebox.NoButton) + #self.timer2 = QtCore.QTimer() + #self.time_to_wait = 3 + #def close_messagebox(e): + #e.accept() + #self.timer2.stop() + #self.time_to_wait = 10 + #def decompte(): + #messagebox.setText("NOT FOR MEDICAL USAGE\n (closing automatically in {0} secondes.)".format(self.time_to_wait)) + #if self.time_to_wait <= 0: + #messagebox.closeEvent = close_messagebox + #messagebox.close() + #self.time_to_wait -= 1 + #self.connect(self.timer2,QtCore.SIGNAL("timeout()"),decompte) + #self.timer2.start(1000) + #messagebox.exec_() + + def loadFromBrainVisa(self): + # Find available patients in BV database + print "LOADING DATA FROM BRAINVISA" + rdi = ReadDiskItem( 'Subject', 'Directory',requiredAttributes={'_ontology':'brainvisa-3.2.0'} ) #, requiredAttributes={'center':'Epilepsy'} ) + subjects = list( rdi._findValues( {}, None, False ) ) + protocols = list(set([s.attributes()['center'] for s in subjects if 'center' in s.attributes()])) + # Fill the combo + self.protocolCombo.clear() + self.protocolCombo.addItems(sorted(protocols)) + self.allSubjects = subjects + self.updateBrainvisaProtocol() + + def updateBrainvisaProtocol(self, idx=None): + """Updates the UI when the selected protocol changes""" + self.currentProtocol = str(self.protocolCombo.currentText()) + self.subjects = [s.attributes()['subject'] for s in self.allSubjects if 'center' in s.attributes() and s.attributes()['center'] == self.currentProtocol] + print 'all subjects:' + repr(self.subjects) + self.patientList.clear() + self.patientList.addItems(sorted(self.subjects)) + # Update the filters + sites = ['*',] + sorted(set([s.split('_')[0] for s in self.subjects])) + years = ['*',] + sorted(set([s.split('_')[1] for s in self.subjects if len(s.split('_')) > 1])) + self.filterSiteCombo.clear() + self.filterSiteCombo.addItems(sites) + self.filterYearCombo.clear() + self.filterYearCombo.addItems(years) + # Loading electrode models + rdiEM = ReadDiskItem('Electrode Model', 'Electrode Model format', requiredAttributes={'center':self.currentProtocol}) + self.elecModelList = list (rdiEM._findValues( {}, None, False ) ) + elecNames = [e.attributes()['model_name'] for e in self.elecModelList] + self.elecModelListByName = dict((e.attributes()['model_name'], e) for e in self.elecModelList) + self.typeComboBox.clear() + self.typeComboBox.addItems(elecNames) + + def filterSubjects(self, value=None): + """Filtering subject list""" + subs = self.subjects + if str(self.filterSiteCombo.currentText()) != '*': + subs = [s for s in subs if s.split('_')[0] == str(self.filterSiteCombo.currentText())] + if str(self.filterYearCombo.currentText()) != '*': + subs = [s for s in subs if len(s.split('_')) > 1 and s.split('_')[1] == str(self.filterYearCombo.currentText())] + self.patientList.clear() + self.patientList.addItems(sorted(subs)) + + def getT1preMniTransform(self): + """Returns the path of the transformation to MNI (vector field) and compute it if necessary (from _sn.mat)""" + #pdb.set_trace() + if self.t1preMniFieldPath is not None: + return self.t1preMniFieldPath + # Find _sn.mat + + + if 'T1pre' not in self.dispObj: + print "No T1pre loaded : cannot get MNI transform from it" + return None + + #look for a y_file_inverse first + rdi_inv_read = ReadDiskItem('SPM normalization inverse deformation field','NIFTI-1 image') + di_inv_read = rdi_inv_read.findValue(self.diskItems['T1pre']) + + if di_inv_read is None: + print "No inverse deformation field found in database" + else: + print "inverse deformation field found and used" + #pdb.set_trace() + self.t1preMniFieldPath = di_inv_read.fileName() + return self.t1preMniFieldPath + + spm_version = checkSpmVersion(self.spmpath) + + #look for a y_file second + rdi_y = ReadDiskItem('SPM normalization deformation field','NIFTI-1 image') + di_y = rdi_y.findValue(self.diskItems['T1pre']) + #pdb.set_trace() + if di_y is None: + print "No deformation field found in database" + else: + print "deformation field found and used" + wdi_inverse = WriteDiskItem('SPM normalization inverse deformation field','NIFTI-1 image') + dir_yinv_split = str(di_y.fileName()).split('/') + name_yinverse = dir_yinv_split.pop()[2:] + #name_yinverse.replace('.nii','_inverse.nii') + dir_yinverse = "/".join(dir_yinv_split) + di_inverse = wdi_inverse.findValue(di_y) + #on fait l'inversion de la deformation + #pdb.set_trace() + #pour le moment ce bout de code ne marche qu'avec spm12 + if spm_version == '(SPM12)': + print 'SPM12 used' + matlabRun(spm_inverse_y_field12%("'"+self.spmpath+"'","'"+str(di_y.fileName())+"'","'"+self.dispObj['T1pre'].fileName()+"'","'"+name_yinverse.replace('.nii','_inverse.nii')+"'","'"+dir_yinverse+"'")) + if spm_version == '(SPM8)': + print 'SPM8 used' + matlabRun(spm_inverse_y_field8%("'"+self.spmpath+"'","'"+str(di_y.fileName())+"'","'"+self.dispObj['T1pre'].fileName()+"'","'"+name_yinverse.replace('.nii','_inverse.nii')+"'","'"+dir_yinverse+"'")) + + self.t1preMniFieldPath = di_inverse.fileName() + neuroHierarchy.databases.insertDiskItem( di_inverse, update=True ) + return self.t1preMniFieldPath + + #look for a _sn.mat if no y_file + rdi = ReadDiskItem( 'SPM2 normalization matrix', 'Matlab file' ) + di = rdi.findValue(self.diskItems['T1pre']) + #pdb.set_trace() + if di is None: + print "SPM deformation _sn.mat not found in database" + return None + + # Convert to field + #pdb.set_trace() + wdi = WriteDiskItem( 'SPM normalization inverse deformation field', 'NIFTI-1 image' ) + diField = wdi.findValue(di) + if diField is None: + print "Cannot find path to save MNI vector field in the DB" + return None + #For a file /database/y_SubjectName_inverse.nii, get SubjectName_inverse + ofname = os.path.basename(diField.fullPath()).lstrip('y_').rsplit('.',1)[0] + + #pdb.set_trace() + + if spm_version == '(SPM12)': + print 'SPM12 used' + matlabRun(spm_SnToField12%("'"+self.spmpath+"'",str(di.fullPath()), str(self.diskItems['T1pre'].fullPath()), ofname) ) + if spm_version == '(SPM8)': + print 'SPM8 used' + matlabRun(spm_SnToField8%("'"+self.spmpath+"'",str(di.fullPath()), str(self.diskItems['T1pre'].fullPath()), ofname) ) + + if os.path.exists(diField.fullPath()): + self.t1preMniFieldPath = diField.fullPath() + return self.t1preMniFieldPath + else: + print "Matlab did not convert the MNI transform to vector field !" + return None + + + def clearT1preMniTransform(self): + """Reset MNI transform field if it was generated""" + if self.t1preMniFieldPath is not None: + try: + os.remove(self.t1preMniFieldPath) #to change with: self.removeDiskItems(di,eraseFiles=True) + except: + pass + self.t1preMniFieldPath = None + + def changePatient(self): + + self.loadPatientButton.setEnabled(True) + self.patientList.setEnabled(True) + self.a.removeObjects(self.a.getObjects(),self.wins[0]) + self.a.removeObjects(self.a.getObjects(),self.wins[1]) + self.a.config()[ 'linkedCursor' ] = 0 + referentials=self.a.getReferentials() + for element in referentials: + if element.getInfos().get('name') not in ('Talairach-MNI template-SPM', 'Talairach-AC/PC-Anatomist'): + self.a.deleteElements(element) + + #for element in self.electrodes: + #for elecKeys in element.keys(): + #del element[elecKeys] + #variablesG=globals() + #variablesL=locals() + self.electrodeList.clear() + self.contactList.clear() + self.currentWindowRef = None + listEl=[] + #for el , value in self.dispObj.items(): + # listEl.append(value) + #self.__init__(self,loadAll=False) + #for el in listEl: + # if type(el)==list: + # listElec=el + # else: + # self.a.deleteObjects(el) + + #del self.electrodes + self.electrodes = [] + #del self.dispObj + #parcourir les objets, détruire les fusions avant + #for obj in self.dispObj: + self.currentElectrodes = [] + self.currentContacts = [] + + #todelete = [] + #for name,obj in self.dispObj.items(): + # if isinstance(obj.internalRep,anatomist.anatomist.cpp.MObject): + # todelete.append(name) + #for name in todelete: + # del self.dispObj[name] + + self.dispObj={} + + #if hasattr(self,"objtokeep"): + self.objtokeep = {} + + self.__init__(loadAll = False) + + + def loadPatient(self, patient=None): + + if patient is None: + patient = str(self.patientList.selectedItems()[0].text()) + + volumes = [] + self.t1pre2ScannerBasedTransform = None + self.clearT1preMniTransform() + + pre_select_1 = self.windowCombo1.currentText() + pre_select_2 = self.windowCombo2.currentText() + + + + for moda in self.modalities: + rdi2 = ReadDiskItem( moda, 'aims readable volume formats', requiredAttributes={'subject':patient, 'center':self.currentProtocol} ) + volumes.extend(list( rdi2._findValues( {}, None, False ) )) + + + dictionnaire_list_images = {'IRM pre':['T1pre','electrodes',],\ + 'IRM pre + hemisphere droit':['T1pre','T1pre-rightHemi','electrodes',],\ + 'IRM pre + hemisphere gauche':['T1pre','T1pre-leftHemi','electrodes',],\ + 'IRM pre + hemispheres':['T1pre','T1pre-rightHemi','T1pre-leftHemi','electrodes',],\ + 'IRM pre + hemispheres + tete':['T1pre','T1pre-rightHemi','T1pre-leftHemi', 'T1pre-head','electrodes']} + + + #pdb.set_trace() + + for t in volumes: + if "skull_stripped" in t.fullName(): + continue + self.brainvisaPatientAttributes = t.attributes() + if (t.attributes()['modality'] == 't2mri') and ('pre' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'IRM pre T2':['T2pre','electrodes']}) + elif (t.attributes()['modality'] == 't2mri') and ('post' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'IRM post T2':['T2post','electrodes']}) + elif (t.attributes()['modality'] == 't1mri') and ('post' in t.attributes()['acquisition']) and not ('postOp' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'IRM post':['T1post','electrodes']}) + elif (t.attributes()['modality'] == 'ct') and ('post' in t.attributes()['acquisition']) and not ('postOp' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'CT post':['CTpost','electrodes']}) + elif (t.attributes()['modality'] == 'ct') and ('postOp' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'CT post-op':['CTpostOp','electrodes']}) + elif (t.attributes()['modality'] == 'pet') and ('pre' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'PET pre':['PETpre','electrodes']}) + elif (t.attributes()['modality'] == 'flair') and ('pre' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'FLAIR pre':['FLAIRpre','electrodes']}) + elif (t.attributes()['modality'] == 'fgatir') and ('pre' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'FGATIR pre':['FGATIRpre','electrodes']}) + elif (t.attributes()['modality'] == 'fmri_epile') and ('pre' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'fMRI pre'+ ' - ' + t.attributes()['subacquisition']:['fMRIpre','electrodes']}) #mettre le nom de la subacquisition + elif t.attributes()['modality'] == 'statistic_data' and ('pre' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'Statistic Data' + ' - ' + t.attributes()['subacquisition']:['Statisticspre'+t.attributes()['subacquisition'],'electrodes']}) #mettre le nom de la subacquisition + elif t.attributes()['modality'] == 'statistic_data' and ('post' in t.attributes()['acquisition']) and not ('postOp' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'Statistic Data' + ' - ' + t.attributes()['subacquisition']:['Statisticspost'+t.attributes()['subacquisition'],'electrodes']}) #mettre le nom de la subacquisition + elif (t.attributes()['modality'] == 't1mri') and ('postOp' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'IRM post-op':['T1postOp','electrodes']}) + elif (t.attributes()['modality'] == 'resection'): + dictionnaire_list_images.update({'Resection':['Resection','electrodes']}) + elif (t.attributes()['modality'] == 'freesurfer_atlas'): + dictionnaire_list_images.update({'FreeSurferAtlas pre':['FreesurferAtlaspre','electrodes']}) + elif (t.attributes()['modality'] == 'hippofreesurfer_atlas'): + dictionnaire_list_images.update({'HippoFreeSurferAtlas pre':['HippoFreesurferAtlaspre','electrodes']}) + + + try: + nameAcq = t.attributes()['acquisition'] + #print "Loading %s as %s"%(t.fileName(), nameAcq) + #print repr(t.attributes()) + # We try to get the acquisition name without the date (if there is one) : T1pre_2000-01-01 -> T1pre + if 'Statistics' in nameAcq: + na = nameAcq.split('_')[0] + t.attributes()['subacquisition'] + else: + na = nameAcq.split('_')[0] + except: + if moda == 'Electrode Implantation Coronal Image': + na = 'ImplantationCoro' + elif moda == 'Electrode Implantation Sagittal Image': + na = 'ImplantationSag' + else: + print "CANNOT find a nameAcq for ",repr(t) + na = 'unknown' + + self.loadAndDisplayObject(t, na) + if na == 'T1pre': + # Load standard transformations (AC-PC, T1pre Scanner-based, BrainVisa Talairach) + try: + self.refConv.loadACPC(t) + except Exception, e: + print "Cannot load AC-PC referential from T1 pre MRI : "+repr(e) + try: + self.refConv.loadTalairach(t) + except Exception, e: + print "Cannot load Talairach referential from T1 pre MRI : "+repr(e) + try: + tr2sb = self.t1pre2ScannerBased() + if tr2sb is not None: + self.refConv.setAnatomistTransform("Scanner-based", tr2sb, toRef=True) + # Add the AC-centered Scanner-Based (for PTS importation using AC-centered Olivier David method + if self.refConv.isRefAvailable('AC-PC'): + acInScannerBased = self.refConv.anyRef2AnyRef([0.0,0.0,0.0],'AC-PC', 'Scanner-based') + inf = tr2sb.getInfos() + rot = inf['rotation_matrix'] + trans = [inf['translation'][0] - acInScannerBased[0], inf['translation'][1] - acInScannerBased[1], inf['translation'][2] - acInScannerBased[2]] + m = aims.Motion(rot[:3]+[trans[0]]+rot[3:6]+[trans[1]]+rot[6:]+[trans[2]]+[0,0,0,1]) + self.refConv.setTransformMatrix('AC-centered Scanner-Based', m.inverse(), m) + except Exception, e: + print "Cannot load Scanner-based referential from T1 pre MRI : "+repr(e) + # Get the hemisphere meshes for the acquisition : name = na + filename base : for example, if the acquisition is T1pre_2000-01-01 and the file head.gii, we want T1pre-head + rdi3 = ReadDiskItem( 'Hemisphere Mesh', 'Anatomist mesh formats', requiredAttributes={'subject':patient, 'acquisition':nameAcq, 'center':self.currentProtocol} ) + hemis = list(rdi3._findValues( {}, None, False ) ) + + + for hh in hemis: + #pdb.set_trace() + self.loadAndDisplayObject(hh, na + '-' + hh.attributes()['side'] + 'Hemi', color=[0.8,0.7,0.4,0.7]) + print "Found hemisphere "+ str(na + '-' + hh.attributes()['side'] + 'Hemi') + + atlas_di = ReadDiskItem('hemisphere marsAtlas parcellation texture', 'aims Texture formats', requiredAttributes={ 'regularized': 'false','subject':patient, 'center':self.currentProtocol, 'acquisition':nameAcq }) + atlas_di_list = list(atlas_di._findValues({}, None, False )) + #probleme + wm_di = ReadDiskItem( 'Hemisphere White Mesh', 'aims mesh formats',requiredAttributes={'subject':patient, 'center':self.currentProtocol }) + + + if len(atlas_di_list) > 0: + for atl in atlas_di_list: + wm_side = wm_di.findValue(atl) + self.loadAndDisplayObject(wm_side, na + '-' + atl.attributes()['side'] + 'MARSATLAS', texture_item = atl, palette = 'MarsAtlas', color=[0.8,0.7,0.4,0.7]) + print "Found hemisphere "+ str(na + '-' + atl.attributes()['side'] + 'MARSATLAS') + dictionnaire_list_images.update({'IRM pre + MARS ATLAS ' + atl.attributes()['side']:['T1pre','T1pre-'+ atl.attributes()['side'] + 'MARSATLAS','electrodes']}) + #pdb.set_trace() + + # Get head mesh for the acquisition + #probleme + rdi3 = ReadDiskItem( 'Head Mesh', 'Anatomist mesh formats', requiredAttributes={'subject':patient, 'acquisition':nameAcq, 'center':self.currentProtocol} ) + head = list(rdi3._findValues( {}, None, False ) ) + if len(head) > 0: # Only if there is one ! + self.loadAndDisplayObject(head[0], na + '-' + 'head', color=[0.0,0.0,0.8,0.3]) + + self.windowContent = dictionnaire_list_images; + self.windowCombo1.clear() + self.windowCombo1.addItems(sorted(dictionnaire_list_images.keys())) + self.windowCombo2.clear() + self.windowCombo2.addItems(sorted(dictionnaire_list_images.keys())) + + self.windowCombo1.setCurrentIndex(max(self.windowCombo1.findText(pre_select_1),0)) + self.windowCombo2.setCurrentIndex(max(self.windowCombo2.findText(pre_select_2),0)) + + # Display referential informations + self.setWindowsReferential() + self.loadElectrodes(self.brainvisaPatientAttributes) + self.refreshAvailableDisplayReferentials() + # Display all + self.allWindowsUpdate() + # Disable the button because no cleanup is attempted when loading a patient when one is already loaded -> there may be a mixup + self.loadPatientButton.setEnabled(False) + self.patientList.setEnabled(False) + + + + # Chargement d'un objet (IRM, mesh...) dans Anatomist et mise à jour de l'affichage + def loadAndDisplayObject(self, diskitem, name = None, color=None, palette=None, texture_item = None): + + if name is None: + return + + #Already exists ! Remove it. + if name in self.dispObj: + self.a.removeObjects([self.dispObj[name],], self.wins) # Remove from windows + self.a.deleteObjects(self.dispObj[name]) # CURRENT + del self.dispObj[name] + del self.diskItems[name] + + print "loading "+repr(diskitem)+ ' as '+name + + obj = self.a.loadObject(diskitem) + # Read all available transforms in the image header (for example the coregistration by SPM to the T1 Pre MRI) + #obj.loadReferentialFromHeader() + if 'ColorPalette' in diskitem.attributes(): + obj.setPalette(palette = diskitem.attributes()['ColorPalette']) + elif palette is not None and texture_item is None: + obj.setPalette(palette = palette) + + if texture_item is not None: + texture = self.a.loadObject(texture_item) + if palette is not None: + texture.setPalette(palette = palette) + #pdb.set_trace() + textured_mesh = self.a.fusionObjects((obj,texture),method = 'FusionTexSurfMethod') + #we need to keep the texture and the mesh as well as the fusion of both + self.objtokeep[name + '_mesh'] = obj + self.objtokeep[name + '_texture'] = texture + obj = textured_mesh + + + # Store the object + self.dispObj[name] = obj + self.diskItems[name] = diskitem + #print "Referential of object %s : %s"%(repr(name), repr(obj.getReferential().uuid())) + # If this is a volume, smooth it : + try: + self.a.execute('TexturingParams', objects=[obj], filtering='linear') + except: + pass + #pdb.set_trace() + if color is not None: + self.a.setMaterial(obj, diffuse=color) + return obj + + + + + def setWindowsReferential(self, ref=None): + """ Get all available referentials from anatomist and tries to match identical referentials from SPM""" + # If the T1pre image is already loaded + if ref is None: + if self.preReferential(): + # Assign the T1pre native referential to the windows + self.currentWindowRef = self.preReferential() + self.a.assignReferential(self.currentWindowRef, self.wins) + + else: + self.currentWindowRef = ref + self.a.assignReferential(ref, self.wins) + + + # Get the click events + def clickHandler(self, eventName, params): + #pos=params['position'] + #currentwin=params['window'] + coords = [0.0,0.0,0.0] + if 'T1pre' in self.dispObj: + pT1Pre = self.a.linkCursorLastClickedPosition(self.dispObj['T1pre'].getReferential()).items() + #pdb.set_trace() + if self.coordsDisplayRef == 'Natif': + coords = pT1Pre + elif self.coordsDisplayRef == 'Scanner-based': + infos = self.t1pre2ScannerBased().getInfos() + rot = infos['rotation_matrix'] + trans = infos['translation'] + m = aims.Motion(rot[:3]+[trans[0]]+rot[3:6]+[trans[1]]+rot[6:]+[trans[2]]+[0,0,0,1]) + coords = m.transform(pT1Pre) + else: + try: + coords = self.refConv.real2AnyRef(pT1Pre, self.coordsDisplayRef) + except: + coords = [0.0,0.0,0.0] + #print type(coords) + if coords is None: + coords = [0.0,0.0,0.0] + self.positionLabel.setText("%.2f, %.2f, %.2f" % tuple(coords)) + + + def preReferential(self): + if 'T1pre' in self.dispObj: + return self.dispObj['T1pre'].getReferential() + else: + return None + + def positionPreRef(self): + return list(self.a.linkCursorLastClickedPosition(self.preReferential()).items()) + + def t1pre2ScannerBased(self): + """ Returns a Transformation object that transforms T1pre referential to T1pre Scanner-Based referential """ + if self.t1pre2ScannerBasedTransform is not None: + if "dead" not in self.t1pre2ScannerBasedTransform.getInfos(): + return self.t1pre2ScannerBasedTransform + rdi = ReadDiskItem('Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True,\ + requiredAttributes={'modality':'t1mri', 'subject':self.brainvisaPatientAttributes['subject'], 'center':self.brainvisaPatientAttributes['center']}) + allTransf = list (rdi._findValues( {}, None, False ) ) + for trsf in allTransf: + if trsf.attributes()['acquisition'].startswith(u'T1pre'): + print repr(trsf.attributes()) + srcrDiskItem = self.transfoManager.referential( trsf.attributes()['source_referential'] ) + srcr = self.a.createReferential(srcrDiskItem) + dstrDiskItem = self.transfoManager.referential(trsf.attributes()['destination_referential']) + self.t1pre2ScannerBasedId = trsf.attributes()['destination_referential'] + dstr = self.a.createReferential(dstrDiskItem) + self.t1pre2ScannerBasedTransform = self.a.loadTransformation(trsf.fullPath(), srcr, dstr) + return self.t1pre2ScannerBasedTransform + return None + + + def mniReferentialId(self): + return aims.StandardReferentials.mniTemplateReferentialID() + + def mniReferential(self): + return self.a.mniTemplateRef + + def refreshAvailableDisplayReferentials(self): + curr = str(self.referentialCombo.currentText()) + self.referentialCombo.clear() + refs = self.refConv.availableReferentials().keys() + ['Natif',] + print "Available referentials from refConv : "+repr(refs) + self.referentialCombo.addItems(sorted(refs)) + #if curr in refs: + #self.set + + def updateCoordsDisplay(self, text): + self.coordsDisplayRef = str(text) + self.clickHandler(None, None) + + def updateDispMode(self, index): + """ Update the display mode of all electrodes """ + mode = 'sphere' + params = {} + isbipole = False + if index == 0: + mode = 'real' + self.colorConfigButton.setEnabled(False) + elif index == 1: + params = {'diameter':1.0} + self.colorConfigButton.setEnabled(False) + elif index == 2: + params = {'diameter':2.0} + self.colorConfigButton.setEnabled(False) + elif index == 3: + params = {'diameter':5.0} + self.colorConfigButton.setEnabled(False) + elif index == 4: + mode = 'off' + self.colorConfigButton.setEnabled(False) + elif index == 5: + mode = 'bipole' + isbipole = True + #is there a json file about the seeg results in the database. + rdi_seeglabel = ReadDiskItem('Electrodes SEEG Labels','Electrode sEEG Label Format',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.brainvisaPatientAttributes['center']}) + di_seeglabel = list(rdi_seeglabel.findValues({},None,False)) + #if not, ask for one + if len(di_seeglabel) == 0: + load_new_file = True + else: + #ask if you want to replace the loaded data + rep = QtGui.QMessageBox.warning(self, u'Use database or Import?', u"Use sEEG stim result from the database ? (if no, it will ask for a file)", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel) + if rep == QtGui.QMessageBox.Yes: + load_new_file = False + elif rep == QtGui.QMessageBox.No: + load_new_file = True + elif rep == QtGui.QMessageBox.Cancel: + return + + if load_new_file: + wdi_seeg = WriteDiskItem('Electrodes SEEG Labels','Electrode sEEG Label Format') + di_seeg = wdi_seeg.findValue({'subject':self.brainvisaPatientAttributes['subject'], 'center':self.brainvisaPatientAttributes['center']} ) + + fichierseegLabel = QtGui.QFileDialog.getOpenFileName(self, "Select a file containing seeg labels: ", "", "(*.xlsx *.csv *.json)") + if os.path.basename(str(fichierseegLabel)).split('.')[-1] == 'json': + fin = open(str(fichierseegLabel),'rb') + new_label = json.loads(fin.read()) + fin.close() + + try: + os.mkdir(os.path.dirname(str(di_seeg))) + except: + pass + fout = open(str(di_seeg),'w') + fout.write(json.dumps({'title':new_label['title'],'contacts':new_label['contacts']})) + fout.close() + + neuroHierarchy.databases.insertDiskItem(di_seeg, update=True ) + + elif os.path.basename(str(fichierseegLabel)).split('.')[-1] == 'xlsx': + + contact_label_class = generate_contact_colors() + + inter_label = contact_label_class.from_excel_files(str(fichierseegLabel)) + + #write the json and include it in the database + try: + os.mkdir(os.path.dirname(str(di_seeg))) + except: + pass + fout = open(str(di_seeg),'w') + fout.write(json.dumps({'title':inter_label[0],'contacts':inter_label[1]})) + fout.close() + + neuroHierarchy.databases.insertDiskItem(di_seeg, update=True ) + new_label = {'title':inter_label[0],'contacts':inter_label[1]} + + else: + fin = open(str(di_seeglabel[0]),'rb') + new_label = json.loads(fin.read()) + fin.close() + + bipole_label_sorted = sorted(new_label['contacts'].keys(),key=natural_keys) + plotsT1preRef = self.getAllPlotsCentersT1preRef() + info_plotsT1Ref= [] + for k,v in plotsT1preRef.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plotsT1Ref.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v.list())) + #plots_label[k]=(label,label_name) + + plotsT1Ref_sorted = dict(sorted(info_plotsT1Ref, key=lambda plot_number: plot_number[0])) + + #remplir self.bipole + for i_bipole in bipole_label_sorted: + #get the name of both contact from the bipole name + try: + pos_bipol = (numpy.array(plotsT1Ref_sorted[i_bipole.split()[0].title()]) + numpy.array(plotsT1Ref_sorted[i_bipole.split()[2].title()]))/2 + except: + print("problem plotsT1Ref") + pdb.set_trace() + entry_bipole = numpy.array(plotsT1Ref_sorted[i_bipole.split()[0].title()]) + #orient_vector_bip = (numpy.array(plotsT1Ref_sorted[i_bipole.split()[0]]) - numpy.array(plotsT1Ref_sorted[i_bipole.split()[2]]))/linalg.norm((numpy.array(plotsT1Ref_sorted[i_bipole.split()[0]]) - numpy.array(plotsT1Ref_sorted[i_bipole.split()[2]]))) + #il faut un orient vector + self.addBipole(i_bipole,pos_bipol,self.preReferential().uuid(),entry_bipole) #on rajoute pour finir un vecteur + + + self.colorConfigButton.setEnabled(True) + #show bipole instead of contacts ? + #remove all contacts (mesh and in the list), and set the bipoles instead + + contact_labels_seeg = {} + params.update({'contact_colors':contact_labels_seeg}) + + self.bipoleLabels = new_label + self.configureColors() + + #self.dispObj['electrodes'][0].__getattr__('name') + + #pdb.set_trace() + if mode == self.dispMode and params == self.dispParams: + print "already using the right display mode" + return + self.updateElectrodeMeshes(clear=True) + for elec in self.electrodes: + elec['elecModel'].setDisplayMode(mode, params) + elec['elecModel'].updateDisplay() + elec['elecModel'].setDisplayReferential(elec['ref']) + self.dispMode = mode + self.dispParams = params + self.updateElectrodeMeshes(bipole = isbipole) + # Update the contact list meshes of the current electrode (so they can be selected) + self.electrodeSelect(self.electrodeList.currentRow()) + + + def updateElectrodeMeshes(self, clear=False, bipole=False): + if clear: + print "UPDATE CLEAR -> remove electrodes from windows and delete them" + #traceback.print_stack(limit=4) + self.a.removeObjects(self.dispObj['electrodes'], self.wins) + #self.a.deleteObjects(self.dispObj['electrodes'])# Should be destroyed in electrode.py CURRENT + self.dispObj['electrodes'] = [] + return + if not bipole: + self.dispObj['electrodes'] = [mesh for elec in self.electrodes for mesh in elec['elecModel'].getAnatomistObjects() if mesh is not None] + self.setElectrodeMeshesNames() + elif bipole: + self.dispObj['electrodes'] = [mesh for elec in self.bipoles for mesh in elec['elecModel'].getAnatomistObjects() if mesh is not None] + self.setBipoleMeshesNames() + + #self.dispObj['electrodes'][0].__getattr__('name') + self.allWindowsUpdate() + + # Add an electrode from a template + def addElectrode(self, name=None, model=None, target=[0,0,0], entry=[0,0,-1], refId = None): + if name is None: + name = str(self.nameEdit.text()) + if model is None: + model = str(self.typeComboBox.currentText()) + if refId is not None: + if self.preReferential().uuid() != refId: + print "ERROR : the electrode is not defined in reference to the T1 pre image (%s) but in reference to %s !\nGoing on anyway..."%(self.preReferential().uuid(), refId) + for el in self.electrodes: + if name == el['name']: + name = self.findFreeElectrodeName() + (newRef, transf, elecModel) = createElectrode(target, entry, self.preReferential(), self.a,\ + model = self.elecModelListByName[str(model)].fullPath(), dispMode = self.dispMode, dispParams = self.dispParams) + self.electrodes.append({'name': name, 'ref':newRef, 'transf':transf, 'elecModel':elecModel,\ + 'target':target, 'entry':entry, 'model':model}) + self.electrodeList.addItem(name) + #index = self.elecCombo.findText("Electrode "+str(self.elecname)) + self.electrodeList.setCurrentRow(self.electrodeList.count() - 1) + self.addElectrodeLabel(name, [0,0,-10], newRef, len(self.electrodes) - 1) + self.updateElectrodeMeshes() + + def addBipole(self, name=None, positionbip=[0,0,0], refId = None,entry_bipole = None): + if name is None: + print("error, bipole must have a name") + return + pdb.set_trace() + if refId is None: + print("error, bipole has to be assigned to a referential") + return + pdb.set_trace() + if refId is not None: + if self.preReferential().uuid() != refId: + print "ERROR : the electrode is not defined in reference to the T1 pre image (%s) but in reference to %s !\nGoing on anyway..."%(self.preReferential().uuid(), refId) + #if refId is not None: + #if self.preReferential().uuid() != refId: + #print "ERROR : the electrode is not defined in reference to the T1 pre image (%s) but in reference to %s !\nGoing on anyway..."%(self.preReferential().uuid(), refId) + #check is name is already taken + if len(self.bipoles)>0: + for bip in self.bipoles: + if name == bip['name']: + print("error, bipole name already taken") + + #je met un objet elecmodel ici ou juste le mesh ? un objet elecmodel de 1 contact ? + rdiEM = ReadDiskItem('Electrode Model', 'Electrode Model format', requiredAttributes={'center':self.currentProtocol}) + listEM = list(rdiEM.findValues({},None,False)) + matches = filter((lambda x: u"bipole" in str(x)), listEM) + + (newRef, transf, elecModel) = createBipole(positionbip.tolist(), entry_bipole.tolist(), self.preReferential(), self.a, model = matches[0], dispMode = 'bipole', dispParams = None) + self.bipoles.append({'name': name, 'ref':newRef, 'transf':transf, 'target':positionbip.tolist(), 'entry': entry_bipole.tolist(), 'elecModel':elecModel}) #to change target and entry + #on ne touche pas à electrodeList + #self.electrodeList.addItem(name) + #index = self.elecCombo.findText("Electrode "+str(self.elecname)) + #self.electrodeList.setCurrentRow(self.electrodeList.count() - 1) + + self.addElectrodeLabel(name, [0,0,-10], newRef, len(self.bipoles) - 1, True) + #self.updateElectrodeMeshes(bipole=True) + + + # Setting names on meshes to get a nice tooltip for each mesh + def setElectrodeMeshesNames(self, electrode = None): + if electrode is None: + electrodes = self.electrodes + else: + electrodes = [electrode,] + for el in electrodes: + for name, element in el['elecModel'].getDisplayed().iteritems(): + if element['mesh'] is not None: + if element['type'] == 'Plot': + element['mesh'].setName(name.replace('Plot', el['name'])) + else: + element['mesh'].setName(el['name']) + #element['mesh'].setChanged() + #element['mesh'].notifyObservers() #Should be needed to refresh display, but it works without it + + def setBipoleMeshesNames(self, bipole = None): + if bipole is None: + bipoles = self.bipoles + else: + bipoles = [bipole,] + for bp in bipoles: + for name, element in bp['elecModel'].getDisplayed().iteritems(): + element['mesh'].setName(bp['name']) + + def findFreeElectrodeName(self): + if len(self.electrodes) == 0: + return 'A' + n = [el['name'] for el in self.electrodes] + newName = n[-1] + firstletter = newName[::-1][-1] + if firstletter in string.ascii_uppercase: + newName = string.uppercase[(string.uppercase.find(firstletter)+1)%len(string.uppercase)] + newName[1:] + if newName in n: + while newName in n: + newName = newName+'_' + return newName + + def currentElectrode(self): + idx = self.electrodeList.currentRow() + print "Electrode %i is selected"%idx + if idx < 0: + return None + return self.electrodes[idx] + + def removeElectrode(self): + """Remove an electrode (and all contacts)""" + elec = self.currentElectrode() + idx = self.electrodes.index(elec) + if elec is None: + return + # Remove meshes from Anatomist + self.updateElectrodeMeshes(clear=True) + elec['elecModel'].clearDisplay() + item = self.electrodeList.takeItem(idx) + del item + del self.electrodes[idx] + self.updateElectrodeMeshes() + + def updateElectrodeModel(self, model): + elec = self.currentElectrode() + if elec is None: + return + if str(elec['model']) == str(model): + return + #import pdb; pdb.set_trace() + self.updateElectrodeMeshes(clear=True) + elec['elecModel'].clearDisplay() + del elec['elecModel'] + (newRef, transf, elecModel) = createElectrode(elec['target'], elec['entry'], self.preReferential(), self.a,\ + model = self.elecModelListByName[str(model)].fullPath(), dispMode = self.dispMode, dispParams = self.dispParams) + elec['elecModel'] = elecModel + elec['model']=str(model) + self.electrodeSelect(self.electrodeList.currentRow()) + self.updateElectrodeMeshes() + + + def updateEntry(self, e=None): + """ Updates the current electrode entry point from the cursor position""" + el = self.currentElectrode() + pos = self.positionPreRef() + # Just ignore if new entry is identical to target + if pos == el['target']: + return + + (newRef, transf) = moveElectrode(el['target'], pos, self.preReferential(),\ + el['ref'], self.a, el['elecModel'].getAnatomistObjects()) + el['entry'] = pos + el['transf'] = transf + + def updateTarget(self, t=None): + """ Updates the current electrode target point from the cursor position""" + el = self.currentElectrode() + if el is None: + return + pos = self.positionPreRef() + # Just ignore if new target is identical to entry + if pos == el['entry']: + return + + (newRef, transf) = moveElectrode(pos, el['entry'], self.preReferential(),\ + el['ref'], self.a, el['elecModel'].getAnatomistObjects()) + el['target'] = pos + el['transf'] = transf + print repr(self.a.getReferentials()) + + + def editElectrodeName(self): + """Update the electrode name of the selected contact""" + name = str(self.nameEdit.text()) + idx = self.electrodeList.currentRow() + sameNameItems = self.electrodeList.findItems(name, QtCore.Qt.MatchFixedString) + if len(sameNameItems) != 0: + if sameNameItems[0] == self.electrodeList.item(idx): # Name was not changed + return + else: + QtGui.QMessageBox.warning(self, u'Error', u"The name %s is already used by another electrode. Choose an other one !"%name) + self.nameEdit.setText(self.electrodeList.item(idx).text()) + self.electrodes[idx]['name'] = name + self.setElectrodeMeshesNames(self.electrodes[idx]) + self.electrodeList.currentItem().setText(name) + self.electrodeSelect(idx) # updates the contacts' display + + + def electrodeSelect(self, idx): + """Electrode/contact selection changed""" + el = self.electrodes[idx] + self.nameEdit.setText(el['name']) + self.typeComboBox.setCurrentIndex(self.typeComboBox.findText(el['model'])) + #import pdb;pdb.set_trace() + # Select the contacts in anatomist + g = self.a.getDefaultWindowsGroup() + g.setSelection(el['elecModel'].plotMeshes()) + self.currentContacts = dict((name.replace('Plot', el['name']), element['mesh']) for name, element in el['elecModel'].getDisplayed().iteritems() if element['type'] == 'Plot' and element['mesh'] is not None) + self.currentElectrodes = [el,] + #Update contact list + self.contactList.clear() + self.contactList.addItems(sorted(self.currentContacts.keys(), key=natural_keys)) + self.updateElectrodeView() + + def electrodeGo(self, idx = None, electrode = None): + if idx is not None: + if type(idx) == int: + electrode = self.electrodes[idx] + else: + electrode = self.currentElectrodes[0] + elif electrode is None: + return + self.contactGo(el = electrode) + + def contactSelect(self, item): + # Select the contacts in anatomist + print "Click on the contact " + str(item.text()) + g = self.a.getDefaultWindowsGroup() + #print "CurrentContacts = "+repr(self.currentContacts.keys()) + g.setSelection([self.currentContacts[str(item.text())],]) + + def contactGo(self, item = None, el=None): + # Put the cursor on the contact in anatomist + #print "Double clic sur le contact " + str(item.text()) + try: + if el is None: + el = self.currentElectrodes[0] + if item is not None: + name = str(item.text()).replace(el['name'], 'Plot') + else: + name = 'Plot1' + xyz = getPlotsCenters(el['elecModel'])[name] + # setLinkedCursor uses window referential : must apply transform before setting the position + if self.currentWindowRef == self.preReferential(): + xyz = el['transf'].transform(xyz) + self.wins[0].moveLinkedCursor(xyz) + #self.a.execute('LinkedCursor', window=self.wins[0], position=xyz) + elif self.currentWindowRef == el['ref']: + self.wins[0].moveLinkedCursor(xyz) + else: + print "Warning : Current window referential is not T1pre referential ! Cannot set the linkedCursor on the selected electrode contact..." + except: + print "Error moving the cursor to the contact" + + + def addElectrodeLabel(self, label, position, ref, elecId,bipole=False): + props = Props() + props.usespheres = False + props.center = [0, 0, 0] + gc = aims.Point3df(position) + if not bipole: + self.electrodes[elecId]['labelObjects'] = makelabel( self.a, label, gc, gc+aims.Point3df([5,0,0]), ref, (0, 0, 0, 0), props ) + self.electrodes[elecId]['props'] = props + elif bipole: + self.bipoles[elecId]['labelObjects'] = makelabel( self.a, label, gc, gc+aims.Point3df([5,0,0]), ref, (0, 0, 0, 0), props ) + self.bipoles[elecId]['props'] = props + + def getElectrodeTemplates(self): + """Returns a list of Electrode objects, one for each available electrode template model available in the DB""" + if self.electrodeTemplateStubs == []: + self.electrodeTemplateStubs = dict([(n,ElectrodeModel(modelPath=model.fullPath(), dispMode='off')) for n, model in self.elecModelListByName.iteritems()]) + return self.electrodeTemplateStubs + + def fitElectrodeModelToLength(self, target, entry): + """ Tries to find a match between the length of the electrode and a model, but prefering uniform electrodes (no variable spacing between contacts""" + length = linalg.norm(array(entry)-array(target)) + + models = self.getElectrodeTemplates() + uniformModelsLength = {} + for n,model in models.iteritems(): + interPlotsM=[] + plotsM = sorted([[int(''.join(e for e in namePlot if e.isdigit())), ] + content['center'] for namePlot, content in model.getPlots().iteritems()], key=lambda p:p[0]) + + for p in range(len(plotsM)-1): + interPlotsM.append(math.sqrt((plotsM[p][1]-plotsM[p+1][1])**2 + (plotsM[p][2]-plotsM[p+1][2])**2 + (plotsM[p][3]-plotsM[p+1][3])**2)) + lengthM = sum(interPlotsM) + if len(set(interPlotsM)) == 1: # All intervals are identical + uniformModelsLength[n] = lengthM + if length >= max(uniformModels.values()): + return [m for m,l in uniformModels.iteritems() if l == max(uniformModels.values())][0] + else: + largerModels = dict([(m,l) for m,l in uniformModels.iteritems() if l >= length]) + return [m for m,l in largerModels.iteritems() if l == min(largerModels.values())][0] + + + def fitElectrodeModelToPlots(self, plots): + """ Tries to find a match between a list of plots [[numPlot, x, y, z],[...], ...] and available electrode templates. + Return None if it fail, [ModelName, [targetX, targetY, targetZ], [entryX, entryY, entryZ]] if it works + """ + + plots = sorted(plots, key=lambda p:int(p[0])) + # Compute inter-contact distances + interPlots=[] + for p in range(len(plots)-1): + interPlots.append(math.sqrt((plots[p][1]-plots[p+1][1])**2 + (plots[p][2]-plots[p+1][2])**2 + (plots[p][3]-plots[p+1][3])**2)) + # Find electrode models with a similar number of plots + models = dict([(n,tpl) for n,tpl in self.getElectrodeTemplates().iteritems() if tpl.countPlots() == len(plots)]) # identical number + if len(models) == 0: + print "Cannot find a template with the right number of contacts (%i), trying longer ones"%len(plots) + nbPlotsModels = dict([(n, tpl.countPlots()) for n,tpl in self.getElectrodeTemplates().iteritems() if tpl.countPlots() > len(plots)]) + if len(nbPlotsModels) == 0: + print "Cannot find a template with enough contacts for this electrode ! (available : %s)\nWill match with the largest available electrodes !\n THIS WILL LOSE SOME PLOTS"%repr(nbPlotsModels.values()) + nbPlotsModels = dict([(n, tpl.countPlots()) for n,tpl in self.getElectrodeTemplates().iteritems()]) + models = dict([(n,tpl) for n,tpl in self.getElectrodeTemplates().iteritems() if tpl.countPlots() == max(nbPlotsModels.values())]) + else: + models = dict([(n,tpl) for n,tpl in self.getElectrodeTemplates().iteritems() if tpl.countPlots() == min(nbPlotsModels.values())]) + + # Now, check the interPlots distance in the model and compare with the template + distanceFromModel = {} + for n,model in models.iteritems(): + interPlotsM=[] + plotsM = sorted([[int(''.join(e for e in namePlot if e.isdigit())), ] + content['center'] for namePlot, content in model.getPlots().iteritems()], key=lambda p:p[0]) + + for p in range(len(plotsM)-1): + interPlotsM.append(math.sqrt((plotsM[p][1]-plotsM[p+1][1])**2 + (plotsM[p][2]-plotsM[p+1][2])**2 + (plotsM[p][3]-plotsM[p+1][3])**2)) + distanceFromModel[n] = sum([(interPlotsM[i]-interPlots[i])**2 for i in range(min([len(interPlotsM), len(interPlots)]))]) + + # Choose the model with the smallest distance, or the first one if a few are equally good, reject if sum is more than 1mm per contact + minDist = min(distanceFromModel.values()) + if minDist > 1.0*len(plots): + print "Cannot match a template : minimum distance found is %f mm, should be %f or less !"%(minDist, 1.0*len(plots)) + return None + # We have a winner ! + goodModel = [m for m in distanceFromModel if distanceFromModel[m] == minDist][0] + print "Found model %s, match distance = %f"%(goodModel, minDist) + #import pdb; pdb.set_trace() + entry = plots[-1][1:] + # Target is not the center of the first contact, but its end ! -> coords - lengthOfPlot/2*vector(plot0->plotLast) + target = array(plots[0][1:]) - (array(plotsarr[-1][1:])-array(plots[0][1:]))/linalg.norm(array(plots[-1][1:])-array(plots[0][1:])) * 0.5 * self.getElectrodeTemplates()[goodModel].getCylinder('Plot1')['length'] + return [goodModel, target.tolist(), entry] + + + def comboMessageBox(self, text, choices): + """ Displays a message box with a choice (combobox), Ok and Cancel button + Returns the selected value or None if it was cancelled""" + if choices is None or choices == []: + return None + msgBox = QtGui.QMessageBox() + msgBox.setText(text) + combo = QtGui.QComboBox() + combo.addItems(choices) + msgBox.layout().addWidget(combo,1,0) + msgBox.addButton(QtGui.QPushButton('Ok'), QtGui.QMessageBox.AcceptRole) + msgBox.addButton(QtGui.QPushButton('Annuler'), QtGui.QMessageBox.RejectRole) + ret = msgBox.exec_(); + if ret == QtGui.QMessageBox.Cancel: + return None + return str(combo.currentText()) + + def loadPTSbasic(self, path): + """Load a PTS file, creating an 'electrode model' for each contact (VERY slow with > 50 contacts) """ + refId = self.preReferential().uuid() + els = [] + elecs = {} + try: + f = open(path, 'r') + lines = f.readlines() + f.close() + lines.reverse() + if not lines.pop().startswith('ptsfile'): + print 'This is not a valid PTS file !' + return (refId, []) + lines.pop() # Useless line 1 1 1 + nb = int(lines.pop()) # Number of contacts + for i in range(nb): + l = lines.pop().rstrip().split("\t") # name x y z 0 0 0 2 2.0 (last ones may be contact length/diameter ?) + name = ''.join(e for e in l[0] if not e.isdigit()) + if name not in elecs: + elecs[name]=[] + plot = int(''.join(e for e in l[0] if e.isdigit())) + coords = list(self.refConv.anyRef2Real([float(l[1]), float(l[2]),float(l[3])], 'Scanner-based')) + nameplot = l[0] + elecs[name].append ( [plot,] + coords) + els.append( {'name':nameplot, 'model':'plot2mmD1mmCentered', 'target': coords, 'entry':coords[0:2]+[coords[2]+1.0,]} ) + except: + print "Error reading PTS file %s"%path + return (refId, els) + + def loadPTS(self, path): + """Load a PTS file (tries to find a suitable electrode model in the available templates) """ + refId = self.preReferential().uuid() + els = [] + elecs = {} + #try: + f = open(path, 'r') + lines = f.readlines() + f.close() + + # The coordinates in the PTS are expressed in which referential ? + refOfPts = self.comboMessageBox(u'Importation d\'un fichier PTS. Choisissez le référentiel utilisé (Scanner-based...)', sorted(self.refConv.availableReferentials().keys())) + if refOfPts is None: + print "User cancelled PTS importation, or no valid referential found" + return + print "PTS import referential : %s"%repr(refOfPts) + lines.reverse() + if not lines.pop().startswith('ptsfile'): + print 'This is not a valid PTS file !' + return (refId, []) + lines.pop() # Useless line 1 1 1 + nb = int(lines.pop()) # Number of contacts + for i in range(nb): # All lines (= all plots) + l = lines.pop().rstrip().split() # name x y z 0 0 0 2 2.0 (last ones may be contact length/diameter ?) + name = ''.join(e for e in l[0] if not e.isdigit()) + + print l[0] + plot = ''.join(e for e in l[0] if e.isdigit()) + if plot == '': + continue + plot = int(plot) + + if name not in elecs: + elecs[name]=[] + + coords = list(self.refConv.anyRef2Real([float(l[1]), float(l[2]),float(l[3])], refOfPts)) + nameplot = l[0] + elecs[name].append ( [plot,] + coords) + #els.append( {'name':nameplot, 'model':'plot2mmD1mmCentered', 'target': coords, 'entry':coords[0:2]+[coords[2]+1.0,]} ) + # Iterate over all electrodes + for k,l in elecs.iteritems(): + # Try to get a real model from l [[numPlot, x,y,z], [...], ...] + res = self.fitElectrodeModelToPlots(l) + if res is not None: + els.append( {'name':k.lower(), 'model':res[0], 'target': res[1], 'entry':res[2]} ) + else: + print "Could not find model matching electrode %s, adding individual contacts."%k + for pl in l: + coords = pl[1:] + els.append( {'name':k+str(pl[0]), 'model':'plot2mmD1mmCentered', 'target': coords, 'entry':coords[0:2]+[coords[2]+1.0,]} ) + + #except: + # print "Error reading PTS file %s"%path + return (refId, els) + + def loadElectrodeTXT(self, path): + """Load an electrode.txt file with triplets of lines : nameOfElectrode\n X1 Y1 Z1\n X2 Y2 Z2 such as used by ImaGIN""" + els=[] + f = open(path, 'r') + lines = f.readlines() + f.close() + lines.reverse() + + # The coordinates in the TXT are expressed in which referential ? + refOfTxt = self.comboMessageBox(u'Importation d\'un fichier electrode TXT. Choisissez le référentiel utilisé (Scanner-based a priori)', sorted(self.refConv.availableReferentials().keys())) + if refOfTxt is None: + print "User cancelled electrode TXT importation, or no valid referential found" + return + print "TXT electrode import referential : %s"%repr(refOfTxt) + + while (len(lines) >= 3): + try: + name = lines.pop() + targ = map (float,lines.pop().replace(',','.').split()) + entr = map (float,lines.pop().replace(',','.').split()) + if len(targ) == 3 and len(entr) == 3 and len(name)>0: + targ = list(self.refConv.anyRef2Real(targ, refOfTxt)) + entr = list(self.refConv.anyRef2Real(entr, refOfTxt)) + els.append( {'name':name.lower(), 'model':fitElectrodeModelToLength(targ, entr), 'target': targ, 'entry':entr} ) + else: + print "Invalid lines in electrode txt file : %s, %s, %s"%(repr(name), repr(targ), repr(entr)) + except: + pass + + refId = self.preReferential().uuid() + return (refId, els) + + + def loadElectrodes(self, patient=None): + """Load electrode implantation (if already entered) from BrainVisa or from a file""" + path = None + #import pdb;pdb.set_trace() + if patient is not None: + rdi = ReadDiskItem( 'Electrode implantation', 'Electrode Implantation format', requiredAttributes={'subject':patient['subject'], 'center':patient['center']} ) + elecs = list(rdi._findValues( {}, None, False ) ) + if len(elecs) == 1: + path = elecs[0].fileName() + elif len(elecs) > 1: + print "CAREFUL : more than one electrode implantation are available, strange -> load the first found one" # TODO Dialogue de choix + path = elecs[0].fileName() + else: # No implantation available + print "no electrode implantation found" + return + if not path: + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open electrode implantation", "", "All implantations(*.elecimplant *.pts *.txt);;Electrode implantation (*.elecimplant);;PTS file (*.pts);;Electrode.txt (*.txt)")) + + if not path: + return + # Check if we have a PTS/TXT/elecimplant file + extension = os.path.splitext(path)[1].lower() + els = [] + refId = None + if extension == '.elecimplant': + filein = open(path, 'rb') + try: + dic = json.loads(filein.read()) + except: + filein.close() + filein = open(path, 'rb') + dic = pickle.load(filein) + + filein.close() + els = dic['electrodes'] + refId = dic['ReferentialUuid'] + + elif extension == '.txt': + (refId, els) = self.loadElectrodeTXT(path) # Verifier que c'est un electrode.txt, si c'est un electrode_Pos ou electrode_Name on peut zapper ? + elif extension == '.pts': + (refId, els) = self.loadPTS(path) + # Demander le référentiel, ou deviner si le nom contient _MNI ? + else: + print "file format unknown : %s !"%extension + QtGui.QMessageBox.warning(self, u'Erreur', u"the file format has not been recognized : %s"%extension) + + if refId != self.preReferential().uuid(): + print "CAREFUL: electrodes load are defined in an other referential that the one of the T1 pre, problem possible !" + #indices = [3,7,11, 0,1,2, 4,5,6, 8,9,10] + #if dic['2mni'] is not None and 'T1pre' not in self.transf2Mni: + #trsf = dic['2mni'] + #self.transf2Mni['T1pre'] = self.a.createTransformation([trsf[i] for i in indices], self.preReferential(), self.mniReferential()) + for e in els: + self.addElectrode(e['name'], e['model'], e['target'], e['entry'], refId) + + + def saveElectrodes(self): + """Save electrode implantation in BrainVisa Database""" + # Saving : electrode model, name, target and entry point + els = [dict((k,el[k]) for k in ['name', 'target', 'entry', 'model']) for el in self.electrodes] + # Save Referential UID which is the base of electrode coordinates + refId = self.preReferential().uuid() + print 'Sauvegarde electrodes'+repr(els)+"\nReferential UUID : "+refId + path = None + di = None + if self.brainvisaPatientAttributes is not None: + wdi = WriteDiskItem( 'Electrode implantation', 'Electrode Implantation format' ) + di = wdi.findValue({'subject':self.brainvisaPatientAttributes['subject'], 'center':self.brainvisaPatientAttributes['center']} ) + if not di: + print "Cannot find a valid path to store the electrode implantation for the current patient !" + QtGui.QMessageBox.warning(self, u'Erreur', u"Cannot find a valid path to store the electrode implantation for the current patient !") + else: + path = di.fileName() + createItemDirs(di) + if not path: + path = str(QtGui.QFileDialog.getSaveFileName(self, "Save electrode implantation", "", "Electrode implantation (*.elecimplant)")) + if not path: + return + # If there is no extension, add the standard one ! + + if os.path.splitext(path)[1] == '': + path = path+'.elecimplant' + + plotsT1preRef = self.getAllPlotsCentersT1preRef() + info_plotsT1Ref= [] + for k,v in plotsT1preRef.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plotsT1Ref.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v.list())) + #plots_label[k]=(label,label_name) + + plotsT1Ref_sorted = sorted(info_plotsT1Ref, key=lambda plot_number: plot_number[0]) + #previous_data.update({'plotsMNI':info_plotMNI}) + + fileout = open(path, 'wb') + fileout.write(json.dumps({'electrodes':els, 'ReferentialUuid':refId, '2mni':None, 'timestamp':time.time(),'plotsT1Nat':plotsT1Ref_sorted})) + #pickle.dump({'electrodes':els, 'ReferentialUuid':refId, '2mni':None, 'timestamp':time.time()}, fileout) + fileout.close() + if di is not None: + neuroHierarchy.databases.insertDiskItem( di, update=True ) + QtGui.QMessageBox.information(self, u'Implantation saved', u"Implantation has been saved in database. Careful, it deleted MNI information if there was any. you'll have to do the normalization again") + + def convertT1ScannerBasedToMni(self, points): + """Converts an array of points [x,y,z] in scanner-based coords to MNI coords if deformation field is available""" + field = self.getT1preMniTransform() + if field is None: + print "MNI deformation field not found" + return None + #pdb.set_trace() + tmpOutput = getTmpFilePath('csv') + arr = numpy.asarray(points)#([ [1,2,3], [4,5,6], [7,8,9] ]) + numpy.savetxt(tmpOutput, arr, delimiter=",") + matlabRun(spm_normalizePoints % ("'"+self.spmpath+"'",field, tmpOutput, tmpOutput)) + out = numpy.loadtxt(tmpOutput, delimiter=",") + #pdb.set_trace() + os.remove(tmpOutput) + + if numpy.array_equal(out, arr): + print "Points to MNI : Error, result read is identical to input" + return None + if out.shape != arr.shape: + print "Points to MNI : Error, result (%s) has not the same number of elements as input (%s)"%(repr(out),repr(arr)) + return None + return out.tolist() + + # Non blocking wrapper of getAllPlotsCentersMNIRef + def getAllPlotsCentersMNIRefNB(self, plots, toKeep=None): + """ Computes the MNI coordinates of plots from t1 pre scanner-based coordinaotes in a thread (non-blocking) + then call finishAllPlotsCentersMNIRef with the toKeep elements : these will determine how the data is saved + + """ + pe = PythonExecutor(lambda myself=self, thePlots=plots: myself.getAllPlotsCentersMNIRef(thePlots), toKeep=toKeep) + self.threads.append(pe) + # Remove it from the list of threads when finished + pe.finished.connect(lambda th=pe:self.finishAllPlotsCentersMNIRef(th)) + pe.start() + + + def finishAllPlotsCentersMNIRef(self, thread): + """ Callback function when MNI coordinates of plots are computed. Will save to basepath + or to provided diskItems (in 'kept' objects of the thread - which must be a PythonExecutor) + """ + plotsMNI = thread.output() + kept = thread.kept() + try: + self.threads.remove(thread) + except: + pass + if plotsMNI is None: + QtGui.QMessageBox.information(self, u'Implantation sauvegardée', u"Implantation has been exported in PTS/TXT file formats in database\nMNI normalization failed !.") + return + + if 'basepath' in kept:# custom path + self.saveTXT(path=kept['basepath']+'_MNI.txt', referential='MNI') + self.savePTS(path=kept['basepath']+'_MNI.pts', referential='MNI') + elif all (k in kept for k in ('wdiptsmni','timestamp','wditxtmnipos', 'wditxtmniname')): # find and save in DB + try: + self.savePTS(path = kept['wdiptsmni'].fullPath(), contacts = plotsMNI) + kept['wdiptsmni'].setMinf('referential', self.mniReferentialId()) + kept['wdiptsmni'].setMinf('timestamp', kept['timestamp']) + neuroHierarchy.databases.insertDiskItem(kept['wdiptsmni'], update=True ) + self.saveTXT(pathPos=kept['wditxtmnipos'].fullPath(), pathName=kept['wditxtmniname'].fullPath(), contacts = plotsMNI) + neuroHierarchy.databases.insertDiskItem(kept['wditxtmniname'], update=True ) + kept['wditxtmnipos'].setMinf('referential', self.mniReferentialId()) + kept['wditxtmnipos'].setMinf('timestamp', kept['timestamp']) + neuroHierarchy.databases.insertDiskItem(kept['wditxtmnipos'], update=True ) + except: + QtGui.QMessageBox.information(self, u'Implantation sauvegardée', u"Implantation has been exported in PTS/TXT file formats in database\nThe saving of the MNI normalization failed.") + return + else: + print "Erreur lors de l'exportation PTS/TXT dans le référentiel MNI" + QtGui.QMessageBox.information(self, u'Implantation sauvegardée', u"Implantation has been exported in PTS/TXT file formats in database\nMNI normalization failed.") + return + + QtGui.QMessageBox.information(self, u'Implantation sauvegardée', u"Implantation has been exported in PTS/TXT file formats in database\nMNI normalization has been applied") + + #add to the elecimplant file + rdi = ReadDiskItem( 'Electrode implantation', 'Electrode Implantation format' ,requiredAttributes={'center':self.brainvisaPatientAttributes['center'],'subject':self.brainvisaPatientAttributes['subject']}) + di=rdi.findValues({},None,False) + ldi = list(rdi.findValues({},None,False)) + + if len(ldi) >0: + if (os.path.exists(str(ldi[0]))): + filein = open(str(ldi[0]), 'rb') + try: + previous_data = json.loads(filein.read()) + except: + filein.close() + filein = open(str(ldi[0]), 'rb') + previous_data = pickle.load(filein) + + filein.close() + + info_plotMNI= [] + for k,v in plotsMNI.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plotMNI.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v)) + #plots_label[k]=(label,label_name) + + plotMNI_sorted = sorted(info_plotMNI, key=lambda plot_number: plot_number[0]) + previous_data.update({'plotsMNI':info_plotMNI}) + + #resave as json file + fout = open(str(ldi[0]),'w') + fout.write(json.dumps(previous_data)) + fout.close() + #pdb.set_trace() + neuroHierarchy.databases.insertDiskItem([x for x in di][0], update=True ) + print ".elecimplant done with MNI" + + print("start generate dictionaries") + self.parcelsExportElectrodes(Callback=lambda:[self.marsatlasExportResection(),self.exportCSVdictionaries(),self.generateMappingContactCortex(),self.generateTemplateBipoleStimulationFile(),self.screenshot(),self.makeMP4(),self.calculParcel()]) + + # Normalize the coordinates and export them in PTS format and TXT format + def normalizeExportElectrodes(self, saveInDB=True): + timestamp = time.time() + plots = self.getAllPlotsCentersT1preScannerBasedRef() + if not saveInDB: # Choose the output file name + basepath = str(QtGui.QFileDialog.getSaveFileName(self, 'Choose a file name for exported files', "", "Electrode implantation TXT files (*.txt)")) + if not basepath: + return + basepath = os.path.splitext(basepath)[0] + self.saveTXT(path=basepath+'.txt', contacts=plots) + self.savePTS(path=basepath+'.pts', contacts=plots) + plotsMNI = self.getAllPlotsCentersMNIRefNB(plots, toKeep={'basepath':basepath}) + return + else: # Find the right places in the Database + # T1-pre scanner-based referential + wdipts = WriteDiskItem('Electrode Implantation PTS', 'PTS format', requiredAttributes={'no_ref_name':'True'}).findValue(self.diskItems['T1pre'])#,_debug= sys.stdout requiredAttributes={'ref_name':'default'} + wditxtpos = WriteDiskItem('Electrode Implantation Position TXT', 'Text file', requiredAttributes={'no_ref_name':'True'}).findValue(self.diskItems['T1pre']) + wditxtname = WriteDiskItem('Electrode Implantation Name TXT', 'Text file', requiredAttributes={'no_ref_name':'True'}).findValue(self.diskItems['T1pre']) + if wdipts is None or wditxtpos is None or wditxtname is None: + print "Cannot find a path to save PTS or TXT files in the database !" + return + if plots is None: + print "Cannot get the scanner-based plots coords" + return + self.savePTS(path = wdipts.fullPath(), contacts=plots) + wdipts.setMinf('referential', self.t1pre2ScannerBasedId) + wdipts.setMinf('timestamp', timestamp) + neuroHierarchy.databases.insertDiskItem(wdipts, update=True ) + self.saveTXT(pathPos=wditxtpos.fullPath(), pathName=wditxtname.fullPath(), contacts=plots) + neuroHierarchy.databases.insertDiskItem(wditxtname, update=True ) + wditxtpos.setMinf('referential', self.t1pre2ScannerBasedId) + wditxtpos.setMinf('timestamp', timestamp) + neuroHierarchy.databases.insertDiskItem(wditxtpos, update=True ) + + # MNI referential + if self.getT1preMniTransform() is None: + QtGui.QMessageBox.information(self, u'Implantation sauvegardée', u"Implantation has been exported in PTS/TXT file formats in database\nMNI normlization is not available (not found in database).") + return + wdiptsmni = WriteDiskItem('Electrode Implantation PTS', 'PTS format', requiredAttributes={'ref_name':'MNI'}).findValue(self.diskItems['T1pre']) + wditxtmnipos = WriteDiskItem('Electrode Implantation Position TXT', 'Text file', requiredAttributes={'ref_name':'MNI'}).findValue(self.diskItems['T1pre']) + wditxtmniname = WriteDiskItem('Electrode Implantation Name TXT', 'Text file', requiredAttributes={'ref_name':'MNI'}).findValue(self.diskItems['T1pre']) + if wdiptsmni is None or wditxtmnipos is None or wditxtmniname is None: + print "Cannot find a path to save MNI PTS or TXT files in the database !" + else: + plotsMNI = self.getAllPlotsCentersMNIRefNB(plots, toKeep={'wdiptsmni':wdiptsmni, 'timestamp':timestamp, 'wditxtmnipos':wditxtmnipos, 'wditxtmniname':wditxtmniname}) + + # AC-PC referential + if self.refConv.isRefAvailable('AC-PC'): + wdiptsacpc = WriteDiskItem('Electrode Implantation PTS', 'PTS format', requiredAttributes={'ref_name':'ACPC'}).findValue(self.diskItems['T1pre']) + if wdiptsacpc is None: + print "Cannot find a path to save AC-PC PTS file in the database !" + else: + plotsACPC = self.getAllPlotsCentersAnyReferential('AC-PC') + self.savePTS(path = wdiptsacpc.fullPath(), contacts=plotsACPC) + wdiptsacpc.setMinf('referential', 'AC-PC') + wdiptsacpc.setMinf('timestamp', timestamp) + neuroHierarchy.databases.insertDiskItem(wdiptsacpc, update=True ) + + #return + + #print("start generate dictionaries") + #self.marsatlasExportElectrodes(Callback=lambda:[self.marsatlasExportResection(),self.exportCSVdictionaries(),self.generateMappingContactCortex()]) + + def generateDictionaries(self): + + if self.generateDictionariesComboBox.currentIndex()==1: + self.parcelsExportElectrodes() + elif self.generateDictionariesComboBox.currentIndex()==0: + #Pour que l'exportResection et l'exportCSVdictionaries attendent que export electrodes soit fini + self.parcelsExportElectrodes(Callback=lambda:[self.marsatlasExportResection(),self.exportCSVdictionaries(),self.generateMappingContactCortex(),self.generateTemplateBipoleStimulationFile(),self.screenshot(),self.makeMP4(),self.calculParcel()]) + #self.marsatlasExportResection() + #self.exportCSVdictionaries() + elif self.generateDictionariesComboBox.currentIndex()==2: + self.marsatlasExportResection() + elif self.generateDictionariesComboBox.currentIndex()==3: + self.exportCSVdictionaries() + elif self.generateDictionariesComboBox.currentIndex()==4: + self.generateMappingContactCortex() + elif self.generateDictionariesComboBox.currentIndex()==5: + self.generateTemplateBipoleStimulationFile() + elif self.generateDictionariesComboBox.currentIndex()==6: + self.screenshot() + elif self.generateDictionariesComboBox.currentIndex()==7: + self.makeMP4() + elif self.generateDictionariesComboBox.currentIndex()==8: + self.calculParcel() + elif self.generateDictionariesComboBox.currentIndex()==9: + self.generateFiberContactDistance() + + def screenshot(self): + #Check if all the volumes are available. + #self.verifParcel allows us to know if the verification has already been made, in that case we won't do it again + Mask_left = ReadDiskItem('Left Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskleft = Mask_left.findValue(self.diskItems['T1pre']) + + Mask_right = ReadDiskItem('Right Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskright = Mask_right.findValue(self.diskItems['T1pre']) + + MaskGW_right = ReadDiskItem('Right Grey White Mask','Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskGW_right = MaskGW_right.findValue(self.diskItems['T1pre']) + + MaskGW_left = ReadDiskItem('Left Grey White Mask','Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskGW_left = MaskGW_left.findValue(self.diskItems['T1pre']) + + if diMaskleft is None or diMaskright is None or diMaskGW_right is None or diMaskGW_left is None : + #if a parcellation is missing we won't be able to make the screenshot, so we exit the function + print "No parcellisation found." + return + else: + #we take out the cursor + self.a.config()[ 'linkedCursor' ] = 0 + #and replace the electrodes realistic model with 2mm spheres, which are more visible + self.updateDispMode(2) + + #Right hemisphere + #opens an Anatomist window and loads the parcellation and the electrodes + w2=self.a.createWindow("Sagittal") + contWin=self.windowContent['IRM pre + MARS ATLAS right'] + content=[x for x in contWin if "rightMARSATLAS" in x] + ele=[x for x in contWin if "electrode" in x] + elec=self.dispObj[ele[0]] + for el in elec: + w2.addObjects(el) + image = self.dispObj[content[0]] + w2.addObjects(image) + time.sleep(1) + w2.windowConfig(snapshot="/tmp/"+self.brainvisaPatientAttributes['subject']+"RightHemiSagittal.png") + #rotates the view by 180° + w2.camera(view_quaternion=[-0.5, 0.5, 0.5, -0.5]) + #waits a second so that the window has the tame to be updated before the next screenshot, they are saved in the tmp repertory + time.sleep(1) + w2.windowConfig(snapshot="/tmp/"+self.brainvisaPatientAttributes['subject']+"RightHemiSagittalRot.png") + + w2.close() + + #Left hemisphere + w21=self.a.createWindow("Sagittal") + contWin=self.windowContent['IRM pre + MARS ATLAS left'] + content=[x for x in contWin if "leftMARSATLAS" in x] + ele=[x for x in contWin if "electrode" in x] + elec=self.dispObj[ele[0]] + for el in elec: + w21.addObjects(el) + image = self.dispObj[content[0]] + w21.addObjects(image) + time.sleep(1) + w21.windowConfig(snapshot="/tmp/"+self.brainvisaPatientAttributes['subject']+"LeftHemiSagittal.png") + w21.camera(view_quaternion=[-0.5, 0.5, 0.5, -0.5]) + time.sleep(1) + w21.windowConfig(snapshot="/tmp/"+self.brainvisaPatientAttributes['subject']+"LeftHemiSagittalRot.png") + w21.close() + + #puts the cursor back + self.a.config()[ 'linkedCursor' ] = 1 + #opens the pictures of the left and right brain which were taken previously + images1 = map(Image.open, ["/tmp/"+self.brainvisaPatientAttributes['subject']+"RightHemiSagittal.png", "/tmp/"+self.brainvisaPatientAttributes['subject']+"RightHemiSagittalRot.png"]) + images2 = map(Image.open, ["/tmp/"+self.brainvisaPatientAttributes['subject']+"LeftHemiSagittal.png","/tmp/"+self.brainvisaPatientAttributes['subject']+"LeftHemiSagittalRot.png"]) + + #calculates the width and height of the new picture we are going to make + widths1, heights1 = zip(*(i.size for i in images1)) + widths2, heights2 = zip(*(i.size for i in images2)) + + total_width1 = sum(widths1) + max_height1 = max(heights1) + total_width2 = sum(widths2) + max_height2 = max(heights2) + + #opens new empty images of the size calculated before + new_im1 = Image.new('RGB', (total_width1, max_height1)) + new_im2 = Image.new('RGB', (total_width2, max_height2)) + + #we are then going to paste the two images from right and left hemispheres together by the x axis + x_offset = 0 + for im in images1: + new_im1.paste(im, (x_offset,0)) + x_offset += im.size[0] + + new_im1.save('/tmp/associated1.png') + + x_offset = 0 + for im in images2: + new_im2.paste(im, (x_offset,0)) + x_offset += im.size[0] + + new_im2.save('/tmp/associated2.png') + + #pastes the two images obtained previously by the y axis + images = map(Image.open, ["/tmp/associated1.png","/tmp/associated2.png"]) + new_im=Image.new('RGB', (total_width1, max_height1*2)) + + y_offset = 0 + for im in images: + new_im.paste(im, (0,y_offset)) + y_offset += im.size[1] + + + new_im.save('/tmp/associated.png') + #verification that the path is creatable + wdi = WriteDiskItem('Screenshot of Mars Atlas','PNG image') + di=wdi.findValue(self.diskItems['T1pre']) + + if di is None: + print "Can't generate file" + return + else: + try: + os.mkdir(os.path.dirname(di.fullPath())) + #line0 = runCmd(cmd0) + except: + line0=1 + cmd1 = ['mv', '/tmp/associated.png', str(di.fullPath())] + line1 = runCmd(cmd1) + #updates the database with the image of the 2 views of the 2 parcellation + neuroHierarchy.databases.insertDiskItem(di, update=True ) + #puts back the realistic electrode model + self.updateDispMode(0) + + def makeMP4(self): + + + from brainvisa import quaternion + + #takes the voxel size of the T1 + volume = aims.read(str(self.diskItems['T1pre'])) + sizeT1=volume.getVoxelSize() + + #verification that a CT or MRI is present, if both are, we take the CT + T1post=None + diCT = ReadDiskItem( 'CT', 'BrainVISA volume formats', requiredAttributes={'center':self.brainvisaPatientAttributes['center'], 'subject':self.brainvisaPatientAttributes['subject'] } ) + path = list(diCT.findValues({}, None, False )) + #check if it is a CT post + + idCTpost = [x for x in range(len(path)) if 'CTpost' in str(path[x]) and not 'CTpostOp' in str(path[x])] + + try: + path=path[idCTpost[0]].fullPath() + volCT = aims.read(path) + npCT = volCT.arraydata() + PresCT = True + except: + diMRI = ReadDiskItem( 'Raw T1 MRI', 'BrainVISA volume formats', requiredAttributes={'center':self.brainvisaPatientAttributes['center'], 'subject':self.brainvisaPatientAttributes['subject'] } ) + pathMRI = list(diMRI.findValues({}, None, False )) + id_post = [x for x in range(len(pathMRI)) if 'post' in str(pathMRI[x]) and not 'postOp' in str(pathMRI[x])] + pathMRI=pathMRI[0].fullPath() + volCT = aims.read(pathMRI) + npCT = volCT.arraydata() + PresCT=False + if id_post!=[]: + T1post = pathMRI[id_post[0]] + + #if both CT and MRI are absent, we won't do the computation + + if T1post is None and idCTpost==[]: + warning = QtGui.QMessageBox(self) + warning.setText("No CT post or MRI post found") + warning.setWindowTitle("Warning") + return + + #finding the brainMask if there is one + try: + brainMask = ReadDiskItem('Brain Mask', 'aims readable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diBrain = list(brainMask.findValues({}, None, False )) + diBrain0=diBrain[0].fullPath() + volBrainMask = aims.read(diBrain0) + brainMaskArray = volBrainMask.arraydata() + except: + brainMaskArray=None + + #if the brainMask is present, the gif will be made taking only the brain tissues + if brainMaskArray is not None: + z=0 + while z0: + maxi=brainMaskArray[0,z,:,:].max() + if maxi != 0: + limit=round(z*sizeT1[2]) + z=0 + z-=1 + else: + i=1 + limit=npCT.shape[1] + + #Erase all previous files + os.system('find /tmp/gif*.png -type f -exec rm -f {} \;') + + #Take out the cursor + self.a.config()[ 'linkedCursor' ] = 0 + #put the realistic electrode model back + self.updateDispMode(2) + + #Electrodes GIF + #load the window + w21=self.a.createWindow("Axial") + w21.windowConfig(fullscreen=1) + #if it is a CT + if PresCT==True: + contWin=self.windowContent['CT post'] + content=[x for x in contWin if "CTpost" in x] + ele=[x for x in contWin if "electrode" in x] + #if it is an MRI + else: + contWin=self.windowContent['IRM post'] + content=[x for x in contWin if "T1post" in x] + ele=[x for x in contWin if "electrode" in x] + #add the image and electrodes + image = self.dispObj[content[0]] + elec=self.dispObj[ele[0]] + w21.addObjects(image) + for el in elec: + w21.addObjects(el) + #get all referentials + refs=self.a.getReferentials() + #choose the T1 pre referential... + for el in refs: + info=str(el.getInfos()) + if 'T1pre' in info and 'native' in info: + r1=el + #...and assign it + w21.assignReferential(r1) + #activate the clipping + self.a.execute('WindowConfig',windows = [w21],clipping=2,clip_distance=5.) + if brainMaskArray is None: + limit=npCT.shape[1] + #take pictures of slices following the z axis + snapShots=[] + while i16000: + volumeposition = [volumeposition[x] for x in range(len(volumeposition)) if x & 1 ==0] + + volumeposition=numpy.array(volumeposition) + (N, dd) = numpy.shape(volumeposition) + dd = float(dd) + + # Q will be our working array + Q = numpy.vstack([numpy.copy(volumeposition.T), numpy.ones(N)]) + QT = Q.T + + # initializations + err = 1.0 + tolerance + u = (1.0 / N) * numpy.ones(N) + + # Khachiyan Algorithm + while err > tolerance: + V = numpy.dot(Q, numpy.dot(numpy.diag(u), QT)) + M = numpy.diag(numpy.dot(QT , numpy.dot(numpy.linalg.inv(V), Q))) # M the diagonal vector of an NxN matrix + j = numpy.argmax(M) + maximum = M[j] + step_size = (maximum - dd - 1.0) / ((dd + 1.0) * (maximum - 1.0)) + new_u = (1.0 - step_size) * u + new_u[j] += step_size + err = numpy.linalg.norm(new_u - u) + u = new_u + + # center of the ellipse + center = numpy.dot(volumeposition.T, u) + + # the A matrix for the ellipse + AA = numpy.linalg.inv(numpy.dot(volumeposition.T, numpy.dot(numpy.diag(u), volumeposition)) - numpy.array([[a * b for b in center] for a in center])) / dd + + # Get the values we'd like to return + UU, ss, rotation = numpy.linalg.svd(AA) + radii = 1.0/numpy.sqrt(ss) + + return radii #UU, ss, rotation, center, + + + def calculParcel(self): + import copy + + infos={} + parcels={} + tailleG=0 + + #take the parcellations + Mask_left = ReadDiskItem('Left Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskleft = Mask_left.findValue(self.diskItems['T1pre']) + + Mask_right = ReadDiskItem('Right Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskright = Mask_right.findValue(self.diskItems['T1pre']) + + #take the parcels names in one list + parcels_names = readSulcusLabelTranslationFile('parcels_label_name.txt') + + try: + #transform the images to matrices + Maskleft = aims.read(diMaskleft.fullPath()) + npleftMarsAtlas = Maskleft.arraydata() + + Maskright = aims.read(diMaskright.fullPath()) + nprightMarsAtlas = Maskright.arraydata() + except: + print "No parcellation found" + return + #take voxel size of T1 pre + volume = aims.read(str(self.diskItems['T1pre'])) + sizeT1=volume.getVoxelSize() + + print 'verif done' + #pdb.set_trace() + #calculate the total volume of the parcels + for key, value in parcels_names.items(): + if value[0].lower()=='l': + parcel1 = numpy.where(npleftMarsAtlas == key) + else: + parcel1 = numpy.where(nprightMarsAtlas == key) + coord=zip(parcel1[1],parcel1[2],parcel1[3]) + tailleG+=len(coord) + + print 'tailleG Done' + + t=1 + #we do the computations for each parcel + for key, value in parcels_names.items(): + print 'doing parcel ' ,value ,t + t+=1 + par=0 + #we locate the parcel in the right or left hemispheres (if they begin with 'L':left, 'R':right) + if value[0].lower()=='l': + parcel1 = numpy.where(npleftMarsAtlas == key) + try: + #we take only the parcel + parcel=copy.deepcopy(npleftMarsAtlas[0,parcel1[1].min():parcel1[1].max()+1,parcel1[2].min():parcel1[2].max()+1,parcel1[3].min():parcel1[3].max()+1]) + except: + #if the parcel is absent we update it with the value 'not found' + print 'no parcel found' + parcels.update({value:"not found"}) + par=None + else: + parcel1 = numpy.where(nprightMarsAtlas == key) + try: + parcel=copy.deepcopy(nprightMarsAtlas[0,parcel1[1].min():parcel1[1].max()+1,parcel1[2].min():parcel1[2].max()+1,parcel1[3].min():parcel1[3].max()+1]) + except: + print 'no parcel found' + parcels.update({value:"not found"}) + par=None + #if the parcel has been computed + if par is not None: + #take the coordinates of the points + coord=zip(parcel1[1],parcel1[2],parcel1[3]) + #volume of the parcel + taille=len(coord) + infos.update({"volume":int(taille)}) + parcelPositionN=[] + parcelPositionNT=[] + parcelPosition = [[round(parcel1[1][i]*sizeT1[2]),round(parcel1[2][i]*sizeT1[1]),round(parcel1[3][i]*sizeT1[0])] for i in range(len(parcel1[1]))] + i=0 + #we take one over 3 values (downsampling by 3) + while i10000: + downSamp=int(math.ceil(float(len(parcelPositionN))/10000)) + while d0: + meshFSRight = aims.read(str(diFSWhite[indexFSWhiteRight[0]])) + meshFSLeft = aims.read(str(diFSWhite[indexFSWhiteLeft[0]])) + + #get plots information + plots = self.getAllPlotsCentersT1preRef() #coordonnées en mm à convertir en voxel + if len(plots)==0: + print("no contact found") + return + + print "start matching contacts with vertexes" + + info_plot= [] + for k,v in plots.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plot.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v)) + #plots_label[k]=(label,label_name) + + plot_sorted = sorted(info_plot, key=lambda plot_number: plot_number[0]) + + #montage bipolaire + info_plot_bipolaire= [] + for pindex in range(1,len(plot_sorted)): + previous_contact = "".join([i for i in plot_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plot_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plot_bipolaire.append((plot_sorted[pindex][0]+' - '+ plot_sorted[pindex-1][0],(plot_sorted[pindex][1]+plot_sorted[pindex-1][1])/2 )) + + #here I have to calculate distances: vertex to each contacts. + meshRight_vertex_np = numpy.array(meshRight.vertex()) + meshLeft_vertex_np = numpy.array(meshLeft.vertex()) + + meshFSRight_vertex_np = numpy.array(meshFSRight.vertex()) + meshFSLeft_vertex_np = numpy.array(meshFSLeft.vertex()) + + dist_contact_meshRight = {} + dist_contact_meshLeft = {} + + #coordonnées longitude et latitude marsAtlas + wdi_longitude = ReadDiskItem( 'Longitude coordinate texture', 'aims Texture formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol} ) + di_longitude = list(wdi_longitude.findValues({},None,False)) + wdi_latitude = ReadDiskItem( 'Latitude coordinate texture', 'aims Texture formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol} ) + di_latitude = list(wdi_latitude.findValues({},None,False)) + + indexLongRight = [i for i in range(len(di_longitude)) if 'pre' in di_longitude[i].fullPath() and 'Rwhite' in di_longitude[i].fullPath()] + indexLongLeft = [i for i in range(len(di_longitude)) if 'pre' in di_longitude[i].fullPath() and 'Lwhite' in di_longitude[i].fullPath()] + + indexLatRight = [i for i in range(len(di_latitude)) if 'pre' in di_latitude[i].fullPath() and 'Rwhite' in di_latitude[i].fullPath()] + indexLatLeft = [i for i in range(len(di_latitude)) if 'pre' in di_latitude[i].fullPath() and 'Lwhite' in di_latitude[i].fullPath()] + + MatLongLeft = aims.read(di_longitude[indexLongLeft[0]].fullPath()) + MatLatLeft = aims.read(di_latitude[indexLatLeft[0]].fullPath()) + + MatLongRight = aims.read(di_longitude[indexLongRight[0]].fullPath()) + MatLatRight = aims.read(di_latitude[indexLatRight[0]].fullPath()) + + if len(diFSWhite)>0: + FSThickRight = aims.read(diAllFSThick[indexThickRight[0]].fullPath()) + FSTHickLeft = aims.read(diAllFSThick[indexThickLeft[0]].fullPath()) + + import copy + for ii in range(len(plot_sorted)): + + print "{} on {}".format(ii+1,len(plot_sorted)) + + np_plot = numpy.array(plot_sorted[ii][1]) + diffRight = meshRight_vertex_np - np_plot #la je sais pas si il y en a pas un en voxel et un en mm. + diffLeft = meshLeft_vertex_np - np_plot + if len(diFSWhite)>0: + diffFSRight = meshFSRight_vertex_np - np_plot + diffFSLeft = meshFSLeft_vertex_np - np_plot + + + distRight = [numpy.linalg.norm(diffRight[i]) for i in range(len(diffRight))] + distLeft = [numpy.linalg.norm(diffLeft[i]) for i in range(len(diffLeft))] + if len(diFSWhite)>0: + distFSRight = [numpy.linalg.norm(diffFSRight[i]) for i in range(len(diffFSRight))] + distFSLeft = [numpy.linalg.norm(diffFSLeft[i]) for i in range(len(diffFSLeft))] + + + #it's too big, I should keep only the indexes of the one nearest than 2 times SizeHorizon + indexvertexLeft = numpy.where(numpy.array(distLeft) numpy.array(distLeft).min(): + MarsAtlasCoordinate = ('L',MatLatLeft[0][distLeft.index(numpy.array(distLeft).min())],MatLongLeft[0][distLeft.index(numpy.array(distLeft).min())]) + pdb.set_trace() + if len(diFSWhite)>0: + ValueThickness = FSTHickLeft[0][distFSLeft.index(numpy.array(distFSLeft).min())] + ValueThickness = (ValueThickness,) + else: + ValueThickness = (0,) + MarsAtlasCoordinate = MarsAtlasCoordinate + ValueThickness + elif numpy.array(distRight).min() < numpy.array(distLeft).min(): + MarsAtlasCoordinate = ('R',MatLatRight[0][distRight.index(numpy.array(distRight).min())],MatLongRight[0][distRight.index(numpy.array(distRight).min())]) + if len(diFSWhite)>0: + ValueThickness = FSThickRight[0][distFSRight.index(numpy.array(distFSRight).min())] + ValueThickness = (ValueThickness,) + else: + ValueThickness = (0,) + MarsAtlasCoordinate = MarsAtlasCoordinate + ValueThickness + + pdb.set_trace() + + + pdb.set_trace() + #test2 = [i for i in range(len(dist_contact_mesh1[1])) if dist_contact_mesh1[1][i] <= SizeHorizon] + + + #generate the texture + #textureContacts = aims.TimeTexture() + print "contacts vertexes matching done" + + + + + + + def exportCSVdictionaries(self): + + #test si eleclabel et resection sont générés + #il faut au moins eleclabel, si pas resection pas grave + + #eleclabel + rdi_eleclabel=ReadDiskItem('Electrodes Labels','Electrode Label Format',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + wdi_eleclabel=list(rdi_eleclabel.findValues({},None,False)) + + #reseclabel + rdi_reseclabel=ReadDiskItem('Resection Description','Resection json',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + wdi_reseclabel=list(rdi_reseclabel.findValues({},None,False)) + + wdi = WriteDiskItem('Final Export Dictionaries','CSV file') + di=wdi.findValue(self.diskItems['T1pre']) + + if len(wdi_eleclabel)==0: + print('no ...') + else: + di_eleclabel=rdi_eleclabel.findValue(self.diskItems['T1pre']) + + fin = open(di_eleclabel.fullPath(),'r') + info_label_elec = json.loads(fin.read()) + fin.close() + + plots = self.getAllPlotsCentersT1preScannerBasedRef() + + #look for mni position, are there already calculated ? + rdi_elecimplant = ReadDiskItem( 'Electrode implantation', 'Electrode Implantation format',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + impl = list(rdi_elecimplant.findValues({},None,False)) + + if len(impl) == 0: + print "Cannot find implantation" + plotsMNI = self.getAllPlotsCentersMNIRef(plots) + info_plotMNI= [] + for k,v in plotsMNI.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plotMNI.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v)) + + elif os.path.exists(str(impl[0])): + filein = open(str(impl[0]), 'rb') + try: + dic_impl = json.loads(filein.read()) + except: + filein.close() + filein = open(str(impl[0]), 'rb') + dic_impl = pickle.load(filein) + + filein.close() + + if 'plotsMNI' in dic_impl.keys(): + print "MNI position already estimated, ok" + plot_dict_MNIinter = dict(dic_impl['plotsMNI']) + info_plotMNI = [(k, v) for k, v in plot_dict_MNIinter.iteritems()] + + else: + plotsMNI = self.getAllPlotsCentersMNIRef(plots) + + info_plotMNI= [] + for k,v in plotsMNI.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plotMNI.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v)) + #plots_label[k]=(label,label_name) + + plotMNI_sorted = sorted(info_plotMNI, key=lambda plot_number: plot_number[0]) + + #montage bipolaire + info_plotMNI_bipolaire= [] + for pindex in range(1,len(plotMNI_sorted)): + previous_contact = "".join([i for i in plotMNI_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plotMNI_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plotMNI_bipolaire.append((plotMNI_sorted[pindex][0]+' - '+ plotMNI_sorted[pindex-1][0],(numpy.array(plotMNI_sorted[pindex][1])+numpy.array(plotMNI_sorted[pindex-1][1]))/2 )) + + plotMNI_sorted=dict(plotMNI_sorted) + info_plotMNI_bipolaire=dict(info_plotMNI_bipolaire) + + + plotsSB = self.getAllPlotsCentersT1preScannerBasedRef() + info_plotSB = [] + for k,v in plotsSB.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plotSB.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v)) + + plotSB_sorted = sorted(info_plotSB, key=lambda plot_number:plot_number[0]) + + #montage bipolaire + info_plotSB_bipolaire = [] + for pindex in range(1,len(plotSB_sorted)): + previous_contact = "".join([i for i in plotSB_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plotSB_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plotSB_bipolaire.append((plotSB_sorted[pindex][0]+' - '+ plotSB_sorted[pindex-1][0],(numpy.array(plotSB_sorted[pindex][1])+numpy.array(plotSB_sorted[pindex-1][1]))/2 )) + + plotSB_sorted=dict(plotSB_sorted) + info_plotSB_bipolaire=dict(info_plotSB_bipolaire) + + + with open(di.fullPath(), 'w') as csvfile: + #fieldnames=['MarsAtlas','GreyWhite','Resection'] + writer = csv.writer(csvfile, delimiter='\t') + writer.writerow([u'Contacts Positions']) + writer.writerow([u'Use of MNI Template','MarsAtlas',info_label_elec['Template']['MarsAtlas'],'Freesurfer',info_label_elec['Template']['Freesurfer'],'HippoSubfieldFreesurfer',info_label_elec['Template']['HippocampalSubfield Freesurfer']]) + + #add a row with "MNI or Patient for MarsAtlas and Freesurfer + list_to_write = set(info_label_elec['plots_label'][info_label_elec['plots_label'].keys()[0]].keys()) + list_by_default = set([u'contact','MarsAtlas','MarsAtlasFull', 'Freesurfer', 'Hippocampal Subfield','GreyWhite','AAL', 'AALDilate', 'Broadmann', 'BroadmannDilate', 'Hammers', 'Resection', 'MNI','T1pre Scanner Based']) + diff_list = list(list_to_write.difference(list_by_default)) + full_list = [u'contact','MarsAtlas','MarsAtlasFull', 'Freesurfer', 'Hippocampal Subfield','GreyWhite', 'ALL', 'AALDilate', 'Broadmann','BroadmannDilate', 'Hammers', 'Resection', 'MNI','T1pre Scanner Based'] + full_list.extend(diff_list) + writer.writerow(full_list) + + #pdb.set_trace() + dict_sorted_tmp = OrderedDict(sorted(info_label_elec['plots_label'].items())) + + for kk,vv in dict_sorted_tmp.iteritems(): + listwrite = [kk] + listwrite.append(vv['MarsAtlas'][1]) + listwrite.append(vv['MarsAtlasFull']) + listwrite.append(vv['Freesurfer'][1]) + listwrite.append(vv['Hippocampal Subfield'][1]) + listwrite.append(vv['GreyWhite'][1]) + listwrite.append(vv['AAL'][1]) + listwrite.append(vv['AALDilate'][1]) + listwrite.append(vv['Broadmann'][1]) + listwrite.append(vv['BroadmannDilate'][1]) + listwrite.append(vv['Hammers'][1]) + listwrite.append(vv['Resection'][1]) + #[listwrite.append(x[1]) for x in vv.values()] + listwrite.append([float(format(plotMNI_sorted[kk][i],'.3f')) for i in range(3)]) + listwrite.append([float(format(plotSB_sorted[kk][i],'.3f')) for i in range(3)]) + if len(full_list)>12: + for i_supp in range(len(full_list)-14): + listwrite.append(vv[full_list[14+i_supp]]) + writer.writerow(listwrite) + + writer.writerow([]) + writer.writerow([]) + + dict_sorted_tmp = OrderedDict(sorted(info_label_elec['plots_label_bipolar'].items())) + + for kk,vv in dict_sorted_tmp.iteritems(): + #pdb.set_trace() + listwrite = [kk] + listwrite.append(vv['MarsAtlas'][1]) + listwrite.append(vv['MarsAtlasFull']) + listwrite.append(vv['Freesurfer'][1]) + listwrite.append(vv['Hippocampal Subfield'][1]) + listwrite.append(vv['GreyWhite'][1]) + listwrite.append(vv['AAL'][1]) + listwrite.append(vv['AALDilate'][1]) + listwrite.append(vv['Broadmann'][1]) + listwrite.append(vv['BroadmannDilate'][1]) + listwrite.append(vv['Hammers'][1]) + listwrite.append(vv['Resection'][1]) + #[listwrite.append(x[1]) for x in vv.values()] + listwrite.append([float(format(info_plotMNI_bipolaire[kk][i],'.3f')) for i in range(3)]) + listwrite.append([float(format(info_plotSB_bipolaire[kk][i],'.3f')) for i in range(3)]) + if len(full_list)>12: + for i_supp in range(len(full_list)-14): + listwrite.append(vv[full_list[14+i_supp]]) + writer.writerow(listwrite) + + writer.writerow([]) + writer.writerow([]) + + if len(wdi_reseclabel)==0: + print('no ...') + else: + di_reseclabel = rdi_reseclabel.findValue(self.diskItems['T1pre']) + fin = open(di_reseclabel.fullPath(),'r') + info_label_resec = json.loads(fin.read()) + fin.close() + + with open(di.fullPath(), 'a') as csvfile: + writer = csv.writer(csvfile, delimiter='\t') + writer.writerow([u'Resection Information']) + #pdb.set_trace() + for kk,vv in info_label_resec.iteritems(): + #writer.writerow([kk]) + if type(vv) == type(float()): + listwrite = [kk,format(vv,'.1f')] + writer.writerow(listwrite) + else: + writer.writerow([kk]) + for ll,bb in vv.iteritems(): + listwrite = [ll, format(float(bb[1]),'.1f')] + writer.writerow(listwrite) + + neuroHierarchy.databases.insertDiskItem(di, update=True ) + print "export csv done" + + + #wdi = WriteDiskItem('PatientInfoTemplate','Patient Template format') + #di = wdi.findValue(self.diskItems['T1pre']) + + def marsatlasExportResection(self): + + wdi_resec = ReadDiskItem('Resection', 'NIFTI-1 image', requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + di_resec = list(wdi_resec.findValues({}, None, False )) + + if len(di_resec)==0: + print('no resection image found') + return + + Mask_left = ReadDiskItem('Left Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskleft = Mask_left.findValue(self.diskItems['T1pre']) + + Mask_right = ReadDiskItem('Right Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskright = Mask_right.findValue(self.diskItems['T1pre']) + + FreesurferMask = ReadDiskItem('FreesurferAtlas', 'BrainVISA volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diFreesurferMask = list(FreesurferMask.findValues({}, None, False )) + + if diMaskleft is None: + print('left gyri volume failed, perform export mars atlas export contact first') + #return + else: + vol_left = aims.read(diMaskleft.fileName()) + + if diMaskright is None: + print('right gyri volume failed, perform export mars atlas export contact first') + #return + else: + vol_right = aims.read(diMaskright.fileName()) + + Vol_resec = aims.read(di_resec[0].fileName()) + + + Vox_size_resection = Vol_resec.getVoxelSize().arraydata() + Vol_resection_mm = Vol_resec.arraydata().sum()*Vox_size_resection.prod() #choppe les trois premiers + + #intersection avec mars atlas label + if diMaskleft is not None and diMaskright is not None: + Vol_mask_tot = vol_left.arraydata()+vol_right.arraydata() + + inter_resec_mars_atlas = numpy.multiply(Vol_resec.arraydata(),Vol_mask_tot) + label_resec_mars_atlas = numpy.histogram(inter_resec_mars_atlas,bins = 255, range = (0,255)) + total_label_mars_atlas = numpy.histogram(Vol_mask_tot,bins = 255) + percent_resec_mars_atlas = numpy.divide(label_resec_mars_atlas[0],total_label_mars_atlas[0],dtype=float)*100 + non_zero_inter = numpy.add(numpy.nonzero(label_resec_mars_atlas[0][1:-1]),1) + + parcels_names = readSulcusLabelTranslationFile('parcels_label_name.txt') + + #pdb.set_trace() + list1 = [parcels_names[label_resec_mars_atlas[1][x]] for x in non_zero_inter.tolist()[0]] + list2 = [(label_resec_mars_atlas[1][x],percent_resec_mars_atlas[x]) for x in non_zero_inter.tolist()[0]] + resection_mars_atlas_info = dict(zip(list1,list2)) #{parcels_names[label_resec_mars_atlas[1][x]]:(label_resec_mars_atlas[1][x],percent_resec_mars_atlas[x]) for x in non_zero_inter.tolist()[0]} + + else: + resection_mars_atlas_info = {"MarsAtlas not calculated":[0,0]} + + if len(diFreesurferMask)>0: + vol_FS = aims.read(diFreesurferMask[0].fileName()) + inter_resec_FS = numpy.multiply(Vol_resec.arraydata(),vol_FS.arraydata()) + label_resec_FS = numpy.histogram(inter_resec_FS,bins = 20000, range = (0,20000)) + total_label_FS = numpy.histogram(vol_FS.arraydata(),bins = 20000, range = (0,20000)) + percent_resec_FS = numpy.divide(label_resec_FS[0],total_label_FS[0],dtype=float)*100 + #we keep only value between 1 and 100 to not display the thousands freesurfer parcels... + interesting_percent_resec_FS = numpy.where((percent_resec_FS >1) & (percent_resec_FS < 100)) + + parcels_names_FS = readFreesurferLabelFile('freesurfer_label.txt') + + list1 = [parcels_names_FS[unicode(x)][0] for x in interesting_percent_resec_FS[0]] + list2 = [(float(x),percent_resec_FS[x]) for x in interesting_percent_resec_FS[0]] + + resection_freesurfer_info = dict(zip(list1,list2)) + + else: + resection_freesurfer_info = {"Freesurfer not calculated": [0,0]} + + #write into database + wdi = WriteDiskItem('Resection Description','Resection json') + di = wdi.findValue(self.diskItems['Resection']) + if di is None: + print('Can t generate files') + return + + fout = open(di.fullPath(),'w') + fout.write(json.dumps({'mars_atlas':resection_mars_atlas_info,'Volume resection (mm3): ':Vol_resection_mm,'Freesurfer':resection_freesurfer_info})) #ici il faut ajouter l'ajout de la key volume mais je sais pas pourquoi des fois ca fait planter l'export en csv + fout.close() + + neuroHierarchy.databases.insertDiskItem(di, update=True ) + + print "export resection info done" + + + + def parcelsExportElectrodes(self, saveInDBmarsatlas = True, Callback = None): + + #check presence of marsatlas data + + LeftGyri = ReadDiskItem('hemisphere parcellation texture','Aims texture formats',requiredAttributes={ 'side': 'left' ,'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol, 'parcellation_type':'marsAtlas' }) + #LeftGyri = list(LeftGyri.findValues({}, None, False )) + LeftGyri = LeftGyri.findValue(self.diskItems['T1pre']) + + #check the presence of freesurfer data + freesurferdi = ReadDiskItem('FreesurferAtlas', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.brainvisaPatientAttributes['subject'] }) + rdi_freesurfer = list(freesurferdi.findValues({}, None, False )) + + #check the presence of Hippo subfield freesurfer data + HippoSubfielddi = ReadDiskItem('HippoFreesurferAtlas', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.brainvisaPatientAttributes['subject'] }) + rdi_HippoSubfield = list(HippoSubfielddi.findValues({},None,False)) + + #if either marsatlas and freesurfer are not found. stop (for now but later has to go throw the MNI) + if LeftGyri is None: + print('no hemisphere parcellation texture found') + TemplateMarsAtlas = True + #return + else: + TemplateMarsAtlas = False + + if len(rdi_freesurfer) == 0: + print('no freesurfer atlas found') + TemplateFreeSurfer = True + else: + TemplateFreeSurfer = False + + if len(rdi_HippoSubfield) == 0: + print('no hippo subfield atlas found') + TemplateHippoSubfieldFreesurfer = True + else: + TemplateHippoSubfieldFreesurfer = False + + + #if TemplateMarsAtlas or TemplateFreeSurfer or TemplateHippoSubfieldFreesurfer: #plus besoin de if vu qu'il faut maintenant forcément passer par le mni pour les atlas mni + rdi = ReadDiskItem( 'Electrode implantation', 'Electrode Implantation format',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + impl = list(rdi.findValues({},None,False)) + + if len(impl) == 0: + print "Cannot find implantation" + QtGui.QMessageBox.warning(self,"Error","Can't find implantation, you have to click on save and after on normalize/export to generate MNI position first") + return + elif os.path.exists(str(impl[0])): + filein = open(str(impl[0]), 'rb') + try: + dic_impl = json.loads(filein.read()) + except: + filein.close() + filein = open(str(impl[0]), 'rb') + dic_impl = pickle.load(filein) + + filein.close() + + if 'plotsMNI' in dic_impl.keys(): + print "MNI position already estimated, ok" + plot_dict_MNIinter = dict(dic_impl['plotsMNI']) + else: + print "you have to click on normalize/export to generate MNI position first" + QtGui.QMessageBox.warning(self,"Error","A template will have to be used, you have to click on normalize/export to generate MNI position first") + return + #else: + #plot_dict_MNIinter=None + + #pdb.set_trace() + brainvisaContext = defaultContext() + + #pour que lorsque le thread Brainvisa ça appelle parcellationdone ET les autres export si il y a besoin + if Callback is not None: + Callback2= lambda x=None,plotMNI = plot_dict_MNIinter, templateHPSub = TemplateHippoSubfieldFreesurfer, templateMA = TemplateMarsAtlas,templateFS=TemplateFreeSurfer:[self.parcellationDone(useTemplateMarsAtlas = templateMA,useTemplateFreeSurfer=templateFS,useTemplateHippoSubFreesurfer=templateHPSub,plot_dict_MNI=plotMNI),Callback()] + else: + Callback2 = lambda x=None,plotMNI = plot_dict_MNIinter, templateHPSub = TemplateHippoSubfieldFreesurfer, templateMA = TemplateMarsAtlas,templateFS=TemplateFreeSurfer:self.parcellationDone(useTemplateMarsAtlas = templateMA,useTemplateFreeSurfer=templateFS,useTemplateHippoSubFreesurfer=templateHPSub,plot_dict_MNI=plotMNI) + + try: + brainvisaContext.runInteractiveProcess(Callback2,'2D Parcellation to 3D parcellation', Side = "Both", left_gyri = LeftGyri) #, sulcus_identification ='label') + except: + Callback2() + + + def parcellationDone(self,useTemplateMarsAtlas = False, useTemplateFreeSurfer = False, useTemplateHippoSubFreesurfer = False,plot_dict_MNI=None): + + #pdb.set_trace() + print "export electrode start" + timestamp = time.time() + Mask_left = ReadDiskItem('Left Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskleft = Mask_left.findValue(self.diskItems['T1pre']) + + Mask_right = ReadDiskItem('Right Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskright = Mask_right.findValue(self.diskItems['T1pre']) + + MaskGW_right = ReadDiskItem('Right Grey White Mask','Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskGW_right = MaskGW_right.findValue(self.diskItems['T1pre']) + + MaskGW_left = ReadDiskItem('Left Grey White Mask','Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskGW_left = MaskGW_left.findValue(self.diskItems['T1pre']) + + + #here put if on use template or no + if diMaskleft is None: + print('left gyri conversion surface to volume failed') + useTemplateMarsAtlas = True + #return + + if diMaskright is None: + print('right gyri conversion surface to volume failed') + useTemplateMarsAtlas = True + #return + + GWAtlas = True + + if diMaskGW_left is None: + print('not found left grey/white label') + GWAtlas = False + else: + volGW_left = aims.read(diMaskGW_left.fileName()) + + if diMaskGW_right is None: + print('not found right grey/white label') + GWAtlas = False + else: + volGW_right = aims.read(diMaskGW_right.fileName()) + + + #on s'intéresse à la résection + wdi_resec = ReadDiskItem('Resection', 'NIFTI-1 image', requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + di_resec = list(wdi_resec.findValues({}, None, False )) + #careful, if we use templates, the resection has to be deformed in the mni template + + if len(di_resec)==0: + print('no resection image found') + DoResection = False + else: + DoResection = True + vol_resec = aims.read(di_resec[0].fileName()) + + #is there any statistic-Data + wdi_stat = ReadDiskItem('Statistic-Data','NIFTI-1 image',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + di_stat = list(wdi_stat.findValues({}, None, False )) + + #number of different subacquisition #not used for now, subacquisition has to be all different + subacq_existing = [di_stat[i].attributes()['subacquisition'] for i in range(len(di_stat))] + + if len(subacq_existing) >0: + subacq_stat=[] + for i_subacq in range(len(subacq_existing)): + subacq_stat.append(aims.read(di_stat[i_subacq].fileName())) + + plots = self.getAllPlotsCentersT1preRef() #coordonnées en mm à convertir en voxel + if len(plots)==0: + print("no contact found") + return + + if not useTemplateMarsAtlas: + vol_left = aims.read(diMaskleft.fileName()) + vol_right = aims.read(diMaskright.fileName()) + else: + vol_left = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/surface_analysis/Gre_2016_MNI1_L_gyriVolume.nii.gz') + vol_right = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/surface_analysis/Gre_2016_MNI1_R_gyriVolume.nii.gz') + + if not useTemplateFreeSurfer: + freesurferdi = ReadDiskItem('FreesurferAtlas', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.brainvisaPatientAttributes['subject'] }) + rdi_freesurfer = list(freesurferdi.findValues({}, None, False )) + vol_freesurfer = aims.read(str(rdi_freesurfer[0])) + freesurfHippoAntPostleft = ReadDiskItem('leftHippocampusNII', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.brainvisaPatientAttributes['subject'] }) + freesurfHippoAntPostright = ReadDiskItem('rightHippocampusNII', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.brainvisaPatientAttributes['subject'] }) + difreesurfHippoAntPostleft = list(freesurfHippoAntPostleft.findValues({}, None, False )) + difreesurfHippoAntPostright = list(freesurfHippoAntPostright.findValues({}, None, False )) + + if len(difreesurfHippoAntPostright)>0: + vol_hippoanteropostright = aims.read(str(difreesurfHippoAntPostright[0])) + if len(difreesurfHippoAntPostleft)>0: + vol_hippoanteropostleft = aims.read(str(difreesurfHippoAntPostleft[0])) + vol_hippoanteropost = vol_hippoanteropostright + vol_hippoanteropostleft + else: + vol_hippoanteropost = vol_hippoanteropostright + else: + if len(difreesurfHippoAntPostleft)>0: + vol_hippoanteropostleft = aims.read(str(difreesurfHippoAntPostleft[0])) + vol_hippoanteropost = vol_hippoanteropostleft + + if len(difreesurfHippoAntPostleft) == 0 and len(difreesurfHippoAntPostright) == 0: + vol_hippoanteropost = False + + else: + vol_hippoanteropostleft = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/leftHippocampusGre_2016_MNI1.nii') + vol_hippoanteropostright = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/rightHippocampusGre_2016_MNI1.nii') + vol_hippoanteropost = vol_hippoanteropostright + vol_hippoanteropostleft + vol_freesurfer = aims.read('MNI_Freesurfer/mri/freesurfer_parcelisation_mni2.nii') + + if not useTemplateHippoSubFreesurfer: + HippoSubfielddi = ReadDiskItem('HippoFreesurferAtlas', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.brainvisaPatientAttributes['subject'] }) + rdi_HippoSubfield = list(HippoSubfielddi.findValues({},None,False)) + vol_hipposubfieldFS = aims.read(str(rdi_HippoSubfield[0])) + else: + vol_hipposubfieldFS = aims.read('MNI_Freesurfer/mri/bhHippoMNI.nii') + + #chargement des atlas dans le MNI (broadman, aal etc ...) + vol_AAL = aims.read('MNI_Atlases/rAALSEEG12.nii') + vol_AALDilate = aims.read('MNI_Atlases/rAALSEEG12Dilate.nii') + vol_BroadmannDilate = aims.read('MNI_Atlases/rBrodmannSEEG3spm12.nii') + vol_Broadmann = aims.read('MNI_Atlases/rbrodmann.nii') + vol_Hammers = aims.read('MNI_Atlases/rHammersSEEG12.nii') + + info_image = self.diskItems['T1pre'].attributes() #['voxel_size'] #ca devrait etre les meme infos pour gauche et droite "probem when freesurfer is indi and mars atlas is template + + info_plot = [] + for k,v in plots.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plot.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v)) + #plots_label[k]=(label,label_name) + + plot_sorted = sorted(info_plot, key=lambda plot_number: plot_number[0]) + + matrix_MNI_Nativ = numpy.matrix([[ -1., 0., 0., 90.],[0., -1., 0., 91.],[0., 0., -1., 109.],[0., 0., 0., 1.]]) + plot_dict_MNI_Native = {} + for vv,kk in plot_dict_MNI.iteritems(): + inter_pos = [kk[0], kk[1], kk[2], 1] + inter_pos = numpy.matrix(inter_pos).reshape([4,1]) + result_pos = numpy.dot(matrix_MNI_Nativ,inter_pos) + plot_dict_MNI_Native.update({vv:[result_pos.tolist()[0][0],result_pos.tolist()[1][0],result_pos.tolist()[2][0]]}) + + #montage bipolaire + info_plot_bipolaire= [] + for pindex in range(1,len(plot_sorted)): + previous_contact = "".join([i for i in plot_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plot_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plot_bipolaire.append((plot_sorted[pindex][0]+' - '+ plot_sorted[pindex-1][0],(plot_sorted[pindex][1]+plot_sorted[pindex-1][1])/2 )) + + #if useTemplateMarsAtlas or useTemplateFreeSurfer or useTemplateHippoSubFreesurfer: #on fait le mni dans tous les cas à cause des atlas mni + info_plot_bipolaire_MNI = {} + for pindex in range(1,len(plot_sorted)): + previous_contact = "".join([i for i in plot_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plot_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plot_bipolaire_MNI.update({plot_sorted[pindex][0]+' - '+ plot_sorted[pindex-1][0]:(numpy.array(plot_dict_MNI_Native[plot_sorted[pindex][0]])+numpy.array(plot_dict_MNI_Native[plot_sorted[pindex-1][0]]))/2}) + + + parcels_names = readSulcusLabelTranslationFile('parcels_label_name.txt') + freesurfer_parcel_names = readFreesurferLabelFile('freesurfer_label.txt') + Hammers_parcels_names = readSulcusLabelTranslationFile('parcels_label_name_Hammers.txt') + AAL_parcels_names = readSulcusLabelTranslationFile('parcels_label_name_AAL.txt') + AALDilate_parcels_names = readSulcusLabelTranslationFile('parcels_label_name_AALDilate.txt') + #parcels_AAL_names = + #parcels_Broadmann_names = + #parcels_Hammers_names = + + #conversion x mm en nombre de voxel: + sphere_size_stat = 10 + nb_voxel_sphere_stat = [int(round(sphere_size_stat/info_image['voxel_size'][i])) for i in range(3)] + + sphere_size = 3 #en mm + nb_voxel_sphere = [int(round(sphere_size/info_image['voxel_size'][i])) for i in range(3)] + #if useTemplateMarsAtlas or useTemplateFreeSurfer or useTemplateHippoSubFreesurfer: + nb_voxel_sphere_MNI = [sphere_size, sphere_size, sphere_size] #because mni has a 1 mm isotropic resolution #int(round(sphere_size/info_image['voxel_size'][i])) for i in range(0,3)] + + print("start contact estimation") + plots_label = {} + for pindex in range(len(plot_sorted)): + + print(plot_sorted[pindex][0]) + #pdb.set_trace() + plot_pos_pix_indi = [round(plot_sorted[pindex][1][i]/info_image['voxel_size'][i]) for i in range(3)] + + plot_pos_pix_MNI = [round(plot_dict_MNI_Native[plot_sorted[pindex][0]][i]) for i in range(3)] + + #mars atlas: + if not useTemplateMarsAtlas: + plot_pos_pixMA = plot_pos_pix_indi + nb_voxel_sphereMA = nb_voxel_sphere + elif useTemplateMarsAtlas: + plot_pos_pixMA = plot_pos_pix_MNI #because MNI has a 1 mm istropic resolution #/info_image['voxel_size'][i]) for i in range(3)] + nb_voxel_sphereMA = nb_voxel_sphere_MNI + + #on regarde si une sphère de x mm de rayon touche une parcel + voxel_within_sphere_left = [vol_left.value(plot_pos_pixMA[0]+vox_i,plot_pos_pixMA[1]+vox_j,plot_pos_pixMA[2]+vox_k) for vox_k in range(-nb_voxel_sphereMA[2],nb_voxel_sphereMA[2]+1) for vox_j in range(-nb_voxel_sphereMA[1],nb_voxel_sphereMA[1]+1) for vox_i in range(-nb_voxel_sphereMA[0], nb_voxel_sphereMA[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_within_sphere_right = [vol_right.value(plot_pos_pixMA[0]+vox_i,plot_pos_pixMA[1]+vox_j,plot_pos_pixMA[2]+vox_k) for vox_k in range(-nb_voxel_sphereMA[2],nb_voxel_sphereMA[2]+1) for vox_j in range(-nb_voxel_sphereMA[1],nb_voxel_sphereMA[1]+1) for vox_i in range(-nb_voxel_sphereMA[0],nb_voxel_sphereMA[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + + voxel_to_keep = [x for x in voxel_within_sphere_left+voxel_within_sphere_right if x != 0 and x !=255 and x != 100] + + if GWAtlas: + voxelGW_within_sphere_left = [volGW_left.value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxelGW_within_sphere_right = [volGW_right.value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + + voxelGW_to_keep = [x for x in voxelGW_within_sphere_left+voxelGW_within_sphere_right if x !=255 and x !=0] + else: + GW_label = 255 + + #freesurfer: + if not useTemplateFreeSurfer: + plot_pos_pixFS = plot_pos_pix_indi + nb_voxel_sphereFS = nb_voxel_sphere + elif useTemplateFreeSurfer: + plot_pos_pixFS = plot_pos_pix_MNI #I have to apply the transfo Scanner-Based to Native #because MNI has a 1 mm istropic resolution #/info_image['voxel_size'][i]) for i in range(3)] + nb_voxel_sphereFS = nb_voxel_sphere_MNI + + voxel_within_sphere_FS = [vol_freesurfer.value(plot_pos_pixFS[0]+vox_i,plot_pos_pixFS[1]+vox_j,plot_pos_pixFS[2]+vox_k) for vox_k in range(-nb_voxel_sphereFS[2],nb_voxel_sphereFS[2]+1) for vox_j in range(-nb_voxel_sphereFS[1],nb_voxel_sphereFS[1]+1) for vox_i in range(-nb_voxel_sphereFS[0],nb_voxel_sphereFS[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keep_FS = [x for x in voxel_within_sphere_FS if x != 0 and x != 2 and x != 41] #et 2 et 41 ? left and right white cerebral matter + + #HippoSubfield + if not useTemplateHippoSubFreesurfer: + plot_pos_pixHippoFS = plot_pos_pix_indi + nb_voxel_sphereHippoFS = nb_voxel_sphere + elif useTemplateHippoSubFreesurfer: + plot_pos_pixHippoFS = plot_pos_pix_MNI + nb_voxel_sphereHippoFS = nb_voxel_sphere_MNI + + #pdb.set_trace() + voxel_within_sphere_HippoFS = [vol_hipposubfieldFS.value(plot_pos_pixHippoFS[0]+vox_i,plot_pos_pixHippoFS[1]+vox_j,plot_pos_pixHippoFS[2]+vox_k) for vox_k in range(-nb_voxel_sphereHippoFS[2],nb_voxel_sphereHippoFS[2]+1) for vox_j in range(-nb_voxel_sphereHippoFS[1],nb_voxel_sphereHippoFS[1]+1) for vox_i in range(-nb_voxel_sphereHippoFS[0],nb_voxel_sphereHippoFS[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keep_HippoFS = [x for x in voxel_within_sphere_HippoFS if x != 0 and x != 2 and x != 41] #et 2 et 41 ? left and right white cerebral matter + + #MNI Atlases + #AAL + voxel_within_sphere_AAL = [round(vol_AAL.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAAL = [x for x in voxel_within_sphere_AAL if x != 0 and not math.isnan(x)] + + #AALDilate + voxel_within_sphere_AALdilate = [round(vol_AALDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAALDilate = [x for x in voxel_within_sphere_AALdilate if x != 0 and not math.isnan(x)] + + #Broadmann + voxel_within_sphere_Broadmann = [round(vol_Broadmann.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmann = [x for x in voxel_within_sphere_Broadmann if x != 0 and not math.isnan(x)] + + #Brodmann dilate + voxel_within_sphere_Broadmanndilate = [round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmannDilate = [x for x in voxel_within_sphere_Broadmanndilate if x != 0 and not math.isnan(x)] + + #Hammers + voxel_within_sphere_Hammers = [round(vol_Hammers.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepHammers = [x for x in voxel_within_sphere_Hammers if x != 0 and not math.isnan(x)] + + if DoResection: + voxel_resec = [vol_resec.value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + + if len(subacq_existing)>0: + voxel_substat=[] + for i_substat in range(len(subacq_stat)): + voxel_substat_all = [subacq_stat[i_substat].value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere_stat[2],nb_voxel_sphere_stat[2]+1) for vox_j in range(-nb_voxel_sphere_stat[1],nb_voxel_sphere_stat[1]+1) for vox_i in range(-nb_voxel_sphere_stat[0],nb_voxel_sphere_stat[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_stat] + voxel_substat.append(numpy.mean([x for x in voxel_substat_all if abs(x) >= 0.1])) + + #prendre le label qui revient le plus en dehors de zero (au cas où il y en ait plusieurs) + from collections import Counter + + if not voxel_to_keep: + label_name = 'not in a mars atlas parcel' + label = max(vol_left.value(plot_pos_pixMA[0],plot_pos_pixMA[1],plot_pos_pixMA[2]), vol_right.value(plot_pos_pixMA[0],plot_pos_pixMA[1],plot_pos_pixMA[2])) + full_infoMAcomputed = [] + else: + most_common,num_most_common = Counter(voxel_to_keep).most_common(1)[0] + full_infoMA = Counter(voxel_to_keep).most_common() + label = most_common + full_infoMAcomputed = [(parcels_names[iLabel[0]],float(iLabel[1])/len(voxel_within_sphere_left)*100) for iLabel in full_infoMA] + label_name = parcels_names[label] + + if not voxel_to_keep_FS: + label_freesurfer_name = 'not in a freesurfer parcel' + label_freesurfer = vol_freesurfer.value(plot_pos_pixFS[0],plot_pos_pixFS[1],plot_pos_pixFS[2]) + else: + most_common,num_most_common = Counter(voxel_to_keep_FS).most_common(1)[0] + #check if it's in the hippocampus + if (most_common == 53 or most_common == 17) and vol_hippoanteropost != False: + voxel_within_sphere_FS = [vol_hippoanteropost.value(plot_pos_pixFS[0]+vox_i,plot_pos_pixFS[1]+vox_j,plot_pos_pixFS[2]+vox_k) for vox_k in range(-nb_voxel_sphereFS[2],nb_voxel_sphereFS[2]+1) for vox_j in range(-nb_voxel_sphereFS[1],nb_voxel_sphereFS[1]+1) for vox_i in range(-nb_voxel_sphereFS[0],nb_voxel_sphereFS[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keep_FS = [x for x in voxel_within_sphere_FS if x != 0 and x != 2 and x != 41] + try: + most_common,num_most_common = Counter(voxel_to_keep_FS).most_common(1)[0] + except: + pdb.set_trace() + label_freesurfer = most_common + if label_freesurfer == 3403: + pdb.set_trace() + label_freesurfer_name = freesurfer_parcel_names[str(label_freesurfer)][0] + else: + label_freesurfer = most_common + label_freesurfer_name = freesurfer_parcel_names[str(label_freesurfer)][0] + + if not voxel_to_keep_HippoFS: + label_hippoFS_name = 'not in a hippocamp subfield' + label_hippoFS = vol_hipposubfieldFS.value(plot_pos_pixHippoFS[0],plot_pos_pixHippoFS[1],plot_pos_pixHippoFS[2]) + else: + most_common,num_most_common = Counter(voxel_to_keep_HippoFS).most_common(1)[0] + label_hippoFS = most_common + label_hippoFS_name = freesurfer_parcel_names[str(int(label_hippoFS))][0] + + if GWAtlas: + if not voxelGW_to_keep: + GW_label = max(volGW_left.value(plot_pos_pix_indi[0],plot_pos_pix_indi[1],plot_pos_pix_indi[2]), volGW_right.value(plot_pos_pix_indi[0],plot_pos_pix_indi[1],plot_pos_pix_indi[2])) + else: + most_common2,num_most_common2 = Counter(voxelGW_to_keep).most_common(1)[0] + GW_label = most_common2 + + if not voxel_to_keepAAL: + label_AAL_name = "not in a AAL parcel" + label_AAL = round(vol_AAL.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAAL).most_common(1)[0] + label_AAL = most_common + label_AAL_name = AAL_parcels_names[label_AAL] + + if not voxel_to_keepAALDilate: + label_AALDilate_name = "not in a AALDilate parcel" + label_AALDilate = round(vol_AALDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAALDilate).most_common(1)[0] + label_AALDilate = most_common + label_AALDilate_name = AALDilate_parcels_names[label_AALDilate] + + if not voxel_to_keepBroadmann: + label_Broadmann_name = "not in a Broadmann parcel" + label_Broadmann = round(vol_Broadmann.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmann).most_common(1)[0] + label_Broadmann = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_Broadmann_name = unicode(label_Broadmann+100) + else: + label_Broadmann_name = unicode(label_Broadmann) + + if not voxel_to_keepBroadmannDilate: + label_BroadmannDilate_name = "not in a Broadmann parcel" + label_BroadmannDilate = round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmannDilate).most_common(1)[0] + label_BroadmannDilate = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_BroadmannDilate_name = unicode(label_BroadmannDilate+100) + else: + label_BroadmannDilate_name = unicode(label_BroadmannDilate-48) + + if not voxel_to_keepHammers: + label_Hammers_name = "not in a Hammers parcel" + label_Hammers = round(vol_Hammers.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepHammers).most_common(1)[0] + label_Hammers = most_common + label_Hammers_name = Hammers_parcels_names[label_Hammers] + + if DoResection: + most_common_res,num_most_common_res = Counter(voxel_resec).most_common(1)[0] + Resec_label = max(voxel_resec) #most_common_res + else: + Resec_label = 255 + + GW_label_name={0:'not in brain matter',100:'GreyMatter',200:'WhiteMatter',255:'Not Calculated'}[GW_label] + Resec_label_name = {0:'not in resection',1:'in resection',255:'resection not calculated'}[Resec_label] + + plots_label[plot_sorted[pindex][0]]={'MarsAtlas':(label,label_name),'MarsAtlasFull':full_infoMAcomputed,'Freesurfer':(label_freesurfer,label_freesurfer_name),'Hippocampal Subfield':(label_hippoFS,label_hippoFS_name),'GreyWhite':(GW_label,GW_label_name),'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name), 'BroadmannDilate':(label_BroadmannDilate,label_BroadmannDilate_name),'Hammers':(label_Hammers,label_Hammers_name),'Resection':(Resec_label,Resec_label_name)} + # add subacq_stat dictionnaries + if len(subacq_existing)>0: + for i_substat in range(len(subacq_stat)): + plots_label[plot_sorted[pindex][0]].update({di_stat[i_substat].attributes()['subacquisition']:float(format( voxel_substat[i_substat],'.3f'))}) + + plot_name = [x[0] for x in plot_sorted] + plots_by_label = dict([(Lab,[p for p in plot_name if plots_label[p]['MarsAtlas'][1]==Lab]) for Lab in parcels_names.values()]) + plots_by_label_FS = dict([(Lab,[p for p in plot_name if plots_label[p]['Freesurfer'][1]==Lab]) for Lab in [x[0] for x in freesurfer_parcel_names.values()]]) + plots_by_label_BM = dict([(Lab,[p for p in plot_name if plots_label[p]['Broadmann'][1]==Lab]) for Lab in [unicode("%1.1f"%x) for x in range(0,100)]]) + plots_by_label_HM = dict([(Lab,[p for p in plot_name if plots_label[p]['Hammers'][1]==Lab]) for Lab in Hammers_parcels_names.values()]) + plots_by_label_AAL = dict([(Lab,[p for p in plot_name if plots_label[p]['AAL'][1]==Lab]) for Lab in AAL_parcels_names.values()]) + plots_by_label_AALDilate = dict([(Lab,[p for p in plot_name if plots_label[p]['AALDilate'][1]==Lab]) for Lab in AALDilate_parcels_names.values()]) + + print("start bipole estimation") + #conversion x mm en nombre de voxel: + sphere_size_bipole = 5 + nb_voxel_sphere = [int(round(sphere_size_bipole/info_image['voxel_size'][i])) for i in range(0,3)] + #if useTemplateMarsAtlas or useTemplateFreeSurfer or useTemplateHippoSubFreesurfer: + nb_voxel_sphere_MNI = [sphere_size_bipole, sphere_size_bipole, sphere_size_bipole] #[int(round(sphere_size_bipole/info_image['voxel_size'][i])) for i in range(0,3)] + + plots_label_bipolar = {} + for pindex in range(len(info_plot_bipolaire)): + plot_pos_pix_indi= [round(info_plot_bipolaire[pindex][1][i]/info_image['voxel_size'][i]) for i in range(3)] + plot_pos_pix_MNI = [round(info_plot_bipolaire_MNI[info_plot_bipolaire[pindex][0]][i]) for i in range(3)] + + #on regarde si une sphère de x mm de rayon touche une parcel + #mars atlas: + if not useTemplateMarsAtlas: + plot_pos_pixMA = plot_pos_pix_indi + nb_voxel_sphereMA = nb_voxel_sphere + elif useTemplateMarsAtlas: + plot_pos_pixMA = plot_pos_pix_MNI #because MNI has a 1 mm istropic resolution #/info_image['voxel_size'][i]) for i in range(3)] + nb_voxel_sphereMA = nb_voxel_sphere_MNI + + voxel_within_sphere_left = [vol_left.value(plot_pos_pixMA[0]+vox_i,plot_pos_pixMA[1]+vox_j,plot_pos_pixMA[2]+vox_k) for vox_k in range(-nb_voxel_sphereMA[2],nb_voxel_sphereMA[2]+1) for vox_j in range(-nb_voxel_sphereMA[1],nb_voxel_sphereMA[1]+1) for vox_i in range(-nb_voxel_sphereMA[0],nb_voxel_sphereMA[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_bipole] + voxel_within_sphere_right = [vol_right.value(plot_pos_pixMA[0]+vox_i,plot_pos_pixMA[1]+vox_j,plot_pos_pixMA[2]+vox_k) for vox_k in range(-nb_voxel_sphereMA[2],nb_voxel_sphereMA[2]+1) for vox_j in range(-nb_voxel_sphereMA[1],nb_voxel_sphereMA[1]+1) for vox_i in range(-nb_voxel_sphereMA[0],nb_voxel_sphereMA[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_bipole] + + voxel_to_keep = [x for x in voxel_within_sphere_left+voxel_within_sphere_right if x != 0 and x !=255 and x != 100] + + if GWAtlas: + voxelGW_within_sphere_left = [volGW_left.value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_bipole] + voxelGW_within_sphere_right = [volGW_right.value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_bipole] + + voxelGW_to_keep = [x for x in voxelGW_within_sphere_left+voxelGW_within_sphere_right if x !=255 and x !=0] + else: + GW_label = 255 + + #freesurfer: + if not useTemplateFreeSurfer: + plot_pos_pixFS = plot_pos_pix_indi + nb_voxel_sphereFS = nb_voxel_sphere + elif useTemplateFreeSurfer: + plot_pos_pixFS = plot_pos_pix_MNI #because MNI has a 1 mm istropic resolution #/info_image['voxel_size'][i]) for i in range(3)] + nb_voxel_sphereFS = nb_voxel_sphere_MNI + + voxel_within_sphere_FS = [vol_freesurfer.value(plot_pos_pixFS[0]+vox_i,plot_pos_pixFS[1]+vox_j,plot_pos_pixFS[2]+vox_k) for vox_k in range(-nb_voxel_sphereFS[2],nb_voxel_sphereFS[2]+1) for vox_j in range(-nb_voxel_sphereFS[1],nb_voxel_sphereFS[1]+1) for vox_i in range(-nb_voxel_sphereFS[0],nb_voxel_sphereFS[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keep_FS = [x for x in voxel_within_sphere_FS if x != 0 and x != 2 and x != 41] + + #HippoSubfield + if not useTemplateHippoSubFreesurfer: + plot_pos_pixHippoFS = plot_pos_pix_indi + nb_voxel_sphereHippoFS = nb_voxel_sphere + elif useTemplateHippoSubFreesurfer: + plot_pos_pixHippoFS = plot_pos_pix_MNI + nb_voxel_sphereHippoFS = nb_voxel_sphere_MNI + + voxel_within_sphere_HippoFS = [vol_hipposubfieldFS.value(plot_pos_pixHippoFS[0]+vox_i,plot_pos_pixHippoFS[1]+vox_j,plot_pos_pixHippoFS[2]+vox_k) for vox_k in range(-nb_voxel_sphereHippoFS[2],nb_voxel_sphereHippoFS[2]+1) for vox_j in range(-nb_voxel_sphereHippoFS[1],nb_voxel_sphereHippoFS[1]+1) for vox_i in range(-nb_voxel_sphereHippoFS[0],nb_voxel_sphereHippoFS[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keep_HippoFS = [x for x in voxel_within_sphere_HippoFS if x != 0 and x != 2 and x != 41] #et 2 et 41 ? left and right white cerebral matter + + #MNI Atlases + #AAL + voxel_within_sphere_AAL = [round(vol_AAL.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAAL = [x for x in voxel_within_sphere_AAL if x != 0 and not math.isnan(x)] + + #AALDilate + voxel_within_sphere_AALdilate = [round(vol_AALDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAALDilate = [x for x in voxel_within_sphere_AALdilate if x != 0 and not math.isnan(x)] + + #Broadmann + voxel_within_sphere_Broadmann = [round(vol_Broadmann.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmann = [x for x in voxel_within_sphere_Broadmann if x != 0 and not math.isnan(x)] + + #Brodmann dilate + voxel_within_sphere_Broadmanndilate = [round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmannDilate = [x for x in voxel_within_sphere_Broadmanndilate if x != 0 and not math.isnan(x)] + + #Hammers + voxel_within_sphere_Hammers = [round(vol_Hammers.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepHammers = [x for x in voxel_within_sphere_Hammers if x != 0 and not math.isnan(x)] + + + if DoResection: + voxel_resec = [vol_resec.value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_bipole] + + if len(subacq_existing)>0: + voxel_substat=[] + for i_substat in range(len(subacq_stat)): + voxel_substat_all = [subacq_stat[i_substat].value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere_stat[2],nb_voxel_sphere_stat[2]+1) for vox_j in range(-nb_voxel_sphere_stat[1],nb_voxel_sphere_stat[1]+1) for vox_i in range(-nb_voxel_sphere_stat[0],nb_voxel_sphere_stat[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_stat] + voxel_substat.append(numpy.mean([x for x in voxel_substat_all if abs(x) >= 0.1])) + + #prendre le label qui revient le plus en dehors de zero (au cas où il y en ait plusieurs) + from collections import Counter + + if not voxel_to_keep: + label_name = 'not in a mars atlas parcel' + label = max(vol_left.value(plot_pos_pixMA[0],plot_pos_pixMA[1],plot_pos_pixMA[2]), vol_right.value(plot_pos_pixMA[0],plot_pos_pixMA[1],plot_pos_pixMA[2])) + full_infoMAcomputed = [] + else: + most_common,num_most_common = Counter(voxel_to_keep).most_common(1)[0] + label = most_common + full_infoMA = Counter(voxel_to_keep).most_common() + full_infoMAcomputed = [(parcels_names[iLabel[0]],float(iLabel[1])/len(voxel_within_sphere_left)*100) for iLabel in full_infoMA] + label_name = parcels_names[label] + + if not voxel_to_keep_FS: + label_freesurfer_name = 'not in a freesurfer parcel' + label_freesurfer = vol_freesurfer.value(plot_pos_pixFS[0],plot_pos_pixFS[1],plot_pos_pixFS[2]) + else: + most_common,num_most_common = Counter(voxel_to_keep_FS).most_common(1)[0] + #check if it's in the hippocampus + if (most_common == 53 or most_common == 17) and vol_hippoanteropost != False: + voxel_within_sphere_FS = [vol_hippoanteropost.value(plot_pos_pixFS[0]+vox_i,plot_pos_pixFS[1]+vox_j,plot_pos_pixFS[2]+vox_k) for vox_k in range(-nb_voxel_sphereFS[2],nb_voxel_sphereFS[2]+1) for vox_j in range(-nb_voxel_sphereFS[1],nb_voxel_sphereFS[1]+1) for vox_i in range(-nb_voxel_sphereFS[0],nb_voxel_sphereFS[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keep_FS = [x for x in voxel_within_sphere_FS if x != 0 and x != 2 and x != 41] + most_common,num_most_common = Counter(voxel_to_keep_FS).most_common(1)[0] + label_freesurfer = most_common + label_freesurfer_name = freesurfer_parcel_names[str(label_freesurfer)][0] + else: + label_freesurfer = most_common + label_freesurfer_name = freesurfer_parcel_names[str(label_freesurfer)][0] + + if not voxel_to_keep_HippoFS: + label_hippoFS_name = 'not in a hippocamp subfield' + label_hippoFS = vol_hipposubfieldFS.value(plot_pos_pixHippoFS[0],plot_pos_pixHippoFS[1],plot_pos_pixHippoFS[2]) + else: + most_common,num_most_common = Counter(voxel_to_keep_HippoFS).most_common(1)[0] + label_hippoFS = most_common + label_hippoFS_name = freesurfer_parcel_names[str(int(label_hippoFS))][0] + + if GWAtlas: + if not voxelGW_to_keep: + GW_label = max(volGW_left.value(plot_pos_pix_indi[0],plot_pos_pix_indi[1],plot_pos_pix_indi[2]), volGW_right.value(plot_pos_pix_indi[0],plot_pos_pix_indi[1],plot_pos_pix_indi[2])) + else: + most_common2,num_most_common2 = Counter(voxelGW_to_keep).most_common(1)[0] + GW_label = most_common2 + + if not voxel_to_keepAAL: + label_AAL_name = "not in a AAL parcel" + label_AAL = round(vol_AAL.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAAL).most_common(1)[0] + label_AAL = most_common + label_AAL_name = AAL_parcels_names[label_AAL] + + if not voxel_to_keepAALDilate: + label_AALDilate_name = "not in a AALDilate parcel" + label_AALDilate = round(vol_AALDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAALDilate).most_common(1)[0] + label_AALDilate = most_common + label_AALDilate_name = AALDilate_parcels_names[label_AALDilate] + + if not voxel_to_keepBroadmann: + label_Broadmann_name = "not in a Broadmann parcel" + label_Broadmann = round(vol_Broadmann.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmann).most_common(1)[0] + label_Broadmann = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_Broadmann_name = unicode(label_Broadmann+100) + else: + label_Broadmann_name = unicode(label_Broadmann) + + if not voxel_to_keepBroadmannDilate: + label_BroadmannDilate_name = "not in a Broadmann parcel" + label_BroadmannDilate = round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmannDilate).most_common(1)[0] + label_BroadmannDilate = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_BroadmannDilate_name = unicode(label_BroadmannDilate+100) + else: + label_BroadmannDilate_name = unicode(label_BroadmannDilate-48) + + if not voxel_to_keepHammers: + label_Hammers_name = "not in a Hammers parcel" + label_Hammers = round(vol_Hammers.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepHammers).most_common(1)[0] + label_Hammers = most_common + label_Hammers_name = Hammers_parcels_names[label_Hammers] + + + if DoResection: + most_common_res,num_most_common_res = Counter(voxel_resec).most_common(1)[0] + Resec_label = max(voxel_resec) #most_common_res + else: + Resec_label = 255 + + GW_label_name={0:'not in brain matter',100:'GreyMatter',200:'WhiteMatter',255:'Not Calculated'}[GW_label] + Resec_label_name = {0:'not in resection',1:'in resection',255:'resection not calculated'}[Resec_label] + + plots_label_bipolar[info_plot_bipolaire[pindex][0]]={'MarsAtlas':(label,label_name),'MarsAtlasFull':full_infoMAcomputed,'Freesurfer':(label_freesurfer,label_freesurfer_name),'Hippocampal Subfield':(label_hippoFS,label_hippoFS_name),'GreyWhite':(GW_label,GW_label_name),'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'BroadmannDilate':(label_BroadmannDilate,label_BroadmannDilate_name),'Hammers':(label_Hammers,label_Hammers_name),'Resection':(Resec_label,Resec_label_name)} + #plots_label_bipolar.append((info_plot_bipolaire[pindex][0],label,label_name,GW_label)) + # add subacq_stat dictionnaries + if len(subacq_existing)>0: + for i_substat in range(len(subacq_stat)): + plots_label_bipolar[info_plot_bipolaire[pindex][0]].update({di_stat[i_substat].attributes()['subacquisition']:float(format( voxel_substat[i_substat],'.3f'))}) + + plot_name_bip = [x[0] for x in info_plot_bipolaire] + #plots_by_label = {Lab:[p for p in plot_name if plots_label[p]['MarsAtlas'][1]==Lab] for Lab in parcels_names.values()} + plots_bipolar_by_label = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['MarsAtlas'][1]==Lab]) for Lab in parcels_names.values()]) + #do the same for freesurfer, broadmann, hammers, all and alldilate + plots_bipolar_by_label_FS = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['Freesurfer'][1]==Lab]) for Lab in [x[0] for x in freesurfer_parcel_names.values()]]) + plots_bipolar_by_label_BM = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['Broadmann'][1]==Lab]) for Lab in [unicode("%1.1f"%x) for x in range(0,100)]]) + plots_bipolar_by_label_HM = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['Hammers'][1]==Lab]) for Lab in Hammers_parcels_names.values()]) + plots_bipolar_by_label_AAL = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['AAL'][1]==Lab]) for Lab in AAL_parcels_names.values()]) + plots_bipolar_by_label_AALDilate = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['AALDilate'][1]==Lab]) for Lab in AALDilate_parcels_names.values()]) + wdi = WriteDiskItem('Electrodes Labels','Electrode Label Format') + di = wdi.findValue(self.diskItems['T1pre']) + if di is None: + print('Can t generate files') + return + + UseTemplateOrPatient = {'MarsAtlas':useTemplateMarsAtlas,'Freesurfer':useTemplateFreeSurfer,'HippocampalSubfield Freesurfer':useTemplateHippoSubFreesurfer} + + fout = open(di.fullPath(),'w') + fout.write(json.dumps({'Template':UseTemplateOrPatient,'plots_label':plots_label,'plots_by_label':plots_by_label, 'plots_by_label_FS':plots_by_label_FS, 'plots_by_label_BM':plots_by_label_BM, 'plots_by_label_HM':plots_by_label_HM, 'plots_by_label_AAL':plots_by_label_AAL, 'plots_by_label_AALDilate':plots_by_label_AALDilate, 'plots_label_bipolar':plots_label_bipolar, 'plots_bipolar_by_label':plots_bipolar_by_label, 'plots_bipolar_by_label_FS':plots_bipolar_by_label_FS, 'plots_bipolar_by_label_BM':plots_bipolar_by_label_BM, 'plots_bipolar_by_label_HM':plots_bipolar_by_label_HM, 'plots_bipolar_by_label_AAL':plots_bipolar_by_label_AAL, 'plots_bipolar_by_label_AALDilate':plots_bipolar_by_label_AALDilate})) + fout.close() + + neuroHierarchy.databases.insertDiskItem(di, update=True ) + #fin = open(di.fullPath(),'r') + #dictée = json.loads(fin.read()) + #dictée['plots_label'] + + print "export electrode done" + + + + def getAllPlotsCentersT1preRef(self): + """Return a dictionary {'ElectrodeName-$&_&$-PlotName':[x,y,z], ...} where x,y,z is in the T1pre native referential""" + return dict((el['name']+'-$&_&$-'+plotName, el['transf'].transform(plotCoords)) for el in self.electrodes for plotName, plotCoords in getPlotsCenters(el['elecModel']).iteritems()) + + def getAllPlotsCentersT1preScannerBasedRef(self): + """Return a dictionary {'ElectrodeName-$&_&$-PlotName':[x,y,z], ...} where x,y,z is in the T1pre scanner-based referential""" + transfo = self.t1pre2ScannerBased() + return dict((key, transfo.transform(coords)) for key, coords in self.getAllPlotsCentersT1preRef().iteritems()) + + def getAllPlotsCentersAnyReferential(self, referential): + """Return a dictionary {'ElectrodeName-$&_&$-PlotName':[x,y,z], ...} where x,y,z is in the provided referential (must be available in referential converter self.refConv)""" + if not self.refConv.isRefAvailable(referential): + print "Trying to convert to unknown referential %s"%repr(referential) + return None + return dict((key, self.refConv.real2AnyRef(coords, referential)) for key, coords in self.getAllPlotsCentersT1preRef().iteritems()) + + def getAllPlotsCentersMNIRef(self, plots=None): + """Return a dictionary {'ElectrodeName-$&_&$-PlotName':[x,y,z], ...} where x,y,z is in the MNI referential""" + if plots is None: + plots = self.getAllPlotsCentersT1preScannerBasedRef() + coords = [plots[k] for k in sorted(plots.keys())] + newCoords = self.convertT1ScannerBasedToMni(coords) + if newCoords is None: + return None + return dict(zip(sorted(plots.keys()), newCoords)) + + def saveTXT(self, contacts=None, path=None, pathPos=None, pathName=None): + """ Saves two txt files electrode_Name.txt and electrode_Pos.txt. Path should be supplied as /myPath/electrode.txt + or as an alternative, both file path should be supplied as pathPos and pathName + contacts should be a dictionary {'ElectrodeName-$&_&$-PlotName:[x,y,z],...} in the appropriate referential + """ + # Get a valid path + if not path and not (pathPos is not None and pathName is not None): + path = str(QtGui.QFileDialog.getSaveFileName(self, "Save TXT files", "", "Electrode implantation TXT files (*.txt)")) + if not path: + return None + if not contacts: + return None + if path is not None: + path = os.path.splitext(path)[0] + pathName = path+'_Name.txt' + pathPos = path+"_Pos.txt" + fileName = open(pathName, 'wb') + filePos = open(pathPos, 'wb') + # Iteration over electrodes + for contactName in sorted(contacts.keys(), key=natural_keys): + (elName, plotName) = contactName.split('-$&_&$-') + # Name of each contact is name of electrode (p for prime) + number of the plot (electrode A' contact 5 is "Ap5") + fileName.write(elName.replace('\'', 'p') + plotName.replace('Plot','') + "\n") + filePos.write("%f %f %f\n"%tuple(contacts[contactName])) + fileName.close() + filePos.close() + return pathPos + + def savePTS(self, contacts=None, path=None): + """ Save a PTS file with all contacts coordinates. + contacts parameter should be a dictionary {'ElectrodeName-$&_&$-PlotName:[x,y,z],...} in the appropriate referential + """ + # Get a valid path + if not path: + path = str(QtGui.QFileDialog.getSaveFileName(self, "Save PTS file (%s referential)"%referential, "", "PTS Electrode implantation (*.pts)")) + if not path: + return None + if contacts is None: + return None + + plots=[] + for contactName in sorted(contacts.keys(), key=natural_keys): + coords = contacts[contactName] + (elName, plotName) = contactName.split('-$&_&$-') + # Name of each contact is name of electrode (prime ' replaced by the letter p) + number of the plot (electrode A' contact 5 is "Ap5") + plots.append("%s\t%.2f\t%.2f\t%.2f\t0\t0\t0\t2\t2.0\n"%(elName.replace('\'', 'p') + plotName.replace('Plot',''), coords[0], coords[1], coords[2])) + + fileout = open(path, 'wb') + fileout.write("ptsfile\n1\t1\t1\n%s\n"%str(len(plots))) + for p in plots: + fileout.write(p) + + fileout.close() + return path + + # Open configuration dialog + def configureColors(self): + + self.bipoleSEEGColors=bipoleSEEGColors(self) + self.bipoleSEEGColors.show() + + + + def allWindowsUpdate(self): + self.windowUpdate(0, self.windowCombo1.currentText()) + self.windowUpdate(1, self.windowCombo2.currentText()) + + # Update a window content + def windowUpdate(self, winId, key): + key = str(key) # Can be a QString ! + if key not in self.windowContent: + return #when QT interface but, there was a variable generated in "frame" and we were not able to delete it, then we were not able to load another patient, there was leftover from previous patient + w = self.wins[winId] + for obj in self.dispObj: + if obj in self.windowContent[key]: + #print "Adding %s"%obj + self.a.addObjects(self.dispObj[obj], w) + else: + #print "Removing %s"%obj + self.a.removeObjects([self.dispObj[obj],],w)#CURRENT + + def updateElectrodeView(self, checkStatus=None): + """Sets the view to electrode referential or back to native T1 referential + checkStatus is Qt.CheckState""" + if checkStatus is None: + checkStatus = self.electrodeRefCheck.checkState() + if checkStatus == QtCore.Qt.Checked: + if self.electrodeList.count() > 0 and self.electrodeList.currentRow() <= len(self.electrodes): + #Change to electrode referential + el = self.currentElectrode() + if el is None: + return + if 'refRotation' in el: + self.electrodeRefRotationSlider.setValue(el['refRotation']) + if 'ref' in el: + self.setWindowsReferential(el['ref']) + self.electrodeGo(electrode = el) + else: + # Change back to T1pre native ref + self.setWindowsReferential() + + def updateElectrodeViewRotation(self, degrees): + """Sets the angle of an electrode referential, degrees is the angle in degrees""" + if self.electrodeList.count() > 0 and self.electrodeList.currentRow() <= len(self.electrodes): + #Change angle of electrode referential + el = self.currentElectrode() + if el: + el['refRotation'] = degrees + + def clippingUpdate(self): + + if self.Clipping_checkbox.isChecked(): + print "clipping activated" + self.a.execute('WindowConfig',windows = [self.wins[0]],clipping=2,clip_distance=5.) + + else: + print "clipping not activated" + self.a.execute('WindowConfig',windows = [self.wins[0]],clipping=0) + + + + def makeFusion(self): + + #get objects + Text_win1 = self.windowCombo1.currentText() + Text_win2 = self.windowCombo2.currentText() + + for obj in self.dispObj.keys(): + if obj in self.windowContent[str(Text_win1)][0]: + #print "Adding %s"%obj + obj1 = obj + + for obj in self.dispObj.keys(): + if obj in self.windowContent[str(Text_win2)][0]: + #print "Adding %s"%obj + obj2 = obj + + #pdb.set_trace() + if 'obj1' in locals() and 'obj2' in locals(): + print "do the fusion" + fusion_obj = self.a.fusionObjects((self.dispObj[obj1], self.dispObj[obj2]), method='Fusion2DMethod') + self.a.addObjects(fusion_obj, self.wins[1]) + + #add the fusion in the disObj and the windowCombo + self.dispObj[obj1+'+'+obj2] = fusion_obj + + self.windowContent.update({obj1+'+'+obj2:[obj1+'+'+obj2,'electrodes']}) + self.windowCombo1.clear() + self.windowCombo1.addItems(sorted(self.windowContent.keys())) + self.windowCombo2.clear() + self.windowCombo2.addItems(sorted(self.windowContent.keys())) + + self.windowCombo1.setCurrentIndex(max(self.windowCombo1.findText(Text_win1),0)) + self.windowCombo2.setCurrentIndex(max(self.windowCombo2.findText(obj1+'+'+obj2),0)) + + #self.allWindowsUpdate() + + else: + print "one of the image is not recognized" + return + + + def generateResection(self): + + #look for T1 pre and T1 postop + T1 = ReadDiskItem('Raw T1 MRI', 'aims readable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diT1 = list(T1.findValues({}, None, False )) + for t in diT1: + if 'pre' in t.attributes()['acquisition']: + T1pre = t.fullPath() + try: + SB_transf = t.attributes()['SB_Transform'] + except: + SB_transf = t.attributes()['transformations'][0] + + elif 'postOp' in t.attributes()['acquisition']: + T1postop = t.fullPath() + + if not T1pre: + print('don t find the t1pre') + return + + if 'T1postop' not in locals(): + print('don t find the t1postop') + print('look for a CTpostop') + CTs = ReadDiskItem('CT', 'aims readable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diCTs = list(CTs.findValues({},None,False)) + for t in diCTs: + if 'postOp' in t.attributes()['acquisition']: + CTpostop = t.fullPath() + method = 'CT' + if 'CTpostop' not in locals(): + print("can't find a CTpostop either") + return + else: + method = 'T1' + + T1pre = None + T1postop = None + + id_pre = [x for x in range(len(diT1)) if 'pre' in str(diT1[x])] + T1pre = diT1[id_pre[0]] + + if method == 'T1': + id_postop = [x for x in range(len(diT1)) if 'postOp' in str(diT1[x])] + T1postop = diT1[id_postop[0]] + elif method == 'CT': + id_ctpostop = [x for x in range(len(diCTs)) if 'postOp' in str(diCTs[x])] + CTpostop = diCTs[id_ctpostop[0]] + + + if method == 'T1': + + try: + self.refConv.loadACPC(T1pre) + except Exception, e: + print "Cannot load AC-PC referential from T1 pre MRI : "+repr(e) + return + + Ac = self.refConv.Ac + Pc = self.refConv.Pc + Ih = self.refConv.Ih + Ac.append(1) + Pc.append(1) + Ih.append(1) + + Ac_vector = numpy.array([Ac]) + Pc_vector = numpy.array([Pc]) + Ih_vector = numpy.array([Ih]) + + wdiTransform = ReadDiskItem('Transform Raw T1 MRI to another image', 'Transformation matrix', exactType=True, requiredAttributes = {'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) #pourquoi la suite marche pas ?, requiredAttributes = {'modalityTarget':T1pre.attributes()['modality'], 'acquisitionTarget':T1pre.attributes()['acquisition']} + diTransform = list(wdiTransform.findValues({}, None, False )) + + for t in diTransform: + if t.attributes()['modality'] == 't1mri' and 'postOp' in t.attributes()['acquisition']: + trmpostop_to_pre = t + #transfo_postop_to_pre = aims.read(trmpostop_to_pre.fullPath()).toMatrix() + #transfo_pre_to_postop = numpy.linalg.inv(transfo_postop_to_pre) + + wdiTransform2 = ReadDiskItem('Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True, requiredAttributes = {'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diTransform2 = wdiTransform2.findValues({}, None, False ) + + for t in diTransform2: + if t.attributes()['modality'] == 't1mri' and 'postOp' in t.attributes()['acquisition']: + trmpostop_to_SB = t + #transfo_postop_to_SB = aims.read(trmpostop_to_SB.fullPath()).toMatrix() + if t.attributes()['modality'] == 't1mri' and 'pre' in t.attributes()['acquisition']: + trmpre_to_SB = t + #transfo_pre_to_SB = aims.read(trmpre_to_SB.fullPath()).toMatrix() + + if method == 'CT': + + wdiTransform = ReadDiskItem('Transform CT to another image', 'Transformation matrix', exactType=True, requiredAttributes = {'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) #pourquoi la suite marche pas ?, requiredAttributes = {'modalityTarget':T1pre.attributes()['modality'], 'acquisitionTarget':T1pre.attributes()['acquisition']} + diTransform = list(wdiTransform.findValues({}, None, False )) + + for t in diTransform: + if t.attributes()['modality'] == 'ct' and 'postOp' in t.attributes()['acquisition']: + trmpostop_to_pre = t + + wdiTransform2 = ReadDiskItem('Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True, requiredAttributes = {'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diTransform2 = wdiTransform2.findValues({}, None, False ) + + for t in diTransform2: + if t.attributes()['modality'] == 'ct' and 'postOp' in t.attributes()['acquisition']: + trmpostop_to_SB = t + #transfo_postop_to_SB = aims.read(trmpostop_to_SB.fullPath()).toMatrix() + if t.attributes()['modality'] == 't1mri' and 'pre' in t.attributes()['acquisition']: + trmpre_to_SB = t + #transfo_pre_to_SB = aims.read(trmpre_to_SB.fullPath()).toMatrix() + + + + + import copy + trmpre_to_SBinvpath = trmpre_to_SB.fullPath().split('/') + trmpre_to_SBinvpath[-1] = 'inv'+trmpre_to_SBinvpath[-1] + trmpostop_to_pre_path = copy.deepcopy(trmpre_to_SBinvpath) + trmpostop_to_pre_path[-1] = 'postop_to_pre.trm' + trmpre_to_postop_path = copy.deepcopy(trmpre_to_SBinvpath) + trmpre_to_postop_path[-1] = 'pre_to_postop.trm' + trmpre_to_SBinvpath = '/'.join(trmpre_to_SBinvpath) + trmpostop_to_pre_path = '/'.join(trmpostop_to_pre_path) + trmpre_to_postop_path = '/'.join(trmpre_to_postop_path) + + + ret = subprocess.call(['AimsInvertTransformation','-i',trmpre_to_SB.fullPath(),'-o', trmpre_to_SBinvpath]) + ret = subprocess.call(['AimsComposeTransformation', '-o',trmpostop_to_pre_path, trmpre_to_SBinvpath, trmpostop_to_pre.fullPath(), trmpostop_to_SB.fullPath()]) + ret = subprocess.call(['AimsInvertTransformation','-i',trmpostop_to_pre_path,'-o',trmpre_to_postop_path]) + + print 'select the center of the resection' + center_seg = QtGui.QMessageBox(self) + center_seg.setText("Enter the center (approximatly) of the resection") + center_seg.setWindowTitle("resection center") + center_seg.setWindowModality(QtCore.Qt.NonModal) + center_seg.show() + center_seg.exec_() + + #convert brainvisa voxel position into spm_voxel position + ResecCenterCoord = list(self.a.linkCursorLastClickedPosition(self.preReferential()).items()) + print ResecCenterCoord + + if method == 'T1': + transfo_pre_to_postop = aims.read(trmpre_to_postop_path).toMatrix() + + Ac_vector_postop = transfo_pre_to_postop.dot(Ac_vector.T) + Pc_vector_postop = transfo_pre_to_postop.dot(Pc_vector.T) + Ih_vector_postop = transfo_pre_to_postop.dot(Ih_vector.T) + vect1 = numpy.array(Ac_vector_postop[0:3])-numpy.array(Pc_vector_postop[0:3]) + vect2 = numpy.array(Ih_vector_postop[0:3])-numpy.array(Pc_vector_postop[0:3]) + + result_cross = cross(vect1.T.tolist(),vect2.T.tolist())/numpy.linalg.norm(cross(vect1.T.tolist(),vect2.T.tolist()))*40 + Lh_postop = numpy.array(Ac[0:3]) + result_cross + + brainvisaContext = defaultContext() + morphologist = processes.getProcessInstance('morphologist') + morphologist.executionNode().PrepareSubject.setSelected(True) + morphologist.executionNode().BiasCorrection.setSelected(True) + morphologist.executionNode().HistoAnalysis.setSelected(True) + morphologist.executionNode().BrainSegmentation.setSelected(True) + morphologist.executionNode().Renorm.setSelected(False) + morphologist.executionNode().SplitBrain.setSelected(False) + morphologist.executionNode().TalairachTransformation.setSelected(False) + morphologist.executionNode().HeadMesh.setSelected(False) + morphologist.executionNode().HemispheresProcessing.setSelected(False) + morphologist.executionNode().SulcalMorphometry.setSelected(False) + brainvisaContext.runInteractiveProcess(lambda x='',trm=trmpostop_to_pre_path,resec_coord=ResecCenterCoord,methodo=method:self.resectionStart(trm,resec_coord,methodo) , morphologist, t1mri = T1postop, perform_normalization = False, anterior_commissure = Ac_vector_postop[0:3].T.tolist()[0],\ + posterior_commissure = Pc_vector_postop[0:3].T.tolist()[0], interhemispheric_point = Ih_vector_postop[0:3].T.tolist()[0], left_hemisphere_point = Lh_postop.tolist()[0], perform_sulci_recognition = False) + + if method == 'CT': + self.resectionStart(trmpostop_to_pre_path,ResecCenterCoord,method = 'CT') + + + def generateFiberContactDistance(self): + + print("not finished") + return + pdb.set_trace() + + + def resectionStart(self,trm_postop_to_pre,resec_coord,method = 'T1'): + + wdi_resec = WriteDiskItem('Resection', 'NIFTI-1 image') + di_resec = wdi_resec.findValue({'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol, 'acquisition':'Resection'}) + + #if the path doesn't exist, create it + if not os.path.exists(os.path.dirname(di_resec.fullPath())): + os.makedirs( os.path.dirname(di_resec.fullPath())) + + + if method == 'T1': + brainMask = ReadDiskItem('Brain Mask', 'aims readable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diBrain = list(brainMask.findValues({}, None, False )) + + id_pre = [x for x in range(len(diBrain)) if 'pre' in str(diBrain[x])] + id_postop = [x for x in range(len(diBrain)) if 'postOp' in str(diBrain[x])] + + fullname_postop = diBrain[id_postop[0]].fullPath() + fullpost_split = fullname_postop.split('/') + fullpost_split[-1] = 'brainpostop_on_pre.nii' + fullpost = '/'.join(fullpost_split) + + ret = subprocess.call(['AimsResample', '-i', str(diBrain[id_postop[0]].fullPath()), '-m', trm_postop_to_pre, '-o', fullpost, '-t', 'n', '-r',diBrain[id_pre[0]].fullPath()]) + ret = subprocess.call(['AimsLinearComb', '-i',str(diBrain[id_pre[0]].fullPath()),'-j',fullpost, '-c', '-1', '-o', di_resec.fullPath()]) + ret = subprocess.call(['AimsThreshold', '-i',di_resec.fullPath(),'-m', 'ge','-t','250' , '-o', di_resec.fullPath()]) + ret = subprocess.call(['AimsMorphoMath', '-m','ope', '-i', di_resec.fullPath(), '-o', di_resec.fullPath(), '-r', '2']) + ret = subprocess.call(['AimsConnectComp', '-i',di_resec.fullPath(),'-o',di_resec.fullPath(),'-c','6',]) + + + if method == 'CT': + + brainMask = ReadDiskItem('Brain Mask', 'aims readable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diBrain = list(brainMask.findValues({}, None, False )) + + id_pre = [x for x in range(len(diBrain)) if 'pre' in str(diBrain[x])] + + CTs = ReadDiskItem('CT', 'aims readable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diCTs = list(CTs.findValues({},None,False)) + for t in diCTs: + if 'postOp' in t.attributes()['acquisition']: + CTpostop = t.fullPath() + + #id_ctpostop = [x for x in range(len(diCTs)) if 'postOp' in str(diCTs[x])] + + #fullname_postop = diCTs[id_ctpostop[0]].fullPath() + #fullpost_split = fullname_postop.split('/') + #fullpost_split[-1] = 'CTpostop_on_pre.nii' + #fullpost = '/'.join(fullpost_split) + + ret = subprocess.call(['AimsResample', '-i', str(CTpostop), '-m', trm_postop_to_pre, '-o', di_resec.fullPath(), '-t', 'c', '-r',diBrain[id_pre[0]].fullPath()]) + + ret = subprocess.call(['AimsThreshold', '-i',di_resec.fullPath(),'-m', 'be','-t','-20','-u','25','-b','-o', di_resec.fullPath()]) + ret = subprocess.call(['cartoLinearComb.py','-i',str(di_resec.fullPath()),'-i',str(diBrain[id_pre[0]]),'-o',str(di_resec.fullPath()),'-f','(I1/32767*I2/255)']) + + #apply brainmask +#./cartoLinearComb.py -i /data/brainvisa_4.5/Epilepsy/Gre_2015_CETo/t1mri/T1pre_2015-1-1/default_analysis/segmentation/brain_Gre_2015_CETo.nii -i /data/brainvisa_4.5/Epilepsy/Gre_2015_CETo/Resection/Resection/Gre_2015_CETo-Resection.nii -f 'I2/32767*I1/255' -o /tmp/test.nii + ret = subprocess.call(['AimsMorphoMath', '-m','ope', '-i', di_resec.fullPath(), '-o', di_resec.fullPath(), '-r', '2']) + + #la faut passer par numpy ... + + ret = subprocess.call(['AimsConnectComp', '-i',di_resec.fullPath(),'-o',di_resec.fullPath(),'-c','6',]) + + vol_connectcomp = aims.read(di_resec.fullPath()) + #a small sphere here as for plots: + sphere_size = 4 + nb_voxel_sphere = [int(round(sphere_size/vol_connectcomp.getVoxelSize()[i])) for i in range(0,3)] + voxel_within_sphere = [vol_connectcomp.value(resec_coord[0]/vol_connectcomp.getVoxelSize()[0]+vox_i,resec_coord[1]/vol_connectcomp.getVoxelSize()[1]+vox_j,resec_coord[2]/vol_connectcomp.getVoxelSize()[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + + voxel_to_keep = [x for x in voxel_within_sphere if x != 0] + from collections import Counter + most_common,num_most_common = Counter(voxel_to_keep).most_common(1)[0] + + #value_connectcomp = vol_connectcomp.value(resec_coord[0],resec_coord[1],resec_coord[2]) + ret = subprocess.call(['AimsThreshold', '-i',di_resec.fullPath(),'-m', 'eq','-t',str(most_common) , '-o', di_resec.fullPath()]) + + #resave as the resection Image and do the .minf + #ret = subprocess.call(['AimsFileConvert', '-i', str(di_resec.fullPath()), '-o', str(di_resec.fullPath()), '-t', 'S16']) + if ret < 0: + print "Importation error" + QtGui.QMessageBox.warning(self, "Error", "Brainvisa Importation error/ AimsFileConvert") + return + + neuroHierarchy.databases.insertDiskItem( di_resec, update=True ) + self.transfoManager.setReferentialTo(di_resec, self.diskItems['T1pre'].attributes()['referential'] ) + + wdi_resec_roi = WriteDiskItem( 'ROI IntrAnat', 'Graph' ) + di_resec_roi = wdi_resec_roi.findValue({'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol, 'acquisition':'Resection'}) + + brainvisaContext = defaultContext() + + brainvisaContext.runInteractiveProcess(lambda x='',di_roi=di_resec_roi,di_res=di_resec:self.roiconversionDone(di_roi,di_resec),'Volume To ROI Graph Converter', read = di_resec, write = di_resec_roi) #, sulcus_identification ='label') + + + def roiconversionDone(self,di_resec_roi,di_resec): + + + neuroHierarchy.databases.insertDiskItem( di_resec_roi, update=True ) + self.transfoManager.setReferentialTo(di_resec_roi, self.diskItems['T1pre'].attributes()['referential'] ) + obj_roi = self.a.loadObject(di_resec_roi) + + Text_win1 = self.windowCombo1.currentText() + obj = self.a.loadObject(di_resec) + self.diskItems['Resection'] = di_resec + self.dispObj['Resection']=obj + self.windowContent.update({'Resection':['Resection','electrodes']}) + self.windowCombo1.clear() + self.windowCombo1.addItems(sorted(self.windowContent.keys())) + self.windowCombo2.clear() + self.windowCombo2.addItems(sorted(self.windowContent.keys())) + + self.windowCombo1.setCurrentIndex(max(self.windowCombo1.findText(Text_win1),0)) + self.windowCombo2.setCurrentIndex(max(self.windowCombo2.findText('Resection'),0)) + + self.allWindowsUpdate() + + def ROIResectiontoNiftiResection(self): + + wdi_resec = WriteDiskItem('Resection', 'NIFTI-1 image') + di_resec = wdi_resec.findValue({'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol, 'acquisition':'Resection'}) + + wdi_resec_roi = ReadDiskItem( 'ROI Intranat', 'Graph', requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol} ) + di_resec_roi = list(wdi_resec_roi.findValues({}, None, False)) + + brainvisaContext = defaultContext() + brainvisaContext.runInteractiveProcess(lambda x='',di_roi=di_resec_roi[0],di_res=di_resec:self.roiconversionDone(di_roi,di_resec),'Graph To Volume Converter', read = di_resec_roi[0], write = di_resec) #removeSource, False, extract_contours, 'No' + + def removeFromDB(self, file, db=None): + """ + If the file is a directory, recursive call to remove all its content before removing the directory. + Corresponding diskitem is removed from the database if it exists. + Taken from brainvisa-4.3.0/python/brainvisa/data/qt4gui/hierarchyBrowser.py + """ + if db is None: + try: + db=neuroHierarchy.databases.database(neuroHierarchy.databases.getDiskItemFromFileName(file).get("_database")) + except: + pass + + if os.path.isdir(file): + for f in os.listdir(file): + self.removeFromDB(os.path.join(file, f), db) + os.rmdir(file) + else: + os.remove(file) + if db: + diskItem=db.getDiskItemFromFileName(file, None) + if diskItem: + db.removeDiskItem(diskItem) + + def DeleteMarsAtlasFiles(self): + + rep = QtGui.QMessageBox.warning(self, u'Confirmation', u"ATTENTION
You are gonna delete MarsAtlas files, are you sure?
DELETE MARSATLAS ?
", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) + if rep == QtGui.QMessageBox.Yes: + atlas_di = ReadDiskItem('hemisphere marsAtlas parcellation texture', 'aims Texture formats', requiredAttributes={ 'regularized': 'false','subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + atlas_di_list = list(atlas_di._findValues({}, None, False )) + Mask_left = ReadDiskItem('Left Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskleft = list(Mask_left.findValues({}, None, False )) + Mask_right = ReadDiskItem('Right Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskright = list(Mask_right.findValues({}, None, False )) + + if len(atlas_di_list)>0: + for i,infoi in enumerate(atlas_di_list): + self.removeFromDB(infoi.fullPath(), neuroHierarchy.databases.database(infoi.get("_database"))) + + + if len(diMaskleft)>0: + self.removeFromDB(diMaskleft[0].fullPath(), neuroHierarchy.databases.database(diMaskleft[0].get("_database"))) + + if len(diMaskright)>0: + self.removeFromDB(diMaskright[0].fullPath(), neuroHierarchy.databases.database(diMaskright[0].get("_database"))) + + print("MarsAtlas resulting files suppressed") + + + def importRosaImplantation(self): + + TheoElectrodes = ImportTheoreticalImplentation.importRosaImplantation(self) + #wdiTransform2 = ReadDiskItem('Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True, requiredAttributes = {'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + #self.t1pre2ScannerBasedTransform + print("not finished") + return + for cle, valeur in TheoElectrodes.items(): + + pdb.set_trace() + rdi = ReadDiskItem('Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True, requiredAttributes={'modality':'t1mri','subject':self.brainvisaPatientAttributes['subject'], 'center':self.brainvisaPatientAttributes['center']}) + newvalTarget=[float(x) for x in valeur["target"]] + newvalTarget=tuple(newvalTarget) + newvalEntry=[float(x) for x in valeur["entry"]] + newvalEntry=tuple(newvalEntry) + volume = aims.read(str(self.diskItems['T1pre'])) + size=volume.getVoxelSize() + sizex=size[0] + sizey=size[1] + sizez=size[2] + xt=float(newvalTarget[0])/sizex + yt=float(newvalTarget[1])/sizey + zt=float(newvalTarget[2])/sizez + xe=float(newvalEntry[0])/sizex + ye=float(newvalEntry[1])/sizey + ze=float(newvalEntry[2])/sizez + #correctTarget=(xt,yt,zt) + #correctEntry=(xe,ye,ze) + #di = rdi.findValue(self.diskItems['T1pre']) + #matriceTransfo = aims.read(di.fullPath()) + #newXYZentry = matriceTransfo.transform(correctTarget) + #newXYZtarget= matriceTransfo.transform(correctEntry) + #matriceTransfoT = numpy.array([[-volume.getSizeX()/2, -volume.getSizeY()/2, -volume.getSizeZ()/2, 0]]) + #correctTarget=numpy.array(newXYZtarget) + #correctTarget=numpy.insert(correctTarget,3,1) + #newXYZtarget=numpy.add(correctTarget,matriceTransfoT) + #correctEntry=numpy.array(newXYZentry) + #correctEntry=numpy.insert(correctEntry,3,1) + #newXYZentry=numpy.add(correctEntry,matriceTransfoT) + #xtf=newXYZtarget[0][0] + #ytf=newXYZtarget[0][1] + #ztf=newXYZtarget[0][2] + #xef=newXYZentry[0][0] + #yef=newXYZentry[0][1] + #zef=newXYZentry[0][2] + #self.t1pre2ScannerBasedTransform.transform((xt,yt,zt)) + self.addElectrode(unicode(cle), "Dixi-D08-12AM",[xt,yt,zt],[xe,ye,ze]) + + def approximateElectrode(self): + + + self.deetoMaison=DeetoMaison(self) + self.deetoMaison.show() + + # Fonction principale qui lance l'interface +def main(noapp=0): + app = None + if noapp == 0: + print "NO APP" + app = QtGui.QApplication(sys.argv) + print "CREATE DIALOG" + window = LocateElectrodes(app = app) + window.show() + if noapp == 0: + sys.exit(app.exec_()) + +if __name__ == "__main__": + print "LAUNCHING ELECTRODE LOCATE" + axon.initializeProcesses() + from brainvisa.data.readdiskitem import ReadDiskItem + from brainvisa.data.writediskitem import WriteDiskItem + + print "MAIN" + # Allow pdb to work for debugging ! + QtCore.pyqtRemoveInputHook() + main() + +#if __name__ == "__main__": +# from PyQt4.QtGui import qApp +# app = qApp +# main(0) + + diff --git a/locateElectrodes.sh b/locateElectrodes.sh new file mode 100644 index 0000000..525bf0b --- /dev/null +++ b/locateElectrodes.sh @@ -0,0 +1,8 @@ +#!/bin/bash +cd /Users/admin/Softwares/BrainVISA-4.5/bin/ +. /Users/admin/Softwares/BrainVISA-4.5/bin/bv_env.sh /Users/admin/Softwares/BrainVISA-4.5 +cd /Users/admin/Documents/GIT/IntrAnatElectrodes/epilepsie/ +echo "#############################################################################" >> intranat-locateElectrodes-`whoami`.log +date >> intranat-locateElectrodes-`whoami`.log +python locateElectrodes.py >> intranat-locateElectrodes-`whoami`.log + diff --git a/logoIntrAnat.xpm b/logoIntrAnat.xpm new file mode 100644 index 0000000..3ad7d99 --- /dev/null +++ b/logoIntrAnat.xpm @@ -0,0 +1,9270 @@ +/* XPM */ +static char * logoIntrAnat_xpm[] = { +"642 465 8802 3", +" c None", +". c #FFFFFF", +"+ c #FEFEFE", +"@ c #FDFDFD", +"# c #FBFBFB", +"$ c #FCFCFC", +"% c #F9F9F9", +"& c #F5F5F5", +"* c #F4F4F4", +"= c #F3F3F3", +"- c #F6F6F6", +"; c #F8F8F8", +"> c #FAFAFA", +", c #F7F7F7", +"' c #F2F2F2", +") c #EAEAEA", +"! c #E5E5E5", +"~ c #E4E4E4", +"{ c #E8E8E8", +"] c #EBEBEB", +"^ c #EDEDED", +"/ c #F0F0F0", +"( c #ECECEC", +"_ c #E6E6E6", +": c #E7E7E7", +"< c #E9E9E9", +"[ c #EFEFEF", +"} c #DBDBDB", +"| c #D3D3D3", +"1 c #D0D0D0", +"2 c #D1D1D1", +"3 c #D4D4D4", +"4 c #D7D7D7", +"5 c #DADADA", +"6 c #DEDEDE", +"7 c #E1E1E1", +"8 c #EEEEEE", +"9 c #DFDFDF", +"0 c #D6D6D6", +"a c #D2D2D2", +"b c #D5D5D5", +"c c #D9D9D9", +"d c #DCDCDC", +"e c #E2E2E2", +"f c #F1F1F1", +"g c #E3E3E3", +"h c #CCCCCC", +"i c #C1C1C1", +"j c #BDBDBD", +"k c #C0C0C0", +"l c #C4C4C4", +"m c #C7C7C7", +"n c #CACACA", +"o c #CECECE", +"p c #D8D8D8", +"q c #CBCBCB", +"r c #BFBFBF", +"s c #BCBCBC", +"t c #BEBEBE", +"u c #C5C5C5", +"v c #C8C8C8", +"w c #DDDDDD", +"x c #E0E0E0", +"y c #C9C9C9", +"z c #CFCFCF", +"A c #DCE1D9", +"B c #809471", +"C c #8D9C82", +"D c #98A390", +"E c #949D8E", +"F c #9CA199", +"G c #A5A6A4", +"H c #B0B0B0", +"I c #B4B4B4", +"J c #B6B6B6", +"K c #B7B7B7", +"L c #BBBBBB", +"M c #C2C2C2", +"N c #858585", +"O c #9A9A9A", +"P c #9C9C9C", +"Q c #A0A0A0", +"R c #AFAFAF", +"S c #B3B3B3", +"T c #B9B9B9", +"U c #BABABA", +"V c #C6C6C6", +"W c #CDCDCD", +"X c #F9F8F8", +"Y c #AEAEAE", +"Z c #A9A9A9", +"` c #ADADAD", +" . c #B1B1B1", +".. c #C6CEBF", +"+. c #406328", +"@. c #3E6027", +"#. c #3D5F26", +"$. c #3C5B26", +"%. c #466333", +"&. c #4D673C", +"*. c #596F49", +"=. c #657858", +"-. c #717F66", +";. c #848E7D", +">. c #969B93", +",. c #9EA19B", +"'. c #B5B5B5", +"). c #C3C3C3", +"!. c #000000", +"~. c #090909", +"{. c #151515", +"]. c #262626", +"^. c #333333", +"/. c #454545", +"(. c #5D5D5D", +"_. c #737373", +":. c #8F8F8F", +"<. c #979797", +"[. c #A3A3A3", +"}. c #B8B8B8", +"|. c #F3EBE9", +"1. c #B37062", +"2. c #A86253", +"3. c #A4766C", +"4. c #A07C75", +"5. c #8B7772", +"6. c #7D7876", +"7. c #848180", +"8. c #8D8D8D", +"9. c #919191", +"0. c #989898", +"a. c #9E9E9E", +"b. c #A7A7A7", +"c. c #C9D1C3", +"d. c #3D5E26", +"e. c #3A5A24", +"f. c #3B5C25", +"g. c #3C5D25", +"h. c #3B5C24", +"i. c #466233", +"j. c #546C44", +"k. c #627553", +"l. c #6D7D61", +"m. c #7E8A76", +"n. c #868F81", +"o. c #949990", +"p. c #A1A3A0", +"q. c #020202", +"r. c #040404", +"s. c #141414", +"t. c #2B2B2B", +"u. c #424242", +"v. c #565656", +"w. c #686868", +"x. c #777777", +"y. c #8B8B8B", +"z. c #A5A5A5", +"A. c #EDDFDC", +"B. c #98321E", +"C. c #9A1E04", +"D. c #941D04", +"E. c #901B04", +"F. c #861F09", +"G. c #822915", +"H. c #87301D", +"I. c #853829", +"J. c #754034", +"K. c #74524A", +"L. c #81635E", +"M. c #816D69", +"N. c #7C7573", +"O. c #828282", +"P. c #959595", +"Q. c #999999", +"R. c #ABABAB", +"S. c #3A5B24", +"T. c #3B5B24", +"U. c #3B5B25", +"V. c #3E6026", +"W. c #3E5F26", +"X. c #425F2E", +"Y. c #4A6538", +"Z. c #536B43", +"`. c #617454", +" + c #707F65", +".+ c #808B78", +"++ c #91978D", +"@+ c #989C95", +"#+ c #A2A4A1", +"$+ c #030303", +"%+ c #0F0F0F", +"&+ c #1C1C1C", +"*+ c #2F2F2F", +"=+ c #464646", +"-+ c #5C5C5C", +";+ c #6D6D6D", +">+ c #878787", +",+ c #EEE1DE", +"'+ c #9C3C29", +")+ c #931C04", +"!+ c #8D1B04", +"~+ c #8E1B04", +"{+ c #911C04", +"]+ c #951D04", +"^+ c #961D04", +"/+ c #921C04", +"(+ c #8E1C06", +"_+ c #851E0A", +":+ c #7B2311", +"<+ c #7F3121", +"[+ c #833F31", +"}+ c #78493E", +"|+ c #70554E", +"1+ c #78635E", +"2+ c #817270", +"3+ c #7F7B79", +"4+ c #868686", +"5+ c #A1A1A1", +"6+ c #A4A4A4", +"7+ c #A8A8A8", +"8+ c #3C5E26", +"9+ c #43602F", +"0+ c #516A40", +"a+ c #5E7350", +"b+ c #6A7B5F", +"c+ c #76836D", +"d+ c #828C7B", +"e+ c #A3A4A2", +"f+ c #AAAAAA", +"g+ c #B2B2B2", +"h+ c #010101", +"i+ c #101010", +"j+ c #393939", +"k+ c #4D4D4D", +"l+ c #5F5F5F", +"m+ c #707070", +"n+ c #888888", +"o+ c #A2A2A2", +"p+ c #EDE0DD", +"q+ c #8C1B04", +"r+ c #8B1B04", +"s+ c #8F1B04", +"t+ c #8F1C04", +"u+ c #941C04", +"v+ c #901C04", +"w+ c #8C1B05", +"x+ c #87200C", +"y+ c #7B2816", +"z+ c #793526", +"A+ c #7D4135", +"B+ c #7A4B42", +"C+ c #735650", +"D+ c #7B6A66", +"E+ c #847977", +"F+ c #828180", +"G+ c #8A8A8A", +"H+ c #929292", +"I+ c #9F9F9F", +"J+ c #395924", +"K+ c #405E2B", +"L+ c #546B42", +"M+ c #627655", +"N+ c #6E7E63", +"O+ c #7C8874", +"P+ c #8C9487", +"Q+ c #93988F", +"R+ c #A0A29F", +"S+ c #0A0A0A", +"T+ c #161616", +"U+ c #282828", +"V+ c #414141", +"W+ c #535353", +"X+ c #7F7F7F", +"Y+ c #9D9D9D", +"Z+ c #E9DCD9", +"`+ c #993B28", +" @ c #8A1B04", +".@ c #971D04", +"+@ c #891B04", +"@@ c #8A1F09", +"#@ c #85230F", +"$@ c #7A2D1C", +"%@ c #783C2E", +"&@ c #7D483D", +"*@ c #7D534B", +"=@ c #765D57", +"-@ c #786D6A", +";@ c #857C7B", +">@ c #888685", +",@ c #3C5E25", +"'@ c #415E2D", +")@ c #4E673C", +"!@ c #667858", +"~@ c #728167", +"{@ c #7C8875", +"]@ c #8F968A", +"^@ c #0D0D0D", +"/@ c #212121", +"(@ c #313131", +"_@ c #696969", +":@ c #DFD3D0", +"<@ c #933726", +"[@ c #861A04", +"}@ c #881A04", +"|@ c #891A04", +"1@ c #8A1A04", +"2@ c #88230E", +"3@ c #892A17", +"4@ c #7D301F", +"5@ c #743C30", +"6@ c #7B4C41", +"7@ c #825B53", +"8@ c #78655F", +"9@ c #787471", +"0@ c #828080", +"a@ c #909090", +"b@ c #3D5C28", +"c@ c #4F683E", +"d@ c #5E7351", +"e@ c #697B5D", +"f@ c #78866F", +"g@ c #869080", +"h@ c #8F968B", +"i@ c #9DA09B", +"j@ c #060606", +"k@ c #111111", +"l@ c #222222", +"m@ c #3D3D3D", +"n@ c #505050", +"o@ c #656565", +"p@ c #7B7B7B", +"q@ c #CFC4C1", +"r@ c #8A3525", +"s@ c #831904", +"t@ c #7E1804", +"u@ c #801904", +"v@ c #811904", +"w@ c #841904", +"x@ c #851A04", +"y@ c #951C04", +"z@ c #821C06", +"A@ c #832612", +"B@ c #852E1D", +"C@ c #7F3629", +"D@ c #744034", +"E@ c #775149", +"F@ c #7E625C", +"G@ c #7A6B68", +"H@ c #797775", +"I@ c #818181", +"J@ c #8E8E8E", +"K@ c #939393", +"L@ c #3C5C25", +"M@ c #3F5D2A", +"N@ c #607451", +"O@ c #6C7C60", +"P@ c #78856F", +"Q@ c #9DA09A", +"R@ c #A1A29F", +"S@ c #0C0C0C", +"T@ c #1B1B1B", +"U@ c #3C3C3C", +"V@ c #525252", +"W@ c #B8AEAC", +"X@ c #7B2F20", +"Y@ c #761603", +"Z@ c #721603", +"`@ c #751703", +" # c #761703", +".# c #781703", +"+# c #791703", +"@# c #7B1803", +"## c #7D1804", +"$# c #871A04", +"%# c #821F0B", +"&# c #7C2714", +"*# c #812E1D", +"=# c #81392C", +"-# c #75453B", +";# c #765851", +"># c #7C6460", +",# c #7E6F6C", +"'# c #7C7977", +")# c #4B6539", +"!# c #5C714D", +"~# c #67795A", +"{# c #76836C", +"]# c #838D7C", +"^# c #8D9488", +"/# c #9A9E98", +"(# c #1D1D1D", +"_# c #373737", +":# c #4C4C4C", +"<# c #626262", +"[# c #727272", +"}# c #ACACAC", +"|# c #ABA2A0", +"1# c #722B1E", +"2# c #6B1503", +"3# c #671403", +"4# c #681403", +"5# c #691403", +"6# c #6C1503", +"7# c #6D1503", +"8# c #6F1503", +"9# c #731603", +"0# c #771703", +"a# c #791704", +"b# c #7B1804", +"c# c #7F1904", +"d# c #821904", +"e# c #841A04", +"f# c #8E1C04", +"g# c #831F0B", +"h# c #7C2816", +"i# c #823826", +"j# c #824235", +"k# c #754B42", +"l# c #725A54", +"m# c #7D6863", +"n# c #857774", +"o# c #817E7D", +"p# c #949494", +"q# c #A6A6A6", +"r# c #50683E", +"s# c #5B714C", +"t# c #6E7E61", +"u# c #5E6B55", +"v# c #12190B", +"w# c #080D05", +"x# c #050803", +"y# c #272727", +"z# c #3A3A3A", +"A# c #736C6A", +"B# c #5A2319", +"C# c #571103", +"D# c #5B1203", +"E# c #611303", +"F# c #651303", +"G# c #661403", +"H# c #661303", +"I# c #6B1403", +"J# c #6E1503", +"K# c #701503", +"L# c #741603", +"M# c #961C04", +"N# c #8B1C05", +"O# c #8E1F09", +"P# c #87220E", +"Q# c #792919", +"R# c #7B392B", +"S# c #81463B", +"T# c #7C5148", +"U# c #735B54", +"V# c #796C69", +"W# c #857D7B", +"X# c #848383", +"Y# c #8C8C8C", +"Z# c #375623", +"`# c #314D1F", +" $ c #293F19", +".$ c #223515", +"+$ c #1B2911", +"@$ c #15210E", +"#$ c #0F180A", +"$$ c #070B04", +"%$ c #040100", +"&$ c #0D0200", +"*$ c #1B0501", +"=$ c #260701", +"-$ c #310901", +";$ c #3A0B02", +">$ c #430D02", +",$ c #511003", +"'$ c #5C1203", +")$ c #5F1203", +"!$ c #631303", +"~$ c #711603", +"{$ c #751603", +"]$ c #7A1703", +"^$ c #7C1803", +"/$ c #7D1903", +"($ c #831A04", +"_$ c #851904", +":$ c #8A200C", +"<$ c #882816", +"[$ c #793021", +"}$ c #7D493F", +"|$ c #7E564F", +"1$ c #77625D", +"2$ c #78726F", +"3$ c #827F7E", +"4$ c #385723", +"5$ c #355120", +"6$ c #304A1E", +"7$ c #2A401A", +"8$ c #203114", +"9$ c #1B2A11", +"0$ c #131E0C", +"a$ c #0D1408", +"b$ c #080C05", +"c$ c #020301", +"d$ c #030000", +"e$ c #0A0200", +"f$ c #110300", +"g$ c #1C0501", +"h$ c #2A0802", +"i$ c #320A02", +"j$ c #400C02", +"k$ c #4A0E02", +"l$ c #5A1203", +"m$ c #601203", +"n$ c #651403", +"o$ c #6A1503", +"p$ c #6F1603", +"q$ c #841C06", +"r$ c #82210E", +"s$ c #842918", +"t$ c #7D3324", +"u$ c #743D31", +"v$ c #7B5047", +"w$ c #7F5F58", +"x$ c #786965", +"y$ c #7B7775", +"z$ c #858282", +"A$ c #385623", +"B$ c #2E471D", +"C$ c #283E1A", +"D$ c #294019", +"E$ c #314B1E", +"F$ c #334F1F", +"G$ c #314C1F", +"H$ c #2C441B", +"I$ c #243917", +"J$ c #1E2F13", +"K$ c #18250F", +"L$ c #111B0B", +"M$ c #020201", +"N$ c #020000", +"O$ c #0B0200", +"P$ c #180501", +"Q$ c #210601", +"R$ c #2C0801", +"S$ c #350A02", +"T$ c #4F1002", +"U$ c #5A1103", +"V$ c #5C1103", +"W$ c #601303", +"X$ c #621303", +"Y$ c #6A1403", +"Z$ c #701603", +"`$ c #7B1703", +" % c #7D1803", +".% c #7F1804", +"+% c #801804", +"@% c #931D04", +"#% c #831E0A", +"$% c #822815", +"%% c #842F1F", +"&% c #7B372A", +"*% c #734338", +"=% c #7A564E", +"-% c #846761", +";% c #7E6D6A", +">% c #797876", +",% c #9B9B9B", +"'% c #385722", +")% c #355321", +"!% c #3A5924", +"~% c #375721", +"{% c #385922", +"]% c #3B5D25", +"^% c #243717", +"/% c #0F130B", +"(% c #080A07", +"_% c #030502", +":% c #121C0B", +"<% c #365422", +"[% c #3E6127", +"}% c #365421", +"|% c #2A421A", +"1% c #213415", +"2% c #1D2D12", +"3% c #0E1609", +"4% c #090E06", +"5% c #020402", +"6% c #010000", +"7% c #060100", +"8% c #0E0200", +"9% c #190501", +"0% c #280801", +"a% c #3E0C02", +"b% c #480E02", +"c% c #591103", +"d% c #641303", +"e% c #631403", +"f% c #731703", +"g% c #741703", +"h% c #7C1804", +"i% c #8C1C05", +"j% c #811E0A", +"k% c #843424", +"l% c #834032", +"m% c #73483F", +"n% c #7F6A65", +"o% c #807471", +"p% c #7F7D7C", +"q% c #35551F", +"r% c #2E4B1B", +"s% c #213512", +"t% c #14210A", +"u% c #192910", +"v% c #37492B", +"w% c #445636", +"x% c #2B421C", +"y% c #2D471B", +"z% c #2B421A", +"A% c #101909", +"B% c #010002", +"C% c #000001", +"D% c #16220E", +"E% c #335020", +"F% c #345121", +"G% c #2D471C", +"H% c #273D18", +"I% c #213314", +"J% c #1A2910", +"K% c #080E05", +"L% c #030501", +"M% c #010200", +"N% c #040000", +"O% c #140401", +"P% c #200601", +"Q% c #270701", +"R% c #340A02", +"S% c #4D0F03", +"T% c #911B04", +"U% c #8A1E07", +"V% c #81220E", +"W% c #7A2A19", +"X% c #7D3729", +"Y% c #7E4439", +"Z% c #765148", +"`% c #725E58", +" & c #7C6B68", +".& c #827977", +"+& c #818080", +"@& c #969696", +"#& c #3B5727", +"$& c #485A3A", +"%& c #3D4836", +"&& c #3B4038", +"*& c #191818", +"=& c #030403", +"-& c #242622", +";& c #787A76", +">& c #747872", +",& c #1E241A", +"'& c #060B03", +")& c #101809", +"!& c #1C2A11", +"~& c #2B431B", +"{& c #3B5D23", +"]& c #3A5C22", +"^& c #395A22", +"/& c #375720", +"(& c #35541F", +"_& c #314D1E", +":& c #2B431A", +"<& c #203313", +"[& c #1B2C0F", +"}& c #131E0B", +"|& c #0F1809", +"1& c #0A1007", +"2& c #040502", +"3& c #030100", +"4& c #160401", +"5& c #250701", +"6& c #3C0B02", +"7& c #440D02", +"8& c #4C0F02", +"9& c #581103", +"0& c #611203", +"a& c #621203", +"b& c #7A1704", +"c& c #8E1A04", +"d& c #8F1A04", +"e& c #891D08", +"f& c #832410", +"g& c #7B301F", +"h& c #7A3E30", +"i& c #7F4B40", +"j& c #7A544D", +"k& c #75605B", +"l& c #7D716F", +"m& c #878180", +"n& c #3A5A23", +"o& c #3F5C2B", +"p& c #5E6D53", +"q& c #A0A39E", +"r& c #C3C2C3", +"s& c #B1B1B2", +"t& c #8D8D8E", +"u& c #737273", +"v& c #777677", +"w& c #828182", +"x& c #302F30", +"y& c #0B1007", +"z& c #395923", +"A& c #35561E", +"B& c #446330", +"C& c #6C835C", +"D& c #698159", +"E& c #536D41", +"F& c #5B6F4D", +"G& c #6E7F64", +"H& c #647857", +"I& c #536B42", +"J& c #466232", +"K& c #3E5C29", +"L& c #365521", +"M& c #345221", +"N& c #314C1E", +"O& c #2B441C", +"P& c #263A18", +"Q& c #1C2B11", +"R& c #14200D", +"S& c #060904", +"T& c #080100", +"U& c #3C0C02", +"V& c #4A0E03", +"W& c #531003", +"X& c #5E1203", +"Y& c #711503", +"Z& c #7A1803", +"`& c #881904", +" * c #871904", +".* c #861903", +"+* c #871903", +"@* c #8B1A04", +"#* c #602004", +"$* c #462605", +"%* c #412705", +"&* c #4A2605", +"** c #5E2105", +"=* c #741D04", +"-* c #871B04", +";* c #861C06", +">* c #8A2410", +",* c #842917", +"'* c #783325", +")* c #744033", +"!* c #804D43", +"~* c #805B53", +"{* c #766560", +"]* c #7A7573", +"^* c #868382", +"/* c #375820", +"(* c #546E42", +"_* c #ABB3A4", +":* c #E3E2E3", +"<* c #EBEAEB", +"[* c #7A7A7A", +"}* c #323232", +"|* c #0F1709", +"1* c #375821", +"2* c #516C3D", +"3* c #99A690", +"4* c #CFD3CC", +"5* c #CFD4CD", +"6* c #C0C5BD", +"7* c #C0C3BF", +"8* c #CBCDCB", +"9* c #C2C3C0", +"0* c #AEB2AC", +"a* c #9DA399", +"b* c #818B7A", +"c* c #495B3D", +"d* c #2A4319", +"e* c #355221", +"f* c #253A17", +"g* c #1E2D12", +"h* c #17240F", +"i* c #121B0B", +"j* c #0C1208", +"k* c #030202", +"l* c #020102", +"m* c #080807", +"n* c #1B1E1B", +"o* c #080200", +"p* c #130301", +"q* c #210701", +"r* c #370A02", +"s* c #480E03", +"t* c #731503", +"u* c #751401", +"v* c #721400", +"w* c #651601", +"x* c #631802", +"y* c #711800", +"z* c #7D1901", +"A* c #801801", +"B* c #7F1401", +"C* c #871703", +"D* c #6C1C04", +"E* c #232D06", +"F* c #0E3707", +"G* c #0F3707", +"H* c #113707", +"I* c #173407", +"J* c #233006", +"K* c #472505", +"L* c #801B04", +"M* c #911A04", +"N* c #8D1A04", +"O* c #831D07", +"P* c #852713", +"Q* c #872F1E", +"R* c #7D3728", +"S* c #734134", +"T* c #7B544B", +"U* c #82635D", +"V* c #796C68", +"W* c #7A7978", +"X* c #273C18", +"Y* c #263B17", +"Z* c #324D1F", +"`* c #3C5C26", +" = c #597347", +".= c #B7BFB1", +"+= c #787878", +"@= c #121212", +"#= c #4B4B4B", +"$= c #898989", +"%= c #4E4E4E", +"&= c #15210D", +"*= c #395A23", +"== c #3F5E29", +"-= c #698058", +";= c #B5BDAE", +">= c #E2E2E1", +",= c #E9E8E9", +"'= c #EAE9EA", +")= c #E7E7E8", +"!= c #E8E7E8", +"~= c #E5E4E5", +"{= c #949693", +"]= c #262B22", +"^= c #050C00", +"/= c #0C1408", +"(= c #213214", +"_= c #3D6026", +":= c #324D1E", +"<= c #2B441B", +"[= c #243817", +"}= c #16230E", +"|= c #090D05", +"1= c #050703", +"2= c #161715", +"3= c #424740", +"4= c #555C53", +"5= c #4E534C", +"6= c #343732", +"7= c #242723", +"8= c #474D46", +"9= c #798375", +"0= c #0E0300", +"a= c #220601", +"b= c #310A02", +"c= c #380B02", +"d= c #470E02", +"e= c #4F0F03", +"f= c #551103", +"g= c #5D1203", +"h= c #671301", +"i= c #671A03", +"j= c #5B2407", +"k= c #352B07", +"l= c #222A02", +"m= c #4F3B14", +"n= c #7E5231", +"o= c #865232", +"p= c #733718", +"q= c #521B01", +"r= c #312002", +"s= c #0F2E04", +"t= c #0F3406", +"u= c #113506", +"v= c #113606", +"w= c #103606", +"x= c #0E3807", +"y= c #113507", +"z= c #432505", +"A= c #741C04", +"B= c #7F1B04", +"C= c #8B1802", +"D= c #8C1903", +"E= c #7F1F0A", +"F= c #7F2816", +"G= c #813021", +"H= c #7C3C30", +"I= c #74493E", +"J= c #755850", +"K= c #7E6662", +"L= c #7C7B7A", +"M= c #243816", +"N= c #090E05", +"O= c #040802", +"P= c #0C1505", +"Q= c #203611", +"R= c #2B4319", +"S= c #223613", +"T= c #223814", +"U= c #2B4619", +"V= c #365620", +"W= c #587146", +"X= c #B9C1B4", +"Y= c #1E2E13", +"Z= c #3A5A25", +"`= c #3C5D24", +" - c #36571F", +".- c #43622F", +"+- c #819474", +"@- c #CACFC7", +"#- c #E7E6E7", +"$- c #E6E6E7", +"%- c #949394", +"&- c #1D1D1E", +"*- c #1C2C12", +"=- c #2F481D", +"-- c #395823", +";- c #3A5B25", +">- c #30491D", +",- c #283D18", +"'- c #203214", +")- c #1A2911", +"!- c #141F0D", +"~- c #0C1307", +"{- c #131711", +"]- c #535951", +"^- c #848E81", +"/- c #8D9789", +"(- c #8E978A", +"_- c #8F988C", +":- c #858D81", +"<- c #868F83", +"[- c #98A494", +"}- c #717A6D", +"|- c #222320", +"1- c #10110F", +"2- c #2A2D29", +"3- c #1B1D1B", +"4- c #353A34", +"5- c #232723", +"6- c #2D312B", +"7- c #52584F", +"8- c #575D54", +"9- c #393E38", +"0- c #171917", +"a- c #0D0E0C", +"b- c #030404", +"c- c #1D0601", +"d- c #320901", +"e- c #3B0B02", +"f- c #460E02", +"g- c #551002", +"h- c #5E1403", +"i- c #693219", +"j- c #745A43", +"k- c #746B57", +"l- c #69725F", +"m- c #596D52", +"n- c #6E7862", +"o- c #7D8072", +"p- c #7C8171", +"q- c #797C68", +"r- c #294113", +"s- c #0F3101", +"t- c #143908", +"u- c #0E2F03", +"v- c #102F06", +"w- c #103006", +"x- c #0E2F04", +"y- c #0F2F03", +"z- c #0F3306", +"A- c #133106", +"B- c #212B06", +"C- c #332605", +"D- c #661C04", +"E- c #861904", +"F- c #8E1B05", +"G- c #8F1904", +"H- c #8D1802", +"I- c #8E1F03", +"J- c #8A1D01", +"K- c #871700", +"L- c #881500", +"M- c #891600", +"N- c #8A1801", +"O- c #8B1A03", +"P- c #891B05", +"Q- c #83220F", +"R- c #7C2C1A", +"S- c #813627", +"T- c #7F4235", +"U- c #744D44", +"V- c #775F59", +"W- c #816E6B", +"X- c #817775", +"Y- c #80807F", +"Z- c #385622", +"`- c #2D451C", +" ; c #040703", +".; c #010201", +"+; c #41453E", +"@; c #71786C", +"#; c #575C54", +"$; c #31342E", +"%; c #242C1D", +"&; c #2B401D", +"*; c #35531F", +"=; c #385821", +"-; c #3A532A", +";; c #90978B", +">; c #E4E3E4", +",; c #363636", +"'; c #080A06", +"); c #3F4F34", +"!; c #597148", +"~; c #4C6839", +"{; c #728664", +"]; c #CBCFC8", +"^; c #EBEAEC", +"/; c #3A393A", +"(; c #263917", +"_; c #385921", +":; c #36561F", +"<; c #395922", +"[; c #375522", +"}; c #375524", +"|; c #476235", +"1; c #546D44", +"2; c #5D7250", +"3; c #607355", +"4; c #718068", +"5; c #798771", +"6; c #7D8977", +"7; c #869081", +"8; c #6E746B", +"9; c #626860", +"0; c #747B72", +"a; c #575D55", +"b; c #050505", +"c; c #262925", +"d; c #3A3E38", +"e; c #141613", +"f; c #2E322D", +"g; c #798274", +"h; c #A5B4A0", +"i; c #9AA695", +"j; c #A0AD9B", +"k; c #BDCDB8", +"l; c #BECDB9", +"m; c #AEBBA8", +"n; c #939E8F", +"o; c #848F80", +"p; c #697166", +"q; c #313530", +"r; c #150701", +"s; c #272018", +"t; c #3D413D", +"u; c #434944", +"v; c #4F564C", +"w; c #5C6158", +"x; c #686C67", +"y; c #737772", +"z; c #787E75", +"A; c #7F8480", +"B; c #576D4D", +"C; c #546A4A", +"D; c #63745A", +"E; c #38522A", +"F; c #0B2A01", +"G; c #0C2902", +"H; c #153709", +"I; c #153809", +"J; c #0D2D02", +"K; c #0C2D04", +"L; c #0C3006", +"M; c #0A3006", +"N; c #252705", +"O; c #661803", +"P; c #7D1703", +"Q; c #861804", +"R; c #74290B", +"S; c #592E0B", +"T; c #712C0A", +"U; c #954620", +"V; c #A87553", +"W; c #A17858", +"X; c #985F3D", +"Y; c #914622", +"Z; c #923714", +"`; c #912708", +" > c #891700", +".> c #871702", +"+> c #901A04", +"@> c #8D1D06", +"#> c #891F0A", +"$> c #7F2310", +"%> c #792D1C", +"&> c #813E30", +"*> c #824A40", +"=> c #75544C", +"-> c #72625D", +";> c #7F706C", +">> c #877E7C", +",> c #848484", +"'> c #3A5923", +")> c #29401A", +"!> c #1D2C12", +"~> c #040602", +"{> c #404040", +"]> c #CCCCCD", +"^> c #DBDBDC", +"/> c #D7D7D8", +"(> c #C8C8C9", +"_> c #B3B2B3", +":> c #7D827B", +"<> c #304224", +"[> c #33521E", +"}> c #253C15", +"|> c #50564B", +"1> c #D2D1D2", +"2> c #EAEAEB", +"3> c #121211", +"4> c #2C3129", +"5> c #7D8477", +"6> c #C1C6BD", +"7> c #E1E2E1", +"8> c #474747", +"9> c #233516", +"0> c #4D653C", +"a> c #547042", +"b> c #3D5D27", +"c> c #36581F", +"d> c #3D5B27", +"e> c #435F2F", +"f> c #4C663B", +"g> c #576E48", +"h> c #617653", +"i> c #66795B", +"j> c #6F7E66", +"k> c #727E6D", +"l> c #353A33", +"m> c #222421", +"n> c #687066", +"o> c #899385", +"p> c #6E756C", +"q> c #313431", +"r> c #070707", +"s> c #121411", +"t> c #4D534A", +"u> c #909C8C", +"v> c #A0AB99", +"w> c #B1BEAB", +"x> c #B6C4B0", +"y> c #B9C8B4", +"z> c #C0CFBA", +"A> c #C2D0BB", +"B> c #C4D3BE", +"C> c #C6D6C1", +"D> c #C9D9C3", +"E> c #C1D0BA", +"F> c #A3AF9E", +"G> c #444A43", +"H> c #000300", +"I> c #090D07", +"J> c #20221F", +"K> c #393A39", +"L> c #4B4D4B", +"M> c #757375", +"N> c #686F62", +"O> c #264319", +"P> c #314C25", +"Q> c #637259", +"R> c #627357", +"S> c #39552C", +"T> c #133208", +"U> c #0A2701", +"V> c #0C2904", +"W> c #0C2C05", +"X> c #2C2004", +"Y> c #661603", +"Z> c #721503", +"`> c #7B1603", +" , c #7D1D07", +"., c #61300E", +"+, c #304211", +"@, c #1B4510", +"#, c #29460F", +"$, c #50662C", +"%, c #708B5F", +"&, c #739064", +"*, c #7E9467", +"=, c #909671", +"-, c #A4997E", +";, c #AD8A73", +">, c #985A34", +",, c #6C2B06", +"', c #5A1A00", +"), c #612005", +"!, c #6B1F04", +"~, c #881D07", +"{, c #8D230D", +"], c #852815", +"^, c #763020", +"/, c #784034", +"(, c #804E44", +"_, c #7B5A52", +":, c #74635E", +"<, c #7B7473", +"[, c #848282", +"}, c #324E1F", +"|, c #18260F", +"1, c #020300", +"2, c #EEEEEF", +"3, c #DEDDDF", +"4, c #737671", +"5, c #1F3013", +"6, c #253C16", +"7, c #13210A", +"8, c #373935", +"9, c #1F1F1F", +"0, c #010001", +"a, c #908F90", +"b, c #555555", +"c, c #040403", +"d, c #626661", +"e, c #A9B2A5", +"f, c #6F8460", +"g, c #365720", +"h, c #35571E", +"i, c #446031", +"j, c #465E36", +"k, c #596F4B", +"l, c #66795A", +"m, c #75846B", +"n, c #6D7B66", +"o, c #475042", +"p, c #191B18", +"q, c #1A1C1A", +"r, c #5B6259", +"s, c #929D8D", +"t, c #9FAC9B", +"u, c #96A292", +"v, c #97A293", +"w, c #9DA898", +"x, c #98A493", +"y, c #A2AF9D", +"z, c #B1BEAC", +"A, c #B2BFAC", +"B, c #A7B4A2", +"C, c #AFBDA9", +"D, c #BAC9B5", +"E, c #C3D2BD", +"F, c #AEBDAA", +"G, c #3D423C", +"H, c #040304", +"I, c #161617", +"J, c #1D2119", +"K, c #33372E", +"L, c #5B595A", +"M, c #5B5E57", +"N, c #425239", +"O, c #254019", +"P, c #112E07", +"Q, c #0B2804", +"R, c #0C2805", +"S, c #331C03", +"T, c #6B1303", +"U, c #641C06", +"V, c #47330E", +"W, c #214010", +"X, c #17410F", +"Y, c #1A410E", +"Z, c #18420E", +"`, c #17440E", +" ' c #1A460C", +".' c #1B470D", +"+' c #245017", +"@' c #315D25", +"#' c #547B49", +"$' c #94A591", +"%' c #B2AEA5", +"&' c #808361", +"*' c #253E0B", +"=' c #112B00", +"-' c #1E2F06", +";' c #5A2204", +">' c #831C07", +",' c #862410", +"'' c #832C1B", +")' c #773829", +"!' c #744337", +"~' c #7D5047", +"{' c #7E5E58", +"]' c #776966", +"^' c #7D7977", +"/' c #868585", +"(' c #2F4A1E", +"_' c #15200D", +":' c #040701", +"<' c #0E0E0E", +"[' c #D6D6D7", +"}' c #545653", +"|' c #050A03", +"1' c #5E5E5E", +"2' c #030203", +"3' c #161516", +"4' c #666566", +"5' c #AAAFA7", +"6' c #728864", +"7' c #385822", +"8' c #3A5B23", +"9' c #37581F", +"0' c #405F2B", +"a' c #476433", +"b' c #3D572C", +"c' c #2A401C", +"d' c #213215", +"e' c #17230E", +"f' c #10190A", +"g' c #080C06", +"h' c #0A0D0A", +"i' c #0F110E", +"j' c #434741", +"k' c #838B80", +"l' c #949C90", +"m' c #8A9387", +"n' c #899386", +"o' c #889284", +"p' c #8F998A", +"q' c #8D9989", +"r' c #9EA999", +"s' c #A1AD9C", +"t' c #9BA796", +"u' c #94A191", +"v' c #A4B29F", +"w' c #B9C7B3", +"x' c #A8B4A2", +"y' c #484E46", +"z' c #09080A", +"A' c #141315", +"B' c #161A12", +"C' c #0D1809", +"D' c #081503", +"E' c #061903", +"F' c #0B1803", +"G' c #381403", +"H' c #541F08", +"I' c #2C310B", +"J' c #163A0D", +"K' c #15390C", +"L' c #17390C", +"M' c #18390C", +"N' c #173A0C", +"O' c #17390A", +"P' c #173B0B", +"Q' c #163B0A", +"R' c #143A08", +"S' c #143D05", +"T' c #355A24", +"U' c #869483", +"V' c #A8ABAB", +"W' c #6E8664", +"X' c #1E4911", +"Y' c #073100", +"Z' c #1B2F05", +"`' c #422605", +" ) c #691E05", +".) c #8C1A04", +"+) c #832915", +"@) c #822F1F", +"#) c #79382B", +"$) c #74453B", +"%) c #7E5A51", +"&) c #826762", +"*) c #796F6C", +"=) c #7D7C7B", +"-) c #365321", +";) c #1D2D11", +">) c #000200", +",) c #0D0C0D", +"') c #2A292A", +")) c #575757", +"!) c #838383", +"~) c #ADACAD", +"{) c #121213", +"]) c #1A1A1A", +"^) c #434343", +"/) c #666667", +"() c #BABDB9", +"_) c #86987B", +":) c #3F602B", +"<) c #3A5C23", +"[) c #345122", +"}) c #375028", +"|) c #465B38", +"1) c #5A6C4E", +"2) c #6A7B60", +"3) c #6C7B63", +"4) c #6E7B68", +"5) c #777F72", +"6) c #80887D", +"7) c #889385", +"8) c #8D9689", +"9) c #90998B", +"0) c #929C8E", +"a) c #959F90", +"b) c #8A9587", +"c) c #8C9687", +"d) c #99A594", +"e) c #9CA998", +"f) c #ACB9A7", +"g) c #A5B2A0", +"h) c #5B6157", +"i) c #0B0B0A", +"j) c #090B09", +"k) c #000100", +"l) c #0D0501", +"m) c #1B0702", +"n) c #280902", +"o) c #1D1907", +"p) c #0D2409", +"q) c #0E2608", +"r) c #122B0A", +"s) c #14330B", +"t) c #16360B", +"u) c #16370C", +"v) c #17380C", +"w) c #18390D", +"x) c #16380B", +"y) c #113406", +"z) c #244815", +"A) c #66765D", +"B) c #999998", +"C) c #798672", +"D) c #294C1A", +"E) c #082F00", +"F) c #0B3205", +"G) c #212F06", +"H) c #671F05", +"I) c #8F1701", +"J) c #8B1500", +"K) c #8C1801", +"L) c #7F220E", +"M) c #812E1C", +"N) c #823627", +"O) c #7F3F32", +"P) c #734A40", +"Q) c #785C56", +"R) c #826B67", +"S) c #817673", +"T) c #7E7F7E", +"U) c #375622", +"V) c #283E19", +"W) c #18260E", +"X) c #0D1407", +"Y) c #1D1C1D", +"Z) c #747474", +"`) c #181818", +" ! c #3D3C3E", +".! c #8F928E", +"+! c #677C59", +"@! c #3C5B25", +"#! c #385A21", +"$! c #3C5B27", +"%! c #405E2C", +"&! c #476234", +"*! c #4E673E", +"=! c #596F4C", +"-! c #65785A", +";! c #6A7B61", +">! c #788571", +",! c #7D8A78", +"'! c #7E897A", +")! c #7C867A", +"!! c #868E83", +"~! c #889183", +"{! c #919C8D", +"]! c #AAB7A5", +"^! c #B5C3AF", +"/! c #838D7E", +"(! c #282B27", +"_! c #0E0F0C", +":! c #343832", +"~ c #755952", +",~ c #766662", +"'~ c #7F7370", +")~ c #86807F", +"!~ c #2F4A1D", +"~~ c #1D2E12", +"{~ c #0D1606", +"]~ c #070A05", +"^~ c #181718", +"/~ c #2E2E2E", +"(~ c #4F4F50", +"_~ c #808080", +":~ c #797979", +"<~ c #717171", +"[~ c #6B6B6B", +"}~ c #636363", +"|~ c #0A0A0B", +"1~ c #363537", +"2~ c #919A8C", +"3~ c #546E41", +"4~ c #34561D", +"5~ c #72806B", +"6~ c #8A9386", +"7~ c #A2AF9E", +"8~ c #AFBDAA", +"9~ c #CBDBC5", +"0~ c #BFCEB9", +"a~ c #7E877A", +"b~ c #3B3F39", +"c~ c #0A0B0A", +"d~ c #212420", +"e~ c #434840", +"f~ c #1D201C", +"g~ c #010100", +"h~ c #020C00", +"i~ c #2E4722", +"j~ c #6E7667", +"k~ c #91918F", +"l~ c #718366", +"m~ c #325823", +"n~ c #1B4E0C", +"o~ c #799772", +"p~ c #B9BFBB", +"q~ c #8F795A", +"r~ c #7A2803", +"s~ c #8B1700", +"t~ c #881B04", +"u~ c #871F09", +"v~ c #89230E", +"w~ c #822817", +"x~ c #773527", +"y~ c #7B463A", +"z~ c #81544A", +"A~ c #7A5C55", +"B~ c #786B67", +"C~ c #8D8C8C", +"D~ c #283F18", +"E~ c #0E1908", +"F~ c #0F0E0F", +"G~ c #7D7D7D", +"H~ c #9FAB97", +"I~ c #466432", +"J~ c #72816C", +"K~ c #899285", +"L~ c #8F9A8B", +"M~ c #AAB8A5", +"N~ c #C1D0BB", +"O~ c #CCDBC5", +"P~ c #D5E5CE", +"Q~ c #C5D4BF", +"R~ c #879183", +"S~ c #333732", +"T~ c #070807", +"U~ c #222521", +"V~ c #0E100E", +"W~ c #010401", +"X~ c #0D2A04", +"Y~ c #213E13", +"Z~ c #5A6B4F", +"`~ c #92968D", +" { c #A4A99F", +".{ c #6E8960", +"+{ c #396723", +"@{ c #719065", +"#{ c #B6BDB5", +"${ c #A29478", +"%{ c #923E1A", +"&{ c #7A2A18", +"*{ c #787372", +"={ c #355121", +"-{ c #1F3112", +";{ c #0C1207", +">{ c #272628", +",{ c #676767", +"'{ c #3B3B3B", +"){ c #484848", +"!{ c #545454", +"~{ c #D9D9DA", +"{{ c #D5D8D4", +"]{ c #708562", +"^{ c #71806A", +"/{ c #8C9588", +"({ c #98A393", +"_{ c #9DA998", +":{ c #B5C2AF", +"<{ c #B0BEAC", +"[{ c #BCCBB7", +"}{ c #CDDCC6", +"|{ c #D1E1CA", +"1{ c #B8C5B1", +"2{ c #5F665C", +"3{ c #1D1F1C", +"4{ c #0C131D", +"5{ c #264A47", +"6{ c #0F2D02", +"7{ c #133604", +"8{ c #365826", +"9{ c #788A6E", +"0{ c #AFB2AB", +"a{ c #A3AC9C", +"b{ c #6D8E58", +"c{ c #739260", +"d{ c #A6B7AA", +"e{ c #B19B85", +"f{ c #963411", +"g{ c #8C1500", +"h{ c #7B200E", +"i{ c #625D5D", +"j{ c #304B1E", +"k{ c #15230B", +"l{ c #0B0E09", +"m{ c #8C8C8D", +"n{ c #5A5A5A", +"o{ c #E0DFE0", +"p{ c #D8DBD7", +"q{ c #798D6C", +"r{ c #606D5A", +"s{ c #8C9689", +"t{ c #9BA696", +"u{ c #A9B6A4", +"v{ c #B6C5B1", +"w{ c #B9C7B4", +"x{ c #ABB9A6", +"y{ c #BFCEB8", +"z{ c #CEDDC7", +"A{ c #CEDEC8", +"B{ c #8C9788", +"C{ c #191B19", +"D{ c #363934", +"E{ c #020302", +"F{ c #0E1725", +"G{ c #2C5158", +"H{ c #143106", +"I{ c #15360A", +"J{ c #123906", +"K{ c #174408", +"L{ c #426930", +"M{ c #92A288", +"N{ c #BBBBB8", +"O{ c #839A74", +"P{ c #6D8F57", +"Q{ c #A4B4A1", +"R{ c #A38061", +"S{ c #871E01", +"T{ c #8C1702", +"U{ c #921B03", +"V{ c #6E1A09", +"W{ c #403F41", +"X{ c #0B1504", +"Y{ c #5F5F60", +"Z{ c #3E3E3E", +"`{ c #7A797A", +" ] c #CED0CC", +".] c #33551D", +"+] c #34531E", +"@] c #374032", +"#] c #81897D", +"$] c #95A190", +"%] c #B4C1AF", +"&] c #B1C0AD", +"*] c #BDCCB7", +"=] c #C2D0BC", +"-] c #B7C5B1", +";] c #C8D7C2", +">] c #D4E4CD", +",] c #858F81", +"'] c #535B51", +")] c #3C423B", +"!] c #0E1623", +"~] c #2B5055", +"{] c #193F0E", +"]] c #1A430D", +"^] c #154307", +"/] c #215010", +"(] c #6C895B", +"_] c #B2B6AD", +":] c #A2AC99", +"<] c #A1AE9D", +"[] c #A4AF9A", +"}] c #755122", +"|] c #891A00", +"1] c #8D1903", +"2] c #6F1A08", +"3] c #334F20", +"4] c #060C02", +"5] c #868586", +"6] c #2C2C2C", +"7] c #383838", +"8] c #252525", +"9] c #0B0B0B", +"0] c #929392", +"a] c #94A28B", +"b] c #3E5D2A", +"c] c #34551E", +"d] c #3E5D28", +"e] c #355520", +"f] c #1B2216", +"g] c #686F66", +"h] c #8C9889", +"i] c #B6C4B1", +"j] c #ACBAA6", +"k] c #B4C2AF", +"l] c #B7C5B2", +"m] c #C9D8C2", +"n] c #C6D5BF", +"o] c #CFDEC8", +"p] c #C4D4BE", +"q] c #99A595", +"r] c #B8C7B3", +"s] c #869183", +"t] c #0D0E0D", +"u] c #1D460F", +"v] c #1F4B10", +"w] c #1A470C", +"x] c #184A06", +"y] c #5D8048", +"z] c #B5B7B3", +"A] c #BCBABD", +"B] c #A7B3A4", +"C] c #6C854A", +"D] c #793B0F", +"E] c #901A03", +"F] c #8C1A03", +"G] c #414042", +"H] c #030601", +"I] c #080709", +"J] c #A3A5A2", +"K] c #A3AF99", +"L] c #738966", +"M] c #7A8C6E", +"N] c #85957A", +"O] c #567044", +"P] c #385823", +"Q] c #080D04", +"R] c #3F423E", +"S] c #949F8F", +"T] c #BAC8B4", +"U] c #BBC9B5", +"V] c #BBCAB5", +"W] c #B8C6B3", +"X] c #ACB9A6", +"Y] c #C3D1BD", +"Z] c #B7C4B1", +"`] c #747D71", +" ^ c #838C7E", +".^ c #171916", +"+^ c #1E4B10", +"@^ c #214E12", +"#^ c #1B490D", +"$^ c #285914", +"%^ c #678B52", +"&^ c #849C74", +"*^ c #6C8E56", +"=^ c #336B22", +"-^ c #514913", +";^ c #8E2208", +">^ c #2D461C", +",^ c #131C0B", +"'^ c #010301", +")^ c #202020", +"!^ c #353435", +"~^ c #989797", +"{^ c #CDD0CB", +"]^ c #D8DAD7", +"^^ c #BBC2B6", +"/^ c #42612C", +"(^ c #070D03", +"_^ c #0C0B0C", +":^ c #676F64", +"<^ c #ABB7A5", +"[^ c #BDCBB6", +"}^ c #BFCDBA", +"|^ c #C4D2BD", +"1^ c #D7E7D0", +"2^ c #8B9587", +"3^ c #141513", +"4^ c #2C2F2B", +"5^ c #575E55", +"6^ c #1D4A0F", +"7^ c #1E4C0F", +"8^ c #1D4E0D", +"9^ c #417128", +"0^ c #70925B", +"a^ c #7D976B", +"b^ c #4F7B40", +"c^ c #45460F", +"d^ c #892106", +"e^ c #8E1A03", +"f^ c #030401", +"g^ c #646464", +"h^ c #8E8D8E", +"i^ c #A5A4A5", +"j^ c #989798", +"k^ c #898C86", +"l^ c #5C6D50", +"m^ c #43612E", +"n^ c #080E04", +"o^ c #31352F", +"p^ c #8B9586", +"q^ c #C2D1BC", +"r^ c #B1BFAC", +"s^ c #ADBAA8", +"t^ c #C3D3BE", +"u^ c #666E62", +"v^ c #2C302C", +"w^ c #143105", +"x^ c #16370B", +"y^ c #163C0B", +"z^ c #164108", +"A^ c #194709", +"B^ c #1B4B0A", +"C^ c #184907", +"D^ c #184C05", +"E^ c #728D63", +"F^ c #BABAB9", +"G^ c #B8BAB6", +"H^ c #AFB9AD", +"I^ c #736638", +"J^ c #7E1900", +"K^ c #901903", +"L^ c #121E0A", +"M^ c #010300", +"N^ c #515151", +"O^ c #7C7C7C", +"P^ c #131313", +"Q^ c #252425", +"R^ c #2E2F2D", +"S^ c #344329", +"T^ c #2B3426", +"U^ c #2D2F2C", +"V^ c #6F786C", +"W^ c #BDCBB7", +"X^ c #6B7469", +"Y^ c #373C35", +"Z^ c #333731", +"`^ c #2F332E", +" / c #4A4F47", +"./ c #252824", +"+/ c #090908", +"@/ c #262824", +"#/ c #383D37", +"$/ c #3E423C", +"%/ c #51574F", +"&/ c #424741", +"*/ c #0D1623", +"=/ c #2D5356", +"-/ c #143206", +";/ c #1E4610", +">/ c #426730", +",/ c #587A44", +"'/ c #5E814A", +")/ c #628451", +"!/ c #79936C", +"~/ c #B9B9B7", +"{/ c #A5AE9F", +"]/ c #5C8049", +"^/ c #A1AF9E", +"// c #ACA694", +"(/ c #763810", +"_/ c #7F1200", +":/ c #8C1E06", +"( c #292929", +",( c #060A04", +"'( c #717F69", +")( c #7E867B", +"!( c #7D8679", +"~( c #272A25", +"{( c #020101", +"]( c #0F110F", +"^( c #0A1420", +"/( c #385D61", +"(( c #676E5E", +"_( c #8D8A8F", +":( c #7F8B79", +"<( c #50723F", +"[( c #2D581B", +"}( c #1A4409", +"|( c #174107", +"1( c #0F3A00", +"2( c #0E3501", +"3( c #123806", +"4( c #153A07", +"5( c #113605", +"6( c #103A01", +"7( c #3A6428", +"8( c #7D9671", +"9( c #A0AF98", +"0( c #A8B49F", +"a( c #AFB9AA", +"b( c #B5BDB2", +"c( c #B4A38C", +"d( c #A3512E", +"e( c #8F1A01", +"f( c #8E1903", +"g( c #304C1E", +"h( c #15210C", +"i( c #666666", +"j( c #616161", +"k( c #050802", +"l( c #1E2E12", +"m( c #365322", +"n( c #707E69", +"o( c #899286", +"p( c #97A393", +"q( c #676E63", +"r( c #000101", +"s( c #111210", +"t( c #282A26", +"u( c #282B26", +"v( c #10120F", +"w( c #07111D", +"x( c #536D80", +"y( c #7C7B77", +"z( c #5F7054", +"A( c #264A17", +"B( c #0B3300", +"C( c #0C3101", +"D( c #0A3200", +"E( c #0D3700", +"F( c #0E3600", +"G( c #0C3400", +"H( c #0D3400", +"I( c #123705", +"J( c #133806", +"K( c #0D3501", +"L( c #133F03", +"M( c #275316", +"N( c #3D652C", +"O( c #527540", +"P( c #67865A", +"Q( c #799A71", +"R( c #798049", +"S( c #5A3008", +"T( c #631C02", +"U( c #801C04", +"V( c #0B0F08", +"W( c #0A0A0C", +"X( c #444444", +"Y( c #606060", +"Z( c #6F6F6F", +"`( c #6C6C6C", +" _ c #020401", +"._ c #365221", +"+_ c #707F6A", +"@_ c #8B9689", +"#_ c #99A494", +"$_ c #575E54", +"%_ c #1B1E1A", +"&_ c #8D9788", +"*_ c #B4C1AE", +"=_ c #8E9888", +"-_ c #373B35", +";_ c #07121C", +">_ c #5B718A", +",_ c #636C58", +"'_ c #1C3C0D", +")_ c #092A00", +"!_ c #0D2E02", +"~_ c #0C3300", +"{_ c #164305", +"]_ c #355F23", +"^_ c #5F7F4E", +"/_ c #678258", +"(_ c #376026", +"__ c #164107", +":_ c #0E3502", +"<_ c #143907", +"[_ c #113705", +"}_ c #0B3400", +"|_ c #0E3800", +"1_ c #144104", +"2_ c #19460D", +"3_ c #153C09", +"4_ c #1C3206", +"5_ c #3B2905", +"6_ c #731D04", +"7_ c #314E1E", +"8_ c #17240E", +"9_ c #252623", +"0_ c #4D4C4D", +"a_ c #3F3F3F", +"b_ c #2A2A2A", +"c_ c #848D81", +"d_ c #565D54", +"e_ c #040504", +"f_ c #CFDFC9", +"g_ c #D0E0C9", +"h_ c #D1E0C9", +"i_ c #3A3F39", +"j_ c #5B7289", +"k_ c #475839", +"l_ c #092600", +"m_ c #0B2A02", +"n_ c #153D06", +"o_ c #3C6429", +"p_ c #7C936D", +"q_ c #AFB5AA", +"r_ c #BEBFBC", +"s_ c #B1B9A9", +"t_ c #AAB5A2", +"u_ c #B3B9AF", +"v_ c #758F67", +"w_ c #1D490C", +"x_ c #143A07", +"y_ c #133907", +"z_ c #113704", +"A_ c #103604", +"B_ c #113806", +"C_ c #0F3906", +"D_ c #292F06", +"E_ c #652004", +"F_ c #0D100A", +"G_ c #2B2B2C", +"H_ c #646465", +"I_ c #687662", +"J_ c #777F74", +"K_ c #AEBCA9", +"L_ c #6F786B", +"M_ c #919C8C", +"N_ c #C6D5C0", +"O_ c #B7C6B1", +"P_ c #C9D7C3", +"Q_ c #BECDB8", +"R_ c #CADAC4", +"S_ c #D3E3CD", +"T_ c #A2AE9D", +"U_ c #1D1E1C", +"V_ c #101210", +"W_ c #333631", +"X_ c #4A5A3C", +"Y_ c #072500", +"Z_ c #1B3F0D", +"`_ c #6C845D", +" : c #ADB1A8", +".: c #BFBDBE", +"+: c #9FAB96", +"@: c #698859", +"#: c #446C31", +"$: c #446D31", +"%: c #8EA084", +"&: c #C4C3C3", +"*: c #758F66", +"=: c #144006", +"-: c #0E3601", +";: c #0F3900", +">: c #103A00", +",: c #0B3804", +"': c #223005", +"): c #652005", +"!: c #365522", +"~: c #090D06", +"{: c #060506", +"]: c #595959", +"^: c #040405", +"/: c #6B7964", +"(: c #80887C", +"_: c #838D7F", +":: c #A8B5A3", +"<: c #9FAB9A", +"[: c #3B4039", +"}: c #B4C3AF", +"|: c #CEDEC7", +"1: c #CCDCC6", +"2: c #5E645A", +"3: c #1B1D1A", +"4: c #848F7F", +"5: c #596057", +"6: c #1F211E", +"7: c #5F6956", +"8: c #113604", +"9: c #556E49", +"0: c #B0ADAF", +"a: c #A7ABA2", +"b: c #648551", +"c: c #2D5C19", +"d: c #174806", +"e: c #164608", +"f: c #154405", +"g: c #24550F", +"h: c #889B7D", +"i: c #557746", +"j: c #103704", +"k: c #123E04", +"l: c #345F22", +"m: c #608050", +"n: c #738F64", +"o: c #4E733C", +"p: c #1B470C", +"q: c #083600", +"r: c #182E01", +"s: c #522206", +"t: c #171718", +"u: c #020203", +"v: c #0C1308", +"w: c #283F19", +"x: c #868E82", +"y: c #899585", +"z: c #9FAC9A", +"A: c #8D9889", +"B: c #222522", +"C: c #5E665C", +"D: c #B2C1AE", +"E: c #CADAC3", +"F: c #848E80", +"G: c #777F73", +"H: c #D3E3CC", +"I: c #474C45", +"J: c #07121D", +"K: c #526D7E", +"L: c #73766D", +"M: c #526746", +"N: c #848C7F", +"O: c #AAA8A8", +"P: c #587B46", +"Q: c #154804", +"R: c #19470A", +"S: c #1F4C10", +"T: c #204E11", +"U: c #164506", +"V: c #325F1F", +"W: c #ADB4A7", +"X: c #98A690", +"Y: c #103503", +"Z: c #103603", +"`: c #164306", +" < c #5F814E", +".< c #A8B2A2", +"+< c #BDBEBA", +"@< c #B9BBB4", +"#< c #B8BAB3", +"$< c #93A389", +"%< c #5D804C", +"&< c #1D5012", +"*< c #112F00", +"=< c #522204", +"-< c #841C04", +";< c #141F0C", +">< c #030402", +",< c #070C04", +"'< c #263A17", +")< c #3B5A24", +"!< c #6F7D68", +"~< c #8A9487", +"{< c #94A08F", +"]< c #A0AC9B", +"^< c #BECCB7", +"/< c #9BA797", +"(< c #C7D6C1", +"_< c #AFBCAA", +":< c #B8C6B2", +"<< c #BECCB8", +"[< c #C8D8C2", +"}< c #CAD9C3", +"|< c #8A9586", +"1< c #070706", +"2< c #1F221E", +"3< c #707A6D", +"4< c #BECCB9", +"5< c #D2E3CC", +"6< c #BCC9B6", +"7< c #565D53", +"8< c #091320", +"9< c #3F6168", +"0< c #6F7368", +"a< c #888787", +"b< c #9C9A9D", +"c< c #919C89", +"d< c #2E5B1B", +"e< c #174609", +"f< c #1E4B0F", +"g< c #1A4D09", +"h< c #819774", +"i< c #A9B1A3", +"j< c #275116", +"k< c #0E3401", +"l< c #133E03", +"m< c #668555", +"n< c #BDBDBA", +"o< c #BCBCBB", +"p< c #799269", +"q< c #466E34", +"r< c #678556", +"s< c #99A98E", +"t< c #C0C0BD", +"u< c #93A48A", +"v< c #29591C", +"w< c #0B3100", +"x< c #412605", +"y< c #841B04", +"z< c #921A04", +"A< c #223616", +"B< c #0D1508", +"C< c #757575", +"D< c #7E7E7E", +"E< c #293F1A", +"F< c #717F6A", +"G< c #858F82", +"H< c #919D8D", +"I< c #9CA897", +"J< c #BFCDB9", +"K< c #C3D3BD", +"L< c #B8C7B2", +"M< c #C6D6C0", +"N< c #CAD9C4", +"O< c #050504", +"P< c #5A6158", +"Q< c #B6C3B0", +"R< c #BFCFBA", +"S< c #BECEB8", +"T< c #D2E2CB", +"U< c #C7D7C1", +"V< c #778074", +"W< c #1B1C19", +"X< c #2A5153", +"Y< c #3B512B", +"Z< c #6D7765", +"`< c #7F8A77", +" [ c #527441", +".[ c #1E4B0D", +"+[ c #1F4B0F", +"@[ c #1E4C10", +"#[ c #1C4D0B", +"$[ c #7E946F", +"%[ c #A2AD9A", +"&[ c #234E13", +"*[ c #0D3201", +"=[ c #0F3901", +"-[ c #51763F", +";[ c #B6B8B2", +">[ c #5E814C", +",[ c #1C4E0A", +"'[ c #164606", +")[ c #194907", +"![ c #265512", +"~[ c #6E8B5E", +"{[ c #BFBEBC", +"][ c #9DAC93", +"^[ c #376628", +"/[ c #0B3200", +"([ c #3D2402", +"_[ c #781C04", +":[ c #1B2910", +"<[ c #070B05", +"[[ c #09090A", +"}[ c #181819", +"|[ c #6B7864", +"1[ c #818A7D", +"2[ c #8E998A", +"3[ c #B1BEAA", +"4[ c #CDDBC6", +"5[ c #ABB8A5", +"6[ c #C0CEB9", +"7[ c #C5D3BE", +"8[ c #798477", +"9[ c #B7C6B2", +"0[ c #BFCEBA", +"a[ c #C1CFBB", +"b[ c #323631", +"c[ c #0E1723", +"d[ c #2A4F54", +"e[ c #123003", +"f[ c #1D3E0E", +"g[ c #244A14", +"h[ c #1D480D", +"i[ c #1D490F", +"j[ c #204D11", +"k[ c #1D4C0F", +"l[ c #1F500E", +"m[ c #8D9E83", +"n[ c #98A68E", +"o[ c #1D480C", +"p[ c #092F00", +"q[ c #214C10", +"r[ c #9AA98F", +"s[ c #C0BEBF", +"t[ c #5C7E4B", +"u[ c #164805", +"v[ c #1B4A0C", +"w[ c #1A4D07", +"x[ c #5F814D", +"y[ c #B9BBB5", +"z[ c #487239", +"A[ c #0D3D01", +"B[ c #2D2701", +"C[ c #781C05", +"D[ c #1C2C11", +"E[ c #1E1D1E", +"F[ c #585858", +"G[ c #1A2810", +"H[ c #6D7A66", +"I[ c #80897D", +"J[ c #A5B1A1", +"K[ c #B0BDAB", +"L[ c #B2C0AC", +"M[ c #C5D3BF", +"N[ c #BAC9B4", +"O[ c #737C6F", +"P[ c #C8D6C1", +"Q[ c #AFBDAB", +"R[ c #132F05", +"S[ c #123407", +"T[ c #153B0A", +"U[ c #1B440E", +"V[ c #1C4B0E", +"W[ c #245512", +"X[ c #9AA890", +"Y[ c #889C7B", +"Z[ c #154005", +"`[ c #072E00", +" } c #385C28", +".} c #B7BAB1", +"+} c #1E500B", +"@} c #1B490C", +"#} c #214E11", +"$} c #174906", +"%} c #4D733A", +"&} c #ABB2A5", +"*} c #B9BCB4", +"=} c #6D8E61", +"-} c #18460B", +";} c #282701", +">} c #671F04", +",} c #355220", +"'} c #080708", +")} c #6D7A65", +"!} c #A0AC9C", +"~} c #B3C1AD", +"{} c #C9D7C2", +"]} c #545A51", +"^} c #121312", +"/} c #939F8F", +"(} c #D1E2CC", +"_} c #BAC8B5", +":} c #B9C8B3", +"<} c #D4E5CE", +"[} c #A9B7A5", +"}} c #232623", +"|} c #1A4A0A", +"1} c #3B6728", +"2} c #B0B6A9", +"3} c #79916B", +"4} c #103B00", +"5} c #406031", +"6} c #B2B8AB", +"7} c #164706", +"8} c #1D4B0E", +"9} c #174706", +"0} c #3A6626", +"a} c #C7C4C8", +"b} c #718E64", +"c} c #0C3F00", +"d} c #1F2B01", +"e} c #6C1F05", +"f} c #3C5B24", +"g} c #121D0C", +"h} c #10180A", +"i} c #63705D", +"j} c #929D8E", +"k} c #CBDAC4", +"l} c #BBCAB6", +"m} c #C3D2BE", +"n} c #333531", +"o} c #121412", +"p} c #B3C1AE", +"q} c #B2C0AD", +"r} c #C5D5BF", +"s} c #C0CFBB", +"t} c #C9D8C3", +"u} c #D1E2CB", +"v} c #95A191", +"w} c #204E10", +"x} c #557844", +"y} c #6C895E", +"z} c #0A3100", +"A} c #436535", +"B} c #AEB6A5", +"C} c #476C37", +"D} c #164707", +"E} c #1F4D11", +"F} c #154506", +"G} c #2B5B17", +"H} c #92A487", +"I} c #5E7F4E", +"J} c #0A3A00", +"K} c #262A03", +"L} c #6F1E05", +"M} c #345020", +"N} c #3B5B26", +"O} c #798276", +"P} c #C8D8C3", +"Q} c #CBDBC6", +"R} c #2A2E29", +"S} c #20231F", +"T} c #95A090", +"U} c #204D10", +"V} c #5B7E4C", +"W} c #BEBEBB", +"X} c #597A4B", +"Y} c #0C3500", +"Z} c #486A3A", +"`} c #AFB6A8", +" | c #476D37", +".| c #174708", +"+| c #356222", +"@| c #A1AC99", +"#| c #BFBEBB", +"$| c #597D49", +"%| c #0C3B01", +"&| c #2B2B04", +"*| c #662005", +"=| c #851B04", +"-| c #4F4F4F", +";| c #1E1E1E", +">| c #2D2D2D", +",| c #121E0C", +"'| c #6C7A66", +")| c #838B7F", +"!| c #96A191", +"~| c #C6D4BF", +"{| c #C1D0BC", +"]| c #869083", +"^| c #383D36", +"/| c #A4B09F", +"(| c #B2C1AD", +"_| c #D2E2CC", +":| c #1E4C0E", +"<| c #235311", +"[| c #859B78", +"}| c #BCBDB9", +"|| c #4C6F3D", +"1| c #0A3300", +"2| c #113C04", +"3| c #6C885C", +"4| c #B4B8B0", +"5| c #456C35", +"6| c #99A78F", +"7| c #B9BCB5", +"8| c #442805", +"9| c #14220C", +"0| c #324F1E", +"a| c #65735F", +"b| c #A0AD9C", +"c| c #BBC8B4", +"d| c #C1D1BC", +"e| c #CBDAC5", +"f| c #5C6359", +"g| c #010202", +"h| c #C3D2BC", +"i| c #CCDBC4", +"j| c #CCDAC5", +"k| c #C4D3BF", +"l| c #B0BEAB", +"m| c #D1E1CB", +"n| c #A9B6A3", +"o| c #1A4809", +"p| c #3F6A2B", +"q| c #B1B6AB", +"r| c #AFB6AA", +"s| c #3B642A", +"t| c #073000", +"u| c #1F490F", +"v| c #B1B5AB", +"w| c #3C652A", +"x| c #184709", +"y| c #134505", +"z| c #366223", +"A| c #B3B7AE", +"B| c #8FA084", +"C| c #154206", +"D| c #0B3704", +"E| c #143706", +"F| c #442706", +"G| c #7C1C04", +"H| c #030602", +"I| c #5B5B5B", +"J| c #111310", +"K| c #253519", +"L| c #626E5B", +"M| c #7A8478", +"N| c #8E9A8A", +"O| c #B0BDAA", +"P| c #CBD9C4", +"Q| c #CADAC5", +"R| c #677065", +"S| c #C8D7C1", +"T| c #BCCBB6", +"U| c #B9C6B3", +"V| c #AAB7A4", +"W| c #6E776B", +"X| c #0B0C0B", +"Y| c #174808", +"Z| c #4A7138", +"`| c #BABCB6", +" 1 c #8FA186", +".1 c #1E4A0D", +"+1 c #255014", +"@1 c #A6AFA1", +"#1 c #2B5A18", +"$1 c #174A06", +"%1 c #7A926D", +"&1 c #B8BBB2", +"*1 c #3A6328", +"=1 c #103806", +"-1 c #123807", +";1 c #332B05", +">1 c #7A1C04", +",1 c #192710", +"'1 c #575657", +")1 c #6E726B", +"!1 c #2B3F1C", +"~1 c #6A7863", +"{1 c #7E877B", +"]1 c #A0AC9A", +"^1 c #C2D2BC", +"/1 c #C7D7C2", +"(1 c #CDDDC7", +"_1 c #161916", +":1 c #727C6F", +"<1 c #B6C5B0", +"[1 c #AFBEAA", +"}1 c #7B8477", +"|1 c #174709", +"11 c #426A2F", +"21 c #B6BBB0", +"31 c #809576", +"41 c #123D04", +"51 c #376125", +"61 c #B2B7AE", +"71 c #275713", +"81 c #1B4A0D", +"91 c #174807", +"01 c #4A7139", +"a1 c #95A58B", +"b1 c #376224", +"c1 c #0E3A00", +"d1 c #0D3703", +"e1 c #103907", +"f1 c #3A2A05", +"g1 c #7D1C04", +"h1 c #060A03", +"i1 c #656566", +"j1 c #191F15", +"k1 c #284018", +"l1 c #6B7965", +"m1 c #868F82", +"n1 c #A7B4A3", +"o1 c #AFBCA9", +"p1 c #6B7368", +"q1 c #3D413B", +"r1 c #B6C5B2", +"s1 c #ACBAA7", +"t1 c #B8C5B2", +"u1 c #BCCAB5", +"v1 c #CEDDC8", +"w1 c #D0E0CA", +"x1 c #060605", +"y1 c #1C4A0D", +"z1 c #275616", +"A1 c #9FAA97", +"B1 c #819676", +"C1 c #103A03", +"D1 c #0B3500", +"E1 c #5E7E4F", +"F1 c #C0C0BF", +"G1 c #819873", +"H1 c #1F500D", +"I1 c #21520F", +"J1 c #6D8C5C", +"K1 c #B3B8AF", +"L1 c #618151", +"M1 c #174405", +"N1 c #093400", +"O1 c #402805", +"P1 c #821C04", +"Q1 c #6C7A65", +"R1 c #94A090", +"S1 c #B5C4B0", +"T1 c #C0CEBA", +"U1 c #666E63", +"V1 c #424640", +"W1 c #6C7368", +"X1 c #0E0F0E", +"Y1 c #0A0B09", +"Z1 c #1E4E0C", +"`1 c #95A58D", +" 2 c #7E9371", +".2 c #0F3801", +"+2 c #0C3600", +"@2 c #6F8B62", +"#2 c #B8BBB4", +"$2 c #4A7237", +"%2 c #1D4B0D", +"&2 c #4B723A", +"*2 c #A1AC98", +"=2 c #BFBFBC", +"-2 c #829974", +";2 c #2F591F", +">2 c #0B3900", +",2 c #123304", +"'2 c #4B2302", +")2 c #871902", +"!2 c #2F2E2F", +"~2 c #232323", +"{2 c #345120", +"]2 c #C7D6C0", +"^2 c #B4C2AE", +"/2 c #CFDEC9", +"(2 c #464B44", +"_2 c #232622", +":2 c #A9B5A4", +"<2 c #CDDCC7", +"[2 c #ADBBA8", +"}2 c #BCCAB6", +"|2 c #C2D2BD", +"12 c #C1D1BB", +"22 c #CFDFC8", +"32 c #757D70", +"42 c #0C0D0C", +"52 c #1E221E", +"62 c #144504", +"72 c #3F6A2A", +"82 c #AFB6A9", +"92 c #7D926F", +"02 c #0C3700", +"a2 c #708B63", +"b2 c #B2B6AC", +"c2 c #376124", +"d2 c #154605", +"e2 c #2F5D1B", +"f2 c #7D9570", +"g2 c #BFBEBD", +"h2 c #ADB4A6", +"i2 c #4D723B", +"j2 c #164B09", +"k2 c #324D13", +"l2 c #682706", +"m2 c #8C1904", +"n2 c #0B1107", +"o2 c #030304", +"p2 c #8B9588", +"q2 c #939E8E", +"r2 c #9AA696", +"s2 c #899485", +"t2 c #4D534B", +"u2 c #0F100E", +"v2 c #697165", +"w2 c #B1C0AC", +"x2 c #B5C3B0", +"y2 c #131412", +"z2 c #265613", +"A2 c #597D47", +"B2 c #A5AE9E", +"C2 c #C5C2C4", +"D2 c #688758", +"E2 c #547545", +"F2 c #BCBEB8", +"G2 c #5D7F4D", +"H2 c #1D4E0B", +"I2 c #547A41", +"J2 c #ACB3A5", +"K2 c #B1B6AC", +"L2 c #6F905B", +"M2 c #789761", +"N2 c #64632F", +"O2 c #6E2002", +"P2 c #233715", +"Q2 c #12170F", +"R2 c #060903", +"S2 c #65725E", +"T2 c #838D80", +"U2 c #CFDEC7", +"V2 c #C5D4BE", +"W2 c #C4D3BD", +"X2 c #525950", +"Y2 c #1C4B0D", +"Z2 c #275614", +"`2 c #BDBCBB", +" 3 c #859C77", +".3 c #2A561A", +"+3 c #103703", +"@3 c #0F3402", +"#3 c #245014", +"$3 c #A2AE9A", +"%3 c #A7B0A0", +"&3 c #2F5D1C", +"*3 c #194809", +"=3 c #1C4A0E", +"-3 c #144604", +";3 c #3F692D", +">3 c #AEB3A8", +",3 c #B8B9B4", +"'3 c #94A985", +")3 c #4B7536", +"!3 c #312F03", +"~3 c #761B03", +"{3 c #284019", +"]3 c #0E1708", +"^3 c #3B3D3B", +"/3 c #B7B7B8", +"(3 c #0A1006", +"_3 c #7F887D", +":3 c #4A5049", +"<3 c #4A5048", +"[3 c #C6D5C1", +"}3 c #484E45", +"|3 c #184909", +"13 c #577B45", +"23 c #BDBDBB", +"33 c #A8B0A1", +"43 c #597D45", +"53 c #1C480B", +"63 c #0F3702", +"73 c #143806", +"83 c #5A7B49", +"93 c #789169", +"03 c #1B4C09", +"a3 c #154604", +"b3 c #537541", +"c3 c #BCBCBA", +"d3 c #9DAA92", +"e3 c #295916", +"f3 c #083200", +"g3 c #3C2905", +"h3 c #17230D", +"i3 c #6E7C67", +"j3 c #656D62", +"k3 c #8E9889", +"l3 c #BDCBB8", +"m3 c #194908", +"n3 c #6C885D", +"o3 c #C3C1C2", +"p3 c #6F8C61", +"q3 c #0C3A00", +"r3 c #0E3402", +"s3 c #0D3401", +"t3 c #204B0F", +"u3 c #B6B9B2", +"v3 c #40692F", +"w3 c #194808", +"x3 c #184807", +"y3 c #6C895D", +"z3 c #819773", +"A3 c #1E4E0F", +"B3 c #0D3101", +"C3 c #4B2606", +"D3 c #121D0B", +"E3 c #192610", +"F3 c #97A392", +"G3 c #BAC7B4", +"H3 c #D4E3CD", +"I3 c #9CA797", +"J3 c #181A17", +"K3 c #808A7C", +"L3 c #C4D2BE", +"M3 c #B1BFAB", +"N3 c #2C302B", +"O3 c #1F4C11", +"P3 c #628251", +"Q3 c #C3C0C2", +"R3 c #7E9570", +"S3 c #144004", +"T3 c #628252", +"U3 c #C2BFC0", +"V3 c #678658", +"W3 c #194A08", +"X3 c #1F4D10", +"Y3 c #1F4F0D", +"Z3 c #7A936C", +"`3 c #C5C3C5", +" 4 c #839976", +".4 c #17470A", +"+4 c #163004", +"@4 c #5A2205", +"#4 c #121C0A", +"$4 c #616061", +"%4 c #191819", +"&4 c #BFCDB8", +"*4 c #5E655C", +"=4 c #737B6F", +"-4 c #BAC8B3", +";4 c #CCDAC4", +">4 c #C3D1BC", +",4 c #798376", +"'4 c #1A4909", +")4 c #3B6628", +"!4 c #3D652B", +"~4 c #083100", +"{4 c #0B3600", +"]4 c #587C47", +"^4 c #6D8A5D", +"/4 c #1A4B09", +"(4 c #19480A", +"_4 c #20510E", +":4 c #859A79", +"<4 c #C1C0BE", +"[4 c #527641", +"}4 c #053400", +"|4 c #222F06", +"14 c #681F04", +"24 c #0F1808", +"34 c #696869", +"44 c #97A292", +"54 c #C7D5C0", +"64 c #C0D0BA", +"74 c #CDDEC7", +"84 c #3E433D", +"94 c #3B413A", +"04 c #C9D9C2", +"a4 c #555C52", +"b4 c #769169", +"c4 c #C7C2C7", +"d4 c #8DA081", +"e4 c #255212", +"f4 c #184507", +"g4 c #849B76", +"h4 c #C1BEC0", +"i4 c #698858", +"j4 c #1A4B08", +"k4 c #315F1E", +"l4 c #9EAA95", +"m4 c #245214", +"n4 c #083400", +"o4 c #2E2D06", +"p4 c #751E04", +"q4 c #1F3014", +"r4 c #050902", +"s4 c #66735F", +"t4 c #838C7F", +"u4 c #ADBAA7", +"v4 c #BDCAB6", +"w4 c #D0E1CA", +"x4 c #3F433D", +"y4 c #3D423B", +"z4 c #CCDBC6", +"A4 c #CFE0CA", +"B4 c #40443E", +"C4 c #1A490A", +"D4 c #32601F", +"E4 c #9CAA93", +"F4 c #C5C1C4", +"G4 c #8CA180", +"H4 c #3A6327", +"I4 c #124002", +"J4 c #597C48", +"K4 c #B5B7B1", +"L4 c #B7B9B4", +"M4 c #51773D", +"N4 c #1A490B", +"O4 c #1B490B", +"P4 c #164507", +"Q4 c #164605", +"R4 c #6A8959", +"S4 c #C3C2C0", +"T4 c #859A77", +"U4 c #0B3402", +"V4 c #3A2A06", +"W4 c #7E1C04", +"X4 c #253916", +"Y4 c #757D72", +"Z4 c #D1E0CA", +"`4 c #818B7D", +" 5 c #879283", +".5 c #AEBBA9", +"+5 c #BBC8B5", +"@5 c #909B8C", +"#5 c #60675D", +"$5 c #4F564D", +"%5 c #889484", +"&5 c #184908", +"*5 c #3E692A", +"=5 c #9DAA93", +"-5 c #C6C2C7", +";5 c #ACB3A6", +">5 c #749064", +",5 c #AEB3A9", +"'5 c #C3BFC5", +")5 c #899E7B", +"!5 c #265612", +"~5 c #1C4A0C", +"{5 c #1E4F0C", +"]5 c #295816", +"^5 c #1A490C", +"/5 c #1F4E0E", +"(5 c #386324", +"_5 c #40692E", +":5 c #21500F", +"<5 c #21530F", +"[5 c #839975", +"}5 c #C6C2C4", +"|5 c #758E66", +"15 c #104003", +"25 c #123204", +"35 c #552305", +"45 c #7F887C", +"55 c #A7B3A1", +"65 c #BECBB6", +"75 c #393E37", +"85 c #383C36", +"95 c #646C61", +"05 c #184808", +"a5 c #32611E", +"b5 c #7B946B", +"c5 c #AFB5A9", +"d5 c #BBBCB8", +"e5 c #BFBEBE", +"f5 c #96A78C", +"g5 c #396625", +"h5 c #19490A", +"i5 c #718E60", +"j5 c #97A78D", +"k5 c #628352", +"l5 c #235312", +"m5 c #1A4A0B", +"n5 c #3D672A", +"o5 c #9DAB91", +"p5 c #AFB5A7", +"q5 c #738F62", +"r5 c #21510F", +"s5 c #8E9F83", +"t5 c #BDBEB9", +"u5 c #446A32", +"v5 c #073400", +"w5 c #2E2C06", +"x5 c #1E3013", +"y5 c #7C8479", +"z5 c #C9D9C4", +"A5 c #A8B5A2", +"B5 c #585F56", +"C5 c #292C28", +"D5 c #7D887A", +"E5 c #949F90", +"F5 c #0C0C0B", +"G5 c #5B6158", +"H5 c #587C44", +"I5 c #6C8A5B", +"J5 c #7C956B", +"K5 c #678654", +"L5 c #326120", +"M5 c #4A7236", +"N5 c #8FA183", +"O5 c #C1BEC1", +"P5 c #BABAB7", +"Q5 c #B3B8AE", +"R5 c #C1BFBD", +"S5 c #8B9F7F", +"T5 c #2F5F1B", +"U5 c #134303", +"V5 c #154705", +"W5 c #5B7F45", +"X5 c #B8BAB4", +"Y5 c #B6B7B4", +"Z5 c #B0B6AA", +"`5 c #476F34", +" 6 c #0D3F00", +".6 c #3C672A", +"+6 c #B4B7B0", +"@6 c #0E3102", +"#6 c #472605", +"$6 c #424042", +"%6 c #324F1F", +"&6 c #11190B", +"*6 c #6F7F69", +"=6 c #96A291", +"-6 c #A3B09F", +";6 c #A9B6A5", +">6 c #BBC9B6", +",6 c #A9B7A4", +"'6 c #636A60", +")6 c #717A6E", +"!6 c #393D37", +"~6 c #8C9888", +"{6 c #060706", +"]6 c #1B4B09", +"^6 c #1E4D0C", +"/6 c #1A4C09", +"(6 c #1B4A0B", +"_6 c #2B5917", +":6 c #769165", +"<6 c #B6B8B1", +"[6 c #C3C0C4", +"}6 c #547741", +"|6 c #759166", +"16 c #BFBFBD", +"26 c #50753E", +"36 c #2B5C16", +"46 c #376820", +"56 c #8CA07F", +"66 c #BBBABA", +"76 c #BDBBBC", +"86 c #819973", +"96 c #204F0D", +"06 c #134401", +"a6 c #6B885B", +"b6 c #C3C2BF", +"c6 c #618051", +"d6 c #0B3A00", +"e6 c #173204", +"f6 c #562305", +"g6 c #1B2B10", +"h6 c #3C3B3C", +"i6 c #4C4C4D", +"j6 c #0D1608", +"k6 c #5C6956", +"l6 c #C1CFBA", +"m6 c #CADBC4", +"n6 c #7F897B", +"o6 c #181A18", +"p6 c #C9DAC3", +"q6 c #474C44", +"r6 c #265713", +"s6 c #7F9870", +"t6 c #BEBDBC", +"u6 c #879C7A", +"v6 c #335F21", +"w6 c #ACB5A5", +"x6 c #B7BBB1", +"y6 c #9CA991", +"z6 c #295C13", +"A6 c #829873", +"B6 c #BABBB6", +"C6 c #A1AD98", +"D6 c #2E5A1E", +"E6 c #144404", +"F6 c #2A5917", +"G6 c #9FA998", +"H6 c #B1B7AB", +"I6 c #305B1F", +"J6 c #243006", +"K6 c #701E04", +"L6 c #090F05", +"M6 c #BFBFC0", +"N6 c #0E1807", +"O6 c #304C1D", +"P6 c #365520", +"Q6 c #3A4435", +"R6 c #9AA595", +"S6 c #A4B1A0", +"T6 c #C2D1BB", +"U6 c #CDDDC6", +"V6 c #C7D8C1", +"W6 c #767E72", +"X6 c #C0D0BB", +"Y6 c #A2AD9C", +"Z6 c #1E201D", +"`6 c #194A0A", +" 7 c #487234", +".7 c #B3B6AE", +"+7 c #B8B8B6", +"@7 c #738E60", +"#7 c #204D0D", +"$7 c #0F3504", +"%7 c #103B02", +"&7 c #2D5919", +"*7 c #638355", +"=7 c #B3B6AD", +"-7 c #ADB3A5", +";7 c #3C6728", +">7 c #2C5B17", +",7 c #698A55", +"'7 c #698B56", +")7 c #275417", +"!7 c #154606", +"~7 c #497039", +"{7 c #BBBDB7", +"]7 c #7D956F", +"^7 c #103F02", +"/7 c #0F3304", +"(7 c #C9D2C3", +"_7 c #2E2E2F", +":7 c #172210", +"<7 c #2F4B1C", +"[7 c #3D4738", +"}7 c #7A8277", +"|7 c #B0BEAA", +"17 c #5C6259", +"27 c #818B7E", +"37 c #547A42", +"47 c #95A589", +"57 c #20500D", +"67 c #0C3200", +"77 c #093700", +"87 c #557A44", +"97 c #78916A", +"07 c #225210", +"a7 c #194B08", +"b7 c #7E9472", +"c7 c #C0C0BC", +"d7 c #4D713B", +"e7 c #083500", +"f7 c #1F3005", +"g7 c #263C17", +"h7 c #6C6B6C", +"i7 c #495542", +"j7 c #2E4C1C", +"k7 c #525F4D", +"l7 c #ACB8A6", +"m7 c #CAD8C3", +"n7 c #B9C6B2", +"o7 c #BFCFB9", +"p7 c #BDCCB8", +"q7 c #4E534B", +"r7 c #0E0F0D", +"s7 c #7C8679", +"t7 c #194909", +"u7 c #456F32", +"v7 c #B4B7AF", +"w7 c #A5B09F", +"x7 c #366123", +"y7 c #083300", +"z7 c #0E3403", +"A7 c #133906", +"B7 c #466B36", +"C7 c #79926B", +"D7 c #1A4B0A", +"E7 c #1D4B0F", +"F7 c #325F20", +"G7 c #A5AD9D", +"H7 c #ADB5A7", +"I7 c #366126", +"J7 c #432705", +"K7 c #243915", +"L7 c #2E322B", +"M7 c #A09FA0", +"N7 c #E1E1E0", +"O7 c #8B9883", +"P7 c #3A5726", +"Q7 c #6A7763", +"R7 c #869282", +"S7 c #A5B1A0", +"T7 c #CBDBC4", +"U7 c #CFE0C9", +"V7 c #828C7E", +"W7 c #646B61", +"X7 c #474D45", +"Y7 c #1D1F1B", +"Z7 c #050605", +"`7 c #98A595", +" 8 c #363A34", +".8 c #245410", +"+8 c #899C7B", +"@8 c #C6C1C7", +"#8 c #426A2E", +"$8 c #204D0E", +"%8 c #164105", +"&8 c #0D3500", +"*8 c #0D3301", +"=8 c #093200", +"-8 c #567748", +";8 c #C4C2C2", +">8 c #7C946D", +",8 c #164903", +"'8 c #174608", +")8 c #B7BAB3", +"!8 c #9AA992", +"~8 c #244D12", +"{8 c #3C2201", +"]8 c #C9D2C4", +"^8 c #233614", +"/8 c #5C605A", +"(8 c #DDDCDD", +"_8 c #E8E9E8", +":8 c #E0E1E0", +"<8 c #98A58E", +"[8 c #869084", +"}8 c #AAB8A6", +"|8 c #C4D4BF", +"18 c #A6B3A0", +"28 c #70786D", +"38 c #818C7D", +"48 c #396425", +"58 c #98A78D", +"68 c #C3C0C3", +"78 c #B3B7AF", +"88 c #7F9670", +"98 c #648451", +"08 c #4C7238", +"a8 c #376226", +"b8 c #275216", +"c8 c #0D3C00", +"d8 c #345E23", +"e8 c #AFB4AB", +"f8 c #B2B6B1", +"g8 c #748F65", +"h8 c #3F692C", +"i8 c #1D4D0E", +"j8 c #70845B", +"k8 c #472400", +"l8 c #3E5230", +"m8 c #91948F", +"n8 c #DEDFDD", +"o8 c #8F9D84", +"p8 c #3D5B28", +"q8 c #7B8379", +"r8 c #B3C0AE", +"s8 c #B0BFAB", +"t8 c #444942", +"u8 c #323630", +"v8 c #B1BDAB", +"w8 c #2E312D", +"x8 c #34611F", +"y8 c #728E63", +"z8 c #95A58C", +"A8 c #BABBB7", +"B8 c #B2B7AD", +"C8 c #A3AE9B", +"D8 c #6F8C5F", +"E8 c #305F1C", +"F8 c #4E7838", +"G8 c #91A484", +"H8 c #BEBEBD", +"I8 c #9CAA91", +"J8 c #2D5C1B", +"K8 c #1A4A0C", +"L8 c #255413", +"M8 c #94A78F", +"N8 c #B1AB9C", +"O8 c #743C13", +"P8 c #831600", +"Q8 c #C7CFC1", +"R8 c #41602C", +"S8 c #819276", +"T8 c #D8DAD6", +"U8 c #DBDDDA", +"V8 c #89997F", +"W8 c #3B5926", +"X8 c #A3B09E", +"Y8 c #434841", +"Z8 c #295914", +"`8 c #3B6827", +" 9 c #4C7239", +".9 c #5D814D", +"+9 c #738E62", +"@9 c #849976", +"#9 c #A9B0A3", +"$9 c #799568", +"%9 c #899F7A", +"&9 c #174707", +"*9 c #47723B", +"=9 c #AEAA91", +"-9 c #9A4E2A", +";9 c #881600", +">9 c #5F784D", +",9 c #B7BFB2", +"'9 c #E7E6E6", +")9 c #D9DAD7", +"!9 c #88987D", +"~9 c #64715E", +"{9 c #828A7F", +"]9 c #ADBBA9", +"^9 c #41463F", +"/9 c #174607", +"(9 c #1A4A08", +"_9 c #1C4C0B", +":9 c #1E4E0B", +"<9 c #376324", +"[9 c #6E8D5E", +"}9 c #90A185", +"|9 c #9BA993", +"19 c #A2AE98", +"29 c #5D804A", +"39 c #205312", +"49 c #79834B", +"59 c #A44F2B", +"69 c #8C1700", +"79 c #C8D1C2", +"89 c #788F69", +"99 c #D1D5CE", +"09 c #E9E7E9", +"a9 c #D7D9D4", +"b9 c #839376", +"c9 c #677561", +"d9 c #838C80", +"e9 c #859082", +"f9 c #C6D6BF", +"g9 c #CCDCC5", +"h9 c #ADBBA7", +"i9 c #A6B2A0", +"j9 c #1D4A0E", +"k9 c #22520F", +"l9 c #386524", +"m9 c #356321", +"n9 c #1D4D0D", +"o9 c #194D0E", +"p9 c #4A5B1D", +"q9 c #99421B", +"r9 c #8D1902", +"s9 c #C8D0C3", +"t9 c #6B815C", +"u9 c #C3C8C0", +"v9 c #D5D7D2", +"w9 c #829475", +"x9 c #3D5C27", +"y9 c #889285", +"z9 c #A1AE9C", +"A9 c #B7C6B3", +"B9 c #343933", +"C9 c #1C490D", +"D9 c #1A480B", +"E9 c #1B4F11", +"F9 c #465419", +"G9 c #953A15", +"H9 c #C6CEC1", +"I9 c #3A4F2C", +"J9 c #888C85", +"K9 c #E0E0E1", +"L9 c #CFD3CD", +"M9 c #707E6A", +"N9 c #95A291", +"O9 c #929E8E", +"P9 c #5B6258", +"Q9 c #697266", +"R9 c #D2E1CB", +"S9 c #C3D4BE", +"T9 c #ABB8A6", +"U9 c #194A09", +"V9 c #235410", +"W9 c #396726", +"X9 c #466F33", +"Y9 c #396526", +"Z9 c #2D5C1A", +"`9 c #20500C", +" 0 c #1C4F11", +".0 c #485219", +"+0 c #943714", +"@0 c #8E1902", +"#0 c #C6CEC0", +"$0 c #637755", +"%0 c #BABCB8", +"&0 c #E6E5E6", +"*0 c #D0D4CD", +"=0 c #6E835F", +"-0 c #80897E", +";0 c #A9B5A3", +">0 c #70796C", +",0 c #202320", +"'0 c #939F8E", +")0 c #2C5D18", +"!0 c #4D7738", +"~0 c #819A73", +"{0 c #B5B9B0", +"]0 c #ABB4A4", +"^0 c #809873", +"/0 c #5B7D49", +"(0 c #474E17", +"_0 c #923412", +":0 c #678155", +"<0 c #C1C8BC", +"[0 c #E7E7E9", +"}0 c #BBBFB8", +"|0 c #596D4A", +"10 c #B4C3B0", +"20 c #6B7367", +"30 c #343833", +"40 c #262825", +"50 c #2D5B1B", +"60 c #738E63", +"70 c #728E60", +"80 c #C2BFC2", +"90 c #92A485", +"00 c #8EA083", +"a0 c #A3AE9C", +"b0 c #8C9F7F", +"c0 c #305D1D", +"d0 c #1D4F12", +"e0 c #454813", +"f0 c #8E2E0E", +"g0 c #8D1904", +"h0 c #C7D0C1", +"i0 c #40612A", +"j0 c #7A8E6C", +"k0 c #CDD1CA", +"l0 c #C2C2C3", +"m0 c #7E827C", +"n0 c #475C3A", +"o0 c #ACBAA8", +"p0 c #232522", +"q0 c #3C413B", +"r0 c #3C6828", +"s0 c #93A488", +"t0 c #BFBDBD", +"u0 c #C1C0C0", +"v0 c #BEBDBA", +"w0 c #BABAB6", +"x0 c #80996F", +"y0 c #426B2F", +"z0 c #1F4B0D", +"A0 c #1A480A", +"B0 c #265614", +"C0 c #386722", +"D0 c #7E966F", +"E0 c #C3BFC1", +"F0 c #7C946E", +"G0 c #1D4F11", +"H0 c #3E400F", +"I0 c #8B280B", +"J0 c #395B22", +"K0 c #466331", +"L0 c #9AA791", +"M0 c #E1E2E2", +"N0 c #C1C0C1", +"O0 c #717271", +"P0 c #485141", +"Q0 c #4D643C", +"R0 c #889185", +"S0 c #BDCDB9", +"T0 c #60685C", +"U0 c #899384", +"V0 c #A8B5A4", +"W0 c #C2D1BD", +"X0 c #305E1C", +"Y0 c #95A58A", +"Z0 c #C4BFC5", +"`0 c #ADB3A7", +" a c #789369", +".a c #567A46", +"+a c #497138", +"@a c #3B6529", +"#a c #1A470A", +"$a c #305B1E", +"%a c #668456", +"&a c #899B7C", +"*a c #A3AE9A", +"=a c #184B0D", +"-a c #4E4712", +";a c #932A0D", +">a c #8E1803", +",a c #3B5D24", +"'a c #7F9172", +")a c #565556", +"!a c #1F211D", +"~a c #293A1D", +"{a c #3E5C28", +"]a c #8B9488", +"^a c #B4C3AE", +"/a c #373B36", +"(a c #656D61", +"_a c #CCDDC6", +":a c #B6C3B1", +"b c #8F8E90", +",b c #363836", +"'b c #323E29", +")b c #385028", +"!b c #3D582B", +"~b c #395624", +"{b c #395A24", +"]b c #292C27", +"^b c #30332E", +"/b c #0C0D0B", +"(b c #4F554C", +"_b c #636A5F", +":b c #4E544C", +"c c #839A70", +",c c #B9BAB9", +"'c c #A6B1A0", +")c c #68682D", +"!c c #7A2200", +"~c c #8A1803", +"{c c #405D2C", +"]c c #76846C", +"^c c #CACBCB", +"/c c #EBEBEC", +"(c c #0E0E0F", +"_c c #E6E7E7", +":c c #E5E6E6", +"d c #839A72", +",d c #61844A", +"'d c #718C62", +")d c #778F6B", +"!d c #638056", +"~d c #50743D", +"{d c #3B6528", +"]d c #5A7F47", +"^d c #B4B7B1", +"/d c #46772D", +"(d c #678C4F", +"_d c #B3B8B2", +":d c #BCBFBA", +"e c #EBEBEA", +",e c #C1C1C0", +"'e c #40403F", +")e c #676668", +"!e c #101D07", +"~e c #0D1409", +"{e c #5D635A", +"]e c #7C8578", +"^e c #BBCBB6", +"/e c #8E9A89", +"(e c #61685D", +"_e c #596157", +":e c #5B635A", +"f c #B2BDB6", +",f c #9F9B83", +"'f c #6A320A", +")f c #841500", +"!f c #5D754B", +"~f c #ACB2A7", +"{f c #D5D6D4", +"]f c #878584", +"^f c #12100E", +"/f c #191411", +"(f c #120D0A", +"_f c #211E1A", +":f c #181511", +"g c #818F78", +",g c #D7D9D6", +"'g c #E6E3E0", +")g c #E7E2E0", +"!g c #E4DEDA", +"~g c #BBB5B0", +"{g c #928B85", +"]g c #AAA29C", +"^g c #C7BFB8", +"/g c #756D65", +"(g c #292019", +"_g c #120800", +":g c #110700", +"h c #889D7C", +",h c #1F5208", +"'h c #114101", +")h c #355E22", +"!h c #93A388", +"~h c #608250", +"{h c #235212", +"]h c #8FA280", +"^h c #967A5C", +"/h c #6E1E00", +"(h c #2C461B", +"_h c #040B00", +":h c #A1A0A0", +"i c #E7DDD4", +",i c #1A2513", +"'i c #C5D3C0", +")i c #656C61", +"!i c #2B5A19", +"~i c #9CA994", +"{i c #B5B8B1", +"]i c #497036", +"^i c #063600", +"/i c #002D00", +"(i c #1D5008", +"_i c #9BAA8F", +":i c #2A5818", +"j c #DFE0DF", +",j c #EAE9EB", +"'j c #C2C2C1", +")j c #969594", +"!j c #A6A4A2", +"~j c #D4D1CF", +"{j c #E4E0DD", +"]j c #E7E0DB", +"^j c #E7DDD7", +"/j c #E8D7C9", +"(j c #E9D4C5", +"_j c #E9D2C0", +":j c #ECD2BE", +"k c #345320", +",k c #CDDBC5", +"'k c #D3E2CB", +")k c #6C7469", +"!k c #5F675C", +"~k c #666F63", +"{k c #40453F", +"]k c #030302", +"^k c #20500E", +"/k c #708D5F", +"(k c #849B77", +"_k c #8A9F7D", +":k c #51763E", +"l c #E3D7CD", +",l c #E4D4C8", +"'l c #ECD8C9", +")l c #ECD4C1", +"!l c #E3C6B0", +"~l c #A5856B", +"{l c #785437", +"]l c #684122", +"^l c #512706", +"/l c #4F2401", +"(l c #643611", +"_l c #AC7D58", +":l c #EDBD97", +"m c #4B514A", +",m c #757E72", +"'m c #2C5B19", +")m c #477234", +"!m c #577D45", +"~m c #718C61", +"{m c #597D46", +"]m c #2D5D1A", +"^m c #527A3E", +"/m c #7A946D", +"(m c #3F6A2C", +"_m c #1E500A", +":m c #275813", +"n c #EFB88D", +",n c #EFB88C", +"'n c #EFB98E", +")n c #EFBA8F", +"!n c #EFBB91", +"~n c #EEBC93", +"{n c #EEBE96", +"]n c #EDC3A1", +"^n c #ECC6A8", +"/n c #EBCAAF", +"(n c #EACEB7", +"_n c #020500", +":n c #233615", +"o c #662004", +",o c #657957", +"'o c #CACCC6", +")o c #E8E5E5", +"!o c #E6DED7", +"~o c #E7DCD2", +"{o c #E8D8CB", +"]o c #EDD3BE", +"^o c #E3C3AA", +"/o c #977155", +"(o c #572D0E", +"_o c #562905", +":o c #572600", +"p c #1E4D0D", +",p c #4D743A", +"'p c #829A74", +")p c #94A488", +"!p c #BBBDB8", +"~p c #B4B9AE", +"{p c #A3AF9A", +"]p c #567A45", +"^p c #42692F", +"/p c #A7AE9F", +"(p c #134503", +"_p c #758E68", +":p c #A8B2A0", +"

Q c #18450A", +",Q c #315F1D", +"'Q c #446E30", +")Q c #BDBCBD", +"!Q c #0F3D00", +"~Q c #3E642B", +"{Q c #BABCB7", +"]Q c #5A7D49", +"^Q c #BDBDBC", +"/Q c #4F7639", +"(Q c #184508", +"_Q c #103E00", +":Q c #809773", +"R c #5F804E", +",R c #375F27", +"'R c #113706", +")R c #771D04", +"!R c #FAFAF9", +"~R c #EEF0EC", +"{R c #DDE2DB", +"]R c #C0CABA", +"^R c #ACB9A4", +"/R c #8E9F81", +"(R c #7A8F6B", +"_R c #657D54", +":R c #4B6938", +"S c #A9B0A5", +",S c #4B7139", +"'S c #0E4200", +")S c #376424", +"!S c #93A489", +"~S c #134501", +"{S c #1E5209", +"]S c #769164", +"^S c #C5C2C5", +"/S c #6A885D", +"(S c #0A3700", +"_S c #163606", +":S c #5F2205", +"T c #8E9989", +",T c #0B1824", +"'T c #3A404C", +")T c #504427", +"!T c #888A8B", +"~T c #838D81", +"{T c #4B6F3B", +"]T c #1C4C0E", +"^T c #1D4D10", +"/T c #1F4F11", +"(T c #1C4D10", +"_T c #1A4B0D", +":T c #124301", +"U c #62300B", +",U c #422504", +"'U c #DFE3DC", +")U c #CCD3C7", +"!U c #B6C1AE", +"~U c #778D68", +"{U c #678056", +"]U c #567143", +"^U c #3A5C24", +"/U c #1A2A0E", +"(U c #111410", +"_U c #B1B2B2", +":U c #010400", +"V c #8B2108", +",V c #901B05", +"'V c #941E06", +")V c #952308", +"!V c #922B0A", +"~V c #85300C", +"{V c #682C08", +"]V c #6C4219", +"^V c #9C8969", +"/V c #BBBCB1", +"(V c #8EA687", +"_V c #467038", +":V c #2F6019", +"W c #203213", +",W c #395822", +"'W c #641302", +")W c #7E1904", +"!W c #891701", +"~W c #821600", +"{W c #892201", +"]W c #91633E", +"^W c #ACB1A1", +"/W c #BDBFBE", +"(W c #ABB3A3", +"_W c #96A68D", +":W c #254F14", +"X c #811D01", +",X c #8D3712", +"'X c #9A512A", +")X c #AC7050", +"!X c #A85A37", +"~X c #912307", +"{X c #EDEFEC", +"]X c #D4DAD0", +"^X c #C1CABA", +"/X c #B0BDA8", +"(X c #819574", +"_X c #637C52", +":X c #4C6A39", +"Y c #0C141C", +",Y c #070C11", +"'Y c #040709", +")Y c #0F1A24", +"!Y c #6C859B", +"~Y c #B0B1B6", +"{Y c #B6BAC1", +"]Y c #BCC2C9", +"^Y c #B5BCC1", +"/Y c #A3A5AD", +"(Y c #8C818C", +"_Y c #7A6C73", +":Y c #775955", +"Z c #817379", +",Z c #76585E", +"'Z c #653F3D", +")Z c #672F25", +"!Z c #6E1D12", +"~Z c #7B1F10", +"{Z c #7E1F0B", +"]Z c #871D06", +"^Z c #951C03", +"/Z c #961C03", +"(Z c #941C02", +"_Z c #931B02", +":Z c #921B01", +"` c #E1E4DE", +",` c #FAFEFF", +"'` c #E5EEF6", +")` c #CAD8E6", +"!` c #BCCEDE", +"~` c #A1B9CF", +"{` c #86A0B6", +"]` c #687F94", +"^` c #435A70", +"/` c #284055", +"(` c #1D3246", +"_` c #0F1A23", +":` c #060B0F", +"<` c #728AA0", +"[` c #F7F9FF", +"}` c #E2E7EF", +"|` c #D0D7DF", +"1` c #BBC4CB", +"2` c #A9ABB4", +"3` c #908792", +"4` c #796C6F", +"5` c #715452", +"6` c #6C3E3C", +"7` c #6A2A23", +"8` c #651E10", +"9` c #731D0B", +"0` c #861D08", +"a` c #8F1D07", +"b` c #921C03", +"c` c #921B02", +"d` c #6F1A09", +"e` c #484649", +"f` c #F0F7FF", +"g` c #E0ECF7", +"h` c #CDDDEA", +"i` c #98ADC0", +"j` c #738EA7", +"k` c #55728C", +"l` c #40576E", +"m` c #26394A", +"n` c #192A3B", +"o` c #13222F", +"p` c #080E13", +"q` c #010203", +"r` c #7A92A8", +"s` c #F1F3F9", +"t` c #E0E4ED", +"u` c #CDD4DB", +"v` c #B5BCC0", +"w` c #9D9DA5", +"x` c #867B85", +"y` c #746267", +"z` c #6C4E4A", +"A` c #6A3A34", +"B` c #6E2620", +"C` c #6E1F12", +"D` c #7A1E09", +"E` c #8A1D06", +"F` c #931D06", +"G` c #921D04", +"H` c #941B00", +"I` c #941A01", +"J` c #701B09", +"K` c #555458", +"L` c #EAF1F8", +"M` c #D2DFEC", +"N` c #C7D8E7", +"O` c #ABC2D6", +"P` c #91A8BD", +"Q` c #6F869C", +"R` c #4C647B", +"S` c #2F495F", +"T` c #20364A", +"U` c #172837", +"V` c #101C26", +"W` c #04080B", +"X` c #020305", +"Y` c #0C161E", +"Z` c #849CB2", +"`` c #EFF1F6", +" . c #D9DEE8", +". . c #BCC6D1", +"+ . c #A8AFB5", +"@ . c #928F96", +"# . c #7C6C75", +"$ . c #735A5E", +"% . c #664541", +"& . c #6A332A", +"* . c #701D14", +"= . c #781F10", +"- . c #7E1E08", +"; . c #881D05", +"> . c #931B01", +", . c #971B02", +"' . c #741C0A", +") . c #696A70", +"! . c #FEFFFF", +"~ . c #F5FCFF", +"{ . c #E8F2FA", +"] . c #D4E2EE", +"^ . c #BCCCDB", +"/ . c #A1B5C8", +"( . c #7B96AF", +"_ . c #617D96", +": . c #485F75", +"< . c #283C4E", +"[ . c #192D3D", +"} . c #89A3BB", +"| . c #F6F8FC", +"1 . c #E6EAEF", +"2 . c #CCD2DD", +"3 . c #B0B7C4", +"4 . c #9CA1A7", +"5 . c #8A8488", +"6 . c #78666D", +"7 . c #735157", +"8 . c #673F3B", +"9 . c #692E21", +"0 . c #711E10", +"a . c #7E1F0F", +"b . c #871E07", +"c . c #6F1F0F", +"d . c #7A7B86", +"e . c #EDF4FA", +"f . c #D8E5F1", +"g . c #CADAE9", +"h . c #ACC1D3", +"i . c #91AAC2", +"j . c #BBCBDB", +"k . c #FAFBFF", +"l . c #F1F4FA", +"m . c #E0E5E9", +"n . c #C5CCD5", +"o . c #A9ACB9", +"p . c #92929B", +"q . c #837C7E", +"r . c #6C6068", +"s . c #A0A4B0", +"t . c #F8F9FE", +"u . c #F7F8FA", +"v . c #E7EBE4", +"w . c #687F58", +"x . c #587245", +"y . c #ABB7A2", +"z . c #FBFBFA", +"A . c #FBFBF9", +"B . c #637B52", +"C . c #3B5A26", +"D . c #CBD4C6", +"E . c #879A7A", +"F . c #526D40", +"G . c #EBEEE9", +"H . c #E7EBE5", +"I . c #BAC4B2", +"J . c #768B67", +"K . c #F9FAF9", +"L . c #647D54", +"M . c #456232", +"N . c #E1E6DE", +"O . c #3C5B28", +"P . c #A3B29A", +"Q . c #869979", +"R . c #667E56", +"S . c #F8F9F7", +"T . c #E9ECE6", +"U . c #486535", +"V . c #3A5926", +"W . c #D0D8CB", +"X . c #A7B59E", +"Y . c #FAFBF9", +"Z . c #647C53", +"` . c #F2F4F0", +" .. c #BCC6B5", +"... c #87997A", +"+.. c #7D9170", +"@.. c #476434", +"#.. c #446131", +"$.. c #A7B59D", +"%.. c #F7F8F6", +"&.. c #567145", +"*.. c #677E56", +"=.. c #FCFDFB", +"-.. c #3E5C2A", +";.. c #CFD6CB", +">.. c #425F2D", +",.. c #D3DBCF", +"'.. c #859878", +").. c #60784F", +"!.. c #C2CBBC", +"~.. c #E8ECE6", +"{.. c #4A6637", +"].. c #516C3E", +"^.. c #546F43", +"/.. c #A5B29B", +"(.. c #D7DED3", +"_.. c #7C916E", +":.. c #C1CAB9", +"<.. c #637B53", +"[.. c #B7C3B0", +"}.. c #7E916F", +"|.. c #7F9371", +"1.. c #DDE2D9", +"2.. c #7C906E", +"3.. c #AFBCA7", +"4.. c #B5C0AC", +"5.. c #6C835D", +"6.. c #A4B39B", +"7.. c #E2E7DF", +"8.. c #D8DED4", +"9.. c #F6F8F5", +"0.. c #607950", +"a.. c #E4E9E2", +"b.. c #738964", +"c.. c #C8D0C2", +"d.. c #798E6C", +"e.. c #FDFEFD", +"f.. c #ADBBA5", +"g.. c #5B754B", +"h.. c #F3F5F1", +"i.. c #809473", +"j.. c #B4BFAC", +"k.. c #405E2D", +"l.. c #4A6638", +"m.. c #EDF0EB", +"n.. c #FCFDFC", +"o.. c #728964", +"p.. c #849878", +"q.. c #A5B39B", +"r.. c #819473", +"s.. c #A8B59E", +"t.. c #4D683A", +"u.. c #ECEFE9", +"v.. c #F9FAF8", +"w.. c #617950", +"x.. c #C0CAB9", +"y.. c #DAE0D6", +"z.. c #446231", +"A.. c #556F43", +"B.. c #FEFEFD", +"C.. c #69805A", +"D.. c #879A7B", +"E.. c #405F2C", +"F.. c #DCE1D8", +"G.. c #4B6638", +"H.. c #C7D0C0", +"I.. c #DADFD5", +"J.. c #9CAB92", +"K.. c #A6B49D", +"L.. c #597247", +"M.. c #688059", +"N.. c #5F784E", +"O.. c #9AAA90", +"P.. c #CED5C8", +"Q.. c #D4DBD0", +"R.. c #3F5D2B", +"S.. c #819674", +"T.. c #4E693B", +"U.. c #496535", +"V.. c #9BAB91", +"W.. c #98A88E", +"X.. c #D8DED5", +"Y.. c #D0D7CB", +"Z.. c #738965", +"`.. c #FBFCFB", +" +. c #F3F5F2", +".+. c #5F774E", +"++. c #C5CEBE", +"@+. c #B0BCA7", +"#+. c #829474", +"$+. c #9BAB90", +"%+. c #BBC6B4", +"&+. c #B7C2B0", +"*+. c #BCC7B5", +"=+. c #627A51", +"-+. c #3A5825", +";+. c #CDD5C8", +">+. c #8A9D7F", +",+. c #C5CEC0", +"'+. c #BDC8B7", +")+. c #829675", +"!+. c #798E6B", +"~+. c #E5E9E2", +"{+. c #415F2E", +"]+. c #456231", +"^+. c #E4E8E0", +"/+. c #F6F8F6", +"(+. c #607A50", +"_+. c #D0D7CA", +":+. c #CAD2C5", +"<+. c #C4CEBE", +"[+. c #587147", +"}+. c #D2D9CD", +"|+. c #91A285", +"1+. c #E6EAE3", +"2+. c #D5DBD0", +"3+. c #577145", +"4+. c #A1AF96", +"5+. c #587246", +"6+. c #BDC8B6", +"7+. c #617A51", +"8+. c #3B5D26", +"9+. c #8C9E7F", +"0+. c #809372", +"a+. c #3B5B27", +"b+. c #E5EAE3", +"c+. c #FDFDFC", +"d+. c #F3F4F1", +"e+. c #526C40", +"f+. c #ACB9A3", +"g+. c #AAB8A1", +"h+. c #869879", +"i+. c #6B825C", +"j+. c #A3B299", +"k+. c #C5CDBE", +"l+. c #D4DACF", +"m+. c #7C906D", +"n+. c #EBEFE9", +"o+. c #516C3F", +"p+. c #839677", +"q+. c #F3F6F2", +"r+. c #B2BFAA", +"s+. c #B3BFAC", +"t+. c #B9C5B3", +"u+. c #F1F3EF", +"v+. c #B4C0AC", +"w+. c #B5C1AD", +"x+. c #B5C1AE", +"y+. c #F0F3EF", +"z+. c #EBDED6", +"A+. c #DECBBE", +"B+. c #DFCDC0", +"C+. c #DFCCBF", +"D+. c #E1D0C4", +"E+. c #FBF9F7", +"F+. c #AF8061", +"G+. c #8A400E", +"H+. c #843D0D", +"I+. c #873F0D", +"J+. c #8D4A1D", +"K+. c #F0E8E2", +"L+. c #AD7E5E", +"M+. c #8C400D", +"N+. c #863D0C", +"O+. c #893F0C", +"P+. c #8C4719", +"Q+. c #AE7F60", +"R+. c #8A3F0D", +"S+. c #873E0C", +"T+. c #8D491C", +"U+. c #883E0C", +"V+. c #8C471A", +"W+. c #893E0C", +"X+. c #8C400C", +"Y+. c #894213", +"Z+. c #F0E7E1", +"`+. c #8B471A", +" @. c #BE977D", +".@. c #C5A38C", +"+@. c #C4A28B", +"@@. c #C39F88", +"#@. c #C8A892", +"$@. c #F8F4F1", +"%@. c #94552B", +"&@. c #F9F5F2", +"*@. c #935329", +"=@. c #F2EAE5", +"-@. c #94542A", +";@. c #F6EFEC", +">@. c #925127", +",@. c #EADDD5", +"'@. c #F6F1ED", +")@. c #F4EEEA", +"!@. c #F7F3F1", +"~@. c #863F0F", +"{@. c #95562C", +"]@. c #985B32", +"^@. c #965930", +"/@. c #98572C", +"(@. c #B18365", +"_@. c #FDFCFB", +":@. c #8F410D", +"<@. c #A16A44", +"[@. c #FCFBFA", +"}@. c #8B3F0D", +"|@. c #A46E4A", +"1@. c #8C3F0D", +"2@. c #A46D49", +"3@. c #90410E", +"4@. c #A06843", +"5@. c #8C481B", +"6@. c #C09A82", +"7@. c #C7A690", +"8@. c #C6A58F", +"9@. c #C4A18A", +"0@. c #D5BCAC", +"a@. c #F9F6F3", +"b@. c #F4EDE9", +"c@. c #925228", +"d@. c #EFE5DF", +"e@. c #FBFAF8", +"f@. c #FCFAF8", +"g@. c #874011", +"h@. c #9C623B", +"i@. c #A06842", +"j@. c #9F6741", +"k@. c #9F643D", +"l@. c #C29F88", +"m@. c #8F410E", +"n@. c #B18466", +"o@. c #AB7A5A", +"p@. c #B88F73", +"q@. c #965327", +"r@. c #925329", +"s@. c #BA9378", +"t@. c #F3EDE8", +"u@. c #ECE2DB", +"v@. c #EEE3DD", +"w@. c #F5EEEA", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ # # # $ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ $ # $ $ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + $ % & * = * - ; % > # $ $ @ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ > - & & & , ; % > # $ @ @ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ @ $ @ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ ; ' ) ! ~ ! { ] ^ / ' * & , ; % # # $ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ % = ( { _ : < ( [ / ' & - , ; > > $ $ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ > , - & , ; > # $ $ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + $ , < } | 1 2 3 4 5 6 7 ! : < ( 8 / ' * & , ; % # $ $ @ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ , ( 9 0 a | b c d 9 e ! { ) ^ [ f * & - ; % > # # $ @ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + % ' ) ~ g ! { ^ [ f * - , % # # $ @ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + # = ] 6 h i j j k l m n o a b p d 9 e ~ { ] ^ [ f = & - ; ; # # $ @ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . & 6 q r s t i u v h 1 | 0 5 w x g _ < ( 8 / ' * & , ; > # # $ $ @ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + # ^ c y u m y z b c 6 e _ < ^ f ' & , % > # # $ @ + + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A B C D E F G H I J K L j t k M l v h 1 | 0 5 w x g _ { ] ^ / ' = & , % % > # $ $ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . } N O P Q R I S I K T U L j r M V n W 2 3 p } 6 e ! : ) ( [ f = * - ; ; % > # $ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . + X { | t Y Z Z ` . J s i V h a 0 5 x ~ : ] [ f = & , % % # $ @ @ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. +. @. #. $. %. &. *. =. -. ;. >. ,. G ` '. s L L L j k ). V y W 1 3 p } 6 7 ~ : ) ] 8 / ' * - , % > # # $ @ @ + + + + . . . . . . . . . . . . . . . . K !. !. ~. {. ]. ^. /. (. _. :. <. [. Y K T T T }. L j i l m q z | b p d 9 e ! { ] ^ [ ' = - - ; % > # # $ @ + + + . + . . . . . . . . . . . . . . . . |. 1. 2. 3. 4. 5. 6. 7. 8. 9. 0. a. [. b. Z ` S }. j l v o 3 p w 7 ! < ( [ = * - ; > > # $ @ @ + + . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. f. g. #. #. d. g. h. $. i. j. k. l. m. n. o. p. ` H S }. L s t t i l m q o a b p w x g ! { ] ^ / ' = & , ; % > # $ $ @ @ + + + . . . . . . . . . . s q. !. !. !. !. !. !. !. !. r. s. t. u. v. w. x. y. z. ` R S J T L L j t i u v h 1 | 4 5 6 7 g _ < ( 8 / ' = - , ; % # # $ @ @ @ + + + . . . . . . . . . . A. B. C. D. E. F. G. H. I. J. K. L. M. N. O. :. P. Q. a. [. b. R. R '. U k u q 1 b 5 6 e _ ] ^ / = & - ; > # $ $ @ @ + @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. S. T. U. g. d. V. W. g. $. X. Y. Z. `. + .+ ++ @+ #+ ` K U U U U s r ). V y h 1 | 0 5 w 7 ~ : < ] 8 / ' = & - ; > > # $ @ @ @ + + . . . . s $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. $+ %+ &+ *+ =+ -+ ;+ >+ 9. Q ` J }. }. }. }. U j i ). V n W 2 b c d 9 7 ~ : ) ( [ f = & - , % > > # $ @ @ @ + + + . . . ,+ '+ )+ !+ ~+ {+ ]+ ^+ ^+ /+ {+ (+ _+ :+ <+ [+ }+ |+ 1+ 2+ 3+ 4+ 9. 0. P 5+ 6+ 7+ ` . J s M m W a 4 d x ~ { ( [ f = - , % > $ $ $ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. f. g. 8+ d. 8+ g. g. e. 9+ 0+ a+ b+ c+ d+ ++ e+ f+ ` g+ K s j j j r M V n W 2 b p } 6 7 ~ : ) ^ [ / = * - , % % # $ $ @ . L $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ i+ ]. j+ k+ l+ m+ n+ o+ 7+ ` g+ J U L L L j i l v q o a b c w x g _ { ] ^ [ f * - , ; % > # $ $ $ . p+ '+ )+ q+ q+ q+ q+ r+ q+ !+ s+ t+ /+ u+ ^+ ]+ v+ r+ w+ x+ y+ z+ A+ B+ C+ D+ E+ F+ G+ H+ O I+ o+ b. R. R I T t l n o 3 p w e _ ) ^ / ' * , , % > $ @ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. f. d. V. V. g. J+ K+ i. L+ M+ N+ O+ P+ Q+ R+ R. J }. T U L j r M l m q o a 0 c d 9 g _ { ] ^ [ f = & , . }. $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ S+ T+ U+ V+ W+ w. X+ y. Y+ R. '. K K }. }. U j r M V y W 1 3 4 5 w 7 ~ : < ( 8 f = * - , . Z+ `+ v+ @ r+ r+ r+ r+ r+ q+ q+ q+ q+ q+ q+ q+ ~+ t+ v+ {+ u+ .@ ]+ v+ +@ @@ #@ $@ %@ &@ *@ =@ -@ ;@ >@ 8. P. Y+ Q [. 7+ R. . '. s i V q 2 0 } 9 ~ : ) 8 ' = & ; % > # $ $ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. U. f. g. ,@ d. d. #. T. '@ )@ *. !@ ~@ {@ ]@ R+ G f+ . }. s s s j r M V v h 1 3 4 } 6 7 ~ _ ) & H q. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^@ /@ (@ /. v. _@ 4+ Y+ o+ R. . J U U U U s k ). V n z a 3 p d 6 7 ~ { ] * :@ <@ r+ [@ }@ }@ |@ +@ 1@ 1@ @ @ r+ r+ r+ r+ r+ r+ q+ q+ q+ q+ !+ ~+ t+ v+ /+ D. ^+ ]+ v+ [@ 2@ 3@ 4@ 5@ 6@ 7@ 8@ 9@ 0@ G+ a@ <. a. 5+ z. Z ` S }. s M v W | p d x ! < ( [ ' * - ; > # # $ @ @ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. f. d. V. V. g. S. b@ 9+ c@ d@ e@ f@ g@ h@ i@ Z I J }. T L j t M l V n o 2 b x o+ q. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. j@ k@ l@ m@ n@ o@ p@ >+ Q. Y I I J K T s j t i l v q z | 0 x q@ r@ s@ t@ u@ v@ s@ w@ x@ [@ [@ }@ }@ |@ |@ @ @ r+ r+ r+ r+ r+ q+ q+ q+ q+ q+ q+ q+ q+ ~+ v+ )+ u+ u+ y@ ]+ t+ z@ A@ B@ C@ D@ E@ F@ G@ H@ I@ J@ K@ O I+ [. b. f+ R '. U r u n z b 5 6 e _ ] 8 / = & , ; > # $ @ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. T. f. g. g. d. #. V. L@ M@ Y. j. N@ O@ P@ P+ Q@ R@ 7+ H T L s s s t y 9. q. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ S@ T@ *+ U@ V@ w. I@ <. a. 7+ . }. U U T T s r y W@ X@ Y@ Z@ `@ # .# +# @# ## t@ u@ v@ s@ w@ x@ [@ $# }@ |@ |@ 1@ 1@ @ @ r+ r+ r+ r+ r+ r+ q+ q+ q+ q+ !+ !+ ~+ /+ u+ u+ u+ )+ )+ !+ %# &# *# =# -# ;# ># ,# '# N H+ <. P 5+ z. Z ` . J s i m h 2 4 } x ~ { ] [ f = - ; ; > # $ @ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. f. d. #. #. g. f. U. K+ )# !# ~# {# ]# ^# /# 7+ g+ U 4+ q. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ S@ (# _# :# <# [# I@ <. }# H g+ L |# 1# 2# 3# 4# 5# 6# 7# 8# Z@ 9# `@ 0# a# b# ## ## c# v@ d# e# e# [@ [@ $# }@ |@ @ +@ @ @ r+ r+ r+ r+ q+ q+ q+ r+ q+ q+ q+ !+ ~+ t+ /+ u+ ]+ D. {+ f# |@ g# h# i# j# k# l# m# n# o# G+ p# O I+ 5+ q# R. R I }. t ). y z 3 p 6 e _ < ^ / ' * - ; % > # @ @ @ + + . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. U. f. g. #. V. #. e. M@ %. r# s# t# u# v# w# x# h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ~. T+ y# z# W+ w. A# B# C# D# E# F# G# G# F# H# 3# 5# I# 6# J# K# Z@ L# # 0# +# @# ## t@ u@ v@ s@ w@ x@ [@ $# }@ }@ |@ |@ |@ @ @ r+ r+ r+ r+ r+ q+ q+ q+ q+ q+ q+ !+ ~+ s+ {+ u+ .@ M# t+ N# O# P# Q# R# S# T# U# V# W# X# Y# P. Y+ Q [. b. R. . '. U k V n 1 b 5 6 g _ ] 8 f = & , % % # # @ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. f. ,@ d. d. g. g. f. Z# `# $ .$ +$ @$ #$ $$ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. %$ &$ *$ =$ -$ ;$ >$ ,$ '$ )$ E# !$ F# H# 3# 3# 3# 5# I# 7# 8# ~$ Z@ {$ # .# ]$ ^$ /$ c# v@ d# ($ e# _$ [@ $# }@ }@ +@ +@ @ @ r+ r+ r+ r+ q+ q+ q+ r+ q+ q+ r+ q+ ~+ v+ {+ /+ y@ .@ y@ ~+ [@ :$ <$ [$ 5@ }$ |$ 1$ 2$ 3$ >+ J@ <. Y+ o+ z. Z Y g+ K s M m W | 4 d x ! < ] [ ' * - ; % > # $ @ @ @ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. S. f. g. #. @. V. f. 4$ 5$ 6$ 7$ 8$ 9$ 0$ a$ b$ c$ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. d$ e$ f$ g$ h$ i$ j$ k$ ,$ l$ m$ F# n$ n$ n$ F# 3# 4# o$ 2# 7# p$ Z@ 9# # .# +# b# ## t@ c# v@ d# w@ x@ [@ $# $# }@ |@ |@ |@ @ r+ r+ r+ r+ r+ r+ q+ q+ q+ q+ q+ q+ !+ f# v+ /+ )+ D. ]+ ^+ s+ q$ r$ s$ t$ u$ v$ w$ x$ y$ z$ 8. H+ O Q [. b. f+ Y I U r u n z b c w e _ ) ^ / = * , ; % # $ $ @ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. T. T. e. S. f. f. g. A$ B$ C$ D$ E$ F$ G$ H$ I$ J$ K$ L$ b$ M$ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. N$ O$ P$ Q$ R$ S$ j$ T$ U$ V$ W$ X$ F# G# G# G# G# 5# Y$ 7# J# Z$ Z@ L# # 0# ]$ `$ % .% +% d# d# w@ _$ [@ $# }@ }@ |@ 1@ 1@ 1@ @ @ r+ r+ q+ r+ r+ r+ q+ q+ q+ !+ !+ ~+ {+ )+ @% @% D. D. !+ #% $% %% &% *% =% -% ;% >% N 9. P. ,% Q 6+ Z }# H J L i V h 1 0 d x g { ] 8 / = - , % % > @ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. '% )% 4$ !% ~% {% ]% U. ^% /% (% _% w# :% 8$ <% +. [% L@ J+ }% G$ |% 1% 2% 0$ 3% 4% 5% !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 6% 7% 8% 9% 0% -$ a% b% T$ c% X$ d% e% n$ H# F# 3# 3# 5# Y$ 6# 8# Z$ f% g% 0# .# b# h% ## c# u@ d# s@ x@ x@ [@ $# }@ |@ |@ @ @ r+ r+ r+ r+ r+ r+ q+ q+ q+ q+ q+ q+ q+ !+ f# /+ y@ ]+ D. )+ {+ i% j% h# k% l% m% U# n% o% p% G+ P. 0. Y+ 5+ z. f+ Y S }. r l y W | 4 d x _ ) ( [ ' * - , > > # $ @ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. q% r% s% t% u% v% w% x% y% z% A% B% C% !. !. !. M$ D% E% e. L@ f. f. g. ,@ d. #. #. !% F% G% H% I% J% 0$ K% L% M% !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. N% e$ O% P% Q% R% a% S% C# l$ )$ !$ F# G# 3# H# G# 4# o$ 6# J# p$ ~$ g% `@ 0# +# @# ^$ t@ .% v@ d# w@ _$ x@ $# }@ }@ |@ |@ 1@ 1@ @ @ r+ r+ r+ r+ r+ q+ q+ q+ q+ !+ s+ E. T% )+ M# .@ ]+ v+ q+ U% V% W% X% Y% Z% `% & .& +& Y# @& P I+ 6+ 7+ ` H I T r u n 1 b 5 9 g _ ) 8 / = & , ; > # $ $ @ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. '% #& $& %& && *& =& -& ;& >& ,& '& !. !. !. !. !. !. !. h+ )& !& ~& e. T. e. e. e. e. e. T. g. #. {& ]& ^& /& (& _& :& <& [& }& |& 1& 2& !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 3& O$ 4& 5& -$ 6& 7& 8& 9& 0& a& !$ d% F# H# 3# 4# 5# Y$ 6# J# K# 9# 9# # .# b& h% ## c# u@ v@ s@ e# x@ [@ $# $# |@ |@ @ @ r+ r+ r+ r+ q+ q+ @ +@ c& d& d& !+ q+ ~+ v+ v+ /+ ]+ .@ u+ q+ $# e& f& g& h& i& j& k& l& m& >+ J@ <. I+ 5+ z. 7+ ` g+ }. s M v W a 4 d 7 ~ { ( [ f = - ; % > # $ $ @ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. S. e. e. e. e. e. e. e. e. e. n& o& p& q& g+ r& s& t& u& v& w& x& C% t. &+ !. !. !. !. !. !. !. !. y& H$ g. e. e. e. e. e. e. z& A& B& C& D& E& F& G& H& I& J& K& L& M& N& O& P& Q& R& y& S& _% !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. N$ T& f$ g$ =$ R% U& V& W& 9& X& !$ H# G# G# H# H# 4# Y$ 6# 7# 8# Y& 9# L# 0# +# Z& h% ## c# u@ d# _$ `& * .* +* }@ @* x@ #* $* %* &* ** =* -* ~+ q+ q+ q+ q+ q+ q+ !+ ~+ v+ v+ /+ D. .@ D. !+ ;* >* ,* '* )* !* ~* {* ]* ^* y. 9. Q. I+ o+ q# f+ R I T t l y z 3 c 6 7 _ < ( / ' = , ; % # # $ @ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. U. e. e. T. S. e. S. e. e. e. e. e. /* (* _* :* <* ] ^ < e R. l+ /. _# [* _@ ~. !. ~. }* T+ !. !. !. !. |* N& g. e. e. e. e. {% 1* 2* 3* 4* 5* 6* 7* 8* 9* 0* a* b* c* d* F$ e* F% !% L@ !% e* B$ f* g* h* i* j* _% !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. k* l* !. !. m* n* ~. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. o* p* q* R$ r* j$ s* C# )$ m$ X$ d% F# 3# 3# 3# 4# Y$ 2# 7# ~$ Z@ t* u* v* w* x* y* z* A* B* C* D* E* F* G* H* I* J* K* L* M* N* r+ r+ r+ r+ q+ q+ r+ r+ q+ q+ q+ q+ ~+ {+ /+ D. ]+ ]+ ^+ !+ O* P* Q* R* S* T* U* V* W* 4+ :. p# O I+ 6+ 7+ R. H J L k V n 1 0 5 9 ~ { ) 8 / = * - ; > > # $ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. T. S. E% X* Y* Z* S. n& z& `* f. S. e. e. 1* = .= { : ! ! _ { : w h s '. += @= ^@ #= $= %= k@ !. !. !. !. &= e* f. *= e. {% == -= ;= >= ,= '= <* { )= != )= ~= c {= ]= ^= /= 3% (= J+ W. g. ,@ _= V. d. !% <% := <= [= 9$ }= /= |= 1= !. !. !. !. !. !. 2= 3= 4= 5= 6= 7= 8= 9= 3= h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 6% 7% 0= P$ a= b= c= d= e= f= g= X$ F# n$ G# n$ H# h= i= j= k= l= m= n= o= p= q= r= s= t= u= v= w= x= y= z= A= B= |@ |@ |@ |@ @ @ r+ r+ r+ r+ r+ q+ !+ q+ @* C= D= N* !+ ~+ /+ ]+ ]+ u+ )+ @% r+ E= F= G= H= I= J= K= l& L= n+ p# 0. Y+ o+ q# f+ ` g+ K t M v W | 4 d x ! < ( 8 f * - , % > # $ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. T. T. 4$ E$ M= }= N= O= P= Q= R= S= T= U= V= T. e. V= W= X= != _ ! ! ! ! _ < ) ] { m G+ 9. i K ,% p# n@ T+ !. !. c$ Y= Z= `= - .- +- @- != #- ! ! ! ! ! ! _ $- < 6 %- &- !. !. 1= *- =- -- ;- e. e. S. U. L@ d. d. 8+ g. g. f. <% >- ,- '- )- !- ~- {- ]- ^- /- (- _- :- <- [- }- |- 1- 2- 2= !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 3- 4- 5- 6- 7- 8- 9- 0- a- b- !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 7% f$ c- 0% d- e- f- g- h- i- j- k- l- m- n- o- p- q- r- s- t- u- v- w- x- y- z- A- B- C- D- E- w@ x@ E- [@ }@ }@ +@ +@ 1@ N* F- G- H- I- J- K- L- M- N- O- !+ !+ ~+ ~+ t+ /+ ]+ ]+ )+ {+ s+ P- Q- R- S- T- U- V- W- X- Y- Y# <. O I+ o+ 7+ R. H I U r u n z 3 c 6 e _ ) ^ / = & , % > # $ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. f. h. Z- `- '- :% ; .; !. !. s. +; @; #; $; %; &; *; h. =; -; ;; >; : ! ! ! ! ! ! ! ! _ ) < { ) { : _ b z. ,; h+ !. '; ); !; ~; {; ]; ^; _ ! ! ! ! ! ! ! ! ! ! { ] 6+ /; $+ !. !. 4% (; S. _; :; <; e. e. e. e. e. e. e. T. f. ,@ V. @. d. e. [; }; |; 1; 2; 3; 4; 5; 6; 7; <- 8; 9; 0; a; b; !. c; d; e; !. !. !. !. !. !. !. !. !. !. !. !. b; f; g; h; i; j; k; l; m; n; o; p; q; !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. %$ e$ r; s; t; u; v; w; x; y; z; A; B; C; D; E; F; G; H; I; J; K; L; M; N; O; P; b# ## t@ u@ v@ d# Q; P- R; S; T; U; V; W; X; Y; Z; `; > .> N* s+ +> !+ q+ q+ q+ !+ !+ ~+ t+ /+ ]+ .@ D. t+ @> #> $> %> &> *> => -> ;> >> ,> :. 0. Y+ 5+ 6+ b. ` . J s k V h a 0 } 9 ~ { ] [ f = & , % > # $ @ $ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. U. '> <% )> !> |* ~> !. !. !. b; {> [. ]> ^> /> (> _> :> <> [> h. }> |> 1> 2> ! ! ! ! ! ! ! ! ! ! _ : ! _ _ : ) 8 u :# h+ !. 3> 4> 5> 6> 7> : ! ! ! ! ! ! ! ! ! ! ! ! : ) l 8> !. !. !. w# 9> 0> a> b> {% e. e. e. e. e. e. e. e. e. e. e. S. T. f. h. _; /* /* c> 1* d> e> f> g> h> i> j> k> l> m> n> o> p> q> r> !. !. !. !. !. !. !. !. !. s> t> u> v> w> x> y> z> A> B> C> D> E> F> G> !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. H> I> J> (@ K> L> -+ M> N> O> P> Q> R> S> T> U> V> W> X> Y> Z> Z$ 9# `@ Y@ `> , ., +, @, #, $, %, &, *, =, -, ;, >, ,, ', ), !, }@ ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ !+ ~+ t+ v+ )+ y@ .@ u+ r+ ~, {, ], ^, /, (, _, :, <, [, $= a@ Q. I+ o+ z. f+ R I }. j ). v o 3 p d 7 ! < ( / ' * - ; % > # $ @ @ + . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. U. -- }, (; |, K% 1, !. !. !. !. !. }* I 8 ) { ) ( 2, 3, 4, 5, 6, 7, 8, y 8 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ [ R 9, !. !. 0, a, <* : ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ^ t b, ~. !. !. c, d, e, f, g, /& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= <; _; - h, /* *= `* K+ i, j, k, l, m, n, o, p, !. !. !. !. !. !. !. q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 0, H, ~. I, J, K, :# L, M, N, O, P, Q, R, S, E# 4# 3# 5# T, U, V, W, X, Y, Z, `, ' .' +' @' #' $' %' &' *' =' -' ;' 1@ c& q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ r+ !+ t+ {+ /+ )+ ]+ ^+ )+ @ >' ,' '' )' !' ~' {' ]' ^' /' 8. K@ O 5+ z. 7+ R. H '. U k u q 2 b 5 9 g : ] ^ / = & , % > # $ $ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. U. f. e. 4$ (' I% _' :' !. !. !. !. !. !. !. <' >+ ! < ! ! ! ! _ ] [' }' |' M% S@ p@ e : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < w 1' !. !. 2' 8. ] : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ( 5 O. l@ !. !. 3' 4' 5' 6' ;- 7' e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. n& z& <; {% *= 8' 9' - <; 0' a' b' c' d' e' f' g' h' i' j' k' l' m' n' o' n; p' q' r' s' t' u' v' m; w' x' y' r. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. z' A' B' C' D' E' F' G' 9& V$ X$ H' I' J' K' L' M' N' N' O' P' Q' R' S' T' U' V' W' X' Y' Z' `' ) @* N* .) q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ !+ !+ s+ {+ )+ @% u+ D. ]+ r+ %# +) @) #) $) %) &) *) =) n+ H+ <. Y+ o+ z. Z ` . K s M v h a p } x ! < ] 8 f * - ; # @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. J+ -) M& H$ ;) |& >) !. ,) ') )) m@ j@ !. !. !. S+ !) { { ! ! ! ! ! ! = ~) {) !. !. ]) S ( ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ( Q {. !. !. ^) v < ! ! ! ! ! ! ! ! ! ! ! ! _ ! ! ! ! < ~ o+ v. &+ !. h+ /) () _) :) 1* e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= {% _; <) W. d. U. e. Z# [) }) |) 1) 2) 3) 4) 5) 6) 7) 8) 9) 0) a) b) c) d) e) f) g) h) i) !. !. !. !. r> j) !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. k) M% l) m) n) o) p) q) r) s) t) u) u) v) L' L' w) x) y) z) A) B) C) D) E) F) G) H) I) J) K) q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ !+ !+ t+ /+ u+ u+ @% /+ /+ $# L) M) N) O) P) Q) R) S) T) Y# P. Q. a. o+ b. R. R I T r l y o 3 c 6 g < f % + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. f. U) V) W) D% X) !. h+ Y) &+ o@ l } v %= !. !. !. !. &+ 5+ < _ ! ! ! ! ! ) 4 v. !. !. T+ R. ( ! ! ! ! ! ! : { _ ! ! ! ! ! ! ! ! ! ) a =+ !. !. !. Z) ! { ! ! ! ! ! ! ! ! ! ! { { ! ! ! ! ! : : ! [. k+ `) !. ! .! +! @! {% e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. T. f. f. h. #! c> =; $! %! &! *! =! -! ;! >! ,! '! )! !! ~! {! ]! ^! /! (! !. !. !. _! :! ~ ,~ '~ )~ >+ 9. Q. a. 6+ }# M 6 ' $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. e. !~ ~~ {~ ]~ ^~ ,; /~ (~ _~ k < [ < ! ! _ ( I+ k@ !. !. $+ :~ _ : ! ! ! ! ! ! _ ] }# ^. }* t ] ! ! ! ! | q# <~ [~ l < ! ! ! ! ! ! ! ! _ _ H+ S@ !. !. q. (. | ( { : ! ! ! ! ! { 9 m+ ^. s ( ! ! ! ! ! ! _ ) ] V }~ |~ 1~ 2~ 3~ - e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= *= z& _; /* 4~ g, 5~ 6~ u, 7~ 8~ 9~ 0~ a~ b~ c~ !. d~ e~ f~ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. g~ H> h~ i~ j~ k~ l~ m~ n~ o~ p~ q~ r~ s~ .) q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ !+ t+ v+ {+ )+ y@ .@ /+ t~ u~ v~ w~ x~ y~ z~ A~ B~ C~ Z q ] > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. 4$ D~ E~ !. F~ o@ [. M n 4 ! : : ! ! ! ! ! ) h v! !. !. h+ [# _ { ! ! ! ! ! ! ! : : q J p : ! ! : 0 G~ ]) h+ b; o@ 5 ) ! ! ! ! ! ! ! _ ) Y T@ !. !. !. M! n@ T : e ! ! ! ! ! < c v. r. n+ ( _ ! ! ! ! ! ! ! : ) b [~ {> ). H~ I~ =; e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= J~ K~ L~ t' M~ N~ O~ P~ Q~ R~ S~ !. T~ U~ V~ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. W~ X~ Y~ Z~ `~ { .{ +{ @{ #{ ${ %{ J) .) q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ !+ v+ {+ /+ @% ]+ ^+ /+ ~+ &{ *{ <. s g ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. U. ={ -{ ;{ ~. >{ Y# p ] ) ( < : _ ! ! ! ! ! ! { x ,{ !. !. !. ^) q ) ! ! ! ! ! ! ! ! _ ) ) _ ! ! ! < ). '{ !. !. !. ]) o+ ) _ ! ! ! ! ! ! ! < 1 ){ !. !. !. !. !. t. ,{ Q 7 < ! ! ! < 0 !{ !. /. 3 < ! ! ! ! ! ! ! _ ~ K 5+ }# ~{ {{ ]{ - *= e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= ^{ /{ ({ _{ g) :{ <{ [{ }{ |{ 1{ 2{ ~. h+ 3{ M! !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 4{ 5{ 6{ 7{ 8{ 9{ 0{ a{ b{ c{ d{ e{ f{ g{ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ !+ .@ h{ i{ Y# S 6 - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. h. e. j{ k{ l{ ^) m{ T ! { _ ! ! ! ! ! ! ! ! ! ! ! _ ) 5+ i+ !. !. S@ G+ ) : ! ! ! ! ! ! ! ! ! _ ! ! ! _ { s ,; !. !. !. !. n{ d { ! ! ! ! ! ! ! < ! [~ !. !. !. !. !. !. !. *+ p# g < ! ! { g G~ b; S@ z. ( < ! ! ! ! ! ! ! ! b u u o{ p{ q{ - z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. n& '% r{ s{ t{ u{ f) v{ w{ x{ y{ D> z{ A{ B{ C{ d~ D{ E{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. F{ G{ H{ I{ J{ K{ L{ M{ N{ O{ P{ Q{ R{ S{ T{ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ V{ W{ $= R } & . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. 4$ D~ X{ s> Y{ i ^ ] _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) y }* !. !. !. Z{ 2 ^ ! ! ! ! ! ! ! ! ! ! ! ! ! _ : K (@ !. !. !. !. k+ p < ! ! ! ! ! ! : 6 [. (@ !. !. !. !. !. r> <' !. {. <. ) : ! _ ) K ]. !. (. p p e ! ! _ : _ { : / M ,; `{ ] {; .] 7' <; {% n& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. +] @] #] $] x{ %] &] Q~ *] N~ =] -] ;] >] ,] '] u> )] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] ]] ^] /] (] _] :] <] [] }] |] 1] q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] W{ n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. T. 3] '- 4] /@ 5] 3 ] : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ~ N %+ !. !. $+ _~ ) { ! ! ! ! ! ! ! ! ! ! ! ! _ _ . 6] !. !. !. $+ l+ d { ! ! ! ! ! ! ) i v! !. !. !. !. !. !. ,; <. 7] !. 8] ` ) _ ! { d ,{ !. l@ [. R. b ] : x } 9 q 7 < P. 9] s. 0] a] b] c] ;- d] {% z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. e] f] g] h] g) i] j] v{ k] l] m] n] ;] o] p] q] r] s] t] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] v] w] x] y] z] A] B] C] D] E] F] q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. J+ G% |, H] I] n+ g ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ] a 8> !. !. !. T@ R. ( _ ~ ~ ! ! ! ! ! ! ! ! ! _ _ f+ y# !. !. !. @= :. { _ ! ! ! ! ! ! < | !{ !. !. !. !. !. s. $= / Y /@ !. b, 9 ) ! _ < b. ^@ U+ g+ a 3 2 ! b P T 0. 0. ,> 9, !. !. /~ J] K] L] M] N] O] 1* _; e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. P] Q] R] S] ]! T] U] V] W] X] w' Y] ;] A{ Z] `] 7; ^ .^ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ @^ #^ $^ %^ &^ *^ =^ -^ ;^ 1] q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. T. >^ ,^ '^ !. k+ 2 < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : { 9. @= !. !. !. j+ u ( ! g ~ ! ! ! ! ! ! ! ! _ ! [. )^ !. !. r. k+ y ] ! ! ! ! ! ! ! : _ 4+ $+ !. !. !. !. s. P 8 ) _. !. T@ ` ^ ! ! : x J@ y. 9 ^ 4 Y m <. n@ m@ ^) )^ M! !. !. !. !. !^ ~^ {^ ]^ ~ ^^ ]{ /^ <; e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. J+ (^ _^ :^ <^ [^ }^ N~ |^ =] T] W] J! 1^ 2^ 3^ 4^ 5^ e; !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] 6^ v] 7^ 8^ 9^ 0^ a^ b^ c^ d^ e^ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. T. N& K$ f^ !. ]. }# < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < c [~ b; !. !. !. V@ 2 < ~ ~ ! ! ! ! ! ! ! ! : ~ a. T@ !. !. S@ G+ ) _ ! ! ! ! ! ! ! { ~ :~ h+ !. !. !. !. !. 1' g 8 g+ ]. !. '{ 1 ) ! ! : ! x ! : ! '. <# s. !. !. !. !. !. !. !. !. !. !. T+ g^ h^ i^ j^ k^ l^ m^ h. f. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. J+ n^ 0, o^ p^ T] E, q^ r^ z, w' w> s^ t^ u^ !. h+ v^ U~ !. !. $+ C% !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] w^ x^ y^ z^ A^ B^ C^ D^ E^ F^ G^ H^ I^ J^ K^ !+ N* N* q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. 4$ <= L^ M^ !. !. N^ e { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ( z V@ h+ !. !. h+ O^ < ) ! ! ! ! ! ! ! ! ! _ { K }* !. !. i+ Q. 8 _ ! : { : _ ! _ ] _ _. !. !. !. !. !. !. )) e ) _ H+ P^ r> Q. ( _ ! ! : : _ ~ q# u. $+ !. !. !. !. !. !. !. !. !. !. !. !. !. r. 9] @= Q^ R^ S^ =- )% T. T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. b> T^ U^ V^ x, ^! W^ i] X^ Y^ S~ Z^ `^ / ./ !. !. +/ @/ #/ $/ %/ &/ m* !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. */ =/ -/ y) ;/ >/ ,/ '/ )/ !/ ~/ {/ ]/ ^/ // (/ _/ C= :/ ^ T. T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& b> 5/ 6/ u, 8~ -] 7/ 8/ 9/ !. !. !. !. !. !. !. !. !. q. 0/ a/ b/ c/ d/ 0- h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. */ e/ f/ g/ h/ i/ j/ k/ l/ m/ n/ o/ p/ q/ r/ s/ t/ u/ v/ w/ x/ J) .) q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. z& $ y/ !. 7] !) :# g^ 5 < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { g [* r. !. !. $+ /~ 7+ ] ! ! ! ! ! ! ! ! ! _ { b. z/ !. !. _# R. 0 w y f+ J@ 9. U g+ _. u. 8] q. !. !. !. !. U+ !) 2 : : : X+ !. w! Y ) _ ! ! ! < 4 !{ !. !. !. !. !. T@ A/ _~ N l+ y# !. !. !. !. !. !. !. !. !. !. !. g~ X) Y* e. f. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& U. B/ C/ L~ x{ D/ E/ 1- !. !. !. !. !. !. !. !. !. !. !. !. F/ G/ H/ I/ J/ K/ h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. */ L/ M/ N/ O/ P/ Q/ R/ S/ T/ U/ V/ W/ X/ Y/ Z/ `/ ( .( +( @( #( $( 1] !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. %( |% &( k) *( (@ I@ =( f+ ( ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ~ 4+ M! !. !. !. !. )) ~ ) ! ! ! ! ! ! ! ! ! < j j+ !. !. !. T+ -( v. [# 0. 8. }~ H+ g^ j@ !. h+ q. !. !. !. !. n@ q x ! _ < Y T@ !. ;( x { ! ! ! ) 2 A/ !. !. !. (# N^ a. d ! _ g Y >( !. !. !. !. !. !. !. !. !. !. !. !. ,( I$ -- T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& B! '( )( L~ m; !( ~( {( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. T~ ]( $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^( /( (( _( :( <( [( }( |( 1( 2( 3( 4( 5( 6( 7( 8( 9( 0( a( b( c( d( e( f( ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. g( h( !. !. r. $+ '{ i( S ( ! ! ! ! ! ! ! _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : g K@ @= !. !. !. !. &+ 7+ < ! ! ! ! ! ! ! ! ! < I /~ !. !. !. !. !. !. !. {> y 4 | n{ !. !. !. !. !. {. z# l+ q# _ { ! ! < w W+ !. x! M < ! ! ! { 5 j( q. !. t. ,% 0 ) ) : : ) ( Q. 1/ !. !. !. !. !. !. !. !. s. ^@ !. !. k( l( m( g. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. n( o( p( m; q( r( !. !. !. !. !. s( t( u( v( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. w( x( y( z( A( B( C( C( D( E( F( G( H( I( J( K( L( M( N( O( P( Q( R( S( T( U( c& !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. e. M= V( W( r. !. !. l@ N^ '. ( _ _ ! ~ _ { ) ) < { : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ | W+ !. !. !. !. !. v! '. _ _ ! ! ! ! ! ! ! < V X( !. !. !. !. !. !. r> Y( 0 [ < Z( !. !. !. h+ u! Z u d : _ ! ! ! _ < R u. =( | : ! ! ! _ { ,% ^@ !. `( 6 ( _ ! ! ! ! { 7 [# $+ !. !. !. !. q. %+ _# p# I@ T@ b; !. _ !> ._ h. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. +_ @_ #_ f) $_ !. !. !. !. %_ %/ &_ I! *_ =_ -_ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;_ >_ ,_ '_ )_ !_ ~_ {_ ]_ ^_ /_ <( (_ __ :_ <_ [_ :_ G( }_ |_ 1_ 2_ 3_ 4_ 5_ 6_ ~+ !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. 7_ 8_ 9_ 0_ ]) &+ 9] !. }* U ( w 6 < < e b ). . H u 7 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ^ Q P^ !. !. !. !. r> n+ g : ! ! ! ! ! ! ! : _ Y+ z/ !. !. !. !. &+ :~ z _ _ ) u a_ !. !. r> @& [ ] < _ ! ! ! ! ! _ ~ a 9 : ! ! ! ! _ < g+ b_ T@ :. 7 : ! ! ! ! ! _ { @& S+ !. !. !. !. T+ $= ). ! e '. K@ 8> !. k) &= G$ g. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& B! n, c_ [- m; d_ !. !. e_ 9- G! 0~ f_ g_ h_ >] r^ i_ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ :_ x_ x_ x_ y_ 3( z_ A_ B_ C_ B_ D_ E_ d& s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. L@ -) J% F_ G_ H_ v. i( o@ X( X+ p ) k I 9 q !) N^ b_ 8] /~ 8> H+ 7 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : Y+ ]) !. !. !. !. *+ f+ ~ _ ! ! ! ! ! ! ! ! { x O. s. !. !. ,; Y+ x ] ! ! _ ( s z# !. 9] P ( _ ! ! ! ! ! ! ! ! : ( { ! ! ! ! ! ! _ d I Q. m ~ ! ! ! ! ! ! : ! G+ j@ !. !. !. ]) += } ^ : { ( 8 r 7] !. !. R& (' h. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& U. I_ J_ o> K_ L_ $+ !. K/ M_ N_ O_ *] P_ Q_ R_ S_ T_ U_ !. !. !. !. !. !. !. V_ W_ f~ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;_ j_ X_ Y_ Z_ `_ : .: +: @: #: $: %: &: *: =: z_ x_ x_ x_ x_ 3( -: ;: >: E( ,: ': ): @* ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. S. U. !: .$ ~: {: j@ /~ _@ @& 0 5 x : g T J@ 2/ =+ %+ !. !. !. !. !. 9, ,% : : ! ! ! ! ! ! ! ! ! ! ! ! ! : e 1' !. !. !. !. ]) y. 9 _ ! ! ! ! ! ! ! ! ! ! < 3 `( l@ ]: j < < ! ! ! ! : ( Q @= ~. [. ] _ ! ! ! ! ! ! ! ! _ { < ! ! ! ! ! ! ! : ] ! ! ! ! ! ! ! ! ! { e G~ q. !. !. j@ i( 6 ) ! ! ! ! : < v j( ^: !. X) >^ 8+ T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. /: (: _: :: <: u( !. [: }: B> N~ m] C> i] N~ |: 1: 2: !. !. !. !. !. !. 3: 4: ^! <: 5: 6: !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;_ j_ 7: 8: 9: 0: a: b: c: d: e: f: g: h: m/ i: E( y_ x_ x_ j: k: l: m: n: o: p: q: r: s: 1@ T% q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. T. *= N& Q& b$ $+ h+ !. k@ _@ n ) ) : : x n+ (# !. !. !. !. !. !. !. !. !. }* . : _ ! ! ! ! ! ! ! ~ ! ! ! ! { ~ ]: !. !. !. j@ Z( 6 ) ! ! ! ! ! ! ! ! ! ! ! _ { 1 . 1 < ! ! ! ! ! ! ! < 6 ;+ 1/ }# ( _ ! ! ! ! ! ! ! _ i G~ s : ! ! ! ! ! ! ! ! _ _ ! ! ! ! ! ! ! { e m+ !. !. !. y# R ( _ ! ! ! ! ! _ f a -+ t: u: v: w: -- T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. /: x: y: z: Q_ A: B: C: C> U] D: J! E, Y] B> E: |: F: E{ !. !. !. !. 1- G: =] D> H: A{ g) I: r( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. J: K: L: M: N: O: P: Q: R: S: T: T: U: V: W: X: p: Y: x_ Z: `: < .< +< @< #< $< %< &< *< =< -< s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. f. Z- |% ;< >< !. C% !. !. $+ [* < : ! ! _ ! T ]: &+ 9] !. !. !. !. !. !. !. !. %= V : _ ! ! ! ! ! ! ! ! _ < { { M 7] !. !. !. ~. K@ [ g ! ! ! ! ! ! ! ! ! ! ! ! ! { < : ~ ~ ! ! ! ! ! ! ! ] q %= O 8 _ ! ! ! ! ! ! : _ O. !. o@ 9 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { d o@ !. !. !. 7] v ] ! ! ! ! ! ! ! _ : a q# '{ !. ,< '< )< T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= !< ~< {< ]< ^< D> /< t, (< Q_ _< :< x> << D> [< }< |< 1< !. !. !. 2< 3< 4< B> r^ q^ 1: 5< 6< 7< e_ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 8< 9< 0< a< b< c< d< e< T: T: T: T: f< g< h< i< j< k< 5( l< m< n< o< p< q< r< s< t< u< v< w< x< y< z< q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. S. f. e* A< B< !. !. !. !. !. !. $+ G~ ] : ! ! ! _ < W 6+ O. ){ @= !. !. !. !. !. !. T+ Q. ~ : ! ! ! ! ! ! ! _ w 3 : 9 Z( r. !. !. h+ /~ Y { x ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! ! ! ! ! ! ! ! ! ! < c N^ m@ o ) ! ! ! ! ! ! _ _ t C< J@ } : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < v =+ !. !. !. U@ v ] ! ! ! ! ! ! ! ! ! ] ] D< h+ !. 3/ E< U. f. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= F< G< H< I< 8~ B> z{ m] E, p] J< K< L< :< R_ M< N< _: O< !. !. g~ P< l; Q< R< l] i] S< (< T< U< V< W< !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. */ X< Y< Z< `< [ .[ +[ T: T: T: T: @[ #[ $[ %[ &[ *[ =[ -[ @< ;[ >[ ,[ '[ )[ ![ ~[ {[ ][ ^[ /[ ([ _[ s+ !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. N& :[ <[ !. [[ `) q. q. !. !. j@ 4+ ( _ ! ! ! ! _ : { _ h I@ {> b_ {. M! h+ !. T@ 0. g : ! ! ! ! ! ! ! ] K b, i( i( &+ !. !. !. b; m+ x : ~ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { h 8> !. j( c { ! ! ! ! ! ! ! ) { 7 ~ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < T }* !. !. !. V+ h ] ! ! ! ! ! ! ! ! ! ! < 2 Z( }[ !. [/ V) [; T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= J+ |[ 1[ 2[ ]< <: 3[ 4[ }< ^! U] N_ R_ l; 5[ 6[ 7[ }< 8[ r( !. !. 1- ,] o] [^ 9[ 0[ a[ l] r^ *] 1: o] i; b[ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. c[ d[ e[ f[ g[ h[ i[ j[ T: T: T: T: k[ l[ m[ n[ o[ p[ q[ r[ s[ t[ u[ v[ T: @[ A^ w[ x[ y[ W: z[ A[ B[ C[ z< !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. S. <% D[ _% !. E[ O^ ;+ !. h+ h+ !. M! J@ 8 _ ! ! ! ! ! ! _ : ) d r R. K@ x. F[ Z{ w. ). ! _ ! ! ! ! ! ! ! ^ H w! !. !. !. !. !. !. M! I@ ) : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ! ! ! ! ! ! ! : } 4+ l@ U+ . ] ! ! ! ! ! ! ! ! : : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { S 6] !. !. !. #= | ] ! ! ! ! ! ! ! ! ! ! ! { ~ 8. k@ !. N= G[ }, g. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= H[ I[ o> J[ K[ L[ ;] 1: [{ M~ O_ B> M[ w{ N[ N_ 1: O[ !. !. !. P! _{ T< 0~ U] W] J< P[ T] Q[ r^ J< f_ ]! q; !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] R[ S[ T[ U[ v] j[ T: T: T: T: V[ W[ X[ Y[ Z[ `[ } .} Y[ +} @} T: T: T: #} V[ $} %} &} *} =} -} ;} >} N* ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. T. ,} &= !. '} C< g K@ S+ !. !. !. b; X+ ( : ! ! ! ! ! ! ! ! ! : < < _ d o M 2 g ! ! ! ! ! ! ! ! ! < p !{ !. !. !. !. !. !. h+ o@ w { ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : { ] : ! ! ! ! ! ! ! ! { b Y g+ a : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { d 4+ T+ !. !. r> _@ } < ! ! ! ! ! ! ! ! ! ! ! ! ] ! Z( j@ !. k) D% F$ U. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& !% )} m' c/ !} D, E, [< O~ [< N[ ~} W] << {} T] B> B> ]} !. !. !. ^} /} (} N~ _} N~ m] O~ O~ m] Q_ :} U< <} [} }} !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: |} 1} 2} 3} 4} E) 5} 6} O( 7} T: T: T: T: T: T: 8} 9} 0} n[ a} b} c} d} e} +> !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. f} }, g} !. T@ o@ H+ 9. }* h+ !. !. !. _# J ] ] < : : _ ! ! ! ! ! _ _ _ { < ) < _ ! ! ! ! ! ! ! ! ! { 6 g^ !. !. !. !. !. !. S@ }~ | ) ! ! ! ! ! ! ! ! ! ! ! ! : ) { e d H ` g ) { _ ! _ { ] _ e 8 = : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) q )) q. !. !. k@ n+ e : ! ! ! ! ! ! ! ! ! ! ! ! _ [ 0. ^@ !. !. h+ h} H$ T. T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= J+ i} <- j} t' w' (< }< k} k} Q~ 0~ l} K[ W^ T] m} 9[ n} !. !. !. o} o' D> Y] p} q} m] k} k} }{ r} s} t} D> u} v} 2< !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: w} C^ x} m/ y} E( z} A} B} C} D} T: T: T: T: T: T: T: E} F} G} H} t< I} J} K} L} M* E. q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. M} 5, ,( !. j+ [# /~ >( T+ !. !. !. !. ]. K@ }# g+ 4 ! : { { : < ) < : : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! < 5 _@ j@ !. !. !. !. !. X( T ! _ ! ! ! ! ! ! ! ! ! ! ! _ x q z. O^ n@ /@ Z{ H d ~ { _ : p n S N 9. k ! _ ! ! ! ! : : : { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) W V@ !. !. !. P^ J@ g : ! ! ! ! ! ! ! ! ! ! ! ! ! ] I 6] !. !. !. !. f' >- f. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& N} 5/ O} S] <] :< N_ }< k} R_ P} N~ l; R< *] Q_ Q} p} R} !. !. !. S} I< 9~ N~ T] r^ 7[ O~ O~ P} r] T] m] M< M< g_ T} 3{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: U} d: V} W} X} Y} D( Z} `} | .| T: T: T: T: T: T: T: T: T: '[ +| @| #| $| %| &| *| =| s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. T. -- f* g' !. !. U@ $= b_ !. !. !. !. !. !. ]. Z 1' 8] V@ =( :. }# o _ 1 M a g { : : ! ! ! ! ! ! ! ! ! ! ! ! ! _ { o+ /@ !. !. !. !. !. #= o ) ! ! ! ! ! ! ! ! ! ! ! _ < R. -| ;| r. !. !. $+ /~ F[ =( S ! J i( {> ^. <' !. >| H { _ ! ! g x ) { 6 : : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { w <# !. !. !. 6] f+ _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! : g 6+ -+ T@ !. !. k) ,| G$ L@ e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. '| )| !| [} U] ~| }< k} [< N_ Q_ 0[ O~ [< {| (< ]| s( !. !. !. ^| /| [< ;] ;] n] (< R_ 9~ M< :< (| U] B> W^ M< _| V^ $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: :| <| [| }| || 1| 2| 3| 4| 5| .| T: T: T: T: T: T: T: T: T: T: .| +| 6| 7| | }_ 4_ 8| y< T% q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. T. 4$ 1% _% !. !. T+ _. )) q. !. !. !. M! }* y# i( W+ !. !. $+ P^ >( k+ N ,{ Z{ !{ Z) G+ f+ 4 : ! ! ! ! ! ! ! ! ! ! ! ! ! < 3 ,{ M! !. !. !. !. U@ s ) ! ! ! ! ! ! ! ! ! ! ! < 1 -+ j@ !. !. !. !. !. !. !. r. w. 6 2/ !. !. !. !. !. !. i( 6 { ! { } >+ <~ !) Z) L { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { w j( !. !. !. )) b { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < g K@ i+ !. !. r( 9| 0| L@ e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= !% a| K~ v} b| c| N_ }< k} N< D> B> d| k} ;] e| E, f| !. !. !. g| 4= A, l} h| i| j| B> z> k| l; U] r} N~ U] q} l| m| n| n* !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: o| p| q| r| s| t| u| X: v| w| x| T: T: T: T: T: T: T: T: T: T: E} y| z| A| B| C| D| E| F| G| d& !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. T. -- 1% H| !. !. !. >| X( j@ !. !. !. _# }# U b. y. ]) !. !. !. !. !. S+ S+ !. !. r. i+ >| n+ 7 < ! ! ! ! ! ! ! ! ! ! ! ! _ < i #= !. !. !. !. a_ L ) ! ! ! ! ! ! ! ! ! ! : w G+ T@ !. !. !. !. !. !. !. w! ,; O { 5+ V+ <' !. !. !. !. >| }. ) _ ) } :# !. b; j@ }* }# : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) w I| !. !. !. i( e { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ) e K@ b, k@ !. J| K| U) U. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= U. L| M| N| S] O| N_ P| k} O~ O~ O~ Q| k} a[ Q~ Q| R| !. !. !. !. y' l] M< Q~ k} e| S| Q~ M< T| U| (< 1: P} W^ V| A> t} W| X| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: Y| Z| `| 1 .1 z} +1 @1 +: #1 @} T: T: T: T: T: T: T: T: T: T: T: 7^ $1 %1 &1 *1 Y' =1 -1 ;1 >1 M* q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. S. F$ ,1 .; !. !. !. !. S+ h+ !. !. s. $= { 8 ] c [* 1/ !. !. !. !. !. !. !. !. !. !. !. z/ a. _ : ! ! ! ! ! ! ! ! ! ! ! ! : { H v! h+ !. !. X( r < ! ! ! ! ! ! ! ! ! ! { V u! h+ !. !. !. !. !. 9, [~ Q. s W ~ _ q [~ ^@ !. !. !. {. Q < _ ) ). Z{ !. !. !. !. i( d { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) 8 q ){ !. !. !. X( h ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : { d <~ S+ '1 )1 !1 7' U. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& B! ~1 {1 2[ #_ ]1 x> D> [< ^1 M< k} /1 q^ << t} (1 V^ !. !. !. _1 :1 L[ <1 [1 Q~ O~ k} O~ k} Q~ K< R_ k} O~ R_ -] L[ 1: Q~ }1 2< !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: |1 11 21 31 41 /[ 51 61 X[ 71 81 T: T: T: T: T: T: T: T: T: T: T: T: 91 01 }| a1 b1 c1 d1 e1 f1 g1 E. q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. U. M} D[ h1 !. r. v. [~ s. !. !. !. !. '{ y ] ! _ { e Y+ X( )^ 9] r> b; !. !. !. !. !. !. !. '{ j < _ ! ! ! ! ! ! ! ! ! ! ! ! : ~ Z -+ '{ _# G~ a { ! ! ! ! ! ! ! ! ! _ { r z# !. !. !. !. r. -( [. e ! { g g : ^ v 8> !. !. !. &+ f+ ] ) s X( M! !. !. !. !. j( p { ! ! ! ! ! ! ! ! ! ! ! ! ! { y y. ]: s. !. !. !. %+ O ^ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ^ c v. (@ i1 j1 k1 U. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. l1 m1 M_ T_ n1 l| D> m] w' o1 T| m} R< E, }{ O~ p1 !. !. !. q1 r1 q^ l} s1 t1 9~ k} k} k} k} k} k} k} (< p] P} q} u1 v1 w1 ]! y' x1 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: y1 z1 A1 B1 C1 D1 E1 F1 G1 H1 8} T: T: T: T: T: T: T: T: T: T: T: T: k[ I1 J1 `| K1 L1 M1 N1 v= O1 P1 E. q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. U. `- a$ !. ]) += 0 9 m+ j@ !. !. !. /~ L ] ! ! ! { ~ v ` @& O. ,{ /~ h+ !. !. !. !. !. P^ <. : _ ! ! ! ! ! ! ! ! ! ! ! ! ! : ~ 2 s U a g ! ! ! ! ! ! ! ! ! ! _ : U ,; !. !. !. !. (# Y ^ { _ ! _ ! ! : _ 8. ^@ !. $+ A/ l ] ( 5+ j@ !. !. !. !. k@ p@ } { ! ! ! ! ! ! ! ! ! ! ! ! : a l+ S+ h+ !. !. !. !. !. #= W ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ^ V a_ r. 2' |& 6$ h. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. Q1 ~< R1 F> S1 T1 }< i| }< *] ~} B> k} 9~ |{ }{ U1 !. !. !. V1 {| p] 0~ x> K_ N_ 1: k} R_ q^ ;] i| D> l; A, E, z> U] Q~ n] T< q^ W1 X1 !. Y1 O< !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: y1 Z1 `1 2 .2 +2 @2 #2 $2 .| j[ T: T: T: T: T: T: T: T: T: T: T: T: T: %2 #[ &2 *2 =2 -2 ;2 >2 ,2 '2 )2 s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. T. |% ;{ !2 Y+ : ) ^ y '{ !. !. !. ~. 4+ : : ! ! ! : ) ] ) e 4 U [* ]) !. !. !. !. ~2 Q : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { < ) : ! ! ! ! ! ! ! ! ! ! ! _ : '. (@ !. !. !. !. 6] q ( ! ! ! ! ! ! ! : 1 x. v! ]: I e _ { w D< /~ i+ 9, W+ 4+ r g _ ! ! ! ! ! ! ! ! ! ! ! _ { S >( !. !. !. !. !. !. !. $+ m+ x { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ) H l@ !. !. 8_ {2 f. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. n( s{ R1 t, T] ]2 }< k} O~ e| Z] ^2 k} /2 (< l| (2 !. !. !. _2 :2 <2 z> ^< [2 I! 0~ l} B> k] }2 }< h| |2 s} V] ^! 12 0~ -] m] 22 R_ 32 42 F/ 52 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: y1 62 72 82 92 .2 02 a2 b2 c2 .| T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 8} d2 e2 f2 g2 h2 i2 j2 k2 l2 m2 ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. h. D$ n2 o@ _ ] ! < c V@ !. !. !. M! 4+ < : ! ! ! ! ! _ _ : { ^ ! q# Y( ^. ]) t. [* z : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ` b_ !. !. !. !. v! z ] ! ! ! ! ! ! ! ! ) ~ n | _ _ ! ! < ! L 4+ H+ o e ~ ! ! ! ! ! ! ! ! ! ! ! ! ! ! { t _# !. !. !. !. !. !. !. !. z# i ] ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { { Q ^. o2 L% l( 4$ f. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= !% Q1 p2 q2 r2 :< N_ }< k} k} O~ Q~ l} p] s2 t2 d; u2 !. !. !. e_ v2 1: (< S| z> w2 Q< *] n] =] q^ }< U] Q_ ;] [< w' x2 << m; l} D> z{ E: :^ y2 J| 0, !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: y1 z2 A2 B2 C2 D2 |_ }_ E2 F2 G2 d2 j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E} x| H2 I2 J2 K2 L2 M2 N2 O2 f( !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] $= Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. S. J+ P2 Q2 C< ! { ! : ~ I@ r. !. !. h+ l+ w ] ! ! ! ! ! ! ! ! ! ! _ ) 0 }. Q Z 3 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ R. 8] !. !. !. !. (@ h ] ! ! ! ! ! ! ! _ 4 7+ J ~ : ! ! ! ! : { ~ ~ { : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! { w ;+ b; !. !. !. !. !. !. !. j+ }. ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ [ J 9, !. R2 M= S. h. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= e. S2 T2 {! i; W] N_ }< k} k} E, t^ U2 V2 I: !. !. !. !. !. !. !. n* H! P| D> R_ N~ :< 0~ E> (< W2 C> J< ^! w> w' E, w' W^ q^ *_ T] W2 (< 0~ X2 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ Y2 Z2 -2 `2 n< 3 .3 +3 @3 #3 $3 %3 &3 *3 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: =3 -3 ;3 >3 ,3 '3 )3 !3 ~3 E. q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ R 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. T. '> {3 ]3 ^3 /3 < _ ! ! ) U l@ !. !. !. k@ $= { { ! ! ! ! ! ! ! ! ! ! _ < ] { _ : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ). {> !. !. !. !. ~. 4+ { : ! ! ! ! ! : ! P. &+ -( T { _ ! ! ! ! _ : : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < R 6] !. !. !. !. !. !. !. u. t ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) 9 F[ !. !. (3 |% f. S. e. e. e. e. e. e. e. e. e. e. e. e. e. z& U. |[ _3 G! q] T] N_ }< O~ }< w' x> (1 (< :3 !. !. !. !. !. !. !. !. <3 W] 9~ R_ }< N_ M< Q~ (< E, C> [3 0~ l; =] E, D, o1 p] S| :{ ^! 0[ N< T] }3 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ E} |3 13 23 33 43 53 63 x_ 73 E( 83 m/ 93 03 7^ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 7^ a3 b3 c3 d3 e3 f3 g3 P1 E. q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ R } & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. f. m( h3 k) b, d < ! ! ! : 7 p@ r. !. !. !. (# 7+ ' < ! ! ! ! ! ! ! ! ! ! ! ! _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 7 O^ r> !. !. !. !. ;+ : : ! ! ! ! ! { _ =( !. P^ I+ < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { x G+ (# !. !. !. !. !. i+ m+ a { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ] I+ ~2 !. !. f' !~ f. e. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= i3 c_ c) n; w> M[ }< }{ }< 0~ w' }< |: j3 !. !. !. !. !. !. !. !. y2 k3 B> D> O~ N_ J! O~ O~ t} S| e| (< U] ;] D> l; _< Q_ U2 t} w{ l3 N~ 9~ Q_ 8= 6% !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ S: m3 n3 o3 p3 q3 r3 x_ x_ x_ s3 t3 X[ u3 v3 w3 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: f< x3 y3 =2 z3 A3 B3 C3 t~ s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y } & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. U. {2 D3 !. ]: } < ! ! ! ! ) 4 i( 9] !. !. !. >| Z x ) : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) l X( !. !. !. w! @& < _ ! ! ! ! ! < n v. !. r. ,{ 4 ) ! ! ! ! ~ ~ { < : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { w 0. m@ i+ b; !. b; :# J _ _ ! ! ! ! ! ! ! ! ! ! ! ! { ] { ! ! ! ! ! _ { < : x 7+ b_ !. k) E3 !: U. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= B/ o> u> F3 /| G3 0[ =] P} r} T] n] H3 I3 J3 !. !. !. !. !. !. !. T~ K3 0[ B> U< L3 Q~ k} O~ Q~ L< q^ }< M3 r] p] 0~ L[ [2 n] 9~ ;] J! Q~ B> m| A, N3 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ O3 C^ P3 Q3 R3 S3 A_ x_ x_ x_ J( X/ T3 U3 V3 W3 X3 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: v[ Y3 Z3 `3 4 .4 +4 @4 N* !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. U. 5$ #4 !. $4 6 < ! ! ! ! ! < 6 K@ {> %+ !. !. {. m+ V : ) ) < : : _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! _ { ] < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < Y :# z/ ^. !) | : ! ! ! ! ~ _ [ ,% w! !. !. @= G~ } < _ < { _ : 6 b 6 { < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < ~ J O. <# =+ <# Y x : ! ! ! ! ! ! ! ! ! ! ! _ < c n 6 < ! ! ! { b a@ Z : ) ^ P %4 !. w# ~& f. S. e. e. e. e. e. e. e. e. e. e. e. z& Z= 5~ ~< M_ F> ^2 &4 E> Q_ J! t} z> U] ;] ;] *4 !. !. !. !. !. !. !. X| =4 Q~ R_ -4 Z] R_ ;4 k} }< >4 E, e| z> -] Q~ N~ Q_ [2 r^ ^1 q} T| Q~ m] }< w1 ,4 r> !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ '4 )4 >3 K2 !4 ~4 y_ x_ x_ y_ {4 ]4 g2 ^4 /4 X3 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: (4 _4 :4 <4 [4 }4 |4 14 d& !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. f. Z* 24 h+ 34 7 { ! ! ! ! ! ! < { o 4+ }* P^ !. q. '{ _~ I+ '. q 9 < { { { { : _ _ ! ! ! ! ! ! ! < g V j z ~ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : g l Z I c : ! ! ! ! ! ! ] b w. r. !. !. !. k@ [# 4 ) c x ) L ;+ l+ O^ Y+ q : : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : 7 c W 2 e : ! ! ! ! ! ! ! ! ! ! _ : { 0 += V+ G~ z { : : ! 5+ *+ k+ b < ) 5 n@ !. !. _' F$ f. e. e. e. e. e. e. e. e. e. e. e. z& e. F< s{ 44 <^ W^ 54 k} k} N< R_ R_ 64 -] 74 S1 84 q. !. !. !. !. !. 94 g) q} T1 << o1 N~ |: e| B> E, R< (< [< q} U] N< 04 >4 x> W^ x> K[ w> T] }< |: T1 a4 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ @[ 03 b4 c4 d4 e4 1| [_ J( s3 f4 g4 h4 i4 j4 X3 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: D} k4 W: l4 m4 n4 o4 p4 E. q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ R 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. S. M} q4 r4 g| m+ g { ! ! ! ! ! ! ! _ ( g b. _~ ^) q. !. b; `) /~ %= <~ :. 6+ T a 6 e { ) < ) < : { ) ] x 5+ #= (@ n{ S { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < ) < _ ! ! ! ! ! _ { s !{ @= !. !. !. ~. q. x! t J n{ ,{ p@ 7] r. r. S+ `) )) H 7 _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : < < { _ ! ! ! ! ! ! ! ! ! ! _ { } R I| <' !. j@ ){ n / 8 c I+ Y+ p@ 6+ : : : I+ 1/ !. c$ Q& }% U. e. e. e. e. e. e. e. e. e. e. z& e. s4 t4 q] u4 v4 Q~ }< k} O~ }< :< :< *] s} w4 I! }- x4 0- h+ 2= y4 O[ N_ =] v{ N~ a[ A, V] n] E, N~ N~ ]2 n] w' s^ N~ g_ z4 k} W2 Q_ l3 }: p} U< U< A4 T] B4 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: C4 D4 E4 F4 G4 H4 L( X/ I4 J4 K4 L4 M4 m3 X3 T: T: T: T: T: T: T: T: T: T: 7^ N4 O4 S: T: T: T: T: E} (4 P4 Q4 R4 S4 T4 N4 U4 V4 W4 d& q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. U. -- X4 b$ !. !. C< ! { ! ! ! ! ! ! ! ! ! : { e t N^ q. !. !. !. !. $+ k@ z/ 7] V@ ;+ y. 6+ J } c 6 < 9 d W [* (# !. !. $+ :# l < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ! ! ! ! ! ! _ : R a_ !. !. !. /~ I@ I@ z. 9 x. !. !. !. !. !. !. !. !. r. m@ ` { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! q n+ (@ !. !. !. !. !. %= z. '. p 6 _ Y+ _@ } : : ! ,> M! !. ,( f* e. T. e. e. e. e. e. e. e. e. e. z& U. a| Y4 A: u{ [^ ~| }< k} 9~ O~ N~ O| &4 k] q^ Z4 O~ }2 7~ `4 5 .5 r1 +5 =] Z] U] O~ N~ x{ ^! p] ;] O~ 9~ S| k} @5 #5 i; E, Q~ N~ << p] F> $5 %5 {} 9~ H: p( o} !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: &5 *5 =5 -5 ;5 &, ]4 >5 ,5 '5 )5 !5 ~5 T: T: T: T: T: T: T: T: T: j[ N4 {5 d< ]5 j4 ^5 T: T: E} /5 (5 _5 :5 <5 [5 }5 |5 15 25 35 c& !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. f. 4$ 5, M$ !. 8] I+ : _ ! ! ! ! ! ! ! ! ! ! _ { / q# &+ !. !. !. !. !. !. !. !. !. $+ w! 9, z/ I| N^ I| O. ,{ %= u! S@ !. !. !. !. S+ D< e : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { Q 1/ M! k+ I _ ) ) < K j+ !. !. !. !. !. !. !. !. q. }~ c < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { b [* ;| !. !. !. !. !. !. !. s. ]. :. { ) H ,> } : ! ( p U@ !. !. ;< M} f. e. e. e. e. e. e. e. e. e. z& Z= ~1 45 2[ 55 65 54 k} k} [< N< [< y> << T] K[ ^1 <2 /2 H: Z4 ]2 R_ o] Q~ =] 12 B> k} 1: W^ 5[ 0~ N< }{ M< E, ]< 75 =& 7= A: 1: r} s} N< w' 85 .^ H! U< O~ U< 95 h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: E} 05 a5 b5 c5 d5 }| l/ e5 f5 g5 h5 T: T: T: T: T: T: T: T: T: 8} d2 ]5 i5 +: j5 k5 l5 *3 j[ m5 n5 o5 p5 q5 /4 r5 s5 t5 u5 v5 w5 >1 M* q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. f. -- x5 k) !. -+ 4 { ! ! ! ! ! ! ! ! ! ! ! ! ! 8 Z y# ,; #= 6] %+ >( z# )^ m@ n@ T+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. j@ ;+ d { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : : _ ! ! ! ] 3 A/ >| ). / { _ _ ! : h g^ r. !. !. !. !. !. !. !. >| g+ ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < ). =+ !. !. !. !. !. !. !. !. !. !. z/ I+ ! x c g ! ! _ { 8. 9] !. 1= I% -- S. e. e. e. e. e. e. e. e. z& U. /: y5 v} 5[ -4 >4 ;] N< Q_ l3 Y] t1 *_ z5 z> Q< z> t} r} m] 0~ ^! Q~ k} m] z> M< k} 9~ R_ v{ l| (< (1 A5 B5 C5 !. !. !. p, D5 N_ R_ e| 22 E5 F5 G5 *] << (1 w' `^ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: j[ C4 H1 *5 H5 I5 J5 K5 L5 C4 E} T: T: T: T: T: T: T: T: N4 Y3 M5 N5 O5 P5 Q5 R5 S5 T5 U5 V5 W5 X5 Y5 Z5 `5 6 .6 +6 j5 Y2 @6 #6 }@ s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] $6 $= Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. #. S. %6 8_ !. r. [~ 9 { ! ! ! ! ! ! ! ! ! ! ! ! _ [ P *+ Q. } V Z I y '. n 7 :. -( `) b; !. !. !. !. !. !. !. !. !. !. !. !. r> Z) 6 : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ~ e : { ! _ _ j X( k@ y. e _ ! ! ~ _ / a W+ <' !. !. !. !. !. !. `) <. : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < W W+ !. !. !. !. !. !. !. !. !. !. z/ ,% ~ { { ! ! ! ! { x 2/ r. !. &6 Z* f. e. e. e. e. e. e. e. e. z& )< *6 <- =6 -6 ;6 ^2 Q_ Q~ ^< T] J< G3 o1 C> 1: Q~ >6 r] L[ w{ ]2 L< M3 h| [< %] A> O~ k} O~ }< B> (< ,6 '6 T~ !. !. !. !. !. T~ <3 M_ 0~ m] (1 )6 !6 8~ U< z5 H: ~6 {6 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: 8} x| m3 ]6 ^6 /6 (6 j[ T: T: T: T: T: T: T: T: v[ _6 :6 <6 [6 +: }6 (5 |6 16 v> 26 36 46 56 66 76 86 96 06 a6 b6 c6 d6 e6 f6 @ ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. #. 3] g6 x# h6 P. L 7 _ ! ! ! ! ! ! ! ! ! ! ! : ) _ n+ W+ t / ! 9 ^ ) ^ ) ) 7 v I 0. =( 6] !. !. !. !. !. !. !. !. !. !. P^ n+ 7 : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ~ V 8. N z. 1 ! < } ;( ~. !. T+ [* w { ! ! ! _ ! i G~ 6] !. !. !. !. !. *+ R. { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : g P ~2 !. !. !. !. !. !. !. !. !. A/ 3 ^ _ ! ! ! ! ! ! ( 2 i6 !. j6 6$ f. e. e. e. e. e. e. e. e. *= '% k6 ~< d) b| x{ l; Q~ (< A> *] l6 E, r] (< O~ O~ U< l} << E, R_ m6 B> Q~ N~ p} L3 e| }< e| ;] E, K< n6 o6 !. !. !. !. !. !. !. !. u2 r, w' w1 n] T_ O| 0~ p6 g_ m] q6 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: E} 7^ 8} S: T: T: T: T: T: T: T: T: T: 8} r6 s6 h4 t6 u6 v6 X/ /[ 1_ E1 w6 x6 y6 $2 z6 A6 B6 C6 D6 E6 F6 G6 H6 I6 v5 J6 K6 M* q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. #. ~& L6 !. Y# [ { ! ! ! ! ! ! ! ! ! ! ! : ] ! y C< 8] 8] F[ X+ @& R. 6 { ! ! ! : ] ^ ] _ ` o@ :# U+ !. !. !. !. !. !. (# ;+ u _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 5 += `) k@ l@ ;+ } ( x ;+ !. !. !. 8] r ) ! ! ! ! ! { 9 f+ :# w! 9] !. k@ _. b { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { w a@ {> U+ w! j@ !. !. !. !. !. V+ l ~ { : ! ! ! ! ! ! ^ M6 _# N6 O6 f. e. e. e. e. e. e. e. e. S. P6 Q6 y5 R6 B, S6 :< N< M< N~ -4 ^! T6 ;] N< ;] D> D> L< z> U6 O~ ]2 Q~ D> T1 r^ E, O~ B> 0~ V6 U< d| V^ j@ !. !. !. !. !. !. !. !. !. !. W6 U< X6 N< q^ p} }: Q~ >] Y6 Z6 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: `6 7 .7 +7 @7 #7 Y} J( <_ $7 %7 &7 *7 =7 -7 ;7 >7 ,7 '7 )7 8} !7 ~7 {7 ]7 ^7 /7 &* @ ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (7 #. w: Q] _7 J ) _ ! ! ! ! ! ! ! ! ! ! < ! 1 0. m@ h+ !. !. !. !. S@ 8] $= _ ] ! ! ! ! ! _ { ] < w ` V@ X( X( b_ 1/ 7] Y# 3 _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { d ;( h+ !. !. 8] r / ] t '{ !. !. i+ p# _ _ ! ! ! ! _ { < u 9. [# )) Z( j : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 9 i b. a@ =( I| ){ 8> ;| !. ~. Z{ (. O^ y { ! ! ! ! ! : ] O. :7 <7 f. e. e. e. e. e. e. e. e. S. e] [7 }7 p( s1 u{ |7 P| k} m} ^< -] T] r} 9~ {| a[ ^1 M3 q} (< }< }< ;] e| t} r^ :< 1: N_ I! << [< (1 _: 1< !. !. !. !. !. !. !. !. !. .; 17 E, ^2 S1 Q~ W2 M3 s^ U< g_ 27 u2 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: |3 37 d5 47 57 z} <_ x_ x_ x_ J( 67 77 87 F2 97 C^ #[ 07 w} T: k[ a7 b7 c7 d7 e7 f7 ): c& q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (7 8+ g7 |= h7 : : ! ! ! ! ! ! ! ! ! : ( 0 4+ u! ]) !. !. h+ !. !. !. !. !. T+ n+ } [ ) _ ! ! ! ! _ : < : 3 z V f+ <. . w < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : K j+ !. !. h+ I| } ) : N ~. !. 1/ 0. ~ : ! ! ! ! ! ! _ : ~ w b 0 e _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : { { : 7 a m 3 Q. }* &+ $+ $+ V@ y < ! ! ! ! ! ! '= t i7 j7 T. e. e. e. e. e. e. e. e. e. V= k7 #] j} l7 m; T] k} }< {| l} W^ m7 }< R_ t} (< B> }2 n7 W^ }2 L3 O~ R_ B> :< o7 O~ O~ p7 x2 {| <2 -] q7 T~ !. !. !. !. !. !. !. !. r7 s7 m| ]2 8~ a[ O~ }< :{ O| 1: O~ :^ r. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: t7 u7 v7 w7 x7 y7 z7 [_ 3( A7 x_ <_ 1| B7 7| C7 D7 y1 E7 T: T: T: (4 F7 G7 H7 I7 f3 J7 -* ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (7 h. K7 L7 M7 < _ ! ! ! ! ! ! ! ! : : M n{ i+ !. !. !. !. !. !. !. !. !. ~. T+ @= b, b. ). x _ ! ! ! ! ! ! _ ) ) { : : { : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : : a. y# !. !. j@ <~ 9. (. (@ $+ !. ;| q# ) : ! ! ! ! ! ! ! ! : { < : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ : { < ) ( 9 }. Z p@ $= | _ ! ! ! ! ! ! ! #- N7 O7 P7 {% e. e. e. e. e. e. e. e. z& J+ Q7 T2 R7 S7 B, x2 k} T7 d| x2 l] k} k} k} k} i| (< B> }< {} N_ M< 9~ S| }^ l| q} m} O~ t} l] i] N_ U7 0~ V7 W7 X7 Y7 }/ Z7 !. !. !. M$ !6 `7 e| M< n] k} }{ 54 x{ T] _| w' 8 !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: %2 .8 +8 @8 a1 #8 $8 %8 1( E( &8 *8 =8 -8 ;8 >8 ,8 '8 j[ T: T: T: T: 7} q< )8 !8 ~8 {8 =| s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ]8 8' ^8 /8 (8 _8 ! ! ! ! ! ! ! : ) n !) -( !. !. !. !. !. !. !. !. q. 1/ %= O. }# b. /. %+ ^. '. ] ! ! ! ! ! ! ! ! ! ! _ _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { 6 P. %= 6] j@ q. j@ !. !. !. !. S@ p@ d < ) ) _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : { < ! { < ! ~ ! ! ! ! ! ! : :8 <8 %! =; e. e. e. e. e. e. e. e. z& Z= i3 [8 q2 T_ }8 f) n] ;] B> a[ _} }< O~ O~ k} i| B> N~ O~ k} O~ k} O~ ]2 ^< N~ q} s1 V2 o] [< N[ {| |8 /1 z{ z4 n] 18 `4 28 d_ F/ Z7 !. !. c~ V^ e| }{ k} R_ q^ :< A, Q~ h_ 38 c~ !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: C4 48 58 68 78 j5 88 98 08 a8 b8 c8 d8 e8 f8 g8 h8 i8 j[ T: T: T: 7^ -3 T3 ). j8 k8 .* ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. <; l8 m8 >; : ! ! ! ! ! ! _ { W ;+ r> !. !. !. !. !. !. !. %+ a_ Z( ,% u : ( / J v! 9, ` ( ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ~ a }# Y( 8] S+ !. !. !. !. !. ]. =( 5+ J W ~ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ : : ! ! ! ! ! ! ! ! ! : n8 o8 p8 {% e. e. e. e. e. e. e. e. z& U. Q7 q8 v} 18 q} z> t} N~ r8 N~ *_ v{ n] N_ m] R_ J< T] i| O~ k} k} O~ k} U] << =] l| _< a[ Q~ &4 (< (< [{ l} ;] A{ 9~ R_ 1: t} s8 ,4 t8 u8 S+ q1 i] z{ D> D> T1 T] ^! }2 w1 v8 w8 !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E} `6 x8 y8 z8 ;5 A8 `| @< B8 C8 D8 E8 F8 G8 H8 I8 J8 N4 T: T: T: T: K8 L8 M8 N8 O8 P8 !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q8 R8 S8 T8 != ! ! ! ! ! ! ! ] 1 j( ^@ !. !. !. q. S+ @= >( X( G~ r 7 ! { : _ _ ! u I p : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ) : W R I@ v! 9] !. !. !. !. 9] 1/ y# b, I ! _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : < ( ) { : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! )= U8 V8 W8 {% e. e. e. e. e. e. e. e. z& e. |[ m1 {! V| [2 }2 1: [< 9[ w' U] i] Q_ *] W^ E, [{ x{ T| U< O~ D> N_ k} }< n] 0~ T1 G3 q} w{ K[ :< M< C> >6 U] B> T] :{ B> z4 m| A{ ^< -] X8 /| *_ Q~ p7 z> M< 9[ [{ ^! /1 k] Y8 !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: N4 03 Z8 `8 9 .9 +9 @9 #9 Q3 %3 $9 %9 76 J2 +| *3 T: T: T: T: T: &9 *9 =9 -9 ;9 .) q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q8 >9 ,9 '9 _ ! ! ! ! ! ! < 6 I@ s. !. !. !. 1/ F[ >+ ,% '. n x < { _ ! ! ! ! _ ] ^ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ) < _ ! ! ! ! ! ! ! ! _ < ( 9 . _. >( r. q. !. !. !. !. r. Z( 5 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ : ! ~ d L }. u 4 _ ) _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! )= )9 !9 $! {% e. e. e. e. e. e. e. e. *= !% ~9 {9 o' B, %] i] [< R_ k} E, z> }< }< S| U< P} /1 x> s1 ]9 N[ Q~ Q< x> k} m] z> k] B> n] }2 }2 O_ J< ;] t} E, M< p7 p} V] n7 k] K< f_ g_ w1 k} i] J< q^ >6 D> D, V] r} R_ K_ ^9 !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 7^ y1 A^ /9 (9 _9 :9 <9 [9 }9 |9 %3 19 29 :5 7^ T: T: T: T: T: 8} 39 49 59 69 .) q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 89 99 09 ! ! ! ! ! ! : [ Y+ ]. h+ !. !. 6] $= 1 ) < { ) { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ~ 0 ). h ! : _ ! ! ! ! ! ! ! ! ! : { 5 b. C< -+ {> y# >| V+ A/ a@ } : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : g < _ b 6+ =( -( /~ ){ i( N M ) _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! )= a9 b9 $. {% e. e. e. e. e. e. e. e. *= !% c9 d9 e9 b| ^< Q~ *] ^! *] q^ l| U] }< k} f9 P[ /1 64 Q_ Z] C, W^ q^ U] W2 z> n] T| W] N_ n7 0~ U6 R_ Y] E, }< g9 r} D, z> Q~ ^! h9 z> z5 e| ;] q} x2 l6 z> O~ N_ D, D> 9~ i9 i_ !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: w} T: T: T: T: T: j[ S: f< j9 (4 H2 k9 ]5 l9 m9 n9 E7 T: T: T: T: T: T: T: o9 p9 q9 r9 .) q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s9 t9 u9 #- ! ! ! ! ! _ e b. _# r. !. q. Z{ f+ 9 < : _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { o O^ m@ :# 0. w < : ! ! ! ! ! ! ! ! ! _ { { w 1 r ` R k V } ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : W p# >+ X+ C< Z{ $+ !. !. !. !. !. -( }. { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! )= v9 w9 x9 {% e. e. e. e. e. e. e. e. z& Z= '| y9 s, z9 u1 N_ L3 y> k] z> N[ [2 8~ 0~ U] y> 0~ Q_ Q_ Q_ ^1 Q_ U< N_ W] 0~ R_ R_ B> U< T] T] 9~ }{ D> r} R_ |^ N~ |2 S1 :< V2 V] r^ A9 [< 1: a[ %] w> *] }{ t} p7 m] O~ <: B9 !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: X3 =3 N4 05 R: O4 8} E} T: T: T: T: T: T: 7^ =3 C9 D9 D9 7^ T: T: T: T: T: T: T: T: E9 F9 G9 f( q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H9 I9 J9 K9 { ! ! ! _ { a. T@ !. !. !. ,; I < { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < J ,; !. !. w! <~ V ~ { ! ! ! ! ! ! ! ! ! ! _ : < ) ) : { < : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ 7 T i( ]) M! S@ S+ b; !. !. !. !. $+ k@ q. ]: } { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! )= L9 q{ N} {% e. e. e. e. e. e. e. e. z& Z= M9 ~< N9 <: U| (< ;4 }{ {| U] d| 64 k] J< S| h| 0~ J< >6 :< U< T1 T] z> :< ^! (1 Z4 f_ S| O9 P< P9 Q9 44 q^ R9 Q_ w> *] >4 :{ -] (< S9 E, }< O~ k} Q~ S1 T9 N~ |8 z> U< (< ]< G/ !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: X3 7^ 7^ @} U9 V9 W9 X9 Y9 Z9 `9 9} @} T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: #} 0 .0 +0 @0 q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . #0 $0 %0 &0 _ ! ! ! : o )) !. !. !. !. 1' g ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < W ]: !. !. !. b; =+ [. 6 ) _ ! ! ! ! ! ! ! ! ! ! ! ! _ _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { h }~ ~. !. !. !. !. !. !. !. !. 9] j( ` Y# J@ c : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < *0 =0 e] *= e. e. e. e. e. e. e. e. z& U. i3 -0 O9 =6 ;0 {| t} 9~ 54 }2 l] z> B> R_ O~ O~ (< 0~ s} w' *] N~ W2 Q_ }2 z: X] ~} S] >0 ,0 !. !. h+ u2 -_ '0 K< q^ M< /1 T| l} B> X6 t} O~ k} k} 1: ;] ^! *_ 0~ N_ E, U| s, J/ !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: @} x3 m3 ]6 )0 !0 ~0 #9 {0 ]0 l4 ^0 /0 ]5 h5 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: #} 0 (0 _0 f( q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q8 :0 <0 [0 &0 ! ! : : a@ (@ 7] b; !. !. j( e < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : I {> h+ !. !. !. ]. D< z < < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { L U@ !. !. !. !. !. !. !. !. !. l@ J = < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! _ ) }0 |0 q% e. e. e. e. e. e. e. e. e. z& e. n( c_ v} F> i9 [1 10 d| Y] ^< w' &4 N_ R_ m] [< /1 -] T] /1 [{ :< T7 Q_ 20 c; S} 30 6: c~ !. !. !. !. !. !. V_ V7 Q| (1 R_ T| }2 (< O_ ^< O~ 1: k} |8 z> q^ N_ ;] N~ T1 n] O9 40 !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: U} C4 50 t[ 60 70 a1 ;[ 80 q| 90 00 a0 B8 d5 b0 c0 ^5 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: d0 e0 f0 g0 q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . h0 i0 j0 k0 #- ! ! _ < O 7] p# V+ !. $+ ;( g { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ! ! ! _ : { < < { _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ~ '. n@ b; !. !. !. S@ -| Z p : < : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : < { < ) { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { L U@ !. !. !. !. !. !. !. !. !. i+ 9. ) { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! : : { { l0 m0 n0 1* e. e. e. e. e. e. e. e. e. *= !% /: p2 R6 o0 :< U] D, N_ t} N~ a[ k} T7 k} N_ E, N~ i] f) l; Y] ;] (1 x{ U~ !. !. !. !. !. !. !. !. h+ u2 p0 r> q0 l| z{ g9 Q~ |7 z> E, 9[ 0~ N_ M< 0~ 9[ ^2 E, B> w{ *] }< j} m> !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: |} r0 s0 t0 u0 v0 w0 r| x0 y0 z0 A0 B0 C0 D0 E0 F0 Z1 k[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: G0 H0 I0 G- q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. J0 K0 L0 M0 : ! ! < p o@ 9. 2/ !. ]. Y+ _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! : { : < { : < < { g W n } _ < { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ) q N^ h+ !. !. !. h+ U+ }~ g+ 9 ! { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { < x q '. s 1 d ! _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { 1 -+ !. !. !. !. !. !. !. !. r. !. m@ z ] _ _ ! ! ! ! ! ! ! _ { _ _ < ) c '. t N0 O0 P0 Q0 S. e. e. e. e. e. e. e. e. e. z& e. Q7 R0 R6 ]! q} x> E, |8 |^ }< [< k} k} k} }< }< r} S0 }2 }2 W^ O~ :< 95 }/ !. !. !. !. !. !. !. !. Z7 T0 ^2 o' U0 V0 W0 O~ z4 Q~ Q~ e| N_ A9 :{ &4 Y] /1 E, (< ;] B> [< }< B{ 3{ !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: v[ X0 Y0 Z0 `0 a .a +a @a #a Y} r3 s3 $a %a &a k/ *a J8 N4 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: =a -a ;a >a q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. ,a U. 'a U8 ,= ! _ 7 l 9. t $= /. n+ ). ! _ ! ! ! ! ! ! ! ! ! ! ! ! ! { ! 5 ). K } e z t y. [# n{ V@ ;+ $= Z 4 < : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 8 }. ^. !. !. !. !. !. h+ 6] l+ 9. | ] _ ! ! ! ! ! ! ! ! ! ! _ _ _ { < : 9 l >+ W+ v! x! /. Z) j ! _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ~ Q. {. !. !. !. !. r. (@ n{ D< j( -| }# ) e ! { _ ) 8 ^ ] < _ e _ { 3 k J P P. )a !a ~a {a g. f. e. e. e. e. e. e. e. e. z& Z= F< ]a i; ]! -] ^a I! l} {| D> m] O~ k} k} k} T7 D> T] >4 N~ S1 Q| i] /a !. !. !. !. !. !. !. !. !. q. (a _a T< k} q} T] 04 E> N_ Q~ N< O~ (< N~ T1 :a L3 1: D> B> B> N< z4 s] P! !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: &5 /1 ka !. !. !. !. !. !. !. !. !. !. 7- t1 k} }{ -4 ^! N_ L[ p} J< (< N< g9 R_ }< T] w' t} q^ :< *] >4 [2 la ma !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: E} C^ na e5 oa pa r3 J( y_ x_ x_ <_ *[ qa ra sa ta ua va f< T: T: T: T: T: T: T: T: T: T: T: T: U} E7 wa Q4 xa ya za Aa C= q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. {% $. Ba ]^ : ) q z# '{ 5 f j N q { ! ! ! ! ! ! ! ! ! ! ! : _ l i( 9, r> !. !. w! w. C< :# ^. /@ <' !. !. !. !. ^@ (@ Y# 6 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < 7 p@ ~. !. !. !. !. !. !. !. !. v! T ) ! : : 7 4 p ~ e a }. I Y+ <~ N^ ^. b; !. !. !. !. !. !. !. ,; K ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : | 7+ a@ K@ [. a ( ) _ : < { : i D< G~ '. W+ !. T+ /~ >( T+ 9] T+ s. !. !. =( b ` t Ca >+ Da Ea Fa U= 1* {% S. e. e. e. e. e. 7' Ga Ha P9 p' &4 N~ W^ u4 v{ D> :} ]! -] N~ B> U< (< k] [2 D> s} [^ (1 Ia !. !. !. !. !. !. 6% Ja r7 !. Ka La N_ Q~ N_ W^ U< r} :< Ma N~ i] R_ |{ (1 |: v1 Na w> i; A: Oa +; #/ Pa !. !. !. !. !. !. !. !. !. !. !. !. c[ Qa Ra x^ {] u] +^ j[ T: T: T: T: T: T: T: T: T: E} x3 t[ Sa Ta Ua [_ x_ x_ Va A_ -: Wa Xa Ya Za `a b 8} T: T: T: w} T: T: T: .b 8} 7^ S: V[ C4 (6 +b @b #b $b %b &b *b i! q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. n& :; =b -b ,= : : O. '{ 0 e w. P^ <. ] _ ! ! ! ! ! ! ! ! _ : ~ Z /. 9] !. !. /@ ^) H+ 0 : e z J a. !{ b; !. !. !. !. z/ P ~ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ( k v! !. !. !. !. !. !. !. !. !. %= q ) 3 <. :~ l+ )) =( :~ !{ 6] 9, {. j@ !. !. !. !. !. !. !. !. !. !. 7] }. ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : : _ ] ] { _ ! ! ! ! ! ! ) 3 o+ ). 6+ u. l@ !. !. !. !. !. !. !. 7] 9. p# z. 9 { 9 ;b >b ,b 'b )b !b ~b {b e. e. e. U. J+ (^ !. .; ]b q' a[ Q_ L< T9 =] <2 z> *_ v8 I! 0~ E, ^< ,6 r^ B> V] T7 K_ ^b !. !. !. !. /b (b n; I< _b :b ;0 << D, E, }2 m] 9~ N~ a[ ;] o1 I< 8~ r] Z] t{ v} L~ [- -6 d; !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. S@ y. 9 $= 1/ M! !. !. $+ M! !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^@ 1' y ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : _ _ ! ! ! ! ! ! ! ! ! { < { _ a r _@ 1/ 9] !. !. r. m@ q# 2 Y+ 1 ) _ { ] ~ qb rb sb tb ub vb f. e. e. U. J+ wb !. !. !. xb i; e| L3 v8 D/ {} }{ M< U] D, C> M< =] J< [2 T] N_ R_ w1 yb zb b[ J/ / Ab v{ (1 5< m] *] m} T1 5[ @5 Bb N~ F: Cb Db Eb Fb d~ R} e~ Gb u2 q, Hb ia Ib Jb q0 ./ Kb !. !. !. !. !. !. !. !. !. !. !. !. ;_ Lb Mb Nb y^ u] +^ j[ T: T: T: T: T: T: T: T: T: T: V[ .8 Ob Pb Qb Rb Sb Tb X9 Ub Vb W} Wb 4| Xb I2 Z1 Yb Zb `b c .c +c @c #c $c %c &c *c h: =c -c ;c >c ,c 'c )c !c g{ ~c ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. {% {c ]c ^c /c ( / 0. a_ 7] !. `) Q ) _ ! ! ! ! ! ! _ g i J@ 8] !. !. (c {> t & ) _c ! ! ! ! :c ) 5 v. !. !. !. !. !. T+ J@ _ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ] u ,; !. !. !. !. !. !. !. !. !. 1' t Z{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. $+ 9, w. L e _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! _ ) 8 w '. a@ x! @= =( G~ ;( v _ ! ! ! ! ! : ) /c i] X6 1: T1 3c T1 |: }{ l; B> ^< p^ M_ 0[ 1[ m* !. h+ !. !. !. !. !. !. !. 4c ({ W^ ;] ^! 5c V7 (! !. !. !. !. !. !. !. !. !. !. !. ;_ 6c 7c 8c 9c 0c +^ j[ T: T: T: T: T: T: T: T: T: T: T: t7 ac bc 68 cc 4 dc ec e5 fc gc hc ic 87 jc kc lc mc nc oc pc qc rc c5 sc m/ tc uc vc wc +7 xc yc zc Ac Bc Cc Dc Ec Fc N* q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. S. <7 Gc a Hc z N !. !. !. U@ L ) ! ! ! ! ! ! : ~ R. k+ {. !. Ic Jc a@ Kc Lc w '9 ! Mc Mc ! ! ! ] 2 V@ !. !. !. !. !. `) J@ _ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ~ =( $+ !. !. !. !. !. !. !. !. V@ R t. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 8] g^ <. z { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ] { S Z ( Y+ 8] K@ ^ : ! ! ! ! ! ! _ _ ] r Nc Oc '% U. U. J+ wb !. !. !. r> E/ T6 B> << m} D> k} k} O~ k} k} E, l; k} g9 }< p} o1 k| B> k} Pc N~ y> >4 Q_ l} 0~ {| {| U] p} q^ K< 4< <2 7[ Qc Rc !. !. !. !. !. !. ~. Sc P< Tc L< N~ [< U7 T< s^ 5: ,0 V~ q. !. !. !. !. !. !. !. Uc Vc Wc Xc Yc Zc +^ j[ T: T: T: T: T: T: T: T: T: T: T: X3 bb X9 `c d ;[ .d +d @d !5 C^ #d 7} w3 $d %d &d *d =d -d ;d >d ,d 'd )d !d ~d x} {d ]d ^d Ya /d (d I8 _d :d q} D, O~ k} k} k} k} O~ E, z> k} P| O~ {} A, r8 (< kd d| B> 0~ ^1 w' U] J! y> J< E, *] L3 9~ << N~ |: |: i] ld md Kb !. !. !. X| nd I! W] N< T1 :< 0~ S| (1 k| y, od pd 0- !. !. !. !. !. !. qd rd sd td Yc ud vd j[ T: T: T: T: T: T: T: T: T: T: T: T: S: t7 wd 48 y0 xd yd W3 @} S: w} j[ E} j[ zd Ad Bd Cd Dd Z5 Ed >5 Fd Gd Hd Id Jd Kd Ld Md Nd Od Pd Qd y0 Rd Sd Td Ud Vd Wd Xd Yd .) q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. <; Zd :& `d H> !. Z7 F[ z ] ! ! ! ! ! ! '9 e .e +e !. 6% !. @e #e $e %e &e !. *e =e -e ;e ;e ;e >e ,e bd 'e += p# >( !. r> u! U < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < f+ w! !. !. !. !. !. !. !. ~2 . 6 F[ !. !. !. !. !. !. !. !. !. !. !. !. h+ }* :. W x ! { : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! g _ ( 8 < < ) _ ! ! ! _ { r 8> /@ u. Z{ _. d ] ! ! ! ! ! ! ! ! ! { != )e !e ,} g. P] ~e <' c; {e ]e ^2 e| Q~ W^ A, n] O~ k} k} k} O~ E, 0~ k} N_ W0 9~ ;] :{ l} Q~ x2 E, U6 9~ 0~ *] U< W^ E, 1: B> Q~ k} }2 k] ^e [< 9~ g_ T| /e (e _e :e 3^ S~ ,6 v{ l; p] a[ w' J< T| ]2 |{ o] N_ 4+ 1 u! !. !. !. !. !. !. !. !. !. !. !. !. (@ . : ] { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : i O^ 8. . 8. [# H : _ ! ! ! ~ R. T@ !. !. !. {. O^ x < ! ! ! ! ! ! ! ! { :* Me Ne }% f. Oe Pe Qe W| yb :} }2 t} O~ k} q} L< O~ g9 O~ O~ g9 t^ z> k} B> W^ m] }{ U< v{ *] N_ (< }< D> U< }< a[ x2 N~ z{ 0~ .5 z> T7 E, r] *] l} V2 22 Re U2 >] Re Se t] `4 l6 i] t} O~ q^ y> p} 6[ g9 }{ |{ {| Te !. !. !. !. !. ;_ Ue Ve We Xe Ye +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: X3 7^ E7 '8 Ze `e f .f +f @f #f }. $f %f &f *f :| X3 T: E} $d &9 =f -f ;f >f ,f 'f )f s+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. *= ^& !f ~f {f _8 _ ! ! ! Mc ed ed ;e Je Fe ]f ^f !. !. N$ /f (f _f :f | !. !. !. 9] >+ ! : ! ! ! ! ! ! ! : >; ^ 6$ 7' n& z& 9f 0f b/ af Q_ M< bf :< M< s} [2 i] Q_ N~ B> t} cf V] T7 04 B> k} O~ }{ B> .5 l6 N< T1 U] :< h| W0 x2 p} E, |: W] q} k} }{ }< B> U] E, k} <2 }< j; t' `4 y2 df t} z, 0[ O~ }{ (< S1 T9 T] U< k} H3 X] S} !. !. !. !. = fd Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : x w. !. !. !. !. !. !. !. S+ $= e m+ !. !. !. !. !. !. !. !. !. !. r> %= u { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { 5 Z( q. !. !. !. !. F[ 5 < ! ! ! ! ! I }* !. !. !. ]) R. ] _ ! ! ! ! ! ! _ >; Rf Sf 1* z& Z= Tf 6~ Uf n; .5 N~ s} 8~ L< Q~ 0~ W] w' -] x2 2c :< s^ U] Ma E, Q~ (< N< D> S1 p7 k} m} B> q^ W^ z> Y] Z] R1 l| P} [} Q< g_ Vf M< p7 ^! }2 e| x2 Wf Xf Z6 q. Yf t' B> *] V2 k} ;] X6 Q< K_ x> J< }{ u} Zf h+ !. !. !. c[ Qa `f x^ {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 7^ g j4 D} 7} C^ 91 @} T: T: T: 7^ ee .g $9 *2 +g @g #g $g %g (4 T: T: T: T: T: T: T: %2 &g *g =g -g ;g c& q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. <; 9+ >g ,g < ! ! Mc ed ;e Fe yf 3f 'g )g !g ~g {g ]g ^g /g (g _g :g _g _g :g U] w{ o7 g9 k} {} N_ ]2 V2 V] w' x> 9g :< T] w' E, %] :< V2 m] O~ z4 T1 -] B> z, ^9 Y8 0g 0/ ag M_ A{ E, _} W] r] 0~ }< 5: !. !. !. !. u( bg 9~ :< N_ t} B> 0~ -] -] k] ;] U7 cg Z7 !. !. !. !] dg H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: .b eg fg gg hg ig jg kg lg x| T: T: U} mg ng og pg qg rg sg tg y8 g< y1 T: T: T: T: T: T: ug .| v6 vg wg xg yg !+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. T. [> zg Ag : { Mc ed ;e Fe 3f 'g Of Bg Cg Dg Eg Fg Gg Hg Ig Jg Kg Lg Lg Mg Ng Og Pg Qg Rg Sg Tg Ug Vg Cg 4g Wg 'g 3f Fe ;e ed ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ~ N S+ !. !. !. !. !. !. <' 0. 7 ]: !. !. !. !. !. !. !. !. !. X( u ^ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : T [~ ){ v! ;( b ) ! ! ! ! ! ! ] 0 1' M! !. b; w! Q ) _ ! _ { ! ! < { Xg Yg Zg n& e. /: `g 44 u{ ^! N~ k} U< E, w{ l] h k} O~ O~ O~ M< 7[ O~ }< U< N_ V2 l3 2c T] T] V] r^ T] M< N_ T] m} T] `^ !. !. !. !. .h +h 1: W^ w' q^ t^ Re r1 I: !. !. !. !. @h :< 1: ;] O~ k} E, L< l] q} K< Q~ '6 Z7 !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: t7 #h w6 $h %h &h +f *h fc ta (6 E} X3 =h -h ;h >h ,h 'h )h !h <4 ~h a7 7^ T: T: T: T: T: T: 8} {h ]h ^h /h yg q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. {% 1* (h _h I, :h U6 qh Z7 !. !. !. !. 3= Y] z> Q_ B> W] z> H: -] x4 !. !. !. !. f| r} z{ k} T7 ;] {| q^ |8 R_ << ka r. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 9} rh g2 sh M5 th uh vh #2 S/ Y3 k[ T: k[ wh xh k/ yh zh Ah Bh Ch y[ Dh Eh T: T: T: T: T: T: 7^ Fh Gh Hh Ih O- q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. Jh Kh Lh !. Mh Nh Oh re Ph 3f 'g 5g Cg Qh Tg Rh Sh Th Uh Vh Wh Xh Yh Zh `h i .i +i @i #i $i %i &i *i =i -i ;i >i Qh Cg lh 'g 3f Fe ;e ed Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ) }. y# !. !. !. !. !. !. F[ a / T &+ !. !. !. !. !. !. !. )^ o+ { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { < ) { ! ! ! ! ! ! ! ! ! _ ! } f+ l+ `) {> n ] < n O. U J ,> j( y. 1' ,i <7 f. 5~ /{ T} !| B, B> j| O~ W2 Q< 2c O~ k} k} k} O~ q^ [^ O~ }{ k} k} k} R_ z> s^ k] L3 i] 12 z4 R_ 0[ E, A{ U< 20 .^ M! !. !. Fb 'i >6 q} ~| &4 p7 9~ >] f) J/ !. !. !. p, <: |{ O~ D> W0 N_ R_ z{ z{ M< )i $+ !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: v[ !i ~i {i ]i ^i /i (i _i @| :i 81 T: T: i8 m] h| I! q} t} O~ 9~ O~ O~ Q~ r^ -] E, k} D> D> [< E, << D, ^1 }2 ~} U] E, a[ x> N_ Re R_ Mi Ni d_ Oi af Re M[ l| w' 9~ Pi }2 e| m| =6 Qi !. !. q. Ri d| O~ N< J< B> *] 0~ f_ Si t' p, !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: j[ &9 Ti 23 Ui Vi ;3 Wi )8 Xi Yi =3 T: T: E} Zi `i j .j *c +j @j #j 16 ic 91 $j T: T: T: T: N4 %j &j *j =j -j q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. 1* a' ;j >j ,j u Z 'j )j !j ~j {j ]j ^j |h Ei /j (j _j :j ( !. !. !. !. K$ {2 L@ hj ij u, yb m; s1 t1 N~ 0~ l} f) v{ Q~ n] [< 9~ 9~ jj C, X] J< 0~ y> z> N_ N< O~ k} 9~ z> v{ 0~ (< p} -] 1: t} kj f_ /1 U] a[ O~ k} *] k; N_ W^ l; z5 U6 |: R6 lj +/ !. q; |7 (1 }< Y] Q_ q^ X] y, T| [< B5 !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: mj nj oj pj qj rj h4 H6 sj |} T: T: T: T: T: pf tj )8 y[ t[ uj fb vj wj V9 V[ T: (6 (4 05 xj yj zj Aj Bj Cj N* Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. 1* Ej X[ N7 '= < ! Fj Gj Hj Ij Jj Vg Kj Lj /j Mj Nj Oj Pj Qj Rj Sj Tj Uj Vj Wj Xj Yj Zj `j k .k +k @k #k $k %k &k *k =k Sh |h -k 3g Of 3f Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { f+ 8] !. !. !. !. !. M! O. ! ^ Y+ ^@ !. !. !. !. !. !. i+ ,> 9 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ~ h I }# 9. p# i _ _ ! ! ! ! ! ! ! _ d P N^ n@ Z) J@ o+ 3 ^ a $= !) k t q e _ ! ! ! ! ) ^ L j+ !. !. .; ;k >k T. !< p2 [- ;0 i] _} L3 K< W^ J< t1 q} ^< *] w' 0~ n] h| 0~ l] W^ E, U] t^ 1: O~ t} Q~ }< 9~ k} 9~ O~ z> [2 0~ N_ Y] N_ ;] O~ e| ,k k} T] Q< W^ o1 D, ;] k} 9~ 'k z> )k K/ ./ z: U7 r} K_ 0g !k 7- d~ 85 ~k {k ]k !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: Y2 ^k M5 /k (k _k :k i [h Hi Pf yf ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : [. )^ !. !. !. !. !. /@ z. { ( R ]) !. !. !. !. !. !. 1/ O : : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ e }. }~ 6] ]. T@ `) A/ r 8 _ ! ! ! ! ! ! { 1 1' !. !. j@ s. ;| v. _~ A/ {. @= U@ g+ 8 _ ! ! ! ! ! ! { ( z. 1/ !. c$ 9$ Jk e. Kk p2 F3 55 V] k| t} ;] N~ 12 << 4< t} R_ A> :< }2 *] N[ t^ 9~ t} :{ :{ z> }< (1 (1 z{ O~ [< S| E: Y] l; L[ }2 C> z> Q~ M[ B> f_ _| O~ z> l6 9[ s1 ~} B> m} Lk H: T| Mk Nk X8 << T7 12 Ok e; !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: X3 @[ S: j[ T: T: T: T: T: T: 8} t7 03 Pk Qk C4 Rk R: @} 7^ j[ T: T: T: @} {5 Sk Tk Uk Vk Wk Xk #: pf Yk Zk B8 `0 `k l .l +l @l #l +* $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. /& %l &l *l #- Mc ;e =l -l ;l 4g Ug >l ,l 'l )l !l ~l {l ]l ^l /l (l _l :l !. !. !. !. !. !. !. !. !. !. k+ 5 ) ! ! ! ! ! ! ! < c n@ !. M^ g* dl e. el R0 !| ]< :< N_ }< k} D> D> [< m] k} k} O~ m] N_ q^ ^2 }: D> ;] N~ -4 K_ q} a[ Q< J< 22 E, J< R_ [{ U] W^ .5 y> fl m} |2 8g 38 gl 8~ [{ J! A{ |: 7[ K[ <: [2 a[ ^! l| z> p] W^ }< (1 (1 yb hl !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: X3 #^ il bb H2 bb jl y1 T: T: T: T: T: T: U} 7^ 8} @} kl ll ml nl ol 05 x| E7 @} pl Y3 ql rl sl tl ul vl L8 K8 wl xl c4 yl zl Al Bl I7 Cl Dl r+ $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. /& El Fl ! $- ed ;e Fe 3f lh Cg Gl Hl Il Jl Kl Ll Ml Nl Ol Pl Ql Rl Sl Tl Ul Ul Ul Ul Ul Ul Vl Vl Wl Xl Yl Zl `l m .m +m _j @m #m Kj [h Bg Pf yf ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ P. w! !. !. !. !. j@ x. 9 { : g Y( !. !. !. !. !. !. ;| q# : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { W )) !. !. !. !. !. !. M! u! '. : _ ! ! ! ! _ : m b, ]) y# l@ %+ !. !. !. !. !. !. S@ 8. { : ! ! ! ! ! ! _ { <. *( k) $m %m U. s4 m1 44 &m :< N_ }< k} t} t} N< i| k} k} k} i| O~ (< A> Q[ T] q^ N~ ^! 1c 3= *m !6 =m [- Re U< r} U< (< ]2 << y> A, << q^ Cb e_ -m ./ ;m j3 F> 6[ 44 >m Sc ,m >6 64 z> q} N_ D> T| Q~ z5 Z4 [2 b~ !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: X3 (6 'm )m !m jg ~m {m ]m A0 E} T: T: T: T: T: T: X3 l[ ^m 58 qc Ya /m 29 (m _m :m K< !( Cm !. !. !. !. 2= k3 A{ U] =] B> o7 (< Y] W^ J! |: Dm !. !. !. !. !. C{ b[ Em !. !. Fm ,] 9~ T7 a[ ]2 9~ w' q} Q~ N_ m| S7 3: !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: (6 Gm Hm K2 Kc Im =2 n< H} Ad /9 j[ T: T: T: T: T: O4 Jm Km Lm Mm #g Nm Om 82 Pm $< e5 o3 o3 Qm Rm Sm ^k Tm T: T: T: il Um C7 m/ Vm S3 Wm Xm Ym N* Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. *= 7' Zm t_ `m '9 Fe yf 5g 3g Gi n =k .n +n @n #n $n hm %n &n *n =n -n ;n >n ,n ,n ,n ,n >n >n 'n )n !n ~n {n xk ]n ^n /n (n li =k Ei Tg Cg 5g Pf Fe Mc Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 5 [* <' !. !. !. !. ]) z. : _ ! ) S 8] !. !. !. !. ~. x. b : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { V u! !. !. !. !. !. !. /@ ;+ ,% p : ! ! ! ! ! ! ! < ] < { : 6 h m ,> M! !. !. !. =+ k _ < ! ! ! ! : : J@ l* _n :n D, S1 w> Q~ O~ k} e| O~ k} N_ N_ O~ |n N[ Q} 1n !. !. !. !. !. !. 2n I3 }2 l] W^ o1 w{ B> 0~ [{ /2 :< H/ !. !. !. !. !. !. !. !. !. !. 3n 4n 'k }{ k} R_ (< l] r] N~ D> S_ 5n $+ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: 81 if 6n 7n 8n 9n 0n an z8 @8 5i e2 /9 T: T: T: T: T: t7 bn _* 61 ]d cn uh dn 5e en h2 xc G2 fn c3 gn hn '8 ug T: T: T: T: x| in jn kn ln +j mn nn c& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. *= - on pn e Ph 'g lh qn Kj rn sn tn un vn wn xn yn zn An Bn Cn Dn En ,n Fn Fn Fn Fn ,n ,n >n >n om Gn ~n Hn In Jn Kn Ln Hk Mn Nn hi qn lh Pf Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ S U@ q. !. !. !. !. z# t : _ ! < c !{ !. !. !. !. k@ Q. _ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { 3 i( h+ !. !. !. !. !. }* u 8 ! ! ! ! ! ! ! ! ! ! _ _ _ : { < 8 W l+ w! !. !. q. b_ >+ 0 ^ { _ < < ) '. On M% A< 7' U. [n s{ p( e) ~} 54 S| B> }2 U] O| r8 N~ q^ B> N_ m] l} &4 O~ k| Q~ (1 a/ h+ !. !. !. !. !. !. R} s, 0~ [< L3 x2 W] << U] /1 Pn d) Qn Rn Sn Tn .^ r. !. !. !. !. !. md U] Pn k} N< P} N< 0~ :{ z> >] H! e; !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: jl Un _] og Vn Wn Xn 1a %j )5 c4 Yn kc ^5 T: T: T: T: v[ fe X[ t0 Zn `n o .o yj +o @o #o $o %o >8 sc &o $} X3 T: T: T: T: T: !7 @a *o =o -o ;o >o d& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. z& ~% ,o 'o )o 'g 4g !o ~o {o %i ]o ^o /o (o _o :o n nm Ul |l 5o ]n ^n .m +m 6o Th 7o Ug 3g Pf yf ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! P ]) !. !. !. !. M! X+ 7 : ! ! { d ]: !. !. !. !. s. a. ! : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : U Z{ !. !. !. !. !. i+ q# ^ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : p 0. {> S@ !. !. w! ,> 1 9 5 j | ( x !{ !. 8o ne f. !< `g p( Bm O| N_ P| D> q^ T| << q^ ^1 N~ &4 l; T6 ~} :{ 7[ :a B> A{ 9o !. !. !. !. !. !. !. !. 0o S1 |: R_ q^ ^1 ^< T1 R_ g9 }{ [^ l] x> r] ao bo co do !. !. !. !. eo B> T< O~ k} k} m] w' ^! 22 :: fo !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: jl go ho io jo w< 5( ko G( lo p_ mo F0 Z1 7^ T: T: T: X3 bb no oo %0 %3 po d4 qo ro so to uo E) vo C6 wo xo yo X3 T: T: T: T: 7^ zo Ao Ed Bo Co Do ~+ Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. z& n& Eo Fo Go 'g 3g Ho Rh /j 6o xi Io Jo Ko Lo Mo No Oo Po Qo Ro So To To To To To To Uo Vo Wo Dn 'n Gn Xo Yo Zo `o p wi _j =k ii Gi 3g Ii yf .p ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : g <. w! !. !. !. !. 1/ a. { _ ! ! < 3 %= !. !. !. !. `) 6+ _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : { b. b_ !. !. !. !. r. _~ ! : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < _ o 0. z# T@ z# b, b, K@ L u. u. L r }* !. )& !~ +p !< c_ p( Bb I! Q~ P| N_ z> Q_ p} q^ O~ D> k} t} r} T] I! N~ W^ W2 |: V< !. !. !. !. !. !. u2 I/ @p l} 1: #p T| [< w' r^ k| p] ]2 D> e| }{ z{ 1: U6 m] G< J> !. !. !. {6 $p x> |: kj k} }{ k} Q~ g_ %p &p !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: 05 &2 y[ *p =p z_ x_ x_ 3( +j -p #< Ed ;p N4 T: T: T: T: 7^ >p ,p 'p )p rc W: 0b !p ~p {p ]p 1( Y' ^p vc /p b1 (p E7 T: T: T: X3 &5 _p :p

n )n Vl hp ip `j jp kp lp mp #m Tg Cg 5g 3f Am ;e ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : e a@ s. !. !. !. r. N^ m : ! ! ! { 5 <# q. !. !. !. )^ R. : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ! P. &+ S+ S@ !. !. ^) 4 ^ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ] ( j Y# m+ b_ S+ j+ 6+ <# !. {> -+ H, !. np op L@ 5~ pp v, B, l} ~| P| ;] N[ d| Q_ p7 k} Q~ m] (< E, 0~ i] z> D> V2 22 qp c~ !. !. !. !. !. 3^ u, 0[ z> R_ |8 Q~ R_ Q~ w' N[ B> N~ E, rp 6[ W2 J< >6 9~ m| T} sp !. !. !. tp up vp wp 9~ B> 1: 5< T< r] H/ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: 05 xp yp zp #a Z: x_ x_ :_ Ap Bp .: Cp 7a k[ T: T: T: T: T: f< C4 Dp 71 Ep Fp Gp Hp Ip c3 Vb Jp Kp Lp Mp Np *2 Op Pp A0 X3 V[ Qp D} Rp Sp Tp Up Vp s+ Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. S. /* Y. Wp Xp Ge 3f 5g [h Tg fh Yp Zp `p q .q +q @q #q )n $q %q &q *q =q -q -q -q -q -q -q ;q >q ,q 'q ,n om )q |l xk !q ~q Ln {q (j rn Kj [h lh 3f Fe ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : x $= %+ !. !. !. <' X+ ~ : ! ! ! : { @& `) !. !. !. /~ K { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < 7 N Z( I@ ;| !. ^. I 6 { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { ! Z U+ !. r. !{ l+ i+ x! v! !. !. 0$ _& L@ [n /- !| ]< w' ]2 P| }< O_ Q_ z4 }< k} }< R_ }< (< z> k] u4 E, C> z4 a[ <3 !. !. !. !. !. q. ]q Q~ ;] k} 9~ m] D> z4 N_ w> :< W^ A> l; z> N_ W0 w{ r] O~ g_ K_ $p 3{ ]k !. !. Yf b/ U] l7 A: x{ U6 w4 $5 !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: h5 Y9 ;5 ^q /q }_ Va x_ G( (q *h _q :q @} T: T: T: T: T: T: T: X3 E7 y1 $d (4 05 91 *f q qq 'q ,n 'n Gn rq sq tq uq vq yi bl Nn ~o wq Bg Pf Fe ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 6 D< ~. !. !. !. ~2 O _ _ ! ! ! ! ) y =+ !. !. !. z/ f+ : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < d V p [# !. r> b_ _@ y ( : ! ! ! ! ! ! ! ! ~ _ { : : ! ! ! ! ! _ < _ 6+ -( !. !. h+ >( 6+ _@ !. !. _' %6 L@ '( ~< $] F3 xq Y] t} D> l] L[ T1 O~ k} i| k} k} N< 64 s} :< *_ E, t} |{ m; d; !. !. !. !. !. lj .5 M< O~ 9~ T| 9g J! t} Q_ << << T| (< yq B> U] q^ >4 zq q^ (1 T< T9 Aq Bq p, !. Cq Dq M_ =m p, Eq g) Y^ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: Fq Gq Hq Iq y6 Jq D( v= k< Kq Lq yh $} 7^ T: T: T: T: T: T: T: T: T: T: T: T: j[ X3 81 $} Mq Nq t< Oq Pq G} Qq Rq F^ Sq Tq Uq s< Vq Wq t6 Xq Yq Dl r+ $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. S. %( Zq @] `q r e Fe 'g lh wq |h Nn bl .r jq ~q ]n +r rq !n 'n @r #r $r %r pq -q -q -q -q -q -q pq >q qq 'q Fn 'n !n &r *r um uq .m yi %i {o ~o wq Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : e J@ ^@ !. ~. /@ w. q { ! ! : : ! { 9 _. r> !. !. r> += d : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : _ { b. s. !. !. b; Z{ 5+ ~ _ ! ! ! ! ! ~ ~ ~ c 5 _ : { _ ! ! ! ! ! : < L j( S@ !. `) _. ){ !. !. }= ha `* =r `g 8g e) -r ;r N~ B> T| (| La z> R_ N< k} k} ;] Q_ U< k} W^ Q< K< R_ R9 o1 >r _2 T~ !. !. ,r 'r ;] (1 O~ N_ ~} v{ Q_ Q_ z4 m] r^ Z] K< N~ z> Q< 0~ r} Z] l} U] t} Na q^ F: Yf !. !. :^ )r !. X1 #/ X| !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: @} !r >h -5 ~r {r ]r =8 ^r /r J2 (r |1 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: S: 05 _r :r q ,q 'q Fn 'n nm &r Yo Zo .k gr hr Ik ir gj wq Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : u l+ /. [# Q. u ~ _ _ ~ 6 x _ : _ P. `) !. !. h+ g^ b { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < W A/ !. !. !. !. 6] I < _ ! ! ! ! ~ ~ _ o+ v. <# 9. p ) _ ! ! ! ! ! _ ] d a. (. i+ !. q. !. h+ K$ ne f. ^{ 6~ u, g) r] N~ N_ 54 0~ p7 x2 x> ^< << a[ n] =] l| N[ q^ z> ^2 jr w' z> m| S| s^ ,m .^ !. !. kr ]1 w1 22 E: V2 0~ V] o1 T] ~| W0 :< -] U] }{ B> B> [< N_ J! ^! [2 =] T< g9 p1 M$ !. K/ Gb t] lr mr !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: il E8 nr 7n Y0 or pr >2 qr rr E^ sr tr T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: U} @} !7 G} R4 e8 ur vr ;c wr xr yr zr Ar Br Cr U} Dr Er -* 7r 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. U. F$ Fr Gr Hr r ;e Fe 'g lh Vg |h {o %i yi gr ^n um *r &r nm 'n ,n cr Ir Jr Kr -q -q -q -q -q -q pq >q ,q 'q Fn 'n nm Vl Yo Zo .k 9j hr Ik Th gj Vg Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ a V p ! { _ ! { 5 0. $= o { < o l+ b; !. q. m+ c { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : e [* j@ !. !. !. M! ,> _ : ! ! ! ! ! ! < 7+ T+ !. {. 1' T : ! ! ! ! ! ! _ ( 1 _@ '{ X( %+ !. .; J% Jk U. Lr Mr u, <] w{ (< k} T7 E, w' p7 m] N_ L3 W0 V2 N~ :< }2 0~ q^ U< (< J< q} ^1 z{ R9 Z4 Nr !. !. !. c; Or z> B> ^< T] << U] O| A, w{ p] T] i] g_ z{ 1: e| N< d| k| 9[ X] w' O~ _} P9 +/ !. !. Y1 `] U1 !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: &9 Pr kf Qr Pb Rr Sr ![ Tr Ur Vr Wr |3 7^ T: T: T: T: T: T: T: T: T: E7 k[ X3 T: T: T: E} D9 d: Xr dc Yr !h Zr `r s .s +s @s ng #s $s %s +@ 7r 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. f. }, &s -( l0 r ;e Fe 'g lh Vg gj ir %i *s gr ^n um *r &r nm 'n ,n =s -s ;s >s -q -q -q -q -q -q pq >q ,q 'q Fn 'n nm Vl Yo Zo .k 9j ,s Ik /j zm Ug Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { { { : ! ! _ : S U@ T@ a@ : : < j =+ r> '{ q# 7 _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 7 _~ S+ !. !. !. S@ >+ _ : ! ! ! ! ! ! { w !{ !. !. !. !{ 4 < ! ! ! ! ! _ ) . }~ [. W V+ !. .; 's )s f. !s ~s M_ v, q} B> }< T7 ]2 x> v{ O~ O~ O~ 9~ k} (< E, }< }< N< 9~ O~ N< N~ q^ R_ O~ H: i9 {s !. !. !. E{ j3 l; 6[ U] U] J< *] Y] :< <1 *] r' ]s ]9 [< e| t} t1 l] W0 << ^2 w' }{ [< E/ p, !. !. q; 6= !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: E} t7 Pr ^s /s (s _s :s q ,q 'q Fn 'n nm Vl Yo Zo .k 9j ,s Ik /j zm Ug Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : g $= @= !. -| z < : ~ g+ G~ Y 6 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : _ [. l@ !. !. !. r> !) { : ! ! ! ! ! ! _ ) 5+ %+ !. !. x! U ] ! ! ! ! ! ! _ x 0 _ ] :. gs k) l( }% `* hs is s, d) M~ L< t^ D> J! T| r^ N_ }< }< k} 9~ W2 N~ k} k} k} k} k} [3 N_ t} }< n] R_ kj js q. !. !. !. y2 d) V2 0~ ;] l6 9[ ks (< s} (< B{ 3: Wf v2 u4 1: 0~ }2 _} U] B> z> U< A{ _| I< Y^ $+ !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: N4 j4 ls ms ,e ns os ps qs c3 _* rs t7 T: T: T: T: T: T: mj ss ts us vs ws {5 N4 T: T: T: T: (4 4e xs wo #f ys zs As $< Bs Cs Ds 35 q+ $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. h. 6$ Es !. Fs Gs re Fe 'g lh Vg |h {o %i yi gr ^n um *r &r nm 'n En #r Hs Is fr -q -q -q -q -q -q pq >q ,q 'q Fn 'n nm Vl Yo Zo .k 9j hr Ik Th gj Vg Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { x p@ 9] !. z/ 7+ : _ _ : e ~ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : w [* ^@ !. !. !. b, 6 ( _ ! ! ! ! ! ! < w Z( <' !. i+ =( } { ! ! ! ! ! ! _ < < x I@ M! >) Js Oe U. n, 6~ !| z: S1 s} (< }< A> K< Ks O| w{ 0~ N~ Q~ N[ }2 T7 k} k} k} m] P[ J! x> B> E, 0~ 'k H! Ls !. !. !. !. ]} << E, m6 a[ Q< (< }2 E, Re Ms K/ !. ]k 8 i; >4 ;] M< :{ Q< << (< P} 9~ o] x{ Ns U~ !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: w} Fq Os Ps W} =o Qs Rs Ss Ts Q3 Us _4 8} T: T: T: T: X3 Vs Ws 0b Xs 6} wo qg Ys v[ T: T: T: T: #^ Zs `s t .t +t @t #t ]r $t %t &t N* Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. f. *t ~- !. /. =t -t Fe 'g lh wq |h {o ar yi vq ^n um *r &r Gn 'n cr ;t >t ,t =q -q -q -q -q -q -q pq >q ,q 'q Fn 'n nm &r Yo Zo .k gr hr Ik ir gj wq Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ~ Y# P^ !. 9, Q _ _ ! _ : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) | ,{ S@ !. !. k@ Y# 7 ) _ ! ! ! ! ! ! { } p@ k@ !. >| j ( ! ! ! ! ! ! ! : : }# ~2 !. H| I% '% U. a| I[ s, v} ,6 a[ 54 }< =] }2 q^ T1 l; E, A> Q~ >6 x> E: k} k} k} B> x> T1 A, :{ N_ N~ g_ f) Yf !. !. !. !. J/ M~ O~ g9 ~| q} Q_ x2 A, R_ e| 5^ !. !. !. 't x{ Q~ D> (< ^! -] <1 :} k} e| D> k} k] )t !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: N4 !t ~t {t ]t k< B( ^t /t (t !i K8 T: T: T: T: E} t7 J4 n< *: ;7 _t :t q qq 'q Fn 'n !n &r *r um uq vq yi %i {o ~o wq Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < K x! !. ]. f+ : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < | [* {. !. !. `) [~ R e : ! ! ! ! ! ! ( p ]: !. _# M ] ! ! ! ! ! ! _ ] 1 !{ !. !. bt P2 ct U. F< o( $] ]< f) :< ^e Q_ q^ S1 :< O~ 9~ O~ O~ O~ (< r^ p7 }{ k} O~ R_ a[ T6 B> .5 }2 z4 22 *] dt !. !. !. !. f; ,6 9~ O~ T7 U< h| W^ _< 0~ T< s1 et !. !. c~ }1 *] |2 O~ Q~ z> Pi :< R_ P} Q~ S| ft u, Kb !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: y1 gt ht #2 it D( jt kt lt pg Ys K8 T: T: T: T: T: mt V: J2 nt ot Fq Y0 23 pt 9} T: T: T: T: T: 81 qt rt st tt ut vt wt xt yt ~+ Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. f. H$ L6 h+ V@ zt At Fe Pf lh [h >i fh &i Bt Ln Ct Dt lq |l Gn om ;n Et Ft Gt pq -q -q -q -q -q -q ;q >q Ht 'q ,n 'n Gn It sq kq uq .m Jt bl Nn |h -k Bg Pf Fe ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) V u. !. t. . { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ] } _. M! !. !. $+ 6] f+ ^ _ ! ! ! ! ! _ ) J _. I+ 9 : ! _ ! ! _ < { u ,{ ^@ !. !. x# Kt 7' U. [n Lt 44 S6 Mt kd (< B> z> Q_ N~ k} k} k} k} [< Q~ ^! [} h| ;] t} O~ =] w' O~ l; r^ Q_ s} U6 p^ J3 !. !. !. fo j; Nt |: O~ O~ g9 t^ :< T1 N_ u} =6 Z6 !. !. Ot Pt A{ 0[ l; D> Q} [< N_ D, Q_ z> A{ L~ V_ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 7^ zo Qt 3a Rt Xn c! St Tt Ut (r P4 T: T: T: T: T: 7^ a7 Vt Wt Xt Yt Zt kn `t u V[ T: T: T: T: T: :| .u +u @u 5a }s #u $u %u c& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. U. &u *u !. {: =u dk -e 3f 5g Cg Tg -u ;u >u ,u 'u .q ip 1l Ul om En )u !u ~u {u -q -q -q -q -q -q ;q >q ]u ^u En )n )q |l xk !q ~q Ln {q (j rn Kj [h lh 3f Fe ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { L '{ !. (@ K { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) 2 )) h+ !. !. !. 7] M ^ ! ! ! ! ! ! ! : 7 : ( ) ] ] ) ( 8 ~ Z %= 6] x! i+ !. .; /u {2 U. [n Mr (u T_ w' N_ _u T7 E> B> O~ k} k} k} k} D> N_ Pi r^ :< J< 0~ |8 V] f) q^ ]2 T| >6 (| z> T< :u S} !. !. !. t8 [- N~ }< K< l} N~ A, ~} }2 t} n mu nu ou pu qu qu qu qu qu qu ru su tu uu -n vu wu 2l In `j xu kp lp yu #m Tg Cg 5g 3f ;e ;e ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : w $= ;| !. 7] j { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ( L ]. !. !. !. !. n@ 3 ] ! ! ! ! ! < c @& 8. k 2 . Z r Q 9. O^ t. r> >( _. {> !. !. f' !~ U. n( p2 $] zu 1{ U< j| }< :< l; O~ k} k} k} k} k} k} X6 q^ ;] M< r} U< a[ :{ T] z> J< u1 N[ z> 1: g_ O9 Au !. !. !. p, Bu *] q^ l] T] *] v{ w> l] (1 Z4 ]e o} Cu r2 w1 B> 0~ U< << {| U< N~ E, 0~ B5 !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E} W3 Du ^q }q Eu Fu Gu _s Pb Hu Iu U9 X3 T: T: T: j[ &9 p| Ju c3 Ku Lu Mu Nu 91 j[ T: T: T: T: j[ Ou Pu Qu Sa t[ Ru Su K6 c& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. )< Tu h1 !. !. !. Uu Vu Hj Wu Xu Yu Rh Zu Ik xi gr `u um *r rq Gn om >n v .v +v @v @v @v @v @v @v #v $v %v &v *v =v -v ;v >v ,v 'v wi _j =k ii Gi 3g Ii yf .p ed ! : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { w _. M! !. a_ M { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < x j( !. !. !. !. b; [# e { ! ! _ { ^ [. z/ j@ >| m@ b_ &+ 8] s. S@ ~. !. !. $+ v! (@ !. !. L$ )v f. 5/ _3 @5 n; !v l; ;] D> :< Q_ 1: O~ k} k} k} k} k} w' [{ 1: O~ O~ g9 E, y> n] ;] Q~ z> ^! l} J< N_ A{ U0 <' !. !. !. o} ~v Pc ;] {v 9[ d| ^e M3 Q_ z5 r} F: ]v V] g_ N_ x> L3 o] v1 Z4 W^ _< A: K/ !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: :| cb 13 og ^v /v e7 (v _v ;8 %[ :v 7} E} T: T: T: X3 u[ f) x> B> l} 0[ r} N_ O~ 9~ O~ O~ 9~ W] U] 9~ k} k} O~ C> }: E, g9 k} k} M[ 9[ p} U] E, A{ j3 !. !. !. !. ,r M_ T< Q~ Q~ ;] R_ C> |2 l} m] [< q^ <2 Pc T7 z> W0 U6 N_ G3 zv ./ Av o^ T~ !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 1s Bv Cv vj #2 Dv Ev .[ D2 Fv Gv x8 &9 T: T: T: T: 8} a7 Hv .f Iv Jv Ys Kv Lv e< /9 9} Mv Nv Ov Pv Qv fb +j Rv Sv K6 d& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. n& P] Tv Uv Vv 1/ {( !. !. !. Wv Xv Yv Zv `v w .w +w @w `o zk #w rq $w %w &w *w =w -w -w -w -w -w -w -w ov Po ;w >w ,w 'w )w !w ~w {w ]w ^w Nn /w (w _w :w Fe ;e '9 [{ y> l} _< -] U] Q_ q^ [< :< c| O~ 9~ O~ O~ e| _} N~ 9~ k} k} }{ }< x2 w' *] t} 9g Ka !. !. !. !. c; s' z4 1: R_ ^1 N_ g9 R_ }2 |w 5: 27 1w :^ Or cg 2w ]- -_ X1 !. 3w ]} up h+ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E7 a3 4w |t sg 5w `[ 6w 7w c7 8w ![ D9 T: T: T: @^ %2 Bv 9w 0w aw 8 gw hw iw jw kw I6 lw mw nw @* $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. S. z& ow J3 {: i+ {. !. +/ pw N$ qw rw sw tw uw vw ww xw yw Dt ip Hn rq zw Aw Bw lv nv nv nv nv nv nv nv Po Cw Dw Ew Fw Gw Hw Iw Jw Kw Lw Mw Nw Ow Pw Qw Rw Sw ed < i Z{ @= l+ 1 9 } ~ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 7 Q. v! r. !. #= W < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! g+ g^ ]. h+ !. !. !. }~ r C< 1/ r. ^@ <' !. !. !. !. !. S@ ]. 7] ^) <# #= s. !. !. !. !. !. e' ha f. Tw Uw !| %p T] =] v4 }2 W^ :< W^ :} }2 U] :< p} 9[ i] r^ W^ W^ 0~ Q~ 1: S1 p} m6 O~ k} k} O~ T1 ^2 L3 S| _| Ia !. !. !. !. !. Vw Ww U7 e| *] J< g_ H3 Xw Ls !. =& Yw h+ h+ =& !. !. !. !. !. !. c; 't e_ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E7 $1 Hq C2 Zw X/ `w x g8 .x vt +x 8} T: T: @[ '[ @x #x v7 $x %x W: &x *x vc `| @< =x -x ;x >x ,x 'x )x !x ~x {x 7r 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. S. 4$ ]x >) !. -( @& Y( ^x /x (x 6% _x :x w cx dx ex fx gx fm hx ix jx kx lx mx Qh nx ox px se Q_ T1 M< 9~ k} E: S| 0~ D, ^! S1 r^ _< Q[ q^ ^< Pt N[ (< k} O~ sx Q~ r^ s} 1: Si T} T~ !. !. !. !. !. tx N~ A{ ux 22 54 T] vx !. !. !. !. !. !. !. !. !. !. !. !. !. !. c, M$ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 05 3m wx xx L( $7 s3 ab yx sc zx a3 E7 il qf Ax Qu e5 >8 Bx Cx Dx Ex Fx Gx Hx Ix Jx Kx Lx )3 Mx Nx Ox Px Qx -* 7r 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. T. 4$ 2% M% !. g^ _ d Rx Sx !. %$ o* Tx Ux Vx Wx Xx Yx Zx wm `o ]n `x y .y +y Ew @y #y #y #y #y #y An ,w $y %y &y *y =y -y ;y >y ,y 'y )y !y ~y {y ]y ^y /y 9d h ^) ~. {. >( ~2 -+ I+ h : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 3 4+ 1/ !. i+ n+ e : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ) e g+ W+ b; !. 1/ Z) ){ s. v! P^ !. b; =+ P 2 ^ ) ) ] { { _ p K@ >| u: k) J% Jk U. (y 0f #_ 5[ v4 ~| }< k} k} l; *] k} k} k} k} O~ (< << a[ U< (< E, ^e T| z> 1{ K_ r^ -] p7 6[ [< :< :< R_ U7 }2 _y q. !. !. !. !. y2 G! J< :y 95 X2 t8 P! !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: ~5 U< S| D> z> _a s} Or Sn c~ !. !. !. ~( a/ }1 .^ .; Y1 h+ !. !. !. !. !. U~ tx Qy Ry G: Sy 3n !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: @[ Ty Uy e5 $b Vy Wy D( Xy Yy {7 }9 Zy Tr }q X5 `y z H( ko `w z} c1 .z +z @z #z 7( $z %z 67 &z x_ *z =z -z r+ $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. S. e. ;z H] !. 1' b w { >z ,z 'z d$ )z !z ~z {z ]z ^z /z xi jq xu uq (z _z :z k] .A O~ k} k} i| [< w2 +A O~ k} k} O~ p7 T] R_ k} R_ M< k] :{ 6< N_ <} l6 @A 1< !. t] <3 #A $+ -m e_ !. !. $A :: U< Re k| l] z> 9[ Pi H: e| %A U~ !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: Y2 &A *A D0 2} =A -A ;A >A ,A ul l 'A )A !A ~A :_ {A ]A ^A /A J2 (A _A :A ( I+ j+ !. !. r. Z) } : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { { C< b; !. !. !. !. r. ,{ p < ! ! ! ! ! ! ! ! ! ] k >| !. H| vA Z- U. !s a~ B{ j} O| P[ P| O~ }< 9[ :< R_ k} k} O~ }{ V2 ^! wA O~ k} k} k} 1: w' S1 }< k} k} k} q^ E, k} k} O~ O~ O~ N_ y> m; :{ f_ B> xA !. !. !. yA !. !. !. !. h+ zA >] 22 k} M< y> V] D, q} q^ |: AA R~ BA !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E7 Y| Gq {d CA qj sg DA EA [| FA GA r6 HA IA C| JA .t KA Vi LA .g mg (6 MA !r NA L0 <4 qs OA PA QA N* Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. T. 4$ RA SA I+ 4+ 5 ) ! Mc re Je TA UA 7% VA 7A WA XA YA ZA `A B .B +B @B #B $B %B %B %B %B %B &B *B =B -B ;B >B ,B 'B )B 0= !B ~B {B ]B ^B /B (B Mc _ ! { ] ). Y# F[ x. 5 < ! ! ! ! { ). n{ V+ [* K@ += I@ b. 4 : ! ! ! ! _ { ). ^) !. q. ;( $= T@ !. !. w. 4 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { 4 Z) S+ !. !. !. !. ){ j { _ ! ! ! ! ! ! ! ! _ ) }. l@ !. x# :n 7' U. F< _B :B t' zu x2 k} }{ t} 9[ i] P| O~ 04 |2 M< h| [2 0~ }{ O~ k} k} 9~ U] x2 t} i| k} k} Q_ L3 T7 }< ;] R_ 9~ O~ k} {| s^ }: AA I< 3n !. !. !. !. !. !. !. 2= _{ Z4 9~ C> N~ 0~ :< q^ [< P} q^ 4< T] et !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E7 ee ( >+ } : ! ! ! ! : } _. r> !. {. N^ )^ !. !. [# d { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { v <# T@ q. !. !. !. U+ q# _ : ! ! ! ! ! ! ! ! ! _ ) S ;| !. x# GB 7' U. [n p2 d) X] [2 X8 w' 1: 1: l; }2 O~ O~ N_ S1 r] T1 *_ 5[ y> /1 O~ k} 1: p7 i] m] i| k} k} Q_ E, O~ S| k] T] 9~ e| R_ Q~ _} s} f_ N~ HB !. !. !. !. !. !. r. :b M< Re k} Q~ [{ p7 ~} 8~ E, }{ (< z> p' IB !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: ^5 x] JB KB LB t| @3 MB <_ r3 NB G1 m/ OB (p E7 T: T: T: T: T: w} n9 PB QB +6 RB SB TB d& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. f. UB VB WB XB I| W { _ '9 '9 C ,C 'C ii )C !C ~C {C ]C d$ !. ^C /C (C _C `m ! : 4 >+ ~2 !. !. !. #= b ) ! ! ! : ) P {. !. !. !. !. !. !. a_ t { _ ! ! ! : x O^ M! !. !. !. !. !. !. w. 5 < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ) { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { ) G+ q. !. !. !. !. )^ a. x : ! ! ! ! ! ! ! ! ! ! _ ) R. w! !. v: :C z& U. [n p2 #_ u4 }2 1{ K_ r] ]2 V2 U] N_ z{ N< T1 }2 [{ a[ p7 O~ }< [^ -4 E: t} W0 J< M3 W^ 9~ g_ =4 =& !. !. !. !. !. R} !| n] p] m] B> N~ X6 [^ ^! q} =] o] W2 / !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: Ou [C ec v_ }C MB x_ I( 02 |C 16 l4 c: N4 T: T: T: T: T: T: j[ |} 1C (s Qm E} 2C cu ~+ Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. f. E% 3C 4C 5C Z( ` ] 2 6C ! fd ed 7C 8C 9C 0C AB d$ aC bC O$ cC dC eC fC gC Kg Kg Kg Kg gC Vx hC iC jC }h Ug kC lC mC nC oC !. pC qC -t ed :c : 2 ,{ ~. !. !. !. !. &+ R. 8 ! ! _ { 8 p u. !. !. !. !. !. !. -( J { _ ! ! ! _ ! P. i+ !. !. !. !. !. !. U+ [. ~ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ g ). r 9 < : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { : 6 o@ !. !. !. !. S+ _. 9 { ! ! ! ! ! ! ! ! ! ! ! _ ] '. 9, !. 9$ ={ n& Z= [n p2 #_ T9 U] J! Q~ I! ^! C> 0~ *_ T| r} Q~ z> l} w{ >4 {| [2 U| 1: kj E, rC m] 9~ E: p] _< -] k} e| 1: k} M< =] B> ;] 0~ K[ W0 N_ U1 sC !. !. !. !. tC uC w' k] *_ << N_ k} R_ E, y> x> N[ o] l6 vC !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: /9 wC #f xC yC oz J( Y} zC AC |t BC &9 X3 T: T: T: T: T: T: T: 05 CC ec DC >2 EC FC ~+ Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. f. ne GC HC q 7 c < ). I@ k IC fd 6f JC KC LC MC NC N% OC VA PC QC RC [g SC SC SC SC SC SC Ux PC TC UC VC 4g 4g ;l WC XC YC ZC `C D .D ! _ _ 1 Z) 6] b; !. !. !. !. _@ ] f ^ : s [. 1 X( !. !. !. !. !. !. Z{ k < _ ! ! ! ! < V V+ r. !. !. !. $+ l@ ){ Q. 6 : ! < ) { : _ ! _ _ ! ! ! ! ! ! ! ! ! < w w. _# o@ q# { ) ! ! ! ! ! ! ! ! ! _ : _ ! ! ! ! ! ! ! ! ! ! ! : ! R O. X+ x! !. !. !. @= l+ n < ! ! ! ! ! ! ! ! ! ! ! ! : ] v X( !. +D -- n& Z= [n p2 d) @D :{ L3 ~| &4 N_ }< ;] z> r] y> =] }< q^ l; i] T| Q_ K_ N~ 9~ E, }2 R_ 9~ r} &4 1{ <^ T] (< l; Q~ B> Z] Q~ O~ R_ k| [^ #D Cu !. !. !. g~ $D %D :{ L3 Pi *] 9[ B> O~ k} k} J< z> M< f_ *_ &D !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: ~5 *D =D 3v +d -D jt &8 ;D >D .t ,D 'D 8} T: T: T: T: T: T: T: T: 05 )D !D ~D e7 {D ]D d& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. S. -- ^D /D (D 8 _ _ 7 R }. : `m `m -t IC JC Ee _D :D d$ _x )z 6 R_ N~ w> B> e| (< B> i] =] q^ 2c p7 W^ u4 W^ t} A> K< (< Z] p} Q~ x2 :< E: r] 4< }{ o] P~ Ww d~ !. !. !. !. o} 4D N~ |^ J< N_ D> k; K< j| k} {} ;] D> N_ A{ :: fo !. !. !. !. !. !] ~] H{ x) gf 5D K{ D9 X3 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: f< -3 6D sc 2b 7D 8D 9D 0D aD bD lt cD D9 T: T: T: T: T: T: T: T: T: 05 -[ dD pr Wa 6v =* d& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. n& eD fD gD < _ ! _ _ e ! _ Gs Lc hD iD jD qC kD 6% %$ lD mD nD Yz G[ E$ !% *= !% =r R0 M_ ;0 _< o1 q^ -] 9= _: U] x> << P| Z] f) L3 W2 k} s} l] Y] q^ T1 d| p7 |7 y{ V] *_ ;] p] W] l; J< V] R_ R_ k} [< N~ m] >0 j@ !. !. !. !. G, Q< u} r} d| k} R_ i] *] }{ P} W] N~ p] << 9~ q} 2- !. !. !. !. !. !] ~] H{ x) wD xD yD zD C^ Zi S: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: S: A0 Q: AD +: BD 9 E( *[ CD DD Pb ED FD t7 X3 T: T: T: T: T: T: T: T: T: 05 N^ '. e ) { ! ! ! ! ! ! ! ! ! ! ! ! ! < q V@ !. !. h} WD U. e. z& e. F< <- R~ !v [^ W^ E, -] XD i) #/ ]v YD ]2 T6 q} q} 0[ D> [< l] k] O| W^ 9~ k} *] L< E> u4 x> 0~ q^ :< N~ k} 9~ |: B> ZD *m t2 F/ !. !. !. Kb 84 S] }< 9~ E, E, T7 ,k T] X] N~ (< w' T] k| V2 w1 -] R} !. !. !. !. !. !] ~] H{ `D E .E +E @E #E $E /4 V[ T: T: T: T: T: T: T: T: S: 8} f< T: T: T: T: T: T: T: T: T: T: T: @[ B^ l9 %E &E *E =E -E ;E Xn .9 {i >E ,E xj zd T: T: T: T: T: T: T: T: T: E} 'E )E !E ~E {E ]E c& !+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. U. ^E /E (E _E f : ! ! ! ! _ ! P G~ b ) IC :E ( (# k+ O 9 { ! ! ! : g !) M! !. !. !. !. !. !. @= I@ o+ w. =( W { ! ! ! ] q O. ]: a_ )^ #= M : _ ! ! ! ! _ ] 5+ r> m@ o < < : ! ! < 4 l+ !. !. !. !. !. %+ l+ q < : _ ! ! ! ! ! ! ! ! ! ! ! ! ! _ ^ 0. @= !. >) D[ [; U. e. z& e. Q1 _B A: s' T| C> Re Li &p !. !. j@ 4E rC V2 N_ :< y> k} g9 N_ E, l3 @5 5E E, 0~ :< p7 E> z> 0[ Q~ E, (< /1 e| g_ 6E p0 !. !. !. q. c; Qn Or k] D> O~ R_ B> ]2 9~ O~ D> Z] :{ }2 l6 E, m] U< l] Qc 7E !. !. !. !. !. !] ~] H{ 8E 9E 0E aE C8 bE cE dE H1 v[ T: T: T: T: T: T: j[ eE zs _4 Y2 T: T: T: T: T: T: T: T: 1s ^5 d: fE gE s[ hE h2 iE c8 jE kE rj lE mE nE y1 T: T: T: T: T: T: T: T: T: X3 .| Ax oE +< pE SB qE T% q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. S. z& rE sE tE P b : ! ! ! : 9 V W 7 :c 8 u x& uE Ic vE wE !. g~ g~ g~ g~ g~ g~ !. !. xE yE zE b, r. !. !. p@ n Z( f+ : _ ! ! ! ! ! ! ! ! ] ). _# `) += z / ] y. S+ ~. }~ l : _ ! ( o _# !. !. r> 1/ /~ ){ V+ P^ !. !. !. !. !. 1/ Y# : _ : : : 8 2 Z{ !. !. !. !. !. !. q. l@ b_ h+ r. N ~ : ! ! ! { ] ~ 2 J t g _ ! ! ! ! ! < d x. r. !. k+ T b d ! ! { 6 2/ q. !. !. !. !. A/ v ^ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { / >+ ^@ AE BE CE e. e. e. z& Z= DE Uw v} Ww T] p7 (1 yb J3 !. !. !. q. EE YD [< 0~ w' }{ }< z> S| R_ Fb FE _{ C> J< W] D, R_ O~ N~ s} N~ GE d) t' q; !. !. !. Y1 y4 HE V] [< f_ U6 9~ N~ 0~ N< D> N~ q^ N_ E, z> l} S| R_ t' !6 {6 !. !. !. !. !. !. !] ~] IE JE KE LE ME NE OE PE QE ~[ H1 f< T: T: T: T: X3 y1 RE SE TE #1 ~5 T: T: T: T: T: T: v[ ]6 UE VE WE XE YE {m ZE Ax D8 `E F o< .F +F v[ T: T: T: T: T: T: T: T: T: T: t7 @F |9 #F $F %F &F *F s+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. f. [; 9$ h+ |/ ` ] _ { { { O -+ t ] _ : z. A/ 4+ k [ y. !. !. !. !. !. !. !. !. !. I - I 6] !. !. !. ;+ ). Z( H : _ ! ! ! ! ! ! ! ! ) o }~ $= e ^ 9 !) ~2 !. ,; | ^ ! ! ! ^ q ^. !. !. !. !. !. !. !. !. !. !. !. !. !. !. Z{ b ( e 7 ! ~ y A/ !. !. !. !. !. !. !. !. !. !. !. z# z ) ! ! ! ! : { < ] ) ! ! ! ! ! ! _ ! z. l@ !. !. l@ J@ Q. g+ : { ) < P (# !. !. !. q. j( c < ! ! ! ! ! ! ! ! ! ! ! ! ! { { < _ g+ ){ X( a, =F -F /* e. e. n& J+ ;F `g S] u4 W^ W^ M[ p] p1 y2 !. !. !. b; >F K< N_ s^ ^< 9~ T1 ,F 9~ 'F !. 2{ E, a[ 9[ w' ;] T7 *] i] V< p0 2= J> r> !. !. !. md y, A> -] ^! l; |2 ;] }2 o1 p7 p] Y] M[ N_ Q~ << t^ v1 W2 )F r( !. !. !. !. !. !. !. !] ~] IE Dr !F ~F {F @j ]F ^F /F (F _F 05 T: T: T: T: X3 W3 :F mo g2 ( R. g ) < ] & s y# !. !. !. !. !. !. !. !. !. !. !. !. !. !. 8> c 7 p# 2/ N O^ #= S@ !. !. !. !. !. !. !. !. !. !. $+ b, 2 < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) h :# !. !. r> p@ p W o : ! ~ V m+ P^ !. !. !. q. <# 4 < ! ! ! ! ! ! ! ! ! ! ! _ < x 7 9 O 6] S@ z# bF cF dF {% e. e. T. P] eF 6d c/ Ww :< >4 A> 9~ T7 fF nd gF hF &/ r2 T| E, w' l7 *] U< i| m| |< E{ 3^ n6 N< E, -] 0[ S| p] M< 2{ !. !. !. !. !. T~ 85 /< k} f9 T| r] :< *_ }2 Q~ [{ r^ s} M< Q~ 0~ ^1 N_ D> T< |7 0/ !. !. !. !. !. !. !. !. !] ~] H{ y) iF jF kF lF (v mF nF oF ]/ C^ X3 T: T: T: X3 d: 'd 4i pF #f Mq qF 8} T: T: k[ u s6 l/ rF sF tF uF v5 vF 1y XE wF ,E xF bb 8} T: T: T: T: T: T: T: T: T: T: j[ xj Ti yF zF 9} AF BF +@ s+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. U. =- CF DF EF 3 < $= += 9 } d _ _ < 8. }* a@ 7 { , >+ !. !. !. !. !. !. !. !. !. I & V 8> M! ]. :# ` < < _ ! ! ! ! _ ! ! ! ! ! : ~ 9. _. w ] 7 G~ M! !. !. 1/ p@ J a W }# m+ ,; m@ >( `) (@ 1' _~ ,{ {> r> !. !. !. !. !. %= ! s >| q. k@ 9] !. !. ;| ;| q. !. !. !. !. !. !. !. w! b. ! _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! : / L ]. !. !. h+ 2/ g f { M a@ C< 8> P^ !. !. !. !. $+ [~ } { ! ! ! ! ! ! ! ! ! _ { ^ h x. l+ }~ ^) 9] !. !. !. FF GF f. e. e. U. J+ 4] o2 js <: 55 Z] =] 0~ (< |{ z{ B> ^2 l; z5 [< z> }2 HF L[ B> }{ |{ od e_ !. 6: }1 w' B> N~ q^ T| U6 y: c~ !. !. !. !. 3n F: p7 U< X6 J< k} [< q^ p] ;] (< l] U] W^ w' N~ k} }{ 22 >] IF ^b JF 3{ !. !. !. !. !. !. c[ d[ A- KF x_ LF MF NF OF }A wo PF QF t7 T: T: T: T: y1 .g RF SF TF UF [y VF WF X3 T: v[ >7 XF YF X9 ZF =[ `F G .G O5 =D +G d2 @} X3 T: T: T: T: T: T: T: T: T: T: @G V[ #G fn $G %G &G *G =G c& !+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. T. !% Y* O= -G N^ '. G~ 8] s 8 { ! ! _ 0 h x ! ~ , >+ !. !. !. !. !. !. !. !. !. I = e R. 4+ . z ~ _ ! ! ! ! ! ! < { ! ! ! ! ! : w v x _ < 3 n{ %+ (@ /~ -+ ;( n{ Z{ k+ 9. '. b t o+ r 9 { g h `( U+ T@ M! !. i+ 7] K@ x. 9] !. !. !. r. N^ R. 5+ _# !. !. !. !. !. !. !. `) I ] _ ! ! ! ! ! ! ! ! ! ! ! ! ! ) 9 | }. 6] !. !. !. ]) G~ 0. ,> %= P^ j@ !. !. !. !. ~. 9, =+ [. g : ! ! ! ! ! ! ! ! : { ] T n@ ~. !. !. j@ h+ !. !. !. ;G <% f. e. e. U. J+ n2 !. et _{ p} C, S1 T] (< O~ O~ |: Z4 9~ D> N_ N_ N~ w' 0[ t} |: w2 lj !. !. V~ >G {! S| w1 g9 p] w1 /| p, !. !. !. !. 7= l7 Q_ :< q^ 7[ 9~ ,G -] N~ l; =] |8 Q_ Q_ ^2 U] O~ z4 J< 'G t2 J> t2 >r T~ !. !. !. !. !. )G Qa !G v) ~G z^ {G ]G ^G /G (G _G Yk 7^ T: T: T: T: x3 :G W} !. I| K [# L ] ! ! ! ~ { ) _ ! ! , n+ !. !. !. !. !. !. !. !. !. I f _ _ ~ { ) _ ! ! ! ! ! _ } J h ! ! ! ! ! _ ) ) ! ! _ < n [. u i W a [. w. Y _ ^ ) ] ] ] { _ { ) 7 v ` >+ i( o+ 6+ 4+ [~ (# !. !. !. b, h ] < 0. i+ !. !. !. !. !. j@ l+ o : ! ! ! ! ! ! ! ! ! ! ! ! ! : 4 _~ V+ X( T+ !. !. !. !. ^@ P^ j@ !. !. !. r. )^ {> =+ Z) 6+ m 9 ! ! ! ! ! ! ! ! _ { 6 b. Z( ^. !. !. !. $+ 9, T@ <' >( @/ cG *= S. e. e. U. J+ n2 !. f~ 8g r] >6 a[ ~} q^ e| =] N~ O~ (< ;] N~ w' (< y> s} |: D> )6 b; !. !. d; [2 u1 7[ Q~ p} 5[ 3c dG -m !. !. !. !. Ka A, D> x> T6 O~ P} t^ W^ T] W] T] Q_ 0~ z> N~ -] <^ eG )F d~ g~ !. 3n Ka -m !. !. !. !. !. )G fG gG hG {] u] w] Zi *3 bb /6 t7 7^ T: T: T: T: 81 Z2 iG *h jG kG ^_ lG mG nG +x 91 _m oG wc 2} pG s3 MB qG rG sG tG uG E} T: T: T: T: T: T: T: T: T: T: v[ C^ U9 _4 vG &} wG xG &^ yG zG J- C= q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. g. {2 {~ `) H+ ! 5 d _ ! ! ! ! ! g g ! _ & G~ !. !. !. !. !. !. !. !. !. I f ! _ _ _ ! ! ! ! ! ! ! ] q V+ Z) 7 { ! ! { : x ~ ! ! ! ! < ( < ) < ] { w : : ! ! ! _ ! ! ! ! ! { ) ] < g ) ] ~ 9 a. :# ;| ]) [. ] : ) | 8> !. !. !. !. !. P^ R. ( _ ! ! ! ! ! ! ! ! ! ! ! ! : 9 :~ <' !. !. !. !. !. !. !. !. !. !. !. >( (. Z) 7+ 1 W d < ) : ! ! ! ! ! ! ! ! { e J@ /@ !. !. r. b_ n@ D< R. Y 0. AG BG CG DG *= e. e. U. J+ (3 0, $5 T_ _< 6[ P| 0~ S1 Pi ^! v{ }{ O~ Q~ << z> D> m] ;] U7 [{ lj !. !. !. c; ]< U7 o1 zb u8 EG `^ Kb !. !. !. !. !. bB ^! R_ x> A> O~ B> 2c M[ q^ V2 ]2 ]2 M< m} FG GG Rc _2 FE g~ !. !. !. !. h+ !. !. !. !. !. )G fG gG x) {] u] +^ j[ T: X3 @[ X3 T: T: T: T: X3 HG IG KB >h 1i 1( G1 JG KG LG MG gg NG wc OG >D PG *8 /[ QG RG H6 72 h5 T: T: T: T: T: T: T: T: T: E7 .| ]5 A2 3} io ~/ hw SG TG UG VG WG XG C= q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. f. 9, !. !. M! ,> < { ! ! ! ! ! ! ! ! ! ! ! : ! [. 9, !. !. !. !. !. !. !. !. M! 1/ k+ [* }# } g ) < < { _ ! ! ! ! ! ! ! ! ! < q y. x! !. !. M! Y( s 5 g < 8 ^ ( K9 `G H =; e. e. U. J+ n^ .H `] w' =] ~| e| Q~ E, 4n ./ !. !. !. h+ &D +H 85 E{ !. !. !. !. !. $+ c~ Cu o^ 9o Q~ }{ z> Q_ T7 p] l} E, }< T7 f_ o] s^ @H bB !. !. !. q. !. !. !. !. !. !. !. !. !. !. !. c[ d[ A- x) {] u] +^ j[ T: T: T: T: T: T: T: 8} 7} #H $H N{ %H f3 ]r p3 .t &H *H =H -H ;H >H ,H 48 'H |_ ^F ]d K2 )H !H C4 T: T: T: T: T: T: T: @[ (4 'D ~H {H kn ]H {/ ^H +t /H (H _H :H O~ }{ [< :< |2 1: O~ Q~ m} (1 0~ 3H mr K/ !. !. r. &p 30 N3 (! 4H p0 h+ !. !. !. !. !. !. c[ dg H{ x) {] u] +^ j[ T: T: T: T: T: T: 81 ^k 5H Xi Iq ^A 6H 7H 8H 9H 0H Np 7| aH bH an +{ cH dH eH Tq fH [v [6 gH hH y1 T: T: T: T: T: T: y1 B^ iH jH Ui Q3 kH !4 !r lH mH pa nH oH pH qH d& !+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. U. )s J% rH h < ! ! ! ! ! ! ! ! _ 9 z. >( !. !. !. !. !. !. !. !. !. !. I f ! _ d 1 1 i ~ ) _ ! ! _ ( :. %+ :~ ! : < K U@ ,; Y ) _ ! ! ! ! ! $- $- #- sH } d tH != _ `m ! ! _ uH ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ! ~ o ). b. 4 ( ^ f u =+ !. j@ ^) H ! { ! _ _ ! _ { _ x 0 ~ < | Z( )^ $+ !. !. !. !. !. ,; l f ) : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : Y z/ 1/ P. i j ~ : ! ! ! ! ! _ ~= vH wH ~% e. e. T. 7' j* xH M_ ,6 y> p] ks l; }2 Q_ x> D, T| z> R_ O~ R_ N_ >0 !. !. !. !. !. !. !. !. !. !. !. ^} S~ $p %A .5 W2 z{ >] T< A{ 1: 9~ E, 0~ +5 I! Y] N_ E> k] 0~ yH y2 !. !. Z7 75 O[ I< U] T] l| T] 8g 7= !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: mj r5 zH d5 u3 AH BH CH 3( <_ 63 DH EH FH GH HH IH JH KH gw Nm QE Ur LH MH 2k NH T: T: T: T: T: T: %2 ,[ 29 ;5 ut i< OH PH QH RH xl -A SH TH UH VH WH H- q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. S. e. XH YH ZH ( _ ! ! ! ! ! ! : ~ 6+ U+ !. !. !. !. !. !. !. !. !. !. !. I ' : v G~ u. U@ j+ 4+ i : : ! ! ] z. s. {> | ) _ ~ ). M ~ _ ! ! ! ! ! `H I g g .I +I @I #I $I ! %I $- )= )= &I ,= != #- _ ! ! ! ! ! ! ! ! ! ! uH < $- H+ 9. 7 0 W o+ q 8 b. T+ !. !. y# y. ! 8 ) ) { } a. =( [* k+ `( L _ x j O. 1' ^) (# !. !. V+ 1 ] ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ g a. _~ 3 [ : c g ! ! ! ! ! ! : *I =I -I =; e. U. P] Q] Ha E5 ]< A, K[ *] S| E, << 0~ |2 p7 E, i| k} v1 J< vC !. !. !. !. !. !. !. k) ;I o^ >G p^ x2 S| (1 [3 J< p7 V] r} D> ^1 Pi l; K[ p7 t1 *_ U] m] K_ >I ,I !. !. !. 'I _< (1 |{ |{ g_ U6 |{ E, 1H !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: il )I A8 .l Dh !I %7 ~I x_ x_ 3( 1| {I ]I OB ^I /I g2 ^q Qm (I _I :I de Dp v[ E} T: T: T: T: T: f< {5 E 1I 2I 3I 4I 5I 6I J) .) q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. T. Zg 7I 8I < : ! ! ! ! ! ! < | v. !. !. !. !. !. !. !. !. !. !. !. !. I ' < j {> !. !. !. r> }* S ] _ ! { d I@ Z( 0 < ! _ ] ] _ ! ! ! ! : 9I 0I mf aI $3 bI cI dI c@ eI fI gI hI iI jI kI lI mI ~ : 9I ,= )= #- ! : 9I ,= )= #- sH d _ U _~ y f+ Y# p@ }# ] 5 b, !. !. !. ]) 0. 0 [. g+ 8 k }* !. j@ !. w! I+ < < ( ! 0 n }# #= $+ w! a. { _ ! ! ! : < : { ] ) { ! ! ! ! ! ! ! ! ! _ { g g _ g n b _ ! ! _ ! ! _ nI tl oI /* e. U. J+ (^ <' pI _{ ~} l] ~} E, t^ N_ k} }{ O~ P} g_ U6 A{ l} hF !. !. !. !. !. !. !. 7E Ry l} W2 U6 (1 B> {| << q^ 0~ l| L[ V] rC U] k} W0 :< qI W^ J< w1 $] p0 !. t^ m} f| !. !. !. !. !. !. !] sI IE x) {] u] +^ j[ T: X3 7^ E7 =3 m3 tI #| uI vI C( ko x_ x_ J( wI xI yI zI -H L4 Y0 AI BI :i H2 Gq m3 (4 j9 U} T: T: T: T: T: E} bb CI DI Ac EI FI GI KA 68 wF HI II JI qt KI LI MI NI OI .) q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. z& PI QI RI /c ! ! ! ! ! ! : x >+ U+ -( -( !. !. !. !. !. !. !. !. !. I f _ ~ q# ~2 !. !. !. !. a_ u ) ! ! : x p g _ ! ! ! ! ! ! ! ! _ d SI $b TI UI bk U. 1* {% =; $! 9+ bI 5a VI WI XI YI ZI $b `I J .J +J g ,j @J #J $J %J &0 -b &J YF >j y *J u a@ o 7 ! < v l+ <' !. !. s. '{ ;| ^. P a@ `) !. !. !. T+ P < _ ! : < ] [ o :~ V@ 0. ~ : _ { ) p z e 3 M h d _ ! ! ! ! ! ! ! ! ! _ : _ ! _ 6 d _ ! ! { : : _ != =J -J 7' *= T. J+ (3 !. 3: `] K_ ^< S1 Q~ }< P} O~ D> V2 s1 vp q} N~ 9~ R~ u( ;J !. !. !. !. !. FE <: <} N_ |^ ;] kd [{ :< Q_ =] z> T| 0[ _} .5 l; >J Pi p} Mt n] f_ N[ f| q; o; -] &4 D> l; p7 R_ l| v{ p] N_ ;] ,m m* !. !. !. !. !. ,J e/ 'J I{ {] u] +^ j[ N4 &5 )J [G 03 !J an t< ~J {J +2 ]J &8 8: s3 ^J /J Pb (J ^4 .c _J W3 &9 N4 E7 7^ X3 T: T: T: T: T: T: T: T: X3 Mv :J e5 P^ j@ !. !. h+ V@ M { _ ! ! ! ! ! < ! w 9 ! _ ! 7 q :. I| I@ n{ v! %= $= z : ! ! ! ! ! ! ! ! ! ! ! ! : p i d { 5 L p } 7 9I qJ rJ sJ ^& T. tJ uJ !. !. o6 )k Q_ N< t} Re w1 *] Or vJ f; 0- t8 af (1 22 _< 6E %D wJ 6: !. !. p, xJ m| }2 p} U] [< R< U] E, B> << :} 0[ m} i] Z] r} /1 U] k] Q~ Q~ yJ B> H! Q< z{ ^< p] N_ D> [< p7 ^! x2 N~ o] v{ zJ g~ !. !. !. !. AJ BJ CJ DJ y_ EJ ' wa xa FJ 93 GJ CA HJ IJ JJ g2 Y0 JH _5 KJ LJ MJ NJ oF Hu OJ Zs '4 #^ X3 T: T: T: T: T: T: T: T: T: T: T: T: T: E} &5 ]p PJ #9 QJ RJ SJ TJ Pk R: S: T: T: T: j[ UJ VJ WJ XJ YJ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. f. ZJ `J K 9I { ! ! ! ! ! ! : ) @ $= !. !. !. !. !. !. !. !. !. I+ / ! ! < 9 a@ 6] !. !. T@ b. ^ ! ! ! ! ! ! ! ! ! ! ! ! ! { .K +K @K :; /& e. e. e. e. e. e. e. e. e. z& =; 7' e. e. z& 7' 1* g, - {% #K $K %K &K /* A& :; e. e. 1* *K =K -K != _ { ! ! ! ! _ 8 o+ w! !. !. !. !. !. !. !. !. !. /@ <# g+ ~ _ ! ! ! ! ! ! ! : < : : w O I| 7] &+ b; r> !. !. !. /@ :. 7 : ! ! ! ! ! ! ! ! ! ! ! : w T ` a w :. Y+ q# M { ;K >K ,K 'K 8' )K !K C% !. !. b; 7- V7 a~ T9 g_ Pt ~( !. !. !. Z7 ~K {K m] f_ Z4 z{ (< u{ G5 42 !. f| J! t} X6 Q_ D> 1: {| z{ >] N< h| l; N_ k} P} R_ 9~ N_ w' l} l| W2 22 B> q} N_ }< X6 E, 9~ T1 x2 M< [^ *] }{ g_ ]K ^K !. !. !. !. ;_ Lb /K (K _K :K F] q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. 8' ha bK 9. ~ _C : : _ ! ! ! ! , >+ !. !. !. !. !. !. !. !. !. O^ 8 _ ! ! { < R. )^ !. T@ ` ^ ! ! ! ! ! ! ! ! ! ! ! ! : w cK dK eK <; e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& =; 1* - =; e. e. z& <; z& z& 7' fK gK 2> 9I < _ ! ! ! ! ] 1 8> !. !. !. !. !. !. !. !. v! Z 5 g _ ! ! ! ! ! ! ! ! ! ! ! < 1 j+ !. !. !. !. !. !. !. !. !. o@ p { ! ! ! ! ! ! ! ! ! ! ! ! : 6 '. y { m R. v z P hK 9, iK Y* L& b> jK kK E{ !. !. !. T~ lK Yf mK 5^ y2 !. !. !. Z7 Dm A{ ,G [< k} }{ |: _| nK O} oK ~K K_ E, f_ k} (< G3 V0 pK w, %A X8 N_ f_ U< N~ B> << (< k} Q~ K_ W^ }{ k} Q~ t} E: [{ |2 9~ T1 T9 9[ 9~ N< m] g_ qK rK !. !. !. !. + !. !. !. !. !. !. !. !. !. O. 8 _ ! ! ! { { . {> ]. H ( ! ! ! ! ! ! ! ! ! ! ! ! '= W TK UK ~% e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& 1* VK gK WK XK h ! ! ! ! ! : : >+ ^@ !. !. !. !. !. !. /~ Q { < _ ! ! ! ! ! ! ! ! ! ! ! ! _ g >+ ~. !. !. !. !. !. !. !. i+ C< } { ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ~ ! _ ~ ] w (. !. !. !. v: y% L@ YK ZK 8 !. !. !. !. !. !. S+ T~ !. !. !. !. .h R1 T< O~ >4 << U< N~ ~| o] }{ U< U< q} l| *] w> Mr y' ./ 3{ P! `K 3: B5 x> m] L[ J< t^ S| O~ 9~ p} L[ U< m] z4 kj }< }: 8~ W0 D> D, R6 ^2 J! i] q^ }2 ^9 !. !. !. !. )G L .L +L @L #L $L Yr %L &L Ah *L =L !p -L ^6 ~5 (4 *3 Gq +o ;L >L ,L |I 'L )L il W3 @b !L ~L xc }J {L l4 ]L ^L /L 8} T: T: T: T: T: T: T: 7^ D9 v[ E} T: T: #} w} S: j[ @G NK (L Fq w3 _L :L + !. !. !. !. !. !. !. !. !. Q / ! ! ! ! ! : ^ i p# n { ! ! ! ! ! ! ! ! ! ! ! ! '= W 2L -- z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. 7' dJ 3L 4L 5L k+ (> < ! ! ! _ ] z. &+ !. !. !. !. b; Z{ 5+ ~ { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ~ { ! x. {. r. !. b; S+ P^ t. [~ t ~ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! ! _ : : ! @& @= !. !. |= :& U. 6L 0) 9o Pa !. !. !. !. !. !. !. !. {6 &D lj js -] z{ L3 << Q_ [< T| V] 9~ z{ o] 1: p] C, 7L 8L p, !. !. !. !. !. !. k) Fb P[ W0 N_ N_ m] e| }{ r} w> i] ~} :} k} }{ q^ &m -r z4 |8 a/ Qc K_ l; [{ w{ gF h+ !. !. !. 9L 0L aL bL cL F( dL eL fL f3 gL hL iL 23 jL m3 T: T: U} 7^ @} x3 kL lL mL {h h5 Y9 nL oL ut Qr pL Xk qL r[ A8 lG /G HK @[ T: T: T: T: T: T: T: T: T: T: T: X3 z1 rL sL U} tL uL vL ]m -3 wL xL yL zL N* q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AL d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. f. J+ BL CL (c q. 9] `) o@ 2 < > $= !. !. !. !. !. !. !. !. !. '. f ! ! ! ! ! ! _ { : ! ! ! ! ! ! ! ! ! ! ! ! ! ! 2> DL EL J+ z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. !% FL GL HL IL JL ) : ! ! _ ] b. ]) !. !. r> u. x. T : { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) c K@ i( V@ o@ x. N ` | ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { : : x Z) q. !. 3/ (h f. hs KL q2 up !. !. !. !. !. !. !. !. ^9 B, v{ K_ [2 6[ W^ [{ Q~ O~ m] N_ N_ Q_ M< }< (1 P[ 7- !. !. !. !. !. !. !. !. !. 6- x> [{ {| A> l} W^ 0~ LL >4 T] S1 }8 A, ^1 (1 n] }2 m} /1 l| z: D: 9[ ]< <3 .^ .; !. !. !. )G ML NL OL PL 8E *8 z} Y' QL %9 t6 |F RL e3 SL T: T: T: T: T: X3 N4 !7 jl R: %d gn W} TL yh UL VL WL U/ XL Wq L4 33 xa C4 T: T: T: T: T: T: T: T: T: T: T: 7^ YL ZL `L M .M +M @M #M $M %M ,e &M *M yg q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . =M d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. f. 4$ -M H> !. !. !. 8> r ^ - I@ !. !. !. !. !. !. !. !. !. I f ! ! ! ! ! ! ! _ : _ ! ! ! ! ! ! ! ! ! ! ! ! : M0 ;M >M <; e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. 7' 7' Oe ,M 'M )M #- &0 ! ! ) k x! !. S+ [# q 7 : : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ! d | 3 d x < { _ ! ! ! ~ g ~ ~ ! ! ! ! ! ! ! ! ! ! ! : 6 g+ o < 4 <~ $+ !. :% O6 U. !< p2 <: Qc V~ !. !. !. !. !. !. P! 5 g_ !M B> U] r] << E, p} &4 1: 1: U< O| p} <1 0[ m| d) y2 !. !. !. !. !. !. !. !. Av T| w' O_ t} *] r] w' w' 6[ 0~ 0~ l3 8~ s^ r} 1: ]2 Q_ X6 V2 N_ R_ 64 5 42 !. !. !. !. !. ~M {M ]M V! v- ^M /M `F Rb (M @8 ,5 _M >7 (6 T: T: T: T: T: T: T: T: T: T: hf :M vj %[ zD 2u | !. !. !. !. !. !. !. !. !. I f ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! '= $I cM z& z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. n& dM eM fM x '= _ : e P. 9, 9, V 8 { _ ! ! ! ! ! ! ! ! ! ! ! ! ! _ : _ ! ! ! ! ! : < < { { : _ ! ! ! ! ! ! { : 6 w ! ! ! ! ! ! ! { < : : x . v ( '. ;| !. H| Kt {% e. H[ p2 <: A: U~ !. !. !. yA r7 gM A: h| O~ r} 12 R_ p] *] >4 I! -] R_ M< p] q^ Q_ *_ o1 [3 9~ Or hM Z7 T~ iM IB J3 V_ _2 ld (1 Q~ -] N_ l; V] [< C> 0~ *] Q_ Pi N~ l| J< O~ N_ z> }2 z> N_ 9~ jM _< kM !. !. !. !. !. AJ lM mM nM oM pM E( qM rM sM 2b tM uM @} T: T: T: T: T: T: T: T: T: T: T: 7^ H2 vM y[ wM xM }_ yM zM AM BM nL CM Iv `8 h5 T: T: T: T: T: T: T: T: T: T: T: T: X3 DM T: #} Fq 3e EM FM GM Z5 HM 77 IM JM y< KM 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . LM d. #. [% #. g. f. S. e. e. e. e. e. e. e. e. e. e. e. e. MM 4$ NM OM PM m@ QM RM SM L% !. !. !. !. !. !. !. !. !. I f ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ TM UM VM 7' e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. {% z& WM XM 0 YM ) 9 W @& _@ z < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ~ g ~ { : ! ! ! ! ! ! ! ! ! ! ! ! _ _ _ ] { 4 7 g 9 ~ ! ! ! ! ! g 4 o d : < : _ ) f+ w! !. ZM z% 8' U. |[ `M t{ B{ J> !. !. JF d/ N l| (1 z{ D> V] y> }< R_ R_ R_ q^ :{ W] N_ l; (< }{ N_ y> X6 (1 m7 .N HE +N HE x, g) F3 A: s^ =] [< /1 m] N_ M3 2c N< N~ J< W^ 0~ D> }2 p} q^ |8 ;] T] +5 9~ P} (< (1 h) !. !. !. !. !. AJ @N #N $N %N &N *N =N -N y6 ;N )[ j9 T: T: T: T: T: T: T: T: T: T: T: T: T: C4 >N *2 e5 7G ,N Dd 'N )N !N 1t tg a k9 mj T: T: T: T: T: T: T: T: T: T: T: T: T: w} w} T: X3 f< j9 x3 ~N +f {N Y} ]N ^N /N KM 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (N _N :N ) !. 3N ~~ 8_ !. !. !. !. !. !. !. !. !. I f ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ >; {t 4N 7' e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. =; S. 5N 6N 7N ,= k F[ `( u ~ ! ! ! ! ! ! ! ! ! ! ! ! ! ! { x b. G~ z. 9 { ! ! ! ! ! ! ! ! ! ! ! e ! < p '. 1' (. 1 ] ! ! ! ! ! ) b }~ X( P { z I@ 7+ 1 g^ j@ !. b$ z% 8' U. 8N 9N @5 t, 0N !. !. #5 7[ y> A> 2c v{ |2 e| N~ 8~ L3 R_ N_ m] 9~ M< -] E, U6 u} |{ 1: (1 f_ f_ e| m} :} 8~ l| 0~ e| Q~ q^ Q~ B> l; (< q^ p] U< J< T| >6 U] L< B> a[ B> (< y> A4 9o q. !. !. !. !. aN x( bN cN dN eN fN ,3 Qb m9 &5 @[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: E} Y| 4k ht gN lG Sa |F t6 G^ :] hN e3 81 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: U} lo iN x| jN 4| xx %8 5v kN {x KM 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . lN mN nN oN pN qN rN sN tN Jh e. #. [% #. g. f. S. e. f. J+ uN D[ K$ vN S. :n !. !. !. !. !. !. !. !. !. I f ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! #- >; wN #K xN e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= =; yN zN AN BN @= !. C< _ : ! ! ! ! ! ! ! ! ! ! ! _ { e I 8> ~. l@ J@ ) ] ! ! ! ! ! ! ! ! _ _ ). O. Z) b, /~ $+ !. l+ } < ! ! ! ! { 6 G+ y# j+ '. I@ M! 6] g^ 9, !. !. |= CN 8' e. )} ]| q2 8~ d) 8L x1 |< g_ }{ R_ m] ;] >4 -] 2c |^ W^ x> q^ D> ;] :< l| 9~ D> s} DN 1: U] Z] (< Q| t} E, l} W^ W^ 0[ *] p] Q_ w' s1 N~ J< i] ^1 E, J< t} Q~ E, N_ .5 w' T7 <2 V] Q< w{ r1 t} r} t^ ]} !. !. !. !. !. ;_ EN FN GN HN IN 2 tG `n il X3 T: T: T: T: T: T: T: T: T: T: X3 7^ X3 T: T: T: E} |} fe ,E JN KN LN %< MN NN #[ v[ T: T: T: X3 8} X3 T: T: T: T: T: T: T: T: 7^ y1 f< U} T: ON PN C4 QN v7 =o ^] RN SN .) $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + TN UN VN WN XN YN ZN `N O L@ g. g. #. #. e. A$ J+ .O .$ !. !. !. !. !. !. !. !. !. I f ! ! ! ! ! ! ! ! : { )= _ _ ! ! ! ! ! ! ! ,= +O @O #K 1* e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. #O $O Z{ /@ !. %= x { ! ! ! ! ! ! ! ! ! < ( ) 0 Q. V+ r> !. !. T@ p# w : ! ! ! ! ! ! ! _ { I 6] !. !. !. !. !. 7] V ] ! ! ! ! ! { 4 }~ b; =+ =+ !. !. !. !. !. c$ }= %O S. e. &O I[ @5 *O (< Mk N3 B, v1 O~ k} K< J< T| 6[ ]2 R_ 0~ ^! &4 U< k} ;] q} :< J< [< S| }< [< << E, N< D> (< l; T| W^ 0~ r^ T| N< t} Q_ U] y> q} x2 w' ]2 R_ Q~ w' |8 [{ I! o1 |7 z4 N< << s^ N< =O ~} ]b !. !. !. !. !. -O ;O >O ,O 0. 'O )O !O y1 T: T: T: T: T: T: T: T: T: T: T: @[ ~O ,[ {O hf X3 T: T: E} 81 w3 '4 Z1 H2 m3 &5 (4 7^ S: f< y1 il W3 ]O /4 %2 T: T: T: T: T: T: X3 eE z2 nj t7 ^5 ^O Gq /O (O _O Nu :O ~{ aO &I != _ ! ! != ,= ,= 8d bO cO *= z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. h. dO eO v! h+ 1' ! { ! ! ! ! ! ! ! _ 7 m j r O^ ]. !. !. !. !. !. @= :~ 7 { ! ! ! ! ! ! ! : w X+ 9] !. !. !. `) Y# ~ : ! ! ! ! ! ( H t. !. j@ @= h+ !. !. !. !. 3A fO U. S. -- [7 gO ~v L~ hO md iO T9 W] D> (< N_ N~ jO W^ 0~ U] d| l} q^ ;] O~ z{ u4 js kO lO }2 O~ B> Q_ U< Q_ E, O~ D> r} ;] ]2 Pi n| u4 }2 t' p; mO nO K_ Q_ (< D> R_ Q~ S| N< h| ]v Ka O[ t} ]! 7< oO k] oO i) !. !. !. !. !. qd pO qO rO ]# sO Kx O3 T: T: T: T: T: T: T: T: T: T: T: =3 _9 tO uO vO wO |3 7^ T: T: T: T: X3 7^ 7^ X3 E} T: 7^ B^ xO hn yO zO AO gc BO y1 ug T: T: T: X3 (6 CO DO EO FO :q GO HO IO JO |I KO LO MO y< E. U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % NO OO PO QO RO !. !. !. !. !. !. !. !. !. SO TO UO pJ &I VO ,= { < 7t WO O+ XO YO ZO `O >; '= != P .P +P @P #P U. *= e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. f. [; $P m* !. :# p < ! ! ! ! ! ! ! { w [* >( }* T+ !. !. !. !. !. !. !. z/ I ) ! ! ! ! ! ! ! ! < 5 J@ ]. !. !. 8> 2 ] ! ! ! ! _ ! ) K ,; !. !. !. !. !. !. !. _% .$ f. T. U. -- (3 9] d; %P u: !. &P 4< -] y> a[ W^ [< Q_ i] Q_ Z] N[ N< }{ O~ 22 z{ F: 2H !. c~ 28 [< M< ~} M< N[ [2 V2 (1 D> N_ [< A{ u4 $A 85 FE !. !. C% 2{ n] N< kd z5 Lk k} 9~ U6 oO !. O< !k *P =P h+ 6: 3{ !. !. !. !. !. !. ;_ -P ;P >P ,P 1e 'P j[ T: T: T: T: T: T: T: T: T: T: $d 03 )P ]0 !P 4u ~P {P u[ 8} T: T: T: T: T: T: T: T: k[ +b ]P ]A ^P 8n t5 /P pj (P _P 8} T: T: T: 8} ^6 Hu s[ o< |u :P og `| B8

0~ 12 A> jP |{ o] E, :u f; !. !. !. u2 kP r} O~ k} t} p} C, t} kd 9g x2 54 ;] Hb !. !. !. !. !. lP F> m| t} 0~ 0~ N< R_ Pc ^2 8 !. mP nP ~. !. !. !. !. !. !. !. !. !. oP pP qP rP sP tP uP j[ T: T: T: T: T: T: T: 7^ wa U: vP wP +6 xP [y yP %f {i zP W3 8} T: T: T: T: T: T: j[ t7 I2 pL AP BP CP DP EP FP Rr GP 05 T: T: T: 7^ ]6 g8 HP IP JP KP LP MP NP OP PP QP RP SP {x s+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <. !. !. !. !. !. !. !. !. !. TP UP VP WP XP YP ZP f, `P Q .Q +Q {& J0 _; N} @Q #Q bI m^ 1* 7' {% e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. [; J% .; !. !. F[ } { ! ! ! ! ! ! : x += $+ !. !. !. !. /~ =+ >( k@ !. !. }* M ) _ ! ! ! ! ! ! ! ! _ ' f+ u! w. I+ x : _ ! u n+ }. < } 7 d !{ !. !. !. !. !. h* -- T. e. U. J+ wb !. h+ $Q Pa !. m> T9 |{ R_ E, ia B> (1 ~| w{ v{ Y] T9 /} o> B5 Ka h+ !. !. !. !. i) d/ z> Re N< M< 9g q} (< T] w> q^ m| -6 -& !. !. !. !. S~ I! Z4 }< T] p7 N< 9~ U2 q^ *m !. C% m* $+ !. !. !. !. !. !. !. !. !. %Q &Q *Q =Q -Q ;Q >Q j[ T: T: T: T: T: T: @[ 7a ,Q 'Q 86 )Q s[ xh <9 !Q ~Q Ed {Q ]Q Pp .b T: T: T: T: T: T: C^ {m ^Q J2 /Q (Q +2 _Q :Q +f N_ r] B> *_ W^ N~ x2 %] Y] Pc t' J/ !. !. X1 iQ *] N~ m] J< /1 |: }< O~ R_ @p r. !. !. !. !. !. !. !. !. !. !. !. !. */ jQ kQ lQ mQ nQ au j[ T: T: T: T: T: 7^ I1 oQ pQ 61 qQ rQ sQ {r &8 tQ D1 uQ sl u3 vQ 91 T: T: T: T: T: T: y1 wQ xQ yQ zQ AQ BQ CQ pc DQ EQ N4 T: T: X3 X3 d: Nu FQ GQ HQ @o ab z_ [_ [_ IQ JQ wz r+ !+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . KQ LQ MQ NQ OQ PQ QQ RQ SQ b> f. @. @. d. L@ T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. Ny J% TQ <. v Mc )= != != : #- $- : { : < 5 U 3 6 6 ~ ( 8 J n{ 7] !. >| j ] _ ! ! ! ! ! ! ! ! : 5 R. }. `( b, 6 4 1' !. !. U@ s H Q. m+ z/ UQ p, !. ; D% 3] f. e. e. U. J+ wb !. !. !. !. !. q. E/ Pc 1: 9~ Q~ l; W^ [^ D> z{ R_ Ry !. !. !. !. !. !. !. !. !. !. !. VQ u{ B> M3 L< 6[ N~ }2 << 0[ :< W^ S_ [2 d; !. V_ #_ C> 3c T| E, t1 q^ N~ 2c }{ &4 8- h+ !. !. !. !. !. !. !. !. !. !. !. 9L WQ XQ YQ ZQ `Q R S: T: T: T: T: T: mt dH .R hE IP q5 gz +R @R &8 &8 #R Y' $R mo %R I1 8} T: T: T: T: T: T: t7 &R sh m/ S/ *R =R -R ;R a3 T: T: @} &9 8a 62 >R Q3 WE ,R Y' 'R x_ x_ x_ $t {D )R z< q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . !R ~R {R ]R ^R /R (R _R :R e. d. 8+ 8+ d. ,@ g. f. T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. *= ~ ! 2R (8 3R < ] [ | n+ ` < _ : p R 0. -( !. v. p 8 : : ! ! ! ! ! ! : ) b. b, y# b_ <. 9. 1/ !. !. q. (@ /@ M! Kb 4R 5R 6R |, <& E$ S. S. e. e. U. J+ wb !. !. !. !. !. !. 7R p7 z{ Q~ 0~ R_ w' w' E: O~ T< .5 m> !. j@ /b ]( x4 :^ Bq 3> !. !. Y1 p^ Q~ << A> U] l] N~ U] T] W0 _} 8R A{ :: )t !. Hb T7 N~ i] *] lO +H q} N~ ;] 9R -] `^ !. !. !. !. !. !. !. !. !. !. !. 9L 0R aR bR cR dR eR j9 T: T: T: T: T: h5 fR Iv 82 gR hR @j Fu iR 4k jR kR +j lR 4s t6 $2 &9 T: T: T: T: T: T: E} jl mR nR -N oR &E 1t y} pR 7^ h5 Ep qR o: B^ V: yI hE `E rR k< x_ x_ sR tR uR @* ~+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . vR wR xR yR zR AR BR CR DR x9 T. ER V. #. g. U. S. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. L& FR GR HR IR lJ JR KR M{ }v LR MR NR OR PR w / 6 R. I < : ! { 8 l '{ !. <' O^ a ! _ { _ _ _ _ : { j v. r. !. S@ (@ 8] 0, !. !. !. !. !. >) QR RR SR #K )% 4$ U. S. e. e. e. U. J+ wb !. !. !. !. h+ !. N3 18 Q_ ^e q} Q~ }2 w> E, O~ kj O~ O9 !k TR t4 M_ W^ <2 T1 s2 UR !. !. :b &4 << p] [< r^ k] M< _} T| m} VR N_ g_ X] +; tC WR }< U< ]< 0/ q. XR 9~ w1 T7 D> YR !. !. !. !. !. !. !. !. !. !. !. )G ZR `R DJ S .S +S *3 T: T: T: T: T: y1 qt @S 23 #S $S 83 %S s0 )8 &S 2I Wq *S =S -S ;S UJ 7^ T: T: T: T: T: T: j[ P4 {h m[ )Q >S Za Iv ,S 'S )S !S W} .} Tq ~S {S ]S ^S /S (S 3( x_ *z _S :S M* !+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vR D |S 1S 2S d] L@ L@ g. #. d. g. f. U. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. (& 3S 4S 5S I~ /* <; aJ 6S 7S )> XH 9$ 8S 9S gD 0S [ c ). _ ( ) ) ` 1/ !. !. ~. %= !) _~ c / ( < : f b N^ `) ^@ !. >( W+ $Q aS h1 >< bS :% 8_ cS =- {% =; *= U. T. e. e. e. e. e. U. J+ wb !. !. !. !. P! dS p^ <1 eS B> M< Q~ E, V] &4 22 9~ C> A{ U< t} A{ T< (1 R_ (1 _| K_ j' !. fS x, z> << }{ m] h| t} U< (< N_ Z] Q~ k} z{ gS hS o} z: (< iS j@ !. T~ jS ]e U1 ld kS K/ r. !. !. !. !. !. !. !. !. !. lS mS nS oS pS qS rS N4 T: T: T: E} f< j9 .| sS C8 pj tS A8 #g Rq uS nf '5 t6 D0 vS wS xS .6 F} T: T: T: T: T: T: T: T: !7 yS zS AS BS CS DS ES FS -N GS HS 7f IS ng JS )Q KS LS MS NS OS 6v 6_ d& q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PS QS RS SS TS H} US VS WS XS e. [% V. d. g. f. U. T. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. n& 1* =; 7' z& z& =; /& =; YS 7' Jk ZS `S T .T n (8 J@ @& j 0 ( [. S+ !. !. !. U+ X( S+ W+ 4+ +T @T %- #T $T %T ]) /; &T 8I Y *T =T Tu l( 1% Z* <% !: e. S. e. e. e. e. e. e. e. e. e. U. J+ wb !. !. !. !. 2= <: A{ p7 :} 0~ |8 1: w4 R_ Q< -] U< k} ]2 B> p] *_ q^ T7 N_ l; ;] >] K[ 2- !. Gb -T (< |: O~ O~ e| Q_ Q_ B> N~ k} D> Xw q7 S+ !. ;T >T `^ !. !. !. !. m* .; Cu Sc 84 Pa !. !. !. !. !. !. !. !. !. ,T 'T )T !T ~T {T ]T ^T /T G0 (T _T HK Dp B^ :T R. v n@ 9] !. !. oT pT qT !. !. rT sp sT ^K }/ tT uT vT wT xT yT zT n& e. 4$ -- U. U. T. e. e. e. e. e. e. e. e. e. e. e. U. J+ wb !. !. !. !. !. zJ AT t{ ]v U1 zA A: BT :^ /a kr >r T} << N< k} K_ bg z> N~ E> V] ;] CT 5^ !. !. DT y, E, H: f_ Q| Q~ S1 J< A{ Re -] [: !. !. h+ t] p, }/ !. !. !. !. !. !. !. !. V_ S+ !. !. !. !. !. !. !. !. !. ET FT GT HT IT `6 JT KT LT MT NT OT PT QT RT ST TT UT Zs VT WT 4e XT ee YT ZT 7f ur `T hN Iq U u u[ x| 8} T: T: T: O3 P4 .U Za +U KA @U )5 ae #U ;3 f3 U ,U 14 -* ~+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . lN ~R 'U )U !U s< ~U {U ]U R8 S. @. #. d. g. L@ f. T. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. ^U nh /U (U ^~ !. !. !. x! _U /3 (@ :U ;] E, q^ Q[ `^ !. !. h+ 6: t8 Eb ^! W0 t} f_ t} z{ z> Db c; u2 !. ./ X7 p, !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ET aU bU cU dU eU fU gU hU iU jU kU lU mU nU oU pU qU .g [G rU sU {5 m3 tU H2 z3 /A uU ^k N5 Qr vU wU :v G p; {! -] A{ m; f~ !. !. !. !. !. !. kr 95 ]q #V $V Ok %V K/ Yf }3 85 ZD :: kr !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ET &V *V =V -V ;V >V d& d& ,V 'V )V !V ~V {V ]V ^V /V (V _V :V }G F yV ./ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ET &V zV AV BV CV * @ q+ .) yg DV YJ ;9 EV FV GV HV IV JV KV LV 2T MV >D D =W sN -W |N e. g. ER V. 8+ f. T. e. e. e. e. e. e. e. T. ;W j{ 2N h+ x# >W ,W g. T. e. e. e. T. z& 1* z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. J+ wb !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. gQ S6 Jb tC !. !. -m :b eo Sc 0- h+ !. !. !. !. !. !. h+ -& K/ 1< E{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ET &V zV 'W Y& )W [@ @ q+ q+ q+ q+ q+ q+ !+ c& !W ~W {W ]W ^W /W (W f2 jn `| ^d 1E _W :W 9 I~ U. g. g. 8+ d. ,@ g. f. T. S. S. lW mW nW `- T. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. J+ y/ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. c; zJ s( !. !. !. E{ oW f| Fb 2= !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ET &V zV 'W Y& )W [@ @ q+ q+ q+ q+ q+ q+ q+ q+ !+ N* pW qW rW sW tW uW 1_ vW ~P wW xW yW zW AW BW CW DW EW FW GW HW IW JW KW LW MW NW OW PW Ih D= !+ !+ ~+ !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ QW RW SW WN TW PQ UW VW bQ x9 g. ER V. WW XW W8 J+ S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. J+ YW !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. {s ZW X| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ET `W X .X Z> )W [@ @ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ ~+ m2 +X @X #X $X Z: ]r %X &X *X =X -X ;X >X ,X 'X )X !X ~X -j D= }@ =| .) D= 2d J) s~ @* q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + {X ]X ^X /X :N (X _X :X f. f. f. 8+ #. d. g. U. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. Z= Y ,Y 'Y !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )Y !Y S ~Y {Y ]Y ^Y /Y (Y _Y :Y . . . . . . . iY jY kY lY mY nY oY pY qY rY sY tY uY 3X !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )Y vY R U 3 / . . . wY xY yY zY AY BY CY DY EY FY GY HY IY JY u+ M# KY LY MY U{ RX SX !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PS RW VN NY OY /F PY QY RY x9 T. #. [% #. g. f. e. e. e. e. e. e. e. U. N} SY n 1 7 / > + . . . . . . . . . . . . . TY UY VY WY XY YY ZY `Y Z .Z +Z @Z #Z $Z r( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )Y %Z Y K o _ & @ . . . . . . . . wY &Z *Z =Z -Z ;Z >Z ,Z 'Z )Z !Z ~Z {Z ]Z ^Z /Z (Z _Z :Z + . . . . . . . . . . . . . . . . . . . . 6Z 7Z 8Z 9Z 0Z aZ bZ cZ dZ eZ fZ gZ hZ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )Y %Z R }. z _ & $ . . . . . . . . . . . . . . . iZ jZ kZ lZ mZ nZ oZ pZ qZ rZ sZ tZ uZ vZ wZ xZ yZ _Z MY RX ~+ !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zZ AZ BZ NU CZ DZ rN EZ FZ 0' U. 8+ GZ = ] ' ; $ . . . . . . . . . . . . . . . . . . . . . . . . . . . HZ IZ JZ KZ LZ MZ NZ OZ PZ QZ RZ SZ uY TZ yA !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )Y UZ S L 1 _ & $ . . . . . . . . . . . . . . . . . . . . . iZ VZ WZ XZ YZ ZZ `Z ` .` +` @` #` $` %` &` *` =` yZ Dj RX aX ~+ !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] -` G+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zZ ;` Q8 !U TW >` # , % $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,` '` )` !` ~` {` ]` ^` /` (` RZ _` :` 4X h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )Y <` t M 3 { - $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . [` }` |` 1` 2` 3` 4` 5` 6` 7` 8` 9` 0` a` NX b` =` 6Y c` RX aX aX !+ r+ r+ q+ q+ q+ q+ q+ q+ q+ U{ d` e` H+ S w & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # $ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iY f` g` h` 9Z i` j` k` l` m` n` o` _` p` q` !. !. !. !. !. !. !. !. !. !. )Y r` z o d ] , @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s` t` u` v` w` x` y` z` A` B` C` D` E` F` G` 4Y H` I` U{ E. !+ q+ q+ q+ q+ U{ J` K` q# r 7 - + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iY L` M` N` O` P` Q` R` S` T` U` V` p` W` X` !. !. !. Y` Z` _ 9 : f > + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . `` .. .+ .@ .# .$ .% .& .* .= .- .; .D. ^Z (Z > .:Z , .' .) .V 2 < ; + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ! .~ .{ .] .^ ./ .( ._ .: .< .[ .fZ (` } .% [ f , # + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ! .| .1 .2 .3 .4 .5 .6 .7 .8 .9 .0 .a .b .c .d .] _ ' # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e .f .g .h .i .j .$ % > # @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . k .l .m .n .o .p .q .r .s .@ - # + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ @ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t .u .@ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . !R kV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v .w .x .pN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . y .,@ 8+ jJ z .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A .B .;- -- C .D .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (7 b@ J+ 4$ g. Ao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E .g. 4$ 4$ ;- F .G .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c a@ L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H .%K e. 4$ 4$ 4$ U. I .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; L G+ ( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , '. l+ 1/ !. <. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OU U. 4$ 4$ 4$ 4$ U. J .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e 8. V+ !. )^ < . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . W >+ /~ r. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K .L .U. 4$ 4$ 4$ 4$ e. M .N .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f I Y( P^ !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % [~ k@ !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. O .%( 4$ 4$ 4$ 4$ P] ;- P .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v ^. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f z/ !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q .;W 4$ 4$ 4$ 4$ 4$ 4$ f. R .S .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . [. !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T .U .!% 4$ 4$ 4$ 4$ 4$ 4$ -- V .W .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X .S. 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ U. /F . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y .Z .f. 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ ;- (* ` .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AL b@ z& 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ P] gY ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ...f. 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ g. +..+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T .@..J+ 4$ 4$ 4$ 4$ -- 4$ 4$ 4$ 4$ 4$ J+ #..MU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; (@ !. !. !. !. !. !. !. 5+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X .e. -- 4$ 4$ 4$ 4$ tJ 4$ 4$ 4$ 4$ 4$ P] ;- $... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ` !. !. !. !. !. !. !. >| f . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . + [ < ] ] { f . . . . . . . . . . 6 5+ 4+ m+ b, /. /. }~ [~ H+ 0 * . . . . . . . . . . . . . . . . . > ] ) ] ] 6 6] !. !. !. !. !. !. !. :. ] ] ] ] ] ] ] ] ] ] < ^ $ . . . . . . . . . . + 8 < ] ] ] ] ) { % . . . . . . . ^ k !) )) /. /. /. 1' [# @& U d # . . . . . . . . . . . . . . . . . %..R .f. 4$ 4$ 4$ 4$ U. (X &..J+ 4$ 4$ 4$ 4$ f. *..=... . . . . . . . . . . . . . . . . . . . . $ ( < ] ] { , . . . . . . . . . > a 0. !) `( %= /. u! ,{ ;( o+ x > . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) n 8. m+ }~ ){ /. /. n{ ;+ 2/ K@ q { $ . . . . . . . . . . . . . . . . . . . . . = < ] ] ] ,% !. !. !. !. !. !. !. U+ 4 ] ] ] ] ] ] ] ] ] ] { * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . % b, /@ 8] 8] )^ V+ ) . . . . . . ^ 5+ I| @= !. !. !. !. !. !. !. !. !. j@ '{ N : . . . . . . . . . . . . . . . n /~ ~2 8] ]. ~2 r> !. !. !. !. !. !. !. w! y# 8] 8] 8] 8] 8] 8] 8] 8] 8] /@ {> g . . . . . . . . . . = :# /@ 8] 8] 8] 8] 8] 9, i . . . . . 6 O^ b_ !. !. !. !. !. !. !. !. !. !. /. * . . . . . . . . . . . . . . . . . =M b@ %( 4$ 4$ 4$ z& -..;..N5 f. 4$ 4$ 4$ 4$ J+ >..,... . . . . . . . . . . . . . . . . . . . . x 7] ~2 8] 8] ;| <# > . . . . . . w H+ #= M! !. !. !. !. !. !. !. !. !. <' u! O - . . . . . . . . . . . . . . . . . . . . . . . 7 <. Y( ~2 h+ !. !. !. !. !. !. !. !. !. !. h+ ;| N^ J@ x . . . . . . . . . . . . . . . . . . . G~ )^ 8] 8] y# `) !. !. !. !. !. !. !. j@ l@ ]. 8] 8] 8] 8] 8] 8] 8] 8] 8] )^ N . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; }* !. !. !. !. !. 0. . . . . . L v! !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 8] <. # . . . . . . . . . . . . . r $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. `) w . . . . . . . . . . f ]. !. !. !. !. !. !. !. '. . . . + p# &+ !. !. !. !. !. !. !. !. !. !. !. !. Q. . . . . . . . . . . . . . . . . . . '..L@ 4$ 4$ 4$ 4$ U. )..@ !..U. 4$ 4$ 4$ 4$ 4$ f. lt . . . . . . . . . . . . . . . . . . . . . 5 %+ !. !. !. !. q. V . . . . . a. ;| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. z# S . . . . . . . . . . . . . . . . . . . + v _@ ;| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. (# [~ 3 . . . . . . . . . . . . . . . . . <# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. [~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. _# ; . . , I@ 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 2/ # . . . . . . . . . . . . i 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 9, 6 . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . / j( !. !. !. !. !. !. !. !. !. !. !. !. !. 8] [ . . . . . . . . . . . . . . . . . ~..{..J+ 4$ 4$ 4$ 4$ U. s< . T .]..Z= 4$ 4$ 4$ 4$ Z= ^..0Y . . . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. <# . . . ! j( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. b; H+ . . . . . . . . . . . . . . . . . a v. $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. T+ a. . . . . . . . . . . . . . . . . ,{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. m+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. g+ . # o@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. [~ % . . . . . . . . . . . i 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 9, 6 . . . . . . . . . . f >| !. !. !. !. !. !. !. J . = V@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. _~ . . . . . . . . . . . . . . . . . . /..)< -- 4$ 4$ 4$ -- C .(... . _..f. 4$ 4$ 4$ 4$ %( %( :... . . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. P^ p . [ Z{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ p# . . . . . . . . . . . . . . > :. s. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;+ , . . . . . . . . . . . . . . ,{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. m+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. V@ . K@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. :. . . . . . . . . . . . i 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 9, 6 . . . . . . . . . . f >| !. !. !. !. !. !. !. s . Y( !. !. !. !. !. !. !. !. !. !. !. !. !. !. @= p . . . . . . . . . . . . . . . . . zZ <..f. 4$ 4$ 4$ 4$ f. w .K .. . [..J+ %( 4$ 4$ 4$ 4$ f. }... . . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. N . o@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. r> L . . . . . . . . . . . . . ; W+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. x. . . . . . . . . . . . . . . ,{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. m+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. s. ,> T+ !. !. !. !. !. !. !. !. !. M! !. !. !. !. !. !. !. !. !. !. !. !. !. {. | . . . . . . . . . . t !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. P^ d . . . . . . . . . . f >| !. !. !. !. !. !. !. l o+ !. !. !. !. !. !. !. !. !. r. !. !. !. !. !. l+ . . . . . . . . . . . . . . . . . . AL -- -- 4$ 4$ 4$ 4$ U. zR . . . G .J& J+ 4$ 4$ 4$ 4$ e. {..AZ . . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. *+ G~ !. !. !. !. !. !. !. !. !. r. r. !. !. !. !. !. !. !. !. !. !. !. !. !. v! / . . . . . . . . . . . . . q 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. $+ 7+ . . . . . . . . . . . . . l+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. w. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. !. !. !. !. !. !. b; z# O^ 6+ t V . I+ o@ 8] !. !. !. !. !. !. !. !. !. !. F[ + . . . . . . . . . e :. $= G+ Y# O. ]) !. !. !. !. !. !. !. !{ a@ G+ G+ G+ G+ G+ G+ G+ G+ G+ $= 0. / . . . . . . . . . . f >| !. !. !. !. !. !. !. $= l@ !. !. !. !. !. T+ ,{ ` s ). z. G~ >| !. !. j . . . . . . . . . . . . . . . . . . |..U. 4$ 4$ 4$ 4$ e. Sf 1... . . + 2..f. 4$ 4$ 4$ 4$ 4$ f. 3... . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. !. !. !. !. !. !. 9] A/ ,> f+ M M R P. )) `) !. !. !. !. !. !. !. !. !. !. >+ . . . . . . . . . . . . . . 1' !. !. !. !. !. !. !. !. %+ t. {> I| ,{ g^ ,{ )) ~2 j@ !. !. !. !. !. !. !. !. !. !. 1/ 9 . . . . . . . . . . . . T n+ G+ G+ J@ I| !. !. !. !. !. !. !. `) D< 8. G+ G+ G+ G+ G+ G+ G+ G+ G+ n+ j . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. !. !. !. !. r> -+ J # . . . . . . . ^ n+ T+ !. !. !. !. !. !. !. !. %+ 4 . . . . . . . . . . . . . . # }* !. !. !. !. !. !. !. [. . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. T+ !. !. !. !. j@ ;( g . . . . . . f 4+ }~ > . . . . . . . . . . . . . . . . . AZ @..e. 4$ 4$ 4$ 4$ ;- 'O . . . . . 4..U. 4$ 4$ 4$ 4$ 4$ U. 5... . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. !. !. !. !. T+ m+ y + . . . . . . . d `( b; !. !. !. !. !. !. !. !. >| & . . . . . . . . . . . . . q 9] !. !. !. !. @= Y( O | ; $ . . . . . ' }. (. M! !. !. !. !. !. !. !. !. !. 4+ . . . . . . . . . . . . . . . . . R !. !. !. !. !. !. !. /~ * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. !. !. !. 6] J . . . . . . . . . . . . U T+ !. !. !. !. !. !. !. !. 8. . . . . . . . . . . . . . . ' x! !. !. !. !. !. !. !. Y+ . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. !. !. !. !. i+ Z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6..MM 4$ 4$ 4$ 4$ 4$ T. 3... . . . . 7..0J e. 4$ 4$ 4$ 4$ J+ {c 8... . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. !. !. !. 8> 1 . . . . . . . . . . . . @& r. !. !. !. !. !. !. !. !. T . . . . . . . . . . . . . + 1' !. !. ^@ _. 3 . . . . . . . . . . . . . g+ (# !. !. !. !. !. !. !. !. y# / . . . . . . . . . . . . . . . . Z !. !. !. !. !. !. !. 6] ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. !. !. l+ _ . . . . . . . . . . . . . . P !. !. !. !. !. !. !. !. U@ + . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. !. !. !. P^ S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9..0..U. 4$ 4$ 4$ 4$ '> %. a... . . . . . b..f. 4$ 4$ 4$ 4$ 4$ f. lt . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. !. r. O. , . . . . . . . . . . . . . . ;+ !. !. !. !. !. !. !. !. w. . . . . . . . . . . . . . . q !. t. V . . . . . . . . . . . . . . . . n w! !. !. !. !. !. !. !. !. 5+ . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. !. -+ @ . . . . . . . . . . . . . . . - z# !. !. !. !. !. !. !. T+ g . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. !. !. h+ 5+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c..-- -- 4$ 4$ 4$ 4$ g. d..e... . . . . . f..e. P] 4$ 4$ 4$ 4$ U. g..h... . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. !. >+ . . . . . . . . . . . . . . . . w T@ !. !. !. !. !. !. !. U@ # . . . . . . . . . . . . . @ P w . . . . . . . . . . . . . . . . . . P q. !. !. !. !. !. !. !. i( . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. u! [ . . . . . . . . . . . . . . . . . 9. !. !. !. !. !. !. !. r> L . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. !. !. -+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i..f. 4$ 4$ 4$ 4$ %( J+ j... . . . . . . 7..k..J+ 4$ 4$ 4$ 4$ P] J+ YX . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. <~ + . . . . . . . . . . . . . . . . . 1' !. !. !. !. !. !. !. /@ 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % 7] !. !. !. !. !. !. !. m@ * . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. f+ . . . . . . . . . . . . . . . . . . y <' !. !. !. !. !. !. !. 9. . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. !. s. } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7..U .e. 4$ 4$ 4$ 4$ e. l..m... . . . . . . n..o..f. 4$ 4$ 4$ 4$ 4$ MM p... . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. } . . . . . . . . . . . . . . . . . . I+ h+ !. !. !. !. !. !. r. r . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p# !. !. !. !. !. !. !. P^ 6 . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. f+ . . . . . . . . . . . . . . . . . . * b_ !. !. !. !. !. !. !. ;( . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. !. _@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . q..L@ 4$ 4$ 4$ 4$ 4$ U. r... . . . . . . . . s..f. P] 4$ 4$ 4$ 4$ e. t..u... . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. c . . . . . . . . . . . . . . . . . . 0 ~. !. !. !. !. !. !. !. 5+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | $+ !. !. !. !. !. !. !. L . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . X( !. !. !. !. !. !. !. j( . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. S+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v..w..U. 4$ 4$ 4$ 4$ P] e. x... . . . . . . . . y..z..J+ 4$ 4$ 4$ 4$ %( e. 2O . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . f T@ !. !. !. !. !. !. !. K@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] >( !. !. !. !. !. !. !. 6+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. )) . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. ]. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 4$ -- 4$ 4$ 4$ 4$ U. A..~R . . . . . . . . . B..C..U. 4$ 4$ 4$ 4$ 4$ L@ 6' $ . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . > {> !. !. !. !. !. !. !. 4+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # A/ !. !. !. !. !. !. !. <. . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . ,> !. !. !. !. !. !. !. :# $ . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. l+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |..f. 4$ 4$ 4$ 4$ 4$ L@ D... . . . . . . . . . . OY T. 4$ 4$ 4$ 4$ 4$ %( E..F... . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . F[ !. !. !. !. !. !. !. :~ . . . . . . . . . . . . . . . . . . . . . . . . . & 4 q l }# R. K y : . . F[ !. !. !. !. !. !. !. n+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . N !. !. !. !. !. !. !. 8> % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. ,> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AZ G..e. 4$ 4$ 4$ 4$ %( %( H... . . . . . . . . . . I..K& %( 4$ 4$ 4$ 4$ 4$ U. J... . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . ]: !. !. !. !. !. !. !. _. . . . . . . . . . . . . . . . . . . . . . 7 T X+ %= 6] 1/ k@ ^@ !. !. b; i+ ~2 n@ K@ X( !. !. !. !. !. !. !. :~ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 9. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. 0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K..f. 4$ 4$ 4$ 4$ 4$ e. L..0Y . . . . . . . . . . . v..M..U. 4$ 4$ 4$ 4$ 4$ f. N..%... . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . o@ !. !. !. !. !. !. !. Z) . . . . . . . . . . . . . . . . . . . k [~ ]) !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . Q. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. Z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v..5S e. 4$ 4$ 4$ 4$ 4$ g. [k . . . . . . . . . . . . . O..f. 4$ 4$ 4$ 4$ 4$ J+ #K c... . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . `( !. !. !. !. !. !. !. Z) . . . . . . . . . . . . . . . . . }. ^) 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. }. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . h0 %( -- 4$ 4$ 4$ 4$ %( K+ P... . . . . . . . . . . . . Q..R..!% 4$ 4$ 4$ 4$ 4$ ]% [m . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . . . . . _ `( $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S..g. 4$ 4$ 4$ 4$ 4$ f. B .S .. . . . . . . . . . . . . $ jJ e. 4$ 4$ 4$ 4$ 4$ e. T..~R . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . . . . j t. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7..U..!% 4$ 4$ 4$ 4$ P] U. V... . . . . . . . . . . . . . . W..f. 4$ 4$ 4$ 4$ 4$ P] {b !U . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . . . f+ k@ !. !. !. !. !. !. !. !. !. !. !. h+ @= 1/ -( Z{ m@ y# k@ b; !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . . . K..f. 4$ 4$ 4$ 4$ 4$ -- W8 X... . . . . . . . . . . . . . . Y..b@ -- 4$ 4$ 4$ 4$ 4$ f. Z..+ . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . . b. 9] !. !. !. !. !. !. !. !. !. !. _# x. f+ 7 * % # # - x }. n+ z/ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . . [Z ba e. 4$ 4$ 4$ 4$ 4$ U. C& `... . . . . . . . . . . . . . . +..+.U. 4$ 4$ 4$ 4$ 4$ J+ @..RW . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . i ^@ !. !. !. !. !. !. !. !. !. 8> I / . . . . . . . . . . . }~ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . . ++.$! -- 4$ 4$ 4$ 4$ -- U. @+.. . . . . . . . . . . . . . . . . >D f. P] 4$ 4$ 4$ 4$ 4$ g. 8Q . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . ' v! !. !. !. !. !. !. !. !. i+ G+ ; . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . . #+.g. 4$ 4$ 4$ 4$ 4$ %( b] $+.%+.&+.&+.&+.&+.&+.&+.&+.&+.&+.&+.&+.&+.&+.&+.&+.*+.^P tJ -- 4$ 4$ 4$ 4$ 4$ e. =+.[Z . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . [* !. !. !. !. !. !. !. !. i+ H . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . MU a' z& 4$ 4$ 4$ 4$ 4$ 4$ 4$ J+ e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. %( 4$ 4$ 4$ 4$ 4$ 4$ 4$ -- -+.;+.. . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . x w! !. !. !. !. !. !. !. %+ g+ . . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . OQ U. 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ f. >+.. . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . <. !. !. !. !. !. !. !. !. $= . . . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. Y+ . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . %..5S U. 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ S. 5N m... . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . ; A/ !. !. !. !. !. !. !. 7] ; . . . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. >| ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. p# . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . ,+.b@ %( 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ P] e. '+.. . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . { k@ !. !. !. !. !. !. !. Q. . . . . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. z/ _ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . / x! !. !. !. !. !. !. !. G+ . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . )+.]% 4$ 4$ 4$ 4$ 4$ 4$ -- S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. %( 4$ 4$ 4$ 4$ 4$ 4$ U. !+.. . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . 4 $+ !. !. !. !. !. !. @= 4 . . . . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . b. !. !. !. !. !. !. !. &+ 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . * }* !. !. !. !. !. !. !. :~ . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . ~+.9J !% 4$ 4$ 4$ 4$ 4$ P] {+.w..ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba w..ba 9+ -- 4$ 4$ 4$ 4$ 4$ e. ]+.^+.. . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . T h+ !. !. !. !. !. !. /~ ) . . . . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . R. !. !. !. !. !. !. !. S@ 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . + U@ !. !. !. !. !. !. !. n{ . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . zR U. P] 4$ 4$ 4$ 4$ 4$ ^U /F kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX xx g. 4$ 4$ 4$ 4$ 4$ P] ;- zR . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . Z !. !. !. !. !. !. !. z# ' . . . . . . . . . . . . . . . . . . 1' !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . j !. !. !. !. !. !. !. !. k . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . u! !. !. !. !. !. !. !. j+ * . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . /+.(+.U. 4$ 4$ 4$ 4$ 4$ P] b@ _+.. . . . . . . . . . . . . . . . . . . . . . . :+.b] -- 4$ 4$ 4$ 4$ 4$ f. w .S .. . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . '. h+ !. !. !. !. !. !. v! 8 . . . . . . . . . . . . . . . . . . !{ !. !. !. !. !. !. !. ;( . . . . . . . . . . . . . . . 2 !. !. !. !. !. !. !. !. p# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ~. o . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . <+.B! %( 4$ 4$ 4$ 4$ 4$ f. 0..(N . . . . . . . . . . . . . . . . . . . . . . . h..[+.S. 4$ 4$ 4$ 4$ 4$ -- tJ }+.. . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . n h+ !. !. !. !. !. !. w! d . . . . . . . . . . . . . . . . . Q 9] !. !. !. !. !. !. !. o@ . . . . . . . . . . . . . . . c S@ !. !. !. !. !. !. !. -| . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . J@ !. !. !. !. !. !. !. !. x. . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . (X g. 4$ 4$ 4$ 4$ 4$ P] f. >D . . . . . . . . . . . . . . . . . . . . . . . . . Ao U. 4$ 4$ 4$ 4$ 4$ 4$ S. |+.. . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . g {. !. !. !. !. !. !. !. Y . . . . . . . . . . . . . . . . Z ^@ !. !. !. !. !. !. !. !. %= . . . . . . . . . . . . . . . / -( !. !. !. !. !. !. !. k@ | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . 1 $+ !. !. !. !. !. !. !. i+ m . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . 1+.M .J+ 4$ 4$ 4$ 4$ 4$ J+ -..2+.. . . . . . . . . . . . . . . . . . . . . . . . . ]8 %( P] 4$ 4$ 4$ 4$ 4$ ;- 3+. +.. . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . $ -| !. !. !. !. !. !. !. Z{ , . . . . . . . . . . . . . @ @& ~. !. !. !. !. !. !. !. !. !. ,; . . . . . . . . . . . . . . . . ;+ !. !. !. !. !. !. !. !. V@ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . * ^. !. !. !. !. !. !. !. !. U+ q . . . . . . . . . # 3 < . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . 4+.U. 4$ 4$ 4$ 4$ 4$ 4$ ;- *..@ . . . . . . . . . . . . . . . . . . . . . . . . . ` .5+.S. 4$ 4$ 4$ 4$ 4$ -- `* 6+.. . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . K@ !. !. !. !. !. !. !. !. m+ @ . . . . . . . . . . . w (. !. !. !. !. !. !. !. !. !. !. !. `) } . . . . . . . . . . . . . . . ` h+ !. !. !. !. !. !. !. !. [# - . . . . . . . . . ^ a + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. !. !. k@ C< r : $ . % e h a. #= M! ` . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . %..7+.f. 4$ 4$ 4$ 4$ 4$ 4$ 8+.K... . . . . . . . . . . . . . . . . . . . . . . . . . . 9+.,@ 4$ 4$ 4$ 4$ 4$ 4$ g. 0+.+ . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . _ l@ !. !. !. !. !. !. !. !. n@ k . . . . . . . . h I@ )^ !. !. !. !. !. !. !. !. !. !. !. !. !. 5+ . . . . . . . . . . . . . . . , 7] !. !. !. !. !. !. !. !. !. z# a. 3 / . . [ 5 s O^ z/ b_ # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . . = >| !. !. !. !. !. !. !. !. !. !. r> y# _# ^) -( ~2 @= !. !. !. y. . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . Q8 x9 P] 4$ 4$ 4$ 4$ 4$ !% a' 1... . . . . . . . . . . . . . . . . . . . . . . . . . . NU a+.J+ 4$ 4$ 4$ 4$ 4$ J+ @..b+.. . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . n+ !. !. !. !. !. !. !. !. !. M! U@ ,{ Y# I+ Z y. Z( #= @= !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. {> - . . . . . . . . . . . . . . . f+ !. !. !. !. !. !. !. !. !. !. !. `) /~ {> a_ >| (# b; !. !. P^ 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . . . H r> !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. g^ . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . nV U. 4$ 4$ 4$ 4$ 4$ 4$ f. kT c+.. . . . . . . . . . . . . . . . . . . . . . . . . . . d+.e+.;- 4$ 4$ 4$ 4$ 4$ 4$ e. f+.. . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . / V+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. [# }~ !. !. !. !. !. !. !. !. n+ . . . . . . . . . . . . . . . , v. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. r> s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . . . . !) !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. Z{ $ . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . ~+.M .!% 4$ 4$ 4$ 4$ 4$ -- e. g+.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . h+.S. 4$ 4$ 4$ 4$ 4$ 4$ f. i+.c+.. . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . 6 y# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;( + c ^@ !. !. !. !. !. !. !. j@ p@ - . . . . . . . . . . . . . . : >| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K@ !. !. !. !. !. !. !. !. !. V . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . . . . # ;( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 1/ / . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . j+.U. 4$ 4$ 4$ 4$ 4$ 4$ !% #..1+.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . k+.J+ 4$ 4$ 4$ 4$ 4$ 4$ z& '@ l+.. . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . . z *+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. S+ !) . . . `( !. !. !. !. !. !. !. !. !. y . . . . . . . . . . . . . . . a >( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. =( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I j@ !. !. !. !. !. !. !. b_ e . . . . . . . . . . . ; ,; !. !. !. !. !. !. !. b. . . . . . . . . . . . . . . . . . . . <. !. !. !. !. !. !. !. =+ % . . . . . . . . . . . . . . . . . . D< b; !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. b; h . . . . . . . f t. !. !. !. !. !. !. !. J . . . . . . . . . . . . . . . . . . . (N N..g. -- -- -- -- -- -- g. m+.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . n+.o+.U. -- -- -- -- -- -- d. lt . . . . . } P^ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . _@ !. !. !. !. !. !. !. [# . . . . . . . . . . . . . e n@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. %= m . . . . ^ =+ !. !. !. !. !. !. !. b; u . . . . . . . . . . . . . . . . 4 j+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. n@ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 9, !. !. !. !. !. !. !. C< . . . . . . . . . . . . ; ,; !. !. !. !. !. !. !. b. . . . . . . . . . . . . . . . . . . . <. !. !. !. !. !. !. !. =+ % . . . . . . . . . . . . . . . . . . . }. ^) h+ !. !. !. !. !. !. !. !. !. !. !. !. !. $+ %+ '. . . . . . . . f t. !. !. !. !. !. !. !. J . . . . . . . . . . . . . . . . . . . SS e. %( P] P] P] P] P] z& ;- _N . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p+.;W P] P] P] P] P] P] ;- O] q+.. . . . } s. !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . 2/ !. !. !. !. !. !. !. _. . . . . . . . . . . . . . . ; P 6] !. !. !. !. !. !. !. !. !. !. !. !. {. N^ }# . . . . . . . ) [# k@ !. !. !. !. !. h+ u . . . . . . . . . . . . . . . . . ] I@ 1/ !. !. !. !. !. !. !. !. !. !. !. !. !. !. r> 8> * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = }# a. 5+ 5+ 5+ 5+ 5+ ,% q . . . . . . . . . . . . @ '. a. 5+ 5+ 5+ 5+ 5+ ,% 9 . . . . . . . . . . . . . . . . . . . c a. Q 5+ 5+ 5+ 5+ Y+ L @ . . . . . . . . . . . . . . . . . . . . % . g^ }* (# 9] ~. S+ 1/ 8] ~2 v! 8> }~ a@ }. e ; . . . . . . . > . a. 5+ 5+ 5+ 5+ 5+ Y+ ~ . . . . . . . . . . . . . . . . . . . |O r+.!U !U !U !U !U !U s+.t+.u+.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . wR v+.}S !U !U !U !U !U w+.x+.y+.. . . . ' Z I+ 5+ 5+ 5+ 5+ Q 5+ / . . . . . . . . . . . . . . . . . . . v Y+ 5+ 5+ 5+ 5+ 5+ Y+ q . . . . . . . . . . . . . . . . [ o+ n{ >| ]) S+ ~. T+ z/ (@ u. ,{ ` _ @ . . . . . . . . . . p $= V@ -( (# S+ %+ v . . . . . . . . . . . . . . . . . . . 6 y. ){ ]. s. ~. ~. <' /@ ~2 >( m@ -| Z) [. q [ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 5 n v y 4 e x / . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . < 4 y v 3 7 ^ @ . . . . . . . . . . . . . . . . . f } y n = . . . . . . . . . . . . . . . . . . . . . . g a v v h 6 x ! ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . / q q q q q q n a + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . { v q q q q q n } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . J ~. ~. ~. ~. ~. ~. ~. y# > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p# ~. ~. ~. ~. ~. ~. ~. N^ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z+.A+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.C+.D+.E+.. . . . . . . . . !. !. !. !. !. !. !. ]) > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . J@ !. !. !. !. !. !. !. =+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . F+.G+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.I+.J+.K+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . L+.M+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.O+.P+.K+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q S+.T+.K+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q S+.T+.K+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q S+.T+.K+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . w >+ ){ q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq U+.V+.K+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . [ S -+ P^ !. h+ v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q pq W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.X+.Y+.Z+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ a p@ ^. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q N+.`+. @..@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.@@.#@.$@.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c T+ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.%@.&@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z M! !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ * ^ _ ! ) f & @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + ; f 8 _ ! ] ' # . . . . . . . . . . . . . . . . . . . . . 6 <' !. !. !. !. !. !. i+ b . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . & { ! ! : [ & . . . . . . . . . . . . . . . . . . . . . . + , f ) ! _ 8 = > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > = ] ! ! < f - . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . @ & [ : ! { / = $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . & 8 : ! ! ] ' @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . g f+ _. k+ -( l@ 9] S+ 1/ 6] 7] V@ p@ R. d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . g Y :~ W+ V+ 6] ~2 9] S+ T@ (@ u! m+ 7+ d . . . . . . . . . . . . . 9 H . g+ S 9. ~. !. !. !. !. !. !. 9] Y# S g+ g+ g+ g+ g+ g+ g+ g+ g+ ` m @ . . . . . . . . . . / J H g+ g+ g+ g+ H I , . . . . . . ) Z ;+ 7] P^ S+ S+ ^@ ]. j+ I| G~ S . . . . . . . . . . . . . . . . $ ). n+ b, Z{ /~ `) S+ 9] z/ }* A/ Y( @& h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . [ ` ,{ A/ }* T@ S+ S+ T+ 6] m@ Z) a. } . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . ^ '. D< V@ j+ ]. %+ S+ P^ t. }* k+ <~ [. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . l 8. o@ j+ 8] ^@ S+ S+ 1/ (@ V@ X+ q# 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . @ g+ n@ l@ !. !. !. !. !. !. !. !. !. !. !. !. !. (# Z{ O ( . . . . . . . . . . . . . . . . . . . . . . . . . . . . _ p# ){ l@ !. !. !. !. !. !. !. !. !. !. !. !. !. (# u. J@ w . . . . . . . . . . p# !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ !. !. !. !. !. !. !. !. !. !. =+ % . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . / y. y# !. !. !. !. !. !. !. !. !. !. !. I@ . . . . . . . . . . . . . . } p@ ^. S@ !. !. !. !. !. !. !. !. !. !. !. !. @= z# O. 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . h ;( b_ !. !. !. !. !. !. !. !. !. !. !. !. &+ <# m . @& !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . v j( >( q. !. !. !. !. !. !. !. !. !. !. !. !. T+ -( !) 7 . . . . . . . . . . . . . . . . . . . . . & Y+ V+ ^@ !. !. !. !. !. !. !. !. !. !. !. !. ;| A/ :. 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . i N^ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. /~ a@ < . . . . . . . . . . . . . . . . . . . . . . . . ( $= z/ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. s. j( k . . . . . . . . H+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^) % . . . . . . . . . . h ~. !. !. !. !. !. !. j@ ! . . . u _# !. !. !. !. !. !. !. !. !. !. !. !. &+ e . . . . . . . . . . . . [ $= &+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )^ y. / . . . . . . . . . . . . . . . . . . . . . . . . . f I@ <' !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 9] <. n+ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . b _@ 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. &+ [* 4 . . . . . . . . . . . . . . . . . . k a_ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^@ F[ [. ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . * ;( 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. }* M . . . . . . . . . . . . . . . . . . . . . $ H+ U+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 9] l+ 0 . . . . . . p# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. =+ % . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . z. <' !. !. !. !. !. !. !. !. !. !. !. !. !. ;( . . . . . . . . . . . . I (@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. *+ J . . . . . . . . . . . . . . . . . . . . . . . L _# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. P^ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . Y# {. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. T@ [. . . . . . . . . . . . . . . . . P 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. :. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . 9 ){ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. s. Q . . . . . . . . . . . . . . . . . . . [ Y( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;| 6 . . . . . p# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. =+ % . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ _ . f+ S@ !. !. !. !. !. !. !. !. !. !. !. !. !. M! o . . . . . . . . . . . 5+ <' !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. k@ q# . . . . . . . . . . . . . . . . . . . . . I+ 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . * 2/ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. r. G~ # . . . . . . . . . . . . . Y+ r> !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. b; T . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . W (@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. _~ . . . . . . . . . . . . . . . . . 7 8> !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. -+ & . . . . . H+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. u. % . . . . . . . . . . W ^@ !. !. !. !. !. !. ~. = o @= !. !. !. !. !. !. !. !. !. !. !. !. !. !. V@ . . . . . . . . . . . H+ b; !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. j@ <. . . . . . . . . . . . . . . . . . . . a. r. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . : -| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. n{ - . . . . . . . . . . . y 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. b_ * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . | )^ !. !. !. !. !. !. !. !. !. !. !. ^@ P^ 6] z# )^ P^ S+ !. !. !. !. !. !. !. !. !. !. !. !. Q. . . . . . . . . . . . . . . . z >( !. !. !. !. !. !. !. !. !. !. !. !. 9] P^ l@ U@ ~2 P^ S@ !. !. !. !. !. !. !. !. !. t. ) . . . . . . 0. ~. ~. ~. 9] M! h+ !. !. !. !. !. !. h+ M! 9] ~. ~. ~. ~. ~. ~. ~. ~. ~. ~. k+ % . . . . . . . . . . W ^@ !. !. !. !. !. !. k@ 4 m@ !. !. !. !. !. !. j@ P^ *+ U+ %+ q. !. !. !. H . . . . . . . . . . H+ q. !. !. !. !. !. !. !. !. !. !. i+ -( W+ l+ (. A/ t. S+ !. !. !. !. !. !. !. !. !. !. r. [. . . . . . . . . . . . . . . . . . I+ M! !. !. !. !. !. !. !. !. !. !. !. h+ ^@ s. /~ (@ P^ 9] !. !. !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . ( {> !. !. !. !. !. !. !. !. !. !. !. ~. P^ ]. '{ ]. P^ ^@ !. !. !. !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . , /. !. !. !. !. !. !. !. !. !. !. !. i+ (# _# l@ P^ b; !. !. !. !. !. !. !. 2/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.-@.;@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . ^ _# !. !. !. !. !. !. !. !. !. S+ V@ p# 4 / - % = / W y. %= r> !. !. !. !. !. !. !. !. !. 9] U . . . . . . . . . . . . . / -( !. !. !. !. !. !. !. !. !. !. P^ !{ K@ a 8 = % = / b o+ _@ ,; !. !. !. !. !. r> L . . . . . . . < q q q z q# 9] !. !. !. !. !. !. S@ 5+ 1 q q q q q q q q q n 5 + . . . . . . . . . . W ^@ !. !. !. !. !. !. k@ <# !. !. !. !. !. s. ,{ t / - & x H v. !. /~ = . . . . . . . . . M ^@ !. !. !. !. !. !. !. !. !. }* >+ c , . . . $ & h O. >| !. !. !. !. !. !. !. !. !. ]) p . . . . . . . . . . . . . . . ` j@ !. !. !. !. !. !. !. !. !. !. >( ,{ ` 5 / - , / a 4+ 7] !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . $ j( !. !. !. !. !. !. !. !. !. !. /. 4+ q / * % * / p Q. I| s. !. !. !. !. !. !. !. !. !. !. 9. . . . . . . . . . }. q. !. !. !. !. !. !. !. !. q. A/ o+ ~ ' ; = 8 L =( z# !. !. !. !. !. I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.>@.,@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.)@.!@.. . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . @ )) !. !. !. !. !. !. !. !. h+ 1' y . . . . . . . . . . . i n@ !. !. !. !. !. !. !. !. !. U+ ! . . . . . . . . . . . . <# !. !. !. !. !. !. !. !. !. b; }~ | . . . . . . . . . . . / t (. i+ !. !. [* . . . . . . . . . . . . . c <' !. !. !. !. !. !. i+ 1 . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. h+ q. !. !. !. !. ){ W . . . . . . . . g+ '. . . . . . . . . . ( ^. !. !. !. !. !. !. !. !. b; += ^ . . . . . . . . . . < [# $+ !. !. !. !. !. !. !. !. %= > . . . . . . . . . . . . . 5 (# !. !. !. !. !. !. !. !. !. 1/ Y# _ . . . . . . . . . ' y. ~. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . !) !. !. !. !. !. !. !. !. !. =+ I @ . . . . . . . . . . 3 ,{ b; !. !. !. !. !. !. !. !. S@ m . . . . . . . . <~ !. !. !. !. !. !. !. !. w! 7+ @ . . . . . . . . = q# 7] !. !. 9, : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q qu ~@.{@.]@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@./@.(@._@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . !) !. !. !. !. !. !. !. !. {. [. . . . . . . . . . . . . . . . y. M! !. !. !. !. !. !. !. !. >+ . . . . . . . . . . . H+ !. !. !. !. !. !. !. !. !. ;| I . . . . . . . . . . . . . . . . 2 {> z# f . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. !. !. !. !. l+ * . . . . . . . . . . . . . . . . . . . . `( !. !. !. !. !. !. !. !. ~. b. . . . . . . . . . . . . . . Y+ r> !. !. !. !. !. !. !. !. p# . . . . . . . . . . . . > N^ !. !. !. !. !. !. !. !. !. )) p . . . . . . . . . . . . . j `) !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . Y j@ !. !. !. !. !. !. !. r. _~ > . . . . . . . . . . . . . . ` ]) !. !. !. !. !. !. !. !. b, @ . . . . . . = _# !. !. !. !. !. !. !. ~. . . . . . . . . . . . . . - 8. ~. W+ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.:@.<@.[@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . 0 S@ !. !. !. !. !. !. !. T@ k . . . . . . . . . . . . . . . . . 6+ j@ !. !. !. !. !. !. !. ;| < . . . . . . . . . 3 <' !. !. !. !. !. !. !. !. U+ W . . . . . . . . . . . . . . . . . . & ~ . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. !. !. !. I| ; . . . . . . . . . . . . . . . . . . . . y j@ !. !. !. !. !. !. !. r. 0. . . . . . . . . . . . . . . . . a@ q. !. !. !. !. !. !. !. y# ^ . . . . . . . . . . . 8. !. !. !. !. !. !. !. !. !. i( $ . . . . . . . . . . . . . . . . 9] !. !. !. !. !. !. !. u! . . . . . . . . . . . = t. !. !. !. !. !. !. !. b; I+ . . . . . . . . . . . . . . . . . u &+ !. !. !. !. !. !. !. b; u . . . . . . ) /@ !. !. !. !. !. !. !. /. . . . . . . . . . . . . . . . s L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q }@.|@.[@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . ,{ !. !. !. !. !. !. !. k@ T . . . . . . . . . . . . . . . . . . . O. !. !. !. !. !. !. !. !. !) . . . . . . . . . <# !. !. !. !. !. !. !. !. 9, | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. !. !. *+ [ . . . . . . . . . . . . . . . . . . . . . i( !. !. !. !. !. !. !. !. o@ . . . . . . . . . . . . . . . . . . %= !. !. !. !. !. !. !. !. 7+ . . . . . . . . . . w {. !. !. !. !. !. !. !. !. ,{ % . . . . . . . . . . . . . . . . . C< !. !. !. !. !. !. !. u! . . . . . . . . . . . 0. !. !. !. !. !. !. !. h+ 9. . . . . . . . . . . . . . . . . . . . ` j@ !. !. !. !. !. !. !. b, . . . . . . e S@ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q }@.|@.[@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . a @= !. !. !. !. !. !. !. 9. . . . . . . . . . . . . . . . . . . . . # V+ !. !. !. !. !. !. !. 7] - . . . . . . . c s. !. !. !. !. !. !. !. r. }# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. !. M! U . . . . . . . . . . . . . . . . . . . . . 6 @= !. !. !. !. !. !. !. &+ g . . . . . . . . . . . . . . . . . . y 9] !. !. !. !. !. !. !. 8> + . . . . . . . . . !) !. !. !. !. !. !. !. !. j+ & . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. u! . . . . . . . . . . [ /~ !. !. !. !. !. !. !. <# . . . . . . . . . . . . . . . . . . . . . ;( !. !. !. !. !. !. !. P^ 6 . . . . . g ^@ !. !. !. !. !. !. !. v. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q }@.|@.[@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . 2/ !. !. !. !. !. !. !. {> ; . . . . . . . . . . . . . . . . . . . . . K $+ !. !. !. !. !. !. k@ | . . . . . . . x. !. !. !. !. !. !. !. !. <# + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. !. b, . . . . . . . . . . . . . . . . . . . . . . X+ !. !. !. !. !. !. !. !. J@ . . . . . . . . . . . . . . . . . . . . n{ !. !. !. !. !. !. !. ~. u . . . . . . . . ^ ~2 !. !. !. !. !. !. !. <' m . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . Q. !. !. !. !. !. !. !. ;| x . . . . . . . . . . . . . . . . . . . . . 6 w! !. !. !. !. !. !. q. 7+ . . . . . ] l@ !. !. !. !. !. !. !. /~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq 1@.2@.[@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . : @= !. !. !. !. !. !. h+ . . . . . . . . . . . . . . . . . . . . . . . , /~ !. !. !. !. !. !. !. 5+ . . . . . . ! T+ !. !. !. !. !. !. !. @= w . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. S+ s . . . . . . . . . . . . . . . . . . . . . * z# !. !. !. !. !. !. !. 1/ 9 . . . . . . . . . . . . . . . . . . . . o+ q. !. !. !. !. !. !. !. Y# . . . . . . . . P. !. !. !. !. !. !. !. !. Z) . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . + 7] !. !. !. !. !. !. !. X+ . . . . . . . . . . . . . . . . . . . . . . . F[ !. !. !. !. !. !. !. Z( . . . . . ; /. !. !. !. !. !. !. !. ~. S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q U+.U+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.3@.4@.[@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . g+ !. !. !. !. !. !. !. 6] ^ . . . . . . . . . . . . . . . . . . . . . . . Z( !. !. !. !. !. !. !. 2/ . . . . . . f+ !. !. !. !. !. !. !. !. (. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. 7] > . . . . . . . . . . . . . . . . . . . . . 3 <' !. !. !. !. !. !. !. W+ . . . . . . . . . . . . . . . . . . . . . _ (# !. !. !. !. !. !. !. j( . . . . . . . * {> !. !. !. !. !. !. !. %+ | . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . c @= !. !. !. !. !. !. <' z . . . . . . . . . . . . . . . . . . . . . . . a. !. !. !. !. !. !. !. a_ - . . . . . G~ !. !. !. !. !. !. !. !. 7] / . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q N+.5@.6@.7@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.9@.0@.B... . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . ;( !. !. !. !. !. !. !. ,{ . . . . . . . . . . . . . . . . . . . . . . . . I+ !. !. !. !. !. !. !. n@ . . . . . . <~ !. !. !. !. !. !. !. b; I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. ,{ . . . . . . . . . . . . . . . . . . . . . . b. !. !. !. !. !. !. !. !. 6+ . . . . . . . . . . . . . . . . . . . . . . u! !. !. !. !. !. !. !. v! f . . . . . . 0 9] !. !. !. !. !. !. !. b, . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . I+ !. !. !. !. !. !. !. 7] . . . . . . . . . . . . . . . . . . . . . . . . o q. !. !. !. !. !. !. b_ < . . . . . r j@ !. !. !. !. !. !. !. !. F[ ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.%@.a@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . , j+ !. !. !. !. !. !. !. Q . . . . . . . . . . . . . . . . . . . . . . . . s !. !. !. !. !. !. !. {> @ . . . . % V+ !. !. !. !. !. !. !. >( ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. I+ . . . . . . . . . . . . . . . . . . . . . . [# !. !. !. !. !. !. !. b; c . . . . . . . . . . . . . . . . . . . . . . Z( !. !. !. !. !. !. !. 9] 5 . . . . . . 7+ !. !. !. !. !. !. !. !. R . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . ,{ !. !. !. !. !. !. !. Z( . . . . . . . . . . . . . . . . . . . . . . . . { i+ !. !. !. !. !. !. (# g . . . . . @ N^ !. !. !. !. !. !. !. !. !. {> L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . o i+ !. !. !. !. !. !. q. _. q# 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ q# x. q. !. !. !. !. !. !. y# ; . . . . 4 w! !. !. !. !. !. !. !. %= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. h+ L . . . . . . . . . . . . . . . . . . . . . . z# !. !. !. !. !. !. !. ]. 8 . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. I . . . . . . 2/ !. !. !. !. !. !. !. <' w . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . 8 /~ !. !. !. !. !. !. !. )) q# 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ z. a@ k@ !. !. !. !. !. !. r> 4 . . . . . . a T+ !. !. !. !. !. !. !. !. !. r. Y( u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . g+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ]) , . . . . s !. !. !. !. !. !. !. !. X+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. b; h . . . . . . . . . . . . . . . . . . . . . # /@ !. !. !. !. !. !. !. N^ # . . . . . . . . . . . . . . . . . . . . . . j !. !. !. !. !. !. !. !. Q . . . . . # }* !. !. !. !. !. !. !. {> - . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . w S@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 2 . . . . . . . [. $+ !. !. !. !. !. !. !. !. !. !. ^@ V@ K - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . 6+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;| , . . . . R. !. !. !. !. !. !. !. h+ R. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. M! w . . . . . . . . . . . . . . . . . . . . . ] (# !. !. !. !. !. !. !. `( . . . . . . . . . . . . . . . . . . . . . . . h q. !. !. !. !. !. !. !. H+ . . . . . ! ;| !. !. !. !. !. !. !. <~ . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . | !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ | . . . . . . . . $= !. !. !. !. !. !. !. !. !. !. !. !. !. V+ Y+ = . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . 9. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. t. > . . . . ,% !. !. !. !. !. !. !. $+ i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ : . . . . . . . . . . . . . . . . . . . . . d w! !. !. !. !. !. !. !. _. . . . . . . . . . . . . . . . . . . . . . . . 2 j@ !. !. !. !. !. !. !. I@ . . . . . b T+ !. !. !. !. !. !. !. N . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . k !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. S+ c . . . . . . . . . $= 9] !. !. !. !. !. !. !. !. !. !. !. !. !. >| <. ( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . D< !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^) + . . . . 4+ !. !. !. !. !. !. !. j@ o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . W i+ !. !. !. !. !. !. !. X+ . . . . . . . . . . . . . . . . . . . . . . . p k@ !. !. !. !. !. !. !. Z( . . . . . m <' !. !. !. !. !. !. !. 9. . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . }# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;| ~ . . . . . . . . . . J t. !. !. !. !. !. !. !. !. !. !. !. !. !. !. (@ 7+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. [# . . . . . Z) !. !. !. !. !. !. !. S+ 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . j ~. !. !. !. !. !. !. !. J@ . . . . . . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. o@ . . . . . I r. !. !. !. !. !. !. !. Q . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . 0. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. X( > . . . . . . . . . . . _ m+ i+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. I| 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . l+ !. !. !. !. !. !. !. M! }~ [~ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ g^ V . . . . . `( !. !. !. !. !. !. !. S@ : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . u S@ !. !. !. !. !. !. !. n+ . . . . . . . . . . . . . . . . . . . . . . . 5 {. !. !. !. !. !. !. !. w. . . . . . b. !. !. !. !. !. !. !. !. [. . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . y. !. !. !. !. !. !. !. !. W+ ;+ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ }~ Z . . . . . . . . . . . . . . z }~ ^@ !. !. !. !. !. !. !. !. !. !. !. !. !. ]. j . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . <~ !. !. !. !. !. !. !. k@ ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G~ !. !. !. !. !. !. !. M! 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . | P^ !. !. !. !. !. !. !. G~ . . . . . . . . . . . . . . . . . . . . . . . | 9] !. !. !. !. !. !. !. [* . . . . . z. !. !. !. !. !. !. !. !. ,% . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . Y+ !. !. !. !. !. !. !. !. i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . n }~ k@ !. !. !. !. !. !. !. !. !. !. !. !. k@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . O. !. !. !. !. !. !. !. S@ b . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . :. !. !. !. !. !. !. !. b; v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . e 1/ !. !. !. !. !. !. !. <~ . . . . . . . . . . . . . . . . . . . . . . . z r. !. !. !. !. !. !. !. $= . . . . . . $+ !. !. !. !. !. !. !. 8. . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . H !. !. !. !. !. !. !. !. }# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | `( @= !. !. !. !. !. !. !. !. !. !. !. {. m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. r> ). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . [. !. !. !. !. !. !. !. q. U . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . f )^ !. !. !. !. !. !. !. w. . . . . . . . . . . . . . . . . . . . . . . . ). !. !. !. !. !. !. !. !. 0. . . . . . t ~. !. !. !. !. !. !. !. O. . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . m !. !. !. !. !. !. !. !. 0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z j( j@ !. !. !. !. !. !. !. !. !. !. 7] ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . b. !. !. !. !. !. !. !. q. ` . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . g+ !. !. !. !. !. !. !. !. ,% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . + z/ !. !. !. !. !. !. !. -| # . . . . . . . . . . . . . . . . . . . . . . 6+ !. !. !. !. !. !. !. !. Z . . . . . n i+ !. !. !. !. !. !. !. [~ . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . b q. !. !. !. !. !. !. !. I@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ). '{ !. !. !. !. !. !. !. !. !. !. 8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . T h+ !. !. !. !. !. !. !. += . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . u j@ !. !. !. !. !. !. !. [~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . /. !. !. !. !. !. !. !. 6] / . . . . . . . . . . . . . . . . . . . . . . =( !. !. !. !. !. !. !. h+ y . . . . . b {. !. !. !. !. !. !. !. {> - . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . 7 T+ !. !. !. !. !. !. !. ){ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ( -+ !. !. !. !. !. !. !. !. !. *+ / . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . 9 ;| !. !. !. !. !. !. !. =+ $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . { >( !. !. !. !. !. !. !. m@ # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . G~ !. !. !. !. !. !. !. 9] 7 . . . . . . . . . . . . . . . . . . . . . . u! !. !. !. !. !. !. !. 9, { . . . . . / 8] !. !. !. !. !. !. !. @= e . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . , ^) !. !. !. !. !. !. !. ;| { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . g^ !. !. !. !. !. !. !. !. $+ T . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. )^ # . . . . . . . . . . . . . + k+ !. !. !. !. !. !. !. ]) 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . !{ !. !. !. !. !. !. !. T+ 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. r> r . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . !. !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . < 9, !. !. !. !. !. !. !. N^ $ . . . . . . v. !. !. !. !. !. !. !. !. '. . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . D< !. !. !. !. !. !. !. b; K . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 x! !. !. !. !. !. !. !. !. Y# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. (# * . . . . . . . . . . . . . . $= !. !. !. !. !. !. !. !. <. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $= !. !. !. !. !. !. !. !. n+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 ^@ !. !. !. !. !. !. q. T . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . 0 k@ !. !. !. !. !. !. !. m+ . . . . . . . . . . . . . . . . . . . . . z. q. !. !. !. !. !. !. !. p@ . . . . . . . H+ !. !. !. !. !. !. !. !. I| . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . J b; !. !. !. !. !. !. !. w. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6+ q. !. !. !. !. !. !. !. i( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . g+ !. !. !. !. !. !. !. w! ~ . . . . . . . . . . . . . . q !. !. !. !. !. !. !. !. b_ * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . l q. !. !. !. !. !. !. !. ]. & . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 %+ !. !. !. !. !. !. !. q# . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . = j+ !. !. !. !. !. !. !. x! = . . . . . . . . . . . . . . . . . . . . v. !. !. !. !. !. !. !. !. f+ . . . . . . . ). !. !. !. !. !. !. !. !. w! 9 . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . ^ (# !. !. !. !. !. !. !. S@ b . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . d k@ !. !. !. !. !. !. !. W+ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T b; !. !. !. !. !. !. S@ v . . . . . . . . . . . . . . & x! !. !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - 7] !. !. !. !. !. !. !. !. 8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] {. !. !. !. !. !. !. !. 4+ . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . O. !. !. !. !. !. !. !. r> I . . . . . . . . . . . . . . . . . . . h 9] !. !. !. !. !. !. !. z/ ^ . . . . . . . ( b_ !. !. !. !. !. !. !. !. p@ . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . I| !. !. !. !. !. !. !. !. ;( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % ~2 !. !. !. !. !. !. !. /. > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m <' !. !. !. !. !. !. !. p# . . . . . . . . . . . . . . . 6+ h+ !. !. !. !. !. !. !. &+ 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6+ !. !. !. !. !. !. !. !. ^@ u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , 9, !. !. !. !. !. !. !. !{ . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . w k@ !. !. !. !. !. !. !. {> $ . . . . . . . . . . . . . . . . . . V@ !. !. !. !. !. !. !. !. D< . . . . . . . . . G~ !. !. !. !. !. !. !. !. S@ i . . . . . . . . . . . . . . . . . . . 9. !. !. !. !. !. !. !. u! . . . . . . . . . . o i+ !. !. !. !. !. !. !. j@ ` . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . < 1/ !. !. !. !. !. !. !. !{ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . b w! !. !. !. !. !. !. !. =+ % . . . . . . . . . . . . . . ; m@ !. !. !. !. !. !. !. !. _# { . . . . . . . . . . . . . . . . . . . . . % . . . . . . . . . . . . . . / 6] !. !. !. !. !. !. !. !. >| 7 . . . . . . . . . . . . . . . . . . . . - 8 . . . . . . . . . . . . . # 7] !. !. !. !. !. !. !. s. _ . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . j( !. !. !. !. !. !. !. !. Y+ . . . . . . . . . . . . . . . . . Z j@ !. !. !. !. !. !. !. k@ p . . . . . . . . . c k@ !. !. !. !. !. !. !. !. /~ e . . . . . . . . . . . . . . . . . . P. !. !. !. !. !. !. !. u! . . . . . . . . . . . 2/ !. !. !. !. !. !. !. !. w! W . . . . . . . . . . . . . . . . . . . . . ; . . . . . . . . . . . . . . . ). 5 . . . . . . . . . . . . . . . . M r> !. !. !. !. !. !. !. 2/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.-@.b@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ( y# !. !. !. !. !. !. !. h+ <. . . . . . . . . . . . . . . . }# !. !. !. !. !. !. !. !. !. ){ x . . . . . . . . . . . . . . . . . . 8 o@ j( . . . . . . . . . . . . . . . p# !. !. !. !. !. !. !. !. !. -( | . . . . . . . . . . . . . . . . . . 5 :# W+ . . . . . . . . . . . . . . _. !. !. !. !. !. !. !. !. O. . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . k r. !. !. !. !. !. !. !. s. l . . . . . . . . . . . . . . . m 1/ !. !. !. !. !. !. !. !. j( . . . . . . . . . . . j( !. !. !. !. !. !. !. !. !. _# 0 . . . . . . . . . . . . . . . . ; :# !. !. !. !. !. !. !. u! . . . . . . . . . . . b <' !. !. !. !. !. !. !. !. b_ l . . . . . . . . . . . . . . . . . . # !) =+ ^ . . . . . . . . . . . . . ' >| &+ I+ # . . . . . . . . . . . . . . I@ !. !. !. !. !. !. !. !. !) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.c@.d@.e@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.E+._@.. . . . . . . . . . )) !. !. !. !. !. !. !. !. <' f+ . . . . . . . . . . . . . . > n@ !. !. !. !. !. !. !. !. !. 8] K . . . . . . . . . . . . . . . $ '. ,; !. h+ J . . . . . . . . . . . . . . & 8> !. !. !. !. !. !. !. !. !. ;| Z # . . . . . . . . . . . . . . 8 :. &+ !. h+ k . . . . . . . . . . . . . . !. !. !. !. !. !. !. !. %+ M . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . $ ,{ !. !. !. !. !. !. !. !. )^ u . . . . . . . . . . . . . v z/ !. !. !. !. !. !. !. !. 1/ 4 . . . . . . . . . . . h k@ !. !. !. !. !. !. !. !. !. )^ }# # . . . . . . . . . . . . . x b, !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . D< !. !. !. !. !. !. !. !. !. P^ P $ . . . . . . . . . . . . . . . n N^ !. !. n+ . . . . . . . . . . . . . U !. !. !. A/ I $ . . . . . . . . . . . u @= !. !. !. !. !. !. !. M! s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q qu g@.h@.i@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.k@.l@.. . . . . . . . . . Q. !. !. !. !. !. !. !. !. !. r. x. 0 . . . . . . . . . . . . . _ v! !. !. !. !. !. !. !. !. !. r. (. M @ . . . . . . . . . . : ` ){ $+ !. !. !. 7] - . . . . . . . . . . . . . . 6 ]. !. !. !. !. !. !. !. !. !. !. =+ R { . . . . . . . . . . b G+ ]. !. !. !. !. l+ + . . . . . . . . . . . . : 8] !. !. !. !. !. !. !. !. 9, }# + . . . . . . . . l :. ^ . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . . { >( !. !. !. !. !. !. !. !. k@ n+ [ . . . . . . . . . & y. k@ !. !. !. !. !. !. !. !. h+ a. . . . . . . . . . . . . . 8. !. !. !. !. !. !. !. !. !. !. h+ /. . ) . . . . . . . . . } n+ /@ !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . > ]: !. !. !. !. !. !. !. !. !. !. =+ H = . . . . . . . . . . ' j (. S+ !. !. !. 1/ 5 . . . . . . . . . . . . j( !. !. !. !. $+ =+ R. ] . . . . . . . + . 6] !. !. !. !. !. !. !. !. b_ f . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q pq U+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.m@.Q+.. . . . . . . . . . ~ ;| !. !. !. !. !. !. !. !. !. !. ]) k+ ,{ [. . . . . . . . . . . . 2 (# !. !. !. !. !. !. !. !. !. !. M! U@ w. b. j 1 e b t L $= -| >( !. !. !. !. !. !. !. K@ . . . . . . . . . . . . . . . s S+ !. !. !. !. !. !. !. !. !. !. !. b_ v. $= I r } x M ` [* X( 1/ !. !. !. !. !. !. S+ z . . . . . . . . . . . . . G+ !. !. !. !. !. !. !. !. !. !. X( $= }. b 7 M z. O. X( ~. !. 3 . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . . . '. r. !. !. !. !. !. !. !. !. !. x! m+ k g ( / [ : | D< ,; !. !. !. !. !. !. !. !. !. !. n{ $ . . . . . . . . . . . . . > -| !. !. !. !. !. !. !. !. !. !. !. !. t. N^ $= R j | e V Q I| ;| !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . 8 z# !. !. !. !. !. !. !. !. !. !. !. ^. (. ,% s y e } k t <. F[ }* $+ !. !. !. !. !. !. g^ . . . . . . . . . . . ~ T@ !. !. !. !. !. !. !. 6] i( q# V 7 n R. a@ A/ !. !. !. !. !. !. !. !. !. !. O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q R+.n@.. . . . . . . . . . . !) !. !. !. !. !. !. !. !. !. !. !. !. !. n@ . . . . . . . . . . . . J <' !. !. !. !. !. !. !. !. !. !. !. !. !. h+ r. r> b; h+ h+ !. !. !. !. !. !. !. !. !. !. &+ d . . . . . . . . . . . . . . . P 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. q. j@ r> q. !. !. !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . ( z/ !. !. !. !. !. !. !. !. !. !. !. !. b; r> q. !. !. !. !. !. R . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . . . . O. !. !. !. !. !. !. !. !. !. !. !. q. S+ z/ 6] b_ P^ b; !. !. !. !. !. !. !. !. !. !. !. 7] ~ . . . . . . . . . . . . . . . 6 y# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ b; r> $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . p z/ !. !. !. !. !. !. !. !. !. !. !. !. !. h+ $+ r> j@ q. h+ !. !. !. !. !. !. !. !. !. !. j@ T . . . . . . . . . . P !. !. !. !. !. !. !. !. !. !. !. $+ r> $+ !. !. !. !. !. !. !. !. !. !. !. !. 6] [ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q R+.n@.. . . . . . . . . . . < x! !. !. !. !. !. !. !. !. !. !. !. !. v. . . . . . . . . . . . . . '. ;| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. X+ . . . . . . . . . . . . . . . . }# s. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. k@ z . . . . . . . . . . . . . I j@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. >+ . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . y. $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. X( ! . . . . . . . . . . . . . . . . . a >| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . b j+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. :# + . . . . . . . . # A/ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^@ }. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q R+.n@.. . . . . . . . . . . . 0 ~2 !. !. !. !. !. !. !. !. !. !. !. )) . . . . . . . . . . . . . . | '{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. =+ b . . . . . . . . . . . . . . . . . y b_ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. M! R. . . . . . . . . . . . . . . $= !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. l+ . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q. M! !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. -| < . . . . . . . . . . . . . . . . . . . } _# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. M! y# !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . { n{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. >| r . . . . . . . . . W !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. %+ R. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q R+.n@.. . . . . . . . . . . . . v ,; !. !. !. !. !. !. !. !. !. !. )) . . . . . . . . . . . . . . . / ;( ^@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ]. 9. - . . . . . . . . . . . . . . . . . . . x }~ S@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. r> )) y % . . . . . . . . . . . . . . . !) h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. m@ + . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . '. '{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. T+ _~ , . . . . . . . . . . . . . . . . . . . . . < j( j@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^@ 7+ H+ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . $ n+ ]) !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. T@ :~ { . . . . . . . . . . w F[ <' !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ~2 g+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o@.:@.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.:@.Q+.. . . . . . . . . . . . . . ^ =( %+ !. !. !. !. !. !. !. !. )) . . . . . . . . . . . . . . . . . u (. r. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. r. m@ P. < . . . . . . . . . . . . . . . . . . . . . . . ). v. $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. w! <# L . . . . . . . . . . . . . . . . . . . 0. `) !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. T+ g . . . . . . . q b; !. !. !. !. !. !. q. ~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , O U+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. b; 1' 2 . . . . . . . . . . . . . . . . . . . . . . . . . T u. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. q. k+ l . :. !. !. !. !. !. !. !. V+ . . . . . . . . . . . . . . . . . . . p _. k@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. $+ t. I@ c . . . . . . . . . . . . . . m i( P^ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. S+ g^ 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p@.q@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.q@.s@.. . . . . . . . . . . . . . . . c X+ -( ~. !. !. !. !. !. N^ . . . . . . . . . . . . . . . . . . . ). 2/ 7] S+ !. !. !. !. !. !. !. !. !. !. !. !. b_ W+ :. h - . . . . . . . . . . . . . . . . . . . . . . . . . . + ). [# m@ %+ !. !. !. !. !. !. !. !. !. !. !. !. @= (@ )) b. _ . . . . . . . . . . . . . . . . . . . . . . c _@ &+ !. !. !. !. !. !. !. !. !. !. !. !. ]) v! 1' e . . . . . . . | >( (# ;| ;| ;| ;| (# y# { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . { Q. b, 8] !. !. !. !. !. !. !. !. !. !. !. <' U@ Z) ). . . . . . . . . . . . . . . . . . . . . . . . . . . . . , 7+ -+ U+ !. !. !. !. !. !. !. !. !. !. j@ 6] l+ k # . . b. v! ,; ,; ,; ,; ,; -( m+ . . . . . . . . . . . . . . . . . . . . . 0 :~ {> P^ !. !. !. !. !. !. !. !. !. !. !. !. /@ A/ I@ i / . . . . . . . . . . . . . . . . . . ~ Y+ V@ z/ b; !. !. !. !. !. !. !. !. !. !. !. S@ ,; G~ 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t@.u@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.u@.w@.. . . . . . . . . . . . . . . . . . * l o+ C< (. u! x! G~ . . . . . . . . . . . . . . . . . . . . . , V <. Z) l+ :# ,; 7] :# (. ;( !) 9. L { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ n <. D< o@ b, U@ 7] j+ W+ l+ j( Y# . o [ . . . . . . . . . . . . . . . . . . . . . . . . . . . c 5+ _@ %= 7] 7] '{ b, l+ Y( O^ @& '. 4 ' . . . . . . . . . ; w 5 } } } } 5 d # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . g Y $= Z( 1' =+ ,; '{ b, g^ D< <. n # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ! . >+ C< (. ^) j+ b, 1' m+ Q. i ) . . . . . # = & & & & & * ; . . . . . . . . . . . . . . . . . . . . . . . . 1 I+ O^ j( W+ _# 7] =+ (. w. O. y. S 6 . . . . . . . . . . . . . . . . . . . . . . . . . 7 k 5+ <~ (. :# 7] j+ 7] #= (. += q# m & . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ , # . . . . . . . . . . . . . . . . . . . . . . . . . . @ ; % @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + % % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ ; % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ % % % @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "}; diff --git a/parcels_label_name.txt b/parcels_label_name.txt new file mode 100644 index 0000000..9fcf3a0 --- /dev/null +++ b/parcels_label_name.txt @@ -0,0 +1,82 @@ +1 L_VCcm +2 L_VCl +3 L_VCs +4 L_Cu +5 L_VCrm +6 L_ITCm +7 L_ITCr +8 L_MTCc +9 L_STCc +10 L_STCr +11 L_MTCr +13 L_IPCv +14 L_IPCd +15 L_SPC +16 L_SPCm +17 L_PCm +19 L_Sv +20 L_Sdl +21 L_Sdm +12 L_ICC +18 L_PCC +30 L_MCC +40 L_ACC +22 L_Mv +23 L_Mdl +24 L_Mdm +25 L_PMrv +26 L_PMdl +27 L_PMdm +28 L_PFcdl +29 L_PFcdm +31 L_PFrvl +32 L_Pfrdli +33 L_Pfrdls +34 L_PFrd +35 L_PFrm +36 L_OFCvl +37 L_OFCv +38 L_OFCvm +39 L_PFCvm +41 L_Insula +101 R_VCcm +102 R_VCl +103 R_VCs +104 R_Cu +105 R_VCrm +106 R_ITCm +107 R_ITCr +108 R_MTCc +109 R_STCc +110 R_STCr +111 R_MTCr +113 R_IPCv +114 R_IPCd +115 R_SPC +116 R_SPCm +117 R_PCm +119 R_Sv +120 R_Sdl +121 R_Sdm +112 R_ICC +118 R_PCC +130 R_MCC +140 R_ACC +122 R_Mv +123 R_Mdl +124 R_Mdm +125 R_PMrv +126 R_PMdl +127 R_PMdm +128 R_PFcdl +129 R_PFcdm +131 R_PFrvl +132 R_Pfrdli +133 R_Pfrdls +134 R_PFrd +135 R_PFrm +136 R_OFCvl +137 R_OFCv +138 R_OFCvm +139 R_PFCvm +141 R_Insula diff --git a/parcels_label_name_AAL.txt b/parcels_label_name_AAL.txt new file mode 100644 index 0000000..9bdadb3 --- /dev/null +++ b/parcels_label_name_AAL.txt @@ -0,0 +1,116 @@ +2001 Precentral_L +2002 Precentral_R +2101 Frontal_Sup_L +2102 Frontal_Sup_R +2111 Frontal_Sup_Orb_L +2112 Frontal_Sup_Orb_R +2201 Frontal_Mid_L +2202 Frontal_Mid_R +2211 Frontal_Mid_Orb_L +2212 Frontal_Mid_Orb_R +2301 Frontal_Inf_Oper_L +2302 Frontal_Inf_Oper_R +2311 Frontal_Inf_Tri_L +2312 Frontal_Inf_Tri_R +2321 Frontal_Inf_Orb_L +2322 Frontal_Inf_Orb_R +2331 Rolandic_Oper_L +2332 Rolandic_Oper_R +2401 Supp_Motor_Area_L +2402 Supp_Motor_Area_R +2501 Olfactory_L +2502 Olfactory_R +2601 Frontal_Sup_Medial_L +2602 Frontal_Sup_Medial_R +2611 Frontal_Med_Orb_L +2612 Frontal_Med_Orb_R +2701 Rectus_L +2702 Rectus_R +3001 Insula_L +3002 Insula_R +4001 Cingulum_Ant_L +4002 Cingulum_Ant_R +4011 Cingulum_Mid_L +4012 Cingulum_Mid_R +4021 Cingulum_Post_L +4022 Cingulum_Post_R +4101 Hippocampus_L +4102 Hippocampus_R +4111 ParaHippocampal_L +4112 ParaHippocampal_R +4201 Amygdala_L +4202 Amygdala_R +5001 Calcarine_L +5002 Calcarine_R +5011 Cuneus_L +5012 Cuneus_R +5021 Lingual_L +5022 Lingual_R +5101 Occipital_Sup_L +5102 Occipital_Sup_R +5201 Occipital_Mid_L +5202 Occipital_Mid_R +5301 Occipital_Inf_L +5302 Occipital_Inf_R +5401 Fusiform_L +5402 Fusiform_R +6001 Postcentral_L +6002 Postcentral_R +6101 Parietal_Sup_L +6102 Parietal_Sup_R +6201 Parietal_Inf_L +6202 Parietal_Inf_R +6211 SupraMarginal_L +6212 SupraMarginal_R +6221 Angular_L +6222 Angular_R +6301 Precuneus_L +6302 Precuneus_R +6401 Paracentral_Lobule_L +6402 Paracentral_Lobule_R +7001 Caudate_L +7002 Caudate_R +7011 Putamen_L +7012 Putamen_R +7021 Pallidum_L +7022 Pallidum_R +7101 Thalamus_L +7102 Thalamus_R +8101 Heschl_L +8102 Heschl_R +8111 Temporal_Sup_L +8112 Temporal_Sup_R +8121 Temporal_Pole_Sup_L +8122 Temporal_Pole_Sup_R +8201 Temporal_Mid_L +8202 Temporal_Mid_R +8211 Temporal_Pole_Mid_L +8212 Temporal_Pole_Mid_R +8301 Temporal_Inf_L +8302 Temporal_Inf_R +9001 Cerebelum_Crus1_L +9002 Cerebelum_Crus1_R +9011 Cerebelum_Crus2_L +9012 Cerebelum_Crus2_R +9021 Cerebelum_3_L +9022 Cerebelum_3_R +9031 Cerebelum_4_5_L +9032 Cerebelum_4_5_R +9041 Cerebelum_6_L +9042 Cerebelum_6_R +9051 Cerebelum_7b_L +9052 Cerebelum_7b_R +9061 Cerebelum_8_L +9062 Cerebelum_8_R +9071 Cerebelum_9_L +9072 Cerebelum_9_R +9081 Cerebelum_10_L +9082 Cerebelum_10_R +9100 Vermis_1_2 +9110 Vermis_3 +9120 Vermis_4_5 +9130 Vermis_6 +9140 Vermis_7 +9150 Vermis_8 +9160 Vermis_9 +9170 Vermis_10 diff --git a/parcels_label_name_AALDilate.txt b/parcels_label_name_AALDilate.txt new file mode 100644 index 0000000..cf33639 --- /dev/null +++ b/parcels_label_name_AALDilate.txt @@ -0,0 +1,116 @@ +1 Precentral_L +2 Precentral_R +3 Frontal_Sup_L +4 Frontal_Sup_R +5 Frontal_Sup_Orb_L +6 Frontal_Sup_Orb_R +7 Frontal_Mid_L +8 Frontal_Mid_R +9 Frontal_Mid_Orb_L +10 Frontal_Mid_Orb_R +11 Frontal_Inf_Oper_L +12 Frontal_Inf_Oper_R +13 Frontal_Inf_Tri_L +14 Frontal_Inf_Tri_R +15 Frontal_Inf_Orb_L +16 Frontal_Inf_Orb_R +17 Rolandic_Oper_L +18 Rolandic_Oper_R +19 Supp_Motor_Area_L +20 Supp_Motor_Area_R +21 Olfactory_L +22 Olfactory_R +23 Frontal_Sup_Medial_L +24 Frontal_Sup_Medial_R +25 Frontal_Med_Orb_L +26 Frontal_Med_Orb_R +27 Rectus_L +28 Rectus_R +29 Insula_L +30 Insula_R +31 Cingulum_Ant_L +32 Cingulum_Ant_R +33 Cingulum_Mid_L +34 Cingulum_Mid_R +35 Cingulum_Post_L +36 Cingulum_Post_R +37 Hippocampus_L +38 Hippocampus_R +39 ParaHippocampal_L +40 ParaHippocampal_R +41 Amygdala_L +42 Amygdala_R +43 Calcarine_L +44 Calcarine_R +45 Cuneus_L +46 Cuneus_R +47 Lingual_L +48 Lingual_R +49 Occipital_Sup_L +50 Occipital_Sup_R +51 Occipital_Mid_L +52 Occipital_Mid_R +53 Occipital_Inf_L +54 Occipital_Inf_R +55 Fusiform_L +56 Fusiform_R +57 Postcentral_L +58 Postcentral_R +59 Parietal_Sup_L +60 Parietal_Sup_R +61 Parietal_Inf_L +62 Parietal_Inf_R +63 SupraMarginal_L +64 SupraMarginal_R +65 Angular_L +66 Angular_R +67 Precuneus_L +68 Precuneus_R +69 Paracentral_Lobule_L +70 Paracentral_Lobule_R +71 Caudate_L +72 Caudate_R +73 Putamen_L +74 Putamen_R +75 Pallidum_L +76 Pallidum_R +77 Thalamus_L +78 Thalamus_R +79 Heschl_L +80 Heschl_R +81 Temporal_Sup_L +82 Temporal_Sup_R +83 Temporal_Pole_Sup_L +84 Temporal_Pole_Sup_R +85 Temporal_Mid_L +86 Temporal_Mid_R +87 Temporal_Pole_Mid_L +88 Temporal_Pole_Mid_R +89 Temporal_Inf_L +90 Temporal_Inf_R +91 Cerebelum_Crus1_L +92 Cerebelum_Crus1_R +93 Cerebelum_Crus2_L +94 Cerebelum_Crus2_R +95 Cerebelum_3_L +96 Cerebelum_3_R +97 Cerebelum_4_5_L +98 Cerebelum_4_5_R +99 Cerebelum_6_L +100 Cerebelum_6_R +101 Cerebelum_7b_L +102 Cerebelum_7b_R +103 Cerebelum_8_L +104 Cerebelum_8_R +105 Cerebelum_9_L +106 Cerebelum_9_R +107 Cerebelum_10_L +108 Cerebelum_10_R +109 Vermis_1_2 +110 Vermis_3 +111 Vermis_4_5 +112 Vermis_6 +113 Vermis_7 +114 Vermis_8 +115 Vermis_9 +116 Vermis_10 diff --git a/parcels_label_name_Hammers.txt b/parcels_label_name_Hammers.txt new file mode 100644 index 0000000..3e09999 --- /dev/null +++ b/parcels_label_name_Hammers.txt @@ -0,0 +1,83 @@ +1 Hippocampus_r +2 Hippocampus_l +3 Amygdala_r +4 Amygdala_l +5 Ant_TL_med_r +6 Ant_TL_med_l +7 Ant_TL_inf_lat_r +8 Ant_TL_inf_lat_l +9 G_paraH_amb_r +10 G_paraH_amb_l +11 G_sup_temp_cent_r +12 G_sup_temp_cent_l +13 G_tem_midin_r +14 G_tem_midin_l +15 G_occtem_la_r +16 G_occtem_la_l +17 Cerebellum_r +18 Cerebellum_l +19 Brainstem +20 Insula_l +21 Insula_r +22 OL_rest_lat_l +23 OL_rest_lat_r +24 G_cing_ant_sup_l +25 G_cing_ant_sup_r +26 G_cing_post_l +27 G_cing_post_r +28 FL_mid_fr_G_l +29 FL_mid_fr_G_r +30 PosteriorTL_l +31 PosteriorTL_r +32 PL_rest_l +33 PL_rest_r +34 CaudateNucl_l +35 CaudateNucl_r +36 NuclAccumb_l +37 NuclAccumb_r +38 Putamen_l +39 Putamen_r +40 Thalamus_l +41 Thalamus_r +42 Pallidum_l +43 Pallidum_r +44 Corp_Callosum +45 FrontalHorn_r +46 FrontalHorn_l +47 TemporaHorn_r +48 TemporaHorn_l +49 ThirdVentricl +50 FL_precen_G_l +51 FL_precen_G_r +52 FL_strai_G_l +53 FL_strai_G_r +54 FL_OFC_AOG_l +55 FL_OFC_AOG_r +56 FL_inf_fr_G_l +57 FL_inf_fr_G_r +58 FL_sup_fr_G_l +59 FL_sup_fr_G_r +60 PL_postce_G_l +61 PL_postce_G_r +62 PL_sup_pa_G_l +63 PL_sup_pa_G_r +64 OL_ling_G_l +65 OL_ling_G_r +66 OL_cuneus_l +67 OL_cuneus_r +68 FL_OFC_MOG_l +69 FL_OFC_MOG_r +70 FL_OFC_LOG_l +71 FL_OFC_LOG_r +72 FL_OFC_POG_l +73 FL_OFC_POG_r +74 S_nigra_l +75 S_nigra_r +76 Subgen_antCing_l +77 Subgen_antCing_r +78 Subcall_area_l +79 Subcall_area_r +80 Presubgen_antCing_l +81 Presubgen_antCing_r +82 G_sup_temp_ant_l +83 G_sup_temp_ant_r diff --git a/pathologypatientinfo.py b/pathologypatientinfo.py new file mode 100644 index 0000000..9837c90 --- /dev/null +++ b/pathologypatientinfo.py @@ -0,0 +1,326 @@ +# -*- coding: utf-8 -*- +# +# Functions to create UI, read and write patient data +# such as type of epilepsy, disease history... +#, and dictionary of available processing methods for each manip type +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 + +from PyQt4 import QtGui, QtCore +import pdb, os, json +from brainvisa.data.writediskitem import ReadDiskItem, WriteDiskItem + +# Types : Text, Line (short text) Int (integer), Float, Bool, Choice, MultiSelectChoice, EditableChoice (list of values, but a new one may be entered) +EpilepsyInfoTable= ('AgeDebutCrise',('Choice',[str(i) for i in range(-1,100)], u'Age du début des crises'), + 'Aura',('Choice2',[u'Inconnu',u'Aucune', u'Abdominal', u'Auditory', u'Autonomic', u'Gustatory', u'Olfactory', u'Psychic', u'Somatosensory', u'Visual'], u'Aura'), + 'Seizure',('Choice',[u'Inconnu', u'Automotor', u'Autonomic', u'Dialeptic', u'Dyscognitive', u'Hypermotor', u'Hypomotor', u'Simple Motor'],'Seizure Type'), + 'seizureFrequency', ('Choice', [u'Inconnu',u'quotidienne', u'hebdomadaire', u'mensuelle', u' < 1/mois'], u'Fréquence des crises'), + 'TraitementTried', ('Choice2', [u'Inconnu',u'carbamazépine', u'phénytoine', u'phénobarbital', u'valproate'], u'Traitement essayés (DCI)'), + 'TraitementNow', ('Choice2', [u'Inconnu',u'carbamazépine', u'phénytoine', u'phénobarbital', u'valproate'], u'Traitement actuel'), + ) + +AlzheimerInfoTable = ('AgeDebutCrise',('Choice',[str(i) for i in range(-1,100)], u'Test'), + 'Aura',('Choice2',[u'Inconnu',u'Aucune', u'Abdominal', u'Auditory', u'Autonomic', u'Gustatory', u'Olfactory', u'Psychic', u'Somatosensory', u'Visual'], u'Test'), + 'Seizure',('Choice',[u'Inconnu', u'Automotor', u'Autonomic', u'Dialeptic', u'Dyscognitive', u'Hypermotor', u'Hypomotor', u'Simple Motor'],'Test'), + 'seizureFrequency', ('Choice', [u'Inconnu',u'quotidienne', u'hebdomadaire', u'mensuelle', u' < 1/mois'], u'Test'), + 'TraitementTried', ('Choice2', [u'Inconnu',u'carbamazépine', u'phénytoine', u'phénobarbital', u'valproate'], u'Test'), + 'TraitementNow', ('Choice2', [u'Inconnu',u'carbamazépine', u'phénytoine', u'phénobarbital', u'valproate'], u'Test'), + ) + +#ParkinsonInfoTable + +#DepressionInfoTable + +#DystonieInfotable + +#TOCInfoTable + +#AVC + + +def buildInt(parent, mini, maxi, label): + lay = QtGui.QHBoxLayout() + sp = QtGui.QSpinBox(parent) + sp.setRange(mini, maxi) + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(sp) + return (lay, sp) + +def buildChoice(parent, values, label): + lay = QtGui.QHBoxLayout() + combo = QtGui.QComboBox(parent) + combo.clear() + combo.addItems(values) + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(combo) + return (lay, combo) + +def buildChoice2(parent, values, label): + lay = QtGui.QHBoxLayout() + combo = QtGui.QComboBox(parent) + combo.clear() + model = QtGui.QStandardItemModel(len(values), 1)# 5 rows, 1 col + + for i,area in enumerate(values): + item = QtGui.QStandardItem(area) + item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + model.setItem(i+1, 0, item) + + combo.setModel(model) + combo.setEditable(True) + combo.activated.connect(lambda index, comb=combo: validatenewCombo(comb, index)) + #pdb.set_trace() + + #combo.addItems(values) + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(combo) + return (lay, combo) + +def buildChoiceSub(parent, values, label): + lay = QtGui.QHBoxLayout() + + combosub = QtGui.QMenu(parent) + combosub.setTitle(u'Comorbitité menu') + + for i,area in enumerate(values): + menu = QtGui.QMenu(area) + + combosub.addMenu(menu) + + #pdb.set_trace() + if i<2: + menu.addAction(QtGui.QAction(area, menu, checkable = True)) + else: + #for ii, area2 in enumerate(subvalues) + menu.addAction(QtGui.QAction("pouet", menu, checkable = True)) + + + + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(combosub) + return (lay, combosub) + +def buildDate(parent, date, label): + lay = QtGui.QHBoxLayout() + qdate = QtGui.QDateEdit(parent) + qdate.setDisplayFormat('dd/MM/yyyy') + if date is None: + qdate.setDate(QtCore.QDate.fromString('1900-01-01', 'yyyy-MM-dd')) + else: + qdate.setDate(date) + lay.addWidget(QtGui.QLabel(label,parent=parent)) + lay.addWidget(qdate) + return (lay, qdate) + + +def buildText(parent, label): + lay = QtGui.QHBoxLayout() + text = QtGui.QTextEdit(parent) + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(text) + return (lay, text) + +def buildLine(parent, defaultValue, label): + lay = QtGui.QHBoxLayout() + line = QtGui.QLineEdit(parent) + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + if defaultValue: + line.setText(str(defaultValue)) + lay.addWidget(line) + return (lay, line) + +def buildCompound(parent, values, label): + lay = QtGui.QHBoxLayout() + frame = QtGui.QGroupBox(parent) + frame.setLayout(lay) + if label is not None: + frame.setTitle(str(label)) + widgets = buildUI(frame, values) + for wid in reversed(widgets.values()): + lay.addWidget(wid) + return (frame, [frame,]+widgets.values()) + +def buildButtonBox(parent,values,label): + lay = QtGui.QHBoxLayout() + buttbox = QtGui.QDialogButtonBox(parent) + for i,area in enumerate(values): + buttbox.addButton(area,3) + + for test in buttbox.findChildren(QtGui.QPushButton): + test.setCheckable(True) + + buttbox.clicked.connect(lambda index, comb=buttbox: MRIlesionbox(comb, index)) + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(buttbox) + return (lay,buttbox) + +def buildLabel(parent,label): + lay = QtGui.QHBoxLayout() + labe = QtGui.QLabel(parent) + labe.setText(label) + + lay.addWidget(labe) + return (lay, labe) + + + +def buildCheckbox(parent, label, label2, checkbox_connect): + #function_mapping = {'checkbox_comor':checkbox_comor} + lay = QtGui.QHBoxLayout() + qcheck = QtGui.QCheckBox(parent) + qcheck.setText(label) + + #qcheck.clicked.connect(lambda index, ChecK=qcheck: function_mapping[checkbox_connect](ChecK, index)) + + lay.addWidget(QtGui.QLabel(label2, parent=parent)) + lay.addWidget(qcheck) + return (lay, qcheck) + + +uiBuild = {'Int': buildInt, + 'Float':lambda:(None, None),# Not implemented + 'Line':buildLine, + 'Text':buildText, + 'Bool':lambda:(None, None),# Not implemented + 'Date':lambda p, value,label:(None, None),# Not implemented + 'Date2':buildDate, + 'Choice':buildChoice, + 'Choice2':buildChoice2, + 'ChoiceSub':buildChoiceSub, + 'ButtonBox':buildButtonBox, + 'MultiSelectChoice':lambda p, values, label:(None, None),# Not implemented + 'EditableChoice':lambda p,v,l : buildChoice(p,v,l,True), + 'Compound':buildCompound, + 'Label':buildLabel, + 'Checkbox':buildCheckbox, + } + +def buildUI(parent, infoTabletext=EpilepsyInfoTable): + """ Generates a UI from infoTable) and returns a dictionary with the generated widgets""" + #remove all children remove + #pdb.set_trace() + if parent.children(): + lay = parent.children()[0] + clearLayout(lay) + #pdb.set_trace() + #for i in reversed(range(lay.count())): + #pdb.set_trace() + #widgetToRemove = lay.itemAt(i).widget() #la widget serait à lay.itemAt(i).itemAt(j).widget() + # remove it from the layout list + #lay.removeWidget( widgetToRemove ) + # remove it from the gui + #widgetToRemove.setParent( None ) + + else: + lay = QtGui.QVBoxLayout(parent) + + + #si c est un choice2 c'est editable du coup faut aller chercher sur le json la derniere version de la liste + wdi_global = ReadDiskItem('PatientInfoTemplate','Patient Template format') + di_global = list(wdi_global.findValues({}, None, False)) + + if len(di_global) > 0: + if os.path.isfile(str(di_global[0])): + print "read previous patienttemplate json" + from codecs import open as opencodecs + fin = opencodecs(str(di_global[0]),'r','latin1') + info_dicti = json.loads(fin.read().decode('latin1')) + fin.close() + + previous_lists_path_full = info_dicti['PathoSpecific'] + if infoTabletext in info_dicti['PathoSpecific'].keys(): + previous_lists_path_protocol = info_dicti['PathoSpecific'][infoTabletext] + else: + previous_lists_path_protocol = {} + + else: + previous_lists_path_full = {} + previous_lists_path_protocol = {} + + else: + previous_lists_path_full = {} + previous_lists_path_protocol = {} + + output = {} + CorresPatho={'':EpilepsyInfoTable,'Epilepsy':EpilepsyInfoTable, 'Alzheimer':AlzheimerInfoTable} + if infoTabletext is None: + infoTable=EpilepsyInfoTable + else: + #pdb.set_trace() + if infoTabletext in CorresPatho.keys(): + infoTable = CorresPatho[infoTabletext] + else: + infoTable=EpilepsyInfoTable + #infoTable = var()[infoTableText] + + for i in range(int(len(infoTable)/2)): + key = infoTable[2*i] + value = infoTable[2*i+1] + if key in previous_lists_path_protocol.keys(): + default_list = set(value[1]) + update_list = set(previous_lists_path_protocol[key]) + diff_list = update_list-default_list + final_list = value[1] + list(diff_list) + item1 = value[0] + item3= value[2] + value = (item1,final_list,item3) + if value is not None: + (l,wid) = uiBuild[value[0]](parent, *(value[1:])) + if l is not None: + if isinstance(l, QtGui.QLayout): + lay.addLayout(l) + elif isinstance(l, QtGui.QWidget): + lay.addWidget(l) + else: + print "Neither a layout nor a widget : cannot add object to the layout !" + if wid is not None: + output[key]=wid + return output + +def clearLayout(layout): + for i in reversed(range(layout.count())): + item = layout.itemAt(i) + + if isinstance(item, QtGui.QWidgetItem): + print "widget" + str(item) + item.widget().close() + # or + # item.widget().setParent(None) + elif isinstance(item, QtGui.QSpacerItem): + print "spacer " + str(item) + # no need to do extra stuff + else: + print "layout " + str(item) + clearLayout(item.layout()) + + # remove the item from layout + layout.removeItem(item) + + +def dumpState(structuredWidgets): + """Generates a dumpable object that represents the content of the patient info from the widgets""" + pass + + +def validatenewCombo(combo_modified, selectedIndex): + + AllItems = [unicode(combo_modified.itemText(i)) for i in range(combo_modified.count()) if unicode(combo_modified.itemText(i)) != ''] + + model = QtGui.QStandardItemModel(len(AllItems), 1) + + for i,area in enumerate(AllItems): + item = QtGui.QStandardItem(area) + item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + model.setItem(i+1, 0, item) + + combo_modified.clear() + combo_modified.setModel(model) + combo_modified.setEditable(True) diff --git a/patientDataFilter.ui b/patientDataFilter.ui new file mode 100644 index 0000000..b8ba920 --- /dev/null +++ b/patientDataFilter.ui @@ -0,0 +1,740 @@ + + + Form + + + + 0 + 0 + 1157 + 783 + + + + Form + + + + + + 10 + + + + + QLayout::SetNoConstraint + + + + + Protocol : + + + + + + + + + + Center : + + + + + + + + + + Year : + + + + + + + + + + Atlas : + + + + + + + + MarsAtlas + + + + + Freesurfer + + + + + Brodmann + + + + + + + + Localisation : + + + + + + + QComboBox::AdjustToContents + + + + + + + Cognition Localisation : + + + + + + + + + + Cognition Type : + + + + + + + + + + Resection : + + + + + + + + + + Stim localisation : + + + + + + + + + + Stim Frequence : + + + + + + + + + + Stim Type : + + + + + + + + + + Engel Score (<) : + + + + + + + + * + + + + + Ia + + + + + Ib + + + + + Ic + + + + + Id + + + + + IIa + + + + + IIb + + + + + IIc + + + + + IId + + + + + IIIa + + + + + IIIb + + + + + IVa + + + + + IVb + + + + + IVd + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:600;">Available subjects</span></p></body></html> + + + Qt::RichText + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + QAbstractItemView::MultiSelection + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 8 + true + + + + Select all + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 8 + true + + + + Unselect all + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Add green subjects to the selection + + + background-color: rgb(150, 255, 150); + + + -> + + + + + + + Add selected subjects to the selection + + + -> + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Remove selected subject of the selection + + + <- + + + + + + + Remove red subjects of the selection + + + background-color: rgb(255, 100, 100); + + + <- + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:600;">Selected subjects</span></p></body></html> + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + QAbstractItemView::MultiSelection + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 8 + true + + + + Select all + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 8 + true + + + + Unselect all + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + Montrer pour quels patients la T1pre est disponible + + + T1pre + + + false + + + + + + + Montrer pour quels patients la T2pre est disponible + + + T2pre + + + false + + + + + + + Montrer pour quels patients la PETpre est disponible + + + PETpre + + + false + + + + + + + Montrer pour quels patients la T1post est disponible + + + T1post + + + false + + + + + + + Montrer pour quels patients la T2post est disponible + + + T2post + + + false + + + + + + + Montrer pour quels patients la CTpost est disponible + + + CTpost + + + false + + + + + + + + + Montrer pour quels patients l'implantation des électrodes est disponible + + + Implantation + + + false + + + + + + + Montrer pour quels patients le référentiel MNI est disponible + + + MNI + + + + + + + generateMNIparcels + + + + + + + Identify parcel outliers + + + + + + + + + Montrer pour quels patients la manip SEEG sélectionnée est disponible + + + SEEG + + + false + + + + + + + manip SEEG + + + + + + + + + + + + + + diff --git a/patientdatafilterwidget.py b/patientdatafilterwidget.py new file mode 100644 index 0000000..685a4f2 --- /dev/null +++ b/patientdatafilterwidget.py @@ -0,0 +1,1148 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# Widget to select patients from the DB using available data as filters : needs an access +# to brainvisa database that is already set up ! (brainvisa axon.initializeProcesses() +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# +# +from PyQt4 import QtGui, QtCore, uic + +import sys, json, pickle, numpy, csv +import math +from collections import OrderedDict +import pdb + +from soma import aims +from brainvisa import axon +from brainvisa.data.readdiskitem import ReadDiskItem +from brainvisa.data.writediskitem import WriteDiskItem +from readElecLocalCSVFile import readElecLocalCSVFile +from readSulcusLabelTranslationFile import * + +class PatientDataFilterWidget (QtGui.QWidget): + def __init__(self, app=None): + QtGui.QWidget.__init__(self) + self.ui = uic.loadUi("patientDataFilter.ui", self) + self.pushedWidgets = [] + self.subjects = {} + #self.selectedSubjects=[] + self.filters=[] + self.filtersAtlases = {} + self.pushedWidget = [] + self.greenDotIcon = QtGui.QIcon('greendot.png') + self.filterProtocolCombo.currentIndexChanged.connect(self.updatePatientFilters) + self.filterSiteCombo.currentIndexChanged.connect(self.updatePatientFilters) + self.filterYearCombo.currentIndexChanged.connect(self.updatePatientFilters) + self.filterLocaMarsAtlas.currentIndexChanged.connect(self.updatePatientFilters) + + self.filterCognitionLoca.currentIndexChanged.connect(self.updatePatientFilters) + self.filterCognitionType.currentIndexChanged.connect(self.updatePatientFilters) + + self.filterResection.currentIndexChanged.connect(self.updatePatientFilters) + + self.filterStimulationLoca.currentIndexChanged.connect(self.updatePatientFilters) + self.filterStimulationFreq.currentIndexChanged.connect(self.updatePatientFilters) + self.filterStimulationType.currentIndexChanged.connect(self.updatePatientFilters) + + self.FilterAtlascomboBox.currentIndexChanged.connect(self.changeAtlasfiltration) + + self.filterAddPatientButton.clicked.connect(lambda:self.moveSelectedItemsToOtherListWidget(self.filteredPatientList, self.selectedPatientList)) + self.filterRemovePatientButton.clicked.connect(lambda:self.moveSelectedItemsToOtherListWidget(self.selectedPatientList, self.filteredPatientList)) + self.filterAddGreenPatientButton.clicked.connect(lambda:self.moveFilteredItemsToOtherListWidget(self.filteredPatientList, self.selectedPatientList, self.filters, reverse=False)) + self.filterRemoveRedPatientButton.clicked.connect(lambda:self.moveFilteredItemsToOtherListWidget(self.selectedPatientList, self.filteredPatientList, self.filters, reverse=True)) + + self.patientSelectAllButton.clicked.connect(lambda:self.selectAllListItems(self.filteredPatientList, True) ) + self.patientDeselectAllButton.clicked.connect(lambda:self.selectAllListItems(self.filteredPatientList, False)) + self.selectedSelectAllButton.clicked.connect(lambda:self.selectAllListItems(self.selectedPatientList, True)) + self.selectedDeselectAllButton.clicked.connect(lambda:self.selectAllListItems(self.selectedPatientList, False)) + + self.t1preButton.clicked.connect(lambda: self.toggleFilterWidget('T1pre', self.t1preButton)) + self.t1postButton.clicked.connect(lambda: self.toggleFilterWidget('T1post', self.t1postButton)) + self.t2preButton.clicked.connect(lambda: self.toggleFilterWidget('T2pre', self.t2preButton)) + self.t2postButton.clicked.connect(lambda: self.toggleFilterWidget('T2post', self.t2postButton)) + self.petpreButton.clicked.connect(lambda: self.toggleFilterWidget('PETpre', self.petpreButton)) + self.ctpostButton.clicked.connect(lambda: self.toggleFilterWidget('CTpost', self.ctpostButton)) + + self.implantationButton.clicked.connect(lambda: self.toggleFilterWidget('implantation', self.implantationButton)) + self.mniButton.clicked.connect(lambda: self.toggleFilterWidget('MNI', self.mniButton)) + self.mniParcelsButton.clicked.connect(self.mniParcelsGeneration) + self.seegButton.clicked.connect(self.toggleSeeg) + self.seegManipCombo.currentIndexChanged.connect(self.seegManipChanged) + + self.t1preButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.t1postButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.t2preButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.t2postButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.petpreButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.ctpostButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.implantationButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.mniButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.seegButton.setStyleSheet("background-color: rgb(90, 90, 90);") + + + self.populateFromDB() + + + def getSelectedPatientsNames(self): + """Returns a list of names (string) of all selected patients""" + return sorted([str(self.selectedPatientList.item(i).text()) for i in xrange(self.selectedPatientList.count())]) + + def getSelectedPatients(self): + """ Returns a list of ReadDiskItems representing the selected subjects""" + return [self.subjects[p]['rdi'] for p in self.getSelectedPatientsNames()] + + def findExistingVolumeAcquisitions(self, volType, subjectName, subjectData): + """For a subjectName, find all acquisitions in the DB of the type volType ('Raw T1 MRI') and store them in subjectData[acquisition]""" + rdi = ReadDiskItem( volType, 'aims readable volume formats', requiredAttributes={'subject':subjectName, 'center':subjectData['center']} ) + volumes = (list( rdi._findValues( {}, None, False ) )) + for v in volumes: + try: + acq = v.attributes()['acquisition'].split('_')[0] + subjectData[str(acq)] = v + except: + print "Acquisition not defined for "+repr(v.fullPath()) + + + def populateFromDB(self): + """Fills the list of patients and necessary information about patients to be able to filter""" + rdi = ReadDiskItem( 'Subject', 'Directory',requiredAttributes={'_ontology':'brainvisa-3.2.0'} ) + subjects = list( rdi._findValues( {}, None, False ) ) + self.subjects = dict([(s.attributes()['subject'], {'rdi':s, 'center':s.attributes()['center']}) for s in subjects]) + + protocols = list(set([s.attributes()['center'] for s in subjects])) + + # Fill the combos + self.filterProtocolCombo.clear() + self.filterProtocolCombo.addItems(['*',]+sorted(protocols)) + + # Update the basic filters + sites = ['*',] + sorted(set([s.split('_')[0] for s in self.subjects])) + years = ['*',] + sorted(set([s.split('_')[1] for s in self.subjects if len(s.split('_')) > 1])) + + loca = ['*'] + loca_FS = ['*'] + loca_BM = ['*'] + cogniType = ['*'] + resec = ['*'] + resec_FS = ['*'] + resec_BM = ['*'] + stimFreq = ['*'] + stimType = ['*'] + + self.filterSiteCombo.clear() + self.filterSiteCombo.addItems(sites) + self.filterYearCombo.clear() + self.filterYearCombo.addItems(years) + + #self.filterLocaMarsAtlas.addItems(loca) + #self.filterCognition.addItems(cogni) + + # Get info for all filters + + seegManips = set() + for s,subj in self.subjects.iteritems(): + print(s) + # Find the T1s/T2s/CT/PET + for modality in ['T2 MRI', 'CT', 'PET', 'Raw T1 MRI']: + self.findExistingVolumeAcquisitions(modality, s, subj) + + # Find MNI transform if T1pre is there + if 'T1pre' in subj: + rdi = ReadDiskItem( 'SPM2 normalization matrix', 'Matlab file' ) + di = rdi.findValue(subj['T1pre']) + rdi2 = ReadDiskItem('SPM normalization deformation field', 'NIFTI-1 image') + di2 = rdi2.findValue(subj['T1pre']) + if di is not None: + subj['MNI'] = di + if di2 is not None: + subj['MNI'] = di2 + + # Find Electrode Implantation + rdi = ReadDiskItem( 'Electrode implantation', 'Electrode Implantation format', requiredAttributes={'subject':s, 'center':subj['center']} ) + elecs = list(rdi._findValues( {}, None, False ) ) + if len(elecs) > 0: + subj['implantation'] = elecs[0] + + else: + wditxtmnipos = ReadDiskItem('Electrode Implantation Position TXT', 'Text file', requiredAttributes={'ref_name':'MNI'}) + dimnipos=wditxtmnipos.findValue(subj['rdi']) + wditxtmniname = ReadDiskItem('Electrode Implantation Name TXT', 'Text file', requiredAttributes={'ref_name':'MNI'}) + dimniname = wditxtmniname.findValue(subj['rdi']) + + if dimnipos is not None: + subj['implantationMNI'] = (dimnipos,dimniname) + else: + wdi_csvnew = ReadDiskItem('Final Export Dictionaries','CSV file') + rdi_csvnew= wdi_csvnew.findValue(subj['rdi']) + subj['implantationCSV'] = rdi_csvnew + + # Find Electrode Label + rdi_elec = ReadDiskItem('Electrodes Labels','Electrode Label Format',requiredAttributes={'subject':s, 'center':subj['center']}) + list_di_elec = list(rdi_elec.findValues( {}, None, False ) ) + #loca_patient = [] + loca_patient = {} + loca_patient_FS = {} + loca_patient_BM = {} + loca_bipole_patient = {} + loca_bipole_patient_FS = {} + loca_bipole_patient_BM = {} + + info_label_elec = None + + if len(list_di_elec) > 0: + di_elec = rdi_elec.findValue(subj['T1pre']) + #subj['elec_label'] = di_elec + #read the json file + fin = open(di_elec.fullPath(),'r') + info_label_elec = json.loads(fin.read()) + fin.close() + if 'plots_by_label' in info_label_elec.keys(): + for kk,vv in info_label_elec['plots_by_label'].iteritems(): + if len(vv): + loca.append(kk) + #loca_patient.append(kk) + loca_patient.update({kk:vv}) + + if 'plots_by_label_FS' in info_label_elec.keys(): + for kk,vv in info_label_elec['plots_by_label_FS'].iteritems(): + if len(vv): + loca_FS.append(kk) + #loca_patient_FS.append(kk) + loca_patient_FS.update({kk:vv}) + if 'plots_by_label_BM' in info_label_elec.keys(): + for kk,vv in info_label_elec['plots_by_label_BM'].iteritems(): + if len(vv): + loca_BM.append(kk) + #loca_patient_BM.append(kk) + loca_patient_BM.update({kk:vv}) + + #on fait la meme chose avec les bipoles pour les stims (puis la cognition) + if 'plots_bipolar_by_label' in info_label_elec.keys(): + for kk,vv in info_label_elec['plots_bipolar_by_label'].iteritems(): + if len(vv): + #loca_patient.append(kk) + loca_bipole_patient.update({kk:vv}) + if 'plots_bipolar_by_label_FS' in info_label_elec.keys(): + for kk,vv in info_label_elec['plots_bipolar_by_label_FS'].iteritems(): + if len(vv): + #loca_patient.append(kk) + loca_bipole_patient_FS.update({kk:vv}) + if 'plots_bipolar_by_label_BM' in info_label_elec.keys(): + for kk,vv in info_label_elec['plots_bipolar_by_label_BM'].iteritems(): + if len(vv): + #loca_patient.append(kk) + loca_bipole_patient_BM.update({kk:vv}) + + #add freesurfer and broadmann + subj['rdi_elec_label'] = list_di_elec[0] + else: + subj['rdi_elec_label'] = None + + subj['elec_label'] = loca_patient + subj['elec_label_FS'] = loca_patient_FS + subj['elec_label_BM'] = loca_patient_BM + subj['bipole_label'] = loca_bipole_patient + subj['bipole_label_FS'] = loca_bipole_patient_FS + subj['bipole_label_BM'] = loca_bipole_patient_BM + + + rdi_resec_label = ReadDiskItem('Resection Description','Resection json',requiredAttributes={'subject':s, 'center':subj['center']}) + list_di_resec_label = list(rdi_resec_label.findValues( {}, None, False ) ) + resec_patient = [] + resec_patient_FS = [] + if len(list_di_resec_label) > 0: + di_resec_label = rdi_resec_label.findValue(subj['T1pre']) + fin = open(di_resec_label.fullPath(),'r') + info_label_resec = json.loads(fin.read()) + fin.close() + + if 'mars_atlas' in info_label_resec.keys(): + for kk,vv in info_label_resec['mars_atlas'].iteritems(): + if len(vv): + resec.append(kk) + resec_patient.append(kk) + + #add freesurfer + if 'Freesurfer' in info_label_resec.keys(): + if 'Freesurfer not calculated' in info_label_resec['Freesurfer']: + pass + else: + for kk,vv in info_label_resec['Freesurfer'].iteritems(): + if len(vv): + resec_FS.append(kk) + resec_patient_FS.append(kk) + + subj['rdi_resec_label'] = list_di_resec_label[0] + else: + subj['rdi_resec_label'] = None + + subj['resec_label'] = resec_patient + subj['resec_label_FS'] = resec_patient_FS + + # Find SEEG manips + rdi = ReadDiskItem( 'Raw SEEG recording', ['EEG TRC format', 'Elan EEG format'], requiredAttributes={'subject':s, 'center':subj['center']} ) + records = list(rdi._findValues( {}, None, False ) ) + if len(records) > 0: + for rec in records: + subj['seeg_'+str(rec.attributes()['experiment'])] = rec + manips = [str(rec.attributes()['experiment']) for rec in records] + seegManips.update(manips) + + rdi_stimresult_label = ReadDiskItem('Electrodes SEEG Labels','Electrode sEEG Label Format',requiredAttributes={'subject':s, 'center':subj['center']}) + list_di_stimresult_label = list(rdi_stimresult_label.findValues( {}, None, False ) ) + seeg_label_loca = [] + seeg_label_type = [] + seeg_label_freq = [] + seeg_label_all = [] + + + if len(list_di_stimresult_label)>0: + + by_default_list = [u'Motor',u'Sensitive',u'Sensory',u'Vegetative',u'Emotional',u'Experiencial','Superior functions'] + by_default_list2 = [u'no response', u'pathological', u'seizure sensation'] + full_list = by_default_list + by_default_list2 + + di_stimresult_label = rdi_stimresult_label.findValue(subj['T1pre']) + fin = open(di_stimresult_label.fullPath(),'r') + info_seeg_label = json.loads(fin.read()) + fin.close() + + #la il faut que je retourne les infos dans tous les sens c'est la merde ... + for kk,vv in info_seeg_label['contacts'].iteritems(): + #seeg_label_loca = + + for freqVal in info_seeg_label['contacts'][kk]['cell'].keys(): + if freqVal not in stimFreq: + stimFreq.append(freqVal) + #seeg_label_freq.append(freqVal) + list_inter = [x for x in by_default_list if info_seeg_label['contacts'][kk]['cell'][freqVal][x]['value'] != 0] + list_inter2 = info_seeg_label['contacts'][kk]['cell'][freqVal][u'Type of response']['fontcolor'] + max_index = list_inter2[1:].index(max(list_inter2[1:])) + try: + if list_inter2[max_index+1] == 0: + resp1 = by_default_list2[0] + elif max_index == 0: + resp1 = by_default_list2[2] + elif max_index == 2: + resp1 = by_default_list2[1] + except: + pdb.set_trace() + seeg_label_all.append((kk.title(),freqVal,resp1,list_inter)) + try: + if 'MarsAtlas' in info_label_elec['plots_label_bipolar'][kk.title()].keys(): + seeg_label_all[-1] = seeg_label_all[-1] + (info_label_elec['plots_label_bipolar'][kk.title()]['MarsAtlas'][1],) + else: + seeg_label_all[-1] = seeg_label_all[-1] + (u'not estimated',) + except: + pdb.set_trace() + + if 'Freesurfer' in info_label_elec['plots_label_bipolar'][kk.title()].keys(): + seeg_label_all[-1] = seeg_label_all[-1] + (info_label_elec['plots_label_bipolar'][kk.title()]['Freesurfer'][1],) + else: + seeg_label_all[-1] = seeg_label_all[-1] + (u'not estimated',) + + if 'Broadmann' in info_label_elec['plots_label_bipolar'][kk.title()].keys(): + seeg_label_all[-1] = seeg_label_all[-1] + (info_label_elec['plots_label_bipolar'][kk.title()]['Broadmann'][1],) + else: + seeg_label_all[-1] = seeg_label_all[-1] + (u'not estimated',) + #[True if info_seeg_label['contacts'][kk]['cell'][freqVal][x]['value'] != 0 else False for x in by_default_list] + #pdb.set_trace() + + + subj['seeg_label_all'] = seeg_label_all + + if 'full_list' in locals(): + stimInter = set(stimType) + full_listInter = set(full_list) + newstimtype = stimInter.union(full_listInter) + stimType = sorted(list(newstimtype)) + #stimType = stimType + full_list + + #remove duplicate #la on récupère les clés ? ou après ? où est-ce que je gère les infos des contacts ? + locas = list(set(loca)) + locas.sort() + locas_FS = list(set(loca_FS)) + locas_FS.sort() + locas_BM = list(set(loca_BM)) + locas_BM.sort() + + + + self.filterCognitionLoca.clear() + self.filterCognitionType.clear() + + + self.filterCognitionLoca.addItems(locas) + self.filterCognitionType.addItems(cogniType) + + self.filterStimulationLoca.clear() + self.filterStimulationType.clear() + self.filterStimulationFreq.clear() + + self.filterStimulationLoca.addItems(locas) + self.filterStimulationType.addItems(stimType) + self.filterStimulationFreq.addItems(stimFreq) + + resecs = list(set(resec)) + resecs.sort() + resecs_FS = list(set(resec_FS)) + resecs_FS.sort() + resecs_BM = list(set(resec_BM)) + resecs_BM.sort() + + self.filtersAtlases.update({'locaMA':locas,'locaFS':locas_FS,'locaBM':locas_BM,'resecMA':resecs,'resecFS':resecs_FS,'resecBM':resecs_BM}) + + self.filterLocaMarsAtlas.clear() + self.filterLocaMarsAtlas.addItems(locas) + + #self.filterCognition.clear() + #self.filterCognition.addItems(cognis) + + self.filterResection.clear() + self.filterResection.addItems(resecs) + + if len(seegManips) > 0: + self.seegManipCombo.clear() + self.seegManipCombo.addItems(sorted(list(seegManips))) + + self.updatePatientFilters() + + def toggleSeeg(self): + """If SEEG is clicked, select the manip as a filter""" + manip = str(self.seegManipCombo.currentText()) + if manip is None or manip == "": + return + self.toggleFilterWidget('seeg_'+manip, self.seegButton) + if 'seeg_'+manip in self.filters: + self.seegManipCombo.setItemIcon(self.seegManipCombo.currentIndex(), self.greenDotIcon) + else: + self.seegManipCombo.setItemIcon(self.seegManipCombo.currentIndex(), None) + + def seegManipChanged(self, idx): + self.toggleWidget(self.seegButton, 'seeg_' + str(self.seegManipCombo.currentText()) in self.filters) + + + def toggleFilterWidget(self, filterName, widg): + """Adds/Removes a filter and push/unpush the widget""" + onOrOff = self.toggleFilter(filterName) + self.toggleWidget(widg, onOrOff) + + def toggleWidget(self, widg, on = True): + """Sets the background color of the widget to green and add it to pushedWidgets, or reverse if it is already pushed""" + if not on: + widg.setStyleSheet("background-color: rgb(90, 90, 90);") + self.pushedWidget.remove(widg) + else: + widg.setStyleSheet("background-color: rgb(120, 255, 120);") + #widg.setStyleSheet("border: 2px solid #88ff88;") + self.pushedWidget.append(widg) + + def toggleFilter(self, filterName, updateUi = True): + """Sets or unsets a filter, then update the ui""" + if filterName in self.filters: + self.filters.remove(filterName) + else: + self.filters.append(filterName) + if updateUi: + self.updatePatientFilters() + return filterName in self.filters + + def getFilters(self): + return self.filters + + def matchFilters(self, subj, filters): + return all([subj.has_key(f) for f in filters]) + + def filterSubjectsBasic(self): + """Filtering subject list using basic factors (protocol, year, site)""" + subs = self.subjects.keys() + if str(self.filterProtocolCombo.currentText()) != '*': + subs = [s for s in subs if self.subjects[s]['center'] == str(self.filterProtocolCombo.currentText())] + if str(self.filterSiteCombo.currentText()) != '*': + subs = [s for s in subs if s.split('_')[0] == str(self.filterSiteCombo.currentText())] + if str(self.filterYearCombo.currentText()) != '*': + subs = [s for s in subs if len(s.split('_')) > 1 and s.split('_')[1] == str(self.filterYearCombo.currentText())] + if self.FilterAtlascomboBox.currentIndex() == 0: + if str(self.filterLocaMarsAtlas.currentText()) != '*': + subs = [s for s in subs if 'elec_label' in self.subjects[s] and str(self.filterLocaMarsAtlas.currentText()) in self.subjects[s]['elec_label'].keys()] + if str(self.filterResection.currentText()) != '*': + subs = [s for s in subs if 'resec_label' in self.subjects[s] and str(self.filterResection.currentText()) in self.subjects[s]['resec_label']] + elif self.FilterAtlascomboBox.currentIndex() == 1: + if str(self.filterLocaMarsAtlas.currentText()) != '*': + subs = [s for s in subs if 'elec_label_FS' in self.subjects[s] and str(self.filterLocaMarsAtlas.currentText()) in self.subjects[s]['elec_label_FS'].keys()] + if str(self.filterResection.currentText()) != '*': + subs = [s for s in subs if 'resec_label_FS' in self.subjects[s] and str(self.filterResection.currentText()) in self.subjects[s]['resec_label_FS']] + elif self.FilterAtlascomboBox.currentIndex() == 2: + if str(self.filterLocaMarsAtlas.currentText()) != '*': + subs = [s for s in subs if 'elec_label_BM' in self.subjects[s] and str(self.filterLocaMarsAtlas.currentText()) in self.subjects[s]['elec_label_BM'].keys()] + if str(self.filterResection.currentText()) != '*': + subs = [s for s in subs if 'resec_label_BM' in self.subjects[s] and str(self.filterResection.currentText()) in self.subjects[s]['resec_label_BM']] + if str(self.filterStimulationLoca.currentText())!= '*' or str(self.filterStimulationFreq.currentText()) != '*' or str(self.filterStimulationType.currentText()) != '*' : + subs = [s for s in subs if 'seeg_label_all' in self.subjects[s]] + CondiLoca = str(self.filterStimulationLoca.currentText()) == '*' + CondiFreq = str(self.filterStimulationFreq.currentText()) == '*' + CondiType = str(self.filterStimulationType.currentText()) == '*' + subs_toremove = [] + inter_stim = {} + for ind_sub in subs: + isthereloc = [x for x in self.subjects[ind_sub]['seeg_label_all'] if (str(self.filterStimulationLoca.currentText())==x[4+self.FilterAtlascomboBox.currentIndex()] or CondiLoca) and (str(self.filterStimulationFreq.currentText())==x[1] or CondiFreq) and (str(self.filterStimulationType.currentText())==x[2] or str(self.filterStimulationType.currentText()) in x[3] or CondiType)] + if len(isthereloc)==0: + subs_toremove.append(ind_sub) + else: + inter_stim.update({ind_sub:isthereloc}) + #for bipole_info in self.sub + [subs.remove(x) for x in subs_toremove] + + + + + if str(self.filterCognitionLoca.currentText()) != '*': + print "no cognition load in the data base for now" + + subs = [s for s in subs if s not in [str(self.selectedPatientList.item(idx).text()) for idx in range(self.selectedPatientList.count())]] + self.filteredPatientList.clear() + self.filteredPatientList.addItems(sorted(subs)) + + def colorFilterListWidget(self, listwidget, selected): + for idx in range(listwidget.count()): + it = listwidget.item(idx) + if str(it.text()) in selected: + it.setBackground(QtGui.QColor(150,255,150)) + else: + it.setBackground(QtGui.QColor(255,150,150)) + + def updatePatientFilters(self): + """Colors the 'patient list' and 'selected patient list' items in green if they match the filters and updates the content of patient's list""" + # Apply basic filters to the main patient list first and update the UI + self.filterSubjectsBasic() + # Filter the list of subjects and filter them + filteredPatients = [s for s,subj in self.subjects.iteritems() if self.matchFilters(subj, self.filters)] + # Color the patients according to the filters + self.colorFilterListWidget(self.filteredPatientList, filteredPatients) + self.colorFilterListWidget(self.selectedPatientList, filteredPatients) + + def moveSelectedItemsToOtherListWidget(self, lwFrom, lwTo): + """Takes the selected items of the list 'from' and adds them to the 'to' list""" + for idx in reversed(range(lwFrom.count())): + it = lwFrom.item(idx) + if lwFrom.isItemSelected(it): + lwTo.addItem(str(it.text())) + lwFrom.takeItem(idx) + lwTo.sortItems() + + def moveFilteredItemsToOtherListWidget(self, lwFrom, lwTo, filters, reverse=False): + """Takes the items from lwFrom (QListWidget) and move those that match the filters to lwTo. If reverse is true, the items that don't match will move""" + filtered = [s for s,subj in self.subjects.iteritems() if self.matchFilters(subj, filters)] + for idx in reversed(range(lwFrom.count())): + it = lwFrom.item(idx) + if (not reverse and str(it.text()) in filtered) or (reverse and str(it.text()) not in filtered): + lwTo.addItem(str(it.text())) + lwFrom.takeItem(idx) + + lwTo.sortItems() + + def selectAllListItems(self, listwidget, select = True): + """Selects or deselects all items of a QListWidget (select = False to deselect)""" + for idx in range(listwidget.count()): + listwidget.setItemSelected(listwidget.item(idx), select) + + def mniParcelsGeneration(self): + + #patient selected + PatsSelected = self.getSelectedPatientsNames() + subject_to_perform = [] + subjects_ok = [] + + for ind_pat in PatsSelected: + + #first we look if it's not already done + if 'rdi_elec_label' in self.subjects[ind_pat].keys(): + if self.subjects[ind_pat]['rdi_elec_label'] is not None: + fin = open(str(self.subjects[ind_pat]['rdi_elec_label']),'r') + info_label_elec = json.loads(fin.read()) + fin.close() + if 'plots_label' in info_label_elec.keys(): + if "BroadmannDilate" in info_label_elec['plots_label'][info_label_elec['plots_label'].keys()[0]].keys(): + subjects_ok.append(ind_pat) + print("BrodmannDilate already estimated for this patient %s"%ind_pat) + else: + subject_to_perform.append(ind_pat) + else: + subject_to_perform.append(ind_pat) + else: + subject_to_perform.append(ind_pat) + else: + subject_to_perform.append(ind_pat) + + #if not we look if MNI position have been estimated already + subject_possible_to_perform = {} + subject_not_performable = [] + + for ind_pat in subject_to_perform: + + if 'implantation' in self.subjects[ind_pat].keys(): + + fin = open(str(self.subjects[ind_pat]['implantation']),'r') + try: + info_implant = json.loads(fin.read()) + except: + fin.close() + fin = open(str(self.subjects[ind_pat]['implantation']),'r') + info_implant = pickle.load(fin) + fin.close() + + if 'plotsMNI' in info_implant.keys(): + subject_possible_to_perform.update({ind_pat:info_implant['plotsMNI']}) + else: + print("MNI estimation has to be done in locateElectrodes for %s, to sensitive to duplicate these functions at differente place"%ind_pat) + subject_not_performable.append(ind_pat) + + elif 'implantationMNI' in self.subjects[ind_pat].keys(): + #pdb.set_trace() + MNI_pos = numpy.loadtxt(str(self.subjects[ind_pat]['implantationMNI'][0])) + a=open(str(self.subjects[ind_pat]['implantationMNI'][1]),"rU") + MNI_name=a.read().splitlines() + a.close() + info = [[MNI_name[x],MNI_pos[x].tolist()] for x in range(len(MNI_name))] + subject_possible_to_perform.update({ind_pat:info}) + #MNI_name = + #subject_possible_to_perform.update({ind_pat:info_implant['plotsMNI']}) + + elif 'implantationCSV' in self.subjects[ind_pat].keys(): + # pdb.set_trace() + print("refaire %s"%str(ind_pat)) + #subject_possible_to_perform.update({ind_pat:info_implant['plotsMNI']}) + else: + subject_not_performable.append(ind_pat) + + + matrix_MNI_Nativ = numpy.matrix([[ -1., 0., 0., 90.],[0., -1., 0., 91.],[0., 0., -1., 109.],[0., 0., 0., 1.]]) + #la blague maintenant c'est d'ouvrir un csv et de rajouter des infos mni sans perdre les infos "patients specifique" + for ind_pat in subject_possible_to_perform.keys(): + + print(ind_pat) + plotMNI_sorted = sorted(subject_possible_to_perform[ind_pat], key=lambda plot_number: plot_number[0]) + plotMNI_Dict = dict(plotMNI_sorted) + #make bipolar montage + + + plot_dict_MNI_Native = {} + for vv,kk in plotMNI_Dict.iteritems(): + inter_pos = [kk[0], kk[1], kk[2], 1] + inter_pos = numpy.matrix(inter_pos).reshape([4,1]) + result_pos = numpy.dot(matrix_MNI_Nativ,inter_pos) + plot_dict_MNI_Native.update({vv:[result_pos.tolist()[0][0],result_pos.tolist()[1][0],result_pos.tolist()[2][0]]}) + + info_plotMNI_bipolaire= [] + for pindex in range(1,len(plotMNI_sorted)): + previous_contact = "".join([i for i in plotMNI_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plotMNI_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plotMNI_bipolaire.append((plotMNI_sorted[pindex][0]+' - '+ plotMNI_sorted[pindex-1][0],(numpy.array(plot_dict_MNI_Native[plotMNI_sorted[pindex][0]])+numpy.array(plot_dict_MNI_Native[plotMNI_sorted[pindex-1][0]]))/2 )) + + info_plotMNI_bipolaireSB= {} + for pindex in range(1,len(plotMNI_sorted)): + previous_contact = "".join([i for i in plotMNI_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plotMNI_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plotMNI_bipolaireSB.update({plotMNI_sorted[pindex][0]+' - '+ plotMNI_sorted[pindex-1][0]:(numpy.array(plotMNI_Dict[plotMNI_sorted[pindex][0]])+numpy.array(plotMNI_Dict[plotMNI_sorted[pindex-1][0]]))/2 }) + + info_plotMNI_bipolaire_Dict =dict(info_plotMNI_bipolaire) + #open MNI filtersAtlases + #pdb.set_trace() + + Hammers_parcels_names = readSulcusLabelTranslationFile('parcels_label_name_Hammers.txt') + AAL_parcels_names = readSulcusLabelTranslationFile('parcels_label_name_AAL.txt') + AALDilate_parcels_names = readSulcusLabelTranslationFile('parcels_label_name_AALDilate.txt') + vol_AAL = aims.read('MNI_Atlases/rAALSEEG12.nii') + vol_AALDilate = aims.read('MNI_Atlases/rAALSEEG12Dilate.nii') + vol_BroadmannDilate = aims.read('MNI_Atlases/rBrodmannSEEG3spm12.nii') + vol_Broadmann = aims.read('MNI_Atlases/rbrodmann.nii') + vol_Hammers = aims.read('MNI_Atlases/rHammersSEEG12.nii') + + sphere_size = 3 #en mm + nb_voxel_sphere_MNI = [sphere_size, sphere_size, sphere_size] + #c'est là que ça va pas ... + #il faut que je recharge celui du patient + plots_label = {} + if 'rdi_elec_label' in self.subjects[ind_pat].keys(): + if self.subjects[ind_pat]['rdi_elec_label'] is not None: + fin = open(str(self.subjects[ind_pat]['rdi_elec_label']),'r') + info_label_elec = json.loads(fin.read()) + fin.close() + plots_label = info_label_elec['plots_label'] + else: + plots_label = {} + else: + plots_label = {} + + for pindex in range(len(plotMNI_sorted)): + + plot_pos_pix_MNI = [round(plot_dict_MNI_Native[plotMNI_sorted[pindex][0]][i]) for i in range(3)] + + ##MNI Atlases + ##AAL + voxel_within_sphere_AAL = [round(vol_AAL.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAAL = [x for x in voxel_within_sphere_AAL if x != 0 and not math.isnan(x)] + + ##AALDilate + voxel_within_sphere_AALdilate = [round(vol_AALDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAALDilate = [x for x in voxel_within_sphere_AALdilate if x != 0 and not math.isnan(x)] + + ##Broadmann + voxel_within_sphere_Broadmann = [round(vol_Broadmann.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmann = [x for x in voxel_within_sphere_Broadmann if x != 0 and not math.isnan(x)] + + #Brodmann dilate + voxel_within_sphere_Broadmanndilate = [round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmannDilate = [x for x in voxel_within_sphere_Broadmanndilate if x != 0 and not math.isnan(x)] + + ##Hammers + voxel_within_sphere_Hammers = [round(vol_Hammers.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepHammers = [x for x in voxel_within_sphere_Hammers if x != 0 and not math.isnan(x)] + + ##prendre le label qui revient le plus en dehors de zero (au cas où il y en ait plusieurs) + from collections import Counter + + if not voxel_to_keepAAL: + label_AAL_name = "not in a AAL parcel" + label_AAL = round(vol_AAL.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAAL).most_common(1)[0] + label_AAL = most_common + label_AAL_name = AAL_parcels_names[label_AAL] + + if not voxel_to_keepAALDilate: + label_AALDilate_name = "not in a AALDilate parcel" + label_AALDilate = round(vol_AALDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAALDilate).most_common(1)[0] + label_AALDilate = most_common + label_AALDilate_name = AALDilate_parcels_names[label_AALDilate] + + if not voxel_to_keepBroadmann: + label_Broadmann_name = "not in a Broadmann parcel" + label_Broadmann = round(vol_Broadmann.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmann).most_common(1)[0] + label_Broadmann = most_common + #label_Broadmann_name = unicode(label_Broadmann) + + if plot_pos_pix_MNI[0]>90: + label_Broadmann_name = unicode(label_Broadmann+100) + else: + label_Broadmann_name = unicode(label_Broadmann) + + if not voxel_to_keepBroadmannDilate: + label_BroadmannDilate_name = "not in a Broadmann parcel" + label_BroadmannDilate = round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmannDilate).most_common(1)[0] + label_BroadmannDilate = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_BroadmannDilate_name = unicode(label_BroadmannDilate+100) + else: + label_BroadmannDilate_name = unicode(label_BroadmannDilate-48) + + if not voxel_to_keepHammers: + label_Hammers_name = "not in a Hammers parcel" + label_Hammers = round(vol_Hammers.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepHammers).most_common(1)[0] + label_Hammers = most_common + label_Hammers_name = Hammers_parcels_names[label_Hammers] + + + #la j'ecrase les infos marsatlas etc ... sans raison + #plots_label[plotMNI_sorted[pindex][0]]={'MarsAtlas':(0,'not calculated'),'Freesurfer':(0,'not calculated'),'Hippocampal Subfield':(0,'not calculated'),'GreyWhite':(0,'not calculated'),'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'Hammers':(label_Hammers,label_Hammers_name),'Resection':(0,'not calculated')} + try: + plots_label[plotMNI_sorted[pindex][0]].update({'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'BroadmannDilate':(label_BroadmannDilate,label_BroadmannDilate_name),'Hammers':(label_Hammers,label_Hammers_name)}) + except: + plots_label[plotMNI_sorted[pindex][0]]={'MarsAtlas':(0,'not calculated'),'Freesurfer':(0,'not calculated'),'Hippocampal Subfield':(0,'not calculated'),'GreyWhite':(0,'not calculated'),'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'BroadmannDilate':(label_BroadmannDilate,label_BroadmannDilate_name),'Hammers':(label_Hammers,label_Hammers_name),'Resection':(0,'not calculated')} + #je remets l'ancienne ligne ? + + plot_name = [x[0] for x in plotMNI_sorted] + plots_by_label_BM = dict([(Lab,[p for p in plot_name if plots_label[p]['Broadmann'][1]==Lab]) for Lab in [unicode("%1.1f"%x) for x in range(0,100)]]) + plots_by_label_HM = dict([(Lab,[p for p in plot_name if plots_label[p]['Hammers'][1]==Lab]) for Lab in Hammers_parcels_names.values()]) + plots_by_label_AAL = dict([(Lab,[p for p in plot_name if plots_label[p]['AAL'][1]==Lab]) for Lab in AAL_parcels_names.values()]) + plots_by_label_AALDilate = dict([(Lab,[p for p in plot_name if plots_label[p]['AALDilate'][1]==Lab]) for Lab in AALDilate_parcels_names.values()]) + + sphere_size_bipole = 5 + nb_voxel_sphere_MNI = [sphere_size, sphere_size, sphere_size] + + plots_label_bipolar = {} + if 'rdi_elec_label' in self.subjects[ind_pat].keys(): + if self.subjects[ind_pat]['rdi_elec_label'] is not None: + fin = open(str(self.subjects[ind_pat]['rdi_elec_label']),'r') + info_label_elec = json.loads(fin.read()) + fin.close() + plots_label_bipolar = info_label_elec['plots_label_bipolar'] + else: + pass #pdb.set_trace() + else: + pass #pdb.set_trace() + + for pindex in range(len(info_plotMNI_bipolaire)): + plot_pos_pix_MNI = [round(info_plotMNI_bipolaire[pindex][1][i]) for i in range(3)] + + ##MNI Atlases + ##AAL + voxel_within_sphere_AAL = [round(vol_AAL.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAAL = [x for x in voxel_within_sphere_AAL if x != 0 and not math.isnan(x)] + + ##AALDilate + voxel_within_sphere_AALdilate = [round(vol_AALDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAALDilate = [x for x in voxel_within_sphere_AALdilate if x != 0 and not math.isnan(x)] + + ##Broadmann + voxel_within_sphere_Broadmann = [round(vol_Broadmann.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmann = [x for x in voxel_within_sphere_Broadmann if x != 0 and not math.isnan(x)] + + #Brodmann dilate + voxel_within_sphere_Broadmanndilate = [round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmannDilate = [x for x in voxel_within_sphere_Broadmanndilate if x != 0 and not math.isnan(x)] + + ##Hammers + voxel_within_sphere_Hammers = [round(vol_Hammers.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepHammers = [x for x in voxel_within_sphere_Hammers if x != 0 and not math.isnan(x)] + + ##prendre le label qui revient le plus en dehors de zero (au cas où il y en ait plusieurs) + from collections import Counter + + if not voxel_to_keepAAL: + label_AAL_name = "not in a AAL parcel" + label_AAL = round(vol_AAL.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAAL).most_common(1)[0] + label_AAL = most_common + label_AAL_name = AAL_parcels_names[label_AAL] + + if not voxel_to_keepAALDilate: + label_AALDilate_name = "not in a AALDilate parcel" + label_AALDilate = round(vol_AALDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAALDilate).most_common(1)[0] + label_AALDilate = most_common + label_AALDilate_name = AALDilate_parcels_names[label_AALDilate] + + if not voxel_to_keepBroadmann: + label_Broadmann_name = "not in a Broadmann parcel" + label_Broadmann = round(vol_Broadmann.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmann).most_common(1)[0] + label_Broadmann = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_Broadmann_name = unicode(label_Broadmann+100) + else: + label_Broadmann_name = unicode(label_Broadmann) + + if not voxel_to_keepBroadmannDilate: + label_BroadmannDilate_name = "not in a Broadmann parcel" + label_BroadmannDilate = round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmannDilate).most_common(1)[0] + label_BroadmannDilate = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_BroadmannDilate_name = unicode(label_BroadmannDilate+100) + else: + label_BroadmannDilate_name = unicode(label_BroadmannDilate-48) + + + if not voxel_to_keepHammers: + label_Hammers_name = "not in a Hammers parcel" + label_Hammers = round(vol_Hammers.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepHammers).most_common(1)[0] + label_Hammers = most_common + label_Hammers_name = Hammers_parcels_names[label_Hammers] + + + #plots_label_bipolar[info_plotMNI_bipolaire[pindex][0]]={'MarsAtlas':(0,'not calculated'),'Freesurfer':(0,'not calculated'),'Hippocampal Subfield':(0,'not calculated'),'GreyWhite':(0,'not calculated'),'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'Hammers':(label_Hammers,label_Hammers_name),'Resection':(0,'not calculated')} + try: + plots_label_bipolar[info_plotMNI_bipolaire[pindex][0]].update({'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'BroadmannDilate':(label_BroadmannDilate,label_BroadmannDilate_name),'Hammers':(label_Hammers,label_Hammers_name)}) + except: + plots_label_bipolar[info_plotMNI_bipolaire[pindex][0]]={'MarsAtlas':(0,'not calculated'),'Freesurfer':(0,'not calculated'),'Hippocampal Subfield':(0,'not calculated'),'GreyWhite':(0,'not calculated'),'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'BroadmannDilate':(label_BroadmannDilate,label_BroadmannDilate_name),'Hammers':(label_Hammers,label_Hammers_name),'Resection':(0,'not calculated')} + + plot_name_bip = [x[0] for x in info_plotMNI_bipolaire] + plots_bipolar_by_label_BM = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['Broadmann'][1]==Lab]) for Lab in [unicode("%1.1f"%x) for x in range(0,100)]]) + plots_bipolar_by_label_HM = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['Hammers'][1]==Lab]) for Lab in Hammers_parcels_names.values()]) + plots_bipolar_by_label_AAL = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['AAL'][1]==Lab]) for Lab in AAL_parcels_names.values()]) + plots_bipolar_by_label_AALDilate = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['AALDilate'][1]==Lab]) for Lab in AALDilate_parcels_names.values()]) + + wdi_csv = ReadDiskItem('Final Export Dictionaries','CSV file',requiredAttributes={'subject':ind_pat}) + rdi_csv = list(wdi_csv.findValues({},None,False)) + + if len(rdi_csv)>0: + #print c'est la galère + info_previous_csv = readElecLocalCSVFile(infile=str(rdi_csv[0])) + + else: + + info_previous_csv = None + + wdi_csvnew = WriteDiskItem('Final Export Dictionaries','CSV file') + rdi_csvnew= wdi_csvnew.findValue(self.subjects[ind_pat]['rdi']) + + with open(str(rdi_csvnew), 'w') as csvfile: + #fieldnames=['MarsAtlas','GreyWhite','Resection'] + writer = csv.writer(csvfile, delimiter='\t') + writer.writerow([u'Contacts Positions']) + if info_previous_csv is not None: + info_mniMarsAtlas = info_previous_csv[0]['MarsAtlas'] + info_mniFreesurfer = info_previous_csv[0]['Freesurfer'] + info_mniHippoFS = info_previous_csv[0]['HippoSubfieldFreesurfer'] + else: + info_mniMarsAtlas = 'not performed' + info_mniFreesurfer = 'not performed' + info_mniHippoFS = 'not performed' + + writer.writerow([u'Use of MNI Template','MarsAtlas',info_mniMarsAtlas,'Freesurfer',info_mniFreesurfer,'HippoSubfieldFreesurfer',info_mniHippoFS]) + + #add a row with "MNI or Patient for MarsAtlas and Freesurfer + try: + list_to_write = set(info_previous_csv[1]['monopolar'][info_previous_csv[1]['monopolar'].keys()[0]].keys()) + except: + list_to_write = set([]) + + list_by_default = set([u'contact','MarsAtlas', 'MarsAtlasFull', 'Freesurfer', 'Hippocampal Subfield','GreyWhite','AAL', 'AALDilate', 'Broadmann', 'BroadmannDilate', 'Hammers', 'Resection', 'MNI','T1pre Scanner Based']) + diff_list = list(list_to_write.difference(list_by_default)) + full_list = [u'contact','MarsAtlas', 'MarsAtlasFull', 'Freesurfer', 'Hippocampal Subfield','GreyWhite', 'ALL', 'AALDilate', 'Broadmann', 'BroadmannDilate', 'Hammers', 'Resection', 'MNI','T1pre Scanner Based'] + full_list.extend(diff_list) + writer.writerow(full_list) + + try: + dict_sorted_tmp = OrderedDict(sorted(info_previous_csv[1]['monopolar'].items())) + except: + dict_sorted_tmp = OrderedDict(sorted(plots_label.items())) + new_dict_sorted_tmp = {} + for kk,vv in dict_sorted_tmp.items(): + new_dict_sorted_tmp.update({kk:{}}) + [new_dict_sorted_tmp[kk].update({jj:ll[1]}) for jj,ll in vv.items()] + dict_sorted_tmp = OrderedDict(sorted(new_dict_sorted_tmp.items())) + + + try: + for kk,vv in dict_sorted_tmp.iteritems(): + listwrite = [kk] + if 'MarsAtlas' in vv.keys(): + listwrite.append(vv['MarsAtlas']) + else: + listwrite.append('not performed') + if 'MarsAtlasFull' in vv.keys(): + listwrite.append(vv['MarsAtlasFull']) + else: + listwrite.append('not performed') + if 'Freesurfer' in vv.keys(): + listwrite.append(vv['Freesurfer']) + else: + listwrite.append('not performed') + if 'Hippocampal Subfield' in vv.keys(): + listwrite.append(vv['Hippocampal Subfield']) + else: + listwrite.append('not performed') + if 'GreyWhite' in vv.keys(): + listwrite.append(vv['GreyWhite']) + else: + listwrite.append('not performed') + if 'AAL' in vv.keys(): + listwrite.append(vv['AAL']) + else: + listwrite.append(plots_label[kk]['AAL'][1]) + if 'AALDilate' in vv.keys(): + listwrite.append(vv['AALDilate']) + else: + listwrite.append(plots_label[kk]['AALDilate'][1]) + #if 'Broadmann' in vv.keys(): + # listwrite.append(vv['Broadmann']) + #else: + listwrite.append(plots_label[kk]['Broadmann'][1]) + #if 'BroadmannDilate' in vv.keys(): + #listwrite.append(vv['BroadmannDilate']) + #else: + listwrite.append(plots_label[kk]['BroadmannDilate'][1]) + if 'Hammers' in vv.keys(): + listwrite.append(vv['Hammers']) + else: + listwrite.append(plots_label[kk]['Hammers'][1]) + if 'Resection' in vv.keys(): + listwrite.append(vv['Resection']) + else: + listwrite.append('not performed') + #[listwrite.append(x[1]) for x in vv.values()] + listwrite.append([float(format(plotMNI_Dict[kk][i],'.3f')) for i in range(3)]) + listwrite.append('not performed, csv generated from groupDisplay') + if len(full_list)>12: + for i_supp in range(len(full_list)-14): + listwrite.append(vv[full_list[14+i_supp]]) + writer.writerow(listwrite) + except: + pdb.set_trace() + + writer.writerow([]) + writer.writerow([]) + + try: + dict_sorted_tmp = OrderedDict(sorted(info_previous_csv[1]['bipolar'].items())) + except: + dict_sorted_tmp = OrderedDict(sorted(plots_label_bipolar.items())) + new_dict_sorted_tmp = {} + for kk,vv in dict_sorted_tmp.items(): + new_dict_sorted_tmp.update({kk:{}}) + [new_dict_sorted_tmp[kk].update({jj:ll[1]}) for jj,ll in vv.items()] + dict_sorted_tmp = OrderedDict(sorted(new_dict_sorted_tmp.items())) + + #dict_sorted_tmp = OrderedDict(sorted(info_previous_csv[1]['bipolar'].items())) + + for kk,vv in dict_sorted_tmp.iteritems(): + #pdb.set_trace() + listwrite = [kk] + if 'MarsAtlas' in vv.keys(): + listwrite.append(vv['MarsAtlas']) + else: + listwrite.append('not performed') + if 'MarsAtlasFull' in vv.keys(): + listwrite.append(vv['MarsAtlasFull']) + else: + listwrite.append('not performed') + if 'Freesurfer' in vv.keys(): + listwrite.append(vv['Freesurfer']) + else: + listwrite.append('not performed') + if 'Hippocampal Subfield' in vv.keys(): + listwrite.append(vv['Hippocampal Subfield']) + else: + listwrite.append('not performed') + if 'GreyWhite' in vv.keys(): + listwrite.append(vv['GreyWhite']) + else: + listwrite.append('not performed') + if 'AAL' in vv.keys(): + listwrite.append(vv['AAL']) + else: + listwrite.append(plots_label_bipolar[kk]['AAL'][1]) + if 'AALDilate' in vv.keys(): + listwrite.append(vv['AALDilate']) + else: + listwrite.append(plots_label_bipolar[kk]['AALDilate'][1]) + #if 'Broadmann' in vv.keys(): + # listwrite.append(vv['Broadmann']) + #else: + listwrite.append(plots_label_bipolar[kk]['Broadmann'][1]) + #if 'BroadmannDilate' in vv.keys(): + # listwrite.append(vv['BroadmannDilate']) + #else: + listwrite.append(plots_label_bipolar[kk]['BroadmannDilate'][1]) + + if 'Hammers' in vv.keys(): + listwrite.append(vv['Hammers']) + else: + listwrite.append(plots_label_bipolar[kk]['Hammers'][1]) + if 'Resection' in vv.keys(): + listwrite.append(vv['Resection']) + else: + listwrite.append('not performed') + + #[listwrite.append(x[1]) for x in vv.values()] + listwrite.append([float(format(info_plotMNI_bipolaireSB[kk][i],'.3f')) for i in range(3)]) + listwrite.append('not performed, csv generated from groupDisplay') + if len(full_list)>12: + for i_supp in range(len(full_list)-14): + listwrite.append(vv[full_list[14+i_supp]]) + writer.writerow(listwrite) + + writer.writerow([]) + writer.writerow([]) + + if info_previous_csv is not None: + if len(info_previous_csv[2])>0: + with open(str(rdi_csvnew), 'a') as csvfile: + writer = csv.writer(csvfile, delimiter='\t') + writer.writerow([u'Resection Information']) + + for kk,vv in info_previous_csv[2].iteritems(): + #writer.writerow([kk]) + if type(vv) == type(float()): + listwrite = [kk,vv] + writer.writerow(listwrite) + else: + writer.writerow([kk]) + for ll,bb in vv.iteritems(): + listwrite = [ll, format(float(bb),'.1f')] + writer.writerow(listwrite) + + else: + pass + else: + pass + #neuroHierarchy.databases.insertDiskItem(di, update=True ) + print("generation of csv done for %s"%ind_pat) + print("everything done") + + def changeAtlasfiltration(self): + + + #self.filtersAtlases.update({'locaMA':locas,'locaFS':locas_FS,'locaBM':locas_BM,'cogni':cognis,'resecMA':resecs,'resecFS':resecs_FS,'resecBM':resecs_BM}) + if self.FilterAtlascomboBox.currentIndex() == 0: + self.filterLocaMarsAtlas.clear() + self.filterLocaMarsAtlas.addItems(self.filtersAtlases['locaMA']) + + #self.filterCognition.clear() + #self.filterCognition.addItems(self.filtersAtlases['cogni']) + + self.filterResection.clear() + self.filterResection.addItems(self.filtersAtlases['resecMA']) + + self.filterCognitionLoca.clear() + self.filterCognitionLoca.addItems(self.filtersAtlases['locaMA']) + + self.filterStimulationLoca.clear() + self.filterStimulationLoca.addItems(self.filtersAtlases['locaMA']) + + + elif self.FilterAtlascomboBox.currentIndex() == 1: + + self.filterLocaMarsAtlas.clear() + self.filterLocaMarsAtlas.addItems(self.filtersAtlases['locaFS']) + + self.filterResection.clear() + self.filterResection.addItems(self.filtersAtlases['resecFS']) + #change font color depending on patient who has the information about the filtersAtlases + + self.filterCognitionLoca.clear() + self.filterCognitionLoca.addItems(self.filtersAtlases['locaFS']) + + self.filterStimulationLoca.clear() + self.filterStimulationLoca.addItems(self.filtersAtlases['locaFS']) + + elif self.FilterAtlascomboBox.currentIndex() == 2: + + self.filterLocaMarsAtlas.clear() + self.filterLocaMarsAtlas.addItems(self.filtersAtlases['locaBM']) + + self.filterResection.clear() + self.filterResection.addItems(self.filtersAtlases['resecBM']) + + self.filterCognitionLoca.clear() + self.filterCognitionLoca.addItems(self.filtersAtlases['locaBM']) + + self.filterStimulationLoca.clear() + self.filterStimulationLoca.addItems(self.filtersAtlases['locaBM']) + #change font color depending on patient who has the information about the filtersAtlases + + +if __name__ == "__main__": + app = QtGui.QApplication(sys.argv) + axon.initializeProcesses() + from brainvisa.data.readdiskitem import ReadDiskItem + from brainvisa.data.writediskitem import WriteDiskItem + QtCore.pyqtRemoveInputHook() + window = PatientDataFilterWidget() + window.show() + sys.exit(app.exec_()) diff --git a/patientinfo.py b/patientinfo.py new file mode 100644 index 0000000..bb1e349 --- /dev/null +++ b/patientinfo.py @@ -0,0 +1,301 @@ +# -*- coding: utf-8 -*- +# +# Functions to create UI, read and write patient data +# such as type of epilepsy, disease history... +#, and dictionary of available processing methods for each manip type +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 + +from PyQt4 import QtGui, QtCore +import pdb, os, json +from brainvisa.data.writediskitem import ReadDiskItem, WriteDiskItem + +# Types : Text, Line (short text) Int (integer), Float, Bool, Choice, MultiSelectChoice, EditableChoice (list of values, but a new one may be entered) +#function_mappings = {'checkbox_comor':checkbox_comor} + +defaultInfoTable= ('currentDate',('Date2', QtCore.QDate.currentDate(),u'Date:'), + 'patientBirthday',('Date2',None , u'Date de Naissance'), + 'patientAge',('Line',u'0','Age patient'), + 'sex',('Choice',[u'Inconnu', u'Féminin', u'Masculin'], u'Sexe'), + 'handedness', ('Choice', ['Inconnu', 'Droitier', 'Gaucher', 'Ambidextre'], u'Latéralité manuelle'), + 'Consentement', ('Date2', None, u'Consentement Date Signature'), + 'ProtocolsRecherche',('Line',None,u'Protocol'), + 'ProtocolDate',('Date2',None, u"Date d'entrée dans le protocol"), + 'previousHistory', ('Choice2', [u'Inconnu', u'Aucun', u'Crises fébriles', u'Infection SNC', u'Souffrance néonatale', u'TC grave', u'Vasculaire'], u'Antécédents Personnels'), + 'previousFamilyHistory', ('Choice2', [u'Inconnu', u'Dépression', u'Epilepsie', u'Parkinson', u'TOC'], u'Antécédents Familiaux'), + 'causaleDisease', ('Choice2', [u'Inconnu', u'Génétique', u'Inflammatoire', u'Métabolique', u'Phacomatose'], u'Maladie neurologique causale'), + 'mriLesion', ('Choice2', [u'Inconnu', u'Aucune', u'Cicatrice', u'Malformation vasculaire', u'MCD', u'Sclérose hippocampique', u'Tumeur', u'Multiple'], u'Lésion IRM'), + 'mrilesionDroite',('ButtonBox',[u'T', u'F',u'P', u'O', u'Ins'], u'Droite'), + 'mrilesionGauche',('ButtonBox',[u'T', u'F',u'P', u'O', u'Ins'], u'Gauche'), + 'neurologiqueExam', ('Choice', [u'Inconnu', u'Normal', u'Anormal'],u'Examen Neurologique'), + #'comorbiditylabel', ('Label',u'Comorbiditépouet'), + 'comoraucune', ('Checkbox',u'Aucune',u'Comorbidité','checkbox_comor'), + 'comorneuro', ('Choice2', [u'Inconnu', u'AVC', u'Dystonie', u'Epilepsie', u'Migraine', u'Parkinson'], u'comorbidité neurologique'), + 'comorpsy', ('Choice2', [u'Inconnu', u'Anxiété', u'Dépression', u'TOC'], u'comorbidité psychiatrique'), + 'comorautre', ('Choice2', [u'Inconnu', u'Parasomnies', u'SAS'], u'comorbidité autre') + #'comorbidity', ('ChoiceSub', [u'Inconnu', u'Aucune', u'Neurologique', u'Psychiatrique', u'Autre'],u'Comorbidité'), + #'medication', ('Compound',( + # 'antiseizure',('Line', None, u'Antiépileptique'), + # 'other',('Line', None, u'Autre'),), u'Traitement'), + #'seizureFrequency', ('Choice', [' < 1/mois', 'mensuelle', 'hebdomadaire', 'quotidienne'], u'Fréquence des crises'), + #'diseaseHistory': ('Text', u'Histoire de la maladie'), + #'exams', ('Compound', ( + # 'checkExams', ('MultiSelectChoice', ['Evaluation neuropsy', 'Evaluation psy', 'Test de Wada', 'IRMf', 'SPECT', 'PET'], ''), + # 'veegExam', ('Date', None, 'VEEG'), + # 'megExam', ('Date', None, 'VEEG'), + # 'fmriEegExam', ('Date', None, 'VEEG'), + # ), u'Examens réalisés'), + #'epilepsyType', ('Line',None, u'Type d\'épilepsie (avant SEEG)') + ) + + +def buildInt(parent, mini, maxi, label): + lay = QtGui.QHBoxLayout() + sp = QtGui.QSpinBox(parent) + sp.setRange(mini, maxi) + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(sp) + return (lay, sp) + +def buildChoice(parent, values, label): + lay = QtGui.QHBoxLayout() + combo = QtGui.QComboBox(parent) + combo.clear() + combo.addItems(values) + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(combo) + return (lay, combo) + +def buildChoice2(parent, values, label): + lay = QtGui.QHBoxLayout() + combo = QtGui.QComboBox(parent) + combo.clear() + model = QtGui.QStandardItemModel(len(values), 1)# 5 rows, 1 col + + for i,area in enumerate(values): + item = QtGui.QStandardItem(area) + item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + model.setItem(i+1, 0, item) + + combo.setModel(model) + combo.setEditable(True) + combo.activated.connect(lambda index, comb=combo: validatenewCombo(comb, index)) + #pdb.set_trace() + + #combo.addItems(values) + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(combo) + return (lay, combo) + +def buildChoiceSub(parent, values, label): + lay = QtGui.QHBoxLayout() + + combosub = QtGui.QMenu(parent) + combosub.setTitle(u'Comorbitité menu') + + for i,area in enumerate(values): + menu = QtGui.QMenu(area) + + combosub.addMenu(menu) + + #pdb.set_trace() + if i<2: + menu.addAction(QtGui.QAction(area, menu, checkable = True)) + else: + #for ii, area2 in enumerate(subvalues) + menu.addAction(QtGui.QAction("pouet", menu, checkable = True)) + + + + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(combosub) + return (lay, combosub) + +def buildDate(parent, date, label): + lay = QtGui.QHBoxLayout() + qdate = QtGui.QDateEdit(parent) + qdate.setDisplayFormat('dd/MM/yyyy') + if date is None: + qdate.setDate(QtCore.QDate.fromString('1900-01-01', 'yyyy-MM-dd')) + else: + qdate.setDate(date) + lay.addWidget(QtGui.QLabel(label,parent=parent)) + lay.addWidget(qdate) + return (lay, qdate) + + +def buildText(parent, label): + lay = QtGui.QHBoxLayout() + text = QtGui.QTextEdit(parent) + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(text) + return (lay, text) + +def buildLine(parent, defaultValue, label): + lay = QtGui.QHBoxLayout() + line = QtGui.QLineEdit(parent) + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + if defaultValue: + line.setText(str(defaultValue)) + lay.addWidget(line) + return (lay, line) + +def buildCompound(parent, values, label): + lay = QtGui.QHBoxLayout() + frame = QtGui.QGroupBox(parent) + frame.setLayout(lay) + if label is not None: + frame.setTitle(str(label)) + widgets = buildUI(frame, values) + for wid in reversed(widgets.values()): + lay.addWidget(wid) + return (frame, [frame,]+widgets.values()) + +def buildButtonBox(parent,values,label): + lay = QtGui.QHBoxLayout() + buttbox = QtGui.QDialogButtonBox(parent) + for i,area in enumerate(values): + buttbox.addButton(area,3) + + for test in buttbox.findChildren(QtGui.QPushButton): + test.setCheckable(True) + + buttbox.clicked.connect(lambda index, comb=buttbox: MRIlesionbox(comb, index)) + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(buttbox) + return (lay,buttbox) + +def buildLabel(parent,label): + lay = QtGui.QHBoxLayout() + labe = QtGui.QLabel(parent) + labe.setText(label) + + lay.addWidget(labe) + return (lay, labe) + + + +def buildCheckbox(parent, label, label2, checkbox_connect): + #function_mapping = {'checkbox_comor':checkbox_comor} + lay = QtGui.QHBoxLayout() + qcheck = QtGui.QCheckBox(parent) + qcheck.setText(label) + + #qcheck.clicked.connect(lambda index, ChecK=qcheck: function_mapping[checkbox_connect](ChecK, index)) + + lay.addWidget(QtGui.QLabel(label2, parent=parent)) + lay.addWidget(qcheck) + return (lay, qcheck) + + + +uiBuild = {'Int': buildInt, + 'Float':lambda:(None, None),# Not implemented + 'Line':buildLine, + 'Text':buildText, + 'Bool':lambda:(None, None),# Not implemented + 'Date':lambda p, value,label:(None, None),# Not implemented + 'Date2':buildDate, + 'Choice':buildChoice, + 'Choice2':buildChoice2, + 'ChoiceSub':buildChoiceSub, + 'ButtonBox':buildButtonBox, + 'MultiSelectChoice':lambda p, values, label:(None, None),# Not implemented + 'EditableChoice':lambda p,v,l : buildChoice(p,v,l,True), + 'Compound':buildCompound, + 'Label':buildLabel, + 'Checkbox':buildCheckbox, + } + +def buildUI(parent, infoTable=defaultInfoTable): + """ Generates a UI from infoTable) and returns a dictionary with the generated widgets""" + + #si c est un choice2 c'est editable du coup faut aller chercher sur le json la derniere version de la liste + wdi_global = ReadDiskItem('PatientInfoTemplate','Patient Template format') + di_global = list(wdi_global.findValues({}, None, False)) + + if len(di_global) > 0: + if os.path.isfile(str(di_global[0])): + print "read previous patienttemplate json" + from codecs import open as opencodecs + fin = opencodecs(str(di_global[0]),'r','latin1') + info_dicti = json.loads(fin.read().decode('latin1')) + fin.close() + + previous_lists_not_path = info_dicti['notPathoSpecific'] + else: + previous_lists_not_path = {} + else: + previous_lists_not_path = {} + + lay = QtGui.QVBoxLayout(parent) + output = {} + for i in range(int(len(infoTable)/2)): + key = infoTable[2*i] + value = infoTable[2*i+1] + if key in previous_lists_not_path.keys(): + default_list = set(value[1]) + update_list = set(previous_lists_not_path[key]) + diff_list = update_list-default_list + final_list = value[1] + list(diff_list) + item1 = value[0] + item3= value[2] + value = (item1,final_list,item3) + + if value is not None: + (l,wid) = uiBuild[value[0]](parent, *(value[1:])) + if l is not None: + if isinstance(l, QtGui.QLayout): + lay.addLayout(l) + elif isinstance(l, QtGui.QWidget): + lay.addWidget(l) + else: + print "Neither a layout nor a widget : cannot add object to the layout !" + if wid is not None: + output[key]=wid + + return output + +def dumpState(structuredWidgets): + """Generates a dumpable object that represents the content of the patient info from the widgets""" + pass + +def validatenewCombo(combo_modified, selectedIndex): + + AllItems = [unicode(combo_modified.itemText(i)) for i in range(combo_modified.count()) if unicode(combo_modified.itemText(i)) != ''] + + model = QtGui.QStandardItemModel(len(AllItems), 1) + + for i,area in enumerate(AllItems): + item = QtGui.QStandardItem(area) + item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + model.setItem(i+1, 0, item) + + combo_modified.clear() + combo_modified.setModel(model) + combo_modified.setEditable(True) + + +def MRIlesionbox(buttbox_modiffied,selectedIndex): + + button_sender = buttbox_modiffied.sender().text() + #print button_sender + #buttbox_modiffied.sender().font().setBold(True) + + if buttbox_modiffied.sender().isChecked(): + buttbox_modiffied.sender().setStyleSheet("background-color: rgb(90, 255, 95);") + else: + buttbox_modiffied.sender().setStyleSheet("") + + +#def checkbox_comor(qcheck, qindex): + #self.patientInfo['comoraucune'].isChecked() + #pdb.set_trace() diff --git a/prepareData.py b/prepareData.py new file mode 100644 index 0000000..3633ebf --- /dev/null +++ b/prepareData.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +# +# Importation et preparation des images et donnees necessaires +# a la localisation des electrodes +# +# (c) Inserm U836 2012 - Manik Bhattacharjee +# +# License GNU GPL v3 + +# 1) Choisir le patient/date +# 2) Trouver l'IRM preop et la postop +# 3) Segmenter le (ou retrouver la segmentation du) cortex preop +# 4) Recaler le preop et le postop +# 5) Sortir un dictionary avec les fichiers d'interet (base de donnes BV) + + + + + diff --git a/readElecLocalCSVFile.py b/readElecLocalCSVFile.py new file mode 100644 index 0000000..9a10413 --- /dev/null +++ b/readElecLocalCSVFile.py @@ -0,0 +1,147 @@ +# +# From Electrodes localisation, read CSV file coming from INTRANAT +# + +import csv, sys, os, re +from datetime import date +import pdb + +def readElecLocalCSVFile(infile = None): + + data = csv.reader(open(infile), delimiter = '\t') + contents = [] + for row in data: + contents.append(row) + + saveSpaceL = 0 + #find the string 'contact' to identify the starting line + for i1 in range(len(contents[1])): + for i2 in range(10): + try: + if contents[i2][i1] == 'contact': + savec = i1 + savel = i2 + if contents[i2][i1] == 'Use of MNI Template': + saveSpaceL = i2 + except: + continue + + props = {} + + if saveSpaceL == 0: + props['MarsAtlas'] = 'specific' + props['Freesurfer'] = 'empty' + props['HippoSubfieldFreesurfer'] = 'empty' + else: + if contents[saveSpaceL][contents[saveSpaceL].index('MarsAtlas')+1] == 'True': + props['MarsAtlas'] = 'MNI' + else: + props['MarsAtlas'] = 'specific' + + if contents[saveSpaceL][contents[saveSpaceL].index('Freesurfer')+1] =='True': + props['Freesurfer'] = 'MNI' + else: + props['Freesurfer'] = 'specific' + + if contents[saveSpaceL][contents[saveSpaceL].index('HippoSubfieldFreesurfer')+1] == 'True': + props['HippoSubfieldFreesurfer'] = 'MNI' + else: + props['HippoSubfieldFreesurfer'] = 'specific' + + startl = savel + 1 + #extract monopolar and bipolar contacts, assuming each list is separated by a two-lines blank + stimpolarity = ['monopolar', 'bipolar'] + ContactsInfos = {'monopolar':{},'bipolar':{}} + i = -2 + for pol in stimpolarity: + i = i + 2 + while contents[startl+i]: + # standard name : 'Ap12' (not A'12, Ap21, a'1a'2...) + nametmp = contents[startl+i][savec] + + testpol = re.search(" - ",nametmp) + if testpol is not None: + polarity = 'bipolar' + else: + polarity = 'monopolar' + + resection = [] + if contents[startl+i][contents[savel].index('Resection')] == 'not in resection': + resection = False + elif not contents[startl+i][contents[savel].index('Resection')] == 'resection not calculated': + resection = True + + #if not Contact.objects.filter(CRF = crf, name = name, polarity = polarity): + if nametmp not in ContactsInfos.keys(): + ContactsInfos[polarity].update({nametmp:{}}) + #newcontact = Contact(CRF = crf, name = name, polarity = polarity, resection = resection, segmentation = greywhite) + + for index_column in contents[savel]: + if index_column != 'contact': + + ContactsInfos[polarity][nametmp].update({index_column:contents[startl+i][contents[savel].index(index_column)]}) + + i += 1 + + ResectionInfos={} + i=i+2 + try: + while contents[startl+i]: + if contents[startl+i]==['Resection Information']: + actualAtlas = '' + elif contents[startl+i]==['mars_atlas']: + actualAtlas = 'mars_atlas' + ResectionInfos.update({'mars_atlas':{}}) + elif contents[startl+i]==['Freesurfer']: + actualAtlas = 'Freesurfer' + ResectionInfos.update({'Freesurfer':{}}) + elif contents[startl+i][0] == 'Volume resection (mm3):' : + ResectionInfos.update({'Volume resection (mm3):':contents[startl+i][1]}) + else: + ResectionInfos[actualAtlas].update({contents[startl+i][0]:contents[startl+i][1]}) + i += 1 + + except: + pass + + return (props,ContactsInfos,ResectionInfos) + + #try: + #ContactsInfos[nametmp].update({'MarsAtlas':contents[startl+i][contents[savel].index('MarsAtlas')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'Freesurfer':contents[startl+i][contents[savel].index('Freesurfer')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'HippoSubfieldFreeSurfer':contents[startl+i][contents[savel].index('HippoSubfieldFreeSurfer')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'MNI':contents[startl+i][contents[savel].index('MNI')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'ALL':contents[startl+i][contents[savel].index('ALL')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'ALLDilate':contents[startl+i][contents[savel].index('ALLDilate')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'Broadmann':contents[startl+i][contents[savel].index('Broadmann')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'Hammers':contents[startl+i][contents[savel].index('Hammers')]}) + #except: + #pass \ No newline at end of file diff --git a/readFreesurferLabelFile.py b/readFreesurferLabelFile.py new file mode 100644 index 0000000..868fc69 --- /dev/null +++ b/readFreesurferLabelFile.py @@ -0,0 +1,7 @@ +def readFreesurferLabelFile(freesurfer_label_file): + dict_label = {} + with open(freesurfer_label_file,'r') as inf: + for line in inf: + info_line = line.split() + dict_label.update({info_line[0]:info_line[1:]}) + return dict_label diff --git a/readFunctionalTractography.py b/readFunctionalTractography.py new file mode 100644 index 0000000..e476e79 --- /dev/null +++ b/readFunctionalTractography.py @@ -0,0 +1,52 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import csv, sys, os +import pdb + +def readFunctionalTractography(functional_result_file): + + if os.path.isfile(functional_result_file): + + if functional_result_file.split(".")[-1] == 'csv': + + full_dictionnary = {} + lastParam = None + with open(functional_result_file, 'r') as csvfile: + + spamreader = csv.reader(csvfile, delimiter='\t') + for row in spamreader: + if len(row)<1: + continue + if row[0] == 'Patient' or row[0] == 'Atlas': + full_dictionnary.update({row[0]:row[1]}) + elif row[0] == 'Param': + lastParam = row[1] + full_dictionnary.update({row[1]:{}}) + elif row[0] == 'Parcel_name': + import copy + row_parcel_names = copy.deepcopy(row[1:]) + row_parcel_names = [x.strip() for x in row_parcel_names] + #for i_parcels in range(len(row)-1): + #full_dictionnary[lastParam].update({row[i_parcels+1].strip():{}}) + elif row[0] == 'EndParcelsNames': + lastParam = None + else: + if lastParam is not None: + if row[0].strip() not in full_dictionnary[lastParam].keys(): + full_dictionnary[lastParam].update({row[0].strip():{}}) + else: + pdb.set_trace() + #if row[0].strip() in full_dictionnary[lastParam].keys(): + for i_parcels_bis in range(len(row_parcel_names)): + full_dictionnary[lastParam][row[0].strip()].update({row_parcel_names[i_parcels_bis]:row[i_parcels_bis+1]}) + + + return full_dictionnary + + else: + print("error, wrong file extension") + + else: + print("error, the file doesn't exist") + diff --git a/readSulcusLabelTranslationFile.py b/readSulcusLabelTranslationFile.py new file mode 100644 index 0000000..aba1ac7 --- /dev/null +++ b/readSulcusLabelTranslationFile.py @@ -0,0 +1,7 @@ +def readSulcusLabelTranslationFile(sulcus_label_file): + sulc_labels = [] + with open(sulcus_label_file,'r') as inf: + for line in inf: + sulc_labels.append(line.split()) + sulc_labels_dict = dict((int(value), key) for (value, key) in sulc_labels) + return sulc_labels_dict diff --git a/referentialconverter.py b/referentialconverter.py new file mode 100644 index 0000000..732e13b --- /dev/null +++ b/referentialconverter.py @@ -0,0 +1,441 @@ +# -*- coding: utf-8 -*- +from soma import aims +from soma.aims import apctools +from numpy import * +from brainvisa.data.writediskitem import ReadDiskItem +import pdb + +# Conversion de coordonnées d'un référentiel à un autre. +# Les transformations linéaires (matrices), le référentiel AC-PC, +# le référentiel pseudo-Talairach de BrainVisa et le référentiel +# Goetz peuvent être utilisés. +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +class ReferentialConverter: + """ This class allows to load linear transformations (matrices) from a referential to the "real" anatomist coordinates (image-based) + All declared referentials/transformations can then be used to convert coordinates from one referential to another. + Functions are provided to define the Goetz mesencephalon/PPN referential, the AC-PC referential (from the APC file in BrainVisa, brainvisa database access must be initialized by the caller), + the BEN referential (Benabid normalization, AC-PC with height normalization using Thalamus height and AC-PC length, no Y normalization). Any matrix transformation can be loaded.""" + def __init__(self): + self.availableRefs = {} + self.withMatrixFromReal = {} + self.withMatrixToReal = {} + + #def saveToFile + #self.availableRefs, self.Hthal, self.Ac, self.Pc, self.Ih, self.withMatrixFromReal, self.withMatrixToReal + #self.Oppn,self.XDppn, self.XGppn, self.Yppn, self.Zppn + + def availableReferentials(self): + return self.availableRefs + + def isRefAvailable(self, ref): + return self.availableRefs.has_key(ref) + + + ############################ Generic transformation matrices #################### + def setAnyRef2AnyRef(self, refFrom, refTo, transf, inverse = False): + if not self.isRefAvailable(refFrom): + if self.isRefAvailable(refTo): # If only the refTo is already known, just switch inputs + tmpRef = refTo + refTo = refFrom + refFrom = tmpRef + inverse = not inverse + else: + raise Exception("%s and %s are not known by referentialConverter ! Cannot set transform between them."%(str(refFrom), str(refTo))) + transf = self.anyMatrix2AimsMotion(transf) + if inverse: + transf = transf.inverse() + # Ok, now refFrom is a known referential, we just have to setup a T2 matrix such that fromRef --T1--> MainRef --T2-->toRef = transf + # T2 = transf*inv(T1) + if refFrom in self.withMatrixToReal: + t1inv = self.withMatrixToReal[refFrom].inverse() + elif refFrom in self.withMatrixFromReal: + t1inv = self.withMatrixFromReal[refFrom] + else: + raise Exception("Referential %s is not defined with a matrix !"%refFrom) + t2 = transf*t1inv + self.setTransformMatrix(refTo, t2, t2.inv()) + + def anyMatrix2AimsMotion(self, mat): + if type(mat) == aims.Motion: + return mat + elif type(mat) == list: + return aims.Motion(mat) + elif mat.__dict__.has_key('getInfos'): + infos = anaTransf.getInfos() + rot = infos['rotation_matrix'] + trans = infos['translation'] + return aims.Motion(rot[:3]+[trans[0]]+rot[3:6]+[trans[1]]+rot[6:]+[trans[2]]+[0,0,0,1]) + else: + raise Exception("Unknown transformation type : %s"+type(mat)) + + + def setAnatomistTransform(self, refName, anaTransf, toRef=True): + """ Adds a referential to the converter from an Anatomist Transformation object + :arg refName name of the new referential + :arg anaTransf anatomist transformation object (anatomist.Transformation) + :arg toRef if true, the provided transformation goes from the native referential to refName referential. If false, the opposite. + """ + infos = anaTransf.getInfos() + rot = infos['rotation_matrix'] + trans = infos['translation'] + m = aims.Motion(rot[:3]+[trans[0]]+rot[3:6]+[trans[1]]+rot[6:]+[trans[2]]+[0,0,0,1]) + #pdb.set_trace() + if toRef: + self.setTransformMatrix(refName, m.inverse(), m) + else: + self.setTransformMatrix(refName, m, m.inverse()) + + + def setRawTransformMatrix(self, refName, matrix, toRef=True): + """ Adds a referential to the converter from a raw transformation matrix ([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] for identity)""" + m = aims.Motion(matrix) + if toRef: + self.setTransformMatrix(refName, m.inverse(), m) + else: + self.setTransformMatrix(refName, m, m.inverse()) + + + + def setTransformMatrix(self, refName, matrixFromReal, matrixToReal): + """ Adds a referential to the converter from an aims.Motion matrix """ + #pdb.set_trace() + if matrixFromReal is not None: + self.availableRefs[refName] = True + self.withMatrixFromReal[refName] = matrixFromReal + if matrixToReal is not None: + self.availableRefs[refName] = True + self.withMatrixToReal[refName] = matrixFromReal + + def applyMatrix(self, x, y, z, matrix): + return matrix.transform( aims.Point3df(x,y,z) ).items() + + ############################ AC-PC intra-subject referential (no normalization) + def loadACPC(self, image): + """ Loads the .APC file linked to the provided Image Disk Item and sets AC-PC referential""" + print "****refConv**** Loading ACPC referential" + rdi = ReadDiskItem( 'Commissure coordinates', 'Commissure coordinates' ) + apcfile = rdi.findValue( image ) + points = apctools.apcRead(apcfile.fullPath()) + self.setACPC(points['acmm'], points['pcmm'], points['ihmm']) + + def setACPC(self, ac, pc, ih): + """ Set AC, PC and InterHemispheric points to define the AC-PC referentials """ + self.Ac = ac + self.Pc = pc + self.Ih = ih + self.availableRefs['AC-PC'] = True + + ####### AC-PC patient referential : no normalisation, origin at AC, X left to right, Y towards front, Z up + def real2AcPc(self, x, y, z): + """Convert 'real' native coordinates to AC-PC with origin at AC coordinates""" + # Compute axes + ac = array([self.Ac,]) + pc = array([self.Pc,]) + ih = array([self.Ih,]) + # Y axis is AC-PC axis towards the front + nacpc = linalg.norm(ac - pc) + taly = (ac-pc)/nacpc + + # X axis is perpendicular to the plane containing PC, AC and IH, so cross(Y axis, pseudoZ axis) + talx = cross(taly, ih - pc)# x = y^z + talx /= linalg.norm(talx) + talz = cross(talx, taly) + posT = array([[x, y, z]]) - ac + return [dot(posT[0], talx[0]), dot(posT[0], taly[0]), dot(posT[0], talz[0])] + + + def AcPc2Real(self, x, y, z): + """Convert AC-PC with origin at AC coordinates to 'real' native coordinates """ + # Compute axes + ac = array([self.Ac,]) + pc = array([self.Pc,]) + ih = array([self.Ih,]) + # Y axis is AC-PC axis towards the front + nacpc = linalg.norm(ac - pc) + taly = (ac-pc)/nacpc + + # X axis is perpendicular to the plane containing PC, AC and IH, so cross(Y axis, pseudoZ axis) + talx = cross(taly, ih - pc)# x = y^z + talx /= linalg.norm(talx) + + talz = cross(talx, taly) + + pos = -x*talx + y*taly + z*talz + ac + print " "+repr(pos.tolist()[0]) + return pos.tolist()[0] + + ############################### Anatomist Talairach Referential : bounding box normalizatiokn + def loadTalairach(self, image): + """From a DiskItem of an image, loads the pseudo-talairach transformation from BrainVisa database""" + rdi = ReadDiskItem( 'Transform Raw T1 MRI to Talairach-AC/PC-Anatomist', 'Transformation matrix' ) + di = rdi.findValue(image) + trans = aims.read( di.fullPath() ) # read a Motion object + self.setTransformMatrix('Talairach', trans, trans.inverse()) + + + ##############################" Goetz Referential for the PPN region (pons/mesencephalon) + # Conversion des coordonnées réelles vers les coordonnées Goetz : PROJECTION PERPENDICULAIRE AUX AXES (la projection utilisée pour les publis) + def setGoetz(self, Oppn, XDppn, XGppn, Yppn, Zppn): + """ Best referential for PPN studies according to Laurent Goetz ; PPNorthoGoetz -> orthoprojection on axes + PPN parallel Goetz is also available (points are projected onto each axis parallel to other axes) + Define the referential from the reference points : ponto-mesencephalon junction, + """ + self.Oppn = Oppn + self.XDppn = XDppn + self.XGppn = XGppn + self.Yppn = Yppn + self.Zppn = Zppn + self.availableRefs['PPNorthoGoetz'] = True + self.availableRefs['PPNparaGoetz'] = True + + def real2Gorth(self, x, y, z): + """ Convert native coordinates to normalized orthogonal Goetz referential""" + u = array([x - self.Oppn[0], y - self.Oppn[1], z - self.Oppn[2]]) + # Vecteurs de la base + oxg = array([self.XGppn[0] - self.Oppn[0], self.XGppn[1] - self.Oppn[1], self.XGppn[2] - self.Oppn[2]]) + oxd = array([self.XDppn[0] - self.Oppn[0], self.XDppn[1] - self.Oppn[1], self.XDppn[2] - self.Oppn[2]]) + oy = array([self.Yppn[0] - self.Oppn[0], self.Yppn[1] - self.Oppn[1], self.Yppn[2] - self.Oppn[2]]) + oz = array([self.Zppn[0] - self.Oppn[0], self.Zppn[1] - self.Oppn[1], self.Zppn[2] - self.Oppn[2]]) + # Normes des vecteurs de la base + nxg = linalg.norm(oxg) + nxd = linalg.norm(oxd) + ny = linalg.norm(oy) + nz = linalg.norm(oz) + # vecteurs unitaires + oxg /= nxg + oxd /= nxd + oy /= ny + oz /= nz + # Produit scalaire entre vecteurs unitaires des axes et la position u pour avoir les coordonnées orthogonale, + # division par la norme des vecteurs pour rapporter aux longueurs de reference + if not self.isRightSideGoetz(u[0], u[1], u[2]): # Selon le coté + return [dot(u, oxg)/nxg, dot(u, oy)/ny, dot(u, oz)/nz, 1] + else: # Right side -> negative X + return [dot(u, oxd)/nxd, dot(u, oy)/ny, dot(u, oz)/nz, -1] + + # Conversion des coordonnées réelles vers les coordonnées Goetz : PROJECTION PARALLELE AUX AXES : résolution d'un système d'équations (m*X+n*Y+o*Z = U) + def real2G(self, x, y, z): + """ Convert native coordinates to normalized parallel Goetz referential""" + u = array([[x - self.Oppn[0], y - self.Oppn[1], z - self.Oppn[2]]]) + # Vecteurs de la base + oxg = array([[self.XGppn[0] - self.Oppn[0], self.XGppn[1] - self.Oppn[1], self.XGppn[2] - self.Oppn[2]]]) + oxd = array([[self.XDppn[0] - self.Oppn[0], self.XDppn[1] - self.Oppn[1], self.XDppn[2] - self.Oppn[2]]]) + oy = array([[self.Yppn[0] - self.Oppn[0], self.Yppn[1] - self.Oppn[1], self.Yppn[2] - self.Oppn[2]]]) + oz = array([[self.Zppn[0] - self.Oppn[0], self.Zppn[1] - self.Oppn[1], self.Zppn[2] - self.Oppn[2]]]) + # Normes des vecteurs de la base + nxg = linalg.norm(oxg) + nxd = linalg.norm(oxd) + ny = linalg.norm(oy) + nz = linalg.norm(oz) + # vecteurs unitaires + oxg /= nxg + oxd /= nxd + oy /= ny + oz /= nz + + if not self.isRightSideGoetz(u[0][0], u[0][1], u[0][2]): # Left side + matrice = vstack((oxg, oy, oz)) + #print "MATRICE : " + repr(matrice) + #print "SOLUTION : " + repr(linalg.solve(matrice, u[0])) + #print "CHECK U : " + repr(dot(matrice, linalg.solve(matrice, u[0]))) + return (linalg.solve(matrice, u[0])/array([nxg, ny, nz])).tolist() + [1,] + else: + matrice = vstack((oxd, oy, oz)) + return (linalg.solve(matrice, u[0])/array([nxd, ny, nz])).tolist()+[-1,] + + + + # Conversion des coordonnées Goetz vers les coordonnées réelles : PROJECTION PARALLELE AUX AXES u=x_u*X+y_u*Y+z_u*Z + def g2Real(self, xg, yg, zg, side): + """ Convert normalized parallel Goetz referential to native coordinates""" + if side == -1: # Right side + return [self.Oppn[0] + xg*(self.XDppn[0] - self.Oppn[0]) + yg*(self.Yppn[0] - self.Oppn[0]) + zg*(self.Zppn[0] - self.Oppn[0]),\ + self.Oppn[1] + xg*(self.XDppn[1] - self.Oppn[1]) + yg*(self.Yppn[1] - self.Oppn[1]) + zg*(self.Zppn[1] - self.Oppn[1]),\ + self.Oppn[2] + xg*(self.XDppn[2] - self.Oppn[2]) + yg*(self.Yppn[2] - self.Oppn[2]) + zg*(self.Zppn[2] - self.Oppn[2])] + elif side == 1: # left side + return [self.Oppn[0] + xg*(self.XGppn[0] - self.Oppn[0]) + yg*(self.Yppn[0] - self.Oppn[0]) + zg*(self.Zppn[0] - self.Oppn[0]),\ + self.Oppn[1] + xg*(self.XGppn[1] - self.Oppn[1]) + yg*(self.Yppn[1] - self.Oppn[1]) + zg*(self.Zppn[1] - self.Oppn[1]),\ + self.Oppn[2] + xg*(self.XGppn[2] - self.Oppn[2]) + yg*(self.Yppn[2] - self.Oppn[2]) + zg*(self.Zppn[2] - self.Oppn[2])] + else: + print "ERROR : side value in invalid in g2Real : "+repr(side) + + # Est-on à droite de la ligne médiane ? + def isRightSideGoetz(self, x, y, z): + """ Check which side of the brain we are on, from PPN Goetz referential landmarks """ + oy = array([self.Yppn[0] - self.Oppn[0], self.Yppn[1] - self.Oppn[1], self.Yppn[2] - self.Oppn[2]]) + oz = array([self.Zppn[0] - self.Oppn[0], self.Zppn[1] - self.Oppn[1], self.Zppn[2] - self.Oppn[2]]) + pseudoX = cross(oy, oz) + return dot(pseudoX, array([x,y,z])) > 0 + + # Conversion des coordonnées Goetz vers les coordonnées réelles : PROJECTION PERPENDICULAIRE AUX AXES + # Résolution du système d'inconnu u tel que u.X = x_u, u.Y = y_u et u.Z = z_u ('.' est le produit scalaire) + # OLD VERSION (slightly slower than the newer one using solve) + def g2RealOrth2(self, xg, yg, zg, side): + """ Convert normalized orthogonal Goetz referential to native coordinates (old, slow version)""" + u = array([[xg, yg, zg]]) + # Vecteurs de la base + oxg = array([[self.XGppn[0] - self.Oppn[0], self.XGppn[1] - self.Oppn[1], self.XGppn[2] - self.Oppn[2]]]) + oxd = array([[self.XDppn[0] - self.Oppn[0], self.XDppn[1] - self.Oppn[1], self.XDppn[2] - self.Oppn[2]]]) + oy = array([[self.Yppn[0] - self.Oppn[0], self.Yppn[1] - self.Oppn[1], self.Yppn[2] - self.Oppn[2]]]) + oz = array([[self.Zppn[0] - self.Oppn[0], self.Zppn[1] - self.Oppn[1], self.Zppn[2] - self.Oppn[2]]]) + # Normes des vecteurs de la base + nxg = linalg.norm(oxg) + nxd = linalg.norm(oxd) + ny = linalg.norm(oy) + nz = linalg.norm(oz) + # vecteurs unitaires + oxg /= nxg + oxd /= nxd + oy /= ny + oz /= nz + # MATLAB : ([norm(OXg), norm(OY), norm(OZ)].*[xg, yg, zg])*inv([OXg'./norm(OXg), OY'./norm(OY), OZ'./norm(OZ)]) + Oppn + if side == -1: # Right side + matrice = hstack((oxd.T, oy.T, oz.T)) + result = dot(array([[nxd, ny, nz]])*u, linalg.inv(matrice)) + array(self.Oppn) + + elif side == 1: # left side + matrice = hstack((oxg.T, oy.T, oz.T)) + result = dot(array([[nxg, ny, nz]])*u, linalg.inv(matrice)) + array(self.Oppn) + else: + print "ERROR : side value is invalid in g2RealOrth : "+repr(side) + + return result.tolist()[0] + + + # Conversion des coordonnées Goetz vers les coordonnées réelles : PROJECTION PERPENDICULAIRE AUX AXES + # Résolution du système d'inconnu u tel que u.X = x_u, u.Y = y_u et u.Z = z_u ('.' est le produit scalaire) + def g2RealOrth(self, xg, yg, zg, side): + """ Convert normalized orthogonal Goetz referential to native coordinates""" + u = array([[xg, yg, zg]]) + # Vecteurs de la base + oxg = array([[self.XGppn[0] - self.Oppn[0], self.XGppn[1] - self.Oppn[1], self.XGppn[2] - self.Oppn[2]]]) + oxd = array([[self.XDppn[0] - self.Oppn[0], self.XDppn[1] - self.Oppn[1], self.XDppn[2] - self.Oppn[2]]]) + oy = array([[self.Yppn[0] - self.Oppn[0], self.Yppn[1] - self.Oppn[1], self.Yppn[2] - self.Oppn[2]]]) + oz = array([[self.Zppn[0] - self.Oppn[0], self.Zppn[1] - self.Oppn[1], self.Zppn[2] - self.Oppn[2]]]) + # Normes des vecteurs de la base + nxg = linalg.norm(oxg) + nxd = linalg.norm(oxd) + ny = linalg.norm(oy) + nz = linalg.norm(oz) + # vecteurs unitaires + oxg /= nxg + oxd /= nxd + oy /= ny + oz /= nz + # MATLAB : ([norm(OXg), norm(OY), norm(OZ)].*[xg, yg, zg])*inv([OXg'./norm(OXg), OY'./norm(OY), OZ'./norm(OZ)]) + Oppn + if side == -1: # Right side + matrice = vstack((oxd, oy, oz)) + result = linalg.solve(matrice, array([nxd, ny, nz])*u[0]) + array(self.Oppn) + elif side == 1: # left side + matrice = vstack((oxg, oy, oz)) + result = linalg.solve(matrice, array([nxg, ny, nz])*u[0]) + array(self.Oppn) + else: + print "ERROR : side value is invalid in g2RealOrth : "+repr(side) + return result.tolist() + + + ############################### Ben's coordinates Benabid AC-PC with thalamus normalization + ###### NORMALIZED BEN'S COORDINATES (normalized along Y and Z axis) + def setBens(self, ac, pc, ih, hthal): + """Set reference points for Ben's normalization : Anterior Commissure, + Posterior Commissure, InterHemispheric point (above AC-PC), + Thalamus height (top of the thalamus, bottom of lateral ventricle, up from AC-PC axial slice). + Origin is at PC, no normalization on X axis, + AC-PC normalization on Y (y/norm(ac-pc)*12.0), Thalamus Height normalization on Z (z/norm(thal-pc)*8.0) + """ + self.setACPC(ac,pc,ih) + self.Hthal = hthal + self.availableRefs['Bens'] = True + + def real2Bens(self, x, y, z): + """Convert native coordinates to normalized Ben's coordinates (IMPLEMENTATION NEVER USED/TESTED)""" + # Compute axes : + ac = array([self.Ac,]) + pc = array([self.Pc,]) + ih = array([self.Ih,]) + hthal = array([self.Hthal,]) + u = array([[x, y, z]]) + # Y axis is AC-PC axis towards the front + nacpc = linalg.norm(ac - pc) + thaly = (ac-pc)/nacpc + # X axis is perpendicular to the plane containing PC, AC and IH, so cross(Y axis, pseudoZ axis) + thalx = cross(thaly, ih - pc)# x = y^z + thalx /= linalg.norm(thalx) + thalz = cross(thalx, thaly) + thalHeight = dot((hthal - pc)[0], thalz[0]) + return [dot(u, thalx), dot(u, thaly)*12.0/nacpc, dot(u, thalz)*8.0/thalHeight] + + def bens2Real(self, xb, yb, zb): + """Convert normalized Ben's coordinates to native coordinates""" + # x is not normalized, so the value is just the distance from the AC-PC line, with X<0 for the right hemisphere + # Compute axes : + ac = array([self.Ac,]) + pc = array([self.Pc,]) + ih = array([self.Ih,]) + hthal = array([self.Hthal,]) + + # Y axis is AC-PC axis towards the front + nacpc = linalg.norm(ac - pc) + thaly = (ac-pc)/nacpc + + # X axis is perpendicular to the plane containing PC, AC and IH, so cross(Y axis, pseudoZ axis) + thalx = cross(thaly, ih - pc)# x = y^z + thalx /= linalg.norm(thalx) + thalz = cross(thalx, thaly) + thalHeight = dot((hthal - pc)[0], thalz[0]) + + pos = (-xb * thalx) + (yb * nacpc / 12.0) * thaly + (zb * thalHeight / 8.0) * thalz + pc # -xb because the sign should ne changed for a direct referential + + return pos.tolist()[0] + + #############################" Generic Conversion ###################################### + # UNIVERSAL REFERENTIAL CONVERTER TO REAL MRI COORDS + def anyRef2Real(self, coords, referential): + """Convert coords [x,y,z] or [x,y,z,side] to native coordinates from any defined referential""" + if not self.isRefAvailable(referential): + print "Referential %s not available"%referential + return None + withSide = {'PPNparaGoetz':self.g2Real, 'PPNorthoGoetz':self.g2RealOrth} + noSide = {'Bens':self.bens2Real, 'AC-PC':self.AcPc2Real,'real':lambda x,y,z:[x,y,z]} + if referential in self.withMatrixToReal: + return self.applyMatrix(coords[0], coords[1], coords[2], self.withMatrixToReal[referential]) + if referential in withSide and size(coords)>3: + return withSide[referential](coords[0], coords[1], coords[2], coords[3]) + elif referential in noSide: + return noSide[referential](coords[0], coords[1], coords[2]) + else: + print "anyRef2Real : no such referential or invalid coords : "+repr(referential)+" -> "+repr(coords) + return None + + # UNIVERSAL REFERENTIAL CONVERTER from REAL MRI COORDS + def real2AnyRef(self, coords, referential): + """Convert coords [x,y,z] or [x,y,z,side] to any defined referential from native coordinates""" + if not self.isRefAvailable(referential): + print "Referential %s not available"%referential + return None + withSide = {} + noSide = {'Bens':self.real2Bens, 'AC-PC':self.real2AcPc,'real':lambda x,y,z:[x,y,z], 'PPNparaGoetz':self.real2G, 'PPNorthoGoetz':self.real2Gorth} + #pdb.set_trace() + if referential in self.withMatrixFromReal: + return self.applyMatrix(coords[0], coords[1], coords[2], self.withMatrixFromReal[referential]) + elif referential in withSide and size(coords)>3: + return withSide[referential](coords[0], coords[1], coords[2], coords[3]) + elif referential in noSide: + return noSide[referential](coords[0], coords[1], coords[2]) + else: + print "anyRef2Real : no such referential or invalid coords : "+repr(referential)+" -> "+repr(coords) + return None + + # Converts coords from any ref to any other referential + def anyRef2AnyRef(self, coords, referentialFrom, referentialTo): + """Convert coords [x,y,z] or [x,y,z,side] from any referential to any other referential""" + reals = self.anyRef2Real(coords, referentialFrom) + if reals is None: + print "Cannot convert to real !" + return None + if size(coords) > 3: # There is side information in coords[3] + reals = reals[:3]+coords[3:] # Keep the side information in case it is needed by the destination referential + return self.real2AnyRef(reals,referentialTo) diff --git a/seegprocessing.py b/seegprocessing.py new file mode 100644 index 0000000..69f2822 --- /dev/null +++ b/seegprocessing.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# +# Functions to process SEEG files, and dictionary of available processing methods for each manip type +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# +# Define all functions to process SEEG data like this: +#---------------------------------------------- +# def extractBetaFunction(seegfilepath): +# try: +# doSomething(seegfilepath) +# return True +# else: +# return False +# extractBeta = ('Extract Beta', 'Extracts the beta band from the seeg signal and saves it in the DB', extractBetaFunction) +#--------------------------------------------------- +# Then you can add the processing method to 'processors' and add the name of each 'manip' it can be applied to + + +from externalprocesses import * + +# --------------------- Specific Functions ---------------------------- +def localizeFunction(seegfilepath): + try: + matlabCallNB("localize('%s')"%seegfilepath) + return True + except: + return False + +localize = ('Localizer processing', 'Launches JP Lachaux\'s localize matlab process', localizeFunction) + +# --------------------- Linking functions to manips ---------------------------- +processors = { localize:['VISU', 'MVEB', 'MLAH'], } +# ---------------------- Dependencies ------------------------------ +# if "advancedAnalysis" needs "basicAnalysis", add advancedAnalysis:[basicAnalysis,] to dependencies +dependencies = {localize:[],} +# ------------------------ Generic functions -------------------------- +def getProcessingMethods(currentManip = None): + """ Returns all processing methods availables for the manip name provided. If no manip is provided, returns a dictionnary with all processors""" + allManips = set([m for manips in processors.itervalues() for m in manips]) + allProcessorsByManip = dict([(m,[p for p in processors if m in processors[p]]) for m in allManips]) + if currentManip is not None: + return allProcessorsByManip[currentManip] + else: + return allProcessorsByManip + +def getManipNameFromDirName(dirname): + return dirname.split('_')[0] + \ No newline at end of file diff --git a/standard_fit.py b/standard_fit.py new file mode 100644 index 0000000..e7aa33d --- /dev/null +++ b/standard_fit.py @@ -0,0 +1,116 @@ +#!/usr/bin/env nosetests -vs +# coding=utf-8 +""" +Linear algebra standard fitting module + +(C) 2013 hashnote.net, Alisue +""" +__author__ = 'Alisue (lambdalisue@hashnote.net)' +__version__ = '0.1.0' +__date__ = '2013-10-28' +__all__ = ['standard_fit', 'projection', 'distance', 'function'] + +import numpy as np + +def standard_fit(X): + """ + Find (n - 1) dimensional standard (e.g. line in 2 dimension, plane in 3 + dimension, hyperplane in n dimension) via solving Singular Value + Decomposition. + + The idea was explained in the following references + + - http://www.caves.org/section/commelect/DUSI/openmag/pdf/SphereFitting.pdf + - http://www.geometrictools.com/Documentation/LeastSquaresFitting.pdf + - http://www.ime.unicamp.br/~marianar/MI602/material%20extra/svd-regression-analysis.pdf + - http://www.ling.ohio-state.edu/~kbaker/pubs/Singular_Value_Decomposition_Tutorial.pdf + + Example: + >>> XY = [[0, 1], [3, 3]] + >>> XY = np.array(XY) + >>> C, N = standard_fit(XY) + >>> C + array([ 1.5, 2. ]) + >>> N + array([-0.5547002 , 0.83205029]) + + Args: + X: n x m dimensional matrix which n indicate the number of the dimension + and m indicate the number of points + + Returns: + [C, N] where C is a centroid vector and N is a normal vector + """ + # Find the average of points (centroid) along the columns + C = np.average(X, axis=0) + # Create CX vector (centroid to point) matrix + CX = X - C + # Singular value decomposition + U, S, V = np.linalg.svd(CX) + # The last row of V matrix indicate the eigenvectors of + # smallest eigenvalues (singular values). + N = V[-1] + import pdb + pdb.set_trace() + return C, N + +def projection(x, C, N): + """ + Create orthogonal projection matrix of x on the plane + + Args: + x: n x m dimensional matrix + C: n dimensional vector whicn indicate the centroid of the standard + N: n dimensional vector which indicate the normal vector of the standard + + Returns: + n x m dimensional matrix which indicate the orthogonal projection points + on the plane + """ + rows, cols = x.shape + NN = np.tile(N, (rows, 1)) + D = distance(x, C, N) + DD = np.tile(D, (cols, 1)).T + return x - DD * NN + +def distance(x, C, N): + """ + Calculate an orthogonal distance between the points and the standard + + Args: + x: n x m dimensional matrix + C: n dimensional vector whicn indicate the centroid of the standard + N: n dimensional vector which indicate the normal vector of the standard + + Returns: + m dimensional vector which indicate the orthogonal disntace. the value + will be negative if the points beside opposite side of the normal vector + """ + return np.dot(x-C, N) + +def function(x, C, N): + """ + Calculate an orthogonal projection of the points on the standard + + Args: + x: (n-1) x m dimensional matrix + C: n dimensional vector whicn indicate the centroid of the standard + N: n dimensional vector which indicate the normal vector of the standard + + Returns: + m dimensional vector which indicate the last attribute value of + orthogonal projection + """ + Ck = C[0:-1] # centroid for known parameters + Nk = N[0:-1] # normal for known parmeters + Cu = C[-1] # centroid for unknown parameter + Nu = N[-1] # normal for unknown parameter + return np.dot(x-Ck, Nk) * -1.0 / Nu + Cu + +#=============================================================================== +# +# Unittest +# +#=============================================================================== +if __name__ == '__main__': + import doctest; doctest.testmod() diff --git a/templatewidget.py b/templatewidget.py new file mode 100644 index 0000000..74676a9 --- /dev/null +++ b/templatewidget.py @@ -0,0 +1,235 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# Widget to choose or create a common template for group studies +# Examples include MNI referential with Colin27 of MNI152 templates, custom SPM/Dartel templates... +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# +# +from PyQt4 import QtGui, QtCore, uic + +import sys, os + + +from brainvisa import axon +from brainvisa.data.readdiskitem import ReadDiskItem +from brainvisa.data.writediskitem import WriteDiskItem +import registration +import numpy + +from externalprocesses import * +from checkSpmVersion import * + +########## SPM calls +# Convert SPM normalization _sn.mat to vector field +spm_SnToField8 = """try, spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +FileNameSN = '%s'; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.matname{1}=FileNameSN; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.vox=[NaN NaN NaN]; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.bb=NaN*ones(2,3); +matlabbatch{1}.spm.util.defs.comp{1}.inv.space{1}=['%s' ',1']; +matlabbatch{1}.spm.util.defs.ofname='%s'; +matlabbatch{1}.spm.util.defs.fnames=''; +matlabbatch{1}.spm.util.defs.savedir.saveusr{1}=spm_str_manip(FileNameSN,'h'); +matlabbatch{1}.spm.util.defs.interp=1; +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" # %(FileNameSN, FileSource, ofname) -> '_sn.mat' file and source image FileSource (normalized with the _sn). For the Database, we want y__inverse.nii, so we need ofname = '_inverse' --> Maybe should provide also the output dir ? Right now, same as _sn.mat + +# API changed in SPM12... +spm_SnToField12 = """try, spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +FileNameSN = '%s'; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.matname{1}=FileNameSN; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.vox=[NaN NaN NaN]; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.bb=NaN*ones(2,3); +matlabbatch{1}.spm.util.defs.comp{1}.inv.space = {'%s'}; +matlabbatch{1}.spm.util.defs.out{1}.savedef.ofname = '%s'; +matlabbatch{1}.spm.util.defs.out{1}.savedef.savedir.saveusr{1}=spm_str_manip(FileNameSN,'h'); +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + +spm_SnToField = spm_SnToField12 + +# Using a vector field, transform points MRI Scanner-based coordinates to MNI coordinates +spm_ConvertPointsToMNI = """try, +P='%s'; +P1=spm_vol([P ',1,1']); +P2=spm_vol([P ',1,2']); +P3=spm_vol([P ',1,3']); +[V1,XYZ]=spm_read_vols(P1); +V2=spm_read_vols(P2); +V3=spm_read_vols(P3); + +%% Apply tranformation to electrodes +wPosElectrode=%s; +for i1=1:size(PosElectrode,1) + D=(XYZ(1,:)-PosElectrode(i1,1)).^2+(XYZ(2,:)-PosElectrode(i1,2)).^2+(XYZ(3,:)-PosElectrode(i1,3)).^2; + [tmp,order]=sort(D); + tmp=tmp(1:18); %% cubic neighborhood + order=order(1:18); + W=1./tmp; %% weight inverse to distance + if sum(isinf(W))>0 + W=[1 zeros(1,length(W)-1)]; + end + wPosElectrode(i1,:)=[sum(V1(order).*W)./sum(W) sum(V2(order).*W)./sum(W) sum(V3(order).*W)./sum(W)]; +end +dlmwrite(%s,wPosElectrode, 'delimiter',' ','precision',16); +;catch, disp 'AN ERROR OCCURED'; end;quit; +""" # %(field_inverse.nii,matrixOfCoords(plots, [1,2,3]), fileOut) + +# Read deformation field y__inverse.nii, apply the vector field to scanner-based coordinates of electrodes +spm_normalizePoints = """ +try, P='%s'; +P1=spm_vol([P ',1,1']); +P2=spm_vol([P ',1,2']); +P3=spm_vol([P ',1,3']); +[V1,XYZ]=spm_read_vols(P1); +V2=spm_read_vols(P2); +V3=spm_read_vols(P3); + +%% Apply tranformation to electrodes +PosElectrode = dlmread('%s'); +wPosElectrode=PosElectrode; +for i1=1:size(PosElectrode,1) +D=(XYZ(1,:)-PosElectrode(i1,1)).^2+(XYZ(2,:)-PosElectrode(i1,2)).^2+(XYZ(3,:)-PosElectrode(i1,3)).^2; +[tmp,order]=sort(D); +tmp=tmp(1:18); %% cubic neighborhood +order=order(1:18); +W=1./tmp; %% weight inverse to distance +if sum(isinf(W))>0 +W=[1 zeros(1,length(W)-1)]; +end +wPosElectrode(i1,:)=[sum(V1(order).*W)./sum(W) sum(V2(order).*W)./sum(W) sum(V3(order).*W)./sum(W)]; +end +dlmwrite('%s',wPosElectrode,'precision',18); +catch, disp 'AN ERROR OCCURED'; end;quit; +""" + + +class TemplateMRI: + def __init__(self, name="", refId=-1, volRefId=-1, anatomist=None): + self.name = name + self.refId = refId + if refId != -1 and volRefId == -1: + self.volRefId = refId + else: + self.volRefId = volRefId + self.referentialDiskItem = None + self.referentialAnatomist = None + if self.refId != -1: + try: + self.referentialDiskItem = registration.getTransformationManager().referential(self.refId) + if anatomist is not None: + self.referentialAnatomist = anatomist.createReferential(self.referentialDiskItem) + except: + pass + self.volumes = None + self.findVolumesInDB(volRefId) + + def findVolumesInDB(self, volRefId=None): + if self.volumes: + return self.volumes + if volRefId is None: + volRefId = self.volRefId + rdi = ReadDiskItem( 'anatomical Template', 'aims readable volume formats', requiredAttributes={'referential':str(volRefId)} ) + self.volumes = list( rdi._findValues( {}, None, False ) ) + return self.volumes + + def normalizeCoordinates(self, coords, referential): + """ Fonction that normalizes a list of (x,y,z) to the template referential if sufficient data is available for the provided referential (MUST BE REIMPLEMENTED BY EACH KIND OF TEMPLATE) """ + print "TemplateMRI : normalization not implemented for generic class !" + return [] + pass + def denormalizeCoordinates(self, coords, referential): + """ Fonction that denormalizes a list of (x,y,z) from the template referential if sufficient data is available to the provided referential (MUST BE REIMPLEMENTED BY EACH KIND OF TEMPLATE) """ + print "TemplateMRI : denormalization not implemented for generic class !" + return [] + pass + + def resampleVolume(referential, readPath, writePath): + """ Resamples the provided volume (Nifti...) in the template referential """ + print "TemplateMRI : resampling not implemented for generic class !" + return [] + pass + + +class TemplateMNI(TemplateMRI): + + def __init__(self, anatomist = None): + TemplateMRI.__init__(self, name="MNI", refId=registration.talairachMNIReferentialId, volRefId='19bfee8e-51b1-4d9e-8721-990b9f88b12f', anatomist=anatomist) #registration.talairachMNIReferentialId + + def normalizeCoordinates(self, coords, refId): + """Normalize the coordinates in MNI referential. refId is the uuid of a referential of the T1pre used to store the coords""" + return self.convertT1ScannerBasedToMni(coords, refId) + + def getT1preMniTransform(self, refId): + """Returns the path of the transformation to MNI (vector field) and compute it if necessary (from _sn.mat)""" + # Get referential file + transfoManager = registration.getTransformationManager() + refDiskitem = transfoManager.referential( refId ) + # Find _sn.mat + rdi = ReadDiskItem( 'SPM2 normalization matrix', 'Matlab file' ) + rdiT1 = ReadDiskItem( 'Raw T1 MRI', 'aims readable volume formats') + diT1 = rdiT1.findValue(refDiskitem) + di = rdi.findValue(diT1) + if di is None: + print "SPM deformation _sn.mat not found in database" + return None + # Convert to field + wdi = WriteDiskItem( 'SPM normalization inverse deformation field', 'NIFTI-1 image' ) + diField = wdi.findValue(di) + if diField is None: + print "Cannot find path to save MNI vector field in the DB" + return None + #For a file /database/y_SubjectName_inverse.nii, get SubjectName_inverse + ofname = os.path.basename(diField.fullPath()).lstrip('y_').rsplit('.',1)[0] + if not os.path.exists(diField.fullPath()): + matlabRun(spm_SnToField%(str(di.fullPath()), str(diT1.fullPath()), ofname) ) + else: + print "Deformation field already present : not recomputed in %s"%diField.fullPath() + if os.path.exists(diField.fullPath()): + return diField.fullPath() + else: + print "Matlab did not convert the MNI transform to vector field !" + return None + + def convertT1ScannerBasedToMni(self, points, refId): + """Converts an array of points [x,y,z] in scanner-based coords to MNI coords if deformation field is available""" + field = self.getT1preMniTransform(refId) + if field is None: + print "MNI deformation field not found" + return None + tmpOutput = getTmpFilePath('csv') + arr = numpy.asarray(points)#([ [1,2,3], [4,5,6], [7,8,9] ]) + numpy.savetxt(tmpOutput, arr, delimiter=",") + print "Launching SPM NORMALIZE POINTS with %s"%tmpOutput + matlabRun(spm_normalizePoints % (field, tmpOutput, tmpOutput)) + out = numpy.loadtxt(tmpOutput, delimiter=",") + os.remove(tmpOutput) + if numpy.array_equal(out, arr): + print "Points to MNI : Error, result read is identical to input" + return None + if out.shape != arr.shape: + print "Points to MNI : Error, result (%s) has not the same number of elements as input (%s)"%(repr(out),repr(arr)) + return None + return out.tolist() + + + +class TemplateWidget(QtGui.QWidget): + def __init__(self, app=None): + QtGui.QWidget.__init__(self) + + + + +if __name__ == "__main__": + app = QtGui.QApplication(sys.argv) + axon.initializeProcesses() + from brainvisa.data.readdiskitem import ReadDiskItem + from brainvisa.data.writediskitem import WriteDiskItem + window = TemplateWidget() + window.show() + sys.exit(app.exec_()) diff --git a/templatewidget.ui b/templatewidget.ui new file mode 100644 index 0000000..9037e11 --- /dev/null +++ b/templatewidget.ui @@ -0,0 +1,141 @@ + + + Form + + + + 0 + 0 + 432 + 657 + + + + Form + + + + + + + + Choix d'un template + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Créer un template Dartel + + + + + + + + Nom du template + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Générer le template + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 341 + + + + + + + + +

q c #723102", +",q c #CF976B", +"'q c #F6BE92", +")q c #EEBA92", +"!q c #EDC3A3", +"~q c #ECC7AA", +"{q c #E9D0BC", +"]q c #727A6E", +"^q c #B5B8B0", +"/q c #466D33", +"(q c #446B32", +"_q c #92A188", +":q c #295915", +"r c #535950", +",r c #161815", +"'r c #889384", +")r c #5C645A", +"!r c #255512", +"~r c #889E7D", +"{r c #265313", +"]r c #0E3900", +"^r c #133E04", +"/r c #899D7D", +"(r c #315E1E", +"_r c #295815", +":r c #5F7F4D", +"s c #823809", +",s c #EACFB8", +"'s c #1D2B12", +")s c #365420", +"!s c #677460", +"~s c #81897E", +"{s c #191A18", +"]s c #97A492", +"^s c #5F824D", +"/s c #789568", +"(s c #B9BAB6", +"_s c #9DAA94", +":s c #1E4C0C", +"t c #885024", +",t c #6F3001", +"'t c #333832", +")t c #454A43", +"!t c #2E5B1A", +"~t c #A2AD99", +"{t c #ABB3A5", +"]t c #2B551B", +"^t c #295317", +"/t c #A5AF9E", +"(t c #A1AB98", +"_t c #92A187", +":t c #C4C2C3", +"u c #E9D0BD", +",u c #EACDB4", +"'u c #EBC8AB", +")u c #F1B98D", +"!u c #C89164", +"~u c #834416", +"{u c #833A09", +"]u c #D09A6D", +"^u c #F9C195", +"/u c #19260F", +"(u c #96A192", +"_u c #CBD9C5", +":u c #909A8A", +"v c #F0C4A3", +",v c #EEC7A9", +"'v c #ECCAAF", +")v c #304A1D", +"!v c #A6B2A1", +"~v c #828D7F", +"{v c #BBCAB4", +"]v c #6F776B", +"^v c #BEC0BB", +"/v c #5C7D4B", +"(v c #335C22", +"_v c #91A386", +":v c #406A2D", +"w c #592500", +",w c #552300", +"'w c #532400", +")w c #663A17", +"!w c #825A3B", +"~w c #916E51", +"{w c #B2947C", +"]w c #E0C7B3", +"^w c #EAD6C6", +"/w c #E6DBD3", +"(w c #E9E1DB", +"_w c #EAE5E1", +":w c #E7E3E1", +"x c #698E51", +",x c #8AA474", +"'x c #557C40", +")x c #0F3A04", +"!x c #123606", +"~x c #452705", +"{x c #861B04", +"]x c #1D2F11", +"^x c #1A1A19", +"/x c #0B0A09", +"(x c #020100", +"_x c #080300", +":x c #140C06", +"y c #311600", +",y c #260F00", +"'y c #342214", +")y c #887A6F", +"!y c #D0C6BD", +"~y c #EBE3DD", +"{y c #CBC6C3", +"]y c #514E4B", +"^y c #4A4847", +"/y c #C2C1C0", +"(y c #6A7864", +"_y c #495047", +":y c #899484", +"z c #EDEDEC", +",z c #A9A8A7", +"'z c #363433", +")z c #060200", +"!z c #0D0600", +"~z c #100600", +"{z c #170A00", +"]z c #665547", +"^z c #D7C3B2", +"/z c #EDD5C1", +"(z c #ECC4A5", +"_z c #FBD1B0", +":z c #AD8260", +"A c #2B5918", +",A c #9CAA92", +"'A c #426B2E", +")A c #1A4F07", +"!A c #3B6D24", +"~A c #234F13", +"{A c #2A5619", +"]A c #749164", +"^A c #AEB5A7", +"/A c #C1BFBF", +"(A c #8EA283", +"_A c #7E9672", +":A c #78916B", +"B c #CDB8A7", +",B c #695546", +"'B c #231306", +")B c #140600", +"!B c #1E150F", +"~B c #938C87", +"{B c #E0DBD7", +"]B c #9A9693", +"^B c #312E2D", +"/B c #312F2F", +"(B c #A2A2A0", +"_B c #879184", +":B c #96A090", +"C c #180700", +",C c #BEAEA1", +"'C c #F3E4D8", +")C c #E9DDD3", +"!C c #E9DFD6", +"~C c #E1D8D1", +"{C c #CCC4BE", +"]C c #5A544F", +"^C c #3F3D3B", +"/C c #CFCECC", +"(C c #F1F0EF", +"_C c #EAEBEA", +":C c #29411A", +"D c #98A88D", +",D c #759165", +"'D c #1C4E09", +")D c #486F38", +"!D c #AEB6A7", +"~D c #476D36", +"{D c #272F06", +"]D c #711D04", +"^D c #1E3211", +"/D c #474A44", +"(D c #D1D0D1", +"_D c #9D9B98", +":D c #181512", +"E c #B7B9B5", +",E c #4F763C", +"'E c #124302", +")E c #5A7D47", +"!E c #B2B9AC", +"~E c #3F6830", +"{E c #172C00", +"]E c #602005", +"^E c #2E471C", +"/E c #060D01", +"(E c #151416", +"_E c #B0B0B1", +":E c #908F8F", +"F c #798275", +",F c #C9D7C1", +"'F c #636B61", +")F c #636B60", +"!F c #576F4C", +"~F c #AAABA6", +"{F c #547443", +"]F c #012A00", +"^F c #1E4B0C", +"/F c #8C9E80", +"(F c #B7BBB2", +"_F c #476F35", +":F c #6E8A5D", +"G c #51584F", +",G c #C5D6C0", +"'G c #9FAA9A", +")G c #0E1724", +"!G c #123105", +"~G c #193E0E", +"{G c #214E10", +"]G c #355F26", +"^G c #4F743F", +"/G c #698957", +"(G c #779268", +"_G c #587D46", +":G c #52773F", +"H c #B0B4AD", +",H c #869B78", +"'H c #093600", +")H c #ADB4A9", +"!H c #3C6928", +"~H c #3B6727", +"{H c #8FA085", +"]H c #B6BAAF", +"^H c #A9AFA4", +"/H c #2E5C1C", +"(H c #0E3B01", +"_H c #164509", +":H c #275115", +"I c #788175", +",I c #292B27", +"'I c #4B5148", +")I c #4C743B", +"!I c #194807", +"~I c #123907", +"{I c #134002", +"]I c #305B1D", +"^I c #92A287", +"/I c #B3B6B0", +"(I c #819876", +"_I c #769168", +":I c #577C44", +"J c #C8D7C3", +",J c #0D1624", +"'J c #102F01", +")J c #1B4D09", +"!J c #124601", +"~J c #708B62", +"{J c #1A460A", +"]J c #0D3600", +"^J c #315A1F", +"/J c #A4B09B", +"(J c #9DA994", +"_J c #295A16", +":J c #759066", +"K c #737A70", +",K c #334C22", +"'K c #3A5A22", +")K c #3E5E28", +"!K c #343D2F", +"~K c #767F73", +"{K c #CDDEC8", +"]K c #7C8678", +"^K c #080907", +"/K c #787970", +"(K c #455E38", +"_K c #355826", +":K c #3A5F28", +"L c #9BA991", +",L c #BBBBB7", +"'L c #648552", +")L c #1C4C0C", +"!L c #718D61", +"~L c #90A282", +"{L c #A9B1A4", +"]L c #8DA07F", +"^L c #60824E", +"/L c #235210", +"(L c #1F4E10", +"_L c #517B43", +":L c #ACA086", +"M c #4C6639", +",M c #344F21", +"'M c #87947E", +")M c #DADCD9", +"!M c #CFDFCA", +"~M c #0C1521", +"{M c #3B5D64", +"]M c #142E06", +"^M c #123406", +"/M c #113305", +"(M c #94A688", +"_M c #6A8B58", +":M c #345F23", +"N c #346120", +",N c #5B7E49", +"'N c #789467", +")N c #869C78", +"!N c #A7B0A1", +"~N c #6C885F", +"{N c #4E723D", +"]N c #0F3A07", +"^N c #352C06", +"/N c #831B04", +"(N c #F4F6F3", +"_N c #B9C4B1", +":N c #97A88B", +"O c #787873", +",O c #7C8177", +"'O c #6D845F", +")O c #1F4F0B", +"!O c #174506", +"~O c #1B490A", +"{O c #184A07", +"]O c #1D4D0B", +"^O c #1C4D0C", +"/O c #124400", +"(O c #597C47", +"_O c #BABEB5", +":O c #093900", +"P c #898788", +",P c #6A7C5E", +"'P c #1B480E", +")P c #587D44", +"!P c #C1BFC2", +"~P c #A9B2A1", +"{P c #4F773D", +"]P c #587E44", +"^P c #8FA184", +"/P c #ADB4A5", +"(P c #779069", +"_P c #215111", +":P c #92A386", +"