PKX/5META-INF/MANIFEST.MFeN0EwK7`'PQHLI^ 9_N{-,W2ps)ެh7R8%eX G`l&屋5z Iט}Tbl3)PK~9PK 85de/PK 85de/uos/PK 85de/uos/cogsci/PK 85de/uos/cogsci/ai/PK 85de/uos/cogsci/ai/btenbergen/PK 85&de/uos/cogsci/ai/btenbergen/bscthesis/PK 855de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/PK 5w+59de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/PK 5w+5&.e e Dde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layer.class1m>de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layerjava/lang/Object?de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/LayersneuronsM[Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;maxValueI(IIII)VCode()V  java/util/Random Jde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron   java/lang/Mathabs(I)I  nextInt  !ceil(D)D #$ % $ ' (IID[DZ)V ) *LineNumberTableLocalVariableTablethis@Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layer;rowscolsinputDimensionsrLjava/util/Random; currentNeuronijweights[DkpLLde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;findNeuronIndex(II)Irow ? @col B Cindex findNeuronP(II)Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron; => HgetPerceptronsO()[Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;toString()Ljava/lang/String;Njava/lang/StringBuilderP Neuon R(Ljava/lang/String;)V T QUappend(I)Ljava/lang/StringBuilder; WX QY: [-(Ljava/lang/String;)Ljava/lang/StringBuilder; W] Q^ LM ` Q`java/lang/Stringcconcat&(Ljava/lang/String;)Ljava/lang/String; ef dgsLjava/lang/String; SourceFile Layer.java!   w *Y:6*h*6i6Z: 6   *"R  Y*&(" +: * S,RCE FGI K&L,N1O7PIORSlTnUoStV}WLKZ-z ./0 1 2   345 #o6 )`7 1O89 4: t ;< => 6>6%*2A*2D>*,egi'g4l-46./6? 6B 4E /6 FG J **I2,x-  ./ ?  B JK /*,- ./LM <OL=,+QYSVZ\_*2a_bhL*+,.:- <./9ij56 klPK !5<XXCde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layer.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp; /** * This is the Layer class. * It implements a layer for a Multi-Layer Perceptron Neural Network. * The type of the layer can be either input, hidden or output. * * @version 02.05.2006 * @author Bastian Tenbergen - btenberg@uos.de */ import java.util.Random; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron; public class Layer implements Layers { /** * The array of neurons defining the layer. */ public Perceptron[] neurons; /** * The maximum value of weights and bias for each neuron. */ private int maxValue; /** * Constructor. A layer is defined by the number of neurons and the dimensionality of the input. * It is instantiated by invoking rows * cols Perceptrons. Each Perceptron * has as many weights as input dimensionality. The weight vectors are initialized randomly, however * limited to maxValue to prevent very large weight differences. * Neurons in Multi-Layer-Perceptrons always fire bipolar. * @param rows The number of rows in the layer * @param cols The number of cols in the layer * @param inputDimensions The dimensionality of the input vector * @param maxValue The maximum value for weights and bias for the neurons. */ public Layer(int rows, int cols, int inputDimensions, int maxValue) { Random r = new Random(); int currentNeuron = 0; neurons = new Perceptron[rows * cols]; this.maxValue = maxValue; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { double[] weights = new double[inputDimensions]; for (int k = 0; k < inputDimensions; k++) { weights[k] = (double) r.nextInt(Math.abs(this.maxValue)); }//end for-k Perceptron p = new Perceptron(i, j, r.nextInt((int) Math.abs(Math.ceil(this.maxValue))), weights, true); neurons[currentNeuron] = p; ++currentNeuron; }//end for-j }//end for-i } /** * Given a coordinate in the structure, this method returns the index of the * corresponding neuron. * @param row The X-Axis of the neuron * @param col The Y-Axis of the neuron * @return The index of the neuron. */ public int findNeuronIndex(int row, int col) { int index = -1; for (int i = 0; i < neurons.length; i++) { if (neurons[i].row == row && neurons[i].col == col) index = i; } return index; } /** * Given a coordinate in the structure, this method returns the corresponding * neuron. * @param row The X-Axis of the neuron * @param col The Y-Axis of the neuron * @return The neuron at the given position. */ public Perceptron findNeuron(int row, int col) { return this.neurons[findNeuronIndex(row, col)]; } /** * This method simply returns the neurons of the layer. * @return The neurons of the layer. */ public Perceptron[] getPerceptrons() { return neurons; } /** * Displays the neurons of the layer. */ public String toString() { String s = ""; for (int i = 0; i < this.neurons.length; i++) { s = s.concat("\n" + "Neuon " + i + ": " + this.neurons[i].toString()); } return s; } }PK 5w+5Ede/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layers.class1?de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layersjava/lang/ObjectfindNeuronIndex(II)I findNeuronP(II)Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;getPerceptronsO()[Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;toString()Ljava/lang/String; SourceFile Layers.java   PK !5E&Dde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layers.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp; /** * This is a Layer Interface. Layers for MLPs should be constructed by implementing this interface. * * @version 01.05.2006 * @author B. Tenbergen - btenberg@uos.de */ import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron; public interface Layers { /** * Given a coordinate in the structure, this method returns the index of the * corresponding neuron. * @param row The X-Axis of the neuron * @param col The Y-Axis of the neuron * @return The index of the neuron. */ public int findNeuronIndex(int row, int col); /** * Given a coordinate in the structure, this method returns the corresponding * neuron. * @param row The X-Axis of the neuron * @param col The Y-Axis of the neuron * @return The neuron at the given position. */ public Perceptron findNeuron(int row, int col); /** * This method simply returns the neurons of the Layer. * @return The neurons of the Layer. */ public Perceptron[] getPerceptrons(); /** * toString displays the Neurons of the Layer. */ public String toString(); }PK 5w+5. Cde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/MLPs.class1=de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/MLPsjava/lang/ObjectrunClassification()V ExceptionsXde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PerceptronInputException updateWinner([D)VupdateNeighbor findNeighborsQ([D)[Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron; findWinnerP([D)Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;toString()Ljava/lang/String; SourceFile MLPs.java        PK 5=1MMBde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/MLPs.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp; /** * This is a Multi-Layer Perceptron Interface. MLPs should be constructed by implementing this interface. * * @version 01.05.2006 * @author B. Tenbergen - btenberg@uos.de */ import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron; public interface MLPs { /** * Runs the classification process runs times. * For each pattern update(int[]) is called. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public void runClassification() throws PerceptronInputException; /** * Updates the winner neuron. To do so, the winner neuron needs to be determined * by calling findWinner(int[]). Each weight in the winner's weight vecotr is then updated * with the following formula:
* newWeight = oldWeight + (LEARNINGRATE * (input - oldWeight))
* @param input The weight vector that determines the winning neuron. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public void updateWinner(double[] input) throws PerceptronInputException; /** * Updates the winner's neighboring neurons. The neighboring neurons are determined and * then updated according to the following formula:
* newWeight = oldWeight + (LEARNINGRATE * (input - oldWeight))
* @param input The weight vector that determines the winning neuron. * @throws PerceptronInputException If the Perceptron's weight vector is not of equal length as the input vector. */ public void updateNeighbor(double[] input) throws PerceptronInputException; /** * This method determines the winner neuron's neighboring neurons and returns * them. This method needs to implement the topology of the MLP. * @param input The input vector determining the winning neuron. * @return The winner neuron's neighboring neurons. * @throws PerceptronInputException If the Perceptron's weight vector is not of equal length as the input vector. */ public Perceptron[] findNeighbors(double[] input) throws PerceptronInputException; /** * This method determines the winning neuron by comparing the activations given the input vector * of all neurons in the layer. This is very close to a standard SelectionSort algorithm, but since the * neurons are not sorted and only the maximum activation, this is done in O(n) time. * @param input The input vector determining the winning neuron. * @return The winning neuron. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public Perceptron findWinner(double[] input) throws PerceptronInputException; /** * toString method. Returns the String-Representation of this MLP. * @return The String representation of this MLP. */ public String toString(); }PK 5w+5=de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/PK 5w+5YM5 5 Fde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/SOM.class1@de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/SOMjava/lang/Object=de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/MLPsclosed_topologyZrunsIlearningrate_winnerDlearningrate_neighborpatterns[Ljava/lang/Object;rowscolsoutput@Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layer;(II[Ljava/lang/Object;DDIIZ)VCode()V      java/util/Random nextInt()I !" #>de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layer%[D'(IIII)V ) &*  , . 0 2LineNumberTableLocalVariableTablethisBLde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/SOM;maxValue newMaxValuerLjava/util/Random;(II[Ljava/lang/Object;)V?  ?(II[Ljava/lang/Object;I)V computeMax([Ljava/lang/Object;)I(I)I !D E1de/uos/cogsci/ai/btenbergen/bscthesis/tools/ToolsG minMaxElement([D)[D IJ HKrdmminmaxrunClassification ExceptionsXde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PerceptronInputExceptionQ updateWinner([D)V ST UupdateNeighbor WT Xji findWinnerP([D)Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron; \] ^Jde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron` getWeights()[D bc ad setWeights([D)Z fg ahinputwinnerLLde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron; winnerWeights findNeighborsQ([D)[Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron; no p neighborsM[Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;currentNeighborWeightsgetPerceptronsO()[Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron; uv &w  y  {row } a~col aneurons s &findNeuronIndex(II)I & winnerIndexleftrightupperlower activation([D)D amaxtoString()Ljava/lang/String; & showPatternsjava/lang/SystemoutLjava/io/PrintStream;  Patterns:java/io/PrintStreamprintln(Ljava/lang/String;)V print(D)V       logPatterns edu/udo/cs/yale/tools/LogService logMessage(Ljava/lang/String;I)V java/lang/Double(D)Ljava/lang/String;  SourceFileSOM.java!      , d**-*  &Y :  $6  6 *&Y-2( +-*/*1*346 fl mp$q-r4s7v;zQW]c5z d67d d dd d d d8 d 49 ;)9 - :; <[ *-=@4 5*67  Af *-=@4 5467   BC5Y M,+F>+2(L:,$>1 143545675-:;&M N'OPR<<1= **2(V**2(Y*݄*3ͱ4 $0;5 <679Z )[ STPR 9*+_M,eN6--1*/+1-1gkcR-,-iW4 (28549679j'3kl .m'$[ WTPR U*+qM,6>,2eN6--1*1+1-1gkcR-,2-iW,4*   7AJT5>U67Uj'Ors3t'E[ $Z noPR *+_M*-xN6-a*z*|*,R,K*-?*-,`,6*-,,`6 a:-2S- 2S,L,*|d?*-,d,6*-,,`6 a:-2S- 2S,*zdF,?*-,`,6*-,,d6a:-2S-2S,*zdL,*|d?*-,d,6*-,,d6a:-2S-2S,Z*-,`,6*-,,`6 *-,,d6a:-2S- 2S-2S,*|dZ*-,d,6*-,,`6 *-,,d6a:-2S- 2S-2S,Z*-,d,6*-,`,6*-,,`6 a:-2S-2S- 2S,*zd]*-,d,6*-,`,6*-,,d6a:-2S-2S-2Sa:,v,o*-*|d6*-,`,6*-,,`6 *-*zd6a:-2S-2S- 2S-2S,|,*|do*-,d,6*-6*-,,`6 *-*zd*|d6a:-2S-2S- 2S-2S,*zdv,o*-*zd*|d6*-,`,6*-6 *-,,d6a:-2S-2S- 2S-2S,*zd|,*|do*-,d,6*-*zd6*-*|d6 *-,,d6a:-2S-2S- 2S-2S,u*-,*|d6*-,`,6*-,,`6 *-,,d6a:-2S-2S- 2S-2S,*|dp*-,d,6*-,6*-,,`6 *-,,d6a:-2S-2S- 2S-2S,*-u*-,d,6*-,`,6*-,,`6 *-*zd,6a:-2S-2S- 2S-2S,*zdx*-,d,6*-,`,6*-*zd,6 *-,,d6a:-2S-2S- 2S-2Sa:*d`6a:-2S-dd6a:-2Ssd6`6a:-2S-2SN-d6`6$-dd66d6`6a:-2S-2S4  ,3M`sy !$%&'(!)),C-V.i/o0w1456789:;>?@A#B)C1D9EAHHI[JnKLMNORSTUVWXY\de-f@gShciijqkylmqrstuvwxyz ~2EPciqy)<Obhpx(;Nagow $*5>DJU[agoz5|Y67j'klsyrsrsrsorsrs)rsrsrs rsi rs rsi rs rsh rs rsg rs#rsrs* rsJ rsgrsrs ) V) D [D G -\ Y 2W Y )_ Z (_ b D [    `) ) D n1 4 @I N ED I <L L ;L O $ a     i  # ! c& & c& & b& & a& ) s  1 1  S6 ; P9 9 O9 9 N9 < \]PR F*-x:62+962+I( (9624*    '.15@5HF67Fj''  =s :k / &[ 2*-4!5 67W<==*2(1*2(ٲ*4* *+ ,-#.+,<0D+P2V35 W67 F[ -Z F<4=*2(1*2(ڄ*ɱ4":; <=">(<9;EA5 F67=[  ,Z PK \(5:XXEde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/SOM.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som; /** * This is the SOM class. * It implements a Self-Organizing Map. A SOM is a neural network * with two layers and the following structure:
* - An Inputlayer with n neurons. The activation of these neurons * is equal to the input values.
* - An Outputlayer with m neurons. Only one neuron in this layer is * active (output: 1) - all others are silent (output: 0). Winner * neurons and it's neighboring neurons are updated with a fixed * learning rate.
* - An input vector with d dimensions.
* - Every output neuron is connected to every input neuron.
* * @version 19.07.2006 * @author Bastian Tenbergen - btenberg@uos.de */ import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException; import de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools; import edu.udo.cs.yale.tools.LogService; import java.util.Random; public class SOM implements MLPs { /** The Topology of this Map. If true, the last neuron of each row or col is connected to the first one. */ private boolean closed_topology; /** The number of classification runs to be performed. */ private int runs; /** The learning rate. Defines how far the weight vector of the winning neuron is "pulled" into the direction of the input vector. */ private double learningrate_winner; /** The learning rate of the winner's neighboring neurons. */ private double learningrate_neighbor; /** This array contains all patterns, i.e. the input vectors. For simplicity reasons, this is an Object array that contains double arrays instead of a two dimensional matrix. Whenever a pattern is taken out of the array, it needs to be casted to a double[]. This should increase the performance on slow machines */ private Object[] patterns; /** Sets the number of rows of this SOM. */ private int rows; /** Sets the number of cols of this SOM. */ private int cols; /** The output layer. */ public Layer output; //The input layer. // private Layer input; /** * Constructor. * Creates a new Self-Organizing Map. * * @param rows The number of rows of this SOM. * @param cols The number of columns of this SOM. * @param patterns The training patterns. Must be an Object array containing * double arrays. * @param learningrate_winner Defines how far the weight vector of the winning neuron is "pulled" into * the direction of the input vector. * @param learningrate_neighbor Defines how far the weight vectors of the winner's neighbors is updated. * @param runs The number of classification runs to be performed. * @param maxValue The maximum value for weights and bias for the neurons. * @param closed_topology The Topology of this Map. If true, the last neuron of each row or col is connected to the first one. */ public SOM(int rows, int cols, Object[] patterns, double learningrate_winner, double learningrate_neighbor, int runs, int maxValue, boolean closed_topology) { this.patterns = patterns; this.closed_topology = closed_topology; int newMaxValue; switch (maxValue) { case -1: Random r = new Random(); newMaxValue = r.nextInt(); break; // case -2: newMaxValue = Math.abs(computeMax(this.patterns)); // break; default: newMaxValue = maxValue; break; } this.output = new Layer(rows, cols, ((double[]) patterns[0]).length, newMaxValue); // input = new Layer(0, 0, 0); // Since the activation of the input layer equals the input values, // the network is implemented as just an output layer. this.learningrate_winner = learningrate_winner; this.learningrate_neighbor = learningrate_neighbor; this.runs = runs; } /** * Constructor. * Creates a new Self-Organizing Map with default values for learningrates and runs. * A sensible maximum value for the neuron's weights and bias is computed automatically. * * @param rows The number of rows of this SOM. * @param cols The number of columns of this SOM. * @param patterns The training patterns. Must be an Object array containing * double arrays. */ public SOM(int rows, int cols, Object[] patterns) { this(rows, cols, patterns, 1, 0.25, 1, -1, false); } /** * Constructor. * Creates a new Self-Organizing Map with default values for learningrates. * A sensible maximum value for the neuron's weights and bias is computed automatically. * * @param rows The number of rows of this SOM. * @param cols The number of columns of this SOM. * @param patterns The training patterns. Must be an Object array containing * double arrays. * @param runs The number of runs to be performed. The more runs are performed, the more "prototypical" * the output neurons are to the input clusters. */ public SOM(int rows, int cols, Object[] patterns, int runs) { this(rows, cols, patterns, 1, 0.25, runs, -1, false); } /** * This method computues the maximum sensible bias and weight values. * @param patterns A sensible maximum is computed according to these patterns. * @return A reasonable maximum threshold. */ public int computeMax(Object[] patterns) { //We need a Random Object Random r = new Random(); //take a random pattern... int rdm = r.nextInt(patterns.length); //...and compute the minimal and maximal element //of that pattern. double[] minmax = Tools.minMaxElement(((double[]) patterns[rdm])); do { //Then, generate a random int rdm = r.nextInt(); } while (!(rdm < minmax[0]) && rdm > minmax[1]); //If the new random int is smaller than the //smallest, or bigger than the biggest //element in the pattern, generate a new one return rdm; } /** * Runs the classification process runs times. * For each pattern, the winner neuron is determined and updated. The winner neuron's * neighboring neurons are updated accordingly. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public void runClassification() throws PerceptronInputException { for (int j = 0; j < runs; j++) { for (int i = 0; i < patterns.length; i++) { updateWinner((double[]) patterns[i]); updateNeighbor((double[]) patterns[i]); } } } /** * Updates the winner neuron of the output layer. To do so, the winner neuron needs to be determined * by calling findWinner(int[]). Each weight in the winner's weight vecotr is then updated * with the following formula:
* newWeight = oldWeight + (LEARNINGRATE * (input - oldWeight))
* @param input The weight vector that determines the winning neuron. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public void updateWinner(double[] input) throws PerceptronInputException { Perceptron winner = findWinner(input); double[] winnerWeights = winner.getWeights(); for (int i = 0; i < winnerWeights.length; i++) { winnerWeights[i] = winnerWeights[i] + (learningrate_winner * (input[i] - winnerWeights[i])); } winner.setWeights(winnerWeights); } /** * Updates the winner neuron's neighboring neurons. To do so, the neighbors need to be determined * by calling findNeighbors(int[]). Each weight in each neighbor's weight vecotr is then updated * with the following formula:
* newWeight = oldWeight + (LEARNINGRATE * (input - oldWeight))
* @param input The weight vector that determines the winning neuron. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public void updateNeighbor(double[] input) throws PerceptronInputException { Perceptron[] neighbors = findNeighbors(input); double[] currentNeighborWeights; if (neighbors.length == 0) return; else { for (int i = 0; i < neighbors.length; i++) { currentNeighborWeights = neighbors[i].getWeights(); for (int j = 0; j < currentNeighborWeights.length; j++) { currentNeighborWeights[j] = currentNeighborWeights[j] + (learningrate_neighbor * (input[j] - currentNeighborWeights[j])); }//end for-j neighbors[i].setWeights(currentNeighborWeights); }//end for-i }//end else } /** * This method determines the winner neuron's neighboring neurons and returns * them according to the here implemented architecture of the SOM. * @param input The input vector determining the winning neuron. * @return The winner neuron's neighboring neurons. * @throws PerceptronInputException If the Perceptron's weight vector is not of equal length as the input vector. */ public Perceptron[] findNeighbors(double[] input) throws PerceptronInputException { Perceptron winner = findWinner(input); Perceptron[] neurons = this.output.getPerceptrons(); Perceptron[] neighbors; //allocate neighbors int winnerIndex = 0; //allocate winner index int left, right, upper, lower; //allocate neighbor indexes if (neurons.length == 1) return new Perceptron[0]; //set neighbor relations for rectangle architecture if (rows > 1 && cols > 1) { //... with open topology... if (!this.closed_topology) { //winner is in upper left corner -> only right und lower neighbor if (winner.row == 0 && winner.col == 0 && this.output.neurons.length > 1) { right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); neighbors = new Perceptron[2]; neighbors[0] = neurons[right]; neighbors[1] = neurons[lower]; } //winner is in upper right corner -> only left und lower neighbor if (winner.row == 0 && winner.col == cols-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); neighbors = new Perceptron[2]; neighbors[0] = neurons[left]; neighbors[1] = neurons[lower]; } //winner is in lower left corner -> only right und upper neighbor if (winner.row == rows-1 && winner.col == 0) { right = this.output.findNeuronIndex(winner.row+1, winner.col); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[2]; neighbors[0] = neurons[right]; neighbors[1] = neurons[upper]; } //winner is in lower right corner -> only left und upper neighbor if (winner.row == rows-1 && winner.col == cols-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[2]; neighbors[0] = neurons[left]; neighbors[1] = neurons[upper]; } //if winner in first column -> no left neighbor if (winner.col == 0) { right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[3]; neighbors[0] = neurons[right]; neighbors[1] = neurons[lower]; neighbors[2] = neurons[upper]; } //if winner in last column -> no right neighbor if (winner.col == cols-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[3]; neighbors[0] = neurons[left]; neighbors[1] = neurons[lower]; neighbors[2] = neurons[upper]; } //if winner in first row -> no upper neighbor if (winner.row == 0) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); neighbors = new Perceptron[3]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; } //if winner in last row -> no lower neighbor if (winner.row == rows-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(winner.row+1, winner.col); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[3]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[upper]; } else { neighbors = new Perceptron[0]; } } //... with closed topology... else { //winner is in upper left corner -> left neighbor is last in first row // upper one is last in first column if (winner.row == 0 && winner.col == 0) { left = this.output.findNeuronIndex(0, cols-1); right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(rows-1, 0); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //winner is in upper right corner -> right neighbor is first in first row // upper one is last in last col if (winner.row == 0 && winner.col == cols-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(0,0); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(rows-1, cols-1); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //winner is in lower left corner -> left is last in last col // lower is first in first row if (winner.row == rows-1 && winner.col == 0) { left = this.output.findNeuronIndex(rows-1, cols-1); right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(0, 0); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //winner is in lower right corner -> right is first in last row // lower is last in first row if (winner.row == rows-1 && winner.col == cols-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(rows-1, 0); lower = this.output.findNeuronIndex(0, cols-1); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //if winner in first column -> left is last col, same row if (winner.col == 0) { left = this.output.findNeuronIndex(winner.row, cols-1); right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //if winner in last column -> right is first col, same row if (winner.col == cols-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(winner.row, 0); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //if winner in first row -> upper is last row, same col if (winner.row == 0 && this.output.neurons.length > 1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(rows-1, winner.col); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //if winner in last row -> lower is first row, same col if (winner.row == rows-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(rows-1, winner.col); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } else { neighbors = new Perceptron[0]; } } } //set neighbor relations for chain/cirlce architecture else { //...with open topology... (chain) if (!this.closed_topology) { //if winner is leftmost neuron -> no left neighbor if (winnerIndex == 0) { right = winnerIndex+1; neighbors = new Perceptron[1]; neighbors[0] = neurons[right]; } //if winner is rightmost neuron -> no right neighbor else if (winnerIndex == neurons.length-1) { left = winnerIndex-1; neighbors = new Perceptron[1]; neighbors[0] = neurons[left]; } //if winner is in the middle -> set both neighbors else { left = winnerIndex-1; right = winnerIndex+1; neighbors = new Perceptron[2]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; } } //...with closed topology... (circle) else {//if (this.closed_topology) { //if winner is leftmost neuron -> left neighbor is last neuron if (winnerIndex == 0) { left = neurons.length-1; right = winnerIndex+1; } //if winner is rightmost neuron -> right neighbor is first neuron else if (winnerIndex == neurons.length-1) { left = winnerIndex-1; right = 0; } //if winner is in the middle -> set both neighbors as usual else { left = winnerIndex-1; right = winnerIndex+1; } neighbors = new Perceptron[2]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; } } return neighbors; } /** * This method determines the winning neuron by comparing the activations given the input vector * of all neurons in the layer. This is very close to a standard SelectionSort algorithm, but since the * neurons are not sorted and only the maximum activation, this is done in O(n) time. * @param input The input vector determining the winning neuron. * @return The winning neuron. * @throws PerceptronInputException If the Perceptron's weight vector is not of equal length as the input vector. */ public Perceptron findWinner(double[] input) throws PerceptronInputException { double activation; Perceptron[] neurons = this.output.getPerceptrons(); int winner = 0; double max = neurons[winner].activation(input); for (int i = 0; i < neurons.length; i++) { activation = neurons[i].activation(input); if (activation > max) { max = activation; winner = i; } } return neurons[winner]; } /** * toString method. Just calls the toString of the output layer, since this SOM just consists * of an output layer. * @return The String representation of this SOM. */ public String toString() { return this.output.toString(); } /** * This method confirms the given input vectors by prompting them. * Called usually by methods testing the functionality. */ public void showPatterns() { System.out.println("Patterns:"); for (int i = 0; i < patterns.length; i++) { for (int j = 0; j < ((double []) patterns[i]).length; j++) { System.out.print(((double[]) patterns[i])[j]); System.out.print(" "); } System.out.print(" "); } System.out.println(); } /** * This method logs the current status of the SOM by sending information * to Yale's Log-Console. The output is similar to showPatterns(). */ protected void logPatterns() { LogService.logMessage("Patterns:", LogService.STATUS); for (int i = 0; i < patterns.length; i++) { for (int j = 0; j < ((double []) patterns[i]).length; j++) { LogService.logMessage(Double.toString(((double[]) patterns[i])[j]), LogService.STATUS); LogService.logMessage(" ", LogService.STATUS); } } } }PK 5w+5@de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PK 5w+5^de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PerceptronInputException.class1$Xde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PerceptronInputExceptionjava/lang/ExceptionserialVersionUIDJ ConstantValue*msgLjava/lang/String;causeLjava/lang/Throwable;()VCode*(Ljava/lang/String;Ljava/lang/Throwable;)V  LineNumberTableLocalVariableTablethisZLde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PerceptronInputException;    (Ljava/lang/String;)V(Ljava/lang/Throwable;)V getMessage()Ljava/lang/String; SourceFilePerceptronInputException.java!  5* 45 Y**+*,=> ?@   ?*+ GH ?*+ PQ  !/*Y "#PK 5 ]de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PerceptronInputException.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron; /** * The class PercepronInputException is thrown when the Input-Vector of a Perceptron * is not of equal length as its Weight-Vector. * Javadoc taken from java.lang.Exception class. * * * @version 01.05.2006 * @author Bastian Tenbergen - btenberg@uos.de */ public class PerceptronInputException extends Exception { private static final long serialVersionUID = 42; private String msg; protected Throwable cause; /** * Constructs a new exception with null as its detail message. * The cause is not initialized, and may subsequently be initialized by a call to Throwable.initCause(java.lang.Throwable). */ public PerceptronInputException() { this(null, null); } /** * Constructs a new exception with the specified detail message and cause. * Note that the detail message associated with cause is not automatically incorporated in this exception's detail message. * @param msg the detail message (which is saved for later retrieval by the Throwable.getMessage() method). * @param cause the cause (which is saved for later retrieval by the Throwable.getCause() method). (A null value is permitted, and indicates that the cause is nonexistent or unknown.) */ public PerceptronInputException(String msg, Throwable cause) { this.msg = msg; this.cause = cause; } /** * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently be initialized by a call to Throwable.initCause(java.lang.Throwable). * @param msg the detail message. The detail message is saved for later retrieval by the Throwable.getMessage() method. */ public PerceptronInputException(String msg) { this(msg, null); } /** * Constructs a new exception with the specified cause and a detail message of (cause==null ? null : cause.toString()) (which typically contains the class and detail message of cause). * This constructor is useful for exceptions that are little more than wrappers for other throwables (for example, PrivilegedActionException). * @param cause the cause (which is saved for later retrieval by the Throwable.getCause() method). (A null value is permitted, and indicates that the cause is nonexistent or unknown.) */ public PerceptronInputException(Throwable cause) { this(null, cause); } /** * Just returns the detail message of the exception. * * @return the detailed message as a java.lang.String */ public String getMessage() { return msg; } }PK 5w+5B Pde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron.class1xJde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptronjava/lang/ObjectBIASDweights[DbipolarZrowIcol returnPos returnNeg (IID[DZ)VCode()V          setBipolar  !LineNumberTableLocalVariableTablethisLLde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;  '  )fire([D)I ExceptionsXde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PerceptronInputException. activation([D)D 01 2inputs6Input vector length not equal to weight vector length.5(Ljava/lang/String;)V 7 /8acti setWeights([D)Zjava/lang/System>errLjava/io/PrintStream; @A ?BVWarning: New weight vector not of the same length as the old one. Weights not updated.Djava/io/PrintStreamFprintln H7 GI newWeights getWeights()[DtoString()Ljava/lang/String;Pjava/lang/DoubleR(D)V T SU NO SWjava/lang/StringYconcat&(Ljava/lang/String;)Ljava/lang/String; [\ Z] _, The Perceptron fires bipolar.a, The Perceptron fires binary.cjava/lang/StringBuildereBias: g f8append(D)Ljava/lang/StringBuilder; jk fl , Weights: n-(Ljava/lang/String;)Ljava/lang/StringBuilder; jp fq fWsLjava/lang/String; SourceFilePerceptron.java!     $****)***"#"HJ KLMNP#Q$>$%&$ $ $$$  P*(* ****#XYZ[$ %&+,-/O*+3**(**# fg$%&401-/:+* /Y69I6(*1+1kcI*(#q ruvw+v8z$*:%&:4$:; <=-+* CEJ=*+1R+# "+$ -%&-K; LM/*#$ %&NOeQL="+SY*1VX^L+`^L** +b^L +d^LfYhi*mor+rs#"$0AH$ e%&btu+; vwPK 5NkkOde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron; /** * This is the Perceptron class. * It implements a perceptron with an arbitrary number of inputs. * * @version 01.05.2006 * @author Bastian Tenbergen - btenberg@uos.de */ public class Perceptron { /** The biad of the perceptron that needs to be exceeded to cause an activation. */ public final double BIAS; /** The weights of the perceptron that weighing the input */ public double[] weights; /** If true the perceptron fires bipolar (output: 1 or -1), else binary (output: 1 or 0).*/ public boolean bipolar; /** If the perceptron is embedded in a neural network, this indicates the row in which it is located.*/ public int row; /** If the perceptron is embedded in a neural network, this indicates the column in which it is located.*/ public int col; /** The value that is returned when the activation exceeds the threshold. */ private int returnPos; /** The value that is returned when the activation does not exceed the threshold. */ private int returnNeg; /** * Constructor. A standard Perceptron is invoked when called. * @param row The row of the structure in which this Perceptron is located. * @param col The column of the structure in which this Perceptron is located. * @param BIAS The bias (theta, threshold) of the Perceptron. Once set, never changeable. * @param weights The weight vector of the perceptron. * @param bipolar Determines, if the Perceptron is bipolar or binary. * If true, the negative output is -1. If false, the negative * output is 0. The positive output is always 1. */ public Perceptron(int row, int col, double BIAS, double[] weights, boolean bipolar) { this.row = row; this.col = col; this.BIAS = BIAS; this.weights = weights; this.bipolar = bipolar; setBipolar(); } /** * Sets the Perceptron to binary or bipolar. Called by the constructor. */ private void setBipolar() { this.returnPos = 1; if (this.bipolar) this.returnNeg = -1; else this.returnNeg = 0; } /** * Fires the perceptron. Calls activation(int[]) to compute scalar product. * @param inputs The input vector. * @return 1 if the scalar product of the input and the weights is higher than the bias. * -1 or 0 else (this depends on the Perceptron being bipolar or binary. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public int fire(double[] inputs) throws PerceptronInputException { if (activation(inputs) >= BIAS) return returnPos; else return returnNeg; } /** * This method computes the scalar product of the input and the weights. * @param inputs The input vector. * @return The activation of the Perceptron - scalar product of weights x input. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public double activation(double[] inputs) throws PerceptronInputException { if (inputs.length != weights.length) { throw new PerceptronInputException("Input vector length not equal to weight vector length."); } double act = 0; for (int i = 0; i < weights.length; i++) { act += weights[i] * inputs[i]; } return act; } /** * This method updates the weight vector of the Perceptron. * @param newWeights The new weight vector. * @return true if update was successful, false else. */ public boolean setWeights(double[] newWeights) { if (newWeights.length != weights.length) { System.err.println("Warning: New weight vector not of the same length as the old one. Weights not updated."); return false; } else { for (int i = 0; i < newWeights.length; i++) { weights[i] = newWeights[i]; } return true; } } /** * This method just returns the weights. * @return The weight vector of the Perceptron. */ public double[] getWeights() { return weights; } /** * toString method. Returns the String representation of the Perceptron. * @return The String representation of the Perceptron. */ public String toString() { String s = ""; for (int i = 0; i < weights.length; i++) { s = s.concat((new Double(weights[i])).toString()); s = s.concat(" "); } if (this.bipolar) s = s.concat(", The Perceptron fires bipolar."); else s = s.concat(", The Perceptron fires binary."); return "Bias: " + this.BIAS + ", Weights: " + s; } }PK 5w+5,de/uos/cogsci/ai/btenbergen/bscthesis/tools/PK 5w+5 ?de/uos/cogsci/ai/btenbergen/bscthesis/tools/OperatorTools.class19de/uos/cogsci/ai/btenbergen/bscthesis/tools/OperatorToolsjava/lang/Object()VCode  LineNumberTableLocalVariableTablethis;Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/OperatorTools;convertFilename&(Ljava/lang/String;)Ljava/lang/String;java/lang/StringcharAt(I)C  java/lang/CharacterisLetterOrDigit(C)Z  replace(CC)Ljava/lang/String;  length()I ! "ö$oe& replaceAll8(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; () *Ö,Oe.ä0ae2Ä4Ae6ü8ue:Ü<Ue>ß@ssB_0Dconcat F GfilenameLjava/lang/String;resultiIfindQueryInClusters\(Ljava/lang/String;[Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster;)Ljava/lang/String;P3de/uos/cogsci/ai/btenbergen/bscthesis/tools/ClusterRcontentLjava/util/Vector; TU SVjava/util/VectorX elementAt(I)Ljava/lang/Object; Z[ Y\contains(Ljava/lang/CharSequence;)Z ^_ ` toStringln()Ljava/lang/String; bc Sdsize f! Ygequals(Ljava/lang/Object;)Z ij k`No Files found. Please check query file nameand/or lower number of neurons to improve accuracy. m hummedFileclusters6[Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster;sjdisplaySongList&(Ljava/util/Vector;)Ljava/lang/String; Signature:(Ljava/util/Vector;)Ljava/lang/String;java/lang/StringBuilderx File number z(Ljava/lang/String;)V | y}append(I)Ljava/lang/StringBuilder;  y: -(Ljava/lang/String;)Ljava/lang/StringBuilder;  y toString c ysongListLocalVariableTypeTable&Ljava/util/Vector;createFileClustersL([ILjava/util/Vector;)[Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster; Exceptions(java/lang/ArrayIndexOutOfBoundsException`([ILjava/util/Vector;)[Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster; Y(ILjava/util/Vector;)V  S addElement(Ljava/lang/Object;)V Y positions[IshowFileClustersJ([Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster;)Ljava/lang/String;isEmpty()Z Y S SourceFileOperatorTools.java!/*  -  q*L=+++_L+#+%'+L+-/+L+13+L+57+L+9;+L+=?+L+AC+L+EHL+ :<=>?=)A2B;CDDMEVF_GhHoI qIJoKJ%LM NOZQM>=6&+2W]*a,+2eHM+2Wh҄+,Ql ,nHM, * TVXZ#\.X?VH`QaXe 4ZoJZpqWrJCLM 4sM tuvw?QL=0+yY{~*]HL*h+ npq2p=t ?U<rJ8LM ? vP*SM>,SYYYS,>,*.2W+]:+h,+AA &+ACN 4PPUJpqLM(&LM P 1QL=$*2W+*2HL+HL*+ &/ 1pq.rJ*LMPK !56>de/uos/cogsci/ai/btenbergen/bscthesis/tools/OperatorTools.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.tools; /** * This class provides some simple Tools for the SOMInput Operator for Yale. * * @version 25.08.2006 * @author Bastian Tenbergen - btenberg@uos.de */ // The methods in this class have been moved here to improve the structural layout of // the package as well as to provide an easier overview of the source-code. import java.util.Vector; import java.lang.ArrayIndexOutOfBoundsException; import de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster; public class OperatorTools { /** * Replaces all characters which are not letters or digits by _ (underscore). Additionally all non-english characters * like umlauts or ß are replaced. The file itself is not modified, since only * the String representation of the file name is taken into conderation.
* Modified from ValueSeriesPlugin v3.2 for Yale.
*

* @author Ingo Mierswa (original author) * @author Bastian Tenbergen (modifications) * @param filename The file name to be converted. Usually the user's input file, but this works with any kind of String. * @return The converted file name. The original file is not changed, since this operator only retrieves the String representation of the user's input. * @version current: 27.08.2006, original: $Id: MusicFile.java,v 1.3 2006/03/21 15:35:26 ingomierswa Exp $ */ public static String convertFilename(String filename) { String result = filename; for (int i = 0; i < result.length(); i++) { if (!Character.isLetterOrDigit(result.charAt(i))) result = result.replace(result.charAt(i), '_'); } result = result.replaceAll("\u00f6", "oe"); result = result.replaceAll("\u00d6", "Oe"); result = result.replaceAll("\u00e4", "ae"); result = result.replaceAll("\u00c4", "Ae"); result = result.replaceAll("\u00fc", "ue"); result = result.replaceAll("\u00dc", "Ue"); result = result.replaceAll("\u00df", "ss"); result = result.concat("_0"); return result; } /** * This method checks if a String occures in the Vector of any cluster in a given Cluster-array. * If a occurrence has been found, the whole cluster is printed out. * @param hummedFile Look for this String in the clusters. * @param clusters The cluster array in which to look for the String. * @return The String representation of the cluster(s) in which the String was found. */ public static String findQueryInClusters(String hummedFile, Cluster[] clusters) { String s = ""; //for every single cluster... for (int i = 0; i < clusters.length; i++) { //...look at it's Vector's elements... for (int j = 0; j < clusters[i].content.size(); j++) { //and check, if it contains the query pattern. if (clusters[i].content.elementAt(j).contains(hummedFile)) //if it does, print out the cluster in line form and concatenate s = s.concat(clusters[i].toStringln()); }//end for-j }//end for-i //create error message if nothing was found. (s should be empty then) if (s.equals("")) { s = s.concat("No Files found. Please check query file name" + "and/or lower number of neurons to improve accuracy.\n"); } return s; } /** * This method simply shows the processed songlist. * @param songList A Vector containing the processed songs. * @return The String representation of the songlist in a ResultService-friendly form. */ public static String displaySongList(Vector songList) { String s = ""; for (int i = 0; i < songList.size(); i++) { s = s.concat("File number " + i + ": " + songList.elementAt(i) + "\n"); } return s; } /** * This method creates Cluster-Objects given an array containing the pattern's closest neurons * and a Vector containing the Song-Names. The Cluster-Objects can hence be referenced more easily. * @param positions An array containing the closest neurons to a given pattern. * @param songList A Vector containing the Song-Names. * @return A Cluster-Array containing the Clusters. */ public static Cluster[] createFileClusters(int[] positions, Vector songList) throws ArrayIndexOutOfBoundsException { Cluster[] clusters = new Cluster[positions.length]; //initialize all Clusters and assign ID. for (int i = 0; i < clusters.length; i++) clusters[i] = new Cluster(i, new Vector()); //fill Clusters with the song names. for (int i = 0; i < songList.size(); i++) { //vorher positions iteriert try { clusters[positions[i]].content.addElement(songList.elementAt(i)); } catch (ArrayIndexOutOfBoundsException aiobe) { // throw new ArrayIndexOutOfBoundsException(); } } return clusters; } /** * This method creates Cluster Objects of the processed files and shows them. Similar files occur * in the same cluster. * @param clusters The Clusters of similar songs. * @return The clusters in a ResultService-friendly form. */ public static String showFileClusters(Cluster[] clusters) { String s = ""; for (int i = 0; i < clusters.length; i++) { if (!clusters[i].content.isEmpty()) { s = s.concat(clusters[i].toString()); s = s.concat("\n"); } } return s; } }PK 5w+5;(ILjava/util/Vector;)V*(ILjava/util/Vector;)VCode()V      LineNumberTableLocalVariableTablethis5Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster;LocalVariableTypeTabletoString()Ljava/lang/String;java/lang/StringBuilder Cluster # (Ljava/lang/String;)V ! "append(I)Ljava/lang/StringBuilder; $% &: (-(Ljava/lang/String;)Ljava/lang/StringBuilder; $* +java/util/Vector-  ./ / toStringln3 elementAt(I)Ljava/lang/Object; 56 .7java/lang/String9concat&(Ljava/lang/String;)Ljava/lang/String; ;< := ?size()I AB .CsLjava/lang/String;i SourceFile Cluster.java!     k***,57 89   M#Y #*'),*0,1A #2/4L=+*8:>L+@>L*D+KMOPM-R /,EF(GHIPK |5-lN 8de/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.tools; /** * This class represents a Cluster Object. A Cluster consists of an ID (positive * Integer value) and a Vector containing Strings in which the patterns are stored. * * @version 24.08.2006 * @author Bastian Tenbergen - btenberg@uos.de */ import java.util.Vector; public class Cluster { /** The ID of the Cluster. */ public int id; /** All Patterns in the Cluster. */ public Vector content; /** * Constructor. Invokes a Cluster Object Instance. * @param id The ID of the Cluster. * @param content The Patterns that belong to this cluster. */ public Cluster(int id, Vector content) { this.id = id; this.content = content; } /** * This method returns the String representation of the cluster. * @return The String representation of this cluster in form of the cluster ID and the content. */ public String toString() { return "Cluster # " + this.id + ": " + this.content.toString(); } /** * This method returns the String representation of this cluster in lines. * Only the content is printed, the ID is omitted. * @return This cluster's content in lines. */ public String toStringln() { String s = ""; for (int i = 0; i < this.content.size(); i++) { s = s.concat(this.content.elementAt(i)); s = s.concat("\n"); } return s; } }PK 5w+5!vv7de/uos/cogsci/ai/btenbergen/bscthesis/tools/Tools.class111de/uos/cogsci/ai/btenbergen/bscthesis/tools/Toolsjava/lang/Object()VCode  LineNumberTableLocalVariableTablethis3Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Tools; quicksort([DII)[Djava/lang/System arraycopy*(Ljava/lang/Object;ILjava/lang/Object;II)V  qs([DII)V  array[DonsetIoffsetsortMetmpDxypivot minMaxElement([D)[D  'minMedMaxElementpositionOfSmallest([D)Iminposi SourceFile Tools.java!/*  ,  m*N*-*--d- 9:;< *  p66*`l19*1*1*1J**1R*)R * * NIJKOQOR"S%R/T6U;VCWHXKYN[U^b_o` Hppp; !m"j#a$! %&K**d(WY*1RY**d1R h i  )&T&**d(WY*1RY**l1RY**d1R r s & *+)*1H>6*1' >*1H* " ' *)%,!#- ./0PK /(5e6de/uos/cogsci/ai/btenbergen/bscthesis/tools/Tools.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.tools; /** * This is class providing tools for multiple purposes. * Currently implemented:
* - a generic quicksort algorithm sorting double arrays
* - a generic quicksort algorithm sorting double arrays but maintining the original array
* - a method providing the smallest and largest element of a double array
* - a method providing the smallest, the largest and the median element of a double array
* - a method returning the index of the smallest element in a given double array
* * @version 20.07.2006 * @author Bastian Tenbergen - btenberg@uos.de */ public class Tools { /** * A standard recursive QuickSort Algorithm. This algorithm takes a double array and * sorts it from the biggest to the smallest element. It takes the median element as the random pivot element. * This method calls the private method qs(double[], int, int) that does the actual job. * This method copies the given array so that the original array is maintained. * * @param array the array to be sorted * @param onset the onset element from which shall be sorted (inclusive) * @param offset the offset element until which shall be sorted (inclusive) */ public static double[] quicksort(double[] array, int onset, int offset) { double[] sortMe = new double[array.length]; System.arraycopy(array, 0, sortMe, 0, array.length); qs(sortMe, 0, sortMe.length-1); return sortMe; } /** * This method does the actual sorting. * * @param array the array to be sorted * @param onset the onset element from which shall be sorted (inclusive) * @param offset the offset element until which shall be sorted (inclusive) */ private static void qs (double[] array, int onset, int offset) { double tmp; // we need a temp variable to copy values into int x = onset; // and two temp variables serving as the upper int y = offset; // and lower marker double pivot = array[(onset + offset) / 2]; // randomly assign a pivot element // here: the median element do { while (array[x] < pivot) // as long as the lower current element x++; // is smaller as the pivot element: increase while (array[y] > pivot) // as long as the upper current element y--; // is lager as the pivot element: decrease if ( x <= y ) { // if the lower curr elem is smaller or equal to the upper curr elem tmp = array[x]; // array[x] = array[y]; // switch the elements and array[y] = tmp; // x++; // increase lower marker and y--; // decrease upper marker to continue } } while (x <= y); // continue until all elements in left half are smaller // than the ones in the right half if (onset < y) qs(array, onset, y); // sort left half if (x < offset ) qs(array, x, offset); // sort right half } /** * Returns the smallest and biggest element of a given double array in a new double array. * @param array the (unsorted) array containing one smallest and one biggest element * @return a new array with the input array's smallest and biggest as first and second element. */ public static double[] minMaxElement(double[] array) { quicksort(array, 0, array.length-1); return new double[] {array[0], array[array.length-1]}; } /** * Returns the smallest and biggest and the medium element of a given double array in a new double array. * @param array the (unsorted) array containing one smallest and one biggest element * @return a new array with the input array's smallest, biggest and the medium element. */ public static double[] minMedMaxElement(double[] array) { quicksort(array, 0, array.length-1); return new double[] {array[0], array[array.length/2], array[array.length-1]}; } /** * This method returns the position of the smallest element of a given array. * It does so in a SelectionSort-like way, but runs through array only once (since we * don't need to sort the whole array. * * @param array the array containing one smallest element, whose position is of interest. * @return the position of the smallest element in the array. */ public static int positionOfSmallest(double[] array) { double min = array[0]; //the current minimum value in array. int pos = 0; //Position of the smallest. Zero at beginning. for (int i = 1; i < array.length; i++) //Go through array, skip first position. if (array[i] < min) { //If smallere element found... pos = i; //...remember it's position... min = array[i]; //...and it's value. } return pos; //when done, return the position. } }PK 5w+5j&. . :de/uos/cogsci/ai/btenbergen/bscthesis/tools/Distance.class1`4de/uos/cogsci/ai/btenbergen/bscthesis/tools/Distancejava/lang/Object EUCLIDEANI ConstantValue MANHATTANNOMINALpatterns[Ljava/lang/Object;neuronsM[Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;metricd([Ljava/lang/Object;[Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;I)VCode()V        LineNumberTableLocalVariableTablethis6Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Distance;c([Ljava/lang/Object;[Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;)V  #measureDistance()[I[D'Jde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron)weights +' *,euclideanDistance([D[D)D ./ 0manhattanDistance 2/ 3nominalDistance 5/ 61de/uos/cogsci/ai/btenbergen/bscthesis/tools/Tools8positionOfSmallest([D)I :; 9<closest_neurons_per_pattern[Iicurrent_pattern_distancesjjava/lang/DoubleCisNaN(D)Z EF DGjava/lang/MathIsqrt(D)D KL JMe1e2sumDcounterdabs WL JX SourceFile Distance.java!     l**+*,*FG HIJ* ! "J*+,$ RS  ! %&Q* L=*N6*s7U-**2(*2-1RZ-**2(*2-4R<-**2(*2-7R-**2(*2-1R+-=O*]*C+6 ]` bef8gVhtijoe`u4 !>? @A'B./TJ663+1H&,1H)+1,1g+1,1gkcJ+)N9O.  58BHMPHT !TQ'TR'RSTOU:@H VT2/JJ66,+1H,1H)+1,1gYcJ+)9Z.  .1;>CFHJ !JQ'JR'HSTEU3@> VT5/GJ66-+1H ,1H+1,1)cJ+)\.  +/2<AC>G !GQ'GR'ESTBU4@^_PK !5bb9de/uos/cogsci/ai/btenbergen/bscthesis/tools/Distance.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.tools; /** * This is the Distance-Tool for the Self-Organizing-Map Operator for Yale. * It computes the distances between the a Perceptron array's weight Vector and * the input Vector. Please note that the Distance measure methods can be used in * a quasi-static way be invoking a Distance Object with null as the Perceptron array * and the patterns. * * @version 15.08.2006 * @author B. Tenbergen - btenberg@uos.de */ import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron; import de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools; public class Distance { /** Constant for the Euclidean Distance. */ public static final int EUCLIDEAN = 0; /** Constant for the Manhattan Distance. */ public static final int MANHATTAN = 1; /** Constant for the Nominal Distance. */ public static final int NOMINAL = 2; /** The array containing the patterns. */ private Object[] patterns; /** The Perceptron array that needs to be measured against the patterns. */ private Perceptron[] neurons; /** The metric to be used. */ private int metric; /** * Constructor. A new Distance Object is created upon invokation. * @param neurons The Perceptron array of which the weight Vectors need to be measured. * @param patterns The Patterns that need to be measured. * @param metric The Metric to be used. */ public Distance(Object[] patterns, Perceptron[] neurons, int metric) { this.patterns = patterns; this.neurons = neurons; this.metric = metric; } /** * Constructor. A new Distance Object is created upon invokation. Euclidean Distance is used. * @param neurons The Perceptron array of which the weight Vectors need to be measured. * @param patterns The Patterns that need to be measured. */ public Distance(Object[] patterns, Perceptron[] neurons) { this(patterns, neurons, Distance.EUCLIDEAN); } /** * For each pattern, this method returns the closest neuron. * @return The array containing the positions of the neurons.tern. */ public int[] measureDistance() { //We need an array in which we store the neurons that are closest to the //current pattern. Needs to be as long as the patterns. int[] closest_neurons_per_pattern = new int[this.patterns.length]; //For ever pattern... for (int i = 0; i < this.patterns.length; i++) { //...we need an array that stores the distance to all neurons double[] current_pattern_distances = new double[this.neurons.length]; //For all neurons... for (int j = 0; j < this.neurons.length; j++) { switch (this.metric) { //choose metric case Distance.EUCLIDEAN: current_pattern_distances[j] = euclideanDistance((double[]) this.patterns[i], this.neurons[j].weights); break; case Distance.MANHATTAN: current_pattern_distances[j] = manhattanDistance((double[]) this.patterns[i], this.neurons[j].weights); break; case Distance.NOMINAL: current_pattern_distances[j] = nominalDistance((double[]) this.patterns[i], this.neurons[j].weights); break; default: current_pattern_distances[j] = euclideanDistance((double[]) this.patterns[i], this.neurons[j].weights); break; } //check the distance to the current pattern. //Then, find the position of the smallest distance. //The position corresponds to the neuron that is closest to the pattern. closest_neurons_per_pattern[i] = Tools.positionOfSmallest(current_pattern_distances); } } //Return the array containing the positions of the neurons. Each position //in the array corresponds to a pattern (in numerical order) and each //value at each position is the neuron closest to the pattern. return closest_neurons_per_pattern; } /** * An euclidean distance. Taken from the ClusteringPlugin v3.2 for Yale. * * @param e1 The first Vector * @param e2 The second Vector * @return The nominal Distance between both Vectors. * @author Michael Wurst * @version $Id: EuclideanDistance.java,v 1.4 2006/03/21 15:35:24 ingomierswa Exp $ */ public double euclideanDistance(double[] e1, double[] e2) { double sum = 0.0; int counter = 0; for (int i = 0; i < e1.length; i++) { if((!Double.isNaN(e1[i]))&&(!Double.isNaN(e2[i]))) { sum = sum + (e1[i] - e2[i]) * (e1[i] - e2[i]); counter++; } } double d = Math.sqrt(sum); if(counter > 0) return d; else return Double.NaN; } /** * The Manhattan distance. Taken from the ClusteringPlugin v3.2 for Yale. * * @param e1 The first Vector * @param e2 The second Vector * @return The nominal Distance between both Vectors. * @author Michael Wurst * @version $Id: ManhattanDistance.java,v 1.3 2006/03/21 15:35:24 ingomierswa Exp $ * */ public double manhattanDistance(double[] e1, double[] e2) { double sum = 0.0; int counter = 0; for (int i = 0; i < e1.length; i++) { if((!Double.isNaN(e1[i]))&&(!Double.isNaN(e2[i]))) { sum = sum + Math.abs(e1[i] - e2[i]); counter++; } } double d = sum; if(counter > 0) return d; else return Double.NaN; } /** * An euclidean distance. Taken from the ClusteringPlugin v3.2 for Yale. * * @param e1 The first Vector * @param e2 The second Vector * @return The nominal Distance between both Vectors. * @author Michael Wurst * @version $Id: NominalDistance.java,v 1.1 2006/03/29 14:24:47 mjwurst Exp $ * */ public double nominalDistance(double[] e1, double[] e2) { double sum = 0.0; int counter = 0; for (int i = 0; i < e1.length; i++) { if((!Double.isNaN(e1[i]))&&(!Double.isNaN(e2[i]))) { if(e1[i] != e2[i]) sum = sum + 1.0; counter++; } } if(counter > 0) return sum; else return Double.NaN; } }PK 5w+5+de/uos/cogsci/ai/btenbergen/bscthesis/yale/PK Q/5'uu?de/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMFileHandler.class19de/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMFileHandlerjava/lang/Objectpatterns[Ljava/lang/Object;songListLjava/util/Vector; Signature&Ljava/util/Vector; verbosingZfilenameLjava/io/File;(Ljava/io/File;Z)VCode()V  java/util/Vector      LineNumberTableLocalVariableTablethis;Lde/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMFileHandler;(Ljava/io/File;)V  # parseFile(ZZ)[Ljava/lang/Object; Exceptionsjava/io/FileNotFoundException(java/io/IOException*java/io/BufferedReader,java/io/FileReader. " /0(Ljava/io/Reader;)V 2 -3add(Ljava/lang/Object;)Z 56 7readLine()Ljava/lang/String; 9: -;size()I => ?  AparseFeatureVectors)(Ljava/util/Vector;ZZ)[Ljava/lang/Object; CD E normalizefilterfeature_vectorslineLjava/lang/String;inLjava/io/BufferedReader;fnfeLjava/io/FileNotFoundException;ioeLjava/io/IOException;LocalVariableTypeTable=(Ljava/util/Vector;ZZ)[Ljava/lang/Object;java/lang/StringBufferT elementAt(I)Ljava/lang/Object; VW Xjava/lang/StringZ(Ljava/lang/String;)V \ U] _indexOf(Ljava/lang/String;)I ab Uclength e> Uf substring(II)Ljava/lang/String; hi Ujjava/lang/Doublel parseDouble(Ljava/lang/String;)D no mpvalueOf(D)Ljava/lang/Double; rs mt addElement(Ljava/lang/Object;)V vw x?zequals |6 [}delete(II)Ljava/lang/StringBuffer;  UtoString : U doubleValue()D mclear   doLogging  normalizeFeatureVectors(([Ljava/lang/Object;)[Ljava/lang/Object;  filterValues weightFeatures java/lang/NumberFormatExceptionvaluesiIcurrent_patternLjava/lang/StringBuffer;endnfe!Ljava/lang/NumberFormatException;tmp[Dj&Ljava/util/Vector;@java/lang/Mathpow(DD)D sqrt(D)D  newPatternsmeansrmsdtmp2Dtmp3tmp1tmp4abs @@@$@YAcA.java/lang/StringBuilderNumber of patterns:  ]append(I)Ljava/lang/StringBuilder;  edu/udo/cs/yale/tools/LogService logMessage(Ljava/lang/String;I)V pattern number : -(Ljava/lang/String;)Ljava/lang/StringBuilder; (D)Ljava/lang/String; mconcat&(Ljava/lang/String;)Ljava/lang/String; [ s SourceFileSOMFileHandler.java!    h**Y*+*F9GHI  !  "?*+$ PQ ! %&')+QYN-Y/Y*14: -8W~I\ Q !QG QH IIJK.JKLM6NO;PQR II CD S# Y:6UY+Y[^:f`d6 g6kquy/:k{~`W*y`Wg@:6   YmR  *BS+@=*****BB***BB***BB*B:PPf !$-:PRbp| p  !IG H   !-ZR*1 RI  V+M>,+2S,+2N-:+d9o96 '6 - \1+ 2 1cR  +  -6 - \1+oR  -6 D9 6  + 2 1- 1gc9  + k9   R  -6 66 , 2 + 2 1 1oR  + 2ل  +,z  *07=CI Zdnt~ "')+) '. !*07=@. F q K ; ' = - <=2>+21 +2R+2܄++:< >#<1::A*< !<8*G=>+21+2\1kR+21˜+2\1kR+21—#+21Ę+2\1kR+21+2\1oR+21Ɨ+2\1oR+2E+7+2 JL N(OHPZQlRzUVLJY* ! Yͷ*BҶ<pY۷`ݶM> ,*B21M,`M*B2,*Y[M,M,ل*B6 bce8g;i@nSoZikq{rscu* !y;LK=.PK Q/5rq::>de/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMFileHandler.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.yale; /** * This is the SOMFileHandler class. * This class requires a String representation of a filename. The file * is then loaded and parsed. The file needs to contain double values that are * separated by a blank space (" "). Every line in the file corresponds to a * pattern and each value in each line stands for an extracted feature. * * @version 08.09.2006 * @author Bastian Tenbergen - btenberg@uos.de */ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Vector; import edu.udo.cs.yale.tools.LogService; public class SOMFileHandler { /** Each element in this Object[] is another double[] with the extracted features. */ private Object[] patterns; /** Each row in the file contains the filename of the song, the features belong to. These filenames are stored in this vector for reference. */ public Vector songList = new Vector(); /** If true, the operator will send detailed information about what is going on to Yale's Log-Console. */ private boolean verbosing; /** The file to be parsed. */ private File filename; /** * Constructor. Sets the fields filename and verbosing accordingly. * @param filename The file to be parsed. * @param verbosing If true, detailed information about what is going on is sent to Yale's Log-Console. */ public SOMFileHandler(File filename, boolean verbosing) { this.filename = filename; this.verbosing = verbosing; } /** * Constructor. Sets the field filename accordingly. Verbosing is set to true. * @param filename The file to be parsed. */ public SOMFileHandler(File filename) { this(filename, true); } /** * This Method parses a given input file. Each row in the file is a Feture Vector and is * extraced as such and stored in a java.util.Vector. The Vector will hence contain Strings * as elements whereas each String corresponds to a row in the file. The method parseFeatureVectors * is hence called with this Vector to extract the actual features out of each String. * That method's output is returned by this method. * * @param normalize If true, the input patterns will be normalized by dividing every element x(i,j) by the root * mean square deviation of the corresponding column, o(j). * @param filter If true, features with an absolute value smaller than 1 are filtered out. * @return An Object[] containing java.util.Vector as elements. Each Vector has doubles as elements. * The doubles correspond to an actual feature while the java.util.Vector corresponds to each feature Vector, * i.e. the rows in the File. * @throws FileNotFoundException iff the file cannot be found. * @throws IOException iff an error occured during file access. */ public Object[] parseFile(boolean normalize, boolean filter) throws FileNotFoundException, IOException { //need a Vector to store all rows in the file. Vector feature_vectors = new Vector(); try { String line; //temp variable for current row... BufferedReader in = new BufferedReader(new FileReader(filename)); //we need a reader to access the file... while ((line = in.readLine()) != null) { //while there are still lines left... feature_vectors.add(line); //store them in the Vector. } } //iff file is not found catch (FileNotFoundException fnfe) { throw fnfe; } //iff error occured during file access catch (IOException ioe) { //e.g. file is corrupted throw ioe; } finally { } //initialize the Object[] according to the //Vector size. Important! Otherwise there will //be not enough space for every pattern. patterns = new Object[feature_vectors.size()]; //extract the features out of each vector using //parseFeatureVectors and return it. return parseFeatureVectors(feature_vectors, normalize, filter); } /** * This method extracts double value features out of a given java.util.Vector. Each String in * the Vector is parsed and NaN values are ignored. Every numerical value is hence considered a double * and stored in a java.util.Vector. Hence every Vector corresponds to a row in the input file * parsed feature values. All rows are stored in an Object[]. * @param feature_vectors The Vector containing String representations of blank space separated double values. * @param normalize If true, the input patterns will be normalized by dividing every element x(i,j) by the root * mean square deviation of the corresponding column, o(j). * @param filter If true, features with an absolute value smaller than 1 are filtered out. * @return An Object[] containing java.util.Vector as elements. Every element is a row in the input file. */ private Object[] parseFeatureVectors(Vector feature_vectors, boolean normalize, boolean filter) { //a vector containing all the doubles of one line. //We make use of a Vector here because of two reasons: //1. we don't know how long the feature vector is, hence we cannot initialize an array properly //2. Vectors can be considered as more dynamic arrays. arrays in java are implemented as vectors //anyways so there is no effect on performance. Vector values = new Vector(); //Remember: A line is one element in 'feature_vectors' //-> One Music File //parse every line for (int i = 0; i < feature_vectors.size(); i++) { //retrieve every line as a StringBuffer StringBuffer current_pattern = new StringBuffer(feature_vectors.elementAt(i)); int end; //now, retrieve all doubles in this line; ignore NaN's. while (!(current_pattern.length() == 0)) { //Set end to the next occurance of a blank space end = current_pattern.indexOf(" "); //If end == -1, then there is no blank until the end //of the line. Hence, set end to the end of the string. if (end == -1) end = current_pattern.length(); try { //try to parse the substring from the beginning the the current next //end pisition (i.e. the index of the next blank space) //as a double and store it as an element of the Vector values.addElement(Double.parseDouble(current_pattern.substring(0, end))); } catch (NumberFormatException nfe) { //The StringBuffer does not only contain the features of the song, //but the filename plus directory name. //If the String is _no_ double, it could be either the filename, the dir name //and filename or two subsequent questionmarks "?". This is because two operators in //Yale cannot extract a feature and hence produce a ?. Seems to be a Bug in Yale's ValueSeriesPlugin. if ((current_pattern.substring(0, end)).equals("?")) { current_pattern.delete(0, end+3); //Remove the questionmarks from the string } else { //The rest should be the dir name and songname. Store both in the songList Vector. this.songList.addElement(current_pattern.toString()); } } //delete retrieved double. When line is successfully parsed, //current_pattern should be empty or contain only NaN's. current_pattern.delete(0, end+1); }//done retrieving doubles //store just retrieved doubles in a temporary double[]... double[] tmp = new double[values.size()]; for (int j = 0; j < tmp.length; j++) { tmp[j] = values.elementAt(j); } //and remove all values from Vector so that //it is empty and ready for the next String values.clear(); //store the retrieved doubles in the Object[] patterns[i] = tmp; }//END of for-LOOP //-> done parsing line. if (verbosing) doLogging(); if (normalize) patterns = normalizeFeatureVectors(patterns); if (filter) patterns = filterValues(patterns); if (true) patterns = weightFeatures(patterns); return patterns; } /** * This method normalizes the features in each vector by deviding them by the root mean square deviation. * This is necessary, since there might be a very large scope of the elements in the feature vectors. This * causes features with a very large absolute value to have a larger impact on the distance measuring than * features with a very small absolute value. 'Small features' hence might not play a significant role anymore. * To avoid that behaviour, the root mean square deviation for every column is calculated and each element x(i,j) * is devided by the rmsd o(j). The root mean square deviation is calculated as follows:
* o(j) = sqrt( (1 / ( n - 1) ) * (sum_over_vectors( x(i,j) - mean(j)) )^2 )
* with n = the number of vectors
* x(i,j) = the j-th value of the i-th vector
* mean(j) = the mean value of all j-th elements of all vectors (i.e. the j-th column)
*
* The features are hence updated as follows:
* x(i,j)_new = ( x(i,j)_old / o(j) ) * * @param patterns The patterns that need to be normalized. * @return The normalized patterns. */ private Object[] normalizeFeatureVectors(Object[] patterns) { Object[] newPatterns = new Object[patterns.length]; for (int i = 0; i < newPatterns.length; i++) { newPatterns[i] = new double[((double[]) patterns[i]).length]; } //need space to store medians double[] means = new double[((double[]) patterns[1]).length]; //need space to store root mean square deviation double[] rmsd = new double[means.length]; double tmp2 = (patterns.length - 1); double tmp3 = 1 / tmp2; //first, compute median of every column in the matrix. I.e. Every j-th element in each vector. //take every j-th element... for (int j = 0; j < means.length; j++) { //...of every vector... for (int i = 0; i < patterns.length; i++) { //and add the elements... means[j] += ((double[]) patterns[i])[j]; } } //...then... for (int j = 0; j < means.length; j++) { //...divide by the number of patterns (i.e. how many j-th elements have been added) means[j] /= patterns.length; } //second, compute root mean square deviation of every column //for every median... for (int j = 0; j < means.length; j++) { double tmp1 = 0; //...subtract the median of the j-th element in each vector from the j-th element of the i-th vector //and square the values. for (int i = 0; i < patterns.length; i++) { tmp1 = tmp1 + Math.pow((((double[]) patterns[i])[j] - means[j]), 2); } //then, multiply with 1 devided by the number of vectors minus 1... double tmp4 = tmp3 * tmp1; //...and calculate the square root of the outcome. rmsd[j] = Math.sqrt(tmp4); } //third, replace old values in every vector by the old value devided by the root mean square deviation. //run through every vector... for (int i = 0; i < patterns.length; i++) { //and replace every element by the old element devided by the root mean square deviation. for (int j = 0; j < ((double[]) patterns[i]).length; j++) { ((double[]) newPatterns[i])[j] = ((double[]) patterns[i])[j] / rmsd[j]; } } return newPatterns; } /** * This method filters potentially irrelevant features from the set of patterns. * Feautes with an absolute value smaller than 1 are set to zero. * @param patterns The set of patterns to be filtered. * @return The filtered feature vectors. */ private Object[] filterValues(Object[] patterns) { for (int i = 0; i < patterns.length; i++) { for (int j = 0; j < ((double[]) patterns[i]).length; j++) { if (Math.abs(((double[]) patterns[i])[j]) < 1) ((double[]) patterns[i])[j] = 0; } } return patterns; } /** * @param patterns * @return */ private Object[] weightFeatures(Object[] patterns) { for (int i = 0; i < patterns.length; i++) { for (int j = 0; j < ((double[]) patterns[i]).length; j++) { if (Math.abs(((double[]) patterns[i])[j]) < 1) ((double[]) patterns[i])[j] *= 1000; if (Math.abs(((double[]) patterns[i])[j]) < 10) ((double[]) patterns[i])[j] *= 100; if (Math.abs(((double[]) patterns[i])[j]) > 10) { if (Math.abs(((double[]) patterns[i])[j]) < 100) { ((double[]) patterns[i])[j] *= 10; } } if (Math.abs(((double[]) patterns[i])[j]) > 1000) ((double[]) patterns[i])[j] /= 10; if (Math.abs(((double[]) patterns[i])[j]) > 10000000) ((double[]) patterns[i])[j] /= 1000000; } } return patterns; } /** * This method just shows the retrieved features in the Object[] by sending it to Yale's Log-Console. */ private void doLogging() { LogService.logMessage("Number of patterns: " + patterns.length, LogService.STATUS); for (int i = 0; i < patterns.length; i++) { LogService.logMessage("pattern number " + (i+1) + ": ", LogService.STATUS); String s = ""; for (int j = 0; j < ((double[]) patterns[i]).length; j++) { //concat each element of each array to a string //this avoids that Yale prints out every feature in an own line //but all features of one vector in one line instead. s = s.concat(Double.toString(((double[]) patterns[i])[j])); s = s.concat(" "); //just a separator } s = s.concat(songList.elementAt(i)); s = s.concat("\n"); LogService.logMessage(s, LogService.STATUS); } } }PK /5Ka"W'W'9de/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMInput.class13de/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMInput!edu/udo/cs/yale/operator/Operator!edu/udo/cs/yale/operator/IOObject OUTPUT_CLASS[Ljava/lang/Class;result_neurons-Ledu/udo/cs/yale/operator/SimpleResultObject; result_filesresult_clustersresult_matchesfilenameLjava/io/File; verbosingZ numberColsI numberRowsrunsmaxValueclosed_topologylearningrate_winnerDlearningrate_neighborpatterns[Ljava/lang/Object; hummedFileLjava/lang/String;clusters6[Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster;metricmetrics[Ljava/lang/String; normalizefilterclass$0Ljava/lang/Class;()VCodejava/lang/Class++edu/udo/cs/yale/operator/SimpleResultObject-  /LineNumberTableLocalVariableTable1(Ledu/udo/cs/yale/operator/OperatorDescription;)V 34 5java/lang/String7 Euclidean9 Manhattan;Nominal= "# ?this5Lde/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMInput; description.Ledu/udo/cs/yale/operator/OperatorDescription;getParameterTypes()Ljava/util/List; SignatureF()Ljava/util/List; EF I4edu/udo/cs/yale/operator/parameter/ParameterTypeFileKFeature Vector FileM+The File containing the extracted Features.O:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V 3Q LRjava/util/ListTadd(Ljava/lang/Object;)Z VW UXQuery Input FileZ4The File to which similar ones shall be queried for.\mp3^3edu/udo/cs/yale/operator/parameter/ParameterTypeInt`Number Neuron-ColumnsbTThe number of columns of the SOM. Together with the rows, this defines the topology.d*(Ljava/lang/String;Ljava/lang/String;III)V 3g ahNumber Neuron-RowsjTThe number of rows of the SOM. Together with the columns, this defines the topology.l7edu/udo/cs/yale/operator/parameter/ParameterTypeBooleannClosed TopologypChoose the topology of the Self-Organizing Map. If checked, the last neuron of each row and column is connected to the respective first one.r((Ljava/lang/String;Ljava/lang/String;Z)V 3t ou Training RunswBThe amount of training cycles in which in the neurons are trained.y6edu/udo/cs/yale/operator/parameter/ParameterTypeDouble{Learning Rate Winner}pThe Learning Rate of the SOM's Winner Neuron. Note that a Learning Rate of 0 causes the Map not to learn at all.*(Ljava/lang/String;Ljava/lang/String;DDD)V 3 |Learning Rate NeighborThe Learning Rate of the Winner's Neiboring Neurons. Not that a Learning Rate of 0 represents a WTA-Network and a Learning Rate of 1 turns the Neighbors into Winner Neurons.? Maximal ValuefThe maximum value of bias and weights the neurons may not exceed. Choose -1 for automatic computation.>edu/udo/cs/yale/operator/parameter/ParameterTypeStringCategoryMetricMThe Metric used to measure the distance between the patterns and the neurons.L(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V 3 Filter PatternsGIf checked, features with a very small absolute value are filtered out.Normalize PatternsOIf checked, the input patterns from the Feature Vector File will be normalized. VerbosingGIf checked, the system will output information about what is happening.typesLjava/util/List;LocalVariableTypeTableDLjava/util/List; initApplyapply&()[Ledu/udo/cs/yale/operator/IOObject; Exceptions*edu/udo/cs/yale/operator/OperatorException java/io/FilegetParameterAsString&(Ljava/lang/String;)Ljava/lang/String; (Ljava/lang/String;)V 3  getParameterAsBoolean(Ljava/lang/String;)Z     getParameterAsDouble(Ljava/lang/String;)D     getParameterAsInt(Ljava/lang/String;)I         getName()Ljava/lang/String;   !  $  % equalsIgnoreCase 89de/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMFileHandler(Ljava/io/File;Z)V 3  parseFile(ZZ)[Ljava/lang/Object;  File successfully parsed. edu/udo/cs/yale/tools/LogService logMessage(Ljava/lang/String;I)V Invoking Self-Organizing Map@de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/SOM(II[Ljava/lang/Object;DDIIZ)V 3 Before classification:toString Classifying...runClassification ) After Classification:&Classification completed successfully. Measuring Distances... 4de/uos/cogsci/ai/btenbergen/bscthesis/tools/Distance output@Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layer;  >de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/LayerneuronsM[Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;  d([Ljava/lang/Object;[Lde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron;I)V 3 measureDistance()[I  Distance Measuring complete. Creating clusters..."songListLjava/util/Vector; $% &9de/uos/cogsci/ai/btenbergen/bscthesis/tools/OperatorTools(createFileClustersL([ILjava/util/Vector;)[Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster; *+ ),  .Clusters created.0Recording Results...2%Output neurons after classification: 4#edu/udo/cs/yale/tools/ResultService6 logResult 8 79Clusters;java/lang/StringBuilder=Files displayed in clusters ? >showFileClustersJ([Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster;)Ljava/lang/String; BC )Dappend-(Ljava/lang/String;)Ljava/lang/StringBuilder; FG >H >'(Ljava/lang/String;Ljava/lang/String;)V 3K .L N User InputP2Songs in Cluster that come closest to the input RconvertFilename T )UfindQueryInClusters\(Ljava/lang/String;[Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster;)Ljava/lang/String; WX )Y [Output Neurons]&Output neurons after classification _ aFiles processedc+Files, features have been extracted from edisplaySongList&(Ljava/util/Vector;)Ljava/lang/String; gh )i kResult Recording complete.m(Operator "Self-Organizing Map" complete.oXde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PerceptronInputExceptionq getMessage s rt logException*(Ljava/lang/String;Ljava/lang/Throwable;)V vw x 3w z SOMInput '| 5': File not found, please specify feature vector file:edu/udo/cs/yale/operator/parameter/UndefinedParameterError tFile '-(Ljava/lang/Object;)Ljava/lang/StringBuilder; F > ' not found.Error reading file ''.java/io/FileNotFoundExceptionjava/io/IOException useMetricsomf;Lde/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMFileHandler;mysomBLde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/SOM;d6Lde/uos/cogsci/ai/btenbergen/bscthesis/tools/Distance; positions[IpieZLde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PerceptronInputException;upeS@1y2ABCDEFGH* *JL+LYNPSYW+LY[]_SYW+aYcefiYW+aYkmfiYW+oYqsvYW+aYxzfdiYW+|Y~YW+|YYW+aYfdiYW+Y*@:YW+oYvYW+oYvYW+oYvYW+1>.DZm2AB )*+12 AB* <*Y*N****q**~õ**õ**˵**c˵**k˵**x˵*Y*[׵******<*:<'*<<*><<Y**M*,**߶* Y********N*--*- *  Y*-::* !* #*,'-/* 1* 35:-:*.Y<>Y@A*/EIJMO*.YQ>YSA*ٸV*/ZIJM\*.Y^>Y`A-IJMb*.Yd>YfA,'jIJMl*npL+u+yY+u+{L>Y}A*~IIJ++y*KLY>YA*IJ+{LY>YA*IJ+{Y*\SY*OSY*lSY*bSr1:N%/9CMWau%,2:AELS[bp,/ANQcsv}       2f <AB%i +##*,*1'2 AB*/,1-2 AB*.0132 ABPK /5558de/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMInput.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.yale; /** * This is the SOMInput class. This class implements the actual operator that can be used in Yale. * It takes a file as input and parses it using the SOMFileHandler class. The operator then invokes the * Self-Organizing Map and performs the classification. * * @version 22.07.2006 * @author Bastian Tenbergen - btenberg@uos.de */ import edu.udo.cs.yale.operator.Operator; import edu.udo.cs.yale.operator.OperatorException; import edu.udo.cs.yale.operator.OperatorDescription; import edu.udo.cs.yale.operator.IOObject; import edu.udo.cs.yale.operator.SimpleResultObject; import edu.udo.cs.yale.operator.parameter.ParameterType; import edu.udo.cs.yale.operator.parameter.ParameterTypeFile; import edu.udo.cs.yale.operator.parameter.ParameterTypeStringCategory; import edu.udo.cs.yale.operator.parameter.ParameterTypeInt; import edu.udo.cs.yale.operator.parameter.ParameterTypeDouble; import edu.udo.cs.yale.operator.parameter.ParameterTypeBoolean; import edu.udo.cs.yale.operator.parameter.UndefinedParameterError; import edu.udo.cs.yale.tools.LogService; import edu.udo.cs.yale.tools.ResultService; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException; import de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance; import de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster; import de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools; import java.io.IOException; import java.io.File; import java.io.FileNotFoundException; import java.util.List; public class SOMInput extends Operator implements IOObject { /** a class array containing the Output classes. Syntactic sugar. */ private static final Class[] OUTPUT_CLASS = { SimpleResultObject.class }; /** The Results that are to be printed on Yale's GUI. Enumeration of output neurons */ private SimpleResultObject result_neurons; /** Enumeration of processed file names */ private SimpleResultObject result_files; /** Enumeration of all file clusters */ private SimpleResultObject result_clusters; /** Enumeration of all files close to the hummed input */ private SimpleResultObject result_matches; /** The file that is to be parsed. */ private File filename; /** if true, the operator will send detailed information about what is happening to Yale's Log-Console. */ private boolean verbosing; /** Sets the number of columns of the SOM. */ private int numberCols; /** Sets the number of rows of the SOM. */ private int numberRows; /** Sets the number of classification runs. The higher the number, the more acurately the neurons are trained. */ private int runs; /** Sets the maximum value, the random initialization of weights and bias of the neurons must not exceed. */ private int maxValue; /** The Topology of this Map. If true, the last neuron of each row or col is connected to the first one. */ private boolean closed_topology; /** Sets the learning rate of the winner neuron of the Self-Organizing Map. */ private double learningrate_winner; /** Sets the learning rate of the neighboring neurons of the Self-Organizing Map. */ private double learningrate_neighbor; /** The Patterns that are retrieved from the file */ private Object[] patterns; /** The user's query input */ private String hummedFile; /** The song clusters */ private Cluster[] clusters; /** The metric used to measure the distance between each pattern and each neuron */ private String metric; /** The different metrics the user can choose from. */ private String[] metrics = new String[] {"Euclidean", "Manhattan", "Nominal"}; /** If true, the input patterns from the Feature Vector File will be normalized. */ private boolean normalize; /** If true, features with an absolute value smaller than one are filtered out. */ private boolean filter; /** * Constructor. Just calls the superconstructor with the given OperatorDescription. * @param description */ public SOMInput(OperatorDescription description) { super(description); } /** * Gets the ParameterTypes as a lists and adds the parameters for this operator. * @return The appended list of Parameters */ public List getParameterTypes() { List types = super.getParameterTypes(); types.add(new ParameterTypeFile("Feature Vector File", "The File containing the extracted Features.", null, false)); types.add(new ParameterTypeFile("Query Input File", "The File to which similar ones shall be queried for.", "mp3", false)); types.add(new ParameterTypeInt("Number Neuron-Columns", "The number of columns of the SOM. Together with the rows, this defines the topology.", 1, Integer.MAX_VALUE, 5)); types.add(new ParameterTypeInt("Number Neuron-Rows", "The number of rows of the SOM. Together with the columns, this defines the topology.", 1, Integer.MAX_VALUE, 5)); types.add(new ParameterTypeBoolean("Closed Topology", "Choose the topology of the Self-Organizing Map. If checked, the last neuron of each row and column is connected to the respective first one.", false)); types.add(new ParameterTypeInt("Training Runs", "The amount of training cycles in which in the neurons are trained.", 1, Integer.MAX_VALUE, 100)); types.add(new ParameterTypeDouble("Learning Rate Winner", "The Learning Rate of the SOM's Winner Neuron. Note that a Learning Rate of 0 causes the Map not to learn at all.", 0, 1.0, 1)); types.add(new ParameterTypeDouble("Learning Rate Neighbor", "The Learning Rate of the Winner's Neiboring Neurons. Not that a Learning Rate of 0 represents a WTA-Network and a Learning Rate of 1 turns the Neighbors into Winner Neurons.", 0, 1.0, 0.25)); types.add(new ParameterTypeInt("Maximal Value", "The maximum value of bias and weights the neurons may not exceed. Choose -1 for automatic computation.", -1, Integer.MAX_VALUE, 100)); types.add(new ParameterTypeStringCategory("Metric", "The Metric used to measure the distance between the patterns and the neurons.", metrics, "Euclidean")); types.add(new ParameterTypeBoolean("Filter Patterns", "If checked, features with a very small absolute value are filtered out.", true)); types.add(new ParameterTypeBoolean("Normalize Patterns", "If checked, the input patterns from the Feature Vector File will be normalized.", false)); types.add(new ParameterTypeBoolean("Verbosing", "If checked, the system will output information about what is happening.", true)); return types; } /** * This method is called by Yale when the operator is created. Nothing is done here. */ public void initApply() { } /** * This method is called by Yale whenever the operator is applied. The file to be parsed is * obtained and the rest of the parameters are set. Then, the SOMFileHandler is invoked and the * file is parsed. * * @return Just an empty IOObject array containing SimpleResultObjects with the results of the computations. * @throws OperatorException - This is thrown when a Parameter is undefined, the file to be * parsed is not found or an error during file reading occured. */ public IOObject[] apply() throws OperatorException { try { filename = new File(getParameterAsString("Feature Vector File")); verbosing = getParameterAsBoolean("Verbosing"); closed_topology = getParameterAsBoolean("Closed Topology"); learningrate_winner = getParameterAsDouble("Learning Rate Winner"); learningrate_neighbor = getParameterAsDouble("Learning Rate Neighbor"); maxValue = getParameterAsInt("Maximal Value"); numberCols = getParameterAsInt("Number Neuron-Columns"); numberRows = getParameterAsInt("Number Neuron-Rows"); runs = getParameterAsInt("Training Runs"); hummedFile = new File(getParameterAsString("Query Input File")).getName(); metric = getParameterAsString("Metric"); normalize = getParameterAsBoolean("Normalize Patterns"); filter = getParameterAsBoolean("Filter Patterns"); int useMetric = 0; if (this.metric.equalsIgnoreCase("Euclidean")) useMetric = 0; else if (this.metric.equalsIgnoreCase("Manhattan")) useMetric = 1; else if (this.metric.equalsIgnoreCase("Nominal")) useMetric = 2; else useMetric = 0; SOMFileHandler somf = new SOMFileHandler(filename, verbosing); patterns = somf.parseFile(normalize, filter); LogService.logMessage("File successfully parsed.", LogService.INIT); if (verbosing) LogService.logMessage("Invoking Self-Organizing Map", LogService.STATUS); SOM mysom = new SOM(numberRows, numberCols, patterns, learningrate_winner, learningrate_neighbor, runs, maxValue, closed_topology); if (verbosing) { LogService.logMessage("Before classification:", LogService.STATUS); LogService.logMessage(mysom.toString(), LogService.STATUS); LogService.logMessage("Classifying...", LogService.INIT); } //THIS IS WHERE THE MAGIC IS DONE! mysom.runClassification(); //THIS IS WHERE THE MAGIC IS DONE! if (verbosing) { LogService.logMessage("After Classification:", LogService.STATUS); LogService.logMessage(mysom.toString(), LogService.STATUS); } LogService.logMessage("Classification completed successfully.", LogService.STATUS); if (verbosing) LogService.logMessage("Measuring Distances...", LogService.INIT); Distance d = new Distance(patterns, mysom.output.neurons, useMetric); int[] positions = d.measureDistance(); if (verbosing) LogService.logMessage("Distance Measuring complete.", LogService.STATUS); if (verbosing) LogService.logMessage("Creating clusters...", LogService.STATUS); this.clusters = OperatorTools.createFileClusters(positions, somf.songList); if (verbosing) LogService.logMessage("Clusters created.", LogService.STATUS); if (verbosing) LogService.logMessage("Recording Results...", LogService.INIT); ResultService.logResult("Output neurons after classification:\n"); ResultService.logResult(mysom.toString()); result_clusters = new SimpleResultObject("Clusters","Files displayed in clusters" + "\n\n\n" + OperatorTools.showFileClusters(this.clusters) ); result_matches = new SimpleResultObject("User Input","Songs in Cluster that come closest to the input" + "\n\n\n" + OperatorTools.findQueryInClusters(OperatorTools.convertFilename(hummedFile), this.clusters) ); result_neurons = new SimpleResultObject("Output Neurons", "Output neurons after classification" + "\n\n\n" + mysom.toString()); result_files = new SimpleResultObject("Files processed", "Files, features have been extracted from" + "\n\n\n" + OperatorTools.displaySongList(somf.songList) ); if (verbosing) { LogService.logMessage("Result Recording complete.", LogService.STATUS); LogService.logMessage("Operator \"Self-Organizing Map\" complete.", LogService.INIT); } } catch (PerceptronInputException pie) { LogService.logException(pie.getMessage(), pie); throw new OperatorException(pie.getMessage(), pie); } catch (UndefinedParameterError upe) { LogService.logMessage("SOMInput '" + getName() + "': File not found, please specify feature vector file", LogService.WARNING); LogService.logException(upe.getMessage(), upe); filename = null; } catch (FileNotFoundException fnfe) { throw new OperatorException( "File '" + filename + "' not found.", fnfe ); } catch (IOException ioe) { throw new OperatorException( "Error reading file '" + filename + "'.", ioe ); } finally { } return new IOObject[] { result_matches, result_clusters, result_files, result_neurons }; } /** * Returns a copy of this operator. * @return A copy of this operator. */ public IOObject copy() { return this; } /** * Returns all Input classes. * @return All Input classes. */ public Class[] getInputClasses() { return new Class[0]; } /** * Returns all Output classes. * @return All Output classes. */ public Class[] getOutputClasses() { return OUTPUT_CLASS; } }PK .5feature_vector_files/PK 75javadoc/PK Gp,5 - javadoc/allclasses-frame.html All Classes All Classes
Cluster
Distance
Layer
Layers
MLPs
OperatorTools
Perceptron
PerceptronInputException
SOM
SOMFileHandler
SOMInput
Tools
PK Gp,5^Ü0 0 javadoc/allclasses-noframe.html All Classes All Classes
Cluster
Distance
Layer
Layers
MLPs
OperatorTools
Perceptron
PerceptronInputException
SOM
SOMFileHandler
SOMInput
Tools
PK Gp,5Cpjjjavadoc/constant-values.html Constant Field Values


Constant Field Values


Contents
de.uos.*

de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException
private static final long serialVersionUID 42L

de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
public static final int EUCLIDEAN 0
public static final int MANHATTAN 1
public static final int NOMINAL 2



PK Gp,5QҔQjavadoc/deprecated-list.html Deprecated List

Deprecated API


Contents


PK Gp,5(5p&p&javadoc/help-doc.html API Help

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.

Overview

The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.

Package

Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:

  • Interfaces (italic)
  • Classes
  • Enums
  • Exceptions
  • Errors
  • Annotation Types

Class/Interface

Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

  • Class inheritance diagram
  • Direct Subclasses
  • All Known Subinterfaces
  • All Known Implementing Classes
  • Class/interface declaration
  • Class/interface description

  • Nested Class Summary
  • Field Summary
  • Constructor Summary
  • Method Summary

  • Field Detail
  • Constructor Detail
  • Method Detail
Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

Annotation Type

Each annotation type has its own separate page with the following sections:

  • Annotation Type declaration
  • Annotation Type description
  • Required Element Summary
  • Optional Element Summary
  • Element Detail

Enum

Each enum has its own separate page with the following sections:

  • Enum declaration
  • Enum description
  • Enum Constant Summary
  • Enum Constant Detail

Use

Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

Tree (Class Hierarchy)

There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
  • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
  • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.

Deprecated API

The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

Index

The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

Prev/Next

These links take you to the next or previous class, interface, package, or related page.

Frames/No Frames

These links show and hide the HTML frames. All pages are available with or without frames.

Serialized Form

Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

Constant Field Values

The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.



PK 75javadoc/index-files/PK Gp,5pu javadoc/index-files/index-1.html A-Index
A B C D E F G H I L M N O P Q R S T U V W

A

activation(double[]) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
This method computes the scalar product of the input and the weights.
apply() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
This method is called by Yale whenever the operator is applied.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5r%3E&E&!javadoc/index-files/index-10.html L-Index
A B C D E F G H I L M N O P Q R S T U V W

L

Layer - Class in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
 
Layer(int, int, int, int) - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer
Constructor.
Layers - Interface in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
 
learningrate_neighbor - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
The learning rate of the winner's neighboring neurons.
learningrate_neighbor - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Sets the learning rate of the neighboring neurons of the Self-Organizing Map.
learningrate_winner - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
The learning rate.
learningrate_winner - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Sets the learning rate of the winner neuron of the Self-Organizing Map.
logPatterns() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
This method logs the current status of the SOM by sending information to Yale's Log-Console.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5IUA),,!javadoc/index-files/index-11.html M-Index
A B C D E F G H I L M N O P Q R S T U V W

M

MANHATTAN - Static variable in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
Constant for the Manhattan Distance.
manhattanDistance(double[], double[]) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
The Manhattan distance.
maxValue - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer
The maximum value of weights and bias for each neuron.
maxValue - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Sets the maximum value, the random initialization of weights and bias of the neurons must not exceed.
measureDistance() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
For each pattern, this method returns the closest neuron.
metric - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
The metric to be used.
metric - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
The metric used to measure the distance between each pattern and each neuron
metrics - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
The different metrics the user can choose from.
minMaxElement(double[]) - Static method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools
Returns the smallest and biggest element of a given double array in a new double array.
minMedMaxElement(double[]) - Static method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools
Returns the smallest and biggest and the medium element of a given double array in a new double array.
MLPs - Interface in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
 
msg - Variable in exception de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException
 

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5/iڹ%%!javadoc/index-files/index-12.html N-Index
A B C D E F G H I L M N O P Q R S T U V W

N

neurons - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer
The array of neurons defining the layer.
neurons - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
The Perceptron array that needs to be measured against the patterns.
NOMINAL - Static variable in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
Constant for the Nominal Distance.
nominalDistance(double[], double[]) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
An euclidean distance.
normalize - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
If true, the input patterns from the Feature Vector File will be normalized.
normalizeFeatureVectors(Object[]) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler
This method normalizes the features in each vector by deviding them by the root mean square deviation.
numberCols - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Sets the number of columns of the SOM.
numberRows - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Sets the number of rows of the SOM.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5V+!javadoc/index-files/index-13.html O-Index
A B C D E F G H I L M N O P Q R S T U V W

O

OperatorTools - Class in de.uos.cogsci.ai.btenbergen.bscthesis.tools
 
OperatorTools() - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools
 
output - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
The output layer.
OUTPUT_CLASS - Static variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
a class array containing the Output classes.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5q33!javadoc/index-files/index-14.html P-Index
A B C D E F G H I L M N O P Q R S T U V W

P

parseFeatureVectors(Vector<String>, boolean) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler
This method extracts double value features out of a given java.util.Vector.
parseFile(boolean) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler
This Method parses a given input file.
patterns - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
This array contains all patterns, i.e. the input vectors.
patterns - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
The array containing the patterns.
patterns - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler
Each element in this Object[] is another double[] with the extracted features.
patterns - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
The Patterns that are retrieved from the file
Perceptron - Class in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron
This is the Perceptron class.
Perceptron(int, int, double, double[], boolean) - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
Constructor.
PerceptronInputException - Exception in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron
The class PercepronInputException is thrown when the Input-Vector of a Perceptron is not of equal length as its Weight-Vector.
PerceptronInputException() - Constructor for exception de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException
Constructs a new exception with null as its detail message.
PerceptronInputException(String, Throwable) - Constructor for exception de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException
Constructs a new exception with the specified detail message and cause.
PerceptronInputException(String) - Constructor for exception de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException
Constructs a new exception with the specified detail message.
PerceptronInputException(Throwable) - Constructor for exception de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException
Constructs a new exception with the specified cause and a detail message of (cause==null ?
positionOfSmallest(double[]) - Static method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools
This method returns the position of the smallest element of a given array.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5ss!javadoc/index-files/index-15.html Q-Index
A B C D E F G H I L M N O P Q R S T U V W

Q

qs(double[], int, int) - Static method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools
This method does the actual sorting.
quicksort(double[], int, int) - Static method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools
A standard recursive QuickSort Algorithm.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5?S,,!javadoc/index-files/index-16.html R-Index
A B C D E F G H I L M N O P Q R S T U V W

R

result_clusters - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Enumeration of all file clusters
result_files - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Enumeration of processed file names
result_matches - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Enumeration of all files close to the hummed input
result_neurons - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
The Results that are to be printed on Yale's GUI.
returnNeg - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
The value that is returned when the activation does not exceed the threshold.
returnPos - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
The value that is returned when the activation exceeds the threshold.
row - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
If the perceptron is embedded in a neural network, this indicates the row in which it is located.
rows - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
Sets the number of rows of this SOM.
runClassification() - Method in interface de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs
Runs the classification process runs times.
runClassification() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
Runs the classification process runs times.
runs - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
The number of classification runs to be performed.
runs - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Sets the number of classification runs.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5 2 2!javadoc/index-files/index-17.html S-Index
A B C D E F G H I L M N O P Q R S T U V W

S

serialVersionUID - Static variable in exception de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException
 
setBipolar() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
Sets the Perceptron to binary or bipolar.
setWeights(double[]) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
This method updates the weight vector of the Perceptron.
showFileClusters(Cluster[]) - Static method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools
This method creates Cluster Objects of the processed files and shows them.
showPatterns() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
This method confirms the given input vectors by prompting them.
SOM - Class in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
 
SOM(int, int, Object[], double, double, int, int, boolean) - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
Constructor.
SOM(int, int, Object[]) - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
Constructor.
SOM(int, int, Object[], int) - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
Constructor.
SOMFileHandler - Class in de.uos.cogsci.ai.btenbergen.bscthesis.yale
 
SOMFileHandler(File, boolean) - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler
Constructor.
SOMFileHandler(File) - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler
Constructor.
SOMInput - Class in de.uos.cogsci.ai.btenbergen.bscthesis.yale
 
SOMInput(OperatorDescription) - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Constructor.
songList - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler
Each row in the file contains the filename of the song, the features belong to.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5 }&&!javadoc/index-files/index-18.html T-Index
A B C D E F G H I L M N O P Q R S T U V W

T

Tools - Class in de.uos.cogsci.ai.btenbergen.bscthesis.tools
This is class providing tools for multiple purposes.
Tools() - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools
 
toString() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer
Displays the neurons of the layer.
toString() - Method in interface de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layers
toString displays the Neurons of the Layer.
toString() - Method in interface de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs
toString method.
toString() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
toString method.
toString() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
toString method.
toString() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster
This method returns the String representation of the cluster.
toStringln() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster
This method returns the String representation of this cluster in lines.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5J[JG G !javadoc/index-files/index-19.html U-Index
A B C D E F G H I L M N O P Q R S T U V W

U

updateNeighbor(double[]) - Method in interface de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs
Updates the winner's neighboring neurons.
updateNeighbor(double[]) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
Updates the winner neuron's neighboring neurons.
updateWinner(double[]) - Method in interface de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs
Updates the winner neuron.
updateWinner(double[]) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
Updates the winner neuron of the output layer.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5t-## javadoc/index-files/index-2.html B-Index
A B C D E F G H I L M N O P Q R S T U V W

B

BIAS - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
The biad of the perceptron that needs to be exceeded to cause an activation.
bipolar - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
If true the perceptron fires bipolar (output: 1 or -1), else binary (output: 1 or 0).

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5Od!javadoc/index-files/index-20.html V-Index
A B C D E F G H I L M N O P Q R S T U V W

V

verbosing - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler
If true, the operator will send detailed information about what is going on to Yale's Log-Console.
verbosing - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
if true, the operator will send detailed information about what is happening to Yale's Log-Console.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5W!javadoc/index-files/index-21.html W-Index
A B C D E F G H I L M N O P Q R S T U V W

W

weights - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
The weights of the perceptron that weighing the input

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5О.. javadoc/index-files/index-3.html C-Index
A B C D E F G H I L M N O P Q R S T U V W

C

cause - Variable in exception de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException
 
closed_topology - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
The Topology of this Map.
closed_topology - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
The Topology of this Map.
Cluster - Class in de.uos.cogsci.ai.btenbergen.bscthesis.tools
 
Cluster(int, Vector<String>) - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster
Constructor.
clusters - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
The song clusters
col - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
If the perceptron is embedded in a neural network, this indicates the column in which it is located.
cols - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
Sets the number of cols of this SOM.
computeMax(Object[]) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
This method computues the maximum sensible bias and weight values.
content - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster
All Patterns in the Cluster.
convertFilename(String) - Static method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools
Replaces all characters which are not letters or digits by _ (underscore).
copy() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Returns a copy of this operator.
createFileClusters(int[], Vector<String>) - Static method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools
This method creates Cluster-Objects given an array containing the pattern's closest neurons and a Vector containing the Song-Names.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5Kl&& javadoc/index-files/index-4.html D-Index
A B C D E F G H I L M N O P Q R S T U V W

D

de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp - package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
 
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som - package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
 
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron - package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron
 
de.uos.cogsci.ai.btenbergen.bscthesis.tools - package de.uos.cogsci.ai.btenbergen.bscthesis.tools
 
de.uos.cogsci.ai.btenbergen.bscthesis.yale - package de.uos.cogsci.ai.btenbergen.bscthesis.yale
 
displaySongList(Vector<String>) - Static method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools
This method simply shows the processed songlist.
Distance - Class in de.uos.cogsci.ai.btenbergen.bscthesis.tools
 
Distance(Object[], Perceptron[], int) - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
Constructor.
Distance(Object[], Perceptron[]) - Constructor for class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
Constructor.
doLogging() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler
This method just shows the retrieved features in the Object[] by sending it to Yale's Log-Console.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5[[ javadoc/index-files/index-5.html E-Index
A B C D E F G H I L M N O P Q R S T U V W

E

EUCLIDEAN - Static variable in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
Constant for the Euclidean Distance.
euclideanDistance(double[], double[]) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
An euclidean distance.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5:Ş// javadoc/index-files/index-6.html F-Index
A B C D E F G H I L M N O P Q R S T U V W

F

filename - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler
The file to be parsed.
filename - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
The file that is to be parsed.
findNeighbors(double[]) - Method in interface de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs
This method determines the winner neuron's neighboring neurons and returns them.
findNeighbors(double[]) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
This method determines the winner neuron's neighboring neurons and returns them according to the here implemented architecture of the SOM.
findNeuron(int, int) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer
Given a coordinate in the structure, this method returns the corresponding neuron.
findNeuron(int, int) - Method in interface de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layers
Given a coordinate in the structure, this method returns the corresponding neuron.
findNeuronIndex(int, int) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer
Given a coordinate in the structure, this method returns the index of the corresponding neuron.
findNeuronIndex(int, int) - Method in interface de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layers
Given a coordinate in the structure, this method returns the index of the corresponding neuron.
findQueryInClusters(String, Cluster[]) - Static method in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools
This method checks if a String occures in the Vector of any cluster in a given Cluster-array.
findWinner(double[]) - Method in interface de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs
This method determines the winning neuron by comparing the activations given the input vector of all neurons in the layer.
findWinner(double[]) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
This method determines the winning neuron by comparing the activations given the input vector of all neurons in the layer.
fire(double[]) - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
Fires the perceptron.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5$$ javadoc/index-files/index-7.html G-Index
A B C D E F G H I L M N O P Q R S T U V W

G

getInputClasses() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Returns all Input classes.
getMessage() - Method in exception de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException
Just returns the detail message of the exception.
getOutputClasses() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Returns all Output classes.
getParameterTypes() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
Gets the ParameterTypes as a lists and adds the parameters for this operator.
getPerceptrons() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer
This method simply returns the neurons of the layer.
getPerceptrons() - Method in interface de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layers
This method simply returns the neurons of the Layer.
getWeights() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
This method just returns the weights.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5l, javadoc/index-files/index-8.html H-Index
A B C D E F G H I L M N O P Q R S T U V W

H

hummedFile - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
The user's query input

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5@,0$$ javadoc/index-files/index-9.html I-Index
A B C D E F G H I L M N O P Q R S T U V W

I

id - Variable in class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster
The ID of the Cluster.
initApply() - Method in class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
This method is called by Yale when the operator is created.

A B C D E F G H I L M N O P Q R S T U V W
PK Gp,5Z(8ccjavadoc/index.html Generated Documentation (Untitled) <H2> Frame Alert</H2> <P> This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. <BR> Link to<A HREF="overview-summary.html">Non-frame version.</A> PK Gp,5$javadoc/overview-frame.html Overview
All Classes

Packages
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron
de.uos.cogsci.ai.btenbergen.bscthesis.tools
de.uos.cogsci.ai.btenbergen.bscthesis.yale

  PK Gp,5Mjavadoc/overview-summary.html Overview


Self-Organizing Map Plugin v1.0 by B. Tenbergen

Packages
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp  
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som  
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron  
de.uos.cogsci.ai.btenbergen.bscthesis.tools  
de.uos.cogsci.ai.btenbergen.bscthesis.yale  

 



PK Gp,5Wץ0%0%javadoc/overview-tree.html Class Hierarchy

Hierarchy For All Packages

Package Hierarchies:
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp, de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som, de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron, de.uos.cogsci.ai.btenbergen.bscthesis.tools, de.uos.cogsci.ai.btenbergen.bscthesis.yale

Class Hierarchy

  • java.lang.Object
    • de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster
    • de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
    • de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer (implements de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layers)
    • edu.udo.cs.yale.operator.Operator
      • de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput (implements edu.udo.cs.yale.operator.IOObject)
    • de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools
    • de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
    • de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM (implements de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs)
    • de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler
    • java.lang.Throwable (implements java.io.Serializable)
    • de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools

Interface Hierarchy

  • de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layers
  • de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs


PK Gp,5dj`javadoc/package-listde.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron de.uos.cogsci.ai.btenbergen.bscthesis.tools de.uos.cogsci.ai.btenbergen.bscthesis.yale PK Gp,5}hjavadoc/serialized-form.html Serialized Form

Serialized Form


Package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron

Class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException extends java.lang.Exception implements Serializable

serialVersionUID: 42L

Serialized Fields

msg

java.lang.String msg

cause

java.lang.Throwable cause



PK Gp,5*k javadoc/stylesheet.css/* Javadoc style sheet */ /* Define colors, fonts and other style attributes here to override the defaults */ /* Page background color */ body { background-color: #FFFFFF } /* Headings */ h1 { font-size: 145% } /* Table colors */ .TableHeadingColor { background: #CCCCFF } /* Dark mauve */ .TableSubHeadingColor { background: #EEEEFF } /* Light mauve */ .TableRowColor { background: #FFFFFF } /* White */ /* Font used in left-hand frame lists */ .FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif } .FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif } .FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif } /* Navigation bar fonts and colors */ .NavBarCell1 { background-color:#EEEEFF;} /* Light mauve */ .NavBarCell1Rev { background-color:#00008B;} /* Dark Blue */ .NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;} .NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;} .NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;} .NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;} PK 75 javadoc/de/PK 75javadoc/de/uos/PK 75javadoc/de/uos/cogsci/PK 75javadoc/de/uos/cogsci/ai/PK 75$javadoc/de/uos/cogsci/ai/btenbergen/PK 75.javadoc/de/uos/cogsci/ai/btenbergen/bscthesis/PK 75=javadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/PK 75Ajavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/PK Gp,5kKKKjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layer.html Layer

de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
Class Layer

java.lang.Object
  extended by de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer
All Implemented Interfaces:
Layers

public class Layer
extends java.lang.Object
implements Layers


Field Summary
private  int maxValue
          The maximum value of weights and bias for each neuron.
 Perceptron[] neurons
          The array of neurons defining the layer.
 
Constructor Summary
Layer(int rows, int cols, int inputDimensions, int maxValue)
          Constructor.
 
Method Summary
 Perceptron findNeuron(int row, int col)
          Given a coordinate in the structure, this method returns the corresponding neuron.
 int findNeuronIndex(int row, int col)
          Given a coordinate in the structure, this method returns the index of the corresponding neuron.
 Perceptron[] getPerceptrons()
          This method simply returns the neurons of the layer.
 java.lang.String toString()
          Displays the neurons of the layer.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

neurons

public Perceptron[] neurons
The array of neurons defining the layer.


maxValue

private int maxValue
The maximum value of weights and bias for each neuron.

Constructor Detail

Layer

public Layer(int rows,
             int cols,
             int inputDimensions,
             int maxValue)
Constructor. A layer is defined by the number of neurons and the dimensionality of the input. It is instantiated by invoking rows * cols Perceptrons. Each Perceptron has as many weights as input dimensionality. The weight vectors are initialized randomly, however limited to maxValue to prevent very large weight differences. Neurons in Multi-Layer-Perceptrons always fire bipolar.

Parameters:
rows - The number of rows in the layer
cols - The number of cols in the layer
inputDimensions - The dimensionality of the input vector
maxValue - The maximum value for weights and bias for the neurons.
Method Detail

findNeuronIndex

public int findNeuronIndex(int row,
                           int col)
Given a coordinate in the structure, this method returns the index of the corresponding neuron.

Specified by:
findNeuronIndex in interface Layers
Parameters:
row - The X-Axis of the neuron
col - The Y-Axis of the neuron
Returns:
The index of the neuron.

findNeuron

public Perceptron findNeuron(int row,
                             int col)
Given a coordinate in the structure, this method returns the corresponding neuron.

Specified by:
findNeuron in interface Layers
Parameters:
row - The X-Axis of the neuron
col - The Y-Axis of the neuron
Returns:
The neuron at the given position.

getPerceptrons

public Perceptron[] getPerceptrons()
This method simply returns the neurons of the layer.

Specified by:
getPerceptrons in interface Layers
Returns:
The neurons of the layer.

toString

public java.lang.String toString()
Displays the neurons of the layer.

Specified by:
toString in interface Layers
Overrides:
toString in class java.lang.Object


PK Gp,5MI11Ljavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layers.html Layers

de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
Interface Layers

All Known Implementing Classes:
Layer

public interface Layers


Method Summary
 Perceptron findNeuron(int row, int col)
          Given a coordinate in the structure, this method returns the corresponding neuron.
 int findNeuronIndex(int row, int col)
          Given a coordinate in the structure, this method returns the index of the corresponding neuron.
 Perceptron[] getPerceptrons()
          This method simply returns the neurons of the Layer.
 java.lang.String toString()
          toString displays the Neurons of the Layer.
 

Method Detail

findNeuronIndex

int findNeuronIndex(int row,
                    int col)
Given a coordinate in the structure, this method returns the index of the corresponding neuron.

Parameters:
row - The X-Axis of the neuron
col - The Y-Axis of the neuron
Returns:
The index of the neuron.

findNeuron

Perceptron findNeuron(int row,
                      int col)
Given a coordinate in the structure, this method returns the corresponding neuron.

Parameters:
row - The X-Axis of the neuron
col - The Y-Axis of the neuron
Returns:
The neuron at the given position.

getPerceptrons

Perceptron[] getPerceptrons()
This method simply returns the neurons of the Layer.

Returns:
The neurons of the Layer.

toString

java.lang.String toString()
toString displays the Neurons of the Layer.

Overrides:
toString in class java.lang.Object


PK Gp,5y7 E EJjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/MLPs.html MLPs

de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
Interface MLPs

All Known Implementing Classes:
SOM

public interface MLPs


Method Summary
 Perceptron[] findNeighbors(double[] input)
          This method determines the winner neuron's neighboring neurons and returns them.
 Perceptron findWinner(double[] input)
          This method determines the winning neuron by comparing the activations given the input vector of all neurons in the layer.
 void runClassification()
          Runs the classification process runs times.
 java.lang.String toString()
          toString method.
 void updateNeighbor(double[] input)
          Updates the winner's neighboring neurons.
 void updateWinner(double[] input)
          Updates the winner neuron.
 

Method Detail

runClassification

void runClassification()
                       throws PerceptronInputException
Runs the classification process runs times. For each pattern update(int[]) is called.

Throws:
If - the Perceptron's weight vector is not of equal length as the input vector.
PerceptronInputException

updateWinner

void updateWinner(double[] input)
                  throws PerceptronInputException
Updates the winner neuron. To do so, the winner neuron needs to be determined by calling findWinner(int[]). Each weight in the winner's weight vecotr is then updated with the following formula:
newWeight = oldWeight + (LEARNINGRATE * (input - oldWeight))

Parameters:
input - The weight vector that determines the winning neuron.
Throws:
If - the Perceptron's weight vector is not of equal length as the input vector.
PerceptronInputException

updateNeighbor

void updateNeighbor(double[] input)
                    throws PerceptronInputException
Updates the winner's neighboring neurons. The neighboring neurons are determined and then updated according to the following formula:
newWeight = oldWeight + (LEARNINGRATE * (input - oldWeight))

Parameters:
input - The weight vector that determines the winning neuron.
Throws:
PerceptronInputException - If the Perceptron's weight vector is not of equal length as the input vector.

findNeighbors

Perceptron[] findNeighbors(double[] input)
                           throws PerceptronInputException
This method determines the winner neuron's neighboring neurons and returns them. This method needs to implement the topology of the MLP.

Parameters:
input - The input vector determining the winning neuron.
Returns:
The winner neuron's neighboring neurons.
Throws:
PerceptronInputException - If the Perceptron's weight vector is not of equal length as the input vector.

findWinner

Perceptron findWinner(double[] input)
                      throws PerceptronInputException
This method determines the winning neuron by comparing the activations given the input vector of all neurons in the layer. This is very close to a standard SelectionSort algorithm, but since the neurons are not sorted and only the maximum activation, this is done in O(n) time.

Parameters:
input - The input vector determining the winning neuron.
Returns:
The winning neuron.
Throws:
If - the Perceptron's weight vector is not of equal length as the input vector.
PerceptronInputException

toString

java.lang.String toString()
toString method. Returns the String-Representation of this MLP.

Overrides:
toString in class java.lang.Object
Returns:
The String representation of this MLP.


PK 75Kjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/class-use/PK Gp,5\W-փ""Ujavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/class-use/Layer.html Uses of Class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer

Uses of Class
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer

Packages that use Layer
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som   
 

Uses of Layer in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
 

Fields in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som declared as Layer
 Layer SOM.output
          The output layer.
 



PK Gp,55% " "Vjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/class-use/Layers.html Uses of Interface de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layers

Uses of Interface
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layers

Packages that use Layers
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp   
 

Uses of Layers in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
 

Classes in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp that implement Layers
 class Layer
           
 



PK Gp,5)ŭ""Tjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/class-use/MLPs.html Uses of Interface de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs

Uses of Interface
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs

Packages that use MLPs
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som   
 

Uses of MLPs in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
 

Classes in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som that implement MLPs
 class SOM
           
 



PK Gp,5==Sjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/package-frame.html de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
Interfaces 
Layers
MLPs
Classes 
Layer
PK Gp,5kL}}Ujavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/package-summary.html de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp

Package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp

Interface Summary
Layers  
MLPs  
 

Class Summary
Layer  
 



PK Gp,5ڏRjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/package-tree.html de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp Class Hierarchy

Hierarchy For Package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp

Package Hierarchies:
All Packages

Class Hierarchy

  • java.lang.Object
    • de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer (implements de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layers)

Interface Hierarchy

  • de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layers
  • de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs


PK Gp,5^b-d#d#Qjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/package-use.html Uses of Package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp

Uses of Package
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp

Packages that use de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp   
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som   
 

Classes in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp used by de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
Layers
           
 

Classes in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp used by de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
Layer
           
MLPs
           
 



PK 75Ejavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/PK R5mIIOjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/Layer.html Layer

de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
Class Layer

java.lang.Object
  extended by de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.Layer
All Implemented Interfaces:
Layers

public class Layer
extends java.lang.Object
implements Layers


Field Summary
 Perceptron[] neurons
          The array of neurons defining the layer.
 
Constructor Summary
Layer(int rows, int cols, int inputDimensions, int maxValue)
          Constructor.
 
Method Summary
 Perceptron findNeuron(int row, int col)
          Given a coordinate in the structure, this method returns the corresponding neuron.
 int findNeuronIndex(int row, int col)
          Given a coordinate in the structure, this method returns the index of the corresponding neuron.
 Perceptron[] getPerceptrons()
          This method simply returns the neurons of the layer.
 java.lang.String toString()
          Displays the neurons of the layer.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

neurons

public Perceptron[] neurons
The array of neurons defining the layer.

Constructor Detail

Layer

public Layer(int rows,
             int cols,
             int inputDimensions,
             int maxValue)
Constructor. A layer is defined by the number of neurons and the dimensionality of the input. It is instantiated by invoking rows * cols Perceptrons. Each Perceptron has as many weights as input dimensionality. The weight vectors are initialized randomly, however limited to maxValue to prevent very large weight differences. Neurons in Multi-Layer-Perceptrons always fire bipolar.

Parameters:
rows - The number of rows in the layer
cols - The number of cols in the layer
inputDimensions - The dimensionality of the input vector
The - maximum value for weights and bias for the neurons.
Method Detail

findNeuronIndex

public int findNeuronIndex(int row,
                           int col)
Given a coordinate in the structure, this method returns the index of the corresponding neuron.

Specified by:
findNeuronIndex in interface Layers
Parameters:
row - The X-Axis of the neuron
col - The Y-Axis of the neuron
Returns:
The index of the neuron.

findNeuron

public Perceptron findNeuron(int row,
                             int col)
Given a coordinate in the structure, this method returns the corresponding neuron.

Specified by:
findNeuron in interface Layers
Parameters:
row - The X-Axis of the neuron
col - The Y-Axis of the neuron
Returns:
The neuron at the given position.

getPerceptrons

public Perceptron[] getPerceptrons()
This method simply returns the neurons of the layer.

Specified by:
getPerceptrons in interface Layers
Returns:
The neurons of the layer.

toString

public java.lang.String toString()
Displays the neurons of the layer.

Specified by:
toString in interface Layers
Overrides:
toString in class java.lang.Object


PK Gp,5GEzzMjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/SOM.html SOM

de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
Class SOM

java.lang.Object
  extended by de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM
All Implemented Interfaces:
MLPs

public class SOM
extends java.lang.Object
implements MLPs


Field Summary
private  boolean closed_topology
          The Topology of this Map.
private  int cols
          Sets the number of cols of this SOM.
private  double learningrate_neighbor
          The learning rate of the winner's neighboring neurons.
private  double learningrate_winner
          The learning rate.
 Layer output
          The output layer.
private  java.lang.Object[] patterns
          This array contains all patterns, i.e. the input vectors.
private  int rows
          Sets the number of rows of this SOM.
private  int runs
          The number of classification runs to be performed.
 
Constructor Summary
SOM(int rows, int cols, java.lang.Object[] patterns)
          Constructor.
SOM(int rows, int cols, java.lang.Object[] patterns, double learningrate_winner, double learningrate_neighbor, int runs, int maxValue, boolean closed_topology)
          Constructor.
SOM(int rows, int cols, java.lang.Object[] patterns, int runs)
          Constructor.
 
Method Summary
 int computeMax(java.lang.Object[] patterns)
          This method computues the maximum sensible bias and weight values.
 Perceptron[] findNeighbors(double[] input)
          This method determines the winner neuron's neighboring neurons and returns them according to the here implemented architecture of the SOM.
 Perceptron findWinner(double[] input)
          This method determines the winning neuron by comparing the activations given the input vector of all neurons in the layer.
protected  void logPatterns()
          This method logs the current status of the SOM by sending information to Yale's Log-Console.
 void runClassification()
          Runs the classification process runs times.
 void showPatterns()
          This method confirms the given input vectors by prompting them.
 java.lang.String toString()
          toString method.
 void updateNeighbor(double[] input)
          Updates the winner neuron's neighboring neurons.
 void updateWinner(double[] input)
          Updates the winner neuron of the output layer.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

closed_topology

private boolean closed_topology
The Topology of this Map. If true, the last neuron of each row or col is connected to the first one.


runs

private int runs
The number of classification runs to be performed.


learningrate_winner

private double learningrate_winner
The learning rate. Defines how far the weight vector of the winning neuron is "pulled" into the direction of the input vector.


learningrate_neighbor

private double learningrate_neighbor
The learning rate of the winner's neighboring neurons.


patterns

private java.lang.Object[] patterns
This array contains all patterns, i.e. the input vectors. For simplicity reasons, this is an Object array that contains double arrays instead of a two dimensional matrix. Whenever a pattern is taken out of the array, it needs to be casted to a double[]. This should increase the performance on slow machines


rows

private int rows
Sets the number of rows of this SOM.


cols

private int cols
Sets the number of cols of this SOM.


output

public Layer output
The output layer.

Constructor Detail

SOM

public SOM(int rows,
           int cols,
           java.lang.Object[] patterns,
           double learningrate_winner,
           double learningrate_neighbor,
           int runs,
           int maxValue,
           boolean closed_topology)
Constructor. Creates a new Self-Organizing Map.

Parameters:
rows - The number of rows of this SOM.
cols - The number of columns of this SOM.
patterns - The training patterns. Must be an Object array containing double arrays.
learningrate_winner - Defines how far the weight vector of the winning neuron is "pulled" into the direction of the input vector.
learningrate_neighbor - Defines how far the weight vectors of the winner's neighbors is updated.
runs - The number of classification runs to be performed.
maxValue - The maximum value for weights and bias for the neurons.
closed_topology - The Topology of this Map. If true, the last neuron of each row or col is connected to the first one.

SOM

public SOM(int rows,
           int cols,
           java.lang.Object[] patterns)
Constructor. Creates a new Self-Organizing Map with default values for learningrates and runs. A sensible maximum value for the neuron's weights and bias is computed automatically.

Parameters:
rows - The number of rows of this SOM.
cols - The number of columns of this SOM.
patterns - The training patterns. Must be an Object array containing double arrays.

SOM

public SOM(int rows,
           int cols,
           java.lang.Object[] patterns,
           int runs)
Constructor. Creates a new Self-Organizing Map with default values for learningrates. A sensible maximum value for the neuron's weights and bias is computed automatically.

Parameters:
rows - The number of rows of this SOM.
cols - The number of columns of this SOM.
patterns - The training patterns. Must be an Object array containing double arrays.
runs - The number of runs to be performed. The more runs are performed, the more "prototypical" the output neurons are to the input clusters.
Method Detail

computeMax

public int computeMax(java.lang.Object[] patterns)
This method computues the maximum sensible bias and weight values.

Parameters:
patterns - A sensible maximum is computed according to these patterns.
Returns:
A reasonable maximum threshold.

runClassification

public void runClassification()
                       throws PerceptronInputException
Runs the classification process runs times. For each pattern, the winner neuron is determined and updated. The winner neuron's neighboring neurons are updated accordingly.

Specified by:
runClassification in interface MLPs
Throws:
If - the Perceptron's weight vector is not of equal length as the input vector.
PerceptronInputException

updateWinner

public void updateWinner(double[] input)
                  throws PerceptronInputException
Updates the winner neuron of the output layer. To do so, the winner neuron needs to be determined by calling findWinner(int[]). Each weight in the winner's weight vecotr is then updated with the following formula:
newWeight = oldWeight + (LEARNINGRATE * (input - oldWeight))

Specified by:
updateWinner in interface MLPs
Parameters:
input - The weight vector that determines the winning neuron.
Throws:
If - the Perceptron's weight vector is not of equal length as the input vector.
PerceptronInputException

updateNeighbor

public void updateNeighbor(double[] input)
                    throws PerceptronInputException
Updates the winner neuron's neighboring neurons. To do so, the neighbors need to be determined by calling findNeighbors(int[]). Each weight in each neighbor's weight vecotr is then updated with the following formula:
newWeight = oldWeight + (LEARNINGRATE * (input - oldWeight))

Specified by:
updateNeighbor in interface MLPs
Parameters:
input - The weight vector that determines the winning neuron.
Throws:
If - the Perceptron's weight vector is not of equal length as the input vector.
PerceptronInputException - If the Perceptron's weight vector is not of equal length as the input vector.

findNeighbors

public Perceptron[] findNeighbors(double[] input)
                           throws PerceptronInputException
This method determines the winner neuron's neighboring neurons and returns them according to the here implemented architecture of the SOM.

Specified by:
findNeighbors in interface MLPs
Parameters:
input - The input vector determining the winning neuron.
Returns:
The winner neuron's neighboring neurons.
Throws:
PerceptronInputException - If the Perceptron's weight vector is not of equal length as the input vector.

findWinner

public Perceptron findWinner(double[] input)
                      throws PerceptronInputException
This method determines the winning neuron by comparing the activations given the input vector of all neurons in the layer. This is very close to a standard SelectionSort algorithm, but since the neurons are not sorted and only the maximum activation, this is done in O(n) time.

Specified by:
findWinner in interface MLPs
Parameters:
input - The input vector determining the winning neuron.
Returns:
The winning neuron.
Throws:
PerceptronInputException - If the Perceptron's weight vector is not of equal length as the input vector.

toString

public java.lang.String toString()
toString method. Just calls the toString of the output layer, since this SOM just consists of an output layer.

Specified by:
toString in interface MLPs
Overrides:
toString in class java.lang.Object
Returns:
The String representation of this SOM.

showPatterns

public void showPatterns()
This method confirms the given input vectors by prompting them. Called usually by methods testing the functionality.


logPatterns

protected void logPatterns()
This method logs the current status of the SOM by sending information to Yale's Log-Console. The output is similar to showPatterns().



PK S5bt7t7Xjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/SOMFileHandler.html SOMFileHandler

de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
Class SOMFileHandler

java.lang.Object
  extended by de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOMFileHandler

public class SOMFileHandler
extends java.lang.Object


Field Summary
 java.util.Vector<java.lang.String> songList
          Each row in the file contains the filename of the song, the features belong to.
 
Constructor Summary
SOMFileHandler(java.io.File filename)
          Constructor.
SOMFileHandler(java.io.File filename, boolean verbosing)
          Constructor.
 
Method Summary
 java.lang.Object[] parseFile()
          This Method parses a given input file.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

songList

public java.util.Vector<java.lang.String> songList
Each row in the file contains the filename of the song, the features belong to. These filenames are stored in this vector for reference.

Constructor Detail

SOMFileHandler

public SOMFileHandler(java.io.File filename,
                      boolean verbosing)
Constructor. Sets the fields filename and verbosing accordingly.

Parameters:
filename - The file to be parsed.
verbosing - If true, detailed information about what is going on is sent to Yale's Log-Console.

SOMFileHandler

public SOMFileHandler(java.io.File filename)
Constructor. Sets the field filename accordingly. Verbosing is set to true.

Parameters:
filename - The file to be parsed.
Method Detail

parseFile

public java.lang.Object[] parseFile()
                             throws java.io.FileNotFoundException,
                                    java.io.IOException
This Method parses a given input file. Each row in the file is a Feture Vector and is extraced as such and stored in a java.util.Vector. The Vector will hence contain Strings as elements whereas each String corresponds to a row in the file. The method parseFeatureVectors is hence called with this Vector to extract the actual features out of each String. That method's output is returned by this method.

Returns:
An Object[] containing java.util.Vector as elements. Each Vector has doubles as elements. The doubles correspond to an actual feature while the java.util.Vector corresponds to each feature Vector, i.e. the rows in the File.
Throws:
java.io.FileNotFoundException - iff the file cannot be found.
java.io.IOException - iff an error occured during file access.


PK 75Ojavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/class-use/PK T5:k##Yjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/class-use/Layer.html Uses of Class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.Layer

Uses of Class
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.Layer

Packages that use Layer
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som   
 

Uses of Layer in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
 

Fields in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som declared as Layer
 Layer SOM.output
          The output layer.
 



PK Gp,5E{BBWjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/class-use/SOM.html Uses of Class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM

Uses of Class
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM

No usage of de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM



PK T5ϰbjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/class-use/SOMFileHandler.html Uses of Class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOMFileHandler

Uses of Class
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOMFileHandler

No usage of de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOMFileHandler



PK Gp,5b)v uuWjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/package-frame.html de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
Classes 
SOM
PK Gp,5bYjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/package-summary.html de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som

Package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som

Class Summary
SOM  
 



PK Gp,5SVjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/package-tree.html de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som Class Hierarchy

Hierarchy For Package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som

Package Hierarchies:
All Packages

Class Hierarchy

  • java.lang.Object
    • de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM (implements de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs)


PK Gp,5TeX}}Ujavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/package-use.html Uses of Package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som

Uses of Package
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som

No usage of de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som



PK 75Hjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PK Fp,5S XXWjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron.html Perceptron

de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron
Class Perceptron

java.lang.Object
  extended by de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron

public class Perceptron
extends java.lang.Object

This is the Perceptron class. It implements a perceptron with an arbitrary number of inputs.

Version:
01.05.2006
Author:
Bastian Tenbergen - btenberg@uos.de

Field Summary
 double BIAS
          The biad of the perceptron that needs to be exceeded to cause an activation.
 boolean bipolar
          If true the perceptron fires bipolar (output: 1 or -1), else binary (output: 1 or 0).
 int col
          If the perceptron is embedded in a neural network, this indicates the column in which it is located.
private  int returnNeg
          The value that is returned when the activation does not exceed the threshold.
private  int returnPos
          The value that is returned when the activation exceeds the threshold.
 int row
          If the perceptron is embedded in a neural network, this indicates the row in which it is located.
 double[] weights
          The weights of the perceptron that weighing the input
 
Constructor Summary
Perceptron(int row, int col, double BIAS, double[] weights, boolean bipolar)
          Constructor.
 
Method Summary
 double activation(double[] inputs)
          This method computes the scalar product of the input and the weights.
 int fire(double[] inputs)
          Fires the perceptron.
 double[] getWeights()
          This method just returns the weights.
private  void setBipolar()
          Sets the Perceptron to binary or bipolar.
 boolean setWeights(double[] newWeights)
          This method updates the weight vector of the Perceptron.
 java.lang.String toString()
          toString method.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

BIAS

public final double BIAS
The biad of the perceptron that needs to be exceeded to cause an activation.


weights

public double[] weights
The weights of the perceptron that weighing the input


bipolar

public boolean bipolar
If true the perceptron fires bipolar (output: 1 or -1), else binary (output: 1 or 0).


row

public int row
If the perceptron is embedded in a neural network, this indicates the row in which it is located.


col

public int col
If the perceptron is embedded in a neural network, this indicates the column in which it is located.


returnPos

private int returnPos
The value that is returned when the activation exceeds the threshold.


returnNeg

private int returnNeg
The value that is returned when the activation does not exceed the threshold.

Constructor Detail

Perceptron

public Perceptron(int row,
                  int col,
                  double BIAS,
                  double[] weights,
                  boolean bipolar)
Constructor. A standard Perceptron is invoked when called.

Parameters:
row - The row of the structure in which this Perceptron is located.
col - The column of the structure in which this Perceptron is located.
BIAS - The bias (theta, threshold) of the Perceptron. Once set, never changeable.
weights - The weight vector of the perceptron.
bipolar - Determines, if the Perceptron is bipolar or binary. If true, the negative output is -1. If false, the negative output is 0. The positive output is always 1.
Method Detail

setBipolar

private void setBipolar()
Sets the Perceptron to binary or bipolar. Called by the constructor.


fire

public int fire(double[] inputs)
         throws PerceptronInputException
Fires the perceptron. Calls activation(int[]) to compute scalar product.

Parameters:
inputs - The input vector.
Returns:
1 if the scalar product of the input and the weights is higher than the bias. -1 or 0 else (this depends on the Perceptron being bipolar or binary.
Throws:
If - the Perceptron's weight vector is not of equal length as the input vector.
PerceptronInputException

activation

public double activation(double[] inputs)
                  throws PerceptronInputException
This method computes the scalar product of the input and the weights.

Parameters:
inputs - The input vector.
Returns:
The activation of the Perceptron - scalar product of weights x input.
Throws:
If - the Perceptron's weight vector is not of equal length as the input vector.
PerceptronInputException

setWeights

public boolean setWeights(double[] newWeights)
This method updates the weight vector of the Perceptron.

Parameters:
newWeights - The new weight vector.
Returns:
true if update was successful, false else.

getWeights

public double[] getWeights()
This method just returns the weights.

Returns:
The weight vector of the Perceptron.

toString

public java.lang.String toString()
toString method. Returns the String representation of the Perceptron.

Overrides:
toString in class java.lang.Object
Returns:
The String representation of the Perceptron.


PK Fp,5ZmImIejavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PerceptronInputException.html PerceptronInputException

de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron
Class PerceptronInputException

java.lang.Object
  extended by java.lang.Throwable
      extended by java.lang.Exception
          extended by de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException
All Implemented Interfaces:
java.io.Serializable

public class PerceptronInputException
extends java.lang.Exception

The class PercepronInputException is thrown when the Input-Vector of a Perceptron is not of equal length as its Weight-Vector. Javadoc taken from java.lang.Exception class.

Version:
01.05.2006
Author:
Bastian Tenbergen - btenberg@uos.de
See Also:
Serialized Form

Field Summary
protected  java.lang.Throwable cause
           
private  java.lang.String msg
           
private static long serialVersionUID
           
 
Constructor Summary
PerceptronInputException()
          Constructs a new exception with null as its detail message.
PerceptronInputException(java.lang.String msg)
          Constructs a new exception with the specified detail message.
PerceptronInputException(java.lang.String msg, java.lang.Throwable cause)
          Constructs a new exception with the specified detail message and cause.
PerceptronInputException(java.lang.Throwable cause)
          Constructs a new exception with the specified cause and a detail message of (cause==null ?
 
Method Summary
 java.lang.String getMessage()
          Just returns the detail message of the exception.
 
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

serialVersionUID

private static final long serialVersionUID
See Also:
Constant Field Values

msg

private java.lang.String msg

cause

protected java.lang.Throwable cause
Constructor Detail

PerceptronInputException

public PerceptronInputException()
Constructs a new exception with null as its detail message. The cause is not initialized, and may subsequently be initialized by a call to Throwable.initCause(java.lang.Throwable).


PerceptronInputException

public PerceptronInputException(java.lang.String msg,
                                java.lang.Throwable cause)
Constructs a new exception with the specified detail message and cause. Note that the detail message associated with cause is not automatically incorporated in this exception's detail message.

Parameters:
msg - the detail message (which is saved for later retrieval by the Throwable.getMessage() method).
cause - the cause (which is saved for later retrieval by the Throwable.getCause() method). (A null value is permitted, and indicates that the cause is nonexistent or unknown.)

PerceptronInputException

public PerceptronInputException(java.lang.String msg)
Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently be initialized by a call to Throwable.initCause(java.lang.Throwable).

Parameters:
msg - the detail message. The detail message is saved for later retrieval by the Throwable.getMessage() method.

PerceptronInputException

public PerceptronInputException(java.lang.Throwable cause)
Constructs a new exception with the specified cause and a detail message of (cause==null ? null : cause.toString()) (which typically contains the class and detail message of cause). This constructor is useful for exceptions that are little more than wrappers for other throwables (for example, PrivilegedActionException).

Parameters:
cause - the cause (which is saved for later retrieval by the Throwable.getCause() method). (A null value is permitted, and indicates that the cause is nonexistent or unknown.)
Method Detail

getMessage

public java.lang.String getMessage()
Just returns the detail message of the exception.

Overrides:
getMessage in class java.lang.Throwable
Returns:
the detailed message as a java.lang.String


PK 75Rjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/class-use/PK Gp,5!FRFRajavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/class-use/Perceptron.html Uses of Class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron

Uses of Class
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron

Packages that use Perceptron
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp   
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som   
de.uos.cogsci.ai.btenbergen.bscthesis.tools   
 

Uses of Perceptron in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
 

Fields in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp declared as Perceptron
 Perceptron[] Layer.neurons
          The array of neurons defining the layer.
 

Methods in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp that return Perceptron
 Perceptron[] MLPs.findNeighbors(double[] input)
          This method determines the winner neuron's neighboring neurons and returns them.
 Perceptron Layers.findNeuron(int row, int col)
          Given a coordinate in the structure, this method returns the corresponding neuron.
 Perceptron Layer.findNeuron(int row, int col)
          Given a coordinate in the structure, this method returns the corresponding neuron.
 Perceptron MLPs.findWinner(double[] input)
          This method determines the winning neuron by comparing the activations given the input vector of all neurons in the layer.
 Perceptron[] Layers.getPerceptrons()
          This method simply returns the neurons of the Layer.
 Perceptron[] Layer.getPerceptrons()
          This method simply returns the neurons of the layer.
 

Uses of Perceptron in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
 

Methods in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som that return Perceptron
 Perceptron[] SOM.findNeighbors(double[] input)
          This method determines the winner neuron's neighboring neurons and returns them according to the here implemented architecture of the SOM.
 Perceptron SOM.findWinner(double[] input)
          This method determines the winning neuron by comparing the activations given the input vector of all neurons in the layer.
 

Uses of Perceptron in de.uos.cogsci.ai.btenbergen.bscthesis.tools
 

Fields in de.uos.cogsci.ai.btenbergen.bscthesis.tools declared as Perceptron
private  Perceptron[] Distance.neurons
          The Perceptron array that needs to be measured against the patterns.
 

Constructors in de.uos.cogsci.ai.btenbergen.bscthesis.tools with parameters of type Perceptron
Distance(java.lang.Object[] patterns, Perceptron[] neurons)
          Constructor.
Distance(java.lang.Object[] patterns, Perceptron[] neurons, int metric)
          Constructor.
 



PK Gp,5s2nHHojavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/class-use/PerceptronInputException.html Uses of Class de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException

Uses of Class
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException

Packages that use PerceptronInputException
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp   
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som   
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron   
 

Uses of PerceptronInputException in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
 

Methods in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp that throw PerceptronInputException
 Perceptron[] MLPs.findNeighbors(double[] input)
          This method determines the winner neuron's neighboring neurons and returns them.
 Perceptron MLPs.findWinner(double[] input)
          This method determines the winning neuron by comparing the activations given the input vector of all neurons in the layer.
 void MLPs.runClassification()
          Runs the classification process runs times.
 void MLPs.updateNeighbor(double[] input)
          Updates the winner's neighboring neurons.
 void MLPs.updateWinner(double[] input)
          Updates the winner neuron.
 

Uses of PerceptronInputException in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
 

Methods in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som that throw PerceptronInputException
 Perceptron[] SOM.findNeighbors(double[] input)
          This method determines the winner neuron's neighboring neurons and returns them according to the here implemented architecture of the SOM.
 Perceptron SOM.findWinner(double[] input)
          This method determines the winning neuron by comparing the activations given the input vector of all neurons in the layer.
 void SOM.runClassification()
          Runs the classification process runs times.
 void SOM.updateNeighbor(double[] input)
          Updates the winner neuron's neighboring neurons.
 void SOM.updateWinner(double[] input)
          Updates the winner neuron of the output layer.
 

Uses of PerceptronInputException in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron
 

Methods in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron that throw PerceptronInputException
 double Perceptron.activation(double[] inputs)
          This method computes the scalar product of the input and the weights.
 int Perceptron.fire(double[] inputs)
          Fires the perceptron.
 



PK Gp,5"[Zjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/package-frame.html de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron
Classes 
Perceptron
Exceptions 
PerceptronInputException
PK Gp,5&M II\javadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/package-summary.html de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron

Package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron

Class Summary
Perceptron This is the Perceptron class.
 

Exception Summary
PerceptronInputException The class PercepronInputException is thrown when the Input-Vector of a Perceptron is not of equal length as its Weight-Vector.
 



PK Gp,5pu__Yjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/package-tree.html de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron Class Hierarchy

Hierarchy For Package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron

Package Hierarchies:
All Packages

Class Hierarchy

  • java.lang.Object
    • de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron
    • java.lang.Throwable (implements java.io.Serializable)


PK Gp,5l00Xjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/package-use.html Uses of Package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron

Uses of Package
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron

Packages that use de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp   
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som   
de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron   
de.uos.cogsci.ai.btenbergen.bscthesis.tools   
 

Classes in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron used by de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp
Perceptron
          This is the Perceptron class.
PerceptronInputException
          The class PercepronInputException is thrown when the Input-Vector of a Perceptron is not of equal length as its Weight-Vector.
 

Classes in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron used by de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som
Perceptron
          This is the Perceptron class.
PerceptronInputException
          The class PercepronInputException is thrown when the Input-Vector of a Perceptron is not of equal length as its Weight-Vector.
 

Classes in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron used by de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron
PerceptronInputException
          The class PercepronInputException is thrown when the Input-Vector of a Perceptron is not of equal length as its Weight-Vector.
 

Classes in de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron used by de.uos.cogsci.ai.btenbergen.bscthesis.tools
Perceptron
          This is the Perceptron class.
 



PK 754javadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/PK Gp,5FaX44@javadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster.html Cluster

de.uos.cogsci.ai.btenbergen.bscthesis.tools
Class Cluster

java.lang.Object
  extended by de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster

public class Cluster
extends java.lang.Object


Field Summary
 java.util.Vector<java.lang.String> content
          All Patterns in the Cluster.
 int id
          The ID of the Cluster.
 
Constructor Summary
Cluster(int id, java.util.Vector<java.lang.String> content)
          Constructor.
 
Method Summary
 java.lang.String toString()
          This method returns the String representation of the cluster.
 java.lang.String toStringln()
          This method returns the String representation of this cluster in lines.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

id

public int id
The ID of the Cluster.


content

public java.util.Vector<java.lang.String> content
All Patterns in the Cluster.

Constructor Detail

Cluster

public Cluster(int id,
               java.util.Vector<java.lang.String> content)
Constructor. Invokes a Cluster Object Instance.

Parameters:
id - The ID of the Cluster.
content - The Patterns that belong to this cluster.
Method Detail

toString

public java.lang.String toString()
This method returns the String representation of the cluster.

Overrides:
toString in class java.lang.Object
Returns:
The String representation of this cluster in form of the cluster ID and the content.

toStringln

public java.lang.String toStringln()
This method returns the String representation of this cluster in lines. Only the content is printed, the ID is omitted.

Returns:
This cluster's content in lines.


PK Gp,5%_aRRAjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/Distance.html Distance

de.uos.cogsci.ai.btenbergen.bscthesis.tools
Class Distance

java.lang.Object
  extended by de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance

public class Distance
extends java.lang.Object


Field Summary
static int EUCLIDEAN
          Constant for the Euclidean Distance.
static int MANHATTAN
          Constant for the Manhattan Distance.
private  int metric
          The metric to be used.
private  Perceptron[] neurons
          The Perceptron array that needs to be measured against the patterns.
static int NOMINAL
          Constant for the Nominal Distance.
private  java.lang.Object[] patterns
          The array containing the patterns.
 
Constructor Summary
Distance(java.lang.Object[] patterns, Perceptron[] neurons)
          Constructor.
Distance(java.lang.Object[] patterns, Perceptron[] neurons, int metric)
          Constructor.
 
Method Summary
 double euclideanDistance(double[] e1, double[] e2)
          An euclidean distance.
 double manhattanDistance(double[] e1, double[] e2)
          The Manhattan distance.
 int[] measureDistance()
          For each pattern, this method returns the closest neuron.
 double nominalDistance(double[] e1, double[] e2)
          An euclidean distance.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

EUCLIDEAN

public static final int EUCLIDEAN
Constant for the Euclidean Distance.

See Also:
Constant Field Values

MANHATTAN

public static final int MANHATTAN
Constant for the Manhattan Distance.

See Also:
Constant Field Values

NOMINAL

public static final int NOMINAL
Constant for the Nominal Distance.

See Also:
Constant Field Values

patterns

private java.lang.Object[] patterns
The array containing the patterns.


neurons

private Perceptron[] neurons
The Perceptron array that needs to be measured against the patterns.


metric

private int metric
The metric to be used.

Constructor Detail

Distance

public Distance(java.lang.Object[] patterns,
                Perceptron[] neurons,
                int metric)
Constructor. A new Distance Object is created upon invokation.

Parameters:
neurons - The Perceptron array of which the weight Vectors need to be measured.
patterns - The Patterns that need to be measured.
metric - The Metric to be used.

Distance

public Distance(java.lang.Object[] patterns,
                Perceptron[] neurons)
Constructor. A new Distance Object is created upon invokation. Euclidean Distance is used.

Parameters:
neurons - The Perceptron array of which the weight Vectors need to be measured.
patterns - The Patterns that need to be measured.
Method Detail

measureDistance

public int[] measureDistance()
For each pattern, this method returns the closest neuron.

Returns:
The array containing the positions of the neurons.tern.

euclideanDistance

public double euclideanDistance(double[] e1,
                                double[] e2)
An euclidean distance. Taken from the ClusteringPlugin v3.2 for Yale.

Parameters:
e1 - The first Vector
e2 - The second Vector
Returns:
The nominal Distance between both Vectors.

manhattanDistance

public double manhattanDistance(double[] e1,
                                double[] e2)
The Manhattan distance. Taken from the ClusteringPlugin v3.2 for Yale.

Parameters:
e1 - The first Vector
e2 - The second Vector
Returns:
The nominal Distance between both Vectors.

nominalDistance

public double nominalDistance(double[] e1,
                              double[] e2)
An euclidean distance. Taken from the ClusteringPlugin v3.2 for Yale.

Parameters:
e1 - The first Vector
e2 - The second Vector
Returns:
The nominal Distance between both Vectors.


PK Gp,5 CCFjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/OperatorTools.html OperatorTools

de.uos.cogsci.ai.btenbergen.bscthesis.tools
Class OperatorTools

java.lang.Object
  extended by de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools

public class OperatorTools
extends java.lang.Object


Constructor Summary
OperatorTools()
           
 
Method Summary
static java.lang.String convertFilename(java.lang.String filename)
          Replaces all characters which are not letters or digits by _ (underscore).
static Cluster[] createFileClusters(int[] positions, java.util.Vector<java.lang.String> songList)
          This method creates Cluster-Objects given an array containing the pattern's closest neurons and a Vector containing the Song-Names.
static java.lang.String displaySongList(java.util.Vector<java.lang.String> songList)
          This method simply shows the processed songlist.
static java.lang.String findQueryInClusters(java.lang.String hummedFile, Cluster[] clusters)
          This method checks if a String occures in the Vector of any cluster in a given Cluster-array.
static java.lang.String showFileClusters(Cluster[] clusters)
          This method creates Cluster Objects of the processed files and shows them.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

OperatorTools

public OperatorTools()
Method Detail

convertFilename

public static java.lang.String convertFilename(java.lang.String filename)
Replaces all characters which are not letters or digits by _ (underscore). Additionally all non-english characters like umlauts or ß are replaced. The file itself is not modified, since only the String representation of the file name is taken into conderation.
Modified from ValueSeriesPlugin v3.2 for Yale.

Parameters:
filename - The file name to be converted. Usually the user's input file, but this works with any kind of String.
Returns:
The converted file name. The original file is not changed, since this operator only retrieves the String representation of the user's input.

findQueryInClusters

public static java.lang.String findQueryInClusters(java.lang.String hummedFile,
                                                   Cluster[] clusters)
This method checks if a String occures in the Vector of any cluster in a given Cluster-array. If a occurrence has been found, the whole cluster is printed out.

Parameters:
hummedFile - Look for this String in the clusters.
clusters - The cluster array in which to look for the String.
Returns:
The String representation of the cluster(s) in which the String was found.

displaySongList

public static java.lang.String displaySongList(java.util.Vector<java.lang.String> songList)
This method simply shows the processed songlist.

Parameters:
songList - A Vector containing the processed songs.
Returns:
The String representation of the songlist in a ResultService-friendly form.

createFileClusters

public static Cluster[] createFileClusters(int[] positions,
                                           java.util.Vector<java.lang.String> songList)
                                    throws java.lang.ArrayIndexOutOfBoundsException
This method creates Cluster-Objects given an array containing the pattern's closest neurons and a Vector containing the Song-Names. The Cluster-Objects can hence be referenced more easily.

Parameters:
positions - An array containing the closest neurons to a given pattern.
songList - A Vector containing the Song-Names.
Returns:
A Cluster-Array containing the Clusters.
Throws:
java.lang.ArrayIndexOutOfBoundsException

showFileClusters

public static java.lang.String showFileClusters(Cluster[] clusters)
This method creates Cluster Objects of the processed files and shows them. Similar files occur in the same cluster.

Parameters:
clusters - The Clusters of similar songs.
Returns:
The clusters in a ResultService-friendly form.


PK Gp,528=8=>javadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/Tools.html Tools

de.uos.cogsci.ai.btenbergen.bscthesis.tools
Class Tools

java.lang.Object
  extended by de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools

public class Tools
extends java.lang.Object

This is class providing tools for multiple purposes. Currently implemented:
- a generic quicksort algorithm sorting double arrays
- a generic quicksort algorithm sorting double arrays but maintining the original array
- a method providing the smallest and largest element of a double array
- a method providing the smallest, the largest and the median element of a double array
- a method returning the index of the smallest element in a given double array

Version:
20.07.2006
Author:
Bastian Tenbergen - btenberg@uos.de

Constructor Summary
Tools()
           
 
Method Summary
static double[] minMaxElement(double[] array)
          Returns the smallest and biggest element of a given double array in a new double array.
static double[] minMedMaxElement(double[] array)
          Returns the smallest and biggest and the medium element of a given double array in a new double array.
static int positionOfSmallest(double[] array)
          This method returns the position of the smallest element of a given array.
private static void qs(double[] array, int onset, int offset)
          This method does the actual sorting.
static double[] quicksort(double[] array, int onset, int offset)
          A standard recursive QuickSort Algorithm.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Tools

public Tools()
Method Detail

quicksort

public static double[] quicksort(double[] array,
                                 int onset,
                                 int offset)
A standard recursive QuickSort Algorithm. This algorithm takes a double array and sorts it from the biggest to the smallest element. It takes the median element as the random pivot element. This method calls the private method qs(double[], int, int) that does the actual job. This method copies the given array so that the original array is maintained.

Parameters:
array - the array to be sorted
onset - the onset element from which shall be sorted (inclusive)
offset - the offset element until which shall be sorted (inclusive)

qs

private static void qs(double[] array,
                       int onset,
                       int offset)
This method does the actual sorting.

Parameters:
array - the array to be sorted
onset - the onset element from which shall be sorted (inclusive)
offset - the offset element until which shall be sorted (inclusive)

minMaxElement

public static double[] minMaxElement(double[] array)
Returns the smallest and biggest element of a given double array in a new double array.

Parameters:
array - the (unsorted) array containing one smallest and one biggest element
Returns:
a new array with the input array's smallest and biggest as first and second element.

minMedMaxElement

public static double[] minMedMaxElement(double[] array)
Returns the smallest and biggest and the medium element of a given double array in a new double array.

Parameters:
array - the (unsorted) array containing one smallest and one biggest element
Returns:
a new array with the input array's smallest, biggest and the medium element.

positionOfSmallest

public static int positionOfSmallest(double[] array)
This method returns the position of the smallest element of a given array. It does so in a SelectionSort-like way, but runs through array only once (since we don't need to sort the whole array.

Parameters:
array - the array containing one smallest element, whose position is of interest.
Returns:
the position of the smallest element in the array.


PK 75>javadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/class-use/PK Gp,5I?11Jjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/class-use/Cluster.html Uses of Class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster

Uses of Class
de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster

Packages that use Cluster
de.uos.cogsci.ai.btenbergen.bscthesis.tools   
de.uos.cogsci.ai.btenbergen.bscthesis.yale   
 

Uses of Cluster in de.uos.cogsci.ai.btenbergen.bscthesis.tools
 

Methods in de.uos.cogsci.ai.btenbergen.bscthesis.tools that return Cluster
static Cluster[] OperatorTools.createFileClusters(int[] positions, java.util.Vector<java.lang.String> songList)
          This method creates Cluster-Objects given an array containing the pattern's closest neurons and a Vector containing the Song-Names.
 

Methods in de.uos.cogsci.ai.btenbergen.bscthesis.tools with parameters of type Cluster
static java.lang.String OperatorTools.findQueryInClusters(java.lang.String hummedFile, Cluster[] clusters)
          This method checks if a String occures in the Vector of any cluster in a given Cluster-array.
static java.lang.String OperatorTools.showFileClusters(Cluster[] clusters)
          This method creates Cluster Objects of the processed files and shows them.
 

Uses of Cluster in de.uos.cogsci.ai.btenbergen.bscthesis.yale
 

Fields in de.uos.cogsci.ai.btenbergen.bscthesis.yale declared as Cluster
private  Cluster[] SOMInput.clusters
          The song clusters
 



PK Gp,5=}/ddKjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/class-use/Distance.html Uses of Class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance

Uses of Class
de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance

No usage of de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance



PK Gp,5ؖPjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/class-use/OperatorTools.html Uses of Class de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools

Uses of Class
de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools

No usage of de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools



PK Gp,5,}FFHjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/class-use/Tools.html Uses of Class de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools

Uses of Class
de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools

No usage of de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools



PK Gp,57)XFjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/package-frame.html de.uos.cogsci.ai.btenbergen.bscthesis.tools de.uos.cogsci.ai.btenbergen.bscthesis.tools
Classes 
Cluster
Distance
OperatorTools
Tools
PK Gp,5Hjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/package-summary.html de.uos.cogsci.ai.btenbergen.bscthesis.tools

Package de.uos.cogsci.ai.btenbergen.bscthesis.tools

Class Summary
Cluster  
Distance  
OperatorTools  
Tools This is class providing tools for multiple purposes.
 



PK Gp,5ãiiEjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/package-tree.html de.uos.cogsci.ai.btenbergen.bscthesis.tools Class Hierarchy

Hierarchy For Package de.uos.cogsci.ai.btenbergen.bscthesis.tools

Package Hierarchies:
All Packages

Class Hierarchy

  • java.lang.Object
    • de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster
    • de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance
    • de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools
    • de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools


PK Gp,5ty y Djavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/tools/package-use.html Uses of Package de.uos.cogsci.ai.btenbergen.bscthesis.tools

Uses of Package
de.uos.cogsci.ai.btenbergen.bscthesis.tools

Packages that use de.uos.cogsci.ai.btenbergen.bscthesis.tools
de.uos.cogsci.ai.btenbergen.bscthesis.tools   
de.uos.cogsci.ai.btenbergen.bscthesis.yale   
 

Classes in de.uos.cogsci.ai.btenbergen.bscthesis.tools used by de.uos.cogsci.ai.btenbergen.bscthesis.tools
Cluster
           
 

Classes in de.uos.cogsci.ai.btenbergen.bscthesis.tools used by de.uos.cogsci.ai.btenbergen.bscthesis.yale
Cluster
           
 



PK 753javadoc/de/uos/cogsci/ai/btenbergen/bscthesis/yale/PK Fp,5cgPgPFjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMFileHandler.html SOMFileHandler

de.uos.cogsci.ai.btenbergen.bscthesis.yale
Class SOMFileHandler

java.lang.Object
  extended by de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler

public class SOMFileHandler
extends java.lang.Object


Field Summary
private  java.io.File filename
          The file to be parsed.
private  java.lang.Object[] patterns
          Each element in this Object[] is another double[] with the extracted features.
 java.util.Vector<java.lang.String> songList
          Each row in the file contains the filename of the song, the features belong to.
private  boolean verbosing
          If true, the operator will send detailed information about what is going on to Yale's Log-Console.
 
Constructor Summary
SOMFileHandler(java.io.File filename)
          Constructor.
SOMFileHandler(java.io.File filename, boolean verbosing)
          Constructor.
 
Method Summary
private  void doLogging()
          This method just shows the retrieved features in the Object[] by sending it to Yale's Log-Console.
private  java.lang.Object[] normalizeFeatureVectors(java.lang.Object[] patterns)
          This method normalizes the features in each vector by deviding them by the root mean square deviation.
private  java.lang.Object[] parseFeatureVectors(java.util.Vector<java.lang.String> feature_vectors, boolean normalize)
          This method extracts double value features out of a given java.util.Vector.
 java.lang.Object[] parseFile(boolean normalize)
          This Method parses a given input file.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

patterns

private java.lang.Object[] patterns
Each element in this Object[] is another double[] with the extracted features.


songList

public java.util.Vector<java.lang.String> songList
Each row in the file contains the filename of the song, the features belong to. These filenames are stored in this vector for reference.


verbosing

private boolean verbosing
If true, the operator will send detailed information about what is going on to Yale's Log-Console.


filename

private java.io.File filename
The file to be parsed.

Constructor Detail

SOMFileHandler

public SOMFileHandler(java.io.File filename,
                      boolean verbosing)
Constructor. Sets the fields filename and verbosing accordingly.

Parameters:
filename - The file to be parsed.
verbosing - If true, detailed information about what is going on is sent to Yale's Log-Console.

SOMFileHandler

public SOMFileHandler(java.io.File filename)
Constructor. Sets the field filename accordingly. Verbosing is set to true.

Parameters:
filename - The file to be parsed.
Method Detail

parseFile

public java.lang.Object[] parseFile(boolean normalize)
                             throws java.io.FileNotFoundException,
                                    java.io.IOException
This Method parses a given input file. Each row in the file is a Feture Vector and is extraced as such and stored in a java.util.Vector. The Vector will hence contain Strings as elements whereas each String corresponds to a row in the file. The method parseFeatureVectors is hence called with this Vector to extract the actual features out of each String. That method's output is returned by this method.

Parameters:
normalize - If true, the input patterns will be normalized by dividing every element x(i,j) by the root mean square deviation of the corresponding column, o(j).
Returns:
An Object[] containing java.util.Vector as elements. Each Vector has doubles as elements. The doubles correspond to an actual feature while the java.util.Vector corresponds to each feature Vector, i.e. the rows in the File.
Throws:
java.io.FileNotFoundException - iff the file cannot be found.
java.io.IOException - iff an error occured during file access.

parseFeatureVectors

private java.lang.Object[] parseFeatureVectors(java.util.Vector<java.lang.String> feature_vectors,
                                               boolean normalize)
This method extracts double value features out of a given java.util.Vector. Each String in the Vector is parsed and NaN values are ignored. Every numerical value is hence considered a double and stored in a java.util.Vector. Hence every Vector corresponds to a row in the input file parsed feature values. All rows are stored in an Object[].

Parameters:
feature_vectors - The Vector containing String representations of blank space separated double values.
normalize - If true, the input patterns will be normalized by dividing every element x(i,j) by the root mean square deviation of the corresponding column, o(j).
Returns:
An Object[] containing java.util.Vector as elements. Every element is a row in the input file.

normalizeFeatureVectors

private java.lang.Object[] normalizeFeatureVectors(java.lang.Object[] patterns)
This method normalizes the features in each vector by deviding them by the root mean square deviation. This is necessary, since there might be a very large scope of the elements in the feature vectors. This causes features with a very large absolute value to have a larger impact on the distance measuring than features with a very small absolute value. 'Small features' hence might not play a significant role anymore. To avoid that behaviour, the root mean square deviation for every column is calculated and each element x(i,j) is devided by the rmsd o(j). The root mean square deviation is calculated as follows:
o(j) = sqrt( (1 / ( n - 1) ) * (sum_over_vectors( x(i,j) - mean(j)) )^2 )
with n = the number of vectors
x(i,j) = the j-th value of the i-th vector
mean(j) = the mean value of all j-th elements of all vectors (i.e. the j-th column)

The features are hence updated as follows:
x(i,j)_new = ( x(i,j)_old / o(j) )

Parameters:
patterns - The patterns that need to be normalized.
Returns:
The normalized patterns.

doLogging

private void doLogging()
This method just shows the retrieved features in the Object[] by sending it to Yale's Log-Console.



PK Gp,5t uPzz@javadoc/de/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMInput.html SOMInput

de.uos.cogsci.ai.btenbergen.bscthesis.yale
Class SOMInput

java.lang.Object
  extended by edu.udo.cs.yale.operator.Operator
      extended by de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput
All Implemented Interfaces:
edu.udo.cs.yale.operator.IOObject

public class SOMInput
extends edu.udo.cs.yale.operator.Operator
implements edu.udo.cs.yale.operator.IOObject


Field Summary
private  boolean closed_topology
          The Topology of this Map.
private  Cluster[] clusters
          The song clusters
private  java.io.File filename
          The file that is to be parsed.
private  java.lang.String hummedFile
          The user's query input
private  double learningrate_neighbor
          Sets the learning rate of the neighboring neurons of the Self-Organizing Map.
private  double learningrate_winner
          Sets the learning rate of the winner neuron of the Self-Organizing Map.
private  int maxValue
          Sets the maximum value, the random initialization of weights and bias of the neurons must not exceed.
private  int metric
          The metric used to measure the distance between each pattern and each neuron
private  java.lang.String[] metrics
          The different metrics the user can choose from.
private  boolean normalize
          If true, the input patterns from the Feature Vector File will be normalized.
private  int numberCols
          Sets the number of columns of the SOM.
private  int numberRows
          Sets the number of rows of the SOM.
private static java.lang.Class[] OUTPUT_CLASS
          a class array containing the Output classes.
private  java.lang.Object[] patterns
          The Patterns that are retrieved from the file
private  edu.udo.cs.yale.operator.SimpleResultObject result_clusters
          Enumeration of all file clusters
private  edu.udo.cs.yale.operator.SimpleResultObject result_files
          Enumeration of processed file names
private  edu.udo.cs.yale.operator.SimpleResultObject result_matches
          Enumeration of all files close to the hummed input
private  edu.udo.cs.yale.operator.SimpleResultObject result_neurons
          The Results that are to be printed on Yale's GUI.
private  int runs
          Sets the number of classification runs.
private  boolean verbosing
          if true, the operator will send detailed information about what is happening to Yale's Log-Console.
 
Constructor Summary
SOMInput(edu.udo.cs.yale.operator.OperatorDescription description)
          Constructor.
 
Method Summary
 edu.udo.cs.yale.operator.IOObject[] apply()
          This method is called by Yale whenever the operator is applied.
 edu.udo.cs.yale.operator.IOObject copy()
          Returns a copy of this operator.
 java.lang.Class[] getInputClasses()
          Returns all Input classes.
 java.lang.Class[] getOutputClasses()
          Returns all Output classes.
 java.util.List<edu.udo.cs.yale.operator.parameter.ParameterType> getParameterTypes()
          Gets the ParameterTypes as a lists and adds the parameters for this operator.
 void initApply()
          This method is called by Yale when the operator is created.
 
Methods inherited from class edu.udo.cs.yale.operator.Operator
addError, addValue, addWarning, apply, checkDeprecations, checkIO, checkProperties, clearErrorList, cloneOperator, createExperimentTree, createExperimentTree, createFromXML, createMarkedExperimentTree, delete, experimentFinished, experimentStarts, getAddOnlyAdditionalOutput, getApplyCount, getDeliveredOutputClasses, getDeprecationInfo, getDesiredInputClasses, getErrorList, getExperiment, getInnerOperatorsXML, getInput, getInput, getInput, getInputDescription, getIOContainerForInApplyLoopBreakpoint, getName, getNumberOfSteps, getOperatorClassName, getOperatorDescription, getParameter, getParameterAsBoolean, getParameterAsColor, getParameterAsDouble, getParameterAsFile, getParameterAsInt, getParameterAsString, getParameterList, getParameters, getParameterType, getParent, getStartTime, getStatus, getUserDescription, getValue, getValues, getXML, hasBreakpoint, hasBreakpoint, hasInput, inApplyLoop, indent, isEnabled, isParameterSet, logMessage, performAdditionalChecks, register, remove, rename, resume, setBreakpoint, setEnabled, setExperiment, setInput, setListParameter, setOperatorParameters, setParameter, setParent, setUserDescription, toString, writeXML
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

OUTPUT_CLASS

private static final java.lang.Class[] OUTPUT_CLASS
a class array containing the Output classes. Syntactic sugar.


result_neurons

private edu.udo.cs.yale.operator.SimpleResultObject result_neurons
The Results that are to be printed on Yale's GUI. Enumeration of output neurons


result_files

private edu.udo.cs.yale.operator.SimpleResultObject result_files
Enumeration of processed file names


result_clusters

private edu.udo.cs.yale.operator.SimpleResultObject result_clusters
Enumeration of all file clusters


result_matches

private edu.udo.cs.yale.operator.SimpleResultObject result_matches
Enumeration of all files close to the hummed input


filename

private java.io.File filename
The file that is to be parsed.


verbosing

private boolean verbosing
if true, the operator will send detailed information about what is happening to Yale's Log-Console.


numberCols

private int numberCols
Sets the number of columns of the SOM.


numberRows

private int numberRows
Sets the number of rows of the SOM.


runs

private int runs
Sets the number of classification runs. The higher the number, the more acurately the neurons are trained.


maxValue

private int maxValue
Sets the maximum value, the random initialization of weights and bias of the neurons must not exceed.


closed_topology

private boolean closed_topology
The Topology of this Map. If true, the last neuron of each row or col is connected to the first one.


learningrate_winner

private double learningrate_winner
Sets the learning rate of the winner neuron of the Self-Organizing Map.


learningrate_neighbor

private double learningrate_neighbor
Sets the learning rate of the neighboring neurons of the Self-Organizing Map.


patterns

private java.lang.Object[] patterns
The Patterns that are retrieved from the file


hummedFile

private java.lang.String hummedFile
The user's query input


clusters

private Cluster[] clusters
The song clusters


metric

private int metric
The metric used to measure the distance between each pattern and each neuron


metrics

private java.lang.String[] metrics
The different metrics the user can choose from.


normalize

private boolean normalize
If true, the input patterns from the Feature Vector File will be normalized.

Constructor Detail

SOMInput

public SOMInput(edu.udo.cs.yale.operator.OperatorDescription description)
Constructor. Just calls the superconstructor with the given OperatorDescription.

Parameters:
description -
Method Detail

getParameterTypes

public java.util.List<edu.udo.cs.yale.operator.parameter.ParameterType> getParameterTypes()
Gets the ParameterTypes as a lists and adds the parameters for this operator.

Overrides:
getParameterTypes in class edu.udo.cs.yale.operator.Operator
Returns:
The appended list of Parameters

initApply

public void initApply()
This method is called by Yale when the operator is created. Nothing is done here.


apply

public edu.udo.cs.yale.operator.IOObject[] apply()
                                          throws edu.udo.cs.yale.operator.OperatorException
This method is called by Yale whenever the operator is applied. The file to be parsed is obtained and the rest of the parameters are set. Then, the SOMFileHandler is invoked and the file is parsed.

Specified by:
apply in class edu.udo.cs.yale.operator.Operator
Returns:
Just an empty IOObject array containing SimpleResultObjects with the results of the computations.
Throws:
edu.udo.cs.yale.operator.OperatorException - - This is thrown when a Parameter is undefined, the file to be parsed is not found or an error during file reading occured.

copy

public edu.udo.cs.yale.operator.IOObject copy()
Returns a copy of this operator.

Specified by:
copy in interface edu.udo.cs.yale.operator.IOObject
Returns:
A copy of this operator.

getInputClasses

public java.lang.Class[] getInputClasses()
Returns all Input classes.

Specified by:
getInputClasses in class edu.udo.cs.yale.operator.Operator
Returns:
All Input classes.

getOutputClasses

public java.lang.Class[] getOutputClasses()
Returns all Output classes.

Specified by:
getOutputClasses in class edu.udo.cs.yale.operator.Operator
Returns:
All Output classes.


PK 75=javadoc/de/uos/cogsci/ai/btenbergen/bscthesis/yale/class-use/PK Gp,5 {Pjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/yale/class-use/SOMFileHandler.html Uses of Class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler

Uses of Class
de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler

No usage of de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler



PK Gp,5=VZZJjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/yale/class-use/SOMInput.html Uses of Class de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput

Uses of Class
de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput

No usage of de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput



PK Gp,5aUEjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/yale/package-frame.html de.uos.cogsci.ai.btenbergen.bscthesis.yale de.uos.cogsci.ai.btenbergen.bscthesis.yale
Classes 
SOMFileHandler
SOMInput
PK Gp,5qGjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/yale/package-summary.html de.uos.cogsci.ai.btenbergen.bscthesis.yale

Package de.uos.cogsci.ai.btenbergen.bscthesis.yale

Class Summary
SOMFileHandler  
SOMInput  
 



PK Gp,5zDjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/yale/package-tree.html de.uos.cogsci.ai.btenbergen.bscthesis.yale Class Hierarchy

Hierarchy For Package de.uos.cogsci.ai.btenbergen.bscthesis.yale

Package Hierarchies:
All Packages

Class Hierarchy

  • java.lang.Object
    • edu.udo.cs.yale.operator.Operator
      • de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMInput (implements edu.udo.cs.yale.operator.IOObject)
    • de.uos.cogsci.ai.btenbergen.bscthesis.yale.SOMFileHandler


PK Gp,5&(lCjavadoc/de/uos/cogsci/ai/btenbergen/bscthesis/yale/package-use.html Uses of Package de.uos.cogsci.ai.btenbergen.bscthesis.yale

Uses of Package
de.uos.cogsci.ai.btenbergen.bscthesis.yale

No usage of de.uos.cogsci.ai.btenbergen.bscthesis.yale



PK 75javadoc/resources/PK S5M99javadoc/resources/inherit.gifGIF89a, DrjԐ;߀Q@N;PK S/5sample_experiments/PK 5+[GG LICENSE.txt GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. PK L!5 META-INF/PK 5XznnMETA-INF/ABOUT.NFOThis plugin provides an operator for the classification of large feature vectors with an Self-Organizing Map. PK Ѝ5}3G"RRMETA-INF/operators.xml PKD5  ? feature_vector_files/medium1.aml[]o"9}_iCOigif%I'Љ̋e(lvAȯs] Fivs=.%?qe^8O1̙̎R,-;^O''d|!, {˽%Z8Ç|jبL\[2W_9J0#aÐ7ʹw.|D,$} Jaa3 ߲3robK*NPss!CQ+,Mp+,/<k Caxt¢ۗLz,ހ,,{7Vaۯš5@.,;_TXס߂w0G++u\\G*>lŵ%sY)_Š3hW5;x,egES\ДcZqAL+X9i:r*5 k40R\Fsӊ aL+ƴ{aL+ƴ{aL+ƴz%5bʦ'Rh:1W kә?uJ~=P5 I: ;hk$6hVqn]i5O7$n7g\?}.h`mFBq Ӕ?$}.0\z|1Mff#!"l2R4Gt\i7kZ/hǃEh8oٱ):>"cQ\vl8N FFn'e&ҹ_G:>`(Ǒ)<: $GFhnƝXTQ\yl4^Ȉ<#Bqd8F 82G?H"|o<6/+p/,ۥL5 1V*>5ܱ{!S\&l3&31t^e H-x-/y&s+5We4 vg`zj~9<=4Kޗ {Z l|&e΍ҷ:oOgfJO$ؽy YE.B3!41=;#FB5awq"aj=\båXb(R,=zb.g$sY_&T36Zg{-VA(;h\3>bS-ME\c<p+P3oB-D]5M:CaLhx[pGbdgd2~1Y4z &R$Y c-pRWB{6IRPJjѨUX{P)=PJ,P&3, 4Ly4ADϣlF\).$q{L CF1|Bb24prdԵH\%D%<| \y-gsZFH5]N @'!3 MG!PbrR<+ш2@޻,3G9q:H*Ѩ<0HO3 p =.MW.obL'm˧jHǃv ;JzIPcqy{Z!\#++ mP#~</=ߞҀ#qPW{^#xQ6YTdS6tF  +(Pykd Xyu@ގ"Lu /6i+}8Hn[bTƲ؇SIStKǨ%+9 7~@5#H"?I>f6rΐ)vvQ-G\yc$Ҏo&1^QG.Q'ټRu) ,Fugܒ!b)ssnl-?-1 qkz3ށyAkHntTr 7p=*1oИ}6&'1;ئEJkݥЪȟyMmBQ<{"؀‹&c1'>bzÈfhfyrsg_6Kk;yffFTҹcL.L0)s֥o#mhV3}7|HEYuѤ*4%P7 u7@ ↧#D׬@,Pgy3?~WQ`2*6MjH%"=)c٪X &<ܻ Vs}pxnְ 3JI 8bq #*in Ou&u_P 6Gk5{捠5A%.$tc8$8wm\9ǾEqB sמ %ZdS|#t3:mߢӴLJ>ek<^>Nde^=׍+"PO |FݾE%^B2P :~ |4CnWYgBnu 쫧]Ň6)xWԁ -nϭnj%@7F` Ӡ- ۃا#Eo4 20ߜޜ7ޜ޽{盟η7 |{_zuUqX[ [ۨ.S7Uƪ a*3 `,qxpz]]n\9Iɨj-Hv:kғtBԕ#Fu  h>w&i(o2Q}{iB:}JA>KrJhfnrI7Ƞ?FSJSɵEowm~M,mcK5jŠGBF^BZ/t^H1]C G9g5' E+&e-6"#tҨK̯ցg&G~X;.nP456Baֵ=цf1zwwG~z8?aIQw0e~.XM2~~u\y)ô{ل<.f} ~P72:ɐdM+#_̥)dW 2ԠĽQ햿+硗sf?OȲZ8#<8r>><ڌ>1~~y#2d>+ӯ'g jTǠ+t`dbW! M35'ĖU*z z[e<ʩʑ,)teY9y)u#*r :E\1#Jcy\l(b)ȵI '0H/r.Lu}JP0/W\НߟЕw釷?69br2Kӕ2G=*Vauzc&"Bpub\P9Brc0't5dC(stP*mc:T 8ةs7jQ\N5Ora!Sn>T;:~ zKݲeN((=ۀty.q5**I>JWK fxA}5jcv`ץGŤ@ARqGGo5h[e1 Q~1([/[YRʺ7kցUSc![לP6xw/mF-Υ ̓8&\yЋtmAyĨp/cSy||F*r0"pdҦ6Ww#^tH#YV_=}Dh"ȹulIy"8a2-"O\l-]m#J~Y+wzzg ;ɁuxdIB~dLU^Ji>=d!4d'4rYdim2N99w"N7lc! trH́'Wz'D]0ȪqO1[Ut9}fŁ[w AqyXbB۟dz/4ϟ}4~YY'qL_%cZRo\g^vj&@T#sdezxR?K:LGy,|p›uYU^n^C)rO]E¡LYnn^_Q{}咎*KՇ|gN>>zT\.\+ՕԍmU 9_Ҋ%Ց=&TN\^7*@ʔ4'jD#=ȺޕBO=)Q2Q/^"4ͫҦ g",=sSOHjW]U_C- sqzn -k?l:z |{ @]QZYrG? uT*9Q;t2 {z*0%J2 VO,B/,J= ֔tPBVU= ԇ1lE(4q(V mR-ٿ5ykiOTCVU8ʀ}h]}:.}[QXpKt[72iKazSwJFIw[0&<=1ջNש* ^2#iִe$u{USJ.+)br.ߌϬ{~[˻_nn>\f! odWBCAuNQl]gi0E* $MJ('}82U94﨣C_*KGTrܬ=ED91{#tb]}"|Nr1@կ;*gU4e(mSZ*ޤ(G>URэ Y苮OmL7Hu4)]9M Ϯ$]+Ti dNk+};C>EfR4BvcYKz+,h8yzuQ_vι E®RIkԧ#T IАtUg(*4eG!VcW*TG"U6{SZۛ:q`<|xW>f&n2d[ѭ EgB[Yy#](h`V5d) S>K?{"֟ʔ崉G =D7*0[E2޺L FQ|::2UUVzJ]:M.QB'- Błlz*LK LasJ(ܔ Y/cnIIvD >D8@٪:' 1zT KيR4%\\9:k%3T:@]>E1"<>WnWˏp)/P L۬4m TXú2v{`$^ _sݟc/7 |/Y I\I-Op&9u*C&d, ]])= ؇䢌;az*ն^L$Qi؋<2j]ٵ^7c?bAO!FDYMRORO/9R҇o*M 6/k ^~)MCNn[:JS$msu; ՞+=UBKTL.W5ozFĩ rtkveE)ݛRX{ܻ@i}_kHV=~flLb48Ͱ47~EI2~DfN #!Ȋcib؟\1HwKScjȂ ƀ%55%-6s9MY?36JtlUjŝCCw)L[ vc$ S;axJ [WvMkGj}Z5a ] ‘éw:09u#y(zeLʧP `Lx[+(wA2V'd/Ο|0Acw7:=] BV\N0TbW&q;.]LR 2Gn#NGw ED`{6Srd3=ltwTI% }Lͩ"g,GnBMS4s*:tH rU C=KF$i)2(H`3Cʜr_?Y쐙eE @tTE'Hln\e}V3חz(DB9S ncczO7A`&hUrQ .xQ5U磟4 Hܪ҈g;4Q{N .jl[VRs{f]#JK NwoonOooo(>z;㕧)|)=5SȄ~.Y]eaL=h+]*Nf+  `X^MF5p!ddDF._v` @RNj=l0HOG/˨!:"20"J?RG5XNOq;5ȡEh3J" ʗ!6[RCo@qI@ vKu`%dW Q..#h7l !sm 33m[eTkB6+@Xm:AGYA ?ln6%3MU0#- of$Sd57w{{{ fxѸc\*a(6Onm05 `Vw/=2-8 r~ j k<חkPAMRU'Ie=Xc=/p ANSejtz* L&tx.Tc(O,RZYl'Tiyefkl"} 9 WYjCuQܝU6pّ1ÁMStp)Jm̙^76A-dZ&tKA?l2"}7⣖o3u/;u+wI J[rZB!#a5--5&53ѱuGL\j^H#ЕmJ7|1O08џ'n7 U-\yx۰ U53SHL5zNf lٔAT8r #TYt59_ziHodTB9&X"O2-l]W"A6W7ڰp]4Ĕpu.KEdg]KL)R0)FN ђ9Kg3G^zڬJзڞ`/!̯Owo0/n޼;]^9ZD3Zcy JNaX>$-<'[R͕:pت7uo]R ?KqG.xsqMGTmF'gOݷV`hV2PL W5,L\tnRwz« ِdNώcH;V*[%ccp cgB{W}##fPH1aF%Z^7_̀,,7@"0R r˪gXxFF)S1x0f`7X(.Z KNB}_^B?9?ܾ9b'_C=D.@4kEgS2N4[&߉m^`3Vɭ_btG{2a,7)<ʚvl#=B>z"J'JbCFq{QOl0^ %M 2&LC9^ S%A6D npPd7oH! 0sp_ݫܿ*DZ'*XKDQ{ԁ0]X|G63E*([8Ȗ4YIHP\f(LX/NI<)7De @Ŋ xe.30PG[t+o WLB&WpUm< dOdz-}RG&*y0LPujڏEY F4j"ljmXO{2'ֶ1\It(h |L)Ĉ6wP m8s6Z>Qd,Vsh.Ee>Caڿ27wy7O}twO7+X3ȕQKi y hޥ=MeT5:~XQdԍ ZA(DJ93t":ҭ0F{ÊN zdXzSS\ͱ PyJlT9H˦]?cnKIxHzs<ʢbrT&f%Cצu0#1E+ѷtڀԯ)肾lX0ݯ?UoO?nV!}EC.11@a(L>w||Rյu+V}QzWqh>0p\f0@GS!r fk;(d2[clD@'K9A+pRGxU .YzhQ{7ؔ7Lzb-f,ΏP0+ q(Ai \cl v>D<z;94U[u<(B2`L@[Z/lÀkR!Cc/@eκ=sM-O1R% 0Yi=J\EKT Ϡȵ$jd| \c*v^,Y2ݦVb%Wkes^'n({Z@!^Y15:f2qfzDATƴI4OwsZedK@ܛ.LHUMUN>3 T!6G:JH_1f }(t./zFi\j ] ][R-S,UO6S]*Tu\4鶯u./ʩoOx\Q՟Ο<ɾ1i=|V-@]h98=H`O3h T Z JTIcSޫ)4NKÑ"ƓJ=B {zCh#juc#A;#b@8 pa %ii8IW* eN!0V T mOˎ~Nݵؗ#!Xk&`Đ6Rdf®uCOO`s: VJ_nm'P4B24(w,38 7ߝo_~a_eJto[ZMLFM-C-[nyD@f#L+3U (*XrL8\7 (=_s ,6%ʮL%v\#u#ҕΑ "@ջ/!(;GC6 DHTI0-wȉq- s1^4VgL!%ӕ8B-Ġƫ+#ק7+ ]`NEY(K 9jUB45Z;n'J F@KvPdF <*Q݂0sFUf ЊZXtt(*u o .c|ӺPQЭFJ 8&kZB03<̩cYO tO ipcLh!pHF9zfF*.G+ly)I8^[izunťGDW~<#Sm#~QÌluJ_PO.@lOg2_7~xJ gr)2%Ix%uTaRƀ.42Fѫ[( _z hIt0m1j {YF :G1(N@{1LaQG_H4tq<}hS6$x=* rGˌb? Krb`Y]JH?P7Zg@4zo0)Z;FrOti\6$kz"&+ y?.)2Lp U(_+Y %èbe,:v{#OY#ӿa |/w?Qj V OWVQ5+ԨnYAfVL!uUHDwҗPF #俖F+y!VklZ7q3BqSG]DĜYjbyXȿV&] d^.(qI.ڲsi E ˙MG`%]i1\,:!E JDr5(Gf^Wl*nh/$I;4A?6(('FSEeAp[C ْ,"pn$gϷG. G;|]>%k}# /J~k>Ɛ aFie->0H6Ce0 ,$*e4 j▝+n4eҝgWU.:Px"wA˾J9a)+ hԸ |zELjhVLYȺy('0} gIa͛=+xu{O }~r[bNlA33[cQQy՛eymI6Lo]WGPO ]bMw|Xtp=ь]- 8+[rup5$[Ci'q)6ɡ=ebL*!&9Ѣgfi\eP7}znaqD3{V6!H&Cd+xŕ Ml2(Du;K2iޡ}SZGP&auGk46C52 g{J&༐Lq;ݽ1 PݳO@b\Bʡ]GYy*[\ @ώykD`nV[JJ,륾*! UɫĜ0T b<|֚^}2>( {%7dڻP?f+Sd DZIO!bH5* ^bV41)mtB>&yEEbh_*Ըv%++"It`P VЂʋB{MS-Xh/@Zs\#-.q4]>袔"931c`Ҷ?]. ~p`R?no~o>_jgτ>Cu6!J f3 sfXiCH;A ()NF㧣g@Y*98!HMn׶vp5C&v<8u HSN.-YĢbYIgʘt&l|8rP{Nl Bܷ,-xM#&tPvŒbRZ(9"j2%s̿IXr]5#Ki2iL{:iLBUQn&U@P8Aq#T%|G_8ʐZ*Rذ>kbdBI.ќMs]lwҤ z5J0;N56!k^c+(4> M+Zߟon,;z-aQg1^Vpӄ|~MeϠh 0w)M^l=(ݨktcg G *DjFfx B \tX3t#^SM]® +'LRu=[K;q)3`6̸syXtMQDhQ& `S;x#5aWnqLl41baVwztY.d%Et?QZxhY ext ܄IT]`o=yx[r߾Ϯwod* [x\6 }@;ǤmKJvqIͩ k 5its٢]|j9KkogwErh0j(y$sQw?b̰ t*[C^,yB(4L>,JȤ$uckm\B._ǫP^.A ;<wJ>_àIxZ0"X3`Fw\2Y`m bHC $Nwt'FdLhX<3E"5#](o+!.2ϵ*o6C_YF2''-ʆV]νWЙqyko_y򃒁ɳQ\2XH.H!n6_ddT{V )l}1URic/+76u&46tGw#$z[P1n,$6ۿ?lo_Wv67·/y9>\%2r|#FΛ]/ %_:ߩZm/DlZdFg+Lf'+JJ:ycI^ `鹅iYPYAS^Y#[f m̸r|e ?'R+xhmX $ChC۴̳ڪ_еvaTЀ0ـY:q2_E* $ˤ@~6B(C1du0<ƘYjXˮNb'rmZ4ƚO?(f0>3Q2 <,mL2;B"eGd 왏;X@\0^N*wF^ϵmpO>iq &[PyC c/V0l=rR*<8cgt@jTGE 9|v{)4+ N!! =C&!z'vXq1F3}Fyf,`n]Qދ Z.[1ШWKk1e)5{2ASM!]]gAc{GkUx26\yM{_ncצ>>cײoF@}Y\eUm<ܪz7zN @Rr؉ H-+tbr%Stf{ӣSXR 5VQN@ t&r9ܰ:˄bXo#` =JX읡+/!X',\.k?Hx!4AeA$Unae1 eNf2 r-=[a/i5]g]j5ʼxDz,HnvEsp[OЛ mWRiȠHwI)=OIpim$*u0X 6ejbur޺ !|u=Bmz@rJ{dUXOzwOvx##r0,HS244^$U+]Z+S`ZJ8:fcsrWFE$UCQĬ7u "{pBLߛˌnEFwA%VI@ XS7KaK5P0{WjCpXhBDDHfdTf! <`2I(IAj,e5bd#1,q4cR(Q~y:^{xA*yƶZx0. >0l=F爵3IitDC xM\˽Qk+h ΧBϣ0/]5G-2^OE()$we?4| ~>yis֗;]0g!߱|߳t%cAx\=$CBa!<`6@4J#hWf"v5,+")dE,WnKyty>4 dĺ1+F!TbҌK"I[jv;؇fbsXe+QȍQnn e_>2ޓl&Bz\U!owK0x=ane欈 <uF^0:Gӛ`@&xyے:}Q`5K>7~ׄ7ᅵa~u,cOo>̟^`= k+0ӷM%EUoa k ]t7sw"X I2KDJ>([By:x4\.WVHrspdƗ,;>4EXz\$L(en ]?*ק?^!ʯq0_ugO+s}8<Ěxwիwtc|!NׇXP^#@'''Up W @މh`.NtA^7MB1qn$(|y)(./Z Qģr~G/!@JjBk[E)MIΣ{Jս5m-,Jp4{U“,J3h\Y ϥ_WcӘ+'٢pn9U*Eޮ봂wO=']di5& ٟԨ͛ۏu}Jw|H@ b'y3];mA^񢥏Wt5uH'*&bWh ['4eB˞B0thzs-r@:&(O%3bzNgYM?FX2c=@vAf;ʕ[Hsn}U.!/}WjziCgk1hRJr܀,aw%tGSDv^ɒG^4~2Ump{ 4LYl[3IJf8T.Yr4MqG^Q0)' }n e>撃,ևܩV,] ⴨)4ҎEdX̀ofleWF8vP&@6f[@[a#^ӛ?m2v+ՠݛw%8]/tZq0Ӑ&sd$P:mۢ>jӡ-y>=Qd'ԇqRsU9b 3_ G ƌSԓ-fiz3P?b{}3gP+:P޶ {P_:x.{W4YB)B͐us_uǗѩXpNBAwAQTZbAeEhjEEHh4ȣ+9XD#0<2ꍆ 3DB2@,ᴕT aA@^@EPI`{A|օ?C=N@e~L$( abg3@)KC؉/e-ˎ_E<%^`G!e- }4䆷O3:~]wd\%i!@RlY&2LpRESDXO-ADmB3t-kQ@}z-oϷnOߞ&0~ >"ElIŌM 0k`*p䏤we`2&^̾'9{-G geʗ}lf0h`hZ(n`lɐK"܂7pe(>}am2/|'U4!71'+/.@E}vY!qYlfFG,p2+X9 Vi$gi "kd7 EAL3\Dz2 x6h6-@PYfθksȶ`uA6u>;%˻π`ۓltj`9LxVOz~1}`*~hgT5^YUGz±Z]Ɋ+Ll#/H,`Vd6BՅ1S{i&hTX4̦0ARBZYCVu¢*Ma+W&0 Z啁 &s$MYM][9HL{fƨiwzr# Y1afX9bY<Ű-؄g_6`M0ZzXd}Fdy:жQ_~ӿ?̿?[Im f8,S&7i`[{f0^]tt+D d ۞^JiJ<ݿ~_ϧ+7M?k<$alW/۴@ޟN=tƆϚ H0# jfAN' )+"+q83pGB%K[ ŚFBn! ?L ;Venv<27S* euZN2"X.Nk &outޜ"4yγ1 }w`dWPef7rra5{IWM܁Sfݍ*Jk*\xxײYLmMvÑo`ٗp:H VӺC˻0?<ݞ& j[#Meᚼ_AtӈZ6m/Wd|a ተZivܥHX9@5^YGx fN/orPb{SlEH9dX4p1"YZ5'SUoU7s1FP9Ť܉b`~&pAAno\[[C4cٰ.TzLƢh8 2ĉ/@aw"=J92ivj3R^Cݸ 7e.KȈCWijs2gnWHgpǦatCĠk`%/AnVakg۰gqAhbI_T2{p> ^hbU*BđЉ=%}]iٴ>:0j}H 0m5c>\sc$ˢ-oEZA/aҁ`?"0漙Tu 1xkX ]c~5J3!! hv Ë޻BZ`;4Dl:&3K [^g],ɒ.@ڂ;Xgɉ:ݽګV34;YS~ CjNXSD< b `a"7Ţi9|o40΃oII{k2@'7z8@JtOhU/P|2!/IX!H.'j+`ۀʳ):;Yd{#Yct]3,2% oadM(Fp4r+$;#t:qَ͉n!%ClQȿg(s^'=`!w{b=~~n|:e8(0&voqG2P2[(ebr.jڭ2F6zK0G.>:効P&{KkP+pun7,/5Wf%~:ݾc _8>?oo@|řa.{؉q9o+*1x {A).j[UHpQ6N`U?-=Z)KCkN7&:;n-x'}8g=Yh֌^YNLsəmʄ ۈ @f=-.]*&:Cޒ. >I æ)xg@g!8LOJVbI^1-7$4ֺju(60&]ŸN̆VF >'?rݯ7\: onc 8yޏCPf]{xyW + 0 -FX] ut)tX8c'kd^^{[kMDP+ ULEzqiȁ8s`4d\4ٺ0Y*Ԟnb6d(5nCg؇,?BZ*28 ›OL?ų(Z:VY"pT-K8ƣqK^DO@}NYoxYFg(E kO x .ڷ/m-2`d' :T?==Go^?yG .8ҹ}%GOdU$>pHu =dC:H? 9.X.-yŪr$";) tQrH:-L۽"B@9-c Di~C(V:p' &$L^ ؆R SF}AY0 ,ܓg<5D'tyUVNJoetvK(_jeh^KLGEjncY*ԺFy )y?>S0"yHk77?=þ\_5x79~O{~_o޿Jy7fuƫ9.l!ӼU Vle HF.:݌ wwρhBmڲV#i ;Oq묖,Z`HQs_|^l)L@f9&^ ar&z8nXTFeeG'/ph;F'?cDMLVIt$љ\ju*rp؏!=IU,yZ sY|va00a#*@Zh0D"ȥ(sHC "!b ^/DPգ뒘L`{`Y<_2t[]DvU2X{CP]E_:%4é+pY?![B@Tܾ(ݲL,ήZO^A} xȜP+7h)qB1h|1!AM]b6渱nU38w͡ #o@~\{ѵC DA?]-&ZUu*Ip}pkG7B#؈wѩjamD-V*{`i`"ӻUesI"g͢ػEV7v=rr". a–AҜ(_ !=Z, %̫i}Mܺ8@A@+Bq4rL;\֡ ӯDfH(?aZ/ó+#9̯?<>]l͢O׻o_Y$lMf]\wX`%O0{}=~}Y8Aw͝%4\C2Ba D^7 վ,7ܦ p%+DZ}4I c5dLG.'QЂ]8| 4.} X&5,po&R;q9ƾL#&Ե+)#/0r,PuQ{-pN)' 7;7کk6 [!:Ye ב궛FH@gS_\62u45#[9 i38dBm i [h4d)Azٷe0}ny>EuFO_Tx{ S?y?tE #9%Ji7 pL BnR$ G|_ƅu 5 ]QYy.l)z3CY&&Q? lX (άB c#lGj2@0p2$mW)å~m X:?Is@0ʪa5[Edl1Rq#T59[ 6B~ej8F~PVoZ ɢhjw1&ѥE19qIؚCdyY4ƙϻk'?=ÅSxI)_|ZHN4.Y{#PEM<*Nϸ+ɡ 3·lW{V^ʝ̝Xk&9\uxqc(:4@f!nM `SG3!T/.{oIlE5,#e@ﳓ"Q;m@f1 28]6aʦ=<˷1Բӣ''^>6HɗR!6G>Gz2﫻3W "{+Z~ʹVan4Pg>Tҧi8o`ӿW$X<3$& ⨠9,ƽ9K+в*a.2˶ҴAjyd EQ/Ȅ~x<āġHN{2 8wCVgM0t4Yr ׈ 6]AP% F/4 }OVuNBp\{&nײpa=,FӘFܜlRȱG8;'h*$awFJx~] EHZ6䒮ϴ A@.v]~Ҫᗇ!xu{Lk Nʞ IPQdfed&r^Q `]UXSA1IA^B$$I;ЁȾ 6RFkO-ZqYRleq"09LOУ=ھLDcp>mKF('CoAK` h5^#Qc:v>bk0MI,X;"/r[^< (KD>d»/mu]?!_U?N )>KbO|{J7Oge3֋4n6BH& $ځjѠFY"_ĞD XHƎiPwF czMٍ]4"x'RC1 6B>jfeZBFdxT~ iώ,k.T I;±o~R퐺=/@^a$"\!ڇ 2-a.J @F/8]"[5#8-.I46(/Qah  Ͷ0麆ߠ٬rRi0O0S\yz8p%ۛH8y*wWJ&t2egrz(%Gwzow3+㢱2{+x7Tpf8f.ZkIA0\Ԉ.IH{W0$QnvrR/VUHO:GihODj5dmVҡ"dd+rYPً3r96H# p_h}Je2Sf&#vڣ~Auw )ђӕ^[K2`Xۮ_t? zDC)'0m>I׳ ƻO2ٓ m PK;D5a= > feature_vector_files/medium2.aml[n9}_`ȓ~2 Ȗ$ؼTwY⨛Tn)꒦l- I`E.6yrbYf(Qvӝ̓L8ۈ~{RXfo[wZtyOVI|ele> 2yɹ_,.L\Z]^IN|Fd5JL4-rJ~ED鈬7u\xR@t}`J KIpWx,{KXR/tL̩{ E(V#&)XKOdfi(ѵJn[,^.-{5NimWp/킯Z)-m/^J,9ҤeV8u"519NkL563}shzcB-7^ ॏ*]p9?r8 +~)uę+6eJs`*vŹJq@`Z2$8 R>6 ,&L~'#=C ] sDŽs%dɐ2C^'Y64Z})Qp LP3vnT'!0f xZ?he>)RDF\ jqd.ld Hos!7R|9VW' RH] .` {k]q#SA.j&=t?:vT^) w* V mjmsO𣉃¬׀B>2qc\Oxsx\^`ֈ[~'uzΤzB*eDCy+> \ٷrJ?Tne{d>U\r6 1Q)RғB*,CY#qȌ EU3qOU:j2U(7*'5tBIqPGb;ۍ߬p6߫`q nȭ-E&˸ޛ&0m} _;%ٍ\뱸!NЍ)]U4&(]m8X7qkİ/|6º5b(B<*(g-Ht'ufÌ#݈;&c+Z2 '%3Dub8iUQ M>OA z!.fv6\n<كp Ff_A_H E_f'|A3}%I!MH["VlEg6j`Go@Ix63IiuYn$c7U]3):aS ōQ܈nju}GA~vRp6`n~Jj-s0'64C(!b>Ė140/BǹWNsh\K|S)pHk(y1DKKz-ǩZS>qZZ'듅?Rq:/G {ϩ}d}k|U?[юu. ĩ//>~to[S09tӔJ)BTj3b<1}x=)Wcmz!]t0tY/Q6]gcӧOt6c3o_,"YPm]W6]2/B})ϗܝN^N}x>pxzk:Mѷ媧Q.[z{hE]Z֓ s>},zENBKn&]p]73Xc2J,nV:"k^Z}[tZB~NPʺJzktB=}H{gIw{?Aݨ+S1 QGM/!$P?([iUHVyie=9N9VDٔV8d~>}@AvQ]*.3qQ}ce:u=:M&l7,_0:~k,t֝eU&'Nxz&Eߣ瑃Mw۰꤇7K)ihk-R߶xw.{{9'Tezz٫ eMQnWA )Ne\:Wv/xIY?)U/ (7˿^S,I7}' \Uz(9:]Qbg$JvSmz-De;RcE5t4u8]I =}nLNצX"Kլ?:.:Ԝ"O3諭i\wk6lL_BAHۥˈb_#;RSuXr qT skhgyXDnHZnB1p0_4$$d7ԥ~QA#̷ƘN;㇇6>>ݿ`jUT?TZ3#9Q=b{LVCmIH|\ey(n)>s,J\MvsI4i"ީߣ+8X Ba٧KUם"eI70F'7SH9+D:/2=L2D0dquY(7av}vyڥ,g᛹5@9d}2E\xTxh:kf1^{ΨsER~H,ev>DpXuX$mGwzVdV[O}DEf@62 +nq~q2)ٽ%8 >~9=x0d*LUۜd)J}27=C=6QNtF&i~bD'(둁NyR?YD٪Ҫ QeJILv̷sLB]7<~C?SQRŔR6))6+/U*٢X\Ax*w}PdB:,jJ.H򂲴*OTɡM6$7L"ҼayHb9W(lnxT!7,:g_gNi\`G}*q S5w|smw._@pdD=L=bjEyAgIt,Jtj*鸩A7?򈍾yww*S("w]RMVa@^Lq 3TFIrSR^/))$|T\d/y>:ȵPs(Pb\,OBC'w*=FWަ,X#\uCq"7R,wХsHz-Mc(q6 d0B~+ר(zUu:|5l.|w$Mtv`XR^Sy>YcݪǔBq+țiFOYEܘjנhHGPXxVAi~=M9w\wF7{<4\:٩ߕ{T6Fo/燳ysqByRV2'cPQȂ}q -$rq/ѕWS{Y\s V*g?=NwFi6v&zWނidM9{'gt~"Gf֙N1٭iɄuYg,d1*_r*sV!鵣"z&)u*7=+CW؆o Bµn+{ۥDq|'懲-֏Gΰ geAZi7]Bү"!Rle:u+c&\ֲ8jW^8T;t#4ͫMpy kYOdpt]C ,z"+}T] O[}~ڍT",U"ZΊzFlcRi*=mc.tt9{vKxner:*Ue^* :K5w55ȠMéL9>9Z-[oIYrr9uA;:OQI 5L2tv#;S٬^kymR4=(U$BQO*i +KgE?l2Ұp*)"*{ZlWɚë~]'hCۣ9J㾄R,zb3A?.[~3aot8k;yh9TToֆUJτ9mq*h&J }TLMf?zr'љ(.(~2Yt\5hۉ D*nddTK pQءLXFςީ#KRSYMI4vUwLFIRQ(5IT!GP, 6W9F9m#vDZUUG&QQ?2iSF#_ٸYEeʛuUT珝.zX!?eRLtmT8ѿRnAen||d6Hr &ܭ-:l9`cƣrgq>U=H)ӭչgFʙșvtQH:lS tz TY %&$WNSYT%Iimn'άޯ\BQĀ~R) W).A7=\3t? IR ]'BS>`W(|e2+TAQ $)6]foCV O9 a_?!D]__k0&T1JU,_Ͳ?dMOf_~ao sX橓~jDN}8A[H(=4T\M6 ,#WֺHSRP Wer9}6jN43}F<`vT/ɳ3Я&i.V=Tݡt:]#GFGO2~) ON__A7ƴU{2 wYaWIW3LDF~/3cFO)sSݘn&2'g)wT+%RIG@RɪQ5l((ON9;9::SƭNRyu4{_VW:7+gؽ!3"}eϏ>X{\곟w75?錂zdf#;\:IRyfD\2RIUtUQ hq?鎤aErH`G6U%)ns(w&rI=|>N !|BQav8f tʉ" i2Rf@KTwP@t$ @idJKI8RvRSU786#~(ÔgIavT(R ko@g'+?kث!=g9; ^~>s?vC)Idhx&vO==.|Z>9 #`{+3S+(Y>B b|K?A{ݧ³W\Ĭ` ?/\CF(GtPeJ 釥+Yḳ2ݘ8ɂ_}UTo%8 |:LOtcg0'2a=Jf6ݓ<8)PaxTpH_'pcF2Sr[6^"(St8ܙf->T*w/_.]rTΠ܏rSTUyEѓ.@uc6%Ѡ;N1sG'g¥lrp$LKt4 L'>?@jCuu\ٰ LJ]kg;m\ivwW>4F`2Jh&g9u ۗtQ,*9]j[ +iMobUk8Nl]3 qN1+>YIْr Sk zV6* ++9YS@ۓBm n(G^R/ELhhE*ڿEdwe|TR VJ N/O}:㕩h&;mYNG "Rx3U)Á]?ܰp &X;2z 24=yuӬaI\]ㆭS(TɄ`{ze3m.tǁqg-/7&*t_>m+/&P?pAVѬ{bXB*>3>eAZ=yPj=PnlO2[F"Gv (Hl>Ddɰ hêfI?ClWhz4Jy/0NcWwztem [ed Hu#[&Ĭ#P]#p^#?LON?z.[%Q<@9/o%&3K3K^ᠽ@ l6:+`㞡 IҸٿ6b?/o^<^h6x4Ae63nevcNS2$ ̈́zؘg3`i7FUiA:jhS`DϭLj':Hul=<Su9/MU9.6F' lYcf nx+Lt6uzf u2h4Sk+ A(s%i;R@(u*7Z4\M;1(lQӦJ} F3B#SsL*)t=GF!9E}[`e[ yzvE 4m>nlx^OctЯ@B J Pshؑ k -7i9[W6sPbXqӪi: Kk_M{I'jX*=IDsޒ@G߼+NeΔoFps*R(Y64Ff8/7lrA ]5*ѽ|d!uU@P$8ԋۜXj7lXW'>%WW ŧ`[$4pV~x{莁Z+a ѩx,tb ]9Xl2EI\R0*06Mq^9BN{wEt4)RХGD&}xy".,?7q8c\GGJ'2Dp;tpugI>3yRx).ن p',lt b`^G\,:H;n]lS2n<6%_.#0syh)`P%I#7K1gjAVu2֬R^oYe@(Woѡ$HO?]kJvTǛEvJx*OU|E<xCj <MH+st ?fpl@E!h !E{s]8#ǢB(J } @Kj[]uXC ^͇>𙑹?/CVrtq@cGݴ]sgR9ݐ֗ffs1qd!ov+$G~ Jh KSZ!1蟆@_J!@AE<0c@Ĥo\{hmR$'کXdzl z֫{ޙiTt|yz9}*7|cJSз馒Q k !p:uXJe %Iyf3*z1yd"D<@OOAƂ570 #Ӓ\,؇$0pDT,Jj=b*B~AI:cpJHi5V橣T ӟ\u "7m\<;?#cE8_GU35!nʤa&P?"BiPd51M~P^SPAS6py8ܦr~,ܯH@%ח"=p`!3l񕕦roi~Bl}v~i l9X&kz: ԭ ;E K@fآLUbV2 Y9]NrDqu^*s_73kOfT@'Cye6c 0CB5ۚW;ttaWk7x JJ@ ob5M-G[IA` Mޜ-E:h !!rM^u_cXw/} j7@6@nz_O R9}~%b@?\; M# 8Se>Ḽ~ihMfGv0 b&";B9#-H<*( L_?"G%fś`I F8Z@@hV+S*XV.!]r tl>Q![j#BGB,D#@{UtC2M:OF܀G*JV=L:M_8\+<ʊ!!8k-ZbڼIQ PvU"34kb޵_ǹ!}!U_{5wMմw7{[  ο ;ha 8eH MO0.\b\)ӓ$:H6`آvvg{:qHÙtȟl}riH@*9!v;ŖM E@_TF2to˫ 5M1RdπAw7ǰՊk̎"k5r]Ay&Vӄ]*joL_BqqcԌaAFC9yCz."f-!^'e7vr7>-, *yaY-W+|`Anjŝj01y]|սk;}p~~9;h//74nщϺ+}sW"b[N3|bF1<) Be~3iB(r_!(ÀZ1N@FraVij]A|S^ j*>Kw73 Sq֝ݙ#@v"K9:u}baBU-> *<-o,#Y 7ﶕjNk'K-ƨRް1*'g%d&BCQ[n]kBWY~+pD308Wʠ~ 83, D7voQ4[y|Vw >V!`ntܶC/YSv"+Zȋ.%O2CpZ`(Qs!FJ- U,AftX;dOeJQ!N#ˤȓ8w YXOi&Zʍ5%#>&dwmWEYEh(Cr84FKHh싢ґO ҘNkj FS5frO-X"\0oA6!1FPMB_jQkǭ^IRnvoS> _O㗻5LUPԌa֤DV4Sv E2D8k8Ez:}/ 1!i#a@Q@Nqi( 6k?r!J:9`F؝Ғ(}\i!-4U"KBaODASjWd?9}#I$B0 3,IKEfׯ]xom0e+8FcӐ+bpw];a1Z/y@ lZP=8b |Mʽv́Uܥ2A[IČh Arױ?OwN_βxŽ>~lUޢy&(`hNp7T[.nlbГh/)PL=&AV'QϜ  s'Đ&sꡂ4tŀQf}>ViQ& p7PAyUU9-Z]3Z4NtcC?ERx|4ZHS5â=KUšTThk#͞87 g# ݥrC?2c$r!#4VQu<;y!H]i p] E=u@e635ڦ"7+66 4Ujmg4JiEZn׷%7b\tɔ<ߝiQ ק?שׂ.{560&XQaЃ_cvvXV '/#Cr[Z\S3f'J<}q׀QcPd1 Sf-o~%Ue[-X*@iM].%z4xΜwv 8Y*ކW)U0Oթ28z :6Yuq3I?mA@\s_nf:UYXg`Q-^Osj\+Qp=K |TQ%gHq" % 3xdD2Z2,8 %ˊ|hlѽ*^ b6dMu+D/hK%2LN'Sx\ A(><|U+@U`7,N4iH8r>4H6;up A|AWrח%t_r9zŞ_Ѩ>}|JϞ߼|_N_ni \hڏR$QV{:鄢"xy`g)S {:YO7:yf[@R);A16|MAI K N.0=AzÐ ]"=bwTKem<=dY$eXKQy2r,q@25Nq36 $Kا)#RQ/-QO4a h-5)[G&iZ2UPp/XץtSn>5]li7Bzk"$4^ls+4ґ#XƐ d dW-sgܾpZ8Wí_.Wۯp׿5gM޵C|&AjEziTUf0dg`ԺWF0FOJK{f/Ԝ_Ki !u֎L`E&ze1j)aip]q@o \.e@h,qB΄7B*hr7:`4:V[+gvFO#IM# Q*}U  /]@p$߃;BWTJiX8΀6J|}V06)!g͜BlxC+X L[;~vwg雳w;eiLS@pR#ivykK[% ^7:Ź^D\;ۜ%έWRҐ@Ku<+9G$KVWݚ ^j~RpB^o$cn=8դm%KC<L򧫰4go4%Qho,hஊ~8 :| :$efqD+V0CR޺ZcZ?@d*+@7{8 ҶSuؽd;/`,Ȩ'mf[l pyg5o@l8$x&lNXCBVE4hәi.ЫixԤV@t,b.tly>IAϪ`Ndf377IskYƧ`dBo;V?V¨z @1r+| ې̓*g x XVDkV}YQI0ҭd3̿hm,cv"^- Ȓed$32*6wRe̤E tHs3q vo1^h!  `FDw˄+KsPA*WN#-%7%Sh fc;Q\Uփ@P}P~2 !ev |V]џآHO1&I7<*4d fz[ i.fT`/;G"k>jpvس>JvaD"w|ڨ' +c7ԕ[- {k q&2h0%#b:`6 ,&Oa(^{|om 0" 1wo)$UylTcxof!4sX=Lꑯ;#/$k?avA#131[[HqR*V{XT/p Oy)eby4kѼjAْaB~n9Rq.aX3Zu""[yUn%V[!A=,PmXDH̢<`ACmȲp!{[^bjm Y'`2Umņ@LC7n\6xFEb[t"n Jbo6^_&;9[N<>z|yw1dO~pw? EEd?Z3 T6" ;Z{W! 9("K=$!Qp$r&BLc#e5\ um :maEdO64uxk f0=(C6nS?1JBiYVH#нhnlC_` 6A[ZOv*q@[̎MÅCSW Zk3\y^]B(uRߏ.~<)ֿ$Ȗ^d.fjc@YrkK^cƾ<7FojnK&Hq9@T3ḆmFFt#I%#+1VIZ$贘^Bk (VUYpG2,:tvP}[B 5,Y$qv?!>MJ 5|ʅZ+ q{lx"=pjei(Ȣ`]OU\)/᭺z¶jN/*n$,?Ί5P'?;@7S/z9eضi;~\?Ow׏/vy-L4 )of/f`H&Hlt"KV/Y>z鎄z,އGthA!Z@AZ >ItZ@%OvwgLn@Hv`ZҌh KFy(?VKc!ۙdMTVVכU@:J8 ="ZzU5c2TVRhQ=#[,l. gG㑹%$aPrz ;l&@=-'96V7)Jb9wŬhyu4Ū5лM Iq}\8 JpTp4VҼlg B Uik7"_l ص-)-v=- d OJ7 v)N?\.*O7 #:ֿGYn͌rg0 ^ExZгH9) bFZlu'!B٪G,SE-s~>6KEc̍TҮc4m *oDzsgqbkYHl *ACeի85|e+QH"Me4'2pz4"*e?@V,[ GBy"dR" iB0$ܐlo]_ ߘj}񿝳r~@o@uDdfYB("8e6k\ 6_46.*۠g>8oZ l ( =&fWs.. 1TG SGDg]O-LX]-FrۺJ;l{:3 XdU c8{P ~$ZPoeᅞ#s ۲|bEI8lA/U+x0p5rC6o`+Zpd.F./Ah4T DdfTU3)_u׾cpѪeaY =Or!rh)(X +,=hm+ܟW+q*L !xmSɕn .o~~VJ6unT@qߕR *݌uvN,i#T "/>SHWY}bJ Cn=QtՑDѓnX/!x!3C?x0$wc57"~ˆ HMO0M:¼Vf: c @e8{?n(T?PnY UԎBʕ)03n/ A2[46u4ȣ3lAe $&()WJjrr.L60!k[ie{SA0&v."b_ V?_^AkwNc< Ab`xd8JZcAw.:gӫm4tM7i])Ԕy_6h9UɆ`$Nc;enzLuSd9+]އ.piT9=*E|dr1uٯUM2Y,i9^M_6,-KKW‡) "ڀ.^-NE0㺝9 mGDG3 d8ɂ;?5ȷAlA؆Lk=-PvCeXqT0m8Y5ǡ纳S8, R{T tD0{M e<+\8C* 4=}FhJhαmqH@aKʼgoxBuI6M&i;'A;zЕ ]\d؋edأ6&=t&b|>>LFk2_2l ϊ#hwݗ՗U{q(JF1T}Q\ a"@%ylx=k/[s;Aoy! > 䢕&hh29,b1F.;o315CfD :6 iAAyi> Hղs{dT19$X?&L WY_dAgU@ngLXڭwԙ]OjE#TSi>%'* 94[W^ڭkY U&KGR Юݛgыݞ߼Szr;U*tAle+18<\f {x]*EB@0){G.ƚ̂O_b&նk꟏Z.f9 so_TB=yS~mvT HT@$nwZCw+.}822zAS\jJ x?˙B 0bf)ޖX+e #d}6׬H^{PBj"{d =Ȓt6vN[CU^[,փ :b ,V*`)mw&rJ7_(V!Uϧ&x5yШRZ\A[xK51 묦.YmpuY!k&h|\7b[;9Yk9}O _N߿NP>k[6Li(ɸ8ݍg3<xjًۀ<#z/,;L7D~_oPUޠip\j.lw_~Qn")ZG WvM4VK]'(=(xxW_*Y#Atl@~kn .^,w(xV i5L^0A#epQF& ` 6§Z(My` 7SubkX+OYD+Ha9C^ #vVakG۽pvދoHU hɅ%NՑ#@0;rc}Qp4ϩԴMJN7=E̻w0*D7~{x }ӟLJ>~<|c5}mJhڴȴ^DxqVHbjJM`c!G J(^fR5Ae1&hh,φpf1G-Aݔ0\P#l>vG7kc* t]uXypg}bյT/D;M!0.hΏ\%G:Tw , aM5xH$t=C  PjV$iTUQ|()~Wk[woO{3Oyq,(|Q mdUXj*_KfRK7ekJPxd4P>qڟZ^XL/jU<(3W:tkv008)&?7l5ޞ= `mHFp ܘknUP ~֖:G(!9e*{D]!7φi 9/7g::0 u'cz,ΌCC S  O uN+j/1Sce[wԖ%|,nKݿ%ڳ_?tyxe^ < I=F3Z#i aJQf}E6ڥ! A%Athab U \0WXhAqc8$ABOaJaoIck@U6enlaA#-iu3:0xk Pղ(^t ,_/w//>aeҽDG ~ 8w{,}Bp7$;Ҏ;A[&}a'k3Ay`yd,݄j.R4uc&DG:Sw8)tWͱ9j ~4(.tZ\ce#܎=L.LsBN>>׷'rGV/D8Bw  k9๷M0K`zRi;cb]xDXx2n Ҹ҅i٣^XS!M]DžiĨĴ\XF#z`quCakw!({fծWpyAmE)QUx%#p{Pĵ7{ڇRwisl٠gLNРl'28Vmh%y(ރ 2z|á*U-`n&S@K眹2CbHVwØyl✭B x"jSӢg,>ohdele{Z c lit q4BM'H{ ?'q"A8"}sdqL|֛ h |v]&iC1TH(ouReP~ 1-tT~:?;ͻˏwS2!5)Ʈ_y8%}:-Q;2vz iv跥V4S)~j)8uwl$CB`;ZT]$h"EjI F}kfrRa]QFпՖ`$PWD`|.SEn> JpA'#'E)<{6%X%_п0 4r>FW9 p8n|?cSOLwuj LZq3?5 Rd(ׯf=ry8/O7 h3$;YA~g8zlF^N4s}ҢE7)*#7@462N;)cQJ^' 'J,OUKGI}(uCZs[ \Q^ R(ҥ#/>dL(e> ˹!ոG{A& PG5`+bPpʼ *4U3$di*r$si=m4PNHXMǔ9ĥLN+FAPHC%%UY߂D3v0r$4}YeYxQ% yf--Y,SMnpB0fR(:BހŁWְOM j[x?{QeWM⏯jC#J?`] Ci=71}қKe-* \.+).'Aόy#u#%ЪyuLppL^a\b6%k!〟 -7"+2^HA&WQͧ"MXG`ȷϤe&K finh'CՋ$5ww 9aLuឦ>,D@D&[& MxJ4 @BՃ?:݅K--]k MjM jlyśZ\Ջi2a'g"!>hӨhBЃ[ ){'%(:iM/;b<Z#7*DBL ziҒEV7'd`^J,XSyIaO15v|6G>PO` =t>:PǢFMԘezJ>+S 0+ћ8 .٧d'_nQ$(ǶgY*y_ k9(Fyo'1Ȗ~Ⱦ5zi+)0~[]xYwN|.@au] LǓձUyr']|lth.b)y^ ,0C' ^ZCH7=֋^4ƛla  ٿNN/-8?|խ`dw :{Ħ7 8Z4pE X0۠2ǥrNEY.!%`^l;sA71   `ҒX =uLiim)7j$)GT\JQʉF DnRRA#$G 6mԴ QL9؋{J3AV)2"EV*DT EGr Y#0>评sv;Q>*ew\i#ʒ`vq~4t՜XPOD%H˻wQsd!{ߜў|2phL*~ʅu"}Ma"4M;X(LȺ'gA,G_k10)tgLJ J!([x-P#ࡑ}t+JdҸh@ 5gS%ž:/Mh+hC;zZ6b,@o8D#R /^0fXN2HݦjWQ!@@I&-u~HTMԇ@C~Fv^5}XrQpNŁ$b!R^'s:rѸwfb/~n k2Dw<L:C$}@T7?%ʾ,GYi:06N'zϨ66@aPJ) eUۘ9H"-.&rh^~|*P##(e4+Y A;"wUw39 >|[4r} "@!"+}>4hlOdeP?}@G9dLR_X Ezk|W F6ݶ9y߻?4 OX\-2}5|[RT>1d~+{o}ph^MFGH:%9RQ2Nr,7_ǢZ)Y0f=!Y,vD O`&hx?lj-FT!;^ޔ Z&7VLW:I hi?-#GzQTH0vۘZqѮ8W0*Mfظs|֯lwN A` oN!UXG|`n'ɰESǡ=-Q"S#ZIA 4 }ϒWy+N )8@鹜p/?fKnQM>E 4lN\ p!\&g'c[t/C_' QUA4<5E/if@1'IMi0:`' ?IZR-|2zUW]|A0u>2AC 49h%B梪EASI0#AXgG0@U$/i{B8qZխ"jRŶBvT=n ܿWyu`2z~AZ,}覢wIKCDRѲ`8fW. 1_W`IҰͽq=V|rB~{www~ֿnG\e8Ӌ@HL&-P5YEE܆=V1VYGsDCo  )18.tg+[J=u+2!n6$h+W ^W-f$X\vگ ^:]?0>36V'8%NLeк\cծQ/f82,G%9|jAqSmOg4hrou*UeW͂:ڄPx%K"DͣEځˀF i7cHxM[m7*,H~D"s3B~Ood/O, 6 Shu%|7PfȩQ|+²ba-PY{6)mnx7$(LY8}Cb;ˆ)+l^ 3P:2ȮN=,ʹVv9Co"ӃHl2iɚ6tsbFI`#5: &Ȣwt "{\[ ܔ [q4nVen*n rw tSdeք`e f&v䇗Bɵ߹Qi*}tNӷ(!}~yŅ͖oYQp+*фGBȱ)7H1B^9QG J,UYxJǣLq(*}<)4z#@ QUil94^b5Tt12+1^ k3z$ a,/LjiE Udie=Ck}.Wuݍi'+KĂ,2nP|dJ}B`Oȅo[{OuTeL.Kə<<_/k=E tH,_̀^ojxy i6cS9h"i8血vgL9IE H , /^^3F#QpuH/I(˨`ց!e&ǩ cR* TUjw@2G rQ.eء}3'G!W%?B84[Zke~O 8 lY(xZڭ)]Jdgw5zT4C+(' աE ]sÇMG;Y^Q%Hͅ߼9D@R>kgy+1b7 ieco>FdT:}uy<_FjbԷw| }rl޸ٛ`SuxM!'7&UqWe. |7 g"7` X0Πhs&9`Ad>wzZȆD0ȆKu !Y@M#2&c,nB$*H5@,v&&!s=2]wХQdN\86PE{b`ͪwvah1QB{cu3貀:j5Y\GD `Ød2`q@ᕌp@bǠzSǺCUVWwO8?Z1u*zj{Qɯ.ߟO< ďB.1\*I'\UPd&DsTFd+=QLtBFjMF o#eq"S1HǪi, &`Ԟy!Ԏg1H=#c#N`i*W kt>}%Kl8d}2DU&z!p0^`kF+b6di;C^{2/!9bM"O٭؃OMi:RZ[ ·^&)2OBpGKd %lԑi j\lOy@+[cJE1胃lPCjʶ(cPC:>&ۦQ>oٺ0jsAĆufV֕̓MnP.*hp UTQ)9$Y{ΑW[Xlu}&E`woaɂߞN_~v.w?+?! 2VG :#q%pC.EUB4b= Ř/>s0'Fe=/|k^V"x}mGI`[IrsCfPRvde=)=wcw$U0=10Gh`P .|x @=$] k{ZcD'-`~h?lm7fuWapc<̔ĉ&)9j!]R {SVCr4y`ak߀ʼnb\˪R~Է$IDA!HMFpra* 26% i*V61 7sد8mo$, 8i2rloNbz!_WR<}?@_ ڈbiuЊp9'2h8sp[maYXiOWSX{cxF7E԰v@5 Th$ ފ3fXf :ֲ|^40'0IP Oo8${XPuG]B;ruTpW ޳0!u'cy) 麣UEؕ?b=b3!E9%PNFPw /e v@loTfVw@"Mzl᧻1!䯯.l/|7ìoO?w~=jyz>Dj} "ɧ%EgZ;~7")&kK(љ۬ZDOaQIE*Zh&`d90 xŴY7mkh@~QT-¢/:tPYt~I0Zs{Ǚܻ+5!X! NaX3#E6T\wڱ|CCr4T u8y,Hҽ.bȧTZ c,Er Fò5ogYI%VgP_pwYwo߮Λ"W#ΌyF;dKjgw秗xϏ7&1 ?҆HE*& ځ7 EX ,* i hњ*d^Wm%|hc\LY:i+ 48'|2`l9,"FbVcU`Xݥ x1sf+8B*fP ށ!L&ێB5k$jrϞݕi(E%s9ÏƂu+}rMwsWB^k°e iw!UO7^I%(׶ i3tF+?3Q$7jBd3(AY'Zܭ00C |P>ޘ"$2nxMף "? D.+ DsAGlR7\4e\z8'ӂ=/dFCteE3\IJ WS`\*tFHd]b@.1A7L}v<;1b e#%y;_vσC0#hXJc"yEoAk`Miq88t'(.{pc?!8lahXoI^e(WA<2cV; *Wc4u䖇Cz'4)-Հ\A"7[dBD>]if#]Zxαt6B2/sIHdⴶWeP|N}P31@x;u le@M:HTVup(cj7݀0j~2J;_y{c_"z|Z hа<˽_Y%@>ML*/[#=Fw=g7~xv$ :l52_r.ow PKF5 = feature_vector_files/medium3.aml[koF#\`dIvKJY2WҬuHV~}C9KElMs=sFI~ij4K)(̢T$&.PeɿC?qtiQwrMVITG1I}|?xgPS.,eQYQܒW˭W󈄛=DgclU{MIVCj6-9MLr>MIms!=?P2 _]YkE=Ҫt"W]uj[Dg׭mvٌ,逾imSMܛ;mrxXpw6_Qwwλ/8([2:Ҭ#|[n%+Kȷ9[ߌt)Q.1"'fS_iWi5E6{UZ}D>֪spٴV} C>֪K(٫ \6'UZͽ~Vs/p_ {~Vs/ޯ"[*TڥH.ֈD-ЙaA +"aC>fs+k=#ީ-LE#/,& &]h,Uȧdݛ)66# >12gb&q<_q/z# S[Wmg&Sy^W: : ˆp&b43CқЋԭ(7h{ɕ~͉MV+'~K6ɥ|a0&IՊuT,n_yƬW+bI)ei;`G6+N(kr(X[l8,^yN +vؗ ~K8OSH{2@}|1h[ dFW-9zp@D5EØ\IT UN= KPKcBPPE̜R f}% CS) I6}g/-_NaRƖt,7n\d> d(>\f#ȝ|5+_^m|id˾-_vryrZW?"@ઢUJl)ćj$+#4|N" \=XK+а_ ~(p ńNNO q(F!-0 $fRDʵ QZsN+? Tw#۵Zq)+d*vAsqƢe,U3wnrpWkS 89 agߜ”y, [9y_03W# Jeez잯&X|*OB%R7]NU˷Z9/y{]ȩp (RwxfroUg{K:O^q{' `Ws }qh"o@ =;-C9z,@h1NW&?VϬjֳ"V 匜M8ezLԒhki'yqWJ == tQ]r ev {A9&g}L.<)ChX fUCr K7c ^+2&.Uҽ~3Іϻ4Qr9eII ˎ>`q*;Y06UE}3T^AOt~zwPKF5A񪜚  feature_vector_files/medium3.datr$Ǖy?f~"u$6i44dah(O?[;N v* 2b>pNsu8p5%6qUqusƹΧyW=soS<ď2iHiL<)^OIyJS?y(r:rϭL)Ou>D&]_)R[OSS=::5]I?s0> u6_i>ʘ>^/i,#_ѧԗkmu!׺I?.ʏ7Mtjy%>^C/E7s=eiHzϺkau]p?:)W]^9]Ut FOэ1uc92RZ'47>!]./]>{~ҿ~{><=xӏחwp/sgg u0YUםS擷y/qǸZY/g)2I_Cg>8[ZuO4Ak&}}𗇴lzG;Xxturu۸,52e-zҍ8>ԜjP˜SzXRY.mLE?JY&.CYoCאRK+N#sa18[ә'V3Nti-w!f>^ypxwwtBeY7$aMʣe0~4֬cZl枒3p%N=(ˬ?Kـ~ =}]_Wf3zCG"~(ShB$帶<ŔӘjn}YP6* ;PPt"Н2UtlC2Q^U ޻;`ϯ]+]hΰҐ0S}FefE,Xw^t;߲X'AiC_BiqO7_/RؗhrJEYMLuuJ'2+U~2V-E` eQ2o|N8nES.9C]=9ML%=sqʲ.)79R<+N%EU 66W͖w-֩GdfŦ2FcT8*kN.ÇO?>eEENl@Ѝ|̠'ۓYe)'2Nt:[ ,i"TSp2̷r+Eu]LFw 7["[T槇O W_ ,TBzS&epbJf.8(PTRf*d{Rey )=I9+~3緐ԲyRg*$1+UL\~vVǏ*d4T]~,x:z3#KETL( Z#M'm Gaz5]߹b=$cE(7P5EV{tUwﯗ?=>=|~7S& +55CέȨb COE1NUYU7Ga(d5r2!2}>=ӯdQeN>\ D56^=}Jrs=vi%r5 U?NH^Ofaw/%uy8!7Cxۜb궫=)RTV\#P~%)(zQ_Wir\G%ۭ K92{ HX_X ^)2R=r%sn':t;J/iÜB#G#s$3ŝ9hNf`b-ϘIO_).KDضo^u{WE#iLǷAXk"Qyp.o~+׻n )u4tcBJ5Rùxe2ڭW J#B H^֧ӅS j0U!CI*QO:xW.`(9RVu#HV)G9M*)ȗg:hQ S#NEZn.`25ٽQ YI| ˹ʍH%NtT/&tTNY"h 7?ɣeg]^MzvSr+iDs2GnM-{=%mޕn䗗R,4{&erw%7F:0p_~|U%%[ 'Z$QIsT* k^کue ;wx4. &#Dy*UI,LJu;CHUa(mOP-!Tţ&àqKu% r33EN)7ԁk˯?*=^ʩgnT'{OxgiJ([f< umA`O|!Q,V;,iSE_yB#y7šFjYUӉ@KOU#)cŅʕB;E.VImUy5'Hzdǖx"ctKMni;e{z ?uGU9 )N HJptS[N,ܽ&%4"zBB.0"\beN2IJKD_=,frcZTfPN̚Po ˿P[EzI:Z*W57wo/|wp?~~NΕ\FZERiaa('6ZoW Ua.2+X)1}ztJd k")ґQR#g_4ӼJn%2/!43B }Y[W8f}9~( k+<( G j'2H~y`iNݘ(VN2Jt۔l)3|QrY-7+jk)咳K?̢7LA(21VCE!˓ǧR3+ rׇk՝ץFC$':4֒+WyJo}b?+]we#79!(>ѤHbJY&k$vK99^u#UV*nF"J4y]*5M)^_NKG;-BBc&"bUKJ!51Xz`M΂ǯ[2AmgVg׊V2aww5ڳ4dJ)䅔xZQGYbD!Hϕ|\OKZ7sQ9s键>Uj<5t(OʳFGIbT|8sLOaGQbzVy]mt{A'Mkٳ$.Ʒ2wOF/nAnMjub6cI2SYFxzgGFKawghD_&L`:ӸTZr^=߉n56IRV檞Ad!қñ)\M8 ҁPUFQQ ?{<>oWQő*{]'gNSuS;'=˭e'aQ⠢/drۗ89L((l6~nD1 I@<ɌPR*2/ΩKa{fYInd%׆)갘HK Otu Kcs[()Ƿ0g# ʔT)=9^=4ue 8wiJ90]QM~W1\tO*xs?{z|y~zQ5+yngkqv(֐P=PA,L-j0]wbO2 6٨FEq .I7hA&x2*ybAsgc:1H\B~p@ƟFywAOɍ+>C7D#/'tѨdН~/=Ȯ~gTN)yRtwJ }*um z4s"&% e4 =U0jO>Ga“¢+܈׊rm2百.,%)yvRzIHˁv*Ӝ<:%4[\ ZS?y9}؆QVǨCU4 `7lMg]RJeL]CpU \LWP)ʧ|Q"*68xqלbGW"Lv!CFhg`}T9 8F6->3 +{*._ٚK6ܾ<ӱg2ww$_z燻O7Yr2H)=Ϲ(2ǡq&hg('2Foij1VmJ{ ~+p'Ob=Nfa*tT*2Nd\!ezae1/%nW`).)Y΢=,aR&㆔Ò;@wQ Ǻ$`FG:Yd4[?w7P GU\7Bd;(O4ILo$_~Kg+PVXFK01r=«ưthtI!71*M%,癜_n ntD<)&/ a)Tiv+zg:c 1.Iv )+!<3*O4f맵@sϽWY^É .V-AS@*ii+g l'@" xqX';fxbBPyaۤ~tkC/C%,>Qgf,O)?wOW9||臁dY̞#O=S)ڞ`06V I[ 0(p9? ~WeH?ࠓC<^T0J9USH Wǐj(hN1:e!izȥk2b@3w^G8y* }rB/[N5e!LyCb{獲'ϦO ʖiV-`ݐ`KH'[d+&OVcrmM?Q2#9\g_jMiu^z֚ e14̐5t31R%)g(Ee:OqOȔ DԒ46;$1m=6 B{~!%rkc}[tbv15j# g1-K& 쉣BJM2nVI=7HW]1UWʍl3$,eOaEH{=aeN9/\e_0x+cVDr?Zɜp4•IƟ4%>(X9(6"k,Fb|&Bl0^t/Ni꙲Yb9fkBxJ :}䒑KXg%eXOD8HJTۻTE6(uag7\FGjΑ>ҥ]Wz3303F^nRHa4߼#$fMR\(<*` v Á1at6[֭BB.mY aKsD|2 (Eȉx( `7-`'0!CЗG)9E:W 3U.|k('lAV`>b_8z|ω¹A@!Ig44M|OKUZ fGoP_8nvR)\qlծ 25E)C#+wJtZN~n,vF|!` K̭i_ՇVj3q|`^ euK^xdCeh"pثtY1;hӬO$Gj,19l=t4!\NUmpo҉Ya N\Mz+OJ e :Y>uuF˨BAFGlT<72a-J&,ܖ=(_)jBgƤ#|*DxE/}DtL<[@ހ8zxH#rBj%&ՠ as3ċaz\O:F9L6j7#aYEpsX&oC!^@4n^;"`#MڝljK+q?ƇfґG0ޥ [RId?*\'b @O@;hU Z u¯WqbUNeޠqH2\ ||M bvfi<¶ "g uӳBsw_6*P(:z4l<Ú&3oUl5d\%tL^66V1W:ܥѲʏknI{8f9⮏1ן^wjp?]Oϗ7S!p)Y"!46?C J` ƄȽBCZC B,LlD+e::uLIP# oGh2ɑJWz%uYR D u-hs53F&:"TatUDYâ!W QNc5WG9;!0E8gPv?ݴ8ûi$rE h?o/cFKHNK`kP,JV>$͐-=8NpW#% G+q!pC .9gw|rG1g4$D!3qmNvZ`iAY@l7(q=&qVBbAZ3ai')*]92wǪCD@O0V|Q+'3up3 5 g^H^ڄ Aa[M 8ҸHZ$r | ShSgoKIB+FdHz{>Y*x@X K+_\:2) Ͻ1Z4*frLї}6X V':YF͕}Z o[#Ee쯴Nʑ6@4>N7`r_򏧻g&Se'OZ xdX#%1v 礛-򴏧Dx(H5(va@HRq@k;OjB%ܖB 笓= Vh6h)C fK*hnQeF{C>Y΂ۢ`cL &y*2i&~pX!8Nfi[uT|zx/A\ԅ%xHh}qԺ50H$)Dwͤ),]:9[z>%Dn'KBY$pC   n4V%PR*}Z791U`*n\pDt%ZuҘ pv ơ*Pv"]6->_zP@HP!:2qRvy 3ZaņNiԨ v׌ٲfOK;qUuT67.M++2(BO|R3E7;Q @!v_l=S1K/ "ʹj}sxOIW>Sϟ3?Mb$51a\Pu䴚YXD d i(2U.%x,:N3 T摔^6`xP VlsEZD\J+XCA qwG!o n.hpkgyFib~Lh塮=T;Xdb!jG7i[xU>M$K0Ϝofl$5 Tn$OΣ(D;ܛ"T^}oG<1a@cԟPKQ9K˫j+ p|NS9]w܎g%7Y,Q Cm? &Hlp(!׃6@^![?65gBe7䄓'=͠/P?ڞ{`i=1e+P!Í5 rg \Hg (ukؿƗ&i<fːLuôzGJg/sx"G8m "NDet S[ P4 >hbM$d6= =d&| ;]Ueons{~nz>ƲP{x| 3|ǻ˷*?g=NC?5dغ!Na( *m|O{2`:3T *NӊTh&?"L h^6PIXtP:Cu ke}|("hOfEsC8zzlwg;4t G."jDČT4Evev)7Hk M. .U?8 'c?E8'Qw+r|:yz^~*it5)FѤA t۽VH+0,`fJp3XSFߡym.h'&Q?}E2$7~tviVww |hT96}` QjDhH98WHY%}&?C;QXk^弖&,瓇sR Xj!_jň.B*˵&-,9`(et֗ WumM>.Wsb !5ELc.t5+AojhB A %4,@,kHŃѕLdR_n;D(zl?h#pƲ3Y\^rn$_[[Y;VK*C~)?>>B8"QSƍc p}4 蚡[Y`0.;EH+@/',|0(Y{$ 4طId y#UC,K6Pmڣ!6nh֠O],ݧʬl/Xݾ MIm[0P C NfB.0}W>SB  յ+Wq}Hk~Df*{7f vR?\RTYFL$r0`{ %*@Ac1N2tgh V4 A'(K|h K@7WПƆlu_i@WeMhӦC]I}P"!]<$/śR)+m=*cdKz$g!ky~%P-o=ĿWi0LAg7 RCD==?fea|"᧤cL5On : [h,r VNX5&4CʬL? Crb }oO樜.-9=#R2C}*|/ߩ-o 6(3r~JЁEGгS"C v' 47UdTlF}e.ZMC <EW],)3^P!iQI<_8 'T,;oH2'zd~x2ZK9TLn=((x8xPB:ƙ9(3.4dqK-xIf-53Eq+uuh'p<0HwO䞪BuD62 Lٙ΄;6J޶t)]ʶ_|΀ j> ,;fxw}?wǗG~fδ7j1~YZF0|@db*yG3N'9aJixqZTmS-_m>I[ӅfЦfuY`ʼc#qBx"㺡WupK[3^ C8S%v`۬ҙt=hcsrY)6?%|`VCĘҌgeNSGQXԇm>fWCM= #@ޟ0Fj=ȥyfE-meqbTˎf"t|[ta&/ݯ ~[6 ~Fw\FM/@cϷcĜ0= fA(R\QR:̕[b&^Pg̟ kaKX.67n梑Ձ o wEb4tK QPVM"- hOt; Fgd5#oVvM{I0i%MFPBH.s~T*2к`?ڃɂKl13q;M6TB3 =[VkO1 2r:^tX /.SJ/8u,gSQ"ƉbO+MQiu:Ye rјV;.Sj,AwНZΑ;#D - ^z$C2{#uC0R }J]4#’heͧ%u<DDS7}DX]ݩ6),@"7ɕGCJȀ C$%hQO}* TLDY5-).o^ I iFPL$Qpg@iMTybwLӪ5_zލ |FjaOUv{}??^n1:1'$E T~")<'c1v=t2X忓?s&_,H8md7f8E LVo@I%+ԟe7*"(+,bM<с@Vr2>̐),L`sY:=w#fv.%f6Dr `Q6}F4%$Yf׹09`5vڴB_6(JRJ9V-Tt,:Yvw3!^(8:ҝjkOtMǪ27w~eC0`}]HY&Vێ73UW_SVFF/gnwWXF]7FA* #8/U!iFo R_]":i=e;.d!_^¢4RN-xSibNs٨ 9HaLa9Do2`8S3ngD)bv?-8tr̕:> AnP+aXF?TêЭ&u0q52bTv ?'(}0E!>t _M5% ԿXH-y[囏ϿthLXL2E~b*CyJA j|#vFshyQ|4%85*R#0ߩxjtt=[=兢Lad:eH p`N[j? ULnrB&n5K1m]WL.6Su3c 4zsԎ>8V@rIQC8* &~a{@x:YM1 u_Ny[Z>Jo9 *z@t}追=`ȗfhG7zF̬6}KK{Bم,۷OooDYp*]Gӏ+:[΋$׀B#I?6'?6BXԠ%O.F0jN5M8YP;p`W*Z7ITV؟.Eit8M93Р/AurR!*.:mBU/4y[l0܈|(Pe[/ThJj#<44]3`(q_+X. GkAsHĵfme/>|/$hwa\'qUPr#S]v0T<VA["O!L፰R'84!N|*CȞ~4tt4Iu*} UBa@1_#Ԫ#wLVRَ~F3DԨ%o=zi4η5Rɋt/)Rç>oNU :dۣKGpNo}W`1Z0}@j~X\c .( ݌ȍ.Q_L@H7XA.a5OX3^/ ̓#d S`Tg)bhv޼\Z]\"Jk4PڔeP3yrhzMQ[¨j6<,,"z pf:TN>-3VCQ+a@1*ebk jHl=㴦d@x[ XJ3p3Hf^Y?Cr`s[$ C*F﫱:Լ+-c|ʣ:hDuZttgbU7/E. ;XxN{~w4R.E(C{R#WK4Lʢ=zJV?tmBM\!{d(ih?3@EDA!Gfc=a4R!\ @O 28.̓9n2Jf:XCj@T)&ƒbF7D*;\,aU:z*j2?=1|:<@tA S|8OR @5 \b`4"RY?]{d;痏w7ZHFsų@d8D7 ~Y}4 9f5g^]_ SMdJe+&4{@~m&`i@b-L#0L/pCی0Yꄜ<4e *XD{!5ms{)|!`j . kd-SM h;F̏-I 4UU/ZTA!'/@C |>-dYȏJsc12LTkgd| ^KEh˥s| A8˚R~zzk-ݪ"]@]ٱB)V, *8z2Բ"<^ϩX ijNHžBii[ϊ9\GeT3J6 CQ&Op`t 8٘hp#ǂ[J|=7c%9t Aad|(fQ:H#ĚY2V:r 2a9+vOnq:-FWُg2/TȰ3[dnz6%XN ]$QtC8dn dɍ&SLB^9 uJ%[s CHK)CmNn;z0KO#֩ue^g\y zfR;{QPx}Gp& ƔWVJdf2fBS;$T)K8*U#df6VC1t* lF 8}+<1$qtPY7K(29"AW V-RNcD.eCL!,L&#(yjhwz"댝%gl V=.f]Z2EwFsVVS˖JAqHh0$8.ʇNSKZ@>.oeZxq-[(Q=mTF˻H<kGePjB*RtQ"ߋ!Fyjtk7U2 K6İDž2B%5c::ʞ"(#6`QâX͞iA 7Z&ΥK^;z,*Wh6JM\ $Tש+th `M.mB?'KjI LȢHf)m_S:x9q†VLY9IWWQws/8a,9m铂-fx XBz$ y X=ۤK.wI~OeZ:}x*թG>FghE;NVHN8)v z6Ղ@ ݗu3TfOI>"o)j$e_]O)KM=5)2<0XKTwn""&O. C^RB'3 #}n)ՙSN4=|tܐY@Aѯh_ҦDgW{%2:*fXfd6VvU NO+x;XDA8Dz%+ʎ(U q:`=2K0q(ua7onM1~>׍ jd]wnY_&Ą=BL.֩/gH~i -JfCu0~ t]d=6Y,}XPbĆS \ILu5֐Ќm}$|c0VQGNQ~]f͝Ǘw/nP JG}q C`Êgͯ@9.+@t0)NydB:/R:tI O%Qi=)pd}D5i//,C_r73*d,4 :.jd# ?؇#08"*,+gdqх%R\ 6,@)  =S]]z8 4 b,ݸjo`"I`7 _ƕ}>]z7oe~N -uD0: Ւ>o*sZ0*u ~u'ttieY ۱V.L1ZX:S՘"BbjB48A@ŠVAbGgOZGjz7'һ7^?(='/?@K}cOt`Re[ngBf `՟;bB/C%" @yѪbK+ %'ļ."\FL|UQ%){`$ECx!)Uw A]B(k!<-%zG2>b]w<@7[Rx?|QAb}27n6?;cXv< &YZ(7 ?`ZYʑc!V }xʡmf;k}tc@ea|$0`yפq5QQLiMa6ƒI8%՚>06e t1;bv,!G Y$CɄGa.z(*?lc\:j^[Y$o ҃6U^;7+.uGY3b,7^h3ψgiRlئc02ZVZ#)eBwێ_a&of29M?o//OUF꘨Nz?Q,$j>PSc!ªt[pnݛJG b 5ffFS! "nIok `D)=,ZFGHw^ѹSʃ&3Ԁ뒛 |G{n}0VpO!sAm#-m`wSNFUL{V  4W< iTNQgYAl[T$,\'mX}Q(py0hQ:,T.]_.޽|4˧ᄏ|~4˝˳?خB9ETS*I(`s,fc8TדVfƣ9> ~ќՃhVV;+_a3m!<~`V6ĠVu%hTC˧W4th}'/FA '-+6mykTi2P~fg`MyQ! LD P-  [}[u6#IJsF1Ժ(k @?YG En$C8#6*3"L'ZP͖=/0Xo#L L ^:$}66KW96MxI&y7f9!'*آl'U A?P .4^UnA %pA/> 9̨:RGH͖xz\L-%hTIMS,iEv8 Z6>p'BN`%VZg2ifDF\y8TRv(E\+6jlb͵2cGr6,W\%]Ά[[UC-P-yQ}xwW@T|wU˫=UIy/ы"4FJk{^ pƑb( ˶@W/Cx ̔AE4#T4bf L(Hxvn#:x .Ǡxu׽6z[3,KH hDzr]e|~>&fyfM4[M;-+W$ɿ^1 =Hːnpq ɨRX$HR kaΞA d#Al2DJ*>RR&o9O*dK!l:hؙ՛?~Rt7R h64nɓZ~GPOl+Ew:*=`JKAٰ7IQJ +'L#6 pȒ3#a5ƤUCO ZѬ8'vuotGtP /SpU }EUgܺ ?iec )bz 3jr| dY5`>$TcX'O_b%>TTznV^bjr#C&r._!8Wv|`M.nUOtLDA`nQy dȀUS8@OxUFQO:c,~[px"鰨hU+: Dyu~G'GqɖzJJ9`rL-6>`ss !X ;17^OqA0B % gV(3htjRn!_,n|+}kPE3#e /f\`h(XO ^d1Ye-Z:yh<}>@FO>YN 6HD;|gc/lF2ьUXQ /TvQ^ͣLA8GYp]oyZ,gVrjzj L,ܽ~jRK^_6LE4 <kŚJƟ,~ԑö.ۊjMjo- chE |q#m -**|VU@&BRneCcf8&[qD\?d]=qA<J2P FZ t@%1@O_A1R,Ul5*h])_0s)rz(IJ8Z銹Kn.Ǹ^6-^F"4HUyWgG3PVs8dCny^*ɋ$d+48?mQL:"l׊rpப ry DC`|}Ҥ=ͤ|mXr-ۯh"ݢ[WhNW)[큶&x}Nz~{xc YhiWGy’"Y;WEifKd\$` %4w:N9jKL&}\AYՀaFr䅺ʮ* mRN>SVn,8, T~ <ag7 ޱ 9B>#Bxr ބ]Ʊh+ZY5rCd=zw|~׏^*,JwhICZ [ BCazbl" Z A k Dre;*@V8Sg|{<; );JU5@4!~AZI5 L\y28yXku\,1&آ@]y $eTeiJzU;+#$H,(Xҽ[@to8=SQLMBF,^[Y'|=[Nq !`#k FkePdAЇgG l^sbP)GUgO}|} |VJП&ȏLfF 0c$}c^i iK+YM=cC h$ ؘ'@4jxi46(of>|^ 8`~LH@iᲲl.YeltP[O[Nw Qf}AKea(4 wx< WL<#Ns|5T$=6ԀhjA"eO ʝ9{NhKQ[7 +u0骮!=\qUE\d4D0o) ʎ @g{_'*& LQp!̅Jd@ )y5Mv@X:F 00lfAUdwjZMj=Ʉ%Ӓ3 uU"%Т!=!O]?%cFxahʕ/-}&j&C dTI ϴX4ҷ/+?4m*(> dWi$vwlo^,=^?,"U#@ 350M ꢥ9,49k@ΤMH`RVBdcezUِUzj&oW/4ÓC2$B]eOR?iz[†AP4ILmQb=d j-, UievMp2Z,ZAۦb?N x`E`@[A)cNH]915cވAĕ%÷EU#`S6K&' T^uzಒi!hXfcT?,Qnբ yެ|Cө6䓽lݸ]leKP)dnw7ǃ.7<cdfѝ@f=,\b]򨌏ڟ^l|\ce2zw'?| Ht}fX! t@(d4ozFˠU.rӲ -+$"q?D^"Y(Ri<&$1p>B6D~`̊#S,43 D!ke{+b瀕T㶢R{sF:5P BNOByҷ_Uk7g _=h :$T[\`>SK?zAle5sgkjc&+"=1߂BR- _ߡ^q囟?@Le5e2lVV%"wT'-颒])汰V9iV"ȃrz!-. &Eṻ ~a/nv-v#bB={ZhxP8&Ēpyk{*p|Re?VN79L?^b"fߪj"AwLuX$FPf_p7Uz]G >/m(x v5 ttS22bQ$Yu{+1 ;f4oWl/UILO~\Fѧ.Ku7=b ncCL0;3` Rφމ,sYA !T袲JdTH4c1=_rpؕшֆV7ah!x n<3HVa&(f=;tpm#{p IA MabNߡ&+e)@fPҁN]DLM42ʊvfbe'Aj0d4&E>kY~IQYy^ݪR^:PY- xg<5]aw>":èdb Vwo?-ĀzlMrBV:L_jӛs=Gt[Uk@;̈N{RD`{^IE?- vbգ$UZD ߧ-!EM9SO60VB(AP/ %0)Swi)l%[ombtpdⰤe r|5=BN{_CrJ0'teZf/HHBVr*@H8R~:yZxI/H\7Ԫ <#yM0&?ም-(C6),3ԀplfbgP.,ZMA F!oF'X n-4߸3'QxZT~Nrɿm.|o@P[a/y PBQ:[-h V}FJ&2R5o Б|<,tɎOHTD;tQ!((/(Fcy, .zln ύہ݋@Í(nue i6s)׈dB}7M5yc(fc2P0Hb-u0 q{wB_Q8{d1,|>mzx)LAHwp__7/o GPK!D5z/feature_vector_files/small1.amlZ]o6}`%h'۴qZ9SKRv_KYr t-"?ιW7/9#&#KSD&(e?h\PPn t"j$y?>ig'ۡ%"-󡭼}2%YRne5:ZuYf Qi2!AӦJfͧGi%Vuh%Bƥ7tubzh(Y歷E7XۃFyB<ƐRq{,/Q}v+1!jKy 7/;Czqs/5L{BhHm=q[a2Qs´pcbsboJ]Ki5i /}YOj^;p8^ LB -7CtON9ߝx_i[߼Y`fqKcBOK8 (r5l/ꆥĵP\g@ me#e4FPےv6 tEVq҂}l<Ѻo Z[2@ &M1bvbnmKM2uۀj`Cy>ɼ~I}#9ck H [$҉!mFKKp3(%@76 $Kͤ]9e91$BYPH % )m%6ѓWX{F?#|[W)=Ino!-/<&[v&IM}OkY[O<}_7$2;Vxt26}K{ :W2Yle{äz׭$ V$SWK+^B# )x$;tiP.cT"?M |(5B25RC("Q.IZٯV=ODL荄f ;7^@ Z &RbWXx`\ 넟, &#|\ K,dOzØ@+U"x<,+C@G6-+ y6|AΚƏ 2ttfx/<{z?[!tR%K{jP [4 ; Yk>2[';Cq`2 v#0fL ؒ)E &)5ej\wOj^(Y BU6 )M h6p\&]g[ZFA,gxs,A2CAYn)"ͪR@V@$V$YsVz" ooyșCw9tAkpKF6Ya_ 8 MW lB;ܚ"NV lQ́]x^END2\p륐!ZNQ2mh@Q®ݻ_8K<}y>}%XO_=}x|w֍x! [7[,QGPAHF^~MvRkUpU%TԱ5XHVuY%[hǥ'%O ,_<QTax9W#0 Ž@&X+4dK{\cWVjlDՑjpy!44r/p4($jKСQ.yq)hρnf'͆RIb%Ģ]RAcPr9N%F" z KU=87eO\K+!+)RsқKDytu[8bj:O)=7?ݽޟϟϏޟ~|>}|[ XȲթ mGٵoG EBn/|^e(CBg3@Ub1~!?ITHY CR7=eAo 7#c!@)Q6)cA\)In&ӀCN›8vvv58!=П^Zi@'+WZ)yLAX*IyNe'BQ.@R l#`Md%pHhXOeYsdtu+hM[*K0zHp _ '޼]awgU޽pƏO/n82,ܬ^j@I:O:AQ.O:t%ئ}!?ÄI" Yc> )# ()nؗ(!I E+&$ * r&v sksa0TZ(AN馠Vn~8`h3D,MBq 5(R-XTP܄85 AjȠ?jk1k1MZeZ|mΤ6.::KϷh"߮Ȭ ; 5|а{xyz<ǡQ{時Y @;c3h#K-k-+$ҴOu_8,RW;(E6/ne>W6rC霈~JXg':Vu`} !X*(Cj0P-p{5GD_7E|Pn{|"@Cv(7P{[1 Ҥ]wp'єu&`sA6 r$7D@гu,Y>W+ݒDH z-z)$L\Waxx-?=||?B".NQ7MU+lPZ,082]L )>:e(ɬL>mkaԀܦ\h^x1UT۫:'@ =1^FX@q[%I߮WD`R;! _;d<B້*͔ố2@hG9) $WNȗZQ͡<ӝrL)/@zAe$;xy=?>R6UF͔6P%u DVPԨDEub: Ʉ/[rCSRO*}alA]T?ƪ9H}s@;hLR]Vȡ*Q -g+K_9 CF<-\VG'R^[4Pj6[P_>8vfB= 6X K@0d|4UlD!qdHpو*:h_2q魂!a8{WL{4;\dBG,E>ReU<-rZC3 HLi\ iPѮ0hqYmG8QY7r *xOi޹B ͼ,|-u;%1_ L}Zr:xfH'>yPmkp0yA](E\cTR-bkm" `A%+s"b _E^6=¥`11]쪽 q3`"l__op7e5 5DD-}l4K{Mܣ62W""&GHDDӜv|S#G;;ۄku A}]-4I';Fi> h9UVY6fQ%`G|eZ{bQ\rʡ􁼅Ы4z];LČϮ" i'8lnfW x2 IGl=5ZOnC -ç!YmK]؄j't%I|#meq ~zy2Q 1!_[[k v˻?A 9"=O;QeG5eMΤ]ljODjmHM8ڎ"Ʃ9-͑6bV2~s2n f)$݀ 9STl0G1G1Q` !'04ȕQy…* Z^(&OIs'Cx5kE|VT傗JH4] >A C::#"-:)\ v;gOuIIq(ڙخ&2pޘimOz%Z_??޿||sǰw`}_( s,Nah8r|YDls 룚{^ cS5s1=la3w#S1eq UlU˰4U/;A v^=*&{fP#Dl/ίH ȑi%84 D^5*ǡpժ5bamVf{'*}6EPrNjCYY;H)@67G8ìfN7vSY5]}~8*~m޴Oښ?(Y,p_q^뗻wo~9SsGjNW)fxӶgjמY"VXbz ֈUGmyp&4/ӦF{H`]9llQi^_ѡSSw<M7Y۴ E T }qǴ^vKbScx#81yHOmǐa ys :xJp[Kv1(v|qHlC엱AҨeW4Pho^au׻坍7'4$-C)8{RwG􂰀p)s;VF g%|IB]&Ө>}E"KRyPf[É38T˰9H Mve1lclc;K~ڥݕu^ޖq3@֗" 糅.Zz ;`]KBï 5D"UE/! ^(BVm Y|WOOO,(l7%=j-Oû3bm6=a8&ըGf*v劣[n17)/>O_;<>ElOP=}xqFYUvX;i'b66jF>=1LO &^<ІxF(Џvat*KFdR.cpVe74l4OY9[ 45#QR18s.H Ϲ4X m\ΰLU,QwS^E^OLitx@a p=xL2dhFfm}pI75<뛪^| M^5zŠsGkNux=>~:>wO>{|yO?}'G+I6~jP]x &Ԧ>6s}zA7C2bj'phhh.5b/ǘƒ[}Ш]wy\vx)s`784+8$'gVt@6pNXujI >Ǐ<$jtfggHSC~nҜ|4C3"EwxK޳\ "?W;o<^ Ry=ukz>:q=tį~:}=#???PF 㠲0JuK)gq|yt,fUV<{?z\ĕdFS:<6{zj7~-but^ +ei}ПQlvڢ=ϧP= *ҕ'SͣAmJz<>+Ź\nvu֪/8Vm7td8cI o6Nepz"h}isg2^ʎ 2ʥ%*QZu*o#7 r%yv:3X:r@[y>,PO<<ɬn0 OVMt6ndGoY8&xxj@!*D$4=-z_''qs>ܣNyƾzO ћlК};q2&  {G}D_C qٯוSm"\=hk8QqH=+X/:I:J@^*xPY  r yh6`JtQEHɊp^3VO7i D_Mhca#C o]}5mF[=HH- xg*Vp a7d{&::M3~5icAfTCpN"꩔Ɋ8{r~ӛg G/թCjuTҶ+Ƶ#\VRqK15r_nO#\RMh)HV qT#\KR 7ZjoB~oF&RWIVķr"Sw$[b.:Ϩt&&Hd7[1k4xWg^+duΐk`(b0Ii7J?pa]Spf(5EE>Bq cN*R, F䘡pB?j^ oDzLUNW9q8n|ezِa\nŠ_yEyʥo2bVKw+X!.L"GP93aõ*"">_%1^rပgv50W,"+;h'G C1HD)d=eL8YFYQ qFR5b_䶐e}bV-kSGBsVehoKtĝ ΘRSڒO>5|nTPKD5xj4feature_vector_files/small2.datn,u鮪KIŖd@B\ hZE }op tDQ==k]Z^H{)}˧uIiQZꚳ֭TZ꽝XW^\S_+WKu)o}I}6JNxH|~J֭=uUrMmlO{w޸׭l"o<-̋e+%r9~Kҷ+_K?ޗZK_+Th~R➶-mRkSi5>R´z|*Oo /`zωQJYď߹{=6WwG-y/z>5aʥ^˶°:xe4׽{VŦC2ȭvca<-{oBپ͏JkX*icۖ鳏w>?r^O/"\kiuc ;ɮXهKJ'Ls /7>b+0LMxؒq?XD*׶u`SzxOͶouI:A,([N0N~W{̃1tƖZ:}[*ࡀ`Ou)P^[ l[Xv~m?xOO<ǗO?߽ tm97/DcZK~/q? Np (R!]tei%bH,j;ϨKUZXF vSLK _e0)Hn|~ ndCrUI<Ĩ^[T۾ Wj'" $O aJ'+tePiƝٰ%:!Jm1N@o{/;'=²|X ǁk̳ؓ^x{?Ʌ?>As*ck$ML\ƈ(eQV^2d&=XZ _Qzf /h#vC-w/|㇇[sDK@c+)]d-փl^ɮjR#sIIg+!K#F!N"O]^cOFWkgw8} MY|!am`S, 2xٜQoY5Y0 e LfskQIk m+$h6s|1>.$osD+Av?׫QQVjLy:ZeSmFIzrOxbl>S@ 1re&W!{ ¾K32?ەN&7cSnn@ݗ_t 6rowwih;xZr ,Ӷ'"A/%;Di-q P)9~w .mHת]@YDkKF+g{Wc! 3_q6B!݆enE&,F%;pa#Hv G/S;~T&BDgRb÷ :(!`eHc l:|)ZefgƛCMl< ]p&MJߧJLQoNDPE x&nys=p&JԌe-,".N>}Ow/w?ny?j2D;:d#fA'>(>_ʅ6ٹrbXKFn'K77!ϟVDj`'=X՞rsI=t~w)x֑ϓiIEcu%)@:}\*=W1j: m]' $Y40vy~qPk vLOdZaZC$BR z 0BBGCUP0\dN'@+xec֬B1PK TL,&q!fV!C &ަKxۯjRޥ/_~:W>Jw~_ Q ne0h/Q0MC(’N [ФT lp! ̢i.<4叚1aan)d2}Ԥm:ܱdt dG뜀%Z- X atawm9ņ]"FW CDr;>%`4l!Z/,>e4h3 uR8蘁離iA!+7pd{hIPr'a).8Uyen^Eb\(5=_E0z)Hii{wVs_ 5oo4ied_Ч ע3ǵh k/Ted%ɨsUbe&~Z#MB+jU{c[/b0)FQ$`CUN& J`KQq,2JqYӦRH8Ȏ-ji=@ oEejE4R  `ATB@34ۥ$+> (ظtsϏHIw/>޿<~E'Fum&`bD7h(9 Քb٠\ƓƧU|)J*KoQ2YźOu(Z־NjYXv-z9B -w(q#ŬN||Hi&Chn<*"^ ňহ9q H?.hۑIEں)4á X G.Ͱ'H y= S( _Jd`,;"6CA3&ڵzvS} <7QWt`7#dM\bnߎ&+gczd?Axx]Zͱub9z Y,oFÛs#~E( ,w}9i(3Mعs`I#v`$7,vudESI%PJ؂5,j k:f6$<ՃY )gM;2%Àŭ1nMMUrTT@Ks8@O46B?8sY>A9DŦn>dub@y#KC*ǭf,W2y(kPmPQcXE}i@'Z"X7E xcDd!i4ծEѿ]&M0NHV>?*Ezuht btvٛnA .Ro@D4 N:FjM׮ "r-az&NEIL@3"yQQY 446 fE BlYZ h|QIۡٱ]Y:Cu< da/*XPfN(8iZ=x,",[3-끃`κ !E؈ݦ#3k2ۏ^~6v=C:.()6"A۸A^#?6.?9ߴ/n/|oOٛH-6x`ݞ8{|Bu&0]/KjU3^.lʤTHVv֣HG9AKQ@ d9ݟy'縨ݬ!sT. yDͱ8b'"; sPPm_ RX5`d0Kt{XN8TCjgdhƺXbug,m\ Gaٌr':2@hy_*fVR^rnM =1s'\n1sa,a5Bim8]B͟pg}W#U"b?=]lС'pG~ج;tr lvIkk\Y =S/QU`o7l.o^>ܝ~ǻw%?߿y[ZK؛F`R\"J)ANPoBVpLj%B(b@pƞ<>{"'p`p=Kg M8(V7#E+kWoZ<ZDz 0䝞[ 6dnh +`sXEDݒ"Kj٪ *;+cbk'{ρjzԮO?4Fqó#C  FXO< FIQ#=Jĝ[YjeoU޽F^nDx8.Q:uP-lA.%GSnmŁ@2"EgH6Y-`*blfg '+G┰GrG,L>)S #:0,NXt=xY+CDi,U6͓>6Vbx@_CWd~-1Ke35 b2\m칁-v,{y{Gq驞~xٴNAPKD5gWy,јW{%"%ʡ}DȰlDٵ*Z=2\&x"tڇ%wwq͉E6X`(AYF , X˩;4SN׺b,Eu02m(QmBMԞ0X;77QF /po;/ՉVmPSS݋ 8rmUd n< 5 ׹qm5Qϼkf_A5D K@$rC[)ݐ9&p;!UX2˶+´m+G6(b 5r-v)vbZ- jk [FK-7vjk2۪-yAtgE\h) 2;jGK1G?* \J:4)ߙ5gp{OsQ.HkƴJa"r3fpHt:fvXn)˕^==>Ipe)[ƔpHe霪ifDIZ崚 Q|ۻ N3dP2+T#&J*uN \KהN,Ř%i~]uVRg˥֣j/tu}i>CFyK?r?5PKD5;4feature_vector_files/small3.datے\UvEľ_i&엌j)*(D=>YYtMEsY{9Z{)lCKLeRGur(kLÜ[PH9՜c̥Fe9 irیqFp=wױ{˽^z9Zkg)C Jemz,!-rC?,DeJMϑtb#f>:V4 E@zR`!oJdg 0%Ed9rHR:OBTc?aC\O:;/kT*oyi#w>?}z{xQ?rq13Amk h,t[`~$$6,F] ʊ֐4KzqCY]#8%+•gdv ߅NpP/%$/"ebIi r͎קO{3= /޽o_rO^ڣ`rNψ6ZʪADk#5͜:oLPw ""kK}IKCFW*}#9r|]@^!*6v(r? aF0mOD"tDVeD>&E>WdC%0ԧS@Ƿ?;~}tz2"ZBAr[:@KNCA0BŪ OBR}f 9 .pn  #:Ϋx8 (7dj3ƒ"+,m˨p9MF)bTZ'~ʾIUF9٠@ |W}hu} \aD}.h1<~!UG, SFc6apExi. MB Ѕ՘I^5APRd^A\A|(͝.wQZt2xSXg3o_<@tg|?NE] QuA fn 4+s 2Ƹ֨Y/!/3gA2`aBj`ntu0؟'D }2<]oY#ߥa-XrdNDmYlBCяd@XÜl(0{&jO r%r aVc9!N{u"KlPצcjrs7%6ls<rqCM ۾r'?N>cM"6X 6 #pslnw9s|hci7+fwހ@?<xx :F)"B@PH":gؠ@(lWM)-bNICD>T- ,uݠ%5.V8AjAzUTdSs*L^Lp8Chм\*ZUYujxdH;_\_ aK9_%ij!IWa/.V(C4 CRvJIX^3{aQ D9OS)y{>2>'N/7S`T1?_Eï?_o?(uKibSXC} @+u:;mpwxYh! 5p>O"<ց;XJhA5DDx]!>i3 +R3f;$4C>PLMת|!xA7^(,kTv0ϡ/iX0Tւۃ K5&Cϡv#_v Ta@m q3dSH5Q6;d zoULzdS]N_ֻt,ZxД#sqUqd Xvy'O;z;o a߆ΓP iZkidJkUqIn2:1@NHI+KKʩ tdjsK޸ v rJ.XGeETA -So -:n&Cq*X@Hk!P̴!SKhbt~~*!H-"ФHQ3v͠nmm?Ѯy3nK}Y jGcx.@2Ա| N@8޻ "$75udY O5ܑt^ )ʛ# zFۡbؙ\N' ͇>>}&_ߟO>iLo(&e&.0y̋\A6D5g-3 ZަP(R?R`RԒ~f8Hv:Uޫ{l8 R[fM$Bp'aAstZD֔ĨiۉPI5hvvbfk;3D$J,B0Čx0Uy b$}ѵondM&b@nQoo A&=6 ڹ^;NEncYlҐat:={ҍԫ_wzSsTF-pJگ:~Xx:_RoEAݩöFT5f\+#%F<^P BPpB2ud3>-l۾g[uI2oZAq/gmڰ]l*G j;Ŧhec%& Cs:dN7}E%h4 v.tk([Daf* 5b3ξLZt+|;sqn)7/E4;ğiA.:xڦU튽$sF#/+ܳ[tm4`!wZB|DpJSwOy?IW5 D'F/ݭE0tϢWtV@Ob?$_Ƭ[i>%pj!CJOc_u:#(|m?)3|4MTB+ˣa t?n.24giFH1cNJvp@ 6i"RvI b!%$I@}:Onu s“(rжU 3g4`[R )^ [$ .W}x8RRږtTP(Kv5Coaz3vl+= ^ܜקLJ7/Orϗ5>>.8'o aC}j]n[NC 2b{Z%RZ=')tGk?S9$8QWSI4`w0B]vdw=:E~XqRAoaF[[N[ {e 6w7;l6q.'w]ܼoϬJswDQ?v*b 0/7z[ǷAqcNdt;Ǜ8jik~oY3(I\ wKՔ}|̌y "^Ba*l^:L2ԥ0\DHpRwTm&L}o5,k#X݆f:"yJKE[2یXZbMI,%,EYLڵ}giUFϧsaaܛ}Ӆ@rsduDY.'(;Ӂ4|g@ـ29g)q y%SÚ%7DB_A'Ч^Nݎ/d|Vjrp,?c(nm;Ѷ1/x?~8~:~G_Nq{xR:@ YA JQ2cp~$w:ԾCT c~lk_?L'>nm+lwDkM"R;#iC. 6NMuljaqڪ_ҽv# >/"QEo*@v6M[ʀo/Vܦn*ǾK+r<Jw;<%DX2_5pK4yF3Pwzn=I׭s^A{ llM\=,R'5l_roB)}>>L SE_=jݛERiJ8=Ґ,2%F\WŁA`P ŊG݊)xc1@noLBlvj \4E]댐5>W%3{My=0%-OnAu>m"j ^Db*X?šF,:jmbjr*WQ/\Ï*hٖڑPrXק$@Hj'ɷ߭e$6d՝:"n2yRf=O&˂D|mQGtv VNP] :OٓI&%#,d`~d2pDe8stoǏ/fG4vXo@lvI4ځ!w^("̻-u^Fdyx$*QNm5lV5,,ob1Et&%zνdAG7J}npxƍt^> 1ꉮcw5߾N.9oQI+HgA@uY);.)mU3_eO=S%,_Eds2Ke=v,I"vt>;a<^7e~vKuR;VS)R]Bk㫏OքO p>is"yY1}m޴mRt٭t٣w>A7.ۡgrMi;8,ZЉqjylģT NXt)Qrg5^ Xϐ4,ӝ̗j,VƂH(mI %uN/K<\{[Ni, Iq7Np_0Iܞ1!ܠϦ;3#Po{\zG\9b'H%Bl~NPYDh݇xy }Tкtc_,:7hexݜ[|T2M/ޝ>y~w<}yjC1 dItg$5Q3̫Qi ꡹mOh: UZ=}jr~iNo$iQ`_+m}eb wZ[݁iaD[RW6M(l_U΅4 zB۞?PA2oڙ&+vަ"xms;O+pnCMԲ!scV^>$zpksf /]|Oupd¼h.d0S ?ӧUۧOIS?[NMͧ 7V>ZpƇGxu>Sa|u7G('MZelW>׿S4[u+w%">[_vQb%sv$-/:g녮0NU8Yb(M{ǽ띭woeΈnoUgۉeg[yt9#wóԽǿfl|+}v[!XrIyG+@~ĒʒFI?/b|/zsS)j >8x.8xW97w!u{:_p]H;_e޴߇3!̵@}H;s-y\ tއ3!|@%2Sw. 7Jav/0&Y$8|Rݶ,R_W(hWïQ0*=_!DM0>ޞ~!qR왞u3Wzf^\Q8_]=_ջ<__jҧiy;]<_MMQ?1/5[Þ{AMN*?6z+竐>TrWl?UYH ʴC%sBU0R_ǂq:9_)q|0+ ? |uXޡ9Z̏FbFOI9"D ǟHb8;>G=*~ [G~K3&.JSaZ96>ҤK.mtҥK.} 2j4tiҥE6]:t&ڼQ%)e)6 shT wBf+H]KH-G 7Rr&I['R8=ʁe `?5Hv%U*9R*vO K$4g"Cfr\ŷ͆ Tm;WGa"hޱMiup L>s|(4=В 9wyJTeJ/;4ۯbZީ" yĢfGy ;4!sGU+cuS!Af6k=\(`:M :rkO >K!m Yâiq+b(8rW$cϼAH jH#.8E WUz/L2=2`9څ56CUo=6FVp.1mMW!$7S$^flB)5Dnp7%8e"JU1r8~f mštÇ9]yEl&=}+Mg ]da^#v_a#s\]XV{ uv1yOrE? Hq9}v(E̞J!//-6_ww*˷>gs;$BHRD׾'D[̿CtwK<ӈPs!d6 {%?SjƗNG^ "HGu-.]lY|Gds>#qJ]tYاWuF#Lt_g~I0 i##6:(P8 Pqٚhsh~ewuu8*㕨6#":M-74t\mQQ^FbOȨۮJe}-AԐ㉜6 YHVPt`Tt@Q4b8w)_f$2ؠ+LTtGLYIQ~]ml;|Vw`=c? mݑa}35 5k?QA9؊K;4;Bmkk6HzJ uk{OcV^1?CG8k}-ɘf)N=v %}뮠E\KYJEuRhpW{Fz.-- OEX~ZWBtQXg^ lo((2IHST׻cI*D01F=Pf)ָ:V[}v$E-jOuTh34_ߒR0)} ;Rv7w Q(=B)/RbHBFE@Y[0b5tSA+o[gyѼ]?l J جԠ=_f;z(@[;G6|$4NZ8iTQLH(q5nas= 0X7z-7{CGƥ]YFBT57އ5 z=V'53xDj(4{T6; 69cW1 C^jmblG4j[NjZ ?9ǥGydh9w`M5F|T@ ;zg ASq.&Su ͳBA&-. }3W;<қ4 kQ>J+hGꎚ])X}iRo!ߚ_3{t1:\I]oaO3Ԕ.z)-r[ G CƼ2u0Ev0$tמef)p+ch.5j LO^zv39m>:3?szS#K[ݥ3/_++77_XN8p5W[ &Mvx0?R o ė&;ydZLx4M95MW{f mJ~WGv¯qؽ.<xER[8GsEGo3p.M t 8dQM-s.)ke;m/k,̅j Ȋ5G^m䮿Gڂ)3k.=80)vgBE4k:a:Cd `I9Dc[p]h%NwnM 3m?c"9{`"S:XP8m[J8b*%- gyO$L. TZ]ptFK۠F- Ϝ<bh-_JkkSLsi @5 ;5M 64U?mjiSL}G,(,9+[G*f^AcKF1_tX.k+iOZ@bq:\J )iXu|k]፴#2!2^l-8yeXGX,}_r0sv:!/ Lp/>C-_b54 Y-A!5TLȴ-Jl ΰL+]<\b4KkF&qe}ӞI0mA\beu~dMg.}+?2 إp4),Pn>#@Nh,_J*\÷ۯ(aPoе]RM>JǂO>^ W\n5BJPr6gvZ"4.ELDLA)V@W[P$/8;7+HP/s>:۽ 2[ Wvwā ]X0 g."FӨVZP$G@;:e{` PF~M!K{)Ñ]ښQ4c~ (7ckQ|Ee т#]7}!h6~ {% 3ê#mH$\;.L`H.zLDɘ܊ƈܐ/?d#iUNe j &LD;5t-'nt=ӮnƘo-Km@hS![ /q5sMteD1Bl:O.xKgR@#=/~@1M ށ Ix-O?'E2yЪHQGm?xE@#̵m,}&2\t2jVN>liQ“rj&1hR'J0|Rɫ@T, ʴ1,VKi Mq˱VUo<-9~Ƴd54jv:0^hvǣHœyBj83ˀf菙BGP>9ԭfkqlM˼Ɍ󛅽y7#vˌ3rG44/[nY|o~k̘;%n%U$B"(B$3 6~ Tfp?Ƿ͛Ls:v@rڢžںb(!I L@ufIΆ>]b~|vߟb1`B!ܩ6o$|Ao蟒dTv&j25!-3 jr'ŷ~h5!i|s.|"i@i`-98C& b["/*ֺ' H OX >(]Ҝpʋ98ZOkw,BPʠ?aD }@04ڍJc6iO Y%vwDž (aecST- mGPH{ =PhRNy|oorH˗4:h$3n)/:b/)Xv{"A\10l mm[Ru--O@ P*1t"3PaXt 3Zi2}r6@A!b` R2m)+FeDUd䯿;6>;½ik;?AXs1 w6@+.wChc5Zhͱֆ32_qÚ ؍h:)d[8 O8'ZN2 8o"uƏBMoDː-IIRNq1 35aͱWઈh9 qb Df"6Vfib7;i!w:=$?wո0A瓃jSK|d [!;ق^GW~k\bՑWwbOqמ8'D#N ;}S:?q"Z$#;I{TS_4Os! pQ ͋ ciTet:z`!hidFD)q!"k>7e ,!+M4MP]O6鷛L k  l(g>cMM|]iDӀ/۝-l{DXĆΧTf˺궺:8Eq22?e -1.CH&ajL݋k>r>cq9?.ő!8Hb!: TU^uaƕ8a' D?u8 ^0hdlOL;B$cR$j{5V1JWN*&ݎp Evα c;%?r釮yp9$- O0|+ϱIbGF` ZHdtpF]𝄈U3BvzE)aLZ:2?'գ1]ȃjcftDBǘb֣gU>ՈC4zLe0zZ@`_XѲ#5q|j2sᅲч>[բZA9,ekNfY =TfP-,E=ԏƸp.],3 dE$4%&!I0~w.!$пe?pBHa `H(TT՟TIt˴-sE(T$4SsӮʎ{ZGn3~$u)C֨ ϡm`oJ-5$3A 0gyk31HHB%ѰX895^c߸||@2"d32FpGE>X :67\bx&ODԆ{J7MPalf T忴ԗbornJw!Nƪ<KR A]Ta<-%r,"MTH!8K*g6WH%dcDC2_ wQ̲ӽ̒LN!}}E2Tꍛ2X+(O@&HTI}[,.&3aمmm`;Wm} h1~XͱT!}8X1#>̞ZADhx{nD'jvoTM%>UWjc4`{H= heF Jpn<5 F MQ<iqnl(oIyU,c C(}|q.:.bQԡdH.gFlڍiBV񈩼FdEh- 4ubd%I%\et?Ry"s-'ir[1*ǐ+N`[#d6s;㙳Ow6%D FRRO0hp[.j"%$UyD0bwYN_4F:Dͻ ~2Dߺ3ƻ#%I~KIj||ڽ2߸V<0NcܓJ+ݷ}zjfmH*|zwHeg}3ϩ &I9f^E eW2{X4hOYO m':$314`&win2GR LhUCof[ ̜*{>6ݦu/{ `V>e6iMϑ4A)}! ?taH{qR$ ǚ**R1Y4*\虉c?ܷx옢V*n==7.6\%cG@\Nl ޘ##7}RQ:6,|FV P%8L$[1 5bX&ME`D;p )3LzL9i"${4v.B8#ҥU3|4 IuR$1P}3E.g;F>\Wu^-'a ̟h17]Wb*fѺ< (AP&?0MaL /<,-:C:.A߂c "p؂Zr8.>36'jh @)c2!9޽m_|u}֛tFc -+QN"pM7פ3YӬ4oNAFtƯ܅cte(6ΌZ3A |H*Jٷp1{L\Ct3^rfb[*.4iS rLl% ':r,Ҏk@ I2&Ȥ&D &\M=!JUjQ . L8[0ا{kbNhEjZHsV]YOL%@I]5Xf+rI> 8[2@zQ,$@3[ HXfBeCde-! 8? l7(i+_:kV困.NVVkFG)F]ӒB;5Wz)J;eަݬZ D[ PaU:m!#ل|-,co=g+7t*C%o>ֵ x^?|Чc6eTݥM> (a]_u^[J,^Ȏ%Zڛ[CeڼD_^0Mf 9:Tk:h^[yNF;j_r΋tɟR5ҷ=w_ו|ѶBf_ū/ymԕL=0X?ײ_1a7l՗^sti4}|wbY[hc섆 Oy^AѪ׵_sj}K'ú٧0Su6=п Џ&;e5Bh: OyИ[j-ixu}[lCh]ݕ59b;~lơ>eyS^(J*T0n_m Mb%BBMoŶ%͎P? j$@r\\!\/Ij_j\P/h9[\̟(!Y/u<2񢡡@[Y8*7/.[B[{|yZPܻk#j_p|I'uN<-MQbzg vHK#$?p\9;ʬ`] ?ah<^x-g)v9D%%#S4y!K[(|ZT[@@YJVdpL}a֯Y5ocMZ"?<:MQG"N/j,zS mZQ7e<ͳ!W!}_lPΥ@%Du7N|ͽy#{*W"+4R\TjنS:EQ[dOd5 ,> CSHߪV;zW'M#ףIf:}`>DXESúqef5L+(Kt;|onu͈+ѵ4OWlXy7nn[h3['46 єj_;aЌ46>[.qIUeurw}'GQ_7g1_FL\<*܎پ__Uلmщ,Y+AMe@e7v,r 7Ӆ"uAH $Be%#$}bh;LvQP4IiTdA#1" |+4zQƱi3mze5N2=(u[duc{hU!§$Px>$rdW8!:1az@^ج#- ~}EĢG f+`,E"_LXiw< / n"GaԜ- q3ټZZf2] \ aD1@/vC[_b:!ʨ"GVq%(iT?(b&'|Z|nԕMp{L9*{LqQ7nbA<5>MYwZ%^K4?5s\x ` ӋJ )$>.Qj.P(JpgRДke$%=H?u]-Bssvg}|jt3{up!2? oU <hTc*<\8lN4 5P@ݕ>KG^0훵 络p Y'[CBw:HZx niO $:A6xᗒ?!xJ2<)),B0A2ע '@[+aV`ڤTFP{#ȂҐ8F3˽ą*NxԱeG\VjpnG/Mp24'!I2}u$i&8?ӠtD^=Y+*/ѷ@QG'`XGcelHakǿá/nn*4M۹Q/ς\JC_kd8@w B@Obŋ#l-&^Q"=yOxM9&nhdt@Qօ޶ޚOF@"{d s@|}=4O/R=a/y# ~'V+ ~ JXrEPB PSёesJtCD@;]f)q{*Fe`MKꐵq?*Ym:XNsz^E:D vDXBaQLNƒw)#W<ÄAG MF^>Lw3;mѳoJ$)*~s>Y2# S,l&\ݶnp6fwmȗ 9$^9(מOz6L P#Z%ܨD3.\) P(/"oUs?iA@mۜ|x!fOQhtrS\ű$z)l̩5. ?J }BQATe>,D+σ΋iC&Ʋ' ;ZNzh'6O3xT~3N9eA ySdhjYm(<Ni~')>z+\;lJCE5iƅԍz^aA;+n::xo 䘀!a2Gy g7۽|"6r6T=Fla o1wԗl Jǥ/i8[_EUlH/L9 XR8^Ǣ#oG:l2v9::<%:&v̎{]!̭nMU {-xY o޳_:p]- z{(1KKJ dH-ɫ_|'6rCh=oLGP૴;]*miȪMkr{MzeY.:.~(6Œ?> Tz?'k}|fwd8B?SFbk]Ƚ҇M{y=ER&' vd„p&y)bѼ9ljn?[{- xEFΝ%;!wB$9h^E2m{~~Pe班/=qAƯ挦V EWx(~(+edR+ۼCu]="o2;J.ULC-tٍl`(=’z#RsXӮ=C&qV9D{^u//V~%dchKUoS-Jxm4A?柟Bu yy$R?-ggwՔcŻ|q sh-*+GY}5ݻgaf=1/9;/[_ѕ7PNò6#w/{lS`H6}I0 K 6K%tdAĻD=?cp5#1?hE>ną1X.47e6;7n (xM|pʨ[lWRpv /~; Oio^W򯔱¸(+G&O}HGpgw5z<=jK//1e'̯fhKTaC./1+cZ~(mʶ(CzB`i;WN1ݡ?\c3.%.yˤc{c"u-_$0p!rvpsjQijSl:pЂQjv7hZjS˝9r[߁f:&IB1|s&Lϸpz-)E;ٳ8p1-SrH޵6 A&6؇ hߖx8@ B6a[0L=vL:ns 9M,fr̈]y\[3E%Nr-}]JM_@uqat҃uO*OlLO6_nS *^h/P4 h{4R/WMWlYA F48#痲>cu ޹%aiM crX^.>L7:1bpeH-N[3=<9)y,PokqNw_"x^+ٚSZm0 *X̟7{ /(YEiSP͒oXA]#j8EfG wM4;lzijkYx0HnE~V p`˃"gZWs&w$7~J^O|3F-pi4<߲Uz r=gW08: `mX*:O{O%4<;h !{^Wh$;71?oB]oj\[YkpAUs>`OF~^0n_ @B_&0+ ~\3\(Zhma팉u3z˅3 4+`߅;GHvm$+vx֝BSfEg]_7%kx*f|M=rCx zV~5i"[ehrҭ(s8(&\XVv'"bσvc߶kx/AQN%]]Z`m,tdg0'2s|v~PݎRf<=gY&i|5!M΀N)K2s"ZEF7܈iz{rֳ'K䥱^ yR!~_2b)hefm Ti Jen0&Vs5tk s4:Bfj]Fhvg}DdI#s1<C "jsoJa9M~}s Z=2?_!%'BM]X?b,b! Ip8QO{UG#/-SUbsNcg16㿕H_ \u!@-xFg"C?ɟqA| +]:0䚮n.ov=-{9TX9ۼ6([ CxAa_Kylw-9#'& nӉi)/b͈RKJL|w!u [ŨymW^՛KO"^U>C2}~O )"&(dXX ZtdWi|4? !9x[unG=z"H_7'6W\W>֘"TG*lXѷ^Pa^3Ʈ@F%ĵrY:J"M|?Ǎq`zEMѷvύ/.Eс jr^$!yQ#U$wl5T9fUse-Ƃ?c;|_6W,uYƘ4e-Ƹ,W<~wdp>;>w/:s$tm/K_s bTr{ K9.Ȏ>sֲm1a7 +WX tp{"KMO<#Vm.;|v_#uJ!.p[%;t"ّSWcxҪq&h? 46f 6s`o@|rV![f34H@e 3egg)2*_@L4~ x\.AjE $PffUdd\>" @j9ϜFf^N`?B9 F hN'P i.Y ʬEBN#PÇ fa HY ;CB6͹qxsq#Wwܫ֫@],kKz8Hl{o+.?gY Shjӡ/|hQHkG5&Pܘ1f΍̺zXh6/r3L8B+~&Jlgn6L gu9r#Ǫ\εěux"\~@ٛS HAm㸆 5!1Ef1\[0NKǙIx?m MQ[ |IC󠀁r@' ORG7.hq.A~ {3>m(қ׃XBu-y?t}]\UoKt6o&C|~q+F#_U'M=QһjA:i6B8K5ޅ1^ɫQhx'_>3~zyn&׆zKS^sR֘q„ 7gYWF E2wׁ:LdGC?j_آ.uf9Ȗ&4Dw!9E%2M\vՙ(vmAֽKV:njQ݋~l=5]DROJcBc#q!Qjc(n5)Wj"R]ٌW# quwk,aյ`%=;Q[!-(0 Yܒ~[tعcͨ &""@jB3xQ{AWGf&񂋷{3Pq]p|hLX.V[a_I=~\60a[\I}KO;93C-T#"X'oS Gb?_UӱŽ [CɣrO|;Sٿ#`Y;ˑ#i6BqK 3HMjf,MX)= wgUw{W{gUIo 0܆ o-윦YP=W{*$޹aЧ" e%y*d~ fR){CW5!hapvk60~tg `uaӃvGƭAp` . -, 7чRo:lK{G}TD=Eb 8u*d?r^,#gNfVi f̕\opPW> mj6JЛ.65BJ#n0ɼT| PV|o#8Bwe&i~X-h܂~ng͂1a!9ݶWH s#Kh;aG{EQQrv BHY2'xa޹at^;;іV]ytLuG&H8_`SDA/^;WgVDs Ld?,+3.}dQXЦČP+lq˫gxõ@j{hKs&K( oBUv %&}8'rWWٗ/=XC*oת4ܼ\S AvX0BYSQ05ߘytFQ~Qz}kc!tS uy4VH9)|y .@H'ejD6 vd`7t̤Cq ^׷f wI %*M:r->e9f7GVL4b 3 PfkFaܸܬn?]z߀Q0oX[8!Z)=ƒLY! ]d=8ά/<+taرXں+ {@-jib"Q `QL^wn"0&wU&n^$ᓯHIY q9IX akÖyÂaqvřB$Co m c;\̘"&ϱ\$#~[͵청mߣ-Y%wZi 55 M5UŸ4%Z\v"kG;ٴQjerF{qGz(ڄ45FeMw{&6mظ;p#F9A Chq2@Q'E}5;^Cm=bU[ `#f;8Ż{?EOszv}AXJ&CHrB:جw7t6A9:{ld?g256cW@mV Qj:^n7#(pU:UM"ԅaZU0o\Ȧ0B}|~Z n0WQ'ا ɞ_E<f_14AxrkiD38?C+OtIy8d/qn>o_N~'z'PKxE5 Gbsfeature_vector_files/large.datْ׵JfvqY$$D4P\7i%$z㟏MH}(deeeF9Zwy[)cjKkҖe: yhI-TX9Var|ΐq4/sg׮˜OӔK͵JvjMN0NCrKq:y*M?T42 XriS:Mg=uy(z#MzpRҐyyy<)5KeJJzVki)s'aZߡTƦ/s۹Y)͵we6d]oNyZ+/ef]qүӔT]qlWJC2O_Ninei9c<~yR']ֽ%eZ\Oy8ynm[XJn^l.˒4ja@~NM?{&]و ax|<2ǖe2w>__?t/._///{KcĽy Yez 21ae[eƒäMy{zRm2ZK讎95Ir2ML1nzi3qd_9}EM3ʞg߻>iB:`>/e ZO%K';1̉9<'݄"΃^$5;kezߵMm9gdnTtU޾ņUdUu:0 Âȯ~^>.kut&y$37˥R>-&Au1'ʢt_FY̼~pe{䋹: uCghɨetv-rK9zIӟgʲZyFDuPfs7W?"C㞱2J}2}0*Outu. l5ssUj:$SǚbK*2TȧI?Ytg\YFT1t.bƤ7Z/`'<".Š\PAq[,bfS&#r i2ݿ7?_{MܼRt'}TYh&G=*VauzT&"Bpun\sdc0*͟Iw0& DRiN[I ީ.n:w!T$:r:dr͇V[}GOAoI[e%" HW#ˬܮGj6Y7oFSmt,X(H*mL:&B,8)[/[&uy_o>׬M^B*tP6xw/6g-Υ ̓8&\yC޶<bԬp/c5Sg.qI[Ώ_Y~&sMvG Vtzg ;Ɂux'z?2*/4^r!4d'4rYdimd: sq"'oRBU)<rugOx(OjDž`U4y b%%r݁[w AM|7]!s[bB۟dzV/O^\~{^Y?\>^(8U]rY?lN/umwVlI%j 82E1GV(Xz)i9;fdm71z =uFM J?H0e wz}EA\Y K:*,U -|k%}DT\.\+ՕԍmU 9_ҊȞzVS|nRV./3 2% :'ɲ5QH.wK$y꽐t Rς5f9JBʔ꽧1@})V.b:J BnV+!ߒˉ[SDe9d]Uʺ H1ۇVէҷ t._AǏ%{#'0tR}dFPNI( n ƤG4S?:P%!KNa$Z̔DVUNz#kP +ӱ_w{8s֧~d~ߎY2!P-cPNԨ H3:NDoh!(T2UGa]LT?ԩT(Hm9L!889eTz{aE/߭LG7U`O&,v SPLuЍU,Sh8ڮ:Dyi,WiZ"D{B,KϬЬ#nӚ}`Pyh9q鮉"+ez?>E*O $MJ(}82U94YG]TT{GTXrܬ=ED91{#L[2_OQH8W.OX_?~|s/_=OG.R9HԭJ̩]g͙e8=ْ)2-w#EWB_<@YސN,kOOQI.utG*~;A xY%J۔Vc &7*ʑOƏ\|E'ᛨ&ڜn.RiPQRBrJ]I^W4Sa5t7*8)ZLwL3|ͤh:YۭJMf/VX^MWp;'$. sbg]CmnJU>P$9F@:EQ);3o?|EbJ)a|dj=w)"f2֞ ,L ȎH^ODfzSze-tUu4kPɠqjiԼN\'d))t (9fǏKd4(5`A+潶U*"7WWO!P-8\rty}n{QOl.ST~9E\le7JHKT3WODt"uhrz̈́O:c:ݩ}rL]4qG>ZQ^<7eNE9UIrBU>y cѐ MvUxdRٱoĚ&D8T[ TlmvN3aH7FP;)O*8L挧NBILf~JRR[AD>ŘFڥH+g̦ܬP^e4jQs&0ȎDem !FV7Y22P9T Da_'҂on~ߎ2JhduQ;!*+3䃉mv|etBmR S.ySR4V0tt@)I^ W@]Oeer# =D7*0[E2޺L %#(}>A)>IuRq+Aޮr l7YB;'-]u\bA{ck=WSe0-J%P*@W)?Y/cnIIvD' >Dx@٪:' 1a=*υlE)xL4%\\9P`*{?ڎOQ8Ύ/}__M>273[=&2?G^bfq@}tJyK!\/YN8*2U\_ (T*(00|RP&-9?Nփqz K`bP6&"7. ~ńPrU)@/DɥKwXI7][V۫ I\I-*D8\§ʐI`3Y;,0qu@uEJdS!GA>(cc_OK+Ve$? {тg^BF#@+֋O\HJO0cz zoNd~ƇL `>,p,(`8[W.t&\ p d qFHO9SɊbNlȨE0͐Bc!rc;mx_>B*d Cm]4-.eSJ"k>3-=Q킶$]lLwwrG=Ż;k,ɵ+(qw[wf H!tF^r,N%t-LtYð kbU$d:Th׶n)闢>3i5s[FS6FaJ)qN}dzcVRj$Lfwd hIc4\JeHʆ޸m\Yu5+ NTG>{pTex/:e6[%DWPK6;JS9*EyYΜ*>2I hTt*.ޕ?27/d!4(H:z(0IjiSdPfʜr_?Y쐙eE皀BE'Hln\e}Vחz*aun i"ncczO7A`&4ЇTΪBy(|tlu|w/޽{ç>͎Oo?^yZ`3/Ez73ᴟK6V 0&4_.'30\R,/t8gFufF._v` @RNj=l0HOG/}Ԑ  !(c,Dk?Sxk:qcLqÚY̡Eh3J" ʗ!6[RCo@qID vKuMKȮ㍫Q..#h7l !smΝ 3s^۶J38օ2lW>I.cۼu&e%ܳى.oƞ<iI|3#ٟ"9fp|kdwװm;ƥr hƑolFA0ƴ& Sul  !C!R Kʠ68@'rJ1PQ`gƄwQYXOśBF3"$)25:PHQ &:xth k?K/ 鍌ʘ]5d+[cĔ!uu,ds׆uigS]zEdg]K,)R0iҍ\@%s F.'Af\G=mV%Xp@[mH\ty}7o?<|/wK06T [M4U]0Q/Tr *=!i5F DoI5Wf4V{ROŵM 9ܸ#\ 6H'[8&մ HU| eԝ*9 ldNϞۙvU%ccp cgB{W}##fPH1aF%Z^7̟TЍ [MPfaD_11R;h eճGN,<#Z\{˔{1h"u(,+#2$xz|X=?#33c3ߖԄdM)AI (1ͰH!\:UA [Pp6vJ]BNθ$j"fj:  mgzg]"{€ny-7Gݬz[v=Đa wCpooϐ4Ԃ/}C&@R碴9OWg| kE%n7q%qc Ռ #;.'gKpfNҨZte+Al?uc2kA* 3LHnZNi6B xP7D@[ 'Aт=Ev΄ưfk />!&ѲeDR#NtI՝ ȖuIugOTTT?Arn"oB @ `"K1[ ^`N[lxY96r+n74?>C󰃍˛#_zD| `c}3Ο"p˟1B@WVH0D3[k wuA:'1GW$Q}z&TL =c. udKT,$t$\|.3f&藀ʘNI<)7De @Ŋ xe.3 j #np*o [q@>:vF* }}FdU[@'2=r> 3<&:ڏEY F4j"ljmXO{2'ֶ1\It(h8R Smw3Eh}=X \9m}wjz- }}/?1z{wyݞ*́ş"c'rdD`)-1!O3ٻTgк)_F/2V|!Uk=Y(5SP!`5gTQDgU0h4h#C 7E1ϥeHKeVgʱGjGt(F\6-첦 Ls:z p@4XJbOiwhϲ9*LB\ڍfcH#(uʹf\`Ci"2MQ? -R: J"Un +Gk=Fa:c Cc6$Δ'$~w]ݿ}wwB |řgiE6(`Zk0s`3VV`BC8HUy a᷎c31AG7O6+ў.k8t62#Lϻ#f:]d$Z lU [x9:E $fm *`3Dٓm2=ߦCDO a9B?v\paU"5x3]Hr$Saa$x: wSV r3V'5q@?:rpx:`vvdPTOs{]._}xyw>{N׿;0s*twhP<ivކ(Ni[}hw~%B Z96D0_Ԡ:36 ,Ɖvf`rf-lF^^0d%Hc9غّB5K7TK(U/#F>{}@1*oPgZê/Tؖ6(%o-@K:U?dJ'3`q=7.SƕL̹ۡO^p]Wpc:LE:+辠Ӫ)1Rz=ڙÌI d}RuuR e>xBTur?~I+]Ŧk r1}0 K^%&/ĬRU ?2gwټx(gJ¨aBsTt 1T" (u&X%诠w[W m wh뒩bPr)02_Ӄ28O%R`20|7dt] pptMoTY@*Ɇ?M\=*$MƤ;0U. JRF6Sc(V@K*|OėD]@VIm"vpDB gBy}=&W9^~ 5v_>^xhJcPRz71%Ru4t &ST* #̚kO[. -FZmР2H~#S]^ L-U|AU5EUy#M0҉CNOhl(:_1wK"67huR3FYYmڌtHfK|<@@W'4 j"Z "" ~RSUZ-e_3=UkI݂}㇮Mq`GbgF߮iN~O. yz#˫ty击WI+R\bqyeT"2 Şp'(ɇW(U][WJaAj+g56 eF ?yp4rk!PzPmƱG(̖Q/c#Bh,̯d;H Te( @.fZ#F}`SRt2^32 Қsp~YC16i`5ƖhHOCCQucتAL De:юo!ɵ ޴ I QBu@1gQٹΦ)F*}WYi(W( r-!dR6~O?"’ȫcr+s%I 7/U 'صzҳeMKbN=x:ƺj]xem#zX"S$->dfzDTƴI4OwsZL?)-#po~0u "El:p9AU Y`~+ O 9i҇BGtA|h48L;TVSfN ؕk.U^&rY5d3V Pչ3im_k.Ss<{BWTͻwr?=|D.j$'.`b-~VхU%)GjJ9'<. S0qgr2O  I!U=eFԹTɠk1 E 4\"-'jTei40}0*zd auiQөr`|2+om RF gP7@tsE= 홱4Im$E7vd|z]GWç+}!Ol#eiQ X38 7_tyÿ._<^Wz |3-S`ҽQnMj@՛4[Z6L I9!IwRGT5`1Pp.3H:RA@YmJ*a]J uG3F6%Α "@U_$n)]ɠֻd#XI-1/RuA<]I:fti>W(ϴ&6Sss!k5|mr,g8\r_ֈ~źשКRAp={\=w|Th@l?>0rysFw܆1 *u5ޔ*E)ܲXA&(bF@ZnEh~ sgE ?c䍉1lQH27 G$~J W@n 1ɧO~t8~5L(..OQYeH)Q!2JXE 1V -k j]Mzo.aPT2vJI982Oـ/x "Y_S%҅'tӹZ1^?h䕏C J+P^ݽlk}_UHATt" gyf3rƬ$h8*]2r).9ȌyUp=aV#/dOWK30@+&ka-Ъ-5NP3]PѤ[ bpȧ-bRrQ;agxԹϩcYO 'E-t\z& }$=3\#]tp(",d^J-έ>Az8Vx.Mκ-]"E78kxŦx%TN OdŅ?*) 4 'r$7U1KBt;BǗ-x}1 ¯rGd[ n,t,GLvգyxG'Q%ma/BO b£ wg a_ \lRV_#@h8VWѿUØWҧ@j: K$}K Wu1-`]_< N^5cHtxP''~ʮd). Mm(G?Tgzd#{7lA؟1w|ˍRS~Jwa #f-+ʓ)P5jDt'}*6b'!\ 3ش7q3BqK.TCb,LS51u%kl#F.?] w?˓{_]>}|ϗ_% = Q76M*+Ari4ݺfL`-iaQtG)UHȺuTVX.qf6c\$HUBv KsR k;,vYAynX6r,ԀbGe]98fj bZfc{y>h%J( {%7d]XB (Ly3Е)l`[DiʓPCŐxKkTb]NŬhbd/K,}L+mы6ĔѾ6Uq' %++"It`P VЂʋ[&) f2xLy]b(8jnź& C?.,8b W"cXqActݹ%{W=Xrq M !rf]3 a޺A /ڪG70Yq(ATȭ)Ep ϊNIm<, jf&@%@BZ-m+e@2WbhUMl)mK>-Xh/DZspbdZ^N e[ !׊:`VfObҟeGfT$v t5_ۼ6dIXvIwCSG7`!;F#+Y *l&7ZL*d6tqP4tX|@Nq8Fu?SY{N.Ji!i j -Op3_Ⱥ'H&˫w_^^}0p _%d}`+ 6!Jfh2̙aVmC -h;Ξ/ygE:GhY!ppֻb4Q 0VV" PZ2]:{ ȸS_hO3Ml*=,Ft1+@rg8,ڰpO~ya?;;A@dtuÇu!4E"nyrHRO!x>LBUF@`6s8Gs B}-(j-/,AdMb5_c gT;ܽ_?^\(a:w |sHXPݤ->M,@Hy 1_X0 >#Fo1E`NweQ=@`xF[u&Bl `,U'F}=$B?H,b-;|7Fv_ Bۨd@$&xKim * j)Vu0ubhir კJWI+U*UB"u[06dV3) NB`eVtyѯn$W{(_} AjJ\cۇk[v SYbCOPEv\={$ҔKؐ Bh Ҫ䘉 P9(./ќc=lMRk)YbB`$1OO`lZ~tG6٨/7L,9;J&Q,բM'W ^†mY#5 t@]-99BlwҤ z5J0;N56zly EA><"H Z]p.6gU8b8PiCqQ5keL\ ð݁tX3ykxsZ&.a0I Sbm+@b:kNe_ &3{*4]%d|T85@n-jDlj{/x4 q:#oRͼEeD[L!Z~t˓;aKb2&YP(&wX.4`̪&Cj F2M@2웊 k7j5w+8[ygqƚ+nj3C>y5pEْ;lE^1Vqv|\%iEJtx"=3hN5$ӴgL&8ŵpFAw/ci!lqGCz1(qو".a;^ʲDY EyW4uAۚXrNg*NY_)z9~ )F +haUL Xce7EyXUfBNstHPj;?bkm| Bf (j/ȓ_ءEctS(M dKØB/P=ùq/ xŐ:$Nwt'Fd,4, ADX.7ZfZ7ۡF(8XPWo5[) {i!87V5(?(<E!f"# ۧ)ہXlNaƈV~Hy7/C$#ك /LVireymbZ_hG2IB;''c,YIm?lo_Wv67· X?~yUp{p9Z>N?#ͮGɗw B-u6Nj9[ %dE)_ITG8|>ka>8b[eaua%Dxq]_n2"!N^CN^60Je PSk4M(&ag}&p&@kl:yyVT[z B;kWF H 1(U@'"@ )kdx6lR7=g̏?_vul;;$ݦUN'~Tɯ3~XuUkU"x鎐HѢ7%{<0+>sI`\ oT3^`57h0b `3'9'TKP1EShV7C7C"C&!z'vX_eF3}Fyft0rpUO7[1ШW6Dz՚l #񠀩.ޮYX-8ޑZ} W^uvW2ص)OZC'P?/>Eީ< |؉ H-+tbr%Stf),AIN(' :InXEe1H.x5ؿDrB#3t%'_R=`{oXw R'dUwtEhX& @S1` MBqlC@Y5yQ!eM'gzMZ2mbdz]gjm̲E˫w`TAB#>܀{-uL` [UтI“c Lp ˋs Wo!w?] wZC,^296Ǝs %uR7Wp` \aل_N\%{`LgB@ VrAb kUX֥f32AXҌKayǺ82"ƱaLxkhni` ;eJ,y ~+E w` NpV6,V%AWUvV,3城Y"&޾7?xռvh3J;d`軐yxjJ7RYKd&;õMLjT^.YEަ%~+af 5 lh2-nN;CyoP(E :TMͰoNpfzac,{D#RUP3YVODF ('埬64Cl geƲ  ,4d9ysBu!hOԙh? d}[;w̫AEj*4{DtO6?ɀ B" emVֶ44+5H1C b6CW1.tUػ~~C͇_?|EB5:OԮƢ~Υb^tg@Ơnp옅0]`D >Vk)<dFlFv2TZ7W[% g\IgyyTdAc[ r-=nl؛4c A^o?!ï?=DX:J8s#0YnSahlQ{R1Ik`ʩpB}∽Av/З Q(f VEkaMTɟpp suok/ƕhEA˾h)\Z3ifK3|pz4 Q2&o5F0Y؉mo3M.GzmV,%0GLru`(Q{Ջ&Vg;^[\.64^vDo*/^rH oR't75ΜU!-mL*`A iF\EgyHzXmN/KB <9ϼ ̠35KfZV^JBhJ2kgb\&WkWA/|K$z AI)kL:t!2b̡ZQԛ|ӋT Sl4<]9Bt6*aCALWK࿡'}*o4?Φ '@'{Cןu֝6g)۲j b(lK\F1Na LQFmYUJ nUƦpGӇ,Hm0Y ̎Gǂd0FjW>YȸEBބgW(nJCE2< Z$?sc !dRȷm $+mwȗ0b'mvrʕHjT&Ӡm{%8ONQA=R$F\[j0>OIpim$Nu0X )6ejbur޺ !38u=xz@rJ{Bɪ>=\ӯx@[񕣅`AB($zQ `T~wiٜP*萚9Q5jvO` _:EzSX *"Z} +@|0D$Ju}Ah~ j RNg+d? o!9ds{3l2\ciW藭~V zr@ _KխlȖ>1J!^|gQ|e)=|~p{<ӑ-'b`Etf0*ݧЭ?rUx'Vr0 La/3FTVX.|-9GEnb|C±Ɓ 1ZNZ,F.bw jb2[r NO|t̡Ҿdf ze!ܫ_>}a.Ow?_Be0)MXE0UXo@[^@p~Ko҂Ud.ʐ $@ VOwa@Wq)BsK/5J:YC8ѹ8C+X^gazUȔ,iUފ ]lǸ1g٤)OmʰoyWH"`DZWnXrgL!! ruaOyaE΋)D3g `sV"0С{-iMEXvzxY gz[ #^^+/?>mfl_?ܽBLߛˌnEFa$ u]|/RؒD<fOY-qZ WHHɌ,J`ZBlEBuyO/XF}/JzS jaW?CIY&+ fYrk]ʣ9UL& N,a_1 j^I3.$%f$vͪ[VT)4˾}Le'K nqɻV}zaz"an>sVۅI>uF^0ւMM0` d \mMBI>z[׍Qo+uAbGƯ\&s{3|fu|/gaKÿ/7O]n]`= k+0ӷM%EUoQ0H5@^EC kKv,#ϩ(Âc國l @ fe-Lkc 0`:CZȺV4!reׇm.hǣFO¢%gk:=S6Cs ԝD/]6iGrP2OjRӸ[gs6<5"馰FH"ˠnYⳌA]Z0zXln,܌w^':zytXXmwG,woEw?!qյU/Kl728] U.`Qip~ߝsQ֙*GAiPЂ=A./`~ E6uoq㷔1Gi3I06bI#%rXw! z+,YoB#!Q\ ہnxF8{rL wAJ I# DGDtё߰U c1$|rZ, JN"+ecPBy:x4\.WVHDYzea7Kiawz ܭ;t^g<>Gr՝M> :pKkVhrϝj >7MH#K;qӿ+2 ^Sq>K/MlHn 5&,cf{3P)%B> y{ k2GQ@ *SK6-ښ샨F:ZْX3#^@vA}'=;)a#Ehհz0f,4rSO`>J3P?b{F=Ԋ6\^PYTww.AOUO!t|>E2|S9) %_d:EyBSjJ[ . 6009DEHh4gVrsƧbF`xd6=3&pd!" /уV6S_yxeVCQ$v5v 8<1HP+(gff, ag|)˜>v,(:'c8r)mad0s!>dpubɸJ jC4HLdkl}<] 3gZ>"vעӯ _=R ]m> L@q}D ؚŌM 0kg8Gһ;Xx)6gTAOb;yT1pV&|;e3AD EvcKpXpr xd|'U4!0'+/.@E}vYaqYlfFm XbV2wX9 2Vi$gi "kdRXـ" &̂)tM h*Ta3Z>-,G]h ¹O`NU{M߽Sj,5f9LxVO"?qӘ>i0occ? /`>&cʹWVE>dw9pP+Xq2{ɚ<L ДS3fvKk @bf6!nbJjPٕ5n:>{Ea "U^8!84A#njʡGven]pFO325R\9̌QSf FrY+$c8])wafX9XS$EO(i1c66lw" V^<Y={燿>,/$z%E_]iY! e# }|ydlJLx;Hb>k& I&CjL, K!qn:NwL`A0+ RV +`>p iJ\3ַ ŚcK#!YrLF&B2f;)XzZN2"X.Nk &oKoNkjTγ1 }w`dWPef7rra5{IWM܁SfF5Jk*\xx^OײYLmMvÑo`v@;7oϘ)`5H=}o`o~廇_&j[#Meᚼ_A&F\iXy-kf|a]BXG4(;jTՑ# Qs}t Hj&dr&7XJ %7vQs'Ce:K,8U# {2<ͻJfp.f[SLʝXnۏ.HW1=kkktfq?;m*CSX T!Ac>1qb Pj]Hw:m=R4;q5)cn\gMYf#2a} >M^M}zNͶQu Hwwsw~bzc0KxM:DҎRbbn&5X yn[U8a56lmk,X@1Lspf^h/*d!HDvɭz,o@aGF\ q7)q)nx[n e9/69fɲh[Ѷx. Ft  U#BcΛ)/uc$w5kзcϴFi&$$z-.baa+{)o-]p̤ m%|{ [^guK8q7Y dYֽUD{ ?j5z0L3$T[RsRĚ"K -m$OX8 &q&< LW;~Bb,}⻖ yI"/vErd?Q^$UMq4d &_ݞiuq3lL !Fnuaɥ ԏC nN t )r`8̍@=C!DEYwﮄ 83ꠟ]##E61к[鲘)Yb* C)1&$Zֺ}% `ku|0I0Xl{eL:n\(}lrƙa䖾r}pk ]-L ,m4` c:=YIƞYV ,ŭsi`%ƑbZ7@]ghLpfye{|,QUø[+Yws 3hǕK],-@1jdEb@)!6'lwg&tt>ۭ-?=BߜH6j*&U}ޝ`!%H!8y&.*ӽB.;ctQ+ְbȤ,-t+Bֶhim=V2з5Wh_zo3}o/.?=}]83,e;~ӂ9: PX!2l_`WBEsG@܂DR;[,{R"1nLt=wƐqFCixD<fQYNLsəmʄ ۈ`]z`  /-.]*&:S%k]P-}6 bPjπBp=VbIwmx`e>_.YO'fCXgKk+#|FKDdYq^pӣ6*-B,)/qʬ b6 LwY4 #PZGBՋ#0vFe5Z\k 'ZGNҬ [%1ZTgZoKxٝMF I =(0' ogVdP{6d(97n3(!~c5GU+P>,#X<cP ; L__1[Bň='z2[,vze2,=1Py'8Rphmt /{ySvE&soaL/rqiq&z8n*v;"βgmUҲtfZA%]4Q"Gst:ae WV67/= 0Ygv 0I Cz\204b_,@h E!P=.lr2J+(O@s<C%C[q,0ZV>)X] ]ԝrX#Qed/C@G+'>^2t uUK(z4 mFW;+V{nuU`i}8Bl ڮ9d2l Sq.t˞38k=zzOW&f洀"@^A{M"-ē$3&̊GR L73LMbce?>}%>prAU̬jǧdRGv//}O^̔wLFӼZO9jf{Y,}@! V@!$m2@qckݪg(#qlCG޶%Ln,2S^MsG*;%t,hU)m$-ǺkG7B#؈wѩjamD-V*{`i`"ӻUe9$f`^ُ"@UAly;g8jxsت6>hz4'B>Z, %}`ܴpyS[d;f;FivZ0{x]! iO`hއgWFgz2]HљZԨKp<^ ﳖ_r:GX&;&f3g?ۻ}{C}ÿ٬_kt`Hϐ<:0ZQAUs2Y{K9K+в*J]dmiٷb',{xwgWo?pyHX/Ҹ9BSzb!(Dk.cW6Z|{%hb! {L8d5]g7othXHf c-Ce4}m|ԥBFdxTHr?{@4،gG5WO7T;P1#F +1\n [|uu*+ + :}٪E ǥo$=mQ^F!ah  Ͷ0麆ߠlVof4zLy)dpoa?LJ_?~W~x$kB'Z|&3$X.}fEy\4V`r4".@w}3Mnv9Ì5sL2YޚxMD0@ ] bU$ <%Lf͝QDzPhB'mkz*DbV"Qgs~mF:sQ>7CZdTCLG*&1G}Guw )ђӕ/T%P0mrwIZ=! ѶQ?C2|{O>Җ C;Vr`K X0m,iUZ}+[]TiP91F{:?A;*XKtLY9WX쪧l_,:&mb83LL-^tpf3~Ɗg@ r(Z+ZG0($ 㙗- ࠟ \6d[~+S ^% B2#ЎlG 0,JD5=޷SIhՐ*YWsLw{OoJE[,D6!#WMLPhn)lCF*/_s˯. @\q76Օ U*cIX jƕECj 2+գp@A53hqm,(* GX>j3@T)DE4D t"S `iJ[('Oޢ3ᗭԺ$5|i󉸖[Qi9/CYA!nݼW gO΂IhJٳ@eҳzZ\7! ѭjc6HF[ PB:gtG8آI`2$eԫo^\n~XmJg[Kaom6ҦW{w 2^* EMi5M<yݒhx-oG^ޤ1=f-d񹃙͛[^ۣFOE`r6#iG)[G&^vr/Cb{"RÒ5ov|±<$@Opnd2Mܜ/() fDZƦꤡT3SAF|fF~le+GeusI+}S KUҷK'DI.vpz`bPޛh* W}`L~%b,ueJPIԸ3 78~|Wh$D3fJhPE X S^)˛WO^:(፮ qX؀'ၲMs[d3E0fVPxrK QRh- 1K؄Yb (#koU #w#:^ЖThMv-09+$% BzkBV h gXNgw6\ԂYzg͢<mAec&=}=#3gQ #^،35W62S~Bp!Zdu0۲e6ubWv719BH/'5'oo$e1~#+`)ߢ:FB c{Aa5NFʉhG鰤+Iˁ:՚xPB(]؀$? G{Yӎfͻ\ lZfap7?_/=r,q iGÇ.|6rhfyeFa̫Pmп /]5&̀33"i'+#P@J[;2K{jhUPgD֫tT@^8E? Ёad5A|)rDP/k: %m,Be` i.&BuX]jTl XnD0ckĜF% 8fC$zOt q`P)V4x3%)(+G v ?ru_1iWKb{rHHNT{_^W?g)$ ۳LȘMA)ȏ\ɺ Nܖ7 "Ԍ~DǞ5U#fvأu, xK&2f2e9󒄽@<3Fi7Ӯa3 G.)9I@ށB%IM ]MH?ِG^j5(:ƒ!(yrN(+!(@&N!=6K>2Xo趌mȢl2F6)9Lw6br5j{8,iS.*H82ԅ|7/>{r+YP0A%ie$nBPv_%B[/Mɽf@fBg`yq=> 9}㆛I\8D WM,{^A#>d9A樒(3[yl3 ;ˋ 84# wjwI*V vͦn.#+o٨.gN?ll9g3NR`C oZ; *HN1LէavD} F- !ZOz0R4?#ae-5-~nxTו{J=uj3>X1:C4``.\NSG?H B%mrD"Kaɠ6%K c7Dz94SOIq禸Wt3[и: n^JH}y3MA$m"R ՜n" Va9lQ7d*9Y;ⵜ*c>nu9V#u=fz$%V >25W_z4n՛:4o5<љ 6c ڱfB$]L ړzn+m-oWdG65-qdEv|`rXʴ*PGB '7(;xP`V_LB m?BChр>hC78]y E]Z fG==Xuh lMsښet.@\asvE g*"?#WbH/~f%bN&-AR]T[%BPjU a WK%`_}sy/`$ $H5d+R e,f w,> 9:gJT!)N g"VAO4LnXTa"u1c{uƎ, k(#6U9tii) ;)хTuTTt PVuˤ vOkpPX!R b7 ?ܼ}~wўŕN'L`bLΫI`Έ>z`typ]Yv $*B>{OĴ05l¾"NTc Jll,chF1??´㉃Dω 8ftu u(ЛkEh$C@LS᪱B/uݲ}+#ıQDs)&R! H%!/0!ρ-/;/_xv0̭nVy }b2C6֏S:_G{BK}=z*u˗^MB&ɃKgov/J1u9yfp)lH>Ҽbe/7jQ H5֚Ӿ玳y7dp,(1fA N$}X`r6Jdb4?c=(x ?S~lh@/Z2sO"R44u.m cyd!QF7e$k1!6uFuΫBv;@* ޕ&Y?4*3dR{h]ْmm3B&|{ dWP `JTB:/Ii:k3C?1Seݫ/u_/|sfMbmv!%(~BIYv{gTABӁ`n m.qSp D *"nEEgS k}mc-rv-`fb9696u^O:c^pJR1JJ֨c솘.w=b\ 4l54$=s(pb_.ڰ2"c u,Z$l:Y0ҏYF_A*5'xV 9,AǮp,i ?F&ofv|nYСOQyw=K\^ J7< Z1E21vJN_P_ W(AyW}tXue#; ]8gp]P"Xs&{Y%G䮛O>2y<̀h5 :UpIb㜍.e9>WϾ,5H97`Nh-(BQ=8{kh(ڄⶣ;4CKfHNÃc0'}ܴ| ɻ'~0Ҭ& UzKY((㩽+gD{[k `-Ѧ2x:"7ԑf9yko"b4N$/'Ac_QH9_Q_%/ڞF[+i<4yPBFkExPߌJ!;EMDkYuB(^oCA*S[p?hd)D3Y x)tfeNȥY: 0Ie5OPzṗ?Lϐ6H@"]G|Ѓ#aE -ᗘFX}m89q˸@f1dS8G`>QΟgkn'ҊuVޟO!KzHIڹȞ\E[Pg KAҳ VWa*9 .H%\f#SWmpak<%?Ýa(iZ7Z&$ؾ1KY 4"3@xa>po$wtŶfhU'21ch<%Mv[}ͬ"Φa\e#ۏ.3eu;_s+= ´MѰ6ԫM7;r[8XGr|hN n˫ۧ_~s˔on8Ng pD*q@1x_7 Lδf%E7@rqM4}v*g.ըXK=y-mhz 0SCwrypAk/v',d3 [i7%,.IwZ">-˰@ ECt1:f@ZlӮ5Rc kvtc4pPo1fk`4>^3@YE\ `H_w>4V`>L"fD͜=K_4:?f&N9tNLV1khl˭J. 374yݩ^HATy-ݍJfG`zV?πa}ePX>-B24Z|f<$ۘ?kino}l6f|ζRe10 6 }dƙx_15+];A=;T?y(|W` 1_#(8P/#QkM/U, @lM_MdREVW,3NXyؔ"uT1ezl22lR4IۍP^Ý[ʴ>afY X*p2QGщ $)3Cđ;Fַ7(>xز -+=Lf|hӘWXi U=ӗ/|uyz 7/^\?Y2F3iϊX 0 1/nJ!7̣X!Y2cCq]ѱsR'_zLVq8fW]hB+3"\Sx )>LW3ef_ݼzZ˯oy舄͂>65ԋ4mʡobPۂ<1RHQ1h|6}[Tp2*)7!I cwUACeg*u˽:[Y(-R GX7Yeu@jPbsYrf!]!nBo^d^(`\}#3E/ц"~Cp hL+ņm)%9pzMqiA9-k'j̲¥[sp qDf3<-q6aOdNO y䴺K3܂LM!wˊ׆bJQ3ͻ;ͫ,:ˑSd@7'cam+2n遣^r]嶪' +Cd7Nv\L# L;UgcaEi;%q3$JЫo 4ky]݅_?Q^WHPO N-:.xfp>"b |{6b _*?"1&C>qf 1r&@h,C -" qrH˃mĐLRLw6Na邛Q/[PpM87E-҆d.:J~)DP%AsgxD#`n6tnm~q@LIʱNm78YFl dp#Z%?9RRA;<%Sqw/On~xa͓WOzsUKALR@p==EE J3*]9`ҧpN!EZS$6|5f-0i m1k=` PLԁs&sBt`TZn( mXrYP# ˣy[T(w=A DR%0Y1N vXEB;g[%Th˪K B`ZUؙPdB|x®)达;}~+zU QJK$ƏA&_00f8[OtePtA" GVՆFcRۑf#A7cIe/Ÿu £ы;4+v~{ZD):, #hbYjvI^ % 3:N\s?8 D}ײ+\*5B %-yh[mD-C?…IoJm|%4 HJhy@}V0 5>?}z7yd?41?8rHg4Fݸzƌj١ꟙ;y*|2{gOtk'=v2WG٨m ں$Z0*~!Ə #> s#RC#%!!hNSC/,"sԼ O AMV,斂vBFBOaXXdju!m$&Dk4bgɌ1V [꺧\/tp˦6?;,,sfhl5ߎf3k ˒ ]jhbl(XTvb燠@O\EAjP=*^J1g0fv޼V>}s)e /Q4D7 9!Y>^ϹԥẄ́ikM@I1 ۺeA3:5Mg$35kM) u;WBͣ/$U!P:Q4^5ps "N~+77{ b9qoG1 B,;c7^~fLuEuZuO-oM3g)4cs,(sGGOؼNCAͷШ ʚW/ o8={^owxtؘ -X7.ȱ?W7K!19_GI((2V_Gby[|yB/0jـv 6yOQ"#$rΖOdMդj??ňi1)o ׶9TH؀c6amc7z\8`Vwe~+NDDGFsk#%_sfMTD(茽8DU֓&zUs ?dݔlAJ&OpNEN74N}:lfe)!|f(17PR7yB9L ^iY6`;m( k= rL :rdSHHox7IEÄ:ZX?(z\XFWN$gPr;bTmd | .n] m.+` A t7pD4ǮiL#6~c5P%yw_u?&V0|J7/QzQĹu`T@x))DN;Z222H0 |Y|*ltЙEM`"|[yW{#a|v]92.h d/7sZ( {T Z<Wߙa mB/Sum/B4O;d-ZCzVsDNه\zU56| 4? tvU|]Bg"܀0}EI=A!1rD, Rֻu,3guB3Fne7/ޯP6ѢHBa2~2`Q,;GYM]QR~r 3 p,I!lrdn?%Ѣ)nOڝH2>Yn=hޫ^z}/`2BXIA0 j,r+jDb4j&+(w8iWzs/Do/O/Ϯ(~0tsW^  ht6KRVlE<8]؉2EIJ I1!43b) Ψ6lW4 k=\n:JRZ@.Tr'ʾb?ÿe{_byJ󡋇L` Īt0mY+vI.‰.g3~=#Ćq%Jm cE A>%BJrco2/R]:崩!eً7b:B$s(Xe<~NY '72^\^+!r3K:n|vk6[NuJKZȧ#\*@|'wwZY2OS" - g$# B 78wCv9&{DҶ~jAɉ>ҙ"+Б"ڙU;)V0v&|&St!Od2 [LUt''U .9ڲЊ d $/-GMXE!\q[dW8gwZoQ3cq_ݨp'U/ B\V@B̶͈[M xX*N!+筋ޏ rm!d]-V1+8ꖦXFGyQ `xo;DGE8v.cBu2VG:u]cUB,ڝ~ "yHur&-J4]͠Yѿz ?<'+ߩxO#ęK4EDd4[1PaL BM4Ęg),$LqimrKtYW/6܆>:(#3 NgB1Eb5(Rij h;ٶdN[SYYBȋTtE͞g&ūDtdT+_dgO,E"N[4+6i 4ؠ]Ɖ`d#u~]nɍٽ&D KPE!RLzf 7*TyUb !i lW؈ <}8J;<G:|gOorų+fe4%c3MP|kZoTX`@eq0Q`2B K p@]ܣ8 vhdr"Mŭt z @UePCD Q$E_s_%20w:\~n--dϊN'q <%wo?grr7(CdPJt߶䕹P p oMxf+JhTB@43 (=F3hEWrc>离BbH8i!׊ѫ'y|O{ݦuSNј 87`BY7;$h8Xp%j$y9xa$LE6?[Mϲb!" S܎̓ sakO1͠qB[Yl B95-dIdQ*AiX`ۑA`sawF@uhLYB9EU5VЉbP "[PoٙzV淤up42Nekk'IM-X+|xƣyIY׷ϾyWѮfZ^x!\C@#,lOt4ps4ur`p0RR+OR%ͱ~!WɛTU>0{.ɂ%(ccԜL(r"g&jpiK~loũAW- Cܞ]ͻow7B+|A{0lUU4g|zUj7wT6SʒWKmcӺ?`4ÕJ=2>wP8 f[i,(@Ct v0ydK!7KDBY܋YB#B)<ɨLY)qF]jQndLMЛkrоT5KzLoV>6W^#%QqT8+GE @Fu~p#LACg :j\{;2Gنq6c` 6G=N@r,`aD`$3dd:' 0e?ρ ގA@q! ԈOR[ahPz*X7 ]{w޼ϳ_/_ ED{sZú.Fҥtv$V[k8MWSURMvLJK&E75UIe5{c!Ox "iņCˁ9Bbu[>¢axN܀o e4؉M"*\^V mE3d"*g "rd5o N"_ %p5)a׹R|H!. kk}8P%uKBx'`1(I'\J>$joВ?*^sE݆u2Zeŋo_܁$o1K>hȶ zP`6⹌f aӈ$e.9#o`Gfe1[?9J{=1OF7SBH .dK8NvƖ4tw}Vz3\14^|tn~W\owr)OAe8(}ױX˯.ϯrDD&K@%Q1`W33OKK.`Լ`Æ|S nsMzip$Mv]꒲w2Yt*;f=~ۼD.B=jp@M-HB8rS,Et)evېSArdB"yymQ;8 y}ύҙ@dtZ*^9hvd`MoWn.9J2U6^Q {z:ńrb">6ᵕZrBر]/a4$`ygtQPusQ]o#:)\c#yЋ!pӐ/+TOtT p@˖wH_,I -E 6a9EA{ٸ^U!E>Þ1&Kh{g!뭑 ]!qNy&urf_6Їd{[؋LrD0i ޣZHfܱaD,Mb֪&sgB60db5\<%Eߐv{0f(bfp;1|hy 4qyS,@y8<sfV͏kH('^Squ3]jJYKEYt䞾-)Y慜3LvAaJ-:@` 9Z v־c*3P; &O1uLZ4 xAfZV^C#5ek[>mЬzUM%w7f2vڤu(PJ}E|`2jn6t_!yF![ӢaE1mN(ٟ`Y2&-g $Bd[YNy6x%Zj ˭K6 Yܬ{7i&bx`-863+3C=H0zZw[uob>|9>1h nz^~}WOًU'U{e v{@Lg# y]񦷁 0,%%^#A\yqC,!b˖VBniGgj=yJ).?qTkڄ&"[(a:MnN6ueËc6gmiG`rz^)GBfyx;la*:˙+YձJ(=i"Js9ȷФPHBlrw=#DoO^Žgn6tÍvWp[(Rj>q@ԡ/)=}3z2'CCo!ܙC [c\LZwp裰]k Gɱ7gCd}AWs6"#!5ZQ`7,o6Ge8̸{F'w2nk r,kԳ! F?-m#-}R!:tV:_ׇyhDML=|kGݱ8r h :,/K`re]mQ;jJw}=#`Ih 3)IC_aI}oy4{ }!?#;rKUI/:rs!$S,uQB4%T:>FHЙ(TjT]sL8,̒ys߽9r6B+xAP40x$\g^M1aRȚ㥻f夠O'[`PF;`ڐLdЂ4h6`/&_9dw&K:>A0Sz~LM菏-t9HTK u"'q-zm'DO.Pg7IS9(gŖXx#טy! f)-&|ݾ1NbQy/ JFx"7FĊ!,LNK=6(IFC-"IC"rpˌ^2Cώr^ƾrNO亶&׌yC+m5dUcKiS u cX&LGeJs_tT4u2q!=r芹J7]Udg/rhZ9sd-' 4^?BT˂zV4Un%+"X[66YՇj8Y<~Ku6NvB%XbLYz2*1`R{U6{!V:(dېse{DW~6ڟ|gy+!aN <Sj${GhڰP"bQdةDI[!$ωF>[6Zc譖|~9Ē6* Z]ʷcz}aV6n*r{@+LxvzśW< c`It3RNe8ņnBaZ/Q.2(ΰIȔN*]rgWL%lC0͹f&-8q@bY/^_hN+E/i\:Qb3 gr3m`܉%ٝ9,{SNȯн50E7e F!yc(] 0f2h!y7\S q ?Kb˝Qc@@qۈrhR;Ls[ Pٽ&Սb "#u n4>m3&dEuTRjG.ƀ2~5?㼎"{ϯ0]62"fޮiMs2ψ%\:WDuRa{q >M 3C,] P`XYw*` 2.p2Fe刿jY5})#Ϋc0g1rxQ p:fh.??a0p\4Ͼ+l&]${#v6k @x@XB =iņu9,c]G4Jp&B+,fG>m%DX+El@ZFLZX&uTrM|t #:3s+dGNL|Qƺʉ\Ncb/eryc“QDAQ2߮2 +ZΝ476 +t%rnGwE &SxB3n fD H:?Df*bը!@ػZ[i}=7C ]=qs2ZyWF_Ǡ(@bƙU hsPBʋ;mIYNQ@{=dNzjWVMvF (؍9څwJ=pG˒ʄRMK"#&,^h1=3sKT8€tWm«C"H͘螫𜬚w[MúF䓻-(!eda\SYiUL =-pr;Nu oEcՅdc:I@V "m66_gnLG>SgZ7r񸦦No|ycʀ5Wڌ-RӱvZl1ިw=Wڌx B+ԯ`[k}"#' /9 A$+sN(2d߷FBi[A\ ypyXQAivE2F8EŊ1'v 0Ѡ0:bN krcmdg%gM=>0*^i uīAA @اl1 EPp܋ƌL%.%oN%A YW:-23$o3)\]"$glcɁ ·4t{1O.!;XtяOGKգ/x7߸thW"fpOw9曽FHl8wgsaf(58/tt\³>!]r9! PqN݇r[DgFSmʈ[ 1"yGLJ2-)R НSOirwe5+~AqGq4MMz/>}57O g/$ĒQT?K5K34ڋLSjЄM׌dg[-G?QN &jvC5ma}s=Se&C$1b(R-T</`5JpeT ~4j kRj:r2Zd{SJUO4*0ž"1Zw&1G\Ɍ,*Vp {НvWPRJWVB(v]|PM[uFU@@,j<1ry| _~ssLoC 8 I=Qnɒ6"Q'+C`wH }"x^,0PU. ]:)=V@b%h,!`K?KnzdzAš~ %[fz|Z6u%bTyHXa횻xTq.롛r6 &`ծ?)8Y1 s n}2 pDs93Kb Tl@|fG^OSGԳ0I5Eˤmdb06">@NM;膥Tc`@^Kxbx`k\G+/X 0)V;G.Dྥ J2cn̹@Gg^E2@gY1ni+"[@ɮ G)2CM%53>-RWo (>꫻(닑X\uiV"6BGW aP m/.V[^vGE?E/I>0=L| ƶH@Ф [&ɬ/lM@䶺J3*=bӦ4Uw֊#[b(35nMa"e2?(7O\p@맲ܫ>$ Xd%Ukm1ګS?Q(ASe]"iqY+i*xڻM (N4[ƐP Bx>Y`Fx{*S"*h{ Nl'8 2ubZre*m[8CX+^LxK(X&t7tlYaxjkkCMz/&SnlL²M]nFsܐq;a{0 u#uҼ@Yq_`:ʏQe=UYicldgFPzrr` k [k<;չ|a].;Z,kTħ^MslAZo` xK?vCx]wfVrC[fAx^ C07ʃLGc. W^XJcPθPXn Ek00bb[2] j ?T&6(ݐ3~r2֨=i*لxJ'}G t T {Jh,k$y5żb_^Q_C*zXZStA[߼(^n^yvF?^zn*lؠ(Eo"slmD9!Xtۑ$5Dx%OCjs̜觚arqR(q#0[۷I @Af3&.zVWë=vH0ACU jW<@Μe@tcM,C볬fs. hzj[e;*;DW?[_'B8Dm&Ǖ#J+f,hx2}SnNX}v?bMZň:^gW䮺 hۍXvV(NsUZfc㸲l+!KR|A{qטܝGF2$pm[,v)بz_ժE8.xXzd JPIv(,)4{OkS3xXR3z~,ۆfkH\)@iAFcWvې wp*ÆҒ]ɺץ_ѺtFbpq ))CWpl=sYɅK{u5tQQ̴L ܼ!ő,FUy~j)փD=Y~0V9~VH}#Krk<i+S9 S19%߫↦&G1`tMDanlUVWqS +n>*gq'j*  ,XDת7#;"ˤ3Bۧ6k J%Ujb$QvvCIZb5dg;[qW(t#1uH3DK1 b\=u{0'yQ<M>9Prm=xYO1OH]dtmjPH% a$[}0o"lw.~2s6_`s3$n@_)G, Dp5w+oqR+ Bjt~Z| "HXIPQa=)KOC{,My1Uyz &|Xh3d؉إ~*GλqdD8ıE9Y~f;G%Ͽ|4fTײlH rq`{f;Ip#Xg584`AѠæ=sgBqoV^uSu:Ky2:J$yZVZ3rS9 w_2,}9:ԥ<QirmV{K7;Z[A,mٖ:L wZC,ߧPiWDߣO7/g||-11]ooY3Gzb 9Wxf[k~PO[~,#_4B*kw]}us$0eA^oٷ48tSsZkm]K8[塗iJ̆S7,|_!ut7>}{M+7Mm34-& M!6b@ ~{XjkM8xCBk9EQYkQ39qPim' =2yd6%G^&Ң+!<"s dxH#.9.~#<&n,,PsmZaH{ȌUQIU3ՇH!] hȍm67P$W^?uƪjݎ*pڌWt8]y :bP YKҺ"5j/hqΦ!-*VE_>%~}[UGu*$tʀ+=k2/u(X %N…#gNagӟdQAt87=Au̘v0@# W[a!`rlZKs}ZK𬺫~ (#ψK>Cߎ*>*G`NéNoݐsCc4R"4|7B.+٬z1HJJKSK!QT9dPQU{F𔏞gɧFd9  m"U֛2E#.!1L'r/Z7o"S{A3xe=Nfe_,.gGeP50&aD^F0TTnwjnm>SC7/T^kzתU~n86bA)-Ωw2Is@z'Y`bGxatt4_M!ϒ!?GŠ'o)1 d1E'@Tw@`1캩- l43iI(QbuTO!T&Tu^6%\aSyl`Ev*z&b&`}(Vc`&Kzɬck G@'}bhUcDݟXݴF@$N5V`J'3@pF>EАgalJ8]^n0 ݹ֌H.˖Ⱦգz|USwj~VbJ~D<nskΟRsͳb&= nCE9Pp4$!B6)̧Jh P+ju{]r+6q],B$BE{c!Jf]"J<{JVA{{ bEA8F20*Z7MR YE'Z nM0UN|g(RÖ~xi "S@ tXBx805:@ -)5\'ZcdZ4?۾zHE>~c/>}HgdA?lT-XYQifC|ȂӨSVow-Ui"j{oLf35j 3icf5#-"p1=mg$L(AB WHQd2x+XMrX^JU(؎CPhCjN$/=kK8[ F-:AM|;V5'G7O#Xqox@Sң'?eCTT0:'=a4OٳzŲ0]o=??|/?ۤ:C~ZitKS7oZ_C"! c|ďLE|qzJxQU[-!?=o}uan, jz xC ME4A-3 +h `!r~ R@'mG^e2X7, Ͼby ` **vpxWuîލz dZ+PTMyZC5?ЮԴDFf5$j'B݌ֽܫ''\;C8š4:~PtIH@ MhP+cwN$ñrgSlf\֐ CLfqDf)fsdGv%Tw iFa:"`|5WZ (denaYuR]Ԥ<%g^CL,l1S PTܸ9m m6[6b|TCU؟$BU2'@X]6l~Fӯ*% vuw명^ڢB|ar_.ukNPnޕi5˘9_K=pSi}Sj`]8Gb__ߟbhQ̫ꉚT:#7FIR9h#W㘀YkuT}ߕ'4-)XidD4W+sg9[f]KԸ&AH֜sB֕@$1)$Me [m/>\&}>gMJ>GC3_i<}%d|RԼ(2iXܛBk+?rCFKq2 tB0h 3b0*O'%`'GvJ#cIuW $?4#h?;KSmHTXܭ }َGDTɞ__}73z?Ì@kDd(44Hxc(EK-~D^rjPJK$p|bAÉ3-[( A(簪&l-GLSqoFʣ?Sϼɋ_t.83`|}aDk0w{ ".TY)pG㱚>Uq[>8?wȈQ1k*2oAxJx'q\ ߟԂ<1rXL0C50ZtTj@_}A3{tIf|yv[E.k[+)4ϲ| m$S}5:+.[a1pHA9`CDڈަOzxj_PB33&#D]ɘgCI :a=A+ ξuOsN9W.cGO)h U.` T.E ¬8&@T a;f˕ 6D^*Ksm QqEœklI3eCôbX7K -G2Ya3gz߬܎`df67g8g/7t;Y7r?N'sBG*uݐI-v*;XmηZl6j1ϾӔ.Q" +rSKzhd`:z:ycղ=51%2bztARRY >fvN_|LaLT%=5)>sDhpwNiÊc4`}kMb,vznC8& # Wu ~ث1a+Րg+N c ͇1bJhsVR]c610 5N="F@Lho~vQ}jp+`̭dh{8"*aWݯA9$f +>r,h[%{̙ld 7,l 26qJ79F!hH>8{)ԓGl- f9;l͙XWE̬fq"c Pem0_b-{@mS-pe +Q,!E[%mhr s7KɄ-09HsFC XLnw ˜]}K'іeXl2Y8VKgoof?p2z-#'0wQSnE}Et:9lEtPbMUC`A}VI7i8F`fᆺ>"kX,2жL\`u{,BQRl/L%%hj4ӳ6a5Is_CA|0f(&o*"&BKJfU_-n 7 _k^&NH&`3u:F@HtIgzQtFKCWpGUu +Z#jbцmI5)ۤHT4cVHU5\ؘs G}O3U@ 5((VhWikVd]%'DE'i!$u?yڕL[Lé> CV4or-n%˥j̜ -u9Tdۗ$|XUҪXjV$Ԡ$,`>V X"CʶACoӂ![cv^ؒe-6<$A*2|ic񊮍F赣m֜Z:*#pRT8'fxrՙ ߵSՁ}ߞ*l&>~kj˔قZق*(aO añ43CC(iXZkD!Dr@lNxb6H[ֳB ) GLZEнG@!F%rRnF5BC_;-QlTU+@Jeny!6_] XUp(ڃ^TGs)nO;Ǡ~ x[o1xvoQNRUqqm:;~&䵗MKvj~j2)=!jz|}vMH{|?H-+jiv ;4m˲~h W۞2`TcR!&|6}<͟7zSV57!Vf(VhЌ(ƁA}Sͮn}Ev? pk( -szm7.H*X bOՄ_GK bj0Tۣ;G~@D ҁ˹`\Bڌ11M2N$\(Q8qCS[' M(?/=ӣO uL!fW~~p~~;4)ahKvЃR_}p rH6ܡ-9q?UO{Am+jYyw3JSێE6'3Ml3M~>}<$bdCALyY7Ɯ.U+҃/bs]B^n |=p&5YM #U+^anr۠bHq j?i+\ GeӎpVGl d1@(eY,\a71_2Q}آ*Y:ZKȫ =@ Mu`-ʃ/0j7C + azL}8lqRT~iT}r-WHO4h \TXzO7xj~ΩaU=wZ 4cZM"P [7qB.d t4dܠ-7Q'E]eܒ°~ 00t|QG <[ΊpVa-ng/D^W :7Rt.ӷX~VߟR(꒡yA2RIQB0۾<נZ>f#A©uj(VT{ȇ=f#\ yMc"l9O<8rri Ej$*M$nv?(j%e:Qi{aj@ I+,/tH.VN?/eh/ r} -+ i4S9Գ}2GRIn+Z@0 l V˜ g F[sVJʼnX%yFtJwvYׇ7LZ[:/ߟI΄kӪgGi'P$FVf%yL:7.]C {p' !?[WM Ni!$suP*0Jƒo4K璣੣OӦ7|QӦjHF>܉qfvRe|A']z0|IhҎmnA,X:TmØv o\<"K~ ecu ٕSP C4]pD()s'B'lGua}6Ek3?m>WYaT",b\R6 *FcbGX5s璸40L Ѓv_77 /s>+]/LR LA&aW(FS_Zn sSpWK;.mpWTX&wdh rއ݁o} [O!w6V5+X1gmXЪǣIE*y(Z9lf:jWsZv(E8|jU"kX u2;u쮊R}S O[F+{ooBOl(Oʛ4E)u49UA>\Rٸ_ W>@[oBhק7Qַq\sEfZ(Z-̧PBD0rXhAM LMCljK^)޶ m`P+F/dyNlJwѐMdBqVxτN3:0mszգtV++]ǁ.pe!DŽg͔f}[s5hhyis/T.n_{8ݫ>ZfT`p>-~;ۯ?^׷'t@"C8`pt> iȩNvTa!&B/YU̚h,{ äų#B[a: T>MLbddQ[fqx> 0D/VNaiM~; #i2A)G ! 7-*IASrZ0U#r|6VTgO֧";4fvgTτ5 LcDPdl ] H]/n=\}Z"+u˫c{[HueY.B)Imd\P${8%AS-GSo_m hI ǂ_pSü-vJsuv60sllg:&?n,IN)uJ}!Ȩ)=6tI[49X7IB4!5UG#,!Ttط)&]2ƤkْџϨ6!!xuK.Q.ւm,jv#Z%FE$-hM2@&sTzx@3.M>:Id<=ND_$'I[HE2ߦB&).> pD2ʞJ"c4tgi;{%k$$tkT:xVT[%1,KG+V9 ]QJl@?Lmi1C21ݶ5V]dyרB$2~Vu]ڤ돱?Jݐt=C5C?e_{1+u0`oY~ <&hAEt"m):U*{11WZ n$H/ɴ(*f}B)F^6@c76Z[yqpodk*>F̧tZ05Eځ mw;&P~t8bs4[ sŕqxhX{LpiGʾX.)4Em$yAvLTP˪ Gv4{%{̪VGG?ǫ״ 6 1 (nLk 9( H+=YC#Z(s=1#tMfG*4R& DBos~#oѬͫiMo@,c+Wɚas{'5q*jsh!PS!S:xHK*4D{kتe8M7[RZ/W!0Qph;P~F*^rnaAT-6q$U5I펒4&tQT1nCjA1\P)/T)@NDvD~N04ﯟ>}5s}ۧ':雎5!scVE /Lm‡ЖDhu,X|Ta o']Zy ?3HOu5R)! aTiQsF^xu{G0!3Ƴ6B7簙DEyۄQYnqh ڿLjNF6viTX"+ 7 d`m7V%κUn oADUF&8F*47tY`;=c¿{1q"Mo{lpl-/l0 \mԹx l1WJ0J&9M0_갟f8LI4qnzVVBOO[4,A.cK:0+Ҏ,޼o5TeEI{+s5BGU;#3,X3:ͷ!"͕!i8m$4@[};QĞTgw-45EaślH~1fڌow/~Uj9&aoyFG[.5Za `1L9hiH9&TzrߞBVu,[t=ˁ˨Nlm&r (4 b+_u0tDPN;䟒ѳi;7#TFJ e8юY9[[>Ficjeކ?v;hSmqގ/FXw*֧mXtX rXd[Yի~( DmSws[UdmWK&;:-}*kú"X&vK&gԬ:(dBy }&DC1O!.O4->}H/}No KTMY^ o9k"7񻇾-=!KUuQz2OVHDnj|Y(!9 ̶VyxHtIg4#*߱m?OlMǷml_!'9Py*Fke9&Txgj˼%=C37WDhhfzu'an.^3XZ ۄmTLF%`@TPö ۙĨ~rdz7ir"Yp9?BvU9HO$u_^?㷟{_!N !e/M6\M8یNJC<ܲڌC޶[{LT{`C&w)1x9WYX kdZ3ᯙ cǎe *ԯat(1c(|E2Iw5%J3_Kx  nSf Š4) _:i! ɹJ!Vi)jȴXVX[+x<Phc<._tV àich|iS: w+uo2̆lx ((t8/?} = 1yp+I=Zaevj4@ƚۡF4`L0S]U akA;TH %jn3{/?&(X@SCNmObaRl1lx`q$!lL G~#1kYmb:X5?eI`VQ%c Agt3g['X J_D$,3PY\i5{G;3᥻R+0? "[7FyȠ:g3."Xbb-%e4˓[kf*R"J|sk*PluC7X\[pbj4 n5T`$+EgW`R9[ }e}ø4U/Jԑ\Y 7 摣ÈTtH7*㶅JsDh8Õ.h/ja $ pZ*R[ DQ-TGtX$ {$)YщKIVʕwL`X;_@@l+h:|ř-swhc$Oǫiq~F)Nkk*qCNJm!*:E*css)343!RذQ3x2ל!*/IaQQ\[#ݎ!jLNsOsDcAj/Gˀv+Y.AyDӎq RsCzLrHWKpoI,PbANeZvnmfv2b~_)m_c y*gĠ}dWѢ?~\Oˇ?~Sv738Y2xA]"o6mZy4 h|m(2;myv(021a$M۴Qqۓ }q~NyMZcE[ע,cԁs'A+ :KXe傏(Å8޸|!Q <-QnOzH٪4S˂_,S' Pi Jw\((ג)MRosS=<:5@ E9ԡM}߳IbqhW@=;l`ۗ'{4ڡ_>܏8+eu }3ŢEts;n kGUt/vw;RHL6wDs. W$&>_l%"k)L8LhJ 8e{5zrRD35[XɪL&G"- s(%B / #~([TB+f}iķ\SzX|=mD}vY/?RՌ' dJ.Y3KR-xHtq*@.=gsW=3 s70"4l^) +>~{@hQazj6|;Pso_ߥʤ[1{UVeYo(y`_ ]w8.@bB̅؃L_ĩ|Kp#n"Eh$ťkudBȆ7LSr)ȜZ2]ӌ`6-ݎeN,)"X&Qg>{u[T1`^T"b;%bAɰ`ȬʖY)66A[º_3uμ^i{!dXO| ,|-ˠi!D_8. :#[~ޥͭbww{*/ ռT5dV7DnڽvX8){hPDv L]7W_񲰉͊b^Ʈ՘ Ulª eD9lREH zoO8 @YxI4\§슭L41+n`%ʃ!򽝹{DSѢfX?\`Y}zߨzq_~xq1&N˘; %I8&^14O8Pٸ2aILfqg"<1'Z ڕhUDOϮf 0IcdֶX_Q)j:[o(< >>EN B h,-9M~ޛ(HP(My +gl5 gos9hHF`ѷ)L?C=f{@'s.kO’W0m`䜾}DcNiPɇ#xNz/T>?m-=k&l`<鈸D B`6=n]Ϯ鍆s`V]%$ l,.@FS$#c b} N8leD8|ϼ>H~܆GJ3_Z'z*SldVB@eDm>7!f@93#VQ&'UjOmKAWD6̱8j ɺˌ?5 V„Evk0GrRiu껖:a殁=ZmPWզhDzn>#h\jA1?[k\js;+p8{&ÿ*} IT Ajq.*NKzd6έ45 גApܹ_?QܞA m| L  /}=6tO|mF %s&u [P5>Hj32{c԰-Jag<9Q\D`Ѐc0]jFG@͆q>psB{RYMhQM=QRND`Keޡn1Nyʜ&&Dk~'Tqix\ED܎u$vۈ>YhUfIhkPA׌NF*tRޱF`\BiOnK5y TxJ_PuN6E~?>{%OժThJ~0q9]0%q9'nuFfkYSaVԵ::Q8aX]q+@iDZr+!gsP5p=܉3K8tkBu[/k+BH!Y]e)u[[B_X۵|a8pΘ.i˝eM'´.RgUye|C{N:W{oqeckݕN/Ev DiAf,7퓅{~R}]F:f\Qyۥ]BӘ+ypZm2uF=#+У;N3RyFH%i'xK%{gթ:.@cnDр1zTm$u Qhx'(qȀ`䱿yՏ43&Y'jMh)\ũߥΪq|6CC O- Y#HWVpX٬VSɹ?S35jOıDw9{wKj-ru. Q?w%v$~>EW)d5*Z09(GCx?GMxTH _ZmP,=]"B}ӸFClOTaHPfy.]SݠJJY mؖ7r#$seiopWZ kœsLS˪`>P%>,SO+يGb59ݵ@QnL)VT._"bqS6AH@ڇ܇DiOs`gϩq戉[MVb8mٳ͖^⮡)9Q mÃTe;`UYb)2 yS0v ~'/F4n8L6-ѕ[Df4{o;>N:-vF^ 1:VҬ^'9.vF")Gi$ e$9FhMIO.G *vi4M@̸qgO)|ԑؚd_uxS'/q~-R(]mDu8@1i )[Kdh~"yk)KpmmjB8M B!3i-b9( Cd~1Rr ]@W5jдeu8BDg6)Qj[PEsTw(Ð^hLsBœ=XДՁ1D`ֻ*]=$hl;%WG?V5 2`+Xt< Nq :͗Ro_ÆOl((#!O" M8PGj…S=*G 7sߤ+e3Z6}XIՕ${"!סp6uJ|cgl 3.m:a7 ^#A)=Ր \V$"#VMǻ5꒹< JU@Uft ُSO ׬Fx@ 6F"[d(#[E“ٜ?<漳*8掅( -Up|ˏTKK}[d^Q TM`A-C_8_fJ國 R$d8|Pe=EՁc޴'z#>a{ MaYbNC%YU~S 63PW_zlNJMcV&FE刊]@ /U8"|0chO1_~o]"}@}bl(|Oo?g?@1=[zNݜuQh5OFCmhUmm 1[ԥF3qRb ,3&Ujx(7MPTƵ \b ѩ6ejd>Jkj1 {sX6+ ԝ 6O\m9v#W=B[fR3^}{,."S&M4 DaW'87JiQkn NS2VqMR۲ψ޵Ռ31&\y{}G^Ѵ]?Dm:~ڼl.ږ}H=s0@=,f:@RJ=ˑu8 "S_଩]c4 BQY7nJr{`+~ǘnR3m]Å ?0>A*K`&m6?hR8(UHh!;Xwl'_Lj!&"ݖei9pW1ƨ:T3Z{q0V4eԂtchM̈S՗A3M9:Vۅ P- !Ki`3e<͞Jn%W;d{oAo5t.aknf49(4ү9({vMUDL*D旾BU+BWyk5!S7a>Iէ截Ҙ:qsNjnZsϕ". E bD{2\;6P=;g (A%k[1 S+'_lV+S)8vK\ʗˏ9R xnF7%A/‰QP`#f3GzCah $E>GK# E󜚙>a@^C:wz w~PI*K> K6#. 8&:o"17D$p1G|^6GZ,\S,DUvh\[,@#`7dK, ̘~4)SLa+6ElNk*2o dW\eG.xZ'rrt$c|~ 4tԺӣG %PQÌwK/`TnZ\m>O77FE('0]C-`C<)}2Ơ1`9ZP#h~|bmB`Q`De℥eH޶6"wARCGc{|zia΁x>#Sj**W[ÜZ.`{^\M9YVhRԉIo%m >@SsH,zQ1 ֌QC=X ̧?Y 7 ",$G+KT~8/Y*@b}uyxiw_OˇߟLpS3:YBJh>[ӰVYwx9 X 9>> $σ VIe@v77;uo0rWDwDĥ5{C Uwnoԣ !WސxU+Pf`wy񆭻;hj猓.N[02jat:J [k|R?B`kLQ7ZZ\31;?wcҲfpEJ!~7Az QrCǙl8׏#:_yR6/9("uN$Ԗ}G19)DFRC/IJ_E"T3‚4;QY-lG(0ٌbt4]ս]ȫ\G[X}Skd TgE@:p/S8( ʹɆ#^|ͯ eb%9MF18)bLUGsWD'KDvTW-4^*]iYPMc{!G\U:o ?R?~{ -/1K9ǚ1[~PR]n2A ]DAu_)$:j6 NK/)&&)IwP*Ū0D}l#/7e8<=s[n,KfcMJ1 6MN Um33jj64'q`r/CEodI9T 6s*XG S׸YEFZU@@6oC%FEӅߺH`Hfߞ c8YHy'Cg}9 RǪ3<)e#ʎIߤv62gC1fŕB+hI𛹁28f(@-umsxO&-s Pa!R &*rh't5K?X׿2?*XP()A퍲@|clЭx<8 ^` RuC.\1tZ@mQ=W-/֗NE sY4ΨvB!U]-L m+~2d"Dh ! C͍ 3ØFʧB<*<ӍLx4wҟ~_۟ hx%HJZ}> Kd}@ tzE?i Gpu`Xqg TeFEB_Q.4qȐ/G#3M34իb0楥94% ^p3KćQHXGAS:i(G~lHIkr<-ǝ9˰I!+cNQf5:7ko+]ӭK! ;UݏXc✾C7ox9d=B'% Ki$NXǓI{Y\qd_MnӪC\ 8DZ%B*з~=42ufs[d)c@dR瞁?5ft>zjS&p/O㵆W2ٗ^5\֢`Pv{j.S8b.XW MW!q\2Z^޿\i.D٢ 7C5֟T`vJ5f`*@_tՃg*Y9b'h%R`Y,אҢ@ORbx@09K>i24o뤷ozk㯯>S"ء L[jB1gd5'tuNiHe,kTks-85;f0vl01z]3Z\6,}t8[^}jؠuTe?>lV!lGc{F+:V]uuE _!1?yQ>1\aД«S]J+?z6}xA6Uz=:9ҽ}ҷ/^q} UO 9Ȱz UKJ UR _T?=f.q4 =2tfKx>l\b,G9'Iq7LB YD@7T K>5)*9`$AU`f0X{C6=Z hn n]>"DX;)BEDLsJCiȪz'L 2~#$SmpՕǦ U#'2-3l!Ӛ/RyVb4~rzIjl57c๽F80=53760J(FUo[C3DKy}Z9x[Ϻr{Q"esA;YxlMGnХH%Οx@ N$P^ӵUwT: AjW_@FCuV9 ^gYFrզfmI w쏁N~ Yuפwek#kdOQr*.*fV>_>a .HmB),Ƿ@D~F)rչ6=;wFgJ3fwcxs? RK>Ro1[cqtpDifHSH3u¤PQ]1 c[FD!nݺєlO܁MZx;T9RM=Tވ 6][G:s]b&j$Rm#:[8Ǵ?R3hs;&d c?z{SCkͭ%hufه:SGt XYm*|Q煑F^ZZgJk"X)-Ё͖?]hC;T쨞5fF~>9p͔%BEաut&TG0rfJi͖!rs'dRsW M5HT): ljwpC<,noǐ6#CCRเyFi2/厐pu?} H?ly?Ƿg^m~.CvNz\yZ0A/ͽ0;>]ȟvtrYBh9 *x h  ,8N8H ~d;E쭗 E4Fܧ%bJt)p*g/o.֊u–YE : iś=TAȖT dH:UnM6chu iC D5񰔉8g?&0[*Lֺ พƊ{ d}kW4;۳01k^R@䎪MWD7/`-9gl~ekLm xU611)F5/iKsC־?e ߺgFtNosRt1*Qdh k }g| F-O/ވL A(NSεee]&ola8úPM55禖1#oCNhȬ*VPfۆ"UǚMÀ֯ZS0-c rzdϗBˮt%> LR6]9z鸴ʒRk] ۟z2)[A#+?~8kرA:h'&&> M)^_6p2?;+Th^!f1R#L+gpqds%r+ ueh+r;z̈́Y:myͦO~yeMH@#DEjh'H8z6_މQwE! rǨ,4}0xdr˜xrs絳dgg0X>-deMv! [آ$Ubh_#S'RizFa*)|ēw8>ϱ8(<HXJ:2Th@‡ QS ~XQ93#RZ&Dk*]M>u{`Pb E鿣?߾}OH&qhB#VNf< 4=6wןdzzn3uD9h\ma6ASbcb- Q=K.qKYCRmmt@rgϚn\ϵ[lf!HVקfoc_.͡~WĩJ7@MK}i怏Px4IhHQpӨ['P3s{~єL?sv>G̴W2@2 b !⿞ G;ʒ#'iz\|!)WeƢb6YmI;,N =v&X{+`uEꀉP9< &aύu!vnB.sY~haUmoleøUY㪝m'kE۴^똮xݫtFVv>R}UDP>٧/)T3m=6'6YU4cyLRϚ9Y"ZOظNRD0Eh*x5Vka^ O(7I?~kۣO1}0J#tEJF1`HοblrƼG+"T Y+]SV&rYmTmÒP",U)Ѯm ~(`jo[Jul(̪uZlB+-M>*|wAxb;bv&z~)#/XB ?xsXF9 _|H;Mo=lKGvu".P+>Y\ʅnxlud縫yg$EM@3(&M3z N˞JQ DiM$D 0wtB`DKEG$ej~R"q(E#n/qLQ:lT){n.G0.T2ϴIWqi,P0:Gހxa~맷o}Owʤfh4}Ҧ@FƩ:E P=QbmxҐ4qeJ};)$Ĭ ?"@qFCFŒEXK2Sa;؎ -U F+f5{z*5q E?~_1cFfي7}_f}jOlMc_~^N"ks3O+NM="P BR=Tɇԣzr V=㜃ZڢRC ?B&EAaQcy"_>R= ןo!tpD#׏}_O"xбnqk; g3dW5I.l2`]n8b) t}jE׆X@Go҆i#P&L+ԛ-d' nO }:;`F!QPє9l-N"RD[hyuM `dڄUQ]<|_ uK`틃Eoy=[}zz72^[@o؆.-vzD +A M${mYM&ĸyWpBgi܅S7aoZvOxϯ_~号gf4-05/X",feݸU-^D FàAc(ij<}m>t~b!>`߰V"rELd?u~_t4޳*’YFԈ*ن;ei7oXlUyASOנ+g?4HT)pB 1' bS:( &=`(!2ϔYK].U^<C2w,zEWr!>67ُ|$e3<DtP튕c`W~bV+щ]DZҾkti UzB:Sh}sZ]*GDž #Jd]*]=yP,jj.UFЊڻak9&?glRP+xmškwtMM7*ց5'dw^#bI+2Y=LAJʠ g}}ٷ*Bx,{&D{Ƅƾ;ikεפmC>"ntni˶lCUK;ԧ֙%׳aK1<ۦOX? g⓸>~gP־JLӚد=VgO??ѓ#TGEkd;Zw9fl@1q@X1+H/a'W̏knjTY~UQz]=i5hiYV),OobevPZ(B|D\\!ve=AKBI|BqN#b9wgZk ߧ+׃˙ j+ O~@pGJ[z:6ֳUxhNSx TyqQ -͛D<߉wM]!x^믷GemHSlpCUɳ h٣Y4aR=F(c!wbм43>0-s (CsOǦATrS( է)f-YUA ^;[SVO¦]CX-T7pz.AuRѹYݨX:?׺JæC86]a.; k ed'KB8_#:k op:[W;%豶tBؙ?ٔ`f4{A0c5OQ80|}8x^N>!(PEM'%K:ֳMʐ0XrX2k*U f?DZLƑN =. ^y6W>࢒=r;8yTYc;z$NN}܊ aPE&Q 58vQr-܄_^V[B{ tQa(QxH+/-.N- (n"6_FcĸΣNȦ3r s{TFArtmD[ S9G4 ϯ\߾^)SMl )?n1s|l7gOp{q:Gqi+ zxD^9ZjRo~T:矔l9=`UsHn"%3g蠩&nڂ'm`C#ܞ*M#!)Y*xSc^q) >rtX^6;j(4S,Kk9})G4=bpcU! fOfS /?%{X9>#DU%@KAr=AGZ2Y?=I^Y߿*9f5>dX=1lYp.cdUsЅjl| xn+[:]75FI猾T"  `N.Y> ra m?30`WJuI&?p}:gtNEi0kz-/i",VyyFPL *. &5չW =p rˏh;d:UW)YŘ*0ٝ[=v fr)n+$ ݅e4Q?bM(պ?Y=ZZU}ه10U^Z?DG'-8^\Ữ\|>4UmѬ9I f9f寊o `mJ>md5d.#"@4;K:2N\AqlܸeDǯ~1eW9{B.ӤUKB2s[S)6.CLTy6S߶FoV.f΃7pP6{%WW( K1ZѬرFBv 2M(gGYWH~d&v[(CԾnr9LsK254CӒDw S~Ġ0Tvj2cy@ڼ{Mi`N:Ոaz=;$iF#*zkl-1n-1i0YLWI VQ5+r^Ɯ42h*tպ~l"V)x5`S(uנIjS>TY>\qLXBO'6d!"p`Y[l&t0PT&v,SaCO^7'pr!}[[SOZxa<kBR8 'ѾS6.6Od]/V$`xs&F-&l( %d}ƽ9N].^5(ke ӘfG@S6i4:{jҡOܼ媁sdWqG1]PŽ>B>l8i4xNPn<vt4-IYVU?hw1fnU-ut, x hIkQ_cP3R]&M3᥻"s8;r07в?K6^oϺ8#rL|_e#.4DȺ5~4.p3Pⴧ˷ԳCM/*ZRԞ{A-  Pڪ>@5q1)D.(88z* 4HWǺTW7!} !xn9$T sF_sw,Po Vz fdҍ'Zv \@I8Ish Ɵ 3ӾCa`S]u'*C2i hé6OgquLya49a/)O̭ 1=t&P~i] K5jcjc0jar@Ӫ|?2yQ3!ϘJВZa0pŰ{=C X;'oH`u+[*0_4->ە<£Fo& 0a_L;'un><<8NfɢЈs-#tXró*8:&FU,Zp1З1NRD)XazƓ84F>MC@4XuQ6yf_IxACϡ;?wo߃mG>s4]Vop>=dPQ2}LqT趠0lEpJJXp Բ*̎㿘r5"2;aq#H@cJe\6sk~GLJ|ChcKٜKt۷}7B;<㻹MV]xփyp ԝ\i̙%.O"s 5ł.U,Z9ob  ڄs :]!xhn`I`*nqBe&dᩲ{ԕۀa5jeaȎ=>s?KFQbKߡoLjCP#,OY 㳭fۯ;qFޏJuZiuWKyX4qx-h폷 }T @R(JaG. ޕç3Iƣv=K[oݒϥ X#|k nȞ'ↁ"72i!{W+MڇUr8eFFAP@`Cu} C_8G5vѬM3l,x=JbfȰ* to:2:k/ol#q"C6hh0oM*$ZJ{=̔͸`zzb?t$.DfIQXF?;_i -b'Goߞ2}1Vd͑nw1xNMvɥvy)b  V{6&?lmýJ?F'+?W,KgDoAo "ʂ`Q[SXvAZs,+}ĹI-q:|/}jPdo5MO)\ M3{Zz* d'7Xɥ]D%&D3xzYZޖE+#^P=-ԬQ2 ό%d5"k mJm/C~>S[0ƿ2D"\W4)ipOlcc3&ϡ^,4\5@RᯮFJZۊ1{IH}ΧlqUǟw$@ "#Y| 0t'$6F3PY b|ZzQ O!HJ[_Je.`-C,)^Gt>:_^?7utnTT9$Bs*f܂hZslVѓﷸ]6Sj&iBٵ" =ʅ8jkFy?nY}F(#IӞQa |MIh.]},KMT;SܞvG ӾQPO_~WX=xZ6AnNmMa/hLU_3YJhra }_, b. GY¯2O:YvZ{u3KMפ]AG<:Nr4kQ%BƁ}R(h@pҽ/s6daY1>qRT@gn`\|]R3:99_,a'/s%(qc 8K4t3ti lNvܸ0Q>7VkvfQQ?^zv}}|ǝ$ڎ Iz@L!S͉am x6S-̹mgu2ԍY\B,nDQKȐEODnU9-o8v͛AQ$ٵ (2<&JY$EKchۻSam_և"xθХ5^~S"iHM^bg2Q ~%ܘu!l4ωz==b2Dd]4OOop4$yD܋N MuчXֳK^~CןH`GceAE` #<'MN%g> K. /A{jxD썳FrB?8]PqS>2:O%;a8𬶆W^"36b/{F堾K49Y.w!ĪJ& dZ߿L>޹u<қ竏 ъ۱vj;ZMV1@?`M yL '31G_3{H(AVw}-C>H4| ֯gz']̿(Wh2(XX[vWU_֭Nh-y?2BB87M4äآaTȽxƤz_/h3nFYa֪- hR4T4sOdž…O6~%A_pʹJ3pbԷ:Ȭ:h: j(R@率[@W1i8J˃YC=VJŪ+VƻVWB@Nӿe6M)3juZ #M2҃OYId~T|eXޱ]m`gqhaB5espFnj߾}|Tu]FdOm`I1~6N &x/u17@/Db ϟ`'w ahCUFݎL ct"xnGývr-[>T #xZmnĺ,@盅8 Q pUr?]/¹g5ETn)* pI Ex`8&&x:1KG1J) w{Bc婩lF}k5>~ǜG$綵*q>nsz'Kv3T*s;\lϙS}Psllf Hyj1 nf(%(/H'qO-d.984BUdHq,SIFa ^ͺvRȄ`Z:UTT (0!F?i._ &jе=XzbdzK?6:CstBR0JM_m~=2l)/W~ c ϙ 'yk6~~ǀ!'څ64KwK*%ljs}8~TƌVHİIuRNphE5Rآ_=)F[b [aOWkoS%i:ESi'1;|/y9Y_ Z=@D)a-o.j0eJOt >xT$Į²*QQmt_$О﶐(*crEWOMHeQRf陌W%=#Z5OT4\SfLA.P|  O>K￱ViLϞ&QO1cx['HmPgH2umfl!Xm)첟ʥh06)`jbx'g~Dxo<;ԭDH(m}xǃm]c<š@6J{l*#JisiMAPc;lK=f E:y6?{{.9S"L ]5ݜ輚Ώd!g'zhՐ 3}NW['wnzD `i%ԛ(sEnv<~hd+5ǃh9:gԧƲ1q3hevIsQe7a(v-wIz@n]oR)`iTlf$qviSPe OWWu?f5 M Aocu JZqh!6t]$ִmZSyع+s DmS̒WPex)X^xFzP ґD4 *5riQg郀 kl.pu|3eA#^$n+GQ6ZCNqc+,?iDӶS2p3m0Ɩ^=b4|.^KR!ؽtG4D٭(##6D&9 0k6YmZiuJщu l8Lnj4sikPbM%֠Y]rɖ% nݯD5(ZI5Q$= sҜ_8($묕YZ(ȓ$ILsnA2 D,̒)[ * TTy3S[nvbpQp`\Lxm*MF_58渧;ڢp`xA8K>wd@h_΃H뤞WMsIh"^"[m}W>p0^HA ?Qg5h#"%#gPosg藉5%o??,%Qnр;a؋_p"pZ}}5 ??Si.YJmxAJ *$VRGg#Ǣµ*DC%|v [JFF&Cea$Cw[Kɜ:{`s Pp=@2_-#碞  7T)~%k2Urm$?x"X ؄ЉIh'IiacWY6BL*>y(0R2NbU ;W~^ V%Q7iNfP]_<XN Ӛ3LCž=e=BQt/M[4ᇘlw]'[*~^ҀK>^&j@oHHFy{nNoMm SHٛq!š`_&S7 ~KV$ P 0o"!jo)v?,,ȥ|e{˓/{Q'E2Sz:nMtΡj[CO_f?N)sDڊ Ksֳyڙ%1^̚5rq.xŵZg9Xq:kZgl2w'7.(I\gr 6[sz,2ۆw+'_*7uצzrqckhwxj~Qt`X_ALs?k/?tA=7%Bw}~g{??g7d.~M]𢓘E/O?u2>S)|w;^@(89(cb&Qi},3FgjFGNO3B]b7XgA䆊E됍@rRFe`+!Aҵ QUwլ@}Lv5a,`)Bօuu>4u\O^e0L|}eT1nA5\!S@zڽ5DnV@uB= jn0_tdrGrD fOg{45_>Ͽ^???]K~o'$`v 1 iiu ݨ*Z' 90N,\z kp#=4=9ދK:MU"p:%clN4'V 8FwNҼ@fTDsiݭG" jY3Ȅg.߲C<̗C?([Xn [{s9XR3Ot'xQ 앳O3m*E,qC4t%vrFK?7: @tv>fStzhlm#/*'EBa6 z;58(Ƿ<>/_xjcf6dF9lꎧG/XYgm~JЎ*DVw>㉺c.M+BЇq|htpȤRDҤanjLF;R: ../9jpcP%/qSZFṙȨ!J"w3pxK` X̂`Z;JT9e47R} O@ ?'RDL`V6_)R*G:ȷGѪ.!ȭ9%|j@X&K dMk߇ 0Ю뫆xos]u504;rWLerbrl9C#y١!J6uROO&nb;D|c]48| 0" CU34xgr_8Ġ-qZIe RdR)oY ֱ/&!l!:^K8M؝pA$>n W<Eb?vG"nŞɘ8b?{z矿 mm8{pkc/18h[xs؇ uGt4^IqԾ^0`t/lm|םvblE"1gDOeD*G0cȑ^ ` ]&Fg3G9@u~P4 7< k&Y2ʮmO%wQ&_HN {^1N^vUQy-@DAD$ $8dUDCޭЄLDJ:U >JEQU&I$*t'TO/k ~БTZ,pbFg'GK %9ڱ`xƞlXrA=񘆉~Pϭ_o>g:]xgfMJua qI)r/EgMVnZY$ hiI4g`zK5 ə\5K7Z-flPᑻӿBu+#NKҞVs o`#G#Vc{C3FT_.T'y%z1299b/{6aEayɞ[p\/S!⧉`\r\16&<:7 %vUW.\pY#F m;^˦1~0MVdKuUd5_B_\qdzbE^jDll~-S{uXG$q:[7i|گDqU-'U/ѵ`$uhQU- K3ٖ&Q[)wvoHh'p:yS ef6S_#ZguAT>$M~/9'A9^ߍho{ R#n.ipvNEuI>b+7s`uQ$״B՗4Ehl=@(tKIׁ=[GeyNg0J }{CD14$S +#0mḯYIbjC;@b+UCW gQ:]Fk*%J5z rwnԴQIx4>/ h+!oTwUyV'2ݦR. F5k# ^HE;em9Bb)^̰anQ1JP :PT1ұmwWO\L6E-?޾SH1^ԣ M^Vd4tZL+;,ms[L'}h T0%՚Cgn+]#hx?;`MOlGm߰}6S1]F?GR>ODEэ^0 &FG*:8>8 r]IzC7Uʶp^}0$n'J@%xs[QQ: o riJݓg#_ە o%q+?L?J, r:o߾o}cGvŢ-v\j!my(/Bg\"b,v'XTF^wrY]Xڔ4N71n3&m@66PscغR9[q^DKw2]+$XVcU#G }}.2cgK Jsb ~9.<#dzIₚt0u[!lrެ}sm`| 9DyvLmX+E Z5`1#jT3+юү_|x"m\qrռUdFyY/X>U$J Dt4)TcmH  jlh ďҩGqJ8u [0Ouss!䓒z? 0zxwFtfYh*I0e\vgB scWj=a,j&h~ q$;vgi˙5Ssy4Nåȕ4zTY{JA7zh/ԠtΜAVUs9ΣF7PI uQxS٪\/3uA֩5m-1a,mBNĩunq .,af Aa.o4pS1F|y\O(\~1MDSPEoVC_+{W ^?}}iUoMuejY57l";.PrҨi9[Ƣl)^ʔ8R 4YČf Գ`.E}gӥhҧ4X L`=𧭉gH@bvʴ&YOAްX6M12dֵmT25531CqMq__VG* 4%QMzHڒϾ~˷?}ҩ3MAREH]ФyD#p?B;d`? C[pq!Öcǖ+x{nL۔}xBx]f vbd:Oy91[5.MeKFg> 5NH i_)eHJ,lmC7o==wDy4ı7]:w }.X ਣ1G(P]v-/:5"dox2xoͅSJ q"@13ɞAZQ`xq 7 ɚ-{[}Cz' " F.v- \w͎N/|(#Ю &? uqg5𪉹 W:`Cgd-sHwQ۶n_̳KRnA4y+I l@ϹOiG/92Tє<eDY>f~K&S=.mJ^e\z./w0l+ю,WJ|A+d~שd2?ewD=۹^oӮ菷>h1$"!Rrfzcp<}ZwI jbU`1[/&Gl-37/E^;|}dH!HN/_W_&tfji2cCu#&MV=FεQosp1i^O*2`>` FosǚOmxEHp9)68>kcd᱃GNVCB*M= b )LeR' sT3h ‘Sg4n?Fsw +=MR*Vcf="7ٙB \CT ѥʽGtpZ{P7vxs5XPLB=YG][#uGD!@-FY&cg8ˊXTQ.v`Ҫ˸Whalw#vn_z9[h<*ϟ._OJ;2Lt 9l:`|nu>wGfWxAZ]b%jk굺 7u  KTT ,Χ[_^{ md(mCJ'5i`PnokL(CsT鎜'1q 3jBmNHx}$Ɨ $;H9E[ ǩmsAa9RtvTm C4tFd @҇Y(0LvBˬ CQqNҽ's2Ѧ=|'fY^z=gݏ8~ϯ_H#tR\vf3a#elh=hpoؚ^w/5K`^7K.syjp~}~-ROG@0X]'P>юgIی޲D&Kͫ (Y_ÈVsB [-vsYfSVtڵn5ՎJȸP/s zׅi: ,*./`szIij~C0(/w+vWB?j%vsfk*Vm5{Myߎ(ϿXL|[5Lz9T"4\6{5,EOf$J :"*XC^ErF3AnaeVGJǔBeSԀ\V%T}ՂZN=/Չ^UhqfEm׆ Ɓ4xҍgHFbmP!W:i+&P3?!'״c-^Oȸ~'2"+";6ٹ>z10 .leP]эr;{Ll e 7IWb#)%XYtsg478ǩaťJvAg@:e\ @fhKklSVh2؞X;i-Bx'6:JbiaFx6(CU5oQ5 Jk*eɪ6/bXjoyez.X݋vWwr, .c4uC^uz'o9`%b==sdt*)=!)"! ƒVӴqEQM6̔"yCwhTˉҠZ.6!c@N9t )z yiPP^Gt;^l}eUCB'zo|o߲7$PG=(b0WCR ȹu@ccOb0_K@\tMw,SvEBm#Tc"QM#M>~;RdzQ=Ib7Tqq< 8x"r/s=xU*'Q١U%lkGzkdN'^* !ۚ!9h_cw+r= I;HʕgnQt\%.GZ ocHVEdI;);Zj,Mzs|dQx^]DAmJL v7 e_|9%~׏_8?>E7?0]}5M`XVJjqg_ZI ҬI›"M3)u 2A!/cѤ-̚ RPƂ U?Im{[HkBT~L؃ԍ,h6ެuNe0?SQ(̇GlCy]/GD'Z&YY[MrSe59[xl݋E_S &&q;oe#b1 0 Ą.wS4kpF3!$^jKa9`{9h-Oohп"ҨII=s^̞nOww\cVSHD21˨f4C҃PVzȈ'wXNVg䴇xխ6Þ܈T3*o> -&u@GLp䉳΍T's~4EF]Se5o 9! l+jvGU dwuSKcfC}Vԫ|Y@ .]͎Qv_(<pN|C`C!;e;Ax}t{uJ?}oOt8LTj+{)l䜝qu VT44GZ(]E[%daUvd;Y )&%rDnef}̒Lײu?WUPSR 1aѩ"h"uzKl]eצXs6Ȫֳtd&6a[V+|׹:y9Qۉ+Tg]@:z Q7M4Hp3DKXdiw•h l"g-ct|dGV0AC؜(.|@i?!΍B1W|)P5eJnoR˒o"a$1}xB,jjP|56"5DŮZɏl,uaE=EzjUE5O +Lk"wǃLJ_!J^l83txl4¸(ɍQ"fTsxe[3AT΁R} jz<mIc%Y.v#Xlc`.ͅ: H_9ЬV0\Rt;pďjizOIiшYX2<]{V_?}_o_ˇSWO+MJT͌sNrx4J z ,>L栳t<ŧgBalVC3x>$oJٺ\.Ť۱k1'QVhӱ!g0ytֺ=zLڝZaP*}}JoboOg 8 ^:@Y!30yuh@m8^e s1`aoLCjU^D8 ZN`gjZhѦ_-;Onix^k-2۹~*ӳU* P:g+7CuVϐê>$oG}!yU/(˹h,ׯ#C~YƼ| )ؠm>IxmՐ NjMEZFqP*E[5Q<^˿מW 6j29?ӵӎhXlBIObS 2praxR!Y5ޒ܈ N˂Ϫ-Wiesu qF2=Qf` ;)8whUǁY)2Hnd\OV1Ns[m{*TL3.zBo-!\gؠ͐HgO7" 4N1 Y nKt_%^|] DMjuWUQYon3sw0YٶךkdosRWA=6lZ)n"غ C$@dճīc%4?89ri\ޣxʋpoqQ=zvI Z>|랈`oז)nY_€mR\L [;!,qSRH33ppuh!N+S}fe0HPzKZy̜ 7f6uw5uȜ{&Ga}xL6 (&ӕI5ױ{r^uvN39ʼnRVu{ #=+6Bk-9 ,4ˊ2^+el1++,U燢RZϚĒT9l۪ Te%єGA=NQ^#B)\iw+w~cgn|Gꓻ庛52;νӃt9H8]wOw5ni1k ݨN|ƥrX4y͗ 0OF8% *'y5sx? 5MeO/DmtB=co()֢/q@%SwsDCRmA!k"S:vyj[lsL95\'k9>>?Hk3=CFl݆\[|WjW>cBa?f!2^mmXBq!D IP}41ken|unDG6`c h<"eO.q};g.I&CpŸ*9DGv!bz>]>~{C6LIqIThHI DY+VJ2!v+;Me{q%_kocpI< H9BQN.SuN)ҪI(v==O7Myq CUH'9kFȋR [ؼNMOßƝ\Bykû̝^޿ڼEeiUߒ&!S6ք0dC٩X z1Dw7!hPKX!X-0~r7{70[ Ek>\w -3naVMϔ6ki?Ve(ݮNnuú[+U֗{ ٝI!uAb*a(O;7KaKэ `Q NNq׃,Xz(Hfث=ExR킓j;Vޔ`j+X5ӻTu2 XX&Z26{tN3W4"՛2[ıIYXC)Գ<.?Y[vO D!v}]SdTT= {iՄ"%y{^ D~fhEcn7_R24KxZdGuWP!ݹE/8D,YiV"JzT|'dW?Z]}@q|y-ڂӞt?3YarR`nj !{Tb-n&$6ǃTnlWfi J8kkߘ8|ȘFP1'dwpKTJ-Q@Czr 0 gڬ޼,e+@ EF4fT#9~x 3n!ƻ7cd &r6rXlg8Y#z(񤀉آ =An):̾՝\Z/:QxDA00h ڛ^u #ޫT9.w ̲)N_M&nOboǗIg-"2?@ÅE AdQ.f xXl<ǨÆٍ tE  cxNb^hjPFuBQ(C k'DL=)g83Y;ZjkhеUZϠJ.╬ v$ }|iZE ?I a Zhfdp%tgGC!'tC{iv(0֛GVSM}Tх"ED|m't% 1SPQ+K Je`ñ,q ĻW~yc 3nz嗗1~}k-׏/K>õ)r.<̛jqXcPInjt<>rF*qk;EwW'eMio^c9YZjC׸|WZCjPd]ӂϗ)`-'3.MR3Onگ4 P rr̉oqjP'VĈXIsPӼM;'4Bb,M2eEkou {8*(ض*`i<[5#K_cU){'w/{>d!qoO y~z9Q]g1m(`Nr=v@:Ȏ>>|^i\}Nnz:UmcAͺLa 1x겭'p}]y7zC'# "^"T;1Jn(EmS#n7 "P`QP{OvjˠmfRYMS#67'p]١`'RgF<除ڋhkL%L#`uI~\e'H*%Uju+w{o??Ol?|zy# NZip-:ÌLFCc@Elf,͍&ӾU4]:a{!1 I*w" |XcXMwкk cEr<ΓoYsk7y\?Ź6?mEI˞|yj㦋1? zs] ߧ|}`|umVmFhGo|*9L=mQf7Q{Р{Um.Xԣ +nm=,R><ٷAۅ WERA=IEV_q,1pRv9&u4t<|E<2х3(ʄRTAb-7Pbi5׳n`U 6X]( jW)Omx% ur7bږvPvymK}]qo_'iy1o 1hq8n_xJ O6uϿ~(@Zl6v̎M;e+h9K 6rHv!:) J?WR5&]ۚd<`hszV96'M3XUH?e1H;膷ІU(!^ ΛЈ(ݩD 1nvUVɮ{\V_F.AƪL曐t}UVG};s+tJfwv=n <<\hb?=.AۏdDyMXAu\ lଌWY)T8*T?1EtNNq86z Rny P'^A Vͪ0GkM'j=Ƙ2P:λȀՃu |Icvmc#Υ1c&Ld5BH}8) Z1nWE*a"(t33VBRgGe쵸=<\7B r0D@O%GfRǛ cxJnֳ74h=/HqC 3筿z'IUITf s1uc3d"הG ꢾ( ;^$-ӫ8"cm GK-$/dGuRV)  'Գ9[u=;t[9y\t܉ޖ-%P.Xy"W惪,b<*^o40 ouӣrvݴnУm}w<ӽ?(,{ (1Y_Kc@I[MI@9t*B-SENdn;(2-)bJ9rKb%U@ ^bnVܮQnJJ.3L+>^H}V,!0 0(\_=mㇵΎ,fgh2 VbrZII4~1T F)3D%OR=XkX_{еן pŘDDg͞i2d"d[]pן͔ޕoxїw_*/{[FJ\A1N=ᄆu?pJ9 vqk#4CGZT5V*US3[ !1 ØrlnW xWbL҇p GoM/L%WS%uZŢ@eܑ جv407, `d3ÑCO>Ux/[㿺,Ss3ez6}5x!&|`}jp2l5!-E0"'bDݖNR"wCxWv~/__ӧ40ʑ))ĩyPb 6+Sw;X'&}'xŰfsmf+}W<20qV(!2c(DP\6RW`][X?|DW#'*n|vU9uh]ԭy7 EL,^XK"d׍?7u#̐ǒeBYJ/!%!<:a!mDj1VkTB&i-TmnѠb~l Er'6r>?o *Sc]-幦-bY_~k>ON:XC. Fp$J9vxc4$gW څmUMurB\,do DQ_sGYo_M4i@ɳI. ʜ಺n"TE I⪖@AǶ^vsHqLg xiUu59jU ̍z´ sR=@^(#kRO ӍxN8 /LfUAf/NEGj"р ++J,[l_DD٨/?f` ǯ_~0mt66ErC7QQdWydXځEA[A7mƽZŵnnÐh&,ud-L1z ᙡ M_GzR)IqI7 x컨{gɦor+B&Tj +ƛtMm$/tʖ{%C6`|U\bʶd Qov !|\NPK1oPa-|ɎuFg,1[S &sdIs~}tAOguM~}w?>?MW;Ĕ'd 8ӫͦ'ϴ@nl&Cq 1[gpt,H{zㅳBCUYkf"l &1UJSu!(%MY4otKu-8}M4ǨLĊgp -VOˍl$\vb͠=0iw I0LR`&Ι!AӠ р p-=A: ѭz%a#k2p9r 71I Ip}<9y1E,.>91RRHvOrUthLp}&ILek[k uوw3d79[ Mԙ{|xv~MZw)Xqǵҥη^ +xWPO}2 X^>!`K {_P(OT^ .O+D?TG1u-PQsU?9Gy_h='= 5ݍ=bJ%A*aڑ͌k5գ,;VNbd`>K.^4,ưsuk&D{ pO/~XWc-alf{K v`hTz]j@@6cS(ƪ7egũ1uc io!6XYc@!D-YivҎw6[c껯_ÿ8=6n,`fy{›7z@ro+j}>bTM`( ۯi(;%~l Ds4>KKmRA%IRXi';ym q6UB ce4@IW Z>hlKn=ѡ9]T`&U?:`$.n j-s>Nz҅_]G P:g@ÐMpÍ4ԩshhd5g@>#x$'ΣfOT Y7p|T1`Կ㇟?|}yO/kcK2 6s키޼j ?6# , ^9[#X:j~^;0S.n]-).0GN3t MKdW`gw_[)I(*G@l]KGbfFy8>bg̞W][д53W5l}@7Jv\egݓ#2z# |Bڶuu;nUq/5tp) !_\Om%(FbѸ^>}m|8~ ンu \fw]Mrv#LK'r5PܗzQg އ%:G%uŦҭ \rF6f~D" 'ぶi Nr38l-!B7N;7r1-nÌ1 7362 (MHGhdSȊ8UXۮ]M 5%ccqDg+SߖQoc]=Q~{Z#9`N!㍜Ԛ-NhmuX95MeMF6:9` \z:WUǘ:NC sQTTk9&a ,DKfb廗{e鴵l =wG4I=\_޿Ӄ$;6O ׽K lГ`:NNTKQgG⮏+z- 6ӵ[jENŞgcY`OA>1a};uNB}Ƅ/Po}ZZ 8ۇ}SWl/Хfn# T߮|M] eeg$6p:+:GjP3Z 16g:.dVGZaڵ V'Ǻ#(E3XFmE' a}x}73~25JcH?>~~m5?<6@kajqD0ة x6Wfjy$Izqg3 /2}@N"u0y&b.):fm WUiҦ(;CzyoM>T&`R\xy;PV'YyU㚆)z7cMІOKwɍwk's)kc~ qڌs؟5=M2_n|,J|H=I%VsnW6Mr+{V Qk3IIjw?&}}#h-gF:fBaI#ұv;Z$x c-|>Њ- @uZ,.X<:C։zBxf)g]# uX } x 4;=^0,=q;WUI?sȮ=;')ɒhpn1 b'fOr19e $ {&Yd Įo#zS h) LO|#HuFЍ0"EFۮ/q}T9? o?=%|yAn<ⷾ~֫͞SSn.yr,:~= goK%HvScOsR+R%#N.sJr_ Z'Xy oq5:6E"N2[n&[l5 j|v"T s2?Zp%*Fj[U˗1[dõz}2ݚyA- E$V;l౥6olhWY\T|+0NVWh3-%N!M#[}eiB但4gNGa)B -$ۨs޾>k1cZ6־EݰE҆fa#7\:RTd!.S }@X7B͸*~1kss?c d2W׍jYIDG--mj/$xGSjj gH-0Xr aW!M"qi`7i]n[/0 LXn30Y4S}zL]כ%%N7> /$)Oւkl&uKt/ Ha(B"4[ o[`bm`C%ElΝ((5no51K/NZ5Mԝj2&E8Q}Oz ݲD㌕!'lw_+b2V=^Uсѭ]Uƨ6 骖jRpcYudfKJa,&XP5ogId︆9uþ=)jf6,^dxIǥ{ݏx"_~{ٽ*^Atz+=q udN;b=0c(c3ry Ԫ3:x7rطT ɟFͫiVsgX#Ni @kAY>.X#?UDG\hs0ĺu޲d&ytşItԃRjV@zF,:PA} Qm2S MPHO*WD8? 4L2z#M!8K? =e{旳M҇~~З__VK;"au۳b7{TŨqam0NI D7לgnw4ʙ;xdl~3gbј$XBbdcuPƸY֧zCGav5qljlIhS %,῵ $jA-[(zGejbCϺόtT B[D?WsF ,iqj0!Mg&v pV{8hvo}|tgy J:]ҷ8"߿cP15?QPgo}Tt #J=ѰY|ԡl`IK>—3!Gy.!ƍUĄv!m z-c#6g 6d6_^Usd9 M7랲'#8 F/$#FႵC Dߝ7$c~̸߯jtS+۹ Jah5Cߘ' IOUbL, xT!X׎lQk&gN}'[H<̟NJ+jmgQGaxMoV14៻7JcLgٯ3Fa<2Rp!kAv!'gZplF6h^aBk/S)L%b2d4OTצN>m/]X2@0u׻zz9f-9ݲkO& :*0Yp;ay~zAA|&9l/CEcp`Ϧ;Cazr5Wg6o*ŤX(Emq^4?<>3b9E(^#y%V\PFlUض(SUƓ}֪zÏbS2<u\Xlaq6h~4#8eiOЪ.QÒyBBA*{J%0AZb_S GU,+‚L\M1a )u<)^1Ony,ͷw0'MKT_'k}ˣ dObq&|  {d:`L4-hs"OJ G6$|?m@wm $kﱇ@zuؠQMBLAN5:frEGĝ-@ȧ ofRVr0BYUX\jOKvײEO-U|{ONi1 ) Q12ֽG]d2gHZc XWl=5Jc$rAQfFyy:Lq"o1M?٥.ɠuJmuPUj&m *ڗ94;9NPIо|lrvGF}FGIo)U]EydY9qd 5[ďuj)`SV!3[?G{>#QVNgz ))k,YBB<9U}sxc%Vn&rO\ʷXw$:C{\jn5X?=DaSp0o~Դ7ZI <<"yomQ" dZcqں[NbLj'ӦyXYuœ&ԸY'h9?4cuDj%i Mr)H(-LIm> 7Ƅa`B `0epTg%0O,o&;\٦kƪ75:eYPv6Q6y>Gt‹8DTLȈxb(p锪Q^si_&Wl%ϴd^C8D,|~]cu$&ӉELt-DOO_iA<}<#* s0AْGbE~sɦ7҄MEP75 ;"LAK aN8cw’"MHH4ņRVq۟ȫXi:g2!VEi`TV<`6d\IՖܺrh@*\|=zG3 VWx4I 0.Yq7E~W0Su[9ueǃ6i] :Oenx湛 Pc_r{Kjݳ ~ȯy8DLF"kb) |m4xOEbf,em>!aP$u VnK܃n8悇^HCB4)GiuX=jJXVlkk$jaFc l̴ #y&9b(MM^Uد/,mOޗ!mHjU>zgERVϦyS후&LyM*[R+=cVCѐT?tx9F c K{XC]12jowJfs*J߿盜*Ìc1 /^dbMBΩz%ά趸}sNFtUc؆ ཞ4Q܏Tbb^Yro,,y}.|v&#X3(XM,6&nUAFzsbhWPwR㖆!]t[%P0_mN>Z۶Ejsܗ׹dyEv]bV ARb^-Rkpp:9B&79 pGædwm/]8!ԬL#_>|__~9bN%`AffUU Ǹٱ2U/%Fn6fllN‚xjE3ʳD}zx!:또N% Ⱦ)ɌF"Tp`<6Qsڊ+<ի"/Uס_Z+8%I@g~k IFk@=%rF]-I/gke~O\YLl4Pi4h|ufw}KtTA v`Tٯ'M$z="ۍmeTޥ чw=aOo߽'tYt5p!uV@SN /Ocb8]lmua}= V];qjֺ}i 1d5K$5ú\":gC~ }uE q!Fs=\&`3[5s=SjMշpEl1#[hPyfCvbo1d mM롅@W3+}:t m: 1EMl4^b06c2[FS}#t14iUdYuLCXę Fz,i޼HG5xaQ4dS && )kgu3HwbZ:z;}3`g^m\&)s@ 1G-̿|ۧ_8(Mƭ5>>Ϯڍ+dC!M]MPkfL3gwAN=C1ZO'z g"ixQ? "Y:P88HQ'_ev8S:iUa\v!_̱ }2kw3^4tF4z.+^/IU[Ƙcߞ\,r `sb_d/pX%˘"'mKjYA" hx ښECy!MgBХ xd}^ٖx?5$һwTp'G oy}y0^R4Èb gc^A)G2J9x ը7FM7X1mc8䠙wjq\EcV UnLcjyݎ.N-8=mŽgH$K^@mKk-nO^? &l83#ƎiXhm8Ļ&Vw b^wXqCz awj+J±4Gi1޳ adZGFCrd4T-0DLÌϝy0,;8 wBy5zw?~~WKHBkkD.!a(v1ЈzswBA?BX;84;sŧŢDϼ؉1 `2zO.^4h=A~/tlg׉;s$HDITooPXuD(>~V{#!JXbZ6r0Dʰ _f6rE3>j0ܒ51 wU׋vw]Fjc ,xW ԳX?y7BT 1?I(5%Gw.1O4";po7aǧ׷_BcǢ"}ͧ7šQ9." _kn'0:h'9;dOOBXl_7U>KKɖD+1R~?rvg@n̊ ]ʳ ZݤƆ`y=ۘ_l[)ZcLyY\7!<*>-g.}~CWL?<Ȏ` "랑`'d@m#d.JS6.DC _ ;a=q, 6ԼP=ByL# f鵴 ' ++ M׎'3zC#vuZfه#ͦ|=ԾrLdTU٣ުZ1~u/W̓C _ܝ60,iYr "X+[_,lUe|f:Fn$FV* 2O(-P(G<O*O_1X>f}>M]^9l F)9 4E7Qߔ,-bTh2rTqlሦ@yK(n:4|UeB0f]DP)+e5#>̀N E_LL-5>eړp6LM=O[^2 bڐ?#z])H_ύ UAb++~% EvQШhz~F1xj91sҫ4٧am?>0uLu[ݽCMf!w?_>|'Fa_!a[[ W* oc 60um&V~Oy?q%?m^E#$yHXKZȃ},T)Z.L'cZ!O<_P8-ۀ䪃3oS;tU"A4FC uF&g'5ȞDz=P&jNOqvs cW7W/2LfjPnzM1d,EH@O!9u]b5Ź΍XP8]U(sTVw؟j 0梇%fwpi4@s/B>1OoϿ=2m@]\@,Ӟ#w~KÄNqUq{CHV( +m}幙Jػaz6C1IEj@ǣG,p4e R̰ږVSN~S7`]ߊk"iw {*̔h;,%;1z_uIKR*tkG4\9D{ZpghLZNٞ UeuqzF dȺl4Kt 6l-Op}y%Q]Bfw?g{/4%8-+ ДT9ž9-0 X',314v' dщ!U5z Qz}!$[1Yo27^IZ[ ^&u;fv\HrSgSdN, 44D0h:|'H5qfe ӹOF̻3HL`lLv4i0q !{Y",'k(l%X<z)< p#88qPgv0_>s!.G[`/!ۗ>p'('7-1TqlIm!5.D LS2:AO-j0Delz.-l#cu4h`:wkƠ䑔#V]L\wEԀlm(BŒ6B7f0 c8m1vrQ[l.+]P9 J%^xD6> 9)Pri2+19?4j1u/BJjnű̀_= b;&IQBzǘgwr#g]kw~2Gח/OCehB;F+oP~M)`){c"I'T/fzPdP ef5K8pO!h30 #"k" qF`\#mF=]tsfo8q\.MzE Q__ı>Um8{`P󹑴j[OnJwsT-n^Q$Ϩ!Vq8+tCal!uLUIAmˉ CTpsƖna9G&b{}K[& )yHr/%|?{Ht\!~FS!lNX8 cd9@}l'ր76{)TI7%wb5Ih2B?lue[B$'֌5hjVgcݣ' :0L?ֈ@݄*pgHrۉ(#?ၸC% #7t$O4hOĀ߾RZKI4W%YՅV?GPghLJ5ݪd Vה",?y{CN~!F&X֐k!}|yE-.|-=|`dx4c)sU+dCk39tm}H4ch1Z::) A kWz4K9(,/FKA&Ӑha0`4`B L@.AZu;gL/An4iP5jO+<+1 SL!:#Ǻ UcTW`4IAc툰|]R| D]IFв^1ȃ}BV/qqH}=%^'qxJ27 piҰGr5cf <rC+)فq Z`~xI"3baUƈŁMKho3f qu5;[][piȾ6jZ]KG@}dxϒ-y%jxx[uúsVә9i % od:CXxRlhBٓ=4WWLX߽) Ks..6+ "XgSzꆲ)B8oAXfm5`eJvPL)U=+ÌI Tq:?-I }k5lo.s0*><>+Dc ps[xUCD8 Y?܌XE.R [< uӈtӷU y7T aVIgnkW*:/6s.fbF:9\ʹKN2zpNp+(&+B뱪f @K -~g!kDwJ Dtƥ}#`ײnS|r茄4U&8gdO}zGSl 1+)H+-!}c٭+_Fᓩ4oD!$7kyV8Ps8]"K ;a#S;Z-&Q|$A{&%#Mil$vODɈDΦ)Y;i_ru6dʢ  6ti&">zqT0Zh7nħgE,siORl'U),Di:¨Q }fqüGy?Ah OsZS۷Q\̈H Q_$oWCF=;fǖ*‹IJb4=1\2.Gojg$.Ab}L/yOYEݼ.8͈"2Y r^?(a;Rcw#Rن<%[LS˶Eb,(v hBO.mg3!Izs_'U &EƝ yk q3o@͎̲cʮ|m0 s pQ㒺nSSs#vu2xkcV6 -_|sդ7(|zEV;nٍ<%"'{󩷣b<|u/:ݲ3SsN>ip/b}ͱtx=n"onQuxKROd珐K<4B9<-_7)[[u_2kR67Vfö́L xv4C?ئ]ɘByC2D3S7^-O:Ykc)_!E ޠ_\3npMoɒzm6iNxa>Qt"='A=e[<&NR4dr*jSloJ˘MAMo-!{f1عÍd@eØθcFFn[Ej T76jjkhS.a3Bݕ]˞"X ՅU>ߚ~7c}v#ܛEX78(2d-jh: nRbN=mN3P0H#q.[w+!k O3\h\vEA.\<)AXT"z[ټLŮFAmȜ^׌./(t`Q0NNw_un[so//XG ⇬ym8c.h>rd { 2լ [ntzuزYclkC03ú$7Y}:)9l#Ov`Q $WפSW ucsC {`꫻ad}q;>C _ s`´CL+.ճVZE5G5 uyb_¦7H6a7Rt i{'/1@L`fip vlٷEx/~~^ WB%:p_}Xh=d#b5t?mU0W|򬁤\#Z]`=cbwax -$2Ж$&hlZacEZLeLuTd24ZXXs7^IOE]ku0eC޾]4R ΜBgĄ])GDj�-/Lp][;jSS@bz_{!_םgVL,W}Vk ҙi$Äwr'Ks2k\o$?Q]c Ԃv5'puP SY-k׶c\%nZ" a"^TCf` BEs]V*vP-#M]S! v7z&riiGVcqؿqdw_yU%V Fow?gߦ?֎D>:k 8zPwBaF`]RKG-Ѣ^CUM[f8q$2_*'g!B 芽t;d0B}ҶQMx 1D8`b$D`V4gSµ93"k̸F@|c^iC^%D#1!w_o04i1Q)'( {Gix!.8EjCX(я{5 Wv\v mԘ<+ϹK{DV~pvě_?s~P{})X mn6Lڭ11=!4 = t -TUL 񾤍lFӎuo,D+6SKNP.1iHbH?55` lp0-$sL'@(} x˗QU"h'ujkCX=-W_(vr2\,zք7z#$"kMڤuQ R^oq1l pm |R0*W>XK4E&nw?}{)fDV58 i1Q  !KԨڍ%4+MJӽ # (^hV >g~ऍnjlˈ8ąn91J~&FkamԸwɒfLC쩁*jʹ:BV+ ؝CfC3/b{Z59!Y]uqt)lO/!$xIuV.Τ1VuTGV,-p"R)եKmPG5cD38.B]Tg r;$)ȳ&rPmjjxK$Df}\1RKO97%[Ӆf {]DQm [+Cchre:#.Qխ?=((Xۨ'4IJN!Aץﭤ'Ԛ1i>D[0^*/LwUu! uDCu[o?_&duc&:(ˆ{GϘręx=y&Oq] Ϙ骘wͯv##}DE +&}25C]@Sq)]Nꇫ|(cZ\_ ][X57ctGRVBn>Ru0|4Sj8dBg.ɴ"f7)ģ^;z9ԲO,Q1eL(G(1;6o;Vݟ'~cr#^&koU_)c8a&%3SN,O6鏜ZHUÞzR۪HwFaTQRZU&측7G9VJ0o#QWlrn3j]@1T54a*`>G%*6:9ktjlTioj kgm|w?V(qؔolv4?mi\ȅZEiD%>;w۲sF7̇O|Jzksyj+O|s4qƳR{{ `73Ppӥ~}䀮o,6+)OP38-L%T&AAtscaIzSD4AujעJ@=}ӵc_d!~0Y0_RR/ħ.v“ Sۋxk4ɆxnQW( {uPb6[ PCzQXo qbMDp}mhdBf:ڽA.Ńtƽ^ʝQn#$kHAQUS:hoz?m. ?~ ;-YTDO/=@{y(cv(Q{71Hx S\#2I/:6Y(E4ꘋXm*1,75smE@>dT!aЛ%Y0}BҺȻkE䴘`]vG E"%"羥h!d>UMU+r\ hHs 5(w0FI8}UAd`>"'y 0Y DGR} 1cGKyTr+yE*<)0 ;sile.ܼgITl͚BXjvZʓ/]z<p+YAP#_̪]IM׾[F kfLYŲjDjU]qR%͌YpEY1f L8!qȷǯ8߹&VXez1$oQ-5!U= Ô(.!Chb6 ]C^ېn2emk6&A ɏ"o~ A@w/g2Zvhۗ]3drϿ|xiNa|+{D8)ڀ!^NqύyG=pǺ=|>̇=B}=?VUGwBڡ~LEuSN-{0[ D*gjGښ l>fY Ud|<+P9<,0 Ǜ-!G(zʆ{ÒD>疸CF]ce z7WҼ1i9*Kvr M:2aO_ki$pUU,9cp9Wo{>uj[ ᜿w;G^<׏Fh5T2L0$Sd*5j7ёfY݄F'm|vD@j&Ժ^u߽6'9}n2 gY_a,ڜSsV*œL"<*aۋu>TyI('wn+Ī>+lԟ<݈b[*iKi׃3'z5duJHU3"i g&lN]8# v2U7w?K$=WaC~1Σ[?>7;8@gIDIK$Dd.utv=fI*T3\"X2)[L, yj<3ݞG>f3أ/M,`MTˆ'RaԔ:p5깫pL~(\ܖ\e 5L=|BCNmc`2MaVf8%@DH1(3: Eva(cprl>~wJ] 87?47=1};`b kjU1Bs><&1Ƞlkbd1nY/hwnUdt`._}'Rl.'ɋE`EOڵQw+PILMnN>yiH=]ߜrBB>{ERuiahIͳ&B6T%A{8M W)dP^dnesfQ[sU)Zɻ0rЧKJ V;QՑS{T}חRڦy9ud?c!zXE1qyON'aIQ~NnTKM=UUpڶPWu|cĬpQK\=AkQ#;RwMdvCvǿBrL;}Kqj܊ܐrSRm}SQQOBjb޽IȪ#%zCQ2vƑm_a.Ƥ ƴZ!91t$,`֛ml:8c!E [M]Bc8/0z݈c\}E>f[}SnȧKib;>.cWɖ=E @B0eЯ,UVz_=fS kTC2<X4)"~UdkrZlFG =FoGC&>Hϯ~Wsg=k'i#u 8(6RM]VhfA':J9dA1IK T*8cs71DL:ADlm(R{>"q4oL@sSf=ht<$/F1WcRŢ2Q,`G]*}RSS4tIQlUnU9*v0p="0qL}7gQa3Ƹ*ۮw2F‚r=X&t:kNn^ʎs̡[Q[XT aqAp"I~TgǏ?>9͵Y;ZL|\s@Pft Zm|?T!F䁴 F%8KvGϟ~_??uC 1GJy= aq ܴnu0Z1={uH0Է查Ňvn^[omk=W3<]:%z]QwDqU>t 7ˣjfӍC9|ÜGk@À -j:SO1EXL@F޿!Ǚ-Emr^ؚfDkt.Z5*oX %`[eAEm8p g€.ṫށ ]UCX7ѹPo/:Xöѕ|e#C6޾zl}ESo_^3|AɁT&>N̎LIP!dY4 SO˒K2;bR(Yæ7Uics,}-] KP$,R5k15\x=nuna1u.ѽ,& iF} _p8_U]>1Ji:d)anZ=M:Ot:@VN ,hM0 by@'8vcI2;?p҇=S[ޛg[ϼOIlqj =}08oMC>+Q jlnoh4v)H\ 7 x@ܟH8-" AzNb@{xNBm'_-| 8d4{%6H-+3 EM]FDS6=0-[,1֔B;'rZHrK9H< HHMG()#X`ɫocw[duNo-Ej@;`U1b vL~{wD 9A!#}A\ҺT$ueƔ@>s;[hߢ-ȒeuXTk;?/ 3vZ ϳ)GmI{RSaa̟⼡S7\l9uNFi=Xfhؕ]\ncۭ%tnG.mNX_!s/I&?0;xG1_?D/o݃CC-ZG6KR|H(̨ʎG ܐ..{.Yc+иq1KjpYRadeY HägΧ*v*۹WS![{,qku=X4'ƨdlsq} <#䂆@1_Dm1>>~jI؍$s4u:z@õk?hv.Yg옮K E9%xVl\cb00G[v[|-8aLb2Ӹ43owB8JkS4b{5Hϵ]뗻=$#7\o4OpOUk!MU>ƸMw\u'Y&Qb4U2SquQK T' O]m|#<+Wcc"ZY wAڙNC!+egՅ[u4tO?fp 8KE]iϚ=X#ZlMhߐ6 ;zc Vp2uD FH xCIPh1EYzXxŊ(L;x2yjE[= ' |藜~|~w?}I`Wg0+->: h@E"fv"]z.uyTbE4miU32t]c,^)&q-X<EJB7GjgaAjO2d!֥Tzr8 u „249KIB.xIJ}9rzz= 6vIDsgcKr' ~JQf?<1 ܮziɥ (yg 7ud7v*,TOoFs̻ço?=!x(9j} N N90mmhlK!c~ʰժCk`‡I] mQr|],·{M@Sy6fgwE eX:xy78zZ\r:uWar1jYlg^{\IuL~OG}g೬gx׺ 8WL-K I;!~TJaʫvdwmƺ;Pz:hEbVS\tn?Ԡ';ջF޾~~)?qB6 h )SFwq G }@%u)w%1/lW:l0T؄*KgV#%j7M5NSHC#~ ĺ"6ww+|Q`7t"QE9ziOߓ:oX1OsfMm㘮gCgl U!&+$Rzk>gQ! 吃pTbQ'Zl4矧+@?niF!Gvՠ!5z Z2-@l̬aָM<PXTA8&ڏw| _n Գdx9Lam`nRT#GO}$zF@0Q!6ںHf`W\N&(@ aDca-Klz2q'c~.ꏅG`ir M`9-$Z^vk(bȃd0XQ(-םnJ@^w#~8|iMVѬ|ͼ{tN4%>zztWc̤ŽoM{8*v <MD!##B]M`nY`V` 57oA :*7g&sZIٖqM9:Y;t;rM(DZk[:U^! )71-:dћd?i`D|y5R%ouиGIj.+_fI߷$ D!aOv^].jN&կ /2.:kΈ9l xpcSmCS;KgMIn[)c'Ep|>2͔ 1j1,N&rѮD}w88,ԙ,ޢ z+ 0**H#ft*"Gt}A[{f(T5[se9 /*&qC4_ MNgwyJ2+,:&8=c;p) ahb]Rw: ɼB#\.j-bT\3*_g~<Lw~B|[P&ufm,Kމ`R:8\[IR`>܉前+Lzk)Hڹ.Di_}7F^ Kz;^;z;tẔ:^oK[Fl)@-"5?ŅiK(mVq"=!?cl7bDg"~O}4gro[װ\Wa&e#}Ox"|}%Ǒ'.MBZz6%u}b\8\lG>6HS v: ګF3~B߻8%3D#X >4#Uk{l<7AuUy4~ v_<(dM:.vHc/hV›2mmӸq^:XM1,4ck.-DZ[uA7qic[}w0 / Kc4}XϐW-uxBz%;VOQ|`Qߖw/fO5w8x_?$H~}pk&l:SܥZ:<$f*c7k8 H_<Tm<;e##3F-08;1q:xB6AC056?Ɩ,M4RF ``f,VfC$ 7ɶ0#1&mKW<i,"Zq␡7&SH\8$cg7O!4'I64֪xqh4#\f܇iϗohйGsH^w߸=Fyjޠhl,y/) p{fo#nN̜Ș`&S"#.9yBko@xrS6f<qm:9hmYЖ^icH ~j餷9]9 8U4#85zuHxz;Wpi1E f7v2#g36/ ŜZu5MQEMڟ-T'ԕ!8P?u٥G ]"Br|ٛa +Q ռBޒ+z~]U@OHk2F;˷rh(*_zPM( `<2v:k&}Jھ_pq-FR5AHXD"S: u&I)v9eCfo{y6*ǽ[MmFckn,S>rNL'|a28W&-E3:dI;IH% ?kUԭ%ogrtkY1$Jbiuu> ك;f?Qc@}at/}ִѽ jYjO&mg`ۖʷt]~3vua74}?K ƃ2F# hӘ6>2o~Ή߯; ,!2t g$f'Ts61< wW4P |_ľ73z uR]l=(KRrMRdpJ(JSX5\d` J' {{7'gLE a<~@s&ǼS"Jg[qbgy3y|Pdr{ˤϸGc^>^>qJ媚c2M&3RSA!O"KdVffFIwȈ">̿')G]f8X gX}5Qb.ɐWs2ژiJs8,ם_lUia٠ "MZޱƺ(7ʠVFEŤ^Q j䖉Tf! F=Xl͝,)]{D<}9+~N3xwiSjKu>v|!՞(?z8ӟ3*Σ7bf߾3~_jAϯ~zs%Gbk\k !bF1c 5ezDs1L9r1X&͛/ZUY'H$a"io1lleR"~"2Fc_-BM?D j K55]ǣE>".Ʌ9GL.Ox BL9ȶUŒIOk6oY[dd:jv딲mIaJ^pöKN]8 9e;`#Vc݅HG%vwisAa0gݽިv4Rr%MoLEy6) `Is4I;w$s+F1aF ۓ`1 n#Xç i(r~Ma5cҊQ) ooOܤ{1WBР,& !} [2Sy41*L8J?\kY+?4F +[]+ϭ40>= U6V s6v1gԲ8i!#{:#TL!im`=uɴ4AkB3`YSr%>0g MtT'lt?OK\E<Q9sT5N30 31C*gAhJ2[ݙo$Ց@x~lp"Yuz͈C|:yFjdhAXfTװxލjS4+*OFt4L] ncK0 oj#u`>ĺS8 A@ 1q;gTr[0N+ 9iGzkc58P|]\RQDfՊR^}A8 iZ[fq6 y<|d>1YDOIܢܘ??[P^ *~Pi 2ug"^M~+6*͆ytϯKUKR" "X,<<5"SSQ8דN9B\L2RYbߓ|҉Nṵ̈YWuq $O}sNO/;f $}5"~Vbb;u= Aχ&^d53=_4`L'+#eE-WvdY[rmA=A0f %u@n+| (v;bMNG7,{2Z?|@ &wd?$ZNH .&WrL[ҿo 64]RE/ǤBX!#j!0f[P}rIK`HGШJut _ZZօ B4TYK3辱G>dX; gZx0pK 7 a"dĒKB5t]ͣL "O~r(NdžF|`2i9M?t%4v4obUSv~{:%v}y-  ђ Gӌf_DvZ`!Rt㱍v8ك6 kEO죮 |*ֲa2XA$yRX%@uXH# pRj_I= m y%¨H /&O:3Ǿ_[nD#uL8^B { ks;Bn2ez^{m:??Q6Q#G63<7:s Z^h OZ(k.nZ))x*1(0aL(%"kkeND @U]pVT RjvX֔uaɁN OrZ8; ?u Cf:qnOƜO0B}d J$ ͛垔2&ds>~>1煳M bDKvX&+@Q.!kڞ;:tkc;?k I-8UuOם:wK-yHVBk6>7O=$ئ 惌ReW*r>ᦺ Eo H lg<`ؾ%Ew{!‹qcm_ƭi2c1_>g+.lz$poejӫǛj6ua3XfH/A]ܩS0@Iz=$jn((@*!C>Vqb[}MS8]1DԹV%L\yuV%XT,(P,]vp= נC ˁ!aU#93'4f UuG_8%^`1C#FOJD6}DM]PQaبOU؎쵅\f([F]Hdj)qKh8d $ #Wrf OZxe"!"T`XB9r'26;8gF{fږj֚#*꩔p&FnZh!qmYc7:@,j/]rGʒ5s_>|zErmn/)x[)ӡ0FH[6I wT&ނ6|;-;_=L8%Gu6Qn![QCuW۷"6E~s̈́zswB/ g9Q9ӥ. "cr1zd)$1sGlk{ ׮j/3|1kʓa7%7?5f4W-0ML?T+s,럿TV;QM뷉]{𼆣 C}H`?Gӕ̖# -Q>#BWJP_O)^4>MS*i^o+pc$uAwԫl&rdoނ2.$> 8{ ݞx5aAjp1tg؇q H"C턒By7ۨc˥xi7DqmGn8 ӴIqC\ ɣRT 8`ŪK<޿eH]Uj_G:Ɵu$,A *P.d t{8GqS-2h־s5 c~ijBLZPZ8q͔*+KXfXB@ɨٗ:cDL`3/3l1]E0;y<;A|1K7kxTC nc TgvIKYIfkњ%ZJ|Hf;_m%ڄ*I>a,8oyr!nt'}`ji鏼yٱ#1/ܧ~ݿnØ~΀׏_-lT`%*k(ֻkcĔ~,R@R#LߠBh -y#6sDwAY-|BVKVS[@'ZGޅoNC-I< mmhpe5SjyiRi4ϏL`GCTPE@[kM~ oO3a;%S9`e-6 }^A>.qq)s1ˊfҒ4m1 c;@zDd;d3U*mTO$v߈hLX?Pvԏ/_}0_׭tmIiPuj}wNZc$zo15ה a*pӄ!dS)\ VNe2ɫh[8鴠7nA-"hlژR:4}TxB?iAQn KwX,<\z\%Ǹt6l@lw@k`-ʏi%'uiZGwr@x(aJ7%RS^(Sޭp FGj*yj?KX: va4BPw__?~W`ۘ+r}=yϸ-|gVYDC[Ϝ--I){5OI"2dA)eCF-4B< 4NNW#R0B{SE,e`K'>yUab q9x:y60 it8,25kDQ7W].s* ֮]G^o̹k+ʞ\ge66-ĢdYS$+钍Aowoo}YCT"?1EV,E|l@^k :iG(ԥmi>-$^/<,ә\ɑ߲K8H zLѱ/7͒.vZȭ4JzՒGDUr"C [yz 6' zT0XtK:RangDqo0XmDk[78@o馪s_[by}=2j*B t [h"3%'6"=}?ݽHTǏ Y~OS׺onf!`jͭk\ǀ~l-nػ8TO @6^n.4d$؉G )5vqd-CEX.͗&SK㛀ySz.=mnZ2œ`>Or2U˂c¤="k(.MtY8ќj|ZnX:g%p}m;!~+Y5rK3VKL ''K߶VܬBMYWGuNCw"wʻ: !yn\; ͡~Uuݏo?|'LJs?HDbWeMz.8f4dᆶ 1D[R+)vE9ct1Gpm ?2" fxj f!/lcf'TSz8I6"N اz5v&/oOndCm[d&ems=ڴt.8.4˄D \6](;Rԕ}_l3(hV]T7BTqS!gzLoͳY='jtɤ߿ay~@y'S'5 FM]0Z.6`[N<^ri~Hc_&!bѸb{$:޼fLuBUY-*Ҿէ<7 L}߈ B5N( 9@{Ws:(Ԁx0m7{4LF%r_0k>J&tj S't~Fyi!T ?!?ʬ] ~pH&<#Œt k%:Ph;PX,ۃy6K-yߞ:L5kQfr8IrKEx<3btN%ھ-j! Ɖ0{a]_2GLY͉J)tj3R3)ڋ= Lw:wؓ 8X-Kjj2mȕ0b?lGyA3V^3r2q|x/'МWw<#x=JOޟ<%+]|ao@CLxF 4Yoٰ&V"cEuL,5/g.BLK]|^4qlk&>|~1SܪX}mT58  ԁ' #M (.e+ }EێQ&)-'>ukW=_9tzxWb0)*Vd!v-~t({X!fI{λW#rx*8겈6K`3'fˡK/>sGE*-VdUٞOz N-ȃAD>9SdzvZ8wLs4ؾ_ n`ar# u]b[Q{ݏ>EɃ T]D$dUT-؞#~]0ش!1ݎGS2צw/r8I񣯻h^. WN1ɎYE_J:ɵ1T$037Ypk5:_lSZOubx@]v7=M iBDLg:وom`Fi ^R~*jzS2P5kwMo,̆7ƥI')vv5KQ->&~fܸygnV [ik|//X l\S,]lh5.ZN3OA ބ}\Jo/uu&vr7ɣ=Ē\^jmf)Ox0v-_=29 h}aԭӠ >3q %C"!PUτ6"bʭ6MD@lyiH,JToO1ɒp JG]oN5jgHu>L~le$.,'LgRA؈Ә'Mҥs\23"exsBAi7;BJ|={)q`O1fW3-}2 uIv%Ȗ1:5gE#;9Wc7~{䷐uzaaaISwz9黗/}~g+nstn"49w-eoo`f6B'P2Ipi bz=Yl ED $ɔR`uN*AWqL}Y] nA֬ ɇcFkwNB̩Sh\cuUvdO/ABqE[*S58,bkf5@E{|*Zg(S=/d. K#蚀Dˈc)Ru.IXWQq@i4[RFfx0(Sok+FwSQ[N:Xϯ;Kꔐh wٶ2DFl]?:wzx=% JE!F[^> p;3 4R^m´l]4 LmQ{T0d!DWz}hx7}։a[]L|__yT+;hb%{Ve"wk4޲v\X;Q|ehf3E(0@S¿}Er]BU;pQNaA.X .l@l!Њo^[ϰBlVjIEvHm 5w33G~NmcGTmRd4IgYmݮ1`$"0p9Sj(pCP39lcK{u!]=YJij}E& WI{W'1%Xw/Kx'dߌY߅,8=ˏ//c%;hLtRf路;Q2m\J9m|7$L!`< A',o< qA `:&OM̲|pnCzˋ0#7UFYG(TCkZ(CF9,eH;e Sd6P澇U7* 7uPn Fz^5_>|y{e6վۻi1Al|Z.x%$\j-hvvj%ә^|.fg'ĕ5Jd>K\Q*FT=Rj7Y3n|s_939?a\ H.o:uC<_R֊1@Z|B-X5yz&v.֚VՐ?yU/l|ŜU=HQR{n.wg&  FW%c,1K96$Gs"9̼F@Fw3'Sܡ0C7 ޟt# . O_(*n.Vh~~K;[xe59ךTtipі+) [^Vh9\F:+Zi}lrP48\ò}K™8VI؄'VDJVdH$a{MLd&~s7m&2ʜޓ9H:D _t#8G3ODZ:v 6xɰwtM+yԞ” KUǯTV˩!h0ȕi"zce<;+K$T׋ʌi7ڳI$T|}ֳ.ZU#Lq됖k@Ӛ]. VgQT)MнtP<|p{.0_M;ܡ{fw?1x7ؠSJ1idC\MqlꄂxUk"l=S#8eD2pN̼S|YMV[=Ykt^O%HxBҞYy>M}7kCGX`مlÀR*kfT a )ɜ6X?Y~Sd|ncȖ~.Sn6Gc'WnR[u \欦~js釷w\Z#:jg2%90z@EG3$,\7j`rlz eQ&Ԇ߆Ƒ_KY Qg=e5NȬ"x;Co#l ¼RT.Rr ViwMx;;'rY^x !IP|'jw]=C%1e Y*OShʋF`ڢ ޗH!MXrH!:5Ct' ud~?*/TwDe.{훭qn !/?J$yq=GJ|rVxJt-V`9c&zy6@&كo&&A_ULǫ(M劝vPX}xTv LpUB`9tGyS'^k;**9!<g9kEk ՙ#qveͣY}ϟ|z@0 Iԫl@n}(/`&_0؍J` 8SSd̸ Oâ=Nw蛆t»xFF?~ۗ׷/."Y[c}fH2jxZmHu4ucƉm_Q,5I>w'O13y*|d?´fC<} k@ʇak,:-1X"7o>b!tgۢ"4T3#)+cAzEg=VɊo 읦[ lb'Ү!V#\/s| acA[ zIgy"m 36@Ϛg/iO 9 AoUpuvbt˃Sjcg8V[b6>|I5O'k佛 x[ñjSxx†@4$!kJD_, Lm)g]W4z;j|FysJb`6QلKfc̴vrSԚƪ-\4΍n7yj|i露S83sp)3kʞ:Ko{BbэjǨsFzs1OZqqUI/B5N~xsm"ANv1rA8@j@㇗<.Nֲ69㚩:͖kZJi2)I= u֧ߓK=I\ԞJ4XIB`#'N{|,/.UQHۊi! mg aqXw0{ҷY.QeWŖe`؅Oժ~yP. t!}clP⥠s :MyCF(nB-I ?Pd=) H@*HY !(_l̠R{&49*тcO;1 5ҡu%7>J Td0-߸o׏~x\Eb)vzr :cFWfh2-^oz>a# -fgྫh{=G|LMA+F&njh?[dZd P^\^i3DzkգϟSzǸ%.!~a~~*=IKk#UZ(d̄423Q1z૿zzV|Bk-> dtyRf]Vj 籵#'[d^33a\3Qw0nN']*h&c=oe53eOnpXP)uSsŧ@&5=]GnwZ7|['s=`h}I $yͶt**.i3Rw?TkƔ?wNA{"r-qRn M4N :$CBi͡JԎ{@(Fqn1n~Y\PNn~tq_ƠMIpצDJ4ceuV Ii̚ f4mlx m"{d[Nv.2 yF;延rqz*+ON΁;Vl^i)k}vִ̙TqYoeE=Q1uZb^/?t3\W= I3E/>0mh!R>Piҟm?2 D *VhpyWkA .SMg"ؠބ"럗_~~㽭H;, h~6BqG8Qtƺܤr4be\&$*ˬUye!V%Nmhl=”Mzf}X4h*u/b!a2J}Byʕ8,Dƞg L1JɹɊe^F86Ρgv|G4=03#!2@&yz/pŸ7G|zi8l5OWYŎYMk{?Ha{C犇.n`뺝/k6gd~WkܖhΫvn7YfJwv_4QPɺ"li}hl I6zf*W^s*OJ`7$Dpْ38T5rゾĝc+[iDu-iSi|g2꺆da!c=m O{̞4!#~3)ZqC4?MM@ivu6X3돣op޶u zdfζ1lzJMf!O;\vbb~ihb4L-"DɉB]u EACu:.yovKw8 *դ=H?ӧ]M?!P飡Hz£IUU]_6hF-:B(t;mJ@HHt\N:HQ %U@\0F ~0 Il-Q!"u1 )&\6|,UnC[ +iw16RV\D"tUb8 ~C\kg 6vQ9:3!Ȉe5H͖x}csK](eRwO∙GZ0략4765% K! oKjj1c '܎>ݳM_{f, ]z"c 6^F]̉YPm͗"=nRG1_p#gv-yB&ˬR5tPJx,)BM~?+㟗qL#ŒZ:/J.?pr=p+zgI+7>Łͅ*Niae+ۖ*Mت湪+=?@LPp@ɨ &%#gl8KsoXW釐ExD[{[NnƦe/<| O~g|w4_ouwu~EGO}SSMO0~c֧Qo#OF7bJ؀ed[mVUS't )'/4f)7c[d$z>񤴕95|(l?ܔ32Z4 ]6?k$;f8wMuћ#r: beONս+i1ë@A}DN{YDOM)Tͻ[Hx&lw~^K06=U`Vz~"O .9Z?Y?Փ'~@uBlhL{o067א@UO7==7 |dKQD/oĔއaG(Q'λ/k:P\^ݥ!{H.:NEJҁ%iE[B(hzQN־*V6IZֶI)âJq>J|)V4ϏΠKy)L6z uN щ577^!Bz·dPPYJRZԣ\zx9kv5l|ˀ@rlڿ}ۿ?2=&v+vxO(*۬{ļu-s H)yLt?Le9ZoeNC:{ꙓ8&1ͮs@WўT`Iqd05p9L$9cî ⭢F{ێd_)J .̼v'Rb!Z%r/ΎIkfE'GR PE#Sl람cpNN K*LʖHxb~!ë ?y;Eg0D79h;B CL!e=j jWY C:﬘nu~Qӿ~ۗ__߇k emMrGf̚TK$xmQ@}_fd޽axc&sq3ONTt A/A(81WCXm݃XBfG{,$&sFOq&NyUgAzS)\W%X5!\2ם7q_f7~m䐙g@~weF}ƳG}=ݔɲPaܷ~W`dƣeAw*¾+b/U'Y)ud3;SCw+; t]XWXb9W2A>VR5o\_JFْKv:S$e;n钖EptѢ:80neL®aQ:ZE^08-PRFyh{!lC {jy\!b#ִ#Jz'nFְB'xX=PA=zMQAw]V9@=I}:@وnKuB= v@pDMWRg ^Ru.lkIrmo[sZ׷~_oj:z{h筆4H~c_٧O 2R_qwUTdFt-+!1 E4pk:~" Ty)kOo6$)}|sv.ڬ t*pS/X&1qFc A3˭6L akPcqmiIh$jŏl;H5bp|e ޮRo{G*z&2H'v*]߾߭q] CIX :` mpYw[2Df%"f97K@?=wzWu»_޽w?߮aff`m,Rd3oBW=Yp\ZiMu 9MaGrO?2!.XѵVM5(^Ig8\$$B&Ť绚 `- ؐ5.Fs1Ʊ.8ᒐh7eN>`D_T6}& W*7h(;(ӫe%ęg3#yfx](}P&GiEq);~t wbGæn!ej;5}β. sWou٢u*/̚>oY_U>}oW* EHb=^#;6r˻詮ٖ;?l,ۡ.ݭ =N6kgcF5FM:`̀Z!R% 63K##eg!%(-ذ(!;rMH_&.N hbSOZտ-\H,Tm th ߉x6Gҳڸb/4[tݪr)fu&[%BQn'S8Q.9*5M?fƯ|= `)c{ӟT/sB CcGGYhsuW+ɣ\dݮ!GihwIc~Yfw1;癅SL[P&ۮ ^8S!yƋN `u]Q9|&sgFGġsZ7oL_d%v;a)v.UhT3ٝ$t(3-{U3S{F37V)h L)"<[R:c2V;i3}@GwqȘF|Qbz6wIa si0líάj7mgmO?w7CƛIv<>͢a-uQGzXKl-mS*BԾ1BIP^ }VuےR|@gn(#s"ZW!zZö́+,G rLb?",X35ޚOty$Ff~yG@\9l:6H$F_Ya7G o{MxDQxd6o[fY, ^jsۍ]H4Axx#6Ŏ;;3FX ˺DROu|j{:ǧo$ˌ_o535+OPCGjHJ5&o)imP,vOrp;qMhi^˩JgR*# mwJҰ="@]enc2C*+>_]6]Lٟ![xNW8}U$k K%83TiO|I>^pɾ2nJHoKk Ug:wT\{Fo"F0\GkJ=AQe*:yq ǏlW>kLl'5?N۟_۟%aT?iCW@>-S2۞8z}JwV5 1֨$=L)mTbu~Y*l,N!'7H͕y5m+s[Z g+b axA%*4|6$%Szڑa{OOеj|?WPmԎyiN䛪~O.Gwa*R|wVMkTG-n01n K2pEa"$8 3q]%%+zm|fжVFjXp{fq&q 5ʼnjg݉|&Q^nFpH&${*{;>StGBI O‚]la`0Ӛf}rdNlI_ղugMYha%cO͙`ߣLjūUTm&wQM) Q*ۄ?)$@.PѕkuցkI*aq˜ ~4h8RZNoqTǂo>n{+Hf.ge7E_oOo>cVp;7&Pzbk[mm>yp_О_oUv`MUO`0|88e q/4_@CutUm֭vO!0hjІꝘ9YΉ .x6z2wUy£κ9cnѱy=n!",cq͙[' #NyΦۿ?=߽z8R+(ZI(1Gk%|*bw1m`.X9C$OլQ&$^ HNI~*(+u6*X;e0 z!U@cO,N:RqGvw}˭Թ^˞M?h \)iOB4RK,rkf41)dVXF1yUMǖ& =[bbE?6!&oRWCTɨ2qDʋx =զٛhfj}?R2Nƍ1]Vi :v(`✱d DP0aV͵jcXNb52:#_]XiR%p=D6ŎuKmyjG-+o+ׁɽbnsY@UGU?{gSק~|7yW=?z)D`PN%sZ=ӓMWUe:xߚR++4S[ZQrQr=PsJo||Sx #Dy7JJ+wk5OpJQ p`7"tɟ1[ ]Q3La o<ۢSBXT;[ׯ^pB"{kZ\ɺּb]gcw&}H+{Kk,Af!BɆ<QK}odcLun3ƦrZC(h7/1ܸX7o>go,?.YE—~F]&agG a#(4Q^XX'{#dwk t[n %u|jkǑ瓛;23mc0PRY]!$ufm f vր0g`9"& oq4gӬK`T?QFGC}cND&]X{6دlk8ѵ:҇5&/VfZ+U;E%5>{e7o! tO~ř;KAK!pfDq# Um;C:ûFw2Ajj;Qb4䛟砑f@Np[%$CR%H$*m+C,h# sv6ͪy]Y0նwԩo2ਇ6s:INaSV}]3tX((uH2v}܋j5۹[O%nK\In$396|k5r~5%$i''sX̡)\$n_ Oo u?wO>O.D9m n) )D'bhşx%^.ǧТ?A7 Tpa*3&@t=3*Ov 8qeWY̖*5Kk˽ 6gփT3:l?O~&fj[.dg}MW' ۭ0wVWzywpsaJ7 tghk#Qn]}c)OC G A기Ui܁*!IG\,X2pc_fvCq?"jɹJ6-[n߂k[U@#Q?~n"/KqXՇ;lÆ =:7y[l)ꘚ(kˬ}5Q`h:@ 9ꟙh iY떟=ooOԘVb5_,m_HqDmwm$NccN'~{͇~ןWߨIo606Wn0,[GF`͜Н)ߤNSSîf`LSV4QtQ]m}W[ezusWs 9 N{\BGlƐUJy?YBP?#l&t=wdq7QO2!OG׼@0$B&*xR5nj45=q,55]vxm2=gd\ݪγ]=_ge=N=M|}ROM/B/†R0c66->գ0DlGrXTijSx}n90ifGU( MY`]7 P^VU;ۦpJC{zFU߄)Zx.QhM&Uۢ8"={Zgnrʙqt$Q/+d:xi;fs}D _L9J#6mۿQV-;?酆=}~ӷ~Nrwȳũ˦D}D}`Ra,͘F7vZ2u>vOjx`H^ЏֺB Ԕ1r>JĒdՒp:kEOapQjqRӷB)VNBmlyvl-Of?2aLuu6=.ftR?ĩgM,ЅA#1x@G3!nv7C/- #hbeQt?&3IG!! ^BymuIhowFk]H35Y΄%v(͕9U;% $D;LYDy gMTw\Já>aDu,cvAU`cbA T7 dMY1BI299PW湙Nu$$*W'?2ӕU]\g#J؇zvI l0_9L>TlZy[&֯!L1e2+ZNA%oMRb7æ_x ӷk:+dk&֌)Rl~?w/_|󫖃ĨqWJas6k2.OcDŽO?m"C,X1zD 5\4k"ԬӰ&;o:Y\vg nIA`ۏ-n* 3Q!ns^^_4cyR"LnjO=KLܨc0<Fd }.բ1U1|6ӿP=xBA(Q  ͱrKxߤ>MIxoƨ1͹X[;ɧa|z{o8}ri1-h'*`Oa= #X窲lj+23Qomc?3e8,iɤθY;Z[)clx!DOU"h,Z@jQ]6q1[kzu^M>Xݵ)oO&ѧO?J}3nmנfTԤzfaP{'<0!SN ŋɤbWQ2IgzX<'v`ۑwo6mѫf *șD'_Hqi4]Z/V}Z=1.%l {}^Vqnai=zL抨K7HIXĔO SoWiuqO5>5tOILUDj~E0ϰ̷ 4їI儱0 46I\(= 6X#yJ0TdpcBtC^k8%[8½OE|j Cxvi1ZǣXb0UWb,fsv2ouo}&c\h4}q--?q`|*6oV2Jb= na/K@ TDu\otșrތ6%$)) f6_bN45iM삖>͚Z]VȔD4$K@P\Emg;͏$Ic{:uj:*΢vbMw*`φ\gAI;rtdžfU!&d P;Dzѳx?qcl}UD]K7xx1ڎ͛Lku<=O1[eS믱Oxg"Ĥ Ok"ln=wʉd$ }k֣ M niI:@Y` Q'.[)#..V~() bJMb(v ېUg BM딁6՟T60vCV^)w^t]zȌV1ߟ?aǢm?+ CvA2בȖ˾ZgkB|o&?d9n$gYv(-$1ȿѓi3[_qsaѲpdbN 1~!×D*o`蚷Xo)|K3FЕ*?-4ۃwzDBl4YcYW;sntFik.`ǡfuC|֫5vP7w5CvQ,O6 ZSb#<҆[&$8!kN R<k% |=޾#5'+ `uuV޴Xt?ikM1xIAݾu"wCt 6(#ɤEd|gjhK ɞ{+E5'm)lܵimcT)Axy2藑K/6kY5wg;Mml#!maD.EDUx`,5{Р)rXm˹=1X#㪞sWz:\} 4oA<.KL  |t.غ]:OA}?i{,%7adVS-ٷڏRZ >;TZK;G )VU|gꅏlϳEC=?~N9ELRSňs\w-UYrU2TZs+g3>i &.b^Q5 ~hUggRm|I zXk*:*qu S02b HژX.mѪz9=x&B`lEAd~՚W6k{cZ68*Ur j+ -ZȘ[گ>U˿2OQ/X2MߤmNw iR^a"o]i\-sEOi7G_/JǕǖ9[_O¬QFWgkNZfL's|6d.7'n~ɀ^mp[ x,錤꛱զ*&P/] cf]wk:e?H<}SS0#S p4jxkӅw0)tJ?_5OFWg,P esG#]7f*֓'P]|?]g&Nȣ*T5B00ԓUr/tOasBy N Fۛ$Z]f=v}aAnMd}Z=}?j_5:KK(xޖ/+%ܨ+k!!" Zp czQL`1?}c~ge]F׏\t 8acD<1"J%%/rH%6.\.so١9n0lt*'A\w(yw-ERnmÓ"Ә,cr=ՏOv'⦃m2;HZ w^߰*>Z޲x=+mu T#9>u#>~9ue- B`yzyǷ5x˷??yVB /Ꟑ WQ;C q;C@!աRvߒG5kgg~*Uȱ,9*$@T! Z^#MlZ/*rTvd_U^q˱zq=0jXngOAAR*RZT&t'-k6q䣸t4/R8 G&kv@fu妫?aC4/swdc.pj]RH7uܞ㏿<_ߙ>7z/~|_{ٻݝ7EB*f#KMyC ]@+vjY-PpHiB~֞Ki!It[ Af;F 5tCV\ΨQI92 0h )m\`<1KqJ+v:TeaNUһJmb y)n/)]T0$v}QqݜOxVLg*T^o~#U=2@yT'O@؀ ~s%leu\ݪoMطl0#S۟>`B#h&#FG&A>_kLN5WzW-K (5:,Pz8^zӪXک(M>|1%UX+n0f~s${Gs@y8CQ/Gf{4_D͞IՈ3tp%6A91*k pҥ6ZA5E8#% 堎p hU>TuftbOKEX7/},ĪJo +hoYW⤛雚B?&w/Ëgg廌bu:/cJsIq?U^2“aKǂ\%*~cSZ JQkt1T-a[|{l-cS= tOu_]3{=|A|V~*Vg<& PN!16כT+QN:Sߓ2XiU3حNMCж7U 46~? df^(afj*u^x[ljZ ;9?~#757o__Ӌ__K#ԯF n[-?râ 'f?gЏ ^zawjnX /_F=Z7l%œRnnTӼ=M9%[s@::?YFInt=G?  j@d M<Ƌ[Mb$?-7\'nɯaNɻj~zHp. Nægg5D+zn7M&oU]Al1apo Oyz(oc &' YfY{6^k-y0TggJ Z=AMhj֞5ک-쥳Uqw J}fMw .4%CiLBcAzIZjs/ՆT@L'mO\$ښFJT iv7w]8o-DB>})vjL0 Crmb0 u7u`L_%5R]n#57팀iziOdY\L`H5k?Iek- k rBav_`!iX2w`6h\e$.:seMQω! 3N$G0N+4{d$m?iv!8 k~qW9wv=: ~{H;/͟%IB7Lxɍ߾.#[m _Qm)"ږl}Yt']W &Oջ-Y-GC,p-p>eUs~{t%Nz| `v=Gw5"ԁK$U"EUe0$+hsM'GKt:k"%1DLrֶ ;;K,ͭݏxUo[}L/ !,8  zc4r47?pe8 !8G2kNo5_L\4*\`%w9@Yf|m8TĤIC;P Nx0gh S&M5 qKڏK ɔȐݷy#ŔOu !n5"uB z_V7f6tKnCc)`X$Īì jqOa KsG "(M> scx1d`Jǭ2"~t5wO/?[_2¸|Vo/~pvgD*j[TjP;J%Z>@gbOWd1:lzrUP:Ϳ%B { "12s lZ+(LbuA1WΡ\ }/̼j[8Nvͩ8t}c ގIX[GE״'s*S -9pXJ!Mk$oC͒1Ե  8Ňk"Ʈ-R w[6ĘNr{&ŷdaڎ[[D6w|lY"e(q_$rt:_x}jEؤdFs{?P {<&\El.E`N2[8"sH:|bxP>Hg`T׳q =ԸXhSM-[]9R(U1iυN KsJ9S_g)e x~JZ׏-\'s>턚,|nlcVT|>M >!Du\y'$77y6\낽+Pun|j>돿 P]?'p~D14v*n n9a r{싵C'alovk/[%Q%#zapQ`hr]QGmݽl0_h$$H爱e4 ۢL&K CUt6xL<9ogВrᰩЅ&naOC$#Z뾛*C.m<*U:7HW6#9$ }7^: }ޚ]m|S*Ƨ?!_| Ykۧ?^쯧0ؒRa5anf.Fv#Z[ߩN0j¬RL}p)>єY;bڵ\`ґ 9j/>ۧ}Ze[B|Ug=v̌E%FA8d%L7>9  ܲh㒽G8 b~?gdեfҜhZ (j !nԑSr4~< 2We)`xKa8lu?ƞ[B2Ge'鮅fdٽʵpRU鍖$-5r`V=^Z aז9NXI^=-.͔^LrDhDrbϺb`-Tz{}3k5_7~p"OMY6oH$oOvb:LmH0hbzkհ ";4"QL:`ZS֐,rS7l?r1jk̀8⒤"7s↬ks{Ӣ=*z! 0_+\g*pu|,Uj:*_JiՎլs2rOe)/Ps}Yt"Y!Lk唺cpҦjNTmiO){1mpGT.v'vCI5:e5`|n%Ǭt;WOql?7%;cp#uzAX31W*mas=|y`KS)H Z= q%\wQ[6o8{Drcsg^+􍜮Q6儐̺M3F܊ՎV 4˶@rsLJg[|<|9; :ԣR0 b?cYʆo9y:O9zla;Te D1-hf_<'DQ1% ~wl=_dws(FI#mޞ|_)|j6{7lckì̭³U[Qk[þPyZZZ6ژ2kh]|W[7. ^^lm+7zŊF'C2pdm;%@Z1}q8r&;-ngQ ys2&rNj0k'lq-RKlĻcN/ ;{DB9$ӕs0FJ`qĎ/vOx@ɚaQtuGyDgW>ܴzr5 9p}ָ nwñ+Oυ҈NW4˧rsݏ[owTHD#&7wYsk@;Il׫U;Gc)ݧeɼM6Z;C2%`BMt"EoÏdx'ݹ1SW#<ݓ5jl П:[XqkĦ"Ozl l'}S[@6G,"6Լo53CB$syS`Fƪm #'sD)i ԷgSuZ ÎI55AI}tΗ> o-/GjKպdPgO=4i a$Yf<k0S[FWɡ/lK1m%NOl IV1!:Y]%kZ*ι!1 57 d+AN'^RI_[% yuϞP)Bg/G8@$Ih{$5nDgFy~Ypg;m9SCnMhIJnj̩6㠋A]p`,:2?bu} 6ZFwI%V8-wC^?Y۟p뛷?AXX2 fN^+ˣsoJ*z9][\ךjmRM H kx My| "Vͮ g;サ 7ZcC/꫚ ,w$lWCA8ikV1gTD|cY6P; 0pAj[AjκP_W'?M=jmMn;R>ZF?Hthuס"lhPVֺCxAq>ֲ\_wbc=qW1].{4u}_ݻ㻧ˠ46qke3nN/pT@ Ѻ 5td[kF;ds.X=B@W{@'5d5}!֠~7PJ~7Xu 3֒!e:9Xu(;ئ#9.-0Ab9"FāIt /Wߪڵ-1u䩷O%?9WOXBGsܸRz²u*ճܰAN)j-,aU =bRqq]S5,ZjMfLy)~E񘤢3QP8G;ۮK=BZ2ur3[NR2>ȮowX x2".r~ 7KMnաG7_+!OSװf= qJ{hXw؏k+4Ec83^߬ضI4.lL.;cl>FגhQa Mۢ:)8kc3"Vp95  IН=Q5B{և9IC 2u18>/.> 0X.'M l%22ebh,͕ H3?Hśv&] g|[/Y<|mGdM7l7 13^$aχ-ʔ\ض015bC)tg^mdPqxtxNU;PoƳ511EKCL ø3d 6?iCu|5a%j0?+ DXmۖ1HS_:Qh㲄cP܉(뮖Dwq'5O#;6>0^WH'E6>t]uͭJM<$9h$` |U-̡LK-dg5 DAP̫ۥ [UվAQ7_oAoD*_VOcXɤfjUA[@Ik)-z4u 4e}ڥd6%C O_81WRQ9$f/OZ˅_E WdZrK9\Xp)MYY=th꼟twĊ0CDPGN%B{SףM^(K~3ۜcÎI-:'ݨ :7ЂT aMQK C({{É4@?Cp5w# ~(uuSzOUrҭѭ`W^_*}S%F\J?e2']˺ kl9v,ჭ>ஞz_}+M)9f^|Щ,iGAChaTz* ¶ДDM@Ťlϻ$p>R$C1Ŵ2ʱB|@fĨt%jNinMkas&J0#6u'd2D"j> ?`rOL4>4\B#aT\+cjL#c+J oV_Ypݯ?omo|L#IEMߜqrv1i3j^02Zű1\rj)j46av#0ƅ7 BZCscoŬ-6-K33a&Й.(hoq. 36FjǷت$L-kqȮ9oMU{ pՏb5ڨA \櫄@8@`z8dst"iNӂ%>_}߉^;4y?ӲZIt;쏤D:OyC nuIs$t3^d2BZ nl] C&[#F?IB45h^ylrÉHYnȼ`C.C7!zAqֻFj_Wvgs|h$yֽ9S bxȳ}NOGKy!:dk;/1 JD¬oJF&7/W;v\C«??}ן:>_wo~|lZ[M ŽJ\vWZg&zɠ֖E@T23iQ`+mŜwb G $IjF@ͷS^PjS1@%EֻӪ3o WX ͋'ֽٓR m@<ֱ,ThXqO{d͞7_^=SuXg(\O@%LJm|NH+o9}]m@\+2aI=4n]Me0Ǣ2NJҥuԈԵpZkHlW]ǘkEz@x %  v m`4 i܆̢"lw?d<&JŒ 6FLnia4 "%QisYg2MN?) x/gN}n2=z+|cT=nNV ˙%CnPp #@K!c5ֺsAwVJ+&*C[T]v,9#-]ЩCK\;s{ͱ6q⥗/t??&gz;յ*%ֹWno~i5 Ы%jT~nPTWf3~{nʶ Zd6+U9O= 5FU=mN&QOYM(83-Է 1H. q_[9S\14rR&Cl/!mg$kCFL >ϊ(x`>Ԡc?6Fit|C˧~oO_}^}oO? 50T+;Olr_[_=Dh` :,~.^w F:H%$u&Gɪ0SM.ߖM3M8d.>+u|wI3`"f9)_h_8\hMmv('le.!l>ɚA#V3X"ZIwmySW:qf U0WDRW3pYT|9u!-¥׺P@y:)q¼a__pC90:Do:ZLL{/~w?COKjWUw/mJ@ef~ ȓA]uuL eU~V9~p}4% Ջ:k5 a^s$e1 (kX˵Iidڃ`}xi]?e7 nG!d j wv˕Y]$fo:L{]G~^;&e]}DaBUhdŲFOI4̓RVP%mQw5,+G98=,;Tr禃k S4H#}'5ӛH[bE N>D%SUStݒ%3)z3JV A\Q \)+(\fnjflkU1'7$6ƚ!kv{`dZ7E}oUag Wh=U6$C{Uqa<|1T :sDU'_b3u{uH󚢰+.w櫗<,V!=ͅRM$M%P-iww X_< 8q>4?*X6Y$pzP}Ci{u}7R%BZڼkl̀_۪&Emŵk~Yek&-ehl|j 0GwpeͲP:s|$vT5@7y*J}D=4hYy'x_` l]mUJ|LA1Πmް4f}~xVUeF!}cxZaՠW$+ e.֝zVQVѿ,93uG ţfڸwS,̡5Nԑ4;m.J[x9Oߠ|N.EfabRW.3Q U?$NUHu @ĘLtHl•V8&,VZuۨ>Bd#AzW. T;LHP@/څd^Mjo,;,{EiWU }\6Co>˱QTхWi 2&=*ԇEbӍM2+7BS-b;r.lC%b[<C_v`ֶƄ73kwKSKUdu+W)֡ (sWWs]s^5;%RVZ?jx/V-Vr1 V,dV3;&8&fZX(:f9ge l/ù*/Fx= 6ɷCvChd,*cp"n$ b~AnBNn`XSN~*<Vn1D~?EylFkvĬ$GPŅx5RW8ZmԪ>@y}Wq$!@2Go~y ش9|mݎկFµGնz'\[f ]Ex%sEf`Br*#Rp3UjBԭ}'CW<~ r.a03<5- wyCh+LvS.zv:@):!a6\s{lWlZLi . UJˉc,iF&6M.1.O_󿳹߾1l5iϞ>3s4I81ݛ@ИMe~Dx 筛ؖ TXUӮpk?s>"iqƱUuY''k(.e8iph,|-,2K|^f#]*6}r 6KQ򈪍q\=.WODJM:{)QFxpWJ 󚤬mk*xKS[͂[pp`t(,Z;f>ZZJKm)eI-x:@oW>_̒=~} ]7Q~lZ/•:} E{~H==_ۘPΘ~*}W`gp4U×z.9j&~QK(JUSsV G4 a;vyc6]'rhk :X@TiTߨoÄ1{҆UG9%ཛ iS"%lдz .\"vlsY" 10Hyq;lf`S rNVj’Z,,vKc["dj܇#KOT{y=U V]0lުʝ(fjwrͤcj dnddx3؈w;R5Mn_f*2&aT{GWypO>^ap]R78ȩ޿<~Ƨ7￾{?-ǿOw|t5Fu9C:ͺ6-q=W_@<[ !YgF&cB .9ڪVV;YTlzl+U4;DKזtvajJTkd ,䞉n*%.A]Luf=z*eBwo$ T2եu1k_)cxc3}?8īo 6,UJF1D4FsH=ՇX=#B}x=8ib+vm$amxpaŸM 8uydM}ןoҕzu_(IZ2mi{qh*Z(gf(f:Y!&!Kɽjp! U+"Ǔ g%bYPMUj<6`ͷY,.UMam>̓A&v R=#s]ZJw*E=H[ 6}U1[ #u2sOn6BDd]<hCtm^_"tY&|6Bv0-Np#{s͛D MIk]0~|w7ӗQ"YnsaYE3\4ɦSZaUh4ʫ\N=K%W4 P]kEc\1c۪M<_EjObXV i Awh$]ihfQ+u}HJn>- 2U+ &N'+G]G0ϗcZ9M="KqŖVz)+l(`S6.<|.\\nn-ةFQ2-Ь"UȈ}Be'4CUvֵ] n =_PrBwKpv-_X!ǻ5^fK( 񪄑 \ByeR!#k25ɤMfaĄ@ >UYIFB`qt~ۏh.urbǷpocr>t>Etq䓱ݩ~[e]A* G~^T  XX18phtDGcD‹=LɥȁO_4DZG }=uU*X/?XGŲvrm0'X[uK7 yVoz4JMJauqDېya>P. eNd[#L Ʌ`8+6תS69Mø-SQ-rz;1Ѧ|!hZ*p(ka)Wu?E &%َ绩gQjoT1QGE1Т'Ι>pZ4i.& tqv<+7(4/GTZSx/ rRB{A~SU.ր) FSV(tcڔ؆z&?e;=}_g]OO>N 8p|̝F~Udf[wEd-5wƦ4y;p/c?A" +UO 诞yKVC81er~U9G-S/eq8*ba ۏAw&zJ/'2J~`Vi%Tu꫌xZw+_l1尤z,)ZO#@H^\>ֺ>D(Vn3ڪAu(Vpc&ylw}~[T3lj4} p._;Dw?ן.G$8Ǡ9Lt ,[-HƇ @@ 1PJ8ddS֞ǺiH2 +$Gn8k$ 8ۆJ)VO<%t4Yjb8ax>{c,8ߘB!HñOJ2xD_Wq)wFU?)-`oq XK3ʹL=,1wjM}|p`,t0@wJy>3M`)jbރW:p|]h~g_|˩{nzzIb4dXȆ;Q-.?[G%ԔՌG[F`5xIª$](۲BoPN9i ӽX1wD^Tؖ3- Ռ*P dd_ewƶ~ZYӝΜśZ%>+ #zAFϴ? uz@<,DP tT yiCw?Z?M_.qhJHͻyK='5+5g_|/?g/f^L,7SHlMnHT$晃GM=" JC֢n“< Z3jIVSSZX<Ʒrv~NU/{H&ړbUml_{>.޲hmsLۋz-4ka|(I3'e6?M2ꄪ YW]`=u<qc8}:[ԙe& ^,3iAs {G/MT&[[ jxM\&5՜Olks}W_@?:4Sd,gt$SSŸ뤎of~<,֜ԣ? ankb'bCU2c2i L[\W-xEg;ƈi]B0VyVq }~[~AQ S|:MI$4ʵlv rw{h(pA W0lx &*w)ưLoN`q]-:zs=^ځJ9"woOt2j0/_>&[7Ͽ2w;i.kcgW^بAd 5L_i=:-C43kAZΓc:4k)sߤά Қ`ZӋFʳ%ͮǻt?_3L1Sqq */Ng[^ax.R^|5(GC}!MdJGэbvęxl?m2H2=s }U=Nlk\e8Lӄ bT1Qߝ/_wh0I_YK4㔫W^,/ ӜP4[r08=K" Ʃ0SO|Z"|)fq,4h}(D18YLnˡl>zq8Zsꌾ}/x o勛e:Y >F*ZZG4Ę]cc:J!N 2 Ǜ}W>}42۽E<}sRiɫ9w0M%yfHwM RLO6H(*CdԍgdЍmC1Z2c3D띦OXF+ׅzҁm:k`F/pM),@pd쵣2z-.ɺ=[U=S[[[TT$;Vm#-"C3RI- 4ewVf~!3ria"uClٲ;>>_Z<}Ԛ>y-$(bKVz~::P;ǚLЯ{ҟY3GwYC]mܦ1)ZlS<ݺhKJX4|ܔ#A#Ƨ4sK2+*ݼ?[\hLi8e$AHS{'KyhlOU\ˑc %*wcj{Ls7?Ζ2vRlL|2|R)Gu[:HؕE' @T}"icIB>z^t[YWS=GTKܻIa cN舳7Ԏx=7Tg߾y[o>{˩P&#Gˁ8"DoQsuͨr 3;(4bAD'TBnfЋzhR>ë/D![Ddn˳8ʿSel.oʿ t{leN`kdѳgbH8` mS/9GGvB ilzxS:3nfy\sƠ@ k9;BuR+9_y}Rcb Gh' *-=\'߁iҦvР 59h,>c_!A+"nRC )66L>Ju{j̐$6Ui16oxRHW(M۰yQ cT]}gT?|[Y(ȡIpӎd1de6"n~Oi VT5-EXT> ;m)̇"ttYJ*2j3}~ۇD&K<}|eJMe2 hޱdF~zX Q8tG m :b=.q{iPcr"U0N8n!6Еi75֜0M wa8MkY.a1360к&%ȟd]ڹ f?Jֵ-%^>r5mxS~/g_x/n R׆kBL@.15c* gx9~J[*>$~M^bbbײDDLCN3F9㭡'v, l3in2J l)s;Z.$>?t;G5w}` [C2^JVV,dh62^#LI` Ũevy^^Rk{_8TS#< xawCwurfFp:`ʞ4D!f9x>*-$&RiysoW# '^0;R9Aoh~Jy}߭ &#& 3 7rB❃lJB֜߯+>g|?T;s1lmްչy=Adl:Ɔq/޷Γ$\"鉁P6]?Pvmu׶62N`çi,;l3u^]UےѾQAcy`/rFik4Q}U G(ھ3ҵs JlږSJ `yU-ԱFl=ƌOg U3~D{5 v &Dz8Z|ÉRx(+x'#Iض:b>h!؈ [_?qcߞf.<-h\ϭ՜<_#@-9)t\|%3"568pyQe<2G}-PU;" +uZ@[u<9ra{C\lP6)KkJզ5qǏ۰$Yat`EXjISHwG-{C ?}.yW-~l;a<ݽ|իߑkJh‚ᤰaJbN&kC=47;0t;nT$gnO NDŽ#Xhm֣Q#2s~qE=rb.yͨVE5iyk \Xszݚb Q$j[՞jKdcyW%BScm- -mCuyMhlh-іW_KW?cZD}i溘Hd?PE@6f@뮴IJz*-ihj0qk 1 Qu$eF #C*"11$sfBK@;?h|v.Mˑ#m]jP`?W3)w4]unb#VD=3lwֆO(N?b)X ďAޗ.C(!㼾߼%.(7ږmD>d=ʗ)Y`}twCM͋uD@"{cO79 /%؇wl4&v\. 6m_b֙RTiu1O(eg7 sGı0cvr@#DD́>13AD0EtYYb/%Ket;Djk6 o6v{V=Dj%[ ZV|=U~}tmzسZ,(DK>vc{PU#,s"rTQM&Ŝu`^X90?;hGo?cVi4>wh15I@Gչagdi )_]ݐ#>_JG$$aȨ~ /&uK(1Dؾ~_-ϩY]OpT%O\TlQ9 o~Ib(S c8t6,5H ϓM'p(f1oT:>{3pfj(T8Hx+~k"ʃI Ytfj am)X{9#&[Ўa1k]i(9ΤfȦBYhAs@Q*DEb g=!;:&Sªuc) 5;.C.im@7uWOOpV/-{$W^0 twjGEE$1Kp r՘wN3\xp{>1,3e.{b>Vţ[1״UT .G5q=&N$th$3=8F5s' J@I>WM Ț3?t]G:7N>)GCz?|/=}ϟX~iy2-LMQ6O5zmu0Pdf׈jЅؚBwWj+ְbYL$jUM`*X8Y۠R AHfTp*9wMAo@`4b}σm s7wEqVUYqa,wER-qH+OiS@52ޅNM{J[DzHkw*y=ՙ5><z3noK T`~].`Ӌ/_4ϟ~}ܯ9O$8-xlo}hZt%<<ӓg ~ʳwhȴ:t{\M}f|M؉I2 m T#CX"=t@?t};Ix}\6:<0%ߌc 8=Ve]I.Ts8~d=U:u'78hUK'Z#0 m'۹zxK9[zja?p?ǝf0{îYtYoKGcpŋ}[z_O>-zKfJ*댩"0x)=Q(pbG7v,HU1`;WW ӛ7&\צ"DFJ|Mi9s?.c M?g5bV;f8d0[H%jxi19x$^3eqî!1O2Zp>J+aJvsf}]#>8ݞm|&٫-Sy?r}Mv`uֿy7<nLSQ [8JFP%3ZHb+xX&`uI&Rg7%W>Rm^R_32%ID 3N, v㫪O꣠8 ^\zK)zRpLoCN>E@ClP0WհQ+%yvtRUMWHVKlw[],ѯy`a^Ћ \T%!_cꮽNiيtlX?Ua/kdWٱy:V­I=t{Www˕7?/ޛ1 fG~w/m?|9ׯCj7P$"9)?tI+;gROE:yP44# ޥyseUب\ɉ6͚N]ҹPt#lbV0haFXxoÛߺ1<9gs铅9n>IRX\"\+U851O%'(0I5͑+jnZ5ƳoH8t/OT8/BӺףEu`**8iyrXhtf$~ &͈-ZdtzvOc}6;GԨ!^۶f8"=*St}MO66#j5R39UQ҄˫dȚ{=`C!%6=FLKLu ۢGZޅP5Ña"2ǵu"Am0=Ui=úG> (Ys\LmK\SCvù70BVfnX˃'otN90Q/: @WKX2Qͱxȅq&gw:G/_?//ұ{ -R' j@Ώ& TsjYƭAd㜨'pC㬊ULs-%#~8PʨatvmrĹ&3K+8:@ @ROc{q1,k.9'i55VS說&8N-vW0*%U*3]˹QpR:V6.ēR&rKLÈe2I'a.k%Q{sLC)NLgrLv-كa?އǶhgJ06t7G{71#Cko?翻6&z` =Rܑv^TW:_UlR`"Zl+)AcҨ$4r^ÃRlUR=H-8>AD3$ h :l)'Ȯ?5ݤvG 4vGsЍ Ko$wf@ENCEAckB_Il}x$z,PT1][G9~g3ZC b U|kqo[vX$0ܾifճ7Ouпktuļb <;i9Ks|# tƬϕ pQpnwsHh<&o)wu cZ%(DFqū&-wUPe-jqu <2+& ݇_WXS L(_0"HׇJ +S&_gBo0@X mM*j$)"8[N TOO#ɜObA%L-Dj<>A3N7 {xzox`OrrvW{} hX3F_ax aO^2NVu6nP6S.SA:TK2 3]!%Jh)tå{nSU1'im@ \Iq?Ijc4- t7Bs^\&VO!^JcX5J%vm8ݙF-[BнIweL,Wl*3la/Ncm">-H /aJ 3+JZ AR}򣵷! siѯĄ:vzC%G^ 8w|4p͋|q~umΏ;3%X* Yy9V xL) bՑā%5k2A!ʪ~7eN}.Vs88B`^h( q8F46)u4C=+i޸nT RytMG6sL桳_ּSFDuj1eXׂ?caO@jzMl&A~KG'0ɣXY,B3>'kl ϑ憞W&`ԤӁXW'p |+R%y-xU^|ތDm*]'8~Z.S f"ZDp紐XƳ鲟`ޙbE)"z\Đ|*7~i^?2u:m]0z7AF̈́l,О 5(M1ƹJ8P2f* #"K}21tFP3iCl rŵr9!emn6iLcm(5+bUm!K࡫8  Yb#T 'x>pW uj f Ծ6oWݮVuzC|v=vN#;O-Ω/m|9, fci.d:ag. >Xյ#,X&j<%`J]\w_W;`uz-縅tH_zoB [z,}c  {b{Q!鮼N7_  JT-+*#]􁮾4Fռ7@`""yvϮ{GXXPاrlX@]Np_:c mL4O\X%P+>qj94n~)62; NȆz5p&B>e An(`P2 I/дD  )P2mRTpƸx[2Y${4Ǜi3]_X31P4t2Iz썐ϾxAOƭh7U;k9_ڠS*THAJ 2fl9Qu&|F ieW7(^ U%ߛ`{L;dXbdײ3zRnmS 0f8ֈ쩕 %u2<aN 3>.J*WcU ;5!nLQ/1)E-J.;)*JXn6cxv}#j3g2:]uO6r0`^=6<t[h3dӌwk]aomQ"z&c߿y0GLuat71qF& f.r5UL3Mb␿lJ&]Cpf}'}K5X:1m *;=WCy@h3C=)1΍`NjqA]Kn>*ِ a/[Z{+˾ńٔUO$\'jը _Ml*ƨV`=aVͤ#EyתWD!j~V_1꽻X쯹#\_SܱjYn?Vѳg_}KhԠ_PhK< .\m9X' %fC܍wo.?KV}cXG%hX{kB.k6H?DpqH-Wg`d́Q;BE5TR3']c4pM&ߚeA,nyuw:ps^ؽ,X]Pݢ6V~PIFXO70Yc!&<:|uekQFGJ dr%ԂD?\#il.cK:Cr|-{EͻB!:2c+qֆwrsjk9b;f8,9EnAʄ6  Bz V79]ŴaW|qt*j Ls_!#é%ψHUx=R /QQnx9G1"\tNl &mLԭ{bn4"Н tW؋xVC }N[1 s4'Cc3Aѕbqvz%M0jEwmS:CG pˋMFؼ.r]R3-_g߾y<"/+2\]2 A@ ڸ%ʹ<&IǍ5>'Z<Q3`^v#]9ХDjmY=x 8Nh=gMLpwDA[~: S~Am-QR#rmE1_9Mk=kv?W7 t-L+ ;ztq a)-|]4`yK\!0Wc #*'у51cBQMLw0HW ɕ\Z$wF]g3<<ͪ=}iM ;%B ;U1Mk5/{ mG]efR 6n1"cO (6'? 1͸{ʄ]IA^SKcQSq & lwsBnO;,F:m+VixukU`; sDaꛌ-.EN#o n@4l8p:0@<;&cWו8k_XuWn 6Tqulf۝M1wHZ[޺ I^>}[a}ūxWJK͓aۭB n.I=h,Z@ڰe:z}Ltjg| QID0Nb>+rF tOI6kM:n}!397/>Ol3w!(7mԋK~f#ŶR a%5vx.kHO{wToG)=t`8&6c^ǁ6p`&|Bm0rK|$H)؊UwrƭӜe\ў`fS[T;z8RhQ*CڂE֨y8^~Ez`rs.mw i bk-j=!^7!bmFl=UHIʇ2~н;S"qK]luldGYm.Β'Nv\%6W/_z!΋ ®k<ŖƐ&.'78եRgTK=^J,6K !!f: O(aD<걘րʘq,ɨՒ\ٴdc$|s;d<=,=Ny/ziJӬ1cs̮1Pņ"n't0^2;=7M%)v5#N2|W^0-v5fFr_ㆿhQwrRv}X~n{絓?h}#}G[lZ篿M 3oe%U5ZW:Q6bMɻ{6~YOa%6xFEYN}l|xީ8.NOa_]J1pNUZ iwfc3Y kkZ6cF#Bt9=|ɘկP,fOoܵ^NF3x_Q7G{/9`TeݣL` AidDJu Xb7AuR9cFeiDD#nyC9:j9Gnxb׷E5A7ٜϞeܒʐMw󎝟ID> ն|$ Al5k*ft!Su&+qWS,e`{uW$ iiA3i]O.f~ 1nY[ݸʵ :WKkf{i '˱Kx)q~'-(Đe)ٜ-AO|;йe #hPux?:$"ļ V _0_֊I D/{2}PC9䬧Ubcjw Q+4p9EfY7F)X nq֝7Lt \w\Q{,9N~x ro^iBU̅$3I ]8^G#2wELmĩՏ jV:2 t ʵi-%n]{EFsY!ȓ1]sEo ɘv4:v9b26GwrH"d0 {ɵ ..i;g )G7m5@6~:HNv\塯g:9߆~%"cN@P탔 z@&-\_R9c[\\wZǷm%s= >g$p;uhLC,һ3Ky:ˮ-=\˖h5X s5xK :4NǔW\5\AM@.ؿ9&S-<ܢ0HKuKÈɘS%pw}T h@( cϯ^Zyɹ-' Oc%%#-m.ѤWpU'E -Lo8! k%*aCj&ب: v)~ MbZn8h#G x\>Xu97UѳϟS /Զ^9(r%Ǫ-F+3 CL”7¦>26rT $acsn2iSauK`V# !oE-x KnfxI1I$p]JZ!=zPsD3 \{ډ{D|}6Hw}x*$ >ھt^jUԭmH<<ZZTvgO*QE7CG~uIZ٦W9&VAMy~-Ս67otmLhׯ<IJp}L=l3_\U<DZwR22,_Iw:Tu-V&̑w!YG1h.=DRD-o;JLm#X# eBOfF9 Q%.H!Aavar*` bkKhܘmF_wa> 12njdm_mk@\I!?"ь„S7v;Nh*貌>6dkPTtc]CmKp*r8q0GO矣s}HHnZZGU,ԿF!(Ut`w @Qf 86\?CvMY;c6'դZ!є5:vQ1ǡ=ۨɼJn'@g:,342cz#M"KQ%crhS&Pop >rXzޣ &"5L\Gz\ILQX}L 6q@fqX0g\c =hDOTF2{;pٰgV0h{Tص]c@EQcPq(I0ai)AIO9Y?U#`,y&?U"}W7b#xgw堇|҈.mɨwaL2${0JcbJ:PxdEU6Oh&\\Rffx 37X Z's>; &((~Q z2kQ=6mHrbop;#qSr(a\3Y}jP*0=O`c0خq1R<ڦ犣XYZg/6LoxPo+5{ 7mKٹ`PM~$=óχY{ (9V ]kq\?`̪UU]xJl<'qvhmR~& <( - @@۴}2s5y2U*OYuKwPU{v6r.ǚV vL4ZkyMlF8T.B<9BI2)Ut PSO5y9Km)M, M9IcAť<o$&w||/]ڡgh!U-xo#6v $ S-ʋmۣ(!E)kϼF@+: ;;È/rK$q&5(m?*~&qLe[5f@#"IqZkDvɥ kXuգkupfTȋ63j"ޖt=W-u+1jH%c%Jc`^Vh7㿿c^՗_| G@eK S_}AN7b6k 9eu 0X_r/uHu}LQ #vG8LIɸf~Hnj``tv'4M?jf(/G#PQ1> C@ȣ`,/745uMM l]ckBb8兾R4vJͯIf83Kș-=sC!R,m؅^s 9]<ŁCiMOm:,^q}7LjR^teTlLoys Dgd(vi0tQw.3}nux7۬LLñ!Fϝ+q,\ԏ0 ǜXG,Iƨ9}di.Ğaޘd&p!uv8HkJM[&fŊޞ}NȝD59n5úGH;>2Ž{10Plpꩬjxϙ3*̛yo y6 ngqI%,)N!%#2<|G:gֽ}֝?ܾσVS/^|u×줟S:=MH$ʈ"Q=f=\;Cz9k6D̪h F7K5X!ć!j;Qn`7~|.|e fLHŎ~I{{)OIsasuH&e0}]L&F w+Rϧ2HJ!P׭vͺ6C|pNg|xi;} V&;ښ!)z|>o`0iU8qܿ2eͫ/4꓾C 0C^=g`+ՎS9Cyl4uE ǪfWTZNU[Éz%S/Ioє uȞVAgy[G,'3_DXճ,u7;O'pKrV .|*0Y\ݔ(b6k3/m-K8Uڼ Dʊ"GX14$faf7!\Ѡ.XČO-E @5Wĸk{=ǴNu5'c4I2d7U|naxskS,Vsc^lLPf xB3s"bŹae;ʔ9z0 Ekqmlr8S [jgݰF!BmI![͹$mW[ψ,ba],#NAJf,")@ z.=GqTU85bz}5a0b>h~ov<; 1)q`陋Yb!+IRSٸ]n@a$2YfײTMRAmW]?A%1lZ>(*[ŐfvHI(u[ctMٲȏ, <Eao{&֍nFGcz$K5侏 _,N7 lӚsWA:=b ]Ek&Hm]յw!ՙH=\ psj4QFgW!8ͶXT!R]۷5BefEm{uբH m2A[ѕI"h͎51ϿL36xqǹQ- (JV-ծw\6aR, v2Dīj% Ĭ>bYmG3 *Ӓ {1U.Z:4՜#8vS"Tut%Qe2%G攼zq'RZ[&xņT5ES5"ϙk-n֎3F* g-0+m2\"tFnyh=#)#)zr yFآ_| zѣաf|W;d.+4=R_nRa×, Hȣkj|ԩ#K*nNE028tLחȮ]{r@kbK_[\TRME1'crhh幅YCrTng%^c"0K6G&h /(cCF6l3[ TFԑ689ULfX2}q>~"T\n`2& jx80Sn5ҶP[E5-P"y;5yv=&"㩝;q:CZN118<6P/HϞΎBT|o}1xe0utRt~4Ec$~սkyQq>cD{n%_XtwJ\&:.@] I2l&n%S5%X$d"CnSdU} iȂU]׎*z?%H>z :)Rf]!%#!4uLNuXGϮq%ӄL~iQ~ApjyWZΦusc1Zjsxe9Chl+T&X"]\;{D*L T bB ;'FȻʻ I PS4'ƙ/|_>p{:zS"E2=3QǘS6pJ"n0DmI0#3&WcL*3D6M(RT,)*D7JQ^ & &8]E=[_8>hu\xQicci8o4ecԟމ`$RE& oJcN=4MnƨU]O͠Mx;~b;U7^)HjtX32HF[ e'» K:]_hs;Ob $=gfe&\qW3%&/'M[[&]|~FG(/N [dmt#}^}{MDCX`"8?e;_*!P* e9Vz;\vQ?918htS=O쭲 5bR-3sddr1rWDX.$){eh,? 'S1FQ46Ge0Ngԛ'|m#&Vw,^=zd|u?FL08:fRV֣~UO]3Ja@U:Kso 6Ycy%/2?v7'^j(|A9ݍ7Oo{ۆ~ٿ=nA`XiZ鹩olȧ`pӒM~/޸#[q3aJ0;hLzW(~1hfsPM8h~lBF(Oi!'圲s\myM\N{4,/p?mU_ ֫>#2N&fJʹf_4cfMw氣[5S)}t8> WIǧ5sF>,5K0hωn7n"{.ΎL xb:_0low?y=[[ `*_rc4/-51il)\2YdCȢfK!tz% Mp庤x VxY;ٯnͯa c(rWGsyT2hq`HL f&mUH7" MkW0HX.FڮTW{$-OVJkj}^s !wR#4|ܘ/stFAeSwBl$OAABP`w wcㅺMj\[Uׯ~xxFr->=={ox7wBnioW@PVtGA)e0Χľ /1?zTy^tn=o`pcP%H[ri/r 9B Ӝ]jUDhXp-ZkZjNv/* vD~@K1f"6% ufUmqK^m|fy6eyPyڃ* D-| MB-z㊅8QPTQY&T);x5Gk[3JVxvt&J2<|c*.2HgeOwQ^)n*)KjGi$+ Z(վa*]3p[^(ܐ궆qbSOvh#VӝRolKwNZp9Bo"_s/4|.2L3/j."(%-0hfy1}djGB=[Lbqc̀p?<_1웚iYo18Nk/zY_ن F/ N*<9|m}cyp{ CjX6әX3,@ӝ!><83T5_g;c@Fva1F*f\enMݐ Ꞟ"uBsZfyQ:01ikzvtOAm#_mq:ьRP;K'F)nxNK~vz'f[jܥk۾kg€gQ:І{mLF?F暹%c,! tT#"R{|8ֵKqd{|mY\k{JnP|0{l9u\T/4v^.7Ӊu5Q>'My=/ȀfwT=X \^U8OjҀ5`-5zsB)A"kW۱w.?zax}޼t3@X.Uxpo0~io3_>{}(/gܥil?f)uhtdFuKh,@i%pZ a8K]:I4$9CUSlŴ7J2FKkaFs(X6=DsKx RŢ d2+_ :HZtт;l|:$˼ 944E%s2UhH"'w]wgby$Jvm bPM:"IrԪn PEdAJ_{<},yb jo<=;nK.cwkeH $*R[n[G~ϥ~;%d EyZ!|S`yNg EK$à-5-yh )vCj+xıǤb'☛1o;U'q%a@:@N YUE>9P^)N-e7F&չOu?&K/yrx_K q09P+'^,uk6-tÅDi ff751_/&D\rnR%_40_<~ݓig9wU RNܦ,Cu8~CfqM`]z50b29kQt :>1$&N?X0$k ť5\8ҀFV=Itgm}ZgÕ1U%Z]g?Bg9]K[č,X\ ̼$FNx.gU%g2ٰ|gwJ1>pw04FfdwqgT?wN\+7酧2,/[7ӣ<2{ 2T#LLI=HTL Hj2l8"e87媴AKwyN^$䠧7}# 8tNp(p+QЗB;DOٖY<"߱%^nr.mO! E0`y;WP2ftcgA j˾M: N;>#^=OQVsТ`q*DlhŪqL-t i kҀ _vDRƛF\(}^{Tjr8+9LFhwt?ty¬py9]2IoC6C7z^O?|w7khMx!dD"e W!OD]/6,d^S5ĿfSaL.N j"'gfuڌ/ :[ RG_NLヸ8 yIԷAISK/Ffp'aYϖhlx )(~xX ҷyA"d@ ywlLRU'PCDu'n_VjDڣ+TWa7C"v"5Hōn|זA/(]cd_a}c&NXuK̏Mfbճןxe7z.OG#HU##1B2x?u_G}'Dfc7@iju?bd:4i .oH:s[Vgjץa9-kS DE֣ݒʳxX2OTXHNT?ÒxS(*47gpKvͪտB0CǛsrxWG.Oa_Nh2gW#` ygIY}<7&'YC-1ް&H.>=% K&[P%PɁ W4l@tVG,|. BBciIŇK*㢴X!y٤r%@hj.\FLxUC˪Ó͢Haksd .*ҦvyQϟEogHJS3|q"e'\65>2?~2U4v1-|lÐG躘K7^@ɋڬN|QL%xc/y[ʅ=R?6qÖʣ$X`ᛑ`tU@\5LȦc(sq Jr2,![OHҵG@k ?g ֝M#۔><<JljmG9udOb)0I?rJuSyb6 }ӳwУo=*;sev(u_idFQ鵮e_,DrY fCElia\㫊OVGv45B7 6P̀l"B&Ь!HÊn$cT>\}R pY=آ-۹x#Bj4Yi^;*sKC<_yMvvBE:?0< qaHc ZvތĀY$g'o9 j 62r'<3&bS\wq CPkMw5￯ M?d~xSi Չ+v><3Z6񜺺.D J:b Su B]fwPAvJѪGF_ݗXVQmN ^՚Rk^5d:.LH45*jLq23fhiCi} }H]^c5͵uQ.3O/8ZrJ,UĂkQgKPūo 7&;q_+!9ʚ 򓫍߶$`Ulv@($2<hQsH"ARݭ~^f fm{5<\C N3du<gZOHfUz2;0VVЯY-˗/>9. (g%r'D1\,sZfxTy$!HFwFǫxRk$- 7:}!=mðфobn12g7:A<+YJ8*11ߢ-EiiKgX %H_O9A° цj/Pض}Qz蜺GLiIA PA)ia[QT=w\}$|. -IGP4O.|Bxӝxݽ"US0(5Ba{ K_~yUɘvCB색$ԺXVy/~!Kف1)O7;KŦ5( >Ly[9k4+zRdž5ͧ G`+ws%&E>*dFD[QDln4m{_GmwER$12nkS<ja9ilPаqnGQ1gGh',WU9!WnŔq[N`EfGe:+ uꍵɱF= r}G݇Z|˕I@pf&.M!o5zǿ{/u9AFX1n !̯w8y4̛E`ʑ_Ǩ*3UlvQ;jgwPgBk#S27۬?1,L-Gt ;щfd! ;]nSByPXSW(kQAi.4|LsVؾrhfJSU >fxR <:ap"m/q?{zN4 jxlۀH;k{mvӶyD pbCkxjYH'=!fmELC$ *2$^ǜ 6stfU_X z!cόM+"20 & =iZ=lF'.(g-xJta)d2p£Zl"R^&C 26ɍYǸ{=MT,UVQA7C;\ )k׍Kba] lyXwF;]1]O(3?#5F{^Jn2z9֊xmɤ9MnyԤƠv-]<61M\]?Aj^o_jf_$+;`9},>lc u .4UHΏ=>l-6Otqhm8XJ UG_?$7QXO쪹o":(4Fu`բޖ͸1`ROq]2XAFH.y`=*]N TRwe:~{ U Q1&UvwHqJ|{{~Q@ C-l~;R,{aϽ0;I >hrؑ^W*LwU^}>]ɋjbw+.fݓ1%.W@mx.)qmyFY{B^"D~ >d#`cLi0mB0Ieb㞚:1cG$wuiA? MCƖׇвq|m7dI/ /4Cw KUP(}VR"쏯ZH}Açr]UCR3FUP+3XiiݷKAa#_L5L9kU+._5rIHw"GQ\.b=^U%t.}b|Xw9ǎ< ZJ=8n-d,:;bvdv!N!qx'c߄I6Y4gT@ Ǒ*Ծ*ڙM-U}@+&Ӵ,t̀(3J&c6+rS1DA=cgS|8d~W ;r[G?~Ji{`(!D|%M Z3{:N <ʉ099}e^lX 2M~\hZZ& ,km}$Q)SXfm4OD5``Z1ȁ 'h #d=e MG‹ߞcTɪfUamD5VųΔ-NjwɑCI֘|FZ I"BvXVS޶̺>:e/IT K"n˱_kcsNǑ &\g8A˧hkjgiY!_jjș]P6Л.Hj5LI7daoڼ=5fA?֜<^fxѾ#9fq Bcv~*BYfX ϊ3*.>pe\Nɭ4ӈhm13n9cKؼO \!r|,)O8m[tgQT  Ӏ%~5u/'NՄuN/ S`jgr m}mkU1] <E>V }R u/C 3&bHk/~"oc&+uhYt6#V%c'7 ~1|iA !ҌX 6,'!\-f9VrDS8IN٧6^ڙ1[>ѶV76# ^:F*?=1j9ԛᅬ/o}̝%"TF39<6 A2˻ݲ ~Ow8ZT̹` Xc#F7MGhy$>WU&'fQ/ICsU 9!V|茚Kk߃I(c?;js:GmR;ׅ/|f"Ś ]Zx6հNy%B 5G?umb  j^lu**5V! F2/+_2fKPIIѴNH 52⹸AGۜuQ+HS7U3?{(m +19&G&N!miWkew+4nG5ndE'|\pl6(WA3wfun9S9%G;gIKݟۚtTH+Xkm(_~4^CLNa?lޚ=ƭJ;va57q~[2죘zha yX_1-1D嗹|@&1̇lr'-&^#gmED3ݚ ]=WUƕ%l x8tx4.Έ鏅4Ձ iDN4Ix};cOI^2tx1qꁯ5<\BK$"2kٓuE;eL$8E ZrwNom~8#YۃTw~y>%,Su~cK볹@s)8Hoĭ1Z4IVe۸ՁDJWj~Jfwްz{}ׂ`LY= 鐭RZ:w Vxϕv&ϐ}pw3&aE^|zJrqԋuG>.73DFi9l8ic#^vj `XCLCC]d񜨕򤷑.DW`%EJњibeXz&AӬ_LPke$&no|c"V6DXV tg5ݜ;u}8ff֕ng) >2S/:6c] D]IR'|?>"x-|"P>~-ZBўA!zk dH[ϒLENHJCp -(L_N_0V"A" k} =q/qap2ЖUt s2TfĭuldWIZQOZ;1T&+"H_)^i+xsbAD=X uxr+lUgF\FB<{!'sWg*A7h㷏zQp࣓E>s.dVspSlJ}Ps/ bcú1rrZ} )\+w>,8e;S۱uFAX`d TSHZؚsCS\k):b.0St&Q3e_yW9mָJl?XC-v[hC3$7#m6 y-+hS^6OVf2v:OwM!|DU{4ƬŊ py}]aۖQYHU&ڻ8DOc̯%q]-Š ^};a7vsZY滗ߪ|ބߵ  (l1&gSA>oS@0eTHA=Ic{H#0:FZ1F3nZƦlҜs1 sRXrsif$SdSN%+'pЇ>fVtS1-u hw (TtдhM)Ip%=o8&mipV/r áM~7B*5fwNw룈|EtgGǨ ީsY{a(Ejxϯ߿~|Ըȏ3NQʞlDxzb mȉSaI[dB̒%9 daSJS0960zyIEÃ]7PTŽ峑l4{da/RۢXOP~W-X]gmJ_0gVl3MO\{6հ"z + ;W͍%&ΑU';DTeN-YGop4|+RGOfiG TIwFA]l-z6!-#ӓABEߠ) 1#:u{n'* | p=fUF?8#)S(5aM` `"Ⓑ||yJ-'7Hϟ><}-чΝv$Cj˄-Y۴GԢǽqgnp̀7~:)bƙmD p38ԉ(wIT&'̆ZOM}TDӒ0m"ޭأOۍ(~/8ПVY;xϸu?Lh5F{NL#F{ӿ2=$ZlwjFA$%!NØ]dEJEr a$JB21*=9l8r$z}v=ȷ|)n)ADJǣ}L0j~{^ckE8R 4eAM} 5 4x5!؍^)A0aiTw[؜ky~Iq0$pZجfuv!SQB'm!5i~ zKܰ^ )֖XPv\\u܅r<*jn]3&)벎L3{|y>u{PbiE^Qk1^@%H\#!7 #ɢֳso3KHp׸X*#r>쨻O;<6FձP?//жd!Ҥ*CE˳4VFdP66Ù ˠ-CMHJh[#W;xΕQz#1l>k9*j{SsjD`[5%@+w}#[kliqG:q3B$6sYjeBk&b<&ĀьXt``6з),MFbR` 鰸?ٍ~\Q}C'g?-l> ;n!u0F 9D iٵzَs%?PP 6CCI\Kϰ%Jfk=`3 ِBMg ad5cb[vq*yS#g3'aߤe~RؖVX͞NꩉAn($BB)!Wp˯evu9ޑ_~e1S]l^ԘyXGyXx?:2?\,(dHݔW@ ` .ɤe]Ut{) 䩁چU Ȓ@\NGVU/9Ƙ~ŒEaH*i!n{_ $L]ckԛ\s[҈'B0cvDL+*95>=uY'[feR=n]9YB"mÍrl5=Vw/}5ʽIFa߿yצD?}F{c]czdOML-s")l=hL#&#-2ȥG$ { EJ%GPmpVhln,]lA;3OPmo#m(: 3ū_nDgftE.I-ej*ON6~^z—R?=`uRXv{0VF¸UV^;Oqۿ"z g^k#&*?}$'thXv?eܫr*rHכ`D_>~xy5\JD-wŏMeӖ"fw7E(mػrƖ9% q=Jr=|NxKu5dr/ꛣ5XvVh n8v yKv:.kF2%\&u::% jSiz$_]j$_p!"%Jh-`3vx[a}~7'tfSr[R x,)p0OKY<'@LI s͈TjԖ+js+l_|p._>}Szp!2.6v.ܬbB-x6g.Lz*cU;LF=1׊/H#bqDEs֜j斊$URt~V䛕3ˉ5zdoB@7H0װhA#Ƈ̶B#nTKdޭ>h;-^{; ˧~;<e'/Im3NA@᩿,<9 v@m-C}Bsr,$Z(]VL<ߘ/p sCä}탺hXSШI>0ppKt5Nr(&SC!o-L/ a" 2'L䡟]47=pָyt.T4G6f oa(` 82 "o֐4-Yv_f\|Ia5@(uSg\s$ 8@zXGEVL'|_u hy $HU2O'2h8CBa쫨v9"Ւ˚n:R/J).϶ΪH]Ì?gh2q T?WtrdEm革`V?Ƿ__|}~K$F#쥴 2GC[FQY-B5vc.d#E'on@e%JU"Q'lQ9m^aӹ pZ461Bs\^6"Swl >\f%GU`HwsTSf֖.ZeC-(61GfFW ѐc~e{ "d/H]e#T%tzmmbd}ѯN75O$m8=^֠ROȓTRDmm&y.K!DO;RrnQ$"'W_-sxELXC H uiyovՌjJ7'܌@<ə~fl U 6'Xr ]1Q_"ȆzJa&O#ؼ/wZuPrt :?tx-esӶK[K_ߨP&C2Vn]DmYDQڐ ho_:4P45}ǐ<^M& =vaU)ʅت8=NG6.?[RAz*>uѸW'o6گ,nڮCEqzٹ7WOt`\эV``h#yP cejneId(E< /uh!כV8Z<;,w{W/ h% QoMvnZ hVX뺋) D#[|&k3<B`ܾؖ^<ǽ~Q6j 4enOMfk(=5*l+jm:~JPʩjz0/;L&Ï{L߱bs`@exRBn h^N|=\YίLHu#vylgIa ǮE$1jC-00@?57_ksZm{:6"VύE͖Y{0-HCH0y$9%nDS_8Ph9ʆR^s2FIi=}Nr 귎fޡDp-uiL f.i%hH"Q^vѤ\$Ӽ̃<>ygIo'$Nr|b9HzN @X.CJX݈zL${]Io]k*]hCVt  (MG_)7=ctFyz$œ|I`L3OޔNN=q[*B)kӳs}-P}P8 J?xNd: ^&F*vcW(]YqzɞC%eơ`[̺;inu0Qe>[Zye')8LYQ Ue[)dƈ3SYAɵ6L .Hn|,ʿ5;ws"lwo8omQo퇯ߵtl R 61!#tmFR4A۠N7!2vmTF#`Ty`]NꥶD->BFO`$TŴvej4# f<I(s4"^䚄QlLi|j+n%5>&5f5m\L-Q5#Epʵ)HYz$)W &;uWxKuc!HU οY!_<¬gg2G?}Н|dW Z>+^{ɍ9 o>~__4H~|y6d5(;!r˼ǐAIَ.T*:.-iڌ\KP\})9Q< DžƅϰVQܯC9KФ!HEV{3)9h=X4< nr|b2J-pKeYf3.0iBfuunjG3ZMzrnjIյyU| +v z̾۬"P=Ki]9*D& 76>G+hww}}V9w/1헗?#Fo?y3XҀG8k]!l}g7!l?` }LnReWχ g*W<14SA!4HS3ͬʭT^)Llj́ &tdxKܩN՚CKyc ;xMԥO.m.[BzMq%Bp2d~iOIF2 ?a gYnuq-$UFmb}AݻAc$`izt"jYiUy`l4";&ųVaE;4ewo<;^oiտyoERTC ϥNBiNRQ9q\o8`׏zT-%5Rj7>-rSN *d2) Q' Yi"`;Ab<&րythv~en \[ L* 2.g;b qk%Ď\(cX;[8]Εyܻ(!%q1o6J֡Kՙo=0و֐~(Zjۂ2\6X<'JK{7l5s$~)UΨKmg+QeMI )KSFWfֶu"2 -S kZvI*M^LOuŘ̶Dh+΍t'8NC-6S~m]"A1z=Zo֌{ ě W!:(c68j]21]/tTs6Ilʟ B!x/r&C<"ԣ1 :CHy,+Cݽ#ĘOL跗?cia{)?1!3͗{ + MhΡOUYRg_JL*5 %yeE Ѽ619h~yb 9a!-TO.8II)䜉|| Usc'B!S!l:8$D1n=QS`HN2g QjZ-RJM.]f Ë<+ 9f^5O[sK#"ņT*P_U$t`),ɹhٝ.&3W(&p&m|WR}+Om)zup],VDe{.m K?wyˇu0ebg<4ؤk)vmڴ,F̷1 'W:#L4CbCHhWڢ8LJ#s!+D̨zd&C4ċ()mTQ|NA Һ~ 츲'OUt"‰099{-Ad8xɆA៛\lTBlwq^ˮnhP?E=fjTjmq)T{'o.LRv19ݬæ(/<އV%{7\|)ѼLD=/I~5p eUeMjw^w hzX[ۇ01DYpky iCF~g&AwK`$w!ŧqM:ppq'mgfM%^[5&0,T': mӸoX\D`&|BZ3u-x0}BcʰIQHtV6me6%3~Cv;ԇיX('VH!񩊵:K\قOh =c&$#Ѳ 5`yXXuLyh>n^-aMǐ;X>YVG?R_~0?t yW]s0 x-v+8h֪Eh2,4j3'OnvJ3e]6hSV`}$)#kW>9ct+I\lcV~1:)WXe-Bfa5Z`j'5f}n-uCl uBOi_T3޼n3X߁qi}z(fg S0D_+r991PŪdhǏθoCxkkq?[>oW`#>ʮw]a~}W-"g0\()*4c"J>j*B`GLߺ"Z߁6E[UT AJ>f#Vbo E]2bgz26|3|MS!o#'ƦzcScq:_[ٺ$ږz!gH0޴k]w)?u]N:gĭ's#S[qy5o@<}_^>}p1MeF+]ۺx.D<ÇF<]#1赳^v 1\懣lėMcאj[ϰbٹ&'j27Skd@^٬<^, u绣 AlzmzOՙɤVKo$-ڮ2Ȕ婂h ֶz5x#\2u!Ĭ+Ɛ6)Ɠ ߅yމ1IZ(86݇7<8\/^':%gG?lR+RA=IG1u،8KCƣI=BkSµ JiֱGk&3 {m {&"xFsFkfyhƢkf J`}3/vKpkṎPlEl >ظ F&ȾǗZ\A!8jpuCzz-]I*0g @mw _ }{'?=?\a:987讙4SfAE3vǢ4FqtUQ[b66%e9UBu͕.0+:1#blI9^xn'KB][&bbPGav<a=bUS!ܙD,s撩imyYo=/^^e0$[A;-MjDZ[NهA}q/aEi =SIR-f*65glXqk5e~$e2K nnc܊, HIfgֈQQ6p)_YZE٩7$qΌ}26pXڈSI?cb_]+OOb4W+ggގЌ#ڶ1g™U%B}nվwOhúC|2!;;?voĤGxOo{Б^>:FZ5EΛc<Ȕ,5nwUX1;eVm=Oƞ{f-]dX:t±] sD̮l}kt2%SeInH\FUĔW@=EC=KCne[$oKٚMm _S'oy˰I4':B.'ʹz^DU⡸Z 7$V J:"8L)d=H zO]t:`2E ;=NGg5BQށ}G*ֻ޽}x\[,ieҔdUxnFAG 8|nUH}[DO-YcJRoiC&`,\vj޲JwAE{{,6jA7"K|1bv"W k/y`S߽t_vht;s^I-X: ܻOy̽=(1Pֹ!Jah4\$_=`s4ΌG-經yQ2;mtn=cvND]VCD+~8n)0 A}A֕朳F lUD?fyyV~t3:+?rmH)ۘ%a;qhv`]4Gr:wy_4!vjqM;Wy5[[R|OgHA)z!7ԼdP IȘ]LX'JO ׇ#rMoLWz#!`PHG~)wT%w!Ÿ~~I2q2]kߑ**9I}jqĈe bbp崝:G: 1×6& :< ܃:F>t5k7 b9˪e`&%L8]ˍ FV˜6(^ SCDl}85 ڼjϜʄt]͖,}_ǸQ0A·$z&7DavMx}in-)`.~T4L_x;svH8 Q7\]Evr%H M}q%dC0CƵQA,N$;vw/KU%`s8cCޗZT h0š֐ 5{G{X Cm5;w?ėZ~갿_t@y {8Skӷw8qzJc V܈ *{\ >FzlSEEқV*EP-!sdys ~67u3fCFuq}l>N6VF͈MC0lʘpF4q0EM*镍bh$ 쪑"sivUeחF]>V`%%"@d#rV(7]oU|$…ýesC U?wǹɂcJ}Bsc<t$J:u !4s<9vH}j+٘O)ø -DMB 'STJkj%+jʬίX?I.\Ȑ 1O4qmIɺ>AՠTlǴ 6%&HuMn {fѯք.jWd(džLwgg5m1Xۆ':=3vj[Ot %3됮PtY@ӆ\z YYn!is4\f \/zoCavo>}}40^="u1YĻ2ڍX]VdZؐ=`@zP$$|hX"Զ7f 020BY fӜBCf}ƩΥ2gۓv”(r̎F{m.~%fԽD|(E>L@"{*S6mӉkFo0g[PK~2 NQQN~'-:f6s($-Uir 75Q[߶^5xnx3^? ~lDo2Q^s.Y&vx7u`@II;uKߪ+B;L7!Ie)TņǘȽ6 'gg@\z |0M̳(?[4GOla ?h7F7bG1{NRV{inGoHl8_k7rզ!Y.c~TEzא.7jzNbOs4Z{|A$qƊ~Fq|ٕ0XfK3kaYkP$wu9 s2WXaվY+*fhln*~E.YerK SR:lȍoW)D% (J||HiGw~'I ~awB߇4/1Н}? x3놝h#XC`]q`47~}hgE18C)5WS(VKL5GǍ+zZS9FG0Å{3:]޿^}ȀYǷ|CE>ֆnj D'InmJ6Uq)V9|=vMErDҿpw:xu%N B ~zjbvҳC'|D3 5=ҏ@3*W$m`.Iu1GOP>f!! v4 04TaFG ӦD ־Bt ~UG3+w8֑M֍Ugs1Kvo6[*r60X6 O҉ï]h$09_t_w7r_^?= n%tpB@;pAJ4PnAo(Z;+homahs %B'жH݇` qMGL:LѪKhhdk?,B&5ՂAwxM' jiXit- Ts_a(^R*fw7{F]z\?G=I\:].R h3 bJQ宍s>q@WOÏ V+nib׹+ N,)eV#i$Zx'|r}HvaF=\ҽk2OUdryG[7^;#eQ9>DĻ kj!h>j7T%fA*]"BU+Bp.;bf KfI&vlw%<WQM@zUl%_!p}̀VrD*p [Q`v݃7|djT~{G3i(TOr7RbPgRvzGCWצ|{KM."jU\i+<bLd-4#:/mI 0!_6 j(i7:ES$`ad:DVvl+>`j꟯4djnA*Nռ4#H#l! !bB>]on9;'&/^/Aik@ɔP:H\IsxR8hwNlHE&Ȉ 4+ؙE:I&ZX5LA 3NFܟ\[?{!d_ykYJ}-ֿ>eٸا|>d49'pLCńy\6c(ʆ7;'A[޻3%-f<M#:)f-s̀.۠7ׁOG,0v2FR˵޷"Ӎa ʐM Ҿ;ZYŴ<:3zXOe=M8eq|Z99LКM9G}8~UEU"_MWMXЁQ( >#+>#0Q?Q?ɀv#F !'%F z7TOS*/+3L|Ϡ`ɫ3;W֮OI@qn_uXťaܴŶ$!EUՅۆ@m/uk7fC&J*$Lms܏b;`3\&aW-%N$E302#}tTtҖ)a>(6Nwo-uڽC7ܨneMX-[ӵWu_ Tng[fN@=uj'qM:7. d} eU4kxWQ Nf_lC[HQo+3O:5~ԣ!fR[6.< Ȱxrviԛj%p;봷auDqk@wb6|¸ּSEاE)T2Dyz>syFܗy+ȁU7 &y 3%p`N-tL{.S= q-k?^ˎ['/d] Zs2hƋ8tLc(>~ʔ*L`IFɚ!@N`/vk/Q~ Ť#MJu4v ]f|v2k幥:v 0{dZF;w:S]tAA<SyD5y6n8mrHϦOOϒXDWHx+A&(ɩ9u#FGqPA`C;.t A/qQ>[[BhOnQb1f#=QU2gu3]bZEGaW5q}W zƎ,ϞǬJudrٛuinvufTOLwZRy+¢cn =m]uFLVZ3 4 Η1D;J*$̛'Bҹ)U! 1um)U~tC ř6iy@X;(ݍ5O8&>(KO3İ DMbh6/2(c%uHTeƒ4?)G(^>_+h&“.`dzc[7%=BN<~ZswC(:?Rc~go-.{y{`& ة2RɇZ['$ n>|Wonָhہ!aVj 9ЧV#b3P@^`y0h'yLninJX-/6Fc b|J! 4 zyr#pf;Ȟ -D`eX<6>73m׭ /k<ө06q6jU 7p 8O"fZnV~`VY9{sWZݐP#vW^Tށ"!UW=HHh_e5ܟ_?|ɔ/ǽ RObu9yڈ|v|LBa+JSM% ʐXz0jQas*MQ۞q̖0gH[Ճ2Mg^UO[miJ @Fb A}L%&nyE#axc,+cebUZ?'I(wT~)l3=j;mj}_0_! (Ql2FDž?ltl+L)Ƃ;s5Tu-〿s7:nv0#m`KS޿e#a6.BY?|廏o>NFԽ5DWvn|_׻"`֔"@)Ֆka$lWqNFb>^2ΙwRߖ dڭmש3k]BA :i=CF3`*tm uRpXZGĵS_IFe>frڸ~T6p}9Wio_2jiuǸ+(uuHLFiZ?t˹^u$nw!7b_25pD KQ>q^hG4UVN_V< L0TMzW{ʴ%-ꪙ1Hmڙ%ɸ5Fzrj3rhasj^Q?cKԄ6yLUj52!!7ԧj62+%kWZ I2{G%FUY0 Id1)m~%J1μUt?~jNuB G2&Xffd>f|3a`C}_ևiY)vK⍐C3*cbZܨydAAJ76l)5Dc,~͋"nsDDvN`^|:X \ȴSx/e9\~~|S xptQR. iAŒr`,~7aduJn} ;L=xM?_q/kJ^: zҍk]:r__]"Ga=<5ݧL*ŷHnDE !EF"$rܱ,gJɁiR@LJrTeݘy.*WN i Z!&PfO!DyURL}.l2PQVկ8r6X7L:ш"7D9%jk:&W=#6]eGQbm둊uUL!! 301#v8~E+߻jEv~y@_׿0v;j%씤EPGNb҈W9 Py]-+0| 'NxLlS# qM72s"Fo|'`8*" h <iï͓"y(FCѹvj1A2Xҳc[ S˕,:ףD9'%*h}Occ a:(Q7YfukC4Qy |hW}uP= caR6g&pM>4|!呂\S.pczWU}{ˣR-TN?|y|rˉF+mȹضsDv9kq{ڢoOAOB4> \c=ڂ9*{L\jSYMcJ}sBS=דOƳ*29/"#oLC"xAO-n9 `:ǣ qk9"Kf񪞪udd'KNvwGV@4$7TWa62G~Mt͗[yRPe$cz[hyCOϏ:L)c~Z3Cm#nLcFz5D4 (LaysVqVIH WgW%TWeP5^ (i;)c-]0M+HFUwB}St9fg],;x1Xl0[Ja=mM痙pekÀ=5Tu<%:@vP "!]S903oRU7S`=$iiD=& όBj7ܿ#z4 zWů@ZY5t7$-j8{utu}nĮ$GsBJ1<A6Q:9g|&Ru.[ - op0]S2'3{zti۾O)AךY,ьkofAr4r$hO|61/ P:vli~w7&zS />~‘hOvf_5 =.Vd6^?\ ?2a3q?ѧ8*u8̎|io1k [cR=aR9~QMR7!Ԉ;o:D`“U a{e2f4d|Y7Pf@9U/$Fi^T (s(0Dhmh:ɘ,=Z$s NDs8մW:쐮1 |%ef*}h伶KHBpx1r]3 xziaw]s>, !C:EUkιؚ~+NoNyJ+q ; p_&OHuˆ6k3R0.$@ >:Wc&H8z$4'766;'>l& n0D *m?!X@Փ)94u*0L<hňIiX2B%zX6*pRs)=X z@j85撖W$`ғ?ص̍fUGlnc>qyc)<_FrKb7 (cߛѯm!g6M60]yG@1D=!ơ|X@Kf¸"adBOhR P\NF`n X+X#s3YMW!kJ·m=Km9e;bk4)pOS7TAn=Aҍ3h@-]qtУq_HZ'{2m: ̤b/z{ݗ V2jvpRc۴tRU@AlTq1>m?0ݦq͖[3pc}vCDuZ8OJoB_Wz̻zLY @!Q|ߥ5dByRy 7lDL62+@E8#J(vٜ+k VT!emmJ5vDJW@xg