isospec-1.9.1/0000755000175000017500000000000013373520171013117 5ustar rusconirusconiisospec-1.9.1/IsoSpecPy/0000755000175000017500000000000013420367305014776 5ustar rusconirusconiisospec-1.9.1/IsoSpecPy/IsoSpecPy/0000755000175000017500000000000013420352725016654 5ustar rusconirusconiisospec-1.9.1/IsoSpecPy/IsoSpecPy/__init__.py0000644000175000017500000002552013373520171020770 0ustar rusconirusconi# -*- coding: utf-8 -*- # # Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. # # This file is part of IsoSpec. # # IsoSpec is free software: you can redistribute it and/or modify # it under the terms of the Simplified ("2-clause") BSD licence. # # IsoSpec is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # You should have received a copy of the Simplified BSD Licence # along with IsoSpec. If not, see . # from .isoFFI import isoFFI import re import types from . import PeriodicTbl from .confs_passthrough import ConfsPassthrough try: xrange except NameError: xrange = range regex_pattern = re.compile('([A-Z][a-z]?)([0-9]*)') def IsoParamsFromFormula(formula): global regex_pattern symbols = [] atomCounts = [] for elem, cnt in re.findall(regex_pattern, formula): symbols.append(elem) atomCounts.append(int(cnt) if cnt is not '' else 1) try: masses = tuple(PeriodicTbl.symbol_to_masses[s] for s in symbols) probs = tuple(PeriodicTbl.symbol_to_probs[s] for s in symbols) except KeyError: raise ValueError("Invalid formula") return (atomCounts, masses, probs) class Iso(object): def __init__(self, formula=None, get_confs=False, atomCounts=None, isotopeMasses=None, isotopeProbabilities=None): """Initialize Iso.""" self.iso = None if formula is None and not all([atomCounts, isotopeMasses, isotopeProbabilities]): raise Exception("Either formula or ALL of: atomCounts, isotopeMasses, isotopeProbabilities must not be None") if formula is not None: self.atomCounts, self.isotopeMasses, self.isotopeProbabilities = IsoParamsFromFormula(formula) if atomCounts is not None: self.atomCounts = atomCounts if isotopeMasses is not None: self.isotopeMasses = isotopeMasses if isotopeProbabilities is not None: self.isotopeProbabilities = isotopeProbabilities for sublist in self.isotopeProbabilities: for prob in sublist: if not (0.0 < prob <= 1.0): raise ValueError("All isotope probabilities p must fulfill: 0.0 < p <= 1.0") self.isotopeNumbers = tuple(map(len, self.isotopeMasses)) assert self.isotopeNumbers == tuple(map(len, self.isotopeProbabilities)) self.dimNumber = len(self.isotopeNumbers) self.get_confs = get_confs self.ffi = isoFFI.clib offsets = [] if get_confs: i = 0 for j in xrange(self.dimNumber): newl = [] for k in xrange(self.isotopeNumbers[j]): newl.append(i) i += 1 offsets.append(tuple(newl)) self.offsets = tuple(offsets) self.iso = self.ffi.setupIso(self.dimNumber, self.isotopeNumbers, self.atomCounts, [i for s in self.isotopeMasses for i in s], [i for s in self.isotopeProbabilities for i in s]) def __iter__(self): if self.get_confs: for i in xrange(self.size): yield(self.masses[i], self.probs[i], self.confs[i]) else: for i in xrange(self.size): yield (self.masses[i], self.probs[i]) def __del__(self): if self.iso is not None: self.ffi.deleteIso(self.iso) def parse_conf(self, cptr, starting_with = 0): return tuple(tuple(cptr[i+starting_with] for i in o) for o in self.offsets) class IsoThreshold(Iso): def __init__(self, threshold, absolute=False, get_confs = False, **kwargs): super(IsoThreshold, self).__init__(get_confs = get_confs, **kwargs) self.threshold = threshold self.absolute = absolute generator = self.ffi.setupIsoThresholdGenerator(self.iso, threshold, absolute, 1000, 1000) tabulator = self.ffi.setupThresholdTabulator(generator, True, True, True, get_confs) self.size = self.ffi.confs_noThresholdTabulator(tabulator) def c(typename, what, mult = 1): return isoFFI.ffi.gc(isoFFI.ffi.cast(typename + '[' + str(self.size*mult) + ']', what), self.ffi.freeReleasedArray) self.masses = c("double", self.ffi.massesThresholdTabulator(tabulator)) self.lprobs = c("double", self.ffi.lprobsThresholdTabulator(tabulator)) self.probs = c("double", self.ffi.probsThresholdTabulator(tabulator)) if get_confs: self.sum_isotope_numbers = sum(self.isotopeNumbers) self.raw_confs = c("int", self.ffi.confsThresholdTabulator(tabulator), mult = self.sum_isotope_numbers) self.confs = ConfsPassthrough(lambda idx: self._get_conf(idx), self.size) self.ffi.deleteThresholdTabulator(tabulator) self.ffi.deleteIsoThresholdGenerator(generator) def _get_conf(self, idx): return self.parse_conf(self.raw_confs, starting_with = self.sum_isotope_numbers * idx) def __len__(self): return self.size class IsoLayered(Iso): def __init__(self, prob_to_cover, get_confs = False, **kwargs): super(IsoLayered, self).__init__(get_confs = get_confs, **kwargs) self.prob_to_cover = prob_to_cover generator = self.ffi.setupIsoLayeredGenerator(self.iso, prob_to_cover, 0.3, 1000, 1000, True) tabulator = self.ffi.setupLayeredTabulator(generator, True, True, True, get_confs) self.size = self.ffi.confs_noLayeredTabulator(tabulator) def c(typename, what, mult = 1): return isoFFI.ffi.gc(isoFFI.ffi.cast(typename + '[' + str(self.size*mult) + ']', what), self.ffi.freeReleasedArray) self.masses = c("double", self.ffi.massesLayeredTabulator(tabulator)) self.lprobs = c("double", self.ffi.lprobsLayeredTabulator(tabulator)) self.probs = c("double", self.ffi.probsLayeredTabulator(tabulator)) if get_confs: self.sum_isotope_numbers = sum(self.isotopeNumbers) self.raw_confs = c("int", self.ffi.confsLayeredTabulator(tabulator), mult = self.sum_isotope_numbers) self.confs = ConfsPassthrough(lambda idx: self._get_conf(idx), self.size) self.ffi.deleteLayeredTabulator(tabulator) self.ffi.deleteIsoLayeredGenerator(generator) def _get_conf(self, idx): return self.parse_conf(self.raw_confs, starting_with = self.sum_isotope_numbers * idx) def __len__(self): return self.size class IsoGenerator(Iso): def __init__(self, get_confs=False, **kwargs): self.cgen = None super(IsoGenerator, self).__init__(get_confs = get_confs, **kwargs) self.conf_space = isoFFI.ffi.new("int[" + str(sum(self.isotopeNumbers)) + "]") self.firstuse = True def __iter__(self): if not self.firstuse: raise NotImplementedError("Multiple iterations through the same IsoGenerator object are not supported. Either create a new (identical) generator for a second loop-through, or use one of the non-generator classes, which do support being re-used.") self.firstuse = False cgen = self.cgen if self.get_confs: while self.advancer(cgen): self.conf_getter(cgen, self.conf_space) yield (self.mass_getter(cgen), self.xprob_getter(cgen), self.parse_conf(self.conf_space)) else: while self.advancer(cgen): yield (self.mass_getter(cgen), self.xprob_getter(cgen)) class IsoThresholdGenerator(IsoGenerator): def __init__(self, threshold, absolute=False, get_confs=False, use_lprobs=False, **kwargs): super(IsoThresholdGenerator, self).__init__(get_confs, **kwargs) self.threshold = threshold self.absolute = absolute self.cgen = self.ffi.setupIsoThresholdGenerator(self.iso, threshold, absolute, 1000, 1000) self.advancer = self.ffi.advanceToNextConfigurationIsoThresholdGenerator self.xprob_getter = self.ffi.lprobIsoThresholdGenerator if use_lprobs else self.ffi.probIsoThresholdGenerator self.mass_getter = self.ffi.massIsoThresholdGenerator self.conf_getter = self.ffi.get_conf_signatureIsoThresholdGenerator def __del__(self): if self.cgen is not None: self.ffi.deleteIsoThresholdGenerator(self.cgen) class IsoLayeredGenerator(IsoGenerator): def __init__(self, prob_to_cover = 0.99, get_confs=False, do_trim = False, use_lprobs=False, **kwargs): super(IsoLayeredGenerator, self).__init__(get_confs, **kwargs) self.delta = prob_to_cover self.cgen = self.ffi.setupIsoLayeredGenerator(self.iso, self.delta, 0.3, 1000, 1000, do_trim) self.advancer = self.ffi.advanceToNextConfigurationIsoLayeredGenerator self.xprob_getter = self.ffi.lprobIsoLayeredGenerator if use_lprobs else self.ffi.probIsoLayeredGenerator self.mass_getter = self.ffi.massIsoLayeredGenerator self.conf_getter = self.ffi.get_conf_signatureIsoLayeredGenerator def __del__(self): if self.cgen is not None: self.ffi.deleteIsoLayeredGenerator(self.cgen) class IsoOrderedGenerator(IsoGenerator): def __init__(self, get_confs=False, use_lprobs=False, **kwargs): super(IsoOrderedGenerator, self).__init__(get_confs, **kwargs) self.cgen = self.ffi.setupIsoOrderedGenerator(self.iso, 1000, 1000) self.advancer = self.ffi.advanceToNextConfigurationIsoOrderedGenerator self.xprob_getter = self.ffi.lprobIsoOrderedGenerator if use_lprobs else self.ffi.probIsoOrderedGenerator self.mass_getter = self.ffi.massIsoOrderedGenerator self.conf_getter = self.ffi.get_conf_signatureIsoOrderedGenerator def __del__(self): if self.cgen is not None: self.ffi.deleteIsoLayeredGenerator(self.cgen) __version__ = "1.9.1" # For compatibility with 1.0.X class CompatIsoWrapper(object): def __init__(self): from .IsoSpecPy import IsoSpec, IsoSpecify, IsoPlot self.IsoSpec = IsoSpec self.IsoSpecify = IsoSpecify self.IsoPlot = IsoPlot IsoSpecPy = CompatIsoWrapper() isospec-1.9.1/IsoSpecPy/IsoSpecPy/PeriodicTbl.py0000644000175000017500000000237613373520171021435 0ustar rusconirusconifrom .isoFFI import isoFFI from collections import defaultdict try: xrange except NameError: xrange = range number_of_isotopic_entries = isoFFI.clib.NUMBER_OF_ISOTOPIC_ENTRIES symbol_to_masses = defaultdict(tuple) symbol_to_probs = defaultdict(tuple) symbol_to_atomic_number = {} for i in xrange(number_of_isotopic_entries): symbol = isoFFI.ffi.string(isoFFI.clib.elem_table_symbol[i]).decode("ascii") symbol_to_masses[symbol] += (isoFFI.clib.elem_table_mass[i],) symbol_to_probs[symbol] += (isoFFI.clib.elem_table_probability[i],) symbol_to_atomic_number[symbol] = isoFFI.clib.elem_table_atomicNo[i] symbol_to_masses = dict(symbol_to_masses) symbol_to_probs = dict(symbol_to_probs) # Several derivative convenience dicts... symbol_to_massprob = dict((key, [zip(symbol_to_masses[key], symbol_to_probs[key])]) for key in symbol_to_probs.keys()) def crossprod(l1, l2): return sum(x1*x2 for x1, x2 in zip(l1, l2)) symbol_to_avg_mass = dict((key, crossprod(symbol_to_masses[key], symbol_to_probs[key])) for key in symbol_to_probs.keys()) def maxprod(l1, l2): return max(zip(l1, l2), key = lambda x: x[1])[0] symbol_to_monoisotopic_mass = dict((key, maxprod(symbol_to_masses[key], symbol_to_probs[key])) for key in symbol_to_probs.keys()) isospec-1.9.1/IsoSpecPy/IsoSpecPy/IsoSpecPy.py0000644000175000017500000002453713373520171021116 0ustar rusconirusconi# -*- coding: utf-8 -*- # # Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. # # This file is part of IsoSpec. # # IsoSpec is free software: you can redistribute it and/or modify # it under the terms of the Simplified ("2-clause") BSD licence. # # IsoSpec is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # You should have received a copy of the Simplified BSD Licence # along with IsoSpec. If not, see . # ''' Bunch of deprecated functions for 1.0.X compatibility. Avoid using them: there is a considerable overhead associated with using the old interface... The backward compatibility module is also very rudimentary, somewhat incomplete and not very well tested too... The current API is implemented in __init__.py, use that instead ''' try: xrange except NameError: xrange = range import re class IsoSpec(): def __init__( self, _atomCounts, _isotopeMasses, _isotopeProbabilities, _stopCondition, tabSize = 1000, # ignored hashSize = 1000, # ignored step = 0.3, # ignored trim = True, # True not supported yet, treated as False anyway method = 'layered' # layered actually not supported yet... ): isoargs = { "formula" : None, "get_confs" : True, "atomCounts" : _atomCounts, "isotopeMasses" : _isotopeMasses, "isotopeProbabilities" : _isotopeProbabilities, } self.dimNumber = len(_atomCounts) self._isotopeNumbers = [len(x) for x in _isotopeMasses] self.allIsotopeNumber = sum(self._isotopeNumbers) self._atomCounts = _atomCounts self._isotopeMasses = _isotopeMasses self._isotopeProbabilities = _isotopeProbabilities self._stopCondition = _stopCondition from .__init__ import IsoThreshold try: algo = { 'layered' : lambda total_prob: IsoLayered(total_prob, **isoargs), 'ordered' : lambda total_prob: IsoLayered(total_prob, **isoargs), 'threshold_absolute' : lambda threshold: IsoThreshold(threshold, True, **isoargs), 'threshold_relative' : lambda threshold: IsoThreshold(threshold, False, **isoargs), 'layered_estimating' : lambda total_prob: IsoLayered(total_prob, **isoargs) }[method] except KeyError: raise Exception("Invalid ISO method") # Reference to iso needs to be held in this object: it will deallocate masses/lprobs/etc arrays on C++ side if we # allow GC to collect it prematurely self.iso = algo(_stopCondition) self.masses = self.iso.masses self.lprobs = self.iso.lprobs self.probs = self.iso.probs self.confs = self.iso.confs self.size = self.iso.size if method == 'ordered': L = sorted(zip(self.masses, self.lprobs, self.probs, self.confs), key = lambda x: -x[1]) self.masses, self.lprobs, self.probs, self.confs = zip(*L) @staticmethod def IsoFromFormula(formula, cutoff, tabSize = 1000, hashSize = 1000, classId = None, method = 'threshold_relative', step = 0.25, trim = True): # It's much easier to just parse it in python than to use the C parsing function # and retrieve back into Python the relevant object sizes symbols = re.findall("\D+", formula) atom_counts = [int(x) for x in re.findall("\d+", formula)] if not len(symbols) == len(atom_counts): raise ValueError("Invalid formula") from .PeriodicTbl import symbol_to_masses, symbol_to_probs try: masses = tuple(symbol_to_masses[symbol] for symbol in symbols) probs = tuple(symbol_to_probs[symbol] for symbol in symbols) except KeyError: raise ValueError("Invalid formula") return IsoSpec(atom_counts, masses, probs, cutoff, tabSize, hashSize, step, trim, method) def __len__(self): return self.size def getConfsRaw(self): return (self.masses, self.lprobs, self.confs) # def get_conf_by_no(self, clist, idx): # idx *= self.allIsotopeNumber # ret = [] # for ison in self._isotopeNumbers: # ret.append(tuple(clist[idx:idx+ison])) # idx += ison # return tuple(ret) def getConfs(self): masses, logProbs, isoCounts = self.getConfsRaw() rows_no = len(masses) cols_no = len(isoCounts) // len(masses) masses = list(masses) logProbs= list(logProbs) confs = [] for i in xrange(rows_no): confs.append([x for sublist in isoCounts[i] for x in sublist]) return masses, logProbs, confs def splitConf(self, l, offset = 0): conf = [] idx = self.allIsotopeNumber * offset for i in xrange(self.dimNumber): conf.append(tuple(l[idx:idx+self._isotopeNumbers[i]])) idx += self._isotopeNumbers[i] return tuple(conf) def confStr(self, conf): return '\t'.join([' '.join([str(x) for x in y]) for y in conf]) def printConfs(self): masses, logProbs, isoCounts = self.getConfsRaw() confs = [] step = sum(self._isotopeNumbers) for i in xrange(len(masses)): confs.append((masses[i], logProbs[i], self.splitConf(isoCounts, i))) for conf in confs: print(("Mass = {0}\t and log-prob = {1} and prob = {2}\t and configuration"\ "=\t{3}").format(conf[0], conf[1], math.exp(conf[1]), self.confStr(conf[2]))) class IsoPlot(dict): def __init__(self, iso, bin_w): self.iso = iso self.bin_w = bin_w masses, logProbs, _isoCounts = iso.getConfsRaw() dd = defaultdict(Summator) for i in xrange(len(masses)): dd[float(int(masses[i]/bin_w))*bin_w].add(math.exp(logProbs[i])) for key, val in dd.items(): self[key] = val.get() def IsoSpecify( formula, cutoff, method= 'layered', output_format = 'numpy_arrays', trim = True, _step = 0.25, _trim = True, _tabSize = 1000, _hashSize = 1000 ): """ Call IsoSpec on a formula with a given cutoff. This function wraps around the IsoSpec class. Parameters ---------- formula : char a string of a form '< Element Tag 1 >< Count 1 > ... ', e.g. 'C100H202'. Using IUPAC conventions to name elements. cutoff : float The cutoff value. See description of the method argument. method : char Can take one of the following values: 'layered', 'layered_estimating', 'threshold_absolute', 'threshold_relative', 'ordered'. The threshold versions of the algorithm rely on user providing a precise lower bound on the reported peak heights. This can be specified in absolute terms ('threshold_absolute'), i.e. in terms of the limiting probability of the isotopologue, or as a percentage of the heighest peak ('threshold_relative'). The layered versions of the algorithm rely on calculating consecutive values of peak thresholds on flight. The ultimate goal is to reach a peak probability that assures that the sum of probabilities of the more probable isotopologues exceeds the provided cutoff value. The sequence of consecutive thresholds can be generated in two ways. The default way, 'layered_estimating', estimates the threshold to joint probability function by a progressive linear spline, check Anal Chem. 2017 Mar 21;89(6):3272-3277. doi: 10.1021/acs.analchem.6b01459. Epub 2017 Mar 8. The other way, 'layered', estimates a threshold as a 30%% quantile of the probabilities gathered in the fringe set, i.e. isotopologues that are direct neighbours of the previously accepted layer. Finally, choosing the 'ordered' version will provide a loglinear version of the algorithm that relies on the priority queue. This version automatically sorts the configurations by their probability. trim while using a layered method, should one discard superfluously obtained isotopologues, i.e. such that without them the set of reported isotopologues already is an optimal p-set. output_format Should the output be presented as lists ('lists'), or as numpy arrays ('numpy_arrays'). Returns ------- masses masses of isotopologues, either a list or a numpy array. logProbs logarithms of probabilities (theoretical heights) of isotopologues, either a list or a numpy array. confs counts of isotopologues (extended chemical formulas that include counts of isotopes of elements) """ assert output_format in ('lists', 'numpy_arrays'), "Wrong value of output_format. Should be either 'lists' or 'numpy_arrays'." assert method in ('layered', 'ordered', 'threshold_absolute', 'threshold_relative', 'layered_estimating'), "Wrong value of method. Should be among 'layered', 'ordered', 'threshold_absolute', 'threshold_relative', or 'layered_estimating'." assert isinstance(cutoff, float), "Provided cut off ain't a float." assert isinstance(formula, str), "Provided formula off ain't a string." iso = IsoSpec.IsoFromFormula( formula, cutoff, tabSize = 1000, hashSize = 1000, classId = None, method = method, step = 0.25, trim = trim ) if output_format == 'lists': masses, logProbs, confs = iso.getConfs() else: masses, logProbs, confs = iso.getConfsNumpy() # print 'Rev Startek is a silly old chump and his mother dresses up silly.' return masses, logProbs, confs isospec-1.9.1/IsoSpecPy/IsoSpecPy/kahan.py0000644000175000017500000000352013373520171020307 0ustar rusconirusconi# -*- coding: utf-8 -*- # # Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. # # This file is part of IsoSpec. # # IsoSpec is free software: you can redistribute it and/or modify # it under the terms of the Simplified ("2-clause") BSD licence. # # IsoSpec is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # You should have received a copy of the Simplified BSD Licence # along with IsoSpec. If not, see . # class SSummator: def __init__(self): self.partials = [] # sorted, non-overlapping partial sums def add(self, x): i = 0 for y in self.partials: if abs(x) < abs(y): x, y = y, x hi = x + y lo = y - (hi - x) if lo: self.partials[i] = lo i += 1 x = hi self.partials[i:] = [x] def get(self): return sum(self.partials) class Summator: def __init__(self, keep_partials = False): self.sum = 0.0 self.c = 0.0 self.keep_partials = keep_partials self.partials = [] def add(self, what): y = what - self.c t = self.sum + y c = (t - self.sum) - y self.sum = t if self.keep_partials: self.partials.append(self.sum) def get(self): return self.sum def get_partials(self): return self.partials class PosNegSummator: def __init__(self): self.pos = Summator() self.neg = Summator() def add(self, what): if what >= 0: self.pos.add(what) else: self.neg.add(-what) def get(self): return self.pos.get() - self.neg.get() isospec-1.9.1/IsoSpecPy/IsoSpecPy/confs_passthrough.py0000644000175000017500000000041413373520171022763 0ustar rusconirusconi class ConfsPassthrough(object): def __init__(self, confs_parser, size): self.confs_parser = confs_parser self.size = size def __len__(self): return self.size def __getitem__(self, idx): return self.confs_parser(idx) isospec-1.9.1/IsoSpecPy/IsoSpecPy/isoFFI.py0000644000175000017500000001371613373520171020354 0ustar rusconirusconiimport cffi import os import platform import sys import glob class IsoFFI: def __init__(self): self.ffi = cffi.FFI() self.ffi.cdef(''' void * setupIso(int dimNumber, const int* isotopeNumbers, const int* atomCounts, const double* isotopeMasses, const double* isotopeProbabilities); void deleteIso(void* iso); void* setupIsoThresholdGenerator(void* iso, double threshold, bool _absolute, int _tabSize, int _hashSize); double massIsoThresholdGenerator(void* generator); double lprobIsoThresholdGenerator(void* generator); double probIsoThresholdGenerator(void* generator); void methodIsoThresholdGenerator(void* generator); bool advanceToNextConfigurationIsoThresholdGenerator(void* generator); void deleteIsoThresholdGenerator(void* generator); void get_conf_signatureIsoThresholdGenerator(void* generator, int* space); void* setupIsoLayeredGenerator(void* iso, double _target_coverage, double _percentage_to_expand, int _tabSize, int _hashSize, bool _do_trim); double massIsoLayeredGenerator(void* generator); double lprobIsoLayeredGenerator(void* generator); double probIsoLayeredGenerator(void* generator); void methodIsoLayeredGenerator(void* generator); bool advanceToNextConfigurationIsoLayeredGenerator(void* generator); void deleteIsoLayeredGenerator(void* generator); void get_conf_signatureIsoLayeredGenerator(void* generator, int* space); void* setupIsoOrderedGenerator(void* iso, int _tabSize, int _hashSize); double massIsoOrderedGenerator(void* generator); double lprobIsoOrderedGenerator(void* generator); double probIsoOrderedGenerator(void* generator); void methodIsoOrderedGenerator(void* generator); bool advanceToNextConfigurationIsoOrderedGenerator(void* generator); void deleteIsoOrderedGenerator(void* generator); void get_conf_signatureIsoOrderedGenerator(void* generator, int* space); void* setupThresholdTabulator(void* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs); void deleteThresholdTabulator(void* tabulator); const double* massesThresholdTabulator(void* tabulator); const double* lprobsThresholdTabulator(void* tabulator); const double* probsThresholdTabulator(void* tabulator); const int* confsThresholdTabulator(void* tabulator); int confs_noThresholdTabulator(void* tabulator); void* setupLayeredTabulator(void* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs); void deleteLayeredTabulator(void* tabulator); const double* massesLayeredTabulator(void* tabulator); const double* lprobsLayeredTabulator(void* tabulator); const double* probsLayeredTabulator(void* tabulator); const int* confsLayeredTabulator(void* tabulator); int confs_noLayeredTabulator(void* tabulator); void freeReleasedArray(void* array); #define NUMBER_OF_ISOTOPIC_ENTRIES 287 extern const int elem_table_atomicNo[NUMBER_OF_ISOTOPIC_ENTRIES]; extern const double elem_table_probability[NUMBER_OF_ISOTOPIC_ENTRIES]; extern const double elem_table_mass[NUMBER_OF_ISOTOPIC_ENTRIES]; extern const int elem_table_massNo[NUMBER_OF_ISOTOPIC_ENTRIES]; extern const int elem_table_extraNeutrons[NUMBER_OF_ISOTOPIC_ENTRIES]; extern const char* elem_table_element[NUMBER_OF_ISOTOPIC_ENTRIES]; extern const char* elem_table_symbol[NUMBER_OF_ISOTOPIC_ENTRIES]; extern const bool elem_table_Radioactive[NUMBER_OF_ISOTOPIC_ENTRIES]; '''); mod_dir = os.path.dirname(os.path.abspath(__file__)) if os.path.exists(os.path.join(mod_dir, '..', 'setup.py')): raise Exception('''Attempted to load IsoSpecPy module from its build directory. This usually won't work and is generally a Bad Idea. Please cd somewhere else, or, if you're really sure you want to do that, edit the source and disable this check.''') libnames = ['IsoSpecCppPy*', 'IsoSpec++*'] libprefix = ['', 'lib', 'Lib'] extension = ['.so', '.dylib', '.dll'] try: if platform.system() == 'Linux': extension = ['.so'] elif platform.system() == 'Windows': extension = ['.dll'] except: pass prebuilt = ['', 'prebuilt-'] def cprod(ll1, ll2): res = [] for l1 in ll1: for l2 in ll2: res.append(l1+l2) return res paths_to_check = cprod(prebuilt, cprod(libprefix, cprod(libnames, extension))) dpc = [] for dirpath in [mod_dir, mod_dir + '/..']: dpc.extend([os.path.join(dirpath, p) for p in paths_to_check]) paths_to_check = dpc paths_to_check = sum(map(glob.glob, paths_to_check), []) self.clib = None for libpath in set(paths_to_check): try: self.clib = self.ffi.dlopen(libpath) break except (IndexError, OSError) as e: pass if self.clib == None: raise Exception("Cannot find or load the C++ part of the library") isoFFI = IsoFFI() # This is done while including the module isospec-1.9.1/IsoSpecPy/setup.py0000644000175000017500000001351013373520171016507 0ustar rusconirusconi """A setuptools based setup module. See: https://packaging.python.org/en/latest/distributing.html https://github.com/pypa/sampleproject """ # Always prefer setuptools over distutils from setuptools import setup, find_packages, Extension from distutils import spawn # To use a consistent encoding from codecs import open import os import glob import shutil if not os.path.exists("IsoSpec++"): try: os.symlink("../IsoSpec++", "IsoSpec++") except: # OS doesn't support symlinks shutil.copytree("../IsoSpec++", "IsoSpec++", symlinks=True) here = os.path.abspath(os.path.dirname(__file__)) # Get the long description from the relevant file #with open(path.join(here, 'DESCRIPTION.rst'), encoding='utf-8') as f: # long_description = f.read() cmodule = Extension('IsoSpecCppPy', sources = ['IsoSpec++/unity-build.cpp'], extra_compile_args = '-mtune=native -march=native -O3 -std=c++11'.split() #+ ['-DDEBUG'] ) setup_args = { #setup( 'name': 'IsoSpecPy', # Versions should comply with PEP440. For a discussion on single-sourcing # the version across setup.py and the project code, see # https://packaging.python.org/en/latest/single_source_version.html 'version': '1.9.1', 'description': 'Python interface to IsoSpec++ isotopic envelope calculator library', 'long_description': 'Python interface to IsoSpec++ isotopic envelope calculator library', # The project's main homepage. 'url': 'http://matteolacki.github.io/IsoSpec/', # Author details 'author': 'Mateusz Lacki & Michal Startek', 'author_email': 'matteo.lacki@gmail.com', # Choose your license 'license': '2-clause BSD', # See https://pypi.python.org/pypi?%3Aaction=list_classifiers 'classifiers' : [ # How mature is this project? Common values are # 3 - Alpha # 4 - Beta # 5 - Production/Stable 'Development Status :: 5 - Production/Stable', # Indicate who your project is intended for 'Intended Audience :: Science/Research', 'Topic :: Scientific/Engineering :: Chemistry', # Pick your license as you wish (should match "license" above) 'License :: OSI Approved :: BSD License', # Specify the Python versions you support here. In particular, ensure # that you indicate whether you support Python 2, Python 3 or both. 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', ], # What does your project relate to? 'keywords' : 'isotopic envelope', # You can just specify the packages manually here if your project is # simple. Or you can use find_packages(). 'packages' : ['IsoSpecPy'],#find_packages(), # List run-time dependencies here. These will be installed by pip when # your project is installed. For an analysis of "install_requires" vs pip's # requirements files see: # https://packaging.python.org/en/latest/requirements.html 'install_requires' : ['cffi'], 'zip_safe' : False, # List additional groups of dependencies here (e.g. development # dependencies). You can install these using the following syntax, # for example: # $ pip install -e .[dev,test] 'extras_require' : { # 'dev': ['check-manifest'], # 'test': ['coverage'], }, # If there are data files included in your packages that need to be # installed, specify them here. If using Python 2.6 or less, then these # have to be included in MANIFEST.in as well. 'package_data' : { # 'sample': ['package_data.dat'], }, # Although 'package_data' is the preferred approach, in some case you may # need to place data files outside of your packages. See: # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa # In this case, 'data_file' will be installed into '/my_data' 'data_files' : [], #[('my_data', ['data/data_file'])], # To provide executable scripts, use entry points in preference to the # "scripts" keyword. Entry points provide cross-platform support and allow # pip to create the appropriate form of executable for the target platform. # entry_points={ # 'console_scripts': [ # 'sample=sample:main', # ], # }, 'ext_modules' : [cmodule], } import platform import sys if platform.system() == 'Windows': # Probably Anaconda distribution. # Of course Windows can't even compile stuff. Install prebuilt C++ lib. import copy win_setup_args = copy.deepcopy(setup_args) win_setup_args['ext_modules'] = [] win_setup_args['include_package_data'] = True setup(**win_setup_args) elif 'CYGWIN' in platform.system(): try: import cffi except ImportError: print("You appear to be using CYGWIN, and CFFI was not found. Please use the Cygwin installer to install the cffi-python package for the appropriate Python version.") print("Installing CFFI using pip will most likely NOT work. This is *NOT* a bug in IsoSpecPy.") sys.exit(1) if spawn.find_executable('clang++') == None: print("You appear to be using CYGWIN and clang++ executable was not found. Please install the clang++ package using Cygwin installer.") sys.exit(1) import distutils import distutils.sysconfig distutils.sysconfig.get_config_vars() # Precalculate the dict so we can... distutils.sysconfig._config_vars['CFLAGS'] = "" # Nuke CFLAGS: they contain gcc stuff not supported by clang setup(**setup_args) else: # Assuming UNIX with a working compiler. setup(**setup_args) isospec-1.9.1/IsoSpecPy/Makefile0000644000175000017500000000014613373520171016436 0ustar rusconirusconireinstall: rm -rf IsoSpecPy.egg-info build dist pip uninstall -y IsoSpecPy python setup.py install isospec-1.9.1/IsoSpecPy/IsoSpec++0000777000175000017500000000000013420367305020242 2../IsoSpec++ustar rusconirusconiisospec-1.9.1/IsoSpecPy/MANIFEST.in0000644000175000017500000000010613373520171016530 0ustar rusconirusconiinclude IsoSpecPy/*.dll include IsoSpec++/*.cpp include IsoSpec++/*.h isospec-1.9.1/README0000644000175000017500000000144113373520171013777 0ustar rusconirusconiIsoSpec, the isotopic fine structure calculator =============================================== The main purpose of this software package is to be used as a library, mostly in mass spectrometry software. We do not provide any standalone programs, except for those in Examples directory which are intended to showcase the usage of the library. Please see the code in Examples directory for example usage. The software is publically available under a 2-clause BSD licence. If you require other licensing terms, please contact the authors. See LICENCE file for more details. More details about the program may be found in the Analytical Chemistry publication: http://pubs.acs.org/doi/abs/10.1021/acs.analchem.6b01459 See especially the Supporting Information for details about the algorithm. isospec-1.9.1/INSTALL0000644000175000017500000000542713373520171014160 0ustar rusconirusconi------------------------------------------- Building and installing the C/C++ library Requirements: A C++11 compiler, clang++ (v3.3 or later) or g++ (v4.7 or later) Make (GNU make is OK) Note: clang++ is the default (and preferred) compiler as it produces faster code (in our tests, the difference in speed is about 20%). If you'd like to use g++ instead, please edit the first line of IsoSpec++/Makefile appropriately. Next, execute the following commands: cd IsoSpec++ make You may copy the resulting .so file to a convenient location. If you wish to develop software using this library, you will also have to place the header files (*.hpp/*.h) somewhere your C/C++ compiler can find them. On Windows, you should turn on the MANN_LIBRARY pre-processor directive when building the library. ------------------------------------------ Building and installing the Python package IMPORTANT: please note that the Python package is standalone, in the sense that it does not need the C/C++ library to be installed separately. IsoSpecPy is compatible with both CPython and PyPy, running on Unix, Cygwin or in MinGW environment. The preferred method of installation is by using the pip package manager. In order to do that, simply issue the following command, replacing "" with your Python executable (python/python3/pypy/...) -m pip install IsoSpecPy If, instead, you wish to install the package manually, follow these instructions: Requirements: Python (obviously) (v2 and v3 are supported) C++11 compiler, clang++ (v3.3 or later) or g++ (v4.7 or later) setuptools cffi (this, if not present, will be automatically downloaded and installed by the setup script, however you may prefer to use your distribution's package manager to install that) Execute the following commands: cd IsoSpecPy sudo python setup.py install Again, clang++ is the preferred compiler and will be used if found by the setup script. If you want to override the behaviour (if you have clang++ installed, but still want to use g++) you will have to replace the last command with: ISO_USE_DEFAULT_CXX=TRUE sudo python setup.py install ------------------------------------------ Building and installing the R package The preferred installation method is to use the CRAN package installer. To do that, simply issue the command: install.packages('IsoSpecR') in your R session. However it is possible to install the package manually, from source, by following these instructions: Requirements: R (>= 3.2.1) Rcpp package from CRAN C++11 compiler, clang++ (v3.3 or later) or g++ (v4.7 or later) Move to the folder containing the IsoSpecR folder. Then run in terminal: R CMD build IsoSpecR R CMD INSTALL IsoSpecR_*.tar.gz All necessary packages should download automatically. isospec-1.9.1/IsoSpecR/0000755000175000017500000000000013373520171014606 5ustar rusconirusconiisospec-1.9.1/IsoSpecR/R/0000755000175000017500000000000013373520171015007 5ustar rusconirusconiisospec-1.9.1/IsoSpecR/R/IsoSpecR.R0000644000175000017500000000760313373520171016627 0ustar rusconirusconi# # Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. # # This file is part of IsoSpec. # # IsoSpec is free software: you can redistribute it and/or modify # it under the terms of the Simplified ("2-clause") BSD licence. # # IsoSpec is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # You should have received a copy of the Simplified BSD Licence # along with IsoSpec. If not, see . # #' @useDynLib IsoSpecR #' @importFrom Rcpp sourceCpp NULL .onUnload <- function (libpath) { library.dynam.unload("IsoSpecR", libpath) } #' Calculate the isotopic fine structure peaks. #' #' \code{IsoSpecify} is a wrapper around \code{Rinterface} that calls the C++ implementation of the IsoSpec algorithm. Given a molecular formula, it will calculate the smallest set of infinitely resolved peaks (isotopologues) that jointly is \code{p} probable, where \code{p} is provided by the user. #' #' @param molecule A named integer vector, e.g. \code{c(C=2,H=6,O=1)}, containing the chemical formula of the substance of interest. #' @param stopCondition A numeric value between 0 and 1. #' @param showCounts Logical. If \code{TRUE}, then we output matrix contains additionally counts of isotopes for each isotopologue. #' @param trim Logical. If \code{FALSE}, then we output matrix contains additionally isotopologues that otherwise would get trimmed in order to find the smalles possible p-set. Therefore, switching to \code{FALSE} results in a slightly larger set then the optimal p-set. #' @param algo An integer: 0 - use standard IsoSpec algoritm, #' where \code{stopCondition} specifies the probability of the optimal p-set, #' 1 - use a version of algorithm that uses priority queue. Slower than 0, but does not require sorting. #' 2 - use a threshold version of the algorithm, where \code{stopCondition} specifies the height of the pruned peaks. #' 3 - for the threshold version of IsoSpec with \code{stopCondition} being #' the percentage of the highest peak below which isotopologues get pruned. #' @param isotopes A named list of isotopic information required for IsoSpec. The names must be valid element symbols, see \code{isotopicData} for examples. Each enlisted object should be a \code{data.frame} containing columns \code{element} (specifying the symbol of the element), \code{mass} (specifying the mass of the isotope), \code{abundance} (specyfying the assumed frequency of finding that isotope). #' @param step The percent of the the percentile of isotopologues in the current isolayer, specyfying the cutoff for the next isolayer. It has been optimised and better not change the default value. #' @param tabSize A technical parameter: the initial size of the \code{C++} dynamic table containing the results. Better not change the default value. #' @return A numeric matrix containing the masses, the logarithms of probability, and, optionally, counts of isotopologues. Attention: this matrix does not have to be sorted. Sorting it would also compromise the linear complexity of our algorithm. #' @examples #' res <- IsoSpecify( molecule = c(C=10,H=22,O=1), stopCondition = .9999 ) #' print(res) #' @export IsoSpecify <- function( molecule, stopCondition, isotopes= NULL, showCounts = FALSE, trim = TRUE, algo = 0, step = .25, tabSize = 1000 ){ if(is.null(isotopes)){ isotopes <- isotopicData$IsoSpec } Rinterface( molecule = molecule[ molecule > 0 ], isotopes = isotopes, stopCondition = stopCondition, algo = as.integer(algo), tabSize = tabSize, hashSize = 1000, step = step, showCounts = showCounts, trim = trim ) } isospec-1.9.1/IsoSpecR/R/data_description.R0000644000175000017500000000271413373520171020452 0ustar rusconirusconi# # Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. # # This file is part of IsoSpec. # # IsoSpec is free software: you can redistribute it and/or modify # it under the terms of the Simplified ("2-clause") BSD licence. # # IsoSpec is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # You should have received a copy of the Simplified BSD Licence # along with IsoSpec. If not, see . # #' Data on isotope masses, abundances and other. #' #' A list of data frames or table data frames (dplyr like), containing different information on isotopes. #' @format A list of 6 tbl_df's or data frames, each constaining: #' \describe{ #' \item{element}{The symbol of an element from Mendeleev's periodic table.} #' \item{isotope}{String composed of the nucleon number and the symbol of element.} #' \item{mass}{Isotope's Mass in Daltons.} #' \item{abundance}{The abundance of the isotopes. In case of enviPat data abundances do not sum to one. In case of all other, they do.} #' \item{ratioC}{As in enviPat reference manual: "Maximum number of atoms of an element for one C-atom in a molecule, based on 99.99 \% of case molecules".} #' } #' @source R Package enviPat and Commission on Isotopic Abundances and Atomic Weights, CIAAW, \url{http://www.ciaaw.org/index.htm}. "isotopicData" isospec-1.9.1/IsoSpecR/R/RcppExports.R0000644000175000017500000000061613373520171017426 0ustar rusconirusconi# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 Rinterface <- function(molecule, isotopes, stopCondition, algo = 0L, tabSize = 1000L, hashSize = 1000L, step = .3, showCounts = FALSE, trim = TRUE) { .Call(`_IsoSpecR_Rinterface`, molecule, isotopes, stopCondition, algo, tabSize, hashSize, step, showCounts, trim) } isospec-1.9.1/IsoSpecR/R/sysdata.rda0000644000175000017500000003071013373520171017150 0ustar rusconirusconiBZh91AY&SY4U/ (}_P( RzS!zh7mv|}tZTC筻[e tWEwU^(Ibݵd톻4]vhI4 AL=25Dɀ4 '$ Oښd1=?AiSi& hfѓ&L&bi҈&`11LCF&LLhFL5Si0#&D)22hi @ҟOѠ4hT44Q&M!1OJyF5O52z=&y?I HmǝIjy@mG&lMGB; kJzHoXPuS 5 [hΡďWYONHm399Q_rVEGCkSۣ O9)25Q 0p,@6|!U,!!4hj JfB$i, ͷٗ3 dž$=Srd%<4u(N3z)/LaX\ץCަ e.ZX!E`w.'vb"v,ZE9IY`qȤ0bɐ5s \WWWL`ԋ𤈭JԪ*RdMMN `ڑ9$B&a\DI3Ui(CU*P&CNB±1bѴFF H eUUe dK˅X+\+*]B]^N {UUUb P*`k0g*V5RCUSTi"fY,uujUR"4ZX*v$]NXR.^dLȹfbP!++\/Ed Y`/B.jzTHjݎo478AF @ L4WT" E|1Pto,PS1p"8 5>;cP" "/à;XLD uDEPEC"i({,uEt_j5,Ry k0Z*^*‡WyA-44]vx縰! Ɂv< KI|W!96lyA.\=o;{lz'^PsQEKn%SeQz)AQ*!]W=M H}_ypB-1߶a\;)+S`t2HV(2~_:a<"`R̆JfPvA!eMCv3o9vh_.M;y9/6۾I&\ ݋m*U /\:6V؈&+^&YAcyc'D*,̔t"K7Td2E8f yG-j&kUec Fe vH#4Z\H6fzR0Oàv #/7 coc;CJsb8&H| t|шㅘ|q@V<95Xuvg:x!Hw\::)4Ck&>^=e`J!FT;56PG鸊%2S@$m̚%0:SnyJoBm^t(v{oq/.ZVDA;|ұև\Udp~ ]밮oOm&)Ơ ktt8}I-30AS74:R<¶mͳF \`;PwE^V>&N8,N]̫+:aj2F4ck >zk+|N6|oAp txX'ӉNeh[%al.;cu>?I/LQ4:ȋ4_{Dh08e|Dh"}(.7JkQ')72(h{ 0"v8>ma>5Ekܱjʀ2C1}ovk:ҬsXS|,Iid\pb?#b.+<+qJZ%qv!/^'}ߡd?..K$I-2?`.&Rfp13yU&}刚p(R@30Yin:sgN_2)ބ8r[oxz G?S7-&pT9 8*p2Y1 ͅTQ^;\8wals pD{@m1*aJųLQ޹b7v9lຣEovq>_rDͻR+9L ;J^~p=[;Q )~5"n>VjIagYFKI34 @-%5HF4G"kχTSDz*XWV,8RF ]EԔ0U44b` D!$c0cm?Caqx''}GIek(D:їqdO=A Q8Eur <3*,.c鴹ֲ^_A|`ņ BHBHB,`>+4T̖e! F+1a3Y NiHF `<]k:66&bǢ d&Dkduf4Nbcbk&;EqcADQht F٢Bbņ4󨁎jtE^Gߙ!}.=/;=W>uUES*QTzJˋ˨TX$(+2H)&&*,Ws͘ڱ4b]y3M}ۏL7 ʻ-IJɑieE"U[AxWYS,xxh4ccOBQjaF1`$$'nH H{+K0L|P#x,eW L#" *kwt˒N#2aT7 A51`z4 Ǭ*r(`1_FLTc+8}|2|s)\K! P$(!ZmUYM.&)#fФ!(ь> 4i$x{7sN~^qF T|9N*d)Fa8ҜaJ4Ў _?ud{LYdTy?\70n.o %jw) Hcf ighaodE0"" "7L&c6xꪗ9vy5\qNէ,XG/~NbߧbGw;7[8X^=#-xC"FC(d X$"ޛ_&r'ge[R,,pVQ]:ߗx٧ '&aP4[67l=lҭ|}{mosOklw3n7kkҪܷ 5m2o]Yqi+݅7IڧaSUψ{ovP7q׵)[YԌm̽,EϖKP^łlTv]IQ<\~Ό!ƍüWb7ŚHbw {ﹳ+iz H18|ӌ=S4.R'ͅ\O)^_~-: '`nJ*`cS8cȬ+ѷ }SĪN@( A)L"MleyGrx xGkc<I>nvǒYnR.݊ tXɟDi@VI8[=3|"ݕ#Gm_z{.Pux\|,?=.oB"2PRJ;">VOOr|SQB8: $J Zډ'n ϲ@7'N^Mv't &élo1Rz]uLn0"ZխW*f,B&,C4:Ҝ܊0OFitn s $ȑ]uO:Sʺ>Ò qWԚ~8O1]w|qc!DRsb/PІ5V+,"qz$ؙ%k` Uuޏz@`B0!f|D3ҁU/I9{'Ȅ7SxL&'=Fx91!Kptߵ\׸\xi zȁ:"|?aFT372e, A-q `"Vj"#ķ/fHY~7SC1 싲YjR|Igi1I ٺ@~~~af$PN?ȿ91)Arm.DPg<֞xiu)-I2{![wŲll4K j%sl0H&fb'd'!wf/ Aso׮-; .o5810T&|m-slnlG\gcj^Pyca٢(<雎>6<$H6*t0_A7;20|ޤD9.Ah<ա[!g y`@rn_bs T9^KTD(E[((i~Hwher8dD#m{8=|"hR%1ENGɌ||EU 8.%nZ_`#eCCV4=4p|@>D?DtiQ\6KA`IԚEM66D#:5~>Q#"#}x.-e̒-4|*4P"1+To-W|[T ^>J  />Wo.VUExzE :PNW#:Pk4!-%9c P!DD? d=&8լG77륶wkXldatzZ͆A ]<skϋ6cxuܫI au4~;-6䆔R&a,l0Rx~n|%{3h;OIvOz"-@*b $rYM,clM+V~^է|E~eӕ^9FT @?)%0#}>>(s=p?ȚOwPë1dyy)y,ah8K/IzJ9’Jځ8qg"0T{w2nO)H6ĭR=c !mV6ÊKٍ]\A ,b1z+#kG Q3-gw8΄9j4zK%A6΂@;S]+d f#)^M_>+=#4ޙ'%Y*1ΟbYM;u \t|"E/ *wKPa5u*q[]ͤVdhxIEP`tdр'/JT}![Aв$m7:ma낮?sXtD뽪oO$J#yi*Н筊"~$}O;č.6珱-1ʎa5iM! eGHp3 0j< z>\([E<0pBڪ7ghgV+)tҼUA(7;H@pR0y.a=M-cϒ8j_C4__Ÿ4P>S[p.{|茉XDKo(S@. ũ=wk\?Lfmr(QDL/@}3({xWR\~~:VI IjBIg"LJ?Bʦ:-7HDQ%԰E^g [BIԦҸjNNk>ipv$ d5 I 7fUܞ4lo~("Neu2YKl%XչP Bb69)A (5cr6t[E#Kڌ edW5$3` `sq<l:Q%l5Y*R:~F At$=f[3îPcVf{>?OozN]DYA@X S̪%2o* 'fES<Ǐ`̰ clr!p3D#0٘d40T9y,K˲!҄\6zȀ$ mbG۸B) i:=N1X\1t1tEgZ_"awifi s9YX`' ɞ{}vk=r9./?w3Uoil1"mZޟ}\S“5 #۝lSYCO2AX,ZR&؋kW{rǜanU=j!+. VNP_Ėҋx(g&јZ6k+e|hTA2&Vp[ysX;RN8'I 9꯰n#h2dkc>7^EТbFgϧ K8+I+ sv=dX Iue/AGȾb䠼`rGRl, PUDsq4G`$@W(FB-ۂ Q1v T|w 9W#B;xV>t^v'!kJnh aUYEv_eCIe5h\AmڟΎǂ@8oiL*M1ӛs @\FRټq.e- 肇x^^~WLB!0Ҝx7DA㜘lW=M?~wƌ8L4᧱2 V&-f`oneP$\6hkR*6bjtJ..p0|/g|C\wnl.q!ɕ$?&!8#|٫%NA0)"ߌ4$^ZEQ6xJ>;1PIh.GhR6:0hniuP Sf?PRk$j|.$c4݆3h`~4gïs( Yك39Nu: ]qYng^s۰ivJ}dLVI6&73+-HKE0_x#^r&i{{‰z]B@/Tisospec-1.9.1/IsoSpecR/src/0000755000175000017500000000000013373520171015375 5ustar rusconirusconiisospec-1.9.1/IsoSpecR/src/RcppExports.cpp0000644000175000017500000000272313373520171020376 0ustar rusconirusconi// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include using namespace Rcpp; // Rinterface NumericMatrix Rinterface(const IntegerVector& molecule, const DataFrame& isotopes, double stopCondition, int algo, int tabSize, int hashSize, double step, bool showCounts, bool trim); RcppExport SEXP _IsoSpecR_Rinterface(SEXP moleculeSEXP, SEXP isotopesSEXP, SEXP stopConditionSEXP, SEXP algoSEXP, SEXP tabSizeSEXP, SEXP hashSizeSEXP, SEXP stepSEXP, SEXP showCountsSEXP, SEXP trimSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const IntegerVector& >::type molecule(moleculeSEXP); Rcpp::traits::input_parameter< const DataFrame& >::type isotopes(isotopesSEXP); Rcpp::traits::input_parameter< double >::type stopCondition(stopConditionSEXP); Rcpp::traits::input_parameter< int >::type algo(algoSEXP); Rcpp::traits::input_parameter< int >::type tabSize(tabSizeSEXP); Rcpp::traits::input_parameter< int >::type hashSize(hashSizeSEXP); Rcpp::traits::input_parameter< double >::type step(stepSEXP); Rcpp::traits::input_parameter< bool >::type showCounts(showCountsSEXP); Rcpp::traits::input_parameter< bool >::type trim(trimSEXP); rcpp_result_gen = Rcpp::wrap(Rinterface(molecule, isotopes, stopCondition, algo, tabSize, hashSize, step, showCounts, trim)); return rcpp_result_gen; END_RCPP } isospec-1.9.1/IsoSpecR/src/operators.h0000644000175000017500000000700213373520171017563 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #include #include "conf.h" #include "isoMath.h" #include "misc.h" namespace IsoSpec { class KeyHasher { private: int dim; public: KeyHasher(int dim); inline std::size_t operator()(const int* conf) const { // Following Boost... std::size_t seed = 0; for(int i = 0; i < dim; ++i ) seed ^= conf[i] + 0x9e3779b9 + (seed << 6) + (seed >> 2); return seed; }; }; class ConfEqual { private: int size; public: ConfEqual(int dim); inline bool operator()(const int* conf1, const int* conf2) const { // The memcmp() function returns zero if the two strings are identical, oth- // erwise returns the difference between the first two differing bytes // (treated as unsigned char values, so that `\200' is greater than `\0', // for example). Zero-length strings are always identical. This behavior // is not required by C and portable code should only depend on the sign of // the returned value. // sacred man of memcmp. return memcmp(conf1, conf2, size) == 0; } }; class ConfOrder { //configurations comparator public: inline bool operator()(void* conf1,void* conf2) const { return *reinterpret_cast(conf1) < *reinterpret_cast(conf2); }; }; class ConfOrderMarginal { //configurations comparator const double* logProbs; int dim; public: ConfOrderMarginal(const double* logProbs, int dim); inline bool operator()(const Conf conf1, const Conf conf2) {// Return true if conf1 is less probable than conf2. return unnormalized_logProb(conf1,logProbs,dim) < unnormalized_logProb(conf2,logProbs,dim); }; }; class ConfOrderMarginalDescending { //configurations comparator const double* logProbs; int dim; public: ConfOrderMarginalDescending(const double* logProbs, int dim); inline bool operator()(const Conf conf1, const Conf conf2) {// Return true if conf1 is less probable than conf2. return unnormalized_logProb(conf1,logProbs,dim) > unnormalized_logProb(conf2,logProbs,dim); }; }; template class ReverseOrder { public: inline ReverseOrder() {}; inline bool operator()(const T a,const T b) const { return a > b; }; }; template class TableOrder { const T* tbl; public: inline TableOrder(const T* _tbl) : tbl(_tbl) {}; inline bool operator()(unsigned int i, unsigned int j) { return tbl[i] < tbl[j]; }; }; } // namespace IsoSpec #include "marginalTrek++.h" class PrecalculatedMarginal; // In case marginalTrek++.h us including us, and can't be included again... namespace IsoSpec { class OrderMarginalsBySizeDecresing { PrecalculatedMarginal const* const* const T; public: OrderMarginalsBySizeDecresing(PrecalculatedMarginal const* const * const _T); bool operator()(int m1, int m2); }; } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/isoSpec++.cpp0000644000175000017500000005540513373520171017645 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "platform.h" #include "conf.h" #include "dirtyAllocator.h" #include "operators.h" #include "summator.h" #include "marginalTrek++.h" #include "isoSpec++.h" #include "misc.h" #include "element_tables.h" using namespace std; namespace IsoSpec { Iso::Iso( int _dimNumber, const int* _isotopeNumbers, const int* _atomCounts, const double* const * _isotopeMasses, const double* const * _isotopeProbabilities ) : disowned(false), dimNumber(_dimNumber), isotopeNumbers(array_copy(_isotopeNumbers, _dimNumber)), atomCounts(array_copy(_atomCounts, _dimNumber)), confSize(_dimNumber * sizeof(int)), allDim(0), marginals(nullptr), modeLProb(0.0) { try{ setupMarginals(_isotopeMasses, _isotopeProbabilities); } catch(...) { delete[] isotopeNumbers; delete[] atomCounts; throw; } } Iso::Iso(Iso&& other) : disowned(other.disowned), dimNumber(other.dimNumber), isotopeNumbers(other.isotopeNumbers), atomCounts(other.atomCounts), confSize(other.confSize), allDim(other.allDim), marginals(other.marginals), modeLProb(other.modeLProb) { other.disowned = true; } Iso::Iso(const Iso& other, bool fullcopy) : disowned(fullcopy ? throw std::logic_error("Not implemented") : true), dimNumber(other.dimNumber), isotopeNumbers(fullcopy ? array_copy(other.isotopeNumbers, dimNumber) : other.isotopeNumbers), atomCounts(fullcopy ? array_copy(other.atomCounts, dimNumber) : other.atomCounts), confSize(other.confSize), allDim(other.allDim), marginals(fullcopy ? throw std::logic_error("Not implemented") : other.marginals), modeLProb(other.modeLProb) {} inline void Iso::setupMarginals(const double* const * _isotopeMasses, const double* const * _isotopeProbabilities) { if (marginals == nullptr) { int ii = 0; try { marginals = new Marginal*[dimNumber]; while(ii < dimNumber) { allDim += isotopeNumbers[ii]; marginals[ii] = new Marginal( _isotopeMasses[ii], _isotopeProbabilities[ii], isotopeNumbers[ii], atomCounts[ii] ); modeLProb += marginals[ii]->getModeLProb(); ii++; } } catch(...) { ii--; while(ii >= 0) { delete marginals[ii]; ii--; } delete[] marginals; marginals = nullptr; throw; } } } Iso::~Iso() { if(!disowned) { if (marginals != nullptr) dealloc_table(marginals, dimNumber); delete[] isotopeNumbers; delete[] atomCounts; } } double Iso::getLightestPeakMass() const { double mass = 0.0; for (int ii=0; iigetLightestConfMass(); return mass; } double Iso::getHeaviestPeakMass() const { double mass = 0.0; for (int ii=0; iigetHeaviestConfMass(); return mass; } Iso::Iso(const char* formula) : disowned(false), allDim(0), marginals(nullptr), modeLProb(0.0) { std::vector isotope_masses; std::vector isotope_probabilities; dimNumber = parse_formula(formula, isotope_masses, isotope_probabilities, &isotopeNumbers, &atomCounts, &confSize); setupMarginals(isotope_masses.data(), isotope_probabilities.data()); } unsigned int parse_formula(const char* formula, std::vector& isotope_masses, std::vector& isotope_probabilities, int** isotopeNumbers, int** atomCounts, unsigned int* confSize) { // This function is NOT guaranteed to be secure against malicious input. It should be used only for debugging. size_t slen = strlen(formula); // Yes, it would be more elegant to use std::string here, but it's the only promiment place where it would be used in IsoSpec, and avoiding it here // means we can run the whole thing through Clang's memory sanitizer without the need for instrumented libc++/libstdc++. That's worth messing with char pointers a // little bit. std::vector > elements; std::vector numbers; if(slen == 0) throw invalid_argument("Invalid formula: can't be empty"); if(!isdigit(formula[slen-1])) throw invalid_argument("Invalid formula: every element must be followed by a number - write H2O1 and not H2O for water"); for(size_t ii=0; ii element_indexes; for (unsigned int i=0; i _isotope_numbers; for(vector::iterator it = element_indexes.begin(); it != element_indexes.end(); ++it) { int num = 0; int at_idx = *it; int atomicNo = elem_table_atomicNo[at_idx]; while(at_idx < ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES && elem_table_atomicNo[at_idx] == atomicNo) { at_idx++; num++; } _isotope_numbers.push_back(num); } for(vector::iterator it = element_indexes.begin(); it != element_indexes.end(); ++it) { isotope_masses.push_back(&elem_table_mass[*it]); isotope_probabilities.push_back(&elem_table_probability[*it]); }; const unsigned int dimNumber = elements.size(); *isotopeNumbers = array_copy(_isotope_numbers.data(), dimNumber); *atomCounts = array_copy(numbers.data(), dimNumber); *confSize = dimNumber * sizeof(int); return dimNumber; } /* * ---------------------------------------------------------------------------------------------------------- */ IsoGenerator::IsoGenerator(Iso&& iso, bool alloc_partials) : Iso(std::move(iso)), partialLProbs(alloc_partials ? new double[dimNumber+1] : nullptr), partialMasses(alloc_partials ? new double[dimNumber+1] : nullptr), partialProbs(alloc_partials ? new double[dimNumber+1] : nullptr) { if(alloc_partials) { partialLProbs[dimNumber] = 0.0; partialMasses[dimNumber] = 0.0; partialProbs[dimNumber] = 1.0; } } IsoGenerator::~IsoGenerator() { if(partialLProbs != nullptr) delete[] partialLProbs; if(partialMasses != nullptr) delete[] partialMasses; if(partialProbs != nullptr) delete[] partialProbs; } /* * ---------------------------------------------------------------------------------------------------------- */ IsoThresholdGenerator::IsoThresholdGenerator(Iso&& iso, double _threshold, bool _absolute, int tabSize, int hashSize, bool reorder_marginals) : IsoGenerator(std::move(iso)), Lcutoff(_threshold <= 0.0 ? std::numeric_limits::lowest() : (_absolute ? log(_threshold) : log(_threshold) + modeLProb)) { counter = new int[dimNumber]; maxConfsLPSum = new double[dimNumber-1]; marginalResultsUnsorted = new PrecalculatedMarginal*[dimNumber]; empty = false; for(int ii=0; iigetModeLProb(), true, tabSize, hashSize); if(!marginalResultsUnsorted[ii]->inRange(0)) empty = true; } if(reorder_marginals) { OrderMarginalsBySizeDecresing comparator(marginalResultsUnsorted); int* tmpMarginalOrder = new int[dimNumber]; for(int ii=0; iiget_lProbs_ptr(); if(dimNumber > 1) maxConfsLPSum[0] = marginalResults[0]->getModeLProb(); for(int ii=1; iigetModeLProb(); lProbs_ptr = lProbs_ptr_start; partialLProbs_second = partialLProbs; partialLProbs_second++; if(!empty) { recalc(dimNumber-1); counter[0]--; lProbs_ptr--; } else { terminate_search(); lcfmsv = std::numeric_limits::infinity(); } } void IsoThresholdGenerator::terminate_search() { for(int ii=0; iiget_no_confs()-1; partialLProbs[ii] = -std::numeric_limits::infinity(); } partialLProbs[dimNumber] = -std::numeric_limits::infinity(); lProbs_ptr = lProbs_ptr_start + marginalResults[0]->get_no_confs()-1; } size_t IsoThresholdGenerator::count_confs() { // Smarter algorithm forthcoming in 2.0 size_t ret = 0; while(advanceToNextConfiguration()) ret++; reset(); return ret; } void IsoThresholdGenerator::reset() { if(empty) { terminate_search(); return; } partialLProbs[dimNumber] = 0.0; memset(counter, 0, sizeof(int)*dimNumber); recalc(dimNumber-1); counter[0]--; lProbs_ptr = lProbs_ptr_start - 1; } /* * ------------------------------------------------------------------------------------------------------------------------ */ IsoOrderedGenerator::IsoOrderedGenerator(Iso&& iso, int _tabSize, int _hashSize) : IsoGenerator(std::move(iso), false), allocator(dimNumber, _tabSize) { partialLProbs = ¤tLProb; partialMasses = ¤tMass; partialProbs = ¤tProb; marginalResults = new MarginalTrek*[dimNumber]; for(int i = 0; i*[dimNumber]; masses = new const vector*[dimNumber]; marginalConfs = new const vector*[dimNumber]; for(int i = 0; iconf_masses(); logProbs[i] = &marginalResults[i]->conf_lprobs(); marginalConfs[i] = &marginalResults[i]->confs(); } topConf = allocator.newConf(); memset( reinterpret_cast(topConf) + sizeof(double), 0, sizeof(int)*dimNumber ); *(reinterpret_cast(topConf)) = combinedSum( getConf(topConf), logProbs, dimNumber ); pq.push(topConf); } IsoOrderedGenerator::~IsoOrderedGenerator() { dealloc_table(marginalResults, dimNumber); delete[] logProbs; delete[] masses; delete[] marginalConfs; partialLProbs = nullptr; partialMasses = nullptr; partialProbs = nullptr; } bool IsoOrderedGenerator::advanceToNextConfiguration() { if(pq.size() < 1) return false; topConf = pq.top(); pq.pop(); int* topConfIsoCounts = getConf(topConf); currentLProb = *(reinterpret_cast(topConf)); currentMass = combinedSum( topConfIsoCounts, masses, dimNumber ); currentProb = exp(currentLProb); ccount = -1; for(int j = 0; j < dimNumber; ++j) { if(marginalResults[j]->probeConfigurationIdx(topConfIsoCounts[j] + 1)) { if(ccount == -1) { topConfIsoCounts[j]++; *(reinterpret_cast(topConf)) = combinedSum(topConfIsoCounts, logProbs, dimNumber); pq.push(topConf); topConfIsoCounts[j]--; ccount = j; } else { void* acceptedCandidate = allocator.newConf(); int* acceptedCandidateIsoCounts = getConf(acceptedCandidate); memcpy(acceptedCandidateIsoCounts, topConfIsoCounts, confSize); acceptedCandidateIsoCounts[j]++; *(reinterpret_cast(acceptedCandidate)) = combinedSum(acceptedCandidateIsoCounts, logProbs, dimNumber); pq.push(acceptedCandidate); } } if(topConfIsoCounts[j] > 0) break; } if(ccount >=0) topConfIsoCounts[ccount]++; return true; } /* * --------------------------------------------------------------------------------------------------- */ #if !ISOSPEC_BUILDING_R void printConfigurations( const std::tuple& results, int dimNumber, int* isotopeNumbers ){ int m = 0; for(int i=0; i(results); i++){ std::cout << "Mass = " << std::get<0>(results)[i] << "\tand log-prob = " << std::get<1>(results)[i] << "\tand prob = " << exp(std::get<1>(results)[i]) << "\tand configuration =\t"; for(int j=0; j(results)[m] << " "; m++; } std::cout << '\t'; } std::cout << std::endl; } } #endif /* !ISOSPEC_BUILDING_R */ IsoLayeredGenerator::IsoLayeredGenerator( Iso&& iso, double _targetCoverage, double _percentageToExpand, int _tabSize, int _hashSize, bool trim ) : IsoGenerator(std::move(iso)), allocator(dimNumber, _tabSize), candidate(new int[dimNumber]), targetCoverage(_targetCoverage >= 1.0 ? 10000.0 : _targetCoverage), // If the user wants the entire spectrum, // give it to him - and make sure we don't terminate // early because of rounding errors percentageToExpand(_percentageToExpand), do_trim(trim), layers(0), generator_position(-1) { marginalResults = new MarginalTrek*[dimNumber]; for(int i = 0; i*[dimNumber]; masses = new const vector*[dimNumber]; marginalConfs = new const vector*[dimNumber]; for(int i = 0; iconf_masses(); logProbs[i] = &marginalResults[i]->conf_lprobs(); marginalConfs[i] = &marginalResults[i]->confs(); } void* topConf = allocator.newConf(); memset(reinterpret_cast(topConf) + sizeof(double), 0, sizeof(int)*dimNumber); *(reinterpret_cast(topConf)) = combinedSum(getConf(topConf), logProbs, dimNumber); current = new std::vector(); next = new std::vector(); current->push_back(topConf); lprobThr = (*reinterpret_cast(topConf)); if(targetCoverage > 0.0) while(advanceToNextLayer()) {}; } IsoLayeredGenerator::~IsoLayeredGenerator() { if(current != nullptr) delete current; if(next != nullptr) delete next; delete[] logProbs; delete[] masses; delete[] marginalConfs; delete[] candidate; dealloc_table(marginalResults, dimNumber); } bool IsoLayeredGenerator::advanceToNextLayer() { layers += 1; double maxFringeLprob = -std::numeric_limits::infinity(); if(current == nullptr) return false; int accepted_in_this_layer = 0; Summator prob_in_this_layer(totalProb); void* topConf; while(current->size() > 0) { topConf = current->back(); current->pop_back(); double top_lprob = getLProb(topConf); if(top_lprob >= lprobThr) { newaccepted.push_back(topConf); accepted_in_this_layer++; prob_in_this_layer.add(exp(top_lprob)); } else { next->push_back(topConf); continue; } int* topConfIsoCounts = getConf(topConf); for(int j = 0; j < dimNumber; ++j) { // candidate cannot refer to a position that is // out of range of the stored marginal distribution. if(marginalResults[j]->probeConfigurationIdx(topConfIsoCounts[j] + 1)) { memcpy(candidate, topConfIsoCounts, confSize); candidate[j]++; void* acceptedCandidate = allocator.newConf(); int* acceptedCandidateIsoCounts = getConf(acceptedCandidate); memcpy( acceptedCandidateIsoCounts, candidate, confSize); double newConfProb = combinedSum( candidate, logProbs, dimNumber ); *(reinterpret_cast(acceptedCandidate)) = newConfProb; if(newConfProb >= lprobThr) current->push_back(acceptedCandidate); else { next->push_back(acceptedCandidate); if(newConfProb > maxFringeLprob) maxFringeLprob = top_lprob; } } if(topConfIsoCounts[j] > 0) break; } } if(next == nullptr || next->size() < 1) return false; else { if(prob_in_this_layer.get() < targetCoverage) { std::vector* nnew = current; nnew->clear(); current = next; next = nnew; int howmany = floor(current->size()*percentageToExpand); lprobThr = getLProb(quickselect(current->data(), howmany, 0, current->size())); totalProb = prob_in_this_layer; } else { delete next; next = nullptr; delete current; current = nullptr; int start = 0; int end = accepted_in_this_layer - 1; void* swapspace; if(do_trim) { void** lastLayer = &(newaccepted.data()[newaccepted.size()-accepted_in_this_layer]); Summator qsprob(totalProb); while(totalProb.get() < targetCoverage) { if(start == end) break; // Partition part int len = end - start; #if ISOSPEC_BUILDING_R int pivot = len/2 + start; // We're very definitely NOT switching to R to use a RNG, and if R sees us use C RNG it complains... #else int pivot = rand() % len + start; #endif void* pval = lastLayer[pivot]; double pprob = getLProb(pval); mswap(lastLayer[pivot], lastLayer[end-1]); int loweridx = start; for(int i=start; i pprob) { mswap(lastLayer[i], lastLayer[loweridx]); loweridx++; } } mswap(lastLayer[end-1], lastLayer[loweridx]); // Selection part Summator leftProb(qsprob); for(int i=start; i<=loweridx; i++) { leftProb.add(exp(getLProb(lastLayer[i]))); } if(leftProb.get() < targetCoverage) { start = loweridx+1; qsprob = leftProb; } else end = loweridx; } int accend = newaccepted.size()-accepted_in_this_layer+start+1; totalProb = qsprob; newaccepted.resize(accend); return true; } else // No trimming { totalProb = prob_in_this_layer; return true; } } } return true; } bool IsoLayeredGenerator::advanceToNextConfiguration() { generator_position++; if(generator_position < newaccepted.size()) { partialLProbs[0] = getLProb(newaccepted[generator_position]); partialMasses[0] = combinedSum(getConf(newaccepted[generator_position]), masses, dimNumber); partialProbs[0] = exp(partialLProbs[0]); return true; } else return false; } } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/allocator.h0000644000175000017500000000311613373520171017527 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #include #include #include #include "conf.h" namespace IsoSpec { template inline void copyConf( const T* source, T* destination, int dim ){ memcpy(destination, source, dim*sizeof(T)); } template class Allocator{ private: T* currentTab; int currentId; const int dim, tabSize; std::vector prevTabs; public: Allocator(const int dim, const int tabSize = 10000); ~Allocator(); void shiftTables(); inline T* newConf() { currentId++; if (currentId >= tabSize) shiftTables(); return &(currentTab[ currentId * dim ]); } inline T* makeCopy(const T* conf) { T* currentPlace = newConf(); copyConf( conf, currentPlace, dim ); return currentPlace; } inline T* makeExternalCopy(const T* conf) { T* res = new T[dim]; copyConf( conf, res, dim ); return res; } }; } isospec-1.9.1/IsoSpecR/src/element_tables.h0000644000175000017500000000267713373520171020545 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once namespace IsoSpec { #ifdef __cplusplus extern "C" { #endif #define ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES 288 extern const int elem_table_atomicNo[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const double elem_table_probability[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const double elem_table_mass[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const int elem_table_massNo[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const int elem_table_extraNeutrons[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const char* elem_table_element[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const char* elem_table_symbol[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const bool elem_table_Radioactive[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const double elem_table_log_probability[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; #ifdef __cplusplus } #endif } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/marginalTrek++.cpp0000644000175000017500000003040013373520171020644 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "platform.h" #include "marginalTrek++.h" #include "conf.h" #include "allocator.h" #include "operators.h" #include "summator.h" #include "element_tables.h" #include "misc.h" namespace IsoSpec { //! Find one of the most probable subisotopologues. /*! The algorithm uses the hill-climbing algorithm. It starts from a subisotopologue close to the mean of the underlying multinomial distribution. There might be more than one modes, in case of which this function will return only one of them, close to the mean. \param atomCnt */ Conf initialConfigure(const int atomCnt, const int isotopeNo, const double* probs, const double* lprobs) { /*! Here we perform hill climbing to the mode of the marginal distribution (the subisotopologue distribution). We start from the point close to the mean of the underlying multinomial distribution. */ Conf res = new int[isotopeNo]; // This approximates the mode (heuristics: the mean is close to the mode). for(int i = 0; i < isotopeNo; ++i ) res[i] = int( atomCnt * probs[i] ) + 1; // The number of assigned atoms above. int s = 0; for(int i = 0; i < isotopeNo; ++i) s += res[i]; int diff = atomCnt - s; // Too little: enlarging fist index. if( diff > 0 ){ res[0] += diff; } // Too much: trying to redistribute the difference: hopefully the first element is the largest. if( diff < 0 ){ diff = abs(diff); int i = 0, coordDiff = 0; while( diff > 0){ coordDiff = res[i] - diff; if( coordDiff >= 0 ){ res[i] -= diff; diff = 0; } else { res[i] = 0; i++; diff = abs(coordDiff); } } } // What we computed so far will be very close to the mode: hillclimb the rest of the way bool modified = true; double LP = unnormalized_logProb(res, lprobs, isotopeNo); double NLP; while(modified) { modified = false; for(int ii = 0; ii 0) { res[ii]--; res[jj]++; NLP = unnormalized_logProb(res, lprobs, isotopeNo); if(NLP>LP || (NLP==LP && ii>jj)) { modified = true; LP = NLP; } else { res[ii]++; res[jj]--; } } } return res; } #if !ISOSPEC_BUILDING_R void printMarginal( const std::tuple& results, int dim) { for(int i=0; i(results); i++){ std::cout << "Mass = " << std::get<0>(results)[i] << " log-prob =\t" << std::get<1>(results)[i] << " prob =\t" << exp(std::get<1>(results)[i]) << "\tand configuration =\t"; for(int j=0; j(results)[i*dim + j] << " "; std::cout << std::endl; } } #endif double* getMLogProbs(const double* probs, int isoNo) { /*! Here we order the processor to round the numbers up rather than down. Rounding down could result in the algorithm falling in an infinite loop because of the numerical instability of summing. */ int curr_method = fegetround(); fesetround(FE_UPWARD); double* ret = new double[isoNo]; // here we change the table of probabilities and log it. for(int i = 0; i < isoNo; i++) { ret[i] = log(probs[i]); for(int j=0; j(_masses, _isotopeNo)), atom_lProbs(getMLogProbs(_probs, isotopeNo)), loggamma_nominator(get_loggamma_nominator(_atomCnt)), mode_conf(initialConfigure(atomCnt, isotopeNo, _probs, atom_lProbs)), mode_lprob(loggamma_nominator+unnormalized_logProb(mode_conf, atom_lProbs, isotopeNo)), mode_mass(mass(mode_conf, atom_masses, isotopeNo)), mode_prob(exp(mode_lprob)), smallest_lprob(atomCnt * *std::min_element(atom_lProbs, atom_lProbs+isotopeNo)) { try { if(ISOSPEC_G_FACT_TABLE_SIZE-1 <= atomCnt) throw std::length_error("Subisotopologue too large, size limit (that is, the maximum number of atoms of a single element in a molecule) is: " + std::to_string(ISOSPEC_G_FACT_TABLE_SIZE-1)); for(size_t ii = 0; ii < isotopeNo; ii++) if(_probs[ii] <= 0.0 || _probs[ii] > 1.0) throw std::invalid_argument("All isotope probabilities p must fulfill: 0.0 < p <= 1.0"); } catch(...) { delete[] atom_masses; delete[] atom_lProbs; delete[] mode_conf; throw; } } // the move-constructor: used in the specialization of the marginal. Marginal::Marginal(Marginal&& other) : disowned(other.disowned), isotopeNo(other.isotopeNo), atomCnt(other.atomCnt), atom_masses(other.atom_masses), atom_lProbs(other.atom_lProbs), loggamma_nominator(other.loggamma_nominator), mode_conf(other.mode_conf), mode_lprob(other.mode_lprob), mode_mass(other.mode_mass), mode_prob(other.mode_prob), smallest_lprob(other.smallest_lprob) { other.disowned = true; } Marginal::~Marginal() { if(!disowned) { delete[] atom_masses; delete[] atom_lProbs; delete[] mode_conf; } } double Marginal::getLightestConfMass() const { double ret_mass = std::numeric_limits::infinity(); for(unsigned int ii=0; ii < isotopeNo; ii++) if( ret_mass > atom_masses[ii] ) ret_mass = atom_masses[ii]; return ret_mass*atomCnt; } double Marginal::getHeaviestConfMass() const { double ret_mass = 0.0; for(unsigned int ii=0; ii < isotopeNo; ii++) if( ret_mass < atom_masses[ii] ) ret_mass = atom_masses[ii]; return ret_mass*atomCnt; } // this is roughly an equivalent of IsoSpec-Threshold-Generator MarginalTrek::MarginalTrek( Marginal&& m, int tabSize, int hashSize ) : Marginal(std::move(m)), current_count(0), keyHasher(isotopeNo), equalizer(isotopeNo), orderMarginal(atom_lProbs, isotopeNo), visited(hashSize,keyHasher,equalizer), pq(orderMarginal), totalProb(), candidate(new int[isotopeNo]), allocator(isotopeNo, tabSize) { int* initialConf = allocator.makeCopy(mode_conf); pq.push(initialConf); visited[initialConf] = 0; totalProb = Summator(); current_count = 0; add_next_conf(); } bool MarginalTrek::add_next_conf() { /*! Add next configuration. If visited all, return false. */ if(pq.size() < 1) return false; Conf topConf = pq.top(); pq.pop(); ++current_count; visited[topConf] = current_count; _confs.push_back(topConf); _conf_masses.push_back(mass(topConf, atom_masses, isotopeNo)); double logprob = logProb(topConf); _conf_lprobs.push_back(logprob); totalProb.add( exp( logprob ) ); for( unsigned int i = 0; i < isotopeNo; ++i ) { for( unsigned int j = 0; j < isotopeNo; ++j ) { // Growing index different than decreasing one AND // Remain on simplex condition. if( i != j && topConf[j] > 0 ){ copyConf(topConf, candidate, isotopeNo); ++candidate[i]; --candidate[j]; // candidate should not have been already visited. if( visited.count( candidate ) == 0 ) { Conf acceptedCandidate = allocator.makeCopy(candidate); pq.push(acceptedCandidate); visited[acceptedCandidate] = 0; } } } } return true; } int MarginalTrek::processUntilCutoff(double cutoff) { Summator s; int last_idx = -1; for(unsigned int i=0; i<_conf_lprobs.size(); i++) { s.add(_conf_lprobs[i]); if(s.get() >= cutoff) { last_idx = i; break; } } if(last_idx > -1) return last_idx; while(totalProb.get() < cutoff && add_next_conf()) {} return _conf_lprobs.size(); } MarginalTrek::~MarginalTrek() { delete[] candidate; } PrecalculatedMarginal::PrecalculatedMarginal(Marginal&& m, double lCutOff, bool sort, int tabSize, int hashSize ) : Marginal(std::move(m)), allocator(isotopeNo, tabSize) { const ConfEqual equalizer(isotopeNo); const KeyHasher keyHasher(isotopeNo); const ConfOrderMarginalDescending orderMarginal(atom_lProbs, isotopeNo); std::unordered_set visited(hashSize,keyHasher,equalizer); Conf currentConf = allocator.makeCopy(mode_conf); if(logProb(currentConf) >= lCutOff) { // create a copy and store a ptr to the *same* copy in both structures // (save some space and time) auto tmp = allocator.makeCopy(currentConf); configurations.push_back(tmp); visited.insert(tmp); } unsigned int idx = 0; while(idx < configurations.size()) { memcpy(currentConf, configurations[idx], sizeof(int)*isotopeNo); idx++; for(unsigned int ii = 0; ii < isotopeNo; ii++ ) for(unsigned int jj = 0; jj < isotopeNo; jj++ ) if( ii != jj && currentConf[jj] > 0) { currentConf[ii]++; currentConf[jj]--; if (visited.count(currentConf) == 0 && logProb(currentConf) >= lCutOff) { // create a copy and store a ptr to the *same* copy in // both structures (save some space and time) auto tmp = allocator.makeCopy(currentConf); visited.insert(tmp); configurations.push_back(tmp); // std::cout << " V: "; for (auto it : visited) std::cout << it << " "; std::cout << std::endl; } currentConf[ii]--; currentConf[jj]++; } } // orderMarginal defines the order of configurations (compares their logprobs) // akin to key in Python sort. if(sort) std::sort(configurations.begin(), configurations.end(), orderMarginal); confs = &configurations[0]; no_confs = configurations.size(); lProbs = new double[no_confs+1]; probs = new double[no_confs]; masses = new double[no_confs]; for(unsigned int ii=0; ii < no_confs; ii++) { lProbs[ii] = logProb(confs[ii]); probs[ii] = exp(lProbs[ii]); masses[ii] = mass(confs[ii], atom_masses, isotopeNo); } lProbs[no_confs] = -std::numeric_limits::infinity(); } PrecalculatedMarginal::~PrecalculatedMarginal() { if(lProbs != nullptr) delete[] lProbs; if(masses != nullptr) delete[] masses; if(probs != nullptr) delete[] probs; } } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/tabulator.h0000644000175000017500000000604313373520171017546 0ustar rusconirusconi#pragma once #include #include "isoSpec++.h" #define ISOSPEC_INIT_TABLE_SIZE 1024 namespace IsoSpec { template class Tabulator { private: double* _masses; double* _lprobs; double* _probs; int* _confs; size_t _confs_no; public: Tabulator(T* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs); ~Tabulator(); inline double* masses() { return _masses; }; inline double* lprobs() { return _lprobs; }; inline double* probs() { return _probs; }; inline int* confs() { return _confs; }; inline size_t confs_no() { return _confs_no; }; }; inline void reallocate(double **array, int new_size){ if( *array != nullptr ){ *array = (double *) realloc(*array, new_size); } } template Tabulator::Tabulator(T* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs ) { size_t current_size = ISOSPEC_INIT_TABLE_SIZE; int confs_tbl_idx = 0; _confs_no = 0; const int allDimSizeOfInt = sizeof(int)*generator->getAllDim(); _masses = get_masses ? (double *) malloc(ISOSPEC_INIT_TABLE_SIZE * sizeof(double)) : nullptr; _lprobs = get_lprobs ? (double *) malloc(ISOSPEC_INIT_TABLE_SIZE * sizeof(double)) : nullptr; _probs = get_probs ? (double *) malloc(ISOSPEC_INIT_TABLE_SIZE * sizeof(double)) : nullptr; _confs = get_confs ? (int *) malloc(ISOSPEC_INIT_TABLE_SIZE * allDimSizeOfInt): nullptr; while(generator->advanceToNextConfiguration()){ if( _confs_no == current_size ) { current_size *= 2; // FIXME: Handle overflow gracefully here. It definitely could happen for people still stuck on 32 bits... reallocate(&_masses, current_size * sizeof(double)); reallocate(&_lprobs, current_size * sizeof(double)); reallocate(&_probs, current_size * sizeof(double)); if( _confs != nullptr ){ _confs = (int *) realloc(_confs, current_size * allDimSizeOfInt); } } if(_masses != nullptr) _masses[_confs_no] = generator->mass(); if(_lprobs != nullptr) _lprobs[_confs_no] = generator->lprob(); if(_probs != nullptr) _probs[_confs_no] = generator->prob(); if(_confs != nullptr){ generator->get_conf_signature(_confs + confs_tbl_idx); confs_tbl_idx += generator->getAllDim(); } _confs_no++; } _masses = (double *) realloc(_masses, _confs_no * sizeof(double)); _lprobs = (double *) realloc(_lprobs, _confs_no * sizeof(double)); _probs = (double *) realloc(_probs, _confs_no * sizeof(double)); _confs = (int *) realloc(_confs, confs_tbl_idx * sizeof(int)); } template Tabulator::~Tabulator() { if( _masses != nullptr ) free(_masses); if( _lprobs != nullptr ) free(_lprobs); if( _probs != nullptr ) free(_probs); if( _confs != nullptr ) free(_confs); } } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/Rinterface.cpp0000644000175000017500000001414113373520171020164 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include #include "cwrapper.h" #include "misc.h" #include "isoSpec++.h" #include #include using namespace Rcpp; using namespace IsoSpec; IsoGenerator* mkIsoG(Iso& iso, int algo, double stopCondition, int tabSize, int hashSize, int step, int trim) { switch(algo) { case ISOSPEC_ALGO_LAYERED_ESTIMATE: // Not used anymore, just fall through to the next case case ISOSPEC_ALGO_LAYERED: return new IsoLayeredGenerator(std::move(iso), stopCondition, step, tabSize, hashSize, trim); case ISOSPEC_ALGO_ORDERED: return new IsoLayeredGenerator(std::move(iso), stopCondition, step, tabSize, hashSize, true); // Using the ordered algo in R is *completely* pointless today // The only point of ordered algo is when one is using the generator // interface, which we are not expising in R // We'll just do layered, trim and sort it afterwards - it's equivalent // and much faster case ISOSPEC_ALGO_THRESHOLD_ABSOLUTE: return new IsoThresholdGenerator(std::move(iso), stopCondition, true, tabSize, hashSize, true); case ISOSPEC_ALGO_THRESHOLD_RELATIVE: return new IsoThresholdGenerator(std::move(iso), stopCondition, true, tabSize, hashSize, true); } throw std::logic_error("Invalid algorithm selected"); } // [[Rcpp::export]] NumericMatrix Rinterface( const IntegerVector& molecule, const DataFrame& isotopes, double stopCondition, int algo = 0, int tabSize = 1000, int hashSize = 1000, double step = .3, bool showCounts = false, bool trim = true ){ unsigned int dimNumber = molecule.size(); std::vector stdIsotopeNumbers; std::vector stdIsotopeMasses; std::vector stdIsotopeProbabilities; const CharacterVector& element = isotopes["element"]; const CharacterVector& isotope = isotopes["isotope"]; const NumericVector& mass = isotopes["mass"]; const NumericVector& abundance = isotopes["abundance"]; const CharacterVector& molecule_names = molecule.names(); CharacterVector stdIsotopeTags = CharacterVector::create("mass", "logProb"); for (unsigned int i=0; i IM; std::vector IP; size_t tot = 0; for(size_t ii = 0; ii >( molecule).data(), IM.data(), IP.data()); IsoGenerator* IG = mkIsoG(iso, algo, stopCondition, tabSize, hashSize, step, trim); int columnsNo = stdIsotopeTags.size(); // standard int isotopesNo = iso.getAllDim(); // Code doing useless copying around of memory follows, as NumericMatrix apparently can't resize dynamically like std::vector does, so we can't directly // write into it, as we don't know how many configurations we're going to get upfront and we can't preallocate size. std::vector logProbs; std::vector masses; std::vector confs; std::vector ordering; size_t data_offset = 0; while(IG->advanceToNextConfiguration()) { logProbs.push_back(IG->lprob()); masses.push_back(IG->mass()); if(showCounts) { confs.resize(confs.size()+isotopesNo); IG->get_conf_signature(&(confs.data()[data_offset])); data_offset += isotopesNo; } } delete IG; IG = nullptr; const bool needs_sorting = (ISOSPEC_ALGO_ORDERED == algo); if(needs_sorting) { // We need to sort the confs for backward compatibility ordering.reserve(logProbs.size()); for(size_t i = 0; i < logProbs.size(); i++) ordering.push_back(i); std::sort(ordering.begin(), ordering.end(), [&logProbs](size_t idx1, size_t idx2) -> bool { return logProbs[idx1] > logProbs[idx2]; }); } NumericMatrix res(logProbs.size(), columnsNo); size_t idx, confs_idx; for(size_t i = 0; i < logProbs.size(); i++) { idx = needs_sorting ? ordering[i] : i; res(i,0) = masses[idx]; res(i,1) = logProbs[idx]; if(showCounts) { confs_idx = idx*isotopesNo; for(size_t j = 0; j < isotopesNo; j++) res(i,2+j) = confs[confs_idx+j]; } } colnames(res) = stdIsotopeTags; //This is RCPP sugar. It sucks. return(res); } isospec-1.9.1/IsoSpecR/src/dirtyAllocator.h0000644000175000017500000000313313373520171020542 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #include #include #include namespace IsoSpec { class DirtyAllocator{ private: void* currentTab; void* currentConf; void* endOfTablePtr; const int tabSize; int cellSize; std::vector prevTabs; public: DirtyAllocator(const int dim, const int tabSize = 10000); ~DirtyAllocator(); void shiftTables(); inline void* newConf() { if (currentConf >= endOfTablePtr) { shiftTables(); } void* ret = currentConf; currentConf = reinterpret_cast(currentConf) + cellSize; return ret; } inline void* makeCopy(const void* conf) { void* currentPlace = newConf(); memcpy(currentPlace, conf, cellSize); return currentPlace; } inline void* makeExternalCopy(const void* conf) { void* res = malloc(cellSize); memcpy(res, conf, cellSize); return res; } }; } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/IsoSpecR_init.c0000644000175000017500000000074213373520171020256 0ustar rusconirusconi#include #include #include // for NULL #include /* .Call calls */ extern SEXP _IsoSpecR_Rinterface(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); static const R_CallMethodDef CallEntries[] = { {"_IsoSpecR_Rinterface", (DL_FUNC) &_IsoSpecR_Rinterface, 9}, {NULL, NULL, 0} }; void R_init_IsoSpecR(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } isospec-1.9.1/IsoSpecR/src/allocator.cpp0000644000175000017500000000227513373520171020067 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include #include "allocator.h" namespace IsoSpec { template Allocator::Allocator(const int dim, const int tabSize): currentId(-1), dim(dim), tabSize(tabSize) { currentTab = new T[dim * tabSize]; } template Allocator::~Allocator() { for(unsigned int i = 0; i < prevTabs.size(); ++i) { delete [] prevTabs[i]; } delete [] currentTab; } template void Allocator::shiftTables() { prevTabs.push_back(currentTab); currentTab = new T[dim * tabSize]; currentId = 0; } template class Allocator; } isospec-1.9.1/IsoSpecR/src/isoMath.h0000644000175000017500000000261313373520171017154 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #include #include #if !defined(ISOSPEC_G_FACT_TABLE_SIZE) // 10M should be enough for anyone, right? // Actually, yes. If anyone tries to input a molecule that has more than 10M atoms, // he deserves to get an exception thrown in his face. #define ISOSPEC_G_FACT_TABLE_SIZE 1024*1024*10 #endif namespace IsoSpec { extern double* g_lfact_table; static inline double minuslogFactorial(int n) { if (n < 2) return 0.0; if (g_lfact_table[n] == 0.0) g_lfact_table[n] = -lgamma(n+1); return g_lfact_table[n]; } double NormalCDFInverse(double p); double NormalCDFInverse(double p, double mean, double stdev); double NormalCDF(double x, double mean, double stdev); double NormalPDF(double x, double mean = 0.0, double stdev = 1.0); } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/marginalTrek++.h0000644000175000017500000002574713373520171020333 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #include #include #include #include #include "conf.h" #include "allocator.h" #include "operators.h" #include "summator.h" namespace IsoSpec { Conf initialConfigure(int atomCnt, int isotopeNo, const double* probs); void printMarginal(const std::tuple& results, int dim); //! The marginal distribution class (a subisotopologue). /*! This class mostly provides some basic common API for subclasses, but itself is not abstract. This class represents the probability distribution generated by one element only -- a subisotopologue. For instance, it might be the distribution of C200, that might be part of, say, C200H402. It corresponds to the multinomial distribution, where each configuration can also be attributed a precise mass. The constructor method perform initial hill-climbing to find the most probable sub-isotopologue (the mode). */ class Marginal { private: bool disowned; protected: const unsigned int isotopeNo; /*!< The number of isotopes of the given element. */ const unsigned int atomCnt; /*!< The number of atoms of the given element. */ const double* const atom_masses; /*!< Table of atomic masses of all the isotopeNo isotopes. */ const double* const atom_lProbs; /*!< Table of log-probabilities of all the isotopeNo isotopes. */ const double loggamma_nominator; /*!< The constant nominator that appears in the expressions for the multinomial probabilities. */ const Conf mode_conf; /*!< A subisotopologue with most probability. If not unique, one of the representatives of that class of subisotopologues. */ const double mode_lprob; /*!< The log-probability of the mode subisotopologue.*/ const double mode_mass; /*!< The mass of the mode subisotopologue.*/ const double mode_prob; /*!< The probability of the mode subisotopologue.*/ const double smallest_lprob; /*!< The smallest-achievable log-probability in the distribution of subisotopologues. */ public: //! Class constructor. /*! \param _masses A table of masses of the stable isotopes of the investigated element, e.g. for C10 it is 2: C12 and C13. \param _probs A table of natural frequencies of the stable isotopes of the investigated element, see IUPAC at https://iupac.org/isotopesmatter/ \param _isotopeNo Number of isotopes of a given element. \param _atomCnt The number of atoms of the given element, e.g. 10 for C10. \return An instance of the Marginal class. */ Marginal( const double* _masses, // masses size = logProbs size = isotopeNo const double* _probs, int _isotopeNo, int _atomCnt ); // Get rid of the C++ generated copy and assignment constructors. Marginal(Marginal& other) = delete; Marginal& operator= (const Marginal& other) = delete; //! Move constructor. Marginal(Marginal&& other); //! Destructor. virtual ~Marginal(); //! Get the number of isotopes of the investigated element. /*! \return The integer number of isotopes of the investigated element. */ inline int get_isotopeNo() const { return isotopeNo; }; //! Get the mass of the lightest subisotopologue. /*! This is trivially obtained by considering all atomNo atoms to be the lightest isotope possible. \return The mass of the lightiest subisotopologue. */ double getLightestConfMass() const; //! Get the mass of the heaviest subisotopologue. /*! This is trivially obtained by considering all atomNo atoms to be the heaviest isotope possible. \return The mass of the heaviest subisotopologue. */ double getHeaviestConfMass() const; //! Get the log-probability of the mode subisotopologue. /*! \return The log-probability of a/the most probable subisotopologue. */ inline double getModeLProb() const { return mode_lprob; }; //! The the mass of the mode subisotopologue. /*! \return The mass of one of the most probable subisotopologues. */ inline double getModeMass() const { return mode_mass; }; //! The the probability of the mode subisotopologue. /*! \return The probability of a/the most probable subisotopologue. */ inline double getModeProb() const { return mode_prob; }; //! The the log-probability of the lightest subisotopologue. /*! \return The logarithm of the smallest non-zero probability of a subisotopologue. */ inline double getSmallestLProb() const { return smallest_lprob; }; //! Calculate the log-probability of a given subisotopologue. /*! \param conf A subisotopologue (a table of integers describing subsequent isotope-counts). \return The log-probability of the input subisotopologue. */ inline double logProb(Conf conf) const { return loggamma_nominator + unnormalized_logProb(conf, atom_lProbs, isotopeNo); }; }; //! The marginal distribution class (a subisotopologue). class MarginalTrek : public Marginal { private: int current_count; const KeyHasher keyHasher; const ConfEqual equalizer; const ConfOrderMarginal orderMarginal; std::unordered_map visited; std::priority_queue,ConfOrderMarginal> pq; Summator totalProb; Conf candidate; Allocator allocator; std::vector _conf_lprobs; std::vector _conf_masses; std::vector _confs; //! Proceed to the next configuration and memoize it (as it will be surely needed). bool add_next_conf(); public: //! Move constructor: specializes the Marginal class. /*! \param tabSize The size of the table used to store configurations in the allocator. \param hashSize The size of the hash table used to store visited subisotopologues. */ MarginalTrek( Marginal&& m, int tabSize = 1000, int hashSize = 1000 ); //! Check if the table of computed subisotopologues does not have to be extended. /*! This function checks if the idx-th most probable subisotopologue was memoized and if not, computes it and memoizes it. \param idx The number of the idx-th most probable subisotopologue. \return Returns false if it the provided idx exceeds the total number of subisotopologues. */ inline bool probeConfigurationIdx(int idx) { while(current_count <= idx) if(!add_next_conf()) return false; return true; } //! Calculate subisotopologues with probability above or equal to the cut-off. /*! \param cutoff The probability cut-off \return The number of the last subisotopologue above the cut-off. */ int processUntilCutoff(double cutoff); inline const std::vector& conf_lprobs() const { return _conf_lprobs; }; inline const std::vector& conf_masses() const { return _conf_masses; }; inline const std::vector& confs() const { return _confs; }; virtual ~MarginalTrek(); }; //! Precalculated Marginal class /*! This class serves to calculate a set of isotopologues that is defined by the minimal probability threshold. This works faster than if you did not know the threshold. If you have no idea about the threshold, you would need to call us, to change encode the layered version of the marginal. */ class PrecalculatedMarginal : public Marginal { protected: std::vector configurations; Conf* confs; unsigned int no_confs; double* masses; double* lProbs; double* probs; Allocator allocator; public: //! The move constructor (disowns the Marginal). /*! This constructor memoizes all subisotopologues with log-probability above the provided threshold lCutOff \param Marginal An instance of the Marginal class this class is about to disown. \param lCutOff The lower limit on the log-probability of the precomputed subisotopologues. \param sort Should the subisotopologues be stored with descending probability ? \return An instance of the PrecalculatedMarginal class. */ PrecalculatedMarginal( Marginal&& m, double lCutOff, bool sort = true, int tabSize = 1000, int hashSize = 1000 ); //! Destructor. virtual ~PrecalculatedMarginal(); //! Is there a subisotopologue with a given number? /*! \return Returns true if idx does not exceed the number of pre-computed configurations. */ inline bool inRange(unsigned int idx) const { return idx < no_confs; }; //! Get the log-probability of the idx-th subisotopologue. /*! \param idx The number of the considered subisotopologue. \return The log-probability of the idx-th subisotopologue. */ inline const double& get_lProb(int idx) const { return lProbs[idx]; }; //! Get the probability of the idx-th subisotopologue. /*! \param idx The number of the considered subisotopologue. \return The probability of the idx-th subisotopologue. */ inline const double& get_prob(int idx) const { return probs[idx]; }; //! Get the mass of the idx-th subisotopologue. /*! \param idx The number of the considered subisotopologue. \return The mass of the idx-th subisotopologue. */ inline const double& get_mass(int idx) const { return masses[idx]; }; //! Get the table of the log-probabilities of subisotopologues. /*! \return Pointer to the first element in the table storing log-probabilities of subisotopologues. */ inline const double* get_lProbs_ptr() const { return lProbs; }; //! Get the table of the masses of subisotopologues. /*! \return Pointer to the first element in the table storing masses of subisotopologues. */ inline const double* get_masses_ptr() const { return masses; }; //! Get the counts of isotopes that define the subisotopologue. /*! \param idx The number of the considered subisotopologue. \return The counts of isotopes that define the subisotopologue. */ inline const Conf& get_conf(int idx) const { return confs[idx]; }; //! Get the number of precomputed subisotopologues. /*! \return The number of precomputed subisotopologues. */ inline unsigned int get_no_confs() const { return no_confs; }; }; } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/cwrapper.cpp0000644000175000017500000001607713373520171017737 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include #include #include #include #include #include "cwrapper.h" #include "misc.h" #include "marginalTrek++.h" #include "isoSpec++.h" #include "tabulator.h" using namespace IsoSpec; extern "C" { void * setupIso(int dimNumber, const int* isotopeNumbers, const int* atomCounts, const double* isotopeMasses, const double* isotopeProbabilities) { const double** IM = new const double*[dimNumber]; const double** IP = new const double*[dimNumber]; int idx = 0; for(int i=0; i(iso); } void deleteIso(void* iso) { delete reinterpret_cast(iso); } #define ISOSPEC_C_FN_CODE(generatorType, dataType, method)\ dataType method##generatorType(void* generator){ return reinterpret_cast(generator)->method(); } #define ISOSPEC_C_FN_CODE_GET_CONF_SIGNATURE(generatorType)\ void get_conf_signature##generatorType(void* generator, int* space)\ { reinterpret_cast(generator)->get_conf_signature(space); } #define ISOSPEC_C_FN_DELETE(generatorType) void delete##generatorType(void* generator){ delete reinterpret_cast(generator); } #define ISOSPEC_C_FN_CODES(generatorType)\ ISOSPEC_C_FN_CODE(generatorType, double, mass) \ ISOSPEC_C_FN_CODE(generatorType, double, lprob) \ ISOSPEC_C_FN_CODE(generatorType, double, prob) \ ISOSPEC_C_FN_CODE_GET_CONF_SIGNATURE(generatorType) \ ISOSPEC_C_FN_CODE(generatorType, bool, advanceToNextConfiguration) \ ISOSPEC_C_FN_DELETE(generatorType) //______________________________________________________THRESHOLD GENERATOR void* setupIsoThresholdGenerator(void* iso, double threshold, bool _absolute, int _tabSize, int _hashSize) { IsoThresholdGenerator* iso_tmp = new IsoThresholdGenerator( std::move(*reinterpret_cast(iso)), threshold, _absolute, _tabSize, _hashSize); return reinterpret_cast(iso_tmp); } ISOSPEC_C_FN_CODES(IsoThresholdGenerator) //______________________________________________________LAYERED GENERATOR void* setupIsoLayeredGenerator(void* iso, double _target_coverage, double _percentage_to_expand, int _tabSize, int _hashSize, bool _do_trim) { IsoLayeredGenerator* iso_tmp = new IsoLayeredGenerator( std::move(*reinterpret_cast(iso)), _target_coverage, _percentage_to_expand, _tabSize, _hashSize, _do_trim); return reinterpret_cast(iso_tmp); } ISOSPEC_C_FN_CODES(IsoLayeredGenerator) //______________________________________________________ORDERED GENERATOR void* setupIsoOrderedGenerator(void* iso, int _tabSize, int _hashSize) { IsoOrderedGenerator* iso_tmp = new IsoOrderedGenerator( std::move(*reinterpret_cast(iso)), _tabSize, _hashSize); return reinterpret_cast(iso_tmp); } ISOSPEC_C_FN_CODES(IsoOrderedGenerator) //______________________________________________________ Threshold Tabulator void* setupThresholdTabulator(void* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs) { Tabulator* tabulator = new Tabulator(reinterpret_cast(generator), get_masses, get_probs, get_lprobs, get_confs); return reinterpret_cast(tabulator); } void deleteThresholdTabulator(void* t) { delete reinterpret_cast*>(t); } const double* massesThresholdTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->masses(); } const double* lprobsThresholdTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->lprobs(); } const double* probsThresholdTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->probs(); } const int* confsThresholdTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->confs(); } int confs_noThresholdTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->confs_no(); } //______________________________________________________ Layered Tabulator void* setupLayeredTabulator(void* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs) { Tabulator* tabulator = new Tabulator(reinterpret_cast(generator), get_masses, get_probs, get_lprobs, get_confs); return reinterpret_cast(tabulator); } void deleteLayeredTabulator(void* t) { delete reinterpret_cast*>(t); } const double* massesLayeredTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->masses(); } const double* lprobsLayeredTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->lprobs(); } const double* probsLayeredTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->probs(); } const int* confsLayeredTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->confs(); } int confs_noLayeredTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->confs_no(); } } //extern "C" ends here isospec-1.9.1/IsoSpecR/src/summator.h0000644000175000017500000000435713373520171017426 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #include #include namespace IsoSpec { class SSummator { // Shewchuk algorithm std::vector partials; int maxpart; public: inline SSummator() { maxpart = 0; } inline SSummator(SSummator& other) { this->partials = other.partials; this->maxpart = other.maxpart; } inline void add(double x) { unsigned int i=0; for(int pidx=0; pidx. */ #pragma once #include #include #include #include #include "platform.h" #include "dirtyAllocator.h" #include "summator.h" #include "operators.h" #include "marginalTrek++.h" #if ISOSPEC_BUILDING_R #include using namespace Rcpp; #endif /* ISOSPEC_BUILDING_R */ namespace IsoSpec { // This function is NOT guaranteed to be secure against malicious input. It should be used only for debugging. unsigned int parse_formula(const char* formula, std::vector& isotope_masses, std::vector& isotope_probabilities, int** isotopeNumbers, int** atomCounts, unsigned int* confSize); //! The Iso class for the calculation of the isotopic distribution. /*! It contains full description of the molecule for which one would like to calculate the isotopic distribution. */ class ISOSPEC_EXPORT_SYMBOL Iso { private: //! Set up the marginal isotopic envelopes, corresponding to subisotopologues. /*! \param _isotopeMasses A table of masses of isotopes of the elements in the chemical formula, e.g. {12.0, 13.003355, 1.007825, 2.014102} for C100H202. \param _isotopeProbabilities A table of isotope frequencies of the elements in the chemical formula, e.g. {.989212, .010788, .999885, .000115} for C100H202. */ void setupMarginals(const double* const * _isotopeMasses, const double* const * _isotopeProbabilities); public: bool disowned; /*!< A variable showing if the Iso class was specialized by its child-class. If so, then the description of the molecules has been transfered there and Iso is a carcass class, dead as a dodo, an ex-class if you will. */ protected: int dimNumber; /*!< The number of elements in the chemical formula of the molecule. */ int* isotopeNumbers; /*!< A table with numbers of isotopes for each element. */ int* atomCounts; /*!< A table with numbers of isotopes for each element. */ unsigned int confSize; /*!< The number of bytes needed to represent the counts of isotopes present in the extended chemical formula. */ int allDim; /*!< The total number of isotopes of elements present in a chemical formula, e.g. for H20 it is 2+3=5. */ Marginal** marginals; /*!< The table of pointers to the distributions of individual subisotopologues. */ double modeLProb; /*!< The log-probability of the mode of the isotopic distribution. */ public: //! General constructror. /*! \param _dimNumber The number of elements in the formula, e.g. for C100H202 it would be 2, as there are only carbon and hydrogen atoms. \param _isotopeNumbers A table with numbers of isotopes for each element, e.g. for C100H202 it would be {2, 2}, because both C and H have two stable isotopes. \param _atomCounts Number of atoms of each element in the formula, e.g. for C100H202 corresponds to {100, 202}. \param _isotopeMasses A table of masses of isotopes of the elements in the chemical formula, e.g. {12.0, 13.003355, 1.007825, 2.014102} for C100H202. \param _isotopeProbabilities A table of isotope frequencies of the elements in the chemical formula, e.g. {.989212, .010788, .999885, .000115} for C100H202. */ Iso( int _dimNumber, const int* _isotopeNumbers, const int* _atomCounts, const double* const * _isotopeMasses, const double* const * _isotopeProbabilities ); //! Constructor from the formula object. Iso(const char* formula); //! The move constructor. Iso(Iso&& other); //! The copy constructor. /*! \param other The other instance of the Iso class. \param fullcopy If false, copy only the number of atoms in the formula, the size of the configuration, the total number of isotopes, and the probability of the mode isotopologue. */ Iso(const Iso& other, bool fullcopy); //! Destructor. virtual ~Iso(); //! Get the mass of the lightest peak in the isotopic distribution. double getLightestPeakMass() const; //! Get the mass of the heaviest peak in the isotopic distribution. double getHeaviestPeakMass() const; //! Get the log-probability of the mode-configuration (if there are many modes, they share this value). inline double getModeLProb() const { return modeLProb; }; //! Get the number of elements in the chemical formula of the molecule. inline int getDimNumber() const { return dimNumber; }; //! Get the total number of isotopes of elements present in a chemical formula. inline int getAllDim() const { return allDim; }; }; //! The generator of isotopologues. /*! This class provides the common interface for all isotopic generators. */ class ISOSPEC_EXPORT_SYMBOL IsoGenerator : public Iso { protected: double* partialLProbs; /*!< The prefix sum of the log-probabilities of the current isotopologue. */ double* partialMasses; /*!< The prefix sum of the masses of the current isotopologue. */ double* partialProbs;/*!< The prefix product of the probabilities of the current isotopologue. */ public: //! Advance to the next, not yet visited, most probable isotopologue. /*! \return Return false if it is not possible to advance. */ virtual bool advanceToNextConfiguration() = 0; //! Get the log-probability of the current isotopologue. /*! \return The log-probability of the current isotopologue. */ virtual double lprob() const { return partialLProbs[0]; }; //! Get the mass of the current isotopologue. /*! \return The mass of the current isotopologue. */ virtual double mass() const { return partialMasses[0]; }; //! Get the probability of the current isotopologue. /*! \return The probability of the current isotopologue. */ virtual double prob() const { return partialProbs[0]; }; //TODO: what is this??? virtual void get_conf_signature(int* space) const = 0; //! Move constructor. IsoGenerator(Iso&& iso, bool alloc_partials = true); //! Destructor. virtual ~IsoGenerator(); }; //! The generator of isotopologues sorted by their probability of occurrence. /*! The subsequent isotopologues are generated with diminishing probability, starting from the mode. This algorithm take O(N*log(N)) to compute the N isotopologues because of using the Priority Queue data structure. Obtaining the N isotopologues can be achieved in O(N) if they are not required to be spit out in the descending order. */ class ISOSPEC_EXPORT_SYMBOL IsoOrderedGenerator: public IsoGenerator { private: MarginalTrek** marginalResults; /*!< Table of pointers to marginal distributions of subisotopologues. */ std::priority_queue,ConfOrder> pq; /*!< The priority queue used to generate isotopologues ordered by descending probability. */ void* topConf; /*!< Most probable configuration. */ DirtyAllocator allocator; /*!< Structure used for alocating memory for isotopologues. */ const std::vector** logProbs; /*!< Obtained log-probabilities. */ const std::vector** masses; /*!< Obtained masses. */ const std::vector** marginalConfs; /*!< Obtained counts of isotopes. */ double currentLProb; /*!< The log-probability of the current isotopologue. */ double currentMass; /*!< The mass of the current isotopologue. */ double currentProb; /*!< The probability of the current isotopologue. */ int ccount; public: bool advanceToNextConfiguration() override final; //! Save the counts of isotopes in the space. /*! \param space An array where counts of isotopes shall be written. Must be as big as the overall number of isotopes. */ inline void get_conf_signature(int* space) const override final { int* c = getConf(topConf); if (ccount >= 0) c[ccount]--; for(int ii=0; iiconfs()[c[ii]], isotopeNumbers[ii]*sizeof(int)); space += isotopeNumbers[ii]; } if (ccount >= 0) c[ccount]++; }; //! The move-contstructor. IsoOrderedGenerator(Iso&& iso, int _tabSize = 1000, int _hashSize = 1000); //! Destructor. virtual ~IsoOrderedGenerator(); }; //! The generator of isotopologues above a given threshold value. /*! Attention: the calculated configurations are only partially ordeded and the user should not assume they will be ordered. This algorithm computes N isotopologues in O(N). It is a considerable advantage w.r.t. the IsoOrderedGenerator. */ class ISOSPEC_EXPORT_SYMBOL IsoThresholdGenerator: public IsoGenerator { private: int* counter; /*!< An array storing the position of an isotopologue in terms of the subisotopologues ordered by decreasing probability. */ double* maxConfsLPSum; const double Lcutoff; /*!< The logarithm of the lower bound on the calculated probabilities. */ PrecalculatedMarginal** marginalResults; PrecalculatedMarginal** marginalResultsUnsorted; int* marginalOrder; const double* lProbs_ptr; const double* lProbs_ptr_start; double* partialLProbs_second; double partialLProbs_second_val, lcfmsv; bool empty; public: inline void get_conf_signature(int* space) const override final { counter[0] = lProbs_ptr - lProbs_ptr_start; if(marginalOrder != nullptr) for(int ii=0; iiget_conf(counter[jj]), isotopeNumbers[ii]*sizeof(int)); space += isotopeNumbers[ii]; } else for(int ii=0; iiget_conf(counter[ii]), isotopeNumbers[ii]*sizeof(int)); space += isotopeNumbers[ii]; } }; //! The move-constructor. /*! \param iso An instance of the Iso class. \param _threshold The threshold value. \param _absolute If true, the _threshold is interpreted as the absolute minimal peak height for the isotopologues. If false, the _threshold is the fraction of the heighest peak's probability. \param tabSize The size of the extension of the table with configurations. \param hashSize The size of the hash-table used to store subisotopologues and check if they have been already calculated. */ IsoThresholdGenerator(Iso&& iso, double _threshold, bool _absolute=true, int _tabSize=1000, int _hashSize=1000, bool reorder_marginals = true); inline ~IsoThresholdGenerator() { delete[] counter; delete[] maxConfsLPSum; if (marginalResultsUnsorted != marginalResults) delete[] marginalResultsUnsorted; dealloc_table(marginalResults, dimNumber); if(marginalOrder != nullptr) delete[] marginalOrder; }; // Perform highly aggressive inling as this function is often called as while(advanceToNextConfiguration()) {} // which leads to an extremely tight loop and some compilers miss this (potentially due to the length of the function). ISOSPEC_FORCE_INLINE bool advanceToNextConfiguration() override final { lProbs_ptr++; if(ISOSPEC_LIKELY(*lProbs_ptr >= lcfmsv)) { return true; } // If we reached this point, a carry is needed int idx = 0; lProbs_ptr = lProbs_ptr_start; int * cntr_ptr = counter; while(idxget_lProb(counter[idx]); if(partialLProbs[idx] + maxConfsLPSum[idx-1] >= Lcutoff) { partialMasses[idx] = partialMasses[idx+1] + marginalResults[idx]->get_mass(counter[idx]); partialProbs[idx] = partialProbs[idx+1] * marginalResults[idx]->get_prob(counter[idx]); recalc(idx-1); return true; } } terminate_search(); return false; } ISOSPEC_FORCE_INLINE double lprob() const override final { return partialLProbs_second_val + (*(lProbs_ptr)); }; ISOSPEC_FORCE_INLINE double mass() const override final { return partialMasses[1] + marginalResults[0]->get_mass(lProbs_ptr - lProbs_ptr_start); }; ISOSPEC_FORCE_INLINE double prob() const override final { return partialProbs[1] * marginalResults[0]->get_prob(lProbs_ptr - lProbs_ptr_start); }; //! Block the subsequent search of isotopologues. void terminate_search(); /*! Reset the generator to the beginning of the sequence. Allows it to be reused, eg. to go through the conf space once, calculate the amount of space needed to store configurations, then to allocate that memory, and go through it again, this time saving configurations (and *is* in fact faster than allocating a std::vector and depending on it to grow as needed. This is cheaper than throwing away the generator and making a new one too: marginal distributions don't need to be recalculated. */ void reset(); /*! Count the number of configurations in the distribution. This can be used to pre-allocate enough memory to store it (e.g. * std::vector's reserve() method - this is faster than depending on the vector's dynamic resizing, even though it means that * the configuration space is walked through twice. This method has to be called before the first call to advanceToNextConfiguration * and has undefined results (incl. segfaults) otherwise. */ size_t count_confs(); private: //! Recalculate the current partial log-probabilities, masses, and probabilities. ISOSPEC_FORCE_INLINE void recalc(int idx) { for(; idx > 0; idx--) { partialLProbs[idx] = partialLProbs[idx+1] + marginalResults[idx]->get_lProb(counter[idx]); partialMasses[idx] = partialMasses[idx+1] + marginalResults[idx]->get_mass(counter[idx]); partialProbs[idx] = partialProbs[idx+1] * marginalResults[idx]->get_prob(counter[idx]); } partialLProbs_second_val = *partialLProbs_second; partialLProbs[0] = *partialLProbs_second + marginalResults[0]->get_lProb(counter[0]); lcfmsv = Lcutoff - partialLProbs_second_val; } }; //! The class that represents isotopologues above a given joint probability value. /*! This class generates subsequent isotopologues that ARE NOT GUARANTEED TO BE ORDERED BY probability. The overal set of isotopologues is guaranteed to surpass a given threshold of probability contained in the isotopic distribution. This calculations are performed in O(N) operations, where N is the total number of the output isotopologues. This class is not a true generator yet - the generator methods have been implemented for compatibility, but the class actually performs all computations during the initialization and stores them, and the generator methods only walk through the array of precomputed values. . It will be reimplemented as a true generator in 2.0. */ class ISOSPEC_EXPORT_SYMBOL IsoLayeredGenerator : public IsoGenerator { private: Summator totalProb; std::vector newaccepted; DirtyAllocator allocator; int* candidate; const std::vector** logProbs; /*!< Obtained log-probabilities. */ const std::vector** masses; /*!< Obtained masses. */ const std::vector** marginalConfs; /*!< Obtained counts of isotopes. */ MarginalTrek** marginalResults; std::vector* current; std::vector* next; double lprobThr; double targetCoverage; double percentageToExpand; bool do_trim; int layers; size_t generator_position; bool advanceToNextLayer(); public: bool advanceToNextConfiguration() override final; inline void get_conf_signature(int* space) const override final { int* conf = getConf(newaccepted[generator_position]); for(int ii=0; iiconfs()[conf[ii]], isotopeNumbers[ii]*sizeof(int)); space += isotopeNumbers[ii]; } }; IsoLayeredGenerator(Iso&& iso, double _targetCoverage, double _percentageToExpand = 0.3, int _tabSize = 1000, int _hashSize = 1000, bool trim = false); virtual ~IsoLayeredGenerator(); void terminate_search(); }; #if !ISOSPEC_BUILDING_R void printConfigurations( const std::tuple& results, int dimNumber, int* isotopeNumbers ); #endif /* !ISOSPEC_BUILDING_R */ } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/conf.h0000644000175000017500000000122313373520171016471 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once namespace IsoSpec { typedef int* Conf; } isospec-1.9.1/IsoSpecR/src/platform.h0000644000175000017500000000610213373520171017371 0ustar rusconirusconi #pragma once #if !defined(ISOSPEC_BUILDING_R) #define ISOSPEC_BUILDING_R true #endif #if !defined(ISOSPEC_BUILDING_CPP) #define ISOSPEC_BUILDING_CPP true #endif #if !defined(ISOSPEC_BUILDING_PYTHON) #define ISOSPEC_BUILDING_PYTHON false #endif #if !defined(ISOSPEC_BUILDING_OPENMS) #define ISOSPEC_BUILDING_OPENMS false #endif #if defined(__unix__) || defined(__unix) || \ (defined(__APPLE__) && defined(__MACH__)) #define ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY true #define ISOSPEC_TEST_WE_ARE_ON_WINDOWS false /* CYGWIN doesn't really count as Windows for our purposes, we'll be using UNIX API anyway */ #define ISOSPEC_TEST_GOT_SYSTEM_MMAN true #define ISOSPEC_TEST_GOT_MMAN true #elif defined(__MINGW32__) || defined(_WIN32) #define ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY false #define ISOSPEC_TEST_WE_ARE_ON_WINDOWS true #define ISOSPEC_TEST_GOT_SYSTEM_MMAN false #define ISOSPEC_TEST_GOT_MMAN true #else #define ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY false /* Well, probably... */ #define ISOSPEC_TEST_WE_ARE_ON_WINDOWS false #define ISOSPEC_TEST_GOT_SYSTEM_MMAN false #define ISOSPEC_TEST_GOT_MMAN false #endif #if !defined(ISOSPEC_USE_PTHREADS) #define ISOSPEC_USE_PTHREADS false /* TODO: possibly put a macro here to detect whether we */ #endif /* can/should use pthreads - or rip them out altogether. * Investigate whether the performance advantage of pthreads on * some platforms (*cough* CYGWIN *cough*) is still large * enough to justify keeping both implementations around */ #if !defined(ISOSPEC_WE_ARE_ON_UNIX_YAY) #define ISOSPEC_WE_ARE_ON_UNIX_YAY ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY #endif #if !defined(ISOSPEC_WE_ARE_ON_WINDOWS) #define ISOSPEC_WE_ARE_ON_WINDOWS ISOSPEC_TEST_WE_ARE_ON_WINDOWS #endif #if !defined(ISOSPEC_GOT_SYSTEM_MMAN) #define ISOSPEC_GOT_SYSTEM_MMAN ISOSPEC_TEST_GOT_SYSTEM_MMAN #endif #if !defined(ISOSPEC_GOT_MMAN) #define ISOSPEC_GOT_MMAN ISOSPEC_TEST_GOT_MMAN #endif // Note: __GNUC__ is defined by clang and gcc #ifdef __GNUC__ #define ISOSPEC_LIKELY(condition) __builtin_expect(static_cast(condition), 1) #define ISOSPEC_UNLIKELY(condition) __builtin_expect(static_cast(condition), 0) // For aggressive inlining #define ISOSPEC_FORCE_INLINE __attribute__ ((always_inline)) inline #elif defined _MSC_VER #define ISOSPEC_LIKELY(condition) condition #define ISOSPEC_UNLIKELY(condition) condition #define ISOSPEC_FORCE_INLINE __forceinline inline #else #define ISOSPEC_LIKELY(condition) condition #define ISOSPEC_UNLIKELY(condition) condition #define ISOSPEC_FORCE_INLINE inline #endif #if ISOSPEC_GOT_MMAN #if ISOSPEC_GOT_SYSTEM_MMAN #include #else #include "mman.h" #endif #else #include /* malloc, free, rand */ #endif #if defined(OPENMS_DLLAPI) /* IsoSpec is being built as a part of OpenMS: use their visibility macros */ #define ISOSPEC_EXPORT_SYMBOL OPENMS_DLLAPI #else /* it's a can of worms we don't yet want to open ourselves though... */ #define ISOSPEC_EXPORT_SYMBOL #endif isospec-1.9.1/IsoSpecR/src/unity-build.cpp0000644000175000017500000000060513373520171020347 0ustar rusconirusconi#include "platform.h" #if !ISOSPEC_GOT_SYSTEM_MMAN && ISOSPEC_GOT_MMAN #include "mman.c" #endif #if !ISOSPEC_BUILDING_R #include "allocator.cpp" #include "dirtyAllocator.cpp" #include "isoSpec++.cpp" #include "isoMath.cpp" #include "marginalTrek++.cpp" #include "operators.cpp" #include "element_tables.cpp" #include "cwrapper.cpp" #include "tabulator.cpp" #include "misc.cpp" #endif isospec-1.9.1/IsoSpecR/src/mman.h0000644000175000017500000000347213373520171016504 0ustar rusconirusconi/* * sys/mman.h * mman-win32 * * This file has been included as a part of IsoSpec project, under a MIT licence. It * comes from the repository: * * https://github.com/witwall/mman-win32 * * which itself is a mirror of: * * https://code.google.com/archive/p/mman-win32/ */ #pragma once #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. #endif /* All the headers include this file. */ #ifndef _MSC_VER #include <_mingw.h> #endif #if defined(MMAN_LIBRARY) #define MMANSHARED_EXPORT __declspec(dllexport) #else #define MMANSHARED_EXPORT __declspec(dllimport) #endif /* Determine offset type */ #include #if defined(_WIN64) typedef int64_t OffsetType; #else typedef uint32_t OffsetType; #endif #include #ifdef __cplusplus extern "C" { #endif #define PROT_NONE 0 #define PROT_READ 1 #define PROT_WRITE 2 #define PROT_EXEC 4 #define MAP_FILE 0 #define MAP_SHARED 1 #define MAP_PRIVATE 2 #define MAP_TYPE 0xf #define MAP_FIXED 0x10 #define MAP_ANONYMOUS 0x20 #define MAP_ANON MAP_ANONYMOUS #define MAP_FAILED ((void *)-1) /* Flags for msync. */ #define MS_ASYNC 1 #define MS_SYNC 2 #define MS_INVALIDATE 4 MMANSHARED_EXPORT void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off); MMANSHARED_EXPORT int munmap(void *addr, size_t len); MMANSHARED_EXPORT int _mprotect(void *addr, size_t len, int prot); MMANSHARED_EXPORT int msync(void *addr, size_t len, int flags); MMANSHARED_EXPORT int mlock(const void *addr, size_t len); MMANSHARED_EXPORT int munlock(const void *addr, size_t len); #ifdef __cplusplus } #endif isospec-1.9.1/IsoSpecR/src/dirtyAllocator.cpp0000644000175000017500000000304313373520171021075 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include #include #include "dirtyAllocator.h" namespace IsoSpec { DirtyAllocator::DirtyAllocator( const int dim, const int tabSize ): tabSize(tabSize) { cellSize = sizeof(double) + sizeof(int) * dim; // Fix memory alignment problems for SPARC if(cellSize % sizeof(double) != 0) cellSize += sizeof(double) - cellSize % sizeof(double); currentTab = malloc( cellSize * tabSize ); currentConf = currentTab; endOfTablePtr = reinterpret_cast(currentTab) + cellSize*tabSize; } DirtyAllocator::~DirtyAllocator() { for(unsigned int i = 0; i < prevTabs.size(); ++i) free(prevTabs[i]); free(currentTab); } void DirtyAllocator::shiftTables() { prevTabs.push_back(currentTab); currentTab = malloc( cellSize * tabSize ); currentConf = currentTab; endOfTablePtr = reinterpret_cast(currentTab) + cellSize*tabSize; } } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/isoMath.cpp0000644000175000017500000000455713373520171017520 0ustar rusconirusconi/* * This file has been released into public domain by John D. Cook * and is used here with some slight modifications (which are hereby * also released into public domain), * * This file is part of IsoSpec. */ #include #include #include "isoMath.h" #include "platform.h" namespace IsoSpec { const double pi = 3.14159265358979323846264338328; void release_g_lfact_table() { #if ISOSPEC_GOT_MMAN munmap(g_lfact_table, ISOSPEC_G_FACT_TABLE_SIZE*sizeof(double)); #else free(g_lfact_table); #endif } double* alloc_lfact_table() { double* ret; # if ISOSPEC_GOT_MMAN ret = reinterpret_cast(mmap(nullptr, sizeof(double)*ISOSPEC_G_FACT_TABLE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); #else ret = reinterpret_cast(calloc(ISOSPEC_G_FACT_TABLE_SIZE, sizeof(double))); #endif std::atexit(release_g_lfact_table); return ret; } double* g_lfact_table = alloc_lfact_table(); double RationalApproximation(double t) { // Abramowitz and Stegun formula 26.2.23. // The absolute value of the error should be less than 4.5 e-4. double c[] = {2.515517, 0.802853, 0.010328}; double d[] = {1.432788, 0.189269, 0.001308}; return t - ((c[2]*t + c[1])*t + c[0]) / (((d[2]*t + d[1])*t + d[0])*t + 1.0); } double NormalCDFInverse(double p) { if (p < 0.5) return -RationalApproximation( sqrt(-2.0*log(p)) ); else return RationalApproximation( sqrt(-2.0*log(1-p)) ); } double NormalCDFInverse(double p, double mean, double stdev) { return mean + stdev * NormalCDFInverse(p); } double NormalCDF(double x, double mean, double stdev) { x = (x-mean)/stdev * 0.7071067811865476; // constants double a1 = 0.254829592; double a2 = -0.284496736; double a3 = 1.421413741; double a4 = -1.453152027; double a5 = 1.061405429; double p = 0.3275911; // Save the sign of x int sign = 1; if (x < 0) sign = -1; x = fabs(x); // A&S formula 7.1.26 double t = 1.0/(1.0 + p*x); double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x); return 0.5*(1.0 + sign*y); } double NormalPDF(double x, double mean, double stdev) { double two_variance = stdev * stdev * 2.0; double delta = x-mean; return exp( -delta*delta / two_variance ) / sqrt( two_variance * pi ); } } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/mman.c0000644000175000017500000001057413373520171016500 0ustar rusconirusconi/* * This file has been included as a part of IsoSpec project, under a MIT licence. It * comes from the repository: * * https://github.com/witwall/mman-win32 * * which itself is a mirror of: * * https://code.google.com/archive/p/mman-win32/ */ #include "platform.h" #if ISOSPEC_GOT_MMAN && !ISOSPEC_GOT_SYSTEM_MMAN #include #include #include #include "mman.h" #ifndef FILE_MAP_EXECUTE #define FILE_MAP_EXECUTE 0x0020 #endif /* FILE_MAP_EXECUTE */ static int __map_mman_error(const DWORD err, const int deferr) { if (err == 0) return 0; //TODO: implement return err; } static DWORD __map_mmap_prot_page(const int prot) { DWORD protect = 0; if (prot == PROT_NONE) return protect; if ((prot & PROT_EXEC) != 0) { protect = ((prot & PROT_WRITE) != 0) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; } else { protect = ((prot & PROT_WRITE) != 0) ? PAGE_READWRITE : PAGE_READONLY; } return protect; } static DWORD __map_mmap_prot_file(const int prot) { DWORD desiredAccess = 0; if (prot == PROT_NONE) return desiredAccess; if ((prot & PROT_READ) != 0) desiredAccess |= FILE_MAP_READ; if ((prot & PROT_WRITE) != 0) desiredAccess |= FILE_MAP_WRITE; if ((prot & PROT_EXEC) != 0) desiredAccess |= FILE_MAP_EXECUTE; return desiredAccess; } void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off) { HANDLE fm, h; void * map = MAP_FAILED; #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4293) #endif const DWORD dwFileOffsetLow = (sizeof(OffsetType) <= sizeof(DWORD)) ? (DWORD)off : (DWORD)(off & 0xFFFFFFFFL); const DWORD dwFileOffsetHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ? (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL); const DWORD protect = __map_mmap_prot_page(prot); const DWORD desiredAccess = __map_mmap_prot_file(prot); const OffsetType maxSize = off + (OffsetType)len; const DWORD dwMaxSizeLow = (sizeof(OffsetType) <= sizeof(DWORD)) ? (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL); const DWORD dwMaxSizeHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ? (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL); #ifdef _MSC_VER #pragma warning(pop) #endif errno = 0; if (len == 0 /* Unsupported flag combinations */ || (flags & MAP_FIXED) != 0 /* Usupported protection combinations */ || prot == PROT_EXEC) { errno = EINVAL; return MAP_FAILED; } h = ((flags & MAP_ANONYMOUS) == 0) ? (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE; if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE) { errno = EBADF; return MAP_FAILED; } fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL); if (fm == NULL) { errno = __map_mman_error(GetLastError(), EPERM); return MAP_FAILED; } map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len); CloseHandle(fm); if (map == NULL) { errno = __map_mman_error(GetLastError(), EPERM); return MAP_FAILED; } return map; } int munmap(void *addr, size_t len) { if (UnmapViewOfFile(addr)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } int _mprotect(void *addr, size_t len, int prot) { DWORD newProtect = __map_mmap_prot_page(prot); DWORD oldProtect = 0; if (VirtualProtect(addr, len, newProtect, &oldProtect)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } int msync(void *addr, size_t len, int flags) { if (FlushViewOfFile(addr, len)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } int mlock(const void *addr, size_t len) { if (VirtualLock((LPVOID)addr, len)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } int munlock(const void *addr, size_t len) { if (VirtualUnlock((LPVOID)addr, len)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } #endif isospec-1.9.1/IsoSpecR/src/operators.cpp0000644000175000017500000000241513373520171020121 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include "operators.h" #include "marginalTrek++.h" namespace IsoSpec { KeyHasher::KeyHasher(int _dim) : dim(_dim) {} ConfEqual::ConfEqual(int dim) : size( dim*sizeof(int) ) {} ConfOrderMarginal::ConfOrderMarginal(const double* _logProbs, int _dim) : logProbs(_logProbs), dim(_dim) {} ConfOrderMarginalDescending::ConfOrderMarginalDescending(const double* _logProbs, int _dim) : logProbs(_logProbs), dim(_dim) {} OrderMarginalsBySizeDecresing::OrderMarginalsBySizeDecresing(PrecalculatedMarginal const* const * const _T) : T(_T) {} bool OrderMarginalsBySizeDecresing::operator()(int m1, int m2) { return T[m1]->get_no_confs() > T[m2]->get_no_confs(); } } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/cwrapper.h0000644000175000017500000000750613373520171017401 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #define ISOSPEC_ALGO_LAYERED 0 #define ISOSPEC_ALGO_ORDERED 1 #define ISOSPEC_ALGO_THRESHOLD_ABSOLUTE 2 #define ISOSPEC_ALGO_THRESHOLD_RELATIVE 3 #define ISOSPEC_ALGO_LAYERED_ESTIMATE 4 #ifdef __cplusplus extern "C" { #else #include #endif void * setupIso(int dimNumber, const int* isotopeNumbers, const int* atomCounts, const double* isotopeMasses, const double* isotopeProbabilities); void deleteIso(void* iso); #define ISOSPEC_C_FN_HEADER(generatorType, dataType, method)\ dataType method##generatorType(void* generator); #define ISOSPEC_C_FN_HEADER_GET_CONF_SIGNATURE(generatorType)\ void method##generatorType(void* generator); #define ISOSPEC_C_FN_HEADERS(generatorType)\ ISOSPEC_C_FN_HEADER(generatorType, double, mass) \ ISOSPEC_C_FN_HEADER(generatorType, double, lprob) \ ISOSPEC_C_FN_HEADER(generatorType, double, prob) \ ISOSPEC_C_FN_HEADER_GET_CONF_SIGNATURE(generatorType) \ ISOSPEC_C_FN_HEADER(generatorType, bool, advanceToNextConfiguration) \ ISOSPEC_C_FN_HEADER(generatorType, void, delete) //______________________________________________________THRESHOLD GENERATOR void* setupIsoThresholdGenerator(void* iso, double threshold, bool _absolute, int _tabSize, int _hashSize); ISOSPEC_C_FN_HEADERS(IsoThresholdGenerator) //______________________________________________________LAYERED GENERATOR void* setupIsoLayeredGenerator(void* iso, double _target_coverage, double _percentage_to_expand, int _tabSize, int _hashSize, bool _do_trim); ISOSPEC_C_FN_HEADERS(IsoLayeredGenerator) //______________________________________________________ORDERED GENERATOR void* setupIsoOrderedGenerator(void* iso, int _tabSize, int _hashSize); ISOSPEC_C_FN_HEADERS(IsoOrderedGenerator) void* setupThresholdTabulator(void* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs); void deleteThresholdTabulator(void* tabulator); const double* massesThresholdTabulator(void* tabulator); const double* lprobsThresholdTabulator(void* tabulator); const double* probsThresholdTabulator(void* tabulator); const int* confsThresholdTabulator(void* tabulator); int confs_noThresholdTabulator(void* tabulator); void* setupLayeredTabulator(void* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs); void deleteLayeredTabulator(void* tabulator); const double* massesLayeredTabulator(void* tabulator); const double* lprobsLayeredTabulator(void* tabulator); const double* probsLayeredTabulator(void* tabulator); const int* confsLayeredTabulator(void* tabulator); int confs_noLayeredTabulator(void* tabulator); #ifdef __cplusplus } #endif isospec-1.9.1/IsoSpecR/src/misc.cpp0000644000175000017500000000321113373520171017031 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include "misc.h" #include "platform.h" #include #define mswap(x, y) swapspace = x; x = y; y=swapspace; namespace IsoSpec { void* quickselect(void** array, int n, int start, int end) { void* swapspace; if(start == end) return array[start]; while(true) { // Partition part int len = end - start; #if ISOSPEC_BUILDING_R int pivot = len/2 + start; #else int pivot = rand() % len + start; #endif void* pval = array[pivot]; double pprob = getLProb(pval); mswap(array[pivot], array[end-1]); int loweridx = start; for(int i=start; i. */ #pragma once #include #include #include #include #include "isoMath.h" namespace IsoSpec { inline double combinedSum( const int* conf, const std::vector** valuesContainer, int dimNumber ){ double res = 0.0; for(int i=0; i( reinterpret_cast(conf) + sizeof(double) ); } inline double getLProb(void* conf) { double ret = *reinterpret_cast(conf); return ret; } inline double unnormalized_logProb(const int* conf, const double* logProbs, int dim) { double res = 0.0; int curr_method = fegetround(); fesetround(FE_TOWARDZERO); for(int i=0; i < dim; i++) res += minuslogFactorial(conf[i]); fesetround(FE_UPWARD); for(int i=0; i < dim; i++) res += conf[i] * logProbs[i]; fesetround(curr_method); return res; } inline double mass(const int* conf, const double* masses, int dim) { double res = 0.0; for(int i=0; i < dim; i++) { res += conf[i] * masses[i]; } return res; } inline bool tupleCmp( std::tuple t1, std::tuple t2 ){ return std::get<1>(t1) > std::get<1>(t2); } template void printArray(const T* array, int size) { for (int i=0; i void printVector(const std::vector& vec) { printArray(vec.data(), vec.size()); } template void printNestedArray(const T** array, const int* shape, int size) { for (int i=0; i inline static T* array_copy(const T* A, int size) { T* ret = new T[size]; memcpy(ret, A, size*sizeof(T)); return ret; } template void dealloc_table(T* tbl, int dim) { for(int i=0; i; template class Tabulator; } // namespace IsoSpec isospec-1.9.1/IsoSpecR/src/element_tables.cpp0000644000175000017500000014632513373520171021077 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include "element_tables.h" namespace IsoSpec { #ifdef __cplusplus extern "C" { #endif const int elem_table_atomicNo [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 12, 12, 12, 13, 14, 14, 14, 15, 16, 16, 16, 16, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 22, 22, 22, 22, 22, 23, 23, 24, 24, 24, 24, 25, 26, 26, 26, 26, 27, 28, 28, 28, 28, 28, 29, 29, 30, 30, 30, 30, 30, 31, 31, 32, 32, 32, 32, 32, 33, 34, 34, 34, 34, 34, 34, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 38, 38, 38, 38, 39, 40, 40, 40, 40, 40, 41, 42, 42, 42, 42, 42, 42, 42, 44, 44, 44, 44, 44, 44, 44, 45, 46, 46, 46, 46, 46, 46, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 53, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 56, 56, 56, 56, 56, 56, 56, 57, 57, 58, 58, 58, 58, 59, 60, 60, 60, 60, 60, 60, 60, 62, 62, 62, 62, 62, 62, 62, 63, 63, 64, 64, 64, 64, 64, 64, 64, 65, 66, 66, 66, 66, 66, 66, 66, 67, 68, 68, 68, 68, 68, 68, 69, 70, 70, 70, 70, 70, 70, 70, 71, 71, 72, 72, 72, 72, 72, 72, 73, 73, 74, 74, 74, 74, 74, 75, 75, 76, 76, 76, 76, 76, 76, 76, 77, 77, 78, 78, 78, 78, 78, 78, 79, 80, 80, 80, 80, 80, 80, 80, 81, 81, 82, 82, 82, 82, 83, 92, 92, 92, 90, 91, }; const double elem_table_mass [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { 1.00782503227, 2.01410177819, 3.016029322, 4.00260325414, 6.0151228871, 7.016003443, 9.01218316, 10.0129373, 11.0093053, 12, 13.0033548352, 14.0030740042, 15.0001088994, 15.9949146202, 16.9991317576, 17.9991596137, 18.9984031637, 19.992440182, 20.99384673, 21.99138512, 22.989769282, 23.985041701, 24.98583703, 25.98259302, 26.98153858, 27.9769265353, 28.9764946653, 29.973770012, 30.9737619986, 31.9720711741, 32.9714589101, 33.96786703, 35.9670812, 34.96885273, 36.96590264, 35.96754512, 37.9627322, 39.962383122, 38.963706493, 39.96399824, 40.961825263, 39.96259092, 41.9586181, 42.9587662, 43.9554822, 45.953692, 47.95252289, 44.9559086, 45.9526283, 46.9517593, 47.9479423, 48.9478663, 49.9447873, 49.9471567, 50.9439577, 49.9460427, 51.9405064, 52.9406484, 53.9388794, 54.9380443, 53.9396093, 55.9349363, 56.9353933, 57.9332743, 58.9331944, 57.9353423, 59.9307863, 60.9310563, 61.9283454, 63.9279674, 62.9295984, 64.9277906, 63.9291426, 65.9260347, 66.9271287, 67.9248457, 69.925322, 68.9255749, 70.9247037, 69.9242497, 71.92207586, 72.92345904, 73.921177761, 75.92140272, 74.9215957, 73.92247591, 75.91921372, 76.91991426, 77.9173092, 79.9165229, 81.9167001, 78.9183381, 80.9162901, 77.9203656, 79.9163786, 81.9134837, 82.9141272, 83.911497733, 85.910610633, 84.911789743, 86.909180536, 83.9134199, 85.9092619, 86.9088789, 87.9056139, 88.905842, 89.904702, 90.905642, 91.905032, 93.906312, 95.908272, 92.906372, 91.9068086, 93.9050853, 94.9058393, 95.9046763, 96.9060183, 97.9054053, 99.9074728, 95.9075903, 97.905296, 98.9059348, 99.9042148, 100.9055779, 101.9043449, 103.905432, 102.905502, 101.905602, 103.9040311, 104.9050809, 105.9034809, 107.9038929, 109.9051726, 106.905092, 108.9047551, 105.9064609, 107.9041839, 109.9030074, 110.9041834, 111.9027634, 112.9044083, 113.9033653, 115.9047632, 112.9040627, 114.903878789, 111.9048244, 113.9027837, 114.90334471, 115.9017431, 116.9029543, 117.9016073, 118.9033116, 119.9022027, 121.903442, 123.9052778, 120.903812, 122.904212, 119.904062, 121.903041, 122.904271, 123.902821, 124.904431, 125.903311, 127.9044617, 129.906222759, 126.904473, 123.905892, 125.904303, 127.9035318, 128.904780864, 129.90350941, 130.9050842, 131.904155094, 133.9053957, 135.907214488, 132.905451967, 129.906322, 131.9050618, 133.9045082, 134.9056882, 135.9045762, 136.9058272, 137.9052472, 137.907123, 138.906362, 135.9071293, 137.905998, 139.905442, 141.909252, 140.907662, 141.907732, 142.909822, 143.910092, 144.912582, 145.913122, 147.916902, 149.920902, 143.912012, 146.914902, 147.914832, 148.917192, 149.917282, 151.919742, 153.922222, 150.919862, 152.921242, 151.919802, 153.920872, 154.922632, 155.922132, 156.923972, 157.924112, 159.927062, 158.925352, 155.924282, 157.924422, 159.925202, 160.926942, 161.926812, 162.928742, 163.929182, 164.930332, 161.928792, 163.929212, 165.930302, 166.932052, 167.932382, 169.935472, 168.934222, 167.933892, 169.934772, 170.936332, 171.936392, 172.938222, 173.938872, 175.942582, 174.940782, 175.942692, 173.940052, 175.941412, 176.943232, 177.943712, 178.945822, 179.946562, 179.947462, 180.948002, 179.946712, 181.9482047, 182.9502237, 183.9509317, 185.954362, 184.9529559, 186.955751, 183.9524891, 185.953841, 186.955751, 187.955841, 188.958142, 189.958442, 191.961482, 190.960592, 192.962922, 189.959934, 191.961042, 193.9626817, 194.9647927, 195.9649527, 197.967892, 196.9665696, 195.965832, 197.9667693, 198.9682813, 199.9683273, 200.9703036, 201.9706436, 203.9734943, 202.9723451, 204.9744281, 203.9730449, 205.9744669, 206.9758979, 207.9766539, 208.980401, 234.040952, 235.043932, 238.050792, 232.038062, 231.035882, }; const int elem_table_massNo [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { 1, 2, 3, 4, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 35, 37, 36, 38, 40, 39, 40, 41, 40, 42, 43, 44, 46, 48, 45, 46, 47, 48, 49, 50, 50, 51, 50, 52, 53, 54, 55, 54, 56, 57, 58, 59, 58, 60, 61, 62, 64, 63, 65, 64, 66, 67, 68, 70, 69, 71, 70, 72, 73, 74, 76, 75, 74, 76, 77, 78, 80, 82, 79, 81, 78, 80, 82, 83, 84, 86, 85, 87, 84, 86, 87, 88, 89, 90, 91, 92, 94, 96, 93, 92, 94, 95, 96, 97, 98, 100, 96, 98, 99, 100, 101, 102, 104, 103, 102, 104, 105, 106, 108, 110, 107, 109, 106, 108, 110, 111, 112, 113, 114, 116, 113, 115, 112, 114, 115, 116, 117, 118, 119, 120, 122, 124, 121, 123, 120, 122, 123, 124, 125, 126, 128, 130, 127, 124, 126, 128, 129, 130, 131, 132, 134, 136, 133, 130, 132, 134, 135, 136, 137, 138, 138, 139, 136, 138, 140, 142, 141, 142, 143, 144, 145, 146, 148, 150, 144, 147, 148, 149, 150, 152, 154, 151, 153, 152, 154, 155, 156, 157, 158, 160, 159, 156, 158, 160, 161, 162, 163, 164, 165, 162, 164, 166, 167, 168, 170, 169, 168, 170, 171, 172, 173, 174, 176, 175, 176, 174, 176, 177, 178, 179, 180, 180, 181, 180, 182, 183, 184, 186, 185, 187, 184, 186, 187, 188, 189, 190, 192, 191, 193, 190, 192, 194, 195, 196, 198, 197, 196, 198, 199, 200, 201, 202, 204, 203, 205, 204, 206, 207, 208, 209, 234, 235, 238, 232, 231, }; const int elem_table_extraNeutrons [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 4, 0, 2, 0, 2, 4, 0, 1, 2, 0, 2, 3, 4, 6, 8, 0, 0, 1, 2, 3, 4, 0, 1, 0, 2, 3, 4, 0, 0, 2, 3, 4, 0, 0, 2, 3, 4, 6, 0, 2, 0, 2, 3, 4, 6, 0, 2, 0, 2, 3, 4, 6, 0, 0, 2, 3, 4, 6, 8, 0, 2, 0, 2, 4, 5, 6, 8, 0, 2, 0, 2, 3, 4, 0, 0, 1, 2, 4, 6, 0, 0, 2, 3, 4, 5, 6, 8, 0, 2, 3, 4, 5, 6, 8, 0, 0, 2, 3, 4, 6, 8, 0, 2, 0, 2, 4, 5, 6, 7, 8, 10, 0, 2, 0, 2, 3, 4, 5, 6, 7, 8, 10, 12, 0, 2, 0, 2, 3, 4, 5, 6, 8, 10, 0, 0, 2, 4, 5, 6, 7, 8, 10, 12, 0, 0, 2, 4, 5, 6, 7, 8, 0, 1, 0, 2, 4, 6, 0, 0, 1, 2, 3, 4, 6, 8, 0, 3, 4, 5, 6, 8, 10, 0, 2, 0, 2, 3, 4, 5, 6, 8, 0, 0, 2, 4, 5, 6, 7, 8, 0, 0, 2, 4, 5, 6, 8, 0, 0, 2, 3, 4, 5, 6, 8, 0, 1, 0, 2, 3, 4, 5, 6, 0, 1, 0, 2, 3, 4, 6, 0, 2, 0, 2, 3, 4, 5, 6, 8, 0, 2, 0, 2, 4, 5, 6, 8, 0, 0, 2, 3, 4, 5, 6, 8, 0, 2, 0, 2, 3, 4, 0, 1, 2, 5, 0, 0, }; const char* elem_table_element [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { "hydrogen", "hydrogen", "helium", "helium", "lithium", "lithium", "beryllium", "boron", "boron", "carbon", "carbon", "nitrogen", "nitrogen", "oxygen", "oxygen", "oxygen", "fluorine", "neon", "neon", "neon", "sodium", "magnesium", "magnesium", "magnesium", "aluminium", "silicon", "silicon", "silicon", "phosphorus", "sulfur", "sulfur", "sulfur", "sulfur", "chlorine", "chlorine", "argon", "argon", "argon", "potassium", "potassium", "potassium", "calcium", "calcium", "calcium", "calcium", "calcium", "calcium", "scandium", "titanium", "titanium", "titanium", "titanium", "titanium", "vanadium", "vanadium", "chromium", "chromium", "chromium", "chromium", "manganese", "iron", "iron", "iron", "iron", "cobalt", "nickel", "nickel", "nickel", "nickel", "nickel", "copper", "copper", "zinc", "zinc", "zinc", "zinc", "zinc", "gallium", "gallium", "germanium", "germanium", "germanium", "germanium", "germanium", "arsenic", "selenium", "selenium", "selenium", "selenium", "selenium", "selenium", "bromine", "bromine", "krypton", "krypton", "krypton", "krypton", "krypton", "krypton", "rubidium", "rubidium", "strontium", "strontium", "strontium", "strontium", "yttrium", "zirconium", "zirconium", "zirconium", "zirconium", "zirconium", "niobium", "molybdenum", "molybdenum", "molybdenum", "molybdenum", "molybdenum", "molybdenum", "molybdenum", "ruthenium", "ruthenium", "ruthenium", "ruthenium", "ruthenium", "ruthenium", "ruthenium", "rhodium", "palladium", "palladium", "palladium", "palladium", "palladium", "palladium", "silver", "silver", "cadmium", "cadmium", "cadmium", "cadmium", "cadmium", "cadmium", "cadmium", "cadmium", "indium", "indium", "tin", "tin", "tin", "tin", "tin", "tin", "tin", "tin", "tin", "tin", "antimony", "antimony", "tellurium", "tellurium", "tellurium", "tellurium", "tellurium", "tellurium", "tellurium", "tellurium", "iodine", "xenon", "xenon", "xenon", "xenon", "xenon", "xenon", "xenon", "xenon", "xenon", "caesium", "barium", "barium", "barium", "barium", "barium", "barium", "barium", "lanthanum", "lanthanum", "cerium", "cerium", "cerium", "cerium", "praseodymium", "neodymium", "neodymium", "neodymium", "neodymium", "neodymium", "neodymium", "neodymium", "samarium", "samarium", "samarium", "samarium", "samarium", "samarium", "samarium", "europium", "europium", "gadolinium", "gadolinium", "gadolinium", "gadolinium", "gadolinium", "gadolinium", "gadolinium", "terbium", "dysprosium", "dysprosium", "dysprosium", "dysprosium", "dysprosium", "dysprosium", "dysprosium", "holmium", "erbium", "erbium", "erbium", "erbium", "erbium", "erbium", "thulium", "ytterbium", "ytterbium", "ytterbium", "ytterbium", "ytterbium", "ytterbium", "ytterbium", "lutetium", "lutetium", "hafnium", "hafnium", "hafnium", "hafnium", "hafnium", "hafnium", "tantalum", "tantalum", "tungsten", "tungsten", "tungsten", "tungsten", "tungsten", "rhenium", "rhenium", "osmium", "osmium", "osmium", "osmium", "osmium", "osmium", "osmium", "iridium", "iridium", "platinum", "platinum", "platinum", "platinum", "platinum", "platinum", "gold", "mercury", "mercury", "mercury", "mercury", "mercury", "mercury", "mercury", "thallium", "thallium", "lead", "lead", "lead", "lead", "bismuth", "uranium", "uranium", "uranium", "thorium", "protactinium", }; const char* elem_table_symbol [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { "H", "H", "He", "He", "Li", "Li", "Be", "B", "B", "C", "C", "N", "N", "O", "O", "O", "F", "Ne", "Ne", "Ne", "Na", "Mg", "Mg", "Mg", "Al", "Si", "Si", "Si", "P", "S", "S", "S", "S", "Cl", "Cl", "Ar", "Ar", "Ar", "K", "K", "K", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Sc", "Ti", "Ti", "Ti", "Ti", "Ti", "V", "V", "Cr", "Cr", "Cr", "Cr", "Mn", "Fe", "Fe", "Fe", "Fe", "Co", "Ni", "Ni", "Ni", "Ni", "Ni", "Cu", "Cu", "Zn", "Zn", "Zn", "Zn", "Zn", "Ga", "Ga", "Ge", "Ge", "Ge", "Ge", "Ge", "As", "Se", "Se", "Se", "Se", "Se", "Se", "Br", "Br", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Rb", "Rb", "Sr", "Sr", "Sr", "Sr", "Y", "Zr", "Zr", "Zr", "Zr", "Zr", "Nb", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Rh", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Ag", "Ag", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "In", "In", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sb", "Sb", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "I", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Cs", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "La", "La", "Ce", "Ce", "Ce", "Ce", "Pr", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Eu", "Eu", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Tb", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Ho", "Er", "Er", "Er", "Er", "Er", "Er", "Tm", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Lu", "Lu", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Ta", "Ta", "W", "W", "W", "W", "W", "Re", "Re", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Ir", "Ir", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Au", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Tl", "Tl", "Pb", "Pb", "Pb", "Pb", "Bi", "U", "U", "U", "Th", "Pa", }; const bool elem_table_Radioactive [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, true, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, true, false, false, false, true, false, true, true, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, true, false, true, false, false, false, false, false, true, true, true, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, }; const double elem_table_probability [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { 0.999884290164307909520857720053754746913909912109375000000000, 0.000115709835692033314582735648023970043141162022948265075684, 0.000001342999991941999914655050951672876635711872950196266174, 0.999998657000008006612290500925155356526374816894531250000000, 0.075933925285977116326208147256693337112665176391601562500000, 0.924066074714022800407065005856566131114959716796875000000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.199480830670926506664741850727295968681573867797851562500000, 0.800519169329073410068531302385963499546051025390625000000000, 0.989211941850466902614869013632414862513542175292968750000000, 0.010788058149533083507343178553128382191061973571777343750000, 0.996358014567941707717579902237048372626304626464843750000000, 0.003641985432058271465738386041266494430601596832275390625000, 0.997567609729561044495937949250219389796257019042968750000000, 0.000380998476006095935803702490218825005285907536745071411133, 0.002051391794432822109073288885383590240962803363800048828125, 1.000000000000000000000000000000000000000000000000000000000000, 0.904766666333356561757739200402284041047096252441406250000000, 0.002709810313278070148523823945652111433446407318115234375000, 0.092523523353365264010328417043638182803988456726074218750000, 1.000000000000000000000000000000000000000000000000000000000000, 0.789876809855211581279377242026384919881820678710937500000000, 0.100001999840012789633192369365133345127105712890625000000000, 0.110121190304775615209642580794024979695677757263183593750000, 1.000000000000000000000000000000000000000000000000000000000000, 0.922220833349999713490774411184247583150863647460937500000000, 0.046858437698747611166449900110819726251065731048583984375000, 0.030920728951252581667707985957349592354148626327514648437500, 1.000000000000000000000000000000000000000000000000000000000000, 0.949850011999040066967836537514813244342803955078125000000000, 0.007519398448124149821059081233443066594190895557403564453125, 0.042520598352131823427502155254842364229261875152587890625000, 0.000109991200703943683199964587160479823069181293249130249023, 0.757594848103037898923162174469325691461563110351562500000000, 0.242405151896962045565686594272847287356853485107421875000000, 0.003336205796380696270847510120916012965608388185501098632812, 0.000629799206452999775149304007015871320618316531181335449219, 0.996033994997166272078459314798237755894660949707031250000000, 0.932580526071084436878777523816097527742385864257812500000000, 0.000117099885242112454345267402722186034225160256028175354004, 0.067302374043673424131029037198459263890981674194335937500000, 0.969400838426726974006442105746828019618988037109375000000000, 0.006472228417153705684605746739634923869743943214416503906250, 0.001350985058105257227353823701321289263432845473289489746094, 0.020860869278785776348428271376178599894046783447265625000000, 0.000042999524425259849917842214228613784143817611038684844971, 0.001872079294802999303859447621789513505063951015472412109375, 1.000000000000000000000000000000000000000000000000000000000000, 0.082520097588289403889305617667559999972581863403320312500000, 0.074411070671519405350657905273692449554800987243652343750000, 0.737141543014838140912559083517407998442649841308593750000000, 0.054113506379234489751528514034362160600721836090087890625000, 0.051813782346118462951434224805780104361474514007568359375000, 0.002503979968160254584302881752932989911641925573348999023438, 0.997496020031839680797247638111002743244171142578125000000000, 0.043450743830478963380947732275672024115920066833496093750000, 0.837881075122238416774678171350387856364250183105468750000000, 0.095010483865806516501351097758742980659008026123046875000000, 0.023657697181476075587447382986283628270030021667480468750000, 1.000000000000000000000000000000000000000000000000000000000000, 0.058452792721208068904559240763774141669273376464843750000000, 0.917532497856775930422656983864726498723030090332031250000000, 0.021190743592002535267138085828264593146741390228271484375000, 0.002823965830013456732028309659199294401332736015319824218750, 1.000000000000000000000000000000000000000000000000000000000000, 0.680769095231327558970235713786678388714790344238281250000000, 0.262230419610671172669924544607056304812431335449218750000000, 0.011399083035777891892426083586542517878115177154541015625000, 0.036346250253448952882706635136855766177177429199218750000000, 0.009255151868774300419340228529563319170847535133361816406250, 0.691494255172344751692037334578344598412513732910156250000000, 0.308505744827655137285660202906001359224319458007812500000000, 0.491645713885820234700929631799226626753807067871093750000000, 0.277325508740183801492662496457342058420181274414062500000000, 0.040405292597461665848879164286699960939586162567138671875000, 0.184515103497573135227227680843498092144727706909179687500000, 0.006108381278961075126765489784474993939511477947235107421875, 0.601079797840404217446064194518839940428733825683593750000000, 0.398920202159595671531633342965506017208099365234375000000000, 0.205705812301332946478993335404084064066410064697265625000000, 0.274503726116209989527305879164487123489379882812500000000000, 0.077504017086240106770844704442424699664115905761718750000000, 0.364982406812098314485837136089685373008251190185546875000000, 0.077304037684118531714716482383664697408676147460937500000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.008938426836876709608015190156038443092256784439086914062500, 0.093712506598838590798905556766840163618326187133789062500000, 0.076302570747548426055573145276866853237152099609375000000000, 0.237686167234566703143627819372341036796569824218750000000000, 0.496053694549759227605534306348999962210655212402343750000000, 0.087306634032410290746639702774700708687305450439453125000000, 0.506898896176611657438115798868238925933837890625000000000000, 0.493101103823388231539581738616107031702995300292968750000000, 0.003552948126957346328819165037771199422422796487808227539062, 0.022860666234272977725971998097520554438233375549316406250000, 0.115931407401451927463575941601447993889451026916503906250000, 0.115000220996773441783922464765055337920784950256347656250000, 0.569863179997571966950431487930472940206527709960937500000000, 0.172791577242972227423933873069472610950469970703125000000000, 0.721691132354705722207199869444593787193298339843750000000000, 0.278308867645294166770497668039752170443534851074218750000000, 0.005609775608975640752429381308274969342164695262908935546875, 0.098606055757769678349333730693615507334470748901367187500000, 0.070007199712011511372189431767765199765563011169433593750000, 0.825776968921243081922511919401586055755615234375000000000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.514422711621750239352479638910153880715370178222656250000000, 0.112234410554393593262290096390643157064914703369140625000000, 0.171550886397901253266340404479706194251775741577148437500000, 0.173788376250214926521664438041625544428825378417968750000000, 0.028003615175739928616627238966430013533681631088256835937500, 1.000000000000000000000000000000000000000000000000000000000000, 0.145308494342837241086741073559096548706293106079101562500000, 0.091496458524138415957516201615362660959362983703613281250000, 0.158387558641321063435114524509117472916841506958007812500000, 0.166690329831184980147185115129104815423488616943359375000000, 0.095999792030779435014764544575882609933614730834960937500000, 0.243900902666405350327494261364336125552654266357421875000000, 0.098216463963333416886669624545902479439973831176757812500000, 0.055402974808013198682044020415560225956141948699951171875000, 0.018726273471579152340993346115283202379941940307617187500000, 0.127588609866636532030881312493875157088041305541992187500000, 0.126054915071900669465421174209041055291891098022460937500000, 0.170586053375378299268305681835045106709003448486328125000000, 0.315451225206183960558803391904802992939949035644531250000000, 0.186189948200308125203505937861336860805749893188476562500000, 1.000000000000000000000000000000000000000000000000000000000000, 0.010207550187954890497099569302008603699505329132080078125000, 0.111463248820283120088525663504697149619460105895996093750000, 0.223336399264176588275176982278935611248016357421875000000000, 0.273264416540030363744762098576757125556468963623046875000000, 0.264546508837878890929573572066146880388259887695312500000000, 0.117181876349676070137029171291942475363612174987792968750000, 0.518389668985958174118877650471404194831848144531250000000000, 0.481610331014041714858819887012941762804985046386718750000000, 0.012567197514954164816458614950533956289291381835937500000000, 0.008928009053980960965657409644791187020018696784973144531250, 0.124890149496662231087817929164884844794869422912597656250000, 0.127983459688489453753845737082883715629577636718750000000000, 0.241267197414976458658131264201074372977018356323242187500000, 0.122184752800125570604272695618419675156474113464355468750000, 0.287277937020044504823346187549759633839130401611328125000000, 0.074901297010766587636254598692175932228565216064453125000000, 0.042954845418549769675564675708301365375518798828125000000000, 0.957045154581450119302132861776044592261314392089843750000000, 0.009707379007667929146641050408561568474397063255310058593750, 0.006608215781738930282018795736576066701672971248626708984375, 0.003409079548521898664348306340343697229400277137756347656250, 0.145370749897527656857576516813423950225114822387695312500000, 0.076859248003039171148742525474517606198787689208984375000000, 0.242144620952342848330118840749491937458515167236328125000000, 0.085916802463334898676272644024720648303627967834472656250000, 0.325722055045137792728127124064485542476177215576171875000000, 0.046317494276545329023875297025369945913553237915039062500000, 0.057944355024143474885978122301821713335812091827392578125000, 0.572091349038115315472907695948379114270210266113281250000000, 0.427908650961884573504789841535966843366622924804687500000000, 0.000909764371027903685079651907585684966761618852615356445312, 0.025505394102927340937991829150632838718593120574951171875000, 0.008927687728878220055350745099076448241248726844787597656250, 0.047401722953754971134898710261040832847356796264648437500000, 0.070696689557404629455916733604681212455034255981445312500000, 0.188376210561464557668998054396070074290037155151367187500000, 0.317407791382032011817670991149498149752616882324218750000000, 0.340774739342510235573513455165084451436996459960937500000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.000952296533640617525774685336870106766582466661930084228516, 0.000890196759683794711613680217254795934422872960567474365234, 0.019102830465697103606848017420816177036613225936889648437500, 0.264005869018636762923790683998959138989448547363281250000000, 0.040709981815666186621971434078659513033926486968994140625000, 0.212323527142361190289676642350968904793262481689453125000000, 0.269085350529324029977829013660084456205368041992187500000000, 0.104356830141138279266499466757522895932197570800781250000000, 0.088573117593851946605099101361702196300029754638671875000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.001060985146207953045902061539607075246749445796012878417969, 0.001010985846198153050023993415607037604786455631256103515625, 0.024171461599537605313692267827718751505017280578613281250000, 0.065920277116120362670415033790050074458122253417968750000000, 0.078541300421794094099858796198532218113541603088378906250000, 0.112320827508414877726750091824214905500411987304687500000000, 0.716974162361726841119491382414707913994789123535156250000000, 0.000888171872103250392010975744483403104823082685470581054688, 0.999111828127896672846475212281802669167518615722656250000000, 0.001851973331584025024912354417949700291501358151435852050781, 0.002511963827720880421123794690174690913408994674682617187500, 0.884492463308528265031327464384958148002624511718750000000000, 0.111143599532166723053983048430382041260600090026855468750000, 1.000000000000000000000000000000000000000000000000000000000000, 0.271519166958828106483991859931848011910915374755859375000000, 0.121740433020292235233306143982190405949950218200683593750000, 0.237977663997580829446931716120161581784486770629882812500000, 0.082929723850915446070608538775559281930327415466308593750000, 0.171890140355501652713599014532519504427909851074218750000000, 0.057561075412857647115583148433870519511401653289794921875000, 0.056381796404024006608146635244338540360331535339355468750000, 0.030772522277086666181444840617587033193558454513549804687500, 0.149881578776357327065227309503825381398200988769531250000000, 0.112382691006085513873991033051424892619252204895019531250000, 0.138246406123312015612469849656918086111545562744140625000000, 0.073792068527347848272412988990254234522581100463867187500000, 0.267451009404714612482933944193064235150814056396484375000000, 0.227473723885095902019770619517657905817031860351562500000000, 0.478103065570820051632949798658955842256546020507812500000000, 0.521896934429179837344747738825390115380287170410156250000000, 0.002009636255837693018938550082452820788603276014328002929688, 0.021826049485043207132317633067941642366349697113037109375000, 0.147985214676143617129611129712429828941822052001953125000000, 0.204672954195290635048820604424690827727317810058593750000000, 0.156491675006823760529783839956508018076419830322265625000000, 0.248435033258980114689862261911912355571985244750976562500000, 0.218579437121880937322515592313720844686031341552734375000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.000562985756460361477619691594753703611786477267742156982422, 0.000952975889709990254573812595850768047966994345188140869141, 0.023291210732368467645203580218549177516251802444458007812500, 0.188889421097646226233024435714469291269779205322265625000000, 0.254747154896981076177553404704667627811431884765625000000000, 0.248957901365095435330943018925609067082405090332031250000000, 0.282598350261738351374418698469526134431362152099609375000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.001395973476503946332158423437874716910300776362419128417969, 0.016012695758780580435054474719436257146298885345458984375000, 0.335027234482544788995994622382568195462226867675781250000000, 0.228686654953555862368475004586798604577779769897460937500000, 0.269776674243189351631855288360384292900562286376953125000000, 0.149100767085425356395234075534972362220287322998046875000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.001232929969577727796758992440118163358420133590698242187500, 0.029822206098693591902470956256365752778947353363037109375000, 0.140905996539396560773838018576498143374919891357421875000000, 0.216800685721051017429417129278590437024831771850585937500000, 0.161027253651992552363481081556528806686401367187500000000000, 0.320249909805123023076589561242144554853439331054687500000000, 0.129961018214165419104588750087714288383722305297851562500000, 0.974008767577204226384424146090168505907058715820312500000000, 0.025991232422795697287742910930319339968264102935791015625000, 0.001609652315099938373749166586890169128309935331344604492188, 0.052668623577307296934613134453684324398636817932128906250000, 0.185969830516608397585898160286888014525175094604492187500000, 0.272821070648739838482299546740250661969184875488281250000000, 0.136190582834107815068946933934057597070932388305664062500000, 0.350740240108136591690168870627530850470066070556640625000000, 0.000120131992311552486551486096377772128107608295977115631104, 0.999879868007688354936135510797612369060516357421875000000000, 0.001209872963338849303702171589236513682408258318901062011719, 0.264988176241494621798722164385253563523292541503906250000000, 0.143124971877952811283307710255030542612075805664062500000000, 0.306387829277925793913794905165559612214565277099609375000000, 0.284289149639287863635672692907974123954772949218750000000000, 0.374005039798408045470523575204424560070037841796875000000000, 0.625994960201591843507173962279921397566795349121093750000000, 0.000209947723016968765524098428087995671376120299100875854492, 0.015926034417430057904541129687459033448249101638793945312500, 0.019615115836156795520173190539026109036058187484741210937500, 0.132457018202467580181291850749403238296508789062500000000000, 0.161519781574387955025429164379602298140525817871093750000000, 0.262554623898649197588639481182326562702655792236328125000000, 0.407717478347891348899878494194126687943935394287109375000000, 0.373050779688124722888176165724871680140495300292968750000000, 0.626949220311875166089521371759474277496337890625000000000000, 0.000121987349911814132899338936066868654961581341922283172607, 0.007821588901230941415221309398475568741559982299804687500000, 0.328605923565726210089366077227168716490268707275390625000000, 0.337788971283677852408544595164130441844463348388671875000000, 0.252107856415289710572125159160350449383258819580078125000000, 0.073553672484163390432598816914833150804042816162109375000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.001509815802472098391837085351596670079743489623069763183594, 0.099707835644051417967048678292485419660806655883789062500000, 0.168701418426951910145561441822792403399944305419921875000000, 0.230990819120067331082779560347262304276227951049804687500000, 0.131793921141620695713925215386552736163139343261718750000000, 0.298589572072207154462830658303573727607727050781250000000000, 0.068706617792629293139938795320631470531225204467773437500000, 0.295204095918081610427918803907232359051704406738281250000000, 0.704795904081918278549778733577113598585128784179687500000000, 0.014094362255097959285565778486670751590281724929809570312500, 0.241003598560575765796798464180028531700372695922851562500000, 0.221011595361855245345239495691203046590089797973632812500000, 0.523890443822470963652904174523428082466125488281250000000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.000054599923560107009460132254652364736102754250168800354004, 0.007204689913434121108226637630878030904568731784820556640625, 0.992740710163005690702675565262325108051300048828125000000000, 1.000000000000000000000000000000000000000000000000000000000000, 1.000000000000000000000000000000000000000000000000000000000000, }; const double elem_table_log_probability [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { -0.000115716530591520062594239337538937206772970966994762420654, -9.064424917075021070900220365729182958602905273437500000000000, -13.520604646423175054792409355286508798599243164062500000000000, -0.000001343000893767296712052561162564767727189973811618983746, -2.577891720978651601825504258158616721630096435546875000000000, -0.078971700466369670889932308455172460526227951049804687500000, 0.000000000000000000000000000000000000000000000000000000000000, -1.612037134131381055368592569720931351184844970703125000000000, -0.222494800137427506392384657374350354075431823730468750000000, -0.010846671177187771836769591971005866071209311485290527343750, -4.529315483514038120915756735485047101974487304687500000000000, -0.003648633607616148452623683340334537206217646598815917968750, -5.615226297668721500144783931318670511245727539062500000000000, -0.002435353337518350851781390176142849668394774198532104492188, -7.872715182829573166145564755424857139587402343750000000000000, -6.189236792082963845018639403861016035079956054687500000000000, 0.000000000000000000000000000000000000000000000000000000000000, -0.100078195781331494296217954342864686623215675354003906250000, -5.910876641640641970809610938886180520057678222656250000000000, -2.380292360271312634978357891668565571308135986328125000000000, 0.000000000000000000000000000000000000000000000000000000000000, -0.235878282572628383828572395941591821610927581787109375000000, -2.302565094793883382351395994191989302635192871093750000000000, -2.206173789605455404227996041299775242805480957031250000000000, 0.000000000000000000000000000000000000000000000000000000000000, -0.080970568540825488268453113960276823490858078002929687500000, -3.060624186220378017964094397029839456081390380859375000000000, -3.476328480144544208485513081541284918785095214843750000000000, 0.000000000000000000000000000000000000000000000000000000000000, -0.051451188958515865767839869704403099603950977325439453125000, -4.890269137820559386398144852137193083763122558593750000000000, -3.157766653355948971437783256988041102886199951171875000000000, -9.115110188972028737453001667745411396026611328125000000000000, -0.277606537419771426389303314863354898989200592041015625000000, -1.417144771312495832304989562544506043195724487304687500000000, -5.702921106825801444983881083317101001739501953125000000000000, -7.370109509296556282720302988309413194656372070312500000000000, -0.003973890456746663815690290277871099533513188362121582031250, -0.069799776156532433724066777358530089259147644042968750000000, -9.052483267360123875278077321127057075500488281250000000000000, -2.698559767416127019856730839819647371768951416015625000000000, -0.031077090678799931117159971449837030377238988876342773437500, -5.040234806716209270405215647770091891288757324218750000000000, -6.606921279942914004834619845496490597724914550781250000000000, -3.869880158236262079896050636307336390018463134765625000000000, -10.054321502209552008366699737962335348129272460937500000000000, -6.280705543488890540970714937429875135421752929687500000000000, 0.000000000000000000000000000000000000000000000000000000000000, -2.494713408178120150893164463923312723636627197265625000000000, -2.598150548864236686341655513388104736804962158203125000000000, -0.304975352295239643396485007542651146650314331054687500000000, -2.916671468480125817279713373864069581031799316406250000000000, -2.960099096648749483762230738648213446140289306640625000000000, -5.989873825712285437816717603709548711776733398437500000000000, -0.002507120169096173530054461053850900498218834400177001953125, -3.136127308188753737283605005359277129173278808593750000000000, -0.176879103699552453488053060937090776860713958740234375000000, -2.353768036988251211028000398073345422744750976562500000000000, -3.744066754776672834026385316974483430385589599609375000000000, 0.000000000000000000000000000000000000000000000000000000000000, -2.839535812544084603104010966490022838115692138671875000000000, -0.086067279673300162157190129619266372174024581909179687500000, -3.854190815670504033363386042765341699123382568359375000000000, -5.869613059277937416879922238877043128013610839843750000000000, 0.000000000000000000000000000000000000000000000000000000000000, -0.384532097536943340276849312431295402348041534423828125000000, -1.338531697560186861650777245813515037298202514648437500000000, -4.474222362274872466514352709054946899414062500000000000000000, -3.314664237037550087450199498562142252922058105468750000000000, -4.682574923715371539856278104707598686218261718750000000000000, -0.368900435688631012087768112905905582010746002197265625000000, -1.176014814002444008878001113771460950374603271484375000000000, -0.709996915609857004447746930964058265089988708496093750000000, -1.282563340904273152531800405995454639196395874023437500000000, -3.208794497707758708315850526560097932815551757812500000000000, -1.690023957076583371872402494773268699645996093750000000000000, -5.098093470692335316130083811003714799880981445312500000000000, -0.509027578151938331352255318051902577280998229980468750000000, -0.918993876681337473755206701753195375204086303710937500000000, -1.581308226517597503857359697576612234115600585937500000000000, -1.292790443930836863373201595095451921224594116210937500000000, -2.557425510595298323579527277615852653980255126953125000000000, -1.007906127076126923114429700945038348436355590820312500000000, -2.560009090805706488680471011321060359477996826171875000000000, 0.000000000000000000000000000000000000000000000000000000000000, -4.717395674310531639150667615467682480812072753906250000000000, -2.367523623737181281967423274181783199310302734375000000000000, -2.573048648630889889687978211441077291965484619140625000000000, -1.436804100526558380934716296906117349863052368164062500000000, -0.701071102975730831019518518587574362754821777343750000000000, -2.438328827816317101451204507611691951751708984375000000000000, -0.679443711102156733261381305055692791938781738281250000000000, -0.707041047215952844773312335746595636010169982910156250000000, -5.639977561836668762396129750413820147514343261718750000000000, -3.778337476933724126126890041632577776908874511718750000000000, -2.154756578276459499932116159470751881599426269531250000000000, -2.162821228909660220551813836209475994110107421875000000000000, -0.562358982058553724669991424889303743839263916015625000000000, -1.755669166607024767046141278115101158618927001953125000000000, -0.326158026142060741836559145667706616222858428955078125000000, -1.279023747338471794776637580071110278367996215820312500000000, -5.183244558647554178776317712618038058280944824218750000000000, -2.316622601837921013867571673472411930561065673828125000000000, -2.659157189193052328590738397906534373760223388671875000000000, -0.191430555333882340685036638205929193645715713500976562500000, 0.000000000000000000000000000000000000000000000000000000000000, -0.664709955358130821778672725486103445291519165039062500000000, -2.187165643480033949686003325041383504867553710937500000000000, -1.762875342696557545707491954090073704719543457031250000000000, -1.749916948420700224531287858553696423768997192382812500000000, -3.575421663722070153568211026140488684177398681640625000000000, 0.000000000000000000000000000000000000000000000000000000000000, -1.928896249393138528915869756019674241542816162109375000000000, -2.391455012103930855005273770075291395187377929687500000000000, -1.842710346617601580021528206998482346534729003906250000000000, -1.791617500319007794118419951701071113348007202148437500000000, -2.343409253862695162951013116980902850627899169921875000000000, -1.410993272797839370724659602274186909198760986328125000000000, -2.320581420206905942649200369487516582012176513671875000000000, -2.893121989774980473697496563545428216457366943359375000000000, -3.977827742728266446903262476553209125995635986328125000000000, -2.058944176423800787034679160569794476032257080078125000000000, -2.071037633074694905843671222100965678691864013671875000000000, -1.768515397703714908672623096208553761243820190429687500000000, -1.153751204177984268639534093381371349096298217773437500000000, -1.680987899482990099997437027923297137022018432617187500000000, 0.000000000000000000000000000000000000000000000000000000000000, -4.584627618010170380102863418869674205780029296875000000000000, -2.194060349407264354226754221599549055099487304687500000000000, -1.499076127310911887846600620832759886980056762695312500000000, -1.297315393792867643796284937707241624593734741210937500000000, -1.329738206325086657955125701846554875373840332031250000000000, -2.144028052451655508292560625704936683177947998046875000000000, -0.657028062796280343249577526876237243413925170898437500000000, -0.730619933776488150733996462804498150944709777832031250000000, -4.376665231519177190477876138174906373023986816406250000000000, -4.718561859232925925766721775289624929428100585937500000000000, -2.080320732081178736194715384044684469699859619140625000000000, -2.055854244595972435405428768717683851718902587890625000000000, -1.421850256682005708697147383645642548799514770507812500000000, -2.102221012532442756537420791573822498321533203125000000000000, -1.247305110167633124262920318869873881340026855468750000000000, -2.591584072043251474326552852289751172065734863281250000000000, -3.147605821582104113076638896018266677856445312500000000000000, -0.043904705171597842305875047941299271769821643829345703125000, -4.634868960235463575259018398355692625045776367187500000000000, -5.019441588675102039474040793720632791519165039062500000000000, -5.681312951243271847090454684803262352943420410156250000000000, -1.928467904013302591792466955666895955801010131835937500000000, -2.565779477876660052970692049711942672729492187500000000000000, -1.418220124080461719273671405971981585025787353515625000000000, -2.454375864191848055639866288402117788791656494140625000000000, -1.121710853164690879779641363711562007665634155273437500000000, -3.072235543110140021383358543971553444862365722656250000000000, -2.848272125086215300626690805074758827686309814453125000000000, -0.558456599237618478426270485215354710817337036132812500000000, -0.848845538512307262735134827380534261465072631835937500000000, -7.002324924918669424300787795800715684890747070312500000000000, -3.668865315739671117967191094066947698593139648437500000000000, -4.718597850559019590832576795946806669235229492187500000000000, -3.049096701706386802754877862753346562385559082031250000000000, -2.649356530974964485380951373372226953506469726562500000000000, -1.669314195717893856141245123581029474735260009765625000000000, -1.147567923673684653351756423944607377052307128906250000000000, -1.076533608421685217493291020218748599290847778320312500000000, 0.000000000000000000000000000000000000000000000000000000000000, -6.956634086757649271248737932182848453521728515625000000000000, -7.024068041375896243039278488140553236007690429687500000000000, -3.957918762987576943856993239023722708225250244140625000000000, -1.331783944951729026229259034153074026107788085937500000000000, -3.201281963147128539759478371706791222095489501953125000000000, -1.549644096147559713116947932576294988393783569335937500000000, -1.312726661492457758129148714942857623100280761718750000000000, -2.259939193445343441624117986066266894340515136718750000000000, -2.423926880572130126978436237550340592861175537109375000000000, 0.000000000000000000000000000000000000000000000000000000000000, -6.848557419252292000066972832428291440010070800781250000000000, -6.896829338845804180380127945682033896446228027343750000000000, -3.722582614455130833874818563344888389110565185546875000000000, -2.719309189565115580933252203976735472679138183593750000000000, -2.544130672523534641982223547529429197311401367187500000000000, -2.186395971313551900294669394497759640216827392578125000000000, -0.332715474789523235621402363904053345322608947753906250000000, -7.026345284034602123313106858404353260993957519531250000000000, -0.000888566530440708531556059934786162557429634034633636474609, -6.291503542654471203832144965417683124542236328125000000000000, -5.986690430272505913933400734094902873039245605468750000000000, -0.122741286268200244791160002932883799076080322265625000000000, -2.196932224286036738902794240857474505901336669921875000000000, 0.000000000000000000000000000000000000000000000000000000000000, -1.303722545566528001614869936020113527774810791015625000000000, -2.105864098995690714133388610207475721836090087890625000000000, -1.435578458464392248572494281688705086708068847656250000000000, -2.489761730430327446583760320208966732025146484375000000000000, -1.760899725099839052688821539049968123435974121093750000000000, -2.854908713800850428299327177228406071662902832031250000000000, -2.875608931369854293080834395368583500385284423828125000000000, -3.481133121051686263314195457496680319309234619140625000000000, -1.897909771509530774125096286297775804996490478515625000000000, -2.185845347988713882614320027641952037811279296875000000000000, -1.978717634408995396100294783536810427904129028320312500000000, -2.606504025680458358493751802598126232624053955078125000000000, -1.318818871830977013104302386636845767498016357421875000000000, -1.480720546667873893653677441761828958988189697265625000000000, -0.737928951383980402667361886415164917707443237304687500000000, -0.650285154216317162756411107693566009402275085449218750000000, -6.209801540532629005042508651968091726303100585937500000000000, -3.824651092041761124562526674708351492881774902343750000000000, -1.910642911045310476936265331460162997245788574218750000000000, -1.586341919151083468264573639316949993371963500976562500000000, -1.854752465261401805918239915627054870128631591796875000000000, -1.392573903203236485026650370855350047349929809570312500000000, -1.520605773895307155640921337180770933628082275390625000000000, 0.000000000000000000000000000000000000000000000000000000000000, -7.482256229504544720043668348807841539382934570312500000000000, -6.955920953990032629121742502320557832717895507812500000000000, -3.759679211363279094371137034613639116287231445312500000000000, -1.666593508702244319508167791354935616254806518554687500000000, -1.367483775157640080166743246081750839948654174804687500000000, -1.390471467634422086945278351777233183383941650390625000000000, -1.263728646463758931162146836868487298488616943359375000000000, 0.000000000000000000000000000000000000000000000000000000000000, -6.574163274461459316455602674977853894233703613281250000000000, -4.134373386461300370342542009893804788589477539062500000000000, -1.093543453498669215662175702163949608802795410156250000000000, -1.475402531411262208038692733680363744497299194335937500000000, -1.310160794679168905219057705835439264774322509765625000000000, -1.903132912453214142800561603507958352565765380859375000000000, 0.000000000000000000000000000000000000000000000000000000000000, -6.698361853186871606169461301760748028755187988281250000000000, -3.512501991875810691823289744206704199314117431640625000000000, -1.959662302151332857746979243529494851827621459960937500000000, -1.528776846501670894085123109107371419668197631835937500000000, -1.826181650981897996999236966075841337442398071289062500000000, -1.138653619844293141127877788676414638757705688476562500000000, -2.040520733384556528733355662552639842033386230468750000000000, -0.026334973760810023724054929061821894720196723937988281250000, -3.649996012338110329409346377360634505748748779296875000000000, -6.431737076661124596910212858347222208976745605468750000000000, -2.943735378782415867959798561059869825839996337890625000000000, -1.682170819948636486529380817955825477838516235351562500000000, -1.298939117547105670524842935265041887760162353515625000000000, -1.993700029844323484695678416755981743335723876953125000000000, -1.047709386165366352017258577689062803983688354492187500000000, -9.026919483738925720217594061978161334991455078125000000000000, -0.000120139208737295727770326425609681564310449175536632537842, -6.717239913861373423742406885139644145965576171875000000000000, -1.328070071947949681856471215724013745784759521484375000000000, -1.944037101159571623298916165367700159549713134765625000000000, -1.182903563582415440436079734354279935359954833984375000000000, -1.257763426233626136152565777592826634645462036132812500000000, -0.983486006261584555510069094452774152159690856933593750000000, -0.468412958710625382252601411892101168632507324218750000000000, -8.468651996251450597696930344682186841964721679687500000000000, -4.139800124064825226355424092616885900497436523437500000000000, -3.931454793849565199082007893593981862068176269531250000000000, -2.021497077106750417385683249449357390403747558593750000000000, -1.823127657291570224984411652258131653070449829101562500000000, -1.337296127555923419549799291417002677917480468750000000000000, -0.897180799465370992784585268964292481541633605957031250000000, -0.986040730030275258677363581227837130427360534667968750000000, -0.466889729967265909582607719130464829504489898681640625000000, -9.011593207854545539703394751995801925659179687500000000000000, -4.850867560763419739089385984698310494422912597656250000000000, -1.112896046865470500719652591214980930089950561523437500000000, -1.085333923798379451852724741911515593528747558593750000000000, -1.377898281389317913792069703049492090940475463867187500000000, -2.609739901377524873282709449995309114456176757812500000000000, 0.000000000000000000000000000000000000000000000000000000000000, -6.495767620713909451524159521795809268951416015625000000000000, -2.305511012885385291326656442834064364433288574218750000000000, -1.779624881481258524829058842442464083433151245117187500000000, -1.465377313319132568381064629647880792617797851562500000000000, -2.026515779816368212351562760886736214160919189453125000000000, -1.208685317218918919834891312348190695047378540039062500000000, -2.677909755533927516069070406956598162651062011718750000000000, -1.220088311290825400234894004825036972761154174804687500000000, -0.349847015838577246604756965098204091191291809082031250000000, -4.261980401619341662922124669421464204788208007812500000000000, -1.422943413816338820154783206817228347063064575195312500000000, -1.509540111140063478600836788245942443609237670898437500000000, -0.646472693195343506289418655796907842159271240234375000000000, 0.000000000000000000000000000000000000000000000000000000000000, -9.815478075212435982166425674222409725189208984375000000000000, -4.933023088148108747930109529988840222358703613281250000000000, -0.007285766694735069763655399555091207730583846569061279296875, 0.000000000000000000000000000000000000000000000000000000000000, 0.000000000000000000000000000000000000000000000000000000000000, }; #ifdef __cplusplus } #endif } // namespace IsoSpec isospec-1.9.1/IsoSpecR/DESCRIPTION0000644000175000017500000000177213373520171016323 0ustar rusconirusconiEncoding: UTF-8 Package: IsoSpecR Type: Package Title: The IsoSpec Algorithm Version: 1.9.1 Date: 2018-11-14 Author: Mateusz Krzysztof Lacki and Michal Startek Maintainer: Matteo Lacki Description: IsoSpec is a fine structure calculator used for obtaining the most probable masses of a chemical compound given the frequencies of the composing isotopes and their masses. It finds the smallest set of isotopologues with a given probability. The probability is assumed to be that of the product of multinomial distributions, each corresponding to one particular element and parametrized by the frequencies of finding these elements in nature. These numbers are supplied by IUPAC - the International Union of Pure and Applied Chemistry. License: BSD_2_clause + file LICENCE URL: http://matteolacki.github.io/IsoSpec/ Depends: R (>= 3.0.0) Imports: Rcpp (>= 0.12.0) LazyData: no LinkingTo: Rcpp NeedsCompilation: yes SystemRequirements: C++11 RoxygenNote: 5.0.1 isospec-1.9.1/IsoSpecR/NAMESPACE0000644000175000017500000000020613373520171016023 0ustar rusconirusconi# Generated by roxygen2: do not edit by hand export(IsoSpecify) importFrom(Rcpp,sourceCpp) useDynLib(IsoSpecR, .registration = TRUE) isospec-1.9.1/IsoSpecR/data/0000755000175000017500000000000013373520171015517 5ustar rusconirusconiisospec-1.9.1/IsoSpecR/data/isotopicData.rda0000644000175000017500000003071013373520171020633 0ustar rusconirusconiBZh91AY&SY4U/ (}_P( RzS!zh7mv|}tZTC筻[e tWEwU^(Ibݵd톻4]vhI4 AL=25Dɀ4 '$ Oښd1=?AiSi& hfѓ&L&bi҈&`11LCF&LLhFL5Si0#&D)22hi @ҟOѠ4hT44Q&M!1OJyF5O52z=&y?I HmǝIjy@mG&lMGB; kJzHoXPuS 5 [hΡďWYONHm399Q_rVEGCkSۣ O9)25Q 0p,@6|!U,!!4hj JfB$i, ͷٗ3 dž$=Srd%<4u(N3z)/LaX\ץCަ e.ZX!E`w.'vb"v,ZE9IY`qȤ0bɐ5s \WWWL`ԋ𤈭JԪ*RdMMN `ڑ9$B&a\DI3Ui(CU*P&CNB±1bѴFF H eUUe dK˅X+\+*]B]^N {UUUb P*`k0g*V5RCUSTi"fY,uujUR"4ZX*v$]NXR.^dLȹfbP!++\/Ed Y`/B.jzTHjݎo478AF @ L4WT" E|1Pto,PS1p"8 5>;cP" "/à;XLD uDEPEC"i({,uEt_j5,Ry k0Z*^*‡WyA-44]vx縰! Ɂv< KI|W!96lyA.\=o;{lz'^PsQEKn%SeQz)AQ*!]W=M H}_ypB-1߶a\;)+S`t2HV(2~_:a<"`R̆JfPvA!eMCv3o9vh_.M;y9/6۾I&\ ݋m*U /\:6V؈&+^&YAcyc'D*,̔t"K7Td2E8f yG-j&kUec Fe vH#4Z\H6fzR0Oàv #/7 coc;CJsb8&H| t|шㅘ|q@V<95Xuvg:x!Hw\::)4Ck&>^=e`J!FT;56PG鸊%2S@$m̚%0:SnyJoBm^t(v{oq/.ZVDA;|ұև\Udp~ ]밮oOm&)Ơ ktt8}I-30AS74:R<¶mͳF \`;PwE^V>&N8,N]̫+:aj2F4ck >zk+|N6|oAp txX'ӉNeh[%al.;cu>?I/LQ4:ȋ4_{Dh08e|Dh"}(.7JkQ')72(h{ 0"v8>ma>5Ekܱjʀ2C1}ovk:ҬsXS|,Iid\pb?#b.+<+qJZ%qv!/^'}ߡd?..K$I-2?`.&Rfp13yU&}刚p(R@30Yin:sgN_2)ބ8r[oxz G?S7-&pT9 8*p2Y1 ͅTQ^;\8wals pD{@m1*aJųLQ޹b7v9lຣEovq>_rDͻR+9L ;J^~p=[;Q )~5"n>VjIagYFKI34 @-%5HF4G"kχTSDz*XWV,8RF ]EԔ0U44b` D!$c0cm?Caqx''}GIek(D:їqdO=A Q8Eur <3*,.c鴹ֲ^_A|`ņ BHBHB,`>+4T̖e! F+1a3Y NiHF `<]k:66&bǢ d&Dkduf4Nbcbk&;EqcADQht F٢Bbņ4󨁎jtE^Gߙ!}.=/;=W>uUES*QTzJˋ˨TX$(+2H)&&*,Ws͘ڱ4b]y3M}ۏL7 ʻ-IJɑieE"U[AxWYS,xxh4ccOBQjaF1`$$'nH H{+K0L|P#x,eW L#" *kwt˒N#2aT7 A51`z4 Ǭ*r(`1_FLTc+8}|2|s)\K! P$(!ZmUYM.&)#fФ!(ь> 4i$x{7sN~^qF T|9N*d)Fa8ҜaJ4Ў _?ud{LYdTy?\70n.o %jw) Hcf ighaodE0"" "7L&c6xꪗ9vy5\qNէ,XG/~NbߧbGw;7[8X^=#-xC"FC(d X$"ޛ_&r'ge[R,,pVQ]:ߗx٧ '&aP4[67l=lҭ|}{mosOklw3n7kkҪܷ 5m2o]Yqi+݅7IڧaSUψ{ovP7q׵)[YԌm̽,EϖKP^łlTv]IQ<\~Ό!ƍüWb7ŚHbw {ﹳ+iz H18|ӌ=S4.R'ͅ\O)^_~-: '`nJ*`cS8cȬ+ѷ }SĪN@( A)L"MleyGrx xGkc<I>nvǒYnR.݊ tXɟDi@VI8[=3|"ݕ#Gm_z{.Pux\|,?=.oB"2PRJ;">VOOr|SQB8: $J Zډ'n ϲ@7'N^Mv't &élo1Rz]uLn0"ZխW*f,B&,C4:Ҝ܊0OFitn s $ȑ]uO:Sʺ>Ò qWԚ~8O1]w|qc!DRsb/PІ5V+,"qz$ؙ%k` Uuޏz@`B0!f|D3ҁU/I9{'Ȅ7SxL&'=Fx91!Kptߵ\׸\xi zȁ:"|?aFT372e, A-q `"Vj"#ķ/fHY~7SC1 싲YjR|Igi1I ٺ@~~~af$PN?ȿ91)Arm.DPg<֞xiu)-I2{![wŲll4K j%sl0H&fb'd'!wf/ Aso׮-; .o5810T&|m-slnlG\gcj^Pyca٢(<雎>6<$H6*t0_A7;20|ޤD9.Ah<ա[!g y`@rn_bs T9^KTD(E[((i~Hwher8dD#m{8=|"hR%1ENGɌ||EU 8.%nZ_`#eCCV4=4p|@>D?DtiQ\6KA`IԚEM66D#:5~>Q#"#}x.-e̒-4|*4P"1+To-W|[T ^>J  />Wo.VUExzE :PNW#:Pk4!-%9c P!DD? d=&8լG77륶wkXldatzZ͆A ]<skϋ6cxuܫI au4~;-6䆔R&a,l0Rx~n|%{3h;OIvOz"-@*b $rYM,clM+V~^է|E~eӕ^9FT @?)%0#}>>(s=p?ȚOwPë1dyy)y,ah8K/IzJ9’Jځ8qg"0T{w2nO)H6ĭR=c !mV6ÊKٍ]\A ,b1z+#kG Q3-gw8΄9j4zK%A6΂@;S]+d f#)^M_>+=#4ޙ'%Y*1ΟbYM;u \t|"E/ *wKPa5u*q[]ͤVdhxIEP`tdр'/JT}![Aв$m7:ma낮?sXtD뽪oO$J#yi*Н筊"~$}O;č.6珱-1ʎa5iM! eGHp3 0j< z>\([E<0pBڪ7ghgV+)tҼUA(7;H@pR0y.a=M-cϒ8j_C4__Ÿ4P>S[p.{|茉XDKo(S@. ũ=wk\?Lfmr(QDL/@}3({xWR\~~:VI IjBIg"LJ?Bʦ:-7HDQ%԰E^g [BIԦҸjNNk>ipv$ d5 I 7fUܞ4lo~("Neu2YKl%XչP Bb69)A (5cr6t[E#Kڌ edW5$3` `sq<l:Q%l5Y*R:~F At$=f[3îPcVf{>?OozN]DYA@X S̪%2o* 'fES<Ǐ`̰ clr!p3D#0٘d40T9y,K˲!҄\6zȀ$ mbG۸B) i:=N1X\1t1tEgZ_"awifi s9YX`' ɞ{}vk=r9./?w3Uoil1"mZޟ}\S“5 #۝lSYCO2AX,ZR&؋kW{rǜanU=j!+. VNP_Ėҋx(g&јZ6k+e|hTA2&Vp[ysX;RN8'I 9꯰n#h2dkc>7^EТbFgϧ K8+I+ sv=dX Iue/AGȾb䠼`rGRl, PUDsq4G`$@W(FB-ۂ Q1v T|w 9W#B;xV>t^v'!kJnh aUYEv_eCIe5h\AmڟΎǂ@8oiL*M1ӛs @\FRټq.e- 肇x^^~WLB!0Ҝx7DA㜘lW=M?~wƌ8L4᧱2 V&-f`oneP$\6hkR*6bjtJ..p0|/g|C\wnl.q!ɕ$?&!8#|٫%NA0)"ߌ4$^ZEQ6xJ>;1PIh.GhR6:0hniuP Sf?PRk$j|.$c4݆3h`~4gïs( Yك39Nu: ]qYng^s۰ivJ}dLVI6&73+-HKE0_x#^r&i{{‰z]B@/Tisospec-1.9.1/IsoSpecR/man/0000755000175000017500000000000013373520171015361 5ustar rusconirusconiisospec-1.9.1/IsoSpecR/man/IsoSpecify.Rd0000644000175000017500000000541713373520171017734 0ustar rusconirusconi% Generated by roxygen2: do not edit by hand % Please edit documentation in R/IsoSpecR.R \name{IsoSpecify} \alias{IsoSpecify} \title{Calculate the isotopic fine structure peaks.} \usage{ IsoSpecify(molecule, stopCondition, isotopes = NULL, showCounts = FALSE, trim = TRUE, algo = 0, step = 0.25, tabSize = 1000) } \arguments{ \item{molecule}{A named integer vector, e.g. \code{c(C=2,H=6,O=1)}, containing the chemical formula of the substance of interest.} \item{stopCondition}{A numeric value between 0 and 1.} \item{isotopes}{A named list of isotopic information required for IsoSpec. The names must be valid element symbols, see \code{isotopicData} for examples. Each enlisted object should be a \code{data.frame} containing columns \code{element} (specifying the symbol of the element), \code{mass} (specifying the mass of the isotope), \code{abundance} (specyfying the assumed frequency of finding that isotope).} \item{showCounts}{Logical. If \code{TRUE}, then we output matrix contains additionally counts of isotopes for each isotopologue.} \item{trim}{Logical. If \code{FALSE}, then we output matrix contains additionally isotopologues that otherwise would get trimmed in order to find the smalles possible p-set. Therefore, switching to \code{FALSE} results in a slightly larger set then the optimal p-set.} \item{algo}{An integer: 0 - use standard IsoSpec algoritm, where \code{stopCondition} specifies the probability of the optimal p-set, 1 - use a version of algorithm that uses priority queue. Slower than 0, but does not require sorting. 2 - use a threshold version of the algorithm, where \code{stopCondition} specifies the height of the pruned peaks. 3 - for the threshold version of IsoSpec with \code{stopCondition} being the percentage of the highest peak below which isotopologues get pruned.} \item{step}{The percent of the the percentile of isotopologues in the current isolayer, specyfying the cutoff for the next isolayer. It has been optimised and better not change the default value.} \item{tabSize}{A technical parameter: the initial size of the \code{C++} dynamic table containing the results. Better not change the default value.} } \value{ A numeric matrix containing the masses, the logarithms of probability, and, optionally, counts of isotopologues. Attention: this matrix does not have to be sorted. Sorting it would also compromise the linear complexity of our algorithm. } \description{ \code{IsoSpecify} is a wrapper around \code{Rinterface} that calls the C++ implementation of the IsoSpec algorithm. Given a molecular formula, it will calculate the smallest set of infinitely resolved peaks (isotopologues) that jointly is \code{p} probable, where \code{p} is provided by the user. } \examples{ res <- IsoSpecify( molecule = c(C=10,H=22,O=1), stopCondition = .9999 ) print(res) } isospec-1.9.1/IsoSpecR/man/isotopicData.Rd0000644000175000017500000000205313373520171020273 0ustar rusconirusconi% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data_description.R \docType{data} \name{isotopicData} \alias{isotopicData} \title{Data on isotope masses, abundances and other.} \format{A list of 6 tbl_df's or data frames, each constaining: \describe{ \item{element}{The symbol of an element from Mendeleev's periodic table.} \item{isotope}{String composed of the nucleon number and the symbol of element.} \item{mass}{Isotope's Mass in Daltons.} \item{abundance}{The abundance of the isotopes. In case of enviPat data abundances do not sum to one. In case of all other, they do.} \item{ratioC}{As in enviPat reference manual: "Maximum number of atoms of an element for one C-atom in a molecule, based on 99.99 \% of case molecules".} }} \source{ R Package enviPat and Commission on Isotopic Abundances and Atomic Weights, CIAAW, \url{http://www.ciaaw.org/index.htm}. } \usage{ isotopicData } \description{ A list of data frames or table data frames (dplyr like), containing different information on isotopes. } \keyword{datasets} isospec-1.9.1/IsoSpecR/LICENCE0000644000175000017500000000010413373520171015566 0ustar rusconirusconiYEAR: 2015-2018 COPYRIGHT HOLDER: Michał Startek, Mateusz Łącki isospec-1.9.1/CHANGELOG0000644000175000017500000000615013373520171014333 0ustar rusconirusconiThis file lists *major* changes between releases, for a full list see git log. 1.9.1 ---------------------------------- - R bindings brought up to speed - Improvements for 1.0.X backward compatibility in Python module - Minor fixes and cleanups 1.9.0 ---------------------------------- - We no longer override $CXX to use clang when available - the difference in speed of produced code is no longer large enough to justify it - Some more minor code cleanups - Python wrapper now returns probabilities of configurations instead of logprobabilities by default. This is controllable through (optional) parameter. - Expose LayeredTabulator in Python ---------------------------------- 1.9.0beta2 - API change: rename eprob() functions to prob() - Added more tests - Some bugfixes ---------------------------------- 1.9.0beta1 - Added more tests - Code cleanups - Some bugfixes ---------------------------------- 1.9.0alpha3 - Brought C++/Python examples up to the new API - Small change of Python API - Speed improvements in IsoThresholdGenerator - Code cleanup, ripped out much of experimental stuff which will be postponed until 2.0 ---------------------------------- 1.9.0alpha2 - Rudimentary module for backward-compatibility with IsoSpecPy 1.0.X API - Bugfix (and usability improvement) for getting configurations in IsoThreshold ---------------------------------- 1.9.0alpha1 - Almost complete rewrite of the entire codebase - Improvements in the core algorithms, resulting in 10x-1000x speed increase as well as lower memory consumption - Reworked API to be more sensible - Laying the groundwork for multithreaded operation (not complete yet) - Expose generators in Python (enabling processing configurations on the fly, as they are produced without the need to compute and store all of them first (using up memory) and process them later) - More modular Python part - C/C++ and Python-only release, R will follow soon after - Some features from 1.0.5 are not yet (re-)implemented: IsoLayered is only exposed as a generator, not yet as a fixed table; as a consequence quicktrim to get the optimal p-set is still missing - THIS IS AN ALPHA RELEASE: IT'S NOT YET EXHAUSTIVELY TESTED AND MAY CRASH OR PRODUCE WRONG RESULTS - API is still not yet finalized. ---------------------------------- 1.0.7 (Python-only release) - Bugfix in Python's getConfs() ---------------------------------- 1.0.6 (Python-only release) - Compatibility fixes for Python3.6 ---------------------------------- 1.0.5 (Python-only release) - Only affecting IsoSpecPy: Speed improvements in IsoFromFormula ---------------------------------- 1.0.4 - ??? FIXME ---------------------------------- 1.0.3 - Only affecting IsoSpecR: improve the efficiency of R to C++ interface - Add an option to skip discarding the superfluous configurations ---------------------------------- 1.0.2 - Some further Python+Windows compatibility improvements ---------------------------------- 1.0.1 - Only affecting IsoSpecPy: provide prebuilt library - Only affecting IsoSpecPy: Improve Python/cygwin functionality ---------------------------------- 1.0.0 - Initial release isospec-1.9.1/man/0000755000175000017500000000000013420361504013666 5ustar rusconirusconiisospec-1.9.1/man/logo.png0000644000175000017500000055565713373520171015367 0ustar rusconirusconiPNG  IHDR7~0|iCCPICC Profile(c``*I,(aa``+) rwRR` ` \\À|/JyӦ|6rV%:wJjq2#R d:E%@ [>dd! vV dKIa[)@.ERבI90;@œ r0x00(030X228V:Teg(8C6U9?$HG3/YOGg?Mg;_`܃K})<~km gB_fla810$@$wikiTXtXML:com.adobe.xmp 1308 1079 vp@IDATx|SRRVt :t0C6ېc gwN)(Pc%'K=}#99bj0x#hFGPb"8ЌD         p8=         85C@@@@@@@@@p{@@@@@@@@@@3p8jfp %&JL         #         Q3@@@@@@@@@G@@@@@@@@@4#f(1xhFGPb"8ЌD         p8=         85C@@@@@@@@@p{@@@@@@@@@@3p8jfp %&l&L  v [z$^D)O<;)A@@@@@"V$14Wn=8Ly< 0 }G9aJ41LR%lQ(L#F(#@@@@@@b⌅&#pj!fϥΈ;Q̎I1m{=Al;!+L5%Q6ω @@@a +g/'ㄹ+'&"qp&T Wf@@@tN (5)H­(W}O6S1v8≊SiL@e(v{RY qŸdK/F:,ѱ$NY4d\A p0oU-SP.@ <'[ESiuwD7y$J cєZb -1Y\8&8D GBLFfqi@N:7Yt%eL̙xW'7=@LQOe.Է]"-z#?`)]ɖ4REЃwaa*V8R4 ?   s^"S ~E4#fiJFDTH<u$WQTyV"EPҤI?>5kF7nPn݊2/A@= mw5okjUq[ؗRy+.&9{)gj>   ??ш?ᰙRJQ >>fq{> pWp8u} ֔bR%kw;THZYQ#~{togq   %z.s.:m/SJ1> |<ѸqhҥcEM.\PAAAۏc@ܑ@lwҥNN_׫DmTћwiTPNUz  `@d1rT3J*OR'IS3w-'o|N[ :t޽ `6q$ӝ*/?4A@@܆_ԔzA12:)VĠWP4m`{߲u =~6m[hUIpep8`oȸn;ou \jB ݣkW*&>Rɲp]ev5;𩋖L%Gϡ?QB&F0MMe(uvw&2=A]>cuG2鄇Ӟ={Sͫ :rrDk\GA@ K_@O6/w=z*k%`n ҍz5tyш-b|29{~ס:nFxq?UjFc@@@ܛ@d}$ ܔD͛Dq(O|ax`:s };J:r4qDʙ3'h0  VPѭ.gm&0-WPQ'TF)Sfygus?'hldsdIG;(R$~ L R/2@@@ x}ޔ6mZFFFd48y^~:V3;)0Q8I  MkwTOԳ͗th$Qj]kZ7BΦzUK^ g&:v 5QիVSܸqV]1pGp8U=cGjU0@ ǡT5ڈ~B%//NꟈOHTb][֢}tҚ>+ІTzu| w#]QO8o޾ B*hO)t5Uɖ4Qh`n<3cdݶY'L@+gIC;P8;@@@@״m6 …Lgu9cY DGw ؑ:}ݪVm]82|BVFiLS,_6:~*թ\\1%qF ZjQر|Xց;ѝ& v"K4t3IN[~EIQZ ++RIab}   9BCCJٳ[8nլúpp8˕>@@_@7[o|o٘:E:)7+V[QƩZjV/cYu!  .pt+};s&O]QFS;]L    O׮]Sٲe)YdVcYuy8*b  `G]Io߽zyQ5    ޿OV"yv?pd]炀կ ;x5ڲ_ 1ϋ*h    """NM`UuX7\'bQʖ1 'NHʛ7/efQ).s\<'@\|`;ؙ;UЬNyU1@@@\@ȣe ܤ.f,جkhtg~% 7\f9xg/#H* XpitA%p/^<.i<' W%^9  v&z:R*ӦT5A@@@ ]޼yCe˔%s\<' W%^9  v&p#U+$MGQ    N:EΝ *P$m9yn^ HGWj@@}uTɴa &;ڴiRR1sܼW# z< GOG=zO+v,J"R'49Ō>3*+zJ!a#DpMߛ$Ds2[Ny+J݇o4,&?? ǡ+?u~'d(a5H4r_yh{MX J엀'"f}/2+K,)iq~)- HP['ޣ2 `%۷Çy~J-uԡ~x+Z  p8"ߴ)y>u"߼HvK@* Pby7Ͽrӿ1i9|?V~T{"ׇE]ʥ {s*sNtJDiҤܹs:I}ൊ+N>=@p@_~RA`ѨTmCgVq`_t4)ilHzUK c)*Uȳ+m !f D$i|cr(w48gvtMU&mY0*̧J^u682Y ?';iƢ4gF%"Zf:{L\Yv AN]!5?^Dgjof|V <0%бǨsΔ.]:t :u*ϗj]  %8J8VJtHSu>Ξ,߰\NPsdHM#zKQ1eFIU3Oi]nj{"9+hp8bR ^_[m`>y49Q`NkSv <"u8o-CErȞ-D2й ^AsdSCMka5ak ܻw&L@EzYfӸ+V{2%Y62&aa!Аv[YG6cc5*S毡:?ڣԫмʍ{"2/;]#fN_E^-!_ǿvVN])fڝS5jdu4jZ?4vM;O~NM_IM cra;@QƮɜaJ_%}?e1 '#VlKkv&M8"ߋY+Uҧix=?TqZ|/: p><"sf͔8qb*VD&6-;8~`Z_JLf@ܱx"~#;v<t: Xk[,Οq~G׫p*-i7\nP;[lwnͨFVlQ]rdm̊*FͦӖF="_G9w*Nwټ(ёv}8q8J2n, +nJ99쩷H4i?h =Ku6Q~T Wf\I(E$[8 !"8҉%h Fm¼#K:RyNU qc!{̒re5<2Pl)܇Vss$v ܣ?qBZi/}a*sء޲^EX"O\yPIXhB\r4%dp9cu+Naw=n:5d^-{3&ݤT.FӧV]Dɂ9ֽ`~qhM'[Z3{N8R}Ӻ-w5je *TQf?{o4Yj Zs/Q1!la]x.Ĭ[N8A]:wT'>|3ydwҔS(o޼TSD*H.:C8+WV|LOD'8G9co}}5 EcC+ޑ=JaOE4#١4B:/"eeD4Wvӻ-ES./!#qWX^_$թTLIj~ZVtT Eu8'Qx9Ѵk qD$(je J9EXnX4o:nCMԥ1}Z2[۷+u354ʝ۷siNE?|NI6 CGQWu8r_vW<%/}19IV7;+;-kIiENEj?.N;RR43]v>SIdY38,;L3G5Kkp_nGQ 7>o\O-'@s zmۦGǏOKqUpႢ3f(=WPP=\[B7\P{^d1 ñVCv4kRjs/_KuOg.oܐE-\:ˑt?䩨{9zmNЩ1n[O|0Ӷ6vt)CFr+'JEȬgηlg#Rd$ wS_DT$9hB_*U8V+4GU12y(cvDڶŹ BO8@ܚzB ~KeL)V=j' ÇǩdɒN隭f<p8z5wqSYkqj^?Z&5S^@8q$D-JxufU/[Hj [8*D-1ieE%FF:wD]4q5s>d G.ҲpVcI 4G¹pݿJd-\C{D]AV9mt 3Mll?G2TivF[HWv<(s)*"^q@ׯ_رc^z骴[)ƍ#۷oOD @Q/Ws8r\U;(8_s'{7Zo}j;puUzaloFxP\QêLGEG3}Ө]tIH%QwT& v1PŤ;N No: 䨷}+Ƌ s?1U}ΰPZeiľ?|nj"Pp#eSTnaр7))ߖ"/ F-ѰNg:utۃMb  V^D7~7Jgh=R9<͝;Wr]MM Lq߾=2L`h*]^VlCDJL1r/ZjV<ዶC}5"MϑF;"ڱx,-8g$"9eֲFl4aP;k~ ;M]4jgQ q7V݇~Z6o]l+wv_9s0œhxN/lR۠Բ^% NuW$+qeSN.ՎkRby~D> _[_zԲ*74$U(!v[MIfsSCTu~fCG #z6MĦ}I5]-A%`&]\9J,a6m6lٳgv@)AtFG]f-٠jcLVe[&Z[jkqʜ^k5x C?Ԫ}S4D{#Z-k4ݻZ5MC.x?|HG Pƌlw-^}il+G9  $ۙcmwrg\* S^i_i5{t7kgiXE*z3iT*˾82@#&8rx 3?uFQEמU1tb4?:DjӌEUN1﵁gnsEp]et YFq2VRE107o(юz.wD7 [ 6NttCcƝ{< GJ˗G9X s*D; эN}G+ Xs xNj+d'gi1aX(g)>:/G =znFCADɔzۏ%{di.2zM`Gdaҟђ5;ژWn#NM2az>)˩Z#ekv*V'Oŗu.z(Խu]DjS؏)""2eDҙw#ҜDc,Yʕ+J H[җYSY:p/w1gF2l:QòK7S^V]S:u8}FFBB?DtdftrM psȓX8lJMCԾT AG޽{t1*Rڍ-ao);bmssҤIZxn(xoooeo>*)S46@@.e˖0)@.ζ0;{f.@US| jˁ4rڱ$q#AkԒ]A"R ybEja7Vj#RfO%eС3ҺZ+*S)5/(Cb&.9ezj%i?*/Z5ϵue\[7@܇UJ*Y)C#ne3pĥڍ=rmI3@IGGZK] D a7GW]_;+am47BbJ(r+J~An)}+kKj!Mrd>5eĖu,I52"5 +~PzKmJ nGȑ#tUZҝ eܤřw)4{=!  (p8:4x߉zVJ=)[4ŚӸ+nT!P.N\|8^:Q2TT98}E8^7\ě-9jU,W뵈.ݲze*5!@@@#ܐe͔$I*ZT8+њF10^yϼwCSScq@"Z< `=,ЇDEOWPsi4DԢZ@*[uF8>{ gGק]}HKr;=H@z0ä )jEpwo)[@mOҵҎc)HR^Bi* lٲEiҲEKNy5k[JuzN4|bիWzA@.p VL  p X6w5}޸v649cxqhPRx2Eٍ0j`X8QR$7}>l'e u,)#O]$[+#eF s:k "9\  p{R)g.ucsY4[ y̠D   R(?Qo14qp;J j;,JK5EwhbK7anrfՃ-)Ϟ;x9ʆ XF:OZZ?vЃ'~(۹xŖms?W1# ʕ+tjժ}:(# i G9:JJbL{j41EA$41XI#ܺCΦ>֧$ȑӗE7k)H--\Ud#x ⻖ڕWlJ"@܁Y$SϹApMF :8}^+ nܸAgϞ%KRʔ)m(;߽G&.6OhfndRO{ggΜ!f{ўt17X Z87n_wl^<HlAOJ\V9szUgiSWb&@SՊ^4N,bL+p3:ʍ.]+$%*)(<*jvn ~r6GTjp3f(GM @ 8)pxq, {M3ױݩ}@-jM+d[uҦd/>@m4Kt?z&$#Sht=EY'՛ۀtn0}'*G{` {۷o+R|el&.ܼ- i 3a6H(>ϜѪAe+ty:tx\ YgUVUfާ/d#CcP~xA:$ӧn|'$=M rlaG9W^֭[)iҤTpa14aV#I0 M(nܸZ/@@{*8xϕarbg~nrxNj^,Ua`]=ѓ0U 3cn?`.m`$a %2SkdrYs;{3H_{?`C / Fi%h`NFCXF1ݨ#mڵkӜ9sթSǰ%OQhD2]ZJ nHG7ؒgHGV_@v<'B/%;l= s8ʖyȦʝņU=C5X@"#9D[drGY~)N|tHtAʝ;7e͚Uz ikQ|-|o9ىh9krsэ'Ni$3a6̨Xb}zʞ=2D9rs//^'OСC}NiN82FsbΝ;Gׯ_'___*^tfJLJ;8e3fh0]c6tuJKatz"YKJ9K|})UJkU `Kѥ/bSɏ? {H{iNц/t\CV?s3BoąrS [Q3E":7ns\+'b47͒F3֑ՓuwMdH-AZG+ߛaA@@n޸δxIQldyQ#DTpPj#<צ<Wumc봌0f:9@Tz }+Qio11y ș&茀默 9 K*ȧKA8ZDC@@awEJ,J&L(m;RJ83d`vK dRLIW(\t#-.]?/@IDAT?ݽwnݺE˔605fo/Z+CߣS3ď=Jǧ;Sf1w&ӝ7X&-3Z8-ԗ8=TFdB~ute>D{rͪ'͜PT)} ~zEmIMvuw9&jyY 7ݻw+θiR"U9ТӥC*T ϜX$~TT) ;ySQmbx]YuLfFbmD淥eRR~Aۛ>0A\ Є@/nM l"[+TiZ-sHr JQzp8y3k۷+Qsf8ʑӡqV э'S  uы/N:6Ebh c*ܼэD,9^1;fh^BhzTp|c*Mߒ)_Qw}:rw)3?΂7pt݁*Xt=Uz'Q50"v8E25Ίڍ%x6M`&UJygS@?g&(F= aӺlHI WMq*EFz>0n )7N^^K2f-dċESut:#._6䛆U[tU%5ӗMLR[:|@@@7oiӦMG%JFs=n¥E9-Rpd̐Y2Sf] }SK3e&PZ@ W{v(ǡ}/4v]Wv$)R ׌T+^G)1*rGh.YS|SO_F'w9R[T,Hz҈)UoׇkZϘ׀L EkcSzԱ2E< .6  );ӣGN:'NMe2v r2ptVS{c̒2[cR,S7P9'~rBZ0M>TW_8 ptk+񅕻iEE $>wy*3IN+]8 )WibK҄dYp~HW359e8Լ?nj%O jAtJgDҦ>SskƢ э`ٴ݇DJ? _DZɔ.nB\NվD[-:MNIdNH4|]ΩfѸ~!Rb9yȩKT6URu]zdd:k^=_*4Okt?VPsr]TW˥.VnGuso+@O`5WTNmcr&,Ƣ(ƈ!flqT={6G9?XE-!:*+O'M :ME~GMkԩ1~d[Wgks){Yi3Onz*S6"-H>'Rick4t9( sA<ɓ&fUW)5+Udj.6y,̖k:2kAуhđ0Gw stp,; F9Vq vM~ Reэzgxy Fk⨚N޼G]P={рg֨L)9K7*='TŔ:5uI2H)0'* YFߩQz,G wiYQj-un[_uizHi|9U+5RW|^d :@ի \@ߛiQtYx"SH}oy-jۜ7?6Çӵkרjժkds("~ ;fˌ5khܹTfM\?k@@puU.@r 7V8uYX;a_@Y|E5MX2e G!mMO&kGՍIb_ߛiyv$DsWEUm07)ݸ7눔iD7RMVHR1Y@"N㪞OQKMž>NQ1S)u 'lU6FMOPhj>G'>[?,M Q!1",* .T%JD/X[ԩ)QgN ~#|'Gꕫ#188nܸAކM1""xәeΝ;Շ.]Dɓ'Jaљ+V4 EGϺح_!G¨ε}qLuZr4~з]j ̗oX"u᫷Sgܱݣv!u*=Zhn7ɒ z ٣F8rQ,ЇW/Fթc_CG*8dݶh4J0^ pA5u$SuT"=7_Ҵ֪nN;Nkkw\ZeS:y[c^VzUJE%.eҗߵz Vn`~ߓY) '8= ͎QA>RϞө6&.}$Oˑ(ܵkצԩRuk !J"xR z!}JD ?.^H &tMf]ddr?; G8޽{>}4=J8 +eȐAMv)S*v=y)7ٵ R/?tU[ ,j=- XÉӼ; L嵹Mo1_E=~Y/UR$OVZ<Z%O[kQ@^e$)L8ԒkJc,rz'| sPQG|) a*.1V"Ef6# έfpM>tcM6(++?}+S(u GEN:F'L)s#)_Kr%a#9!yhDMJ>"VO^49P/wNΐ'OEjy? :|FD.-kփ@TޔdQ:?b!Nц% /_P8rz8I[&@b4ӑ_NgϞR%KQ4if1Oã.En˜mJf1)c}275b)e̞_ X"%B8VVRъnd%e?'xXN7tT*~>4}DgU:jsG;$JpVj>yXNY!T)&捰kÌ+"m=%2o~Շ^Hw&"?܎,mwψlGT^tG*-gi&M[!vCёexN2uѲQRhPL-g8Wo=ՎnSF4:reN_փ f& DT{{ZWnomPFCܢ'Q2đu\|ʩx)/_~S}^fg#7Fv6# ӳ~Z"!5@lQ?8S+QQnjםspqwxV#(s`׵K&9S)1k;ޡfkc9kq9N`вqny(b籌>|TH>Ly~˶NJ*L. k$|pt=k%5V3ɬM8K6E n;z>&rZphTx^SUi%I[tM˵mTU Nr) J}Ԧ؇ڄ:{te7m޽{ԬQ| })<<\׎;v*ƌ_l;ӳÑmR___If׀_#9:8* p="%2qYgQt@ajGA|_4//Dva?R2R8UlK76@'˟]qFȤzh-ExQ"QA^#p4@Ef։%R MOub}'(_JYn(F F03q jԛ_DaIyq ui6]X"/m%TҚ֞Լ:.QvWZU:g/ޠr"wc^t޺._@@_6mZ嗂Ҋz)EIWm6J,,T_pg///zvg91Eb7GF|-𵁀)  xyŦ3Q,,56`]jZ'bl>>$GQ4DH~A:Q0w+*Y0m={:R  ekpvjߏknFg7%); m_xUn9J7EbkZN?{M\H+}KDD#!Y2=)؉⎢UͼR9\Y) GCL]SNi[:%Hdjp:|iXڝJZ--\ݬ N֪P.jmˡ2Ǔ nK'F<[3Gl3jFnݷFŪ1\^(oitҥ m@6lؠD1rjcf&/^77ћpsd415q^3ݳ(A9kׂ#K@@@⋸ZpJ`ѨTγ3+U f'_VU7dVlܨfQt:ׯ_GRH[ qgy|{YPN!>? :"rf"nHeS¹aîhƽj>]lgnv[D56Qp :!(8֙QZNjnvQ_( ;41Ur4r+G)mp|"D3Ь-My13~Wk(с8p&~&! Oxr=B<3~!msh\^ h2吏5q-EvC'/*pꢹHM'8a>KI4:$Wm5S{9?qBs[u9{MtH9C'.Po)غ63V)NEEs+~o*qf'(C) eӡ; `gϦ+WP^:q#izSjIR,ƩzHz ?m۶z06: 0zzw8NYUJ;n$:֬Ny<=饉"b#-5fq",3glS[/^8+pFsEϚ4B~y k֖ñYi(EcoQutVJXszΎu%o{;ӽ}p"ܕ[NXWS6G܏ #p%5kUXTb⺃IZ\@\tcuNFձkv6ƍcsslڴnJ~-eΜP@Y/$OqSi2-ҎY1D=Hg#sh=[үckg[7]FgMy~ljݠTpkYz"D1c16$M8lwM4IldI 8.c *J>ν}yhsӥri*bY_}1#6zS;6׈hub%Sy(_{C6U͟S=,qVo7<H TUUɚ5k$%%+ffeJccc z}aQ(S*)@싔o 7GWg/^/3 Ppm!T[U0kGY}GBۮnm*$! _ p\\$^)kt7D`K*y`xqywߓ`ca|zk{̏?r_O,Qf]? ??'_Ƚ+n zteޫa1ai@,@_c_P~##aVt#"}51HEqpp"]+`GqTΉu5VCbۨ" k8v\׺?e*kj@?& hbQEE:rU+sGfL/_h5fH}aZ٬` ('|J?c G\L \nAZ<><;]Z._[rAD38ǒm}X_˛Z(R_\3"K$gyF#ķ5>LA~$yI#O`-Fׅ]~?Wev9yeeH`8nPn, }{~//m+aX$=5E>`dV *Q=mVqJTEOK|Jq_;pxm)Zy7RefZ nT]/u(YG0? ښZia-8Ѵk?*1Ov4Ɓ`4Bq,!gl?  v.CY=$4F$ڌXzTC=ϟgJ~^̺vV@Ǐ7)Sd.}Bt#"\z}c7^>"Wjqs>ҮJ&1Z;$@#@1|y  Ruo[wk_=*B8kluFvouP;)/hs*DӐ2Ani`ݲj&Mb^x}u@YZ<^(_3yL ;˵Q'־_77Rg5sWꃗ߹[DSQtl(Y*{T};Qzf3XC}(qXH`((++#G!A؛;w۹sՙ/^,~͛7s322dҥ.TiUO:e·x骪3>c+dB``V00+mRYYiN5k"^#.~3e㭣I#>}x갅y92jDܨ! M,~deW\"UյrN:<,ȍZ{iYAtAG N`0B1_b]1W; h?/8ΔU2f E#`+"E=zd)ܺݪs­P[{G8;RlsTkj . {9 %qHHb+"7n|#t`Y{{ : >5^ tqh:w"|IYrZʝ |Xu@"3_ڙ 4 M;3GG$@$@$@$@$@$&GteDGxUW^k{־.{99A#(8ё @D TVU]nR*˩ivcγ#%%e_(҂FwV_?%f/v ؏]_wg{?6޼~Nxs.ې s رCnYzIeo4|RWW'vcC!oQ50;;i_ Df_7[$;+[qKn[(Fnbh^^̚5v 6o<\i4vܿ^zɤh/iv.ې D##ÝW%     !O`uF[q #~:`|=zt_c A7nYk:".$$& jC̊rDzcj5ҞQc TllO`B8ܠ ]HHHHHH b!$\|Gw𕙙)ELLt']ߡ>O{; (1c.`N`n[2>o zƼ +^|Eոlٲ`KK :G8X@LKp, D;b`H CrD$@$@$@$@$@$Q[6o1׬Y#L"ꔛgeg!6Pz(|m6dfeFP9*ژ+gϞ/F$ZC˗ ",o~ݬ!xرN!@Ct#"c+475cA[ 3cY3c9$r[^t&$@$@$@$@$@$@$OzAz2":;:c RkkkX2%7Jұs'0UcEyA_I (8F>M$@$@$@$@$@Cٳ\^u{\)_,qq13I03~іNs̑yɾ}TÎ)tH% . ̙#v2iZmNC%XήNSJioo'IA~INb7֜U+WɡCdݺuO|:g ';1 P&~9uꔬ\Ҥb]A2CJ2MHL0Փm1㻭f|H̜ p  Bu"3cO#Z8gO٘HHIFh\rS%9!!A:::$11# |P 5([[$=#=իW'a( ^G4*kcO̙;94Ff gq_9y [ W>kvE^<>,[^̆$$|? HvC$0 lذA^}U> H B$jwwu2Q;Sƞ9k};pw+Vw/ / 0KPlFÍ> > H h|Ky;kZ0~h3 & [nSw\q. ioIII&ұ~wTm÷b#X9b ss sF$X= @ D ] HQ7n4bA!z "}֝sɓKǏKEE/W=rѣG)@_9s<";v9h`1ybQĉ@ OR25h]!S[4 %5cs     gwtY`;Ʃ/ֺE&TQ^aD4l#"r>lRq2Dì,@B$ :;3U>}dgͼ! Bĉ:YJ}}g„  t.."-6Mϟ؍ׯO>eTˢ"点JZreԦ;H 0±HHHHHH$QݴNOs]\ 8^[s s|&N RN @$ Hip!>CrC~G~w~ D{d)pAk :٥w;ݙHt_P %J_}$%&I%7/ zbG t'|IIIQ#GHIg:~vvYr3~x ۻچ߉ a;7Wf|N322eʔ)nY?O9Ә1uxyG(KsNHϐZ3 @ `YtIMZ[[M >H \b#agE$@$O?̗_җ/%c^óe}ŏ:1Us#{OܢlWg^uG#7_"cMGf=ϯ~l?)$@!&C {      A u׬Y؈QChB`4*Zʯ,ijn+UPǵbV5)]qvn0w؈&$&֪\  w1 D عCf͚%3fՈ(H. د i7HYSSI[ƒGƊ1G9100Xڗ;ζ$(8F}$@$@$@$@$@${9#u]>;oKĒCH !Ԯ*n̑ʌG(X9G#-c~[     3gȱcdٲe(X"֋H?gT΃gkѦTҽNIvR1pQj99G#c^S     Gk׮5/_C#jR^}=ъLԁ;=Rkkʍp> xOؒHHHHH-۷KEE}f=@@@ g*_rԢ-X1hk쀄RA8p@"J kgbaaHbظOHHHHH"F}=Z͛q˟%,(ҬE\Bm--JJJJP.tpD9yGGG֠100]j]$@;3A$@$@$@$@$@Ê/(|߽#pERguVf457 ʰbcSXM Q@c0"Jqc J=AE @ @\|Yv-s+Lzq`ZBb)b.Ff$)i 60̈RG=AEI @tntޑ H`f;3=7u]0K[[&~GHft)ϡCQj91'i$hj@IDAT@MctzG$@$@$@$@$@#pa9~vm_?Bq`-q5hď̠;)ʡ( RAEÌF<(j=x2 3Q>     }vS!yҥ~@^YY\; v3gnM+iп祬T Lk.8r|]WW'OVIKOm1>Tu弲jRԓy(.^ڗڍwjuN@r̘3GL(U㞆$@>,6%     @޽{XnV JѣGú.ihhpw0wRܹSNht޽{c>gb#ڜ/+CN:i33OPw@ vɓ'9:VBo-3£l";{뭷òCٻ?"J!X>:$ǎswI01'171G] ٮ;i?}zRvG%U3$' (8MIHHHHH`8h R#ѲmkhDX̌nDhIݺ9}X ј^юۧvQ X|gf1GlW"oH<Y8AsQG|uNҡ!OCs$@NlذAOf̜9S k99h3vnPQ3Vml:m4Agf3lv蕩k0^3uj`1crseqn_k>wCKKOiӧXSC>?# ̕L(q8ݥ.>k긴L.caN/zdwd ~'=p gq# &oB^ >0ph&_OV>sF p|)cɂ 䡇 +=9ww)̃B44>kc=s׷c>ٳG/HQQv+'KV>r$h[*򕺣ҹj7I`J;:̗gbGl@PpDIHHHHH`@ZBr#a<+/?QzuFtbg@lPq*8=ւ!sssםտ{?HV} 9^9r݈1Z)yE~!>;xȼ+ /- D=D˒'7tS"vЋeJMM5>4X<>45э(XabbZnc9#i'RSSu2oOTF$       i&~`qB&sۦalmu."*ujun$Qy}+%$$j8רk?*`gD91u뺦jrL3s<ӂ9|wZ.:jET\ERKJRE2vVHĝW҉AC#DOihlN .y|w`vX(cF&,*c#4S.yX+ԖodS9[n @cx* (tԻ;jc":I/rHDZUP8}#,҄GvuxU&O)^ EF,<QՂ4iάSN]Xh5 >0$rhABp= .c.#Jש-QFY#?/?O\i7I$Gό؂HHHHH,29x,YD";κ"]zמR1}@b>u}Ą}HFZuWgOuVM=}ҴS=/6R3O# G.咙wF9&bkIFzǴkgrDNk')э׾1wݸ}v...v,J xdCyvzw E_x k׮5x+WlE.\531N40.DӞU`J4MSG<Ud5)Dz4[U4ezVadj8IΞ,nIZ#vYmmm&4ntZDth(sժ1?YfXMP.9&HBD NynI"NZ[[%]uEZMAo9}x=-|&v%_~wx*S#2Uҵ"7w#ҝ?] 昇9KPDaw;A9MF>\F"YN.+Wn֣S"y )qgѲv3>;v{NxM:5k<#}iG$dp 2PvG$@$bH}5MS` ,%U)$@$@C@KAii,E+R2ٹԦ˒$_.oܸQF'x8ſHU^*2>`A"`F.MOY2ƫ%b ]:IeQcK:r}Tlt?l;8}J5"S?޳}(ٶ KlėѴv#.۶m3s{ܹ">˂ 5 @01D`- :F}ɀG0i4D`uvH"vHn~#J|?BH`=)"ܩߕ_SkcYc)Eqz@lׯ7U}~a>}umSOldtZ#[RdcE'fqmXDtW.]ങQ)&.z(Re?.o[nkF L8Q>jqիWV $99Y UOwF#2^R5eZ#+v);NTH> ®."-V_2I̖Qc8ҠY4F\ g$ҋ^B|4_ ؓO ZsOچyyNe%QMFƇlΓ=Sr)--?r!3=$@!8^HHnD5n$qhNMt8] U&SS)8ђ !PL_?#k[F'}|wC=i9l&?߷ SN53g4K4"޶o}C:cL~C.뚆N;@ǯH(OoK\(=''iZ+2Zztb3۹MZZW<)_iƆykO3ۜr._S%:Oɔߓ=џqp kҝw~-QFH'_|iJv]Lǎ+3f Jv>[dsE9{ϟ/*i{5#֒GimҥRXXh ?o>FA<G?4  ?G"mPѱN~S&r]wW$  KNY|#Ƕ+ZD&CcIRNӱ [ZTL]AfEAHD*uuǂwK\9I=I-ķV:$6viuʹ 6نX]]-ih3b#:Ct+8ީ)@-Ouӳw|*yBt68<]ICw\ olnj FlęuǸKQ[_lM$@$@1FuyZrTJV#H/KSkd⤉R\\lj5fjZmZű0jaiԤLn-5%YS{4]i]Aa_Is^Kr~㤩;'L iӵ7]oQz WjL2jԨcn>476J&Nx~ș'ELջ㦝Mx]wOd5zO hM[/7,ƩLմ|XebXE{g!ї{x]wI3f9Y!%ğ9}<%@z Dc@x2 @8 t'iĆ>|hGi$@$@$0d ,E3UlAV9>]t%cj8JٳKùvgrNӗݸHfΘ)"C_"ThzkpsMkGDr>OFV,Yvk'[!6UO(6Td#D@ ټKœ X ^/QO<ʞ]xںt)j=ȬsMF*4ҩ-Q:]߽ d<N`EEEG֤u*Bӟ$۷o7Ed xG`p w @4awSiIG " xO g yT?ߐz,>sby3q$5fS3k8ƛ6m2bġ4A) 4䴮Y"w؈ KC}e"7>v taA "5;bab:x466XӭedV ޳u꺔3EN,(`yVMoן #BܷOcD$5 ^bC  @7G[ ._Z&*VMK_[>;eFzqyw];/()+;KfSUhTAt|/%i'iNtˬǧ_2ZBSllj>232e*pw}EV]տ7 =&7!>^DF[di,|ss?4 p-<UHHH/QW|*cq ?&Gz]31)[ r6XGKeZ$9GGwҥK{na 2iҤK/~bFffEHvf'Q?"ԙagG^vJכN*Ծh, .?YxI|&G$     ~ljy׻e#y|ᅞ{Mũ׉k*-{mHl@C$+ɊC4d4F!U/ߓDn~RxL?jBM~["Jn0.ܛh* FqQj5K񳀟 lHBGcزg     &`6o,'Ȝ9E^E6/i񗆳eh_IíIKFجFWiES 'CSAS[NjuMՔxˮYDKs$30tvDBLKO8N,g? pe$@$@$@$@$@$Qo*kUqvqj-rƮhF 4s>4@uG%3+S))MZq4]A!o k9⋵W.g~-tȑx 7Vg` E{7"J1wJ?~&𳁟 @hPp WJ$@$@$@$@$@#P~\' .[?+ZӘ52nB2~D1R sފGq(iii`)bkyl북 r4O"ɹ=M zDTEvy:cLo#JppJ : ي(EV\\l~63 @ Pp >SH$@$@$@$@$@%n:#=F5X}:Pӧ)r Jݠ^߁0UpDHFܵ =#I=A]VQ.j1tQKtՅb%DpN_#J-WZe~FB#> gIHHHHH " ~sT/|Y>:(LQ1Ú>KKVr;{T(JA@G+;t@o"'O8ʊ$~577wȱmura9}J1%҈ A;۩ZV&]#=Wwt\ߧ[`(EwэHvň{{9.>"j_wj|(lx3=g o$zӈmHHHHHHvIRIRN&2}nоEɤ)2uL7]ViҦE=`m7a4'@A8c*꽣kMVUHRj?a@S+Q:oV]kVk$A jolV;̩iV2nLV9zprݒ+7޲̯~pR raO~TTj#5 whr-&nvyZ/R^^nni)J0W+m۶p2q4Ҡ<`"ZOŋj޽{evH0_ @,jkgUvىyb#^Wۿc֫}b#hw1)nMu_[=Eu uWl9uKhsui8}X0a6vQhwlݳ.Ik~7/&򊊎=Q&Q]Yuu9`Bg 2"Е5ηt՗M <Q:''OrtHgU|' D@q^@J^< ,mJ߿ߋEct}VQh_v~AE7 xJw87ߍ_s`u,{-=+[eJrZO’cӍ9`HIՂ3ENA/;XRtiZ4vȲ?P;ҩ"RIZǍwYЕhQ#Ft-3aTZ>=ZRSR%//O GKoϷA(c\FɹyW*ʥQsG~!UbtF9V|0Q|pl-}%O)k0efy\6͈iI~yv]}MKJ`uFi:c%Jyd֬Y }0%wa &     j>[D=;1&D!-U5u_?rK""\g]D5ϘQl9"^)Se~fP_JSa63#3 ˩-ȴ;we{!e |hnjq=DLb}C "i$@8C@$@$@$@$@$@!ppYsDiETCm ?rU /؆h5>#ї?n]A_sllvLp<47nyJ&Ef)ڮڜ9ؤofȈ+Vwڵs (8IHHHHH *Tϕ)"q` vQlS*c UF,MP̬LZky{̒n|G A0{l"J3Sbukzjwi3 (8 @D HV6VuH_+Q}2RCs qbFy HF q ̱FvBRĭԵvv\]/DCQjh"{6nhֳHw{gA$@$@$@$@$@$ C<ײq$>URȬ;D+r ΈCߡ4DO3665 RCmHF qDĽ(MQ=u:7>$rRò`o[Cz/+k֬16l; Lp; @l~)~-Fǁ;D!/P"n1w(ƠWww("Ձ(,Y~&txAt3B21a-K(|6m\{&Jk7I|$@G`lN$@$@$@$@$@%pE$ݬ88JovV 4o(c }F!W81ZVk?.#JG-]^ܪk>-+)܁nT5+;+n|:2Bsk<6&'@HHHHHH 7f,ϸY6q(3Dk+Xg!1Ј;tBUƙ4H)8bYl?~\N/R6Ա'3:g&[dh֮tw<q\'xB^xy!A @@ v}z*q#[dRSUiڕ=,WHݥJ);|@.?<RE7V~OlD urA>_Uq^˲|S][SqRGsz|_6tC[^3'3G];dǦ Ҭ)Ǯ ̱v38Mn,m|EN|˞# Njkdƍ ;oPˆ 칳@څ!~UUUyuF'NERH<[ @7x5|;rc}~%-5MvKݕAI [JMt蚘INZIZ:6w)ƥo3)¨AMG)+W4swMo0G;Ƕ^رck+zށ-[T$w%v{˼<я~$NH lGL~, @;"rTSY{ʤel K'x kiA%]so`! _;AEPCQ0Jl5{d-K%)-Mr'-d!KחTl{Q ~'#{v#@+c?gM8mg|ޗQ#FsHfQ}Tlu Шժa{-2"J{z;"#愳288CpZf)cu?ϵu}k?#0/CAJ˛Sܻ|Ms!aK㰽8 @@864  'ƝZ.&_/#2j5>2_uwExd5$Cl `o.[aDu bj ⇾s'@XD#L"J6~xYh{??ˑ#H` p D/,ޤ)^HWúM?谍?ژV HYӾ;QrWs#w=>j.+_jUd|F!cg??#:'ޱQjXjןz)SLf֬Y!> ,Q D0CqpN D`ߕ޿.䯑̧"QjMF{>x(߫d麆&2")?x?$U[kk5uGScLc{O}=./{@( Pp %]M$@$@$@$@$@J_w^8ﵵwW[dd3^cueg^jkWKjϟtٕ% ޮevJi.=ӆk&M{R=Rg̚.I;Gjkfk hBcZ|SEG}ve`nk~7T˞ͯ /I2>o9uR^u='g+< V"J::#J9sFΝk3 Km/Užou[z2`Ncs0pk M 5/DÏ@}oDz?$SGv܀ngkEa?,9-cYIDg)8467asc:~Ǹ4':m;H3O6zppBIZ뫡W%9tK`Qj,+'W{Ugñ?vujT{SV{ڕF}[$z("n^%“/ANyp\5ώ|hW5Jc3h{y >[:wv2#hpi$ f7>gkpb1M\L0̟W̔ϔ= (/dPT$Lw}S^V#[;:SP .Ij/WIQoyYR{4F&hqqnG9kfI2cnSfH3vMimz|жu5[˸f"K&KAκ,EN!WU=NMvй`YD}sM7n3s-:SQz@tmE˓O,t-8ќ9sMF g0!*ڃB`_xEwnw/\P$Cre"Jq"?o6ygò%RPXK'!Oo!?lp(ඞ˜i gGUWWKWÜ/p!^Oyoxv ٻѷ/l6 2T/;|.@IDAT!Csޝ8W{1,7Q _V`ryns}:gv(8[>5d>"/K}ϻF2:pTR oM>|CV$@֊E*je˭]Ey<ч%gl3  hS1z`\tQT*..ި}Jvo擇K#s%9gp䥫~"aڊ%鼤~:vdN#qvbcsLjtsα__^{(u~o!Z4tvJNdWT5- \U7jzwͮCgu#\yQj-[&6mwyGNj$0lPp6%     &rڸܕ!Ew' "a ?Lj;: 1y "PY cΒUrUqq םSDn "---^EѺ"V}A8vvtH,k墳,_\v-ׯ/~sÂ@d&h9H     p PwXS};'<,)پBA!ĿpP'_U[SӠHKMmVDƌ(Ð̗ ({w֠6f%a>+oj{JnlOC?9Cb Dj_pu(~9!Ɗ?O%0%SSShpZAT%  Qp)9#cm]^:^{j"q]Ckb#R⺿0Ν+cǎ^{M7[LÆas9P     (-}.t OᎸ TwVv6 pfwǵpMDb(j8ղuœI]jm#(|pFw}}Iλ_zI`k`@IHHHHH jվyڟ ጸ mhCDÐJ D܅+(2C+iC>vuW6֍+#J;0#f1$򱤤D͛'{Jk7I`X8,n3I$@$@$@$@$QSWN ;qa"͂!8b6Dԡq;H#vE@ R{Q9+ߢ%ƙa j+O2ljYزcZtD({w24NXz8mHHHHH Z*DiuK&: DA(,1'Ha? S$骼a!ɳHʪ%>';/J?K؀ HiX2T6٭kYv_ABTXe(ړ_<ߋ 8"ISmet阤JD5vDhvw(9oDynn~/ˁdΜ9p}@;W  @%:HCgWAu @bRs&t^7L;]vt `Q&h$MQ5E[h"QQ U:HeYX]:ss3sNي9y&޷y gMlI>q\Β3P_x(*`ejiV-E5aDjWhj]݅ʎG`c6<%:nQrjGh8vj}-l=R;\$L%*Zˑ^ k2I{8 '0vhS,tHv8IGQ}ظq#>c5]X} yݍTwOD#B@! @"T >"cS\U`!&3N[SSYpdAS*sTUPC4:Gy NCwQl x[:]_B%џը̑{|Sl8u|ޫ_nF8+ˠ66Q\5k8wDxM^. W{q9G5=NYk7r{ܘ(swE +Vhe>!- 7[ަlJ! B@!6K:lh؛hs(̹c_яȒgwQ-8 ̚O̚<ꚾS'<.4Xl䪫Сkm(8Yg!5ѬcsQ>\M%P [(ٹE{qΜzuط NށܜcX{:VWAj/*w!q=;ʣT11p@^ZЮׇ^W|v@AE`q?eh"8EC! B@!M@6`{N+3y'eطic-^k,Oz:ߴu]aػnnu{LҼw}6@DaZuOPuyt{) mϟ]չWa⌫- Wg?c±PfdO8E YnIty:tqV'DeB27 jZw?"T88"ң:JR Ԋ2z~-۹ў{١:8I5W }Nb2Bh̜"7$:쌠g`ٷTU#1gHc;мb#\R{9')))ϯޮ3gթj91uT-wZZ^Yd`+:tVyp9e_^;˱_~0aB% 髡Ͼ!y+C~6YZ৕B#;b5S! B@!e'^ m^*sĀ/+qaԤ)8wL2xdQ\q-z3Q=3}BXOCa̼y.my ?35OGuQ/2CXkĘ盏oM>ǧ]gqg#_A$֍\mF3(5s9a85H/z=8#ǟ FzԄ &c{B|9833ufn`zz_=J؍cefEl>}&`.[ /5`>~)q? 'GeB XL/B@! R_,uRըm܎HΦ<ĖH 32˕0SfCCzWcvhKE=^w gC-b?g "/a'fWѴs3Ebiى܌F4x'ǡۄwT)yfŐBcfydc4NZ(WcAcIi bb)ࡩi^]U4{JZyޤJ&sB#!M( ҤAv^J/g}sZ,Scbg`JǁwxhAR:[VB@! BJa>ݝR!;B {9jbPVqBO#{ᨩ=11C|i̵>9Hƽa >WKἇ|`cr/ԷͤF!GIjDJ*bF{u豿pvLh&{ 5nU,qp5esÝm:uĆuQp:ݒ`4h@e#GbĈ1e$'`sWlx gSup ?|%S cv[gJYt),.B@! g8ɳ0f ]zk<6c'OYMg"\›= 4n[ $P_Z1"&j$%3QMLE-?BrY>C-+b`?QG%CW(] PoK_R,..IxJYLJ2@lr@I !- 8GpG){B7o?`Ÿ[w$yko@0 e~;|N@NG. ! B@!#Pl}u[gaK\]UнXᗕ"UKSY]eU%(88zũ ֣3njf""'l d܏[l$gU$Upg,iy[w(Av.vVY 8Por'SI]wّ߽kaN>v@w! Ic'!B@! B%'@=yՑ:5nq/,wVE $LZӞmqWOٝ9!5PnsZ6{Z-@sG;3=1w+s4;ԦIT aǭi6f!V dYDwy/i^7K +VϞ7lJ 7^>CBt>كB@! g/=7\/w+&s]wu!;] 5aH{SC!EP(Yd1Ji.J$mO\M5# 9̺ՃGQikҒfN,f*R}'HDEE%ڟ(WU]xLpԭ^w+ ,7(ٕez/ ;@"mߏo㳳`t"F~ͯ09q'~穓zU{I1ԜP-Aqze<{:4kgF*陰/&5)Yⲷ3Nmp4X[Sx2FFc U]q%]\7cΫv7R\ua8>z4|.^^߈7,ePQ/:"yfDpflG! B@@Sk]n: ʙa8ҵ`yܱbt*cPͰFaP"Kܺ}bkLoZ-8? +gDB;7gEL[Yľpy Ͽ xXǎhxI\<8wmE{o >uG{:US;` DJRRRZBa^*-[Du-oθ;{'9QLgQ}s`Xl*װrٳӦqH pruDplK! B@nN7>qX 6uw*BǝK'Q?1(#u‚=Bz g4>@$qΝ$AD9iG\V Cw+:vl@ot媨A#OWPQv)~GE)l1? 3"23[fq̻[X=',VUUydSLLul/w].0fϻ8cbƍ:u*ӵ.?O? wȑ#ɵ$iLhdcB@! B@t]k|ggɑmXt)x[D/Y ug Pqd?b#uVϣ~ۛS_/?s*ZZji8 u>Xl3Jl4jzVj|JjV-YS2eي? iXbY73R5]J]mçgNV\oiѩ wJn,8vgR}/^U߿ϟ/bI"85lT! B@v!P_w1!t_ iC'`/eW[#WBWmn<$gOt]ZpR_E5gsr?\cp7"p;x-=i 4lKހݧ\ gfjI5/cJ I=ꂽp~D!^ּ῔ث<+?@:м}Κ*s(/3׸S:9# r.]B.VDp (IYuu;ZZdsJ83gޛy$UR{bƌ8t<{WKp3ߚfBxu>de! B@! @'(7YZ @]> rt?%CiPHF߹{7۽kua1(ޱ էrFq[SNGTz}AgLjfn*/C4$&%[NPjs=%i^TPi-9zycjjiw+-[h'OĤI *KKK5ᒫj(-'.A'N9CaAB;;}! B@! :@ݮW1'iC(#YݲMG֥cpdKe]bcYe^{xJ OUH g.َmT M_ %y@f"ȹ{.EPy~C5Ѝ'; gΜT3j B.;}! B@! ڝQ;\jLr@)@I]ZOQU83(p/~ Xu;v<~4qqa8ƌÉa kAQp˸C}sl| ,V}ʤcB:-Z'Vc.#ܒgpgŰ,8 npk/[L0V D-K¾c_l]h@̟S-er!#çsk?GZki6àӠLˡ6xΜuf㨚Oqʼw%g/+,/9غu+M,*O?n9َB@! B]$]('s`1b##0ՔU! {)n~5T?+WnvZwF#mΫ*:*P3)ĂcMw9z0;aͰlv$~v(~,%- s$u^خɧYP2z葌WmsA}x)_ 6zgD1zfh6͚.^-z)|4 Tfٶ!XS[DO8!Gx|'fI3g_vgOLL=g-K~~lWKO83! B@! Y@ϐϑa/VOȱxv% >#Pu .үC5u IP\V?Jьް9B[ԣϣ%ŖCl}ML!x.~ٰ?X\43QhP̺@ Qwv\0&^k\[z>:sσ'#y,ѹ,=i8 SG+̜ywGjxzOh6l܀?FrxoRݑS= ! B@!"2g8z[@ǮڪQ 5&u+?Cuf8ΖЃjmކݿyR!yHRFշ>yKԯ$ , KoW?F>/NJ.\Xj.2Iޅ@& cxdsB@! B@t)/{[-9/"=3sEVe%&Xgۺ9A>A--(}QrXK^txU`۔g%nYq`|68~1¹DߜP)qBgM*#N!=I(9좹Nh6>~ Ut(5.]=5!T5ls d= ]"l+9y7C!^FqUe(e~سqРAXz5&QVmSzgy݄@~M6B@! A8,y_;0co0Ԟ~uvC {oŠȜ@]#@uX`]z%g2*})iK_)Wn8zԳCny෿o>߾THbM PV_#qL5=Dތ|;G^woKj:{͵np=J#2GG m V߽ g|n!d$YF! B@!- 4[vmXL >umV`ϯښZ[ɟٸ F0@gܩGx`n}"ػr$-^}\Pt_@#~ʧZW w!qr6Wy?oA]?,>"W op?,Δs[n;w7;N|bTyZ c,P} ##2[ڵddn%G+FM&cF@l5}zcظq#\l٤Jt"8vBv"B@! @w"'@= ^dd}%XH쑈 p@G Aa8\Z߇J 6B) 9`{ҙdG7.FI\+1@6nMpqʀ)ͳ18c RX{vUl^荒,gu#𗷡;oWǶhxOPϜc9ѷ>mzE0z_ܡ;EԞA epr~]X*"*]?\YD=ݜ/$crig6{Xj+_PJ_!ЙDpLڲB@! ݟ@"Z>?{!d^b-^cm5s?yx3^AMIiYCLYOjM%jE{ܱ^rmEĵF 34=P]'n#"ؿgrsrŦ률9qȻ'O$Ә`ɟxkP?EգT_{Ĉ9r$݋Cۢ'B#TeN! B@! N{R݁(8*(!q,jkPx8 rsB#>$ V o ϴO%fgNiwOt Bͧ%voOm4YlؗD63^zŻz%w1zCOE[qDaq̣Ƀ"/?ehs9F aک;yE]a?Y!Oe&ҔcecvyMm,=J8q-Ѓ\efnvCkC<<y͏;sg(N6 cƌѣGsVwqI:`:~ZsB?CMϊv\eGf~NZM>R7z]X]WE|.f;Fe;B@! B@%~ =n^A G.soaLZ}#2KHw{<3~u^4g^t6-|~ւ6ғ I ֔4G>>3y1zygOD|LԜq,";;*ͽ A y8674 @'%w vaAve(wY|{;w:~3f󳮟QZ˫3'88pWp mÇײYĢ,1u6+"^\q, 2{-n|Aw\a)⊯=cDZz{'yMxJ+s3g1M )$aԙy1#p98Ul4Ua[D#I o9}? ,D yO~z .'_.ߒl@! B@!I(3W<9 Cj,d`2l/ESS}1qV8@:/ D8 3M<?ɇIi_mxJAt"/O7-Zx(<{YyI;(D;瘫.Ҿ=n{z÷(yJJ:yl&kgY17%W(wV 2o]mx/r[pl{kA3+R6֮&'aҤ6iu Ƹqi&-*&]B@! B@t!$6kwF#mΫ38ˢ[B 1Qxv̔B^TLLcb2`>ϻf`}۬jzPWކzt[d0e'֣̞QW݂KBֵpJIGɈ8g,lj,JZ1q|k!25gbFJJJ(Â[Am5 ѶQ{<~4` SyV(K e8zJxB鯒x{@Q)G^Y8cPyJmՒFu8i2p2N KO'l@Zk>[P|x/CLk= >){W*IIs_Gt/򸫦ϊ|-hzjOJFc|emYNV{|" QjQgw>Á eĄ@W+B@! B@t%ͩNKmXVVؘ6 )¨3 y=ho6z>e?3OpUiF]\D"n-Hå"o(.N٨g)( onj\hy'k瓽;δs=Ê+PgYI}d#w%B@! gR#sR6$u{+Ę0 w7P拨Xwu0'c/u;y|4?r7y:L&coGWPJʚ1B-*@OiBzӋ2@ͥ2|TNg+c-rH/v[yzIXxc.ә?롌o.X 4P[lL8N$؊ӧGmUd"!`M@Gk>*B@! 6 3j ȚJuv/Nm"00"L3%r10G#]_MJ>1TS70-,~D0(T$qXtٻݩǢxwp3pѣܪ7HlfuѰóAsmy5˳(ݾѣ?/xiy"w^dwJ,,k( A}:P^wuUJ̙ /Ⱥ{Dp厅B@! &P̛#m:{<?tvlG{ievd:R3wLټEGYn۟l33 2D+ mnJ2Z|VuPRu=gqn1sGiMpVHt V~jCJ\ᆕY \w`;oaotWV(9c^El]k-Hqo>SXQ1YEiI*nJ Ey,x{ d|fbAA ˉ5^C5NHu٥Q.ظqcX!-Z[! B@!Е6K~TDd{7'IGVTi_VPf>Oh.ٛ.68ϬŦ4tc0wjqW VIIns ʘL{ J6w#_7᷀ ؇;pteaӾ!q96㎽\蝪JJprn5pb(QQ 1uk^og"דIW[yr`M?EG1!ЙDpLڲB@! O΍׺C1ף-! DTklfG][`#!ד1!D[rO_ [w/%fs*=[<׬^=^!k)ZXѣ׶>0; 1H4ЋI}>xN2I2Z:GCȓՆt| MfNwm,Ȟ}36yY3Qz1d`|}h .Awp1HKKڟ1spTmOzCMTaôԞA1#G_=]Zц:!`E ?Y*mB@! B@B`S@qm7HDL}PgGr2QϥpXJBõ쩗 t^y\oz>g:"LԠs` g%ecdD fڪ 1t#!2|66iR#t5 /![$hHk m9z"5^DlC!sڥ[Fs7nQI)9[q-v""IhP0CS_ ƃ_~B !gveF^{ڙ=hGiDx 0aqh}z_I{XFI rbo9u 7o|n߲R/ڕx8+NL!b|6/w"+! 8 Ԝv<9bA @tb Z.P\]1Rlv$]} n33%*Iif]u8U 2 jW]|Q#Is/A˅z1B͓л_dV6b&'"v֕uVauD급H6Sfjyq8n,e9YC o=k͛DŽWذ>Mw6ޯ+;^4Z=Mywv9++K;q'eo lޣ# 3;BKJaÇmSfCa޽?{4|IQm ! 6 njɠ\ޜ~l'²{$j ,?("UiHD $G wzn2-Zí"n1zpy8sf#0xE|֠ qZȸـkiGy[$y&S,cz!c}B V $(t4;Y4;{%x %YJc1]5Y5~GLɄKmbٗ]%y-zIh?R~,e&! @࿜T0g /?#bB@! @JEa8'9\u`C9̴Xpب.x$-1Y?DʉNjH^ Ɣ~|i4=cPCWh[o+P63[ܼ.$rw# /Y=9Kؤ&/ŋyf\0pA*!vi2B@t|wiBc#[w# |4 bB@! yLuEvs!ak菊" kJt %5IZlMaz;%ňQDo /_X:?ѵ~~Jt!h5~烈@*wZ%vo}OLZQb)?눻NyF;g&.>^^ǿo!ae;<5Yug=Y'wԓG)W;{6؅^Njɧ`ѢEs6l[xdzm ! {=?.|tw˪|jB@! :7R=I[RUb{ ;kbFll,*kC g`(CG!ù _ <Cb(t߽P`uzW] ۦMUmSH7}^v@錁[nRZdvyna(߹Z(󾊈pS ei|CD,O taW`yuO=A$vzlI?#"&o=TYUeٰw~VJkXz5~rWD@ǐpIg! @$xj>r-B-܂ VOdf;zD.`8< @hwppt?e T`^Wz q/e>GO.p<8){<ܲ(:q%%Oqλط_<eE!o[Ρ4ϧ7Uph/ilcle6]wB+D8^em ?uuug@̙#RR%s*?x`SybBQde^! @;ϑpvނL'B!o$Ö=G'i<[nC59LnyNjۋ@{zT_-Dy{r,D ? rŤ)?MK(+/)@I?zrA :%Q f s 4S4꡽f4R¾&(={ym|T { :7st]YhNb7$]Uw2b&`˱LM{LQ;e4ʵxgo~f)/}HB[`Ajg9K7]p<[Q[ޅB@t$G"AO*Q=:rvEgeo;~qu{4p3e:9bYLmlǑG } (C{Wj~{ѣbPo B]<4=cx7@9yi"F9'퉉,/s@H 9BP| Φ:G>/Vמ#)st\OH,౸~6 lq ԓ {23H>}:VZ=C ?#١B@#_`B@!JŔ<$;@G30Imٻu͇V7=D/PdQJl4̫~vޣ;?R[ 6t.@-?M-9opBcoB__"a_ vcҒxwK?~eB-'oVS&9!jzUW&_陟^:1=]dL7:wII|'[~6\cF-\r nݪVw}m}Ο(+ ! B@! &~z`˜1Q7xSˏFPf)JBSVW38@[N\!%[oi{okG2 ur` ǎɧOO _jqC Gtx`\kW!6c~ר yk/.qҒxw7{=u՜%.Qg`}^UU1Uwa=a{ۢ{Y؝;w[ɿbB De>! B@! {{}gݻ7NqC QDls)`.lغe@ƕ(ߺg.> XZ\k#8Na&|W3SHhd-yxb_uX8t_e}w^wuљg G+CvBGo)Β JH(38|2ׅk*ԑG Psn|<*-]JNIF[]le`Z ﮦ{k4wC {310a[ɿzxS!`J@GS,R)B@! FR[cv .[hB{U yHLJQͻ>^͋ 1))L9U;7kOw{5n^k\G^a8k;$ǝJ"v~,-c8Y̮mM+\P no.]pu.ׯ.3-kI-5xR-T(%6|6t$F ﷐؏: Ɏ>~URښ=7ˉ{KBnysLߋh-ʭJ\lh/"8IG! B@.#{ժ0 'OƠA(ѽhMF8{vnلTq!o݀zt3eYcDjrQpvnPK(t]cμsGfmcODMF庩)7+D0 cab$cM' Uj!ᖌ7dx[qOq>l[*x|j]!8o|-֮Z3gZ|9gLݣԻg{֯Æ $ʱފ+rJh;q6϶/]0ظq#VY۷aGVXE[Mf ?VNL^I,b `Mie! B@! @'&fmUՖkBiɗ(PQ>c,86Yd4ZE?AY_k³gpfexgbLB9m 52yö*-bZZHoRUs/ZLZFcѱ5c>*sD}C+"2'j٩-3,82sH-ߛ*zgq2\4/)irqq >}:s3ߧ&{Is 8~ج3kpj6QLۃ!B@! @83UCm m+)Q_v*75EC2< !ms(۔(\]q?ޣc-1ɷ:%ͷ.%5M gw a= {SjrS=%)xVLHJ5mj7G/g(0d3 $字Գ'b gAͧ9I:<&ܗ3tb,e;e(߇ h:1##S;ѻ=4zV@Leeet6XHeA՟Qs~ME”$&&_~yV }/l+d^-BMZצ)dB@! Bc-Hι7ۑv^SDe,pا'8]{d89ϻa8ч%=tT؉PLDJ8\q[{ԓWk#ef3u{B-%.|<|}{@maKud`7rz^d>ݍGXisjC@m +\Uh;P 2: "P O"zt3hy<8"L΃YfqBx_ܟ=)Y[8ܶ]߳P͓٦Y $E] ۙð;Ɵu>SULx8B@! B>u۶mĉ͓&D~sf6 F/H 1ខEg_cba;> m_%cSYe3l?%lL³YpVCy+HĩCy9=rv/^XB^e̔qp z##LL]qWKu?MQ{3f`}-J#p-JsX/oB_|\:99$AjbэP=J9~ <#gKEcؑ%`]Rz X_ʝ}4֘jQqŜzwЫJk.ufeWp zBMLf lnd2_Prf7 Lh{p "*ą2UUUj?LQxlc6A@A@Ab]wM\0 GTMR@?KN''%+x~@?)xdzvViهlh c"ALעԨVP}^1m3=4«ʗ/8LlmpC9ςLHtOvPƋ xnmkˢx8ٍY8 vb\{=!Gb2իH=p4}tE<ꎀJVUСCӵkM>PAAx+))~t=Ж-[(ieA@A@ݻwӍ73d2@6Z@ ItVo~\*g` tS-,{("#(!Icĉy%;w*.] (]WIKS>=s"8qNLb9ϭ> E` `qkjVPn\?]z%8-@|)R6H ]&ij|u(c!8w*b4+30ܷ>z\f6A/p: ϟ?Oo6更pBڴiP4*I{=neܭAF?={*++iƌs%c~~SSSҩVA@A@A 4qҎ{ٳiG`x'G @  q:^~O$v7`ŘK 2,t"u,6:vH{VXvzN 3uES䴙/Qi]CV$Lwu9^.'vhΤ?+R>m+ o0}@~mѕ[e%X51AZQv\C Esٍ ,c`5b]zu@?jtEvp'RM*Ų2***2MCCUWWS;^l\rD9X.mcqq1\z'mo߾]7ʝ:uJW>A@A@A +g[ua±6\I`0 ĄDj8"JR)qRJXpDZߕJjyhI]e迾M]ŭuQׯ~2lJ_%ΟS7"{ZdEHEj_PWŔtt%ak&Kiyb&;+S]lL,wSgdR,-kZzyEF 2W8-! ˌuE aHj_ ̑l,&sPs@1cO{D#«,A=*s|aRN^^ܺu눢dfyy9qi|5D)SpƱ`] _%Fe   @zIZv XN&=͎Ds,$YҒn&.WSU)S82g]Fi}7YrY(;G %(Ǚ0?)8(`/pLv6Ϳt +O@'cF+Q6. %~_6ah.#ɍ^ޗNQieh1N:Y [=s66vG}C<">$|y_u.[,@$h^ A zo՞q;,A'~.cl#@D?X%O/dyž!s=" _swܡ8;wxտOPE(Ԯ_җ{&aU3_}97\Gp>;͙3/*z< ~7g}V} UעET+VɓU;XD$:u*UUUӧl5ɼ;l޼ٯݢm֓+n\x  ,xX6n|ҚdZof8C:Aͨ8}ݑOl=14< ]$oჟ̇VZ>DF#P^nv[AjJ 4R)jZ٢)$'kCGVnkb6Y* dlZvc6IknО]Y}5QDfB=IoqS?Zy^8D7#ι&UvdQ_X\ 8,oH8ݧb1nҶ`3Yd*w(jkp+x'\$9z^cO>_cJU,ևE CaW\1%ќvgX5kT`u h&΢ύxW 8&r>xK8^>}hW+­OҮ?|H˃EBȻ^Cz*bOL@f1I"JRrTe/U[oU@8b?^|Y۸q#Ą IL.ӦMS$^0XG:A6_{4)ᮼG!+/؞̒8fEg0 V`12]t=F~P,1x1&s%a fF2GYٞ[)RAr?F+} JܑiL478hd@$!Fb8_&FKI5]L8lf~m6Xňk"qpmczoaq#kKfQYF.6}3r4'.; 95y? 75s5il%x0zμ&SU>OM+.x5Z;$r JۂHsDӶg ٨߱=Z.=#z JpLOEZ$2^VĞ~V6 OD?WG/wg+Uod!+rC>BKJ۽iYʆ+B8뙱 5ͣnMLܷoK/C^\La7$m`#+6Llq9Eh@fkLԨc7٨.Ջ IAS/\ܤp# =v#^Ƌ`3Z٢lz12Q#Kqyw<3 BMP.ߧ"ԧ>s6/9WqmP'ql-J+R`BOJ.ʼn^ܩHF}ܼbCm1L,Yw{0gu_,Pr5j=:Nd!Ϋ;#t=֘{Ztn7mgS>XΚO=WlV ͜gkP힑}ϝJq | ]f7~6Hdpڊ[G VJת+5em8OH7e&޽3k Ϫ7lTȬA/;T=A k_`iEW4\w-A##}zc._ٝcyD߲e g?ScH&#ӳKh3:1:۴hd:W_rEcXGbDŽKG^{5:{\\l@R4/nؘQ_T}q@PYov/1fA@A@A`;^q$)}{aN3XܨPOgbO/F;c˙V`4bYnHٔ[9aKdL4g._b%-ZM{ZUGc%'֌7lg†{m2,[G]:ۍ-6F[ܡ?(qLd,:8YEiڻl_-uuݑ` tQ}KGyAעnٱ=Oގ-}rAfu!_r`ffñXA A/>- Fc<}@{vseQj1[1sg>V(ŴA+c/=т7 w "LRV a 1Ի@FlL~ +A"bWBmX7؎u+D-s=t]w QVV6a   xD8 6xeI3LTXulaݪ=M h{O$wcu{즚>{|h+G>Kw?J fS Co܆tǙpڇ6EEG?GlE3OX6a܁D1>iܤaO;;)*9I${g|/(&wڈQr(5xD%0qğǟYKʸd7zocx{/c㹖f4לf>D92ٌd sc`,E2Ԗf}BvC` ɉKx0O>fOjĜs\}M[8DiiG(xw;E7?B/xI3< 8AD &1pcv@4ݻW7X~j0gD _ kIA@A@A cAa|L057%J s2,3Q?MC?GCd %X}!x}]>s %`&G3{d"N[HBZ8I O=M:q?-bJ uxhXL-GN-ǿSúѝ[o[fݺu+ 'Xn۩lPR38P#&}ϨicAwͱLڔMc c 1+&~|%Í_^y59!h,&C;C]Db3"FQ#uzzr_d+61!f]DA@A@X+[*!]̥De8;usPnYeuBh}lO~v$HJMDM㸈v̞Bq.>07Ƹ`cViY7 z|Bz?;;;xa\NH)Y0M.nXabb #ﯡ(5uy z8|̀7T#]Sh"OPw3_~~|\c;Lߢ:^;eD߄k<"2L#Ν;UV_~^}U*//WVJ]PP0+`EEN3gJ٨aш'~Ց8Ƌ8hH XY YFkT|w byުofuMcsM„ڭU/⮣C#[6CVDzJ9p(ո`Hfn؍Zg7w88Gp0GcƜklkɧ!z7ioyVQ M@+xA Qn@o}K= lիxZJq̙*ڸkӟLmDX(7kw%/]ۖuA@A@A $!q{v-&&?u7'miR |WAp#a#yk#n+bj8#i5\F90bj˰ogwmZmtO78&,Όƹf*?h *Ƴ KAodF˅s!xw `*?yKYʟǶlz*$ h ׸!?yRݴieO@?Ī LI&9|m.H6cr4ydEdbrDG خ,   f>uZylٲBɬG۲W: +p)`fq)\Iz.!7D$@"!]q7D„8i8 QW:l{g^7':}gx, fw<8A(XNbc,hc͛i׮]9|C@0 x3ϡ'v8G@q~]<LxϪ<ģ  ̓@命t2fк *MNk7,T!Aܵ}ƍ=EۈQ~/*/jF ; {R&O.xogE ?I}Y/ӌEV{S=lJ 4\*~5|>9Lq .1OWn85yzԦ)hQlZ./UɵRl0qŜ' -3:h^!g.u3 H#yj,.ˮXy\~SO=`E.@@gQDA@A@@L6~mWz*}?Go_DMEsJrPONdbo^p\BӦM3%〹vgW[Xb>=~8Zp_[]FΝSm,Zg|pUJ==t׿u_O8NtAA@A@53Rwk8a46ʟ9]^rjg}T>& kkktK3¹/1( jӵ+\4TR2#PYy;z jY.~/32l'+7..=mmt"9NXgY&{}٬Z<_/ʩ9afEb?'űF&;2vxI0_k!mx.@IٓaIώHPKRg" =w   " wkB/vKAa};VNu+ %VVveee9A8ABY]}dDLrt'Y9Ф-pTHQzw5dS5'9ɴ ld zwEu[\~匿 A3I⸐&4+{vP~Br*M򠭞(6#ʱ m(ݷ1aߑ𖔌IfhǴac/kI:xH4.' eXO͓.&*ϝ-~f[OӶX ĀR[s}}jG[nvohhPeNJiIbS},6"q)=)MbҬBgMta7H@G԰ލ D(a;'- 1sy.jXjLU0¯/R5/͍7   ^"A/=zn}rõz @6p:C __ (@׿i踡,{æM*V S`BjD%U#_$*xtDѹ QFV60>i҈+]#"͗ɟHϕR4ziFIL`MhD]6f-\NM8˜ŷx8&yj<ϥu^eΤ=-~<: c+z761NˠC1_0k-`ygM9Zϟ?d,zSbu~OϢC f!朢t'sۅ| &tF^SCIL\e3rw? OP{{+ 40׉b9NϧtsO|J].ݗ͎2e˕3\!WPP@jxfָ L1WIcެ͛7+_gϞMS򦨸Z_ ,g# .[y(!2~qK   tz/bЖҤA[7iS/ Џj0:iÆ EaacrI`2g:#Uo]` '9#8#o6س _@|A&UoddU3ogrCH 1EIy99guUq\«UqQob(y+eX:K [JY/nU (i {(wj0Q#m}pnDl;TFrdin+N2e֝(&%mDv&pVC~nRhL0'k c=9/ ;b۱jhJDŸWr D U"STgC˦tv9΁]]ڭ:J-X1b0vwkl}Ү눛rqL\r 669D(9d t=/B8A@A@CNӷ }muz驷Ǟ\j(\DS(~ӟVv&%GXrQ\:QW5UVY6߬IM2Vy+ma7ljGؼ.ֻ(}F꭯HgbՋ88>F|)jڷ9u[ERev&ؒCArO:.gb(xXb$a X#LӲ4jB@$t_9[D+ F )m - /w '޾M'.g*e} \I:?Gqcg9hokWAQ>l:g%Ѳr,)-J |El.eZ0F;ː p]?f@\Ei+[O贼܎9s=Ӽɦnz8|PA@A@QD ^e)"+xazIvze֧-Vˁ' PHT)k0c( a:;;Q?I^ ]aqGX\UIӂ   \tN:Ek֬QI\R`DF!hh񥫅;)B ݲ]I语5S8Z0Z7 4‘]J@wlSK}`?vF^ײLPp*p^Q>f@W/ #JP 4D;Ole%MȌpD5KAf'[yd~ؑ0"-.Ʋ`2A٪O|9.9C60wVp'==ܮQs=|; B8[iYA@A@ 0Do4s.w簤D@L uLD`EMڢԓ+aA{́7y^   !CO ,YfyGID `O|knĺQWRGpOʃu^w(zK@59Q?TR%V:AYv?Dxa ~Dx$0vX rcH8Ak$EQGP j=(պc=D?B8s,=A@A@B;^V}[ R`!'r%j~}!P1ԤHCzChuҞ@wykQNj;mQ-u`U ZUQ纛%X+zjQ8G=PIK3'ТԨ#0Qk%̽(:jr=3QE{G zwQz(  Bt9(#3k5@ )b. 9ᧉˉn_4)1w @<4]8JLM՚yqjK"'&pPX]9}[ΥMF+Sd`/4lj}UXY+-[$ 0sTu urI4u帓F0vxOYgSDc >np9WrwVђo8,saڭ1lI;AQgo,JqP  u@bQ b"maqذa޽po(** 0v9ESA@A@A@cJJJ*YG_ȘG*yu_B*IY4kl6E%NOM ⿣)C$qDs#T0?,@='{ꮩRy#dCtLrrkTVΞV_zaik6mt('> LNnN4XYtӅ=S/ilkV{78k;+Wruj׫3K-o=Pl|%cMm <҂58Kާnc4h{% sC(uD럣6@;s",^B}JY^J4)+ G4u\A+Q c$H|yMNΟS .4nVztE2e z׀4g|\AR9|Y"GcҾY]mnu>w c;v0e+8Iglt0`T u#۸_+RqtTq20ǹýي5>kz/ }gN>>ܲ~^2TT Lc14>swAdxmZndw{p㳯+A@A@ApY—{,!/Bx@୷Rni\CNJ :}K+VzI>5{7OpPԑP]LXHijuQn~E)fZ3q$ǜ嫨B1aq4sR۶v/YAr>LMˬc%ڵ5g՗>5+쪘LеC1hк^pG$dL `ApDž4A ƸK9Uw /yL Iii3ccRj 7O`ol`>9qx<,ՔCM5Id'RB0,hRw1J߲R2j2 ̵ŝqQ;Ϡ8~126䞱ի *U؞llmROv2g i\&ay[ .<#eJ4 ȢE_J}<~GiN)^sݏ%bѼtJ3٨u@ [2򩵥Usz7 gS)#F.i>0LZ@9 ؒ<Ƌی1jوMߓ M=Vw赭D]1whzo @ Α d-荱(uq@lnCDeNA@A@4U\IGS$DQAEA`L ,{ӧl%d &&h=:X 4)&666$ A@_$l9r?KvE49`q 7jF4 0 \ǘnxCp m$k?f;gށ{%"!y^ 7xQ2{Y2vS#Bk?=mTŝ) dh֣ξ|D7:X )3q4VkIZ+Gvp1yǁeVk{THҟ(Q#@t lgMSH,wlbR22iњu UD0V_BŇ29Gԙ͚h[YXIqOsX9./t>w$ݨo,ȜolƫebUg_/)?Dv.zh.Z(Wc oTrz;R\{ ^3=_X)< M@C?+qUWU+q Uy*%tDkԩSFӦM;">fSZU6fs0>}X֘GgGFn2sL߅Y__OSyl EpOcɓ4Ͼf#7   ^"PYUI555իV{Y{xqL@fR_0ژB; ~ݹ^<DzR&>Mي;k#iR7LgN:p 1c& YU\@ uשݘtӥZ Da平6EW+.) 4sT[΢)eVdX__mnj>f-֮_JŴ*/(bǬ-Oqe"l|I6Fq Fl8L [[-ٹ" ӧu_sӦ@fybqw1=4; g*"9veڵ1״>rXa~#xRq= !p'̟*;za\0#{ cU0!   (!8tԴԡe_2 Q':U uߝJ/zP! Q _ka)u0ԏdWA34Xcjr-2"juNHC߰n;Ƶ:nH71s:kF{尦kiş%:ĢxV5WlD8Ra\swnу:n؆7˞ :>*>YzҾ%Z1Da6,F;8&<;r8gšW1Ǘ=ǗNhpT9UA@A@ 2}]En۶LW.]JW\tS@OGvU+WQ=[!ၙhnvDƬYUB.79/odS~J|59QۛaeAR,c+)]ݼClf OuS-"h gћ1g ,9Gj<}r gec=55QBD3 H7k2.}}T:ٝ}|ߘXTF <&g4+ΌIKϠ\v5i9;c,Jl=Dg;u莗9PѲe w b,&u;^f[{.N/kcs Ԙ0!3ʮr8 -ܢ\rMc/:Y4HrKU&1#:šfA֬^M !ՁeVcbγsgHbz;5kPCCMTPPwW-@t>][+1 v@>+ pfuDu٪(&hU˘4Xл1)k:4$xhkk $sW%U?{TŸ'k:1f1ZZ9! >QNy'?{M}dBvB(5{6+p181^@X4 y~|i7gJx-wzOsz~~ Wt\FˈqYO~={ @@COW:yn>ntgmc]]~R+W "cmNESA@A@A@x1ݵk[ЪUY7 /)ɗ%Z&o,[Q޽(Es=NR5)`lpvs,aKǹ%薔tQZ c•\2sol "I ?J3U0Vp c\  @~:}pB1sFՔ&aB$8HD#-Ta\IXLJ= NV @@ohP䑫K>z$] #,XւdCێM\ ;kqp(5vHcĢx -5kF0AH9q|̀ރ{EȪw^cd9 1 O$  "fz_f&ZZO{8fJMusQ a.o Aw ~ G\D mcA;1xvH79+xtV(p(ս؀#Ƙ+&ѱ`Qj| }̀`|t7L1azbD-A@A@A 9rJJJ A.^H7oiC8+t]};!~BpNX[P[(ԡ@K% O;\La pl/1!1m-{1V },XF5 {{T<̌19=ׯ={&AEBX8w9   ՔDZ&[A=1IQ"DQ;͓XvkY9,ƒvR@IDAT*5z%"^\8laowhѫ/ oXۡcM0V0fƚrz}%<75=>鱆s @!)   e˖@{nj&NE?+GpH|&"{aʷU )bgDVm֌mm?H@`U}09\5n[Ѿ?&zhxu)"ytbb@g-E&N8\0^kikQcc2V17/d ǘ bnuXҽK/۷6l0 iu ǛKA@A@{EޢS*6+V% tҒdEjD w6VC[ȹbIgU A8Rј<RggJ2tđk&w I@䱑lD ?f]9:d#tIK;ї H ccF' gğ5 Wp5 ]ܘg,{ouO½ (E@=7   R^ El۶M1HM'&&fI&#hO7A6̑܂iC:i02$ 0b܍"z#0H?`>\9>Ctߙv?GO(&a )ܥY5fx#M9S\.A%äC= %F4A@A@B+W?˗ӴiӔcЄ+El w'jU/!eK8iimQbe2VHMhk;-J|]'پ /r>۹}4 X} g@d-c1ZEr'\,FR'X?f@wܓpo= *D@B7¹s_WpV E8>bvS'TוN-qTQQNQ[Yw"߾"$C)2hާ>zh_1b&],zg9*Ԋa$x"]7_F  Ɛ'w8UUUjrmv?ډc@oXQWUVQ%s^h'c 答'1|? cބ՘q g]~R=^ϬKA@A@ǎSSSrW[zi xG5B )8^LꆒΘu /,Y&OlZE:Ηk!]ʤ^ԹGM,ց#ަxR||ZU<}l1WvF4Qǩ:a5?C-2Tr,Pxf1>񸂬\223;:DocBp^>f  %Tmo(**hbQ׭[LF5a|HJJ"qu`.?~\ ‘pɓ':<6mڤrtt9u{yǸw\Ҭ""Ct\9   ! J+e/fb$Bh& D>#e6ݑ0(uҮmxnL/^Iw?gs8U dqw}b>_o}ccG}:/2t8<4TgSDm"z+vqyYE㯍 0t҇|cƹ&a0ĨSoܮ1D[ٕ: ,u}U7l10\łe/PEAiYqc ZqLmX8:7|Y#.O~C@7XBh nl×E=7>R ܠCpA DvX#'zYl2w1ﯚ&V"F8hxX&UHKKS_ɁGD@!)z}ve -G&N8uYq2]ƨvp*]DXUR [E:Gc x~1uņXjii8 QKlaYX4o9*w*'0ިcEgLfdl͵lK5c͜9gK;{*ڛ{nXGYzE*P^^i>}h#==]xg]eG<`8t2&120LBپY8hF̍]Pp9x1}mZOLW+((P^.\SNҥKmhv<"$:?8Ҳ 1R|}(c]{u*NএnnO'|0v/Pۿwv|vc{DqRa) Y Z:k?{fE̐fIJ$("~CwM**kZ?{t1"$Is!O;t>zRWݝSلG?D< AGޖY?͒lVZ[3l0"~/M hpXL+{ȹ"{}UNg>s8G^FMAG|"e׿cK̎I"m$@$@$@$@$@! ~t՗؈RAd 7 /G2F"z̃Lck*zk!kv֏geL>/)eWZarQ#\*!6ZM`ȹ_QV|/ʟ,(gyg*bI48f#ބ~wPns~/T"wľN,uó kPGstAs[2(û&5PpLR @R {p³<ҫO-  z(L!I [Z59"-/ i,f&_%N )rp梹D*ZêxH„ E~%26 R#8YCQ_DXd.Hm[8v$"ÐS.(9ǹ+ llq=3Pv{82DCοgesc˭qRj)Țx|OkoKT[Q/V=JTRUvno5sw|{zK5La,) d ͛6ԩSUVK- mF.QVCFuD:>` ˭i[ m뾷9 -nq wȪEǾP A0v{|rkuE><[d"\%Ҟp57?z3 ݣԙ>"qkRD[Xׂ؉qďqpO\cFܤ10O DX~@}wqdH߻[kO GH& ?\:ghB`IHHHH"%Lo*2ibbjM{ܡ7Vnn[WUVy.cKRzsoc)UƐklV|_O-;=Gixmoˬ8EbZHr[[N]),WST%["_yK6",R]Z=.a,aB0KlwȾmE -6]Ci/Y";uֶzkZC0Cث)x׃aS{toa0w;12=@x) 9zƳz<~_~G]w-ȥ$/֪o=y46 HHHHH |f8p`q8NB@(7;WY<^Bl^luá:l?xn~ Њ Az+aZX|z`Zc!=-wwXZ˂a% `w˗/oo*(Nz܁9 jXYgjm6b.A? d3QVq {7M1+IHHHH ĉ~ҵ55)/Q .{8k,+dž:U!E^RCsAÍ܈~Hk~mZ WP >L)\_4rZKi5:T:X1bxiYv̚5N^#сH?~_.שO@ibAitT#9v勼;,X`'zbWU}f;c I7|cƹ;cKW_~N:ɞ(BdmS|: ɗ{v[b񜟱ЍH֭iӦ;X iժUvzMv_Xt j[eΝKs sa x03% ܹ3˗/yE,sbc{[ͱ^{r#C=͛7c9ƅ!p?f,ZH,Y~xZ2… {s\2w3Y-ӪU+[-yD>s++_i Žzrp=B\h3_n9gy գ=}7xw)v{(ñoEz-RdݥoA2s9!َ#fn̨kA$@$@$@$@$z^PQÆi-rؘnS|Xz]B;(JZb# zpbSRͮ#uUHl޽{^5+aff! @qBJ@8FPhB~* Sh 9l0[^E[=2#P ,?@ٹ2!?pmy]Ǹ נ59#/Lk^μJ Up |6R&g w3gnq u ~w^|nczx?<4ZJ /1N^lEz{8f%@$@$@$@$@@`ҥvkΚ'/Өq"n/v!uǵ9N.[jꆏp" z hM;10qmf͚C6lq(G&Mle˖fP12(n" C' ͨj :=5w5lPoZWzECV݆;>9M ="L(({ƫN3訣̠ݘC{+W, 78m۶rJ:RxU^=pA;s+~@ZZG;G=) G՘bdOHqKY7ύXc։H vJ엘DW7o ¯R4>bq ʌ S`#U帎"Sp_bHz0 `X#>2`# 's6a eyIL 1i=y%~/w.zD; d*_0R^`.@tkz'R0=9cMiy`j:3kzg~~!A ^zTX-[<XcMV&~{LG-NXӻɏ?uحQ]3+$z  Gϙ$#/Ӷ~J]qJJU֖HHHH2|m/q9$TlX]4qލn=/4!Ǎf"ʍl0G2^nWX]4f SӀyizAZhVUV\cr7\077<#gء}&E+VFz<3>nw(u bN oKw+SWbqϫeZV=eTlzFy$@$@$@$@$@*}4iD:u|A@PH Uf 1ʮd1GVPHVX)Ku.8y" ʟ`!^i3H %À9Uޣ`3J'ٔ,a̓Xw!މx76R5]դ ws]2lHz ] ~%&    &|=MJ NKUBzah,z UF_4Čd0(;DA! C,cG.=Jss, GqF"8"nz*sYg7ü`2=JL`QeǻS}'a]v;HT*%AwHF"PA$@$@$@$@E`۽:7nE* t6;vʘcD'RQ Uv! 1`գTSQeW ,#dHH3 B-xf1cI6!c/?fx3HoO>{a飱鼽2{AR2JH#,"    "0yRay8E" `a 3T[V SQw"ʍ9XZ8Auە/U$_Ѳq*"^`zܡ878G8W6(wУgxv3cF2{j9QBF-gw)'%էI!å`seym^!9gKl9Ӭ' @V={orꩧJjR a+Q&>* qr%  <w(;z+JQv eG?`(5HvR~TaP~0˝B)8'878Gbpq!Nʵr=('~@9#ҏ(7މx7w)cI@ ?ː6ɝ2(U:)8aHHHHH :(裏Fҳg2Sp lRɨ(sX<h/?@*(5Qj5[ꡉ^aؒhYVӍBL(qa0,7`\aǹ sJ!$Z2xy*♁graL%N\GS ûH+Τ @jŃs$    #_ʖ-[OnMQN" J8 D=Epw`f @ K5esw* NSu38RGSu7SiXYm%井B$T1e%y9_ĻLq{?9p?4{./CIHHHHBضmԢE 9!b&/HE!ФD 1 +jl/QSYA]*[spRnXCSр׼6O*c GO0 jpB K<; q=JSKxG] N5sΕ͛˗T/Q4&!    T%ч=J뗪E& X`éSY@) cۚ'N> 3X$ u07{m VX*cVsڐd-l7qu`RxYb.ړ?f(scʎw%zaݩ榛n 6HfMՋvR EHHHH֭[eOk׮R~Ttޯ;z+WIyEA= |f{?,=T_ 0`^'K?fr,3Ϙt1e J3\|{_ 7 M6E( Pp @Xp=3ϊh63A^^FEd y B&,qi* @ņJ U0#-_͘@8F|"C^[GV*۷o>۽#nj)ԪfpP ʎa8'3an3Y n 8^e757? ^ ʨz33aqY{S/L0΍ ݌2dz\eB3^ig4{rQG=p@Ae5K;g ]ƒDxaФ#i uC6V@))uХrZa3z9.67Fx x?l~GϕT իKV:|Lbx8UT)jq# \B2!߷_v9S1'*lz_1a̻v[-^_Wac>-䁼^  =ݼ oο`$P _Pz,8Bt ,vJW0p`7"tDC#DueZ eb1)_V-m ̬ZچaoW~=zA㨟yyyҩS'k֬92jJ4h`âͬw Ϭ?lvҶm[;edQ|W_}e܊&3 ={BDϣNӰaC9cm ~:/AT4Cټy̜93,OUVE{邺gp>g O4aB³ &Uݻw=ӬY3ɫg@vI'y_lJYs2fj7V;˶H/荀_hO/=⟁.ܗ? 0ǎ;fM4xM =y_)8۝ݥ^*ӧOJ'bT>}ҩSy饗䪫J-[+HrV߾}E~*?('Nt*ʕ+ڵSS=|Iy衇ҪkӦMK ah^+GNԗt'@ѝ }I 50cj\~ON:KG,0p["X9)(2`7@K!ApYӻQ Yn̚5N!8*8y)WNvަMNr-1Iث&j-SJ=\:|~l֭[UӵѣG_Hr;Vh &h6.\fޏq) @ `E[nohc>f+y}J<Dn4УhO`rꩧʳ>+˗/y@Xxdvd͛7O<~ţ̓HHHH 1s|Ad<|8nc/EQ0"z$Zzë$1Oߣ<Ok&kZx)}k’g1q@':B8@ff$@$@$@$@$hiK $a{@M&o{<É=(F bެ{O055cL     0 _;UnZ1 &x7-AF?q5kS ^b$TdKwH6b=I+%4<8 "@1aA٣G?X)5D| @Xbےu,9n,,X@KlzLrL^1K$ n#Zv-۶WNwLJ18dSe2gYvl+ xvϳ 2eo?t;w/|JXs޼ylٲ+_6h p׮]v?rWAt @_5QzzQiQ;J}+s]42gر_Kgȝ@(Xe"}i/!XXeN~[o)8fuuj3Sre{s駟nǘ6m<կ1w*U창{ez4$@$@$@$@$:L}Ij"#t>-{Ql -r؈kʕ}ZגO}^ wXb#r.\~$ !HW| [ꫯʨQՈEc:vh[NȍA$@$@$@$@$8O;J>{ɰsq(uNA]E^ @vC:h/ 2ydޏk׮ ޿݋+Qc1:u2(KnntM%A$@$@$@$5GQY蓛ɍ(\3䁷.&nTyj%i @'.G85aļ؂09|8Ȋy $qcMo3mt/XKHN=,$@$@$:?P[f83OGޱ|eg/̗HHHH }[g74-+\VMw={:\)S&Ll @p½s8 ?t,C,h~A+8N0^N=TӧOܘ @0T# rqi@< ZƠH Q"yA M4naf=5.W't>h;c>Lټ Ǡ/G$@$@$@IaIM{yq3Әx5A7 xџHR@$b7ܻqq78!Pm:Mc @fp~Ut^nn~f9Mq[>q&H +k ǵ+RzO$)an~#3/3Np36Gn RܰaԮ];TN$@$@$@$lƿxGna!|`N(vPF~ 0Rc< T!V(O&jmp~Km>2}c /28qbHHHH r w~8"t;*$@$@$m=&atƏOAn2靶W~xڧlAA<2i$)HHHH  u?_Q^t>64:2 d3pSw-kxf>61 Uncڑ7NkqժUW_/[l)bƌE~^h?RǺudёHHHH } w?O>cY p$@$@$ "ino0~q58?rIHp Â={`!    /79u_mpӍ},M?.u3.IHH {ҭ;όg#}~}Qx4 yj|s_Hu ?aIHH  :gS?aN 8n8׼o;7qKC\5fK%;mm۶%cÆ /Hqy@    P~ C7|pGOLo<3 $@$@$VNݧVt~gn38q4OL~ Zf͚ɹ+S/۞0aL6v~],B;yyyҥKi߾TP!J$@$@$@$ h1yAmƱ"c<73IHH  ]s|zCfGj# ?=3nOk7ߔK/Ե6m*O>d]ѓHHHH ; 4_nMepײ85.lqѴjq> *#}L?Cߑf;f\3_[󂿺M˙ǂ3NA(FЌk{qr*lg۶mRU֓HHHҎ3[Ln[4eb$95i8@/EgI漶+\[A3vapØ~oss['n,q(8FH+0 ṃ\fͭ~ƴ5tSJ[y F'jvL}l$g Vw*lNOݰasnHi/8$瞓'x< @b uu;m~Cbk£ mʍjՆmOtoM;mp|+Vȥ^*>TV34fϞ-3f̐E]WE~zOdӦM>S0 @Fir#KW,7 @detF[#?~μ5?i)8bYkVty_|Q;8曋G_.&iHHHH6?tc}8꧶'  |Pp5VQ4 oJvxZꫯF8au?N:Ŏ    &it_m3 n4}|T87<IHH2[@A}M K;-N;MjժU%\RlÆ 1? b$@$@$@$@I rƻ*@ǣHHH ;l3~ ǾܷӸ_rHuŊދ>,\Pj{G7eʔ=zH.]tռ<ܹtU!   Ho@Wm_4<;i$@$@$@JBvç_anO#q B QFh #   P*tk:?u{fġ!  >hq[(IML rkxzA+Áb8 d(Чl3 h6؈}   #b)2j[# xB$R7ښֹ3Vp%7777 @@CۯA\ݼhi IHH2FMDH hCn?xfzK#D^F< 'mͬF7HH 9Q)$4 @b rg 7ܐhYM.@;Bµ)ea?Ι3GR0* @p6!kC< 3*2_cM$@$x^۶mKyĬ%`چp~j4W7l3w޿̝;Wl7^ׯ>H>Cٻwo܎ÌIHHH'm#!n[0Wt/Zo>)[lpڿU\9lD2eq/i53z @!jR5V# }l66/76:4,e'~!    '0W[onnƇj[ac ={wyRzu;3f_-M4 .@*TP,k8>n8Yrt]uf|2{lׯtI#oz[."Tr'  Ol Ͷr}=~mKI!& 4j׮mz˓Ν;9#{ny33    0F%1~j}D~_{РAr駟.fҥ2AAvu ڪ0-!ð1M67o.;wÇ~|ԯ__Ǯ]$CL܇G10ikt⯢:Xxt҇] ˌ#{>[V2g&=D>E:B=p=,aց޻SQtbTe66:ixQ.LIk2l0{~;x     #u-spP6>*txy֭k/Pхbʖ9Ԍ700aˉ'(j}5ȑ#_yaVhr"`ΨE c."^>RRΦC_U˵QuU4kF)_㛶Gݡ3,m-Zo!*U'M$@$@$@$2ڰ7m4~VѴ_ˠqԩ#k׭˶eE^nnQ\]bEAX5kԨa'?裥Yf"4-[e˖+Xwq #<˔-#v/`A㏀ʺK)~zg'/lS<ûHy F {;p-k^E&(T筷ޢؘ< d 0@q~lx-@ 1#HCH0a=tN5UjժҴiS{~ 6ȧ~*zjѡn"}\yŕl2W@|ܱcGQ:HHH#}Fi3`3 wةSIHHHқ6X}{vm2k,Axe KļkTN;M;4^xaQ:HHH#`mBQ W[GVdi;:Yx\    ' rmȫyiǃWw40륗^*|>RdXR   D^1nZ.s6`go>ygeeO "~TZ3HHHH2^F?nUҟHH2n4Ǵ4C?ci۶r-!F+W?iݺ7. O)L$@$@$@$`!|Laf8IHHl'M[nq?Mɶ3^pOsϕ FzժU2`_r'-02 d1ƷϹo2ԭ6<&  6B68N[Ýs~pg5kã`k֬)Gu4h@rsseɒ%;w,GM6ɋ/(eʔ)N    $`!M7j}nq2kE$@$@$$m \fq4xns8jz3 ~澙O<+8bˆ aN+SNSc!~Z># _~'x"?:HHHH26aV;x_4&  |@MC0ӭ4~R=e/8}ոqc9묳xԯ_(#<" ,(O5^xA ­ۅA؁+$@$@$@@~j|ӟHHH 3ma;kopx^ny헱9sX 8P}?.f f޽ruI8‰f\t{nfZӽ~ټyl۶͎'_3=$@$@$@$oѶO.\ZQ'/ud$@$@$@G@Vݦ0Ө_$$Mq3vH?\瞋)w|W%/_/(d;'[n,SJܹԭ[Wʗ/_h۷o/[L֯_/RV-9cK.vҥK;0O?d_Y\9g׮]vEyC01cHNcǎS!   T' w>lss͌0w> @vжZkv95j 3Ow ñyH-J*"c=|͔!mܸDG-Փի7˗| [N@AڴiSV}QC1c7$A+ 01!"^ժUC? @ІڑOӨL 0F7 @6v8[d 293vHof׵[n:G^xnܹG\xvӧO,Kk '+Ik6 v$=⓺R^R53 `B5!26moV&Md/qä"W {P,b5nSN9 rŊaiذ='$cFlİr^D>F qՂ !tBlР'   %i=T|i "(~FRKf&/~}֡y܋X@sZ1}cQ {qmϭwluFzͩ[mgL팧yᘈg-n"2Vp>|?^VZ%Bk 2鱠J2ǵkʔ)SlqϖM7Tj-[웦]vRNx5jdN:([UqA`pm=!1Db&ļ\,+$@$@$@)N \]'^PqlҖNzEZ6|?j-><,kh-eף;bƲdzoM_rymnm#V`8q}[o٢ /`k`Űc5i0-B-[Y&Rܼy=#;#) "z/BP C!jb0rnD/O ze#/܈DQOA =pŶ{np9rϞ=E̚}L2z[5SF ZLBP.ιӀpf^n}І yׄií7p;7\GnnwsǷ̝HHH U h[Cˇ}n;?3/߯#i^Ayҥ\SN;/b s=EL?"w2Q">V\z Þ+I/_X1dS#@pļ1g+W,7Jc7<^G/D_!Pb܉A&59z }&ڥP= 6Z-̸;ϥ^Nk@fڨu-hne_ s´0|ƾssUTPt;pgڳ9gG$  $m҇ JŖh &T̰1!VZưa?w͎!oرw'~-$q1Wc8_!8B t?D#ըQf}4cIݺu< /qB E''!2dzK1&u\{ ? [&|αewlMUA)]z6Zk&uOtpM8hN.&|B/qiz0m63m M[Dӆ97#pvH$@$@$@B@((*t{O5UpysO'x[h DEb#>T@|֭- #1S_tEaXfvQUyС-dZ?QN~0Nx><3\ϫAdS/ UѰl_1@xxAv=m6^dua8r5Wg'  Amf|3MtX gy.Q Al")b "D4|1DGsX5~ǐkRJQՐX-WFë~H$m9&֭kEс3ސÊ]tK+xc>+VeE?     +B$@$@$3lm#xWߞ1_e =kâWn/~S~}[qb*:u긖=Νk^1yBaIHHHHHHH@ }ڋdǩK֭mq񫯾Wlذ#̙clӦ@t/ZZl)Z*46hBհh̪Uަ0iHHHHHHHH@ Fz8a<~x{5k&gu=T+b#n_ma4BpTӴiSY|3ò!`mV0̝HHHHHHHH v4"X1s48ОC1\4*^on{;=u` GDիTcu9"1O>ҡCc&       Hmi+86ĕ `![o 1!CdvoǃC1U!46oC{F" Ă1Ѹl2;_ hҐ ďӺ(ox3g    (8geĐ . T#A| -3у1diqթ1"&F'! @|GAL}\½SJ$@$@$@$@GPp<"kݺurUWI]t脄8CC$@$@$d۶miR0O3+W(T(F0$< @6JqPa'B 䥗^GHHHH 0/3'0 ?AdAy %#zg<> @@QE*V^IHHHH )2Vp|gdҥ6ԜgϞRld ̜|=)'J$@$@$BRcs,$@$@$@$@$O)o,IyO2(_] 6Fj0 / yyy2`i׮]Y0> N *,0C    p!PqH5w\]tJlD֭[˭*t%iHHHHHHHHH dk.mڴqOF zK֭[W{=|d4        >+8иhѢjZ{yWd1 HHHHHHHHH  dxkr'\ǜ9st N 7HQ*X.ذ&kIL}5ł;V`P),޹c|;3g3 ԅ@ii^zi:^ eT~ƍe)\R&@@@hӷo_wui3LrIZtit+WFAغu;YZf@ߪU+㩬uw X @,X`˖-$H_~*;g繀d:Y;oxbe]k׮yf5kOy @@6ؿ(ygիW/W-fi Pꝡzd7n-[ n?͡v@"0uT{|  8;7>q1Zƍﷶmڛoi^{}6qDpLΰR@@h#FQF|vWu]W9i${v=,UPQ-Z*PիmժUzo @X=PVB+h{X֭뾫rɑ@ccΝ낏wyvZ{\]Uݨ$s?b\KVU«j^ɕr:W3ٶPQ9YWE*WYh /ꪫ\OoezeׯE N4ԇqmڴɽ 8@2Z@=z饗\o .<5mޙ<7jl~n;źtbzG>}m֬YR1X^ '4WR%{F)9-݂Nn[JKy8}}(HE'Pwm7?]B=x {l8b3ǏoW\qE4{ذaqF@ne@=})P @ ދvٳbnO/YlW^y=̙ccOk/69T}2}Uov,[T6/ZY);m+ɶUV.Y>L]y 1&5T:t8aK:ۧOӫ{o֭ަOnv}Z̥; 7'"@ C[O}?EB@ w9#~;餓[n|}wuHgy~w_Jm"EVPXt}WS<NLV{m,&AUۖ?_P{+W>d9%Y>̕Z }Q_z-3f^>=쳦Oz6%}8=#ֶmxCZOO] /)7<@"wS;tݥjlѼ_H}CWAI=\F ڭn'/@H@Nt j׮z6&J\`ྼ%Z|]DF_jמ@2G{1Ez}uF矷Y3g駟]q;… m̙6x`u# 5}G//_=C_VXgU8ׯr-2 2@@ZU;-Z(AY K.7xVZez*e 'Gɱ˗W_-ݷo8#     ]ph-]V\pgz)} ogqE}.]e@@@@"Yp,**K.&Nh_ưoŊ@@@@6 8zOԩYge|p!    MYp|ꩧ̹QFvmg]gdE  d@iii&mNڶ"H_NX%E)+yX啫*˗[82Ԯ"H MW㗈 nLe}h :k  *3'VR}f;H#ԏ*M!+qm_ն VWaRC׶jAmYpg} .p97o޼C@@'P,/Noꩆ{)9W4{逧^h,}WMMn+3Ti^]}JnJU$ǎ;kٲeE<@@H@WFheB;|E*SH/4gfUmyaP:TT}RYm֕jlV~#   d@wߌEe@@@@U 8c@@@@d|t6@@@@L kS]{fΜiͳsڗ_~izuΝmv'.RY@@@@șW_}e_|=sqm„ vWۈ#[naÆ-K&    ȉKzӧO`c,ԩSmȑ.@qL#    @~a+Òm̘1v|d#    @P ԗT/XR pzlС֭[7޽5kϟ8g[|yv/l-Z(3 @@@@(+ڀz(~މyyyv'5\c=z(ZpOzTo]v e@@@@bB{Iz&N<9?0ب:uf̘aOt6eʔ4#     P^ Ǚ3gFβqE}Կկ\R;󭨨()    @N 68k,w@ [omvϞ=jł    ] Ǐ>[&M}|'u֮{u     am~pnРA5>;v:׸>*@@@@@  83=u:iȐ!%K^$@@@@(/ڀc~N6CFc@@@@>rJtu&S}թe@@@@(ZvU/q/>Wg[t@@@@.ڀ{i?ݾ{Rzj\հ    mQ@}/+GT=[ViРAa!@@@@.ڀz8{۸ql}3g&}\_|EKs    Bp._֡CO<" :*l޼ye;<;C1  @] ;۲e[~?蠃ʬ~ڵ6i$۸qkFi>Ixbmlذan:Wn̘12 %I=g͚_Mx۝wޙ"C@@ -rWh+r/_^n/@O㦫}{=;wn*"@@e=cmر֨QtsQ /_~J1@@.Ιk{r!eV^O='l;w{'uO.\h+Vp>`w^  jP_R˧vo9rf{woq_Zliz޽{[ݽ1  @UCLԽɗ.]jGydիV۲el֠A:t{ޏ{챇ݨTo+7Ȋ¼=4F3vFXR\byjTiHY+*˶8??鶕)JOt22ʕuIjmxTjoRŠ7qg7ѓ+  "]{j'x 4ϟo >:vȝP֫ע6mrTRo?~A*>{;VD0%?lE(pH(GBhX%G Ѷ'RMj|r[ri_k".TlC m_͘1ýkqܸqa:n   @ 4it8`u]hplڴկ_VZezŋMW{yء{b_m۷wd*J-y~UVPXaߚN Y tDV:Umy[OBcGٿsm$/S9qĨӣ   }8sLvڶmk|}駦~hץ*)>7|]ގk/@H@hgώw3  @6 8жnBgq 8jQ=2N9woG=Z;,;lݺws=$׮] #  @*Bۇxɒ%ΧuI;ԁ  @mލ͚5N߿TuĈ!1ZѨK/_rkat9tyf R G}Zrmܸ߯!xԅ  @] =z'_~eD޽2{Wt@@  86͆ lE,ԕ^ؕT{ƹjN8'S&ef/SUJۦ"ʥH^䣠2reY7hn=~d|=UVU_﫟3i;U$8CmKl^u}]<@@\mq=^{G4c2niZb;8~[@QQQ١ɗC/okߚoy[c @zV9ߊC{ۃ4߿|/S>}kRwui^> qk<˿ M^ @hft7R3DS3x?f2Q;1ckqz>.9֕8dǡӉ*c6  *ѣ޲3fأ>jzjbRyztҙnջ8+?NEFN_e_mŲVnT꧂j ޼08k_S퐗c; 3cW~?[ڎo |ߘxU:Κ:Oq I  @. 6ਃ͆]vej=ŏeߟc2g/tO W zo2e;m[*1ITX%ڶ[I{ḁ +zšxf_oTQxufc5>P2z]qmOiok+^j;ec+8Om@~54  fPl\pqtRxw0Ӝ۷D']9QK;,L0Nf)SKLuRm2L:ZXns]#0HcekdLSaUouIY}eKvmebX  ) n&>|-[ؙgis B{iӦpw    ԡ@{8~駮Gw}Wt„ Raa5iҤ&VZUY#     8Λ7Fe˖-ի+,L@@@@HN T{u#    $+ڀcC@@@@ jQGeGq :󉯦P    Bpk&@@@@jE wƎ[+hT    Bp<1     Pk԰h@@@@ {ǜ=F@@@@BuIuii-X>OmΜ9;v:mĈ<֚#   @h 2{6eʔ G}]r%֫W 2@@@@&To޼~۠A* 6fѢEv=؀+ 6TM     P zܸqv֭[d[lnh_u"!    @?OOvYNsΖgϷ?dMg}7ް=zf@@@@ G=F=}_xv饗b@yGolԨQZjg@@@@&뮻.caÆ6i$s=}AAӽ;0; /?-wٕW^iw}w:  @ vF$39`\K*9'V̼Wr]mc֑fvvUS3]iK2ʀz+>ۣ>Za1ށ9rM6xxwuY{[<@@rV'`a 8&y0{s*<4xL4)}n*m#^{|+G]l2w4<:^5~tG%$!    @2ضmEk2Ү];ݻ⣏>IU,    @ deSN6}xMG쪠cM%Y@@@@ W2.X&M1ӓS|1U&S]ԃ    @deQFva9{͛o=Ziذa)J@@@@5 8 xXmٲ?EzR l     eYp<ꨣ_oC=Tc?ܚ6mj#Gq]T    @. dmQ?zcvgG+..Uud6i$k߾}U<    D6ਣ{5\dII8{W.]jǏUA,    11Y7yWo'Nt[oYϞ=ݸ4L>}zņ Ri     Ypܴi2^xV\Ymܸ>*3#E)j@@@@@;8l `o@@@@n/l=    !cѸqckѢE0q@@@@H@V9m} U"    @P k]v֬Y0    i{8>pX5    68|xC    Q ki4c     @c@@@@@n     @c@@@@@n     @0A>    Byْ%K[n֩SLU @f p̬   P`ܹWm֠a2e׭]gӦOb߳gOymƌ_ȑ#]Ħ;~2th:TTɓ'~3;sSZ7!$%ՙt4@@L6n&80aw}a0wmSL~۾=Ӷl2{]v 3,o .5Q= ^g  $%[Ν#1c^kVYv{SK.nkzrիWaflې!C 2@- o;Z^#iFY1   >V~}tϬիW>x7 {Ns_oܸhl߾)pvZs=-//M2Ҋ<*-#U./J;-aQQ!ME 2㫶vlҏ+}rkR~=J[k6-}:k&@@Zѣ[ԩS_~ָq20`hcO>=Cv%GmK.q+b^T HV[''悍8$j!#!B_NlۉNGb dG÷)ߣ\VMA\5KUhSaapF@@"=#v!^7zq;u;7˯,Xzn9s\ǧ"wpޮFqc  d{S-_݋a6~xs6|}ֶm[WI&2v]w1?=ƦOnڵ޽{4'Q۔8qO$6NdnÚxdlOU6o*5WF**cE:C@@ Cdj=Vi;wv嗛[G.>ꨣ\ƇMyw}vYgE{L,u@[b{pŋmРAl EcX$  j=uZFA1ؠA7>bkԨ{Ho}[AQ{ 3Æ sVI  @*8R@@%!CO}`)mڴqD$IO7ܻQy6zh4ΦM1 Xc @@Ht{l[PPPz;i?}u/T -ƶTM= -@1[  @`ӦM_%%%f͚ VE6TQ@?c~z;EX@Xc<6@E]Rի׬Y.!փSG.֥Ŗ>g͛n+VX~8fa[@: XȬ@@ u9n:mʕV\\^ D*ةS'1uk&ޏ-~DGn|@@ pTQjUQQ 8UV\3aDQzga@ XԎ  bhTQFPܚ  >g  Pp1ou @@'@1}@@LSk*,,,1!  &ig  ؀ 8Vϔ@@T pL&u! U@H  @z8ן#    *:      ^֎    @8p3    WczY;          ^g    Jc';    @z8ן#    *:      ^֎    @8p3    WczY;          ^#  @6fÖ6X^q^$k3m Ƶ>GP}bMJ#o.駞}`#G#smwACw'Zu]sα^zY&M\ ^~gvI'd{lC@@@!9pWXa ,p/DҥKnݺ띨^ͳ/]"@9slv={?s㏭M6֮];k֬Yz@@@@-9ppܞFYn{z.*8|w9uNl̘1W_򕧲*駟'|bC ݻ[FK    @n ṕ,ꞌ 5ʎ>r{Ĩ7 lwwAVZe\\ha26mٳgސz B @@@@Ϲ=VQ/=EN@OV/E=F/psF1 >"Pk׺{8.\=Z}7onD7txc=\SAt$TPTCRjn_m^Cm@~Ü\DO\}v}+*#]ZoőσH{ s1KIyz/ ~K@<;}mDھ}ijx+KeTNƃW~pZkZ 8 @%DrI8Uǯ]&ˢ0ԥѺgqZQO]v]*[oY׮]]qܹ6|pt\dӟFb2:S_S' I/tUHgٷmQP۰^DZ {[+U)3{KL1{+)ʷͥ0u/^{Cy+I&6ݟ~{yG[Bt:^/i\Pz8vi_?hǎ!  C|%Y_գQD | "*o̙Nر{ hM6uI]4a3zb3W^\&Ml͚52kwd])QPPP q)kjCr30CYA %{xÒXA n? #-(K#xz[USDB]mO#xI@TL<},?^HfP>'|`QC%Gi:vOk@ < 4mq_!  v~V,8Ў;8֭ : Qŗ^z~aD| [li/pǞ={Kg͚ezg ڔ)SxԲ piРAi2Y;H:iJtr_ү_|q뽠w˾ j=01G(/?-/AL}ak+z/ϭT2PB;>&zۀ]y~Z'z^|18lm28TJ~=V,8  f!>R '`| eQ?ϟ^{ݺukknZ_uiy\;]Q=(uNj.=Pk۶_U u/ tDmP;ۚz̩"me zpJW+қ\ʏZGA?t\yhߓ10Q^&}mr h_9C9;E?uz0|jo! @%9p]UH=tuZ랎6l!C6:.X]j=j('ŋe]m/   d}=Y@?7 Mzd'Ogy&u_xTQD@ѪU\=Zv}q==Z[}.}+   &G٘1clر06/7GA[vmFxԒf(8qq6m4[tiI5KCD=LOV9=}M0CHAk7ްI&?. r矻ލɨS^QvSuF%u"0_!!  dI :&!%ͺ.߿-\>t|]Q_ԇ'lÆ sOV?@7o>=zsOOܹ5c ׻QF*ףG`U#   @:4$!Uq>PC]Z`d6m'?vi;[&MԬ6$uOF;B uFtz<3g ٵk2|y   dΉJ ltpLzEFb 4j}`*_O=uulG= FO+ب{5Ժukk\oFTw|.;t."   m/w}l| pL+ݬ\@7k̽ Tl%]n/% J~uݛQnITRQoIR˒@@@V=_>z pL+ݯ\AFI .*WIB@@=Ǐoׯ!l-vҷ% }nj-F@@$;{ܽ<̤xO-amҥ6p@Y{$ f]a~}lX@@@ {+$C]{͞=;Z^oϛt+gy6FՂnnR &oOz7ZʊK]r TIc(  @zKkܥ}>=6DADS@Q8Pqٲe.{ozۭnSڌ3~),P@mʕk V޷/"Gs=>䓔֝K^ھ{[vm.6) D@@@q q9c>[.ZgGSO9N9=/ƲGY8k;i=J]s1vקtsJKJ]Po>(uLb׏/bꃲێOEm[o>:R1^76UgTj]ԃ@mpPN@@R,^ZGq{_>}\qѢEֳgO+V؊ȫ_~̠A Nnvyg6m5jX-I?҂1(غu1UXPhM5vZغukSNmwk5~VXX)#/fǝ.;v =}@D۟c(-[8dxKx^x둉7nh6mr˯ukm֡Cgyn51g㤇exjx.k2s=th\u'v^U{0M' Sy6yd KI*%˦ʨ~ЏOjGۻ6ƍ[˖-S򴮥u,h9O, ۚ4nYlZ﷖I 6VZYkܹsmmn@h~=H5_3jO^}v&wmGɬ[hU֠akӦ[o_[Iu}6Va.ms6&y%hdQ݉֗5-g@@!6iX'JiKWanؤIw)6_|5|p[줓N2ҽ>`S*? 4n @h{+ZOe7il{m޲$s\6+m+pNGoTG8O$aì.]rJP:.x9F˝1ryyyѫK j:]`M]* ߶#c.]+p̝wy[IW1W޿ܽ{2Ĭ̤+V~~x袋\Ν;t,!1S}/iwiն?mVZ:KX8k=mes"yGe)r|FOǎͶϋ~eopW9f "AH=蠃 u2[a}<"7RpOPnc$ ^O֪6&uj?WU>|fY*BS⿦Mv@@IիNla/͚n @*Yfב济SƦꅥތ ۮ׋{у>hW]uU8檴H ݺ#Q詭a^D Ĩl[t"_]}Y-eqʶmtСC]@mGQl&S$r p+%\OdvRj u®HDm[S"#mz}=s=pAc )|__ad?T{T~h߂m 4o۶ +0]:b&iGɼ? e]B]vCBz YV1XnR?m.~*h5kбکN֡cq4EN;i^m)?fdcGxz+[voM\d-Z~|bUS|P֥n_зlہ ^v@@@ 2^u;clҤIֶmHЮ{ѨK@|W#=OtO1bJ8q׿ `;;yW1sGDN]PU%(O+2l2)imzUnS$l2ѠG) )=̘qQ/V3+c_Pd"u.qƪ쇯7Zψ3Lz?aEI;ҫxt^eb,~ELx*rqAVV>Ŷʗ*_:V5tUPU5,"ߚ\wK9li(Q  Ԏz,J=/w{衇wK.^u82mzO RLΝ%SLGHԆz@rS 'D`@@tmZ5\ؠKLu\!-7b+Vp%*K'ǟ`n5I  @*8R@@%]D.`PQ^ڴm B',1x<_!  P@@H {bpbL<  @ucuXG@IDAT@@@@ p,GB    TWcuX@@@@ p,GB    TWcuX@@@@ p,GB   _ /?/ r $r$dH E5<>ri[UѪlaų   -*bU QXA!ʌ|ڕ|(+VNɖeRC@@@@J8VJD@@@@HVcRC@@@@J8VJD@@@@.$X  T*O0( Cٔ)@@t E:Y7 (>07D1ԅ  *R ǃeG@ ~wt嗉-3}X!  )DoO$2 _|a֠Akosvo׷=Zhaߙl [h{uuW_͛7۾k:t(_M2vqG=ztt{g_~k׮|F_?oH&MlĈڋ>3 y6|pK/[  >}k׮~V^r0jӧO={Njf͚bM6_۲eޭuܱk[SgVn\X|ګֲe2mh6sLܹL;x [h\RR{6mo'-//2 L9l  @TK~D*eβ!o~c֪U+kڴ 2>S{g]ի]0_ܞyO~b?n=zؙgi (XNk5kuA|> 쥗^{džj=w^.Rk۶k 4&M8 6]nڞ~i;s\S?`~;5j+[ou]g*򗿸u}/~ ;~];#Ų8i_}Vo#{Ί]N?6m?;}NX YLm޼y. CrsqGzh0H4c}~ 8fʑ`;@@*/~yW.6OaZw#PUVن LԆCuTNNuB?ok֨Q#뮻~;ݒN{tIv '؇~z'.Xy 7Dc${~wyk{+))1FԾ֬Yc첋 Jk:Ⱦ{Sc==\[xkwY֭\v]lr!wf|; PL>͎8 g[nq;G/_꭭H.rSODZ'k׺^g}:.hO? W}gL=+٥0Wlʗ-[^X}~ WLpL`  u*/*?6C_&v:l N?NǍNug̘a<; M=Dr:AeꥨK`u"@z=f .˖E]d7vA&;W\isANrT qկ~.V:#ݱ*8p@׻UW^y q.jo˨u.oܤqHM3qAգ4f;S쬳rޢ 1  ,pN_yŕ֭{7V [mH=aY@zCl\HV[AJ}}GG}ҥ*ZI3۷I2@?޳U[>voV6ߗKp{tu"  ~AO|4&DZ:Y>\P/[oփ>ݻQy/z(Pw}N}Q=t?>'񫯾r]z~h԰ɽ&C@ӥͺg?]}矻=&Olv dSmKJ=nqy$<uO]U~gtRL{zcvhzS ȑ#]%Ϻ]8V5İa+Vpej_ɭ /zx+Ń7|o>/uM_O2_ЗÊ<uͺ@@F /*|g@6vpL:Vo% RO\g~劕 ճQI! YC>5l4_/i3:_~+fף/0S0f]wuA;{jR/]{vRfVTHmJ#*KvUW=e (@cq!1=SNsuk}Nmڸ ]|ꩧݰ~ѽuY}D}Qw?G]bzGnmݯQ=[IU`k}'X{Cxp:``$8?8(3Q  ~Q0v`YDW^yN9ۺu ½zr{snZ=9w^>ƍݽ@F(ѥХzX2;o_;D'ǏwA[x_j@jJzzC*\XPz.A^wOQGM]y(uIz/mH=tHRxԞ=\wOE>OÆ~P@13"}ڕ>~2'ǭiۿ>gV/H6 l'(?ёjDU~a]   .I@UGu뉷xeC Stb';m.{ݸ8x{AAFRyeoϣ.V I3uvnGyPSg.g` = LCPIR8tϻ_|=(HBS}ҧ^ :gzʪM^jߌ<Xx]K\՛kպdmt&#Y)PPX`'t{@ކ<&]tq?ds=m&èv v~K,qUӬj}6)^w P*Xa4ҏ0zؖ>o5- y/\, (+_K>n2_I֯_?w3h%IML}jѢN[^!~~I^I_tK}',V$2;4=?cz_2_|=ڿzgHؓN2tد0z0M*?2[=A`j>;~a\:!}PR{}tWTP2V#PKC?D/}ni^cqdꍨ)u}F6jK.qz黛ziOU^:JI]Kku?խN9׽{|= W@mKj[j'ۖ^맵jT]jAV\m)(zYN=dՆt9xaU侐;D/<'{dm>kԆ=Q}@'jo7l-[h-_GնtuhR*}y΍CMOk߾k_ MJ4kmO4Og␀c& @@= F\|?S~:>txeDǫʱW6^^^^D2+8ϏOap_ϋWFy2=1-L  )%1DxG@ +2?X6}X?  @6 ˿7T=g S ]=~5T^p&řJLp G8@@2K /ٱbWʋc_&v,8 @t@+5䇾Lp;/v:X6]Z1E@@ ^ZZ M_~"%Ϸ8qWR9_Ə֭[vjZIK_C-xpq|,,,4m nem{y~/?OD4O>ϏǛF?q*_I&_]8VW@@2V@_X)?vWUDCA~Ӹ| 5 4Ϗ@:V;#!C<暴/D0Xtn@@:Зsp 8Q/kڏkK'>jOJ|%կiy~Y cZ׸R\Gbz8V\[7ѯ58wԏ>?8xU^/|pUh?4O:brpL:D@%ǔoKcqMyuj<޶|?/8//8\m 8֦.u# d+ a`_e:_o OZbֺוh[oiH$ED:#@] k+}%l//8?vG0ߛ<_gꐀc @@ %w* r_աN0|/8T(ދ`1Q/~]~H$ntG+y[x/?OqP?]Cg  iq׸jw_&:uq?T~q_ӱ)؋Q4ZO~[4:}9oDDGJ.i}i_P5_C?OW6hm+Mt& 8fQ`@@R&࿌'[`\q%҉QY?;|MKI'5*+_-[غulniӦְaCW+嗫lh;G FOz}>C@ dECͫ쥿ƫ~9?^ЯCkܧx<_cp eց  }A6 XN~:8 uuZa6}~9 lڵqFxTҟܒL5  T@$PQA p e 5+qM*1D9 im=<=U]Bpiӗu~-*ޗXS ^ odؔ73oi[XAq_uGU,~7U8J@$  PR@2srqO9-n\hQws=5XcR)aU;/;ꡟbP]^ [ ;wv>]g< 2|~q.ؤ6 Q|*I$  Hܣh qcBaa;;XSuw΍1igaGZ H[W燿FĻ,\ H@ o&~bv(ß w 46¢vvxUw"<[㰟K@$  PQxQ<H!}fjGءT8 v8G/ʉ:aq^Umᯑ@33,AHLع;+of>)!yyy=v5]c!0 aҷl H@$ w( N `Ǐ8y`G@/g49čꪫ6(Mí@'T8vB8; ;wneMx_WeVD wn5E5AR8p( H@$0 t;UEܺ~tR0&,7[pҐO >"I0V2I 1-$ aP;ڡ pqNoC!v5|*A2$0MtwߝrƵ^;jf&$  5:ܡtw_~ܮX`bcܗm#/X߇ƅ_p$FlF;vHSGNzwJx{&ܹ]uW/>ܹ;Hwrv46ّ.,3(qP-G ;#]z` o5XcT$0~P]}:7 UEc%<'Cል;bkq_?m T ;ݮ^@?;;°ȸ wn>EȳEv5 Y^p5Q@y[n)W8Ftnġ*$  V:}/ܤNz  6;#P"~Qvčsaw3£}頻 M܇ ҭq-KS$Vjt̅ƢEZk5\M& H@?d7ptOyX[ل1_~OP&jaJ+IqZ m 4#{{/ H`P] S?쪻\X?Nu"ZmExc7<^U8yH.]Z~,*8qɒ%}.%  H@GPhi7Ϡ V2bG|$  H@ 9Ga6)rw_&°i('?lbR2eE2Q_~hEwFc+BI@ w]ܮow :wGY]Xu "oPn"m9y+o[ A3M* H@=ov#(1᮳ l҆1W.#.6Cም'P mxvn_'F0 p^/ܝBFpvbGI;F>% H@$stQTm N{x jE"g@"n )0nQ!a"nLaQ/#g^[= H@F ~^q߉ME>U?~g~W<aarwqu$  H@:⹢}"uj\P&JpwrOzr/ (rz-:\p$0lw;V6_}%Nqڅq{n*W$  H@]U~Q}wQg@b& ڄEZ:}(C0UM[[whKJ Uý$0 f6u 7v/r{:<ܝ?LîsaaGA*Er$  H@F\IWT:@Pd$"n܇M:QpW O(#6~(5hF@c32K@"en_ծU71/7o?&*R%  H@Fr{pGG=~n \9X?򏲈cE<܄@ +q<8QF ;=v_[{$0 [/;#߇:qӦʝ}*GX H@$ cB%HUy%# ~ .H4a(#"ʈ,#.&V7Fx/-:7~JI@6] ~us:7~a{T Q}2K$  H'茇;æƐWK67ͯHeDΕ;(C; 0xu~yn նO0 >~Vg7܆G~~ Ӊ;V8(Җ# H@$04tC]~ wFE:ϯP,w~E.P 1E:m tJ@c' @o_auvj\Um#[~U8eI@$  :xk;i"Kn?v;#q^EGvZOIeutF@. sv_5N]X_?sw5qԞ$  H@:졈@kã<Åi?&˪2VU(VEc(#2쿨KS- 1Z&0P d^d;<@4j*G)XiوfP;(v^UTݫ|OY¸!l5Ɖ|gE0~bnu}̙Z"3a3!+{!|uR=7]fgvra7 : Ej?*I׼%  H@FB_^CuV@#> Dj~tTx/w*ޱa H@"uׅ~ܑW^ו/†ip&}˖$  H@:uJG*bLj`g]<Ս܇'z抡7oKiKasi$  2vr.vq >ww3摇 ۭqO%  H@Fx'nEesb3wme+;īyGHk$0Nasi$  ř_&w/wׅWv/[cȚ$  H@H=UcIrc4>uWCC9ի'bW tB v8M4*}]X'~yM=u~uq6 ƋU8yI@$  $:ܝ(y5~]qW܎8Eyx5,v'qg/xB8{Ir H`&w.niŵD AP H@$ +U.~ٯǯQvFFZlX S.xžn~$0huP_6 U|q {$  H@@a* [*~]X> r(3oU<.i"]Ӈ?60Qז@w F(腜ˣίʡ.NG#^՞jj>SW8Ur$  H@w|kڙ?^ q ?i#fGH-n4{øAy I>4 k_s"]#]?lj$  H@#My7ʷ|]W  qSMq D^y#^|tKfVK@&7h_۵]:\c$  H@ @ǼNi[vʩiU.q]aݔ- P}_[L%ocwotWŽ ^P4 H@$ Iz2u4^[}4yxKwkM/ ZLyuz:NmOc;BK@$  5+h$jYғ6O+«r@7wrƕƅtet^V) H@$0# ЁoaeVs_QVG|m L@ôF@/~+{Gf C$  H@EҴXf)?]?, H@$ Av~ 4*޷o $ )p㔰H$  H@$  H@#±~$  H@$  H@p6I@$  H@$  H@uT8QO$  H@$  H@Sf" H@$  H@$  H :*I@$  H@$  H@S"qJL$ H@$  H@$  PXGE? H@$  H@$  H`JT8N $  H@$  H@$ :<$  H@$0&&&Ғ%K}ݗ-[͛V[m44wk+FY? H@_*2 H@$  5K;|/뭷^Zk*̙3q$ Q%qT$  H@ZKew=oOniZwuӂ Z7P$ P* H@$  ŋӝwޙxj EW_]c$  H6iFF H@$  H` +Tv E$:j$  H@n$  H@4 \̕]3ז$  HT8K@$  H@}"Gaj$  H@!q8-U$  H@&s箤p$K{\4\$0e*΄$  H@$  H@@ *%  H@$ CzT܊J@Ƙ 1~6M$  H@$  H@&q-O$  H@$  H@cL@?\& H@$  H@$ AP8h' H@$  H@$ 1&qM$  H@$  H@ p4q˓$  H@$  H@P8צI@$  H@$  H`T8I@$  H@$  H` pk$  H@$  H@$0h*M$  H@$  H@$0T8õi$  H@$  H@4&ny$  H@$  H@c*4 H@$  H@$  A< H@$  H@$  1cpm$  H@$  H@M@㠉[$  H@$  H@Ƙ 1~6M$  H@$  H@&q-O$  H@$  H@cL@?\& H@$  H@$ AP8h' H@$  H@$ 1&qM$  H@$  H@ p4q˓$  H@$  H@P8צI@$  H@$  H`T8I@$  H@$  H` 4 H@$  H@cM`bb"qiOKkVZwuܹ/o$  0#p$  H@$ f.]t7J{7͟??ziiW// H@"k$  H@HeW_nքՎaP<.\T:$  H`P\c?(Җ# H@$  HXxw%K˗ Gl; H@0pu˔$  H@$0M(<1jٲe1_떀$  ~6 H@$  H@}"0gΜڜFS$c*{ $  H@$  _^}? _C H@%±$  H@FQ.Ν8 W9vƙ@/8ԶI@$  H@$  H@}'±-@$  H@$  H@ m$  H@$  H@N@c[$  H@$  H@fYR H@$  H@$  Ǿ# H@$  H@$  *gϳ$  H@$  H@;}Gl$  H@$  H@=ϞR H@$  H@7˖-K<@{Ғ4'uY'-X ͙Sh$  H`T8J@$  H@@/,_t/\p4*j-$  2*g$  H@ƅۨ-Z/^&&&ʋUw}wq\i;$  4~4f=1+ H@$  H@%V5{jFlV>.]? H@<gn$  H@$d~լtH@ppwK$  H@$ iXeUWpcU Y$  g8X6~͛Wf x8JՂS$  H@9)uc0*{ %  tLUs} fPHvmA$:@IDATfy/ H@$  H86I$05.G 駟.tUW_mxN;k`rfev9礓O>9tMiUWMlI{iV[m(/tᇧ=#=OOkcc%  H@$  H@zG@cXlN~{h=HO{vmWj_[o|%+HsOD[=TTחEhQ6^tE/ywQ< H@$  H@#E%#_*G&F} Wv7Gv=O .,Wxi gήE+nV̝3|klhzCi?1<ޅA*xw}crI=-~Jŋ'QǶx)>Pf:g<dQ4"Љe H@$  H@0(ijAƸ-(X,`Zkb=Άլ8=(`""lB鎢+<묳NZ{'Vƙ?‘0[߬zo?޳flQְDL00\h+7F ƶ(ZPavr.p"(^r$teO?r 3G E]g&<hBJ t"b"8X?7QzTszs[~X#kua)f'Ul?y[a$20Vϙ0YnfE\6ϣx_ĸ.) -/:筨yiĪiْi~TW+d~;GG)g;A,N)+wɻ] d~so♇pL3%D?Ay. w-}n{Ky0:G~ {QyoQZtWzW t"0}{0Ye#X 2~@)c5,ǎv|iNiM7 X4}Gp2=7\FagB,dT&z-a~naȿѯy#:\Ơra%,0tո39?/ "g3&lP:sVRkPf;y0[!=_nCo%``h,$I FtƄjV>{ʶW/>:9%vU8#4Bb2s^0h䅌n'=\Hz/^^wz_b0eկ.oYNM nw% sbJtc+@*ܛC ]nʐ_ޞ@3y?Ӝb+5 pWh?JG +\Qƣw6@•-Լ%G 3^d.Eevg_^; cAt䏁CDH0\=jGT}-(~f2=>^~V.=?5`3m~pUxǸ6m Wժ1xڴ&=4 _Nb3&qMaL8q6Zio5 W&޿{t.E1v  ApY`T]f9n HKq#31Kp)/nV.K?sUW]Uyp \vei Ǻ' H@$  H@mXl5 :,B|ոAʅ`;?>lFrK.)?M V|hc5cVxvZlnRvj^bc3("5$  H@$  H`PtcE_/W5 -}#lfY'.袄:tyJBκ`tAyxg G?e<d2=k(_? H@$  H@$+{6ڍNkX R=o/}W+_>'tRk*ysveՒ$  H@$  H@?s 55#`x융p0((I9:'a]w]y#gY_pֿ# dTȊ:YGBL#YI+5BolLy!l%hX>}pfr%D٩ͥ򰐉*{f[0+ AJC߂Q <`C$  H@$  H@萀uh$  H@$  H@@{*32$  H@$  H@$!2$  H@$  H@$О ! H@$  H@$  tH@c& H@$  H@$  '±=#cH@$  H@$  H@P!(I@$  H@$  H@ pl$  H@$  H@@T8vh$  H@$  H@@{*32$  H@$  H@$!2$  H@$  H@$О ! H@$  H@$  tH@c& H@$  H@$  '±=#cH@$  H@$  H@P!(I@$  H@$  H@ pl$  H@$  H@@T8vh$  H@$  H@@{*32$  H@$  H@$!2$  H@$  H@$О ! H@$  H@$  tH@c& H@$  H@$  '±=#cH@$  H@$  H@a5zMyܚ;wn)CG.L y F!k".v ;˚k\^j߭gW/qVC! ,^kCFY#ɓ4 H@&rj!Oԩ>?TX}K`oZy򐇤v!=iOKlA:9眓쓞'6۬Tf鷿m:r<&=MOzғVR:^yOS+(|#|FmP7zANGqDSy;pן]w]Ӣ7AM-*eڳԧ>t*O?=XnazߘG$ @V!{~ߧn!dp@mJYӟ5DnH>|3L\ve|B ȤM+/I'xb KI=e]"$ `<1snB/-eq=r̜݌C>ȃJ7K/M18ea>YC_w]:3VJO<7dg Ǚ*C"quM(sAl 3֬!.(djnt뭷{|aSN);kFZk<:r֚'?e2V5eS/VVDx| _Xx/ H,:!3Cd򍼹R'?)W0F]NHwqGKGgy?t"GÐL H@$pM7f 0!JOn(w0q\g?=$Weua6[zjY>~ Yy$+7xcC1>i1g[Ûo9!_!+ frOU#G]ƥ±WoH`< Dۧ޺A|d Nt4O;RpCڥH.W(% CdD[L|jYkq=L{90@!@A) .y&lF" ܩ31lɦoCк3Oz\VV+ d ؂L5j\sC|N5\S.3曧EU,DN(@VJDx"xS s- A`bȃ%gz4zA (6tr[yxWIfw2tBQ>2ByD +{(pd#8e&B(7X$Xѽ`a9ɐ?ȝ͊I_dW~y$2r, !?ÑL\|y^"e(;) qa҆#diy~%  tJ9xyL0Fs*Qjr!Yl gD}{PcuK`(c"7 Y`9yWzE `xEyD(rF!pSH|fu=y Kt:5zAyJk-wKyC duad(&%hnKGf2FN2x()=oyH@Cd vB>G?c8cYi>y%# ƓO>aG rC}?e2 P2pg;6u*$0U2jB~[.!5& CnU!e&Q ׷!Ƽd?1T?  FFA@tt74 :-W\NLmG"|s)X=Tn!NlBE=䧑$ y#A!yCv YJ/S?d9&hAcT8qm H`Ts!PAUBfMDӑ3(]#leQ6e&9`f~0eW# Hb"#:dUyH篙,+ƉO9 Y- H[_ `UґUƐ$ 2 ?~Ȩfo 912c!F5QA !0'8][k| ![ -}0t$F'\P82̊:!#=BN'G EG wbƛ3#ɓC(5giGy䉛&Yҩp t 0XF2Xt~)S# HP";!Y6($[C$ iF}ӟ.;{t!q"C5|!|`4 -:$ n ?d'XN#)WD?yȊ&Q!"!dU <%~>PI%! PVHwdRy !o V얁%  @yCGyH?y0۱#iGɤ r~`.yx=C&|Ȑ!"r,-3‘7E#HY1cRmU5f 97?ܖcKZgȇvm&:*~Dj0Px|sSȶBZSG:euœ8$ tNaC<n&Pi&#?lq *IV{3{V:tNO8rO~+tJHld73Y^p1 H`@b欳*4Gb(F3#PD0FaD&!4qml =7!E##93yH~ 'LΜr),?̉ꖀCن8L0#{WQ y򐕈ú iƵ Cl>iʅ;_/|U8on t(nRrA-B _kEXA"@]Hgڙ$.3_C& E3ڜIGYf'J|,aO#)!"@# HB2윐Z '{٠p y,n[ԑ'9;kJ&eAfRFMgA>yILP? 'QDj$  LDߏ1 Y,Bq7|3ˏ_1`‘ Z",l¸XX5(6eEQhRdԉvZ~V"V6"9Ky{^y4E5_%  Lق,B0قCq-#| *[w"&Q,"??'*5; <yd:ydq&?=> @QQcGQQ1 m|U:-f%  H?5yMX?'_g fcP?L'K?AwO XMyL|{+ y:!+ot*OنlD~~k_+ܣc=_~)E"~c7RNS&#I^dԖOä.p@ Lgc2o}kk+6;uS'>S;a@Nc*ԧ&d5q5zAyB֜X'(FM.&Xݸs7}Jq$" ;KMޣwN1dQuϗ1a #2eF`gd 9+nmF ɼ0gl7eѱґ-,=<aX= 5(7t\ˌ7BV# HBR-{Y% H@$  H@$ !P8) H@$  H@$ q%q\풀$  H@$  H@pt$  H@$  H@P8OvI@$  H@$  H`T8EJ@$  H@$  H`\ p'k$  H@$  H@$0*"%  H@$  H@$0T8듵]$  H@$  H@C("% !p9;6 .L|+n)s17Mku]͛fۖ{Їjw_N>tW+2-X mFi7OozVYez6~_b,ַg<]K_R;J;JN Cn_W'k079~Ug?M74x ~H@$  H@O`DaƿP#7-^x2 'q?M'i֠h 70}3ihG>o~3ne=U<5baӟҎ;8YsK/4=яrH:&lOL[mդ0zjz^.jv5+<,CZUjFK>ޚH@$  H@T p*9I`ysV&}R|DfUV&F?>qi$  H@$  H@-*GyX |iמR8jַ7޸k^󚕶~(m'͒%K::8|@fk geRal+q6n ό;? wm$  H@?{ǯH_җvjEG=Q+nz^_(>F/|a2 +9p6āE/YyWo6V[.]Z]xw] ӥ^Z~}IOzR?Xd]ݣ?|/.W>O,;{GWyN%2ʑ_Lo{u3(PlgΝ;7񑑭޺!_~|f7[(>(g>i~y;Q(*ߧ=igqFEN(&}'< evCx]}cWnirx ED̓떀$  H@H`FJ G1Uc h:ٕi?6 ʋU{뭷N Ң8`xӟ>Qlj|X(Wo_!z*VZvUTR!^(VM+L(dʘj f&4)VFNyysiK H_Xm[^?"~J-C-߿IŪV8Pƛ@i ` &qDj!8uXQQpDI׾؆:h뮻JqxwڶXRbuj0@u L|3i[^gW!?GNX<$  H@9*GX! @u_iUpD) |nE^t|#'~ (oy[ʋgۇvXC] <-O0r)Ԯ5!-g^_~b+.79QlWoHGٲk+hH(7)7p`&*$  H@ ± XF8*QNT]1uad`ub+Sc7QאU73]tQJJV.uA-t& E[ɿ8auV"nU%M4G?'&iϥΰ#]78KeQ8JmʖV[a7#hY?s-yf~b5n7eru+3fۭFYW^ҧIDATjY<2!޵,Ci[gP9ʡmi0|__v%q}sPj̣P1YT4vN>tG\fz_[)b%J~G]‹mGBx.u>ܑ}P^}q炦y>T(&zկ~u2b+z*i]v:`Tlm.~lǔ&'ć`N:餶_/VBqԸ{x+ʏ[knA>"X͜qe)V6[lOŪTLBi<$  H@$0*T8ʓ@GJbct?a2`y򾕣؂܉±Xr% Tl{'NfIVS"NF׏sN*J?tMӟt=G!éo0:+)r+(9ۙG8Y7;P:ʱ:$͹)VLŊܫYSln~q@C~-')P@ B12vL;ۢ[$  H` pgl %0V- i)K5llO{n5Qh2 +>$+#lv56M&g5Gظ+SvԬbu*7e_? bdԡ"?yKMozSs.⸂;Q=TcP=yO \&re?&O?<۶T||m<"h(V^q>e*4ِ /LVGm H@$  2t$aaAV0zֳ]UEg] ˕(RV`Waӟj;+Hm.>֑U׮Ň2UW]UŌT*>2F/BG?dϼ8'2V$  H@fٚնl%6ԭp{A ~~rÕb5gqAA'?TDH믿~QVW`ũXKyE1y\2⍪S|5!:+j}C.n4LΝvک7x{YPBш<7SxunR;5lˮ*,ۥS+#ɂYhQyfiq \qɿc5$  H@epc$ TW)=Vtv̷*fق./ϖF9Cv}o$)n[~0Ӧn||bd+/K{GW[x;p~d%FG4F7M/J뮻j|XJ,a[=nʥW"[ejnMkq©Zng3_ĠDWR\Mm H@$  @g^f>AO|! QU5\An=etg&C9}٧w]G8C_fU[?OeJL\J6}TW&ϾQN?W8֕7n GVS5Ufuc|{uޭmo{[U;{c5_Zpa*&l2$  H@phO裏nȄ3Ъ_%BU7 <9r ߧMl{͏w+jFי/4s\qGvR`ԸoI뮻nZ`A_/nyrf`7ԕ7vv77iPu*]V߽Ny($ gPwݕ>1[5$  H@5p'b}$ Z|ci{^p7Ul%Y/}K7T&"+|eP\pAz+)fꮲnat{6fu^5N6ju^ߩrˆdwyg}77ul0S /첆{ʑՎgBrcn.䒴tK$  H@oB8Jb%ʣHM #QQP(օ0,R@*5uAAjЅx(B/E35{>S,X%C6Ν;lƯ `ӧ:dWheFj  @G p(I-PM%eԨQQpjpZ.͛J@?e˔)Sx[-,EE6**d4FJvsR6]f9s&F2LsV>~;bl^޶ 5w Noq >x`pMPhnUe4wb:{^@@+@#Tܿ?nT6Ν;Z+Zrem۶`?oGfB <:t(R&ڵ+ǵ2_2q-[L47nRs[g9˾0| {ʢP}ЊٌzuӴ_Ê{ǴѪUn|mѱcǂzgc}2ͻ`c6V֭[S   E XĻB@ Т'Z4Az?铞]UYQ˗/^}VdO)t…zU,,ʚ5k,F`޽{U~QkӧOo|viCnݺH٤L:5j"!jg̘1ŋ&>}B<6[^}hΜ9i5.Q@TG5u[z|O>4|<)Z8Fd̙30mڴXG(駟~݃cQS4^~,J=koNYǏO@@@PCAhStv=]?8 KcC#evޝM:ӱ|xEm~DgC^S~oA_Y6ZpcA|[YZmAF+ulVv6gdPOmڼժl-r,ȖaYA=[@%Ԋ_}UPWwӲ+=<cz~ofЦHcrF=疕]jCeQEeHV@@"?2(~xw&|ĉ:i/^=~> }ֱ'F&LvP*$[uimoy D<~x\޽{,@Id襗^uڵ[Aچ2t ZW4V6mOѰe˖Czxn]Smٳ27Dlu4hPԻw`x~gvdjIk.GywF;Nf͚ǧ>ik?c@{Kٷ(g+rUv2c,Xp59rdܞ24ף۷/z 3A^vt@ 0U$h[9֢*ݭ[Xܹs#UWPY#-dAx~WNS}h&:ۃ!^i!}TOi22~hǎٳ)d+W"ck]oɑ+@@xbE|xEp XcR{lnzKb߆RYCwu6[p… fGj+i߂CNَ :eE%רjgP ,64Q+ GeA8̏ϥzB[\q+Vu,Д^7o믿v Vk[VNO/cC:s6`~ :Ա OUԳif ={רcшߎp`mҶlNpzZyDwv}@@ )E( @T^:p[7n8 `hbvXH/BOeV|bt}{.z,ʶ0l61bۼys iӎ7-ν|ULQCڂk+$T=QV/v7oLeCA( W4VCI{xREʲe9ճWlQ7z蠎[vd^eW|7ۿڶ9ʾdβ Mm7pTO~(aS,ټN*j>:|m,@@GR@B@C5\SI[.̤x ,JZlZ[=_ê:ѐp- ɽoD@ iHXFfKڻuV< subisotopologue * iso -> molecule * partialExpProbs -> partialProbs * L... -> log_... * Types: * why get_isotopeNo is an int and not a signed int? * the same with the subisotopologue configurations. * general WTF: * get_conf_signature ??? * IsoOrderedGenerator::candidate ??? * IsoOrderedGenerator::terminate_search ??? * IsoLayeredGenerator::advanceToNextConfiguration * why does it print out things to the console??? * why is advanceToNextConfiguration_internal public, if it's called internal? * it ain't used anywhere else beyond that class anyway. isospec-1.9.1/tests/0000755000175000017500000000000013373520171014261 5ustar rusconirusconiisospec-1.9.1/tests/C/0000755000175000017500000000000013373520171014443 5ustar rusconirusconiisospec-1.9.1/tests/C/test_arrays.c0000644000175000017500000000147013373520171017151 0ustar rusconirusconi#include #include "../../IsoSpec++/unity-build.cpp" using std::cout; using std::endl; int main() { cout << "Welcome to the test!" << endl; int isotopeNumbers[] = {2, 3}; int atomCounts[] = {10, 10}; double isotopeMasses[] = {1.0, 2.0, 3.0, 4.0, 5.0}; double isotopeProbabilities[] = {0.5, 0.5, 0.5, 0.3, 0.2}; void* iso = setupIso(2, isotopeNumbers, atomCounts, isotopeMasses, isotopeProbabilities); void* p = setupIsoOrderedGenerator(iso, 1000, 1000); MassSpectrum MS = set_tablesIsoOrderedGenerator(p, 100); double *masses = MS.masses, *lprobs = MS.logprobs; int confs_no = MS.confs_no; for(int i = 0; i < confs_no; i++ ) { cout << masses[i] << " " << lprobs[i] << endl; } deleteIsoOrderedGenerator(p); deleteIso(iso) return 0; } isospec-1.9.1/tests/C/Makefile0000644000175000017500000000042113373520171016100 0ustar rusconirusconiall: test_IsoThresholdGenerator test_IsoOrderedGenerator test_IsoThresholdGenerator: clang++ -std=c++11 -x c++ test_IsoThresholdGenerator.c -o isoThreshold -lpthread test_IsoOrderedGenerator: clang++ -std=c++11 -x c++ test_IsoOrderedGenerator.c -o isoOrdered -lpthread isospec-1.9.1/tests/C/test_IsoOrderedGenerator.c0000644000175000017500000000132413373520171021554 0ustar rusconirusconi#include #include "../../IsoSpec++/unity-build.cpp" using std::cout; int main() { int isotopeNumbers[] = {2, 3}; int atomCounts[] = {10, 10}; double isotopeMasses[] = {1.0, 2.0, 3.0, 4.0, 5.0}; double isotopeProbabilities[] = {0.5, 0.5, 0.5, 0.3, 0.2}; void* iso = setupIso(2, isotopeNumbers, atomCounts, isotopeMasses, isotopeProbabilities); void* p = setupIsoOrderedGenerator( iso, 1000, 1000); while(advanceToNextConfigurationIsoOrderedGenerator(p)) { cout << "mass="<< massIsoOrderedGenerator(p) << " lprob=" << lprobIsoOrderedGenerator(p) << std::endl; } deleteIsoOrderedGenerator(p); deleteIso(iso); return 0; } isospec-1.9.1/tests/C/test_IsoThresholdGenerator.c0000644000175000017500000000137213373520171022127 0ustar rusconirusconi#include #include "../../IsoSpec++/unity-build.cpp" using std::cout; int main() { int isotopeNumbers[] = {2, 3}; int atomCounts[] = {10, 10}; double isotopeMasses[] = {1.0, 2.0, 3.0, 4.0, 5.0}; double isotopeProbabilities[] = {0.5, 0.5, 0.5, 0.3, 0.2}; void* iso = setupIso(2, isotopeNumbers, atomCounts, isotopeMasses, isotopeProbabilities); void* p = setupIsoThresholdGenerator( iso, .001, true, 1000, 1000); while(advanceToNextConfigurationIsoThresholdGenerator(p)) { cout << "mass="<< massIsoThresholdGenerator(p) << " lprob=" << lprobIsoThresholdGenerator(p) << std::endl; } deleteIsoThresholdGenerator(p); deleteIso(iso); return 0; } isospec-1.9.1/tests/C++/0000755000175000017500000000000013373520171014571 5ustar rusconirusconiisospec-1.9.1/tests/C++/layered-test.cpp0000644000175000017500000000230313373520171017675 0ustar rusconirusconi#include #include "isoSpec++.h" #include "summator.h" using namespace IsoSpec; int main() { SSummator s; // unsigned int cnt_tot = 0; // int total_t = 10; double threshold = 0.999; // double mmin = 3815900.0; // double mmax = 3816000.0; double mmin = -100000000000.0; double mmax = 100000000000.0; IsoLayeredGenerator* iso = new IsoLayeredGenerator("C1600H2700N1000", threshold, 0.3); // IsoLayeredGenerator* iso = new IsoLayeredGenerator("H2C2", 0.5, 0.3); unsigned int cnt = 0; int cntr[10]; while(iso->advanceToNextConfiguration()) { if(iso->mass() >= mmin and mmax >= iso->mass()) cnt++; iso->get_conf_signature(cntr); // std::cout << cntr[0] << " " << cntr[1] << " " << cntr[2] << " " << " " << cntr[3] << " " << cntr[4] << " " << cntr[5] << " " << iso->lprob() << std::endl; if(cnt%10000 == 0) std::cout << cnt << " " << s.get() << std::endl; s.add(exp(iso->lprob())); } delete iso; std::cout << "The isotopologue set containing at least " << threshold << " probability has " << cnt << " element(s)" << std::endl; std::cout << "prob: " << s.get() << std::endl; } isospec-1.9.1/tests/C++/from_formula_threshold.cpp0000644000175000017500000000467213373520171022052 0ustar rusconirusconi#include #include "isoSpec++.h" #include using namespace IsoSpec; #ifndef ISOSPEC_TESTS_SKIP_MAIN size_t test_threshold(const char* formula, double threshold, bool print_confs); int main(int argc, char** argv) { if(argc < 3) { std::cout << "Proper usage (for example): ./from_formula_threshold C10000H1000O1000N1000 0.01" << std::endl; std::cout << "...will the configurations with probability above 0.01 for the above molecule" << std::endl; return -1; } size_t no_visited = test_threshold(argv[1], atof(argv[2]), true); std::cout << "The number of visited configurations is:" << no_visited << std::endl; } #endif /* ISOSPEC_TESTS_SKIP_MAIN */ size_t test_threshold(const char* formula, double threshold, bool print_confs) { IsoThresholdGenerator i(formula, threshold, true, 100, 100, true); size_t confs_no = i.count_confs(); if(print_confs) std::cout << "No. confs is: " << confs_no << std::endl; i.reset(); IsoThresholdGenerator i2(formula, threshold, true, 100, 100, true); IsoThresholdGenerator i3(formula, threshold, true, 100, 100, false); int* confspace = new int[i.getAllDim()]; int* confspace2 = new int[i2.getAllDim()]; //int* confspace3 = new int[i3.getAllDim()]; // these will be in different order... int no_visited = 0; double total_prob = 0.0; while(i.advanceToNextConfiguration()) { assert(i2.advanceToNextConfiguration()); assert(i3.advanceToNextConfiguration()); if(print_confs) std::cout << "lprob: " << i.lprob() << " prob: " << i.prob() << " log(prob): " << log(i.prob()) << " mass: " << i.mass() << " conf: "; assert(i.lprob() == i2.lprob()); assert(i.mass() == i2.mass()); assert(i.prob() == i2.prob()); i.get_conf_signature(confspace); i2.get_conf_signature(confspace2); assert(memcmp(confspace, confspace2, i.getAllDim()*sizeof(int)) == 0); if(print_confs) printArray(confspace, i.getAllDim()); no_visited += 1; total_prob += i.prob(); } delete[] confspace; delete[] confspace2; assert(!i2.advanceToNextConfiguration()); assert(!i3.advanceToNextConfiguration()); assert(!i.advanceToNextConfiguration()); assert(!i2.advanceToNextConfiguration()); assert(!i3.advanceToNextConfiguration()); return no_visited; } isospec-1.9.1/tests/C++/from_formula_ordered.cpp0000644000175000017500000000257113373520171021476 0ustar rusconirusconi#include #include "isoSpec++.h" using namespace IsoSpec; #ifndef ISOSPEC_TESTS_SKIP_MAIN size_t test_ordered(const char* formula, double total_prob, bool print_confs = false); int main(int argc, char** argv) { if(argc < 3) { std::cout << "Proper usage (for example): " << argv[0] << " C10000H1000O1000N1000 0.9999" << std::endl; std::cout << "...will print the minimal number of configurations necessary to cover 0.9999 probability of the above molecule" << std::endl; return -1; } #ifndef ISOSPEC_TESTS_MEMSAN size_t no_confs = #endif test_ordered(argv[1], atof(argv[2]), true); #ifndef ISOSPEC_TESTS_MEMSAN std::cout << "The number of visited configurations is: " << no_confs << std::endl; #endif } #endif /* ISOSPEC_TESTS_SKIP_MAIN */ size_t test_ordered(const char* formula, double total_prob, bool print_confs) { IsoOrderedGenerator i(formula); double target_prob = total_prob; size_t no_visited = 0; int* space = new int[i.getAllDim()]; while(target_prob > 0.0 && i.advanceToNextConfiguration()) { target_prob -= i.prob(); no_visited += 1; if(print_confs) { std::cout << "PROB: " << i.prob() << " \tMASS: " << i.mass() << "\tCONF: "; i.get_conf_signature(space); for(int ii=0; ii #include "isoSpec++.h" #include using namespace IsoSpec; #ifndef ISOSPEC_TESTS_SKIP_MAIN size_t test_threshold_simple(const char* formula, double threshold, bool print_confs); int main(int argc, char** argv) { if(argc < 3) { std::cout << "Proper usage (for example): ./from_formula_threshold C10000H1000O1000N1000 0.01" << std::endl; std::cout << "...will the configurations with probability above 0.01 for the above molecule" << std::endl; return -1; } size_t no_visited = test_threshold_simple(argv[1], atof(argv[2]), true); std::cout << "The number of visited configurations is:" << no_visited << std::endl; } #endif /* ISOSPEC_TESTS_SKIP_MAIN */ size_t test_threshold_simple(const char* formula, double threshold, bool print_confs) { IsoThresholdGenerator i(formula, threshold, true, 100, 100, true); #ifdef TEST_SIZE size_t confs_no = i.count_confs(); if(print_confs) std::cout << "No. confs is: " << confs_no << std::endl; i.reset(); #endif int* confspace = new int[i.getAllDim()]; int no_visited = 0; double total_prob = 0.0; while(i.advanceToNextConfiguration()) { i.get_conf_signature(confspace); if(print_confs) { std::cout << "lprob: " << i.lprob() << " prob: " << i.prob() << " log(prob): " << log(i.prob()) << " mass: " << i.mass() << " conf: "; printArray(confspace, i.getAllDim()); } no_visited += 1; total_prob += i.prob(); } delete[] confspace; return no_visited; } isospec-1.9.1/tests/C++/main_test.cpp0000644000175000017500000000412313373520171017260 0ustar rusconirusconi#define ISOSPEC_TESTS_SKIP_MAIN true #include "from_formula_layered.cpp" #include "from_formula_ordered.cpp" #include "from_formula_threshold.cpp" #include "from_formula_threshold_simple.cpp" #include "element_zero.cpp" #include "unity-build.cpp" #include #if !defined(ISOSPEC_TESTS_MEMSAN) #define TEST(formula, prob, function) \ std::cout << "Testing " << formula << " prob: " << prob << " function: " << #function << "..." << std::flush; \ tmp = function(formula, prob, false); \ std::cout << " " << tmp << " confs." << std::endl; \ total += tmp; #else #define TEST(formula, prob, function) \ tmp = function(formula, prob, false); \ total += tmp; #endif int main() { bool zero_ok = false; try{ test_zero(0.1, false); } catch(std::invalid_argument&) { zero_ok = true; } assert(zero_ok); #if !defined(ISOSPEC_SKIP_SLOW_TESTS) char test_formulas[] = "P1 P2 H1 H2 O1 O2 H2O1 C0 P0 C100O0P100 C100 P100 C1 H10C10O10N10S5 Se1 Se10 Sn1 Sn4 Sn4C1 C2H6O1 C1000 C1H1O2N2Se1Sn1P1 P1C1Sn1 Se5 Sn5 Se2Sn2C2O2N2S2B2He2U2Na2Cl2"; #else char test_formulas[] = "P1 P2 H1 H2 O1 O2 H2O1 C0 P0 C100O0P100 C100 P100 C1 H3C3O3N3S3 Se1 Se3 Sn1 Sn3C1 C2H6O1 C1000 C1H1O2N2Se1Sn1P1 P1C1Sn1 Se5"; #endif size_t tf_len = strlen(test_formulas); std::vector formulas; formulas.push_back(test_formulas); std::vector probs = {0.0, 0.1, 0.5, 0.01, 0.9, 0.99, 0.01, 0.0001, 0.999, 0.362, 0.852348}; for(size_t ii=0; ii #include "isoSpec++.h" #include using namespace IsoSpec; #ifndef ISOSPEC_TESTS_SKIP_MAIN size_t test_zero(double, bool); int main(int argc, char** argv) { if(argc < 1) // yeah... never. { std::cout << "Proper usage (for example): " << argv[1] << std::endl; std::cout << "...will hopefully throw an exception instead of segfaulting." << std::endl; return -1; } size_t nc = test_zero(0.1, true); std::cout << "No confs visited: " << nc << std::endl; } #endif /* ISOSPEC_TESTS_SKIP_MAIN */ size_t test_zero(double threshold, bool print_confs) { int dimNumber = 1; int isoNumbers[] = { 3 }; int atomCounts[] = { 100 }; double isoMasses[] = { 1.0, 2.0, 3.0 }; double isoProbs[] = { 0.0, 0.4, 0.6 }; double* IM = { isoMasses }; double* IP = { isoProbs }; Iso ii(dimNumber, isoNumbers, atomCounts, &IM, &IP); IsoThresholdGenerator i(std::move(ii), false, threshold); size_t confs_no = i.count_confs(); if(print_confs) std::cout << "No. confs is: " << confs_no << std::endl; i.reset(); int* confspace = new int[i.getAllDim()]; int no_visited = 0; double total_prob = 0.0; while(i.advanceToNextConfiguration()) { i.get_conf_signature(confspace); if(print_confs) std::cout << "lprob: " << i.lprob() << " prob: " << i.prob() << " log(prob): " << log(i.prob()) << " mass: " << i.mass() << " conf: "; if(print_confs) printArray(confspace, i.getAllDim()); no_visited += 1; total_prob += i.prob(); } delete[] confspace; return no_visited; } isospec-1.9.1/tests/C++/Makefile0000644000175000017500000001041313373520171016230 0ustar rusconirusconiCXX=clang++ OPTFLAGS=-O3 -march=native -mtune=native DEBUGFLAGS=-O0 -g TESTFLAGS=-fsanitize=leak,undefined TESTMEMFLAGS= $(TESTFLAGS) -fsanitize=memory TESTADDRFLAGS= $(TESTFLAGS) -fsanitize=address LLVMTESTFLAGS= -fsanitize=dataflow,cfi,safe-stack CXXFLAGS=-std=c++11 -Wall -I../../IsoSpec++ -Wextra -pedantic SRCFILES=../../IsoSpec++/unity-build.cpp all: main_test cmdlines main_test: clang++ $(CXXFLAGS) $(OPTFLAGS) main_test.cpp -o main_test_clang g++ $(CXXFLAGS) $(OPTFLAGS) main_test.cpp -o main_test_gcc g++ $(CXXFLAGS) $(DEBUGFLAGS) main_test.cpp -o main_test_dbg g++ $(CXXFLAGS) $(DEBUGFLAGS) main_test.cpp -DISOSPEC_SKIP_SLOW_TESTS -o main_test_dbg_fast clang++ $(CXXFLAGS) $(DEBUGFLAGS) main_test.cpp -DISOSPEC_SKIP_SLOW_TESTS -fsanitize=address,undefined -o main_test_asan clang++ $(CXXFLAGS) $(DEBUGFLAGS) main_test.cpp -fsanitize=cfi -flto -fvisibility=hidden -o main_test_cfi clang++ $(CXXFLAGS) $(DEBUGFLAGS) main_test.cpp -fsanitize=safe-stack -o main_test_ss clang++ $(CXXFLAGS) $(DEBUGFLAGS) main_test.cpp -DISOSPEC_TESTS_MEMSAN -fsanitize=memory,undefined -o main_test_memsan cmdlines: formula_layered formula_ordered formula_threshold formula_threshold_simple formula_ordered: clang++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_ordered.cpp -o ./from_formula_ordered_clang g++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_ordered.cpp -o ./from_formula_ordered_gcc g++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_ordered.cpp -o ./from_formula_ordered_dbg clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_ordered.cpp -fsanitize=address,undefined -o ./from_formula_ordered_asan clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_ordered.cpp -DISOSPEC_TESTS_MEMSAN -fsanitize=memory,undefined -o ./from_formula_ordered_memsan formula_threshold_simple: clang++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_threshold_simple.cpp -o ./from_formula_threshold_simple_clang g++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_threshold_simple.cpp -o ./from_formula_threshold_simple_gcc g++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_threshold_simple.cpp -o ./from_formula_threshold_simple_dbg clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_threshold_simple.cpp -fsanitize=address,undefined -o ./from_formula_threshold_simple_asan clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_threshold_simple.cpp -DISOSPEC_TESTS_MEMSAN -fsanitize=memory,undefined -o ./from_formula_threshold_simple_memsan formula_threshold: clang++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_threshold.cpp -o ./from_formula_threshold_clang g++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_threshold.cpp -o ./from_formula_threshold_gcc g++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_threshold.cpp -o ./from_formula_threshold_dbg clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_threshold.cpp -fsanitize=address,undefined -o ./from_formula_threshold_asan clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_threshold.cpp -DISOSPEC_TESTS_MEMSAN -fsanitize=memory,undefined -o ./from_formula_threshold_memsan formula_layered: clang++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_layered.cpp -o ./from_formula_layered_clang g++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_layered.cpp -o ./from_formula_layered_gcc g++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_layered.cpp -o ./from_formula_layered_dbg clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_layered.cpp -fsanitize=address,undefined -o ./from_formula_layered_asan clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_layered.cpp -DISOSPEC_TESTS_MEMSAN -fsanitize=memory,undefined -o ./from_formula_layered_memsan ti: $(CXX) $(CXXFLAGS) $(OPTFLAGS) ../../IsoSpec++/unity-build.cpp titin-test.cpp -o ./titin mr: $(CXX) $(CXXFLAGS) $(DEBUGFLAGS) marginal-test.cpp -o marginal -g tabulator: clang++ -std=c++11 tabulator_test.cpp -o tabulator la: $(CXX) $(CXXFLAGS) $(DEBUGFLAGS) ../../IsoSpec++/unity-build.cpp layered-test.cpp -o layered IsoThresholdGenerator: clang++ -std=c++11 IsoThresholdGenerator.cpp -o IsoThresholdGenerator -lpthread nr_conf: clang++ -std=c++11 nr_conf.cpp -o nr_conf -lpthread clean: rm -f *_gcc *_clang *_dbg *_memsan *_asan IsoThresholdGenerator layered main_test_cfi main_test_ss marginal nr_conf tabulator titin isospec-1.9.1/tests/C++/nr_conf.cpp0000644000175000017500000000667013373520171016732 0ustar rusconirusconi#include #include #include #include "../../IsoSpec++/unity-build.cpp" int main() { std::string formula = "C100"; int tabSize = 1000; int hashSize = 1000; double threshold = 0.01; bool absolute = false; threshold = 1e-2; { Iso* iso = new Iso(formula.c_str()); IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize); Tabulator* tabulator = new Tabulator(generator, true, true, false, true); int64_t size = tabulator->confs_no(); std::cout << size << std::endl; delete iso; delete generator; delete tabulator; } threshold = 1e-200; { Iso* iso = new Iso(formula.c_str()); IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize); Tabulator* tabulator = new Tabulator(generator, true, true, false, true); int64_t size = tabulator->confs_no(); std::cout << size << std::endl; delete iso; delete generator; delete tabulator; } formula = "C520H817N139O147S8"; threshold = 1e-10; { Iso* iso = new Iso(formula.c_str()); IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize); Tabulator* tabulator = new Tabulator(generator, true, true, false, true); int64_t size = tabulator->confs_no(); std::cout << size << std::endl; delete iso; delete generator; delete tabulator; } threshold = 1e-50; { Iso* iso = new Iso(formula.c_str()); IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize); Tabulator* tabulator = new Tabulator(generator, true, true, false, true); int64_t size = tabulator->confs_no(); std::cout << size << std::endl; delete iso; delete generator; delete tabulator; } threshold = 1e-100; { Iso* iso = new Iso(formula.c_str()); IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize); Tabulator* tabulator = new Tabulator(generator, true, true, false, true); int64_t size = tabulator->confs_no(); std::cout << size << std::endl; delete iso; delete generator; delete tabulator; } #if 0 threshold = 1e-200; { Iso* iso = new Iso(formula.c_str()); IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize); Tabulator* tabulator = new Tabulator(generator, true, true, false, true); int64_t size = tabulator->confs_no(); std::cout << size << std::endl; delete iso; delete generator; delete tabulator; } threshold = 1e-300; { Iso* iso = new Iso(formula.c_str()); IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize); Tabulator* tabulator = new Tabulator(generator, true, true, false, true); int64_t size = tabulator->confs_no(); std::cout << size << std::endl; delete iso; delete generator; delete tabulator; } #endif } isospec-1.9.1/tests/C++/tabulator_test.cpp0000644000175000017500000000153213373520171020332 0ustar rusconirusconi#include #include "../../IsoSpec++/unity-build.cpp" using std::cout; using std::endl; using namespace IsoSpec; int main(void){ // int isotopeNumbers[] = {2, 3}; // int config_size = isotopeNumbers[0] + isotopeNumbers[1]; // int atomCounts[] = {10, 10}; // double isotopeMasses[] = {1.0, 2.0, 3.0, 4.0, 5.0}; // double isotopeProbabilities[] = {0.5, 0.5, 0.5, 0.3, 0.2}; // IsoThresholdGenerator* generator = new IsoThresholdGenerator( // 2, // isotopeNumbers, // atomCounts, // isotopeMasses, // isotopeProbabilities, // .001, // true, // 1000, // 1000); // cout << reinterpret_cast(generator)->getAllDim() << endl; // void* tabulator = setupThresholdTabulator(generator, true, true, true, true); return 0; } isospec-1.9.1/tests/C++/marginal-test.cpp0000644000175000017500000000206613373520171020050 0ustar rusconirusconi#include #include "unity-build.cpp" #include "marginalTrek++.h" #include "summator.h" using namespace IsoSpec; int main() { SSummator s; unsigned int cnt_tot = 0; int total_t = 10; double threshold = 0.1; double masses[] = {1.0, 1000.0}; double probs[] = {0.9, 0.1}; Marginal m(masses, probs, 2, 100); MarginalTrek mr(std::move(m)); int ii = 0; while(mr.probeConfigurationIdx(ii)) { std::cout << ii << " " << mr.conf_lprobs()[ii] << "\n"; ii++; } #if 0 IsoThresholdGeneratorBoundMass* isob = new IsoThresholdGeneratorBoundMass("C169719H270464N45688O52237S911", threshold, mmin, mmax, false); std::cout << isob->getModeLProb() << std::endl; unsigned int confsig[5]; double cnt = 1.0; cnt_tot = 0; double lc = isob->getModeLProb() + log(threshold); while(isob->advanceToNextConfiguration()) { cnt_tot++; } delete isob; std::cout << "The isotopologue set containing at least 0.9 probability has " << cnt_tot << " element(s)" << std::endl; #endif } isospec-1.9.1/tests/C++/from_formula_layered.cpp0000644000175000017500000000237713373520171021503 0ustar rusconirusconi#include #include "isoSpec++.h" using namespace IsoSpec; size_t test_layered(const char* formula, double total_prob, bool print_confs = false); #ifndef ISOSPEC_TESTS_SKIP_MAIN int main(int argc, char** argv) { if(argc < 3) { std::cout << "Proper usage (for example): ./from_formula_layered C10000H1000O1000N1000 0.9999" << std::endl; std::cout << "...will print the minimal number of configurations necessary to cover 0.9999 probability of the above molecule" << std::endl; return -1; } size_t no_confs = test_layered(argv[1], atof(argv[2]), true); std::cout << "The number of visited configurations is:" << no_confs << std::endl; } #endif /* #ifndef ISOSPEC_TESTS_SKIP_MAIN */ size_t test_layered(const char* formula, double total_prob, bool print_confs) { IsoLayeredGenerator i(formula, total_prob, 0.3, 1000, 1000, true); size_t no_visited = 0; int* space = new int[i.getAllDim()]; while(i.advanceToNextConfiguration()) { no_visited += 1; if(print_confs) { std::cout << "PROB: " << i.prob() << " \tMASS: " << i.mass() << "\tCONF: "; i.get_conf_signature(space); for(int ii=0; ii #include "../../IsoSpec++/unity-build.cpp" using std::cout; using std::endl; using namespace IsoSpec; int main() { int isotopeNumbers[] = {2, 3}; int config_size = isotopeNumbers[0] + isotopeNumbers[1]; int atomCounts[] = {10, 10}; double isotopeMasses[] = {1.0, 2.0, 3.0, 4.0, 5.0}; double isotopeProbabilities[] = {0.5, 0.5, 0.5, 0.3, 0.2}; void* iso = setupIso( 2, isotopeNumbers, atomCounts, isotopeMasses, isotopeProbabilities); void* p = setupIsoThresholdGenerator( iso, .001, true, 1000, 1000); int conf_no(0); int *space = new int[config_size]; while(advanceToNextConfigurationIsoThresholdGenerator(p)) { cout << "mass="<< massIsoThresholdGenerator(p) << " lprob=" << lprobIsoThresholdGenerator(p) << endl; get_conf_signatureIsoThresholdGenerator(p, space); for(conf_no = 0; conf_no < config_size; conf_no++) { cout << space[conf_no] << " "; } cout << endl; } deleteIsoThresholdGenerator(p); delete[] space; deleteIso(iso); return 0; } isospec-1.9.1/tests/C++/titin-test.cpp0000644000175000017500000000200613373520171017377 0ustar rusconirusconi#include #include "isoSpec++.h" #include "summator.h" using namespace IsoSpec; int main() { SSummator s; // unsigned int cnt_tot = 0; // int total_t = 10; double threshold = 0.01; // double mmin = 3815900.0; // double mmax = 3816000.0; double mmin = -100000000000.0; double mmax = 100000000000.0; const char formula[] = "C169719H270464N45688O52237S911"; // const char formula[] = "H2O1"; // const char formula[] = "C63H98N18O13S1"; // substance P // const char formula[] = "C520H817N139O147S8"; // Human insulin IsoThresholdGenerator* iso = new IsoThresholdGenerator(formula, threshold, false); unsigned int cnt = 0; while(iso->advanceToNextConfiguration()) { if(iso->mass() >= mmin and mmax >= iso->mass()) cnt++; s.add(iso->prob()); } delete iso; std::cout << "The isotopologue set containing at least 0.9 probability has " << cnt << " element(s)" << std::endl; std::cout << "prob: " << s.get() << std::endl; } isospec-1.9.1/tests/correctness/0000755000175000017500000000000013373520171016613 5ustar rusconirusconiisospec-1.9.1/tests/correctness/molecules_2_cpp.R0000644000175000017500000000637613373520171022025 0ustar rusconirusconi# add this file to the tests library(enviPat) library(stringr) library(IsoSpecR) library(tidyverse) library(microbenchmark) library(jsonlite) data(isotopicData) # store args in function env for multiple calls without the passing of args envipat_call_factory = function(...) function() isopattern(...) is.error = function(x) inherits(x, "try-error") # test the call for results and their timing test_envipat = function(..., times = 100, timing = T){ envipat_call = envipat_call_factory(...) out = list() call_result = try(envipat_call()) if(is.error(call_result)){ return(call_result) } else{ call_result = call_result[[1]] if(timing) out$timing = microbenchmark(envipat_call(), times = times, unit = 'us') call_result = tbl_df(call_result) call_result = call_result[,1:2] colnames(call_result) = c('mass', 'prob') call_result = arrange(tbl_df(call_result), desc(prob)) out$call_result = call_result return(out) } } run_test = function(molecule, threshold, out_path, timing=T){ res = test_envipat(isotopes = isotopicData$IsoSpec, chemforms = molecule, threshold = threshold, verbose = F, rel_to = 2, timing = timing) if(is.error(res)){ return(res) } else { file_name = file.path(out_path, paste0(molecule, "_", threshold, ".tsv")) readr::write_tsv(res$call_result, file_name, col_names = F) return(res$timing) } } out_path = "/Users/matteo/Projects/isospec/IsoSpec/tests/envipat_results" thresholds = seq(10^{-5}, .05, by=.01) data(chemforms) atoms = c("C", "H", "N", "O", "S") envipat_mols = chemforms[!str_detect(chemforms, "\\[")] envipat_path= file.path(out_path, "envipat_mols") mist_mols = c("P1", "P2", "H1", "H2", "O1", "O2", "H2O1", "C0", "P0", "C100O0P100", "C100", "P100", "C1", "H10C10O10N10S5", "Se1", "Se10", "Sn1", "Sn4", "Sn4C1", "C2H6O1", "C1000", "C1H1O2N2Se1Sn1P1", "P1C1Sn1", "Se5", "Sn5", "Se2Sn2C2O2N2S2B2He2U2Na2Cl2") mist_path = file.path(out_path, "mist_mols") human = fromJSON("/Users/matteo/Projects/furious_fastas/py_data/human_fastas_small.json") human_path= file.path(out_path, "human_uniprot_mols") human = human[,atoms] human = sapply( split(human, 1:nrow(human)), function(x){ a = atoms[x > 0] x = x[x > 0] paste(a, x, sep='', collapse='') }, USE.NAMES = F) timeout = R.utils::withTimeout run_no_timing = function(..., secs) try(timeout(run_test(...), timeout = secs), silent = T) run_tests = function(molecules, out_path, thresholds, secs = 10, mc.cores = 5) parallel::mclapply(thresholds, function(thr) sapply(molecules, run_no_timing, threshold = thr, out_path = out_path, secs = secs), mc.cores = 5) mist_timings = run_tests(mist_mols, mist_path, thresholds) envipat_timings = run_tests(envipat_mols, envipat_path, thresholds) human_timings = run_tests(human[1:2000], human_path, thresholds[1]) save(mist_timings, envipat_timings, human_timings, file = paste0(out_path,"timings_envipat.Rda")) isospec-1.9.1/tests/correctness/envipat_results.tar.xz0000644000175000017500000364452013373520171023230 0ustar rusconirusconi7zXZִF!X7zXZִF!t/ɔ]233-M KNO5r @TB=s+,KubsWV{?n9 } Tvq9(MiPz4 ̋S5/Ow7#/ C!->H!cjܒsl* ;q\+i簼8krǫǹ,Z(gdz$X%PX'*#G{w$MH\>CQ+`f)MFeh|F9PIz-BN;~qY'Ow`۳|(wk&T^1əR8ފ<.]A,['SIkXs='ݶc ?':G;Upʤ0&M'G!g<ڬ)Lu"a'(N7ы+W/m?ݙV_d{’yޛR\_BlXWLڶiG28ؕ>{b*`Կޖa Ӕ@;~9ذ*Q#Q.wym-]ފgu$M_jޗ0h.'3[1Ǿ?]'1݈9{s<W{˅q iGXN]l8o m0"rn^KVv1C1]+PPX3 a9OML`R'T{Sg-Ϧ5|4[/da?-g &>uv\ÅJ,\` Mk[drM ,}P5+ǼJ\p,CL >+>r)3EٳX|[^®EpgL|Ÿ'_.$ս\ן=ț%YgЊ) ;yѿ>HEt~ᐑh [^̋ udgn:!-p@6b_ڽ"*5zqK|B-h6j'u I{܄4a,ٌ&i3l,qmx` ,DMFhqYޞ7qssA B;H,ë ၅u'آmD,gR%fEk_QSH_r։T(YF@o:c>W?bD `|H/B Y|nG ,}n~ +hdmj֜_4Pγfi78F&8+5\D[CO#eA?JM .$ee~YC .:rrup0.g J±0MwFqÎ%;m45#V/? #hFWD2{i9{qA'"(Ж@ N YZaW]1Fx aagչo} nW&P 4G.szvUT*<&_p=Z%Hؑ|} .'c:qN*uNr.5JaϭXmNU)lHnO|QZ@FsACclvt6#޾gs{c*P9*X-Ԛ%duyJ$Gp2AU 0?Zc;B1_25s Xk)B#%Vj_pkPѷeE>:3/.O- Wcֺ8j?ܥb圹ȧ˽OtC^aV }@y)F@Ek#k}k}<5ꩴl`H_PQP݇VH 6ij! `DCPE5rzefDB eClw т9:H(I8Ea0?Q98@(\l̶07uش!s@|Jqb VҘйҼc ݹv)>A5>> -Uo^)탵 qWĞPc#-ܗnyjmF}R-Z5Fب[q.X//Op+D DKr!b){=bhMСkAiu'E'(ΦMC0^`; Q0H x ئUa.: Wsz?3Uf+VO}숁6䙢1=i (ƖuFMZկ퇈tFB@4@x{gZN$[`7y(B U>dO} m"GjpmnJ*@,e 'UQVqH>A1n`'oO_|-{[r 󶨠{t?F,sv`XU Bj2akn]BW]&mQK*^S\ǿܻw ڌՅˤx. a1+Ư&˺2 @oqί|lě~lKia30 ePF"͡Т:tR>*zZ$D-rd] ~N<ˈU_O@:S7ݥvc-}$nj&xAzICPGad Ry6eqyGtƖ3s[J? ƕh={[?ܔND"yr%lx SI#}3(aqOo,uy^e%EgGYJiL7>_Ϡ4 %0CWGJ:$ILMf LvfX3ʚ| K#~%!"{lx(Hg'qǢ z6KXV4:u<1;uOJ6h%|H)P_V9vԕn33f^u% d⢈~16룥tp a? mh"EHAg]\N0lՖ@N7U6H7jfx B;ڢYE! K3UN8$~Wc\YYށk&"ZPMɕa$uUTh٩V-MKdCﱃͧD?Eɱ "06Ǝ_w] GL.Mk ME ^ .?RZQŽ1YcqYhPK'x%JVBL|F-wndc8 E_V55y e`49y09 pi.fhHϝ.qB$NBWt~-%^{)N.%?:B\?țUA /]L9C \c,ƸxQhiILߘ{@MRm xjJB( = |5sQg;Iުx8фG,3 O*3@D74bI3$wIOFݳN7mHZkt1̪uKy$("^'ch~يSM걈 `PL!"5KYUı<4'|N1:iBME 7fVf.P  /nw&+ = .[ FhVooPPz)Y|~f[W2n]cpMZ@/- JWO&ayk~H{:A5垩QoمUF96#ku|#VUM7TvPkӶZӔNmck8fE#1bajy2Am t@ +% >k l?gFEk}nP0ȳ9P%żwb}RX (`?Bcr@X~C,"!P3^wHQZ(8LƻP@Of(#/w,`y0J;Mo~t<O(G!orѦ0ݚVT7: *)@i)t.;ujm2zG^O%^31%?RZ&$bj΁*zwa:1 0gNbI8F0H)x_R]b.{Ʋg@gt\nqwx84a>I?~%3 ;[aDz=]˧/x߽^3ز0n?VHm22=ѵr,+{WP(868G~^EvVZag`,%agyC7%`0Od#AWHVKO@U3Ρ,5YN~C/8>?%?:u tz![MnW2T/AHJ @嚻ntxm^,=V=xX͘bk".h6MӋ$u>ʁ*j&jw~ŭO`̺^Szgnnߠ4kn͙+H?im3+IaK/=m|Ȯ}C|d(j 0ZH9p:ˌ ij(y _;_cBqQ~Y(M&N!Ll 8cԿI>@H}_x^W8ž3ߖVn߿~ kU^4OyY5n#J-]yQi-FO-0Ɍ |I=#ݾ7^/ZN_Dq<*ɹ_5Oo"!A,&v8V͌|is=oCY\sJ)n7Thwp3/a-6D7Z*?3N4IH7xaBM Tݒ_[o9ʌmU$1 1 BK)ٵO_ןha\XeNrґFm`ҦXJ~)( WGO=n-p)-f$ `r9xJEj+xZԮ19/c2aK#ǜMLud$;Vp 뽕eIq`Yz#D/L:&hW 8*9zXѝXFt;LoW4K &Oɲh2L+KB.&iX \Qdл0#-q^ R޺hC^<v(1W| ?" ¬6ư|jŧ%"`.G&XINV4x/ };Ͷ50"lOI _#kcqKSİKWR-΅zWkdkW'Rset}YIRX!k N Rqsb].Qk-'S*!ˏ#@@D;4q+C#k&h$$CDBcwc.4{ij vrH!5.O>R=d$hqHE=4IZp]/P 2ܓk/$Vdǰ5BBP'i?,GQ9L F4~@p%~<֒x[IGbuqxݸ\mPw?UʞƗ d;gL m&#HY4 "2vk'^}ʚgjE?#n&rDx -t Z5'7V,JGٸS!;Wb{U՝ l5rnC3%EBz6::^rH묬9i.7s唇O Kӥ}wdYm=Ao(mqIPI t-̣J[ch|f+Nɚϩ=]Rkw@+Į7w]i_ԛP9oF*# 2Έ־)ϱGD׹WXj c6qt`d|r(wl#fv^Kfe9\x98HX>)[9o:st|ސ yKă @.)*K<_ǗU E>xmBkM~thwRx9R"axl~,o|tu#wCp5[;|@6d0INC]yP,QlO0՜m lc5|7aeAaM\Qi )uSM=QB~TɺNRlaQ&p'}''9.c4իlZ,R+s 8p#Z2#A}F/O1 @4s WW{} ΋rM`ǒMe7P/*Ϋ΢{#^~#{ k@7#_(j&D=Z)akmUm`aE#e(0yU=`n xDVL:~Ȍo@A9Ql'o-r搙s,9lZ(Y{/v\m իqC6;j}rOc:#MM &A В9j^KX~wܓ(K"q4H9N 꼌P: c[pbϣeJWvMwJBj~EHB?L"V:#{9LյjZ[ "t"V4^ 魸C]w_7t!+!0E>1!ݪʇv=-t+A@vLnCábKq rJªbvCy54D@بD=݈R-i?%4U4m \ ~sjNǏBΨeDl٦ׄPBԸ |^(Dg$t,h(ɢ?ۑ\X*~ (hqw~o] l5YHJB}WIߑmq4TQ@=dif>;&o ,mD zJ)cy_ ZAL6!|ãV"z`n9ܳϥ%:Ac ?ro;*MCn'(S!+Vnȧm>SwGܞ`h9/躮oU[Nw}VHJ V k= b,6 ts8ztR X Fr#q=nɽ[ kRN 1d&ֶ?*\=ZE>ȍ䲵W |/Fya{!+Je&ʁ} gXD7(zukJZ|~wr0^Pgg2?het)9+$L$HXdsVy730f`|mPx=c`15I+DM˵(^z,l8j;`uVisfF !7G~3SHN\!i0@:NM%Zݛq %VcϠ2y\يWzGB 7zK0y%u03,sl\0kc R" ۮP I0`YG\ W:+W"7ǵ\fS;Eh`霐Y1P AV]nRdi8;v -6TYlvC$pVvu6+섹:VFňf [vI Wn`1$XUzWZ(;\z {]B]^ࠖ6{#x?Kڭghʣ m;X"-}7vڛ(C` KJ "";@ *aGuwK)MF iK]4GR_]"C;d ),0L.n?kܟ, Gmt右c/>ڴ9;g@<ۙV?ɜE >Rg!Ց81 0jlOEt %F1`m %X+)s{ $* %w5̏\S_NɕzC&y a[&y W_s5)A9yR q#m6LLhb>O;C'9<*mz_R;V<bMz~3L\b:.K$,)O`V)1Vk $ϸU ɅkDs썪{j-NH\fwaCt!PAlB[evW$tFMGW:W}<3c\C]h8B0ւ j 㰺1 4Vg푆a*,^*4NKY8EN޽@^bRFno͝|i5BՃh:bY/p0#kuݯ?-Nٖ? .J7nq/HyxBEc@ra.qP7o *H ]Y\0z&F;@˭W'ٸgSAW  'Tpʱˎu갅>apPNOQ2&f-Ըos><43\YRsEwPnq`a\nK,N!Y/ 0_{sH79&Ԉ'xൎ .bo[ c3" L2\F 7! PUFǁԉ8K/ԦoX3Z6唐yS^GeJKp`jb=#1 ۿ01ϚҋRM-X:!ȦaĆqb6#7 _9%U%r]54dӔ2לLd}WW`k/YJ]S5,Pawlth l"J`1VEk"x^tMK6crˮB[d7`qP^ 1KZD5_;VC$ĚVRᒨl'TlθW0~Px41ؽJ齂 kCsьBchiCN,9Y Ti#pR+.qJ F-0od4wߣXky';A*ӊ\@=ĵ6*y+*/8Z A?;-HՕch vR;Kv[cc_W%8_%1 7` $5m_b:$HOq4%biJw}"QbL6 뵡$oSp}i[ ?fRI>툙]TY'!mP~mHز[JMtD&׶_A7d+3aGUg>uDI; } 4X&aB*WdYDFDABu$ +}^S)MwU(P^2p*!pY@;Ƅf&КS~t8IMoRAoprCxޠzg˶U)E-ޑCZ߇ˆ6b;De6x2Į f !|*9 P?ܪבbĺŦ'3GnF *Js\ȶ&:“UOi1O^Rg.(g"m@Xz{RoUAjPo#mSqZ*YVzfqlv(E~nw1;mF]C؆9wH8Qvrwݽ߄ Ns.U Ƭ(|?o AbjD|1D֭B)mXRuOc[0,^vS_Po1rP>e#8 =$OQRu欫Nblu@gJtF1~#b#u>ˋZ#;#K1hr;1 'OoI CA(\hHl9>T )믭f:Kl9D{#']OK4*X4+LIA7ԯdi]cCj#Zٴӭs`e'Peqg( 1*a/` t^+WҜ ;E2{v V./(Z&w|-FM>=YlY۷H\ʪmOhK.%Δ'd 81&ء$Osf{pAuwʟ@ETAɑ ¡A Ae"ЯuW9G otNZ&=ocqPu>A-@`s8 5@7$Yt龣n`K`]+kɣ u -Fm0+=$t6Z: L[;Z0'|:Ӄs3_oTqW0g2 -W=U)xa8Ero OM0II@ .9~m\T8AQ-aXy*9QzF:5a{pI1A;6| s)PhEpE]EUF$k@$V3@<ڼU cm ʠi#Oҥ݂ [HHV0  1[0diF ǗRBؔ5uVP1rkyuքԅҊ",MD\!塅ʷD\05L}" dvgCuzR\GIqۢH ٣< !4QwL)3ŸFvj^"~YiEV@hUA !J0[#۠sz`X_{k-ZTbu ઠrhP0՛s^FHL"|rl>:ƈ+.-~- )T(;^\IUP*Yj8fEۢع-GTu!O564МT!D/mp\g;˦4nz&={S|^&ZWPSj"N,0DŽVpN!Guxs_V1ꓖ (xP*T8Y'YEfUFe5bLє+%XC,]00NCXr325H/l <o^rC 9>`MlNeƵ|&lVŨjƀ/)5kH64rوv1+rtY;IoaXy7NShO |q!$b:[c5xu.z=<?}PV9fiuz&Cg-~,a^>72Jba-h%K 5 C>_/PJڟ&lW]!kM s}t[ec~vM&=33/:c ]vf6tvU 'Ho&hŷ-䲍_4<)+$Vȝ rͿ-5b{ q?0>^-7ز#T6$ć6Gi{g{}my4m_ilT?ȸH , \ű8(Оa.A-bӃӴc{S$g# $x F`c`j[h J9 !׎7!IʌƆh_}kfiB+X>cV*. eŊmPmd\gE6Qdrk`2E쬔gl[}۾ST)ڀZq2s!mLT=B`K|% u.\}!S [RZ\ !`D 2]7F6ϺT5XiS}0k5 Mu%+ 4Ϩu-IO@NxxdEGc`.߯61Oڼ[2[>l#h?F`Na.ΙkH$Wހ&S?| bTxtnڊr|;R+4 7=x{Ξ4픦F1 tXdS5iΖYHly0TgnyP qjUVIYrS\\4yu $nQu?>%ϙ_vB,5R0#}6Tuf,aCl9uMʙEX߼憂3t1.bKeifyvޮ6zAy@Glv(v-7ܲw˺G\ET'<b&JW&'%/ݔ&̭sWH T7uW1E'dVq*$f CljW| r'%)wO15JnД?xaMY;Y dEb2٢&ИB8?&4R\ [BĀ*ɼpE@p,+m*H^]y\C|ɀcx޼)a!dkV_(c8t-#,XVT=ipB(gP}* MommJS57'V;5,Pa :4I·VAT}( hQ#0j+|ePG/u<}0BZΧ~iܨ%<ۢ1|@lj@"dwUR.z6W(Z+& \du"ʟDM:D*7/狆9rKӻi0Esִ^8[d {gU@.meJ.O:bu/!!|+-:nKbPlg:.c~nx2TNvv eY^jBCZJ @Wr*ui{G5N=*@O@ezQNuWK<]33M Nb zpEzh`biaXoCK:}gMIkame[iBG-W'RwcE;ɀlq,=ug3Mw~w=t"564!FX[h|(@;7C`E-PxM{b; R"=O L|p 0UX& ./(- t޳^S;|@i= )ZE= G>? vZ4s7QR 5A<#7 ͗EIsun[O'R7t1b^u7PiӒ;Cff]ԩ&ƬٯI\]Zqy8G`5`HAbl^Em/٬5)(n-1b.0!{ @sR(PiA"-u[+B W I()gBeN੄i4\а!p~~#ƆmUx)p"?[?vQE@ek*;ۀѓvpd~c$f=|,g_6+QuH,U91U`YdP-(F:'9`$H\ܒ3i{rN;HA%7?s`T_Pr-@*4*fXk˭ j@gͅ?j5|sH80o^c)$BHM!J.u|$yij+f6 Io&g&, mMAGc#{ +QD< ~$Eٻo~a^٤J;pT9YވYe6O `NpP%-LֽEػ˜ -n 6P6:]6)ԆbA2E]cAVy^C#bgG.vԅ*? ?!6e|+P0ND4PH+Cp#ָ/be+"ym=Mkr;K,-XVqca|Ӑ@5Ml(`x`}Tg`ߠw l@kǦw%L*T{dJC^-/(CQQԜ[f&,9ϭ}d!~vJyM{AzT6QEC$)~FboBcU67Zưr)xXlȪHMDQ#l8@ݠ_ Kp44Y,M$qVFiy)L]-d)+#FքA&.tv5:z&h(؟=be8-X˹yڍVAJѨcj^Dv+~i}OZx"#,،1b?3H/ɴ,a֕n%/IVwcq_+M`< L8nވpA?2 4Ls7VLaOP&a͐3J(ϖ/fIui!/]N?T3AX  9۴3< y'G~0(:e4ܥ~e* lW~D#ì{h^~V hǁ y6QYu:-` oiҰ3)tISA_oY#yӅ:.CXNxҭ9*L%Ak{6]Szհɞ9&O]ω"o_8$B|8vh0 .C}fђqqT v^z,İgӂj6N$.?>:=tz\j9s۬/4D^|b0rԞ?0%((O Ev7r\cd26[7VPh3Pw:tD6XX (X?[~ߖYBF[Vji PA?:WSOۚ@!ǪM૒ ϣQɿh^bdVK NM?[f2ߩUֵF#TěkZʱeܯ49o?jV]"挶XK\~=R}o1y <& l5u}Z80UٟrId#?VWS!൘#@ "KԐZ2/(ssُ?jfw>'K2uDˬJ;`F?nx5`!Rݼ U囐?cod㷵]md^v>M>@ߣ<İAqBql`KivEq{5&0*_#J\&~ H Jw[BqPi#|SrM5}^1XYcJul+-2 tٜ8LEՖBNr0CN]nO@O-Q͖؊CЌRJGRC+3uI0".ikœn4 _a )+,Jz-I#׌$̤sJ|3"PC)JE')ol4biP8C -jԕܾ7YR.)" zL'paG7xg(3y9%K}if/qE/R P84yEԀ(Uyɶ5 |.xc~<|]Vof C>Yĺ'y\׈C/hG}ϙ.H^!˽ğwH` nEWIXr!?lubfU1C1e)u_0STyKykuÐ}p1Xx%{a0o@!ىyG*AS񗝆gПHś|zy&7g nk"3yݩXuK.H@b`; 引?88d(C P^QY;2^=:t3bqW<*G"RݬmԠ?ݹFAH.y%[`n]`aL %t߁%0`.m`%M|L0,VW T{?$cYd49L μzDq?d/҇<̉xZR×aj*nj8+SkэlzkH#gN[o{黭(!GiB wȌ/ۑ [Bv%n~*.JRq 7V;f ]6yi4(l0P$/tnv +UjsܙC}jW.WRtN}F#pt DukZ~9 WzjV6Z&zZ& ٦A1:I&DJ*eHYl!LisQ7$ai?[bP\e|+7\ %3OjS=FrNv )MNZ>,x†c! 'N]qZrbP'MgR>#ĂnpaPѤjތ;l_% ¥ mYV:2n5dkǩrsÎ; U8nX1oX̙BƖ;A RSQ=(V~,{j!"(6+¸VaS/DQXI@K6"'T($j褊)M:G~OAhr @B])[oF- S=)Nag=B\p)>xDȖO:mKRpV\ͬ@'~Ezf,l痠GۯӮSRE]x<UxSʵ+ gVxȍ՟ʥ SdR^xU+>>U:7@\p䟧>u:fȿi.i3IKQ 5FtV4F(韒фvpgM,$~N㱦P!+Ng0t~}*;pOLWӺ"v*Y@sW76jӍǩľ l xIwshrPz qu NRzF߳(}}w@j? UIJVv7d**6efuzdӜ۹ Yb/ ahpL3ZfسD z(^<Eg{-! aDoCL`ְ~[{b0⽷7TKk[qS3,C qi|!rTc<+dAm~k\?0ʗeTh;%f`eHb.kYN 5W U)ňWk$hlAڥV9>JG9ݥA0[Y80۷4)Aq=7 $ -S-txZ5 ୴IqR]JѦw9 y!es`pGݞg.0݆o"dNaf vMKYy܎Tu^PZ+[[mm]zhS{{xtjؕ6t+7vU/ӤzͭpmJaL)OR$u>aJS Oc/7s7ңLy+V8dݻ_m25r؁@E Lwŭb/Έ%֐2\q/5#^P? c<~Lt]-H:Z=![s#EL ־Z*^J_ =y]eܐyyRuE6j-^LMa+$_1/DKHziyά k5"6{SƞIA%kDwѺN+ۖuFvNA4Q(P9:d \B k62ݪ2j` t0B|*%=g0ؐ.z-&>*79K%_(YSTGڢ^sX_S$O#gwTjN-GV۩D78El!@an4Œ\)=N;DE?$T\4=@"~HN?w,jI}H߫["> ΛB K*:fP5y{mQ.RaO6B ?05 {k?a3mU [Rw0tcQ<(-5ѻ#\AklGܺ{N5I/5j8L]RwM=`a7' 7R˯(kX.~j 6ArsIi<&d-#ZNbx U*D8PT!ʘRCzArH.7fٿטȺ[AC׳qv\U=C|=oS~µjEs`"tPXbK7D3Wb C7Ԝ%Bokkvbd"&ȯMoWŎ$@܊roiGF_ Mi9{#Kn]Q$tز@$hq+ n`U Q3 W"gTDv|D(yC 鳲G@M&$h'f ( ہ.i2A5A_."Zc _գӂC-a_G2}.oaJ=MfVRic !Sm&Aʻ\$ {<NxI\[B(I*!E~\cy"Ȅz5YY7*\Bd`2ł~9v-MJ=to٫jD$]"X"Eq~Ȭ|N_ 96 HsGp/JB#L:6׉OamTοeҺȖ>~ZKJP{pG"[Aw"َ0焺OQFtOLONйJ_GV%ΝrA6WM̆f{ O vE0_Lv}"ni=blCeGϠ*-Y;- I$.oRl ]ajd$U+)2#o;z3sm\puY!F(ο]2De5U5\S 0'?&o`ǯ(9ʊuV-mnyIYw5P2p|bڊq\A:/+͓d@ O'DMV`T e?.ɳb}LxiԿj_^uLUksūJSdcM>gM}yRqW j*M`p%/r4lr6Ntc^V$۲j.#g]dNv*_2#Fe z4%U]&B뫿zNK]e_bέéQxۣzV/]trɏc˯:)6C@A@4~1=YA6O7Gq\8H-gc f70j[yyb'q[nwߩj2 <5MoZç|<;&܄[LS)l[bЎvmZr=k4\X>EcMgvn[ _}IuJ-q_= V("qF6XqNRF3|*:ĝB"O|\Eʌs>Fà OB3QڼbY ~W}C{RVhHʼn#6'Bt b4=R>) (Ϋ &+MU@&c:BhO c6`zį@uJ?I: @@t\A2SͲ[#f%(׆CoXlV9n_E YkgUz ٩H Ep7Eeg/M\ 0N2US$S2dg'@FWh@5A"7v|w$385@y6K\(J:ػK7@2{>'E!U9Б><߇)5Rj3> fVYb4au`4cJޢHHT13AD2{'+|4'6n-t3Eg̓=y)4;)y[{0iHIr_,ƆN[A|mn?י"G Tpw3& u|jbxU -B<Ylf?%_|cЇ?ƏFG7vfMc`#HY\Gl:*2!Eppp!g+; MF^ϯ2!b|BD]+$[h6hd /Vjwʺ!Ii"ԋfK.g٧~CZ+ŷ^;)|nK)ve2g%%;q RFPV =/_'uۆ^Nj_ *WR*T7}&wPk;*eg0Lr`Y.c:9&K` cਃ_vw\P.D-= 7M)3{5C$%A0m+}Θ|Fl'Ot-S^j!":^*W84wCS@Jo9K]ן4cmHVTä8k\CI̻K .vl43»/cX4}:Uj ;Uxy` ֪E[O+dm Dʃ0GV=DyP@GRw.fmrZvݚ7e1*p[|hfjʻQB;вח$-A';!bF)y(C^y5@dU}R> 9d{:ks7x"/SFL&v@ >/" 'CAt"iCv=5ը; ܢvל_ Hb26ebaSvγ1zKf((q\'HEV>w4"> d',aE*wAvN -Vl{HvZ1 8vZWa܌Oע!x1zO_QSD¨=DLӿ0kptJTT/*YY$)U>t>@9MH: S ܧugUp^o4nbTtZW6At6Zl zrm-+QiٱZi+ADM=7. *z{,>9.$vs 2(xAb|*f:vt-M1iMJ yɆnop^Lz;RxT*Hf|"q\9{wguzQL? }}\9epR֚m>lT?7EjP;HbT8Q_ӕ̕yJ׺6(AgY[rGs{v?L\ElKdL(dFC_<5!Z4H/ Z:AZ_.=H5r|~U9@箋~~(@r$N_m VsSBWm`",$m-42w Mp@:p/{LT I_?!d~]J9+!ܕwlQ*-ˏnJI=P){UZ>|Kz%QE|!@N:ʦ*,Hte!s]=LVŎFN7M29j<]8-7Nh}SuywXT#N}ޘY^a<~f9/=3}V<=6,ZEIH`[Gw.ӎSᡢld(ޤy3wE`_sHÚ&-q]N;*yĔΌn:Ic5rWg2ƫ| g~S6JW4 _/r&0aˬM9:KXٜwN{󙉹#$Q cCEn%R- W' PRRBCُP\" H?KI!.C',v$3~@iKbz w-kzWDPA` )!5% ,OP8EA 8 UxGޏ3 |b@f8Yh Z^":iMZV~۩w=hq&O|[*@a갭X֯kpc7n?ua]W֘K+N>|OHbG%ͳ⋔i|Wl!vYO0`-e,' NEeМ*OT x晍h$|ǧJfs(8c~Ab(s@رA*$TNT֙wl9x4PY!^?kcsh2TJ'9''-EC|勳2UyhmGd_x9;1~r%YN7=u91ua)X'9.fX P_|p'CVh#h]cF+1*jbiyI}rn!ɑztҳRh0}@-NcV#씡  " 0}AWuZ"0>ǎIh2rgT媄"y$C2wF)OYȍ!l!Z_abT.Q#ƟٍEWOrOH*F/r]vQ3OH7fJD6F.&K/\BiPIxLaֵΏ9k0Xf==$0CI87fSȤ#W3Ѻ|.+as)Je "ЙIȯ/*kΙFl1լ\{3dQ2 =~z!y.y+?8Pr*fqmtrDgneP?oMuǐqg-/DEBb2&,~< %b\|X.l_گ(m4q 콤kבMWx71YxM+6 Z5q%c5PWgSm:0Vb򖒧NMPlSTdp4ꃩZA@7zoӂgQ5æ19/^)1t-^K1Ϡ0,ϷJTȩOG2ջJyot${2ʪ}0BuU\O]C,#vH "y r D<9; ~9T!yB>Dpݪbl )z*$R7& MHh,>ok_WjA9׮Qp1m~;5.Ƕ,1!Osl.'HҠE,o{Ě)q;5IC0J% ˼m0b^CZyT~[0ûM"3q]-휾t4E^1Od̩ ++Qdq}]ôi %s{nzcQF cU25oʏZH|C6Ω*.a>|rYy(3|ڿ]jXzSd{Ea&4fZh{SؤQ X[֘5?^QlgJLz$Jt4Q‰:r,pXq֝QD-0C%Dv[1Je|0d]fQ8D 3_٘M&o4Ĺ|=UH;B}!Mc_xUuA ǸҢou[Sm$68Bj9iϒqv\bl/cg^ږa.tz |jS".qM~P*`̆f(\B)SI6xߔj@Ecn/Ƣu ڝ Ne4B2ZA;qI P7CP1ŘSGbC #F[ ǙZm*ȣ˴\ @M0?O, ƈBۖkj1WƥS[;][ӞE9 o.27Xu jJ~Jb.h՝Y( y2$Y4:BLSC/3p{^ uYsW.)$s!%ߠ:_${M̤΢ .A5z`" ?3R/=@~D"Vc{]΋ $qN0|#oKq.2"rе9r2<6G99!~1¼>~7dz<|Y8wc+b)9zhJh:"p_d! gpB@} k([0U|8"NX,Rfq䚧/m8Y/6 H]~1~tKx5dȼL] lї4\{PRp+~3rp] 03){y7~d{f+ho^[j )_n I>Z'Esuh3Sk+c GG`@:K?*{r"x {$(q{]CfA2ԩ.ѧZ 6pҐ諤2JyHF 1ǜuBt<,D3MCMQ:˘7v  V\} Qj l2ݫ2AJh\.5(;oϏ.Xsi(pz~,nL,^5RsXMM?CA ;ի!yOHac>4~wVvvW|ҳ@FBݒ/P3=;Xn+Bw9_EZLx{E|{`% Z7jڛ%GHJ]q_2$bc'1G=(5Z":TfDCZq^̏ϚyO:O^Mȯջܶ -7 Mkʡ:;/O=zf<1Bὶ7CuY6 σD{31UUP Л7Xd1yNGL߈W K)6|8 f1 ѩrgmő8zVZY*ǽ++ӷO\Ns?JJM o~#__mGfIKӈ9Mȡlfc)cWcO:cRss?8@~I J_oM6\)GuUٙ"eK{E@1}ʣޫ˒jH9͞'UIS֚hp*zH"4w)3L& KcܾᔧN8|vlF4#!+An' S; \3a93U Ԉfyt7)lY' 7|=F%̺n0`=Kf佈~pY)*/ cxPSJ1pPέT7 f |}KxśIN'lS 7ä=1G͜fii`B {ASg-tACia$fM,P(14Δ$*P rE!݋g"Q;0F4F `s] #(}Dp=!_"(`NtE&dFKw{~bB^;". HN}؞Ѥ<+Znʙ8p{Jp_q]]-sspH@YxM;7 Y+6]jų#cȒx(6B*K "j _,EmX3_aO`AGo]c0{c3>OP(Xs3&cjIvY'qm &M_Ɵ:CB*c6ft*ҥOv WK5Xe @0At7mzT㫞IsyDc,*=x{y/TQ)(ik"l"&ll̄};gjv*|Sx5CVB9{+CWWgwpy\U&Bo<>827Jד{z1Z.8)۷f=ձJX3=#fr%,r|ZI(bFf[ )*T#kCT$?7Q]"w`/yf#Y1OYH6Rʢ@-{?Ӡ TJ&:2i)R+T wa^'WRŠqUKzJ3h ΠLnB|Rxv\R84/4y\.^!qB e}ˌ҄ۨLry%WHJe,^Ŕ,Jέ_jБ2 8;|S7 ! nd^:cZ[T~s gw-'o`+?2hPʁrhqUd3Κu6) 8~m8 :j#CW1JEi^C9oMnr# *Y`"`P6-H5pP&G|W=ES%L*G6m{iwF:HyܐĜZm.fҦfn gWR<Е2|n)6:֏*dChΩoxb;N#d5bzB CG4' s2X8pW%$58.R^,}[>AnI~n++ByciH5'aC[N[ٮ3-W~9 'ձ~@p/Zԣт3d6Hw4^VPbaPOuR,nۄ!6zlJIo$W9?(S ePdt>݁9YM6A (uPcEh7?4}Q8x\UF}KbpL~ 0=c ɢOCn~ @Oa.'GWy(Ȅ!q FWA8RGa?RIUuozѐу1zej~7&)pk d) />%# "a D\iH ~M|=pveUV~c^ %،Odq3w`̒"@C#W)[hɕ+V~j+zmw>G88hE*vrPzuNyrD=ǣ_зӒ9bz ;g~-*:;}TQ^`Q,qhhSݕ,|م}Xn&|ߥVzm"f'WX!yaiS`s-҉gQ4-ɵM,zv; 6i|>;h4I(}Tq}ދW bRWudp-N2>__ɇܸcru.p}i a9b^-KYcly+z>odmT˖YDq0P vyYoWR%҂g$F(|f-]V4DWoX?϶]LVh{h`g)n,xE^}MەL'+:UY)!zNWU;o*=o{;ysTQ KKH`#={1YD;A6?ffTlRê1 )UkQT4Hy'WlġUZDN}2D$3,U¢=no2&˴cpvV٘S&%ç[b-DK˺O*Vd U+Grq2 3~޽JcmsQ~0[!m2ԋ@ɤf6z?NSy }r_ix_{ėaX_x3B!e7t&Q]Z A%/k~xRK>& a8e]O 5 O! 3V)=˼b6"ji܄S$y$p&}9IΒ(,锿7rjn!K!?-pRϧ^|K,+" $).rV}]e|xx )Vi70M>ʼn Z*Ceaˊu.UnD:ʘwDVMH!4V^A'e<þM(\îtdP `Ҕkó+0 ۺO7jL9QYU^+FqFQHr]FN,8S:zMp0wl[[Pt'Y/` GkH'Q#jR }]b6HdE.ͻ@na)(ã!A!/sEЪx &"u,C_dBqA/j$5cr:Ȳl=(o{Drd#^=4wMMR2 CĬQ d=}eLWLj؇Fsn,L1H?J ]dX%ڕ~bXr*_Z>V%וV:,bl;J,sNݥxUeOmE'xbHş" }* [%1u/1Lmtwr=#7>]DH0t1ZO4I7|2hf./* Iԁ>[,!5* Y I<"D}ґS}u^k|Z|mva_oYƆq9q^GCk0K1Q689L _l<ſXU-NPG -h.KOޔ6uR{4+ZK7r"F,HB 0ȍ ϠmߗS(t~:Q͙]X@dmPqo  {1\6g_đve6;FR{"}^_=]PDlS1O [[s_,$(VӃvu^9]YAsv>lorD X=ߩNqԸ5tnKRZoTүⴥ\^\롩%`#1f> "0LRЏ>QƈZ,RFv׫oP{rQj {H[??GhcA.wgĕ$6=O{k;őAemQ#C9-Z7D-KtC}@+C(@Tt}Ϯ2I&jB\\ɴ}QAo%!G6b(&^*ǘ봽Y`H"p$ LTLWc]'fd,fo:V~J$[7Q? 7Lz uO#<&x SwN<;6qn*b;NPPW|hf ` 2Y XDYf1=q ӎ1m3k6)9%TK02P4 Z?9s 6@j؂)?"+t\G mebc\UCw)BtRtXɓ ^r{Ozl&WM=1쥯4> N LK zx";~B;(0-S쨔Xp^牧H[v>s%sq64wo*Ӯlf@#4 hxjH>6b%Ѹ]˛7V><пY[pxQ^Ro -Mn,V4nd>ئ"_Bn0^2q)yY@ [&.Mac׋ٓC[dc#DMNzy p03|ZȖcL&U Sb,Y-$ 6J$sbe0']n82SOكik't!g &2h9ۑ|U:4o' /. E\+^vYx.P)`+)U `JwY'-Z*x^Z-PLLqj^)  =L{|r%7?=~]qbgtt)-{[1d4ˌag_F}B_>a J h?SeRpo V\N'ÁE_&P݅ kIP_OLOiE^lbk8{3]iKP8#os:.XIi!V7=TJƛ=6:𤂈ɀu|9sTs$ rmb6Xiv}Xl0ڊqAQI{Rz9C;L9:l,`b{>ζ ڊ vZB~uO(828*9RMLO.qDd%gucʘH6Der<-0Ҭ 1)m{i#$i9TjZOT;jCbV{Rذ󑌷/5HCKfU/FV1ʉ Bv)Ig7\n:3x=s-ʼ8J"3 4F'ЎN"),ic{  `,bI"_TX{{WǡzbUugtz̀Zј߬.I'y5g%wZXhG@;:efT//,n[Dãɝwg$~@2<1XIg@?;7'~)idG$[a6$ԞuGI#@pp!_- !q ~YY{$.֐c=I=AUV-D qȪݠZ~P(Wq7]3tNz^[BI!1;L,0 W3O Oe٥8QL*|| P2DsZ0oZ09 eky\GBwmZT_ #~#!`D0jʍ Y,P*2`DZ)#Ds蝣_>@ч PLˉwEbOFP3fWRN^o9*; m(ts\Sn Vw|'L:0sѵ, E JWC@Qԩ;iBe3, +4nos-H^ _*HXnÃP޴;=_'5 DBA#A{`|((?Ce:l|w$!!^͜*&,8=u d  >^Nk$uv];b@ r+ꔮ zESO!lW jjy2oH ok;G߇ȏYku =aj*u콰v9NMty*A+\W6xknW 2-EHuȪݰo_ؙF`qh,22"ĕC1ͷ)`̤/벹hA:-'sKAeWk K#Bcv'ZA ftz|JbS'H2Շ( ʷ𻿬>to-97tn1'n gy75}n7<zɵQg*2`1*;8E;:ԼC1[}ӄл+Zat:K2ֿݭR,d#d; d7 V: b{H/UN- ق{ݏR @ -.E}f!Jn PGS+ٱ4< Njǭt[.a~r?.M@p?, [h]2saC#st#6*.NF{3w ɖ+sߩqW4r#XnvmOVSZ!<_a.pϸjpd-Gb3p6vGIP.~OkKBH7 JC.lО^ E6cNJ]qC F6쨱\RemH.3mB0FMUDxCr)cC/Bi%"D? D{܄A7Z^`үI?ϺeֆWab~ )bseB\GCBN鈀+Cmbx⠁ (aչ8Ҕ,geOi/7k-Vq~)XPݮ;3 Ւzs<93to#aޚ[؉]"Z[Mor*}< LK|~2XJaٹiJa@o\RQ3&N觢9a@ wz^-r%l{ <[;Ē@P5{yyiqV9v֣ J9Cr~›Ur<[L@s;v.`]d#qKGVݲkSJ`ɈW\,LߝZ [ ހ7`V"ƲeNe[zU @-M?1"`n[l'ɓ2LH=hQ/+O:]O2H}δ]to5g, f>E$e$#9;9Gwĩ9굚75Ce]wolywLK"|6'|K.{'Eڱvv=H5 P-i|"ȓ@{,Ds hѡ+֬ ~4MDS֡ʾt ;yc˥+Fp[hN(ۑ9Q¦wb9\H7y)~4{t}}0YQc(n|bn{&Irʤ}NgK:  9m/;k3iq(E1hp?#GLZ~R}[.L0Cy~܅,diMvwUks Wѹ etx IoKtA:0TXnDXYol:${02n_#s cv/y͑MBTgLRcV"+yR*3*c@l?П~l'Ջaѓ2ψdT LO7žsAaQ>$[B-}o 9ү U`N9w !o^g:)^Ǣjˈ\{qNyP1#-} [e1%qSFx7&Ah4a!毃~alK}Bo\I`P:)l[|/|^TƷ ڱ=rv2_']cOsŔ!Bi@#T:P'>X4x=bsi2ibM0d#ERQ s&0U9<3Oۉ[`t"!EaͰ @ S7ҋ eG#f6q9|L^a(Gib9hdd`qh&!l\$V IJ-SrnH+g S((.#z^Xl1PJa ?Ý&Mh^5UU/wKK4o3L-76柧ՆGԋ*`~j{xåFb1qʫ5 e,0}xgS[j#~ ps Hvo'[IEDa=:[j@㙨/ȿw;ʪWw=BO[wP?aQb8߇ֆj':* *R~z4G,>@yDzw1$- u sN!N#οATD2k2Ёmy5l=`#dgxӨ\&tԟ6(~;1A@G GG- ܸfЎrpJA*WFف\ou`?q.R^Fn9b.1ys_:DPTbne$ 4R1Mq^O ,H|zWM5 EŹLF-(b@Z"N%^M6 0NISŗ[,^g|…7c%f)BqS̛-cw9S>lZt^aL2APԤu:Xo^NuN{,w+تцqnBUO5x[y"6TD rfǴGg,hᔭ}#1&G*Áqvqe?f߫u j˚$g3Xbm9ik8-FīCA:<5zxt<Ə<jCZ?̌]>w sK(mA r^oe1@u#ûp.p.0I%gE5آҠܘ+c٭ysoκLdh.+r3ϿujwU@^y:Y}Ņ;|r^NJp΀ Fd͋WH3_d6&i}7TF!\sDmIVs Rŗ.+, Aqg*"D!oveO8.~'i'r0)ֵDpⴙ~p^ YN܃VT8@爆 1e EI0gMeKZ"s7#k팬 9M|6eO2xYDW~f.famf}@ղp 43|T y]d*oc|x& &0jE2/c`;z10w){>}.o pZgXRA_ ve,۰'X-CSyA5 L(.YGno}m_?[[k|_c#O-,W)8G&k~fԴvu@gibYd6iŧHvQYfI-b!$޼.E:/?R3o/'+jv) n{[eHԔV[62uğ[s!:u_smœR@ 3x>avOJ6lNv=_r;nsQ 1L{ElMA[ڄ YتྪJTܻ߾KOzAIb0wOaf1?C2 08 5cmxˇM"nҳ5zS~h^ d=v eKGNw:E- 6@B)6.m-[T ( g z Y/\zANPa}~CO+,Vr2/a~yet,ΰ@Qw9NtmTf<_^HF#PuH1ByaP[\Yy֜lxHc~ I= r O BȨ;YRnȳ pI\jUw/=Rqs#skEI*Hs'u95/fv𕢏}AϿ@U.Yu7ṫ4-yLdlqBjśu gX̴@1L*+%=X7K5iv$r DAo>73D:*:F1t ?}d_яNI-fxʶF Mz򈉥 S)%p? _R}=gtӧԅ2M -s!%y^9) w ^JC1|r]pwk,Q\MH#?}>~nm;^&ts5{w(b`D,+?ıːokxiBˍd/{IϏG ON7ꟿařReɠyjEYJE9@lRYZ3|Sq*Xgcw^rZ~=<;>-?s*a,-+RTV~hW3&kN oNs 7ҞzS\0-be!E?5jX /\8Nն%{}|PA*HvVllE}Hu5T%b&?AC+NO=6 t?3 ԐQv$4YʓUM?%Yj׸jp?y9KqNsGIRlHyyTvT\*_+ۡBNŸP8Rjn_Wg4RywA`GaZugg^d6b;Mw$y>zdF#^W>IRfKoKhQe\lSr= DMNtINW+<=^5|W4{O.RľyՅc2)'0h92MqDDZ.vG%DHC~_A$[f7/kΛlpzN^.tWB"j$|.0=HƬHN3iqKDD Y7||G &l!]Y]w3Pۭ{RZ>Zk]Woki!< &Qsi Rv[I[/U{~S;m`wUV{ f²PYJLp29J\81r^MP35]źaTA%k.qW@{ '_ cH羍VMh0O*Oz,˻+ٯ&SX !sO>YS&^h=;jp~q8{?vhb>]ÓHʂB{Iɧy1") $F,Iw3YĔ~p'g9"&׮ =v 3F2zL2j7'`EZS |p':Ij'5H ،ӽbrȔ, wpbڒY\4"ϣQrcpgkςd]@/b_֫x-~![v$`K*yV/3yR_w_1fIM>XP?)ۄ>]iDi0~ms,]I{`Eӓ%ʊ]$Zn:)` s]cFJ;saQ@+2.N ,F,k.I="J**Ɣ1;>~EXsӴ 8D%.1'T*k%`\DYSM0)a`7ҧ*%'vՠYm̏E8&yVkE ު=$XN-j$p_;GY:PL5;AF+lENs~1t ș>ԓ%;`| .;ĝYFrih2`q+2keA}uaes .^t3)(y"_iFy~fH "qZx_%Y>eх)>CQ#@8KB`ê =bb_uO6@P%?m:N4T=Xèu>av6)~R5%89R)+. L$^1?R\㻙No+'Y|^:odb~*…2uGfO/8ävPqF&ᙁH5EDf $2%)~'RП+=,#1G|1>t$-k\e0 XSk:̸3V7S+m)gD-u߉sv0{Ʌ(%T]-uǍ&`:Sb<pA 7RK}]Ù$OތK\D3~;,ĺz pv 0x^+;#9//]@dP}e-.CJtWQ2 `nxw & F@ X}1$FVoMIuh/mM0]Bi}֦$H>C]}_a_J\:&5uu7iÉ_#˺ Ne3 arhq1ȏYO PS95xR`AZKDNQ |D#2,Y%Br׼7e|(qN V 5RQrBM,3wfQ]ږ~ ) m>wL&_;5ޙme-0!{AOL«nk>q\3_o]Hm[^h`ÀGC`j+ޓM|ΛAH=q*t7mt&w,/,?}=N%#H, $uNRYFCP6\MԳ^Ev'B3>QeTմ7粓mЭU#g鱀5+M8YZ9*a C`ۻ)'hfs8C(v?aB^~80UL$ގqRŰ aUo;$xtʍ&2䊧K۔`^yߣv"^\Ebž g)uy=A^/Uocʼn0@v,dˤmP=j2}Asm e}f3; cQg1Uu(Uυ1O:a8c֡#^ @o"]7ezgfeU<7sL]I˲HT%9BEPY)BU^4ekP ŝ'ET}@3>VݧR|%N/ey$c^ ŚRKiT wg8.tE'a$(F!Gd]#-ҏITG_98]X-5VWhԇ4泬itͨ\CorĮޞyL^ؽ50H"b Qv/)uf㟖m^ Jܰ2iUF"ҌB*%"7ͷ}8=6K';'/ Ph.qЫ@Ք!2]dsYp5OL;{#NUOt2k2Fj3$x(@bgV)7VjXGU }^>aRY\+ %es"ُDI&ɳQAM -W3SF.}GJX'?s̀b{8I !eٸks$x"|"(r7pV~u:2!=~$yE_; ѻKכ^F!K yR`pĿJkE+(fAϵz)܅: c8{DوbxI 3jw'g4h( ۶X JO))ٽûF@P BvybF-tC 90">W) f+s7s|*ik:h='!!C$OD{3d{\cHk,R6~Ns&KhcD@@Koh0hw2|F*1rƽDͲ&EA/Ck7(ׅVzWwh#TQSm G"֣9L\}奿b{F[Fm^e0Oj_uJJ<\8UmȘ-ǽY 1\_aipсk@kS}~]QtVw)T9nD<ٰ*IȩI]=y'F$݋iJ mj_:d~?PDұN\-`+~dv@YqVNØyy{hjC'LR ^<Y:k6npn=KRȹdu]7Ap-_Y*u^xqѠa_ǭşȕd!!/!Ofn?:T_cgZwr>U+gzj971H,xڞhX'aꇷsnTXj|{/{+INYrXK<zX3|0\<R)5ɣV274Sn:T8{ڪ!m9*ve.*̮iJ(dU5^DA RU;,13Wq% nYM"7F 4>dD24\"%^py‹#< $QC̮Bs)6\P*85Gn POtMTJJ=J` !87[*8n'Qh1eIT ~=9Or;اcpf&hIj,ImׯĺAO{Nv$Ga`R% I]m6}e|jΰ%6XKr>H(ܠTIפk,-|K3^R9N{]ĔIy>{'4 @WkHYqNɨJZWX-GCx%Vs{U-ٱ{֢jsCۯ;xC8Q;WHc_,IA$Xhvd-}tg+E"#Jw0|{吙2&8O1NM,6 &WS57Yy7#onF,N?EJ#>p8Ƨ*"P<[>cL*ΪN^$h{T.ާsT#!k-fp :m^xQP]i&3;r R:YvJB =IIGhیGkh0E`u?BBw%d?6|:@;,c <}WpwdZ)9v2mO91o8?lD9;F(WUY^ U I5 *kz'(obc.\;+YZ*]_{\ ëZrX`L]d=?ChZKBxĔ:W}u\#P//2q4VsG Wޒi35t' Nnp0Ф޷'c@" * G>QA(>AZ^booHp)Jq{e~t?4WyiS M26!,E'V;< YSgʈ8Q{[iS߲7g0+*zp \U=;yElY sfC7$};(uj\+124 0k`hrsGiZof#yDl|12Ȁ-u$7CmkP,>g"7LXhy\fkq/^gh@^ҊY<\SP6Y@Z*߲q%F칐 喐- ;?bS6oґvOE,\(e]u0"_XF%sR 7c#POTtus̾,; =R`e4\PɝY1}oR$ow@cg⏕w ܨb*l\l洔^ Gw)gm@ђ<{7TάV55s4xJ 0#k)4jZMKBMt/-L1`fe5I,2zH #y? rj !4Ǝ}_Zdq6ۧ!by==?!"yBʦR6_CQ$W[὾F eW-Ɲ9p)d=+iML"$/14aa跅Qx)EE N>H@J_w{MKQkU,YE: *|R`3ytmc {J]CL&&AG?}Gs c* .@Z'o~ b=kLhY% "K#<+<WJ$wUBɐ4?7T$QF2/;7zŴJqx >/erZJ}CM~vv4z,BiT(X <,@Ԝ?759y#=VxNs}v5| &~DA*Qf*!DEZ3g>Se#)/SRڈDnLM0߁T4[kLy?VH[ [BqաɈߢAq%Ef<@5_Uۓq{6>a76F JG7 :a~_\[x zeV憗6d0YJgxH0S}F = }i*(7 ~rV "(DH[I_X}/S,cgەn#Yghb؊3~ Jj~"2y"jx8εG#R B h}&>,Z\I@ &0,*I'x .kV)t\dR_XpjwSo&hⲄ]Ɔp-8tvCeQ~)#U$asӔoHSa@?iÕ:ֻkUN۫~H+F޽_gʼnL]>b[rH]@*O0ݡ{KXMK4=k_D SŃ"O0c}j ($#/zYlA#!7GbiALT:. *\*a O-Hi"U9;lnN>I^.Ո;^|~(!^IW14yZŸrS`F6t ,PI29-4)™aTDzJ|/]m̤]>::[ h5a'fd9pMTd#1p bMA+ϟ31M8MpAA(jY_(#;Ş2vr+(3)GAkR<_<(ri^0*Y/Il3/\D|m1'.^'PO;o[Pf`;v2 {;;u=y"Awp8 ~"rֱ+`+TE5yvP+'+qx~kԴfhM 3vo(yX0%Ƴ8}O`eλ":vhJ1ꥇBTu8pFg4*tl2R j@3?oGy:Iqr*C(V(m] Ub7&m;kW 5Gs)*́QG? 04t0!pnCb-` F;F5|wd9EA#V0] ]BnβL0}D̺xx:]R#{/^ ,!$ cB(IPpRG6!+S̒' ?edDz}T x|;u;Cv~9g,\,\-VIE/KX8ZZC m…kBS#Fr\޼c3s!+Pʪr) T6cGN۰"HY@؈޾J`F˛ <0:NR*0Є:gV?=Cb,E:pO|DG6hT> ɱ;'ϹнҶ1@zr(|BB NAy%Cv&w7 Pl8Heo>z2DDpsLGΊCO`'V7$Z#W-'dW1o9P-쳣®ux(1s|}尗Գڠcac~TZ[Eݪ4]ڲdi/Jx7'y]}OPDPbWhlz35S}˪xo90OX+i|.QcA߫BH'̚glnw4;9+aSJŞKdbrt" ]-|JK{1'μH爂4Qϯ$ة{1Sbj!*[d˻W9.uRādT경c)v"TrFƽ@ULQ;!@BcNɸ-{u 98 e?ED(0JݪieS)ƾf|!4F*W-'uюܬǚ(|dH|oᰪ&2оכGஉo.X(XF9AC\;> : (~uov:܁'uGڽ8OVX!Ax yaS5c~C^i. l709%lB/))i #@޳LZi ܟPwGvkeW~ѭ*SY|t;W.J‡joܒ\D7Sh#()`Wo0N2ۜU%?Qml]Jj7S0 Wdގ֊^43d^tuR]C=}ih^Ѩ ڴroM7@juGʅ4OP8êOA#@,T6,}.ʧ;lxx{)cV򃑱ɤ;eAu"io8zSO?8|HN[QYAL2~ƕy5Σ̋|ū B?(x-ޞhQDȯk|{wyb vK5)Op֏݇GO&\0R^OUȦ`B/hȾ'AQ:!sȶe⨰e}C^(ӝK"2H,nSwRV=J#OV= /Nb]`G}OCE揤=b+vJF8AQ,ā >샻܊*P7p ]ȉnn%ShMjeVR/'˳E7=1IpjMfZY/Z-[:bx G a+/1]#t-@}^s2=ZT t/,Qn(oѓL^'jȻBY [R00%M.6 ) aL`4%L=_DQ+};[_/2f@6)B7b ޠR(_#o|fMMP񮕐fT}L1%vco1#EN\aA]*oo-.֫%SJ#Rc0ѮaqR%' PDCҰ'^՜<`yJ՜1yO!7){L;𣉸33 V1u^Kn!0߽ba/QZYrQ0~B]2-|>i8ٚEB G߳UR AxUP7-s@HY.k*I]d+TC5 }W~hh78@O9N֊ .0@ zx^9oU@! /BsKOEwRӈLչv;yTz׆R\Q`|6!3UoQ&PK,%ix2*[H||]IVϝ\RPʼnR߰WQ,OM} W [Nꋲ'FFj+d ˌ8.w#ED!`X\#')ʓ--ۙJi.|$ZĒIS085gs)mt|@p 'cd6h yV5 ¨*Ϙ=lq[i5LKvыl47BJS|ŏ5I Ov?N.{ e=z/QBA-+bͼ|̇^EPMZ lt2XjnIc ?#>{m>E ' )k/\!]s@}2Vwsh(̰5VjX'YɆ{`ap% 9K>wvA^DSEO.˨yd%ѸDصt$0xꕔ(WX 3G|qn%ٚq l+$UeNO@W:רSeD̞ t*||*E \r+,͎hZ%،"J=bE=,NZjG+JWaϼ*_\ORIђ}k{kL}_u>ԓ$fp;Zr*ıy8-eҀb&`*pRƥsL mӞm">X&(gu> * |]J`Dl5ϙz}$ ҫ; .4hڋ ,nik`#ӑ-B?(?qkDӧ%c,U % KzԄ|zi Pv@G/|Uygzoq}U:.@5S" g5#S։[QKPm>~s˃J'yt_:L ^B #n_QMMgݤvT+Oos ;^.~339-HR2&z͔z X#6y : Û}cw mZAdO818K8ndĄ E{M{V ;rcɟe[*_6VJ:#- U^t2)]\ w@%eG^9@[Hhgo(d t7uQE AQFs,A}?:!7Q݉d @d@뱐i;Iwwl{| sk{uh\gD>OŸ.M5v*I:燼eLy]-C>&sjjS}o-8ܛ@^%':/ ĬDq9}HT@`A|7 ضў2 e#1ayr:+"ϐ€; :ݟê`Έ*I$ :@@o]NYo݊BgqH>]:^ rRWYu,_^;RY%{ Dݲ̄l)W.=(2Km.~,{P W9J!Tf'ڗ@r#U"#*:rT.\AsaB'iHK<"Rf׋cgaQ4<Ⴅ@Z ^D[ss`Qu>AEɽ/9 m6 @rGg78Dly2A@}4?gK1hzk=5A7Bt nKqz{,L'ܪi>Y;nZa;ѱ?,d6z $\d'q,sYl8YG9_KM7!frpoέg"O&Ǡ2_M [MJh0)KqJm2t B¥v(QWGv{0tsgy"ђHT}He+*:u" л7ξ^ֹ)P |l reÝXo[K9м8N[\ӗʩZŠhL|Kv<FchZDtyvrLq2į\na:5TO71lJA|c#\w_d`[R&̘ETKG"2i0gr$3]2ϑJV]?I4#b53)O%P ʪ@" Ft,$wep_P-;3PȣԾ?uTH X9ջc{"`R9oOO+.ÏOKߤſsQC:Cnh|rW/vA^oa5b_2)0`pF$ j1Y/) BnJXü՝ G'w4:Hk2FE P&<=-ե~:T]N#7m0vq{ ͿYb bQFc.6Z*Ч;O4շ\ϛė 1(>'^:𫿷 Ʉ oC "RD6]>[NKI" [oԚʺؓoBs8Njp$&7yhG"7l]pu2܎pn(ġ |Pz;0q\eĴ[r x̛7(CㅴjV3t%VK*_8hB55$=PҴ1 P6='Á:4 3[O?r>s.Ŀ’K~vu޺9q"Xg~0),.)@ڇDٱ̿{:gˎ"~iӹAVAEDǭ6{b[~etyWSMKyg;ҔEkCp$I֥~Y2RGƻ7=LJVA!%`Г 6+i_`FVi޳廘YXn环>3pJش7նAJy"c|gۛ|+jN23*uKwrR1!`qW4hJ}|z HBuzR2@c0%;$5V| K$2MZ W-Q ? !Oْ 4Bi]#Fu2ccWCQ[7RxLho;:/ƞooҭn^.cI㧜R),աȞ2FC]xxߨG?S/cCa<f4^ {4aP8s4rk('p0}i1̶umaؒlvTfD<.ɵvW7O ~.]̆(L\n!dɵ٠'YD]}8ѿ[`7e:Y2qV↍ @D(vyuEu0Z9S =.)_+1M$cH^;"GZO[cͲ䇔;dk2} A=}i &ϑɾk 3r %9c@JѸC70m K~D8JDž"eУP2+4$(bWKFմ/s U>ʐc#n<5W{ҷkgD@^NzuKwZh; P=z) 1ZD9%Ҵi,KcXMǷ?{H`+?≐SV@W; ZȠmpBܱݵP4}Jh֎;KIik2)U=  v"<(Wp}(a%^>bwy6yaΦ4T#;n >E|'[Ͽ0j&Uo+R$5i&\y;ԘRiarrD 80!kмC<MGsfG"?"\_raV P<I?oʞzb.c)zXlUrDlG,{5>t)٨Jt@Vpں96O`Koe= FHt5>@~)]{`XU ''ll@0|fC&c*z][c t׶yr*.ũyˊwE8O̥:騈M5~L\_$zE7F^\>%d Ž#hvd{q/ lM8&#-+|Eϲ݇250 y_̜k\!"9-a"c >t?:-n (8i*PH3:OH˸u' 4Oq!A$fūF/- H-͝^RxA9 IsCc!JPMD5ַ1`9`:RjBdMT٭"hL`[`U4{  fuv A"ɺum"sop/erH/. W34 \1WkyԂϬht@I?lPW=ַwCJsywo*\Al{ă΃U&V@o]MrzS"ͣz6;0U`G9wig)lO4Qե zVץ҄%TVn 0]d ]ͺWh%+nVleQK!oGD&!3oX^a3m}v${kc>&-ͪ2uiuG;|`hDhI*M҈Ա_'InY d,aW8&[nSgEsSrs݄_4y,C=_5 F y{bd|s>5x;[L3ClpPCh hmTWbc͆Ӳ2]x$˩LcZ[Q:G"7U0om7Irj?TColǓ'$>/[BUհ`<`Vh(ۦl).lV7|p?O9MMGxbTL xz0NR\H R,s&%⭮=<P_Z fHg;I &$pO{QaHM 6"Uzۀt*tXkBr } d`w-/\ ;/jrXO2#^tI㺫/Y+.Nɨ=%b =Szt$/׈D +* #DU0HK[QG}EIF"!(N]FzbK| Be FpK 4GYq n&e=+gan `@0[Z{V%[ONUYZ:A?kA:pJ4enfӁXBV;0D\|:IFPt4krkW$ouX 䮲SQoʔ9=#QZTAC+[xy~gKNÛ%T׏뷜HzsAY(š|Z5eȋ/z5Zq̨A^Eyh :=) gjt]L{K7991־ bݓo/Z0xMsd Bp5Y ?iWʾ& y1]vA81N! rvV+s͚kcD!NF3?!4рti_^=~hS Oj9tu*싼*~Ǹ98l U*~QLqQDW6Q!vmOD"wV,>*R",É_\(Z|sJ813G`vsBczG]T.RRn4׽X\@h|iw/B:YQ'Fe<@Aa$~m@3KA7W_a 9}WEjv5؆Rm8_PdX>0T&Gcs;N@t ? !7ԇsJҺI,hxC0{(|KwbńTLXRynRzg.eGgɅ G&H`9/ι籫ֵe_Tu%{@5(- WT #xɢ76(['%0R',<%Qg~%ˡ]{)Aa]a"l?gg7Ltz*,w.rZ9#Mwf Ȭ^jUCQJ~9}iHG#V{ND"ݷ@LqQTjm<ƄڰJU Cp6 UP]hZ%FǀLb,-wډi+<]yC#k2-⿆J}8dѵ˫Lbrh{X fBSM:M,w"EA@#@Ts=w=v:=<1c,6*}X<ӈ+0Y9Lpx?*;ﺖ`;խUT=X< )8 0M#(>:~H|L& Ȗ@ :y!3轫P8 $B%eP,ߴO}c{xê_^9&+D۬DAQn{jN@bQb5K&`)!J1pڌ%C3:2[e.k|;"kHr=fz]U !u̽q R@ՃB^'zC15Hm\cJ$"̐},H˦YٔjL.qHh{$[.f/hFM^EcZ,Y[bdbphaPG'՛?dNО`e1]f`SQbu⧸>Cl,;(d]dt#7T$9A):s]/ YN"ZQ@kZeU {eZ* l[?#ZmΪi&2I|l @Sj^v].Go)Y)0SٯXbo}׾eKd(l @h8H9- wFX?ᑦ]}"aEOހQuwg9Hlyb3'좗hjyW(3,S]j߱nO}Hc%D<^(_5KQNTnyՇJ(S*Zar9u*٧uy[50` v7T}+kvʭG?ҡxKj-z*Nmٔ*dG.0=\@1/ڴ]f)}ŵA% R*,f4&A!톃(C]ߴH uͪ˂)<6'hN!HJ~wWn'0xW%!ߓ >d,x㍩r07g'>DʱssHf;۔iwO"ԏ ;g7D ^eGbiޡXIambe\"phkQ|Q2N'zi%p!Q)8dizS&5Zw2Ăk=Ͼͻ,W +) X Yg~]_\Ie66"%ѤUz L7O* /X5c7 λW4Roի TiKK)<-4Xܰ]Pס}T^Nhq_~$SM%Q6x}Yq.ޞ-["rnVtD4huq):s%+EWӟ;luQj? 8v񁡜A<nWzD&.A۠NjYSbBV B=qy#[Xc[q3Qh!e6eR'tѬT0_hlE3rJ/>n+N_x~=ԏc^A ԛRRwLݬ׿Hcb+ib {&#Tcij|Vj|1,C'u$һ~,'mlqRζJxޣu4%rݶ9葞޼B4feEKEѬ=Hb3vQMW-rUpa{CpݴtIƍv;ZP*t4-6ϓI%=BCu-mnפ&?~4VXwE0\i"x:xqv%)Nj;^0%-a't p9?UwΡ噖}ʷݳ"*ePDhu uYB:I:6ޛbZķLT䊠޿6] R*$GTDlH<.C{W.,iȀԇR O]YP]ZP'$~ϣ`dr[ؤp^,G_>a2߫_I2"$ѧvw6LQfͲx=< Lqwvrgj,T~ ~f# Yqj sDu@sI*#h{%jm0GJ*4Oυ+ؒE:37" _ޑzֆʼncRc5`t "-Q?T*33l]ՐPtyqmx5Z0U63b8b9r1POl=Li7c{ؑ?B)ƍ% LtLf ip,)I %H%Aj|Ʋ(a$nҫPK+ڜ S(5dQ_{/f3;Pw/P^9\}/⽈"ۧ\,Dx)m5LFH0ƈ4&!*p\g62z׫DuA;G JM*+ITtٍI`9)1f )Zs?vo*Ɂ}bDm.&]9%c0 ^ ʈaIMѰ0ZfWmEhN-Tb~Te8ygF؎37׻LGi y䬑v9s%\]*]F\nÖE@wmyҷ?o4^2kbJΪפzZ_*ΥoG[ˉl? {u}iCP,%(4bBqT&D\ͻ## {c@t(XNXnٟH 3`1%c6+%[oԼu9F=>*"<> 8ލ"כGhg;˔2kficV;|A"SC4%$$j6dW-uoQDHB*5ޔs\54_~JC)8.Y`TD%q猒~e:Ƶ{-yPK|E_ϰ\hwSjh2 8dp3*N=.vqVQG=(DSǷx٠sW@5jq? T^qdC!ee٫_oDK=sA!˩yގ6V#LN֧Q;Lh-鱋4.= > QwD9x NOr#`"IW2#(Y :]OuVGiAn r Z)IXCq<@)IJI `PZf BSQLjv(w{= 1N{26ƭJ%X_ˆVhō!B,K|Vl1{}mM\XS٭ąAS،;~iߔO5[˧ѹD`Yx'z2 2#x_pv<){꜕pL3xwWDk #h*w~#'9(9leG{GF=6);R^+z-c|Ƌ,DkRx]νT_*sӺP9O'f;waWH\a4gmaH E*0o9Jm \dQFs+*Msgg[X'/nf\T\iuȼuhO-tG5Vp)4*Au?^vTݱ$]JF]F*rB<(n1"aLM6=T !:58Sy[ZHnbŲ=[f6-5~Z@bU8Z!8_c鱎m2qԝYRCU/  =uxQR䱞/].\tXshA=N=By/ Db\!QrLXbE"Z>"0m]CN/C h[~I$ uw_#@ 3Gjx!q(z.uq?ۭdmC,9GFg0? d((7jwXaxa,>bAJhyxer ,if]$ޖf'C\[>a!: ]z'+>.ъ9sV6)dPQ2؈ <ںЉXLk ?4ȃtpޥh[ԌGX+230g:..7RIswcxCe ~ۓFMspN}:Aܿ XM܂E8="RЩadtz*Ro&FJ@(ZHL%k,4V9nKedB_V>>ۨ,5.>?A]\7k?4ʪ?C \o%IU.Gh+N~.|B4 "gb|YtK]ᷣw L@,$sYmxBc:ӏ?A<;A j bj}? #5>.`m(Uh_J>Mq4ٺ@KrGҚbźBۣu[-JpYV'H ~ P~?eDU[ޤX*Q!?vP]ΉWTݼ 0H ҭb+]@ƱdH^d!-f`4ܯ)'s jD U3xF Sg`λFq{h}~uA;9i|b7Eb;*;e_,>TTM•YCXntL+r0T$+>8q d<%؊+ʑt+˃|#Nbv̼, T7{9;Miao߆xShF Osd;@aqutrKr 2O n14K3XDZDҢl2.jgaTYW̧s[3 L{ 4ڢ e?)"-^UO2#0(BMӅa^J5||Ge_:WɡA)rHOXuB,6Qr Ѷu},=S=՝\xz$,umN3!e"RCgIheHh}ڥ'ߧʟVodF[E2NaX޼FvA`a5wUf~GefR Q`U^\6Ss9ͬV']OQmpR&_3ɉ* ~"¿ ?LUXp(?B Ho1r~#>'l@(i[!>i3;˳^՛(}~@/Z0+]bZs5D`$/qOX1Ń39 8 BäaT4jx/K-) ~>ce6ך*K'.&y% @f 0UT9>zØ:q)ѣwg^I0 hn,Y@5bU_'`sբ iwl.7aUwP"F/H~$SXhWEPQ-}$WBI t9wŔko77=8^t4:,aJk13 <%1[{U5P܈݋rCHqҽQ+ $i~0=r>˙!FК'Y, !٠1),1bV6ܳ)K @R:|Iͤ\:!{NU; 0uv8Z 7̈́]Td~YC}a$ }JNZke BL*ʅ@Az5%Kd?+;d'.,XCʉ݋o\OE;d*`{e̸1m.˟hEݬc/YR+` (k-C{"U8 Z1]0Ȉ8> `ngx1M"j rX2ʇLjЉDN8 W&r%&_sT6W൝/kA7%~GA54 0Ue}@u O"CLwaΥ /p~H랰[ W~`qFGDd~x]-8>·LfkBG5`D˒q%t#;x)`^He/9vK6{앫EbްG{>k ,vyJ:8K\}!zMg,iCuȖŨw [F<7Z(h b;vDvK0P PNϼ-g/湛F@S'j"  S臹hjTx̨|_"IJY(0s誛.zzkr3,ݰr/t 6 벦% s-^mFC6Zt2C.sCbGa 5¤x6qvט2q!ffddk G1Kf}J;)?~X?F. #bHAܺyhY חig]$<&WGSgofzu#[lQYF0K9}7ng C$ȜDX4 lӝSLA[> 渿pb&m^K읰F/_TH$܎-?ʲkCVw[/*|%ى)7-EWIO_UIjԜk"W!Jb5-Eau]* /ڑ~G =4`=ӬC;]\0dvpnrŵdF_Ӵ7^g7Uc?X2:oRɔ LAn:MWc튍B򅢧o7j*oكo}KU| Ԉ/]#!.z">0He/0b69%׉95&VO >d_;@V&T3/!j&x^dI~^Rs\as1QvPnY!QSH!3X뀻thețzNwߴM( {S Vu+YK7FT>k߾ >u'娦0rOtt0^)xǻì[.]ggn!77ak .iz9o\)&o_et*=ޯVQsi^qnӈ6ۋ+7D4*K1].0 73#[nWj*\8`<9snJINur϶KV2tuX%M2[%VɸX^ZBZu5]]ir`w|j|ϸf›37^ zhSI}EEԱK[cY-2.(p0QWgK#jZq.3??X:T^(09\7, x$5F+>LADzdJpA*50XwR>̖J٤uvI>N*G*+zBKtNh8>ww"R,ޏY:6j%O G< 6(NY,qP?5#o/R>#;\0ف)mOK?>mWſubӯ^]ItF*,Fx%Iw&Go,罻hSo|&-}ҔVG؛\o#"^ьLqJn A;cMJX1d83kEb%[K5MZR)GiF)|ܓ|);S%LPtQkTr^:5;u +\}J[iMn;xuȔ1.8P+Ѕ-G\CzP }Sn"^̳CMHZ"V߱7 I+qjŊ2Ц)`!JS7LGI a^ٷNS'KJ B!@2qP0 ӞXCCpIstjc7P ׏Q%`7Tl]|vd#[z鑜?GB]5~TSNb_W1@*62ZŲĮyp#WhZl759q]%Ov_ޟO,>NĮ&s}1SAhqn"x.遙!ѳעN}d;fpJtCPH ~i<~ _;{MY_f Ex yHO+F-_wxk4s#Ÿ*^AENѯ v|\^BjEs0kL>=Qyw5u8%i c) ]J1nMޮqaԽ~~R5rt2ǯO$pgBN8~vEXnػקT.ohAƂ|sR]^U? ya/JP58i*-{?/F)ʗK5:.kQww}(J q|U\#:ş&>kdB;_qĴU6L?kӔΐlǩ`LCA(DPmtAh-#T z;qbR]y%E4?M;&屆sa 6ylᤇ*}I YU46maA>t-u7-y-A@M퀱Yg188ڒiOMEȣkOPqnn/ _ A>%@PF 3wV@E촩#B 9 / }زv7^+/؝>M16=:d5Jp+q_ޟ"cNt[>Ŋo.nh+q%;2xJO\"s'}~4303]uH;.h N1 #qo3?߱E-̕q~pws1HM?^Q>]vTkRލ`zxO4/ULZgږެ⑐C8k|Ƅ-$F9ͨ5=U:ߨԸ-kSu9q)DRg]5Hv;@hy,n[ U2[j/R+1bjS>Aet9$cuYvj0}۴r~mIoO8+ +]TWRs==h!ԚLf'4ܬ(Zr?mQ_1;g}] Axm 9k]3ZHH6Ʋma3/LIuľ`I]>E{qê GsX~'г&HL7OO&ɶfY}@VH*gH k{d՛d3s'5qvL˝JJ3I#kD~֠+s9>@J2s "Ny GGLkjdU]<-3AGf":fekqN>Ol>œp;2o0` it1) >Eɱ]}WM;cۭbcheR>v1eso"UҍZ^nSleRԃB"u$y%Yb=zPdsӝ;ܺÌnP!|Ʊ$vYv=κ}\,O^۞˝ SOSM_WhdJf+߷ٯ8O}< j +M ؂G8HA*$]6a5˶wI>w\Z4 fz#u#_c3/+rE.2O7>J?cB;'&4ЦEhL,$;!Ⱥe^oy!V.7xsGY$t#G)XPւ |p|ŔZWu ek{ТNȻft|1=WĂ9 Al.J3HI,*a3^0hUzሜN&a=g:Yj\nAO9oZZCEk 'ղ0=[,V1g]NɱէprC}oٟyu}ƙY+C_6# >]8SZ1cpҙ}X޴vCi5qK>KP>N4GHsdͳxH@®+;=,ubyhXў{/ ^?Lޗ6]d)QEqM쫟GQ IN)TUDw&}|G:g((JyifEa 'h"ZD7A)'~EC/~HxOG4;}Wŗ-]6Z1dh הO`OfCq\+!3W̜<ffw$~XkVi-yۗtw}/ PGV4@}.DD-J< ;WO\p$PS X EllG6 * &6`0fElCDm@AwR̆‰ܮcm We GS;iˎY p~фUoߓ76x |+a@@FBLFH~a^{:2íݕJb~x#ta̒1RuR Zp2g]> xÏx,!@zIJu F;`.>`|5Bci]\[`ٚYpWOӚ<#hEBBX?JV8}xŠ󗏪`!dy#W4J;e+(JN) 6_"bqĨ; lT#CϬɾd[ӃLgAZ]gmc&&{8agbxx>Ӗ.,b^OQ9-3 {KOlI1*UQ8)r77MN_o_|f嬻cI<:_D.dj JZ6X24N߳|jU-?m\/HHZfxgAȎdj׍]Q<*ag?,WJ]n4-O P}q߁^ Wc> i[Ow 3TTMw"Q$Ěpυr鮣m"@k`N}&^$)5?Oʷհ~S/sW}BٓQMN?}0|RxNZ&z)wfC`ODΨ{tfx?^dzg|N;D3~qwaxv_dB2JGÚ g'pyE10ہVO`/ᙓb0[&^a] *O~#wt_Ai,ayp}[(IpWN5 9kg1@>U➀/ϗ)8l3Z^+9nɶL7[;&ꂍ.~,TX0x(#L%0S1<:.k|w."Z5NKwn3ݞ\KwbQI)=霕v@BІٖrֳUVp;zj<Sm ͨݙc|&]2(H䂱BQ<+--=zbv.i%CZ%s ̶6\E( 3n W_fܛr:-jH)OM- MW5`yCUAiI܎ KW]#GHl,֛l }ȥq xCT·չ@|/t/?.SǁBmǭ\F}djnod6p8DNä#*%v 4ҀkV*[t 4. eK=DPYJ>wp|TWS48A#@#lmO4f\`ƍhu` 3qQd3߮/5L򡃿-<ҰwxjJؕk/'ayIń~oΖuƟ_;uvnhK"%ꍆy@*>cq%De=_Doٽ=8$w kLoɄ$CžV y=7-j.A а9 L O s}Q)UDʙ@~f'/s1%IlVJ@1xiI{;d6y#:B5c43[?=R#ˀཞ f럇 gD P= nnukÓRd !nZ*`P yA_˷`6p*x2ލ/&;[ܨq U-")Ȃy )2/ dg_d ȓ;~,zБURjAHW߰H~m7 :&4nW-&{˨YAZqj{Ma|NbiթGxWdu5mT@IoQ9bOALGY>5QҔKj@~:(/:Zo{xx,ԎW(+ }ulq0eo&^|lEcj1d>[Կb%#V٬qg[H.۰yinb&9ʉLZGs>x̥7SHWȲ[?J*+ı|}ZB jtCr¸+*}װ &4D-$r.cG,J!$h8AUBImJ,"[NSHd"^KjK^<ס6x XGbur!4".9|*j`alJ[ȟ4U v P@W6p\dqCk@> s1~#XQ#?rM4,zK~w`U8nlY퐘&X"^yI ޗX(1XWsAGuK(8.w}زŽ8#"r@7A!h+5]0.)T\sDb,#rd>;y=OՈ %D<bq Oy٭ŝMr"'cm2ko@oSI==%OH˹d6rCDuԎOw:xE1%DMCn jOk:5uN!)46hf飥xƨxh ;@`' ֋,#,) ƿ|pҩKzi,RyP&t3C h,/mnʝ )W$F^~g2yg".>I{FTL5u-@Y$?Pٴv? dC\HlY}rF~P`3+L9<&ʄv_O!NP}egrQ.ݥ 낆6T%hB Ģ2\s;0ńض+ 7̵wk^YDLB5;Fv2j8'9\|~,˞{9L*6BM?A `/O- y|fzAʸlLӝSg@:?|3feʈHH/W~] ~8]d/|rd32y-2ώ?r5Qjj^+Hg@E>qJ؂7G#NŀD}gLLŒ18^IYԛ Q7ay h+Kr2J1 ɑpiF5eDp8^V=4-ς2G@3'S]~56aB<۝&>x\;`UQgbz?7q3?/K';eaFYAϐh-@a{u#M/>N9@H(JQƢi7A#[#Qa޶eͼ7r݉u^fU̅9\zbʪ9@.#i0izD#*($Gd8"7@$:8z,r6b( ` [fR o`%$#41ħ| bIF[%E s!{E[Y>Zo !NZd<@PjYwhsh/dz"OVRC˒G!NΛfkU oN! 6pvJUKlwfKDvvLIo8^!y])˶NZ,_8#?ܠkt%GY V/\iy=UXB0^XDl׹&2Gegg|⩍ +'s2|kBj$jːT\2~)S[d4xx)?ٻ]WQ#xhv"^n:Id}ˇz3u&7tl{97rw:z8Xvp \g#0=R%M)ՠ"E2?9==~JtH^f7Yi|'zt|`!!FbpcPO>u+^13Sˢ3cZܸ.ESLV;ٴbi_p|~#(m݀BnS.=̏5Mqr%p8W\2X#.QTQw3(apXj(UC& ywINf&e >`UprirQLP:)"^N\C{w l!]fWt"0aW1w" -J§3X ȏ5@慙uq\0'渏TNzm1<+\Aުu( Wa9a*O ;=Tpȴs/܃Mt8">TI;BN.ݳm"z7AZC' %+MxO<2E?ə;τk<.1zУF}f8X?RkFB'7pXITs3!Җ,?uys+D/uG͋zT&NzV ,KGY&ًӽժb%W,wdB(6‚r Hʱ>"jyf-pBN+!:X@G,<9Ru]'hHY|mwօ:$a ^).QTCc2Yxj>&! ZEZD| U!"ߑ۴.)jd\6 砗G;g)GZ|2-a>/\+}K)iα>{a*@s4tD gJ<(S9AgO{+e.b$H>=ú)ft/ x̰Eҟ eD4{ 9 4z%ѻ3eCU7 !>LGFJ=f1&2nc)7]'͘x@@i6qQr`\5$Tθk>ʂ*GZDAaR#9;hZsRÚ?8TlH1}&֥8qWQ؍ p|Dgnx*ccMYwA-C^yI?\cZ:O~ԝ N b/4*]8FȽ}#!4e/ʶкo5`XJJ°#X1k:*`Z[\Eq-oYWR3C,fvQB_y),TIR)ӻ7>t? rƦʮMet[:N(mn|'9@F>|`ə8_ӱzJ š5[GA^pO+sLfm%M|v̄ Е(]s'e)V(o)x;;̯L/8 o\Meh ;Xŏ&"vy3[ȇv1(_ףU,VL\"yqv  gU(6LeЖLCM}âlc?f7oSvTZ%/ ZA n^iWR}ч4(,3C EZr1)4YG_/,Q{PgIM j %g yfET w ^ n2QpW@+N w&C;ϻFl@Y0ŽКwI@ǕAŃ<ʺZM PmɆ9ιDt*߽HV|Yn»&C9P}o~FK|ݾ@YO]%;T*vCȇr8=rM7@irgm{N*:+KAz,"mVL$JwjzV-O.ݜ/\)Ie> flWJ^1V& 4S9޽R^eį>d_1f0caل*SG=p9[ bnV߾} 4^ڢcj޾"J-*6W;W~h-$1݈{Lv($eCpL`:dEa+)=e sU<\.۲|n gRRm56f%*(ؒ=lDn*2>u9CK6y,(v3<|K켟n܅?~Yy0 O&? iT)* H| |YFv.sPiK>}+d=؅09 s&*5b0&@V]?!q,ϓ*8X)Ys ?|DyM\aJ[Yw=z93Qai;`wR,ќ%k4>/KvXas2oO*jZmN[q0q h~]ծR[!m}.ee]z|L AB=iD—1ej`bRǗa)MO@Zx1DoR Fu+m2}sl7].dqBUJ{=B B ̒S{c*?чUXcMsb}jMc$^Jx[ޱ TK}6rܾemLbȷH.CE^b,P2ziO!폱& }yϬ[`p 'zJZL5aw/DHnTEhWI W#XҐQPd/aߞ٢02 0J cXJCmESOj ΏdѼͼھA/hUj4x;&@ƒp Q"%TMt=Q$A0/I7:5YNz`ѭGi Tx7hFfѸs2/3Cbq?ЌS'쯨{zyR'בF.q4^tZA#\e0}r}23v[H.'k\aeOy1THb>(MX;0*Nx+ [WYoA0 [{sQ0t}E:VzwLg bD,iy &Mނ5bEf !T\<Fh@ O e0bHЬO-GrWJ/XX'N5Xv(G>Qb;M[ovi*17`_ xhf1K q=DR,XWZOoȻ{WZ9B+_ܻ)LB`kiu.rL G\\J {xyNq_&f#㪖2(+7շI0q&Bk9 +B`46]0WxhU^w2p69O-²YŤ?m0LrH#̒X]*1cIL] R {gڧOG7Equ }R:ȷgWݬcd Ů"MNv}-+mLXIX F]Q1K*2|v21c8wiS>@k+(W5}F0 I5|J .ıN%}U OKG3TO;nF6>9aZ߮F%y.VI0^Ga.^ W|`x#^~Y|k7l&ăkQ%em?sޑvF~d'K /((~7[˳\0\??O¸Ye/ΐpG UTH)h$N;3_Y>7 z fXpM't\x&lXGiU>cwkfKIVM6'cgGM"-Th$o#,4`_6\ry!7xInTe}{鍹Fe LLs"H6\=gJJjGhaŹS2;&6Jw)A[iM\Yo%UY V*{bOĿ$mU>BӴiJۚ|ҥ":Jy7ޘCq5 _Rtlbap.Z7x͹lDV! Dg?{6wٍHG-`;Lؘd˒ˬZ<ӘDJ:TzF_;eNU~.@m1,Rm6v_D`@}baX =bh9^_:(gӻ>d#$JCRB( TCu0{LO{I;,2~৙YzPW"1-]q8 ܎`8q[nYB͡y;Quxl͋ܘCK>EC+CQAx\ѳH*܇3-%q"kT7Q։t!ُMrHel59)Ќ/o!R~߉nB =dLUCu0Vjg wYܷyM eU~Ze};ʿBMϙn!!H*̬mWIR/D0O;TR6!sB+Y ]( G/ zȃ}7Wtix:M=ԫ]8+]d9C`[zӕI5b/Mӕux Uµ0OjQeɵ2p%†˪L8Sج+qfFr=P1Ha `:WQ>VELwsIB#j}N-g=ɾ{yr+T%ȅJL BN,Ô2XwMì>=|ES[ܽA1[{50GYpO_pM:^,CV~L~kG T$?#i7Ha'C4wVU:˝S;(pתtyQT,g.~, uv\'+HtK+ݮ/Xφ4`6S% >GOik=|wˉWD-c96pC%~SSMIW٢ӞzF%x衞,J!E4bps ^m(+U lc"njC0bUKWn?0p,r] (h(bkYaFRf$C ~O3@V]Q#jf,1@MUZAEat7cFT4\e4j"ّGjٳrlfnŸD;H%;I"Yhqgh5aGG'?!߅v=}4hʿG̅bi/q7vN79:CNܚ8X6X҅$VVޜ"lx^#"E-Vg-,4g̏7b.>+0Tf 6A5$ >ɸ<0a"zVVH-Z2+wSN`7Nt >jɔyH?N@D=>T?mͣFjF#r?BoTVSRj2MdLJ?>Xpx:I\#C;/lw;-/o-7:Vs@h3y([e'p'H/*Z6[d6{ >--, =jq9,0,&i 'J(o\,+6ۭ\Z_M=uTZ5\Frs? uա!a;`NAg!n4P2Dz{ÌC(DMTv2}ZUa`Vkw{5.RAA,Zo@RnA xԳO c3)z@bʫ\$0 QKb@/(l|^8!M@MRajHKviodL9dtgbIΩ#ҡ3'זU»5-pGtF%H#**A$hrvLǨ+xWIT7KNB)uSc3*ǹOK !.1*H⃌x c鬺K P[dWSkzO%%fB[l3+۠EnicrO>DUP:f7g:[ iq}:*qq h#I]Xї7`fojEv(؉y W(QorI 3GK(ܑ&czWN>#J"5/ mn7,`H[E @u{"Ew]CoT̫T(pkc=>$ƥ_ZKSL|][j*W'rF.c?I XL$Kl6xަ?뼵EON>iG?[#{F/&1C`x2Tuh!ف8h 2OpU`{ʹcmQUzSJY^>F\=jR,?5\i9xWlR:7QgĴP&Gz%dEF[@{pJ)3NB|z]96*2nPf XxWopDR,J񚝗`. 'M!Aj*1- VfaoT:|d{Zq\T\Tߦ=K䨔@9(f{hHd_e(n&G]̮X>`D`:#]jHTdY4&p Hmz]߽UcFc,%>b̴ sR{anÌԵF_4FCH[$0w)ȱv;Ó}Fhh.eū]2mo|iĬ|*d $gXFZOlwCvƋ G\ о%c|> /6"[K65RA)3\߅YM1jurgh)մ P0-+ 8Ե$hKgW+v%L[4 e^0Im*m3PJ؋NyܬtInWcOi%Ima[EKρo#NB;!ڎKMR ~Ϟ=TzGLj@/`3 kiqf=IڥFhIiâz03*I u"=2^*,!EhLqS54e?刨w/GQlbpX~i1 9Lo Dj|MvP).FĊѐ3Ÿ-Қ%VY=ߴ'iPVnQt^)DweG?Ȕ6<ґW-58rWvh -0 ҏ8 u) KlgQm'='\zC$zh/N~e.UJ)>]xn2 :'!~КKZ:r1=4cELD{~(`q@ӣ҉W &+f\ɭICf(\9"W%bҵЛꠕU叠跓鎙۶Magj&²k2~ hk`dZ;muKIm+]P&ul+TGG_CF>mkђ_d[w/-x3f* eyTiKhR>\"5 ̘E))줡ȒD Avq()my>J@̌yԤ:G'?+G."sei"g$Ow&?U d5x-؊% ]I#~|@l|ck]I3;&5_Qܢw7 *gkxTY JmΫ7xu,v6}]T?#=r q e9hm\8,-#OojN.;F-om0!AT%N `1cpH}p4aכ>2xeiX J=-G!><wΆ*qJ #/TQEZ| fE[On㋊tV݌o!`VkW56 9D?97Վ~~*Z 0fN>.TvʎheU0}D1[U$' Kq~O]ƈiaX7LE^y`0umS@8^>!xL-u=˱p1'x,yЂueOkbNh<v݋|. /FQ #(&&zZfPU6a8=t!b+YegQw)X{t}܂w"-UMjZAӱaFl_M+(( F }9P!-%cXOtwk҂[~Ť! y͂o88Oa%+$ %Odakn.6e4_Yw4̃YVM\6Pj j snɚA8o_}Yb||.210ER⸒ȉ);#,E-bo/uLi`od@bh)O6@<pyҜi3%n$C.t.kUg'sDOa3XR='՚՟C1 MᐆJ*哾 }(O["WXch,A{-E\ }Q۟H2}^InmNR ^^W ~4ȿ{>,SM 9W &@?L8()L!&Nqx,A&Pɬa8ARB7=9UN _ާЉ?kbP V|lxc.C((-.|d(hGR;/}e\͇rlb)-߷tZ\;jMy;Z+OFKy=k_3:m1Tdܰc%?CG<5Gi/o GU565WM`+@Use%к($i:* =taYGM~FTk2@r/Nw)q2}* f~!4|n7E.&qi++C^ȋ>d ]AɜHhw]y&Az, z)@>Oq}nwڻȳDu+_hM62;ۜD3ILmSy>ϧFkD/%zaf/!Vt#esN:i_gk1ƎU.mF ½t8 Tϐݶ8v+g @ %|`TzzVAOxEc 1| ݯSZ{m'' إd|dE*rɌHBh khӷZf8D7/Rq(6gyPsm[(~w( Y!]fwq )WC$J`7bV&eg;F7]N-"nv(`R~p@k_*oQWyUDh_p*Z{I Z,^hWZjV><^ܡ?>IR?jpwH'I(mPo] 2eySreJl>z6C) ˖(a佾$v F^oO&>1qM2(T6=m mmRbX>urHyi*Pe׿%X OL,{Ncɾ14 y,نo? F'wywSRZɠ㑀-GS]T_>^M6EĦ(#{5czzsݰ2!|йˎmDlnQ/HY>a^><›츕`͈=e#8RL.uF"[gmy<\b9u ,xaΛf_cȈ>&61س~ed{ײ;2{?D>+8Ϳ$$My)r.yU8fzŏ"ffx$~VۚaZI@i1/`{~^營H,D6踩2*bz"L8!FIS궿r3b}i & 0 'ֽɇ3̈KJ4mֶ7aKM@Q^ST) iTWDh -'J4zzBـ܊n8w}3 EK~a$BbҩM#Ӫ\*à V֊TqD9E1Va1Nj18;7F oBd[/wMlXV/ߖO~]W@ႛԷ{+ CC,)BZSrY v*݅TY%~RHkvT4aF6)#ziLswqH^8(SƱb\A(E+9 57w\JpymR~ ٞjd!֗6ۯ$W8>f=&zݯl1Aڥc.By#)þȝҘ4QC`C: ;^-8is8}6_?זN*/3LRQ*cMjfe~oLj[r ѓ*"( 0^.;@7hu cfG ?; ĝM[wϜ}:eUlnt56֮K1W}'Ԓ]\BgUpD =odzMh(b1UW(f4@W~QL. )`IwdZgeeoϸ ƩǒQԮEPg*Jc}z@ OPZa74T%[`l5XfQ71mbƟvG[^mK JMy#TpNtŞz+5՘ƨaF ¸#= 6Dw !ˣap4Ԛ%`NA{"?C" 9apB dZA4hjD;`amU3p4&)%~e^)-hdO"a?J[a//H6.JĐ6ΓAӃ!Iz~ ۼ8-zE@'l6s'jWs ơפ(7cæ8m_3gdQkc~ɩ:c2yL늫|{A2I]IkaLR%:_E7i/u"$w]2;Tix [CkT~Γlw sXQ QtN,AHwZc[8[ hA,Qf4, 7xDѠB7!=B5HңS}`]M3_RsFrک&sxJf" jz3mԋ~R9~_+ 8dyjZhW/e+> ]:s}O)Pyv-0 :>Jq}Q.h/䳓0_5]ﻐBx0 ΁2ϡ㪄0hBy,nr"/e؇&O%O[۸Xiצ BeL7i|tGXѺ{M9Em! J:Mur/f& > 2wvY.˭U`j% kԃ'b1”sГ?wg<[x<'ZFz; XDɔHF"e0zh]dl|$&a^ .3;j]m[chS ŀיsHȘ85r4BpS[~3pj6 8 5-ޜ!~R !0p;S~aZ/OI miןg/19upXkD0j!uOD̀g?49 1(h #CRh=%{8yORtcWDPpog1c9U sŊ=Ɂf}  al9sZG:м̞כA̷E Y*FeKdr@vXՑ4R%)g8&@Zq%AM+ƋL{1S:Lo3zneUAe lT283B1%Urˏ%tPkV&T5tRm?ĐUA~?@cZzic6ښNR𺏨_Q X+fgWêȵm;8 8GǯڃqR;=eOY+"`H[}8&А)+R9?kdCSc<@Wh)OE㚇)dKіXQt94l܂) z%fx]=TQ4_ϒ/&Rv*e@SxVi!Ѱ;ޛbM1 V`0ȵdޘe~=$ǐ9#K1Xls@H5a Zb9ݷt{8yxU6]%1}biJ^ҋ >uDf .kN E09Ge>YD./Y KT?oe; . )ٮհ&Zޟw hIiHiq!Ɗ[|0ƕ^aPl<7@cVo\qnQ %m)Woi{s{~þ-:c02do?wlga9eP:܋}-A0JdB~]hm1y&U_c! m5j<l.2ƃ2 bcJ pBotht73yWgtT>ܩ4SDo2.\kg$>[ߛ :/:I,?U C0͔zW,08FQ,8v{VlRڝ]t6\@)శ _Ja~X۠>iDS}f`njZv oȩ=ʹ8s8Ri|ip3dCbwz*!*kFvL2[?.8 d)^=&|vJkL! l&u'LGVC?oҊKr V+ֲԓآ*is" ͳK Lf]^ځ?Aqo|-TZЇt= {Xs*Hv9cVtȏWq֫hG[Py]MA(*7VRhdt;L2lxX[Mw?0>g=X҈рP=Jiۢ :x}8K`uc$Uݽ:B(eѥ76JL%|݇H( U%‰DNNU"5iΆ @c2ˎJ|"RPqPB>a^7' UzfOf.$73IJpqٜ0v Y@jNؼL܏ hqbӐf onoe(ؾ=yzc.c ovp7U$#=?RF]pm?B@PCimoۘ&~UxXPhII|oQUx E]ZtW0=\N#Ш'iwjX ޶&#]~X`73X4(=*ƌKV-uNd!a0+,[| Xc/wPan?,NpΪg /Ҭ^PtEҫsQfRO434ǃ̡tv,o7P"f"v9kWm%+}].velV!X$8Ӑ+OB OT(>Jc' ? =B[GV Ni r>fLK޴ZP<Lm "]!ӑ2̅2lSmYm.܈bܞ388dC!;Qi/<&ʺ( }qIwDAO=eF4o,^'8]%ZY+Ю7t |KD x=a$yNv޵? f;#;|Im҅ R4nPKߢw6̝Pdk8@]і-4*>DMhB;ٷ#~qk.G *\O&@?pG#WkY0}@QvRߞB-q&Б,ΣաQ_' ;ԪgAHS#ux$l>=K ,ʼe7&?ua:aNr/@Y bJ5 ..o=>/}wT=[B fR>imiTf/NtRdHUGaJ'm?P # dfBd؟k}@) #M]v3 `[PXmPܸJ=tvE3 }uRpZ k׈ (W/cm+IɶH$% ,m|l~P84밍'yN9L.^zGErDV |ziKxu0S@bs`4_haww >Zha(L`*V2,*q#OJƆq4~$]Ey%JX|چsCK*M2.2y7E溤Lʋd!~2 \Lمda[~IuT6+M ^jBfjjTCLC۫,W(-+|%,k@"@@fxdms.Xqf*sXX4X5 VPi/,wM~cơ?x HrywSH@t쬃N\T(pj+Oc}߃ ~)M -^"?T\?&D%ʑ4"?^,6^j!NjүzLTMzS4;BEI*w5jo!jduk͔9'D(ʏ~FY}*՛S n6sƧ`Iث]{,h=7em~qanIˏV,>LYP@å]MtJp+YS]|9LcfrbOw1*Q|?j"+&"ԵUkQoE8iC[*p<AG*ai[KQ M(KO XQ[4F5 1C ՊnLƂĴjlӬ} _ܲ|'gfـfE2nIb((oCmUm) ǡQ>K9?^%~7HYxf#!uQf ԘѾuVVGܴv8`lL Uk=296ե-aȌHՊ_hUBW\K"8TSrV2_6$&ʊ$zU@A{\Iq1~1˝X V[rIħ[ 2'cJH{Jp:,8zU!`&[|b{`+ B@g!+1J9|z~kbW&,~XN=G]ΎF ҷbC`SpRڏa}P t$}Wہ1&/+]Gycn יhq9gز%= p V rdi [_" _SdBqz Ȣ6O@fHGřXn:{xrZլ&n5y21DGs*򿀷Hە %a n +g:|mԼ[HYz\! t:n+IC`> =%?vGJuL "(`,nBryVŬ\n].\wNaݮ7tg@3!yR1/_h C`A# 2b*6̨%gbѧK1oYvtݭD@%*?:MDoXAՆ I*J>l7L;vB͒S5 ׳'5Up0C"vTk#+\[=lc׉c :]%)W8Lh<@UBAAE/oMr;}LX-vbM(z p_҅O:r:u bt¹? jd$ >[ D14"vX99 \Άa pJNwjTIz)oz+P;Ƿ wԳ\uƍTE XPH>Q Ś-Gzl6df&pZ=ad&)"7еL½{ymv1BޕM)?}VXꪒêHz | `5,F*fQ>uYQI_97nh3 Z}yE3Dԁ5.J 6zƭ%,TV 5臔5~NyQP@}O&bXCǯRiDZ˄ԋjRpntw xa\h)dlp6)8jNc"GFe.2YAiVݻA]5&<~rh;*u)ss =|GY^޼s$-zGL ;X?l 0S(NYslVozTVTEpP:ո'nض4ƈA1jEwChJۑvKe2\մ%(=lU 0}up4[ێ.QGyV/%a*R?m뒬ˍY_ꪼ灭>@u?G4h?KvM('Lf" 6ڟCw06|$_>f#yjCz \#Skm1D%6Jw+KNk-gT;K步/ Hu8/ @gZW6.'@Y\( m*;Dkh -zmNWQp#=DvG'oڹ_4llͤj#{-{vX/d}!O?0LJrlP5s 84&c%PBzY|̠*GQpb;9FosUIٵ󫯀EtԜN(0@0h Dm~MAyqQ&W[T2YzqFpt''j)=qkDR"Ҟ/X-602@5l rx{I\.'g\/wV!dl֞lZ5DR .2E,Zv\p7( ˩H 󻀧:?&G9 @ACg#( q_S0fZ?7 _rĝoop}饶1 /6ϼR| {ϱ*trS#w1}mLɚ%r8j-3e镓^ʺԓ0Pkꋅ0zz׳2hj-?pct&o? -Lv7Gr ȸIYKֺqmPgw(@ҧͯ/P-g _=+Y=e~ cl 4kraheDrh]厯j \Xi˷6~)x31̜bfpF&HQH+Rm^0sx c͌]r:f9)JG(fƖ9Qsh3$m(sVA"-_BY}OU֊Q4O鋑w#XBM8eOx%WJ+`S4JO_(.Po>ABhW89>W5y@p,xN-t%p&S+S{ ,wg8`auUcFJ!017?d  2e]ˑk:A Cbl@3g2Ō"uy4Ou7q"CH+y2C' L+=H@b$om#BpUA [&Щ -lpV' hVf)h֠ 279ډ=dL슚%BO ʹ1Is]/P{[ep>3:H B69hEJF L3وGV/6}g\DK<ηdsorֿAi')08˙m֭K9hTE(* O⧌:X=!l5 /^iϹn>4vL:-vExH3:Kh'Le?l7W_|pbyY( 4Z[rZi&=CeWԽRC/nd_UEkG1v+ AVMTQIPSbi^_g2K*A Q o= .< $OuB*:zl(-##7VeD1%u/ IsQm-@x6pt_Q=C,xOD]}ۀ^W%_Ay#NK4B7:1f uF >]a93ATG pG+֡\5x>`QfYeCB_o@6\Q|>hI@K(s6oI&3\;i"8Z˒`9S]Adj|ت HU ؀%(ʧ?VU(uFQë|㳊oeЗ6%"! KLCdzFcQᑘ"ul†ccG=.k i,-96U~z]?q2Oc@*,Ѕ=Ni>:|<l<˲fx<3*#voJn Locȵr+c1 c5uȩME?:()6TMr'[ųj^yH3pp<|ot/EY@,`%_5vqWkMg7&=QtMPh$0a44M3m,8HG/9H<-{&4읊).,^=T Ƌi` $G0+a")qA -ɶwx 1m뾖\~-ӟ;gyw]Xp¶'vȭN23h,+|Բ)!伝Khr6tx݄vJ+BMڌkгe:с8Y6gC{³8N8oplؿϾ7e-I>g?eUWIiF wDƓX)xVvg+[+'|vS-=e' } R!Iku?Xw[5_+ȦbH7ē:i`&c%FV2,ƫhjsz4%3`iAMHy k9zuQSBX̳L=|?$sd7=XKw( A5vqۢChi%h}m77p<Y*Mh/nۖCoUeW`g#\~{HeRF AY&ܓdwקn@$78 &]$7s7#8fX7\x#NS|Wu=@x"6 dEV; =?Cv'Bn偖[o3; }>xZԐV"e۶o֠#cU\L)OՑ%"%ӠSjڂɖՆ;&_!UܾR@YtUY37~oS1w1Ơ9D$U4,}Vu?hf_r5jҴ]%.`CNWs iypy7wk19*ce~>oxKd;;kHK'knL-&|6x3L u-iK(oRۺ{Y0 0_R@A\W \טo)Qw ̅+sC6X&Tì2wpw5J4ꎞ{ 4#ݯQeJ52V?e-i(}~;~M'QI[Uk@EUOL_ ah@ޞ28R2(V*,>Y~RW-+CP{ qd.?+&s %^>Ug.̑usvS{ikx@9U99iNT\O/ R(01ם @G*C(R$+P9(~%20ZZ)CL<6/Ƣocܔ%}AA'PhӠvI ^uzVGI0-kq'ѠlP½.*nsA m+bdl~S9-  %Ec<U,Ϋ*vhuKu;UEΓ~&-U,\F8%=uĂV\Slg1>DVXL1u3C`& aEK9 kVB%ʱ8XSF C P bgͽطucN݆r&C>a(psFtޛ3EѨï,~KS16֩!77&Aj7c ,ꦦFL.-; ^fYfI'½nIY)t+%:Ctw^C'X?!9 Y׻C>nyԡ%4s1k+!HlΑjw?.[Q躪tSBPk?EbM7|:rJ4̊?͢uGwLRl8zTĠX(`jM0*w]?ҡPfH AhĜu jY@Mw^2a`xGb@ѠGZC'j) “J`Y:4W/$|kh^!0j7nhٯ!͓8U *.APP rYB@XO-Q'E^:#jjCgJIGs2tK-$Dr`KV0=*: fMgՐuݟ#!5k Ȁ|~ *vBkv"QF|ﮤv0-aF&X\:S+U?{$8,ާI i+@OhWQTF9u{dRTjq?)%YEק{Bem#I, |iCP+HB3xqv# KS|Տ]:g 3}{ʏ~9ym-Z$8o }EG\'yd̗;dT{:׃`y8tx (t)mlNkhto|$-W,H<˳y>AboyB4')יa_0œjXi#׍0a*DҏA/@C)- ׋o46땢MO?y$1ɍC"<@ZQ 37 pd=嚛759 dků%8K+%co5zosG<\֟`U{@>>eӿ }pTSYes]tW9\ɶV x@yڒ} ym<@MYrء-D,)Z0 MMb)hp>#?+yyl-ܫ&@f߃h kJo"^m᫑slQ8tG-ƝoL8T|[*>/ꂇ 'AXihE*Q?T;B庡ꋯXf-dW$8^\(:,+0 暾_]O~KYt IYR근gFv; uv n5˖ota ǡh{I1ץRnn2+ɞ~p6v|#vӹu,+*%`O˔xn } 6 ".dy3j`P_؈dƾ9t|}a fm^DRX' msK,Q7d ŕ+@ܜ yƲI¿"z`ӲY.MMU{DԍYFbT h٘`u)R e8Z]sسZ(4.QJ璔lYtՀ*$m&())Cր\YMX.l+D[,f#2}GKYX`0Gݲ'n*BP0N5ŋ(jxMb} Ge_Wm V9ɥop)b!҂êQ?Ec.hpғwb:U. sq\5j+'cYp;Y~.?G<=jy+9$qSИM}v k(Gۯnb|+G &()}zUyU(Fx5c4Jc_oVSjqSS$ܰџSIN*|4`{~}LE |4.T({J(!1^TV.vv*R_>wTy7&p8(EYRԦ X Y0bCR:l] <ߓhvUD~ӯ7= >oNO,U]c 'L)"- ;= Qs4lqkc.e`%*jSB۷THr _ Tp8zY+Գˑ9tmZ(H hEc`ԗ~Й^΢s /zQҭ9`e,%Bǥ.Gx<"vZ!p @ 2c%,& pn`ŝ2%- Q2d,>r7"C,;`9tD,vn Q&zFMZ[80f3/tO_ەQZo"1CJG<# &#E*Pȧ\H .;4P.ȫf&bfUyg1aʏJ&4cʣRFE#MaA5\qg+M;bups|H0M8]CÂ'9D$'Yd!7{=51bGV"A o+2z#K #MJ/*FTg <~^Óg,E>Mt |.89؄҂X,IKsч1u"x~j=J-/XGg0+TcV)2@h~ FVmveVg_9:X~F7&*Z̹pt){w j8|mQBG6T" /đj2 XU,^L*Gg ]W4g BvN tRꙁoԗT,\pC;B#m?$'#0mJtąo,f.'xU QyzZ^lh ;,9QSWHz|V\RbKW0夥;ٰb(fMU.QqF:+!] gzO,Y0n$@U`bÎ>czؚBK \r1NВN6/CqVnH]OG8HzdGŸudz/69~Lx Uӹ+2H`| T%Elwݰ/y]\(TU/s>;t,‘NS&U׵Nd Bo;%QFV$ƼL`8yoGXq}ZM{Ko|bzQj'udǕ! s K"m[sWhJ\cO=d ]y̫t12{_"ӯSg8Y`8iyE֚wR>x( *MT 7Z&a681qgϮ2lk}}ۂ"&\>^et>E-@dܫDC;D=ZcZ"\ɴyѴ]U~e@nku݋w{}7>FJ1ͦ> @ͣ&*ȇhZo'ь#wV}j$%$ mWKqmS" `(g5+fxd*l71>y"_8r)'u[ {@DЃkY gID z@Kxqn^xKn|5eʗ7460|ACҘKV M9|.^|ȟY~zy)ek5x `-jr$Xzab]JNK_{`B LwdQТ=_EyGsY'a̷![ZVnXf-kY.r59v-#'G^kЇ,v΢cu\H_"D4`Kp?cewWAP_`6bok`@lU_$5.c *vM,R=EPSTȄ۰@ ]>poCZFpKq5oMsw1XO`&4~2x) ]f~rOxb{<`AV]aۈ)LƔtFhV8{+oE4*͛Gw*lu&$|G6F5*Ws#].W^ 4v`nOSeUPYˏ"8vK0lzt_ Eb{~V=d7D|z_:=t:.8{xp"Yzi yHmn(U=m=fD"U>ZQQp3v^#g6zE+<5˿0@Էb  @=lWLrXHu7QU&efٯ@pZ Rr4@vYhDg %*]՞A'4^3h!kÉ0΢!eD, zjm&Zϣ5 }nYX~1 KaxezX]<GFEH"Z6W*J]V)A=Wq𭛧h!B`m:|lD/vОXڂ'fWUaѺ0}f]|wqIK[ycּiMJă˹K^ģj,F8ϫㇸᖏ'RBQS$l!cd)1J-oRњ/{8Su"0&-A[W(@_Y((!~3dbe1 i"HBå#wڒM! hĿ* ro&섽3]3^d,S@sw\-%8 h#XLÚ{BS|шSm\#%5o#@0U'VF8'!bޖ@/ZlGFpPRȨj┴Q_XN؛94jRn[>+845wFTTQm/Ÿ郔3DuwcvYҚ&T:#HΈ[!svr[Θ"_^AtvAkKzO 񻊱gȔszv0z/A5>:7݊{KڴgMoյ+7gn?w|'B8ZQ ѷoH s16&c\fj8jW izJ 94 `HCߞ 4|08۶7eK uy4#<+e}N.f%+KAϰUnB䐣vGr9&' _I' ]}( % hZ@]SIQ3QDn`Η([!mnکPOK۹t.G,$]Ŕ%&O {"zuzJ*AXl'HIl]g=BLe&w,W e;=ԙP<VM H,GOov9- 5c r]hKO$">%Z3 F^Z'pNRr󴬥0W Cl.BH?@AۜŢJ۝} w!~؛GНzӯ3]mx+m!/11'4$84Kzx.7] XY(U$brRMl"͚|~~LuQ3..XÅ{D9/}Z䟀> \hX0Fobـ♏ρ8LRmqDD>HLDZJ)iZNW!׊!|jBA$[%ȲzwlgCsG3ZM!}T12#vj)+]6ɮdtC |2P P!S@HSXE,T|d Q sXZT2WZ]XX{ )sݒ dSnj*dQxL^]Y895Q3UwX*tʳ@r˓P[;tmnںkr}¹b2S~x$ݢH(eiփ5ُ#ߐ= 1oc&l.c . !ۼ\& Ud(g˃)\ħI Mt-0DH$@o_h@6N=PBG`jw5N84@bJann",̏xRL"\QJD#tJY,v&?g@z/2D (7:w":?wVvک~xS h1Ǒ9-+Ll]V$jBḂgItЕr/ 1>=pV>#eg[{66UP W1>UJhXZ!t l_ײw.'$SJKPuspf7 [Qއ%g<3}GiNd*"`7'ŭbFCz wQDSn>ݤ7M*PGLf~HvЊ[s.?i&V[QVؤ Y ^3J]G8,pV(m zp" 6erhD'6v%Ԗr8f'g [ NɁ}IȹX_yT%CHsaV>lυ1hk~Sc o1ZBt3XXN\k+;pׅ27tBc[ \t`2 h3D@bY85ȇz ?B)jo?aV~v8mFnSDĠ afZ"ăNqs "8-,6W5.tؔ۝Ry'4])7!nQиɎ0AJ5*UW?HxzmHT˖CÉS(h Z^w4v.!&@v-Eu T\ IEk[$#gDl+q]یWb|6lf?j8d{XGE =J;"D; 5 7E=`̼IӴSo Ս!NIyF·bZdؔ]Lx:s}g}tْH6~Dxa^KJ}uAv9W50 9'9cZhb"SmXLL3HIJG 2 kQM~l`ې6 9Q5.p+*0D3a~F2xݽa.s6.Ϗ ו=o1 t UnOYrt55gPґƬm?'a:ߣPu3:d ՚޷N W=7κsaU襄qj`>z¨9g+eE "8Sηw;r#)Sib`nNT܁ Q:Lւg6jKx| Yc'v: |ɯFB6OEi\G sRjFl PdESXmr27h9MxV`k2ECs@PS-d*e 5ڂx!hgTpS](QFGtKtWD'GokP@F)9(0xl,0V6]%W@uye iu8EL&xtS<.q43 5T ν^)ĸ,\iH[cZ$ڜ401/ gUjJ/dgT$FMz]#=OOo) E #r{&}RE6*;{|JrCi8LK˘!ZϿEH;'krXWxXol ݋˰Tv)ƘD1֤y?G;huߑM\cvl <: z5)y-u82\})~ G$+gY4eڬLw'5X {h7#/"?7[ɪޔ\ o8. \/! F5 .o͋ .\6!DB+f.ʵCJkւowL#`՘p㧵XX0K䖫;V&mfs"E)-NܫCWen ۣ Q*nXmٌhG1Yd{#q`x[~YiQ#4#ޅ g!L Hy@]'au] /e`:/*I-HB[jlOl9m-s([gA=( qa2dGB牻_%Բd9)1;sd 1B &C!zf*B'fj^M~VRɝѱ oLQU0b'54J+\Hh sX 1~-3m?}P,M_;qo !XD#$~ОY0~FZbah^$ - Bpʀ;?5Z1_@ W@](oZYQ^m|v&l.Hp*; a4&oAͻ,bσNf7H=v9#8Z9_SSwpOSxts46CXE }Qp`Q5Wt:!TXxtZ "?DXT9?Ivb+nUnP8 eXx{+Ͽ,B)ʄ5v:U<p$an7ggkfx$ 7썈 8QBt~=&XTdZ0 cU0%m!Fg]ː")^=((X&ЊQ`YT(b@Wdd5)H@F3+J Sf#i_(,7\"  4`zGG"vWi$YϠs׊L?X%b56>UN牓E .p포Iv3g!LL2 gfrQ̲K˶{xz9FR`\'֩&ԯImzd#/QN|]=ʪ S04YS@Y4AH#ʛtc3ECj0 %QS<ʯe`bQ.&69 p)UC`n HGkqaBr',J(sMvFĨ4wbPrBSc,DeS](|ARMdǖzZ%j35h|e\Mz4̥žwCr pE=РeVV{|[Sph4'RF>/Qn(<]w9$OljSi )ir+6] ׁC*S3:pp 9gǜQ}dz:ɊK'k;* Y&B蓹|+Qnw RjC؇}wSy.ꇤ'8~  6%?'c+twzB>^4E" Pk% P@at|ۮ ~0wlYyu+-u9FQW @qBZ /jk$de3,`ʣq\H =۲ FA|#nd粙.^4F9U[,-C?$꺐jfslLmb߱@iF-3-\PW. -؉`ʆr#\!WrQ1aWԯ'-\T KT8ޣ"bl$0ye^h͢h~l,,AsBjH!U%Kp3R\V!∿[5f\Γf 6JY?yTj^ɭv=rV0|zPScH0~عwNzm>=Uϵ.ԤɵyQυ*|$܅ه M5 Nsa${:ży%a.1!CڮZE-Zݤx,0߆2^H~5#nFOwt{/dן p#H- #~-趷XŞ`LE!(g=QXL(j<( :Tlx>QQcH1zU@q):z#e!v:= ZXti4?ݗ;#PT=G$d5=nh8M1E>%`&@"^uhcoiV"V`[%Eӌ w]cjf6 L^MfN{]?i5z+6΋&s, p&N)V&P]I[Sa87nHp$L+҇_0>(OY ?-$#>H]Oʳ( :f_H7k2.a5zίt̻Sfm,3Ю|A5PnzZFߋ5 pQm`v>Ĝ-[؂0yd9UĘ(A7 7)[3Zd%ޯb=тQSNhLm JmVzd2W΍- (T}U~qJO@oE$`3AtPK)Eyfr rD64Ɓ;} d#|G#,;K'߱u -8+QTP:zԢ&/C9UϤ$v-fGօ200]E"08_S&DIͥz-ȃ_ މPk|sdo$WSK[鐈OjyQBTǾ&fF/A[n$J ]46&"pYcYM_iJ Gު`3~M0Mkj652#/+5%Qc[ׄ:!7Fy< 5%WSjB_dmO'oEjaB1:,et0=<tM¡-QG02[e;!P7TrRj#iQ\YK;:G ATtJ@?Ecq4_=`(eglag_u ۞/^#e#G:g{ A'\L c e%ެ땉 kɽ+$XԓVΥ!chbr^LV4R mp[ð.3{L^Jvn: Xְ5Ȝ*5H>j'?-!hЅtҠTDQ!>aoqfkOrfla4w45tPMZ E]9!>ȖE$%6γ(5R@3peI %!~JT?H-B+^NR|y1j؍zw ㉼dؓ);/ Q}ta/+k Ϝn ~9f vQ9ط:^ Zk>>nI4<ZmxAfo GU1Ivv?[(*ʯߕ_W`Sk ʖ*|Vm흯< ֫1{ZIg){ގt4x^$ 4&[ nɺPX5؊k3ӖGA$@x ȖACbpuszz,Y]|RU(6$ѡqGp%ѽaL OT'^nzHsf B*0ZdH1dxIn% &1x.X1ٝKE_ Sҭ/=t7bug%Bv*~sL?+һV \Hީ*dz$8[ZLA.Q7AMv{gMwjt3yQDaڜxa{=Ь"2Sp oL6o?*uO|4Z2Z5_\yܢmׯ[X `Yܼ JW]_4[b=8rl(#֌7aT6f',k^ Tk on%"Pwp## xT2ЄcQRhN[(@H"?Ѐ y v~z͑hh/ro7v:pO&F[ RK03!WcԞG4R#A` 0]aJ9M߉ϲ~Z\ɕURVtn%[ŝHmWY M'PRX);a8&o цUH6'K<h+}\Eu+lˌ;Bn$vu'`Xq07s6? v_3;9Gj૊Da _U(aϢQGT0II0)Ș傌z S76Nk3vz)p\ܼ( }9)Դ(!\_oTk)6ppGLܯ/bGO=i6x*|+n*NU[ 4uXx4/FBw;DWߋ#ۿB՗qQ` âs"a;-WVavRir">G|SW~#XN]`&\Xa'"U6Clg|.UT|yH\& O#- Nɧ/_@lԴ `.8GoyS_zXxxJƮ9kPgY TD@a,`sQ-*swgӉ(J:1<ҎZ/%opgFYK{ >FRz/;Z" 7d8Hn^T>r֍&- o +^%L,~HZ`MUq R=n;%̈@Ei r4K{ {b(Q?9MFL4p҄=*^fısZU^6CcU, s/ZPJpVP63Zrʳ p^F X]%7S|@G3_0La' 0R[B˵"T~RTO$WE #BfB9۶}qTlK*fECC ޖ]Kv7Dtςn`Z`k9? vk QJF|4HSeujL{)@.  (|Cq@qJ\sxUbLE6I::Jt|Bjg$ Q@J殸<ؐNh'&;jp_ENXg]$]sḇݪD. Y@Ƹ.%I4?m=bv(sfZ`bj1%.Cެ/ s4'L~قJ Q5# 2Ho^׫v%:<} .+dtxOrz0K6;jd,WYn!`$m>JcG&fCec%R M@WgUS${C^SĖP[X .'eK!y"J RA/hxUԣھNe[Y&rYNjŀWTS)v+/6y'Sb}y:mI ͉ <'զ£qaVSŚl4ư4ݪՆiF@n2J lϴxqQωi.0j[9Z~fx4۷_C/ltV04zY g=w>CBJa̦\7օ&ew]W>/Z$ucjh0@ fpV{ysHyq]zѨ,Ϙ*j'#fZᷛ `,,tX[9h'ՖE#Ș*?=;wx~f 2Z`E^=u^_͓':}u0V3q;2JBDj3r5p;G]8JppNW^9@pMM0]106Wa.!BOVJdEYxqU 3vrp%2*q$+g Hꅫ "+,}Exp`0tʬURԿX#jvJ+ZIbj /w]<'.\iCBMKpgf_?ew%Ѧ87 Vdh̸)L!^{GlC ovNb}Șy.q-sxYԲ7$Ţ M0I՟ϏkÀS)? u3uU~;h!9ɄI$t>0рm@Z1Fsѯx~xqg_M*,.ugH:\uxH*ʜgJc ]A)J_sc•%Vݧ@_mZkxrp_zmeY0;y݆d53QÛ9`-w r)9A盍U|F{QEϜEgygzwl%M=o;y1"|6č^Z3GO+vf1Dq3zT;SZ3/>ZW3Af~LW?5 c|$)ucMa" 4xJSq2e'#zN&\ 7;<||CA1Z1etnԟi_YKwPPI0剻.(`}%닟FZk `DI ĐoK/aտ=ñW+vS)I\e7MaB& b+32jpl-p51EaQq YF\1Œ 9h/S/l6ZX3bG^";f%ǕHp Ο- )9;Q۾ O*T Ȯ" 㐹2tLW Q>CBl4"W,t_WGyIun;=4ߋ e[;d"‚b8^y$Q. W:j+Bn=11?ݠxi:~SJ6cJ <)&КSPB@6$?"X2ҍ'F鬎B9afr^H5zW臏<57NN8œzBzϯ|_.vZ5{% e_E +#(9rL2}tM.IuIF 2VϙB=<ȂT;^A'a$jh *=<~q1yR Dm*IFnw_xB Ϛ5oolL]=,&e =_ö+kDQ_WZ'Pa$a7Go|H֬]:E7*!sሓHÎ\eǸFRD۰I拁o!9rVē} ulb~rĐeTrn& LգևvUR3_HEv vv; o}5JEA}v6]}PG\Dm俬] ?9OQl~Od 0G^"SfW jd0(r%M q".) s XDŽU pfe3o)Z;*Wߎ7IGs\7hs[=T7{A1F>ƻrږ+Lݨ<:&ϒ((M@՗=P!{fU69~e~gR?AЌjɿMFB[:U*] ~NiюHIAʤ7nU*0!s>;?w,*+tb"[̛&CD>e~W*#b_Vvl|LSU2AB5Xٜ~kpvkBj8 yL!FYEW ?r˰.fpoɼ7Khv+p]'\D4%EL6=^Ŝ=b)}0M)MӆOuKM.1U]<=<_80ٚr'swDv<_iy[h"NْCn> &\%Z^KGfVׂ[ta:/?r}CQUkJ"|BKM4?>HaA4X3 Qex KG{o!~JKPL#ܬ"@&?)SQ6JޏU\36Rf'0N_{հ&atn&8?>J%+Ftkfu!.uYp"{ ?9e tBlR.RSya`=0_+ r ҂ $oIf8[1FacAZQAeZ` `$Mru\!N5ȗ/A~%X N%Tɹe viLkzHZU#_rr= `n_B6Bxz'PAAWrgƯ1vبHC I*% .! j,7Ӂ'-/A2@*1[%4~Yݶ{ZF|rh"#r^xq(4CxT mS%*? k1U o(v 4u2_h=%\|82V4Sp7)!rО<87zr`@\JCt>(IApW&ocp@?p:*Ri(7oߝ)V7O)Vs4Q'Lv3'&OfNbWtG@+&c<S5@Ei98;#XĎ!am^VOLPlޱ9f&v#hI2TVJأ\A/.I?ҳ., eM3Ͻ7Y[FW X^9"FfٺA=h\⇵>w¥`RFz5Lw@Ȯ H8^gb<j!S[}MB:)+ @1=IbzF8 G<({An.rJ6RWaDЖ$ꆚ>#I+fZ'wX !#.Rd`vPa!,a~ARJ!efo<crdK_/AW'߶PM\Ӊ4Hcy% ufvtO$}V66 fZerN7h'_ JHvOʎ; u3^\uq)j@~o{> &b. IR81*xy}_,4rʺ.gk? //Δ>=vJp'#8B9*$tkgۚw>J"gmJ7)9B@k8+9\A :Ո%%ܤ)@hhGvVu-;H| qC,didR!l-0#k%hW3 W/ҡGRrJ}fH(V-sQgn6Ff9{]s3~+AuaFG~И̯ TjCHP$y:. ϒx7Rc~@beF_eAY$W/UV!/r6M!uM ^mn5;?AnQT~ nyVجO*QX6կw+GKܘ898:ދT^Eff/1|5H)JωD"H~_rf1ԟė(A^4<óyFڪ9C~KrMk:$R{Z݇A@Cl#)>2 e$$A9r0\RqȟГ]WKΏ6sȩ ?~zlQ8BHUg?oMoZ|m˖r7^I) s rxwp[`4uŮP=P*=q`z,sb'5 hu{3ea,<k7+>UK>`kuH09&H],|Џ.a#snymMi|LG;>l0ٹɞUP4Ts eoҌH­δ9f7.zH.MĹ(BxԏB[QA]x 5hRVqevZFmy[ĵHEXKCUJ,PfcW0ܱz̑v*aupZU&֌"Ƅ^jv0叛m?U.^f iR':SgS>]HHUNGQ1NfKG/}±'z5K(טK郗fkɆLP%<8E$ a0} p_q7v^J>eQ:fc9Lք\%Qaz N;flkq%w*T0YG4 ,;a"b7kdQ}7rj P퇹M'(xN];^;c+`th]LtۗrBֻxRL8 }dP~LcJX͋G8Gm|c`;!䨺(VwzbɕQH}usRձD=n4oUV 9OQP 3)eDf%ITa{7&!2e#:x5/俏 Co,Hxzv(>ψ+;o"icׄn/ǖ><}h؍!8,FՊxpm(ʁ@5*];}p&u7lpqm˩_!+ 5d4V S m^4T,PYb?$нD{, R.pR\ؘrB/ƑA=Ɖ@顒C CNw=#E(`W!cDzD Ԟ&ZddE^kaB)(i;4ѱ0> E:}[MBEn!;!Hnۻ 3t}Z Kv4ѴUÿ_?9lhJ&{L?{=+I9JOԸhfp{^B?v$EJ.X b`Pc3*r>J+ n,稼Kه+NcE;N/LdF  mG/Eݳm&IЏYLs}|KBUߨ45z237 E/Q! kv /ЗPBYQ[w3?#g]U9"É]x/kAtpi+ p;ʕL<٧ך3YkoqrP =H:p;I]Hbx . IeLt0zܪ\x~ :kfc F.NZ0*E FI py!Гg_~;vtofEhJ9S 9|(yL;( [JlPhn3J>4lxnܭ00"q<~ #omj &ƣg)h9+k2"u\B-z:w)iƿƅOku謥aLn$Q5=RPs)n)e|[૞ΝqsP71~_0!pmai{=XC'-]ߏzp!Vhq0&v؝W{|-G+h Nr\Yz')ܐ>-{i?*Jk}72q%L=ECOAnI 9YGut%(RJpTBϿ~uĊ+j\1Bm Iw\T.Ajv‹ DQ՟m <ňJrW :)U%`6JXM9/p23IIq|z0?6.*Ye6jew:.P(Ca$QRVm\J`ҭ;1Qii&>p/>8QQIC,Ĭ^“4F;򯊼KzD:@!T-zf|(A$jsnhE Ip}zDqhb*B"g(s*XכY-^srIpvYrm%!=l#U|~"hQ1٭qmU |Ɩ̜e,h A}LѐpH%>@|RL!qOp7?3W4rh4& 7hNO}p/=W-M05xͣ@T*@ HU&H D"X,V0Lv%5k=(lgu6W+_T6z0 M;uE6pqH~v)$TsbV Z&Q:uL'U{¸/$q'` (S>Dh/=rG LEl294pMN?5e',EtT s;0 <@?b*3_6R=W}ꎇIvѥV~rZ@ / wh#g ˝^]IvKgFC;"C36bDٙ<+oBmÚ.x2nF{귯{n?ݵJ[aG͞Yp}/g'+-_VFʬ6{kCelEV'O_+()%{sb6#uqt1q)!`iIoJ-C 0Ƈ.Zl{x8 R Ӟ1"ᏐT ʢ> n?tGAۚZ:co, PmtQ YLZMotK"O]W tRrۓL+ZZw,^ؠ tBՕr[jLg[&GO{c͑ K0S1~΄1%xh}87䉅/ 7Gb;%A@!Gj}ɣś _%sѻX$2t@eWϜFgSK < RN0t%d>0O'm>v׶KMXpXvSm~:jX͑ø% w(n!P%%n* nCKKD8pmux ӏѶ$#{9 ˥O|%uG[)i-:\$d~C hxgc5:|h#eSqXXۉrW0dS&é0&o|"6i W?ʠЗ?J7q^ þK7MU7z^WM;JnPnj4xӢZ>s1&l&>3JFL>b4iG-҈)YG)#n !_y ?^<->0.:Sb!k+L ɟ>:"2 =E%SPgJ+6 s iyyԵg[qcIEoh<%WSJ-4gxս'SJJUմbE*.T,mܐvçn;Yx@K2Rt2GrKy)`Pm~U$gD_- Ђd8}PA&1?(,q(O.()( Մ)$7 Ƌs< zoX8+ǛhI*SaQq؁{MAqχcE+O[ ,= H .V֩i!6}0@åWdsm b,GCn7A1?K{;q]^U8hk-,auOPNY_W ]Ο+,[hք_%.q,b|WX)@ֹa}W׍ma*1 86]\ލ%yU~bڐxz0%7()f@CuJ=s^&൪za wN䴁XU)adAĬ _/xF:"NmwnQE|1h3=|FAP ,vT=8Gb(Ȥ0^¯0϶(ۏӛ`4H$1tBdG @o$\5Q=aIt{}ZpP∓5T($Vɣgp{/O}&2췯M\{'!1M-`tޟ@V-Z&XY%<0~2íZ*H cH VtgY{Z燅857bj]/}oNV> DVkt}KłL/L /#5ф\˄b3iV#n=w&uqj+$v׸w~&UC49=ߘ{ {IuV$d+mMr ~N$epM=Dh r3J?OYߦ]߫-9F!>Cg>"2pA0,z@}_7?27x0@y0lӴ^|[N>hɇ:u:DQ! HDNVC×ba6I^p|YzP4\U ʲU1h i L/!GXzN+^KuBܢ|x m9v3N02f? ?ouq" t@[PN]Xq>>rˣ/9)Y [_ 3rUH`OFeߗշA M~| ; G',7rt=чVS؞l^:@3/\AJ?(K|/O"+O#{ӿ͙J#+3 ^pn{yqL9^QUhL^[A@B$c,;MnoI\J)B(!jm nOb9i1=]n ;:վj~[B`gu k.??WdW>lqNSYHf̺F_' s99${[MOAi\EaBz#6A u` HjEP͵,2ŪGP`^aw*Ant$773HJ{*P> NR4qJ؞-'tK^,)Wf44Fa=qXPH̚st8/娕 %ruM'-~Zua#yOu%NXlޯNbLtI@]>S791lLc4X6$sY7##h=n~O"JPb~?sdԽ)0XzV! 1k*0yQMI+A-tr ]#<} eAa8,9rr.07G!L݂8=2Ce2wz:K}haJ. Q7|ܬܺYqr'• W*)Bm-cHlwW3#-6jr0۶2g>DsZ.#J~7amXs0]5UvjVxIߨ8j۴;E6L'>gYo;v @.';넪^4fofl#݀@ZMS#x9Ũ 5UA`Qn׼2g){j1ƆΌEo(D,骎q5sUi)Bs[zP:%WB L]|kO_Bn b^^=%QŮpEJЛ Ⰿ}8C8H^^l_r>M);AN}BImNS+Z5Ҩ5}D>N:=J-NV>”{ 8cX=c}%*+5놆]q(1V_-8muo;f`tv x5N"A3kj(]lx0s`V^|E{fәo!qezBU7՘=-0::iv-:_+ACgvJs_}iE[rŽ6ҷyٕGwFr>t1i(=BEQC- k؊ )#2CQH $FȢ2>c6,hs,' f;uQ;/x,yǰ n^'O,9@m;L8rؖ AyNo㛫C!mJ>Dw/Oi6B MUC܎nvGHܐGY`"s1K) ee*/nHoѕ {dbS +XF=~;aΆyADs~j k//ƞ4V GBxXU9GÁTen50O5SLoTB YT 3Zs0>13_c*)Cv}Ϣ-rwmEvj9x=lB0Ty YrKk䱫1YRA̛*ךd?SҖ%@H>V_w5Aثh䂠Ì:& Qស#Y \V}0O/1U 8WjP˔Z${}=GF `. OIgB]#OS&KQ9@ r`<|\}DEߠol]ji-K#a&Yށs#ʆ9 %I~)5Rx}#y;Z s׻c ؇ <. : m̮>ԴQbOuܟp6-k .JeEM8^$=^m>.a߷NpA kHLar#h01 I(s⍲YWD$ 2zWG5i@͌Tj9a C5G aӮtaJs7,ޡ$_b1u[ Y{@8:~eo.;pDl*;p $~05 |]k̈́b =ꆑ@| DFιvYq3A',w=*ס`V p&IGd=(ڴ`'9E TXN##Ab?p Is>u@dBJ=_یàA [g[j&*W\-h+@A(IU2,#,./8Y/6c0n૜I G?e^4?͋%jy-zȸк9wsJr1C`Q˕0l1D T,/re8C__e9C$( iG,cL8'}GnO 4Mދbܰ`5+LkN25{(6ͧgg0ɴ}h-a&6T7벞oJqr^- r$VV9j" JU>2zp]EW 2|xvԏWL^ ҰE'K\Ȑ.9(`B":mVR:Ýt "(Bu>2k)8-3 m{V?{{G4 b3?Iߣhw@l|ee r?|y$~N*2G bQ"W*MZR#B]T G%(F^ ;uxKIH߽9H,/bZF)vOJµ-\"8{BK;y)>؜7lgjC//bBjdxjT.QfDTyf"7q78~\w+z@ `ğAX'~wcȮX%fbې>6fXxtA_Дq,&jVWϢ'}_yG~YU ŒTD mA!|974gU̒} n5k筛Uar Juy'$xbL"}ǷCڏZ[ y$faYj U;/25v9DY:п_'^q GzS{ϩbkL~]|B*"6\V!g-$1o\mqK N1Y ̏n5BD ƽ{S }C]2Ĺ8<\w$1Kis5T`>|ˮ( pQQdC0f]Hb+m}@,BS5)"-Pt;5)>)$E͹(~0-(KnX 29貞Bqfu'VQAK؍pVW,}6fHb=;$\]3C#DjYR8d fF!uL#|i[#[k2yܰ%./8 \0I$c ЂiIBF.|ğlK(*0uV|2eߦoٙ9GZUe:x܍w|;'}*:Ga+EuCJ}i?\\+@ 7A~Ϧ<P"<-]>CC>[iWr=,IZ5GQ聗u2ʶKj 4M 1*&D^YMvx%#|"t Pbbv _B/Mvxz٩"Ħ߶FdQuQ"=הEhm %ae|q7Qe\uyܫDWs$dZA|)\!p#@F %twX"B 9 fyX$>{nvsY۷qy ST9Xm>X?5kR۽Ch7 _~i},yN"qdu-JurcܫBU? :͘ʂ2 ,cF釳̾{:RN"ZX97VG+ثK`=z HFVW4| w+Ʉ KI r34}zw@H9̒ުlv9"'s~sA+eW?#{Mv5Rj1EwfoKCuQE Wm& VIYe-/hۥə\Ǯ#mcY?]`\XF{]#UO'l40xJ{ruZ;gYHo݀.``?@!L i`% FjP` `PfŲ]WVOѳIwthz w?Z 1ej~#Q+g0쯬 uS8Bί0rP}/)H?ಇ}*L'B]lNHcXet]%܋˔LLFjwE5 ȈPTiWe[]Ύ΢vwu~>Tasi//#2f$ SG|”ͤ9:4D=P`vc)}ˇń/zObɋG-P/Mf[FsL_F eFۣ; BgPVvqjvufJ΂2b_ҤSrS< S"@ ʠ`!&0wؑE foCVp72kXY@rq=Ś}cPb$|М{nn$[#OXJrh;YzR9i?}qwj"*R*9Y\+.\SЅ+;yjGɖCHrH-}wS;?QuxG9U[|ݥks 9xqP#jM`2gP| 8giD.5cгauV dqLK`b_{HbmW+Sj0V4'qg6K Ek'j:.җ&uHُ2ջJitݑɅfyyj qF@~+.67fڑ5/ f²53HBR2H+ lʯ5N7$X6hLGqLӌStq>HqA4MtRuv=a/P^Y>/n'xtvUJEYcO4̦.J0`2ҭ%iH8YCm'8HW9+Pt ?dڰzTp.G]ҴݥoIy5` D/1Qc_fx^E [9ᒧЀzGB7,k,p)gM' Ry!9]h*|r0nL :([)w43Iқv[Ͽɑs3|-<Pj3$^4lܳgK\uV2V$80Fфu_)i^bHPTeO׃)wo-mK/KET1ڷ[:iBD|!5r^Ӡ0݌t}xF}S5ܢ?Ws~$H|CTanEhz4ܙu$m tiƞm].7m79@J)@Z?(½"6.LRWs>dӇ(^ȘS $P΀ Zj8}~{fe94&s_RidI tÜCdmN- ,ʗLA%PUhea?K~ij PXR-)UH^JKG(xԻ0L}La[ƶ|R%fv܈UdpGTxir >azI폢)kVv`uyJUeK)4M,Ln!>}@]cŵK94 _e8'@MId!,1!8wsd&Ҡե~bʃעn 62_$:Zl?Mߋ Ѝ$:zҶFkҮ"ywoE )]~d v o=o\C HYQ2SOmM|}?˩H ̥OF&DE1m)~~Ө]W+#قV V0ԕÑx\\~@F!Pt3j_#g<{>&L`Drn8?[S[AЌ;n|<)+#3{DGę hY$1y`8DfFTHX)aeQ^u:*(}X-=-M%QeE <8IܘsL`rd2TLu\dYH3HOWU z1ϞHSK/@EX=xEc:=$byp`>&փ{ėBFg _I7pa&^3_u|sبܥZu \s\3`V"UwlS&[r!MW z4Tc+![BI%>On{-O#\Tn/"4̡|F|?rëᒾǔzu e5Ft#+alSn4CrEHHʎҙԗ6uN݆U=k~K9Y& LI`&FzDrC a"|T*ǔZzb;żi~)c*I;^: =QN30U{hXĴVIhi(FiW+4߽/jʬ8vX}oNt0p`rW~w{|]*,[BekyeQ7eNa:0aHXS 7;Rs<Ŋ"-?˥_GHp\ɇ#m>,*^N;;>hI3Cx#YɎbdbnF|6z5[K0cwF yyY&4kwHD_rO"簯 ɘ/oxfU=g+еCH ]Q/2%1=-W]h]֑ň9Ơ4&TR/8^2`o;< ;ӯO 3SCI#1mDۆƽ `CV<: veB"Av<:sQ?q^+ٷ|֓l0`Nq d<3Xs7$y#R&CF~4ax2S6|Su9DYP uQ l,_mmυ=BńC뵣Lu$7N2CLky/z"K)G7_ѷK' ,& -[t ɨ%HtNkE |{v)Ob'oq2Gz8L6 ԙ;0PL749k_!+ j@~$PSR32ĕV`3aަ*r]*d/zU /OX1jw\&3aCڒP]p[:ɱp 6|odn,m "aǒ%z[Om-DNˑ(27J8 3=Xr`?xM]]Ex"q)͚Q7 ;S,t56Z3d lU#F\TGOemW]A}!١FAš>fj''G-{ Hӱlu&Gm(d27k# jK` HEtcg3&rAYt%fAl$ pFߞ(mf=i#g=+2YћЗz -ʂC,It?V9\;QkCtwGYN_MXzmXLtQǶzVW!];Dc[B5`XAd/ץi9(G&7gl0smA7pEc%RN?mqЎ #F-B>7e)C`z n -OD0 蚧 L lsFM}wS/Z&}}$hB-+)sBXN7"WAG83̵W_ +r̾1e'Ovbmg5\YUpJjM܈U) ȚMh@3]_C+8"uoGeX=D}k~Zo\XiyZòtaг3?}Jy |@2a*ńxaL=@(cjy1Piθa҉wWuѐL\+mCvK)odhɃbPqD":(1C̕%!M7חWZ:gZڢ N&[saH m\D-r=z NEg6o /3r\)͠6_n.L^x3;?ȚStK6\ܑ=LՇD@٭LȽJxٜY~H|Xe\6o]{BD&\69m#^<fS6EڛTVX17;^1W۠-'hDnJlT16+gx,Owv8k9nN@O1{ԎfQ0ⓋX""p<0z\-rQES¤n@dn8Zi:@Ӫ9a ѼCKv dpD\˜ѓ8t%3ײ91 duc"1KfNvyy$qA؃;183I"NWP[<ٻSkkZw׸S!n()0\pmpՆr&电W~ɣ 3'J2+]Tb#Cu:Sf~!zӟK׽Xwt6ib32 lW_fMG̱7 2T6VztFP&;]F9ũr {ɴdgu}IwSW"bƿ/(mv5Ӽ;Y^n~=&֩ŞV2tbqC3btx2KL kHP3*RiΠMF="U up{| DڠC(2&mh2nTlUH*fwg 7[ ׋3)iW2 %gN*\y!g.5!qle Kw@"@CcaAA8mp}j~cu]c'`" N| }"G15Ys}'CN8ƮG|@QVʘc=+%/OFyB Wip$]xDaZ--KUqaGf{0!$4^w&I*D@ݯ~dR661H}IZ3 Fhxq\Ɠf|@2)+B߼7R{Mn7-7#VE DPN+DXa0dp_Q.G(x3oS\73 )fLQg f=w1?CWUum|)(\߮vHH Z;A. > ttO( C歐&vxuuWrl w86)Pe$Y? 37B;d5]%sg.1kD>(Gy: 7M~K)gfGJ|e=8?K #Y Oce0YY'JѨZ/nX˄gBcKXK#a}ھOY+hF%O!/2 +)$aO$β1C*|E ;=)`mF^?ZBښ_(5F;=:orLmBq੺NӠ$c9\ 6bCOp𩉜| 62K!^`  ERF+pW&n_Jᴭ_ \K"7E\1WƆށnouwez.Τ^0adV-5jHpy"tG׫'2bF5P@%ްY4듩dU!IM!65VՏYz5R`c-Li}&铈#R€I.bٗ4i![i5Ds8UːY6SP/{>&WW Ӈ I.q:[sNL;I] Ɵ ?7K =,5EqW ='>6=z)4ٸm+?7O4C4e~<B7"O{;%EkI5Ya8/tPoi I%I\a6yt:s?6`র\ d:BL;h2yY5%m<хJΩV;j=wbVɢ2ȇe\1* QCyOV"1Sbd*_ "=G> % rxZCR#?P'閭ц hi:bCPV >C[^GW6'hW;ΡO2e"KnVoq1 UP)Ro׌5^#5()Cm+s:F[d֓H8b`@c!Ff1uܹ3 {k{pu߀3ijE,4 tdr2PP/v##_+u'cc! ?H06ޒ@/r~n8{ ֧ 6pQ4S vgyCDGǼ}+Db.@A"Od7ʆgiyo.Qʌ)ԊQ"bާ' :bqOFΟՈ,.U[PvKw..@ 29eB]=5meae|avy:WGzMe E΁S;Ɖq W*Wo̶^P&—*_)p44O`6b!ܠ#E8ZRg.wÒ8QO=؂Q+O K-i-V톰d)Y}"0 VwٯD| +kp=ͷBdjxUY(A|J> *Q`EiR:dSRr6Xێ)}yU? ҵOX*UkZsOB`) X,|OE>etmxHsA|@۔2Ct;K7Z%>;9:sX>ah[=7n4 S8{ fÌ{dtd666JL1ľ{A릀9d&o(~~ݶO}m~ͬrA]$sJ|0 dH;qlMkHW~h#%2 QYP}بH(  kkfEk"w܍pk, 1qdC$E"R %M~˻/i"} Y L:Cƻ՝3acK<;i1AE#gPcc7 &o*ʼn4K]CUkp,h;ܬZy\1l΀XϤpf8eA"-IGGJQr_&] ~k]rl~pz dF&ƖCi'@@4{+B-trʅOu1M@w^*Xx.yȨ`Ev6\T]*h {]Z {č`ˀp ciO[Bh-r?ߩҦchqօWnzLp>rt{EvNyUjF8m+'7'3:e |nԲJa,iZ6k tqS^ڭT(bZ^+y< zUf6WGY7hKZfXUJ*+sPRs/䪣>}MI/^qV;8ɭ21KK0W֜=Ml M1YV-9W(T h("I_;[$mBլTXvB g`o^-!Xj<ʇ^ ==_9NTT9H`;f&mC/#ޘXTcW!!(p!9ARIٔ$_ֲGrɹfl7YJY(ӽX}>E:},G2@9A@3sCW Nչu˜Ye֫&/R -&]< m y'b  &q pVPN+?I10_>LEMKYJ5me(- Tn+ԺĠ1ZQwK5 F%ہ V!uF^&3VgvtY/WnMd?%pĽ =ƴ}sZTW^*6)%5!,&1RC(Mv+6C`;K 0<{UծM1Xl"~pio9WiUgj76Kh:k*MQh<^PNtեEc.k"-A:%_(&\Cm3q輫ګ31t;} [S]"QT9g+ۊڙV1/2ٯp!Q$kfMSQ%k~4AferC>Lly(A~6JK|,1Д)J>ހ]hꎳݙ ihֲ.~"ͩ/kai~0~o9Q9 4lå7~h}면7}3Q_̔߷B'Y L+_G7moIMI:D11aP7EƩf*jiQK39'"LUbCi5qFQSVs +/qu5ۛ~4< Pc"E3e+0{RVZOmu]L b6l֝yd'bL2bSF0D[iT4AsVV97~% n1~zX KFfttb7UThtfϨnѠZZF}{ax@b2+ՃmÅOOg72#M3u l-X_JmbMtrZ/B>;"4`[ |Eܤ-ۢg_q>* z`d؍`*9/ նL*i>]Ss`:̅VbwHz/ə@5?zv: rUZPik_inbmen>[,cÚOh]fZn x ӫ;יYrlxbo` R%1y?\4^QWS!Ao]"Ij20^9r w@:WT똆tU_Cv[ _L1ߋ UIȲTT_v'T6m Xxd@nK}Zfnx5ͺ('MT};&wm }vP-7fDq>欧wt~reO*QM%8miu 1He^oE:)8Ht>/-Xmb MP*oebv[wX"Ls6@%mpR:H:GKX[rf mt +bSdb~[ui˫$rk~v5i˙Z-mȊ&H()&'@Y3|bE ?1,ha+o`>B1RT~CpݐӋxQ(M g"WYL wr`bCGaY]Zf!`K0xVwe>%'c A{}r}pLr&߮В*f{۬A n9(e6{dcYTnD&~xzAĪ?~ )8烠;}=Kg?D8%&|IhEߨ ssAZOca6e;m[ALUD؏QȔ,ia兡a7j=$X9(z/d7*=߹B^n!0E hf4}AwOSEaʛR|Q, (lAU /TEs⼨Mi:cE%搴eW}g) gZ$oE(„؊QMЊ+c;ӅB6XGOza Po!p%K) b+U&沣E"[Dotm*=bUd!,UsH'Dj3i> JoK!lfn᪥X տ8nh5$iXUҁEG{n%V8?oG{"NË3p:w Kx"M#2iaPY1.wOtSDzœxRT(:BO{s:i|`sp y}Qv$T-:eEVN%?0tiyY؆1{:Qv㨒|a +H~2f'•+U > pNpL{*dS]po){RdP‘pkDҊ7>yjwBM0(3'ˠºvF-zl]&<֘o!yatߣRAqs5RF+/r>' <\rj sdclKlc Ĉڃv01P8lܓcG8Fgɺo.?`#"`dCYdc0A ]!uY0+hVqT߆Ksų=a<&͢CAmOA/.kI,p*҅ɋ)#c;w֞9SVC.YӤ+x܉ǯ1#++Jk2H#fg(_A6 U[?ϓl 2ˆ)7 2طè&|4+ʳCA&qFj)#4;^{6 A5{vnt5\sx$Ż_o<8Jl_sBQ2L3 O6M&c] $-O4]#;1|3 ѰtVά f`>Q2`mHP,Evȣe.P 8L8B?ld<4̽o>q#޿Kn?7e>OXޝVCI-: 5θXE]Ūh% `p7t6Ug01UUѾxȤikh=P\sHMS<2M95wIBdm9:nW+'P/QsotDi 4䑱ݜ$N7~S u%GM)ge5?xjY@ ޱJ8م BU^?)+?]+0>Ă&glj\_WFu{h% j0Wrtg^֡2š$=JTIxNz!,3q33N|A3oi^i ϵr } qRR:MSh?=C|8_VL >P}@֚##]J(5SHj~fx_>SP71r1ND:iZcu'e+ii)e; Dogq]?qO1 ;GPB9׽!B)?D֢E&/mȨd[/mO=oNB kR`,]2=y#9Mԩ_~[0prSQ*.ZXPETYƪM-JH seAJyjjlMH[a[INW!6 dA,Z]d:PJLe X%> {vJky՞"@B^ҟ`_IoJ):-XLDPFpr,5*@bYѓm5(˻rL3deMsX(t+uó52S fL "$\+pW3:{$bd[_k>Tΐ|M! uB׷O*tr}>fQ>=TN Ntbusߦjי G3fvڋCc;6_&ѵn (DBĂzйsZ+3U@!$ڼO䰄@BRj4/J[š3L*=:gJƮBxl~2F䭝]5t#<*T)6Ap[$sI{zekCb=.\wiF͗zi01C~\ |ݨ6!=K쳋+@tY Tzmo@0 pZw4L>]h^4%?Cҹ0G?Bkenɢ 77A{4]!lݭnjn62 A#סWdya4 Ӈ8rgِ:ѵH!j6ntK(%$Em(% h"ga͈xM}7M+W'^71LQ-A嬙\V $wזET |g]Hgt (+ VV !eΒh(3BܡJN.8e>KB=1)lj)-5(n%3O: Q [h*ҫhʥ&Tb7#斩* :rDI9ۥsֺ2gpS e:׈dTԭזoEbw`M=OlOv=Y-@*a}9T0L^JAawaLj:}(Sa FM_qm؋*zX"%"Mrͩ [cj/e#`tuxnJ7 mQ&Z{g(^G@ LSX"x/oHcׯ68OlSkq-'Gz!!L4B&zkVJyNhE[t,y QW]Pq;yS^നufOp.her䕚 .=޷=%=ypB<\TLD 87DS S^a5^ y9rum#24ִm `9R?5xc(Ze2e}:P;4L}lH4vz:7>s?K~/V,֣FCcQqԦJCP5ImIh( (ڨ"U`v>l2/X;3m*FXTEĚo!`^!mBr跱x d f'ҿ6hv=^C Z8(N4E /oTh6oANEHy16<_Db7[@ヷHrfBaa zrNʬh*<4$GF#k'ߔfY0U"R=. MXb[qw"au~NVHJZxx0:`Mbz_SĊ h{׼rτ;;l7D]7+FR8oS>?­ . Ҡ]/嚸ZڿC&"2$$݉fKa~?WA܌ppFb @z{"}ZӐ@2yw̠ "nFiݥ47NoN!ZiҖ riմR@Ii}qPC^Z:4Ʌ6R*E#G@E0J0S׊Ǒ0C@# :9z(u!'l hGxG%°4mb D* mm(ϩgZx.{]~RrNBRg"hcu.RVPϏŨCH["<~ݦlM߰?Q(>I[<{cvS΍ya1A$^B.OpSI0&Ba̷`])3,01k]f&'htԤ0 Ex;'\x{YE]<k0~ɕyW ʱf>|W" _3r:ez~I$?>!8Y;Ϻf;a{}RJ>zlDYGJeP糖zP'ǀʐu>,pLat9$WoqCD͎eE۶IXphQ9_AQ'o'V@"[4dWq7,K;Q O\dAH)JT.Ihź616iS*2PZKIz(=_ź:JKk:~ʕ,{`7:ޞM9U=s2Cp&Iq@T}#j򽖬P6m{ WBfS@qCOdPS]}F!T'A\VZڌ>)R5qJ n.r{g;Fe- J%6Oj,Xm1wE^.qωQ~)1fVʂíl,nlV/f~W4*mϿWEIG]-ͱĐn(xqKmbm;q$j2H2DCÒ8b,XQƵwK46ɢT(Y' M MB I֥M۱:,MdLolƪGOF7]շ$mV]k4$]aRfto5zAG-\/ ؈ wx9On w`|ݍN W/)ĹʞZƆԠ: P-BtxG}%ܖrdw YY'1n7Оa/o[ؑ : ȵό7߾afvXy,#A-hTxGӛ݅rUB龜N0HxT/N*;~VYNF\s/"888~lΦ"DOU)S*5yxd1Ą MmO#|Wx$k-}wFA`J y!iw]|H&`ƭh=.Gg~S~,3A9 fHe;tn3ge|7LjTzxs,Jkl_,jAXx] KB>%8k>Lq̆bkEzᄀMT7:kvb=&9­-1,VlLrР(wa5B1[ &ٵq!HA%1X+?cy {KD:z(g#s_NiΖGyޝE~ u4FuYR. Dy ox dJm~-%l<-C,S.ߧG=տ_ea?VI}֋ |բxFC a5y?`{%[ ]<[b)--D.@WB|?}S3yȦO=FތY1>=6AY7ְƪn'*OCVt M/MZĈGQ?r!5ق*sKR{T?#u"H! taD6n =9TAa V|!] d?`^r b rn2؜LuONo =VYG@83|J(!` u."l &}r!㌿i@xmf.V1>rT/HOA𵃦M]!yorA9+7TGzWKjldɁ^9ueFF0 ]`3/79_֦ 9kا!I|eUk÷b\zc܄DNJ_&gțu葍-Ba.b-< ctʴFu#Wsj, sD&8:>e5;T)ᘬ|_|-5%.d|L6M~9M(k?L#(YRCzd-DJP䂃Bc=6˜CJ.h5Ν%+jRhmDQs EڧK޺fH0qh7x!nOM>E rdً7RRvI:?Y˨. * u(y*,sSlX6i/*z)*:GзAwE<[b! _0E _5cp<v.S`R$AX>}\-! m<0e(GM6a[I#{Z#GT 0NOQ S хI|LhlGEդEpA缺NbP>K+V1eBU^q ܉ D(E+ȶ9 ] E}y\ ~y(Nj0 xDJڿVŸNIMԏk0ֆ66SU4OFTlW8ǻ,Y͊OB>_F~Ґ^uH%o09,>ĻDSUzF(Q~@FZ\yëomzFvzlhRz<cΒ;%5^POԼ3#Id=,}6Ǒd}<)9߫O$~(3{^)?R1:>)K\Fy0s\ h1SP(lݛE +5n+8_hTHC!6jSS! L:q+_ BF)* G [7A߉N[liD}N|:ߒW:y8y^LF,xHj{rIԴDCJa,D—2,?;[Ȼ"o)d|8?G /㘨Gy,*}E BBxn fm.&-UPFxh#,Iy9D-a6lEEӌ*%/rpƑ^gߏ%cz8!O=g7=/%A ]Zv3jO2Y /a-~_CZj+5_6(]繯O(Py!Vټ#tIc&ފyA㍩1"Py/'o-3O悓p7X-B* 5S.Ziiva1D&C7y%8 >=sY?AɱS$SEŞJž]O7ຽN k ˜gș#FxohQ|zJ[oe!о?ܧQ:RE3m6q(PǼ=A[_pO:k5cN TPX6l5O4GJ݀y)Zqp!t8\nj$M6D%Z1K2Y0_Jhk"RȐv!rٴ(taJ\]  1q&uGx\Ju%rE L2-u<=Ub5&h fɮہ$&O"@ڙ]xbZUSu(#dQ3\dE vHg'i&\C T#h8|#jתp| hXÃ]Ta01%d5|( bFv n 5iGQb*y3tFu+nq'܉%xjH-U?pS. 15x2rqz(=x { b)ϰ6#UI0ٳ^!]26F? w&Ʉ~﹠K&@r7'J?$ 7-ݳu, oPvxb2uvW"rK{m,<Sc|4LoOep Ŷgo/x2,0+~;'TUGսGVGIdóڃOffoUoRs! %#V5ƇQu)i:}Oqw>MKn }#q\%t+wK"<떒3J JvIDI38o[[:͓:ƌx ]Hَɤ4TOdž3p%ML#﹗+AHJ3y܀T#>}|Зcs6k{aw0%= I?Xw% @ YCn ?Y}[ 0nDVVaqvOk\(Pr+p{UPW, H "21\p[aA** : wHI<(+yVW6(>+"cТ[Nj0\JoX$eQ1ET7R- 29>$+q>~Ȟ62gZNIԑX`3~8ٍ8Xp¨(੏gUH.} #/ϻI"<,B^v=,XdL9͞v0c.W/Mɽ&aRI"bXL5 Q/ uN7,Gٲoo0`iatC3ӡM1sY_k|ڛfɛ"6K*BcpVǫ'!J|(/R^޹<2]]*_Jfn}WDUb ˁK_A5F  4{e=1PhP8RΆ)Zj^yknȊs:hRđZf}cA*G@,惇,_%/W RΟ';'3ȑ1$,*%hd y/ZpH`_=d ,%w:P~ p-`?b*ړ]lo Bq(~6phV")ȫɽ.} 0FcPKj7+ RRu/_Hq=cz@_*֢NR&`ۀo<}? Mn!vqeLOab *^V'8i1|=/Ϝ;&=QF 1Z9%V2z;s;ܼ$rLIs*C1SWbjH(DF^L:͟h‡G?" 3o7wRB`#H;vIX \4 zyO/<3hĈU݄UA8&N{N$;ڽ qCٜlkzyvCK'ѾD7erM{WsLpID`D9Cs!Ax~E ?lb}LBX#ɞ8I.Sm@pZ-$!XBxd<8fAeoΝ]iaNc14 g}3~Ʃ3C%7Z. h5X'0Rp ye PRS$s ^` )rVNLJA!0HŠͱ4r5Xp'JF-1((D  $`؉I «#KG|Z_J6Y|ISL'"E<GdXOI9sխb8 p[P2Q&!ӪEg'>  %ֿK:$ivG6|ѼEPk9&Ǧ%0*WɯR2zebqʤE8u9;pp$m[B :\! ]5kD"0u"D0qosBLva;:(~9&;6wrVq->Ֆ!iGF.Ifl#CCgYr(>X RNH?%5eZLlɪlvp4.^([W"Nndޛ"DV̀ܨSPPq#,gQ8 WaF@їkmJ#Pײs|\TqܗH|S)yTA$ʁ _CC@*RZI*f ͕6ݬPLw=ИX339d ko"SCȶj2OZeBVZpjg\~ru6r>0[!w(+\Ӯ"Ň;IcAX%mD"ep Qߴ"̏L34#}>.؟^Vz\lXLi;HPȧ}cHn3gޭti U RF⧦uϧ #J֯sb/h!`öG}6u^@Hen :!v-u~$ä+:nXf1ױBߢЊZ[A\l1ud>Co +$!+E`Bh,| G65F)^ۋ |Z%3C9hxG;v SU?jH)Y1|WnNefcvш'\1_;X[( +.ػlVi枯hς+pP3[?| CX-BѭA!ELvQśv*.t'4zfZQ/9qopKIm8n9 '7SFnJ+nb~t^ 3ۡdK:c|`3դyD(^bvd)mdX-[3*8N Mљ{U^s,?Uꪇ BcÕ?æ *@R̙ ècᄲ?`\̬,0;6ňgLGeR#,lM:kqfMYVOWZH̡Y16ΐ a)yUO^2x?si>dDĬ8g>oMXrq 2fa2kp~YF{"0,ن_ )O-x_- uIxc2lRO#dשS1 A D1 :`i*̎a, 8F[WMo܍{F8ٓTl} P.ݧy)ыHJXQpl[ V~FXPY_} SU?,oǺ)fR\w0n4A?+j Z p*E4Ю >&2"aUZ^7 _>rfD~Qάqbk*jAE9Gwzm$U|* :$bOVr3/2 KT۽ܹ L$UG۱ sY,x2Gd<XJ*dI[XtU!D-&|*%ʦ.ZZݜGN#HjАL|ОCd6-UNfC$+x#z7Cs^a#g6pQ 0)A8 3l}[ؤ;@4 ! bfCAvAOx&EO.lmQ b!\\'LJk>^Zy`DdMEItRAB5D!\'ˆzA*4~М1kfwAH TXx l3xB&4QanQyHMqw0eO*tҦM+ Uh>eп/d-E}`>!~RN5E"mk@bo2}hE̋LhxY؂4KązbN߹@aIv ϲq!UҵAݖtxߤv[`ֿTL#|KtQ#TY98&ucءft}oA2^&?e0i ~ݠi'KKd DhJQ^/n)tzI1|HpԔd)Op VS:3@=oQ 8[\ `lhٔ޺ysZy+YWY[8ۀ@><amIrj͜5pW*.)pH*$%Ȧ|RLe[K;f/h KgJ /8gS۫ܣ~hpԙJ$?y O,58_mka0h:9>~u;[Sijx=蟣(Y$cg4z"@.6kC6"TBNN"DJBV`/NrL!S ǜ!/Xbѝ9C:i^@{ol1T{!O)-OzW/E# q;|+p՟H\%&BgBRLBeJr]</ov+yb}4'^($ Qȶz$nyׇ]Xi/rzp1A1_է ]X^*+@:X'~|5L)+ aQ $ ̛ߏV4$dz'&MPؠ&>ŁmtzCJ"VVa^A'/hMAF%d\`hpO]BYz{x S kS ߗǴƴ+iTm3X!59 5EɨTOߺ`y<_0Gw zSY #}R j5G=TR'Ev -'KOaq %Yo-_@+pz"@f.no-q Ep<%4r2.f"p,8N~ߊ3Bژ{r6kԤ뤩Z#rG[Mн+Wɲ|/PYMoDwlyeQ!x 55=<x }C~,$¿3EZlb,α)E,TT>UX8q](4/ad/ B {|u >߭m)ЂsAzõ 9!aP~^ nLUcsQ_،jKBA,zh* Zv⨇"//5%R :Z]JaD=#o s6f_mBD}v[|t'E9 7K~e9=z_@t!61R\>t`Aֿׯ$!ܼgH?k:߆ _.dnFhcg5\Y#5տD0iG8%R'W~nғVbQ̭!uw\eH~͉Ʌz ;UqK@M&de5o6O^$<4ƭr]‘e׺:Wк0U '{[ #91¥kA\eNL5٫Vl6bh@C) eZ.4`9#0Na_j P4]E$T}QDc218W tQmYiƝvi,BtjA=NkR$2\j5l迈.P2`x+=Gƭ H 1A/c.IᯪձM)r3 W¬Dyd`1js& )7Xq*H]a2x{F1 c\}JԋSzd] gKy6Q#7b+[&w~])엏CAwnwO~-ꯃG]<ǣT@I`񹘉["X/ t^`iLxbmaFvx6ޅFuNPF(TS QϮu<ǁC.  V*Zݫ^0K0Lo :ɚ#-,\݀ RF_IM7ěRS1K2B~spB=,W\*pdP(^^RsDcYRBmwK{NēeU`ᄌc5KLm$MLۯ0Ӎ)/;:Cm @Ȯ$QLb 8|ﮍoTu۷cQ ldpNZs!pga0M.'sRaP)wf F\yLϵݐHLj^ .(C82cUjbا^I[8;Jf xQpcSV垨(xlk +j;5ڰ<@IՉjU [^S [w>цOKӌٵl+帧y„ԯDSZLfg#Ӟ+Zܽ]C8Q$--dAӠܛ*5 8'1C:!#ےb\@HwSIHEe&)Y#%?(<czn21`V m:u(^# @"ydLUN.<._ !"oz1S2r=WG*M*v2G $(.Q**D. c'?zZ';3 ɤ8Q(^0qL"+pQ1A*`eZgܖc ~%Pe1{XXΐUH4vDY5;MiŖt@Ί^ 8&u}-'jXօ߭xȤ DÃDjH]ωoEfjm1' kU`UgPn9hʐ#mipvڧBRiٵ`$CX m$"Eт'ȐmzfSP"Y WC}}۔^vQA_w-.]L_}vS[QDYr]y~bNm7,7?@ b^&~>B-*`mrA'岮} ZɲSqqy0+BڅĢ#'"_v(y`uctLܸ,<%%۩E/&\ ? !n RntR[a { ; =6xP3Cp3M -{EeT,VQM@v@?&O*"=Dnc;peGNT1hleN) <ɨ"[3YlEVƑd)\2XM!z qf}0bBd^v'( m)z'Hr4̢\Wt3W(|ZnĶ Ǎ62,I;K}KtǍKΝ6Y.| sXp$zA:aNg`|`*b >CU %(6iMr3?w]iPtQgIo1A(a*{䨍 b}Pb;[4[0ǧnRH/s6NuQz4Dv5;^vubȲƬ= C,siW-yJN\'82E>dEħtZŘH=?P]cPݾ1~A*vWobZ5pw&s7J"iT\`~DjI \!4[-VKXɶe+KT>)Zx鋯ŷ-wV;7 3řAk~<<6fc9+p~ejUR2'FA]Cp~~=Oz ^x\JyK@@Sx)-v ֌_X-YCVmƊ6myZ^qttȡ)Al3>u`KVp}Mr(ɜxM2ty,=VAhsz7(F}0J OW03XMbA03R@l^D ο"gHEU<J>IFc| "J4P6>i BѦ:.}ڹQsc"Ru|\rbEJ"]C"(Lh%q8PLPF{R?fmֻkzUJJ#f1M(0GKQv`dW, v9D1=6;|yIc2XǕKox`s`.ܠDq~:N B(0*>qŚirë^ bs΍{h|u9 9QƍPR2UՒH34a(܄{_x T::])|.cH!1'E4A# YsSd qSEH6ڎ-L)h,Ĝd>!uvO\4d3b9G|&LF C /VӁǓn<%:$[@xEp&ѻ:\Y2d3yHƑUr[0\r DRS qYAp dzE ]imIS7c:qE_:e ]?T=lkV KaWI`UIV{We5b)/5S]fj*h$˾d bB+־nD9[ pG4T&|4dfG b}s(w#xa1ݟpgoxFtV>3p?>Z 쩒[( @z 'mՊ`qbp   Z)2Uy$Er_O:c*TFʁsZ((INeI5[錅XiW\>`2 " =u'ɇG@jBϾ#1tgz!E!]0뎐Es_Z Tlj5IgcH/v"7!l^ȾٶG0AEie: G]nt&(3wdY78i W:\"Fkۢ7o-_4觱gr[uI(4+Ζv䀽A$9ٳن:զFL{y $RI y NvDQSU\u]vnzy PNY ZK F:K݆S368W-ߗ GlU d3n V̀_ȅu ZH䥼YiZAM\&H SGGiIT bw) Dc& < 7YL4X_7 ,^7,0zH2N*{] e׃fnX>7 OX )>TsO"v D`=W8̄ˤ[ǢQO܈΍BeY1ҬEk\1ֲ-/m ?w 1BHb*t(6JXxYW_FdvYyA/%NU[.02@Z像48Y$/vm `ә6WJtm1Z :[-PXtGepouwVJOyOm夷[8+f,$&nFN i$KNSa3tXȌ%!đIpa-[Z0qicJP$[iGsn;ڶC1z=N8am'['N<@QɅ`^ea }Q] wTr >姑js`9~&L[.9eYLKm]° 8Nf\Eq~ObN%`5dP7fgK%g'$g 7黒%m3V@Q 1^#$AhGj:՗W~t)i!C$cYA0hD}'eF- M NsY! ɬٞ LZ]ds |n~~ 1BH0ŚۧƷtx@Q >u3m3zvN`ɥjC*iN\7QtBC\h0x+=1,SK 氒r:X,7d?6LKLP)ҢlXe,UFm}F~'sDO1FmaAYĊPz@Gh׾9}\0عęw7~euzbqi_n`dl͇ش;O$z8V6$^8cOIu*s:S+Nyx9;zB&F%։ Ɏ 7o|@8ۚhbF_ & gkF| 6,^QVWUeOuo|ftFl}X?fbxuQ?726e`>j^EͮNC+fڭ`SN~0>RYgr UiD@fsf3*ylzTh= ?2%5v43ꛠ^6oCG"FcIM3Y֐=XnINؖ?y œ>XwS//~%v"|ӜvaʇjJ¡22GߘZWUy Lb3 {Əsض ~"Jְn++`ieS@{cttE"W*!Y\'nN6_ͯѪ=T. "F{55:*C\9Y|+S4Yu,Om ɻ 5oW sdjOhx|LO]dhKWT--UȉsF*jEY 8~IH[ANJbXVٛF2B#w``AN~hq7lѽƭ(4 HR ҷWXf2xab-աg*XIC?@g*2{b_2o|L k/Jdm&3&!#τB"׌|<:$S/󮷔baM_ ANr\̴e,| لg.C2ʈpԌ]R˖/3|.?|P޹bֻzU%{ISZء#acjoΠYD8.}ڛ_uWuM K=|)x'iR >xC˩? ?\ Ŭ z /7pq obP*Ú#9f:7GῨTç&'gj3jY o/%W3!N2(iݪ\#.]85[d!ʶ7+2*|Fn9 ]+R={P-`r ;FA!-d$⪧s `GVU%c٨yc5\{Նe;lo4p. #22ܦ_Pg;["ؔ2.e\qiS@S!Ko+AuPHoRШT˽1q7z=D`:VK"[}0p;xDֿbyyqݚlso@SIT^:Op6_ϻ%\#D#Xq`s;d.DF~nuNU+Z!œ~yLiu}2wi*o%yӹrE7+rOm[gCd+鍺?ae%FZ\ߕ7ˣ2vM[} xQ،m=U]pCW z$6Db0-`IuMP]P p_Q?C!IP·'n=ɟhk=r/⥖αa9<߀Iʠ+I 흸Y*_(fvVDQ'D˙Vν^0nmx 8̟yb-)*zRT8N235X }^I0/+6`nINz6ˊyp9EG˴a}2F~J;\F-U0+/ݘbV? 9_ uԾ H4NCn_3nݪŎwz ¸ t8/OW2qA,Udh~l*.IuO Ƹ<8~Չh}QGiwi&E8}Mǁ -1Ӆ6ٕm?~3f.W pw @QGJ!P$U"`:׌r,yhj%Hէzwz/K #z?vMާBI؅e*TQ%{8"&ޛ EW{?zdx*T_ ? /3>?~ğAYm=5ݚוk7Ǫ& d;OY%wbJ֧sxl]Зj$NؖX1%~(@y>*KcY>}x r{Ǚ Kl^ӔˋM}$X:M.MK)WG[oAs($,ȑY6,$XMLt/W,&28̗,7M6x7$uRYeu㓶TLώ-2E93q8 56$WpSw!;Mj]y*$܅؀ 6@`lŠ8R0D95Qև,ybS'T CS5K)""(<G<)Ԕqae373uW4s 4,,KBm.-=%lV. m1ÅlZuB:)`q˻_ߠ<NDWŬc?m(,:-b%,ضbguda  89<+9 :8 Ȼr=H@8pңtG$.?s:lL_܇^ bZ`ӏ2;{AD ${ٸ6tO)e`"ŧoKf=R\ydr,@)v=^-35_?fjUԂZOa]Fz. xe,"Z?Nj*[.lkz#U$r?)a(|rNV^NVCHupwzֵRȞkVC[5E ٩G/!7B>EВFy0JkjVUdOEA .r}ƱaFp{scGta~Y=Zy(Z!Ӫo5ȕĄ:86ORE`wWHBj}/q $G>n(h=͸{E!J:_F8IۡC&RNH!0Wa5ϐ=hjYZWǎЄGS`q cIk)9IUq_lYO !&ڈf-a.0\6HQ$ٽQ$$:pm}kKK)mlӌü:uB *C7==*^R=ܟŎN9cڣ^C9DL;KD\خ$v1Р,v;~K)}6PO ԰E1:he?޽}_̃7Ew"]$.'zDy?f)판<`Q^U}w5j NT)b&nVNF{rسCP͸ d2xނS<{gN(J=k$8w䙜L%U؃[@ d|h!AM;?iР]p4P\OTf A G<X7-G8fCϼٽ@#c:*idC8?Z$ 6JloZ6}.9hڈ.ܠP&ekJXL \pxFs H$xls v > l$^Z! Pf + QViB0.h0_G$mr;(_ѬW E@@lN lʼncxP =Nɐ|z"0M>—n<Փqk:Tx;2-#*\𗍎\ ׼KCC^x.8iH)IlgԶDW|~aZC傤xflqyP\ 3$:U QGDJ,}56tcjh.,(j*>N*iֲ؈h<m5 >G{5۩<#8iyBm$L& Acd?GMJ"zF <,&JvA*)gG:4xKYA&(?ㆪ'ar>*NJ# sǞptGgUZpC;C~e 7cEu YsQ5C*^Q %9}roq5؉^¾9bvp$-M-P:Ȯ1oݠk-FD˙_q}25/BYذ#{îq(W X}>I+vJ>D8Ԇ$ o% ܍JmK[{ \0qID̀>y2i$ղLT*c'rXUα %5RJx2vƊ?ZgM-%H׾2SwЫ]~=\b(V.֊4iupӌxk9~"]ev-|9piT)@nq/oôǣ`qаLE\LVr-4C !#(A Ftj|UrLQqd$1Q-`i\ +8=9tvnB: !xrr H*MՈ6,w\R+`~Cf ڗކKܙpuLi/=Pa RW0w(J!ߞtѐ$s'/ɹwkI 5{c6`0QnWRB@yoν:3fsf@.fI,>fqQ!?a}(/ڋWNiU[J"Mb\Sgt6ԢHфDha& ]L,?cT)w#4k>o> ˇ;c{ϸg^lsw>1jjqLD, W^[\Yi4Hl].Xt°'$1@ Z~ϵ*=\ux|li,r9R+H= bSЍ }b >ks*~s&Ua1Y$$1H'/ω_b*cv8\O:5T&I?bS9gJfT0 멽ȸxv PIzG=H\U-+͞^ t$=0,ā}jC`Bm{t׮_\sJu 1luvVIS:õ*dPwL332r8$7!ıÖn9EJ2 6-7Mu|ij\x#`W>_|C16G(D{Nff59 D4fڏFo5b{% - Gգ:k٬*nO߿)FZ#8+2_ ݧ uo$Eq{.3u9`V9?(''jMj.V ŏ*Tm]I/7iPh8k_b2 re7/}:1 1zHb6~'3ֲUܬN쌜K!,~j Xϻbpćs I$w,Dt~L (D@[ˍbP%Z 2EnX_ b*@~iRiйO$ FAC&fۣ1y,)bZKnk*}MTvz$P knљXI]t >a^>E);{0I\}wv VkߢPT #]NO؋S=8+)PEƦ -(<+s g=>Yx?>crwT1}gPڢvC Cb>y=Rs)uAo@,s" E=ޮtB8 нk24vP b݉dҔawo 威^l,8J!ngh:u bKI<s܊oJ/y_@%NJ;mϏԠds + YZ0y1V5D^ʭ EI r+eX|Lѝ#3I{06w o|=hOP2&{0 м?v 3}5WZeug,Բ$DWHJy6Yͺ;ZIy4's%FhQK+R`4%d;T{024cS6bH^l0nVߤӱuLwWODr(ǢOzc8;cw*HK ky, 1V!z".@\+  c hmΛb&EӦT`;VeCҺ[Hsi|/\+gQ @\Dd>t-vGV 4 i\huACk/2aa7&7Vz{=0aݏ)sp\:2#@~(Ѳ۝k f؟ &$ $;}n%8ڥ :8zr<Q@@N̳n#h)#s47+ g.HFI֯D+}6'hvZ? }FiĠ}uBLEͬ+q5NLVʄsWض`w'y#`urbcmש L@>h 7^z׶Dp#i^}@P:61Lj#H@]Su8 GJ[[HMfjwg❠[-/)8 Ey~~o͙YgВW-r>&8j-a/2m-_Ct-%(\Tk,t#ʰ:)Ap*eL* {P B /ybAaS-JdӋɴ+isQ[Up~i+zB8( 4i?'5JgDb`V-M8n+IkUqVz#fMyPL[G5q2"d0k` O,sz4BH.{ɪ8ޜ a) gȻHk n7h.vB/io9b({+jt]b<|22_>p<Ԧ1.KUڱX6G3duo!f7O 0n:ݲB? Igً 6br7+r'? /<6TFXJ.!O{O?nR<Qg^=F5MNlfabyw sfyɴjr0N9' P"nH%GAB{^.OoIr?9j.p]w3q~'81޴W?5].Ȅ_y&pc$-%b0%TKRq|?V*: q'I#'!l:謶,OS=S #}?'QՃldډtRV9ʃca[di|6:#v +MV233kPk{/59*g=|TkzL7U yyVYꡍIuSTLMb3Hmk!Ux҇#_`׹gpRnKElAfI:tĕzzЛ1&ᘥZ=o86xaҖ{l^I_>hrXF&v~l?ԜReǤi -0wO=Az?hqh`6<ɀ"f& )vߪ cwN@.5Qa{W [M؈`z:ef@]-ܲ/Œ/$%{G=՚S0%ΟHS#8\=9F#uff${ȵjMXϒ-7ޘΖ(ܼFЪ[N!gz'\OhnH~eOV{pXd! e  vpߐ5Baa_l݈8S3W8M*b M1k?1O~>) YRtv0;<k  a4.PW'ь\)جchcUҫ|izNW1}!nƜ2uzQ|Yd_Cė;yT[,4ha~ oTBIbFd+U9@xrZXriBZAPخӹꇡau,/d|ʢX& [)~ZҝP#E2%̘'c ?\jhn/"O>(/q姱9?脣8_l::Ȇr$bGGؾM6C?3F])q}IؗvNH@v &/ɑf!齠I/v/vТAکidGSlLTlf"Vh"M85.NJi0ѳ9{VQ.ْ<8f\gm֑@ r hL 8 Ǚf^cx( ZfYLp9 f㝓e;Zf]_g,å6t}on p"rx&m]c]A#^4ӥƮ@?0UVމ9T.ސ?3V/֎w%xkMcF.jqrlx!P%/Ss!I`>U"LJU/p$Q'`69o)q6skrT7yJ,G߲g+ɡgYHUwU3O\/gl>o (F-,qb:Ȅ㖌zQUEQ^FlGY&*#8-lunLCrnNgAhǠbQR|x]!ť zn")W+I:lTQtx|;=ryiEî _*/D2< k&w߸5;k,&%5\z0;;uXi/=n437"e:f*Q^WYt\ گԩ,Qʍ-z8^v֡4f_!B +ɡDubLoI_V n/,`Ale*R hX-=ÅIIǒA5$|-R5G Zɩ]#17|oՂ?:Sly[[cfؤbI:ҡ )~[2chkZ[u~d/$۩긪 R]T\Օw *EW\{X*A8f <ʅ ѤBJ 6f9(}%WSr[/T4rfB\d+vw9fxAA1e[}{ Ar@! U#7ϖ2M˷{qTċ((X1+bͦC1;:]j8CyH|JݚSnB):9]Q3,?yP%$G|l˪ bTwwZ++Dx= 'pBku`uXF!CtgFc=57Jڡ:3dχU \;IB g,i~ C 4le^{eUنaH/bU(6<%Av+;j(DPuxwEaRH/g>QiifD#c+c+'ʏO@M{됾~l$,"iʕOKT ƛsg AofA{fɮeS(Ѫ>Tp/7eԙ9!v(&T\ ´ d[_ FRO"Isk*!#lYz1ϟKyT]]5hӰ XM) Cv@wzHn \IT,n!݈CRDҷrEUߦ 3??YD̾_I:wf피l"KgG [!{15R' 55L w6SB5=dG2"3bɖLx>MѵegQ|q;*}`Ty^7t? Wx3Cj5* ;kնXƚh>)ֹfK; zOF2(MԗԼ8&ũ7\W$aAKl9V/8 `R^#q؝ 8m'**L7rET4QHX'@sS sx:UKuK#{6#u 7sjFd0H[wWcp { ҩhA!a0Lo}-ɴ< QqVcVPZ06.+#@@ޥc!WNvac|f,.6ϡ&Lۿ^H"( ֚4:c]ҏDA' 4j=}^L[@f>z[K3f~NW{K9=>%ђ2}rhB! U9$Hn[m-=\Hu e3v܊ެV)/Vk/fͽŎ8!1̀&ҖRĤ<:y~릤[/=Z:`kG'u mڪL*14G؈3@q><$:hh:){]֔\ 윏 \9rwɆnW4Y Gvr^|;$i-[㦠S8rmcթᾎIf度Q(<: ^ja -A2Rw3]A1AX7E?mG`PjӷuЋ1 8EO`?#ؠu"v>qd<z5C P*"im~śϪzN󜘎uƇ>AGd(PRؘs27¸}k~7νz=$t'IfVӯ(hj3'Hi zU;US p&8SWv$!ʚ|@`h Z.T~hiTYLE68^(;u}^NGU=RY;WM d'SPDOG{@x(V53i B&F{W?M%'X1ͮ!8o>hX_~`Y r;Qn-&VC}ZD; Jb|Tők 3oҙwu49pޕE6۴1q)evPϤ%Yoo?S+ hMӓ77hsIҿD79{!\0MOyz!Q 8vN1b,hXw/Bw%YM9P- &»owS傱lT(Hc e/*cȝ8U2'ͮw#" y>_hǒru>^_@F7;{{HIXOن km&~P(ē"t8 (?,R% HO tW*yޗϔh=|T8F.] 0:L2R-`K&-SLEγtRtSˁt\b.K̢, `SM|lڸ!ô <9^,p7pТKiՠ  5,9|3$gr .PzB#Ny0 >U?92ol ,Z,[# /yIu1Y^ʺ}yc]q@vw C ,oʑ;/sC!`uOjzOHvCi[*jBIwl75jr/wHi7?yS 6?CNh6γ:Fv'`13*(20و7 l"i[Jw(У~h:G~2SkYY0'Dݗǚs aqJ~ ʠy۩Jfeb:u1.k\_.}eZo]].Uxn'bJηmm CwҔ};'2.ېjd,Zuli`.?*=ږX;Sb.'Ĭ@=#%Tg?SDfԣdl++(RŻP =l24G$|li~ ̏~@F_NʺZQ]!NgN|¨ol~>0S̊!@Z?iH"ntɣ$o7 0 h TjȪk:][aghɉgdVC8ΑÃ6m ^ 819>HpX:*uO4[qА0|Dc/o\$ :z>S G"J+"Wa.vy] h]<ug*EpM̪ `ذ FumO^îͅ=cH>myS>R]8 D|%YKoa;6FeR'cP:v,x;#_ar m(䗇e]DHOk "&k2HV$+ź2m ]ek6Kz9nH =r+2qȪR`G iQMTѿe8xlz^VN$%\ˤ޾%Ax9)u#-R74+ͼM)n4$t܌ΞvV,rq a&l!JV $~u J)d nHK2 qȱS} UE+^Ͷ,;%Fe[c@} ke*Fe&Ož KBd~OQyiۉ"t1,7/ r#">0L{|Q^{3Bo,˲}b)RT§l8vh-eu{fD?R>f"z'#dዢBhC̏AB|JR& Jt{'/+]`jHu(2oe;[F +x֌某@PCgj*^ *쀤 r&-AbDXl n0џL) ZA&U II4HFTIKɎeGfcԏ͖0hꑌ/,GPl[*Բ Ǐѕ 94hV/\7ã(ͨ^># IP~'ɟ2wtvWK";l\gׂ֏\5%l2y&_!+UyJ]KJRx~PD!mK@-9s& y6dMOpo0oixujPoHOָxa":WzU㖫7ރLWVf쒉d ;.Z/qP!%f z^%{kFewK,6HvvҨ"΢!-EBs ޺ NQAGÇ]4҃H@':);gݘTs_ -DE1njYPWbr"p#hk"Nd"p${A0J5\$yԚ`rV!E}yuoNɡ1$ Ti {wTEoZL 3QH:+e:h}SqЩs'xkY6DhkVJ UAXq̕E6K:!9wwŸ=d1U{lgmoiGؤq,1Q5>31[7cV^\BPl[>^_*>ERr bͬI Bko( MޯW{nb0qQyƎUc` )H4*Lru O+C+; q3*RSpmR}#snG_IQz ʇIaSqs4MiIucj?ыVtS]Fn4wQh mmmbs6i$/u$ĸ@i) yC/3N+mgؾ"*-RKsib]jtB`|C@gF_j2!`^`T uhXYX-4ϸF3%/-M=Jh2:HYP N6W*Mr9dѤNłf_ٵLm(Q`#ӫ9Y|-ufE ad'KCH@N| qOM~k.,E48 5$ژEx=͞2h NilZ/Atʇڔ@1r`2|=~'O[iU#Qq!&J+G%v IWҘAƒ~`]3ocy DF2cJ 9/I7 qܘDS,PknU\dFSAP r#e+p>gc8r;Ez CuhEH O6xl,Ы®P*eYR|CYK YTa r[_<<&9sfHsZ %[ 5S¹ZeOJv?[|72|Y'} LR29=C5d#\- ~>єV*cuuC}!rإ 5Ώp@bJVx6P4]V}ۭ=4/mF ?s#o Ob ē; :f`bG+p7Gcw${]픑m:A?2+R,ztu}h=z(+ȜNǶ׉[B7 GVc&{Ol~Il1M/=O'וz S<1267p_Iݼ@yoEzBk6.s߼67ֶ)XP9Ze$d%4pU~-z :~kv$| @fbkckHTwT0"4yQ6UbQ] ,۴ 4(FVStǑޭW.lU*dQq+UUC׹XR33)XW 8^'AdkDr2BH`g -EcrJHm%^y7A3 u/~T1KrZ5&ّyDq+d1yA>ÇPمKH)XWYN$ ]Jp7bgGe E/×eIH8(AO zіIQJġ+9\~7*9N$hN%]іJ]]F";>4*1> čqWOuđ3tFa/M9" \aW'+'~lEKPy⬂bTt携,7' @jI: ̨NJ6GYrtSu`{v KB`Q9Q&)w 1B[`Qv%֮I?>[G1k*s-_yھU+5-YJ%6WZ7l-Yqt ^ke1kŧ)C Sye vpO`j@]#~( G䫖k¾Äpf:X@/=N#tfڃ ڶ)5N46ǯS+\ +MNԓ9*Vܓ&ťz>攘P%,]:'סG?X,ӜMkN1-fYˎ[j\AZ.ăc> Yױx~E<|{c5-J@SQ}|z(L\)]d 2X}-*T_;B(Nz:ޮ%J&z| WIĕt䑾Ƕ-+Ml7SW ;e+ ^W8Y}->CrPG9ҥh ȱ`6h+~~FoE- bg9~bS&P/U@_,kjW5}k?(S7jdw%Xo{$ rBLڟ U~q&ÓZ~S83r \oBBZ9> ] TGc) g8*Y=4>HJ{DT`hSPwλy#BJY)]a~Ñ7? ˵yGNc=K0k<}FeUCoŭ!!?ɱom3]RK,֪O4Lu&Ho`m3&9PaOH-TA1, *M_3 )ae`IOwA~JU#rEP^Q "熰RA{ d>Sځh}Ol._¥15yvd E%V% f\6>jpAjo\:ӟSX\hG^d=j_߄.S! -s dzl('M@Z],%u%%Ї\6̹X!ޡ'+ ڵ-/_xp1[Ghk @ 8$_]}m#8- a&[or+ QRTmLd#LAOZ."gr7ҡk{{N҅F\M~Ώ㫀cUR`IB6$yvUo_x_t)ւ))Dzc\ָ`_0Iެ.w wm9< FŏE0zu;R`8Hl yR5t?Yb˼qj#:4×gڕ^BVU?II-pNF~C_&h#&Q]ݞҨ(<^`D쏞s |K{mt]w`,łx^k{ʇ,6WOlHPƜ^{]|װ023XVؾxt'ZHj3s4x#`Q.i;p|Ljz(5 8Bb} t\| *\+Tɬ.X>}ݼLe3o mКxubÁDK,|֡%bWEsDIoghbyQq(%!`T_&}lkVo<NR;:Yzm%5 <LKO18fknȲejc `#[<0BNoր4qJ&~7/ ɒC%n3͈"BКеg&K~{g!\h)9h*Gp o2EόYQ#v`Yi@JԽ]I>{QVb-itw%>`F0Y U]~?#J0B:Ons''%t篞*J=<4ʧ¡cc|uotv\L^O{xPQ Ad7r \FRWhr6 Of @0bd>\ǙNk/ຐzMcwzD . M=\biC.!wi_X}!ЖG*[^>FO\nyYΫbts蓻rKȴ$B&1=(!`gk.3g\Ouҳdo_-7L$ZI=ҚTo q/ ^x~*8Us ~yےQXW|"d [W9p֧D/ # \OOWR{)*i(sbTզ6'C/OΣU ԓ2}O\f v!ki !h}BךO`X0ؗjaFrګX )#mq#Zys7?3=̷3*R&_ ToE> yp5-!(YՎ"ֈB6BPxs2цr`Ey /jv_-͈ga`_?J|2u} ChR@ii7v>w֭gYE( *| ܹp*؀p*s?VE;"ĕt^N7A+_K.y͗B (&D*X>a\''ȈgKr,?)Bo1/\uf*dya%'xM=u.A}Mv3Yg`pFȈF!Y`<܅r": ޷'c"Jd&XWSf w(2҄ bb/rUx&Iv3- >w0h"߄ y< ^nA G.* ܙCM^\wӜLH?IIH^~7sV3tw3xwޯ$C;JmuԁZ] `!Z$<53HYA0M8Ƨ@2>(/'_"&WAippY?+̌*^:noʹ(r6*1TL'5:׆tDvKJA1O.c%WM2iŲ>{*|ڤEu,:,~:=F^mgYJYGA5LYyoЖ|1߅!~lqY*%u!4h|":;;v>SׯnacT ר]_faNA܌jl) 6^5jY鄻̈́ԅ@|]$M2v0{mo߅|r)NJ!-V>X%B]E9!7\Ƒ/*G3:RyV|ߏz0a)--.CUi+IͿ.wMձXrym`x LjÞzuD@EU-g"&@ rh=dA[; |zPW]>|@9COא0{N`ځ{ /G#55!9e;h_,@vJx8m:f#"u 6i%dks$[d۵,v"C1_5KbsYwN[DFdj( s93bœo$arOѰhO#fdSM TTBT1Ir\Pw+Y"1}U@uluDD^[-ǗġP{ m+'$"XN )(l`S6TI;4,{^C;8ɾy1Tz5XvDhh! s˜`X0G̢?maF_B$:q qAx9Rx%%I}p}.dIh'MAVjٛzmD j˫*qͪ'7UqO V!·fl/IiTgنߖGhUT<Ko>$!LH6Zmb]rfսS3OUJ5T G麕<+myo]+HM`<.k!+iͥJZ!WȜ/Ӵ?)5\2Ywze>6 cQV8/[ͱxL!\\5q+]a)~oZN):I^cI" Za63H7=73q I*xT$y<˘#8~ʐB .f +=kA%!]}\LVt.i';9EZŦ\x1P$S5 s>g%Yh+4#/ jlν]a@v#M IlOP8Οt]!Gyh8ZU6!(kv[GꦩL Y\GIc؈^+ׁ DJd{ɛYy9Oxm. Ӌ<2(VUzҐE%͚£K$Z4T^M[nJߣ0Mmi3US}b/B[PY!PdY9}eF.=(hYįh}l E9et8_l뒪Nj^PAZnFh6 XkW=m`\ɔӳU ,Vރ2X p䨑ukǃ:tƵ09)K6!r a" sO\f`q3\dA[`x:essWaѻm;).;Ɩ|mA$ {/=ɳftT$*u#6zΒKZ?hT9OC614!k7l"9Tl}D?]NN!jTԽeݲ^=تՖ+$f*t#'Z?Y#k%> &vYo A(dv*/R'&D 欪;0A[߀E:]T~wuȶ)I.c 5t 9HW=! ; ̍" J" ~4Y';dj/AR%T`FDEHu:߆as&06Bd@ڇNNK5E[S Ua]U)7-vG%)HR%p:${8QD.~ldlrgy\ʖ:ze2iL/䐲)+U*r=:07|_mÒERGγ눊wSNh9s=iU'S質6*[4<"osyEC ֘]$Y1,#<%&E}lQic\!RHRY#>Z_wgL|(dйMDB: Ho[Mx X[bfT1 T6Ry1̏l0֣ ס{Q``9Nz86_wpsInM6=ݰRIF D0R1~ !iKgw8 |3_;(j-.yZ(n˦>Po3 T=+᪨s2\a!)c7UmzQR*y&KQ;w 8M[0tb> \-0!xT T28f+uE({՜{=`"iTf|7rY2'UN06$U;mX/G*(sVkgjYp5rޞ { n. WJQ)Y'Hl_'.R@5S!eCdYV2ewa;[6RGQ*k5Ya P$s/bo7$E~aZ*We'`}= `_Ӿ_ ,sG~;ӅI֝BGaz*QK&"| EGL` ^U̢g|I#P^R?j=Y] M@CUnGPW6)ZW]Xʐ4 +S{Fo^nM79T7,g'kM40Y^d1SQa4)E HS2ːFZs6ӁO([_^}T=Ŏ;URӪUmjjoī;R[\LņZM٧Woz,Pvlys!ۭna;X`2Ӈ6b:e!)1P/!OH᷊o*IJ> q0b~3\P*껊3d!Q<.5@{>tGߴIJDb8S{k$$DZiT78;8 5N"wEHBWXw*_[ SXBkX-D{2+ZP6k!0`O R?XbD 7 Ȭ/#DhS.?[8XÂHwᤠ^ةMS+hk;,nl-^Rägk"s)VZz)JHJ @7 e N1߲<]wv ڙ+=|.pH%DaWds oM/Vc . BM}}a!̢Ôff(Z `o.V C{RVn/fW-5C`i3 !'+::=&`gD:Yj?F4Fk.b!%kkb'2ejdM 6[Q} zEE< c6f8SQbP[qpSUr=vd%f/F')pT(W,׉WXtEZJ I"yAik(R M`=AU'ys[δ=[χ;%mpS`t? ;VJvHmf\.ި@/q>I=h;#ˌ 9ԁS0įKho>J32[$\OxE%VόsB n{ɀ@r|%d?/s+eLfkPT{? 'UU"ĥ[C?h}} EBvD(B5-3Q:[!4'V5Vc-758ܰ]9Y-Fxg[rTsʉ-Ҝ^Խg(Ԝ;Q; UCķNQۨ? 'l!U 'nz;熣Xb^:3Z H妵j)MDL֤_mǫt'+fԥ[{%Un3Â.6_<;,( ~:l: B/kt5uY? *u"|Ρd қ* Ώ#.2a"l_bjg%-P{;S##>[tTy6p) #OW\. yM,HS'WA -S63 4ސT$h&euz:זʖ8&#aW4>D HcԜYHD;{1Icb'zջokg0wcu'U >Tur0ܰ\hŲq5zЯWDb!ejnJ.Z1y4lLV&4g'$kc ҿqDZXC&z14" i; Xc=Չb9sE8*a(VZʹ20e=Ma?,DXyq~U1т,`6/mqJrfz+e e#Kc/*iEcx :E5Hs^ =nU7kS֎<4xD5,gtitsx6q^nYd2)ˣ~\n1#({;Iޮ o@Nn鍼f "4=!ξ\g{3}*$&,8k')/3{&Rv7)(z!%u/1p_0#O=²z'K|"7Dk1 R>&S 􌒖N|umSُ{?h]@Ltm7m#5`N.9QP *#V=u6Z[W",?(c]Ąw^@"LXQS"kߓ>tBui(to$ Ut"y..ǔ؉kGů%h$?N^=Nءx4*SĨ}ZhEI)V\цzw+q́V9 ޚWRo`},)y5d =T g 0 Epnn3U@¨.׊\:27# }xzb-j/c`"ƈCBcf QQ%NU]UKk+t`ev9 a2O 7h9^nxDA[6ևhWs2@TDU46?,xx-GE:[0;&4DTnЊj:ع-%J-mʶ,ث=c46`֌Hc9E27.i @zIrb{kBJ lKCC:'^+q@䰢OKȶ{i㒄Y;E)xG+)~3b^7@ze kuUw jQ;$3eUtdŷvfueӇ(AxRyg"@hP 47uNN{:S^J*|eK6/-U= Ewr:P_:w묔kr<RtJrdVܚA4?YK#NFO|o _j1V(N>Mp0o6TOfKqH@''a ռ9p$W!G2:cٛ۳KćRxf|.O2FP~;/ީ(eכc83h>egQ#qmbxPY@+^ AgvacGE ^~WO 2jWeF5Y_qUVF9_R^ae܈0MiWKu$I׺Q/16 3SoD]5`W}],k ~(PΜ,E,>=v?eSqz1)cB8+"d]{.~ q8لRX1q~ ㏰A4gkᢂ,VN5p7DT[DA)bpl2E0=Nki b>:mdRA'sj:Mx$fUy:ZRIj6`/ze^O-L 4qAö?Ho9|M#(4-Wf!a Y&ޥ^j\҆{2/Z5Cd-AZ5h_\fy|G32q 9O/v+74 *P;Y(.!)/&mH/l3,漿x:& DO'aK B#t@;e[g2I-+&WO[)S[Q^{iWj;ŹW%!x 5),Qn}6w;% \.܏h? h?9geμ$@ u+'St>5].i%aS$f`Nf5ـ1gDIdDԄ]fҾO/^ |+0ٰ/p$xe|͟_A2 1Db ˌM.lbt=ZE%9NC@z  ފ޾ねW w3KQ󹃿%Z' I ΩծHZK':+v% gY$@4{E}^t:㇥SA5#_p4'nH"#P_2LDnf2[| .v3.]!]&q}viJ14b|(^Eμ\bcf!!t o?'+ GcKN=Y8 ֫TF 49 8E]-dޜIyಃ9;o(7TPs֩xX0VC7YNXhx82KT0mUˉQy)-:خ:L"ī|%C1ۺgn`Pۘzb  @Q+r(v,6t+Ok#>H;͛A N 3fxp@3~r/(Jrq7r]zOۄ!Zo} 3<Q댭s)ر?iBkAv`sc1NIhZ$nG$); щaX6 >@^kP+Vk&EŔAJM _Fj?U 9QןVy.is0U56,#;Lnl4h`z&S&rLaA._)9Z>nO,r| E="k^m\zkC11Iה2yVK:3l"rt܁2²}[Ƨt0 _)r&1Z!':4 :%?D MG~$k4cYt6ȥTҰY+rz2{D* )ikOiP֘6zҳ!Oz^.0nQj~FZ#cDcm/{Eo[cf1)e6$ yJ=x mZ>@)ύ԰J/5Ŷ\"}6N:[)t6joаD:N~t8NB(@#J:tCQ$wBhE|K=iӏp%rFbWliY=k3B8qa騑c/(axקT SBa%RqvFH&*J+:\bS%ȟǗ]2OH"uF[mFOK~'+÷G7΍2*(!m^Cj,3' I &F|ClSZfҜ .ofm3PT0Ƀ?@bi8}tf5GN쯧jj{; ˷Se،za,s]bc֍=j &'̚I-矨2Y5[ C[ɠB+NJRLAh&CkԾ wM|̓[V*[G\44p1Nӊ(tZ $(WlR?]wy: b "(velt'I/q/+os$"p4YO6tX(o+z2`%zMr[d8gW6&2f1Dn5\rtE$W"d^ZB#۹${$сT=$pod`$mtAj!y߬cx"Y (-a~YŜjIO$<ޮ<=F[k3% ̭Om=eHy=(43y㍰2ʪfd Se!qÉ4߆мG0B tZƔVƻ˽a6J 8ȵQG:mK 9'[|b&|Q9 @ϧԏI/*F4§tVа5 VߜrJdWC0xJk.P bf|#o{ ՠIZǂO9 {3WkNઃg)B IX^٧ΐOU/w}14!,и&4˱8Rfэ2O%,Ls*W5_i@!'пs/X7b~+Uqpn<%‰hXUY}Gz%kWÜn\q&âJ&"cm@eR' OKó4MLRt/įx~Ao!S PD5:12]p$=բû%JaX #i}kVq;/eaiZY{48!AR@O0GSaen(镲3%r HLXcW`]QO->aN+%}@ $rM1D߇S܂YjnJp >Wށ%ݵ/Ud'jkljk^ c%+ ݪGK,4+_&nd]]kS{n[w)sis 3Sinf 7enWpm9~Iaz90UcYSo DmȠEy6W.KG|9JMx^wjFA c55K6Jj0'Zytǔs|G]y=2D3nΎtsY{Bv'~yKhHeZWrŢscXA)AW殇s5v;OJ"m$wK恿1lXM{tI%Qm./V$g&|ۨf7>.k7\|6-DSELvKWi,ə&c#چU_ƕUL2rR)d_պ}Aؖ'`IRkT᠌8 'Lb+PRB}9gz+c.l7+|m #im V*x1-,D(=C 6ۢwu|s|^-S&|/\ҫꛉ䇛Ǯ_b7:qƅ22p7AZB$Y!TYe" JٛWBx͎FKH]sRE*M٠+j FPf2ZX濦aCt*dsˈ29zxԬ_яzWUrmK-|;Ų'TqϝC i#.gjxڛ'G~cyGa4Tl hYl<"+!H!EpC`:Pme,aa=h8%ӵ}nq,8|p7֎1]& Om7Bjn!MK,f\7YG|s۔“v?*f Ie4]O뜉?%+2뽰0Yo7AC&ig~!E>ū$[aڵ"!2~ɪi1Qv֙KO tEr|Bj P`0Eg<3! #5!b2FJ9_ 'ӷ$Q͆OC&Isi6Ns!vj.Bpֳofm[6^r/V B<v_ 6WY!!;v;ZTkv_Xp9 z/˕.>geh R~%ݟa ueA,>i"*Ǭ/ =UOnvI1\x7ɊpJ3H]ebp?󝐌T.U@ ^-/oS6Y7m&AɿB_;YhR8lGҀ!|d+q<LOڡX|wtc$;t͝t^~,nICQP!|,ȱo0K1g2;7H{Vbe/ n kg1xUҬT8 uPPy}4&#A:Hd?d5l웞8e$P/ꪩ{$N{uf|ZWz ֥ك򦝷uR sk?`p)&~ klk\*n)}oaʽ<ZkwDR2 ި * j?upjj>ѓR[BTD&HsbU6 U}=?Ȅ; _jl *Lxvfh#'ea*$$:ٙ/D3RpPq:h]n3U [Ŏnɝ {OzMrcU_=Q6=/1zs i)Hm$QGoZ7仹ڸ}L c>"KÏh61n*y_g#<8C 2e Ǽ%Q9FN1+G(oJ>$"^ķa)HtP:&)YX/,ɇ4I+4j?&e뒮VI{H ;Z87,78椐cj3F68{cFsK^Li3˨\#7^18Pq]B>6 `Z 3e23BgAokw%I>mT`CP*˔㳈 imeMh2N%%b ndȭ3PΊZjM%9yzyB Y;ߜ!r SRiIR]R FЉ:Dd@ƨfeg,Ӕ6,NdWGk@_Lw~ ϥ1kjmvƐ]uKh]J;GGN`g+jHlKO^ `rG2WrJZW )]`p|?Kṙ{aH|&Mt u|=36q\4z##ʭP?Z ;le&Tb'44ׂ%i0 BJ,?WNQoН>M/ fPyC,>wQձs u*肢$lS[+=L"J''67zG6Ը>> *$:\.ri$XU&K,  wS":F oqb*Qe tFZ<x! Q7w ~ 2n'P\Ca"eV5R d0uDl6=.e6?O{~nSS Su8;];v-ȨŠ3t@NT. Iuf8VBST|Kt' 'Id6'E"oVpBK.%L!ظcpj@K?L?/n3 ~5ozdL$3NhfH¿YwX}".›ʈG8D7,v6fu Bp yWal%ǝ;_;D#&=}347.л-ޣ Rl^duRB CwGAVvߞ_ 6atGwKU`1Gt#cڧv#U^IKڋ"Fm6lܔ=9_?kXe 5XM[:uQ%wbL >CjqMPs ʝzaV{ 9ug/`OF29F96lpɽ!FmIпke-I~ɂHt!Mm`VCye35GR- LK4Fg6O9GOҰ`;_ =0loc<1U%|'[7eEGރ J hR'Y)=/ riy %9?!5)NJOxو8ߞquhսA͑ w&c=\33"4FtaLtlE%ON"33q_>@OVW g=_P[G[OAһpó(sǂUMw73%қ(I}}346ٌ,8$06 xp|zIj{U߆$iOnd^n_sD"@/ 3w)(X>KO,p}@j5$b&?Dtol#3OmS[ nݪֈy;Ǣ5͌Q ቧ.Yމ,!5i2iY3J68jt/AK~z$Z#Kutcn=`6巳(Hj2{-0MP*zppGdծ >eYʜw,n *U 9 J TM38-.zY(2ym+,y&ۀիǘ!,}'/\t)9z틝έ;zk>eBu5/V*1 B$ ]Lsane6K}J*0^[\ƏUbqP6ai{[77< k9% hi#ѺX*o T}PVؑI}u%rH-n6*3+^^[ZV]3#[سAl#OJ)m 'M/Z r*u% FP*lyp}4bqBU=衽|fk**8whxˆO> qwͷbl/\8 dAgOMLWo=q3(]'YHu_ fvB!ۤ&YyiӓJ\_|lYM"$(K)YRk c3KCHaޝZ-ys'xemV uXCEA)N{Qh#k䶴)L2nPvtDxCb;.}(kRM.14m 8h [?ֶ3or ڬXsk!u*VM78vRSkg4Nˋ$+aoEڭr-[ƄM]Yw 9dL9`-:xu`zWU|D|g*`)Sn@gRP=aN[fNlW`gJ0L"^8cER7 "0_m=Z-S]ZGO5KcQ}P7a/;eE[0,7:DUr[ק<۵9%"?YY9 u*f<8?AVxN9OopR 4ې@k^߳4xy_K8̋Fm׈"Uy9!̼)[hEȖۉe[̔9Ee&[6pFY-ufHN{nʆ&-.m+ 7dZaGBZ6 _t\S"P2ps3;ȅ<,}s{7Oq\N}X!{еyk'Avg#('w-론D5Eۄ1} 56^j+YL V&_L6ѽ%j" g'\191簹e$cE F?I[5"tGKs `hd qpކS2ih6N5u|% )E%pKx}UlRMvJ͋,*&)j! jb& bE84SBQ A!SuʚtQaV;#xI$ 66dyXC=Bqޱ_2ҪyL`XY X@ j__KT?zвuTV&J+/>{;cec8Jq~kdW;ѰF2A9iTںSo;r CPc"9X G>>dC\:.i`F!zm9f]ȈIW7>e"ߝm2 ra$Am %bl3cmRtCLIlBh E1/iAώބ>QTkL0Zj:a}츑 d_*^,$͒hmP/n aǟ~T) w՚':I{OaoJECjkbgV)=?]QJ)6fߺ~IWXE, 1IIꚶ) E;aX%*6TbbUʿ7N_`35q%x;XՉt(~_Gv V^NVF ~mLEbd\Տ4NX!31;ڱb\o_=&yd|dw3{69!\ڨ*|: 99Ö59z4&/aᆴmZ`3☳ùf%ctiSN8|T*ZYUo!Qᤵ~ :Q8iM۟Å.!LE^yYMR@nGcgmffڅHS(jQ\;&9e֑P3x|+n>fjm7gȇf<>?V7Qtʹ6l ƨ!ޡmozJ%R8s|;j+?*R"J(W:`"Lܒ$n F; $(8Kd6;'nPUNى'iA@· %A=QI,>"Fb 3x`eV|oLINu:ϭ[ %f؝K!G"TBoRD"bq9uW"J7۞IWt&p,--CY*,͓R md"\+4}Ɗzӊ^Ə.GJv [އQXvQ<7Xڔw! ܎|c<ڳՄ'q5ZړP(Q`ΚN`P> W˸v&2M@#wFkDEnp$8q e\1tB ,S݋9nsfW^>ߗL!~(|Hgj/P 2o_"$KbnK~ʨ~lѷ Q^忽]-&e:|ԝDs,h|溨鎞V#LӉ'c5 310qNt;~wDh86 :]Y-zb8҅:j>#Fy[33e;`vꗎ7kiNL.aLYuxE@8%O XL[J pfF7')QG]  :`puQ0'[vy*% ;Э T1[|+١;p`?15auD Ò@KwTvːy]hDy(.q|z̠J;qkڀĸHY]8IT@0XB2ŘTlVXFܔlF x TC:*&!Yfv֛Ϡ j "XZ^Stt8N A»;&L!1t($`7OGh'RBE >^{z&8L[z.$rQoNj-q!g]빍epj ~ ܴb(1) %b7.(,Y1i`IJ_erGf󻥰\lX+`moIf0Ɨ*a-%5s} ^eXܵHSN|?Y9?wӬ(8 иf\7sla/FIw/we g+Y)q_@ ؗGŊ?)jc(]Cj:|ek\p"뇬P]Wj ͉FPS5 '3!2# eMf7YQ|.yLwlywOxfд|//1\]ѫ$FҿO͇1 o}A`",{Z w b2ݻMyJhW* Z}b~(XEѦ}|Ev6cՔ;wo0Mf &43]FU7I$Fqsq$aF?Dw>j-BKڱTVjK2'\:}*et?mMEy_0 3:@1He`~I^o罡$mtU9 rdYx _k6q|m&o&…di2:pg.b:B%[mcfjw7jB%:>s.mXq`+O7fVr"=ᓶ]EtUVݪ2Jr% qɸoQٙ'cj6WMFp SQ xS[41bۏș+4FaN~qWn(DYn+,ͳB5.NiN@6GYAnVD= iP SIm'BZςϛD.3DL6лN0kA- :g>7b@vANPY9.}#$7 X<-t$+M" `PT|[w/̄*;Ayu6`G]Cnt1#V\{j.ů ݰIьQe c݅/| )hApĩ`Z971#OD0 S4m^Fd`WN׊~*5W0Sƶ>Cs]?^Ǧߣ_B1*z1}x&^قVaL`LX]/)yx7p9ۆ:VΙ/PV&{]emnpoK-D(8%AǎiXj'q?q@I#h8Wd3KJd6%͸s|MdSƻ*Swn0G@]yB6-dN}Zi?qtuq2\ǧߊI<tt2qmD8=VSBǫeh;alGF-P)I gzOeCwVD ~u?Q]u@r6`${6tf5}m&Ճ>M4(HId0qsl=h@T5(  !ٲaӼ_*5}6L"} ƥNԦ4qeH'VU5LS1ƃؼbyy-iKz ok8b. dCzPzYLWЫjz\f]vqSg_3MӽtFOuH߮i¥FE#~eh-M$ 3Tlq,=s#`qnP֮Ept\j$B_km R$Bxm#T%LI8GCrJ,uj^uZÆ#A:1Y Ϛ͝*\rZ ] :BwYNv\Y eQm1yW"晡3Q94gҳs5Df:#$i/ TOPHayB(?^Q>` Q5PB$T$̑J OÙRhk h!C[NF{hBI @j.y8y<%RMOS&QIK ZqO5яKo #i%\'#K#j 'pFр& CD( h v:rvt\TV0@&wOTUg}7FA kA),NB)~5Ǖن٪vy[Ah>X͙ 3rܞi\|\W ~U@d.u|,::8<Ȩ_t\S5u}NNtPVlډsxk%>%s9L@墋6dž39+Nצg(*p'" ~܎ht12z*gZ3BQ|xGsΪ<gȠ^| :M!~N16GV3"g` Iq9h(Ɏ$ʮDE{Ķ9!?l܇rD:=\WzC3zvi"0W@eZc .QmX2/8!  0xxԟ(܁9݀X܍;@ 3G3U38K}THCm Ԫ|-N wv Q>`K0mܦ@SIk|SR(qJZ@2/c.Wx9C߄P[Ӕ~thi^t\W,Q/ p_loPŝaI1<mp Oުc'"j3ykBLw3F#MK[x5NN`w5_V kše0NH^2 y \#4}CΣOb{HS\[Wq&&ܒ?띚\sx`E]dŶNP-Gub?-29dQunUm8 /eV`wWPLMxhPfIMH_kCp.47[֠'A.#o\u[#I6B3˧ ]S9edOE ++}.SsRemj> vhH() Ez @R=ƭJnGV3,fDsHّC]q((m|1 J4Z>fHaC2+bVo^[{ ʢ/. \3cU2)zJ8h(Ā-z[aMĹxЎ l'ypSQX:2usnu 2rӣVN~8~}}^Mq9xf}]}N9#=&7 L ?nk*҅Q h0 iW{zvs:*Gmnhw2.0RT7ސ:8 yFd=2?*!"ˤ~ %$?lz校mdzY0)HIH}:ŒAuH / SxinQS=G|}f狙}8nd-ץ g†n#9G""ZyQi18݋o޲;< a! A_QY#ϡ9y Gdؠ?[$v`n<7j~Lӎ}'981ޝ$^a!3?Uh3OC-_%#[ь]K8)xvx璄|ʅJХJx؏ r?]﴾JL;߷P0ۙ'blbY}jycϲ8u3ۜ]r_ڇҼF"g@/xnPH I\(at&v˦x*.5uHx{-3N'=& $uNc價!CaUݥnIڂXB< inQ@N]A`1Z3#}{2ҍv 67yF_^jQ7+{63D^, n 1?Ы[ QyI;O婻CzWBtu ="=ӞZ ' T k]UmKTcf&Pgjv")7Bb@v, K] W$k6N Te|nr_ːV{f,'ŪIǀH9WTV>#(Oh<lsYe>Fћ@,靦Bk|@u#%mn' 8so*i5~:[Z"azP]{ܑܸ;-3X3#N~6x)+eI$<&xQBp}eh:4`O[Btf !\lQqWSGpyP1jZ qY0 #8/%>}]0'w!IxcǶFT`  1QՃqƖk砜V$ʋ_\or{mzf@t[t:­Z.FǛ M WVԐ瑤F}\Yb7-ώ:IͳEY:|5ck9eA52oyg4` г\G6M$">]ͺTXtO* pr`O +HV;JV(> +G(SyIX$qp,f27gϧ9zУ;rrXNȒ &3W"V%Coo:'xp]w\>rub*Xɳqn}tB7S=Of Z.*H {!P&(!wld,ZB?,x/Y 7`)'FOEqkEJֳ ѓD4Dk)SƎEZb"Ae3P'*nN$~5PԸEZSFy\Kb!2eOޜ%ƍ' `Ȝ* fÌ53em5#]x|PFmx[ 䶆7Ay [%CZ -`X˦#)n GޖHD"S 4ϭf(YZ.6Bh"Mzh4AJv 1NO9d*Lco"d 珧ƌBer^[Zݛn2N*η(JOV1%/2k[:HpJǍ#._xw/ūC9?@JHFVuf_ƣC`S!Br^6yrNd}\' kn J-Z T- JZ-CM%ak}Yٟ ,ٝ+$#kSH.i>;H.f{4f(w)Ĵ둓).<Ȧ)}c WÓEVx휆'2!;M'YDJXU{&[Xͮe z^A:촒i$с́[ T64Lnfʺ۝)<,&f+]J~D!$2[}4 [Փ 1F_FƏ|;+ra>fI +ar;%3/%Y`d)j탴5q~akl!LyfHhjB{W &#w|P }T&c׻cƲ.p. όK_⻡ N3q1P_R 埾.9'עGGBw~ { kUt8؊bf\C` [8|Y'lNGIHV7i%>XfqAOSղIv=հB gJ#d[Dz D9@nwGy0ƏYuh\>\P:يu( s(r+sYPGAAodNa[=dP9i(5UT u%s.!lH˯bZЧB^1pUmmnm$.:S $īG aߺ.}e_'F fCD?ǪPV"fjLI6%-~r1-TWA/;  Ӱ_VgYyTTa.ұ5@jfJ-\00ǵk"ހFHŁ\>PFZv} 4/ 91ΓW;z$إl:켊ߝr7Y -=Ǧ.퐨8/},c{L'Y1"?^-W;f6v(H LXK#_o=tj4ZᬸM $zf p[9Ⱥ+hsv%0Sߖ=є;.p:$gU.OlXS"" s*I9JD][؟v_GT^g/fyˋߥL;)D*'l$?H<ƑW y}mO)%\4wo|6 ȬwV#BSaZZ?}! ܟ@ZE[،8ܿL0H8W›L-w? KZlAd} KL};F (54/(H*s}whrdA\rQ!#dmB—eLbrІތ6M O[Y J,"pӧY:/D\L-O!&4p12t}^H Fr-DX?->Z$z_\SF&p{USr˳};d["()mwA{/ o|N4YiʽV[9H.A6+ kjLrN2HEI7֡ [ݘW^GkR)}쓪OKfR?r5cf0b~:OOt vk*'|M>CI"IxH>kLI[ôbi!a9ݳjq=ŃZrJ$?$-߳Zp@#fGu5hH9+Qst˧K(DGcNM/5Lzapֶha M}~"?X/=:p{zix 0xT3J[kپU2RmƔI[ ߒ˧?~@mxdSs{lm Z_]?5DN+`-\]u:9ѯ? [kgaDn=$lTdfi Q'>=];ԗm=.0i&AO79`ufjw1tZB_xzp*w6&XX1Hǵ)>N暘4i˥Rs.o$VjûgXCpޤ 4bO³1'<k5`+` PÀD 9PbW}eK!m`OSEX`ex~HiJ艃 ފG|bJr`&^V‡U3Ǘy~1 Kccd׷F?ŇYO~qp:A Mh5t`,60m"{H-NR1{Q\Jz=NhY.t*]܋tF~'/kxtFӆ8qԂB[ww-cބX.wk !~zDXJy)r 1%m/3--2rQBO( ?dWDa%K?5Oyo _@rBs?X7x͜V+9s?xv B\DX#`q1qs<+R<g Sxdϥ*;c%0򰫡AkP$ˤX`y1} tqP7|ӎXhSȱ1)kqNOm%[6Ey <̿{-.;y0O9u &a>{|2UV/ɶ < kMl[*Z /KߑLM ;5d@axTp5rמC4"UIdl6:6:{ZPyLNGt RkH ƼvAϮqu(t{RЮ^Zv ^y^)m:ێfMjZ2K/98BKRaSrl49#T o v|+5bR 5α&^Jvٳ:Z,ʻk'#{9ꝚAyC}c$[(rTn-BKE'ۛKyLea`fwe|'Ȉѕ+GS~! G4VYT^v= g}.쟐Hpq<~`ky|Ŏ'΄齁nplOGE7Pzx ,r!Hu*Db" "4Òm~wi4L 41UELji|ɾ3qP\,@nV#j?Xݵja2R蠶IbGeeiHbSE }ato5.KǬG$B$D &VHߑ{R6 <+yxV Ka?4+",DWu{m(eGdDWq=IU_}wbM?A[ a(@А'e_ E !s&BZ *if93’;6>Pzo ,94XカbVa,ѧ \x.M#qCswS i h`X6sblg4=j a #j6a>n7{uv8>N@Es3gc~8߭Es us7nxǑ֏dF*@F/1<_!5Y/:T W#=&?:AZg[ܠ 0)ε7ƹGJ-x f >o'<wܡĭƑ/| 5cYoN 3v%Hq7z nK\kb?4;TlJ}*eC8"}^B4S_S2L*S֏)UobA3{;yJf'Ҕ #:PFEїd!xp +4v$^\L q98ԏ*2,+a@պQBΖ&iY cG%]֬Sxg UX( `'<h:Nb!x=\X4w~J#aCd+& fA`g^hظu4!-)W)N]ŧ4q:#"; hq|vLTwcC/@6:єM;]}ީ8_^_5rzK6`c}{; k+P\N_o\P U:=/ElZ,94/C:W:^2-|;{Rd_ƻF(fH|3s p mRў"qIMfMO\ih )xqXEEsAc/\Kc@DUElrƕs8Q*q޻:&08Z'EiAj^P~wtJ)3pԉsR7sf5! %PHP{[nL$闒ݢ'B^Po|v68"c-awdR\gwODynQ朋$"i\,f 'Nm"8i.דOHuW<] (I-v tM螖fIBԠY|ir{wL8ʼn# !o~@zA1t,`!=E,ywt>jQpKQnNe1ZOn;\ dǀ m'vā X5Qf6都DGĜ5yQ,Z:zJLDPFwjpic=Q\y13TR|_M"6wX@͎Co0^׆$p1iXfxҪU& ْf^U{P0ᴎ]D05I_A:(#t^-Iz!A'L^TQ;)gF _W]c-~b݊L"WW`\IMmra fַ*Z ) *#$2;WRyvm q>}Ԧ`|r:]7*X2&Tsh7Ob Oq5I[sX Іn%Rجm\ V5\.jq,!5D@5XCWqz,eoʈXf4ԸQjN"w LS- ; //2k( _#B&:V+boy'2 i=t2qڮ_#5 4HM73yS]Toƍt6Qm#B[-֥t^'RPZ^T݂z'!p8A䅐=Si00HzgR5*HN!mF I(1O6? +k*l8Y4U#=$~Ϣ](+V +FEZRmDeFy Sr ёXT)A?\K[)SP@aP]cLrt)boܮ\练̀OխLQ]wrI%i}*YڂخLyAZH'7scb^#}hVwGe9O#DHxa\Ѧ 9 R3्OBƹ-AQ%N@U)L4mW^ 8?4ǺA};wRH3}Z (%Ŋ@^H)>hOn&Q +%*Fٲ Mx ̍lјh^#P^(8d3ao`vOv!ȅ J`J# YixRb r8-9K51' 03^]f^OGm;j3PΎZY vbu^X'Oa ,M8*8=7,'y|Q-c׳s8j Ԯ22od1Eثp#plDǃ_JD./OvmkxEkq* Njk0ih;,'V Gg6P@_1Ϻ- ?ҙZ>׭0Et[0\Z/qS*O΂GMB#S%7:{2=Jfhj*w0vmYUԠ\Q# ٹa5Br1ZKNt;o7Dx87 0]𬰾M@f_2"ϐ\%ʈ%O:&If>BmvO[8#{`)0{ *g_l0Ve%zkJ$SP*iu7MÌ |pd8+ygY <1rH$pizKx +"=I=8c9T$#k rAjĒ'h`&zFcn~Hf&8(Z87hv}`tl5%o2*Q <0OXz̗EGay&حs7sh1s)/pN+|%&-[s|W~$L1*!/o*ȭj#BOIY-@‹. Kx]|~ecuVȅ"#.0qS1@1ZaI~9O\;as'gr(ꔽ~ǂ3I LlkzZ3Q,C Y9iF"tI{]<  O.KkoӼ(w0%50 I`$hgP9&OA~G.Q)]>e J%25],z2'M$:M 4T8GR $(xEso^CLК naT;ST| 67d)r`ˋc 4Bs&[81Py|_TJ1V.];¡^8ϐͩsuOݲ{KTAC^_ݮ1C.xyO̺Z-f_TcDЦ复fRUjFMvi`x&d0>;m&L`kR楦c߰M6t n5pv hlu\,-tN ֤ޮqPwp+p]( wXLMW $r:"sT_. gm=Kaᕆ+R 2nA2ډ2X.eeXQyUpf2V?Ќyo|$b},гQZH]rۮ{$("j[+Qh!ޖ`T"EP @*o+onL@Ӳ. } U\trElEz2u@PoTnuO X_`.\!#ȍ_;G, G=FM/c:/ǃ%!Ĥ]̾/{cZ2 <͠'2j ^;[4My]1!fxAc b. "'z?5h?k查i\Ƴ)< WjϋGyaX~+:hp4r۞x 0/4"(1ӋuJRQ<#L.HW6t% fJ wMa|#ӈ$oVƚUK8)0p++v-iC=!IuN&8;uǦς*pZ"u-6ۤX`]El7i^^k1'' ;:1~9 <_aIwrtz7U+YӧdTʄ66i o"H1[-UKͬ|ZT!T e@m^0h񹱒to+r6AIO.@bQB5+6^HM~k%)󱻹+QH.Mݞ߆BP|Jʉ6ք^n>B꜌0팹 VJ_Ċ?C\({ߨv-D:O 7cR8F=o-y.R'C9(k$ 1pLv(lJv( O9B`,pw11EBkH_߱MdNbGal2ؗlfu4&%oTVei)r5Kl=8oLXo0]|D?G}j0 > -Z K JN}~sihrh{=J;R>fD`[2J+tSN|#2k-+rtJt,ry &XAA8(NTiB@QdPH.c!jq=nE.'Xr%uzzDdd͖bӨ\pu1O5*"Iht}Fͫm/}0ihg+'<IVIce:Tͥ.":F`MX^zbSRβsP΀R3={vO(&!҂1"Imk%GXs"[@2 ʜ,靶ŁhU?'HF`1\M.HOv91׆lo_˖e܏D֯S3}rNkW{q\ &gwQ $ Rľ Ԃe4:-}_y#7taK!6% i(7kN2T뒘Qk=-II^K\r?m *SS벖[e$ÝWddaCBm|cPbƗlHϞĊtlރyگ>ɭyJyY+SDyV:9z,xNĴ۲0)ͪL4/x`wR 7򣚛JBg扝p5`\(np^C$Ba}Ѡʱ(bt_f 0zHc9SoXKdԬ(``K>:J vUĚEڰ攏hGѝd .m]g_%]* ӆȹ5t|zԓQE A&wj &rp(5_1b'%㿡 LnչٯdG `Tu"1H`g\&{ TzC726e>݈).vM.&ȩ2JfXԾUS9檚5TIgF\vfmD/ƄN׫^C׻H)Ef'_TLl$)jQVgKi/;"#&cܞiAݣo;+vs;]Of.h:&ipfD^v$#TxwܰX)3­>T`1? y<@Gq_ء&8ڭ(lӟKStU~hT1{zWDԳ!}p^:al\GHm0k4-_H<ژp@q_kMj7ψTsN֪HFԃJ)L,"la S SD^~2je0 f$ ]&3~0Bi^dp9{`i72fy!4(7!DrxiY71E5O*[YTMnkrVL5 V3 mIGfa~7l\@nNHOy_'Td$,[dSAG5\fڻq[" +fGR bg_b,؀.8Or:ΫS0ygʧp2c„R鹖^E(%a:M /`uixc=0VG,O077e8[ ?Np3,'p'#kJڈT{3! KsF5q@NhӾ(+:uLͯ1xN%ȦD(>V7,F;1up 7$2l!z.LZ.;+sA)¡x1l}\A'`M5W'Bi6gr7YMnN )ڍznK^|~rTE Dq&g j-T1vۼˊ[5Pᗢn^Y|>zR1(ʏ/ӴoWg!o p#.`3z+t* ŭ rW]-I/e=8"?jv<ΌЈKR9 =#d:T{9(o$b  s=S>; lN>N{_#+*/7℘:A)RtW.@ϕ}u h)Uoȧ.IsT)G{uNM5IWF>OFބNbZ5ƮEs%VGRr4+V"QSau4d;nUSDoAX6N4jdcxucC4I_l5.1%*T`{5)VŶPvRRn (rKa᪲| ӊΆjD'${pjW(t%=E-, Ɨq Tx4GuᮥT#>m @\,eǍCiPh .f%Ve몒\čVB{ 2Op*cy:}!t2rs:MrbAVOq8um"H΍42p ;j)Gn4вsnc謶xZms@,)xt<&N96bY%5Ti mCO v%omS( BML"D2OdRy0%\m;{od$vCLý)0[hMGc}'go@,>zE[VjF/4`۴L5,A-02Lvga H黎ϱI^]+q HӨ8DXhzZV7IDJaԪDo>1eZ kd ^e:ڭnOi32q2~_le~ܘN+6Ⱥ{5Fm*R=fIaYNH.ĸ\ΞxaКxT"fͷ5.\W(P&HzC:":O6p$$T^@ =}]}Q\/uםr֨XQ2/V}l1MΣtOjIڀXu]Nu%A^t沰Eupho?.B]{u"J/**5"IƜqXwe=\Vo;G+{VEqp*bUyƣ;Jp9M<-b?rOV9X'Edkζ4ypM#6j\.ʙ20lPjf N,# ?XS_u`"BySW(ggٶLkmv,$ZXIeάn|uվeXՌP%,v|v/r>l?la&_]cwK oF4̝mkˆ̧%MgogD;:txCbkNJ]9+@1c_ܡ< ?k,Q@UherX[בҫXP7?bɖ޹n"CHVU#V鰁伟b֫>"O~`U\Ya5+.>;z0b^TIavLq(0m]Her=d(yڑHWfC d_]Pz'~paaFo}!&Sa]#BFZ'(] |e:V[>':ٗu=o:|st' ğ4 by:O.\'F6_ ӹdFe3t biΑKoz:yTarۇ%$SkfLz5q{eg!msJ~>@݄hX(3GJd Ѣe41e}}Bb6nTRQsĖZQ@TA:`?)&[b1hJ|T `SFLakx@H#CF"ǎ|1+}_B4޲0 5Ps~&,v=?(1XފQʬ3OI >@wQK1&O>"y5 &vEb@V6b/̑Đ2t*,mֱ2@ oa!܎|7NcN>z?;r!W ײB,r$Dڌm7O^K(*TݱW[ |SjL@r5WK:jlPEuwU>Apai9?TuW>CYo9ut6x/%IMl5d2zꫡHyEY^q/*F ?@޳M>hwސ_BvVI^Z(S@lqhݪ^gRwΈp% !6&P!#zV;5qUIq(qg U[9:LTbzFgkZА].d_?jLoN}HM+y7Θ~nm3Y25\ၙ#e(  0K*b;ك';s٬f"1N%٘_Ush>HdÕ;?L2ݭ~{X$m` l,e5V!^l`oBfM]ձYe~m!\3x1Iߙq eb Ć+bj|ihAMω]51Qq^ϳ\b&Z XyЄ9Xg@DjGn 7:^usR dҭPΣ+]vAq1PAMzP&b-ͨA<_鱐L.L=?uFz't&u[7Tٛ2R}Sљ`wS(Ê&MmP[% "29|Ġ!l]m6s|Ӑcqxn*QϙK8T!b:혬eyUf=F~\Rd]Xs9j^B>!UlU7yRpȼ6:5iw9f'x{ XLGveD@#?!TZ~Vմ" j"GQ$7jnOy e?ر?r4ASQ*DV؜AUĈ+s:/Z*Ԝ$2;Kb$BqKH8Dz銌l7v4W([uҜaNK@KcSH|XFA-cj95Z լ=1@WRxU&wѓ2h]!{5N Q##6 {߻|qDYh:F )"c$z~X}pbUAgoh;ZpN=GڷA^&{yN3 fZ!@U9@$JvZzثlbXё?p*Gn#Km+ŹV荒DKoKC3$wa5dV%:FvB0v*|(B|Ckpq I (W1(€x dZԳHqHhig @Z3hza E -NlTu* UB STsw^ҹk_BVEtI@\tHj_רq{}ꜣ]^gɓ'C]5̟C+*H3<%$ʶ4o.s 9v}53rla^Q-80aТ.QUmFpl.w/U [0ldUw_c[ZmUܰPCB{\>-;+z*Zէ#m18v[iv(!F = "Ѐ9fߤ)v.=1~c_uCeYvcsIhg|3wL_;O!o2{.E\ё>D5Ox~ ~kMlN"ѣү[ɩڕ; ?ʬSP6,#d1΅>H=^VDq1YP0x ddl!>gf,ƨmlQo]jwKnUl#3Eפ.Syn{LD@J}ɚnVNh&Ǝ}8@|-[ 8>P m3EeTi+oF~l_ܠN O3~ i?6Х_)fwseOK9cxJ%kTq+ qu鯰^IdFޕx'z5 Sjx_͑K#Du-1ZJ:fu/Y}r]WaFH| cNdw΅CpU t ~H@Vv"G_$X^5~ 1?+3]Lc#(]p}fDJ8?~,wF^#1;cLfS)gu^uW 32O2Q͔ր²#:rr+8 a˙f+{1,3-{k|Ҵ 5ϐĈVm'1kYDFS/)XQ1ǯi}v^DMF4Q ApQJ9{\_˞>| =vgw%|gG@&0.T߸;qCMr/Cx! )/o~qCPc]L !YNs$׹Ow~(↼B.nڥ j܉P545sc늻T_aWZMAfïӠ(:yY4  2c#ic{)ۖK N:i?3,=Cv9O䔲8׮ʭ |&ayN'hmrvʦU6>̭?މ ^MmPSkdi‚^N3޼Y\E!Ǹ]Ek%>k: CAwVk±BBzʧR)X#N\l-ƐR<[ 3,*(= ;G oI>+[CM5Q3z;36|1޵>{Bb۷=wz 2sRw `G8x>j0.diYM5޿O ̰0 >;\:&I\c?eQ6CJ& "teG>\ @Y/f#I6ٲfWe05/:s~5[2("\=ѐ5Z Zt98ڍI9E{ Ҍaf]t\l?#ոXӂndNxm=Ng~Zyl8{Ĭ\5m0A(TL~2I΋9aEeEmC/5(5n7' f&iq_0|@fsnhW]b\7D3"0om6#ΪYo>#!kJ<'ӌq-23r%\@ֱ;3~I (yfk9=`b:roLSzx"#B(L6tW/ie>'%5+_h`CQVA+< k!oA;ښ ̣ˣF@]0E+vb[˥{Y/%n.@H#鋳z Ui_\|v2>V6hEUʙPو+&Ze.R4R(}^XqdbűY1> Jqߴy$CkЏB{2#tq*$[՛*TO--⊄ 6UE1Kzf'HO4P=:k=ՌǒĂȁwƹwRGR3{k K)OJFWo_ I( b|q raꦣ ;D^ }FȀhŒ3)cb)I=`l ^!NpY!@rSH\W W%cG+H-#?ak(°059D27缜6M*PT?L/%y5 GB6Pq=߉3.1 `C@㭣īT~|.zGspfgԶˎ_3::ަJɸbU4 c<$e!4eצ^!Sn,0]_@8Lٍײbu6 :9c(ĠL zOpEp̪]##jp ݼ9}{ c'LZFF$/9}KdR#/LiڇE/3@ L5m?rYPs\'40/.F̥ q/} 1$K |U0r͖ Pk(1Яzނmz #24gٽ;#[ y%5GDP#0-~4ڙPtd|`iV*)Vjyy-zTsS"ah_͞fes7L h-ne63`i20F"nӝasi6o>(KEJUҰ]RtOmBʥ3צ}Ar;TmڿE.jX@mx&w^RX:Z#ԨpZK Ԧe:/e0 ϊ\yVTߏnojhCvmdε 7xU$SkZo |Nhr ~m24/WF)e8& |:uX{쾀HXxfLŷ8\G/Y#k+)I@WriLmJ8O0;M.Ad,,h/:#r<ք7fpT io$=}RxcIud ȲE]\ 5t<^6 ΂|6?nuv9;}t_8'(17S>?JFzs2RNbf(BbEX>ak^R#rynՌH?}&a[&:bMβvA]4,Hz_6 ۋp2CK WɆ/1qۥD uɗuAeL Bw0bNYr|OHV"mt`3iн4q>ur@a$4jM#hŭ0Zx/ϗ"\ssq}A.]}S;EV_l=}H湷qo]P{i94y7m[j+$;vr-e_E.OVR>.5'!\Ȗ{aJeC6ba8(|4R_9~gĚu܀B)I'S-]먦Pjl~h鑖Y PtGKDGA{**'G7^"܄WC5G% ,35Xr"Pݏ `;X*2:7/ 8"cHQt[Oˏ/lR?sAdhSm](nCb8iQ d[aA]-$7Qre K@8jv#ye\q4qFWj(ۑ ,zZAD\UĔChrNƊ UmXdj6U#4<uҧ"!Q;7 CK#APfT\:XOΨW5cZ?Ql]ƓQ&aKZd0lԣeM9>ngy<@h#}W ʳ%ٚמs t0eOZZ?Atvt`OI=`H#aA݈ Vqr_Na 1/de)a50!.e׷f89;LL 4ɤ혳}}@&AQ.=dݴcJ ١D8ќrv8|tIQükTLEcB Q?/_ϓ b3ͮUti\$P̹H׹l%VExq8iBNj`+n:ؖrb5-=ĐOLXo]ˀu7ẅ́$Mt|c|圳JӿsqM,%PJ DcƤkhţ/@3~OIhV"ׂ7v}Lt08Z{ߚa%eդ.)$Xj!.Ez1>ĤG4Qd ] `8Oι5}qŊ?2O}{O Bnlu=:gR%$.a"0SE5##)8Ib2l.BE$+] D{v>p`'㊱4ûIDLGŝ&,H,'O㇢| 3V ډxJYô͸,(謹,]oW)^$|=^`"9Pj Î-A1X)- ):UmL-nD]jO0bY"~g!q] ! [[}h.RFJa0-N{.}=8VM2Qf2.AFo on9<>ۊ|l&@,o62e4Ї!B^ N ;7\eԏ ڢOEAݽp.g6 { ^@YMħJL.+2)Y0/2A0 *NZԼQS~1_*V+Utl wF=ЯYicG-HH)q_\✸}D@oݧ טl6?\KIN@Fݱ37}m I,"g>en`eazFb^V{o j}b}֒;hs,)[%]ܕQIrQ[k؎!MSSkkϞk$=zZwWտ8fH)sIP*Q`R-`F҆t9; @[s}%wbE\9fK֑~ S{0*]x_.:L~ ɊK8A\Y×4zE7kFl\msnpkx[ǒAEdLNѬ N@ t#>F:်tzg. W.85?<;Y9}ȥƝe^f+E_26թj|͚]N"vLON5p[L ¥(M~0E=FCPt#:&CZلxL2tLzn ^ơ$Ô!ʞN:w|WgJ@b"l(=h$%FrqG(D, ަA9#]w.cXQ.Ln~oI샼Ь _ujx0t| G`^ɞ)kĖyUNLGLjd7<$?0IH5T [G?2IPbx8!MV,>=[5pg /ء$^X UJ7uk)6 Fx 6 ~F/gmAjaZa=T'+(̌F ].H 1I8_''y[t3 }y{^p4ߝc[]_jrԈl2 B\11~:DVl .jP[jzZ| /F q]nX |׮}㟢|'#(@E}S:2uykO¼qS(}*}6kP삅y_E@٩|nq?p62eih*sI-F "DsV1Q_,*?<=J~`1N;~ mzFêbps88omrU}ͱ6jjEI BnkaAqT0|(zF˼*`n7{ .2L-ތYJrɂ<$ӎh%Wg㥖+i嗇 zO1EG~+~af={v0W4xr<1]݉\͒Tg;t'ibA?e*(NMhugfrvZO> k(_5PCO-E$807p#*9pLMpn'Թ1+ÙQAfLoI)\m̝Y@} _v֚i1nsڼvQ dbjwCLG)#(ַ֟;1p[V8X)E'AVe|=Q;Lg۽G>{c3[!\5=zk&Eg"TS Ay;$l1mRUiє"eNؑ$Aɇ_ Gm"haNnGu˼vN(Oֻ !rfzKۼS*+*>ܑh;* )ܛmoOb3Qgj))Q"3dR#kYm>DHc)Hei4R}8eC'}V 2shT,hсޖ1 D(8b |Iւmok󀙫Z7rVs0c6X ֽȃ]I߲ ޭ߷d轪[Q g28BcSxpޭ!rCΏSզ(2_ޙ`裕(ycrvU4U4_rD/(9JtAɁIs&/ [kLk y >w>]R[  Tb6+K,(a: )p MQb8'A!q ]MvJ5S5zEsYģ?Yʘ"`GA5M~"K5`ně%CP3v7gb#Mm1!`l7Y"2ӫL8|6;$^4U~Ld\pi%#6x:NR$NeN3Sʦ\v71ӰT+:8ci к#R]T-%#{UÐَ|7ΈGZe%BYx4sP()b;MZͤtfTM+I*f̑GR:]w0IY* URjfo-cL3ic:TbvW#3h IҒݴٌ~O{e艃l}DbFu=Y8 +~H-_ )ObX<&4'5 *jڥA/ ĮƇ3d@9\MJM NgD:lxbk>~ v `POEUi\}cx.Oa˹ZU}SD&]b!Yv(ɮMag;UJq%zaf2)^J; \wC,\lkOD#č{ p>1JWІf"FB&xݏU wvR 3o6&VP@jcyvqMwG2g`p[ƽ_[`O%<#¥!v/Kg[(px}&~4H2fڮ \&uQ3wt.YGU =u_lNád!VMyXg_jZQS2xQ \~@Tfq] A6K_0ZEz :喩OqyHcT.U漮W;噒bSA#"Mی=_׫Ԣ;E0 HHkqgWuYl}>fq`B/Nnؘ:QII{=IӁq=|aL B}a#넩d"ύum}"u; =";pE{ j:eY*"c . cD]d,%K FJkgPn[xT( |IGHFBo_..Kybvi Y0+L)} u_ }Y  e`L4s$"FF8 0ռqFCaj$=hҮ4SEu%:R1V S'|oytҥDc(.cpp/M yWƩ#kXsȢ|:S(*߻gAk /zU2&M$ HsbME&pź;C&lmEo%v=r^T~Ăȿj[ȑ7!i' {ϛqAw]ЦK<-\6}< )6Ӥ+$Jy굝Y2BT8.`/vK?7]Q!cyZR]f_.?_L7q&P.)2FHꐾ$=i i]',y3XDiYL!rN-vu@J978ߤޟ猚j~~q€"} C?k :v#ա /{f h ԟ-7t[FeCŃvvϘm.v2/Fe B{8-"8TvmwHiU\J) d 軡SĶـ|3·7e&{3)^N%v-˃.5^ -sܿ } QƸH$ESfU׆]Za)hG`=%̃Relu.rm^9.@6>!ܝt%!Ak;mB vQ<)؟5c4=|}Z9z=z2JPȳi8.QWc ^:r -|M^FS/."Rƻ O{ 襬*]vsȷd1A;ATm4٠ՠhl NɜGF'4G؉ETF29`7~h ˼Łgo,CoJ{z/3JLo,9XVhU\2& έc [D~kSlS x̍$(Qᑹ׫k}E^kfBxPDQjOI@xL*~f16g`J y%6geޡ)swZx@斬Ulu{gLQF=y4ks\8)t+cbC * O<՘9JOf-(aR$lWIpy5 #XŷVMJ64LKgR-̵>Ah֪ja`O˛*-i F҈77җ]&f:%W]InɝJ>J xsNfo6ZBJ [ #ip]3%4P@P4qB5u?BWi7MrYaΏJ9Yїiʵ[1ގw dэAh:Y[2)t* Y~˴ӵ@xjkXA) yĩX;,ݍJjyѴ6q$!{Xzn#E%(ёY&B "M ?FInU$- tM!P+ ԍ!߫WԎ5QWv\-ͮ"OW,bc/˶V>|;bpaǗP9b"<`f*]xǽ|Kk~=>jєr<zQJN&so*=o5|6W,ΗN7xVKZ>((ٜoK/ZQy43U3 '?KxV睕}3X9Rtx]&VX?}W:豥)Oñdz Ai&0oMw>\J׋-<}`/rF_VWؕن|.m:L(_ yr+i[g>N|۽aj۾>ï)H ]R~bTxfmS)i.`5#ï@9jY{WߥMX28V|}<=fTn K)/>!,(PD6^eAT_V ;_xW^=Kw._dpby#x ~+RLjm{HLrT舅aMV,qR$;dzdG 1BïiʏbBUJ,LU.qjϾ~ZL2УǫWD$Jx ш) WW!9 r(^CG-+ bauJ/䱏ح ?Sⅰ~bru(rm%?MxȯcP{H})QL j տ }wѨ]Lf,XV; v4k!2+S\)ڢy>4C-/AxHDtʑT33`5veGeY<t0HBBRшww5-CFFDЇ(ՠP'VٓԎNb*MKB_`Ql[Ϯ]=]iG;p.dܼ$)&w~InU^8!u )͎9YD(KͰz^GN :r\0ѱ~E+x6x%F 0椿07&<~OԄfksE*4|ht'Z}0}DMY'rAC3K3_tYȶ6XDZ|kO^uA<`Liڂ2ƤTE[rڅ` Tlxg ˯[ӽ9kEJ]_yмjCѰM&c &!k {i^[6 )ƪ~8 p*DSg.(G 4nfD -%Lm.M6!sZi#q 17?6H=)\Wfs=8NďlU6CB~u;3u{>}B`6:(Fyh{] ގS@UpS@|A2.&ZjgPOQT2iDi!}y8]"bԦ9 T'bneU {PHSK}l<+W{K);Gp_8;ht'b<~k\Sl[XK4{pWp&W ȅ 21}UNcpXtZP]:LCP+*ɨXܞiJuD_x$mZ^ZJLG袦_uͺn{9IָPUC\E8X+ޏLA$U֧L TnO «z}Y9xUy\=&;WܵײOGH2|E-uţe7!FF윇M;iV1VMXw37%mz } \xZ5=Fnv@6G4&&Mm\Jks1JÓܦ :ni}1bLIzLp!E; 0`kDj\^)03|V,XݠfT z.3EN~DVܵCSlHլIL>ۮlJ/fzW6I-fO좨FSt8bGlP1.S#pxzT.OIG)5Vf~H WT\ J|Gk;\ᶛǻji'2ǩ PO۽&iU}lCU.1{úa'@s+.EKZN=^9BByՃZEgs|2&B<39$ϷWX}5~puSX08'b{C#HTtWH9% 9)ISv5lPMiiD9wm=mLy ",hie{tPdw79}Vs'`oOޭ0;Vt̄ Xr۽쾨Iwɮ$Qrg8T_#糈pWpcT-YOq'*IJo z+4:0y_ rgaNiֱ^ܖ|F@y6;頛jwzzsc9N@MOJ DNǔ/Y s@Z'^Gb2pGLy若 $a>ԐZKr,#\NxmIr}i 'OrAxnNV`%R SDWlx띕{β3=ytЃB  s <=)<.Vl,H>Ca5Epow^dtx3mC]I)Ky-yRp$":aU+$Eb܄]jx2}X@5Ԕ뚺 P5{M3bNJhnRvE˻W'ujpTD;/ګ]I)f@ǥ3*Kw?h?H[qOMlldN-5k)RDׯ+eiYG&6teTr$H]$YVb2?~O: xj) BrƎD*E<++yKœ=cw6Oz\`ڹ h\%S[r*-vԿ[.8wqjwVjfQDQyti "3(m~u\,dZU tJ3{ĬVhrdu㕴Kӌ.SR&Tr2 dFQgO8eVPYgBw;Uq9&p7qRD$D<98#\#bT]^en)(;]]?΢̧'ԪosV,;=R7&)G0V B<ЛhI ~R+\4Tl~ t2~/F{yI1yKG 7WNpJmŇ>€z3<P37p r&Jԭ^ IJEnzz-'˵C-|ZW|e0v 2}tVċ@QJq|ɐ}ĺًn#K$E-W 6y~[|iM6(#" KhzB4E`8O(ws= ξ|ooOKi̒GшEm@nHmIpq܄Oe$ /W`ʇ3ʄ(B 5@:+a -{Ru-w}Q|4qО-Gy9@64FòDNxUu@`t-x8 h& e W/T0 <+jp%tAf,|ϑ*>߼כ7sx(Ct8fy\/{;6%֯#E%L 钚8ywk9=Z7xP1 # ABv.rU9`i3Q;rOuvNA3gl& ,xW.h̦M%Z μװm 0:Œ3~faJX <&Lo"$یWM-Z"G}HUę!,*󧊅9g }tm Ey"pԛEΆI!DGDS\ 紓%[ mm:&iibD+hI߱]!м2'j*X)v新i!j6D,49rHfBhiPfb[ ԋIh޵wiN"iGt\_=f͋PϟeY0I JýtK[,9y+o}<IbI es0ϡ(ˢettZ0G!qU1ljheS*]g.`+]щ?-+S%!9pKmL# NˑiuM,<`jSslVd9AM/6H M>="9;K|H!ZOفO.\DW$Ob' k9l1}a]?gWEHFi=)e_!i&t 3_wVT10]gR8g!>#]ǧmK%̰=nwRm5aSO ˺B5>ZVQzLKQx!jQb''ե]mjRz %n@zmTHIj7! R!'IZR۷˟X{l1NI\Q7H 1P9ʊA83/u<`I6 (`JLW`j^ձ jpĨ3|-ʎEet}ǾpKu!r =hcGد(,d0;V8ad!'}D!3Z`Ac_(-ٟ |eݏH}b5j[l2vpo7jH^kJ ̈́/^.S16 7TGq "CA%2>.  ۞d2nAHr3S@fmwG&jɧ/l nVA6V!"pJ@_Nbeer;Q꫑MZ;R,!\2.DZA3WI@m&3/T_ce[bxyZd8Bޯ@4jy֕ϴWJg\~1շ́ $9}Ov%^D,m:h VQkk.P?Nκ.Tn6x5]2Gk­=rbY4'ȊfFe2|W̟Pm cZ˖&&BRTR^ De۳l\sC XͯVlOb%˥gh##RZHd8AA9z2XG{r ]c${Ѭx "J3)[ ƃMjqaƈUHt `/ < V򯚚=O{ŧ$^F7PX2tG!4Չ>hOMV_Iv9o2㉲t;n`–?*޾~$O0dxE<<88Ֆc8deqP `iTf18 F|8,wٕivK WA0Å#s:x~ >> +ivǖ=UBliz hM"4%[VӝpPă"lc%՝.~"ZVxI G؁@JvU`6+ aFt r[X$=,˪K 5&CknG,Ak5&Q0!Ƭ#M{fK>ܡObE"C[t&J$<9w,.v!eU}uJ7ӱEʷ~U}]?ٰ' i ,*g}A%Ɠ$1py\b-Bdn,l1'Y:pU84lK>VU'as'ug*XVk+/Ӿ wʿs"󖖶*dXA+Ӿ0Z$M¼ P3 JôxtQ 9T=&s?%sc'ZLg Q iK^)g}FAtAQ*2_vx'7 aeyncQלgVٲ[kO9wK١.TOjNګׯ@vpK8mŜeI?u\:-?C= ?9RWQ9mQl%\*T>!tyZ趿aMX\kݺR{SUАN r ,_x øl* {6d\v-46owF7- *B^&r;AbeIILSѠEI22]&Z^Hyj ޵2#^ɫ:6-lEc@D*'8.b◔[ @0[N. o;Bߢav+M=dǛpa+H ].~/eLkmPy 4gQOW?m$ l!5%s(\Po]WhSt|N rb~m0zz9ZBPuEs]oַz}BɠdDQ'n)UU]\&_V2УT u""T6V-u))D,{:wk((jY؞p9MM-1 iNz jo0c SJ@=BwJj,y3JEn蓠mV24& #G\dܢ%Doު)uMOZ'>VQ*a_'sX C] ^ u5$s"浭a 9 !*!kxI38RԔ 0ʱJ7VJ 9ǖd( WhpY:2*8(YP41_)Jg4xcpݷ/*::?aIO8 Bxc'W+ enkS7IyzKI}T3rY-%?˩ e=sbԊL`_^M̬]LblW? ).ԶKSXw[r axb313csږs0 w9j8DmX*L+tpi n aG RƗS r֠KOCEay e$Qqc R~a| tܞox% &ߨ,8yY3[^n^%B ;8cBSqo lq=9E(C< q!*l&^e"=fhQaZwh_l\CF!Q)/w[$`d[%g,z}(yVk/;<6lqe DzBѩDV_jIw!HUp`8QTƀ9 `xC;X>u6DY}R:v'Vaޥ$("0,镀)( rxtÕx2bH' Mx Z.)ek;ݩ#@WiW+L5OswN4jIQ]|໎F?f^6e- 4*d A4vȚcqF8ҊCb۫~~Ogm|'N& ɾ0AnQx{ju^fÕ< Zt}.θ6U;m=~8CƂ4:k[C`k)OMaݞt^ҘU/L\k :PAO gN] >.۝ 4XͷId[u Nly_@a@[cc);lפ~8L26<NJkԊάDnM(b?c nLD[ـIZYRcF+w`=Q:2zkgAoc@ Q-(PPCaQ GٙpSjOU)(\sZ0cL]jtZTJ,`p|/l7GUUXg gyIDi|DG~Uuhb/-%#l5& 0eP6u},5%_3^5~EgDa8Ӥxcuɓ bY9"5g-냯ЉqPNIU* (j˅X<+a}8 NQ4N ٿjkVв)uk.e %N_ƪdU,ALD]}Kn IeajLW)0Pֿ٥Y&ݲg -ޅ}#On'.D5@Kl)WfH~7|3: Jʡ(%X FPc4)EN4Ǿ]:N6pn![B+be b\_Ӽd屝Os 6WY.3 }nTbȈɾQu\R[ 0]+\X(xʝ+Uj ] (E\DIBA73t&UZzK.Rk 1o|Rl?Bˣzp@d++Xol";LW4ENfQ'/|$z4H[ 4JyC)Aw=T45qtKo0Tdvn#Q%j,9t榧Vf)W?*5 yJKx-$iPutLG}t?XP$fwGpa,{j {TⷛH F^PD(iv1G5pwXn>fF)NT g1cG09p9w\^^枊sEs ,i<p¶&<%K\A d0A CT@$-8L'Hjr/垹 SXxmPw9ɡGxqogQk[xϴV ܰ53I:HʘUM'rB5sN{y-Q[ aXd> 6Ռ);:js18S$PU/E8zIwXG$~C2/j#ѬW>c+,6iz,4sЇm"۝'U7NX:,cj&AP1JZ "(8!݅[X83:|O]O<XHn8"סdN2˪::\6][s6^%/y<֯f-$>U#jIJ 1 s=**Ub{5RQ+)I4 Cm8 JSЍ{_BOY;Vd2obx'Tlw:y;u'lbMJz .KhwƶԇN'7 1Fi<7|0lF! 6T*i(wrhu1:tޗkゔ 6:ʉI(^,֋kKpLFwS7϶(AH δ2/?-CE6hp\dzB0zfP!oU'k^2~8Vd'ލDe(D ZxRQ$6L0$)~6ݐ"n %a$`rI)&275*y:$Ҕe[ *n:kDc?,IМnJO{BĨ"ޱCƘlb8\2MDD0 y1SM7CqڵJD'y+cpSМF,[=.8ד~qM5CTh' 汙@KmpMi6 :,? GiKI}'^VQT[!Rz )Vo20Β+jDF6wD"ANp# `dy+%Ό Ku/^_gȠ;KFr`J;{ H D|[bzĤLPmG NJQ~A7d Rnu\ƒv`K\Ud\=FЉ&,-^ jѢj87g)dٍU qx6)h}=4ʸ2P˺P휾<*M$!V<'ޚo~uDP,<\_fR%G<аW$Ssh34HvE\ ex.}sQ#\fy)(eB΄6K\E?=uW̝š Ҩbj~-N1*oLAhdwAJYnmk O]“:1/jVJZt23 c25-ڊͫ@Ӵ͚Nc`Ɨ|1㙛~8fseB26LCl~3vǁ({d.E h3 5$n6děLj9E4x0=NcnCfrqOE0SՅi/gؚ\W)ғ6\NUB_ lELk@׮Suz<+d86[0t<)] { {׮89ݽEGwJrGɚ(ٴC8ՐZ t݂/o?#+kˎ4oGbLJ~>QQzBÿ"(­zWՔUR\=/}[F?GE6‡Jr;o.!<֍wpzԻ hCQ~=ܝD `5!?^ tf7bɤXTSC\хOYEkSdHf5UrB+0p5&ݍN*Gs<*:V2'*4"Fjo u3JFȔ,|(9ig:+ٕ"er|u0콪1fAҩoCQ odygҔX"}}ẵr:ْU@0tR_ <@<.~~ +02++!ߍZ'~y2tc7XAGLǚĜT'3 B+Ƽ>z̔28v6X`OD-Ў73ݗ1h4ELZ!B ,Vɼ! Y75.SSOPujFH;K"(3 W9n4& f08K6Ӎ^S$f 6p"%O}7u]YսmGu~_>о+jHnc^Σ" 2Y|x cbz(빮fA ۩gBR=\p|1cCUcU%O'Ğ4t^xJ^@t>ꃯ$^A*Gd(D.lM= zYc3j'g,!^l#S0n -ra(}yX'-[\c`*\ታ+6֬I^q_RI+@34wSϏ,* &r*6k -B^{mlt" Bt?hy{d0[8`AoˌCƮiC1.T7!/.,*pƝ+ g]u܈(T` "j1)|[EqC 0 @KH9:eyTJl#ZCimu*WV]QЧs߀p;d֯Rυu2aO@%x$@5L|Qw|_&ar]0qÓ9A,btlۄqh`;dj "5^d|i /'?ӳ=Uذ9j/q7R# 8NV~v0gz&2NIԳHODxa#ώ0 2tX4.JEИZkP`\OpDŽ 5) [41f;nkQoF30;r d";B ]3͍`WQV;-ٹ".nc]kF7r,he$|.tӯ@E,7%ZIL@_47צق)D ycVa:A3<[cXhj}x-,u^($Np¶:bɏ(Fx`f4G*HJy/rzi~Qwv:ֳ{.n2˖te!֌,xz S 0pC !1z{ttU_q ԥgk~֏ %i!L-h/4_#ʼ\O΍Ŗ.#>ꔯf~l-^(4Y" x"ԮԄN,AWb`ZL9!MN3ZG}H+oH $_ tׄ[9z*|dA$_IR 9/(9E\:>91,LwQe:S`,[CO=Ƨn:os_Q)ѵ1?PDAYODi1~w,p< mtGPJ%z<]EXFoBr^7Q;m, kaF-iV[R\enu&?#~{ё3B{P6xW,%$qhaRSBrXtJ_^fyR0Xۛ% Kp5u-x$F\$} &Cg.1D H:+ |΃tD(.enZd˕_{6g*kͥr4 Z阊YvJ%.ڥX[, ei|;g gJ 2"rNDaxM @?;xMaF@1W"ēRktٷ)o)tmӦ% cvv,EJ l8/>!$s/.$1K %Mg Kp:8Wdו7t Ч'[ثs)G ZOPa8uU)@_,|_@rGX,BMH,#,rb3&t85 S|9<`Cwn5+Q I~؋z6i+'4Wp +c5d-pV3 mL $Z]r_Tdx[?06V5 x?:sn "&ꠧh-'ޮQ6bEncdۉێԛ=~._[,ēL{1U2({<%ODŪQ%spUYKV/u/}$۰?ڰ=xH ݏWl߶Ǿgfj[47hWP&[VVP+4 (s(?q5͎Y"5P|؂el4 ;!Ey]}jQTH#WmRk#UnXNViPc6P!@ԝGON=AfۜxmGzިS{3rJP%}:[AyB#ݚ|o( 褾#oHE%WAyžœ,$*BqL^j|{A T2'6`hRɣK݉B'B8jثm@?!&DŽGD"~Ӈ _=*o+YUA`0<`24jVa]klȝr h>˧9Yֻjl^0o[Ep~X)cԱYTw54#q!G6F,Sfx n Iy&"yzfH*@ts?ϊ3BJ!Ǧ!՗l "=s+ʦ5͐ 1fa)t㇄3O)6FTkAk/qI +}_UQ,ͨc$Վ 02_\\1I(4 ZHpC[ȗQLiLJgj 7L>* 6U|/29FA'KoO-950X9Q?TlmݪIuˑ{ Ψ5ݲ&) )Diσku'!w)Q c&?q`lqsdwUɥtJk_pr48ey1tyyIsξL skYyv@ڞ' Hu# 9"2- G\%1-/ۢ.l9-¶6fg6\ >ʹd6hZ,)`r7'(DuJxmsj p\ԛ@=^itװRӖd W7kjYN6̣i:il׿q9/x &Ŀ̰-_m_#mC4}=)5"Z0kژ4-=w;nY[kdahZWVacЄκYn"la!:lfpڥ#2> kuj8n.r#K{nRn_Opq͘0A1B>c5HI8TqZczfՄ췹d}4лGNQgt}W1f,N䆮ZJT]AJNg1JcŠ EfA]8E2uS0-[an0p_e)xPCL?4qjoS-M+z*d%[xfEP\y3S6I^ܭG 0qMG,V&9fĭ醢@蒥" Fl]3Ds ,ŏ`5%0 5hUߕ!NrgE.'x6~=d&YH%(c|[p>׈}\ !e[ H_|ފ܈#C` BP Sb00%K3 tNnu^-zrQ T ߭DيDdd465 uOfwõ~^}gp_&^L< N4Z mVa>t]ּhGqذ/P=}֨ U;8_HW?rq{*1c2?D Vm#C>!م^4RtIA}g,?<]IKuPb - 3J,grRL`-X:Eki~4G/) ,rѱA#^5I4~Eh vӿ׍Du-$y!LZYK[vpl^4aUrLȆ퐊@ *(xʾwC|Dii"7͸|lx0GB鎧 U-fbr"EAru>3`+)xPs.s E 9C?Ue;U”ti:t7 7Pڗ< 1W5!tWZ (8mc· x#2gl u ;恩&22e$^\DZܒdﭥ Ҍ_Gk{Ye,6 iNvf=$<݆GOOk`G=gOF`TvjkS4ܷVЂqL" p!v1CS~a>us-| p';FEPQ*KηYt'-do]L0">_,B_D%vG̵Ʋ ܢ1cpTGb>tS$;97޳܃Q7M`6syZ.{ B]Zt"-ҋ#F͚t5@R^qNȩ(te!ގ@w~$ɳ} 0x`0a ]D# mI_GpV+^T iK sDZ.Ȣ+Gqf4R)9Y,Q3pp.։-j :&(-E/1B(Wv128C aȾiPBD@{K+Kk6<obuc3mZio/ѴiXaLK.r_ 5WCһo}ے\On5ZSdPPoMu)9^%AB#& k3oW9 ݱwA>d!Lܼ(;j0[&GOn5e6`-]O|!|ك@ *=8q vC&n;pً9PW-6J L)YIfN:C< /Z=bXX.8+nu~߹w,*ϖ4`ԇ:C }/ 䌫kIh^K0lVLQzp"Ez4{d- ơ)RH&"FN ^ss\Ep)=`L/m̏ʪrMM1~+ٕ{5;NHjo;`Hú/%%SQ򝿊SYsP=U}-ڛ8Z+&n?S5HzYww e H9`VNdY]0 (d>`J}7rvjៃvak'W|J31TJlaD7j;7 P}1Xk.;;2Gݢ5xx>4 )- ty_ŏkC_+(DkY¤jg%Ld,Ek $X)vEFlu{t;{]isQY6nN(}B,TKQ'/lVsMc 2v(ܹ1=Tt"Q (yjvLE U&Y_pد!+zB cN/U%4e"8 Wș:gKc@OLJ `w^T!l3. qmlGRNYDc9! x8 'DG\%p`uEj3\D_3uF>J X.IVuySu*dgfXmrGeSI< Mu΋Ox"lk 邈k΋W/ @P95GeA= smflfU=xOFʉnR#&~"vl2jdeͣ~{ Py(xj)uf"лX9,dYS :U}g9[zNqD8j؜;2gOQ|$~Iv`c5KxF%˹j2΁o6?U/ef_&Ekĩ򱏯xo l> 2/pg3%cXa"X E{/d(\AA+ q{^t*(ll9fΡHDm:]ݤ',{hh ?tq S3T;UmS.i@_]ʳEN}B]W.;jՍl"XжןjH`ډp/[nSWjIt!dr*;aΎӭ)\ ֿ5$ZDAmvw٣`k? ]mT/S.#P 8>ի1ow`FyX$)>7K@,7l;r 7hTsng #†m7s.$}}- s׸!V: u,,sRnnI5-"p0j.k㊡`Ƌkq l0n0:9!d7cqC_ JH~},er Zӣˆ__<^ {}R5Ao4f5#c*+PH%NP [g^we)7wBkŌ'wwln!Q#0}ADL i@Oeߥw%Q%+N ID]{R^ ڃ6!'x;h*1Rz_>Y}@ K9r>̚۩~Iai(Sɖ 8SjfE0q\jW #Ɍ*AJ!W%(|#YR(Ԛ5_ѸsT}{΃ǵNX9 7(a LF"dUMɗv R]?#2OH6^׵͆Ҹ+W{|N~<ĐCQ ?D4㋣'&эX;u9/1=~֍4aUN}T;QpFL9͛1 n ր]쥋Mydo|,ơ( &ib}C#Fx^eKjim]2 GpwP:XR^<<.Oy^xxE`GX;sx-s3bg1y}@]7ҖkR{,;/"~_8@V8ClҍPZ=XτA <0~*`[IBB^b3|`ks_vUꖧ @r$WLBOtedlzy Np:aKU+ZĨ.Ena>L kVg׌@;vJ"VC㈑)%%`"=zzgö^'V\ɿ.^iv!blD+6Ы1t:VSB&: `t#;^+ <1ȑ[dwz+2X6>/D2;Sl[),"59N_g>AHni,D5 jD~/\*q=x;ur֗9M<'̵U_RY( @r.e*+5H4%w?iwî< Ix$ַJi,Q%8O LYat$!@܎ɟD-K{J eCQ"W )zJ =kNU-JO0u`dYHk ߶YmE->kj])w|1Kb!9ihȣ_F鯻f ݝ924;rnE^_pR~^6.z<۰<$4m&H4Ι3qk&Ť)9A{e0{F3]V, <܇WvdV^@ D6KՑ-cFo7dpCiXsyϏ~Z9בm_3vI^p!m)N:}|A+ qS;,a/l;nB&rIb۾h@Ԅ]L*lMH",Q+]U$+ޓ M{}/)mS{sQ B#MlEl/'wL/ <PdJX;|ԯKTqW@@@&{g:j4 ܼ jIFJ#/#J~)C"eɋE7텪BLj(/15U}T-H}?0TΘNYfv4A?2DD1{ٰ>䏨J;y*= vd68;~dhRp<* ,ժ\yqVWwp܄dXʏqM r|l9$YO7LBQػDC8nAzN\)T8TN "&BɗR cfŞ8f2,Vu An'-A\0HrG @8C4GvL0ȡXi0ǐr 9+$`y3ųuVxֲlT‹ldz4gz8}WY!sWPs['65WSHXH~bSH4%\٧u @}/*S\d6T+x(?.JVOwqs2UWQ!r 2,޹=k R>/TRtO`!}`du9IY޳k%ZoFSOoQRV poYkr_q0Á!ƶ7ط`q+(Uñˡqt[Mg۫=+D?$B gI(]=lB(^cV$l+"HpafwI+g;"@/p,jޛE˽i*ď(ʊ)sY>'N3#OicQsl7c<|KP9QIQicD B/j07HQ ͣza<$D4{~sq_Q`PAJC$H j+ [*~`-9VԹ%N/THqzc=VD D)sh)g Pe o ,agu#LЊ`է[G0ZVd0-(ԷާFfs b_o(5[5oB6&ӈP=C 3H!?4u@7B8)iG?E;"*iNtOn]E^E^/8h vY9rR$?0 ,Y3Xދ#olj&\/V-G+(?h[_<(r@y}K8u7BxPԵ5; D}BjoA69z%>5f !"`6@KJ&ꌒu\v &% H47XIXjU/Q$=[YcCQlXҗ278P_-Y7`0<ė|/N|O̠o89Pt%ґj<$:KHk'c%9Pts@M7X3TqX)qZo%]^_T 2.Q g@תpIVl7-GF9[BkاR">[>䁨[n+ְDvg 8PO# I)dӾtoWn ~tNvHitjX@96n>I~DU6Wq2@/ bhk/|zžsN%0Mc{Aq5ϣdC?Ơd{Ho9,C|;V ߂z{ci|ʤ l+)dۺZvǏl*$^,2;:10eb4P׹;EeP+b(^7^* Q3׋0@A! & wŀd2OOKtp+oσ]ʬdkˈ`Z (;GO>9C`'I|z=wyW=KY \ lGO6Ez7a+N`5gֆSk.$-SH Jzbq7zR6Ɵ0žZVҥ |}5RO{`H&#^<97Y:5Db@hO<}@$[Eʬ춓i*J@;Ҡ [!OSfTHp9 Zжp˟9.: U\(.8a!pH,9#,u3 Jl4U/6Ql<Z糛iɄc 1载cCBZ7[$gs}z%~!۸1-1ߑN/f\Jc&Gn?a4W_oږ&"I4Gs뽶d?ܪ:P"Wx YNCȐ0*g>5esU^: ā|r>k^xDÐ-a1ۼh8(2bi:c(̃o7m`Ha'8? GHA^15atMn%F7] `(-Oҙ YxRY,bӉ!\hvl|E1n?4 O@feZ2s?=jTn0z~tˠ|dk@ƴ{6 t%a)qF?y1ɰ @촗nb@K7D.Z+oFDR^|)͵ 1FsZt -&4t[<mFS*h "H__6(?^hS9Y=C7}|^8`pb|u[PؠmʵȪk^ 7)@y?8oD68}6>nCZ .8*-`])|D(̡0t23,.d5ʇ/Z <ۦTΚcj'[am}EeVa5on5Mo61Te& ˰~9%@1M߇UH?٘eJdU70mOM/͛OO㗸iZ[?57ѝA W^HJOg߬a ҙgH+] }Ϛ^6\(kUMu%2r'Ȣ~q[tlj\  U>6h]kݑ#O1j]O*60[\/g7ٵ(Z#gz 1-zEN4|aer>g5π#+ӷǬ'5DT|XZw5;A-0Dn%S'[4ŠfE>( 뛸[T0d9sxo̵|;!+NH;.lczxF7ba0' Չ0r{ocK )Dt:j^ӝq-:$gXfO5BRB<]<3QN#MU$Xbr`c͈Ωfyz!·ec5!ʠ7 Q>nLĠs$kV- 3kX#kE;H圆 ARk|iV,>) Sp_uS#W_8zN9߱Ȳ^u{]{AƧg|~fRyĎ m%09XAC|ݑ3$Y4Ѿզt cCB:}6**/s/ۂ\"~(p0; ;{-$ZԒ-kK%kHnε>Ȱ5S%"5"V4hiiF^R(ѽ)UHX@/@o;=is}D!$!Vd×8PA1t* <;cEfnR@7˴p^Voa؞tq\Hr9RU $tA}y B%zɜBR3Y\AFB0Tig7Nں^qDM=ϋQhEe, ԲaWdzxS`杪LJ ubVc9]H2y0 *0j2,EhrhM7ޛa~$\CӴsW#Epk:Uj>05Wxp{&=X5AT;H;VS6ͷ%}xm af*?A!(De5aCs{B=]vmO%3yR >,Ӳ*}RUهn3f+W h=36蜑5C(J?\ݘ(1jF\O.dPjI7 pgHwWi`|P5yXebTmO~Q$J9,*A7&@gAѹh {kY(D%ZѫC~Sw~V?qNlys6A0s"> .$le+|2ܝefZH@ٮv%%xcg'f%^ _Y0LF[ëu-qqQgYM>2p ĉ8E9%df800iFe24mWaEkۆL71d< 6OQA0R f M3zCZ刃WE ]P0tnDZ04?$OF8ub2CFv傢 sV e3CpNѹ0Q#(mIY!V-hag>[N|8O*4l AjU:\fw#SY\/;U堕;;C_asޖ(ͦU\ [ԕ/J^VQ̮q/1cj'G35`=Mҍ':L'Gkƕrx#l> OS_Eg̫")SZL/d{Pf|b̌R 7ql>jc.="VgC\]Fop` utuX EĘ458{Zg q(06 *|#rn 968,u䤣4K8Io^ /r[_Ay.ԗRa:jB\w7W33L2)DhH4_۫9D_j^t4 SV҇$*%4"AyMf/+2EfIG5wMj|ïB]YS n)boȣ% 3-kXփ,,=3  4z"j- PaDcθ 3*qB 1DD21y9 чU=Û^?E;D1G'/(d $3dl`z!`wztOOE~ؚ"HL=@8-:a3]dd &4z,a\?>{0ц)M3ͯ,cq˓'otdDOW_@F+kU@+ 4mH߈eDK/3Xo:/uKG-p]O TfDF+b-B[m2; V]Vi]e}QpNcgv+3KԣJ<ҜRRv?J4ėR3Ūr Lf{`^n"1h^ĻMdn>68$LLR,<_G,G n@5y;Cs7,Rΰwc$0.rU1pZyz܈jn_os+}Ì1 mnCT JqBYU3/E)J3 `e''w_/ ~S$1ڴ7{zU6Y#g4!4/[k,}]$Jӏ],p 4c2Ǚ[yrI%*'<)1[7ʪ,rk:}*=3qV[[q2hvR2'nId TUq|Zd{A3|vni/U1'XFv?݂f AEQ;҆hu(E<30R\y5*$8Ph޸L& )kMQ2Kq{=+}.5YXM7ʬ|ui?-i߾k7qD sR=Ѧ;AiX|#6a T11?24w`ϱqyyqeJ]f[mEXc0cSfX&]_T\6}!K+<>6c1b}t*)M{s/וe&h;YOU>p/+1n%^Zt]9icj{>y0c}A= 9-qma2O ۫"ӅA8M2=6_=pI]y,0&㩆\hY.y.NjFnjz)Xᄾŀޭ0f(Dq6wQ6Fvފ'ļ t9G6r!Fat#NQOS&ޅ-ׁ,F >đi@17.iӠz`)OaC%)Xcfe/:[hzLu28*G#^O$yW`Ɯ؉<*`lp^!YC6֖sQ*yz=* j[RiA(廁 ʙH@= UibSTuJ]ze+Ӛd_X<iI:QƸO^L?Qx -ɟR:0k8]v^ȼ~`q`V{mLckICPh}HℬyvJ iv~T/%T`%x_?+b.OE2\hegac aSrE$#g4 AHcWa yJv?~H-(Ũ"-!Adpsͯ˵@OVAEpvL\Ajiɂ2)4HG>فN;&L0^g'K 먯 Ή]}fnZݔ]CoT z-m7 xG2D+ϹsN>Yz2"d_r|€!ea c6c+ٙٛPyIWQl@C5'E7 Rt8J-3"—j֞EHj1 n=m}Ϳݜ]QqO26YgTҷi|!^ 0U%Ϥz wɁOʢZ2K@˅/C'[C2:w~o*c^ŵS(44ul(IV@]K :;XAo"1W vb ]ʼnĿd* kIcI 'uvCnh@܏7?w]u!]v..vh!"N@gh1BVqbQ܁%:#s?\i|m%Y<ҖQ̩ Ѹ܌]eKtD i2)VqۈIᄇer=ZohWAnk<+MIq %ܞ$Y4$T" **8k~X?}# hO}_B1-`' \r,JPߺw-R")w%YSH v{uaHbDϿI<̳hGVlM2v~x G;w6w"tڧE; Z]1g_[R>$JMV$8ςK i&[͸{R`&농 룋.[!=ww3 Qʆ,I={ck'_OET5-H5MWcow<ɏ+4~ v"?f!xs0C*WI4˫9bHU?fGjb@,źEO]@ ݱTL+Vv:0}4 Y6A#BF j#Ua2+M+\W)Rբ0Jja w_1) J)Ćس2W*."Qp= ˥=M"i9V`-Kr,;]\ڼ wu\k Pz$cv|h$/\ &\=}A@,ۦ1 "XIZIsO腉Dco,d g,|}^d81c{dٷBYp渋{ߗt`Hõ2S/x}P',G,UwI6S"OU_eS+6cpGAA+S%C%T"FU\b'k,IY 9"Rα%m8i ҥyul#6$ڌ-m!{2|2-bB$ď$*LD-:CK0eErDpI|3 d4B/UV{o?VD5|a6V3I..0FJc RPb? x0v"7㱯aUzjy7 FFYPC.+"e Y7t` `c!"fJ[30vx 'E-0@ͨC"oZ&~A8cRZuƴwqXd,2j}ұ~=K_q[OMƽ1 4~G|p?PS0aB.].]nJdŔD3Y}KY")#V/4dݶJ Rw,TwmoPU_c}M©L=b&Q?`0V?ڪ6͠-Obu1]MPPV-%uq2+C>f*;E2+߸N{)g%JM¨-XpEGM[_YMpT!?XTXț_%{:qSYn]P2H4 )$1 K@$5F@ XJEDس]o],^gDOV[#U gqxS3tN{/fka7j/jwQa,IA)دK*X I".t꿅$!7 2Viq2%/*>XI_9|9)K?zYOtQoz2V&ș`Kn{wzVy#ϙ0ti"Yn,q ^MJ *޴(w%q,YZD 1U=5|؇TM+c!o{<ܫjᦋzava(. ~- <VAOPk= a"G,Nզ. <ŠLWh{JE6z`{UΧ}PL-ޖ?b$/9z7uޟ"|@3y {bB 1a:%fa`/#qi\iB$::IgK%TU#e^rPٺ_kD3s GL_PwZXT-V 68AM` j>;yH,W`cec3 Gn&ш˫&.E "@&78=$O4A`g1Wb+qx{"!cxV8̹8{妤 uZ87s|I"K˫_O1%|2\^b~#b^ԋrxr:J3q34ב!sHy_TqZ!k5@Q"<#li׹N$h3aCPaV瓱3۰OSn+9 >>UDl|s|113U\CnzBXux;qҤ@J;_oMcgbq' , (YPpbf2+t_yIڦ*ZzJpl,U侕\ Œ}+ĸqmzK0 nSuOTPJ*h`AW:4sjHYMaPc/w}h_"Gs&WDPUJm~X<\ Vh|-O CX}~*,J֊rG/)5GnPa&hAkKoM{kD[XR}fS"%9i`7>+ULe6?zb/P@#Wjѓ@6r戋(`86E^81øӪ~Hm9bl2$@dwwW\Ik6C2W/WrV)jd|%!c^3Hz B_6pGtJ4Mve_SmXv,bvjROl#›HêQ6`wmC&gxfHy(>Qf!Y0%wHT!d j;#x؏lØN>_CaIDwzyi )}4c25H6ypw;Ƭ:B2[;z 4a8GؿTR$ IT8 !HZ6t7V \qϢ{#/Q%.^lm C*{5jxLJG a 0J//6季k!/^b' xcgwb aS׹zͱ:3CdW+oٷyz`?';A! j#{; %4xrBN! 0%$orl1/Ѱ&W|;uϥxڍ.d.t4Ї@7lXh$XLm1P|FxDՙۦaɃ8ٛyeΓ ;a^Э6lS?> owW,O"b UH'rEA~T䜁]|a)bQ~y 'LNIfΰ̌a9GnQndM`zǯ<9J`H"bLY?{Way-b 5teۤdq؃G5"׿af*`4ʭb O[q݌6r;sAB渑 D@5.o@rviDe|OȕK.[VFH3{4om/LȔ!IFyޕ L}U;am_Y[,[挠%x$S38Gz}]R'WlүȎUTGr%_#SlWl#P͌Da$^$gAӷoҼ7VeFU;TdRZfӋK>s-T?9c/Ƥ~n^ ˞p {Oj_Od>?7\,*k6 Eur3vR\;E! (D&>+_zĵS-WO̊R,L58=XͻP[Z¿ 6B#*Q Z^O>˓v@Imjn(~~Uj3Ke zCRU%최m"16 o()(g_!.!4n%D 5m{a`Bgh@ SO/zu{|YU٭W.Y;\C '񽠹N4MgsM{Ÿ.%fJ iu 50'\rre Qw ˴%X̀"4c2uQk_DaELNr!! :OI-]Xf5G! E)֌pD$Yۑ,v"t#uq@22BRDehVV#/nfh9 ( !_ԥx1?#v/P< 6FyvXف$ǰSΔ5eN_]3„5'rf[bh#!Z~,B*Q5& [M$ 0~u\SK0ed(1/ =j=p0rtb!iQȽ3 2кX㬥>~ L#t^׷? prMзG_J+⭏&h d SYSZ֯ߧ֋lRsO)MT~v=`C"J# n5n)ԬЌ=59!N1˅$?R'lY1ހ[C"h ❐ J,tZְ'g Jbx?2d ćp@_͋ʜ) d2 .[K(tBm#%sE,cQK|C@?f6ONx+$Pfٿ?⻥S91)9kr5c qEV޺]sx`2l/5:}n=_*]=jAN.{t}RlL5+taF_ɩn&WSd>{'Fv   pXB\9_GQrIUCM ' LMj^>㢂vZohn< <>eBy1 Cl%'ʐ6dh [.7(c]AO*P3ƨBkDrzeDy@G"$9%o C$+0݁:7k`zR}Aҳ0r4E#ܭlOaD1MٟLQ[#b%rʣrqqW*BkH>yL#syܢ?bBg'J}{R a^sZ+KT_\�^'JͨfU߿A~>gZE۶P\^25J= 6)Xbh[ hQ>POhY־EQ,23,sh Ytl[Q׊05#=adbh&Ƚ"v i1lЫ}$:ɑH絙ݷO,iBͼkB5϶nTO9kМ-!l0k>- C $LZ8R-gm_mB{xC`wj|@V8G"*2J Oh.{4]E!S. 9oX֢!uZr=mñ) 4?buF7xJ>o A<RʭU̙  77C\)bb񯁫1@Iڤ}s= 3Fa2K eH?V߼ o?? LӃCë)UavpX =\[BnX?Ɗ%23cP`s¤n7 MNw QA]7Z]dFX.$bp| LWZBgEڇe0 :ږ"'`\~QWbQtƚ1 m& ܪ?q`5) Wsk4#0DɆihpǛ٩HQ\Kk\fv+j,L+eO N& 0k%{gD2  !Fee kp(ZV)v_+l7A=BBݡkW/¡#2>N_ I,ݴ-e!K.3,oMkAAO|0kBKk9qlϛ`&Jy[ wyYcH5׍;mp%)U? qY쮢UlMf%Mv~_{JLH5$ 5d.FmO훲 @iE@bJ`ukԧKd @ۺgc_ eN${<6Nw999ų=C!2:QeC瑧7h.s23@w[fRyYb796u@>9yc.ʌrʄr-?5L\NT`^' B>=Kխ5ܚ Ă: 5 QNQd!p7F?A5 5F \xdؒ?8ꨯtg?tu-2% +`YV4dį qwǸtf70,iÿikBY%ҬoL֋d5dg#Lቭv"AVln>A WQmb$ 9tҴ|{݂oơZ_ 3 Ny7R[ 0fY Q]X>+),s[ p#1%}fB tw%i {koӫ)?ςY\\۴SO$ZÂ˼Yfl"#khe$jˋU<*9C܇+ӷ>+P4tDFxm!rjs@ew\D!2;QZˮ9DbOd_QsvUq}e wYxck&ɨ4E'XWA>S2HL!*h5E[뙹k2rvq~1.%qJ"gNšǤ:ӝ?PŸ >3\[jS_NN(?:몍PGjKtg=o'z26@^4V."x(x*^o gH=.B̥htƒ1wT'Ȇ(2[)86:jgZ[a%YI<~YOSo/ngSzc&;,geT dRր )N!`15'CTH8qdTzNG=AKDf\7~?7/﫻he=h!oA6'TDfrm &v0p./ ϯ{z\Z2&^ C"41]'r tqғ'IoߌBYr̳.#sc2G 7="ӟ YS}{@EѪ |60C+ԉۓ~@\3õ/9ƍsöwkfd Qnl ^/Y7W 7%+loɅ|_v.Mу>{{G6b;)I@=/CilpC6lD8urN)/;9c`>w Ubs4fs୼o>v.jvy)V;Aiin7Dmx_"z) y-,-$^ߣ'꯼MޫĴ1 Gʯ >}-;w6/GɡbW̖|l;pyLoP4_r\DGM$\*Ȳp18z_36␭8hvyZAAyܻn?0b\ J.\JձpRw'A#IZfpܠ]-U!,E6v/,*ƒ Ǒ{{;6Fzǁ)jm急EW  \#^OگǨk4Fmd'H.O8t·σo\+!*iA@7Wmq)*έ [i 谍o~}˸}T1h mn]fu}pp6Eؘ_'Sn;lX ~޽ }Ir鄧GSG}3f]98Nj0URq.n?NFUDCKt>(Y^=dt]z VۼK*Lsk|bLVp69D,Jo㗖,$ȫTZV8~@CJHbw.ϱZ!?lEj%[AW˂' \cef-cȍ>dS+VwL$y3B/HρKNE_l{Z0 pWa_f' ܕ '6CEt'4UxR@/ir 5! Q=bam*l7Fc?`@fwZ-zI { B(8R\}W\j~pڗ(k0Em~>>p8blW_Xn䚭` ) 'JT6SO]g] . ?ȉDXfYyVcL6b܀ΕWHL rV2tt*iYukl U ^]y.QZfE]q\z1H8"n#i OHQ5ڢZ@+f铀UKnG!6IX%d+d׳,N폜GX\3 wɘ_izD=^-f-=Avatn"˯oyj̤9m꯼.2; 伴ƧRFmbky=FⓦԽ;]9т{<i46-0Vi"%lvVԸ3܄ XρGb64.l>8Rzb?CjcʑBf2!:J='[4~N!$ <5t4O[|!V/7D\6$Sl38( n@iU<@;jMnd~Q FźyjER~.Qy fm4ftuM|@6 a9J3-.n w!C#ܚPe.@K[?R0Ȫ.1Qk{Z~#8 3ϨdJ{~ 5p4ȊW%Xy!+9}jyNV8&zrVǭ:+0K}yiW1eS`D T,m BF&U ၾ:ܟ{dtRqQeW:O*<OUUj8@IY,hzXb䋌rC\8ToJ$iQW`W=qN K_~ m ~h*yHOXx}slaƴB åBq6l(1!TXjT0y4w{4=ozZvm;Jt[fPJ8gn4?);`SIP|0>/Kshpe N&˦$Rv3Huzd/#o*ivy3Yٽ(-Gū DMƯyE)_n"e?(yR*DFxH3\fgy$9xV)@u!@ofy_mfA;4f*w2Vwդ/9"rsvmX1^C{ dX{`!n @em˳p%[ٙvf{Ga zp^ u^Gd(xfUL%j*LJY-U|B&Z/Ѯ[!6?N双,aiYN*;Zˎk($YP\Sv| :3yOA9711]5P2ǿ.:$K%[2Jݧfrwm+=saƖ{^ǖ- d7 p|_y0 a4`[,Na@PRP)5sԼ##%]3o> >ُ8Xs eu)˶F8I:m RTLTr-2>p dߕsHμ}[۰σ܊-s>W%g:Uddq4Rw 2odɭ`3ďWimȬLFz/?ԒOs3 FG^ ;Ҹ &$I_w$u'SBF'ERiؠES{οS %+rMהfƒd~Rl8BhEi$iOqT jQ K ALʠ60§y08;n$~BA' 1q9SDPc?V14;o i B;N:Weka&vg%i`LܢΠd*ϳOY*%,ΓYչm  +3ܰdZ`…,C3w:=> >wȰvlh0AӺ&#?f. {zNTEΊI1_]wdhcn;ÌOð^4sf=Q>@>O"gj jW}M};^jIꎙ̲VFZ wJ_$G+qBl `Q ]RGT9Z|/W|k *dfwՋPt:"P՟b.E mPr\ж6җ+OUPx?3mjq:V[]ȖoKOW{61RA|?L%r7CoHB灳 OZIeڮg\p˦,#i\NG[i$ rH hg]g FdNH䴘v@ S;WZOI21$8V1L^ݣ5|W~@.ἄcݚXuQ9ʹV롗oS0Վ9['9 >*}R95ы%h5r{i_@*n%'էTR:'gdi?x'_MhYZ>ӵ$zx0+]˳Ń n8g2g8-aArsb۞K+z,Μ^vTbHOm)x]8bQ[hӜ$Q;W+/^3"CSNLAtt!{YMy]eukFP4@FOKٽĵjXE'?-{'$bۼcfFlJ %z^%hHKϳjw9:|Y@t(@rY"U.k1ǩoNČ | x:ۺvSƱAg73޿#lȃcpPtKm.pIԴKZ'bTcO+gIE9tfB:yn"%dLaُkߌcs̱t Su4ޕ,0 փˑO BNɰq#O%_EYuqyǔEBuhg&-l=(c~Ll@*1Ft0W.Dq$/SzO_Co63-S 5î?fARB,n%l^V`fk=?慿 [rގ~؃!\58-]^]Z䧲 ckq\RѾIuBQ2q.YZw 0H^scl$8{ᳺ3]<)l>3fb@>yziG`leSM- o93KE*.x;cnf/@)_(yFm 0!tǑUhX~m}`&61,܍c[VKCGlQ`Z7ҤELxm̢ ;Z#yѼ4Yk90{Uoq N.J2H,ܻcIR̓BM?Ə,A*{z$h $ԀgP?uOr\_$ͫN޴@EEFo׌oJjZHJ6?,ŇvW e[pw<)P-ВZZrGiv#TmsK'(%5,̪f-H᯷45-%Zg;)?A-B,ځ\jȂdߓ(#WW/T%/[v짌1|-qnUqj: '*( I#H"N!©o&#:LYLd#LPk+&*he7lg@D1]Nml z_H3Ԕ^l#T~2o@yP?EߝE迋 2{ƪ_im  ty+XLr :K 'C?۟_VeLJz126X*Xz2Q-"gš-uϝ# iC]#vZdTQ{geKj"KD;1n $7[@2i::+52|@Ru)m9"q>Za]v"u{BǨ4Oǟ[TNj& rVflX+ w > P?pkNRr 0}ԙ^rTGR 8Vk4t1֫vTsE &?:nP,(LꍋAOlRy>,<'ց}B!V{]A*U 7^1w+2QQ:|-_gMhhT:E:GIkƕN4@J̎E6t""us :{w= 'Ffg_ꚍ'o+7& iD MLEګJwDtW>L88qA/V+) 뵚C#ʣ8oC%s( -/]{f& ^W iANfҞ1mǙ$e"|9mt-k'-T ME>NJ2]yǏÎq+xXM玗ӇoIJE7xS:3GEsU67+'"cDW:].Ņ:U>ŜMIr?{QK #94'\qbHw&9KZԏvؿ^fmORSS06x5PV\;5PD ᛩwW[5z5.)p䠐XE\=U:@_i >wfH O+M(gXTY ٥$ޖ ƵХfQa]9~Dp%q{ѱ$/ ]"o( oq'EKkf98VU2L._ƕԹ=~=kDG!B qjZBu@ڛHKO"T'9O*&Քjt+ $a*9<%^aEϝTM` jouU0䲮g q/yuU)eѻֳ/(HBw ~!U5bE&$`<-#vM*"jg-pG5]V++xjtZloJ#]7,"Ƨ`f 0i}R^Ӣ57Xvϐ -,T49졌IDdLnT^Q_La/{ LKBՋțxiOO%w D;d+{41FSl hR.~2:PRimJ}y Hi(< A2ЇVj ufW4wAg%(p R>XԀW,_F`g}VQ91Ɖ̰=5t3h$ n%ŪSΉ1?b}>H9؝Bԣ[){p n:k b]v:oޖTD)C,ֵJ`ޑrA,9os[y]t$|FIW>úixor:FGÂ&OA8ÔȠZMߐX:`缓+#X/sN'FqO*\ Zgᇒ, [\gExt}BV \*Y|7nԗd3qExT7:ƍ=ls}ew;D◌hI2s] Qok1VG3vX+M :C^ǰ0o%˩kDCUN4MiĐ[$ |~8|Q,] 9 :e+dG2efo,b͍!Ji';͖`[wy0WY+"<ܥ@m!x pkR8]-f[:{m;/lC|7z}UHw{L?=a^"쀑pfy OKX Pw9xkՙQa3GiB_dR),q6,,w~F\-Q^.x<0c+aeѷ @i:ٿYUO9 wJZK&cnt_k{p?$b|Au銗{hW7S nUh_L՗c](}XFE?⫄UqhrHciKEvslkVTxb?]-ИMmS[D%6&cR"cBHy2óȫG&Du5o3Eze6Y!w's e{@Ħuk$;d3ۙ\[)D#QW '=h'79]kvh;kſFН|)jE [?ʧCf6mJk N*9 xA53 C,z1xmAue]zOFB5=^[OO'?]*TFղ8u|0*P9]@% %%Xp%\BLK-}MvE@kC%]ƒz5?<:۫-$L?{{* dyK7 z/Y\YvCnI r!E˿ ϖ.DY%懩GG#F#Ԉ: CRCU q_[#9ps'H߰|Iqs97F6Gj}iyfOH.d{7QȎ}0ӿLwԹ_Y\b0~qD+~2@>1{T6ؖKqS0bqվs =>\lh\R\I@@)&`k)y^V0[=y !ntB-brSolsL9}볹(œC]@'q>nmZ';QbE?Y{j;^V?Nvyqj z|f?}3 K~<.512K!f1j2X_hnrYAD{zGq{v9~GD5WqXգZY 8QyG^\(߅`3ũ͕#։ΨnAQO* "v %ַ 0E%f{;ѥTMZc-LhOԓ==$KTAΙe8dJLR1ꥤ(.c`F,yZKDIrf 5VrrX3e]bh Uʨ_" ^Kյ: R_ǯ@l/Zs$+iu WW~WJKӂ;@0֓ PxT4D@Sr.o1 p>O47cJ:k8 ?Eqp&˄ d}S0nj :~G%U=%V>0(+0nxX)n9Q|ut- Jmn NID2d'ڽQ>Ф'!tn͉ /s%k}Ǯh5>84c-d!Az%6)dBTpvTE()qF!<ԧ3!bvᅨ7%+I6{&,h1ZO EȽ?M3cIb P&5J+wke0DՅҪ%ѓ $̻Gۿ( ,Zp'PSt'}6q^5}y6%ek3u3cn~ra Bɣy$33xڸOkoev5y* \F FJlr i/,=,'>}w;O?Ŏ8L@ײ0Hz}+zu:j@NWTl62mTa.// yHqif"#] =V-=9_bq cKV p=d:wR]Pp@iH{5yqg v>U֬xAk^}Kob"nzN@46uG*̂xOA}h(0>ȊH"pr|5Ntfk jZ[^+4Ie{FJX"}`^^u?L7YsxnJƛ} }/f5*X^ XxxƝW\)'v.A$щT!6߇eP&<1v^s0'/_cy;]켔+E}W Xp-aC-M)OԎ+2ae![U>+ME{u/=`dj*ݎcOF24,p Z2Ua2xIghx+3ҒrWWYoM "U]ghDp2b p9٥ɄVENc`=+ dyD]Y_nų$j ny)ڷQW&{k"&EGMm!ng (td~O6؟SXa?dk7mTkT0ٞ./G=`24ID*d|𚭚K@J >mhzI)+sNuh?.ԥڬ̩  [qx$=l{̐VPl4Y<,;tUUTqXdY'ȋ// UߥY f] .1#\f{@ז`@66 =I-u[Zs^)ٸ3kRQd"4H&O"(VF0~&Jm+h~.z~elGEԁֶ yLM;qoe@wD//HB&7o-^FܡtEV0r .#NcAPDM?9*cO Fڧ3A[*rb'Dc{W˴]4cv;1X:_D3Q g2+%o[)'x󵞊9̬yh2Z>Z)2A\U%7+ @v8@)O"L%œ#'DKE)dh*_Nl0ʒ;H'ŢdR֬!z\WA$AJc'-Lx]\DZem%D3*3t 72~.+=?i'HDg&7֜V~F|δNpEph]bX@ [K> lhPF)8M-2'}5vhTn裣h5^U  [p3~ҡ}3aH37!'-ٱY\ BIʳPu =Ĥju9gN6onlϑjgG s>n gge?_NxLA.sE{(;bys=Bq9Y1ѾiQm zCLs,Hk 딨AF#l bB/SiQEVa.ͦ)؇e4[|df dA`pVx&G"MW6 ^pXJ~]8- $3d %% v>j:L ͙؁hY_BIE4c`e@9:,^RW6 gXL=AxuF]Ő6˜a4}Ve3`GZ@*Շ<# ՔzJ<-q9L0ֈȧgê&EuY(ɋ`~IƷOJ'B;k)A1l*5+vtJr k˽OB"x~+A6^N*ИqeA56w>AGEbXq7͛ՎKzǦYqt)MvYaN1caqdQNc,fV~nՃX+w_;͛38[~+cGxB~#h z (l?BY:-A]Pfϰ ~5pj:Ռ4"u^kѯ 4N]?یfIYf?pv,CڻgOAE.r^Rk*şxę "e)& bܧ M.-y XqqTqEp_d`uYȞl) 2&K)[ppX1 \@u " 6E>/0{d{F0@Xw{ 'L'85CO1u>cK^P|8b-cۻ|Wb{c|g6F~©<#LcMKK5PR$ђ?(֗T3GS)ݒmly=u NNV9r֯ UD rĞw YTcpSghڼq!(@_<YhT23}Th1: 7 ?!Orme|MZ:V1n? /LE+h ")Sh%;o6mmG]S> GZEcDϜ4ӝ,rT栠bY6ZVS$ }uDn\JVt^&\og Öќt/'d_v4>ro]Ԣ{u/@*I,/{ db,4'wh'$G;aZW2&`ܶ?џΏeWV $p#8M2fle`|lutV{v:{Rȶ@#C+\߄d8)1<˦pcQ^Pv%dlkoR6kr(g H-*Zng iHiпu@$OiHA݊Sx8!#﹭ :OZP'Bp/h6^ʬ|m-S~jp}x[8 92nbz@ DxgBU]ºs {\sv,+]은֙t!"<\ Yq|yW䎔4)2Ҩs 󢦓u6hO"B )=xC鹅>kp,̊ .*=1nOb7q497Sw| iD儴t֓wo0][YQT^P#V3GHjfO:0}Qi=H}t`l4W7:9I"ݡ ;wJoxPV- 7ĕx׋8N?VY`" eTqaÐgL fOVE4[]#[SRC%&tXE.Vlxe"4R]Gs55]l,;{_*/r\/Jv@JD(2s6) 71K=d SUj,yףcPXK&Sܼ/[]p[Eb:F# ?;,IRyUm6N8t.>;险=7x4#e~(z[(=/ *:V_ B6Ex҆6@+`0>B[N1zˇ˪~Ikuj1gq/w\w.*aq!i9̥IMZbw2ݟ1q E^7y0UzULQ>\<\#=x~룵Ix .j_B: GaB{Bƞ;ܑ8q v 5Y._P\`"& jp3 F{1 ,qtA7+Ȝ  0: YYn~U92g+CpuDXR6[|1JEbki+``>k/\tq_+٧=_`/) ?][JgIC:r);.B8Fr:EdM~5D_w}6~m[r$HbcbՍCK,7ڻ;G·M^jk݆ȱY,y..u5B:-BlMlBXdkdW[ۀyoyG՚)5p\ ^v`iL&-p_TK"OyOc-=Q'FT}V1o Pb7 ɬGQ- LRvXTF%$j 鲦 _кLOFY8,iVNDƹ[S\ h*^>*Sm|h G+RBypEәw}yXU-Y)2fH^tcDs% vKf+?Ma)w)E-)9y]T Q|f~p]ZRЍB]yLR^i~ ? .ˁ,VʄCDSn5-Os~"|^$tL>qdJҙq<7#hk5}O U/r S 'offrG:羄8T ۸/xrV8E5d"nѶi _%* )GU#vL?h; " LH9Wuz,z.2x ~zZwO؍GPUt%* o_1HC\#%LjVv+J7'-ZEk rE (C)kn#VnknZNW'[;Fz-u0;ޏHouk1m5R6s6K&{Y$(8kTr)2 ɉQ+jvpXwf@/.j|bc%滢,8uѣ  [(Yzb{]߁++ۭ?դphnDDu=?YƻK.)z/G ߆H[TT1i)GS4niccFjx2*_ rJ&&Kj27 Q1k.YOzg-)3Mj{O75hWxo[$X㟵ީo6%ѸxZntIoP)z}V"/V4ۣGeVpylx5YS8s Tܝh3"0nvB&)k':%hwh/MOeNqV1N4gхԌI)Ԫg\y"ZM:Bw;h-uXQ73?",­Ϝ"$Ƶw!p4FeeZiU~hDc7ojF3i\]A 2O~rLv SQJ^42^Ӷ^^KxJ+*4YlX oIʟ{ljEJ_N0ƥz骍]Ơ ~9[_%~*Co'$]aA lb{?r#im,p讗,sW5_;AݝU<5OE. qüs獫3c|K.eрTvcpOudur%停cX3&<m$ǧf% ]_XҨ(~U> V.)ݠ&@ޖQwC 8Y(kښ[McE7̎X_۔ZX2WrHyk+:ĐЁyX .q9 )}URwf\IJ/ID6ridFNuR P( dm4U_m[2]$PPo6mjq%@5Y, xxQ.CD49=2La=_/g'L ĩӵ'_|}ei {!ṁi01SswMNн󬖅J6Z's\7ԵԻ>%<M% 9M E[X;0#h->pIMD4"=U'uw=u`e_`m;[2dMKaZJ#s`k\Kp4 2 *9gof:0!7w5A'Hd6j(l4Mqεy|>T"xJN@(Vl|w>^9~NT\`dn^ .s&U_W"vNi+yܹ J +Zey)9~5`廣t68K:"@vq=>foz}A誨]utB@܎pXg$bس %֠ G"\K2Dm|Q0; t 3f33BSPQR9їcuάA:udVR"'3zԅn/#5pޱ(׊#pbZƃB `1G51Ѝ5?WcbOw凳@D6gDK_4u9J9lQS^-ǣ9RajwZE-uU%+*࿞WCVa /t?f|e]J!7;reC[[%`g+&n;t;Ev6+ W5w\rrli2%:-"ЙL<#I×3Ur#k&s Jnֆk$*8N= b&+?$Վu6.0]x }xcW j*։M0sYk*֯bD0X8DCJ;c}^\h/.Sۀ{uzjrZ +H5 tTգnjc˻)7^tIfAo+Ͱ$,5͗2JeK<Ԋ>ڇqTuN ۍZ~vauU'=lDEuQ [$NTS-T_!uqr>IC(f ,B6+" :\wIɣ>lak䥼SZha,db 8a~EYi}̅5zAFkyA9Ꜫ2 fVR*P 1Ď=JstjY^“?׳=\rμ0͗)9PrOR u Vp}% D9`}d-otIO^^ ¸ g2mѠ_I5`CA*s}eT̳شҷ}]}>PC4kfkpX,iŔ›\JY0;'!tgIu\=lX˯V1Xև ig =8^w<{ xZ!nq8^0FwF46;CoOYNH[F*`,D4}uC,/=R|V˽;ʣ@RS?,xjBmxBW#zʋdf\G\ *HsvA Ef؞,~KwJpN %;.߆)">oBu dNg.P}]m-|z= C7jC=C Zшlv@d,4Uaz{ sp\^! miRd 'թ:}_#rӃً6N }"_-zC qD&hZ\>oW][Jwqy6꽏y%3PTTIXZTc)c~V[HTǡ 푋R馢e g3*(WbNRB_g%- }@ka~YЯn ]iң 4Rrpk.K9X|P1i%)Pu,1ߣ^^y3R[Z Ճ^z0~V}A]~6B'kޅd@SũئЬ6#spaNWt6nY0b=[> 17_$}_7uaU}J\2 ܧh/ tgZ&1 ]nN,&c jZN{^c6*)="en>bbns9tƙLӔ5P (p׬_AfUgH5WQ@9\+9B*K@O&Y.F/{Tx^lǮuZ!M!pVݹ1W=z"˲{Ut7HB@ek [g ǚ="H#g{"L>Q]ߝ)Lr 3DGI$G5sdg^J}EPK?uz(}gy]M?,>Bm P-rbCljJDn^e+nJ\,1hp|V;?Y]]RN˴v/SgZDVi@-aülM gsgo~{MuZ7I k=eVc̗_!S d򵰉ꭸm i\A FGic|C˱3I?LV3yu]U0 ͚;M$5L)C:}щ7zc)7o]Li twm:p@)K{3!;Pp!+:bdđhK&sn jv}onls-$9}>vexhS("B}:Oj뺸EG,Cy Zl|/IB+RsVęeӫjp&Ld"23WopuL4 mO?UQ-)`;^a`sz[@L-'}| )2r۞3W,.1^^XaMU ~i۹<ř@D ݖl^+(ȳ=V243lakU2 8Ak9P}b:{OIkwgTґGhVr{ms9%:/g|#5 I܍`B˴QWI%^:k2\vs)ZcxZ=YX6YFLL )A]fc4!…Vo]¤m.rPhN/ ]m:UL̫KZb P9)3|8!X^%+8oVI _uJ0{|{]9'L >bUCq~sJ$zgCcIR8B28zJM+?ְG.&('8ZARl _.}xÝhXރ6 E7**ѻ#PasfkCpC$l[[0[ǖƹZ^H=&كO\F*Ⱦ?6(tYUӅK[Q>n!/e@u$k{=H3+3=𜠟`W6Mci: Wk.xg:U/&e8chqc:ItlrGپlJd [o~K5EFRm#q g#',/dB }ZB'A K6(+l]PNea:.u& D=#ZJIDνJQC6c'Iü1N)(0z<[_W%ٸ~^ihI~ @[L1+uGaJҎApoxFE猲}auVe-1R!0zf)A!kr6~edY&cDjM!҃tY~ U/KHX:R?r'`lp0Qj}$Ɵ#.-s3tR"hF0e5&ݖ~j\EW ȟZqc<-CXyD-Y bdL8dn˜a[bb {׉PIԗ)]vcPWCXb^<%\~vBP[|J? 4&]ڱJ> 406\[ϘLo 㨈 ԆLL&_>)_ߟ+XʞujP%aw5?FGNp$9ߒO6gRK"Z +)5=GL^5[\j0(%q9*$):<`kQY엢WC} ҒAU=B{])u8J_`6ê '¿V 5}?&+C'@*Ub}et-L{~Qzh2/<;փdvSvKz\R&3mJF:T:rl,o_:o?\l\+Ϧ:Oh貯D/sjd?LDK?PMcFf"I ⿫ӱ]|ǐ%biCWZ٠ϼK tnzfɥˁ-vNwqƅ;M8LexW젗zNU<0ZHzFՎX&>h+Yj8h@=<(L9Hb>\y8N͍S٪l<< "%+V5Wc3%f4ma{ Rר\aa8[T* !78=W ;jYL <('Z˸GM恥@'6\N'Kvr<43Dwwb Kg أR}q)lfCUAcb|4fs,)Y(^<׎rgI+QX38nN Ƞn&h-({?7t)N 6!Ixw`3CfD+pe@ug8˴(EuH\Ͱx2ccܱA Z$cYČY/ a)̓ GQ&ɫ#[϶Ik}8DQȳۄ:˵`SKEO f~0uZlLs63d^^,f f"$|Ud};'#T*!JŃFt 4ĉV{ðWvy~;B³ iv 1&`j@}QPɬqpgHV9E: >d?]F6- %\I*dqfάWeJgOu)Khci4q0ƾ6]81 0g-n.׶]PjI'4?%rK;j_PdˆNRRF 0+D>h{& Pi²?uջD*q,LeJĹ'}"> g-[Έ6-$Z[Ī|} H7d,iHg6;SuxC܍1, =c3qHWyiK큕hmU?8h"Tp@ J)!f$%,$B'ѪݟT! 3ﯗnMO0v|1?Л繻L+NnM-Ts |CK;[]Xd|+_:4 MՏgERNpzEh\ ~tVW¤-ٓ~<5i95M׾"RkԚ 2,l=L^/':/e]I©-CȾ>o(n9>ewc5igTJNFcrlk]kx&$s#^L_p]p| wAVzLh􄀝) FGU3[l@'ʀy:xDW@>S~=,&J]uEFWYp}*T,_Wwi/ؔ_ ʸP}E\0}QJ0`p\4q Z€~h..EgIO6gzdB>lM'=jl+^' M%zb҄e>c:VDm(>n|薳9Kf㻚fe~4 ֪+>4!hU${d`^ƆA[S#f)Yh=WvEqY-4{*QFM.e nx0K0 ֦~NU8L`Ց2jym6k8oDWVVBy7~bmoG?XBBT+daq4e}Ɵ0/N pՠ5c黸H٤Қ4'|rz-T(?Ei󺮶[=H=Ysw@Ljgn01Yx8?v  i7*}yw {[]BD&`?3C6po3‚gns$wϣ#>[r g\ !-&jZ^odq) qU,lź.fiY:'`lB1TȹyJGQ)f?$\NP(zRn]4{}݄NJc\H"ܬӜ?vZ`K-Y](aMWNYPpT!m[K,L%GG )=ޚhqN *VtQNZT 3VS'`+VϚGOF yЋ8atQH(9PY5b^[Սa%$@•dF,Oٮ.h4yPtˠx鑠<g/"O( $ vp97}-n]p%NScJUT}Hk~-hT{ y i & 4U/ J]wYVQz&|7 zUC]-IU]^u-1)4㯊JG@Z $^=W6$okEI 1?xS` H1 R,Tе[o=-{%[ɝ5n]$-ƿX7s8"x5+I M]b2P,ڀ#*pOx2۲Fښ̀if{¾cD+JRDȎ;;аw16Qk7S^XK1AzW8q{Cr RنY)=tu1QAH:@S<3wGs![JU^̦ {BI;:EZ nEm- g&Il5gӭY7q rh?i,K^[.C"SK`mwvQqDW)2*jdBbd0 ۑ[ݛ` _![t6Qϲ75D6"\AV|@a*'H YRa9$,~b8.b%~ٯo }*c6*?t(i[oH&>OI& d1(> e98AI}:\=12einaf6"_RÕ9ŋ#+'pC"Q}hݝ/^ G ] u1o^@b)I,. A@#J ~kiP҃)z, #}7AǜM,,ږ8XaX5dȟRF@9,J*v;pk}[x\PMJ2o;tpρ,i_oOsvb\'űZ\m{ӵJ-#)>zR:m⌔ßn Td׼gVd\"V߉^/iƤ&Z=Ӄ(|YY- pCB nΠ٘j L۟lwQ%Qk"chr㋮c#9\ݡy8P}w I!)HDM@CHŒn\B[)vӽP̯trDnn5B4i Ip;B_,Uj%c$S"pHs:lwP{8. 3 PI&ݪwyEBe?Fd(b<ԯ:Dzi+;P%lIvHߠW#pOb<10HiB&Anay&H[~w/ق3C&B\QyP~2'݃+qROo5'݃g.5OS 0ӺrIoI"RͭI;L}[$꒪{cSɯL|o/>4loqlND+`Gk=N/0S&~R>xJS*Ծ$d H?hXTBݓfq&,XoxP2i3G[8Wu%kr} ^8@6-^9$cY] "~SҌ|Z=$FdBG)'oU=i"XxeXp,&"J40N@Pp>Qv*ԇeF,ť:-9] GSIQ \& fgNzd(%z>e '"]jqLUBw#FY}02MAY֧ӡ sl Ӈ=pPk{xQY>Xʉdƹ.'WVL(L{y%wh#iʃf1P̑@`/Չ.bda*ZKPt!Jϖ$Fz-ptO؂b{Xw/JFZ!bH;)qG⠆5(>,bqnݐ?x-Yc4Z 3İM]]!"n=8_lbiIBPq*X9- q1[{UݭT8R1);*3ޢܹEg+w`Hl[>9yf9$W/~ Nh˹J(|JF+"5ovK`ꙏue7txxJ#crW\["׸JmѱJb*{3/1Ҳ"/kټc;x6+_'5w`9O߅#b?[tM+gu,>^΄.hٵjf,kݮi0+ Ԏ +ޖhDSqz TIO$zH@O=XgtUvֺ>vzښֆ2MVT!(E1?PĬȭ%G,kt}e1eSCWR~^f( 췔AJp}urCe:FF#/[#ޫ~:uevHwN@t/ Ve8_ E~I|-}X;BS@t21[s5wT:nJl>;܊ 4EE&c1J[OE$ut:E\JWZЂ"ϩ,R2p?ewL !fHM,@R+<+myZK0Sdb_g.[% ?rϯD2`B|T4{i&W,J͒8m{(?  Ác]ݘL=֞FY7gh;fSJREӌ{ M'恭'xtsMЅ/"|eHɎj25|%QMA0LٝUZ,:U#P3,0yXEZuE&^wIj0#-! 4Pmҫ~IoIeC$7d-'Me7=auc~A+vP 0 ~ε-k`62>[Űߪ7~rD?B@%yԂx{#H0Aプ:*Z^I55*u՘Qfd%m0—%[4D(Dbh;b0ĩG+;Ư'4v;W20类 [>넓Y|pf"([|^N'9[Bd}TYH[~ K%B>Fy<`o&^ v=KX+dhxDϙɁk}^;_XD0تaD}~y@Pb bБډPF Y$cV[Blhᝌ. @986b6uKz'[ɣvhF{ј 5Q-#:_jATTJBb߾eI@Zi ^c՜i 3M/^i8 e/0'٣|Vf"D!$]RBp:jKn}(=="(|V=?1/M>UxlJ$޳i\(O VnWB 8ޔӚ%sTl VRnhb"\DcTӄpVy4 xO%,i_$)E![עɎDebLv?!^.l2p"wW*Ha66m^%d6􎬪ϔ$a±Hĥy?(722cD]֠qwDܖZcIc7/etb+F@ ~:Пtt?l]ZϜ%H!Đ7H }AO2ݲT[B/ 4}ljf ˜^HfjTbFd(ꗅȬ"Qd@<~,A&fNn +b}2!Z_owBƒbAД冨g0ҎJ1LoY*l9CɋF6P`?tѫfX:KQC?Svv0xk)f2,͗30pPqܦ#.F9 Uˡz8z, ہCy~ߠu˺3H. M e HKx Oͻm;kr~^l 俭6@.fHׇe@ 4˱.539W5z1k2٣zJw\آX&hujHz}TVȬ(@ HU2[bRn/4"GZիb2eBO@UQ/ 2#c ,NdY~Ȓ˓e$SZߥTl=ǿw4ٕ,n#w}8D,!tkSqCub~ صb 6(QP8XjI]nRgH'7 N+X/Jo,- VL۝*w~ʹB!F<zd<شrԹvh7."P= y!*<'5rJK YŲE2*j1O>oclm 5\b6@Ѥqĥ•4ru޾i=e h!ܓ 맨F׎՘nrzLVdSs~z7 `pmTyO% `HxlM9:x餤V ?PL3iߌ*: l?=hhPW?qw `PG_Jqˮi?y6]U^:mJܚ9܁uꌈBAW W>2aw t%XW?՟\`۸[lQ4nm~MȄ+=5JzM&T 1DFTu#@l#*[-Q 1M֘&u3Q􍤻9'0ģ %A>^ɰ ^Rh.kİ-T&ڀZl8=>JJr{i{Jof(l'?B t9$(!xa߮o^8Uw:^N(UWcWBy5~o4dF1"C3<h, @Ra f45FU=`n}+%㑹.`a,7QK[ԴRiSB^m8r}~FIڱ-\bᏲ#0dh(?іGqn|Jk0{bۯE[s>f&@rU(u{,SvPSXVOK%g 2`@r'QofWm93 L"*(w9N# s Qωr:;&9Q \ʺo(@/~J MrVR{T!A!-ݰ)6>UwE!DdWcZb=ݦ25)IHa 1YH )v|ufkXVq;m_YI.>š`ptЫCB5N*x"Ob,Os=Ut0R"w7 ̖x3*ҷ5~ ?`|DINg7v*ĒrJoYqZzIkЦ ;h ,1&h;)J<`sGbvRǒWZyR1jA$]wM3yqzr蝈±D75jXX.G*,ZTbd%dTB픺d*r]EN:73\.wl_yoB[w%#Ee+7 06W;J%c͕4<~gE KAE듶<|gFImݢG[nm[:qRʁ7 }h5jg_墒`ZQ*ƍ $ec,6wx4⊌}iЄXY=J(|T+aSJ_cqr4b 7r~y ¤\PmD+M]PN|60"ź`t kq Gf(ǿAiI9i'U02WM(g:$lI0i&Y})e  /˗slOt&d2@y;Oj1߇LE#:ESzfB3*9 s@U!*dT~LWNWF;Bib@U_rڭX".dV#|4Pɠo[M%{KtAr z Z m*uJR.ђfIuN6bָN]/ 1қZ-fR^AYd؏"{s䖈jH&~2OV5%7t-tmPh47$2:$d+EwB:[`2.2H~pk=*@]}0FHwaI[3uP"&sI Gwz&ïcl;&Q3ZʱHZ7 `x"!}j):J8Z),8y)+tPuY[IEXhDDD-6gN*/4ROSzTc/&dMELi" ,{.iƿg ۱Aѧ7 vm \j Zm-DZ֋n–ȎZ :gJLw{UᒗljX+f-U<%V\ Z-]阈츎KuL\sygD 1$CC`wQMEj48e3"+ɨ7zTYw$('04mfn!UItjJ Ԙ&3IaJ f݆D3,@0Ņˍ8B4{؛Qҹ?Fzdl{(Q5{d7M6@yڑBsƄ n@5nНda=V n;} :ǥUX AZ+ 1SERS}+=1r{ބYCPwUH:5,hfˆwIwIb 8C0X`N k:82&@`M U[}Ԏ-eٖz-Z:gb:ouxq]@ /[mmL/ev>,pjT=ǂځw%RoQI3pWw.w+4wdճ[=8T r:HYo)Tgs:c3.ZF[y'?m?:{4#3&wRWQ|h8ˋäP!֍Xz%{A}_e(P/X~U[|ݽ,\Gev pp!bc4Uj hc᱿~H=8K{aV@8kw1?XQ\e BEwR:& $TMV[zGWp7du+Xe>{#sᅱ )5ubCl"X bQm`T->[Y _ >m.L.o+`g}/oq 儝2HJ'-co3yP)o*I:VRyaB"JЭ˃-F<=?ĕ!?ᤚ?80(,/ 5ҁ,"^V".E9Uؒ]զשjTm@j g>圎T_A8d ,9|OX!`8:Ĭ.~>;,ثoF9S |I=u9%1E +,Qy.jKU؎-VDy(>]5ȉ/}N#6vSUWm0I~;lIiT&RA$"1ݮR6Bݔ]9^0g5Ps Z/6d䌂(c-Ax.;)XX l6oWJRυ Bn$hbԭjԣ%SBp#Qwp{aG:y߹b3?`JT(?TPHC5,q&}9Rx$bGo Z9&m?$L<t\û3 0ˢxt* Ed((Μ5ȤOwR([z-vdqWz6.gRǦ\Gq/^uODCP090}Y/Pn9'ڹP#nBlNZ8hMb[')ܩ~[ AD/'5/X:D?x@r Їɲ",e &ZzmE2k@d.Y P6Agԟ+NjOT 6ujvb3?˷ĩtW':Խ"!襒A|wRe\OsuP[+>k{JFz2)\>1f>?>g)ׇu+rGp+2I@bV`剡cO Dvpaca>S>W EkoNY[LrQ:7]nC_at֥"Yie5BlTzHƸXe+&T'e?Un4T)rgzVR*9/F{k\r|;_S7ϰymP>} @=)Р Jj\1uUsX콽5:”7є#7<8ocRbM@ Ñ|i{D#}u{].+6ݭAU߫Jv]x=&,OqM{20!m*?kzF߆6 Uphd\/@^i,[aB9B(nB3Q0:d=XG@IO^YWK7q2rج}SųK!סnn(b*O҃\zVMrEopJurȾ^V*CgDNuh}yu ~o6X ,"[[JpQk9ڵx#v ۸ #vEֹ6yt 5#4t6kIa:2(EJm@y Lx8j\˒8LBIlZAُ̖9/ rў}o83=UZl!C)M*(?SZrXElxjp`7=BWa[>Y[8Y'},j( ɍ k/%4JM|Y]lyE/\'5V?!Ax_ʷ>hpQZYe[E ژSNPI4Zy X cêG*in?Z+1Ub9SR6 s|z(Ci< U:~Loa |i0{' ǟ8o2(@6:@?EW^Å=,;Iӭeb7c0Bs /n'Aehܫ?{ X$j K7 }JFNBqKzM/tIٰ.DTaX#\X޽D\TD`b0>p«.]Ħ];0DRs&#h[uMX:RIد]K˓VNƨ/OKB 6 3E+% BT>+4f QQ#3rz$2D[G[X$9uӏ9 y n!-ӹ71 sdTisod,0f_eˌpivi.p%S½+ZT,,u A|]?xg3E.VѮ>LO7Nk\*rY'PTXyEsfVd1c=*c[o,KkX繑xz@Mܤ͢X_ڃ4ECA~F_M4s_Ymg4=xx/>-Sn: N1 5š市;sp0 aEɮloLcMպ/JXBo;d". M UgD cr^!L~~#4@cK6Z-5z!tT\2,"8Oҧv9C؝':3[p^dk\_VS6Gk!{;@9?b<"V&G~V~::OJija&`8bjTx Vdt>`wڧbI'lzv‚ Qx`7Nv  =Y}{XN\8\=czYHL>N&^z'ci>x"`=Z qw-<)GC"l})8^jl}՟KP!Vɠn?].Y(WPƝ֟azJYevY %&3;ٔ${8-1JH"Wh6Me;V޽K\ b``,76 xK\)EMg]g1jtG?1'-ךuҗ05SAf8GS7WHE5PÆlX]p||LJ"ljF&]t\" q+4twgao{*lc_b"HIʹ[lW`{{+扠slkЪWs*bW̋.zCXkpX#L5NR}biS|E@ /8 UzOHߞ}hp jKDŋD޾("Dw  RYX!S} H s;I'B"\"mfYɊVi 7B©L+mۼ19܄hs>Yr'4~<H.%Gb\<Au+0+1P0ƽfy1o3c]NQDrF̻$^a닗(+] Jޕ M|zTXl>³kYpQJC_'Ԝ!`A4΃yϣឡ4G݌KB7<yZ a5 LRt&\ &pQzuͺ=X LG3QlD40IՉ+M1]ى6, a)O@PaqU ]ɚ ,ůr|$NVM674G˙>؆@ W%z +G}.JĢ Dpe\`ΰK+#`+ m"lߪp2n:3SEae1Ią 4P94&?l?`TW EwxPkD#o CXV ̄f=ad+MU&"We)TKGU:寈Q'f+ª\*d\IIT,eB9[3"#䃞ևT"8ގ#Wе72ia40@zF\kPqEW{vtnl 9gUNú&dFOivé5[:?`ZsFaB-^U9۳]sc²3t q f ǗqJ \'h3g% ,P<̫:=~-D,bRo+&eؾjP(_3cmLr:g"x29V4BSorS()) V+ba}P@.F9x*)YFHk\>Wկ"['ċ29Rkc[UFsut\&$EDVx6^DTFe/Ȳ(irɿTkd+Q?u۩KźDYHΛUqV[k\ I 1ң#;LDd{Z۾ц?s%z[$"tN EIyB¡J#T?8.$猙w(h'+A`4[-QCeTPVԁ&:Ol FfS4WÛYT{e>j=@XYʽ^ Ȩ T($j͔_N^(@kIj[ndY8В*d6$^.M f[NeopG[z4We(hs'@ 3i<*xaR203֜>J'FC7PCZ*@$ \58 WToR\EA$0))Փ:<\MEҥ \q +ח>i0Ùmʧn)pnn}8:T5օ\Եm?~.[ A|f衍IFX]ƨ^_w]ܚuy$ ײԫynp0yܰ<+ktR`m| ԹY\AcݯAM+skV:}MK၇'.Y7fwl .(V=>J@ֿF #RIΕojm2NnL_Zn7_no(Rr6>WD<[N#?SȇVy{NR3RH(xHK }G+ȉH0dH4yΰsB)=$WAǰRA 5=gVg:hRu\&PK#"0ftwDܶ;nG/Rg'cw|=$鏋|ڛi|? v3kU;}#6.@6Z_2"+K\p=vSXO)W |_G A[eζzBB_?z6ly_ЎEa\vw(Z-:n{@TҌ %]8 (xrXbygAs܊A fWZ.K|bC$691 xaڸ*/fT IZ*3R7\/|Dگ&+]*U3j(WyZoy=mOQM-ͳ IUW̐(b4*uz{hw5'\2(t]nwjށfAoO^\E޽((v],r@㉁rfz0)?8>opCcs:*+3a'w9SUuT!%}tEEG9~˩݂yܲkbu_۽eJd!G;_tșUGih/nzr9#Z$?^F$76u)ը!$ %꿨jҴ9_wd=2w^h3,M+"Dء 6&ZwSk?aq`<K C"D  LDRR&xfdb6wd WCz+%ʡ71P`xDF:,ߞdu`H']txƱ$+V `F.ːL8 ^r]^cC.lH \T"i'1`0 DC:bqfa 'R+Opo\Yؖ_;"5!+шtgwêxRZ?Ioޭ=4YڋNt\^NGdB%6Na!:El,&4!.v ۯXG!]U06ڻBSR1W96)()ΒO7ᮨX6گb%ƚzyFUʓ<ڗ!^4OW CܳބD<ĥmrFLZ 麟8+ZfPn9C,-xDAsiWB/~E(1 7DۛB0ϥg/B %0wixmÞm>x5IzAQ?/,f @aLD.v#pa0۴Ja܊T{' j ko19ɏx)!Ea :Nf#1rw6(0Lb=~?jkpO.Īu)/2%Əte:{!  rW\ Xze 9铒! -F[HYls%]Eovmq[Ā8bEէD@|KÄzɡ%Mf%?Au[ӫC4IӴqz."s{(`;,dX779eE9 Z`TY88Pp-bgQh0EX<;,}&m2#߰HvЮݵ:+0u"tt)Zmu-d5kp8d `fh1rApM'roPW0vρ2cM^GC."0ĶHjFBBk-.(Usnz?MzVb (5RF|{8v6wyi}J!2v/x Ӡ f@O?(3Oa+SHR C{w*0PL%j^`_į`yD+kg1/jdB?,O>f-SmDmu]jq!mF˸7EWv !?Ius ,)}o(=½wb=VMoRO?UQ[\G A߉)c8ՊK_BzMD5O\'a)ǫrԼۘja0*JXߦw0μ2ε}?{Ă'ѝhYN ᄷ<83Wj*1eVTC-X.QGn. hDꢜQ&AOXbEvS>?Ӝܗn㴛 #c!C1(u|xڜRӚAgO,UPۄE |˖?JYnEBE׸b3z\'!"~㙹Xu4::09;^#rٽHj^LkpmkwC\hn.։:|b-]uS&X-|OܦhS5w(F >ǧ+iO$}O58*o0T4=?S!ZOZ})-%DƗ?nG=>ˏĮ21M01%pSb!AԷj@k2HLP,nX;U[MlPq< AcDN״Yc,|^Liu{ Y[PS6^.{1L Q{[( ЌIqLe?B yiBeBER381\h]tPIwVWbB?uv@l/̓w7}I7ua= ݪ|xܲFkߌY_<~ ZY7UG-69cgx5AKh]"GBPÊh(3k7=ån1qBsOxۛA!p0fXDtJk5Se˨nzEs7p2,Z|ɬzS UC;n_㰁GU-cd#,~5;ϡQyN>0T*J6\ "䂃%ˎJ*jFjiɂf&M%Mh%Ye\6_@|_4TEwv8 W]H tVїs 4m/FcȎ$l Y ) E2UpW pK ~g,fD4O_ЋRabY(ʴlFp'Sk4_-z=/N~X/$3 ؀iq4 c].z_q!?ǹ,xƦ/N;geaōsH~z.4;>ɇ,v,Le{ħ# n IpS]Y@y/ |I;y_%={4i_I}SJuAf ! zj PXM"zpYNؿ%x3$&лsXaeR˕G,3´ge꺻GH'~ ~qT"K#ˤo=>=LʋAXi˗1a3blɟ8*~!$AA-n0@DC~HExhF eRܰ>L,/6ZqD6K*Vwl^.*osUbr3JKQgs $:na`yl vgZ,%¨ey9{\sgS0R}{ ЛA8T+H T/Nu+=uʼMQm"UVzDVC3&,=}KVZɉ[pd+/T`Nˊ6./߾j}n-쫀)X*QȤ3Tv3[4Γ ɺԭjTg Z[j7 cTkE^kJSi3s3`~:dDpLQ'#~SS:TA}cfe^9]Y!CA(Ra󮀤[(֮C@=X c'XI }p.0SD~l)" X/\8FD։Ў`6z(%4Tm|إyRO 6>L45n-o=xvN⺴=< B;.HQ,3erP; }S5 ?Tm<aBV U?UQF%~Ir׬XEFc(Oh1v[`b2G}IHE% 4ݨADqX{p#d7 sߙu q.L <)G"GJ8/ӨT kwL\ ʏ0oIq$D#6 A&"@AEVʊdkP cjP XK|*@ h\ۡx8(fY ` U0J dxD{WZ_A ޶6^񬁤A_4f 51jlv6O 娇kr2AO+m;iXY̹ {`ЭW#01.Xe>>ݑyA|J]#^k69:17W+IO[]VmR iLDw)= ֶN_3{ F.zEqBn:'5N茂/ kB鸂.d^mC-pqW!jv @;5,"^mnSǔ;/Wv$\L@z6P߫٤w+Œ/h7iB@AE(g_*qC A^{>HOC, z;QAK|n[+RU:8l:ռUjڌcC"4uk^@K( 2{J!y_3,TWkqOT26,+R%H'k˼|Ѝw}z5lAn=S'KȕkGw+Qyb٬fya>9;6r#iD21D|{}J6e+·a7#P`BjpzG2@!Fi諀B\Ej;[i*Zጅi Czr瞙WlR+[H.b7qFU/j1$:B*2yaVrm 0d o]>B2`M Gmvyօey<;cB|{j_u -*Z̧:jz#}gJձUkS=UlE[ (wa.JsE([iyÝ,)Sq"{ynx΄{Y=C"x;(d+G2QjQ)>~3jW}a.F3tW}jPYt;g$>(BwscAFqܼѦ`s\x/\2R"|)u$-''8b.{aJ"3MgSSpRA22(fd=<0Q5eʱ}53[67\N Copgȳ 'U,s ʮ'B\QcaGߥI7*6r4(ZM# sҞmc4´Cl- jHӡqE shp7yJi/ rTzG/79T4`^ ?.^q$fxU T9m:ik b׬Gʒf0kuȍ?.HQXՁg?W Ȅ @^䉬ɘpz34;?¦v,977s!YKصEd5eSR{+)mG&E^H sHЎE@ OIڕd%tyj$oBX0:$"6azQ.)w5Xӝae ]o"I, Y!F5Lc-rViS,#E ViBM뤊@/ڤ(Nwyy|@@~VӖ}1;&F@9Dl[0rNM^MsaA ls5nd?ܤ-$71vbCQp qߵO3xʸe P@+_xk9&B^RTsybȒ6yz$_D %h1DN-#$>Mc 8ƟS\'lEb%$B]̇wsju/Ircʼn7</1r3McN5y=S!(xtξwsof_ GEoϗ`'4aʵ}.tZ#ُYF&Јev!Ј ۉ[_fֱk('<\^J4H?Ɇ@6=}T`ZDO/F]7; sT!{{2nJO 9)g@i+%f%ƈ6dʖjUF %%uȐ.9! oy {8af䂴AŔH-SOK^ȤdT!:TTTg{I J ]'L&p3 e)׽dM?=$6M ŲOcyܹodRdžɘ}'aUBR —& / IkPs2IADq =[UR,o3)7gSO![ \K{㬶a\Ɩgmm 8ͅ$ϯPh8*dxVnz^/[eJDSğj/M3f(U:D/3%t,-Mc8iA{7^z%O)?B7Ox9=$kx%oE~RBޠWKD Lj9<ܕ٫)Σ|dp9i \/ПE4 {?=99:w4g6efB/e^sA?`9N.,^ F1߈'Dy@^9O RjԂ#h mc`'):fsnNCgey7bZNe ຀$yCSqĜߵыvh V̆޶uɗU&TŧSO"$MRnjjxRwKND+triHj,o!X]%5S  3VTml4Mon}Pm.ݝpy5qʜR]+׻(c".ҷA/y-;Ǥ įCzZ8EpQ.t:6!Ȃ+@_tpIB$aTvײb6.:dZ=VW-_yZ]wXW du(öO^x3߮$ç*9}f# 4baO|zLCEsqPk?o )l&Kb jMtZ$,6apCt~Us_窷4H+0ճy!'C5ƟEr31N U' =+KWZ)H"9 ~4Z'C67 1B(@1PJ!m՝Z'9~/`FPk*|ӧd i$OEfp^/E(ϯ;yQ<4an0O*fGcf?(2/b9W.. ["5Y(YQ5nDryķE#Mz5o 野yQ2 Ip\I͐o57_66faZ%YZ }lJ(oN{B 5$;dnzLb- E+h]BO% I1=&DJ!|i3xb k42P=UNRTH W>glYs #qc `cP^ZN„&O"ѣv1DKnQ*cٴ~ 1Ck҅v muNa/{\[Or]gqXVo[ݫ绳UWJTW35!9&+s?#n91k_)ĮAj҆nP h8@EUquEd+l[sǾ}>UBec&G`Uj$:rNHa$G=<&)v6J(k >Q`QzpivB{f 6ܸw!]QoYJLg6Ic,&'*wElN$vϷ'h['DZjF4(E fGHvK b-R69T X)% a؏c;C_uۙa k2UT(@/'jÆu FԢ1RfQ -!)Zji6$g<3-%E pETc-C'[Fu)G ZexL1eGݲËCw.CܒT)npI3O7]3gޖRsrg'zUVxֳiGV 1z2Um禣)Nn&%BeSytm.NAO%uzG Vu e=~7~6uE+,1˜9 ̃(/emh"37︴,^Q?ş_g suB23ee#MƩUBScK>|Du=c.x{!wvTYÝ0ҕD¸YDw~MF]9^7ƋTv ~m  Tō+~gD߸.v/ XRD=mrOqŇ+nãz}\F/_ ~^>M2?*/Br+֎ǤüwwZju9(&+Źy:ѯc06ȉ `}1y4 Ԏ,j/WQDb;-wuyx k cnN9"XZLS䘆EV뫠f!1C3FpyD:}0@mNQ Զg]{@ˊ.L9C؅@kҔ~i>g5_zVf5Xe8o,J#ʠ! vqOl2'˘3K'͖_saZ.7wDLc45)  =? ~S c:)<Ywhä' Q0PNOM+΍H"ٽ[+y ݭ^_=6b=pJ1r#GOWH4P'Hchi[Ů%ڭ926 z:=) Dؒ=LQ([ V2G=#Q ej*DY[-'H/ MŴ#$6(ݜQ{B?ula1o~Gj/bi薙D97J0 TLfCDcg9A: TZœDU$ѶNz +,Ϡ3[3".(!گpa]#Cd'b(u@w+$LۂOB/zˤlʕ uV3`6IztJٟ`Wۤ;!m,̝7i$#g;{.b4KjM,O&0 ^ `T5Iڃ-*YX *yT&$,4vkR: 4Dc{h|uAx2S%HAAcOWmN+? P"Mr#!1=?S "t $*U?-%4~k/$uҵ Jo~`T$lB42旕γr>䖃~\IA"hSl ܃V&+V3]528>]vPfMƉJk4b 2378#}HX XӤDOlL+T@*wn͖܋8pMoԞh %U~l+4]puN;Wt́L>zT)n>sg|DŽ&菻z\Mğ[0ce$,)<-1]YT\͔Qxt6f ȋ}Q;2#*:[.ifnYA˘#*Z^=!ӫSNY 6FSD˜!9ffXڂ;z'L ޱ-Zs Xi,1Wrz miS}RQnr+pՏF*M`o:sŐbX"ߊl?-0_=@{ 7ij}Tv+{I"ĚХm +aҢpyN7h>\ һPqd9!ܖ]# 0얼2!jnzx3u".(4ګhPMAqsٖm 4E˜)jR}//Ҡ&_~:+|*Q%d}Yk~,mJ뭯ֹ&;?(=k|G׼Ir&;u k{fBs!k #BWنݝlhYs][@zNuXIK߬TD˛ ϢP ׷u;J!W"O]JI u@:O j}O~{ '$L9>{#Sy8MM#.: T+lu[&9!K|pɾ")슇ڹx&VA|hL˾¾4vsT$mKcw]eN~AP9M:MCXOWf A9aHOi)^,lim23?}^7b9zxG(x(dS˚Iέ8_0O%!Skr[#Q l٤J^E7?x9#/ 2,M'I<=c`~4O D"Z>uv w꼌j~Cv~[*ٟMᛷ%\r@㰏uM _J1=o{ L)^ ߼9>פ΃10+nCLG2؃UGǴBثZQj?K| Uk29e#ư&@dV=`-goHy( YvCZÍXBhCCi@{oY G#@="NWE5 R[TÌ D7 _>yg@L0w7LYn2lbOXb~^Kt/n1g{zi$ +cܣsVI6ppяxv._ýt)bLp^32H0 {D" u MTFoJ y{_$k"ֳ [˒W{VeM⸣>xZ :BуJa'.j(q_ q0.TG i <;({](G߁sD޻J,<(F)-Qy|G[¦1oa@ 4R?w dG s 1x Xԥ̓!NbMVoaZpSXR*J?L 4!q_ʔݞhtHhW]pv9FGcceU$a7"S:ٵ_VzԼjF;d.#yes f(UeyA 'g3JNBT& Y%Yq1}ă nF~ JD;Pm6'/UK5k&A}WVjzTn 9} ԭ#K gy,pNzFE95~I  ehdqdUsCS9i>2a\3[KwKm剽o33C\}M,%v%N2znJdj(qR[ I9([9&I5\3qx:|S6~$E֬Ro\VV$ku9YLi=1EBvl Kt?wi^٦L=.k=47mYute*jcAu6hjػ^e WR$) )Ot|CkiHzj}^Sz. % LL>D2XElG.jKAnM83|`ol>媥-2]lzhuP$y*?9~mW8zI΃g[#ѯ%MYx{N_ALTv:uoӥ+d#0Y`VRO3bE_JZ?TRΈ= Ѹ!;{b:p|95[CFfw&4x 'uLQ`vv5!$hPN`xAlq|KѾOI7͊zXGӧ<'Y}%֛k Y~ ${F;Ȏ%fqYX& *f-;7SHN9c.b/@veoLMfVBA]S *[2—E-j8&~i)ˎY7S6 y k QSur~n\nA=g6-ht kw_֭(Dӫ83`_#8_e ֈ/45|*n,>8[#Z? &o:1**%k41Fh_ńb=Uta8MioE:Rn.| #(4j\ J='yjHb2T{foٽFvyCUKҔ!#MX9 ?]^zbAD>mv4' 'U~b\D D%;Bò4SyȏIΙҜU0*~0ιoFb,-XC 25i]Gr[[Ls:wzLwi%D[P-X+_' OX $*ޜ49hLn] l^stRog5Uc&G\qqN$6:ЮgZ9!;}r4wTC?bMfrOÞrj 6]tt6(k8C| 5S'(|ٳZgB &Φ[}9)xCū1mVQl8㮞-/Cm&C+~sDQrir:QL@eȇ̵<|탥_C.LK:OjHo"~zoV0qkǞn`sPT *ˆmfL`O%a;}5~.v;s3_ ;C2Ơ T;ì:ch"*ip@ޜ ~[CO85[K'1O+wf{J q{ӴgveXu&c'ơ-)-sGI^QI#w"$Q1Mf2kVg =(o'iľ#9wP8a gppJ#GzSa I[|ҭ_)Hkn: 뽺B&F9qZ$d*7j#?(B%|0s% I|(\&e]Y]>|if[idhg*B@ +b;TW$vr 3"t9 /*ZZ+9[K! V|oN4LF>st1]l58~AGBM3RvF*0De ;K9U'b07);I7BŸ۾Y<=-$DQӆ  kt=C U.YWw<s` á!y5$6`zt?kZVk,x=MCp iEzfI#/vxŜf[^+53 u)=q4S FBQ_jM ySĞ3yZ2 +>󒅟y JLQ:#M0hQ{ضiv"j<K朅G2q0'|AxI5[9/MɡO O`Sr%'pB sm&Ck[DHnBH*Rut;o I#F؞O,֩7 ڦ&$lMkz&IL8OYk_vZ KnF=`9D[;6y+V8t{w,nbŧ5VS+nRa |'ZA.?Ȋ\rS0I8!3܍ϬCXڛO6[KQkjK[WoBƧ"*{!2=Fdkq"~ZS!xgn ;qvȶL.R%ZrDk/RF/Ve}Z*&붡5Va] mnB,z=Я93Q 餛g:/KJci[L&3{YD7о~+MžWĨ`D ^S s&י O"{!c֟Q_J[Jk#{kzXIۧg@Kݚ Ɛ-dpb[0G#-xAA^_8=j~N3$ xs-ۑ=#GhY!*2?[+%L`E rEgБ;+|M@D*ZvFFR_2rqIYC\u qM4C{ '+e&5k>/R>*e".ѫP* ]pZR6{m#} ξS[3A/7IJ;oU)-}/i82?_آ +c6&'yj5oQo(tSyѱrn/<j 9u)Q }PO$i?2~V76>G0Ĺ\(wKw@(G@X:Fl-]kҧKW$eaRo_4Ot$D#Ӽ~C2[W vQ˘+ET grO۵Qȇ0+1z|&,N{bopFo~u7;9RLIkiW=KGmNDTYGY^aBh(իI-\q"KˠC3*=5 Tφ<:Ob&:/M,"]L4~K rrj‹h5)uyL Ov-e0<c+Ips5z] q`~$eO200h!`+ztVwd=]qG]f,Xp`q'_`dA}5m.3%Mb>Ng}D9Cɋh_mW(ngrّ"3$g +𞄙3ti^}?Vl'9H1k9Ӥ)ALIuUV.0.d,H"MWCxظ:'e|uFjvCZʍjt05\ Q;)֟5WnJܟ5\ }{w:hrî_f5C:QBk^1N%:(_5@pO,qdJ+&PKFk;X<5qeeC u- SQxhק5}h ׾ޭP'hL>GdSFsbV2`c7Ywr hQ|^-mhby9,ϙ~<<˩"?Emu&`lxҖ"2/G`"P߲` f[SۙvB! Q^2%P$ŠwrpRYK̀%Cs*(idt5əig "4Cc{!y(k-#3$D0X#yy39&fly}ir !2Z/-<(- 25H*]ӈ-)e1@ (8%+ZwМ4P }$5r# ]ɓ5drO~ ~sC ~ 59)H x(2_HN9ʅOHNVk*4'jJ ,!֦Kf(xNL<;gR3N~TXosoM^1@VQy9>rԠ0bm`b:% DpT^Zɫ`E O(҄irƉVR!hQ@vû]|_#:*/h 1΢*rʨl!muZ];, Ă:-ܡ`hȦ̍%+Unб2-/ssw\^t$&h[jŅ( =Ѱb̀D%\*@or\kVssQoF0@Yږ-XWS8K.>1,8OT-~Xۥ![ǎf4, ºf(ziz2AtUb|x\"KB [pQf^9iQԁŰ_FOʇ (۟:B.TUaslRǘM7ZRvs{;a5宦'\X^ZCR?jC[qRVt3Z i">|119Yئs61_ bѷ#" ;y(_QUoijußov&`cU#-./+Ŵk ,fB 6$ }&a2U,dc'EvP7ڐM/HDjs2c Ԏ8GOCKÙ\aП:5ߔ>,6א@MWxX"hoXgMrGC)'JEVȮtI)ơ;٨+cʰ5  `,SmUز;6HG~qt>_HB6JA F%wEu.v%xkՙ9$FԎoJ'tw{,flAsP5s"NEpV11'S8-黅|>k1eƺ&0xFpP*ú^GZuӓPUuriIX6N%3ނ/ܯ雀WoA9MvW0''XذW8|ԅ H4϶ŧHd kk&|&294Nj.پqdj@Z!ifnl|"M'vdr(qJk5q-OtL20L-pr;NB"Hb4K^A}Xt|y`W7t-EdƎA yB:Grٽs9byiS.Ӹʞ5L"bdgD/I~H(IƁH8Ok:53O.)6-Blm"Gګ ji{_J{)]0` D)ԡN!q)٤ޚ# tRO':ڤF:F(\ г">mgʷ|rz Oy78bđO%VPBaי0~O١[C:g{rLxN5Y2>0G%~nS-/ \B–> F9B˨:i򘶂C<5#Ny$>:!Tޣ2VnE@|;̓Y2.xE /9=z~6"OMtЦTva.#7^f8~! iiP8YZ+Xs &jSOEQ$lh>)#'YPyj2a?RUW#?\H1J]:vaŔ1(net/qBK)nȻ2Tr-+y)(([шα/hwu=9M xj6xQS|/,idW/iȭ^A"a#k:&I9-0I'L{z kuċYPNgF#qƺWG VFrBD.ȩk(tlGS~OĄ̸^Lo`%tJؔM_{$).nDA6 {OI᱈AsVkIZ[Z|.J+swC۞o-L?G%ޕܓȐ a g  2, |d}8gяhEA19{|%QQ/M71ZBs5tt`\i]:Ld}Xh!?~|Atϻ6RSSآ^_",}j%M3Fv_҈ X>?m<{f 3*]zjg-A@^37Cdݕ3zH_ҝ[8 æ?+4g&'C\UAc/G; Ot-aK#WTnG~-7͛|c.u (ٙbXq?\I Sہ[(Vk:z৊UufQG"+|BI{_+l=T LxkM̞\.G^L6N} gۀ1~9T^#hKDZgSy%ϧ͉vκqx~$94:Bޛԟ:`^+Oht'$@4rjXr)pB"<vhj>B.^ .2]nqT ^ex &=Fo|!2J(׷pW$wj&s[y78H]ulru:ܠMhQ4Fn6i*!u#$jI"7z_ P(':=~i6"+Wт ;3@JirAE勺Sr\lAD?Ze/ i0PB:1 2;փ__)"ٟ p&;Pk(- ErH1r!woN؀6ىIirJXjɒČۋd.Ea50PR|P>g#R;M8joA\Q첼|SL3eڒ]XqE}IFO՜ihW{n^TdKkDޅ ":l< d+Ҋ23/fky:u~jIۖXx Dis_]AM_="'h&\ Xt}v.Ŀ1Dȅk?I.ĨD7DB[Ek hT8e% ÀgaLva Q:7O܌\#PS| ;DU&Pk.rvl+Ϩ-fvE Iud$݇g3 o=6-@TW~آ8 ~fZѓ?2Ԗ%הWGtcק̵AfVm#5n8 }n;1&* 6nթ!b q`9]nU>yIKBkf . HA.{j0 )^DkHWhfOvgG SjgF dj~}Hc o6&.a}˪ƿl~[b i |)pj\|g,~1J=5;|"aW+_x5d)O_:E9R &5)P/&{;R.:VW(F86m4mX{71:W(Q~dɚmҰQ⎹[;>b7-W0GòIcbdLVNO+S^)#tpB.u=|15ɘ$ǐv^P2>h]dD0I 7-g"Ys3lx0iSX_͒?LS}JqEa[Kʄ@3FU1T+bf2@è397̹K7_ g4N킄8z&BdOXRbflE؎G1%)o} j2Aɜ**j|]^W_ P#: l]4>^FԼXşu")aW;Fa:.lTZsNEډj/;^jm[#dJ15\~Z8Vv֏$]]OlGfHGV--l@}3ALَGjsބ<@a;8)=si#QwwluN(}e$e\խ~P"wwtZ,5J1&PE!k*Dfi <`Muy=L86Б6Dg]N'P^!Z(gA#@CG ׼ʤuiq{=y  !Fd;t֬.UFR]dfEwʼn]$=. :{d<@Bj{\[#Z?̨fQIFsCK4~F6QG`o&dI[5. 6/ME}ltuQ49 ß7+; bXLN r z˟^|94Â<2,W@XSv{C)lHyaAfuKQ{׆  t-p}Ȣʑ-@"N܃ZɃ|> nY8#"~NUɪnJQ`nzOJk {ƭz-cꈠkCM&Jư-eJ~8w ̢QZLm~ tޛf'8 WԅWlΪWi:A+ZYX)PmRV9$T6صTT/nv cXS<ґG9haB"$%8&zJ_8㰕 >sn ~Xp)QZ-3m=(V7='>U5h5^Zm4ȎG4-C#%`n8 [ !L̞4(~Q[^-e;8MЛ.=7#E~HjC6oJf8Ahcג'':GP D,^^.%;XwQ (^H?AxO_@V Y`!◔Mߋ mZ*<`{s6dgC" a![ fbS`]qLH|L  =ɜBaTU/g []i.Om58YyEC.ۙèĵjf_i3~nT鹞yz~.P C-o'E  9]&@4t qj齬>d7~fJUŌC_$eZ8Ebr垪ZȒ.?Y؉Jm f:y?+ozjqoivK , Mːlٴ)Hu:/.P[ &y+/]%WIl=xETpbʣ%#sb+FK'q\f$Z9@ )/8 mqϝQONq?5աNiʓ&w\L=#nc`mYHqt5CthwVtfUO}O!y&fe 2Gpu OdSgV`\̀sm8y-C^w▔쉼L 3īqXN`D:VbkWDžsqp98ַrdGȔ;wz2L0IGҦ&1eMk倨2.TĉD5\ν[ahv-Lx^N{#Tޤ9M{7H8cAo~Wc1;!8Ok g_k>e+5?b;.cc҄ }覜"+|(]δzj,POyXߘ5V@"!%sb? ЈyI?-mRd*y,+XcZ$-6@KAS|3}'`Pf++( t͒t[^0"A؋Yai'[#JEKf]ˊ ʡj-VoX_88d7}SڝFU/dB{Dd9ZO0#*aJFޣ I %d "T9~>#[jS# ƻa!~-(x9Z BB ,x-Pop +Ϭk+HelQI`Mδ\&0kBx_ʘt<)pQ8MlˑtOc'Y2xW h?o6{3k>C|i이tڛ/4)?e!۪ybByf *D$QCߥ6t镥#gmaϛuj؉&;khs˂Z<@{i]Nt3ØZtP'p-Aw7b+h*A}ܯ/7ऋ||c& })9KkzЮ8[0p*(Uz keMôDE;n9z8%eH)1;ۥe$E i|ql ";ԫ>3s?,&Nl?@﷍gJ^d ' @5yJ[l(Lgn'ɜ7ǝg _k8Hmk#fUƁA j9hŴt *oŵf7!|2-!!0,xE͕ R 5 I9yk gwIQ˷~ YIgr{5 bj;fs*RtC9:TO VW73m|P>IPsnAʜ$%PXD/un*ʠfԗc8>},?T؜uJ\)$C q@:4RUo1ztmiPVj-wX5^6&pLМkf'S Qaԭ6LJb. v2[ɢ[*~n9j00TLoܬaޑm7`Fm3Ae)5DԵlXI9p_'Bq!бUI,HXFӀ$RVXC&E6K׻XHFj_ :{'RT5fhi@cL`}] :+ڠ<-:Uҏ$sϤE7(KmGޕAX[ Z_Ѭrba/QWZj gWmNS/ٖ]ψ4Q'leM+a 3i e.8ƹqoeʹb/Vt^jmJ̶>6b;σwO jN0&J4 wA9,nh=S:?HI@ւtoLq ~Lz!YڈJvQڠ5H 5zuR֔!D/G*MP{ᣌ@&|@:U;pжQ8_VE:nUJw|i> ) ;'n<Œ. bQvCzq>y}skNU;cZwNh=!䥝&M%2h֔O,Gw̛mi @ i`z#pkqƦwBOl 49r Jp.[U?[qDxbtQZ6I^a X/*྾]~Hc6l\/ʛwO o~Թ!ktq%d]5.[Q;.^O! G0 B'.*Y,.JT;ۋE%9{gD|DMc|?λ!W5w;(>xՃDz?qD$ƦTuΔ\N~0ylty!k1Wk"bAΌHͫ@b,4eeE.!.ioĨ];埡DɻGWץIsw5u`0kC.k 6nei,HYMϔ{(?~q9{2Q63 ʕi1+{jjn4U MĢ[Uf"=_H  mV6qjHs0ʦ~%tO{ HL=n/ȖV%1aw3HHx8ZJ#%C*[hnνUQ dP݊a{;\#4,@'j!9e;D$y n`+Bv/| ]aH@sZԟҾ]1O)>6B/&u_<~TV")YCK}eBd=~6 eY4@E7p2 V?Pe&v.c>o4bhWaO/[Χt'H'"[=&!}ʪٮ&L_R1TTD%/ ĎZK yj,+vIwբN:C/Ӊڽ[ wRPyBn#FS.{|7--;x}@x Lyej¾̳P;]Gpd# /`kO*+v\+WE\?+fs >x`Y pEQ(0r ́"/Ӻ2ݵ񑟉Qш'1L!M(%ɈEe~}ná[͆v J8(W+eHf։JR 99pa>,P1mWuϭrzH˧Ge*Ggz}m)#{Yo??%6ɩp}`#+ʢ t)Zܠ[׽f~z|hcW;+!ߤ6H K7Yiwv6e\l>]*<9J}޷qCB9hWc9!l90h89cxJPisߛa0- mQ"-KZҕw amc{UK_UgP$Dr,z{Q1EK] Ȼ1 de $^w>;#7@+"8DAomYDEwF*tHl2Z UrcARUz }`K5.맪Y{;QL7'wj摡ZNzUDfN6Cb/\|AGկJ2 “0:xZ|a-)5٨ŒF taX@Ok9lT!q% X l*jF?(xM,u7:k?:T},K,n-y~g7 &l!'9-/=mI߯?Ǡ8OV&*jzʒd@|qQP(Tr6;Uج`4/h]wC[D3sNyݞ+qq[@DOQxoܿ}=S8eh9fT+8F׬.WsoZЦ玠,5W銬|HчYgaý=pVym5ׯs3_|,2A^bnO3gV3sINnkT$.sDffI3N,s3$Щł1ƛ$XR2kZ¨Ֆ1:g,,8kZ" 'P1y=D=\2|# 0$)PпP."Օ!:bA龐 q<:MӊЖrtdsOƧny3AhWM܂ VK A|H,Ņ[J@ klZ~Qf ?&VI#hgr,ĞS;jtGÒO82׷Ä$D8ZE.9YuEEw&ѻ4( vP k(_>e$_؝0L1" Jx{lXMYy 8rd_LKֆwa͛^|139#LM\ݷݍ"eC}>2G[mNb5j% b̩j?'r`8ZyUU(vt4`u fA_ (L,! c17PE8uJzW݆*spmC7٥g["d U[a Mdm/ ʔuH'kMDr՗Hc@AU*-IWQA(<]iU˪#g63ӴڻWAl):\{xf2]i62:HBN0_mj U.yl1(ޥ>r+bP>Җ:8EΫk(՚< )_Y .kBaR')tgX8;@&1+ګUi1:x␁S}`x{qo1g2?<n! MS/#'(`nb=ݦMu9I8>4y]V+:R_yST+1F0p21{X@IO;Q585z~^H=X$k>h _1}b/]Z=cvF=PI>j?IJWdMEs7\LvNW@IQ+DBRgmwTɩj! JfJs!0yAjWp~!e$,o-aS5V텼5]ïTcŽݫD lH`G.Sx>hY(%gS"Θ gB#>B)s#9S`:"<9JlOb>l:틻cVm\*b>f<ʎ}}-.8^m5s ` LZ cQ8O o?<_ \捹o.m=FQ;d1 :2i02I! ȇJ3@B%F8!.dv˻R:9ɧHr{7*9ܷ yYlBh1H~EHqҭcRD%քc[@='ʷVk򁊞W=/ IOOc[flcU4 /@usX**%3.49B BjژɎ![#N#O] W'FݗP,|̼ޝ\I| ;ތKm_ jvКuG|z붦GHvL^ .ܕK{O ] 8I?*;ȲMYڤ PٕپBqjлR&ޝ?T=Z ҝ`9ql|YJnoR]1X(T,;Xm,pʍHPz * EmB[^-OUXƸ&9&瀦ZyB:8{Z0hUv+߲K s~ Ew2/Dw5A +{*fFD:OSZPR(SOaJ: wKS3Y\jݪ,rWaŏ 1=͌鬵^{Vr{qY6m 'DDJ:V 3de8OMm OgG۔pig5-8~SE-T"Ay{kzl977O(=&y[et-7"/Inu}pV r m>ҁ 2s ԆW](9q`[ Z5T̈qY_A꤆A0)?sqszK>;j?Fqc֦PK3H3KTW(9:$|pFv0(\ fIwo0AU3p -qx>lM)ŋ<34[VLM@A@HKMy+*drVIt:C˵ D5|ASc|7ӮpCeӨ0֎+d,5J~.Վ?>HnE0’6Ƹ65a*F!/"ޞd <8/X9-ӱ0]-is+( 72Bp_0TQ?(jJ=~_xUn~a #|+<VmGnzHPeg\Gʩ _Wl:|X^1 Zc|Y<+t &‡嘳0r+hxZӍuha<*M3x\"mS9߀)OJX.|b &^CqeśW-*0W.T4l(E7/ݡ@Nbs7^)!|$` KDDY<:L'Bq,-IVO%`#,?zbrlmO&[1]U5e|bSw#ΈTfbTLkg#t\pWB(IJ>xOOf諽!$˥&ߏ+b 'v5on"yQW}"P>yr*$UZ]N`ht35Øx HzX|8]4iڱMwz%rehu0 |$0~쨬#eYFҥxL<2zaI1"F~CN=s8M~/"AxKZ#3Y2A𴏙GAlaB as9-TzoDh ? L7)=5VU*>A5-FLbZ?jϞ EAh饄]\9aquvwytk+Y }KӃQ@У%R.,*i(vA`e&û͸:Q|x1'cwud7̤&_qTBZ|"]2$t!>aӌO  ;ɿ+e0/]h\X||ΒGq]S9͞E_iHė.ousT\\ >L "JNapSOO_c9|)ڝn tT&X/lILF]S`;]3'r\“|bvL]?#Me~B32<9=/%MRn`8][rD!+ځ?*|vv!/n>!-gN!9 F)Aigs;u\JH=LpDmóOkA #y 649pI dO9wipO9Oo<]?Ӗ}ܧ6H. bԽ] p8bQ{oQ8Mj=P2C6"m;r&Wfv+Ȭf"%E@&Ɵ\Mqg_yw7_IP!z077 o;NP ǵ.VeB't"*ĵM@ޯ6]'qpKf{ve앤!*>P'sKU8B!s$w7M֥X-bas >oKSľB*/4Th D0λLΎ)xO=|3=Di}d*LuXFͱ|hLs-4֛+1ÃUXҡSNAj5g*`U?F((%eIώO,C@w'!*Ja L}}l+y* bMT:(/m;4rMl}ZRu7yj!op P| /R[%@>)M#"l6+O?Yurtӳ':ctHi(bR9'ZG@<oAWDæqCH-ZFSs~l7m|*f3',\bL|G wp29 o c0ʦiX…ﵔ#Gifh_@Ǖp|u7_OZY*4wV˪d=Oa@DSxΞт _5te(ޭZ KOyќ-,}S !HK%apށ[eG3^Q[\i@VܯQKZ %f 2;x {+B#ҩ4a"y@pl옲d%QũˠW2O,0kqG*1q贷¡!'ĶC-ߦo:%8TC \ċ0T\`oC+^Ka z.9m6mrH ߢFKkץ~qe,.,g)L! 5,*6-Ҋ{AjW~dh]Gz:O ՚C)SǍsEy @)T. _k%{5N:&1 tuFmr+7M΃V2}dAjo? 6 3W/TBÌ %oOvb/3.B^ͅvMntO.Vj+y4C$}(7r-c*J9Mi%YP K]kj:cRYAql[ N՜^+Q%f@Qs.?I%|A긊Ifۻ@ t/\6)z~a#cbiJc]4U\*œ'xoyJI^bW* 1C ?g} t&Anº|=o<`( _":NĹ~m"敃HB&K}t'5Zm.9ӴYkg POvڌ>{;c/91ۄ0hbD1*utt6)r`B(M S=r lOP#9ЀSlr<ӈ1u{\fa+D#[9[pǜQCWE/XDC+1GHe$A0BzuZMZ"3/lmT`9fr#ЃKtoCOQAS |$, "%v߾v9j噕./sYQ=v`gH(ͅS{2^ʘopH1(/睁cMw#d;ua$#lpMHFQ^($< {x^c-rC< 6EUr!XkoHt: +)5WޣnK&ѵ}쓔Ϧce!-+Sʻ焉 V婇a,tˢb:BQ%">|p!%w3_cnAO5IF3 +|+|9x2AMk5a#;UzS~G"`Ahz9&VF.vd-ޜʓn?Ѻ0خwg{),rDah}6ǍI wBYXCz$j['&O[!YNL= ӧQځߢ.m2WJ8n *H!N^yCy&{._)Z K[AZL|0*:xL%DcaDmv*mp|$ rv\5zC\-0x[ "vhE%Zui//XB2jxEt0~jS`H [)oꩠBDZ^^ '~9hz$Q@9ۦZ( 6xu*b2R~J(ﯮlq.E ^\L/e sv~78p5Ca/ww*~d3u>Ebo[z5yW"Z3)@QWka= rx_u;P'?]P׃M2ڒ}s%+|gE;HXnst7&]M8kmhe&d T6(L38P%AwT[kr862{5:IN?2% w _"$Mr<7˗G ~Vkװ4P)xN2{BDгVfz+=+54"[=qj*r)ѐ9~hHH<2n7e}OgW9?V8y?C(Z=ذwo`G;%MGDL'4lCMxˀB->#XD#khZTPl\ C pQl6qMOP?Rk<e2/P0o_{*'ǢQU[!ߑ %FzR-H Ў$ nH`l m2orwIûHJo ?;.vJlhD%j5JUy/ibZ;ʛmJ^4-c!i1s>ar&i e$v)c.ϦRFkJ QBI)`vok\WNrc{gcS>Ku!m f`e$Z됫u)'#xX 9.]s@h̓؄ɩGM~$m:4 bՏLeb]Xv6vHXeо/"+礭S"+ RvF`HqظZصY~xl0T)'{mueΧ ؽV1oЕ( 2_^Q2wE[:ңV}HpqZ|l.jE],FtQW=ZM5Z  ~ߧ}FQ=2ْ.`$hא@ l@;D6 xnu2~BeKΧc{$R?uCbCEE!ļ aO i1E=z+n߆`FO.4ئ얲H1S:m⸢:g'_?FXnx5T|@Hy}o 紡o-F&DIm*.;Q-!;Onǧl`B=9r[m:$QUMD g/3my LBRdTPN8b@f V]Q0eV࠱3v8S3k`sكTk1`^ltJ%FȞf>KrI%g5M+KD2: L3 T#hT?B}l$.OBg3`$bj_>8W4;_ZSUOV&DloEӭ۶LJ7A*z%Z2hk>rYvR_Mc"STɀOd] AڵMEt P) n 7pfҏYT3e#$s0vQ8CeWԅV= V|n@r> T#\6\'3MrX4j%,I2KX鏟caHb6wseH/%br0wD"vGPIO"n#:l]"`k (';g s[T^I} 3WX*} bC| J?z̳\Ҩ k!Tl]MA4jnpZNdSRZɞtRH;M^;X-&B8/o0b;3l0ѓU/[ֿco(@5XG"\'{s\e4.qpzmvTl.m4KSpj{'u;*E˽t7Iwuq8lLZ~[GaS#_-4Y ||s+Bn<@QȘk! eW2Vkcjc'*t/R/f10Up`~H~!q2P-'{(@yqvTޤ1HcjQH,7?Eeoޜ)TgKy[)@D9_-_ >vޝϳ4IwqKVJCr'wՖFwX]a ʮE6nJjsi"oY;TPA1TQ琚h<06K~:Wq 0_tkɶqEDx9рqT'_e|Kc` v'G%&8.Q_La uXxOB(Mɩ~~WkϼiK1 .JDI2Dՠ$fGtA'& 15޺P4]) <ǹr ҀxW;4}\#7+[{jf6m%^CV􎸀o{ _hzo) b-ՑZn|kS ; i}&}s0:/c|5O5C@ӔuS;w"9.}y}[ѻ3rG1 ^te&G|6lK;EǷsIֹā%p=0~ 9Z;j kPU[;k }QgMϒ^fH >QGf aH+KXbبTK1㚃-n"뾒 'dDqٜ,45tLVF'ci~6_1e1?{F9ac;ch٩d8kj\ >M>' {6೩i[Y탥fJ.'MxweFxJ ы^R*F+9q];k!9^T1q|zBψ)ϏO ag?H |ߪZ;Xy"]h[7wS9nhDCS =}ؽᰝB" ϴ'I7/~R)[Txw,ڂ3o^c<%u_='dd&g#ut-%Ћkb+P\P6 c&*!\U [Q5~_@Bf#QF~A:mƢ(#:F' ga:x$ slQۦUhl}.՜=f+'"џ4G;XC"Do2ڬL ZA`r[LxQuq«Rc7"L Th: >r)ے_5c@e.BSmy*_ê>9T ZxnzOX s 9!y [dk/.̛<93̡(`d|^Ű^ auvk_hbr!p@:jc-w c~gK*H]=#]|ڵ;[JEЖ՗4NcL4'ynl%8KLw >_'n ر#xkL]srwt7Y}3+9  J9&vI5RnqV@惺OO%3K;sjBœRT`^#[~Fķ:-$qA4&baII@[GJX gSnyq<8 iȤN5GUqKpMQe߂\xՠd5 z.R9>u_T9ǁE~D,G bg%}v ߁E&_4 %R 4.3)EbJsҝt7p!m=wVXf_ f!f]3Lh| -4!% 4#VսqiHUIN!kS˚g8 {vP{(t5!;%%[2*+ƅDqy-O"ZK=T. )_џdWOolRc/"!ko7f>M֙`XLG G&SGR/uDmsȪ}ALU&E@F1\=yƴ^y;xPDCRNdYkTeJ66[ ߐa aSؖ, %QL@+l@HRj; ,xV:Ʉ$)acF K,PClFߓj;E+ox*Ͽ8].ܰ!QgPɘՉ*+IX1R(-N: X|K˳3;uO {,F/"^-rfP"nB^I껫B\;(:省 Jz\]zERZm %siF>"Z/{l4LɎAέd\pٶ^$rtZEYoY|T$3yM ωr"6CA`b{<o9Vʔ/PE[ ޺N|^>;Oۧ_B{dW?@/"rs"ҎUû@c⮔o"劜E:Yڵy.unoW{L ,|ypɉsp r Bab$u{biwK(Eģ"V;8=2 wX3İ)ºNrx,bIXIĬ):o3MEDhJ7}1C^Vs jDLdr=\JM*Th dOמLH ]7(&ro+wxz )? 30~_;|v[4%fnw#w%Ո|aM-Bux;&$x_̤M)U_g|Wz٧uk}%U}7uiЋXmf8[MnV"P:_iܠk쀣1vh4O0ssMI2T?SآzN6 c̍r^gt`D؟U~Kn/cNYQsI\ўϘ5ג  \ (/V* 2y9XPu.0ۿUAOThPL? h|-KtHMHV:A4Elq0%ERVrUCFǦ~sqMԑL.RӐ`0~Q=SD*y8MqԒlFrDr_ ]rD^$S;ȗ*wՖ= Ne~WC0pG0] 냥l,N 7\%3x'sޖՑ?`+u؝c<$l"~%^`; ah^>EI`vPBMY ᘁ^yu$('e RПJ{Vџڵ$kFhEPS8ܘ#Joy>2ltRiYb4a2m[J/WƯ$ܥ,M]@'R=5zY}J]РH?O* ʐ+ddq!Ja 7"~w}䒪FRab) 9rB}~KP$UVPTUIZ`$5±ŀ`ncN1q1 Rh!cEVhYV ځΟTn+`i $O[ZV8Y[2'ˋۤ(W6/!0ˣO<&wA29xБH"f؜}'Tcb*1n&·*)|{'ta`!L$k)K!|p$w0n=ÔM\{qm$I!:Iv;J6W!m+:?Ce%~A9=3oJe}w "طf^xy>4f@NRԨG0rZW8J.|?f Ν2+Nh(ɚa|RoKlv j3CmN" АMa7 Vz(wz>K>^Pxu|9Yd|LN^g0EM-.9Έʽ=HnA,_<^~5#Ǧ0%hɪb,ge};֓,Yj#=sxga䷈2@J,"wͦ' w R=A(smgmQo/0lx*{rT4)Ej7x-҅O>dd'#ڥs3:hmXvM2O"H,h>z ;p&uQw=JJk{q͗P{=I:Zw@ pvW_8v9,c(8%޼/n6[pݗCV/yVAnq­e|{{Pnr_Z S'!j K'}p>^zle٩ -T޳j<47KRREd?F[~=2> =@ogqra spMdWgFH0¥:/zևJmܼ=Pi;5|$6m e^ˑlg^>),n{`:ur]I3) %|NpUi8O1ap:[TFNsT':'~_EllQfۡϮ rR"{.Āl"3%,9Kv{0A |IկMM(howfqsTʁP<"u:_Hn s#{W~.)/P $hYRZE~a8L ? 9ej~dc#ܛ)˰Zs˿ƹ@LhWȐ uӐUK5a/"ą"B-2WWxJ$'BtBE5+vh3%R\/ iX2XZOR.<$<taW .JPv 3Wo a`XYO%41)*>d<ćsWV:%zhLwN^P+J2KMZvC Y/^;YP6Nk/fQuʴ'Mgr'}xE%VZλO;273<`wh4J NȯwIWI60%MTmYpah,BͿ/iF8F pY݇Șr}0@3{n|?!.p= {R|*nm"dGҜ*CTB ]â059[AX%7&`}Q)kwG{$@e$ eT.fxFeK)B7'(zmo%;pb E1>N(2fD=9)ìĬ~Es?~$-]Gu'+`lLʕ;S˂'_lkڷɺ8:/ *Y`f*<;`W"(1Nޞ)~1M.q%`6:rjoHO `MG\JAlj^÷r7U]KehrH2oH tRx,ژf7tXisڣ{n= k?k A9gQ\HD(Ȉ#gc!ޮI|ٴDmG_$ >] 3ƭ 17݈>B=~a/Tpÿr'> WލV pv띌P , zmrBSPQ*$`PN)P=`Ӳ  .#D”NDJJV)81\j܀;]m j(rK RM[vl6Ih% KB4gP&;U6-DCSf9<@rS st}]N8FS|oj$Qv{>ŠO<|W-if)67Vxs#F[(Az֎@㜩s(%-~_W:C"_4}'Ï>,џ4h+%" :o\'n,Nҟ,<-3gQ]+d{S`_mf?2*"KP!Ni@dtI6 RpJ*!oL\vw+[\3?TbR|6SpsDOթ9vIih%/|M:7ߤ ڀ"B`9~F{`}MOP*֑^0j~U9y򔠐E3:Z( o%#t tAKUw*o#9ԦxH1uLEm[_TP85H-^ѯK4ZA ˭H+BuG 16 @U4?Kɻ]@ vݳotL+/ȖjCs4ZY{*Nןͬy*:#v,=Ч8wtWl um=fd y9Խ\i|p$fŚt6Kz Oy=DfM\JRGI]C[X>uz{}HmˠϖQz$7U;,J" 0NY#وw_Z{H+8(G(ȈlT "`07ϫNh6O |dZϿ:yh+>P tIo=Vŕ4@eПC%_Zt9B- gMrq`.5 `@9wNv8NM5U=ߨ N^-V-]-L Dx 4Stvd3r}=w5BwQV.JGxU &"uo١D*1_jNpK A*VL7ͼNaW84t7Ur.<>,.''*il_H\ܽI ;a(? ۭ0߽ؾ㶸kn~@hεGWUA /\MP6(Zr%e倠"6I. X94㼱}2D_,ٮz7ZQLәXEIt35~rH buIp3"NgV nMou~㷒) ~w'b GϏR/FwmYpu6B )",GlDuG<GowX>{1 <\̈́ʳurAz~*l+'N:6iCi=y%DYϘbY#^wݹv?ޝi+2F|i 0Qևq+zEqxde9M9ًH YRBhX/n}Cۑb BԆL4G) ,%kQTK60xMyF;x~MH2Qj۵.nq[q;"we}oܼzm. zw{,:s$κ-`0`_H^$v?MjK9vd?AïH\H?Indj0s\j9I?n8P{C-=nu%|)}kجa[Hk-4ߚa@.Zi`PO/+71haCܺD/**])f܆%>ĠwPmoˀ|T·28\:J#UPξj{*ㆅA ,IE}ehs^J(Klm(1 "\O+huQBxu.ۤjؗ[HF3j| q (uEj`5È/حK\NFڝ2:O+珉TR9}ml^#IS'€x0=6%$WZqG6ۡYC4R"\W^6D~Ia/HUS׃ˣj|l6OԚs;`:in;=Rx%<FO.I3-Ӫg_sAE Vzq}ÆG30{"&$@)e!y)|?j_5f"쾥-SV0,y8);+#*×(\UU99W.\BnR^oZpa`#Nlp{| Iՠ}f55qYFoawݽd|6Eno+Kc椷"vߓQktP)5Fkm]y(: hMeZ <*J{zQtB**O<{ptꢔF9(ԮcΒ):=F6tz"Ct\A.m*FVt[L BY!qmxĽj 4B e8&K?:tHqx3ʏ|`oQ=Z:/H,s4F{m/L^qO_1,Tw!֏sXaX _Wϻv8Zmr x ʅNv3O8o8i mS׋vW$4A%1}#̋f u@Т0ui]Y RCƏ4ϵ(P?}#a:}oyGdiCĭ.Sqxȉu^bշtV%$A&(}YB kD,}YC)7Y;H?mH)qX 9Di̕T74 wqmt_>S:7THĻ1&Y}GFv&/wuz K=ݩ~˶L$ Xţ렀TW.sh?A/9Z*+jZj9?J\Hҹ$W&K KUyAE;/RϖfN`sxvx t.G['\ЪaiBLU`i1̠v\M9KeoǬ.<1 +IK~a\CY|lbL8 ҜQVnlůɳ KO-Sa.A-P6׿6t7F_8]Lީ>bΡ8*ŐiZ.f&ݢ'nvBB `3w jBC?eϣb6<) W( IWqﯴO%29Sxx fC $^ߦ{1@2Aį詿`)_7t!*_0f,*\֋kz{_ Y6BP}+N*EU t?R .Hn1akG%}Kvä>R3X/'W8Կ,RS_0Aq2wÎbUGpz8zaLňĚ9 t|i@^!`:yH!IYpng2@2fedw f$̄_j:@ h K)Z49߃Kcz=o /ZHsPޣiExF!n>-ܽ`G Q~ /R6ݽZg=w( {=Jʵ {`DRy߁0)k{ofR|Ĺ Մ- Fh/7@ HEr7@cY7Wv8zrK 2.=Oަq$Ғ4v96(}2 f3DuɯQ|vͨ/%(f {팩1w2ޜ6nMes$`RlZcPY6@j.W7,.OGa"."HŎ@ڣ6r.rѮiE|lK.kk jtDfĴ-(vIWTAt ԓ3Ebs .{i9r44gm&Ny &f#/g+(2j0Bs v4`ViKPAoLcnk3sqA13"HU~dкO| {Dk"ՓeY勠 ' YV0?]AL Bj)wG~2AYZbat^Ʉz A12X -z$e8A v9vŠiX+"j!2мf'7JИg}>Om>#wJ3g&$gf]!!* ʺkl O?㏁wRN{Jk"LH|i{n=axWHKhYů $D֠~XJOvN/b7Ly:MT̢S`|7V\`Cs7{c U{W,esL/~4'n-+!BssPX99}rH}KWxR;q@fP -qTU9Q+u >q3vy6*ȿˑUJSb՚TwvBHި9Xnc4eHՊ(o,+yL R1?Ouf6 86P!+ڥPP'h; !@}N`w򁇚)1]%%9C i=s9x+!4]"d9AsWɼp>Þ7(^Dcpy~|d/H4G.lІˮ"%hMtWGeiu,r[i Z}S!:*8Fa$VToZ-JBb낋~mFd9*j'q*K^b]⥀00+@[mQă`u+[ϑAc0#]1Swa MD)sRߴʩۛ޿jf.0&Q+M0aN<8$XVzXo/X4>@tK}АΞі՚ vUsCl,m2Q]џEC3b#!i IG6a5ś\يPfZh>qC\HbW 9?񾖘g !@2:?r<4b[n+&Eϛ;W*;.ݦ*,ģK+,޳]P/pxħÄExdt^?9 L_r=SۑL:D|sP eQجy &|*jq_&4}xuZZtwyCk][R0ޗ4f4; D R/yZa_84n]os)Ϝ -A Ti.ۊ!s-|͡60y[+w΄7p79bf^(o GLH,(zh]%qSRY.m#Tk-I(;:Yuy6WވgD% Cjzƞ3 H2 ڶjG JMt>-? 6H(5~SNdŀ,.)ߡӋ"/P`NK:#2;u˂D,^G.LsQHwkq %Qa?Fo4S(Dn%Jȸ.9Bn{?\8Wh3gˏv"VzSs_8Ma,Fh:qq,ڄ6UT q6W jU@rBWѕ0&PS%/t,ɉNh¿u`&Ѐo!jNB1"jcr`_.tFlfȮ7WXl\D&-))@7" 3TzZĴavUW= SFq@MתGk+cɡ^8eA#xH;xVG8`aJj* 1{JI6w@ێ8ߖ.ت@#"+h74fJ:^')ZxucMO!)ON+փ?-{eVBwP;C ?Ζk.figM~&RB̆sy$(ۛy\VFQǦJv ?dD %wnCtCAekZ8Q(##j[]bj.srwFG閾h$@SFp_H ,_W7;C3:Fw;9[H ͻG\Æ80wg_F eI;ˎ1:z`Mj3#{q09 C32@|$ձ׀aQD]d|5Z-YC*? "! j[Fy0 0e+0.=KQaSVE>a-{ JKݞ+.6:P;\{,U'ᥤGbZޱ.:;%֣`d{\HP;_Csy^SrY"V䠣k 8/uQ8Aɓ o5SHئJMt48FbGrN aC1>ofR/ YP{w`<_+y](~)FvBDPy bGo.w2Wc[ZGu*g ls_h˒"Rl'~bڗԛ&WGR֧{Fnz#22@^CLQ iB$>Q[ ă|e7gY2K: GB3g^ kY2/mMQhd]YlTMϦ]Êptʫ?=Y~DJ x`C5̜N25i9ګ73.'\Kl*>G'"K0=]H*u\0&INr9>om:tU@yפ>CBꥠ'搅G]C"jUn@Ù,|pIB,`a,@ٕ@:df-킏UI1 )OV *} oEq8зL$):$V*v%kإ{i ~>SI[!OY*{'̳kv(=/L=٧~Gaf=#dJa ,H KBwa6p ^K,gfG ϕY=Vg4hy?*Ovu`+hp2!s3ߡ74cd2uO^NLzy݂U;!(:9n'^lxm%tUxu)wN&_L)7z^~0 +qٴvCn<0֫6Qۮ0qaȠHRkT_Kmn3IR@lZrr]9%z]y4KY NK-݈yYB2t ڠyIazl̞~3Trdw K rrK\V(104v+SoL"k՜yK=7$=6b8[0sUVY{\\K-`,&Рolr e'fnK)vJː'۾a"EMCuYׯ/VᅮUKؐQJy8Zi=.Xrzc 1`a]t'{_1<!;zkVDIzn+ck,4'ihwHn/y|DR=}d\{U {,;9=<2Gw]Q /sң*fe¯SQp9{}XV o%8@d{Uj^x _gttz+Vͬ@DS+]hW V7VʀQhhfPr}LyJĤQqņkd+Da;R_o_>'- *emm53٨-t[MA[.zRoD^9ePGI:_,"]]: t)P0{kOJNސekY35ݮ΅JڒΔhU)^ ZV m3@UBWrs9LTX1};WsWbh7Voѧb{TJ-;q&8I[]@&beblg~ *Ynly[OC74Q[+$>;a|m#D=ˢ$rOZݭBl؀h2Cܭ] V=[+|d#/6P}+n^ ar\ FG-R gVQϑw iZx?xL8™-#~i.ܞ[iL8!qw&qƛ@.dH# tmCyq7y2ݳ7"ٜ,tt: J=`ޣrW?L] |BxR,gc~M5c:d,JӁty OIJ1\l/WVS?:?c(/?4TwPHj,/dT8yJW;گpJ/.ɠc:UYYELDVqYnl{#Kt I@}W.IlNjYLFO.'nX&|3fze˷6\J@d?|7xqiD)QT+M<=de l@1JB 1co@C#h "uN*`?mHky>v3RK\#UWko|-7 HprCrȂ%wMhXioLJbv #H!_~NˣP{ixӎΗ.WȻJQI5f#lg7s>r6wNX (FVui ݅NۏRWp+x]чPe,XPWdb^/Wn|ow; IƒѡΩK{|A*0h?[:*qᲷ@JǰOۮ^AyX,nV,-`UC$szLewbjruo@*a@aY-E$%u Hm#Ցp.JyxeS+gw '6־l+^}#,Q9QUE6C]P,0qQS&:%I Z)aR+*m5/dis؜d\?؅BDJ.,bF||>(}x[SZEFk '!hwwDMAoW?$˘b>#t%2wO*Е k!)rZ$T}$­I*~\Pn |1}gm5" LY$2!MAW^Bx}%z#Pu&bԯ,9 GY?K }Xhn$.{.E mot˜[hv,(4d7С Go\^#0G#[ѾX";z#Nڵo>c-߀ ]Él_\|0i%[(h]NSY榓~t为K7jI jEqceW6QDc1"@PB"4//}ioZ1?2_Ž-;LzYdf#Lcf mK^l3k/(@5䜦oG?XmOޢn<.22aaĒAp$2QfC,!if `iAK&٤(I]ʄ+{t[G:wtōCN#‡iU}QBP[2 ~%Lb1Ut6T`i aoU'cMc]AqgQщ@V;%k7 QC)> !O@$'p~gG؍ ;b/.C=_t_c|x X[R;4ւl ]PwHP7{&Y_ǗPG(/QnW]k"Q 9|^z<#B npx,mw/x95eY[E Ȼ؛:h_ey0 Y(h!<+VnVtL8ڝkv7kI׽S+MN17%iGx!RгrFG4(JۣCSPXh*7IFɦ9-\ot9 ._"纓uOv 6`W^ЃguMf3^3̩Wg*ѻTIn5ݍ3X!A u$(_hZXD?P: J3xy*U`,j8/1^bHV@M{[##RWmQn?`sfy3Aj wuB C|=FYqw b]Z(<+Lo7?<,8KQji8n/F.(89Hp4H "r+ˣE׳QPz:e aL~A?X_֠+V8xR7 _bHi;lՈ%1[N&p íkc6h|7?QsßEjǯ8? ?I@QˬȦM'hK֠S L,6ROePK vL&#T林*O AMl>=v6MW!?EU'kUI Z_ALUM8a]63zuۃ>YA^.vt6ډygL&9{ ? h `o>yWLNalm-**bH: V7w.dXGTn$mjt_@6 's;~3I*Rw7cyұtc>&(ݥl} b4coTmB79 %Tz;Gsf 2^`bæ^.i!" êr%RZ9"ӛ8C䖞қba4>3 C5V?H|RC|hx@y.o6ﬨﺌWe#AJF%Yh*vh5WH|NJ.oE2)ڵ{lCX{%{CRtԵi-σH Bx4-.D<#q9n2΅ |?bkI2u2ӹ++.1W>MLZ_ "PcNi訤?Ah2|'5X]+GZ׌6Ll7 |TIjyyr0Gg٣)uIcIr0%3ѹ]aA&Qqo \q~PRqjkNH0'IN Ecuџg<#pa}@0 Eomm ::4njRMh'=:Fvb]Ϋ'D;>ok!I&jh]zmRPIk=_!]h`isNO`[1**'esN}2mS`дuc_CV G}(A𜴔^S>>␗ R(rA b&gƗse҃[9H]KWQVڐe?)OXceB>5BO#̐{rO|*&O1x`pGAtfDn#J r@sÀo7vq,uvtbt3?|8Jx$Pb l I \ɲl²P-}u/dϴAJ~¸gSc/ @ }**17ѧ] Rj ҍir:v5]b+3*rlV12'yZ]i\ꁎb-z51zQVv|T WJ:JUPrbIgViPH8Bh\@Q^xj'%1u@NMnFf%CAz8M#lYPc`X\h8K6/ItYMR84\E-@SNzm5Of x1tfRǧ*73!lrJDКJ n!a[P?28u^48n]PY',˻]v2?hY0|wp}8_3Jн?zΐAm.&LFӗ>sYC>- U{*,4AQ+lrȘC>&ɳ0k>?"d7]y2FlS[֍5b1KQxNUSwu|sS_(6`L2=ȝswҐ˿#p3B'|bP*\28Rʒ -@o|xR{n5"N bh^ b o iHB =nf:Db?6ni;}fXU4ѕ&7ezO-Pi@}jU Ƅdm݌6+ ͰӵO3߇4\kmyt ZmCGiUMs ^tRÓ&lDš/W > 9shI%9V-* / 4~y݂'Eɀ<#4ҁq4M/ucl1GC@bV\gea穻#T eMR1%\4F6OݧϢ[=QsY OurHy;6W}=:x^& W4dO[T$PK *ϋM,hNS8f|.!6Rzz`AKNmδI:M/";nZ{[1F FI˂nyx V5!`R1EXȹ2~HrZu)APW vKZJJ<7Sҫ9w‘ݕ^mI|HB?|)ޑ PI@#)J\K7FUt~)&LK5mNrsg6tmoJ*88)6(!ǽD-7p}u3GzyB Hi0 i4{ή]'Aj:ZMOIe8aCA̐ȍA8ҍw28$duuHAekc(&zNvZ~]S#DQqiIuC.kku( R GL<‘=cpL|ŧc9Ż1?R/vK*%wdKr6>Nqx0S6t!=xѣ3{r2Qc* upzav棫I'Ї8.J׷ ẑ9s\dXؤ _2L?h!o(DQA߃C"3Uן\Yؙ3MJP".͹L7e*L(V#ѤRǕK,g#U8 Ñe78'2hJx|\;rZg}KPx5 Z4½%-2qT鱔?"?=ײ'+"9 x<3WӗQ?; bş¹25M9ƫ0,m,꣟2e.P;%77ғ%(<+јޛ1MdaY0>yL O${ 2-DsaVaE?T\Jy8Cďymz# F#T7LF2HCjkbI,n"@@} Yd<먮#ٮoHE@=TdtG.}l`~>ϫ^3{9qv3<(v?4q&rA[kk ukby_e?[Vݯ8c:Mo]l2여qیך)\U'}9RRlfMT*Uщ\kX՝*eI#e0a.[ {#UU_*AeEX`+Xzy9@ x1:8so@EuF0:tn.PNՈO 6cZ;Z>8&yc_;\lư5U='br](#e3(oݲEHrU1 ggDa!Erĵɖj%VǨ#-]l.H;nXL]5odlT5M<: 볡Xg OE݌,-d& l$9Zg(ܫEHi4?9,Fvnsz]2rkK pYԏ'KCȤq=@6>NJz_@*cJsf7фՆNS96\/ce}ٷ i;…0uAu;rzfe|,X =ጹU0*1chIQigmF~B-n:_(1Ftcb1h/MFR4i%3*H0]L&uLҎa<Ň}~+Tt; viB)HBnDB:Y&e"ELJ Ix1 g>Dq tƕ,m󰨹gٙr)MBC M;#+* !⽚|~A'Ed4N<ٽX<(ԁ f| "S*bɊ݈i[G/<IYb> t̚ GF}~b ,}d^ٛڐ4ϑ>gcl(4} V;wN3d~c[vpsO8pUtPHRs?P5:kB#zgm40/e7,/-y7)OM`^Ʉ %/&?:O'B[)"c?{ِ>DΤXvZ`*]V4 EIe!z$B#/oX1@SO@>G_s+18o{M ͉)؃T'Dw+5]qDI&t t 5 0WܩSM5'],rU69Y{#fbtݐ5i(0.fl-J(&uIOKnIo>SvPKI~')`9ЄLiSٕ{q9cW628Ep,띋v(28N=0#,V?y@6O=uep|՞m΍P/p|K>M$ ƎÖcB2 ]n~~t5jeW A|GmI<݅m.?Q<f3Uę\Rxim_~sod]P1B;̵$vwD" }(G\jm.0J- GG0 ?_|&-WU:^3L,2sk$cB!apπVAԳ *Yo‡$VUg;qΑ NzR'ġ}؟E174t͢j*vd]N{*^xPt\O(\]{jcLq3lQm*L1 |(lHyZdWSo^9ϊN9 }H jL(I^EI4ҲQ1(&(VaV%TCoX_̜RrQVnZR! oK B\y 8r޵GY YRgJ7U_*g%?'6Ӿ9 d}ګ;~7eZ1n&QFsWՠ}G ߼Ge4䒠>rDiZ^s-Q*-'`!ib.[mKBݚ"BJ]]|0=NY6vI|LBxEWjJ=q ާIb~sfe֊+F4fM'E'",\9$ivd!/PCRL}gSyP__izT7ܻ_(&LJj_ %bw(Қ\<.l\^KCt}2I|YKPeHA NE6%p\G$d_[ϒu(c85-mٔhæ`ʼn&V5s'Z(̍XP. H_Xl6N} sT\4emLmt>Bkx}8Ej |RgyUs7ZK|ƁIRAaQdF4!'F suqXl"zX+07oU+K.LM)]),jĉnUg]P)-G"H?m4P_qJ2$A:CP]p[5IqZ"g 6/{/h5}<6|D?~Ly?{?jT 9u(w{:kg6VӻJ˂#+ȇZ\)ژC./h|Q>wD1X<ݱ>'0 cMGQ7 b|̠}`9o]۬MKkux>/ț&of0LȄy7G=/gZfc^yq^}U9%Ry܂ՆR5H 34T:;Z=}8?[4i)d6,;C9f<]$*1~p18gwؔNKH\>SUs1#_~gB7zEok:1a)'Zoe :K&R{]iOT݂(+!U(Cg_ZZfML̷~8[80.wqj,f.I 6T.]2A8hvΜVaXΛݢ)\>m@tE8WDfa%*f0,lREX~q#., Uy{]5cYdK1kQyXc{Nߞ86,]*%SˮDcnQeEl+~*y 95/N0vuR(^. )$ OYqX)\7A,&^JW4Aّ(v Wi9nH~5AsCQ {OPnkejy%kL yl%rEضѫc{<0OѰt.# {9bF] WbuE{E@-}zY=3~Q&HEn4yFhv}ݑuK%2&ң^G"?y͹MJ)Biv#>ۙS]A7HW;GߘK຀ѯStܦDdsa]Kvp% 3GН-}ϙ{Sg%hN@A\(fuʉ+~Xe:9A)H~9zZkԁi?~o9f5RD'9"ҵL" ^Z_}+MD0)yq!3:͒k9M ?Zi~vԉ#M?`-K KҷPkx{{ HВ6iK4,QmU\:&;ܢz#P5ڡC? 7E]xdU+hC%{cX.'qDg\2z VBj]h3QusjAőCPŏxpWwi(Xo??Zcq8Q?bplFnƟhׇGvgxdaglzcPh=FsCXlFĤOkCl>P/jMq0z Q/a S_'ʕJ6L0Ay*1H,JIq5k=Bp@+lLYsNIϮADsU9Ƭ(\?\fh@$k"X5`SYc]&`hcyT,$Uʊ@Ȉ۝]d;"ɹ,做9GNRyPF86XKIT1ܬ\$p Ca\gQ@D1 E"R#3$ sHs+ 5#eTldqVqgkFv%yXSbvHDVR|UnC!lT"갛xZsKd{^RT9ٷMba3@"/ǚ^2/@?UTLj#i$4Hv,u =ue OpÑ| )@M{r,ٗ|pHb"oKD8=Ɏ dv~4ZU0,nARߌfp^b5wOدb(fXyOۅ؇P]p?_h8MIuOs߾Ҿ=:J8tvNo" NS|JܵܥmOCg%\EAPNgTQ h--z::7Hp"A &pוp*Ii't`R0`$wBkԩq A`]z3k^V7u*_BM8mGLQr 'v_,xŠl;ڌwb=x)>}aXRQSp/Ҋ> 1Y_Y/ZSE[VNt=- ib\:pQa'Βm񵕳 Cf !HsAN.f6C±B|Gk`0v*ϷxEflͿwJy`6|2*E2#BP^[| PoZ8+άp#gwTH:~Fԓ3_ Q !yjdLV|m@v" ݠ](x981 裝vA.64آվCy?wý9}VC[6Q I&:`$WSmoc]dRkJb2 vezXX8SJuoBYơ9ۻyA'Giw :D&2(VWvi>EI|AR;pJ?TM&!4Fsәe;؏.\;(fvKr4+/}JDdxmH+%FWM'VF247.aȟ).DݛBŘ(W{p&V| :et Qbնe>'`TH%G;jF-Xr@T1'K(AZ D_A.1jT݉;{a%QQ;_V' p3EGkIޙ1FIxW.1 !w\B:kxK{}zP`rJKi& mQP[ī'l8;Wo,4p3. 7$0\ɺ(ƸRyh Um1-p揵m`ɾk> u͙5x^/CtRA} kNK>Rd^6jHZn*0+GC` ([{e&&?NI[^776AqWh]dȁΎtHXU"h#KF?e]|_ \1/S8sô^4 4~cD4tw=JFmۖĸ f/zkvBU:2Q=Ñ|U(J* _W:vsy ӖOGS]+Q(ԅjE}G.r-p@.PiWhV~wE]DA;8}n􇰂r:j9mٸ$T XpC1<ԝΗNn:z8,-Y Tb1zm:[~@ hʑP3q`D%exޒکGVVp ]u>|GJCC,-d@6hDb)8nvYo@u!?MZ4+IMזdTP=>guzlʙ 4,b)"QZWNa-oaPp46OY%W/7Fԥ~p0p& 7aն >ϑ l_~>q$tD);8'M`ѢSե m?vDD3ځ/0ڣW4~`C )nCYGZ;zMG;qzT;ݕ>÷öETmQF7vM&^?w@ Y ]x %T5^=yL^|2N\?nVͽA3p<Qi K~Y5 w4"1_0vۆKF=_s B?Ӷl%C[^Scłme0ģHtSɶ&W -3mZ3>HUkh: ,gA_ꭝ c}(< 9$]iגVwrʩ];oC)M|%0_HW9>Unmq!fjwWBW h[ɯaю y#3Esv@jz=θ-c/BD &hhRP譵`;s>S^,EJi9 `NXtB*Wu;rDvH0Q _I_צGssy竏#s@s!NbhvoAN-_^9l\@VwYAAςW G0~ 4@q1Sm7q \Lkѱh pyW`߱GkqteH&){_iU~zFҥB7QMҵ?<=[_;.C[~o%9Nηd@AQz%ݫ)4TԽuao K6au'V5 4< e]m͆PTUKR|P \P6j[ٲO>vB֙dd٫:-(+T޸rKL;:cz_DT6e9ѡ@,p6nש~ T!&3eH3}~| ={Gܸ>i'K N#g̋Y u5\>ю"Ňٌ @xӗHޗYD,E JoԻ$ж=V8:{4bA=1_/a&"d1ubQSmzط$ @nf~j\=u_xcүUწ "H17,F+$_$'}&O3NSPf`l>@f1 \C1f_RN@ LfaZ l淯=ŒQ9#. bh@&ǞrA_0Q-db.EjDžp VXjzK'dؑyTzTHA ltN(vƼӬNtpcĸR#LC:(?7/d$nͯSg]Zu[g.;=~B^}V6 Iz@&zy>>Uq~:1˘I3{9IZKUlnIpxO›Wz(G#fMWѶ;cOng|jYsm5V+.3qtd42@W>E7)tC_i{%?k v N~HиU9ґ 6҉p D.Q&I\T~~0nrd._Wz OtfcT4Eש,gl >y%=zR~ve1S\l~'"d1PO*!&YhذgK<3CeNy-!Ӵy+M=)kYSN#|{'D{gXsZ0~W`ċƛG&@e2RFxɠHvL $E,aW/ϝҠv*Jdbcg\/gWb]1Ru_+OʟHfS~}u]+~wKcyZS+z#F))u|ǟ[}BP5P"S9d.S 4}|go %omFsҁXtz$FW4ؔc o&ˬ iĜx&.f[\BCR2jOX, 2#f[j=!iU:z0Mf==[K UD"[N+n-ʨE1(?ma 4Hh_uT}W+Nn[BQ5ϫ"&S{YLfٟ眘SU|?vrf)/%(Poq^\/5ʦ ޷Ti]OUt|dFhWꜞ`z>=1~lZsKE)d 6p&UMt;uAR ivY%j)]ϊ ѵ9uQd,k]ff Va eO%-XnQ"'cQvd '\5@ѐmHh3-Qǫ4^u@zƌ;? b)] 4];KNW$Z" G.ƺBpVXCdSL,.]AV0(ø=- 4gBi?lR.[w;it:;E]+Cp˓& Q `zƨ'+܍A)8$ 1Z.4Tq% Vg_ Vg}v.)oi0Vq99gI>R r7Vkvp h8ɼ ˝?m;kD^:isj2T <3 O-u 4$Aا+a8B%hC꺼?mο汐,qZCHIYJ )TK KG׻t"i-C>k@GNQ F4zmZ%z" S4m߉y+ا"""Oy>ɟHOreN\p,Oj*rOoAVx뢟Ïl `$ ;e$˥>mDEPz 4'dFZ{lgAttDr;#7_Br0CD݂HL4?iu)$Xߋ(C}[xԠB}Y4 Q5 `$QpiğShӎ\U!6<sH2"OcA{|ΐ[QeƦr5hk6 E&t|hdQil]8>Tj%Bu 8dڵs:R:7k 5ۅze?kA؄-}F`;$'1N+a5JÙ-dòFrږ@d1Y#.%"t޴ ,1߱qxS,Q*`Դ֊5FCԙ y.{SB5@ȓQV^mC0SX➱'ĭ3 X]2H %o3ǫ9 @-"T zm6vX>ŕƋR8ߺlyq63Q]KsȬӃJۢm1+U>Z!,6_j`XAabM9MV[.X5:|dtm FI\B鰨<<:\.d}c# ȣ=}ͺ2]#ǪvtCDko3!\jfF[|,ò n7|z8ssQJ1i7P-78_EsRzw2,&0k<~8pH4[,?\{͇\G?NL{)S`pB1"Bx#]L-|n%Y掊p׀ie52R޵I3iUP[Hrtfͱ)G< JJ,Y/Od$E`xXJpX`L4L=0y0܇pP&!Q摦1lZ)4*j{"|)(i~ /}hZ5#^^>WrDp'Rl ˶7&xVgމ\}͛"ݽǤ 'އgu=s}0`KArno@#*Ve0jzCQ* ~E,Ƞi$\`Bi|'ݿI74PЇ;Iiwoac:[%`b#K<.]IEVe!Y$cPv%}Sz| 9YJB=T=(EMs5L5¹ӑ3SK~9jsJ%[Hޖ;m'Y2v@V]jO>U48iIGNg]{c#n!7G?bZ]I%Ŀ%B=9TFY0dTIe"p8Z6]?_Q~n~j%ۜ;D O<3{i_@:?L~-3}.!:8&WV ^HyA oĖWECA(Gb-+VPa\oXh]iZ^?^fiF:="Ճ0Nܺ&>~x͍o\K3xH:S޽$E 6'* 59w*&QEoj9gA>n;3`/rzyeH͚\[M<*zW)t ,ȔِaRC9ߡۀ##vUlT5ncVO/Z~%N:UgJ 3T6<63ZS]޾ 5aTy=?))ZH;5җ :]jgۢpXGD];lM 8ِv{=B|dGcB] h+%M nt"{fy]4S@2›Jqʻ͡$ADŲ'[0¹PF&`Տ &,r#jDy[}2å\Ov?Q7; ?v+OkI,k7*V?zG FE!'޾ =k a>ZP5.<뉁]Y*@ZޅD#C֤F+ghQkhQawF֋C.ӈmg¿_Ifm4>ݦz-؍cr={#dW@p%.9] V tKE e 9ɶ%B,C֢ ᠤ yMkt뚏'~ -"M<^ c.6qRr&[wTyD)B..`7N`8ō!oޅ|H:?lcԎQcTG .6S/:5E@߰0RKk|u}(^OxaY:u@NDY8J8 K074>5u;~v} }[XA}ż:?\HZỊm9\bAXDtltYC[HvH*uqkbsgQRpmhy ږԌFHvTw< {$ ]nэ1T 5hm:"ZG@K6zA H@Vt^qA=NCkSc4։s @pTsۆY bQF/{.mATx/ɝ-zƋWGiנf 콍06\$ͪ6&D(ZF%Wlx'3R0?iZ}䞁#Q&Iro6!U!#俆hc(#5ɺ~4}X~< , 5!ߜCo\0ǁɗ@vԥg\̀*SNC&SaǻwnkwԔ fҋD;ǪRPUzqҩ`U@k oň5#s Ok$hWG1Ktk c(k{9uF\*bXwy @Q~gB Q.:8!%Ldu~c=AI2;w'̄ykv[(h.h%8=Y4d_hv3'SX@7.Pf>-ZgAwa=i5B){M; Ab9?(YE ŕgUJ~Kdi]|=?vQ.s9l_ڙxo_䁞9+Wdфڅ.ƪc +ut2zvR rS£RV-S2$nx>sSt(cT0XȻ;N>8Kx=JE৯`OUԮ5x'ɫY|G6*0&Ywov%sOk򤻜Av8Bc˟ͷ"ZT*#7|j{1MXHjWaK@_i'+ƕ?#+@Ir~ 3qu"uQ%k|w佥G2iY3ލ`aCZqz7E&JuLc*χgHn)Q/b+('Dޒjc򑏼^b\iic.oIJ-Lg9C,j(ޕAAi]u|rxW51ƍ[>f<' ']ZS!"eȹ8xI}x!lwJ `N*ۆw-4(N3 0N?pU*/}_ַ3HEF;cs\X2zM'4xZϜ%! 7|$7`^Wis.NpoF i"[KgF-Lw!@/t,3diLup]4J)` )uL*]I5' IHjdI+/OmNy 4LKifMʼn+ (,#;$X"M];-%2stMTM[^c,f(\iBn5h۾\D7o;@@ۅz:%Suƻ8Bo5^%Hq\`.4ogaf6n^@o _ uQZ; ^Bs$@1j/Rygc-,<*WC,M8JcMl|Y:RW-QY0PBq+f\{4E>!H̲,P^w ~ϣwѢ" 䎊qWk>nCVGKS1$ŠЛG]~}C> :8'99+oR-:0|1TPz3bsxaO ,o4l_7Pp"ó<5m'`Q(E;fk\hc.w; t+|kT:%5n25.T }5Ở" d7BJDWn#g / Aytl^|:Cic%CLƍ}|{'\Vs-]/ϛ%;N0N_}~45x?BCJi7>b](4M&iUwO@̭W !'@@gUr\Sj."?Doz]=@ix܆`2~`5ǜQ"I>h.Y_SŸ +in]2^l$qvD[dwp=e 0 J{u_U 8WA!00Կ\biqk>lTr/5`&9Y7i)>:7ZK$1rIamj w, MuswřixHj>nSr, j)bd vr0:Q /JhBy]8:"d&UGK&0d7 j:գ6alƋǿi◦̼"Y,*bZ> rd1X.JFݘSyd fFDOQkdb}(c ŧN>3[O^4s(1YZԐ)>1Wb"t.[yZBb(Fg!&tI*H.GeVIŵ<@⑷Ws~xUzr女M;qY&I[V'_U#,f)2wJI (!ժ>#_]]dl|ma*".9/rJϾl.04;&?Dl%!,!!fSԂ&JkX}"Hz JE{" +.F (߈8 ~{»V/pPfopz䬖>k:@ ߍh m%g0J}HoE/b#n)`ӊ90:(}{rCg4vgPj9.R|@ЦE2&?4*-GZ'xKwd.jA㻀yUP,W\OnR8Xo)wŘٶ?lQ 66DNsrJ7ngѲjb7( ^Gƴ{0}ifz4z<;FP]K,v!o@?L"GOkcc#2t`"XxĬ-ƯDV\ZQ2L6 )\@ 1Mmi\sjANP `'\6{㢒!ؗc$j%CE}cC AZ&c@I#;b?!6)D.Jbas;`[7 7gXMݚXܵ8Z?RsZ -py*c.Ž1٢0Drv񕫾ՙnr&[?0󵠼\@9bَ ?[WE$b])p"@T~Id=gf {49/(L<# &=wJ觩} a:aLvFb! o[6vLE/ !)5aHYX&6%zA7:~xb, 59'_bC;r~ɳƬo}K4cjCftNx!XT&yɲGQ,a7i$vPGu]&mЁPFԻ"Rs#Xxۦ@uD8^-."fop| TyYY*Y{4+0:);t,WUH]3>bbxQF<(WHةh:>Sr4ONڌprOZljSu*' H2G({,i߬AYT#4FJŏ<;0YBQ6ҹGJ5~lRSWUa6J/@UʓxL髱ɴuAnl$_>k47 "]~qk 5C܅D '/rHŧbDFwv :=wxY$t!T?C/dMk?H d '0/ʄMEV}+ki;!Җvv6#UR+)%~93X$YڀuclJX WiR|epԌ، vZ pLOJ9mpq{mCX.w΄sipvG7|Sz-TL(+}K #aׅ'G r&_, pJSbem^Ȼm)~r4v;t-w*?SQz-.A9F5Jpпf[JI3i2% &ht}`sR.%?(Y߽BCc%Eg !& PJC"B`äm-+YQcq^l༶-''+Y~vpCz{.fX/oc[rBM7嶉̱(ѰхN;(*UlT?蔛 ox&d:TUFMy]+N e1uM\ *${G%3>e ,ΚDAhSLY;?T+3Jԣx4{eu|g=c02^v;w#^v|lf%=+^i=lC$š'LU ,L0AHot\Lj~fXgغE;, Pas6VodAP-㦶 I@ %-9ݻq;# \70S0R?NFcr+h2EX e "úav=_\f1--iTr(4Z^: @|FΠK֨,][b$YsM"[ZIQO?:2UlޤQokN2yؠCU>on=LH^961ޣĥ0Oơ[ tȇ4${rk @UO1ջ}-s OkV8-JuyTs B5njւLQ@-9%E(mҚ31nr@\B6t#,3)x,hxDMVe-Z-[|CF05쎿xK/*[Wv3)3;l\{`  ,ـ(SzU0y+F‹}#|4ؙ H:6T2)5%9L5!M'r*8Fe<{#%Ħ9 B8CE^=Դ/v'#]dGpҦOu^=4I"A6PP - lT]i> T:w46x`yax69VD@X;ŠّC 35B`E^A AӍ~0(ƀ7sC6bea12 M>~p^k HS`C|JrDP1R;mg٠/)ҝ7#2;Ac~#3D⼃F{_C!%,H9ߋr(,cGaۑr3.X#2{MyE@ШHN$c7i/;W'J$N/ }H%] ! l{BLbgz^`K]M.vfg2m[V}&HNJ>DV7т;ƂI}}|/I^KKw{R]k>qscOE1bY4T Lz|]tHMsxm(@yLԔf\|/BAD}#9Flf$U) %Xqz9jR7y/A?NI& Dۺǣ1;m4.B`QgqEdҬ4su^ԂeڵsqjH21-!]%#e1|#`ﳨ1fѪijs<[M$RQF22Ʒ><]tT/dg;zM7endU{]9"m*y4W*"̞Bu !o8YzY>omN\>gCf3h<+rnUg#&Pƭ"d3P +6Ofv$ z;섖HmeШXӒQDD MKl6J s.L'Z+u^m r3J>)^^u3  !ďw;\ e>wy 8t)TǀIOϭئIE;>]}3 KIU_6R$wPUl# )kOM$Zi,0zpƙ9fņ$0cգHsW;EaVBCJ?q9zWin.>"JJ P Ɖ Em xGOQ#953IE Vx@F$QZ"TgAޢl]u< Y:ȓ";sJ'|q Ysdd&6ˌ'Y!/l6ʵDZbË%~*v5O=袓Hӿ}=*XaWM0yǮl)']U3_骚 <*@+t{C ?L`R7ˈo#, .IӢսUsI2h0e XwOҕ9[^Jp]T+-}[$XJ:Yu(,և7ԠL#$ih̤ [ӁJܔMЪhqad\\qڕ^MX(2_Wa[,.7UwfJm'b%kpJ3I\F_Xa( !ȭFdeH!ĥVB[̌ZJ">-nkIGv![*MnLx _}J^# 78,inUME)S'UQH若D?(;: ZK+:٪Gޅ_RƘ3q(Y}~CM?2bLzV>,$EB UDite _,FqK$g"_Fu87˔*=X`ɹIх~?)FO(w7$Zj}8DC&.Qʛ 9= Us1;L$Q_'f):]gA4jh`tYB ?2A\YךXe({WTK],_mQ Q( *KLY#2Xm5'@$NV|G7cw%gWY.z#ȋ/A=, =v_e| r̐B]oS&j4p_Y"QV ъ';9ſY\ODUgWE%/Kux)c~!]q;jg}nE@d<_~$ |h&UWƳi#׼o#} ZD-Q]pU!ku| #Qϩ! #foa/gI3"w̵j =1\@- + >SU d1K>hg}BɻqhuF9ۂ`=']bnIc&OEٓ=R G+O6%*w_ףFj']6߶~&F,x5)d {) -p 0')6\Y&[ l##qh`ZGRK:6<ޱf<Kbp}>FrԹ@qaȕ.6ٶ?ho(;ӦXi ˂#U]x냒ic rumguN޾iDȼbZP".7H1؉u;D(}̘p.vbsk@A0n8Ee,nt-lF;Mh2EFgı0!ޯLU7/@yN.qD-p+HphB6d/=rch͚MD0gXoєL0|5Ms)| Y*!F1aᖴ]~ Ę''ZKxgnzU_SUl'O͔,E:Ǘ,SE53yUwLPgժ0|hk"IDd;btL&S Jd,i U`w:ܓY:iK^vJD.'ݬ=YUKl]`$K)5?,5.^V3sDy]. nj~l{Rg'HT@-ݘ܉ڌ"fՓ)Ր1ߝ~c-ٙc)Um)d"Q\*vLf_jdvIGWcb}K#!ŬVUt>PB{D ~JGX NR=Όr/B'B%|#7CҟU)!$JO  /0V4^ uඇz* U6"fbϲ̞&zq g~Vw#cTSf~}\~nYgPnKe/ٛJt<kKr@w PN~u~[0jRR^\LoHCx6%f-0f d h_wD@N2v[7=fMAE&`MPNYio0~^ɈܮUH3IR"hTCw\&=pYBu 1䲽4| W8IdJ3{8WX)7+,X7cQY} afn 6 W@vԕ׺=$'"VVÛ7>yzO_VwߢKH^\by6un']Á0,6vt`|VA!%808j2EB 7)7lA>J34NGRj}AB9`RyzF@abBFq,v^O| d~N\|/D2_Ǡ؜SݙZ3tS gۓMrʒ^`?@vѝSa:XK즣Bd Փvױ IG[J4eMiL(Xև/jm*~9v]V琕nʉIJ1P݋q/v7m b\If29s#Ќ&&)Fcȴ ."S^\ ^ "ΑzQݽiP"'â#.Ũ=쉤Չu2F8()*r~o[*\5szhFKXg+$/<@u`Bh(&픛!6D۫zY:+Hf0Jzb%$ߡECO$iޔU-Fd1io v x:c_OW<'hܽv7ʆ>$t94o[_AJ4_rBѥ0[=dBNtyQHT4.+ZzT! T*W]X,0n?!ucћ;'2 [~2KhL1G^wan3֬-SL?Yt;[Վ)PJg+AouDHNbH 8%/SzuI !Sڤ㜚=#Mw+@rCkI{U4cN?dl+" #=XMCrvتR[vgV0'?Tc B*zbIQ*B=.caHy\IGrAdK*c$W]G?J9GD1Oӿw"m8_/^0=H@|w뤷ُV97^,̢$LQ*<Ljm[w$[%V?=HAa _Q(vS_8(4uE*MP˙t/֞Hp8){1-!Oxn9)=m ׬y#˘ӵ O>_%eCiRܚl44p7oӏ+ l{\9т`N\|j,x]c~c H|2 X3yN#q5>1{Vj_nZ{qAQ i;n5E7KC|R{Gej) "e /JfyWXi| nP1*c0sy>Fʜ|ȏp}œdbg\\jI@g?gҹzR|DߏΐVI Km!:J]uJօ8w>s޵e"_˗yy=>Z]2QџXiuo'g춤k{Y}R|x϶@3;1 E2r!=R,*lfE + BVKv$joa! n4<6c11 }+YA}-W{YFk3)mWCƂ P3E 翱%<'Rb7Y5J\oH#a[5,- ~owG>Y0hu|1-IG.E @eUp>px!a{?T)vQ?"L P *o~mt-G=}+%3(]@`2;~S~W :ҕ1$ʖO?XgϱB%PRqxުF+jAjq^}W1jҶDjsZ6cj[H ksM)#YCcJ6ČPz&Hژ0Pe+Y=<u=7k,' RydswFܳjyR*&\R~ e^?uϰdkoef~{솳? S7OhS[P. `~ӗPd+vya { |}wyp"`dl8G &kIg@!bB E^x!H3ll6%p uqz,3΍^瓔pAONmASeyްXo _oH+/x1hbb(1#b3zؓXl%9Ji&Da[xF=}=%H<<^c(!J7*F~W ynx& m{ O~($MHW|x+`i5xZyXGXD{lxɌő7i*TDwyH*σ c\ aL"AH^ lޭ Bּo ёgt'^YݛLZzn_]O7;~ [EE2#(jH3N_Z':\uP1 X=VF*JK4`- ƌS"-(Ь_X޼tk)9 #y/W-"o؛'dH8U bW5 co8,e&[!+⻗039KO^ ?q]{Ce]hoM2 MmǟSn@̲^4_lK&/Ոmc$@GsxVV:C/L#;\{^/!Ț;)v-pֈtņh'y6v~Z3P[چ%ځF]p lqh .4'>_FHq z uOSѮzv ^t-[p(@b +;XSt(2'AÝ~(qT+qwM{5R } ތ|FCC2)tqͭ^CD '~iq>> PnE@|; 9qS?}3+=wy;6܋ƷC$iGjՐ}#K U $j:?0?<͏Rwn10<lj싹 _2 [a_ 8tn3 nbÒ$u[O59-SQ+aK]ǯ.;Q0?BìLFDTA25rn )Uy`0ڢC$)NQ]D|B C>hɓ`5UWA}4j8xv{ ·g͏%ڧ@|y e|Vww:lϡcvm\`P-.HD>HGOa]+0)A]|y4X4J~,!5ȱQR:WGz~E 8TpPMT7'kla oX^ج^'vѦpŧ{Y`:T&A_ &+6Б˫{/"Ƅf7<=3}2LN%O*2%޸]Y|%w^a&d{;WU"MF řSs$@OJ)ӵ|df$4Aw\JޞƓ}Oz W$~o ģ]MwڜFF7cnC * . II&w8FvHը̙4^ {d9.}0'f NxջW 7W)Hwx8Нi9$F/,?(k;|0v"Y_H޵Ffjve,cbTRF)Q,qei zȡ W*۲S..Q-cv"$mL%Vx.]VLE&NPaspqZ탺Ԡq` h˴ MF[IzQFt0,k)jM yzh U IKbAVN/= #~$66<f_#xG TT|,~Y:]o# [4S`ffH^h#IBK8|/DcdMDU_ciE8߫9gB_?dHFMXa NŊ { 7󸾐n@A96||I ^-l?i[Y]wo>j`S֡bhhm<(1grRI﮽=@eIKVw(qJa:sbߵ\%TA'px3/ QEѤhLXڸZω@YB9 X}0I)iZ|.L!K MW/ CB}>gx*`p`OhIiDf/ Ipn͌jGGHn<~Y :]Z.WunjXrJ^fƽ3^lV i'sFK3 2ޤ`:-<3$k΃ύai)}ڽ"4"ΚçL4=̔xgɻkf ۫mo"팫aM1C.Mu,#Ίkhz-d8( b ނw< _6 6F/ga@c+>a]?вYz\|1Y$JEܫF]l(8ZsY-E\s9oƼU٭BPI+I0 Duy?(W{#mBľ8!?]z5eQOںU/6a؅h w#Tm#H*6ョP%Y؟\?/<|܂@T~:BbnR.DYyz2Ӆ_&l޵ohm7ܗu@|^(ID݈Ry$!&h _:{9{} X-᎕Q( tvE}ES#ջpPG:Q0Q+AS/zȓ&n^.`Os*gk1ӓ7}QwA؂%ޕw|XtLjd;@LGp˯1!hSe{vҮ$*\TeeOId|:)$Rzg\3f PyXO̜^ lx(a1)n=H9ML(ru,TW"0F<]>!Zj5B͉ձroHFloUsԪ pO=kq̥O\-f:<,%t,X拔e=ˆN)pKv6x%qوV%7DxOɄ=hSW6Zp y>i*+~@x_+fòaK~/KvDu ('Ɨ]S9ԈVĂ{( HF8]Rh7U&F,R$_)\ 5p~IV#PyY$-h&'UŲ u$/-QC͜Tr|ph ˛,-* r\{Hxwn>PJ,5ȋbFlO|e7P= '5rs/ߥ-kۺot5|dMOX WNxƮ~Xczb )J"w42OZI"`^p?t@Px#lBQj"],D;d5cz`XǓJGDwk)+iQ_{#DBr'hphj=zLg.[Uj@:ȹ'eƷJa2b=,3&(tc%(Te4ZdAu0җ$KɦW^\ R2(w'.vb*sCp,$ p}>H߽2 ˰Eh'$H8jCηMYH #xVOs%LClˡMo6WmGԝ[, r/Qicߺc ~ ?w!G@rMi@ۍzoÕbKg`n,i}aҲǓE=fwU ]2wvF2NYPJ% ^jZ{γVpd̏"ƩFZߨKCqi E(z~6L ,e_FqJZݾL [sq/0VjTs?CO!V()A9q~ݾ'3"4i.2v8xTed9hayiE6 Sx2+$*9뫼ps9jVfQџ~򹛚S,@~"mE%W^5u٪j>b6KU YL4-jӽ}\t)|@RU VEU j:>KhܴzW&Tܹ ^4 B/sUfky)V)RRRL~,r!m;ᘌg5Xhua(e!k<:Pdv͢Zk!5|6'룞<iX Xt9<7tľINӝ-]4f pu6 odv^zZ߹O{gS\{²w{Ĩ]G[s8/v͒n^X6׊>[; tM i.kfč}M>kpe)ؚDޟɚD.2 .)mU h.苌$TXiwրe:g^j=5Lo/*aX9W2?꫱hEҒw|9-jQr0S|l;5M%)iS .nhMɏ l#~C~LiXBh= )+G8kB{>9~|yPs6k0ڿl;fNr"&\ak? ER?!I!P<7o~JN 76ޙm'P}XZgK[nhN\gP_3EޏW8g>H7Om$8/~iw"Pe72l(h'G;ߺ$4o1`nӍdtqOGfƵ۰;tVMliphK?g9λAۉס_Զ)<, .>W҉<;^4[“A⬒YIB܏&b#+kCd3N]콲}mD@iLH(-wD˹QQ~D?v +NSw ^]a51]Cz:0ᗑhk˨n!R=K ؊XWM}ZM(=eg.B"cf:qN\o3_|ڤ㖹{Y<[,m07^Dj+pۆ80UL-6;Wuum;2^O`y+<<#|Oֶkݨ_ ^J8慾( _eNBRn}M2|Bn#1|-sB@Qvjv1_iina[]d.հ]\ݯU5.b*C**hۈ-&iKR(xp2bU$֖2/:C[?sI8,u qԟ!vϏ\]}Ċ1 a>@""ɛ:Gq]Ql2J~dUϿ5fU[PNp1k ~IO8YR6^Ռюj6*qWg"OAsk6p\ $uuxav<]W`?@87-Gp$u.w6줡j0N_n[2#[ྭ#HLiDi Ǘ^MHkJKD]y{I7ttchX OA.@!V|ݫH?7Rԑ%;I&x9s!a[SF֏ZC Kp원uNF.[r'OXH +SkEP ̓ZoJjY"˾Է ,i4G?weҿ86m(?)zC^,NpQ]o߶Y'K[oK+8̿G,U)dͧ{8=.V DVi(ݔkY`}`ߐ?\jNQ v%u`5C`L5uHCq1ޑR%e+H0_n@x#1j$O}{Wܦ|_Endt@zMLqUX=|N@Yz`t6د+2n{4v)-{@]0qn+n7l-p|ԓ-p?0Ӽ~ 3oޫw<ܐ;08istTdRz'bNk=vVMס/4C;<چs:D lQ #`|/8t,XPo R"7.r*b6N۝qDOQE+r@rJg 2 3I 9Οഉr3=rI)agiijhΫ,˃Xۢc$ij }z#giQO'(DMOÁ6Y\&d?|r3iִg̴aAM֐zo8m@vl3U׾)7ȬmOa|*SkmذrcsӮγz͙Ȑ8.pz5;j;aHFdoe?X+RpPݣt[KV֚q90ׁQH2LJcAG܊޵SdhL~)ʋf#jxn6a5d(>Y\ncMSS{Z)胻/WQXwpG2ihާ{c7xOUy__@rS`j.-NZ& 3"m `/L 8&o6NWN"bIO zM&cRE}3:wIt4zcl );eY ct ?8#Y^<I]"C  9hՎ`- Pw0ƺUjGoyGY)&,lWggOY8/=ÝCkƇ'#6'o/H*o̸VW!8ȥSNtn u2m%U;i[!Ws(_UGN(x[ذЦ'E1SF~p})NtK/nK2pTdoҭk  TPHv5eMxFr9Y#]U];ցpCidd_=v}ɕ/hJdPh,uqP2'bCoZ(Ѳp`u'3YK>βc@Rm de9oGtiϜYv%Nxmހnòʴ^x΅b0oĮO^ۦcbD-E$ޙv8t2v+1m:wc|Ƨuʌ _h)tb`1*H}\5֭,@n6x# )LΉ=ǒ踻PL#.큥u &Oןy0Z 'G9΋YBd)elZ}) H" \+hy| L-s%JڑIQ0G-H~}²>͌A3XCqÉzÛus׺n0 ߲n+^0ɢ@OOuI40+L6z~6]c:c/P\s"F6yV&3 CWN?uEM )EI]Ɣ-3@01ys mai N&,R%gWI^+%Z|)ēK _j=0-@)+Ύ %^U]Ҥ 2đ7smJ = ɼT" XJ-![-RЪqC)vBIOW. )]quz=]H}TiHo_ +<ѳR3'i֛kX? trQJ&>3lݖ͕?S~,&;n_ob|mNʖSFBQ﬋P=-|SW/a6C%]ÒW0<1`BD#r3)e1#/+B΁A$ЎAk͊} -L,+tj R1vhHz{)Tf8 Ί}-*<3IXR&egނU8A` X4S P3+S=!}NWi FC=TAf0)I6My*Kݬr:{5^^ xY +rDߵi@569,+ȥ^)Fm0B֎R6!Fc٤+4G8/=|/ [r$dߘgS<󑡣Xn4֑W:BFdQxgqbJS_^.垯G!@ +%ήxrOQF&sc:a׵TStP0grK|?YᆴpRhOd'Qpez6˦w܄r[%YMx+ (B14:# D&K9be(HS[~_!4L唤!o4yNkYV;y`.5r4#}~st. D%&S"ťsGGMwBfYTn I\k"K\Q |E0 6uq1prp*k{ fnzĠ-tD::ipDˊ*+;ݸLhS{ښ;AෳRv 㰴eu~/=Y|w!KA $%.OC%c\]%3W(kݪxƶw">MVɎ+%x"%Y~`_HEF|3EsM(H rϸ !)LCTqq=KhCTbicS w\ A36DGy"?-+ Z}*^>&yܳDa^w)!|3@/$}a{2|ր6wtL:Yblfxr&4dZ8PPfcfa:9Qw; 3/ʔbuoR}>tX]-J P^MkV%V^,b^V\4᩹ns;ejr(.IVhxU%n?5p׽sex %vbQjz-gk"M3({[ pR.(SɅ_2,ˌEiO*x63Y0XLEtWwr*~\鴓l_.U.6H~L$?}99݂ _F/ŏpyV}p#ɅѰ}n?Џ06xtb m7;,5N^zak&З+=,K! ƒ5c2a"0Ux&"N%P\' pFaԴda9ww VD%L:͗73$މ(n~njn@H "COwCvg>Q>BHw.rBO `c`Qmv˯`v>a+Le6֜l*j!i >nVOxʒSw-;jf wy/|oشf>9t3'3~yYH AK{V_AogVk>Mҙ KzSG c_. Z4s֪VVNt3DR_5Fz,chnB"XvA$kK(-lnȄO2*hL}Iќ/*E*- p4W.decA%w.%+01O@T7#r5}9o~=1,.0^9Ia`@ 6}UXv@]"'] !BF#0t\TH2m>Xl1c:?7^q3WK\J~X-~fQ/NGa)e`k:sh=]oWUeЩv.Ǩo_ $ 8!LaX)'Ny ԊW=vWJr蟥<謘 M~ Ѓc+҇SL1hFǎ3ԙeT {2t#p̿#KSzL}<|7?ă"l4.+_ 8= { ) {C~ 𥩘c{.QEs Ɨ49]|_| l!I򺹞^2rٞ˕> ׀Q 欩>: gPJG%wJ/i:AUy лEE*04.ëJahFFF20nEפa6F҄:c2͒Qٹ68A*B(+N xȼ'|Hr5>b9NG8ؔ)5{s 9MYcR;{tMYR & |n +>W'TϨ|-& 6LW>X KJlD1ȽZua5.aQPjmo3&wȃ607 z.wٓ9O H&*IK iآ zDMSi~ K}CKTbxc3{( |E/wS85I{{>+og3SҌqH@2X{k/o};P8R6}a&GQ kRdx1Z2= ^@,)hK*%,LV!N Lf3h,^ \#߅/ܮDgvֽ r>Іkf%kuh2= %M. 'NU1=9P`},u|r`$]sœl7-ȴ,%w|3(70a|B"؞<=/)eQ3I( }<^Lo`SMI]hgS 6UpkP"1-?{a pPaN ]FR tR Fˇc]_lxx4}ɯ'{rc1Ҏf oss9Mod0ZN2oU MGzV6*iz2Hsk7W TOOyM} *[7R8Dh;äC/xa Fz>Ph =Ȋ[@+"-? jzH5GVYJ^B zk>os/se& 3߱rR'F1f–~U]ld}ZH =>=3 R+չtve+E/$3 ёNX!Q +UuF SƊ8h"CKʓgZnj0nus/YE"6ۆ |Jt0z2+mxO߷X̭2s fؾf"Pj`kJkNeGc4! !:sH»YqAn~fs oD݇2B4cveyqkXAyzȟU횔L7mSɱ4\ AUtiNYMCKx=bϝ)>6\ō|4QҠ9<L coVSYZ)Z-< m( W~Ă`5Jt fpJX2H>nW{ۚjtLAr9|~:IT(H2~A:[ꆴ=s#)]{$<e JY&>]?dzhwY.ozt;;HAw>ls*NˋYm 8{_O6 ͘@G>z%"D yN9)14ڽװNv;%m%DZoO9]ey/ 5vƨއڨeLrB1I-4QDbczkNsP3ИGbV;;pVuELڙm ^9Bw,1iHN.'EeJeu/|RUjCc|i`:g,k8SW]DwoT9S0k_*Lmek+e6&ƛP}j9걅x73XKdWʞ涏؃jܶn$4\߿*3۰)v-p p4;뉸%ݯ%3ǫOn"4^߄S$?_Kz:KLR:Ƃidi@_uq١?Ҩ}XQW5D,DVJ!3AAc o$[Ke&]̨*'mZ8]#OsuFǁ0,FyR)s+P$}ɉX݊ĪG8|dM( X7[vXɏ2{LARRXCn) X_v___GKv`pPX/]$rَ/2<ȑ{.:> Io_%qela&mT 0Cq3ОAtLgbRl _aSr}CgHW?0`RPGSaણ6Q{ψ Nn&]<2MA 5\UƠ\B/ _`am3"Uyҩ'-Pd*GHD>V/_Fq{J|j`:66y_۷,"/YNȤiee: dg+C/2f6jPjOWcw_hY_Loh8JUL9(kiY-j #ukX޵ڰn$:.1ڇ8?B=9]@;,;{MGXT9H!ZOLTj׀D7pw* T4aCoPw1 &6PJ:!P8ꌧF`SLj0?Tw];(&aE%lgϡ/_ ?v`;e?H`vG.`@*Ҷ(y'|ʤ̮8 &Ēr'珒ԟ;*(!01A|pf;~Qx fTSp"#f+PD YOZ&J `sEO)hj֟l=%~rM{[5>!~.{'_Iĕ ,k5(KM;j+š^E`yjZX}y[!1AgBl=τ4i5bXI B) ?,3_}a-WP(G"V4.ɔ/qמ/ V(>/ 򄢭P#m' }` L%%|̨//+ ;;p<|FYA,|*"$%YaF>4b.0a^Z\wf}8Q;[0'qM?Q)FAEw7G<19q{LsF1uxw'bKHTzCkYg[驧nQJmTrThA`[X?'y_9'NfDTXOIE燡MqwC!aB}Iu<nߗ4l=$Ij`υBbھdajC^30Qayj8ưD4MG0E^#^xADn7{3s{m6c*ŌĺE* t5R$΁L8󬸚DFh4]VTAh幔Dw=,4;6~т i[0=n5 Ʉ;Lᳵ; ZOJ`1׵@Hw>>/ kk2 @u*͛jm{jOO{PiGCa]PPb'qpZٜa圫B1 @K͓TmH$7S1 ;U" 2E1n ss(,6 K  QOCѻW7v#5T~ ŗA!7n/d#_*B0!./.!&PLYY|(+1!4YxV&FA\V.[0&p*K@S?/ﻅ_t{`(b1YєJ^ ε_l-ٛ;2G.w>s{=H'đf5GͣNF)t.;q SC/uMm- u" Sҝ7X1#v;za=D?)gqBŨ <5C]PxxSU482鑽DŽ"KSU3CdW㖇Tѐ&rIF혦f膪Z 3Wp(\*/- dɫ7{\?W/.KAEEi]d!3E6(jy~* 9WE.;5QWZV֭V~_ө m_AV裓_} %JWix3D,ti\ NLgڈ;78rܞWǢRa86  P?ȚqE {:cfdHtdG&!z>˕J詹(Aʷރhޠ2A O<,h>Gg2x\ռTCCT0tX4ן Y${DZ9&hDLYtD; SM7jkDg6;,$c?#A #qnZ Gӥ1$}[$l#hb:إT3iBQx\|M+!' ĮXSs68'9mâ3Q 3_JK[*$|I U:mׇ5]R;꿂ixs@9' =?a䛷FЉM.[^ ?/t u6t7vԽ2SP城ϾH}._Tg 镉y@ YZHE};.Y=ZBaG+2_wd 5MKDA8FuEw7sf~J17Nx&-dž4rϻDP A$2}pU.U[}qd`Nmw@4{I"nyP~M-1UZDvøErrr9 +jTV0iIo$1:Z~nkvx܉ {u3~7!OjmǼXIOѷB!C&C&{AcFqAġbkh Y/}Dfz3sBUN"1]^W@M^03RX[J_dp"fZ%fbEYeԏu?Nfe/rR$p]EillLo-.i(4Cɜdݞ呄π#[hQ=2}<Ў&u"5%纷K|2nkEHة[_ڕpQ{!tݽ<ȼC5TI|ŹTkj]ckLu:.3P |6曣B蒈țmb\xY8,(.Yw'zmePK,l`V.9Ȋ!j=?* %A,zy~;74BUU#}FN,"@}LW<mJK{+#X#;&#XQ+,:_x{&['o^yKp׆`,E nZZ9ؼfuc$ƈn aۉ2/Y m$n'}ZYs*狽A4,ѧRkqkZl?8B`uV>ٍC&yJTpa^C㚪 }펀MΔ&C5ǿ9HgD4AH[2g._Q_hqwECۢ|g=\Fr`3}eFpSEJ n =,Q$lNŭv *,jowoc1L벬i{Wm!' %L䵇n*U#e,%>=Ŷz2:pסR Ju\1R,@!3- 8ySZL*]m. hTUd2j9kn{]^U_@#*г2{TŁĎ$*HK/ݎ}>oI//'͹}:T/X+A;ct$zƙ-"[EK'a5 F.1Џ8pBX"* sKJ_m W҅_^n<]oʺBbHT8F3T_ W]"v_i?{"xpn0g(ھ`dwPccvxN-X|f9ktp9 N)}uN;⃘"!7C$F/őIu=p "r>E{So-̶JG,yټ_3܀fЬxKQQBXjV챱pg]o8kЕ_ U]X0'f~ZX/8yK/73La4 4^FMkS^Ou@xJ[("N#|jz-͏MAӪ(3 tr@aVc*Җ7>^o l&TbGCo=6\׾HdF'Sr  400y[Eo rUQ"bf4Q'Ϫf Hh:t!= iC՘}oZdǣ*+S^I0h\m-"&f67Nf JǭG|쭽'{BYkom5Lf5/ll@~8|t>9BZQ/ᎬK7f/hTcK5lZ\d][nzG:GbX]Q}NG'mZ=G Эaa"L&T}GaBN1w9ܕW[a Txv4j r`=#C2(_5 k\T̫E~DAqmeAY" i9/ '6V\0ibƕC%q}LSJx1SRfgۇ="A!75Zfn \W{}prƞ2Y,2/P^GC1?]i#"N\ug :qoKyW.$vך!O1!D/"2?3[Jn܍c0jo}M7nY-#rJl &XjAGz#\M dN ] 4JVi)O5= Ek`xͽ'ba+[WS􊄅帺~N꿈 >LiΔu#mtIٻUJL^:MDzVjr/^zMW9}"&4s[/~*rwJ.6 @~C'1VL467=PAbwGp 9m9G8 vі`ozmO(XXZl)17rBvfze$pKf,XR1;zR=eM@NNLY~:g8iElsI/^yq93ˈar68%kb= > Ǿfq?d$*ױPi( y'-,߂LC3F$m6ThXT?xbhR3U}1(Uc#!c)G t&姲LLc *'je4 `--Kѣ玤iZyó` U/:=?pGcE&TOIxDK#z]UMdFfw5zÐѹ8 V?| ~;%* j+CXeV2!tzz'q ZR̲A׵_ɍ7/%Nsx' bH%8'ir^[x:H!&-KX@qv7K"(˙:%hNtqT:/pҿQV9o`j?Qf{]:~Y*ЫO1;p |OPУ{r5i|ȨePI(aBe ~;^/uc`cE'")Zf2/("UR Po۷s!fƏEd,*Ȩ( i%%S yVvXtL$ s,)R ꓶR3 (hO k:&s)7ڭa '_m((%ni!JW-$Iflyvi7n$&!^>bW :$hp-Q;cu3Od ,SR'ޏ>ZZoqE)& @y'ߞn$_Nz U|ցMv<= c<S%b';n3Js1|kp*f_?6H7,?Oɧ :"9t?sзd7!˫RE,7uGlUɔ_\u( P꧵ Ƥ˙!^iGVkmlWYw<^D$e]ENJzG%𭛞exF糵2 1,[Iup4dc|Üց#SI"7+j)u(I CR׷f*._y+![?WfC Z0$cٹ,v"9KP\eu*,#A\J)&8ƞnQ?HǠ7Pq N_VO+ƪ~¿P,rW% ԨwZB"J2LzZ OmqFř悭~" ?eHbg&һ3 x<޻?Sqx?s\o)}n<+<#INkk]1&W9T9>T1I^ɱxps QEJK$J# aɄ29@HoJ °= Y;_,"·х[bJ?Kڍ'A?Iq)`"ʟw oB;BAxkt˂Ee*QAz5]ܭMUÂ7Jgzܚz;-G0#y3J+_EU\BdHmMPicQ+@s7 Vb| 2B,W [yБfU !]sHNT̚}̴CSS |YMT5xz*nqREm)1IOLM?6М,;}hH;K Eנ*x ]tpd`Q`D $LӞ;Hh2jm0L:R,FX!rI, q9}2QeJ֍`|HCIT671Aӹ Pb>!#8n&t0YJb=|*^?dZ? n_Ƀ,;`^dOE Qc^ 468uw 8 7hZi-k?C1yIz.8JяQ>F6b{rsM @UŬAOF|K(a%N6Ҩ!LoY[lz捀4m&0KI^f9158Vh'j6aQ1 7:4Ҡ/yi=b,3h2e`7Gx3A3 'DpҶ2NNONc:3{Ѣ7jBl`1'Gӳ›呣$,}mt{.iBǠ!9ƭvk!l|*w[Q8 Mx_bFeΔ\R2@b?e$(hHD/_hN ĉ+yrB/=rH+ǹ5ˏ]ҤW(x _vy\_j<:Q]_ R1S[?!W:"TgßZ_GR~W# 1Bic!ؓs^m\Z1Ռڿ1o)eSzʏ6SO;X۱LxZ[?x~g Yaa^`R\ЩH`^Aہ|RnA_Tsh 8z5jTb6gƚ`P'w_mer3W)rc D 9/Tk> = p?MG^Xs|yir}h#(sNL `Yk{,,+Yc/TyzR8x g!5?kh{8_y{{z]yyΐ wy[hYikpc(T)0nOr+L]YxX*2s|tQ\1[Tb!A,n`=WdE Կyw`(w9ZaO/hFG )9oG|sQAb JZ ɨ_;RÄ rRa L+!fcy[¬|Qg]HYĎ8T}uGEfp}p<(\I*Uc_ʃ#FzpwA#l+ C$<rn*4q*RG3脁5~q:STxLᑮ%ugl bS ]YbP%j uAþ5H $?9YS"%As네;8U鼵70yi WNb|" 73%ivMуX|J& j֤fK U.(/`dRc =.}ϻ/S0r 4!pr}.5P;\]Vx=n.L,eTH-+BNm|ͧrBN+ɥlh9Fvk! 'Z} 5&<Κˇ5g.P H-hudz ًvI$2c ̜fB d~X$=1㪱/26xP:kKU"VJ, x+u帋/{X,O쭱e0)Dl1칯n&efIv/N5[MDhH-X|-|IP|l8qn7 oan`KPi`MOvMKI ?Ô.,贝B "0]M,i]0"L{]!V Tϵ #U^q"6vG{fbʇ G P11k֡3w3jn؆'{ GcY%DiRdv☣qC"Bћ@ =tT+씨4M`:i'.xG<&қk$B C3?vMZMikTl޷d(iW+? OrDLn16ZĽqx W>1Sئ6!2LƐlqiq:Ѽ;GՂ't)$k}XtHZ<U:VpNQNxx6-{pm̢ɉ/'Iwaʷ|Eo@ D Hv zs5cZɼ*}UT7>44|3N[sHۗ9ºbZ]Z[MShh.>2f_E$"fʗ)3Q6YlE WWAe7&i~gcng;n Bkk9|&jAazwetNd;rv$ qՀVpqdfe"E;R`Dhen dbE$"=k [URA`E/6 \#*fk0a^#)—'q2}@aG6jH}{-J;p|_h % *|]:GFTĔϸ;ʽ=)?r[ce'=5;+@;3(R)IW^PIֽO7ĘUi@v؜_+DaAΦl Aa<ـ+Ǹ{_4ZQCܩ6vc5D&hvB0rr7\OWZȋX#H#;K4ܟC!Xgx:帋&FSogAv.fs\e3- "CU(yл8wNI*PP>韚nC E32ok8 ("*Kc2eyYWJAČnI .ȟv?g֕0oklI'r(p)5~z5<ܞ4>=a4m#92-..r-rk:[mYM{20 1GpRrk1dULG{˹+H3cD jխPu'DmѝZNl$Ęƈźuw,9†Ev*˿78)Oa ;+_nn3Sͻ7rצLr&O;ƴ},'ϽYp^YР(%x:*fS1#('DvXO|NW3J/nKvpx=,ɵJLu]qPQ=>1{(o??%mݩ6c}v;N,ͪ1uՠ<DZ>m6Z_RWa4Z]Ly\X^%9X0-[*<~Mw&; i( sj^@K݂< e%n}bܨQV+7`R'\vaYk6GTIY;/^GUiܒp=.F-Î& FЫW̅AbBLڞՇfMROrm(쿣AFrgENkdNvj#fHܕU[w[q,O1,%#TL=WiT7Or" &\o<^ə>ϧ `=5]ioZL [>p;T-\M&R0l@U hн{ fQ%Q`.= #iqQ"leY9 YD v 90A83-]jӘAz웞h:q"|haRn27fi +LRB0҃Ipqyﳆ006s5(jz8Жo@6(dSD0檂G9eW|VRO'` O;QP2l9[iл?Hl1j]14i[g(%kяYO$Oz XO~ @d3GuîlToP.k+O_$z*EΞZrv^ ||\ڏ8Mz3 .wNNꠈZZsysR#|0e4[p!Ts}'fA௑92|Fi;[sZMXAm׎ضw^uNV(v|)Ls0۬&q #ega-WA<&;[zJW~ySyeb.jP\>ML.<+y(q4[G43>=`A}FJD2UNų·6l IzwZLn"UPtt⢵Ζ4>:Uq+nSvb癜P e knIq -x|zxd=bs%@:9xZ[A3Mb6"kN`;Z!tEWrSplHvs*6qQtFEz%*/F\ QTFNI0 `^Afys.I__*s<`a[ =Q۹?j{n]~ՐxzSO*dM@$fLm01UGU%IzK  =M8}MRKؽIZ݌EkB<HdR?rgTAjZNCSFJz)aGcbGqw8(젬D paINc)d@m[M@Ja(X-V]%S͚@4H .?R,#}@&k<3>a}ekA<=d 9 _M2I0QcE{[%6*?1}9{WK g  H\E% sK5bKVi3f%Ҕ jo5 y W%Y9%Ui=Wt!#T]IEӳ &Z Xz`zw^?qRMQ'4RⱼBbu nP? ;gP# Ծ nj&$aic/1.œ֫]}ʊD=SDIJáNz90}t(Rb&_1 tܣR~c4;VL{ԶqhJrx9}7ۻ-vg׃zA恅4l6R`_|3-C[Ĕ[Y#fDd[O.3SL_^u +fĬ1͘auֹ_7pw]Ry_mwڅķDx\nYHSef8|JK=SCX i]Q͇Uԅ8# %hw9@crS$^yYW n W;(5.%T85A*Clg9oqŘsL(W{\R`q{\|6ZVONo1)02wKŅ>%zY c2YOҁh")8K4DtW(01pAh9l'ρ؜$1XڼB1^4^Kr{1@jdnrKƂOq`sar}'ǩkQ)1]lhq wB* @%Xd2j-iJ}K3awlF`Ӄ[A5n^+K1gQۚ (wL3anU]8^ D/*#@tLs0o[yi͗ J:Π.Idg( aՍoDzH7ᅄFi}BRʫwS.}΍j3cM[8CNGפ1N=# n" PNSt=:6dO1h IʘoBShbma8ϢSXQwts*1}s:DfH/OP܊{dZ,fѪACЁ-,ߒgAs sd枷۸Jg2WӃ]X^LIL f'DoD<K o8dD.`$jM4{<{p t[NxGl;"ܟՏ*"{Gt`(ry=3 ƹWSBEj\0 B%,:Oo11L2KP~>^"8ѮQ}iԱ1HG3Yڤpǰqgn[0QwɡC_LŰl;,APphę|񄐟w# ͔._DL]۰֛~0/)v<*^ s2D΅uwp QJB~5'똏t: MC|k Cᄱ;ި ?LҦ"+A91vȋ ,[bE Z ҡ\i >- dN-o#z  w"OmYn5E}R6_@oX1|ͱ:AOeL-x9)Fz^? 0!SyYuÖT®oB֜\vǑRM]۟P%%"akB &#;?3#wn[$UtR:OPuhjnޕ⋎!# %G/B~>gBM…o -9kf~]t0ա#>([vc PɁys5 hXb_' wwV%L MK|RI7/G Ͱ"4oЪXfή4Z BemSP"3Ƴs RhMIч 9Ya*S:XHŚ[.yT]}zS'WԼs I^ -Z@hpΞkK_E޷!uPҹZFIS"ތ]NoxݜJbRqdtN xNEBI;lR4|uT/oA "cAlmttV;9;zoRQHG[XaQZZp]GkbSOvW: oC]UN NP ی-f oLߐϣU,E} aw`<>BV>ԓB: E"?t㟜3wBs֊#+*XYCM^VϰQpVhu*@@tz%g{'_sW9G3:&K"Mp Ϙ ߊCS,e#Fu8G>|>CgZ jc#=-hÌ`~zub].BMjY`>I>Mu* =?h%(6 W-V2zPnJ;A[ etɔ RŢ<{B/s?e:Q)4vwc:|P|x>A~]9Иcy߁29%}BKMFcJ-;W0a1vIOS#TNFnVts&֬T o(06rh!I&s^-TЎss1|nKL$@a +ˊ؊wA{1ҩMH'i0xQ->ε>kɑދ!TEMnY ;˞8!whg?C'8 pX#Q#m}%2#P 2vK%4!=o[(z^|&:zV[]Xs2b&;вk%:{lH|V۰0)辚몶ԲlN$]a\U4oʗ}|RvoцrٕKFUͫ(5ݿ5x{+@@]&p"SD8<9mv@)r7X'}û}H#{.Pk|I @w_vׅ <ζ$>޸äxO&"$) ĐDO]a7ǝ .2檓ED<-_KW٥ Ζc9< +ci2ռV05T&Yu ݈DvBK*$ӹd_矢(Φ5:Ĥ$yiеƤac*!M(4nvD=0MYXJ.cog})0B.sRgz{a0^tXu˪>(TJAw=P>W~}(Wۨ߷8\%2G'ϝ j&3z۫$Z(KG}\Zs л Mx: ߛk+=Q FqZ>d;H7K+ZD5Aph0,Bԣ FEtlj_04ZlKq8+)Rėee:{Eo?QhJ)}O iSlq;Z@BA&3$4 ,眮\6gw/44 6W j~>[n^ !o4cP}m)tb\lrMQ׵Yp`@<ͫl!#K4` 95=]0|E[6qƠtuځjv|7 u& /)x̸8߸Aa;EyY tshݶ%qG0!:Zz΢936_.rT 0th0mҼjcܵR- 27OÎvz1de wDm jھddUmJJv?SG S^nGRo4=O.G=u$4pQo\]r0d .e'İeQngX$l܂WշWHv{Hߙ`O6|+ f_,Yvv^: FݪsS;Cbli/wU?yWB+;:${&O.ccOFZ>/}JVޡn6J= U6-ĎugVKV-Z43'$␳3|aK) |ERQkRp'pb! R&1V'Jçy1ʆ}nAW8vK)ا<|ՠx8It[ɅmXISK\W3[^c*UiNpszi*gobrNb!ஷ+:_);.F݄ýMcpR%_h sꀷeٜ`Wql%`!jl5"9YQ4 W6)QԴrdYE. $G{\AO'yߞ@.hN3dk F^Zs '%אñ/:3xz9A C0i )a;[1@Tb~|Dgs3_ӞpERa{WtX/15t ~݈iZ@^|:-ݽI+4<)=ʽp;Ԟ* 2t%1jj/P,fĜIXk`t[dBӌPI޹= > TD2F}Sݭ ?)Yf:1yM,+2)?IEJIy|~Š[wސ^mRBh 'n` L[Q6~ / Zp)]@=yN=LЋG Hr kv\%zLG1HJѓc”+4D9 l{Һ1A`e`QA=xҨ6s9wC' 5/bAwf9Xҝo .9\ҫ*{v"ĔХ넩;B2 Еz!ڕd=FiK_1/Ӗ6$l|e)E:i2viS.&X?.[;,Ҏ .h^A7"TjTBLJױ]4f]ĥYD+T]? ^i [a|vQ184~<"*@olm̫E\*"vB\l~y*z6Y2x3o-R}t?D]asKMQt&FB@ Y(P WW2WK`22 byxH@cOd53uXdNFk@7O 0}SGTzf(8#yȕu>c~ILNWpV3hP9Eǖz ݟc}e[f־ QU[., r*9UR_A>UJō(atTK<$xsj #S`+ 3I{J*S>C0)(&',-ZQ47`8KoM2},|Bj/AWidj9^ g}XL5l /US7.ma`/BOn߈X owz0)ִQ{Ua5 i\S&B֋'%OҦrD& wv]rQ˦JiUqԀZt=oB:֍E zvĢ$"ظ֊J~rӟ rN)%|n_.YoP"j9\7c,˴h9g=f_Zgmѽl{m=`4llU*6DSCQ֜85ƛJtC/T]45r2 e ^(r,@Y$&?tb-/Ȇh"N0\~+ {$o$n!C]-߿q]ƻ$P>B>Y@D5C%u mp\$/*KFFXUSBge _&"d>+kcͷsg#XV)9y;"}N߃~sՍ ;p]bG<Սmÿ8 ]St6ddgZ"wls*G>LJtgTV΄9 TFcf峹aclu]5vDQ4z 4v$CL!4BrG rA3!Gj Fb*E{##Pcyԃ$)iw.\f_h#G/U{c-aM8K:t+)r>sI榟[)#b 1?@=(1׉ˤfiR[u` ZtPճl<^z3w%+r3F7/*0ryg5J,{ǷλY>h3iq|0}\ .5=m@svEi/[_zvve<ϑk߱ ;,|?ɩxܷrl(c ^-C@0oEkSRbx)*yG4 AW)7d^ S(A, iuGb_5*5cEB W}J>[Yn M)}[Yf^&3Ir顳dIwϓMlFj5)trP 17 ~1ltPL˜ 4Uw齎釢m~;:eH# `CUV{(^fvv&\<}Lkd>>*DpEwsl4)k@t~}@a>U|Paq‰;#;`Y> 78&+DJbN5% H* TE:'_Q'5]"]qtR]"e\#"Hiwfy]OS%@Q@(L)P?ȅ*P=p6.a[mn91KjRw-cxp(W ŴVVdFNVP&>}ţ$RHz/B8*"Ƅ Pb+: {IVjX<rlJ(|js?q &j2dt˛IbU`=n*wï>Oe BЍжZf%J#!$g |TkyXx̠ˬ³m FnK2g\ Xie h2%c( ifm\rO| mҝ-a=~i$X/(V+O V&`^٧'y*!6 诧Mu*KM9ncd`|t[ ͹^,>%+FI~VdvW/}}W'^ (D@>7tB SSyjWnՋ?̀ h-l29ЪIA.YssY׿uNo­|9|2T[(O:4cܲXD@5>R?hHya(:9`F%A @Q浦"ZYĞz F.\} Y8@RFMx^JZBo.YA4mH Ku/ Zyg/D`chgbțk;n?"8 &F J6ZZ0>\,Գ .asX9*8Y^GkSՕ܊s6dy{,wJs7Euo~M R) 0}tapnCwh3VUA͢0<(CPnp^z:D9ǧ;?#׊E=HHV) gA0^`]C^xuo ]\f H)x`)z~,3: @շK}le4&&ʔ c_0SSS/}iyv!<b =2_)3ep|Z y6b^`Roр,3\Ncc% FmyPm}|sɽ1v@qo$ab!F"o{(+q~ RcWxX#ily%>($E)o6}󚿨ʮQϷONt`>9AD3Ec% 8C!mrB*0CI~Vz ^)ZYơ/9$uXL~cg䀕F]xN$C7L4/:$ɚAc]cet_9xuz8S f,MR.6&veAy6e>Au9oٳMVaA1 MA\J$Os=(lP{AXy5x?XFG/`0,}k9iCHy@Azu~iN rcE7U.6th><`mQg]|߿R}r5Ʊ[W VT:p1.)V`_ x@(E\|xJE ?-X2PGll4=%w'DAz2 W%fLW[/o׆H"(0 ʻB椓s:pm:SjE[mLla~ Tyxx_NiAus!0̑TSOWܱH0EƃBpl ͉U<@B4l{2k&,TlI看^@ l@%#%/kp+'0b>X* <@h$ailG+q]1x>BZO {ivD.u%b :" Z-BAZ[VX!:&X &/}4hďZTC.qy R%%cXm\BwƐ.&c! J)kGȄXmO#lͿޡVTFP#U f|g1E} -~7& Ęs֧4q,* ˇ9/EW+~DE7.lWgfOP4:7`=$~=DEI@@Z+y9T0loWȸKW\̈́Mڬnm_GDԹӮߨ8r찹$ Vjӹ;؅) !t- 44S'{z;r ޫnt4]k~o{72vk;Boґ?x$I)K- ԧbx.9>p1 ^F.lYL7<\ǜ+.s=- d}ŗoYV;/Rbt# 1sS l!oJ`3V\%L2ٗ$:u{UźvwC`d+āĖe: d QݿA-&tr9c3&)U m n<ξGY283@q. tR#Rawh@s^%cPꣵcEtodK(8?*2sсVIАP=GK)viu6/w={XZ )˫^bP+_xņ:9j+R.@ǨJ;4x, 6z>J-RMJ'y~yMHYsJYRvj^;9qx:s0fb6mLVؘ9fm_#G@ߝ47$l_[4]!J^1ڷ D3AAMћJCMV-X5?kY2p\`s8|aV_'<,8ys+_h7@j T[ŗ{,yvcuy [r/_{e`hISI ,PtuXk|z ";.,m8sF5:Z7` 麠Zķjk4uF3` c9Jxi`aQo5.1F#(.ߎPv `!ea0H1]J(3xpEȈP=j{$^@>@}sAwa }BR2`(/t8KfV<!T5r2!>t)ʼn`I 2Y>Ȳ+^5y ݺwrqV=@2Tm2#⥙Mb5\uno R{cj4v^O0h'ĖWV!8R )8g jJg}=4\V(K8чi[) =\:hn2`9Fxg55EOm7CiqFFC}Ó⡙ﱳx۱Vfs,_` Q$ZQe*h=Һ%K@P377ZBܛ4әJJEiHIoڃjl Zco)zmX7{!PRb@mwJP"_;4 TѵW:76Mn+U##.Vr>LeꗟƽQuȝtaRnAy\e‡ Eq)p#/k'dl206K~NgmVNblkěip7:\E}n7]`e4VM8?g>6GPjBզH  JХ\\C+ZM\s΀FM=*f΢K, p 2 Ze]Wx _Ik*$ A,t%98ɳ"p$@8u5Oy YTKPծV:\^<Gogh=6nowhI{464+q?Ќ)؝p6"GC׊˷DrJZ,4uORɹGG7G IMJg|l :nT42$6FLj7b7kM$aPl*-V ÇEPh@FV&k%Nke҆Q>l"`2:%LUХXD9%d.7wE3s(0Z˘OՠY\\gg@2]d/Єa/#P1X3Pc;L8sbjp~h|! ձUbO2?|}@(p`Q (e+94UǰsׯG@h7JQ(3 -YO](2%\<3tU6R]7~oHg1F9Q,6p8 6Fp6vvGQxN,##~@Ts(4K_bVMlAh&~n>A} *:~$^ S҅fG8X0zU]SaWX){$.IhiEp"'tuRrTQxAHPP{0 F2{UR4' F!=aԩZTLvX[ƾ XVk|dOH:!OfJARj{F`v \:+!l*_-Š9k0B}Kֳ1.)˙.6^ T̊֍SKf \v;͘mL"_i#L[(' YϹ mo'kD)ZD|HV?$`㋤f='q ͊U:=?v"Rn0|o E4{EG\ْ)eAp1cɦ|î"w4AI]XE>0Nf9 YF;Ƞy(vy5hq;i klYɟ:Hg=E]q 6n!AUV;$oZΰ<π.gc̯? eYq:0,~T!Z`*M+X6+e xoIŎaC5[N$shJy3fMcY7 2Z'.iSCf]Ŏ¨96W] 1ʼn6* ڈyazRY=O`D;'Tʊsn'Ym^77V;w7X~tkfqu.{7tʛVzUEdrqпT:EC G,n U-y(ͱyk׆kAi~FGD c@nI8XDP9O/id: v<) :/FBsB+JdFڧčCA ĕ #+HUMk<%)Yc#sx\ZD2d`&IlӀSk~ޡ3r4f$ZugM s.: ikxQ"##*bhΘWp*r%y8Iw?L"3N]RaCLe?_UA'a]i)Sֻ!JGLΪ szx|Ìt'G+`gIK| eUÄ|J4W)e5oVHŇ7r.D|0)M@&Ӯ[X@aA8A}E'X " +sSKJwhƌeb[~(j:fն`NU0^4pOn>UF& &G~&?q~F&d}\/hoS3AWFe?u{+膺w^t6Ұ1P|FACǘN&`߹̾Z?d,5Ai2FjEd J<~*/Xf u! Q "*3`$">42{] XP>7?5z|O~pY^R'572sU9=p\ub2"8}{þ!ZpLBl>N/ V,P!E.u 锣4e+)9>gOK"Rz瓻 Fh|gYl!wg[%%uT$V+-yERf2͐H β=?xjCRgEx<+7AW2>qռO6|e jh"жDc xxoh:ʣ,%Qg&@ w[Cs-XQL="7EB]|-1BZX d::{Pw G]Җ%;A6@F@7ENijZFAnߢ~sk)(q:@*4;DUQ-C`Sحu{EV5, ccVv$*dZ6J^pl7!X]z9[Y?oVd7"CEpOceH7\*RC%U?E}c ƲXf[@mi:H 9nZz<.gwC]R,6?d4$t4IwgE{(pr3!߉xef\ O`1(\E|1s]+'לd{-7]L̍V5ٷ񛌃opmXu֒80e! 6h8MG{ťlK1FnHYm0* &6slĖ삜Q/ UjDk;5 U{ͺV|Y&8l9p= g&2E`tvRJu8OPן u<Nx%!Oz+9{g,֯I Uf,?D( XX{uף‡Y.{n]]ѿWWEA1VU@wu졃Q'?IyX՞o3P7& +| ;E pe WxK /AJݖ0OØ$cM( JbP"Yݪjmc5N1\nS4ud=>Je04_, ަYoeKGkyg -岜B -Y{$$V q5-H$]_yl$ (:\9!$8;cwI|{nqp(v{:dˌK85M"̸;Ѧ?Dn!ў蓯.?rJ}(Sv$z5?:]ud(Ehil ){e T{֛#I0% $$b仙лs)\- BbMWQ'5@k@0-"YԌ$PGW^i2 BKfX2IJ,F>+Qle|G,v ?kXhx%;\vT/6~ U!틌TJI&=bś`P&wt%RFo}5щt#کb<2]9|S(QZ ˌҍme|*y6JS'`՚jlG 2[i5@=)B r.2[ ]1OMO-luofCDEq7Ll$jL%?rhe[Ltll941M}x&B*S{sDy O6[07OؔALpr4fx6bTK7_" a?+<ߚ8`9I4ƽIڿgI'saV0o\0+|AW(,5/橏f=_5s-ҕ:Box!i^mZ8\fމbDZL8Z!l,fgU/G9F?cؒwAu'c=8Zn-˫2f93 cu26í-H0nw `"f6j:]k@ۧDJBL=ZSF㾐,}mWVs:'`wo˪EThWʹZ|Q^8-.Z:аmÿ%&A+4DN|N`"_.幟#[RwO:,Xg0D;iX7t"lI|zJ V] $$ԅ#>l J4c5ȡb4oFG-u`^)E{&3%t9XJ )_[{tujjtw4zP\qxQ0׉&^xӥmtUpĞ-bM,E:'s9EE,rϴUG{z%t^IsPޯX\ؒŢ?ޑEHX 0rm5٥0r|/)ƁJ4u&v%Mu; ʝÌ*לZRAX?<_ЀNiH<}q6ZW?/ŝ%9!$OME;t\姛ob΢wzGB5J]8兌3 Ež3TB0lY CM913G6=vjrdN\iLkIV;|+pmAPL/l,9К;i?:ǝI \_@OTh;G5NKSN(hB fR ~L$o:Md `R2;TPUzrhJHM&8 S:o6Z!{² yRRrQ )9i %Z|##CН "}}=}[a$N{fHRS,N{p d.rY?I^ٯJ&:0_϶HV:IkB>/e.5%r]e-;4[ʅ~և [<1S&|ԽgiHrZ 6>UK{9"Es+~do:q$a-#)=LIX P9/Co'*D[}y=!`dƑWb >E;ݒ 2wye`U1 Gxh3A\1?+{1i ] {qLXECGGY$de"_\EWcn!5MlC *wS `܀W[ /hз ЬS j8t!c<:/\f㮓_OdgZ?B{&q eظsu\~ה b]61r$3:+nopd=Z%{Ў`eLNw3%<-h h}'a`zM>\IA.ښiE]UR8_vAmR1d]z}'o@ƞ, BYnn4{<K$d~B[A8 LnKxD(wG#VـhT u*0(7>(͵s8Yc\eqHu3\^-y]=0r Ur Z8oa0j75/OEMIdfyԟ&8U3!-L1{/j]=JB|Amk}DC1LͣC_nXz}~ ;a) C5d|D3 /嗎Zg\x^11+`N>Eb\z.-<|@;ƩDKL CrCk 'lM {QŖx˿'7J;~vE(%9&Wm6Q.6D/q Dk[Jq`ه)ոS.E\8z%r*+Y'_phզ.S)ui)>}J049Z"L ;+mWW6Fޖ.{4="EcQ\*ʥl,jB(8FE*w_oե>/TeKA)ڛѵq]pSTaTA5 r-O7eW/<囙 F!ǂ{;Njo e>[%nδ84Vwƞ2EEϝ`Tgl1J ѿmu編S6iqL>cl#Y\ fz~14a艏copUW[*~|cO^pNvuJ'^F+y. frك˨ 1x^pAvmkw0UF/D%{nF ğA{ZX +V͇ 亹8?1KgfANzX;< $bMޡUD7l$'-ʉ&!IlA{@yT;Vy[<>Ma ^.=sW0Row v-n7'/T?w_#9o~( QdVXT8\/¢ۑMd>}_GYrQѡG C$ jFǍiœQsgb 7MCxHf%*,ux &@֤4vz \ٟ R$Yq@AiU,ћ.ȻZ=*؏:^z ǂ9(Chpt`~,ad(?# nJ(uW뽀] )+Ξ}w'35f!%Pο2mH c!_d1]%oGr[ (c}*2 vޏ .rndsD3·q)B7ϲ#8%B$VQ?>y0l_0!촴6WY>ogR݅g g;,⏾i-yGxL ۼ^1T0zM+9Mv|2>Ud%fIQ";U>4`Bi,2vzQe8:%#!4[ާ-K$Roi邟0 ߷$B\Rd/QimɷsCe+=1|hP[ac:{I9l?Y@?'U&S]DHPcbzїN|?:ՏlTҨșכҢ+s ݃٤3&L?Q ZLU[L鸙"oHf/ uG+w/oA_e)u猪B$gcAe_"ٴ0V\sb7%>]ab\E,܊8 HM3a5 X\c0άxNL˃I7hp}\>6L. WVydy968ŽdX]vԎa[[eM-gr zsǰMpayj1 ֻLU_$3* i2+2KI?Հd-YV3o" mZ(@կrݍsce4||X&"(j;X1ɼy+HVNjLEf[T & ǝM5nзyciEx.~kQp'4vj_Jxw )7}1pF p|s㞔U&˭?v4&P3Cʓ]e"%ԵQu=_mje2[v肞^ zMWKZt6NV¦Y~hth nD?eh{`j'&Wn +HX զa&ǼGK1/Di}yLO ߋ2F=ØU:Fv >zV7"J԰F@“ GiybV-Jd ҵL KLK٢aB( ^]gH/&@`Li1Gdj}eEs" VUȧA-d? k|7XaT_DG] z"Ǿ9C%<)B,tcɕֆQUM67EQ-a^u쏑xR*Czx1ئ}E~JÖ2G$_ _&A4WW8D aVV0(mnG!)~USQ9GP_HQ*.W?)nr5(.H0A`eKB5Ϻ?KX.!6Y`1xbj:xV'`]HJbTeV\w!ѷ/9Itsqhs[UdMHUYtOd.FE"(4DK(6HpIpY;cQȒ |b0R״X▪g䈖H;OXws55_7enAKP}CAks$Лt6Ȉ]MNaz>䏄 G,Nv6m'b2dĹ$An\'+_ǐnkao !P<*O?V E>n'a:ҵݾq]qg{' F6mu:d;rrh{jek:вb{ٕ$C@4gkN/.(,yԅ##Ga/VRzGo?XXPL8[m? h|x͠Sqx7sh(H4XbF7z(6!0;T'xݲ8'6\0VYo^1 Іw EޣPt3l>AGق>Er؛B35%ƛSMcLT HThËUr]_Vcתؼvj+;+b< hH5uH^r|Kr8%BB zvL7n bUȰiЖ OxbgMTDmE$NN#&cы o5r $#P-M]8e >h>J(_?|4 +`I!Go8 Weܴ"ZWxg,)s#Y!Xq&p*y\ 7|(~j-aOQzP)I>/BߙrvYuEnovВ36[ C18`4fS nB"D$,)ց[56pJ%""x?Oͅ xd1gg X៴`s{\ `FwMMY{bD&akZ]*hZ iͧONL" pCR[]+8 =^9p`kb NW+{b2[^} h<"RQOI+a.)[ˉGt-/+d7ڰZ8W+#wX0nCPaW-$Y[cV1,ʈks [/Z>"4y K2&j gU47.pm2^IE44|smT*Z߳!ʦ]QIN͙ai(+zG}Ӊ: Q\r 2N-o _hk8a~n]C%NoDM J.iy"&R27ȞHɌ4LL.!p~*&HQ(,ʃ+[:_hOۅqkQ1vːΑdBiq;6ii`]-)^]S;K 1[6˯GVkx3k-(@ɪ"[-j{Gx(sMߘh B'}) 4c!j'7?ɀ;9>?^b T"@gtkۺ-"g,+ ,IE叿RVƱvku8)I7RY\RgN>^D 4 ưItWK}"͉㶞OC"fڂ:XZTǎSDx5UvX);ǿah]>$ W8*`CNCo@I4豤ApDݬ_X .i!JWHȨEK0s]ਛq ;BEl/_apE!C$55 Ft993y}*Sgfŋ@}۬/j]Qj^p\6|B2ԐLc#1P@#* e,(>’Dhe+J.G% 1!{q3eA ѝ.0FϨfKokg^Ca7,XUyrka9k^&J@0EVWT|pB@ QE觀?r-t88Lb(<Uxa{8f"r}k;uжB6+|<Fcj_ƐhHMud7X J$ rn?)E*)vQA&nq!APo,DG[ǰG9l{ϝaP_pflUfNPT " Axd 눟Iم40h1`7>O`)Sšel}3ݖ>\97(;f*Nٶ (zhe GR.u*Ԥ6!8TkJ'"c6)+mtE1 ͟V؞kd2?%'#TAbZٱ`?8RQ=g :7% LSwǑjM-$pE^t)SH}e$b\#xQ7\˟2uhN8;" XR^[|4`gWR\)Xq"x&Xb'ww1aF 4l]9Oopbb sڀK!b o:٣&QT&wCQZ"v5H<-MEgY;̿Or6!.Dp,[VMKNMYoK?]1gtk̤~?Gy`1Jߟ6 W#F t&.*ǚˢ?blQҀї&"G.ςH,ڝV`hUno֦(W #2Ra[r5NRNJUュ0dQe*;$3i)+"/?k1~fd:s8cHFfc)zq;~Hۯj;ӒPɬ 0`$uƍ{SaHgp|IZuZ,ݵò_h4R!o?Jmc魶Ӟ(gG^{^]kA#lpѵAoǮHnrT9d"sVQ(HrJE*VSjփs74jD@@9"2ް5Ei$žxSh}5AVLGŃ!aހrC%T);-*燪-RJ۴oJ>-[4U5*@M8W_bmx%v C^v'2/!t1ruk$7B/0ѱ"]a%F{l#Wgްƶt8\KBUdk =':% @w*ZQbC7VkU\;θ9)=}D^nb>wQ%P'zshPӾSgEcD) 6 MJƨ~SSWuQrI*7JFAn5@%jDǨӗgҡ|pj8HQOOw(v')N -E ǰ[v |LhӣYwe4H g};,fg @TND4Xʊ_떵N" ّ1LL̺ 2btu=? xv U]v:@vQc?i҃1Z+7|: qZb b|tƬ56ȔW\͓?` @`(; x|;!!HuR7vqCLzDͫylA>xN+N:%-1)D# ~F5Adk@>}v/>%E9L{\m8S^ @`k<7+̻*[+<Fssc^ RyxFR ptt~6b~l;{\ ;>S ͣf7?zާ{¿}z8x|`6`;A38lTmOusBݜ) 2@ZĎi)o0n/yz\au>f=dwYZ FwcP!>~?h[r9 ~ass$~x5S9 ǝƤ{4'lT3Ikq2~K_w:wVv]D!x]bկyp\sYoF#D!A#SrGLq=O3n^*†F^X@`Nfm8l|@wRjdvez]p$axcubȪo@$4Z*&yB][(;9P 1S-R8ͦy#.YfBJӄQ7o;9zdVk W|x&>Ǒ5kwkwzɟ@30wN7}!A|'(o2-f7v@y㧲4}c@hAVlcI3Fb6MTx=Oƴ$6I%W/ck+*{7h-hRZyneh"d|4H4DAbWmOy͵f,*8Or{@yyE()n~CI3 G_:owX/"ElYmlhy?zmAr=pmN߁lg@G\Ӄ>.>%,{:uyv+YT6^~<>~.;HIKܸPVW~ySgqpVEu=#Gi3÷ |nH@ٺ ]{P[  vdgtVVP{l ʥ;/En&}+:qk]2P m{#l._ʱSsz*2MuקpvPD.)r'N_-;>Z1Ty/,zq(1Xr]І&Dk`˶ۥ5Xm$= j`;LIk DZp> cu2p6uY2mPuX$?w)&ؔ$ߧ2E :Fn]j?@LIЩ0?|8hyϗ3AgX̓b 35e_҂3L\gZ WT… 01 7<ꘖC.9-YI`zZ췥3)l靇_闏RGDrslk#"6oyؒ\ ƺ)vk} 'L ";̴I]- l!>lf|? ΑE>`"Tk0}ہwf$?4r9htvj?'1IG ."EuS7({}VmtEe8YQaoM0+CցG= r[3:A:__H-ը?h:Uad%~@φ(AYjQ)kG9dFy<^΃&޿y ̬[4рh@M ͣ}WYEuUQǰ>}+#LGӉs8W6(ڛq\sF ◟EPALJ?pygcp~$MZ+d3;XKbӆnE^h1n]_oCQ`׾6[/iDqҘj~#TnAL?ځ Ô. agzi?ſN_ I3[AbF+zy6q}q5՝A!Jm>6q@3`*\͚ov~X[̆DȜ=[M;O~Yyp*ϴvB`]j+u<ޙ ; $P Gz6WϚ7QS5b!AڬpP<"1,_f;]1c?&^@ә2ϋ R8 1Rji@1@4S&zVHJdtV^*Vw)MMPA~v*^))8&i%V!8A!ts08xds>[*7P/vݺ)uMLOlUDLkm /</F{$Eӗ.7ٖvW_.{/M#7D.Gzq02^ .hwyDž) Pr _.pU, 0P kNР5:𩲴[*[EB:rЅ34:KCJܧRLlF_z QSW *.˜VKfU?xR4|'xZ4i{QloE솣)So PZȱqoA~sN|_nKXRNct>0fh}9nQ@ʪ"mlbLQ9ws6Ή>_/xH*< yQcVˬϱ.۬p"^ B.dcДK {:k[ɛ*Ļ?vJga) gt:`qce> Zc[(8 Vu%ƣg?*\Qxwg"PX9z]8¾cV5orMI~pI% /X&/F!˖MyňՠԘ1 ]N gDꭋ΂*dÒ>Xdb XeaHVV*Vѭw#M0zz QgS}n t3ac>2~g;_15U{S!( MlڧLs~Γ]ߡk9 >muGrX7PUobHgZhnC>T8>ilkޫ;+xM.BkזaBgpz^&~_ҝ=10mV}Rd!Ʈr,ZA?wOS~ëOd3٨zNaerюgk𥟛p֡N>!`z=jfgp/uڅ![X6ԏ31Ú35o/"3"6O VYwp+ApbwOlfUI%IXg.zltK"ByZi>a/uf>}ڼA2㳁*":!r ^4bnO2Mt0!שy`\"IsAZawNVЈ2 2a+\v:f S٪.,`z;9GlCSj WHsERӎ? }&QE='29mꠐ?>exz`(A}tpoQ!ȆoDM5$# ܜ%AO^c1>Dwbtw4'7'.1[5;hQ2,+0F0 Ë^S?Luy~qa=y;# 9}N- L- 5霙./F"M̀pK[cҪ'`VuDF1*9若>8gb$[[4f (E$4v4& Dž8:H;:I!lBrEY#mbH]Y=3oZ:M"Ru ϧ(ˆ-,mZB\n~i=ç 4ug #b1P 9DU ink98$\\Z"e@m2&ݬIC.KQU?(ُOG_.9xݣʎq>z'/0 nqIv}MY[Npz'[IGB Bg!L"9fnW()VX*U?Wt:Ϯ^5q˼  bs4AK8z_DO]Mr{A- 'l~rx{19jWEKXZ8(ޕ`Ox/"P.=2mh+N82(Cr||eY{ݜƶXs_ k6:[ťE(QdhΖz)a۠R 7X)؂f`-m_4]bK?lyq-y_ߚxxpaYd镲ݒh jӓTڄW[tiCQm_5 /Zօs#!xYoAI=v,ڛDˇWlP mԝ؜ɺ"߆8ݩi&ض7fht*T׏^dOaĒ @yU]B,繳DlOcP(Ըd҂@3.#JC%Bsdmif0H;NM Lee`ٽVoiSbw٩Ƭf1]-b-:G{_@M4ZȎHT[#X1$f6M5 Uɞx-Y^UL`:qȘ-ڤvs+pI0x?k`hZ)<쨄T[b #%JCϺu gaW5/Y  DdHnx> [aOpb`2](2@8Ti^Ԣ79ڣJ ܜiIUՋBU#8Ekѯ.~`Ym|' sA/< C1Vg0s$ք9ak$z\l 2\3mIo_9W 9љ,~3X= Vx8C"Fe :UxUŲͱVs,JHᾎ.`::?df/-PJ= wm+Ֆ3!K &\ }\}{a /Ut .:n~'݁jo&fP$MD|he=vIFq=%yi]g|C?ւ藫w]ZHoR!1h+h/?g6W[g l(Or«=Q,`T%e*n.7NMQ&eJ<*|3p_B8w0!I7QUڞdPbjHYi~%oQ]7+by/h y&]8 2\:l‰[ ;7^}M oTFg }IG,7Km7pYmbY=RPlWr8J-/M_p5N*)8Qsr,Wh.У}Qu*C]hq2VJx ρn~)7mT7`JV tw'؃=Tfҩ j3zK.To36d?g #q;[QBAF&Z x~RydŔJ'!>Y\%>U#Z~th=%@l#uG?8mʋqsPzA< 荡;{Qĝya"UQjw߿1ީXk'f٩ռ8 'cAю/ N4Csz Gh$E|(<;j\֚ۚGYa"¿o"fإdN6Ae h"-M%`HEtrK!69Mu \Lt9 W t&Nb-3ufaP_ZgyHz3$j',Xaik' / Lm#/¼ sγtu+pռΉC_mKvY_v$ˊ)(,ڣ[駒ަh5;_O/@'WFgkU#7.pc,zDyMh؋"-S5_ɪHDژrP*ȶNq]:5˘qt2yVwE 2.efm1q={g2+Ѵ57mj>Oxmg9uY= 'ObY0؜Gxeej28,p*[|S#jRXTy\'˗&U|%$d,a .dt#dƙOWM jyC \'B&2/s;t,,|$t]E`3>"# 65T,n|B iwoנsd3v3TWx/At{.?OOXz2}ުN#!.^LRt^mM]Ll2⳧: .Op^LWb]h( e-Xu3Wj'杘epy" . Z^ C|Lnϑ*@?U|S;2fܛ݁ P$kɲ >CD{4<"2)rQ#Ma_kN,PFkiC!2+LX?(] 8y<䢭6q ǫY6X4x$z !n9\~.&:vhR3aGL:Hʬa9!%6'z[eknC &%<'Jۙ*\|=.%icBZͽ3:דD6* @P £^+kAOmGkoq1 H1aH)::R;NWa}W  c= !|ͤJ\(Nꗁ履hS*SkxﭽE62v R|»{~ <_ʬV4֗f"2!!&γѡ簭8 У{EZwK׀شv~;}uZ9QN_y Xũ$b=@{5򕐸>:5 no(Ik k>֋+YnsYޞ ?F.V'#l6\gDd^ŵ=rv# ++Ƃ*VI# >aBUGz$B߉) $p{p'fd &j~Z@&ۂDgᙧ{¥v&%6x)6?lfjlͥl50jLw> e r Y8dt&%LLW|0KU= EuB!ۡ*'v6kO$p#|mH!iWu?l^Ỿj.^Ű9 zΛǾ#@E.:xLJvUb&^ t { ~5hXے gPV`цߵ YV}!dUŰ\y> %j4VP¢S5'[SH5sSN? hKُJIYzd֩k a';^luctQ*87A$A/u ICX "jPiy'3X\T?]~])c X2$vd @7a%bi^0'M2(K'rΫo[ p5kз=&a NF ʌN44~a8$j rKVTĔh?Cj>ꤕ^PovuJ!L{i1Ӧ3Or)֥F~b`xdR{!>Jm:dRWI^L6]j~\"vSUnʕ)O@vP$$!1N:MK'D5/¹tN v8cnZ梋.O[Lx9ȳ5!p! CW^M1PȲo @t|EVX14^yX񭩑R.,2h˷^f$ ʏ?I&27@\ Cu1yuP5S/^GabBLa|l ^s2j.bPR^bݝ tzD0dtvjg)\RKXi:nUN<5ѱqDGœgI]\~z2T\-)ߡ~<_c+Y1eU$l,8~YٞJ]0YZ`r(dGS:*}z2*d>ᒫl }Mpȝwf?k)㩎sB=Ep .q*GrBx,tϞZFe@ ~uţ* V/諁ji%[o)VJg`(Hqh!^2du[x*V=نxI]]L z §sVز li!M)s 'ȶ_;[I42;\*D;,Pac&?l<Ý;&zqM \e#&ÍKuK_q'2"ɳt?eY!糵f9md.:NRpi9EDӂOg^l!pn0qTGoWi3[ 05;C%A7:4O%Uڠjg=@jpLЭ +?w!tVydOO֓? 猙O0D sa=\ulȄk441ӁίŽ>-(bDWKP g z\Hu~}y*eJ{[{'Iƽ\ 'v 3${$\ܗJKp4!lFKΪD*`tCpǵ&?sMFz*QNFAm0U?lQHRB,,7J߇ "]iorkqwœ:!*VeE̫͎A{ [f]'WyC&Um$wB}EH@HVl,8SMKvw&3rH%KB_d}GwW* X(c+xGe=mRK}L.}g_%%gVe)F2ވ\`@*Sp(RaOdIGoC?v > Vݺ|qv`K: JWɂ3vA]>Zä?B6P|BJTȭFH//i cGUIgh6sa\ؠP܌|x',)zV_6>whK XjBYLN޾d,a]|k?) ^&>JP:ihc ms.AJm0tOaxrlIVt\>h6cZe_n%#hpyONċgp j 3O~V_]+KKI4JčȜl\c33})`Mkb<ۥ`Iv'&j^"jιchT&ge.]8Lɧ>}#IZ/3c!t.YF_P )wc{xźV)-Qu=N0|8J[N8[@~_[ E:?_W"8 NV&}kFDž8dtNt ]^)",ϐ-hMx7( deZ~A8(sU_KJ4rn @1I>4SXIW[Y5 & aDT'.%f-)zLjIRV;s-tM)h_E2X ~ns<ś?Jw+i#Й4s"bBV K=~M| "$N*ݥp)JԕTE8EKQyqa)emr" o>זz@a g iK.49OiػBaD HeP_Q{n;KYʣ.~qC#2']$jffab7 P#fE_C$"Ck jh$m}u9jW&Cic&/q3b2~x߯Z%Bx18aHyFSW9s5E_*-Yk] *"#a"!Y ٙZ7 㷟,fR*k 9j-5~!V;-#n^֭a{Ck%l ܲc(N_ܵ=].^rNgO}Qέеd45&rOS+˕Qm9.H"0?#E!Ȏ!h%vEϯ:T:$\ /\>!Ù?*RdC~a|*|sp%+9S5 Rp=LHW{ZI\S?VCOiQW ӱ+`Eٽġ2+٬ |R|(#+?_zJխU+ч"阻IN M_a"q.7= cȬ2DHl H %Am5N'76'4 ~Tz^fY3*]RB-aȮIR.I$Pr9 ;$VdPB/RMָ`$9d(&LQaYO12 +_럄1[$bOmU )U>l4'(Dd૞ɜS M4k`ݥ-=NgU)B%S8C+Ys#Scf9ۓ҉He!JQg&/}`VT$ă@CԞk:鬮cvXo+Gr ɍ"/10yՓua;;8d#D(Hka&Fhɂ-RftlR90:0+N[blޱ&k~FHr~ʆ|;ZW'YE lemԢ@h[= ؋#p;}y;rgcYyG++P4FwS2t<2Ҧr?gn;1*=wvS |=~<َ?2:Wv^*|[i =צ"t{#y 7Њ[vEV9huﺗV->Nl0 ڡqj#—yN<Zj~l!v7 O $^"EDPo}YNvxJ?wlLm0Z.";$9AEZI06O ¯Q*NcLHI?Ζ^`B=L,xOgUC4zB峜zsT0XE{ Q)Vt$xojIӮ7j&A^8) a70&c0:sܕ}Yj4_ӆ!%`( h~opskɧPn<) afŐ N(p+$6os'w"?'sڰ~>=@~ŵS>D[/WHH0\Lzi RcA*[[\0_h3|0Cاn^_75 LNJ|BW NO(O-Wv܉nY& EL`p+# },':6 [۵u͡>ݕU2{Qmc9u y$@Hʨ;dexdw|VY5S}+xbm0Yp7&3mgNijͮ'hhf",lA6hR<iSM긻_p$j~fd1a2\T1.Qm YpJY2ӫ}꿆៨4\p}u5 ] 6>ueamߴr 2bȚ |I7C'`~(c/j-i4KLj`f^pRUUKeB YyTܺ$cu󖑣32:F8l TCb!A&paTl}2: P* s`nd#Z\cjk6QGг[ֈ9ǵ Tg r ~d`4@,#7eyj#c^i'dSQduEN,~'f8 0)$w>CwqjN [楏}sI',Lu$`{OoXޔHBA}% w>!|F(5nŷMKa J֒ ̠rs]t/[vŤ9q#A <$J=a | T|* DGNr\ X_q$:$r*?=@ 6W+CTppJZ!D~vY]쒝q1//TWk]\RVԕ>EZ斛g7zH*TxuFi[ޅ@S ͎8\+\m pܥO-&"q8﫾ǿ<(O  v.uVzºݖI- OtS0>%ʫ8{)R|v{'հ[ ܸekxb;dπwA"}m8wQ[G%1ZJFTKJ+4@uѰ7!{4 xG/BbagFo]ZH//o9:F%BSx UA<[7hċ֢'m5VuBYPE<ROFO1BH #:ڝJ֮w a⸤n/DO&m=B^Ifiet"qf3CrE-M/?Z&`J;]m)RVok]Tv֔hawf|*g@6 X`kq]^K3Ҏ1%2/׳A܄w pEh<8z }XYly&/ +qɉcGLL60WVޅ[S(Y5X$KpАu%Я3 )xae# QD`fŹ8or!(1Rk^ E# M6drZ%t8KT&RJ,eϟϐdPsGeAy@Bdx N u)V~HhC4BQyէp[`єfˤQB>{l=K9:Y[L!G䆼vKb%9&)ϩ,L1rӲ\j#"F_߇'"(_UDI7rZr.'ۀ冷"s$eBw%,,KO\9<ДqSKG[!e^NߨD y#sm71,E B0̱N6\iI怇FP_\!v͠yVMGZTGϜh 4wXi7kwQl>h|. M dG-<:7I'PS_ dr<&sFBT+G%:q_iMS$%:2XsB/'񋍃o,[rc̒<e^n^ɕ]QD<*bS $trC>?lڶYC+ilsga)X/4;]!,617!RNIO%~ _/о{٦5_ 1AYՏSL%zW)* Pbȉ-ȇL=']h1P[ Ӯ*Y1K(1_jJT)8[p\Sӣz &' ǹ(uɖp`@D:&s*Jupg_JQ}G`}Yd/hF<Ӈ؎԰ 3u(>cjj(mp:*dmb*Q>_⣄Z9, Լ;@eSS21A dאI%qCenvEp$B0zcgۚb%9ñ;i) 5 tpVkh[U@$]K ~>՞A.D,0)웅㏚YkJj?/g2`'LР6Ho6~-4v|1mPC_4(eN_xWLzzb0 RrmбVqZAŸ;3X- |'#(3emk,M~?( )+4[Z]4[1H'y`Kz7$` cBtH$l/tH'Ņ) yheHKB*s&آ=B,̿Zy=`{* e~8b:@`zy VؠykO=m|*wJ0t-D4QIU  ;cNL[p؄tH応{9}7= g*v n2$ad4?yMik'ښlelUFTqC)‹zRݒO{E%,T2`f;C:i:B|AF1!6G/}У2mkC;6C^UkC~4UG1|ߚQ^IMjD-} h |B>\"ɵ ^9K?!~5prmB{ࣶyħnĦ'p hd%z=1gps-`3PC'YTVv:]d~K ,Gz7YB[GjsSKj@.T4_@d,PY qPA-9 䁶EbJ?ͤ*X!(d,@P Q6.l*,6`۳ 5E$c2OG5uw]MPQݗLx zd-<Θ[&P q{c+h"KD\E+V#NHXoԽk98ȣ+;CcS^nMQN4oIt߉<^ݑg=iX.E\.MdizNƝ b+@6hbVΗjjnqK=Z~p: )y|FFTɑGLVM̯Md˓&Lʬ<Ѱoh#ֹ.쿗hI/2a&ot=nu_-xG/jŎH0SjAڶ@~\$iu0Br"Jm&4Nf1pD qF0;}`bamW)$:yɄ0s*:;6Y`'='M2*"p}+_Y DI;xa$n7'g4{ x&nMK;F2j S(dǼ(絅(l.0!-{^ EåfR{H#eiKs$'=LzaIb9[Wʭ(evoCPwSCSza|X #r2t0 `-Wr,MKh: P#<ҍHo|*yLB\m{t %ު(V]l/ўG匢"Z_Șe&*k?*vbM] #${ M=^1]ˁ} {kN--,0q+;!gPjRLho>ql |2+ϗDLH@FןqSBLp.ju:6%6Ԇ+j'dL4wr(e cU2ꗽsWZ٩BY}Ԇ;| K+W_L)VڥC^=@u" AD ZLVq/mnro)Ú ݉RVt['vLCd4pgj~"+:{u%3;{ARZz,^31K8w^C6\wN]0MTK y' 2øu8&*p pŪ{ 4w3tA|7yЀ=(hJJ{W@Ft:V!7kien~`gm.>! 7@"&d7|Z%|x['GKAQ&hFlxyêpFCn : (J/B-aܐR;_NZlegIJǿ썷|ARP(<13X&eM TQCiYmÓ:KSh$1w+7ݯ/ 2nM5Iʄ<4]{VTc2T^e^#ͧbd{PT ~=T(\=2/x]C}ȈR t.k~.Z'^7yF#,Zt/0˴|E';༭j1ag񾰑EV;Kՙ i=pW QV{ÔQ%dXΪ ؠEM*IbmUU[ܒBtٹ$:Cbڔ㟇"+q,t"W좭̓)Erhbã  Nl]"2ggmr(-X.&nd.zBpjGY<[@L$˼2_0 T0l^/Z9*1% I>aۮ(zG16hRiUGfYFs+5$ @,=vKB}vE37.(\S23}Nk4Yu V~a}2(5LqOk4puIVOCZnD8<gA<$%L^𣋭6vp{@Nml9κj16)ƪ[GJv\7vsglPy'"үfLY]FyPP*5G{K2(;rswj(u#a ϼ,FsYV[ ԖљdrvO[IWd甋Ė&ƶσI3j揷|A'gwt[l!Wnq)R4ӝp@$YƷڧo:8Q2+ڧD#%FxRLh9ׇ fO'_S)anjD]$,clnD!`} ;::Iu`.O|MS+ǩ5{D[}[b Л5/S_^R00ُ@b*-wb{NopNs h׊ZLhPzOּ X_.lBVuwTa"2]~].َ)ڏC9B)Hxy]EgCO m͍y`C.[薨,ѥY;dy36`21'VFL|U+HkoNdy6;_syY5wB਍=b[{C(|KUIMWhb A~Us2+͂(cK]joPυ$jz0ZɄMZqyi<*bO?cdoc8yUti"?a*G&` Ah_9'3|\p@gC<: A^*Zf{dfΆGl\ Oܔk6IfS v0c 8X=:? ^}5 wq kyk1=8)\뎒0@" '}V, s D9dKJL)uaq@i$e}āgx¨#Cc 7ojX `L.tM0a6W^ӲHrk]lijwy70r{)sR i/_Ū{DZUn`n/zayxX}m7_~(/q#ҦzD1SI W%d[#2٬oĚ'ڧ'7&{ 3fXYG(K\;ؤаDG0PC4"!Jy!`,tKVGu yoWUpgI CPWU?.|6x9ZOЫoKIƍ#:oYX}{Z$0%V$5Tvș!n6AZ| T^eZƌv7W -=3efeD;U, (~4RHEݔCf*v{ƶEe!0fsmN[Ob( ,v# aPc]^}{iCr5 9y}|OjCڪ-474DxCpiw42tODbB~aC'3Ev!^^ wɅ+P's';r$'0pbfg@W^wMӥ޽&|/='b&>ڜ<vSo %ͅy)؃XgcNWI$ ɎSWtI%jY$z~gwvek,Y]H}^e!Ә](.O~bSؗ%p, Y6עԄ 3@ 7Uՙhd1 =oW%>Bk891}u쭍"7O[hBA͒Hr (Љi^(V)XY |ewޣmAR'ú_u q/_cY\e ? L 1n;譱LL涎:gGC$;C_G l8smx#j@u\ۿ mxBHF@?A&(3UŰh)VK+&ijpLu2s{Rt?pv #඘#3KDeiK9wO*|峁# _\6nƎbž-/+u;7+ RiF06PMMNDвAA0GƸDM}ZQYIE\**4 Yob2&!M:!zF.ŋSw !JtKP<|3"\F]:f&Nf|(/!]lx{:+5mrǹ\TT{aEiSk#Ⱦ)I`ȈW _V5s"tIce!GиJA .Bb`Y{ɐdȬe}eH\[&9x H`Sȣ9N6^XSe_Wɻ|}Jk( `~KiݘDd9d\˲ߠXee!ķϯ9w yw%-[8gk~sqqvl:<$m͇f:u+.pa ?[oK3a@:aX} (QYK{XH l$*2wewy09:YMKq]8i3(C (flomLkW>uOlGrcA3hdtա /gzoņBQ<,qs2^iGFUTJy)eW굞E)%d#Ő%a \h!o@8x *U) .q2uďUk>>gH$Les2#D"P)# p"XFi;aχ `fmM|Me&%ņO(6v6ي78W!E;i L8.fUȞޕiU!ƞB%~I &'կ)Pp_e"ih Zt A\.P{WߕBդ5RYzGM@| 9}ٔa w!Q-=.Zbu@GK7&<0OTWd_Q/ ?m(F`ٽy'h LyL,jp4l) 3`Ml5?Qɮo G-}QR̩rbH ٴK,AW:&&"ph}ȬBE2kRHwk/qwVXȌ_PZ"n_LOuU $-;_2Hŀg DNG# ұ 1wQߟ3,6BHQYyyygϿlyA楈]i6wY6Zݣrz+kKWӡTdQŐB|t*NqQ:s=`b+<(W5nr'Uf=fZF&,t~$%PC; Eඒ7Kf 3izǺObX`˭[T#D&94M&c͂snD>\*>Ԅ6Z;c|/3D* b! ćk3KRUеRo\ >k[jcʕ)E_!.rtk9k $8r1ŌA shTp)kR.MA^.j`I[!J]\};Mi39`\>Vxc2LMjO`e vg2&^+K1;I0% $^6,k$|lL`MU/u'Ӹzk{G-/\}a&GBeZXtvB8Xk:ڢL$,਼{2>"|qAݢ0+$~- }Q:{2i(uK(VdIJETL@[ZO8[W%VܰpЁ0*w u#q{~z~8k*_L݆D:BfAXZ`&q ޴K2  `CJ zzfh㡵,mZbңC?' Uydqn\5-C8pG֟_N0x:vi &ô !bMS7ZW:W.3ԤO]7E@p-,o(U|(z,z,gJG 3hd^ c?xSAܫ/ 5=eI4r{wpe7-/c40 tӮey0.hkPl]$Ñ0(΃Ʊ`R~E;Z;(;hB؄'9%p WI5:E:b *cD#) A,6%/)FM֝$ &=FlQ m D)R,Ţmw7ʭYSP6o<H!] M;inO#OF,Q>uQ2* lNĭ9m{ۭ[ o!4v] 5= RV /Syg.K Yk3O4z Mb9ؓ<ꂗ6Dn}&qIL&&|P{WIGyL}}?9|[yP\fNH"˚$J!Q<R@Ne06p}>!d3>ٙXٖG_UT!P[>^zyj3dz`^{`rߢ>x^jxUjWaݜcq:%S‰<)ЀlR tD0$N*r1QbxrH|yS;nҁ@?mpQ$[{({N=VpTA"Qճ8Gq:z|Y3{Y[?-"Yka|2jzgYݢ\X^Tɫ G_9^w$ʊB/j6* CRw^I؞ - O{[tu,bt8Y3aʚ,S X/"4e!~eRՖ.Kmx˜sMM/~&?WN%AK-@r!ҁQ@yrI2,Jg^Ryw[#Q:DGp+.u/]ͼFCnUtf9}s04daʴdh](S6F#{l?V!RwyW;MzJaBRI~U,M{Q/ve[ Bb;cU^qJOC&tsIZ~ iu0eM q >h&^d!o__u4a\($K`^PE jM)Jz'^_kG@rWx.VʹƸ<P5~\AB.zNW5,B<4y@&h֠X%cV&:':&6EYΠ(vᚨJߵF/n3qWΊ}6P״;.E0"} ?)p4hMz;@Ћcމe=<t8æp [bL@e¡ |&?ۅW%su@%ifwn3nq,bC Pv-`D|ii$,:*slj?P _[irʷS.ڇU\ϧ.J`V& 04wPW7z]9uU؀3߂}z2/v9NE#9j 9 U ?(#F XPíb4 5Sԛ2h#[eï #VERjD ^/yh&oՒ]Yip@Ke$:̩b$>( )럒P=ہ.P[&`yPm`l>\l絋qAk{fGFi8>%jD,*aNeV]eZQT!gs\IRw6WQ_G<8]#$vp8g+fzŴRcR-nJ;b a~~̨ϐBH}, 3M"Oh&WraObhySwn4X=lIFЁ*|Y6҇\̖rp)Ow DS;αoNd?ݯx>oX*j5m5GJܛ V/Qg>7LڗrR(UZc+0 /ńqNq=gb2l6Cլ @HI#B6[GQ.DҔMh]ߋfZ7\S\1NThaVR%yLei ^ %qM**2{3.-Y5# M nV6BBB=,R{`E4W]ί=Uؔ`WŴ6K(|2EofBʝx޽rJjltƁ5y2]u=W? _sK'_zzffP1 M}2Q?>W\:k9X+PN]N"4q8gUZ6ߊt);yBDov#0ɏCya;j lN2hg.z@o^CLsttyJҨtʆYXIDJ[M2# :? ee<8xadL`wID>p$jI;!խYf􈀹UVD<1@ 7pj"OPhQx:%g弄;T(]p8II02V='$$/SWY2_eMSArp n.Omr ^Wt]|XBL2T:4x#D0I;ilA|kT/}8ژ+a;pf#Pb}Ԓ?hTrtOhhF~~Lp(6~הoe*Fn'WʝfEaːb_?1/bX gğ3% Ⱥ?~j KOhPj q.%әVn+LN>.+[E |Ux$4(*5qUt%ܧ`57䔦b ͖= yM66!RGqG@6Ϧw 4ܤD51E,UR\a`SOta'BPu,Zzpzy[Qj@C4D^y #ͱZ( 30m;6=͎]~_N(Y-OQT):0`NJh0kɪuw `]A %?Zǹy(MP % Rux*2K-t6֠_xTFv`]~'kГFU_y۷b2y)nK@ +אs{y_!kEPӾƂM?Q߻3F"D!}F3s m:gf3nVpu¨qKQJl6֜E>5V'W(N%yP0D5jw!py#M͗UDM>b Svu$bɆ Q OR/:̿fBa;x˚a*'͝OˤVtB37lwC ĵlcpgX_w;p*ш)Fm-50fp F?fm(Dfp&ARDmp XƊ؅3LqH~mAd[qmWx/9XRR81@u qLY=﬑ I uP[sK]̕DM4戭>Oem@I.fb~'?4|#Y-Zѣ'WMNp~`Q=及`rNpkf%+DՇ({!UI`r_^ߩ#mgCU@i"U}|{-چGI='4SyB m0,SSY^9; d?[I, c VKz+* ̬qq7Jػs[dB[?~, Cw3!-K{ZgsLABQ96?xp4;ةfErЩ $/H?٫&CT?9{mjܢ:ͫfB<L!?9Ysȯbk!S2^!?h'NV[1QY,jSN "q&}F2ԓm6m Eꢪ,`FY"Bn|Somp24n*o(g'˷L"'0o:̟;y]^a ?@kY DI ;-VzɎ\S%x=Dād~oJinbw\ %޹NlP8tF:cn!h}*=/l <*[CM2$]<WgU8/'s~D^zFZo86Ӄ -O[mw'*mxRݿޓr>wdi3v3F!0yq[ȒAʆ>{(q3Lbhs4Բ3-*m=5_q_"k{!` HD#Tz^3ABxѩ#o:{/2 ʑr#Q%D 9 0!\:O+PTX.LQ-7DE=;z41VE:Hi)7cD$ts \yElZshEI[u!sYYV,pQ<49J(_/nIkhif`S698 ;}ͱ23X"7r)%Wc6y+.(̿JO0"'z,V2bW9U\scs Db6x,`wW/~[ e/s1ճ?Gl<|`6ybZ)+3n["NeaxFt'6`}Mih Zxgy [ ?mʩ2TWaޑ+β1vCY: W: yN-]в^g(jBtrzD9f cee9#Um~>vN>I]`VU~Ҿc;ƹ&4D'-%m4ʷ7YV\-/l&!W Fdz?eYψJ 2nA" @ v e/PJUvH2/s#+]u `P~rb/\7ZkUC6+]|vcUԾ&sטh:#m8S*ٚLC 8Ka^ Ik`Kكܟ7[^{ ~>F ]O늼i uh d`4qv(\Z]U[nOUY{}C=ϹL2w< g/rW,.5r܈"4#hx5멂sj(vE9V#*p, j\nB٩{(ӽwV)r20Xvlͳԥ8I@wtZht=-/d_凜,ct1KŌNc75hn/NmWQX(T.L'IPɌ{~_?6x`r90ki#a2|I%EǸqXq]R֨Is+87(%Vf< ˜V 4zIq@Yr;q#67AH( SPƴs?Y*kq_O98G: P ! "XNcqlZ"y7 * Ę ilُa.YF[ ?&d>G߳? a bxRũozx8o)m'OW^[cL i+\ dE8EDI5OZ49eٜ/j.Q{4k03s[_/ϯAW{NRM;1dCZvfի,'mmΎWC0e ÞnOgPr5avVJHZXU,b[dM ֪{C1ovŽ ʣ"ۀPqzTG[GǃγI18HhQ^FN%!*q lP n٠8\.R y$mdfƴF6]ߔkOYT0ghH1t Ĉ=ʁkP|mt2YV2 N.ћ=R%^,1;;)hcaR.MPB]?a«b{ob򑚠#,}+lݡĜR dQ"HpIoFc0J p|pYN]BSͰۿ9C-ӭt[6JycO=>u@N%;@1H Ru{e%lڙ=9gJ߲ɂA_W$~Ҝ̌qre"\KɣzֿA K18`! :!5_/},jT 4mʳX7\#qtl^AXqA]uz'[$u i:8Lk9Nj8c[{`R^r+w3^.!KWf5!0̵y`(mێyʁMJ0Bh%,`(Pf!qNsϮCec4oH% .2~;Lڼ!$Y;~.T[L/.%Bm p-QegQmqr*s gceiDdg6C} Tr@?kxum ٷ2m̂gt7@>K$B28?͜.08ow)c0L`<4j^9ᏙD"U!.rK.5(@KME{mÌJ/ "~U%C84}Ǘ.V:3%0XmP0cYս|ɶ)%5d@SWI_1*'gkjkTcxDh"i 8bWko &ƣ?nsP M6LZ .pIʮ ;9rl+p>0QЩy Pi#i [RwsMt1Tt=Y:H>W9Q>>5seh? _+ S<FfB \NWG͐Itl(!pw5 Ll@vf梒#.ttpzWS԰(D CyF ˂(>/s[,[Bj/y+ܠ\e2li@XwzABaA1 `5l?1]v{.coɱ=IEKMF/jP|R5P<;/ ݘbnZnꎣP0MׂU Dsչ??ElwX6>@q{Uf Y: ]4lvh|iKd@;PP$8+H:#)Y%Gk؂|Kzė9Dƌ0ۯr.ɦ~>WP#SQOd/3L:c8H~]t%nGSBSFDSo}{qf|px}a-Tnz΢7Q&-l?*C'9u^*gkkK 2Kg+wAnƲ|Z xg+4c֮GĄ @\1;؁"S+S= T4q-,FFY#l!Z5}dcU$Vbxe  5=( !mV hOTua|Q x)g'*Wa׬^﨏 DŽL_Uz 6a'E _zy#x]XGY# IK<Ǎ{0#Ms&^A$]ZLl7JM($jRn_WI,&vB)4 L;*l-s)7,LC.>_7ǜ/QWTAE}|I8yXm!.lW lts{В_^*X'Fw%e"4+ΗV?,U !MͿNe2&&(%U`*2ggiDlRR4+h)_K ÉAqPD2IkY"u'=3W%IJ597%(K~Aa07՜=8YUD yS" vrC!ɹme~val0y܀#zYlbmj4.l8xbMQde{({P6#q7 Ď[3$ Sk߆_6eS26Fdwi6tDEg@0&RCIĤC%TD>֢Tnȸh)+Nfah(xz!L1x>}U6)k@A&f6ouZO:97fVDC3Ь1pt$3zX|d>L #dk}o+Ʊ PTOf]mQA!v1JpGC9'֊ya>v>((^I3\8%mt_)?9{b+?M־NL^`H{ S3M3)I`[3*)/= l>1DzE.EY 1+G[0# 4%XC S_SM/-uxwW>Pobۋ5HyڧFuÐ3mҤBXEK~_vrKpYELO_2iG}YR'aY'0|nFIMn6>}mIZj0CvJZ 3, LIn5d3Q'KN65y?. F[{3Ɯ##q #˜io|SWLFYiLj !* Ok}6E0*4m%l]k2TySS4+ C. -l`j!qd|֥`xDTfڢ1O-@cW?mʷkA}з%iekS*B7)f jt*VKY;$fFh%/ ˛g{2EEGB3ɼƱ{>nO,< , (S R_b|UlOcB{*'{(ݵXc&w(e̽$6?}9ም205]dX=|غyd1n:op"u;F7!,e XET -֚7<nbl廉Y%寪hmԱ ^Hw(+ 2q=_ } w|Jk}H2"I]XyCVڱO~5lna͊ n<ҪC9 !<<( >Gwăq$QYW$I3VؕWP 3zmSSPgn.nf(:k)ͼ+LQe,{#u,Z_Ƙ+KZ,'+ڼ` CێZi6qAL+-`5Vj\Ź3@4_|?]A AWD.c]gn))ʎ@%pNqV n-263G*e6Pڰq,g& w7g{A׷d 42Ш- z?.֫ϾOՌ9\H4m|UX1 +`lJyh7-:Z.\h߁Ū+#,3Pua{|xl2KPWWrp`#z Jj⍑qfdcULGբԃ\ϢnPsJK o8%ϗ.TzOaοE'9٥2fgS8yq`*~f3'j*q&kSDde)J4V` g/.+ޛG,%Α=Yvy Ìon F2U r!.I&LGRWנ-l&U @Kp}fyY27|t ty(AEÏaOTok`I=gӗLWv_+>̎ӎ>ڜoCZZȹxZ5ЩY <<\Bv8>}QgQvT&|d VsIVNY eY$"mPNR~t387uA8<3}e :1v\FԪ|xsNn[?;FGQ5+N\*䄈m81<` ydªyg^"vrJ+RAǝ,njQ_@-0Oߝ]o/F2V=wE ־.0qF_Sx; zh&m4&ujTOc\HD?CfV3)awҔ3j˄!BM~ćs=0t]:YU$Xjv[4E53ϸ, '),ǰ ݬ z㍝_"ɶ=c<1(K>si94^Z!!xXy!itI)̠GxsT(tc?ô 7ȉQ/`U4Fx& @#Mz\_;8Q_Ԫ6 E,F+ǩusv#DΎ!PԣAcޔssLbCHA4@Q [yH(N _)iKp'J˧GL W2vRgP9:YK~٫yb?q $!$/.6K!Q^\ %{.[I2ý7c"˜W}j W)"Ɉc&|y/56!s&H]nO§Ѯ<20Js7%B֊\*a4..ptE}o)oP6C>\=ݸhuܜ6 jHO{LcciJ7]R.IB'c~3|ZYjhLYa/0!z>yO;H;TxG+:ieZ']i\LaZ+[2ǟXͷT@RSiI mBq+ݐE ~rJ\\kJ:8Yc1N6)rQ[XO.)1@LéXJm#˨OK[t<Xl8Ra4>Iu ;f5'ȧـAmRX\C_<=t0д\Bk^jQdiܝCDTH\B dli?i(4v87nKJz|tOGFOG4-CXACE,vQKӠY'+,)C;jx;uʮ6k|yh*QSbwC4Z_אpmXfOKmH8q}(F9fc&O!s"#7Fj$jZZ,ͯ5N 7"4F[bjC jPa(ǧ[mnԤ UA-ouk $8#JÀnH!fa>>]OnԦS_Wݻ$@4PoLn~?c|m4(("߮Q1TNaK1ʿqܿ)k'xʧ)\H&r-,@H~\ޚѸ_|4SYy{몭\hP غ>hxM{tnGo^."jȺ{'e[<ľ٬dso7jb3!LLƈG85Nl[53JI&a| ʹA 2te |U$ @QwC,b,g¯}L5.Ab, WȤl;2Xl'Ъ#0ڨsS㶡V2f=n1F(`R +;EHCЃᐫC!&&.ݕ;#hC`P?6 Ps)r/eB Q 'pk/o(`K`q'.)XNFԢ8;hL,^ `auÊ&BNJAOsqC@!җi.S.I\EAm O) oιC%V,go31d?AAl\2dw$^ \@k_t!5-;]qvЪV9WO7by1nF.] byZ04}&dhJ5$̈>nMID%pG6 T3>G}R4axYа$6 jA=P^,KV7}9vWoS}%g?wDnE~e4v)|Y{Z9[ yj!4P-woVuq"RpZR5 (S1^PjQyYa>W/i 0b]vඡZ۱6ٴW=L%ڐϼL>oi-yȢ\1U:gWǀ䏂s[BTA Al?h=2~sqnX$6r`p$H1Fڳ>Ҍh(^2avCk%+*)LUxuцTE(+D@wsRI(GoΩs07p_>4.Y(W&Ae1u5\~[k ZafS>ZtQd7tTog LO5=díx&SUnr r d|%/\hvE"y^텿 C/,rQI n|]$t,2 q(.AޅM®Q sA*,IԤ,Ž7ee5p҃.b&nЕ ݐ)~fQL͔ DSLb!wN+P֨u2bUat E$hE/,zS$+^Ṅi¼6 YUA2CJ-aemUTޙؗ֗[#"U*vEnqOօM c]R$/vV6gsӭ=޿[sx@SLsVd4ej1duaLyF<|m-![ڌ@iZE61Tʏ[h+vQ1<'NH@#b\ .pRdNU\ы%9ѠN~Ζ_lXk\Ўf9I(W{/1ΗU)տDbX~613\G]QvCl8ʬҦƝ)m^4 l)"{̳s!f7uqd^9 pJ(ӷO,ZIߝȦP͂>Ԕn뚀YZ&/ex*,+#/d4^QZ]C|_~Ll-ii5y.-৥t)8۹uXy+uյ F:JE/>2 x"̏fh !%WjG|)>c 3#xH-4ؗLV2zpk['Űtk9s_˔Ͳ?q߰dܮ5z0oD!$>Hx EVO0d.lf#"H8-]̳ye6sH ]wX'\%6r &HPi Ԡd-U'1GVLR`!XH{X=E3ǧ mpܒJ8ˆ{h#PqNPNRϑ D B=S ‹;kZk&r Rj}\] H ܬ47*[-*q98(җ&g9]qԮu m\C,T}ntcyA xEf(FoSvu@_Ex7f )Mguǎ kꂏ۟Nw:~K88ȷw Hx}3dxaoԠk\yš@f~^W?S7jm p9Bӛ5ƒ%s"Ûg_TpKOpd "DId9Y\>- C;C龭j}h ŨԹw*[|jSJms+L|?0\1ڜSYu~dX#\ytlXY3б9,G}DeNѩkgb,5nvm zH$ Khp89вuXaQ b@FPLKؚ Y_x~G^NN(- RTfD W".Xz5庙ÿѴkء;Dih&$YHv bhixDϮA8$i(-%GU: . p~(V~=V3'3:봀 q2*VeגFZnN^ yC>C S\BEz!jgΧQQ6Ew_3X+1SOr.vRvNǒ=`N5]ģcH*hH^Y|l[v>0ϸVR71ta "w*"}LP4j?\ܼRuy,1=TٺcO"Yh o;;_~7=-)ΆZBI{fEsA)<34^* ༖[K$"[ zW B5W߳{={*ld^NX?>DzӵA ZHl|03smĹSb~\Kk!O2t12|LVP62( ԛzwe70r`,i2 !(X6.u`Sf)LTa\R?ojdv`}(,Mex_ !g 5rآe[=;h\;Ҽ ,0K+"g،S?b\((t)}ylaߣ ٲqW_"@`X*`#f?F:ܘ X4uLs 2fC?eD?EzR1cCz{2d =S5y\num9Ymm ˵&6Oof~3s5Lhd|U&ٿgf<|$y1|CְrL|x%~Q{܈d P]*Ha*&:26״@ Y<~$z0f "GMKV!`44.J8ŽT*#DļNc__"{Lfk9'iU0q=6md5Q F;L&։-ι5zA۽8*exs#.BNdEHXAeVAPN t/MW"FR -$FgnKYTӂ^w/ TFåBk 'Ĵ< oGY&WI6}6TJ }:t@z8p&TˣWC=x%NNZ"mjl1`n1>vc{=Q{>tu3][QcDe-oX돥2Wz]vJR:\ܛ nM؉NUTouBYV׶nޕu~& (|14 ( PW~BŴwA-?yZ"?<Ȫ@]#tylfLTP]+wtwsIl2Oy]%nu|-fGD?O߂\KD4/'X4vPI3g``mٲ~.X0e\5!DN nO(M P|"G:Vxgv&k#Ol! ~|>%EkLm? NJgJuJ4# D|BK0EIγ8Q5wϲZYu'P.7\H^mԓE];C+?㑩C<l_ukI&5 {^k& ?cQkWQo+qht'(ǒ3LʡXw!;Ir-WYZӿDuHj˙vR<>t-JD7oShgi'ѪIQ^uПW>]Z6͌f3A n0n1I' T>[u.kM\XbrIt9&pݙv)z{oU#%ZKEFh"u[-iw@ f/?PD6 BcT!X]0 lqˡ$ME&lB nZCf\g#;$2)teK"V FY/&sDC2] ]:0?$K+vo5#j4lm>53Y=oosHe'WF NaƆ.FZ'Fz*v{zRMoe<$фR>$~Kڊ,-dylRpQ{irsE Maᦡ0rsm3ƗyJ+_1|DlDlHKc _&?MϞ l7tzER{T𲈬aX1*Zǹ4I&5Hb#liuObၺP'+1aםjJ! /GH1Zx@EԀk#O*I(,mw,nl AMtEHJc7/5-еWRbF}縔!]s,}Z:$.'PGxOw8BX7 !YsiYYs眞-dĥL`~,L8Hgk;%,j/"uK-X U99jb?_њ&b0݆&YTi1eMapA?YooƄHF2k2 -a!pQ= r"sc-K^:$\m/XLɨ{;{|s=꣋B=aRܟ0tt/gPwen?YGmw27fNlE& ZFǩYX5SbqGOChi~-6?0\$)e.ȾIc^4%,z'uGKYN$[jvXߤWEhZ0C3Bi"":<[|5; *z7fj kWW~v''L48$&.%}4Sy30O4 R1q[ ^`'R̠sIhyF˦Y2@iV'&%Bgu:63n9Yܜpƚa-c*=8t%.W5Nۢx!Ltʌ 6*(D=]Uh; 2Ws1K;H!U2(-Ʃʑ ˇ dQ%jfv0k ƠtzyϮRL^^jqzd `fɲE,mV}fklMfeZ=ղ0fԏ 6&@!v茹;c+j$eC j4i&ٙ,1rje4UY98t*_&KgO܋8.%\̺43'r˧D#Z!? 3CY9g(d$?\(܅97~lW@*K27GYE.a>:^ZpXa]Gy+BAU}`թŞZݼRJ[G'pB/<,BZ/ySsGc+?}Y`@9Ϩf[J`=Zq4-P~=PH^62:lVzV3 DuQ$Yb$pKT*ih{ ms-iF`鷉jAzɂK?آa!$F1qEHt>xm,AUU(j~$oPqDvK%Oi e<"ҌtAjt{?$D28(TQ|w%X8gyH/'q׬zIho$֡%(PKzh+cS-H}~{PܜD?F[}Xk_הN3ZJz LG0 튩@r'PinD< 2V/#K?f}B aNsU,v]̊NU:R.^q,yo[Jԭ` F5ꩇNR !r Z{\ʔ+{[dBs{6ϲFJX-H5D)V=Kp}S3U"NfFthD {m9݅ҔC:%y_Upx;Q|PCBf_ZDn{}?Ȍk[FBG%vsэ@G7n3$c!*?m9*DQ&aGHPF򦤉"9l4.(Qko9[hɪ8C8g9rnzDO_.XT&b~xoP[)gNw}PQe^$U|hZx}Kd߅',rK|$y-Dz8.//NI؀=#xE']>y mPQvv$W&[&o>;q>, Y՞YŕE'wcŢ'Ի(6`%>~q +D)S} h8^Uū$h\Y˟c#:=J\d F + `B ) #zM^j"b)O;u/,:76Qj44_Z,,e^}zSmU-DUju"LSH$5c!3# {ӕG3rY8LV0p[ceXEĉ4w[A*K dœpwTDqZwW7Ა+V- E V KLn6-0W٠'Mعа}[ -/+@N0<E҈ 5'FkЁւ3(N ;3):S?EE%;nzf @mp'Em{^P z >A=yA]F3}?Q3}꛵%uj-x'$xa?*i=.wϡ(&xo5<(~Uxf DHFSCtjG:(+ ?OiϜp_e<s5Lx!*+ڥ"$H)^I#^Ìy*zYC2zMwVg$lV)#ۊ$=] ۯWq) AI ԝ9mOҮM5cD1EvcavoXP3qz(&X ?wtKў%{J2O.@Y9mGj*k4M '(O).tBJ7Xv΄R'`Ε g(dYyF^q2-uyȜN!yQ%<:?N^PDЪbd*[NEU~ ; {)/$LC}ںKѾIfoc wl-6Zq"QmLPy[/.-^~ g5[˖Yk??S<̂&Vez*X9JAL=`#`yTJºtzM%gC{ H[*~s2=x=l0ڶ j[p3c63{eF1 _g3##I.Yj@},xjφKX@D2r~ZKѝYgRV7bΓQ2"\wRa/Qu˂:6qt:7cDDlI38Zj5ToOؖM?wn;3 {Eo J6Q(gvp]rLpӼQ%*NNkUnp ]I53}`u)4ڟuΪAE@gk5pˢt7X+XXELB \i~qy΁!KXU }rfM dRrn/J /OIRn&ګBi{9dh8[Wb% +ߊd:~~=8~t|7n Cn54DaK^հZ>A?UZ‹9^oKpTQJO3>~B;^~'F KLq"%L{Mc:~A?EJYv065[o솩}ɶ0:2~!Cl2ځiCO'!:%;3MB~[]d{8p '寞:BP}l}|>wɡ0d3h'HĎAuhĪD1%J6 YM:B7 ]FkDi1jTAj f)E𢜧sU콯"') ZsEm^,h,IC%%!J:]P"3-Ot0ڰ6s!!v8em-c+Eyꥣ̰edo p҂5K:x5SB-ib$#F9xw|YX`MkN]5*d\@Bi HޫsV,J>}]P^~,bRGu[l旲/ *{A7#-* mwb@X8\d>Ny!le{Sʵ)sK90Bɘ6;T/dȝqN얅@KVuJAT7cɻ1es:}rW3W1#}) K,V F]( ˴KZ7df3bcL6/$E |4_34VA[e",EB3yYoC?$R# DF)܁TmE=' o ډѠ_́)f &ȨpEڏtEP٧!-x ai?5ոJó)" faF1U % =ʭIkkZ&>8+cޱ `H1KS!ԌK}b d`K:b2b()\A _Go=v2wdk5M+|:WJ6`tv~R~wx]EoɊ|QꉴsP X-ZCK2Z<;4|`ʒW缃zGOQ*}]CS D_<{(/KarɢiY|w@k '* a;UH ̴ffPu#)P10Cv%BJܤ3A6ۇDsAž<>.h|aŜIV肤%TdUP4>d9ZF Z!*$^Э8ҥ,q|ԞDg>8W B϶q;ssigZFiI"n-1̜9&ӻ:_Cq;5ŢK1M8ԒiW;%j L걐H.WUMeA Bfly {.x?^igCwvS>@̵d=,~t5i Q&%J95p$sK72w'BDst5)RvO;xe3PU$?ϓ"e,,;gmƶ7FD*l֣F~q;}B&۵!  Isw Fo [Q ~<@&E,"sɈ)7&Hۭ:6C<mqxn_e$3gB`yVvP _ 6Q%هS\Ӵ`xu:a1[5>Y]'}N[v ϖ"Vj=Vy0u}4m t@5 $oj EJpKܹGFQ-#WNØRYW31fݜZVMk]ʻsn! ^?c:5 5sufY&3Pv~84%T0)5 s}PN*U:xp{: GE=GSɋA[ˊ)!(%pEc}͗X򲙼XC( 1=0.kȘcfO0}Y2L=npC1rg鼛RSG e%j\~S6a:jYM>/ vuj #Rh/=5 o*kS琉q~w ܱb[a$<{x7kzS0X;@^HU; 68}mƯ/rWoQW_ wN0^:>ZVK@F9-ZǶ(.J68PJzٸ5j;e]iE 2<Zs=/?7s t""!ov[k ޠ kmnm<L8+=3iYru E3,:(jbx^ i$K)>ѿhruy_w{LP'vb/mtn.Y~ ԫ&4|:ͅdwd;痔|[}t!R)9BK_/P`=^,~:wnzʬpߟ_U J;V=r2F3QHKHO\@CHX{jOov]!cbu f*[__g+I O/.i/ (=Pi^X0Wb ˎ#pn?Cb7./$ @cTBYp3Y,A`墢U]#5/pqn͕u Q4RyGlcN Yu Wd(vQ~ N"6Ao5H7Nv0u8"Gai":j>&EA@b:RDJ*!EJue BlS|RkP5ii-<^ǓVPt[v=E6Los P,Q0j}t-;r₭Ot\op|*Ed)dgtuT ]p~B EϢP/G9PħkƟ ڮׄ^qxi>]li.M0iigE.~WGK#jX:nTa`>l D2/93o0>!̟dvس=dfc^k_[-x."XT$%ng6ӏ\`lbs(ng;{;xu-JpRoΏA#ؐgt3~}[6V.gfJV>3ΩdzTTyx^pKCc,l${k1 5k}ioee~rZ'4aV5 bUwٗѥ/{Pi aM co '||6*[ߚ&R.9Dx&H2oli::Hxޔ20+DFb![,)k-*v; uP!]#} 9N„>[ׇQ٤A Kc@?{znNi.ԩ"@V(aTrAE:nzRS((/D`jJߊw U=%jLlo_ߞTs&q}tj:ݺEg?K%K\.r7^'2ViEU?co]75 ?Z {@ iU ȐD~cHn.nHv;8[e؟}E"%/0kIc4u rs/]&ه5V3Z ~R ?4^1(B1o]_=ˍFR3U 7PVYef|YS`p:lN&x fxJ:)W߬y)[$(j3I$oW xh4 ܤz1rͲկ)ht6J)STQLJq7=͵%+=YCdz[ZIbhKpu \h& m$jڏT$KԜ ߔzER t l βQ0H^Bìs)>u,e(諭a㼺H$Y+8t(V84 0N~ͼ7Rs#&gzŽ"H4no>23JX\ Wڼ4\ >+O=9 0;TR|CB6sk|Sq=[s\!ٝҠ?SIbE+s'H v,f - G,Ә/|j;_i5j|#҇{a:vQ ͗ $IR\B=o)Q%p(v>U QكqX } 9T2E'd٦̋+Ũby:xv}'OMB Ś^Tfolk1C*V+ϕR3hmC6? }6TG ]7C LX3 yA}u!|H}RL)!liW#}CYDN싄RUW(vF0;JY;50&߇-o\ g>qdQ-]jmuդi̋`]Wۢ߂o#$n0>A i"Sy=%YaR-"䪵qAű >?`v54]] J"wL%G١cqd ;ZѪߋ|3HkP 댺yVLqZz_"zcUm gBzCmm.aPmWs7B'G N4nnKeaVYe ʿY!"Az4#J9j{6[Fevra/xrّlg:\OO_[V * #wΠN&F&@鱐/0.}"k $=)!p(&XD\DoVڊEpتddeU2h_ 2# 3QR mcM#B3fI 9hB/ o1X|Gʧ0FHL{4fZ2yg8lAcˇ1*;뾋ЋE%[mr0QNSAZmiG |wq1Aeޖۚc'|e\S5A<00 9Z ^< ]aWwYX݁9jDKq|lYg76;SH\ҁ`w'b!,0OWp@ǟM. Yn\b3XƲQtƒ `#x/_Ψf\wk(`Q&M;k~,\5;_|ۇygʼn{!psL[dc:t+MLRN{X4wWL@.!DTWY(C>ۄ4nd>}z{ۈa i}^pٍѷp^d9"Xǀٮ~:^RFEcBހb\NO*po Y'aɹH3}-d nCC?}Iɵ?UF&tmsc9Kl4W+ >t}bF4&G'94em"!edBC \ɄH^8ˣòy_TH)n#4Y~Xe[6 r$"r@ݻdvM+ *5Q|[, ~0&zdVOZ؊lh\nWROO/ef)S\cBa/5jύՒ Q֣9y߂iD>c?]!ˋ,d`πV@&5C^rLL(mWXR;犵S L3dEEth )\Q+lo+f`LO'4CrszV+8OU>ׅTBe ֿ19ExH}*] S|t.i^XaM|L=tH;NI{r`j6"Gظ/NRqd}Тr~=7mCk$`,|hXtmQ PˇQD6eJ4@yEdBzB,tKy rix5HGB.JrG\u` KT 8(M-_yP] CH}Do"$1) yv0Q1!#0I>D=L^;X*c]@xEϲA#ݽ5= =+QeWU#Ju`<!eD+ PGN* {$f; @ T2g7K6 WW !}AV ީ:Q4~eⓧ]Z8WAc( w5K ")}nO*AHa0Dl3Q#ȡ^]n &8wA5ʙ^<棉>I~ m>p#뎓#oF#PXtՀ$RuxgE4('F_$)CwuyH~tJmًPkʱ+C1J1N4dW[ЃGN"pA7an}°8 ƈi-P U+6>g[uVc8q;S;+A ̯P IY*pt[BnDem&X9 !'3WZ zYaq J U'2+HK@F?LnyUu^QUǞ j;|h{ dTHIKxu#MO^e] XbYNkg{q͟ۅPzr}"E0 :-+lQ|ynZf" <rRBb)]xmpjw7R[7qSMc(HXҪ!!HgQsF+C@{)gOq 1gW!rR*w1׃Wil$a8b"|=KKwa|;gUAZ%3F0;:pS*MrHPGJC7x=?>'vv #+_lb@nLwx\yZ_)fUVa|cN f ūӼiwgTFR[B6( 26xd3pS_Zi? ^?j!j#[R-/\DT_gVW?,D3a >eUOK4^:OPCP,OHJpi?MᶱuP0cgH3an8ݎE< f "SB@.Dw@{s//4˳Y]z|=`mJ%̙>$sBthVPt])?*?vgf˦`2NhqXe%6b夆TxCbm:E!y5*p[DX)G% ]`DI'cEe QӁx!8%9lwHtz|T7gמBڇVPPcjFcWLvr>l~øYݏ T:fG,#|3~ۙ!@DR{o*GMfj^ =9w] ^d=q{u db?[E,{D )cc΄Ъ=™z C+L!I:|fCg[ 4n+S;}Mj@q'>@0J#\S< v( TKzND4lKyTzkXPVij! (/@9uǮT9A4pk. y2`;eXS?լꈬ5X; 9QV;IZa)su7 aی2V7v, U. ū07{fO{}>-a31t?kjXkvÁv:0BHNhpp4Z@p=8/:.]P\"" "sS~s&nyYHE>bs,) Q*A$&eI|\A8P ˝3(f"&%KS`8VM =1JI4-쪂F}\隊GҀi2jGQ?:ɽQ?v"ˣ&U'goZYT{tDN)akJ^ <+73妥4)C {y;st4GL찞 s Qc{"Y$}F\vRbn}}H5*߹]wycuAm$?pHZJAO%_ƒDkiż"@+GfI;Z9"06j 2R$zNN#NK' 5N ,WJi !}gSU8B]V΃Xﴌj*i{7qӞYɗ-h10GQTXܧ.xk K1`pT ʙxoEr:5KB#Y77s >D4*vwJmseJ1ol~NBs+N q˰XItʒUq7B6osSO`6l04ONN g|1Vm|+9߇4/Ϙq;tMF.` ,DyyPFZ [- 17pSI^WKH׼K=T%PJa+/s 9zB(\V |nƶ 덶َ6=H7́<[$݉2}X1Y]-qk.wֺvZz1D2( i6i'lб]1) y~=Q)h~@fYi`Wowxy[E38򧲵{13K*&jz2?"=fs eD`f:/r[!E}6vFp߸lVcn~xyh$igw_N:y3=*bq4ެ#˥4ATy^}[UАw{; 4w!^h$r5K{֞mR_\yJmIIDDycŮt 84y~uM ϼ2]<\ 0ui!1 {]jV=Dٜ|WqE_I&q Ң؍˳\}>Г|er d͋ˢWMy9t'I_+(I=ǘ8$CLFA+6h0[ET5Wuf'!E/T91}ӵ_dp^O#!>VH:KKU2ҍѳ"6Q.&쪪# `|pw6}3+#QgPB8/d&IR`6Uꁈʟ }qa^y% z¡S\?j̒o7'Y2\0i@n>Qw6蓧W)V_w@&IIݽekd7 C)Vjl~T8^ͳVN>egbxɣ~ 82JL!|wz@uu%_Z0V*a<*Qk8&= HT* s؉ `}?7U퉢~+[q$X2:*h``o٨jC9A&-lqblwV9ǭrmG`YJG] *ap:+ȩk]Bv Y fei F(Lߑ飼*g0hm:<$<%0ka}•#3C>4%d.XR鳮 .ڤ3&=~T;CPeϗ8.>1X[ǨN|ZYu@>$cSuB*W8!ҹ2:^9u3 =`.%.c]Sxb8A͕fia"x-a'!(#d-ɒ8UO D )B]I1HHnk8ׂwkݠ/)ezGMNNɡsWE{S20Ï̘E^+ȧ[ _!n[Ϗ o% %r8h Y c rI}Xh' g NEx)vޓ.NDb<9M7F3_Xc۶\yV#[ZHjA`D3W0|0NhXlW6ڳ6hG2sGl ƀK4O|m ^fw񊎴e'?Pvn_ѸPg"oKu>ãݓkC%ܣW]Q3uQVr˘+FKkHl #=XjDmH|2!*%{vk%=$fo+a^M5$Ԭ>QP"c:rH)s؟RTˣ g+Q[e5h;c8k׼hq7VXru|-Y96|t ߲Jh ÿɈ  #-XK& 2ri@ܫ=^u3u">_fPMA ۍ]\~Q$/QI`, (_DX]8<~>CRn5̄X:>~p GcpD0?Ls" c1~ a}Բ!w,+}@dcOi ܔ:@PB;ېCxNVV8ir`P˧Ojo`dǭcG^"MT{? KYFހ| q'ԏ (a(? f{)C;0ɠr|{R <8e1d,XBx~"A੹$$rc)B@^Ju%$)_4!WaQaj ^&n\0T뺝_a7Mv`Pz0E>|&a((8G+p7 n7avpUjUvhM~zdhi4;H=#ۉ>:ԱM @흐&>HivW9PsFxRy+L(\$\eslCk!S+ Gi" X8! F|.؇f&|e55hꙌ5wge'5fO_)L7qZV7\`7nn h*?INPw}SkY6r}!ZEu# \pr o ϖ\g %OL]%!47[خ-[9ڲxl_\5AƤG5Ƚ3>(*' )k&yM ~1rA!i iryiE?LPѐn=<HbK ꧦ^ a2gmMe5TNKewux=Ekjv@|17EF3ᗯgHs+$lM7;cgYm9aUW7xB8%b^'+4;|`nV*<.&jR%l ?ULoFO䲫I>^z>'*6wE:J1X*(<l3$N_c+V(O@f)G*u VgDG~0EBhĝZIKLz|΃lO@ilR %Gm KEDhaO<77zk^(h̎HɳX[[Rz'XHf<϶yZ.cd۵6IP#y3Xa,Ry vpIMw?4K.꿧GԟF )nn$HK,.r6Ԭ/47U6~{2 #Mdb[zk뼙oD;BeK>D3wZi+Lv ,h)d8G6pS1>;$H<0g.D5XK꽒SIޙ:}D0!($]'YGW yBKgڣ/޲fWTڄڕğ}[. Pu&vVmޏKn}@g( UJ3pTG85Fu2P*,hEd_fcB!-j~ܧ ^L  !8 nx x!5q(!H^%/}l&:0.O 0UO WB_۳2)ݍ&b*'m:gy ls [Ěi/|@v U `ʅHcfi+(9ę4 ] rx)b"+띯?Uݱ4DiO$%0AƣZ'/[*ހ-^,20F;Q;iғs6Hk:j=c+w;#jB[hL*LIGd%KF䙐L͋E4O31[^V".`!xL"7udV 3}3ʼ-/>dr_>5hEJp$M+%: Tòp05x8X蔠 plE/ΜzOenu6f2$"aɔp5nayU$|lԅDgW(cw xzOϔ%X9Ž`ç~oCcefW, lB{cm2TZ:z$R t6QC}?cjiLǐ0jN;!XM>H"l>j$Η>ށFY{\:.T,TG4A (L1{) .P_rNb3G.:zmCC\v! < {w-,Ղ8<,.|S?ҶIM4U%$ ,)η;b:_>V'8sSlX9*FO$^1Ft.ݺ3HڰL/sD5jbG+J:%Ỳ7h"Yp W2R(ВXfUk<6c0q"J>.QNiiʲӡ^0n!nXu QIJ%iwoYE9iw0H/oq,*zlk@@IO[ %*xLÍ;" qF tqbRqҊ'MYyјl$= Px69&Zmp)@ }+]&`DS͈xfϔQ` #z}P}Ϟ9xIXWRFZq8H%|82w2&qX &7f7?1 (۰\(lY;rV/z!mOd]ȶ^<N|0ٿprlmy8N{Ω=AwU}0e+>T#hraTc `rnj7(Nwqc,$3kX0DsQ|ԃ1\3 k1wgbƄ¿BLZ˿3*3Eace(&J=4#("ao$>B/f8ѳ~ue6 ͢L"H}E_rNn?&.H[}1uqyքNb[@-; :lh ?Jndyk `oCj=:c&,#]>$%gK%Ẩn^m*zJd[&3rU֊Afa'iZpK^cˣAx&>ӡG3CW\ƵK[;N3;btv}P355šJ*:"YHz>;t7kҭ:))c|̥|\j=p-xh4"XIGN^?x)_ XﴒǡT#gb22t|[RkEjq^*clb^IRr*M3:LjɣN_ uaA#2d%]ixwP?_0!Y뻾#KT@RlVUT,OjqFFGYGLvE)%5m $OB<@EA& k@iU -P(wW5YFцg0Eu8 NL/jh>k67^._{'PKf%St>&D/k 1r5TlݱXt8] -υ6Ŵ> l|GR{aPUnEr>G/0JEu;GvZ̞i>|p/V7yg 㗌qEk؅JN";oob{Xj^]B^{ʹJ)Ν "%.BG;j=0Hf;uЮ+ ?G(;d0lÁwEJ5D\w𰓖yome7O6FUgC@{Ƞ 4:à0^罄Rok l>1Vdfsi +E+26KLa+ClCN ǂ5}~ WN=I][G۠P`w-jۏDh,ý,c "[֋].9X +Oׅ:l$zV!0:MƜb:~t/m\'./) u49`IH樱@3xؠ:(V ǤFp6fyYESX(7L|6hWޱr_cp qLh [iO[~~b:{jmunҰ [;#:`A=gIV8"w` m5¸!RIto ~lT.'P:u_L:ѯ@+d=hQfIsh7 >8Oj$ 6Q? M- o_傘ѠM %g݆߭q'#uqy*(Յ~-]91q<\帣 =#/O:8m"oU+D  ~~Mڐ)qK}]~Eۯ yROjS6,V3A_/"O=5ϵɝRs嶏MmFe JxltXu1ݔ{SNB,-ܺ^^'̸%"O`P&tWgQZ᥮%v)&&6ϋY %cP:a *8[36t\,u"޾@jn+@'?y(t4kemWFڲFT,yP: @+4& 8/^=@{u2|(+mC/=co͓KJm}2,imxrQن+/ٛ/Hcsꦪ YX[;ϋo $c@}='tk鹀Xg{`&jgJ(e"ɝOBel9HEI=\9)6ͦϵ"z]cwrSAm B쑥ml;]e>i;@%g"FDYvKo 5 yo$d cߵǰ(Ug$Ϲ]Mv~ s5AM-vL{5{a?bEaȦ_7D7X@1JEG8! 5D,%|YyMd384藪3-,2~AZ zLqI}hSvSU"|QZyHSvJ|r@Q6Pz͉X{rDr,OWpHwj,-/ʻPKR8qyisC: %K[ 68K駅]޾; ^ {xH+Gi.%]'^/kڰBUEf0$4}\":!0X3=~i)s&78x15\@(x^c3e|z]c:/ݗF,m|/zb5/xa6LNu}ǖR;[Y6){W]GRDƌ3U\14JA1C.ԫKr燯 Yth_;UkkV:g{ b+ %q66ȝm Mdѭ$ltZ oh:q~ wHy+j~5[. c_L|+&eR{5aRi`Oy5*JT;>3v-=6 LN3 "E%[5(2S 2[d6E!f2OoK$E)ug^IH }nhO&{&> J*$5?7r+HamWؚ wo9`r@5^s-o];]t2rv`. ۯ=ƋIq f2 -;^1e_=,=5 L)q,<?0i/޸GJ|^ɘO+]]ĆRadF uWbv#ɤ- :fC``C+9'ĭHQQ`#8%>$85i`T[́ &\9pzj"i̒ MtZo\#eȑNIG/rm=Q s{@q: n Z@%wP̪ܬ5gQ}:xekW[%I#>TKr7QvAHlvZW@iܼ%)c67VIލsVUS;/,&ѷ`egʼyImЋ?2Qv;1+C[:) mn4mE5dcY+:5ov9͕0,/$:8픿p5-`U,!=JC LR!Nv4Wډ5`vd]^۞NC'("cĦrv.w:eiE{$Y^КAD  b/,NM Q8'-X)/B%k5?6}ӚG`Z5tVV +L($3Zcfhɵ=" vHwjDerrE*F,VHbЖqlA"8".[I?e#s˨wNp׊z S>+Jý)~Nq`=lFs v` W_Vz]3Ghyx_֣' _U<ݭMr5sli37֔p%I[ gOL {zN d*h}۰*Ur)CCN]p I}txotLF]_t>đ\ٷSф:)JIHpƄ9w䆨l6=Nt$Sjė3+4ӬM, IR_tѵT#-?F**˸ctŠ!͕.؇=9\c$fZ^_r!=uL<@򥯞 $P-yEEl͒XoGW:._qN÷KdhזwC 67`O6&Dg^J}4PzC~ #1 AYE3/jn;"ՙ9=0c}˷u2p-Df`mخ?2^?0~c}̯6 [Z80%wp@rr|o?X@~Gkq*[Ư:OzAstEوkpܹؐBNJx^aYIF '-^vU h6{HE|-U\GݬW}sl̾򱩦H%ą K_FFZ}QzӇsl_OU'ƿF nʹ PӦϤbѵ^ρWwl'ZϦEzc]>uJT5s֭A"|?\/8DT$Ie0s|wV]9Z1W^yee{KW{wYZ{Zo=mV -caXtN XF>|.K$7JvˮոFqz%{%F@2Kc iW+(.^fmd%4@ԸvPo-NJv{o(`؁RQQ=VP_+/'`!%^~hV' DI5_e#c`Ūn#@%\2^)R卄B@8>RJpr0IXd>*A70@40.ޡ *Ң=TIwX=,x&A&RX"ДB4_&P &*)cl9_4ū!ex1g =F{n< xXNeY(k9<8S8jx-I,Z;pJ +ɢzy.fR]{*.LZaR˞Oٗ L&<g'V-(?CsD_hjFW^VR@^E[STuA3]Z4̳-lx5" RHʺ.> ?i, O *qERq#Ea//rG Q =I.H`˟-<Jㇾ *(%߀7obݘl j ?E6\K"YW6S)& W9ԍj8=1񠐕 M|OөuP:6#?STslu1|OWIBeyo|1 )K0(>2 xS *uT_g“ğ湫*;ΛMt A|۩x۬`QL +j+wc^0֞R'mg:wSxVPrjTź> >!<N\X&Q=j=놁429sXvw̐A%G} ,@b?KϽa)sك"-җc[qYXͺޫy9+p3<Zbί: P2  hMvvu>ybSvTۃlqA*I(?Mm,/^(ߏĜs:Z{ǺYq8 "ܲ2( ^h'5Qt2Zqh`~_|rluQl5*Sj,:Pn3f4DdTI<.eEl(E7, H-]ZBcқ-qmkʮ'A1XDunHŹli08x2Ij3&{}D'ׄgW#[7^3_@>*'=+&53NoQpۃMPw!*a z;zu"5bBABpkDoC6fg+Ljپܢq -6tv僽X.fJbTL>%urb ^3dn4ہ wqFz㟛ykQlP$0(l]rǎڼ]QVcj r>HLu-8FU%;7(WֳP\gk$Ȑ̔S~mz2.$s&($tqX vDqj}M R4u I$0=;j/܇_#Wr9_R}Iڲ28 jT~@" [.AvZWܫs֪7 pE#_ mp;6|,X-9)q3+6۾kmx7<oGU^+¢9M’#} /gF31&y@j ;O>DBPQz泩4듡ҩaɒmkYB,{CUH#X= .@(@]m=CS,|NSقQ` %)I+"*C&>+l8xh4o{`]Ft.8 O] E<j2uߑg?n@Ǒ1. NyPū*o~?HDR^JcVQ;4dE16DeAiF Auuxد(%>&瞣AE NR4CՈiCC2y`\,j~G̼}ݪRvPݸ%^?FKɼޭJrR1qşQjQ>vs4 p刺`NICfxf +/AdvÙv^ANNQ]B`y-;Z_Up" N`XGrf&"r}9wt$>vh+ t9_A]PMD*"!;Pe+s;,b=n@=W:FLlrYP?7NCK*r`4"uQ/H֦T:&rIX{eꨇSo Dqxq JX ZY5ͯ6M dw'#j TI"YWg(s cS-zsz=04!G!cWهJ9StYR%œw-HoМ*k룜*KQ)oV[U"Pz;ZrMӍ0Ꮇ#Eć\d-2G(R=5E}$+{]5 IXz6ƕޓz'x{y3O}6r]}gx@ײޢExKtnutRq#1hsmic`&ѲǍns\3N7q»v䅳r8bqtcG" q)~u/3Jψi% ڮ'G[N~`S£= ^ҏSdw /Ӻ=4HHZݟF>OK`.<}s%jzmZqsWWNi=o56:2|IP[ajwS]l#3 ϧ0xm:T9<oD`J6Stɭ|#+{n Ly\'0v&ؾ4O:Acp)>8pΌ|.CW4<yAdj2+K߬n%/kš8L6bw(MŸ˰ù2a /AփrUkU8To`mE "sWBh3_ k,SPNOzSR 6 ZǮglEKuN3hZ(mW#9 Hl +[5SM8u2(s9rOϹgs`-hX|<\U7+7̠ Fƭ?1,}{f1ھg6==%;1FPIٶ{L1a<;GȘQhj4ym4Oyxp5&͕ Mg90 aPvVlJy.$a!]#$ຌ2}oW(ʎ `YX|3sp4-r^@LMoSڢ",Yue.W %Ӕ!3ttmu] 4'ڠ8!ɐ"ꬄ:ߓdU=1_(n~VnxJm~K~Y?9MCK /32_3E.;vBBk P^K+`d&>Q(@%&bi4:*WۓUj; z"{gjȘF9V^]3 ?Ev<@cْM|s[T:##Ma4 xem 0(R!Iq5e$t*!Rwg蜱Q*T)Fc8)_O58 b uʾ$Ȼq qqpG\?ӑٜXHWO}CQtNE:wE=KŨ?i?)}ZJ5NЗ׃oxh--D(ɃZ P0N1U zCB6JLtUٿ^uzh:Gn T~޶w`C㪹LHNa-s =3W`~*qiv^ mYqj|+Q[?茷7K?X~T~FŐՑKb-nִޞ Qi x(f eF%e|4||jc] 7[",zeDEpC!" }G]?oɓEJdM .P|מ|j<%ξ"G*P̊~ڢи;UqZrxRb-3ڹ gC#g4vǐ$+ }W(2:숻6s':`~kedxƪý0440|T&`b|:M{UF34LUO>.&efPuu HA4K<_)Hn12t`ԽyeƉ:Ax B'̛P35x3w9G̝Ư>ŀy ,Y .x9GK"ז=D@Y- hu-E=Č$Z.a}y"kmנGY[ Ds[@@-| o An~;qcvqd à M+TQ:OxU`ɘ', 3?wd'С*kWeHj}DE/Y4E bm?o=yV7"|6:>1NaչjѨ>,elh xjáO04!N#^1 RAUl -u~+=i4:K(EeaMrCJj.F eݴU3ը֑Cʅ Ԗ ̇6@>E)hr:0J%Js~)2)$vd``Wl`=bE:~:W*֚\ ѭS@+$s*)U=[fcdw^W5BΑ-wfoSx%S߶qz> r۝˿2ۖ\q9::lY&"Z<-=j@zF4~Ι;% 뿒s8TLT;dy^iԅ=|Z 87s :0!qIhjge.a6W*"sHMf̛KSi~t 2X51\1ֻu뚤ںkg 6MV-dtP^ ~3Bn+u]Ã\ܠ>sk5%jpkjd9zQ ٻ7ft$)l]Ӕ5 ۢ$8Mvs^Hor*J'bPd@=n bFnP= &ϗ:+뾿Rx%]-c۠9thz:Yi>Ê=+޿Cim6Nt^hLEJ#\8z(Ãc(H MyjHM?Y [gɎ P4P%}dw͓O׬,O8mh`o. *- 1G%eF5%fl7=[=bY^j 5Op_#8G_.0 5Y O_Pf .)-[Ev\-%㝋a9>r<p; =/Sl0"L?5YOfO޵;èNģ_p{UOLy1Š }ecl[NRVQ}s*q`h(V ( MEn6\je6Rs㘘mc,+ )"]GãrCVր AzS&*Kmr4>͆/sWhh$ X3m@1rxF,Zq[b=yZT\B\ryAQ|&sV&/@I=]bo#NYz[ 3{TтЪ?=O5 id8c:*XD٠v5A?I0?w/4,H|R>5F+tSE*5Л^yqȥˊ;~È! J^fUSD v@mIFǻ>\lRUWnՙy~~mt&Hz3,H9FE0(D2w:uyrn{N]i{_?gSQkZ-5w%榌}P#=;˨>H(CSKnzֺݥ*(M P0՟l]+B'<9bBj2ûpV){^rn^~gj>E3ے-<&as=ІLIzvE&[wd Fe{ee=PS:R d`fWli;&O?a F=)PC2m!(x`%L>I2dȐ!,N`'T j$nƍB%aj+yN1鴰ek0iч D Q@<WQR‚5kha1IIlfA"V`/ro&:Yx@gzD 6{XlB;n(Dt\]9Ѓv@JO oW<ǩik ,f#"V gs PJIԱ]S-nvWc>j&XT Y{@eҪmzqY Zj'0Y W>0zЯL12ڣ UC]Aw5TěE/ [*YLvOfyMx7gк#߭"mu_X?SuL-pQd*Of}qB9d+U0&nKӔXm;=U ͹+i (5y:]_/{/*3Jaj[.IȸXBpj\P&0a׋x)8e-Oӄi|4k  ue[P1E0$.ߵaRF;<:vϺoE٦fS̄S)FـuhϨ CtUjq> ^ʰ˓x3npbtP_w0raYՐk7glx}=!N% !4j"ߛ`wǖntoTN=w(Ag(%C, ?nӅK/Y 5]t b1ujؒmvxvaaBBRqW&]qJn@r1>N|z&s2,N9ZnZ{Ӆh@9e`'-6|jʳ6Sْ{ws05'aqewЫM=L'~hŤUPGx󛘔=jrmcDRFY^6obV3; "fHEI 3@NhsgM ~05aG2=8ԜgN'xfSp/Յñۏfx YH< 46c Aǽ3'C܋^P8vx9s _訞(jɦJl>d=i5Yh͒>.,\+[CsbB`k*Kb Gv>Wo )].f B*]cj@ű\WEr25݌wtvY>*j4bWlUMOC|G}J{D}.+ˢ*y)c"̓ :6k"K<%*;nHrNyu\~hnzaI3ص}v z, =J ߘr#z9AHV` A8 A$PDiם*[X~N¦sO ;l":n󚛯N)i)5Ra\l㙀&*2@ 2كXa<(emmh*sԮ(̻)J ޛI2e0t 5G6VĚ˩rRlI?i.sU a6捛"DfILBc|ģsAW7Qe4xv]Df¥^HH?y~f)JZbzS!,& 0cF>}fcɾ i>Wm{$O|$@EV'}RMo[leqnI5]$!i_0:01IQftz|)e~Bt,O*9޶꾛Y\ 3.d K+{JGMPcw)d AfკD%fz^[ڛ <Ё3 g|Ƨ5UkGlc'd(gUR]l1 :HֶHߕ aXXiά3`=w~لK?Dlj\#obn ǘZٳo3 ܛFKxiSE+q3BzDA< .mmPT +7Fýޕ8 h6i?)⻕$Q]zs2r9x^ oo (iqm|/e*q;&:k6 x"MeW\a|gP?~T4 6: ijd/tq[1[5ϠDcJTȂX:HĕTA&xGlO'vqEIŖ/1zR6z5k@L :S Kצ(Uʼ%SC 'Sϋrd; Ia7SDsx3s۞]cI?:5)ߜYpZO)|E zA_ʨj}ɖmp3~ 'ֹy95ј%;~롈8(SpA`LG p$("4 B p.9raf^R7\ @욇HRRtef4-qDS(=m| JzT޽u`!鼿X&d:*n" :N \',:tUqCվ( JK-=p[iۨy GdE8`3(nȻKuJX~ղ~(F\ݣY.Ao{D5#ҋoA CUQ8"QVh- e,1_+CVKS2f(Y彞2E>[PsA9m#p~ @C?+h,2Zd_[PB*7TgST7U˱V_|C!݇.ɥiYk?]x IjK /Ncּyfqķ(ۦiv4(5ဘ.ڣ^AX\sgos}tn $>Qy9z4H  M &aKcxF֔i" HS;h likby f׆#F?FH"u3SLܮ 鑀S:aJ1%JC/t4˹z dPdIeC+3(7(&-%z }W#0i9#GNo~7LIww o,5 w_(Gc-Ԛg'0Dyi1 CIo*HԀeV2) #f ͵}ey᳴;/NR֓(L;F"Y}Ga,(t=+wWtP>K ذq3 62؉ܵLX&P>M9˪,hEڔuHM Sٚӛ;-=XpϗGjqeMcսv_9P\I~)QEqo]xaxɷ@KS&#m=[XqJ;s-s Vp,-:Θ. PO͗d$/hRyG 4qRd_^`JڧIgYYف'MAӲLm@F&cf#wuE!7-"[JǎMY#ο9B;DmRث! Rgw4E6[R=qBAU^ }$#tEJ֬t\R+ȷ3}z" ؙRlX~Pbn]kNrQy Y/Bz1B)^n&Ѵ~%i)Ҋz ?3/l=h)g"t9B7Iɸi߱*ʓiWf`ْ@";LJQW܋zC@#^jg| XW)Ve{tf yWp͢1J.|xǩ|o4kҋsȊnbC7˼騛 Sf\W("WyC?.ͻI 7q*m=̈́Vܛ 4Bx`!̋LNl.!Xm!J^ +1P+D$zbAZmRsk]TCm\"xit`' !q/@g7@)cb%!&B-7z5 y`Fnwu0I "|аE.;( <Ɔ`VNYت]Ӣ-@E\ʀŗ"ߚ¯Yj {z9jژN iyK;rCK4y$D3\.oJ(1c^vnW QRqݒle]~aCd$FU bu3J&QF$Ǿ@pngD9"t:bV~p;lJ*.LueWJyۊ ; %Ev.'<ނ+M.}Ccc- ŏp3̕ ~?_tTv3KF̌?=[JĦd!vG$wS-VVq_SS=Dve(uHgIf?ᰝ7?g^LݍA'xm*4Js2Ψx24_{Ȼág;ƚg 1M xX$cȤpz#"O?Oxp]aLi2F˝6lv<庌?=g)97t4݊޵/\[F3Uqq~ Ⱥ&~e& eTgXq ~`C/eO8@qJ]eh(_ژOJ+T9i( 2Y]h̎N#S q^+m}9j,䳵]Hx5~U3;33L C.I0.]e;Fdh.+v<5(B:O\Ft`J\:`~zszJ%[gMowh~}Q[oI伓s8)ϯۨk%b&~ީ GU}̧y|C= 92ݓ3^ԑ1 Im#`/R4Tܹ-"PL2,BG .GΕXّm4G}=i$5f'륮|6ev#Zw  8:t{T 66#cQ%`;,/-q(HB)a8ktK& UWGJI/G⸞YNQ3(~>H'+LEʘ-XHL!x2ɣVIМpaۤȁX}3pLƜTV'[GF@//m韴t䯏i/BX\Gj}[-m%.6PG2L҄ eN <: ߉7vqd:E3GE. gM{SsT]`%_$k*tG>) r4,_G_4Dspw_ak=>U?[bJźӅv%BkqfDQ5cIzF0LT<澓ho~Ić +y(֖&'JY[ JzdWbȘ),fRE=?ftxΗvdg?4 L\谴t HKau mş2R_q"W!l7u8Yp~K9 ,[KonpVg2/xpL1Z XbJ!݌cPEYn8I!(d*PrQ i lZj'\[mf*ʞf&X&`sli9lW\F+}CLwjJ45&37" 6u-# D=cX%yn&0ZRA}آ=Z"@ڍY<$BU>ecS癥s|&x GyPL%fwcWW' zMDŽ2rf˗zqx+ZLi!VSp 0q`rOkq4,K$_Ոk-hI-^C@{[@m ڦOe(Α삻@Fnt{:F uж'WiE?zfsqYuѲ}+g\a^yփ#*A⨮DAZ\~OUzKMfÅh5N~B׾6*k}fh1`y0fhoCN`F"=&KKYNICm/=M SAo^r8%T~w6tiz\J~gQ ngӮ_iYiL(=F)++%nVu^/ף& Aېc\(qb!F?{moLé>TYwS$͟}-YbE]$9%?j˽V`zQqVӶ`$B^EoU1x=wˢ3/*,c0 O))7SpQck*FjlchT֝Bpil|k>ȹ_ZsQ`ԟ6 æ5HH o8=*: χOy-"WH4ZXKR#q.rټ /kؤArP S')>(1e J3@paMo=mWO4jdM~YVdDK_,2Z 1 5yj?]@Ș kŬJJqWFlr&[7,%`_JHR%`LFckT^7,}ҙ`߰OKiAb Dc%7uUf\/°:I2n|F;41"&eG+{*%g,!fdRSJ LH#R@Lj[P5z4m5l&^U VF>F輲Q/yԽn0&\f8L?p*gx7 ]*iJ m_XՂ 0u/k^4g"D^@m#X ~و @'o}SvW:W_5Yq tsslc7a*;f&-rvBGk(:II>C[d\)+3T+w%ԯpByͺ㬤 ѽާhIXMEy-&Փ߰P"ja UK%9lٺ*VhMИZn v+fH;2 KZ$\ץGR&+0G/ỹ9XPXAL_5Hmݲnу񩿖'fc0Tޠ`,.]:/@)!; b+H#$&:=eeeфGn;dxA(\K[CA4DvI1GyJ/[ypqa26ޮ56T+rmG-pf^MZ[E0S{B37;{2l VzC$4b}sIaQFgզᷖ`+]LJFCK>x{F4<;mZTJH߽qOv1*xV~STU'L8i/C bpȵ'%+C @@5EɴWQchO1?tXJGȀeu!ʖ5KNJDnUak\,$c܉Ea47~x禓hh ؛StvpCs4lcq`و 8k+>V312y0%=*aOv BqH[#Vp6jj紀 ZwQ֬簸> S9dX6ȧJY3}uGAO#-{T$_(OtMݼ ,%IWolңЎd_d^UWѠ;R@E#3WcŃ:/gǶ,2eU-͸Vi&c DD)Ypn=K^ξD,6!cεӆ0rޅG!7T]\ 5-pR}Hr[YF..f*D[1\ߠM0l@Gò#{ #0j'V UbXh7LWP%?kReL3x!O1CT0kMhxMEb~!O򶇅N/ٸ⪡?|Y#w'g]O,AnWʷ={zvďD,* >0;Ս&BCWUANԨK^ȢBƳWSAzC4,bHC\kKdMRc4R5݁Q ,#zX\jRDCKfCÅQ>fLSG$*I8i2l*]ݮTvxM5㫦HIQc7ZEqDxܠQ=_0z8u:joZy֢/cw_w&ZĀe`4(45[ m,ľ&)&+/-9YW8uWmU1Ţ~,Ӂ|OdvWӁML#FϞiRV jlNoTF:5&#gqEع%2xѐ:E=a/Ǔ}tugjlL+m*[4/t'(c G5%3kMP)&̓c?/RW!rvЗCF0LH}!&<`ҭcKTP:3'WMҔbk962f9֔BydX>;f?YK; SHVѓ&-Q+BU.+6CkڬwWq#w[>{a8%46z>PnUZ(A)^%+ߊ+D(K}̓ZQB{WA2. *d.2 } qӸ%YK~q~9q,+,ƺAf`=[Xə x%< JƉ^`e/_ٻ~Vb;vkFͬ-7{dr,64Y g7yrו*I̦ER Y5,mQMV6kR^ЅNrԼ DP-(wР{ʇZRHmFhjJs'y 4 6v5-xf3:pG;'k8y g;s]bI]'P ka&eZ^h7о\1uy,si,v n[?Onpې%"KT׾,G&ꬱ,gzcD`N44!=&y8.mVkZH\*$]Ly4aWrY" =b@:b]KD k BvܹH%$ޚXc+ok'݌eФ f䓉P[8F!05|R?{ ARrJpjH *Β|)%ߓ3veEzyիY6;Ɍڀr/lO0Č ;eςۛZ,0ǽ ? eW' KT2S1. h/6R#(+~5pލ Ĩ}"3GÖD)zC%_y mxd`f*Y"/$➜e0a&C$ԺRX?2,ybn<5IIq9N$K`31UӼ`J~E1Ir)ͧdΩq2,-Bt|h}qAtMB^_g(N&cf%p?`@),PZs#rӉLf15]j>.+X3; ;ٚ[?[罸A%w尟%1ʛ+k v$(-4%_-rm7)g"|q$ueֆkR -]{$zMG32up Fu:11)Cs_{m5qPr;9` YI%O&H`ߐjǟj5M),+9ɘ.,G.Ǔ膆S  N3\Qz~7/oB$2=Css@fӿΣa;nҺOwa*+H]jyOٞkdCOdq_B/  B ?~,vn{DH2p)Hx.8)-x7[6:THVb^AQMG^pf~F⎤Aumt$:B~K%jW;t>Bϳ7i35,Ƒ/nt!.z_hЧOG^k; -ϗ=c;eҟ .mƇWg讋mW3FeY5>cSrddz$m-Dh Wu>[k`1cI`*1U=Uu\ V-ߌNqҪB~z_!.?p[' MпR%^8q@EHxj)liJ6g id9HObz.ԣK8RrV0&t>tm4UnHU ZXN"Ѩ\_$;goȍM/AV'ӼpO#Y#̬jn}24+yHnL&*$%jRx>R1x{*MFb~x17;=UP:oJ_aolhh%BOoG2k'()l~(QM[_}|M8ʠ.',^żyM=ŁVfuźy_4{$ks)vr$b5ڽt.r^k ^P5WGf+vh-Ӣ@Fp!?QZQtmlƣ ;&*[Y3XKV,TBLK u?uA͎:0go% #Ӿ!++G#jR(trƳiRk~h tE@t.;< É-vavm-BwRWmyTwwuD 8t#D,/@novSj*`Ů_)˒]jek_c

1^ܩ0ͅi*&}ڻƸP/m{VqpZ[F?6H挡'UR9A(LptgV8{qzN;(RBVAfh3f.dY"JWtb1D,)E8qz#7T9MDYLPgx,Sd8 }XK&lkqp\㼴۬v{OQa:Bdј (mE+h~ QdN9uu:.^WM / >3~$8ݶԤWd Qm"hJ&(ݞIOn&މ51A arZo%֢n(xXr熃T@_7^~ ."ix`0ckIY1iaF2VЅ;| L-/oSP(9N2iq;^&OGqT—_D{r4imZllOJG"nx\@7s8bm]yuBua_`ZԘXC&ƼAOIz}c[;Ҋ~ za !ObGT.hMQ&R;1.i,1&•KPSڈWT;"og>:T{Qs@D@4ɘw RF!L)ɉ_ aOHM~W>f^*6[rcGCh ˫w?Ǒ" !zUT,h(=ɛ#|5}FE+q FOɣ9 ( RJ<(>(@?ʹ4蚗b,38Iڮ7m(C5te&iU~4F5b D3a>4){@_9͡R\^Zքp .2<Պ^|Ut?JR9B2"&U].|f&Y" 4kѸī(abOeUdZ!VO=݀,|?@pLx6:pĊU#/]rOZVWNOCte2MmEe0n0 RR}V%bpo-Z-⎂pT/th(Ma-5=-C{T qN|9P4dM y2DC~ NoAhzie,2bg!5>@}HiԴ 9gSyI1VP^70(иCWw܋zI+״c) )Ӌ/;fG$c׭;^s>Ģ $8[d1Ψ0 r'͓ĺ#|횎kY ItF(;ieT{ΘCy?Cɿ)߾[: % ն.E9|L;GGK KOz|]0n=]}}$#>|4ucUJ}f`sSƈ*~pujuO/OIh v*x cB4h҄:L!KpjZdh $ g  @rȃ v12j;n {( uDKBa$2 wH`GA@L̃ -P?^.`Hi.>a"PC$O9k /вhv*NǁKsyL ubwN76=GVǬz9x0`d͎XE[`!%P˲ĤPVibXzijw8DR8n2JC,!5jqJ4yBZp~s<<< !o}Y\P{]T|㚐D7 Q T*c&HT} KsjQYG0pS0';בc hݴŒ}4Qg Ժ4(.o6(j+ƫ7-ל9N#2!a[̛i cF9}ZU&{X֍9Re$BK~ıuAQGF #3vK~h蚂({Oo2/wƤmqa *X0 Rbm,JG!-$A=s)w7y@ &P@M/gp->l ˬҘ~FSw#ZjiZ˄'[_2=nH*Q! ][sU bluzϐw8\@GoP"8eXl録ߠތz"~nӚ|e/ 6=&1URG"0<噰T_o"m(LGmiD{2S-FC6"!+ ZuB;| C?,3ˊDH(:'EhInhs89hd$$?H/ Г6س@oo^Q /졙˼ysl?`3(\ 9ϳjOګa @{8dNF*Q 9/{)4@)eqFNt斜LF)6nFN &%;qq*&KJ;;A|WF~j6uٽpX=ڠ WdQl#AYPe0k]t!UFQ[E]8i黁FI蟻dV97H-.)cD [Y, \FΑ9 1m-h,h3sc(JY/gZ|ˉrw_M]nk؋:2`+2.!eGp K6(_M<@~2+ d!)mZ;щS".uJ^Us|9I;}vo8˥:':@yMitEaTj$<=ϒ~&<5u#!^%n&v>:,7B8SNoT%:R13 -b3XU„'2E6=lfϜCɯ0V$[(_ Dbvu<4C:0^Vu gƿG6>Xf~f>Y$]JٷDM! zǗWvcP)ePؒtPEstTX+ZRs _ LI./Қyd\%'m%<_f2lis_rRqYqHl^FΒ-I8aAq55' U6W`XG zLZ&~@wv: ,]\BG,jQkvR7!L.h=K !86BjB.}`JImuZmuvz˳Lz( sXaݤa'%;ٴ#$Ƙx\7x}8Ouq ia-3NGjՃ.(+Cf'Kπcd_0+cd($a(+,&7kC@g+;0+JCeN]B]Tn,:n188TQY',# 9z!p=f ,(\/]%N ݣ#C g]<1ۜyLac,Bzn]ua rݹFBwCދXjiحvgE=Ňno"v ѐrHZA1@NsF_f9vh;>l:{+k CljJ+R=@?䠸_ +؆|ˆ0ypU$(g\3tGx1s'"hh);!+1'a(@7 ;;qULȈllƵYSq0V]EM+cG JzY`zKHGW|Zۭ%b *W ,*̞FUmy";iP(j~/C6lT{̋5@;ӓ!qG.d.!%_[uVd}CNM,NFM}+A*~m4$BÙn?wJ#P"&ѭ䄧Kvj}ḃΠZ5.3X} {H5^P 0b Of%^pI/%rPÑD$ܬ)*QO:1X/{*<9 Slp:?p&kfKC4 (5xFsUNGH <5AAXy~ڜ~z^9sۛ0V[,ޠ Ng Mi>Ϲ#etZ0&v Wܹ'')zqfHҺ UB|k*J{i7_Vjs3}c_k; CNeӁI?[A]gj9_A>F"GT;'Ač58_B:YRMV0lUc$>x#m{  KiR 96wN; -1 bͻzteb~/GtʹFŀi#XSKÕ}ž~c!+YwK)et~'tz-4%CA:m6Ĵ.z4~9c'\F^,UȴX=%te͐dwqFIyӶw҈*kqY Pb,"Th)-S㩼j{OjJۿp=&tV7Ͼ۬ɉٽ]פo3`:Yň֠'Otpu#BcMy{X8׎7Fa,Π&gZ^m%ki샪`bM 7=#olͭo="ɐ|D y:dqYCn\Uarm,qZ@WT@a⺣Pq&YG ePFnIE::W.^Lx$"*F2緹)4F*)*F!CyL@B,^C¬e'D4D2oI#}7kKEhkD!;, 62x1L7B|(SuX$,QFڦR7;ukC^QAߠj龣;}O_2{*+;Z\؅W-}V[,B2C;Ġ Ë2ksZ i3Xjj3i.,|2sd e'hX%s+}Z0~lo@O%i =vjʢoQe%*j6Y z'#.i>O4 ]I6R~-1w+HEe)YDP]NPrUG\l̗ UK`VWC@Gub)Qw:-ki9͈,ZKQA^y5Ǩ* tDC.`鮫"i+c7#!*-kM Hٺ=tcI,7Ry7E *ҲΤ\Z "(F DE&!o4,7s=.כ(1"+Lq3#M|KsV1njr%epz&,;<׶ }B`msdGNⵅ>/1  ;#o \t(yTI֘Q8(KX;QX* !j|)]mƬ&aeI"hO!2Ũ4ϚWxE-1u A8b7L+BV˚1kڐ&(Z1#Oq ѷ_mi!F ]8ػH!0=Oi74' oĜv*Kc;mw0ujFf(97O!ORIbͲDRěZJfZl,d=?;O-7%\L*Y $D#!zSbٙU  Nx&7FjaكIrhf( X}M FX] Nqo[F$FFԚP}>ZX'ȥX$b BX.uIa,dمMλ0b[g}s ] 3m--L^T OHATvm6IW_]9a6~:f-U~LU1 *UQ "9{-F (v:kMbƤd"L?r3meGqHn_^jѳ_и]{>15D n$*ơ BaY@]@y.l>V"ZBS`\nSKC"AB"טZ%O #ȥgHQՈu!nQc!FJqxE=aP֝A6&ⳝ={-vPR2즳 0 Iիy"/mS!CbWg$/sl}ٞP&^ҙh.л|Ƽ# r!{ȕȐ"|F(t ke(U!YsE?"  r~Ig.˔Ɛh{8!Dq~֬qy|ëȽL4 62 Ѹv.~ _T19ǽ:( &PeF<wR*>Fj1ܯ= CpFw:mܞXݳ#]7}ˁlC` |M6 X"yC/LIA[0 f5\)Fіqd9!N֟1ǒ簀=<'@2L5}vLr8Yn:f@}Ȥt/LĬ^:.?:CXe[26K h E ߛgۡʾ;艗PaoX)G fIU;G:AoL߳Rݲr$+9c(vvhjI74cX1xq0mwz 匙MΖvp@ ƯP зثkJ`r]\$_׿` AЖNH$nGd2Q:Gt||Q-ˍZaJbUc il'Hj XVj9B_R.Dn[{L5uNJl8++ZG g?slDXtAװk%ONОWnV)$Yt}.S~WQ\!vxD ecR*2I4G :+ṁnHvT5f6s R=){w?DZ KZ~( WgoAd3ľ)4R+'Gؑ+_m@ω(DIv\(j}ռ-ͧ9ݨ* e\9VAA܎!h:BuYjZpA pʙh( [V+~u/=!8%+{,P*6d×|]I)F|T]L`)Nq@6gLr"gk=8)u)4L@ȁ)*Kez(1<-K}gPN0hc$R_Ёl]YH B JʔTS㔠blr;vuGL&L tm^HiL="G$O՜ꬫ/IBqϢ?"v-i΢Qfu겸xP? |Dᇫҫ e[D*[/;g8r!9gr33zD`s=;Z:3HǏC烦l>GPt\㝵L2i 7k vd;p΍.u\!TAGX 6F`lȽc2b> ,ٷ@iKMXKU$-b%E:y*÷J5>z~9D 5k ڂw*\sZt_r A: .#}5eD=1ْ$NŞڕ:s=#{2*~m?(LJf'ύRхY\@-Ԣ ]%k 1v'4[A(R%[vN<7r9^v~u+-M#PοLĸv:?V)v:8NT^ H]JUzTO' m8)PMs3m apm I0 /{N{&ˇVu )Caz75HzQ`Xbz&wA"cǢϔ?T/F $崺ϴa{EU:ūDJKZS1&F&&1g UcR&$:IF\yid-{5uq2RFM !gcu+/Эe%UQ: O 13T}d\P5rL?,Fz2lwȄt3U|3V-tުg 0ӌ(0,,l&zΠ{m,ؒer@c-$3ׄ2RzN`,ot5cReMHP+{Ѻoo6vKTLS+44d!ny HVOߡqz D ,jܣ?v/ /?*o/ lʩ{!cXy$Q^.k#".ȳwDP#gg}\鋍Y/\G.ܮվ 8Wd \vLÂՓ^\({" +_%kYJTlo d6+;,T6v!va*[AkJ~Kؾ3YV ^nE4beskN{DPƑa Ğaz`cq5ϐLNg:3&~֦? rm۫*dS;OHɉk% IZT:NG38\}'rdj4E ~yH ?^RwLtz9/sYᓑ X#¹j7l307W>p;'e\=ԍnS$1c4~]3xSȧ  8H@H˅ 7X߭#%h8{2ܪ}Zq+xE.׶x*vOEߊhqUȷT0js85e>Pm<Ck,iB%y'` :Fi2U&Vx|M@;9p7fFT/%D7?&$̢}Ȭm_}wJbNz3xN㞁r1wfn  FU#ځPm=< i1 9T%xBBRpKy!!;a=cqDh,U8&Vx\| 4q M3:P`ߪKj}{m4^?:rLT>߅k*m|mU1U'bSZ"1g޾P 7iЬ |ZFtXCT'sMk1޼RPW6zP{T=+s1Qgy>9V-ňb pҘtJI\7Y{M'\;(v{KFw ɻ|(.<̠T1@*'@VjuI";&"ǎpHY܉k|I%-[ng}X,NŶq,W&6S% 'Yjqef&TP߫_ -+{~To XT.(r͢l2̐9ۄUq=3qT`e_nf Daon?&pEbFu9ѷy PYp;9%\r]:J3wq{ vB~a긜9]ѣ;@Do N-Ul.wc j CvS(7|.EKT ,::l~;c߳-y-;RuY2>+TP@xd3O9?u)nQ:C(Ι#J-jJI}! R$EK >Jo#1` w"KRwQYh%^$,C=U{mE0r5'=!v;7کy5D n_JUTH*bc? |idKm>/WPĤT҂h~I*UA$p/:?|DE)cn6}JY*nayljqG՞ꝰR6}G%IK~7``jp&?6lxQu+簮EJ'2 u  sLkv=yC|QQM^V|e`ҟ+&qg U{vJ|zy-vT;n ?vNKn+9w^ڨb=9n𐊼ϙ'9CmR +Y:'+yuyWlG?st]zH㋼UF81&MH$*Ҵs1VL̥.I 'pO~)@z\d,L>?3Az{ <=wXlL46I>~\WR vXnB/N'{s94峃ƥK{Ͷ 2勜9(U|vxE˫LLw&6Ek`YIXZ 9Ibx4a 5(%(Rew+ͽJ$r7^讔0^ץE7.]VmKwk!7;9Öة rbMMw7*gjNNxPyK"k/zcO3bGϪAtx!4N WQޡK(3NΒW5:k-V B}ܟ~|DwXS9x˖lU[r-=t7uvֈhNyxne&1+v6Jt:$QQ㘊'SPpME*r ƀt?:`لhLx]dpY<=9&B X)IjLrYx4X\JR^ QG8PÌ˻ج "m I%;|a6[1m΍#p 0rԍ|8O̝NL'/nH*9 bWFNũZϸ5)jbldyyvV΀ 3E ECu1; ej?:lMC2MȐrJne| TqI*j0m"s+GNEI@@W=9hfc45ٜ( gkKZ 6l?\U+t#?3 }'{o^ֆmI9Y금WNE?K<`Tg;0m0r gu 5R\LCQ :GyXqĤk{_:e*t1W~ʀV .xu>]bq0w]LUoVԘKErPVACc^B cDeXz.y5(m%9)-$ɕ&|G lUm|˕T_Pl-fd&H6C9c͑ &V=|A߿deW= ;1*f&8sAHS [, - }U>q*`ă?z@t}w6a%!ӈ=My%`@}O */2Jlw޾Pe˰t$X>a%XQ ϯBA5YoFU5d ŕQ{=1Idɭ=d6c#G< ]3eBv^qD y\h:TYPgSgHC4đCusy9g# N}Mbڟ¼yr)) ރ*\kG9)<; V0 d]As[@=;?bW8@o-qc[ӰR̰Ww43lv{1RJQj"M :wQ`)W\CvwR?AM^ !6/{jZ*.!B $]2v+#QeQ9OStg{*Ι(rH LK̈́JY/ )S(4 ;,I>i.1aY&.ǠM$nS8"vo@|NPC71Q?q4\֖]AvC,vUq(tj)Rmdpup;srVИ 9aV4u=ehDK)7s?rYƮ\B e$RɡV w:8iYDl̀ =MDtQ Ãhw!JEA 77?YM\]w䁠\jgy͵Ts>7cş _Oo=a&U Nz>,S}h^)~ly1̽?{a$38c*^?k&}6软p b/"/R0N,?^ևBC'|THwjрxZZQBwwFzpCC`XEn9m<*A}Ja=8r>6q or,{!m{7WG\J|ߚh֤$ǵݜ\D:jp4Xr92`(2RZ*jzxߓ&0-p)  ϺSno[D$??L%Zl-R/%`m#-J,4c ,|JIy=gi0+Ph^M3[dk<B~#uaoLdH)DqƟ-堄22ZWDAױf{6kD~ǦJ~Vm:6e.[|]CyU9~w+hE7劥yd`ص^~na&3OjRFUoVͬxHڋ&P3PPz'9Ejzs`^9Lfo&ucwJ N.=xvƲWc ۱0 6[8pɕSIOS5Ͳ-.?R#ӚVq!%@´OQzQ+ɬr]Bx]6F)rI ZVWժdOOUR㻬Og}[L6JgG7:?[,;]$V) @q(:> H:孡đDN:/^̊J{#o#TCZᴹ;ρƚO `5kȧۊ ,e q1=Kaj ۇ2z\~h 6HJW=]:]P0OD}g"". 9.䁘RTT>+竈6?騢{rVvU:)mlSR: gCF*Ukw.Jxpsp$ +vL= ]V' wqA7F6|q~ji.L*ѩ#;3Xi=wHJſ-v6ngr6X1y /X 7\ u/LMX7IX1_Vb }bw6ő("+ A47IM{[]2h }"ݘ XN\Eu:eTٸes RQN#F@{?m gCM,izZЌ`V@^Awکcb.hBu\ Yc$d<:ڤJIaO$ טtUmqr׾C:`_wی&zDļ{nTK G;_b`؃`çmFGZҢ J#(єy_\兣RMFGV7D$*`1/i,MOˬh BΈx%b9sZ0|S`r[V+0[jPl$g͒ (:<ͷ B㩿tsv7m7i<LS%]MR :6hqfT(s'-W^ $Tizx;xb8~Gn(6V*6ާPK@3`^t&|>7K; aæ~E"q3گkQ++ ,V0Y{6 S K%J^B5-W1(mQR⳧Ǘ'yIo\ǿ+X]iU:%U= =V 0 eݞR ,di 9 u{,E, dσL8 ì*ag>iF,q$?Y#wU6D; ty%~ 3Sƪ-ZO=T6>SlT*3}q`߅!pX+MTVmZ }g8o18F96ߏi"z to~ wmٌj1 >j\)NPzg3e*VA2ߒ Є6d" j3n*^OFo7ʞD8ȨUw!~n*4n kcE_b}|&t;&PՈd9yP dUq]փMcؓTӀ[@Onӵ%D/<},w/=(m~D;4GJ( HZ@G`!aX:đL2PX|Imr5uUi$k|rߔ 9M?r0@rH.p|Hude̖k`_*E] /CAh򑪭弃ى3G213eX_*CT pJZymJb%s}rƜnײ45}?RMqt A݅Zb<FuӔzf 4<|<9ɉ+0K IYGŻh?ƾXBbi$@b"IK梂jgψWl|ɲI ?G==oc{yrvZc꺠mz4`: }w&7C ɁA:;-^=nqJbNzԖ(i_˺OtIfHmyNѢIV됲 ERD9to}:r~zV5V /O%ё7Ad#$1u9}(@ݷm4cVw!g:5ZlwT F1O vHNVA1T{߮6P ^ p:ٳTFznkõS 9/nF9B'5Aˬ n qflCi0)Ans;CHsO[M9[0#tNj4ЩlQ{ŝ  hxȥgX mJr')wu^%L'λbk}b}Dbك(9gVزm 3Ttug3].Ы-{BF\Q,I~9=4l.#b;ZAFLP@EzP15r Xě;֋#P{-X(5?a'z%pw kKۋgUֹ+Ny.wJ&HlK9:?"-NvU "Plkį<\rqWC}w[GQF6 WZןjo:7z̅?HI,&t uϖa%,2zfg 8.K :ѵAV [2-Bx3[.28lR1 =)Gh8J$; Nm:|f%Iרnq[e@غ~0xwn2?Rld(a|_UW JyN3 q.цf6a:[ &MwS p6l<ɩ$|$YP }F&iP$C= /,c['Fn#+< E|iIRV)Yx(i•2~uX`l8##seNϹ͆iP0p:ORȭj:UYJ9h쓫=rB9HO JbIf7A):jçŴu'~2Ue\_6x[:ُ!qA9xWI:(CdЩWN BuEI2՝:C&낕Dt=*-y 2:owɮG,EA}YXg 7ނu)' fҌcW<%#N띍섯극\p[NʄuPsg_9ŲnCwdTY[WQJ~}h ֿ8'=[+ "0vKUaC1ֿ_5$ ?߉y׺tg!96ryj8aIi>}3hq k&r_Ҋ4/lTqXK`4ՕQe:V2fkO{$StI јYVJnBx JdM: <$2%Sm+q` h)b?#py. *1뎥 S +a c DQIcIxYݦBTH7ßFG/0{vk]g*njVJ*팬Ѡ0{VݜN [qq;O:1O/`&?WɾC#>E&hV:tGnj.Лk& iVVkWVI@A`1t-_8yo\ZT{[OP3`ѿ OӤ]Jj03k31]%֫A8 ˋYɤ"VwNH%! Jld-a:Dhéz6,x$aVlp+]gz1)=n7 u'9Jd;!ZIy:sj$WWi%R^hJq6՜ nϜdшVYp.Z8& 8.Ŝ}6߈?g Oy"௵2lE LPAjx 4ٓV DP:R1v´/iPQqb9hK=⯣zu")TW"q l?w5gϣ\͍I>;R,BpESrFu7W-RXp[2\'n¯~ga`rm 12};6VA札E4l4'+G,S?Ʋ av}c=X[w -`WIVo(MK-@w^CmS;[ٹr?H OtfZuQgd"IO&$UWJQbHhe߾[<$vQ(CJa@'z-,YOb! }UjPuQ]g$>LXCJUY%3wj6ξ=e8G@>ua 0mlxr4yJ_b8<؏B2Wxcݾ4L< vq=TQ<םSB-^/b4#ᶕ)pB=bp[kxR)\mzpKP67w鷟@1dl]%|.$!N2~mI/@*wb=ʠ a 41vPJ[Lv 1C'! 97: {^hSwCV }8swKH2CTg\9P S;hx0^ˀZ~yտ:ST}dlUSxkFtqxo-?M<RZX7RD*l^ԝzD[q _QFY꟪9ŹMǍ$N_M[  x}TYC?\/E×>S*7}6,Adc#E4m&(70귂'i> IX%ۑ|b@P?P`N'y>%pQ+:?40z˩`NXP9.E$J,VO<:鳌9/nV^DoD.:9i댝 `tQL 34g/ ]ʴ=tdJةSC4inu I@}3n[dS`k[2a4x[쨩1~FI/Ry=8R3LS?!wo5B=$~`ԍ(dr!7 `͊jZppV#$qWB}֢ PI|א~VM=D23 UYc?:uذ= "8)'9æ~Oәn_Cnj;A%P"Bg q8Qԯk`{*g?yx4_*r2 ;6|ekmjwKap:߃@4c72 !c{1?1^6VG&(j'̒Eb5<JQ4吂 =k讫%D&T 0!9i$('C/PLOߚ" cra2E x4O߆/wu4vOZtNj#;fBkcIXJ⢰SՋnC-/ӵuj>v;l4uQ zR!:DdDdE gf kˀl"{ddJpU_s _Oe`CMW86zP `x{693oRE".{_a4}H^ Q\:_X¯G#c|>aO>{c@|6XYAfP턤18k` pNHjV! Ұ!|ŮM Ơh />-[| 1.M7>بrPzo7ls5KxAZڱ@֞dBHA-ބT_%A I(IhcteVBUBYF؇Xq#$ʌ0+mnEuذ!Yٱ2mJACvXx =ʏŦݣu'] 4 ⛨e5*}H-q:n) 5ܹAQI l!iƃ|p!,6fט8i7`6´z1 pUܥ5 Vun8}ёތ,PUZ쁦ji`jgF4I54%EgݪB>Kԃ,% t"W;Iz<tl)m*Fg[,b7P.KRRYĽ&OD:zq8a@oGN H?C#B3WZ>Z2A[7jc@DB!⢻w7 W$Fʢ%}wB,0 fŁbvHσOKL}pLN`hK(FLE~78PPT-2@j݋bLB\4c& Sw *wLD6BА DN:`6m;졁TPQHU2ljC&)Ep]s%#E'ń׋$f7jz J RL#H*'eI^\)#N?'WUg! ݣu=5z8NV@J4d6S:/"*sHkCM ?5KBV́i^@^gI5Fܴx;"@ :Xqo'?TMq|MSfnv}^R{l ΀ KX8/܄؏0pGۄdt Z6T1M..7-sdpVR;_Lb@^x(59t#6PcAı&-lVBXG9@P8/s Ǹ x;m9A&bo#|j*|x#ȩi`&}e/_Ŝ?3-:Щ.Iw7T=a8+]`9廏+]$+e ƩªAmz5CC9|gAXR6!lJi$c, óDlo0Eqft QRL1Z(,)lrT&hsFX)CքdIn5'5g5;7s@-@E}f"YRㅋy r*hILqOa!2Lt0-2<^ m)ٜ׀9Xͽȯ7 |D 2Vs9?Gm@t^7G]h6: nmQ[.\V4K 1~W؟A83irkcU_(<:rjVj{)eIPfٓ]d1;0v=h p?c v}L@Oؽ0V0GTKu`iAw<ֳi6˺۽EZo+y1-p({+#&֞FH1ԁN59lذgj y$DHYAt`nSɗ p¿&gv}_4ZVR1G.%sΚvDKܰswM,ڿaXVqՊ?G^n3.yϒC}M@̇+0|I!5Gt1{z }vW[X9vv%˗|e_z_ щ+T}eF. YL7ke43c;;(zYO >@EwwSu. 'kH^XI꤬J׭}gm#YF-៲o 8aLjA'ixCd%"7y|O-.y+T2}5W)b/h@u őj_1ԕ<$X6cmF0XY<~"؍]7p1^X.Y{a *&;@f`adBkAf{o sYT玝7QnDUD3`AoM_Qg(vTE:ZъXB$lE =wM0e\Ѓi'Bxfش0rzR5{'5% `~* 97Q 3TEF3`S"^ZVL4P[Ԍᅾԅ_lʘ ߙxL]wIyE;5,O\tQ$F^1ijǂtt8HRP(\^oEPK5rv˓bzQA'%2ԡW bC\8񟪊K=|v a_j{ы 4}tq}Ϛ1BuS;qVxxp] W,އ1X ML"S^gARVFI+OkRg^qw[RG2R1$0̱NʣՇVf%i;msr|c.?z%v=a.&β3H[PQ/U]nQh:+贍 쬳XXV<\Bǰ(dZMS@rRډ$8#>NC\X)Ճk;qdfww'sYrtY7<7&y@*P ' yȗ!E4_}劉jXcw?7)~י`Ȑ sRa]O5H6{nBZ9nmAe$,N1v.#Gx+e/]m\m&GJz$ j@"S82Xy?'} sz=}[#ߘ|j3@MQ&nPǵ7k1κD F@.W'); 8ITR&[|bxoͰg0pBRMp؊owGn f6\,"S]ۆG w: <ɖ86Q0Ii}i0 ¯ǨOPlT|뛹s)JVsEsm'Q 8#o@&pD#Ie$y_c@$K\g[RvmcQ_#Eo4Tj)EsbNVPʳφ@czy+fX}|M "!\7YJv%)=lY]{:͇Ttfe!kEн}f0qG(xǛң4- $N\kVsƈzǁq N'[}r:?Fb!B$בn*Ǔp*@P+RK{ xbw #P^PK ~o陲w57tm2PTji!2A<%0-_R"<3B"_JE@#Yf{z/৿3m l<56'sjƷͨ_tMAOn@N?\T[lO_ MFo_FJsX,eǫB6pkɈ5!;FEA>W~Ǫ湠J0tY61ϛTt`DO3NSU6۠M3>z'L ƙ80?|KPkNK?fz:JoŜj015 62Q{RbY&>f 2$ܵ֟&矦(r ggx:3%w:*gKnU QJ咧7n Xy/U( s5:5 E8qeO*J?:!wDy<3]Jv`*5xc)A6j0!>P٦v$P(LhgI=JrZzjNJm#ud"}+o <~9'/?.qɦt=1ѵLٙRLbW_IM,+JDg&qpu Z(%J Y"ѱ `֜%Eסu|ߒgTtS\WOTo* Z o)Qib9OOAN(*R =s|BTu@oO MO8Cw5KQg`TQ)D.%' v_,Á^hr{xE"鐿xnCBBͅЕI^=?'XGN(VW 8X6Ewl.5$zYf ҍǐx~c2 /,DΩm0 (d -TY¢ZlEס6#|q`}1nKJ!~4Dpb Ώlb~c]7Zl}+3<9/oԹ]))e3iLV >1'|aʙ㾁@%G"x,dMÁus^3 ,f,3Jcyo W)} +[6OE|WaFg ~ c-YZ9fw"G,-uf&ܰ@ӹzbj{#~+@ >GױHcKe_S91s7|#S~2 R{Lѩ<Z̺iOfvl*%_٧ٚc5&dBuַ+WHU J58W58?Zu;[X OgU3$X4 V,F^$tfS_!^XD)|)at=BYYӝLNHR KFɾTwsCUYI&KٚUth!Rn ͣ~zˎ eɮ?BK#}z̕73OiN+)ɉCKՖ!u&Tԋ'?+IiZhcϜ]DxDӀjCT6iuW BR P@U G]!g_[$4g#aQ:8RVH -.m2.ئ'3mPoz1 Mȱg)mxim$$[uBϯ}{KP:KLi6grYgIF3#u[٥Rd —%,`Y?A nTUxe>UkJ٧I21=OhS`7_0]z[ވcąO _ȉ\D4|9o-C!ŋ:B_- Ccd%m$&d1j?d(ǘ$ShEtoJ ڥʱƝ"XH},;h>&hG \Ȑ҉}(:Z+ZB %6`4_ ~LRYY-n`&(sI]@8I 47Ɵ¹<kЩ9@ U";$DA!es?CAoٍJ̸E|=P3sduAmQ@\l,B2(5Lou{2XsdT=IF,AT`*)lAT '3 zrhayϏwls^SHXԻ'Ւx'(Pa6L\sGe4z٤,幦?-*eKASF(]qp"w2FSsCr>Mcg3;Og]iz QΛ8ugrP$?t@3Q"H 5EՍmbG"%GMdv{f(QB~yPH]@һhV-*xrOaSOS:ۀ{Y>Ivƨ#W}80e/]׻5Z$r,n9Lwx{/3T DI *p\ G2fWHD~GP++5!ٸIp^#J#[\:AE e jU5Q!-+ArZR Q+(?n/XwQ94rT|Z jSrq rZ:#ӿjmLyxȨaCt5'tQJDD kvu`YP,s° X Fb娄K>!#l6&,(?P4P\Gs3skԦ JdJj<]ECeęď&Z_ Mǟ.{ *GE_8Qh .h3l4j7:gRjҺ#[!Z1f(])'0/n>t6f |ҵ5g 67b!"ܲR\73ǻ;.SmhKr)'‹NY0IV=>'ijcK WlMW`nu,e 85A{nMmPsIo" 2q>|2kɏτC'E5]ɾӉ Dqc(vO~zQuzv:8g|dhnx'R6[mn G egI3sĄ-M{ KrD퐽EB6mc.5NQ41Jn/_Ft7~& xDžJ>8*Ǹ $xCdȁ 1fo4Kxv}9mG9<]q ,aKj'0"qDz\+@?'ir)R'"TJ1eЃ3R&(Nm/lM,լZT%, hvvB0{EC>qޭ,FhNjbz6:Ӡ {i|mNǮ @[x0ӕҞkٷ҅<ҳT(qǯvwZ|຀:y9Eʹ&\Cyb1g {*j&~I[ B ǟM]MW.B+f1vOk NucGn_s~}WW~]G"ʿ\0CUr=Źmaa8u]=&EO!`chq=879|lQ MC‡7,t{׋FΪZ:.A!cW${V7z+VSp+ѵj.SXe\vs[V 6bUzbأ昔{od7̗~?GNLJU0v=4x?Gœ6M6) 5VV/ "hl) Erp;ix87L֎p:~4jx]vnϛ+2hJ_DgnO1!Jr}W@'mĠoKq x O{{whs*R#dO[mZZXM 5(s_1i!NjT}F>7iJ`€2=$ $*7,=AEAar\)UXסD7_% @gn԰G=ڍs/5_= /ʿWɬn53o۝DD{3on-7MS[Ra\mOgݫF3(P%l&GO,{Ar C1_CbefR3*yh0P+n4c"qHyuu2tB3rmӣ@qa'~ ~Di5I\F#ZiLHeͶG\=v3|y!򄾏qdqG +=f+g1gX+.f Ԭ^LъJ7g 1ީǀq4V$"&QC(!{x7fRm@QyY&?V4F>49=uwik,Cb͋ _QҭL[XP ߤ|0s\X=\ʏ]oK-L X +U?4 RL {ɋ0b3Ҳ?򶭐ͭa oghn,ǂIL'|1Tc\GO_B>{@}}2a(F JMe:;2 ~%kHKݢ2H5-ɳk@|$PO:{DbZ7 Wⶀb<,R z}U+L $:'dҰWbG#ۀ34>eW LD܎ @7l6h)?f kg%+-Ciׇz mf/ZAer}`p\Ś%I"dRƪ!_YNCm۾HT@\ !J_K'6EY\P S"ގvq} Ŋ7-mJqh>cTlzÅ5\{6̝["bw`@|\ߍKVvLlx&3K 2p%G{wId(Ӏ>Syuz܈+p+*M9Fiуޝz[qng"Sh_[xU?1xnOm`V̝\^ZpN[cGGIS?Hf36)aIAڵ| 7l\1m(42woy }(ϕi#T}W{OKvHCԷzbHĐnF?DDǾGMxTjJs40/+oftl} {+VCjW(W:ϩL,oN$0oű4#:TF׫z= d}B/+Cz̳sgb'3x)31]޲-$[.4 %2nUGڵy>*apNo[ @{iV. 4& a5QDg HZ{86E~)U" SXۢ=Pk"/_gljz)H;\hvԛVϽ:7ކ^0I!A8@ `#R&SNfUu M$Mj&YW4nJ>AVvTp MjS YHq\1&P X?",1j}Mn1_vaqw +##]ұaKo{>T>FV`W* !M2$OxƑtn&7x _,zC"?..D2;k?s ]q76"RkII@ ;^U}h$R#C ZxWqKlVb`A:"ybCU atUn^7|M)lx A@G8ޏ~MRވ&bƪoɷU=.r?m T@Z,1ezx)mP@I3{ E7'!&HS#01rPc(Cg//Wæߤ]Lԏ/<\WNK# :([R#dra2qГMRqQQ Yp@a?e{நf&p-u65U`C%~Ԟ*@> S֠C$}ay7 -"w4v4H1} S<]zI"bL/w|ok: vN:J^ BæCAR׶!2nޣs%&@ڡšBݤR񰝒U5H~2f03@vw۲j'p[S﵆r!P%\`FlZ' bc΁tWIg`^ΐcÊAXB􎓔Euon;AUa{6eX-;s&h:Z㘠"R%:LG-GyM"Nw o1"5$ڻ2F:mx,-ݕY c?跏s8nQN϶)nP| w e0vxl@\yO=q()py4% 0Ils$Zm~gԠQ$yy~- ]Vmq3im4ԣ__ItAc`NA'!Y4+CA3ѻ"w?ޒuDVND0iOd xVCg)^Xf\: fh"Wv8UAoIuSjLVc΋d ^`,HV (zRxP'CQl?6`WBc}a.&8O1'"M{|YIxV;ڷ*PZR* ÖvW ě/67/(pYV*p*]0'rP[G`$ :xC3byp;]{+V``>C&c,y!S@$&U&v^;҉ʯ-i삲Rd 6E[{rR6?m7lWo]Ժi(%f3m1 c3̘-{=OZĚ$ؒuUNu9C)Z˩:f\?#ؙD8<>i6 ^3PqjO5ȡhB 3b%A-wެ(SUP5<-$ 8ʐ:H,'K0pn=Ƭ:dGL.u0I0%p&rIQ2c23B1f tH;,W_*3;Dg]6?zm3(6KyBkDnCz6u%-߽w QgO25N(z H> Upt؇~7Iy[Z6$yx]/ڝb}O$g]]q׺Sšj@3F!J0#e ҍ9)3էL4)>TBјrZK`8pBi9_qvFk-z1I^כH~Jfκ A8A}@Sh-6r(d3 ϟUcF DAhR]c`8;ҊfG+gl(d;_$D6ѺIO6QďșjDC偏E??}H[B2SC~ 㠭M ,$**ȶND90}1;7 f|GD@4zoz^]{H=Y4 '-D9<7${W@W樎{rV-Xd-D;',y {@Q[셻|qՈ)J14~`ʕ[#뵥-)f3dTxgSc90 ^Ͷ[Bf_c"*vULZAB;f^5&$)ZŽUf8)|F}O^udI ]C S?o}Hr7N}i9)$;.1Bue{ f֊8tq8 ;IU?Nֈ9(A.Mꮢor~䈒>J"4~GyfO4fauw/ߎEdULp6ѕH1\/n8Q:~X4@6m/?TblǁVVQwBq}pi MںY8(?5 o !WFy(xM{uֿ6բWw+/:9ϒuK|bƃ8n#w $jݯlEVLqeCiᱏ҂sf=I3k2+@PU .WڦJ*ĉC {& =tp݂ z6[~Y# q U;N dUL'ŦZX<,sΔTZbE찜W.jҦ"C5r& IDynC09a;\nVUֽ"Ht&9\nl0E^VV-zˆr޿!1>觋|-xq-~SԽ ŅNrEV`%ܮ@{ʵx8O!C%gbhbу/onj[{4;)/LYdumd}[ycf<`"ʨ(R N~zx϶ĭjy%gOJD2Ngl"gDƔjL{jSx|8`h /D!vfCL֫y=@Y'I_ZjH@5eaE)kC4<1BT>F{K V;hPFs1qsaP݃^@.gq`e,ɳ=Ct;;<6ĝ(BVgB^[o@H,FC<@a  FOMN`3B09WZmsؽ$Mzz] el®*S,".+44gQS)9 TFre2!L}@k&fɅzn@cDb0b_._oE. dC]8fl-#.olZw3qtCOJp,N= q.Yr y8yU6\|t`7!?cЍ0ʊfg, rhtF%gB>hH$$nuJnF8Xd!VNڏ!h\WJ7PXDqk4Dz_l4P:{F(df.!9svFdnI5yq1Xȵ!{UΜhar4.YBbiZ$T&p^oh>4CDE/KBmwMlv#B,n|i>]v@WDMHHQ|lZw7c*ud85j>T_ꁥ.KےO` LaIGib8k )޾Iy]UnYG; f`##ul i`9Ldߡ^CUK5ƅ`vcΏZZ/ު蚧yq8Ş~)O~O~fjHe*tx\۫~G|v2ͅug`_pit +[* BIҌ{=_T{!S3XјIie1G)W0:Uޟ }$4@=zVCe]w.մ7n9tiñc$d+`aa?:y@h/`ؤU|j3Ū?m0.K:;`еhDU1#~ Yy g3'xϕSܾUR bΧ\gY,{*֧H[qGciЎ-Aw$oA΋{~;ٛR܌xp[tF5aqtP,6< N#JWgQ!jլڞnk]/WMOL07B 'chu2p[ٟB' _3SDw7/9lu(KyR(Xa5Ud`;',蟋|A5"3#rq|٥Չ1FLuXJh8&0Dx%1b3"G"=ҧ|˨ 5eK6rbU \cqy >Ik:YĚ  1+Aj&m׊?B:V618P)(Ti!D=%;3x!)*55KKr]>dHNL0NbCGc!2C8EšV2 jMºJF"2`4 z>"͏f;XEL,{3B,0s^nG<\8¯]Q $_bX eA^X-Sg5 Z͜{o1'{o%x(&a7Hq>ę0nRZ7FYh~Jc{"O)%c9Qá~s~Re\$$ ;x.J'f"d,ɂjݜ>'ȠӑIyFoDBzd*Sk$&bi@p17W=T gƺU s\=jc= `i›/~=)("箶\⢪}-:+ϥjP? YN'֘2>|O2+P{^/a쑃 zV 5(܈jjgH>uFQ\oNeQӁ[2m޽ l~V ,DbV؏bpƝ i>4_\2&w*?&嵤d1YG05pY?_; A&xIR`ն`y[e&K f&M0Nz蘌E-/svx0llblEfp) /_zl˼"1B^`~:*-gh[,Oxd0D{Gp_9lPR i &'b]70 O:~ZVbrt|BW{ ]nU{0RK\^)G̔T00|E>~QW?ɒc!|YMt y=[D:SJYÊL equ~e69b:(tȼf wpj?f1 o&>BJڥ~|߅е"CW)jZzlV~{{J?,uC85`Nj ?))y2XP iS+vQlk(t7r!ÃڂgeKSj B_l3MӦUJos{zn'b,:LP1#Jɐ{HnKgz("31{V8۟[F͡]7z L(LB2-&K$ z h#Xv ä\8$1 *F?ߕ:r, z ;դ W~-{_^ĕtyybBcF >ʭf.9 b: ԁ'esLumA8r縁)B z&&LMz Sz|,P("L-e1X>BlQ?(DUQ &MM䇎q)LJ^?]gccgNq4%B%|wwbd*_W9InK.Jfq婕aX=Bk* 8 ?cE,QReN?'*d'0UՖ3kw8x@fG @wk,_/ 9w;蛼PLBЩ沈Z Ҿa @J0t"ÎT2t[]ɣHHQMu>>Rm,}!hSqD$P:ǩ-\4ՙ6, ޑY#Hl§lPc+58 (dd>k1_<CjnN e, G,r?`7K#QگnrY|sg:(|e2غ8amGKl^`A2|sHjQvw os4_n¥f5Cg]#Ӎ4pM緵ZdR,E.q"Tf#FBuDB$LL6 0cYl`u-X*dXGR@1z~+htLSrV%c19[I( :иב9'i g1\sȞ%\)ٙ32d]M1hƥڥi^AÉ]OA3(UZk) _i ~FxΥ9=w{A>͗PX/Tkb\ٰ^viY 5|׳`A{Z.>#{bhEX?Wi`ן9ߊY鳲5S*+nJz`}˷xQ 3{H )_ѿ[@ٝ3 ܢEUKj`Tz ybݗ)0hԷE]D{?a2=! qjiF}w< QZ=EAnc]7czf$y1wʿ^PAoK 5\=A:ր@R}e=nxKr=R]E v-ʗxk3k7L&&,)ۤū!TB!)m{7cS?[ᰛgxν fedI!pxq:pR Fdnr#t7Q.vT}ݴa$-x6i$ %1.8.Xv]`V>tW yx F/_IO:9!O4C4o6a.]:3uB| Z9fXQȪb#r lկŋA]:IpBr^ bس3ӬGqv:J$@^K k6|ÆkMo9L -2v˾HKJ^z&Ge͑:{,v({ 7ZOԋb*dIV@L5A)(/BYߊ< CJZ%G fަDŲ%#G CY'_=,`&_GGے69 5TOr-;o7]1S}4kMՇk0:hD~ &֝AQpxY h `wNשipL߈iH'g O2lCAF#VT6uh)釱IpU8{aUU@*(`nE49>7vNgPmp&dWDtڃ'j,,qg}Ok&ķ 矲u_/OphmVg3:\Eo1 r56 kݷ`0YF7Zt>,l#(RlkU+ !sC]0 uaLB (X:hkA9Bs ı3- Ö5Z_T3.$}|E_xgO^X]Liz6JgR0>[-=dR:s%d>X|>.:d4ʔ3hFqtsmq֝ɯgH bpf&o44wzä#]Lޜ=E;BG@֠u/uJcGO2sܦ}p9~kC782#sIWg`7>~-I7]bLp@ 3CJX9ўXjrs'x--OezcA#7ׯf'QL`]u50; ڹz]O EwX/4^\a $Fn GkBW|g@,VzwE&|LaaFNi\D5Gs) }CZe8^EmL}x6X8>_-M}׌.-MܕZ]سFLz9kE #NfBg~P R#jW0_KVemLn P1˟m?U.APgSŀ`Q?PV[M%g|W1gsiГڥ~2[pTw°~~K)~0.1:yRUn0S.oI>2P(K7R9F+`]zC :7Ż@jx%=~ 5 4 эՈi̢4H.݂#ٵ/:%n,yG.7Mp^X/X 2$QcN@#DtO!%d;7CI=oQ`3g'TעCGiA ri.e+U^D1V1_\k*Uⵛl'1&rBr#[6M}tr 2FS|u% <l\l_J]~xH{`CC$T>`ނϯ ŔCRN #^`HMx`~lU+>3 B쫛$iӼ=kt5]nT|")O]&zlSeC >tm8Ussx>&u0ˮ}ܾ#+FiWo'Y/B`iŽ.hl+Xs~$2lJ)(tjFݬ+YٛZi|ȑ2BLBiS( h~)aOS-iI9UJi602}Ϭg,#8ق`xįFڠh?#VX*HW4O@ 5ﲮ[smS<&N "`9dXX!y2S&.$88-LeQ_B/yht ٖ{EъY`  bwuLVJkO !I, e6ouŸ'7Q~~a7!0a|$q|F6@= b}!\6>9U&@Au/)֖|0I"7bҩ o weDqR9EfI?a T)l\B_gWܳNi?gsw O4Vy̝R4hٸ΋kav")?%S]ZRYY^(5Q-vnX;ʟk4ȲCcJ%Uc[jV9z9pm9vܾpSׄ:Ɠ1iagN cxb֤}uNś!g5S[igĖ2;,g \eeߺ ?E}YF* gw#c-_ z>oLQ-E w+œu9g&ig@Jvю+g߽JeV$ѓ| .pI9Pu^toP2B0D,eߎ_1X_Pľn|w5w 6 Uo /~aFuv.S\.L}N꞊eIV\8j(~47鰿+Ը%{LNcCUK; ixS%M>5;ꦢ4'6KxMռ tj Q96)z Qz[1m'XhIXWJIk Wo%DZbgҮ0Ҡi~oؗQJ/kg<`R^ΜSy$C%ju TV?"|DH0u֋ Mz\:+ ܱSKx*4y\ʹEm1lA'*M1/B(#A&?J1nu޺&w1Q}RNCB 0xẐr147;eM [z >JZ#Dبl2Y3Q; mNj#+80li4B~98 pf?Hk  "yk;Yy#jf$ors.H5ST a]0|]L[ 1Jkh7@^'2Td޶ќ%5T(8G'w|z ZޛYb&ϩEGaAGR*)Q/Y6{cs<;%ae7 TQďH:35f?A\_.5dHtd+ȰJlY'>8n$'?k,&ƺź9c{ ,"趞R/XH]D4z)+`%.}!vܦ1+V%P1ukqfyh~FXѦd=DŽ|\`CJoܦڃ,$"G.Ԕ{uud/?ax=_}$9j2 \]cur D/rlX=4/YܨmXt.޸$|0phd%]0'rq)hu8HXJdQ'@SBTdD?ڧfKgogSXxb>֯iaie`½='kxo5M=qpYfד=DOv\5${dM+d؁Q#:[%%w8S)Omzg@t?1͙"ɳSw 4mӌe-$wBӞLan&Há@}ǹ]wxi\Rw6{h:.;:6KbOmU}xDH.Y?&/R |M3`iWgjf;8vCNӊh66t<Q.rY\xΓK/IosaJrVakQKS]2;AIʕU\<F$'#]ߴD" *nas:.d"ԏΩ1hEn22Z^aqwV W\IZ'8Ni8\Ji ߅ tdfD~=xq*=>Sd{@w tSqf1[aL{p8+kAYW#X3 e}#u8AP>ZaY vj&aO=}PYALJ=r}VSBM?eaKb<8v!Oҧ.P-!iEa%b/:>TKey|hVs p6Oʆi g7kǻX5rjw2i']T!1-t%*3fN 9X~5U;jEn"E=o娑.Ȫ\˵_Ql; "T$\1R-o_! {j(Do3ui!ɌVSpO M;,J;wE‹bNpp&lKyǃLkzIh5mQvڰ)V 9XJ't>~\kɽBB{T~J|TꏅZpmx|_]ɗ+x w忣q&;*|ʁU WgD&x0^Ibg-}om`Mt}/s>F)]*Y'8x׵BAOv-Qwdg?k/j4XCPFy*r2q$vްǴ2mĐpniCÔ }lk腡ϥ Qj]? 6UxQ0e؀@E'Hb]Ȼ_tm.&el&2Jw]{S#;}r@j0yu:_\w"GF%\xٶ!_I(1Ǥ<)- X>w>YȟcH| Gb40W3A0lrM Ц:} 1PLtƷJ2]8uͤ C@%a""/40g򓒗n(izNjc 48ʽΦ !~oy#UC F&ܑ1Y;"#!5GS[1j{W(ݔdO!l㌯&\\H kv]*kJ},\7csQ*%msdb:Dm'פgvWhr<Q!C1ãyx]"!(V]:xķ;O4=F0|-YDZ㙱99_}nE ug&ia&͔Vv}@9}C;p?~u]lz!W#= e_ ⱨm)};J5"9&b@fmOÏQ3,|@o RN5iyE;B8d֮Pns>7 lD鞢Vٲ'" ,nGȮ6)i; 5OXԠјVVcܣchlJQfSw~ Xij5H6DY"C$yp>j !նGSgBWek.W5_ Ϭ$#S~? b͑Ķ`T_N2ïˠ_~!oYT1 mb!!nF~ԑ߰p Rsݥ B*!ջDRgШiK?Md?=W}|gy#F eV_ r`ydc'*|(5"91 UY"n®\I1]5k0PCoB6 2FUNG=h|nfPL5ð/fp<_JSNQz5.ZZXeiCo19ؼAE5A1ˬ4Ϙ ;)^H7/8%&6Iv#1,8pk٥-,4Swa]gutKS1e4ʗfK??Deܱ`r]3Wsil&=J-:_0td oabUV] HY:K,\guUjFӰ3u`C, ttpX#7ƒƲ40m @paw_r-0䩓2;PIA \hIQG}#[ޞ Qp NEr-`ai"{,-C&á/u_.E_QC9Y" )BC2634:4Ȗ>p=k@of1u{mmbV?mcT@Hk)4;trRgtj ~N3 Eϯ RyCrqnlO;N$6P2g/2 #S58 J.o=SFSee؟XyVyܛ; 4WWSZ]OL;Tďӿ6,.ϋE٧<g % ^镳L.,:mAQ#z> 4^Cדt[,摂YQѾⷬeg VFۑ'P!RNH}I+2oXrQuq$7s %ͦ[k_*ȫjѿ0H dh^LJȨ_0S#$YʥjxwBh$Jo HCIuJ{?x:Kf3)SC1/O˽d^!^~ I{Yr IiِM]cL-`\8I l|N!\ Zણ٤;Lbg9S(\rЉĘ)ur[G$˹7x)m QLxurHga*[Õr ۉ/x8}2U)^#ׯ8wE1/QHi 9+vOR  `>Dz\ (^rHj)@:=\[W39C7#ƙiZk靆_]x`"xMD,_M!+`ؿ0}'MHŪZ9 C*S$?]}@֐˴H10 ,n_[>w$Q VrG]@ G(]i >&ږvۤkJ[/S ݛWCY81R`]|r:nx.`p2_]W FRSɡx w֓gnl&}舵mwd-.xy@y=?/$}`HuJ^y? \}'ݣAHg(o؎%^G% (OaeJ'%YeSPq aAnD LmjY)t &aJT1umdj 7C5ޱrYOsdNo.|!v?x!|*Ƴ@?kC=͛svjضM09BD+\v7T&|§" ƫ~C&0e̳wݏ~/9vH4ҹTUW#VG/WEa1r]+!b㤷&a9kqW v M=e氺M/ iF3}W҉;++o\ O|OpXu-  pgI[SN_#17].p~;s.cz[i!JC+0gdGݏEnz}w:jySJN(; 26䳅!%c4ԎۏJ Ln:p)UrbKO 3D 4 Y>AM̑7" R|Wh39dhұ) ]ٷ|e!JiƬ6ӵIVzL7,)oK1n3سj]쒾7sz5:1J38W 3-MMo}RD}TX1'ZO@gzv0 LKT_~)[⺠PF !ӁІau;5-%/Vj~IfWGgM7PXeHN>;^yu(yG;@AX;p`6}un=q{MEznQ|@Zf2/0Q 7+]J422v68>SP=Y0bhK&upnWEU])w^a>8>GQj6vh:!+ic +hزqjt"rӿ4J]9`޹4_(gߍXeU:旨(?eV>ĂLxr9sEƑN+#>Ŏ Nb?o{%>s`%}qZhpQyj\?ҭ\O ?GԱbl4dž(]E}&ڹfL/yYwU3E9/ `GMKG"A%j*-:B\2̰ ҀXH]ٿ|~i>ȅ,N|IwbɦQoyD9K`fN7zd`$D+ 6wzomk:T3ou^O<>bŸ: :"-fɥjQDs\wZݧp8KZ=OHLpdLPLNдTbWMJY/qN/J1*%>ȅXӁa'L '].|ep=[I2_ M9{.iLN?GѷbIO;CF&gH;|Zl1r;z$1h Hid3PlSeACUؕ!& TS\mO~Y c- $էg`1L.= mxUʵ6SIܤւwK%~P!doe)]heHByGЛa0WW,QL'Qc*+s-g,#ZݘsH/d!+x&R'MYP@dfnh#Ɍ7] /%e*R߈xf K$Zr'2zw76CK]dB\gK [ 2Ҁ>{~o4:FC6}H';L1&88>(dg"):g9cRQY.jLw@K0ٛ>b+Æe(NJߢ s'2I1 [P;|)DbV@ɛ0\iL0 kFms$kKsz?d^Wz_9T:X}ȋElXO4dGkͥ) \:ۤKP5$O& 4w>$K }Zsny+NxQ}nW 8m ^k kNT_pYwj+E|l=vrz3.8g&}F,~A^E8Z޵< 1 fxжA%T`"MJo8J+V?[.~U>KޮD`*EP<Τ"06V2ځSrk|pRowe>ʟT+ Aioۡ @oBf逜KȢ׶8H66\ y氃%?.Јnijt1IpAL Pw[0ʯWD)8TL`gK{XKVϸdd|v5ig"ZX+nySVt m ~Q~ci+Vָ)VUI0s(O %.ljxB } =l[Bӌ{L Ws$#)I~I*lBв6>w10N!Z^l}Pd TUlOB6stZ9㴭B/#\QD\,mW% sQ%Cr.wEumsC["xk+eD\&0^|RMΙS(;(?ϰH Ȯ>Cwaig_#cp,  zgZ565qu[Ob3Iy@u+.vrʅUk$#A$<ьt5wHj/$wzTZ'54/ff51%$B}kLaQlC4|3Aԅ gY u=ár 'Tܧ g]}lv;VAȔlJW\`J5ە"1uʋ K:1+o`|JMi$>hc,ڟ(W$usόc`ırKB}rE}sb6o w-];N_"Yٌ7sEe]#~36smܐE4yAYeCm \꣋5R\a%M4ad34d ikMJ])Xl%ӁnH6| ?g8Icf74w6DYڂu"w[kOwO!έ$ W*!#,R^f\[#_.@6xJ5"ܞw=jxC5 #Wuԁ=y ƤRPmF^ɟ^nWj5`ns1'Vt, Kۡm#JLJ|RI>vu]JK܆4;Vߕ|50v NN\ҥS^Ҳ0վ{1PV_.Ѿ\V!^EP^L[|g3PCP'VeO'y|A,JGu}NJQ]i1(QZCRif 6k:6m|ŨHb1GMΐC%-yRYeȞLP=1͏vc3nrTZ+5{4lȘø3 kۦ_Ȗw`{t*#Gٟ[mX:]&#&/AOl׃$^OA^Q6ƓSL9vC]dNU%Dv' gCaP?`gpn #h< vdB^/F#8O$8rԒQ2a5H_bqf|ٯ՝e&Y|cBٔA[`7~n$(|)|KRulqEgI;`-K3.{#|;VSstkA>D<ÃsQAG pJk289~zmٜ5zf6_֙&\.Fqp q^1tկdCpzߤ(HpHCWzd #^isseDfo2w`Β+[%/4t9N|\qXc5)/Ơbe)D)C,}ƸO#Lv5Q7 RZj)!hݔ(8y35(JҊb}30uRU 2c[M-o\_#l)zjP/o:||~;}׍)9[\k-u~Wl|4ij#G0 Hbd> 1R0s;W065iTPnMiBxN7UEҾ[(]3Ug^Z-Nyj("^$Ǟ(B\'kݹ)Ry Fu&=yӟ7y>\#ΉaVFM$_t5e@/lJ\"Gp]vp&9c:,-5ILe)s;}x(xLqH C,1c>HM:]7riAWt]UR e(],K\ײLS+|\\ate4Yq9ՁNF~gK?qD?Ռ<-dD+^CI5S$81E0ĵ #Û(OGGiv] FНK⭏[JépUᚈU\O춏.s[E ?V^#P?Iݸ]RҶF(6hxgFRpA},>'8j%xJUÉx´ֳcH>~u;x5 $ K޷5BBR*1%SU|S2,"vd{*+z#(ZA@A&[Ӧ+7I %>΁_3Zr7Ăћdi8 8Ue|~k'/>Vsv13ؘS9]Sܧzt@~FgYQ _ (Q"<(r!?)!O8$<v>k (]/e!Nj\-Z},Vӡ$I?W4''jr`XLsVޒu.]t+Ԣu; \jz3.у?߱*PbՇu sLYs hp= ,ɤu)!)zD=zOdfF{gڟGVkFb4rtAv oBjmV-vp}dN9 ´>;rJ6 |@+[nO9?vwܚ֠J(<4&G}mKQ㮃@(EiC^VWDbo513bkg#qLz(7~˃ޝ4]rDpڄ`Y0e=N*M쪐/ʭ 3^ r-xY$w*~[鵹R.lN VUU*-s9\l; A*,)ƙDu"-Pr=)mS 3.PFAoNTj,lɤŽ鯙3p9;mM6_j.-zvVYd­C&lEP0ij Fݕ.1RQ,\~^ U-fTX^_}7j$L(Xh8XM0 B-W Y$<&2R r \\}o9ioB2ݵu}€3h >J_ —6Tm796L 壔#`uILF']j5@H@{[svkŪIrZ.P|yRT|.#Szo Y%WB\3gr b*1pwPֿkJS@Njlkoeu #Hl㔄nSeyCAi#( rHN 7͇B-iE ;J꿆~ P{v\]]/?|; phz 1:EW^O ΎL;mfĬ c)_)/Bߝ)hنMJM&HYG\];wF neaЀ1NItz f/rxzdÌ (23虛h;CmFN MDvg1ff؊W95-jQ_4'tw:^8CyX –EsI,zw rxqo:üOpHn/AΑ+UIVk"%(92/JU=?@)BR-Sm ;O |V:Z Tnղ"+@J]B/ ]B"GEK~΁~iB5SssEA3%e p'ͱr-LH}b[lOIh` Fi$_@E ܌@cQIo ڔekest"|PcVlgoˊL25e3_Yo/veJ/ O-S^Ӡ^Q"Q f%<Zr楮n`Ay- 58!|웜D ,+tD';X͂xE $ˤwsOJI0mmKWq#zEby&!.kP7kH$o'yEѢd`51JoNCo2[ 1\7(6b-.}TLOy!QH`Qv^e5_</ns<wm *O"ն-)jHۻilF!G!0doI1,Ng"JvhVޞ:y hCq}ejo ?D2ɴIWJؐm ]Dc_r nl0@}qG-!M%)PfFMVIɁ'xNv$T9[j]Zkj_^qFU[&``6-5.DO}/;@*LWt14MDP67`𸼾༶ G0J”˞u4NW)(Z:D@KњTYB ~gy$"wr:s(잞=l8*8 $5xjL;]xuэzebnW9rS鱡cAG!NA d"PAUrM!"Rq%BVP͆ckhu JSSLmg?M̒jX~XlO֏doh5  .skpoUMDnx/)wXg 3ʠ Ѹܫ?ao߱0A@8<a%i>YQ긆a9 \4zEktzusBý>fAxjƨv5qr^b%[1}?߄@y}~Ub/zai:7?<-T='N+C-" uh70@y{JSZs٦W`9_U&uyH` Pr,cR7mYo?DK7xxP}Ybi:{Ԧ. %MspNn6+V.L iEVdz+ ZrC>bHW# ]IzLJ CdC1i@!]<=~>϶  7ɟx7e?g? WThmaVz'ZIE'[h|i,IM>Lļ HyiȀ/Vav6SyWRh+>hӳV pz1XB l o{eWye_~tn+}3Se %FYDRf0rr?aM{h 41U)Nb!1iaʴxTHRm2I~@*;QfiM-ԍ; ;^k}3+9T~kKE1ǫ8h^_pwu+ u2?nq4 (<`AWyv&hII= FNtiYM1KR<&xrFaBϗ 7R m6s18ne$՛0Ǣj$(*Gij&uQ-ɽR-n"U\hu`yF*H-"Lhq9'r0Bi=`SS vӃ6)yXr6z?zT0~Ifdk< l)n3Zpxڜ"ۿD5Зqz` "oz n? M߲:q@W8NYe▸ZY@j.rB49 |O(Qj[8 ɥU?@b9tokvnPd!^|\`ȶ–r|PtŭSWhd!U;$R0}uSfŽ"퓤.3jawiT!?{FS^mZ q"]ǡ-rcВڒX@, d낱w1WI>gz +ifkp!rB;wQ^`b (.3 ~aRp5(YyYZA^M%$њokѠ3GZ<5$`Ol掶[},cGa>?V>g) 1m$Qw{yǪ9_s5&۫Z "AI=KX]c,\^˒rutҵ+ T@wZT0δW|;a%4Y,s_Ŵ2Z˰Ԧ8eWh4[F<2Z:HHLȸs |B"c &`U(v) |f *Q )^0Tzsi]bZ)rz+cxmL"T&mń݉6 8!e秢")Jk1F%/ ?:OPP.?Bg&[TEb%>z}5E;S-BTu;ӕT{6oMW5_ٓ bwDH,J]2^-F~HLE ,|nu׋RF'7mܛn¼Q1"5#x#,WQ^tW" \KtBZltx9TYҷlP^*Sgb"M2+q9=T6@9 x,p_QALC#8q%0@*[g1>%$+iOT$ q,{`t'dDj8uV/މT1BvxyWEWJp&Fӥ'u2xA}݀0.Q9q0/"S1!MEDcέ&Yq8d {WN$:?=/ $]"<~=r gxMl,%1MZhX\!oQy%0}oGe?n_DG*M=VIIm*T(?0 Dtrr50|˫|~ס^HьǰIcBDh Ɛ4(=29Ĺ@홏]XY2>6j\vܒ 6Ʉ$Y],})^S* FOX)iM7 @٣sZ@4X/nv%)[wl)+FН?S2-?8 EA6oNo,Mq75V # Bzspxɼ@UKzqxz>oWR"m7Z8 =04 +902 prؚ-h <NV(Eᤉ ̝Ȭ : i]Nh`D*]:؍wӟ? ( ܖk}W Ҙݙ;J&Ĥ?-0xLPMm-VDA\x GKCgm7~W| V&3dzR| ):- P\}^r=A41*ѕx.)~ 44wb;V#oBUiU\{M cUM 21.^+\& eNOĸ<fHK.}# n{yta\|U4D7b*'X ._o^"gNk1NR>طtD<úr Lϣ"Aϱ0qC X3`ǘQ3AdQSfe|ޅ8+@q_Ӳ(;fX|`.>W H']K;ǽg!Il.hJ&oe`!7u\<=ߕA_Pf~m A3}|wcJ-^>uŶŤ1{1)B|Ga{5j}-XO%G{n^ y8# ~U !s?L%j2..Nn<' ^%i Ne2 OS#SoHy䞄|T_(mBǥvunIa9Ӈ;3bW8+Ǚ:Z &WWX2_b;PK~l Qb2)Hn$#B*FE(n#Rd |w'ꛙ`5> %(ۯ7^% ΟFz\klL׸׽$C@3q?PtVBۨMz W~ Qk*4Սtѵ[^n+pg^ (\zZ8O<1a{bo]\q"A/14sj24(wqtMqun\ѓD&_h Unk<ܮ-05Mss}I?߃b4n?ozL/gp% $ӋPƒm6tsRSpyTogmx].eW!Y\UZ>=ڷclti6gȕYБM$A\rz, E6$/6i 1]Z&+򤓁{~y.~e2OG`ƽ050̠aMHʄĪ ,uïOÛq]_U >tvv*B<^*7H2Z.ﵱzG~Ttejja)@lbBg1ܖ}kЌ7#*&؎( (WC(y"Smd,+ӬH)L~๦i%Sхo7,-vQqa 5!!f H0M &vȓ~:3|Z7# Y]$D@ ly>\ H"5U0cOٹU!tk?&RvBѻCravk0zO1T+*0Sۅrnn)dON3A=$ eH%') RØ!TFX)Q*Z+UyD0~BK #Ɣuy񰎆ޥxc\VGШܫspB L̂,:wlrt+ÚSm$Z<[XJE $TBQfjW(Ӡ(~c4qVc6Wu Ч'<A_x.[B@U]|XITdaNݎx;iX\Tqĝ ulclnǝr?hy_nX^>;-} l,Xn30-aB1trP7Tdi0ɫwP'į*D9c*e5޲E~4bVP0qfh՟C(5!i_sp!ԫ YOF|,ԀoVhkAHL7!1W;q~ ;YW6n0fb/&[MFK4<9Xk.7dG.v~b{|U3{NIfփ¥,~r7P{-\CH-ˏBrTBux,&M#i]zl- 6 ~.Jmدs[]K^~AkWsC>p-]CAG+ɭyH8iy&}PI}5.3 rgrͽ搗@69NO?;;W]*;ѱh֟X PT׸EG9hHAVlczDKyق,-M: B#Oñ y)8vR?0w{A{I/] HװK&A4$e\Z/Z*?p/L6#5873} kzY^Z&@QrqEZ7GZv'*ҠՆVbkQ+(='[ kW&&W ?SAE^/\4(8`>TS7XLuNS9PX4u?P~.UlMb0BAQ8dDatɓz-|QLjp 89U`UKOC#v_ztD~B~6svǨjbM1熠 ؄:ek6= ( STPCax&r%1Uea u/ldi&͵?}H|cHe4< ȼn_bT(CɖUu%p(듍LH6“(5EMΪw2房@NT^G6ɲ">蝑|l|oE;s 18*vRQь3Fud_e=9h5zB@9d2i@t' )PTˀ6d`)F+8D ;U$oVw7\ʞx j]`C򆩻!X`ʴZwEw㑕YzK6qp39])z6f( klNډcfG;+Ltokmn郮 G3?e+;",ڏ([anqtu܈a;Nil; Id3oY7Zm1,N&ڃ&_ %d+ WcZ3%j;$@~"7v 8xbLܹE'ՒHC~$>ٮ.W b;P~ R}TH0Me,<=lv]}f@5Z}<\OmGj=W‘ 7q\R)>ܢkU{N:""!lg F٤^@Cvj1MȽCjҋ‚V1v 6U㌠3S^NOz6^M=z\shVz*=mx8-52UFOiB"b~47k&!{OU^`9;ޟm_ }Qw~=EGY|+;iSl\{ %r%ѫ\vKPmjtvdxYP-y pl̺PX7/tF51 A$BˣR~N]DgePO1D tq1פ-:ߴB~S?=khMz0N-k^GL0x(]!:ص^%^+ kh mh1 _%'o}iQ1KRi-"nwz^,MJ2<hM<Z0sg{`Lm~d: t~wq%m{ o9 `'~S6hgB? UiRSb-p {x*xՐ;QW#TmW2QԬBr ,7آSD}\/PB}\˕jkS2$;< "^SY\mokƋ.7Ec7("g,FZѠ1V2nJWSMp2R-v~wSnL`kb)3^i ?E2C(*}T ˜+Ȑӷ'{AAzZq'@ xۈiϺSâQ;&HƎQڐزwM@U5P7\xkmm(ʰ縦O@g;,,5>\ھa7Ԍ b{a0t̼qJn_y;)9'u;7O8['/Yœ`W-ɔZjƕOz\|[}aDkW (|C-]|բI 8ٯBeP.E5,,!4gk+D6$CzT{'IV_y{ܦۇ<`4D&Wc SVZWD2w̌*-&;_N4^γ&&?5'ܫ} DX\׊'O^vpXq[gi"Jb} NӁ*d+/x )ऄl&gkt8yOtm`f2`\sERΣ沐k-ﻼ%mN&Ec9`nzO`nvDŽ|7 mhU8g!s9ss1-ab=5A#r` عTFje q$DF g]O)_#P 0AuV* ~8=;C萷 ǴWUZK8|<;l&IQ @hu̳/6`6>@Уd)!>KƠLwAb*]J'L~Dl [Ϋl6T{,95;:e|5һ,.X]"Jؘz:%>L!+Gg.X\!?8NP+>w$IpL9rK'P41^zq"f#ϖ:O#U.i% nN:Xv]+\>3Y#e~-<|8[N-DZ#]*6ʺx}_q jvPM+mERUP#K%2'I.^Uɧ{][8 ⦸Cq-Sk\cH f 5uInJLӚcVҬIԿlzR惆ׇs]-QOC;Kb"6hH T8~C8!\9FhK8 &DC{cnt,6S:W0xmGNI֋$cνNl:>VӾPsGݭcnBcf]4ZFeqƹ BzFC!k&=ZLB_Mt-I|ɗ}r -&=M7t?R*K]WbwJJjZ_))SiFJ/[-G1Fĩ¯M3mjw!W$5o F6bZFGώKl+,SE@i ~7/oJ;5v =N$32Z?>ˑ2DcxХE1oFO[/Iu[O}0 f {SgO)">%H8>?d:KWK Vʼ3?/|QtTR  @s$Kt6$$=޺v srsh SzJ휈D!f2g'# eOb7'C t?Z7-_àHB MYҴdX ;UmѱK'UMCHE7'q[Yx/X+c'wV|>#ȌNjfk,<ʸE-bqʌ4kY,gM:F ֿ̦d52@+5[o> #afbپI3U=k^٥Z1\ײ!Rz}y$˩]I5QVeH)$r*aI&+vl5VJT; J5=I4~8/8\snN+\Z\ll72գӜ6wmIn*켞%y¬n=Ol5J  vzϪw^vC=HHIC(r"&yWbdac&nW[ܓr@qS9x|o3^-z'>~Kwȫkk*+gʥ B]voEN!4TH5IqZqҳczz۶ _B%y0VrW&08یQn:.C[ܾd喺|Ǔ<ӹ\Oh3H(Gw;~ʷu;;v7Բ;D)VJCJ D.mlmuBcj Ƹ/1,F'q\nk1;abNHk ]=HKvPwxV0u[2 Ĵg5nQC1=+D;tXS%EtIs-_6hd˲)8$)A?jG$sj0$k )2ө㔴aY>Wrv@M&9nhjdy7YYuipO_V׬naB+0 y7ttN<.* *P')%;-}YW\Gp2+\є bE#5E0H_egCbVÔ$Hk,0 St:m\"zGdjKJ*@љZ^O y`2O.pË_ I(FzTj8M[)j= 4!ˢNoWЫdQb%w*Z2 aﴽRI#<*Q"AqWEp$#b)750]wqm\U!y@`IxMQު&<%sgB{) S~um>?3K=%DWw?]ioijEor-@Q0%qR f1؜6֡h֊y*=Vz҄i "'y;˂r꛴N#@ɂXF~֑%֗8ם`a3Wpm\8/]O D&VW@>ߨ3~<(DNߜ=;2n14EV Kz!͘:vIyGW̒%:DRpC|=Ka,0-"ؼ,et .V"r$ܺ_;/SZ D/VpRz$xF)nQFiht[tjSh?d# 1 [ I45'+h^VYfx Zp[³z!c~R+nkΖTdʜ.H[r ?1IS̓Kƒ'Df,,E߃i5/o/ /o+Z#gZsF69g8U}naOn76^|nx(aX{ GeqzTi q矒IA&SM&εrF#㵢>H&)4|*{cJ/8 8% 9>L4;eP˺`k[o2I3ߊ$`B>컲kehB z(af,xin<~09` ޹ @qXv{a?WDo!8 ZY";xPc]%purD;/.w;IlGGMp\"X2"@nO[n:9rKDmIߣMGcnNRϵoO:Vo2 [iinM78nXdҙ]"3ӻL9)4+O%i1zRU53reFH35kYKԱ( ޼X,GQqWt.˨ه^rG\;1`Fԉz985@4q:VVđ-MFmD3}4)iUƘ@!#xIgaWؠP։os3=BAt0wLSsdyh9u *1AÛ:8aʍ&AlT*sEt-=9\;i2}+Zl᏿!>JŽ J a lU*={gϣcF7sAeGO^ZΕp6uؓw@bߜw\4cAU:_}ʌ,]BGY8ހv4ǵBUS7+kkd .cߒ(o¡YƠC `)1.26թL"tq.`]~7" ~1(&E`cVw}XEdq ;l_Ag Oo#O*?uiC1oRp<?U<%Qo` 3kJ4␎toFS G WƲ,*%=LM° T^DTyŮm7C9@N5S@C'Nnm"M6^"gbPjZh_5=ԣ^R_A&v2ʉ(%n,6gqy{YZfRIۅtcȃϨv=P4jߒs[-7Vq>@l<7Ӯ g5P%3O}a׶Wk(HƟEWKMj-B )f? c6j #;&'@{8R!z^Iɽ vDW9 ) O-@Q*}B<zh\Ӫ ʝO\'،cS vުHV+F]-w~hќh#@NC$3[^k'̩["g@Dޒ0ۯ{L OmwCf?-j5V\L:0=H;G|oK و²eW)-Uw<=8y!%J+wAiOLaȜ7 foS{dBSk;jV#}4& G%r:o7ZLS` WGuE_X~wv#OZ+ԣLZ _;ľѫU \|;hP"QEw UOJEɺ OwHA`q[d.ԣEO7pݎՆ ]'THN3JqJU1&6<|{A̪r4ѓ(/p u_M6tc % h JmB3.Ru4ǽ&ty>Ch$9Dhw^^ )}aDB0{+'@'XBω2!d\|#TtO5o+jJçsI^cK0!G`i38_9X#OWI7g4ڈZ/_ؗL/03L 7f8&7 AlX謠Φh,^z6*hB= 5`KȪ1 CV5kIG RgbZ0-)]TUs9N6^V 6 (g܍˵iOz:':6] ZkS؆;kSXaj52eoYA9@ THhED@n}?az w}t. e{;|o[u r=aĺ.'-a \Ŏ뢁Sj⨢81ysYYmʚdUŧ"d1FaxD8P>P'm!hMArxcMJ+{H5'c Ts ,:eKCHh.׿WXq]+S4|`%cdZkE!Q45JY`2hgeGjV1ʪ$>F\y,䍸ؑXv3"pfEgX3N oH|@&E )rPP/]=k/k}tr:gH3§P, loI$a8w@;q*926"z670xx^_@eGd h)s4@-,@Ə~ssId M_Ҽ?~ e4vB.yΟb ')ۊ ,53YS GB46ΜM0<ȶ_JDGE:3ig7:K g`!鴸xy2_O] efǷfJ=dIGƭF[O宧#BҖ2? |m&>u)J+ivN; 5d2"Cތ{ *\jb@E" `ORiϑn^z40dVDl !Y*bZmNGɽ'3'J-eE# pև<6!FM [ȹ|ؼgr8wL!|r:a66@Š痿4a|80h%6jIt6dQ͆NI1q`OQqm4"f[R criK!ѪfdLtr$A0, >蘩q3@xg`ghG M庿Foem9޿yĿ'_":~rhwv[n>":>-ot! K!XG(S&UP6J/YNZ(YġE;ِ)4RmB| >kv@VaPff>4Rۂk9&o]РS&Þ[4Kމf$wbW 38I}*M}Jr;Z:SUK {zNe\!#%1JXV[7g/3|cz*ቦ6oD|ŷ*i= bmoF@<*M}DE4{ȶ0> dUk.ȗsBA&eiXP))4%י!`.;Q8 F.Su~oߜ\ziE˶@}ҁ98&;q)F:6*U3g j+5rb[l_mFKHY ,;ZĝOz(d@.CĸkF* EI(Z.jb2a\k/Z:Ӛ%әf]@SSտsfӅ7is&eJ\ْ{ʆ#Q׉. zJI.د::OHaC/-W#g%W=\|gM*Nt:-C|9>`Kw5EՊ7u0*F)8vhY.V> %2OXa M@Х0 Q\7:F*mPvLkaQuIԉa)C${L9I #m|\?^k\b-@;}gEhKix%5oH7+\+.lpER_6R_#Ŧio'z% 4D3{t <@1obDP|Џ‚Bo1-( 4$t|/]AVzz$RPͼzUvhxVQF?< \!L~PhIP`PUG5a&)i\ACr)?YoY#6ߴt]< M]7)=)m.#jmƇ 9.鈘0·ΘR^) 2C*kIa0 ޘ(z7Y zoMfto s^gn%^ַ&d+H:O: ݯL֜,D4 c5a1v͝5Q<{W!ӍxnJ#){JKrwm9A$t:}"2< EqbW)=39Hm1~U"ݜN ۑd\miup]U|f*h-ne}6hD'z3dQ ؽ\#ZДw@FsOvX`@旇x:.ϒ;_@B8:#W5êpŃ0\/d|?>'wTͭ<,RM#[' ?jRE@ "1\V3NV~Gg=F%ׇwa(B\!Dr;?-ji]- -^6ִJ s$W+ Zfs? 2]4 e$(e5tO7>lޠ^ E7c DoC ١U]RЌl&04B{KČ,LvWxHRsd^lqe\rq~Yi.0?GeM frˤ#wM_I}c3D]yG&\ .r" |zXxgKYuh>J~@`⬞ȯBSZ=T~jJ68 7} ~Ӓp`yYðA8A-(u ɾOeUexb6О? L[$^<'Z;Ӊrz w$Wb%&oKf9,ÉT в%w%oh[H$JĠ߈нyIՄEx(Ea\fr _1#Thů. \Y"ތHy~X0.MX=?vҁZ,;x`w{/(>?kR1^>oF2w%;FlqT$5R=J{AoHNt*(Ku'.<oXSf&m[pP@Bgja.Ke5OWס%2-Q:[8M:=|O)$ipLZƫ-y!gHQAHhduP}ueRsrRfw Y) CywwiCb:\eL[f K6rZ/Qޣ4[o1!s7'4]׫ʥXⰎ& 2 o _V\!P0}EwOe_,SyY{Yb%fz@#m };.hv`dPpXRwloJ"S_/jA*o,k`75#YR.PA9 vTi87Iح]P FV#d:~E N"VERA*w{8 qI-<)%rL4yϸG W~i[KV]$Vg.}"&:SV%^@aٲ 5[lZmIMzM7 VY[~ +fB0 {a'\M9 Z,,_ 0 օ, :[_Mo+KAԄ4>0EG,֝EJ!O5\|У쉲%\\"J`ྜྷ^1~l’mv|=%:KԞs4_v $F19G,-b]8^LE&[EXXb3a%ȾPYYи]ΐnV]Omz"%&Kb0;F=`,8%c&^)J㶠&<ݘ6nc_gɌUl-Jy5Μ HFioaM}br%{icU CRO Wl"\GbRѵcŜQcyȏTMS>2[{SFJ,ٔ"Vs 6 s;Gˀg=R$a]IV V>*Oy?݇ҝ8e Mg?MlS0"yΧAP<1Lǀ'])9Ra)}2H+O/4T#$"8Z.p腧4n Q^ʴ5/^X%@5/ GZrɂ}O1w]'@@棌ٷfdFʍ%Fk KV1@}iQ}ňD@B'> _zV}0ˮR@N=% I!c@ؠNG6v{v`>r\{sۃp9w[Q$ dyLSb0cٱNg>mfKmƬ0Bb P2.v8Iؘn ?A}`b`W\tZ+{G r?!d#Rv#6_)IwFdq=d"C("S5 ",+oqS=uaqx՚}rr* fB:cc,v (DUCl/)@7<8%cR"=SuK']@@wZuu%~ Tnà̧tLG _OTqC)ꨲIZA L횓o^p"`]ac%;9 uF&p@70 i{|e9╰[Tےv=AoaYֿ0u )qcHJn>`@RyA;`Tɚ7qCo90~+H,RzO' V!-fھh0q0$[/鴍'{A= b=Dr0 N<9Ɲ8 g SÅ׼Om֎)ZuJ䱲؈_''3nrvYܯYkX9,wqg& 7﷓ޣb'ÞtSӳR;r+8z=ȭ*ֱY#z3CPjݧQ!()u&QV,(!WUy]aDvQ[ٖE\s|IQP@'/ȐV[XK2 2lm"UG# q/C{-A[2/zbc"wUmԓa[:}~|2B25iד_/3Zu䵵8mO` @Yi@…cw5 Yr/qZF,}.smޗ^of!_ '\Ks^cĒ;#Ғ1b|mFȬcH3XK2ϕh!7d魸=U2/-)|@q9=Sw9&)To!O7H~?wA05y'[RuuS\B#˕םgďb5M`I]^}ns߄U [:a9Ok}ޭ ('#gLxo78?h$w"*7 lCL!߲Ϟ8ת=m[ؽl%#ӉfDD zed %8&T{d(g6Ļ YQ@ !~dR,lf55l ZI3FFʔ)sK(E 7AS ^f]O`վ9/z60lAv;yRqꄂv[*E5XCF.Ɖ53sD@H_.j9AcŦ<*4R DjʂuDsM ս8,ŝ^o;.KZgbM9Qf-RiZMA ƄVЬ'?}o" ;w"q=ypX-~*zCKx]r߇k7  Jݿ>oz0G,ohѢ6=/2GDg{du>?Ta|l6Zq=~^~^3PaQ4VmF|U]y$Go`9;蓎}\'RHOsQXts&WͲaY7_`tp`6\hu[]D辠qvyܨV:]7DŽ:V)‰Y`~aBQ./|B/=KvzbL/}-1!s5czbPYcll@sf&TGn|&| ͯ_y_VXiY*nvtoiCn{% B- jD{@2?2P@5d=MA#S*f>3 ޑaȸs>ߙ͵f8g½k؈-Ȯf}R)/C~h&i5F)r"9>o#x}>' zY`ko a.;/#^!]^o h L]-؄; pqd:e3KIx#?RݞdUTp:\azv)=3T揄*|EMꈽ2F3}2lal܈P ߁'.d..,y$<((f,VXmii2ٖQRX?l S1٢y }ެNNm%z(܃DiA'|6GwjOF|j\֏jS/l+[8A4)T =S ǓѪ'plzd:}JF4k4[gvm.ڻGyHn$M)Tj*+,dSY$Ȍ5+Pw|޾t魵HP^8%ǟf,tw1ʴ K I]43O `>F1[+?kM(NvʁS@ %!d* @z})f}Ec": XO3Cѷ gnL|:'Qyr'DJc1@>n\{.UEEd]fS)ޤyӥ /IP Kw"痳;7+6 ̛3F2@[w0JRĜW*xZ'y-8vDxOVzeF&l&VM0YfGE2 ݅ܬç3 %āzyQ]t\SyeO ;i5@_ 9yF-5WɎmtaZEon~zJ&Z,U:i\6-/So>-W6!]ϪU57k)$ *n,h+P8U^4pW6x[9dL}y6pv'Pv-|siq+IHK]WߧtmJ~f": I1yIC.۲I(J4^GSrWqOr3e?d;O"RTwM ߇:ߚOz&x!*t`ncH؇e_G ms[Gl/cNJmn.K_˟ܹJ;׫"cp# @uj7F?|WghWCM+]导*7(te) & HHD&I-=l!p2%;GcfqbFz:+HbM[;`O=A}ܒB,`u͸˭-GtEϡ]3^O{$j<.;}+R}e`}ew/ש_e PDR'?H_dGU!_l jQ} Y,xN;"́ /Nte5( u9c z'.z'.ͲRۗ7g?ztlE2I]ysQNgnXDudnVoMn?rδz:-n_Y(NVb ɒw'Tâ䒉Ul (aLKV׬[6EyiL(1Phb2̗CxH8:pl)* Z =tN-.sq)3w}^@T.cλbr]fb>wƏ(:c>iuβ}=sr!F:辳msA'-wVդܚ!gshs%^y:ɨWo~ʪVXKmR-0DsSc/BuA喁)}1~Stw 9e`n+0KvNNz=LbU7dnOLv-Lk)%{noPc#G,Gb~zhѤ`,0.q}9YӺ5{Uy4ӭx׶%LkuҎygjlKZ>qL^5.>6+ޫ nevb+ iftR$S&MTB]Z0% 6缕H6a~f/&<+wAEa"c1aƃwc,^ҤwkU_gxoK\$ 6Xbd3x]YQ"qKCKVxP gAʮĽob?:E2,~=I{5u?v^fWK称%xKX弣"K*Jk+R[;$C:9u730Ʋ TqEDGwi r"'QR7[5XF8W`~%`uUuز#m,{9Gx`Zcfo xX/8F>h^;}\)/rϒj`@'M NzF;rhM0_A%Mup4-4@A$5u̓ X"Ɔ֎X jgM6IR>#,m `K;K 0:Ł~1|r=@&AᅣAHSsFB|G8>]+#^;M,4ZWZrjMġ9:X;ޥZq2ukF ݣ*y4=Ud/:~#PGF OHa987W<`&Z|Q4}C@"v?3i;*]4Pz Id揦08% rHȓ4]c@"un]…%7; u/æoivHedILxQ`tN1ⅹE&䕮?\^gx ѐDdC2Ձr T'vF/&;r}SU %s:3̦`u_WR3-EmܓOSCR&ŭ&kL\\b"Pl7Zsn;X[9,{Y`;RQDAtak[9+U%6Յ@Q:t/ KN$:E_}"{\1[ n)Гy%-i,\,CLCZĿ5b́hzKQŞP1w~YcP? |"?ݸ̓}bt+D3ve,bR8c I-$fO#I=ayw0VIXޛtZUpjNb B&=bQ9k-;̵hր5Xj1+5fNPb/ѓ!-ݛ{$B ()ur2,4 3Zr ƩG\v$$,D@qEBv|tӕxMg^ 8p}=:hQ.%;?ZzG++U}aB^7k9}R.(|=bBm !0ڟ~kt[l||?fZ7Di nYɸNrB5'>ǷwK0!y⊭Mΰt)J[d69%q%NAp'D;lr&V X/'z)/ct^1{ߴ0FTO4g%\&ߩӴ1Buދ~:`f̼$sM;%tTePċ{YT  `44>?fΓ(3GyLZG料AɌ~eGQWp$AP.HL 蹏?Q 8zo) Of_Ar]'y׻؁XdWpf͠%',Y5kȽ )L0ml13_r Պ?e&mYq|gwN xK7G`i`C#FV C)5'Nfty 5EV L'>єdSQ/L1$n7zگYٯEBì ~3~?@}rySF. k^UV9PnƇ/!L4ɃKm5\iKj5 +X28wFm(-,EKsc?ȏ: 3~=k1pV٨]F;~6wSĉpQvNi[vB+'@g@O[ريzytZp%K~ɢd/oQ'*Ƌz-\{/I]%}{"Pm:rD1SR>C3BZ1!V3p&X_V_aܣBP~@2h2!B=5 WOȒP$%Iӄ8+my4Žv1 !rvI@{j!NeD2"eA3ay׳|gu:/c :C9vR^ij 's}d-CyTː_ÿtBrt٧7NyF"8 c.u|lj>UyHtQaCrBnVlځ\Cci{wJ)cŒ=+~C'7n57%w TJjOyq@g6E)CyqaIdAdS>NB<Ns:$Bۊ_>]f1K@zEAwgFʲF`U}s_)çO}Ըޯhl֒ߊbS/_+[GJ EK*u|;Hcb_ڒ _oZ ]sޮ%֩ފ"| NvUr%Ė}eԈ%M  %Azc}."c?Q_ sŌ? }*(D΂2K58wnuV' Yk_pB&RުJLLFLF"cW9f}5Q+=ϡ=&s:Cݡn# k ՋdԸYM֒@7^[Ad Y!w%#L-9h(t~c...ҝlD: }[d}p )nA$2wHACx=ގyu֝F%@Jƞ5Tj}qV1$pY zm.F̍9 Љk7IO)x GTřZ8XrK 21*".셌Äy%D #ò:3z.%,]2N00I:fٙ_OpȸnƲ-&!{USypݦ6 d;(!$dm`a1jbk9yޏ6絹͖)TW I|T:ȴaD٬" ?~മQb%?^8; =ܛQi}9p&"4e/$ [fp!DaWW mJ\V/N?-WJm|<_]7eZ#w;'J\'d2fb(ISIY xYayY}? g6[Nt: ,E1OCq|#ď"uOӫi`v捒SC `Uމo{FmHE9\2\lkRHUK<":|B+ ')p]W[ `?ՍN͉bd77j=2B `wgw|4ގJ߾}7qɫSSE|"l.$  יGEy~eP;@1lgˏZ~jشX*ఝop<٢: H26SKWU 2x%=]:1Զ:y;ߣ!Cʽ!,ǀ<'[{+P iZ'֭5|A*HEX6dQ?Nݗ]Cwmd+;H1ЀVW_Sb>*(Ʉ|N!g_#C7K!gHT +ohriɩ})y#b95P֋7):"E+$d&^ q%No=@:q q??yARcX^R$MtkdY~DDŽPo䮥²Wfg.tShtܢJaѱŎX6(`1gԻ.emXeΠ#6Xʒ0>9A6< 6/ѼpmT]*x+gGŚCƄb^7Kgp @~PukC8+*P]`hlR7>01GrcxG "_~gUeS&K2=y Yhy5>G,UwhҩC0,WCɦA9p)"b?Ew2Ίw7wCuw#Q3g,, ,]9<6@/|왎wZjś$.'G1%)SZ7\&zwɈen2W0{—VJ5qw}DP8ŐPIgzP sxOH.6|fS\Z"78{}NS"pIGM = \$*_>pOe\oRaQb &zhb+ |tщ%Kxf<.pr%%L&CI9YTqg, z"[;VAN51w puk+s,˯p@Z ~$Ŗ>3oc}&:H<ՄIG3&Mnd''JM\ r֍M{p^, idu`&#&7P_Vb ^gܝ Ԫb#h]s1vjDI TH*zhY Шy-*!4`ҏZzKH;Cl*SF(lREwl-ZM3["@^[JٓoUt`3E-b< :odU,|()1{彞H%\*??}!U*m\4ވ j1W sڸ4QCb-X'Pl{lq8 oʕc)uS 4Lu:v^Lo0 b5Zp?:xI ?qiJlRXn# {`#`$*J\O~wz.CĢ8/e݄]ޚQm6kUɈdUۄ)B?oOz7z}ڵR& 0ni(m[̖ͽ3n+VT`5 4 vn{DnӘJe_c?`Ԟc/2Qzcܼgx+00Qܬ/&!a>nr[~†;}ƃD5dsr}鸨8a;I:hDk;3r^[FJp,~صN`nD5 ,}!o=u,ho|H4]"B #GaksT ni^oq֎BgA``46Y|! jUKF5~ wU/>kHT*/,)j:bi P? j㞃i&I3g8ۑjThcvoWl#͹gQG퓧 Ǿ>=_4jwh D+i,tyjޓJ8,F2mz]g0w$|Ge2 .Uhn;8(sODժ[ U-v? EȪ,uqE& {T u~{c#_u*L2 VD L䄁!Al>F"QNga.ͼP,Mto"h =F栗92Iq2ߎd"ՔɈ"<"FpڝG%Z%7?x cƓcnYv'A$6` ZŢM1z*^: $F3Iai]7DD O+P-kĔ'k*zK0bCܬ\N\aù ! ? =&ij .##J8]B* 3§Y$8"n&/ cCRD-^\W"gnJ 17KWԥ%F'1V7@8tXQ-kH;M[6p6+0s= ^ >N|uu/X#)BO.!Nu }7/"X\I+,_7 UA߹ŎC%T*onoFx& ՎA9>vp e(v #gH>wu Ejl7OPfJ%[;=u31QQy 7YS$bn^ג7fYf|0 Q6mɆT;PzVigz&66Lt96}EJ^%DFKT|(6&>fd\;^+F(}T]vm,}vI=y,xn?1+ ̘[\&L`?Utg=܀JSڟB]uɏ4)'=ǫ'D׊?wZԠ bEfLѧ9A;߭ %T>I%R D s8q!›$r4K뀳(Z XL&Tۛ5ڰ3?_ !Qㅰ:d 7XӮr$Mu'څ8Ƕ A Sw"IS=MZ#B|0V@bbv5L&p~H+nnVרC!d5t^A"LWmq>d[ypV6/"2"6GFm~oMC wd }KdK;wO4 E]}ZجhֽՋL&b/!eZ<^ cu_Ǡ @u ,6 є}k+s%.m9@H,߅v+cj@]sWeJd\iKgPHa\z[F:rAሂǿ}4Vpt3b0%6W)(?$W<?nm~j#e7=/{53M:{QTW ϵ'7WDծ~|ë"lf'AvLNa|aMhC-}Ɍ3^ ;2LtT$O;j;[];Š%np[@ݲly-=LEpʖ,l A[D ϭHjX'\"v x< y RaUY35Wm%Y5:angLRRpBBՁXNTΈDX/*xqb`,ªB.npŎR#ôYzzOXTu-(=)5`,e,@s U|:(i!vl9WH% HltkEE-˥[)B;~_ϭ|Rs<7+wcl"PUmֆѯ5ݯrhvԛ״Al苼nN?jR7W2 ҔK8ᑆj Zb %Y }#!$"YC0 (#6*ޢ JaYBw3/|tuIǮxΎb'p8ְkva'^ h3VJ~<+}#@7 8 :'Ό+ np(=^ͶXHT!yrrEUyGnxPDf)'Jv167yt{$1XC_R=}P-2Yԭ"Yija4&Lp*)c٠^ Ֆ uo74,Zlܥpt6uIAp@),Q e9ZӸ`oBFNmh6wĜEQ/r#A̍X]hqJ3(1<{>7BWx'"1a뚚n1baSS/8.C0]o_ Gi,㓘C>J]BUkf 9RN.q_Jez :]aq6"hvr#cq08z "T#! LU%{@*>Q\!"qxeA3 o7gWؐ"aJz^SA}6S\Ao86q&k<~{<Z* th.@˕>jb"XeeHr"}KSljf%JZ߲ӅTp\6wuD+~Uu]!YȜ& X'jlE݈sSOjVȅx z^1'T.]_zG ~mdLKwNs P,Vh'^kDo(zYe6LﱰnAx+T՚ +@K47i }'KMHbl%YBD57wWT؅CCwd2Of|x˺ۛbzd#b*iԈn}D1Pw+'uɡ П:QjFVd Ġ h7 L1pJi v𙘢j{$[V&d㉌/5;F}-ya90+AF> >NuL>nk}1, S&m䈛S +|P}NՕ:&<._bH)G"|e.O(Fm?qtx_ Ad++hVk]89ט#x.Aӆrʎs}k; ݳSo9Ȍ9P%>tSo+b[Пfmr0" "34mSoiA(|4:4T]&oda 'u6w slj(K ˪Lfc^$9`FCIwq.u >(Ǎ QOUG㧹7tf< ah 8m#hgOraDz k'4 rGCfjDͲ!@Q,/u9SX3[3s#Π SQM:8VC:Wfai- 5Q><9j% o)_|3!f F$+ceVV.R>+qTs&tvm  ueg9A@AC}Sf;ؤzhu}ϴx[8 ~S(wɉaIq3 |Pa@;!$F"pcl&~_+u`axJ ln6IIvw].C̉u.uA#Bb0ؿ9j5$8/D,jd] G> u0<9lgCi١1 Yc9 k#'׊X Qu ($"ʼnF;?׷U)WVNڏ<hFeGƁ#Yf6]o`jZ sx L{CBvW9G'uGos݃?X HGHpQDphp3kw cl9/*͒Y?KkX!ʖ;G)]wi eVO^1 jZf&<;y#<FZ[4?;g ~q qXhgϧuU'Z3|ʟނ(  \0VCaMl݂z&\XǸdՃŕXnQ=IГ|SY&j Q&CZ|1fw3SX[f&Ga~On&ac7WfEOT;>}M$X[>i*)wG+›U~xG&07sb5{.; h45_מa'Ajq%3f~wz:q`9+)GE z|&"[ġYsIX+@PrNySG^ͺ4 6@N]>є|otm-8,sJI& nWTbj!X)5k)8ڴ3 >%T~`gcfXx#L2m;w^[{(jEԥ9JOjEPS~Ohc}dZa=7hY"X9?Eր\D^;DS8sa/aJdS&﨨ʾu͗MHեb*t'P<=FAj^YVז69_5(N>eޭWSd\vQMW9$bc=jXpL̙W_KHKs~/!6xZ&eLo~x)<,( Dsit3um0D*4K4i|i6'XΥniI3o s^H1o KfWU$`"B8EQ57+7bˮ -qEF$VQ'[Bb"Jayco\v/#bKK5\; -w c@ 2NxDjef,چs9xksp LO͆TZ[%?8BRfa`㷴<М _sA+b8W giv "|nTԙ1BVE.\^CZܻ=>QO wl@Vv,LO wk=r8Na@M*=/eZ8I09욾^S*011G;NA cO$o:!gA5/8o\4>C ErR7[x[3DaϚn:8F=ɴ_ϐdj)1u)J:(00&jAdH8;w*:D^B<{MkDsvF]ڰN{ե] zl?gG-$'e3pQn=S4:MYڢފ6Ks 疾-k~o|Cyz<20\th. EKiī{@0+"R~! *%GFPcD|Jz;6oTck0mhpE7]w9&^-wտ렘EJizZPrEc;t ·?1Kc|y (> *O-2/ߴsؗdW m!z?(,}J"0@{5)8Z0L `K tQ_ףyh L8kn,:Ez {[ckiW 6P3N 'ƛ\$1CZآηg֩@!˹vdz~6x)ː蹅Q҃il.L+[ůlC ͜,PS&lA(':4]F%1XGoX+xOʥ`i>u?,Smvi9> %ȼZj| TyOF@@0 `&#+r~M&jQ#(O DA%ƾևރyCS4uWuBqGO#-c,R$mq\{7&J^;f?Nt>+/>_6NFtc! 1>P٦Wx vRïIh'9; P$5P(biW'TnIHl\FCoǾ9x+T#, V:BSG b|.:paaV4Вx4h!4 =F$;U`>,(T W-ߚ?3! ;H&1^(f# ^r|o2]6l8Ϣ"HU0Xr ︕;U`9ZCz 2Բt  d[{ENd{IXIC)G3e0 iWuxrnDDdJ܆_ckA*+W$} bNsEE)Nw/M·fmfZܖXFTh, F }%1oU}7[8j$B?ȧXc4w&i0]=[g[H :vj8T"+gW˕B.4H co1_ Vyp1-;veW 3WW"+QZBΊ{JY& S=Cѯ$O69ox]odK(#5]3oVf]"j(Zp?3*h H{"]ҺՖNrrWϴd&ݰZR r_ _Ct+]T`Z5f=ɿeN'aMZ-YeYC+ө&mkh7AUK^xYu%CbdMvoc~B*{^LWsepj[xiR M* ,@{ [p: XQ~-bJ['qx4,:SҴePƈx7{)L2,[S|k8QHSsg'QsbS޼:BYQ?G-%Neͫ.7gc¨M(0V"R4GU<Φh*(97Nf6hƁ$S(Y֐bp!'Ox# дʉ|It8oYN̗nCΚGɸ_>mPE[*|H& G]g6Wy>h2{ø\H01jH~d)@03ZEU6dN.*/ծ >2w=c+=OruEHn*,ڰ|7/o\Vɲf69.*AݷxӘCM`6t/4nnX(S;c&> k`R Za[{Ղ-ޝ- qmk]7xbSi p],I,q..Wc|9 W0r{é 2qܒjg,)aA/΢H"H.ҿ8vGXD3d@*TJ˾Rn7a^Yvo+PS=F_ %eknxuw@3>ښ1's͹CJLPo6~,Hj*QrjM$MUǎkws,; *>)30wP8~_>Pa}rh 8ᢡ)htk4] 2eL=8B?k$m\K/4h,nM"~ 5ʎJ&aa L(.;֍Ux-܉F') c 0E#Bi:C1f~@* T^-Ny[ڇ2=~P\ŚsS3g9lJoH L :.ktc5z0--(A b,: U',"NeSll=Pěz.l;|D4u>GԷ:\i)'o5ε88v` ÜΟhos`^l i".$vT\6(ZeM4R ET2Mx3 yTd[8׼`B$#esA }3fKܮZ2A7qs8J_?7r8)U,{{9䞖{F'kAl$ll|u wA%'rFiZ]A5+E@廧M1<7vsSr[\DjT޴< .JyǍ}KP݅vb-y"::ꅙr_1TS$^fb䯝]lb;-)KN {׏8AS,'b0Â9e9C 3ߛT\Ӂ5;n9l|j`5Q.Q6E`@Džw8E,Z=ro }vd5?on\CUBݑ(􆽵(H)PkK9,=}n+0WO=DJ/wйrPbF@mx/m+uRtj#?hXxCDjU"Z֨vc̬U}M{ &8E P`ܬlao z]p QcH4XJ5na[Cm G3`7L`5&~p<2qfM~_Q[y-Jb;K<}jx0 җ3f4v ȸ qRAܱ~M{թ'++Vrsʀ)8+r@՛C8Lڰo4qCGGq{0ڀL PPEj.e)N;cS;|6D VMw%sg7x !/t4,*lxI7d%l޷$Y^SFͷ늌!'ep]\} bx4CoXHrG7(~BcZF[\ Jv%GE[=VӉ4g "-$ 1N_s o=}p+JF ]X` =V‘{ dj2Npꋹ'@Qp Lٚ}屐DHc(ɻhL{P& Lk"Tjl"eU/e3jQxm0"tX!0/-?u{ma ot,VZE]qs1Gh&y *TJgNۯ6</i3r8ճEZx~0fh3!CyjԪ sV/3[6 9U^<$xgo\\ s FbW5m+nNJz!Jj@=WzҠiꆜK+V]'<9~ކS,!mTog(MM'_A 7zRaM/F(JMu(S.oo @w^0)"~0V!_үK.M?bwDxx>H5xv]En:ڭ֚jC S‹fmy2| e2teD*!Bj?N  Oe@|DāQ%_*pLiUis6&Ɋ8B h#0c4εoàbQq=ʣ3#^qr"F`T,Ic sY/&g88PЩrDHM`J_`Lʬ IN3G =sgQ>c烯ɈJo͞*Dg:Qkt,R͑h}_EP䩉-eMҠ󉻤,m'ryBE1,| ƣ}֜|ܺw n5hIna0{= "oUƐ$]r܋H:2֜_nA3mV2?;]L1>2~`vx3֮.\&K6@pT?K#GwnngA,Opp(DcpRIX-H_fB"|3u:.>a]L6(y bj0BQ&$zХޥwwc';PrewBcI׆ wAVtfKݑlD-Cff 3;Lj=~B3XLNCcͳ:<͛qB^ q'.o.9 10˸rp-22 T w= =:| 45λH| ff>֩o"Qǯ 3&Cl(bF AL96MͪCrv[be1xK$ eWސ0K=avɗj#SRo{CoqAuw5"niWL&NjL^n'K~, AA͚N X&p'd en'ſߌ KZXj8mFpFAY \(|Ӟ ّ3…9m09Y UlĽO~Ȯo0?(3.% n㼕5&)5vzq% GO䈁\Տvz=c˯T~1)̏a$f̊ x/x@*VN4d @ŶE4!qM+-Cs<ۓ}̚]7+g0k;rj`*Qf6 敇)jڱI`Ц LN zieJO+5>ﻅ~O9>ˆõ1 )PJt t_zE뗥Ky &$!`&Pb<w+c1eJ qa"#Ytak'ȀP68>?VzU\;kJD&HX SANI&UyE)UPNQֆ/vXܚV؇#gr*[S_gbz"bRЌ5`?w2x9 C.r6OsNJ9qyf iYX^sh ~? kG^R(B¿?O1H)0g/mzZ,ԖB+6~ȟMIT,z#=F~m7JJ S={aÓXoSb"~ -o Ys)KդP1}_`K`Wx7[aNErh|Bo-"PqrAޒ>zh<]{hږ.Qt:1UI6)GEu0;[%O#DK^ֱ>6ŪK)[5^O16k@n=ߞiV*ig;i|axLV:bY@;>R_ura^ cg23XG|ARU9À. ]!fd|~抒 3uAS<\OK >QKceU[;Y5Ǖ!2mFj HR;0yz2Ux"lI2gݡ/ո;~a;3ɨ&7Q7ĕEDdD8K'\<'VJVOŗbmFU !,DM#I~-(F(pgt 2@.T ^/׹*e$ =>?ae&|je 1Q2t{r%#H3M#y$Kc*$\|Kn#= dvѣF O՞v P yW>ٜ D Q9gxr6z#qʺ#hgmb̉ n ug!q6O%>|vkJʱRJ z1TnG72*PzjЬ0tݸcUx~ oCHzj]ׯU|hmLkVձtNu94wJg%}NN6 ̆}M Nm'Д4X^&T!|biīɕAxpdl0G)&d1D0I=&;_NNks5p5d?ΓOI})z~d55E" Pԑ` \p맳OHer?j >έEkA&e˜(J]{RSnTH:5I3L M1 Ee{яU,0Prq(B:t![V{Qv\X%X}2Ja`^zu9e NZp)VymP}GRkطvB'5OL#8/j)Et GƈFc^M"RcN YOP58I_yFWY]t,& sA; !Q(ԙίkCC< N }2LZ6O겁쁇'IMWhבve (yY";jyɨX53" @݀11pFCmVM/o7hA忽8Tlԓ#vE6$_'$ŕ 3(hb4V`p}aN=vИ!\ykOi6 3$16c<4xe{U,fJ-pȉsEκPXÛ65֪[!#;߆T*2 ` woi7|jgxRCSt7(Rn)`¬*IH@a/NPqQ10̸7uAgNM1BM#b͈w@GƀIέ?"Y-GF\d 1NEliBT6YyYzJ7Wk =97H/×4>.7B~&z&nt=vv]zIvZ?u(}֨穰l8M%\M)&mKp~[Ah#NgDڥQ0Y³o#J禔^)khS-( ;Py16ԬlC]o󝀆T(n @vMpI\xYR{oQǽ`7ѥM0xd(ЗIJ4F Nlg%T~oz TfT} n!uv0)22U5eߜovL\&VчE`: Ez%ޙ?V5`esu+9ZԫɘbP2yڈ;m _,YaűqF-|0\ư@Y]VTɛW[ ƞ}pZX7b 2&o:%zïz"ڼ{'k`Oqs5C\&yT& wk[àLvZRk(SV{e:S5+En^D >ѵxڎo(>s.XKRiQ,8LB1bڽaLg!dUzQ#r%c0ep{ny7_󅥯i.5n(8fjъN hp{\C=hdSa@`PxYQ/ i93S 0+ < 'Xyt+]GiI]J@ Tw_zӫEMܞ j 3(An Y cF#ǟQ(U=6woܝJLĈ`__> ~{\&QL  _ KoucbWw b̸W5ƜU;7髃,-[Vj=wD?rpBd9FClDiiz^G})'Q;X(r)UGU/:qZ!ccTǵO*v#MOT)6Tdbj 5E*PFߝTW9yIt9wmV*.dd9Z"Fń5gk ;`Q4t{%nGsXۄ-~?5$<` B-8gӫ)&Pxa\E22@Ad9S€l/ě,Fl./_@IN^@cG񚱷B^hΝӂYƨvSssZX~R .g) @l:Jʽ_`$iXyb!f" ˘t#7_͏0} D_%h B !i=b5 8OG*?qw> dΧ'tS" +t_"DY0ۺSj*!͹"4^ȿNXŊN*o7c&f;LXjp5jv|- yFj&BhIQH% IRr%K^]:7g5$#7-tPKo{Km W*Jc[ Bt),).3<Q{'3zrvrp \1l`! ʳ ݠk\x$Nn ._pw*)X&#Z5 v2049C1%eюSpGD&^i^;k|U=s&r:1NiRaݳoZeml a(p[1d÷7wl::3߬nq1OHRπ.lF=/S ItZhZV}y$Rڰ}'(#ɤ~-HM ~}݂f1lA;+ K|r}=;Л/n̏ワ5$Jjڎx9uzo`ƆpqfCB4x/P6r/'d}F#ˉslŮo;^rQY $~ 2O# W4-/UD gax6@cq[sf6kqhu/ʂuV > .␤lgFRpXTP!.`^ ʢs٫Z8Aby5Z,P$0R\اF (XK+0SRvDdqr/iLi9EC2w UR\`[vޛON9OCzUғto4^|2BSus]qN4B+D*UkwcnM ! N//gV a\_`En.J['hc7#֫DWwZXo3:t[+;j k~&PB|mD#8yun1 h2%AKEm:D5cw˸!rz> NY]<)rK8B3yh_5dmC+·lMԩYdfQ-4ġ6OZX,F;`3v02ZgJ7+]Y{A9\ xLΦ:3`Yu*Pz<3X M|7mU)&4,f6PW'\pSr?ρ+4VImb /NҗG|~8ngnUcr/82XuHsGwX:Ϟh<苉d_<3ӷ8$ꘜSog+ NC!&ՏRu2r_uay`,3HmDM Y $.3P26AMg)Gڙ&7`E=_YfPpf|WRlES eI%jR@ $2+T T91mh79Hbo JVj/JI6΍&w2w~{]\~b/nHDR nʄģدt&>H YONAy1303֫-2) ?O_屢#gruOq&5/MUS %rC7M%#t6R -<]BPufrd@wqζrUʉ1W'pKAAk9adֻh^T+kNcVZ Q#q%?ي,3e|~{?0 ߰/I}:!_N4bְ Ke{>Qsj:A=O٪3兌&-AޘZ S[f;t >2stT1s4Ʒt g&n\?q݉&rE'ؖeGBφ"U_V?t"*kG;9]bbY+uVǸAT Gl[ FD'¡{`1ַ\hee_^K 8r O|J# D ToR7 Tz[4뽮Z NW6AE & [#K[ D-\ 'Y3z& ўKb1#S;ZFHJm@(s+-hmb'{ PI#C8"_FֿqrԹ|f1ùxULh!k‰H]P)mf$^j3oS+ P!aOL/7YI(yH?í(y|R 3uJV=(JaU/C7񊽞tx}B=)ݝb)}!@*AzG f㯾tяNDW~<6,6}M ;ބS,-QV[G1*m2YoV4$cH(ѯN㋣x#ǫ|ٺ,t}>wT4%/&W31 r,d,j/^\6R㱢 'Y'B'eecoDŽ⬨̓*̟y#7Oξ(Q'DW л'ϬDg I fN!Զ1oˋS? UoTPJq hlk3TuFyJ>H'97^dp|?U$-sn!S~!O@ _?sPP A&Xe9vUԌag.{=˯mؿyn-BX1j~ FU_*sCW_dZ':!:GϜ/>D:0A] ENl Da`oSD؀2I!֞/ Z RMO#*2*j0֣hX i J$)JSEbCD+XȇseNVD|śN_BG zF1ûjf,4*ST4c wmՇEGS"yVgEMG[ K NFXE- j5j v?)uDtJyWYl&="W?ɀݲuX!sIc8ˏ<͟ ;EnsohUs4 |Yi܂a3>kge 9҃\Ņ-wZK$Bc B[$ZJ'(hsJѦ<=xgMx$p;Q<ƍgQQglCئS"Ixwr00zA\ZӳEsj`pPu5\&@N] ƘHH@:z:BQkInf iFFE}:Ŀ4l:KdzcVW؈t"Xf-}²nS6d:s{zQ >dq-O17T Be;C K)4'-d?0;z4Fv4^x+""l%mQ{/CjHtTQ}$ P`Yʥ떔ce(t1[>F穱\imS,'E01#09r\ǬGJDccFH]h1xmiC/}I˳O% _sB'k8F| tC)aUzhZ={wLKH)g-={ _W=yМb =J.T;^~"$GN\5x$!/DjOH$6@Y`?)Jպ$f)wW.hʦd0/!@)} A~Ad6 LDRV>ʣ x\}M?7w%Ju1jg@:QþAcn: X":0gl8xQ&(y}@9&A Tg_[V총CJ'k}>>̋=di0V :'nCibܴ#uj|mtDcQ~;2c8͟K06dGC9dl(On,k XFv=DbZ We<|f5^S'"T\ >QD3r\ JjH?4}F._<@j}k[*l^qE>ymsi`8A [M~T[ü  kܰ: INÝ)U)s߆w3USWm)9`XkÎ{uvU 1V)ٹ2f|5p%{HP y[?Vt;a?QzZd)gg맕%k #EO|;﨔yHxe|C/&~l%Ld>"T 8tO 7N޾)EwQ%j ]!V m}CNWT}9؟C?rKpF)WreIgTCC(ՏA-55-0q ش5xoGC-t@%g#|I4vxϊh2`ZnM1vv˜b y|Y-Wiۭrl>J"ng.imQ՚nBHa?T_ I^'09oK<*ی;v m7L;<Qn2)r^1O\n- l^8ÿB[|i/oxœ﹑w>vOgB⚹d_Y*tmoqgO3d{:l x;"ɦt;vr?KBH7~L=p>78s;A D\&2@⩊M\2 lJzd[8gyMnO lX $ G.">51u-}zA]<ϔ!<IN9HO[Ȯ oJ38]5B fŅ{ŢZ , QAUuGOpѵ.Q"|Jv-s >jMHyq%pA#HU z3Kt&G9{ E_`⥜&%\a/Y  r(YH ԖΔ)21#i,gD.Jn# P^HQEr@U )M;YyW[IN,w+ɶCwc!p_ c)v:"*oKUҞcS=f Atҽ!g=kĝFOLL wA{,u ܣjȞ9]&"(iG$9R vuqŻU~'w {lk! ef+6jHq ʊ[@β9yn|*Ykm7 㱀h씵 \8 =<@Z/RUk._Nv,Gԩ$F"x@{Z#-c8ִLݏ7zt6X;~܁D1d_-v Y~D,_#-hx>vu[*.0NӦj;c0 ?Dq$ioC–5h :STphhwK1  єc8޿7o0:^C$qF^+,[kKB_hc@t;\(=HeM~X TcbzOf7.wԑ6^i#1٩ > {USlNʴWm0E˱Epo Q'jjB>(Jt|H >nfrv֔UMO?sVIiKrY(5!IRAM.ygVjGO'h0 rS\cK׻4m^Zho4~9$<+raaCVp)N20)Y:<[G stT%vfwyxr7 3Js8Fۊ7ِJ{azM(%8ގ#.&=\I MtC>&pc E2&n [Z_t4UrxB.GcTe=e/I>R<߸vB8?Iz 7$]꼩$ Ja]8@d]x _3^d7,XN7wfQKa `E V-Wl[`!,@z1pJ{EϞWl zKWV` h ђ-fB bGEXn|I:~ w3 sʋ?rc ?bYU2k^\04GJcZg@C|T)CuÚ95|#H@ъܪ&б[I+tI+u8| MŔ!_!j4-w+UN5QS!GIrQζ#˯cdqCf[A]nwbf^h*ArD:{av;Fߜw #f(u&EҺ !`@&H6>&Ķ»‰YP . 7_NTC)k0m}g+w:H a38vX|8w_Wȗ/r?uH%>sL W!,n ׳ť]y* QT\qmORA>ʠ5%iWMm>inԆGfVbpƵZ'Gy(?RlmNIFޯ_ ?!ڠqtf go,ogZJMZ.7T],sbzbT#ߚ-Mk24)$u߹ ȸsqP hǝd0Y4S(k_`uOӒ\K`VIҩ 9&10x~~t p7EL]"qiJ]\P5J,o[J3#%W9RԳ\ 'Hzetak)Txo:5(=m}('{] T n ͅMyM~ޟ*cѱ?>,*.yA~]CTqRl/% gjSy p/}__<=>[_O)qA:&A^TPpZh#mx9l$M AýfR/}l7Fx$f<,D8$3p#6XkNДb۷zƬI ?Y.Z"l(eAy*z(8Gp´ UEl9HIwIT3%ϊ.߻)3Bn;Z\[,JQ!>d}t_$34΄@e1y><\:׸JWORXdKN Q|9/Cj1,+FH.KB9h6xۡK f>19d80_CKL/m+r"- IfP8wEI-E|[bŹ'덗wI/bNwrU.RAH ~ e;AYQcKG} a~8_\3*%f\{OXl>u_PA/9T|h!K"O _|}7R|U6܏Ms]yP {R/5i% c@pA(MC^ Xa]gg}2#jG|7@Hpݔ~W(:O[Bz^ #Q60Mq36-5q@YC{C~"5 CJ/P'tB.ײ /g 7$kI Nsj>/ձch~!dyi(I17mh~i_$BEaౄ70PQ|ڂ ᶚ;JBZ*shPM uܩf*eFM!N! &*]MMܑ XHSfX M,_ J, Ȥ wxY'.n#^`zϏZ̶G؄{u kVH= Oאҏ7mg>Zrw?['$?]Xv|oi~.sh+AftqMxVgJɫx'k{u-I}Q4Tt 2H?;ߎkYY˜U5G?<l O%.@i\A9oPP0NZ#^4VJ$kkvu'SKL1qe81 G^1F2FOl(MSZ#YOߔ.&Z$3AΊ6sAY~_;蠛h\.O,!0Psר6jp]T؟ >b$a>iY^ͽʯ;_.V: G6~@+2~Lɷ&>z2)[G F!L#BUpANy-;v\+&ZI).C:"PHb946)Ikea)܈d_#u3Q*w6tw"v)Ìgά|q6H!r8>ϊ(TK\SGH[kîwxK)Wn/+jɁ+5J5)hk /[T Λ:ud)\`Vm?6 ezt=/v kaBv$- Õ<,,;N_K dwhW5P v؃ Jlcϡ!5r/?^S4 iqQEV5_" D;(,=N j鯏#<|Xg$|Jsh8 BFhlfðܕ֟ Jr'}c:Hr{elNM篖T.8F7[~c z0Nq.ut1iAS2E=<)H%IF4^V&piZ6t5_Zo4 ^dۈ8iB2Ϡ:13WprMy#vD˜gei^Z'Q% ȼ>߾rYW)_g]"g\Aux \6"ռyI"7$VM+ ʺ0˙bE'4TW fK0m Vr!FW.ogOyX/;>h}_G{=5A =.io<-ٻ*+kbQ(p l~Z'd )yU)-ҟ/ ΕkQ/ݱaXE:HljG;{!#7I|WbfpqGFjO' Mq.A\--K] Qg#ot,|MDiߢaw<īB[:\Qg=DjƔaٱE{*P,,eEzH c݆?D&U^/:W7I׳We8³ G\< :"ұ4V+#o GL <a =,?r8z~q'{٢ԉ? Rځ#zTy>?8.fRԻ(J!:N[޺%V'=L-K22Ðufjo(eT8ɕ2l!tO[Sm~vKbtyrIޭop9Q\[ M^!He.ŪAAMqF/LIc>*4G 0D#" .7oTyB_]( H5/?f}2G ȿHgLD=?YSb0DiR+WLҸ`V75㣎=G0U`3Q'_ 7\6;rrbC uD"ye ?/Id ɯ|j %P|>fPa|.LZ俸u|:]zy"ذUɾ@$inަ[hEj4O|t>"S"ikru Ιm-Oa$3Y_HDw2MR0["Q&CwkRJ|_ȿ/|BQ!%pݪM.|4i.| /pFf#ckxSsƑ2By8> T% QxLm u3i=:F&-ҐOThPxAp. 64}ߍ ܉o8. 8US"# 䶟XeLn}5Ad8Y*(6* J:u"giĝ;W5_ܨ $Xpݫl\4֛&Gf2s͛ݫӟ<8-pC#[2QuAP#bgz {QG[mDEOkHCXrh+LhKŁ捁,T7\Y̤)8'vd9ye-khA$˲2v;up9_ NE$`mz& Jvu!pD~>˔\Gi4$av6 0VU`OraUc M|儉ÖWȟ%S!eln(@AF\ܫ؏$/S{:$ʡtu8@n۽A0|V"K3*$JaQ]/$1\hst֊A$&rI2 hi>9`%(Y>67RTDe7jp$=UԺkjvZ#l[j[! MFmLEi_5xˍCbJ- Gdd 7c2In6>MÙr f 겅RU!t+$hܴY"撹Ē'% k\ 'tRRotpUxd+CP(jzt:YvƱ*ỷǓR2t"Ӷ0;2ck &DڈnEJvXޥpRtۓdzQѳ"nX4gb*L.4(/Lb)ubIvAzA}wlkg3qT^f1N&fwTgP$L>3ڰr3[2"Sdh`,&M4UGt/7j\pvijH ]B=[g9XEJ=P(ÏL|âJ8`֏9 | '5k3aR 81.2 I^Q󨝆n.A~Swq=SG1n\`JL•k9j;Y:DfkwzYY+\. VR6%*'I7WӸ2 HʟGdR|lFB4t5vkZ̲ w3%A3zUZG9ani˙]_ww=fKV )D4~Rvya27Hfq8#&|9#0~5(LW<Œ =\T2 9o3f}2F:M޹{>!p_I2AӕI4/V8hsܗLv;ȤN_l,hJ~ߑ{i qths/D}/bA!(^"SHկt#G_6N@~.s8?=7[FpO{y;w"$!jU!nnOH !ӦuxbiLi,{4Y'&qz^4`*qܖt(BZdKw~=U8JҳP%a*anFTп]l[r_=ΔnkɜBȯN1$I{FKoFT#4B~#:]٠ @q<0ʻJ\(s8"{3%NҎJG'3t\|Mi[}"St}Uf#`wRqtst{Ҿ D#{FNsq\D(mHz}w/B6jB|Am9SfY3Uǎ8FnbѷcUHde*HX%EK$ٖt71i/KUѽVZb$뗍 kB`c)mQA돴?<ʈϹw`J/o(v#jsCoUU AvԚ/.oLd60,U 0T9[k3QԊD6 Z'0GqPW=}XuS Nzˊ4Qل}y4vea'EP=yOE *7*=r?<&TުT}Ot_' e4{73MWvaqZOdry`>R]~:$X*&}꯮"5˃,d6G肸SA@sEׇM_Ip9WmLJ0<Z퀘^q]N`g$x 5y%J+N=y+QĊM E1nݱk'|AyyӞAڲn@ћ1&;_7=*Rq5Fچf~t+M/U6>lt#|@#y - K(!U})أNk 9gq%F~ 0OXEQGKVEPz)PQ:\n< TA\4f&O1TRN;%zDA t==~iGkp#v8oeHń 6G W`8qKSLwm@J(hx4VS:lʌ.e"? |  LZ]Sn(e-Ű$?S\-=fAZL%@.Ϩsˈ>*3I}T\A)E`xI{4=糢FE"#wt7V% LY5u޽U%_q/h#Y|t*fn@X]S+="Tx͘@Uz}#i~.'^5oGzE?m7Zl,x+ uhz,A˽w,I?icP*] fRmE-ں4VGjo7^,??F<)jvJu]`L}vjIs߅WYJ݉7҄$\,wDӱFEFXhD!r7xGb^ D^dMjS?n6 3s ^R^p*ă.$վe$E[/, S_}~MPF3<z>u;POF}oC?k.OG#a&Փ(=2}'!x!^Nai7Ddc{}:G>+iky+c떵3REՙC ^F T>ZX,+92bUcfs2rЌ^e=(K&lu01Jma|TO7L;E+9ne+LGgzl-/G|JϧVIIe{\s\9l[EPW. M1,- CV3e`!jmӺG|MW'8i)H j|&MN޲u*l۔}P XC2K(a4YfCs\9/ !ǣII)'|}AT#%N\p[DU ^\/dknY0}s5s,$}{Nwbi[i|7@ӂ(QӒEۛ 1SΤTfs~x)#?#:C=U&u=-ω[7:VZDߎ$Vؒ3R I*m$z$NS~MID&]<ptj?CPpߩ2}*2Md>pߵ{i z& i/ԛqMշX5K}?0D|{T鿠O`i<22-S=";FU ׊@]P$'ڨI׫;7WPP!#f[Q)p?ƸpI@#G#.iW;U dJ#pu@5 xMQ\#%$'#Ic-B@)k NYM#}Ww<#VvHX}XDї"ԗU*#kz$cA4$jDЎt$Ao*EJcM9zO)V1 dKE&e/`//:_C󘛞FJL"^h4`R%wfj? ^?q|Z" Jh_ ?M"RuqE#x2v;?!Wgl̑="<]:[%Jj˒&vrj 1u^y}::"pC9L&HUoOb5nsm@aܥ?;td/UXnp h*(Or6k _n'He ێ&e$yì6vISP3 j6e{7D1ecT`v-h<$zy`2j+ܿհsO* Qf$#)W_̏ВmN-&Y&#ūH Xq(puAfiP:ص XDF?z(]w?O5(1W\/ S%^{B;_ҵfVzܔI+;m/#aO@)"':~CO]?h_Q;Vc{ySlKG=Ω-лȔ&_Qyԕ!&c~Em060uybHME!\ǞbG E<\ǧA+;AhN_Vmj v]`Uܥ%y`g}ps!`Fr@ܣ e[0ߚ8 Qu@,N%(K%"\d!M>qmiL0<էE> !Ͻ0Q8{i<>*3H3Hwkn:6S3ׯ%Yy'6w\B!-˃hES_=Lt`%dTJ O"siAG%TN4efȧ Ym8SG4O3U}-P*0Pi<`fzv`aA}Y,`o荍.0E \ywt(v<թĻ];!@YCE=D b䳭2,iЭy$4.^$T; 6I1%/\N~%ql;~R ӑ>W8R}+[#s<|zQ!ĘHYBe>3T2*N}=9Ǡ-&$IWvʫH4:%m3¨Kbqwus8gl  uR]~$ify oص7b58s[%+ӸeC& 3W 뒛ԵIhoh-C>g}iٺN=Okj ܄i{ hsF*2@Z= S#nqttdz'*fufzg c;I6Cztf<aVe7/995ॠ^XyjZC@@S|{vE茱̳ |~JvD=9=qhFo5?Q-9|i&U$R=T*$NJX&ʧz  9[`A (bDR$>#bu8:qn,i32'.̗Z8`[4!O"DR2i+)B&Qx[^x&s(DڇgRH;)ifMP6M5$=jB<˰-yJ {O. uߺGtWS 'lJÿs|8~jKD{iK,sR5zpSC"@UҲT[#UEgT_<"Hdx^QBE2QL ,xv䬤 gREkFύ* MeS&VjO7'q7M '??W&ZnvzeZI*qPO^ȽX-`0aŌیs1K_OE,Vd@!"&R#% f6[ݾZɹv58L7-%̡=EsU>8Lɦbp1aGA \-Ck ?|aN7JԑK'>8*j'_*CUO;R+i6!^ۂ2@ 7s8Xvu{#Q*]"Qqر?_smխ;iDbM["a ?vԎG=?ۭ+"RdU-=μ>ޙsŸoJ)RXU2kOx o#<\lߵ E\njn!DNfEQI !V' o"33fldw|YVa.D,męMH nErRg)wLŭ [j ekq0FRkN;)Z2핤j7dFiA׎4"ݯ79Ck}8( W ALlnBğOrLLt0vt 8;1R#%5>\<%A 3,t++J唉lzh8hC?^N֖рT`*3Kb h\vORӀ=Aj"Kg2)ބCu^imD37g&d3Ŷz(о@Ƒq{eh/Tȷ&]Z#Mn 1NMt@qH2M[b ׭L 4}ٯ(:|8C1Ԭ. \Bilf7GQ<" * 5͗C56v8f LrZ)e.0@l粁gAet$'< 2䘷TZ|0,Q'4:m =&]Cj_Xy[>:3b?m>̯Yeܠy<Þ:7(DnyXo>G>o->,sb9~ԂtD@K>zdM<5W8a)/ "n:ƫc11c~~Q\޸}y8QMӼĢF(}$Xbz91w6$Ń"3q2a6Mmqs|3 uT^F$K>(8;3 CtY~ъl+Ii#(!\DN[M"xoM~Ig+@^D7)j80 NfK+QtK0g h]3%A -44D+Kژ?yL|>1IȫaE/*+6nJˍƸYlّږ \ Uϱ 1k޺+Oܾ||mb`о<] 8TsNm_lO9uKCT4ߢI!PD@pkBqX}}nzj7XPN7( \us)KӽYnAC];2"$bf3| { UI-?"$?h=3O:ُ' hJ2+|KWH |#0;bt Cn=/<]Dռj#-5C mݸ&{c<$BXJ%c/ e: GOFBT Ī?3y EhbECdgt# K.* ^3%H 12Z(cõW+}^:u';mO~emn`vsD-C'Y!,'ߏl"! / NpءĖ5F44QN6Lo6΂ xsu4CPoa&7 'ܠrV hWğ`Ӹ0Q$IZNS}]VmI7ֻ3NDOF StqJ$Ġs;spA>kmz2z(h# ¨'8w+OhEړW\O b4E0gv" m>!G|݉wL:E%kA+GZ sw\f|TEg N{z~L`Cde`JPwWB*qeԡs4aM!̢sDK$|5 mMJV[}9,`fDxeo GV޷b*bVmEm>Q$]f"GE9玪{8 (Raj'T2J KBbfz!ȶՎ2!,Ւ1/cΤׂ`keÑ<ML9Bh<[\)x?a @G"CiKQybB($]闝cIP{̯/(]ű/ `M.l!ohlj"(AZD*o0Q\PXۻMk3ǷY@r[jRw]lS`eAJ;D-Kl3f1NǴgL!'i)-%Lj?68{1Ju @~^o骞xqǓil*x蹟]?H`ڃQxwȴ).qZW]Upqa52*&BN}:& Mgj`gU܅ױi7s{9^\8=!<{Tp:"48DWIMWQ'z'U"#b%b~y\Yd߭rr}OΧwLb%~2`J\){#"NX۵nD+5WEڟ'/k9+†9HU5KDUԨXq"0s:r>o Ei' 9u "mh: ?f2?m=[ߧZ2;_zHarw:h_o~@~-c0-n'.2NHvkr-&U#G~3@bk{c BT` =ȥ_:h:Z e"8qgX{zksfY+ĮdN.T@! {Gҵ,D5n![@nw; JuSXpӳ1$)] ms)\_[浧ꌇ+0&Ф*N)hOCu}H2R%1wfAxSe<pRc'I>B:39}I̼sHx0-rWJ?F\]p|S|02`@q:KM)ʆ;$Օl:+mQFUhiHN`2 ;H^b2%JNx4%sw9R:h4V#q=OnT2j!(0YDnp6-^v.ߕni#'U?õ(fdf_fuMRsT| p띍w\[B])`'DMkK-MA^+/oXq 'ke2O'0q~ \s {Z.hQO"ڥ FݱcGoT:Dbl>Ѫ`ߍm0pV@ Q8  Y}*H,u20N__!-+RjoCT[\Mkt%ԩn>}Op"$A&DC9-ǣ, v:9!f&!Jxh# bL|Hf"\g1I$ﻮh͕6jzɤ[DIdn'fۆTp+%+5W)Sp=5*٧8<x4q>%2 W. &y@WsJRD Pع|-H'^wX [F/ֵ…%G>肠>abB Iy??oɹPvLLR]Qcڝܧ8<8g_֛̎wZ6Ĵ;UEnt24IxXdIQ,= ]54 |.}Ƶ R\$gđzrPQ،K[P 4XTYJ@uH t'e{ko"Cb*XҐO&B0eJ?< Ѭso5k.|aPXMW¿E~>iO]st`gҎ> [zM .$&+ƀ_ &AbΐhOH̙зu`3Ʌ%t:]$5p8YmPh%a̳Vf Vuf oO?mzU<@g<N9F Jb'o>"Y(EK|,Vm΢h|3qEa%TO&. 5gܻVIՈ ]t7D?80$ۑ'}Hq BwFYf&v3_"rܑE\Pw bw5t˗|s܌xؙ 84OO٤ %avulȟި/r!UyD%VA\CA&t(S!Qqc1^TEAJ4JYq%4AJclÊf3 -E_G'"`٠Gjzz7>;P:nghd~, ~cye5Ӵ51S\YQ=AD0eIbFE߄uYʋ@(\P[ᅵ:LR*Qk,ěq/䲋:>l.r)C_(NqpsӉXj`HHTJG/IiWcQՂI|(DzzV;FKsFZ chg*Niyz 6fQJ*ƅrI> Ʈݰۂ.X͙3W+3]CeMwûwCN k> awS .)> b<2qIjO 7"_y>Cr *Pe*+HOO?p2֠&1X9c )~QH^fK$N&θ{eƙn ޻29 "0O-^:wK+0GU^I¥%)Zm>l(gmF`ffݯʳ^6 >͉DzD/eMEyqZRU^2-ӔG0mRBTߍнӠE_>*b!QKA@9;0iN!}X ԮCKDicZLh mYfU{9 s dT; SQM@Cnd8ѓLb0Oao"pT 99 _]LDEx4?V*ke_]5:"" Wh, r÷1_s C=eQsG[g4K=~RzvsswltLj&IA~U{_y['"Lʴfa+֤%ը,T1SM~NkuƤZm7ar0?MX}P|MsYJaU͞FQC_@=]o=+f*"G*.Pv$ 捪K<R <6PbQ(:sqDg1 캍 9:HkHfke`>0bO'B\9,AVΪuM7 ϱiBQHV?ŷk`O"oeIJ&hh}6?wv_<Zvm0ؒL.3{)vD !N[O3K33[_,D773qv ݟCin$K PbD8?KˮS{.}k\[7c&@K+ 7]ғiFq)iʢ,,`~lgKD .VmC֐DE^0 )yYDMit$n*D&NKX?_X7GuεZUݟ|3L [<nmJ5+»mfFBgԠAeG*LM[bW1廡фEEL۲R3g)3+@!hQHu4_Rt 9\ޑ) ~rB[w]GBh{0VLrBBD|}~Fo<ܹA/ ]v7HHFZ,YkTqwjȸx1L:)hx2(zzjJM ;AG RY*H:`R6pUwaFߌ?IίΤd*|Yu~wR+xb,/ҧT-w"Ε8nWš?1oQ{DOl vax.00?b[k_-a sSPd *؟)v(n:fWOŲz3 v3`'Z$T4Wjq`c]Œ:"d{ (6[7KGySe94~tvwx^ٿ`s45`z']s!=EL`TqU {s0Wb_w93C -}3Ga;JGOd&U2]C}â zw$yj;d*u8y[g(^rj3~]&nBt[Ms+8y@<]E&EO iE5AܫXBVbF?s&ccEoG'Q3Y09]5N܉DfҞaiJjbhFtH.)Q57ҵ\ʐ`}RP&KM3hNT&;.9;7fN@2u QUxbp죑* ۹Ki&M ²WOԒM&e„`eȣn]Q> aPʜሟt-<;d{,MT\ƒ- + 7K)r P9yStBa2}NHG^ c5"_Qβ NRƮ@z~6ی1~ لJX̒Vq7ZO'@z߀K'U̎]X/7 ?|o Bma0?MZA&`IEex՗T/'ȓ(! U:z7ܠ{>)S?%)t=cŕPlA.0e6[h ;9t:?N8yH P-.gӺԤüGoM5]W(!^fB>bШ@rޚNȪĝނe*g e{uMe%Pg \%NE ]tNDǁ  m`[lOԓD-_~΋Vp[htQ<4'PڏN)vo vslIglY:vs5P7PPV1b1IZّ-,ֻB%C W_7C0;W=}+F("tfGs-9.k bѦ3L=8o7>zYuHB  <=,5WLi,Ej4~JA.s`DU!qlh1wq\^ЪnTy/ll4 5ǒS!ŒWtz֑q}C޺w>.l7rJ*ܹ" jmufV/fb * lw? fEtip2>Cu6֣F ϯ%O׊% *9=d𾒮ϽrSXW㋙^;JZ U<(/k(6e6)Yw[ m A}YE)oB l V۶!enڳzsb@>Ruԑ(f#~I>?XJ~,To6:c>J blgAa\Eӆ_D _Wxׁ~(;2QCFUpT#2%(+jw=+?}T]=jt~12IfdHu W#`MPd4 bJ@;DPl1m: {oD~ÁMupKơ>ʙTKcn{J(.4p]Э8opA =i5?7$\5='n R|׋~6ChaZ`wg.۾5gH,L*ژF2?5_!P>Q%L( 偲ً(%$yTX}.G ]1yI$#yDi.R}&{O$ !WϻV&YYZ8(KDFr=ոJ'/'s`a,)\ti JIcD_rܛsfŠ/{eoLЅ(3X^xI[[-]0^0ׯw.?3Y9LQ_L5*kY($q]:P׃ e8?N.9`.m,tYݯ/D dY=;1`Jttio|HG+ odG3-i/MW`?ۜ쥯:o<y(_pڥQE;j bDhV0c8ٞMX]x/G,ed7T"LwtoJJÕo6;4a"$ٝ_MCRA{sݎ'P?=.aǚx9peeN[F-nn5`*]%ZadVa^tKZAҤ.+HFDp|>on^۝z ׍ ϖBrqE-\ѕR2xMΌ?3'm9Ie|0@!?ٲ|cbbjD<1,5u6҈ h Y+]"MGN1$8_QE y.ƖlF)HqamAOG P(Cfpnpf"s$& 19Va>Ȣ$,gSxJZ닧HoJ){*!n( _&bB٫}́\бГy$7q<숢R*MqDy8[wf_aO*RVhepuLdڴc vA TgۻO\{~$eV6eйON)91褯PL p+qJ.=GftrMg?,,*nda`B׌fD 9eb3l96Wd9N8|$,QBR+8Tzi@S 2]ujկ`zI o"#;ʈD_,gFKV[(iFjLOɋWBq?W(eVg3:F5ҴK'cVȖgFېg}V&Si/٘|# -2Nd2ˈ5 cT+G.g:sz߂=}/9Kiҥ[r;HcuŭHz$1[Sx:,|@8w0++IK~|ꠡ9Hyl=3s4]8F3Sv\8g Xs=rN]Ε#sc?a=Q[M hLi$5ߦ5ZNd8X.9rxלq(֊SWˆzmm}j&ƣU|)=fiG!j0c+'eЖ ~~m)ct(Ifp59Q_HtHP:uT(̃ipѩG3fg  Xh.C=1T''n{Ҍ ڋu,Yg7)..0!Ssi-.}\4(Di"˜Oݱ;~u]8Ɓ|)|}we\;Wo~d30P uO?=if BhAe$EB3ᲪԶD-.bj0;"iBщi:5g=&Ak c9&x@sZmb#naU/cem{̖v^ñAN*X$}#ၢNEZ4NOl+`t!שj>#xT?66jA125Q9GWK>_9OI|f9 S4{D͹p$F&?YB>zd޺l-:Q3 V`DKzI'rzO-)ռBox.^bX \߸ iQ40,dBЛ1,2Kqxh}ye`0614FGVCH?Y>f멵d C\&iÎD"b2Yl#:GZ-'PUK{dEW5pZ_X@h< ڿjAF5eLz.A@ RydV0AqTsvRLKK Tm-\#/eF+h0X{Ja'g CpCӌȅXD Wr܆ rA/Q!4a&2r#K00FQN[x͟iie$xhrBͭr-ə7FHyَP.Ėj!aQc5V=V.s:x9k|P!xe3?;݂&{q1 |KKC&~\ G3ٚ"궻3^ҩHcIƒ˟$Xuqugq{h|b %/rAL2'gZ.tu]3Z#[0eҽɶHTFѷjKW=" tMrVKXM8AؖDg~׈^iNpH6 $6%ٰSyer0NƞR^*$PXL%ُ7&GtyQAɾ ڞ4 Ėݣy| 5(FYkoblj'}1O¸V@z1LFq3x?OiB:նkecW41p33]%iǦi'Lwk  #V>_xacD)/.@d.ЬTUdwdAVtUt{=$NzV)W'u?'Ŧ'[x1=DࡐBjB(9\ɖkKg0lP҅ABL)Ru3We7IK`GYbݿ;z?ʫ\  VV jz:˙̾VftCɓC5Kg\%cnE{a4o^*hȞ|t=l#1&*[y/zePD/m_lFޥbQ+Α(@ ?7m _ 1 [oΖS &R9m꒚0 >FE!f^? t.I[,i#IsPZO7gd)Tzc$+"PS-|iuOj\mz\Oa{.VDދꝕmWOjnP >-+Kba Z* XZTr|Tʙ!2@-Va&R(PFϧ{$$?~ Y3 7ѢQ]HV J*ˣ{85*7 zq搅,dMcSB ax}+[ Q`͎M4fɿIώN5 .Բ> 7 +~}_gtȠW߱{jYw'#iMeFfL0u:h-S$ lXZVz2vTyNvͻb.rCr{MJ` F/z>0~ b3WHtcW.ԴV[)<ԉ+^9.͝MF@q`gX yQ,V3qʯ"hN5WLR~^g:Y0W˔;-s\ixLx}Sս_!v)Y}!k5&/"Av~$"F#[{֔KQ>A-% >Q"bޅ&NgM_?h5/qL>^ܞb2EPzHל|ʾ[mc憨Kkn9U2Att X^21(ͣ*@@Y3,48£kj!׼9BbЯCY_`{˖uX xhmv ֙s+"" ikqi*̝=,*mnν2SHq \FjHL/d aʃ\%2sW;fW9|2h׆2yg~SSMg^Øꔉky}Nͯ,CXaC`rSt/^̊[uU~፡T㯄=JT,W3dBf Ż;Yc* ;LD'-A쒜:aAIbWicn;uVgGDO;W߼.$B#`z;kλvL<tש׉>BP&,9B PBf6P ˎ! 2_1>608CYac\btт @K%꾿N'"wj!>#cC#";o'7 7`RgO9aNez컬$|#X( gy<`|T/jQ==v"(3y0UWFEM86:I^ģ*zM%fE1tEL$iЛ7#Y+xI+7 N4+`X-Uk׼HUwS M^k=BGiaI_?Uz<ٷ Ez߻rT~5܄ͼgB &/ܠ=V=yJW\`MQNݘD\,e۰i8d4̇ˡcb a|&-q5+M7#v3 `^g. hX-˺y[|ͺY҈^ܝ4ɶm0MGe:,4۹ePg"bhw\0\m{" jUs*/c(ҾQgvBMUU07j M7U\n@9)qyR^F~}  QXm,J*^^WQf7x&Moi -E?p|0OHQmBlǚߩsE{Y[A!ejDwj˕`:< S۩ e ZCXX֧>;=yUM[o4tUӰP,(^S!mO< a8c -x,TNZ69bP#a%, u1#"xz5^>v[ ^GDۊ@Qz`4Tw5 c!wӯ=ga&UY͑Obx{<ҚE.rLѻhj"&I:B/3mnfGiԶQ"Pb iUĠi2=Bhwon9l 搉rډ7b^J<\C1Cdo$!%2An(-b(g$̮GBUqϿtwmlC@ J$ t65u,BL̈́کlb_Ic\MT"[Dz(tmH35'p"lD=XƱƛ"rg#ڞRc)΅j4j|ߊͅt8lJLe acT_I` _/ N-*e_Ⱦp ZTtL.Ɉo(cA)?lg]3c+x6)oJ=Okr.xl%;=&Jk af;h ͒X&Ip,/e{0bbIG i 7se-2㲐9O]+c!8cLx^a2uqhmVN;pjn?~<?WK2x! x|{DŽΞnp #+̶d{7sVL.EpPs kkKW ͊5 r>Yq?d6YDE- <t?3~N9Ysa.⹇4y3I~-.f*Hd°<]_0,r ډ]@:8z^}4h"٦W1{UBA> V3^F3y]h:3O{l TD޽9%%`Ѣ$,a0/@7{6ڊVgI^Ihŵl!95siqEju@e.܆B;xR(~#R>pO_&L' /sN[y [c'/lBxKM5A:Q?FD{u5k]hU}Ei> $[`AbQ0 bscG^К6`V!}lV|(Ѧ(Y{cy"kA?V?#᫦|{"s..0՘/?ٞu xK(=J\Q (#fw48Jrd (kzX@+/;p"(s&L">F*%T}ErP():ƂZ?j'}a!V<ŏ"1"ϨRDkJT@.|VTlN0GxnTo R PSصuoa.ϥn/7`Lyh\S#= :l)7VIg tc(z}/pLhkd̫j{6xW] S8 gmo!}Ѝ``E"N2s*Y VHxP= wgb̉y~@֋5qL{¶I: \ґћ=_(L2g\>zڶn]<;<&=$!v>O\0#l91q/qk Rf!jq+Qj{|"MSvpH f ZK}h4DXrG2 EQ|I r {,)O,lJ)"j[g ߢ| _yej-|T \LbH ?ƛ?2fhW5ά@LȲؐ@۫F3ӾLy0>^G#ThuU_QWU)ѣ֤4dH}}}͗ `S*(xG<n+X=I"%i0v]M[2?۵3{eJ9).q4R:) V nv_q5̀;9)5vT *b"\ޥ͔Ƚ ա #!%Ip3G/ i`|(ݢqeDXZGuQELlw:'6&3EgI G9l[bMкptf\_gcrR!Թi**u>4gUd%U_KG~Eys5)_zT܍܃'<'h#\ΊÂjQ15\B~Dy;4Bw5]WdejT`M7/NnIºku2wJhi L(`KңKз ^SAxK<̻ȶ>r^GHXh $T?UÔIld&~!DH~,Wnwz 5;#(jY]I CCYhNj" "2mx2;PA.:B_{e\e/{V!/[e|S@fR*[Jpi%ņ-lc`5oE[׭PYO[ XݐC1_q,cƐ (Kq|E& 0n`NY mCw$c( HэtO <νl~@Qkjs. 3JGEms@o;$ WMmPі%KdI/J h1!twrɻS:5܊C΅z1n#(ۖ9wC% %G+vєu,j9BnGeU^yn+rαTJyYkQ<{$ƚ4SFk|\hOIz-&ʸeߟN|#J>r3 mn+9!mW<#̍5 eY=^l9F||FTG/̴B]v`g鐔QCCqR(*5|칟Jl Gd;D\]OiYt\388`I jbl3[3Z{aF|dOyuz[q+W/壻j'yE\)3zM"ca'<`d)day= $ЃL~ܝL'& I<..0%ڼۏf؝eӍo1/OQBW(\-VbqEf̈́0*^^.EBWjT'#Z촓9'-06NL +?c 3b?j ._gܟ1RDI=Ղ)lQyHZ9;] :-2&}^ڣA'2xBl"F[VBF>D燡/kI㤊"B>Xa{[w I`>6WKVХ2"{5R!ewW*lka•*մ(O&LlM|8l);34 k{΋qY. M=6w6k~kSXB;Ȩ K [<`y3Mdh;_XmM)%E>=CU*%QnQo&X0M VW~piS҈) Fg&lϕ,`Xdi6k,c:b)r XP%zǴt#X +k?} ?)B 0mo0>mq-~Z>KgmfS4XmMJ`nDsP}K˳Al;N~3y=16eu(\O#'A ;n@(q %vy@Y(\sNW1K޶Դ6n&o{ §Q.JdzP74;/KRN\AڃM><vSU MPw-]R- 9~\'P<cΜ3~/,pmz?2Uf"H2c06zHb 7;]FJ;R ?JHu WI% hyƯ~('StQ!VerA@p8N5i%t'e=9rdQ⾼xZ`[DĔa9PvPIs?z^!|w}[ձL2cRǔCv|+:Ƀ{7WE#M(6Ϧ]a^Co-;ߙʙpVP" CR^.h4AҮ 6; s _w$u7HPΙu%]DcR$  .Xa qvWE=,([­>;~'8^'Fٯ0+x&HQI= r&ŗ':@9+R"#cM'fJN'rNO5AX)NꎶkWmҁ̨hԮSOՆQ7Y(At4j)"x:UleWEm\{(l,`$5l!wE&PaϝlrGyX*fOAul39Ҟ]#f,1`>7(z~`{q  Xʚ:587|j eﴣX,pkx ُv? -S:GflvᇨX6ow{Aa]G6A6#b&+DC8^apkp)}*xP0 qyyHIu{=(U&G*₀WL2ӃVhRJ`k:̘@ewP!Z}?4  (U:%2A_>g}b26VZFSwյ?f"W, 3ʷCK}ʤ\5z)dݗw=}Ρ EGٲNzy۞\%2ˤ005먏'?; XD<8gOLjO|1ScS 6C~"y2S1\<()"YZ7#qA3Đ+"02d\SV լ7 ==v0UY`3 OA܂㪒.>|nݺG[3>ce4*2#`ד#u+`bW|qKŲ//t_溎<dt?i oALy6 S.?G1~ӻp+s'EtW&BdlvJ?\5 n$`F6Qa#gpy=.GŶjn Yi(0S2pd#vRna冱h kV:V9EQsM: ՙxI=aIkRҖ;:$Ooao>v|ʎsoZC>G1-1ml`2aPF]NBMCOXJPOk|>o_'`vnDB@h F{ 4ٞ7_rPmz8˪ݠJ n_L@rͷ¡i!q_1bWt,(Km# fzռ!7.5Yq+>*!NlvDQ%U4+[pVc()g40d &ލ BoB(Wc1C}c<n"^NLkg[/Nέ´ έpVt~ĝW,\&M=8= L߼nǻ\K0c.[- ,ۏ8n)AH*rR%|8K23]EdObԁϧ v-$i r{8esw]UZqB9ЬPð>#7CJ2RS0[jLOKӣm"^ 0tObU7a yޘtՠ63%Sywhi ͧJNs% ٟg,3麦hӞj}ףe r*F&/p| E{e!A=wC)Qz#zGDyIʙ&̓uDp*âaH 琸`]6  ZΥٜ=i ˸GŽ$gܘtVv:ZVmϞc*(BPdgmSCu(_\1 }-_^aԟ{m*hY $וt8ؽ3fJYp6:'^3`w7'D@[15|I%dvcԈc(qaZ!~==;`xY%kVp) Ւ{~D3Ձ*>BH0Vq0ZP]+y!5 A@Ȭٗ ",jk*;87Owq=0 ~`'ux ɫ;>lAF 1&GL"bgX"͋ K3~Iyĉ=QyKD`mq+DA}Ѓ 3IieZo * VOB,TgPX!bJ\7roP$eib)~*6S΂%z(lt 0AaW[ƒ"sEgHM(Ew:xʊkW"`h@<@䔙`djd~4Vac@]02G[g3S&r-n$ࠤz6|-r)ٯZpմo; ÈA_RcvkkqG-x-஽MkckV'o}\X4Q5Hm ^60ω8|>tpoQZw~Vo"e8攳 MP^쮌؊f+ZjgՆn_o)}wӅ)m`k\yI!DnMgN77¯oRTڈþ f&aA _E5dMJx9vC2H5[/YOΒ?ў2H~XjSz Yi]@w"k9G,zչnn?*Rͮ(t}/.b=mp&D'@=ٛP|!dgpSf)Rܮ5\,v Ry`9hDSĊ%hín\>hu}~VKWSZΦ ѵNX[r`NXҦ(bC0i Wӕ{aOY-, jH!nw0d눎m3ԸYs'b4׳RhwH}ྃrʖKe7gHrkW3rA8û^ŕv zH^ hz ĖK%> \C_>=4d$LjA'LRIcB ǗVbLd2*8Cq{{}n^xB'q"YY薶+&M'(K U&).Dž+VBeƱ*jZSn۟;t^egS2/E;pT0z$8m OGː\M/4fNhd m2>,$1$>LkW^"bHgsltYwʏͦ>ߴ,(N UY:im`]T.?o9qucATbLcxh8wq 5=GFKGڄ69bUQxxtј{.eX1>)L; [[Gz3B rm7З!!͋Th9mJlזn"6FӣlFl(V7PָFȒ`D^ W gki&1n$%,_-jX>8yȘVʆnڐodjYy^}Gy 5gzIo,Ehd9 QpiK gT͒llV"i4:P们DWlO$W;~V|L>/8֟ 'i3ZPf _]EE2Ks8=tZSdJĈaM0k@c:L"نpIOzeWptӕ$cdavhݮz)&V)jC lTMT;m&:~3ksoЪّ;.lj퓞~*?Ӂ`ޟ38)7#}峷ÑI!wH_!ZO~?#O+þV~%jOsCe_c}c|{#踒u|U<_x\EmvId ]$Dũ==ro)U|C|t*̟oyPP71M /zX5xS4zzkzB)@lUZ5NN Ҫ^oI 3ny x1Сt6˹CO^fCf\gNDZpQ afRb EGt̕JVjpUϿIޤuYU5AFXMUy17zߙݢ*ړqBt*;+0OJIR^SqC,zf#8@j Kj #胧h{ppf9U-,G6%L_&LffhK,C ~|P%CT*;C2ZM"PbX}}ׄv,W&Ϭ#\RӌAe\Ycg'YV/-ѫvUUm(1mS~C A/p!hм3fKP|%cPBڢN+S*@W` *4D6auMTOe~V?='\Ӕ4BY\-,ȇMV߃D J9}GE [_?[l_lcrqÐtag mޚmx nd+WZ_\z#.HqY]8\ޔ=~-I oi߳.s؝SX^b1 /r@U#NCuZ>R=3W4Lꗸ;yYN.JIau}AQz""'H6X7vtcc AyAUMnYkrc& m'N!z3m͸0i?;B ܺұ |UV/B @OزmV OGG%aٙ$ƴ@΋*YedSDZ~{o<2Q-,D1i$=rˆBR9,ۿw"B/ʙ9SFeJ}0!8hDZrև#I 8ZjN>SHy 6EgiI!h7ek9r2Hykw# O^^)p[Ewu?#4uOaVh"2$`0=Vve剖 \q tOsC&x j, >= 8Ӭ*Y{ċ.DhH`s$(oq E&IT˲e0T9Y;1ܲҬ4}Q>4rD2֗&fkE ;t&@FJč=W6Q h;ȪXG?V:窞Te>SL];.]EnjMs x*fM"P$|lн˛}q9ێ0WlItxNQ񳈢t:fܨ(f2sX^͞oG zc#geU.X3HHsůs. d**-i ះ=rXe\!Tʠ} 7#90PZBi x#GC>NUsxt/Y(W rK?) dP_A> 1[2$1E' ^>ݩ rG DK g, %V844+7ۥI@df={ڥN.[ȩ\e! oGH9ni/DF - #"TDd8b5ˢ\rHw ܅f`Q@a6i2r3.J~ `+5ӱz7E Q', ))S z$S ?<;r+;x()d4zJyLoyҰyC`j+ccd!$Vo׷˸c,zjfKBCzb1cVMJd~tk`&(7&@F#=l; <}cXˎ)V=d:+MFFg퀠tґW.9r03]UAk-U5j6e|Z>; p$;qӗ{ÔF%Y'|&b$= (umfSF)T4 9_{f+-w$y+wށ i(\Ư3nu`n#E+I}7;!@ VKβ =jVNSJPg x7MS bEYORnb0h]rI{K5413l ʳ \MJ +\Rn7~|6.r<ݼ{(ƶ^b:, SpygBˇG67>yѲ񈥈J/Օ~`< Bq#? $I2`_Uɿ1:*4/? LBKsΪlTodr2',8d 6~fw{pRz%5ip{`R Z%D[r$XwGOZu%kb=RbF; o]+e=r C \QbCkؤB*>jfZ$]i-yHĽԶRg8 Ub#|bO:hMr'ʠsC0{(^Rb@%iͣ]0k]U"8ڹ9R[ƌ } ˷']VGD>CBk,V8 KpG CD2Z/ ۿ׺hYnVBIUhIK%M6Ҋ5zUȰā6MXVf&Ҳ94D*Z {9H|}԰Oe'OxP s܀zve4gT.LaI*Z]nKVSAQ[Ł{8穸n]Uk< kcq3j{f4øO_}`PEBN/RS.#"k͏lx\eo?+|/q@W[^/CIn{ny>_srPvOtmp)&H-'/lDDp{4ifm{G/+pFYG}2 zL1t&{A?p+lXFhj;jK`vr\W/45]"7H!/5Ćֺ v!5;hjgj6s:Z؞b.~͊L>f*d,?CFt;,I.M.6 1v?R҈R^f cKtKp+Ŀ:DRE3a%qa]_!=)X\,E+6(o9 9Ts}쒜!ir.6LJ d.(^$#pGtPp$&;9MX6սN#~"l$UgxRgjVLXâuPZİh]Vtǂ@?o]x1 8%0"Cgbv+k⬿`g3Nbқ;acQw'n C>}ifCT?eSn?uoc``W/^5*Ρr4#-xDCB\XaoXsuWv*jt+i^Mh,Rž1^Cm}@dz ")uJ,wF@;rLuf0AFJn䂏+3g7٩Je=hĄ Zmwe67Tn}]h2ݏSϢ XJ?8:=xDDKF+6ӛ!֗d IEMzʗӭgN1s$ CµMuׂ*>hESm0‡}vu4SZơ-̗rs8ڬRrL&+k>q%E f#҆NFk67U`Ei+zmT+ߘA.H{:,噱Kʸ][b6[U/X[쩨?cq VT]ʔ5 +MB~5D }qlOpf@J%r7ؤ8aYB\(A`8(RAHYT) 婍H6;ΞYeITtIL N4t Z0L{H[y5eS01wE|rzQ%Aҝ4]L6vt L"BЅ-PGcڸ *Ǎyr#Ch}<K̲1~v,I&R>Ɩ1X K^?j̄dY'yX/\% #Uς$/,6{V&4o|WXJPE.*g@6I\nu{a(|3lI `J}@&z>U}f$9VTPe!t"-"}(6*Ɓn^4JYK78b!4L<uw76&E],пO&A2E.D2m^RUZ)Z')lǕj+Fz>DHFZV0E#oGaJҧY3wx/2:1Vf(X6> sVqto`#I|5Rp = ue+gśj"|~%lDKxlkݓfvc܎S9-cASVĞzWk*ߏZƮFpHz{R7KD |µ5c%F:5h|U[?0τZ 7i36KKb%Z2%Y^rz6ϱ{sލn ? 1p ͲF7paZ$$046VI^NMy2IiK~Qr[>EXYHZIQG{0y0Y sQD Z)ge,?x+ G~hٿ3O VŞ_g O!e[$3zן#w&ZoţZh|Sホ4@xYyhy+p{_V#ݣN2Rԗ{۟NPo55oe ֐0guwTw$r1b{% =\kFpFt mk>E@[l]P4iw4U~L۽ڳQX/ XH݅0Lkum;z`($@"z=2S-Q!sGn2SHjXǛg׆%:c!n9&fNFuMr(ZV<*T{9n}I?tŢe/׈K0`UMC#\I؃2Cz5 ݒ! A!O> L3]nL-pXjJ{j8%U= 5:Y3:q[$tX]uf2*i!Q1o[GHXjNThFDu3}@wH~KGT !RzpQ&볎Dzg·kT !Ij;١Y? EA(VvFFX64bg*vV[V,v31!ҙ܂0dԶQ:ݭ -.5h+J쁮JI ;f! v;n!5~樟eG%B5,2Q K- ԟ}`b]#i. ~,^OD-yMx>필VwmKYuora*m%/gxQy(b$DGX+ ^ u~PX%&n횱w0{Ky^+ owu|M&JCBguz\Q:{JλJ1ή.~WH1ƼCğU̿4;WiD"ea.qsr'B9pDQЌJ]Y53bB9.S 8lMW4 4nC.v  -M_FkdQ}4-RQ#W|>y``\|YFo +}Kg[$'SAd OWy 쒗WO)TL|!ͫ 7_VZH_;5|\ Ԭ#` \x;tDt7ͨ]uZϯ֑:/JO]+ ;>WRi]V*WD%FSs+bY;5W/a|n+װ6@צ;hÛ)U4T܇8I%m|e&G0RE + ]@ϭڞ HBٻ'݅+Ku Aȝ-!_ sm8:ylpzXt3LP}ZJ֤JPO jIKBbK؁lh+JfL5-c*bQ,Nٌ1~^LX4UqQ:FL{GD}QB6`]t(>!Ό nh9p /MP'4~ 3NPGm6V|[= qֈˌ)f33RHm^gݗ/~J+U[ =p( QMyB;5>& #iW'h%+ݞk;~ՈnHqėVXfQحv. Cڣᠲ- =ƛ_gq Ǥ))>ػ>H݌S(ѱCozM /$_R(tz>@~8}}(EP3 ;6{$ZD JOM)p9UO˛qa`G(/0a0la}lft-~+5*GkBT4fhIRWXFmoG@bpo>F7z2rbݚJ^[s·~K&pf0uPG MA_ )##uJ?AИ'R>|=5忟sԦr.*-^KjiM*85bBiGv~#+xS5ZKW2o@,8lΘ[8W:ɱLj(o2n .[V¶ۚ(x]`+J^J mLE4 z:}˅ߪ JbQ} 8XneiAjzͶ-Z僺, v^|ze<GhO|#Z{ 0Uikט<' bOJb_90*EХ+BDx6{oz>"FvI[Pd7 '"͵Ad4 L}36)V[ TC[g9/Ҭ%no_w^NAU6>bT{#?x%Xke Mq: dgE? xnjunn:όrtixz / F.j.s,'y1Y1IϠѦu/ifE>xVʟ}nkYYHQp-&,qr=QNUoQB}B>RUL kHLtܻ>Q5B uq_<=dik i AktNry*ȻUFV^6^mqD2 cdoR b8~}8b"S^o&7zvKdFԝ?_bi"*e*; Dd؅_W5Si(ͲX? 6Rp |R0f1)-/C<djiFN~ҋqH咬w-ݩ@Ul6M"_phG6&[̷Vh+z-eB4g4`H0Yro+*.O1z.S#Q /t:A苬x 4x(1z Y`難ER}DȰ'0"1U!$n@%qu7gJk'6#ɷqGX)B#N.̏- sxAVEEKgQ0}^h[~PTE VumbبlVj>G/#jQԂ}5 $&q>!⛋tŻBŠw(c4GkJヲ TbdPMN"Ώ :"\BY Q0zWoE&w?5l֌ Y^H|k ,)u2Ÿj.Mb^a'FnP; V%0 8R߇_ԏݺ1* :i64BOvzgOzOK'A ( / cW;oKtM%s?uT ?).8*x.[WCTL{'nC)ϼoeH4Ԧ+8@_W]PԚDRv4A\HhH3_t$ Byc`yڔ~ZCcIHuIuO';Ak^ghզ`#Z=cD9Z1Xd=5=Vj;:ȒOL:نj뜇g_682)G!K֗G +v &kC8/ښw~otα)LmШ6~Yx_ i?=0,$F'^wV/f|c{H2_{y7fҝ\Z2(.Re+ ZoYsl|x2dgU\%J. `SXL`d&5x&֖"zOmHTgWj&\gƹvמЦpz?6~W_㶄C6aCXڎ S9=Df{SXSZwn^4Tf;X8hJo4wx48o2Fxq}/KV[,6Oh¦m\7^toί/L(9箮JA+"OыUUƍt*l\ngPrq:)n _o]!=L}g"OU䤍u㨔0'$oPrQ ~WO߹𿃤m2N.Kuؤ9 [EH|tn,0'5|'l3?u1ā##sNGݮ W8%\]fҀ k@nN΋[4z  8?1#]-"Y"cOm곉U*b(MU3_y^^ΉL!HydZ EFwieR-@9|;$9l-ںb']'yc9M(D4y-=ޤ}gnWhkU+_2/{hK/qvE>s)Ȳ,`\A fLL}"L聰7^&obW0@F_N y;4l pAޕH$u~miߐx\{K+0JzDNxR0b F'33QxldK>><QXnu~h>s0A.ZjD$קMzQo-E Uo]&;' LrQ!.vS*heX"P'x0D'@Jt)d\/ -1Tco:)dY`)1@ Z&lFLȧq&zsm@2-cu J͂jj+wD蔥|&@*eA2VKhջ0֛2SCCZ+YWs+BhqOQO&UN0ERRaPJ(Hֈ&?|YxFe`Fi\7v c <3rK7"Y}f ^كX|t삈p8V]|.gtUԄLNZ̥8w\o탪THzb=DyL5rZ :$UyTW S؛ߢHy`!eD4U|ͮ '[`A @̺*kl 7RV9/+rݛ.ī X^˘VIG7;/j3=*_U V Y;y B5ucN=xc;[չҐE^șhy,1D^9 ԟO(k4-}{lo0x7\uLetHb]&M_-/)ժd>)$ 4umD -hv H=V?!`;?hEj;bU-^ u,$u{%.d%s]*4J5qm/8[GC41ZiT@6cDs<=f__HIΰ T =b$h#m /NʇE!_5 h۬J+/Ѫ5Y^OzA{2hRwWҙ5Lx %\劚^p)Flɦ?|,.s͟ΐ:Wj ̤!xLo1u}@C 5>W4CHP/ 7.H蝯OZŻݐ% 4h)/qhl]X)?\ 948l^sM)v;1*}sLq +]a#yK"_@F_J,7Z't 3jƺ(MU7hI{%JGI/؃XUz~a&CFbMS(ܱ 3P3O90u Ӯ?gPT2Ia'gooL-y۽]g4L_ua<a!{a{|v݉#4FKfs)B#5ۊC&M3DuwȧTU!:q{zMګ}e,+sU뿮B81 )D@'8zE`U2,<\H(!l.L`D[ PZK㾿Q` CRc1iAt-*mZFJV&?wrT;\P|_d}G7%i\I]* Q|Ѭ N <^eݸP5"2.|_vIz>fbP)K?1Nȝjj=tS@\y@ *^;m2)EgC!A3$fXbM ,2ogGu3Ĵ1sfk BK84$ x3ScuΥD Cl@:ag;[xXUE@ C}C۠'H,VUꣁwbb;ƖA#ͤC+. Y *E ܸ/[5%SveVye| J~`ʫҰvDLn_;KϓUJYʋܐJ9TRc?~] ~  Gy3ÿ&YzwjAgĹ#ܶ#$_;!eGw)(,%fU3 |s[e'Ñam|չB Lc)8=QK=?Q -cd(Q҃x74d;89[!I@](洒5 T/b{{/Tm6.SΪ[K'fV7:$m*y^Z.}YT:\v~Iâ/oыۑ0hz4K83tx5y2VVQ!j {NoVaj"zY)d;BiR'$v=XA˸!_*oei 2v"4BRƴ6z G #> /Y(M3,o(wuя # aS{yvA[ITUa5 $D]]a҂[;$ayg|e S)vڦ/jlbHe!$mCrPΌc1\bXP&J*җe9{Ǥ;DJΆ=uC"Z.,/r UleBc͜2g#<3oSXD ~RDRێ{P%8a=E8e`=~Be8$ H z=?7t,x vjT;11' dyQF[ )u[:"#&%\{^jkR^gղ@D,fJHbHN,:]~ŕ6xeW0s7+N1p*n`d2lpa=JXYUG:&xŃ546yõiZ6(]ǣ CQa:.o:մ}UoTQ|GI2;^dg-"S|JΑ69G4i>qGW0\Ea"LpT}p˭!IJh&Ƙ^itI$A9VĢL;Civ8@(r 7ǕpoU<Ȇs,2Ŷi*E~)GLGR#e'.'o8u  ?9dIFs#4{2.;;~MwlӡFbn)MkK-jn(oÐ;<0inKg5t_ }N3uNĶ*JuaA(hd:xK)t sj[2|:qB2ш\W^1Wj(|1ff.xeB#֐:@>#!4є iIroh*'ON ᪇Le9?9(0bF-8]T?iՆRj;Su[rpN6)}5>I7)ģ "@>ϣ r+T&v!a;64VH;lO6ܙ:9 ǷݫbJĸzώ9 ;"(h]4:;"VcX*Q7 RtIm_k᳢4T8A,jNj$+W&멱}˙f]*E]TK 5uNC]r|=vTC;Bۡ?°|SyUd1Kx-(ֻĠ3ο䚵Ds>N0KVRݩFksQC g5E 6b4z҂FMx{y?4~!aHϫcpg#=?!P}b RTV0aśmrYYn\ffOO3oz 1&btDcrC4aA91jNm) 0YĿ`/p;D vr΀k)QOWWuh{iԃZTT DA`53A&) ?J{kO JlDo}#6G%k4ͤ? 8.af٠~oGɻ3 Ǖşl- %p_< l'e,z\ʫoq>D>EBW Q14)L_[J x!Fe@(yByݸ$F+x[s~VPBX. ɥ[ ŹbŹ,gg\QHf QTHOPۢ5ms}*;MR+$ d?ԉ/gv%|0L\Mc/9"-F z yY~يP_YftNo{˒e^.>c bPad U7ި3rz2f;T b3% %:y vнu0hݠ?YIWhs|//"퇹v>Fol5KVqse!|)PAB-9H!WɻMɉ߇4MIng ~lyf|.5`֥.KCxAM@hma- ?ѝLG'0!U8ئ 1}+c*` ȶArq@gH,waztX O)4RQr\~!κstRtZ?[w'g#p}j$c&@"mty.>~ʏL( ')Ѓ܀S?vawqـLc30'drҁ :INiߕw%,}^xj}Ooƹ&Wѻ%?q&DS1{Y7Ui3GIV}GWyG2X@`UD> aLEuڂ>O_1ߚ2'do[x: L6P̝D0A~S7ye%!WFVQUri6cKf2p0:Ikz%^[[]2{m 0 t-K)MY^By8켖{RMɨ+'"w8)QV-\ 23ݑyyQr/KmFo%uLx^'~|LΕM5)Qd؄4lN֙p C;>Z44/pz5n?VEYPqbƂdBmq4ߙ d[&qOZ]11yO_Y5;`2 p锝 S!Zw{лwc5@]0ިr@#E0汻4Ur/'R/ GpֲeZF/ 7#B7n ʾj>w^5}G," IwhHlyt5+uMf7B;ELY枯N(=\u0i4ML9fcor,q(%f\rTmhJsi{D0h/{N/>Ú@; k01Suz/^nh2BXňkcNmҐZgYՒWn@ N0&㹁d@0Xe:ppɵ TA䟔¢`Bdw‹~=d<x㹉E}EEjWȰq$Xc~Yg?c^D U:l ;huw A=:VC<62d0|8J!NZqx ueӃ꿑׳d|cSI_OF/oQʺW'؈!@,w]FNY/arzr.SA٠4XEwJtN *?40_>3|ddDm5V.[c[8+cꀷ˟wυ{Fy`3D(jm=)Dtn]J]!-D)f6aJ#T*Z `Y})bMfn w} u;]dmB޳L99ֻD'2 ["FkBH89Yѫ ŗ|d@KP,) =Q/PTt6J\3]Zb̷Y5WȢ Q'37닰Ɵ7F/vK"$ր͹Fcu\\SB ^W"m ꕻxRź Aezl׆F< 5t 'AX~>оSGۘUQ.X7I8'8b AYllwPt*r# &(ADKR< GH,#oը,DزތaɟwfM#~$ z$a_CeW;SC;fg_nJOEbUm#l$Q` v#O͵_VvB ,)eBIҢGgqWӌAa#aES.: `3hפӉ1C*"02{VVpuejn6x!J9Cw;B`ٜ>_;L~RTYa6a{Kv gf!]Kn7MPΩgETGɭFŊ_㞌P`p S@Fh!O(UawrVD&譌w4Ȯ;fz䨇iB#Zޑk21nyڐf0xԒO "azmqqAobMV%&νf1 %;wB=n/bTʿR}/Vs˞ZRFUpX,Ij:IO! \ +" ׅB1X7@i{tAB!q:RYP'4]]77/DXX <,>unC}/]]= "x1}&꾕~o_!~Nî<ݕͅZ0$j?s(Y!9ET$Cc2 C A|Nqa*QȞ]35 Xv*AoqCE>˜0w0K Muǥ_\SEt LR,eQ/~/*>R>&+-:ka2NnŴo@yjNѭfZj'FdgMU/[  k BMavM剈fP ۶;nHlL.V;÷N-/-I*W~# ;,gy(1+ &F"s -tnh,^Z]L>@"W8 t(!buq/wv_P}|Fz;Ge,Gce@JLxgm%]yxU@*$Cj;6}/Uvf͖}_԰)Yb؏l \W{MRY@=2E!*YAF޳ty Wj]ڪwjPV/b'"I&el8z]B7ك6HR%w^WWD:֦܃0YfSR8 Hl#t#lN;?+mDG. ꍃ;SYA @Fu/Ж@x'tçi*@`ԘhբÕt]M_܉s4cjpT0QbԧSsNB+kdziݬNrQ-)rR!=`u$i8KC1Ѣ>3^"ةKc0 Hzܷ+)q_~rS\1T!Z֮~D`PzD.qMHˆocϖ8*м?r|m矵{'ta(%/~ ;q{5K3ŒW%f "I5\oSf @V xnPMk G”QWJ :V/O{z!tD0 e0ޕKaHNh$sRWW=;39^U` AH{ ᓯ0%>|֮ wܽq`ءXtѫ{ -UQ{-L:`N;uډR|L6;=͋|L!3|x~Nl8ke>p %߽#%b3`9(Q0u2Z^cpO\Q*Q?פet&츕ڦy*z="(7iTma CxZ]}ȷ|H}jv;wk^X$Wd eZ:`M LO'cxʍQ'ôkJ &/tQ*œ!١Z۶|mbf:1!m۶VX3$cPW V 0gb_%x5h5%m|E>*#|?jF]bxӭ4C-qoh}2]䇱5G6s(&tM9bk~ SRj.&{úЦ6FK_[eAᛂ^G}2챛4IΈh¹6{1$@KAotBwuD UKY}>^E'D*w異 /=T-krΧ^rNLrP΢OY#ۘ]fN^ZhϡFgȢgto/Yxt8TBә %ML 3 '#ϥb +S9(th8h0jKae˹b\ƼyBP@k[uLry.@+|M Qb q85)`!کh Ev\k<7SEHC9b-1y;JLM nOšP=yntީ'qA9! #XKߛ^{Q0ôqJl*_sHY=bBp߈g"_$fjF+g#P׼ TZQzi}4bh.oȮ:MB@ ńe*p5k+SI$P@;\b@鬧Ew#͘P~NtDsZ 29cJ{-6% .<$kJ6|a(v8̷kellЅ{d7ؿz,*=3M zOVa_P#iFu*AB]8s%Zq&ȧV{Q]Vp>h#_<;7^ޝ9W3[ /َG:ta+!@;Y/4>%(ҹ(u\%Ti jKЧOb\<= z:֪lv#Z[K `]{Cze)S$策hJy;<@l183R>)؊8ût=4<+@Ș[N.85aO32ҍx#5TT(Qh݁R4]ARi0)vL袈-p w4Yk 9IiC2aF@kVEȰ2Fh38nљ6N_qC'1rMv)736Bȏ۰EYX$ Dy-[ G1Jg6B,-YC2Fv& lFm AI[8mzvkVV f7" f(Hw2GA2ߩi?ِ!,{R=k#ǐ@d7 ah%bDv[$\AVpNñ:cH+m q٫ >7!W hu)s .,s>=3*.Wb% #[B1'$|eEZ"o"YPJCMP[] ,1޹]黏n+i@KQ^Iϐ_u@.ߏninV=(ZX]i0bblA<#W~sє7P,vq  b_|W4Wua/^g ?^FOi3Sφh@F$EZzɀyPUUH_ɳ'Lȋ0eDdz;-,cOヽ9Gyx:lf-"\:)򡻄K@^-_¸nEa7i˒ʋaڂEu0;%D/H8 omK7g2PdQt&șLB[mbe %A/?黕iUnz |e_ceپĢ7c4X68s븉Ɋj J,Y<!9Hrv,ڵ G6vhQTo:[p0ℍU#BxzCZj;j+u}_Wu h5dӂX}Q6 F? JwʹMgިop6֦#ɩ3SGWXjP~VNe|N%I4r^}hɡU i79=EΠhQ6=o"ܱ3*$bM-r2RrkēEڟV̟6b+92R;p:3ʉwB7`GmK=P)i-&ym24|^gcO UfR2ZHcR;1yn ˠ>TaIIrv{ng)AUf\&~"g Oaמ~dIE}xNd7)ߡk Xkyڇ޶k9nNfwr^V,3e3b:k " 1'e$ii,xSRŭפp _?m..T!٢9y"kXLCH<ݨ 4d%2UziPH(xrXvbŢ=HCÍ-=q2!A BD9:\yDzZV`DAR;>8zYnEzo&lm2In&-1=ofx n˚5N)3fhKyMbm8OmNlۿ.v{@  4EKM?= \Zw w-/Kach%zfDgĠhU9&Oք(E#^p$r,&FW75~ G Lö%]}~R ?$ r&be7(\o$ݟϛX;om9OE]E͊>8:?_ïiT#srYSѪm,"JLxgjr !صi$(`{y9Cl :]EZtW`>TQ+SAݨs߱ge3ɩw0Xd۝+A#}}z)M.1CvyPꀸ:ֻמ}i~*W~p3or( y#<;vvm)Xүr*kព=q}0enJwİZ¦bpYN qtݜJ{O'ɇA[x͕RPŨ" [SdK.ҳ qb܅9Lhrm@:$B;A ȑ㉥1HBoh9sa .r)6{(ĉBͿArX+=v 7eǃLBE랠̿~D ?rh!X&l 7mL,ζm!- y H p<) `e`P2juӭ)rnQA8-C%d2d0SY ޓ#/]N\B |ye_ۼ,1ٌ].ϱ 97SNδ_TWlh޻Pm7,-)'HpZ#f8ױџHlqhXY$T՞(Htio?s-r)݌iwFN37?۞2~CY8; 8ZTA4R~腫+KDwJ%+}N5㖌7%Ee֟8y$^5 \Fw|4nfH}G|K55"F̮V'D)|RbQO|ꌼ:g(T8g4CT&:zD<ћ =^yܮKJ-6rIaJxk(U}C^:#>N>{Z83Fisa瀾ހ{jrK N [̢ :tGUN ;9&i1ʸ,Ie(/9@ɐ?JfӀ#fPIOo1 D6U0. 9a*l]h ;Wb绑uIYψNAkps#sekق@5:9,j5TsLRITP2/Pu%̔BF(#@(j4X 3z7HoaD~ >4_u){'tN_)%ݛ!K'18`7ArozPl{ 33]Jk ќ xO я(I+Gwj+ Q[3q|$`yh(_ ;D@E$pN Y>q_),\U)op@#Ru;M󔭇pVj]svj6#sqֳT8 j'~1b4ESyL-H3/ЅʹjrUk~YfdT-0_"+Cv\x`?c|J- 0AWb2%mOj-2DTk }ı~d쾪+|ύڱ9 \/zWaB]; x(g tsRLp#V[8<)kGƚPo*FQ_L=q-Ϛl;YV8UC#v#*,oE /MS(qH;@#~e]OTprMaJrER}ͼ,WѧKX P@ xO18J)n˪.,|yU 0Qz^?r#u$?Lrg⴪84H*W6e*b:~ =g Hӭ yκlf:3A`1\M '4O9=O8)ƴSߩDJקp;w4 >9v#>WZo.2 C)ᨋ=Є]m_RÈklwYVQzLqΙ9sD.ugm!\=zҎm6"ⷾI*A_rqKSzxшMտ:p]:|8K Îk8ʾS6) A$4f !J7:2rv.)+ha7ѹ1iՁؚn\ F8%x؈ 3A9lr,r cDpܑ=O4Yfdʹư?W.@[qQ)τlPʇ~%nJ*%P0Lo TjaE>pX]ͫ^y]Vb0;J2ώc!{`+8 36M-=`,$DAՠ5]3*2! KG9+L5HͬɲD9C=-p.7V7<ź%ӡhsE|RWՌуn]SMjDƓ5GNq\Xb F{8@F=Oe^4kaYr‘<&]/O@2Qu/iJRGm0w{zedr nْ#=Q܃B rDG-~&Cde$Ȓ27Ssc  wSs(f LYNhaTlN~K# ;4!Ga&nA*jKC-+O5Cf\i5aVև?7{(#&SZXOo?(c.Vn[M#<`yztZV1j?O}牌Lt! {y064J`C[NˇBt38dm]d#LjVdI5}?v11Їu`kXAqSc@K_y13:t,=:@wNUury$+wvp17 /=U0} 7'\({d#ê\,#@(ȠNhNt*u {vHq6YWh _}yL_:V0Srji/yLM&w Tn1xOR>g6w[7ϣWkGS~.KQDC󞑒 ]\+6d^LH_FV.x${.9e+*=Ӭ.;|qL$B 'vrf X',8+XdθK;{6c+*Mj3O(-ԥivDgQ-"e;ֲ+> j6Ӗ MXlT6p|6u|A>\zxfnU9L"ݚ`hsȓ}Wyw; n}e#Z,23$gӝ7EFP)?X%ʻE!i@̳Z7c'+3Nt˝x)-7bWK5dzMqjNrKynȪ #sc6SH{;~V򛪇2rNe߆'đgKUܛy֒L681 HW4i6H"kiɒu>(YޗkJ%/^[r;[nӭk뒩݈_?ۆB^%(BLԖ~+e*Z+!ۿů[)~ iP<^&Y3IanUTJQ}xT@n@k:2wR5m^uH %i?6=3g1Gb%ދ!s {SϷR֨RDp#sD.~Xο~8l/=X'HיuGVZP*Ly8=PHICn@qr?e1*w/ ;KIGO0쉱0YVzMwgfLˊazDmkCk&&QsEMo;tzق?Δ`辈ܖySEU*~a90:ƹ73U8NFD^&d~~e.7pD!uw"weqqV _<__{Iieџ+MþB# wsxbo I rfdOͼP/ g)r9)MY_uV<2Bϰ+F  @5ld 2=e:_* g'n`f*#R@,췅/h$iRq@PGth2kݗ*PZ,ܢC ԧUEd66YԚGa]苊8i\TNOsΞ1 a$e iᜱmZv͊s=$3=eFnRABp.qAd&"*+4dBjxAs ޏ)QBpRL|Y4t3D:ǧz[#19? ef¦˭aZS^9j_5HpQ< *  Xņ\';4ߊϛd%Di?G+̻ŴVo>Xu8 )T땻cyu8e_1_Y^_m2RZ"#&1; } .4{8/ٰq5^(ZN7|e1){e]L=<zQyZϮBMHُ]০Tǀ.! M-bq?EdAcY'\5qA\* p06J{њdг1 %K~FOE€wWk]Y$=~L^J?qkO=tDu6 o tqD]M>̪oW u}娗 ǜJc#Ŭ©y/F9UI |r#|A2NO.8 ]^% ͨ[MR6X{-^קz.a)(J1l%CƑ # {HY;ɓ+-!=0Υ4$͖[ُ1E=d8:2oSd/B**ꀭńp_I%4Ԕ mM|w?<7C.q Sٸm?x0IGݫf&RbXU[v+<,%7%g|$Ęb[%aW߬`}TW|Ɩ]SsYa W4.iXSWWdC(Y1`R+ͬڰ#P=8l_|7:s_qpy^KnB9wV91AJ4~I@o~Ix6)}#KM>s[d__ʒiW^ze9n jl ~VKc2\K8ָfVO -&:jCK⶜kx| 7ۯaă@#y]Bgoҿ%E-G'K5A`Z ,իZ\1$aI\e[_FqITz|$^\ ;$yi PR{|B#U(7U6S=Ea"|jˣ\喜p!j %Mx8¬B*p 3?mr0yey.+)ۯC=4eUc@+pkVyx%Oz-W^%=A By oLJK${^׾Gr#8tr??&=KpWZ1Em$RO7V6W Gd} P-yF-jV?_ܘA]=#)`p+8mv˂JD'oI3C?2=PmVtFRBjf|A6~`QCRebXpR,l]OT8Gӝ'˙&dh8RdYZ\@t}-%Ʌ6DʹYJHb1h.yc?9 oik15X'CZ[?(mZ?pl$<7P>ox# ==aTpEi0 ኄ4(? Ftw!V,-G!✻g=E[~d^NaNxq:T&hrm)ܞ}@EI$=p:daIYx;^ zeE~(TtY&g7Jhȷhf-o؅TB5{ͪzW]ԕU Ҥ;)5sUuըtᇷs1Գ,RM6g}oP͍Q XēùR-i E8`Xfg/QfJg #T?k@d0ItQ$w,{99^Zg漏 TTKD GΎOaWhi,-̕%޼%~4@? tFX" | =z5z:U޾z=. u:f]DEfΛZUqQz:R !3<@JZ͏<=0H(IlfQ 42?yHp\"\$alXW?XW[< ER08 F-{bh], Go263^7eQc w!0A4 aylw 0dw vV.ckUjyk;30Awt|8/=6dSfEMÙg³0NzaI2G T:CѩASjQx1Nak^I(, EqSJu#ܽ0-SR?a .\a4$5rPc7) 27 xju.OORCrßI> jOk,tZU}Xax8*lUxF>A%^6!|}ߵ.{mu=NIV߅AK֔0?IMJ ڻmK$S< !=\NS6|z]?L:l,JI2G}*r|quwut5H/dj(?SL !C DZ"r;fsU)G ßEϚ_D}ҀJPE vZ`deZ+ٗ>5ˣ/\>h3ނ_T\u|ζ"}e6QgFo7 E i_zmrm%W|T`e;2j_P.:`eY}-pȷi+~aEے/+338M Ԝwa<"QS:-NlKh Ԑ3q&ܯ\cIl8CCdah|aHZm6I|yZ1NN{"NÝ_*:)hR5& }ޮ`:'-p)Svg=8h߯:uACkE1'"| I#]B;IۛW511lGuY-SLE0+yyٰw"- * +I.;ldRQ%cpUvP& w zF*<jBB?ۥ8dOY4?Ôp4/ߋb7348{GndS4],lc i6nsCM,' `$;\`6ìW?+y'20m2}:{r6؇yJ] DtD,zp?MB={ 蓑bH [f P<ǀKU'_ y;2*fҗ/V%͔5 qM\@8/j;6B&F{Kت b}HIVD~KO+@g o)IbVR)ua\/J/Qb#Po |Η<{ȳ+֢W=IقPK5Ȗ$*NHY+>%+6`O cӋ#hyAP zksm=L\ 3Z0 KN>|e\b=2-*Tg&qS3=~a# gaCă°LӹRzFy*SAQEL)v|!_a6"9+̟Wv?#;@(dxV8dK[[QhG%TO^ l` 4i ]QU&%pĹ_T+Szקt~oFo} N x>DT9z+;J&lO£GrY]̗}"+,ve7M@ߣuW<;L>UKp6h .dpuRH'CDiVicwg.[P-IiPlD'#mڃ$1ƸuqoZ(M/sio .%[Ґypz1贊d@]ߨe)Q*Y1G;D|6~xf\8W-g9p2VPb'S9ܭX*͆ .\cJ& ",a<٧l{sAO`8ݽ:L s%UΌLkUd7$z2RءPl7 p ze/J|0#rMZ^{O|KW28AןHwc˹:= hO1"M췺Pg]('.5yb!IS&kE 2A:mܣǝ)Mb9Rϑ1Ym]Txj[̻d*4i{.!.z7nIF,lA3yx4~۩gF="m]аQr[=h[zTv le)%OO$ !y*odw?p? S]9L]z,)aL<* Y*il8{T/M2#{gvwI80.9p\kZ L.5;nBa #OIC@51Z6SbJ2o>cl`k%T*@jkjǧU":'Ov]3qdXp2$] .ΖDwIl-2~8E~ibʍu8g7SF fR(5F~$yDGJ:Q%?J;, Bqk =b@+N^j gK!eFuKw]Q@x#{c?eHZr~rBvQH{w#W~@6KB@ D\6eVRL R YsQ*؉BL^[|Ng+Q.Z{S:>kkB Ǭ 9fڷ|P3p,14m'18R~ mEbKO ؑP@6xTԫ]9Lt)vm fw:6۵3j?k4qNBr*23 !Rѭ.G )"xY2#@扼R6+>$`ߝۓXyq;! #Qű<& FRRYxȯ v#e:9zL`"G8zoa&x<-7]Ђ)҄9`KmۂF}6m|" n'mc܆(٤fz^2QfԿYNkn}r(ʉ"*sv >e#jh*n(LLAYRCd"1!K=j3(hN`x ì4"yY)[F%14Ysvð AӪnn]ḭQ -d(tUI^vl [Lam-qo\!B(7aڣOE5-JeۛnrZrmTQ={ wV `IC9!h |9"C2(hflWJ?F"敧\/ ekUU:Gޖ.- )`b[ATP347z4o"}$r`1nS{wobY_N<bY Xb#c/EHƼ$/YtַvW? >ncJZۇLqBNlA$Q<<^ HLɈ+,ppB<[ʬ&rْ~oɺ 0zZP9ڮL9?B:xX7IJrܘaRFH*WnnT@)}:,yQьLM.`KqeIZ.VoR9jkOD#c:GdÑa[sTbƱyj{oV?icN9>Qaǥ>҅f!r dxSըM5RyuMnO?%[ q3TI*|> "x,9V#HԢ3Ő A&>`>袘@ZXO|)Z(K3 8餣@REƉ|_.Ade) oQ߆Hi7(؂o4)[9LRF%FA߿#n y5OE^6 11^[s/NXwm7 ,>0nIFc߉6KAUSxhHu_0.rsv]N'xv@rE;F+!{&N_c1R-0~,}39kJAhQ= g]@^@Y& |ĸ U M"ZqI=?oxcV2hkfIaIr8Ymgy}O6?8tfPM ^|js\SiKu!iZ[Hp &7Tbb5üT[;N5x&s#G =vf1Nܼp6ʧc'1sf7`FKaZVhz]cwZ^ ΍{wzWdcSu?ja<zMcRG,$zۈ?e-M0Y=*'J ?a_WIszb5e9uno7gPO|>.TSg|acp8͟*?6Z( k ) l!*}4fOlj~։Z!~Kk{2ťF)֡Bj8,3>r{$;3L[/Ma1b)k{Bn9lN`st[|Wl4إSB5tHH?q*z6t^ Rcolou\,Bќ eRd"yV1V2wp3ɧheybR"x$+RT޺_c)AJ :ݚ9β4ub>i.ĩi*w;d-fVTXrMNzuD ua m,`Sd.SsgCcֹ^" >Y6+k񻖋1}{;Vɺw1ZF5[H!X x*![1^)_h6 ΍aIFHىɧ$U6H yΝͥ9*I1 wl8YMR'@XSD ی#.:SJFɿLAjKcɣqRG_Ag)_ëj{)C$Si{kÛw|cח薭ѯgr:C%QGp5o# :4ĨS/B~(Cp%JA(r}5[:/? ZL1T b-4#s턋Θd٪2#|]ӥD@#GİJV@F*SU|O- wwxCsO! *{.|/)Ce`ɢ,{~#6qvQ@X1&%&wGm2TDWjMv<@?Y\ɻ xaˀ alR@3QI4O3YjMc(aUѺпQm2uJ q%HPD>*iдb *obKvw\ #P OG D!Bnk~)_4-$Y$:.N97u9K]nA>la'^cO]O$+b{T3{^ұYMZ ǸRoWgi/{Plx#~ JjcZL$n2 IvQ=p IwܵVڍ "9@mۃ6inCl]dٻJ 0[Ed- =FˑXg*MߊpJ\$gBf@'ti4k+au}@mEpzgN3h[&NZєFgnÒdjRXkevhKm8$50Z&5"..aD[ί:FTg_&]ƴ͵d<*&irbGEoQ%A9jj:ɼWK~ʮuf{Nϲ9kʶmRnicnħjP!qZ?^KͲsbA&9Gm~Vr{iJhtf]J̡D]-d /KPuY1]{)C[hIWlө5DXWЙuM$JIBQb3RӃ2:o@xNcxGK,{UC턻ɕiDw6'ɴhx`dcu&L0܍9[C5hEvv+"V6dk^]~0>jkn$Ljs"nAvk:^:Zʑ<m&3Ge~ے| %C3*zx'[alڀ*֋mZAQ w T2%Inm"?WFIשӼEkMEʈBW3TP⦧hUaa=QJ #K%Rќam5Rg1:niPXrل 6 \ .D<XV$8Ͳ>SJPwuѲlq'vGY6"EiL"5@0t3!CP?cK~^Y}tO~Zߏ׽ڗhN7dW*vd&\gY&hf=;C4.54k&k*Vvy1/K ^K~l/3<vgΖ}RCJa@UrH"qBK(ND.md={YkӄCWsx bwj̧W{(/'EFbA $]xM VYY!G;a}{VXퟞ"%fEN8jKz:/RhZ@" I]i"}!r2@Dh~x>z{Ut{I5pmӧn9ɴ>թe(ds JZ6RY.OBlÔs~.Ֆ-u}ʇu-'5K zBy}P[ VK_v_>8F=mZH% cyk)Y sOmf~ q>ߺ^{4IAfhKԉ57kuR$RwpFP?&ru%nnڳr/]U ㋈} R?[Ė 4gLD;+$G"n٣eh.XQ񉺫ۦsj:F ;pdWG,[{3xb c3=l=)[+i8bm= hԌJ=jÕrA.kp녳&ewqon;" MӋoOFǙ|[?\ZluX T-`}y9m@YʛBA&3Sg?Cha8@&2%eɨ *Y[\\ DV"Ȟ˝#%\VA=竚Π,u}sN-V3{n'/5gֱn=t#.^+Ng[@ wջkL*`Ob5+y27ޝ{UhJ?W8 j^b<21#a6ؠ]IKu i!3Sl ɛ[NJO`Dip+D 'xvJzԈن^l33>Zgחh3{K䂍F!#.tSa>arAONZZ|_yīcs]iO?Ԅd[y!&b SmAvE$+Eخ.jF)_3NDO^sU[^o`0$U.,@ՃpUN>_)KG@6w:wTQHC;0}:t$#SqG2 6#މ|GsQǰߪ=RtQ/}X)CD`80.qb{sp*x[S^2t ~g!ݡ]b[J|PW:R)h*e6 &e6=۷ղ< *g VU+jk5@^ r%JoJsA0]2xCQHhs+e[8/>e蚓Ll#:\C] SF]\˵ R`*vYYtkjwGI)uxعJ$&kH73ǖq*93Gp;+O>VF$8_NARxGXfG>Dtm=Z&1Sht"颌/7$_dm#%JwIlR!ߧ"%+fkPHD#ϖK3-2gZ$p@ЭfCS\T\?{=IvG_sz}1 t6<BݼjnN<{S><%nE4qQu'*oC΃U ?8k9ЂwVƕEj;m zs',M]D( p%*Z}쟥|y.??Cqd9Ga "J1cl36c۳aoىU4 /C0#kv:|'*O7!#\] qmʛl@[J+)a Md\DI{ &=7?[ZV$k0mKП5al~`GZ!yyZ |mq>x?Wk8WKaxYxBЀor]Ř0&JaQ/#{2CJB>4%]<73K>QwL Hmp5}0Iv&xsAnTnqÊlYƜjQan8Q(-)zWCǨ[= Ώh4!V(njKRa5'䗫@*OhKc9Enm97֞.k:JuF˴/--<~sb,shѵ >1%޾fNAOw;8~_,7}ڟ!3`¢1zZJnL@f|Œjoꂥ*iu%JoٷE:~M9's5Ӳi1:]!,s#[:ܲ4LT݀ccnOoQ"X 5Rpr "C:+"<ێ:c$E|M n@lx-V]GN~%FED㟜0=]^l6,Ȫm*8Ꮗ۟/yh{RB.nc06%ZSvH[C2MD6ab&n-X{#:L>b.Rz#E|Ef!R*QZ[zzi8"kN^v$T.|" l> &@HK1Ͻ`&ER"T@|%yD6Ml_;C v,؄]5ɽ~tq:rB!o8(@Hn{ճ )XȇüuD3Im 4HC#ݶ( "7]D[Ji#($JSR&CȓE ;%>fĿMy7vKe9H^C]yDUc7p]L(ŵ9&NWtA'SRɨ;F{JG&h\V2Q-ŶX t;geؓdƿvܫL!yL:ޓχ3GP8\;h9<_q(J7MD# j_Oya; IGuS|}0yh-wQ)|dSH$EټUl? Ysm kUdZ޿nQ nV~Ƞ뒏*B^]ewucl>I<=zPjqA&{ilBea2h 6,oTKnMwjڍ_YṬkZ)˷pY Bc!E\xi[)x}@v;SyPCu؃6+U%Ѧ YPIG SD=-y55XU,ARvRnAP : F}u@u .ja,?ҭ)0Uq>SUC>Ĝ<Z`(%5`K9z2Tʣ1x_:R`ت_}6(LŨy JMBV.0f C;`* 8_Ȱډ,UΈP0ж܆c: M>PgjzgNXڙbr!fR*`E@WR",bH*7U[OF8e^|2~0蘸h F!obsS倳?0T:twX]ą8Uz^Vu[U7kWyIŷaz,obnu1z%B0BБW 2.vx7N0^Bmn$rx3g86Lc`P}T=PH5ٿ;=2}?'ցTGM_=%I lXJ Z=sVY8 +axQOqPeTxJ[S?-c!IߵFK J'~ Ve2`<> [N[CFʨPvr*7X< 2o$ ^c͔R*e8!Eb2 Qwp)C~U@ٯ0D*_ $ȨyG&cUŬfg쳞NstiEaѰ2#4ί&ctܐϴ׉hoCa'I#"W#qy4/gO)TH\k{XO vyuXݖ> 䳼O怵!mf%Z`Dx3>H2] 6އ3KcwX`Zo/HA A~:| s6PX<\}~4hA>Ig@j[D'F&SnEܷnzJ=zq {7ݻaX:,7|IZ2K2z( *2Hoa J1]xOfyOJH# vv,{ 63MfR#h: fvT&+g7n]COGN__֣- %'ȕ/)\2 =[t|@JH;a, UVB*A穙Cիt*6" ֿCf*.r%d{LQ۷S\ӧw%)iF:2M<̴׷s).dC7z)9~쁽&FLNJ $M"ˑDs9jXj$*lD?Y0H1'쿘<4k-:578r19'~_x53TD)9{(l i$挏⃾y~y>g#ΘwTN>=ԃJjno\qﲗCXr=l e=a?/Q lKǢ߸ Pt f_Nm|fK%I e 4iZX[ebKg'~! dqv"nD%"_#qʀ>i]TZs6uOvgԂVAs96$JFUA 1રV=h팫S(dzcNkul#1Ex)aAM2Jq‘+ ɩH-*>}+]!ykj\@CN(lrO ]DdYLeװf?Zv$ SCMLƯ= b^p͉C IF ^#9x UN0(] DOuH Uu~ɘ_PZv|~Λ E&R~pGk=yB2J+^;!X ?7 $r}a#;Cq`iׯViBēRZZ6f lC}@!^eGhmHEV2JQ>qQͼ@OToI}B[:cgn`4V1%fHtc~FĄ]"/jp!)K+!Z6N u&*,]z e`!Ap‡Tizڥ wCKI^xY't 0Q NLU* ]B+:ܞ^i3MEVx@V4uEUk#D)IKd_^'xHeFwȻiS>`sHoYI {Vjѫ&B׼xf%q`!u*d oll.BNRB"{eIϑyEȢr0A5'L Цm%ְdH\Ō(6KF.uB?jҭ3h>OQ&:(4n}/2b}~ߘA$_Zt`B8Ѭy] m4<~4c)lH)*L9D}% E=<74bQů'[[ @ZD$Y kCP " q _BΏ U`P;X*@#mYZANP%]u*Tȵ{1bI @?7iw`7Z5й.^8$$Sm8и߇hW*{{1ºcqgy)$IHNH3%$ [خb2&QIN'*%FX{Ԃq16h$|ـ17ru_3akC4 vG: n1PjQXvˠ\s:Ơ)4Nb Lg3^y89WJkG4b!";m`NT|;e<<}k m<$/,(nVx<*r|{ؘ~Uz2an{yd+g)!b 4޾T]ܐˏA4U}wu-1z 1_v%C>1=}vpaqKe]|YTZpS <ݕF_0ܞe."ͼxtjZ 'n!$؄6sE2O'F3 k$jszO2\jbͤXp؄YBg7W"\X|<y ẅ́Ĩ*r"q3Bn ΕߙxZkvj=UKWkݫ>dtCnob^\>xL4MdCTq차qrze>w C`syB<LH K6XO-!/M!$ǒHm(ʼnmC?\|k9!J2/t~* .s4p)J l(f[y@AZGuQt_cb+u:V (oȁ`sxO7q7(Q2{R֌ 51z|6:]cQ#?n QyQ J&qg%(O+P83 M79XK|Y$mn:2|wiT&3`.^!~&*Mga؝4k ߐe/עD0g<+,#P)ќ<>A=A%saczfUaͻǿ@ Mar"] ;c!Ɩ~?8x %l M7NqF]H4V$ HtDV .U Ƹzo%Zx7qȧ#Uy} |,v$ݭ0DƻEMon?VE}aÃDswwCW}G{pA)"Lg$\>b}7]p>':Ha;gDlgh?ӨTsA6LºX44[$ X|V{=psOҨ$n+K1(ݥ1d\~NHJ 9]|8ΘS?$6̫4oRYB 3!00eԎ%4OcuH*cJQ!kOv{wqoCU&z >j=ڗpHҶ H-fl)oqA;!v>4.QIފ[FPZ-Plx\t[9T)I)ϼ9?KޑM$fcC#rκ?2G`‡zUCU43fGzV>vNmFƇX%;D0 FwLPvKN^9=m{=k)vlT`eOsԓq$=N4 ?3?<v1 . x8kɶ @EY8-.b صFT6FC* +:a,8l)qy8ҳPaa̎z=fY?,U.ќS@Ԑ{G,r_"Lv5'YB8 Gdϝ"8f*@?6Kf^R~T>4|+F U@ ?']ѓ%;+,03:^$dWRrDt65>kMxm9Ћp8d^D)D:yiM, ] nЛgkxq&Yi5ɝ0mr-0 >e?s\J/՜O "OzV t8d?Y4N?c07  O%/!vXd,6a]EJz\|bӭ= lz M]׺&+C]?ͅf@y1x>l].hCEi@:ޔ⠃iE4YmSzG~!ȼ*mszti|r6ú"Qyf K,UXGCV4r p Z uΚ! PC`Q䂸Nn5!vY߷M+ǡx=ݮ ZHOHIC_(C908K60觮(:8ޚchLRyNӅYEg.3j\(v] E(ꂊⴎg9 7Ch,ڧzRTґPQ4ױ9 &z-+fx D č[iWbg.}4Z2lESp}|H&\Rҟ?2^*96lfֶ}c52z$t*1zhЋNz23ǭ6XPv2> S:NE{cw*!Y{#Du"Q,Va=}2Y˩;4 5j!">Ku榑\3Lǽo9n?G?|Y%4N{=Mn>;ijs<3uQDaU76qe72tdŝv9~&<̭"GEe>sGxy*&UkP0:H'*!>'xlMt*my>JM~ۚ) w+d2ޜM{̉zxr4e)>xXA"BCg[w!1L;IwP9x] 9 ˃A)v[dP61fه4! j#tnk%1gRSk/]ZVKu31•i͙h*Yx.u= A^f4~i h;cR6%f}Q4ҏ&j?w>&} ,U!3ژB$g($ixS`&"jAHKڅ yc6 d2`j䉫Vhy֦0y.e\[נ{,IY 3 0mS Fh&v25cR54̙ *8H[m’#O|ހ 9*((5֏=vhGepB U3W<К`ϵ RÌS)#aꞫ]8T#86Ձ*}rD(J R8ԥ;wӇOxQDE[jAAP(ɦܥ6!?)KWnUfȇb*xekVmmI996G֮</rz6\=qg-hF# ;a$/oq [HŃcXl>,^loq|@ͭ'ef@OuU}Ks;z-Ml\]"eY>0:e4?i VDM[FRd5c=td/UHQVQuh**ZK#o~*)SM.ݻwJW%a_fq3i4DQd)Ku8)/ߣ)9C#u[z 8A]1 js0/Y[o>۵QAבC?W5FYdCG4 ,1`nhvHo6Ku Z0 sk %.Nua ĞB5q!&J&+ė[HD9"^ݷ$SeMyMWEAL,\i](ET0!xha )RfN| #rCÛTfhz.tY畖whi*Pxl>vi%,ϛ&wpn_%Vo Y|q$&qM-MRӪvr@wmsD5c›ڤ@&T35Cؐ+dq8c+<4uDybZ*`0&T(K pжm+Ļ/˭u[e\Lpq`0OEn^QY)Dž1KlFhTpql[Zί0 svI]b*1[^M@kxʰ2089WzY.a)ޒ`O/+Og -@g g ]zo;ΒdlkWu/6e;+%TdɃ{P88:~>ꮛ2H]S[JH5F\ĝ[*3|XҒm[r]vHmAחԯj~ %Rg-&,&צsK(N<TOahJ){aJ,h=qB0D6Tz̠D'=BD8QSqS >J4o{{Z粋EK6&_BQW;A(0`Xd5F@<(DŽa*6Ov1/ 8X'Tfl`UHF7s5QFwXS`NN޲bN5a}:#|B*!\~/] jP FǼ{~GY!?_]YXU`"1p :D5Pg40Hԭ,EQݫUc<ׂy{ܑ޹lE=%E־b4kN(/vm YԴ'hV~U2`G])W[/z9(P[WnØ^u''.6,YMj?;cwĕY\KwqWi=#fH?O[J+PjKlIsހaU=X3r<) !}R6u9e"L @BC9q*ſr.ȋՏ=ޜUZI>}vZYj_'T ]O63qvr)3ɀ.H*ϧ1vO=Q3F[Qx 92 '9dI+uK!F;. )kqo|gx($Y# #:yI? `&Z lXOo4T؛R]e0vf_dCvԲz:k-LںTL M>v烆 }9 g @ y<ޒC>κLD2 ؃ x>pۗ u޵J{#cP/ ެcЀkGf(Wz*Des'"By/ EcML2a{.[)c,44Sx*YmDDm Vʄ2NLFqY f[i4 cV``ƜO{h  MZܐmˠ,0͆vlڦ|!x`Ao`@1AALyðJq<bZƝ4 +hM\~ȮU"l*ĥjM7u(=$ %!MIbcИ;MPyܡq~ugKu L, mhR󇯢YUPNnk#M Z/H&f[¨Dyݰě2?Vdҩgygs|/b+txWZ ⁁Uc-tlobz7Kp# 4G3M?*i%?ϤEb u puYv*4FZ 2"Ci,/;_%ꁋJm[*Ap7Qn_\͈ЂfFYV4 OKv(lTԖ!.գDAt8A!Ec5_^Mnq#u]f1Mc2rƦׇX">*+c ™xl;;dp d m"r̉G6bKhꭎ zQk&FadoZO!訡}|G:_ȃ:VIjcWw4Zz 35I̧R.ug)%ۈM~VQg9L癲bEԶ8'_Hѫ4X VqwliJV۠-AwE_G7ԥ E2UV4 5/Y<$c&{7syq0ETچ|7K+oCB8oASzjܛc+f'!wS 9 QlxiTOzTgYgJO?^4™*Wg[2.o"z;]nezx]O^JH{&⅚G^Z_5+*I>\ w}M+4:f)l0C*rG?|k"wi!,to1x{" K ȭ 7m A9,gP`WΖa{BoYx=/ۿeY7 |`>䇰@8G oE۱(ͥ]|Sz( Y04~lM,A~~-ڛ'fN˕ꧫd9 ^ߍ6Z[1 .O`Y!ѮOYiI(8`(\pPЄmMtJ E$5^.TDS)B3x(em!~Hz ]kJg %.OŰv"s%N|+#ymxawg r{Unzq c_{8"պ%NجÕ$4dH{g=N\B3S̐B獵DJ`}!D]=DbRb4ݕ6 RAjbڲ*pQԥB^UdGΕbQ@A32GmQ G3:fGo~?D` :^DQݦ1SqttXօr"-  D?l\ђI UOHD)K JiG_AQ_r8l*|Q!QlT2^!JO(|=uWtYI*pbKsV$OgHZ# 1QX4TU[1MԵ6l !?Ͻ|!dvA֎UKprRmfsw%ba&Z/HrPOm I+/B{L:ݨj-_Vvkjl,қܳeֳ(a&^zsZ1[\Fm!r 8SHsUɪE#*#nׂHZP֎;x "]VWXY>ٌE;6v&e5wM)%nzFӯ#b[|Z}ᄶA}Ә) p+g 뾶S+(N VADR{(RzkZE~M!!U⯦쪻fCXvaع{AÂJARQ56H3O&Jf+Wwi#Mu@DNVCϟY\Ǐ W>8 kgP 4w2$@]NЀN3njCX~̷@Ozޟ] qV۴ `J8\I? cV0=S oD7\z%k5%{J zEr>:,Th]&:,Q钭PT(MftV /3'H̍g {;p/s.g{RCiꕢ+LJإѷ+Zzoܨrsꜚg+Es.$!;J:kv7;x{|i4 zFbpX2qB, "i>$ ?L3+0dIue""Op4݀خTSU3;JoṄ]N>)}WTly˩e {{3@nDMH!Ja2R9a~a7" Q.e'>9!~V_XBHt-ǮYMbaJ[5VHL=EЃnqn1ɰiC1S*m6=VR4O?E>^tlQY"q vAk7Hju0 <΅uc+3.^ #}f.zh2|G3|AWD`qIvEc9Ȟ:(B53CmӤ|n*- Ӣ0%ALCC6ł"!QGMr%dFpz $Ϛ{A;MBjee]5IAIY9@.,Ia7% uWUWcI]{V T4K\fw&5k>_-@ g"A^k Pv~}Rup9+]˚*X> wsZj|u  bUIn:p[KF'1R?S8]!CӰHsn m2Dݭ]5K2$KcqHtzʜ* N&6!CUP X:7- d#+]Dz}z}e{-ֈVL+4X#_5,׮hK~*Z3S}M8Ť,vV&EUrX?Hsݾ&UӬg@ț HW}wŤM[\ўAj3B9k͝uis ҝn#k8 *{#G\Y'Ryۀ!7-{C,s!zB x{4lKw}ג5JrF íU;#fq %0#۱IUmoEZ[|Y |]"z Sw=#+pܙYуxYA*@#$=&&h'W`2hn7eo#T0:MWA?$$D7";RZ}+|ϵkej<>(JSҋ#FB]ŵ& 5:n+f- >a%ac0 Ə,,mSoI%5 jFNe\Y+7j*;\SNFw gr ϒ~V6` ":Rv}:,qkT9SU <3dZqn$h{7hmJ>$s.yTe.s k@} \1t '(``8LA"K JZ&pp1hJST޴C;JZ;A;!%@z4"ߥ54u09;aD~'4Tf̫x nxYKP!x"P5nLMbRƸV㙑*aL*8u_~쉛ZC][UX4)zC֩"q̞ԊN+nGsUHZojۏ^94g|>Wyy-!0>P{2D&.,sN fsT8x͸2tnd?~67 zH6C 4wa]j %c1t2ݗS͜Ey^Ly AfDo +%k"5d/\A"8qeD.cL50$ǽEˉ4:m uctX+o؂$v@69?GPçҏu??~&znXG(;Ha4Go`\~GAȻTܣ[K/ő^;/)O m>Q!g_WVYEעS4+'Kt*@=BB~$rHgy5b|}AM7q4cb,Zr5Z o?0~*_mμiLX&gA1WH q[I-hQߜ@;+x-Nv~I8=KԠUcʰ2V(<EE*f%vLw&b=5> Eͤu=ٓN&BEuVZ4tYπ Y C.I tSTגVsjI|4&;11duQ t5 7U(:~S46\)/$o2gRitd%q6/JUSfz SZCL0x7}T?7r}חWmczL`iPߢ=+QP6g6uHi~7Iu`zŹפU]ygR; -&L6 +օ\PYV{t,oOseKB:Fé?/#-Zށ0WzO1`Mv ]]s͖VK0V=Hin)1whEbͱ%OY?{ܪ!ӓ΂teNtf;իѰNPⷔhXN0"[0 ǫ+9*_e̍VJ~ڱͮ$cGp`z Ś2I]]-1A ~UE_#8c4Ge!3Fedb[Lɾ&x)c}Utu\ᙈF8T,K> fëAw.>!2Oʏ6Z ,Ow9fO_g2&2ZEC`E[Fg ʕ㐐GQw7A`'A@1L|aZH,'L8ͮU@n4a :}SS~J!Us}y6Bb 63̇ukeRYv%C/?l:gת=fq:WFop? (W? /$_~W /܆kQ 3(屠j9w_qs* MTQ.EkF3 I%;AŒ>YZP|v%X6iwuARmTJϋ"/QY8΁lZll'Ur x&Ĭ܊d m5^:qZ3M 6 32\sMۂGl-O] cBؼB{F23ihmf[ 7+TgzK"pU--@F4*K !4"OU 3AxXձ cpZ '90|IN E Q/*1!)0]>MLm5 (Lg67^Lݞ2}TP)UPYS+ܧh~] t AwI 6"YcԦIQxWx ,Εk=Un1tMoGc -/yt+%ע 6/bege@΅M (T{Lai_MCc&g CZUj,/v[ ~B)iO˓V-qP#H8z xONGpaڋw# k%^6Ie7;Ohr||ZHh\`&[6̃xz|ף긦5bȁf8`mA`q~(dž k;ܯ0f.dr 2I#cx`NO!/ h93 3wfH,rx'F}X_P[#ڇyʆkX!+H RYU\&WwEc=25+%9޿!P9\7Zy%yx9rAc'L YHz21,IEYD1N5&o Ƒ^tk*AH һ{{a0Pb@>~ą[L ϋEF[k볋A~7C 3 O!r_[}tMKʄj)%ldz,‘nv̚={GrPNDž|5a禜uq* 2w4!9 tVe7}mNo F~$磍;*| yR^[_?ozq+Iwn(%UY3k#dweΣJF<Ѳ}ܶ7DOJ M"R!TWT_g/"p*UG"L W\rqEcԨ~>pf 33.Me@?"ĉtL֑0QNG]H$o;{d '@؀&NA69>ōJhƙK$45n LL}3 NP9; #E;՟}n(@4t(V[!w/## )ݔklnDHe߀i"_mlT&0YWyIUm0VE.AHCK3|݆Qy8L>tD\(Ac <4hL3BT˫o$y=D_#~'@Mlm޳ H!X -S]%ANE9ꇪyr[f;|F'+׽'Y?-]ҍ"5[髵MfiNTgd6v Sk XPRkE['ԛ.볌]_Owmd5"{+몋D~ =c k:>tK̵0HLp* Eݸ+yf_hiw2.5'_[Lk wA[W$тW+uMi ڊf@kp#)"&z%dsWȶkYizS9$'b$6>N!:o$_j`5KVqF`x_#%CGuq'`d__<)h''-$*Ao g(uqݓJLyz]W!${e% tX4^a/6 QxJۅr]E{wYg^19ћ@ 5mKMϹ ]l0Oa` a3ZϣK{Q ,FΌjp$HzÈ,SߔM:WD}ެtF,HjH!.ޱZOt7O R Shl'\wM/Y>'m zUT6Sl+ZRct*xLNȮMٶ&ʹ})LrRZ< {@|>5ƀ^r>hZҘ2G]5xҼ.SxU%PH?!}㞲UuՓi0]G-IX .ݟ8WKN駃i +y1큘IY/gٜf$0*yGfR| #-r#%=o&@;GIQ7V;>m-׃wO3KRuBZDc}P4CT۩Ja zҌ1:Oq2!a%p[Xsd[a\VbhO{NߢqkpG[Z.R &$wĺ"%/D()o`XOƒfDt WXgW!P'J@ybK&6yqIjQ\5ѷƝT,g|Q֩Y:.h`LdW-@ppɛ⑪?*Čq$-"xE&rF|&ʆ!-riIVKz*3ș՟#3dv"l尔q65purNj\S'>cS)v@-d3JkZZ g4F e ©mR1\N^ Z&QRqDNV )3_'J}Pij\xЖBARU>'FW⼠w=)"{^\6<~hZs79$.\G wn Nm_?}{dU,HjPͶ k:8Up}o)^G)g.C:KA9d#$Yfc|8<&G{I_x ]4z2'5'i/֜Wp'{s$9\+Sv`b,Q @)m`U Lt)]r:UT+h_'0d>Yow:%m^]QiI[0C{}[_I ڮwx#wl]R"vAgܰDےWi]=CDrݚ&Ase^hw_4" t'=eS$@?+PN}4kρ ""cJ>@neZ|zA/&_s QҀFmIj$*qe'&~/)(pL&n#'= UO&Tfa2E=1bj^}ƿ!G[>Ƃ(o1V\+ٶA*%AoZ2Žhӕ\/c1V&F:4Dݤ$SԤNR$0՛d^~jbv{:TxIAք|H$)xΤ!ojWAC0jtR.CG}d|q T+s6V]"wg]wPq핸b3ЙU \2+ bJE+4{Bh+F]a2^6@,Jk_fJ9e4Rx1p7iiLjU&o#iY}ےR}8dA1g9xt3!KxJʟ_Y/k9nj6t]!fgE40ye&~>rdg|Y}aE;Ц[uU2NF}6lN݁!qoxAizq*6|D./3}jbb3P@1F~ }r:f ?`IcͷL/ |&K3_Gx gc>)\-({28%b7R\Ku$٧l.r 1W3~1#2-ȻY(6#*{`g.{.Ͳ[")_^!BNΖG,#E5Mx @",U2c\;Se]=5V"ƌYN*E 4 COi!'?t `Bz, Q8pS_װ1x$3dZ7L(,#.<5S%)3_>ƤN@*1>̮1>=h8nFT<ĸxFeD5_iW͵ st_q$6ѩ∩S˜X&Ly _wBRri<Έ?n+^ 9p-y>wF&8g<\cv01dT3bM"x#"qn`}ǰ[˜J:thPk!Zpm[4 JkdZx#[\\f.`a*1)@mNh pXf7gyl r҅`ij|Gx_ϊnO}GAK$n ٬pY{Mp_Ӡ5jvt9Ґp0sv'D'q&Q/))M E-h53lWGD6{-y>5=V,IFRS?R&]7/,s{|2i84,ȥT)אCfr!U_Ș. H7`x`_lݵ%dI's{]4@?%Ѕ+Iֈti RJG 8=#P) oJm>ZP#@.,H[IߨW_@\?O]7+F8!Nj=3|\Nv(w 4`[YOn4܂]i ֖ńYK,q%8NksNLfbfsd Vj0xr-#黿 =yvvQ&n)1vbGe|2ZJtp>CbQs笒K]?Lȕb_Go~uFSY{-XzHRY!V#A3aato'5-.wՑ B4o@L23̺)P.4\r-`NIfD"}':(6YO,)):.ߊAyphXʘy)ʔ4%hFӏ8wO!hqBsfգXHՀ)?H@8u PHnsv[n?lH"\vҫ>8Ds#_=WIr+eFb&a'Q~2e3#ϣi&UlѫFL(yǭ&\`{ iܢU 2YkMaʲ: 0qv,N=#RMAM*@x0pŽ*[zЍt>Nx;-סk1twltU4Ÿ-_!K!4ľγ –߃SO1ذOƾ]6{M4UF/GߊP"µBS q籟dqz^}R 53&IRV9" Nhqit蝽Ok+ª֣/}]Ph$@[w€AݚsKal/8uj$0ȷ(S. _ 7Uѽd1z~U|<+w}dXs2K`vDP ypNdsaIuiQ_i;P}ԶܩskaU_N剾b Z-D9_iPh*IZ +2R'J[@1辂(t+>Znt~#Ĥ˝'6u׺1SF&~pvhufAwx |`GCGl* QQUVA/6H-4z:J)1JzAꨘ4)U:R]zt{.JMրR3 3$ H"\(BSi: 亖U[MX/1}ڊEvսB=uRB CdzǧElivE ~A9Y eEZHe:k\)>y+'<7+I@"H۔&9i r*21(ㅲt|V9:?{5+4`0j5xtj*(*K$\~1%CBZaţL\ iVԯ8KaPU.t 50:yC' vάƝauE;5D 6[hÓrtS\Y6ƴ#K:ER9PeG2Rv P Ne읡QPgf%\1}ty UY(jC /a<։f1 щ(cyX4r> ;~1Ƅ$ urd4S<6 #8H4e-X(,㡷K -8yg=]x**nɱ*S%hzWpHqY*3wa($stŬ-}XZ9WEyWe$ZBI!+ baC}v] !"EʻW^%?[ 9ff\\FO7"Z5ᴒE7ϷlMTAA];N+vµ Us]giP(:$u؍/+ #>4+^ط)<ˈ?EQd91QӴ$xwf+`dX`X~&=\13M,.)*g Ҿ9۠R`>p{A8xqhޖ+yI]muޑ~y4IJd 4:2'y%f|fYb9{UK^%cZ.Ƌc05&5yǜ0^`V߱=f:MnxF;'J-5\zd^ Vcb9 0g|My'#b"[a4p{ϩd*Cp10/8LU|܅~L}Z;% x[ 373A}n$-*w!#ֵhi2 "6Rw͗@scv~-ї.xY̑Cf%\.Mqx< 8Նlk0t V 1?n"`){k tL䵭L}~21Hƅ k{ɎhF < @]3exƔfOD&SN;;M`>rkx*M\~ έ9x!k*k|/ssd`ަc!OF +?=]8_;p󂁽6?\5ciMu6{J/+ϓ2 >wyLi[!]"7T%uAlUv܇@ ҙҽ:3 '6/N|tvmNd&G-UnK'G=C_=SI27 ˆTCGB#"YiX/F.X4b'AMj1~k{+֙sZs{N8c/8w-os1R%!j-=<{d00ߨhak0湳0(_ȸ'Q6s^}e-\Ah쥴AߝZ<1ȗ9OK^xBobPyw+%c٥ꆰp xbv6CZa){ h9/L}1X;B,vI`mZZ_:O~dNND3CfT+RX K9P']=KR=_ fܳfK6=gGJhNHڼ*zh׫gI:,P&!s{>Iێ ٵCCPܽRTN*l; 'xjCr(Gjd-ka.Cy0Rg@]_jзl|eH&EE(K /޾vxY=XyMeHnk™)C}VݳzTEO-Y!7]dh{(q4" a(U]۫`&86* CE* Ι3YSŘ/ ] ]˂ Yɖg^ O2љK r`}S¦bJNHoYzD ]$S6L2cDPʪuV 110T?NϪzGߠ۠/&Оo848E@ugyƶQӟpBzٖM]J<)l%2HזDzM\rJfhSX[żeu|]`sO#;uFKETGc@kfq[ezSN<{ϑKhԪEA;d|! m4i2_jW]#U%εsIȕ$Ei_=7V;0YZ#Uy ==r՚gYZisospec-1.9.1/tests/Python/0000755000175000017500000000000013373520171015542 5ustar rusconirusconiisospec-1.9.1/tests/Python/test_IsoSpecPy.py0000644000175000017500000001051513373520171021033 0ustar rusconirusconiimport sys import IsoSpecPy from math import exp, log def sprint(s): sys.stdout.write(str(s)) sys.stdout.flush() try: import OldIsoSpecPy except ImportError: print("This test compares the results of installed IsoSpec with IsoSpec version 1.0.7, installed as OldIsoSpecPy") print("You must install it, using:") print("pip install OldIsoSpecPy --index-url https://test.pypi.org/simple/") # Correctness tests comparing IsoSpecPy 1.0.7 and HEAD. The trouble here is that due to slightly different way things are calculated # we get different rounding errors, and therefore slightly different results - and that's OK. The function kinda_like reflects that # - but is still WAAAY too strict. Often we can justifiably get different configurations, or different counts of configurations... molecules = "H2O1 C100 P1 P100 C1 H10C10O10N10S5 Se1 Se10 Sn1 Sn4 Sn4C1 C2H6O1 C1000 C520H817N139O147S8 C1H1O2N2Se1Sn1P1 P1C1Sn1 Se5 Sn5 Se2Sn2C2O2N2S2B2He2U2Na2Cl2".split() parameters = list(map(float, "0.0 0.1 0.5 0.01 0.9 0.99 0.01 0.0001 0.999 0.362 0.852348".split())) def kinda_like(o1, o2): if type(o1) in (list, tuple) and type(o2) in (list, tuple) : assert len(o1) == len(o2) assert all(kinda_like(oo1, oo2) for oo1, oo2 in zip(o1, o2)) if type(o1) == type(o2) == float: assert o1*o2 >= 0.0 # same sign check assert abs(o1*0.99)-0.000001 <= abs(o2) <= abs(o1*1.01)+0.000001 return True def sort_confs(confs): if len(confs[0]) == 0: return confs l = list(zip(*confs)) l.sort(key = lambda x: -x[1]) return ([x[0] for x in l], [x[1] for x in l], [x[2] for x in l]) def confs_from_ordered_generator(formula, target_prob): ret = ([], [], []) prob = 0.0 for conf in IsoSpecPy.IsoOrderedGenerator(formula=formula, get_confs=True): conf = (conf[0], log(conf[1]), conf[2]) if prob >= target_prob and target_prob < 1.0: return ret ret[0].append(conf[0]) prob += exp(conf[1]) ret[1].append(conf[1]) ret[2].append([item for sublist in conf[2] for item in sublist]) return ret def confs_from_layered_generator(formula, target_prob): ret = ([], [], []) for conf in IsoSpecPy.IsoLayeredGenerator(formula=formula, prob_to_cover = target_prob, get_confs=True, do_trim=True): conf = (conf[0], log(conf[1]), conf[2]) ret[0].append(conf[0]) ret[1].append(conf[1]) ret[2].append([item for sublist in conf[2] for item in sublist]) return sort_confs(ret) def confs_from_threshold_generator(formula, target_prob): ret = ([], [], []) for conf in IsoSpecPy.IsoThresholdGenerator(formula=formula, threshold = target_prob, absolute = True, get_confs=True): conf = (conf[0], log(conf[1]), conf[2]) ret[0].append(conf[0]) ret[1].append(conf[1]) ret[2].append([item for sublist in conf[2] for item in sublist]) return sort_confs(ret) is_ok = False try: i = IsoSpecPy.IsoThreshold(0.1, False, atomCounts = [100], isotopeMasses = [[1.0, 2.0, 3.0]], isotopeProbabilities = [[0.0, 0.6, 0.4]]) for x in i: print(x) except ValueError: is_ok = True assert is_ok for molecule in molecules: for parameter in parameters: sprint("{} {}... ".format(molecule, parameter)) old_ordered = OldIsoSpecPy.IsoSpecPy.IsoSpec.IsoFromFormula(molecule, parameter, method="ordered").getConfs() sprint(len(old_ordered[0])) new_ordered = confs_from_ordered_generator(molecule, parameter) assert kinda_like(new_ordered, old_ordered) new_layered = confs_from_layered_generator(molecule, parameter) assert kinda_like(new_layered, new_ordered) if len(new_ordered[1]) > 0: new_threshold = exp(new_ordered[1][-1]-0.00000001) else: new_threshold = 1.1 new_threshold_res = confs_from_threshold_generator(molecule, new_threshold) assert kinda_like(new_ordered, new_threshold_res) if parameter > 0: sprint(" thresholded: ") new_thr_r = confs_from_threshold_generator(molecule, parameter) sprint(len(new_thr_r[0])) old_thr_r = sort_confs(OldIsoSpecPy.IsoSpecPy.IsoSpec.IsoFromFormula(molecule, parameter, method="threshold_absolute").getConfs()) assert kinda_like(new_thr_r, old_thr_r) print("... OK!") isospec-1.9.1/LICENCE0000644000175000017500000000320313373520171014102 0ustar rusconirusconiIsoSpec is provided under the terms of 2-clause BSD licence. If you require other licensing terms, please contact the authors. We would appreciate if you let us know if you use this library in your own software, but you are under no legal obligation to do so. ------------------------------------------------------------------------- Copyright (c) 2015-2018, Micha Startek and Mateusz cki All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. isospec-1.9.1/Examples/0000755000175000017500000000000013373520171014675 5ustar rusconirusconiisospec-1.9.1/Examples/R/0000755000175000017500000000000013373520171015076 5ustar rusconirusconiisospec-1.9.1/Examples/R/water.R0000644000175000017500000000640613373520171016351 0ustar rusconirusconilibrary(IsoSpecR) water = c(H=2,O=1) # A water molecule: p = .99 # joint probability of the output # calculate one of the smallest sets of isotopologues with # probability at least equal to 99% WATER = IsoSpecify(molecule = water, stopCondition = p) print(WATER) # the outcome looks small, but water can only have 3*3 = 9 isotopologues. # (for a general formula, see the formula in the supplement to our paper) # you can see all of them by setting the probability to 1: this will include all isotopologues. WATER = IsoSpecify(molecule = water, stopCondition = 1) print(WATER) # The default output consists of a matrix with two columns: mass and log-probability of the # isotopologues (the natural logarithms, with base equal to 'e'). print(WATER[,"mass"]) print(WATER[,"logProb"]) # to get the probabilities, simply run WATER = IsoSpecify(molecule = water, stopCondition = 1, showCounts=T) print(WATER) # Let's get a bigger example: bovine insulin bovine_insulin = c(C=254, H=377, N=65, O=75, S=6) BOVINE_INSULIN = IsoSpecify(bovine_insulin, .999) # as you can see, there are 1301 isotopologs such that their probability summed together # exceed .99. This is one of the smallest such sets. print(nrow(BOVINE_INSULIN)) total_probability = sum(exp(BOVINE_INSULIN[,'logProb'])) print(total_probability) # there are other ways to get this outcome, but this one is the fastest. # if you want to get the isotopologues sorted by probability, you can run the # priority-queue version of the algorithm. BOVINE_INSULIN = IsoSpecify(bovine_insulin, .999, algo=1) is.unsorted(BOVINE_INSULIN[,'logProb'][nrow(BOVINE_INSULIN):1]) # is.unsorted == FALSE is the same as sorted == TRUE. It's elementary :) # using the priority queue has poorer time complexity, which is O(n*log(n)). T0 = Sys.time() BOVINE_INSULIN = IsoSpecify(bovine_insulin, .999, algo=1) T1 = Sys.time() BOVINE_INSULIN = IsoSpecify(bovine_insulin, .999, algo=0) T2 = Sys.time() print(T1 - T0) print(T2 - T1) # If, for some reason, you just want to generate peaks above certain probability threshold, # you could use the third algorithm BOVINE_INSULIN_peaks_more_probable_than_10_percent_each = IsoSpecify(bovine_insulin, .1, algo=3) print(exp(BOVINE_INSULIN_peaks_more_probable_than_10_percent_each[,'logProb'])) # ATTENTION: it is not a good idea to do it. # Remember, that we supply you with infinitely resolved peaks. # your experimental peaks are most likely generated by an mass spctrometer, # that does not share this quality. Hence, the smallest observed peak might # be actually a sum of some smaller, unresolved peaks, giving you false impression of security. # Anyway, if you still want to, you can also precise the limiting height of the peak w.r.t. # the height of the heighest peak. # You can achieve this with algorithm 3: BOVINE_INSULIN_peaks_higher_than_the_one_ten_thousandth_of_the_height_of_the_heighest_peak = IsoSpecify(bovine_insulin, 1e-04, algo=3) LP = BOVINE_INSULIN_peaks_higher_than_the_one_ten_thousandth_of_the_height_of_the_heighest_peak[,'logProb'] print(exp(LP[length(LP)] - LP[1])) # so, as you can see, this is a peak very close to 1/10,000, but still above the threshold. # The next most probable that was not yet calculated, would have had that ratio below this number. # You are invited to test it yourself :) # Matteo and Michał.isospec-1.9.1/Examples/C++/0000755000175000017500000000000013373520171015205 5ustar rusconirusconiisospec-1.9.1/Examples/C++/water.cpp0000644000175000017500000001024413373520171017034 0ustar rusconirusconi#include #include #include "../../IsoSpec++/isoSpec++.h" using namespace IsoSpec; int main() { int configs[5]; { // We shall walk through a set of configurations which covers at least 99.9% of the mass. // For water we could obviously go through the entire spectrum (100%), but for larger // molecules the entire spectrum has far too many configurations. Luckily, most of the // likelihood is concentrated in a relatively small set of most probable isotopologues // - and this method allows one to quickly calculate such a set, parametrising on the // percentage of coverage of total probability space required. // // This is usually better than just calculating all isotopes with probabilities above a // given threshold, as it allows one to directly parametrise on the accuracy of the // simplified spectrum - that is, the L1 distance between the full and simplified spectrum // will be less than (in this example) 0.001. // // If for some reason one would wish to just calculate a set of peaks with probabilities // above a given threshold - it is possible using the IsoThresholdGenerator class. // // Note: the returned set will usually contain a bit more configurations than necessary // to achieve the desired coverage. These configurations need to be computed anyway, however // it is possible to discard them using the optional trim argument. IsoLayeredGenerator iso("H2O1", 0.999); double total_prob = 0.0; while(iso.advanceToNextConfiguration()) { std::cout << "Visiting configuration: " << std::endl; std::cout << "Mass: " << iso.mass() << std::endl; std::cout << "log-prob: " << iso.lprob() << std::endl; std::cout << "probability: " << iso.prob() << std::endl; total_prob += iso.prob(); iso.get_conf_signature(configs); // Successive isotopologues are ordered by the appearance in the formula of the element, then by nucleon number, and concatenated into one array std::cout << "Protium atoms: " << configs[0] << std::endl; std::cout << "Deuterium atoms " << configs[1] << std::endl; std::cout << "O16 atoms: " << configs[2] << std::endl; std::cout << "O17 atoms: " << configs[3] << std::endl; std::cout << "O18 atoms: " << configs[4] << std::endl; } assert(total_prob >= 0.99); // We must have covered at least 99% of the spectrum } { std::cout << "Now what if both isotopes of hydrogen were equally probable, while prob. of O16 was 50%, O17 at 30% and O18 at 20%?" << std::endl; const int elementNumber = 2; const int isotopeNumbers[2] = {2,3}; const int atomCounts[2] = {2,1}; const double hydrogen_masses[2] = {1.00782503207, 2.0141017778}; const double oxygen_masses[3] = {15.99491461956, 16.99913170, 17.9991610}; const double* isotope_masses[2] = {hydrogen_masses, oxygen_masses}; const double hydrogen_probs[2] = {0.5, 0.5}; const double oxygen_probs[3] = {0.5, 0.3, 0.2}; const double* probs[2] = {hydrogen_probs, oxygen_probs}; IsoLayeredGenerator iso(Iso(elementNumber, isotopeNumbers, atomCounts, isotope_masses, probs), 0.99); iso.advanceToNextConfiguration(); std::cout << "The first configuration has the following parameters: " << std::endl; std::cout << "Mass: " << iso.mass() << std::endl; std::cout << "log-prob: " << iso.lprob() << std::endl; std::cout << "probability: " << iso.prob() << std::endl; iso.get_conf_signature(configs); // Successive isotopologues are ordered by the appearance in the formula of the element, then by nucleon number, and concatenated into one array std::cout << "Protium atoms: " << configs[0] << std::endl; std::cout << "Deuterium atoms " << configs[1] << std::endl; std::cout << "O16 atoms: " << configs[2] << std::endl; std::cout << "O17 atoms: " << configs[3] << std::endl; std::cout << "O18 atoms: " << configs[4] << std::endl; std::cout << "Probabilities of the remaining configurations, are: " << std::endl; while(iso.advanceToNextConfiguration()) std::cout << iso.prob() << std::endl; } // TODO: demonstrate other algorithms } isospec-1.9.1/Examples/C++/COMPILING0000644000175000017500000000035113373520171016450 0ustar rusconirusconiThe easiest (if not the most elegant) way to compile the example is: clang++ water.cpp ../../IsoSpec++/unity-build.cpp -std=c++11 You may replace clang++ with g++ if you do not have LLVM installed. Run the example by: ./a.out isospec-1.9.1/Examples/Python/0000755000175000017500000000000013373520171016156 5ustar rusconirusconiisospec-1.9.1/Examples/Python/water.py0000644000175000017500000000377013373520171017661 0ustar rusconirusconi# Calculates the isotopic distribution of water in several ways import IsoSpecPy from math import exp try: if IsoSpecPy.__version__[:3] != '1.9': raise AttributeError except AttributeError: print("This file is meant to be used with IsoSpecPy version 1.9.X. You seem to have a different version installed on your system.") import sys sys.exit(-1) i = IsoSpecPy.IsoLayeredGenerator(formula="H2O1", prob_to_cover = 0.999, get_confs=True) print("Calculating isotopic distribution of water. Here's a list of configurations necessary to cover at least 0.999 of total probability:") for mass, log_prob, conf in i: print("") print("Mass: " + str(mass)) print("log(probability): " + str(log_prob)) print("probability: " + str(exp(log_prob))) print("Number of Protium atoms: " + str(conf[0][0])) print("Number of Deuterium atoms: " + str(conf[0][1])) print("Number of O16 atoms: " + str(conf[1][0])) print("Number of O17 atoms: " + str(conf[1][1])) print("Number of O18 atoms: " + str(conf[1][2])) print("") print("Now what if both isotopes of hydrogen were equally probable, while prob. of O16 was 50%, O17 at 30% and O18 at 20%?") hydrogen_probs = (0.5, 0.5) oxygen_probs = (0.5, 0.3, 0.2) hydrogen_masses = (1.00782503207, 2.0141017778) oxygen_masses = (15.99491461956, 16.99913170, 17.9991610) i = IsoSpecPy.IsoLayeredGenerator(atomCounts = (2, 1), isotopeMasses = (hydrogen_masses, oxygen_masses), isotopeProbabilities = (hydrogen_probs, oxygen_probs), prob_to_cover = 0.999, get_confs=True) mass, log_prob, conf = next(i.__iter__()) print("The first configuration has the following parameters:") print("Mass: " + str(mass)) print("log(probability): " + str(log_prob)) print("probability: " + str(exp(log_prob))) print("Number of Protium atoms: " + str(conf[0][0])) print("Number of Deuterium atoms: " + str(conf[0][1])) print("Number of O16 atoms: " + str(conf[1][0])) print("Number of O17 atoms: " + str(conf[1][1])) print("Number of O18 atoms: " + str(conf[1][2])) isospec-1.9.1/IsoSpec++/0000755000175000017500000000000013373520171014612 5ustar rusconirusconiisospec-1.9.1/IsoSpec++/CMakeLists.txt0000644000175000017500000000156713373520171017363 0ustar rusconirusconiproject("IsoSpec") cmake_minimum_required(VERSION 2.6) set(my_sources cwrapper.cpp allocator.cpp dirtyAllocator.cpp isoSpec++.cpp isoMath.cpp marginalTrek++.cpp operators.cpp element_tables.cpp misc.cpp ) ## platform dependent compiler flags: include(CheckCXXCompilerFlag) if (NOT WIN32) # we only want fPIC on non-windows systems (fPIC is implicitly true there) CHECK_CXX_COMPILER_FLAG("-fPIC" WITH_FPIC) if (WITH_FPIC) add_definitions(-fPIC) endif() # Only add those definitions on non-windows systems add_definitions(-std=c++11 -Wall -pedantic -Wextra) else() ## On MSVS we need this for mmap set(my_sources ${my_sources} mman.c) add_definitions(-DMMAN_LIBRARY) endif() add_library(IsoSpec SHARED ${my_sources}) configure_file(IsoSpecConfig.cmake.in "${PROJECT_BINARY_DIR}/IsoSpecConfig.cmake" @ONLY) export(TARGETS IsoSpec FILE IsoSpecLibrary.cmake) isospec-1.9.1/IsoSpec++/operators.h0000644000175000017500000000700213373520171017000 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #include #include "conf.h" #include "isoMath.h" #include "misc.h" namespace IsoSpec { class KeyHasher { private: int dim; public: KeyHasher(int dim); inline std::size_t operator()(const int* conf) const { // Following Boost... std::size_t seed = 0; for(int i = 0; i < dim; ++i ) seed ^= conf[i] + 0x9e3779b9 + (seed << 6) + (seed >> 2); return seed; }; }; class ConfEqual { private: int size; public: ConfEqual(int dim); inline bool operator()(const int* conf1, const int* conf2) const { // The memcmp() function returns zero if the two strings are identical, oth- // erwise returns the difference between the first two differing bytes // (treated as unsigned char values, so that `\200' is greater than `\0', // for example). Zero-length strings are always identical. This behavior // is not required by C and portable code should only depend on the sign of // the returned value. // sacred man of memcmp. return memcmp(conf1, conf2, size) == 0; } }; class ConfOrder { //configurations comparator public: inline bool operator()(void* conf1,void* conf2) const { return *reinterpret_cast(conf1) < *reinterpret_cast(conf2); }; }; class ConfOrderMarginal { //configurations comparator const double* logProbs; int dim; public: ConfOrderMarginal(const double* logProbs, int dim); inline bool operator()(const Conf conf1, const Conf conf2) {// Return true if conf1 is less probable than conf2. return unnormalized_logProb(conf1,logProbs,dim) < unnormalized_logProb(conf2,logProbs,dim); }; }; class ConfOrderMarginalDescending { //configurations comparator const double* logProbs; int dim; public: ConfOrderMarginalDescending(const double* logProbs, int dim); inline bool operator()(const Conf conf1, const Conf conf2) {// Return true if conf1 is less probable than conf2. return unnormalized_logProb(conf1,logProbs,dim) > unnormalized_logProb(conf2,logProbs,dim); }; }; template class ReverseOrder { public: inline ReverseOrder() {}; inline bool operator()(const T a,const T b) const { return a > b; }; }; template class TableOrder { const T* tbl; public: inline TableOrder(const T* _tbl) : tbl(_tbl) {}; inline bool operator()(unsigned int i, unsigned int j) { return tbl[i] < tbl[j]; }; }; } // namespace IsoSpec #include "marginalTrek++.h" class PrecalculatedMarginal; // In case marginalTrek++.h us including us, and can't be included again... namespace IsoSpec { class OrderMarginalsBySizeDecresing { PrecalculatedMarginal const* const* const T; public: OrderMarginalsBySizeDecresing(PrecalculatedMarginal const* const * const _T); bool operator()(int m1, int m2); }; } // namespace IsoSpec isospec-1.9.1/IsoSpec++/isoSpec++.cpp0000644000175000017500000005540513373520171017062 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "platform.h" #include "conf.h" #include "dirtyAllocator.h" #include "operators.h" #include "summator.h" #include "marginalTrek++.h" #include "isoSpec++.h" #include "misc.h" #include "element_tables.h" using namespace std; namespace IsoSpec { Iso::Iso( int _dimNumber, const int* _isotopeNumbers, const int* _atomCounts, const double* const * _isotopeMasses, const double* const * _isotopeProbabilities ) : disowned(false), dimNumber(_dimNumber), isotopeNumbers(array_copy(_isotopeNumbers, _dimNumber)), atomCounts(array_copy(_atomCounts, _dimNumber)), confSize(_dimNumber * sizeof(int)), allDim(0), marginals(nullptr), modeLProb(0.0) { try{ setupMarginals(_isotopeMasses, _isotopeProbabilities); } catch(...) { delete[] isotopeNumbers; delete[] atomCounts; throw; } } Iso::Iso(Iso&& other) : disowned(other.disowned), dimNumber(other.dimNumber), isotopeNumbers(other.isotopeNumbers), atomCounts(other.atomCounts), confSize(other.confSize), allDim(other.allDim), marginals(other.marginals), modeLProb(other.modeLProb) { other.disowned = true; } Iso::Iso(const Iso& other, bool fullcopy) : disowned(fullcopy ? throw std::logic_error("Not implemented") : true), dimNumber(other.dimNumber), isotopeNumbers(fullcopy ? array_copy(other.isotopeNumbers, dimNumber) : other.isotopeNumbers), atomCounts(fullcopy ? array_copy(other.atomCounts, dimNumber) : other.atomCounts), confSize(other.confSize), allDim(other.allDim), marginals(fullcopy ? throw std::logic_error("Not implemented") : other.marginals), modeLProb(other.modeLProb) {} inline void Iso::setupMarginals(const double* const * _isotopeMasses, const double* const * _isotopeProbabilities) { if (marginals == nullptr) { int ii = 0; try { marginals = new Marginal*[dimNumber]; while(ii < dimNumber) { allDim += isotopeNumbers[ii]; marginals[ii] = new Marginal( _isotopeMasses[ii], _isotopeProbabilities[ii], isotopeNumbers[ii], atomCounts[ii] ); modeLProb += marginals[ii]->getModeLProb(); ii++; } } catch(...) { ii--; while(ii >= 0) { delete marginals[ii]; ii--; } delete[] marginals; marginals = nullptr; throw; } } } Iso::~Iso() { if(!disowned) { if (marginals != nullptr) dealloc_table(marginals, dimNumber); delete[] isotopeNumbers; delete[] atomCounts; } } double Iso::getLightestPeakMass() const { double mass = 0.0; for (int ii=0; iigetLightestConfMass(); return mass; } double Iso::getHeaviestPeakMass() const { double mass = 0.0; for (int ii=0; iigetHeaviestConfMass(); return mass; } Iso::Iso(const char* formula) : disowned(false), allDim(0), marginals(nullptr), modeLProb(0.0) { std::vector isotope_masses; std::vector isotope_probabilities; dimNumber = parse_formula(formula, isotope_masses, isotope_probabilities, &isotopeNumbers, &atomCounts, &confSize); setupMarginals(isotope_masses.data(), isotope_probabilities.data()); } unsigned int parse_formula(const char* formula, std::vector& isotope_masses, std::vector& isotope_probabilities, int** isotopeNumbers, int** atomCounts, unsigned int* confSize) { // This function is NOT guaranteed to be secure against malicious input. It should be used only for debugging. size_t slen = strlen(formula); // Yes, it would be more elegant to use std::string here, but it's the only promiment place where it would be used in IsoSpec, and avoiding it here // means we can run the whole thing through Clang's memory sanitizer without the need for instrumented libc++/libstdc++. That's worth messing with char pointers a // little bit. std::vector > elements; std::vector numbers; if(slen == 0) throw invalid_argument("Invalid formula: can't be empty"); if(!isdigit(formula[slen-1])) throw invalid_argument("Invalid formula: every element must be followed by a number - write H2O1 and not H2O for water"); for(size_t ii=0; ii element_indexes; for (unsigned int i=0; i _isotope_numbers; for(vector::iterator it = element_indexes.begin(); it != element_indexes.end(); ++it) { int num = 0; int at_idx = *it; int atomicNo = elem_table_atomicNo[at_idx]; while(at_idx < ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES && elem_table_atomicNo[at_idx] == atomicNo) { at_idx++; num++; } _isotope_numbers.push_back(num); } for(vector::iterator it = element_indexes.begin(); it != element_indexes.end(); ++it) { isotope_masses.push_back(&elem_table_mass[*it]); isotope_probabilities.push_back(&elem_table_probability[*it]); }; const unsigned int dimNumber = elements.size(); *isotopeNumbers = array_copy(_isotope_numbers.data(), dimNumber); *atomCounts = array_copy(numbers.data(), dimNumber); *confSize = dimNumber * sizeof(int); return dimNumber; } /* * ---------------------------------------------------------------------------------------------------------- */ IsoGenerator::IsoGenerator(Iso&& iso, bool alloc_partials) : Iso(std::move(iso)), partialLProbs(alloc_partials ? new double[dimNumber+1] : nullptr), partialMasses(alloc_partials ? new double[dimNumber+1] : nullptr), partialProbs(alloc_partials ? new double[dimNumber+1] : nullptr) { if(alloc_partials) { partialLProbs[dimNumber] = 0.0; partialMasses[dimNumber] = 0.0; partialProbs[dimNumber] = 1.0; } } IsoGenerator::~IsoGenerator() { if(partialLProbs != nullptr) delete[] partialLProbs; if(partialMasses != nullptr) delete[] partialMasses; if(partialProbs != nullptr) delete[] partialProbs; } /* * ---------------------------------------------------------------------------------------------------------- */ IsoThresholdGenerator::IsoThresholdGenerator(Iso&& iso, double _threshold, bool _absolute, int tabSize, int hashSize, bool reorder_marginals) : IsoGenerator(std::move(iso)), Lcutoff(_threshold <= 0.0 ? std::numeric_limits::lowest() : (_absolute ? log(_threshold) : log(_threshold) + modeLProb)) { counter = new int[dimNumber]; maxConfsLPSum = new double[dimNumber-1]; marginalResultsUnsorted = new PrecalculatedMarginal*[dimNumber]; empty = false; for(int ii=0; iigetModeLProb(), true, tabSize, hashSize); if(!marginalResultsUnsorted[ii]->inRange(0)) empty = true; } if(reorder_marginals) { OrderMarginalsBySizeDecresing comparator(marginalResultsUnsorted); int* tmpMarginalOrder = new int[dimNumber]; for(int ii=0; iiget_lProbs_ptr(); if(dimNumber > 1) maxConfsLPSum[0] = marginalResults[0]->getModeLProb(); for(int ii=1; iigetModeLProb(); lProbs_ptr = lProbs_ptr_start; partialLProbs_second = partialLProbs; partialLProbs_second++; if(!empty) { recalc(dimNumber-1); counter[0]--; lProbs_ptr--; } else { terminate_search(); lcfmsv = std::numeric_limits::infinity(); } } void IsoThresholdGenerator::terminate_search() { for(int ii=0; iiget_no_confs()-1; partialLProbs[ii] = -std::numeric_limits::infinity(); } partialLProbs[dimNumber] = -std::numeric_limits::infinity(); lProbs_ptr = lProbs_ptr_start + marginalResults[0]->get_no_confs()-1; } size_t IsoThresholdGenerator::count_confs() { // Smarter algorithm forthcoming in 2.0 size_t ret = 0; while(advanceToNextConfiguration()) ret++; reset(); return ret; } void IsoThresholdGenerator::reset() { if(empty) { terminate_search(); return; } partialLProbs[dimNumber] = 0.0; memset(counter, 0, sizeof(int)*dimNumber); recalc(dimNumber-1); counter[0]--; lProbs_ptr = lProbs_ptr_start - 1; } /* * ------------------------------------------------------------------------------------------------------------------------ */ IsoOrderedGenerator::IsoOrderedGenerator(Iso&& iso, int _tabSize, int _hashSize) : IsoGenerator(std::move(iso), false), allocator(dimNumber, _tabSize) { partialLProbs = ¤tLProb; partialMasses = ¤tMass; partialProbs = ¤tProb; marginalResults = new MarginalTrek*[dimNumber]; for(int i = 0; i*[dimNumber]; masses = new const vector*[dimNumber]; marginalConfs = new const vector*[dimNumber]; for(int i = 0; iconf_masses(); logProbs[i] = &marginalResults[i]->conf_lprobs(); marginalConfs[i] = &marginalResults[i]->confs(); } topConf = allocator.newConf(); memset( reinterpret_cast(topConf) + sizeof(double), 0, sizeof(int)*dimNumber ); *(reinterpret_cast(topConf)) = combinedSum( getConf(topConf), logProbs, dimNumber ); pq.push(topConf); } IsoOrderedGenerator::~IsoOrderedGenerator() { dealloc_table(marginalResults, dimNumber); delete[] logProbs; delete[] masses; delete[] marginalConfs; partialLProbs = nullptr; partialMasses = nullptr; partialProbs = nullptr; } bool IsoOrderedGenerator::advanceToNextConfiguration() { if(pq.size() < 1) return false; topConf = pq.top(); pq.pop(); int* topConfIsoCounts = getConf(topConf); currentLProb = *(reinterpret_cast(topConf)); currentMass = combinedSum( topConfIsoCounts, masses, dimNumber ); currentProb = exp(currentLProb); ccount = -1; for(int j = 0; j < dimNumber; ++j) { if(marginalResults[j]->probeConfigurationIdx(topConfIsoCounts[j] + 1)) { if(ccount == -1) { topConfIsoCounts[j]++; *(reinterpret_cast(topConf)) = combinedSum(topConfIsoCounts, logProbs, dimNumber); pq.push(topConf); topConfIsoCounts[j]--; ccount = j; } else { void* acceptedCandidate = allocator.newConf(); int* acceptedCandidateIsoCounts = getConf(acceptedCandidate); memcpy(acceptedCandidateIsoCounts, topConfIsoCounts, confSize); acceptedCandidateIsoCounts[j]++; *(reinterpret_cast(acceptedCandidate)) = combinedSum(acceptedCandidateIsoCounts, logProbs, dimNumber); pq.push(acceptedCandidate); } } if(topConfIsoCounts[j] > 0) break; } if(ccount >=0) topConfIsoCounts[ccount]++; return true; } /* * --------------------------------------------------------------------------------------------------- */ #if !ISOSPEC_BUILDING_R void printConfigurations( const std::tuple& results, int dimNumber, int* isotopeNumbers ){ int m = 0; for(int i=0; i(results); i++){ std::cout << "Mass = " << std::get<0>(results)[i] << "\tand log-prob = " << std::get<1>(results)[i] << "\tand prob = " << exp(std::get<1>(results)[i]) << "\tand configuration =\t"; for(int j=0; j(results)[m] << " "; m++; } std::cout << '\t'; } std::cout << std::endl; } } #endif /* !ISOSPEC_BUILDING_R */ IsoLayeredGenerator::IsoLayeredGenerator( Iso&& iso, double _targetCoverage, double _percentageToExpand, int _tabSize, int _hashSize, bool trim ) : IsoGenerator(std::move(iso)), allocator(dimNumber, _tabSize), candidate(new int[dimNumber]), targetCoverage(_targetCoverage >= 1.0 ? 10000.0 : _targetCoverage), // If the user wants the entire spectrum, // give it to him - and make sure we don't terminate // early because of rounding errors percentageToExpand(_percentageToExpand), do_trim(trim), layers(0), generator_position(-1) { marginalResults = new MarginalTrek*[dimNumber]; for(int i = 0; i*[dimNumber]; masses = new const vector*[dimNumber]; marginalConfs = new const vector*[dimNumber]; for(int i = 0; iconf_masses(); logProbs[i] = &marginalResults[i]->conf_lprobs(); marginalConfs[i] = &marginalResults[i]->confs(); } void* topConf = allocator.newConf(); memset(reinterpret_cast(topConf) + sizeof(double), 0, sizeof(int)*dimNumber); *(reinterpret_cast(topConf)) = combinedSum(getConf(topConf), logProbs, dimNumber); current = new std::vector(); next = new std::vector(); current->push_back(topConf); lprobThr = (*reinterpret_cast(topConf)); if(targetCoverage > 0.0) while(advanceToNextLayer()) {}; } IsoLayeredGenerator::~IsoLayeredGenerator() { if(current != nullptr) delete current; if(next != nullptr) delete next; delete[] logProbs; delete[] masses; delete[] marginalConfs; delete[] candidate; dealloc_table(marginalResults, dimNumber); } bool IsoLayeredGenerator::advanceToNextLayer() { layers += 1; double maxFringeLprob = -std::numeric_limits::infinity(); if(current == nullptr) return false; int accepted_in_this_layer = 0; Summator prob_in_this_layer(totalProb); void* topConf; while(current->size() > 0) { topConf = current->back(); current->pop_back(); double top_lprob = getLProb(topConf); if(top_lprob >= lprobThr) { newaccepted.push_back(topConf); accepted_in_this_layer++; prob_in_this_layer.add(exp(top_lprob)); } else { next->push_back(topConf); continue; } int* topConfIsoCounts = getConf(topConf); for(int j = 0; j < dimNumber; ++j) { // candidate cannot refer to a position that is // out of range of the stored marginal distribution. if(marginalResults[j]->probeConfigurationIdx(topConfIsoCounts[j] + 1)) { memcpy(candidate, topConfIsoCounts, confSize); candidate[j]++; void* acceptedCandidate = allocator.newConf(); int* acceptedCandidateIsoCounts = getConf(acceptedCandidate); memcpy( acceptedCandidateIsoCounts, candidate, confSize); double newConfProb = combinedSum( candidate, logProbs, dimNumber ); *(reinterpret_cast(acceptedCandidate)) = newConfProb; if(newConfProb >= lprobThr) current->push_back(acceptedCandidate); else { next->push_back(acceptedCandidate); if(newConfProb > maxFringeLprob) maxFringeLprob = top_lprob; } } if(topConfIsoCounts[j] > 0) break; } } if(next == nullptr || next->size() < 1) return false; else { if(prob_in_this_layer.get() < targetCoverage) { std::vector* nnew = current; nnew->clear(); current = next; next = nnew; int howmany = floor(current->size()*percentageToExpand); lprobThr = getLProb(quickselect(current->data(), howmany, 0, current->size())); totalProb = prob_in_this_layer; } else { delete next; next = nullptr; delete current; current = nullptr; int start = 0; int end = accepted_in_this_layer - 1; void* swapspace; if(do_trim) { void** lastLayer = &(newaccepted.data()[newaccepted.size()-accepted_in_this_layer]); Summator qsprob(totalProb); while(totalProb.get() < targetCoverage) { if(start == end) break; // Partition part int len = end - start; #if ISOSPEC_BUILDING_R int pivot = len/2 + start; // We're very definitely NOT switching to R to use a RNG, and if R sees us use C RNG it complains... #else int pivot = rand() % len + start; #endif void* pval = lastLayer[pivot]; double pprob = getLProb(pval); mswap(lastLayer[pivot], lastLayer[end-1]); int loweridx = start; for(int i=start; i pprob) { mswap(lastLayer[i], lastLayer[loweridx]); loweridx++; } } mswap(lastLayer[end-1], lastLayer[loweridx]); // Selection part Summator leftProb(qsprob); for(int i=start; i<=loweridx; i++) { leftProb.add(exp(getLProb(lastLayer[i]))); } if(leftProb.get() < targetCoverage) { start = loweridx+1; qsprob = leftProb; } else end = loweridx; } int accend = newaccepted.size()-accepted_in_this_layer+start+1; totalProb = qsprob; newaccepted.resize(accend); return true; } else // No trimming { totalProb = prob_in_this_layer; return true; } } } return true; } bool IsoLayeredGenerator::advanceToNextConfiguration() { generator_position++; if(generator_position < newaccepted.size()) { partialLProbs[0] = getLProb(newaccepted[generator_position]); partialMasses[0] = combinedSum(getConf(newaccepted[generator_position]), masses, dimNumber); partialProbs[0] = exp(partialLProbs[0]); return true; } else return false; } } // namespace IsoSpec isospec-1.9.1/IsoSpec++/allocator.h0000644000175000017500000000311613373520171016744 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #include #include #include #include "conf.h" namespace IsoSpec { template inline void copyConf( const T* source, T* destination, int dim ){ memcpy(destination, source, dim*sizeof(T)); } template class Allocator{ private: T* currentTab; int currentId; const int dim, tabSize; std::vector prevTabs; public: Allocator(const int dim, const int tabSize = 10000); ~Allocator(); void shiftTables(); inline T* newConf() { currentId++; if (currentId >= tabSize) shiftTables(); return &(currentTab[ currentId * dim ]); } inline T* makeCopy(const T* conf) { T* currentPlace = newConf(); copyConf( conf, currentPlace, dim ); return currentPlace; } inline T* makeExternalCopy(const T* conf) { T* res = new T[dim]; copyConf( conf, res, dim ); return res; } }; } isospec-1.9.1/IsoSpec++/element_tables.h0000644000175000017500000000267713373520171017762 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once namespace IsoSpec { #ifdef __cplusplus extern "C" { #endif #define ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES 288 extern const int elem_table_atomicNo[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const double elem_table_probability[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const double elem_table_mass[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const int elem_table_massNo[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const int elem_table_extraNeutrons[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const char* elem_table_element[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const char* elem_table_symbol[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const bool elem_table_Radioactive[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; extern const double elem_table_log_probability[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]; #ifdef __cplusplus } #endif } // namespace IsoSpec isospec-1.9.1/IsoSpec++/marginalTrek++.cpp0000644000175000017500000003040013373520171020061 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "platform.h" #include "marginalTrek++.h" #include "conf.h" #include "allocator.h" #include "operators.h" #include "summator.h" #include "element_tables.h" #include "misc.h" namespace IsoSpec { //! Find one of the most probable subisotopologues. /*! The algorithm uses the hill-climbing algorithm. It starts from a subisotopologue close to the mean of the underlying multinomial distribution. There might be more than one modes, in case of which this function will return only one of them, close to the mean. \param atomCnt */ Conf initialConfigure(const int atomCnt, const int isotopeNo, const double* probs, const double* lprobs) { /*! Here we perform hill climbing to the mode of the marginal distribution (the subisotopologue distribution). We start from the point close to the mean of the underlying multinomial distribution. */ Conf res = new int[isotopeNo]; // This approximates the mode (heuristics: the mean is close to the mode). for(int i = 0; i < isotopeNo; ++i ) res[i] = int( atomCnt * probs[i] ) + 1; // The number of assigned atoms above. int s = 0; for(int i = 0; i < isotopeNo; ++i) s += res[i]; int diff = atomCnt - s; // Too little: enlarging fist index. if( diff > 0 ){ res[0] += diff; } // Too much: trying to redistribute the difference: hopefully the first element is the largest. if( diff < 0 ){ diff = abs(diff); int i = 0, coordDiff = 0; while( diff > 0){ coordDiff = res[i] - diff; if( coordDiff >= 0 ){ res[i] -= diff; diff = 0; } else { res[i] = 0; i++; diff = abs(coordDiff); } } } // What we computed so far will be very close to the mode: hillclimb the rest of the way bool modified = true; double LP = unnormalized_logProb(res, lprobs, isotopeNo); double NLP; while(modified) { modified = false; for(int ii = 0; ii 0) { res[ii]--; res[jj]++; NLP = unnormalized_logProb(res, lprobs, isotopeNo); if(NLP>LP || (NLP==LP && ii>jj)) { modified = true; LP = NLP; } else { res[ii]++; res[jj]--; } } } return res; } #if !ISOSPEC_BUILDING_R void printMarginal( const std::tuple& results, int dim) { for(int i=0; i(results); i++){ std::cout << "Mass = " << std::get<0>(results)[i] << " log-prob =\t" << std::get<1>(results)[i] << " prob =\t" << exp(std::get<1>(results)[i]) << "\tand configuration =\t"; for(int j=0; j(results)[i*dim + j] << " "; std::cout << std::endl; } } #endif double* getMLogProbs(const double* probs, int isoNo) { /*! Here we order the processor to round the numbers up rather than down. Rounding down could result in the algorithm falling in an infinite loop because of the numerical instability of summing. */ int curr_method = fegetround(); fesetround(FE_UPWARD); double* ret = new double[isoNo]; // here we change the table of probabilities and log it. for(int i = 0; i < isoNo; i++) { ret[i] = log(probs[i]); for(int j=0; j(_masses, _isotopeNo)), atom_lProbs(getMLogProbs(_probs, isotopeNo)), loggamma_nominator(get_loggamma_nominator(_atomCnt)), mode_conf(initialConfigure(atomCnt, isotopeNo, _probs, atom_lProbs)), mode_lprob(loggamma_nominator+unnormalized_logProb(mode_conf, atom_lProbs, isotopeNo)), mode_mass(mass(mode_conf, atom_masses, isotopeNo)), mode_prob(exp(mode_lprob)), smallest_lprob(atomCnt * *std::min_element(atom_lProbs, atom_lProbs+isotopeNo)) { try { if(ISOSPEC_G_FACT_TABLE_SIZE-1 <= atomCnt) throw std::length_error("Subisotopologue too large, size limit (that is, the maximum number of atoms of a single element in a molecule) is: " + std::to_string(ISOSPEC_G_FACT_TABLE_SIZE-1)); for(size_t ii = 0; ii < isotopeNo; ii++) if(_probs[ii] <= 0.0 || _probs[ii] > 1.0) throw std::invalid_argument("All isotope probabilities p must fulfill: 0.0 < p <= 1.0"); } catch(...) { delete[] atom_masses; delete[] atom_lProbs; delete[] mode_conf; throw; } } // the move-constructor: used in the specialization of the marginal. Marginal::Marginal(Marginal&& other) : disowned(other.disowned), isotopeNo(other.isotopeNo), atomCnt(other.atomCnt), atom_masses(other.atom_masses), atom_lProbs(other.atom_lProbs), loggamma_nominator(other.loggamma_nominator), mode_conf(other.mode_conf), mode_lprob(other.mode_lprob), mode_mass(other.mode_mass), mode_prob(other.mode_prob), smallest_lprob(other.smallest_lprob) { other.disowned = true; } Marginal::~Marginal() { if(!disowned) { delete[] atom_masses; delete[] atom_lProbs; delete[] mode_conf; } } double Marginal::getLightestConfMass() const { double ret_mass = std::numeric_limits::infinity(); for(unsigned int ii=0; ii < isotopeNo; ii++) if( ret_mass > atom_masses[ii] ) ret_mass = atom_masses[ii]; return ret_mass*atomCnt; } double Marginal::getHeaviestConfMass() const { double ret_mass = 0.0; for(unsigned int ii=0; ii < isotopeNo; ii++) if( ret_mass < atom_masses[ii] ) ret_mass = atom_masses[ii]; return ret_mass*atomCnt; } // this is roughly an equivalent of IsoSpec-Threshold-Generator MarginalTrek::MarginalTrek( Marginal&& m, int tabSize, int hashSize ) : Marginal(std::move(m)), current_count(0), keyHasher(isotopeNo), equalizer(isotopeNo), orderMarginal(atom_lProbs, isotopeNo), visited(hashSize,keyHasher,equalizer), pq(orderMarginal), totalProb(), candidate(new int[isotopeNo]), allocator(isotopeNo, tabSize) { int* initialConf = allocator.makeCopy(mode_conf); pq.push(initialConf); visited[initialConf] = 0; totalProb = Summator(); current_count = 0; add_next_conf(); } bool MarginalTrek::add_next_conf() { /*! Add next configuration. If visited all, return false. */ if(pq.size() < 1) return false; Conf topConf = pq.top(); pq.pop(); ++current_count; visited[topConf] = current_count; _confs.push_back(topConf); _conf_masses.push_back(mass(topConf, atom_masses, isotopeNo)); double logprob = logProb(topConf); _conf_lprobs.push_back(logprob); totalProb.add( exp( logprob ) ); for( unsigned int i = 0; i < isotopeNo; ++i ) { for( unsigned int j = 0; j < isotopeNo; ++j ) { // Growing index different than decreasing one AND // Remain on simplex condition. if( i != j && topConf[j] > 0 ){ copyConf(topConf, candidate, isotopeNo); ++candidate[i]; --candidate[j]; // candidate should not have been already visited. if( visited.count( candidate ) == 0 ) { Conf acceptedCandidate = allocator.makeCopy(candidate); pq.push(acceptedCandidate); visited[acceptedCandidate] = 0; } } } } return true; } int MarginalTrek::processUntilCutoff(double cutoff) { Summator s; int last_idx = -1; for(unsigned int i=0; i<_conf_lprobs.size(); i++) { s.add(_conf_lprobs[i]); if(s.get() >= cutoff) { last_idx = i; break; } } if(last_idx > -1) return last_idx; while(totalProb.get() < cutoff && add_next_conf()) {} return _conf_lprobs.size(); } MarginalTrek::~MarginalTrek() { delete[] candidate; } PrecalculatedMarginal::PrecalculatedMarginal(Marginal&& m, double lCutOff, bool sort, int tabSize, int hashSize ) : Marginal(std::move(m)), allocator(isotopeNo, tabSize) { const ConfEqual equalizer(isotopeNo); const KeyHasher keyHasher(isotopeNo); const ConfOrderMarginalDescending orderMarginal(atom_lProbs, isotopeNo); std::unordered_set visited(hashSize,keyHasher,equalizer); Conf currentConf = allocator.makeCopy(mode_conf); if(logProb(currentConf) >= lCutOff) { // create a copy and store a ptr to the *same* copy in both structures // (save some space and time) auto tmp = allocator.makeCopy(currentConf); configurations.push_back(tmp); visited.insert(tmp); } unsigned int idx = 0; while(idx < configurations.size()) { memcpy(currentConf, configurations[idx], sizeof(int)*isotopeNo); idx++; for(unsigned int ii = 0; ii < isotopeNo; ii++ ) for(unsigned int jj = 0; jj < isotopeNo; jj++ ) if( ii != jj && currentConf[jj] > 0) { currentConf[ii]++; currentConf[jj]--; if (visited.count(currentConf) == 0 && logProb(currentConf) >= lCutOff) { // create a copy and store a ptr to the *same* copy in // both structures (save some space and time) auto tmp = allocator.makeCopy(currentConf); visited.insert(tmp); configurations.push_back(tmp); // std::cout << " V: "; for (auto it : visited) std::cout << it << " "; std::cout << std::endl; } currentConf[ii]--; currentConf[jj]++; } } // orderMarginal defines the order of configurations (compares their logprobs) // akin to key in Python sort. if(sort) std::sort(configurations.begin(), configurations.end(), orderMarginal); confs = &configurations[0]; no_confs = configurations.size(); lProbs = new double[no_confs+1]; probs = new double[no_confs]; masses = new double[no_confs]; for(unsigned int ii=0; ii < no_confs; ii++) { lProbs[ii] = logProb(confs[ii]); probs[ii] = exp(lProbs[ii]); masses[ii] = mass(confs[ii], atom_masses, isotopeNo); } lProbs[no_confs] = -std::numeric_limits::infinity(); } PrecalculatedMarginal::~PrecalculatedMarginal() { if(lProbs != nullptr) delete[] lProbs; if(masses != nullptr) delete[] masses; if(probs != nullptr) delete[] probs; } } // namespace IsoSpec isospec-1.9.1/IsoSpec++/tabulator.h0000644000175000017500000000647513373520171016774 0ustar rusconirusconi#pragma once #include #include "isoSpec++.h" #define ISOSPEC_INIT_TABLE_SIZE 1024 namespace IsoSpec { template class Tabulator { private: double* _masses; double* _lprobs; double* _probs; int* _confs; size_t _confs_no; public: Tabulator(T* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs); ~Tabulator(); inline double* masses(bool release = false) { double* ret = _masses; if(release) _masses = nullptr; return ret; }; inline double* lprobs(bool release = false) { double* ret = _lprobs; if(release) _lprobs = nullptr; return ret; }; inline double* probs(bool release = false) { double* ret = _probs; if(release) _probs = nullptr; return ret; }; inline int* confs(bool release = false) { int* ret = _confs; if(release) _confs = nullptr; return ret; }; inline size_t confs_no() { return _confs_no; }; }; inline void reallocate(double **array, int new_size){ if( *array != nullptr ){ *array = (double *) realloc(*array, new_size); } } template Tabulator::Tabulator(T* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs ) { size_t current_size = ISOSPEC_INIT_TABLE_SIZE; int confs_tbl_idx = 0; _confs_no = 0; const int allDimSizeOfInt = sizeof(int)*generator->getAllDim(); _masses = get_masses ? (double *) malloc(ISOSPEC_INIT_TABLE_SIZE * sizeof(double)) : nullptr; _lprobs = get_lprobs ? (double *) malloc(ISOSPEC_INIT_TABLE_SIZE * sizeof(double)) : nullptr; _probs = get_probs ? (double *) malloc(ISOSPEC_INIT_TABLE_SIZE * sizeof(double)) : nullptr; _confs = get_confs ? (int *) malloc(ISOSPEC_INIT_TABLE_SIZE * allDimSizeOfInt): nullptr; while(generator->advanceToNextConfiguration()){ if( _confs_no == current_size ) { current_size *= 2; // FIXME: Handle overflow gracefully here. It definitely could happen for people still stuck on 32 bits... reallocate(&_masses, current_size * sizeof(double)); reallocate(&_lprobs, current_size * sizeof(double)); reallocate(&_probs, current_size * sizeof(double)); if( _confs != nullptr ){ _confs = (int *) realloc(_confs, current_size * allDimSizeOfInt); } } if(_masses != nullptr) _masses[_confs_no] = generator->mass(); if(_lprobs != nullptr) _lprobs[_confs_no] = generator->lprob(); if(_probs != nullptr) _probs[_confs_no] = generator->prob(); if(_confs != nullptr){ generator->get_conf_signature(_confs + confs_tbl_idx); confs_tbl_idx += generator->getAllDim(); } _confs_no++; } _masses = (double *) realloc(_masses, _confs_no * sizeof(double)); _lprobs = (double *) realloc(_lprobs, _confs_no * sizeof(double)); _probs = (double *) realloc(_probs, _confs_no * sizeof(double)); _confs = (int *) realloc(_confs, confs_tbl_idx * sizeof(int)); } template Tabulator::~Tabulator() { if( _masses != nullptr ) free(_masses); if( _lprobs != nullptr ) free(_lprobs); if( _probs != nullptr ) free(_probs); if( _confs != nullptr ) free(_confs); } } // namespace IsoSpec isospec-1.9.1/IsoSpec++/dirtyAllocator.h0000644000175000017500000000313313373520171017757 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #include #include #include namespace IsoSpec { class DirtyAllocator{ private: void* currentTab; void* currentConf; void* endOfTablePtr; const int tabSize; int cellSize; std::vector prevTabs; public: DirtyAllocator(const int dim, const int tabSize = 10000); ~DirtyAllocator(); void shiftTables(); inline void* newConf() { if (currentConf >= endOfTablePtr) { shiftTables(); } void* ret = currentConf; currentConf = reinterpret_cast(currentConf) + cellSize; return ret; } inline void* makeCopy(const void* conf) { void* currentPlace = newConf(); memcpy(currentPlace, conf, cellSize); return currentPlace; } inline void* makeExternalCopy(const void* conf) { void* res = malloc(cellSize); memcpy(res, conf, cellSize); return res; } }; } // namespace IsoSpec isospec-1.9.1/IsoSpec++/IsoSpecConfig.cmake.in0000644000175000017500000000130613373520171020714 0ustar rusconirusconi# Create imported target IsoSpec # adapted from http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file#The_FooBar.2FFooBarBuildTreeSettings.cmake.in_file # Compute paths get_filename_component(ISOSPEC_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) if(EXISTS "${ISOSPEC_CMAKE_DIR}/CMakeCache.txt") # In build tree set(ISOSPEC_INCLUDE_DIRS "@PROJECT_SOURCE_DIR@/") else() set(ISOSPEC_INCLUDE_DIRS "${ISOSPEC_CMAKE_DIR}/@CONF_REL_INCLUDE_DIR@") endif() # Our library dependencies (contains definitions for IMPORTED targets) include("${ISOSPEC_CMAKE_DIR}/IsoSpecLibrary.cmake") # These are IMPORTED targets created by IsoSpecLibrary.cmake set(ISOSPEC_LIBRARIES IsoSpec) isospec-1.9.1/IsoSpec++/allocator.cpp0000644000175000017500000000227513373520171017304 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include #include "allocator.h" namespace IsoSpec { template Allocator::Allocator(const int dim, const int tabSize): currentId(-1), dim(dim), tabSize(tabSize) { currentTab = new T[dim * tabSize]; } template Allocator::~Allocator() { for(unsigned int i = 0; i < prevTabs.size(); ++i) { delete [] prevTabs[i]; } delete [] currentTab; } template void Allocator::shiftTables() { prevTabs.push_back(currentTab); currentTab = new T[dim * tabSize]; currentId = 0; } template class Allocator; } isospec-1.9.1/IsoSpec++/isoMath.h0000644000175000017500000000261313373520171016371 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #include #include #if !defined(ISOSPEC_G_FACT_TABLE_SIZE) // 10M should be enough for anyone, right? // Actually, yes. If anyone tries to input a molecule that has more than 10M atoms, // he deserves to get an exception thrown in his face. #define ISOSPEC_G_FACT_TABLE_SIZE 1024*1024*10 #endif namespace IsoSpec { extern double* g_lfact_table; static inline double minuslogFactorial(int n) { if (n < 2) return 0.0; if (g_lfact_table[n] == 0.0) g_lfact_table[n] = -lgamma(n+1); return g_lfact_table[n]; } double NormalCDFInverse(double p); double NormalCDFInverse(double p, double mean, double stdev); double NormalCDF(double x, double mean, double stdev); double NormalPDF(double x, double mean = 0.0, double stdev = 1.0); } // namespace IsoSpec isospec-1.9.1/IsoSpec++/marginalTrek++.h0000644000175000017500000002574713373520171017550 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #include #include #include #include #include "conf.h" #include "allocator.h" #include "operators.h" #include "summator.h" namespace IsoSpec { Conf initialConfigure(int atomCnt, int isotopeNo, const double* probs); void printMarginal(const std::tuple& results, int dim); //! The marginal distribution class (a subisotopologue). /*! This class mostly provides some basic common API for subclasses, but itself is not abstract. This class represents the probability distribution generated by one element only -- a subisotopologue. For instance, it might be the distribution of C200, that might be part of, say, C200H402. It corresponds to the multinomial distribution, where each configuration can also be attributed a precise mass. The constructor method perform initial hill-climbing to find the most probable sub-isotopologue (the mode). */ class Marginal { private: bool disowned; protected: const unsigned int isotopeNo; /*!< The number of isotopes of the given element. */ const unsigned int atomCnt; /*!< The number of atoms of the given element. */ const double* const atom_masses; /*!< Table of atomic masses of all the isotopeNo isotopes. */ const double* const atom_lProbs; /*!< Table of log-probabilities of all the isotopeNo isotopes. */ const double loggamma_nominator; /*!< The constant nominator that appears in the expressions for the multinomial probabilities. */ const Conf mode_conf; /*!< A subisotopologue with most probability. If not unique, one of the representatives of that class of subisotopologues. */ const double mode_lprob; /*!< The log-probability of the mode subisotopologue.*/ const double mode_mass; /*!< The mass of the mode subisotopologue.*/ const double mode_prob; /*!< The probability of the mode subisotopologue.*/ const double smallest_lprob; /*!< The smallest-achievable log-probability in the distribution of subisotopologues. */ public: //! Class constructor. /*! \param _masses A table of masses of the stable isotopes of the investigated element, e.g. for C10 it is 2: C12 and C13. \param _probs A table of natural frequencies of the stable isotopes of the investigated element, see IUPAC at https://iupac.org/isotopesmatter/ \param _isotopeNo Number of isotopes of a given element. \param _atomCnt The number of atoms of the given element, e.g. 10 for C10. \return An instance of the Marginal class. */ Marginal( const double* _masses, // masses size = logProbs size = isotopeNo const double* _probs, int _isotopeNo, int _atomCnt ); // Get rid of the C++ generated copy and assignment constructors. Marginal(Marginal& other) = delete; Marginal& operator= (const Marginal& other) = delete; //! Move constructor. Marginal(Marginal&& other); //! Destructor. virtual ~Marginal(); //! Get the number of isotopes of the investigated element. /*! \return The integer number of isotopes of the investigated element. */ inline int get_isotopeNo() const { return isotopeNo; }; //! Get the mass of the lightest subisotopologue. /*! This is trivially obtained by considering all atomNo atoms to be the lightest isotope possible. \return The mass of the lightiest subisotopologue. */ double getLightestConfMass() const; //! Get the mass of the heaviest subisotopologue. /*! This is trivially obtained by considering all atomNo atoms to be the heaviest isotope possible. \return The mass of the heaviest subisotopologue. */ double getHeaviestConfMass() const; //! Get the log-probability of the mode subisotopologue. /*! \return The log-probability of a/the most probable subisotopologue. */ inline double getModeLProb() const { return mode_lprob; }; //! The the mass of the mode subisotopologue. /*! \return The mass of one of the most probable subisotopologues. */ inline double getModeMass() const { return mode_mass; }; //! The the probability of the mode subisotopologue. /*! \return The probability of a/the most probable subisotopologue. */ inline double getModeProb() const { return mode_prob; }; //! The the log-probability of the lightest subisotopologue. /*! \return The logarithm of the smallest non-zero probability of a subisotopologue. */ inline double getSmallestLProb() const { return smallest_lprob; }; //! Calculate the log-probability of a given subisotopologue. /*! \param conf A subisotopologue (a table of integers describing subsequent isotope-counts). \return The log-probability of the input subisotopologue. */ inline double logProb(Conf conf) const { return loggamma_nominator + unnormalized_logProb(conf, atom_lProbs, isotopeNo); }; }; //! The marginal distribution class (a subisotopologue). class MarginalTrek : public Marginal { private: int current_count; const KeyHasher keyHasher; const ConfEqual equalizer; const ConfOrderMarginal orderMarginal; std::unordered_map visited; std::priority_queue,ConfOrderMarginal> pq; Summator totalProb; Conf candidate; Allocator allocator; std::vector _conf_lprobs; std::vector _conf_masses; std::vector _confs; //! Proceed to the next configuration and memoize it (as it will be surely needed). bool add_next_conf(); public: //! Move constructor: specializes the Marginal class. /*! \param tabSize The size of the table used to store configurations in the allocator. \param hashSize The size of the hash table used to store visited subisotopologues. */ MarginalTrek( Marginal&& m, int tabSize = 1000, int hashSize = 1000 ); //! Check if the table of computed subisotopologues does not have to be extended. /*! This function checks if the idx-th most probable subisotopologue was memoized and if not, computes it and memoizes it. \param idx The number of the idx-th most probable subisotopologue. \return Returns false if it the provided idx exceeds the total number of subisotopologues. */ inline bool probeConfigurationIdx(int idx) { while(current_count <= idx) if(!add_next_conf()) return false; return true; } //! Calculate subisotopologues with probability above or equal to the cut-off. /*! \param cutoff The probability cut-off \return The number of the last subisotopologue above the cut-off. */ int processUntilCutoff(double cutoff); inline const std::vector& conf_lprobs() const { return _conf_lprobs; }; inline const std::vector& conf_masses() const { return _conf_masses; }; inline const std::vector& confs() const { return _confs; }; virtual ~MarginalTrek(); }; //! Precalculated Marginal class /*! This class serves to calculate a set of isotopologues that is defined by the minimal probability threshold. This works faster than if you did not know the threshold. If you have no idea about the threshold, you would need to call us, to change encode the layered version of the marginal. */ class PrecalculatedMarginal : public Marginal { protected: std::vector configurations; Conf* confs; unsigned int no_confs; double* masses; double* lProbs; double* probs; Allocator allocator; public: //! The move constructor (disowns the Marginal). /*! This constructor memoizes all subisotopologues with log-probability above the provided threshold lCutOff \param Marginal An instance of the Marginal class this class is about to disown. \param lCutOff The lower limit on the log-probability of the precomputed subisotopologues. \param sort Should the subisotopologues be stored with descending probability ? \return An instance of the PrecalculatedMarginal class. */ PrecalculatedMarginal( Marginal&& m, double lCutOff, bool sort = true, int tabSize = 1000, int hashSize = 1000 ); //! Destructor. virtual ~PrecalculatedMarginal(); //! Is there a subisotopologue with a given number? /*! \return Returns true if idx does not exceed the number of pre-computed configurations. */ inline bool inRange(unsigned int idx) const { return idx < no_confs; }; //! Get the log-probability of the idx-th subisotopologue. /*! \param idx The number of the considered subisotopologue. \return The log-probability of the idx-th subisotopologue. */ inline const double& get_lProb(int idx) const { return lProbs[idx]; }; //! Get the probability of the idx-th subisotopologue. /*! \param idx The number of the considered subisotopologue. \return The probability of the idx-th subisotopologue. */ inline const double& get_prob(int idx) const { return probs[idx]; }; //! Get the mass of the idx-th subisotopologue. /*! \param idx The number of the considered subisotopologue. \return The mass of the idx-th subisotopologue. */ inline const double& get_mass(int idx) const { return masses[idx]; }; //! Get the table of the log-probabilities of subisotopologues. /*! \return Pointer to the first element in the table storing log-probabilities of subisotopologues. */ inline const double* get_lProbs_ptr() const { return lProbs; }; //! Get the table of the masses of subisotopologues. /*! \return Pointer to the first element in the table storing masses of subisotopologues. */ inline const double* get_masses_ptr() const { return masses; }; //! Get the counts of isotopes that define the subisotopologue. /*! \param idx The number of the considered subisotopologue. \return The counts of isotopes that define the subisotopologue. */ inline const Conf& get_conf(int idx) const { return confs[idx]; }; //! Get the number of precomputed subisotopologues. /*! \return The number of precomputed subisotopologues. */ inline unsigned int get_no_confs() const { return no_confs; }; }; } // namespace IsoSpec isospec-1.9.1/IsoSpec++/cwrapper.cpp0000644000175000017500000001622713373520171017151 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include #include #include #include #include #include "cwrapper.h" #include "misc.h" #include "marginalTrek++.h" #include "isoSpec++.h" #include "tabulator.h" using namespace IsoSpec; extern "C" { void * setupIso(int dimNumber, const int* isotopeNumbers, const int* atomCounts, const double* isotopeMasses, const double* isotopeProbabilities) { const double** IM = new const double*[dimNumber]; const double** IP = new const double*[dimNumber]; int idx = 0; for(int i=0; i(iso); } void deleteIso(void* iso) { delete reinterpret_cast(iso); } #define ISOSPEC_C_FN_CODE(generatorType, dataType, method)\ dataType method##generatorType(void* generator){ return reinterpret_cast(generator)->method(); } #define ISOSPEC_C_FN_CODE_GET_CONF_SIGNATURE(generatorType)\ void get_conf_signature##generatorType(void* generator, int* space)\ { reinterpret_cast(generator)->get_conf_signature(space); } #define ISOSPEC_C_FN_DELETE(generatorType) void delete##generatorType(void* generator){ delete reinterpret_cast(generator); } #define ISOSPEC_C_FN_CODES(generatorType)\ ISOSPEC_C_FN_CODE(generatorType, double, mass) \ ISOSPEC_C_FN_CODE(generatorType, double, lprob) \ ISOSPEC_C_FN_CODE(generatorType, double, prob) \ ISOSPEC_C_FN_CODE_GET_CONF_SIGNATURE(generatorType) \ ISOSPEC_C_FN_CODE(generatorType, bool, advanceToNextConfiguration) \ ISOSPEC_C_FN_DELETE(generatorType) //______________________________________________________THRESHOLD GENERATOR void* setupIsoThresholdGenerator(void* iso, double threshold, bool _absolute, int _tabSize, int _hashSize) { IsoThresholdGenerator* iso_tmp = new IsoThresholdGenerator( std::move(*reinterpret_cast(iso)), threshold, _absolute, _tabSize, _hashSize); return reinterpret_cast(iso_tmp); } ISOSPEC_C_FN_CODES(IsoThresholdGenerator) //______________________________________________________LAYERED GENERATOR void* setupIsoLayeredGenerator(void* iso, double _target_coverage, double _percentage_to_expand, int _tabSize, int _hashSize, bool _do_trim) { IsoLayeredGenerator* iso_tmp = new IsoLayeredGenerator( std::move(*reinterpret_cast(iso)), _target_coverage, _percentage_to_expand, _tabSize, _hashSize, _do_trim); return reinterpret_cast(iso_tmp); } ISOSPEC_C_FN_CODES(IsoLayeredGenerator) //______________________________________________________ORDERED GENERATOR void* setupIsoOrderedGenerator(void* iso, int _tabSize, int _hashSize) { IsoOrderedGenerator* iso_tmp = new IsoOrderedGenerator( std::move(*reinterpret_cast(iso)), _tabSize, _hashSize); return reinterpret_cast(iso_tmp); } ISOSPEC_C_FN_CODES(IsoOrderedGenerator) //______________________________________________________ Threshold Tabulator void* setupThresholdTabulator(void* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs) { Tabulator* tabulator = new Tabulator(reinterpret_cast(generator), get_masses, get_probs, get_lprobs, get_confs); return reinterpret_cast(tabulator); } void deleteThresholdTabulator(void* t) { delete reinterpret_cast*>(t); } const double* massesThresholdTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->masses(true); } const double* lprobsThresholdTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->lprobs(true); } const double* probsThresholdTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->probs(true); } const int* confsThresholdTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->confs(true); } int confs_noThresholdTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->confs_no(); } //______________________________________________________ Layered Tabulator void* setupLayeredTabulator(void* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs) { Tabulator* tabulator = new Tabulator(reinterpret_cast(generator), get_masses, get_probs, get_lprobs, get_confs); return reinterpret_cast(tabulator); } void deleteLayeredTabulator(void* t) { delete reinterpret_cast*>(t); } const double* massesLayeredTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->masses(true); } const double* lprobsLayeredTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->lprobs(true); } const double* probsLayeredTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->probs(true); } const int* confsLayeredTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->confs(true); } int confs_noLayeredTabulator(void* tabulator) { return reinterpret_cast*>(tabulator)->confs_no(); } void freeReleasedArray(void* array) { free(array); } } //extern "C" ends here isospec-1.9.1/IsoSpec++/summator.h0000644000175000017500000000435713373520171016643 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #include #include namespace IsoSpec { class SSummator { // Shewchuk algorithm std::vector partials; int maxpart; public: inline SSummator() { maxpart = 0; } inline SSummator(SSummator& other) { this->partials = other.partials; this->maxpart = other.maxpart; } inline void add(double x) { unsigned int i=0; for(int pidx=0; pidx. */ #pragma once #include #include #include #include #include "platform.h" #include "dirtyAllocator.h" #include "summator.h" #include "operators.h" #include "marginalTrek++.h" #if ISOSPEC_BUILDING_R #include using namespace Rcpp; #endif /* ISOSPEC_BUILDING_R */ namespace IsoSpec { // This function is NOT guaranteed to be secure against malicious input. It should be used only for debugging. unsigned int parse_formula(const char* formula, std::vector& isotope_masses, std::vector& isotope_probabilities, int** isotopeNumbers, int** atomCounts, unsigned int* confSize); //! The Iso class for the calculation of the isotopic distribution. /*! It contains full description of the molecule for which one would like to calculate the isotopic distribution. */ class ISOSPEC_EXPORT_SYMBOL Iso { private: //! Set up the marginal isotopic envelopes, corresponding to subisotopologues. /*! \param _isotopeMasses A table of masses of isotopes of the elements in the chemical formula, e.g. {12.0, 13.003355, 1.007825, 2.014102} for C100H202. \param _isotopeProbabilities A table of isotope frequencies of the elements in the chemical formula, e.g. {.989212, .010788, .999885, .000115} for C100H202. */ void setupMarginals(const double* const * _isotopeMasses, const double* const * _isotopeProbabilities); public: bool disowned; /*!< A variable showing if the Iso class was specialized by its child-class. If so, then the description of the molecules has been transfered there and Iso is a carcass class, dead as a dodo, an ex-class if you will. */ protected: int dimNumber; /*!< The number of elements in the chemical formula of the molecule. */ int* isotopeNumbers; /*!< A table with numbers of isotopes for each element. */ int* atomCounts; /*!< A table with numbers of isotopes for each element. */ unsigned int confSize; /*!< The number of bytes needed to represent the counts of isotopes present in the extended chemical formula. */ int allDim; /*!< The total number of isotopes of elements present in a chemical formula, e.g. for H20 it is 2+3=5. */ Marginal** marginals; /*!< The table of pointers to the distributions of individual subisotopologues. */ double modeLProb; /*!< The log-probability of the mode of the isotopic distribution. */ public: //! General constructror. /*! \param _dimNumber The number of elements in the formula, e.g. for C100H202 it would be 2, as there are only carbon and hydrogen atoms. \param _isotopeNumbers A table with numbers of isotopes for each element, e.g. for C100H202 it would be {2, 2}, because both C and H have two stable isotopes. \param _atomCounts Number of atoms of each element in the formula, e.g. for C100H202 corresponds to {100, 202}. \param _isotopeMasses A table of masses of isotopes of the elements in the chemical formula, e.g. {12.0, 13.003355, 1.007825, 2.014102} for C100H202. \param _isotopeProbabilities A table of isotope frequencies of the elements in the chemical formula, e.g. {.989212, .010788, .999885, .000115} for C100H202. */ Iso( int _dimNumber, const int* _isotopeNumbers, const int* _atomCounts, const double* const * _isotopeMasses, const double* const * _isotopeProbabilities ); //! Constructor from the formula object. Iso(const char* formula); //! The move constructor. Iso(Iso&& other); //! The copy constructor. /*! \param other The other instance of the Iso class. \param fullcopy If false, copy only the number of atoms in the formula, the size of the configuration, the total number of isotopes, and the probability of the mode isotopologue. */ Iso(const Iso& other, bool fullcopy); //! Destructor. virtual ~Iso(); //! Get the mass of the lightest peak in the isotopic distribution. double getLightestPeakMass() const; //! Get the mass of the heaviest peak in the isotopic distribution. double getHeaviestPeakMass() const; //! Get the log-probability of the mode-configuration (if there are many modes, they share this value). inline double getModeLProb() const { return modeLProb; }; //! Get the number of elements in the chemical formula of the molecule. inline int getDimNumber() const { return dimNumber; }; //! Get the total number of isotopes of elements present in a chemical formula. inline int getAllDim() const { return allDim; }; }; //! The generator of isotopologues. /*! This class provides the common interface for all isotopic generators. */ class ISOSPEC_EXPORT_SYMBOL IsoGenerator : public Iso { protected: double* partialLProbs; /*!< The prefix sum of the log-probabilities of the current isotopologue. */ double* partialMasses; /*!< The prefix sum of the masses of the current isotopologue. */ double* partialProbs;/*!< The prefix product of the probabilities of the current isotopologue. */ public: //! Advance to the next, not yet visited, most probable isotopologue. /*! \return Return false if it is not possible to advance. */ virtual bool advanceToNextConfiguration() = 0; //! Get the log-probability of the current isotopologue. /*! \return The log-probability of the current isotopologue. */ virtual double lprob() const { return partialLProbs[0]; }; //! Get the mass of the current isotopologue. /*! \return The mass of the current isotopologue. */ virtual double mass() const { return partialMasses[0]; }; //! Get the probability of the current isotopologue. /*! \return The probability of the current isotopologue. */ virtual double prob() const { return partialProbs[0]; }; //TODO: what is this??? virtual void get_conf_signature(int* space) const = 0; //! Move constructor. IsoGenerator(Iso&& iso, bool alloc_partials = true); //! Destructor. virtual ~IsoGenerator(); }; //! The generator of isotopologues sorted by their probability of occurrence. /*! The subsequent isotopologues are generated with diminishing probability, starting from the mode. This algorithm take O(N*log(N)) to compute the N isotopologues because of using the Priority Queue data structure. Obtaining the N isotopologues can be achieved in O(N) if they are not required to be spit out in the descending order. */ class ISOSPEC_EXPORT_SYMBOL IsoOrderedGenerator: public IsoGenerator { private: MarginalTrek** marginalResults; /*!< Table of pointers to marginal distributions of subisotopologues. */ std::priority_queue,ConfOrder> pq; /*!< The priority queue used to generate isotopologues ordered by descending probability. */ void* topConf; /*!< Most probable configuration. */ DirtyAllocator allocator; /*!< Structure used for alocating memory for isotopologues. */ const std::vector** logProbs; /*!< Obtained log-probabilities. */ const std::vector** masses; /*!< Obtained masses. */ const std::vector** marginalConfs; /*!< Obtained counts of isotopes. */ double currentLProb; /*!< The log-probability of the current isotopologue. */ double currentMass; /*!< The mass of the current isotopologue. */ double currentProb; /*!< The probability of the current isotopologue. */ int ccount; public: bool advanceToNextConfiguration() override final; //! Save the counts of isotopes in the space. /*! \param space An array where counts of isotopes shall be written. Must be as big as the overall number of isotopes. */ inline void get_conf_signature(int* space) const override final { int* c = getConf(topConf); if (ccount >= 0) c[ccount]--; for(int ii=0; iiconfs()[c[ii]], isotopeNumbers[ii]*sizeof(int)); space += isotopeNumbers[ii]; } if (ccount >= 0) c[ccount]++; }; //! The move-contstructor. IsoOrderedGenerator(Iso&& iso, int _tabSize = 1000, int _hashSize = 1000); //! Destructor. virtual ~IsoOrderedGenerator(); }; //! The generator of isotopologues above a given threshold value. /*! Attention: the calculated configurations are only partially ordeded and the user should not assume they will be ordered. This algorithm computes N isotopologues in O(N). It is a considerable advantage w.r.t. the IsoOrderedGenerator. */ class ISOSPEC_EXPORT_SYMBOL IsoThresholdGenerator: public IsoGenerator { private: int* counter; /*!< An array storing the position of an isotopologue in terms of the subisotopologues ordered by decreasing probability. */ double* maxConfsLPSum; const double Lcutoff; /*!< The logarithm of the lower bound on the calculated probabilities. */ PrecalculatedMarginal** marginalResults; PrecalculatedMarginal** marginalResultsUnsorted; int* marginalOrder; const double* lProbs_ptr; const double* lProbs_ptr_start; double* partialLProbs_second; double partialLProbs_second_val, lcfmsv; bool empty; public: inline void get_conf_signature(int* space) const override final { counter[0] = lProbs_ptr - lProbs_ptr_start; if(marginalOrder != nullptr) for(int ii=0; iiget_conf(counter[jj]), isotopeNumbers[ii]*sizeof(int)); space += isotopeNumbers[ii]; } else for(int ii=0; iiget_conf(counter[ii]), isotopeNumbers[ii]*sizeof(int)); space += isotopeNumbers[ii]; } }; //! The move-constructor. /*! \param iso An instance of the Iso class. \param _threshold The threshold value. \param _absolute If true, the _threshold is interpreted as the absolute minimal peak height for the isotopologues. If false, the _threshold is the fraction of the heighest peak's probability. \param tabSize The size of the extension of the table with configurations. \param hashSize The size of the hash-table used to store subisotopologues and check if they have been already calculated. */ IsoThresholdGenerator(Iso&& iso, double _threshold, bool _absolute=true, int _tabSize=1000, int _hashSize=1000, bool reorder_marginals = true); inline ~IsoThresholdGenerator() { delete[] counter; delete[] maxConfsLPSum; if (marginalResultsUnsorted != marginalResults) delete[] marginalResultsUnsorted; dealloc_table(marginalResults, dimNumber); if(marginalOrder != nullptr) delete[] marginalOrder; }; // Perform highly aggressive inling as this function is often called as while(advanceToNextConfiguration()) {} // which leads to an extremely tight loop and some compilers miss this (potentially due to the length of the function). ISOSPEC_FORCE_INLINE bool advanceToNextConfiguration() override final { lProbs_ptr++; if(ISOSPEC_LIKELY(*lProbs_ptr >= lcfmsv)) { return true; } // If we reached this point, a carry is needed int idx = 0; lProbs_ptr = lProbs_ptr_start; int * cntr_ptr = counter; while(idxget_lProb(counter[idx]); if(partialLProbs[idx] + maxConfsLPSum[idx-1] >= Lcutoff) { partialMasses[idx] = partialMasses[idx+1] + marginalResults[idx]->get_mass(counter[idx]); partialProbs[idx] = partialProbs[idx+1] * marginalResults[idx]->get_prob(counter[idx]); recalc(idx-1); return true; } } terminate_search(); return false; } ISOSPEC_FORCE_INLINE double lprob() const override final { return partialLProbs_second_val + (*(lProbs_ptr)); }; ISOSPEC_FORCE_INLINE double mass() const override final { return partialMasses[1] + marginalResults[0]->get_mass(lProbs_ptr - lProbs_ptr_start); }; ISOSPEC_FORCE_INLINE double prob() const override final { return partialProbs[1] * marginalResults[0]->get_prob(lProbs_ptr - lProbs_ptr_start); }; //! Block the subsequent search of isotopologues. void terminate_search(); /*! Reset the generator to the beginning of the sequence. Allows it to be reused, eg. to go through the conf space once, calculate the amount of space needed to store configurations, then to allocate that memory, and go through it again, this time saving configurations (and *is* in fact faster than allocating a std::vector and depending on it to grow as needed. This is cheaper than throwing away the generator and making a new one too: marginal distributions don't need to be recalculated. */ void reset(); /*! Count the number of configurations in the distribution. This can be used to pre-allocate enough memory to store it (e.g. * std::vector's reserve() method - this is faster than depending on the vector's dynamic resizing, even though it means that * the configuration space is walked through twice. This method has to be called before the first call to advanceToNextConfiguration * and has undefined results (incl. segfaults) otherwise. */ size_t count_confs(); private: //! Recalculate the current partial log-probabilities, masses, and probabilities. ISOSPEC_FORCE_INLINE void recalc(int idx) { for(; idx > 0; idx--) { partialLProbs[idx] = partialLProbs[idx+1] + marginalResults[idx]->get_lProb(counter[idx]); partialMasses[idx] = partialMasses[idx+1] + marginalResults[idx]->get_mass(counter[idx]); partialProbs[idx] = partialProbs[idx+1] * marginalResults[idx]->get_prob(counter[idx]); } partialLProbs_second_val = *partialLProbs_second; partialLProbs[0] = *partialLProbs_second + marginalResults[0]->get_lProb(counter[0]); lcfmsv = Lcutoff - partialLProbs_second_val; } }; //! The class that represents isotopologues above a given joint probability value. /*! This class generates subsequent isotopologues that ARE NOT GUARANTEED TO BE ORDERED BY probability. The overal set of isotopologues is guaranteed to surpass a given threshold of probability contained in the isotopic distribution. This calculations are performed in O(N) operations, where N is the total number of the output isotopologues. This class is not a true generator yet - the generator methods have been implemented for compatibility, but the class actually performs all computations during the initialization and stores them, and the generator methods only walk through the array of precomputed values. . It will be reimplemented as a true generator in 2.0. */ class ISOSPEC_EXPORT_SYMBOL IsoLayeredGenerator : public IsoGenerator { private: Summator totalProb; std::vector newaccepted; DirtyAllocator allocator; int* candidate; const std::vector** logProbs; /*!< Obtained log-probabilities. */ const std::vector** masses; /*!< Obtained masses. */ const std::vector** marginalConfs; /*!< Obtained counts of isotopes. */ MarginalTrek** marginalResults; std::vector* current; std::vector* next; double lprobThr; double targetCoverage; double percentageToExpand; bool do_trim; int layers; size_t generator_position; bool advanceToNextLayer(); public: bool advanceToNextConfiguration() override final; inline void get_conf_signature(int* space) const override final { int* conf = getConf(newaccepted[generator_position]); for(int ii=0; iiconfs()[conf[ii]], isotopeNumbers[ii]*sizeof(int)); space += isotopeNumbers[ii]; } }; IsoLayeredGenerator(Iso&& iso, double _targetCoverage, double _percentageToExpand = 0.3, int _tabSize = 1000, int _hashSize = 1000, bool trim = false); virtual ~IsoLayeredGenerator(); void terminate_search(); }; #if !ISOSPEC_BUILDING_R void printConfigurations( const std::tuple& results, int dimNumber, int* isotopeNumbers ); #endif /* !ISOSPEC_BUILDING_R */ } // namespace IsoSpec isospec-1.9.1/IsoSpec++/Makefile0000644000175000017500000000216313373520171016254 0ustar rusconirusconiOPTFLAGS=-O3 -march=native -mtune=native DEBUGFLAGS=-O0 -g -Werror CXXFLAGS=-std=c++11 -Wall -pedantic -Wextra SRCFILES=cwrapper.cpp allocator.cpp dirtyAllocator.cpp isoSpec++.cpp isoMath.cpp marginalTrek++.cpp operators.cpp element_tables.cpp misc.cpp mman.c all: unitylib unitylib: $(CXX) $(CXXFLAGS) $(OPTFLAGS) unity-build.cpp -fPIC -shared -o libIsoSpec++.so debug: $(CXX) $(CXXFLAGS) $(DEBUGFLAGS) unity-build.cpp -DDEBUG -fPIC -shared -o libIsoSpec++.so debug-gcc: g++ $(CXXFLAGS) $(DEBUGFLAGS) unity-build.cpp -DDEBUG -fPIC -shared -o libIsoSpec++.so nonunity: $(CXX) $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) -DDEBUG -fPIC -shared -o libIsoSpec++.so clean: rm -f libIsoSpec++.so windows: g++ -O3 -std=gnu++11 -O3 -shared -static -static-libstdc++ -static-libgcc unity-build.cpp -o ../IsoSpecPy/IsoSpec++.dll x86_64-w64-mingw32-g++.exe -std=gnu++11 -O3 -shared -static -static-libstdc++ unity-build.cpp -o ../IsoSpecPy/IsoSpecPy/prebuilt-libIsoSpec++1.9.1-x64.dll i686-w64-mingw32-g++.exe -std=gnu++11 -O3 -shared -static -static-libstdc++ unity-build.cpp -o ../IsoSpecPy/IsoSpecPy/prebuilt-libIsoSpec++1.9.1-x32.dll isospec-1.9.1/IsoSpec++/conf.h0000644000175000017500000000122313373520171015706 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once namespace IsoSpec { typedef int* Conf; } isospec-1.9.1/IsoSpec++/platform.h0000644000175000017500000000610313373520171016607 0ustar rusconirusconi #pragma once #if !defined(ISOSPEC_BUILDING_R) #define ISOSPEC_BUILDING_R false #endif #if !defined(ISOSPEC_BUILDING_CPP) #define ISOSPEC_BUILDING_CPP true #endif #if !defined(ISOSPEC_BUILDING_PYTHON) #define ISOSPEC_BUILDING_PYTHON false #endif #if !defined(ISOSPEC_BUILDING_OPENMS) #define ISOSPEC_BUILDING_OPENMS false #endif #if defined(__unix__) || defined(__unix) || \ (defined(__APPLE__) && defined(__MACH__)) #define ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY true #define ISOSPEC_TEST_WE_ARE_ON_WINDOWS false /* CYGWIN doesn't really count as Windows for our purposes, we'll be using UNIX API anyway */ #define ISOSPEC_TEST_GOT_SYSTEM_MMAN true #define ISOSPEC_TEST_GOT_MMAN true #elif defined(__MINGW32__) || defined(_WIN32) #define ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY false #define ISOSPEC_TEST_WE_ARE_ON_WINDOWS true #define ISOSPEC_TEST_GOT_SYSTEM_MMAN false #define ISOSPEC_TEST_GOT_MMAN true #else #define ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY false /* Well, probably... */ #define ISOSPEC_TEST_WE_ARE_ON_WINDOWS false #define ISOSPEC_TEST_GOT_SYSTEM_MMAN false #define ISOSPEC_TEST_GOT_MMAN false #endif #if !defined(ISOSPEC_USE_PTHREADS) #define ISOSPEC_USE_PTHREADS false /* TODO: possibly put a macro here to detect whether we */ #endif /* can/should use pthreads - or rip them out altogether. * Investigate whether the performance advantage of pthreads on * some platforms (*cough* CYGWIN *cough*) is still large * enough to justify keeping both implementations around */ #if !defined(ISOSPEC_WE_ARE_ON_UNIX_YAY) #define ISOSPEC_WE_ARE_ON_UNIX_YAY ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY #endif #if !defined(ISOSPEC_WE_ARE_ON_WINDOWS) #define ISOSPEC_WE_ARE_ON_WINDOWS ISOSPEC_TEST_WE_ARE_ON_WINDOWS #endif #if !defined(ISOSPEC_GOT_SYSTEM_MMAN) #define ISOSPEC_GOT_SYSTEM_MMAN ISOSPEC_TEST_GOT_SYSTEM_MMAN #endif #if !defined(ISOSPEC_GOT_MMAN) #define ISOSPEC_GOT_MMAN ISOSPEC_TEST_GOT_MMAN #endif // Note: __GNUC__ is defined by clang and gcc #ifdef __GNUC__ #define ISOSPEC_LIKELY(condition) __builtin_expect(static_cast(condition), 1) #define ISOSPEC_UNLIKELY(condition) __builtin_expect(static_cast(condition), 0) // For aggressive inlining #define ISOSPEC_FORCE_INLINE __attribute__ ((always_inline)) inline #elif defined _MSC_VER #define ISOSPEC_LIKELY(condition) condition #define ISOSPEC_UNLIKELY(condition) condition #define ISOSPEC_FORCE_INLINE __forceinline inline #else #define ISOSPEC_LIKELY(condition) condition #define ISOSPEC_UNLIKELY(condition) condition #define ISOSPEC_FORCE_INLINE inline #endif #if ISOSPEC_GOT_MMAN #if ISOSPEC_GOT_SYSTEM_MMAN #include #else #include "mman.h" #endif #else #include /* malloc, free, rand */ #endif #if defined(OPENMS_DLLAPI) /* IsoSpec is being built as a part of OpenMS: use their visibility macros */ #define ISOSPEC_EXPORT_SYMBOL OPENMS_DLLAPI #else /* it's a can of worms we don't yet want to open ourselves though... */ #define ISOSPEC_EXPORT_SYMBOL #endif isospec-1.9.1/IsoSpec++/unity-build.cpp0000644000175000017500000000060513373520171017564 0ustar rusconirusconi#include "platform.h" #if !ISOSPEC_GOT_SYSTEM_MMAN && ISOSPEC_GOT_MMAN #include "mman.c" #endif #if !ISOSPEC_BUILDING_R #include "allocator.cpp" #include "dirtyAllocator.cpp" #include "isoSpec++.cpp" #include "isoMath.cpp" #include "marginalTrek++.cpp" #include "operators.cpp" #include "element_tables.cpp" #include "cwrapper.cpp" #include "tabulator.cpp" #include "misc.cpp" #endif isospec-1.9.1/IsoSpec++/mman.h0000644000175000017500000000347213373520171015721 0ustar rusconirusconi/* * sys/mman.h * mman-win32 * * This file has been included as a part of IsoSpec project, under a MIT licence. It * comes from the repository: * * https://github.com/witwall/mman-win32 * * which itself is a mirror of: * * https://code.google.com/archive/p/mman-win32/ */ #pragma once #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. #endif /* All the headers include this file. */ #ifndef _MSC_VER #include <_mingw.h> #endif #if defined(MMAN_LIBRARY) #define MMANSHARED_EXPORT __declspec(dllexport) #else #define MMANSHARED_EXPORT __declspec(dllimport) #endif /* Determine offset type */ #include #if defined(_WIN64) typedef int64_t OffsetType; #else typedef uint32_t OffsetType; #endif #include #ifdef __cplusplus extern "C" { #endif #define PROT_NONE 0 #define PROT_READ 1 #define PROT_WRITE 2 #define PROT_EXEC 4 #define MAP_FILE 0 #define MAP_SHARED 1 #define MAP_PRIVATE 2 #define MAP_TYPE 0xf #define MAP_FIXED 0x10 #define MAP_ANONYMOUS 0x20 #define MAP_ANON MAP_ANONYMOUS #define MAP_FAILED ((void *)-1) /* Flags for msync. */ #define MS_ASYNC 1 #define MS_SYNC 2 #define MS_INVALIDATE 4 MMANSHARED_EXPORT void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off); MMANSHARED_EXPORT int munmap(void *addr, size_t len); MMANSHARED_EXPORT int _mprotect(void *addr, size_t len, int prot); MMANSHARED_EXPORT int msync(void *addr, size_t len, int flags); MMANSHARED_EXPORT int mlock(const void *addr, size_t len); MMANSHARED_EXPORT int munlock(const void *addr, size_t len); #ifdef __cplusplus } #endif isospec-1.9.1/IsoSpec++/dirtyAllocator.cpp0000644000175000017500000000304313373520171020312 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include #include #include "dirtyAllocator.h" namespace IsoSpec { DirtyAllocator::DirtyAllocator( const int dim, const int tabSize ): tabSize(tabSize) { cellSize = sizeof(double) + sizeof(int) * dim; // Fix memory alignment problems for SPARC if(cellSize % sizeof(double) != 0) cellSize += sizeof(double) - cellSize % sizeof(double); currentTab = malloc( cellSize * tabSize ); currentConf = currentTab; endOfTablePtr = reinterpret_cast(currentTab) + cellSize*tabSize; } DirtyAllocator::~DirtyAllocator() { for(unsigned int i = 0; i < prevTabs.size(); ++i) free(prevTabs[i]); free(currentTab); } void DirtyAllocator::shiftTables() { prevTabs.push_back(currentTab); currentTab = malloc( cellSize * tabSize ); currentConf = currentTab; endOfTablePtr = reinterpret_cast(currentTab) + cellSize*tabSize; } } // namespace IsoSpec isospec-1.9.1/IsoSpec++/isoMath.cpp0000644000175000017500000000455713373520171016735 0ustar rusconirusconi/* * This file has been released into public domain by John D. Cook * and is used here with some slight modifications (which are hereby * also released into public domain), * * This file is part of IsoSpec. */ #include #include #include "isoMath.h" #include "platform.h" namespace IsoSpec { const double pi = 3.14159265358979323846264338328; void release_g_lfact_table() { #if ISOSPEC_GOT_MMAN munmap(g_lfact_table, ISOSPEC_G_FACT_TABLE_SIZE*sizeof(double)); #else free(g_lfact_table); #endif } double* alloc_lfact_table() { double* ret; # if ISOSPEC_GOT_MMAN ret = reinterpret_cast(mmap(nullptr, sizeof(double)*ISOSPEC_G_FACT_TABLE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); #else ret = reinterpret_cast(calloc(ISOSPEC_G_FACT_TABLE_SIZE, sizeof(double))); #endif std::atexit(release_g_lfact_table); return ret; } double* g_lfact_table = alloc_lfact_table(); double RationalApproximation(double t) { // Abramowitz and Stegun formula 26.2.23. // The absolute value of the error should be less than 4.5 e-4. double c[] = {2.515517, 0.802853, 0.010328}; double d[] = {1.432788, 0.189269, 0.001308}; return t - ((c[2]*t + c[1])*t + c[0]) / (((d[2]*t + d[1])*t + d[0])*t + 1.0); } double NormalCDFInverse(double p) { if (p < 0.5) return -RationalApproximation( sqrt(-2.0*log(p)) ); else return RationalApproximation( sqrt(-2.0*log(1-p)) ); } double NormalCDFInverse(double p, double mean, double stdev) { return mean + stdev * NormalCDFInverse(p); } double NormalCDF(double x, double mean, double stdev) { x = (x-mean)/stdev * 0.7071067811865476; // constants double a1 = 0.254829592; double a2 = -0.284496736; double a3 = 1.421413741; double a4 = -1.453152027; double a5 = 1.061405429; double p = 0.3275911; // Save the sign of x int sign = 1; if (x < 0) sign = -1; x = fabs(x); // A&S formula 7.1.26 double t = 1.0/(1.0 + p*x); double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x); return 0.5*(1.0 + sign*y); } double NormalPDF(double x, double mean, double stdev) { double two_variance = stdev * stdev * 2.0; double delta = x-mean; return exp( -delta*delta / two_variance ) / sqrt( two_variance * pi ); } } // namespace IsoSpec isospec-1.9.1/IsoSpec++/mman.c0000644000175000017500000001057413373520171015715 0ustar rusconirusconi/* * This file has been included as a part of IsoSpec project, under a MIT licence. It * comes from the repository: * * https://github.com/witwall/mman-win32 * * which itself is a mirror of: * * https://code.google.com/archive/p/mman-win32/ */ #include "platform.h" #if ISOSPEC_GOT_MMAN && !ISOSPEC_GOT_SYSTEM_MMAN #include #include #include #include "mman.h" #ifndef FILE_MAP_EXECUTE #define FILE_MAP_EXECUTE 0x0020 #endif /* FILE_MAP_EXECUTE */ static int __map_mman_error(const DWORD err, const int deferr) { if (err == 0) return 0; //TODO: implement return err; } static DWORD __map_mmap_prot_page(const int prot) { DWORD protect = 0; if (prot == PROT_NONE) return protect; if ((prot & PROT_EXEC) != 0) { protect = ((prot & PROT_WRITE) != 0) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; } else { protect = ((prot & PROT_WRITE) != 0) ? PAGE_READWRITE : PAGE_READONLY; } return protect; } static DWORD __map_mmap_prot_file(const int prot) { DWORD desiredAccess = 0; if (prot == PROT_NONE) return desiredAccess; if ((prot & PROT_READ) != 0) desiredAccess |= FILE_MAP_READ; if ((prot & PROT_WRITE) != 0) desiredAccess |= FILE_MAP_WRITE; if ((prot & PROT_EXEC) != 0) desiredAccess |= FILE_MAP_EXECUTE; return desiredAccess; } void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off) { HANDLE fm, h; void * map = MAP_FAILED; #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4293) #endif const DWORD dwFileOffsetLow = (sizeof(OffsetType) <= sizeof(DWORD)) ? (DWORD)off : (DWORD)(off & 0xFFFFFFFFL); const DWORD dwFileOffsetHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ? (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL); const DWORD protect = __map_mmap_prot_page(prot); const DWORD desiredAccess = __map_mmap_prot_file(prot); const OffsetType maxSize = off + (OffsetType)len; const DWORD dwMaxSizeLow = (sizeof(OffsetType) <= sizeof(DWORD)) ? (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL); const DWORD dwMaxSizeHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ? (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL); #ifdef _MSC_VER #pragma warning(pop) #endif errno = 0; if (len == 0 /* Unsupported flag combinations */ || (flags & MAP_FIXED) != 0 /* Usupported protection combinations */ || prot == PROT_EXEC) { errno = EINVAL; return MAP_FAILED; } h = ((flags & MAP_ANONYMOUS) == 0) ? (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE; if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE) { errno = EBADF; return MAP_FAILED; } fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL); if (fm == NULL) { errno = __map_mman_error(GetLastError(), EPERM); return MAP_FAILED; } map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len); CloseHandle(fm); if (map == NULL) { errno = __map_mman_error(GetLastError(), EPERM); return MAP_FAILED; } return map; } int munmap(void *addr, size_t len) { if (UnmapViewOfFile(addr)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } int _mprotect(void *addr, size_t len, int prot) { DWORD newProtect = __map_mmap_prot_page(prot); DWORD oldProtect = 0; if (VirtualProtect(addr, len, newProtect, &oldProtect)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } int msync(void *addr, size_t len, int flags) { if (FlushViewOfFile(addr, len)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } int mlock(const void *addr, size_t len) { if (VirtualLock((LPVOID)addr, len)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } int munlock(const void *addr, size_t len) { if (VirtualUnlock((LPVOID)addr, len)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } #endif isospec-1.9.1/IsoSpec++/operators.cpp0000644000175000017500000000241513373520171017336 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include "operators.h" #include "marginalTrek++.h" namespace IsoSpec { KeyHasher::KeyHasher(int _dim) : dim(_dim) {} ConfEqual::ConfEqual(int dim) : size( dim*sizeof(int) ) {} ConfOrderMarginal::ConfOrderMarginal(const double* _logProbs, int _dim) : logProbs(_logProbs), dim(_dim) {} ConfOrderMarginalDescending::ConfOrderMarginalDescending(const double* _logProbs, int _dim) : logProbs(_logProbs), dim(_dim) {} OrderMarginalsBySizeDecresing::OrderMarginalsBySizeDecresing(PrecalculatedMarginal const* const * const _T) : T(_T) {} bool OrderMarginalsBySizeDecresing::operator()(int m1, int m2) { return T[m1]->get_no_confs() > T[m2]->get_no_confs(); } } // namespace IsoSpec isospec-1.9.1/IsoSpec++/cwrapper.h0000644000175000017500000000755413373520171016621 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #pragma once #define ISOSPEC_ALGO_LAYERED 0 #define ISOSPEC_ALGO_ORDERED 1 #define ISOSPEC_ALGO_THRESHOLD_ABSOLUTE 2 #define ISOSPEC_ALGO_THRESHOLD_RELATIVE 3 #define ISOSPEC_ALGO_LAYERED_ESTIMATE 4 #ifdef __cplusplus extern "C" { #else #include #endif void * setupIso(int dimNumber, const int* isotopeNumbers, const int* atomCounts, const double* isotopeMasses, const double* isotopeProbabilities); void deleteIso(void* iso); #define ISOSPEC_C_FN_HEADER(generatorType, dataType, method)\ dataType method##generatorType(void* generator); #define ISOSPEC_C_FN_HEADER_GET_CONF_SIGNATURE(generatorType)\ void method##generatorType(void* generator); #define ISOSPEC_C_FN_HEADERS(generatorType)\ ISOSPEC_C_FN_HEADER(generatorType, double, mass) \ ISOSPEC_C_FN_HEADER(generatorType, double, lprob) \ ISOSPEC_C_FN_HEADER(generatorType, double, prob) \ ISOSPEC_C_FN_HEADER_GET_CONF_SIGNATURE(generatorType) \ ISOSPEC_C_FN_HEADER(generatorType, bool, advanceToNextConfiguration) \ ISOSPEC_C_FN_HEADER(generatorType, void, delete) //______________________________________________________THRESHOLD GENERATOR void* setupIsoThresholdGenerator(void* iso, double threshold, bool _absolute, int _tabSize, int _hashSize); ISOSPEC_C_FN_HEADERS(IsoThresholdGenerator) //______________________________________________________LAYERED GENERATOR void* setupIsoLayeredGenerator(void* iso, double _target_coverage, double _percentage_to_expand, int _tabSize, int _hashSize, bool _do_trim); ISOSPEC_C_FN_HEADERS(IsoLayeredGenerator) //______________________________________________________ORDERED GENERATOR void* setupIsoOrderedGenerator(void* iso, int _tabSize, int _hashSize); ISOSPEC_C_FN_HEADERS(IsoOrderedGenerator) void* setupThresholdTabulator(void* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs); void deleteThresholdTabulator(void* tabulator); const double* massesThresholdTabulator(void* tabulator); const double* lprobsThresholdTabulator(void* tabulator); const double* probsThresholdTabulator(void* tabulator); const int* confsThresholdTabulator(void* tabulator); int confs_noThresholdTabulator(void* tabulator); void* setupLayeredTabulator(void* generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs); void deleteLayeredTabulator(void* tabulator); const double* massesLayeredTabulator(void* tabulator); const double* lprobsLayeredTabulator(void* tabulator); const double* probsLayeredTabulator(void* tabulator); const int* confsLayeredTabulator(void* tabulator); int confs_noLayeredTabulator(void* tabulator); void freeReleasedArray(void* array); #ifdef __cplusplus } #endif isospec-1.9.1/IsoSpec++/misc.cpp0000644000175000017500000000321113373520171016246 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include "misc.h" #include "platform.h" #include #define mswap(x, y) swapspace = x; x = y; y=swapspace; namespace IsoSpec { void* quickselect(void** array, int n, int start, int end) { void* swapspace; if(start == end) return array[start]; while(true) { // Partition part int len = end - start; #if ISOSPEC_BUILDING_R int pivot = len/2 + start; #else int pivot = rand() % len + start; #endif void* pval = array[pivot]; double pprob = getLProb(pval); mswap(array[pivot], array[end-1]); int loweridx = start; for(int i=start; i. */ #pragma once #include #include #include #include #include "isoMath.h" namespace IsoSpec { inline double combinedSum( const int* conf, const std::vector** valuesContainer, int dimNumber ){ double res = 0.0; for(int i=0; i( reinterpret_cast(conf) + sizeof(double) ); } inline double getLProb(void* conf) { double ret = *reinterpret_cast(conf); return ret; } inline double unnormalized_logProb(const int* conf, const double* logProbs, int dim) { double res = 0.0; int curr_method = fegetround(); fesetround(FE_TOWARDZERO); for(int i=0; i < dim; i++) res += minuslogFactorial(conf[i]); fesetround(FE_UPWARD); for(int i=0; i < dim; i++) res += conf[i] * logProbs[i]; fesetround(curr_method); return res; } inline double mass(const int* conf, const double* masses, int dim) { double res = 0.0; for(int i=0; i < dim; i++) { res += conf[i] * masses[i]; } return res; } inline bool tupleCmp( std::tuple t1, std::tuple t2 ){ return std::get<1>(t1) > std::get<1>(t2); } template void printArray(const T* array, int size) { for (int i=0; i void printVector(const std::vector& vec) { printArray(vec.data(), vec.size()); } template void printNestedArray(const T** array, const int* shape, int size) { for (int i=0; i inline static T* array_copy(const T* A, int size) { T* ret = new T[size]; memcpy(ret, A, size*sizeof(T)); return ret; } template void dealloc_table(T* tbl, int dim) { for(int i=0; i; template class Tabulator; } // namespace IsoSpec isospec-1.9.1/IsoSpec++/element_tables.cpp0000644000175000017500000014632513373520171020314 0ustar rusconirusconi/* * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek. * * This file is part of IsoSpec. * * IsoSpec is free software: you can redistribute it and/or modify * it under the terms of the Simplified ("2-clause") BSD licence. * * IsoSpec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Simplified BSD Licence * along with IsoSpec. If not, see . */ #include "element_tables.h" namespace IsoSpec { #ifdef __cplusplus extern "C" { #endif const int elem_table_atomicNo [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 12, 12, 12, 13, 14, 14, 14, 15, 16, 16, 16, 16, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 22, 22, 22, 22, 22, 23, 23, 24, 24, 24, 24, 25, 26, 26, 26, 26, 27, 28, 28, 28, 28, 28, 29, 29, 30, 30, 30, 30, 30, 31, 31, 32, 32, 32, 32, 32, 33, 34, 34, 34, 34, 34, 34, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 38, 38, 38, 38, 39, 40, 40, 40, 40, 40, 41, 42, 42, 42, 42, 42, 42, 42, 44, 44, 44, 44, 44, 44, 44, 45, 46, 46, 46, 46, 46, 46, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 53, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 56, 56, 56, 56, 56, 56, 56, 57, 57, 58, 58, 58, 58, 59, 60, 60, 60, 60, 60, 60, 60, 62, 62, 62, 62, 62, 62, 62, 63, 63, 64, 64, 64, 64, 64, 64, 64, 65, 66, 66, 66, 66, 66, 66, 66, 67, 68, 68, 68, 68, 68, 68, 69, 70, 70, 70, 70, 70, 70, 70, 71, 71, 72, 72, 72, 72, 72, 72, 73, 73, 74, 74, 74, 74, 74, 75, 75, 76, 76, 76, 76, 76, 76, 76, 77, 77, 78, 78, 78, 78, 78, 78, 79, 80, 80, 80, 80, 80, 80, 80, 81, 81, 82, 82, 82, 82, 83, 92, 92, 92, 90, 91, }; const double elem_table_mass [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { 1.00782503227, 2.01410177819, 3.016029322, 4.00260325414, 6.0151228871, 7.016003443, 9.01218316, 10.0129373, 11.0093053, 12, 13.0033548352, 14.0030740042, 15.0001088994, 15.9949146202, 16.9991317576, 17.9991596137, 18.9984031637, 19.992440182, 20.99384673, 21.99138512, 22.989769282, 23.985041701, 24.98583703, 25.98259302, 26.98153858, 27.9769265353, 28.9764946653, 29.973770012, 30.9737619986, 31.9720711741, 32.9714589101, 33.96786703, 35.9670812, 34.96885273, 36.96590264, 35.96754512, 37.9627322, 39.962383122, 38.963706493, 39.96399824, 40.961825263, 39.96259092, 41.9586181, 42.9587662, 43.9554822, 45.953692, 47.95252289, 44.9559086, 45.9526283, 46.9517593, 47.9479423, 48.9478663, 49.9447873, 49.9471567, 50.9439577, 49.9460427, 51.9405064, 52.9406484, 53.9388794, 54.9380443, 53.9396093, 55.9349363, 56.9353933, 57.9332743, 58.9331944, 57.9353423, 59.9307863, 60.9310563, 61.9283454, 63.9279674, 62.9295984, 64.9277906, 63.9291426, 65.9260347, 66.9271287, 67.9248457, 69.925322, 68.9255749, 70.9247037, 69.9242497, 71.92207586, 72.92345904, 73.921177761, 75.92140272, 74.9215957, 73.92247591, 75.91921372, 76.91991426, 77.9173092, 79.9165229, 81.9167001, 78.9183381, 80.9162901, 77.9203656, 79.9163786, 81.9134837, 82.9141272, 83.911497733, 85.910610633, 84.911789743, 86.909180536, 83.9134199, 85.9092619, 86.9088789, 87.9056139, 88.905842, 89.904702, 90.905642, 91.905032, 93.906312, 95.908272, 92.906372, 91.9068086, 93.9050853, 94.9058393, 95.9046763, 96.9060183, 97.9054053, 99.9074728, 95.9075903, 97.905296, 98.9059348, 99.9042148, 100.9055779, 101.9043449, 103.905432, 102.905502, 101.905602, 103.9040311, 104.9050809, 105.9034809, 107.9038929, 109.9051726, 106.905092, 108.9047551, 105.9064609, 107.9041839, 109.9030074, 110.9041834, 111.9027634, 112.9044083, 113.9033653, 115.9047632, 112.9040627, 114.903878789, 111.9048244, 113.9027837, 114.90334471, 115.9017431, 116.9029543, 117.9016073, 118.9033116, 119.9022027, 121.903442, 123.9052778, 120.903812, 122.904212, 119.904062, 121.903041, 122.904271, 123.902821, 124.904431, 125.903311, 127.9044617, 129.906222759, 126.904473, 123.905892, 125.904303, 127.9035318, 128.904780864, 129.90350941, 130.9050842, 131.904155094, 133.9053957, 135.907214488, 132.905451967, 129.906322, 131.9050618, 133.9045082, 134.9056882, 135.9045762, 136.9058272, 137.9052472, 137.907123, 138.906362, 135.9071293, 137.905998, 139.905442, 141.909252, 140.907662, 141.907732, 142.909822, 143.910092, 144.912582, 145.913122, 147.916902, 149.920902, 143.912012, 146.914902, 147.914832, 148.917192, 149.917282, 151.919742, 153.922222, 150.919862, 152.921242, 151.919802, 153.920872, 154.922632, 155.922132, 156.923972, 157.924112, 159.927062, 158.925352, 155.924282, 157.924422, 159.925202, 160.926942, 161.926812, 162.928742, 163.929182, 164.930332, 161.928792, 163.929212, 165.930302, 166.932052, 167.932382, 169.935472, 168.934222, 167.933892, 169.934772, 170.936332, 171.936392, 172.938222, 173.938872, 175.942582, 174.940782, 175.942692, 173.940052, 175.941412, 176.943232, 177.943712, 178.945822, 179.946562, 179.947462, 180.948002, 179.946712, 181.9482047, 182.9502237, 183.9509317, 185.954362, 184.9529559, 186.955751, 183.9524891, 185.953841, 186.955751, 187.955841, 188.958142, 189.958442, 191.961482, 190.960592, 192.962922, 189.959934, 191.961042, 193.9626817, 194.9647927, 195.9649527, 197.967892, 196.9665696, 195.965832, 197.9667693, 198.9682813, 199.9683273, 200.9703036, 201.9706436, 203.9734943, 202.9723451, 204.9744281, 203.9730449, 205.9744669, 206.9758979, 207.9766539, 208.980401, 234.040952, 235.043932, 238.050792, 232.038062, 231.035882, }; const int elem_table_massNo [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { 1, 2, 3, 4, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 35, 37, 36, 38, 40, 39, 40, 41, 40, 42, 43, 44, 46, 48, 45, 46, 47, 48, 49, 50, 50, 51, 50, 52, 53, 54, 55, 54, 56, 57, 58, 59, 58, 60, 61, 62, 64, 63, 65, 64, 66, 67, 68, 70, 69, 71, 70, 72, 73, 74, 76, 75, 74, 76, 77, 78, 80, 82, 79, 81, 78, 80, 82, 83, 84, 86, 85, 87, 84, 86, 87, 88, 89, 90, 91, 92, 94, 96, 93, 92, 94, 95, 96, 97, 98, 100, 96, 98, 99, 100, 101, 102, 104, 103, 102, 104, 105, 106, 108, 110, 107, 109, 106, 108, 110, 111, 112, 113, 114, 116, 113, 115, 112, 114, 115, 116, 117, 118, 119, 120, 122, 124, 121, 123, 120, 122, 123, 124, 125, 126, 128, 130, 127, 124, 126, 128, 129, 130, 131, 132, 134, 136, 133, 130, 132, 134, 135, 136, 137, 138, 138, 139, 136, 138, 140, 142, 141, 142, 143, 144, 145, 146, 148, 150, 144, 147, 148, 149, 150, 152, 154, 151, 153, 152, 154, 155, 156, 157, 158, 160, 159, 156, 158, 160, 161, 162, 163, 164, 165, 162, 164, 166, 167, 168, 170, 169, 168, 170, 171, 172, 173, 174, 176, 175, 176, 174, 176, 177, 178, 179, 180, 180, 181, 180, 182, 183, 184, 186, 185, 187, 184, 186, 187, 188, 189, 190, 192, 191, 193, 190, 192, 194, 195, 196, 198, 197, 196, 198, 199, 200, 201, 202, 204, 203, 205, 204, 206, 207, 208, 209, 234, 235, 238, 232, 231, }; const int elem_table_extraNeutrons [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 4, 0, 2, 0, 2, 4, 0, 1, 2, 0, 2, 3, 4, 6, 8, 0, 0, 1, 2, 3, 4, 0, 1, 0, 2, 3, 4, 0, 0, 2, 3, 4, 0, 0, 2, 3, 4, 6, 0, 2, 0, 2, 3, 4, 6, 0, 2, 0, 2, 3, 4, 6, 0, 0, 2, 3, 4, 6, 8, 0, 2, 0, 2, 4, 5, 6, 8, 0, 2, 0, 2, 3, 4, 0, 0, 1, 2, 4, 6, 0, 0, 2, 3, 4, 5, 6, 8, 0, 2, 3, 4, 5, 6, 8, 0, 0, 2, 3, 4, 6, 8, 0, 2, 0, 2, 4, 5, 6, 7, 8, 10, 0, 2, 0, 2, 3, 4, 5, 6, 7, 8, 10, 12, 0, 2, 0, 2, 3, 4, 5, 6, 8, 10, 0, 0, 2, 4, 5, 6, 7, 8, 10, 12, 0, 0, 2, 4, 5, 6, 7, 8, 0, 1, 0, 2, 4, 6, 0, 0, 1, 2, 3, 4, 6, 8, 0, 3, 4, 5, 6, 8, 10, 0, 2, 0, 2, 3, 4, 5, 6, 8, 0, 0, 2, 4, 5, 6, 7, 8, 0, 0, 2, 4, 5, 6, 8, 0, 0, 2, 3, 4, 5, 6, 8, 0, 1, 0, 2, 3, 4, 5, 6, 0, 1, 0, 2, 3, 4, 6, 0, 2, 0, 2, 3, 4, 5, 6, 8, 0, 2, 0, 2, 4, 5, 6, 8, 0, 0, 2, 3, 4, 5, 6, 8, 0, 2, 0, 2, 3, 4, 0, 1, 2, 5, 0, 0, }; const char* elem_table_element [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { "hydrogen", "hydrogen", "helium", "helium", "lithium", "lithium", "beryllium", "boron", "boron", "carbon", "carbon", "nitrogen", "nitrogen", "oxygen", "oxygen", "oxygen", "fluorine", "neon", "neon", "neon", "sodium", "magnesium", "magnesium", "magnesium", "aluminium", "silicon", "silicon", "silicon", "phosphorus", "sulfur", "sulfur", "sulfur", "sulfur", "chlorine", "chlorine", "argon", "argon", "argon", "potassium", "potassium", "potassium", "calcium", "calcium", "calcium", "calcium", "calcium", "calcium", "scandium", "titanium", "titanium", "titanium", "titanium", "titanium", "vanadium", "vanadium", "chromium", "chromium", "chromium", "chromium", "manganese", "iron", "iron", "iron", "iron", "cobalt", "nickel", "nickel", "nickel", "nickel", "nickel", "copper", "copper", "zinc", "zinc", "zinc", "zinc", "zinc", "gallium", "gallium", "germanium", "germanium", "germanium", "germanium", "germanium", "arsenic", "selenium", "selenium", "selenium", "selenium", "selenium", "selenium", "bromine", "bromine", "krypton", "krypton", "krypton", "krypton", "krypton", "krypton", "rubidium", "rubidium", "strontium", "strontium", "strontium", "strontium", "yttrium", "zirconium", "zirconium", "zirconium", "zirconium", "zirconium", "niobium", "molybdenum", "molybdenum", "molybdenum", "molybdenum", "molybdenum", "molybdenum", "molybdenum", "ruthenium", "ruthenium", "ruthenium", "ruthenium", "ruthenium", "ruthenium", "ruthenium", "rhodium", "palladium", "palladium", "palladium", "palladium", "palladium", "palladium", "silver", "silver", "cadmium", "cadmium", "cadmium", "cadmium", "cadmium", "cadmium", "cadmium", "cadmium", "indium", "indium", "tin", "tin", "tin", "tin", "tin", "tin", "tin", "tin", "tin", "tin", "antimony", "antimony", "tellurium", "tellurium", "tellurium", "tellurium", "tellurium", "tellurium", "tellurium", "tellurium", "iodine", "xenon", "xenon", "xenon", "xenon", "xenon", "xenon", "xenon", "xenon", "xenon", "caesium", "barium", "barium", "barium", "barium", "barium", "barium", "barium", "lanthanum", "lanthanum", "cerium", "cerium", "cerium", "cerium", "praseodymium", "neodymium", "neodymium", "neodymium", "neodymium", "neodymium", "neodymium", "neodymium", "samarium", "samarium", "samarium", "samarium", "samarium", "samarium", "samarium", "europium", "europium", "gadolinium", "gadolinium", "gadolinium", "gadolinium", "gadolinium", "gadolinium", "gadolinium", "terbium", "dysprosium", "dysprosium", "dysprosium", "dysprosium", "dysprosium", "dysprosium", "dysprosium", "holmium", "erbium", "erbium", "erbium", "erbium", "erbium", "erbium", "thulium", "ytterbium", "ytterbium", "ytterbium", "ytterbium", "ytterbium", "ytterbium", "ytterbium", "lutetium", "lutetium", "hafnium", "hafnium", "hafnium", "hafnium", "hafnium", "hafnium", "tantalum", "tantalum", "tungsten", "tungsten", "tungsten", "tungsten", "tungsten", "rhenium", "rhenium", "osmium", "osmium", "osmium", "osmium", "osmium", "osmium", "osmium", "iridium", "iridium", "platinum", "platinum", "platinum", "platinum", "platinum", "platinum", "gold", "mercury", "mercury", "mercury", "mercury", "mercury", "mercury", "mercury", "thallium", "thallium", "lead", "lead", "lead", "lead", "bismuth", "uranium", "uranium", "uranium", "thorium", "protactinium", }; const char* elem_table_symbol [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { "H", "H", "He", "He", "Li", "Li", "Be", "B", "B", "C", "C", "N", "N", "O", "O", "O", "F", "Ne", "Ne", "Ne", "Na", "Mg", "Mg", "Mg", "Al", "Si", "Si", "Si", "P", "S", "S", "S", "S", "Cl", "Cl", "Ar", "Ar", "Ar", "K", "K", "K", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Sc", "Ti", "Ti", "Ti", "Ti", "Ti", "V", "V", "Cr", "Cr", "Cr", "Cr", "Mn", "Fe", "Fe", "Fe", "Fe", "Co", "Ni", "Ni", "Ni", "Ni", "Ni", "Cu", "Cu", "Zn", "Zn", "Zn", "Zn", "Zn", "Ga", "Ga", "Ge", "Ge", "Ge", "Ge", "Ge", "As", "Se", "Se", "Se", "Se", "Se", "Se", "Br", "Br", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Rb", "Rb", "Sr", "Sr", "Sr", "Sr", "Y", "Zr", "Zr", "Zr", "Zr", "Zr", "Nb", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Rh", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Ag", "Ag", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "In", "In", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sb", "Sb", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "I", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Cs", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "La", "La", "Ce", "Ce", "Ce", "Ce", "Pr", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Eu", "Eu", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Tb", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Ho", "Er", "Er", "Er", "Er", "Er", "Er", "Tm", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Lu", "Lu", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Ta", "Ta", "W", "W", "W", "W", "W", "Re", "Re", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Ir", "Ir", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Au", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Tl", "Tl", "Pb", "Pb", "Pb", "Pb", "Bi", "U", "U", "U", "Th", "Pa", }; const bool elem_table_Radioactive [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, true, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, true, false, false, false, true, false, true, true, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, true, false, true, false, false, false, false, false, true, true, true, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, }; const double elem_table_probability [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { 0.999884290164307909520857720053754746913909912109375000000000, 0.000115709835692033314582735648023970043141162022948265075684, 0.000001342999991941999914655050951672876635711872950196266174, 0.999998657000008006612290500925155356526374816894531250000000, 0.075933925285977116326208147256693337112665176391601562500000, 0.924066074714022800407065005856566131114959716796875000000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.199480830670926506664741850727295968681573867797851562500000, 0.800519169329073410068531302385963499546051025390625000000000, 0.989211941850466902614869013632414862513542175292968750000000, 0.010788058149533083507343178553128382191061973571777343750000, 0.996358014567941707717579902237048372626304626464843750000000, 0.003641985432058271465738386041266494430601596832275390625000, 0.997567609729561044495937949250219389796257019042968750000000, 0.000380998476006095935803702490218825005285907536745071411133, 0.002051391794432822109073288885383590240962803363800048828125, 1.000000000000000000000000000000000000000000000000000000000000, 0.904766666333356561757739200402284041047096252441406250000000, 0.002709810313278070148523823945652111433446407318115234375000, 0.092523523353365264010328417043638182803988456726074218750000, 1.000000000000000000000000000000000000000000000000000000000000, 0.789876809855211581279377242026384919881820678710937500000000, 0.100001999840012789633192369365133345127105712890625000000000, 0.110121190304775615209642580794024979695677757263183593750000, 1.000000000000000000000000000000000000000000000000000000000000, 0.922220833349999713490774411184247583150863647460937500000000, 0.046858437698747611166449900110819726251065731048583984375000, 0.030920728951252581667707985957349592354148626327514648437500, 1.000000000000000000000000000000000000000000000000000000000000, 0.949850011999040066967836537514813244342803955078125000000000, 0.007519398448124149821059081233443066594190895557403564453125, 0.042520598352131823427502155254842364229261875152587890625000, 0.000109991200703943683199964587160479823069181293249130249023, 0.757594848103037898923162174469325691461563110351562500000000, 0.242405151896962045565686594272847287356853485107421875000000, 0.003336205796380696270847510120916012965608388185501098632812, 0.000629799206452999775149304007015871320618316531181335449219, 0.996033994997166272078459314798237755894660949707031250000000, 0.932580526071084436878777523816097527742385864257812500000000, 0.000117099885242112454345267402722186034225160256028175354004, 0.067302374043673424131029037198459263890981674194335937500000, 0.969400838426726974006442105746828019618988037109375000000000, 0.006472228417153705684605746739634923869743943214416503906250, 0.001350985058105257227353823701321289263432845473289489746094, 0.020860869278785776348428271376178599894046783447265625000000, 0.000042999524425259849917842214228613784143817611038684844971, 0.001872079294802999303859447621789513505063951015472412109375, 1.000000000000000000000000000000000000000000000000000000000000, 0.082520097588289403889305617667559999972581863403320312500000, 0.074411070671519405350657905273692449554800987243652343750000, 0.737141543014838140912559083517407998442649841308593750000000, 0.054113506379234489751528514034362160600721836090087890625000, 0.051813782346118462951434224805780104361474514007568359375000, 0.002503979968160254584302881752932989911641925573348999023438, 0.997496020031839680797247638111002743244171142578125000000000, 0.043450743830478963380947732275672024115920066833496093750000, 0.837881075122238416774678171350387856364250183105468750000000, 0.095010483865806516501351097758742980659008026123046875000000, 0.023657697181476075587447382986283628270030021667480468750000, 1.000000000000000000000000000000000000000000000000000000000000, 0.058452792721208068904559240763774141669273376464843750000000, 0.917532497856775930422656983864726498723030090332031250000000, 0.021190743592002535267138085828264593146741390228271484375000, 0.002823965830013456732028309659199294401332736015319824218750, 1.000000000000000000000000000000000000000000000000000000000000, 0.680769095231327558970235713786678388714790344238281250000000, 0.262230419610671172669924544607056304812431335449218750000000, 0.011399083035777891892426083586542517878115177154541015625000, 0.036346250253448952882706635136855766177177429199218750000000, 0.009255151868774300419340228529563319170847535133361816406250, 0.691494255172344751692037334578344598412513732910156250000000, 0.308505744827655137285660202906001359224319458007812500000000, 0.491645713885820234700929631799226626753807067871093750000000, 0.277325508740183801492662496457342058420181274414062500000000, 0.040405292597461665848879164286699960939586162567138671875000, 0.184515103497573135227227680843498092144727706909179687500000, 0.006108381278961075126765489784474993939511477947235107421875, 0.601079797840404217446064194518839940428733825683593750000000, 0.398920202159595671531633342965506017208099365234375000000000, 0.205705812301332946478993335404084064066410064697265625000000, 0.274503726116209989527305879164487123489379882812500000000000, 0.077504017086240106770844704442424699664115905761718750000000, 0.364982406812098314485837136089685373008251190185546875000000, 0.077304037684118531714716482383664697408676147460937500000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.008938426836876709608015190156038443092256784439086914062500, 0.093712506598838590798905556766840163618326187133789062500000, 0.076302570747548426055573145276866853237152099609375000000000, 0.237686167234566703143627819372341036796569824218750000000000, 0.496053694549759227605534306348999962210655212402343750000000, 0.087306634032410290746639702774700708687305450439453125000000, 0.506898896176611657438115798868238925933837890625000000000000, 0.493101103823388231539581738616107031702995300292968750000000, 0.003552948126957346328819165037771199422422796487808227539062, 0.022860666234272977725971998097520554438233375549316406250000, 0.115931407401451927463575941601447993889451026916503906250000, 0.115000220996773441783922464765055337920784950256347656250000, 0.569863179997571966950431487930472940206527709960937500000000, 0.172791577242972227423933873069472610950469970703125000000000, 0.721691132354705722207199869444593787193298339843750000000000, 0.278308867645294166770497668039752170443534851074218750000000, 0.005609775608975640752429381308274969342164695262908935546875, 0.098606055757769678349333730693615507334470748901367187500000, 0.070007199712011511372189431767765199765563011169433593750000, 0.825776968921243081922511919401586055755615234375000000000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.514422711621750239352479638910153880715370178222656250000000, 0.112234410554393593262290096390643157064914703369140625000000, 0.171550886397901253266340404479706194251775741577148437500000, 0.173788376250214926521664438041625544428825378417968750000000, 0.028003615175739928616627238966430013533681631088256835937500, 1.000000000000000000000000000000000000000000000000000000000000, 0.145308494342837241086741073559096548706293106079101562500000, 0.091496458524138415957516201615362660959362983703613281250000, 0.158387558641321063435114524509117472916841506958007812500000, 0.166690329831184980147185115129104815423488616943359375000000, 0.095999792030779435014764544575882609933614730834960937500000, 0.243900902666405350327494261364336125552654266357421875000000, 0.098216463963333416886669624545902479439973831176757812500000, 0.055402974808013198682044020415560225956141948699951171875000, 0.018726273471579152340993346115283202379941940307617187500000, 0.127588609866636532030881312493875157088041305541992187500000, 0.126054915071900669465421174209041055291891098022460937500000, 0.170586053375378299268305681835045106709003448486328125000000, 0.315451225206183960558803391904802992939949035644531250000000, 0.186189948200308125203505937861336860805749893188476562500000, 1.000000000000000000000000000000000000000000000000000000000000, 0.010207550187954890497099569302008603699505329132080078125000, 0.111463248820283120088525663504697149619460105895996093750000, 0.223336399264176588275176982278935611248016357421875000000000, 0.273264416540030363744762098576757125556468963623046875000000, 0.264546508837878890929573572066146880388259887695312500000000, 0.117181876349676070137029171291942475363612174987792968750000, 0.518389668985958174118877650471404194831848144531250000000000, 0.481610331014041714858819887012941762804985046386718750000000, 0.012567197514954164816458614950533956289291381835937500000000, 0.008928009053980960965657409644791187020018696784973144531250, 0.124890149496662231087817929164884844794869422912597656250000, 0.127983459688489453753845737082883715629577636718750000000000, 0.241267197414976458658131264201074372977018356323242187500000, 0.122184752800125570604272695618419675156474113464355468750000, 0.287277937020044504823346187549759633839130401611328125000000, 0.074901297010766587636254598692175932228565216064453125000000, 0.042954845418549769675564675708301365375518798828125000000000, 0.957045154581450119302132861776044592261314392089843750000000, 0.009707379007667929146641050408561568474397063255310058593750, 0.006608215781738930282018795736576066701672971248626708984375, 0.003409079548521898664348306340343697229400277137756347656250, 0.145370749897527656857576516813423950225114822387695312500000, 0.076859248003039171148742525474517606198787689208984375000000, 0.242144620952342848330118840749491937458515167236328125000000, 0.085916802463334898676272644024720648303627967834472656250000, 0.325722055045137792728127124064485542476177215576171875000000, 0.046317494276545329023875297025369945913553237915039062500000, 0.057944355024143474885978122301821713335812091827392578125000, 0.572091349038115315472907695948379114270210266113281250000000, 0.427908650961884573504789841535966843366622924804687500000000, 0.000909764371027903685079651907585684966761618852615356445312, 0.025505394102927340937991829150632838718593120574951171875000, 0.008927687728878220055350745099076448241248726844787597656250, 0.047401722953754971134898710261040832847356796264648437500000, 0.070696689557404629455916733604681212455034255981445312500000, 0.188376210561464557668998054396070074290037155151367187500000, 0.317407791382032011817670991149498149752616882324218750000000, 0.340774739342510235573513455165084451436996459960937500000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.000952296533640617525774685336870106766582466661930084228516, 0.000890196759683794711613680217254795934422872960567474365234, 0.019102830465697103606848017420816177036613225936889648437500, 0.264005869018636762923790683998959138989448547363281250000000, 0.040709981815666186621971434078659513033926486968994140625000, 0.212323527142361190289676642350968904793262481689453125000000, 0.269085350529324029977829013660084456205368041992187500000000, 0.104356830141138279266499466757522895932197570800781250000000, 0.088573117593851946605099101361702196300029754638671875000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.001060985146207953045902061539607075246749445796012878417969, 0.001010985846198153050023993415607037604786455631256103515625, 0.024171461599537605313692267827718751505017280578613281250000, 0.065920277116120362670415033790050074458122253417968750000000, 0.078541300421794094099858796198532218113541603088378906250000, 0.112320827508414877726750091824214905500411987304687500000000, 0.716974162361726841119491382414707913994789123535156250000000, 0.000888171872103250392010975744483403104823082685470581054688, 0.999111828127896672846475212281802669167518615722656250000000, 0.001851973331584025024912354417949700291501358151435852050781, 0.002511963827720880421123794690174690913408994674682617187500, 0.884492463308528265031327464384958148002624511718750000000000, 0.111143599532166723053983048430382041260600090026855468750000, 1.000000000000000000000000000000000000000000000000000000000000, 0.271519166958828106483991859931848011910915374755859375000000, 0.121740433020292235233306143982190405949950218200683593750000, 0.237977663997580829446931716120161581784486770629882812500000, 0.082929723850915446070608538775559281930327415466308593750000, 0.171890140355501652713599014532519504427909851074218750000000, 0.057561075412857647115583148433870519511401653289794921875000, 0.056381796404024006608146635244338540360331535339355468750000, 0.030772522277086666181444840617587033193558454513549804687500, 0.149881578776357327065227309503825381398200988769531250000000, 0.112382691006085513873991033051424892619252204895019531250000, 0.138246406123312015612469849656918086111545562744140625000000, 0.073792068527347848272412988990254234522581100463867187500000, 0.267451009404714612482933944193064235150814056396484375000000, 0.227473723885095902019770619517657905817031860351562500000000, 0.478103065570820051632949798658955842256546020507812500000000, 0.521896934429179837344747738825390115380287170410156250000000, 0.002009636255837693018938550082452820788603276014328002929688, 0.021826049485043207132317633067941642366349697113037109375000, 0.147985214676143617129611129712429828941822052001953125000000, 0.204672954195290635048820604424690827727317810058593750000000, 0.156491675006823760529783839956508018076419830322265625000000, 0.248435033258980114689862261911912355571985244750976562500000, 0.218579437121880937322515592313720844686031341552734375000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.000562985756460361477619691594753703611786477267742156982422, 0.000952975889709990254573812595850768047966994345188140869141, 0.023291210732368467645203580218549177516251802444458007812500, 0.188889421097646226233024435714469291269779205322265625000000, 0.254747154896981076177553404704667627811431884765625000000000, 0.248957901365095435330943018925609067082405090332031250000000, 0.282598350261738351374418698469526134431362152099609375000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.001395973476503946332158423437874716910300776362419128417969, 0.016012695758780580435054474719436257146298885345458984375000, 0.335027234482544788995994622382568195462226867675781250000000, 0.228686654953555862368475004586798604577779769897460937500000, 0.269776674243189351631855288360384292900562286376953125000000, 0.149100767085425356395234075534972362220287322998046875000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.001232929969577727796758992440118163358420133590698242187500, 0.029822206098693591902470956256365752778947353363037109375000, 0.140905996539396560773838018576498143374919891357421875000000, 0.216800685721051017429417129278590437024831771850585937500000, 0.161027253651992552363481081556528806686401367187500000000000, 0.320249909805123023076589561242144554853439331054687500000000, 0.129961018214165419104588750087714288383722305297851562500000, 0.974008767577204226384424146090168505907058715820312500000000, 0.025991232422795697287742910930319339968264102935791015625000, 0.001609652315099938373749166586890169128309935331344604492188, 0.052668623577307296934613134453684324398636817932128906250000, 0.185969830516608397585898160286888014525175094604492187500000, 0.272821070648739838482299546740250661969184875488281250000000, 0.136190582834107815068946933934057597070932388305664062500000, 0.350740240108136591690168870627530850470066070556640625000000, 0.000120131992311552486551486096377772128107608295977115631104, 0.999879868007688354936135510797612369060516357421875000000000, 0.001209872963338849303702171589236513682408258318901062011719, 0.264988176241494621798722164385253563523292541503906250000000, 0.143124971877952811283307710255030542612075805664062500000000, 0.306387829277925793913794905165559612214565277099609375000000, 0.284289149639287863635672692907974123954772949218750000000000, 0.374005039798408045470523575204424560070037841796875000000000, 0.625994960201591843507173962279921397566795349121093750000000, 0.000209947723016968765524098428087995671376120299100875854492, 0.015926034417430057904541129687459033448249101638793945312500, 0.019615115836156795520173190539026109036058187484741210937500, 0.132457018202467580181291850749403238296508789062500000000000, 0.161519781574387955025429164379602298140525817871093750000000, 0.262554623898649197588639481182326562702655792236328125000000, 0.407717478347891348899878494194126687943935394287109375000000, 0.373050779688124722888176165724871680140495300292968750000000, 0.626949220311875166089521371759474277496337890625000000000000, 0.000121987349911814132899338936066868654961581341922283172607, 0.007821588901230941415221309398475568741559982299804687500000, 0.328605923565726210089366077227168716490268707275390625000000, 0.337788971283677852408544595164130441844463348388671875000000, 0.252107856415289710572125159160350449383258819580078125000000, 0.073553672484163390432598816914833150804042816162109375000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.001509815802472098391837085351596670079743489623069763183594, 0.099707835644051417967048678292485419660806655883789062500000, 0.168701418426951910145561441822792403399944305419921875000000, 0.230990819120067331082779560347262304276227951049804687500000, 0.131793921141620695713925215386552736163139343261718750000000, 0.298589572072207154462830658303573727607727050781250000000000, 0.068706617792629293139938795320631470531225204467773437500000, 0.295204095918081610427918803907232359051704406738281250000000, 0.704795904081918278549778733577113598585128784179687500000000, 0.014094362255097959285565778486670751590281724929809570312500, 0.241003598560575765796798464180028531700372695922851562500000, 0.221011595361855245345239495691203046590089797973632812500000, 0.523890443822470963652904174523428082466125488281250000000000, 1.000000000000000000000000000000000000000000000000000000000000, 0.000054599923560107009460132254652364736102754250168800354004, 0.007204689913434121108226637630878030904568731784820556640625, 0.992740710163005690702675565262325108051300048828125000000000, 1.000000000000000000000000000000000000000000000000000000000000, 1.000000000000000000000000000000000000000000000000000000000000, }; const double elem_table_log_probability [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = { -0.000115716530591520062594239337538937206772970966994762420654, -9.064424917075021070900220365729182958602905273437500000000000, -13.520604646423175054792409355286508798599243164062500000000000, -0.000001343000893767296712052561162564767727189973811618983746, -2.577891720978651601825504258158616721630096435546875000000000, -0.078971700466369670889932308455172460526227951049804687500000, 0.000000000000000000000000000000000000000000000000000000000000, -1.612037134131381055368592569720931351184844970703125000000000, -0.222494800137427506392384657374350354075431823730468750000000, -0.010846671177187771836769591971005866071209311485290527343750, -4.529315483514038120915756735485047101974487304687500000000000, -0.003648633607616148452623683340334537206217646598815917968750, -5.615226297668721500144783931318670511245727539062500000000000, -0.002435353337518350851781390176142849668394774198532104492188, -7.872715182829573166145564755424857139587402343750000000000000, -6.189236792082963845018639403861016035079956054687500000000000, 0.000000000000000000000000000000000000000000000000000000000000, -0.100078195781331494296217954342864686623215675354003906250000, -5.910876641640641970809610938886180520057678222656250000000000, -2.380292360271312634978357891668565571308135986328125000000000, 0.000000000000000000000000000000000000000000000000000000000000, -0.235878282572628383828572395941591821610927581787109375000000, -2.302565094793883382351395994191989302635192871093750000000000, -2.206173789605455404227996041299775242805480957031250000000000, 0.000000000000000000000000000000000000000000000000000000000000, -0.080970568540825488268453113960276823490858078002929687500000, -3.060624186220378017964094397029839456081390380859375000000000, -3.476328480144544208485513081541284918785095214843750000000000, 0.000000000000000000000000000000000000000000000000000000000000, -0.051451188958515865767839869704403099603950977325439453125000, -4.890269137820559386398144852137193083763122558593750000000000, -3.157766653355948971437783256988041102886199951171875000000000, -9.115110188972028737453001667745411396026611328125000000000000, -0.277606537419771426389303314863354898989200592041015625000000, -1.417144771312495832304989562544506043195724487304687500000000, -5.702921106825801444983881083317101001739501953125000000000000, -7.370109509296556282720302988309413194656372070312500000000000, -0.003973890456746663815690290277871099533513188362121582031250, -0.069799776156532433724066777358530089259147644042968750000000, -9.052483267360123875278077321127057075500488281250000000000000, -2.698559767416127019856730839819647371768951416015625000000000, -0.031077090678799931117159971449837030377238988876342773437500, -5.040234806716209270405215647770091891288757324218750000000000, -6.606921279942914004834619845496490597724914550781250000000000, -3.869880158236262079896050636307336390018463134765625000000000, -10.054321502209552008366699737962335348129272460937500000000000, -6.280705543488890540970714937429875135421752929687500000000000, 0.000000000000000000000000000000000000000000000000000000000000, -2.494713408178120150893164463923312723636627197265625000000000, -2.598150548864236686341655513388104736804962158203125000000000, -0.304975352295239643396485007542651146650314331054687500000000, -2.916671468480125817279713373864069581031799316406250000000000, -2.960099096648749483762230738648213446140289306640625000000000, -5.989873825712285437816717603709548711776733398437500000000000, -0.002507120169096173530054461053850900498218834400177001953125, -3.136127308188753737283605005359277129173278808593750000000000, -0.176879103699552453488053060937090776860713958740234375000000, -2.353768036988251211028000398073345422744750976562500000000000, -3.744066754776672834026385316974483430385589599609375000000000, 0.000000000000000000000000000000000000000000000000000000000000, -2.839535812544084603104010966490022838115692138671875000000000, -0.086067279673300162157190129619266372174024581909179687500000, -3.854190815670504033363386042765341699123382568359375000000000, -5.869613059277937416879922238877043128013610839843750000000000, 0.000000000000000000000000000000000000000000000000000000000000, -0.384532097536943340276849312431295402348041534423828125000000, -1.338531697560186861650777245813515037298202514648437500000000, -4.474222362274872466514352709054946899414062500000000000000000, -3.314664237037550087450199498562142252922058105468750000000000, -4.682574923715371539856278104707598686218261718750000000000000, -0.368900435688631012087768112905905582010746002197265625000000, -1.176014814002444008878001113771460950374603271484375000000000, -0.709996915609857004447746930964058265089988708496093750000000, -1.282563340904273152531800405995454639196395874023437500000000, -3.208794497707758708315850526560097932815551757812500000000000, -1.690023957076583371872402494773268699645996093750000000000000, -5.098093470692335316130083811003714799880981445312500000000000, -0.509027578151938331352255318051902577280998229980468750000000, -0.918993876681337473755206701753195375204086303710937500000000, -1.581308226517597503857359697576612234115600585937500000000000, -1.292790443930836863373201595095451921224594116210937500000000, -2.557425510595298323579527277615852653980255126953125000000000, -1.007906127076126923114429700945038348436355590820312500000000, -2.560009090805706488680471011321060359477996826171875000000000, 0.000000000000000000000000000000000000000000000000000000000000, -4.717395674310531639150667615467682480812072753906250000000000, -2.367523623737181281967423274181783199310302734375000000000000, -2.573048648630889889687978211441077291965484619140625000000000, -1.436804100526558380934716296906117349863052368164062500000000, -0.701071102975730831019518518587574362754821777343750000000000, -2.438328827816317101451204507611691951751708984375000000000000, -0.679443711102156733261381305055692791938781738281250000000000, -0.707041047215952844773312335746595636010169982910156250000000, -5.639977561836668762396129750413820147514343261718750000000000, -3.778337476933724126126890041632577776908874511718750000000000, -2.154756578276459499932116159470751881599426269531250000000000, -2.162821228909660220551813836209475994110107421875000000000000, -0.562358982058553724669991424889303743839263916015625000000000, -1.755669166607024767046141278115101158618927001953125000000000, -0.326158026142060741836559145667706616222858428955078125000000, -1.279023747338471794776637580071110278367996215820312500000000, -5.183244558647554178776317712618038058280944824218750000000000, -2.316622601837921013867571673472411930561065673828125000000000, -2.659157189193052328590738397906534373760223388671875000000000, -0.191430555333882340685036638205929193645715713500976562500000, 0.000000000000000000000000000000000000000000000000000000000000, -0.664709955358130821778672725486103445291519165039062500000000, -2.187165643480033949686003325041383504867553710937500000000000, -1.762875342696557545707491954090073704719543457031250000000000, -1.749916948420700224531287858553696423768997192382812500000000, -3.575421663722070153568211026140488684177398681640625000000000, 0.000000000000000000000000000000000000000000000000000000000000, -1.928896249393138528915869756019674241542816162109375000000000, -2.391455012103930855005273770075291395187377929687500000000000, -1.842710346617601580021528206998482346534729003906250000000000, -1.791617500319007794118419951701071113348007202148437500000000, -2.343409253862695162951013116980902850627899169921875000000000, -1.410993272797839370724659602274186909198760986328125000000000, -2.320581420206905942649200369487516582012176513671875000000000, -2.893121989774980473697496563545428216457366943359375000000000, -3.977827742728266446903262476553209125995635986328125000000000, -2.058944176423800787034679160569794476032257080078125000000000, -2.071037633074694905843671222100965678691864013671875000000000, -1.768515397703714908672623096208553761243820190429687500000000, -1.153751204177984268639534093381371349096298217773437500000000, -1.680987899482990099997437027923297137022018432617187500000000, 0.000000000000000000000000000000000000000000000000000000000000, -4.584627618010170380102863418869674205780029296875000000000000, -2.194060349407264354226754221599549055099487304687500000000000, -1.499076127310911887846600620832759886980056762695312500000000, -1.297315393792867643796284937707241624593734741210937500000000, -1.329738206325086657955125701846554875373840332031250000000000, -2.144028052451655508292560625704936683177947998046875000000000, -0.657028062796280343249577526876237243413925170898437500000000, -0.730619933776488150733996462804498150944709777832031250000000, -4.376665231519177190477876138174906373023986816406250000000000, -4.718561859232925925766721775289624929428100585937500000000000, -2.080320732081178736194715384044684469699859619140625000000000, -2.055854244595972435405428768717683851718902587890625000000000, -1.421850256682005708697147383645642548799514770507812500000000, -2.102221012532442756537420791573822498321533203125000000000000, -1.247305110167633124262920318869873881340026855468750000000000, -2.591584072043251474326552852289751172065734863281250000000000, -3.147605821582104113076638896018266677856445312500000000000000, -0.043904705171597842305875047941299271769821643829345703125000, -4.634868960235463575259018398355692625045776367187500000000000, -5.019441588675102039474040793720632791519165039062500000000000, -5.681312951243271847090454684803262352943420410156250000000000, -1.928467904013302591792466955666895955801010131835937500000000, -2.565779477876660052970692049711942672729492187500000000000000, -1.418220124080461719273671405971981585025787353515625000000000, -2.454375864191848055639866288402117788791656494140625000000000, -1.121710853164690879779641363711562007665634155273437500000000, -3.072235543110140021383358543971553444862365722656250000000000, -2.848272125086215300626690805074758827686309814453125000000000, -0.558456599237618478426270485215354710817337036132812500000000, -0.848845538512307262735134827380534261465072631835937500000000, -7.002324924918669424300787795800715684890747070312500000000000, -3.668865315739671117967191094066947698593139648437500000000000, -4.718597850559019590832576795946806669235229492187500000000000, -3.049096701706386802754877862753346562385559082031250000000000, -2.649356530974964485380951373372226953506469726562500000000000, -1.669314195717893856141245123581029474735260009765625000000000, -1.147567923673684653351756423944607377052307128906250000000000, -1.076533608421685217493291020218748599290847778320312500000000, 0.000000000000000000000000000000000000000000000000000000000000, -6.956634086757649271248737932182848453521728515625000000000000, -7.024068041375896243039278488140553236007690429687500000000000, -3.957918762987576943856993239023722708225250244140625000000000, -1.331783944951729026229259034153074026107788085937500000000000, -3.201281963147128539759478371706791222095489501953125000000000, -1.549644096147559713116947932576294988393783569335937500000000, -1.312726661492457758129148714942857623100280761718750000000000, -2.259939193445343441624117986066266894340515136718750000000000, -2.423926880572130126978436237550340592861175537109375000000000, 0.000000000000000000000000000000000000000000000000000000000000, -6.848557419252292000066972832428291440010070800781250000000000, -6.896829338845804180380127945682033896446228027343750000000000, -3.722582614455130833874818563344888389110565185546875000000000, -2.719309189565115580933252203976735472679138183593750000000000, -2.544130672523534641982223547529429197311401367187500000000000, -2.186395971313551900294669394497759640216827392578125000000000, -0.332715474789523235621402363904053345322608947753906250000000, -7.026345284034602123313106858404353260993957519531250000000000, -0.000888566530440708531556059934786162557429634034633636474609, -6.291503542654471203832144965417683124542236328125000000000000, -5.986690430272505913933400734094902873039245605468750000000000, -0.122741286268200244791160002932883799076080322265625000000000, -2.196932224286036738902794240857474505901336669921875000000000, 0.000000000000000000000000000000000000000000000000000000000000, -1.303722545566528001614869936020113527774810791015625000000000, -2.105864098995690714133388610207475721836090087890625000000000, -1.435578458464392248572494281688705086708068847656250000000000, -2.489761730430327446583760320208966732025146484375000000000000, -1.760899725099839052688821539049968123435974121093750000000000, -2.854908713800850428299327177228406071662902832031250000000000, -2.875608931369854293080834395368583500385284423828125000000000, -3.481133121051686263314195457496680319309234619140625000000000, -1.897909771509530774125096286297775804996490478515625000000000, -2.185845347988713882614320027641952037811279296875000000000000, -1.978717634408995396100294783536810427904129028320312500000000, -2.606504025680458358493751802598126232624053955078125000000000, -1.318818871830977013104302386636845767498016357421875000000000, -1.480720546667873893653677441761828958988189697265625000000000, -0.737928951383980402667361886415164917707443237304687500000000, -0.650285154216317162756411107693566009402275085449218750000000, -6.209801540532629005042508651968091726303100585937500000000000, -3.824651092041761124562526674708351492881774902343750000000000, -1.910642911045310476936265331460162997245788574218750000000000, -1.586341919151083468264573639316949993371963500976562500000000, -1.854752465261401805918239915627054870128631591796875000000000, -1.392573903203236485026650370855350047349929809570312500000000, -1.520605773895307155640921337180770933628082275390625000000000, 0.000000000000000000000000000000000000000000000000000000000000, -7.482256229504544720043668348807841539382934570312500000000000, -6.955920953990032629121742502320557832717895507812500000000000, -3.759679211363279094371137034613639116287231445312500000000000, -1.666593508702244319508167791354935616254806518554687500000000, -1.367483775157640080166743246081750839948654174804687500000000, -1.390471467634422086945278351777233183383941650390625000000000, -1.263728646463758931162146836868487298488616943359375000000000, 0.000000000000000000000000000000000000000000000000000000000000, -6.574163274461459316455602674977853894233703613281250000000000, -4.134373386461300370342542009893804788589477539062500000000000, -1.093543453498669215662175702163949608802795410156250000000000, -1.475402531411262208038692733680363744497299194335937500000000, -1.310160794679168905219057705835439264774322509765625000000000, -1.903132912453214142800561603507958352565765380859375000000000, 0.000000000000000000000000000000000000000000000000000000000000, -6.698361853186871606169461301760748028755187988281250000000000, -3.512501991875810691823289744206704199314117431640625000000000, -1.959662302151332857746979243529494851827621459960937500000000, -1.528776846501670894085123109107371419668197631835937500000000, -1.826181650981897996999236966075841337442398071289062500000000, -1.138653619844293141127877788676414638757705688476562500000000, -2.040520733384556528733355662552639842033386230468750000000000, -0.026334973760810023724054929061821894720196723937988281250000, -3.649996012338110329409346377360634505748748779296875000000000, -6.431737076661124596910212858347222208976745605468750000000000, -2.943735378782415867959798561059869825839996337890625000000000, -1.682170819948636486529380817955825477838516235351562500000000, -1.298939117547105670524842935265041887760162353515625000000000, -1.993700029844323484695678416755981743335723876953125000000000, -1.047709386165366352017258577689062803983688354492187500000000, -9.026919483738925720217594061978161334991455078125000000000000, -0.000120139208737295727770326425609681564310449175536632537842, -6.717239913861373423742406885139644145965576171875000000000000, -1.328070071947949681856471215724013745784759521484375000000000, -1.944037101159571623298916165367700159549713134765625000000000, -1.182903563582415440436079734354279935359954833984375000000000, -1.257763426233626136152565777592826634645462036132812500000000, -0.983486006261584555510069094452774152159690856933593750000000, -0.468412958710625382252601411892101168632507324218750000000000, -8.468651996251450597696930344682186841964721679687500000000000, -4.139800124064825226355424092616885900497436523437500000000000, -3.931454793849565199082007893593981862068176269531250000000000, -2.021497077106750417385683249449357390403747558593750000000000, -1.823127657291570224984411652258131653070449829101562500000000, -1.337296127555923419549799291417002677917480468750000000000000, -0.897180799465370992784585268964292481541633605957031250000000, -0.986040730030275258677363581227837130427360534667968750000000, -0.466889729967265909582607719130464829504489898681640625000000, -9.011593207854545539703394751995801925659179687500000000000000, -4.850867560763419739089385984698310494422912597656250000000000, -1.112896046865470500719652591214980930089950561523437500000000, -1.085333923798379451852724741911515593528747558593750000000000, -1.377898281389317913792069703049492090940475463867187500000000, -2.609739901377524873282709449995309114456176757812500000000000, 0.000000000000000000000000000000000000000000000000000000000000, -6.495767620713909451524159521795809268951416015625000000000000, -2.305511012885385291326656442834064364433288574218750000000000, -1.779624881481258524829058842442464083433151245117187500000000, -1.465377313319132568381064629647880792617797851562500000000000, -2.026515779816368212351562760886736214160919189453125000000000, -1.208685317218918919834891312348190695047378540039062500000000, -2.677909755533927516069070406956598162651062011718750000000000, -1.220088311290825400234894004825036972761154174804687500000000, -0.349847015838577246604756965098204091191291809082031250000000, -4.261980401619341662922124669421464204788208007812500000000000, -1.422943413816338820154783206817228347063064575195312500000000, -1.509540111140063478600836788245942443609237670898437500000000, -0.646472693195343506289418655796907842159271240234375000000000, 0.000000000000000000000000000000000000000000000000000000000000, -9.815478075212435982166425674222409725189208984375000000000000, -4.933023088148108747930109529988840222358703613281250000000000, -0.007285766694735069763655399555091207730583846569061279296875, 0.000000000000000000000000000000000000000000000000000000000000, 0.000000000000000000000000000000000000000000000000000000000000, }; #ifdef __cplusplus } #endif } // namespace IsoSpec isospec-1.9.1/.gitignore0000644000175000017500000000035513373520171015112 0ustar rusconirusconi.DS_Store *.pyc *.h.gch *.o a.out libIsoSpec++.so IsoSpecR_*.tar.gz IsoSpecPy/IsoSpecPy.egg-info IsoSpecPy/build IsoSpecPy/dist IsoSpecPy/IsoSpec++ IsoSpecR/src/CMakeLists.txt IsoSpecR/src/IsoSpecConfig.cmake.in IsoSpecR/src/symbols.rds