cluster-1.52a/0000755000100500010050000000000012177164024013115 5ustar mdehoonmdehooncluster-1.52a/python/0000755000100500010050000000000012177164023014435 5ustar mdehoonmdehooncluster-1.52a/python/test/0000755000100500010050000000000012177164023015414 5ustar mdehoonmdehooncluster-1.52a/python/test/test_Cluster.py0000644000100500010050000010525111505643553020456 0ustar mdehoonmdehoonimport unittest import numpy class TestCluster(unittest.TestCase): module = 'Bio.Cluster' def test_median_mean(self): if TestCluster.module=='Bio.Cluster': from Bio.Cluster import mean, median elif TestCluster.module=='Pycluster': from Pycluster import mean, median data = numpy.array([ 34.3, 3, 2 ]) self.assertAlmostEqual(mean(data), 13.1, places=3) self.assertAlmostEqual(median(data), 3.0, places=3) data = [ 5, 10, 15, 20] self.assertAlmostEqual(mean(data), 12.5, places=3) self.assertAlmostEqual(median(data), 12.5, places=3) data = [ 1, 2, 3, 5, 7, 11, 13, 17] self.assertAlmostEqual(mean(data), 7.375, places=3) self.assertAlmostEqual(median(data), 6.0, places=3) data = [ 100, 19, 3, 1.5, 1.4, 1, 1, 1] self.assertAlmostEqual(mean(data), 15.988, places=3) self.assertAlmostEqual(median(data), 1.45, places=3) def test_matrix_parse(self): if TestCluster.module=='Bio.Cluster': from Bio.Cluster import treecluster elif TestCluster.module=='Pycluster': from Pycluster import treecluster # Normal matrix, no errors data1 = numpy.array([[ 1.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ]]) # Another normal matrix, no errors; written as a list data2 = [[ 1.1, 2.2, 3.3, 4.4, 5.5 ], [ 3.1, 3.2, 1.3, 2.4, 1.5 ], [ 4.1, 2.2, 0.3, 5.4, 0.5 ], [ 12.1, 2.0, 0.0, 5.0, 0.0 ]] # Ragged matrix data3 = [[ 91.1, 92.2, 93.3, 94.4, 95.5], [ 93.1, 93.2, 91.3, 92.4 ], [ 94.1, 92.2, 90.3 ], [ 12.1, 92.0, 90.0, 95.0, 90.0 ]] # Matrix with bad cells data4 = [ [ 7.1, 7.2, 7.3, 7.4, 7.5, ], [ 7.1, 7.2, 7.3, 7.4, 'snoopy' ], [ 7.1, 7.2, 7.3, None, None]] # Matrix with a bad row data5 = [ [ 23.1, 23.2, 23.3, 23.4, 23.5], None, [ 23.1, 23.0, 23.0, 23.0, 23.0]] # Various references that don't point to matrices at all data6 = "snoopy" data7 = {'a': [[2.3,1.2],[3.3,5.6]]} data8 = [] data9 = [None] try: treecluster(data1) except: self.fail("treecluster failed to accept matrix data1") try: treecluster(data2) except: self.fail("treecluster failed to accept matrix data2") self.assertRaises(TypeError, lambda : treecluster(data3)) self.assertRaises(TypeError, lambda : treecluster(data4)) self.assertRaises(TypeError, lambda : treecluster(data5)) self.assertRaises(TypeError, lambda : treecluster(data6)) self.assertRaises(TypeError, lambda : treecluster(data7)) self.assertRaises(TypeError, lambda : treecluster(data8)) self.assertRaises(TypeError, lambda : treecluster(data9)) def test_kcluster(self): if TestCluster.module=='Bio.Cluster': from Bio.Cluster import kcluster elif TestCluster.module=='Pycluster': from Pycluster import kcluster nclusters = 3 # First data set weight = numpy.array([1,1,1,1,1]) data = numpy.array([[ 1.1, 2.2, 3.3, 4.4, 5.5], [ 3.1, 3.2, 1.3, 2.4, 1.5], [ 4.1, 2.2, 0.3, 5.4, 0.5], [12.1, 2.0, 0.0, 5.0, 0.0]]) mask = numpy.array([[ 1, 1, 1, 1, 1], [ 1, 1, 1, 1, 1], [ 1, 1, 1, 1, 1], [ 1, 1, 1, 1, 1]], int) clusterid, error, nfound = kcluster(data, nclusters=nclusters, mask=mask, weight=weight, transpose=0, npass=100, method='a', dist='e') self.assertEqual(len(clusterid), len(data)) correct = [0,1,1,2] mapping = [clusterid[correct.index(i)] for i in range(nclusters)] for i in range(len(clusterid)): self.assertEqual(clusterid[i], mapping[correct[i]]) # Second data set weight = numpy.array([1,1]) data = numpy.array([[ 1.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ]]) mask = numpy.array([[ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ]], int) clusterid, error, nfound = kcluster(data, nclusters=3, mask=mask, weight=weight, transpose=0, npass=100, method='a', dist='e') self.assertEqual(len(clusterid), len(data)) correct = [0, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 1] mapping = [clusterid[correct.index(i)] for i in range(nclusters)] for i in range(len(clusterid)): self.assertEqual(clusterid[i], mapping[correct[i]]) def test_clusterdistance(self): if TestCluster.module=='Bio.Cluster': from Bio.Cluster import clusterdistance elif TestCluster.module=='Pycluster': from Pycluster import clusterdistance # First data set weight = numpy.array([ 1,1,1,1,1 ]) data = numpy.array([[ 1.1, 2.2, 3.3, 4.4, 5.5, ], [ 3.1, 3.2, 1.3, 2.4, 1.5, ], [ 4.1, 2.2, 0.3, 5.4, 0.5, ], [ 12.1, 2.0, 0.0, 5.0, 0.0, ]]) mask = numpy.array([[ 1, 1, 1, 1, 1], [ 1, 1, 1, 1, 1], [ 1, 1, 1, 1, 1], [ 1, 1, 1, 1, 1]], int) # Cluster assignments c1 = [0] c2 = [1,2] c3 = [3] distance = clusterdistance(data, mask=mask, weight=weight, index1=c1, index2=c2, dist='e', method='a', transpose=0); self.assertAlmostEqual(distance, 6.650, places=3) distance = clusterdistance(data, mask=mask, weight=weight, index1=c1, index2=c3, dist='e', method='a', transpose=0); self.assertAlmostEqual(distance, 32.508, places=3) distance = clusterdistance(data, mask=mask, weight=weight, index1=c2, index2=c3, dist='e', method='a', transpose=0); self.assertAlmostEqual(distance, 15.118, places=3) # Second data set weight = numpy.array([ 1,1 ]) data = numpy.array([[ 1.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ]]) mask = numpy.array([[ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ]], int) # Cluster assignments c1 = [ 0, 1, 2, 3 ] c2 = [ 4, 5, 6, 7 ] c3 = [ 8 ] distance = clusterdistance(data, mask=mask, weight=weight, index1=c1, index2=c2, dist='e', method='a', transpose=0); self.assertAlmostEqual(distance, 5.833, places=3) distance = clusterdistance(data, mask=mask, weight=weight, index1=c1, index2=c3, dist='e', method='a', transpose=0); self.assertAlmostEqual(distance, 3.298, places=3) distance = clusterdistance(data, mask=mask, weight=weight, index1=c2, index2=c3, dist='e', method='a', transpose=0); self.assertAlmostEqual(distance, 0.360, places=3) def test_treecluster(self): if TestCluster.module=='Bio.Cluster': from Bio.Cluster import treecluster elif TestCluster.module=='Pycluster': from Pycluster import treecluster # First data set weight1 = [ 1,1,1,1,1 ] data1 = numpy.array([[ 1.1, 2.2, 3.3, 4.4, 5.5], [ 3.1, 3.2, 1.3, 2.4, 1.5], [ 4.1, 2.2, 0.3, 5.4, 0.5], [ 12.1, 2.0, 0.0, 5.0, 0.0]]) mask1 = numpy.array([[ 1, 1, 1, 1, 1], [ 1, 1, 1, 1, 1], [ 1, 1, 1, 1, 1], [ 1, 1, 1, 1, 1]], int) # test first data set # Pairwise average-linkage clustering" tree = treecluster(data=data1, mask=mask1, weight=weight1, transpose=0, method='a', dist='e') self.assertEqual(len(tree), len(data1)-1) self.assertEqual(tree[0].left, 2) self.assertEqual(tree[0].right, 1) self.assertAlmostEqual(tree[0].distance, 2.600, places=3) self.assertEqual(tree[1].left, -1) self.assertEqual(tree[1].right, 0) self.assertAlmostEqual(tree[1].distance, 7.300, places=3) self.assertEqual(tree[2].left, 3) self.assertEqual(tree[2].right, -2) self.assertAlmostEqual(tree[2].distance, 21.348, places=3) # Pairwise single-linkage clustering tree = treecluster(data=data1, mask=mask1, weight=weight1, transpose=0, method='s', dist='e') self.assertEqual(len(tree), len(data1)-1) self.assertEqual(tree[0].left, 1) self.assertEqual(tree[0].right, 2) self.assertAlmostEqual(tree[0].distance, 2.600, places=3) self.assertEqual(tree[1].left, 0) self.assertEqual(tree[1].right, -1) self.assertAlmostEqual(tree[1].distance, 5.800, places=3) self.assertEqual(tree[2].left, -2) self.assertEqual(tree[2].right, 3) self.assertAlmostEqual(tree[2].distance, 12.908, places=3) # Pairwise centroid-linkage clustering tree = treecluster(data=data1, mask=mask1, weight=weight1, transpose=0, method='c', dist='e') self.assertEqual(len(tree), len(data1)-1) self.assertEqual(tree[0].left, 1) self.assertEqual(tree[0].right, 2) self.assertAlmostEqual(tree[0].distance, 2.600, places=3) self.assertEqual(tree[1].left, 0) self.assertEqual(tree[1].right, -1) self.assertAlmostEqual(tree[1].distance, 6.650, places=3) self.assertEqual(tree[2].left, -2) self.assertEqual(tree[2].right, 3) self.assertAlmostEqual(tree[2].distance, 19.437, places=3) # Pairwise maximum-linkage clustering tree = treecluster(data=data1, mask=mask1, weight=weight1, transpose=0, method='m', dist='e') self.assertEqual(len(tree), len(data1)-1) self.assertEqual(tree[0].left, 2) self.assertEqual(tree[0].right, 1) self.assertAlmostEqual(tree[0].distance, 2.600, places=3) self.assertEqual(tree[1].left, -1) self.assertEqual(tree[1].right, 0) self.assertAlmostEqual(tree[1].distance, 8.800, places=3) self.assertEqual(tree[2].left, 3) self.assertEqual(tree[2].right, -2) self.assertAlmostEqual(tree[2].distance, 32.508, places=3) # Second data set weight2 = [ 1,1 ] data2 = numpy.array([[ 0.8223, 0.9295 ], [ 1.4365, 1.3223 ], [ 1.1623, 1.5364 ], [ 2.1826, 1.1934 ], [ 1.7763, 1.9352 ], [ 1.7215, 1.9912 ], [ 2.1812, 5.9935 ], [ 5.3290, 5.9452 ], [ 3.1491, 3.3454 ], [ 5.1923, 5.3156 ], [ 4.7735, 5.4012 ], [ 5.1297, 5.5645 ], [ 5.3934, 5.1823 ]]) mask2 = numpy.array([[ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ]], int) # Test second data set # Pairwise average-linkage clustering tree = treecluster(data=data2, mask=mask2, weight=weight2, transpose=0, method='a', dist='e') self.assertEqual(len(tree), len(data2)-1) self.assertEqual(tree[0].left, 5) self.assertEqual(tree[0].right, 4) self.assertAlmostEqual(tree[0].distance, 0.003, places=3) self.assertEqual(tree[1].left, 9) self.assertEqual(tree[1].right, 12) self.assertAlmostEqual(tree[1].distance, 0.029, places=3) self.assertEqual(tree[2].left, 2) self.assertEqual(tree[2].right, 1) self.assertAlmostEqual(tree[2].distance, 0.061, places=3) self.assertEqual(tree[3].left, 11) self.assertEqual(tree[3].right, -2) self.assertAlmostEqual(tree[3].distance, 0.070, places=3) self.assertEqual(tree[4].left, -4) self.assertEqual(tree[4].right, 10) self.assertAlmostEqual(tree[4].distance, 0.128, places=3) self.assertEqual(tree[5].left, 7) self.assertEqual(tree[5].right, -5) self.assertAlmostEqual(tree[5].distance, 0.224, places=3) self.assertEqual(tree[6].left, -3) self.assertEqual(tree[6].right, 0) self.assertAlmostEqual(tree[6].distance, 0.254, places=3) self.assertEqual(tree[7].left, -1) self.assertEqual(tree[7].right, 3) self.assertAlmostEqual(tree[7].distance, 0.391, places=3) self.assertEqual(tree[8].left, -8) self.assertEqual(tree[8].right, -7) self.assertAlmostEqual(tree[8].distance, 0.532, places=3) self.assertEqual(tree[9].left, 8) self.assertEqual(tree[9].right, -9) self.assertAlmostEqual(tree[9].distance, 3.234, places=3) self.assertEqual(tree[10].left, -6) self.assertEqual(tree[10].right, 6) self.assertAlmostEqual(tree[10].distance, 4.636, places=3) self.assertEqual(tree[11].left, -11) self.assertEqual(tree[11].right, -10) self.assertAlmostEqual(tree[11].distance, 12.741, places=3) # Pairwise single-linkage clustering tree = treecluster(data=data2, mask=mask2, weight=weight2, transpose=0, method='s', dist='e') self.assertEqual(len(tree), len(data2)-1) self.assertEqual(tree[0].left, 4) self.assertEqual(tree[0].right, 5) self.assertAlmostEqual(tree[0].distance, 0.003, places=3) self.assertEqual(tree[1].left, 9) self.assertEqual(tree[1].right, 12) self.assertAlmostEqual(tree[1].distance, 0.029, places=3) self.assertEqual(tree[2].left, 11) self.assertEqual(tree[2].right, -2) self.assertAlmostEqual(tree[2].distance, 0.033, places=3) self.assertEqual(tree[3].left, 1) self.assertEqual(tree[3].right, 2) self.assertAlmostEqual(tree[3].distance, 0.061, places=3) self.assertEqual(tree[4].left, 10) self.assertEqual(tree[4].right, -3) self.assertAlmostEqual(tree[4].distance, 0.077, places=3) self.assertEqual(tree[5].left, 7) self.assertEqual(tree[5].right, -5) self.assertAlmostEqual(tree[5].distance, 0.092, places=3) self.assertEqual(tree[6].left, 0) self.assertEqual(tree[6].right, -4) self.assertAlmostEqual(tree[6].distance, 0.242, places=3) self.assertEqual(tree[7].left, -7) self.assertEqual(tree[7].right, -1) self.assertAlmostEqual(tree[7].distance, 0.246, places=3) self.assertEqual(tree[8].left, 3) self.assertEqual(tree[8].right, -8) self.assertAlmostEqual(tree[8].distance, 0.287, places=3) self.assertEqual(tree[9].left, -9) self.assertEqual(tree[9].right, 8) self.assertAlmostEqual(tree[9].distance, 1.936, places=3) self.assertEqual(tree[10].left, -10) self.assertEqual(tree[10].right, -6) self.assertAlmostEqual(tree[10].distance, 3.432, places=3) self.assertEqual(tree[11].left, 6) self.assertEqual(tree[11].right, -11) self.assertAlmostEqual(tree[11].distance, 3.535, places=3) # Pairwise centroid-linkage clustering tree = treecluster(data=data2, mask=mask2, weight=weight2, transpose=0, method='c', dist='e') self.assertEqual(len(tree), len(data2)-1) self.assertEqual(tree[0].left, 4) self.assertEqual(tree[0].right, 5) self.assertAlmostEqual(tree[0].distance, 0.003, places=3) self.assertEqual(tree[1].left, 12) self.assertEqual(tree[1].right, 9) self.assertAlmostEqual(tree[1].distance, 0.029, places=3) self.assertEqual(tree[2].left, 1) self.assertEqual(tree[2].right, 2) self.assertAlmostEqual(tree[2].distance, 0.061, places=3) self.assertEqual(tree[3].left, -2) self.assertEqual(tree[3].right, 11) self.assertAlmostEqual(tree[3].distance, 0.063, places=3) self.assertEqual(tree[4].left, 10) self.assertEqual(tree[4].right, -4) self.assertAlmostEqual(tree[4].distance, 0.109, places=3) self.assertEqual(tree[5].left, -5) self.assertEqual(tree[5].right, 7) self.assertAlmostEqual(tree[5].distance, 0.189, places=3) self.assertEqual(tree[6].left, 0) self.assertEqual(tree[6].right, -3) self.assertAlmostEqual(tree[6].distance, 0.239, places=3) self.assertEqual(tree[7].left, 3) self.assertEqual(tree[7].right, -1) self.assertAlmostEqual(tree[7].distance, 0.390, places=3) self.assertEqual(tree[8].left, -7) self.assertEqual(tree[8].right, -8) self.assertAlmostEqual(tree[8].distance, 0.382, places=3) self.assertEqual(tree[9].left, -9) self.assertEqual(tree[9].right, 8) self.assertAlmostEqual(tree[9].distance, 3.063, places=3) self.assertEqual(tree[10].left, 6) self.assertEqual(tree[10].right, -6) self.assertAlmostEqual(tree[10].distance, 4.578, places=3) self.assertEqual(tree[11].left, -10) self.assertEqual(tree[11].right, -11) self.assertAlmostEqual(tree[11].distance, 11.536, places=3) # Pairwise maximum-linkage clustering tree = treecluster(data=data2, mask=mask2, weight=weight2, transpose=0, method='m', dist='e') self.assertEqual(len(tree), len(data2)-1) self.assertEqual(tree[0].left, 5) self.assertEqual(tree[0].right, 4) self.assertAlmostEqual(tree[0].distance, 0.003, places=3) self.assertEqual(tree[1].left, 9) self.assertEqual(tree[1].right, 12) self.assertAlmostEqual(tree[1].distance, 0.029, places=3) self.assertEqual(tree[2].left, 2) self.assertEqual(tree[2].right, 1) self.assertAlmostEqual(tree[2].distance, 0.061, places=3) self.assertEqual(tree[3].left, 11) self.assertEqual(tree[3].right, 10) self.assertAlmostEqual(tree[3].distance, 0.077, places=3) self.assertEqual(tree[4].left, -2) self.assertEqual(tree[4].right, -4) self.assertAlmostEqual(tree[4].distance, 0.216, places=3) self.assertEqual(tree[5].left, -3) self.assertEqual(tree[5].right, 0) self.assertAlmostEqual(tree[5].distance, 0.266, places=3) self.assertEqual(tree[6].left, -5) self.assertEqual(tree[6].right, 7) self.assertAlmostEqual(tree[6].distance, 0.302, places=3) self.assertEqual(tree[7].left, -1) self.assertEqual(tree[7].right, 3) self.assertAlmostEqual(tree[7].distance, 0.425, places=3) self.assertEqual(tree[8].left, -8) self.assertEqual(tree[8].right, -6) self.assertAlmostEqual(tree[8].distance, 0.968, places=3) self.assertEqual(tree[9].left, 8) self.assertEqual(tree[9].right, 6) self.assertAlmostEqual(tree[9].distance, 3.975, places=3) self.assertEqual(tree[10].left, -10) self.assertEqual(tree[10].right, -7) self.assertAlmostEqual(tree[10].distance, 5.755, places=3) self.assertEqual(tree[11].left, -11) self.assertEqual(tree[11].right, -9) self.assertAlmostEqual(tree[11].distance, 22.734, places=3) def test_somcluster(self): if TestCluster.module=='Bio.Cluster': from Bio.Cluster import somcluster elif TestCluster.module=='Pycluster': from Pycluster import somcluster # First data set weight = [ 1,1,1,1,1 ] data = numpy.array([[ 1.1, 2.2, 3.3, 4.4, 5.5], [ 3.1, 3.2, 1.3, 2.4, 1.5], [ 4.1, 2.2, 0.3, 5.4, 0.5], [ 12.1, 2.0, 0.0, 5.0, 0.0]]) mask = numpy.array([[ 1, 1, 1, 1, 1], [ 1, 1, 1, 1, 1], [ 1, 1, 1, 1, 1], [ 1, 1, 1, 1, 1]], int) clusterid, celldata = somcluster(data=data, mask=mask, weight=weight, transpose=0, nxgrid=10, nygrid=10, inittau=0.02, niter=100, dist='e') self.assertEqual(len(clusterid), len(data)) self.assertEqual(len(clusterid[0]), 2) # Second data set weight = [ 1,1 ] data = numpy.array([[ 1.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ]]) mask = numpy.array([[ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ]], int) clusterid, celldata = somcluster(data=data, mask=mask, weight=weight, transpose=0, nxgrid=10, nygrid=10, inittau=0.02, niter=100, dist='e') self.assertEqual(len(clusterid), len(data)) self.assertEqual(len(clusterid[0]), 2) def test_distancematrix_kmedoids(self): if TestCluster.module=='Bio.Cluster': from Bio.Cluster import distancematrix, kmedoids elif TestCluster.module=='Pycluster': from Pycluster import distancematrix, kmedoids data = numpy.array([[2.2, 3.3, 4.4], [2.1, 1.4, 5.6], [7.8, 9.0, 1.2], [4.5, 2.3, 1.5], [4.2, 2.4, 1.9], [3.6, 3.1, 9.3], [2.3, 1.2, 3.9], [4.2, 9.6, 9.3], [1.7, 8.9, 1.1]]) mask = numpy.array([[1, 1, 1], [1, 1, 1], [0, 1, 1], [1, 1, 1], [1, 1, 1], [0, 1, 0], [1, 1, 1], [1, 0, 1], [1, 1, 1]], int) weight = numpy.array([2.0, 1.0, 0.5]) matrix = distancematrix(data, mask=mask, weight=weight) self.assertAlmostEqual(matrix[1][0], 1.243, places=3) self.assertAlmostEqual(matrix[2][0], 25.073, places=3) self.assertAlmostEqual(matrix[2][1], 44.960, places=3) self.assertAlmostEqual(matrix[3][0], 4.510, places=3) self.assertAlmostEqual(matrix[3][1], 5.924, places=3) self.assertAlmostEqual(matrix[3][2], 29.957, places=3) self.assertAlmostEqual(matrix[4][0], 3.410, places=3) self.assertAlmostEqual(matrix[4][1], 4.761, places=3) self.assertAlmostEqual(matrix[4][2], 29.203, places=3) self.assertAlmostEqual(matrix[4][3], 0.077, places=3) self.assertAlmostEqual(matrix[5][0], 0.040, places=3) self.assertAlmostEqual(matrix[5][1], 2.890, places=3) self.assertAlmostEqual(matrix[5][2], 34.810, places=3) self.assertAlmostEqual(matrix[5][3], 0.640, places=3) self.assertAlmostEqual(matrix[5][4], 0.490, places=3) self.assertAlmostEqual(matrix[6][0], 1.301, places=3) self.assertAlmostEqual(matrix[6][1], 0.447, places=3) self.assertAlmostEqual(matrix[6][2], 42.990, places=3) self.assertAlmostEqual(matrix[6][3], 3.934, places=3) self.assertAlmostEqual(matrix[6][4], 3.046, places=3) self.assertAlmostEqual(matrix[6][5], 3.610, places=3) self.assertAlmostEqual(matrix[7][0], 8.002, places=3) self.assertAlmostEqual(matrix[7][1], 6.266, places=3) self.assertAlmostEqual(matrix[7][2], 65.610, places=3) self.assertAlmostEqual(matrix[7][3], 12.240, places=3) self.assertAlmostEqual(matrix[7][4], 10.952, places=3) self.assertAlmostEqual(matrix[7][5], 0.000, places=3) self.assertAlmostEqual(matrix[7][6], 8.720, places=3) self.assertAlmostEqual(matrix[8][0], 10.659, places=3) self.assertAlmostEqual(matrix[8][1], 19.056, places=3) self.assertAlmostEqual(matrix[8][2], 0.010, places=3) self.assertAlmostEqual(matrix[8][3], 16.949, places=3) self.assertAlmostEqual(matrix[8][4], 15.734, places=3) self.assertAlmostEqual(matrix[8][5], 33.640, places=3) self.assertAlmostEqual(matrix[8][6], 18.266, places=3) self.assertAlmostEqual(matrix[8][7], 18.448, places=3) clusterid, error, nfound = kmedoids(matrix, npass=1000) self.assertEqual(clusterid[0], 5) self.assertEqual(clusterid[1], 5) self.assertEqual(clusterid[2], 2) self.assertEqual(clusterid[3], 5) self.assertEqual(clusterid[4], 5) self.assertEqual(clusterid[5], 5) self.assertEqual(clusterid[6], 5) self.assertEqual(clusterid[7], 5) self.assertEqual(clusterid[8], 2) self.assertAlmostEqual(error, 7.680, places=3) def test_pca(self): if TestCluster.module=='Bio.Cluster': from Bio.Cluster import pca elif TestCluster.module=='Pycluster': from Pycluster import pca data = numpy.array([[ 3.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ], ]) mean, coordinates, pc, eigenvalues = pca(data) self.assertAlmostEqual(mean[0], 3.5461538461538464) self.assertAlmostEqual(mean[1], 3.5307692307692311) self.assertAlmostEqual(coordinates[0,0], 2.0323189722653883) self.assertAlmostEqual(coordinates[0,1], 1.2252420399694917) self.assertAlmostEqual(coordinates[1,0], 3.0936985166252251) self.assertAlmostEqual(coordinates[1,1], -0.10647619705157851) self.assertAlmostEqual(coordinates[2,0], 3.1453186907749426) self.assertAlmostEqual(coordinates[2,1], -0.46331699855941139) self.assertAlmostEqual(coordinates[3,0], 2.5440202962223761) self.assertAlmostEqual(coordinates[3,1], 0.20633980959571077) self.assertAlmostEqual(coordinates[4,0], 2.4468278463376221) self.assertAlmostEqual(coordinates[4,1], -0.28412285736824866) self.assertAlmostEqual(coordinates[5,0], 2.4468278463376221) self.assertAlmostEqual(coordinates[5,1], -0.28412285736824866) self.assertAlmostEqual(coordinates[6,0], -3.2018619434743254) self.assertAlmostEqual(coordinates[6,1], 0.019692314198662915) self.assertAlmostEqual(coordinates[7,0], -3.2018619434743254) self.assertAlmostEqual(coordinates[7,1], 0.019692314198662915) self.assertAlmostEqual(coordinates[8,0], 0.46978641990344067) self.assertAlmostEqual(coordinates[8,1], -0.17778754731982949) self.assertAlmostEqual(coordinates[9,0], -2.5549912731867215) self.assertAlmostEqual(coordinates[9,1], 0.19733897451533403) self.assertAlmostEqual(coordinates[10,0], -2.5033710990370044) self.assertAlmostEqual(coordinates[10,1], -0.15950182699250004) self.assertAlmostEqual(coordinates[11,0], -2.4365601663089413) self.assertAlmostEqual(coordinates[11,1], -0.23390813900973562) self.assertAlmostEqual(coordinates[12,0], -2.2801521629852974) self.assertAlmostEqual(coordinates[12,1], 0.0409309711916888) self.assertAlmostEqual(pc[0,0], -0.66810932728062988) self.assertAlmostEqual(pc[0,1], -0.74406312017235743) self.assertAlmostEqual(pc[1,0], 0.74406312017235743) self.assertAlmostEqual(pc[1,1], -0.66810932728062988) self.assertAlmostEqual(eigenvalues[0], 9.3110471246032844) self.assertAlmostEqual(eigenvalues[1], 1.4437456297481428) data = numpy.array([[ 2.3, 4.5, 1.2, 6.7, 5.3, 7.1], [ 1.3, 6.5, 2.2, 5.7, 6.2, 9.1], [ 3.2, 7.2, 3.2, 7.4, 7.3, 8.9], [ 4.2, 5.2, 9.2, 4.4, 6.3, 7.2]]) mean, coordinates, pc, eigenvalues = pca(data) self.assertAlmostEqual(mean[0], 2.7500) self.assertAlmostEqual(mean[1], 5.8500) self.assertAlmostEqual(mean[2], 3.9500) self.assertAlmostEqual(mean[3], 6.0500) self.assertAlmostEqual(mean[4], 6.2750) self.assertAlmostEqual(mean[5], 8.0750) self.assertAlmostEqual(coordinates[0,0], 2.6460846688406905) self.assertAlmostEqual(coordinates[0,1], -2.1421701432732418) self.assertAlmostEqual(coordinates[0,2], -0.56620932754145858) self.assertAlmostEqual(coordinates[0,3], 0.0) self.assertAlmostEqual(coordinates[1,0], 2.0644120899917544) self.assertAlmostEqual(coordinates[1,1], 0.55542108669180323) self.assertAlmostEqual(coordinates[1,2], 1.4818772348457117) self.assertAlmostEqual(coordinates[1,3], 0.0) self.assertAlmostEqual(coordinates[2,0], 1.0686641862092987) self.assertAlmostEqual(coordinates[2,1], 1.9994412069101073) self.assertAlmostEqual(coordinates[2,2], -1.000720598980291) self.assertAlmostEqual(coordinates[2,3], 0.0) self.assertAlmostEqual(coordinates[3,0], -5.77916094504174) self.assertAlmostEqual(coordinates[3,1], -0.41269215032867046) self.assertAlmostEqual(coordinates[3,2], 0.085052691676038017) self.assertAlmostEqual(coordinates[3,3], 0.0) self.assertAlmostEqual(pc[0,0], -0.26379660005997291) self.assertAlmostEqual(pc[0,1], 0.064814972617134495) self.assertAlmostEqual(pc[0,2], -0.91763310094893846) self.assertAlmostEqual(pc[0,3], 0.26145408875373249) self.assertAlmostEqual(pc[1,0], 0.05073770520434398) self.assertAlmostEqual(pc[1,1], 0.68616983388698793) self.assertAlmostEqual(pc[1,2], 0.13819106187213354) self.assertAlmostEqual(pc[1,3], 0.19782544121828985) self.assertAlmostEqual(pc[2,0], -0.63000893660095947) self.assertAlmostEqual(pc[2,1], 0.091155993862151397) self.assertAlmostEqual(pc[2,2], 0.045630391256086845) self.assertAlmostEqual(pc[2,3], -0.67456694780914772) # As the last eigenvalue is zero, the corresponding eigenvector is # strongly affected by roundoff error, and is not being tested here. # For PCA, this doesn't matter since all data have a zero coefficient # along this eigenvector. self.assertAlmostEqual(eigenvalues[0], 6.7678878332578778) self.assertAlmostEqual(eigenvalues[1], 3.0108911400291856) self.assertAlmostEqual(eigenvalues[2], 1.8775592718563467) self.assertAlmostEqual(eigenvalues[3], 0.0) if __name__ == "__main__": TestCluster.module = 'Bio.Cluster' runner = unittest.TextTestRunner(verbosity = 2) unittest.main(testRunner=runner) cluster-1.52a/python/test/README0000644000100500010050000000045111160362776016302 0ustar mdehoonmdehoonIf you use Pycluster, you can test your installation by running python setup.py test from the top directory (the one containing setup.py). If, instead, you are using Bio.Cluster (the C Clustering Library as part of the Biopython distribution), use python test_Cluster.py from this directory. cluster-1.52a/python/clustermodule.c0000644000100500010050000030265112174110223017465 0ustar mdehoonmdehoon#include "Python.h" #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include "numpy/arrayobject.h" #include #include #include #include "cluster.h" /* Must define Py_TYPE for Python 2.5 or older */ #ifndef Py_TYPE # define Py_TYPE(o) ((o)->ob_type) #endif /* Must define PyVarObject_HEAD_INIT for Python 2.5 or older */ #ifndef PyVarObject_HEAD_INIT #define PyVarObject_HEAD_INIT(type, size) \ PyObject_HEAD_INIT(type) size, #endif /* ========================================================================== */ /* -- Helper routines ------------------------------------------------------- */ /* ========================================================================== */ static int distance_converter(PyObject* object, void* pointer) { char c; const char* data; const char known_distances[] = "ebcauxsk"; #if PY_MAJOR_VERSION < 3 if (PyString_Check(object)) data = PyString_AsString(object); else #endif if (PyUnicode_Check(object)) data = PyUnicode_AS_DATA(object); else { PyErr_SetString(PyExc_ValueError, "distance should be a string"); return 0; } if (strlen(data)!=1) { PyErr_SetString(PyExc_ValueError, "distance should be a single character"); return 0; } c = data[0]; if (!strchr(known_distances, c)) { PyErr_Format(PyExc_ValueError, "unknown distance function specified (should be one of '%s')", known_distances); return 0; } *((char*)pointer) = c; return 1; } static int method_treecluster_converter(PyObject* object, void* pointer) { char c; const char* data; const char known_methods[] = "csma"; #if PY_MAJOR_VERSION < 3 if (PyString_Check(object)) data = PyString_AsString(object); else #endif if (PyUnicode_Check(object)) data = PyUnicode_AS_DATA(object); else { PyErr_SetString(PyExc_ValueError, "method should be a string"); return 0; } if (strlen(data)!=1) { PyErr_SetString(PyExc_ValueError, "method should be a single character"); return 0; } c = data[0]; if (!strchr(known_methods, c)) { PyErr_Format(PyExc_ValueError, "unknown method function specified (should be one of '%s')", known_methods); return 0; } *((char*)pointer) = c; return 1; } static int method_kcluster_converter(PyObject* object, void* pointer) { char c; const char* data; const char known_methods[] = "am"; #if PY_MAJOR_VERSION < 3 if (PyString_Check(object)) data = PyString_AsString(object); else #endif if (PyUnicode_Check(object)) data = PyUnicode_AS_DATA(object); else { PyErr_SetString(PyExc_ValueError, "method should be a string"); return 0; } if (strlen(data)!=1) { PyErr_SetString(PyExc_ValueError, "method should be a single character"); return 0; } c = data[0]; if (!strchr(known_methods, c)) { PyErr_Format(PyExc_ValueError, "unknown method function specified (should be one of '%s')", known_methods); return 0; } *((char*)pointer) = c; return 1; } static int method_clusterdistance_converter(PyObject* object, void* pointer) { char c; const char* data; const char known_methods[] = "amsxv"; #if PY_MAJOR_VERSION < 3 if (PyString_Check(object)) data = PyString_AsString(object); else #endif if (PyUnicode_Check(object)) data = PyUnicode_AS_DATA(object); else { PyErr_SetString(PyExc_ValueError, "method should be a string"); return 0; } if (strlen(data)!=1) { PyErr_SetString(PyExc_ValueError, "method should be a single character"); return 0; } c = data[0]; if (!strchr(known_methods, c)) { PyErr_Format(PyExc_ValueError, "unknown method function specified (should be one of '%s')", known_methods); return 0; } *((char*)pointer) = c; return 1; } /* -- data ------------------------------------------------------------------ */ static double** parse_data(PyObject* object, PyArrayObject** array) /* Takes the Python object from the argument list, and finds the microarray * data set. In case of an error, the array is DECREF'ed and set to NULL. */ { int i, j; int nrows, ncols; double** data = NULL; if(!PyArray_Check(object)) /* Try to convert object to a 2D double array */ { *array = (PyArrayObject*) PyArray_FromObject(object, NPY_DOUBLE, 2, 2); if (*array==NULL) { PyErr_SetString(PyExc_TypeError, "data cannot be converted to needed array."); return NULL; } } else /* User passed an array */ { *array = (PyArrayObject*) object; /* Check number of dimensions */ if (PyArray_NDIM(*array) == 2) Py_INCREF(object); else { PyErr_Format(PyExc_ValueError, "data has incorrect rank (%d expected 2)", PyArray_NDIM(*array)); *array = NULL; return NULL; } if (PyArray_TYPE(*array) != NPY_DOUBLE) /* Cast to type double */ { *array = (PyArrayObject*) PyArray_Cast(*array, NPY_DOUBLE); Py_DECREF(object); if (!(*array)) { PyErr_SetString(PyExc_ValueError, "data cannot be cast to needed type."); return NULL; } } } nrows = (int) PyArray_DIM(*array, 0); ncols = (int) PyArray_DIM(*array, 1); if (nrows != PyArray_DIM(*array, 0) || ncols != PyArray_DIM(*array, 1)) { PyErr_SetString(PyExc_ValueError, "data matrix is too large"); Py_DECREF((PyObject*) (*array)); *array = NULL; return NULL; } if (nrows < 1 || ncols < 1) { PyErr_SetString(PyExc_ValueError, "data is an empty matrix"); Py_DECREF((PyObject*) (*array)); *array = NULL; return NULL; } data = malloc(nrows*sizeof(double*)); if (PyArray_STRIDE(*array, 1)==sizeof(double)) /* Each row is contiguous */ { const char* p = PyArray_BYTES(*array); const npy_intp stride = PyArray_STRIDE(*array, 0); for (i=0; i < nrows; i++, p+=stride) data[i] = (double*)p; } else /* We need to create contiguous rows */ { const char* p0 = PyArray_BYTES(*array); const npy_intp rowstride = PyArray_STRIDE(*array, 0); const npy_intp colstride = PyArray_STRIDE(*array, 1); for (i=0; i < nrows; i++) { const char* p = p0; data[i] = malloc(ncols*sizeof(double)); for (j=0; j < ncols; j++, p+=colstride) data[i][j] = *((double*)p); p0 += rowstride; } } return data; } static void free_data(PyArrayObject* array, double** data) { if(data[0]!=PyArray_DATA(array)) { npy_intp i; npy_intp nrows = PyArray_DIM(array, 0); for (i=0; i 0 || ndata != 1) { PyErr_Format(PyExc_ValueError, "weight has incorrect rank (%d expected 1)", PyArray_NDIM(*array)); Py_DECREF(*array); *array = NULL; return NULL; } } /* All checks OK */ if (PyArray_ISCONTIGUOUS(*array)) weight = PyArray_DATA(*array); else { const char* p = PyArray_BYTES(*array); const npy_intp stride = PyArray_STRIDE(*array, 0); weight = malloc(ndata*sizeof(double)); for (i = 0; i < ndata; i++, p += stride) weight[i] = *(double*)p; } return weight; } static void free_weight(PyArrayObject* array, double* weight) { if (array) { if (weight!=PyArray_DATA(array)) free(weight); Py_DECREF((PyObject*) array); } else free(weight); return; } /* -- initialid ------------------------------------------------------------- */ static PyArrayObject* parse_initialid(PyObject* object, int* nclusters, npy_intp nitems) /* This function creates the clusterid variable for the kcluster and kmedoids * routines, and fills it with the initial clustering solution if specified * by the user in object. */ { npy_intp i; npy_intp stride; const char* p; int* q; int* number; PyArrayObject* array; /* -- First we create the clusterid variable ------------------------ */ PyArrayObject* clusterid = (PyArrayObject*) PyArray_SimpleNew(1, &nitems, NPY_INT); if (!clusterid) { PyErr_SetString(PyExc_MemoryError, "could not create clusterid array"); return NULL; } /* -- If the user didn't specify an initial clustering, we're done -- */ if (object==NULL) return clusterid; /* -- Check if the specified object is an array --------------------- */ if(!PyArray_Check(object)) { array = (PyArrayObject*) PyArray_FromObject(object, NPY_INT,1,1); if (!array) { PyErr_SetString(PyExc_TypeError, "initialid cannot be converted to needed array."); Py_DECREF((PyObject*) clusterid); return NULL; } } else { array = (PyArrayObject*) object; /* -- Check if the array contains integers ------------------------ */ if (PyArray_TYPE(array) == NPY_INT) Py_INCREF(object); else { array = (PyArrayObject*) PyArray_Cast(array, NPY_INT); if (!array) { PyErr_SetString(PyExc_ValueError, "initialid cannot be cast to needed type."); Py_DECREF((PyObject*) clusterid); return NULL; } } } /* -- Check the size of the array ----------------------------------- */ if(PyArray_NDIM(array) == 1) { /* no checking on last dimension of expected size 1 */ if (nitems!=1 && nitems!=PyArray_DIM(array, 0)) { PyErr_Format(PyExc_ValueError, "initialid has incorrect extent (%" NPY_INTP_FMT " expected %" NPY_INTP_FMT ")", PyArray_DIM(array, 0), nitems); Py_DECREF((PyObject*) array); Py_DECREF((PyObject*) clusterid); return NULL; } } else { if (PyArray_NDIM(array) > 0 || nitems != 1) { PyErr_Format(PyExc_ValueError, "initialid has incorrect rank (%d expected 1)", PyArray_NDIM(array)); Py_DECREF((PyObject*) array); Py_DECREF((PyObject*) clusterid); return NULL; } } /* -- The array seems to be OK. Count the number of clusters -------- */ *nclusters = -1; stride = PyArray_STRIDE(array, 0); p = PyArray_BYTES(array); for (i = 0; i < nitems; i++, p+=stride) { const int j = *((int*)p); if (j > *nclusters) *nclusters = j; if (j < 0) { PyErr_SetString(PyExc_ValueError, "initialid contains a negative cluster number"); Py_DECREF((PyObject*) array); Py_DECREF((PyObject*) clusterid); return NULL; } } (*nclusters)++; /* One more than the highest cluster index */ /* Count the number of items in each cluster */ number = calloc(*nclusters,sizeof(int)); p = PyArray_BYTES(array); q = PyArray_DATA(clusterid); for (i = 0; i < nitems; i++, p+=stride, q++) { *q = *((int*)p); number[*q]++; } /* Check if any clusters are empty */ for (i = 0; i < (*nclusters); i++) if(number[i]==0) break; free(number); Py_DECREF((PyObject*) array); if (i < (*nclusters)) /* Due to the break above */ { PyErr_Format(PyExc_ValueError, "argument initialid: Cluster %" NPY_INTP_FMT " is empty", i); Py_DECREF((PyObject*) clusterid); return NULL; } return clusterid; } /* -- clusterid ------------------------------------------------------------- */ static int* parse_clusterid(PyObject* object, PyArrayObject** array, unsigned int nitems, int* nclusters) /* This function reads the cluster assignments of all items from object */ { unsigned int i; int j; npy_intp stride; const char* p; int* number; int* clusterid; /* -- Default is to assign all items to the same cluster ------------ */ if (object==NULL) { clusterid = calloc(nitems, sizeof(int)); *array = NULL; *nclusters = 1; return clusterid; } /* -- The user specified something. Let's see if it is an array ----- */ if(!PyArray_Check(object)) { *array = (PyArrayObject*) PyArray_FromObject(object, NPY_INT, 1, 1); if (!(*array)) { PyErr_SetString(PyExc_TypeError, "clusterid cannot be converted to needed array."); return NULL; } } else { *array = (PyArrayObject*) object; /* -- Check if the array contains integers ------------------------ */ if (PyArray_TYPE(*array) == NPY_INT) Py_INCREF(object); else { *array = (PyArrayObject*) PyArray_Cast(*array, NPY_INT); if (!(*array)) { PyErr_SetString(PyExc_ValueError, "clusterid cannot be cast to needed type."); return NULL; } } } /* -- Check the array size ------------------------------------------ */ if(PyArray_NDIM(*array) == 1) { /* no checking on last dimension of expected size 1 */ if (nitems!=1 && nitems!=PyArray_DIM(*array, 0)) { PyErr_Format(PyExc_ValueError, "clusterid has incorrect extent (%" NPY_INTP_FMT " expected %d)", PyArray_DIM(*array, 0), nitems); Py_DECREF((PyObject*) (*array)); return NULL; } } else if (PyArray_NDIM(*array) > 0 || nitems != 1) { PyErr_Format(PyExc_ValueError, "clusterid has incorrect rank (%d expected 1)", PyArray_NDIM(*array)); Py_DECREF((PyObject*) (*array)); return NULL; } /* -- The array seems to be OK. Count the number of clusters -------- */ stride = PyArray_STRIDE(*array, 0); p = PyArray_BYTES(*array); *nclusters = -1; for (i = 0; i < nitems; i++, p+=stride) { j = (*(int*)p); if (j > *nclusters) *nclusters = j; if (j < 0) { PyErr_SetString(PyExc_ValueError, "clusterid contains an invalid cluster number"); Py_DECREF((PyObject*) (*array)); return NULL; } } (*nclusters)++; /* -- Count the number of items in each cluster --------------------- */ number = calloc(*nclusters, sizeof(int)); p = PyArray_BYTES(*array); for (i = 0; i < nitems; i++, p+=stride) { j = *((int*)p); number[j]++; } for (j = 0; j < (*nclusters); j++) if(number[j]==0) break; free(number); if (j < (*nclusters)) { PyErr_Format(PyExc_ValueError, "argument initialid: Cluster %d is empty", j); Py_DECREF((PyObject*) (*array)); return NULL; } /* All checks OK */ if (PyArray_ISCONTIGUOUS(*array)) clusterid = PyArray_DATA(*array); else { const char* p = PyArray_BYTES(*array); stride = PyArray_STRIDE(*array, 0); clusterid = malloc(nitems*sizeof(int)); for (i = 0; i < nitems; i++, p += stride) clusterid[i] = *(int*)p; } return clusterid; } static void free_clusterid(PyArrayObject* array, int* clusterid) { if (array) { if (clusterid!=PyArray_DATA(array)) free(clusterid); Py_DECREF((PyObject*) array); } else free(clusterid); } /* -- distance -------------------------------------------------------------- */ static void free_distances(PyObject* object, PyArrayObject* array, double** distance, int n) { int i; if (array==NULL) /* User passed a lower-triangular matrix as a list of rows */ { for (i = 1; i < n; i++) { PyObject* row = PyList_GET_ITEM(object, i); if (PyArray_Check(row)) { PyArrayObject* a = (PyArrayObject*)row; if (distance[i] == PyArray_DATA(a)) { Py_DECREF(row); continue; } } free(distance[i]); } } else { if (PyArray_NDIM(array) == 1) { const npy_intp stride = PyArray_STRIDE(array, 0); if (stride!=sizeof(double)) for (i = 1; i < n; i++) free(distance[i]); } else { const npy_intp stride = PyArray_STRIDE(array, 1); if (stride!=sizeof(double)) for (i = 1; i < n; i++) free(distance[i]); } Py_DECREF((PyObject*) array); } free(distance); } static double** parse_distance(PyObject* object, PyArrayObject** array, int* n) /* Takes the Python object from the argument list, and finds the distance * matrix. In case of an error, the array is DECREF'ed and set to NULL. */ { int i, j; double** distance = NULL; if(!PyArray_Check(object)) { /* Convert object to a 1D or 2D array of type double */ *array = (PyArrayObject*) PyArray_FromObject(object, NPY_DOUBLE, 1, 2); if (*array==NULL) { /* This is not necessarily an error; the user may have passed the * the lower-triangular matrix as a list of rows. Clear the error * indicator set by PyArrayFromObject first. */ PyErr_Clear(); if (!PyList_Check(object)) { PyErr_SetString(PyExc_TypeError, "distance cannot be converted to needed array."); *n = 0; return NULL; } *n = PyList_GET_SIZE(object); distance = malloc((*n)*sizeof(double*)); if (!distance) { PyErr_SetString(PyExc_MemoryError, "failed to store distance matrix."); *n = 0; return NULL; } for (i = 0; i < *n; i++) { PyObject* row = PyList_GET_ITEM(object, i); if (PyArray_Check(row)) { PyArrayObject* a = (PyArrayObject*)row; if (PyArray_NDIM(a) != 1) { PyErr_Format(PyExc_ValueError, "Row %d in the distance matrix is not one-dimensional.", i); break; } if (PyArray_DIM(a, 0) != i) { PyErr_Format(PyExc_ValueError, "Row %d in the distance matrix has incorrect size (%" NPY_INTP_FMT ", should be %d).", i, PyArray_DIM(a, 0), i); break; } if (i==0) continue; if (PyArray_TYPE(a) == NPY_DOUBLE) { const npy_intp stride = PyArray_STRIDE(a, 0); if (stride==sizeof(double)) /* Row is contiguous */ { Py_INCREF(row); distance[i] = PyArray_DATA(a); } else { const char* p = PyArray_BYTES(a); distance[i] = malloc(i*sizeof(double)); if(!distance[i]) { Py_DECREF((PyObject*)a); PyErr_Format(PyExc_MemoryError, "failed to store row %d in the distance matrix.", i); break; } for (j=0; j < i; j++, p+=stride) distance[i][j] = *((double*)p); } } else { row = PyArray_ContiguousFromObject(row, NPY_DOUBLE, 1, 1); if (!row) { PyErr_Format(PyExc_MemoryError, "Failed to cast row %d in the distance matrix to double precision.", i); break; } else { const double* p; a = (PyArrayObject*)row; p = PyArray_DATA(a); distance[i] = malloc(i*sizeof(double)); if(!distance[i]) { Py_DECREF(row); PyErr_Format(PyExc_MemoryError, "failed to store row %d in the distance matrix.", i); break; } for (j=0; j < i; j++, p++) distance[i][j] = *p; Py_DECREF(row); } } } else { /* Convert row */ const double* p; PyArrayObject* a = (PyArrayObject*)PyArray_ContiguousFromObject(row, NPY_DOUBLE, 1, 1); if(!a) { PyErr_Format(PyExc_TypeError, "Failed to convert row %d in the distance matrix.", i); break; } if (PyArray_DIM(a, 0) != i) { PyErr_Format(PyExc_ValueError, "Row %d in the distance matrix has incorrect size (%" NPY_INTP_FMT ", should be %d).", i, PyArray_DIM(a, 0), i); Py_DECREF((PyObject*)a); break; } if (i > 0) { distance[i] = malloc(i*sizeof(double)); if(!distance[i]) { Py_DECREF((PyObject*)a); PyErr_Format(PyExc_MemoryError, "failed to store row %d in the distance matrix.", i); break; } p = PyArray_DATA(a); for (j=0; j < i; j++) distance[i][j] = p[j]; } Py_DECREF((PyObject*)a); } } if (i < *n) /* break encountered */ { free_distances(object, NULL, distance, i); *n = 0; return NULL; } return distance; } } else { /* User passed an array */ *array = (PyArrayObject*) object; if (PyArray_TYPE(*array) == NPY_DOUBLE) Py_INCREF(object); else { *array = (PyArrayObject*) PyArray_Cast((*array), NPY_DOUBLE); if (!(*array)) { PyErr_SetString(PyExc_ValueError, "distance cannot be cast to needed type."); *n = 0; return NULL; } } } if (PyArray_NDIM(*array) == 1) { const npy_intp stride = PyArray_STRIDE(*array, 0); const char* p = PyArray_BYTES(*array); const int m = (const int) PyArray_DIM(*array, 0); if (m != PyArray_DIM(*array, 0)) { PyErr_SetString(PyExc_ValueError, "Array size of distance is too large"); Py_DECREF((PyObject*) (*array)); *array = NULL; *n = 0; return NULL; } *n = (int) ((1+sqrt(1+8*m))/2); if ((*n)*(*n)-(*n) != 2 * m) { PyErr_SetString(PyExc_ValueError, "Array size of distance is incompatible with a lower triangular matrix"); Py_DECREF((PyObject*) (*array)); *array = NULL; *n = 0; return NULL; } distance = malloc((*n)*sizeof(double*)); distance[0] = NULL; if (stride==sizeof(double)) /* Data are contiguous */ for (i=1; i < *n; p+=(i*stride), i++) distance[i] = (double*)p; else /* We need to create contiguous rows */ { for (i=1; i < *n; i++) { distance[i] = malloc(i*sizeof(double)); for (j=0; j < i; j++, p+=stride) distance[i][j] = *((double*)p); } } } else if (PyArray_NDIM(*array) == 2) { const char* p = PyArray_BYTES(*array); *n = (int) PyArray_DIM(*array, 0); if ((*n) != PyArray_DIM(*array, 0)) { PyErr_SetString(PyExc_ValueError, "The distance matrix is too large"); Py_DECREF((PyObject*) (*array)); *array = NULL; *n = 0; return NULL; } if ((*n) != PyArray_DIM(*array, 1)) { PyErr_SetString(PyExc_ValueError, "The distance matrix should be square"); Py_DECREF((PyObject*) (*array)); *array = NULL; *n = 0; return NULL; } distance = malloc((*n)*sizeof(double*)); distance[0] = NULL; if (PyArray_STRIDE(*array, 1)==sizeof(double)) /* Each row is contiguous */ { const npy_intp stride = PyArray_STRIDE(*array, 0); for (i=0; i < *n; i++, p+=stride) distance[i] = (double*)p; } else /* We need to create contiguous rows */ { const npy_intp stride = PyArray_STRIDE(*array, 1); for (i=0; i < *n; i++) { distance[i] = malloc(i*sizeof(double)); for (j=0; j < i; j++, p+=stride) distance[i][j] = *((double*)p); } } } else { PyErr_Format(PyExc_ValueError, "distance has an incorrect rank (%d expected 1 or 2)", PyArray_NDIM(*array)); Py_DECREF((PyObject*) (*array)); *array = NULL; *n = 0; return NULL; } return distance; } /* -- celldata -------------------------------------------------------------- */ static double*** create_celldata(int nxgrid, int nygrid, int ndata, PyArrayObject** array) { int i; npy_intp shape[3]; double* p; double** pp; double*** ppp; shape[0] = (npy_intp) nxgrid; shape[1] = (npy_intp) nygrid; shape[2] = (npy_intp) ndata; if (shape[0]!=nxgrid || shape[1]!=nygrid || shape[2]!=ndata) { PyErr_SetString(PyExc_RuntimeError, "celldata array too large"); return NULL; } *array = (PyArrayObject*) PyArray_SimpleNew(3, shape, NPY_DOUBLE); pp = malloc(nxgrid*nygrid*sizeof(double*)); ppp = malloc(nxgrid*sizeof(double**)); if (!(*array) || !pp || !ppp) { Py_XDECREF((PyObject*)(*array)); *array = NULL; if(pp) free(pp); if(ppp) free(ppp); PyErr_SetString(PyExc_MemoryError, "Could not create celldata array -- too big?"); return NULL; } p = PyArray_DATA(*array); for (i=0; i= 3 else index[0] = (int) PyLong_AS_LONG(object); #else else index[0] = (int) PyInt_AS_LONG(object); #endif *n = 1; return index; } /* Check if the user specified an array */ if(!PyArray_Check(object)) /* Try to convert to an array of type int */ { *array = (PyArrayObject*) PyArray_ContiguousFromObject(object, NPY_INT, 1, 1); if (!(*array)) { PyErr_SetString(PyExc_TypeError, "index argument cannot be converted to needed type."); *n = 0; return NULL; } } else { *array = (PyArrayObject*) object; /* -- Check if the array contains integers ------------------------ */ if (PyArray_TYPE(*array) == NPY_INT) Py_INCREF(object); else { object = PyArray_Cast(*array, NPY_INT); if (!object) { PyErr_SetString(PyExc_ValueError, "index argument cannot be cast to needed type."); *n = 0; return NULL; } *array = (PyArrayObject*) object; } } /* We have an array */ *n = (int) PyArray_DIM(*array, 0); if(PyArray_DIM(*array, 0) != *n) { PyErr_SetString(PyExc_ValueError, "data array is too large"); Py_DECREF(object); /* can only happen if *array==(PyArrayObject*)object */ *array = NULL; *n = 0; return NULL; } if(PyArray_NDIM(*array) != 1) { PyErr_Format(PyExc_ValueError, "index argument has incorrect rank (%d expected 1)", PyArray_NDIM(*array)); Py_DECREF(object); /* can only happen if *array==(PyArrayObject*)object */ *array = NULL; *n = 0; return NULL; } if (!PyArray_ISCONTIGUOUS(*array)) { *array = (PyArrayObject*) PyArray_ContiguousFromObject(object, NPY_INT, 1, 1); Py_DECREF(object); if(!(*array)) { PyErr_SetString(PyExc_ValueError, "Failed making argument index contiguous."); *array = NULL; *n = 0; return NULL; } } index = PyArray_DATA(*array); return index; } static void free_index(PyArrayObject* array, int* index) { if (array) Py_DECREF((PyObject*) array); else free(index); } /* ========================================================================== */ /* -- Classes --------------------------------------------------------------- */ /* ========================================================================== */ typedef struct { PyObject_HEAD Node node; } PyNode; static int PyNode_init(PyNode *self, PyObject *args, PyObject *kwds) { int left, right; double distance = 0.0; static char *kwlist[] = {"left", "right", "distance", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "ii|d", kwlist, &left, &right, &distance)) return -1; self->node.left = left; self->node.right = right; self->node.distance = distance; return 0; } static PyObject* PyNode_repr(PyNode* self) { char string[64]; sprintf(string, "(%d, %d): %g", self->node.left, self->node.right, self->node.distance); #if PY_MAJOR_VERSION >= 3 return PyUnicode_FromString(string); #else return PyString_FromString(string); #endif } static char PyNode_left__doc__[] = "integer representing the first member of this node"; static PyObject* PyNode_getleft(PyNode* self, void* closure) { int left = self->node.left; #if PY_MAJOR_VERSION >= 3 return PyLong_FromLong((long)left); #else return PyInt_FromLong((long)left); #endif } static int PyNode_setleft(PyNode* self, PyObject* value, void* closure) { long left = PyLong_AsLong(value); if (PyErr_Occurred()) return -1; self->node.left = (int) left; return 0; } static char PyNode_right__doc__[] = "integer representing the second member of this node"; static PyObject* PyNode_getright(PyNode* self, void* closure) { int right = self->node.right; #if PY_MAJOR_VERSION >= 3 return PyLong_FromLong((long)right); #else return PyInt_FromLong((long)right); #endif } static int PyNode_setright(PyNode* self, PyObject* value, void* closure) { long right = PyLong_AsLong(value); if (PyErr_Occurred()) return -1; self->node.right = (int) right; return 0; } static PyObject* PyNode_getdistance(PyNode* self, void* closure) { return PyFloat_FromDouble(self->node.distance); } static int PyNode_setdistance(PyNode* self, PyObject* value, void* closure) { const double distance = PyFloat_AsDouble(value); if (PyErr_Occurred()) return -1; self->node.distance = distance; return 0; } static char PyNode_distance__doc__[] = "the distance between the two members of this node\n"; static PyGetSetDef PyNode_getset[] = { {"left", (getter)PyNode_getleft, (setter)PyNode_setleft, PyNode_left__doc__, NULL}, {"right", (getter)PyNode_getright, (setter)PyNode_setright, PyNode_right__doc__, NULL}, {"distance", (getter)PyNode_getdistance, (setter)PyNode_setdistance, PyNode_distance__doc__, NULL}, {NULL} /* Sentinel */ }; static char PyNode_doc[] = "A Node object describes a single node in a hierarchical clustering tree.\n" "The integer attributes 'left' and 'right' represent the two members that\n" "make up this node; the floating point attribute 'distance' contains the\n" "distance between the two members of this node.\n"; static PyTypeObject PyNodeType = { PyVarObject_HEAD_INIT(NULL, 0) "cluster.Node", /* tp_name */ sizeof(PyNode), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)PyNode_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ PyNode_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ PyNode_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyNode_init, /* tp_init */ }; typedef struct { PyObject_HEAD Node* nodes; int n; } PyTree; static void PyTree_dealloc(PyTree* self) { if (self->n) free(self->nodes); Py_TYPE(self)->tp_free((PyObject*)self); } static int PyTree_init(PyTree* self, PyObject* args, PyObject* kwds) { int i; int n; Node* nodes; PyObject* arg; int* flag; if (!PyArg_ParseTuple(args, "O", &arg)) return -1; if (!PyList_Check(arg)) { PyErr_SetString(PyExc_TypeError, "Argument should be a list of Node objects"); return -1; } n = PyList_GET_SIZE(arg); if (n < 1) { PyErr_SetString(PyExc_ValueError, "List is empty"); return -1; } nodes = malloc(n*sizeof(Node)); for (i = 0; i < n; i++) { PyNode* p; PyObject* row = PyList_GET_ITEM(arg, i); if (row->ob_type != &PyNodeType) { free(nodes); PyErr_Format(PyExc_TypeError, "Row %d in list is not a Node object", i); return -1; } p = (PyNode*)row; nodes[i] = p->node; } /* --- Check if this is a bona fide tree ------------------------------- */ flag = malloc((2*n+1)*sizeof(int)); if(flag) /* Otherwise, we're in enough trouble already */ { int j; for (i = 0; i < 2*n+1; i++) flag[i] = 0; for (i = 0; i < n; i++) { j = nodes[i].left; if (j < 0) { j = -j-1; if (j>=i) break; } else j+=n; if (flag[j]) break; flag[j] = 1; j = nodes[i].right; if (j < 0) { j = -j-1; if (j>=i) break; } else j+=n; if (flag[j]) break; flag[j] = 1; } free(flag); } if (!flag || i < n) /* break encountered */ { free(nodes); PyErr_SetString(PyExc_ValueError, "Inconsistent tree"); return -1; } /* --------------------------------------------------------------------- */ self->n = n; self->nodes = nodes; return 0; } static PyObject* PyTree_str(PyTree* self) { int i; const int n = self->n; char string[128]; Node node; PyObject* line; PyObject* output; #if PY_MAJOR_VERSION >= 3 PyObject* temp; output = PyUnicode_FromString(""); #else output = PyString_FromString(""); #endif for (i = 0; i < n; i++) { node = self->nodes[i]; sprintf(string, "(%d, %d): %g", node.left, node.right, node.distance); if (i < n-1) strcat(string, "\n"); #if PY_MAJOR_VERSION >= 3 line = PyUnicode_FromString(string); #else line = PyString_FromString(string); #endif if(!line) { Py_DECREF(output); return NULL; } #if PY_MAJOR_VERSION >= 3 temp = PyUnicode_Concat(output, line); if (!temp) { Py_DECREF(output); Py_DECREF(line); return NULL; } output = temp; #else PyString_ConcatAndDel(&output, line); if(!output) { Py_DECREF(line); return NULL; } #endif } return output; } static int PyTree_length(PyTree *self) { return self->n; } static PyObject* PyTree_item(PyTree* self, int i) { PyNode* result; if (i < 0 || i >= self->n) { PyErr_SetString(PyExc_IndexError, "tree index out of range"); return NULL; } result = (PyNode*) PyNodeType.tp_alloc(&PyNodeType, 0); if(!result) { PyErr_SetString(PyExc_MemoryError, "could not create node for return value"); return NULL; } result->node = self->nodes[i]; return (PyObject*) result; } static PyObject* PyTree_slice(PyTree* self, int i, int j) { int row; const int n = self->n; PyObject* item; PyObject* result; if (i < 0) i = 0; if (j < 0) j = 0; /* Avoid signed/unsigned bug in next line */ if (j > n) j = n; if (j < i) j = i; result = PyList_New(j-i); if(!result) { PyErr_SetString(PyExc_MemoryError, "could not create list for return value"); return NULL; } for (row = 0; i < j; i++, row++) { item = PyTree_item(self, i); if(!item) { Py_DECREF(result); PyErr_SetString(PyExc_MemoryError, "could not create node for return value"); return NULL; } PyList_SET_ITEM(result, row, item); } return result; } #if (PY_MAJOR_VERSION <= 2) & (PY_MINOR_VERSION <= 4) #define lenfunc inquiry #define ssizeargfunc intargfunc #define ssizessizeargfunc intintargfunc #endif static PySequenceMethods PyTree_sequence = { (lenfunc)PyTree_length, /*sq_length*/ NULL, /*sq_concat*/ NULL, /*sq_repeat*/ (ssizeargfunc)PyTree_item, /*sq_item*/ (ssizessizeargfunc)PyTree_slice, /*sq_slice*/ NULL, /*sq_ass_item*/ NULL, /*sq_ass_slice*/ NULL /*sq_contains*/ }; static char PyTree_scale__doc__[] = "mytree.scale()\n" "This method scales the node distances in the tree such that they are\n" "all between one and zero.\n"; static PyObject* PyTree_scale(PyTree* self) { int i; const int n = self->n; Node* nodes = self->nodes; double maximum = DBL_MIN; /* --------------------------------------------------------------------- */ for (i = 0; i < n; i++) { double distance = nodes[i].distance; if (distance > maximum) maximum = distance; } if (maximum!=0.0) for (i = 0; i < n; i++) nodes[i].distance /= maximum; /* --------------------------------------------------------------------- */ Py_INCREF(Py_None); return Py_None; } static char PyTree_cut__doc__[] = "clusterid = mytree.cut(nclusters=2)\n" "Given a hierarchical clustering result mytree, cut() divides the\n" "elements in the tree into clusters. The number of clusters is given\n" "by nclusters.\n"; static PyObject* PyTree_cut(PyTree* self, PyObject* args) { int nclusters = 2; npy_intp n = (npy_intp) (self->n + 1); PyArrayObject* aCLUSTERID = (PyArrayObject*) NULL; int* clusterid = NULL; /* -- Check to make sure the tree isn't too large ---------------------- */ if (n != (int)n) { PyErr_SetString(PyExc_RuntimeError, "cut: tree is too large"); return NULL; } /* -- Read the input variables ----------------------------------------- */ if(!PyArg_ParseTuple(args, "|i", &nclusters)) return NULL; /* -- Check the nclusters variable ------------------------------------- */ if (nclusters < 1) { PyErr_SetString(PyExc_ValueError, "cut: Requested number of clusters should be positive"); return NULL; } if (nclusters > n) { PyErr_SetString(PyExc_ValueError, "cut: More clusters requested than items available"); return NULL; } /* -- Create the clusterid output variable ----------------------------- */ aCLUSTERID = (PyArrayObject*) PyArray_SimpleNew(1, &n, NPY_INT); if (!aCLUSTERID) { PyErr_SetString(PyExc_MemoryError, "cut: Could not create array for return value"); return NULL; } clusterid = PyArray_DATA(aCLUSTERID); /* --------------------------------------------------------------------- */ cuttree((int) n, self->nodes, nclusters, clusterid); /* -- Check for errors flagged by the C routine ------------------------ */ if (clusterid[0]==-1) { PyErr_SetString(PyExc_MemoryError, "cut: Error in the cuttree routine"); Py_DECREF((PyObject*) aCLUSTERID); return NULL; } /* --------------------------------------------------------------------- */ return PyArray_Return(aCLUSTERID); } static PyMethodDef PyTree_methods[] = { {"scale", (PyCFunction)PyTree_scale, METH_NOARGS, PyTree_scale__doc__}, {"cut", (PyCFunction)PyTree_cut, METH_VARARGS, PyTree_cut__doc__}, {NULL} /* Sentinel */ }; static char PyTree_doc[] = "Tree objects store a hierarchical clustering solution.\n" "Individual nodes in the tree can be accessed with tree[i], where i is\n" "an integer. Whereas the tree itself is a read-only object, tree[:]\n" "returns a list of all the nodes, which can then be modified. To create\n" "a new Tree from this list, use Tree(list).\n" "See the description of the Node class for more information."; static PyTypeObject PyTreeType = { PyVarObject_HEAD_INIT(NULL, 0) "cluster.Tree", /*tp_name*/ sizeof(PyTree), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PyTree_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ &PyTree_sequence, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ (reprfunc)PyTree_str, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ PyTree_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyTree_methods, /* tp_methods */ NULL, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyTree_init, /* tp_init */ }; /* ========================================================================== */ /* -- Methods --------------------------------------------------------------- */ /* ========================================================================== */ /* version */ static char version__doc__[] = "version()\n" "\n" "This function returns the version number of the C Clustering Library\n" "as a string.\n"; static PyObject* py_version(PyObject* self) { #if PY_MAJOR_VERSION >= 3 return PyUnicode_FromString( CLUSTERVERSION ); #else return PyString_FromString( CLUSTERVERSION ); #endif } /* kcluster */ static char kcluster__doc__[] = "kcluster(data, nclusters=2, mask=None, weight=None,\n" " transpose=0, npass=1, method='a', dist='e',\n" " initialid=None) -> clusterid, error, nfound\n" "\n" "This function implements k-means clustering.\n" "data : nrows x ncolumns array containing the expression data\n" "nclusters: number of clusters (the 'k' in k-means)\n" "mask : nrows x ncolumns array of integers, showing which data are\n" " missing. If mask[i][j]==0, then data[i][j] is missing.\n" "weight : the weights to be used when calculating distances\n" "transpose: if equal to 0, genes (rows) are clustered;\n" " if equal to 1, microarrays (columns) are clustered.\n" "npass : number of times the k-means clustering algorithm is\n" " performed, each time with a different (random) initial\n" " condition.\n" "method : specifies how the center of a cluster is found:\n" " method=='a': arithmetic mean\n" " method=='m': median\n" "dist : specifies the distance function to be used:\n" " dist=='e': Euclidean distance\n" " dist=='b': City Block distance\n" " dist=='c': Pearson correlation\n" " dist=='a': absolute value of the correlation\n" " dist=='u': uncentered correlation\n" " dist=='x': absolute uncentered correlation\n" " dist=='s': Spearman's rank correlation\n" " dist=='k': Kendall's tau\n" "initialid: the initial clustering from which the algorithm should start.\n" " If initialid is None, the routine carries out npass\n" " repetitions of the EM algorithm, each time starting from a\n" " different random initial clustering. If initialid is given,\n" " the routine carries out the EM algorithm only once, starting\n" " from the given initial clustering and without randomizing the\n" " order in which items are assigned to clusters (i.e., using\n" " the same order as in the data matrix). In that case, the\n" " k-means algorithm is fully deterministic.\n" "\n" "Return values:\n" "clusterid: array containing the number of the cluster to which each\n" " gene/microarray was assigned in the best k-means clustering\n" " solution that was found in the npass runs;\n" "error: the within-cluster sum of distances for the returned k-means\n" " clustering solution;\n" "nfound: the number of times this solution was found.\n"; static PyObject* py_kcluster(PyObject* self, PyObject* args, PyObject* keywords) { int NCLUSTERS = 2; int nrows, ncolumns; int nitems; int ndata; PyObject* DATA = NULL; PyArrayObject* aDATA = NULL; double** data = NULL; PyObject* MASK = NULL; PyArrayObject* aMASK = NULL; int** mask = NULL; PyObject* WEIGHT = NULL; PyArrayObject* aWEIGHT = NULL; double* weight = NULL; int TRANSPOSE = 0; int NPASS = 1; char METHOD = 'a'; char DIST = 'e'; PyObject* INITIALID = NULL; PyArrayObject* aCLUSTERID = NULL; double ERROR; int IFOUND; /* -- Read the input variables ----------------------------------------- */ static char* kwlist[] = { "data", "nclusters", "mask", "weight", "transpose", "npass", "method", "dist", "initialid", NULL }; if(!PyArg_ParseTupleAndKeywords(args, keywords, "O|iOOiiO&O&O", kwlist, &DATA, &NCLUSTERS, &MASK, &WEIGHT, &TRANSPOSE, &NPASS, method_kcluster_converter, &METHOD, distance_converter, &DIST, &INITIALID)) return NULL; /* -- Reset None variables to NULL ------------------------------------- */ if(MASK==Py_None) MASK = NULL; if(WEIGHT==Py_None) WEIGHT = NULL; if(INITIALID==Py_None) INITIALID = NULL; /* -- Check the transpose variable ------------------------------------- */ if (TRANSPOSE) TRANSPOSE = 1; /* -- Check the npass variable ----------------------------------------- */ if (INITIALID) NPASS = 0; else if (NPASS <= 0) { PyErr_SetString(PyExc_ValueError, "npass should be a positive integer"); return NULL; } /* -- Check the data input array --------------------------------------- */ data = parse_data(DATA, &aDATA); if (!data) return NULL; nrows = (int) PyArray_DIM(aDATA, 0); ncolumns = (int) PyArray_DIM(aDATA, 1); if (nrows!=PyArray_DIM(aDATA, 0) || ncolumns!=PyArray_DIM(aDATA, 1)) { PyErr_Format(PyExc_ValueError, "received too many data (%" NPY_INTP_FMT " x %" NPY_INTP_FMT "data matrix received)", PyArray_DIM(aDATA, 0), PyArray_DIM(aDATA, 1)); free_data(aDATA, data); return NULL; } /* -- Check the mask input --------------------------------------------- */ mask = parse_mask(MASK, &aMASK, PyArray_DIMS(aDATA)); if (!mask) { free_data(aDATA, data); return NULL; } /* -- Create the clusterid output variable ----------------------------- */ ndata = TRANSPOSE ? nrows : ncolumns; nitems = TRANSPOSE ? ncolumns : nrows; aCLUSTERID = parse_initialid(INITIALID, &NCLUSTERS, (npy_intp) nitems); if (!aCLUSTERID) { free_data(aDATA, data); free_mask(aMASK, mask, nrows); return NULL; } /* -- Check the number of clusters ------------------------------------- */ if (NCLUSTERS < 1) { PyErr_SetString(PyExc_ValueError, "nclusters should be positive"); free_data(aDATA, data); free_mask(aMASK, mask, nrows); Py_DECREF((PyObject*) aCLUSTERID); return NULL; } if (nitems < NCLUSTERS) { PyErr_SetString(PyExc_ValueError, "More clusters than items to be clustered"); free_data(aDATA, data); free_mask(aMASK, mask, nrows); Py_DECREF((PyObject*) aCLUSTERID); return NULL; } /* -- Check the weight input ------------------------------------------- */ weight = parse_weight(WEIGHT, &aWEIGHT, ndata); if (!weight) { free_data(aDATA, data); free_mask(aMASK, mask, nrows); Py_DECREF((PyObject*) aCLUSTERID); return NULL; } /* --------------------------------------------------------------------- */ kcluster(NCLUSTERS, nrows, ncolumns, data, mask, weight, TRANSPOSE, NPASS, METHOD, DIST, PyArray_DATA(aCLUSTERID), &ERROR, &IFOUND); /* --------------------------------------------------------------------- */ free_data(aDATA, data); free_mask(aMASK, mask, nrows); free_weight(aWEIGHT, weight); /* --------------------------------------------------------------------- */ return Py_BuildValue("Ndi", aCLUSTERID, ERROR, IFOUND); } /* end of wrapper for kcluster */ /* kmedoids */ static char kmedoids__doc__[] = "kmedoids(distance, nclusters=2, npass=1,\n" " initialid=None) -> clusterid, error, nfound.\n" "\n" "This function implements k-medoids clustering.\n" "distance: The distance matrix between the elements. There are three\n" " ways in which you can pass a distance matrix:\n" " #1: a 2D Numerical Python array (in which only the left-lower\n" " part of the array will be accessed);\n" " #2: a 1D Numerical Python array containing the distances\n" " consecutively;\n" " #3: a list of rows containing the lower-triangular part of\n" " the distance matrix.\n" " Examples are:\n" " >>> distance = array([[0.0, 1.1, 2.3],\n" " [1.1, 0.0, 4.5],\n" " [2.3, 4.5, 0.0]])\n" " (option #1)\n" " >>> distance = array([1.1, 2.3, 4.5])\n" " (option #2)\n" " >>> distance = [array([]),\n" " array([1.1]),\n" " array([2.3, 4.5])\n" " ]\n" " (option #3)\n" " These three correspond to the same distance matrix.\n" "nclusters: number of clusters (the 'k' in k-medoids)\n" "npass : the number of times the k-medoids clustering algorithm is\n" " performed, each time with a different (random) initial\n" " condition.\n" "initialid: the initial clustering from which the algorithm should start.\n" " If initialid is not given, the routine carries out npass\n" " repetitions of the EM algorithm, each time starting from a\n" " different random initial clustering. If initialid is given,\n" " the routine carries out the EM algorithm only once, starting\n" " from the initial clustering specified by initialid and\n" " without randomizing the order in which items are assigned to\n" " clusters (i.e., using the same order as in the data matrix).\n" " In that case, the k-means algorithm is fully deterministic.\n" "\n" "Return values:\n" "clusterid: array containing the number of the cluster to which each\n" " gene/microarray was assigned in the best k-means clustering\n" " solution that was found in the npass runs;\n" "error: the within-cluster sum of distances for the returned k-means\n" " clustering solution;\n" "nfound: the number of times this solution was found.\n"; static PyObject* py_kmedoids(PyObject* self, PyObject* args, PyObject* keywords) { int NCLUSTERS = 2; int nitems; PyObject* DISTANCES = NULL; PyArrayObject* aDISTANCES = NULL; double** distances = NULL; PyObject* INITIALID = NULL; PyArrayObject* aCLUSTERID = NULL; int NPASS = 1; double ERROR; int IFOUND; /* -- Read the input variables ----------------------------------------- */ static char* kwlist[] = { "distance", "nclusters", "npass", "initialid", NULL }; if(!PyArg_ParseTupleAndKeywords(args, keywords, "O|iiO", kwlist, &DISTANCES, &NCLUSTERS, &NPASS, &INITIALID)) return NULL; /* -- Reset None variables to NULL ------------------------------------- */ if (INITIALID==Py_None) INITIALID = NULL; /* -- Check the npass variable ----------------------------------------- */ if (INITIALID) NPASS = 0; else if (NPASS < 0) { PyErr_SetString(PyExc_ValueError, "npass should be a positive integer"); return NULL; } /* -- Check the distance matrix ---------------------------------------- */ distances = parse_distance(DISTANCES, &aDISTANCES, &nitems); if (!distances) return NULL; /* -- Create the clusterid output variable ----------------------------- */ aCLUSTERID = parse_initialid(INITIALID, &NCLUSTERS, (npy_intp) nitems); if (!aCLUSTERID) { free_distances(DISTANCES, aDISTANCES, distances, nitems); return NULL; } /* -- Check the nclusters variable ------------------------------------- */ if (NCLUSTERS <= 0) { PyErr_SetString(PyExc_ValueError, "nclusters should be a positive integer"); free_distances(DISTANCES, aDISTANCES, distances, nitems); Py_DECREF((PyObject*) aCLUSTERID); return NULL; } if (nitems < NCLUSTERS) { PyErr_SetString(PyExc_ValueError, "More clusters requested than items to be clustered"); free_distances(DISTANCES, aDISTANCES, distances, nitems); Py_DECREF((PyObject*) aCLUSTERID); return NULL; } /* --------------------------------------------------------------------- */ kmedoids(NCLUSTERS, nitems, distances, NPASS, PyArray_DATA(aCLUSTERID), &ERROR, &IFOUND); /* --------------------------------------------------------------------- */ free_distances(DISTANCES, aDISTANCES, distances, nitems); /* --------------------------------------------------------------------- */ if(IFOUND==0) /* should not occur */ { Py_DECREF((PyObject*) aCLUSTERID); PyErr_SetString(PyExc_RuntimeError, "Error in kmedoids input arguments"); return NULL; } if(IFOUND==-1) { Py_DECREF((PyObject*) aCLUSTERID); PyErr_SetString(PyExc_MemoryError, "Memory allocation error in kmedoids"); return NULL; } return Py_BuildValue("Ndi",aCLUSTERID, ERROR, IFOUND); } /* end of wrapper for kmedoids */ /* treecluster */ static char treecluster__doc__[] = "treecluster(data=None, mask=None, weight=None, transpose=0, dist='e',\n" " method='m', distancematrix=None) -> Tree object\n" "\n" "This function implements the pairwise single, complete, centroid, and\n" "average linkage hierarchical clustering methods.\n" "data : nrows x ncolumns array containing the gene expression data.\n" "mask : nrows x ncolumns array of integers, showing which data are\n" " missing. If mask[i][j]==0, then data[i][j] is missing.\n" "weight : the weights to be used when calculating distances.\n" "transpose: if equal to 0, genes (rows) are clustered;\n" " if equal to 1, microarrays (columns) are clustered.\n" "dist : specifies the distance function to be used:\n" " dist=='e': Euclidean distance\n" " dist=='b': City Block distance\n" " dist=='c': Pearson correlation\n" " dist=='a': absolute value of the correlation\n" " dist=='u': uncentered correlation\n" " dist=='x': absolute uncentered correlation\n" " dist=='s': Spearman's rank correlation\n" " dist=='k': Kendall's tau\n" "method : specifies which linkage method is used:\n" " method=='s': Single pairwise linkage\n" " method=='m': Complete (maximum) pairwise linkage (default)\n" " method=='c': Centroid linkage\n" " method=='a': Average pairwise linkage\n" "distancematrix: The distance matrix between the elements. There are\n" " three ways in which you can pass a distance matrix:\n" " #1: a 2D Numerical Python array (in which only the left-lower\n" " part of the array will be accessed);\n" " #2: a 1D Numerical Python array containing the distances\n" " consecutively;\n" " #3: a list of rows containing the lower-triangular part of\n" " the distance matrix.\n" " Examples are:\n" " >>> distance = array([[0.0, 1.1, 2.3],\n" " [1.1, 0.0, 4.5],\n" " [2.3, 4.5, 0.0]])\n" " (option #1)\n" " >>> distance = array([1.1, 2.3, 4.5])\n" " (option #2)\n" " >>> distance = [array([]),\n" " array([1.1]),\n" " array([2.3, 4.5])\n" " ]\n" " (option #3)\n" " These three correspond to the same distance matrix.\n" " PLEASE NOTE:\n" " As the treecluster routine may shuffle the values in the\n" " distance matrix as part of the clustering algorithm, be sure\n" " to save this array in a different variable before calling\n" " treecluster if you need it later.\n" "\n" "Either data or distancematrix should be None. If distancematrix==None,\n" "the hierarchical clustering solution is calculated from the gene\n" "expression data stored in the argument data. If data==None, the\n" "hierarchical clustering solution is calculated from the distance matrix\n" "instead. Pairwise centroid-linkage clustering can be calculated only\n" "from the gene expression data and not from the distance matrix. Pairwise\n" "single-, maximum-, and average-linkage clustering can be calculated from\n" "either the gene expression data or from the distance matrix.\n" "\n" "Return value:\n" "treecluster returns a Tree object describing the hierarchical clustering\n" "result. See the description of the Tree class for more information.\n"; static PyObject* py_treecluster(PyObject* self, PyObject* args, PyObject* keywords) { PyObject *DATA = NULL; PyObject *MASK = NULL; PyObject *WEIGHT = NULL; int TRANSPOSE = 0; char DIST = 'e'; char METHOD = 'm'; PyObject *DISTANCEMATRIX = NULL; PyTree* tree; Node* nodes; int nitems; /* -- Read the input variables ----------------------------------------- */ static char* kwlist[] = { "data", "mask", "weight", "transpose", "method", "dist", "distancematrix", NULL }; if(!PyArg_ParseTupleAndKeywords(args, keywords, "|OOOiO&O&O", kwlist, &DATA, &MASK, &WEIGHT, &TRANSPOSE, method_treecluster_converter, &METHOD, distance_converter, &DIST, &DISTANCEMATRIX)) return NULL; /* -- Reset None variables to NULL ------------------------------------- */ if(DATA==Py_None) DATA = NULL; if(MASK==Py_None) MASK = NULL; if(WEIGHT==Py_None) WEIGHT = NULL; if(DISTANCEMATRIX==Py_None) DISTANCEMATRIX = NULL; /* -- Check if we are using the data matrix or the distance matrix ----- */ if (DATA!=NULL && DISTANCEMATRIX!=NULL) { PyErr_SetString(PyExc_ValueError, "Use either data or distancematrix, do not use both"); return NULL; } if (DATA==NULL && DISTANCEMATRIX==NULL) { PyErr_SetString(PyExc_ValueError, "Neither data nor distancematrix was given"); return NULL; } if (DISTANCEMATRIX==NULL) /* DATA contains gene expression data */ { int nrows; int ncolumns; int ndata; PyArrayObject* aDATA = NULL; PyArrayObject* aMASK = NULL; PyArrayObject* aWEIGHT = NULL; double** data = NULL; int** mask = NULL; double* weight = NULL; /* -- Check the data input array --------------------------------------- */ data = parse_data(DATA, &aDATA); if (!data) return NULL; nrows = (int) PyArray_DIM(aDATA, 0); ncolumns = (int) PyArray_DIM(aDATA, 1); ndata = TRANSPOSE ? nrows : ncolumns; nitems = TRANSPOSE ? ncolumns : nrows; if (nrows!=PyArray_DIM(aDATA, 0) || ncolumns!=PyArray_DIM(aDATA, 1)) { free_data(aDATA, data); PyErr_SetString(PyExc_ValueError, "data array is too large"); return NULL; } /* -- Check the mask input --------------------------------------------- */ mask = parse_mask(MASK, &aMASK, PyArray_DIMS(aDATA)); if (!mask) { free_data(aDATA, data); return NULL; } /* -- Check the weight input ------------------------------------------- */ weight = parse_weight(WEIGHT, &aWEIGHT, ndata); if (!weight) { free_data(aDATA, data); free_mask(aMASK, mask, nrows); return NULL; } /* -- Call treecluster to perform hierarchical clustering -------------- */ nodes = treecluster(nrows, ncolumns, data, mask, weight, TRANSPOSE, DIST, METHOD, NULL); /* --------------------------------------------------------------------- */ free_data(aDATA, data); free_mask(aMASK, mask, nrows); free_weight(aWEIGHT, weight); } else { double** distances = NULL; PyArrayObject* aDISTANCEMATRIX = NULL; if (!strchr("sma", METHOD)) { PyErr_SetString(PyExc_ValueError, "argument method should be 's', 'm', or 'a' when specifying the distance matrix"); return NULL; } /* -- Check the distance matrix ---------------------------------------- */ distances = parse_distance(DISTANCEMATRIX, &aDISTANCEMATRIX, &nitems); if (!distances) return NULL; /* --------------------------------------------------------------------- */ nodes = treecluster(nitems, nitems, 0, 0, 0, TRANSPOSE, DIST, METHOD, distances); /* --------------------------------------------------------------------- */ free_distances(DISTANCEMATRIX, aDISTANCEMATRIX, distances, nitems); } /* -- Check if a memory allocation error occurred ---------------------- */ if(!nodes) { PyErr_SetString(PyExc_MemoryError, "error occurred in treecluster"); return NULL; } tree = (PyTree*) PyTreeType.tp_alloc(&PyTreeType, 0); if(!tree) { PyErr_SetString(PyExc_MemoryError, "error occurred in treecluster"); free(nodes); return NULL; } tree->nodes = nodes; tree->n = nitems-1; return (PyObject*) tree; } /* end of wrapper for treecluster */ /* somcluster */ static char somcluster__doc__[] = "somcluster(data, mask=None, weight=None, transpose=0,\n" " nxgrid=2, nygrid=1, inittau=0.02, niter=1,\n" " dist='e') -> clusterid, celldata\n" "\n" "This function implements a self-organizing map on a rectangular grid.\n" "data : nrows x ncolumns array containing the gene expression data\n" "mask : nrows x ncolumns array of integers, showing which data are\n" " missing. If mask[i][j]==0, then data[i][j] is missing.\n" "weight : the weights to be used when calculating distances\n" "transpose: if equal to 0, genes (rows) are clustered;\n" " if equal to 1, microarrays (columns) are clustered.\n" "nxgrid : the horizontal dimension of the rectangular SOM map\n" "nygrid : the vertical dimension of the rectangular SOM map\n" "inittau : the initial value of tau (the neighborbood function)\n" "niter : the number of iterations\n" "dist : specifies the distance function to be used:\n" " dist=='e': Euclidean distance\n" " dist=='b': City Block distance\n" " dist=='c': Pearson correlation\n" " dist=='a': absolute value of the correlation\n" " dist=='u': uncentered correlation\n" " dist=='x': absolute uncentered correlation\n" " dist=='s': Spearman's rank correlation\n" " dist=='k': Kendall's tau\n" "\n" "Return values:\n" "clusterid: array with two columns, while the number of rows is equal to\n" " the number of genes or the number of microarrays depending on\n" " whether genes or microarrays are being clustered. Each row in\n" " the array contains the x and y coordinates of the cell in the\n" " rectangular SOM grid to which the gene or microarray was\n" " assigned.\n" "celldata: an array with dimensions (nxgrid, nygrid, number of\n" " microarrays) if genes are being clustered, or (nxgrid,\n" " nygrid, number of genes) if microarrays are being clustered.\n" " Each element [ix][iy] of this array is a 1D vector containing\n" " the gene expression data for the centroid of the cluster in\n" " the SOM grid cell with coordinates (ix, iy).\n"; static PyObject* py_somcluster(PyObject* self, PyObject* args, PyObject* keywords) { int nrows; int ncolumns; int nitems; int ndata; PyObject* DATA = NULL; PyArrayObject* aDATA = NULL; double** data = NULL; PyObject* MASK = NULL; PyArrayObject* aMASK = NULL; int** mask = NULL; PyObject* WEIGHT = NULL; PyArrayObject* aWEIGHT = NULL; double* weight = NULL; int TRANSPOSE = 0; int NXGRID = 2; int NYGRID = 1; double INITTAU = 0.02; int NITER = 1; char DIST = 'e'; PyArrayObject* aCELLDATA = NULL; double*** celldata = NULL; PyArrayObject* aCLUSTERID = NULL; npy_intp shape[2]; /* -- Read the input variables ----------------------------------------- */ static char* kwlist[] = { "data", "mask", "weight", "transpose", "nxgrid", "nygrid", "inittau", "niter", "dist", NULL }; if(!PyArg_ParseTupleAndKeywords(args, keywords, "O|OOiiidiO&", kwlist, &DATA, &MASK, &WEIGHT, &TRANSPOSE, &NXGRID, &NYGRID, &INITTAU, &NITER, distance_converter, &DIST)) return NULL; /* -- Reset None variables to NULL ------------------------------------- */ if(WEIGHT==Py_None) WEIGHT = NULL; if(MASK==Py_None) MASK = NULL; /* -- Check the nxgrid variable ---------------------------------------- */ if (NXGRID < 1) { PyErr_SetString(PyExc_ValueError, "nxgrid should be a positive integer (default is 2)"); return NULL; } /* -- Check the nygrid variable ---------------------------------------- */ if (NYGRID < 1) { PyErr_SetString(PyExc_ValueError, "nygrid should be a positive integer (default is 1)"); return NULL; } /* -- Check the niter variable ----------------------------------------- */ if (NITER < 1) { PyErr_SetString(PyExc_ValueError, "number of iterations (niter) should be positive"); return NULL; } /* -- Check the transpose variable ------------------------------------- */ if (TRANSPOSE) TRANSPOSE = 1; /* -- Check the data input array --------------------------------------- */ data = parse_data(DATA, &aDATA); if (!data) return NULL; nrows = (int) PyArray_DIM(aDATA, 0); ncolumns = (int) PyArray_DIM(aDATA, 1); nitems = TRANSPOSE ? ncolumns : nrows; ndata = TRANSPOSE ? nrows : ncolumns; if (nrows!=PyArray_DIM(aDATA, 0) || ncolumns!=PyArray_DIM(aDATA, 1)) { PyErr_SetString(PyExc_RuntimeError, "data array too large"); free_data(aDATA, data); return NULL; } /* -- Check the mask input --------------------------------------------- */ mask = parse_mask(MASK, &aMASK, PyArray_DIMS(aDATA)); if (!mask) { free_data(aDATA, data); return NULL; } /* -- Check the weight input ------------------------------------------- */ weight = parse_weight(WEIGHT, &aWEIGHT, ndata); if (!weight) { free_data(aDATA, data); free_mask(aMASK, mask, nrows); return NULL; } /* --------------------------------------------------------------------- */ shape[0] = nitems; shape[1] = 2; aCLUSTERID = (PyArrayObject*) PyArray_SimpleNew(2, shape, NPY_INT); if (!aCLUSTERID) { PyErr_SetString(PyExc_MemoryError, "somcluster: Could not create clusterid array"); free_data(aDATA, data); free_mask(aMASK, mask, nrows); free_weight(aWEIGHT, weight); return NULL; } /* --------------------------------------------------------------------- */ celldata = create_celldata(NXGRID, NYGRID, ndata, &aCELLDATA); if (!celldata) { free_data(aDATA, data); free_mask(aMASK, mask, nrows); free_weight(aWEIGHT, weight); Py_DECREF((PyObject*) aCLUSTERID); } /* --------------------------------------------------------------------- */ somcluster(nrows, ncolumns, data, mask, weight, TRANSPOSE, NXGRID, NYGRID, INITTAU, NITER, DIST, celldata, PyArray_DATA(aCLUSTERID)); /* --------------------------------------------------------------------- */ free_data(aDATA, data); free_mask(aMASK, mask, nrows); free_weight(aWEIGHT, weight); free_celldata(celldata); /* --------------------------------------------------------------------- */ return Py_BuildValue("NN", PyArray_Return(aCLUSTERID), PyArray_Return(aCELLDATA)); } /* end of wrapper for somcluster */ /* clusterdistance */ static char clusterdistance__doc__[] = "clusterdistance(data, mask=None, weight=None, index1, index2, dist='e',\n" " method='a', transpose=0) -> the distance between the\n" " two clusters\n" "\n" "data : nrows x ncolumns array containing the expression data\n" "mask : nrows x ncolumns array of integers, showing which data are\n" " missing. If mask[i][j]==0, then data[i][j] is missing.\n" "weight : the weights to be used when calculating distances\n" "index1 : 1D array identifying which genes/microarrays belong to the\n" " first cluster. If the cluster contains only one gene, then\n" " index1 can also be written as a single integer.\n" "index2 : 1D array identifying which genes/microarrays belong to the\n" " second cluster. If the cluster contains only one gene, then\n" " index2 can also be written as a single integer.\n" "transpose: if equal to 0, genes (rows) are clustered;\n" " if equal to 1, microarrays (columns) are clustered.\n" "dist : specifies the distance function to be used:\n" " dist=='e': Euclidean distance\n" " dist=='b': City Block distance\n" " dist=='c': Pearson correlation\n" " dist=='a': absolute value of the correlation\n" " dist=='u': uncentered correlation\n" " dist=='x': absolute uncentered correlation\n" " dist=='s': Spearman's rank correlation\n" " dist=='k': Kendall's tau\n" "method : specifies how the distance between two clusters is defined:\n" " method=='a': the distance between the arithmetic means of the\n" " two clusters\n" " method=='m': the distance between the medians of the two\n" " clusters\n" " method=='s': the smallest pairwise distance between members\n" " of the two clusters\n" " method=='x': the largest pairwise distance between members of\n" " the two clusters\n" " method=='v': average of the pairwise distances between\n" " members of the clusters\n" "transpose: if equal to 0: clusters of genes (rows) are considered;\n" " if equal to 1: clusters of microarrays (columns) are\n" " considered.\n"; static PyObject* py_clusterdistance(PyObject* self, PyObject* args, PyObject* keywords) { double result; int nrows; int ncolumns; int ndata; PyObject* DATA = NULL; PyArrayObject* aDATA = NULL; double** data; PyObject* MASK = NULL; PyArrayObject* aMASK = NULL; int** mask; PyObject* WEIGHT = NULL; PyArrayObject* aWEIGHT = NULL; double* weight; char DIST = 'e'; char METHOD = 'a'; int TRANSPOSE = 0; int N1; int N2; PyObject* INDEX1 = NULL; PyArrayObject* aINDEX1 = NULL; int* index1; PyObject* INDEX2 = NULL; PyArrayObject* aINDEX2 = NULL; int* index2; /* -- Read the input variables ----------------------------------------- */ static char* kwlist[] = { "data", "mask", "weight", "index1", "index2", "method", "dist", "transpose", NULL }; if(!PyArg_ParseTupleAndKeywords(args, keywords, "O|OOOOO&O&i", kwlist, &DATA, &MASK, &WEIGHT, &INDEX1, &INDEX2, method_clusterdistance_converter, &METHOD, distance_converter, &DIST, &TRANSPOSE)) return NULL; /* -- Reset None variables to NULL ------------------------------------- */ if (MASK==Py_None) MASK = NULL; if (WEIGHT==Py_None) WEIGHT = NULL; if (INDEX1==Py_None) INDEX1 = NULL; if (INDEX2==Py_None) INDEX2 = NULL; /* -- Check the transpose variable ------------------------------------- */ if (TRANSPOSE) TRANSPOSE = 1; /* -- Check the data input array --------------------------------------- */ data = parse_data(DATA, &aDATA); if (!data) return NULL; nrows = (int) PyArray_DIM(aDATA, 0); ncolumns = (int) PyArray_DIM(aDATA, 1); ndata = TRANSPOSE ? nrows : ncolumns; if (nrows!=PyArray_DIM(aDATA, 0) || ncolumns!=PyArray_DIM(aDATA, 1)) { free_data(aDATA, data); PyErr_SetString(PyExc_ValueError, "data array is too large"); return NULL; } /* -- Check the mask input --------------------------------------------- */ mask = parse_mask(MASK, &aMASK, PyArray_DIMS(aDATA)); if (!mask) { free_data(aDATA, data); return NULL; } /* -- Check the weight input ------------------------------------------- */ weight = parse_weight(WEIGHT, &aWEIGHT, ndata); if (!weight) { free_data(aDATA, data); free_mask(aMASK, mask, nrows); return NULL; } /* --------------------------------------------------------------------- */ index1 = parse_index(INDEX1, &aINDEX1, &N1); if (index1==NULL) { free_data(aDATA, data); free_mask(aMASK, mask, nrows); free_weight(aWEIGHT, weight); return NULL; } index2 = parse_index(INDEX2, &aINDEX2, &N2); if (index2==NULL) { free_data(aDATA, data); free_mask(aMASK, mask, nrows); free_weight(aWEIGHT, weight); free_index(aINDEX1, index1); return NULL; } /* --------------------------------------------------------------------- */ result = clusterdistance(nrows, ncolumns, data, mask, weight, N1, N2, index1, index2, DIST, METHOD, TRANSPOSE); /* --------------------------------------------------------------------- */ free_data(aDATA, data); free_mask(aMASK, mask, nrows); free_weight(aWEIGHT, weight); free_index(aINDEX1, index1); free_index(aINDEX2, index2); /* --------------------------------------------------------------------- */ if (result < -0.5) /* Actually -1.0; avoiding roundoff errors */ { PyErr_SetString(PyExc_IndexError, "index out of range"); return NULL; } return PyFloat_FromDouble(result); } /* end of wrapper for clusterdistance */ /* clustercentroids */ static char clustercentroids__doc__[] = "clustercentroids(data, mask=None, transport=0, clusterid,\n" " method='a') -> cdata, cmask\n" "\n" "The clustercentroids routine calculates the cluster centroids, given to\n" "which cluster each element belongs. The centroid is defined as either\n" "the mean or the median over all elements for each dimension.\n" "data : nrows x ncolumns array containing the expression data\n" "mask : nrows x ncolumns array of integers, showing which data are\n" " missing. If mask[i][j]==0, then data[i][j] is missing.\n" "transpose: if equal to 0, gene (row) clusters are considered;\n" " if equal to 1, microarray (column) clusters are considered.\n" "clusterid: array containing the cluster number for each gene or\n" " microarray. The cluster number should be non-negative.\n" "method : specifies whether the centroid is calculated from the\n" " arithmetic mean (method=='a', default) or the median\n" " (method=='m') over each dimension.\n" "\n" "Return values:\n" "cdata : 2D array containing the cluster centroids. If transpose==0,\n" " then the dimensions of cdata are nclusters x ncolumns. If\n" " transpose==1, then the dimensions of cdata are\n" " nrows x nclusters.\n" "cmask : 2D array of integers describing which elements in cdata,\n" " if any, are missing.\n"; static PyObject* py_clustercentroids(PyObject* self, PyObject* args, PyObject* keywords) { int nrows; int ncolumns; unsigned int nitems; int nclusters; PyObject* DATA = NULL; PyArrayObject* aDATA = NULL; double** data; PyObject* MASK = NULL; PyArrayObject* aMASK = NULL; int** mask; PyObject* CLUSTERID = NULL; PyArrayObject* aCLUSTERID = NULL; int* clusterid; char METHOD = 'a'; npy_intp shape[2]; PyArrayObject* aCDATA = NULL; double** cdata; PyArrayObject* aCMASK = NULL; int** cmask; int TRANSPOSE = 0; int i; int ok; /* -- Read the input variables ----------------------------------------- */ static char* kwlist[] = { "data", "mask", "clusterid", "method", "transpose", NULL }; if(!PyArg_ParseTupleAndKeywords(args, keywords, "O|OOci", kwlist, &DATA, &MASK, &CLUSTERID, &METHOD, &TRANSPOSE)) return NULL; /* -- Reset None variables to NULL ------------------------------------- */ if (MASK==Py_None) MASK = NULL; if (CLUSTERID==Py_None) CLUSTERID = NULL; /* -- Check the data input array --------------------------------------- */ data = parse_data(DATA, &aDATA); if (!data) return NULL; nrows = (int) PyArray_DIM(aDATA, 0); ncolumns = (int) PyArray_DIM(aDATA, 1); nitems = TRANSPOSE ? ncolumns : nrows; if (nrows!=PyArray_DIM(aDATA, 0) || ncolumns!=PyArray_DIM(aDATA, 1)) { PyErr_SetString(PyExc_RuntimeError, "data array is too large"); free_data(aDATA, data); return NULL; } /* -- Check the mask input --------------------------------------------- */ mask = parse_mask(MASK, &aMASK, PyArray_DIMS(aDATA)); if (!mask) { free_data(aDATA, data); return NULL; } /* -- Check the cluster assignments ------------------------------------ */ clusterid = parse_clusterid(CLUSTERID, &aCLUSTERID, nitems, &nclusters); if (!clusterid) { free_data(aDATA, data); free_mask(aMASK, mask, nrows); return NULL; } /* -- Create the centroid data output variable ------------------------- */ shape[0] = TRANSPOSE ? nrows : nclusters; shape[1] = TRANSPOSE ? nclusters : ncolumns; aCDATA = (PyArrayObject*) PyArray_SimpleNew(2, shape, NPY_DOUBLE); if (!aCDATA) { PyErr_SetString(PyExc_MemoryError, "could not create centroids array"); free_data(aDATA, data); free_mask(aMASK, mask, nrows); free_clusterid(aCLUSTERID, clusterid); return NULL; } cdata = malloc(shape[0]*sizeof(double*)); for (i=0; i distance matrix as a list of arrays\n" "\n" "This function returns the distance matrix between gene expression data.\n" "data : nrows x ncolumns array containing the expression data\n" "mask : nrows x ncolumns array of integers, showing which data are\n" " missing. If mask[i][j]==0, then data[i][j] is missing.\n" "weight : the weights to be used when calculating distances.\n" "transpose: if equal to 0: the distances between genes (rows) are\n" " calculated;\n" " if equal to 1, the distances beteeen microarrays (columns)\n" " are calculated.\n" "dist : specifies the distance function to be used:\n" " dist=='e': Euclidean distance\n" " dist=='b': City Block distance\n" " dist=='c': Pearson correlation\n" " dist=='a': absolute value of the correlation\n" " dist=='u': uncentered correlation\n" " dist=='x': absolute uncentered correlation\n" " dist=='s': Spearman's rank correlation\n" " dist=='k': Kendall's tau\n" "\n" "Return value:\n" "The distance matrix is returned as a list of 1D arrays containing the\n" "distance matrix between the gene expression data. The number of columns\n" "in each row is equal to the row number. Hence, the first row has zero\n" "elements. An example of the return value is\n" "matrix = [[],\n" " array([1.]),\n" " array([7., 3.]),\n" " array([4., 2., 6.])]\n" "This corresponds to the distance matrix\n" " [0., 1., 7., 4.]\n" " [1., 0., 3., 2.]\n" " [7., 3., 0., 6.]\n" " [4., 2., 6., 0.]\n"; static PyObject* py_distancematrix(PyObject* self, PyObject* args, PyObject* keywords) { PyObject* result = NULL; PyObject* DATA = NULL; PyArrayObject* aDATA = NULL; double** data = NULL; PyObject* MASK = NULL; PyArrayObject* aMASK = NULL; int** mask = (int**) NULL; PyObject* WEIGHT = NULL; PyArrayObject* aWEIGHT = NULL; double* weight = NULL; int TRANSPOSE = 0; char DIST = 'e'; double** distances = NULL; int nrows, ncolumns, nelements, ndata; /* -- Read the input variables ----------------------------------------- */ static char* kwlist[] = { "data", "mask", "weight", "transpose", "dist", NULL }; if(!PyArg_ParseTupleAndKeywords(args, keywords, "O|OOiO&", kwlist, &DATA, &MASK, &WEIGHT, &TRANSPOSE, distance_converter, &DIST)) return NULL; /* -- Reset None variables to NULL ------------------------------------- */ if (MASK==Py_None) MASK = NULL; if (WEIGHT==Py_None) WEIGHT = NULL; /* -- Check the transpose variable ------------------------------------- */ if (TRANSPOSE) TRANSPOSE = 1; /* -- Check the data input array --------------------------------------- */ data = parse_data(DATA, &aDATA); if (!data) return NULL; nrows = (int) PyArray_DIM(aDATA, 0); ncolumns = (int) PyArray_DIM(aDATA, 1); if (nrows!=PyArray_DIM(aDATA, 0) || ncolumns!=PyArray_DIM(aDATA, 1)) { PyErr_SetString(PyExc_RuntimeError, "data array is too large"); return NULL; } ndata = (TRANSPOSE==0) ? ncolumns : nrows; nelements = (TRANSPOSE==0) ? nrows : ncolumns; /* -- Check the mask input --------------------------------------------- */ mask = parse_mask(MASK, &aMASK, PyArray_DIMS(aDATA)); if (!mask) { free_data(aDATA, data); return NULL; } /* -- Check the weight input ------------------------------------------- */ weight = parse_weight(WEIGHT, &aWEIGHT, ndata); if (!weight) { free_data(aDATA, data); free_mask(aMASK, mask, nrows); return NULL; } /* -- Create the matrix output variable -------------------------------- */ result = PyList_New(nelements); if (result) { npy_intp i, j; /* ------------------------------------------------------------------- */ distances = distancematrix(nrows, ncolumns, data, mask, weight, DIST, TRANSPOSE); /* ------------------------------------------------------------------- */ if (distances) { for (i = 0; i < nelements; i++) { double* rowdata = NULL; PyObject* row = PyArray_SimpleNew(1, &i, NPY_DOUBLE); if (!row) { PyErr_SetString(PyExc_MemoryError, "could not create distance matrix"); break; } rowdata = PyArray_DATA((PyArrayObject*)row); for (j = 0; j < i; j++) rowdata[j] = distances[i][j]; if (i!=0) /* distances[0]==NULL */ free(distances[i]); PyList_SET_ITEM(result, i, row); } if (i < nelements) { for (j = 0; j < i; j++) { PyObject* row = PyList_GET_ITEM(result, i); Py_DECREF(row); } if (i==0) i = 1; /* distances[0]==NULL */ for (j = i; j < nelements; j++) free(distances[j]); Py_DECREF(result); result = NULL; } free(distances); } else { Py_DECREF(result); result = NULL; } } /* --------------------------------------------------------------------- */ free_data(aDATA, data); free_mask(aMASK, mask, nrows); free_weight(aWEIGHT, weight); /* --------------------------------------------------------------------- */ if(result==NULL) PyErr_SetString(PyExc_MemoryError, "Could not create distance matrix"); return result; } /* end of wrapper for distancematrix */ /* pca */ static char pca__doc__[] = "pca(data) -> (columnmean, coordinates, pc, eigenvalues)\n" "\n" "This function returns the principal component decomposition of the gene\n" "expression data.\n" "data : nrows x ncolumns array containing the expression data\n" "\n" "Return value:\n" "This function returns an array containing the mean of each column, the\n" "principal components as an nmin x ncolumns array, as well as the\n" "coordinates (an nrows x nmin array) of the data along the principal\n" "components, and the associated eigenvalues. The principal components, the\n" "coordinates, and the eigenvalues are sorted by the magnitude of the\n" "eigenvalue, with the largest eigenvalues appearing first. Here, nmin is\n" "the smaller of nrows and ncolumns.\n" "Adding the column means to the dot product of the coordinates and the\n" "principal components,\n" ">>> columnmean + dot(coordinates, pc)\n" "recreates the data matrix.\n"; static PyObject* py_pca(PyObject* self, PyObject* args) { PyArrayObject* aMEAN = NULL; PyArrayObject* aPC = NULL; PyArrayObject* aCOORDINATES = NULL; PyArrayObject* aEIGENVALUES = NULL; double** u; double** v; double* w; PyObject* DATA = NULL; PyArrayObject* aDATA = NULL; double** data = NULL; int nrows, ncolumns; npy_intp shape[2]; npy_intp nmin; int error; double* p; double* q; int i, j; /* -- Read the input variables ----------------------------------------- */ if(!PyArg_ParseTuple(args, "O", &DATA)) return NULL; /* -- Check the data input array --------------------------------------- */ data = parse_data(DATA, &aDATA); if (!data) return NULL; nrows = (int) PyArray_DIM(aDATA, 0); ncolumns = (int) PyArray_DIM(aDATA, 1); if (nrows!=PyArray_DIM(aDATA, 0) || ncolumns!=PyArray_DIM(aDATA, 1)) { PyErr_SetString(PyExc_RuntimeError, "data array is too large"); return NULL; } nmin = nrows < ncolumns ? nrows : ncolumns; /* -- Create the output variables -------------------------------------- */ u = malloc(nrows*sizeof(double*)); v = malloc(nmin*sizeof(double*)); aEIGENVALUES = (PyArrayObject*) PyArray_SimpleNew(1, &nmin, NPY_DOUBLE); shape[0] = nmin; shape[1] = ncolumns; aPC = (PyArrayObject*) PyArray_SimpleNew(2, shape, NPY_DOUBLE); aMEAN = (PyArrayObject*) PyArray_SimpleNew(1, &shape[1], NPY_DOUBLE); shape[0] = nrows; shape[1] = nmin; aCOORDINATES = (PyArrayObject*) PyArray_SimpleNew(2, shape, NPY_DOUBLE); if (!u || !v || !aPC || !aEIGENVALUES || !aCOORDINATES || !aMEAN) { error = -2; goto exit; } if (nrows >= ncolumns) { p = PyArray_DATA(aCOORDINATES); q = PyArray_DATA(aPC); } else /* nrows < ncolums */ { p = PyArray_DATA(aPC); q = PyArray_DATA(aCOORDINATES); } for (i=0; i 0) PyErr_SetString(PyExc_RuntimeError, "Singular value decomposition failed to converge"); else PyErr_SetString(PyExc_RuntimeError, "Unknown error"); Py_XDECREF(aMEAN); Py_XDECREF(aPC); Py_XDECREF(aCOORDINATES); Py_XDECREF(aEIGENVALUES); return NULL; } /* end of wrapper for pca */ /* ========================================================================== */ /* -- The methods table ----------------------------------------------------- */ /* ========================================================================== */ static struct PyMethodDef cluster_methods[] = { {"version", (PyCFunction) py_version, METH_NOARGS, version__doc__}, {"kcluster", (PyCFunction) py_kcluster, METH_VARARGS | METH_KEYWORDS, kcluster__doc__}, {"kmedoids", (PyCFunction) py_kmedoids, METH_VARARGS | METH_KEYWORDS, kmedoids__doc__}, {"treecluster", (PyCFunction) py_treecluster, METH_VARARGS | METH_KEYWORDS, treecluster__doc__}, {"somcluster", (PyCFunction) py_somcluster, METH_VARARGS | METH_KEYWORDS, somcluster__doc__}, {"clusterdistance", (PyCFunction) py_clusterdistance, METH_VARARGS | METH_KEYWORDS, clusterdistance__doc__}, {"clustercentroids", (PyCFunction) py_clustercentroids, METH_VARARGS | METH_KEYWORDS, clustercentroids__doc__}, {"distancematrix", (PyCFunction) py_distancematrix, METH_VARARGS | METH_KEYWORDS, distancematrix__doc__}, {"pca", (PyCFunction) py_pca, METH_VARARGS | METH_KEYWORDS, pca__doc__}, {NULL, NULL, 0, NULL}/* sentinel */ }; /* ========================================================================== */ /* -- Initialization -------------------------------------------------------- */ /* ========================================================================== */ #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "cluster", "C Clustering Library", -1, cluster_methods, NULL, NULL, NULL, NULL }; PyObject * PyInit_cluster(void) #else void initcluster(void) #endif { PyObject *module; import_array(); PyNodeType.tp_new = PyType_GenericNew; PyTreeType.tp_new = PyType_GenericNew; if (PyType_Ready(&PyNodeType) < 0) #if PY_MAJOR_VERSION >= 3 return NULL; #else return; #endif if (PyType_Ready(&PyTreeType) < 0) #if PY_MAJOR_VERSION >= 3 return NULL; #else return; #endif #if PY_MAJOR_VERSION >= 3 module = PyModule_Create(&moduledef); if (module==NULL) return NULL; #else module = Py_InitModule4("cluster", cluster_methods, "C Clustering Library", NULL, PYTHON_API_VERSION); if (module==NULL) return; #endif Py_INCREF(&PyTreeType); Py_INCREF(&PyNodeType); PyModule_AddObject(module, "Tree", (PyObject*) &PyTreeType); PyModule_AddObject(module, "Node", (PyObject*) &PyNodeType); #if PY_MAJOR_VERSION >= 3 return module; #endif } cluster-1.52a/python/MANIFEST.python0000644000100500010050000000026411160364636017113 0ustar mdehoonmdehoonREADME INSTALL setup.py python/__init__.py python/clustermodule.c python/MANIFEST.python src/cluster.c src/cluster.h python/test/README python/test/test_Cluster.py doc/cluster.pdf cluster-1.52a/python/__init__.py0000644000100500010050000006104311475450307016555 0ustar mdehoonmdehoonimport numpy from Pycluster.cluster import * def _treesort(order, nodeorder, nodecounts, tree): # Find the order of the nodes consistent with the hierarchical clustering # tree, taking into account the preferred order of nodes. nNodes = len(tree) nElements = nNodes + 1 neworder = numpy.zeros(nElements) clusterids = numpy.arange(nElements) for i in range(nNodes): i1 = tree[i].left i2 = tree[i].right if i1 < 0: order1 = nodeorder[-i1-1] count1 = nodecounts[-i1-1] else: order1 = order[i1] count1 = 1 if i2 < 0: order2 = nodeorder[-i2-1] count2 = nodecounts[-i2-1] else: order2 = order[i2] count2 = 1 # If order1 and order2 are equal, their order is determined # by the order in which they were clustered if i1 < i2: if order1 < order2: increase = count1 else: increase = count2 for j in range(nElements): clusterid = clusterids[j] if clusterid == i1 and order1 >= order2: neworder[j] += increase if clusterid == i2 and order1 < order2: neworder[j] += increase if clusterid == i1 or clusterid == i2: clusterids[j] = -i-1 else: if order1 <= order2: increase = count1 else: increase = count2 for j in range(nElements): clusterid = clusterids[j] if clusterid == i1 and order1 > order2: neworder[j] += increase if clusterid == i2 and order1 <= order2: neworder[j] += increase if clusterid == i1 or clusterid == i2: clusterids[j] = -i-1 return numpy.argsort(neworder) def _savetree(jobname, tree, order, transpose): # Save the hierarchical clustering solution given by the tree, following # the specified order, in a file whose name is based on jobname. if transpose == 0: extension = ".gtr" keyword = "GENE" else: extension = ".atr" keyword = "ARRY" nnodes = len(tree) outputfile = open(jobname+extension, "w") nodeindex = 0 nodeID = [''] * nnodes nodecounts = numpy.zeros(nnodes, int) nodeorder = numpy.zeros(nnodes) nodedist = numpy.array([node.distance for node in tree]) for nodeindex in range(nnodes): min1 = tree[nodeindex].left min2 = tree[nodeindex].right nodeID[nodeindex] = "NODE%dX" % (nodeindex+1) outputfile.write(nodeID[nodeindex]) outputfile.write("\t") if min1 < 0: index1 = -min1-1 order1 = nodeorder[index1] counts1 = nodecounts[index1] outputfile.write(nodeID[index1]+"\t") nodedist[nodeindex] = max(nodedist[nodeindex],nodedist[index1]) else: order1 = order[min1] counts1 = 1 outputfile.write("%s%dX\t" % (keyword, min1)) if min2 < 0: index2 = -min2-1 order2 = nodeorder[index2] counts2 = nodecounts[index2] outputfile.write(nodeID[index2]+"\t") nodedist[nodeindex] = max(nodedist[nodeindex],nodedist[index2]) else: order2 = order[min2] counts2 = 1 outputfile.write("%s%dX\t" % (keyword, min2)) outputfile.write(str(1.0-nodedist[nodeindex])) outputfile.write("\n") counts = counts1 + counts2 nodecounts[nodeindex] = counts nodeorder[nodeindex] = (counts1*order1+counts2*order2) / counts outputfile.close() # Now set up order based on the tree structure index = _treesort(order, nodeorder, nodecounts, tree) return index class Record: """Store gene expression data. A Record stores the gene expression data and related information contained in a data file following the file format defined for Michael Eisen's Cluster/TreeView program. A Record has the following members: data: a matrix containing the gene expression data mask: a matrix containing only 1's and 0's, denoting which values are present (1) or missing (0). If all elements of mask are one (no missing data), then mask is set to None. geneid: a list containing a unique identifier for each gene (e.g., ORF name) genename: a list containing an additional description for each gene (e.g., gene name) gweight: the weight to be used for each gene when calculating the distance gorder: an array of real numbers indicating the preferred order of the genes in the output file expid: a list containing a unique identifier for each experimental condition eweight: the weight to be used for each experimental condition when calculating the distance eorder: an array of real numbers indication the preferred order in the output file of the experimental conditions uniqid: the string that was used instead of UNIQID in the input file. """ def __init__(self, handle=None): """Read gene expression data from the file handle and return a Record. The file should be in the format defined for Michael Eisen's Cluster/TreeView program. """ self.data = None self.mask = None self.geneid = None self.genename = None self.gweight = None self.gorder = None self.expid = None self.eweight = None self.eorder = None self.uniqid = None if not handle: return line = handle.readline().strip("\r\n").split("\t") n = len(line) self.uniqid = line[0] self.expid = [] cols = {0: "GENEID"} for word in line[1:]: if word == "NAME": cols[line.index(word)] = word self.genename = [] elif word == "GWEIGHT": cols[line.index(word)] = word self.gweight = [] elif word=="GORDER": cols[line.index(word)] = word self.gorder = [] else: self.expid.append(word) self.geneid = [] self.data = [] self.mask = [] needmask = 0 for line in handle: line = line.strip("\r\n").split("\t") if len(line) != n: raise ValueError("Line with %d columns found (expected %d)" % (len(line), n)) if line[0] == "EWEIGHT": i = max(cols) + 1 self.eweight = numpy.array(line[i:], float) continue if line[0] == "EORDER": i = max(cols) + 1 self.eorder = numpy.array(line[i:], float) continue rowdata = [] rowmask = [] n = len(line) for i in range(n): word = line[i] if i in cols: if cols[i] == "GENEID": self.geneid.append(word) if cols[i] == "NAME": self.genename.append(word) if cols[i] == "GWEIGHT": self.gweight.append(float(word)) if cols[i] == "GORDER": self.gorder.append(float(word)) continue if not word: rowdata.append(0.0) rowmask.append(0) needmask = 1 else: rowdata.append(float(word)) rowmask.append(1) self.data.append(rowdata) self.mask.append(rowmask) self.data = numpy.array(self.data) if needmask: self.mask = numpy.array(self.mask, int) else: self.mask = None if self.gweight: self.gweight = numpy.array(self.gweight) if self.gorder: self.gorder = numpy.array(self.gorder) def treecluster(self, transpose=0, method='m', dist='e'): """Apply hierarchical clustering and return a Tree object. The pairwise single, complete, centroid, and average linkage hierarchical clustering methods are available. transpose: if equal to 0, genes (rows) are clustered; if equal to 1, microarrays (columns) are clustered. dist : specifies the distance function to be used: dist=='e': Euclidean distance dist=='b': City Block distance dist=='c': Pearson correlation dist=='a': absolute value of the correlation dist=='u': uncentered correlation dist=='x': absolute uncentered correlation dist=='s': Spearman's rank correlation dist=='k': Kendall's tau method : specifies which linkage method is used: method=='s': Single pairwise linkage method=='m': Complete (maximum) pairwise linkage (default) method=='c': Centroid linkage method=='a': Average pairwise linkage See the description of the Tree class for more information about the Tree object returned by this method. """ if transpose == 0: weight = self.eweight else: weight = self.gweight return treecluster(self.data, self.mask, weight, transpose, method, dist) def kcluster(self, nclusters=2, transpose=0, npass=1, method='a', dist='e', initialid=None): """Apply k-means or k-median clustering. This method returns a tuple (clusterid, error, nfound). nclusters: number of clusters (the 'k' in k-means) transpose: if equal to 0, genes (rows) are clustered; if equal to 1, microarrays (columns) are clustered. npass : number of times the k-means clustering algorithm is performed, each time with a different (random) initial condition. method : specifies how the center of a cluster is found: method=='a': arithmetic mean method=='m': median dist : specifies the distance function to be used: dist=='e': Euclidean distance dist=='b': City Block distance dist=='c': Pearson correlation dist=='a': absolute value of the correlation dist=='u': uncentered correlation dist=='x': absolute uncentered correlation dist=='s': Spearman's rank correlation dist=='k': Kendall's tau initialid: the initial clustering from which the algorithm should start. If initialid is None, the routine carries out npass repetitions of the EM algorithm, each time starting from a different random initial clustering. If initialid is given, the routine carries out the EM algorithm only once, starting from the given initial clustering and without randomizing the order in which items are assigned to clusters (i.e., using the same order as in the data matrix). In that case, the k-means algorithm is fully deterministic. Return values: clusterid: array containing the number of the cluster to which each gene/microarray was assigned in the best k-means clustering solution that was found in the npass runs; error: the within-cluster sum of distances for the returned k-means clustering solution; nfound: the number of times this solution was found. """ if transpose == 0: weight = self.eweight else: weight = self.gweight return kcluster(self.data, nclusters, self.mask, weight, transpose, npass, method, dist, initialid) def somcluster(self, transpose=0, nxgrid=2, nygrid=1, inittau=0.02, niter=1, dist='e'): """Calculate a self-organizing map on a rectangular grid. The somcluster method returns a tuple (clusterid, celldata). transpose: if equal to 0, genes (rows) are clustered; if equal to 1, microarrays (columns) are clustered. nxgrid : the horizontal dimension of the rectangular SOM map nygrid : the vertical dimension of the rectangular SOM map inittau : the initial value of tau (the neighborbood function) niter : the number of iterations dist : specifies the distance function to be used: dist=='e': Euclidean distance dist=='b': City Block distance dist=='c': Pearson correlation dist=='a': absolute value of the correlation dist=='u': uncentered correlation dist=='x': absolute uncentered correlation dist=='s': Spearman's rank correlation dist=='k': Kendall's tau Return values: clusterid: array with two columns, while the number of rows is equal to the number of genes or the number of microarrays depending on whether genes or microarrays are being clustered. Each row in the array contains the x and y coordinates of the cell in the rectangular SOM grid to which the gene or microarray was assigned. celldata: an array with dimensions (nxgrid, nygrid, number of microarrays) if genes are being clustered, or (nxgrid, nygrid, number of genes) if microarrays are being clustered. Each element [ix][iy] of this array is a 1D vector containing the gene expression data for the centroid of the cluster in the SOM grid cell with coordinates (ix, iy). """ if transpose == 0: weight = self.eweight else: weight = self.gweight return somcluster(self.data, self.mask, weight, transpose, nxgrid, nygrid, inittau, niter, dist) def clustercentroids(self, clusterid=None, method='a', transpose=0): """Calculate the cluster centroids and return a tuple (cdata, cmask). The centroid is defined as either the mean or the median over all elements for each dimension. data : nrows x ncolumns array containing the expression data mask : nrows x ncolumns array of integers, showing which data are missing. If mask[i][j]==0, then data[i][j] is missing. transpose: if equal to 0, gene (row) clusters are considered; if equal to 1, microarray (column) clusters are considered. clusterid: array containing the cluster number for each gene or microarray. The cluster number should be non-negative. method : specifies how the centroid is calculated: method=='a': arithmetic mean over each dimension. (default) method=='m': median over each dimension. Return values: cdata : 2D array containing the cluster centroids. If transpose==0, then the dimensions of cdata are nclusters x ncolumns. If transpose==1, then the dimensions of cdata are nrows x nclusters. cmask : 2D array of integers describing which elements in cdata, if any, are missing. """ return clustercentroids(self.data, self.mask, clusterid, method, transpose) def clusterdistance(self, index1=[0], index2=[0], method='a', dist='e', transpose=0): """Calculate the distance between two clusters. index1 : 1D array identifying which genes/microarrays belong to the first cluster. If the cluster contains only one gene, then index1 can also be written as a single integer. index2 : 1D array identifying which genes/microarrays belong to the second cluster. If the cluster contains only one gene, then index2 can also be written as a single integer. transpose: if equal to 0, genes (rows) are clustered; if equal to 1, microarrays (columns) are clustered. dist : specifies the distance function to be used: dist=='e': Euclidean distance dist=='b': City Block distance dist=='c': Pearson correlation dist=='a': absolute value of the correlation dist=='u': uncentered correlation dist=='x': absolute uncentered correlation dist=='s': Spearman's rank correlation dist=='k': Kendall's tau method : specifies how the distance between two clusters is defined: method=='a': the distance between the arithmetic means of the two clusters method=='m': the distance between the medians of the two clusters method=='s': the smallest pairwise distance between members of the two clusters method=='x': the largest pairwise distance between members of the two clusters method=='v': average of the pairwise distances between members of the clusters transpose: if equal to 0: clusters of genes (rows) are considered; if equal to 1: clusters of microarrays (columns) are considered. """ if transpose == 0: weight = self.eweight else: weight = self.gweight return clusterdistance(self.data, self.mask, weight, index1, index2, method, dist, transpose) def distancematrix(self, transpose=0, dist='e'): """Calculate the distance matrix and return it as a list of arrays transpose: if equal to 0: calculate the distances between genes (rows); if equal to 1: calculate the distances beteeen microarrays (columns). dist : specifies the distance function to be used: dist=='e': Euclidean distance dist=='b': City Block distance dist=='c': Pearson correlation dist=='a': absolute value of the correlation dist=='u': uncentered correlation dist=='x': absolute uncentered correlation dist=='s': Spearman's rank correlation dist=='k': Kendall's tau Return value: The distance matrix is returned as a list of 1D arrays containing the distance matrix between the gene expression data. The number of columns in each row is equal to the row number. Hence, the first row has zero elements. An example of the return value is matrix = [[], array([1.]), array([7., 3.]), array([4., 2., 6.])] This corresponds to the distance matrix [0., 1., 7., 4.] [1., 0., 3., 2.] [7., 3., 0., 6.] [4., 2., 6., 0.] """ if transpose == 0: weight = self.eweight else: weight = self.gweight return distancematrix(self.data, self.mask, weight, transpose, dist) def save(self, jobname, geneclusters=None, expclusters=None): """Save the clustering results. The saved files follow the convention for the Java TreeView program, which can therefore be used to view the clustering result. Arguments: jobname: The base name of the files to be saved. The filenames are jobname.cdt, jobname.gtr, and jobname.atr for hierarchical clustering, and jobname-K*.cdt, jobname-K*.kgg, jobname-K*.kag for k-means clustering results. geneclusters=None: For hierarchical clustering results, geneclusters is a Tree object as returned by the treecluster method. For k-means clustering results, geneclusters is a vector containing ngenes integers, describing to which cluster a given gene belongs. This vector can be calculated by kcluster. expclusters=None: For hierarchical clustering results, expclusters is a Tree object as returned by the treecluster method. For k-means clustering results, expclusters is a vector containing nexps integers, describing to which cluster a given experimental condition belongs. This vector can be calculated by kcluster. """ (ngenes,nexps) = numpy.shape(self.data) if self.gorder == None: gorder = numpy.arange(ngenes) else: gorder = self.gorder if self.eorder == None: eorder = numpy.arange(nexps) else: eorder = self.eorder if geneclusters!=None and expclusters!=None and \ type(geneclusters) != type(expclusters): raise ValueError("found one k-means and one hierarchical " + "clustering solution in geneclusters and " + "expclusters") gid = 0 aid = 0 filename = jobname postfix = "" if type(geneclusters) == Tree: # This is a hierarchical clustering result. geneindex = _savetree(jobname, geneclusters, gorder, 0) gid = 1 elif geneclusters!=None: # This is a k-means clustering result. filename = jobname + "_K" k = max(geneclusters+1) kggfilename = "%s_K_G%d.kgg" % (jobname, k) geneindex = self._savekmeans(kggfilename, geneclusters, gorder, 0) postfix = "_G%d" % k else: geneindex = numpy.argsort(gorder) if type(expclusters) == Tree: # This is a hierarchical clustering result. expindex = _savetree(jobname, expclusters, eorder, 1) aid = 1 elif expclusters!=None: # This is a k-means clustering result. filename = jobname + "_K" k = max(expclusters+1) kagfilename = "%s_K_A%d.kag" % (jobname, k) expindex = self._savekmeans(kagfilename, expclusters, eorder, 1) postfix += "_A%d" % k else: expindex = numpy.argsort(eorder) filename = filename + postfix self._savedata(filename,gid,aid,geneindex,expindex) def _savekmeans(self, filename, clusterids, order, transpose): # Save a k-means clustering solution if transpose == 0: label = self.uniqid names = self.geneid else: label = "ARRAY" names = self.expid try: outputfile = open(filename, "w") except IOError: raise IOError("Unable to open output file") outputfile.write(label + "\tGROUP\n") index = numpy.argsort(order) n = len(names) sortedindex = numpy.zeros(n, int) counter = 0 cluster = 0 while counter < n: for j in index: if clusterids[j] == cluster: outputfile.write("%s\t%s\n" % (names[j], cluster)) sortedindex[counter] = j counter += 1 cluster += 1 outputfile.close() return sortedindex def _savedata(self, jobname, gid, aid, geneindex, expindex): # Save the clustered data. if self.genename == None: genename = self.geneid else: genename = self.genename (ngenes, nexps) = numpy.shape(self.data) try: outputfile = open(jobname+'.cdt', 'w') except IOError: raise IOError("Unable to open output file") if self.mask!=None: mask = self.mask else: mask = numpy.ones((ngenes,nexps), int) if self.gweight!=None: gweight = self.gweight else: gweight = numpy.ones(ngenes) if self.eweight!=None: eweight = self.eweight else: eweight = numpy.ones(nexps) if gid: outputfile.write('GID\t') outputfile.write(self.uniqid) outputfile.write('\tNAME\tGWEIGHT') # Now add headers for data columns. for j in expindex: outputfile.write('\t%s' % self.expid[j]) outputfile.write('\n') if aid: outputfile.write("AID") if gid: outputfile.write('\t') outputfile.write("\t\t") for j in expindex: outputfile.write('\tARRY%dX' % j) outputfile.write('\n') outputfile.write('EWEIGHT') if gid: outputfile.write('\t') outputfile.write('\t\t') for j in expindex: outputfile.write('\t%f' % eweight[j]) outputfile.write('\n') for i in geneindex: if gid: outputfile.write('GENE%dX\t' % i) outputfile.write("%s\t%s\t%f" % (self.geneid[i], genename[i], gweight[i])) for j in expindex: outputfile.write('\t') if mask[i,j]: outputfile.write(str(self.data[i,j])) outputfile.write('\n') outputfile.close() def read(handle): """Read gene expression data from the file handle and return a Record. The file should be in the file format defined for Michael Eisen's Cluster/TreeView program. """ return Record(handle) cluster-1.52a/windows/0000755000100500010050000000000012177164022014605 5ustar mdehoonmdehooncluster-1.52a/windows/resources.rc0000644000100500010050000002644611353767075017175 0ustar mdehoonmdehoon#include #include "cluster.h" #include "resources.h" ID_ICON ICON "cluster.ico" ID_MENU MENU BEGIN POPUP "&File" BEGIN MENUITEM "&Open data file", CMD_FILE_OPEN MENUITEM "&Save data file", CMD_FILE_SAVE MENUITEM SEPARATOR MENUITEM "E&xit", CMD_FILE_EXIT END POPUP "&Help" BEGIN MENUITEM "&Help", CMD_HELP_HTMLHELP MENUITEM "Read local &manual", CMD_HELP_MANUAL MENUITEM "Read &online manual", CMD_HELP_DOWNLOAD MENUITEM "&File format help", CMD_HELP_FILEFORMAT MENUITEM SEPARATOR MENUITEM "&About...", CMD_HELP_ABOUT END END ID_ABOUT DIALOGEX 0, 0, 200, 130 STYLE DS_MODALFRAME | WS_SYSMENU | WS_POPUP | WS_CAPTION FONT 8, "MS Sans Serif" CAPTION "About Cluster" { LTEXT "Cluster 3.0\nusing the C Clustering Library version " CLUSTERVERSION "\n\nCluster was originally written by Michael Eisen\n(eisen 'AT' rana.lbl.gov)\nCopyright 1998-99 Stanford University\n\nCluster version 3.0 was created by Michiel de Hoon\n(mdehoon 'AT' gsc.riken.jp),\ntogether with Seiya Imoto and Satoru Miyano.\n\nUniversity of Tokyo, Human Genome Center\nJune 2002", -1, 20, 10, 200, 120 } ID_FILEFORMAT DIALOGEX 0, 0, 325, 341 STYLE DS_MODALFRAME | WS_SYSMENU | WS_POPUP | WS_CAPTION | WS_MINIMIZEBOX FONT 8, "MS Sans Serif" CAPTION "File Format" { CONTROL "",-1,"STATIC",SS_SUNKEN, 37,10,250,230 CONTROL "The input for the clustering program is a tab-delimited text file.\r\nAn example is shown below.\r\n\r\nThe cells in red must appear in the file, although they can be any string.\r\nThe cells in bold are headers for optional columns/rows.\r\n\r\nUNIQID: (string/number)\r\nThis column should contain uniqueidentifiers for each gene.\r\n\r\nNAME: (string)\r\nA text description of each gene which will be used in display.\r\n\r\nEWEIGHT: (real number)\r\nA weight for each experiment that can be used to count certain experiments more than others.\r\n\r\nGWEIGHT: (real number)\r\nA similar weight for each gene can be used when clustering arrays.\r\n\r\nGORDER: (real number)\r\nA value to be used for ordering nodes in display program\r\n\r\nEXPID: (string, e.g. EXP1, EXP2,...)\r\nA text description of each experiment that will be used in the display.\r\n\r\nDATA: (real number)\r\nData for a single gene in a single experiment. Any desired numerical transform (e.g. log) should be applied before clustering. Missing values are acceptable.",-1,"EDIT",ES_READONLY|ES_MULTILINE, 38,11,248,228 CONTROL ID_FILEFORMAT_BMP,ID_FILEFORMAT_BMP_LOCATION,"Static",SS_BITMAP,10,250,305,81 } ID_FILEFORMAT_BMP BITMAP DISCARDABLE "format.bmp" /* For some reason, the bitmap does not show up automatically when compiled * with windres. Set the bitmap explicitly in gui.c instead. */ ID_MAINDIALOG DIALOGEX 100, 100, 320, 375 STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX FONT 8, "MS Sans Serif" CAPTION "Gene Cluster 3.0" MENU ID_MENU BEGIN CONTROL "",-1,"Static",SS_SUNKEN,5,5,310,120 LTEXT "File loaded", -1,10,16,80,8 LTEXT "Job name", -1,10,82,80,8 LTEXT "Data set has", -1,10,105,80,8 LTEXT "", ID_FILEMANAGER_ROWS,140,100,30,8 LTEXT "", ID_FILEMANAGER_COLUMNS,140,112,30,8 LTEXT "Rows", -1,170,100,80,8 LTEXT "Columns", -1,170,112,80,8 EDITTEXT ID_FILEMANAGER_FILEMEMO,95,14,210,60,ES_READONLY | ES_MULTILINE | NOT WS_TABSTOP EDITTEXT ID_FILEMANAGER_JOBNAME,95,80,210,12, NOT WS_TABSTOP CONTROL "",ID_TABCTRL,"SysTabControl32",WS_CHILD | WS_CLIPSIBLINGS |WS_VISIBLE ,5,130,310,230 CONTROL "",ID_STATUSBAR,"msctls_statusbar32", WS_CHILD | WS_VISIBLE, 0, 0, 320, 10 END ID_FILTER_TAB DIALOGEX 10, 20, 290, 200 STYLE WS_CHILD FONT 8, "MS Sans Serif" BEGIN GROUPBOX "Filter Genes",-1,10,5,270,195 AUTOCHECKBOX "% Present >=",ID_FILTER_PERCENT_XB,25,35,80,12 CONTROL "80", ID_FILTER_PERCENT,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,105,35,50,12 AUTOCHECKBOX "SD (Gene Vector)",ID_FILTER_STD_XB,25,60,80,12 CONTROL "2.0", ID_FILTER_STD,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,105,60,50,12 AUTOCHECKBOX "At least",ID_FILTER_OBSERVATION_XB,25,85,35,12 CONTROL "1", ID_FILTER_NUMBER,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,65,85,25,12 LTEXT "observations with abs(Val) >=", -1,100,87,120,12 CONTROL "2.0", ID_FILTER_OBSERVATION_VALUE,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,195,85,50,12 AUTOCHECKBOX "MaxVal - MinVal >=",ID_FILTER_MAXMIN_XB,25,110,75,12 CONTROL "2.0", ID_FILTER_MAXMIN,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,105,110,50,12 PUSHBUTTON "Apply Filter", ID_FILTER_APPLY,110,134,70,15 CTEXT "", ID_FILTER_RESULT,20,157,250,10 PUSHBUTTON "Accept Filter", ID_FILTER_ACCEPT,110,175,70,15,WS_DISABLED END ID_ADJUST_TAB DIALOGEX 10, 20, 290, 200 STYLE WS_CHILD FONT 8, "MS Sans Serif" BEGIN GROUPBOX "Adjust Data",-1,10,5,270,195 CONTROL "",-1,"Static", SS_SUNKEN,20,20,250,24 AUTOCHECKBOX "Log transform data",ID_ADJUST_LOG_XB,25,26,80,12 CONTROL "",-1,"Static", SS_SUNKEN,20,54,120,69 AUTOCHECKBOX "Center genes",ID_ADJUST_CENTER_GENES_XB,25,60,60,12 AUTORADIOBUTTON "Mean",ID_ADJUST_MEAN_GENES,45,75,40,12,WS_GROUP AUTORADIOBUTTON "Median",ID_ADJUST_MEDIAN_GENES,45,90,40,12 AUTOCHECKBOX "Normalize genes",ID_ADJUST_NORMALIZE_GENES,25,105,70,12 CONTROL "",-1,"Static", SS_SUNKEN,150,54,120,69 AUTOCHECKBOX "Center arrays",ID_ADJUST_CENTER_ARRAYS_XB,155,60,60,12 AUTORADIOBUTTON "Mean",ID_ADJUST_MEAN_ARRAYS,175,75,40,12,WS_GROUP AUTORADIOBUTTON "Median",ID_ADJUST_MEDIAN_ARRAYS,175,90,40,12 AUTOCHECKBOX "Normalize arrays",ID_ADJUST_NORMALIZE_ARRAYS,155,105,70,12 LTEXT "Order of Operations:\n\nLog Transform\nCenter Genes\nNormalize Genes\nCenter Arrays\nNormalize Arrays", -1,20,133,120,60,WS_BORDER PUSHBUTTON "Apply", ID_ADJUST_APPLY,180,175,70,15 END ID_HIERARCHICAL_TAB DIALOGEX 5, 20, 300, 200 STYLE WS_CHILD FONT 8, "MS Sans Serif" BEGIN GROUPBOX "Genes",-1,5,10,135,110 AUTOCHECKBOX "Cluster",ID_HIERARCHICAL_GENE_XB,15,30,40,10 AUTOCHECKBOX "Calculate weights",ID_HIERARCHICAL_GENE_WEIGHT_XB,15,50,45,20,BS_MULTILINE CTEXT "Similarity Metric", -1,40,80,65,8 CONTROL "", ID_HIERARCHICAL_GENE_METRIC, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 15, 90, 115, 108 GROUPBOX "Arrays",-1,155,10,135,110 AUTOCHECKBOX "Cluster",ID_HIERARCHICAL_ARRAY_XB,165,30,40,10 AUTOCHECKBOX "Calculate weights",ID_HIERARCHICAL_ARRAY_WEIGHT_XB,165,50,45,20,BS_MULTILINE CTEXT "Similarity Metric", -1,190,80,65,8 CONTROL "", ID_HIERARCHICAL_ARRAY_METRIC, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 165, 90, 115, 108 GROUPBOX "Clustering method",-1,5,130,285,45 PUSHBUTTON "Centroid linkage", ID_HIERARCHICAL_CENTROID,15,145,61,20 PUSHBUTTON "Single linkage", ID_HIERARCHICAL_SINGLE,83,145,61,20 PUSHBUTTON "Complete linkage", ID_HIERARCHICAL_COMPLETE,151,145,61,20 PUSHBUTTON "Average linkage", ID_HIERARCHICAL_AVERAGE,219,145,61,20 END ID_KMEANS_TAB DIALOGEX 10, 20, 290, 200 STYLE WS_CHILD FONT 8, "MS Sans Serif" BEGIN GROUPBOX "Genes",-1,10,10,130,165 AUTOCHECKBOX "Organize genes",ID_KMEANS_GENE_XB,20,30,90,10 CONTROL "10", ID_KMEANS_GENE_K,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,20,51,25,12 LTEXT "number of clusters (k)", -1,50,53,70,12 CONTROL "100", ID_KMEANS_GENE_RUNS,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,20,70,50,12 LTEXT "number of runs", -1,75,72,50,12 GROUPBOX "Method",-1,20,95,80,45 AUTORADIOBUTTON "k-Means",ID_KMEANS_GENE_MEAN,30,105,40,10 AUTORADIOBUTTON "k-Medians",ID_KMEANS_GENE_MEDIAN,30,120,50,10 CTEXT "Similarity Metric", -1,45,145,65,8 CONTROL "", ID_KMEANS_GENE_METRIC, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 20, 155, 115, 108 GROUPBOX "Arrays",-1,150,10,130,165 AUTOCHECKBOX "Organize arrays",ID_KMEANS_ARRAY_XB,160,30,90,10 CONTROL "10", ID_KMEANS_ARRAY_K,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,160,51,25,12 LTEXT "number of clusters (k)", -1,190,53,70,12 CONTROL "100", ID_KMEANS_ARRAY_RUNS,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,160,70,50,12 LTEXT "number of runs", -1,215,72,50,12 GROUPBOX "Method",-1,160,95,80,45 AUTORADIOBUTTON "k-Means",ID_KMEANS_ARRAY_MEAN,165,105,40,10 AUTORADIOBUTTON "k-Medians",ID_KMEANS_ARRAY_MEDIAN,165,120,50,10 CTEXT "Similarity Metric", -1,185,145,65,8 CONTROL "", ID_KMEANS_ARRAY_METRIC, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 160, 155, 115, 108 PUSHBUTTON "Execute", ID_KMEANS_BUTTON,120,180,50,15 END ID_SOM_TAB DIALOGEX 5, 20, 300, 200 STYLE WS_CHILD FONT 8, "MS Sans Serif" BEGIN CTEXT "Calculate a Self-Organizing Map", -1,80,2,130,20 GROUPBOX "Genes",-1,10,15,130,160 AUTOCHECKBOX "Organize genes",ID_SOM_GENE_XB,15,35,90,10 CONTROL "4", ID_SOM_GENE_XDIM,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,15,54,25,12 LTEXT "XDim", -1,45,56,50,8 CONTROL "4", ID_SOM_GENE_YDIM,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,15,75,25,12 LTEXT "YDim", -1,45,77,70,8 CONTROL "100000", ID_SOM_GENE_ITERS,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,15,105,50,12 LTEXT "Number of iterations", -1,72,107,65,8 CONTROL "0.02", ID_SOM_GENE_TAU,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,15,126,30,12 LTEXT "Initial tau", -1,50,128,50,8 CTEXT "Similarity Metric", -1,40,145,65,8 CONTROL "", ID_SOM_GENE_METRIC, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 15, 155, 115, 108 GROUPBOX "Arrays",-1,160,15,130,160 AUTOCHECKBOX "Organize arrays",ID_SOM_ARRAY_XB,165,35,90,10 CONTROL "4", ID_SOM_ARRAY_XDIM,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,165,54,25,12 LTEXT "XDim", -1,195,56,50,8 CONTROL "4", ID_SOM_ARRAY_YDIM,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,165,75,25,12 LTEXT "YDim", -1,195,77,70,8 CONTROL "20000", ID_SOM_ARRAY_ITERS,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,165,105,50,12 LTEXT "Number of iterations", -1,220,107,65,8 CONTROL "0.02", ID_SOM_ARRAY_TAU,"EDIT",ES_RIGHT | WS_BORDER | WS_TABSTOP,165,126,30,12 LTEXT "Initial tau", -1,200,128,50,8 CTEXT "Similarity Metric", -1,190,145,65,8 CONTROL "", ID_SOM_ARRAY_METRIC, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 165, 155, 115, 108 PUSHBUTTON "Make SOM", ID_SOM_BUTTON,125,180,55,15 END ID_PCA_TAB DIALOGEX 5, 20, 300, 200 STYLE WS_CHILD FONT 8, "MS Sans Serif" BEGIN GROUPBOX "Principal Component Analysis",-1,10,10,280,180 GROUPBOX "Genes",-1,20,25,120,100 AUTOCHECKBOX "Apply PCA to genes",ID_PCA_GENE_XB,30,45,90,10 GROUPBOX "Arrays",-1,160,25,120,100 AUTOCHECKBOX "Apply PCA to arrays",ID_PCA_ARRAY_XB,170,45,90,10 PUSHBUTTON "Execute", ID_PCA_BUTTON,125,150,50,20 END ID_HIERARCHICAL_GENE_WEIGHT DIALOGEX 58,18,80,60 STYLE WS_CHILD FONT 8, "MS Sans Serif" BEGIN GROUPBOX "Weight Options",-1,5,5,70,50 LTEXT "Cutoff", -1,10,19,20,12 EDITTEXT ID_HIERARCHICAL_GENE_CUTOFF,35,17,35,12,ES_RIGHT LTEXT "Exponent", -1,10,39,30,12 EDITTEXT ID_HIERARCHICAL_GENE_EXP,45,37,25,12,ES_RIGHT END ID_HIERARCHICAL_ARRAY_WEIGHT DIALOGEX 208,18,80,60 STYLE WS_CHILD FONT 8, "MS Sans Serif" BEGIN GROUPBOX "Weight Options",-1,5,5,70,50 LTEXT "Cutoff", -1,10,19,20,12 EDITTEXT ID_HIERARCHICAL_ARRAY_CUTOFF,35,17,35,12,ES_RIGHT LTEXT "Exponent", -1,10,39,30,12 EDITTEXT ID_HIERARCHICAL_ARRAY_EXP,45,37,25,12,ES_RIGHT END cluster-1.52a/windows/gui.c0000644000100500010050000021473212177146335015555 0ustar mdehoonmdehoon/* Software and source code Copyright (C) 1998-2000 Stanford University Written by Michael Eisen (eisen@genome.stanford.edu) This software is copyright under the following conditions: Permission to use, copy, and modify this software and its documentation is hereby granted to all academic and not-for-profit institutions without fee, provided that the above copyright notice and this permission notice appear in all copies of the software and related documentation. Permission to distribute the software or modified or extended versions thereof on a not-for-profit basis is explicitly granted, under the above conditions. However, the right to use this software in conjunction with for profit activities, and the right to distribute the software or modified or extended versions thereof for profit are *NOT* granted except by prior arrangement and written consent of the copyright holders. Use of this source code constitutes an agreement not to criticize, in any way, the code-writing style of the author, including any statements regarding the extent of documentation and comments present. The software is provided "AS-IS" and without warranty of ank kind, express, implied or otherwise, including without limitation, any warranty of merchantability or fitness for a particular purpose. In no event shall Stanford University or the authors be liable for any special, incudental, indirect or consequential damages of any kind, or any damages whatsoever resulting from loss of use, data or profits, whether or not advised of the possibility of damage, and on any theory of liability, arising out of or in connection with the use or performance of this software. This code was written using Borland C++ Builder 4 (Inprise Inc., www.inprise.com) and may be subject to certain additional restrictions as a result. */ /* This program was modified by Michiel de Hoon of the University of Tokyo, Human Genome Center (currently at the RIKEN Genomic Sciences Center; mdehoon 'AT' gsc.riken.jp). The core numerical routines are now located in the C clustering library; this program mainly constains gui-related routines. Instead of the Borland C++ Builder, the GNU C compiler under Cygwin/MinGW was used. MdH 2002.06.13. */ #ifdef UNICODE #define _UNICODE #endif /*============================================================================*/ /* Header files */ /*============================================================================*/ /* Standard C header files */ #include #include /* Standard Windows header files */ #include #include #include /* Local header files */ #include "resources.h" /* Defines dialog windows, menubar, icon, and bitmap */ #include "data.h" /* Includes data handling and file reading/writing */ #include "cluster.h" /* The C clustering library */ /*============================================================================*/ /* GUI utilities */ /*============================================================================*/ static double GetDlgItemDouble(HWND hDlg, int nlDDlgItem, BOOL* lpTranslated) { TCHAR szBuffer[256]; TCHAR* endptr; if (GetDlgItemText(hDlg, nlDDlgItem, szBuffer, sizeof(szBuffer))) { const double dValue = _tcstod(szBuffer, &endptr); if (lpTranslated) *lpTranslated = (*endptr=='\0'); return dValue; } else { if (lpTranslated) *lpTranslated=FALSE; return 0; } } static BOOL SetDlgItemDouble(HWND hwndDlg, int idControl, double dValue) { TCHAR szBuffer[32]; /* Note: wsprintf does not handle floating point values. */ #ifdef UNICODE swprintf(szBuffer, TEXT("%4g"), dValue); #else sprintf(szBuffer, "%4g", dValue); #endif return SetDlgItemText(hwndDlg, idControl, szBuffer); } static void SetMetrics(HWND hWnd, char initial) { SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)TEXT("Correlation (uncentered)")); SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)TEXT("Correlation (centered)")); SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)TEXT("Absolute Correlation (uncentered)")); SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)TEXT("Absolute Correlation (centered)")); SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)TEXT("Spearman Rank Correlation")); SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)TEXT("Kendall's tau")); SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)TEXT("Euclidean distance")); SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)TEXT("City-block distance")); switch (initial) { case 'u': SendMessage(hWnd, CB_SETCURSEL, 0, 0); break; case 'c': SendMessage(hWnd, CB_SETCURSEL, 1, 0); break; case 'a': SendMessage(hWnd, CB_SETCURSEL, 2, 0); break; case 'x': SendMessage(hWnd, CB_SETCURSEL, 3, 0); break; case 's': SendMessage(hWnd, CB_SETCURSEL, 4, 0); break; case 'k': SendMessage(hWnd, CB_SETCURSEL, 5, 0); break; case 'e': SendMessage(hWnd, CB_SETCURSEL, 6, 0); break; case 'b': SendMessage(hWnd, CB_SETCURSEL, 7, 0); break; default : SendMessage(hWnd, CB_SETCURSEL, 0, 0); break; } return; } static char GetMetric(HWND hWnd) { int index = SendMessage(hWnd, CB_GETCURSEL, 0, 0); switch (index) { case 0: return 'u'; break; /* Uncentered correlation */ case 1: return 'c'; break; /* Centered correlation */ case 2: return 'x'; break; /* Absolute uncentered correlation */ case 3: return 'a'; break; /* Absolute centered correlation */ case 4: return 's'; break; /* Spearman rank correlation */ case 5: return 'k'; break; /* Kendall's tau */ case 6: return 'e'; break; /* Euclidean distance */ case 7: return 'b'; break; /* City-block distance */ /* The code will never get here. */ default: return 'e'; /* Euclidean distance is default. */ } } /*============================================================================*/ /* Callback functions --- Tab pages */ /*============================================================================*/ BOOL CALLBACK FilterDialogProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { static BOOL* use = NULL; static int useRows; static HWND hAcceptButton; switch (nMsg) { case WM_INITDIALOG: { use = NULL; hAcceptButton = GetDlgItem(hWnd, ID_FILTER_ACCEPT); if (!hAcceptButton) MessageBox(NULL, TEXT("Program initialization failed"), TEXT("Failed to initialize filtering panel"), MB_OK); return TRUE; } case WM_COMMAND: { if (HIWORD(wParam)==BN_CLICKED) { switch ((int) LOWORD(wParam)) { case ID_FILTER_APPLY: /* Filter data. Apply user selected criteria to flag (for subsequent * removal) rows that fail to pass tests. Note that filters are * assessed here and applied separately so the user can adjust * parameters to get appropriate number of rows passing */ { TCHAR buffer[256]; HWND hTabCtrl = GetParent(hWnd); HWND hWndMain = GetParent(hTabCtrl); const int Rows = GetRows(); const BOOL bStd = IsDlgButtonChecked(hWnd, ID_FILTER_STD_XB); const BOOL bPercent = IsDlgButtonChecked(hWnd, ID_FILTER_PERCENT_XB); const BOOL bAbsVal = IsDlgButtonChecked(hWnd, ID_FILTER_OBSERVATION_XB); const BOOL bMaxMin = IsDlgButtonChecked(hWnd, ID_FILTER_MAXMIN_XB); double value; double absVal; double percent; double std; int numberAbs; double maxmin; int intvalue; BOOL error; int Row; /* Read information from the edit boxes */ value = GetDlgItemDouble(hWnd, ID_FILTER_OBSERVATION_VALUE, &error); absVal = error ? value : 0.0; value = GetDlgItemDouble(hWnd, ID_FILTER_PERCENT, &error); percent = error ? value : 0.0; value = GetDlgItemDouble(hWnd, ID_FILTER_STD, &error); std = error ? value : 0.0; intvalue = GetDlgItemInt(hWnd, ID_FILTER_NUMBER, &error, FALSE); numberAbs = error ? intvalue : 0; value = GetDlgItemDouble(hWnd, ID_FILTER_MAXMIN, &error); maxmin = error ? value : 0.0; SendMessage(hWnd, IDM_RESET, 0, 0); /* Store results in boolean use */ if (use) free(use); use = malloc(Rows*sizeof(BOOL)); if (!use) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Filtering failed"), MB_OK); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Filtering failed"), 0); return TRUE; } useRows = 0; for (Row = 0; Row < Rows; Row++) { wsprintf(buffer, TEXT("Assessing filters for gene %d"), Row); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)buffer, 0); use[Row] = FilterRow(Row, bStd, bPercent, bAbsVal, bMaxMin, absVal, percent, std, numberAbs, maxmin); /* Count how many passed */ if (use[Row]) useRows++; } /* Tell user how many rows passed */ wsprintf(buffer, TEXT("%d passed out of %d"), useRows, Rows); SetDlgItemText(hWnd, ID_FILTER_RESULT, buffer); EnableWindow(hAcceptButton, TRUE); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Done Analyzing Filters"), 0); return TRUE; } case ID_FILTER_ACCEPT: /* Accept results of last filtering */ { int ok; HWND hTabCtrl = GetParent(hWnd); HWND hWndMain = GetParent(hTabCtrl); EnableWindow(hAcceptButton, FALSE); ok = SelectSubset(useRows, use); if (!ok) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Failed to apply filtering"), MB_OK); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Filtering failed"), 0); return TRUE; } SendMessage(hWndMain, IDM_UPDATEINFO, 0, 0); return TRUE; } } } break; } case IDM_RESET: { SetDlgItemText(hWnd, ID_FILTER_RESULT, TEXT("")); EnableWindow(hAcceptButton, FALSE); return TRUE; } case WM_DESTROY: { if (use) free(use); return TRUE; } } return FALSE; } BOOL CALLBACK AdjustDialogProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) /* Adjust data values in various ways */ { static HWND GeneMeanButton; static HWND GeneMedianButton; static HWND ArrayMeanButton; static HWND ArrayMedianButton; switch (nMsg) { case WM_INITDIALOG: { GeneMeanButton = GetDlgItem(hWnd, ID_ADJUST_MEAN_GENES); GeneMedianButton = GetDlgItem(hWnd, ID_ADJUST_MEDIAN_GENES); ArrayMeanButton = GetDlgItem(hWnd, ID_ADJUST_MEAN_ARRAYS); ArrayMedianButton = GetDlgItem(hWnd, ID_ADJUST_MEDIAN_ARRAYS); if (!GeneMeanButton || !GeneMedianButton || !ArrayMeanButton || !ArrayMedianButton) { MessageBox(NULL, TEXT("Program initialization failed"), TEXT("Failed to initialize adjustment panel"), MB_OK); return TRUE; } EnableWindow(GeneMeanButton, FALSE); EnableWindow(GeneMedianButton, FALSE); EnableWindow(ArrayMeanButton, FALSE); EnableWindow(ArrayMedianButton, FALSE); CheckDlgButton(hWnd, ID_ADJUST_MEAN_GENES, 1); CheckDlgButton(hWnd, ID_ADJUST_MEAN_ARRAYS, 1); return TRUE; } case WM_COMMAND: { if (HIWORD(wParam)==BN_CLICKED) { switch ((int) LOWORD(wParam)) { case ID_ADJUST_CENTER_GENES_XB: { UINT state = IsDlgButtonChecked(hWnd, ID_ADJUST_CENTER_GENES_XB); int flag = (state==BST_CHECKED); if (GeneMeanButton) EnableWindow(GeneMeanButton, flag); if (GeneMedianButton) EnableWindow(GeneMedianButton, flag); return TRUE; } case ID_ADJUST_CENTER_ARRAYS_XB: { UINT state = IsDlgButtonChecked(hWnd, ID_ADJUST_CENTER_ARRAYS_XB); int flag = (state==BST_CHECKED); if (ArrayMeanButton) EnableWindow(ArrayMeanButton, flag); if (ArrayMedianButton) EnableWindow(ArrayMedianButton, flag); return TRUE; } case ID_ADJUST_APPLY: { HWND hTabCtrl = GetParent(hWnd); HWND hWndMain = GetParent(hTabCtrl); BOOL bLogTransform; BOOL GeneMeanCenter = FALSE; BOOL GeneMedianCenter = FALSE; BOOL GeneNormalize; BOOL ArrayMeanCenter = FALSE; BOOL ArrayMedianCenter = FALSE; BOOL ArrayNormalize; int ok; SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Adjusting data"), 0); bLogTransform = IsDlgButtonChecked(hWnd, ID_ADJUST_LOG_XB); if (bLogTransform) LogTransform(); if (IsDlgButtonChecked(hWnd, ID_ADJUST_CENTER_GENES_XB)) { GeneMeanCenter = IsDlgButtonChecked(hWnd, ID_ADJUST_MEAN_GENES); GeneMedianCenter = IsDlgButtonChecked(hWnd, ID_ADJUST_MEDIAN_GENES); } GeneNormalize = IsDlgButtonChecked(hWnd, ID_ADJUST_NORMALIZE_GENES); ok = AdjustGenes(GeneMeanCenter, GeneMedianCenter, GeneNormalize); if (!ok) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error adjusting genes"), MB_OK); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error adjusting genes"), 0); return TRUE; } if (IsDlgButtonChecked(hWnd, ID_ADJUST_CENTER_ARRAYS_XB)) { ArrayMeanCenter = IsDlgButtonChecked(hWnd, ID_ADJUST_MEAN_ARRAYS); ArrayMedianCenter = IsDlgButtonChecked(hWnd, ID_ADJUST_MEDIAN_ARRAYS); } ArrayNormalize = IsDlgButtonChecked(hWnd, ID_ADJUST_NORMALIZE_ARRAYS); ok = AdjustArrays(ArrayMeanCenter, ArrayMedianCenter, ArrayNormalize); if (!ok) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error adjusting arrays"), MB_OK); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error adjusting arrays"), 0); return TRUE; } SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Done adjusting data"), 0); return TRUE; } } } } } return FALSE; } BOOL CALLBACK HierarchicalDialogProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { static HWND hWndGeneWeight; static HWND hWndArrayWeight; static HWND hGeneMetric; static HWND hArrayMetric; switch (nMsg) { case WM_INITDIALOG: { /* First assign the default values for the weights */ double GeneWeightExp = 1.0; double ArrayWeightExp = 1.0; double GeneWeightCutoff = 0.9; double ArrayWeightCutoff = 0.9; /* Try to read saved values from the registry */ HKEY hKey; LONG lRet; lRet = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Stanford\\Cluster\\WeightSettings"), 0, KEY_QUERY_VALUE, &hKey); if (lRet==ERROR_SUCCESS) { DWORD dwSize = sizeof(double); DWORD dwType = REG_BINARY; double value; lRet = RegQueryValueEx(hKey, TEXT("GeneWeightCutoff"), NULL, &dwType, (LPBYTE) &value, &dwSize); if (lRet == ERROR_SUCCESS) GeneWeightCutoff = value; lRet = RegQueryValueEx(hKey, TEXT("GeneWeightExp"), NULL, &dwType, (LPBYTE) &value, &dwSize); if (lRet == ERROR_SUCCESS) GeneWeightExp = value; lRet = RegQueryValueEx(hKey, TEXT("ArrayWeightCutoff"), NULL, &dwType, (LPBYTE) &value, &dwSize); if (lRet == ERROR_SUCCESS) ArrayWeightCutoff = value; lRet = RegQueryValueEx(hKey, TEXT("ArrayWeightExp"), NULL, &dwType, (LPBYTE) &value, &dwSize); if (lRet == ERROR_SUCCESS) ArrayWeightExp = value; } RegCloseKey(hKey); /* Create weights window */ hWndGeneWeight = CreateDialog(NULL, MAKEINTRESOURCE(ID_HIERARCHICAL_GENE_WEIGHT), hWnd, NULL); hWndArrayWeight = CreateDialog(NULL, MAKEINTRESOURCE(ID_HIERARCHICAL_ARRAY_WEIGHT), hWnd, NULL); /* Set the weights that we found */ SetDlgItemDouble(hWndGeneWeight, ID_HIERARCHICAL_GENE_EXP, GeneWeightExp); SetDlgItemDouble(hWndArrayWeight, ID_HIERARCHICAL_ARRAY_EXP, ArrayWeightExp); SetDlgItemDouble(hWndGeneWeight, ID_HIERARCHICAL_GENE_CUTOFF, GeneWeightCutoff); SetDlgItemDouble(hWndArrayWeight, ID_HIERARCHICAL_ARRAY_CUTOFF, ArrayWeightCutoff); /* Set up metric combo boxes */ hGeneMetric = GetDlgItem(hWnd, ID_HIERARCHICAL_GENE_METRIC); hArrayMetric = GetDlgItem(hWnd, ID_HIERARCHICAL_ARRAY_METRIC); if (!hGeneMetric || !hArrayMetric) MessageBox(NULL, TEXT("Program initialization failed"), TEXT("Failed to initialize hierarchical clustering panel"), MB_OK); else { SetMetrics(hGeneMetric, 'u'); SetMetrics(hArrayMetric, 'u'); } return TRUE; } case WM_COMMAND: { if (HIWORD(wParam)==BN_CLICKED) { switch ((int) LOWORD(wParam)) { case ID_HIERARCHICAL_CENTROID: { char c = 'c'; SendMessage(hWnd, IDM_HIERARCHICAL_EXECUTE, (WPARAM)&c, 0); return TRUE; } case ID_HIERARCHICAL_SINGLE: { char c = 's'; SendMessage(hWnd, IDM_HIERARCHICAL_EXECUTE, (WPARAM)&c, 0); return TRUE; } case ID_HIERARCHICAL_COMPLETE: { char c = 'm'; SendMessage(hWnd, IDM_HIERARCHICAL_EXECUTE, (WPARAM)&c, 0); return TRUE; } case ID_HIERARCHICAL_AVERAGE: { char c = 'a'; SendMessage(hWnd, IDM_HIERARCHICAL_EXECUTE, (WPARAM)&c, 0); return TRUE; } case ID_HIERARCHICAL_GENE_WEIGHT_XB: { if (IsDlgButtonChecked(hWnd, ID_HIERARCHICAL_GENE_WEIGHT_XB)) ShowWindow(hWndArrayWeight, SW_SHOWNORMAL); else ShowWindow(hWndArrayWeight, SW_HIDE); return TRUE; } case ID_HIERARCHICAL_ARRAY_WEIGHT_XB: { if (IsDlgButtonChecked(hWnd, ID_HIERARCHICAL_ARRAY_WEIGHT_XB)) ShowWindow(hWndGeneWeight, SW_SHOWNORMAL); else ShowWindow(hWndGeneWeight, SW_HIDE); return TRUE; } } } break; } case WM_DESTROY: { double GeneWeightExp = 1; double ArrayWeightExp = 1; double GeneWeightCutoff = 0.1; double ArrayWeightCutoff = 0.1; BOOL error; double value; HKEY hKey; LONG lRet; value = GetDlgItemDouble(hWndGeneWeight, ID_HIERARCHICAL_GENE_EXP, &error); if (!error) GeneWeightExp = value; value = GetDlgItemDouble(hWndArrayWeight, ID_HIERARCHICAL_ARRAY_EXP, &error); if (!error) ArrayWeightExp = value; value = GetDlgItemDouble(hWndGeneWeight, ID_HIERARCHICAL_GENE_CUTOFF, &error); if (!error) GeneWeightCutoff = value; value = GetDlgItemDouble(hWndArrayWeight, ID_HIERARCHICAL_ARRAY_CUTOFF, &error); if (!error) ArrayWeightCutoff = value; /* Write weight information to the registry */ lRet = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Stanford\\Cluster\\WeightSettings"), 0, KEY_SET_VALUE, &hKey); if (lRet == ERROR_SUCCESS) { const DWORD dwSize = sizeof(double); RegSetValueEx(hKey, TEXT("GeneWeightCutOff"), 0, REG_BINARY, (LPBYTE) &GeneWeightCutoff, dwSize); RegSetValueEx(hKey, TEXT("GeneWeightExp"), 0, REG_BINARY, (LPBYTE) &GeneWeightExp, dwSize); RegSetValueEx(hKey, TEXT("ArrayWeightCutOff"), 0, REG_BINARY, (LPBYTE) &ArrayWeightCutoff, dwSize); RegSetValueEx(hKey, TEXT("ArrayWeightExp"), 0, REG_BINARY, (LPBYTE) &ArrayWeightExp, dwSize); } RegCloseKey(hKey); return TRUE; } case IDM_HIERARCHICAL_EXECUTE: { char method = *((char*)wParam); const int Rows = GetRows(); const int Columns = GetColumns(); HWND hTabCtrl = GetParent(hWnd); HWND hWndMain = GetParent(hTabCtrl); BOOL ClusterGenes; BOOL ClusterArrays; BOOL bCalculateGeneWeights; BOOL bCalculateArrayWeights; char genemetric; char arraymetric; FILE* outputfile; TCHAR* jobname; TCHAR filename[MAX_PATH]; TCHAR* filetag; int result; if (!hGeneMetric || !hArrayMetric) { MessageBox(NULL, TEXT("Program initialization failed"), TEXT("Cannot start hierarchical clustering"), MB_OK); return TRUE; } if (Rows==0 || Columns==0) { SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("No data available"), 0); return TRUE; } ClusterGenes = IsDlgButtonChecked(hWnd, ID_HIERARCHICAL_GENE_XB); ClusterArrays = IsDlgButtonChecked(hWnd, ID_HIERARCHICAL_ARRAY_XB); /* Check if we are really clustering anything here */ if (!ClusterGenes && !ClusterArrays) return TRUE; bCalculateGeneWeights = IsDlgButtonChecked(hWnd, ID_HIERARCHICAL_GENE_WEIGHT_XB); bCalculateArrayWeights = IsDlgButtonChecked(hWnd, ID_HIERARCHICAL_ARRAY_WEIGHT_XB); /* Find out which metrics to use */ genemetric = GetMetric(hGeneMetric); arraymetric = GetMetric(hArrayMetric); if (bCalculateGeneWeights || bCalculateArrayWeights) { const char* error; double GeneCutoff = 0.0; double GeneExponent = 0.0; double ArrayCutoff = 0.0; double ArrayExponent = 0.0; SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Calculating weights"), 0); if (bCalculateGeneWeights) { ArrayCutoff = GetDlgItemDouble(hWndArrayWeight, ID_HIERARCHICAL_ARRAY_CUTOFF, NULL); ArrayExponent = GetDlgItemDouble(hWndArrayWeight, ID_HIERARCHICAL_ARRAY_EXP, NULL); } if (bCalculateArrayWeights) { GeneCutoff = GetDlgItemDouble(hWndGeneWeight, ID_HIERARCHICAL_GENE_CUTOFF, NULL); GeneExponent = GetDlgItemDouble(hWndGeneWeight, ID_HIERARCHICAL_GENE_EXP, NULL); } error = CalculateWeights(GeneCutoff, GeneExponent, genemetric, ArrayCutoff, ArrayExponent, arraymetric); if (error) { #ifdef UNICODE TCHAR buffer[256]; MultiByteToWideChar(CP_ACP, 0, error, -1, buffer, 256); MessageBox(NULL, buffer, TEXT("Error"), MB_OK); #else MessageBox(NULL, error, TEXT("Error"), MB_OK); #endif return TRUE; } } SendMessage(hWndMain, IDM_GETJOBNAME, (WPARAM)&jobname, 0); filetag = filename + wsprintf(filename, jobname); free(jobname); switch(method) { case 'c': SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Performing centroid linkage hierarchical clustering"), 0); break; case 's': SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Performing single linkage hierarchical clustering"), 0); break; case 'm': SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Performing complete linkage hierarchical clustering"), 0); break; case 'a': SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Performing average linkage hierarchical clustering"), 0); break; default: SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("ERROR: Unknown clustering method"), 0); /* Never get here */ return TRUE; } /* Find out what we need to do here */ if (ClusterGenes) { wsprintf(filetag, TEXT(".gtr")); outputfile = _tfopen(filename, TEXT("wt")); if (!outputfile) { MessageBox(NULL, TEXT("Error: Unable to open the output file"), TEXT("Error"), 0); return TRUE; } result = HierarchicalCluster(outputfile, genemetric, FALSE, method); fclose(outputfile); if (!result) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error performing hierarchical clustering"), 0); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error performing hierarchical clustering"), 0); return TRUE; } } if (ClusterArrays) { wsprintf(filetag, TEXT(".atr")); outputfile = _tfopen(filename, TEXT("wt")); if (!outputfile) { MessageBox(NULL, TEXT("Error: Unable to open the output file"), TEXT("Error"), 0); return TRUE; } result = HierarchicalCluster(outputfile, arraymetric, TRUE, method); fclose(outputfile); if (!result) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error performing hierarchical clustering"), 0); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error performing hierarchical clustering"), 0); return TRUE; } } SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Saving the clustering result"), 0); /* Now make output .cdt file */ wsprintf(filetag, TEXT(".cdt")); outputfile = _tfopen(filename, TEXT("wt")); if (!outputfile) { MessageBox(NULL, TEXT("Error: Unable to open the output file"), TEXT("Error"), 0); return TRUE; } result = Save(outputfile, ClusterGenes, ClusterArrays); fclose(outputfile); if (result) SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Done clustering"), 0); else { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error saving file"), 0); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error saving to file"), 0); } return TRUE; } } return FALSE; } BOOL CALLBACK KmeansDialogProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { static HWND hGeneMetric; static HWND hArrayMetric; switch (nMsg) { case WM_INITDIALOG: { /* Set up metric combo boxes */ hGeneMetric = GetDlgItem(hWnd, ID_KMEANS_GENE_METRIC); hArrayMetric = GetDlgItem(hWnd, ID_KMEANS_ARRAY_METRIC); if (!hGeneMetric || !hArrayMetric) MessageBox(NULL, TEXT("Program initialization failed"), TEXT("Failed to initialize k-means clustering panel"), MB_OK); else { SetMetrics(hGeneMetric, 'e'); SetMetrics(hArrayMetric, 'e'); } CheckDlgButton(hWnd, ID_KMEANS_GENE_MEAN,1); CheckDlgButton(hWnd, ID_KMEANS_ARRAY_MEAN,1); return TRUE; } case WM_COMMAND: { if (HIWORD(wParam)==BN_CLICKED) { switch ((int) LOWORD(wParam)) { case ID_KMEANS_BUTTON: { const int Rows = GetRows(); const int Columns = GetColumns(); HWND hTabCtrl = GetParent(hWnd); HWND hWndMain = GetParent(hTabCtrl); TCHAR* jobname; TCHAR filename[MAX_PATH]; TCHAR* filetag; FILE* outputfile; /* One for the terminating \0; to be increased below */ BOOL ClusterGenes; BOOL ClusterArrays; int kGenes = 0; int kArrays = 0; int ok; if (!hGeneMetric || !hArrayMetric) { MessageBox(NULL, TEXT("Program initialization failed"), TEXT("Cannot start k-means clustering"), MB_OK); return TRUE; } if (Rows==0 || Columns==0) { SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("No data available"), 0); return TRUE; } SendMessage(hWndMain, IDM_GETJOBNAME, (WPARAM)&jobname, 0); filetag = filename + wsprintf(filename, jobname); free(jobname); ClusterGenes = IsDlgButtonChecked(hWnd, ID_KMEANS_GENE_XB); ClusterArrays = IsDlgButtonChecked(hWnd, ID_KMEANS_ARRAY_XB); if (!ClusterGenes && !ClusterArrays) return TRUE; /* Nothing to do */ SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Executing k-means clustering"), 0); if (ClusterGenes) { char method; char dist; int* NodeMap; int nGeneTrials; int ifound; ok = 1; TCHAR buffer[256]; kGenes = GetDlgItemInt(hWnd, ID_KMEANS_GENE_K, NULL, FALSE); if (kGenes==0) { SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Choose a nonzero number of clusters"), 0); return TRUE; } if (Rows < kGenes) { SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("More clusters than genes available"), 0); return TRUE; } method = IsDlgButtonChecked(hWnd, ID_KMEANS_GENE_MEAN) ? 'a' : 'm'; /* 'a' is average, 'm' is median */ dist = GetMetric(hGeneMetric); NodeMap = malloc(Rows*sizeof(int)); if (!NodeMap) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error performing k-means clustering"), MB_OK); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error performing k-means clustering"), 0); return TRUE; } nGeneTrials = GetDlgItemInt(hWnd, ID_KMEANS_GENE_RUNS, NULL, FALSE); ifound = GeneKCluster(kGenes, nGeneTrials, method, dist, NodeMap); if (ifound < 0) ok = 0; if (ok) { wsprintf(buffer, TEXT("Solution was found %d times"), ifound); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)buffer, 0); wsprintf(filetag, TEXT("_K_G%d.kgg"), kGenes); outputfile = _tfopen(filename, TEXT("wt")); if (!outputfile) { MessageBox(NULL, TEXT("Error: Unable to open the output file"), TEXT("Error"), 0); free(NodeMap); return TRUE; } ok = SaveGeneKCluster(outputfile, kGenes, NodeMap); fclose(outputfile); } free(NodeMap); if (!ok) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error performing k-means clustering"), MB_OK); wsprintf(buffer, TEXT("Error saving file %s"), filename); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)buffer, 0); return TRUE; } } if (ClusterArrays) { char method; char dist; int nArrayTrials; int* NodeMap; int ifound; ok = 1; TCHAR buffer[256]; kArrays = GetDlgItemInt(hWnd, ID_KMEANS_ARRAY_K, NULL, FALSE); if (kArrays==0) { SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Choose a nonzero number of clusters"), 0); return TRUE; } if (Columns < kArrays) { SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("More clusters than experiments available"), 0); return TRUE; } method = IsDlgButtonChecked(hWnd, ID_KMEANS_ARRAY_MEAN) ? 'a' : 'm'; /* 'a' is average, 'm' is median */ dist = GetMetric(hArrayMetric); nArrayTrials = GetDlgItemInt(hWnd, ID_KMEANS_ARRAY_RUNS, NULL, FALSE); NodeMap = malloc(Columns*sizeof(int)); if (!NodeMap) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error performing k-means clustering"), MB_OK); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error performing k-means clustering"), 0); return TRUE; } ifound = ArrayKCluster(kArrays, nArrayTrials, method, dist, NodeMap); if (ifound < 0) ok = 0; if (ok) { wsprintf(buffer, TEXT("Solution was found %d times"), ifound); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)buffer, 0); wsprintf(filetag, TEXT("_K_A%d.kag"), kArrays); outputfile = _tfopen(filename, TEXT("wt")); if (!outputfile) { MessageBox(NULL, TEXT("Error: Unable to open the output file"), TEXT("Error"), 0); free(NodeMap); return TRUE; } ok = SaveArrayKCluster(outputfile, kArrays, NodeMap); fclose(outputfile); } free(NodeMap); if (!ok) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error performing k-means clustering"), MB_OK); wsprintf(buffer, TEXT("Error saving file %s"), filename); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)buffer, 0); return TRUE; } } /* Now write the data file */ if (ClusterGenes && ClusterArrays) wsprintf(filetag, TEXT("_K_G%d_A%d.CDT"), kGenes, kArrays); else if (ClusterGenes) wsprintf(filetag, TEXT("_K_G%d.CDT"), kGenes); else if (ClusterArrays) wsprintf(filetag, TEXT("_K_A%d.CDT"), kArrays); outputfile = _tfopen(filename, TEXT("wt")); if (!outputfile) { MessageBox(NULL, TEXT("Error: Unable to open the output file"), TEXT("Error"), 0); return TRUE; } ok = Save(outputfile, 0, 0); fclose(outputfile); if (ok) SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Done clustering"), 0); else { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error saving file"), 0); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error saving to file"), 0); } return TRUE; } } } } } return FALSE; } BOOL CALLBACK SOMDialogProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { static HWND hGeneMetric; static HWND hArrayMetric; switch (nMsg) { case WM_INITDIALOG: { hGeneMetric = GetDlgItem(hWnd, ID_SOM_GENE_METRIC); hArrayMetric = GetDlgItem(hWnd, ID_SOM_ARRAY_METRIC); if (!hGeneMetric || !hArrayMetric) MessageBox(NULL, TEXT("Program initialization failed"), TEXT("Failed to initialize SOM panel"), MB_OK); else { SetMetrics(hGeneMetric, 'e'); SetMetrics(hArrayMetric, 'e'); } return TRUE; } case IDM_UPDATEINFO: { int Rows = *((int*)wParam); int Columns = *((int*)lParam); int dim = 1 + (int)pow(Rows, 0.25); SetDlgItemInt(hWnd, ID_SOM_GENE_XDIM, dim, FALSE); SetDlgItemInt(hWnd, ID_SOM_GENE_YDIM, dim, FALSE); dim = 1 + (int)pow(Columns, 0.25); SetDlgItemInt(hWnd, ID_SOM_ARRAY_XDIM, dim, FALSE); SetDlgItemInt(hWnd, ID_SOM_ARRAY_YDIM, dim, FALSE); return TRUE; } case WM_COMMAND: { if (HIWORD(wParam)==BN_CLICKED) { switch ((int) LOWORD(wParam)) { case ID_SOM_BUTTON: { const int Rows = GetRows(); const int Columns = GetColumns(); int ok; HWND hTabCtrl = GetParent(hWnd); HWND hWndMain = GetParent(hTabCtrl); TCHAR* jobname; TCHAR* filetag; TCHAR filename[MAX_PATH]; FILE* GeneFile = NULL; FILE* ArrayFile = NULL; FILE* DataFile = NULL; const BOOL ClusterGenes = IsDlgButtonChecked(hWnd, ID_SOM_GENE_XB); const BOOL ClusterArrays = IsDlgButtonChecked(hWnd, ID_SOM_ARRAY_XB); const int GeneXDim = GetDlgItemInt(hWnd, ID_SOM_GENE_XDIM, NULL, FALSE); const int GeneYDim = GetDlgItemInt(hWnd, ID_SOM_GENE_YDIM, NULL, FALSE); const int ArrayXDim = GetDlgItemInt(hWnd, ID_SOM_ARRAY_XDIM, NULL, FALSE); const int ArrayYDim = GetDlgItemInt(hWnd, ID_SOM_ARRAY_YDIM, NULL, FALSE); const int GeneIters = ClusterGenes ? GetDlgItemInt(hWnd, ID_SOM_GENE_ITERS, NULL, FALSE) : 0; const double GeneTau = GetDlgItemDouble(hWnd, ID_SOM_GENE_TAU, NULL); const char GeneMetric = GetMetric(hGeneMetric); const int ArrayIters = ClusterArrays ? GetDlgItemInt(hWnd, ID_SOM_ARRAY_ITERS, 0, FALSE) : 0; const double ArrayTau = GetDlgItemDouble(hWnd, ID_SOM_ARRAY_TAU, NULL); const char ArrayMetric = GetMetric(hArrayMetric); if (!ClusterGenes && !ClusterArrays) return TRUE; /* Nothing to do here */ if (Rows==0 || Columns==0) { SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("No data available"), 0); return TRUE; } SendMessage(hWndMain, IDM_GETJOBNAME, (WPARAM)&jobname, 0); filetag = filename + wsprintf(filename, TEXT("%s_SOM"), jobname); free(jobname); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Calculating Self-Organizing Map"), 0); if (ClusterGenes) filetag += wsprintf(filetag, TEXT("_G%d-%d"), GeneXDim, GeneYDim); if (ClusterArrays) filetag += wsprintf(filetag, TEXT("_A%d-%d"), ArrayXDim, ArrayYDim); wsprintf(filetag, TEXT(".TXT")); DataFile = _tfopen(filename, TEXT("wt")); if (!DataFile) { MessageBox(NULL, TEXT("Error: Unable to open the output file"), TEXT("Error"), 0); return TRUE; } if (ClusterGenes) { if (GeneIters==0 || GeneTau==0 || GeneXDim==0 || GeneYDim==0) { SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error starting SOM: Check options"), 0); fclose(DataFile); return TRUE; } wsprintf(filetag, TEXT(".GNF")); GeneFile = _tfopen(filename, TEXT("wt")); if (!GeneFile) { MessageBox(NULL, TEXT("Error: Unable to open the output file"), TEXT("Error"), 0); fclose(DataFile); return TRUE; } } if (ClusterArrays) { if (ArrayIters==0 || ArrayTau==0 || ArrayXDim==0 || ArrayYDim==0) { SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error starting SOM: Check options"), 0); if (GeneFile) fclose(GeneFile); fclose(DataFile); return TRUE; } wsprintf(filetag, TEXT(".ANF")); ArrayFile = _tfopen(filename, TEXT("wt")); if (!ArrayFile) { MessageBox(NULL, TEXT("Error: Unable to open the output file"), TEXT("Error"), 0); if (GeneFile) fclose(GeneFile); fclose(DataFile); return TRUE; } } ok = PerformSOM(GeneFile, GeneXDim, GeneYDim, GeneIters, GeneTau, GeneMetric, ArrayFile, ArrayXDim, ArrayYDim, ArrayIters, ArrayTau, ArrayMetric); if (GeneFile) fclose(GeneFile); if (ArrayFile) fclose(ArrayFile); if (!ok) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error performing SOM"), MB_OK); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error performing SOM"), 0); return TRUE; } ok = Save(DataFile, 0, 0); fclose(DataFile); if (!ok) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error saving file"), 0); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error saving to file"), 0); return TRUE; } SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Done making SOM"), 0); return TRUE; } } } } } return FALSE; } BOOL CALLBACK PcaDialogProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { switch (nMsg) { case WM_COMMAND: { if (HIWORD(wParam)==BN_CLICKED) { switch ((int) LOWORD(wParam)) { case ID_PCA_BUTTON: { const BOOL DoGenePCA = IsDlgButtonChecked(hWnd, ID_PCA_GENE_XB); const BOOL DoArrayPCA = IsDlgButtonChecked(hWnd, ID_PCA_ARRAY_XB); const char* error; const int Rows = GetRows(); const int Columns = GetColumns(); TCHAR* jobname; TCHAR filename[MAX_PATH]; HWND hTabCtrl = GetParent(hWnd); HWND hWndMain = GetParent(hTabCtrl); FILE* coordinatefile; FILE* pcfile; if (Rows==0 || Columns==0) { SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("No data available"), 0); return TRUE; } SendMessage(hWndMain, IDM_GETJOBNAME, (WPARAM)&jobname, 0); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Calculating PCA"), 0); if (DoGenePCA) { wsprintf(filename, TEXT("%s_pca_gene.coords.txt"), jobname); coordinatefile = _tfopen(filename, TEXT("wt")); wsprintf(filename, TEXT("%s_pca_gene.pc.txt"), jobname); pcfile = _tfopen(filename, TEXT("wt")); if (!coordinatefile || !pcfile) { if (coordinatefile) fclose(coordinatefile); if (pcfile) fclose(pcfile); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error: Unable to open output file"), 0); free(jobname); return TRUE; } error = PerformGenePCA(coordinatefile, pcfile); fclose(coordinatefile); fclose(pcfile); if (error) #ifdef UNICODE { TCHAR buffer[256]; MultiByteToWideChar(CP_ACP, 0, error, -1, buffer, 256); MessageBox(NULL, buffer, TEXT("Error calculating PCA"), MB_OK); #else { MessageBox(NULL, error, TEXT("Error calculating PCA"), MB_OK); #endif free(jobname); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Principal Component Analysis failed"), 0); return TRUE; } } if (DoArrayPCA) { SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Calculating PCA"), 0); wsprintf(filename, TEXT("%s_pca_array.coords.txt"), jobname); coordinatefile = _tfopen(filename, TEXT("wt")); wsprintf(filename, TEXT("%s_pca_array.pc.txt"), jobname); pcfile = _tfopen(filename, TEXT("wt")); if (!coordinatefile || !pcfile) { if (coordinatefile) fclose(coordinatefile); if (pcfile) fclose(pcfile); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error: Unable to open output file"), 0); free(jobname); return TRUE; } error = PerformArrayPCA(coordinatefile, pcfile); fclose(coordinatefile); fclose(pcfile); if (error) #ifdef UNICODE { TCHAR buffer[256]; MultiByteToWideChar(CP_ACP, 0, error, -1, buffer, 256); MessageBox(NULL, buffer, TEXT("Error calculating PCA"), MB_OK); #else { MessageBox(NULL, error, TEXT("Error calculating PCA"), MB_OK); #endif free(jobname); SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Principal Component Analysis failed"), 0); return TRUE; } } SendMessage(hWndMain, IDM_SETSTATUSBAR, (WPARAM)TEXT("Finished Principal Component Analysis"), 0); free(jobname); return TRUE; } } } } } return FALSE; } /*============================================================================*/ /* Callback functions --- Other windows */ /*============================================================================*/ BOOL CALLBACK FileFormatProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HBITMAP hBmp = NULL; switch (uMsg) { case WM_INITDIALOG: { HINSTANCE hInst = GetModuleHandle(NULL); hBmp = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(ID_FILEFORMAT_BMP), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); if (hBmp) SendDlgItemMessage(hwndDlg, ID_FILEFORMAT_BMP_LOCATION, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBmp); return TRUE; } case WM_SYSCOMMAND: if (wParam == SC_CLOSE) { if (hBmp) { DeleteObject(hBmp); hBmp = NULL; } DestroyWindow(hwndDlg); return TRUE; } break; } return FALSE; } BOOL CALLBACK AboutProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_SYSCOMMAND: if (wParam == SC_CLOSE) { DestroyWindow(hwndDlg); return TRUE; } break; } return FALSE; } /*============================================================================*/ /* Callback functions --- Main dialog window */ /*============================================================================*/ BOOL CALLBACK MainDialogProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { static HWND hWndTabCtrl; static HWND hWndPages[6]; static int iCurrentPage = 0; static TCHAR* szHomeDir = NULL; static TCHAR* directory; switch (nMsg) { case WM_INITDIALOG: { /* Variables needed to read registry information */ HKEY hKey; LONG lRet; /* Reserve MAX_PATH bytes for the file name */ DWORD dwSize = MAX_PATH; TCHAR buffer[MAX_PATH]; int n; /* Generic tab page information */ TCITEM tie; /* Get the icon */ HINSTANCE hInst = GetModuleHandle(NULL); HICON hIcon = LoadIcon(hInst, MAKEINTRESOURCE(ID_ICON)); SendMessage(hWnd, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); /* Read directory information from the registry */ lRet = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Stanford\\Cluster\\Directory"), 0, KEY_QUERY_VALUE, &hKey); directory = malloc(dwSize*sizeof(TCHAR)); if (directory) { lRet = RegQueryValueEx(hKey, TEXT("LastOpenDirectory"), NULL, NULL, (LPBYTE)directory, &dwSize); if (lRet==ERROR_MORE_DATA) /* directory was not large enough; dwSize now contains the needed size */ { free(directory); directory = malloc(dwSize*sizeof(TCHAR)); lRet = RegQueryValueEx(hKey, TEXT("LastOpenDirectory"), NULL, NULL, (LPBYTE)directory, &dwSize); } if (lRet!=ERROR_SUCCESS) { free(directory); directory = NULL; } } else MessageBox(NULL, TEXT("Insufficient memory to store the last open directory\n"), TEXT("Error reading last open directory"), MB_OK); RegCloseKey(hKey); /* Get directory information */ GetModuleFileName(NULL, buffer, MAX_PATH); *_tcsrchr(buffer,'\\') = '\0'; n = lstrlen(buffer) + 1; szHomeDir = malloc(n*sizeof(TCHAR)); if (!szHomeDir) MessageBox(NULL, TEXT("Insufficient memory to store the home directory\n"), TEXT("Error saving the path of the home directory"), MB_OK); else _tcscpy(szHomeDir, buffer); /* Create tab pages */ hWndTabCtrl = GetDlgItem(hWnd, ID_TABCTRL); if (!hWndTabCtrl) { MessageBox(NULL, TEXT("Program initialization failed"), TEXT("Failed to initialize tab pages"), MB_OK); return TRUE; } memset(&tie, 0, sizeof(TCITEM)); tie.mask = TCIF_TEXT; tie.pszText = TEXT("Filter Data"); TabCtrl_InsertItem(hWndTabCtrl, 0, &tie); tie.pszText = TEXT("Adjust Data"); TabCtrl_InsertItem(hWndTabCtrl, 1, &tie); tie.pszText = TEXT("Hierarchical"); TabCtrl_InsertItem(hWndTabCtrl, 2, &tie); tie.pszText = TEXT("k-Means"); TabCtrl_InsertItem(hWndTabCtrl, 3, &tie); tie.pszText = TEXT("SOMs"); TabCtrl_InsertItem(hWndTabCtrl, 4, &tie); tie.pszText = TEXT("PCA"); TabCtrl_InsertItem(hWndTabCtrl, 5, &tie); hWndPages[0]= CreateDialog(NULL, MAKEINTRESOURCE(ID_FILTER_TAB), hWndTabCtrl, &FilterDialogProc); hWndPages[1]= CreateDialog(NULL, MAKEINTRESOURCE(ID_ADJUST_TAB), hWndTabCtrl, &AdjustDialogProc); hWndPages[2]= CreateDialog(NULL, MAKEINTRESOURCE(ID_HIERARCHICAL_TAB), hWndTabCtrl, &HierarchicalDialogProc); hWndPages[3]= CreateDialog(NULL, MAKEINTRESOURCE(ID_KMEANS_TAB), hWndTabCtrl, &KmeansDialogProc); hWndPages[4]= CreateDialog(NULL, MAKEINTRESOURCE(ID_SOM_TAB), hWndTabCtrl, &SOMDialogProc); hWndPages[5]= CreateDialog(NULL, MAKEINTRESOURCE(ID_PCA_TAB), hWndTabCtrl, &PcaDialogProc); SetWindowLong(hWndPages[0], GWL_USERDATA, (LONG)ID_FILTER_TAB); SetWindowLong(hWndPages[1], GWL_USERDATA, (LONG)ID_ADJUST_TAB); SetWindowLong(hWndPages[2], GWL_USERDATA, (LONG)ID_HIERARCHICAL_TAB); SetWindowLong(hWndPages[3], GWL_USERDATA, (LONG)ID_KMEANS_TAB); SetWindowLong(hWndPages[4], GWL_USERDATA, (LONG)ID_SOM_TAB); SetWindowLong(hWndPages[5], GWL_USERDATA, (LONG)ID_PCA_TAB); /* Show the dialog */ ShowWindow(hWndPages[iCurrentPage], SW_SHOWNORMAL); return TRUE; } case WM_NOTIFY: { if (lParam) { switch (((NMHDR*)lParam)->code) { case TCN_SELCHANGE: { if (hWndTabCtrl) { ShowWindow(hWndPages[iCurrentPage], SW_HIDE); iCurrentPage = TabCtrl_GetCurSel(hWndTabCtrl); ShowWindow(hWndPages[iCurrentPage], SW_SHOWNORMAL); } return TRUE; } } } return FALSE; } case WM_COMMAND: { switch (LOWORD(wParam)) { case CMD_FILE_OPEN: /* User will select a data file (*.txt) */ { OPENFILENAME ofn; TCHAR lpstrFile[MAX_PATH]; ZeroMemory(&ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWnd; ofn.lpstrFile = lpstrFile; ofn.nMaxFile = MAX_PATH; ofn.lpstrFilter = TEXT("Data (*.txt)\0*.TXT\0All files (*.*)\0*.*\0"); ofn.nFilterIndex = 1; ofn.lpstrTitle = TEXT("Select data file to open"); ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; ofn.lpstrFile[0] = '\0'; SendMessage(hWnd, IDM_SETSTATUSBAR, (WPARAM)TEXT("Opening file"), 0); if (GetOpenFileName(&ofn)) { char* result = NULL; TCHAR buffer[256]; TCHAR* extension; FILE* inputfile = _tfopen(ofn.lpstrFile, TEXT("rt")); /* Save the directory name based on the file name */ SendMessage(hWnd, IDM_SAVEDIR, (WPARAM)ofn.lpstrFile, 0); /* Read file */ if (!inputfile) { MessageBox(NULL, TEXT("Error opening file"), TEXT("Error"), MB_OK); return TRUE; } SetDlgItemText(hWnd, ID_FILEMANAGER_FILEMEMO, TEXT("")); SetDlgItemText(hWnd, ID_FILEMANAGER_JOBNAME, TEXT("")); SetDlgItemText(hWnd, ID_FILEMANAGER_ROWS, TEXT("")); SetDlgItemText(hWnd, ID_FILEMANAGER_COLUMNS, TEXT("")); result = Load(inputfile); fclose(inputfile); if (!result) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error reading file"), MB_OK); wsprintf(buffer, TEXT("Error reading file %s"), ofn.lpstrFile); SendMessage(hWnd, IDM_SETSTATUSBAR, (WPARAM)buffer, 0); return TRUE; } if (strcmp(result, "ok")!=0) { #ifdef UNICODE MultiByteToWideChar(CP_ACP, 0, result, -1, buffer, 256); MessageBox(NULL, buffer, TEXT("Error in data file"), MB_OK); #else MessageBox(NULL, result, TEXT("Error in data file"), MB_OK); #endif free(result); wsprintf(buffer, TEXT("Error reading file %s"), ofn.lpstrFile); SendMessage(hWnd, IDM_SETSTATUSBAR, (WPARAM)buffer, 0); return TRUE; } /* Extract job name from file name */ SendMessage(hWnd, IDM_SETSTATUSBAR, (WPARAM)TEXT("Done loading data"), 0); SendMessage(hWndPages[0], IDM_RESET, 0, 0); SetDlgItemText(hWnd, ID_FILEMANAGER_FILEMEMO, lpstrFile); extension = _tcsrchr(lpstrFile,'.'); if (extension) *extension = '\0'; SetDlgItemText(hWnd, ID_FILEMANAGER_JOBNAME, _tcsrchr(lpstrFile,'\\')+1); SendMessage(hWnd, IDM_UPDATEINFO, 0, 0); } else SendMessage(hWnd, IDM_SETSTATUSBAR, (WPARAM)TEXT("Cancelled"), 0); return TRUE; } case CMD_FILE_SAVE: { int ok; TCHAR lpstrFile[MAX_PATH]; OPENFILENAME ofn; SendMessage(hWnd, IDM_SETSTATUSBAR, (WPARAM)TEXT("Saving data to file"), 0); ZeroMemory(&ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWnd; ofn.nMaxFile = MAX_PATH; ofn.lpstrFile = lpstrFile; ofn.lpstrFilter = TEXT("Text files\0*.TXT\0All files\0*.*\0"); ofn.nFilterIndex = 1; ofn.lpstrInitialDir = directory; ofn.lpstrTitle = TEXT("Select file name to save to"); ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; GetDlgItemText(hWnd, ID_FILEMANAGER_JOBNAME, ofn.lpstrFile, ofn.nMaxFile); lstrcat(ofn.lpstrFile, TEXT(".txt")); if (GetSaveFileName(&ofn)) { /* Save the data to file */ FILE* outputfile; SendMessage(hWnd, IDM_SAVEDIR, (WPARAM)ofn.lpstrFile, 0); outputfile = _tfopen(ofn.lpstrFile, TEXT("wt")); if (!outputfile) { MessageBox(NULL, TEXT("Error: Unable to open the output file"), TEXT("Error"), 0); return TRUE; } ok = Save(outputfile, 0, 0); fclose(outputfile); if (ok) SendMessage(hWnd, IDM_SETSTATUSBAR, (WPARAM)TEXT("Finished saving file"), 0); else { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Error saving file"), 0); SendMessage(hWnd, IDM_SETSTATUSBAR, (WPARAM)TEXT("Error saving to file"), 0); } } else SendMessage(hWnd, IDM_SETSTATUSBAR, (WPARAM)TEXT("Cancelled"), 0); return TRUE; } case CMD_FILE_EXIT: { DestroyWindow(hWnd); return TRUE; } case CMD_HELP_HTMLHELP: { /* Open Windows HTML Help file */ if (!szHomeDir) MessageBox(NULL, TEXT("Home directory is unknown\n"), TEXT("Cannot start Help"), MB_OK); else ShellExecute(hWnd, TEXT("open"), TEXT("cluster.chm"), NULL, szHomeDir, SW_SHOWNORMAL); return TRUE; } case CMD_HELP_MANUAL: { /* Open local manual (PDF file) */ if (!szHomeDir) MessageBox(NULL, TEXT("Home directory is unknown\n"), TEXT("Cannot start Help"), MB_OK); else ShellExecute(hWnd, TEXT("open"), TEXT("doc\\cluster3.pdf"), NULL, szHomeDir, SW_SHOWNORMAL); return TRUE; } case CMD_HELP_DOWNLOAD: { /* Open Cluster Manual in Browser Window */ ShellExecute(hWnd, TEXT("open"), TEXT("http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/manual"), NULL, NULL, SW_SHOWNORMAL); return TRUE; } case CMD_HELP_FILEFORMAT: { HWND hWndFileFormat = CreateDialog(NULL, MAKEINTRESOURCE(ID_FILEFORMAT), hWnd, &FileFormatProc); ShowWindow(hWndFileFormat, SW_SHOWDEFAULT); return TRUE; } case CMD_HELP_ABOUT: { HWND hWndAbout = CreateDialog(NULL, MAKEINTRESOURCE(ID_ABOUT), hWnd, &AboutProc); ShowWindow(hWndAbout, SW_SHOWDEFAULT); return TRUE; } } return FALSE; } case IDM_SAVEDIR: { TCHAR* fullpathfilename = (TCHAR*)wParam; TCHAR* filename = _tcsrchr(fullpathfilename,'\\'); int n = filename - fullpathfilename + 1; if (directory) free(directory); directory = malloc((n+1)*sizeof(TCHAR)); if (!directory) MessageBox(NULL, TEXT("Insufficient memory to store the last open directory\n"), TEXT("Error reading last open directory"), MB_OK); else { _tcsncpy(directory, fullpathfilename, n); directory[n] = '\0'; } return TRUE; } case IDM_GETJOBNAME: { TCHAR buffer[MAX_PATH]; TCHAR* jobname; const int n = GetDlgItemText(hWnd, ID_FILEMANAGER_JOBNAME, buffer, MAX_PATH); if (n==0) { MessageBox(NULL, TEXT("Please specify a job name"), TEXT("Error starting calculation"), MB_OK); return TRUE; } jobname = malloc((n+1)*lstrlen(buffer)*sizeof(TCHAR)); /* One more for the terminating \0 */ if (!jobname) { MessageBox(NULL, TEXT("Insufficient memory"), TEXT("Failed to save job name"), MB_OK); return TRUE; } lstrcpy(jobname, buffer); *(TCHAR**)wParam = jobname; return TRUE; } case IDM_UPDATEINFO: { const int Rows = GetRows(); const int Columns = GetColumns(); SetDlgItemInt(hWnd, ID_FILEMANAGER_ROWS, Rows, FALSE); SetDlgItemInt(hWnd, ID_FILEMANAGER_COLUMNS, Columns, FALSE); /* Update SOM defaults to reflect new number of rows */ SendMessage(hWndPages[4], IDM_UPDATEINFO, (WPARAM)&Rows, (LPARAM)&Columns); return TRUE; } case IDM_SETSTATUSBAR: { HWND hWndStatusBar = GetDlgItem(hWnd, ID_STATUSBAR); if (hWndStatusBar) SetWindowText(hWndStatusBar, (TCHAR*)wParam); return TRUE; } case WM_DESTROY: { /* Write directory information to the registry */ if (directory) { HKEY hKey; LONG lRet; lRet = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Stanford\\Cluster\\Directory"), 0, KEY_SET_VALUE, &hKey); if (lRet==ERROR_SUCCESS) { DWORD dwSize = lstrlen(directory)+1; /* One more for the terminating \0 */ RegSetValueEx(hKey, TEXT("LastOpenDirectory"), 0, REG_SZ, (LPBYTE)directory, dwSize); RegCloseKey(hKey); } free(directory); } if (szHomeDir) free(szHomeDir); Free(); PostQuitMessage((int)wParam); } case WM_CLOSE: { return EndDialog(hWnd, 0); } } return FALSE; } /*============================================================================*/ /* Main */ /*============================================================================*/ int STDCALL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) { /* Show the main window */ return DialogBox(hInst, MAKEINTRESOURCE(ID_MAINDIALOG), NULL, &MainDialogProc); } cluster-1.52a/windows/cluster.ico0000644000100500010050000000137607472152300016767 0ustar mdehoonmdehoon è( @€€€€€€€€€€€€€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÌÌÌÌÌÌÌÌÌÌÌÌÌÌË»ÌÌÌÌÌÌÌÌÌÌÌÌÌ»»ÌÌÌÌÌÌÌÌÌÌÌÌÌ̼˻ÌÌÌÌÌ»»»»»»»»¼ÌÌÌÌÌÌ̼ÌÌÌÌÌÌ̼̻ÌÌÌÌ̼ÌÌÌÌÌÌÌ»»¼ÌÌÌÌ̼ÌÌÌÌÌÌÌÌÌ»ÌÌ»»»¼ÌÌÌÌÌÌÌÌÌÌÌ̼Ì̼ÌÌÌÌÌÌÌÌË»Ì̼Ì̼˻»»»»»»»ÌÌ̼Ì̼ËÌÌÌÌÌÌÌË»Ì̼ÌÌ»»ÌÌÌÌÌÌÌÌÌÌ̼ÌÌÌËÌÌÌÌÌÌÌ»»Ì̼ÌÌÌËÌÌÌÌË»»¼ÌÌ̼ÌÌÌË»»»»»ÌÌ»»Ì̼ÌÌÌÌÌÌÌÌËÌÌÌÌ»»¼ÌÌÌÌÌÌÌÌË»»»»Ì̼ÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̼ÌÌÌÌÌÌÌÌÌË»»»Ì̼ÌÌÌÌÌÌÌÌÌËÌÌÌÌ̼ÌÌÌÌÌ»»»»»ÌÌ»Ì̼ÌÌÌÌ̼ÌÌÌË»»¼Ì̼ÌÌÌÌ̼ÌÌÌÌÌÌ»Ì̼ÌÌÌÌ̼ÌÌÌÌÌÌÌÌÌ»»»»»»¼ÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̼ÌÌÌÌÌË»ÌÌÌÌÌÌÌ̼ÌË»»»»ÌÌÌÌÌÌÌÌ̼ÌËÌÌÌË»ÌÌÌÌÌÌÌÌ»»»ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌËÌÌË»»ÌÌÌÌÌÌÌÌÌÌË»»»ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌË»»cluster-1.52a/windows/format.bmp0000644000100500010050000014153607521011762016606 0ustar mdehoonmdehoonBM^Ãv(a¢耀€€€€€€€€€€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpwwwwwwwwwwwwwˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆŠªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªˆ€ˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆ‡ÿÿù™Ÿÿù™™™ÿŸÿÿŸù™™™ÿ™™ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿÿŸÿùÿùÿÿÿÿŸÿùŸùÿÿÿùÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸÿŸŸùÿÿÿùÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸÿŸŸùÿÿÿùÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿùÿù™ŸùÿÿÿÿŸùÿŸùÿÿÿùŸÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆ‡ÿùÿÿÿÿù™™™ÿŸùÿŸù™™™ùù™ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿùÿÿÿÿùÿÿÿÿŸŸÿŸùÿÿÿùÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸŸÿŸùÿÿÿùÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿÿŸÿùÿùÿÿÿÿ™ÿÿŸùÿÿÿùÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆ‡ÿÿù™Ÿÿù™™™ÿŸÿÿŸù™™™ÿ™™ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpwwwwwwwwwwwwwˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆŠªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªˆ€ˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿù™Ÿÿù™™™ÿŸÿÿŸù™™™ÿ™™ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿŸÿùÿùÿÿÿÿŸÿùŸùÿÿÿùÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸÿŸŸùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆ€ˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸÿŸŸùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆ€ˆˆˆˆˆˆ‡ÿùÿù™ŸùÿÿÿÿŸùÿŸùÿÿÿùÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùÿÿÿÿù™™™ÿŸùÿŸù™™™ù™™ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùÿÿÿÿùÿÿÿÿŸŸÿŸùÿÿÿùÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆ€ˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸŸÿŸùÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆ€ˆˆˆˆˆ‡ÿÿŸÿùÿùÿÿÿÿ™ÿÿŸùÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆ‡ÿÿù™Ÿÿù™™™ÿŸÿÿŸù™™™ÿ™™Ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpwwwwwwwwwwwwwˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆŠªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªˆ€ˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆ‡ÿÿù™Ÿÿù™™™ÿŸÿÿŸù™™™ÿÿùÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿÿŸÿùÿùÿÿÿÿŸÿùŸùÿÿÿÿÿùÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸÿŸŸùÿÿÿù™™Ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸÿŸŸùÿÿÿÿŸùÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿúª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆ‡ÿùÿù™ŸùÿÿÿÿŸùÿŸùÿÿÿÿŸùÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿúª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€€ˆˆˆˆˆ‡ÿùÿÿÿÿù™™™ÿŸùÿŸù™™™ÿùùÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆˆ‡ÿùÿÿÿÿùÿÿÿÿŸŸÿŸùÿÿÿÿùùÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸŸÿŸùÿÿÿÿÿ™ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿÿŸÿùÿùÿÿÿÿ™ÿÿŸùÿÿÿÿÿ™ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆ‡ÿÿù™Ÿÿù™™™ÿŸÿÿŸù™™™ÿÿùÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpwwwwwwwwwwwwwˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆŠªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªˆ€ˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆ‡ÿÿù™Ÿÿù™™™ÿŸÿÿŸù™™™ÿ™™ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿÿŸÿùÿùÿÿÿÿŸÿùŸùÿÿÿùÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿðÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸÿŸŸùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸÿŸŸùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿùÿù™ŸùÿÿÿÿŸùÿŸùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆ‡ÿùÿÿÿÿù™™™ÿŸùÿŸù™™™ÿù™ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆˆ‡ÿùÿÿÿÿùÿÿÿÿŸŸÿŸùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸŸÿŸùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿŸÿùÿùÿÿÿÿ™ÿÿŸùÿÿÿùÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆ‡ÿÿù™Ÿÿù™™™ÿŸÿÿŸù™™™ÿ™™ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpwwwwwwwwwwwwwˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆŠªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªˆ€ˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆ€ˆˆˆˆˆ‡ÿÿù™Ÿÿù™™™ÿŸÿÿŸù™™™ù™™Ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆ€ˆˆˆˆˆ‡ÿÿŸÿùÿùÿÿÿÿŸÿùŸùÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿðÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿúª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸÿŸŸùÿÿÿÿùÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆ€ˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸÿŸŸùÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿúª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆ€ˆˆˆˆˆ‡ÿùÿù™ŸùÿÿÿÿŸùÿŸùÿÿÿÿÿùÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆ€€ˆˆˆˆˆ‡ÿùÿÿÿÿù™™™ÿŸùÿŸù™™™ÿÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆ€€ˆˆˆˆˆ‡ÿùÿÿÿÿùÿÿÿÿŸŸÿŸùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸŸÿŸùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿŸÿùÿùÿÿÿÿ™ÿÿŸùÿÿÿùÿÿŸÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆ€ˆˆˆˆˆ‡ÿÿù™Ÿÿù™™™ÿŸÿÿŸù™™™ÿ™™ÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿúª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpwwwwwwwwwwwwwˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆŠªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªˆ€ˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆ‡ÿÿù™Ÿÿù™™™ÿŸÿÿŸù™™™ÿÿŸÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿúª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªª ª ªªª ª ª ªªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿÿŸÿùÿùÿÿÿÿŸÿùŸùÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿðÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿúª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªª ªª  ªªª ª ª ªªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸÿŸŸùÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿúª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªª ªª ª ªª ª ªª ªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸÿŸŸùÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿúª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªª ªª ª ª ªª ªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùÿù™ŸùÿÿÿÿŸùÿŸùÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿúª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆ€ˆˆˆˆˆ‡ÿùÿÿÿÿù™™™ÿŸùÿŸù™™™ÿÿŸÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿúª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªª ªª ª ª ªª ªª ª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùÿÿÿÿùÿÿÿÿŸŸÿŸùÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùÿÿÿŸùÿÿÿÿŸŸÿŸùÿÿÿÿŸŸÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿððÿÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿÿŸÿùÿùÿÿÿÿ™ÿÿŸùÿÿÿÿùŸÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªª ªª ªª ªª ªªª ªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆ‡ÿÿù™Ÿÿù™™™ÿŸÿÿŸù™™™ÿÿŸÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿúª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªª ªªª ªª ª ªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿðˆpwwwwwwwwwwwwwˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆŠªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªˆ€ˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆ€ˆˆˆˆ‡ÿðÿÿÿÿÿÿÿÿðÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿðÿÿÿÿÿÿÿÿÿðÿÿÿðÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿðˆpˆˆˆˆˆ€ˆˆˆˆˆˆ‡ÿðÿÿÿÿÿÿÿÿÿÿÿÿÿðÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿðÿÿððÿÿÿÿÿÿÿÿÿðÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿðˆpˆˆˆˆˆˆ€ˆˆˆˆˆ‡ÿðÿÿððÿÿÿÿÿÿÿÿðÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿðððÿÿÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿðÿÿððÿÿÿÿÿÿÿÿÿÿðÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿðÿÿððÿÿÿÿÿÿÿÿÿÿÿðÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿððÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿððÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿððÿÿøÿðˆpˆˆˆˆ€ˆˆˆˆˆˆ‡ÿðÿÿÿðÿðÿÿÿÿðÿÿÿðÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆ‡ÿðÿðÿðÿÿÿÿÿðøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpwwwwwwwwwwwwwˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿ™™Ÿÿ™ÿùŸùŸÿù™™ÿùŸù™™ÿÿÿÿÿÿÿÿÿøÿðÿðÿÿððÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿðÿÿÿÿÿÿÿÿÿðÿðøÿÿðÿÿðÿðÿðÿððÿðÿÿøÿù™™™ùÿÿùùÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿù™™™ùÿÿùùÿÿÿù™™Ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿù™™™ùÿÿùùÿÿÿÿ™™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿù™™™ùÿÿùùÿÿÿÿÿùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿù™™™ùÿÿùùÿÿÿÿ™™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùŸÿ™ÿ™ÿùŸùŸÿ™ÿ™ÿùŸùŸùŸÿÿÿÿÿÿÿÿøÿðÿðÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿðÿÿÿÿÿÿÿðÿÿÿðÿðøÿÿÿðÿÿÿðÿÿÿÿðÿÿðÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿÿùÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿÿÿÿùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿÿùÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùŸÿ™ÿ™ÿ™ŸùŸùŸùùŸùŸùŸÿ™ÿÿÿÿÿÿÿÿøÿððÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðÿðÿÿÿÿÿÿÿÿÿÿÿðÿðøÿðÿððÿððÿÿÿððÿÿðÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿÿÿùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿÿù™™ŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùŸÿ™ÿ™ÿ™ŸùŸùŸÿùŸùŸùŸÿ™ÿÿÿÿÿÿÿÿøÿððÿÿððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðÿðððÿÿÿÿÿÿÿÿÿðÿðøÿðÿððÿðððÿÿððÿÿððÿÿÿøÿùÿÿÿÿùùÿùÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿùùÿùÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿùùÿùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿùùÿùÿÿÿÿŸùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿùùÿùÿÿÿÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùŸÿ™ÿ™ù™ŸùŸùŸÿùŸùŸùŸÿ™ÿÿÿÿÿÿÿÿøÿðÿÿððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿððððÿÿÿÿÿÿÿÿðÿðøÿðððÿððÿÿððÿÿðÿÿÿøÿùÿÿÿÿÿŸÿù™™ŸÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿÿŸÿù™™ŸÿÿùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿÿŸÿù™™ŸÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿÿŸÿù™™ŸÿŸùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿÿŸÿù™™ŸùÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùŸÿ™ÿ™ùùŸùŸùŸÿùŸùŸùŸÿ™ÿÿÿÿÿÿÿÿøÿðÿðÿðÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðÿÿÿððÿÿÿÿÿÿÿÿðøÿðÿÿÿðÿððÿÿÿðððÿÿÿÿøÿù™™™ÿÿŸÿùÿÿùÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿù™™™ÿÿŸÿùÿÿùÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿù™™™ÿÿŸÿùÿÿùÿù™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿù™™™ÿÿŸÿùÿÿùÿùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿù™™™ÿÿŸÿùÿÿùù™™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùŸÿ™ÿ™™ùŸùŸùŸÿùŸùŸùŸÿ™ÿÿÿÿÿÿÿÿøÿðÿðÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðÿÿÿððÿÿÿÿÿÿÿÿÿÿðÿðøÿðÿÿÿðÿððÿÿÿððÿÿðÿÿÿÿøÿùÿÿÿÿùùÿùÿÿùÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿùùÿùÿÿùÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿùùÿùÿÿùÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿùùÿùÿÿùÿùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿùùÿùÿÿùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆ‡ÿùŸÿ™ÿ™ŸùŸùŸùŸÿùŸùŸùŸÿ™ÿÿÿÿÿÿÿÿøÿðÿÿðÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðÿÿÿððÿÿÿÿÿÿÿÿÿÿÿðÿðøÿðÿÿÿðÿððÿÿÿððÿÿðÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿùÿŸŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿùÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿùÿÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿùÿÿ™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿùÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆ€ˆˆˆˆˆ‡ÿùŸÿ™ÿ™ŸùŸùŸÿ™ÿ™ÿùŸùŸùŸÿÿÿÿÿÿÿÿøÿðÿÿÿÿðÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿðÿðÿðÿÿÿÿðÿÿÿðÿðøÿÿÿðÿÿÿðÿÿÿÿðÿÿðÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿùÿùŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿùùÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿùùÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿùÿÿ™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿÿÿÿŸÿŸùÿÿùÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆ‡ÿùŸÿ™ÿ™ÿùŸùŸÿù™ŸÿùŸù™™ÿÿÿÿÿÿÿÿÿøÿðÿÿÿÿðÿðÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿðÿÿðÿðÿÿÿÿÿðÿÿðÿÿðÿðÿÿððÿÿÿøÿù™™™ùÿÿùù™™ŸÿÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿù™™™ùÿÿùù™™Ÿÿ™™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿù™™™ùÿÿùù™™Ÿÿ™™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿù™™™ùÿÿùù™™Ÿÿÿùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿù™™™ùÿÿùù™™Ÿÿ™™Ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpˆˆˆˆˆˆˆˆˆˆˆˆ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿðˆpwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwpˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpøˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpÿÿÿÿÿÿÿÿÿÿÿÿ÷øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡øˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡ø€ˆpˆwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwpˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ€cluster-1.52a/windows/cluster.iss0000644000100500010050000000437110762213614017013 0ustar mdehoonmdehoon; -- cluster.iss -- ; The installer script for Cluster 3.0. ; Michiel de Hoon, 2002.06.15 [Setup] AppName=Cluster AppVerName=Cluster 3.0 AppCopyright=Copyright (C) 2004 Michiel de Hoon OutputBaseFilename=clustersetup DefaultDirName={pf}\Stanford University\ DefaultGroupName=Cluster UninstallDisplayIcon= AppPublisher=Michiel de Hoon, University of Tokyo AppPublisherURL=http://bonsai.ims.u-tokyo.ac.jp/~mdehoon AppVersion=3.0 OutputDir=. ; uncomment the following line if you want your installation to run on NT 3.51 too. ; MinVersion=4,3.51 [Files] Source: "cluster.exe"; DestDir: "{app}\Cluster 3.0"; MinVersion: 0, 1 ; Windows NT, 2000, XP Source: "clust95.exe"; DestDir: "{app}\Cluster 3.0"; DestName: "cluster.exe"; MinVersion: 1, 0 ; WIndows 95, 98, Me Source: "cluster.com"; DestDir: "{app}\Cluster 3.0"; MinVersion: 0, 1 ; Windows NT, 2000, XP Source: "clust95.com"; DestDir: "{app}\Cluster 3.0"; DestName: "cluster.com"; MinVersion: 1, 0 ; WIndows 95, 98, Me Source: "cluster.dll"; DestDir: "{app}\Cluster 3.0" Source: "../doc/cluster3.pdf"; DestDir: "{app}\Cluster 3.0\doc" Source: "cluster.chm"; DestDir: "{app}\Cluster 3.0" [Icons] Name: "{group}\Cluster 3.0"; Filename: "{app}\Cluster 3.0\cluster.exe" [Registry] Root: HKCU; Subkey: "Software\Stanford\Cluster\Home"; Flags: createvalueifdoesntexist; ValueType: string; ValueName: ClusterDirectory; ValueData: {app} Root: HKCU; Subkey: "Software\Stanford\Cluster\Directory"; Flags: createvalueifdoesntexist; ValueType: string; ValueName: LastOpenDirectory; ValueData: {app} Root: HKCU; Subkey: "Software\Stanford\Cluster\WeightSettings"; Flags: createvalueifdoesntexist; ValueType: binary; ValueName: ArrayWeightCutoff; ValueData: "9A 99 99 99 99 B9 3F" Root: HKCU; Subkey: "Software\Stanford\Cluster\WeightSettings"; Flags: createvalueifdoesntexist; ValueType: binary; ValueName: ArrayWeightExp; ValueData: "00 00 00 00 00 F0 3F" Root: HKCU; Subkey: "Software\Stanford\Cluster\WeightSettings"; Flags: createvalueifdoesntexist; ValueType: binary; ValueName: GeneWeightCutoff; ValueData: "9A 99 99 99 99 B9 3F" Root: HKCU; Subkey: "Software\Stanford\Cluster\WeightSettings"; Flags: createvalueifdoesntexist; ValueType: binary; ValueName: GeneWeightExp; ValueData: "00 00 00 00 00 F0 3F" cluster-1.52a/windows/main.c0000644000100500010050000000513311207455524015702 0ustar mdehoonmdehoon/* The C clustering library. * Copyright (C) 2002 Michiel Jan Laurens de Hoon. * * This library was written at the Laboratory of DNA Information Analysis, * Human Genome Center, Institute of Medical Science, University of Tokyo, * 4-6-1 Shirokanedai, Minato-ku, Tokyo 108-8639, Japan. * Contact: mdehoon 'AT' gsc.riken.jp * * Permission to use, copy, modify, and distribute this software and its * documentation with or without modifications and for any purpose and * without fee is hereby granted, provided that any copyright notices * appear in all copies and that both those copyright notices and this * permission notice appear in supporting documentation, and that the * names of the contributors or copyright holders not be used in * advertising or publicity pertaining to distribution of the software * without specific prior permission. * * THE CONTRIBUTORS AND COPYRIGHT HOLDERS OF THIS SOFTWARE DISCLAIM ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE * OR PERFORMANCE OF THIS SOFTWARE. * */ /* If the user specified any command-line parameters, we run the command-line * version of Cluster 3.0. If not, we run the GUI version of Cluster 3.0, if * available. */ #include "command.h" #ifdef UNICODE #define _UNICODE #endif #include "stdlib.h" #include "windows.h" #include "tchar.h" int main(int argc, const char* argv[]) { if (argc <= 1) { /* Invoked without command-line arguments: start the GUI. */ int result; TCHAR* p; TCHAR szHomeDir[MAX_PATH]; GetModuleFileName(NULL, szHomeDir, MAX_PATH); p = _tcsrchr(szHomeDir,'\\'); *p = '\0'; result = (int) ShellExecute(NULL, TEXT("open"), TEXT("cluster.exe"), 0, szHomeDir, SW_SHOWNORMAL); if (result > 32) return 0; /* GUI started */ if (result==ERROR_FILE_NOT_FOUND) MessageBox(NULL, TEXT("Unable to find cluster.exe"), TEXT("Error"), 0); else MessageBox(NULL, TEXT("Unknown error"), TEXT("Error"), 0); return 1; } return commandmain(argc, argv); } cluster-1.52a/windows/resources.h0000644000100500010050000000627511353766415017013 0ustar mdehoonmdehoon#define ID_ICON 1 #define ID_MENU 100 #define ID_FILEMANAGER 200 #define ID_FILEMANAGER_FILEMEMO 201 #define ID_FILEMANAGER_JOBNAME 202 #define ID_FILEMANAGER_ROWS 203 #define ID_FILEMANAGER_COLUMNS 204 #define ID_FILTER 300 #define ID_FILTER_TAB 301 #define ID_FILTER_PERCENT_XB 302 #define ID_FILTER_PERCENT 303 #define ID_FILTER_STD_XB 304 #define ID_FILTER_STD 305 #define ID_FILTER_OBSERVATION_XB 306 #define ID_FILTER_NUMBER 307 #define ID_FILTER_OBSERVATION_VALUE 308 #define ID_FILTER_MAXMIN_XB 309 #define ID_FILTER_MAXMIN 310 #define ID_FILTER_APPLY 311 #define ID_FILTER_RESULT 312 #define ID_FILTER_ACCEPT 313 #define ID_ADJUST_TAB 400 #define ID_ADJUST_LOG_XB 401 #define ID_ADJUST_CENTER_GENES_XB 402 #define ID_ADJUST_MEAN_GENES 403 #define ID_ADJUST_MEDIAN_GENES 404 #define ID_ADJUST_CENTER_ARRAYS_XB 405 #define ID_ADJUST_MEAN_ARRAYS 406 #define ID_ADJUST_MEDIAN_ARRAYS 407 #define ID_ADJUST_NORMALIZE_GENES 408 #define ID_ADJUST_NORMALIZE_ARRAYS 409 #define ID_ADJUST_APPLY 410 #define ID_HIERARCHICAL_TAB 500 #define ID_HIERARCHICAL_GENE_XB 501 #define ID_HIERARCHICAL_GENE_WEIGHT 502 #define ID_HIERARCHICAL_GENE_WEIGHT_XB 503 #define ID_HIERARCHICAL_GENE_METRIC 504 #define ID_HIERARCHICAL_GENE_EXP 505 #define ID_HIERARCHICAL_GENE_CUTOFF 506 #define ID_HIERARCHICAL_ARRAY_XB 507 #define ID_HIERARCHICAL_ARRAY_WEIGHT 508 #define ID_HIERARCHICAL_ARRAY_WEIGHT_XB 509 #define ID_HIERARCHICAL_ARRAY_METRIC 510 #define ID_HIERARCHICAL_ARRAY_EXP 511 #define ID_HIERARCHICAL_ARRAY_CUTOFF 512 #define ID_HIERARCHICAL_CENTROID 513 #define ID_HIERARCHICAL_SINGLE 514 #define ID_HIERARCHICAL_COMPLETE 515 #define ID_HIERARCHICAL_AVERAGE 516 #define ID_KMEANS_TAB 600 #define ID_KMEANS_GENE_XB 601 #define ID_KMEANS_GENE_K 602 #define ID_KMEANS_GENE_RUNS 603 #define ID_KMEANS_GENE_MEAN 604 #define ID_KMEANS_GENE_MEDIAN 605 #define ID_KMEANS_GENE_METRIC 606 #define ID_KMEANS_ARRAY_XB 607 #define ID_KMEANS_ARRAY_K 608 #define ID_KMEANS_ARRAY_RUNS 609 #define ID_KMEANS_ARRAY_MEAN 610 #define ID_KMEANS_ARRAY_MEDIAN 611 #define ID_KMEANS_ARRAY_METRIC 612 #define ID_KMEANS_BUTTON 613 #define ID_SOM_TAB 700 #define ID_SOM_GENE_XB 701 #define ID_SOM_GENE_XDIM 702 #define ID_SOM_GENE_YDIM 703 #define ID_SOM_GENE_ITERS 704 #define ID_SOM_GENE_TAU 705 #define ID_SOM_GENE_METRIC 706 #define ID_SOM_ARRAY_XB 707 #define ID_SOM_ARRAY_XDIM 708 #define ID_SOM_ARRAY_YDIM 709 #define ID_SOM_ARRAY_ITERS 710 #define ID_SOM_ARRAY_TAU 711 #define ID_SOM_ARRAY_METRIC 712 #define ID_SOM_BUTTON 713 #define ID_PCA_TAB 800 #define ID_PCA_GENE_XB 801 #define ID_PCA_ARRAY_XB 802 #define ID_PCA_BUTTON 803 #define ID_STATUSBAR 900 #define ID_MAINDIALOG 1000 #define CMD_FILE_OPEN 1001 #define CMD_FILE_SAVE 1002 #define CMD_FILE_EXIT 1003 #define CMD_HELP_HTMLHELP 1021 #define CMD_HELP_MANUAL 1022 #define CMD_HELP_DOWNLOAD 1023 #define CMD_HELP_FILEFORMAT 1024 #define CMD_HELP_ABOUT 1025 #define ID_TABCTRL 2000 #define ID_TABPAGE 2001 #define ID_ABOUT 3000 #define ID_FILEFORMAT 5000 #define ID_FILEFORMAT_BMP 5001 #define ID_FILEFORMAT_BMP_LOCATION 5002 #define IDM_SAVEDIR WM_USER+1 #define IDM_GETJOBNAME WM_USER+2 #define IDM_UPDATEINFO WM_USER+3 #define IDM_RESET WM_USER+4 #define IDM_SETSTATUSBAR WM_USER+5 #define IDM_HIERARCHICAL_EXECUTE WM_USER+6 cluster-1.52a/windows/cluster.hhp0000644000100500010050000000112207550723306016770 0ustar mdehoonmdehoon[OPTIONS] Auto TOC=9 Compatibility=1.1 or later Compiled file=cluster.chm Default Window=Default Default topic=..\html\index.html Display compile progress=No Full-text search=Yes Language=0x409 English (United States) Title=Cluster 3.0 Help [WINDOWS] Default="Cluster 3.0 Help",,,"..\html\index.html","..\html\index.html",,,,,0x62420,,0x3046,[271,372,593,566],0x30000,0x20200,,,,,0 [FILES] ..\html\Bibliography.html ..\html\Cluster.html ..\html\Contents.html ..\html\index.html ..\html\Introduction.html ..\html\Development.html ..\html\TreeView.html [INFOTYPES] cluster-1.52a/windows/Makefile0000644000100500010050000000421511571564751016261 0ustar mdehoonmdehoonOPTIONS = -DWINDOWS -DHAVE_GUI SRCDIR = ../src DOCDIR = ../doc HTMLDIR = ../html all: cluster.com clust95.com cluster.exe clust95.exe cluster.chm \ $(DOCDIR)/cluster3.pdf cluster.com: main.o command.o cluster.dll gcc -Wall -mconsole -O4 main.o command.o -L. -lcluster \ -o cluster.com clust95.com: main95.o command.o cluster.dll gcc -Wall -mconsole -O4 main95.o command.o -L. -lcluster \ -o clust95.com cluster.exe: gui.o resources.o cluster.dll gcc -Wall -mwindows -O4 \ gui.o resources.o -L. -lcluster -o cluster.exe clust95.exe: gui95.o resources.o cluster.dll gcc -Wall -mwindows -O4 \ gui95.o resources.o -L. -lcluster -o clust95.exe main.o: main.c gcc -mconsole -Wall -fno-strict-aliasing -c -O4 \ $(OPTIONS) -DUNICODE -I$(SRCDIR) main.c -o main.o main95.o: main.c gcc -mconsole -Wall -fno-strict-aliasing -c -O4 \ $(OPTIONS) -I$(SRCDIR) main.c -o main95.o gui.o: gui.c $(SRCDIR)/cluster.h gcc -mwindows -Wall -fno-strict-aliasing -c -O4 \ $(OPTIONS) -DUNICODE -I$(SRCDIR) gui.c gui95.o: gui.c $(SRCDIR)/cluster.h gcc -mwindows -Wall -fno-strict-aliasing -c -O4 \ $(OPTIONS) -I$(SRCDIR) gui.c -o gui95.o resources.o: resources.rc $(SRCDIR)/cluster.h windres -I$(SRCDIR) -i resources.rc -o resources.o data.o: $(SRCDIR)/data.c gcc -mwindows -Wall -c -O4 $(OPTIONS) $(SRCDIR)/data.c command.o: $(SRCDIR)/command.c gcc -mwindows -Wall -c -O4 $(OPTIONS) $(SRCDIR)/command.c cluster.dll: cluster.o data.o gcc -Wall -O4 -shared -o cluster.dll -Wl,--export-all-symbols \ -L. cluster.o data.o cluster.o: $(SRCDIR)/cluster.c gcc -c -O4 -Wall $(OPTIONS) $(SRCDIR)/cluster.c clustersetup.exe: cluster.dll cluster.exe $(DOCDIR)/cluster3.pdf cluster.chm \ cluster.iss strip cluster.exe strip cluster.dll iscc cluster.iss $(HTMLDIR)/index.html: $(DOCDIR)/cluster3.texinfo $(MAKE) -C $(HTMLDIR) cluster.chm: cluster.hhp $(HTMLDIR)/index.html mv cluster.hhp $(HTMLDIR) cd $(HTMLDIR) -hhc $(HTMLDIR)/cluster.hhp mv $(HTMLDIR)/cluster.chm $(HTMLDIR)/cluster.hhp ../windows rm $(HTMLDIR)/toc.hhc cd ../windows $(DOCDIR)/cluster3.pdf: $(DOCDIR)/cluster3.texinfo $(MAKE) -C $(DOCDIR) clean: rm -f *.o *.a *.dll *.exe *.chm *.hhc cluster-1.52a/html/0000755000100500010050000000000012177164025014062 5ustar mdehoonmdehooncluster-1.52a/html/Distance.html0000644000100500010050000004074611505777254016525 0ustar mdehoonmdehoon Distance - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Next: , Previous: Data, Up: Top


3 Distance/Similarity measures

The first choice that must be made is how similarity (or alternatively, distance) between gene expression data is to be defined. There are many ways to compute how similar two series of numbers are. Cluster provides eight options.

3.1 Distance measures based on the Pearson correlation

The most commonly used similarity metrics are based on Pearson correlation. The Pearson correlation coefficient between any two series of numbers x = {x1, x2, ..., xn} and y = {y1, y2, ..., yn} is defined as

r =
1
n
n

i = 1
(
xi - x
σx
) (
yi - y
σy
)

where x is the average of values in x and σx is the standard deviation of these values.

There are many ways of conceptualizing the correlation coefficient. If you were to make a scatterplot of the values of x against y (pairing x1 with y1, x2 with y2, etc), then r reports how well you can fit a line to the values.

The simplest way to think about the correlation coefficient is to plot x and y as curves, with r telling you how similar the shapes of the two curves are. The Pearson correlation coefficient is always between -1 and 1, with 1 meaning that the two series are identical, 0 meaning they are completely uncorrelated, and -1 meaning they are perfect opposites. The correlation coefficient is invariant under linear transformation of the data. That is, if you multiply all the values in y by 2, or add 7 to all the values in y, the correlation between x and y will be unchanged. Thus, two curves that have identical shape, but different magnitude, will still have a correlation of 1.

Cluster actually uses four different flavors of the Pearson correlation. The textbook Pearson correlation coefficient, given by the formula above, is used if you select Correlation (centered) in the Similarity Metric dialog box. Correlation (uncentered) uses the following modified equations:

r =
1
n
n

i = 1
(
xi
σx(0)
) (
yi
σy(0)
)

in which
σx(0) = (
1
n
n

i = 1
xi2 )
σy(0) = (
1
n
n

i = 1
yi2 )

This is basically the same function, except that it assumes the mean is 0, even when it is not. The difference is that, if you have two vectors x and y with identical shape, but which are offset relative to each other by a fixed value, they will have a standard Pearson correlation (centered correlation) of 1 but will not have an uncentered correlation of 1. The uncentered correlation is equal to the cosine of the angle of two n-dimensional vectors x and y, each representing a vector in n-dimensional space that passes through the origin. Cluster provides two similarity metrics that are the absolute value of these two correlation functions, which consider two items to be similar if they have opposite expression patterns; the standard correlation coefficients consider opposite genes to be very distant.

3.2 Non-parametric distance measures

The Spearman rank correlation and Kendall's τ are two additional metrics, which are non-parametric versions of the Pearson correlation coefficient. These methods are more robust against outliers.

The Spearman rank correlation calculates the correlation between the ranks of the data values in the two vectors. For example, if we have two data vectors

x = {2.3, 6.7, 4.5, 20.8};
y = {2.1, 5.9, 4.4, 4.2},
then we first replace them by their ranks:
x = {1, 3, 2, 4};
y = {1, 4, 3, 2}.
Now we calculate the correlation coefficient in their usual manner from these data vectors, resulting in
rSpearman = 0.4.
In comparison, the regular Pearson correlation between these data is r = 0.2344. By replacing the data values by their ranks, we reduced the effect of the outlier 20.8 on the value of the correlation coefficient. The Spearman rank correlation can be used as a test statistic for independence between x and y. For more information, see Conover (1980).

Kendall's τ goes a step further by using only the relative ordering of x and y to calculate the correlation (Snedecor & Cochran). To calculate Kendall's τ, consider all pairs of data points (xi, yi) and (xj, yj). We call a pair concordant if

  • xi < xj and yi < yj; or
  • xi > xj and yi > yj,
and discordant if
  • xi < xj and yi > yj; or
  • xi > xj and yi < yj.
We can represent this by a table:
- (2.3, 2.1) (6.7, 5.9) (4.5, 4.4) (20.8, 4.2)
(2.3, 2.1) - << << <<
(6.7, 5.9) >> - >> <>
(4.5, 4.4) >> << - <>
(20.8, 4.2) >> >< >< -
From this table, we find that there are four concordant pairs and two discordant pairs:
nc = 4;
nd = 2.
Kendall's τ is calculated as
τ =
nc-nd
n(n-1)/2
,
which in this case evaluates as 0.33. In the C Clustering Library, the calculation of Kendall's τ is corrected for the possibility that two ranks are equal. As in case of the Spearman rank correlation, we may use Kendall's τ to test for independence between x and y.

3.3 Distance measures related to the Euclidean distance

3.3.1 Euclidean distance

A newly added distance function is the Euclidean distance, which is defined as

d =
1
n
n

i = 1
( xi - yi )2
The Euclidean distance takes the difference between two gene expression levels directly. It should therefore only be used for expression data that are suitably normalized, for example by converting the measured gene expression levels to log-ratios. In the sum, we only include terms for which both xi and yi are present, and divide by n accordingly.

Unlike the correlation-based distance measures, the Euclidean distance takes the magnitude of changes in the gene expression levels into account. An example of the Euclidean distance applied to k-means clustering can be found in De Hoon, Imoto, and Miyano (2002).

3.3.2 City-block distance

The city-block distance, alternatively known as the Manhattan distance, is related to the Euclidean distance. Whereas the Euclidean distance corresponds to the length of the shortest path between two points, the city-block distance is the sum of distances along each dimension:

d =
1
n
n

i = 1
| xi - yi |
This is equal to the distance you would have to walk between two points in a city, where you have to walk along city blocks. The city-block distance is a metric, as it satisfies the triangle inequality. Again we only include terms for which both xi and yi are present, and divide by n accordingly.

As for the Euclidean distance, the expression data are subtracted directly from each other, and we should therefore make sure that they are properly normalized.

3.4 Missing values

When either x or y has missing values, only observations present for both x and y are used in computing similarities.

3.5 Calculating the distance matrix

With any specified metric, the first step in the hierarchical clustering routines described below is to compute the distance (the opposite of similarity; for all correlation metrics distance = 1.0 - correlation) between all pairs of items to be clustered (e.g. the set of genes in the current dataset). This can often be time consuming, and, except for pairwise single-linkage clustering, memory intensive (the maximum amount of memory required is 4 x N x N bytes, where N is the number of items being clustered). The algorithm for pairwise single-linkage hierarchical clustering is less memory-intensive (linear in N). cluster-1.52a/html/Data.html0000644000100500010050000002671011505777254015637 0ustar mdehoonmdehoon Data - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Next: , Previous: Introduction, Up: Top


2 Loading, filtering, and adjusting data

images/cluster.png

Data can be loaded into Cluster by choosing Load data file under the File menu. A number of options are provided for adjusting and filtering the data you have loaded. These functions are accessed via the Filter Data and Adjust Data tabs.

2.1 Loading Data

The first step in using Cluster is to import data. Currently, Cluster only reads tab-delimited text files in a particular format, described below. Such tab-delimited text files can be created and exported in any standard spreadsheet program, such as Microsoft Excel. An example datafile can be found under the File format help item in the Help menu. This contains all the information you need for making a Cluster input file.

By convention, in Cluster input tables rows represent genes and columns represent samples or observations (e.g. a single microarray hybridization). For a simple timecourse, a minimal Cluster input file would look like this:

images/minifile.png

Each row (gene) has an identifier (in green) that always goes in the first column. Here we are using yeast open reading frame codes. Each column (sample) has a label (in blue) that is always in the first row; here the labels describe the time at which a sample was taken. The first column of the first row contains a special field (in red) that tells the program what kind of objects are in each row. In this case, YORF stands for yeast open reading frame. This field can be any alpha-numeric value. It is used in TreeView to specify how rows are linked to external websites.

The remaining cells in the table contain data for the appropriate gene and sample. The 5.8 in row 2 column 4 means that the observed data value for gene YAL001C at 2 hours was 5.8. Missing values are acceptable and are designated by empty cells (e.g. YAL005C at 2 hours).

It is possible to have additional information in the input file. A maximal Cluster input file would look like this:

images/maxifile.png

The yellow columns and rows are optional. By default, TreeView uses the ID in column 1 as a label for each gene. The NAME column allows you to specify a label for each gene that is distinct from the ID in column 1. The other rows and columns will be described later in this text.

When Cluster 3.0 opens the data file, the number of columns in each row is checked. If a given row contains less or more columns than needed, an error message is displayed.

images/fileerror.png

Demo data

A demo datafile, which will be used in all of the examples here, is available at http://rana.lbl.gov/downloads/data/demo.txt and is mirrored at http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/demo.txt.

The datafile contains yeast gene expression data described in Eisen et al. (1998) [see references at end]. Download this data and load it into Cluster. Cluster will give you information about the loaded datafile.

images/filemanager.png

2.2 Filtering Data

images/filter.png

The Filter Data tab allows you to remove genes that do not have certain desired properties from your dataset. The currently available properties that can be used to filter data are

  • % Present >= X. This removes all genes that have missing values in greater than (100-X) percent of the columns.
  • SD (Gene Vector) >= X. This removes all genes that have standard deviations of observed values less than X.
  • At least X Observations with abs(Val) >= Y. This removes all genes that do not have at least X observations with absolute values greater than Y.
  • MaxVal-MinVal >= X. This removes all genes whose maximum minus minimum values are less than X.
These are fairly self-explanatory. When you press filter, the filters are not immediately applied to the dataset. You are first told how many genes would have passed the filter. If you want to accept the filter, you press Accept, otherwise no changes are made.
images/accept.png

2.3 Adjusting Data

images/adjust.png

From the Adjust Data tab, you can perform a number of operations that alter the underlying data in the imported table. These operations are

  • Log Transform Data: replace all data values x by log2 (x).
  • Center genes [mean or median]: Subtract the row-wise mean or median from the values in each row of data, so that the mean or median value of each row is 0.
  • Center arrays [mean or median]: Subtract the column-wise mean or median from the values in each column of data, so that the mean or median value of each column is 0.
  • Normalize genes: Multiply all values in each row of data by a scale factor S so that the sum of the squares of the values in each row is 1.0 (a separate S is computed for each row).
  • Normalize arrays: Multiply all values in each column of data by a scale factor S so that the sum of the squares of the values in each column is 1.0 (a separate S is computed for each column).
These operations are not associative, so the order in which these operations is applied is very important, and you should consider it carefully before you apply these operations. The order of operations is (only checked operations are performed):
  • Log transform all values.
  • Center rows by subtracting the mean or median.
  • Normalize rows.
  • Center columns by subtracting the mean or median.
  • Normalize columns.

2.3.1 Log transformation

The results of many DNA microarray experiments are fluorescent ratios. Ratio measurements are most naturally processed in log space. Consider an experiment where you are looking at gene expression over time, and the results are relative expression levels compared to time 0. Assume at timepoint 1, a gene is unchanged, at timepoint 2 it is up 2-fold and at timepoint three is down 2-fold relative to time 0. The raw ratio values are 1.0, 2.0 and 0.5. In most applications, you want to think of 2-fold up and 2-fold down as being the same magnitude of change, but in an opposite direction. In raw ratio space, however, the difference between timepoint 1 and 2 is +1.0, while between timepoint 1 and 3 is -0.5. Thus mathematical operations that use the difference between values would think that the 2-fold up change was twice as significant as the 2-fold down change. Usually, you do not want this. In log space (we use log base 2 for simplicity) the data points become 0,1.0,-1.0.With these values, 2-fold up and 2-fold down are symmetric about 0. For most applications, we recommend you work in log space.

2.3.2 Mean/Median Centering

Consider a now common experimental design where you are looking at a large number of tumor samples all compared to a common reference sample made from a collection of cell-lines. For each gene, you have a series of ratio values that are relative to the expression level of that gene in the reference sample. Since the reference sample really has nothing to do with your experiment, you want your analysis to be independent of the amount of a gene present in the reference sample. This is achieved by adjusting the values of each gene to reflect their variation from some property of the series of observed values such as the mean or median. This is what mean and/or median centering of genes does. Centering makes less sense in experiments where the reference sample is part of the experiment, as it is many timecourses. Centering the data for columns/arrays can also be used to remove certain types of biases. The results of many two-color fluorescent hybridization experiments are not corrected for systematic biases in ratios that are the result of differences in RNA amounts, labeling efficiency and image acquisition parameters. Such biases have the effect of multiplying ratios for all genes by a fixed scalar. Mean or median centering the data in log-space has the effect of correcting this bias, although it should be noted that an assumption is being made in correcting this bias, which is that the average gene in a given experiment is expected to have a ratio of 1.0 (or log-ratio of 0).

In general, I recommend the use of median rather than mean centering, as it is more robust against outliers.

2.3.3 Normalization

Normalization sets the magnitude (sum of the squares of the values) of a row/column vector to 1.0. Most of the distance metrics used by Cluster work with internally normalized data vectors, but the data are output as they were originally entered. If you want to output normalized vectors, you should select this option. A sample series of operations for raw data would be:

  • Adjust Cycle 1) log transform
  • Adjust Cycle 2) median center genes and arrays
  • repeat (2) five to ten times
  • Adjust Cycle 3) normalize genes and arrays
  • repeat (3) five to ten times

This results in a log-transformed, median polished (i.e. all row-wise and column-wise median values are close to zero) and normal (i.e. all row and column magnitudes are close to 1.0) dataset. After performing these operations you should save the dataset. cluster-1.52a/html/Introduction.html0000644000100500010050000000433211505777254017443 0ustar mdehoonmdehoon Introduction - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Next: , Previous: Contents, Up: Top


1 Introduction

Cluster and TreeView are programs that provide a computational and graphical environment for analyzing data from DNA microarray experiments, or other genomic datasets. The program Cluster can organize and analyze the data in a number of different ways. TreeView allows the organized data to be visualized and browsed.

This manual is intended as a reference for using the software, and not as a comprehensive introduction to the methods employed. Many of the methods are drawn from standard statistical cluster analysis. There are excellent textbooks available on cluster analysis which are listed in the bibliography at the end. The bibliography also contains citations for recent publications in the biological sciences, especially genomics, that employ methods similar to those used here. cluster-1.52a/html/index.html0000644000100500010050000000640511505777254016074 0ustar mdehoonmdehoon Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Next: 


This is the manual for Cluster 3.0. Cluster was originally written by Michael Eisen while at Stanford University. We have modified the k-means clustering algorithm in Cluster, and extended the algorithm for Self-Organizing Maps to include two-dimensional rectangular grids. The Euclidean distance and the city-block distance were added as new distance measures between gene expression data. The proprietary Numerical Recipes routines, which were used in the original version of Cluster/TreeView, have been replaced by open source software.

Cluster 3.0 is available for Windows, Mac OS X, Linux, and Unix.



November 5, 2002.
Michiel de Hoon
Human Genome Center, University of Tokyo.

cluster-1.52a/html/mac.py0000754000100500010050000000064010436714277015204 0ustar mdehoonmdehoon#!python # This script inserts a line in the header part of index.html that is required # by Project Builder. inputfile = open('index.html') text = inputfile.read() inputfile.close() insert = text.find('') outputfile = open('index.html','w') outputfile.write(text[:insert]) outputfile.write('\n') outputfile.write(text[insert:]) outputfile.close() cluster-1.52a/html/Development.html0000644000100500010050000000752511505777254017253 0ustar mdehoonmdehoon Development - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Next: , Previous: TreeView, Up: Top


7 Code Development Information

In previous versions of Cluster, the proprietary Numerical Recipes routines were heavily used. We have replaced these routines by the C clustering library, which was released under the Python License. Accordingly, the complete source code of Cluster is now open. It can be downloaded from http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster. We used the GNU C compiler in order to enable anybody to compile the code. No commercial compiler is required. The GNU C compiler is available at http://www.gnu.org. There you can also find texinfo, which was used to generate the printed and the HTML documentation. To convert the picture files to EPS files for the printed documentation, we used pngtopnm and pnmtops of Netpbm, which can be found at http://netpbm.sourceforge.net. The HTML Help file was generated using the HTML Help Workshop, which is freely available at the Microsoft site. The Windows Installer was created with the Inno Setup Compiler, which is available at http://www.innosetup.com.

For Mac OS X, we used the Project Builder and the Interface Builder, which are part of the Mac OS X Development Tools. The prebuilt package was created with PackageMaker, which is also part of Mac OS X. The project files needed to recompile Cluster 3.0 are included in the source code. From the command prompt, Cluster 3.0 can be recompiled by running make from the mac subdirectory; this produces a universal binary for PowerPC and Intel processors.

For Cluster 3.0 on Linux/Unix, we used the Motif libraries that are installed on most Linux/Unix computers. The include files are typically located in /usr/X11R6/include/Xm. You will need a version of Motif that is compliant with Motif 2.1, such as Open Motif (http://www.opengroup.org), which is available at http://www.motifzone.net.

To improve the portability of the code, we made use of GNU's automake and autoconf. The corresponding Makefile.am and configure.ac files are included in the source code distribution. cluster-1.52a/html/SOM.html0000644000100500010050000001024011505777254015413 0ustar mdehoonmdehoon SOM - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Next: , Previous: KMeans, Up: Cluster


4.3 Self-Organizing Maps

images/som.png

Self-Organizing Maps (SOMs) is a method of cluster analysis that are somewhat related to k-meansclustering. SOMs were invented in by Teuvo Kohonen in the early 1980s, and have recently been used in genomic analysis (see Chu 1998, Tamayo 1999 and Golub 1999 in references). The Tamayo paper contains a simple explanation of the methods. A more detailed description is available in the book by Kohonen, Self-Organizing Maps, 1997.

The current implementation varies slightly from that of Tamayo et al., in that it restricts the analysis one-dimensional SOMs along each axis, as opposed to a two-dimensional network. The one-dimensional SOM is used to reorder the elements on whichever axes are selected. The result is similar to the result of k-means clustering, except that, unlike in k-means clustering, the nodes in a SOM are ordered. This tends to result in a relatively smooth transition between groups.

The options for SOMs are

  • whether or not you will organize each axis;
  • the number of nodes for each axis (the default is n1/4,where nis the number of items; the total number of clusters is then equal to the square root of the number of items);
  • the number of iterations to be run.

The output file is of the form JobName_SOM_GXg-Yg_AXa-Ya.txt, where GXg-Yg is included if genes were organized, and AXg-Yg is included if arrays were organized. X and Y represent the dimensions of the corresponding SOM. Up to two additional files (.gnf and .anf) are written containing the vectors for the SOM nodes.

In previous versions of Cluster, only one-dimensional SOMs were supported. The current version of the Cluster introduces two-dimensional SOMs.

SOMs and hierarchical clustering: Our original use of SOMs (see Chu et al., 1998) was motivated by the desire to take advantage of the properties of both SOMs and hierarchical clustering. This was accomplished by first computing a one dimensional SOM, and using the ordering from the SOM to guide the flipping of nodes in the hierarchical tree. In Cluster, after a SOM is run on a dataset, the GORDER and/or EORDER fields are set to the ordering from the SOM so that, for subsequent hierarchical clustering runs, the output ordering will come as close as possible to the ordering in the SOM without violating the structure of the tree. cluster-1.52a/html/Hierarchical.html0000644000100500010050000004443611505777254017351 0ustar mdehoonmdehoon Hierarchical - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Next: , Up: Cluster


4.1 Hierarchical Clustering

images/hierarchical.png

The Hierarchical Clustering tab allows you to perform hierarchical clustering on your data. This is a powerful and useful method for analyzing all sorts of large genomic datasets. Many published applications of this analysis are given in the references section at the end.

Cluster currently performs four types of binary, agglomerative, hierarchical clustering. The basic idea is to assemble a set of items (genes or arrays) into a tree, where items are joined by very short branches if they are very similar to each other, and by increasingly longer branches as their similarity decreases.

The first step in hierarchical clustering is to calculate the distance matrix between the gene expression data. Once this matrix of distances is computed, the clustering begins. Agglomerative hierarchical processing consists of repeated cycles where the two closest remaining items (those with the smallest distance) are joined by a node/branch of a tree, with the length of the branch set to the distance between the joined items. The two joined items are removed from list of items being processed and replaced by a item that represents the new branch. The distances between this new item and all other remaining items are computed, and the process is repeated until only one item remains.

Note that once clustering commences, we are working with items that are true items (e.g. a single gene) and items that are pseudo-items that contain a number of true items. There are a variety of ways to compute distances when we are dealing with pseudo-items, and Cluster currently provides four choices, which are called centroid linkage, single linkage, complete linkage, and average linkage. Note that in older versions of Cluster, centroid linkage was referred to as average linkage.

4.1.1 Centroid Linkage Clustering

If you click Centroid Linkage Clustering, a vector is assigned to each pseudo-item, and this vector is used to compute the distances between this pseudo-item and all remaining items or pseudo-items using the same similarity metric as was used to calculate the initial similarity matrix. The vector is the average of the vectors of all actual items (e.g. genes) contained within the pseudo-item. Thus, when a new branch of the tree is formed joining together a branch with 5 items and an actual item, the new pseudo-item is assigned a vector that is the average of the 6 vectors it contains, and not the average of the two joined items (note that missing values are not used in the average, and a pseudo-item can have a missing value if all of the items it contains are missing values in the corresponding row/column).

Note that from a theoretical perspective, Centroid Linkage Clustering is peculiar if it is used in combination with one of the distance measures that are based on the Pearson correlation. For these distance measures, the data vectors are implicitly normalized when calculating the distance (for example, by subtracting the mean and dividing by the standard deviation when calculating the Pearson correlation. However, when two genes are joined and their centroid is calculated by averaging their data vectors, no normalization is applied. This may lead to the surprising result that distances may decrease when we go up in the tree representing the hierarchical clustering result. For example, consider this data set:

Exp 1 Exp 2 Exp 3 Exp 4
Gene 1 0.96 0.07 0.97 0.98
Gene 2 0.50 0.28 0.29 0.77
Gene 3 0.08 0.96 0.51 0.51
Gene 4 0.14 0.19 0.41 0.51
Performing pairwise centroid-linkage hierarchical clustering on this data set, using the Pearson distance as the distance measure, produces the clustering result
  • Gene 1 joins Gene 2 at distance 0.47
  • (Gene 1, Gene 2) joins Gene 4 at distance 0.46
  • (Gene 1, Gene 2, Gene 4) joins Gene 3 at distance 1.62
This may result in ill-formed dendrograms. For an example, see the Java TreeView manual. A solution is to use the Euclidean or the city-block distance, or to use one of the other hierarchical clustering routines, which don't suffer from this issue regardless of the distance measure being used.

4.1.2 Single Linkage Clustering

In Single Linkage Clustering the distance between two items x and y is the minimum of all pairwise distances between items contained in x and y. Unlike centroid linkage clustering, in single linkage clustering no further distances need to be calculated once the distance matrix is known.

In Cluster 3.0, as of version 1.29 the implementation of single linkage clustering is based on the SLINK algorithm (see Sibson, 1973). Whereas this algorithm yields the exact same clustering result as conventional single-linkage hierarchical clustering, it is much faster and more memory-efficient (being linear in the memory requirements, compared to quadratic for the conventional algorithm). Hence, single-linkage hierarchical clustering can be used to cluster large gene expression data sets, for which centroid-, complete-, and average-linkage fail due to lack of memory.

4.1.3 Complete Linkage Clustering

In Complete Linkage Clustering the distance between two items x and y is the maximum of all pairwise distances between items contained in x and y. As in single linkage clustering, no other distances need to be calculated once the distance matrix is known.

4.1.4 Average Linkage Clustering

In average linkage clustering, the distance between two items x and y is the mean of all pairwise distances between items contained in x and y.

4.1.5 Weighting

Weighting: By default, all of the observations for a given item are treated equally. In some cases you may want to give some observations more weight than others. For example, if you have duplicate copies of a gene on your array, you might want to downweight each individual copy when computing distances between arrays. You can specify weights using the ‘GWEIGHT’ (gene weight) and ‘EWEIGHT’ (experiment weight) parameters in the input file. By default all weights are set to 1.0. Thus, the actual formula, with weights included, for the Pearson correlation of x = {x1, x2, ..., xn}and y = {y1, y2, ..., yn} with observation weights of w = {w1, w2, ..., wn} is

r =
n

i = 1
wi (
xi - x
σx
) (
yi - y
σy
)
n

i = 1
wi
Note that when you are clustering rows (genes), you are using column (array) weights. It is possible to compute weights as well based on a not entirely well understood function. If you want to compute weights for clustering genes, select the check box in the Genes panel of the Hierarchical Clustering tab.
images/weight.png

This will expose a Weight Options dialog box in the Arrays panel (I realize this placement is a bit counterintuitive, but it makes sense as you will see below). The idea behind the Calculate Weights option is to weight each row (the same idea applies to columns as well) based on the local density of row vectors in its vicinity, with a high density vicinity resulting in a low weight and a low density vicinity resulting in a higher weight. This is implemented by assigning a local density score L(i) to each row i.

L(i) =

j with d(i,j) ≤ k
(
k - d(i,j)
k
) n


where the cutoff k and the exponent n are user supplied parameters. The weight for each row is 1/L. Note that L(i) is always at least 1, since d(i,i) = 0. Each other row that is within the distance k of row i increases L(i) and decreases the weight. The larger d(i,j), the less L(i) is increased. Values of n greater than 1 mean that the contribution to L(i) drops off rapidly as d(i,j) increases.

4.1.6 Ordering of Output File

The result of a clustering run is a tree or pair of trees (one for genes one for arrays). However, to visualize the results in TreeView, it is necessary to use this tree to reorder the rows and/or columns in the initial datatable. Note that if you simply draw all of the node in the tree in the following manner, a natural ordering of items emerges:
images/order.png

Thus, any tree can be used to generate an ordering. However, the ordering for any given tree is not unique. There is a family of 2N-1ordering consistent with any tree of Nitems; you can flip any node on the tree (exchange the bottom and top branches) and you will get a new ordering that is equally consistent with the tree. By default, when Cluster joins two items, it randomly places one item on the top branch and the other on the bottom branch. It is possible to guide this process to generate the best ordering consistent with a given tree. This is done by using the ‘GORDER’ (gene order) and ‘EORDER’ (experiment order) parameters in the input file, or by running a self-organizing map (see section below) prior to clustering. By default, Cluster sets the order parameter for each row/column to 1. When a new node is created, Cluster compares the order parameters of the two joined items, and places the item with the smaller order value on the top branch. The order parameter for a node is the average of the order parameters of its members. Thus, if you want the gene order produced by Cluster to be as close as possible (without violating the structure of the tree) to the order in your input file, you use the ‘GORDER’ column, and assign a value that increases for each row. Note that order parameters do not have to be unique.

4.1.7 Output Files

Cluster writes up to three output files for each hierarchical clustering run. The root filename of each file is whatever text you enter into the Job Name dialog box. When you load a file, Job Name is set to the root filename of the input file. The three output files are JobName.cdt, JobName.gtr, JobName.atr The .cdt (for clustered data table) file contains the original data with the rows and columns reordered based on the clustering result. It is the same format as the input files, except that an additional column and/or row is added if clustering is performed on genes and/or arrays. This additional column/row contains a unique identifier for each row/column that is linked to the description of the tree structure in the .gtr and .atr files. The .gtr (gene tree) and .atr (array tree) files are tab-delimited text files that report on the history of node joining in the gene or array clustering (note that these files are produced only when clustering is performed on the corresponding axis). When clustering begins each item to be clustered is assigned a unique identifier (e.g. ‘GENE1X’ or ‘ARRY42X’ — the ‘X’ is a relic from the days when this was written in Perl and substring searches were used). These identifiers are added to the .cdt file. As each node is generated, it receives a unique identifier as well, starting is ‘NODE1X’, ‘NODE2X’, etc. Each joining event is stored in the .gtr or .atr file as a row with the node identifier, the identifiers of the two joined elements, and the similarity score for the two joined elements. These files look like:
images/tree.png

NODE1X GENE1X GENE4X 0.98
NODE2X GENE5X GENE2X 0.80
NODE3X NODE1X GENE3X 0.72
NODE4X NODE2X NODE3X 0.60

The .gtr and/or .atr files are automatically read in TreeView when you open the corresponding .cdt file. cluster-1.52a/html/KMeans.html0000644000100500010050000001330511505777254016140 0ustar mdehoonmdehoon KMeans - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Next: , Previous: Hierarchical, Up: Cluster


4.2 The k-means Clustering Algorithm

images/kmeans.png

The k-means clustering algorithm is a simple, but popular, form of cluster analysis. The basic idea is that you start with a collection of items (e.g. genes) and some chosen number of clusters (k) you want to find. The items are initially randomly assigned to a cluster. The k-means clustering proceeds by repeated application of a two-step process where

  1. the mean vector for all items in each cluster is computed;
  2. items are reassigned to the cluster whose center is closest to the item.

Since the initial cluster assignment is random, different runs of the k-means clustering algorithm may not give the same final clustering solution. To deal with this, the k-means clustering algorithms is repeated many times, each time starting from a different initial clustering. The sum of distances within the clusters is used to compare different clustering solutions. The clustering solution with the smallest sum of within-cluster distances is saved.

The number of runs that should be done depends on how difficult it is to find the optimal solution, which in turn depends on the number of genes involved. Cluster therefore shows in the status bar how many times the optimal solution has been found. If this number is one, there may be a clustering solution with an even lower sum of within-cluster distances. The k-means clustering algorithm should then be repeated with more trials. If the optimal solution is found many times, the solution that has been found is likely to have the lowest possible within-cluster sum of distances. We can then assume that the k-means clustering procedure has then found the overall optimal clustering solution.

It should be noted that generally, the k-means clustering algorithm finds a clustering solution with a smaller within-cluster sum of distances than the hierarchical clustering techniques.

The parameters that control k-means clustering are

  • the number of clusters (k);
  • the number of trials.

The output is simply an assignment of items to a cluster. The implementation here simply rearranges the rows and/or columns based on which cluster they were assigned to. The output data file is JobName_K_GKg_AKa.cdt, where _GKg is included if genes were organized, and _AKa is included if arrays were organized. Here, Kg and Ka represent the number of clusters for gene clustering and array clustering, respectively. This file contains the gene expression data, organized by cluster by rearranging the rows and columns. In addition, the files JobName_K_GKg.kgg and JobName_K_AKa.kag are created, containing a list of genes/arrays and the cluster they were assigned to.

Whereas k-means clustering as implemented in Cluster 3.0 allows any of the eight distance measures to be used, we recommend using the Euclidean distance or city-block distance instead of the distance measures based on the Pearson correlation, for the same reason as in case of pairwise centroid-linkage hierarchical clustering. The distance measures based on the Pearson correlation effectively normalize the data vectors when calculating the distance, whereas no normalization is used when calculating the cluster centroid. To use k-means clustering with a distance measure based on the Pearson correlation, it is better to first normalize the data appropriately (using the "Adjust Data" tab) before running the k-means algorithm.

Cluster also implements a slight variation on k-means clustering, known as k-medians clustering, in which the median instead of the mean of items in a node are used. In a theoretical sense, it is best to use k-means with the Euclidean distance, and k-medoids with the city-block distance. cluster-1.52a/html/Cluster.html0000644000100500010050000000512211505777254016401 0ustar mdehoonmdehoon Cluster - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Next: , Previous: Distance, Up: Top


4 Clustering techniques

The Cluster program provides several clustering algorithms. Hierarchical clustering methods organizes genes in a tree structure, based on their similarity. Four variants of hierarchical clustering are available in Cluster. In k-means clustering, genes are organized into k clusters, where the number of clusters k needs to be chosen in advance. Self-Organizing Maps create clusters of genes on a two-dimensional rectangular grid, where neighboring clusters are similar. For each of these methods, one of the eight different distance meaures can be used. Finally, in Principal Component Analysis, clusters are organized based on the principal component axes of the distance matrix.

cluster-1.52a/html/images/0000755000100500010050000000000012177164025015327 5ustar mdehoonmdehooncluster-1.52a/html/images/order.png0000644000100500010050000004504307505046774017167 0ustar mdehoonmdehoon‰PNG  IHDR‚ðC‹+`gAMA± üabKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÒ ~ºá IDATxœå}y\SWÚÿ¹7uª hÛ·­a±Îøj!lÓ)Ê’°X;‹Bœ­Š€mßÏ´Yw„$JÛy?YÄe¦3U¨µŸ·‹H@°j[°ØÎ´#;vÚi ¸Crïùýñx‡@¡¥¿ç>!¹÷Ü{Öçù>+Ãó<<!¤T*·nÝêëë»{÷îÈÈHèÌÌÌæææ’’†a Ebbâ•+WöíÛ×ÕÕuæÌžç_|ñŶ¶677·üü|†aÞxã²²2„Б#G}ôÑÿûßJ¥²¯¯ã8ÄqÏócŒ±Ñhä8.%%eúôéhȈ³,;ÎC4q N$1 S]]ÍSOO»»{iiipp0 TNNŽF£éé鉈ˆ0ááác©Tj0:::Nž<Š1æy¾§§Ç`0øûûÃùùùãÊÊÊœœŒqlllMMN§swwÓc /wáÂ…[·nÉd2²KàîÛ°ÙŽD"ÏóÇ!„ìììŒF£D"±p(9;;'$$$&&644À&`fË–-ÇùúúŠD¢úúúÐÐP///±Xìêêêââ’—— :;;GDDÀéÇq\RRROOOJJŠJ¥â8®¯¯Ïßßc¬ÕjÙ¼@r¹!´k×.˜CøËqœ…%3‰:B#ÞB–<Ü›]YY‰1 ƒ¿õõõ+W®$Ã%—ËÉg£Ñ˜]QQ1îîî–Ëå*•ª­­ cìëëÛÓÓƒ1îééaáI°=B ÃܼyS$q“<~…Ï“š…a…ÍaázŒñ³Ï>[SS“žžÇraaaJJŠ\.Ÿ?þÁƒµZ-Æxúôé¹¹¹uuu‘‘‘555QQQF£1..îÙgŸmll”Éd<Ï{xxtvv–””¼óÎ;ƒA­VÇÅÅ…‡‡oݺ‘¥a0àÃ’%K†Ù±cù‰¬Ÿ‘îÀ"ÍŰ…cÍäØXÐ&ù ‚y ü DZà8îÞÒ‹Åc“õB$3ô“Ø @dg3 CwÐÜÅÇÁ>€¿0, Føc œÚñ.ƒvàp }À@³,=Üä1&abèo57“nz /Cq’9 …Ü ƒ`ø¨‰! >ØÙÙÑ«™°wx´Éûˆ-¼+Y5<Ï‹Åb`ä._¾ü§?ý &Ò`0Lˆg-nÉd!•JµeË–… ~õÕW ,P«ÕQQQ ,˜?þñãÇÅbñéÓ§Y–íîî^µjÕ7Þxã ©TúØcy{{kµÚ´´´”””#GŽ8pàW¿úU^^žL&‰DgΜٲeË]IÉä| Fmß¾ã8rÆ‘cN4­VûÔSOMÜàÙšFôz½››Û©S§d2Æ8++K"‘º»»WTTð<ßdPPPpåÊ•ÄÄDŒq}}=ÆX"‘èt:Œ1ˆ[ëׯoiiQ«ÕÇÏÈÈÐét2™Ììn‹Å,Ë # »Á™Ø×××ÔÔ$‹SSSíííÉ>}ðÉZÜ0sæÌ7®^½º©©‰çy‘HŸŸŸKN*ׯ_ïííõñññòòjkkC-Z´¨¡¡ÁÏÏÏÉÉ .C¼$‘Hêêê4 Çqþþþf§Á`0 aÕ „`MÑìÝ»M*½“‰^hÄ7ǧ¤¤TUUÍ™3Xî¢E‹ÊËËg̘!ß¿"‘¨®®N«ÕΞ=»««ëÊ•+ð 'NÈår`ò uuu­\¹’ã¸ŠŠŠŒŒ ¥R©P(ÌJ;vì ¿‡ÓÉ`0üå/Y¼xñÂ… í XØÑ&ÑØ ™†„„Ìš5+-- cìéééççWSSãáᑜœœ——çää¨T*õz}XX˜¿¿?GcGGG8‘0Æô÷÷_·nƸ»»û‘G1 ±±±'Nœ0; Û¶mƒÉ[Æ¿üå/sçÎE‚°|ÒÍ„U¸¾ fnè-F¿”>pÐÞ¬¶Žh[‰L&‰ZZZ®^½*‘Hâãã‘ ùÙÙÙÙî̘² 7`A.'ç,>øÕÄL@àHbˆv†1pÌN¹™~uxoWW×õë×Ã#‰¼<‰èînʺa41…¨L0BÈ`0ØÙÙ˜h€Œ£4³,Úò›¼!‰‚ƒƒAÞ˜,vkqCHHÈ”)S²³³·mÛöóŸÿ<77÷¹çžøýï¿fÍšcÇŽýío³³³[¾|yrrr___tttOOϱcÇ.\¨V«A©wèÐ!‰D’ššÚØØøÐC;vÌÁÁ¡¥¥E¥R]¿~ã8K,zèù¸cÇ„L&+++@7qãgS² 7xzzž8q¬ã²²2µZ G|dd$ÇqR©cœŸŸ_TTÔÜÜœ€1.,,Äk4¥R‰1öññÁoݺõƒ>ÀGGG×××ßµ7XÛ–eïܹÙÒÒRTTdoo‚‰´ýh7¬_¿~ãÆµµµp™½½=ì~­Vëëë[SS>þ|Œñµk×|||`Œ×­[§Óé¶lÙ’1~òÉ'-Zôí·ßîÙ³‡çùk×®y{{#„´Z­ÕÓ€Ð0gΜ¬¬,ødä±Í’µ¸!”––VQQ!‘H€%ܾ}¶QZZZYYÙ/ùË]»v)•J†af̘ÑÚÚêéé S{óæÍ¸¸8…B÷vwwŸ;w.==½±±ÑÇǧ§§çÚµkŽŽŽ<Ïe@­oݘ,s€뽸†ÂÃÛšš222rrr†Ù¾}»N§+//oll>>±±±ÎÎÎnnn<Ï«Õêèèh†a<==­æ "‘(((þ%"ðä2HXko —™(ÖˆÂnŠFQ¤qÚä×ß߇˜1¬^ÅÇQlmš¬µ7ë‰]:˜D/r (,ˆû€hÇ{{{x4Ù…,Ëš=”e¼úê«ð`ŽãÚÛÛѧ&ú!Ô××ÛÝÝ}øðaooïäädàØD-]ºt``€a˜ÊÊʨ¨(ƒÁPQQ1‚½a×®]`”Þ±cÇ®]»víÚåîîN&ƒŒûd™š¬µ7¼ûî»ðMvv6èMkjj°àŸ,ì ---IIIÇõôôF€ c™LÖÐÐÐÛÛ‹1Þ³gÏÉ“'ÓÒÒF°7ȼmÛ68+++ÛÚÚ¦L™’šš Šœ’?U{ƒ££crròš5k‘pÚÄÇÇÇÄÄøùù!C †¶¶¶ëׯûøøH$’¶¶6–e###Åb1\~øaqqq]]ÝÏþóO>ùäܹscKö‘HK†eYš!„zè¡;w’mA󺟬ŠÃlÞ¼Y£Ñ¸»»#á@ûí·Ïž=«V«ÓÒÒ€?üñÇÿüç?ö³Ÿ577{zzº¸¸Àí}ô‘Z­®®® Û»w/ÆøæÍ›õõõŽŽŽ.\xõÕWsss …Ùiጰ‹ûûûi'ÉÅŸ­Å Ç=ûì³_|ñEjjjvv¶X,.((˜5k–F£ñöövrrª¯¯öÙg¿ýöÛøøøU«VÅÄÄ9räÍ7ßD)ŠÞÞ^gg猌 „PLLÌ7²³³õzý—_~ÿÞ{ïI$³¼aÏž=‹/FƒÄ3Ï<ƒrpp0¹erùôYko 6yú.ÚËÈ:˜ȯx0’ mv€› xy`Áég hˆ,1[®Øq&kí äXFË$fø•Œ´Ì!$‰ˆî™À „ðTÚnavø`dÉSÉëbaGËIGw •öFpª3t$°}f°¯)4ú7˜0¸Œçyb(»w™…w…%í’É„MMM/¿ü2˲·nÝš:uê‡dÂÉZÜ…1Þ½{wff¦··÷¾}û¢¢¢`öïß_[[{âÄ –eÏœ9ƒ1¾zõªR©lmm-//Gåååæçç#„Þ|óÍ×_½¨¨(88˜eÙÖÖVµZ ñ –VV $piŸ†©««KHHhjjB‰ÅbPöM""®o<Ï_¿~Ý•ÿûßýýý¯^½Š1Þ·oBèôéÓK—.-//çy~Ñ¢Eï¼óNYY,Ð;wî„„„´´´·Œ†††7677{xx<þøãr¹|``ZÎÈÈHMMõðððóó3;  ú l&£¿¿X­[·šššX–ݾ};¦\|C|ÃúõëµZ-–#Œ¨×€÷öö~ÿý÷O>ùä“O>YXXH"®xžwwwïììtww_¾|ù?þñ{{{Ð õõõùùùaŒ-Ù ò!D¼q Ô)SÐ`ç¥ÌÌL4©€´µ¸cœžž^]]íêêJ¸z?¢´x,ËÖÖÖ^¾|ÙÓÓÔþDÆ·¶¶FGG£*‰º»»u:³³3Ïó–<3ˆOp;;;X½½½ ç˜Ddm|Bè׿þõ¥K—¶mÛs “É>ÿüs¹\^WWWXXØØØ‘‘‘1nhhÉd—/_†Pèèè   £ÑèîîÓY\\œžž^PP€1V©TÃÄ7"ö‡%ŒñÎ;†Y¼xquu5¼"LÒärUn /#wÁ‡„ ‘˜8EÇ:Ð Ž`oÀƒ¥Rr3ÙY&JöÉBVár ­4ƒCÎ:‚~%.¦,ËÒ JK`<}s&Ò*t˜úàú~“‚` Ž>¾6ò !1Ä¢sƒ÷2(“»ÈXÑv3lÙÞ0eÊØq4{¡õ0¼àVŽGa?y@h¼qCVVÖ°qÑ!½^Ÿœœ¬×ë³³³·nÝʲìÿýßÿm߾ݒ¤Æ$8à†FΨÖÖV˜ÿªª*ÍO?ܰtéÒ „†Ù»w¯ƒƒÃ¯~õ+øwÆ jµäã%K–<ùä“;vìHMMµ¤a%ÆR8Ý`2ÈÖ»ví\¶}ûvb ´Ù '7n˜7oÞ°qÑ`tKJJB•––þâ¿øôÓO«««GŽo‹+AÑð=&iÄb£Ñ¸k×.<زú€ÓxãÐÙ‘{OŸ>­V««ªªd2™§§ç™3g nwúôé•••$¾Á,‹ž2e -bÀ÷hhhÈËË#2?Ø9ù§ñÆ ⢓’’ÂÃõZmXXX```KKKtt´‡‡‡%{Cff&ØýwîÜ òïÀÀÀîÝ»…™™Éf‚Ç7À¯ÃÆEÓMÆÍìn > X vvvçÏŸOOOŠŠBa!¸OV qÅ ÐæÐ¸hD!PIÀÀO#Ä7ùW,eeeAz¢.'#wñBüÅ(‡f"éî´7`€¨Š)–n‚Ý€@°D‚”OÆ vë"‹`,ñ ^7,,l```Ú´i ì¢u[‹ÂÂÂX–U©Téééà›!“ÉÒÒÒüüü<<<Ž?Žª¬¬Dµµµ©Tª––Èm¢Óé^|ñÅîîn•Jåíím!.ÚfÓ€1–ÉdUUUvvvdXH1zÜðî»ïúúú¶¶¶bŒs’J¥ááá¾¾¾r¹üĉ!à2™¬­­ ä±7fgg{zzBS%%% ­­­QQQ...[·n7Œª««E"Q\\œ‹‹ IKfÃömBcðSJLL|饗.^¼ˆÂçææ¦§§+ Lé'zzz®_¿îáááááqøðah­¢¢B¯×cŒKKKœœÆ=¡"!!á™gž!®M6lß&d-n`&--M£ÑxyyHòÄOÈåò‚‚æ…]CCC}}}JJ ­Vòòò*//ß·o_]]\.·m3 Zê &òE[‹xžˆˆhllÜ´iÃ0yyyÛ¶m“Édz½!tèÐ!ˆö|cMMMK—.ÜÀq\bb¢L&ƒ †Y¾|y``àÀÀ€»»»T*½zõêï~÷»pØ!±’Ée¹¹¹H½È—ðÍÙ³gÍ àY‹ˆŒoÎNà‚Ñh¤¡ƒÉõôCyk㢭%²üÉAô`2gd½Ÿ°$èD»C Ý„„„o¾ùfΜ9………¿þõ¯ïܹsöìÙŒŒŒ±àÐñyyyÑø¼a!=1¢°DV¹,""¢ººZ,“BЈÍÏ7«ì ß|óH$•Ú²eË.\èçç·jÕªÒÒÒãÇŸ9sÆßßýúõvvv …"66V*•r÷è£Â@÷ïßïààˆZ²d‰D"Ù²eËq´Hp2‘ÿ`ì°CG³ß‰¸:s±X X4>>ÞÍÍ 68Çqp­fÂZÜ0kÖ¬äää矾¾¾}à³gÏ Õjµr¹ÜÅÅE$ýìg?ëííU©T>>>+V¬ø×¿þEÒl8::>ûì³Ð#//¯úúú3gÎŒ70”§& Å%Ý 'Ìh]áÌ!&³(‰Ö®]:âíc#kqÏó¯¾újee¥D"A‚Þ ºßÙÙ-•JÕjuvv6B( à‡~ˆÏÈȰ³³#î<ÏŸ>}zÿþýUUU3fÌøè£¶lÙ¢R©Æˆˆe2Ö ‰'ãqɱF¬çH0i!‘Ú\Eh-n`YvéÒ¥Ÿ~úiff&ìËââ⌌ Ÿ™3gVWW×××ÆÙ³g«Õê·ß~[&“-]ºôÅ_ä8nÏž=yyy[¶l),,D)Ѝ¨¨O?ýT.—ƒaU¡Pü(ܧ,èBH,k4r±…¸‡a‚é<{ö,yÖh²[KÖâ†;wîÀà |O÷ˆ@spÁä–1òD©íhó¬ÑhLII™9s&Æ6¹µr4É? ¹‹ p:‘µ¯jŽn û[%Àe Ò-·`‚1eY–¸*­b -‡Ž…7˜¼4ÄêbÁ¿©©iôj ôDÿ;t°lEØš¸hr 96ién(k!Ë‘äa%½à ˜$ºq«§ZF§L™Bò7Á†02™,88˜x4™›Ú‚~૯¾êàà@viµZEÖâ¹\Î0ŒR©Ü²e‹T*ÍÊÊêììT*•½½½3gÎô÷÷/))ÁGGGƒRllì°ù”ÜÜܶnÝZ[[ûÈ#äååEGG#„FŽ‹¶ÌΞ= oI¾'6¿ÜÜ\n¹4†x Ò†ã!)>.úÚµksçÎ---…’c¹\®Õj{{{ÝÜÜà_Œ1i(((0—O‰çy(q¥J¥²¤¤dä<¬æˆrY¡ºà Öi¹p(?ØO`¿EA–þgžy†|¢ˆºæÇŒ;!kqôiÓ^zé¥äääÚÚZ¢M’J¥gÏžMJJjoo¯©©‰ŒŒtqqa¦··W*•›O‰a˜¹sçJ¥Ò®®.µZÝÝÝ­Õj+**ƈ`P ½=ù—ŒÃ0&¬lX"‡™62‘‘‘¯¾ú*=.6äÖâHù«Ñh$ 9â{{{/]ºT\\óôÓOçää¨T*£Ñèääd.ŸBèæÍ›UUU›7o†£éìÙ³iiicÄ Œ`! ^LÄm H ŒN0r´Ñ>‚l‡lz:Y‹8Ž[¶lÙ¥K—222à5233cccÏ;çààP]]]SSsç·ÿýßÿ]±bÅ©S§bbbX–uqqâ?ï¼óÏóÞÞÞÀ9æÍ›'•J¯\¹BpÃXv£Ñs,8ÑÄ—&Žß或‘ˆt;mÚ4LÊAYûª–‰¬Ë/)‰Þ{ï=†9Ž„èWBÐ…÷ߟ„èõzZR‚Toäì…ä'Nœ@cXñà6?…t Ñ(xì*BÆša˜'Ÿ|¦“È`Ö¾¤e² 7·Ã‚IþÂú »™ì*†aˆ ú½0Y”DKF¾¹w€˜¼¥eZ¼xq[[ÛñãÇoß¾Í ´mÛ6"Ø-J“[hà6~õͰ5¸\@¸­Fƒ¡#ß“ɹGv}­pƒoÄ<¯Gqo²Ð ‘H$‘H^yåÍqÜîÝ»!þ¼„…vX–íïï‡ qhëÖ­dÿòC\¬~$7nP(7nÜxóÍ7ýüüŠ‹‹óòòüüü †!+ÀÁˆŒ7àáíÁ{¿öÚkIŒ¨‚F`D@6ñh#sf“9 4~¸¡   µµ599™ã8HÁô /477cËyX¡óöööðŽËݦ…<šÏŒ:›‘¸“‡Œ»DÅzu[ÍÄxã___‰DÒÒÒ§ ÏóO<ñDWW—‡‡‡¥<¬DCÂRÉ4FÔýÒÖDñ(48Ǻ…î õÀ…u°k×.$€D†Ê h+šÜù”`A···ÇÇÇ3–ó°šœãê«h¢—?¹—ÌÈ6dì,ì¢h$r ýPÚ§Á¶Ó@³.~tù”~ó›ßnÈÉÉAn`Yv(nX³fM||ü¡C‡òòòB` tuuE‡•œòAAAAAAÎÎÎh$Þ@ëÖMxÃþýûá_ºÆÙ°\%@Z#ºxÒ²»ÅÈZ{€Ï‘r"ðVܬJœù*‹¼ù<¬wežçe2ÙÅ‹ñ(P+OùØ}Ê8$=¾‰h<쪄 A‘ˆ*Æh"ÒY¹è-ѸâZ•©, xpVZXgY*¿+ øÃæÎ;"o /M"'T5&£iy8h >Ddò¯m§Ö&;:?%‚L¾AÍÂ=,&¨û¡¤GŸ´,¦‚X,^»víÕ«W¿ùæ›±õ !TXXøÁÀ¦3±o<d-n0W/Ú××·¡¡A.—ƒWv\\ܺu뺺º”Jå°ñ ¾¾¾–ò)Ѩ¬’pä¡{!–e›››ÛÚÚ8¡N ­Ô¶¥Ñû)8qÂßß¿½½ýÎ;YYY ÃÈår??¿ÐÐÐ¥K—¾üòËgΜ©¬¬ô÷÷OHH€³}Øøžç-åSâ…ÔÓ!–eoß¾ 1 cëÏó>>>¿ûÝïÈ¡9ÚˆCcˆ‹¶^ôÌ™3Á‰¤©©)$$ÄÃÃa ñ –ò)‹ây~êÔ©c[ÂÀž~úéÌÌLü æø±7 „RSS«ªª .†K©T†………‡‡ó<¿hÑ"•J¥R©ˆB߇k!Ÿ-a!]Ézˆ)ãÁ°yYkoÀfêEoÞ¼¹¡¡!77W«ÕŠD"gggµZ­ÕjÍÅ7àó)xv4 ÒPB1 ó /ØVÌ·9Y…L|~pEy· ߀-çS2Y ÐÊØ‘Y‡ y‘x4¯Ê˜©Í 9 F€¡ÆtØød9Ÿ’Éù3¢^Ï Û^ˆ#¿ÂÛ#lBð£Ä HàêˆòMBCjÕÂL$×ðC"68kó)¡oH0ÀÑN´’HÀÆ—/_NIIƒLl²7˜«ûŸPPPpêÔ)žç5X,{ƒ9?% ù”†á £´7 %ØãP*™¶FÐ0žç,X0ACnžFoo0W÷Œ†I½h uߢ££!ÇqYYY¥¥¥c÷S2Gd.§M›f¢ì#R(Ù¿úê+„ÐöíÛmõh«ÈZÜ`®îB¨¾¾^*•ÂF×ëõ½½½`oÖO !4–|JÖa*ÿõ_ÿEsúü‰DwîÜ!»ÂÄÓpðußBgΜÖkjj,û)YȧdËÝÀ î-æ *uâ[o½uøðaËšƒ kí ÈLÝ·ÊÊÊÚÚÚ?ÿùÏŸþyTTÔwß}÷ûßÿ^¡P¬Zµjغo›7o†|J?üð¦M›nܸù”JKKïÆ7Ø7 „^ýu7Àç£G‚éˆ|Ðï Y‹Èe&FB·oß&ŸG¬ûÆ[•OÉZ‚æÐ`?{,3::::;;]\\þøÇ?2£v»'²7Ðö‰¡âBhêÔ©¤ûæê¾! 1ð£Ï§4¶¾ÑC”Ì ÿJ$’õë×ßß9@Vâ2 Ðp\¶zy‘ÄFOôxä–‰°@ˆÔÒ%Ï €G››.Y IDAT%kqƒ¹¸hGGÇ+V\»v ò°ÆÄÄlذ¡££#--­»»{Ù²e¯¼òJTTèò4 BÈ‚ŸÒ¸OK†a òüÅ“,ß÷…~|\t`` B¡8qâÄ»ï¾ûþûïnذcœ˜˜(—Ëe2Ù¦M›0ÆÙÙÙàÎÄ0LEEE}}}ffæùóç—-[–žž¾uëV777KõlE$:¶\.oii9zôèx?×Ù*.zæÌ™QQQõõõçÏŸÿíoëáá1vwwwww/,,„Îúûû———×ÖÖ:::Ú²^´µ‡#Xk}¹ººÞ/Ѐl1þ׿þµråJ¨­R©àü)..~çw¶lÙ"‹÷îÝË0̵k×jjj"""lY/zl=ñéAH6f-n`Y6""âÒ¥K™™™»wèÒÒR±X¼xñâ?ü°¡¡|–öïßÏó|ZZZxxøòåËûúú …N§³³³mÁOiܧ !¨Äds‡Ô±3ºø„Ðûï¿1¹° ®\¹‚(‹äädŒqqq1|™ššJ®|çw ˜x•JÜÑÞÞc,“ÉBCCïzÊŒkW‘ s…S˜Èg“7 ÁqÑCÝ@˜²Z·v,Dí£!~J åˆÅ’«áRe˜œ¡¤•1tM–ÊHz§Á*Ü€› èA”QÞcÄOŽL3| CjâYŠ1›4J܈3ý®c;OX–mlläy¾¾¾>((ˆeYP3‘d-nÉdvvvYYY;vìX°`Z­îêêÚ³gÏ­[·îܹóë_ÿúرcöööeee<Ïߺuë·¿ýíµk׊‹‹.\ȲlaaáÉ“'¡Ê€…<¬÷2„ÀWUU………*)88ØÎÎÜ,FCðÞ¹¹¹ô—pJΛ7ÏÚ€¢q¥ÑÛ þ ¤¤dñâÅðÍo~󛦦&N7wî\N¸á§7ß|3??¿££#11‘ã¸îîî   àà`øÖ¯_ßÒÒ¢V«?>ÈÞ`²ÞoܸÁ²ìáÇõzý/‹#~7¦¡;wŠîk~Vkqƒ““SRRRbbbSSH·wîÜY¸p!Ã0—/_o%±XÜÓÓ£Óénݺåçç÷øã·¶¶²,»oß¾äää·Þz šâ,çaÅT}Qžç¿ûî;Žã®^½J»Á‡1¬b¸4°·D÷5EëØü”4‹‹ °\N×ÓÓãääD¤^ŒñåË—/]ºäììüå—_J$@sZ­¶¾¾¾¦¦¦   11q„<¬&#ÒÛÛ‹rqqyüñÇÔ8¶£o$e‚î#Yë§Äó<ŸÏÈÈ7'''>>~Ù²e©©©ùùùMMM))) Ã(Šwß}wÅŠIII Ãh4^pófFÌÃJNv†aÎ;7cÆ †a/^ É…wìØº¹½à½MxÐO<æCnHJ¢‰'«ì ؼ“’I;Ãú ½—œX èÞY„( TçDF½¶^¼ÁBZ$„ÉãpÉ*Ü€… <–Jgƒ¨èÒŽhpm1r¹ØRVÚŠ~Ëa_n4ç’‰Û$AXðj% ŽvæÃ™î.@kâȈ£!ãC†ŽŒ,Ž“n’ÄÃÄ7تoDä½sç sX!s,ì6ÒË—/oÞ¼Â%açñ#kqƒ¹øžç333!%p…ÄÄÄ+W®¼öÚk|ðX,ÎÉÉ©®®fYöÀžžžß}÷ÝK/½Ô×ש)[[[U*Õµk×îÅE“uQUUåàà€Z¼x11Jxz’ñeY–ľÑÇîc=‚ä­VûÔSO‘ÞN0ë=nèééqww/-- †åääh4šžžžˆˆH;„1–J¥ƒ¡£££¤¤$,, î-..6åååO)66¶³³“¸l)ŠÚÚÚ»qѶê1 ’¤ª<û?eÊ^‹ƒõ~óæÍ¦¦&±X ¥ŽAÏA ûø‘­â8Žóõõ‰Dõõõ¡¡¡^^^b±ØÕÕÕÕÕõàÁƒ!£Ñ¸nݺžžHzfŸÕ«WO›6íïÿ»““85!ÛÚÈA‰‡èLX–}ì±Çººº¦M›F ¯0aà7Fk®lõJÃÒØpðñ àúþÔSOíß¿_¥R‘6§L™çž^¯_µj•B¡œ‹‹KuuuNN¸Ú÷õõõõõÍœ9Ó–ö"€8dÂa7˜xl\ܤ… ÀtÖÚ0ß T*B………¥¥¥ÎÎÎóçÏ?xð V«ÅOŸ>=777$$dË–-µµµK—.-++óôôtppøÏþÃ0LJJÊÆ###§OŸEâöìÙ£P(Bwã¢mÂH  Ä=!„ 1(PEE©6ŠG ¢¶-Yë§„-Šÿ亜ƒÉƒè˜ê¡Oä,׋¶Š°p(ÍŸ?ŸpcÚÀ@äe¸ž¤$¦y ž±Õ*ÜÀ˜‰o€î:˜Jû.¢rÇò”ë"‰†éDÔ ÙØO‰§r.˜Àb …oHϱ·;f}‰µ£fU|ý¶ •¹—d:é+Ñà™CTlÚ„&ÀO Ð#|¦óÔcà8.$$ÄÞÞþÖ­[à÷0Þ’ëì !•JµeË–… ~õÕW`uˆˆˆxê©§æÏŸuß `ÃÕ«W•Jekkkyy9B¨¨¨(///000??c.++³³³kiiÙ·oßݸèqí31òôööÊd2تßÿ=H)ü1\F„o½ŸÒÉ“'}||¾þúkžçsss÷îÝ[\\ìååÕÚÚºyóæððð·Þz«ªª*00099™çù––`û'Nœhhhظqcss3ÊÚ·oß¼yóà×ÌÌÌ”””»qÑÓm²g!7#$@3 »wï€q!Z¬ñ£1Ä7lܸqõêÕMMM°Yãããóóócbb ÐáŸÿügDDÄO<ruu•H$………Ä=’çyww÷ÎÎNOOO??¿òòòèè膆''§ï¿ÿþ^\ô¸öc,“ÉΟ?ïââ²fÍëK—.•••!„222F“ËVd-nÀ§¤¤TUUÍ™38ó¢E‹ÊËËûûûÅbñ‚ öîÝ …Õi@¸Bkk+8Âdee‰Åâ›7oB˜4D¦Ø7X ÂÁæÌ™³{÷nà ¹¹¹`{‚#ËdtƬŠÄ……}þùçÛ¶mS*•EEE3gÎÌËË‹ ûúë¯?ÿüs–––öÅ_Èåò³gÏFGG-X°ÀÝÝ!´zõêo¿ý–RwíÛ·/::šeÙqÁ UUU&B1ÆxÛ¶m!¹\Nì¹¹¹´t1uÌ‘µöúbPDÒ_ÒAѼdÁ&Ö'Ù7˜#V¨5‚àaøv7ŸÈ¬ÖÚ¥Ä …z°€ L¢‘ÿŒ©ehpZél‹°`ÞÚ%‘PÚüDIº·#@Ü@¿ (™?2”´\û†r‚ø‡©àÂBH³¶Ô°"„Üg(ï(£K³T|\XXذÞp6'[ÙBþþþ‰äí·ß¶··ÿðÃÅbqww÷ªU«t:]AAT*-..Þ»wï‘#G‚‚‚Äb1”;|øpppphh(Ã0c¯ûfŽÈú²··7ÙéxpøN'˜³°°0(rƒ2¶¶Œ‹&b2Ñë!AH†L§ EBÖ\¢übæùçŸÍÁ¸’­ì ÍÍÍ¥¥¥¾¾¾ðþ ---ö âðÈZNNNüñæÍ›÷íÛgãêé!p4 iiiõõõŒL¼­­$³‡õ¬244”¬°6Ç;=Ÿ­ì ³fÍÒjµ‰ü” äÞÊ•+ EAAÁ›o¾‰Úºuë©S§Nœ8‘œœœ˜˜˜––vêÔ)''§ÎÎN(¸råÊwß}wø¸è1ãèLeeejjêôéÓÑ`„Ð’%K€1F°’„î¡sçÎML"&›ØÈít#&V–¡IXM@é¯yœHŸ}öÙ7žyæ27.\ î€éY–5 »víÚµk—‰|\‰Èš´ÈhŽ70TšfâÒÀPyœÉÚ¼DLñ¬Aƒ Lç µyßÈ7‹/Þ¹s'é'ɵKrɻ۶m€û‰Qf Áfó‡—ñ¥ º‘ñE” h2%Ä@Dd–ñÅ Ö¬}";‰D¢_|ñá‡ïçZ‹,׋þá‡N:…Љ‰ILLìèèP*•mmmà½úðÃûûû_¼xqçΛ6mšÜ`-1TìHñ_~ùå?þñ‰yú‹XµjÕ_ÿú×S§N•••ùûû'&&ò<ÚÞÞŽbYöôéÓžžžkÖ¬Aƒ¬%¢œA ìÞ½›’cŽ÷s­Â â¢CCCAN ?>ÏóàRøða8”jjjfÏž&7XKp&L™28öÎ;G#Âÿx²7ðf⢆éììŒ]´hÑ믿\²‘G¼ÿþû‹/¦[7Ü7ÿjX`9o&Æ’Æ £‰o`ÍÔ‹ppp¨¨¨¨©©¹}ûö#<¢V«kkk###kkkÃÃßçååÅÅÅASiiiÅÅÅÛ¶m+..–J¥€ÆX÷ÍVDÇç"*ôÄȬèGÇE#AFß°aBH*•Âzg$Ô†ÿá‡XÁ/_¥RíÝ»—ĉêt:žçÇX÷ÍVõ†È‰ÌRÅÆ›¬Â È|½hDå…Á¥dJH(÷††Ã ÷\ìAÃ314y¦2ªãÁ† òÙæ| Øèý” ìã! e•d%^ˆÉ¦?a>t Ú»páìBâ!Ì“è#ÑøäØ%nÀCÂB¢«««£k6lØÀ0ÌáÇaU™Ã "‘ÈB>%1¢Bh¡à³ÍYâP mnnþë_ÿ ¯ ?++ –ùh!ÏV¶ÖÞ€§K"3GÔÝô–"lÕ7‹‡­û6¨¬$¢ðý%ÙÅ£Ž{d¤~îîîÛ¶m£»®¤Žm]±!Yko ðž°1âeBÃO2J´uˆt–Œ»‰u.»×ùÁÄ£‚J¤¢‘Fžñ?ÿó?p‹…~²“¤^tdd¤ÑhÌÍÍMIIñóóS*•Ï=÷ÇqR©´¡¡!<<¼¢¢‚çùÓ§O‹D¢öövµZ=l|Bè…^¸råʼyóòóóyžÿæ›oöìÙqѦå÷8Ž#1„D–@ÂXàfÄgíòåËðaĵf—H¯««Cƒ“üÚüœ=n())ñññéèè‹Å {xx:t(''Ç××÷Ì™3ååådO›‹oH$jµÚÁÁ‚pE"ÑË/¿œ‘‘q7¾;ðT£Ñ8eÊ”›7o‚Ç£H$ë×#L!è{9rõêÕÑ&Ì_/ÚÑÑ199yÍš5HX[ñññPý T¯×ëõzWWWÈÃʉoðòòš1cÔâ€vÕ}#C üù¡‡úÅ/~ñÉ'Ÿ,Y²ä“O>á8Ž8¡Q¨?wìØ¶½®®.ˇ/Ø ËáÈzÑ ÃlÞ¼Y£Ñ€s<ÜõöÛoWWW«TªM›6‰D"–eµZm]]]zz:2ߪªªR«Õ&<<\§Óéõz'''žçÅ´X‚2 pVˆD"HäL³£A: ‚=d9†hòÔ‹~öÙg¿øâ‹ÔÔÔììl±X\PP0kÖ¬²²²gžyföìÙŸ|ò‰\.¿víÚŠ+´Zmjjª¹ø†ØØØ¾¾>GGÇÍ›7#„Ôju\\Ïó÷ò°b!sÏó$*h™ ܰ¯Kµd/±¼Hç-Ò²#&Fp[D=JÜ ‰NŸ>©¢Žmmmðžÿú׿ŒF#”%k¿²²ì‰ãÄÄÄäädÒ¯’’pAXX˜\.¿Û;D9wÐÅBD8¤…Ý@vÏóôQ6,Ѻ{L%¼a2—G7¶£"²ÿÈZСÁà—$ý‚÷7130æã`y¾ŽÔ‰#ò§i’7òY•<`m¹{XpËéïï'}39*©(3êE½—´@¾¤EJLÕÃCÕ!…l²‡ÆÝúç/¼V«•Ëå㤳%Y‹,ÔoX¾|ù7Nžþøã“²6L6ôS’ÉdZ­ö‹/¾ˆˆˆ˜3g˲½½½ÞÞÞ^^^ÀÆ-ZÔÐÐàçççää„ÊÎÎþÓŸþtìØ1†a<==›šš***†™?%^(a±GãýÄѼÏèqƒ9?%žçÛÛÛãââ.\¨R©@)éààÐÕÕuåʤår9ÌúçŸÞØØØØØxøðáÇ{ì£>ÚºukNNÎÄù)aŒé$¬÷ñDbmä§8kÖ,FsùòežçgÍš¥T*ãââÞ~ûí?üáIII?óóó ˜x!`` ¿¿?((`Ýù)Ð&‹i­ä}dÑ„F‰E?%Œñ†  Caa! ÿÊÊJØ+pMOOmGÐh4d#öõõaŒÁOi܇ƒRìÑúóñ~¨e² 7 3õå<†„,Ë’8\{ àópOOnÃîÀA÷ ^”D\ÙŒ¬Â &×€ªÆäKb 3h™˜y!•‚_Eƒ³ÛÙòP"z'š À‰dggWTTôÖ[o «AšH²n˜1cFLLLoooii©H$‚¸è7nDGG[/Z"‘LP|#dð¥7¬ø{ìØ±ìì쎎HÞóÀ O?ýtllì‰' .–×ßÿþ÷¸¸¸•JUTT4kÖ¬ŠŠŠŠŠŠ’’’´´´‰ˆo {ìYàTðo[[[GGÇœ9sÖ®];¢p2®d+Ü0}úô°°°ÚÚZ±XÌ0Œ^¯ïéé¹~ýºT*5W/z‚âàœ¡Ý,DBRn` ^^^»wïž07ÙaÉV¸A$µ¶¶ÆÄÄÀ’úì³Ï¾üòK õ¢ÑÄE³BbI"˜;vììÙ³  …¨ybO½j%kí ¬™ºo©©©Ï=÷œF£Ñjµ×®]ûío»víÚøøøaëEƒZi´qѹ¹¹K–,AcªMè™gžAƒsÛÀ(31Áψ·&.c|çÎøÀ )>Aâ¥IƒæêEóMýÂ… Gíèè PYYyñâEâ–c«‡Žˆ´6?%d&¾6Òvâr¢9H®äÆQÅE‹„|­cî¡çŸžî!ÏóçÏŸgçmËÝoÂÖø)Ñ.F&`h°  ö'£³Ã›0!bÚ‹i$G•Œ´Mv{ƒåú W®\)--ÅÇÇǯ]»¶¯¯/..Μ½!;;»ººšã¸¢¢¢¤¤$±Xüá‡BÝ7±HÈKÖ…m“&Lv{ƒ¹|J¾¾¾111•••P]/ `ݺu§N²`oxøá‡ËËË«ªªJJJd2™D"ÉÌÌLMMU(b²›*§ŽmÇhRÛÌåSÂ?õÔSãK—.EEEÍ;—eÙo¿ý6 Àœ½aýúõz½þÕW_}ã7¾ûº:ØþþþbbYÓdgüxšìöd&ŸRhhhdd$Æøé§ŸÎÉÉÉÎÎ6 P¦bX{˲ׯ_W(«V­züñÇ CUUÕæÍ›Õjõ]ܰxñb( 8H?cÛÎcA¹O…m1J²7`óù” °çÓO?5 <òÈk¯½–˜˜SXXXPPmæçç···CÇÝÝÝg̘¡ÓéB ÍÍÍ111'Ož”H$âàààO?ý”+,¤³a·'»½áÌ™3d0 ÓÞÞ‡*Üž€òóóc…”EÃÚBÿùÏà@†é‡2‡wí .\à8nûöípð†Ä†¼a²Û‹õ˜ÁqÄÄ5f¨½ NJ˜Š !÷Þ•XvíÚ…}ü€)?}DÙ+ȯ&Í13LR{²X¿\câ·Š¨HN[À8µ¹ØÄÄŒ<æðáÃûÛßúûûAÌ€˜5Lù>àd-n°P¿„ÑÒÒR±X¼bÅŠÄÄijgÏfgg߸qãÀ‡µ  à©§ž‚÷o¼ñ˜£9òè£þûßÿV*•P¿áîÃ0¥S")ö–,YÂ0ÌöíÛ‰êãèÑ£sæÌABD‘HH}6žã6.Dü™‘ê¾éõz77·S§NÉd2ŒqVV–D"),,”H$`Ò‘ËåF£\ä»»»1Æ%%%YYYãððpŽã’’’ZZZ0ÆPL£²²2''cS3rÝ7‚'X!Ƥ££ã믿†üÿ<ÏO:6ÚýÅbVÑ⢇­ß§}}}TTdüœ5kˆI/½ô¨óX–usskoowuuMJJêééIIIQ©TÇõõõùûûãë7€üÊÁ‹„)¹»»ƒ Þ´W¶°ñ!kq6S¿aƌӦM3 >>>jµZ­VÃîIHHذaCddäóÏ?SÞÖÖ¦P( ´w\\\\\œ§§§H$êîîÖétÎÎμ…ú ¬i}ôèQ{"‘6—HÈâLüÎ*²70fê7¬\¹2ß644ÆiÓ¦½öÚk...‡ÂCvŸåË—šóððxä‘G †èË/¿ ñ cOOϻʶmÛÞ÷@ÄŽ&‹ƒ‚‚¸Á G'Yko /&õx*?« õ÷÷“ àzò“² äƒÙÝ ‰4Í‘#G:::ˆ4VYYyþüy8 Èü1ã6;~d•½ξOû~!Ê…\Ïó<$ÕÎJ®‡[b`©üQ,‰‹J0k×®%ÿÂd@:U“gO¢9@VÚˆÔOw™LŒ‰§™Z©F7B·C ƘÄEK"*Ŧª­ò<ßÐÐѼå•vLzÀÉZÜ —ˆQ*•[¶l‘J¥YYYJ¥R¯×?ú裋-*))aYöw¿ûÝ /¼ÐÑÑ¡V«›››+**X–?%ooÀÂÂÂ÷Þ{ïÃ?dYö믿޹sç­[·,ᆭ[·šœhƒaçÎ&ÜÌ$Pg²Ðèqõk׿Î[ZZ ŠRŒ±\.×jµ:ÎÅÅ…çy¢g½}ûvkk+¨Tá^¸eëÖ­P¾µ»»ÛÏÏ/$$ õ¢¡K¸ °ä¥amß¾=((ua=;Y ƒµ¸aÚ´i/½ôRrrrmm-ÁOR©´¢¢"99¹£££®®.,,ì±Ç›:uª»»»»»û¡C‡Z©T*óóó—,YBR lKz½ÞÛÛ›a­V{÷aCw$F…Y%¥]y¡°ÆxX„Ÿ8óIå-,p¸7$$D¯×çääxxx´µµ}ñÅÑÑÑXðÀC/ÆX§Ó•——C‰7ŒqxxxXXØìÙ³óòò0ÆR©T§ÓaŒ{zz,±hÚï ® Ãó<­³µÝbw²7p÷›ßüæÒ¥KO !”™™‹rpp¨¬¬üÇ?þqëÖ-''§}ûö…„„À^^^cgg·aÃGGGŽãÊËËa:A»§V«W®\‰-ãØ &bØ55‰¶µ¸ö=]ó™T¡€ †ò“ýGŽòtÎBÝ7P²W;•ÌQb¾ßƃ1Uö,Ø `௠&09ˆ x½Ð– :o ¦ÓpÏI°K“ohA›„'h@VÚèy"ó7ô^ÈÐFC¦Ä}ú_LYkÄ´¯ 1M „òóóÏŸ?ûöm2{"*Çüä%kqƒ¹<¬qqq6l(**:y²Å ˆIDATyò¤Ñh\µjÕóÏ?ßÙÙ™žžÞÝݽlÙ²W^y%** Žˆµ‚¤%~~~³¯««kÏž=7oÞ4Å ööö¹¹¹AAA´¹˜&£]ÁYeoðôôÜÕÕ¹•€ÿÐÆýÃEc°7 ›‡Õh4BÖË—/C¬¹H$š3gŽ‹‹Kaa!œ+þþþåååÅÅŵµµP8;;ûرc 3ýî»ï|||Bƒpœò¯½öÍåñpîÇ“šÆ€xž—ÉdD,üðÃU*Æ8""b``@&“Õ××nÀ„‡‡WVV’§dddœ9s†ã8NWUUªÓé`’z{{1à²Àá/©#JOX±e{Rµ¸™ÏÃzéÒ¥£G666r÷ðÃgeeM›6-%%%<<|ùòå}}} …B§ÓÙÙÙ‘h°‰B*«œœœ+V°P/ VþùÏu9½È’™taX² 7ða*L„5˜XÈ@™DBðTp2Œ÷p+¤$6àÁ‡K¾Hàã»V'„¬õS¢í •â~"±ÆD¡¾ÒdˆIS *ßñ‡æºxH¾UbtCB¶¦ŸÁÞO Š1À`»Ñnð÷`lé0rõøº§…V\\\ ƒôäÒž¬Å êEó<WZZ:00ðÇ?þqݺuz½~åÊ•z½>??ß××7""N{H/œœLò°rGçaEh¸,§“H£Ç ===à gzNNŽF£©©© Çn?¥ÂÂÂÂÂÂööö 6`ŒÃÃÃzzz€1@’ ©T -¯X±¢¶¶öž½¨Q9Ž[½zµ››žT¶e«ÈVñ ŽŽŽààÝÐÐåææf4Á„àææÖÕÕ…1öññ)+++((hllttt´‡uPg„x¢ý„i ¸Áh4‡{³³³+++ àW¹\~é񴯯XŒq~~>xÒ¯_¿ž\Ÿžž^^^N¤R©ÊËË1Æ>>>ÄÞpwαÀ¬Î;7Jõïä%Ä`h,ÃRžç#""ÓÒÒà777(PPP0sæÌººº 6dggëõúˆˆooïúúzŒqLLŒ\.'ÐO¡PDDD( øW£ÑDDDÈåòääd†8¯Ö¨²²rÉ’%?mÞ€縱|übÊA†È¸xˆÓìÀH>ðƒÓƒÒyX‰XÄóü]ßú1VIr“‘¬Å ÃÆ7 A%™V¡†1;dX¡`ì$³yX¡¢Oeïÿ©òg «âx*U'ä[%.I˜J  ÄSEXH+†JþPŽ¼Ã½‰‚¯þû¿ÿ{öìÙ?Ý‘9úñö†¨¨¨ßÿþ÷k×®-...))ÁÿáX½zuEEÅk¯½öÃ?J¥Rgggÿ†††M›6¥§§=ztÁ‚àºÑÙÙ¹k×®{~J´àOµ™Mì Ài—.]Êqœ··7Ƹ··—çùãÇÃàžäêê žãäää¶¶6žç£££ïâÂúûû÷îÝK N¿#kÉVöŒñåË—,XpñâÅeË–yxx „¦OŸ^\\üæ›o¾ð <Ïûøø466úúúΜ9 øÌÅŪjôõõ-Z´Ñöñy”Þ;“‘lhoo—àààÚÚZ…B§ˆû‘‘‘`CKKK;tèÁ`ày>**Šã¸7¶¶¶bŒýüü`ßõS‚”`ˆªIø>šleo(//ohh(((øê«¯0ƳgÏ~ýõ×]]] ìììÖ¬YRÓ¡C‡ZZZ€{?÷Üs¾¾¾...¡œœß0Lž ò~ã< ÷°•¸>9‡|€/!Šˆž&7’ †¶LR‰ð<OÃj‚PlÔå—øÑÅ7 ðàro&7’Æ ŽöÀƒÑùk’Ð讽Ȱ×aÁdÁQh#Æä%2¦ØJ{ƒÉ ÐN`CMˆÂdly**‚£ªdßÛ $ƒ+½³ÈÆ)..>räÈ$ 54G¶Â æêE+•ÊŽŽŽ>ø@,C%–e8àééi 7°BB+b_%á]D(**ruuý)q ›àƒÁ`4 øúúbŒ[ZZJJJÀI c\\\l4ËËË•J%¶Œ0•™VTqB)m„Ð7ß|ÓÙÙùÄO$$$Œ~#?˜d+Ü€Ì׋>xð BÈh4®[·®§§Š:"‹¸AŒ1ž:u*Ô…¤3ùIŽpŽyóæAY· ²ñ Ò)©²ª^4BhÊ”)pîéõúU«V) °¤öéêÕ«+W®Dõööêõú{qÑýýý€,€7ÐÒ0“ææfÞbÏID6ôS²P/zéÒ¥eeežžžÿùφIII±„L Ñ&ÿ‚J!$‰/^¼8nã3qd+Ü@‹ªtk&FdfÏѸAl0vïÞMBDiÐ@´²üñ¹sç¦NúÓØÄZ0Ü@†˜\o ø!õ¢ ˆážy‡Â ƒR’X€8Ž–°dÉ’/žD¬¼<å¾gù"Fš\LP‰N  Åv÷ÃTD!¶• óO&¹©©)$$d²ïú)ùûûK$’·ß~ÛÞÞê7twwÇÇÇëtº¢¢"ooïÞÞÞ7êt:•J%•JMpÃ×_}7Œ¸v8ŽÛ¾}û„ ÓÄÐ÷Sjhh A dQ´µµŸRtt4ÔŽ†¦,á “kûöír¹òÈàÿÏpƒ?%µZM.Óëõßÿ½N§“J¥‰¤µµ!TYY™””Ä0Lii)Ä7`s¸ÁÜ뉖k“ ßüd?”Æ€†ÍÃÚÜÜ\ZZêëë ‚eCCCcc£ƒƒC[[[{{»»»»Á`˜7o^EEENNN]]L&³€,J4ÿá8ŽNB3©É&~Jr¹ÜÉÉ)??Ö¬YáááÞÞÞ*•J§ÓÉd2©T æÏ‚‚‚°°0ãøùù%%%ÁHBñî»~JØü!CäW"áŽfí<ø„mä§D9!˜Vk›´Lã³è‘n‘Øæ~s€lä§„d€†ÌO¥:§ç€§‚v n€fÿ8YŸñ¡<ÉGIEND®B`‚cluster-1.52a/html/images/hierarchical.png0000644000100500010050000001163707555176442020475 0ustar mdehoonmdehoon‰PNG  IHDRá|wДÄgAMA± üabKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÒ 6™ÞIDATxœíݽnÛÈ`é wq—ënË-ö2¶Ør;Á]ʹ .ÝY¥Ó9€s=9…Î<üÓq>Rσ )rf4þôzHÉòþýíu@Hÿ)=zÉh€¸>”C>~ú\zÙüüñ½ô`}dt\?}ÞR®ýõ÷?ß¾~)= X™ÔŒ^Ë‚®jksŸ-ôn·ûí·ßþúûŸ———Òi*[3qz'¦¤Œ^Ñ‚®Z¬­hÌÖþ¦OÀoJÙš Ò;aÍp]awZ¬­kÌ”U¶f"ô¾|¿¤ó¾Žõ¹¹½ëü²±=o/£ÚÏ;¸f2z;.ýëH~Ý –7ñ}…ÒûÛëÍí]õÿä¦HN~ÕáÕmq–èì·#qçË©¾­õ®;¿×ÙÜ~– ô>¿;bšþÞ»F5Ì©•*¯[¦»èLÙR5Ûˆ•Ó—cïªÚ¬ïзgç±PÿNÕþbÉØîhÉÞ‰ Öû£ç,cSÌ\)§[à ÜÕŽ•jKß]ÃaÔyogûyu£¯\ÍN“ò¸–pcæEöödËè¾ï ·”6ëÇ4;sä/µÞètBe }çÝ}[Rîj7~vHóhl¸œ]ËWßÇö>ER¬`׬ÚôŒ—õWz™ŽZ¦ ¸j¤o…˜rxñ’Þ]Ã…Vyó›í{ì×9êï`IYË7nô]¬Pï4峞ü£hxµÍ6d»ÝgNÌ\æUUÿ„'@©2íé:áÇÞí3°]Bu¥œ=4™öÌòCtrñH[.~=zr‘ ¬Î&/Üfâ´EÊ%ÈÙAV·ûîJ?êìžͦ¸ïKßœ7¶$ÎäËÌ—z‰‚U[î5Ô½\·[Nì«qºšøL»è³±b}7Ú_ιkà:õÀ±)æäרUÿ¨¾r}'tÞònð'kw‘Œ®ŸÙ¥¬Î:÷i¯Î:›Í2Ôí7v=±Rð¬Ý@~õ­Ië÷¦Ìdã;˜>ªÆ0}ý‰5­ë”!µ¿d{ög‹f]Ÿ}ñøô|<_^^&9Èd]Óžâô­ ø >ókfí½ü¦Pñ»àqÉ見h€ ×Ðõè­~ÌüZlòztÀ¿ÃÜßßw¾0pæ}‹ úóßÿüãwmOÏ}w¹Ö—ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’Ñq}X²³›Û»êöûÛë’]C¢›Û;ÅIËet£ô=Î*v­C@ÐiéP?ჲB\¾¹½;ý«¾¬6öíÓÞ.¡*³F‰¶+¶qCq’EÎkOÏíþñ{cKU»§¥tý¢Gu»q£½O{ÏÎÞÙŒÃáðóÇ÷™ —hUK’¸ÑyÉNq^§,%Ú–ùzôáphliº*ßjK{ÅÑY÷NO€jÏv×lÆÃÃC®¦RJô¬á5²â¼BK´!ÿk†*>åÚt{ŸÆbç?ÁؤRI¹@Ñ8«ëÜGq’K™ëÑ}•ø ©þ÷ò¹T+ßê_ziv®_âØ)N2Yî½wõ’¸rl}‹÷‡°°¾ð­_­Vœä²èï°ÔK¶ïvß]×:ò‘kÕW`x¶ö'¹,šÑ°=–Ì\”Œ†Y¤3âwXè$£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸ŠýÍÙǧç³û‡Ÿ?¾/0hS¢DPòï‚Ç{¿}ý²Ô@ ›¥¸’½Ûí^^^úîXžÜÜÞU·ßß^O[N7 /%JY…3ºÓ~¿ÿõëWß½ZUúž'd¡DYL¸× ÷ûý¨ý4 S¢,©|F×+~lõ7ÔO0«Û7·wÛûvƒŠ¥ ×:NgŽUõœEŽU9V7ÚwA›¥”½«-O2Vÿn·{{=Õw»¸-IE‰RDùŒ¾Ðò¤R=ÚÛ³÷Å&)Q *=z÷oÝO«þεFýÞîßçÀ¨ N‰RJùuôIzõ7ª¹¾Ö¨îê¼±ûÿóʪ«R(QŠ(™Ñß¾~™ö{´g…7·CE‰R\±Œ>¥º†J”Še´O¢!8%J!^3 “ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸V™Ñ7·wÕ¿}Ò[Ë4.ø%J.J`´›Û»÷·×¾//×$R¢d´Êut%8%Êë[G÷©ÎO‰ÆöúÒ£½Þi´PíÐ×8¤S¢L°Œî,ërOiáìsÒ)Q&(–ÑOÏg÷9?|Olðìë*g 7ËË;l†%‚’ëèãñ8pï·¯_Ò›j¬#& f¸ “ë¤D)®ðµŽ———¾»—'égv}—öFq"ym”(e­ïzôûÛk½v««r]ßÞØ³ÝN£…Ó–÷·×v#0@‰’Ñú2z×S…Õ—íw¥ï ‰”(¹¬þýÑ&£â’Ñqm9£û^÷NR‚P¢œµåŒNÅS‚"”(gm9£Ö®ä{ï¾}ý’þ{´•ú‡È´oœöéÛ¾«­\ª· ¶›Ýy'»ÝN‰@±Œ>yLùœšê™Ð~òô=©¸ZJ”Šeô„åIÝ©@'ÿîl_q×qkÎðØ%J«ü=Ã>Yª¶ý¼‚\”(c­ï5ÃzöëäÁ;?'FQ¢d´utßÇʤTsû³i,RÈN‰2Á*3ºQß·ë_ö½PÞ¹Òg>%J.«ÌèQ:ßÕq(Ql?£=Á)Q¬ï5C€ë!£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2ºÃÍíÝé_}Ëðþg÷IÙ¡o·Ä'ìÌJ)Ñë!£›nnïÞß^Oÿªbz{8døÞÆny ´ÝZâ`X/%zUdôRÅ”¾>âÊ)ÑÍ“ÑIªSÅê³~¦Ù¨ÑÆyhýFk‡ŸIçIng/=Ù0%ºUJ œáóÇêd°q£½OýÞÆ>g×>§1Ôÿo4ØÙx½ÙÎ=Ù%zUdt‡™¥sÑuÁ„ÆUÿö(Ñë!£3k¬&·S­PÚÛ§”èڸݴØÕ±S‰O>ËK§ë}£D¯ŠutSúû™Î>°CçºöžgÇ6°–™ó(ˆL‰^•ýÀì|üôùçïém=>=‡Q‡\9/•$ÊUZJt,%šhfi=>=Ço_¿´ï²Ž.ã´‚Pý„¥DƒÑe(}‚S¢AxÍ . W±kOÏ¥º&ˆà/ß)Q"”hÉëÑÇã±`ï”Õùv4Jôš)ѯ¾¼¼”¹ŒZnüõ÷?—I^Jt3VZ¢Þ×A6?}NÙíáááÒ#Nk,QMNÅ/ÞÁ°Õ•¨÷uÄ(£÷53Û™¹CÆ£r9õ^v (Ñ™”ñQ2z¿ßÿª¹Äw±jóׯ_ŽpT»ë™.43¤Øv‰&v‘¥e­Šˆ_¢‰})ãࢬ£××N?Šû®ÓõXß§óÚ_}å’ÒxJw郸òx¶eŠ[]‰Ô2^‘(½ë©Œv´·§ìSßÒ·Ã@›ÃãLigZ§ë:mܼՕh£µ”®‡ûRÆË z­#š kýåO• R¢)”ñ(ÖÑÁE¨ªcêÓ®Pðò¨çKTF“GœÏÛ…N+-Ñ’ýíë—Õ}N }‚üÑŠ¼”è–¬´D‹eôáp(Õ5¤P¢DP,£-ON‰÷uÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄõ!osy„¼”(ë’3£‡CÆÖ ;%ÊêäÌèŸ?¾gl ²S¢¬ŽëÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’Ñq-šÑ7·wÕ¿jKÆÆs5•±—eFlÕr}s{÷þöZý^);¿¿½Î]†dWìZÇE#`rþÍÙÉNKìÆíÓÒµo{uWµÛi‡êÿƱU_õŸ õ¦úi slíçLÀIÎŒ~|znoüóß'4UOäÓÆ—í»úŽmgk]£ÙÎC½œÝ¹³ÇÎÉ6ãp8\âÏg^G‡Æ–iƒ®’®}Iäì5ËU”^¦µßž`3.Ôrþk¹~’4¤õíYÚ?Û{Þ/ñؼb¯v.TïÉ~ûGÌ7Ûd´Ük†À­/Të/ÙµoìþÿÒGûºQýŽ=¤1€ôGõÐi?t?}u†þøô|¡«æ¹ôå,À3Óïñéùx<~ûú¥}Wˆ÷Þ]Tßâ ¾íg´\ÖËg*Ä%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’Ñqû¼ŽŸ>—ê:¦ûûûÎO½ª˜±36–ëìŒ- äg*EþÓ…%þµC3V1cc™±±‚ü R×:â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â šÑ7·wÕ¿ì-o9}Ù×oöñ\H{öÒG~vÏUOQÞÒšÓÈꦱàV7W•ü]ð>7·wïo¯}_¦Ø)±©ÄÝbªÏCu;û#ZãM.­™ Xã4–rst]wߘ\ÌÞ““îôSgÛ+Ö˜"®£ûTõqzjÕ‹¦±l¬oìI(¾ôIKóJ§(¯ÁouëKÚ”OÆÁ¯n®æXSFùA×.Ê” 2øQ&ùz¦¨20ømLãäô¬¿èàCÍU^+xͰ=ÅÅú½ÏxñdÁgïbBƒÁ§èrÍ_P×E˜ÆSÞÕÿÕ¯¤õ]%˜ÙûJçê"®£s]¿VßÒw`ãšTçQs¾¾ÚM oYæúLzw}S1̧hriUΖSãºí&§±Ï@ïË ~Es•n?0¸Ÿ>úÃ9OχÃ!ñ±¯TâkOÏÇãñìßš»ôŒyådZ§Ef,ò+KgǤÆ:-<±Ÿ•õÓÓoT_×Ñk×^©EVd´ëš¢°V= ~½s%£ó[Wíº¦¨mØÑÆ3ʃ_ï\­à5C€«%£â’ÑqÉh€¸d4@\2 . —Œˆ«äï°<>=ì}ÌØXfl,3M±Œ¾¿¿/ÕõJ™±±ÌØXf, bøI%TÌØXfl,3ëÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 ®ÌŸ©ôðð·A€k–3£‡CÆÖÈ™Ñ?|ÏØ®GÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 ®Ãw?>=/3Ú†2úþþ~±qж{-=º¹ —Œˆë¿ 7FíLRIEND®B`‚cluster-1.52a/html/images/fileerror.png0000644000100500010050000000433607555173440020041 0ustar mdehoonmdehoon‰PNG  IHDRGdšdegAMA± üabKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÒ :&_É P[IDATxœíÝÛoUðߘ†7”`4˜H¸ØíEhíŠF» "h‚(HxñÑ'±„‚ B`­E[ ðøfl´¼áJŒ¶ ¤… JbŒñÀ ø¾> ÌÎÎ9söÌì\ÎþöûlvgΜsfv~ó;3ݵÆG‡ ¸xiÃÖ"jléH»'|>OD ö‹‰±‘T;‘ipž=°úË""Kþh)þYò¥³b«¶¬œ¤BÙ²ŠYÒæ%–/«˜å»-¤KÝ\V1Ëã’eùoxÿYd)+¼¹¼¤BŸY¥-¦¨°šj%•ûV«lQöOZ¡kYÅ,Õî­аš§LÚOn _©¡rHÖºö©ú…s¹Ü‹û†ÜSRŒê"‘ßhC1  .h^ê:&N4=WÿøÕN"š»äuû¥Uݱàô‘nûIÛª~ûÉïo ¢ŽçDÐW3x£ú¿‹‡Ý/§.x9ÂÆ~ÙMDwg_‹ªÂsŸm#¢Æe{¼3¼Ñ]$²N¸‰ˆ­ì#Ë:5´‘ˆÚŸÝUOb’iÍ‘ûs%ây®¾uÞúê¯È‰îêØvãÊ`ÚÚVõG¾vqδf3­Y;Œ+†4éŒÀÿ=ˆ¦5vý=qà¶Ì†¿Æ÷Ñô¦WÏôÏhî&¢Ëc}Ná™ 7ѧöѬ¶-¿ì½³}«3×ÉÕ¿|÷¦»‰{ÞáiôÒ׻Ğ\ø²TlÁã¥&>}•ˆ2Oî!¢³GK͵<½O¬äÔ‘îEÏôŸü@’«‡»œç‹×—H…ØÎKuyù_¶®_8tmòеÉgÊ?Ý®ž½q^ze¬ˆnoÝtÇý›ˆèÏÓo9e~?Ù«n{öâí³ÚND?Óãž~éDžˆæ<ºkNgÞ=}ÞÒžùK{æ?öÿ¼4Œo\¶Çi"jZ¾·yEoóS½D4öÑ+b£‹Vö‰‰hd°‹ˆ²k|~€ˆ¾}w½ºóIr"Yç#Þº#ði]7?'AD4½i#¹_ËÌjÛâüý>î\íÇ«C~/ÊëQqµ3W0ý¸ãâñD4iYÖäÛ¥eìn^ÑKùxKˆV²kÊ>j`÷¹´ûÛ>[`4Ïå1÷53?ò\}ýÂkEÿ²5£¥ûÊXßåÑ·í—3n®>ÅÝûÈÎK'ò?•_0›»¤çâñ“åƒðûžØ}î³mÎÕ²¦å{ÏÝzæ“0YºcõÁ‘Á.÷|ñÚÊòÉÓrŸ5>:ÜØÒ116’ø·;¤_ÀˆèkŠ Ë—UÌ’Të­<\µ>›ßî]-»ow¬kŸªÿÙ²B¡`b´yʤý²fΫ¡Þø¡_©Z&ý(¨&D50ã{,P&Ì’ËåªYQ @¦}×Èó¬ p €›R®þ~ð…ûu¯èz„ª Wpƒ¨àQ À ¢€D57ˆjnÕÜ ª¸ATpƒ¨àQ À ¢€D57¢Z}g¶8L]Â=7sCùõJœ®ÙÿTVS§Q»Œ~÷BÞ5ÁÓ€ÎÇã¦sŸäÈ$׺KZA§L¬<¿äâ0á- -ô[¨N÷”äß8‘ý áïò¯ÙFèeãº?‘ <{€HËÄÊÉⱦv%¼é’ãªÙŽìµI8Îy抋‹‹¨§xjp¦HKŠo‰Î‚Š£¸ºZªDZLÜbÒ†Ô{›¸^!ZT7ç.æ¹½ØaÅÆô4-=>ú•‘Ö¬Ù–ß6ñÛt"Í5­¸÷j–ÑL×á£ZÚ u¾òKb:‹ˆû“ßÊë—ôP/¨³D2ÞÖYý@•-(5yÞ2÷KZƒº-uÍÍ¥¹^A³qÅݦâißô÷[Q”#p÷]A1Qq$K’¢Qéþ¡Þ³¥‡ÿj†sâ°HÚyC~M‹å »µþ¾¡YÒ³é4󶢕 i¿J†ÞcT1@J2¼#€ÄÖ„0vs¤ãé²ê2ö M¡8^ë4!m%P»Õ3ý/[©¤hQÅn=–GÞš'Zb»©Ðl=ÐJ…n³íUZI;‚ójR¾[ãå×Ttj‡@úƒ¢ Ã'E74{è7…dÉ*P»1ñ´è×Ð[’ü/1èÔ©.#[±ÿÒn(¶¶Îç×JÐýÙ¯ iVJ¿³U±(©'«Èñ[£´ÔÄ–¬ØÉ:ú­„SÔ¢†ýUÒï^]DµÉoU•¯Zò ߘúÝ3ýj…¨àQ À ¢€D57ˆjnÕÜ ª¸ATpƒ¨àQ À ¢€D57ˆjnÕÜ ª¸©‹»&˜É-ÆÇð›0†¨NS±XL» ±Èår…B!í^Ô/DuÊøÝrpèXÚ]¨w8¯àQm ç÷–júLP_÷7J¦5[,í-oø=k5Ùkaß’ºP(0X£šco|äj#ðkÁ¢Úq _3­Yû¿´•˜ZŒ¼N×Ày–SÿºmL~äjC W!Ú,ç ZÏï°Åw\mDµËr±^–C®6¢Ú<²µ`Qm„IJ\5¿A­SyL5C ˆj#Diêéø¹Ú¸n„ȳœ;tÅÊcú­fäjC W!Ž,7>:lÿwO‘> rµ!ÕFà‘åx¬ˆj#ðÈr<Ö‚DµœÓàš~D®6¾³•÷w¶8Áw¶Rdo|\Oî‘CT§)—Ë¥Ý`Q&ܲ
N N;!&¸À ¢€D57ˆjnÕÜ ª¸ATpƒ¨àQ À ¢€D57 D”ÏçÓîDÆêììL»¥ÿ*[Ì cXIEND®B`‚cluster-1.52a/html/images/pca.png0000644000100500010050000000635211353772707016615 0ustar mdehoonmdehoon‰PNG  IHDR×}ÙaµsRGB®Îé pHYs  šœ IDATxÚíݽnÛLPûƒï&â..£.eŠ\Æ[n'¨sé—áÂ¥;«Lºˆ¯'[àÎΣ!Å#hŠ’/GŽtýç÷Ï+fò] ….Ô]ûôùËŒkÿxÿåHa¸èž7ÿõïÿ<=>8KOáy¯Õý®êkió¶7dùÛ2{ófïŠ~ýúU/=…g¿V÷¸ª¯¨ÍÛÞåo˼Í[û%–1ü³Þ®¯êH®ÍlÈò·eK»š-H»½»ŸÖÈNÿºÿöîÞûKa`HiÈFQ+y7©èï…oïîßúú]½».júþEú«Þ͘lC¢å×O‡]oº´òå2ç9 v?¤Ç´ñXÏÒà°ƒ\e´» ¾pt>çúURæ|˜à²_¸ŠÆÆÌ»!cïœ ìs…Gª~¬7Ê"úÂãç£^Ì'ë/è• ÞŸ}–Díà ;Ý%×u…wY}á|ÿ.ì8„E\=-ïo¶õ1Ó_ xƒ¾E+-ìðβ!'÷yù¯Â–G}ÀÆÍ9s+ºö(O¶!¼âFóÌÒuí·j½l)Üí4H«§1ËÊ +óÚ~Qö[X˜qónÈÕ©áÔN«Ë©¶½”Y~¿Ûó¶WÕG*º‰)lCô mH¡ðž¦ä%'<Þð….ð%¦p×nà°…5}ÍÕ§V¿”vCÒîꀫK#»äêr~¾SŸ±d«Ó·.zÁ3/0çO.¶¡ê ‘ü–*ÓK-ïÀ›Ýéß Íµ!ýöùH«;s±Ñ^m‹Îü6¶¡ß¤H†Zu4òk x“Æzw®¤VF½_«z"õOaíFVøÂ…tFúŸcüEZ§dµµÖ5ÔöXuæj–qãl:ÂúÂÿwÿU2¬Ö8OZ²‹éüߨI´umfÜÆÕ5ö+»¾ê䜃lE¦«ØÖ¯ìÚ†ôͺ~;3í–7X>Râ:*”uýÿúç—×ãñøööÖ»Í éÆž¿![:(nÞίjøLµíH …‹nB ….ÔÿÆ…}þ4L`!ãÂoooŽÅŒv»]=4³¨úÆöãû·ß¿9Ù罆OHÌI Ha) €ÂHa) €ÂHa) €ÂHa) €ÂHa) €ÂHa) €ÂHa) …¸€¾½»Òß–/§÷œ™,PF–¼dÛâfâõýùý3Ì‚ðiø¸|!]*Ó€yÓvÊ–,d«« ‘XxUÑ¬ß úÂSÜtWqþ¦dDÕ”4žÚæìz_/¿~¶¤d]ÛÎs²Í% –>ˆM¶ÂÏ/¯éÄß¿¥yžüQ D ÆSÛ F=½S¨¥sFËI³,š³ñµ%íÏ,9mI~ %›œ¾ªqbãá"ûýþãý×rûÂûý>š6·$3ó”ô8Б¶ªw÷³dᯪ¢6º†EÓcD‡Ã F$¼JtÜHïÓ— _æþµCá&G}êÆ‰s8¸d+{wnØl>© ×XwQ럮M­^’Žÿ†ËiœLìfùM c"< §Ÿ ”Æ÷ô2ËÏÄhùkËçéÑeÎor8òž¾×8˜Øu}~úüåüÒç—×aÇ­ oƧñXÅ}ƒx…ÁŸrÏ/¯Çãñéña5}aú{ˆ`0"1úHſ׏ívW>Í@ Ha¤0€@ Ha¤0€@ Ha¤0€à|‹þLµÆ¯ … O½!…ã3Á‰lÒjF$D0S^þ}RøÄyRýÔOë‰mó¤3@§z‹J¨±£êsŽH<¿¼¦|ÿ–žaw8úî÷hbÝ‘‰æIçl\;K0êWæ«®.¨Š2ÇÊÔ›ª[G W[MIwDø]îQ.gÆ+¢yꓪž3]5Kp8–Pu%äÌoÕ›ª[M ÷;JƈÓy¢ÞÍ\×=– sôK†¢›­|«7òÖ1.ÜVè…'ÌUðµÄ†êÈgkøS^-ÕÌá@„zc5}á|YŸ|\òÚpŠ¿µ`Øâl¼Sol!…£ n{Üö«Æ Ç›Âz‹.á'‹°di°¾†µ eˆ]¤0,¨ å|š€ÂHa) €ÂHa) €ÂHa) €ÂHa) €Âp‰ªï óoÛ¿¤®ë¯ÌúôùËÇû¯3÷üòºßï —Óuæ“ó”/ÅêT”¨ªSuƒ—èóËëñx|z|¨ž®éÛ?Çcæ·õ&ÁŒUw{wïË@Ûîì™F+ûæ···¶_å/M=* ÿ’èöªž3œ¾\ ®W§ª;ó o¸êÔÿFR¸Ñõõõ߿筪ªÜ£¢/9¤óƪnìºÞªSêmþÙÀÉPxø§s ìªÌÒ¦¯ºÙúb«No§/öAJ"øä]U'ï鯻’‡«h«×LƒÃæUÓÕhŠóa¼ªËÔÉz«.œ3*³Æ:L—ŸöÙY÷ˆDuJÔ'C~8¢>öQD]†Æ)]£¼SÒ²­ѯÚfޤóLpno>ˆOV]´‡×[uùÖf¶¨-ë•ܦR8ìÌ2"¼„;¬ôN3߃OHçÃxU7å¸ðô5Öuž°äñvR¸¼Ü©˜f¯æ1ÎÆÆ“aÔªkü»…5V]zÖo×þmö…«S¢$‚ÓÄéšAé`k×ÓàÌôØÆ¶yôJ&¨ºAúò«®°åaÉ]yCbc#çD´½sÕÖ…ìT‚OKnÙW—.'3sf'ÃU—?è«®ºò G•ܦRøéñ¡ëÿÌTöÉ¢Ï×M&û PÒ¤Ì}nfEåÛÈàU—y+l½U—yÉÉŠêúö£^®ý~?ýJr/|[œ%TÝùh½Ç|Ë•îêSxØL)ì$.¤n”.Óã[WÕ ^¨úÂm|²% œD>¾²ñ_Üf5ŸlÉ…XÔ'[¢êÆ(¡è“-õ…ŒHHa¤0€@ Ha¤0€@ Ha¤0€@ Ha¤0€@ Ha¤0€@ Ha¤0€@ Ha) €ÂHa) €ÂHa) €ÂHa) €ÂHa) €ÂHa) €ÂHa) …ÂR) …ÂR) …ÂR) …ÂR) …ÂR) …ÂR) …ÂR@  …¤0R@  …¤0R@  …¤0R@  …¤0R@  …¤0R@  …¤0R@ Ha¤0€@ Ha¤0€@ lÓͼ«?Žª)<ý~ï ê³ùxÿå ê¸pÆ…¤0€@ Ha¤0€@ Ha¤0€@ Ha¤0€@ Ha¤0€@ Ha¤0€@ Ha¤0€ÂHa) €ÂHa) €ÂHa) €X»»€Á}úüeÃ[·Ûíže¤0‹öñþk“Ûõüòêà2,#R@  …¤0R@  …¤0cðçXÛ»ûðéŸß?í¤0Lj¤ä½½»—é,“ ) Ùnlú ú ç §D¿:ùr˜‘ š¹máØBõ8ÒøÂjzáÌ …¹Pi,V9þ*Ó-IU½`¤0 œÔS¾†e\˜¥«Æ êq¾WMÉw{uŠÑ†\26vZÃ8®fÈL‰Di®SŒ†ÓcõÄôAæ…™W _ŒH …¤0€@ Ha¤0€@ HaFä03Šç—W;¤0óØívvHafóôø`'@!ãÂR@  …¤0R@  …¤0R@  …¤0R@  …¤0R@  …¤0R@  …¤0R@ Ha¤0Àå¹|‰‡ÃÁn˜'…÷û½} 0[ ¼ÿ²OÊÂR) …ÂR) …ÂR) …ÂR) …ÂR) …ÂR) …ÂR@  ….ÏMøäùåÕ˜'…w»Ý0±ë?¿Ú s1. …¤0Óû/H9(ýOcb¦IEND®B`‚cluster-1.52a/html/images/tree.png0000644000100500010050000000246607505045612017003 0ustar mdehoonmdehoon‰PNG  IHDR`6·- …gAMA± üabKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÒ 4nÈdzIDATxœíš¿/sQǟ󆤄DE÷bc ©Ä€ÐMbµÔBÚARɽMØ,š]ÚÁfP {Y$$†&*·’’ˆN Òåy‡‡ãj«½·=—[ñ™NÏ}ίoÏyÎO†ˆðÇ×üûé Øñ1q/4Æãñú+¯ªjqP½½½õWQÁr‹RišVšE©\è3oל*×C,Œ1Þþd2éñx$IRÅëõʲ¬(ÊÍÍ U) ƒADäIcš¦É²Œˆ‹‹‹ú<@Ó4I’,éAó¬ /Ž7ß;éB_)&•MB<ÜÔÔTSÖŒ,±)‹åóy±}3…Ballìää$‰øýþ\.WêyŒªªªªÂŽ///÷÷÷}>ŸËåS©qÊþ? ʇª¿« ªv á´ÕX²êëë’O&“’l8Ä –ÛÑÑAön·*ÎbXÑ9"âÄÄÿ©iÚ'ûú"D(c¢J§§§Ü²­­ ÞŠÔ<|_Iò9 ?¯-ÉŒ4ÕÚÛÛ‹Š¢„FcZsËT*‰D( …cªª–v(=d&I’^#X^^v8`‘úøŠÙï÷@(¢Ÿ’$q›«««õõu}ª²fíííù|žÄjøYlrrrkk Ñëõòx;t|Á#‡††677õɹ£áfŒ1§Ó‰ˆçSI‡Æ7S$Yå­mµJS•DDVásÇïîîVWW…çüK²Ž†÷AVó'Pì(P ‡öb9888>>¦°íŠÅbf“Ý…¤ÓéÒÛ är¹Ê—(###Œ±ùùy.Ð?9Që0[%EQúûû)<335m5žžžôÅî0Ûv=ˆˆF£hlV ƒétšÂ‡‡‡<•,Ë´Õ¨œ™uvv~efSj€1ÖÚÚÊ=W (µ) £££ú˜²fzLïÅDõˆ"›ÍÒ="ºÝîóósŠÛÛÛðù⬹¹ùââBŸœÌº»»«ôÙ|„uÐ3íˆÝÝÝÊ[l6 _o5fgg¿JX] D"!¢í†0%¥Ô⃉„u®uü'mUÁ¦---ýÈû Âçó•)½ªwàNÚR¤¿6˜¤¨!õ¼ÒgHáuPÕÎëëke!ÐŹq„¿¢¯¼}t{{[wëÄ`V#¢hPȲL‡‹v¡EfN§S¿ª€Øàwêbß=>>^__ó3›øïñA5âÞaÉqÂo¸ø>¨L¼ñ?ʶ=ÈRlº²U¡´°°@ûVc‹÷AÆGãww˜ª›À÷A===üg&“ADÓgõ"¨†‘úˆ}Äq»Ý‡kpÒf­#õû>ˆ`Œ½¼¼Àßû ²fˆèr¹hSÖð³˜ð÷AÄýýý[è;‡ŒEI&ê}P @DVÖ´á°ð}ÐïÈ:ÞYÍÏEJfÿ2-IEND®B`‚cluster-1.52a/html/images/adjust.png0000644000100500010050000001257310207277010017326 0ustar mdehoonmdehoon‰PNG  IHDR×}Ùaµ pHYsÃÃÇo¨d-IDATxœíݱ’Û¶Ú`æŸs7ñLÜÅåq—2E.#EÊtœí\ºðel±åv»¥Ó93Îýü} !ˆ¢ôâóŒÇ#Q ]ƒ¯!Pøúås@ÿ‹nÀ¡Ia€Hÿ‰nÀ¥~üéçè&l㟿ÿŠn`ß)üãO?ßMxýþÇŸŸ>~ˆnpk3)¼£ÑåÝDp×uÿýïÿãÏ———è†\dú/Ò`GŠm^;µÓ”4…w4ºlð$¿Ü^~ùKÆ}›)¶yÔNk¾»:׿™ÃŽ #úf;RlóZ¨ýöõrÒ=FâÍÛwå— Nyü³²q]×Ýw ŸTù•Ù¨ýúåóð§Äb(;ÂÓqßt¹"_n9„|óöÝɈÜÄUkIŽ<>ݶÆühõÇߤä% ØÐlçœí´›78?Ë µ_^M©ú¤Z2fœ>®¾¾±pyÇs[)ïÊC†æ­JV¶v¶Š¥cvÕcð‚kïü€ßk_ê—ôö³äݲv…ÍH\{9ô×i-ÃÆáOÍîÓ}ë{>S1î[9‰qL呿Õüsß¾ÁÉá¿%¶²æ[KÿE'¹“ 'Osºoá°70CVÔxÖûîÕj~çõ/M›—Œgÿ]ò}×5¾¾|¹ ÓTJÊ„ «fªR¸|âåïݦCÑÊvö]1-Ð]yùûÁÊJó¤8ùÒÉcVVwò÷Vø—š}^>þº7ÈK{¿ðd WÙ†äÁÒ”BÁ¹o}N6xõ6å$ïódýX3/¼ä’àÛp™wÍÊΚÏ]Ôìxí3!®&µ/íXó{Ë#ûdÉ ÿ•—Fßå½NnI²îÝÌ…ÿÁ\Rugì|`[®#±É[Ô­†³Í›=ÂôÍlþ [tÌŽ›ò*¦çä5&ò–~çþÞ6éë—Ï5Åf£öë—Ïßr‹i D| ¿yûîdDnâ6µœ%>…g%Óù¼Äô¥ÙíçV‘Sd7ðŸkWðøôœoüí×_†Ã@¸ûß@ux<>èN¥j¾KåÜÅ´d¾oþÒìOܱ¾ïÿùû¯TtõïûdËV?Û˜Ýõá;:yIp*ÿ€;öððp³ºn‘Â]1v/|ã?D×+ ·g_ºÍ‰ÀÝ(…gåéY™§Ó Üñó'w\Ö×™ÂK–>Ì0nŸ}Ð-Œ‹ÇCM·çUL'7\—n&2…ó‘i~}ìd¤dùé…µl®ÑOªÄ>RØà¸WûHa€{%…"Ia€HR ’ˆ$…"Ia€HR ’ˆ$…"Ia€Hm­léÆBÀõÜì&Fgi+…»É-éŽÀŒ@$) I D’‘¤0@$) I D’‘¤0@$) ©¹o0ϪY_¢Íoˆ”í#…»®{}}-¼úéã‡[5`K»Iá®ë^^^–^Z¿yûîë—ÏWkQ­m›ÑÈl¼pÉ›·ï69ÈmBs“Ö7&…"íiFb+ã˜q¢NG‘ɸuɆ—’Ýóc™éÓ¥}‡ÇÓíɾy³Ë?ÈlE@³—ÂÓù1@gãx0¾”?˜F^’ÈÉöäiþR^&™Ç˜mäÉ£åÇZs¸¾\!©Ç§Cö];þ Áæˆa/¤ðyÊçQ2ľqK* ´ÀÕ¹íå³½Kî,œ\yK.…uŸ̇´5Ùºt…-¯º^^ïÒ–äg·›þôñÊ/(φ]¾ñäÕ¹$ˆ—Ž–_«Ü·ð ¦Ùå-ÛG ÷}½ƒ>¦pmûHá«.Ó#y@®ÎD’‘¤0@$) I D’‘¤0@$) I D’‘¤0@$) ©­Õ|®ºv@ƒÚJ᫮Р3‘¤0@$) I D’‘¤0@$) I D’‘¤0@$) I D’‘¤0@$) ©­õ…Ÿž£›@‹ú¾?kíi‰Yçv¤Ûh+…»®ûí×_¢›À=Ð‘Ø 3‘¤0@$) I D’‘¤0@$) I D’‘¤0@$) ©¹u$fÕ,ÎÒæ:4EG¢AûHá®ë^__ ¯~úøáV aßt$Z³›îºîååeé¥ÂàåÍÛwãã¯_>oÜ&vHG¢){JáÞ¼}7=a’§õ;rp:×s¬«sÎ6¡#±¡; /ß]§Ó0`6Ž'Ø8ŠÉ wÙy˜¿]­¬bZféà4ëz))3-<[i^‘^´GLáé›ÄÙ<«ƒ®ëÍ5{Í… avdÛŽ”¿©ZWF/Ú—c]Ë{íYãÜ­ÅKe’I@šÒ‘– &ŸÖ‹öâÎÇÂI_'ÚòËb³;oë* /m©Ù+i˜QLk¢:R}™é¬±^´/»IáO?¬û^él_L6NŸ.†ÔpéL+WQ>8ÚKG*ì{²“èEû²îû>º %¾Uµw¤ {ïÀ>R¸ñÕUœ{ÑxGZAß»Ǻ:Ð) I D’‘¤0@$) I D’‘¤0@$) iß`¾™Ç§çñño¿þØvMG¢žþf8m^__“íN!΢#q.)Üu]÷øô<œ6Ÿ>~7þþÇŸ]×õ}?»ÌãÓsr^å[8‰¤ð¿¦gNþ4÷ãO?'çU¾…Ò‘8‹«s߯/ã©òøô<Ôûçï¿~üéçÙ¦¹j#iŸŽÄ:Rø;ã9Py2,WÃ8=H²ex”ánèHÔ“Âëõ}?Œb’‰¼áiß÷}ßçF¾e,æü98éà¤ðwÆs þòÈ0ŠIÆ2OÏé5¼”oéû~œþ[ ±S:õ\ûvžüþÇŸÃŒ^rÚ”¯“üöë/ù™–Üßl­ gÈtИ{¢#±Žþæä…ì‚ÙlØ2¾ÇtÕû t$Î%…»®ëÆñÅ´ç[–öÍ·Œã”Ù‘ ÷JGb)üM>­V>m¦çÌPrºeåâ,:ç2#Ñuÿ»{îpÝñϰ¥p[Æ“[ ;ºEØ]Ò‘XÁXø_É]NÞ4!¿ëAå}Æ;ŒY‡ð.éHœÅXøÛøeéTùçï¿–F1Ó»¬’8sÄ:ÆÂY†Lï[žlŸ/%%‡íÃF3‰Ç¡#™±ðz}ߣ˜ñL Oû¾ïû~œ¼·ŒÅ†‘QRrZØ”ßAèHg,|©úùñéyø{Üøøô<> , v’’à 6Þ¾Ìû̓БK {¿öûÎÎè•»ïp—Üüßt¨R0ŒVò{ë:aöHGb)üÍÉ Ù³'ذ%yY¹/û¥#q.)Üu“»‹Oûq¾eiß|Ë8™¡Ì–äèH¬ …¿§Ï’-K¦çÌPrºe^ÚÞ¹´½O:ç’Âß9ë=ÝқǚW§O—¶ŸÛÚ¡#QÏ'Õ"Ia€HR ’ˆ$…"Ia€HR ’ˆ$…"Ia€HR ’ˆ´Õ|jnÙÒ÷½%K(Ó‘hÐ>R¸ëº××׫—,­Í¡èH´f7)ÜuÝËËËÒKKƒ—7oß}ýòyéé…†£m{Ln@G¢)÷?/üæí»«ß™s:Wrÿ) в=ÍH¬³ô^oÚ / O‡ÂÓ»É %ÙeÜ8Ý+9`77Æ9YxzÌBíI®ªåŽ4[u¡k%fÎÍÜ ÏšžNããqËRÍw%'Øìñg«^*œ<ÈËä%¹½ÀŽ4{œ¤êr]³mãö‘Â[]ú893˜'ìê#—GÐÝä‡ròÜLk©¦•ËèE-8D wß¿C\ç䉑œŸguëšÂyÖo¯ŽT“Ô5eô¢p®Îm£Ð//•Éç¹[u¤%C‡É'…õ¢@G w LºêAëÉž:=`áøùqj“—ɯùpÍv¤úº¦³ÆzQ¸Ý¤ð§V|¯téjFᥚÓ§ÉU‘¥ãϾT8Á «©‚%wÙ‘ Ç?ÙIô¢pûHá¾ï£›°™ü£HÜÌ=u¤ {Û´¾§ÕUœî©#­ ïµÉÕ9€HR ’ˆ$…"Ia€HR ’ˆ$…"Ia€HR ’ˆÔÖ:_l…­èHìH[)|ðÅVØŠŽÄŽ˜‘ˆ$…"Ia€HR ’ˆ$…"Ia€HR ’ˆ$…"Ia€HR ’ˆ$…"Ia€Hm­/üøôÝZÔ÷½%ƒ¹Wm¥p×u¯¯¯ÑM -Ÿ>~ˆn\Qs)Ü9ë€#1/ ©Å±ðàÍÛwãã¯_>—K– œ¬(Ù½¾êMªެÑN¢êzÉ5Áרz<ަÌHDjt,¼d˜+†“Óyƒé«I¥Ù†q{åhwvš¢PãREcuù¾Ã«ùñ§N¶Ø—¥p7ICT%[fßþ×”9Yu—åéìÑÊÍ‰¸o÷yu®©Añ…Ç'‹»ÔèX8‰ž|0˜gÓtËÒàñÜ2]6™;ÝX8ÚR󦳯õ-quîX£)Ü-dÓtãl4Ÿu„Ê2ëj\*œ_¾+ì[> pîsF`/¤p-CQà¤0@$) I D’‘¤0@$) I D’‘¤0@$) I D’‘¤0@$) ©ÑUÞ/¼¯D~Ÿ‹‹[äVÀU4šÂÚüA"¸3‘ö4Îo—Y¾Cèìîã0yº×0ÔHÊw“áp¾o—ÝÍ3Ù`ÉnRx:'0†æläwÕœfk’ÈÉö|–#y)/c8i7)¼­<µgoeÿõËg1 \Õç…Çx-'ìt’àJŽ˜Â5òÙ^€khwF"¹ò–\þê.ˆÈš—®°å͸D£)<pùÆòÕ¹<@Ïzi©üÒ¾…KMág}L  M;NaÉ ÜWç"µ;¾Í„ƒi V£)œ|ë¬þKhg}]mu-[ÙÇŒÄmÂQ·×èXxIå*<åew6¬hZæÜ*º}¥ðìJ:ë–ÝÉ<<(ì»´ÜO¾ÅÌPoO)ÜU¬ÂS.¼$;WV”ßÑÃ@À¹v–ÂgÜ%iX³ïìwù „³ìãê\>2=k‰šÂKeê÷µ°B£cá$Ëòå{–Æ›ÓiÊÂ'×ì;Ýb, Ôk4…»º}Ê«ð —pnEå* ö1#p¯¤0@$) ©ÑN>f°í§¦i8wÇñφ펬ݫs×þàí¹·ôp Ž…Û'‚M´;^úÚÒ=ù§} Ëîtß/Г°;'g-ý¬Ön Ï*¯ÑS^ß§››FH2qöøyf«›­ÚÒ?@YÓ)¼Õ² '/¦%)y²UI1Kÿ«5ÂÝË2œLØ$èWÄ¢¥€ÕŽ~u®ƒ…ô·ô°•ÖÇÂÝùëìvŸ5=`áø–þ®¡Ñ®YL'yZó`ú4¹p·tüšfXúXíè3±¤0@¤Fg$àüøÓÏÑMØ¥÷ïßúø!º·Ón çßj»^E¦h¹’þþ+º ;óøôÝ„[k4…W/#R}ÙǼðõ‚5_Mà–ö‘£dyßñ³ß'Î W~«"?ìl½y]—ýpÀ5:#1«fÝœ®¸ÈN2¦žnŸ–/bóÂyö5Î-,¥6ýSÌ¡ðt"bÜXß*€®Ù±ðì]0ê×Í)¯Ësac’VM GЈüö4«Ñîí¬us …gŸ\Á;kÑa}ÆnîÕ}ß]m¾±vS¸Y†½4îä‡jnÆÍHá³é¬À†¤0Ü!Šw¤ÑÏH$}hÛ.5½çк}¡Y—|øg|ˆkkw,|íN ‡q4ù§† Ÿ#r‚ÜL»)Ü Ÿþ¡}…<=µ:vˆvSx)ï’ÿ½óoLäŸÞý?_M-ùøNýWï’óæ*7¦sÞ^»)<«¼FOy}Ÿnn–#IêÙãçÕYú‡Ý©œsÐ'o¯éÞêíÿÉ«5+ElU¥€©¦S¸Ûbq†“ ›ý…‹´Yú8Kë)|m…4,ÌN”wL䳯ãç‡1°ƒž½òÖUO`MOxù@–þaê€÷²ä\¦pͪ=ÉÓšÓ§É…»¥ã/m´ô'½ÿ>º ì@£)|7 {ìÓÇÑM`¤ðuÉ_ ¬Ñu$B Dj.…M¥‡ÒÖ¼pß÷ÑM¸©¶RøŸ¿ÿŠnÀM57#p(R ’ˆ$…"Ia€HR ’ˆ$…"Ýâ[7¨`®žÂ¾” Ppõö¥d€ó‘¤0@$) I D’‘¤0@$) I D’‘¤0@$) I D’‘þ]Síñé9°Çô-…߿ۀcúáë—ÏÑm8.ó‘¤0@$) éÿº4ó€ô}©¡IEND®B`‚cluster-1.52a/html/images/kmeans.png0000644000100500010050000002566410322074750017323 0ustar mdehoonmdehoon‰PNG  IHDRß}ʶõêgAMA± üa pHYsttÞfxtIMEÒ ! ,†H++CIDATx^í[–$©ŽE£g–C»Ã»ŸýÑó‰¶jnS` ÉLÆkûªU+ÓCÂÄáhŽGºÿ×ÿü÷¿x    ̦ÀEgþC@˜MŸÙ ¢@@¿N5PPP`B 3;_(ð;÷cÂΤ$€Î_°épŸ]dž\?þL^!娀ˆÎsï{þ®.]¿Uj®Ö¹ÍDÂìæï«ýë_ ¿÷ÌØ…ž]¯°Oç%º+¬bÜ-TsÕÛLäšÝkèü= Æ.ô)/òºWìÐy‰ÖŠêÇкë*ßf"йmű =êž´z{~V?tžñÜylÓ¾k¾Æ þúÝÿ»k•?j?/x§Æ.ô¨Y?_¯CF€ÎÐÙWèÜ@ t>„³¶iZèœýsÇëÂa_cØÝ¤CÙ&fu½Þݬ¦ øl"Y…ñ¯æÊ«²?Ùºf¹f:§ãyŸ;än„»]d\Ö4±ºÖ6ÅŽ-»¬í4ƒ>ìýõÊÈF:7ZZå’¬S’ ûœÎBMÛ­Ø.õáDîè,¬\&)Rx(!¡sUÏKhfτ܌é ÄW9U5§üî(ѰMçì–Pn€äíS],è,l‡Qaѹ½û~èõî_2~\¤îF©1šäBÚ¦}Ý=’"ߢsõZ¯åµ‘Tr9êÎc]:ß-},F~'¾Ú«ÞîÖ%›£ÐÐY(Ô¨°wèœõRfÙ;w÷©ãË?—Nm龜{®ñ…dúвüsVþ5^ânÕDº{7ùå’Þ1.nH3DfC¥nnïËéÜq¹4Uµþr•ÓÄ»6ó¦sÆîX†ö6 GrÈut. Ùã”ÞºcM÷5]•‰B¯WÛµMç,eìDÒ;J£°êÝ(Õ­­Cuä Ê™e«WìžlT‰SÖÖ€lYÕ]wt“Ÿ;ß9önAÊ«kÏÛZµ_}–|aï<„¹ò‹éÜhËÆGµ”A™í²iw":—TˆOftHofi'Rv~ nI%íu¹»o¥“½›àÓ¥s•)B:—÷ƒî3UÀu9uwohÜÃÚw² žp?QõÕÙäÍßµ|("=ð¥sae[v¹Ù¦ä“ȃª=&¿Í4¶uî•7m•å+ªnwÄiË9kйá„ö Or‡È¶ Õ.êrJHçò~Ù«|¡Ã8w{ç»ýJÝY{‡1å |DçrGSºíŽVY®jwL¹CgÙÏr6îÏ'Ò½Ÿ©n’{a¼bwOšEJè,·©wd÷Üù wÁ‡tPîîîÔƒÎÞ¾z8þût橪NŠ·ýÒdÙ2h–Ö¼ózÃÁÙ¦£Í寡±y)džH—Î!àNó»Év³kšæ–¿~ºÄ‡ÈÏËùÞíj3·”&¼µtîª}·¿®b:?¤§wº…ÎÞ5™Çïþ¾swäj u³^x>‘×K2¸4ͳ&Ž]hè,\¦QaÐùÿŽ:¿nDèÜ:¿î·„ξŸ2aóÊØ¦µÕ|—¡ó»Ž:g4è }€ÎÐùž¾;Ó[:ÿ=\qWÞµ¬ÇhñÅÊ®KÀ¼&W úM-:{´c¢   ¤ ÜþÊÐÒÇ…¬1   ¬®tö=]]ÝÔ(0Jè QP`F óŒ«2ê^ÍuQæQ:Cg@˜Qè<ãªÌs÷¦@Q @gèŒ(€3*g\•Q÷j®‹(0Ð:£  ÀŒ @çWež»7•  ŒR:Cg@˜Qè<㪌ºWs]@y€ÎÐPfT:ϸ*óܽ©P`”Ð:£  ÀŒ @çWeÔ½šë¢ Ì£t†Î(€(0£ÐyÆU™çîM%(€£€ÎÐPfT:ϸ*£îÕ\P` 3tF@€Î3®Êi¤ÜÝø»›èÈîvä’RdWƒëºc†€e蜾x̶!Ý“è,·l¡X„M®€¡O^¡sj°ê®9L. å0¸Nx••è,œaÇ*`èCŠP^^– …Z=ÌÏBÐyÆÁ¹º_GÕoèCJwvüò\W¢<,´ÞÉÆN+Ê\<0ô‰!Å£rÆ\W? ±wf&>1¤¬Ë*÷PÀÏBÐy6y8o­1 }bHYKªõVÀÏBÐ:¡O )ÞÝÎøk)àg!è¼›Öò´Gµ†>1¤xTΘë*àg!è ÷QÀÐ'†”u9Bå øY:ïÃ&ç­5¦¡O )kiBµÞ øY:Cç}0ô‰!Å»Û-ü,÷aÓZžö¨ÖÐ'†Ês]ü,¡ó> úIJ.G¨ÜC? Aç}Øäá¼µÆ4ô‰!e-M¨Ö[? Ag輆>1¤xw;㯥€Ÿ… ó>lZËÓÕúÄâQ9c®«€Ÿ… 3tÞGCŸRÖå•{(àg!è¼›<œ·Ö˜†>1¤¬¥ Õz+àg!è ÷QÀÐ'†ïngüµð³tÞ‡MkyÚ£ZCŸR<*gÌuð³t†Îû(`èCʺ¡rü,÷a“‡óÖÓÐ'†”µ4¡Zoü,¡ó> úÄâÝ팿–~‚Îû°i-O{TkèCŠG匹®~Z•ÎWÝÝÇïïïºKNå }¢JéZN5ša‚¤L¨€ß¢/Lç?ÍǵŠÐyB+»–dèUJè–Æ×¹®ïœƒ«,¤šÂÚt¾ø{÷hôÉOòP‰Õ¾†|k(Æ1+`èUJè\g^ -UR)°!/P†]suïœaªªì2y°¡OT) :ãºÉ½áWžÊBª2v£sØCg• ¶ 6ô‰*åŽÎ¸n &¢²jüåéXñÄÂ@ç´+>â31 †•ÏT‡*WÅp•´¶8`z9ÕÚïlèUJ¤ó®K­^š9ópjò,x?ig¤²jðèZ%E³Î™ƒ 35Ã3¥w«&é“•8f ÜîU²,Žh.Å }¢JIé¼¢ëR3KüSI71*Ö쬲J„M蜡ùu:gûÜ»U§Y:K®RÝq«–|ã`CŸ¨R2:/çºòuaµw>„ËÕÞQYHÕ}ËÓ¹Ü5‡SŽKÕ»‚w6ÍvÐ}®dëíŽÓ”»}z;¦¼¨jù7 6ô‰*%=w.Ѽ´ë$þo¼ÜÌHªé¨,¤ùú¡2åö÷Ãü~‰X5Éìý™ð23} ¡swƒ,¤s÷ïlgRïª,U)»®Açê![¶kQAg³`•…Tsßaï\ýýÓ;:—/îª{Þ¸3Š?MŸ¹;Ù¨;„'+7À$:»Jcž–uŽjí÷ 6ô‰*åîw6¢—säd£ñ¥÷s”dF* IŒ1 Ó¹;ÏçÛü*U»×Õ|smU+ÆúD•rweYÅu݉¤X´!—ÊB*ÙW¥sãßkeç*9îvÖÚAºñå.»›B@WCŸ¨RVw]WÀ»Wx†ÄsRTRɲ*U“$ø }bH9DL¦)TÀÏBЙOÝGCŸR„MKØ! øY:ïæCšáÝ@¿Öb9QÀÏBÐ:¡O )‡@‡i ð³tÞ‡MB3mfèCÊÆ25ƒ~‚ÎÐy }bH140)+àg!è¼›6náÔ }bHCØ! øY:Cç}0ô‰!åè0M¡~‚Îû°Ih¦Ã }bHÙX@¦fPÀÏBÐ:¡O )†&ecü,÷aÓÆ œš¡O )Âb;D? Ag輆>1¤¦)TÀÏBÐy6 Í´q˜¡O ) ÈÔ øY:Cç}0ô‰!ÅÐÀ¤l¬€Ÿ… ó>lÚ¸„S3ô‰!EX a‡(àg!è ÷QÀÐ'†”C Ã4… øY:ïÃ&¡™63ô‰!ec™šA? Ag輆>1¤˜”ð³tÞ‡M7€pj†>1¤‹!ìü,¡ó> úÄrt˜¦P? ­Jç«î/Ï¿hY¸Ò„=QÀÐ'ª”/-§*ì‰hä>TÀo¥¦óŸ¯×âAç‡þ&ÝÐ'ª”Ð-ßIL¬B'¥¹Õk _®ŒT¡vª“t€ëTˆ¾ZÈu žNç°;.{#}: Í´bŸ¨€îºwŽ¯Þ ³Ðo!lE× 'ŸÒ9¾ªªº$ýi52nÞã‚eÏ„¿fËi‹É¶ÆiÁ?wÃÒÊ ÃÞYøÛ:㺥]…½ð3.§Š]TÅV#2’´ŠæÌšò˜nmí{L{·ÒÐáᙉÜÍÚß)šjïnº’w;Ò{væ±Ò9râ:¡ÓÒ0•…Tã³w~Î Vè÷Åe×epöRšUÒ¹½¡N7éÕÜÔmÕ]v¹ÇQTlèUÊ<'ªûº„θNå4èÜúü‡wû$nX ï ¾Þ'å!Fã Á»tN]Ý;—w…ê^˜½³âõÚ}hpã¥pãu®»;ÙÈ^G–/+;KTÝàUWgïì¸wŽ/?Käu_ ÷Å:§1åöö©þ¿#øÝ4«pWÙTlèUÊ»{‚ì—8Uï ¶WÇðŠ­ñúÏöŠ × MÛƒÎOßùî¬àÎÙN6=:ˆ?ŠX¯nQÓæ˜ê=£1‹*‹Ó«ßíb²®žs3 ˶ðž;WeÇuK¸NnèÜ1Ú~)ú„°6¡sßjI®¶ÌŠ®N :÷[†>šén§ßx^>²$RµªRüN6Jâ:ÉŠ·Í>Øh-$ŸT™ÏÙèš>QYj`° µÐyàJítiƒë„Ó‡Îìùn”¿~ABò{g‰J§Å@ç¼y.E¾4öß8|Y׊ úD•‚ë0[©€ÊB*WÝ;÷w¼oG¨d%xˆ†>Q¥¼í©þxCdä¢*TÒŽ¼ä¹³j’¢€¡O )‡ˆÉ4… øYhÕ½³P8ÂŽRÀÐ'†”£$e²]ü,EouWˆ€0ô‰!e†™RÃ< øY:Cç}0ô‰!e.PÉ øY:ïæœ:¶CŸRÆÎ‘«Ï¦€Ÿ… 3tÞGCŸRf£õŒUÀÏBÐy6õè W7ô‰!e†™RÃ< øY:Cç}0ô‰!e.PÉ øY:ïæœ:¶CŸRÆÎ‘«Ï¦€Ÿ… 3tÞGCŸRf£õŒUÀÏBÐy6õè W7ô‰!e†™RÃ< øYhU:_uoüàC—l½gèUÊÆ–Sé`[]³ü¤[˜Î×çƒlù¸L mlèUJè–-¸Îf¹+Ke!ÕUÖ¦sÿ3¾Œ OTNƒ }¢J ݲ §ú%ãº/]'¼tî÷ãúDèÝ2L…Ú®JÎæ¥Ù8Qe!•Ðùcöö/UfïÜ·” ×}é:áµ ³À¹šø÷!éúkxÄ1ºÏ¸öɋ߃ùâPB³và »UÊB{g­q]×]w* ©®5èmÆV±›B9ÀºûÌ}2!šµÇ»žlØ|ˆëTÜ|øŠMx-èüãf9ãoú);áu:‡}kØ"…ULw²éO«‘qo’=“Ž,‰YÕb²‚Ë¿ª\ûâkLUkMëºr‹¡õawïŒë^tÐíì×Û;—\¾b îØ])pïÈž¹§1~6ZãV‘ÞHª÷¡ea*Ôîz²a{ '¡s¶j¸Î`!•É¡ó’t–VÒQqï\¼±7¿#xåN\6÷‰ èì«·ØxK.·±'8ÙuBFCgèüŸã‘r\}¦Kp!³]¶Ð¯í0j @‡Î/Ò¹ñúÌoO0‰ë„n‡Î[ѹ<ü•ì;ñ'}Ò=‰~½U sãéöû’“;ŸàºK[!pUaÐÙ‘ÎN¿ï\nNæÒ]mã5f|E™6[y–]nmÚ1YUÕbR§£©,Û†ÎU:K|h 3®3¼üRY:¿LççÃuûDµÀGCg³ýp¹S ®^ :›ýì•HŸ½[†úD•²Ð¹³Ö¸îK× ¯µ6v§O„Þ…Î/z×}é:áµ ó‹g(úDè]èüŽáþo\÷¥ë„×Z˜Î®æôðŠR¨jVSÞÒ¹ÆWÕ³V0®³­—Áu ­Jçw s%\?ÂR }¢J™Ó*/V… ¨,¤U:«&Ið! úÄrˆ˜LS¨€Ÿ… 3ßɽ†>1¤›–°Cð³tÞ‡M‡4Ccš†>1¤ 3 < PkH¶a‡(àg!è¼›iöÎ,ôT @gŠ} }bH™ 3\? ±wî÷üðå§¡†>1¤‹!ìü,¡ó> úÄrt˜¦P? Aç}Ø$4ÓÆa†>1¤l, S3(àg!è ÷QÀÐ'†C“²±~‚Îû°iãNÍÐ'†a1„¢€Ÿ… 3tÞGCŸRÓ*àg!è¼›„fÚ8ÌÐ'†”djü,¡ó> úÄbh`R6VÀÏBÐy6mÜ©úÄ",†°Cð³t†Îû(`èCÊ!ÐašBü,÷a“ÐL‡úIJ±€LÍ €Ÿ… 3tÞGCŸR LÊÆ øY:ïæ@85CŸR„Åvˆ~‚ÎÐy }bH9:LS¨€Ÿ… ó>lšiã0CŸR6©ð³t†Îû(`èCŠ¡IÙX? íI矟ŸÌ å3¥]$1i–6~cƒN25CŸRî&‹ë&±ÁÇe¼h¡¬rèüïØTZÚjã?6Í—3ô‰!å:ãºmüù¢…N¡sŠÎëÏ ’Ò''÷É‹­•Ù ×mã«öD^´tþk³œvNüsÀtµÇJÖ·{ï_Î6MCŸR{çÆž×Íæ–·êyÑB›ÐùR¤|ĹEÎÚÆÿ§¨þ(ÛGgÍVM¿ž¬³Á“¿¿¿o9ø›q }¢JÁu¸ú× ÛaÕsçÐTÙCH縋‘ƒ»DyJê²’ žQaKè6ï0Cͪ\çmlÕrxÛI8¾_ÍkÓ¹ûþLy¦Üxc]²S.c„K¸\˜Ÿçü¤0Ô¬Ji7̆넋®Zá˜Þa~5Mç·öÎÞË?d|?ÏùMÇP³*å:㺆TËág$ÕÈ~5oNçì¬#ü5{¦}jQ .ŸT-çÁ~žó›¾¡fUŠÎ¸Î¼Äªå0_åÝD¿š÷¤ó»êŸ9šŸçüô4Ô¬JQûMsã‘WTدfè¼Ï¿c~·iý<÷néh†šU)ª`¿in<òŠ ûÕ ¡s]?ÏùÁÅP³*Eì7ÍG^Qa¿š¡3t†ÎÒ_ëöëëšÚŠ ûÕ ¡3t†Î³téT7 U°_ÍÐy_ª ñA°ŸçüŠ7Ô¬JQûMsã‘WTدfè Ù;³wž¥ üHçwKó«ùD:_sŽ¿5[}d?Ïù)c¨Y•" Æ`æ%*lß#ѯæ³èÚæOòÏx¬ÙêcúyÎOCͪ”n0{¸¸]…Žï‘îWóAtŽ\N?É%€úîc±$Ÿ ×»ìá ï1ý<çW¹¡fUJ;ƒ=_YÕr<¿Ü+#øÕ|«ŸlK›úyî•–¨b¨Y•"¡3{²¾ªåxr¡sýj>…ÎažwŸx-UÐí½sã£Ö_\ûQCùyÎoF†šU)àÌ`á“X¢ß0˜pÑUË!Ó;̯fèüWu›§ú ò/¸Æ/¿#>™žÌs<âç9¿n1Ô¬JÒ9ýñh &\tÕrÇôó«:÷›§JLÕׯ¤þˆ‰wßÃ2  ý<ç×-†šU)Nt>Ó`oMùÙI8²ÊBÂ1CtîÐ9뜰- ÛÞêÿÓmr ΞŒ‰a 2L«ÖÏ/ØÏsSÕ¬š¦Î—¥ä'Ç :wá:Ç‘áM›ÆÖ¦ÊÖê1Hz|qGçìùî⹨°åZ‰|pCͪ”vðÝ{Wýí·Ï4tîû,:9R@ÇgªJ5vµåªÁé;Ý)ggÖî UØêúì›Cͪ”.1ØÃ…V-ÇÃk½•îWóAtŽ\NW%¾iÓ¦s¹«ínÓcž¾1XÒ9Ƽeš‡ãøyîaatCͪ”npi' ¦Zî®ÂªÑ¾ ö«ù,:ßmm¾Yŵ®âç9? 5«R„Áå‹3¿)o6²Pá©fíWó‰tžji§-ÆÏs~S6Ô¬JQûMsã‘WTدfè<˧sÍÖr~žó›©¡fUŠ*Øoš¼¢Â~5CgèÌ'ˆò ¢³téüni~5CçY|éçÛÈ~ž³Õ#É2Ô¬JQK &&S`E…ýj†ÎЙ½3{çYºÀt~7B¿š¡ó,¾ôsmd?ÏÙê‘djV¥¨‚%ÃÞ¹áè Ù;³wž¥ V¼ÿùÕ gñålÛ(?ÏùÍÔP³*Eì7ÍG^Qa¿š¡3tfïÌÞy–.ð#ß-ͯfè<‹/ýÜcÙÏs¶z$Y†šU)ª`IÁÄpî̹3V+°"‰ 5«RTÁ× ÀŠ ûÕÌÞY-ƒçVLñ󜟆šU)ª`¿in<òŠ ûÕ|"¯9ÇÇÆF85?Ï=,¬ýJðî“”ï²TÓc0ó 6ï‘èWóYtms}ýk|„g<Ölõ1ý<ç§Œ¡fUJ7ƒ=\Ü®ÂÇ÷H÷«ù :G.§ð0ÝþêŠêж?ß¹a‚òóø=ó|L?Ï=¯í•pD5Ív0{¾²ªåx~¹WFð«ù8:¾¹ÊƒÎ¯ØÂu?Ïù•m¨Y•"¡3{²¾ªåxr¡sýj>…Îaž±sä_Êy·ŠÕ¯>‘,ù$_¹Ý-ÕÏsÝK› 5«RÁ™Á2F_3ª¾>k˜a{ƒUWYµfŸ¼›èWó‰tN¿D*~±P»yªçÙ·O•­>“l¤_gu™&þ´1ø»Þzñ”à›ÂW1ô‰*ÅÎ :wû:ÿÅçöÖ¦ñ•É)jÍßú©ärÉñîr¾ ÂÖ‹×}2”¡fUŠÏ4tîZýD:_8–Ÿld_o–\NéœnÏ#y3 Ç¿J¾ ¶»¯¨°õúÕmjV¥xÐùXƒAç®ÉO¡ó%ÄÝÉàÝÆ9ÝÏ–:–;åêÞ9%rIçìø¢Êñr„ ÂÖ+W|>ˆ¡fUŠÓ»‚½sj‰Í »†?‹ÎAŽò+“»¿QW≠i8ÙйѓÝÕ} ÂÖ“ ½˜k¨Y•Ò¥3{¸šªåxx­·Òýj>ˆÎ‘ËéªÄw«KUÒ3†5xö;ñ $B¼z‚Ñ=‰£½e&á8~ž`3Ô¬Jé—vÂ`ªuì*¬í›`¿šÏ¢óÝÖæ›U\ë*~žóÓÁP³*E\¾8ó›òf# žjÖ~5ŸHç©–vÚbü<ç7eCͪU°ß47yE…ýj†Î|FŸ¾Ï§ïÏÒ~¤ó»¥ùÕ gñ¥Ÿ{l#ûyÎV$ËP³*E,)˜˜Lö«:CgöÎìgé?ÒùÝýj†Î³øÒÏ=¶‘ý1¤¦)TÀÏBÐy6 Í´q˜¡O ) ÈÔ øY:Cç}0ô‰!ÅÐÀ¤l¬€Ÿ… ó>lÚ¸„S3ô‰!EX a‡(àg!èìBçŸÿDƒ^O4Ì~ÚŽ‘„K”ãtGNkSOÕ†>1¤L5ålá‚ïpÝ—käg!èü>åí‘yHˆÅn˜ŠÎÝѾ4úÃkúÄò°H§t\ç$lwX? Ag_:w—Ö°iíò´Ü@5Rº£©¦06ØÐ'†”±s¼»ºy…‰Ý0\÷º1 óGtŽgÑÄ©›³“ì`$M e|ù 7}y›m¬²K§µ¥#Y¯›ïõ ¨5¤¼^ö+Vé‰ë^Ѷ=ˆŸ… óûtŽ-_lÆg²?d´ÍÎ «ÁFË=x:fyݘÞ.) ÛÝ7}Ð’KúÄ"©dHLy7½»‹W½ël«æg!èìBçÌèB¦ L;í]:Ç‘%­kóë¨,CŸRFÍN~]¡aî^±Uqw¯2½12®“¯#tžŽÎÝ·°Oª›ër,Ù;Ëý46Ò€ZCÊØ9J®n 3®“[ñ³t~ŸÎ¥ÑU{gyŸÄ#”Ì4 |w/KådÃÜ·_&âº/ÕN¯ßg¨ëZ><>Üq³±AŽ@b:TâªÕ‹ƒúÄòbÁï…ëÞÕS8šŸ…Ø;/Æý»m²ÐI{‡úIJ·†’Ù-tÖLçaŒŸ… óªt^kWû°„é†>1¤‹Ù2 וËêg!è¼*·lþ‡“2ô‰!åa‘¤o¦€Ÿ… 3tÞGCŸR6ƒ Óy¨€Ÿ… ó>lzh² Ò }bHÙ@(¦ð¢~Z•ÎWÝ<Wà÷÷7ë1CŸ¨RœéWÝ¢²ê®°0ÿð8XËåCè|°äLýÏ[®2zm:_ýÉc„~ a'ÞêÕÆ'tË‚3‹òîÞ6á‹®º:ãÒ)´•<¢eGí%E³„£\—°EþGê^¸jbèŒiÞR`”ë ó[+È8_(0ªO8Ùøbug½Æ(×Eçôƒ)®?ËÍ‚ËÕ ’ËÝ]H’{B̨>yBg\·º3G¹î8:ÛŒrGa':W‹|ýZ6)Æf꓇t¶‰†ëlº½ž5ÊuÐY´”ô‰H&ÿ ´O²=iöÙóœ;›o«¸ÎßP¢+ŒrtþÇyEì‡Øùaõ²‡” 1 <Wûn„jËefe¤—¨^.–×( Ì"+RäÍ™‚²]LèÔÍ“Ó9[©ö²f?½si¹ÄUc”­Ú×E¡F¹î8:—„*ûäî™ÌÄ%µã3)ÐÊÉݾ\õ*iƒÅž¬ÞH„EÎDàV-åk̸ ™•§¢3®«¶®ò·¶Éï;ßí[KØe¾I¹\…ic7}Çôì¢w›ô»°´áÛ7˜rçUÕa‰V©ž^Ó)í;Km…KÖ¸¹f¯ªûëê=u®“Ø~”ë„ì†ÎÿΆ¼¯Ú›Y ÓGúz¶q;)oe7J9g̨÷g^WPî"É+¶.pË­«ä%cÕ~íFu[3§—äUrtþûÜ9lF2—»f‰­%1]:g86Ó¹»y—Ûtxä¨>ñ£3®nªn£\wË#ˆ€ã aé¹A¹Yhœc¤Ìm>¤žÈLA\}qzŸmvâ¼²—½];N0ªOÒ×¥6žÖ]w…rÝYt^Μ)0ªOžÐ™E\]Q®ƒÎ«;ç¬úGõ t>Ëgÿœí(×Aç“]·ÞÜ/¿Ê?ÜýÅÏr„Îëy彊G¹:¿·†Œä¯€ö£Ý«»jC‡¨Rø|g#|z…Q®ÛŸÎ¶«W—ÿP¥|²û ÿò”‹Î»ŠÉ¼„ ¼â:áµVý}çOï°\lV>¦ó¬2P×§ rx‹%û¯ò/hC„üe °‚æ7Im%Ä/ª€ÁB†”EÅ¡l'ü,´êɆ“Ð »´†>1¤,-Å¿®€Ÿ… sþªáõÅcÀÏ0ô‰!å³ép¡%ð³t†Îû(`èCÊÈ ÈÏð³tÞ‡MŸÙqÚ úÄ2íô)lˆ~‚ÎÐy }bH‚.:­~‚Îû°iZû~V˜¡O )ŸM‡ -¡€Ÿ… 3tÞGCŸR–@E~¦€Ÿ…æ¢óU x¢€ö÷ñŸ\‹\ h]'¼sLDçOÿ1&ÛW¡õCؾ20³OP¹N<…†(€'(÷9u=Á¯ÌÎQ:Cg@˜Qè<㪜³;`¦(€w @gèŒ(€3*g\v(€(¡3   ̨tžqUØ5   t†Î(€(0£ÐyÆU9a×ð³ûã„EdŽ® @gèC O蜞<„¹Þ YÙ95ï Îà j @gè¹ÏAÆ#—¿8‚¿–^ý‰–ÿ²¤Rûe”pŸ§ ER'DPÔ$5@tgæ©ã|Ã:\UyêåïùB?þì»`pþ³Å+¶à_¿ÿö¯ßs¸mÖËë[æY³ÑIj€è$5@t’ :I ¤ˆNRD'©¢“ÔÑIj€è$5@t’ :I ¤ˆNRD'©¢“Ô›pwÿPÿdÚ ßÚLýJl9ßÉæÞ»Í†¼Ì ]¸pìv®÷gd}Îßó…[wwÿм‡oë×ëíè’ÕÏnªÛàJ/3¹÷DfaÆÔ›s)s«9ˆ6 fcêíªÃ¢;8m.Ï u»[¨ôm<ÿÔØ~ÙBµz«WÝ%ÍÛZ¥^R·¬¶'w1á5NÛ+&©·+™¿£¦ º-φ{ß~w¿p`ßvc",Ù«¾uìz‚¸Û8¹‹Ö lE|_7†¿ l¤Þ®³'àgbÚõÉÌS}}¶“³,™§™Æ}ÿ×¹Éò$õF Âi[è‹° û8®Ÿ`TgfÛ¶ÆÝºÁ6¹¢¸9“?79ÐçjY0ÅLAP–1õú%§D[ “[-“Öºë~}~$gœûÖÊìºoáð—™ßu¦3]Cº1dƒC:6pwlÇþt:ýýן}Oûþ#ó,ܨÆÈ—ìÂ~ƒ^^ߎÇãóÓcòYcj¶b¾ùtW"©ÙŠ¢s®]HyZ\QˆNRD'©¢“ÔÑIj€è$5@t’ :I ¤ˆ.Ä¿Qôop‰ÏwqPPù¤^ì~¬7*Ü쇘& îý´`Iá’ºéîþ¡ú©­öµé6€k¨Ë¬U¢ÝŠm=PœL°ÄìÇËë[wá¿~ÿ­µdÈ-±ó7m.©$÷ÎÍ9×ûªô|‰6ïB›¼ nòƸɛ²+λj‰.4O}8ZKº/©.âzÉ»óen;Ò·knÎüqí] )ѳòãeŹb×.Ñå®(N¨û!sÖ}÷:ª—»g eJeÈ”Å×*N¦‰5OÝWß“ú¿.þ0—z\ÿ /­ªqsÒc§8™¤ü§ôZ·4í{©“öûýétê{¶U¯s•¯c€á”(KŠxEq¿ß—îä(QbLÝž\r Tç›Õ¸£{îY/©ýúüh­R/ɬØÝ㨽$7Øj@4+(ÑfËîf»ûm=HnœÅ„Hêݯ#¡>2ç•y­ ÛõÄb_Eî:éÙÚTß)m¦qëA·M²Ds‹%šÜfw;™ÕûúÀ¢$õ®1T™| ä5G"•LÙ%¤¹öÒjS‡µÃ ¸[,Ñ!Õ›o£>#‘Ô³ UòF%okì0ª@‡4î¶iµ‰æFKtÈ6‡´QŸÅE¹¢XUÿ•ŽQ2yáຯMkê˜ÖW¢}ªRìNR«Ï‚BŒ©+ÃäE•Lƒä’Œæ¼asÅî `f/}ÇR·M÷’#1­ DÏvµÛgõAá¤~~zœö/q“E“<ÌqëqëzK~_“÷2v”µšmý:j~O}W2©‡Ã•¶|Vj/të%:ásL%“úzßk³L©æÕ»õ lÇ6.ÊEúHj€è$5@t’ :I ¤ˆNRD'©¢“ÔÑIj€è$5@t’ :I ¤ˆNRD'©¢+y'—×·%ww8®÷Åð¬’%ˆÂ÷Q<Ëìèùéq™±2J”Êß›üýý}½ª0™¥8óÔÑIj€èVžÔûýþl›»û‡ä’»û‡ú'ß&Øÿr¶¥¥ü<õõ 9ò¾>?ªw÷õãúL¶ßïO§S÷ñXJt#V>¦âëó£9iV|_¸Ð¨hV¢¬6©GSê*O-­Ïúñeý…%ºqkžý¥:F6VëµÆ®»1C %ºeëSO˜ø«ŠØ¸ƒ%*T%ºeëLêݯ ë»Áÿ¨ÆŽ3!¦wJt«Ö™Ô§_v.Ý´N “G‚ÓFæ5-¦+JtƒÌSçÔǃc€Ù5Ïö&JO‰nÄÊ“zÈüÀSryòYbe‚±ŸÒK.Q¢Û±ÎÙ€5‘ÔÑIj€è ÏS??=úZ^"S¢DP2©‡CÁ½ÃYJ” J&µ¡ Á)Q‚0O ¤ˆNRD'©¢“ÔÑIj€è$5@t’ :I ¤ˆNRD'©¢“ÔÑ•ü.½—×·%ww8|5£(Q‚(|'ãñ¸ÌŽžŸ—Ù+£D‰ ü½Éßßߨ‹¡ “)QŠ3O ¤ˆnåI½ßï϶¹»H.¹»¨òía‚ý/g[*QÊÏS_Ïc ïëó£zpwÿP?®Àdûýþt:u¥D7båcê!¾>?šcfÅ÷µ Šf%Êj“zÔ8¥®òä1ÐÒ:ñ¬_Ö_ÈQ¢·æÙQª#aÔicÕ¸^kìêPMÐ R(Ñ-[ç˜ú’‰?XÌét:N—_PaõÖ™Ô»_Öws\W(kI}úe7òÒM§Ìkö„]7óÔ9õEÇójNz\2˜P¢±ò¤ûY¨Ì¯­åÝÏ®:TeB@+ÑÍZçìÀšHj€è$5@t…穟Ÿ}-/‘)Q"(™Ô‡Ã¡àÞá,%J%“ÚP…à”(A˜§ˆNRD'©¢“ÔÑIj€è$5@t’ :I ¤ˆNRD'©¢“ÔÑIj€è$5@t’ :I ¤ˆNRD'©¢“ÔÑIj€è$5@t’ :I ¤ˆNRD'©¢“ÔÑý£à¾_^ß îýÚ‡ÃßýYº\D‰DɤÞívÇã±l®äùé±t˜‡%‚ÂI½ÛíÞßßKwa~†*k¢D)Î<5@t’ ºÍ%õ~¿oýZ™}Éw÷™_'lá—wæì6™ H‰ªÌh6”ÔÝ2Ýï÷§_ª§æZ2\й»øúüh.©~Ö½z­Ö6«`‰ªÌP6”ÔU™–b©l(©cúúü莚KªÇw÷ÕOý¸Ù ¿¤õlf­dZÛIn¶ok™uû^HêD*³Õ¥Ôi9å?¥Ç@õI_ëA}W-iž-vÛ´–gÚôí7¹J~kÉu[ºËiª¦/J÷"Me.@R—×*âË]éÿÿ™ÍNØcwò±ú#ˆé®R1­2wa*SR‡<Ó¼dksmjÈf[“K¶o@ÝUv4­2w1*Ó·=¦n~˜©*ñºÖ»OUÏ6×½pï_ŸÍ¡GõëöÝ–õ’³á¶(QfqÛI½ëTsó×ÌSCt/­Ô[O%[vÍ´Ì?ÅMS¢\nC³7JRD'©¢+÷g)Q‚(™Ô†*§D Â<5@t’ :I ¤ˆNRD'©¢“ÔÑIj€è$5@t’ :I ¤ˆNR§ÝÝ?T?Í%ùögÛ iÐ×lÔëÜæn ”è¦Hê„ú¦ŸÍ›{æï7ðÎrU³yË´»5·¹[=%º5’úŒR%5|¬ÄÆ)Ñ-ÔCÕ'õ)góܳU©­3Óæ*­­%W?Û“äior/­–¬˜]±ÂwçŠ)FYŸ¶tÛ4Ÿmµ9;ªúÐüokƒÉ77›lÉ:(Ñ­‘ÔiÐUÇ6îX%º)’z~­‘ÂäíÔ£•îòé%zƒÌS',6kVúäó¾áý4¸2JtkŒ©†òéìê™É™»n˳}ËŒk.yD¦D·f:27`þöýÇå·g~y};nóœäBÊ×.!%š¡D‡¸¼„^^ߎÇãóÓcòYcêbªÑ„c€°”h’ºÁ)Ñ8\QˆNRDWröãåõ­àÞ‰ øu<%J-›iß]R7ëþ µÁ¾öuƒ³ïv)ÿ¢nT³î#J¾w™w¼^ñì;ÞW“»l±1Ü •h¬¤Nfb¾ýfC†3cÏgëcãì+¿ñÖèieÇ[òVª7­o|0¡œÎ¾ã™¾òn¥D71O×/Ùì¾s.?ª´íÎE|}~T?­okZ£Û¦ÞlwžzB7`1ÆÔÜžä…¾îøºoõî<5'©‰«Ïœâhµœ1‚“Ý€%™ý`%º•î§ñ–êÌÆ˜šÐº#Ù¾DÞ5¿Í6Ý9îîS­m&w:õÀ $5å³²¾ÝÇ™lM>5p¡È¦³ÑIj€è$5@t’ :I Ï~°w€…i$5 ùùógé.À­’Ô,äùé±tàV™§ˆNRD'©¢“ÔÑIj€è$5@t’ :I ¤ˆNRD'©¢“ÔÑIj€è$5@t’ :I ¤ˆNRD'©¢“ÔÑIj€èÎß›üåõm~ÐçLRÿüùs™~Ðg:þþëÏÒÝ —yj€è$5@tÿ²y¥æ›ëøSIEND®B`‚cluster-1.52a/html/images/filter.png0000644000100500010050000001143507555175242017335 0ustar mdehoonmdehoon‰PNG  IHDRáñDæjgAMA± üabKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÒ  %W»éšIDATxœíݽNäÈÞàîW{7ƒ´dC¸dn°—q‚ž¬EFHÀe’AÈdŒÄ\o`­åuù»?ê_öó!·]®*ƒû×åj7ì??Þw„ô¹;@/ —ŒˆKFÄõÛðæo¿¿L?Nè×Ϲ»pCýí÷ï%æÝþû¿Ç‡ûܽ8ÞŒ.4 w»ÝüñŸÿþïõõ5wG–kþäK¼”i ~,y»§u™ë(WÑç_})Pî+e-ø±äí^Ö‰Ì{†U—1Cm®àÇ’·{Z¿|»Ì²d}u}Ó|øùñ~u}S_\•O<´,œëhåióáܤ® ï¸à tæ:ª‘øY›¨¿Ú´¸W×7õ×ÂÎMn¨óáiÛMk›^ÿIJÓêüvþ®OÞáf+­†úzuLs„uš÷ [ƒÜúa}Þ4N·ö¨ö„¦÷--™÷‚àܼˆiþ¦šçÞ1W³¤ ]²u‚X8Ž36ÏæêkAªì›nšØç Õw¹ Ø‚áQê…M9o/ßáÖKHöŸçpšùè>Çœ4³.„OÕJ:Zi Þ'–;›8ëÁ”k—雚=o;çÈ£˜;íC3³Ze² <36MéÎ{ôIž´1Ú¹iJ…Íž^UºË¬ ‚´}›&Ëh?'6×ùsHC¹³ŸiýË.½ûöjÝ/ÔœyŸÒ‡ÖBßdÅ€¹×£^üR4ÜÎs›Õ¸ÐgX¦œ:‘O¯úì_–A 6 wf †#›K}´ä‘WK}#÷á½F×´*Yö<òå瘦wÆÝìv»sdtóŒœ2 é,“N®uV;Ë‘3$Ë)'¿ Õ×Ã35wdµ­Ÿj_°¦{-èÆ™>kÓf¢WlIF÷=gÒgZú”­jJác‚²oMߎÍòŸiA.N;ópªúSÇä×ÜÞÎjëT¸ éé5ï_±XÕþ½Ž)ú†äŸ·›Ò…]O¬\ì‚`âuŽIçî5Zò$G1_}cÒ¹}hý§÷ªÕV[S† šžÒ¥ô!«´ï;oÂþ…QOÏ/oooËþXL1Hu¯¯¯…þ š‚KÞîEhÝŸU .Ðç h‘Ñÿa P“Ñq­v>ºèÿÃlÊíímß+¼¯ãï¿þüû¯? }¶æéùe`«¹€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —Œˆ+Üÿ¿º¾i>üüx¿º¾©¿SÛ‚Ýò —Ñ»$L›g%u«ð²”ÈhCs(NÝšý¨^]ßT_͇Óëlí›ÖÐ*3· €ãe˜ëxz~IWþýןõrƒ#ßjesâ¢^î)·*ìÜ·µ–IKv°V‡Ãá×Ïn4Ï|ôáph­iùÄI‰éCÚ:[öMí{÷².™°VwwwYÚÍöžáñ/GÇÌ/OÙ7-Ó__þØšæ£GMP÷•™¾oõ½Šé™X(â½wšÃÓÖ»çéÀò”}›kÜ\L¸Œîœah®Oúvl­ì[îÛÔ×€‹YÃ\ÀZÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . ×o¹;@hOÏ/¹»pF‡Ãá×Ϲ{Cd4#ÞÞÞrwá,îswÆÉhƽ¾¾æîÂéAS„R3zÊ5¸+Y t¥fônìÜ•,°gônð|`}u}³Ûí>?Þ¶ÖúŠÜ~¿¯¾¾¾úÖ@|egôW×7Uì¦ µæÃtë ûÀ™ì÷ûf4}}¥kòõfØÜýÑŸïW×7EkðPÙ\Fïv»Ï÷¹]Åzs¹™ª›å;Ë´º$¦Ôææ:j݌˺LëÕrkHžè\H›N÷mm=æ`·¦šÜ¨—óvŽ±ÑŒAb縛§F+L«š¾ Ì>³[Ìèæ¨v7? G‡À‹ãÕ8hÙÜ|tkÚᘉàz¢y×3¡<«æÖоê[ýµ¬‡@é67ŽnŽvŒ£›Y\OJ4ëI ôUrî;ü¶,6CM¡ ÎèLJû#?êÝ‹£+;ç:&>ì›Ð'—±h¦D¥fôápÈÝ€³+5£ý±$` 6÷ž!@AJGs1ÇÏû‹Éh†˜÷‡¼d4CŒ !/óÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 .ÿs–!OÏ/¹»pF‡ÃÁ?Õ%8͈···Ü]8‹Ç‡ûÜ]€q2šq¯¯¯¹»pzFСԌžr îJ(]©½»w% ¬@Á½¼A_]ßT ŸïÕÃj¡¯pkk½¦®§®êHmÄik‹i¿ßW ___Ó7AXegôÍœZYÍ€nî›=þ¦tàóã={?Ïj¿ß×ùÛ\Þ‘múþè*­ªäªW¶–'&ÚI‚/íÉŠóô$/ë³¹qôtÎ¥T+›Cøf™¹uö­iMÂ4Š{(Ñæ2º9V=Õ$r³¶Î¹”ÖÂÜù–´|g ØZ@›Í`56—Ñ»®gzé÷‰µõÍ–´Z(S—ìl½¯|gå' Y“-fô¹MOöÓÖÉN@³:›{Ïpt»›ÿC_ƒß2í§å§´²šõÙÜ8úTóÑ­zú–OÒ‡´|ßšÏ÷“O¸—¥¾ z·Û}}}Õ©]-×ëótæ+8£î—}Ô{ :GËL)ßÚ·sÓpýéÖYk:°niø6׈fJTjF‡,íý1r{›UjFgücIåÆ\¹=‡ÍÚÜ{†)uÍÅ,ž÷Ž'£’kÞ¨Èh†AC^æ£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸ü?ÃËyz~¹ds‡ÃÁ#\¥ ŸHæ¼m‘Ñõööv™†î/ÓY\ìDº0çmJF_ÚëëëZ1Y½ËœHæ¼M•šÑS.÷\4¥+5£wc—{.š€(û¾Ž×~Ã;^]ßY  ý~Ú /öC8_C­šg54¥ðÕõMZ¬oÇj}‰§Ö‘öÿ˜µ‰JÙ}*'|Údyz–×?«Ï÷35QÕ|¦_ÊÕõÍ‚ž~¼o*¦÷ûý×?ZgéÀ&j[Ìèꩵ¦çIu–çîÅFµÎ¥Á½¦S1åÌ<Ò3ºÓÀõiëz¶oÍhUñ-;Øæšz¹óÒYÛ@zë@Ò&új®aÙáKwï´²§Uð{†ËÔÜê‰Qy:Ç>ÍÍ›kêõi²,8Øá]RÃ…;këkqîpu æ)Ý[ÖzZá@ÉÖáwÖS´jf#w/ʳ¹Œžkô¡úÙµŽ'Ò°ô`û€uÉè™ØâpšÒG+lí>Ú™ÎÖ;vJ…• w²Pz±-fôÜgNkß4qFsaM¦\t:2¬û:p*»7½õ¹Ç»âq´€>ƶæ£ëAPý5knq`ýF¦6]sŽ0íë@kz¦—ÌÃ?²ÑÖ¾­³tq‡#ÐGÚâ8:Õ÷k>›ÏÿÎ2çˆsKv—Ü×y°­]¦Ôß\Ó’ÖÖêÀ¬C›2#ÜZ9|øSÒ½BO˜éš÷ÕU·ÙU©Ý¼åNŽ÷)8£îç~Ô»3…;7 \Ë®Éõ|;þ,Ÿr Ãef=Ü5²o´üèìÊpátžwÙïqÖL÷ÄcÝž–Í5¢yT©}8rw­[vÍ´úQ3§UjFûcID° m4³lë=C€²”:Ž.Ô‚9tH9‘¶CF_Ž9tN‰´)2úr |8 'Ò¦˜ˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqùŸ³ yz~ÉÝ…3:þ+ÁÉhF¼½½åîÂY<>Üçь{}}ÍÝ…Ó3‚¦¥fô”kpW²@éJÍèÝØ5¸+Y`ʾ¯ãµ_ß.W×7£kŽÜq´Âª:÷=aÓ«·ÿǬMVÁãèUúüxÏÝ…‚í÷û¯¯¯tyxDVö8z™æ`súÀóóã½µã1y:«‹›ÞÚ°Zò²>[ÌèW×7ÕWý°µ0e¯#;Ðü>eÚd X+Üâlq®£J®æ÷æ¦jaÖ0yÁ^}hU5\çhÓuu±ÎÝWÆl«±ÅŒFXµ¦Ê²V°öíÕYçÜ4l•_ÖtkßÝ(‘€fM6šÑiØíþ=>E0ºW_,vöa–‰ÞÔ8Z@³2Íè‰Ò ‡ãƒu±eM·vY_(7 hÖg»¦Õ²wØŽy_îÈÄm:×ËIFÍÛŸ¿¾¾êÔ®–ëõy:óœÑ÷ >êÝÍ}[ë‡ÃCѾ½ô!5>¦é­t¾Í5¢™•šÑ‡Ã!wήԌöÇ’€-ð€¸JGs1Ëæý“Ñ 1ïyÉh†AC^æ£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’Ñqù_YÌöí÷ï¹»P¤ÛÛÛLJûܽ 02š%üŸÃ¹žž_rw"™ëˆKFÄ%£â’ÑqÉh€¸d4\]ßœv—«ë›æW]~AC…{ïX¹Ï÷¾‡W×7­­q4QT‰i„ MÆÑÄÕÌëjÀ›®©KÖ†‡Æ­ÍÓ†Œ²ÉNFB•ÕPºÇz¡Y µf´æVUMi²§ AF2š•›µæXˆIFEÞ”4j&&M~é¬ÅÜ;.ê7Z7{ŠŒ&´t6y`~yn¶ÖsßÍûI4¡ÈhòHÛÑ ŽÔ¾ÝÓúgU #£)žûäX1M\g3¤3+æs†qÉh€¸d4@\æ£YÂP…ËÑÌv{{›» °2šÙîsw¶Â|4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\¿åîåùöû÷Ü](ÒíííãÃ}î^PÍ¿~þÈÝ…Â<=¿äîE2×—ŒˆKFÄ%£â’ÑqÉh2»Ø OÏ/ͯºiw\™{ïÈïÛïßO~3ßÓóËßýÙZy8Ò¦Ÿž_¾ýþýîî.-ÙG“S•¤www稼ó³6¿~þ¨¿vÿ¾ÑÛgsÈ8šÌê‘l—õäC=°]Óœ¯¨ËŒ[cíº|gåFÙd!£É¦ŽÈj(]âßýY i«•SÖìó­5Í‘r=`¯·z…¨–«òÕî•ût%—'£É©9|®—ë…*+›£ìzMý¾ß®‘³ÍªZk*ÍùèÎÀ­VW—$£Éit&:MÆjMúîßDS¢vqåpr2š<šó•tú8½7£¹¦óžc¦ø¬•Ãt2šlÒ[îêYàêas^xxÍÓóKk®¹9Ç=E]¾yŸI]ùG G‘Ñ䑦g½¦9¾nNC¯Içš«2õË@_‹­výüѪÜPšŒd4ÙôÍ5o:fM_´ÝÑá2|†…50Ôe­d4+a¨Ë*Éh€¸d4@\Þ3d ·£ÁeÈhf»½½ÍÝØ Íl÷¹»[a> . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqåùÛ¤wwwYÚ(K†Œ>—o D2Úÿo˜È|4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ5ôwïžž_.ÖR½}{{{É~Ú~¼çîÝÌGÄ%£â’Ñqý?x€8Ò˜IEND®B`‚cluster-1.52a/html/images/filemanager.png0000644000100500010050000000415310046571610020305 0ustar mdehoonmdehoon‰PNG  IHDRáпyNå pHYsÃÃÇo¨dIDATxœíÝ±Ž›H`ï)os‘.ÝåR¦Èû¸M™"±Å–ÛeˤK¤Íóä $Ä10`ŒÍý}Š"Œ‡a¼àßãÃÃëÏï"ýµu%£rÉh€\2 —ŒÈ%£r½{âñéùší¸[Çãñ÷¯ƒOfôápøôñÃeÚÀ,Æ:rÉh€\2 —ŒÈ%£rÉh€\2 —ŒÈ%£rÉh€\2 —ŒÈ%£rÕ®{GŒ…½¨\nô$2zg^^^¶n0áë—ÏkU%£÷gÅÍ„3 KFä:9£ß¾{ßý×Ìiÿ¯/¸ }s–ZVóÞõ¶Â`ÁézÉ™ꕟ¿Ez5L¾Ø‹ª¬ô>÷=®iI?úõç÷ö_ópíV1K»n&)*/dæ‹=çO±íŸqÎg-wÈXÇ-˜L®^Þô™Ÿ²eåýؾ¥Ï$˜´Ây½÷dûþ{£–*sæ,EW»9š,;).{äæaoãVÞ>œÜÆæt¶ýå9¬°ÛþúºêËŽý%'÷ÏîÃÉ•v+鮫œà-Éèɬœ®èÍé•\ª,Ccñ›¹¾iSI1dó·õà稬¢¾®Jóêá8gÿ«ªþ{íúž-Éèú³ 1¼n(ôººƒÝÞŠÁ@™\|òpb[IYÏÌæÍ? W®klÙ²ädcVÜ?Ë®7÷lýß°œºcÍìÛ_·µ`ääPlµÁm½¬æJ…ó×uÒׂ:û'rÁc†êùêP—*iòÚ9Â6Ø­ž¿–nUcs*-¬Ì«gpþ9^©s²äÌ{þþÙ‘?³*nÀÊýè^"Ì)0ç?g©;4ø§^a“Ûîpb²Ÿ´­'?9Û6Vá`Æ ®«l^wÙÉ}xì•Îÿ›L~jžó=ƒð0¶íŸž?}üpåÖP÷øôüòòâzïïþÝ»JaçGä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’ѹd4@. KFä’Ñ;óõËç­›\Ï›­À ŽÇãÖM®JFïÉï_?¶npUÆ:rÉh€\2 —ŒÈ%£rÉh€\2 —ŒÈå7,{òøô¼u€YŽÇã*?:“Ñ;óòò²u€ +^WGFïÏ·oß¶nP³âeŒGä’ѹfôÛwï<Å…<<6§ÿúó{óìXáîÃzIÊ!ŽvΟ?z›éf~YÈtnF7±Û›.ç”å+…{Úd¯T{‡zÛ›ÓL·aÝ, ºöùÑe¶Î?Æèhä$áÆœ–Ñ«w`{½ãza}çIzÄpcvyÌP‡z’5܆ÓúÑåq¼vÎaÑÁ½îâóKêP:‡çÔ;ÔóKÛ:y<ºÌÇÞœJ€vŸê¦ü`™Ê2^{sÚ‡• Ù.Ç:È%£r¹~ôÎ|ýòyÅKÓádôžÇ­›\•ŒÞ=h¸7Æ£rÉh€\2 —ŒÈ%£rÉh€\2 —ŒÈ%£rÉh€\2 —ŒÈ%£rÉh€\®MÊfÆnôþöÝû±{Ì÷î"þmˆW¯Ö%£ÙF/ˆËP,ÓÍÐ^¼.Ö«SLÅXÛ85 +}m¸a2š QÉûöÝûæ_û°2±V§zŒu°±z.ŽY¯åÝx~©·°+Ïù€áfÈh¶4…3ƒò'¥S [¬}( ¹cl¦ ÄvР2tØ]mbzëVp›d4Û(£¶éŠ63ÓRøÐé/÷¦›tÓ\ÈÉcƒƒwרb™É}©|WÞèóWÝ–´[r c;ÖãÓó§Êù Ž¥œcðë°7pKþþçßß¿~ >uÖX‡ïwµæyåwÃÞ˜Ýaèû`ï{b¥’S—\Àެ™ÑeªvÏOê=Õ{XžÒTV2¶TY¿SVÛp‘~ôü§ÊsKç žŒu«+ÕìÑj=vYœúS‡ÿŸÆtX4:1v™4h`ïÎ:fx~VÎ-=çh¤SVÛ°¤=x° Äî€C}¬£­ª<)uNwxlÕÇ ;ùühÖu©ó£¸(×½cƒ7©Úä—ßs.oàø3[‘Ñl£¼ëÕüË ¬hì„}a¬ƒEÅbNK !£a@ïFYíÌÞt·Xyc­^ n©ÅÆ:ØRyC“mÛÓ8iÔ¥wÕ± ×'`ýh‚t/ó¿wå œ³Ï2šÍÜ[2ç‹;"£I‘_3Û° ©®OÀ2Æ£I±É±z¡9vM‚^áQk¬ƒeü`c~ °K2 —ŒÈ%£rÉh€\2 —ŒÈ%£rþÎðx<^³”F3zìG/\±€\2 —ŒÈ%£rÉh€\ÿßÞn3&ëfÑIEND®B`‚cluster-1.52a/html/images/maxifile.png0000644000100500010050000003002707505046646017644 0ustar mdehoonmdehoon‰PNG  IHDR³W-<ðgAMA± üabKGDÿÿÿ ½§“ pHYs  d_‘tIMEÒ 4é†Ô IDATxœí}MlI–f”hÑ–iu÷–k€Q².SUØ“¾ŒÝ ˆ?‡•<@Ѥ ˆ¬Ô‡bÁԺȀ(@ÖÁô˜Lɧ@^l`P¤9ËñçЮÙC1 ,¦j.f‹ª)·”)˦LŠÔž %L‰*KÝ›ŒŒŒ|‘Éxù"â}ïévwwÑYB­öÇòÛ¿?m)NzýïŒçþå´¥øåBÚ0000œ9èBÉdÒétªª Eóóó!Y–'&&œNçÄÄ„,ËpÔIªi §§§OD²X¬48´Žq¾­“C“Sêàк¢ÔèšÙl!¤(µÁ¡õ`pN¡ÿND*†ÆUx”##ðøž¤¶'§ö~‡“Sj,VBûÏãj0¸I?PY®Èr…Ÿ/N;Ž|>/B:ŽD"V«UQŸÏg6›ÇÇÇI!Bˆçù¯U …ÊBxëÁ‡ÊåÊ{帗,–®Tê­×k"5S©m›Í˜Í• …½n.W¾sç¢hé>yNW¯]é÷_ðŽ™²¹òÐõ•§}<§ÇK–8E©¥RÛ…BÅë5 ;¹\Y raG Þ1´ 8„ 7³¹òìl/B(ÞÊfËÏVúTu—ülB¹\YUwÇÆL.u78³i±t{ÇL‚` ¥jØÆÕ¡ë´¨ß<ÿµ ÈLQkSSªÐoðzM¤P.TFG••§}piø€â8BˆîKpf38ó ~ç#(Š …ÈðlÿÜd2‰D$I’$ÉçóE"Ç Áãñ¼xñ¢ÁTU ’$…B¡NÚAaŒ=O$Ay<žb±(B‡²y<EQHIü'I’Õjõx<@  ‚011áp8æææBv»=ŸÏ‡B¡‡"„¬V«ÝnG™Íæb±-„wÌ‹—0Ñèk×gçlÆX¼š!ärõdse„P.[v¹zˆ¥)Zºm6ãÉJÅp"ˆF_ÛŒ·g{B6›‘ãt‚`€Í–µf0fseE©es彇(†úª(µè—ožÿñW¢Øú …ÂN³ëBŽÓ×7Õ¬…ð-jA>xa“XXØÂk‡~u6›±P؉ÅK þêÅ&ØŒrsŠD"!I’Ýn¥v$Íèv»7660ÆÅbÑáp$ «Õêv»G(’eYÅc Š ì§Áó|:¶Ûí m;׌úKJöÖEQ …BÇl6ߺu !T,é>X­V¢€Óé¼zõ*˜t¡Óé<)«!Äñz¿ÿ™§ž¤Þº\=7]=¹\™h@A0(Ê.Œ"ÛÀÁOpèÆºéü¦ó?°ÙôYƒ\رˆÝ¡l¶¼ÞRÕ]xšF¹P7¼ð r…¨•px ¨éü¤)Ð_ ÎÂ[©}K”B¨¾~34kã*ˆ °ˆÝ䇜ÙZ¿vý¥¢ìc–@ ¤&ƒüžÉ´=/ùýçÛ¿u­¡( ÌÛxž§ ö‰D`ø“¦8Žƒ–;lnnîáÇ'2§ä8ì°@ йM6??Ïó|   v`æææÀ'%ô ?û|>°`#‘QÕ>Ÿ¦äf³¹)5ð~>•Ú&?¯l¶¼¶VåxÆÕþ~C,~°HtÓu.úå„m`®<í+½¹RzsåÙJß JÅÐ9xN§R‹k±X ¬~›Í˜Ë–Ÿ¤ÞÚlFÛ€1—-Ë…‹eor3;Û ´ôæ 9æ§d©ãj˜z›Ö×o†íÐ¢ÒŸÇÆL.×9Œ«‹‹5s ˆ`{BOýþó…BÅï¿pÓÕóNñÞîÞ½+I’FSœ5¨ªzõêÕ|>/IR'íȲ Z Ú!k M÷¦}>Ÿ$I° «ª*¬;À!«ÕzëÖ-X‚$û6 ¹ív;¼^N üa³1/õ÷¢Ñ7 á-ž×ÑËç.WO,Vr¥_C ¸\=±xIQj6›Ñÿùyž×A¹ÅÒ%vx^'—ë\6W^[«Òó€zˆbw¿Þ‹·g{[W>F;°ªSQjd‚Œ-Ý_ø/øý¦í¢¤RÛ.×¹f—ÃMWÏãG—aAóx2×Ãjµæóy„P>Ÿ?êÔu~~þÞ½{hß"MÁDðD&Â'ǃJ§ÓLð°‰Bnv5« û*f³îŽÇãÑ,XÌÍÍÁbêÝ»w;”¬5üŸŸÿäÓŸàs*µ½´ÄÁ VQjþÕ‘B›Í¨ª5×gçTõÀC38³Éq{ÚñÎEQd»1g^¯©P¨|òéOKw¡Pá8=h"Û€qm­zÓu!Äóz„P¿> 0-÷•½òø?2ª¤RÛ¡Bag¬nbÛ&¶ãõš²¹2Õåê! Ü€Û³½±X)ÞZ\¼„öuWa&éôz=ƒ±ÙŒcc¦àÌæ7Ï}<™5€½Ø6!ã¼M8²å‰DÜn·Ùl†u³@ p²FO'H&“étíï÷šãñšEquu!”ÉdÑf:ÚÓ;“ÉX­Vºÿ°k6›É¬™®Gív{ý‰Çñô†4üôe¹¢ª»KW¡°C¯dËr…ŒA0ÈrE»¥†qU»5ïa‹¥‹Tf8#À¸Šq•ãtôK+›-“‡o>8 ?RM §£ðÄɹŠRÓ¥›åy}³ù¯¦ZT²M¤iŽÚlFò«#1èöm6#-TÐ\®Oo˜Ç’ªªæóyÍçy¾sÓ Ë2Ïón˜@É×Q>Ðq¢auŒÃÀpÁ80§ fC1000h¡kgÏŽá—½þwÌfd```Ðboo:+Ñα@?Ç«l¶Œq6ãb±¬@ÓŽ„@ŠZo‘½BhãtÞ1,*kŽîQ(æ4ò:ÌÀðKÀ“Ô6ÏéO„Ô â†Ù!Π`à‰¥ª»´·Ã¾3D¼Dïä ‚øX-„·‚3›P>õ{ÕyÒÂá-Œ«ŠR»vý%èÍTêí'Ÿþ[ÌpôàZû:1›-×Sú:A,VUhËãØP”ÚÐõúñ~<œMÁFF•\¶¬*µk×_§ÔF›ÍHk_‹¥K.Tl6c.W0f³e`€ë B¨¡ª¸ç®5‹FF6ÀÑ¡¾&KÐV6[>©×ÃýèëhôM+BNû/Îiêl †q5—+÷ï¿ÓÔ[§æ@3Ò>´ÏVúlÆBa'›-Cø†l®,ôh—+â¹ê3‘‰p*õX(àÞå÷_ j‘8] åágÂMWÏþ '(à›ç¿†PC7u6£ý¦Á@ÙŒ4%~Àf _ñœnÀf´ ƒ3¯DK­¤‰¡×Ð$Ìf˱x 8¡PslÌÁÈÜœáÄÑš¾}ŒÖÈ:XçMH;¤µ“¬!4£&(“hé^[«fsåÇþËDZu6´û\®sÑè›Û³½^¯Éë5Ñ﯉ÐõN ¯aÑ㪰?Ù?ÐŒÙlyí-gÚŒ6›±¿ß (»p¦ÍfŒÇK‹w.’útp0b?zÇLñxiphhR¹\¹>4à ŒÁঠTµF"€ˆR£9›àšÃsz×ÍsÜ…â9½ FþaOÍq‡ È{8mÆ+W “ÿëükjBæ¶*ñÛ•dŒi†Ÿ0lO$ef0¸yR£U–+×®¿}B’”t‚X¬ÔNJÈv Ë•+þHÇŽ8°é¬làœÙ|°Ä•Þ\y°Äg6Éiï?ÿßøJ‚î@áÊÓ¾X¼Dn"IÝGvÀŒðuv¶—‘aNŠR[[«Þ¹sqåií€|¼¦äÂÎó?þji‰ƒh2 Þú ¥7WDKWç‘ Â[‹x’Úº±N'Ò@´fĸšÍ–áAÂ{WqTt¹z¢Ñ×&(v{ÇL`!$*Ðà‰¼"Þ ø’Ë–£Ñ×&>ây=D‡ ‡·ŽtŒàñãË_FuÞÐÇÆÕ¥¯N&cW¡°óøÑeMá! á!>³õ)ê®E<ðÆCvÿ(°¸9NçrõÔS\8^¯ìçŠÇK)î-BH´t;w.WØbéZZ:+©Èþb ¨5×gçüþ ±xirJí<Óºªî ý†BádŒ›ûÑ×ñxéùÕa;–¸“JEÛ0Ö×fôzMt žÓÑ„mŒ«<·—xåiÇé†n¬ ‚¡þ¥¤*5RsñÎ%‡úÀ€ñÙJß䔚Jm;/0C3ÜtõÜÜϺ~"1r ` l?tH8¿ò´ïìÓÞššµ~ÿ…ø~8Ûl¶—üþ ä¨(v/-qt4==½¼¼LŸ/Ëòðð°ÓéL&“P2??ït:'&&ÈY²,;NrJ2™„SæççIz ­Ó²\‰ÅJš(DÅb%ð ¬mY®LN©ƒCë á-’C–9EQj¤&z’ÚZŸœR5'’ÆáE©Ñ"Õ_ˆÈ09¥‚{in0Ü$„ÆX’$EQ‰ÔÎçóÅb‘nÎãñX­Ö@ àñx0ÆËËË’$…B!EQHãp8Òé4ÔO&“>ŸÏãñD"uâÙJìëÃQìÆkÕÛ³½ðJTu² âµ*ÐåÂBãjpæTú #£ ݲ¢Ô€t §g^¹\çàZ eâ±Ò³•>ÿç秦)nh\Qj#£Šÿóó<¯§Eâ8æBDï˜irJ%-h” ;ÐÂãG|_¯}>Ñí X,®®®®®®Þ½{WÓŽ$I’$²êP0UU}>_>Ÿ'%{³iI’"‘H&“ ¡PH„P$ñx< AËɲ\,€Ûí¶Z­‰D"‘Hx<»Ýîóù@Ÿú|>ZôP(‰DÆÇÇÝn·$I‡£^ á­Å;ÁýJÃíA¥Ro…~Ãì~áƒ%8B¿AQk­©¦ ï\¬wâÿÂA“éQU÷LH›ÍØ·Ÿçõ‚`hhá/2÷øÎ19¥žµÄm'(ŒÊfc¶$I šñ(Âêê*Çq‚ (ŠÒäÔMq‡òx<í¼¼¼lµZ­Vk›Me2³Ùõ{•¦ý „TµVa3—WfœíÝøø“Ÿ&§Þ:uíúK¹°Ó‚8Åsz¿ÿüBÇqJ~áøþ»ß¼“¦õžq‚"‰¢877wTÅ177g·ÛZ^^þè£Ú4Í@"„TUD"ôYãD"177×¾T O‡¢(šÙ´c –L&Íf³¦ûöÑÜÜ™S#„2™L±Xäy¾X,šÍ棾‚Z€¼|Z,26ÃâK0[\\¼Ô¢ÏéhË«…F“ÙàÌ«ûÑ×0¹^yÚ§ÑAWï\\¼sqª‰¦S_T´tóü×ß<ÿ•Ëu.8óªEâpèÔ7Ï-ZºZ»éê)È•³O®bø‹Áøøø‹/š™G ¡ªªÇã‰D" Œ`fe2EQÚ\t»ÝwïÞµÛí·nÝ¢§º²,çóùo¿ýöÛo¿íP0Œ1Ë iªéÌQ’$³Ù‰DB¡Ïó 5#XÅÐÉ|>v2t¾ÖŸBÏÍC¡ÐÕ«WÛìÒ‘àrõÀ‘¡‘Q¥…V";'‚`P÷? „x^O¦Ã‹¥[»E±{Àf¼_“MQjÙÜå^UwÁTäyýMWhé"Ù¾¡|Õ42`3⵪ÆöÔÔ\ZâØœšá=cL6+Ìfs›jY–}>_$E‘.‡9l:V…Vs-L&3™LÃCdêi6›Û\Qm&,}‚`¤©¦„óD"!I’ÛíF©ªÊóúè#°FOÐ¥áõš&§ÔÉ)U ÙlæÈÍ*ÛŒ#£ ë…ÕÉ‘Q¥PØÁ¸Ú,&Ýþ ##+(/ese„P*µ=K-h ‚Áf3­ÛlFPs6›‘ãt#£0oJ¥¶I€9bœ¦RÛ]iA~8—–Ÿçõ~ÿùÑÑv×}ŽŠåååññqAÒé4( EQ4 ¥!À(óx<°ëàp8@sÙív2N§Óm.£Á|Ùãñäóy˜ÿ‚`¢(’ùµ¢(ÍÖŽ!iê§w&“±Z­Ç©ªšÏçéëɲLVI!T–e™Î5›ÍÄ^mØš¢(pº¦OoY®u7Œ«§£wH¥¦ª» >à¦>ÆU‹¥«á¦ Ýš¢Ô …ºf6[ƒFŸÒ+J ã*Ïë‰q×ðB ÇéèÕCˆ\B¬KY®xÂô’(œKÄÐtBB‘;P/!C À?SÑL4"uèé­ªª¢(ôd¶Ȳ ê|@û“ÂvÔ"Úìä«Ùl½AKB7ÞfƒDŸ¼7Á†á,‚q`NŒÃÀÀÀ ÓŒ Z0ÍÈÀÀÀ …! e2 AÑòò²,Ëàs³¼¼œL&éCªª’ýr„ªª_}õÕÊÊ l7#„ 5Œ1´”A¨ Ë2lòhššŸŸ'§ïîþßjõÚߦ ±XI»!Ùp …¤¦,WþíWzzt©Ô[²AWÈf˱xI.T>þ›®ž´@Z#»W …A0,„·È¢8)<ÙgÀð3žµÆíŸ>šÍ–ÏȆÆÕè—oÈÏ!¤Óýµ¡kô]gá{÷FcP§ÓÑCµ5` óÍ7Ÿ~úiOOÏ;Ë[ôÔta&“Éd2õ27Cë>BkíSé F”ØåË—¯\Ù‹ä­GY­ÖH$ŽKàò7¸„’$‘h´Ë2°Ñ¬ªj&“ÆK$€V«5Nƒ{£¢(Äõ‹ ‡„H#›+Ó>}àŸ˜Í•é@¤jÊr%8óÊ6`ĸJ'È&Hf.žÓÝX—å ^«>ÙÏ‹—HæXúq©Á¸š=Kd[†ÈfË#£¡è—¯ëYCWGF7h§×S„¢Ô®]Y+¹l¹ýœV0<­Vk±X$!`B»ÀápH’Ô̰>Ÿçyžç5”àÅ™ÍfšÉÖóóóÅbÑjµú|>šÍaµZÁ §}~N³>"„B¡¡Át(xð†Ü±.„Çq@Ìöù|@ €‡$IЙD"Ž`ŒÁÝIðJ§ÓgnnÎl6‡B!hÜ…tº½„‚à²Í¢æ>áÍà÷ŸŸšR!q- P‹ñ`zÇL á­ÇžX²\á9!ÏØlÆ`psv¶7/ÝtõÈrE´t‘ˆragqш²XºsrFŒ †6‹—\®žÛ³½B¿a!¼¥áÎŒnœÛŸçõ]¶ÙŒ÷£¯³mS?!ò‹Ûív»ÝN§“8åI’”H$8޳ÛííøúaŒyžC ”Ж Œ}ÂŽ{'Òéôêê*B‚Ñ×EpˆQUU’¤‡vÒGhØö€ Q3à.E"âÒ¸§5Ün·ÃáÝLnQ—’$5dò (ÜDp›*!ù*tæÞ½{À’ (P  åóù#Å•-ݱ›z¹PU¼c&¢9^{¶7LýÎRÿz(©!ð£E±´!o…J ‹çäÏdÕE kk‡PÁà¦ÅÒ}¦¨Ó gf^i¨ú-@Æš„¡%ŽÚ”†Râp8®^½zõêÕ6éÉ %¡1kÚl¡Y1Æù|Ø(&yy>ìÀH’T,#‘x_õ=(Šf³™";¦§§!þÇq‘ |ÐáóQmF„ÐíÙÞhô ͆ŽÇKß<ÿU,^¢ a}ðéºd ŽÓ®ÏÎ¥RÛÙ\y€òÎ ‹ãð—'©íX¼ärøªªµ´Ñ÷Œ/üžÿñWõ™ŠŠP(œNg'c“B@"‘8F  Žç^A666æææîÞ½Kèybbbâ„Á×ÍHBæÀWX4›Í:4f}[ Îƒ Ú(c¢ì§§§aulr°ik”ÍlFŽÓ)jóx\‡Ã:,Þ¹ÄóúúX³³½ á-`C»>;G¯+a\ÃpÀfŒÅKðLÈTê-0ÿöâ8X‡?b%ÆÕþþƒ‰s¡°£ª»££J<^*vÎÂR# TLvÿÚ9«_XQh±SÚm¦‹E‡ÃÁqØ4m’ ê->ßÕ~ Íúˆ1n õ‚©ª:11áp8hÎâ;xÓd*n6›AÒ;0>ŸÏáp`›Ãb-ü ²,G"³Ù a/ÁX%A€p> ß!7]={8}6WçÅn‹Ø=ÖA»]®ž…ðÑk<¯¿=Û TeX(„@xW£_¾ÚòMWÏàÐ:Y‡‚U¿ª¸´Ä]»þ§úðe gÞ1ÓÈèÆBØJmÃSƒIôíÙ^xÖ á­l¶¬Y<-Lý^-*@fm“³ëQ<ÏÛÈm°ÜoµZa¢ÖNS~b ‚M+v»= zM§Óm¯u8óóóV«V÷ôèDKw=™šálB û·F¼VüŸçàÇóã5ÍãÓ<èÓ•+ï˜éûÿ¨þÍÇ]‹w.µéµÓÓÓãt:Ÿ>}Jbª®¬¬À–é÷ߟÏçº|4ÃßýÝß=þ|{{; õôôȲÜÓÓÃóüðð08Ÿüá¨rЇcüÝwß…B¡>øàÇ$6šªªíì½³¡üÇL$ÛÛÛøÃÚt'j(˜N§Se{{¶I 8b¼i†³ Æ›>]0 ƒL32000hÁ4#ƒ]!Œ1Ķ…":¤&*-įÕ,ë¾3rm&“áy^EŒ1‰ L7E"æÒÍBÜVòÖÎrQ ò+  1e›Å»ÕD%…ätÿ£ÅÒ…ÒD‡mÿrtTZt8Z-d $‡ p)Ù"МHǯ¥ÃÙjjjv MòèÒ¤CêÖg_ Oo!˜ÆË¤Eß34·TŒ«ŠR; ;0¸±G ¦Ko§ÀlºuS0NëiX1m¢>B-¨šv£¯Ø°í F×Ñè:à­Iƒ±­@‚8L§‡†PãÄ‘2hü¦§§!y4dtÿØé¶5xÏ{<ž‰‰ ÚuÑápÀ¶¸,Ë ýcñ$€¿½Lö‡¹(ŠRÙˆ~ù&›+ÝX§°BagèÆ:®±x †w,Vºvý%´víúK’d ãê䔚J½…¯ParJ…ªºK¼ÞŽt9@pæé͹μ¢]Çc±ÒȨ’Í•ƒÁMHqs×cˆIDAT‹X(ìdså…ðÜ„½î7ƒÁMdO¤/12ºA³ƒ ……ð9 ‚‘®‘„,W®]©yôé“S*´¬épÉé;Ö¬ïW?ùô§…ðÖµë/5Œ)´—wãìP›®]92ªLN©õO¡ÀÛçó‘È!Y–ÁS˜¹­¡ªêÕ«WÓé´$Iõ©™H|™#azzZãåsïÞ½@ N§-p=&&&ˆžiØÇö£ë@²ûD"át:5Õ@ïÑ›]h?¥ªÏç{ñâE °Z­°A¾¼¼ ”>I’4i°Is‘Hü‰._¾œL&¡Û_ýõ½{÷€ò zžS(‚ì\Š¢€ÏãÇÁÀløñŽ™Z¿Bƒ3¯fg{áµ{¶’® „\®ž`p“æVc\ÅKß<ÿ5|õ~>8óêÁ‡ŠF_/.^ŒF߀×8¸ÑžnDëµ9õsORÛ4D^q5•Ú~¶ÒG'§TŒ« ÌÚ² á*±X©_0ìñ¾gÑBx++Ñ2C¿FF•›ïÍf3jƒ¦<û8®ÁÒÊÁé³hphZÖœN¸Ft¹¦ ïÌÏŠhôµmÀøøñåûÑ×áðÖÍÃ\@Håh±œ‰Õ$Y®pœ~å)úð¯þ èXï<+™Lz<ªN§“D6H$¡PÈn·Ch‚v|ýÒé4áOOOg2bUÍÏϧÓ飿h…<|šÂb±øõ×_#„ yT³P àZغm ¦©‰D€7}ïÞ½d2IZK&“>wï— j‡‡‡ÁÁ I¾éfþ¢ báÖ¹…Pýà+ÇqsssétÚçów•ÙlÞ4Ä·€ìˆÍxÓr¡¡¢`€5º‡\²ýþó`‚A“ÞïIjÛï?O¾ò¼Ô"B(›+ßtõÀT½¡Ǹ Ò¢aã±’wÌä3)‹—Æ(òK\ÃÙ_*µM'k÷~>Ug Åâ%͹W5¨jMsW½c¦g+}ͦœP’qkzÔ‚y©éãû‡\رˆÝ!ÑÒM[ñ¡X¬T(TÚg(ÿÜÅîg+}<¯9Û\h‘ž3 ÍÏÏG"‘6 'n·›¨B:#<´¶ººÚ~43„ªª¡P¨ž5G¬+Í%hðD*“%°w2êêûøþ7:xN|yE­qTä¤Ô¿¾][«~òéOðµ>@Ù© +Mý^]úŠkŸ~JÆš’$ÁœÑn·kf - ª*.mæ;m†L&CŒ¾|>IP飠ÛÔ€ÍúØ!@;µ®Ó”7-I, „ŠÅ"‰õX, —h‘H¬S`8†B!˜€Ã201Ëçó<Ï[­VžçI³¢(Òóñcb5..^C,V‚¥.2ŃIn4úÆ6`¼éê‰F×cý{ sORÛªZƒ¹$§{’Únh÷õr-dN¥Þ’%Eù³J<^Z\¼48´.Zº!3õBx‹Ìô_ýÂä”zõÂú]}µÅÅK×®¿´ ;TCD>Acr‰D"‘Lœ9ŽE‚Jž7“ Ž¢ðÞWÑÒ›d.ì3y½&žÓƒ›Šºk³?âB§öc«|á¿P(ì€Éðø‹—ˆAôøÑål®L/ðÝtõÄ⥛®½Ë‘rÒ Ð®Û¼›îÆUÚÅîè—o@¶pxk!¼%†Å;ÉÀú ¤5A0]œ ¯†3¦´`š‘A ¦´Ð#„’ɤÓé$éo&&&Hj׉‰ úÐôô4„D'eyxxØétVãüü¼Ó霘˜€³2™ŒsÀâL&“p $¤n!œ,W&§ÔÁ¡õ…ð–¢Ô¥FÈÂ!ø n­“?à2+Jm!¼58´>2²A»žÜ¾¦«5«I_Qi:BORÛ##t õuB±X 5¤>t!DK»ÇD¦º—~’ÚZ§3k3ðd›ÝÆûÑך}ŠÈfËä7ðN. UU5‰˜²,k†j;˜žžÖ”€rn? ¤U¡u(‡†¿´ !$Ë2Ý}=BÈív+ŠüÉdøÛ!Œ±$I›jçóyMÂÈÂ.ŠcÈühpÆ ÉÀ ¤npSJ$-2K`\ μº=Ûûl¥Oè7ŒŒ*<¯ï $HÁȨ26fZ\¼ôl¥’Ÿ­ôÉȨb±t=[é[\¼¾‹•Tu÷ÙJßãG|6W†Â†5åÃd2UÝÅkU„ГÔv*õvi‰{¶Òáêëì ¿VUÕ]Œ«ñX êsœŽ¤x}¶ÒbD£o0®Bž­ôyÇLcc&8ëñ#Þ;f:;!þì‹•b±ÒíÙ^U©Õ߯l¶<3óJó O›Ãf3ÚlÆöiæ™L†ŽÿB°¼¼ ˜öÀk¼ü s"‘—6› ¸A’$H€ÔÊ«««<Ïß»w¯}ÙN ÍCû4epï€ëc&“l°àƼKpÕnx%HhÜn7[€jm·ÛA´ÏUBy<A€P9>>îv»%Ij‘iz!¼E<û¼^øcá¿Í–e¹r?úÚfkìÒü$µír‡mA0,-qÑè„ÉDYEKw³šÍo=Xâà‡û`‰kíÑ¢M•/üÆ;ó¼^´tjY®àµª(v?ImyMçìäüü³C*µ}ÓuÎf3ŽyM‚9Úq}vî´d«ðSQÛÎŒÈô¤)„QÙfn,º)𩦠AX]]å8RhµÙ„ùâ8Ž(ÀQÃRœ8š †'PºdÏ;Â퀑-Ð~ÐÈØ0Ü,’ŽUQB»!´Ǧ(ŠÕj-‹´/»(Š-|î5áˆóðãGüȨÂsºf±m …Zg‘70˜`W>üÑbév¹Î}á¿‹—ÖlM4 X1Dxà¢XÄîk×ÿÄó:Û€qv¶±©*5¹°³¸¸×H8¼µ´Ä¡Ão†cCQw-û)Ï耒¡‘Qev¶WUwß™‹ü½ãªhéR•Úõßþé»ÿM›ÊñáÇõ…0¬Žšttnn®Ù¡ååezp¤Q·Ô ø{×Û¹ïÁ’ɤÙlÖm<sssdNÊd2I ò~õDðâÅ‹¯¿þúîÝ»Í íëS´*²©ôœŽ¶¹Èg0¦ZJi–¨ãêƒ%î‡ÿü`ñÎEUÝ 7[§´~'4«W^¯ &ÅdRqÕÿùùï¿ûÍãG—-–î‘Q!ZÒ6`3 ÆUŽ×ŸJ´®_îG_ P‹Iè´%B¡ï¿ûÍãÇ—/ ÏZ¨‹ñññ/^¤ÓiÍ ô¨KmuuìÓ“¯C`ŒÁX†Èi¤M‡¢$IÀÈÈe 5#aÿ ýxA$¼|Å“ аôÜ< Õ‡É$p¹zèŸÈÈ¨ÒæÔò¦«‡ž“yJôË70 D±Ûÿùy¹°Ó¬f3БÊ¥6tc½Eehˆq‚`ðzMªZCqœ–“h‹æõðL´ÓS†-]¹‚ö¸wÄGžÓ[,Ý UµvÖ+0®­Ã‹ã*!›ž:0ÆdArÊéôúb0_4›ÍGZ=qhóù|ét(’D°¦%`u4 $IĆuY$a6›aµÑjµ:Î|>/I’ $ÏóíÑáp|ôÑG`¶0E½^Óä”:9¥ ‚!›-·I³G †ÆL×®¿t¹z 7œoÏöŽŒnØŒ¯O¥¶—¾âšÕ$^„=Ý^¼sqdT-]¤…Ö’x½¦Á¡õI¼×ÿçMíÜ\¶ìÝqÓÕ38´¾†«ra‡Ž)Ép$øý®]98´^(T`™" ßžíÝ‹ ÞÊfËíǶùù žÓÁª ÏëÈ;ò¨Ð¶é$Áì "„Hž’w"8N0’VWWI‚ØÑÄ^xŸh&YIH§ÓdN}ˆ7Mò±@ zâ i[`%‘BåwæÑT % ÓAhxÓ °HÒRHçZiX9@è<'0éëkÒ3,A0pœ®>Œf‘QQjtZ¨OçQi˜Ê¦^Îf LÚD}j:/ÍÏÓ>oš¤[¡ó®¨ªª(ÊQ£+’0Æ<ÏÃð¤Cµ :Ý -ÉñÔœ š  o ‹(ÁÀpÁ"Jœ.Ø’?ƒgÎfd```8uüP°û]•¾HIEND®B`‚cluster-1.52a/html/images/weight.png0000644000100500010050000001264107555177042017337 0ustar mdehoonmdehoon‰PNG  IHDRà~ÕÚ^ñgAMA± üabKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÒ  t¶lvIDATxœíݽnÛHÛ`éÞM$]R®»-·ØÃØbËíw)Sä0\¸tg—Ù. xÇo!€Ãß!9ä<¤® A SüÑo†y~ýñý@<ÿWºtÐA h€ ~)Ýz½ûð©t²ùïßJ7öG@õîç#…ÚŸýýíë—Ò­€I è½tåꉶ—6÷9R:ŸN§_ýõÏ¿þ~~~.ݦ²5gëÄ4Ð;êÊUÝ´µ¹ÓÞß]úü¥”­™ ['¬‘ƒ„ûJºk7m_m¦¬²5aëÛo—tÎâØ™÷?wþؘžw+“ÖŸ·%pËôA¬ýPß8…íÍ9‹£ÑEzýñýýÇÏÕÿ³WµA ´pöK¨¯˲D£¿ŽÄ™×SýZë›îü]gopû¯l`ëË7GL3O³k”Â’B(ñºmê/q)ûBªÕ62åúãÔ§ªuÖg蛳sÙ¨ÿ¦ê/³XlohË­A ó —t`S,ì#§Ûà… <ÕΔjJßSÃIÔùlçúó¾êƶr­vž”×µ}ƒ{^^Ož€î{cè²¥¬³¾ìÀj¶¼ñc£ÐFÙ_HßÇí¾))OµW>Ú¤Œa45YF{ñÕï±=O‘+¸ivmf@'Ë@Ï+½F'õS\­¤¯o˜²xñ’¾¹†•úwËWÛ÷ÚÇ6ê竤ôâúÆ(Ô7š²Èhƒg¿ 7 ³¶9†8õdJÁ²wáÕ×­?›²'¿ÁôV5šÑØÖèÛÕ¼M§4©ý#Çs.š}]×âáñéåååùùyv›ƒô>öµÛS\5/ͳ¼fö¾õ€¿*¾ê ”€þI„î3À•€ªw ú¨×Œß‹CŽA¼£ Dpww×y0`è,Žƒeýñûoüþ›Š‚¶‡Ç§¾§ q% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P¿l¶¥÷?W_|ßl»îýÇÏŠ“86 èFÝû3UfˆC:еßPÿ¨e•ƒ~ÿñóõ_õc5±ožö °†ªÌ%򨯮ÅIÙ†8ŸÚÿøý·Æ”ªp¯èúXGõ¸ñ =O{Îέs—Ëå¿ÿY¸’á­j©Qr:GêçmÊR¢m9Ç /—KcJ»ÅUíVSÚ}΢oÌp­þjÎö¦9Œûûû\«J)ÑQýcÅyƒ2–hC惄3Ê=e<º=O£›³Æ{‡4P*)ãÏsó(Nr)0ÝWÖ‰ÕÿŽçKÕç­þ¥—ÖuæúÈÆIq’ÉF§ÙÕëuàqʲõ)Îac}É[¡Vœä²ÝUêõÚ÷¸ï©Î!ŽüMäVõXgŽÖžâ$—íŽGg™U h˜O4³ªò_T “€J@% ‚ÐA h€ 4@P ( ”€N§±ËIN½eâÅüªÛӤϟ2Ûah`¾ô/»·³µq•×ð½æåQ hàtj]IµñøÖ’1K&è»­h=Ð7¾‹ãÀ&Ú˶7׸éÀÖ÷H@à I¼¹sŸÎ»<·7&ÖoÈ›¸¡öšëËNºÙt–»÷®tOØQnËÀs«\kÿ_Í<éf`YOš_5œe‰Â]Oä©éÜÐy!®ÆufÓûfƒ5(Q¦*?ÄqÓ¨Òy`|cª¾kµt^iEO‡í)Q†•èS­ïœ1O]WK©èŒÁÍ–è’ Ë­-ÔÙ“…z¥¾s¥ïb:#q³%:|c)ÑΞ,߃¾fô¼tî¬ìÆåhG/ørø¿ R¢Îb,%Nßùª|@Ÿ¦ô®®R¿6JûÁéç“7{‹3Ö¦DɨX@ûúeÞ›ÕÀ‡Á‰Ó¡¢D)®L@ϾµlãKtùÚ'¥1p kÕc`Ë• èh=Ðpk%šøÈ”±ò€é\…oãp×ÀSAÄú&!A¨„ÝFÀt> h OßW«_ƒÜªâ,`/R¾ë¸£¸1h€ ŒA0‡€šƒÈÆ”K1Ät²ï«ûú®cû‚?ÕhÆÚ×ZN@§SOÎ.ÿdð­ÿ3—+†8‚ÐA h€ ŒA̾XàMÐÀÖnðbóh`kúΉŒA% ‚ÐA h€ 4@P ( ”€j]ݪrà"âé×w%r²S¢ä²³oÖoUÙþq½ A"%JFûëA×)P‚S¢,±³tŸ¾»ï4¦wÞ+¾o Õ {¹µ‘)ÑÙŸ¶ÜÜår‰s©ƒtgMÔzÊFÿ` ]âååe› }ûúe› %*Ð)o‰“ÞÇF¤ŒVm–ã9†æùùyƒ­Äé;_ëA¿%Nzkô f4fx ‡ì’0J‰R\É!Ž·ÄÄ÷±ôt}Ãy“õó#}”(e…ƒ>ŸÏ7Býñ½^¸ÕH\g5×§7æl¯§±†ë”×ßÛ+;-ÑöÊç­g†3§¬X}>ŸGçé,ÆÄêÇö̧Òç„D;-Ñ‚u^ªãŸ8e>º¾ƒâï,àHÞÞÞÂö¯ÊQåšËU:ß_p;ªqëƒÎ¯°7¦Ôçœ:Ϻ/fŸB qHg(.e »qÂuç)Ø)ó oô–è···•Ò¹oTËan‚ˆV¢cÜÕË%ëq^àlå{Ð׌ÎÞwN¯‘M·S¢»n|YåÇ OF6 ¤öi|ËW˜e=·£XúÛ×/3¾U90†ÕwÑ™öI©Õľ‹ÎxÃçt{%ÚÙŒ¾yÚçw÷-’>¿»¶2}¹\ò®0å4õƒÈ(ÚÓ¹Y·V¢Ãçn§œ‹Ýþ±o©”y¶ù|™€^xE’öÑáÓ”OO£oãÒ%Jåæ’ëËTºÏ¬dï%êïb{!¦«Wg_¥Î>Ñy ˜D‰’ÑAzÐ}"RJùµuÑ=²S¢KÌ;`{û èÎ# §þ}‡Å;ç¹µºg J4¯ìlwd=IÊ™CPu›}竃´Š'8%Ê€$¸ ( ”€J@uð³8€†ûûûÒM •€†rË_úØ# 7ä–¿ô±GÆ ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P (Ýôþãçë¿ú”áùGçI™¡o¶ÄgÌÌN)ÑÛ! òþãç×߯ÿªJzýñ}`‘ág³å­ÎöÚÃ~)Ñ›" {•ª¤ôž7N‰ž€W}B¬>WÖ?`6 ´ññ³¾Hcm‹¶¤ó³mçVsr`Jô¨ÜQå'ëπíyêÏ6æíõ\ÛPÿ¿±ÂΕ×WÛ9'Ç DoŠ€nZX7«öf¬\é½:§F¿`özª¾I{úüÆÝcÐ?ÙlDìZß³?Ü¥·ÓßÁ(Ñ›¢ý“ôS—F˜¡sT®=çhÛz1K^‘)Ñ›rîÛ;ï>|št‡ö‡Ç§Ëåâ¦îéI”«´”èTJ4ÑÂÒzx|zyyùöõKû)=è®}¥OXJ4]€º'8%„ƒ„A h€ Ê q<<>Ù.q?^§D‰P¢ÅÆ _^^Jmšâ:XG£DoY-yðùù¹àÖÉhRGãÏ¿þ^¯%y)ÑÃØi‰:‹ƒ<Þ}ø”2ÛýýýÚ-N{,QM6Åì`ØîJÔYAE èsÍÂõ,œ!ãR[º¶0~;÷K‰.¤DgÐçóù­f_aµÎ···ËÎXjê&²¬g¥½‡U¢EDƒ^»ÔXUçÅÒöÕa%ºk;*Ñ=è>O”ÕãöÄö{r{zãV{å5w¶§smí Oé[jøU§¬9‚›ºˆ»}±Jt‰¸}®}¨¬~»UÏåú sžj†¾eû¬&N*¦ÆRí5'nkàõ=UŸ’Þà ÔË=lé/§D•èÚât¢ôîɨy54°TõT»1K ´<`g¤OçÝHo“i%q z’Î2:׎™D¨•IW)N»¼ô7£DÊ_¢{ÐóêuË*OÜVg§)ËV"üIß2%::³Í"Dº1¦v}î›ë[°>Oçx_½Ï’²òÍ ¶×œþBF$G×̪”¨-"D@ŸzÊ¢ýëoOO™§>¥o†u¬¿s©¾Mok^Ãöõ‰r×”¨Ý^Ä!ŽhvÔ 8¯ÿ…R¢G¥Ü^Jª`;C]ì)ÑQ{,QMq®Ÿ vZ¢ÅúÛ×/»»ô}‚Ü~"/%z$;-Ñ2}¹\Šl)Q"(Ð:&§D‰ÀYA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐAý’q]÷÷÷×Ù)Qö%[@_.—\«‚5(Qv'[@ÿ÷ï?¹VkP¢ìŽ1h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ ¶ è÷?Wÿª)WžkU·²M«€£Ú( ßüüúã{õoRr¥Ìüúãû‚Öeh@ve†8VÍS€cÈvÓØÙ®ëÆãk§µozõT5Ûu†êÿƲնêo õUõ-Òn@gÛÚ3/Ù!WÙúáñ©=ñß›±ªz_4~l?Õ·l;Xë«í\¤±•Ñ™;·Ø¹s€Ã¸\.kÜ6>gúr¹4¦Ìkqsí‘ÑÎi–Á“­Ì[{χq¿Òš3qäzitEëÓ³¬tëyW¸Æ[+pxevvQ§ß Ÿìó¼:€Œ6:HØHÛzµ~Œ®ýàôóˆGûˆÜ¤íN]¤Ñ€ô™'m Ó¹/éÞ}ø4éƒùÃãÓJÃä¹ô…,À ÓïáñéåååÛ×/í§ÊŸf·ª¾n;@|h¡ ì—‹%% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA•¹Ç»ŸŠl7¬»»»ÎkYUì±{l*{lªÑ=¶bKŠ|aÒ%ޱЫØcSÙcS¹¨!€ 4@P ( ”€J@% ‚ÐA h€ "ôûŸ«Ù×<<åúcßv³·g%í½—ÞòÑ9w½‹ò–Ö’•ìn7lÒîöUFžêÝçýÇϯ?¾÷ý˜¾`§ÄU%ÎS}?T³¿¢=î¢Ù¥µpCö¸K¹Í}±]w›¿•\ì½vNºë[αûª1…ëA÷©ŠãúwU¯˜F‡±>±s©ÓØÇ¢j=íMÔgèlXcåÍØÞÀ+j·¶1½³ÍGÚEí"©~쬥v#;_`ÊëÚïnìü Ö¹'û6µñûÝWKì# ûª¡ñ š§1}øqÊvû?µþ&Û+Xv õžN{[WÔ·+ÒÛ¼Ç]ÔÙþS« l´´F÷I_3îÆú‹XíðØZÆÆGÞWÙí# O]IºÁ>¸ú”ÑõlüÙp òÒwZb›wº‹òhüQwc½3›ÒÝÉØøÝí«%vÐAÞâÚ™RA?Éì6ßÎ.ª 4þ»qvtV‹¯ÚøPû*¯è Ûû·øûÞë‚£%4>û&f¬0ø.ZoCË»Òuvã5ìêÿêh}ƒ ·¾Ó}µ†p=èÆŽ®~Õ§ô-؇ê\jÉï²±­öª†§l3,“¾¹¾]±¼ÍwÑìÒªŒ–Sc¬ö»±ÏÀÖ·iüŽöUºs_ãÞ}ø4éþ7O—Ë%q‘©+ߩăO///£÷‹[{9T2o£EöXäCI£m Rc6Þ±ÿ*ë3§§ß¤m…ëAï]»Y‘Öîk…µëݸqã÷»¯tfûúõií¾vQ%Z³£µg’¿ß}ý !ÀÍÐA h€ 4@P ( ”€J@Uì‹*O¥6½SöØTöØTöX4eúîî®Èv÷Ë›Ê›Ê ¨L@'^‚„Š=6•=6•=1h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( T΋%Ýßßg\ÀËЗË%ת8e èÿþý'ת8ƒK@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P¿ <÷ðø´Y;hè è»»»-Û@ÃùõÇ÷Òm ƒ1h€ 4@P ¨ÿ=>Ä'¢:ûIEND®B`‚cluster-1.52a/html/images/format.png0000644000100500010050000001210107543101026017311 0ustar mdehoonmdehoon‰PNG  IHDRa¢ xsBIT|dˆøIDATxœíÝk’£0²†aùÄì˵3;ƒ•1?ú0% Ièž‚|ŸˆŠêæf>(ã4ñZ×u7êeŒÙ×u5ëºJ¯ €ÿ±ÿóûû+´ºüǰïý¯N.Ëb>ŸÙ¶­ûkÍh]Wò“Ÿüä—^ä'?ùÿòŸŠ0cŒÚ0ÊÿI¯€FÞ3aO÷óó£îF„ŸŸïpÍÛASvßþמÿ e;p 8o-ÙCŸyZ? gʬ®;vÀl;bíoB7«¦ìÆœ÷¿öüiÞ¾¿wmï̇ˑPÁw°=Šq­´ç‡¡b‹÷¤Q„A5¾ºq €$U—#íoC/IjoÝh¥·Mâí"!GU¦ö6aпs¶ÁAc1:þC–š"ìøcsÿè(B@÷@Šš"̾ àŒ" EEÃüØ-wÇèàÛÏÚ 0íù¡Gè8Ï{ÒT ÓN{Ã|÷@¬)»1:ÛÁØh˜¯›¯cßCšŠ"ìê¦á¨!c ­ÛAkîƒöüư ŒÑ» bW‚´™-³ŠË‘³¡ð2Æì뺚u]Íïï¯ùýý•^'€Ç;µ û|>Ý_tY–!¯3«mÛÌûý–^ 1ä'?ùɯùÉoç?aÛ¶ ]!h  ºkÒÑéëõï'6¬t{øÕøÐô¾yz½^æå¼†o˜=õ=+ü7î5"ÿÀãY6òûû-OŠÄþŸhTa"=Íçn¼cú}ÿ÷“³Œ’y*HAû¾ýH9²»ëÒj›ääl±.¾×нvêkºÓÅÖ+eýs—ã[ÿ&ûìx¯¹?Ç8ßAÕ^ß¼¾yfÕ3ÿ1mlÛH#ÿ¿ÿc¾Èï[öŠ‹°[<îÁ.À%EÕÀB,Æþ¶ÿ›VúìV 7×Áþ`Oý€-«åº´–úš¾éZ«­‹Þé¸mM´æ>hÏ©a¢ØS?(̃?Ë)Hñ¾3¹óßYmþ»#}þ;o·šü“ç¾ßc‹f<•ÜȾïMŠ w9±åºÃ%/IöÔ+§†âoÈßHh;ºg±'? #¿xËüök̶ Ùÿþá­òû.MNâ~EØáÁ~¡FÒÆü}…ÕëõªúPœ±èêñ¡_{y2´ßåÂZ­ò·ZNjºª×©ÝǾm?áßvÐÈü3~Èoÿ¶mÐ;ÿly]½ó»ËŸh{ܳãlØ£Ít‰Qb]îÖÎkØ6:œ¾è$Ô®ZäŸèÃ'ûŸü%ù'ß6ºú ›àC½VNW31-¹ö¡Fû3žÝ“ôˆbÌ>ð>øKXP‹üO(ÀŒaÿçæ·ÛRÙÿ¾“ïÿûa)÷®F{çå6ì˧‚[Døº/èу”™rÌ|æË7]«Â“öáî\€Õšà¸"jß¿ŽaZL¾ÿç¸yG=Ï…–b憜ŽËšCÚó4`·që±>9Ëí½.5¯é›.e½BmS–Sºí²¶W¬anèòÓ ‹žùCg?fÚv=óûΜ̔Ýþþïÿê"¬YWWÅ7>õº°o¸{z3g] u€Ÿ2]ê¸Y¤-†÷˜¯tY­§KYšmó:IJÞûöðœ×›ðï¾{þ3ÛFìÿ™·ÁÈ¿ÿ’é{S¾ÿï{9²ÖÄ;<ŸÞ" @Ð˳¯ëjÖu5¿¿¿æ÷÷wÈ ‹Ûói´çR5)ÂZ´3F¾M˜-åAÊ¡ièæ´"Úó©ª/G¶*ÀfC[0ÐSU6ª u+qÕÝÀ¬Š‹°§£¡?€ZÚÚó¹Šû ³j‹2é†ùGg«t6ààë„9ÔæéjÚ;Òž詨k},åMš&wxùJ—ா¼¥N{WÚó—оÈŸ–ÿvý„<E€€ÓåÈQí·mò:³"?ùµúyÿH¯‚¬·ô #¿nä7ë¶þï¿§"ìóùt_‡eYÌû­wOlÛF~òK¯@€}ü?aš¿¡ŒB›0ÅÏŽlÝG˜1Æ·£?÷ÏXG€Ç´¯×y>wxÊr|óA­œ¾è'éŸägúÞŽ±Ù^žñ±>B}ÓδKÈFþøôä¿^FhY“å/î¬Õ-ºª{Ð÷;¾aIõ„Â)u9PÏWL„ ŒœiŸ,»çôÔå1Ü¿{¦ñ®X`~iäÿF~ò+É_t9²ù”¡¢ißË ¡ÒùRÖ ˆÐVlù4):¥Vä'?ùU˜¿M˜Ô‡¦@ QHSÜ&̘ïvaÃæ:Ãå»l;›•ºs°/!”\R¨_ùÉOþ”¿ª³ ¯ê6a¶XýVEÅÐØ ¦ªëÆþЪiÛuu6 般¡—óÛž²‰kç—Fþïßöpò÷Ÿ_ÚƒóÏY„7GÖAèn©QóK#ÿùÇÍ/í¡ù‹æ»}„U ÝÍØâ,V‹;% ` ØßPcßVS_ùÉOþó¿]È_t&l]×öµúŠ¥P§«¡ùs–MÃ|$Ú÷=Ú«]tÓÑak&÷í¨ms‘ÿùuQœ¿ørd—»![t°š¦´q?ž0ñ"ÊG±õ'y[\M–;þêÿ¹ËïümÇ“¿íò{Sžþ~ˆ" @Àérä¨NW·mò:³"?ùÕzK¯È±ÿ§"ìóùt_eYÌû­÷H¼mùÉ/½öñÿT„©þ†0mÂ4)šuÞúz}ÿ\÷MêÿË&e9±u*¯×ëë§Õ´O”ÿåù¹š>e¡eͶKÈO~ò«Í_ýØ¢¦˜Û¯oXJßC)=íÇÆ§® Tðõ€ê?gÚ'*ÎïŽõr} wÇïži¼+˜_ù¿‘ŸüJòÏq92Tà”>r¨öQEJ>0Ñž–b+¤Yþ '"Šüä'¿ UEØÏÏOÿ.-”¨€gª¾9\ê3³a¡"ŽgG÷b_B(¹¤P;¿4ò“Ÿüÿ<(qÖõ,XìAÞÍ.wd,‡ö`(¤©=˜öü3ç™0û ]Û¶«¶€¢C!íHÓü/ç·=<å%jç—Fþïßöpò÷Ÿ_ÚƒóaÇ‘ö‘CÚ‡F†B`ò‡î–5¿4òŸ‘ÜüÒš¿¨s‹­ê,tƪETz§$ Q€5ÈoC}[MiÛQ;¿ò“Ÿü绞ˑ¾bÉw /iPï[vl9Ǹ”õÁãíû~êtÔ.2ì¢ã˜.6ý“çwߎ:6×ò#¿.Šó7)š]†¬é`õjšœÆýJ>0‘.VDØã´[!Eù¯fÉõÿÜå÷Fþ¶ãÉßvù½)Ï?Gg­ÊP„8]Žu‡ã¶mC^gVä'¿Zoé9öñÿT„}>Ÿî+°,‹y¿õ‰·m#?ù¥W À>þŸŠ0ÕßСM€€ªgGºªÛ“]õËëtõ˜6Ôɪ=€×´íº:à^Îo{xÊÛ»v~iäÿþm'ÿù¥=8ÕåÈÇ: ?»¤˜C‚ãŽ@ûÎ@Mg†ºæÝ-5j~iä?#ÿ¸ù¥=4ÿEXèŒU‹Â§äNÉëJº²x’fùío¨±o«)m;jç—@~ò“ÿüo×òa뺶ï¬ÕW,…:N ÍŸ³læ#ѾïÑÎZµZ]¸oGm›“üßȯ‹âüsµ kÑÁjhššÆý|Àª+²JÇi”ÿj’ÜñWÿÏ]~oäo;žüm—ß›òüó÷ð@aN—#GuººmÛ×™ùɯÖ[z@Ž}ü?aŸÏ§û ,ËbÞo½GâmÛÈO~éÕ°ÿ§"Lõ7t€Ah  ¨‹ ·°Cu{²«~Âb®Ó†:Vµ‡§.'4êÄú »šO[7î¶2æb{ùÞŽ¹/ÆúcöM;Ó.!ÿ™¦üP­¸³V[“‡w§ö˜Ÿò–ÒÃ}MŸcPÅWH¥W¾bD‹ìÂ3õƒòîŽß=Óø„æ—FþoÚòC­9.G†Š¦’GÕÌ`Ç¥Vä×jTaM΂ÅHœâY‘¨¤ñ2¤1zs@‰9à#õ™¡‡‚§.'å9–NJÛÏ]/Øü]B*¹¤T;¿4òëÎGª*º‹@­è¹mÆ8;†DÚÏ•´Ÿæ<f°kÚv] Ky}ɺ[/ç·=<å%kç—Fþïßöp ùñXÅEX÷¶`À —âìKrœ j$t·Ü¨ù¥‘ÿLS~<ÒwG†îflq °äNIî¬D¡}ß¿~ŽaZ4ë–Ã>C;[‘r]íüȯ;?Ô˜çr¤¯X uºš?gٱ央 TØ÷=ÚØœ3]®¶UûvÔ¶9ÉÿM[~¨U\„u¹Ù³ƒÕÜÆý|¨Â+$JÇ=UuG­µã¯þŸ»üÞÈßvüÝòCµ9.G(C àt9rÔÛ¶ yY‘Ÿüj½¥WäØÇÿSöù|º¯À²,æýÖ{$Þ¶üä—^ €ûø*ÂTC„6aªzÌ·5iKvÕ7W¬#HûÁÛ¡þÅBç-'¶.P¥ô¡ÔûËÞV¾·cl_ç›±7}ÓδKÈFþøôä¿^FhY“å/*Â|,ª~Œ‘¯xò Kêø1¡§ýØøÔu ¾B*¥¸jÖ{ü”n«äå1Ü¿{¦ñ®``~iäÿF~ò+É?ÇåÈPSòÈ¡šù®– [Ñ™Àã@©ùÉO~æ(Âb(~pC/Cò]Ž\×µO›°©ÏŽ<Ά…>S–cOÃ*̾Û¬µ/!”\R¨_ùÉOþ”ž6a¶X£øVôËÆÂNG›0$Ò~Ìͯ}{@HñÝ‘]…ÎF•,§´xâC(Ò¥àz9¿íá)/W;¿4òÿ¶‡“¿ÿüÒœÎ" ¸©ã2œ}9Ž3A„î–5¿4òŸ‘ÜüÒšކù¡»[\ìq§$°ïû×Ï1 ™ìo¨±o«)wQÕÎ/üä'ÿùß®䟧a¾¯X uºš?gٱ央 TØ÷=Ú)gºþ\m« ÷í¨ms’ÿùuQœ¿ørd—»!k:X½š&·q?ª°Ä ‰ÒqO•ùjòÜñWÿÏ]~oäo;žüm—ß›òüs\ŽP†" @Àérä¨NW·mò:³"?ùÕzK¯È±ÿ§"ìóùt_eYÌû­÷H¼mùÉ/½bÖmU_ûþ'?ùÉÿ—ÿT„©þ†0mÂwQ!öo€˜óÞÇåHÿCpÞ^vU=>=ÇÏ÷׺‡ˆ®¿ª€–ÈY€@" Hd‰,@ ‘$²þ^z¬Îýþaé!lUõ?íá ˆ,=¾¾¾–ÂÆ‡Óé´ô(X#‘¥Ÿ?Œžîñéyé!°^Öd‰,#š%Z߇¾CÙwá"s¿øúújþ Þï<™SÐ<>OϧÓét:y¬¶Ë»p± Õ(óø0Jd)©{E|ÁÑÊw¹ß?¤_»Ù/ä­0Ê« (YÿL-azs†µŽõ?>,ÎL–’Š3µ&yW6õ»²_‡f²”„ÎÔÒB5'êni÷lw()Û!½c÷DßÿíÌd%²”ÔºânÓLfÛc¶?¤;œu꬞™nš»'ú¯¾`”ÈR²þ‚LaÐuýú'²”Tœ©-»|TC3YF‰,%A×Ôç¶©}Æìûã©›E…e”ÈR=S뮨ÖXÏI»þ›¾ª¡î¯c&Ë(‘¥¤JA ¹-iyCwïÿ¬ÃN§°Œò:YJÖð:Ðæ¯¹Ö™³5<>¬œ™,%¡i›¸ °Î¼6Ö<6VÂL–’5¼—àú¿C·:$—¾Õ!Sx«Ã+.Ëôó‘*P…ÈÒãp8,=¸"K¼ µˆ,9 ‹P‘WY€@" Hd‰,@ ‘$²D ÈY€@" Hd‰,@ ‘ä­Ùív»ìã`Û®j7f[²Ï¶šóÝã>¹¶{äîãÐÝs= ë$²·®ûQ€YA>Þ^º[v›ÊÇ”.÷¶û[ïþ|ĺûôþ[Å-³\pë².Ð:÷a)4š[f&Ë… —ÒíÏC×Ôí–òÍÞ-£#éNY ˜>á5Ee:‘%71"…6Ö²õ‡òÍ¡-鹆.ê‡F[¸×Ð}ËñíýÇÆ4––ÈÒctþxnAºO¥+˜ÙÍÂyç7ñ³&ÂÜ ‘%ÜÐsñéöîÍùÇÙUXd($UmIyâ‹Ü”Yä7gší lóCv³Ö‰¾?Èî2H:ûþÎÁ¹f²äÒØ¥—óå-©ÂÎÙ)²¦œnúh³Òq–ÇßýE†v›xnÙ]õÿ3ŸžÇãçûkÝò.–Ù¢¸pY.$²Tf )‘$²D ÈY€@" Hd‰,@ ‘$²D ÈY€@" HdùørÿüûßÒCؤÃáðû×Ï¥GÁêˆ,=|zйŸž—+e¹ ÈY€@" Hd‰,±î÷³(ýjO=Û ——p±I÷û‡·—lc¶%½Ù»?ÌÀL–@MÚÌ%¹ef²Ì­mn;µÝ’f:ݧ<9ÍvhoöÜ<— "K”6jÍd¶-ZVÉ)[v}míf±ëÔІö‡*D–ÅU/[a˜ØJËÌId tqÎB§–æ­ÌÉ_„h®ÄÓ¯np/ÛRwq‡†™,³Jk›®Ø–·ì:ë­ÙÒíÄóf¹7¥e"KˆÂzëèë[/Û2´C÷¼£w„Š,Y6Àd“íY€@" Hdyu=|, Ô"²ä‡ÃÒC€ë!²ä~ÿú¹ôàzX“$²D ÈY€@" Hd‰,@ ‘$²D ÈY€@" (ä­üøqX€Í©ÙãñXý˜U?²Ÿï¯Õ °QÖd‰,@ ‘$²D ÈY€@" Hd‰,@ ‘$²þ)J§šOƒhIEND®B`‚cluster-1.52a/html/images/cluster.png0000644000100500010050000002040110046571506017512 0ustar mdehoonmdehoon‰PNG  IHDRæz*_œ pHYsÃÃÇo¨d IDATxœíÝM“$Û]àSŽ^8À²lp`ƒH–„4-M;0𶄏ÝÀ7w1o¼ôÆ× ,]IWªé‹@„ð¿€#´ëŬpt] ¸‡0áÔ£71‡ Þ¶9“““o••õ’õÏzžè˜ÉÊ:yΩîì_Ÿ<™•5¹º¼Hl½—?ðÊ )¥7o ÝÚ§”^È<~ôpÐÎ0ß ùÒ{îüÇÞµL&“”Röϳ…É““ç =Yýd¡´Xª¢´j’ž¯ï¹êž¬.ý_iã¹µ¥º'uÛ•º_êàsO6´ÞüŸ.•›kÿ”¿ó^céûÿÜw®¶o=^ã“ÂóÜÊu?îæ}¬Ô§å÷±Ò+ßÇJ}[~küW;Ôk«ìÒËîc¥Öç¿ÆšgÛö±º]zîkÜfïþ«_Ê^(=ñÿ~ï?´lö⋳ÃÃYJéðp6›¦”>ý¹¯Ïiê:û6µ¬ “rd7™N璉gGG³”Òlö$»7èiÔ__§â_E€Uøgß÷†î…ŽŽÎÏÏ*ÿ/>õ G+ÙV¹®‘R:>¾›ÒÝ,»Sa ½$9°¨ŽgõNœõ+¿ÌV™úÈÎs¹äøøÙú!ÚÏùß¿u’Rúö÷|xÅõ.öþ0µÙš¹óÒíÕ¶Õ8Ê.¦sª ñ×_?,Fö_~å~©À_Ç/×·çüñoªøðï~ß+‹Öðû¿þZJéÍïÿx¿|ñ¿|4_~çÿléÙÏÿ§gýy÷ýÜsÏ•rýÙÄŽÀ‡‘»qóV˘zoÿ ¥T|sLuMI׉‘ÃÃYJwóålJäðpöéÏÝHOóú›ßþrélñªdyýwþá‡R¡MúÒ¯¼šRzÇ?ù™É$}á—?ú…_þÈy–ÚWg¯¤”Þõ£'i2ùü/}èw~éC7ÿé§ëZÜœh—ü0´étZ]™]IÝâêòboÿ`oÿ Ëè¹yºGvvÖñ©»Ù³ÙaJs®ùÆ?›/¿ñÆRJvõïŠþÖ»ÿu¶ðõGŸÉWþíðo;v,¥ôG?™Rú{I)ýáû™”Ò›þÑGSJð›ŸÈË|×÷,[øŸÿõµ”Ò›`šRúêëwóo=[Èç²ÿü Ÿ­-YõõËŸïX²£?øO¤”¾ë}k*PhçÞöƒ¯Mê&vš&Fèî:¥‰„‡‚|ˆÏ´˜?1rx8+](’_£]{‘ß7¿ý_å©ÉFÙÅ7û5ÉFÙ+™­~Ó{_ýÚÓ‰‘ÿõ?OŒ”d£ì.}#Œët½Ê3)°FÅñuq^»ÉœÈ>??L)çÐ_ýðõ×Ó\ä7×w¾÷Õ4y2Ð^R~ú±¸òñþpJiïö'—¯ŸAÍ›áqX°{ò‘on7=-͇”ÎFÖšÙ³ÙálvX;ReÓÛ^þ˯Üÿ‹/—¯ó{Ã;~ü_üÅâÄH>—]ò-7?ø'>Sœ)ÎeÛ÷þÔÿö§þÏvñ\ñ"¿ï¸õá?zøÉ?¼xn¦âkÅsïûXš¤ïþþÿþ¯¿–Ÿ~|ËL¿úkÇÏ<Ëjyc{ù…6\´•¢ù§kS;›0I)ͽ.Ø~‹¥úHÿ­µü2[åæDvémë¹éôîÝ»w·ù¶PÀ¶Ùò¨/Ý3o;[)Gö_ûûÿ²ËfŸþ\úôçnb+à><=‹ìß:ýçö¨s]Y`§ý•¡;@W" ‘ †È£OdWß}¿rh œ¶ÈÎnP’¥U$i©Ñ ÐÝœ·Ò”Þh¿Ž{YÐQ×Ë”î ØýÃoºÔ\­ª8÷×`Nd·„f1¾»|˜Bms«ê×À(-61RÒo&ºvmR`®Å&FJV8ì5‚˜k5×e¯pŒl¸ Фÿ(;ÿ ÷´ô¹¥ªžáˆnruyqãæ­ÇÝ“N9dNœÍf³¶Qö:>c¸vÞC.tÑÙëHÒ…êåEn †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„1ÿæ«§Î6ЦÓiû}U;Ý/ûÎK·WÔú31†ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙatº“ÛÆq!й÷S]ˆÈŽj6› Ý`Žû÷NV[¡Èlå{°åÌe„!²ÂèÙ{ûůlMþoû†ýš[I€¸–šË¾º¼hyÀj™c•WŒìíÚù4EÓè»Z eM—­Æm©Èn åb|—¢¼¥@iM©LíVÕ2cµÊ¹ì’ê#@‹5¾•fѳ‘ÇËNr;k§×4.6ÜvͺFÙÙ,s¾Ü¥@qMµL÷­ÆªdWƒ¸t ±i£¥ÀªÖŒ’ë²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙQÝ¿w2t€M{aèÐÇt:º ÀDvH=º ÀLŒ„!²ÂÙaˆl€0D6@" ‘ †ÈÃ[iB:}p6t€N¦Óé ßû&²£šÍfCw˜cå÷ÙŸŸÝ ÍÊï-a. ‘ Ʋ‘½·Ðã)z0ÊCd„±Ê+Fò™«Ë‹¦5ùú«Ë‹ìÙ¦ÂŇí%vÄÊ";KáÒruMµ|KáR<è[ª±Á®Ë®Fm÷Ó•Nl»©gd¯|x[;·6²vSìÓ†ÛÀNé9Ê®žÌפ^ç ‹›w/i¸ ì”þsÙÕ¸,­iÉÓâSÅЯ-Ó²°SbOŒì‘ †ÈÃý²£ºïdå·â¶œÈi:Ý`";$ãkØMæ²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †›¯BJ)ííúHh¶“Ȇ'Š1½· µÙB&FÂÙ0ÇÞþAö•?lY(M°Àj™'Ši›ÏŠgHÚgKògMª°>FÙðÄÕåEþ5w°œår)峇òšõÙ°2]²–!²a1Y.gCéâr>Ä–Ú¬Oÿ¹ìÚ‰¿M2cÈ#¸}31Â,uúqÑÓ2ËЬUiï*>¬îxMÏÚEY·ÕLŒ8Ø€µ\äW=,Í÷¥ºñHé ²¥’E·ªm œµDv5dó5Mù[º¦µöbØÚ¼.] [ÚÊ¥²À˜¬w”Ýý©<^«ãåMƒî–jâZ}d—ÈŸJÏ_/•zMeÔÖ_ª ®Õœ~\>[®i]æÄ¦Ke1Yj”]{.±šÅÙ‰ö‰‘¼ªêŰ]ËMM'§Q˜\]^ܸyëñ£‡M%NœÝyéö&û°›ZÒøôÁÙl6ó†u€0Ü|žèr§²–Ȇ”šß([ÅÄÔ×l'‘ mJŸ"–¯,-‹U?u¬TƒÏ£7#Шû§ˆ¥§óê=šnÆ`î…Œ²a½ª·uõ^zÙ°iÞŽKo"jtŒÔÉë& ,Ã\6¤TÉЦ'” ÷H^#,ÃÖ¶…7¬Œ‡ÈCd„!²ÂÙaˆl€0D6@" Œùï~œN§èsÍì–7F°I&FÂÙaˆl€0D6@" ‘ †È£ë‰Ý¸yk­ýXW”#Ó)²Û?ilk½üWîß;º+3?²ƒæuJéðððå¼r~~>tGú+~ç#èmùk¶{ÛÓ:[nüŸ°zwÌâþáÌmùk¶{[Ò:ÛÏéÇ­–(lgÆ-jË_˰ÝÛ†Ö7ß.=,5ÊÞÛ?(>¼º¼ØÛ?Èÿí]Õ¢Ûìˆe'FJñZ|¸hpç…Û7ìñ÷`¶qb$§¯µ‰–ú³§zw`oÿ ÿêٹΠÕ>\m»Õں׿’’Ët`…j¦µ?ë•w¸ØJ©¡¦^-Ó[nŧKCàüa¾v,—¶m©v…º÷­ZrØÃ…u‚ìà!Nñ'UÜ÷–9¦\Hµ¡M¶ÎVYv”Ý>¢,îÜÙWmÙ¶úTÇ>o` Ÿ6r¸° ÚǰÖe¿Ý|‡KQÿ.±>+žËn²Ì>´ÐQóªZ©ŽeJCûŽCéÚ&Öz¸ÐåȦûSÅž—F—µ/gÉW±èhqnŠV*3ȰtÀ¦‡ ]—½’ßáÚT­}ªK…ÅDî^Uu“…ª}hzªãk™ÛÏŽÍÕ~ª]ÛÏjýýŽÓ›¶*]‰TœµïÒ‡ÒBÓÌF‹Eçv¸÷_¦öÔîی̦ßJÓeOÚæ½-ÿeèI=žjïLK K6WÍ÷¹%—<–j×·o5wM©’~?Á%ÿ-Ót2*§`‘]ÜA» RjËT'æj«]È’Ó)ý†0+?\˜«©‡kjnÉjKßÕ¦œ­nÕ£„¶tx­M›Å½¥"»éW¨ú‹Wý œ[U—ÂËäfÓš¦ ‹å;þâmÉáÂj§)VUÕ2q¶hojkU/°GÓÝkN­Àñßc¤‹¦ûUáÌUu!5¤ÌÆ:¾¢Úë¢[Í-¹’WÑgM#ÖEûPú vïU©¥¶ºŒBz4Ý¥KÕ‡ŒØäêò¢ýÎ[{Sˆ¹NœÍf³~÷»Ù’JöÎÏσþжüµ Û½mhÝ¡¶\öcÚÆw?PKd×Û†!6@‰ÈcüsÙ¡?•Ø)GGGM'²@ó#w^º}ç¥ÛAÿÞ»æôÁÙÜ2&FÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" Œíý„õ½ýƒâëˋ½ýƒüßejë±9À6ØÞÈN•l->\(¸K…û…>ÀàvqbD^AEŠìÒTIþpoÿ û*>ì^giÛj ¥2‹6°*CNŒœ>8«®¼óÒí|9ÅÚqq¶²8Ë‘/7£KÖn[Z¨–©–¬}!ÀXM§ÓÇÒôÀsÙÓé´´¦øè8ƒÑ}À›Gm˶ÕF›N„æ%«¯«ããã[þôãò¬–™›î²mµLiô=Ôß[`×DšËž«Ëp»©L÷m³³Ô^°ƒK~”ÝOqv¢}Ê;=¯-Ë]¶-®qå °aÛÙµÓÅõÕ…¦ K+›–›žjê À†jb`ÜD6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †Èã…¡;@ §ΆîÂM§ÓÇÝ ˜OdÓÕl6º kqÿÞÉÐ]€®D6 8??º «g|M á#»Ë»Ã^`ÂGvšwÀî°1Dvj=`o_ïí¤”®./ZžÍ5cËM&“láúúºi D1’Èîaoÿ KáêB®ø°úì ûÀšL&“bR___W× ×;XØî^—}uy±·В׃( íŠv7²SJW—‹æu–òÅåbÈÖ>,–¯-Sê’ÔšìîÄH®%¯‹é™—©¦|¶\°W Ô.T›®n[zv™»k²™|yØÎÀòv=²ÛÇ×íùX;@ÎGîÕs+¬VÕ}j™¹fdv:²‹cÞ´x8Î ÷N[£l ÖîÎe—æ(–™DÎ'©SÃdôB5—þYßò¯~=ÆawGÙűpQv1šóŒb=ÕM•¬ûRÂ]VË6»Mhcˆìû÷N–|?zmJÎ]Y;1ÒñaÓ䉼^¹j.Kjâ ÙÓétè.lHøÈv¿'`wìîéG€p²٘åÏKÙtâœl‘M'Æ×° Ìe„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0|\/œ>8º k4N}1!ˆlºšÍfCwa-îß;º ЕÈfçççCwaõŒ¯ $|dw9`wØ ŒCøÈNóØö£1†ÈN­ì-ãë½ýƒláêò"{˜-4.=›¯ÉëÉ«ZRK[+±ÚÚ¶Ód2É®¯¯»?[n$‘ÝC1¶zDX1¯‹Ûž†]:puy1x?×j2™äq\\n ¶Ÿë²Sz:4΂,_YZîp+ÉÁjOF¯ë ˆ«Ýeo@íÄK¶²8À/–Y´Î¦5¥›âCéqíndG²«š€.ÖV;ñRZXtr¦Z¾¶†–ìZ^›ú`dv7²Sݰ4Áê¿kkšZ)µØR&/YÛzSùÚÊwœ¼f|v:²×­{Я¶N’¼f¤v÷ôãÜámZüÊŠ¦:[†Æ-eÚ[¯–ïÒʎ׌ÕW5—]ª§iy%}¨–oZsuy±òÉúXò‹¯SJ×××yˆgËùúa:}!²ïß;é÷~ô–$[¦KùÒ¶µOµ×_}v¡5-·j×Hjâ ÙÓétvC¿%nÏaÇ…ìï÷7õâövÜîž~'ü(›é}ÎX‘M'C3ŠD6_Ã60— †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„á³púàl“ÍM§SŸÜ8JÞ‘6Ì~[Kdc6›m¦¡û÷N6ÓƒØØŽ´aöÛ&"{0çççhÅ8eô6³#m˜ý¶IøÈîrlè ‡ð‘æ:ÂFc$WŒœ7kßpoÿ`É[h2™¬¶Â}Ö×P©æ…êRxoÿ Z¬iÃl}Ä]kI“§zŠ¢‘Döª¬ð·h_È ;}þ½ºº¼XSYÍkú¡ìíôèùÕåÅN¥öd2¹~ª´—¶,½º¼(m¸L¼.Ô‡ÞMïÚ [3V;Ù-öö²¯üai¡ËVKv øo—9––b¥¬‚Ú鉑,ÈŠÿŸÊD÷ت¥¥ªÚëœÛtÞD^¬vó‘1õÁÈìtd·¨&Z¶&‹¶RÎ6mU[ç¢áX*߯éÒ¶=º‘¼f|v=²«Ù—ž¨vŸO˜»USJÖöa!;¼S£lyÍ(ízdwTX>g{ë×ti“ñet‘¼f¬DvMxõ;Y·Ì)¾%tnÓCýuPñ²ëëëë<ijå|ý0ƒ¾ÆÙ÷ïôx?zmR7=›?l¨6mÕ£ÕçešÞµ¼®fqq¤&®ð‘=N‡îÀ†„l÷{v‡·Ò„~”ÍÆô;g¬È¦ç `ˆl:1¾†m`. ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †£¿7o Ý…ŽŽŽîß;º„$²YŠÏ„\Ô郳¡»@`&FÂÙaˆl€0D6@" ‘Í6ÚÛ?Xí&{ûů¼|†`@.òcW\]^4=ÜÛ?(= ÛÉ(›­“¨ñ/Te@1¾³ápuM^2/Ð>p.(nXmÈœ-!²Ù.ytfí<+ó…bÒš¹5—ª*ª}µ!œÈfWtL^2l3‘ÍÖ64©Ùf"›-RâXôZŽü¼åòÉë2¶È&†êLtËÜô¢Q›Ï›¯T‘×l!‘Íi ß¹¹Üž°M›Wë_¨ZØ0‘Íx¸ ÑÙÐqêCX3zÞý†ÈCd„a.›¥øðYØ$‘MGGGCwv‹È¦¿û÷N†îìsÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙaˆl€0D6@" ‘ †ÈCd„!²ÂÙa¼0tìÆÍ[Cw!¤£££û÷N†î!‰l–òøÑá»Ì郳¡»@`&FÂÙaˆl€0D6@" ‘Í¶ØØ¥§Ί_yÓ®å`û¹È-rãæ­•_5xúàìÎK·K+§ÓiµéÓg7nÞ:>>®–‡-a”ÍVÈ‚õøøx•×¾åçñ£‡ùWzþsobke³-òqnžžùLE>컦8¹‘—™;p.Äóòµ•ƒ3 ‘ÍðòÄÌÚy>Þyév6àÍVvY“ “¥5Åqt>œÏó7ûƒ‘-gå³Ík+÷žO†"²Ù ÅÁu¾œ/dÑYƒçkòSˆ©»ÅªJk2ŹìÚüÍV¶W›'²Ù sg±«A™­©žHì¨Kòö®ÖDd3°âäF¦:õ\½ê£¸&¯c–y­•âD6ë^Û—Ï g‹sÊíkNœ•æ©‹óã]äå‹W°ä•/ñ*aD6«†i¾¦8ú.Na·¯©ÎSgeò¿ M-–Ú}üèa©rm'²^Ó¢iaÈBIEND®B`‚cluster-1.52a/html/images/minifile.png0000644000100500010050000002031107505045400017620 0ustar mdehoonmdehoon‰PNG  IHDR[NÁ"&gAMA± üabKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÒ "¨ü IDATxœí]PSYº÷Ÿ$ä#ÙÑZùʨݨ-xËH»FQ§û-¿8ï{ÑajÞ'¹h¨:XsA}Ñ`Õ$NUOw8€Vц‘*›ÂiœÆ6éÐhlq‡¨ddï$|$!á\<¸‰I@P!›éý+Ë"+kï¿z>z­ïÕ¶.O­¯R Þ?ÿ™ûᇜ7ßœùïÿöž;Ç­ª s8xW®Ì^¥{NNN˜Ãæpp ¼çÎù%†9/ßIuÚMäÄ—ïlU¤'ªÍèt›ÛÓ5jÇ Cã.è%'zÉ HŽŽP¤'&GGô’C㮡qæô̓‰6·Gm~ÔùØŽðœx6ú×1Û XÞùØ.ä‡ýôn&åö4üÃúEz¢$NÚ‚ÌÇ•a2KgwΗÁ÷Ñ$º\~öã˜HçY>T¦ácéKã÷-ZâûÑ·2/^LÇbÒ—iù¸2Lv>þ+t‹òý¸øš÷m*a rKK½JåŒÅ‹¹ÅÅàmnæddpÿðàìÙÃ-(ðÖÕqÿòŠš¹~fŒFŽXPßyD„ó°`/VŠiì™Ãæöà¸ýÓ=oTìH9±1–£ÜÓ5ÙoÞn"'.“Ký¡Ó×:}ýî•arpÜIðy«· /$^Ð24fs{è9Ô|ö¯ ¿»~wpÜ™¡6?Z`΃;¼ñï[‰pÖíà¸ÓæöÞ]Cã."œ÷u^ZMöÆ–á1Ó²u¾ŠôăIkq¾³;^¸@Î%Õ¼Ííñk*óô{öðÁhô8à=wŽûá‡þÿ”îxëêpùàÕ’&Š*J}Meîzl«È|ÙU‰¢Ôõ6×ôŸß¤S$ñ"œ—¥3(ÒwÇ _ÿüæÞÖ^ÓØDR4ß46±·µ7³Ù ‰¥¾¶ÔßúlÏë”ÛsúúÝôµQ;RVoA^žŠ)Ÿ÷úç7ËnÔdoÜ'´ÅÀiåö¨LÃø°/§0œW“½©ó±=þÂß;Û¿|g«0œGü @Èçµ ½þùÍ’îûE©¯-ßx—¨°/P¤%,sI5/ çù5Î ë³ÈÂÂòÖg‘……eŽç¯Z­<^ïÿ„Ú–Ÿ)Lœ5LMnµ ,,?SØY ˼ýï±¹ìñQ¿›ËÑóÐ "Ð5|sÐ>’,œ}bÚGz­wéˆß!Ðk5ÿ4fñ͆y|SðT¾Gù2=]ýª‹¹,Ñ8-¯é hµ“Û·û ]HÒ{þ¯7n¸·¤†­Yà ‰a´mm.±˜'yüÔÔŽgÿÚŸX,žÚsú—¾Ã%•ò¿²Xª¤íì2”ýÅ!Iï±ãcúŽy:˜†V;)/¢Ó';ô®½ëØñ8#Ðdïú§Ñ8M‘Þì]V½Þ¿VkjÇ•Êe—¼´u“ö€ÅâÉÞe¥Hoí¹ñŠÊW êY&´ÚÉ÷åhë&÷ç=ñûÖ`p?NZ,«ÙWžù‰¬ô›jå.yU·F™-O‹M€–{íD„@’”uù^ûÁMoý™Æupï÷í§›Ï¨oÕÜô¶úV½2[.IÚ™ß$ï¾™,ÜßT„]Ìì!}Íê[õ5ûÊOl;ÜØ×\ÒV.IÊ:±íð2UÄRÉ;ðDœ²jF5µã–àNre¥1ø(‹Œz¸²FÍa±xÊJc #€qýž®‹§¶6®J/†Ñà–É"¶g„gd<³o±xÄbžJ%Ôë]•( •Ïçjë:±˜¥Aš„¼ˆ"ˆÙ$WÈQfËût%måÉ„¢³Ïö†>$)K’˜ÕÒß>ßot÷¤Ç¥ ù1’ĬΡž®á› IÚ¹;1:‡¾³9íÊlyÑ['éCZúÛÓãR± 8±ípû©zætÐýml³Ç~¾”G«TÁÝפR¾Åâ9vl¬ªj%|„ƒ"ó°; I¯N7%Íyf°ý¾œ*.~Y'ÎÃ`œ®«›¬¨täxB’^:]*ågd„gï²*”6Uèªú¹FâDX«ÌyöBTT:Ä)¼ŒŒÙfÏù['%IYC=µûÊ…ü´˜FÍ7åÜœK9íôÄa©¤Å¦úÝð”Óî»v€ã–å€ 8ÅÅÑ:Ó`p‡Ð ’ôæxRüA´ï¡¦vJŠ£Cg×Ò8¯!º¿½Úº.##\[7I§ëõ.£Ñ­ªÊdk*‹,,,s°>‹,,,s°= ËlÀÂÂ2Û#°°°ÌÁ‹>˜0hIK€AûˆæV‡ÃAU’ª[Ó5Üófü–º†o6öéüÞ)b"}›ËñéM×,ÿ“B$ ?ž³×j~cÝÆÇÿÔÜjÀ¯‹þ{”N¨ú?EÓjQ­Ðhµ“ºfg Žˆ9 j!Ö? ‡µCÌd¾ªÆtÔÂ0Y 7_“ÀtƒqVÇ€’¶rt*ÓW«o5à½Ýk5WukÔ·h÷¤Î¡ïªº5¾çê¾™ß$¿Üß^ÒVŽ>§›ÏTukúš÷ÖŸ²¹(…ºÜß^Õ­9Ý|&Y°¡ª[ƒjˆ–{íUÝõ­z<ß™—½Þuìø;>æ+_±X<ûóžP¤W§›b²j…¦¢ÒQ{nuD¾®µÌ‘ßÌg! ÖöʶT(HP¥Ó IoÐ&A7£qzë¶Q’ô†)²å }Í¥újevÑå{í5O™~lN& ®a>éÁå{íÉ„¯OÖ—´½Üß^´ãTçPO;rIRVæ'²Î¡Êi—$e}v¸Zý}=Þóéq©&«:‡{ÐuL£wð«¨ÐÖMªª„……‘âž¶n’~@ië&È"T*!Iz³wý³¬4feìya´ÚI”¯ÔŒNç¤ß-3G~3Ÿ…èL ûóžhÔÌ}O3_A wJ Ov8B>[Î)“­Q©„øØ£Û¶Åâ¹xaíÓká1§¹P»¯¼s¨§øYâåþvIbjQ+ˆÉz'E¸R„L£fÓ¨R„ É‚ `½sbÛá/ßU ù1xÿ€$qç£fèê©”ž¡œö^«ù‡Qs²0{¢o‹yí ApHj(jf``¹6Þ… øÄÇ`æÈoæ³¹¤›‹yL¾‘hæ+ˆÑ8MQ^…Ò~ì8©ÕN΂cñ±àÙ¦‚ÝÁà¶X<a\ؘyb›lÐö f_9æëµšmR„p-`1º†(i;k5ãÉÓãRmÐ2-6õÐæÜΡ“õ +BKaA¤N7µ?ï *ÉW/«E~S[;QüÁª‘?E*å£êjë:…Ò?$×jÁ`p;N^¼ ‰¸³^Ìø¨Çg;4üØ ôÜ~¾‰!°=ÊéH&1@9í8¦H&vÖ;7ÿŸ‡oÆ¥€úVýÓ!CÖåþvÓ¨ùä6Ù²–ÙÁ!)/”WDÌí/$qo÷ÅáJ»J0‚à¤W$âR¤7ÅgM‹–ßH¥üÐêˆæ³žúÕ¯Š,XÄOÅ4‚ƒ[i¤— žÙSK«¬¨t\¼ Âk|/æËýí‡6ç~úïÿš[ ¥újzâ zÚMH’vÜ”[ÒV^¦ÿ¨±OwpSnZlj²0¡ª[Ò—’¤¬Æ¾æÆ>]z\êéæ3ðå»ê´ØT"B€Ë ppsn©¾Òã¶,KMŸœ"‚[Yé(þ hNí¹qU•°¢Òá§Õc&2Ù…Ò.“Ehë&»¿½Þ%•ò¥9|…Ò–‘f±xB+˜ÏBüc{·J`APµa±xJ›ªJ¨ÓM0·Í‘­ÉÞeÍ‘òqAž¶yP(m AQ3z½+##ŒW^^ƒö›Ë~b› ÿîîù¿oþŸ7Öþâ£cMVók7€Íe´à¿da‰m‡9=~ÈZÿfåÛg"xü=IY&«™rÚ+¥ÌZŸÞÒßX6×ÏÿxâÉš0~ÑŽSD„€ˆôZÍñÑ¿PdÏm»¶Üo·oôÈ«­›Ü¿?%ú:ÓbñFbúöíáÌ_Vi¿­ÍÕÖæúÓŸ¸[áûr ÷Æxí5nmí„Ó ÿ¥Ýà0´€Ñ8½eKØj#¤ºz\,æegó§¦fþú×É5k8ª*A·´\‘ˆ›º%¬¶vB$â¢Øæ-Ï£GÞ7Üøø×¿g•N,,,s°>‹,,,s°= ËlÀÂÂ2Û#°°°ÌÁÝÛp*óoGðCc_sÜÇ;Ñ}ÈærÄ}¼3îãôΨªnMÜÇ;}¶¹G?/ŠûxgæßŽ`¶Æ¾æ×Õ{ã>ÞY¦ÿó”´¥3 ÚGâ>ÞÙØ× -ýßÐÙ|ÓW’ôîÏ{õpÞ?u…ÂõpËÖÑÐî_¼HjjÇ×oxõð}9¨¨©eJL…Âæg úÒbU_bª®Á· ÷–­£‘QŠ nHÌ©j_ ·¯[ÍmÛ7'·v_ù íª[cs9ÊôÕ‡6çb¼ôSLKEo¥ 4þ¨ëêùìp5COè× ÊlyÑŽ“}ºÍÉ€ÏW ù1EoªêÖ@·&=.uwb&ÓÒߎp}QÈIK5šm΀ƒ›ÞFÔŠm—ÅÅѼÜht£j•í…‘yždï²’äL)ãu ¸VN—…0>Êþ¼'W[×=÷Ø•A,æábA8€Þ"åjë:\™¯­ÀðÐ̱y>JKcŽÃõš#²5 PØ "W‹.ãˆlMe¥#{—Õbñ`”ÇÙ6Ð#Ïêí#ƒ¶ ¯ds9L£fÕc&ŒûƒOC6@²pC²`fÆ¿1½×j¦œ:RÓs3ø}„Ñ5¤×hœÎÈç+êÀfWõ.±˜Çü•E,ým¦•…ðl¡B‹_õJ¥|ƒÁí«fæ>‹~ˆº ÚTÔ>¶æ@’^?½¹oÛöµÙ7'«tbaa™ƒ‰óO–PÁö,,,s°= ËÜ®á›ô{›ËÑ5|sÐ>»|Ø5|ß#"ƒößA€^«9𨠧ò=jå±X{—Õ7Š`:c•Nÿb,Páx9ðv࢛@é7Õƒö‘ªn2[Žú‚–{íD„àÐæÜ¶fÇèL÷~ß.IÊÂèLè ýÕ{ÓèìHÁd½#IÊúê=ÍWïi ±¯Y}«¾f_ùèÿÿ®f_ycŸnÅ$4è-G’A^²ìÏ{b4®Õ#rI7¥PÚ·ÆwÎW[×D†¶w«¬t\¼°¶ûÛX‚àú6Dl|Ý߯j4º$°,+—tSÁíþ6öâ…µº,¹œ¢[WÈQfËût%måÉ„¢³Ïö†>$) c:Í÷3Ã=è¶ IÌêê¡]ѹ shV×H9íUÝj”9´ô·§Ç¥¢öÉWµ’§õʺ oÏkˆU¤hØžÔ·G*å‘­1Üã4† Fã4¾À—Jù¾#²ŒŒ0‚à*6ÎYÈà-Œÿe˜ïBÀ%Ý”e`nÏn.Èß:‰×jŸ†xC%ÒÁM¹7çRN;=qX*¸R»…rÚKÚÊm.å´cTdÅô޾ˆDÜùÜ~™æd²0 [‹'‚ÎŒBEÍP”—q)Ò‹±3XBIzårÊ7ÐÞìB#Úq°å^;”´•g~"ƒÅÅtò½Ïé"BðÕ{šš}ÿY)ý#å´›FÍÉ‚„§Ž6—£¤íì|ÂJ–—¤°0ò¼†`fœRmݤL¶¦¬4F£!”Jûó`YPЦPÚF·Bi3ÜÁ• }ºô¸TœüŸØ&ó8Ð/í#‡6åvõ´ôÓÐ×,IÊÚ˜IDÔ·ê1Ê ÆŒÌo’kn54ü¨€ô¸Ô“¿’ Ú”´í¾YÒVÞØ§óÓP³¼ê`s9zš€3ë\€¯q÷$´ôZïÒ¿C^«ÙéqaJÐ x*¿DšåŽ Ã¿_xo’ôÞ¸áfî\¸$HÒûè‘— 1Üë×yÅÈ IPƒ ·ÙìÁæÄð² ä,ÐHßôW¬t€^«9¿©%A30Vé¤×»P ”½ËÊÀ=K…!’­ Z,„!.žcÇÉ@ƒó<©¨tTT:æ“x2¤e~é¯Xé¤êÖä7Ñq30Yé¤ïp]¼°öjëºÛ}q ŒÒ³$"ÙšO‹Œ±pñÔÔŽwtøßó84¸Úºîjë:&ï+=Ÿ´ÌbñDú¦¿J¥‚¯OÕ/ÉJ§²ÒTƒü 8Ò1D²5Ÿ cá"Á˜z¢,ƒÑMÜõ­ßðˆÉ±Bç“–‰Å¼’âh‹ÅC§¿b¥“ü­“ôžËAa¸Ò ÷±ãdh]ý^†H¶0ƒ!.’÷åTqqT Í"‚[Vóp䵋ÖúFOd KË,ˆààmÖ‹ŸáJ'üxù^;†‡]€ k„’ Ã=˜bs9J¿©þýŽ“!é‚rI7¥PØ/^­–}øYV½Þ…ó…ÙÍSxôÞ¬]*å 0w?(ZZF’Þ Kž T)•ò¥Rþþ¼'z½ëU*ϘÉJ'½ÞUYé¸ÚºŽíX|ÉÈk½²'•øþÊWTð–9Ì'-³X<[¶ŽbºÑè~õJ'?NüJæ—ÉJ'£Ám4NoÝ6Љ“ëCjÔ¿&¨t µKC$âb/€Áqî°?ïIYiLaa¤N7ÅQÙ³ÈÀ‰:IDATJËh¥Sqq¶yU•P,æ±J'–9íPÁ²Â01Ê-—»;Ô&°°üLa⬅…%Tü/^¾•gCUIEND®B`‚cluster-1.52a/html/Bibliography.html0000644000100500010050000001216511505777254017400 0ustar mdehoonmdehoon Bibliography - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Previous: Development, Up: Top


8 Bibliography

Brown, P. O., and Botstein, D. (1999). Exploring the new world of the genome with DNA microarrays. Nat Genet 21, 33–37.

Chu, S., DeRisi, J., Eisen, M., Mulholland, J., Botstein, D., Brown, P. O., and Herskowitz, I. (1998). The transcriptional program of sporulation in budding yeast [published erratum appears in Science 1998 Nov 20; 282 (5393):1421]. Science 282, 699–705.

Conover, W. J. (1980). Practical nonparametric statistics (New York: Wiley).

De Hoon, M., Imoto, S., and Miyano, S. (2002). Statistical analysis of a small set of time-ordered gene expression data using linear splines. Bioinformatics 18, 1477–1485.

De Hoon, M. J. L., Imoto, S., Nolan, J., and Miyano, S. (2004). Open source clustering software. Bioinformatics, 20 (9), 1453–1454.

Eisen, M. B., Spellman, P. T., Brown, P. O., and Botstein, D. (1998). Cluster analysis and display of genome-wide expression patterns. Proc Natl Acad Sci USA 95, 14863–14868.

Hartigan, J. A. (1975). Clustering algorithms (New York: Wiley).

Jain, A. K., and Dubes, R. C. (1988). Algorithms for clustering data (Englewood Cliffs, N.J.: Prentice Hall).

Jardine, N., and Sibson, R. (1971). Mathematical taxonomy (London, New York: Wiley).

Kohonen, T. (1997). Self-organizing maps, 2nd Edition (Berlin; New York: Springer).

Sibson, R. (1973). SLINK: An optimally efficient algorithm for the single-link cluster method. The Computer Journal, 16 (1), 30–34.

Sneath, P. H. A., and Sokal, R. R. (1973). Numerical taxonomy; the principles and practice of numerical classification (San Francisco: W. H. Freeman).

Snedecor, G. W. and Cochran, W. G. (1989). Statistical methods (Ames: Iowa State University Press).

Sokal, R. R., and Sneath, P. H. A. (1963). Principles of numerical taxonomy (San Francisco: W. H. Freeman).

Tamayo, P., Slonim, D., Mesirov, J., Zhu, Q., Kitareewan, S., Dmitrovsky, E., Lander, E., and Golub, T. (1999). Interpreting patterns of gene expression with self-organizing maps: Methods and application to hematopoietic differentiation. Proc. Natl. Acad. Sci. USA, 96, 2907–2912.

Tryon, R. C., and Bailey, D. E. (1970). Cluster analysis (New York: McGraw-Hill).

Tukey, J. W. (1977). Exploratory data analysis (Reading, Mass.: Addison-Wesley Pub. Co.).

Weinstein, J. N., Myers, T. G., OConnor, P. M., Friend, S. H., Fornace, A. J., Jr., Kohn, K. W., Fojo, T., Bates, S. E., Rubinstein, L. V., Anderson, N. L., Buolamwini, J. K., van Osdol, W. W., Monks, A. P., Scudiero, D. A., Sausville, E. A., Zaharevitz, D. W., Bunow, B., Viswanadhan, V. N., Johnson, G. S., Wittes, R. E., and Paull, K. D. (1997). An information-intensive approach to the molecular pharmacology of cancer. Science 275, 343–349.

Wen, X., Fuhrman, S., Michaels, G. S., Carr, D. B., Smith, S., Barker, J. L., and Somogyi, R. (1998). Large-scale temporal gene expression mapping of central nervous system development. Proc Natl Acad Sci USA 95, 334–339.

Yeung, K. Y., and Ruzzo, W. L. (2001). Principal Component Analysis for clustering gene expression data. Bioinformatics 17, 763–774. cluster-1.52a/html/Command.html0000644000100500010050000001374311505777254016346 0ustar mdehoonmdehoon Command - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Next: , Previous: Cluster, Up: Top


5 Running Cluster 3.0 as a command line program

Cluster 3.0 can also be run as a command line program. This may be useful if you want to run Cluster 3.0 on a remote server, and also allows automatic processing a large number of data files by running a batch script. Note, however, that the Python and Perl interfaces to the C Clustering Library may be better suited for this task, as they are more powerful than the command line program (see the manual for the C Clustering Library at http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/cluster.pdf).

The GUI version of Cluster 3.0 can be used as a command line program by applying the appropriate command line parameters. You can also compile Cluster 3.0 without GUI support (if you will be using it from the command line only) by downloading the source code from http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster, and running
configure --without-x
make
make install
The executable is called cluster. To run this program, execute
cluster [options]
in which the options consist of the following command line parameters:

-f filename
File loading
-l
Specifies to log-transform the data before clustering (default is no log-transform)
-cg a|m
Specifies whether to center each row (gene) in the data set:
a: Subtract the mean of each row
m: Subtract the median of each row
(default is no centering)
-ng
Specifies to normalize each row (gene) in the data set (default is no normalization)
-ca a|m
Specifies whether to center each column (microarray) in the data set:
a: Subtract the mean of each column
m: Subtract the median of each column
(default is no centering)
-na
Specifies to normalize each column (microarray) in the data set (default is no normalization)
-u jobname
Allows you to specify a different name for the output files (default is derived from the input file name)
-g [0..9]
Specifies the distance measure for gene clustering. 0 means no gene clustering; for the values 1 through 9, see below (default: 0)
-e [0..9]
Specifies the distance measure for microarray clustering. 0 means no microarray clustering; for the values 1 through 9, see below (default: 0)
-m [msca]
Specifies which hierarchical clustering method to use:
m: Pairwise complete- (maximum-) linkage (default)
s: Pairwise single-linkage
c: Pairwise centroid-linkage
a: Pairwise average-linkage
-k number
Specifies whether to run k-meansclustering instead of hierarchical clustering, and the number of clusters k to use (default: 0, no k-means clustering)
-pg
Specifies to apply Principal Component Analysis to genes instead of clustering
-pa
Specifies to apply Principal Component Analysis to arrays instead of clustering
-s
Specifies to calculate an SOM instead of hierarchical clustering
-x number
Specifies the horizontal dimension of the SOM grid (default: 2)
-y number
Specifies the vertical dimension of the SOM grid (default: 1)
-v, --version
Display version information
-h, --help
Display help information

For the command line options -g, -e, the following integers can be used to specify the distance measure:

0
No clustering
1
Uncentered correlation
2
Pearson correlation
3
Uncentered correlation, absolute value
4
Pearson correlation, absolute value
5
Spearman's rank correlation
6
Kendall's tau
7
Euclidean distance
8
City-block distance

By default, no clustering is done, allowing you to use cluster for normalizing a data set only. cluster-1.52a/html/TreeView.html0000644000100500010050000000433611505777254016520 0ustar mdehoonmdehoon TreeView - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Next: , Previous: Command, Up: Top


6 TreeView

TreeView is a program that allows interactive graphical analysis of the results from Cluster. TreeView reads in matching *.cdt and *.gtr, *.atr, *.kgg, or *.kag files produced by Cluster. We recommend using the Java program Java TreeView, which is based on the original TreeView. Java TreeView was written by Alok Saldanha at Stanford University; it can be downloaded from http://jtreeview.sourceforge.net/. Java TreeView runs on Windows, Macintosh, Linux, and Unix computers, and can show both hierarchical and k-meansresults. cluster-1.52a/html/Makefile0000644000100500010050000000022510325265211015511 0ustar mdehoonmdehoondocdir = ../doc index.html: $(docdir)/cluster3.texinfo makeinfo --html $(docdir)/cluster3.texinfo python mac.py distdir: . clean: rm -f *.html cluster-1.52a/html/Contents.html0000644000100500010050000000765611505777254016573 0ustar mdehoonmdehoon Contents - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Next: , Previous: Top, Up: Top


cluster-1.52a/html/PCA.html0000644000100500010050000002732711505777254015376 0ustar mdehoonmdehoon PCA - Cluster 3.0 for Windows, Mac OS X, Linux, Unix

Previous: SOM, Up: Cluster


4.4 Principal Component Analysis

images/pca.png

Principal Component Analysis (PCA) is a widely used technique for analyzing multivariate data. A practical example of applying Principal Component Analysis to gene expression data is presented by Yeung and Ruzzo (2001).

In essence, PCA is a coordinate transformation in which each row in the data matrix is written as a linear sum over basis vectors called principal components, which are ordered and chosen such that each maximally explains the remaining variance in the data vectors. For example, an n \times 3 data matrix can be represented as an ellipsoidal cloud of n points in three dimensional space. The first principal component is the longest axis of the ellipsoid, the second principal component the second longest axis of the ellipsoid, and the third principal component is the shortest axis. Each row in the data matrix can be reconstructed as a suitable linear combination of the principal components. However, in order to reduce the dimensionality of the data, usually only the most important principal components are retained. The remaining variance present in the data is then regarded as unexplained variance.

The principal components can be found by calculating the eigenvectors of the covariance matrix of the data. The corresponding eigenvalues determine how much of the variance present in the data is explained by each principal component.

Before applying PCA, typically the mean is subtracted from each column in the data matrix. In the example above, this effectively centers the ellipsoidal cloud around its centroid in 3D space, with the principal components describing the variation of poins in the ellipsoidal cloud with respect to their centroid.

In Cluster, you can apply PCA to the rows (genes) of the data matrix, or to the columns (microarrays) of the data matrix. In each case, the output consists of two files. When applying PCA to genes, the names of the output files are JobName_pca_gene.pc.txt and JobName_pca_gene.coords.txt, where the former contains contains the principal components, and the latter contains the coordinates of each row in the data matrix with respect to the principal components. When applying PCA to the columns in the data matrix, the respective file names are JobName_pca_array.pc.txt and JobName_pca_array.coords.txt. The original data matrix can be recovered from the principal components and the coordinates.

As an example, consider this input file:

UNIQID EXP1 EXP2 EXP3
GENE1 3 4 -2
GENE2 4 1 -3
GENE3 1 -8 7
GENE4 -6 6 4
GENE5 0 -3 8
Applying PCA to the rows (genes) of the data in this input file generates a coordinate file containing

UNIQID NAME GWEIGHT 13.513398 10.162987 2.025283
GENE1 GENE1 1.000000 6.280326 -2.404095 -0.760157
GENE2 GENE2 1.000000 4.720801 -4.995230 0.601424
GENE3 GENE3 1.000000 -8.755665 -2.117608 0.924161
GENE4 GENE4 1.000000 3.443490 8.133673 0.621082
GENE5 GENE5 1.000000 -5.688953 1.383261 -1.386509
where the first line shows the eigenvalues of the principal components, and a prinpical component file containing

EIGVALUE EXP1 EXP2 EXP3
MEAN 0.400000 0.000000 2.800000
13.513398 0.045493 0.753594 -0.655764
10.162987 -0.756275 0.454867 0.470260
2.025283 -0.652670 -0.474545 -0.590617
with the eigenvalues of the principal components shown in the first column. From this principal component decomposition, we can regenerate the original data matrix as follows:

6.280326 -2.404095 -0.760157
4.720801 -4.995230 0.601424
-8.755665 -2.117608 0.924161
3.443490 8.133673 0.621082
-5.688953 1.383261 -1.386509


·
0.045493 0.753594 -0.655764
-0.756275 0.454867 0.470260
-0.652670 -0.474545 -0.590617


+
0.4 0.0 2.8
0.4 0.0 2.8
0.4 0.0 2.8
0.4 0.0 2.8
0.4 0.0 2.8


=
3 4 -2
4 1 -3
1 -8 7
-6 6 4
0 -3 8

Note that the coordinate file JobName_pca_gene.coords.txt is a valid input file to Cluster 3.0. Hence, it can be loaded into Cluster 3.0 for further analysis, possibly after removing columns with low eigenvalues. cluster-1.52a/src/0000755000100500010050000000000012414674314013706 5ustar mdehoonmdehooncluster-1.52a/src/data.h0000644000100500010050000000602412175473052014772 0ustar mdehoonmdehoon/* The C clustering library. * Copyright (C) 2002 Michiel Jan Laurens de Hoon. * * This library was written at the Laboratory of DNA Information Analysis, * Human Genome Center, Institute of Medical Science, University of Tokyo, * 4-6-1 Shirokanedai, Minato-ku, Tokyo 108-8639, Japan. * Contact: mdehoon 'AT' gsc.riken.jp * * Permission to use, copy, modify, and distribute this software and its * documentation with or without modifications and for any purpose and * without fee is hereby granted, provided that any copyright notices * appear in all copies and that both those copyright notices and this * permission notice appear in supporting documentation, and that the * names of the contributors or copyright holders not be used in * advertising or publicity pertaining to distribution of the software * without specific prior permission. * * THE CONTRIBUTORS AND COPYRIGHT HOLDERS OF THIS SOFTWARE DISCLAIM ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE * OR PERFORMANCE OF THIS SOFTWARE. * */ #include /* contains the FILE declaration */ /*============================================================================*/ /* Function declaration */ /*============================================================================*/ int GetRows(void); int GetColumns(void); char* Load(FILE* file); /* Load in data from tab-delimited text file */ int Save(FILE* outputfile, int geneID, int arrayID); int SelectSubset(int n, const int use[]); void LogTransform(void); int AdjustGenes(int MeanCenter, int MedianCenter, int Normalize); int AdjustArrays(int MeanCenter, int MedianCenter, int Normalize); int FilterRow(int Row, int bStd, int bPercent, int bAbsVal, int bMaxMin, double absVal, double percent, double std, int numberAbs, double maxmin); const char* CalculateWeights(double GeneCutoff, double GeneExponent, char GeneDist, double ArrayCutoff, double ArrayExponent, char ArrayDist); int HierarchicalCluster(FILE* file, char metric, int transpose, char method); int GeneKCluster(int k, int nTrials, char method, char dist, int* NodeMap); int ArrayKCluster(int k, int nTrials, char method, char dist, int* NodeMap); int SaveGeneKCluster(FILE* outputfile, int k, const int* NodeMap); int SaveArrayKCluster(FILE* outputfile, int k, const int* NodeMap); int PerformSOM(FILE* GeneFile, int GeneXDim, int GeneYDim, int GeneIters, double GeneTau, char GeneMetric, FILE* ArrayFile, int ArrayXDim, int ArrayYDim, int ArrayIters, double ArrayTau, char ArrayMetric); const char* PerformGenePCA(FILE* coordinatefile, FILE* pcfile); const char* PerformArrayPCA(FILE* coordinatefile, FILE* pcfile); void Free(void); cluster-1.52a/src/data.c0000644000100500010050000012320612176166400014764 0ustar mdehoonmdehoon/* The C clustering library. * Copyright (C) 2002 Michiel Jan Laurens de Hoon. * * This library was written at the Laboratory of DNA Information Analysis, * Human Genome Center, Institute of Medical Science, University of Tokyo, * 4-6-1 Shirokanedai, Minato-ku, Tokyo 108-8639, Japan. * Contact: mdehoon 'AT' gsc.riken.jp * * Permission to use, copy, modify, and distribute this software and its * documentation with or without modifications and for any purpose and * without fee is hereby granted, provided that any copyright notices * appear in all copies and that both those copyright notices and this * permission notice appear in supporting documentation, and that the * names of the contributors or copyright holders not be used in * advertising or publicity pertaining to distribution of the software * without specific prior permission. * * THE CONTRIBUTORS AND COPYRIGHT HOLDERS OF THIS SOFTWARE DISCLAIM ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE * OR PERFORMANCE OF THIS SOFTWARE. * */ /* This file contains C code needed for Cluster 3.0, particularly file reading * and data handling. It is platform-independent; platform-dependent code is * located in windows/gui.c (Microsoft Windows), in mac/Controller.m (Mac OS X), * and in x11/gui.c (X11 using Motif). * * Michiel de Hoon, (mdehoon 'AT' gsc.riken.jp). * University of Tokyo, Human Genome Center. * 2003.01.10. */ /*============================================================================*/ /* Header files */ /*============================================================================*/ /* Standard C header files */ #include #include #include #include /* Local header files */ #include "data.h" #include "cluster.h" /* The C clustering library */ /*============================================================================*/ /* Data declaration */ /*============================================================================*/ static int _rows = 0; static int _columns = 0; static double* _geneweight = NULL; static double* _arrayweight = NULL; static double* _geneorder = NULL; /* Saves gene order in the data file */ static double* _arrayorder = NULL; /* Saves array order in the data file */ static int* _geneindex = NULL; /* Set by clustering methods for file output */ static int* _arrayindex = NULL; /* Set by clustering methods for file output */ static char* _uniqID = NULL; /* Stores UNIQID identifier in the data file */ static char** _geneuniqID = NULL; static char** _genename = NULL; static char** _arrayname = NULL; static double** _data = NULL; static int** _mask = NULL; /*============================================================================*/ /* Utility routines */ /*============================================================================*/ static char* GetLine(FILE* inputfile) /* The function GetLine reads one line from the inputfile, and returns it as a * null-terminated string. If inputfile is at EOF, an empty string is returned. * Empty lines are skipped. * If this function fails due to memory allocation error, it returns NULL. * The calling routine should free the char* returned by GetLine. */ { int c; int n = 0; int size = 1023; char* temp; char* line = malloc((size+1)*sizeof(char)); if (!line) return NULL; while (n==0) { while ((c = getc(inputfile))!=EOF && c!='\r' && c!='\n') { if (n == size) { size *= 2; temp = realloc(line,(size+1)*sizeof(char)); if (!temp) { free(line); return NULL; } line = temp; } line[n] = (char)c; n++; } if (c=='\r') { c = getc(inputfile); if (c!='\n' && c!=EOF) ungetc(c,inputfile); } if (c==EOF) break; } line[n] = '\0'; temp = realloc(line,(n+1)*sizeof(char)); if (!temp) /* This should not happen, as temp is smaller than line. * But let's check to make sure anyway. */ { free(line); return NULL; } return temp; } static char* tokenize(char* s) { char* p = s; while (1) { if (*p=='\0') return NULL; if (*p=='\t') { *p = '\0'; return p+1; } p++; } /* Never get here */ return NULL; } static char* MakeID(const char* name, int i) { int n; char* ID; int ndigits = 1; int remainder = i; while (remainder/=10) ndigits++; /* Count how many digits there are in i */ n = strlen(name) + ndigits + 2; /* One more for the X, and one more for the \0 termination character */ ID = malloc(n*sizeof(char)); if (ID) sprintf(ID, "%s%dX",name,i); return ID; } static int SetClusterIndex(char which, int k, int* clusterid) { int i; int cluster; int counter = 0; int* index = NULL; if (which=='g') { index = malloc(_rows*sizeof(int)); if (!index) return 0; for (i=0; i<_rows; i++) index[i] = i; sort(_rows, _geneorder, index); for (cluster = 0; cluster < k; cluster++) { for (i = 0; i < _rows; i++) { const int j = index[i]; if (clusterid[j]==cluster) { _geneindex[counter] = j; counter++; } } } } if (which=='a') { index = malloc(_columns*sizeof(int)); if (!index) return 0; for (i=0; i<_columns; i++) index[i] = i; sort(_columns, _arrayorder, index); for (cluster = 0; cluster < k; cluster++) { for (i = 0; i < _columns; i++) { const int j = index[i]; if (clusterid[j]==cluster) { _arrayindex[counter] = j; counter++; } } } } free(index); return 1; } static int TreeSort(const char which, const int nNodes, const double* order, const double* nodeorder, const int* nodecounts, Node* tree) { const int nElements = nNodes + 1; int i; double* neworder = calloc(nElements, sizeof(double)); /* initialized to 0.0 */ int* clusterids = malloc(nElements*sizeof(int)); if (!neworder || !clusterids) { if (neworder) free(neworder); if (clusterids) free(clusterids); return 0; } for (i = 0; i < nElements; i++) clusterids[i] = i; for (i = 0; i < nNodes; i++) { const int i1 = tree[i].left; const int i2 = tree[i].right; const double order1 = (i1<0) ? nodeorder[-i1-1] : order[i1]; const double order2 = (i2<0) ? nodeorder[-i2-1] : order[i2]; const int count1 = (i1<0) ? nodecounts[-i1-1] : 1; const int count2 = (i2<0) ? nodecounts[-i2-1] : 1; /* If order1 and order2 are equal, their order is determined by * the order in which they were clustered */ if (i1=order2) neworder[j] += increase; if (clusterid==i2 && order1order2) neworder[j] += increase; if (clusterid==i2 && order1<=order2) neworder[j] += increase; if (clusterid==i1 || clusterid==i2) clusterids[j] = -i-1; } } } free(clusterids); if (which=='g') { for (i=0; i<_rows; i++) _geneindex[i] = i; sort(_rows, neworder, _geneindex); } if (which=='a') { for (i=0; i<_columns; i++) _arrayindex[i] = i; sort(_columns, neworder, _arrayindex); } free(neworder); return 1; } static int PerformGeneSOM(FILE* file, int XDim, int YDim, int iterations, double tau, char metric) { int i = 0; int j = 0; int k; int ok; int (*Group)[2] = malloc(_rows*sizeof(int[2])); double*** Nodes = malloc(XDim*sizeof(double**)); int* clusterid = malloc(_rows*sizeof(int)); int* index = malloc(_columns*sizeof(int)); if (Nodes) { for (i = 0; i < XDim; i++) { Nodes[i] = malloc(YDim*sizeof(double*)); j = 0; if (!Nodes[i]) break; for ( ; j < YDim; j++) { Nodes[i][j] = malloc(_columns*sizeof(double)); if (!Nodes[i][j]) break; } if (j < YDim) break; } } if (!Group || !clusterid || !index || !Nodes || i < XDim || j < YDim) { if (Group) free(Group); if (clusterid) free(clusterid); if (index) free(index); if (Nodes) { if (i < XDim) { while (j--) free(Nodes[i][j]); free(Nodes[i]); } while (i--) { for (j = 0; j < YDim; j++) free(Nodes[i][j]); free(Nodes[i]); } free(Nodes); } return 0; } somcluster(_rows, _columns, _data, _mask, _arrayweight, 0, XDim, YDim, tau, iterations, metric, Nodes, Group); for (i=0; i<_rows; i++) clusterid[i] = Group[i][0] * YDim + Group[i][1]; free(Group); for (k=0; k<_columns; k++) index[k] = k; sort(_columns, _arrayorder, index); fputs("NODE", file); for (i=0; i<_columns; i++) fprintf(file, "\t%s", _arrayname[index[i]]); putc('\n', file); for (i=0; i nFileColumns) { int n = 1024; char* temp; char* text = malloc(n*sizeof(char)); if (!text) return NULL; sprintf(text, "Error reading line %d: %d columns given (%d expected)", fileRow, fileColumn, nFileColumns); n = strlen(text) + 1; temp = realloc(text,n*sizeof(char)); if (!temp) { free(text); return NULL; } _rows = 0; _columns = 0; return text; } } } /* Read the first line into a string */ rewind(file); line = GetLine(file); if (!line) return NULL; /* Save which word the user used instead of UniqID */ s = tokenize(line); n = strlen(line); _uniqID = malloc((n+1)*sizeof(char)); if (!_uniqID) { free(line); goto exit; } strcpy(_uniqID, line); /* Allocate space for array names (experiment names) and save them */ _arrayname = calloc(_columns, sizeof(char*)); if (!_arrayname) { free(line); goto exit; } column = 0; fileColumn = 1; while (column < _columns) { char* token = s; s = tokenize(s); n = strlen(token); if (fileColumn!=0 && fileColumn!=geneNameColumn && fileColumn!=geneWeightColumn && fileColumn!=geneOrderColumn) { _arrayname[column] = malloc((n+1)*sizeof(char)); if (!_arrayname[column]) { free(line); goto exit; } strcpy(_arrayname[column], token); column++; } fileColumn++; } free(line); /* Allocate space for array weights */ _arrayweight = malloc(_columns*sizeof(double)); if (!_arrayweight) goto exit; _arrayorder = malloc(_columns*sizeof(double)); if (!_arrayorder) goto exit; _arrayindex = malloc(_columns*sizeof(int)); if (!_arrayindex) goto exit; for (column = 0; column < _columns; column++) { _arrayweight[column] = 1.; _arrayorder[column] = column; } /* Allocate space for data */ _data = calloc(_rows, sizeof(double*)); if (!_data) goto exit; _mask = calloc(_rows, sizeof(int*)); if (!_mask) goto exit; for (row = 0; row < _rows; row++) { _data[row] = malloc(_columns*sizeof(double)); _mask[row] = malloc(_columns*sizeof(int)); if (!_data[row] || !_mask[row]) goto exit; } /* Allocate space for gene quantities */ _geneweight = malloc(_rows*sizeof(double)); _geneorder = malloc(_rows*sizeof(double)); _geneindex = malloc(_rows*sizeof(int)); _geneuniqID = calloc(_rows, sizeof(char*)); _genename = calloc(_rows, sizeof(char*)); if (!_geneweight || !_geneorder || !_geneindex || !_geneuniqID || !_genename) goto exit; /* Unless a GWEIGHT column exists, * fill the gene weights with the default value */ if (geneWeightColumn == -1) for (row = 0; row < _rows; row++) _geneweight[row] = 1.; /* Unless a GORDER column exist, set the gene order to the default value */ if (geneOrderColumn == -1) for (row = 0; row < _rows; row++) _geneorder[row] = row; /* Read in gene data */ row = 0; fileRow = 1; while (1) { line = GetLine(file); /* Reached end of file */ if (!line) goto exit; if (line[0]=='\0') { free(line); break; } if (fileRow==arrayWeightRow) { column = 0; fileColumn = 1; /* Skipping UNIQID column */ s = tokenize(line); while (column < _columns) { char* error = NULL; char* token = s; s = tokenize(s); if (fileColumn!=geneNameColumn && fileColumn!=geneWeightColumn && fileColumn!=geneOrderColumn) { _arrayweight[column] = 0; /* Default value */ if(token[0]!='\0') { const double number = strtod(token, &error); if (!(*error)) _arrayweight[column] = number; } column++; } fileColumn++; } } else if (fileRow==arrayOrderRow) { column = 0; fileColumn = 1; /* Skipping UNIQID column */ s = tokenize(line); while (column < _columns) { char* error = NULL; char* token = s; s = tokenize(s); if (fileColumn!=geneNameColumn && fileColumn!=geneWeightColumn && fileColumn!=geneOrderColumn) { _arrayorder[column] = 0; /* Default value */ if(token[0]!='\0') { const double number = strtod(token, &error); if (!(*error)) _arrayorder[column] = number; } column++; } fileColumn++; } } else { column = 0; fileColumn = 0; s = line; while (s) { char* token = s; s = tokenize(s); if (fileColumn==0) { const int n = strlen(token) + 1; _geneuniqID[row] = malloc(n*sizeof(char)); if (!_geneuniqID[row]) { free(line); goto exit; } strcpy(_geneuniqID[row], token); } else if (fileColumn==geneNameColumn) { const int n = strlen(token) + 1; _genename[row] = malloc(n*sizeof(char)); if (!_genename[row]) { free(line); goto exit; } strcpy(_genename[row],token); } else if (fileColumn==geneWeightColumn) { char* error = NULL; double number = strtod(token, &error); if (!(*error)) _geneweight[row] = number; else _geneweight[row] = 0.; } else if (fileColumn==geneOrderColumn) { char* error = NULL; double number = strtod(token, &error); if (!(*error)) _geneorder[row] = number; else _geneorder[row] = 0.; } else { char* error = NULL; _data[row][column] = 0; _mask[row][column] = 0; if (token[0]!='\0') /* Otherwise it is a missing value */ { double number = strtod(token, &error); if (!(*error)) { _data[row][column] = number; _mask[row][column] = 1; } } column++; } fileColumn++; } row++; } fileRow++; free(line); } sort(_rows, _geneorder, _geneindex); sort(_columns, _arrayorder, _arrayindex); return "ok"; exit: Free(); return NULL; } int Save(FILE* outputfile, int geneID, int arrayID) { int row, column; if (geneID) fputs("GID\t", outputfile); fputs(_uniqID, outputfile); fputs("\tNAME\tGWEIGHT", outputfile); /* Now add headers for data columns */ for (column = 0; column < _columns; column++) { putc('\t', outputfile); fputs(_arrayname[_arrayindex[column]], outputfile); } putc('\n', outputfile); if (arrayID) { fputs("AID", outputfile); if (geneID) putc('\t',outputfile); fputs("\t\t", outputfile); for (column = 0; column < _columns; column++) { char* ID = MakeID("ARRY",_arrayindex[column]); if (!ID) return 0; putc('\t', outputfile); fputs(ID, outputfile); free(ID); } putc('\n', outputfile); } fputs("EWEIGHT", outputfile); if (geneID) putc('\t', outputfile); fputs("\t\t", outputfile); for (column = 0; column < _columns; column++) fprintf(outputfile, "\t%f", _arrayweight[_arrayindex[column]]); putc('\n', outputfile); for (row = 0; row < _rows; row++) { int index = _geneindex[row]; if (geneID) { char* ID = MakeID("GENE",index); if (!ID) return 0; fputs(ID, outputfile); free(ID); putc('\t', outputfile); } fputs(_geneuniqID[index], outputfile); putc('\t', outputfile); if (_genename[index]) fputs(_genename[index], outputfile); else fputs(_geneuniqID[index], outputfile); fprintf(outputfile, "\t%f", _geneweight[index]); for (column = 0; column < _columns; column++) { int columnindex = _arrayindex[column]; putc('\t', outputfile); if (_mask[index][columnindex]) fprintf(outputfile, "%f", _data[index][columnindex]); } putc('\n', outputfile); } return 1; } int SelectSubset(int n, const int use[]) { int row; double** data = malloc(n*sizeof(double*)); int** mask = malloc(n*sizeof(int*)); char** geneuniqID = malloc(n*sizeof(char*)); char** genename = malloc(n*sizeof(char*)); double* geneorder = malloc(n*sizeof(double)); double* geneweight = malloc(n*sizeof(double)); if (!data || !mask || !geneuniqID || !genename || !geneorder || !geneweight) { if (data) free(data); if (mask) free(mask); if (geneuniqID) free(geneuniqID); if (genename) free(genename); if (geneorder) free(geneorder); if (geneweight) free(geneweight); return 0; } n = 0; for (row = 0; row < _rows; row++) { if (use[row]) { data[n] = _data[row]; mask[n] = _mask[row]; geneuniqID[n] = _geneuniqID[row]; genename[n] = _genename[row]; geneorder[n] = _geneorder[row]; geneweight[n] = _geneweight[row]; n++; } else { free(_data[row]); free(_mask[row]); free(_geneuniqID[row]); if (_genename[row]) free(_genename[row]); } } free(_data); free(_mask); free(_geneuniqID); free(_genename); free(_geneorder); free(_geneweight); _rows = n; _data = data; _mask = mask; _geneuniqID = geneuniqID; _genename = genename; _geneorder = geneorder; _geneweight = geneweight; sort(_rows, _geneorder, _geneindex); return 1; } void LogTransform(void) { int row, column; for (row = 0; row < _rows; row++) { /* Log transformation */ for (column = 0; column < _columns; column++) { if (_mask[row][column] && _data[row][column] > 0) _data[row][column] = log(_data[row][column])/log(2.); else _mask[row][column]=0; } } return; } int AdjustGenes(int MeanCenter, int MedianCenter, int Normalize) { int row, column; for (row = 0; row < _rows; row++) { /* Center genes */ if (MeanCenter || MedianCenter) { int counter = 0; double* temp = malloc(_columns*sizeof(double)); if (!temp) return 0; for (column = 0; column < _columns; column++) { if (_mask[row][column]) { temp[counter] = _data[row][column]; counter++; } } if (counter > 0) { if (MeanCenter) { double rowmean = mean(counter, temp); for (column = 0; column < _columns; column++) if (_mask[row][column]) _data[row][column] -= rowmean; } else if (MedianCenter) { double rowmedian = median(counter, temp); for (column = 0; column < _columns; column++) if (_mask[row][column]) _data[row][column] -= rowmedian; } } free(temp); } /* Normalize genes */ if (Normalize) { double ssqu = 0; for (column = 0; column < _columns; column++) { if (_mask[row][column]) { double term = _data[row][column]; ssqu += term*term; } } if (ssqu > 0) /* Avoid dividing by zero */ { double std = sqrt(ssqu); for (column = 0; column < _columns; column++) if (_mask[row][column]) _data[row][column] /= std; } } } return 1; } int AdjustArrays(int MeanCenter, int MedianCenter, int Normalize) { int row, column; /* Center Arrays */ if (MeanCenter || MedianCenter) { double* temp = malloc(_rows*sizeof(double)); if (!temp) return 0; for (column = 0; column < _columns; column++) { int counter = 0; for (row = 0; row < _rows; row++) { if (_mask[row][column]) { temp[counter] = _data[row][column]; counter++; } } if (counter > 0) { if (MeanCenter) { double columnmean = mean(counter,temp); for (row = 0; row < _rows; row++) if (_mask[row][column]) _data[row][column] -= columnmean; } else if (MedianCenter) { double columnmedian = median(counter,temp); for (row = 0; row < _rows; row++) if (_mask[row][column]) _data[row][column] -= columnmedian; } } } free(temp); } /* Normalize arrays */ if (Normalize) { for (column = 0; column < _columns; column++) { double ssqu = 0; for (row = 0; row < _rows; row++) if (_mask[row][column]) { double term = _data[row][column]; ssqu += term * term; } if (ssqu > 0) /* Avoid dividing by zero */ { double std = sqrt(ssqu); for (row = 0; row < _rows; row++) if (_mask[row][column]) _data[row][column] /= std; } } } return 1; } int PerformSOM(FILE* GeneFile, int GeneXDim, int GeneYDim, int GeneIters, double GeneTau, char GeneMetric, FILE* ArrayFile, int ArrayXDim, int ArrayYDim, int ArrayIters, double ArrayTau, char ArrayMetric) { int ok = 1; if (GeneIters>0) { ok = PerformGeneSOM(GeneFile, GeneXDim, GeneYDim, GeneIters, GeneTau, GeneMetric); if (!ok) return 0; } else sort(_rows, _geneorder, _geneindex); if (ArrayIters>0) { ok = PerformArraySOM(ArrayFile, ArrayXDim, ArrayYDim, ArrayIters, ArrayTau, ArrayMetric); if (!ok) return 0; } else sort(_columns, _arrayorder, _arrayindex); return ok; } int FilterRow(int Row, int bStd, int bPercent, int bAbsVal, int bMaxMin, double absVal, double percent, double std, int numberAbs, double maxmin) { int Count = 0; int CountAbs = 0; double Sum = 0; double Sum2 = 0; double Min = 10000000; double Max = -10000000; /* Compute some row stats */ int Column; for (Column = 0; Column < _columns; Column++) { if (_mask[Row][Column]) { double value = _data[Row][Column]; Sum += value; Sum2 += value*value; Count++; Min = min(value,Min); Max = max(value,Max); if (fabs(value) >= absVal) CountAbs++; } } /* Filter based on percent values present; * remove rows with too many missing values. */ if (bPercent) { int number = (int) ceil(percent*_columns/100); if (Count < number) return 0; } /* Remove rows with low SD */ if (bStd) { if (Count > 1) { double Ave = Sum / (double) Count; double Var = (Sum2 - 2 * Ave * Sum + Count * Ave * Ave)/ (Count-1); if (sqrt(Var) < std) return 0; } else return 0; } /* Remove rows with too few extreme values */ if (bAbsVal && CountAbs < numberAbs) return 0; /* Remove rows with too small Max-Min */ if (bMaxMin && Max - Min < maxmin) return 0; return 1; } const char* CalculateWeights(double GeneCutoff, double GeneExponent, char GeneDist, double ArrayCutoff, double ArrayExponent, char ArrayDist) { double* geneweight = NULL; double* arrayweight = NULL; if (GeneCutoff && GeneExponent && GeneDist) { geneweight = calculate_weights(_rows, _columns, _data, _mask, _arrayweight, 0, GeneDist, GeneCutoff, GeneExponent); if (!geneweight) return "Insufficient memory to calculate the row weights"; } if (ArrayCutoff && ArrayExponent && ArrayDist) { arrayweight = calculate_weights(_rows, _columns, _data, _mask, _geneweight, 1, ArrayDist, ArrayCutoff, ArrayExponent); if (!arrayweight) { if (geneweight) free(geneweight); return "Insufficient memory to calculate the column weights"; } } if (geneweight) { free(_geneweight); _geneweight = geneweight; } if (arrayweight) { free(_arrayweight); _arrayweight = arrayweight; } return NULL; } int HierarchicalCluster(FILE* file, char metric, int transpose, char method) { int i; int ok = 0; const int nNodes = (transpose ? _columns : _rows) - 1; const double* order = (transpose==0) ? _geneorder : _arrayorder; double* weight = (transpose==0) ? _arrayweight : _geneweight; const char* keyword = (transpose==0) ? "GENE" : "ARRY"; double* nodeorder = malloc(nNodes*sizeof(double)); int* nodecounts = malloc(nNodes*sizeof(int)); char** nodeID = calloc(nNodes, sizeof(char*)); /* Perform hierarchical clustering. */ Node* tree = treecluster(_rows, _columns, _data, _mask, weight, transpose, metric, method, NULL); if (!tree || !nodeorder || !nodecounts || !nodeID) { if (tree) free(tree); if (nodeorder) free(nodeorder); if (nodecounts) free(nodecounts); if (nodeID) free(nodeID); return 0; } if (metric=='e' || metric=='b') /* Scale all distances such that they are between 0 and 1 */ { double scale = 0.0; for (i = 0; i < nNodes; i++) if (tree[i].distance > scale) scale = tree[i].distance; if (scale) for (i = 0; i < nNodes; i++) tree[i].distance /= scale; } /* Now we join nodes */ for (i = 0; i < nNodes; i++) { int min1 = tree[i].left; int min2 = tree[i].right; /* min1 and min2 are the elements that are to be joined */ double order1; double order2; int counts1; int counts2; char* ID1; char* ID2; nodeID[i] = MakeID("NODE",i+1); if (!nodeID[i]) break; if (min1 < 0) { int index1 = -min1-1; order1 = nodeorder[index1]; counts1 = nodecounts[index1]; ID1 = nodeID[index1]; tree[i].distance = max(tree[i].distance, tree[index1].distance); } else { order1 = order[min1]; counts1 = 1; ID1 = MakeID(keyword, min1); } if (min2 < 0) { int index2 = -min2-1; order2 = nodeorder[index2]; counts2 = nodecounts[index2]; ID2 = nodeID[index2]; tree[i].distance = max(tree[i].distance, tree[index2].distance); } else { order2 = order[min2]; counts2 = 1; ID2 = MakeID(keyword, min2); } if (ID1 && ID2) { fprintf(file, "%s\t%s\t%s\t", nodeID[i], ID1, ID2); fprintf(file, "%f\n", 1.0-tree[i].distance); } if (ID1 && min1>=0) free(ID1); if (ID2 && min2>=0) free(ID2); if (!ID1 || !ID2) break; nodecounts[i] = counts1 + counts2; nodeorder[i] = (counts1*order1 + counts2*order2) / (counts1 + counts2); } if (i==nNodes) /* Otherwise we encountered the break */ { /* Now set up order based on the tree structure */ const char which = (transpose==0) ? 'g' : 'a'; ok = TreeSort(which, nNodes, order, nodeorder, nodecounts, tree); } free(nodecounts); free(nodeorder); for (i = 0; i < nNodes; i++) if (nodeID[i]) free(nodeID[i]); free(nodeID); free(tree); return ok; } int GeneKCluster(int k, int nTrials, char method, char dist, int* NodeMap) { int ifound = 0; double error; int ok; kcluster(k, _rows, _columns, _data, _mask, _arrayweight, 0, nTrials, method, dist, NodeMap, &error, &ifound); ok = SetClusterIndex('g', k, NodeMap); if (ok) return ifound; return -1; } int ArrayKCluster(int k, int nTrials, char method, char dist, int* NodeMap) { int ifound = 0; double error; int ok; kcluster(k, _rows, _columns, _data, _mask, _geneweight, 1, nTrials, method, dist, NodeMap, &error, &ifound); ok = SetClusterIndex('a', k, NodeMap); if (ok) return ifound; return -1; } int SaveGeneKCluster(FILE* file, int k, const int* NodeMap) { int i, cluster; int* geneindex = malloc(_rows*sizeof(int)); if (!geneindex) return 0; fprintf(file, "%s\tGROUP\n", _uniqID); for (i=0; i<_rows; i++) geneindex[i] = i; sort(_rows,_geneorder,geneindex); for (cluster = 0; cluster < k; cluster++) { for (i = 0; i < _rows; i++) { const int j = geneindex[i]; if (NodeMap[j]==cluster) fprintf(file, "%s\t%d\n", _geneuniqID[j], NodeMap[j]); } } free(geneindex); return 1; } int SaveArrayKCluster(FILE* file, int k, const int* NodeMap) { int i, cluster; int* arrayindex = malloc(_columns*sizeof(int)); if (!arrayindex) return 0; fputs("ARRAY\tGROUP\n", file); for (i=0; i<_columns; i++) arrayindex[i] = i; sort(_columns,_arrayorder,arrayindex); for (cluster = 0; cluster < k; cluster++) { for (i = 0; i < _columns; i++) { const int j = arrayindex[i]; if (NodeMap[j]==cluster) fprintf(file, "%s\t%d\n", _arrayname[j], NodeMap[j]); } } free(arrayindex); return 1; } const char* PerformGenePCA(FILE* coordinatefile, FILE* pcfile) { int i = 0; int j = 0; const int nmin = min(_rows,_columns); double** u = malloc(_rows*sizeof(double*)); double** v = malloc(nmin*sizeof(double*)); double* w = malloc(nmin*sizeof(double)); double* m = malloc(_columns*sizeof(double)); if (u) { for (i = 0; i < _rows; i++) { u[i] = malloc(_columns*sizeof(double)); if (!u[i]) break; } } if (v) { for (j = 0; j < nmin; j++) { v[j] = malloc(nmin*sizeof(double)); if (!v[j]) break; } } if (!u || !v || !w || !m || i < _rows || j < nmin) { if (u) { while (i--) free(u[i]); free(u); } if (v) { while (j--) free(v[j]); free(v); } if (w) free(w); if (m) free(m); return "Insufficient Memory for PCA calculation"; } for (j = 0; j < _columns; j++) { double value; m[j] = 0.0; for (i = 0; i < _rows; i++) { value = _data[i][j]; u[i][j] = value; m[j] += value; } m[j] /= _rows; for (i = 0; i < _rows; i++) u[i][j] -= m[j]; } pca(_rows, _columns, u, v, w); fprintf(coordinatefile, "%s\tNAME\tGWEIGHT", _uniqID); for (j=0; j < nmin; j++) fprintf(coordinatefile, "\t%f", w[j]); putc('\n', coordinatefile); fprintf(pcfile, "EIGVALUE"); for (j=0; j < _columns; j++) fprintf(pcfile, "\t%s", _arrayname[j]); putc('\n', pcfile); fprintf(pcfile, "MEAN"); for (j=0; j < _columns; j++) fprintf(pcfile, "\t%f", m[j]); putc('\n', pcfile); if (_rows>_columns) { for (i=0; i<_rows; i++) { fprintf(coordinatefile, "%s\t",_geneuniqID[i]); if (_genename[i]) fputs(_genename[i], coordinatefile); else fputs(_geneuniqID[i], coordinatefile); fprintf(coordinatefile, "\t%f", _geneweight[i]); for (j=0; j<_columns; j++) fprintf(coordinatefile, "\t%f", u[i][j]); putc('\n', coordinatefile); } for (i = 0; i < nmin; i++) { fprintf(pcfile, "%f", w[i]); for (j=0; j < _columns; j++) fprintf(pcfile, "\t%f", v[i][j]); putc('\n', pcfile); } } else { for (i=0; i<_rows; i++) { fprintf(coordinatefile, "%s\t",_geneuniqID[i]); if (_genename[i]) fputs(_genename[i], coordinatefile); else fputs(_geneuniqID[i], coordinatefile); fprintf(coordinatefile, "\t%f", _geneweight[i]); for (j=0; j_columns) { for (i = 0; i < nmin; i++) { fprintf(coordinatefile, "%f", w[i]); for (j=0; j<_columns; j++) fprintf(coordinatefile, "\t%f", v[j][i]); putc('\n', coordinatefile); } for (i = 0; i < _rows; i++) { fprintf(pcfile, "%s\t",_geneuniqID[i]); if (_genename[i]) fputs(_genename[i], pcfile); else fputs(_geneuniqID[i], pcfile); fprintf(pcfile, "\t%f", m[i]); for (j=0; j<_columns; j++) fprintf(pcfile, "\t%f", u[j][i]); putc('\n', pcfile); } } else /* _rows < _columns */ { for (i=0; i<_rows; i++) { fprintf(coordinatefile, "%f", w[i]); for (j=0; j<_columns; j++) fprintf(coordinatefile, "\t%f", u[j][i]); putc('\n', coordinatefile); } for (i = 0; i < _rows; i++) { fprintf(pcfile, "%s\t",_geneuniqID[i]); if (_genename[i]) fputs(_genename[i], pcfile); else fputs(_geneuniqID[i], pcfile); fprintf(pcfile, "\t%f", m[i]); for (j=0; j #include #include #include #include #include #include "cluster.h" #ifdef WINDOWS # include #endif /* ************************************************************************ */ #ifdef WINDOWS /* Then we make a Windows DLL */ int WINAPI clusterdll_init (HANDLE h, DWORD reason, void* foo) { return 1; } #endif /* ************************************************************************ */ double mean(int n, double x[]) { double result = 0.; int i; for (i = 0; i < n; i++) result += x[i]; result /= n; return result; } /* ************************************************************************ */ double median (int n, double x[]) /* Find the median of X(1), ... , X(N), using as much of the quicksort algorithm as is needed to isolate it. N.B. On exit, the array X is partially ordered. Based on Alan J. Miller's median.f90 routine. */ { int i, j; int nr = n / 2; int nl = nr - 1; int even = 0; /* hi & lo are position limits encompassing the median. */ int lo = 0; int hi = n-1; if (n==2*nr) even = 1; if (n<3) { if (n<1) return 0.; if (n == 1) return x[0]; return 0.5*(x[0]+x[1]); } /* Find median of 1st, middle & last values. */ do { int loop; int mid = (lo + hi)/2; double result = x[mid]; double xlo = x[lo]; double xhi = x[hi]; if (xhixhi) result = xhi; else if (resultresult) j--; loop = 0; if (inr) hi = j; if (i==j) { if (i==nl) lo = nl; if (j==nr) hi = nr; } } else { if (jnr) hi = j; /* Test whether median has been isolated. */ if (i==j && i==nr) return result; } } while (lox[hi]) { double temp = x[lo]; x[lo] = x[hi]; x[hi] = temp; } return x[nr]; } /* ********************************************************************** */ static const double* sortdata = NULL; /* used in the quicksort algorithm */ /* ---------------------------------------------------------------------- */ static int compare(const void* a, const void* b) /* Helper function for sort. Previously, this was a nested function under * sort, which is not allowed under ANSI C. */ { const int i1 = *(const int*)a; const int i2 = *(const int*)b; const double term1 = sortdata[i1]; const double term2 = sortdata[i2]; if (term1 < term2) return -1; if (term1 > term2) return +1; return 0; } /* ---------------------------------------------------------------------- */ void sort(int n, const double data[], int index[]) /* Sets up an index table given the data, such that data[index[]] is in * increasing order. Sorting is done on the indices; the array data * is unchanged. */ { int i; sortdata = data; for (i = 0; i < n; i++) index[i] = i; qsort(index, n, sizeof(int), compare); } /* ********************************************************************** */ static double* getrank (int n, double data[]) /* Calculates the ranks of the elements in the array data. Two elements with * the same value get the same rank, equal to the average of the ranks had the * elements different values. The ranks are returned as a newly allocated * array that should be freed by the calling routine. If getrank fails due to * a memory allocation error, it returns NULL. */ { int i; double* rank; int* index; rank = malloc(n*sizeof(double)); if (!rank) return NULL; index = malloc(n*sizeof(int)); if (!index) { free(rank); return NULL; } /* Call sort to get an index table */ sort (n, data, index); /* Build a rank table */ for (i = 0; i < n; i++) rank[index[i]] = i; /* Fix for equal ranks */ i = 0; while (i < n) { int m; double value = data[index[i]]; int j = i + 1; while (j < n && data[index[j]] == value) j++; m = j - i; /* number of equal ranks found */ value = rank[index[i]] + (m-1)/2.; for (j = i; j < i + m; j++) rank[index[j]] = value; i += m; } free (index); return rank; } /* ---------------------------------------------------------------------- */ static int makedatamask(int nrows, int ncols, double*** pdata, int*** pmask) { int i; double** data; int** mask; data = malloc(nrows*sizeof(double*)); if(!data) return 0; mask = malloc(nrows*sizeof(int*)); if(!mask) { free(data); return 0; } for (i = 0; i < nrows; i++) { data[i] = malloc(ncols*sizeof(double)); if(!data[i]) break; mask[i] = malloc(ncols*sizeof(int)); if(!mask[i]) { free(data[i]); break; } } if (i==nrows) /* break not encountered */ { *pdata = data; *pmask = mask; return 1; } *pdata = NULL; *pmask = NULL; nrows = i; for (i = 0; i < nrows; i++) { free(data[i]); free(mask[i]); } free(data); free(mask); return 0; } /* ---------------------------------------------------------------------- */ static void freedatamask(int n, double** data, int** mask) { int i; for (i = 0; i < n; i++) { free(mask[i]); free(data[i]); } free(mask); free(data); } /* ---------------------------------------------------------------------- */ static double find_closest_pair(int n, double** distmatrix, int* ip, int* jp) /* This function searches the distance matrix to find the pair with the shortest distance between them. The indices of the pair are returned in ip and jp; the distance itself is returned by the function. n (input) int The number of elements in the distance matrix. distmatrix (input) double** A ragged array containing the distance matrix. The number of columns in each row is one less than the row index. ip (output) int* A pointer to the integer that is to receive the first index of the pair with the shortest distance. jp (output) int* A pointer to the integer that is to receive the second index of the pair with the shortest distance. */ { int i, j; double temp; double distance = distmatrix[1][0]; *ip = 1; *jp = 0; for (i = 1; i < n; i++) { for (j = 0; j < i; j++) { temp = distmatrix[i][j]; if (temp= n) { /* Householder reduction to bidiagonal form */ for (i = 0; i < n; i++) { l = i + 1; rv1[i] = scale * g; g = 0.0; s = 0.0; scale = 0.0; for (k = i; k < m; k++) scale += fabs(u[k][i]); if (scale != 0.0) { for (k = i; k < m; k++) { u[k][i] /= scale; s += u[k][i]*u[k][i]; } f = u[i][i]; g = (f >= 0) ? -sqrt(s) : sqrt(s); h = f * g - s; u[i][i] = f - g; if (i < n-1) { for (j = l; j < n; j++) { s = 0.0; for (k = i; k < m; k++) s += u[k][i] * u[k][j]; f = s / h; for (k = i; k < m; k++) u[k][j] += f * u[k][i]; } } for (k = i; k < m; k++) u[k][i] *= scale; } w[i] = scale * g; g = 0.0; s = 0.0; scale = 0.0; if (i= 0) ? -sqrt(s) : sqrt(s); h = f * g - s; u[i][l] = f - g; for (k = l; k < n; k++) rv1[k] = u[i][k] / h; for (j = l; j < m; j++) { s = 0.0; for (k = l; k < n; k++) s += u[j][k] * u[i][k]; for (k = l; k < n; k++) u[j][k] += s * rv1[k]; } for (k = l; k < n; k++) u[i][k] *= scale; } } anorm = max(anorm,fabs(w[i])+fabs(rv1[i])); } /* accumulation of right-hand transformations */ for (i = n-1; i>=0; i--) { if (i < n-1) { if (g != 0.0) { for (j = l; j < n; j++) vt[i][j] = (u[i][j] / u[i][l]) / g; /* double division avoids possible underflow */ for (j = l; j < n; j++) { s = 0.0; for (k = l; k < n; k++) s += u[i][k] * vt[j][k]; for (k = l; k < n; k++) vt[j][k] += s * vt[i][k]; } } } for (j = l; j < n; j++) { vt[j][i] = 0.0; vt[i][j] = 0.0; } vt[i][i] = 1.0; g = rv1[i]; l = i; } /* accumulation of left-hand transformations */ for (i = n-1; i >= 0; i--) { l = i + 1; g = w[i]; if (i!=n-1) for (j = l; j < n; j++) u[i][j] = 0.0; if (g!=0.0) { if (i!=n-1) { for (j = l; j < n; j++) { s = 0.0; for (k = l; k < m; k++) s += u[k][i] * u[k][j]; /* double division avoids possible underflow */ f = (s / u[i][i]) / g; for (k = i; k < m; k++) u[k][j] += f * u[k][i]; } } for (j = i; j < m; j++) u[j][i] /= g; } else for (j = i; j < m; j++) u[j][i] = 0.0; u[i][i] += 1.0; } /* diagonalization of the bidiagonal form */ for (k = n-1; k >= 0; k--) { k1 = k-1; its = 0; while(1) /* test for splitting */ { for (l = k; l >= 0; l--) { l1 = l-1; if (fabs(rv1[l]) + anorm == anorm) break; /* rv1[0] is always zero, so there is no exit * through the bottom of the loop */ if (fabs(w[l1]) + anorm == anorm) /* cancellation of rv1[l] if l greater than 0 */ { c = 0.0; s = 1.0; for (i = l; i <= k; i++) { f = s * rv1[i]; rv1[i] *= c; if (fabs(f) + anorm == anorm) break; g = w[i]; h = sqrt(f*f+g*g); w[i] = h; c = g / h; s = -f / h; for (j = 0; j < m; j++) { y = u[j][l1]; z = u[j][i]; u[j][l1] = y * c + z * s; u[j][i] = -y * s + z * c; } } break; } } /* test for convergence */ z = w[k]; if (l==k) /* convergence */ { if (z < 0.0) /* w[k] is made non-negative */ { w[k] = -z; for (j = 0; j < n; j++) vt[k][j] = -vt[k][j]; } break; } else if (its==30) { ierr = k; break; } else /* shift from bottom 2 by 2 minor */ { its++; x = w[l]; y = w[k1]; g = rv1[k1]; h = rv1[k]; f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y); g = sqrt(f*f+1.0); f = ((x - z) * (x + z) + h * (y / (f + (f >= 0 ? g : -g)) - h)) / x; /* next qr transformation */ c = 1.0; s = 1.0; for (i1 = l; i1 <= k1; i1++) { i = i1 + 1; g = rv1[i]; y = w[i]; h = s * g; g = c * g; z = sqrt(f*f+h*h); rv1[i1] = z; c = f / z; s = h / z; f = x * c + g * s; g = -x * s + g * c; h = y * s; y = y * c; for (j = 0; j < n; j++) { x = vt[i1][j]; z = vt[i][j]; vt[i1][j] = x * c + z * s; vt[i][j] = -x * s + z * c; } z = sqrt(f*f+h*h); w[i1] = z; /* rotation can be arbitrary if z is zero */ if (z!=0.0) { c = f / z; s = h / z; } f = c * g + s * y; x = -s * g + c * y; for (j = 0; j < m; j++) { y = u[j][i1]; z = u[j][i]; u[j][i1] = y * c + z * s; u[j][i] = -y * s + z * c; } } rv1[l] = 0.0; rv1[k] = f; w[k] = x; } } } } else /* m < n */ { /* Householder reduction to bidiagonal form */ for (i = 0; i < m; i++) { l = i + 1; rv1[i] = scale * g; g = 0.0; s = 0.0; scale = 0.0; for (k = i; k < n; k++) scale += fabs(u[i][k]); if (scale != 0.0) { for (k = i; k < n; k++) { u[i][k] /= scale; s += u[i][k]*u[i][k]; } f = u[i][i]; g = (f >= 0) ? -sqrt(s) : sqrt(s); h = f * g - s; u[i][i] = f - g; if (i < m-1) { for (j = l; j < m; j++) { s = 0.0; for (k = i; k < n; k++) s += u[i][k] * u[j][k]; f = s / h; for (k = i; k < n; k++) u[j][k] += f * u[i][k]; } } for (k = i; k < n; k++) u[i][k] *= scale; } w[i] = scale * g; g = 0.0; s = 0.0; scale = 0.0; if (i= 0) ? -sqrt(s) : sqrt(s); h = f * g - s; u[l][i] = f - g; for (k = l; k < m; k++) rv1[k] = u[k][i] / h; for (j = l; j < n; j++) { s = 0.0; for (k = l; k < m; k++) s += u[k][j] * u[k][i]; for (k = l; k < m; k++) u[k][j] += s * rv1[k]; } for (k = l; k < m; k++) u[k][i] *= scale; } } anorm = max(anorm,fabs(w[i])+fabs(rv1[i])); } /* accumulation of right-hand transformations */ for (i = m-1; i>=0; i--) { if (i < m-1) { if (g != 0.0) { for (j = l; j < m; j++) vt[j][i] = (u[j][i] / u[l][i]) / g; /* double division avoids possible underflow */ for (j = l; j < m; j++) { s = 0.0; for (k = l; k < m; k++) s += u[k][i] * vt[k][j]; for (k = l; k < m; k++) vt[k][j] += s * vt[k][i]; } } } for (j = l; j < m; j++) { vt[i][j] = 0.0; vt[j][i] = 0.0; } vt[i][i] = 1.0; g = rv1[i]; l = i; } /* accumulation of left-hand transformations */ for (i = m-1; i >= 0; i--) { l = i + 1; g = w[i]; if (i!=m-1) for (j = l; j < m; j++) u[j][i] = 0.0; if (g!=0.0) { if (i!=m-1) { for (j = l; j < m; j++) { s = 0.0; for (k = l; k < n; k++) s += u[i][k] * u[j][k]; /* double division avoids possible underflow */ f = (s / u[i][i]) / g; for (k = i; k < n; k++) u[j][k] += f * u[i][k]; } } for (j = i; j < n; j++) u[i][j] /= g; } else for (j = i; j < n; j++) u[i][j] = 0.0; u[i][i] += 1.0; } /* diagonalization of the bidiagonal form */ for (k = m-1; k >= 0; k--) { k1 = k-1; its = 0; while(1) /* test for splitting */ { for (l = k; l >= 0; l--) { l1 = l-1; if (fabs(rv1[l]) + anorm == anorm) break; /* rv1[0] is always zero, so there is no exit * through the bottom of the loop */ if (fabs(w[l1]) + anorm == anorm) /* cancellation of rv1[l] if l greater than 0 */ { c = 0.0; s = 1.0; for (i = l; i <= k; i++) { f = s * rv1[i]; rv1[i] *= c; if (fabs(f) + anorm == anorm) break; g = w[i]; h = sqrt(f*f+g*g); w[i] = h; c = g / h; s = -f / h; for (j = 0; j < n; j++) { y = u[l1][j]; z = u[i][j]; u[l1][j] = y * c + z * s; u[i][j] = -y * s + z * c; } } break; } } /* test for convergence */ z = w[k]; if (l==k) /* convergence */ { if (z < 0.0) /* w[k] is made non-negative */ { w[k] = -z; for (j = 0; j < m; j++) vt[j][k] = -vt[j][k]; } break; } else if (its==30) { ierr = k; break; } else /* shift from bottom 2 by 2 minor */ { its++; x = w[l]; y = w[k1]; g = rv1[k1]; h = rv1[k]; f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y); g = sqrt(f*f+1.0); f = ((x - z) * (x + z) + h * (y / (f + (f >= 0 ? g : -g)) - h)) / x; /* next qr transformation */ c = 1.0; s = 1.0; for (i1 = l; i1 <= k1; i1++) { i = i1 + 1; g = rv1[i]; y = w[i]; h = s * g; g = c * g; z = sqrt(f*f+h*h); rv1[i1] = z; c = f / z; s = h / z; f = x * c + g * s; g = -x * s + g * c; h = y * s; y = y * c; for (j = 0; j < m; j++) { x = vt[j][i1]; z = vt[j][i]; vt[j][i1] = x * c + z * s; vt[j][i] = -x * s + z * c; } z = sqrt(f*f+h*h); w[i1] = z; /* rotation can be arbitrary if z is zero */ if (z!=0.0) { c = f / z; s = h / z; } f = c * g + s * y; x = -s * g + c * y; for (j = 0; j < n; j++) { y = u[i1][j]; z = u[i][j]; u[i1][j] = y * c + z * s; u[i][j] = -y * s + z * c; } } rv1[l] = 0.0; rv1[k] = f; w[k] = x; } } } } free(rv1); return ierr; } /* ********************************************************************* */ int pca(int nrows, int ncolumns, double** u, double** v, double* w) /* Purpose ======= This subroutine uses the singular value decomposition to perform principal components analysis of a real nrows by ncolumns rectangular matrix. Arguments ========= nrows (input) int The number of rows in the matrix u. ncolumns (input) int The number of columns in the matrix v. u (input) double[nrows][ncolumns] On input, the array containing the data to which the principal component analysis should be applied. The function assumes that the mean has already been subtracted of each column, and hence that the mean of each column is zero. On output, see below. v (input) double[n][n], where n = min(nrows, ncolumns) Not used on input. w (input) double[n], where n = min(nrows, ncolumns) Not used on input. Return value ============ On output: If nrows >= ncolumns, then u contains the coordinates with respect to the principal components; v contains the principal component vectors. The dot product u . v reproduces the data that were passed in u. If nrows < ncolumns, then u contains the principal component vectors; v contains the coordinates with respect to the principal components. The dot product v . u reproduces the data that were passed in u. The eigenvalues of the covariance matrix are returned in w. The arrays u, v, and w are sorted according to eigenvalue, with the largest eigenvalues appearing first. The function returns 0 if successful, -1 if memory allocation fails, and a positive integer if the singular value decomposition fails to converge. */ { int i; int j; int error; int* index = malloc(ncolumns*sizeof(int)); double* temp = malloc(ncolumns*sizeof(double)); if (!index || !temp) { if (index) free(index); if (temp) free(temp); return -1; } error = svd(nrows, ncolumns, u, w, v); if (error==0) { if (nrows >= ncolumns) { for (j = 0; j < ncolumns; j++) { const double s = w[j]; for (i = 0; i < nrows; i++) u[i][j] *= s; } sort(ncolumns, w, index); for (i = 0; i < ncolumns/2; i++) { j = index[i]; index[i] = index[ncolumns-1-i]; index[ncolumns-1-i] = j; } for (i = 0; i < nrows; i++) { for (j = 0; j < ncolumns; j++) temp[j] = u[i][index[j]]; for (j = 0; j < ncolumns; j++) u[i][j] = temp[j]; } for (i = 0; i < ncolumns; i++) { for (j = 0; j < ncolumns; j++) temp[j] = v[index[j]][i]; for (j = 0; j < ncolumns; j++) v[j][i] = temp[j]; } for (i = 0; i < ncolumns; i++) temp[i] = w[index[i]]; for (i = 0; i < ncolumns; i++) w[i] = temp[i]; } else /* nrows < ncolumns */ { for (j = 0; j < nrows; j++) { const double s = w[j]; for (i = 0; i < nrows; i++) v[i][j] *= s; } sort(nrows, w, index); for (i = 0; i < nrows/2; i++) { j = index[i]; index[i] = index[nrows-1-i]; index[nrows-1-i] = j; } for (j = 0; j < ncolumns; j++) { for (i = 0; i < nrows; i++) temp[i] = u[index[i]][j]; for (i = 0; i < nrows; i++) u[i][j] = temp[i]; } for (j = 0; j < nrows; j++) { for (i = 0; i < nrows; i++) temp[i] = v[j][index[i]]; for (i = 0; i < nrows; i++) v[j][i] = temp[i]; } for (i = 0; i < nrows; i++) temp[i] = w[index[i]]; for (i = 0; i < nrows; i++) w[i] = temp[i]; } } free(index); free(temp); return error; } /* ********************************************************************* */ static double euclid (int n, double** data1, double** data2, int** mask1, int** mask2, const double weight[], int index1, int index2, int transpose) /* Purpose ======= The euclid routine calculates the weighted Euclidean distance between two rows or columns in a matrix. Arguments ========= n (input) int The number of elements in a row or column. If transpose==0, then n is the number of columns; otherwise, n is the number of rows. data1 (input) double array The data array containing the first vector. data2 (input) double array The data array containing the second vector. mask1 (input) int array This array which elements in data1 are missing. If mask1[i][j]==0, then data1[i][j] is missing. mask2 (input) int array This array which elements in data2 are missing. If mask2[i][j]==0, then data2[i][j] is missing. weight (input) double[n] The weights that are used to calculate the distance. index1 (input) int Index of the first row or column. index2 (input) int Index of the second row or column. transpose (input) int If transpose==0, the distance between two rows in the matrix is calculated. Otherwise, the distance between two columns in the matrix is calculated. ============================================================================ */ { double result = 0.; double tweight = 0; int i; if (transpose==0) /* Calculate the distance between two rows */ { for (i = 0; i < n; i++) { if (mask1[index1][i] && mask2[index2][i]) { double term = data1[index1][i] - data2[index2][i]; result += weight[i]*term*term; tweight += weight[i]; } } } else { for (i = 0; i < n; i++) { if (mask1[i][index1] && mask2[i][index2]) { double term = data1[i][index1] - data2[i][index2]; result += weight[i]*term*term; tweight += weight[i]; } } } if (!tweight) return 0; /* usually due to empty clusters */ result /= tweight; return result; } /* ********************************************************************* */ static double cityblock (int n, double** data1, double** data2, int** mask1, int** mask2, const double weight[], int index1, int index2, int transpose) /* Purpose ======= The cityblock routine calculates the weighted "City Block" distance between two rows or columns in a matrix. City Block distance is defined as the absolute value of X1-X2 plus the absolute value of Y1-Y2 plus..., which is equivalent to taking an "up and over" path. Arguments ========= n (input) int The number of elements in a row or column. If transpose==0, then n is the number of columns; otherwise, n is the number of rows. data1 (input) double array The data array containing the first vector. data2 (input) double array The data array containing the second vector. mask1 (input) int array This array which elements in data1 are missing. If mask1[i][j]==0, then data1[i][j] is missing. mask2 (input) int array This array which elements in data2 are missing. If mask2[i][j]==0, then data2[i][j] is missing. weight (input) double[n] The weights that are used to calculate the distance. index1 (input) int Index of the first row or column. index2 (input) int Index of the second row or column. transpose (input) int If transpose==0, the distance between two rows in the matrix is calculated. Otherwise, the distance between two columns in the matrix is calculated. ============================================================================ */ { double result = 0.; double tweight = 0; int i; if (transpose==0) /* Calculate the distance between two rows */ { for (i = 0; i < n; i++) { if (mask1[index1][i] && mask2[index2][i]) { double term = data1[index1][i] - data2[index2][i]; result = result + weight[i]*fabs(term); tweight += weight[i]; } } } else { for (i = 0; i < n; i++) { if (mask1[i][index1] && mask2[i][index2]) { double term = data1[i][index1] - data2[i][index2]; result = result + weight[i]*fabs(term); tweight += weight[i]; } } } if (!tweight) return 0; /* usually due to empty clusters */ result /= tweight; return result; } /* ********************************************************************* */ static double correlation (int n, double** data1, double** data2, int** mask1, int** mask2, const double weight[], int index1, int index2, int transpose) /* Purpose ======= The correlation routine calculates the weighted Pearson distance between two rows or columns in a matrix. We define the Pearson distance as one minus the Pearson correlation. This definition yields a semi-metric: d(a,b) >= 0, and d(a,b) = 0 iff a = b. but the triangular inequality d(a,b) + d(b,c) >= d(a,c) does not hold (e.g., choose b = a + c). Arguments ========= n (input) int The number of elements in a row or column. If transpose==0, then n is the number of columns; otherwise, n is the number of rows. data1 (input) double array The data array containing the first vector. data2 (input) double array The data array containing the second vector. mask1 (input) int array This array which elements in data1 are missing. If mask1[i][j]==0, then data1[i][j] is missing. mask2 (input) int array This array which elements in data2 are missing. If mask2[i][j]==0, then data2[i][j] is missing. weight (input) double[n] The weights that are used to calculate the distance. index1 (input) int Index of the first row or column. index2 (input) int Index of the second row or column. transpose (input) int If transpose==0, the distance between two rows in the matrix is calculated. Otherwise, the distance between two columns in the matrix is calculated. ============================================================================ */ { double result = 0.; double sum1 = 0.; double sum2 = 0.; double denom1 = 0.; double denom2 = 0.; double tweight = 0.; if (transpose==0) /* Calculate the distance between two rows */ { int i; for (i = 0; i < n; i++) { if (mask1[index1][i] && mask2[index2][i]) { double term1 = data1[index1][i]; double term2 = data2[index2][i]; double w = weight[i]; sum1 += w*term1; sum2 += w*term2; result += w*term1*term2; denom1 += w*term1*term1; denom2 += w*term2*term2; tweight += w; } } } else { int i; for (i = 0; i < n; i++) { if (mask1[i][index1] && mask2[i][index2]) { double term1 = data1[i][index1]; double term2 = data2[i][index2]; double w = weight[i]; sum1 += w*term1; sum2 += w*term2; result += w*term1*term2; denom1 += w*term1*term1; denom2 += w*term2*term2; tweight += w; } } } if (!tweight) return 0; /* usually due to empty clusters */ result -= sum1 * sum2 / tweight; denom1 -= sum1 * sum1 / tweight; denom2 -= sum2 * sum2 / tweight; if (denom1 <= 0) return 1; /* include '<' to deal with roundoff errors */ if (denom2 <= 0) return 1; /* include '<' to deal with roundoff errors */ result = result / sqrt(denom1*denom2); result = 1. - result; return result; } /* ********************************************************************* */ static double acorrelation (int n, double** data1, double** data2, int** mask1, int** mask2, const double weight[], int index1, int index2, int transpose) /* Purpose ======= The acorrelation routine calculates the weighted Pearson distance between two rows or columns, using the absolute value of the correlation. This definition yields a semi-metric: d(a,b) >= 0, and d(a,b) = 0 iff a = b. but the triangular inequality d(a,b) + d(b,c) >= d(a,c) does not hold (e.g., choose b = a + c). Arguments ========= n (input) int The number of elements in a row or column. If transpose==0, then n is the number of columns; otherwise, n is the number of rows. data1 (input) double array The data array containing the first vector. data2 (input) double array The data array containing the second vector. mask1 (input) int array This array which elements in data1 are missing. If mask1[i][j]==0, then data1[i][j] is missing. mask2 (input) int array This array which elements in data2 are missing. If mask2[i][j]==0, then data2[i][j] is missing. weight (input) double[n] The weights that are used to calculate the distance. index1 (input) int Index of the first row or column. index2 (input) int Index of the second row or column. transpose (input) int If transpose==0, the distance between two rows in the matrix is calculated. Otherwise, the distance between two columns in the matrix is calculated. ============================================================================ */ { double result = 0.; double sum1 = 0.; double sum2 = 0.; double denom1 = 0.; double denom2 = 0.; double tweight = 0.; if (transpose==0) /* Calculate the distance between two rows */ { int i; for (i = 0; i < n; i++) { if (mask1[index1][i] && mask2[index2][i]) { double term1 = data1[index1][i]; double term2 = data2[index2][i]; double w = weight[i]; sum1 += w*term1; sum2 += w*term2; result += w*term1*term2; denom1 += w*term1*term1; denom2 += w*term2*term2; tweight += w; } } } else { int i; for (i = 0; i < n; i++) { if (mask1[i][index1] && mask2[i][index2]) { double term1 = data1[i][index1]; double term2 = data2[i][index2]; double w = weight[i]; sum1 += w*term1; sum2 += w*term2; result += w*term1*term2; denom1 += w*term1*term1; denom2 += w*term2*term2; tweight += w; } } } if (!tweight) return 0; /* usually due to empty clusters */ result -= sum1 * sum2 / tweight; denom1 -= sum1 * sum1 / tweight; denom2 -= sum2 * sum2 / tweight; if (denom1 <= 0) return 1; /* include '<' to deal with roundoff errors */ if (denom2 <= 0) return 1; /* include '<' to deal with roundoff errors */ result = fabs(result) / sqrt(denom1*denom2); result = 1. - result; return result; } /* ********************************************************************* */ static double ucorrelation (int n, double** data1, double** data2, int** mask1, int** mask2, const double weight[], int index1, int index2, int transpose) /* Purpose ======= The ucorrelation routine calculates the weighted Pearson distance between two rows or columns, using the uncentered version of the Pearson correlation. In the uncentered Pearson correlation, a zero mean is used for both vectors even if the actual mean is nonzero. This definition yields a semi-metric: d(a,b) >= 0, and d(a,b) = 0 iff a = b. but the triangular inequality d(a,b) + d(b,c) >= d(a,c) does not hold (e.g., choose b = a + c). Arguments ========= n (input) int The number of elements in a row or column. If transpose==0, then n is the number of columns; otherwise, n is the number of rows. data1 (input) double array The data array containing the first vector. data2 (input) double array The data array containing the second vector. mask1 (input) int array This array which elements in data1 are missing. If mask1[i][j]==0, then data1[i][j] is missing. mask2 (input) int array This array which elements in data2 are missing. If mask2[i][j]==0, then data2[i][j] is missing. weight (input) double[n] The weights that are used to calculate the distance. index1 (input) int Index of the first row or column. index2 (input) int Index of the second row or column. transpose (input) int If transpose==0, the distance between two rows in the matrix is calculated. Otherwise, the distance between two columns in the matrix is calculated. ============================================================================ */ { double result = 0.; double denom1 = 0.; double denom2 = 0.; int flag = 0; /* flag will remain zero if no nonzero combinations of mask1 and mask2 are * found. */ if (transpose==0) /* Calculate the distance between two rows */ { int i; for (i = 0; i < n; i++) { if (mask1[index1][i] && mask2[index2][i]) { double term1 = data1[index1][i]; double term2 = data2[index2][i]; double w = weight[i]; result += w*term1*term2; denom1 += w*term1*term1; denom2 += w*term2*term2; flag = 1; } } } else { int i; for (i = 0; i < n; i++) { if (mask1[i][index1] && mask2[i][index2]) { double term1 = data1[i][index1]; double term2 = data2[i][index2]; double w = weight[i]; result += w*term1*term2; denom1 += w*term1*term1; denom2 += w*term2*term2; flag = 1; } } } if (!flag) return 0.; if (denom1==0.) return 1.; if (denom2==0.) return 1.; result = result / sqrt(denom1*denom2); result = 1. - result; return result; } /* ********************************************************************* */ static double uacorrelation (int n, double** data1, double** data2, int** mask1, int** mask2, const double weight[], int index1, int index2, int transpose) /* Purpose ======= The uacorrelation routine calculates the weighted Pearson distance between two rows or columns, using the absolute value of the uncentered version of the Pearson correlation. In the uncentered Pearson correlation, a zero mean is used for both vectors even if the actual mean is nonzero. This definition yields a semi-metric: d(a,b) >= 0, and d(a,b) = 0 iff a = b. but the triangular inequality d(a,b) + d(b,c) >= d(a,c) does not hold (e.g., choose b = a + c). Arguments ========= n (input) int The number of elements in a row or column. If transpose==0, then n is the number of columns; otherwise, n is the number of rows. data1 (input) double array The data array containing the first vector. data2 (input) double array The data array containing the second vector. mask1 (input) int array This array which elements in data1 are missing. If mask1[i][j]==0, then data1[i][j] is missing. mask2 (input) int array This array which elements in data2 are missing. If mask2[i][j]==0, then data2[i][j] is missing. weight (input) double[n] The weights that are used to calculate the distance. index1 (input) int Index of the first row or column. index2 (input) int Index of the second row or column. transpose (input) int If transpose==0, the distance between two rows in the matrix is calculated. Otherwise, the distance between two columns in the matrix is calculated. ============================================================================ */ { double result = 0.; double denom1 = 0.; double denom2 = 0.; int flag = 0; /* flag will remain zero if no nonzero combinations of mask1 and mask2 are * found. */ if (transpose==0) /* Calculate the distance between two rows */ { int i; for (i = 0; i < n; i++) { if (mask1[index1][i] && mask2[index2][i]) { double term1 = data1[index1][i]; double term2 = data2[index2][i]; double w = weight[i]; result += w*term1*term2; denom1 += w*term1*term1; denom2 += w*term2*term2; flag = 1; } } } else { int i; for (i = 0; i < n; i++) { if (mask1[i][index1] && mask2[i][index2]) { double term1 = data1[i][index1]; double term2 = data2[i][index2]; double w = weight[i]; result += w*term1*term2; denom1 += w*term1*term1; denom2 += w*term2*term2; flag = 1; } } } if (!flag) return 0.; if (denom1==0.) return 1.; if (denom2==0.) return 1.; result = fabs(result) / sqrt(denom1*denom2); result = 1. - result; return result; } /* ********************************************************************* */ static double spearman (int n, double** data1, double** data2, int** mask1, int** mask2, const double weight[], int index1, int index2, int transpose) /* Purpose ======= The spearman routine calculates the Spearman distance between two rows or columns. The Spearman distance is defined as one minus the Spearman rank correlation. Arguments ========= n (input) int The number of elements in a row or column. If transpose==0, then n is the number of columns; otherwise, n is the number of rows. data1 (input) double array The data array containing the first vector. data2 (input) double array The data array containing the second vector. mask1 (input) int array This array which elements in data1 are missing. If mask1[i][j]==0, then data1[i][j] is missing. mask2 (input) int array This array which elements in data2 are missing. If mask2[i][j]==0, then data2[i][j] is missing. weight (input) double[n] These weights are ignored, but included for consistency with other distance measures. index1 (input) int Index of the first row or column. index2 (input) int Index of the second row or column. transpose (input) int If transpose==0, the distance between two rows in the matrix is calculated. Otherwise, the distance between two columns in the matrix is calculated. ============================================================================ */ { int i; int m = 0; double* rank1; double* rank2; double result = 0.; double denom1 = 0.; double denom2 = 0.; double avgrank; double* tdata1; double* tdata2; tdata1 = malloc(n*sizeof(double)); if(!tdata1) return 0.0; /* Memory allocation error */ tdata2 = malloc(n*sizeof(double)); if(!tdata2) /* Memory allocation error */ { free(tdata1); return 0.0; } if (transpose==0) { for (i = 0; i < n; i++) { if (mask1[index1][i] && mask2[index2][i]) { tdata1[m] = data1[index1][i]; tdata2[m] = data2[index2][i]; m++; } } } else { for (i = 0; i < n; i++) { if (mask1[i][index1] && mask2[i][index2]) { tdata1[m] = data1[i][index1]; tdata2[m] = data2[i][index2]; m++; } } } if (m==0) { free(tdata1); free(tdata2); return 0; } rank1 = getrank(m, tdata1); free(tdata1); if(!rank1) { free(tdata2); return 0.0; /* Memory allocation error */ } rank2 = getrank(m, tdata2); free(tdata2); if(!rank2) /* Memory allocation error */ { free(rank1); return 0.0; } avgrank = 0.5*(m-1); /* Average rank */ for (i = 0; i < m; i++) { const double value1 = rank1[i]; const double value2 = rank2[i]; result += value1 * value2; denom1 += value1 * value1; denom2 += value2 * value2; } /* Note: denom1 and denom2 cannot be calculated directly from the number * of elements. If two elements have the same rank, the squared sum of * their ranks will change. */ free(rank1); free(rank2); result /= m; denom1 /= m; denom2 /= m; result -= avgrank * avgrank; denom1 -= avgrank * avgrank; denom2 -= avgrank * avgrank; if (denom1 <= 0) return 1; /* include '<' to deal with roundoff errors */ if (denom2 <= 0) return 1; /* include '<' to deal with roundoff errors */ result = result / sqrt(denom1*denom2); result = 1. - result; return result; } /* ********************************************************************* */ static double kendall (int n, double** data1, double** data2, int** mask1, int** mask2, const double weight[], int index1, int index2, int transpose) /* Purpose ======= The kendall routine calculates the Kendall distance between two rows or columns. The Kendall distance is defined as one minus Kendall's tau. Arguments ========= n (input) int The number of elements in a row or column. If transpose==0, then n is the number of columns; otherwise, n is the number of rows. data1 (input) double array The data array containing the first vector. data2 (input) double array The data array containing the second vector. mask1 (input) int array This array which elements in data1 are missing. If mask1[i][j]==0, then data1[i][j] is missing. mask2 (input) int array This array which elements in data2 are missing. If mask2[i][j]==0, then data2[i][j] is missing. weight (input) double[n] These weights are ignored, but included for consistency with other distance measures. index1 (input) int Index of the first row or column. index2 (input) int Index of the second row or column. transpose (input) int If transpose==0, the distance between two rows in the matrix is calculated. Otherwise, the distance between two columns in the matrix is calculated. ============================================================================ */ { int con = 0; int dis = 0; int exx = 0; int exy = 0; int flag = 0; /* flag will remain zero if no nonzero combinations of mask1 and mask2 are * found. */ double denomx; double denomy; double tau; int i, j; if (transpose==0) { for (i = 0; i < n; i++) { if (mask1[index1][i] && mask2[index2][i]) { for (j = 0; j < i; j++) { if (mask1[index1][j] && mask2[index2][j]) { double x1 = data1[index1][i]; double x2 = data1[index1][j]; double y1 = data2[index2][i]; double y2 = data2[index2][j]; if (x1 < x2 && y1 < y2) con++; if (x1 > x2 && y1 > y2) con++; if (x1 < x2 && y1 > y2) dis++; if (x1 > x2 && y1 < y2) dis++; if (x1 == x2 && y1 != y2) exx++; if (x1 != x2 && y1 == y2) exy++; flag = 1; } } } } } else { for (i = 0; i < n; i++) { if (mask1[i][index1] && mask2[i][index2]) { for (j = 0; j < i; j++) { if (mask1[j][index1] && mask2[j][index2]) { double x1 = data1[i][index1]; double x2 = data1[j][index1]; double y1 = data2[i][index2]; double y2 = data2[j][index2]; if (x1 < x2 && y1 < y2) con++; if (x1 > x2 && y1 > y2) con++; if (x1 < x2 && y1 > y2) dis++; if (x1 > x2 && y1 < y2) dis++; if (x1 == x2 && y1 != y2) exx++; if (x1 != x2 && y1 == y2) exy++; flag = 1; } } } } } if (!flag) return 0.; denomx = con + dis + exx; denomy = con + dis + exy; if (denomx==0) return 1; if (denomy==0) return 1; tau = (con-dis)/sqrt(denomx*denomy); return 1.-tau; } /* ********************************************************************* */ static double(*setmetric(char dist)) (int, double**, double**, int**, int**, const double[], int, int, int) { switch(dist) { case 'e': return &euclid; case 'b': return &cityblock; case 'c': return &correlation; case 'a': return &acorrelation; case 'u': return &ucorrelation; case 'x': return &uacorrelation; case 's': return &spearman; case 'k': return &kendall; default: return &euclid; } return NULL; /* Never get here */ } /* ********************************************************************* */ static double uniform(void) /* Purpose ======= This routine returns a uniform random number between 0.0 and 1.0. Both 0.0 and 1.0 are excluded. This random number generator is described in: Pierre l'Ecuyer Efficient and Portable Combined Random Number Generators Communications of the ACM, Volume 31, Number 6, June 1988, pages 742-749,774. The first time this routine is called, it initializes the random number generator using the current time. First, the current epoch time in seconds is used as a seed for the random number generator in the C library. The first two random numbers generated by this generator are used to initialize the random number generator implemented in this routine. Arguments ========= None. Return value ============ A double-precison number between 0.0 and 1.0. ============================================================================ */ { int z; static const int m1 = 2147483563; static const int m2 = 2147483399; const double scale = 1.0/m1; static int s1 = 0; static int s2 = 0; if (s1==0 || s2==0) /* initialize */ { unsigned int initseed = (unsigned int) time(0); srand(initseed); s1 = rand(); s2 = rand(); } do { int k; k = s1/53668; s1 = 40014*(s1-k*53668)-k*12211; if (s1 < 0) s1+=m1; k = s2/52774; s2 = 40692*(s2-k*52774)-k*3791; if(s2 < 0) s2+=m2; z = s1-s2; if(z < 1) z+=(m1-1); } while (z==m1); /* To avoid returning 1.0 */ return z*scale; } /* ************************************************************************ */ static int binomial(int n, double p) /* Purpose ======= This routine generates a random number between 0 and n inclusive, following the binomial distribution with probability p and n trials. The routine is based on the BTPE algorithm, described in: Voratas Kachitvichyanukul and Bruce W. Schmeiser: Binomial Random Variate Generation Communications of the ACM, Volume 31, Number 2, February 1988, pages 216-222. Arguments ========= p (input) double The probability of a single event. This probability should be less than or equal to 0.5. n (input) int The number of trials. Return value ============ An integer drawn from a binomial distribution with parameters (p, n). ============================================================================ */ { const double q = 1 - p; if (n*p < 30.0) /* Algorithm BINV */ { const double s = p/q; const double a = (n+1)*s; double r = exp(n*log(q)); /* pow() causes a crash on AIX */ int x = 0; double u = uniform(); while(1) { if (u < r) return x; u-=r; x++; r *= (a/x)-s; } } else /* Algorithm BTPE */ { /* Step 0 */ const double fm = n*p + p; const int m = (int) fm; const double p1 = floor(2.195*sqrt(n*p*q) -4.6*q) + 0.5; const double xm = m + 0.5; const double xl = xm - p1; const double xr = xm + p1; const double c = 0.134 + 20.5/(15.3+m); const double a = (fm-xl)/(fm-xl*p); const double b = (xr-fm)/(xr*q); const double lambdal = a*(1.0+0.5*a); const double lambdar = b*(1.0+0.5*b); const double p2 = p1*(1+2*c); const double p3 = p2 + c/lambdal; const double p4 = p3 + c/lambdar; while (1) { /* Step 1 */ int y; int k; double u = uniform(); double v = uniform(); u *= p4; if (u <= p1) return (int)(xm-p1*v+u); /* Step 2 */ if (u > p2) { /* Step 3 */ if (u > p3) { /* Step 4 */ y = (int)(xr-log(v)/lambdar); if (y > n) continue; /* Go to step 5 */ v = v*(u-p3)*lambdar; } else { y = (int)(xl+log(v)/lambdal); if (y < 0) continue; /* Go to step 5 */ v = v*(u-p2)*lambdal; } } else { const double x = xl + (u-p1)/c; v = v*c + 1.0 - fabs(m-x+0.5)/p1; if (v > 1) continue; /* Go to step 5 */ y = (int)x; } /* Step 5 */ /* Step 5.0 */ k = abs(y-m); if (k > 20 && k < 0.5*n*p*q-1.0) { /* Step 5.2 */ double rho = (k/(n*p*q))*((k*(k/3.0 + 0.625) + 0.1666666666666)/(n*p*q)+0.5); double t = -k*k/(2*n*p*q); double A = log(v); if (A < t-rho) return y; else if (A > t+rho) continue; else { /* Step 5.3 */ double x1 = y+1; double f1 = m+1; double z = n+1-m; double w = n-y+1; double x2 = x1*x1; double f2 = f1*f1; double z2 = z*z; double w2 = w*w; if (A > xm * log(f1/x1) + (n-m+0.5)*log(z/w) + (y-m)*log(w*p/(x1*q)) + (13860.-(462.-(132.-(99.-140./f2)/f2)/f2)/f2)/f1/166320. + (13860.-(462.-(132.-(99.-140./z2)/z2)/z2)/z2)/z/166320. + (13860.-(462.-(132.-(99.-140./x2)/x2)/x2)/x2)/x1/166320. + (13860.-(462.-(132.-(99.-140./w2)/w2)/w2)/w2)/w/166320.) continue; return y; } } else { /* Step 5.1 */ int i; const double s = p/q; const double aa = s*(n+1); double f = 1.0; for (i = m; i < y; f *= (aa/(++i)-s)); for (i = y; i < m; f /= (aa/(++i)-s)); if (v > f) continue; return y; } } } /* Never get here */ return -1; } /* ************************************************************************ */ static void randomassign (int nclusters, int nelements, int clusterid[]) /* Purpose ======= The randomassign routine performs an initial random clustering, needed for k-means or k-median clustering. Elements (genes or microarrays) are randomly assigned to clusters. The number of elements in each cluster is chosen randomly, making sure that each cluster will receive at least one element. Arguments ========= nclusters (input) int The number of clusters. nelements (input) int The number of elements to be clustered (i.e., the number of genes or microarrays to be clustered). clusterid (output) int[nelements] The cluster number to which an element was assigned. ============================================================================ */ { int i, j; int k = 0; double p; int n = nelements-nclusters; /* Draw the number of elements in each cluster from a multinomial * distribution, reserving ncluster elements to set independently * in order to guarantee that none of the clusters are empty. */ for (i = 0; i < nclusters-1; i++) { p = 1.0/(nclusters-i); j = binomial(n, p); n -= j; j += k+1; /* Assign at least one element to cluster i */ for ( ; k < j; k++) clusterid[k] = i; } /* Assign the remaining elements to the last cluster */ for ( ; k < nelements; k++) clusterid[k] = i; /* Create a random permutation of the cluster assignments */ for (i = 0; i < nelements; i++) { j = (int) (i + (nelements-i)*uniform()); k = clusterid[j]; clusterid[j] = clusterid[i]; clusterid[i] = k; } return; } /* ********************************************************************* */ static void getclustermeans(int nclusters, int nrows, int ncolumns, double** data, int** mask, int clusterid[], double** cdata, int** cmask, int transpose) /* Purpose ======= The getclustermeans routine calculates the cluster centroids, given to which cluster each element belongs. The centroid is defined as the mean over all elements for each dimension. Arguments ========= nclusters (input) int The number of clusters. nrows (input) int The number of rows in the gene expression data matrix, equal to the number of genes. ncolumns (input) int The number of columns in the gene expression data matrix, equal to the number of microarrays. data (input) double[nrows][ncolumns] The array containing the gene expression data. mask (input) int[nrows][ncolumns] This array shows which data values are missing. If mask[i][j]==0, then data[i][j] is missing. clusterid (output) int[nrows] if transpose==0 int[ncolumns] if transpose==1 The cluster number to which each element belongs. If transpose==0, then the dimension of clusterid is equal to nrows (the number of genes). Otherwise, it is equal to ncolumns (the number of microarrays). cdata (output) double[nclusters][ncolumns] if transpose==0 double[nrows][nclusters] if transpose==1 On exit of getclustermeans, this array contains the cluster centroids. cmask (output) int[nclusters][ncolumns] if transpose==0 int[nrows][nclusters] if transpose==1 This array shows which data values of are missing for each centroid. If cmask[i][j]==0, then cdata[i][j] is missing. A data value is missing for a centroid if all corresponding data values of the cluster members are missing. transpose (input) int If transpose==0, clusters of rows (genes) are specified. Otherwise, clusters of columns (microarrays) are specified. ======================================================================== */ { int i, j, k; if (transpose==0) { for (i = 0; i < nclusters; i++) { for (j = 0; j < ncolumns; j++) { cmask[i][j] = 0; cdata[i][j] = 0.; } } for (k = 0; k < nrows; k++) { i = clusterid[k]; for (j = 0; j < ncolumns; j++) { if (mask[k][j] != 0) { cdata[i][j]+=data[k][j]; cmask[i][j]++; } } } for (i = 0; i < nclusters; i++) { for (j = 0; j < ncolumns; j++) { if (cmask[i][j]>0) { cdata[i][j] /= cmask[i][j]; cmask[i][j] = 1; } } } } else { for (i = 0; i < nrows; i++) { for (j = 0; j < nclusters; j++) { cdata[i][j] = 0.; cmask[i][j] = 0; } } for (k = 0; k < ncolumns; k++) { i = clusterid[k]; for (j = 0; j < nrows; j++) { if (mask[j][k] != 0) { cdata[j][i]+=data[j][k]; cmask[j][i]++; } } } for (i = 0; i < nrows; i++) { for (j = 0; j < nclusters; j++) { if (cmask[i][j]>0) { cdata[i][j] /= cmask[i][j]; cmask[i][j] = 1; } } } } } /* ********************************************************************* */ static void getclustermedians(int nclusters, int nrows, int ncolumns, double** data, int** mask, int clusterid[], double** cdata, int** cmask, int transpose, double cache[]) /* Purpose ======= The getclustermedians routine calculates the cluster centroids, given to which cluster each element belongs. The centroid is defined as the median over all elements for each dimension. Arguments ========= nclusters (input) int The number of clusters. nrows (input) int The number of rows in the gene expression data matrix, equal to the number of genes. ncolumns (input) int The number of columns in the gene expression data matrix, equal to the number of microarrays. data (input) double[nrows][ncolumns] The array containing the gene expression data. mask (input) int[nrows][ncolumns] This array shows which data values are missing. If mask[i][j]==0, then data[i][j] is missing. clusterid (output) int[nrows] if transpose==0 int[ncolumns] if transpose==1 The cluster number to which each element belongs. If transpose==0, then the dimension of clusterid is equal to nrows (the number of genes). Otherwise, it is equal to ncolumns (the number of microarrays). cdata (output) double[nclusters][ncolumns] if transpose==0 double[nrows][nclusters] if transpose==1 On exit of getclustermedians, this array contains the cluster centroids. cmask (output) int[nclusters][ncolumns] if transpose==0 int[nrows][nclusters] if transpose==1 This array shows which data values of are missing for each centroid. If cmask[i][j]==0, then cdata[i][j] is missing. A data value is missing for a centroid if all corresponding data values of the cluster members are missing. transpose (input) int If transpose==0, clusters of rows (genes) are specified. Otherwise, clusters of columns (microarrays) are specified. cache (input) double[nrows] if transpose==0 double[ncolumns] if transpose==1 This array should be allocated before calling getclustermedians; its contents on input is not relevant. This array is used as a temporary storage space when calculating the medians. ======================================================================== */ { int i, j, k; if (transpose==0) { for (i = 0; i < nclusters; i++) { for (j = 0; j < ncolumns; j++) { int count = 0; for (k = 0; k < nrows; k++) { if (i==clusterid[k] && mask[k][j]) { cache[count] = data[k][j]; count++; } } if (count>0) { cdata[i][j] = median(count,cache); cmask[i][j] = 1; } else { cdata[i][j] = 0.; cmask[i][j] = 0; } } } } else { for (i = 0; i < nclusters; i++) { for (j = 0; j < nrows; j++) { int count = 0; for (k = 0; k < ncolumns; k++) { if (i==clusterid[k] && mask[j][k]) { cache[count] = data[j][k]; count++; } } if (count>0) { cdata[j][i] = median(count,cache); cmask[j][i] = 1; } else { cdata[j][i] = 0.; cmask[j][i] = 0; } } } } } /* ********************************************************************* */ int getclustercentroids(int nclusters, int nrows, int ncolumns, double** data, int** mask, int clusterid[], double** cdata, int** cmask, int transpose, char method) /* Purpose ======= The getclustercentroids routine calculates the cluster centroids, given to which cluster each element belongs. Depending on the argument method, the centroid is defined as either the mean or the median for each dimension over all elements belonging to a cluster. Arguments ========= nclusters (input) int The number of clusters. nrows (input) int The number of rows in the gene expression data matrix, equal to the number of genes. ncolumns (input) int The number of columns in the gene expression data matrix, equal to the number of microarrays. data (input) double[nrows][ncolumns] The array containing the gene expression data. mask (input) int[nrows][ncolumns] This array shows which data values are missing. If mask[i][j]==0, then data[i][j] is missing. clusterid (output) int[nrows] if transpose==0 int[ncolumns] if transpose==1 The cluster number to which each element belongs. If transpose==0, then the dimension of clusterid is equal to nrows (the number of genes). Otherwise, it is equal to ncolumns (the number of microarrays). cdata (output) double[nclusters][ncolumns] if transpose==0 double[nrows][nclusters] if transpose==1 On exit of getclustercentroids, this array contains the cluster centroids. cmask (output) int[nclusters][ncolumns] if transpose==0 int[nrows][nclusters] if transpose==1 This array shows which data values of are missing for each centroid. If cmask[i][j]==0, then cdata[i][j] is missing. A data value is missing for a centroid if all corresponding data values of the cluster members are missing. transpose (input) int If transpose==0, clusters of rows (genes) are specified. Otherwise, clusters of columns (microarrays) are specified. method (input) char For method=='a', the centroid is defined as the mean over all elements belonging to a cluster for each dimension. For method=='m', the centroid is defined as the median over all elements belonging to a cluster for each dimension. Return value ============ The function returns an integer to indicate success or failure. If a memory error occurs, or if method is not 'm' or 'a', getclustercentroids returns 0. If successful, getclustercentroids returns 1. ======================================================================== */ { switch(method) { case 'm': { const int nelements = (transpose==0) ? nrows : ncolumns; double* cache = malloc(nelements*sizeof(double)); if (!cache) return 0; getclustermedians(nclusters, nrows, ncolumns, data, mask, clusterid, cdata, cmask, transpose, cache); free(cache); return 1; } case 'a': { getclustermeans(nclusters, nrows, ncolumns, data, mask, clusterid, cdata, cmask, transpose); return 1; } } return 0; } /* ********************************************************************* */ void getclustermedoids(int nclusters, int nelements, double** distance, int clusterid[], int centroids[], double errors[]) /* Purpose ======= The getclustermedoids routine calculates the cluster centroids, given to which cluster each element belongs. The centroid is defined as the element with the smallest sum of distances to the other elements. Arguments ========= nclusters (input) int The number of clusters. nelements (input) int The total number of elements. distmatrix (input) double array, ragged (number of rows is nelements, number of columns is equal to the row number) The distance matrix. To save space, the distance matrix is given in the form of a ragged array. The distance matrix is symmetric and has zeros on the diagonal. See distancematrix for a description of the content. clusterid (output) int[nelements] The cluster number to which each element belongs. centroid (output) int[nclusters] The index of the element that functions as the centroid for each cluster. errors (output) double[nclusters] The within-cluster sum of distances between the items and the cluster centroid. ======================================================================== */ { int i, j, k; for (j = 0; j < nclusters; j++) errors[j] = DBL_MAX; for (i = 0; i < nelements; i++) { double d = 0.0; j = clusterid[i]; for (k = 0; k < nelements; k++) { if (i==k || clusterid[k]!=j) continue; d += (i < k ? distance[k][i] : distance[i][k]); if (d > errors[j]) break; } if (d < errors[j]) { errors[j] = d; centroids[j] = i; } } } /* ********************************************************************* */ static int kmeans(int nclusters, int nrows, int ncolumns, double** data, int** mask, double weight[], int transpose, int npass, char dist, double** cdata, int** cmask, int clusterid[], double* error, int tclusterid[], int counts[], int mapping[]) { int i, j, k; const int nelements = (transpose==0) ? nrows : ncolumns; const int ndata = (transpose==0) ? ncolumns : nrows; int ifound = 1; int ipass = 0; /* Set the metric function as indicated by dist */ double (*metric) (int, double**, double**, int**, int**, const double[], int, int, int) = setmetric(dist); /* We save the clustering solution periodically and check if it reappears */ int* saved = malloc(nelements*sizeof(int)); if (saved==NULL) return -1; *error = DBL_MAX; do { double total = DBL_MAX; int counter = 0; int period = 10; /* Perform the EM algorithm. First, randomly assign elements to clusters. */ if (npass!=0) randomassign (nclusters, nelements, tclusterid); for (i = 0; i < nclusters; i++) counts[i] = 0; for (i = 0; i < nelements; i++) counts[tclusterid[i]]++; /* Start the loop */ while(1) { double previous = total; total = 0.0; if (counter % period == 0) /* Save the current cluster assignments */ { for (i = 0; i < nelements; i++) saved[i] = tclusterid[i]; if (period < INT_MAX / 2) period *= 2; } counter++; /* Find the center */ getclustermeans(nclusters, nrows, ncolumns, data, mask, tclusterid, cdata, cmask, transpose); for (i = 0; i < nelements; i++) /* Calculate the distances */ { double distance; k = tclusterid[i]; if (counts[k]==1) continue; /* No reassignment if that would lead to an empty cluster */ /* Treat the present cluster as a special case */ distance = metric(ndata,data,cdata,mask,cmask,weight,i,k,transpose); for (j = 0; j < nclusters; j++) { double tdistance; if (j==k) continue; tdistance = metric(ndata,data,cdata,mask,cmask,weight,i,j,transpose); if (tdistance < distance) { distance = tdistance; counts[tclusterid[i]]--; tclusterid[i] = j; counts[j]++; } } total += distance; } if (total>=previous) break; /* total>=previous is FALSE on some machines even if total and previous * are bitwise identical. */ for (i = 0; i < nelements; i++) if (saved[i]!=tclusterid[i]) break; if (i==nelements) break; /* Identical solution found; break out of this loop */ } if (npass<=1) { *error = total; break; } for (i = 0; i < nclusters; i++) mapping[i] = -1; for (i = 0; i < nelements; i++) { j = tclusterid[i]; k = clusterid[i]; if (mapping[k] == -1) mapping[k] = j; else if (mapping[k] != j) { if (total < *error) { ifound = 1; *error = total; for (j = 0; j < nelements; j++) clusterid[j] = tclusterid[j]; } break; } } if (i==nelements) ifound++; /* break statement not encountered */ } while (++ipass < npass); free(saved); return ifound; } /* ---------------------------------------------------------------------- */ static int kmedians(int nclusters, int nrows, int ncolumns, double** data, int** mask, double weight[], int transpose, int npass, char dist, double** cdata, int** cmask, int clusterid[], double* error, int tclusterid[], int counts[], int mapping[], double cache[]) { int i, j, k; const int nelements = (transpose==0) ? nrows : ncolumns; const int ndata = (transpose==0) ? ncolumns : nrows; int ifound = 1; int ipass = 0; /* Set the metric function as indicated by dist */ double (*metric) (int, double**, double**, int**, int**, const double[], int, int, int) = setmetric(dist); /* We save the clustering solution periodically and check if it reappears */ int* saved = malloc(nelements*sizeof(int)); if (saved==NULL) return -1; *error = DBL_MAX; do { double total = DBL_MAX; int counter = 0; int period = 10; /* Perform the EM algorithm. First, randomly assign elements to clusters. */ if (npass!=0) randomassign (nclusters, nelements, tclusterid); for (i = 0; i < nclusters; i++) counts[i]=0; for (i = 0; i < nelements; i++) counts[tclusterid[i]]++; /* Start the loop */ while(1) { double previous = total; total = 0.0; if (counter % period == 0) /* Save the current cluster assignments */ { for (i = 0; i < nelements; i++) saved[i] = tclusterid[i]; if (period < INT_MAX / 2) period *= 2; } counter++; /* Find the center */ getclustermedians(nclusters, nrows, ncolumns, data, mask, tclusterid, cdata, cmask, transpose, cache); for (i = 0; i < nelements; i++) /* Calculate the distances */ { double distance; k = tclusterid[i]; if (counts[k]==1) continue; /* No reassignment if that would lead to an empty cluster */ /* Treat the present cluster as a special case */ distance = metric(ndata,data,cdata,mask,cmask,weight,i,k,transpose); for (j = 0; j < nclusters; j++) { double tdistance; if (j==k) continue; tdistance = metric(ndata,data,cdata,mask,cmask,weight,i,j,transpose); if (tdistance < distance) { distance = tdistance; counts[tclusterid[i]]--; tclusterid[i] = j; counts[j]++; } } total += distance; } if (total>=previous) break; /* total>=previous is FALSE on some machines even if total and previous * are bitwise identical. */ for (i = 0; i < nelements; i++) if (saved[i]!=tclusterid[i]) break; if (i==nelements) break; /* Identical solution found; break out of this loop */ } if (npass<=1) { *error = total; break; } for (i = 0; i < nclusters; i++) mapping[i] = -1; for (i = 0; i < nelements; i++) { j = tclusterid[i]; k = clusterid[i]; if (mapping[k] == -1) mapping[k] = j; else if (mapping[k] != j) { if (total < *error) { ifound = 1; *error = total; for (j = 0; j < nelements; j++) clusterid[j] = tclusterid[j]; } break; } } if (i==nelements) ifound++; /* break statement not encountered */ } while (++ipass < npass); free(saved); return ifound; } /* ********************************************************************* */ void kcluster (int nclusters, int nrows, int ncolumns, double** data, int** mask, double weight[], int transpose, int npass, char method, char dist, int clusterid[], double* error, int* ifound) /* Purpose ======= The kcluster routine performs k-means or k-median clustering on a given set of elements, using the specified distance measure. The number of clusters is given by the user. Multiple passes are being made to find the optimal clustering solution, each time starting from a different initial clustering. Arguments ========= nclusters (input) int The number of clusters to be found. data (input) double[nrows][ncolumns] The array containing the data of the elements to be clustered (i.e., the gene expression data). mask (input) int[nrows][ncolumns] This array shows which data values are missing. If mask[i][j] == 0, then data[i][j] is missing. nrows (input) int The number of rows in the data matrix, equal to the number of genes. ncolumns (input) int The number of columns in the data matrix, equal to the number of microarrays. weight (input) double[n] The weights that are used to calculate the distance. transpose (input) int If transpose==0, the rows of the matrix are clustered. Otherwise, columns of the matrix are clustered. npass (input) int The number of times clustering is performed. Clustering is performed npass times, each time starting from a different (random) initial assignment of genes to clusters. The clustering solution with the lowest within-cluster sum of distances is chosen. If npass==0, then the clustering algorithm will be run once, where the initial assignment of elements to clusters is taken from the clusterid array. method (input) char Defines whether the arithmetic mean (method=='a') or the median (method=='m') is used to calculate the cluster center. dist (input) char Defines which distance measure is used, as given by the table: dist=='e': Euclidean distance dist=='b': City-block distance dist=='c': correlation dist=='a': absolute value of the correlation dist=='u': uncentered correlation dist=='x': absolute uncentered correlation dist=='s': Spearman's rank correlation dist=='k': Kendall's tau For other values of dist, the default (Euclidean distance) is used. clusterid (output; input) int[nrows] if transpose==0 int[ncolumns] if transpose==1 The cluster number to which a gene or microarray was assigned. If npass==0, then on input clusterid contains the initial clustering assignment from which the clustering algorithm starts. On output, it contains the clustering solution that was found. error (output) double* The sum of distances to the cluster center of each item in the optimal k-means clustering solution that was found. ifound (output) int* The number of times the optimal clustering solution was found. The value of ifound is at least 1; its maximum value is npass. If the number of clusters is larger than the number of elements being clustered, *ifound is set to 0 as an error code. If a memory allocation error occurs, *ifound is set to -1. ======================================================================== */ { const int nelements = (transpose==0) ? nrows : ncolumns; const int ndata = (transpose==0) ? ncolumns : nrows; int i; int ok; int* tclusterid; int* mapping = NULL; double** cdata; int** cmask; int* counts; if (nelements < nclusters) { *ifound = 0; return; } /* More clusters asked for than elements available */ *ifound = -1; /* This will contain the number of elements in each cluster, which is * needed to check for empty clusters. */ counts = malloc(nclusters*sizeof(int)); if(!counts) return; /* Find out if the user specified an initial clustering */ if (npass<=1) tclusterid = clusterid; else { tclusterid = malloc(nelements*sizeof(int)); if (!tclusterid) { free(counts); return; } mapping = malloc(nclusters*sizeof(int)); if (!mapping) { free(counts); free(tclusterid); return; } for (i = 0; i < nelements; i++) clusterid[i] = 0; } /* Allocate space to store the centroid data */ if (transpose==0) ok = makedatamask(nclusters, ndata, &cdata, &cmask); else ok = makedatamask(ndata, nclusters, &cdata, &cmask); if(!ok) { free(counts); if(npass>1) { free(tclusterid); free(mapping); return; } } if (method=='m') { double* cache = malloc(nelements*sizeof(double)); if(cache) { *ifound = kmedians(nclusters, nrows, ncolumns, data, mask, weight, transpose, npass, dist, cdata, cmask, clusterid, error, tclusterid, counts, mapping, cache); free(cache); } } else *ifound = kmeans(nclusters, nrows, ncolumns, data, mask, weight, transpose, npass, dist, cdata, cmask, clusterid, error, tclusterid, counts, mapping); /* Deallocate temporarily used space */ if (npass > 1) { free(mapping); free(tclusterid); } if (transpose==0) freedatamask(nclusters, cdata, cmask); else freedatamask(ndata, cdata, cmask); free(counts); } /* *********************************************************************** */ void kmedoids (int nclusters, int nelements, double** distmatrix, int npass, int clusterid[], double* error, int* ifound) /* Purpose ======= The kmedoids routine performs k-medoids clustering on a given set of elements, using the distance matrix and the number of clusters passed by the user. Multiple passes are being made to find the optimal clustering solution, each time starting from a different initial clustering. Arguments ========= nclusters (input) int The number of clusters to be found. nelements (input) int The number of elements to be clustered. distmatrix (input) double array, ragged (number of rows is nelements, number of columns is equal to the row number) The distance matrix. To save space, the distance matrix is given in the form of a ragged array. The distance matrix is symmetric and has zeros on the diagonal. See distancematrix for a description of the content. npass (input) int The number of times clustering is performed. Clustering is performed npass times, each time starting from a different (random) initial assignment of genes to clusters. The clustering solution with the lowest within-cluster sum of distances is chosen. If npass==0, then the clustering algorithm will be run once, where the initial assignment of elements to clusters is taken from the clusterid array. clusterid (output; input) int[nelements] On input, if npass==0, then clusterid contains the initial clustering assignment from which the clustering algorithm starts; all numbers in clusterid should be between zero and nelements-1 inclusive. If npass!=0, clusterid is ignored on input. On output, clusterid contains the clustering solution that was found: clusterid contains the number of the cluster to which each item was assigned. On output, the number of a cluster is defined as the item number of the centroid of the cluster. error (output) double The sum of distances to the cluster center of each item in the optimal k-medoids clustering solution that was found. ifound (output) int If kmedoids is successful: the number of times the optimal clustering solution was found. The value of ifound is at least 1; its maximum value is npass. If the user requested more clusters than elements available, ifound is set to 0. If kmedoids fails due to a memory allocation error, ifound is set to -1. ======================================================================== */ { int i, j, icluster; int* tclusterid; int* saved; int* centroids; double* errors; int ipass = 0; if (nelements < nclusters) { *ifound = 0; return; } /* More clusters asked for than elements available */ *ifound = -1; /* We save the clustering solution periodically and check if it reappears */ saved = malloc(nelements*sizeof(int)); if (saved==NULL) return; centroids = malloc(nclusters*sizeof(int)); if(!centroids) { free(saved); return; } errors = malloc(nclusters*sizeof(double)); if(!errors) { free(saved); free(centroids); return; } /* Find out if the user specified an initial clustering */ if (npass<=1) tclusterid = clusterid; else { tclusterid = malloc(nelements*sizeof(int)); if(!tclusterid) { free(saved); free(centroids); free(errors); return; } } *error = DBL_MAX; do /* Start the loop */ { double total = DBL_MAX; int counter = 0; int period = 10; if (npass!=0) randomassign (nclusters, nelements, tclusterid); while(1) { double previous = total; total = 0.0; if (counter % period == 0) /* Save the current cluster assignments */ { for (i = 0; i < nelements; i++) saved[i] = tclusterid[i]; if (period < INT_MAX / 2) period *= 2; } counter++; /* Find the center */ getclustermedoids(nclusters, nelements, distmatrix, tclusterid, centroids, errors); for (i = 0; i < nelements; i++) /* Find the closest cluster */ { double distance = DBL_MAX; for (icluster = 0; icluster < nclusters; icluster++) { double tdistance; j = centroids[icluster]; if (i==j) { distance = 0.0; tclusterid[i] = icluster; break; } tdistance = (i > j) ? distmatrix[i][j] : distmatrix[j][i]; if (tdistance < distance) { distance = tdistance; tclusterid[i] = icluster; } } total += distance; } if (total>=previous) break; /* total>=previous is FALSE on some machines even if total and previous * are bitwise identical. */ for (i = 0; i < nelements; i++) if (saved[i]!=tclusterid[i]) break; if (i==nelements) break; /* Identical solution found; break out of this loop */ } for (i = 0; i < nelements; i++) { if (clusterid[i]!=centroids[tclusterid[i]]) { if (total < *error) { *ifound = 1; *error = total; /* Replace by the centroid in each cluster. */ for (j = 0; j < nelements; j++) clusterid[j] = centroids[tclusterid[j]]; } break; } } if (i==nelements) (*ifound)++; /* break statement not encountered */ } while (++ipass < npass); /* Deallocate temporarily used space */ if (npass > 1) free(tclusterid); free(saved); free(centroids); free(errors); return; } /* ******************************************************************** */ double** distancematrix (int nrows, int ncolumns, double** data, int** mask, double weights[], char dist, int transpose) /* Purpose ======= The distancematrix routine calculates the distance matrix between genes or microarrays using their measured gene expression data. Several distance measures can be used. The routine returns a pointer to a ragged array containing the distances between the genes. As the distance matrix is symmetric, with zeros on the diagonal, only the lower triangular half of the distance matrix is saved. The distancematrix routine allocates space for the distance matrix. If the parameter transpose is set to a nonzero value, the distances between the columns (microarrays) are calculated, otherwise distances between the rows (genes) are calculated. If sufficient space in memory cannot be allocated to store the distance matrix, the routine returns a NULL pointer, and all memory allocated so far for the distance matrix is freed. Arguments ========= nrows (input) int The number of rows in the gene expression data matrix (i.e., the number of genes) ncolumns (input) int The number of columns in the gene expression data matrix (i.e., the number of microarrays) data (input) double[nrows][ncolumns] The array containing the gene expression data. mask (input) int[nrows][ncolumns] This array shows which data values are missing. If mask[i][j]==0, then data[i][j] is missing. weight (input) double[n] The weights that are used to calculate the distance. The length of this vector is equal to the number of columns if the distances between genes are calculated, or the number of rows if the distances between microarrays are calculated. dist (input) char Defines which distance measure is used, as given by the table: dist=='e': Euclidean distance dist=='b': City-block distance dist=='c': correlation dist=='a': absolute value of the correlation dist=='u': uncentered correlation dist=='x': absolute uncentered correlation dist=='s': Spearman's rank correlation dist=='k': Kendall's tau For other values of dist, the default (Euclidean distance) is used. transpose (input) int If transpose is equal to zero, the distances between the rows is calculated. Otherwise, the distances between the columns is calculated. The former is needed when genes are being clustered; the latter is used when microarrays are being clustered. ======================================================================== */ { /* First determine the size of the distance matrix */ const int n = (transpose==0) ? nrows : ncolumns; const int ndata = (transpose==0) ? ncolumns : nrows; int i,j; double** matrix; /* Set the metric function as indicated by dist */ double (*metric) (int, double**, double**, int**, int**, const double[], int, int, int) = setmetric(dist); if (n < 2) return NULL; /* Set up the ragged array */ matrix = malloc(n*sizeof(double*)); if(matrix==NULL) return NULL; /* Not enough memory available */ matrix[0] = NULL; /* The zeroth row has zero columns. We allocate it anyway for convenience.*/ for (i = 1; i < n; i++) { matrix[i] = malloc(i*sizeof(double)); if (matrix[i]==NULL) break; /* Not enough memory available */ } if (i < n) /* break condition encountered */ { j = i; for (i = 1; i < j; i++) free(matrix[i]); return NULL; } /* Calculate the distances and save them in the ragged array */ for (i = 1; i < n; i++) for (j = 0; j < i; j++) matrix[i][j]=metric(ndata,data,data,mask,mask,weights,i,j,transpose); return matrix; } /* ******************************************************************** */ double* calculate_weights(int nrows, int ncolumns, double** data, int** mask, double weights[], int transpose, char dist, double cutoff, double exponent) /* Purpose ======= This function calculates the weights using the weighting scheme proposed by Michael Eisen: w[i] = 1.0 / sum_{j where d[i][j]= n; i--) { k = tree[i].left; if (k>=0) { clusterid[k] = icluster; icluster++; } k = tree[i].right; if (k>=0) { clusterid[k] = icluster; icluster++; } } nodeid = malloc(n*sizeof(int)); if(!nodeid) { for (i = 0; i < nelements; i++) clusterid[i] = -1; return; } for (i = 0; i < n; i++) nodeid[i] = -1; for (i = n-1; i >= 0; i--) { if(nodeid[i]<0) { j = icluster; nodeid[i] = j; icluster++; } else j = nodeid[i]; k = tree[i].left; if (k<0) nodeid[-k-1] = j; else clusterid[k] = j; k = tree[i].right; if (k<0) nodeid[-k-1] = j; else clusterid[k] = j; } free(nodeid); return; } /* ******************************************************************** */ static Node* pclcluster (int nrows, int ncolumns, double** data, int** mask, double weight[], double** distmatrix, char dist, int transpose) /* Purpose ======= The pclcluster routine performs clustering using pairwise centroid-linking on a given set of gene expression data, using the distance metric given by dist. Arguments ========= nrows (input) int The number of rows in the gene expression data matrix, equal to the number of genes. ncolumns (input) int The number of columns in the gene expression data matrix, equal to the number of microarrays. data (input) double[nrows][ncolumns] The array containing the gene expression data. mask (input) int[nrows][ncolumns] This array shows which data values are missing. If mask[i][j] == 0, then data[i][j] is missing. weight (input) double[ncolumns] if transpose==0; double[nrows] if transpose==1 The weights that are used to calculate the distance. The length of this vector is ncolumns if genes are being clustered, and nrows if microarrays are being clustered. transpose (input) int If transpose==0, the rows of the matrix are clustered. Otherwise, columns of the matrix are clustered. dist (input) char Defines which distance measure is used, as given by the table: dist=='e': Euclidean distance dist=='b': City-block distance dist=='c': correlation dist=='a': absolute value of the correlation dist=='u': uncentered correlation dist=='x': absolute uncentered correlation dist=='s': Spearman's rank correlation dist=='k': Kendall's tau For other values of dist, the default (Euclidean distance) is used. distmatrix (input) double** The distance matrix. This matrix is precalculated by the calling routine treecluster. The pclcluster routine modifies the contents of distmatrix, but does not deallocate it. Return value ============ A pointer to a newly allocated array of Node structs, describing the hierarchical clustering solution consisting of nelements-1 nodes. Depending on whether genes (rows) or microarrays (columns) were clustered, nelements is equal to nrows or ncolumns. See src/cluster.h for a description of the Node structure. If a memory error occurs, pclcluster returns NULL. ======================================================================== */ { int i, j; const int nelements = (transpose==0) ? nrows : ncolumns; int inode; const int ndata = transpose ? nrows : ncolumns; const int nnodes = nelements - 1; /* Set the metric function as indicated by dist */ double (*metric) (int, double**, double**, int**, int**, const double[], int, int, int) = setmetric(dist); Node* result; double** newdata; int** newmask; int* distid = malloc(nelements*sizeof(int)); if(!distid) return NULL; result = malloc(nnodes*sizeof(Node)); if(!result) { free(distid); return NULL; } if(!makedatamask(nelements, ndata, &newdata, &newmask)) { free(result); free(distid); return NULL; } for (i = 0; i < nelements; i++) distid[i] = i; /* To remember which row/column in the distance matrix contains what */ /* Storage for node data */ if (transpose) { for (i = 0; i < nelements; i++) { for (j = 0; j < ndata; j++) { newdata[i][j] = data[j][i]; newmask[i][j] = mask[j][i]; } } data = newdata; mask = newmask; } else { for (i = 0; i < nelements; i++) { memcpy(newdata[i], data[i], ndata*sizeof(double)); memcpy(newmask[i], mask[i], ndata*sizeof(int)); } data = newdata; mask = newmask; } for (inode = 0; inode < nnodes; inode++) { /* Find the pair with the shortest distance */ int is = 1; int js = 0; result[inode].distance = find_closest_pair(nelements-inode, distmatrix, &is, &js); result[inode].left = distid[js]; result[inode].right = distid[is]; /* Make node js the new node */ for (i = 0; i < ndata; i++) { data[js][i] = data[js][i]*mask[js][i] + data[is][i]*mask[is][i]; mask[js][i] += mask[is][i]; if (mask[js][i]) data[js][i] /= mask[js][i]; } free(data[is]); free(mask[is]); data[is] = data[nnodes-inode]; mask[is] = mask[nnodes-inode]; /* Fix the distances */ distid[is] = distid[nnodes-inode]; for (i = 0; i < is; i++) distmatrix[is][i] = distmatrix[nnodes-inode][i]; for (i = is + 1; i < nnodes-inode; i++) distmatrix[i][is] = distmatrix[nnodes-inode][i]; distid[js] = -inode-1; for (i = 0; i < js; i++) distmatrix[js][i] = metric(ndata,data,data,mask,mask,weight,js,i,0); for (i = js + 1; i < nnodes-inode; i++) distmatrix[i][js] = metric(ndata,data,data,mask,mask,weight,js,i,0); } /* Free temporarily allocated space */ free(data[0]); free(mask[0]); free(data); free(mask); free(distid); return result; } /* ******************************************************************** */ static int nodecompare(const void* a, const void* b) /* Helper function for qsort. */ { const Node* node1 = (const Node*)a; const Node* node2 = (const Node*)b; const double term1 = node1->distance; const double term2 = node2->distance; if (term1 < term2) return -1; if (term1 > term2) return +1; return 0; } /* ---------------------------------------------------------------------- */ static Node* pslcluster (int nrows, int ncolumns, double** data, int** mask, double weight[], double** distmatrix, char dist, int transpose) /* Purpose ======= The pslcluster routine performs single-linkage hierarchical clustering, using either the distance matrix directly, if available, or by calculating the distances from the data array. This implementation is based on the SLINK algorithm, described in: Sibson, R. (1973). SLINK: An optimally efficient algorithm for the single-link cluster method. The Computer Journal, 16(1): 30-34. The output of this algorithm is identical to conventional single-linkage hierarchical clustering, but is much more memory-efficient and faster. Hence, it can be applied to large data sets, for which the conventional single- linkage algorithm fails due to lack of memory. Arguments ========= nrows (input) int The number of rows in the gene expression data matrix, equal to the number of genes. ncolumns (input) int The number of columns in the gene expression data matrix, equal to the number of microarrays. data (input) double[nrows][ncolumns] The array containing the gene expression data. mask (input) int[nrows][ncolumns] This array shows which data values are missing. If mask[i][j] == 0, then data[i][j] is missing. weight (input) double[n] The weights that are used to calculate the distance. The length of this vector is ncolumns if genes are being clustered, and nrows if microarrays are being clustered. transpose (input) int If transpose==0, the rows of the matrix are clustered. Otherwise, columns of the matrix are clustered. dist (input) char Defines which distance measure is used, as given by the table: dist=='e': Euclidean distance dist=='b': City-block distance dist=='c': correlation dist=='a': absolute value of the correlation dist=='u': uncentered correlation dist=='x': absolute uncentered correlation dist=='s': Spearman's rank correlation dist=='k': Kendall's tau For other values of dist, the default (Euclidean distance) is used. distmatrix (input) double** The distance matrix. If the distance matrix is passed by the calling routine treecluster, it is used by pslcluster to speed up the clustering calculation. The pslcluster routine does not modify the contents of distmatrix, and does not deallocate it. If distmatrix is NULL, the pairwise distances are calculated by the pslcluster routine from the gene expression data (the data and mask arrays) and stored in temporary arrays. If distmatrix is passed, the original gene expression data (specified by the data and mask arguments) are not needed and are therefore ignored. Return value ============ A pointer to a newly allocated array of Node structs, describing the hierarchical clustering solution consisting of nelements-1 nodes. Depending on whether genes (rows) or microarrays (columns) were clustered, nelements is equal to nrows or ncolumns. See src/cluster.h for a description of the Node structure. If a memory error occurs, pslcluster returns NULL. ======================================================================== */ { int i, j, k; const int nelements = transpose ? ncolumns : nrows; const int nnodes = nelements - 1; int* vector; double* temp; int* index; Node* result; temp = malloc(nnodes*sizeof(double)); if(!temp) return NULL; index = malloc(nelements*sizeof(int)); if(!index) { free(temp); return NULL; } vector = malloc(nnodes*sizeof(int)); if(!vector) { free(index); free(temp); return NULL; } result = malloc(nelements*sizeof(Node)); if(!result) { free(vector); free(index); free(temp); return NULL; } for (i = 0; i < nnodes; i++) vector[i] = i; if(distmatrix) { for (i = 0; i < nrows; i++) { result[i].distance = DBL_MAX; for (j = 0; j < i; j++) temp[j] = distmatrix[i][j]; for (j = 0; j < i; j++) { k = vector[j]; if (result[j].distance >= temp[j]) { if (result[j].distance < temp[k]) temp[k] = result[j].distance; result[j].distance = temp[j]; vector[j] = i; } else if (temp[j] < temp[k]) temp[k] = temp[j]; } for (j = 0; j < i; j++) { if (result[j].distance >= result[vector[j]].distance) vector[j] = i; } } } else { const int ndata = transpose ? nrows : ncolumns; /* Set the metric function as indicated by dist */ double (*metric) (int, double**, double**, int**, int**, const double[], int, int, int) = setmetric(dist); for (i = 0; i < nelements; i++) { result[i].distance = DBL_MAX; for (j = 0; j < i; j++) temp[j] = metric(ndata, data, data, mask, mask, weight, i, j, transpose); for (j = 0; j < i; j++) { k = vector[j]; if (result[j].distance >= temp[j]) { if (result[j].distance < temp[k]) temp[k] = result[j].distance; result[j].distance = temp[j]; vector[j] = i; } else if (temp[j] < temp[k]) temp[k] = temp[j]; } for (j = 0; j < i; j++) if (result[j].distance >= result[vector[j]].distance) vector[j] = i; } } free(temp); for (i = 0; i < nnodes; i++) result[i].left = i; qsort(result, nnodes, sizeof(Node), nodecompare); for (i = 0; i < nelements; i++) index[i] = i; for (i = 0; i < nnodes; i++) { j = result[i].left; k = vector[j]; result[i].left = index[j]; result[i].right = index[k]; index[k] = -i-1; } free(vector); free(index); result = realloc(result, nnodes*sizeof(Node)); return result; } /* ******************************************************************** */ static Node* pmlcluster (int nelements, double** distmatrix) /* Purpose ======= The pmlcluster routine performs clustering using pairwise maximum- (complete-) linking on the given distance matrix. Arguments ========= nelements (input) int The number of elements to be clustered. distmatrix (input) double** The distance matrix, with nelements rows, each row being filled up to the diagonal. The elements on the diagonal are not used, as they are assumed to be zero. The distance matrix will be modified by this routine. Return value ============ A pointer to a newly allocated array of Node structs, describing the hierarchical clustering solution consisting of nelements-1 nodes. Depending on whether genes (rows) or microarrays (columns) were clustered, nelements is equal to nrows or ncolumns. See src/cluster.h for a description of the Node structure. If a memory error occurs, pmlcluster returns NULL. ======================================================================== */ { int j; int n; int* clusterid; Node* result; clusterid = malloc(nelements*sizeof(int)); if(!clusterid) return NULL; result = malloc((nelements-1)*sizeof(Node)); if (!result) { free(clusterid); return NULL; } /* Setup a list specifying to which cluster a gene belongs */ for (j = 0; j < nelements; j++) clusterid[j] = j; for (n = nelements; n > 1; n--) { int is = 1; int js = 0; result[nelements-n].distance = find_closest_pair(n, distmatrix, &is, &js); /* Fix the distances */ for (j = 0; j < js; j++) distmatrix[js][j] = max(distmatrix[is][j],distmatrix[js][j]); for (j = js+1; j < is; j++) distmatrix[j][js] = max(distmatrix[is][j],distmatrix[j][js]); for (j = is+1; j < n; j++) distmatrix[j][js] = max(distmatrix[j][is],distmatrix[j][js]); for (j = 0; j < is; j++) distmatrix[is][j] = distmatrix[n-1][j]; for (j = is+1; j < n-1; j++) distmatrix[j][is] = distmatrix[n-1][j]; /* Update clusterids */ result[nelements-n].left = clusterid[is]; result[nelements-n].right = clusterid[js]; clusterid[js] = n-nelements-1; clusterid[is] = clusterid[n-1]; } free(clusterid); return result; } /* ******************************************************************* */ static Node* palcluster (int nelements, double** distmatrix) /* Purpose ======= The palcluster routine performs clustering using pairwise average linking on the given distance matrix. Arguments ========= nelements (input) int The number of elements to be clustered. distmatrix (input) double** The distance matrix, with nelements rows, each row being filled up to the diagonal. The elements on the diagonal are not used, as they are assumed to be zero. The distance matrix will be modified by this routine. Return value ============ A pointer to a newly allocated array of Node structs, describing the hierarchical clustering solution consisting of nelements-1 nodes. Depending on whether genes (rows) or microarrays (columns) were clustered, nelements is equal to nrows or ncolumns. See src/cluster.h for a description of the Node structure. If a memory error occurs, palcluster returns NULL. ======================================================================== */ { int j; int n; int* clusterid; int* number; Node* result; clusterid = malloc(nelements*sizeof(int)); if(!clusterid) return NULL; number = malloc(nelements*sizeof(int)); if(!number) { free(clusterid); return NULL; } result = malloc((nelements-1)*sizeof(Node)); if (!result) { free(clusterid); free(number); return NULL; } /* Setup a list specifying to which cluster a gene belongs, and keep track * of the number of elements in each cluster (needed to calculate the * average). */ for (j = 0; j < nelements; j++) { number[j] = 1; clusterid[j] = j; } for (n = nelements; n > 1; n--) { int sum; int is = 1; int js = 0; result[nelements-n].distance = find_closest_pair(n, distmatrix, &is, &js); /* Save result */ result[nelements-n].left = clusterid[is]; result[nelements-n].right = clusterid[js]; /* Fix the distances */ sum = number[is] + number[js]; for (j = 0; j < js; j++) { distmatrix[js][j] = distmatrix[is][j]*number[is] + distmatrix[js][j]*number[js]; distmatrix[js][j] /= sum; } for (j = js+1; j < is; j++) { distmatrix[j][js] = distmatrix[is][j]*number[is] + distmatrix[j][js]*number[js]; distmatrix[j][js] /= sum; } for (j = is+1; j < n; j++) { distmatrix[j][js] = distmatrix[j][is]*number[is] + distmatrix[j][js]*number[js]; distmatrix[j][js] /= sum; } for (j = 0; j < is; j++) distmatrix[is][j] = distmatrix[n-1][j]; for (j = is+1; j < n-1; j++) distmatrix[j][is] = distmatrix[n-1][j]; /* Update number of elements in the clusters */ number[js] = sum; number[is] = number[n-1]; /* Update clusterids */ clusterid[js] = n-nelements-1; clusterid[is] = clusterid[n-1]; } free(clusterid); free(number); return result; } /* ******************************************************************* */ Node* treecluster (int nrows, int ncolumns, double** data, int** mask, double weight[], int transpose, char dist, char method, double** distmatrix) /* Purpose ======= The treecluster routine performs hierarchical clustering using pairwise single-, maximum-, centroid-, or average-linkage, as defined by method, on a given set of gene expression data, using the distance metric given by dist. If successful, the function returns a pointer to a newly allocated Tree struct containing the hierarchical clustering solution, and NULL if a memory error occurs. The pointer should be freed by the calling routine to prevent memory leaks. Arguments ========= nrows (input) int The number of rows in the data matrix, equal to the number of genes. ncolumns (input) int The number of columns in the data matrix, equal to the number of microarrays. data (input) double[nrows][ncolumns] The array containing the data of the vectors to be clustered. mask (input) int[nrows][ncolumns] This array shows which data values are missing. If mask[i][j]==0, then data[i][j] is missing. weight (input) double array[n] The weights that are used to calculate the distance. transpose (input) int If transpose==0, the rows of the matrix are clustered. Otherwise, columns of the matrix are clustered. dist (input) char Defines which distance measure is used, as given by the table: dist=='e': Euclidean distance dist=='b': City-block distance dist=='c': correlation dist=='a': absolute value of the correlation dist=='u': uncentered correlation dist=='x': absolute uncentered correlation dist=='s': Spearman's rank correlation dist=='k': Kendall's tau For other values of dist, the default (Euclidean distance) is used. method (input) char Defines which hierarchical clustering method is used: method=='s': pairwise single-linkage clustering method=='m': pairwise maximum- (or complete-) linkage clustering method=='a': pairwise average-linkage clustering method=='c': pairwise centroid-linkage clustering For the first three, either the distance matrix or the gene expression data is sufficient to perform the clustering algorithm. For pairwise centroid-linkage clustering, however, the gene expression data are always needed, even if the distance matrix itself is available. distmatrix (input) double** The distance matrix. If the distance matrix is zero initially, the distance matrix will be allocated and calculated from the data by treecluster, and deallocated before treecluster returns. If the distance matrix is passed by the calling routine, treecluster will modify the contents of the distance matrix as part of the clustering algorithm, but will not deallocate it. The calling routine should deallocate the distance matrix after the return from treecluster. Return value ============ A pointer to a newly allocated array of Node structs, describing the hierarchical clustering solution consisting of nelements-1 nodes. Depending on whether genes (rows) or microarrays (columns) were clustered, nelements is equal to nrows or ncolumns. See src/cluster.h for a description of the Node structure. If a memory error occurs, treecluster returns NULL. ======================================================================== */ { Node* result = NULL; const int nelements = (transpose==0) ? nrows : ncolumns; const int ldistmatrix = (distmatrix==NULL && method!='s') ? 1 : 0; if (nelements < 2) return NULL; /* Calculate the distance matrix if the user didn't give it */ if(ldistmatrix) { distmatrix = distancematrix(nrows, ncolumns, data, mask, weight, dist, transpose); if (!distmatrix) return NULL; /* Insufficient memory */ } switch(method) { case 's': result = pslcluster(nrows, ncolumns, data, mask, weight, distmatrix, dist, transpose); break; case 'm': result = pmlcluster(nelements, distmatrix); break; case 'a': result = palcluster(nelements, distmatrix); break; case 'c': result = pclcluster(nrows, ncolumns, data, mask, weight, distmatrix, dist, transpose); break; } /* Deallocate space for distance matrix, if it was allocated by treecluster */ if(ldistmatrix) { int i; for (i = 1; i < nelements; i++) free(distmatrix[i]); free (distmatrix); } return result; } /* ******************************************************************* */ static void somworker (int nrows, int ncolumns, double** data, int** mask, const double weights[], int transpose, int nxgrid, int nygrid, double inittau, double*** celldata, int niter, char dist) { const int nelements = (transpose==0) ? nrows : ncolumns; const int ndata = (transpose==0) ? ncolumns : nrows; int i, j; double* stddata = calloc(nelements,sizeof(double)); int** dummymask; int ix, iy; int* index; int iter; /* Maximum radius in which nodes are adjusted */ double maxradius = sqrt(nxgrid*nxgrid+nygrid*nygrid); /* Set the metric function as indicated by dist */ double (*metric) (int, double**, double**, int**, int**, const double[], int, int, int) = setmetric(dist); /* Calculate the standard deviation for each row or column */ if (transpose==0) { for (i = 0; i < nelements; i++) { int n = 0; for (j = 0; j < ndata; j++) { if (mask[i][j]) { double term = data[i][j]; term = term * term; stddata[i] += term; n++; } } if (stddata[i] > 0) stddata[i] = sqrt(stddata[i]/n); else stddata[i] = 1; } } else { for (i = 0; i < nelements; i++) { int n = 0; for (j = 0; j < ndata; j++) { if (mask[j][i]) { double term = data[j][i]; term = term * term; stddata[i] += term; n++; } } if (stddata[i] > 0) stddata[i] = sqrt(stddata[i]/n); else stddata[i] = 1; } } if (transpose==0) { dummymask = malloc(nygrid*sizeof(int*)); for (i = 0; i < nygrid; i++) { dummymask[i] = malloc(ndata*sizeof(int)); for (j = 0; j < ndata; j++) dummymask[i][j] = 1; } } else { dummymask = malloc(ndata*sizeof(int*)); for (i = 0; i < ndata; i++) { dummymask[i] = malloc(sizeof(int)); dummymask[i][0] = 1; } } /* Randomly initialize the nodes */ for (ix = 0; ix < nxgrid; ix++) { for (iy = 0; iy < nygrid; iy++) { double sum = 0.; for (i = 0; i < ndata; i++) { double term = -1.0 + 2.0*uniform(); celldata[ix][iy][i] = term; sum += term * term; } sum = sqrt(sum/ndata); for (i = 0; i < ndata; i++) celldata[ix][iy][i] /= sum; } } /* Randomize the order in which genes or arrays will be used */ index = malloc(nelements*sizeof(int)); for (i = 0; i < nelements; i++) index[i] = i; for (i = 0; i < nelements; i++) { j = (int) (i + (nelements-i)*uniform()); ix = index[j]; index[j] = index[i]; index[i] = ix; } /* Start the iteration */ for (iter = 0; iter < niter; iter++) { int ixbest = 0; int iybest = 0; int iobject = iter % nelements; iobject = index[iobject]; if (transpose==0) { double closest = metric(ndata,data,celldata[ixbest], mask,dummymask,weights,iobject,iybest,transpose); double radius = maxradius * (1. - ((double)iter)/((double)niter)); double tau = inittau * (1. - ((double)iter)/((double)niter)); for (ix = 0; ix < nxgrid; ix++) { for (iy = 0; iy < nygrid; iy++) { double distance = metric (ndata,data,celldata[ix], mask,dummymask,weights,iobject,iy,transpose); if (distance < closest) { ixbest = ix; iybest = iy; closest = distance; } } } for (ix = 0; ix < nxgrid; ix++) { for (iy = 0; iy < nygrid; iy++) { if (sqrt((ix-ixbest)*(ix-ixbest)+(iy-iybest)*(iy-iybest))0) { sum = sqrt(sum/ndata); for (i = 0; i < ndata; i++) celldata[ix][iy][i] /= sum; } } } } } else { double closest; double** celldatavector = malloc(ndata*sizeof(double*)); double radius = maxradius * (1. - ((double)iter)/((double)niter)); double tau = inittau * (1. - ((double)iter)/((double)niter)); for (i = 0; i < ndata; i++) celldatavector[i] = &(celldata[ixbest][iybest][i]); closest = metric(ndata,data,celldatavector, mask,dummymask,weights,iobject,0,transpose); for (ix = 0; ix < nxgrid; ix++) { for (iy = 0; iy < nygrid; iy++) { double distance; for (i = 0; i < ndata; i++) celldatavector[i] = &(celldata[ixbest][iybest][i]); distance = metric (ndata,data,celldatavector, mask,dummymask,weights,iobject,0,transpose); if (distance < closest) { ixbest = ix; iybest = iy; closest = distance; } } } free(celldatavector); for (ix = 0; ix < nxgrid; ix++) { for (iy = 0; iy < nygrid; iy++) { if (sqrt((ix-ixbest)*(ix-ixbest)+(iy-iybest)*(iy-iybest))0) { sum = sqrt(sum/ndata); for (i = 0; i < ndata; i++) celldata[ix][iy][i] /= sum; } } } } } } if (transpose==0) for (i = 0; i < nygrid; i++) free(dummymask[i]); else for (i = 0; i < ndata; i++) free(dummymask[i]); free(dummymask); free(stddata); free(index); return; } /* ******************************************************************* */ static void somassign (int nrows, int ncolumns, double** data, int** mask, const double weights[], int transpose, int nxgrid, int nygrid, double*** celldata, char dist, int clusterid[][2]) /* Collect clusterids */ { const int ndata = (transpose==0) ? ncolumns : nrows; int i,j; /* Set the metric function as indicated by dist */ double (*metric) (int, double**, double**, int**, int**, const double[], int, int, int) = setmetric(dist); if (transpose==0) { int** dummymask = malloc(nygrid*sizeof(int*)); for (i = 0; i < nygrid; i++) { dummymask[i] = malloc(ncolumns*sizeof(int)); for (j = 0; j < ncolumns; j++) dummymask[i][j] = 1; } for (i = 0; i < nrows; i++) { int ixbest = 0; int iybest = 0; double closest = metric(ndata,data,celldata[ixbest], mask,dummymask,weights,i,iybest,transpose); int ix, iy; for (ix = 0; ix < nxgrid; ix++) { for (iy = 0; iy < nygrid; iy++) { double distance = metric (ndata,data,celldata[ix], mask,dummymask,weights,i,iy,transpose); if (distance < closest) { ixbest = ix; iybest = iy; closest = distance; } } } clusterid[i][0] = ixbest; clusterid[i][1] = iybest; } for (i = 0; i < nygrid; i++) free(dummymask[i]); free(dummymask); } else { double** celldatavector = malloc(ndata*sizeof(double*)); int** dummymask = malloc(nrows*sizeof(int*)); int ixbest = 0; int iybest = 0; for (i = 0; i < nrows; i++) { dummymask[i] = malloc(sizeof(int)); dummymask[i][0] = 1; } for (i = 0; i < ncolumns; i++) { double closest; int ix, iy; for (j = 0; j < ndata; j++) celldatavector[j] = &(celldata[ixbest][iybest][j]); closest = metric(ndata,data,celldatavector, mask,dummymask,weights,i,0,transpose); for (ix = 0; ix < nxgrid; ix++) { for (iy = 0; iy < nygrid; iy++) { double distance; for(j = 0; j < ndata; j++) celldatavector[j] = &(celldata[ix][iy][j]); distance = metric(ndata,data,celldatavector, mask,dummymask,weights,i,0,transpose); if (distance < closest) { ixbest = ix; iybest = iy; closest = distance; } } } clusterid[i][0] = ixbest; clusterid[i][1] = iybest; } free(celldatavector); for (i = 0; i < nrows; i++) free(dummymask[i]); free(dummymask); } return; } /* ******************************************************************* */ void somcluster (int nrows, int ncolumns, double** data, int** mask, const double weight[], int transpose, int nxgrid, int nygrid, double inittau, int niter, char dist, double*** celldata, int clusterid[][2]) /* Purpose ======= The somcluster routine implements a self-organizing map (Kohonen) on a rectangular grid, using a given set of vectors. The distance measure to be used to find the similarity between genes and nodes is given by dist. Arguments ========= nrows (input) int The number of rows in the data matrix, equal to the number of genes. ncolumns (input) int The number of columns in the data matrix, equal to the number of microarrays. data (input) double[nrows][ncolumns] The array containing the gene expression data. mask (input) int[nrows][ncolumns] This array shows which data values are missing. If mask[i][j] == 0, then data[i][j] is missing. weights (input) double[ncolumns] if transpose==0; double[nrows] if transpose==1 The weights that are used to calculate the distance. The length of this vector is ncolumns if genes are being clustered, or nrows if microarrays are being clustered. transpose (input) int If transpose==0, the rows (genes) of the matrix are clustered. Otherwise, columns (microarrays) of the matrix are clustered. nxgrid (input) int The number of grid cells horizontally in the rectangular topology of clusters. nygrid (input) int The number of grid cells horizontally in the rectangular topology of clusters. inittau (input) double The initial value of tau, representing the neighborhood function. niter (input) int The number of iterations to be performed. dist (input) char Defines which distance measure is used, as given by the table: dist=='e': Euclidean distance dist=='b': City-block distance dist=='c': correlation dist=='a': absolute value of the correlation dist=='u': uncentered correlation dist=='x': absolute uncentered correlation dist=='s': Spearman's rank correlation dist=='k': Kendall's tau For other values of dist, the default (Euclidean distance) is used. celldata (output) double[nxgrid][nygrid][ncolumns] if transpose==0; double[nxgrid][nygrid][nrows] if tranpose==1 The gene expression data for each node (cell) in the 2D grid. This can be interpreted as the centroid for the cluster corresponding to that cell. If celldata is NULL, then the centroids are not returned. If celldata is not NULL, enough space should be allocated to store the centroid data before callingsomcluster. clusterid (output), int[nrows][2] if transpose==0; int[ncolumns][2] if transpose==1 For each item (gene or microarray) that is clustered, the coordinates of the cell in the 2D grid to which the item was assigned. If clusterid is NULL, the cluster assignments are not returned. If clusterid is not NULL, enough memory should be allocated to store the clustering information before calling somcluster. ======================================================================== */ { const int nobjects = (transpose==0) ? nrows : ncolumns; const int ndata = (transpose==0) ? ncolumns : nrows; int i,j; const int lcelldata = (celldata==NULL) ? 0 : 1; if (nobjects < 2) return; if (lcelldata==0) { celldata = malloc(nxgrid*nygrid*ndata*sizeof(double**)); for (i = 0; i < nxgrid; i++) { celldata[i] = malloc(nygrid*ndata*sizeof(double*)); for (j = 0; j < nygrid; j++) celldata[i][j] = malloc(ndata*sizeof(double)); } } somworker (nrows, ncolumns, data, mask, weight, transpose, nxgrid, nygrid, inittau, celldata, niter, dist); if (clusterid) somassign (nrows, ncolumns, data, mask, weight, transpose, nxgrid, nygrid, celldata, dist, clusterid); if(lcelldata==0) { for (i = 0; i < nxgrid; i++) for (j = 0; j < nygrid; j++) free(celldata[i][j]); for (i = 0; i < nxgrid; i++) free(celldata[i]); free(celldata); } return; } /* ******************************************************************** */ double clusterdistance (int nrows, int ncolumns, double** data, int** mask, double weight[], int n1, int n2, int index1[], int index2[], char dist, char method, int transpose) /* Purpose ======= The clusterdistance routine calculates the distance between two clusters containing genes or microarrays using the measured gene expression vectors. The distance between clusters, given the genes/microarrays in each cluster, can be defined in several ways. Several distance measures can be used. The routine returns the distance in double precision. If the parameter transpose is set to a nonzero value, the clusters are interpreted as clusters of microarrays, otherwise as clusters of gene. Arguments ========= nrows (input) int The number of rows (i.e., the number of genes) in the gene expression data matrix. ncolumns (input) int The number of columns (i.e., the number of microarrays) in the gene expression data matrix. data (input) double[nrows][ncolumns] The array containing the data of the vectors. mask (input) int[nrows][ncolumns] This array shows which data values are missing. If mask[i][j]==0, then data[i][j] is missing. weight (input) double[ncolumns] if transpose==0; double[nrows] if transpose==1 The weights that are used to calculate the distance. n1 (input) int The number of elements in the first cluster. n2 (input) int The number of elements in the second cluster. index1 (input) int[n1] Identifies which genes/microarrays belong to the first cluster. index2 (input) int[n2] Identifies which genes/microarrays belong to the second cluster. dist (input) char Defines which distance measure is used, as given by the table: dist=='e': Euclidean distance dist=='b': City-block distance dist=='c': correlation dist=='a': absolute value of the correlation dist=='u': uncentered correlation dist=='x': absolute uncentered correlation dist=='s': Spearman's rank correlation dist=='k': Kendall's tau For other values of dist, the default (Euclidean distance) is used. method (input) char Defines how the distance between two clusters is defined, given which genes belong to which cluster: method=='a': the distance between the arithmetic means of the two clusters method=='m': the distance between the medians of the two clusters method=='s': the smallest pairwise distance between members of the two clusters method=='x': the largest pairwise distance between members of the two clusters method=='v': average of the pairwise distances between members of the clusters transpose (input) int If transpose is equal to zero, the distances between the rows is calculated. Otherwise, the distances between the columns is calculated. The former is needed when genes are being clustered; the latter is used when microarrays are being clustered. ======================================================================== */ { /* Set the metric function as indicated by dist */ double (*metric) (int, double**, double**, int**, int**, const double[], int, int, int) = setmetric(dist); /* if one or both clusters are empty, return */ if (n1 < 1 || n2 < 1) return -1.0; /* Check the indices */ if (transpose==0) { int i; for (i = 0; i < n1; i++) { int index = index1[i]; if (index < 0 || index >= nrows) return -1.0; } for (i = 0; i < n2; i++) { int index = index2[i]; if (index < 0 || index >= nrows) return -1.0; } } else { int i; for (i = 0; i < n1; i++) { int index = index1[i]; if (index < 0 || index >= ncolumns) return -1.0; } for (i = 0; i < n2; i++) { int index = index2[i]; if (index < 0 || index >= ncolumns) return -1.0; } } switch (method) { case 'a': { /* Find the center */ int i,j,k; if (transpose==0) { double distance; double* cdata[2]; int* cmask[2]; int* count[2]; count[0] = calloc(ncolumns,sizeof(int)); count[1] = calloc(ncolumns,sizeof(int)); cdata[0] = calloc(ncolumns,sizeof(double)); cdata[1] = calloc(ncolumns,sizeof(double)); cmask[0] = malloc(ncolumns*sizeof(int)); cmask[1] = malloc(ncolumns*sizeof(int)); for (i = 0; i < n1; i++) { k = index1[i]; for (j = 0; j < ncolumns; j++) if (mask[k][j] != 0) { cdata[0][j] = cdata[0][j] + data[k][j]; count[0][j] = count[0][j] + 1; } } for (i = 0; i < n2; i++) { k = index2[i]; for (j = 0; j < ncolumns; j++) if (mask[k][j] != 0) { cdata[1][j] = cdata[1][j] + data[k][j]; count[1][j] = count[1][j] + 1; } } for (i = 0; i < 2; i++) for (j = 0; j < ncolumns; j++) { if (count[i][j]>0) { cdata[i][j] = cdata[i][j] / count[i][j]; cmask[i][j] = 1; } else cmask[i][j] = 0; } distance = metric (ncolumns,cdata,cdata,cmask,cmask,weight,0,1,0); for (i = 0; i < 2; i++) { free (cdata[i]); free (cmask[i]); free (count[i]); } return distance; } else { double distance; int** count = malloc(nrows*sizeof(int*)); double** cdata = malloc(nrows*sizeof(double*)); int** cmask = malloc(nrows*sizeof(int*)); for (i = 0; i < nrows; i++) { count[i] = calloc(2,sizeof(int)); cdata[i] = calloc(2,sizeof(double)); cmask[i] = malloc(2*sizeof(int)); } for (i = 0; i < n1; i++) { k = index1[i]; for (j = 0; j < nrows; j++) { if (mask[j][k] != 0) { cdata[j][0] = cdata[j][0] + data[j][k]; count[j][0] = count[j][0] + 1; } } } for (i = 0; i < n2; i++) { k = index2[i]; for (j = 0; j < nrows; j++) { if (mask[j][k] != 0) { cdata[j][1] = cdata[j][1] + data[j][k]; count[j][1] = count[j][1] + 1; } } } for (i = 0; i < nrows; i++) for (j = 0; j < 2; j++) if (count[i][j]>0) { cdata[i][j] = cdata[i][j] / count[i][j]; cmask[i][j] = 1; } else cmask[i][j] = 0; distance = metric (nrows,cdata,cdata,cmask,cmask,weight,0,1,1); for (i = 0; i < nrows; i++) { free (count[i]); free (cdata[i]); free (cmask[i]); } free (count); free (cdata); free (cmask); return distance; } } case 'm': { int i, j, k; if (transpose==0) { double distance; double* temp = malloc(nrows*sizeof(double)); double* cdata[2]; int* cmask[2]; for (i = 0; i < 2; i++) { cdata[i] = malloc(ncolumns*sizeof(double)); cmask[i] = malloc(ncolumns*sizeof(int)); } for (j = 0; j < ncolumns; j++) { int count = 0; for (k = 0; k < n1; k++) { i = index1[k]; if (mask[i][j]) { temp[count] = data[i][j]; count++; } } if (count>0) { cdata[0][j] = median (count,temp); cmask[0][j] = 1; } else { cdata[0][j] = 0.; cmask[0][j] = 0; } } for (j = 0; j < ncolumns; j++) { int count = 0; for (k = 0; k < n2; k++) { i = index2[k]; if (mask[i][j]) { temp[count] = data[i][j]; count++; } } if (count>0) { cdata[1][j] = median (count,temp); cmask[1][j] = 1; } else { cdata[1][j] = 0.; cmask[1][j] = 0; } } distance = metric (ncolumns,cdata,cdata,cmask,cmask,weight,0,1,0); for (i = 0; i < 2; i++) { free (cdata[i]); free (cmask[i]); } free(temp); return distance; } else { double distance; double* temp = malloc(ncolumns*sizeof(double)); double** cdata = malloc(nrows*sizeof(double*)); int** cmask = malloc(nrows*sizeof(int*)); for (i = 0; i < nrows; i++) { cdata[i] = malloc(2*sizeof(double)); cmask[i] = malloc(2*sizeof(int)); } for (j = 0; j < nrows; j++) { int count = 0; for (k = 0; k < n1; k++) { i = index1[k]; if (mask[j][i]) { temp[count] = data[j][i]; count++; } } if (count>0) { cdata[j][0] = median (count,temp); cmask[j][0] = 1; } else { cdata[j][0] = 0.; cmask[j][0] = 0; } } for (j = 0; j < nrows; j++) { int count = 0; for (k = 0; k < n2; k++) { i = index2[k]; if (mask[j][i]) { temp[count] = data[j][i]; count++; } } if (count>0) { cdata[j][1] = median (count,temp); cmask[j][1] = 1; } else { cdata[j][1] = 0.; cmask[j][1] = 0; } } distance = metric (nrows,cdata,cdata,cmask,cmask,weight,0,1,1); for (i = 0; i < nrows; i++) { free (cdata[i]); free (cmask[i]); } free(cdata); free(cmask); free(temp); return distance; } } case 's': { int i1, i2, j1, j2; const int n = (transpose==0) ? ncolumns : nrows; double mindistance = DBL_MAX; for (i1 = 0; i1 < n1; i1++) for (i2 = 0; i2 < n2; i2++) { double distance; j1 = index1[i1]; j2 = index2[i2]; distance = metric (n,data,data,mask,mask,weight,j1,j2,transpose); if (distance < mindistance) mindistance = distance; } return mindistance; } case 'x': { int i1, i2, j1, j2; const int n = (transpose==0) ? ncolumns : nrows; double maxdistance = 0; for (i1 = 0; i1 < n1; i1++) for (i2 = 0; i2 < n2; i2++) { double distance; j1 = index1[i1]; j2 = index2[i2]; distance = metric (n,data,data,mask,mask,weight,j1,j2,transpose); if (distance > maxdistance) maxdistance = distance; } return maxdistance; } case 'v': { int i1, i2, j1, j2; const int n = (transpose==0) ? ncolumns : nrows; double distance = 0; for (i1 = 0; i1 < n1; i1++) for (i2 = 0; i2 < n2; i2++) { j1 = index1[i1]; j2 = index2[i2]; distance += metric (n,data,data,mask,mask,weight,j1,j2,transpose); } distance /= (n1*n2); return distance; } } /* Never get here */ return -2.0; } cluster-1.52a/src/command.c0000644000100500010050000006020212174711007015462 0ustar mdehoonmdehoon/* Software and source code Copyright (C) 1998-2000 Stanford University Written by Michael Eisen (eisen@genome.stanford.edu) This software is copyright under the following conditions: Permission to use, copy, and modify this software and its documentation is hereby granted to all academic and not-for-profit institutions without fee, provided that the above copyright notice and this permission notice appear in all copies of the software and related documentation. Permission to distribute the software or modified or extended versions thereof on a not-for-profit basis is explicitly granted, under the above conditions. However, the right to use this software in conjunction with for profit activities, and the right to distribute the software or modified or extended versions thereof for profit are *NOT* granted except by prior arrangement and written consent of the copyright holders. Use of this source code constitutes an agreement not to criticize, in any way, the code-writing style of the author, including any statements regarding the extent of documentation and comments present. The software is provided "AS-IS" and without warranty of ank kind, express, implied or otherwise, including without limitation, any warranty of merchantability or fitness for a particular purpose. In no event shall Stanford University or the authors be liable for any special, incudental, indirect or consequential damages of any kind, or any damages whatsoever resulting from loss of use, data or profits, whether or not advised of the possibility of damage, and on any theory of liability, arising out of or in connection with the use or performance of this software. This code was written using Borland C++ Builder 4 (Inprise Inc., www.inprise.com) and may be subject to certain additional restrictions as a result. */ /* This program was modified by Michiel de Hoon of the University of Tokyo, Human Genome Center (mdehoon 'AT' gsc.riken.jp). The core numerical routines are now located in the C Clustering Library. This file implements a command-line interface to the clustering routines in the C Clustering Library. MdH 2003.07.17. */ /*============================================================================*/ /* Header files */ /*============================================================================*/ /* Standard C header files */ #include #include #include #include /* Local header files */ #include "data.h" /* Includes data handling and file reading/writing */ /* The routines in the C Clustering Library are called */ /* from data.c. */ #include "cluster.h" /* Contains the version number of the C Clustering */ /* Library. */ #include "command.h" /* Contains the declaration of commandmain */ /*============================================================================*/ /* Utility routines */ /*============================================================================*/ static int load(const char filename[]) { char* result; struct stat filestat; FILE* inputfile; if (stat(filename, &filestat) || S_ISDIR(filestat.st_mode) || !(inputfile = fopen(filename, "rt")) ) { printf("Error opening file %s\n", filename); return 0; } result = Load(inputfile); fclose(inputfile); if (result==NULL) { printf("Error reading file %s:\nInsufficient memory\n", filename); return 0; } if (strcmp(result, "ok")==0) return 1; printf("Error reading file %s:\n%s\n", filename, result); free(result); return 0; } static void display_help(void) { printf ("Cluster 3.0, command-line version.\n"); printf ("USAGE: cluster [options]\n"); printf ("options:\n"); printf (" -v, --version Version information\n"); printf (" -f filename File loading\n"); printf (" -l Specifies to log-transform the data before clustering\n" " (default is no log-transform)\n"); printf (" -cg a|m Specifies whether to center each row (gene)\n" " in the data\n" " a: Subtract the mean of each row\n" " m: Subtract the median of each row\n" " (default is no centering)\n"); printf (" -ng Specifies to normalize each row (gene) in the data\n" " (default is no normalization)\n"); printf (" -ca a|m Specifies whether to center each column (microarray)\n" " in the data\n" " a: Subtract the mean of each column\n" " m: Subtract the median of each column\n" " (default is no centering)\n"); printf (" -na Specifies to normalize each column (microarray) in the data\n" " (default is no normalization)\n"); printf (" -u jobname Allows you to specify a different name for the output files\n" " (default is derived from the input file name)\n"); printf (" -g [0..8] Specifies the distance measure for gene clustering\n"); printf (" 0: No gene clustering\n" " 1: Uncentered correlation\n" " 2: Pearson correlation\n" " 3: Uncentered correlation, absolute value\n" " 4: Pearson correlation, absolute value\n" " 5: Spearman's rank correlation\n" " 6: Kendall's tau\n" " 7: Euclidean distance\n" " 8: City-block distance\n" " (default: 0)\n"); printf (" -e [0..8] Specifies the distance measure for microarray clustering\n"); printf (" 0: No clustering\n" " 1: Uncentered correlation\n" " 2: Pearson correlation\n" " 3: Uncentered correlation, absolute value\n" " 4: Pearson correlation, absolute value\n" " 5: Spearman's rank correlation\n" " 6: Kendall's tau\n" " 7: Euclidean distance\n" " 8: City-block distance\n" " (default: 0)\n"); printf (" -m [msca] Specifies which hierarchical clustering method to use\n" " m: Pairwise complete-linkage\n" " s: Pairwise single-linkage\n" " c: Pairwise centroid-linkage\n" " a: Pairwise average-linkage\n" " (default: m)\n"); printf (" -k number Specifies whether to run k-means clustering\n" " instead of hierarchical clustering, and the number\n" " of clusters k to use\n"); printf (" -r number For k-means clustering, the number of times the\n" " k-means clustering algorithm is run\n" " (default: 1)\n"); printf (" -pg Specifies to apply Principal Component Analysis to\n" " genes instead of clustering\n"); printf (" -pa Specifies to apply Principal Component Analysis to\n" " arrays instead of clustering\n"); printf (" -s Specifies to calculate an SOM instead of hierarchical\n" " clustering\n"); printf (" -x number Specifies the horizontal dimension of the SOM grid\n" " (default: 2)\n"); printf (" -y number Specifies the vertical dimension of the SOM grid\n" " (default: 1)\n"); return; } static void display_version(void) { printf ("\n" #ifdef HAVE_GUI "Cluster 3.0, command line and GUI version,\n" #else "Cluster 3.0, command line version (no GUI support),\n" #endif "using the C Clustering Library version " CLUSTERVERSION ".\n" "\n" "Cluster was originally written by Michael Eisen (eisen 'AT' rana.lbl.gov)\n" "Copyright 1998-99 Stanford University.\n"); printf ("\n" "The command line version of Cluster version 3.0 was created by Michiel de Hoon\n" "(mdehoon 'AT' gsc.riken.jp), together with Seiya Imoto and Satoru Miyano,\n" "University of Tokyo, Institute of Medical Science, Human Genome Center.\n" "\n" "Visit our website at http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster\n" "for GUI-versions of Cluster 3.0 for Windows, Mac OS X, Unix, and Linux,\n" "as well as Python and Perl interfaces to the C Clustering Library.\n" "\n"); return; } static char* setjobname(const char* basename, int strip) { char* jobname; int n = strlen(basename); if (strip) { char* extension = strrchr(basename, '.'); if (extension) n -= strlen(extension); } jobname = malloc((n+1)*sizeof(char)); if (!jobname) { printf("ERROR: Failed to allocate memory for job name\n"); return NULL; } strncpy(jobname, basename, n); jobname[n] = '\0'; return jobname; } static int readnumber(const char word[]) { char* error = 0; long value = strtol(word,&error,0); if (*error=='\0') return (int)value; else return -1; } static char getmetric(int i) { switch (i) { case 1: return 'u'; case 2: return 'c'; case 3: return 'x'; case 4: return 'a'; case 5: return 's'; case 6: return 'k'; case 7: return 'e'; case 8: return 'b'; default: return '\0'; } /* Never get here */ return '\0'; } static void Hierarchical(char genemetric, char arraymetric, char method, char* jobname) { int ok; FILE* outputfile; const int n = strlen(jobname) + strlen(".ext") + 1; char* const filename = malloc(n*sizeof(char)); if (!filename) { printf("ERROR: Failed to allocate memory for file name\n"); return; } if (genemetric) { sprintf(filename, "%s.gtr", jobname); outputfile = fopen(filename, "wt"); if (!outputfile) printf ("Failed opening output file %s\n", filename); else { ok = HierarchicalCluster(outputfile, genemetric, 0, method); if (!ok) { printf("ERROR: Failed to allocate sufficient memory for clustering\n"); return; } fclose(outputfile); } } if (arraymetric) { sprintf(filename, "%s.atr", jobname); outputfile = fopen(filename, "wt"); if (!outputfile) printf ("Failed opening output file %s\n", filename); else { ok = HierarchicalCluster(outputfile, arraymetric, 1, method); if (!ok) { printf("ERROR: Failed to allocate sufficient memory for clustering\n"); return; } fclose(outputfile); } } sprintf(filename, "%s.cdt", jobname); outputfile = fopen(filename, "wt"); if (!outputfile) printf ("Failed opening output file %s\n", filename); else { Save(outputfile, genemetric!='\0', arraymetric!='\0'); fclose(outputfile); } free(filename); return; } static void JustSave(char* jobname) { FILE* outputfile; char* filename; int n = 1 + strlen(jobname) + strlen(".ext"); filename = malloc(n*sizeof(char)); if (!filename) { printf("ERROR: Failed to allocate memory for file name\n"); return; } sprintf(filename, "%s.nrm", jobname); outputfile = fopen(filename, "wt"); if (!outputfile) printf("ERROR: Failed to open output file %s\n", filename); else { Save(outputfile, 0, 0); fclose(outputfile); } free(filename); return; } static void KMeans(char genemetric, char arraymetric, int k, int r, int Rows, int Columns, char* jobname) { FILE* outputfile; char* filename; int n = 1 + strlen(jobname) + strlen("_K") + strlen(".ext"); if (genemetric && Rows < k) { printf("ERROR: More clusters than genes available\n"); return; } if (arraymetric && Columns < k) { printf("ERROR: More clusters than microarrays available\n"); return; } if (genemetric) { int dummy = k; do n++; while (dummy/=10); n += strlen("_G"); } if (arraymetric) { int dummy = k; do n++; while (dummy/=10); n += strlen("_A"); } filename = malloc(n*sizeof(char)); if (!filename) { printf("ERROR: Failed to allocate memory for file name\n"); return; } if (genemetric) { const char method = 'a'; sprintf (filename, "%s_K_G%d.kgg", jobname, k); outputfile = fopen(filename, "wt"); if (!outputfile) printf ("Failed to open output file %s\n", filename); else { int* NodeMap = malloc(Rows*sizeof(int)); if (!NodeMap) printf ("ERROR: Memory allocation failure\n"); else { int ok = GeneKCluster(k, r, method, genemetric, NodeMap); if (ok >= 0) ok = SaveGeneKCluster(outputfile, k, NodeMap); fclose(outputfile); free(NodeMap); if (ok < 0) { printf("ERROR: Failed to allocate sufficient memory for clustering\n"); return; } if (ok==0) { printf("ERROR: Failed to allocate sufficient memory for saving file\n"); return; } } } } if (arraymetric) { const char method = 'a'; sprintf (filename, "%s_K_A%d.kag", jobname, k); outputfile = fopen(filename, "wt"); if (!outputfile) printf ("Failed to open output file %s\n", filename); else { int* NodeMap = malloc(Columns*sizeof(int)); if (!NodeMap) printf ("ERROR: Memory allocation failure\n"); else { int ok = ArrayKCluster(k, r, method, arraymetric, NodeMap); if (ok >= 0) ok = SaveArrayKCluster(outputfile, k, NodeMap); fclose(outputfile); free(NodeMap); if (ok < 0) { printf("ERROR: Failed to allocate sufficient memory for clustering\n"); return; } if (ok==0) { printf("ERROR: Failed to allocate sufficient memory for saving file\n"); return; } } } } if (genemetric && arraymetric) sprintf (filename,"%s_K_G%d_A%d.cdt", jobname, k, k); else if (genemetric) sprintf (filename,"%s_K_G%d.cdt", jobname, k); else if (arraymetric) sprintf (filename,"%s_K_A%d.cdt", jobname, k); /* Now write the data file */ outputfile = fopen(filename, "wt"); if (!outputfile) printf ("Failed to open output file %s\n", filename); else { Save(outputfile, 0, 0); fclose(outputfile); } free(filename); return; } static void PCA(char which, const int Rows, const int Columns, const char* jobname) { const char* error; FILE* coordinatefile; FILE* pcfile; const int n = strlen(jobname) + strlen("_pca_array.coords.txt") + 1; char* const filename = malloc(n*sizeof(char)); if (!filename) { printf("ERROR: Failed to allocate memory for file name\n"); return; } if (which=='g') { sprintf(filename, "%s_pca_gene.coords.txt", jobname); coordinatefile = fopen(filename, "wt"); sprintf(filename, "%s_pca_gene.pc.txt", jobname); pcfile = fopen(filename, "wt"); if(!coordinatefile || !pcfile) { printf("Error: Unable to open the output file"); if (coordinatefile) fclose(coordinatefile); if (pcfile) fclose(pcfile); free(filename); return; } error = PerformGenePCA(coordinatefile, pcfile); fclose(coordinatefile); fclose(pcfile); if (error) { puts(error); free(filename); return; } } else if (which=='a') { sprintf(filename, "%s_pca_array.coords.txt", jobname); coordinatefile = fopen(filename, "wt"); sprintf(filename, "%s_pca_array.pc.txt", jobname); pcfile = fopen(filename, "wt"); if(!coordinatefile || !pcfile) { printf("Error: Unable to open the output file"); if (coordinatefile) fclose(coordinatefile); if (pcfile) fclose(pcfile); free(filename); return; } error = PerformArrayPCA(coordinatefile, pcfile); fclose(coordinatefile); fclose(pcfile); if (error) { puts(error); free(filename); return; } } free(filename); } static void SOM(char genemetric, char arraymetric, int x, int y, int Rows, int Columns, char* jobname) { int ok; char* filename; char* extension; FILE* GeneFile = NULL; FILE* ArrayFile = NULL; FILE* DataFile = NULL; int GeneIters; int ArrayIters; const double tau = 0.02; int n = 1 + strlen(jobname) + strlen("_SOM") + strlen(".ext"); /* One for the terminating \0; to be increased below */ if (genemetric) { int dummy = x; do n++; while (dummy/=10); dummy = y; do n++; while (dummy/=10); n+=strlen("_G"); n++; /* For the '-' */ } if (arraymetric) { int dummy = x; do n++; while (dummy/=10); dummy = y; do n++; while (dummy/=10); n+=strlen("_A"); n++; /* For the '-' */ } filename = malloc(n*sizeof(char)); if (!filename) { printf("ERROR: Failed to allocate memory for file name\n"); return; } sprintf(filename, "%s_SOM", jobname); if (genemetric) sprintf(strchr(filename,'\0'),"_G%d-%d",x,y); if (arraymetric) sprintf(strchr(filename,'\0'),"_A%d-%d",x,y); extension = strchr(filename, '\0'); sprintf(extension, ".txt"); DataFile = fopen(filename, "wt"); if (!DataFile) { printf ("Failed to open output file %s", filename); free(filename); return; } if (genemetric) { sprintf(extension, ".gnf"); GeneFile = fopen(filename, "wt"); if (!GeneFile) { printf ("Failed to open output file %s", filename); free(filename); return; } GeneIters = 100000; } else GeneIters = 0; if (arraymetric) { sprintf(extension, ".anf"); ArrayFile = fopen(filename, "wt"); if (!ArrayFile) { printf ("Failed to open output file %s", filename); free(filename); if(GeneFile) free(GeneFile); return; } ArrayIters = 20000; } else ArrayIters = 0; free(filename); ok = PerformSOM(GeneFile, x, y, GeneIters, tau, genemetric, ArrayFile, x, y, ArrayIters, tau, arraymetric); if (GeneFile) fclose(GeneFile); if (ArrayFile) fclose(ArrayFile); if (!ok) printf("Error performing SOM: Insufficient memory\n"); else Save(DataFile, 0, 0); fclose(DataFile); return; } /*============================================================================*/ /* Main */ /*============================================================================*/ int commandmain(int argc, char* argv[]) { int i = 1; const char* filename = 0; char* jobname = 0; int l = 0; int k = 0; int r = 1; int s = 0; int x = 2; int y = 1; int Rows, Columns; char genemetric = '\0'; char arraymetric = '\0'; char method = 'm'; char cg = '\0'; char ca = '\0'; int ng = 0; int na = 0; int pg = 0; int pa = 0; int ok = 1; while (i < argc) { const char* const argument = argv[i]; i++; if (strlen(argument)<2) { printf("ERROR: missing argument\n"); return 0; } if (argument[0]!='-') { printf("ERROR: unknown argument\n"); return 0; } if(!strcmp(argument,"--version") || !strcmp(argument,"-v")) { display_version(); return 0; } if(!strcmp(argument,"--help") || !strcmp(argument,"-h")) { display_help(); return 0; } if(!strcmp(argument,"-cg")) { if (i==argc || strlen(argv[i])>1 || !strchr("am",argv[i][0])) { printf ("Error reading command line argument cg\n"); return 0; } cg = argv[i][0]; i++; continue; } if(!strcmp(argument,"-ca")) { if (i==argc || strlen(argv[i])>1 || !strchr("am",argv[i][0])) { printf ("Error reading command line argument ca\n"); return 0; } ca = argv[i][0]; i++; continue; } if(!strcmp(argument,"-ng")) { ng = 1; continue; } if(!strcmp(argument,"-na")) { na = 1; continue; } if(!strcmp(argument,"-pg")) { pg = 1; continue; } if(!strcmp(argument,"-pa")) { pa = 1; continue; } switch (argument[1]) { case 'l': l=1; break; case 'u': { if (i==argc) { printf ("Error reading command line argument u: no job name specified\n"); return 0; } jobname = argv[i]; i++; break; } case 'f': { if (i==argc) { printf ("Error reading command line argument f: no file name specified\n"); return 0; } filename = argv[i]; i++; break; } case 'g': { int g; if (i==argc) { printf ("Error reading command line argument g: parameter missing\n"); return 0; } g = readnumber(argv[i]); if (g < 0 || g > 9) { printf ("Error reading command line argument g: should be between 0 and 9 inclusive\n"); return 0; } i++; genemetric = getmetric(g); break; } case 'e': { int e; if (i==argc) { printf ("Error reading command line argument e: parameter missing\n"); return 0; } e = readnumber(argv[i]); if (e < 0 || e > 9) { printf ("Error reading command line argument e: should be between 0 and 9 inclusive\n"); return 0; } i++; arraymetric = getmetric(e); break; } case 'm': { if (i==argc || strlen(argv[i])>1 || !strchr("msca",argv[i][0])) { printf ("Error reading command line argument m: should be 'm', 's', 'c', or 'a'\n"); return 0; } method = argv[i][0]; i++; break; } case 's': { s = 1; break; } case 'x': { if (i==argc) { printf ("Error reading command line argument x: parameter missing\n"); return 0; } x = readnumber(argv[i]); if (x < 1) { printf ("Error reading command line argument x: a positive integer is required\n"); return 0; } i++; break; } case 'y': { if (i==argc) { printf ("Error reading command line argument y: parameter missing\n"); return 0; } y = readnumber(argv[i]); if (y < 1) { printf ("Error reading command line argument y: a positive integer is required\n"); return 0; } i++; break; } case 'k': { if (i==argc) { printf ("Error reading command line argument k: parameter missing\n"); return 0; } k = readnumber(argv[i]); if (k < 1) { printf ("Error reading command line argument k: a positive integer is required\n"); return 0; } i++; break; } case 'r': { if (i==argc) { printf ("Error reading command line argument r: parameter missing\n"); return 0; } r = readnumber(argv[i]); if (r < 1) { printf ("Error reading command line argument r: a positive integer is required\n"); return 0; } i++; break; } default: printf ("Unknown option\n"); } } if (filename) { ok = load(filename); if (!ok) return 0; } else { display_help(); return 0; } Rows = GetRows(); Columns = GetColumns(); if (Rows==0 || Columns==0) printf ("No data available\n"); else { if (l) LogTransform(); switch (cg) { case 'a': ok = AdjustGenes (1, 0, ng); break; case 'm': ok = AdjustGenes (0, 1, ng); break; default : ok = AdjustGenes (0, 0, ng); } if (!ok) { printf("Error adjusting genes:\nInsufficient memory\n"); return 0; } switch (ca) { case 'a': ok = AdjustArrays (1, 0, na); break; case 'm': ok = AdjustArrays (0, 1, na); break; default : ok = AdjustArrays (0, 0, na); } if (!ok) { printf("Error adjusting arrays:\nInsufficient memory\n"); return 0; } if(jobname) jobname = setjobname(jobname, 0); else jobname = setjobname(filename, 1); if(jobname) { if(k>0) KMeans(genemetric, arraymetric, k, r, Rows, Columns, jobname); else if (pg==1) PCA('g', Rows, Columns, jobname); else if (pa==1) PCA('a', Rows, Columns, jobname); else if(s!=0) SOM(genemetric, arraymetric, x, y, Rows, Columns, jobname); else if (genemetric!='\0' || arraymetric!='\0') Hierarchical(genemetric, arraymetric, method, jobname); else JustSave(jobname); free(jobname); } } Free(); return 0; } cluster-1.52a/src/main.c0000644000100500010050000000337311070055130014766 0ustar mdehoonmdehoon/* The C clustering library. * Copyright (C) 2002 Michiel Jan Laurens de Hoon. * * This library was written at the Laboratory of DNA Information Analysis, * Human Genome Center, Institute of Medical Science, University of Tokyo, * 4-6-1 Shirokanedai, Minato-ku, Tokyo 108-8639, Japan. * Contact: mdehoon 'AT' gsc.riken.jp * * Permission to use, copy, modify, and distribute this software and its * documentation with or without modifications and for any purpose and * without fee is hereby granted, provided that any copyright notices * appear in all copies and that both those copyright notices and this * permission notice appear in supporting documentation, and that the * names of the contributors or copyright holders not be used in * advertising or publicity pertaining to distribution of the software * without specific prior permission. * * THE CONTRIBUTORS AND COPYRIGHT HOLDERS OF THIS SOFTWARE DISCLAIM ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE * OR PERFORMANCE OF THIS SOFTWARE. * */ /* If the user specified any command-line parameters, we run the command-line * version of Cluster 3.0. If not, we run the GUI version of Cluster 3.0, if * available. */ #include "gui.h" #include "command.h" int main(int argc, char *argv[]) { #ifdef HAVE_GUI if (argc <= 1) return guimain(argc, argv); else #endif return commandmain(argc, argv); } cluster-1.52a/src/Makefile.PL0000644000100500010050000000155711505126757015673 0ustar mdehoonmdehoonuse ExtUtils::MakeMaker; use Config; use POSIX; # Check if this is a 64 bit machine my $CCFLAGS = ''; my $machine = (POSIX::uname())[4]; if ($machine =~ /64/) { $CCFLAGS = '-fPIC'; } WriteMakefile( NAME => 'libcluster', VERSION_FROM => '../perl/Cluster.pm', SKIP => [qw(all static static_lib dynamic dynamic_lib)], C => ['cluster.c'], H => ['cluster.h'], OBJECT => 'cluster.o', MYEXTLIB => 'libcluster$(LIB_EXT)', CCFLAGS => $CCFLAGS, clean => {'FILES' => 'libcluster$(LIBEEXT) $(OBJECT)'}, ); sub MY::top_targets { ' all :: static pure_all :: static static :: $(OBJECT) libcluster$(LIB_EXT) cluster.o : $(CC) -c $(INC) $(DEFINE_VERSION) $(XS_DEFINE_VERSION) $(CCFLAGS) -o cluster.o cluster.c libcluster$(LIB_EXT): $(O_FILES) $(AR) cru libcluster$(LIB_EXT) $(OBJECT) $(RANLIB) libcluster$(LIB_EXT) '; } cluster-1.52a/src/Makefile.in0000644000100500010050000003675712177155022015771 0ustar mdehoonmdehoon# Makefile.in generated by automake 1.12.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = cluster$(EXEEXT) @MOTIF_TRUE@am__append_1 = gui.h subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am__cluster_SOURCES_DIST = main.c command.c command.h data.c data.h \ cluster.c cluster.h gui.h am__objects_1 = am_cluster_OBJECTS = main.$(OBJEXT) command.$(OBJEXT) data.$(OBJEXT) \ cluster.$(OBJEXT) $(am__objects_1) cluster_OBJECTS = $(am_cluster_OBJECTS) cluster_LDADD = $(LDADD) @MOTIF_TRUE@cluster_DEPENDENCIES = ../X11/libgui.a DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(cluster_SOURCES) DIST_SOURCES = $(am__cluster_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ cluster_SOURCES = main.c command.c command.h data.c data.h cluster.c \ cluster.h $(am__append_1) @MOTIF_TRUE@AM_CPPFLAGS = -DHAVE_GUI @MOTIF_TRUE@LDADD = ../X11/libgui.a all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) cluster$(EXEEXT): $(cluster_OBJECTS) $(cluster_DEPENDENCIES) $(EXTRA_cluster_DEPENDENCIES) @rm -f cluster$(EXEEXT) $(LINK) $(cluster_OBJECTS) $(cluster_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cluster.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic cscopelist ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-binPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cluster-1.52a/src/cluster.h0000644000100500010050000000776712414674314015561 0ustar mdehoonmdehoon/******************************************************************************/ /* The C Clustering Library. * Copyright (C) 2002 Michiel Jan Laurens de Hoon. * * This library was written at the Laboratory of DNA Information Analysis, * Human Genome Center, Institute of Medical Science, University of Tokyo, * 4-6-1 Shirokanedai, Minato-ku, Tokyo 108-8639, Japan. * Contact: mdehoon 'AT' gsc.riken.jp * * Permission to use, copy, modify, and distribute this software and its * documentation with or without modifications and for any purpose and * without fee is hereby granted, provided that any copyright notices * appear in all copies and that both those copyright notices and this * permission notice appear in supporting documentation, and that the * names of the contributors or copyright holders not be used in * advertising or publicity pertaining to distribution of the software * without specific prior permission. * * THE CONTRIBUTORS AND COPYRIGHT HOLDERS OF THIS SOFTWARE DISCLAIM ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE * OR PERFORMANCE OF THIS SOFTWARE. * */ #ifndef min #define min(x, y) ((x) < (y) ? (x) : (y)) #endif #ifndef max #define max(x, y) ((x) > (y) ? (x) : (y)) #endif #ifdef WINDOWS # include #endif #define CLUSTERVERSION "1.52a" /* Chapter 2 */ double clusterdistance (int nrows, int ncolumns, double** data, int** mask, double weight[], int n1, int n2, int index1[], int index2[], char dist, char method, int transpose); double** distancematrix (int ngenes, int ndata, double** data, int** mask, double* weight, char dist, int transpose); /* Chapter 3 */ int getclustercentroids(int nclusters, int nrows, int ncolumns, double** data, int** mask, int clusterid[], double** cdata, int** cmask, int transpose, char method); void getclustermedoids(int nclusters, int nelements, double** distance, int clusterid[], int centroids[], double errors[]); void kcluster (int nclusters, int ngenes, int ndata, double** data, int** mask, double weight[], int transpose, int npass, char method, char dist, int clusterid[], double* error, int* ifound); void kmedoids (int nclusters, int nelements, double** distance, int npass, int clusterid[], double* error, int* ifound); /* Chapter 4 */ typedef struct {int left; int right; double distance;} Node; /* * A Node struct describes a single node in a tree created by hierarchical * clustering. The tree can be represented by an array of n Node structs, * where n is the number of elements minus one. The integers left and right * in each Node struct refer to the two elements or subnodes that are joined * in this node. The original elements are numbered 0..nelements-1, and the * nodes -1..-(nelements-1). For each node, distance contains the distance * between the two subnodes that were joined. */ Node* treecluster (int nrows, int ncolumns, double** data, int** mask, double weight[], int transpose, char dist, char method, double** distmatrix); void cuttree (int nelements, Node* tree, int nclusters, int clusterid[]); /* Chapter 5 */ void somcluster (int nrows, int ncolumns, double** data, int** mask, const double weight[], int transpose, int nxnodes, int nynodes, double inittau, int niter, char dist, double*** celldata, int clusterid[][2]); /* Chapter 6 */ int pca(int m, int n, double** u, double** v, double* w); /* Utility routines, currently undocumented */ void sort(int n, const double data[], int index[]); double mean(int n, double x[]); double median (int n, double x[]); double* calculate_weights(int nrows, int ncolumns, double** data, int** mask, double weights[], int transpose, char dist, double cutoff, double exponent); cluster-1.52a/src/gui.h0000644000100500010050000000323310762007121014632 0ustar mdehoonmdehoon/* The C clustering library. * Copyright (C) 2002 Michiel Jan Laurens de Hoon. * * This library was written at the Laboratory of DNA Information Analysis, * Human Genome Center, Institute of Medical Science, University of Tokyo, * 4-6-1 Shirokanedai, Minato-ku, Tokyo 108-8639, Japan. * Contact: mdehoon 'AT' gsc.riken.jp * * Permission to use, copy, modify, and distribute this software and its * documentation with or without modifications and for any purpose and * without fee is hereby granted, provided that any copyright notices * appear in all copies and that both those copyright notices and this * permission notice appear in supporting documentation, and that the * names of the contributors or copyright holders not be used in * advertising or publicity pertaining to distribution of the software * without specific prior permission. * * THE CONTRIBUTORS AND COPYRIGHT HOLDERS OF THIS SOFTWARE DISCLAIM ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE * OR PERFORMANCE OF THIS SOFTWARE. * */ /*============================================================================*/ /* Function declaration */ /*============================================================================*/ int guimain(int argc, char *argv[]); cluster-1.52a/data/0000755000100500010050000000000012177164024014026 5ustar mdehoonmdehooncluster-1.52a/data/cyano.txt0000644000100500010050000001453510322060735015702 0ustar mdehoonmdehoongene 0 15min 1hour 6hours 15hours sll0617 0.0 -0.141164092921 -0.564656371686 -0.219393769051 -0.582969948517 slr0452 0.0 -0.124988599702 -0.499954398807 0.195680498436 0.0781478593432 slr1513 0.0 0.788547158236 0.228594792282 0.255819396258 0.304823683415 sll1471 0.0 -0.770355431265 -1.10115338201 -1.00607440632 -0.834932250086 sll1694 0.0 -0.328239937586 -2.16037133914 -1.184544471 -1.36760041273 sll0430 0.0 2.57611845993 0.920296714116 0.331897478085 0.353984672049 sll0851 0.0 -0.260488607867 -1.04195443147 -0.870951657169 -0.563146663432 sll1260 0.0 0.488375211397 1.03336768086 1.05808458732 1.10257501897 sll1031 0.0 2.22636090218 1.2737708006 1.22441048661 1.13556192142 sll1097 0.0 0.623623937789 1.50986566464 1.39858048748 1.19826716858 slr1853 0.0 -0.625110852947 -0.579158937711 -0.272812836139 0.27861014669 slr1856 0.0 -1.48647925428 -1.15482923751 -0.78849128943 -0.129082982895 sll1807 0.0 -0.00351865963644 1.6220065 1.2103168781 1.40663921545 slr1280 0.0 1.68363550419 0.570482993127 0.452252082077 0.239436442188 sll1578 0.0 -2.08646119875 -4.16618882331 -2.95371220804 -0.771254300567 sll0927 0.0 1.53540350362 0.994485177541 1.06558243705 1.19355750417 sll1028 0.0 2.66231034349 1.02053065748 1.07291269701 1.16720036816 sll0170 0.0 2.49313251019 0.836378625633 -0.181000866758 -0.0686024829202 sll0020 0.0 0.622961311166 0.107769339289 0.00823295222619 -0.170932544487 slr1128 0.0 -0.586091367103 -0.97123113608 -0.33489639532 -0.721672688608 slr1687 0.0 1.53531583449 0.508364720306 0.226540131559 -0.280744128185 slr1986 0.0 -2.46180941179 -3.32064191349 -1.63229875815 -0.376249913875 sll1091 0.0 -2.22018219109 -2.1088225644 -1.36642505311 -0.0301095327889 slr0011 0.0 1.73715425472 0.482870189015 0.589476956697 0.781369138524 sll1816 0.0 0.142823046786 1.37138583483 1.04715754859 1.22776365079 slr1655 0.0 -2.29708296628 -2.79999101137 -2.20032491329 -1.12092593675 slr0839 0.0 0.36757936343 0.316678106928 -0.022663603088 -0.633478681117 sll0262 0.0 0.792040285896 0.692818192651 0.0313375710134 0.309366941681 slr1641 0.0 2.89423066687 0.551559514181 -0.150705464209 -0.21442787406 sll0854 0.0 0.609090206082 0.545338052749 0.120323697197 0.223173714031 slr0151 0.0 -0.989349574879 -0.964206703429 -0.796587560432 -0.494873103037 slr0476 0.0 1.51215261659 0.0821117222648 0.0400809926852 -0.035574320558 sll1614 0.0 0.702656762339 0.0659783997373 0.12124636938 0.220728714738 slr0374 0.0 -0.735627268934 -1.18538074714 -1.38437562074 -1.74256639322 slr0737 0.0 -1.95828768621 -3.25510704118 -2.25413896187 -1.64370116412 slr1718 0.0 0.27148722 0.266555463231 0.233677084773 0.174496003548 slr1604 0.0 2.1572537861 0.725639316761 0.422501046212 -0.123147840775 sll1002 0.0 0.508059527897 0.0824733876347 -0.0882211947902 -0.395471443155 sll0814 0.0 1.8783237838 1.05679078007 0.703832500504 0.0685075972789 sll0521 0.0 1.24736478909 0.245331279252 -0.260997955485 0.203910618354 slr2051 0.0 -2.30444924968 -2.88255028204 -2.19877779485 -0.967987317903 sll1802 0.0 0.654022904601 1.52846049032 1.32249540635 1.58960701188 sll0519 0.0 0.71144846192 0.130603846991 -0.169447274526 0.227932117511 sll1799 0.0 0.772806717851 1.2614816942 1.36702488224 1.55700262072 sll0416 0.0 2.17493062772 1.83773620171 1.00316264737 0.89958779106 slr1459 0.0 -1.84683738354 -1.76706597763 -1.23525660491 -0.277999734026 sll0414 0.0 0.509743056433 0.0513699916594 0.0972244284813 0.179762414761 sll1580 0.0 -2.66568327835 -4.75038508692 -3.05542980829 -1.50909884887 sll1214 0.0 -1.77089540875 -1.69909446506 -1.22042150714 -0.358810182876 sll1096 0.0 1.11463877184 1.76808187333 1.6898020583 1.54889839125 sll1809 0.0 -0.308925470579 1.25214953341 0.755536551289 0.934592129992 slr1793 0.0 -0.188658422905 -0.75463369162 -0.551734332459 -0.652770294667 sll0185 0.0 0.475723926868 1.17385783916 0.25580017747 -0.398252652408 ssl3093 0.0 -1.74156851194 -1.68999525836 -1.34617356779 -0.727294524774 sll1577 0.0 -2.69307453928 -4.01652450572 -2.10165498881 -0.913595745519 sll1801 0.0 0.424986483758 1.69994593503 1.17676212936 1.42075516304 sll1626 0.0 -1.29747066365 -1.42816324407 0.229661068119 0.402910409671 sll0587 0.0 0.101731075535 0.406924302139 0.293220382758 0.0885533278713 sll1745 0.0 -0.481145108669 1.54524431132 1.08885362403 1.32807145143 slr1557 0.0 -0.233123792905 0.38207343775 0.251423195029 0.0162527581309 sll0144 0.0 0.126487813486 0.505951253942 0.577427967822 0.706086052805 ssr2554 0.0 0.13615218811 0.544608752441 0.510697496813 0.449657236683 ssl1533 0.0 -0.976223092984 -1.79120966623 -1.50978457116 -1.00321940003 sll1029 0.0 2.15885601259 1.43436207323 1.39960209915 1.33703414581 slr1834 0.0 -1.22814786087 -4.9125914435 -2.29625008403 -1.3861063113 slr1963 0.0 2.74242625203 2.03564274259 1.1817718736 0.708083394055 slr0642 0.0 0.515146959875 0.216658153529 0.175698434146 0.101970939255 slr1469 0.0 0.15989040024 0.639561600959 0.651815247578 0.673871811492 slr1348 0.0 -0.341259875426 -1.3650395017 -1.48360163296 -0.771117544254 sll0680 0.0 0.468061810654 0.47893279739 0.551406042302 0.681857883143 slr1350 0.0 1.40748598766 0.243441801508 0.297824411515 0.395713109526 slr2067 0.0 -2.32952202122 -3.00737597353 -1.21052938382 -0.165886542092 sll0901 0.0 -0.58063741361 -0.550767565801 -0.351635247076 0.0068029266283 sll1327 0.0 -0.244114184609 0.309923760626 0.433468520609 0.655849088579 slr1237 0.0 0.170112231199 0.680448924797 0.452827162876 0.819425110497 slr0208 0.0 0.989182216723 0.552781664868 0.494996312133 0.390982677209 sll0258 0.0 -1.50076873955 -1.79981911592 -0.640454228214 -0.249419331693 slr2075 0.0 2.42821403418 2.3071326893 1.49992372341 1.47640034609 sll0819 0.0 -2.37808970042 -3.52413199514 -1.84434038376 -1.09948837995 sll1306 0.0 -1.42003698886 -1.37616377635 -1.08367569294 -0.557197142809 sll1712 0.0 -0.86615483627 -0.909858951035 0.101616387622 0.276541138336 sll1743 0.0 -0.0641585219021 1.74757738748 1.27941498138 1.53167033547 sll1579 0.0 -3.24384564456 -4.79909291932 -2.53482033158 -1.30738786253 slr0329 0.0 -1.21518493475 -1.18796085587 -1.00646699667 -0.679778050107 slr1545 0.0 -1.37596809732 -1.20718375614 -0.0819548149425 -0.311131980425 sll0322 0.0 1.31871339578 1.31043011048 1.25520820851 1.15580878497 sll1810 0.0 -1.07577613026 1.36721436079 1.27154453167 1.09933883926 sll1804 0.0 -0.355404076657 1.82391138426 1.66569445792 1.38090399051 slr1835 0.0 -0.852039667525 -3.4081586701 -1.87136872275 -1.14231721195 slr1855 0.0 -2.94512669297 -2.66557104831 -0.801866750577 -0.264637777028 cluster-1.52a/data/README0000644000100500010050000000135607636777402014731 0ustar mdehoonmdehoonThe file cyano.txt contains the gene expression data, after preprocessing and linear spline fitting, of a time-course cDNA microarray experiment of the cyanobacterium Synechocystis sp PCC 6803 under high light conditions. This experiment is described in Yukako Hihara, Ayako Kamei, Minoru Kanehisa, Aaron Kaplan, and Masahiko Ikeuchi: "DNA Microarray Analysis of Cyanobacterial Gene Expression during Acclimation to High Light", The Plant Cell, Volume 13, pp. 793-806, April 2001. The k-means clustering result applied to these data was published in M.J.L. de Hoon, S. Imoto, S. Miyano: "Statistical analysis of a small set of time-ordered gene expression data using linear splines", Bioinformatics, Volume 18, no. 11, pp. 1477-1485, November 2002. cluster-1.52a/Makefile.am0000644000100500010050000000403112177152100015137 0ustar mdehoonmdehoon## Process this file with automake to produce Makefile.in DOCDIST = doc/cluster.pdf doc/cluster3.pdf doc/cluster.texinfo \ doc/cluster3.texinfo doc/structure.eps doc/Makefile WINDIST = windows/cluster.hhp windows/cluster.ico windows/cluster.iss \ windows/main.c windows/gui.c windows/format.bmp windows/Makefile \ windows/resources.h windows/resources.rc MACDIST = mac/main.m mac/Controller.h mac/Controller.m mac/cluster.icns \ mac/English.lproj/InfoPlist.strings \ mac/English.lproj/AboutPanel.nib/classes.nib \ mac/English.lproj/AboutPanel.nib/info.nib \ mac/English.lproj/AboutPanel.nib/keyedobjects.nib \ mac/English.lproj/FileFormatPanel.nib/classes.nib \ mac/English.lproj/FileFormatPanel.nib/info.nib \ mac/English.lproj/FileFormatPanel.nib/keyedobjects.nib \ mac/English.lproj/MainMenu.nib/classes.nib \ mac/English.lproj/MainMenu.nib/info.nib \ mac/English.lproj/MainMenu.nib/keyedobjects.nib \ mac/Cluster.xcodeproj/project.pbxproj mac/Makefile mac/Info.plist PYTHONDIST = setup.py python/MANIFEST.python python/__init__.py \ python/clustermodule.c python/test/README python/test/test_Cluster.py PERLDIST = perl/Artistic.txt perl/MANIFEST.perl \ Makefile.PL perl/Makefile.PL src/Makefile.PL \ perl/Cluster.pm perl/Record.pm perl/Cluster.xs \ perl/t/01_mean_median.t perl/t/02_tree.t \ perl/t/10_kcluster.t perl/t/11_clusterdistance.t perl/t/12_treecluster.t \ perl/t/13_somcluster.t perl/t/14_kmedoids.t perl/t/15_distancematrix.t \ perl/t/16_pca.t \ perl/examples/ex1_kcluster perl/examples/ex2_mean_median \ perl/examples/ex3_kcluster perl/examples/ex4_somcluster \ perl/examples/ex5_treecluster perl/examples/ex6_clusterdistance \ perl/examples/ex7_distancematrix perl/examples/ex8_kmedoids EXAMPLEDIST = example/example.c example/Makefile example/README HTMLDIST = html/mac.py html/Makefile DATADIST = data/README data/cyano.txt if MOTIF MAYBE_X11 = X11 endif SUBDIRS = $(MAYBE_X11) src EXTRA_DIST = $(WINDIST) $(MACDIST) $(PYTHONDIST) $(PERLDIST) $(DOCDIST) \ $(EXAMPLEDIST) $(HTMLDIST) $(DATADIST) cluster-1.52a/install-sh0000755000100500010050000003253711314437555015137 0ustar mdehoonmdehoon#!/bin/sh # install - install a program, script, or datafile scriptversion=2009-04-28.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cluster-1.52a/setup.py0000755000100500010050000000304512174112071014624 0ustar mdehoonmdehoon#!/usr/bin/env python from distutils.core import setup, Extension, Command import sys import os.path import shutil import sys import numpy shutil.copyfile(os.path.join('python','MANIFEST.python'),'MANIFEST') extra_link_args = [] if sys.platform != 'darwin': extra_link_args = ['-s'] extension = Extension("Pycluster.cluster", ["src/cluster.c", "python/clustermodule.c"], include_dirs=['src', numpy.get_include()], extra_link_args=extra_link_args ) class test_Pycluster(Command): "Run all of the tests for the package." user_options = [] def initialize_options(self): shutil.copyfile(os.path.join('python','test','test_Cluster.py'), 'test_Cluster.py') def finalize_options(self): pass def run(self): import unittest import test_Cluster test_Cluster.TestCluster.module = 'Pycluster' suite = unittest.TestLoader().loadTestsFromModule(test_Cluster) runner = unittest.TextTestRunner(sys.stdout, verbosity = 2) runner.run(suite) setup(name="Pycluster", version="1.52", description="The C Clustering Library", author="Michiel de Hoon", author_email="mdehoon 'AT' gsc.riken.jp", url="http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/software.html", license="Python License", package_dir = {'Pycluster':'python'}, packages = ['Pycluster'], ext_modules=[extension], cmdclass={"test" : test_Pycluster}, ) cluster-1.52a/ChangeLog0000644000100500010050000010046312177160277014701 0ustar mdehoonmdehoon2013.08.03 Added checks for all calls to malloc in src/data.c, and corresponding error messages in the GUI and command line programs. Using MinGW instead of Cygwin to create the installer for Windows. Using productbuild instead of productbuild to create the installer for Mac. Removed the mean and median functions from Pycluster, as anyway these are available from Numerical Python. This also avoids problems with deprecated API usage. Added checks for calls to malloc in Algorithm::Cluster. 2010.12.27 Modified Pycluster/Bio.Cluster to be able to compile and run with Python 3. Changed the number of passes in perl/t/14_kmedoids to avoid spurious test failures. Some minor updates in the documentation. 2010.04.05 Remove the #include's of stdio.h where they are not needed (perl/Cluster.xs, src/cluster.c). Remove the tests on the eigenvectors calculated for PCA when the corresponding eigenvalue is zero, since those eigenvectors are strongly affected by roundoff error, and are not relevant for PCA anyway. 2010.03.29 Rewrote the code for Principal Component Analysis and made it accessible from Python, Perl, and the GUI and command line programs. The previous code for the singular value decomposition is no longer available. Fixed a bug in src/data.c, in which sizeof(char**) was used instead of sizeof(char*). Check memory allocation in X11/gui.c and src/command.c more carefully. 2009.09.11 Fix an error in the calculation of the number of times the optimal solution is found in the kmeans and kmedians routines. In Algorithm::Cluster, fix the routine identifying which values in the data matrix are missing. Try to be more consistent in the coding standards of Cluster.xs and Cluster.pm. Make the docstrings in Python/__init__.py consistent with the Python recommendations. Changed the tests for NumPy arrays in Python/__init__.py by tests for None. 2009.05.30 Rewrote the Algorithm::Cluster test scripts using Perl's testing framework. The text 02_matrix_parse.t was dropped. Rewrote two lines in perl/Cluster.xs to be ANSI compliant. Added a missing reference to numpy in python/__init__.py. Improved unsigned/int correctness in python/clustermodule.c. Added a cast from int to char in src/data.c. Fixed a bug in src/cluster.c in the calculation of the number of times the best solution was found in kmedoids. 2009.04.21 Fixed a bug in Perl/Cluster.xs, which caused the size of the array returned by somcluster to be incorrect if transpose==1. Modified python/__init__.py to be consistent with the Python style guide. Updated the docstrings. Removed the CALL (STDCALL) definitions in src/cluster.c; this doesn't seem to be needed any more. Updated windows/resources.rc to be consistent with the latest version of windres. 2009.03.22 Fixing a bug in Cluster 3.0 on Windows, which caused Cluster 3.0 to crash if a user attempts to read in a file that does not have a file extension. For Cluster 3.0 with X11, don't use the obsolete Xp library. In Pycluster, call test_Cluster.py from "python setup.py test" instead of from a separate script test.py. When initializing a Record, read the data file line by line instead of all lines at the same time. Updating the unit tests. In Algorithm::Cluster, removed the typemap as it was not being used. Replace Record by Algorithm::Cluster::Record for robustness. Introduced the Algorithm::Cluster::Tree and Algorithm::Cluster::Node classes to represent hierarchical clustering results. Adding cut and scale methods to the Tree class. This will affect Perl scripts calling treecluster. Make sure that all tests and examples are included in the distribution. 2008.10.01 Removed the print_matrix_dbl function from perl/Cluster.xs, since it was not being used. Removed the deprecated PyArray_FromDims function from python/clustermodule.c. Check memory allocations rigorously in src/command.c. 2008.09.12 Fixed a memory leak in the spearman function in src/cluster.c. Converted python/__init__.py to the new NumPy; this should have been done in the previous release. 2008.08.30 The command-line version of Cluster 3.0 now allows it to be used without actually clustering, for example for normalization only (patch by Jeff Chang). Better handling of memory allocation failures in Algorithm::Cluster. Fixed a memory leak in clustercentroids in Algorithm::Cluster. Converted Pycluster to the new Numerical Python (NumPy 1.1.1). 2008.07.29 In the command-line version, missing breaks after each case in a switch caused median-centering to be applied when mean-centering was intended. Updated the documentation for Algorithm::Cluster, which was still showing the old output for Algorithm::Cluster::treecluster. The documentation is now distributed with the Algorithm::Cluster and Pycluster distributions. The DataFile class is now removed from python/__init__.py; replaced by the Record class. 2008.07.05 Fixed a bug in the pairwise single-linkage clustering algorithm. The size of the hierarchical tree is one less than the number of items to be clustered. However, one more node is used during the calculation of the hierarchical tree. Therefore, memory for one more node should be allocated. Used Python's unit test framework for the Pycluster tests. Added a version() function to Pycluster and Algorithm::Cluster. 2008.03.08 The executable for the Cluster 3.0 GUI can now also be used as a command-line program. Having separate executables is no longer necessary. It is still possible to compile Cluster 3.0 as a command-line only program, though. The Makefile.am and configure.ac files were updated accordingly. In Pycluster, the DataFile class was renamed Record. The recommended way to read a data file is now to use the Pycluster.read(handle) function, which returns a Record object. The clustercentroids function was added to Algorithm::Cluster. This module now also contains a Record class, which stores the data in a Cluster/TreeView-type expression data file. The appropriate functions in Algorithm::Cluster can now also be called as methods on a Record object. The treecluster function in Algorithm::Cluster now returns a single array with three columns. The last column returns the distances between items; this information was previously in a separate linkdist variable. 2007.11.21 Updated X11/gui.c to correctly deal with 64-bits architectures. This affects only the GUI, not the calculation itself. Replaced Netscape by Firefox as the default browser to read the help files on Unix/Linux. Updated the documentation. In Algorithm::Cluster, fixed the argument checking for the method argument in clusterdistance. In Pycluster, added argument checking for the arguments method and dist in clusterdistance. In src/data.c, replaced the use of strtok by a new tokenizer function to deal correctly with the case in which UNIQID is an empty string. 2007.06.19 Updated contact address to RIKEN. Rewrapped the docstrings in python/__init__.py and python/clustermodule.c to make each line fit. Removed a spurious return in python/clustermodule.c that prevented the distance matrix from being freed. In py_distancematrix in python/clustermodule.c, avoid the first row of the distance matrix from being freed, since this row is always NULL. Avoid this first row also in find_closest_pair in src/cluster.c. Rewrote the k-means algorithm in src/cluster.c. The previous version used a floating-point comparison that caused this routine to hang on some platforms. 2007.02.28 In src/cluster.c, let spearman return 1.0 if all ranks are equal. Fix casting of the result of floor. 2007.02.26 Allow a list of rows to represent the distance matrix in the Python functions kmedoids and treecluster. Make the docstrings for Pycluster more readable. Change i to l in the format string in PyArg_ParseTuple* functions for Pycluster to behave correctly on 64-bits machines. Updated standard exceptions in Pycluster. One minor change in src/cluster.c. 2006.09.25 Replaced calls to pow() by exp(log()) or sqrt(). The function pow() caused crashes on AIX (see Google for more information about the pow() bug on AIX). Check for sqrt, log, and exp presence in the math library; don't check pow. Replaced the ranlib random number generator by a random number generator written from scratch. Hence, ranlib is no longer needed, and was removed from the C Clustering Library. The examples were updated accordingly. 2006.05.12 Updated the website of Java TreeView in the documentation. Removed skipped lines in Makefile.PL. Updated Makefile.am to account for the new build process on Mac OS X (building a universal binary with XCode 2.2.1). Fixed the Makefile.am files such that configure looks for the Motif libraries and its dependencies. Also, check the math library only once for the sqrt and pow functions. The routine PerformPCA in src/data.c now returns an error message if a memory allocation error occurred (NULL otherwise). The routine randomassign was removed from src/cluster.h, and declared static in src/cluster.c, since no external code uses it. The functions getclustermean and getclustermedian were replaced by a single function getclustercentroids; the function getclustermedoid was renamed getclustermedoids. The functions kcluster and kmedoids now return if a memory allocation error occurs, and set *ifound equal to -1. Hierarchical clustering solutions are now represented as an array of Node structs, where each Node struct contains the numbers of the subnodes that were joined as well as the distance between them. The treecluster routine now returns a pointer to a newly allocated array of Node structs; cuttree accepts an array of Node structs as input. The cuttree no longer checks its input; if the array of Node structs is inconsistent, a segmentation fault may occur. However, cuttree is called only from python/clustermodule.c, which guarantees that the input to cuttree is consistent. In Python, hierarchical clustering solutions are implemented as a Tree class, a read-only list of Node objects. The cuttree function is now a method of the Tree class. Removed unneeded code from perl/Cluster.xs. Fixed the Perl test case in perl/t/14_medoids.t; previously, the clustering problem resulted in two nodes with an equal distance, making the solution depend on roundoff. The Python file reading routines were moved from python/data.py to python/__init__.py. Reading Cluster/TreeView-type files is now implemented as part of the DataFile class. In python/clustermodule.c, None arguments are interpreted as missing arguments. The clustercentroid function was renamed clustercentroids. Makefile.PL now checks for 64-bits architectures, and adds the -fPIC flag if needed. Simplified the quicksort calls in src/cluster.c and src/data.c. The function getrank now returns NULL if it fails due to a memory error. In the k-means/k-medians/k-medoids routines, previously the iteration stopped if no item reassignments were made, or if a periodic loop was detected in the EM algorithm. Instead, we now monitor the within-cluster sum of distances, and stop the iteration if no further improvement is obtained. In the k-means/k-medians/k-medoids routines, previously the iteration stopped if no item reassignments were made, or if a periodic loop was detected in the EM algorithm. Instead, we now monitor the within-cluster sum of distances, and stop the iteration if no further improvement is obtained. The routine svd sets ierr to an error flag if a memory allocation error occurs. Rewrote the initial random cluster assignment in kcluster, requiring no extra memory to be allocated. 2006.02.26 In the Perl module Algorithm::Cluster, allow hierarchical clustering to be applied to a user-defined distance matrix. In the Python extension module Pycluster / Bio.Cluster: fix the glue code in python/clustermodule.c in order for the extension module to work correctly on 64-bits machines. 2005.10.15 The k-means clustering routine accepts all eight distance functions available in the C Clustering Library. However, using distance functions other than the Euclidean distance and the city-block distance is discouraged. The reason is that other distance functions (such as the Pearson distance) calculate distances between data vectors that are effectively scaled (by subtracting the mean and dividing by the standard deviation for the Pearson distance), whereas the centroid calculation is performed by averaging the data vectors without normalization. A more correct way to use these normalized distance functions is to normalize the data (using the "Adjust data" tab in the GUI program) before starting the k-means clustering calculation. To discourage the use of distance functions other than the Euclidean distance and the city-block distance, in the GUI-version the distance defaults to the Euclidean distance for k-means and SOM calculations SOM (other distances can still be chosen, though). A similar argument can be made against the use of distance functions other than the Euclidean distance and the city-block distance in pairwise centroid-linkage hierarchical clustering. Fixed a bug in the command-line version of the code that caused the -ng and -na flags to have an effect only if the -cg and -ca flags were also specified. Fixed the Load routine in src/data.c so that it doesn't crash if the users attempts to read an empty file. Fixed the reading of empty lines in the data file in the Load routine in src/data.c. Removed the AlwaysCreateUninstallIcon option from the Inno Setup configuration file, as it is no longer supported by Inno Setup. Fixed a bug in windows/gui.c that caused arrays to be centered if the "Center genes" checkbox is checked. Simplified the way in which the bitmap is displayed in the "File format" help window, and fixed its position (previously, it was partly covered by the text on Windows XP). Fixed a bug in FilterDialogProc in windows/gui.c that caused a NULL pointer to be freed the first time the filter is applied. Gave ID_KMEANS_ARRAY_METRIC and ID_KMEANS_BUTTON different identifier numbers in windows/resources.rc. Updated windows/resources.rc to comply with the latest version of windres. Modified somworker in src/cluster.c to take the mask into account. Changed my email address, as I'm now at Columbia University. 2005.04.27 Bug fix in py_treecluster in python/clustermodule.c: the variable nnodes was not set if the distance matrix is specified instead of the data matrix. Bug fix in py_treecluster in python/clustermodule.c: the routine returns if the linkdist array cannot be allocated. Further cleanup of perl/Cluster.xs. Input data are now checked more strictly; any error will cause the calculation to abort. Previously, some errors were ignored, for example rows of unequal size in the data matrix. The algorithm for pairwise single-linkage hierarchical clustering was replaced by the SLINK algorithm: Sibson, R. (1973). SLINK: An optimally efficient algorithm for the single-link cluster method. The Computer Journal, 16(1): 30-34. The clustering result produced by this algorithm is identical to the single- linkage hierarchical clustering result, but the SLINK algorithm is much faster and uses much less memory. Hence, it can be used for large data sets. Removed the alternative implementation (using a cache) of pairwise centroid-linkage hierarchical clustering, as the new single-linkage routine looks more useful. 2005.02.23 Removed the harmonically summed Euclidean distance from the set of available distance metrics. For the Euclidean distance and the city-block distance, the sum is now divided by the number of observations present. Previously, the sum was divided by the number of observations present and multiplied by the total number of present and missing observations. In k-means clustering, when calculating the centroid of a cluster, the normalized expression profiles of the elements are summed. Previously, the unnormalized profiles were summed. Normalization depends on the distance metric. For the Euclidean distance and city-block distance, no normalization is used. For the Pearson correlation and the absolute Pearson correlation, the mean is subtracted from each expression profile, and the expression profile is divided by its standard deviation. For the uncentered Pearson correlation and the absolute uncentered Pearson correlation, each expression profile is divided by its standard deviation. For the Spearman rank correlation and Kendall's tau, the expression profiles are replaced by the ranks. In k-means clustering, previously the order in which genes/microarrays are reassigned was randomized. Since all genes/microarrays are reassigned before the cluster centroids are recalculated, the effect of the randomization is minimal. The order has an effect only if the last remaining gene is to be reassigned to a different cluster, as those reassignments are prevented in our implementation of k-means clustering. In the present algorithm, the order in which genes/microarrays are reassigned is no longer randomized. Previously, the k-means clustering algorithm returned the expression profiles of the centroids of the k clusters. Some applications of the k-means algorithm simply discard these (e.g. the Cluster 3.0 program). Since the centroids can be recalculated trivially, the current implementation of k-means clustering does not return the centroid profiles. The hierarchical clustering routine treecluster previously sets the first two elements of the clustering result to (0,0) if the available memory was insufficient. In the present implementation, treecluster is a function that returns 0 if not enough memory was available, and 1 if the calculation was successful. Previously, the treecluster algorithm took an argument applyscale to indicate if the link distances should be scaled by usage by Java TreeView. Since such scaling can be applied trivially after the treecluster routine, this argument was removed. Added a memory-efficient implementation of pairwise centroid-linkage hierarchical clustering (currently accessible from Python only). Cluster 3.0 GUI, all platforms: o) Changed the layout of the "Adjust" tab page, such that users cannot choose both mean and median centering at the same time. o) For hierarchical clustering, if the user specifies to calculate the weights, then for the first calculation of the distance matrix the weights as stored in the data file are used. For the actual clustering, the distance matrix is recalculated using the calculated weights. Previously, a distance matrix calculated as part of the weights calculation was reused for the clustering calculation, leading to inconsistencies. o) Calculation of the weights for hierarchical clustering is now implemented as a separate function in src/cluster.c. Cluster 3.0 for Mac OS X: o) Send the retain message to the directory variable after setting it by calling NSHomeDirectory(); otherwise the directory is autoreleased. Cluster 3.0 for Unix/Linux: o) In the routine MenuFile, a pointer to the static variable directory is passed to the OpenFile and SaveFile routines via the client_data pointer. The OpenFile and SaveFile take care of saving the last accessed directory in this variable. This avoids a call back to MenuFile. o) The routine Cleanup was removed. Previously, the WM_DELETE_WINDOW message caused the callback function Cleanup to be called, which in turn called Free, Filter, and MenuFile to free allocated memory. The CMD_FILE_EXIT command in MenuFile called Cleanup. Now, the WM_DELETE_WINDOW message has MenuFile as the callback function, passing CMD_FILE_EXIT as the client_data argument. The CMD_FILE_EXIT case in MenuFile takes care of freeing allocated memory. Hence, exiting the program via the menu or by closing the window becomes equivalent. o) The routine InitFilemanager is replaced by the case ID_FILEMANAGER_INIT in the routine FileManager. o) Setting the FileMemo and Jobname is is now done by the case ID_FILEMANAGER_SET_FILEMEMO and ID_FILEMANAGER_SET_JOBNAME in the routine FileManager. Previously, the corresponding code was located in OpenFile. o) Updating the rows and columns in the file manager is done by the case ID_FILEMANAGER_UPDATE_ROWS_COLUMNS in the routine FileManager. Previously, this was done by the case ID_SOM_UPDATE in the routine SOM by calling the routines SetRows and SetColumns. These two have been removed. o) In the routine Filter, freeing the static pointer "use" is achieved via the ID_FILTER_FREE message. Previously, the Filter routine checked if the Widget pointer is NULL. When freeing "use", we now check it to make sure it is not NULL. o) All routines except main() are now declared static. o) To create the pull down menu, the defined values CMD_FILE_OPEN and CMD_FILE_SAVE are used instead of the hard-coded 0 and 1. Cluster 3.0, command-line version: o) Changed the definition of the command-line option -l (previously -l 0|1) and -s (previously -s 0|1). Added the command-line options -cg a|m (center each row in the data set by subtracting the row mean or median), -ng (normalize each row in the data set), -ca a|m (center each column in the data set by subtracting the column mean or median), -na (normalize each column in the data set). o) Allow the user to choose the number of repetitions for k-means clustering. Perl interface Algorithm::Cluster: o) Added the kmedoids function. o) Added the distancematrix function. o) Allow the initial cluster assignments to be specified by the user in the kcluster and kmedoids functions. o) Allow the parameters cluster1 and cluster2 in clusterdistance to be a single integer instead of an integer array. o) When converting Perl arrays to C arrays, function will return NULL if an error is detected (previously only a warning was raised). This has not yet been implemented for all conversion functions. Documentation: o) Equations (before shown as PNGs) replaced by HTML code. 2004.06.09 Replaced 1.e99 by DBL_MAX in src/cluster.c. Rewrote the Makefile and the Inno Setup Compiler script for the Windows version of Cluster 3.0 such that both an ANSI (Windows 95, 98, Me) and a UNICODE (Windows NT, 2000, XP) version is included. The installer determines on which version of Windows it is being run, and installs the appropriate version. Some minor changes were needed in windows/gui.c for it to compile correctly for both ANSI and UNICODE. The routine distancematrix in src/cluster.c now returns NULL if not enough memory can be allocated to store the distance matrix. In src/data.c, the function ClearDistanceMatrix now does not take any arguments. Previously, an argument specifying the size of the distance matrix was needed to free the matrix appropriately. As this is error-prone, the size of the distance matrix is now stored as part of the _distancematrix struct. The routines that make sure that genes and arrays are saved in the correct order in the .cdt output file are now static routines in src/data.c, except for the new routine ResetIndex. Added a routine GetWidgetItemInt to X11/gui.c to make reading integer values from edit boxes easier, as well as a routine ShowError to display error messages. Code cleanup in src/data.c in the PerformSOM routine. The calling code in src/command.c, windows/gui.c, mac/Controller.m, X11/gui.c was updated accordingly. In the new version, the SOM calculation is started after opening all output files, and no calculation is performed if the function fails to open any of the files. Code cleanup in the hierarchical clustering section of windows/gui.c, mac/Controller.m, X11/gui.c. Previously, some unnecessary steps in the calculation were performed. The treecluster routine now returns (0,0) as the first linking event if the routine fails due to lack of memory. This may occur if the treecluster needs to calculated the distance matrix but cannot allocate enough memory to store it. Added the code to check if the first clustering event is (0,0) to python/clustermodule.c and perl/Cluster.xs. In src/command.c, routines that are only used locally are now defined static. In mac/Controller.m, added a struct FileHandle and the routines OpenFile and CloseFile for file access management. In src/data.c, local variables are now defined static. In src/data.c, SetIndex, SetClusterIndex, SetOrderIndex were rewritten as ResetIndex, SetClusterIndex. Replaced empty argument lists by "void" in function declarations. 2004.05.09 Bug fix in python/clustermodule.c: In clusterdistance and clustercentroid, the TRANSPOSE variable was not initialized to 0. Check for missing gene names in the Load function in src/data.c. The function returns an error message if the gene name is missing in a data row. The Windows and Mac OS X versions of Cluster 3.0 can now handle UNICODE file names. Fixed a bug with the City Block distance measure. Previously, distances were not scaled correctly, causing errors with Java TreeView. 2004.04.02 Cleaned up python/clustermodule.c. Fixed an error in the test routine test_Cluster.py, which caused an incorrect result to be displayed in the results file test_Cluster. The kcluster routine in the Perl interface Algorithm::Cluster now includes the residual within-cluster sum of distances in the returned output. Updated the Perl example scripts accordingly, and added tests for this output variable to t/10_kcluster.t. Added the city-block distance to the Unix/Linux version of Cluster 3.0. In Pycluster, for the routines "treecluster" and "clusterdistance" the order of the arguments "method" and "dist" were interchanged for consistency with kcluster. Generalized the usage of clusterdistance in Pycluster such that clusters containing only one item can be represented as a list containing one item (e.g. index1==[17]) or as the item number itself (index1=17). Removed the Windows Registry keys that are specific to TreeView from the installer program for Windows. Removed the "Launch Java TreeView" button from Cluster 3.0. With the improved installers for Java TreeView, this button is no longer needed. Minor cleanup of the automake/autoconf files. This affects the configure script. Fixed the version number in the command-line version of Cluster 3.0. In the Perl interface Algorithm::Cluster, fixed a memory allocation error that caused core dumps when clustering microarrays (transpose==1). Code cleanup: removed casts in front of malloc. Updated the automake/autoconf files. For the GUI-version of Cluster 3.0 on Unix/Linux, use configure or configure --with-x For the command-line version of Cluster 3.0, use configure --without-x (so the --with-motif is no longer used). Added the -lXt and -lX11 libraries to the link command. 2004.01.27 Cleaned up the examples in the perl/examples subdirectory. Renamed the installer program for Cluster 3.0 for Windows from ctvsetup.exe to clustersetup.exe. Changed the file name of the Cluster 3.0 manual from ctv.pdf to cluster3.pdf (the name of the manual for the C Clustering Library is cluster.pdf as before). Updated the Makefile in the examples subdirectory. Added the cuttree routine to the C Clustering Library. This routine takes the tree structure generated by the hierarchical clustering routines, and groups the elements in the tree into a given number of clusters. Generalized the kcluster routine so that it can start from an initial clustering specified by the user. This is also available from Python, but not (yet) from Perl. Updated the manual. Added the city-block distance to the Perl interface. Fixed a bug in the Macintosh-version of Cluster 3.0, which prevented the arrays from being adjusted in the Adjust tab. Added the k-medoids algorithm the the C Clustering Library, and added the corresponding Python interface to the k-medoids routine. Rewrote the Python interface to the kcluster routine. Added a Python interface to the distancematrix routine. Added tests to Bio.Python / Pycluster. Modified the command-line version of Cluster 3.0 to enable users to specify which kind of hierarchical clustering is used (pairwise complete-, single-, centroid-, or average-linkage). 2003.09.07 Bug fix in the pairwise average-linkage hierachical clustering algorithm (palcluster in src/cluster.c). The last row in the distance matrix was not being copied properly. Thanks to Chris Torrence of Research Systems, Inc. for noticing this bug. For the Mac OS X version, the close button in the main window was disabled. 2003.07.17 Bug fix in the GUI for Cluster 3.0 on Linux/Unix. The bug led to a crash when users try to use the help window for the file format. The hierarchical clustering routine in Pycluster can now cluster a data set if only the distance matrix is available, and the original gene expression data are not available. This is also useful in cases where the distance is defined but the original data are not well defined, for example when clustering proteins based on the similarity of their shape. Clustering using the distance matrix only is not possible for centroid linkage clustering, which always needs the original data. The INSTALL file was added to MANIFEST for the Perl package Algorithm::Cluster. A command line version of Cluster 3.0 was written, with the command line options consistent with Gavin Sherlock's xcluster program, following a suggestion by QuangQiu Wang of Stanford University. For the compilation, "configure" now writes the Makefile for the command line program, while "configure --with-motif" generates the Makefile for the GUI program. There is no longer the option to compile the library by itself, as it is easier to do this by simply collecting the appropriate source files. 2003.06.13 The city-block distance was added as one of the measures of similarity in gene expression data. The manual was updated on how to use the clustering routines from Biopython. 2003.05.28 The license was changed to the Python License instead of the GNU Lesser General Public License for the C Clustering Library and Pycluster. Algorithm::Cluster is covered by the Artistic License (same license as Perl itself). Replaced the routine for the Singular Value Decomposition with a routine that is compatible with the Python License. Cleaned up the file reading routine in src/data.c. Bug fix in the PCA routine in src/data.c; the data matrix was not being scaled correctly. In the Perl test script 01_mean_median.t, write out floating point values with a limited number of decimals. Previously, the comparison of floating point values led to spurious errors when running this test script. 2003.05.06 Fix for a bug in GeneKCluster, where the temporary array cdata was not allocated enough space, leading to crashes. Also a speed improvement in the kcluster routine (thanks to Minkov Minsky). 2003.04.25 Several changes in version 1.17, including a fix for a bug in kcluster that significantly increased the running time, and a fix for a file reading error in data.c, affecting Cluster 3.0. The file reading error caused missing values to be interpreted as a zero. Thanks to Justin Klekota of Harvard University for noticing the bug in kcluster. Cleaned up the API for hierarchical clustering and self-organizing maps. This version also includes the updated documentation for the Perl interface. 2003.04.04 Fixed some memory leakage problems in somassign in cluster.c. 2003.03.30 Fixed a file reading problem in Cluster 3.0 due to the different end of line character on Macintosh computers. Files edited on Macs (e.g. with Excel) can now be read by Cluster 3.0. Thanks to Ivan Baxter of the Scripps Research Institute for noticing this error. Some cleanup in the perl interface (e.g., removing unused variables). 2003.03.22 Added the perl interface to the C Clustering Library. The perl interface was written by John Nolan. 2003.02.21 Updated the manual (Thanks to Timothy Chklovski of the MIT for pointing out an error in the description of pairwise complete-linkage clustering in the manual for Cluster 3.0). Fixed a typing error in the Python interface to the SOM routine. 2003.02.01 Cleaned up palworker (improved speed and memory requirements). 2003.01.20 Bugfix in palworker. Thanks to Jin Hu Huang, Flinders University, Australia, for noticing this bug. 2003.01.07 Change in the onepass routine in src/cluster.c. The number of elements in each cluster is tracked during the iteration. If a certain cluster has only one element left, no reassignment takes place in order to avoid empty clusters. 2003.01.03 Change in the onepass routine in src/cluster.c. Checking for periodic solutions is interrupted as soon as a different cluster id is found. 2002.12.12 Bug fix in src/data.c (gene weights and array weights were switched). 2002.12.05 Bug fix in X11/gui.c (unallocated string problem). Some changes in the documentation to refer to OpenMotif. 2002.11.05 Cluster 3.0 was ported to Unix/Linux using Motif. Some functions were added to Pycluster, mainly to read and write Cluster/ TreeView style files. The Java/C hybrid JavaCluster will no longer be maintained because of portability problems. cluster-1.52a/perl/0000755000100500010050000000000012177164023014056 5ustar mdehoonmdehooncluster-1.52a/perl/Cluster.pm0000644000100500010050000006111412175616437016051 0ustar mdehoonmdehoon#--------------------------------------------------------------------------- package Algorithm::Cluster; #--------------------------------------------------------------------------- # Copyright (c) 2003 John Nolan. All rights reserved. # This program is free software. You may modify and/or # distribute it under the same terms as Perl itself. # This copyright notice must remain attached to the file. # # Algorithm::Cluster is a set of Perl wrappers around the # C Clustering library. # #--------------------------------------------------------------------------- # The C clustering library for cDNA microarray data. # Copyright (C) 2002 Michiel Jan Laurens de Hoon. # # This library was written at the Laboratory of DNA Information Analysis, # Human Genome Center, Institute of Medical Science, University of Tokyo, # 4-6-1 Shirokanedai, Minato-ku, Tokyo 108-8639, Japan. # Contact: mdehoon 'AT' gsc.riken.jp # # The Algorithm::Cluster module for Perl was released under the same terms # as the Perl Artistic license. See the file artistic.txt for details. #--------------------------------------------------------------------------- use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS @EXPORT); use vars qw($DEBUG); use strict; use DynaLoader; require Exporter; $VERSION = '1.52'; $DEBUG = 1; @ISA = qw(DynaLoader Exporter); @EXPORT_OK = qw( mean median kcluster kmedoids somcluster treecluster clusterdistance clustercentroids distancematrix pca ); use warnings::register; bootstrap Algorithm::Cluster $VERSION; #------------------------------------------------------------- # Debugging functions # sub version { return _version(); } #------------------------------------------------------------- # Wrapper for printing warnings # sub module_warn { return unless warnings::enabled(); warnings::warn("Algorithm::Cluster", join '', @_); } #------------------------------------------------------------- # Make sure that the first parameter is a reference-to-array, # whose first member is itself a reference-to-array, # and that that array has at least one member. # sub data_is_valid_matrix { unless (ref($_[0]) eq 'ARRAY') { module_warn("Wanted array reference, but got a reference to ", ref($_[0]), ". Cannot parse matrix"); return; } my $nrows = scalar @{ $_[0] }; unless ($nrows > 0) { module_warn("Matrix has zero rows. Cannot parse matrix"); return; } my $firstrow = $_[0]->[0]; unless (defined $firstrow) { module_warn("First row in matrix is undef scalar (?). Cannot parse matrix",); return; } unless (ref($firstrow) eq 'ARRAY') { module_warn("Wanted array reference, but got a reference to ", ref($firstrow), ". Cannot parse matrix"); return; } my $ncols = scalar @{ $_[0]->[0] }; unless ($ncols > 0) { module_warn("Row has zero columns. Cannot parse matrix"); return; } unless (defined($_[0]->[0]->[0])) { module_warn("Cell [0,0] is undefined. Cannot parse matrix"); return; } return 1; } #------------------------------------------------------------- # Wrapper for the mean() function # sub mean { if(ref $_[0] eq 'ARRAY') { return _mean($_[0]); } else { return _mean([@_]); } } #------------------------------------------------------------- # Wrapper for the median() function # sub median { if(ref $_[0] eq 'ARRAY') { return _median($_[0]); } else { return _median([@_]); } } #------------------------------------------------------ # This function is called by the wrappers for library functions. # It checks the dimensions of the data, mask and weight parameters. # # Return false if any errors are found in the data matrix. # # Detect the dimension (nrows x ncols) of the data matrix, # and set values in the parameter hash. # # Also check the mask matrix and weight arrays, and set # the parameters to default values if we find any errors, # however, we still return true if we find errors. # sub check_matrix_dimensions { my ($param, $default) = @_; #---------------------------------- # Check the data matrix # return unless data_is_valid_matrix($param->{data}); #---------------------------------- # Remember the dimensions of the weight array # $param->{nrows} = scalar @{ $param->{data} }; $param->{ncols} = scalar @{ $param->{data}->[0] }; #---------------------------------- # Check the mask matrix # unless (data_is_valid_matrix($param->{mask})) { module_warn("Parameter 'mask' is not a valid matrix, ignoring it."); $param->{mask} = $default->{mask} } else { my $mask_nrows = scalar @{ $param->{mask} }; my $mask_ncols = scalar @{ $param->{mask}->[0] }; unless ($param->{nrows} == $mask_nrows and $param->{ncols} == $mask_ncols) { module_warn("Data matrix is $param->{nrows}x$param->{ncols}, but mask matrix is ${mask_nrows}x${mask_ncols}.\nIgnoring the mask."); $param->{mask} = $default->{mask}; } } #---------------------------------- # Check the weight array # unless(ref $param->{weight} eq 'ARRAY') { module_warn("Parameter 'weight' does not point to an array, ignoring it."); $param->{weight} = $default->{weight}; } else { my $weight_length = scalar @{ $param->{weight} }; if ($param->{transpose} eq 0) { unless ($param->{ncols} == $weight_length) { module_warn("Data matrix has $param->{ncols} columns, but weight array has $weight_length items.\nIgnoring the weight array."); $param->{weight} = $default->{weight} } } else { unless ($param->{nrows} == $weight_length) { module_warn("Data matrix has $param->{nrows} rows, but weight array has $weight_length items.\nIgnoring the weight array."); $param->{weight} = $default->{weight} } } } return 1; } sub check_distance_matrix { my $distances = $_[0]; my $i; my $row; my $column; #---------------------------------- # Check the data matrix # my $reference = ref($distances); if (!$reference) { return "Wanted array reference but did not receive a reference"; } elsif ($reference ne 'ARRAY') { return "Wanted array reference, but got a $reference"; } my $nobjects = scalar @{ $distances }; unless ($nobjects > 0) { return "Distance matrix has zero rows"; } $i = 0; foreach $row (@{ $distances}) { unless (defined $row) { return "Row $i is undefined"; } unless (ref($row) eq 'ARRAY') { return "Row $i is not an array"; } unless (@{$row} == $i) { return "Row $i has incorrect columns"; } foreach $column (@{$row}) { unless (defined($column)) { return "Row $i contains undefined columns"; } } $i++; } return "OK"; } sub check_initialid { my ($param, $default, $nobjects) = @_; my $i; my @counter = {}; #---------------------------------- # Check the initial clustering solution, if specified # if(ref $param->{initialid} ne 'ARRAY') { module_warn("Optional parameter 'initialid' should be an array"); return; } if (@{ $param->{initialid}} == 0) { # no initial clustering solution specified if ($param->{nclusters}==-1) { $param->{nclusters} = 2; # default value } if ($param->{nclusters} > $nobjects) { module_warn("More clusters requested than elements available"); return; } unless($param->{npass} =~ /^\d+$/ and $param->{npass} > 0) { module_warn("Parameter 'npass' must be a positive integer (got '$param->{npass}')"); return; } return 1; } if (@{ $param->{initialid}} != $nobjects) { module_warn("Optional parameter 'initialid' should contain $nobjects elements"); return; } foreach $i (@{ $param->{initialid}}) { unless($i =~ /^\d+$/ and $i >= 0) { module_warn("Optional parameter 'initialid' should only contain non-negative integers"); return; } } if ($param->{nclusters} == -1) { # number of clusters was not specified. Infer it from initialid foreach $i (@{ $param->{initialid}}) { if ($i > $param->{nclusters}) { $param->{nclusters} = $i; } } $param->{nclusters}++; } else { # check if initialid is consistent with number of clusters foreach $i (@{ $param->{initialid}}) { if ($i >= $param->{nclusters}) { module_warn("Optional parameter 'initialid' inconsistent with nclusters"); return; } } } # Check that none of the clusters are empty for ($i = 0; $i < $param->{nclusters}; $i++) { push(@counter, 0); } foreach $i (@{ $param->{initialid}}) { $counter[$i]++; } for ($i = 0; $i < $param->{nclusters}; $i++) { if ($counter[$i]==0) { module_warn("Optional parameter 'initialid' contains empty clusters"); return; } } # No errors detected $param->{npass} = 0; return 1; } #------------------------------------------------------------- # Wrapper for the kcluster() function # sub kcluster { #---------------------------------- # Define default parameters # my %default = ( nclusters => -1, data => [[]], mask => '', weight => '', transpose => 0, npass => 1, method => 'a', dist => 'e', initialid => [], ); #---------------------------------- # Local variable # my $nobjects = 0; #---------------------------------- # Accept parameters from caller # my %param = (%default, @_); my @data = @{$param{data}}; #---------------------------------- # Check the data, matrix and weight parameters # return unless check_matrix_dimensions(\%param, \%default); #---------------------------------- # Check the transpose parameter # if ($param{transpose} == 0) { $nobjects = $param{nrows}; } elsif ($param{transpose} == 1) { $nobjects = $param{ncols}; } else { module_warn("Parameter 'transpose' must be either 0 or 1 (got '$param{transpose}')"); return; } #---------------------------------- # Check the initial clustering, if specified, and npass # return unless check_initialid(\%param, \%default, $nobjects); #---------------------------------- # Check the other parameters # unless($param{method} =~ /^[am]$/) { module_warn("Parameter 'method' must be either 'a' or 'm' (got '$param{method}')"); return; } unless($param{dist} =~ /^[cauxskeb]$/) { module_warn("Parameter 'dist' must be one of: [cauxskeb] (got '$param{dist}')"); return; } #---------------------------------- # Invoke the library function # return _kcluster(@param{ qw/nclusters nrows ncols data mask weight transpose npass method dist initialid/ }); } #------------------------------------------------------------- # Wrapper for the kmedoids() function # sub kmedoids { #---------------------------------- # Define default parameters # my %default = ( nclusters => 2, distances => [[]], npass => 1, initialid => [], ); #---------------------------------- # Accept parameters from caller # my %param = (%default, @_); #---------------------------------- # Check the distance matrix # my $message = check_distance_matrix($param{distances}); unless ($message eq "OK") { module_warn($message); return; } $param{nobjects} = scalar @{ $param{distances} }; #---------------------------------- # Check the initial clustering, if specified, and npass # return unless check_initialid(\%param, \%default, $param{nobjects}); #---------------------------------- # Invoke the library function # return _kmedoids(@param{ qw/nclusters nobjects distances npass initialid/ }); } #------------------------------------------------------------- # treecluster(): Wrapper for the treecluster function # sub treecluster { #---------------------------------- # Define default parameters # my %default = ( data => [[]], mask => '', weight => '', transpose => 0, dist => 'e', method => 's', ); #---------------------------------- # Accept parameters from caller # my %param = (%default, @_); #---------------------------------- # Check the data, matrix and weight parameters # my $message = check_distance_matrix($param{data}); if ($message eq "OK") { $param{nrows} = scalar @{ $param{data} }; $param{ncols} = scalar @{ $param{data} }; $param{mask} = $default{mask}; $param{weight} = $default{weight}; $param{transpose} = $default{transpose}; $param{dist} = $default{dist}; #---------------------------------- # Check the clustering method # unless($param{method} =~ /^[sma]$/) { module_warn("Parameter 'method' must be one of [sma] (got '$param{method}')"); return; } } else { return unless check_matrix_dimensions(\%param, \%default); unless($param{transpose} =~ /^[01]$/) { module_warn("Parameter 'transpose' must be either 0 or 1 (got '$param{transpose}')"); return; } unless($param{dist} =~ /^[cauxskeb]$/) { module_warn("Parameter 'dist' must be one of: [cauxskeb] (got '$param{dist}')"); return; } unless($param{method} =~ /^[smca]$/) { module_warn("Parameter 'method' must be one of [smca] (got '$param{method}')"); return; } } #---------------------------------- # Invoke the library function # return _treecluster(@param{ qw/nrows ncols data mask weight transpose dist method/ }); } #------------------------------------------------------------- # Wrapper for the clusterdistance() function # sub clusterdistance { #---------------------------------- # Define default parameters # my %default = ( data => [[]], mask => '', weight => '', cluster1 => [], cluster2 => [], dist => 'e', method => 'a', transpose => 0, ); #---------------------------------- # Accept parameters from caller # my %param = (%default, @_); #---------------------------------- # Check the cluster1 and cluster2 arrays # if($param{cluster1} =~ /^\d+$/) { $param{cluster1} = [int($param{cluster1})]; } elsif(ref $param{cluster1} ne 'ARRAY') { module_warn("Parameter 'cluster1' does not point to an array. Cannot compute distance."); return; } elsif(@{ $param{cluster1}} <= 0) { module_warn("Parameter 'cluster1' points to an empty array. Cannot compute distance."); return; } if($param{cluster2} =~ /^\d+$/) { $param{cluster2} = [int($param{cluster2})]; } elsif(ref $param{cluster2} ne 'ARRAY') { module_warn("Parameter 'cluster2' does not point to an array. Cannot compute distance."); return; } elsif(@{ $param{cluster2}} <= 0) { module_warn("Parameter 'cluster2' points to an empty array. Cannot compute distance."); return; } $param{cluster1_len} = @{ $param{cluster1}}; $param{cluster2_len} = @{ $param{cluster2}}; #---------------------------------- # Check the data, matrix and weight parameters # return unless check_matrix_dimensions(\%param, \%default); #---------------------------------- # Check the other parameters # unless($param{transpose} =~ /^[01]$/) { module_warn("Parameter 'transpose' must be either 0 or 1 (got '$param{transpose}')"); return; } unless($param{method} =~ /^[amsxv]$/) { module_warn("Parameter 'method' must be 'a', 'm', 's', 'x', or 'v' (got '$param{method}')"); return; } unless($param{dist} =~ /^[cauxskeb]$/) { module_warn("Parameter 'dist' must be one of: [cauxskeb] (got '$param{dist}')"); return; } #---------------------------------- # Invoke the library function # return _clusterdistance(@param{ qw/nrows ncols data mask weight cluster1_len cluster2_len cluster1 cluster2 dist method transpose/ }); } #------------------------------------------------------------- # Wrapper for the clustercentroids() function # sub clustercentroids { #---------------------------------- # Define default parameters # my %default = ( data => [[]], mask => '', clusterid => [], method => 'a', transpose => 0, ); #---------------------------------- # Accept parameters from caller # my %param = (%default, @_); #---------------------------------- # Check the data, matrix and weight parameters # return unless check_matrix_dimensions(\%param, \%default); #---------------------------------- # Check the other parameters # unless($param{transpose} =~ /^[01]$/) { module_warn("Parameter 'transpose' must be either 0 or 1 (got '$param{transpose}')"); return; } unless($param{method} =~ /^[am]$/) { module_warn("Parameter 'method' must be 'a' or 'm' (got '$param{method}')"); return; } #---------------------------------- # Check the clusterid arrays # if($param{clusterid} =~ /^\d+$/) { $param{clusterid} = [int($param{clusterid})]; } elsif(ref $param{clusterid} ne 'ARRAY') { module_warn("Parameter 'clusterid' does not point to an array. Cannot compute distance."); return; } elsif(@{ $param{clusterid}} <= 0) { module_warn("Parameter 'clusterid' points to an empty array. Cannot compute distance."); return; } my $clusterid_len = @{ $param{clusterid}}; my $nrows = $param{nrows}; my $ncols = $param{ncols}; if ($param{transpose}==0 and $clusterid_len != $nrows) { die "Parameter 'clusterid' should have a size of $nrows; found $clusterid_len"; } elsif ($param{transpose}==1 and $clusterid_len != $ncols) { die "Parameter 'clusterid' should have a size of $ncols; found $clusterid_len"; } my $nclusters = -1; foreach (@{$param{clusterid}}) { if ($_ > $nclusters) { $nclusters = $_; } } $param{nclusters} = $nclusters + 1; #---------------------------------- # Invoke the library function # return _clustercentroids(@param{ qw/nclusters nrows ncols data mask clusterid transpose method/ }); } #------------------------------------------------------------- # Wrapper for the distancematrix() function # sub distancematrix { #---------------------------------- # Define default parameters # my %default = ( data => [[]], mask => '', weight => '', dist => 'e', transpose => 0, ); #---------------------------------- # Accept parameters from caller # my %param = (%default, @_); #---------------------------------- # Check the data, matrix and weight parameters # return unless check_matrix_dimensions(\%param, \%default); #---------------------------------- # Check the transpose parameter # unless($param{transpose} =~ /^[01]$/) { module_warn("Parameter 'transpose' must be either 0 or 1 (got '$param{transpose}')"); return; } #---------------------------------- # Check the other parameters # unless($param{dist} =~ /^[cauxskeb]$/) { module_warn("Parameter 'dist' must be one of: [cauxskeb] (got '$param{dist}')"); return; } #---------------------------------- # Invoke the library function # return _distancematrix(@param{ qw/nrows ncols data mask weight transpose dist/ }); } #------------------------------------------------------------- # Wrapper for the somcluster() function # sub somcluster { #---------------------------------- # Define default parameters # my %default = ( data => [[]], mask => '', weight => '', transpose => 0, nxgrid => 10, nygrid => 10, inittau => 0.02, niter => 100, dist => 'e', ); #---------------------------------- # Accept parameters from caller # my %param = (%default, @_); #---------------------------------- # Check the data, matrix and weight parameters # return unless check_matrix_dimensions(\%param, \%default); #---------------------------------- # Check the other parameters # unless($param{transpose} =~ /^[01]$/) { module_warn("Parameter 'transpose' must be either 0 or 1 (got '$param{transpose}')"); return; } unless($param{nxgrid} =~ /^\d+$/ and $param{nxgrid} > 0) { module_warn("Parameter 'nxgrid' must be a positive integer (got '$param{nxgrid}')"); return; } unless($param{nygrid} =~ /^\d+$/ and $param{nygrid} > 0) { module_warn("Parameter 'nygrid' must be a positive integer (got '$param{nygrid}')"); return; } unless($param{inittau} =~ /^\d+.\d+$/ and $param{inittau} >= 0.0) { module_warn("Parameter 'inittau' must be a non-negative number (got '$param{inittau}')"); return; } unless($param{niter} =~ /^\d+$/ and $param{niter} > 0) { module_warn("Parameter 'niter' must be a positive integer (got '$param{niter}')"); return; } unless($param{dist} =~ /^[cauxskeb]$/) { module_warn("Parameter 'dist' must be one of: [cauxskeb] (got '$param{dist}')"); return; } #---------------------------------- # Invoke the library function # return _somcluster(@param{ qw/nrows ncols data mask weight transpose nxgrid nygrid inittau niter dist/ }); } #------------------------------------------------------------- # Wrapper for the pca() function # sub pca { #---------------------------------- # Accept parameters from caller # my $data = shift; #---------------------------------- # Check the data matrix # return unless data_is_valid_matrix($data); #---------------------------------- # Remember the dimensions of the data array # my $nrows = scalar @{$data}; my $ncols = scalar @{$data->[0]}; #---------------------------------- # Invoke the library function return _pca($nrows, $ncols, $data); } 1; __END__ =head1 NAME Algorithm::Cluster - Perl interface to the C Clustering Library. =head1 DESCRIPTION This module is an interface to the C Clustering Library, a general purpose library implementing functions for hierarchical clustering (pairwise simple, complete, average, and centroid linkage), along with k-means and k-medians clustering, and 2D self-organizing maps. This library was developed at the Human Genome Center of the University of Tokyo. The C Clustering Library is distributed along with Cluster 3.0, an enhanced version of the famous Cluster program originally written by Michael Eisen while at Stanford University. =head1 EXAMPLES See the scripts in the examples subdirectory of the package. =head1 CHANGES =over 4 =item * C Clustering Library version 1.52 (2013.08.03) =head1 TO DO =over =head1 THANKS Thanks to Michael Eisen, for creating the software packages Cluster and TreeView. =head1 AUTHOR John Nolan jpnolan@sonic.net 2003. Michiel de Hoon mdehoon "AT" gsc.riken.jp 2003-2010. Seiya Imoto imoto "AT" ims.u-tokyo.ac.jp 2003-2010. Satoru Miyano 2003-2010. A copyright statement is contained in the source code itself. This module is a Perl wrapper for the C clustering library for cDNA microarray data, Copyright (C) 2002 Michiel Jan Laurens de Hoon. See the source of Cluster.pm for a full copyright statement. =cut 1; cluster-1.52a/perl/Artistic.txt0000644000100500010050000001414210443113626016400 0ustar mdehoonmdehoon The "Artistic License" Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder as specified below. "Copyright Holder" is whoever is named in the copyright or copyrights for the package. "You" is you, if you're thinking about copying or distributing this Package. "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as uunet.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) give non-standard executables non-standard names, and clearly document the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. You may embed this Package's interpreter within an executable of yours (by linking); this shall be construed as a mere form of aggregation, provided that the complete Standard Version of the interpreter is so embedded. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whoever generated them, and may be sold commercially, and may be aggregated with this Package. If such scripts or library files are aggregated with this Package via the so-called "undump" or "unexec" methods of producing a binary executable image, then distribution of such an image shall neither be construed as a distribution of this Package nor shall it fall under the restrictions of Paragraphs 3 and 4, provided that you do not represent such an executable image as a Standard Version of this Package. 7. C subroutines (or comparably compiled subroutines in other languages) supplied by you and linked into this Package in order to emulate subroutines and variables of the language defined by this Package shall not be considered part of this Package, but are the equivalent of input as in Paragraph 6, provided these subroutines do not change the language in any way that would cause it to fail the regression tests for the language. 8. Aggregation of this Package with a commercial distribution is always permitted provided that the use of this Package is embedded; that is, when no overt attempt is made to make this Package's interfaces visible to the end user of the commercial distribution. Such use shall not be construed as a distribution of this Package. 9. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End cluster-1.52a/perl/t/0000755000100500010050000000000012177164023014321 5ustar mdehoonmdehooncluster-1.52a/perl/t/01_mean_median.t0000644000100500010050000000123011200522131017217 0ustar mdehoonmdehoonuse Test::More tests => 6; use lib '../blib/lib','../blib/arch'; use_ok ("Algorithm::Cluster"); require_ok ("Algorithm::Cluster"); ######################### #------------------------------------------------------ # Tests # my ($meanval, $medianval); my $dummy; my $dummy_ref = \$dummy; my $dummy_sub_ref = sub {}; my $data1 = [ 34.3, 3, 2 ]; my $data2 = [ 5, 10 ,15, 20 ]; is (sprintf ("%7.4f", Algorithm::Cluster::mean($data1)), '13.1000'); is (sprintf ("%7.4f", Algorithm::Cluster::mean($data2)), '12.5000'); is (sprintf ("%7.4f", Algorithm::Cluster::median($data1)), ' 3.0000'); is (sprintf ("%7.4f", Algorithm::Cluster::median($data2)), '12.5000'); cluster-1.52a/perl/t/12_treecluster.t0000644000100500010050000003062211245631541017353 0ustar mdehoonmdehoonuse Test::More tests => 224; use lib '../blib/lib','../blib/arch'; use_ok ("Algorithm::Cluster"); require_ok ("Algorithm::Cluster"); ######################### #------------------------------------------------------ # Data for Tests # #---------- # dataset 1 # my $weight1 = [ 1,1,1,1,1 ]; my $data1 = [ [ 1.1, 2.2, 3.3, 4.4, 5.5, ], [ 3.1, 3.2, 1.3, 2.4, 1.5, ], [ 4.1, 2.2, 0.3, 5.4, 0.5, ], [ 12.1, 2.0, 0.0, 5.0, 0.0, ], ]; my $mask1 = [ [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], ]; #---------- # dataset 2 # my $weight2 = [ 1,1 ]; my $data2 = [ [ 0.8223, 0.9295 ], [ 1.4365, 1.3223 ], [ 1.1623, 1.5364 ], [ 2.1826, 1.1934 ], [ 1.7763, 1.9352 ], [ 1.7215, 1.9912 ], [ 2.1812, 5.9935 ], [ 5.3290, 5.9452 ], [ 3.1491, 3.3454 ], [ 5.1923, 5.3156 ], [ 4.7735, 5.4012 ], [ 5.1297, 5.5645 ], [ 5.3934, 5.1823 ], ]; my $mask2 = [ [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], ]; #------------------------------------------------------ # Tests # my $tree; my $node; #---------- # test dataset 1 # #--------------[PALcluster]------- my %params = ( transpose => 0, method => 'a', dist => 'e', data => $data1, mask => $mask1, weight => $weight1, ); $tree = Algorithm::Cluster::treecluster(%params); # Make sure that @clusters and @centroids are the right length is (scalar(@$data1) - 1, $tree->length ); $node = $tree->get(0); is ($node->left, 2); is ($node->right, 1); is (sprintf("%7.3f", $node->distance), " 2.600"); $node = $tree->get(1); is ($node->left, -1); is ($node->right, 0); is (sprintf("%7.3f", $node->distance), " 7.300"); $node = $tree->get(2); is ($node->left, 3); is ($node->right, -2); is (sprintf("%7.3f", $node->distance), " 21.348"); #--------------[PSLcluster]------- $params{method} = 's'; $tree = Algorithm::Cluster::treecluster(%params); # Make sure that @clusters and @centroids are the right length is (scalar(@$data1) - 1, $tree->length ); $node = $tree->get(0); is ($node->left, 1); is ($node->right, 2); is (sprintf("%7.3f", $node->distance), " 2.600"); $node = $tree->get(1); is ($node->left, 0); is ($node->right, -1); is (sprintf("%7.3f", $node->distance), " 5.800"); $node = $tree->get(2); is ($node->left, -2); is ($node->right, 3); is (sprintf("%7.3f", $node->distance), " 12.908"); #--------------[PCLcluster]------- $params{method} = 'c'; $tree = Algorithm::Cluster::treecluster(%params); # Make sure that @clusters and @centroids are the right length is (scalar(@$data1) - 1, $tree->length ); $node = $tree->get(0); is ($node->left, 1); is ($node->right, 2); is (sprintf("%7.3f", $node->distance), " 2.600"); $node = $tree->get(1); is ($node->left, 0); is ($node->right, -1); is (sprintf("%7.3f", $node->distance), " 6.650"); $node = $tree->get(2); is ($node->left, -2); is ($node->right, 3); is (sprintf("%7.3f", $node->distance), " 19.437"); #--------------[PMLcluster]------- $params{method} = 'm'; $tree = Algorithm::Cluster::treecluster(%params); # Make sure that @clusters and @centroids are the right length is (scalar(@$data1) - 1, $tree->length ); $node = $tree->get(0); is ($node->left, 2); is ($node->right, 1); is (sprintf("%7.3f", $node->distance), " 2.600"); $node = $tree->get(1); is ($node->left, -1); is ($node->right, 0); is (sprintf("%7.3f", $node->distance), " 8.800"); $node = $tree->get(2); is ($node->left, 3); is ($node->right, -2); is (sprintf("%7.3f", $node->distance), " 32.508"); #---------- # test dataset 2 # #--------------[PALcluster]------- %params = ( transpose => 0, method => 'a', dist => 'e', data => $data2, mask => $mask2, weight => $weight2, ); $tree = Algorithm::Cluster::treecluster(%params); # Make sure that @clusters and @centroids are the right length is (scalar(@$data2) - 1, $tree->length); $node = $tree->get(0); is ($node->left, 5); is ($node->right, 4); is (sprintf("%7.3f", $node->distance), " 0.003"); $node = $tree->get(1); is ($node->left, 9); is ($node->right, 12); is (sprintf("%7.3f", $node->distance), " 0.029"); $node = $tree->get(2); is ($node->left, 2); is ($node->right, 1); is (sprintf("%7.3f", $node->distance), " 0.061"); $node = $tree->get(3); is ($node->left, 11); is ($node->right, -2); is (sprintf("%7.3f", $node->distance), " 0.070"); $node = $tree->get(4); is ($node->left, -4); is ($node->right, 10); is (sprintf("%7.3f", $node->distance), " 0.128"); $node = $tree->get(5); is ($node->left, 7); is ($node->right, -5); is (sprintf("%7.3f", $node->distance), " 0.224"); $node = $tree->get(6); is ($node->left, -3); is ($node->right, 0); is (sprintf("%7.3f", $node->distance), " 0.254"); $node = $tree->get(7); is ($node->left, -1); is ($node->right, 3); is (sprintf("%7.3f", $node->distance), " 0.391"); $node = $tree->get(8); is ($node->left, -8); is ($node->right, -7); is (sprintf("%7.3f", $node->distance), " 0.532"); $node = $tree->get(9); is ($node->left, 8); is ($node->right, -9); is (sprintf("%7.3f", $node->distance), " 3.234"); $node = $tree->get(10); is ($node->left, -6); is ($node->right, 6); is (sprintf("%7.3f", $node->distance), " 4.636"); $node = $tree->get(11); is ($node->left, -11); is ($node->right, -10); is (sprintf("%7.3f", $node->distance), " 12.741"); #--------------[PSLcluster]------- $params{method} = 's'; $tree = Algorithm::Cluster::treecluster(%params); # Make sure that @clusters and @centroids are the right length is (scalar(@$data2) - 1, $tree->length ); $node = $tree->get(0); is ($node->left, 4); is ($node->right, 5); is (sprintf("%7.3f", $node->distance), " 0.003"); $node = $tree->get(1); is ($node->left, 9); is ($node->right, 12); is (sprintf("%7.3f", $node->distance), " 0.029"); $node = $tree->get(2); is ($node->left, 11); is ($node->right, -2); is (sprintf("%7.3f", $node->distance), " 0.033"); $node = $tree->get(3); is ($node->left, 1); is ($node->right, 2); is (sprintf("%7.3f", $node->distance), " 0.061"); $node = $tree->get(4); is ($node->left, 10); is ($node->right, -3); is (sprintf("%7.3f", $node->distance), " 0.077"); $node = $tree->get(5); is ($node->left, 7); is ($node->right, -5); is (sprintf("%7.3f", $node->distance), " 0.092"); $node = $tree->get(6); is ($node->left, 0); is ($node->right, -4); is (sprintf("%7.3f", $node->distance), " 0.242"); $node = $tree->get(7); is ($node->left, -7); is ($node->right, -1); is (sprintf("%7.3f", $node->distance), " 0.246"); $node = $tree->get(8); is ($node->left, 3); is ($node->right, -8); is (sprintf("%7.3f", $node->distance), " 0.287"); $node = $tree->get(9); is ($node->left, -9); is ($node->right, 8); is (sprintf("%7.3f", $node->distance), " 1.936"); $node = $tree->get(10); is ($node->left, -10); is ($node->right, -6); is (sprintf("%7.3f", $node->distance), " 3.432"); $node = $tree->get(11); is ($node->left, 6); is ($node->right, -11); is (sprintf("%7.3f", $node->distance), " 3.535"); #--------------[PCLcluster]------- $params{method} = 'c'; $tree = Algorithm::Cluster::treecluster(%params); # Make sure that @clusters and @centroids are the right length is (scalar(@$data2) - 1, $tree->length ); $node = $tree->get(0); is ($node->left, 4); is ($node->right, 5); is (sprintf("%7.3f", $node->distance), " 0.003"); $node = $tree->get(1); is ($node->left, 12); is ($node->right, 9); is (sprintf("%7.3f", $node->distance), " 0.029"); $node = $tree->get(2); is ($node->left, 1); is ($node->right, 2); is (sprintf("%7.3f", $node->distance), " 0.061"); $node = $tree->get(3); is ($node->left, -2); is ($node->right, 11); is (sprintf("%7.3f", $node->distance), " 0.063"); $node = $tree->get(4); is ($node->left, 10); is ($node->right, -4); is (sprintf("%7.3f", $node->distance), " 0.109"); $node = $tree->get(5); is ($node->left, -5); is ($node->right, 7); is (sprintf("%7.3f", $node->distance), " 0.189"); $node = $tree->get(6); is ($node->left, 0); is ($node->right, -3); is (sprintf("%7.3f", $node->distance), " 0.239"); $node = $tree->get(7); is ($node->left, 3); is ($node->right, -1); is (sprintf("%7.3f", $node->distance), " 0.390"); $node = $tree->get(8); is ($node->left, -7); is ($node->right, -8); is (sprintf("%7.3f", $node->distance), " 0.382"); $node = $tree->get(9); is ($node->left, -9); is ($node->right, 8); is (sprintf("%7.3f", $node->distance), " 3.063"); $node = $tree->get(10); is ($node->left, 6); is ($node->right, -6); is (sprintf("%7.3f", $node->distance), " 4.578"); $node = $tree->get(11); is ($node->left, -10); is ($node->right, -11); is (sprintf("%7.3f", $node->distance), " 11.536"); #--------------[PMLcluster]------- $params{method} = 'm'; $tree = Algorithm::Cluster::treecluster(%params); # Make sure that @clusters and @centroids are the right length is ( scalar(@$data2) - 1, $tree->length ); $node = $tree->get(0); is ($node->left, 5); is ($node->right, 4); is (sprintf("%7.3f", $node->distance), " 0.003"); $node = $tree->get(1); is ($node->left, 9); is ($node->right, 12); is (sprintf("%7.3f", $node->distance), " 0.029"); $node = $tree->get(2); is ($node->left, 2); is ($node->right, 1); is (sprintf("%7.3f", $node->distance), " 0.061"); $node = $tree->get(3); is ($node->left, 11); is ($node->right, 10); is (sprintf("%7.3f", $node->distance), " 0.077"); $node = $tree->get(4); is ($node->left, -2); is ($node->right, -4); is (sprintf("%7.3f", $node->distance), " 0.216"); $node = $tree->get(5); is ($node->left, -3); is ($node->right, 0); is (sprintf("%7.3f", $node->distance), " 0.266"); $node = $tree->get(6); is ($node->left, -5); is ($node->right, 7); is (sprintf("%7.3f", $node->distance), " 0.302"); $node = $tree->get(7); is ($node->left, -1); is ($node->right, 3); is (sprintf("%7.3f", $node->distance), " 0.425"); $node = $tree->get(8); is ($node->left, -8); is ($node->right, -6); is (sprintf("%7.3f", $node->distance), " 0.968"); $node = $tree->get(9); is ($node->left, 8); is ($node->right, 6); is (sprintf("%7.3f", $node->distance), " 3.975"); $node = $tree->get(10); is ($node->left, -10); is ($node->right, -7); is (sprintf("%7.3f", $node->distance), " 5.755"); $node = $tree->get(11); is ($node->left, -11); is ($node->right, -9); is (sprintf("%7.3f", $node->distance), " 22.734"); #-------[treecluster on a distance matrix]------------ my $matrix = [ [], [ 3.4], [ 4.3, 10.1], [ 3.7, 11.5, 1.0], [ 1.6, 4.1, 3.4, 3.4], [10.1, 20.5, 2.5, 2.7, 9.8], [ 2.5, 3.7, 3.1, 3.6, 1.1, 10.1], [ 3.4, 2.2, 8.8, 8.7, 3.3, 16.6, 2.7], [ 2.1, 7.7, 2.7, 1.9, 1.8, 5.7, 3.4, 5.2], [ 1.4, 1.7, 9.2, 8.7, 3.4, 16.8, 4.2, 1.3, 5.0], [ 2.7, 3.7, 5.5, 5.5, 1.9, 11.5, 2.0, 1.5, 2.1, 3.1], [10.0, 19.3, 2.2, 3.7, 9.1, 1.2, 9.3, 15.7, 6.3, 16.0, 11.5] ]; %params = ( method => 's', data => $matrix, ); $tree = Algorithm::Cluster::treecluster(%params); # Make sure that @clusters and @centroids are the right length is ( scalar(@$matrix) - 1, $tree->length ); $node = $tree->get(0); is ($node->left, 2); is ($node->right, 3); is (sprintf("%7.3f", $node->distance), " 1.000"); $node = $tree->get(1); is ($node->left, 4); is ($node->right, 6); is (sprintf("%7.3f", $node->distance), " 1.100"); $node = $tree->get(2); is ($node->left, 5); is ($node->right, 11); is (sprintf("%7.3f", $node->distance), " 1.200"); $node = $tree->get(3); is ($node->left, 7); is ($node->right, 9); is (sprintf("%7.3f", $node->distance), " 1.300"); $node = $tree->get(4); is ($node->left, 0); is ($node->right, -4); is (sprintf("%7.3f", $node->distance), " 1.400"); $node = $tree->get(5); is ($node->left, -5); is ($node->right, 10); is (sprintf("%7.3f", $node->distance), " 1.500"); $node = $tree->get(6); is ($node->left, -2); is ($node->right, -6); is (sprintf("%7.3f", $node->distance), " 1.600"); $node = $tree->get(7); is ($node->left, 1); is ($node->right, -7); is (sprintf("%7.3f", $node->distance), " 1.700"); $node = $tree->get(8); is ($node->left, 8); is ($node->right, -8); is (sprintf("%7.3f", $node->distance), " 1.800"); $node = $tree->get(9); is ($node->left, -1); is ($node->right, -9); is (sprintf("%7.3f", $node->distance), " 1.900"); $node = $tree->get(10); is ($node->left, -10); is ($node->right, -3); is (sprintf("%7.3f", $node->distance), " 2.200"); cluster-1.52a/perl/t/14_kmedoids.t0000644000100500010050000000535311504675234016623 0ustar mdehoonmdehoonuse Test::More tests => 30; use lib '../blib/lib','../blib/arch'; use_ok ("Algorithm::Cluster"); require_ok ("Algorithm::Cluster"); ######################### #------------------------------------------------------ # Data for Tests # #---------- # dataset 1 # my $matrix = [ [], [ 3.4], [ 4.3, 10.1], [ 3.7, 11.5, 1.1], [ 1.7, 4.1, 3.4, 3.4], [10.1, 20.5, 2.5, 2.7, 9.8], [ 2.5, 3.7, 3.1, 3.6, 1.1, 10.1], [ 3.4, 2.2, 8.8, 8.7, 3.3, 16.6, 2.7], [ 2.1, 7.7, 2.7, 1.9, 1.8, 5.7, 3.4, 5.2], [ 1.6, 1.8, 9.2, 8.7, 3.4, 16.8, 4.2, 1.3, 5.0], [ 2.7, 3.7, 5.5, 5.5, 1.9, 11.5, 2.0, 1.7, 2.1, 3.1], [10.0, 19.3, 1.0, 3.7, 9.1, 1.2, 9.3, 15.7, 6.3, 16.0, 11.5] ]; #------------------------------------------------------ # Tests # my ($clusters, $error, $found); #------------------------------------------------------ # Test with repeated runs of the k-medoids algorithm # my %params1 = ( nclusters => 4, distances => $matrix, npass => 10000, ); ($clusters, $error, $found) = Algorithm::Cluster::kmedoids(%params1); #---------- # Make sure that the length of @clusters matches the length of @data is (scalar @$matrix, scalar @$clusters ); #---------- # Test the cluster assignments is ($clusters->[ 0], 9); is ($clusters->[ 1], 9); is ($clusters->[ 2], 2); is ($clusters->[ 3], 2); is ($clusters->[ 4], 4); is ($clusters->[ 5], 5); is ($clusters->[ 6], 4); is ($clusters->[ 7], 9); is ($clusters->[ 8], 4); is ($clusters->[ 9], 9); is ($clusters->[10], 4); is ($clusters->[11], 2); # Test the within-cluster sum of errors is (sprintf ("%7.3f", $error), ' 11.600'); #------------------------------------------------------ # Test the k-medoids algorithm with a specified initial clustering # $initialid = [0,0,1,1,1,2,2,2,3,3,3,3]; my %params2 = ( nclusters => 4, distances => $matrix, npass => 1, initialid => $initialid, ); ($clusters, $error, $found) = Algorithm::Cluster::kmedoids(%params2); #---------- # Make sure that the length of @clusters matches the length of @data is (scalar @$matrix, scalar @$clusters ); #---------- # Test the cluster assignments is ($clusters->[ 0], 9); is ($clusters->[ 1], 9); is ($clusters->[ 2], 2); is ($clusters->[ 3], 2); is ($clusters->[ 4], 4); is ($clusters->[ 5], 2); is ($clusters->[ 6], 6); is ($clusters->[ 7], 9); is ($clusters->[ 8], 4); is ($clusters->[ 9], 9); is ($clusters->[10], 4); is ($clusters->[11], 2); # Test the within-cluster sum of errors is (sprintf ("%7.3f", $error), " 13.000"); cluster-1.52a/perl/t/16_pca.t0000644000100500010050000001145511356303056015564 0ustar mdehoonmdehoonuse Test::More tests => 74; use lib '../blib/lib','../blib/arch'; use_ok ("Algorithm::Cluster"); require_ok ("Algorithm::Cluster"); use warnings; ######################### #------------------------------------------------------ # Tests # my ($mean, $coordinates, $pc, $eigenvalues); my $data1 = [ [ 3.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ], ]; my $data2 = [ [ 2.3, 4.5, 1.2, 6.7, 5.3, 7.1], [ 1.3, 6.5, 2.2, 5.7, 6.2, 9.1], [ 3.2, 7.2, 3.2, 7.4, 7.3, 8.9], [ 4.2, 5.2, 9.2, 4.4, 6.3, 7.2], ]; ($mean, $coordinates, $pc, $eigenvalues) = Algorithm::Cluster::pca($data1); is (sprintf("%7.4f", $mean->[0]), " 3.5462"); is (sprintf("%7.4f", $mean->[1]), " 3.5308"); is (sprintf("%7.4f", $coordinates->[0][0]), " 2.0323"); is (sprintf("%7.4f", $coordinates->[0][1]), " 1.2252"); is (sprintf("%7.4f", $coordinates->[1][0]), " 3.0937"); is (sprintf("%7.4f", $coordinates->[1][1]), "-0.1065"); is (sprintf("%7.4f", $coordinates->[2][0]), " 3.1453"); is (sprintf("%7.4f", $coordinates->[2][1]), "-0.4633"); is (sprintf("%7.4f", $coordinates->[3][0]), " 2.5440"); is (sprintf("%7.4f", $coordinates->[3][1]), " 0.2063"); is (sprintf("%7.4f", $coordinates->[4][0]), " 2.4468"); is (sprintf("%7.4f", $coordinates->[4][1]), "-0.2841"); is (sprintf("%7.4f", $coordinates->[5][0]), " 2.4468"); is (sprintf("%7.4f", $coordinates->[5][1]), "-0.2841"); is (sprintf("%7.4f", $coordinates->[6][0]), "-3.2019"); is (sprintf("%7.4f", $coordinates->[6][1]), " 0.0197"); is (sprintf("%7.4f", $coordinates->[7][0]), "-3.2019"); is (sprintf("%7.4f", $coordinates->[7][1]), " 0.0197"); is (sprintf("%7.4f", $coordinates->[8][0]), " 0.4698"); is (sprintf("%7.4f", $coordinates->[8][1]), "-0.1778"); is (sprintf("%7.4f", $coordinates->[9][0]), "-2.5550"); is (sprintf("%7.4f", $coordinates->[9][1]), " 0.1973"); is (sprintf("%7.4f", $coordinates->[10][0]), "-2.5034"); is (sprintf("%7.4f", $coordinates->[10][1]), "-0.1595"); is (sprintf("%7.4f", $coordinates->[11][0]), "-2.4366"); is (sprintf("%7.4f", $coordinates->[11][1]), "-0.2339"); is (sprintf("%7.4f", $coordinates->[12][0]), "-2.2802"); is (sprintf("%7.4f", $coordinates->[12][1]), " 0.0409"); is (sprintf("%7.4f", $pc->[0][0]), "-0.6681"); is (sprintf("%7.4f", $pc->[0][1]), "-0.7441"); is (sprintf("%7.4f", $pc->[1][0]), " 0.7441"); is (sprintf("%7.4f", $pc->[1][1]), "-0.6681"); is (sprintf("%7.4f", $eigenvalues->[0]), " 9.3110"); is (sprintf("%7.4f", $eigenvalues->[1]), " 1.4437"); ($mean, $coordinates, $pc, $eigenvalues) = Algorithm::Cluster::pca($data2); is (sprintf("%7.4f", $mean->[0]), " 2.7500"); is (sprintf("%7.4f", $mean->[1]), " 5.8500"); is (sprintf("%7.4f", $mean->[2]), " 3.9500"); is (sprintf("%7.4f", $mean->[3]), " 6.0500"); is (sprintf("%7.4f", $mean->[4]), " 6.2750"); is (sprintf("%7.4f", $mean->[5]), " 8.0750"); is (sprintf("%7.4f", $coordinates->[0][0]), " 2.6461"); is (sprintf("%7.4f", $coordinates->[0][1]), "-2.1422"); is (sprintf("%7.4f", $coordinates->[0][2]), "-0.5662"); is (sprintf("%7.4f", abs($coordinates->[0][3])), " 0.0000"); is (sprintf("%7.4f", $coordinates->[1][0]), " 2.0644"); is (sprintf("%7.4f", $coordinates->[1][1]), " 0.5554"); is (sprintf("%7.4f", $coordinates->[1][2]), " 1.4819"); is (sprintf("%7.4f", abs($coordinates->[1][3])), " 0.0000"); is (sprintf("%7.4f", $coordinates->[2][0]), " 1.0687"); is (sprintf("%7.4f", $coordinates->[2][1]), " 1.9994"); is (sprintf("%7.4f", $coordinates->[2][2]), "-1.0007"); is (sprintf("%7.4f", abs($coordinates->[2][3])), " 0.0000"); is (sprintf("%7.4f", $coordinates->[3][0]), "-5.7792"); is (sprintf("%7.4f", $coordinates->[3][1]), "-0.4127"); is (sprintf("%7.4f", $coordinates->[3][2]), " 0.0851"); is (sprintf("%7.4f", abs($coordinates->[3][3])), " 0.0000"); is (sprintf("%7.4f", $pc->[0][0]), "-0.2638"); is (sprintf("%7.4f", $pc->[0][1]), " 0.0648"); is (sprintf("%7.4f", $pc->[0][2]), "-0.9176"); is (sprintf("%7.4f", $pc->[0][3]), " 0.2615"); is (sprintf("%7.4f", $pc->[1][0]), " 0.0507"); is (sprintf("%7.4f", $pc->[1][1]), " 0.6862"); is (sprintf("%7.4f", $pc->[1][2]), " 0.1382"); is (sprintf("%7.4f", $pc->[1][3]), " 0.1978"); is (sprintf("%7.4f", $pc->[2][0]), "-0.6300"); is (sprintf("%7.4f", $pc->[2][1]), " 0.0912"); is (sprintf("%7.4f", $pc->[2][2]), " 0.0456"); is (sprintf("%7.4f", $pc->[2][3]), "-0.6746"); # The last eigenvalue is zero. The corresponding eigenvector is strongly # affected by roundoff error, so we don't test it. For PCA, it doesn't matter # since the coordinates along this eigenvector are zero anyway. is (sprintf("%7.4f", $eigenvalues->[0]), " 6.7679"); is (sprintf("%7.4f", $eigenvalues->[1]), " 3.0109"); is (sprintf("%7.4f", $eigenvalues->[2]), " 1.8776"); is (sprintf("%7.4f", abs($eigenvalues->[3])), " 0.0000"); cluster-1.52a/perl/t/02_tree.t0000644000100500010050000000203011200471141015725 0ustar mdehoonmdehoonuse Test::More tests => 15; use lib '../blib/lib','../blib/arch'; use_ok ("Algorithm::Cluster"); require_ok ("Algorithm::Cluster"); ######################### #------------------------------------------------------ # Tests # my $node; my $node1 = Algorithm::Cluster::Node->new(1,2,3.1); my $node2 = Algorithm::Cluster::Node->new(-1,3,5.3); my $node3 = Algorithm::Cluster::Node->new(4,0,5.9); my $node4 = Algorithm::Cluster::Node->new(-2,-3,7.8); my @nodes = [$node1,$node2,$node3,$node4]; my $tree = Algorithm::Cluster::Tree->new(@nodes); is ($tree->length, 4); $node = $tree->get(0); is ($node->left, 1); is ($node->right, 2); is (sprintf ("%7.4f", $node->distance), ' 3.1000'); $node = $tree->get(1); is ($node->left, -1); is ($node->right, 3); is (sprintf ("%7.4f", $node->distance), ' 5.3000'); $node = $tree->get(2); is ($node->left, 4); is ($node->right, 0); is (sprintf ("%7.4f", $node->distance), ' 5.9000'); $node = $tree->get(3); is ($node->left, -2); is ($node->right, -3); is (sprintf ("%7.4f", $node->distance), ' 7.8000'); cluster-1.52a/perl/t/13_somcluster.t0000644000100500010050000000360711245631616017221 0ustar mdehoonmdehoonuse Test::More tests => 6; use lib '../blib/lib','../blib/arch'; use_ok ("Algorithm::Cluster"); require_ok ("Algorithm::Cluster"); ######################### #------------------------------------------------------ # Data for Tests # #---------- # dataset 1 # my $weight1 = [ 1,1,1,1,1 ]; my $data1 = [ [ 1.1, 2.2, 3.3, 4.4, 5.5, ], [ 3.1, 3.2, 1.3, 2.4, 1.5, ], [ 4.1, 2.2, 0.3, 5.4, 0.5, ], [ 12.1, 2.0, 0.0, 5.0, 0.0, ], ]; my $mask1 = [ [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], ]; #---------- # dataset 2 # my $weight2 = [ 1,1 ]; my $data2 = [ [ 1.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ], ]; my $mask2 = [ [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], ]; #------------------------------------------------------ # Tests # my ($clusterid); my %params; %params = ( transpose => 0, dist => 'e', data => $data1, mask => $mask1, weight => $weight1, niter => 100, nxnodes => 10, nynodes => 10, ); $clusterid = Algorithm::Cluster::somcluster(%params); is (scalar(@$data1), scalar(@$clusterid) ); is (scalar(@{$clusterid->[0]}), 2 ); %params = ( transpose => 0, dist => 'e', data => $data2, mask => $mask2, weight => $weight2, niter => 100, nxnodes => 10, nynodes => 10, ); $clusterid = Algorithm::Cluster::somcluster(%params); is (scalar(@$data2), scalar(@$clusterid) ); is (scalar(@{$clusterid->[0]}), 2 ); cluster-1.52a/perl/t/15_distancematrix.t0000644000100500010050000000450111245631730020031 0ustar mdehoonmdehoonuse Test::More tests => 20; use lib '../blib/lib','../blib/arch'; use_ok ("Algorithm::Cluster"); require_ok ("Algorithm::Cluster"); ######################### #------------------------------------------------------ # Data for Tests # #---------- # dataset # my $gweight = [ 1,1,1,1,1 ]; my $eweight = [ 1,1,1,1 ]; my $data = [ [ 1.1, 2.2, 3.3, 4.4, 5.5, ], [ 3.1, 3.2, 1.3, 2.4, 1.5, ], [ 4.1, 2.2, 0.3, 5.4, 0.5, ], [ 12.1, 2.0, 0.0, 5.0, 0.0, ], ]; my $mask = [ [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], ]; #------------------------------------------------------ # Tests # my $matrix; #---------- # test dataset with transpose==0 # $matrix = Algorithm::Cluster::distancematrix( transpose => 0, dist => 'e', data => $data, mask => $mask, weight => $gweight, ); #---------- # Make sure that the length of $matrix matches the length of @data1 is (scalar @$data, scalar @$matrix); #---------- # Test the values in the distance matrix is (sprintf ("%7.3f", $matrix->[1]->[0] ), ' 5.800'); is (sprintf ("%7.3f", $matrix->[2]->[0] ), ' 8.800'); is (sprintf ("%7.3f", $matrix->[2]->[1] ), ' 2.600'); is (sprintf ("%7.3f", $matrix->[3]->[0] ), ' 32.508'); is (sprintf ("%7.3f", $matrix->[3]->[1] ), ' 18.628'); is (sprintf ("%7.3f", $matrix->[3]->[2] ), ' 12.908'); #---------- # test dataset with transpose==1 # $matrix = Algorithm::Cluster::distancematrix( transpose => 1, dist => 'e', data => $data, mask => $mask, weight => $eweight, ); #---------- # Make sure that the length of $matrix matches the length of @data1 is (scalar @{$data->[0]}, scalar @$matrix ); #---------- # Test the values in the distance matrix is (sprintf ("%6.2f", $matrix->[1]->[0] ), ' 26.71'); is (sprintf ("%6.2f", $matrix->[2]->[0] ), ' 42.23'); is (sprintf ("%6.2f", $matrix->[2]->[1] ), ' 3.11'); is (sprintf ("%6.2f", $matrix->[3]->[0] ), ' 15.87'); is (sprintf ("%6.2f", $matrix->[3]->[1] ), ' 6.18'); is (sprintf ("%6.2f", $matrix->[3]->[2] ), ' 13.36'); is (sprintf ("%6.2f", $matrix->[4]->[0] ), ' 45.32'); is (sprintf ("%6.2f", $matrix->[4]->[1] ), ' 5.17'); is (sprintf ("%6.2f", $matrix->[4]->[2] ), ' 1.23'); is (sprintf ("%6.2f", $matrix->[4]->[3] ), ' 12.76'); cluster-1.52a/perl/t/10_kcluster.t0000644000100500010050000000663511245631272016654 0ustar mdehoonmdehoonuse Test::More tests => 28; use lib '../blib/lib','../blib/arch'; use_ok ("Algorithm::Cluster"); require_ok ("Algorithm::Cluster"); ######################### #------------------------------------------------------ # Data for Tests # #---------- # dataset 1 # my $weight1 = [ 1,1,1,1,1 ]; my $data1 = [ [ 1.1, 2.2, 3.3, 4.4, 5.5, ], [ 3.1, 3.2, 1.3, 2.4, 1.5, ], [ 4.1, 2.2, 0.3, 5.4, 0.5, ], [ 12.1, 2.0, 0.0, 5.0, 0.0, ], ]; my $mask1 = [ [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], ]; #---------- # dataset 2 # my $weight2 = [ 1,1 ]; my $data2 = [ [ 1.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ], ]; my $mask2 = [ [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], ]; #------------------------------------------------------ # Tests # my ($clusters, $centroids, $error, $found); my ($i,$j); my %params = ( nclusters => 3, transpose => 0, method => 'a', dist => 'e', ); #---------- # test dataset 1 # ($clusters, $error, $found) = Algorithm::Cluster::kcluster( %params, data => $data1, mask => $mask1, weight => $weight1, npass => 100, ); #---------- # Make sure that the length of @clusters matches the length of @data ok( scalar @$data1 == scalar @$clusters); #---------- # Test the cluster coordinates ok ( $clusters->[ 0] != $clusters->[ 1] ); ok ( $clusters->[ 1] == $clusters->[ 2] ); ok ( $clusters->[ 2] != $clusters->[ 3] ); # Test the within-cluster sum of errors ok( sprintf ("%7.3f", $error) == ' 1.300'); #---------- # test dataset 2 # $i=0;$j=0; ($clusters, $error, $found) = Algorithm::Cluster::kcluster( %params, data => $data2, mask => $mask2, weight => $weight2, npass => 100, ); #---------- # Make sure that the length of @clusters matches the length of @data ok (scalar @$data2 == scalar @$clusters); #---------- # Test the cluster coordinates ok ($clusters->[ 0] == $clusters->[ 3]); ok ($clusters->[ 0] != $clusters->[ 6]); ok ($clusters->[ 0] != $clusters->[ 9]); ok ($clusters->[11] == $clusters->[12]); # Test the within-cluster sum of errors ok ( sprintf ("%7.3f", $error) == ' 1.012'); #---------- # test kcluster with initial cluster assignments # $initialid = [0,1,2,0,1,2,0,1,2,0,1,2,0]; ($clusters, $error, $found) = Algorithm::Cluster::kcluster( %params, data => $data2, mask => $mask2, weight => $weight2, npass => 1, initialid => $initialid, ); #---------- # Test the cluster coordinates ok ( $clusters->[ 0] == 2 ); ok ( $clusters->[ 1] == 2 ); ok ( $clusters->[ 2] == 2 ); ok ( $clusters->[ 3] == 2 ); ok ( $clusters->[ 4] == 2 ); ok ( $clusters->[ 5] == 2 ); ok ( $clusters->[ 6] == 0 ); ok ( $clusters->[ 7] == 0 ); ok ( $clusters->[ 8] == 2 ); ok ( $clusters->[ 9] == 1 ); ok ( $clusters->[10] == 1 ); ok ( $clusters->[11] == 1 ); ok ( $clusters->[12] == 1 ); # Test the within-cluster sum of errors ok ( sprintf ("%7.3f", $error) == ' 3.036' ); ok ($found == 1 ); __END__ cluster-1.52a/perl/t/11_clusterdistance.t0000644000100500010050000000526611245631350020211 0ustar mdehoonmdehoonuse Test::More tests => 8; use lib '../blib/lib','../blib/arch'; use_ok ("Algorithm::Cluster"); require_ok ("Algorithm::Cluster"); ######################### #------------------------------------------------------ # Data for Tests # #---------- # dataset 1 # my $weight1 = [ 1,1,1,1,1 ]; my $data1 = [ [ 1.1, 2.2, 3.3, 4.4, 5.5, ], [ 3.1, 3.2, 1.3, 2.4, 1.5, ], [ 4.1, 2.2, 0.3, 5.4, 0.5, ], [ 12.1, 2.0, 0.0, 5.0, 0.0, ], ]; my $mask1 = [ [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], ]; my $data1_c1 = [ 0 ]; my $data1_c2 = [ 1,2 ]; my $data1_c3 = [ 3 ]; #---------- # dataset 2 # my $weight2 = [ 1,1 ]; my $data2 = [ [ 1.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ], ]; my $mask2 = [ [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], ]; my $data2_c1 = [ 0, 1, 2, 3 ]; my $data2_c2 = [ 4, 5, 6, 7 ]; my $data2_c3 = [ 8 ]; #------------------------------------------------------ # Tests # my $distance; #---------- # test dataset 1 # my %params = ( transpose => 0, method => 'a', dist => 'e', data => $data1, mask => $mask1, weight => $weight1, cluster1 => $data1_c1, cluster2 => $data1_c2, ); $distance = Algorithm::Cluster::clusterdistance(%params); is (sprintf ("%7.3f", $distance ), ' 6.650'); $params{cluster1} = $data1_c1; $params{cluster2} = $data1_c3; $distance = Algorithm::Cluster::clusterdistance(%params); is (sprintf ("%7.3f", $distance ), ' 32.508'); $params{cluster1} = $data1_c2; $params{cluster2} = $data1_c3; $distance = Algorithm::Cluster::clusterdistance(%params); is (sprintf ("%7.3f", $distance ), ' 15.118'); #---------- # test dataset 2 # %params = ( transpose => 0, method => 'a', dist => 'e', data => $data2, mask => $mask2, weight => $weight2, cluster1 => $data2_c1, cluster2 => $data2_c2, ); $distance = Algorithm::Cluster::clusterdistance(%params); is (sprintf ("%7.3f", $distance ), ' 5.833'); $params{cluster1} = $data2_c1; $params{cluster2} = $data2_c3; $distance = Algorithm::Cluster::clusterdistance(%params); is (sprintf ("%7.3f", $distance ), ' 3.298'); $params{cluster1} = $data2_c2; $params{cluster2} = $data2_c3; $distance = Algorithm::Cluster::clusterdistance(%params); is (sprintf ("%7.3f", $distance ), ' 0.360'); cluster-1.52a/perl/Cluster.xs0000644000100500010050000014061412177160200016052 0ustar mdehoonmdehoon#include "EXTERN.h" #include "perl.h" #include "XSUB.h" /* The Perl include files perl.h redefines malloc and free. Here, we need the * usual malloc and free, defined in stdlib.h. So we undefine the ones in * perl.h. */ #ifdef malloc #undef malloc #endif #ifdef free #undef free #endif #include #include "../src/cluster.h" typedef struct {Node* nodes; int n;} Tree; /* ------------------------------------------------- * Using the warnings registry, check to see if warnings * are enabled for the Algorithm::Cluster module. */ static int warnings_enabled(pTHX) { dSP; I32 count; bool isEnabled; SV * mysv; ENTER ; SAVETMPS; PUSHMARK(SP) ; XPUSHs(sv_2mortal(newSVpv("Algorithm::Cluster",18))); PUTBACK ; count = perl_call_pv("warnings::enabled", G_SCALAR) ; if (count != 1) croak("No arguments returned from call_pv()\n") ; mysv = POPs; isEnabled = (bool) SvTRUE(mysv); PUTBACK ; FREETMPS ; LEAVE ; return isEnabled; } /* ------------------------------------------------- * Create a row of doubles, initialized to a value */ static double* malloc_row_dbl(pTHX_ int ncols, double val) { int j; double * row; row = malloc(ncols * sizeof(double) ); if (!row) { return NULL; } for (j = 0; j < ncols; j++) { row[j] = val; } return row; } /* ------------------------------------------------- * Only coerce to a double if we already know it's * an integer or double, or a string which is actually numeric. * Don't blindly run the macro SvNV, because that will coerce * a non-numeric string to be a double of value 0.0, * and we do not want that to happen, because if we test it again, * it will then appear to be a valid double value. */ static int extract_double_from_scalar(pTHX_ SV * mysv, double * number) { if (SvPOKp(mysv) && SvLEN(mysv)) { /* This function is not in the public perl API */ if (Perl_looks_like_number(aTHX_ mysv)) { *number = SvNV( mysv ); return 1; } else { return 0; } } else if (SvNIOK(mysv)) { *number = SvNV( mysv ); return 1; } else { return 0; } } /* ------------------------------------------------- * Convert a Perl 2D matrix into a 2D matrix of C doubles. * If no data are masked, mask can be passed as NULL. * NOTE: on errors this function returns a value greater than zero. */ static double** parse_data(pTHX_ SV * matrix_ref, int** mask) { AV * matrix_av; SV * row_ref; AV * row_av; SV * cell; int type, i, j, nrows, ncols, n; double** matrix; /* NOTE -- we will just assume that matrix_ref points to an arrayref, * and that the first item in the array is itself an arrayref. * The calling perl functions must check this before we get this pointer. * (It's easier to implement these checks in Perl rather than C.) * The value of perl_rows is now fixed. But the value of * rows will be decremented, if we skip any (invalid) Perl rows. */ matrix_av = (AV *) SvRV(matrix_ref); nrows = (int) av_len(matrix_av) + 1; if(nrows <= 0) { return NULL; } matrix = malloc(nrows*sizeof(double*)); if (!matrix) { return NULL; } row_ref = *(av_fetch(matrix_av, (I32) 0, 0)); row_av = (AV *) SvRV(row_ref); ncols = (int) av_len(row_av) + 1; /* ------------------------------------------------------------ * Loop once for each row in the Perl matrix, and convert it to * C doubles. */ for (i=0; i < nrows; i++) { row_ref = *(av_fetch(matrix_av, (I32) i, 0)); if(! SvROK(row_ref) ) { if(warnings_enabled(aTHX)) Perl_warn(aTHX_ "Row %d: Wanted array reference, but " "got a scalar. No row to process?\n", i); break; } row_av = (AV *) SvRV(row_ref); type = SvTYPE(row_av); /* Handle unexpected cases */ if(type != SVt_PVAV ) { /* Reference doesn't point to an array at all. */ if(warnings_enabled(aTHX)) Perl_warn(aTHX_ "Row %d: Wanted array reference, but got " "a reference to something else (%d)\n", i, type); break; } n = (int) av_len(row_av) + 1; if (n != ncols) { /* All rows in the matrix should have the same * number of columns. */ if(warnings_enabled(aTHX)) Perl_warn(aTHX_ "Row %d: Contains %d columns " "(expected %d)\n", i, n, ncols); break; } matrix[i] = malloc(ncols*sizeof(double)); if (!matrix[i]) break; /* Loop once for each cell in the row. */ for (j=0; j < ncols; j++) { double num; if (!mask || mask[i][j]) { cell = *(av_fetch(row_av, (I32) j, 0)); if(extract_double_from_scalar(aTHX_ cell,&num) <= 0) { if(warnings_enabled(aTHX)) Perl_warn(aTHX_ "Row %d col %d: Value is not " "a number.\n", i, j); free(matrix[i]); /* not included below */ break; } } else { /* Don't read the value if it is masked. * Set it to some arbitrary value. */ num = 0.0; } matrix[i][j] = num; } /* End for (j=0; j < ncols; j++) */ if (j < ncols) break; } /* End for (i=0; i < nrows; i++) */ if (i < nrows) { /* encountered a break */ nrows = i; for (i = 0; i < nrows; i++) free(matrix[i]); free(matrix); matrix = NULL; } return matrix; } /* ------------------------------------------------- * Convert a Perl 2D matrix into a 2D matrix of C ints. * On errors this function returns a value greater than zero. */ static int** parse_mask(pTHX_ SV * matrix_ref) { AV * matrix_av; SV * row_ref; AV * row_av; SV * cell; int type, i, j, nrows, ncols, n; int** matrix; /* NOTE -- we will just assume that matrix_ref points to an arrayref, * and that the first item in the array is itself an arrayref. * The calling perl functions must check this before we get this pointer. * (It's easier to implement these checks in Perl rather than C.) * The value of perl_rows is now fixed. But the value of * rows will be decremented, if we skip any (invalid) Perl rows. */ matrix_av = (AV *) SvRV(matrix_ref); nrows = (int) av_len(matrix_av) + 1; if(nrows <= 0) { return NULL; /* Caller must handle this case!! */ } matrix = malloc(nrows * sizeof(int *) ); if (!matrix) { return NULL; } row_ref = *(av_fetch(matrix_av, (I32) 0, 0)); row_av = (AV *) SvRV(row_ref); ncols = (int) av_len(row_av) + 1; /* ------------------------------------------------------------ * Loop once for each row in the Perl matrix, and convert it to C ints. */ for (i=0; i < nrows; i++) { row_ref = *(av_fetch(matrix_av, (I32) i, 0)); if(! SvROK(row_ref) ) { if(warnings_enabled(aTHX)) Perl_warn(aTHX_ "Row %d: Wanted array reference, but " "got a scalar. No row to process?\n", i); break; } row_av = (AV *) SvRV(row_ref); type = SvTYPE(row_av); /* Handle unexpected cases */ if(type != SVt_PVAV ) { /* Reference doesn't point to an array at all. */ if(warnings_enabled(aTHX)) Perl_warn(aTHX_ "Row %d: Wanted array reference, but got " "a reference to something else (%d)\n", i, type); break; } n = (int) av_len(row_av) + 1; if (n != ncols) { /* All rows in the matrix should have the same * number of columns. */ if(warnings_enabled(aTHX)) Perl_warn(aTHX_ "Row %d: Contains %d columns " "(expected %d)\n", i, n, ncols); break; } matrix[i] = malloc(ncols * sizeof(int) ); if (!matrix[i]) { break; } /* Loop once for each cell in the row. */ for (j=0; j < ncols; ++j) { double num; cell = *(av_fetch(row_av, (I32) j, 0)); if(extract_double_from_scalar(aTHX_ cell,&num) <= 0) { if(warnings_enabled(aTHX)) Perl_warn(aTHX_ "Row %d col %d: Value is not " "a number.\n", i, j); free(matrix[i]); /* not included below */ break; } matrix[i][j] = (int) num; } /* End for (j=0; j < ncols; j++) */ if (j < ncols) break; } /* End for (i=0; i < nrows; i++) */ if (i < nrows) { /* break statement encountered */ nrows = i; for (i = 0; i < nrows; i++) free(matrix[i]); free(matrix); matrix = NULL; } return matrix; } /* ------------------------------------------------- * */ static void free_matrix_int(int ** matrix, int nrows) { int i; for(i = 0; i < nrows; ++i ) { free(matrix[i]); } free(matrix); } /* ------------------------------------------------- * */ static void free_matrix_dbl(double ** matrix, int nrows) { int i; for(i = 0; i < nrows; ++i ) { free(matrix[i]); } free(matrix); } /* ------------------------------------------------- * */ static void free_ragged_matrix_dbl(double ** matrix, int nrows) { int i; for(i = 1; i < nrows; ++i ) { free(matrix[i]); } free(matrix); } /* ------------------------------------------------- * Convert a Perl array into an array of doubles * On error, this function returns NULL. */ static double* malloc_row_perl2c_dbl (pTHX_ SV * input, int* np) { int i; AV* array = (AV *) SvRV(input); const int n = (int) av_len(array) + 1; double* data = malloc(n * sizeof(double)); if (!data) { return NULL; } /* Loop once for each item in the Perl array, and convert * it to a C double. */ for (i=0; i < n; i++) { double num; SV * mysv = *(av_fetch(array, (I32) i, (I32) 0)); if(extract_double_from_scalar(aTHX_ mysv,&num) > 0) { data[i] = num; } else { /* Error reading data */ if (warnings_enabled(aTHX)) Perl_warn(aTHX_ "Error parsing array: item %d is not a number\n", i); free(data); return NULL; } } if(np) *np = n; return data; } /* ------------------------------------------------- * Convert a Perl array into an array of ints * On errors this function returns NULL. */ static int* malloc_row_perl2c_int (pTHX_ SV * input) { int i; AV* array = (AV *) SvRV(input); const int n = (int) av_len(array) + 1; int* data = malloc(n*sizeof(int)); if (!data) { return NULL; } /* Loop once for each item in the Perl array, * and convert it to a C double. */ for (i=0; i < n; i++) { double num; SV * mysv = *(av_fetch(array, (I32) i, (I32) 0)); if(extract_double_from_scalar(aTHX_ mysv,&num) > 0) { data[i] = (int) num; } else { /* Check if the item is numeric */ if (warnings_enabled(aTHX)) Perl_warn(aTHX_ "Error when parsing array: item %d is" " not a number, skipping\n", i); free(data); return NULL; } } return data; } /* ------------------------------------------------- * Copy a Perl array into an array of ints. * If an error occurs, return 0; otherwise return 1. */ static int copy_row_perl2c_int (pTHX_ SV * input, int* output) { int i; AV* array = (AV *) SvRV(input); const int n = (int) av_len(array) + 1; /* Loop once for each item in the Perl array, * and convert it to a C double. */ for (i=0; i < n; i++) { double num; SV * mysv = *(av_fetch(array, (I32) i, (I32) 0)); if(extract_double_from_scalar(aTHX_ mysv,&num) > 0) { output[i] = (int) num; } else { /* Skip any items which are not numeric */ if (warnings_enabled(aTHX)) Perl_warn(aTHX_ "Error when parsing array: item %d is" " not a number\n", i); return 0; } } return 1; } /* ------------------------------------------------- * */ static SV * row_c2perl_dbl(pTHX_ double * row, int ncols) { int j; AV * row_av = newAV(); for(j=0; j= 0) free(p[i]); free(p); return 0; } for (j = 0; j < ncols; j++) p[i][j] = 1; } *mask = p; } /* We don't check data_ref because we expect the caller to check it */ *matrix = parse_data(aTHX_ data_ref, *mask); if(*matrix==NULL) { free_matrix_int(*mask, nrows); return 0; } if(weight_ref==NULL) return 1; /* Weights not needed */ if(SvROK(weight_ref) && SvTYPE(SvRV(weight_ref)) == SVt_PVAV) { *weight = malloc_row_perl2c_dbl(aTHX_ weight_ref, NULL); } else { *weight = malloc_row_dbl(aTHX_ nweights,1.0); } if(!(*weight)) { free_matrix_int(*mask, nrows); free_matrix_dbl(*matrix, nrows); return 0; } return 1; } static double** parse_distance(pTHX_ SV* matrix_ref, int nobjects) { int i,j; AV* matrix_av = (AV *) SvRV(matrix_ref); double** matrix = malloc(nobjects*sizeof(double*)); if (!matrix) { return NULL; } matrix[0] = NULL; for (i=1; i < nobjects; i++) { SV* row_ref = *(av_fetch(matrix_av, (I32) i, 0)); AV* row_av = (AV *) SvRV(row_ref); matrix[i] = malloc(i * sizeof(double)); if (!matrix[i]) { break; } /* Loop once for each cell in the row. */ for (j=0; j < i; j++) { double num; SV* cell = *(av_fetch(row_av, (I32) j, 0)); if(extract_double_from_scalar(aTHX_ cell,&num) > 0) { matrix[i][j] = num; } else { if(warnings_enabled(aTHX)) Perl_warn(aTHX_ "Row %d col %d: Value is not " "a number.\n", i, j); break; } } } if (i < nobjects) { nobjects = i+1; for (i = 1; i < nobjects; i++) free(matrix[i]); free(matrix); matrix = NULL; } return matrix; } /******************************************************************************/ /** **/ /** XS code begins here **/ /** **/ /******************************************************************************/ /******************************************************************************/ MODULE = Algorithm::Cluster PACKAGE = Algorithm::Cluster::Node PROTOTYPES: ENABLE SV* new (class, left, right, distance) char* class int left int right double distance PREINIT: Node* node; SV* obj; CODE: node = malloc(sizeof(Node)); RETVAL = newSViv(0); obj = newSVrv(RETVAL, class); node->left = left; node->right = right; node->distance = distance; sv_setiv(obj, PTR2IV(node)); SvREADONLY_on(obj); OUTPUT: RETVAL int left (obj) SV* obj CODE: RETVAL = (INT2PTR(Node*,SvIV(SvRV(obj))))->left; OUTPUT: RETVAL int right (obj) SV* obj CODE: RETVAL = (INT2PTR(Node*,SvIV(SvRV(obj))))->right; OUTPUT: RETVAL double distance (obj) SV* obj CODE: RETVAL = (INT2PTR(Node*,SvIV(SvRV(obj))))->distance; OUTPUT: RETVAL void set_left (obj, left) SV* obj int left PREINIT: Node* node; CODE: if (!sv_isa(obj, "Algorithm::Cluster::Node")) { croak("set_left should be applied to an Algorithm::Cluster::Node object"); } node = INT2PTR(Node*,SvIV(SvRV(obj))); node->left = left; void set_right (obj, right) SV* obj int right PREINIT: Node* node; CODE: if (!sv_isa(obj, "Algorithm::Cluster::Node")) { croak("set_right should be applied to an Algorithm::Cluster::Node object"); } node = INT2PTR(Node*,SvIV(SvRV(obj))); node->right = right; void set_distance (obj, distance) SV* obj double distance PREINIT: Node* node; CODE: if (!sv_isa(obj, "Algorithm::Cluster::Node")) { croak("set_distance should be applied to an Algorithm::Cluster::Node object"); } node = INT2PTR(Node*,SvIV(SvRV(obj))); node->distance = distance; void DESTROY (obj) SV* obj PREINIT: I32* temp; Node* node; PPCODE: temp = PL_markstack_ptr++; node = INT2PTR(Node*, SvIV(SvRV(obj))); free(node); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ MODULE = Algorithm::Cluster PACKAGE = Algorithm::Cluster::Tree PROTOTYPES: ENABLE SV* new (class, nodes) char* class SV* nodes PREINIT: Tree* tree; SV* obj; int i; int n; AV* array; int* flag; CODE: if(!SvROK(nodes) || SvTYPE(SvRV(nodes)) != SVt_PVAV) { croak("Algorithm::Cluster::Tree::new expects an array of nodes\n"); } array = (AV *) SvRV(nodes); n = (int) av_len(array) + 1; tree = malloc(sizeof(Tree)); if (tree) { tree->n = n; tree->nodes = malloc(n*sizeof(Node)); } if (! tree || !tree->nodes) { if (tree) free(tree); croak("Algorithm::Cluster::Tree::new memory error\n"); } for (i = 0; i < n; i++) { Node* node; SV* node_ref = *(av_fetch(array, (I32) i, 0)); if (!sv_isa(node_ref, "Algorithm::Cluster::Node")) break; node = INT2PTR(Node*,SvIV(SvRV(node_ref))); tree->nodes[i].left = node->left; tree->nodes[i].right = node->right; tree->nodes[i].distance = node->distance; } if (i < n) { /* break encountered */ free(tree->nodes); free(tree); croak("Algorithm::Cluster::Tree::new expects an array of nodes\n"); } flag = malloc((2*n+1)*sizeof(int)); if(flag) { int j; for (i = 0; i < 2*n+1; i++) flag[i] = 0; for (i = 0; i < n; i++) { j = tree->nodes[i].left; if (j < 0) { j = -j-1; if (j>=i) break; } else j+=n; if (flag[j]) break; flag[j] = 1; j = tree->nodes[i].right; if (j < 0) { j = -j-1; if (j>=i) break; } else j+=n; if (flag[j]) break; flag[j] = 1; } free(flag); } if (!flag || i < n) { /* break encountered */ free(tree->nodes); free(tree); croak("the array of nodes passed to Algorithm::Cluster::Tree::new does not represent a valid tree\n"); } RETVAL = newSViv(0); obj = newSVrv(RETVAL, class); sv_setiv(obj, PTR2IV(tree)); SvREADONLY_on(obj); OUTPUT: RETVAL int length (obj) SV* obj CODE: RETVAL = (INT2PTR(Tree*,SvIV(SvRV(obj))))->n; OUTPUT: RETVAL SV * get (obj, index) SV* obj int index PREINIT: Tree* tree; Node* node; SV* scalar; CODE: tree = INT2PTR(Tree*,SvIV(SvRV(obj))); if (index < 0 || index >= tree->n) { croak("Index out of bounds in Algorithm::Cluster::Tree::get\n"); } RETVAL = newSViv(0); scalar = newSVrv(RETVAL, "Algorithm::Cluster::Node"); node = malloc(sizeof(Node)); if (!node) { croak("Memory allocation failure in Algorithm::Cluster::Tree::get\n"); } node->left = tree->nodes[index].left; node->right = tree->nodes[index].right; node->distance = tree->nodes[index].distance; sv_setiv(scalar, PTR2IV(node)); SvREADONLY_on(scalar); OUTPUT: RETVAL void scale(obj) SV* obj PREINIT: int i; int n; Tree* tree; Node* nodes; double maximum; CODE: if (!sv_isa(obj, "Algorithm::Cluster::Tree")) { croak("scale can only be applied to an Algorithm::Cluster::Tree object"); } tree = INT2PTR(Tree*,SvIV(SvRV(obj))); n = tree->n; nodes = tree->nodes; maximum = DBL_MIN; for (i = 0; i < n; i++) { double distance = nodes[i].distance; if (distance > maximum) maximum = distance; } if (maximum!=0.0) { for (i = 0; i < n; i++) nodes[i].distance /= maximum; } AV * cut(obj, nclusters) SV* obj int nclusters PREINIT: int i; int n; Tree* tree; int* clusterid; CODE: if (!sv_isa(obj, "Algorithm::Cluster::Tree")) { croak("cut can only be applied to an Algorithm::Cluster::Tree object"); } tree = INT2PTR(Tree*,SvIV(SvRV(obj))); n = tree->n + 1; if (nclusters < 1) { croak("cut: Requested number of clusters should be positive"); } if (nclusters > n) { croak("cut: More clusters requested than items available"); } clusterid = malloc(n*sizeof(int)); if (!clusterid) { croak("cut: Insufficient memory"); } /* --------------------------------------------------------------- */ cuttree(n, tree->nodes, nclusters, clusterid); /* -- Check for errors flagged by the C routine ------------------ */ if (clusterid[0]==-1) { free(clusterid); croak("cut: Error in the cuttree routine"); } RETVAL = newAV(); for(i=0; inodes); free(tree); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ MODULE = Algorithm::Cluster PACKAGE = Algorithm::Cluster PROTOTYPES: ENABLE SV * _version() CODE: RETVAL = newSVpv( CLUSTERVERSION , 0); OUTPUT: RETVAL SV * _mean(input) SV * input; PREINIT: int array_length; double * data; /* one-dimensional array of doubles */ CODE: if(SvTYPE(SvRV(input)) != SVt_PVAV) { XSRETURN_UNDEF; } data = malloc_row_perl2c_dbl (aTHX_ input, &array_length); if (data) { RETVAL = newSVnv( mean(array_length, data) ); free(data); } else { croak("memory allocation failure in _mean\n"); } OUTPUT: RETVAL SV * _median(input) SV * input; PREINIT: int array_length; double * data; /* one-dimensional array of doubles */ CODE: if(SvTYPE(SvRV(input)) != SVt_PVAV) { XSRETURN_UNDEF; } data = malloc_row_perl2c_dbl (aTHX_ input, &array_length); if (data) { RETVAL = newSVnv( median(array_length, data) ); free(data); } else { croak("memory allocation failure in _median\n"); } OUTPUT: RETVAL SV * _treecluster(nrows,ncols,data_ref,mask_ref,weight_ref,transpose,dist,method) int nrows; int ncols; SV * data_ref; SV * mask_ref; SV * weight_ref; int transpose; char * dist; char * method; PREINIT: Node* nodes; double * weight = NULL; double ** matrix = NULL; int ** mask = NULL; double ** distancematrix = NULL; const int ndata = transpose ? nrows : ncols; const int nelements = transpose ? ncols : nrows; CODE: /* ------------------------ * Don't check the parameters, because we rely on the Perl * caller to check most paramters. */ /* ------------------------ * Convert data and mask matrices and the weight array * from C to Perl. Also check for errors, and ignore the * mask or the weight array if there are any errors. */ if (is_distance_matrix(aTHX_ data_ref)) { distancematrix = parse_distance(aTHX_ data_ref, nelements); if (!distancematrix) { croak("memory allocation failure in _treecluster\n"); } } else { int ok; ok = malloc_matrices(aTHX_ weight_ref, &weight, ndata, data_ref, &matrix, mask_ref, &mask, nrows, ncols); if (!ok) { croak("failed to read input data for _treecluster\n"); } } /* ------------------------ * Run the library function */ nodes = treecluster(nrows, ncols, matrix, mask, weight, transpose, dist[0], method[0], distancematrix); /* ------------------------ * Check result to make sure we didn't run into memory problems */ if(!nodes) { /* treecluster failed due to insufficient memory */ if (matrix) { free_matrix_int(mask, nrows); free_matrix_dbl(matrix, nrows); free(weight); } else { free_ragged_matrix_dbl(distancematrix, nelements); } croak("memory allocation failure in treecluster\n"); } else { /* ------------------------ * Convert generated C matrices to Perl matrices */ const int n = nelements-1; int i; SV* obj; Tree* tree; RETVAL = newSViv(0); obj = newSVrv(RETVAL, "Algorithm::Cluster::Tree"); tree = malloc(sizeof(Tree)); if (!tree) croak("Memory allocation failure in Algorithm::Cluster::Tree\n"); tree->n = n; tree->nodes = malloc(n*sizeof(Node)); if (!tree->nodes) { free(tree); croak("Memory allocation failure in Algorithm::Cluster::Tree\n"); } sv_setiv(obj, PTR2IV(tree)); SvREADONLY_on(obj); for(i=0; inodes[i].left = nodes[i].left; tree->nodes[i].right = nodes[i].right; tree->nodes[i].distance = nodes[i].distance; } free(nodes); } /* ------------------------ * Free what we've malloc'ed */ if (matrix) { free_matrix_int(mask, nrows); free_matrix_dbl(matrix, nrows); free(weight); } else { free_ragged_matrix_dbl(distancematrix, nelements); } /* Finished _treecluster() */ OUTPUT: RETVAL void _kcluster(nclusters,nrows,ncols,data_ref,mask_ref,weight_ref,transpose,npass,method,dist,initialid_ref) int nclusters; int nrows; int ncols; SV * data_ref; SV * mask_ref; SV * weight_ref; int transpose; int npass; char * method; char * dist; SV * initialid_ref; PREINIT: SV * clusterid_ref; int * clusterid; int nobjects; int ndata; double error; int ifound; int ok; double * weight; double ** matrix; int ** mask; PPCODE: /* ------------------------ * Don't check the parameters, because we rely on the Perl * caller to check most parameters. */ /* ------------------------ * Malloc space for the return values from the library function */ if (transpose==0) { nobjects = nrows; ndata = ncols; } else { nobjects = ncols; ndata = nrows; } clusterid = malloc(nobjects * sizeof(int) ); if (!clusterid) { croak("memory allocation failure in _kcluster\n"); } /* ------------------------ * Convert data and mask matrices and the weight array * from C to Perl. Also check for errors, and ignore the * mask or the weight array if there are any errors. */ ok = malloc_matrices( aTHX_ weight_ref, &weight, ndata, data_ref, &matrix, mask_ref, &mask, nrows, ncols); if (!ok) { free(clusterid); croak("failed to read input data for _kcluster\n"); } /* ------------------------ * Copy initialid to clusterid, if needed */ if (npass==0) { copy_row_perl2c_int(aTHX_ initialid_ref, clusterid); } /* ------------------------ * Run the library function */ kcluster( nclusters, nrows, ncols, matrix, mask, weight, transpose, npass, method[0], dist[0], clusterid, &error, &ifound ); /* ------------------------ * Convert generated C matrices to Perl matrices */ clusterid_ref = row_c2perl_int(aTHX_ clusterid, nobjects); /* ------------------------ * Push the new Perl matrices onto the return stack */ XPUSHs(sv_2mortal( clusterid_ref )); XPUSHs(sv_2mortal( newSVnv(error) )); XPUSHs(sv_2mortal( newSViv(ifound) )); /* ------------------------ * Free what we've malloc'ed */ free(clusterid); free_matrix_int(mask, nrows); free_matrix_dbl(matrix, nrows); free(weight); /* Finished _kcluster() */ void _kmedoids(nclusters,nobjects,distancematrix_ref,npass,initialid_ref) int nclusters; int nobjects; SV * distancematrix_ref; int npass; SV * initialid_ref; PREINIT: double** distancematrix; SV * clusterid_ref; int * clusterid; double error; int ifound; PPCODE: /* ------------------------ * Don't check the parameters, because we rely on the Perl * caller to check most parameters. */ /* ------------------------ * Malloc space for the return values from the library function */ clusterid = malloc(nobjects * sizeof(int)); if (!clusterid) { croak("memory allocation failure in _kmedoids\n"); } /* ------------------------ * Convert data and mask matrices and the weight array * from C to Perl. Also check for errors, and ignore the * mask or the weight array if there are any errors. */ distancematrix = parse_distance(aTHX_ distancematrix_ref, nobjects); if (!distancematrix) { free(clusterid); croak("failed to allocate memory for distance matrix in _kmedoids\n"); } /* ------------------------ * Copy initialid to clusterid, if needed */ if (npass==0) { copy_row_perl2c_int(aTHX_ initialid_ref, clusterid); } /* ------------------------ * Run the library function */ kmedoids( nclusters, nobjects, distancematrix, npass, clusterid, &error, &ifound ); if(ifound==-1) { free(clusterid); free_ragged_matrix_dbl(distancematrix, nobjects); croak("memory allocation failure in _kmedoids\n"); } else if(ifound==0) { free(clusterid); free_ragged_matrix_dbl(distancematrix, nobjects); croak("error in input arguments in kmedoids\n"); } else { /* ------------------------ * Convert generated C matrices to Perl matrices */ clusterid_ref = row_c2perl_int(aTHX_ clusterid, nobjects); /* ------------------------ * Push the new Perl matrices onto the return stack */ XPUSHs(sv_2mortal( clusterid_ref )); XPUSHs(sv_2mortal( newSVnv(error) )); XPUSHs(sv_2mortal( newSViv(ifound) )); } /* ------------------------ * Free what we've malloc'ed */ free(clusterid); free_ragged_matrix_dbl(distancematrix, nobjects); /* Finished _kmedoids() */ double _clusterdistance(nrows,ncols,data_ref,mask_ref,weight_ref,cluster1_len,cluster2_len,cluster1_ref,cluster2_ref,dist,method,transpose) int nrows; int ncols; SV * data_ref; SV * mask_ref; SV * weight_ref; int cluster1_len; int cluster2_len; SV * cluster1_ref; SV * cluster2_ref; char * dist; char * method; int transpose; PREINIT: int nweights; int * cluster1; int * cluster2; double * weight; double ** matrix; int ** mask; double distance; int ok; CODE: /* ------------------------ * Don't check the parameters, because we rely on the Perl * caller to check most paramters. */ /* ------------------------ * Convert cluster index Perl arrays to C arrays */ cluster1 = malloc_row_perl2c_int(aTHX_ cluster1_ref); cluster2 = malloc_row_perl2c_int(aTHX_ cluster2_ref); if (!cluster1 || !cluster2) { if (cluster1) free(cluster1); if (cluster2) free(cluster2); croak("memory allocation failure in _clusterdistance\n"); } /* ------------------------ * Convert data and mask matrices and the weight array * from C to Perl. Also check for errors, and ignore the * mask or the weight array if there are any errors. * Set nweights to the correct number of weights. */ nweights = (transpose==0) ? ncols : nrows; ok = malloc_matrices( aTHX_ weight_ref, &weight, nweights, data_ref, &matrix, mask_ref, &mask, nrows, ncols); if (!ok) { free(cluster1); free(cluster2); croak("failed to read input data for _clusterdistance\n"); } /* ------------------------ * Run the library function */ distance = clusterdistance( nrows, ncols, matrix, mask, weight, cluster1_len, cluster2_len, cluster1, cluster2, dist[0], method[0], transpose ); RETVAL = distance; /* ------------------------ * Free what we've malloc'ed */ free_matrix_int(mask, nrows); free_matrix_dbl(matrix, nrows); free(weight); free(cluster1); free(cluster2); /* Finished _clusterdistance() */ OUTPUT: RETVAL void _clustercentroids(nclusters,nrows,ncols,data_ref,mask_ref,clusterid_ref,transpose,method) int nclusters; int nrows; int ncols; SV * data_ref; SV * mask_ref; SV * clusterid_ref; int transpose; char * method; PREINIT: SV * cdata_ref; SV * cmask_ref; int * clusterid; double ** matrix; int ** mask; double ** cdata; int ** cmask; int cnrows = 0; /* Initialize to make the compiler shut up */ int cncols = 0; /* Initialize to make the compiler shut up */ int i; int ok; PPCODE: /* ------------------------ * Don't check the parameters, because we rely on the Perl * caller to check most paramters. */ if (transpose==0) { cnrows = nclusters; cncols = ncols; } else if (transpose==1) { cnrows = nrows; cncols = nclusters; } /* ------------------------ * Convert cluster index Perl arrays to C arrays */ clusterid = malloc_row_perl2c_int(aTHX_ clusterid_ref); if (!clusterid) { croak("memory allocation failure in _clustercentroids\n"); } /* ------------------------ * Convert data and mask matrices and the weight array * from C to Perl. Also check for errors, and ignore the * mask or the weight array if there are any errors. * Set nweights to the correct number of weights. */ ok = malloc_matrices( aTHX_ NULL, NULL, 0, data_ref, &matrix, mask_ref, &mask, nrows, ncols); if (!ok) { free(clusterid); croak("failed to read input data for _clustercentroids\n"); } /* ------------------------ * Create the output variables cdata and cmask. */ i = 0; cdata = malloc(cnrows * sizeof(double*)); cmask = malloc(cnrows * sizeof(int*)); if (cdata && cmask) { for ( ; i < cnrows; i++) { cdata[i] = malloc(cncols*sizeof(double)); cmask[i] = malloc(cncols*sizeof(int)); if (!cdata[i] || !cmask[i]) break; } } if (i < cnrows) { if (cdata[i]) free(cdata[i]); if (cmask[i]) free(cmask[i]); while (--i >= 0) { free(cdata[i]); free(cmask[i]); } if (cdata) free(cdata); if (cmask) free(cmask); free(clusterid); free_matrix_int(mask, nrows); free_matrix_dbl(matrix, nrows); croak("memory allocation failure in _clustercentroids\n"); } /* ------------------------ * Run the library function */ ok = getclustercentroids( nclusters, nrows, ncols, matrix, mask, clusterid, cdata, cmask, transpose, method[0]); if (ok) { /* ------------------------ * Convert generated C matrices to Perl matrices */ cdata_ref = matrix_c2perl_dbl(aTHX_ cdata, cnrows, cncols); cmask_ref = matrix_c2perl_int(aTHX_ cmask, cnrows, cncols); /* ------------------------ * Push the new Perl matrices onto the return stack */ XPUSHs(sv_2mortal( cdata_ref )); XPUSHs(sv_2mortal( cmask_ref )); } /* ------------------------ * Free what we've malloc'ed */ free_matrix_int(mask, nrows); free_matrix_dbl(matrix, nrows); free_matrix_int(cmask, cnrows); free_matrix_dbl(cdata, cnrows); free(clusterid); if (!ok) { croak("memory allocation failure in _clustercentroids\n"); } /* Finished _clustercentroids() */ void _distancematrix(nrows,ncols,data_ref,mask_ref,weight_ref,transpose,dist) int nrows; int ncols; SV * data_ref; SV * mask_ref; SV * weight_ref; int transpose; char * dist; PREINIT: SV * matrix_ref; int nobjects; int ndata; double ** data; int ** mask; double * weight; double ** matrix; int ok; PPCODE: /* ------------------------ * Don't check the parameters, because we rely on the Perl * caller to check most parameters. */ /* ------------------------ * Malloc space for the return values from the library function */ if (transpose==0) { nobjects = nrows; ndata = ncols; } else { nobjects = ncols; ndata = nrows; } /* ------------------------ * Convert data and mask matrices and the weight array * from C to Perl. Also check for errors, and ignore the * mask or the weight array if there are any errors. */ ok = malloc_matrices( aTHX_ weight_ref, &weight, ndata, data_ref, &data, mask_ref, &mask, nrows, ncols ); if (!ok) { croak("failed to read input data for _distancematrix"); } /* ------------------------ * Run the library function */ matrix = distancematrix (nrows, ncols, data, mask, weight, dist[0], transpose); /* ------------------------ * Convert generated C matrices to Perl matrices */ matrix_ref = ragged_matrix_c2perl_dbl(aTHX_ matrix, nobjects); /* ------------------------ * Push the new Perl matrices onto the return stack */ XPUSHs(sv_2mortal(matrix_ref)); /* ------------------------ * Free what we've malloc'ed */ free_ragged_matrix_dbl(matrix, nobjects); free_matrix_int(mask, nrows); free_matrix_dbl(data, nrows); free(weight); /* Finished _distancematrix() */ void _somcluster(nrows,ncols,data_ref,mask_ref,weight_ref,transpose,nxgrid,nygrid,inittau,niter,dist) int nrows; int ncols; SV * data_ref; SV * mask_ref; SV * weight_ref; int transpose; int nxgrid; int nygrid; double inittau; int niter; char * dist; PREINIT: int (*clusterid)[2]; SV * clusterid_ref; double*** celldata; double * weight; double ** matrix; int ** mask; int ok; int i; AV * matrix_av; const int ndata = transpose ? nrows : ncols; const int nelements = transpose ? ncols : nrows; PPCODE: /* ------------------------ * Don't check the parameters, because we rely on the Perl * caller to check most paramters. */ /* ------------------------ * Allocate space for clusterid[][2]. */ clusterid = malloc(nelements*sizeof(int[2])); if (!clusterid) { croak("memory allocation failure in _somcluster\n"); } celldata = 0; /* Don't return celldata, for now at least */ /* ------------------------ * Convert data and mask matrices and the weight array * from C to Perl. Also check for errors, and ignore the * mask or the weight array if there are any errors. * Set nweights to the correct number of weights. */ ok = malloc_matrices( aTHX_ weight_ref, &weight, ndata, data_ref, &matrix, mask_ref, &mask, nrows, ncols); if (!ok) { croak("failed to read input data for _somcluster\n"); } /* ------------------------ * Run the library function */ somcluster( nrows, ncols, matrix, mask, weight, transpose, nxgrid, nygrid, inittau, niter, dist[0], celldata, clusterid ); /* ------------------------ * Convert generated C matrices to Perl matrices */ matrix_av = newAV(); for(i=0; i 0) free(v[i]); free(v); v = NULL; } } if (!u || !v || !w || !m) { if (u) free(u); if (v) free(v); if (w) free(w); if (m) free(m); croak("memory allocation failure in _pca\n"); } /* -- Calculate the mean of each column ------------------------------ */ for (j = 0; j < ncols; j++) { m[j] = 0.0; for (i = 0; i < nrows; i++) m[j] += u[i][j]; m[j] /= nrows; } /* -- Subtract the mean of each column ------------------------------- */ for (i = 0; i < nrows; i++) for (j = 0; j < ncols; j++) u[i][j] -= m[j]; error = pca(nrows, ncols, u, v, w); if (error==0) { /* Convert the C variables to Perl variables */ mean_ref = row_c2perl_dbl(aTHX_ m, ncols); if (nrows >= ncols) { coordinates_ref = matrix_c2perl_dbl(aTHX_ u, nrows, ncols); pc_ref = matrix_c2perl_dbl(aTHX_ v, nmin, nmin); } else /* nrows < ncols */ { pc_ref = matrix_c2perl_dbl(aTHX_ u, nrows, ncols); coordinates_ref = matrix_c2perl_dbl(aTHX_ v, nmin, nmin); } eigenvalues_ref = row_c2perl_dbl(aTHX_ w, nmin); } for (i = 0; i < nrows; i++) free(u[i]); for (i = 0; i < nmin; i++) free(v[i]); free(u); free(v); free(w); free(m); if (error==-1) croak("Insufficient memory for principal components analysis"); if (error > 0) croak("Singular value decomposition failed to converge"); /* ------------------------ * Push the new Perl matrices onto the return stack */ XPUSHs(sv_2mortal(mean_ref)); XPUSHs(sv_2mortal(coordinates_ref)); XPUSHs(sv_2mortal(pc_ref)); XPUSHs(sv_2mortal(eigenvalues_ref)); cluster-1.52a/perl/Makefile.PL0000644000100500010050000000065311505126746016040 0ustar mdehoonmdehoonuse ExtUtils::MakeMaker; use Config; WriteMakefile( NAME => 'Algorithm::Cluster', AUTHOR => 'John Nolan and Michiel de Hoon', ABSTRACT => 'Perl interface to the C Clustering Library', VERSION_FROM => 'Cluster.pm', PM => { 'Cluster.pm' => '$(INST_LIBDIR)/Cluster.pm', 'Record.pm' => '$(INST_LIBDIR)/Cluster/Record.pm', }, LIBS => '-lm', INC => '-I../src', MYEXTLIB => '../src/libcluster$(LIB_EXT)', ); cluster-1.52a/perl/Record.pm0000644000100500010050000004652011160355277015645 0ustar mdehoonmdehoonpackage Algorithm::Cluster::Record; use strict; use Algorithm::Cluster; sub new { my $class = shift; my $self = {}; $self->{data} = undef; $self->{mask} = undef; $self->{geneid} = undef; $self->{genename} = undef; $self->{gweight} = undef; $self->{gorder} = undef; $self->{expid} = undef; $self->{eweight} = undef; $self->{eorder} = undef; $self->{uniqid} = undef; bless($self, $class); return $self; } sub read { my $self = shift; my $handle = shift; my $line = <$handle>; chomp($line); my @words = split(/\t/, $line); my $n = scalar @words; $self->{uniqid} = $words[0]; $self->{expid} = []; my %cols = (0 => 'GENEID'); my $i; for ($i = 1; $i < $n; $i++) { my $word = $words[$i]; if ($word eq 'NAME') { $cols{$i} = $word; $self->{genename} = (); } elsif ($word eq 'GWEIGHT') { $cols{$i} = $word; $self->{gweight} = (); } elsif ($word eq 'GORDER') { $cols{$i} = $word; $self->{gorder} = (); } else { push(@{$self->{expid}}, $word); } } $self->{geneid} = []; $self->{data} = []; $self->{mask} = []; my $needmask = 0; while ($line = <$handle>) { my $count = ($line =~ tr/\t//); @words = split(/\t/, $line); chomp @words; scalar @words == $n or die "Line with " . scalar @words . " columns found (expected $n): $!"; my $start = 0; for my $key (keys %cols) { if ($key > $start) { $start = $key; } } if ($words[0] eq 'EWEIGHT') { @{$self->{eweight}} = @words[$start+1..$n-1]; } elsif ($words[0] eq 'EORDER') { @{$self->{eorder}} = @words[$start+1..$n-1]; } else { my @rowdata = (); my @rowmask = (); for ($i = 0; $i < $n; $i++) { my $word = $words[$i]; if (defined $cols{$i}) { if ($cols{$i} eq 'GENEID') { push(@{$self->{geneid}}, $word); } elsif ($cols{$i} eq 'NAME') { push(@{$self->{genename}}, $word); } elsif ($cols{$i} eq 'GWEIGHT') { push(@{$self->{gweight}}, $word); } elsif ($cols{$i} eq 'GORDER') { push(@{$self->{gorder}}, $word); } } else { if ($word) { push(@rowdata, $word); push(@rowmask, 1); } else { push(@rowdata, 0.0); push(@rowmask, 0); $needmask = 1; } } } push(@{$self->{data}}, [@rowdata]); push(@{$self->{mask}}, [@rowmask]); } } if (not $needmask) { $self->{mask} = undef; } } sub treecluster { my ($self, %args) = @_; my %default = ( transpose => 0, dist => 'e', method => 'm', ); my %param = (%default, %args); $param{data} = $self->{data}; if (defined $self->{mask}) { $param{mask} = $self->{mask}; } if ($param{transpose}==0) { $param{weight} = $self->{eweight}; } else { $param{weight} = $self->{gweight}; } return Algorithm::Cluster::treecluster(%param); } sub kcluster { my ($self, %args) = @_; my %default = ( nclusters => 2, transpose => 0, npass => 1, method => 'a', dist => 'e', initidalid => undef, ); my %param = (%default, %args); $param{data} = $self->{data}; if (defined $self->{mask}) { $param{mask} = $self->{mask}; } if ($param{transpose}==0) { $param{weight} = $self->{eweight}; } else { $param{weight} = $self->{gweight}; } return Algorithm::Cluster::kcluster(%param); } sub somcluster { my ($self, %args) = @_; my %default = ( transpose => 0, nxgrid => 2, nygrid => 1, inittau => 0.02, niter => 1, dist => 'e', ); my %param = (%default, %args); $param{data} = $self->{data}; if (defined $self->{mask}) { $param{mask} = $self->{mask}; } if ($param{transpose}==0) { $param{weight} = $self->{eweight}; } else { $param{weight} = $self->{gweight}; } return Algorithm::Cluster::somcluster(%param); } sub clustercentroids { my ($self, %args) = @_; my %default = ( clusterid => undef, method => 'a', transpose => 0, ); my %param = (%default, %args); $param{data} = $self->{data}; if (defined $self->{mask}) { $param{mask} = $self->{mask}; } my @data = @{$self->{data}}; return Algorithm::Cluster::clustercentroids(%param); } sub clusterdistance { my ($self, %args) = @_; my %default = ( cluster1 => [0], cluster2 => [0], method => 'a', dist => 'e', transpose => 0, ); my %param = (%default, %args); $param{data} = $self->{data}; if (defined $self->{mask}) { $param{mask} = $self->{mask}; } if ($param{transpose}==0) { $param{weight} = $self->{eweight}; } else { $param{weight} = $self->{gweight}; } return Algorithm::Cluster::clusterdistance(%param); } sub distancematrix { my ($self, %args) = @_; my %default = ( dist => 'e', transpose => 0, ); my %param = (%default, %args); $param{data} = $self->{data}; if (defined $self->{mask}) { $param{mask} = $self->{mask}; } if ($param{transpose}==0) { $param{weight} = $self->{eweight}; } else { $param{weight} = $self->{gweight}; } return Algorithm::Cluster::distancematrix(%param); } sub save { my ($self, %args) = @_; my %default = ( geneclusters => undef, expclusters => undef, ); my %param = (%default, %args); $param{data} = $self->{data}; my $ngenes = scalar @{$self->{geneid}}; my $nexps = scalar @{$self->{expid}}; my $jobname = $param{jobname}; defined ($jobname) or die 'jobname undefined'; my $geneclusters; my $expclusters; my $gene_cluster_type; my $exp_cluster_type; if (defined $param{geneclusters}) { $geneclusters = $param{geneclusters}; if (ref($geneclusters) eq "ARRAY") { if (scalar @{$geneclusters} != $ngenes) { die "k-means solution found, but its size does not agree with the number of genes"; } $gene_cluster_type = 'k'; # k-means clustering result } elsif (ref($geneclusters) eq "Algorithm::Cluster::Tree") { $gene_cluster_type = 'h'; # hierarchical clustering result my $n = $geneclusters->length; if ($n != $ngenes - 1) { die "Size of the hierarchical clustering tree ($n) should be equal to the number of genes ($ngenes) minus one"; } } else { die "Cannot understand gene clustering result! $!"; } } if (defined $param{expclusters}) { $expclusters = $param{expclusters}; if (ref($expclusters) eq "ARRAY") { if (scalar @$expclusters != $nexps) { die "k-means solution found, but its size does not agree with the number of experiments"; } $exp_cluster_type = 'k'; # k-means clustering result } elsif (ref($expclusters) eq "Algorithm::Cluster::Tree") { $exp_cluster_type = 'h'; # hierarchical clustering result my $n = $expclusters->length; if ($n != $nexps - 1) { die "Size of the hierarchical clustering tree ($n) should be equal to the number of experiments ($nexps) minus one"; } } else { die "Cannot understand experiment clustering result! $!"; } } my @gorder; if (defined $self->{gorder}) { @gorder = $self->{gorder}; } else { @gorder = (0..$ngenes-1); } my @eorder; if (defined $self->{eorder}) { @eorder = $self->{eorder}; } else { @eorder = (0..$nexps-1); } if (defined $gene_cluster_type and defined $exp_cluster_type) { if ($gene_cluster_type ne $exp_cluster_type) { die 'found one k-means and one hierarchical clustering solution in geneclusters and expclusters'; } } my $gid = 0; my $aid = 0; my $filename = $jobname; my $postfix = ''; my @geneindex; my @expindex; if ($gene_cluster_type eq 'h') { # Hierarchical clustering result @geneindex = _savetree(jobname => $jobname, tree => $geneclusters, order => \@gorder, transpose => 0); $gid = 1; } elsif ($gene_cluster_type eq 'k') { # k-means clustering result $filename = $jobname . '_K'; my $k = -1; foreach (@$geneclusters) { if ($_ > $k) { $k = $_; } } $k++; my $kggfilename = $jobname . "_K_G$k.kgg"; @geneindex = $self->_savekmeans(filename => $kggfilename, clusterids => \@$geneclusters, order => \@gorder, transpose => 0); $postfix = "_G$k"; } else { @geneindex = sort { $gorder[$a] <=> $gorder[$b] } (0..$ngenes-1); } if ($exp_cluster_type eq 'h') { # Hierarchical clustering result @expindex = _savetree(jobname => $jobname, tree => $expclusters, order => \@eorder, transpose => 1); $aid = 1; } elsif ($exp_cluster_type eq 'k') { # k-means clustering result $filename = $jobname . '_K'; my $k = -1; foreach (@$expclusters) { if ($_ > $k) { $k = $_; } } $k++; my $kagfilename = $jobname . "_K_A$k.kag"; @expindex = $self->_savekmeans(filename => $kagfilename, clusterids => \@$expclusters, order => \@eorder, transpose => 1); $postfix = $postfix . "_A$k"; } else { @expindex = sort { $eorder[$a] <=> $eorder[$b] } (0..$nexps-1); } $filename = $filename . $postfix; $self->_savedata(jobname => $filename, gid => $gid, aid => $aid, geneindex => \@geneindex, expindex => \@expindex); } sub _treesort { my %param = @_; my @order = @{$param{order}}; my @nodeorder = @{$param{nodeorder}}; my @nodecounts = @{$param{nodecounts}}; my $tree = $param{tree}; my $nNodes = $tree->length; my $nElements = $nNodes + 1; my @neworder = (0.0) x $nElements; my @clusterids = (0..$nElements-1); for (my $i = 0; $i < $nNodes; $i++) { my $i1 = $tree->get($i)->left; my $i2 = $tree->get($i)->right; my ($order1, $order2, $count1, $count2); if ($i1 < 0) { $order1 = $nodeorder[-$i1-1]; $count1 = $nodecounts[-$i1-1]; } else { $order1 = $order[$i1]; $count1 = 1; } if ($i2 < 0) { $order2 = $nodeorder[-$i2-1]; $count2 = $nodecounts[-$i2-1]; } else { $order2 = $order[$i2]; $count2 = 1; } # If order1 and order2 are equal, their order is determined by the order in which they were clustered my $increase; if ($i1 < $i2) { if ($order1 < $order2) { $increase = $count1; } else { $increase = $count2; } for (my $j = 0; $j < $nElements; $j++) { my $clusterid = $clusterids[$j]; if ($clusterid==$i1 and $order1>=$order2) { $neworder[$j] += $increase; } if ($clusterid==$i2 and $order1<$order2) { $neworder[$j] += $increase; } if ($clusterid==$i1 or $clusterid==$i2) { $clusterids[$j] = -$i-1; } } } else { if ($order1<=$order2) { $increase = $count1; } else { $increase = $count2; } for (my $j = 0; $j < $nElements; $j++) { my $clusterid = $clusterids[$j]; if ($clusterid==$i1 and $order1>$order2) { $neworder[$j] += $increase; } if ($clusterid==$i2 and $order1<=$order2) { $neworder[$j] += $increase; } if ($clusterid==$i1 or $clusterid==$i2) { $clusterids[$j] = -$i-1; } } } } my @result = sort { $neworder[$a] <=> $neworder[$b] } (0..$nElements-1); return @result; } sub _savetree { my %param = @_; my $jobname = $param{jobname}; my $tree = $param{tree}; my @order = @{$param{order}}; my $transpose = $param{transpose}; my ($extension, $keyword); if ($transpose==0) { $extension = 'gtr'; $keyword = 'GENE'; } else { $extension = 'atr'; $keyword = 'ARRY'; } my $nnodes = $tree->length; open OUTPUT, ">$jobname.$extension" or die 'Error: Unable to open output file'; my @nodeID = ('') x $nnodes; my @nodecounts = (0) x $nnodes; my @nodeorder = (0.0) x $nnodes; my @nodedist; my $i; for ($i = 0; $i < $nnodes; $i++) { my $node = $tree->get($i); push (@nodedist, $node->distance); } for (my $nodeindex = 0; $nodeindex < $nnodes; $nodeindex++) { my $min1 = $tree->get($nodeindex)->left; my $min2 = $tree->get($nodeindex)->right; my $order1; my $order2; my $counts1; my $counts2; $nodeID[$nodeindex] = "NODE" . ($nodeindex+1) . "X"; print OUTPUT $nodeID[$nodeindex]; print OUTPUT "\t"; if ($min1 < 0) { my $index1 = -$min1-1; $order1 = $nodeorder[$index1]; $counts1 = $nodecounts[$index1]; print OUTPUT $nodeID[$index1]; print OUTPUT "\t"; if ($nodedist[$index1] > $nodedist[$nodeindex]) { $nodedist[$nodeindex] = $nodedist[$index1]; } } else { $order1 = $order[$min1]; $counts1 = 1; print OUTPUT $keyword . $min1 . "X\t"; } if ($min2 < 0) { my $index2 = -$min2-1; $order2 = $nodeorder[$index2]; $counts2 = $nodecounts[$index2]; print OUTPUT $nodeID[$index2]; print OUTPUT "\t"; if ($nodedist[$index2] > $nodedist[$nodeindex]) { $nodedist[$nodeindex] = $nodedist[$index2]; } } else { $order2 = $order[$min2]; $counts2 = 1; print OUTPUT $keyword . $min2 . "X\t"; } print OUTPUT 1.0-$nodedist[$nodeindex]; print OUTPUT "\n"; $nodecounts[$nodeindex] = $counts1 + $counts2; $nodeorder[$nodeindex] = ($counts1*$order1+$counts2*$order2) / ($counts1+$counts2); } close(OUTPUT); # Now set up order based on the tree structure return _treesort(order => \@order, nodeorder => \@nodeorder, nodecounts => \@nodecounts, tree => $tree); } sub _savekmeans { my ($self, %param) = @_; my $filename = $param{filename}; my @clusterids = @{$param{clusterids}}; my @order = @{$param{order}}; my $transpose = $param{transpose}; my $label; my @names; if ($transpose == 0) { $label = $self->{uniqid}; @names = @{$self->{geneid}}; } else { $label = 'ARRAY'; @names = @{$self->{expid}}; } open OUTPUT, ">$filename" or die 'Error: Unable to open output file'; print OUTPUT "$label\tGROUP\n"; my $n = scalar @names; my @result = sort { $order[$a] <=> $order[$b] } (0..$n-1); my @sortedindex; my $cluster = 0; while (scalar @sortedindex < $n) { foreach (@result) { my $j = $_; my $cid = $clusterids[$j]; if ($clusterids[$j]==$cluster) { print OUTPUT $names[$j] . "\t$cluster\n"; push (@sortedindex, $j); } } $cluster++; } close(OUTPUT); return @sortedindex; } sub _savedata { my ($self, %param) = @_; my $jobname = $param{jobname}; my $gid = $param{gid}; my $aid = $param{aid}; my @geneindex = @{$param{geneindex}}; my @expindex = @{$param{expindex}}; my @genename; if (defined $self->{genename}) { @genename = @{$self->{genename}}; } else { @genename = @{$self->{geneid}}; } my $ngenes = scalar @{$self->{geneid}}; my $nexps = scalar @{$self->{expid}}; open OUTPUT, ">$jobname.cdt" or die 'Error: Unable to open output file'; my @mask; if (defined $self->{mask}) { @mask = @{$self->{mask}}; } else { @mask = ([(1) x $nexps]) x $ngenes; # Each row contains identical shallow copies of the same vector; # modifying one row would affect the other rows. } my @gweight; if (defined $self->{gweight}) { @gweight = @{$self->{gweight}}; } else { @gweight = (1) x $ngenes; } my @eweight; if (defined $self->{eweight}) { @eweight = @{$self->{eweight}}; } else { @eweight = (1) x $nexps; } if ($gid) { print OUTPUT "GID\t"; } print OUTPUT $self->{uniqid}; print OUTPUT "\tNAME\tGWEIGHT"; # Now add headers for data columns foreach (@expindex) { print OUTPUT "\t" . $self->{expid}[$_]; } print OUTPUT "\n"; if ($aid) { print OUTPUT "AID"; if ($gid) { print OUTPUT "\t"; } print OUTPUT "\t\t"; foreach (@expindex) { print OUTPUT "\tARRY" . $_ . 'X'; } print OUTPUT "\n"; } print OUTPUT "EWEIGHT"; if ($gid) { print OUTPUT "\t"; } print OUTPUT "\t\t"; foreach (@expindex) { print OUTPUT "\t" . $eweight[$_]; } print OUTPUT "\n"; foreach (@geneindex) { my $i = $_; if ($gid) { print OUTPUT "GENE" . $i . "X\t"; } print OUTPUT $self->{geneid}[$i] . "\t" . $genename[$i] . "\t" . $gweight[$i]; foreach (@expindex) { my $j = $_; print OUTPUT "\t"; if ($mask[$i][$j]) { print OUTPUT $self->{data}[$i][$j]; } } print OUTPUT "\n"; } close(OUTPUT); } 1; cluster-1.52a/perl/MANIFEST.perl0000644000100500010050000000116711505234670016155 0ustar mdehoonmdehoonMANIFEST README INSTALL Makefile.PL perl/Artistic.txt perl/Cluster.xs perl/Cluster.pm perl/Makefile.PL perl/Record.pm perl/t/01_mean_median.t perl/t/02_tree.t perl/t/10_kcluster.t perl/t/11_clusterdistance.t perl/t/12_treecluster.t perl/t/13_somcluster.t perl/t/14_kmedoids.t perl/t/15_distancematrix.t perl/t/16_pca.t src/Makefile.PL src/cluster.c src/cluster.h perl/examples/ex1_kcluster perl/examples/ex2_mean_median perl/examples/ex3_kcluster perl/examples/ex4_somcluster perl/examples/ex5_treecluster perl/examples/ex6_clusterdistance perl/examples/ex7_distancematrix perl/examples/ex8_kmedoids data/cyano.txt doc/cluster.pdf cluster-1.52a/perl/examples/0000755000100500010050000000000012177164023015674 5ustar mdehoonmdehooncluster-1.52a/perl/examples/ex3_kcluster0000755000100500010050000000344411245630714020242 0ustar mdehoonmdehoon#!/usr/perl/perl580/bin/perl -w use Algorithm::Cluster qw/kcluster/; use strict; my $weight1 = [ 1,1 ]; my $data1 = [ [ 1.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ], ]; my $mask1 = [ [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], ]; my $data2 = [ [ 1.1, 2.2, 3.3, 4.4, 5.5, ], [ 3.1, 3.2, 1.3, 2.4, 1.5, ], [ 4.1, 2.2, 0.3, 5.4, 0.5, ], [ 12.1, 2.0, 0.0, 5.0, 0.0, ], ]; my $mask2 = [ [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], ]; my $weight2 = [ 1,1,1,1,1 ]; my %params = ( nclusters => 3, transpose => 0, npass => 100, method => 'a', dist => 'e', ); my ($clusters, $error, $found); my ($i); $i=0; ($clusters, $error, $found) = kcluster( %params, data => $data1, mask => $mask1, weight => $weight1, ); printf("\n"); printf("Clustering first data set:\n\n"); $i=0; foreach(@{$clusters}) { printf("Gene %2d belongs to cluster %2d\n",$i++,$_); } printf("\n"); printf("Within-cluster sum of distances is %f\n", $error); printf("\n"); printf("Clustering second data set:\n\n"); ($clusters, $error, $found) = kcluster( %params, data => $data2, mask => $mask2, weight => $weight2, ); $i=0; foreach(@{$clusters}) { printf("Gene %2d belongs to cluster %2d\n",$i++,$_); } printf("\n"); printf("Within-cluster sum of distances is %f\n", $error); printf("\n"); __END__ cluster-1.52a/perl/examples/ex6_clusterdistance0000755000100500010050000000463011245631053021600 0ustar mdehoonmdehoon#!/usr/perl/perl580/bin/perl use Algorithm::Cluster; $^W = 1; use strict; use warnings "Algorithm::Cluster"; my $weight = [ 1,1 ]; my $data = [ [ 1.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ], ]; my $mask = [ [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], ]; my $clusterA = [ 0, 1, 2, 3 ]; my $clusterB = [ 4, 5, 6, 7 ]; my $clusterC = [ 8 ]; my %params = ( transpose => 0, method => 'a', dist => 'e', ); my ($distance); $distance = Algorithm::Cluster::clusterdistance( %params, data => $data, mask => $mask, weight => $weight, cluster1 => $clusterA, cluster2 => $clusterB, ); printf("Distance between cluster A and cluster B is %7.3f\n", $distance); $distance = Algorithm::Cluster::clusterdistance( %params, data => $data, mask => $mask, weight => $weight, cluster1 => $clusterA, cluster2 => $clusterC, ); printf("Distance between cluster A and cluster C is %7.3f\n", $distance); $distance = Algorithm::Cluster::clusterdistance( %params, data => $data, mask => $mask, weight => $weight, cluster1 => $clusterB, cluster2 => $clusterC, ); printf("Distance between cluster B and cluster C is %7.3f\n", $distance); $distance = Algorithm::Cluster::clusterdistance( %params, data => $data, mask => $mask, weight => $weight, cluster1 => $clusterA, cluster2 => 5, ); printf("Distance between cluster A and item 5 is %7.3f\n", $distance); $distance = Algorithm::Cluster::clusterdistance( %params, data => $data, mask => $mask, weight => $weight, cluster1 => 1, cluster2 => $clusterC, ); printf("Distance between cluster C and item 1 is %7.3f\n", $distance); $distance = Algorithm::Cluster::clusterdistance( %params, data => $data, mask => $mask, weight => $weight, cluster1 => 1, cluster2 => 6, ); printf("Distance between item 1 and item 6 is %7.3f\n", $distance); __END__ cluster-1.52a/perl/examples/ex7_distancematrix0000755000100500010050000000230111245631103021411 0ustar mdehoonmdehoon#!/usr/perl/perl580/bin/perl -w use strict; use Algorithm::Cluster qw/distancematrix/; my $weight = [ 1,1 ]; my $data = [ [ 1.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.1, 5.2 ], ]; my $mask = [ [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], ]; #------------------ # Define the params we want to pass to distancematrix my %params = ( transpose => 0, dist => 'e', data => $data, mask => $mask, weight => $weight, ); #------------------ # Here is where we invoke the library function! # printf("Calculating the distance matrix\n"); my $matrix = distancematrix(%params); # #------------------ my $row; my $number; foreach $row (@{$matrix}) { foreach $number (@{$row}) { printf("%7.3f\t", $number); } printf("\n"); } cluster-1.52a/perl/examples/ex2_mean_median0000755000100500010050000000101611245630635020635 0ustar mdehoonmdehoon#!/usr/perl/perl580/bin/perl -w use Algorithm::Cluster qw/mean median/; use strict; my ($meanval, $medianval); my @vals = ( [ 34.3, 3, 2 ], [ 5, 10 ,15, 20 ], [ 1, 2, 3, 5, 7, 11, 13, 17], [ 100, 19, 3, 1.5, 1.4, 1, 1, 1], [ 3, 2 ], [ 0.1, 3.2, 2.3 ], ); foreach (@vals) { $meanval = Algorithm::Cluster::mean($_); $medianval = Algorithm::Cluster::median($_); print "Values are: (", join(", ", @$_), ")\n"; printf("Mean is %7.3f\nMedian is %7.3f\n\n", $meanval, $medianval); } cluster-1.52a/perl/examples/ex4_somcluster0000755000100500010050000000234711245630761020612 0ustar mdehoonmdehoon#!/usr/perl/perl580/bin/perl use Algorithm::Cluster; $|++; $^W = 1; use strict; my $weight2 = [ 1,1 ]; my $data2 = [ [ 1.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ], ]; my $mask2 = [ [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], ]; my $data3 = [ [ 1.1, 2.2, 3.3, 4.4, 5.5, ], [ 3.1, 3.2, 1.3, 2.4, 1.5, ], [ 4.1, 2.2, 0.3, 5.4, 0.5, ], [ 12.1, 2.0, 0.0, 5.0, 0.0, ], ]; my $mask3 = [ [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], [ 1, 1, 1, 1, 1, ], ]; my $weight3 = [ 1,1,1,1,1 ]; my %params = ( transpose => 0, dist => 'e', data => $data2, mask => $mask2, weight => $weight2, niter => 100, ); my ($clusterid); my ($i); $clusterid = Algorithm::Cluster::somcluster(%params); $i=0; foreach(@{$clusterid}) { printf("Gene %2d assigned to cell (%2d,%2d)\n",$i++,$_->[0],$_->[1]); } __END__ cluster-1.52a/perl/examples/ex8_kmedoids0000755000100500010050000000553111245631135020207 0ustar mdehoonmdehoon#!/usr/perl/perl580/bin/perl -w use strict; use Algorithm::Cluster qw/kmedoids distancematrix/; my $file = "../../data/cyano.txt"; my $i = 0; my $j = 0; my (@orfname,@orfdata,@weight,@mask); open(DATA,"<$file") or die "Can't open file $file: $!"; #------------------ # Read in the data file, and save the data to @orfdata # We know that the file is intact and has no holes, # so just set the mask to 1 for every item. # We don't check for errors in this case, because the file # is short and we can spot errors by eye. # my $firstline = ; # Skip the title line while() { chomp(my $line = $_); my @field = split /\t/, $line; $orfname[$i] = $field[0]; $orfdata[$i] = [ @field[2..5] ]; $mask[$i] = [ 1,1,1,1 ]; ++$i; } close(DATA); #------------------ # Make a reverse-lookup index of the @orfnames hash: # my %orfname_by_rowid; $i=0; $orfname_by_rowid{$i++} = $_, foreach(@orfname); @weight = (1.0) x 4; #------------------ # Define the params we want to pass to distancematrix my %params1 = ( transpose => 0, dist => 'e', data => \@orfdata, mask => \@mask, weight => \@weight, ); #------------------ # Here is where we invoke the library function! # printf("Calculating the distance matrix\n"); my $matrix = distancematrix(%params1); # #------------------ my %params2 = ( nclusters => 6, distances => $matrix, npass => 1000, ); printf("Executing k-medoids clustering 1000 times, using random initial clusterings\n"); my ($clusters, $error, $found) = kmedoids(%params2); my $item; $i = 0; foreach $item (@{$clusters}) { print $i, ": ", $item, "\n"; ++$i; } #------------------ # Print out the resulting within-cluster sum of distances. # print "------------------\n"; printf("Within-cluster sum of distances: %f; solution was found %d times\n\n", $error, $found); #------------------ # Try this again with a specified initial clustering solution # my @initialid = (0,1,2,3,4,5) x 15; # choice for the initial clustering; the data file contains 90 genes. %params2 = ( nclusters => 6, distances => $matrix, initialid => \@initialid, ); printf("Executing k-medoids clustering with a specified initial clustering\n"); ($clusters, $error, $found) = kmedoids(%params2); printf("Within-cluster sum of distances: %f\n\n", $error); cluster-1.52a/perl/examples/ex5_treecluster0000755000100500010050000000366411245631011020744 0ustar mdehoonmdehoon#!/usr/perl/perl580/bin/perl use Algorithm::Cluster; $|++; $^W = 1; use strict; my $weight = [ 1,1 ]; my $data = [ [ 1.1, 1.2 ], [ 1.4, 1.3 ], [ 1.1, 1.5 ], [ 2.0, 1.5 ], [ 1.7, 1.9 ], [ 1.7, 1.9 ], [ 5.7, 5.9 ], [ 5.7, 5.9 ], [ 3.1, 3.3 ], [ 5.4, 5.3 ], [ 5.1, 5.5 ], [ 5.0, 5.5 ], [ 5.1, 5.2 ], ]; my $mask = [ [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], [ 1, 1 ], ]; print "--------------[pairwise average linkage]-------\n"; my %params = ( transpose => 0, method => 'a', dist => 'e', data => $data, mask => $mask, weight => $weight, ); my $tree; my ($i,$j,$n); my $tree = Algorithm::Cluster::treecluster(%params); $n = $tree->length; for ($i = 0; $i < $n; $i++) { my $node = $tree->get($i); printf("%3d: %3d %3d %7.3f\n",-1-$i,$node->left,$node->right,$node->distance); } print "--------------[pairwise single linkage]-------\n"; $params{method} = 's'; $tree = Algorithm::Cluster::treecluster(%params); $n = $tree->length; for ($i = 0; $i < $n; $i++) { my $node = $tree->get($i); printf("%3d: %3d %3d %7.3f\n",-1-$i,$node->left,$node->right,$node->distance); } print "--------------[pairwise centroid linkage]-------\n"; $params{method} = 'c'; $tree= Algorithm::Cluster::treecluster(%params); $n = $tree->length; for ($i = 0; $i < $n; $i++) { my $node = $tree->get($i); printf("%3d: %3d %3d %7.3f\n",-1-$i,$node->left,$node->right,$node->distance); } print "--------------[pairwise maximum linkage]-------\n"; $params{method} = 'm'; $tree = Algorithm::Cluster::treecluster(%params); $n = $tree->length; for ($i = 0; $i < $n; $i++) { my $node = $tree->get($i); printf("%3d: %3d %3d %7.3f\n",-1-$i,$node->left,$node->right,$node->distance); } __END__ cluster-1.52a/perl/examples/ex1_kcluster0000755000100500010050000000540511245630616020240 0ustar mdehoonmdehoon#!/usr/perl/perl580/bin/perl -w use strict; use Algorithm::Cluster qw/kcluster/; my $file = "../../data/cyano.txt"; my $i = 0; my $j = 0; my (@orfname,@orfdata,@weight,@mask); open(DATA,"<$file") or die "Can't open file $file: $!"; #------------------ # Read in the data file, and save the data to @orfdata # We know that the file is intact and has no holes, # so just set the mask to 1 for every item. # We don't check for errors in this case, because the file # is short and we can spot errors by eye. # my $firstline = ; # Skip the title line while() { chomp(my $line = $_); my @field = split /\t/, $line; $orfname[$i] = $field[0]; $orfdata[$i] = [ @field[2..5] ]; $mask[$i] = [ 1,1,1,1 ]; ++$i; } close(DATA); #------------------ # Make a reverse-lookup index of the @orfnames hash: # my %orfname_by_rowid; $i=0; $orfname_by_rowid{$i++} = $_, foreach(@orfname); @weight = (1.0) x 4; #------------------ # Define the params we want to pass to kcluster my %params = ( nclusters => 6, transpose => 0, npass => 100, method => 'a', dist => 'e', data => \@orfdata, mask => \@mask, weight => \@weight, ); #------------------ # Here is where we invoke the library function! # my ($clusters, $error, $found) = kcluster(%params); # #------------------ #------------------ # Create a reverse index of the ORF names, by cluster ID # my %orfname_by_cluster; $i=0; foreach(@{$clusters}) { push @{$orfname_by_cluster{$_}}, $orfname_by_rowid{$i++}; } #------------------ # Print out a list of the ORFs, grouped by cluster ID, # as returned by the kcluster() function. # for ($i = 0; $i < $params{"nclusters"}; $i++) { print "------------------\n"; printf("Cluster %d: %d ORFs\n\n", $i, scalar(@{$orfname_by_cluster{$i} }) ); print "\t$_\n", foreach( sort { $a cmp $b } @{$orfname_by_cluster{$i} } ); print "\n"; } #------------------ # Print out the resulting within-cluster sum of distances. # print "------------------\n"; printf("Within-cluster sum of distances: %f\n\n", $error); #------------------ # Try this again with a specified initial clustering solution # my @initialid = (0,1,2,3,4,5) x 15; # choice for the initial clustering; the data file contains 90 genes. %params = ( nclusters => 6, transpose => 0, method => 'a', dist => 'e', data => \@orfdata, mask => \@mask, weight => \@weight, initialid => \@initialid, ); printf("Executing k-means clustering with a specified initial clustering\n"); ($clusters, $error, $found) = kcluster(%params); printf("Within-cluster sum of distances: %f\n\n", $error); cluster-1.52a/configure.ac0000644000100500010050000000412412174110404015372 0ustar mdehoonmdehoon# Process this file with autoconf to produce a configure script. AC_INIT(cluster, 1.52) AC_CONFIG_SRCDIR(src/cluster.c) AM_INIT_AUTOMAKE AC_CONFIG_HEADERS(config.h) # Checks for programs. AC_PROG_CC # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADER(float.h) AC_CHECK_HEADER(math.h) AC_CHECK_HEADER(stdio.h) AC_CHECK_HEADER(stdlib.h) AC_CHECK_HEADER(string.h) AC_CHECK_HEADER(time.h) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T # Checks for library functions. AC_FUNC_MALLOC AC_CHECK_LIB([m],[sqrt,exp,log]) # Check if we are building the GUI version or the command line version AC_CONFIG_FILES([Makefile src/Makefile]) if test "$with_x" = no; then AC_MSG_NOTICE([Building command-line version of Cluster 3.0]) AM_CONDITIONAL(MOTIF, false) else AC_MSG_NOTICE([Building GUI version of Cluster 3.0 using Motif]) AC_PROG_RANLIB AC_PATH_XTRA if test "$no_x" = "yes"; then AC_MSG_ERROR([Failed to locate the X11 include files and libraries. Use --without-x if you want to build the command-line version of Cluster 3.0.]) fi LIBS="$X_PRE_LIBS -lX11 $X_LIBS $X_EXTRA_LIB $LIBS" CPPFLAGS="$X_CFLAGS $CPPFLAGS" AC_CHECK_LIB(Xext, XShapeQueryVersion, [], [AC_MSG_ERROR([Failed to locate the Xext library. Use --without-x if you want to build the command-line version of Cluster 3.0.])]) AC_CHECK_LIB(Xt, XtMalloc, [], [AC_MSG_ERROR([Failed to locate the Xt library. Use --without-x if you want to build the command-line version of Cluster 3.0.])]) AC_CHECK_LIB(Xm, XmStringCreateSimple, [], [AC_MSG_ERROR([Failed to locate the Motif library. Use --without-x if you want to build the command-line version of Cluster 3.0.])]) AC_CHECK_HEADER(Xm/Xm.h, [], [AC_MSG_ERROR([Failed to locate the Motif header files. Use --without-x if you want to build the command-line version of Cluster 3.0. Otherwise, use CPPFLAGS to add the Motif header directory to the path. For example, if Xm.h is in /usr/X11R6/include/Xm, use ./configure CPPFLAGS=-I/usr/X11R6/include ])]) AM_CONDITIONAL(MOTIF, true) AC_CONFIG_FILES([X11/Makefile]) fi AC_OUTPUT cluster-1.52a/NEWS0000644000100500010050000000075512177160252013622 0ustar mdehoonmdehoon2013.08.03 Added checks for all calls to malloc in src/data.c, and corresponding error messages in the GUI and command line programs. Using MinGW instead of Cygwin to create the installer for Windows. Using productbuild instead of productbuild to create the installer for Mac. Removed the mean and median functions from Pycluster, as anyway these are available from Numerical Python. This also avoids problems with deprecated API usage. Added checks for calls to malloc in Algorithm::Cluster. cluster-1.52a/missing0000755000100500010050000002623311314437555014526 0ustar mdehoonmdehoon#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2009-04-28.21; # UTC # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, # 2008, 2009 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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, 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, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and \`g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # normalize program name to check for. program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). This is about non-GNU programs, so use $1 not # $program. case $1 in lex*|yacc*) # Not GNU programs, they don't have --version. ;; tar*) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $program in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te*) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison*|yacc*) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex*|flex*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit $? fi ;; makeinfo*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar*) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cluster-1.52a/AUTHORS0000644000100500010050000000121511475703277014175 0ustar mdehoonmdehoonMichiel de Hoon (currently at the RIKEN Omics Science Center), SunYong Kim, Seiya Imoto, and Satoru Miyano. University of Tokyo, Institute of Medical Science, Human Genome Center, Laboratory of DNA Information Analysis. http://bonsai.ims.u-tokyo.ac.jp Contact: mdehoon 'AT' gsc.riken.jp Cluster 3.0 is an enhanced version of Cluster, which was written by Michael Eisen (http://rana.lbl.gov) while at Stanford University. Cluster 3.0 was written for Windows, and subsequently ported to Mac OS X and Linux/Unix. The Perl interface to the C Clustering Library was written by John Nolan (jpnolan@sonic.net) of the University of California, Santa Cruz. cluster-1.52a/aclocal.m40000644000100500010050000010400312174721321014747 0ustar mdehoonmdehoon# generated automatically by aclocal 1.12.5 -*- Autoconf -*- # Copyright (C) 1996-2012 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.12' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.12.5], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.12.5])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated. For more info, see: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_INIT_AUTOMAKE-invocation]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl dnl Support for Objective C++ was only introduced in Autoconf 2.65, dnl but we still cater to Autoconf 2.62. m4_ifdef([AC_PROG_OBJCXX], [AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The 'parallel-tests' driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2001-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of '-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR cluster-1.52a/mac/0000755000100500010050000000000012177164023013654 5ustar mdehoonmdehooncluster-1.52a/mac/main.m0000644000100500010050000000111310762012513014744 0ustar mdehoonmdehoon// // main.m // Cluster 3.0 for Mac OS X // // Created by mdehoon on 17 October 2002. // Copyright (c) 2002, Michiel de Hoon. All rights reserved. // #import #import "command.h" int main(int argc, const char *argv[]) { int result; if ( (argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) || (argc <= 1) ) /* Double-clicking adds an additional argv, which starts with -psn */ result = NSApplicationMain(argc, argv); else /* Run Cluster 3.0 as a command-line program */ result = commandmain(argc, argv); return result; } cluster-1.52a/mac/Controller.m0000644000100500010050000010344112176171107016160 0ustar mdehoonmdehoon#import "Controller.h" #import "data.h" #import /* contains dup */ typedef struct /* So tired of Objective-C ... let's make a good old struct instead. */ { NSFileHandle* handle; FILE* pointer; } FileHandle; static BOOL OpenFile(FileHandle* file, NSString* path, char mode[]) { file->pointer = NULL; /* Initialization */ switch (mode[0]) { case 'w': file->handle = [NSFileHandle fileHandleForWritingAtPath: path]; break; case 'r': file->handle = [NSFileHandle fileHandleForReadingAtPath: path]; break; default: return FALSE; } if (!file->handle) return FALSE; int fd = [file->handle fileDescriptor]; /* Duplicate the file descriptor so that we can call fclose on pointer * and release on handle. Stupid Cocoa makes life difficult. */ file->pointer = fdopen(dup(fd), mode); if (!file->pointer) { [file->handle closeFile]; return FALSE; } [file->handle retain]; return TRUE; } static void CloseFile(FileHandle file) { fclose(file.pointer); [file.handle release]; } @implementation Controller - (void)UpdateInfo { const int rows = GetRows(); const int columns = GetColumns(); [Rows setIntValue: rows]; [Columns setIntValue: columns]; int dim = 1 + (int)pow(rows,0.25); [SOMGeneXDim setIntValue: dim]; [SOMGeneYDim setIntValue: dim]; dim = 1 + (int)pow(columns,0.25); [SOMArrayXDim setIntValue: dim]; [SOMArrayYDim setIntValue: dim]; } - (void)FilterReset { [filterresult setStringValue: @""]; [filteraccept setEnabled: FALSE]; } - (void)InitDir { if(directory) return; directory = NSHomeDirectory(); [directory retain]; } - (void)SaveDir:(NSString*)filename { if(directory) [directory release]; directory = [filename stringByDeletingLastPathComponent]; [directory retain]; } - (char)GetMetric:(NSComboBox*)metricbox { int index = [metricbox indexOfSelectedItem]; switch (index) { case 0: return 'u'; break; // Uncentered correlation case 1: return 'c'; break; // Centered correlation case 2: return 'x'; break; // Absolute uncentered correlation case 3: return 'a'; break; // Absolute centered correlation case 4: return 's'; break; // Spearman rank correlation case 5: return 'k'; break; // Kendall's tau case 6: return 'e'; break; // Euclidean distance case 7: return 'b'; break; // City-block distance // The code will never get here. default: return 'e'; //Euclidean distance is default. } } - (IBAction)FileOpen:(id)sender { int result; NSOpenPanel *oPanel = [NSOpenPanel openPanel]; [statusbar setStringValue: @"Opening file"]; [self InitDir]; result = [oPanel runModalForDirectory:directory file:nil types:nil]; if (result == NSOKButton) { NSString *aFile = [oPanel filename]; FileHandle inputfile; [self SaveDir: aFile]; if (!OpenFile(&inputfile, aFile, "rt")) { NSRunCriticalAlertPanel(@"Error opening file", @"Error", @"OK", nil, nil); return; } char* result = Load(inputfile.pointer); CloseFile(inputfile); [FileMemo setStringValue: @""]; [JobName setStringValue: @""]; [Rows setStringValue: @""]; [Columns setStringValue: @""]; [self FilterReset]; if (!result) { NSRunCriticalAlertPanel(@"Error reading file", @"Insufficient memory", @"OK", nil, nil); [statusbar setStringValue: [@"Error reading file " stringByAppendingString: aFile]]; return; } else if (strcmp(result, "ok")!=0) { NSRunCriticalAlertPanel(@"Error in data file", [NSString stringWithCString: result], @"OK", nil, nil); free(result); [statusbar setStringValue: [@"Error reading file " stringByAppendingString: aFile]]; return; } [statusbar setStringValue: @"Done loading data"]; /* Extract job name from file name */ [JobName setStringValue: [[aFile lastPathComponent] stringByDeletingPathExtension]]; [FileMemo setStringValue: aFile]; [self UpdateInfo]; } else { [statusbar setStringValue: @"Cancelled"]; } } - (IBAction)FileSave:(id)sender { NSSavePanel *sPanel; int result; /* create or get the shared instance of NSSavePanel */ sPanel = [NSSavePanel savePanel]; [statusbar setStringValue: @"Saving data to file"]; [statusbar display]; [self InitDir]; /* display the NSSavePanel */ result = [sPanel runModalForDirectory:directory file:[[JobName stringValue] stringByAppendingPathExtension:@"txt"]]; /* if successful, save file under designated name */ if (result == NSOKButton) { NSString *aFile = [sPanel filename]; [[NSFileManager defaultManager] createFileAtPath: aFile contents: nil attributes: nil]; FileHandle outputfile; [self SaveDir: aFile]; if (!OpenFile(&outputfile, aFile, "wt")) { [statusbar setStringValue: @"Error: Unable to open the output file"]; return; } result = Save(outputfile.pointer, 0, 0); CloseFile(outputfile); if (result) [statusbar setStringValue: @"Finished saving file"]; else { NSRunCriticalAlertPanel(@"Error saving file", @"Insufficient memory", @"OK", nil, nil); [statusbar setStringValue: @"Error saving to file"]; } } else { [statusbar setStringValue: @"Cancelled"]; } } - (IBAction)ShowHelpManual:(id)sender { [[NSWorkspace sharedWorkspace] openFile: @"/Applications/Cluster.app/Contents/Resources/cluster3.pdf"]; } - (IBAction)ShowHelpDownload:(id)sender { [[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: @"http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/manual"]]; } - (IBAction)FilterApply:(id)sender { [self FilterReset]; const int rows = GetRows(); /* Store results in boolean use */ free(use); use = malloc(rows*sizeof(int)); useRows = 0; const BOOL bStd = [FilterStdXB state]; const BOOL bPercent = [FilterPercentXB state]; const BOOL bAbsVal = [FilterObservationXB state]; const BOOL bMaxMin = [FilterMaxMinXB state]; /* Read information from the edit boxes */ const double absVal = [[FilterObservationValue stringValue] doubleValue]; const double percent = [[FilterPercent stringValue] doubleValue]; const double std = [[FilterStd stringValue] doubleValue]; const int numberAbs = [FilterNumber intValue]; const double maxmin = [[FilterMaxMin stringValue] doubleValue]; /* Note: Applying doubleValue directly on a NSTextField causes the text to * be interpreted with following the current localization. In particular, * with European localization settings, numbers such as 0.02 are * misinterpreted, as they should be 0,02 according to that localization. * However, applying doubleValue to an NSString instance always expects the * US number format. */ int Row; for (Row = 0; Row < rows; Row++) { [statusbar setStringValue: [NSString stringWithFormat: @"Assessing filters for gene %d", Row]]; use[Row] = FilterRow(Row,bStd,bPercent,bAbsVal,bMaxMin,absVal,percent,std,numberAbs,maxmin); /* Count how many passed */ if (use[Row]) useRows++; } /* Tell user how many rows passed */ [filterresult setStringValue: [NSString stringWithFormat: @"%d passed out of %d", useRows, rows]]; [filteraccept setEnabled: TRUE]; [statusbar setStringValue: @"Done Analyzing Filters"]; } - (IBAction)FilterAccept:(id)sender { int ok; [filteraccept setEnabled: FALSE]; ok = SelectSubset(useRows, use); if (!ok) { NSRunCriticalAlertPanel(@"Insufficient memory", @"Memory allocation error", @"OK", nil, nil); [statusbar setStringValue: @"Error accepting filter"]; } else [self UpdateInfo]; } - (IBAction)AdjustApply:(id)sender { int ok; [statusbar setStringValue: @"Adjusting data"]; [statusbar display]; const BOOL bLogTransform = [AdjustLogXB state]; if (bLogTransform) LogTransform(); const int GeneCenter = [AdjustCenterGenesXB state]; const int GeneMeanCenter = GeneCenter && [AdjustMeanGenes state]; const int GeneMedianCenter = GeneCenter && [AdjustMedianGenes state]; const int GeneNormalize = [AdjustNormalizeGenes state]; ok = AdjustGenes(GeneMeanCenter, GeneMedianCenter, GeneNormalize); if (!ok) { NSRunCriticalAlertPanel(@"Insufficient memory", @"Memory allocation error", @"OK", nil, nil); [statusbar setStringValue: @"Error adjusting genes"]; return; } const int ArrayCenter = [AdjustCenterArraysXB state]; const int ArrayMeanCenter = ArrayCenter && [AdjustMeanArrays state]; const int ArrayMedianCenter = ArrayCenter && [AdjustMedianArrays state]; const int ArrayNormalize = [AdjustNormalizeArrays state]; ok = AdjustArrays(ArrayMeanCenter, ArrayMedianCenter, ArrayNormalize); if (!ok) { NSRunCriticalAlertPanel(@"Insufficient memory", @"Memory allocation error", @"OK", nil, nil); [statusbar setStringValue: @"Error adjusting arrays"]; return; } [statusbar setStringValue: @"Done adjusting data"]; } - (IBAction)AdjustCenterGenesXBChanged:(id)sender { if ([AdjustCenterGenesXB state]) { [AdjustMeanGenes setEnabled: true]; [AdjustMedianGenes setEnabled: true]; } else { [AdjustMeanGenes setEnabled: false]; [AdjustMedianGenes setEnabled: false]; } } - (IBAction)AdjustCenterArraysXBChanged:(id)sender { if ([AdjustCenterArraysXB state]) { [AdjustMeanArrays setEnabled: true]; [AdjustMedianArrays setEnabled: true]; } else { [AdjustMeanArrays setEnabled: false]; [AdjustMedianArrays setEnabled: false]; } } - (IBAction)HierarchicalGeneWeightXBChanged:(id)sender { if ([HierarchicalGeneWeightXB state]) { [HierarchicalArrays addSubview: HierarchicalArrayWeight]; } else { [HierarchicalArrayWeight retain]; [HierarchicalArrayWeight removeFromSuperview]; } } - (IBAction)HierarchicalArrayWeightXBChanged:(id)sender { if ([HierarchicalArrayWeightXB state]) { [HierarchicalGenes addSubview: HierarchicalGeneWeight]; } else { [HierarchicalGeneWeight retain]; [HierarchicalGeneWeight removeFromSuperview]; } } - (IBAction)HierarchicalCentroid:(id)sender { NSString* method = @"c"; /* Multithreading is not yet implemented, but this is how it would look like [NSThread detachNewThreadSelector: @selector(HierarchicalExecute:) toTarget: self withObject: method]; */ [self HierarchicalExecute: method]; } - (IBAction)HierarchicalSingle:(id)sender { NSString* method = @"s"; /* Multithreading is not yet implemented, but this is how it would look like [NSThread detachNewThreadSelector: @selector(HierarchicalExecute:) toTarget: self withObject: method]; */ [self HierarchicalExecute: method]; } - (IBAction)HierarchicalComplete:(id)sender { NSString* method = @"m"; /* Multithreading is not yet implemented, but this is how it would look like [NSThread detachNewThreadSelector: @selector(HierarchicalExecute:) toTarget: self withObject: method]; */ [self HierarchicalExecute: method]; } - (IBAction)HierarchicalAverage:(id)sender { NSString* method = @"a"; /* Multithreading is not yet implemented, but this is how it would look like [NSThread detachNewThreadSelector: @selector(HierarchicalExecute:) toTarget: self withObject: method]; */ [self HierarchicalExecute: method]; } - (void)HierarchicalExecute:(NSString*)method_string { int ok; const int rows = GetRows(); const int columns = GetColumns(); const char method = *([method_string cString]); if (rows==0 || columns==0) { [statusbar setStringValue: @"No data available"]; return; } // Find out what we need to do here const BOOL ClusterGenes = [HierarchicalGeneXB state]; const BOOL ClusterArrays = [HierarchicalArrayXB state]; if(!ClusterGenes && !ClusterArrays) return; // Nothing to do here const BOOL bCalculateGeneWeights = [HierarchicalGeneWeightXB state]; const BOOL bCalculateArrayWeights = [HierarchicalArrayWeightXB state]; /* For a multithreaded application, this routine would need its own * autorelease pool. NSAutoreleasePool* threadPool = [[NSAutoreleasePool alloc] init]; */ NSString* base = [[FileMemo stringValue] stringByDeletingLastPathComponent]; NSString* jobname = [base stringByAppendingPathComponent: [JobName stringValue]]; // Find out which metrics to use const char genemetric = [self GetMetric: HierarchicalGeneMetric]; const char arraymetric = [self GetMetric: HierarchicalArrayMetric]; if (bCalculateGeneWeights || bCalculateArrayWeights) { const char* error; double gene_cutoff = 0.0; double gene_exponent = 0.0; double array_cutoff = 0.0; double array_exponent = 0.0; [statusbar setStringValue: @"Calculating weights"]; [statusbar display]; if (bCalculateGeneWeights) { array_cutoff = [[HierarchicalArrayCutoff stringValue] doubleValue]; array_exponent = [[HierarchicalArrayExp stringValue] doubleValue]; } if (bCalculateArrayWeights) { gene_cutoff = [[HierarchicalGeneCutoff stringValue] doubleValue]; gene_exponent = [[HierarchicalGeneExp stringValue] doubleValue]; } error = CalculateWeights(gene_cutoff, gene_exponent, genemetric, array_cutoff, array_exponent, arraymetric); if (error) { [statusbar setStringValue: [NSString stringWithCString: error]]; return; } } switch(method) { case 'c': [statusbar setStringValue: @"Performing centroid linkage hierarchical clustering"]; break; case 's': [statusbar setStringValue: @"Performing single linkage hierarchical clustering"]; break; case 'm': [statusbar setStringValue: @"Performing complete linkage hierarchical clustering"]; break; case 'a': [statusbar setStringValue: @"Performing average linkage hierarchical clustering"]; break; } [statusbar display]; if (ClusterGenes) { NSString* filename = [jobname stringByAppendingPathExtension: @"gtr"]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; FileHandle outputfile; if (!OpenFile(&outputfile, filename, "wt")) { [statusbar setStringValue: @"Error: Unable to open the output file"]; return; } ok = HierarchicalCluster(outputfile.pointer, genemetric, 0, method); CloseFile(outputfile); if (!ok) { [statusbar setStringValue: @"Error: Insufficient memory"]; return; } } if (ClusterArrays) { NSString* filename = [jobname stringByAppendingPathExtension: @"atr"]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; FileHandle outputfile; if (!OpenFile(&outputfile, filename, "wt")) { [statusbar setStringValue: @"Error: Unable to open the output file"]; return; } ok = HierarchicalCluster(outputfile.pointer, arraymetric, 1, method); CloseFile(outputfile); if (!ok) { [statusbar setStringValue: @"Error: Insufficient memory"]; return; } } [statusbar setStringValue: @"Saving the clustering result"]; [statusbar display]; // Now make output .cdt file NSString* filename = [jobname stringByAppendingPathExtension: @"cdt"]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; FileHandle outputfile; if (!OpenFile(&outputfile, filename, "wt")) { [statusbar setStringValue: @"Error: Unable to open the output file"]; return; } ok = Save(outputfile.pointer, ClusterGenes, ClusterArrays); CloseFile(outputfile); if (!ok) { NSRunCriticalAlertPanel(@"Error saving file", @"Insufficient memory", @"OK", nil, nil); [statusbar setStringValue: @"Error saving to file"]; } else [statusbar setStringValue: @"Done Clustering"]; /* Release this thread's autorelease pool here in a multithreaded application [threadPool release]; */ } - (IBAction)KMeansExecute:(id)sender { int ok; const int rows = GetRows(); const int columns = GetColumns(); if (rows==0 || columns==0) { [statusbar setStringValue: @"No data available"]; return; } NSString* base = [[FileMemo stringValue] stringByDeletingLastPathComponent]; NSString* jobname = [base stringByAppendingPathComponent: [JobName stringValue]]; const BOOL ClusterGenes = [KMeansGeneXB state]; const BOOL ClusterArrays = [KMeansArrayXB state]; if (!ClusterGenes && !ClusterArrays) return; // Nothing to do [statusbar setStringValue: @"Executing k-means clustering"]; [statusbar display]; int kGenes = 0; int kArrays = 0; if (ClusterGenes) { kGenes = [KMeansGeneK intValue]; if (kGenes==0) { [statusbar setStringValue: @"Choose a nonzero number of clusters"]; return; } if (rows < kGenes) { [statusbar setStringValue: @"More clusters than genes available"]; return; } const char method = [KMeansGeneMean state] ? 'a' : 'm'; // 'a' is average, 'm' is median const char dist = [self GetMetric: KMeansGeneMetric]; int *NodeMap = malloc(rows*sizeof(int)); const int nGeneTrials = [KMeansGeneRuns intValue]; ok = 1; NSString* filename = nil; int ifound = GeneKCluster(kGenes, nGeneTrials, method, dist, NodeMap); if (ifound < 0) ok = 0; if (ok) { [statusbar setStringValue: [NSString stringWithFormat: @"Solution was found %d times", ifound]]; filename = [jobname stringByAppendingFormat: @"_K_G%d.kgg", kGenes]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; FileHandle outputfile; if (!OpenFile(&outputfile, filename, "wt")) { [statusbar setStringValue: @"Error: Unable to open the output file"]; free(NodeMap); return; } ok = SaveGeneKCluster(outputfile.pointer, kGenes, NodeMap); CloseFile(outputfile); } free(NodeMap); if (!ok) { NSRunCriticalAlertPanel(@"Insufficient memory", @"Memory allocation problem", @"OK", nil, nil); [statusbar setStringValue: [@"Error saving file " stringByAppendingString: filename]]; return; } } if (ClusterArrays) { kArrays = [KMeansArrayK intValue]; if (kArrays==0) { [statusbar setStringValue: @"Choose a nonzero number of clusters"]; return; } if (columns < kArrays) { [statusbar setStringValue: @"More clusters than experiments available"]; return; } const char method = [KMeansArrayMean state] ? 'a' : 'm'; // 'a' is average, 'm' is median const char dist = [self GetMetric: KMeansArrayMetric]; int *NodeMap = malloc(columns*sizeof(int)); const int nArrayTrials = [KMeansArrayRuns intValue]; ok = 1; NSString* filename = nil; int ifound = ArrayKCluster(kArrays, nArrayTrials, method, dist, NodeMap); if (ifound < 0) ok = 0; if (ok) { [statusbar setStringValue: [NSString stringWithFormat: @"Solution was found %d times", ifound]]; filename = [jobname stringByAppendingFormat: @"_K_A%d.kag", kArrays]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; FileHandle outputfile; if (!OpenFile(&outputfile, filename, "wt")) { [statusbar setStringValue: @"Error: Unable to open the output file"]; free(NodeMap); return; } ok = SaveArrayKCluster(outputfile.pointer, kArrays, NodeMap); CloseFile(outputfile); } free(NodeMap); if (!ok) { NSRunCriticalAlertPanel(@"Insufficient memory", @"Memory allocation problem", @"OK", nil, nil); [statusbar setStringValue: [@"Error saving file " stringByAppendingString: filename]]; return; } } NSString* filename = 0; if (ClusterGenes && ClusterArrays) filename = [jobname stringByAppendingFormat: @"_K_G%d_A%d", kGenes, kArrays]; else if (ClusterGenes) filename = [jobname stringByAppendingFormat: @"_K_G%d", kGenes]; else if (ClusterArrays) filename = [jobname stringByAppendingFormat: @"_K_A%d", kArrays]; filename = [filename stringByAppendingPathExtension: @"cdt"]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; FileHandle outputfile; if (!OpenFile(&outputfile, filename, "wt")) { [statusbar setStringValue: @"Error: Unable to open the output file"]; return; } ok = Save(outputfile.pointer, 0, 0); CloseFile(outputfile); if (!ok) { NSRunCriticalAlertPanel(@"Error saving file", @"Insufficient memory", @"OK", nil, nil); [statusbar setStringValue: @"Error saving to file"]; } else [statusbar setStringValue: @"Finished saving file"]; } - (IBAction)SOMExecute:(id)sender { const int rows = GetRows(); const int columns = GetColumns(); if (rows==0 || columns==0) { [statusbar setStringValue: @"No data available"]; return; } const BOOL ClusterGenes = [SOMGeneXB state]; const BOOL ClusterArrays = [SOMArrayXB state]; if (!ClusterGenes && ! ClusterArrays) return; // Nothing to do here const int GeneXDim = ClusterGenes ? [SOMGeneXDim intValue] : 0; const int GeneYDim = ClusterGenes ? [SOMGeneYDim intValue] : 0; const int ArrayXDim = ClusterArrays ? [SOMArrayXDim intValue] : 0; const int ArrayYDim = ClusterArrays ? [SOMArrayYDim intValue] : 0; if((ClusterGenes && (GeneXDim==0 || GeneYDim==0)) || (ClusterArrays && (ArrayXDim==0 || ArrayYDim==0))) { [statusbar setStringValue: @"Error starting SOM: Check SOM dimensions"]; return; } const int GeneIters = ClusterGenes ? [SOMGeneIters intValue] : 0; const double GeneTau = [[SOMGeneTau stringValue] doubleValue]; const char GeneMetric = [self GetMetric: SOMGeneMetric]; const int ArrayIters = ClusterArrays ? [SOMArrayIters intValue] : 0; const double ArrayTau = [[SOMArrayTau stringValue] doubleValue]; const char ArrayMetric = [self GetMetric: SOMArrayMetric]; FileHandle GeneFile; FileHandle ArrayFile; FileHandle DataFile; NSString* filename; NSString* base = [[FileMemo stringValue] stringByDeletingLastPathComponent]; NSString* jobname = [base stringByAppendingPathComponent: [JobName stringValue]]; [statusbar setStringValue: @"Calculating Self-Organizing Map"]; [statusbar display]; // To make sure statusbar gets updated before the calculation starts NSMutableString* basename = [NSMutableString stringWithCapacity: 0]; [basename appendString: jobname]; [basename appendString: @"_SOM"]; if(ClusterGenes) [basename appendFormat: @"_G%d-%d", GeneXDim, GeneYDim]; if(ClusterArrays) [basename appendFormat: @"_A%d-%d", ArrayXDim, ArrayYDim]; filename = [basename stringByAppendingPathExtension: @"txt"]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; if (!OpenFile(&DataFile, filename, "wt")) { [statusbar setStringValue: @"Error: Unable to open the output file"]; return; } if (ClusterGenes) { if((GeneIters<=0)||(GeneTau==0)||(GeneXDim==0)||(GeneYDim==0)) { CloseFile(DataFile); [statusbar setStringValue: @"Error starting SOM: Check options"]; return; } filename = [basename stringByAppendingPathExtension: @"gnf"]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; if(!OpenFile(&GeneFile, filename, "wt")) { CloseFile(DataFile); [statusbar setStringValue: @"Error: Unable to open the output file"]; return; } } if (ClusterArrays) { if((ArrayIters<=0)||(ArrayTau==0)||(ArrayXDim==0)||(ArrayYDim==0)) { [statusbar setStringValue: @"Error starting SOM: Check options"]; CloseFile(DataFile); if(ClusterGenes) CloseFile(GeneFile); return; } filename = [basename stringByAppendingPathExtension: @"anf"]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; if (!OpenFile(&ArrayFile, filename, "wt")) { [statusbar setStringValue: @"Error: Unable to open the output file"]; CloseFile(DataFile); if(ClusterGenes) CloseFile(GeneFile); return; } } int ok = PerformSOM(GeneFile.pointer, GeneXDim, GeneYDim, GeneIters, GeneTau, GeneMetric, ArrayFile.pointer, ArrayXDim, ArrayYDim, ArrayIters, ArrayTau, ArrayMetric); if (ClusterGenes) CloseFile(GeneFile); if (ClusterArrays) CloseFile(ArrayFile); if (!ok) { NSRunCriticalAlertPanel(@"Insufficient memory", @"Memory allocation problem", @"OK", nil, nil); [statusbar setStringValue: @"Error performing SOM"]; return; } ok = Save(DataFile.pointer, 0, 0); CloseFile(DataFile); if (!ok) { NSRunCriticalAlertPanel(@"Error saving file", @"Insufficient memory", @"OK", nil, nil); [statusbar setStringValue: @"Error saving to file"]; } else [statusbar setStringValue: @"Done making SOM"]; } - (IBAction)PCAExecute:(id)sender { NSString* filename; FileHandle coordinatefile; FileHandle pcfile; const char* error; const BOOL DoGenePCA = [PCAGeneXB state]; const BOOL DoArrayPCA = [PCAArrayXB state]; if (!DoGenePCA && !DoArrayPCA) return; // Nothing to do const int rows = GetRows(); const int columns = GetColumns(); if (rows==0 || columns==0) { [statusbar setStringValue: @"No data available"]; return; } NSString* base = [[FileMemo stringValue] stringByDeletingLastPathComponent]; NSString* jobname = [base stringByAppendingPathComponent: [JobName stringValue]]; if (DoGenePCA) { [statusbar setStringValue: @"Performing Principal Component Analysis"]; [statusbar display]; filename = [NSString stringWithString: jobname]; filename = [filename stringByAppendingString: @"_pca_gene.coords"]; filename = [filename stringByAppendingPathExtension: @"txt"]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; if (!OpenFile(&coordinatefile, filename, "wt")) { [statusbar setStringValue: @"Error: Unable to open the output file"]; return; } filename = [NSString stringWithString: jobname]; filename = [filename stringByAppendingString: @"_pca_gene.pc"]; filename = [filename stringByAppendingPathExtension: @"txt"]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; if (!OpenFile(&pcfile, filename, "wt")) { CloseFile(coordinatefile); [statusbar setStringValue: @"Error: Unable to open the output file"]; return; } error = PerformGenePCA(coordinatefile.pointer, pcfile.pointer); CloseFile(coordinatefile); CloseFile(pcfile); if (error) { [statusbar setStringValue: [NSString stringWithCString: error]]; return; } [statusbar setStringValue: @"Finished Principal Component Analysis"]; } if (DoArrayPCA) { [statusbar setStringValue: @"Performing Principal Component Analysis"]; [statusbar display]; filename = [NSString stringWithString: jobname]; filename = [filename stringByAppendingString: @"_pca_array.coords"]; filename = [filename stringByAppendingPathExtension: @"txt"]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; if (!OpenFile(&coordinatefile, filename, "wt")) { [statusbar setStringValue: @"Error: Unable to open the output file"]; return; } filename = [NSString stringWithString: jobname]; filename = [filename stringByAppendingString: @"_pca_array.pc"]; filename = [filename stringByAppendingPathExtension: @"txt"]; [[NSFileManager defaultManager] createFileAtPath: filename contents: nil attributes: nil]; if (!OpenFile(&pcfile, filename, "wt")) { CloseFile(coordinatefile); [statusbar setStringValue: @"Error: Unable to open the output file"]; return; } error = PerformArrayPCA(coordinatefile.pointer, pcfile.pointer); CloseFile(coordinatefile); CloseFile(pcfile); if (error) { [statusbar setStringValue: [NSString stringWithCString: error]]; return; } [statusbar setStringValue: @"Finished Principal Component Analysis"]; } } - (IBAction)ShowFileFormatPanel:(id)sender { if(FileFormatPanel==nil) { if(![NSBundle loadNibNamed: @"FileFormatPanel.nib" owner:self] ) { NSLog(@"Load of FileFormatPanel.nib failed"); return; } } [FileFormatPanel makeKeyAndOrderFront: nil]; } - (IBAction)ShowAboutPanel:(id)sender { if(AboutPanel==nil) { if(![NSBundle loadNibNamed: @"AboutPanel.nib" owner:self] ) { NSLog(@"Load of AboutPanel.nib failed"); return; } } [AboutPanel makeKeyAndOrderFront: nil]; } @end @implementation Controller(ApplicationNotifications) - (void)applicationDidFinishLaunching:(NSNotification *) aNotification { [AdjustMeanGenes setEnabled: false]; [AdjustMedianGenes setEnabled: false]; [AdjustMeanArrays setEnabled: false]; [AdjustMedianArrays setEnabled: false]; [HierarchicalGeneWeight retain]; [HierarchicalGeneWeight removeFromSuperview]; [HierarchicalArrayWeight retain]; [HierarchicalArrayWeight removeFromSuperview]; } - (void)applicationWillTerminate:(NSNotification *)aNotification { Free(); } @end cluster-1.52a/mac/cluster.icns0000644000100500010050000010253707552061626016231 0ustar mdehoonmdehoonicns…_ics#His32ý‡@€€À…€€À@…€Àƒ€‚@‚ƒ€‚¿€€À¿†ƒ€…@€€@€À€€€€ @¿€¿¿„@€@„¿€†€‚„¿¿‚†@€Š¿€‡@€€À…€€À@…€Àƒ€‚@‚ƒ€‚¿€€À¿†ƒ€…@€€@€À€€€€ @¿€¿¿„@€@„¿€†€‚„¿¿‚†@€Š¿€‡ÿ¿?€€…ÿ?ÿÿ¿€€…ÿ€ÿ?€ÿÿƒ€‚ÿ¿€ÿÿ€‚ÿ€ƒÿÿÿ€‚ÿ@€?€€@ÿÿ€†ÿƒ€…ÿ¿ÿÿ€€ÿ¿?ÿÿÿÿ€€ÿÿ ¿€€@ÿÿ€ÿÿ@@„ÿ¿ÿÿ€ÿÿ€¿„€@ÿÿ€†ÿ‚ÿ€„ÿ@€@‚ÿ†€¿Šÿ€@s8mkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿICN#ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿil325˜‚ÿ’„ÿ–ÿ‚‚ÿƒÿ—ÿÿ„€ÿÿ†ÿÿ‰€ÿŠÿÿˆÿÿˆÿŠÿÿÿˆÿ…ƒÿ‚ÿˆ‡ÿÿÿÿ‘ÿ‡ÿ‘„ÿÿ˜‚ÿ†ÿÿÿ‰ÿ…ˆÿÿÿ…ÿ†ƒÿ„ÿ…ÿ‹ÿÿ‚ÿ“ÿ‚ÿÿŒ€ÿÿ‚ÿŽÿƒÿ‚ÿ€ÿ„ÿœÿÿÿ‡ÿŒ‚ÿˆÿŒÿ€ÿÿ‡Žÿœÿ€ÿ—ÿœ€ÿ˜‚ÿ’„ÿ–ÿ‚‚ÿƒÿ—ÿÿ„€ÿÿ†ÿÿ‰€ÿŠÿÿˆÿÿˆÿŠÿÿÿˆÿ…ƒÿ‚ÿˆ‡ÿÿÿÿ‘ÿ‡ÿ‘„ÿÿ˜‚ÿ†ÿÿÿ‰ÿ…ˆÿÿÿ…ÿ†ƒÿ„ÿ…ÿ‹ÿÿ‚ÿ“ÿ‚ÿÿŒ€ÿÿ‚ÿŽÿƒÿ‚ÿ€ÿ„ÿœÿÿÿ‡ÿŒ‚ÿˆÿŒÿ€ÿÿ‡Žÿœÿ€ÿ—ÿœ€ÿ˜ÿ‚’ÿ„–ÿ‚ÿ‚ÿƒ—ÿÿ„ÿ€ÿÿ†ÿ‰ÿ€ÿŠÿˆÿÿˆÿŠÿÿˆÿ…ÿƒ‚ÿˆÿ‡ÿÿ‘ÿ‡ÿ‘ÿ„ÿ˜ÿ‚ÿ†ÿÿ‰ÿ…ÿˆÿÿ…ÿ†ÿƒ„ÿ…ÿ‹ÿÿ‚ÿ“ÿ‚ÿÿÿŒÿ€ÿ‚ÿÿÿŽƒÿ‚ÿÿ€ÿ„œÿÿ‡ÿŒÿ‚ˆÿŒÿ€ÿ‡ÿŽœÿÿÿ€—ÿœÿ€l8mkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿich#Hih32楄ÿœ?…¿ÿƒ€œ‡ÿ¢ÿ„„ÿ•„¿ÿ„@„€•†ÿ¤ÿ€‚ÿ‡ÿ•ÿ€‚ÿ‡¿ÿ€€•ÿ€‚Šÿ˜ÿ€Žÿƒÿ€Ž@€ƒÿ€™ÿ€ÿ€™ÿ€ÿ€€ƒÿ€ÿ€€ÿƒÿ€ÿ€ˆ…ÿ€„ÿ€ÿ¿ˆ¿ÿƒ€ÿ¿ƒÿ€Œÿƒ€ÿƒÿ€šÿŒÿ€šÿ†ƒÿ€š‡ÿƒÿ€¥ƒÿ€—?Š„ÿ€—Šÿƒÿ€—ÿÿ€ˆ?‹¿ÿƒƒƒÿ€ˆÿƒƒÿƒÿ€ˆÿŠ…ÿ€‡ÿ€ˆÿŠ@„€ÿ¿ƒÿ€ˆÿ’ƒÿƒÿ€„ƒÿžÿ€„ÿÀ€€¿ÿ“?ƒÿ€„ÿ€ÿ“ÿƒÿ€„ÿ€–ÿ†ÿ€„ÿ€@”€¿ÿ€ƒÿ€„ÿ€—ÿƒ‡ÿ€¢†€ÿ€™€Œÿ€™€ÿŒÿ€“„ÿ€ÿ€“ÿÀ€ÿ¿Œÿ€“ÿ€€ÿŒ–ÿ€“•€ÿ€?¤ÿ€ÿ¤ƒÿ§€¿ÿ€¨ÿ¥„ÿœ?…¿ÿƒ€œ‡ÿ¢ÿ„„ÿ•„¿ÿ„@„€•†ÿ¤ÿ€‚ÿ‡ÿ•ÿ€‚ÿ‡¿ÿ€€•ÿ€‚Šÿ˜ÿ€Žÿƒÿ€Ž@€ƒÿ€™ÿ€ÿ€™ÿ€ÿ€€ƒÿ€ÿ€€ÿƒÿ€ÿ€ˆ…ÿ€„ÿ€ÿ¿ˆ¿ÿƒ€ÿ¿ƒÿ€Œÿƒ€ÿƒÿ€šÿŒÿ€šÿ†ƒÿ€š‡ÿƒÿ€¥ƒÿ€—?Š„ÿ€—Šÿƒÿ€—ÿÿ€ˆ?‹¿ÿƒƒƒÿ€ˆÿƒƒÿƒÿ€ˆÿŠ…ÿ€‡ÿ€ˆÿŠ@„€ÿ¿ƒÿ€ˆÿ’ƒÿƒÿ€„ƒÿžÿ€„ÿÀ€€¿ÿ“?ƒÿ€„ÿ€ÿ“ÿƒÿ€„ÿ€–ÿ†ÿ€„ÿ€@”€¿ÿ€ƒÿ€„ÿ€—ÿƒ‡ÿ€¢†€ÿ€™€Œÿ€™€ÿŒÿ€“„ÿ€ÿ€“ÿÀ€ÿ¿Œÿ€“ÿ€€ÿŒ–ÿ€“•€ÿ€?¤ÿ€ÿ¤ƒÿ§€¿ÿ€¨ÿ¥ÿ€„œÿÀ…€@ƒœÿ€‡¢ÿ€„ÿ€„•ÿ„€@„ÿ¿„•ÿ†¤ÿ‚ÿ€‡ÿ€•ÿ‚ÿ€‡€@€•ÿ‚ÿ€Š˜ÿŽÿ€ƒÿ€Žÿ¿ƒÿ™ÿÿ™ÿÿÿ€€ƒÿÿÿ€ƒÿÿˆÿ€…„ÿÿ@ˆ€@ƒ@€ƒÿÿŒƒÿ€ƒÿšÿ€Œÿšÿ€†€ƒÿšÿ€‡ƒÿ¥ÿƒ€—ÿÀŠ€„—ÿ€Šƒÿ—ÿ€ÿˆÿÀ‹€@ƒÿƒ€ƒÿˆÿ€ƒÿƒƒÿˆÿ€Šÿ€…‡ÿˆÿ€Šÿ¿„@€ƒÿˆÿ€’ÿƒƒÿ„ÿƒžÿ„ÿ?@“ÿÀ€ƒÿ„ÿÿÿ€“ÿ€ƒÿ„ÿÿÿ€–†ÿ„ÿÿÿ¿”@€€ƒÿ„ÿ—ÿ€ƒÿ‡¢ÿ†™ÿ€€Œÿ™ÿ€Œÿ“ÿ„ÿ“ÿ?@€Œÿ“ÿÿ€Œÿ–“ÿ•ÿÿÀ€¤ÿÿÿ€¤ÿƒ§ÿ@€€¨ÿ€h8mk ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿit32'‡çp¿ÿçp¿ÿÏ‘;ÇÿüçŒàÏ18T‘p¯·Ûÿñ«ŒÏ8?_‘·¿ßÿ🌀ÏT_‘¿ÇÛßïÿèoŒ@Ïp¿–ÿà?Þp¿ÿüçŽàãîï÷ÿãWŒÏp¿ÿçoŽ?W“ŸÏÿøÏŒÀÏp¿ÿà?Žp¿ÿ¼Ž;Çÿà?Žbp¨à¼TŽp¯·Ûÿà?Ž?Gk¼`Ž·¿ßÿà?Ž8@`€¼Ž¿ÇÛßïÿà?Ž 0@¼À“ÿà?ãÀÿüñðè‰àãîï÷ÿà?–‡¼Àÿ竟o‰?W“ŸÏÿà?–T`‡À¼Àÿà€@‰p¿ÿà?–p¿‡ÿ¼Àÿà€@‰p¿ÿãW–;Çÿüç„à¼Àÿà€@‰p¿ÿî“–p¯·Ûÿñ«„¼Àÿà€@‰p¿ÿ·¿ßÿ🄀¼Àÿà€@‰p¿ÿ÷Ï–¿ÇÛßïÿèo„@¼Àÿà€@‰p¿žÿà?ÃÀÿà€@‰bp¨™àãîï÷ÿãW„¼Àÿà€@‰/™?W“ŸÏÿøÏ„À¼Àÿà€@©p¿‡ÿŒ«;Çÿà€@©bp¨‡àŒT«pÜÿà€@©?Gk‡Œ`«ßÿà€@©8@`‡€Œ«¿Çïÿà€@© 0‡@ŒÀ®ÿà€@ÆÀÿüñðè¦àãøÿà€@ÆÀÿ竟o¦?WÏÿà€@ÆÀÿà€@¦Àÿà€@ÆÀÿà€@¦Àÿà€@®„ŒÀÿà€@¦Àÿà€@®T„pŒÀÿà€@¦Àÿà€@®`„ŒÀÿà€@¦Àÿà€@®„¿ŒÀÿà€@¦Àÿà€@®À„ÿŒÀÿà€@¦Àÿà€@™Ž;ÇÿüñðèààŒÀÿà€@¦Àÿà€@™T`ŽÀÇðÿ竟o??ŒÀÿà€@¦Àÿà€@™p¿‘ÿà€@ŽÀÿà€@¦ÀÿãW™;Çÿüç‹àãøÿãWŒÀÿà€@¦ÀÿîÀ¸”™p¯·Ûÿñ«‹ãÿîÀ¸”ppŒÀÿà€@¦ÀÿïÇ¿Ÿ™·¿ßÿ🋀àÿïÇ¿ŸŒÀÿà€@¦Àÿ÷ãßÏ™¿ÇÛßïÿèo‹@WÐÿ÷ãßÏ¿¿ŒÀÿà€@¦À£ÿà?‹À„ÿŒÀÿà€@¦¨žàãîï÷ÿà?‹¨„àŒÀÿà€@¦0ž?W“ŸÏÿà?‹0„?ŒÀÿà€@Ép¿ÿà?£Àÿà€@Ép¿ÿãW”ŒÀÿà€@Ép¿ÿî“”pŒÀÿà€@Ép¿ÿŒÀÿà€@Ép¿ÿ÷Ï”¿ŒÀÿà€@Ép¿—ÿŒÀÿà€@Ébp¨—àŒÀÿà€@É/—?ŒÀÿà€@çŒ;Çÿà€@ÁŸŒpÜÿà€@Á18TŸpŒßÿà€@Á8?_ŸŒ¿Çïÿà€@ÁT_Ÿ¿ÿà€@Áp¿ŸÿŒàãøÿà€@Áp¿ÿüçœàŒ?WÏÿà€@Áp¿ÿçoœ?ŒÀÿà€@Áp¿ÿà?«Àÿà€@™¡;Çÿà?‹ŒŒÀÿà€@™18T¡p¯·Ûÿà?‹TŒpŒÀÿà€@™8?_¡·¿ßÿà?‹`ŒŒÀÿà€@™T_¡¿ÇÛßïÿà?‹Œ¿ŒÀÿà€@™p¿¦ÿà?‹ÀŒÿŒÀÿà€@™p¿ÿüçžàãîï÷ÿãW‹;Çÿüñðè‡àŒÀÿà€@™p¿ÿçož?W“ŸÏÿøÏ‹ÀÇðÿ竟o‡?ŒÀÿà€@™p¿ÿà?žp¿‘ÿà€@–Àÿà€@™p¿ÿà?žbp¨ŽàãøÿãW‡ŒÀÿà€@™p¿ÿà?ž?GkŽãÿîÀ¸”‡pŒÀÿà€@™p¿ÿà?ž8@`Ž€àÿïÇ¿Ÿ‡ŒÀÿà€@™p¿ÿà?ž 0Ž@WÐÿ÷ãßχ¿ŒÀÿà€@™p¿ÿà?³ÀŒÿŒÀÿà€@ކ;Çÿà?³¨ŒàŒÀÿà€@ކÀÇÜßïÿà?³0Œ?ŒÀÿà€@ŽÀ‹ÿà?ÓÀÿà€@ŽÀÿüñðèàãîï÷ÿà?¶‡ŒÀÿà€@ŽÀÿñÎÇ«ÀÇãÿà?¶18T‡pŒÀÿà€@ŽÀÿðÇÀ €¸¿ßÿà?¶8?_‡ŒÀÿà€@ŽÀÿè« p@W”ŸÏÿà?¶T_‡¿ŒÀÿà€@ŽÀÿà€@p¿ÿà?¶p¿‡ÿŒÀÿà€@ŽÀÿà€@p¿ÿãW¶;Çÿüç„àŒÀÿà€@ŽÀÿà€@p¿ÿøÏ¶ÀÇÜßïÿço„?ŒÀÿà€@ŽÀÿà€@p¿¾ÿà?“Àÿà€@ŽÀÿà€@bp¨¹àãîï÷ÿãW„ŒÀÿà€@ŽÀÿà€@?Gk¹ÀÇãÿî“„pŒÀÿà€@ŽÀÿà€@8@`¹€¸¿ßÿŒÀÿà€@ŽÀÿà€@ 0¹@W”ŸÏÿ÷Ï„¿ŒÀÿà€@ŽÀÿà€@Áp¿‡ÿŒÀÿãWŽ;Çÿà€@Ábp¨‡àŒÀÿøãàÐŽÀÇðÿà€@Á/‡?ŒÀ–ÿà€@Þ¨“àãøÿà€@Æ„Œl“ãÿà€@ÆT„pŒ`“€àÿà€@Æ`„Œ0“@WÐÿà€@Æ„¿¤Àÿà€@ÆÀ„ÿ¤Àÿà€@¶‹;Çÿüñðèàà¤Àÿà€@¶‹ÀÇðÿ竟o??¤Àÿà€@¶ÀŽÿà€@¦Àÿà€@¶Àÿüñðè†àãøÿãW¤Àÿà€@¶ÀÿñÎÇ«†ãÿîÀ¸”pp¤Àÿà€@¶ÀÿðÇÀ †€àÿïÇ¿Ÿ¤Àÿà€@¶Àÿè« p†@WÐÿ÷ãßÏ¿¿¤Àÿà€@¶Àÿà€@†À„ÿ¤ÀÿãW¶;Çÿà€@†¨„à¤ÀÿøãàжÀÇðÿà€@†0„?¤À¾ÿà€@¶¨»àãøÿà€@‡¤l»ãÿà€@18T‡p¤`»€àÿà€@8?_‡¤0»@WÐÿà€@T_‡¿äÀÿà€@p¿‡ÿäÀÿãW;Çÿüç„àäÀÿøãàÐÀÇÜßïÿço„?äÀ‹ÿà?먆àãîï÷ÿãW„äl†ÀÇãÿî“„pä`†€¸¿ßÿä0†@W”ŸÏÿ÷Ï„¿ïp¿‡ÿïp¿‡ÿçp¿ÿçp¿ÿÏ‘;ÇÿüçŒàÏ18T‘p¯·Ûÿñ«ŒÏ8?_‘·¿ßÿ🌀ÏT_‘¿ÇÛßïÿèoŒ@Ïp¿–ÿà?Þp¿ÿüçŽàãîï÷ÿãWŒÏp¿ÿçoŽ?W“ŸÏÿøÏŒÀÏp¿ÿà?Žp¿ÿ¼Ž;Çÿà?Žbp¨à¼TŽp¯·Ûÿà?Ž?Gk¼`Ž·¿ßÿà?Ž8@`€¼Ž¿ÇÛßïÿà?Ž 0@¼À“ÿà?ãÀÿüñðè‰àãîï÷ÿà?–‡¼Àÿ竟o‰?W“ŸÏÿà?–T`‡À¼Àÿà€@‰p¿ÿà?–p¿‡ÿ¼Àÿà€@‰p¿ÿãW–;Çÿüç„à¼Àÿà€@‰p¿ÿî“–p¯·Ûÿñ«„¼Àÿà€@‰p¿ÿ·¿ßÿ🄀¼Àÿà€@‰p¿ÿ÷Ï–¿ÇÛßïÿèo„@¼Àÿà€@‰p¿žÿà?ÃÀÿà€@‰bp¨™àãîï÷ÿãW„¼Àÿà€@‰/™?W“ŸÏÿøÏ„À¼Àÿà€@©p¿‡ÿŒ«;Çÿà€@©bp¨‡àŒT«pÜÿà€@©?Gk‡Œ`«ßÿà€@©8@`‡€Œ«¿Çïÿà€@© 0‡@ŒÀ®ÿà€@ÆÀÿüñðè¦àãøÿà€@ÆÀÿ竟o¦?WÏÿà€@ÆÀÿà€@¦Àÿà€@ÆÀÿà€@¦Àÿà€@®„ŒÀÿà€@¦Àÿà€@®T„pŒÀÿà€@¦Àÿà€@®`„ŒÀÿà€@¦Àÿà€@®„¿ŒÀÿà€@¦Àÿà€@®À„ÿŒÀÿà€@¦Àÿà€@™Ž;ÇÿüñðèààŒÀÿà€@¦Àÿà€@™T`ŽÀÇðÿ竟o??ŒÀÿà€@¦Àÿà€@™p¿‘ÿà€@ŽÀÿà€@¦ÀÿãW™;Çÿüç‹àãøÿãWŒÀÿà€@¦ÀÿîÀ¸”™p¯·Ûÿñ«‹ãÿîÀ¸”ppŒÀÿà€@¦ÀÿïÇ¿Ÿ™·¿ßÿ🋀àÿïÇ¿ŸŒÀÿà€@¦Àÿ÷ãßÏ™¿ÇÛßïÿèo‹@WÐÿ÷ãßÏ¿¿ŒÀÿà€@¦À£ÿà?‹À„ÿŒÀÿà€@¦¨žàãîï÷ÿà?‹¨„àŒÀÿà€@¦0ž?W“ŸÏÿà?‹0„?ŒÀÿà€@Ép¿ÿà?£Àÿà€@Ép¿ÿãW”ŒÀÿà€@Ép¿ÿî“”pŒÀÿà€@Ép¿ÿŒÀÿà€@Ép¿ÿ÷Ï”¿ŒÀÿà€@Ép¿—ÿŒÀÿà€@Ébp¨—àŒÀÿà€@É/—?ŒÀÿà€@çŒ;Çÿà€@ÁŸŒpÜÿà€@Á18TŸpŒßÿà€@Á8?_ŸŒ¿Çïÿà€@ÁT_Ÿ¿ÿà€@Áp¿ŸÿŒàãøÿà€@Áp¿ÿüçœàŒ?WÏÿà€@Áp¿ÿçoœ?ŒÀÿà€@Áp¿ÿà?«Àÿà€@™¡;Çÿà?‹ŒŒÀÿà€@™18T¡p¯·Ûÿà?‹TŒpŒÀÿà€@™8?_¡·¿ßÿà?‹`ŒŒÀÿà€@™T_¡¿ÇÛßïÿà?‹Œ¿ŒÀÿà€@™p¿¦ÿà?‹ÀŒÿŒÀÿà€@™p¿ÿüçžàãîï÷ÿãW‹;Çÿüñðè‡àŒÀÿà€@™p¿ÿçož?W“ŸÏÿøÏ‹ÀÇðÿ竟o‡?ŒÀÿà€@™p¿ÿà?žp¿‘ÿà€@–Àÿà€@™p¿ÿà?žbp¨ŽàãøÿãW‡ŒÀÿà€@™p¿ÿà?ž?GkŽãÿîÀ¸”‡pŒÀÿà€@™p¿ÿà?ž8@`Ž€àÿïÇ¿Ÿ‡ŒÀÿà€@™p¿ÿà?ž 0Ž@WÐÿ÷ãßχ¿ŒÀÿà€@™p¿ÿà?³ÀŒÿŒÀÿà€@ކ;Çÿà?³¨ŒàŒÀÿà€@ކÀÇÜßïÿà?³0Œ?ŒÀÿà€@ŽÀ‹ÿà?ÓÀÿà€@ŽÀÿüñðèàãîï÷ÿà?¶‡ŒÀÿà€@ŽÀÿñÎÇ«ÀÇãÿà?¶18T‡pŒÀÿà€@ŽÀÿðÇÀ €¸¿ßÿà?¶8?_‡ŒÀÿà€@ŽÀÿè« p@W”ŸÏÿà?¶T_‡¿ŒÀÿà€@ŽÀÿà€@p¿ÿà?¶p¿‡ÿŒÀÿà€@ŽÀÿà€@p¿ÿãW¶;Çÿüç„àŒÀÿà€@ŽÀÿà€@p¿ÿøÏ¶ÀÇÜßïÿço„?ŒÀÿà€@ŽÀÿà€@p¿¾ÿà?“Àÿà€@ŽÀÿà€@bp¨¹àãîï÷ÿãW„ŒÀÿà€@ŽÀÿà€@?Gk¹ÀÇãÿî“„pŒÀÿà€@ŽÀÿà€@8@`¹€¸¿ßÿŒÀÿà€@ŽÀÿà€@ 0¹@W”ŸÏÿ÷Ï„¿ŒÀÿà€@ŽÀÿà€@Áp¿‡ÿŒÀÿãWŽ;Çÿà€@Ábp¨‡àŒÀÿøãàÐŽÀÇðÿà€@Á/‡?ŒÀ–ÿà€@Þ¨“àãøÿà€@Æ„Œl“ãÿà€@ÆT„pŒ`“€àÿà€@Æ`„Œ0“@WÐÿà€@Æ„¿¤Àÿà€@ÆÀ„ÿ¤Àÿà€@¶‹;Çÿüñðèàà¤Àÿà€@¶‹ÀÇðÿ竟o??¤Àÿà€@¶ÀŽÿà€@¦Àÿà€@¶Àÿüñðè†àãøÿãW¤Àÿà€@¶ÀÿñÎÇ«†ãÿîÀ¸”pp¤Àÿà€@¶ÀÿðÇÀ †€àÿïÇ¿Ÿ¤Àÿà€@¶Àÿè« p†@WÐÿ÷ãßÏ¿¿¤Àÿà€@¶Àÿà€@†À„ÿ¤ÀÿãW¶;Çÿà€@†¨„à¤ÀÿøãàжÀÇðÿà€@†0„?¤À¾ÿà€@¶¨»àãøÿà€@‡¤l»ãÿà€@18T‡p¤`»€àÿà€@8?_‡¤0»@WÐÿà€@T_‡¿äÀÿà€@p¿‡ÿäÀÿãW;Çÿüç„àäÀÿøãàÐÀÇÜßïÿço„?äÀ‹ÿà?먆àãîï÷ÿãW„äl†ÀÇãÿî“„pä`†€¸¿ßÿä0†@W”ŸÏÿ÷Ï„¿ïp¿‡ÿïp¿‡ÿçÿà€@çÿà€@Ïÿüñðè‘àÄ~p8ŒÏÿñÎÇ«‘~PH$TŒpÏÿðÇÀ ‘€pH@ `ŒÏÿè« p‘@8$ Œ¿Ïÿà€@–ÀÞÿà€@ލŒàÏÿà€@ŽÀ¨l`00Œ?Ïÿà€@ÀŽÿà€@¼ÿüçŽàÄ~p8ÀŽÿãW¼ÿñ«Ž~PH$ÀŽÿîÀ¸”p¼ÿ🎀pH@ ÀŽÿïÇ¿Ÿ¼ÿèoŽ@8$ ÀŽÿ÷ãßÏ¿¼ÿà?“Àãÿà?‰À–ÿüñðè‡à¼ÿà?T`‰À¨l`0À–ÿ竟o‡?¼ÿà?p¿‰ÿà€@À–ÿà€@‡¼ÿà?p¿‰ÿà€@¨–àÄ~p8„¼ÿà?p¿‰ÿà€@l–~PH$T„p¼ÿà?p¿‰ÿà€@`–€pH@ `„¼ÿà?p¿‰ÿà€@0–@8$ „¿¼ÿà?p¿‰ÿà€@žÀÃÿà?p¿‰ÿãW™¨„à¼ÿà?p¿‰ÿøãàЙÀ¨l`00„?¼ÿà?p¿©ÿà€@‡Œÿüç«àÄ8p¿©ÿãW‡Œÿñ««~#p¿©ÿîÀ¸”‡pŒÿ🫀p p¿©ÿïÇ¿Ÿ‡Œÿèo«@8p¿©ÿ÷ãßχ¿Œÿà?®p¿Æÿà?¦p¿Æÿà?T`¦À¨0p¿Æÿà?p¿¦ÿà?p¿Æÿà?p¿¦ÿà?p¿®ÿüç„àŒÿà?p¿¦ÿà?p¿®ÿñ«„Œÿà?p¿¦ÿà?p¿®ÿ🄀Œÿà?p¿¦ÿà?p¿®ÿèo„@Œÿà?p¿¦ÿà?p¿®ÿà?„Œÿà?p¿¦ÿà?p¿™ÿüñðèŽàÄ8Œÿà?p¿¦ÿà?p¿™ÿ竟oŽ?8T`ÀÀŒÿà?p¿¦ÿà?p¿™ÿà€@‘p¿Žÿà?p¿¦ÿà?bp¨™àÄ~p8‹bp¨ààŒÿà?p¿¦ÿà??Gk™~PH$T‹pb?GkŒÿà?p¿¦ÿà?8@`™€pH@ `‹p8@`€€Œÿà?p¿¦ÿà? 0™@8$ ‹¿¨/ 0@@Œÿà?p¿¦ÿà?£À‹ÿà?„Œÿà?p¿¦ÿãWžÀ‹ÿãW„Œÿà?p¿¦ÿøÏžÀ¨l`0À‹ÿøÏ„ÀŒÿà?p¿Éÿà€@À£ÿà?p¿Éÿà€@¨”àŒÿà?p¿Éÿà€@l”Œÿà?p¿Éÿà€@`”€Œÿà?p¿Éÿà€@0”@Œÿà?p¿Éÿà€@—Œÿà?p¿ÉÿãW—Œÿà?p¿ÉÿøãàЗÀŒÿà?p¿çÿŒàÄ8p¿ÁÿüñðèŸàŒ~#p¿ÁÿñÎÇ«ŸŒ€p p¿ÁÿðÇÀ Ÿ€Œ@8p¿Áÿè« pŸ@p¿Áÿà€@ŸŒp¿Áÿà€@œŒÀ¨0p¿Áÿà€@œÀŒÿà?p¿Áÿà€@À«ÿà?p¿™ÿüñðè¡àÄ~p8À‹ÿüçŒàŒÿà?p¿™ÿñÎÇ«¡~PH$À‹ÿñ«ŒŒÿà?p¿™ÿðÇÀ ¡€pH@ À‹ÿ🌀Œÿà?p¿™ÿè« p¡@8$ À‹ÿèoŒ@Œÿà?p¿™ÿà€@¦À‹ÿà?ŒŒÿà?p¿™ÿà€@ž¨‹àÄ8‡Œÿà?p¿™ÿà€@žÀ¨l`00‹?8T`‡ÀŒÿà?p¿™ÿà€@Àžÿà€@‘p¿–ÿà?p¿™ÿà€@ÀžÿãWŽbp¨‡àŒÿà?p¿™ÿà€@ÀžÿîÀ¸”Žpb?Gk‡Œÿà?p¿™ÿà€@ÀžÿïÇ¿ŸŽp8@`‡€Œÿà?p¿™ÿà€@Àžÿ÷ãßÏŽ¿¨/ 0‡@Œÿà?p¿™ÿà€@À³ÿà?ŒŒÿà?p¿Žÿüç†àÄ~p8À³ÿãWŒŒÿà?p¿Žÿço†?8# À³ÿøÏŒÀŒÿà?p¿Žÿà?‹ÀÓÿà?p¿Žÿà?À¶ÿüñðè‡àŒÿà?p¿Žÿà?18Tpb?8À¶ÿñÎÇ«‡Œÿà?p¿Žÿà?8?_pG@ À¶ÿðÇÀ ‡€Œÿà?p¿Žÿà?T_¿¨k`0À¶ÿè« p‡@Œÿà?p¿Žÿà?p¿ÿà€@À¶ÿà€@‡Œÿà?p¿Žÿà?p¿ÿà€@¨¶àÄ~p8„Œÿà?p¿Žÿà?p¿ÿà€@0¶?8# „ÀŒÿà?p¿Žÿà?p¿ÿà€@¾À“ÿà?p¿Žÿà?p¿ÿãW¹¨„àŒÿà?p¿Žÿà?p¿ÿîÀ¸”¹pb?8l„Œÿà?p¿Žÿà?p¿ÿïÇ¿Ÿ¹pG@ `„€Œÿà?p¿Žÿà?p¿ÿ÷ãßϹ¿¨k`00„@Œÿà?p¿Žÿà?p¿Áÿà€@‡Œÿà?bp¨ŽàÄ8p¿ÁÿãW‡Œÿà?/Ž?8p¿ÁÿøãàЇÀŒÿà?–p¿ÞÿãW“p¿Æÿüç„àŒÿî““pbp¿Æÿñ«„Œÿpp¿Æÿ🄀Œÿ÷Ï“¿¨/p¿Æÿèo„@¤ÿà?p¿Æÿà?„¤ÿà?p¿¶ÿüç‹àÄ8¤ÿà?p¿¶ÿço‹?8T`ÀÀ¤ÿà?p¿¶ÿà?Žp¿¦ÿà?p¿¶ÿà?†bp¨àà¤ÿà?p¿¶ÿà?18T†pb?Gk¤ÿà?p¿¶ÿà?8?_†p8@`€€¤ÿà?p¿¶ÿà?T_†¿¨/ 0@@¤ÿà?p¿¶ÿà?p¿†ÿà?„¤ÿà?bp¨¶àÄ8p¿†ÿãW„¤ÿà?/¶?8p¿†ÿøÏ„À¤ÿà?¾p¿¶ÿãW»p¿ÿüñðè‡à¤ÿî“»pbp¿ÿñÎÇ«‡¤ÿpp¿ÿðÇÀ ‡€¤ÿ÷Ï»¿¨/p¿ÿè« p‡@äÿà?p¿ÿà€@‡äÿà?bp¨àÄ~p8„äÿà?/?8# „Àäÿà?‹ÀëÿãW†¨„àäÿpb?8l„äÿpG@ `„€äÿ÷φ¿¨k`00„@ïÿà€@‡ïÿà€@‡t8mk@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿcluster-1.52a/mac/Cluster.xcodeproj/0000755000100500010050000000000012177164023017271 5ustar mdehoonmdehooncluster-1.52a/mac/Cluster.xcodeproj/project.pbxproj0000644000100500010050000004143511352151107022345 0ustar mdehoonmdehoon// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 42; objects = { /* Begin PBXBuildFile section */ 40BF80970D78432B002D71C0 /* command.c in Sources */ = {isa = PBXBuildFile; fileRef = 40BF80960D78432B002D71C0 /* command.c */; settings = {COMPILER_FLAGS = "-DHAVE_GUI"; }; }; 40BF809D0D784354002D71C0 /* command.h in Headers */ = {isa = PBXBuildFile; fileRef = 40BF809C0D784354002D71C0 /* command.h */; }; 40CDB5410A2ABD9100E334F0 /* Controller.h in Headers */ = {isa = PBXBuildFile; fileRef = F5E3644B035912F601000082 /* Controller.h */; }; 40CDB5420A2ABD9100E334F0 /* data.h in Headers */ = {isa = PBXBuildFile; fileRef = F54D6BC40359C83001000082 /* data.h */; }; 40CDB5430A2ABD9100E334F0 /* cluster.h in Headers */ = {isa = PBXBuildFile; fileRef = F54D6BC60359C85801000082 /* cluster.h */; }; 40CDB5460A2ABD9100E334F0 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; }; 40CDB5470A2ABD9100E334F0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 40CDB5480A2ABD9100E334F0 /* cluster.icns in Resources */ = {isa = PBXBuildFile; fileRef = F5E3644903589B6901000082 /* cluster.icns */; }; 40CDB5490A2ABD9100E334F0 /* cluster3.pdf in Resources */ = {isa = PBXBuildFile; fileRef = F54CD24A035FAD1001000082 /* cluster3.pdf */; }; 40CDB54A0A2ABD9100E334F0 /* FileFormatPanel.nib in Resources */ = {isa = PBXBuildFile; fileRef = F594A11F035FB72001000082 /* FileFormatPanel.nib */; }; 40CDB54B0A2ABD9100E334F0 /* format.bmp in Resources */ = {isa = PBXBuildFile; fileRef = F594A122035FBA6801000082 /* format.bmp */; }; 40CDB54C0A2ABD9100E334F0 /* AboutPanel.nib in Resources */ = {isa = PBXBuildFile; fileRef = F594A126035FE6D101000082 /* AboutPanel.nib */; }; 40CDB54D0A2ABD9100E334F0 /* html in Resources */ = {isa = PBXBuildFile; fileRef = F564D3E2035EF29C01000082 /* html */; }; 40CDB54F0A2ABD9100E334F0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 40CDB5500A2ABD9100E334F0 /* Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = F5E3644C035912F601000082 /* Controller.m */; }; 40CDB5510A2ABD9100E334F0 /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = F54D6BC20359C81501000082 /* data.c */; }; 40CDB5520A2ABD9100E334F0 /* cluster.c in Sources */ = {isa = PBXBuildFile; fileRef = F54D6BC80359C86A01000082 /* cluster.c */; }; 40CDB5570A2ABD9100E334F0 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = ""; }; 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 40BF80960D78432B002D71C0 /* command.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = command.c; path = ../src/command.c; sourceTree = SOURCE_ROOT; }; 40BF809C0D784354002D71C0 /* command.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = command.h; path = ../src/command.h; sourceTree = SOURCE_ROOT; }; 40CDB55C0A2ABD9100E334F0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; 40CDB55D0A2ABD9100E334F0 /* Cluster.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Cluster.app; sourceTree = BUILT_PRODUCTS_DIR; }; F54CD24A035FAD1001000082 /* cluster3.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = cluster3.pdf; path = ../doc/cluster3.pdf; sourceTree = ""; }; F54D6BC20359C81501000082 /* data.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = data.c; path = ../src/data.c; sourceTree = ""; }; F54D6BC40359C83001000082 /* data.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = data.h; path = ../src/data.h; sourceTree = ""; }; F54D6BC60359C85801000082 /* cluster.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cluster.h; path = ../src/cluster.h; sourceTree = ""; }; F54D6BC80359C86A01000082 /* cluster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cluster.c; path = ../src/cluster.c; sourceTree = ""; }; F564D3E2035EF29C01000082 /* html */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = html; path = ../html; sourceTree = ""; }; F594A120035FB72001000082 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/FileFormatPanel.nib; sourceTree = ""; }; F594A122035FBA6801000082 /* format.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; name = format.bmp; path = ../windows/format.bmp; sourceTree = ""; }; F594A127035FE6D101000082 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/AboutPanel.nib; sourceTree = ""; }; F5E3644903589B6901000082 /* cluster.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = cluster.icns; sourceTree = ""; }; F5E3644B035912F601000082 /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = ""; }; F5E3644C035912F601000082 /* Controller.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = Controller.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 40CDB5560A2ABD9100E334F0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 40CDB5570A2ABD9100E334F0 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( ); name = Classes; sourceTree = ""; }; 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { isa = PBXGroup; children = ( 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, ); name = "Linked Frameworks"; sourceTree = ""; }; 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { isa = PBXGroup; children = ( 29B97325FDCFA39411CA2CEA /* Foundation.framework */, 29B97324FDCFA39411CA2CEA /* AppKit.framework */, ); name = "Other Frameworks"; sourceTree = ""; }; 19C28FACFE9D520D11CA2CBB /* Products */ = { isa = PBXGroup; children = ( 40CDB55D0A2ABD9100E334F0 /* Cluster.app */, ); name = Products; sourceTree = ""; }; 29B97314FDCFA39411CA2CEA /* Cluster */ = { isa = PBXGroup; children = ( 40BF809C0D784354002D71C0 /* command.h */, 40BF80960D78432B002D71C0 /* command.c */, 080E96DDFE201D6D7F000001 /* Classes */, 29B97315FDCFA39411CA2CEA /* Other Sources */, 29B97317FDCFA39411CA2CEA /* Resources */, 29B97323FDCFA39411CA2CEA /* Frameworks */, 19C28FACFE9D520D11CA2CBB /* Products */, 40CDB55C0A2ABD9100E334F0 /* Info.plist */, ); name = Cluster; sourceTree = ""; }; 29B97315FDCFA39411CA2CEA /* Other Sources */ = { isa = PBXGroup; children = ( 29B97316FDCFA39411CA2CEA /* main.m */, F5E3644903589B6901000082 /* cluster.icns */, F5E3644B035912F601000082 /* Controller.h */, F5E3644C035912F601000082 /* Controller.m */, F54D6BC20359C81501000082 /* data.c */, F54D6BC40359C83001000082 /* data.h */, F54D6BC60359C85801000082 /* cluster.h */, F54D6BC80359C86A01000082 /* cluster.c */, ); name = "Other Sources"; sourceTree = ""; }; 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, F564D3E2035EF29C01000082 /* html */, F54CD24A035FAD1001000082 /* cluster3.pdf */, F594A11F035FB72001000082 /* FileFormatPanel.nib */, F594A122035FBA6801000082 /* format.bmp */, F594A126035FE6D101000082 /* AboutPanel.nib */, ); name = Resources; sourceTree = ""; }; 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, ); name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 40CDB5400A2ABD9100E334F0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 40CDB5410A2ABD9100E334F0 /* Controller.h in Headers */, 40CDB5420A2ABD9100E334F0 /* data.h in Headers */, 40CDB5430A2ABD9100E334F0 /* cluster.h in Headers */, 40BF809D0D784354002D71C0 /* command.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 40CDB53F0A2ABD9100E334F0 /* Cluster */ = { isa = PBXNativeTarget; buildConfigurationList = 40CDB5580A2ABD9100E334F0 /* Build configuration list for PBXNativeTarget "Cluster" */; buildPhases = ( 40CDB5400A2ABD9100E334F0 /* Headers */, 40CDB5450A2ABD9100E334F0 /* Resources */, 40CDB54E0A2ABD9100E334F0 /* Sources */, 40CDB5560A2ABD9100E334F0 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = Cluster; productInstallPath = "$(HOME)/Applications"; productName = Cluster; productReference = 40CDB55D0A2ABD9100E334F0 /* Cluster.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; buildConfigurationList = 40CDB5390A2ABD8800E334F0 /* Build configuration list for PBXProject "Cluster" */; hasScannedForEncodings = 1; mainGroup = 29B97314FDCFA39411CA2CEA /* Cluster */; projectDirPath = ""; targets = ( 40CDB53F0A2ABD9100E334F0 /* Cluster */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 40CDB5450A2ABD9100E334F0 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 40CDB5460A2ABD9100E334F0 /* MainMenu.nib in Resources */, 40CDB5470A2ABD9100E334F0 /* InfoPlist.strings in Resources */, 40CDB5480A2ABD9100E334F0 /* cluster.icns in Resources */, 40CDB5490A2ABD9100E334F0 /* cluster3.pdf in Resources */, 40CDB54A0A2ABD9100E334F0 /* FileFormatPanel.nib in Resources */, 40CDB54B0A2ABD9100E334F0 /* format.bmp in Resources */, 40CDB54C0A2ABD9100E334F0 /* AboutPanel.nib in Resources */, 40CDB54D0A2ABD9100E334F0 /* html in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 40CDB54E0A2ABD9100E334F0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 40CDB54F0A2ABD9100E334F0 /* main.m in Sources */, 40CDB5500A2ABD9100E334F0 /* Controller.m in Sources */, 40CDB5510A2ABD9100E334F0 /* data.c in Sources */, 40CDB5520A2ABD9100E334F0 /* cluster.c in Sources */, 40BF80970D78432B002D71C0 /* command.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( 089C165DFE840E0CC02AAC07 /* English */, ); name = InfoPlist.strings; sourceTree = ""; }; 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = { isa = PBXVariantGroup; children = ( 29B97319FDCFA39411CA2CEA /* English */, ); name = MainMenu.nib; sourceTree = ""; }; F594A11F035FB72001000082 /* FileFormatPanel.nib */ = { isa = PBXVariantGroup; children = ( F594A120035FB72001000082 /* English */, ); name = FileFormatPanel.nib; sourceTree = ""; }; F594A126035FE6D101000082 /* AboutPanel.nib */ = { isa = PBXVariantGroup; children = ( F594A127035FE6D101000082 /* English */, ); name = AboutPanel.nib; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 40CDB53A0A2ABD8800E334F0 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; }; name = Development; }; 40CDB53B0A2ABD8800E334F0 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; }; name = Deployment; }; 40CDB53C0A2ABD8800E334F0 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; }; name = Default; }; 40CDB5590A2ABD9100E334F0 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../src; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; PRODUCT_NAME = Cluster; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); WRAPPER_EXTENSION = app; ZERO_LINK = YES; }; name = Development; }; 40CDB55A0A2ABD9100E334F0 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../src; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; PRODUCT_NAME = Cluster; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); WRAPPER_EXTENSION = app; ZERO_LINK = NO; }; name = Deployment; }; 40CDB55B0A2ABD9100E334F0 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../src; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; PRODUCT_NAME = Cluster; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); WRAPPER_EXTENSION = app; }; name = Default; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 40CDB5390A2ABD8800E334F0 /* Build configuration list for PBXProject "Cluster" */ = { isa = XCConfigurationList; buildConfigurations = ( 40CDB53A0A2ABD8800E334F0 /* Development */, 40CDB53B0A2ABD8800E334F0 /* Deployment */, 40CDB53C0A2ABD8800E334F0 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 40CDB5580A2ABD9100E334F0 /* Build configuration list for PBXNativeTarget "Cluster" */ = { isa = XCConfigurationList; buildConfigurations = ( 40CDB5590A2ABD9100E334F0 /* Development */, 40CDB55A0A2ABD9100E334F0 /* Deployment */, 40CDB55B0A2ABD9100E334F0 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; /* End XCConfigurationList section */ }; rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; } cluster-1.52a/mac/Info.plist0000644000100500010050000000164312174112032015616 0ustar mdehoonmdehoon CFBundleDevelopmentRegion English CFBundleExecutable Cluster CFBundleHelpBookFolder html CFBundleHelpBookName Cluster 3.0 Help CFBundleIconFile cluster.icns CFBundleIdentifier com.u-tokyo.Cluster CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType APPL CFBundleSignature ???? CFBundleVersion C Clustering Library 1.52 NSMainNibFile MainMenu NSPrincipalClass NSApplication cluster-1.52a/mac/Makefile0000644000100500010050000000136212177152014015313 0ustar mdehoonmdehoonDOCDIR = ../doc HTMLDIR = ../html build/Default/Cluster.app: $(HTMLDIR)/html.helpindex $(HTMLDIR)/html\ idx $(DOCDIR)/cluster3.pdf xcodebuild rm -r build/Cluster.build Cluster.pkg: build/Default/Cluster.app productbuild --component build/Default/Cluster.app /Applications Cluster.pkg Cluster.tar: Cluster.pkg tar cvf Cluster.tar Cluster.pkg $(HTMLDIR)/index.html: $(DOCDIR)/cluster3.texinfo $(MAKE) -C $(HTMLDIR) $(HTMLDIR)/html.helpindex $(HTMLDIR)/html\ idx: $(HTMLDIR)/index.html /Developer/Applications/Utilities/Help\ Indexer.app/Contents/MacOS/Help\ Indexer ../html -ShowProgress YES -LogStyle 2 -PantherIndexing YES $(DOCDIR)/cluster3.pdf: $(DOCDIR)/cluster3.texinfo $(MAKE) -C $(DOCDIR) clean: rm -rf build Cluster.pkg Cluster.tar cluster-1.52a/mac/English.lproj/0000755000100500010050000000000012177164022016371 5ustar mdehoonmdehooncluster-1.52a/mac/English.lproj/InfoPlist.strings0000644000100500010050000000115010443424661021712 0ustar mdehoonmdehoonÿþ/* Localized versions of Info.plist keys */ CFBundleName = "Cluster"; CFBundleShortVersionString = "Cluster 3.0 for Mac OS X"; CFBundleGetInfoString = "Cluster 3.0 for Mac OS X, created by Michiel de Hoon, University of Tokyo."; NSHumanReadableCopyright = "See Help > About... for copyright information."; cluster-1.52a/mac/English.lproj/FileFormatPanel.nib/0000755000100500010050000000000012177164022022150 5ustar mdehoonmdehooncluster-1.52a/mac/English.lproj/FileFormatPanel.nib/keyedobjects.nib0000644000100500010050000004362510003621724025320 0ustar mdehoonmdehoon $archiver NSKeyedArchiver $objects $null $class CF$UID 77 NSClassesKeys CF$UID 67 NSClassesValues CF$UID 68 NSConnections CF$UID 8 NSFontManager CF$UID 0 NSFramework CF$UID 5 NSNamesKeys CF$UID 62 NSNamesValues CF$UID 63 NSNextOid 20 NSObjectsKeys CF$UID 59 NSObjectsValues CF$UID 61 NSOidsKeys CF$UID 69 NSOidsValues CF$UID 70 NSRoot CF$UID 2 NSVisibleWindows CF$UID 6 $class CF$UID 4 NSClassName CF$UID 3 Controller $classes NSCustomObject NSObject $classname NSCustomObject IBCocoaFramework $class CF$UID 7 NS.objects $classes NSMutableSet NSSet NSObject $classname NSMutableSet $class CF$UID 50 NS.objects CF$UID 9 $class CF$UID 58 NSDestination CF$UID 10 NSLabel CF$UID 57 NSSource CF$UID 2 $class CF$UID 56 NSMaxSize CF$UID 55 NSMinSize CF$UID 54 NSScreenRect CF$UID 53 NSViewClass CF$UID 14 NSWTFlags 1886912512 NSWindowBacking 2 NSWindowClass CF$UID 13 NSWindowRect CF$UID 11 NSWindowStyleMask 3 NSWindowTitle CF$UID 12 NSWindowView CF$UID 16 {{109, 95}, {654, 708}} File Format NSPanel $class CF$UID 15 NS.string View $classes NSMutableString NSString NSObject $classname NSMutableString $class CF$UID 52 NSFrame CF$UID 51 NSNextResponder CF$UID 0 NSSubviews CF$UID 17 $class CF$UID 50 NS.objects CF$UID 18 CF$UID 35 $class CF$UID 34 NSCell CF$UID 20 NSEnabled NSFrame CF$UID 19 NSNextResponder CF$UID 16 NSSuperview CF$UID 16 {{63, 190}, {528, 498}} $class CF$UID 33 NSBackgroundColor CF$UID 25 NSCellFlags -2072904127 NSCellFlags2 4194304 NSContents CF$UID 21 NSControlView CF$UID 18 NSDrawsBackground NSSupport CF$UID 22 NSTextColor CF$UID 30 The input for the clustering program is a tab-delimited text file. An example is shown below. The cells in red must appear in the file, although they can be any string. The cells in bold are headers for optional columns/rows. UNIQID: (string/number) This column should contain unique identifiers for each gene. NAME: (string) A text description of each gene which will be used in display. EWEIGHT: (real number) A weight for each experiment that can be used to count certain experiments more than others. GWEIGHT: (real number) A similar weight for each gene can be used when clustering arrays. GORDER: (real number) A value to be used for ordering nodes in display program EXPID: (string, e.g. EXP1, EXP2,...) A text description of each experiment that will be used in the display. DATA:(real number) Data for a single gene in a single experiment. Any desired numerical transform (e.g. log) should be applied before clustering. Missing values are acceptable. $class CF$UID 24 NSName CF$UID 23 NSSize 13 NSfFlags 20 LucidaGrande $classes NSFont NSObject $classname NSFont $class CF$UID 29 NSCatalogName CF$UID 26 NSColor CF$UID 28 NSColorName CF$UID 27 NSColorSpace 6 System textBackgroundColor $class CF$UID 29 NSColorSpace 3 NSWhite MQA= $classes NSColor NSObject $classname NSColor $class CF$UID 29 NSCatalogName CF$UID 26 NSColor CF$UID 32 NSColorName CF$UID 31 NSColorSpace 6 textColor $class CF$UID 29 NSColorSpace 3 NSWhite MAA= $classes NSTextFieldCell NSActionCell NSCell NSObject $classname NSTextFieldCell $classes NSTextField %NSTextField NSControl NSView NSResponder NSObject $classname NSTextField $class CF$UID 49 NSCell CF$UID 43 NSDragTypes CF$UID 36 NSEditable NSEnabled NSFrame CF$UID 42 NSNextResponder CF$UID 16 NSSuperview CF$UID 16 $class CF$UID 7 NS.objects CF$UID 37 CF$UID 38 CF$UID 39 CF$UID 40 CF$UID 41 Apple PDF pasteboard type NeXT TIFF v4.0 pasteboard type NeXT Encapsulated PostScript v1.2 pasteboard type NSFilenamesPboardType Apple PICT pasteboard type {{19, 14}, {615, 163}} $class CF$UID 48 NSAlign 0 NSAnimates NSCellFlags 130560 NSCellFlags2 0 NSContents CF$UID 44 NSScale 2 NSStyle 0 $class CF$UID 47 NSClassName CF$UID 45 NSResourceName CF$UID 46 NSImage format $classes NSCustomResource %NSCustomResource NSObject $classname NSCustomResource $classes NSImageCell %NSImageCell NSCell NSObject $classname NSImageCell $classes NSImageView NSControl NSView NSResponder NSObject $classname NSImageView $classes NSMutableArray NSArray NSObject $classname NSMutableArray {{1, 1}, {654, 708}} $classes NSView NSResponder NSObject $classname NSView {{0, 0}, {1280, 832}} {213, 129} {3.40282e+38, 3.40282e+38} $classes NSWindowTemplate NSObject $classname NSWindowTemplate FileFormatPanel $classes NSNibOutletConnector NSNibConnector NSObject $classname NSNibOutletConnector $class CF$UID 60 NS.objects CF$UID 10 CF$UID 18 CF$UID 35 CF$UID 16 $classes NSArray NSObject $classname NSArray $class CF$UID 60 NS.objects CF$UID 2 CF$UID 16 CF$UID 16 CF$UID 10 $class CF$UID 60 NS.objects CF$UID 2 CF$UID 18 CF$UID 10 $class CF$UID 60 NS.objects CF$UID 64 CF$UID 65 CF$UID 66 File's Owner NSTextField Panel $class CF$UID 60 NS.objects $class CF$UID 60 NS.objects $class CF$UID 60 NS.objects CF$UID 35 CF$UID 2 CF$UID 16 CF$UID 10 CF$UID 9 CF$UID 18 $class CF$UID 60 NS.objects CF$UID 71 CF$UID 72 CF$UID 73 CF$UID 74 CF$UID 75 CF$UID 76 18 1 6 5 19 8 $classes NSIBObjectData NSObject $classname NSIBObjectData $top IB.objectdata CF$UID 1 $version 100000 cluster-1.52a/mac/English.lproj/FileFormatPanel.nib/classes.nib0000644000100500010050000000044610003621724024274 0ustar mdehoonmdehoon{ IBClasses = ( { CLASS = Controller; LANGUAGE = ObjC; OUTLETS = {FileFormatPanel = id; }; SUPERCLASS = NSObject; }, {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; } ); IBVersion = 1; }cluster-1.52a/mac/English.lproj/FileFormatPanel.nib/info.nib0000644000100500010050000000103110003621724023561 0ustar mdehoonmdehoon IBDocumentLocation 63 197 356 240 0 0 1280 832 IBFramework Version 349.0 IBOldestOS 3 IBOpenObjects 5 IBSystem Version 7D24 IBUsesTextArchiving cluster-1.52a/mac/English.lproj/MainMenu.nib/0000755000100500010050000000000012177164023020652 5ustar mdehoonmdehooncluster-1.52a/mac/English.lproj/MainMenu.nib/keyedobjects.nib0000644000100500010050000201770711356353440024036 0ustar mdehoonmdehoon $archiver NSKeyedArchiver $objects $null $class CF$UID 1546 NSAccessibilityConnectors CF$UID 1543 NSAccessibilityOidsKeys CF$UID 1544 NSAccessibilityOidsValues CF$UID 1545 NSClassesKeys CF$UID 1200 NSClassesValues CF$UID 1201 NSConnections CF$UID 873 NSFontManager CF$UID 0 NSFramework CF$UID 6 NSNamesKeys CF$UID 1139 NSNamesValues CF$UID 1140 NSNextOid 990 NSObjectsKeys CF$UID 1101 NSObjectsValues CF$UID 1138 NSOidsKeys CF$UID 1202 NSOidsValues CF$UID 1203 NSRoot CF$UID 2 NSVisibleWindows CF$UID 7 $class CF$UID 5 NSClassName CF$UID 3 $class CF$UID 4 NS.string NSApplication $classes NSMutableString NSString NSObject $classname NSMutableString $classes NSCustomObject NSObject $classname NSCustomObject $class CF$UID 4 NS.string IBCocoaFramework $class CF$UID 872 NS.objects CF$UID 8 $class CF$UID 871 NSMaxSize CF$UID 870 NSMinSize CF$UID 869 NSScreenRect CF$UID 868 NSViewClass CF$UID 12 NSWTFlags 1886912512 NSWindowBacking 2 NSWindowClass CF$UID 11 NSWindowRect CF$UID 9 NSWindowStyleMask 5 NSWindowTitle CF$UID 10 NSWindowView CF$UID 13 {{178, 87}, {596, 637}} Gene Cluster 3.0 NSWindow $class CF$UID 4 NS.string View $class CF$UID 214 NSFrame CF$UID 867 NSNextResponder CF$UID 0 NSSubviews CF$UID 14 $class CF$UID 212 NS.objects CF$UID 15 CF$UID 32 CF$UID 36 CF$UID 40 CF$UID 49 CF$UID 52 CF$UID 56 CF$UID 60 CF$UID 63 CF$UID 66 CF$UID 864 $class CF$UID 31 NSCell CF$UID 17 NSEnabled NSFrame CF$UID 16 NSNextResponder CF$UID 13 NSSuperview CF$UID 13 NSvFlags 256 {{17, 598}, {73, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 18 NSControlView CF$UID 15 NSSupport CF$UID 19 NSTextColor CF$UID 27 File loaded $class CF$UID 21 NSName CF$UID 20 NSSize 13 NSfFlags 1044 LucidaGrande $classes NSFont NSObject $classname NSFont $class CF$UID 26 NSCatalogName CF$UID 23 NSColor CF$UID 25 NSColorName CF$UID 24 NSColorSpace 6 System controlColor $class CF$UID 26 NSColorSpace 3 NSWhite MC42NjY2NjY2OQA= $classes NSColor NSObject $classname NSColor $class CF$UID 26 NSCatalogName CF$UID 23 NSColor CF$UID 29 NSColorName CF$UID 28 NSColorSpace 6 controlTextColor $class CF$UID 26 NSColorSpace 3 NSWhite MAA= $classes NSTextFieldCell NSActionCell NSCell NSObject $classname NSTextFieldCell $classes NSTextField %NSTextField NSControl NSView NSResponder NSObject $classname NSTextField $class CF$UID 31 NSCell CF$UID 34 NSEnabled NSFrame CF$UID 33 NSNextResponder CF$UID 13 NSSuperview CF$UID 13 NSvFlags 256 {{17, 512}, {63, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 35 NSControlView CF$UID 32 NSSupport CF$UID 19 NSTextColor CF$UID 27 Job name $class CF$UID 31 NSCell CF$UID 38 NSEnabled NSFrame CF$UID 37 NSNextResponder CF$UID 13 NSSuperview CF$UID 13 NSvFlags 256 {{17, 468}, {78, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 39 NSControlView CF$UID 36 NSSupport CF$UID 19 NSTextColor CF$UID 27 Dataset has $class CF$UID 31 NSCell CF$UID 42 NSEnabled NSFrame CF$UID 41 NSNextResponder CF$UID 13 NSSuperview CF$UID 13 NSvFlags 256 {{182, 542}, {397, 76}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -2072904127 NSCellFlags2 4195328 NSContents CF$UID 43 NSControlView CF$UID 40 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 26 NSCatalogName CF$UID 23 NSColor CF$UID 46 NSColorName CF$UID 45 NSColorSpace 6 textBackgroundColor $class CF$UID 26 NSColorSpace 3 NSWhite MQA= $class CF$UID 26 NSCatalogName CF$UID 23 NSColor CF$UID 29 NSColorName CF$UID 48 NSColorSpace 6 textColor $class CF$UID 31 NSCell CF$UID 51 NSEnabled NSFrame CF$UID 50 NSNextResponder CF$UID 13 NSSuperview CF$UID 13 NSvFlags 256 {{185, 506}, {391, 23}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 4195328 NSContents CF$UID 43 NSControlView CF$UID 49 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 31 NSCell CF$UID 54 NSEnabled NSFrame CF$UID 53 NSNextResponder CF$UID 13 NSSuperview CF$UID 13 NSvFlags 256 {{313, 481}, {37, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 55 NSControlView CF$UID 52 NSSupport CF$UID 19 NSTextColor CF$UID 27 Rows $class CF$UID 31 NSCell CF$UID 58 NSEnabled NSFrame CF$UID 57 NSNextResponder CF$UID 13 NSSuperview CF$UID 13 NSvFlags 256 {{313, 460}, {60, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 59 NSControlView CF$UID 56 NSSupport CF$UID 19 NSTextColor CF$UID 27 Columns $class CF$UID 31 NSCell CF$UID 62 NSEnabled NSFrame CF$UID 61 NSNextResponder CF$UID 13 NSSuperview CF$UID 13 NSvFlags 256 {{182, 481}, {129, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 71303168 NSContents CF$UID 43 NSControlView CF$UID 60 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 31 NSCell CF$UID 65 NSEnabled NSFrame CF$UID 64 NSNextResponder CF$UID 13 NSSuperview CF$UID 13 NSvFlags 256 {{182, 460}, {129, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 71303168 NSContents CF$UID 43 NSControlView CF$UID 63 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 863 NSAllowTruncatedLabels NSDrawsBackground NSFont CF$UID 19 NSFrame CF$UID 222 NSNextResponder CF$UID 13 NSSelectedTabViewItem CF$UID 224 NSSubviews CF$UID 67 NSSuperview CF$UID 13 NSTabViewItems CF$UID 223 NSTvFlags 0 $class CF$UID 212 NS.objects CF$UID 68 $class CF$UID 214 NSFrame CF$UID 221 NSNextResponder CF$UID 66 NSSubviews CF$UID 69 NSSuperview CF$UID 66 $class CF$UID 212 NS.objects CF$UID 70 $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 72 NSFrame CF$UID 215 NSNextResponder CF$UID 68 NSOffsets CF$UID 216 NSSubviews CF$UID 71 NSSuperview CF$UID 68 NSTitleCell CF$UID 217 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 72 $class CF$UID 214 NSFrame CF$UID 213 NSNextResponder CF$UID 70 NSSubviews CF$UID 73 NSSuperview CF$UID 70 $class CF$UID 212 NS.objects CF$UID 74 CF$UID 83 CF$UID 87 CF$UID 91 CF$UID 95 CF$UID 103 CF$UID 108 CF$UID 111 CF$UID 151 CF$UID 168 CF$UID 172 CF$UID 186 CF$UID 198 $class CF$UID 82 NSCell CF$UID 76 NSEnabled NSFrame CF$UID 75 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{18, 305}, {107, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 77 NSControlView CF$UID 74 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 % Present >= $class CF$UID 80 NSImageName CF$UID 79 NSSwitch $classes NSButtonImageSource NSObject $classname NSButtonImageSource $classes NSButtonCell %NSButtonCell NSActionCell NSCell NSObject $classname NSButtonCell $classes NSButton NSControl NSView NSResponder NSObject $classname NSButton $class CF$UID 82 NSCell CF$UID 85 NSEnabled NSFrame CF$UID 84 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{18, 260}, {128, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 86 NSControlView CF$UID 83 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 SD (Gene Vector) $class CF$UID 82 NSCell CF$UID 89 NSEnabled NSFrame CF$UID 88 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{18, 215}, {70, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 90 NSControlView CF$UID 87 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 At least $class CF$UID 82 NSCell CF$UID 93 NSEnabled NSFrame CF$UID 92 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{18, 170}, {151, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 94 NSControlView CF$UID 91 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 MaxVal - MinVal >= $class CF$UID 82 NSCell CF$UID 97 NSEnabled NSFrame CF$UID 96 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{199, 83}, {112, 32}} $class CF$UID 81 NSAlternateContents CF$UID 101 NSAlternateImage CF$UID 99 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags 67239424 NSCellFlags2 137887744 NSContents CF$UID 98 NSControlView CF$UID 95 NSKeyEquivalent CF$UID 102 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Apply Filter $class CF$UID 21 NSName CF$UID 100 NSSize 13 NSfFlags 16 Helvetica $class CF$UID 4 NS.string $class CF$UID 4 NS.string $class CF$UID 82 NSCell CF$UID 105 NSEnabled NSFrame CF$UID 104 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{214, 6}, {84, 32}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 99 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags 604110336 NSCellFlags2 137887744 NSContents CF$UID 106 NSControlView CF$UID 103 NSKeyEquivalent CF$UID 107 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Accept $class CF$UID 4 NS.string $class CF$UID 31 NSCell CF$UID 110 NSEnabled NSFrame CF$UID 109 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{13, 54}, {485, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 138412032 NSContents CF$UID 43 NSControlView CF$UID 108 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 31 NSCell CF$UID 113 NSEnabled NSFrame CF$UID 112 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{177, 304}, {78, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 114 NSControlView CF$UID 111 NSDrawsBackground NSFormatter CF$UID 116 NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 115 NS.compact NS.exponent 1 NS.length 1 NS.mantissa CAAGDmB2ZA642v+/lrKlkA== NS.mantissa.bo 1 NS.negative $classes NSDecimalNumberPlaceholder NSObject $classname NSDecimalNumberPlaceholder $class CF$UID 150 NS.allowsfloats NS.attributes CF$UID 117 NS.decimal CF$UID 142 NS.hasthousands NS.localized NS.max CF$UID 146 NS.min CF$UID 134 NS.nan CF$UID 147 NS.negativeattrs CF$UID 0 NS.negativeformat CF$UID 144 NS.nil CF$UID 145 NS.positiveattrs CF$UID 0 NS.positiveformat CF$UID 135 NS.rounding CF$UID 0 NS.thousand CF$UID 131 NS.zero CF$UID 137 $class CF$UID 149 NS.keys CF$UID 118 CF$UID 119 CF$UID 120 CF$UID 121 CF$UID 122 CF$UID 123 CF$UID 124 CF$UID 125 CF$UID 126 CF$UID 127 CF$UID 128 CF$UID 129 CF$UID 130 NS.objects CF$UID 131 CF$UID 132 CF$UID 134 CF$UID 135 CF$UID 136 CF$UID 137 CF$UID 142 CF$UID 143 CF$UID 144 CF$UID 145 CF$UID 146 CF$UID 143 CF$UID 147 groupingSeparator locale minimum positiveFormat formatterBehavior attributedStringForZero decimalSeparator allowsFloats negativeFormat attributedStringForNil maximum usesGroupingSeparator attributedStringForNotANumber , $class CF$UID 133 NS.identifier CF$UID 43 $classes NSLocale NSObject $classname NSLocale $class CF$UID 115 NS.compact NS.exponent 0 NS.length 0 NS.mantissa AAAAArgAAACAcaWguJaBkA== NS.mantissa.bo 1 NS.negative #,##0.#### 1000 $class CF$UID 141 NSAttributes CF$UID 139 NSString CF$UID 138 0 $class CF$UID 140 NS.keys NS.objects $classes NSDictionary NSObject $classname NSDictionary $classes NSAttributedString NSObject $classname NSAttributedString . -#,##0.#### $class CF$UID 141 NSString CF$UID 43 $class CF$UID 115 NS.compact NS.exponent 2 NS.length 1 NS.mantissa AQAAArgAAAAAAAACuJaBkA== NS.mantissa.bo 1 NS.negative $class CF$UID 141 NSAttributes CF$UID 139 NSString CF$UID 148 NaN $classes NSMutableDictionary NSDictionary NSObject $classname NSMutableDictionary $classes NSNumberFormatter NSFormatter NSObject $classname NSNumberFormatter $class CF$UID 31 NSCell CF$UID 153 NSEnabled NSFrame CF$UID 152 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{94, 214}, {45, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 154 NSControlView CF$UID 151 NSDrawsBackground NSFormatter CF$UID 155 NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 115 NS.compact NS.exponent 0 NS.length 1 NS.mantissa AQAAArgAAAAAAAACuJaBkA== NS.mantissa.bo 1 NS.negative $class CF$UID 150 NS.allowsfloats NS.attributes CF$UID 156 NS.decimal CF$UID 142 NS.hasthousands NS.localized NS.max CF$UID 167 NS.min CF$UID 157 NS.nan CF$UID 165 NS.negativeattrs CF$UID 0 NS.negativeformat CF$UID 162 NS.nil CF$UID 163 NS.positiveattrs CF$UID 0 NS.positiveformat CF$UID 158 NS.rounding CF$UID 0 NS.thousand CF$UID 131 NS.zero CF$UID 160 $class CF$UID 149 NS.keys CF$UID 118 CF$UID 119 CF$UID 120 CF$UID 121 CF$UID 122 CF$UID 123 CF$UID 124 CF$UID 125 CF$UID 126 CF$UID 127 CF$UID 129 CF$UID 130 NS.objects CF$UID 131 CF$UID 132 CF$UID 157 CF$UID 158 CF$UID 159 CF$UID 160 CF$UID 142 CF$UID 143 CF$UID 162 CF$UID 163 CF$UID 164 CF$UID 165 $class CF$UID 115 NS.compact NS.exponent 0 NS.length 0 NS.mantissa AAAAArgAAAAAAAACuJaBkA== NS.mantissa.bo 1 NS.negative # 1000 $class CF$UID 141 NSAttributes CF$UID 139 NSString CF$UID 161 0 ###0.00 $class CF$UID 141 NSString CF$UID 43 $class CF$UID 141 NSAttributes CF$UID 139 NSString CF$UID 166 NaN $class CF$UID 115 NS.compact NS.exponent 0 NS.length 0 NS.mantissa AAAAArgAAAAAAAACuJaBkA== NS.mantissa.bo 1 NS.negative $class CF$UID 31 NSCell CF$UID 170 NSEnabled NSFrame CF$UID 169 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{155, 216}, {210, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 171 NSControlView CF$UID 168 NSSupport CF$UID 19 NSTextColor CF$UID 27 observations with abs(Val) >= $class CF$UID 31 NSCell CF$UID 174 NSEnabled NSFrame CF$UID 173 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{177, 169}, {78, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 175 NSControlView CF$UID 172 NSDrawsBackground NSFormatter CF$UID 176 NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 115 NS.compact NS.exponent 0 NS.length 1 NS.mantissa AgAAArgAAAAAAAACuJaBkA== NS.mantissa.bo 1 NS.negative $class CF$UID 150 NS.allowsfloats NS.attributes CF$UID 177 NS.decimal CF$UID 142 NS.hasthousands NS.localized NS.max CF$UID 167 NS.min CF$UID 178 NS.nan CF$UID 184 NS.negativeattrs CF$UID 0 NS.negativeformat CF$UID 144 NS.nil CF$UID 183 NS.positiveattrs CF$UID 0 NS.positiveformat CF$UID 179 NS.rounding CF$UID 0 NS.thousand CF$UID 131 NS.zero CF$UID 181 $class CF$UID 149 NS.keys CF$UID 118 CF$UID 119 CF$UID 120 CF$UID 121 CF$UID 122 CF$UID 123 CF$UID 124 CF$UID 125 CF$UID 126 CF$UID 127 CF$UID 129 CF$UID 130 NS.objects CF$UID 131 CF$UID 132 CF$UID 178 CF$UID 179 CF$UID 180 CF$UID 181 CF$UID 142 CF$UID 143 CF$UID 144 CF$UID 183 CF$UID 143 CF$UID 184 $class CF$UID 115 NS.compact NS.exponent 0 NS.length 0 NS.mantissa AAAAArgAAAAAAAACuJaBkA== NS.mantissa.bo 1 NS.negative #,##0.0### 1000 $class CF$UID 141 NSAttributes CF$UID 139 NSString CF$UID 182 0 $class CF$UID 141 NSString CF$UID 43 $class CF$UID 141 NSAttributes CF$UID 139 NSString CF$UID 185 NaN $class CF$UID 31 NSCell CF$UID 188 NSEnabled NSFrame CF$UID 187 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{358, 214}, {78, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 189 NSControlView CF$UID 186 NSDrawsBackground NSFormatter CF$UID 190 NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 115 NS.compact NS.exponent 0 NS.length 1 NS.mantissa AgAAArgAAAAAAAACuJaBkA== NS.mantissa.bo 1 NS.negative $class CF$UID 150 NS.allowsfloats NS.attributes CF$UID 191 NS.decimal CF$UID 142 NS.hasthousands NS.localized NS.max CF$UID 167 NS.min CF$UID 167 NS.nan CF$UID 196 NS.negativeattrs CF$UID 0 NS.negativeformat CF$UID 144 NS.nil CF$UID 195 NS.positiveattrs CF$UID 0 NS.positiveformat CF$UID 179 NS.rounding CF$UID 0 NS.thousand CF$UID 131 NS.zero CF$UID 193 $class CF$UID 149 NS.keys CF$UID 118 CF$UID 119 CF$UID 121 CF$UID 122 CF$UID 123 CF$UID 124 CF$UID 125 CF$UID 126 CF$UID 127 CF$UID 129 CF$UID 130 NS.objects CF$UID 131 CF$UID 132 CF$UID 179 CF$UID 192 CF$UID 193 CF$UID 142 CF$UID 143 CF$UID 144 CF$UID 195 CF$UID 143 CF$UID 196 1000 $class CF$UID 141 NSAttributes CF$UID 139 NSString CF$UID 194 0 $class CF$UID 141 NSString CF$UID 43 $class CF$UID 141 NSAttributes CF$UID 139 NSString CF$UID 197 NaN $class CF$UID 31 NSCell CF$UID 200 NSEnabled NSFrame CF$UID 199 NSNextResponder CF$UID 72 NSSuperview CF$UID 72 NSvFlags 256 {{177, 259}, {78, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 201 NSControlView CF$UID 198 NSDrawsBackground NSFormatter CF$UID 202 NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 115 NS.compact NS.exponent 0 NS.length 1 NS.mantissa AgAAArgAAAAAAAACuJaBkA== NS.mantissa.bo 1 NS.negative $class CF$UID 150 NS.allowsfloats NS.attributes CF$UID 203 NS.decimal CF$UID 142 NS.hasthousands NS.localized NS.max CF$UID 167 NS.min CF$UID 204 NS.nan CF$UID 210 NS.negativeattrs CF$UID 0 NS.negativeformat CF$UID 208 NS.nil CF$UID 209 NS.positiveattrs CF$UID 0 NS.positiveformat CF$UID 179 NS.rounding CF$UID 0 NS.thousand CF$UID 131 NS.zero CF$UID 206 $class CF$UID 149 NS.keys CF$UID 118 CF$UID 119 CF$UID 120 CF$UID 121 CF$UID 122 CF$UID 123 CF$UID 124 CF$UID 125 CF$UID 126 CF$UID 127 CF$UID 129 CF$UID 130 NS.objects CF$UID 131 CF$UID 132 CF$UID 204 CF$UID 179 CF$UID 205 CF$UID 206 CF$UID 142 CF$UID 143 CF$UID 208 CF$UID 209 CF$UID 143 CF$UID 210 $class CF$UID 115 NS.compact NS.exponent 0 NS.length 0 NS.mantissa AAAAArgAAAAAAAACuJaBkA== NS.mantissa.bo 1 NS.negative 1000 $class CF$UID 141 NSAttributes CF$UID 139 NSString CF$UID 207 0 -#,##0.0000 $class CF$UID 141 NSString CF$UID 43 $class CF$UID 141 NSAttributes CF$UID 139 NSString CF$UID 211 NaN $classes NSMutableArray NSArray NSObject $classname NSMutableArray {{2, 2}, {512, 354}} $classes NSView NSResponder NSObject $classname NSView {{20, 20}, {516, 374}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 218 NSSupport CF$UID 19 NSTextColor CF$UID 219 Filter Genes $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== $classes NSBox NSView NSResponder NSObject $classname NSBox {{10, 33}, {556, 401}} {{10, 7}, {576, 447}} $class CF$UID 212 NS.objects CF$UID 224 CF$UID 228 CF$UID 327 CF$UID 517 CF$UID 674 CF$UID 816 $class CF$UID 227 NSColor CF$UID 22 NSIdentifier CF$UID 225 NSLabel CF$UID 226 NSTabView CF$UID 66 NSView CF$UID 68 $class CF$UID 4 NS.string 1 Filter Data $classes NSTabViewItem NSObject $classname NSTabViewItem $class CF$UID 227 NSColor CF$UID 22 NSIdentifier CF$UID 229 NSLabel CF$UID 326 NSTabView CF$UID 66 NSView CF$UID 230 $class CF$UID 4 NS.string 2 $class CF$UID 214 NSFrame CF$UID 325 NSNextResponder CF$UID 0 NSSubviews CF$UID 231 $class CF$UID 212 NS.objects CF$UID 232 CF$UID 246 CF$UID 259 CF$UID 265 CF$UID 298 $class CF$UID 220 NSBorderType 2 NSBoxType 1 NSContentView CF$UID 234 NSFrame CF$UID 241 NSNextResponder CF$UID 230 NSOffsets CF$UID 242 NSSubviews CF$UID 233 NSSuperview CF$UID 230 NSTitleCell CF$UID 243 NSTitlePosition 0 NSTransparent $class CF$UID 212 NS.objects CF$UID 234 $class CF$UID 214 NSFrame CF$UID 240 NSNextResponder CF$UID 232 NSSubviews CF$UID 235 NSSuperview CF$UID 232 $class CF$UID 212 NS.objects CF$UID 236 $class CF$UID 82 NSCell CF$UID 238 NSEnabled NSFrame CF$UID 237 NSNextResponder CF$UID 234 NSSuperview CF$UID 234 NSvFlags 256 {{18, 15}, {143, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 239 NSControlView CF$UID 236 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Log transform data {{3, 3}, {510, 51}} {{20, 324}, {516, 57}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 244 NSSupport CF$UID 19 NSTextColor CF$UID 245 Box $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== $class CF$UID 220 NSBorderType 2 NSBoxType 1 NSContentView CF$UID 248 NSFrame CF$UID 255 NSNextResponder CF$UID 230 NSOffsets CF$UID 256 NSSubviews CF$UID 247 NSSuperview CF$UID 230 NSTitleCell CF$UID 257 NSTitlePosition 0 NSTransparent $class CF$UID 212 NS.objects CF$UID 248 $class CF$UID 214 NSFrame CF$UID 254 NSNextResponder CF$UID 246 NSSubviews CF$UID 249 NSSuperview CF$UID 246 $class CF$UID 212 NS.objects CF$UID 250 $class CF$UID 31 NSCell CF$UID 252 NSEnabled NSFrame CF$UID 251 NSNextResponder CF$UID 248 NSSuperview CF$UID 248 NSvFlags 256 {{10, 13}, {139, 118}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 253 NSControlView CF$UID 250 NSSupport CF$UID 19 NSTextColor CF$UID 27 Order of Operations: Log Transform Center Genes Normalize Genes Center Arrays Normalize Arrays {{3, 3}, {231, 144}} {{20, 20}, {237, 150}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 244 NSSupport CF$UID 19 NSTextColor CF$UID 258 $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== $class CF$UID 82 NSCell CF$UID 261 NSEnabled NSFrame CF$UID 260 NSNextResponder CF$UID 230 NSSuperview CF$UID 230 NSvFlags 256 {{373, 89}, {84, 32}} $class CF$UID 81 NSAlternateContents CF$UID 263 NSAlternateImage CF$UID 99 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags 67239424 NSCellFlags2 137887744 NSContents CF$UID 262 NSControlView CF$UID 259 NSKeyEquivalent CF$UID 264 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Apply $class CF$UID 4 NS.string $class CF$UID 4 NS.string $class CF$UID 220 NSBorderType 2 NSBoxType 1 NSContentView CF$UID 267 NSFrame CF$UID 294 NSNextResponder CF$UID 230 NSOffsets CF$UID 295 NSSubviews CF$UID 266 NSSuperview CF$UID 230 NSTitleCell CF$UID 296 NSTitlePosition 0 NSTransparent $class CF$UID 212 NS.objects CF$UID 267 $class CF$UID 214 NSFrame CF$UID 293 NSNextResponder CF$UID 265 NSSubviews CF$UID 268 NSSuperview CF$UID 265 $class CF$UID 212 NS.objects CF$UID 269 CF$UID 273 CF$UID 289 $class CF$UID 82 NSCell CF$UID 271 NSEnabled NSFrame CF$UID 270 NSNextResponder CF$UID 267 NSSuperview CF$UID 267 NSvFlags 256 {{18, 80}, {106, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 272 NSControlView CF$UID 269 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Center genes $class CF$UID 288 NSBackgroundColor CF$UID 22 NSCellBackgroundColor CF$UID 46 NSCellClass CF$UID 285 NSCellSize CF$UID 283 NSCells CF$UID 275 NSEnabled NSFont CF$UID 19 NSFrame CF$UID 274 NSIntercellSpacing CF$UID 284 NSMatrixFlags 1143472128 NSNextResponder CF$UID 267 NSNumCols 1 NSNumRows 2 NSProtoCell CF$UID 286 NSSelectedCell CF$UID 276 NSSuperview CF$UID 267 NSvFlags 256 {{66, 38}, {68, 38}} $class CF$UID 212 NS.objects CF$UID 276 CF$UID 281 $class CF$UID 81 NSAlternateContents CF$UID 280 NSAlternateImage CF$UID 278 NSButtonFlags 1211912703 NSButtonFlags2 0 NSCellFlags -2080244224 NSCellFlags2 0 NSContents CF$UID 277 NSControlView CF$UID 273 NSKeyEquivalent CF$UID 280 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Mean $class CF$UID 80 NSImageName CF$UID 279 NSRadioButton $class CF$UID 4 NS.string $class CF$UID 81 NSAlternateContents CF$UID 280 NSAlternateImage CF$UID 278 NSButtonFlags 1211912703 NSButtonFlags2 0 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 282 NSControlView CF$UID 273 NSKeyEquivalent CF$UID 280 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 NSTag 1 Median {68, 18} {4, 2} NSActionCell $class CF$UID 81 NSAlternateImage CF$UID 278 NSButtonFlags 1211650559 NSButtonFlags2 0 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 287 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 400 NSPeriodicInterval 75 NSSupport CF$UID 19 Radio $classes NSMatrix %NSMatrix NSControl NSView NSResponder NSObject $classname NSMatrix $class CF$UID 82 NSCell CF$UID 291 NSEnabled NSFrame CF$UID 290 NSNextResponder CF$UID 267 NSSuperview CF$UID 267 NSvFlags 256 {{18, 16}, {128, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 292 NSControlView CF$UID 289 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Normalize genes {{3, 3}, {231, 116}} {{20, 188}, {237, 122}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 244 NSSupport CF$UID 19 NSTextColor CF$UID 297 $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== $class CF$UID 220 NSBorderType 2 NSBoxType 1 NSContentView CF$UID 300 NSFrame CF$UID 321 NSNextResponder CF$UID 230 NSOffsets CF$UID 322 NSSubviews CF$UID 299 NSSuperview CF$UID 230 NSTitleCell CF$UID 323 NSTitlePosition 0 NSTransparent $class CF$UID 212 NS.objects CF$UID 300 $class CF$UID 214 NSFrame CF$UID 320 NSNextResponder CF$UID 298 NSSubviews CF$UID 301 NSSuperview CF$UID 298 $class CF$UID 212 NS.objects CF$UID 302 CF$UID 306 CF$UID 316 $class CF$UID 82 NSCell CF$UID 304 NSEnabled NSFrame CF$UID 303 NSNextResponder CF$UID 300 NSSuperview CF$UID 300 NSvFlags 256 {{21, 80}, {111, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 305 NSControlView CF$UID 302 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Center arrays $class CF$UID 288 NSBackgroundColor CF$UID 22 NSCellBackgroundColor CF$UID 46 NSCellClass CF$UID 314 NSCellSize CF$UID 312 NSCells CF$UID 308 NSEnabled NSFont CF$UID 19 NSFrame CF$UID 307 NSIntercellSpacing CF$UID 313 NSMatrixFlags 1143472128 NSNextResponder CF$UID 300 NSNumCols 1 NSNumRows 2 NSProtoCell CF$UID 315 NSSelectedCell CF$UID 309 NSSuperview CF$UID 300 NSvFlags 256 {{74, 38}, {68, 38}} $class CF$UID 212 NS.objects CF$UID 309 CF$UID 311 $class CF$UID 81 NSAlternateContents CF$UID 310 NSAlternateImage CF$UID 278 NSButtonFlags 1211912703 NSButtonFlags2 0 NSCellFlags -2080244224 NSCellFlags2 0 NSContents CF$UID 277 NSControlView CF$UID 306 NSKeyEquivalent CF$UID 310 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 $class CF$UID 4 NS.string $class CF$UID 81 NSAlternateContents CF$UID 310 NSAlternateImage CF$UID 278 NSButtonFlags 1211912703 NSButtonFlags2 0 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 282 NSControlView CF$UID 306 NSKeyEquivalent CF$UID 310 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 NSTag 1 {68, 18} {4, 2} NSActionCell $class CF$UID 81 NSAlternateImage CF$UID 278 NSButtonFlags 1211650559 NSButtonFlags2 0 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 287 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 400 NSPeriodicInterval 75 NSSupport CF$UID 19 $class CF$UID 82 NSCell CF$UID 318 NSEnabled NSFrame CF$UID 317 NSNextResponder CF$UID 300 NSSuperview CF$UID 300 NSvFlags 256 {{21, 18}, {129, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 319 NSControlView CF$UID 316 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Normalize arrays {{3, 3}, {231, 116}} {{299, 188}, {237, 122}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 244 NSSupport CF$UID 19 NSTextColor CF$UID 324 $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== {{10, 33}, {556, 401}} Adjust Data $class CF$UID 227 NSColor CF$UID 22 NSIdentifier CF$UID 328 NSLabel CF$UID 516 NSTabView CF$UID 66 NSView CF$UID 329 $class CF$UID 4 NS.string 2 $class CF$UID 214 NSFrame CF$UID 515 NSNextResponder CF$UID 0 NSSubviews CF$UID 330 $class CF$UID 212 NS.objects CF$UID 331 CF$UID 363 CF$UID 452 $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 333 NSFrame CF$UID 358 NSNextResponder CF$UID 329 NSOffsets CF$UID 359 NSSubviews CF$UID 332 NSSuperview CF$UID 329 NSTitleCell CF$UID 360 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 333 $class CF$UID 214 NSFrame CF$UID 357 NSNextResponder CF$UID 331 NSSubviews CF$UID 334 NSSuperview CF$UID 331 $class CF$UID 212 NS.objects CF$UID 335 CF$UID 342 CF$UID 347 CF$UID 352 $class CF$UID 82 NSCell CF$UID 337 NSEnabled NSFrame CF$UID 336 NSNextResponder CF$UID 333 NSSuperview CF$UID 333 NSvFlags 256 {{7, 22}, {128, 28}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 340 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags 67239424 NSCellFlags2 138018816 NSContents CF$UID 338 NSControlView CF$UID 335 NSKeyEquivalent CF$UID 341 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 339 Centroid linkage $class CF$UID 21 NSName CF$UID 20 NSSize 11 NSfFlags 3100 $class CF$UID 21 NSName CF$UID 100 NSSize 11 NSfFlags 16 $class CF$UID 4 NS.string $class CF$UID 82 NSCell CF$UID 344 NSEnabled NSFrame CF$UID 343 NSNextResponder CF$UID 333 NSSuperview CF$UID 333 NSvFlags 256 {{138, 22}, {120, 28}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 340 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags 67239424 NSCellFlags2 138018816 NSContents CF$UID 345 NSControlView CF$UID 342 NSKeyEquivalent CF$UID 346 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 339 Single linkage $class CF$UID 4 NS.string $class CF$UID 82 NSCell CF$UID 349 NSEnabled NSFrame CF$UID 348 NSNextResponder CF$UID 333 NSSuperview CF$UID 333 NSvFlags 256 {{261, 22}, {120, 28}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 340 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags 67239424 NSCellFlags2 138018816 NSContents CF$UID 350 NSControlView CF$UID 347 NSKeyEquivalent CF$UID 351 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 339 Complete linkage $class CF$UID 4 NS.string $class CF$UID 82 NSCell CF$UID 354 NSEnabled NSFrame CF$UID 353 NSNextResponder CF$UID 333 NSSuperview CF$UID 333 NSvFlags 256 {{384, 22}, {120, 28}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 340 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags 67239424 NSCellFlags2 138018816 NSContents CF$UID 355 NSControlView CF$UID 352 NSKeyEquivalent CF$UID 356 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 339 Average linkage $class CF$UID 4 NS.string {{2, 2}, {512, 73}} {{20, 20}, {516, 93}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 361 NSSupport CF$UID 19 NSTextColor CF$UID 362 Clustering method $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 365 NSFrame CF$UID 447 NSNextResponder CF$UID 329 NSOffsets CF$UID 448 NSSubviews CF$UID 364 NSSuperview CF$UID 329 NSTitleCell CF$UID 449 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 365 $class CF$UID 214 NSFrame CF$UID 446 NSNextResponder CF$UID 363 NSSubviews CF$UID 366 NSSuperview CF$UID 363 $class CF$UID 212 NS.objects CF$UID 367 CF$UID 408 CF$UID 412 CF$UID 416 CF$UID 420 $class CF$UID 407 NSCell CF$UID 369 NSEnabled NSFrame CF$UID 368 NSNextResponder CF$UID 365 NSSuperview CF$UID 365 NSvFlags 256 {{11, 10}, {222, 22}} $class CF$UID 406 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 339 NSAltersState NSArrowPosition 1 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags -2076049856 NSCellFlags2 134349824 NSControlView CF$UID 367 NSKeyEquivalent CF$UID 370 NSMenu CF$UID 372 NSMenuItem CF$UID 371 NSPeriodicDelay 400 NSPeriodicInterval 75 NSPreferredEdge 3 NSSupport CF$UID 339 NSUsesItemFromMenu $class CF$UID 4 NS.string $class CF$UID 381 NSAction CF$UID 380 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 372 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSState 1 NSTarget CF$UID 369 NSTitle CF$UID 373 $class CF$UID 405 NSMenuItems CF$UID 383 NSTitle CF$UID 382 Correlation (uncentered) $class CF$UID 377 NSClassName CF$UID 375 NSResourceName CF$UID 376 NSImage NSMenuCheckmark $classes NSCustomResource %NSCustomResource NSObject $classname NSCustomResource $class CF$UID 377 NSClassName CF$UID 375 NSResourceName CF$UID 379 NSMenuMixedState _popUpItemAction: $classes NSMenuItem NSObject $classname NSMenuItem $class CF$UID 4 NS.string OtherViews $class CF$UID 212 NS.objects CF$UID 371 CF$UID 384 CF$UID 387 CF$UID 390 CF$UID 393 CF$UID 396 CF$UID 399 CF$UID 402 $class CF$UID 381 NSAction CF$UID 386 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 372 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 369 NSTitle CF$UID 385 Correlation (centered) _popUpItemAction: $class CF$UID 381 NSAction CF$UID 389 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 372 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 369 NSTitle CF$UID 388 Absolute Correlation (uncentered) _popUpItemAction: $class CF$UID 381 NSAction CF$UID 392 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 372 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 369 NSTitle CF$UID 391 Absolute Correlation (centered) _popUpItemAction: $class CF$UID 381 NSAction CF$UID 395 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 372 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 369 NSTitle CF$UID 394 Spearman Rank Correlation _popUpItemAction: $class CF$UID 381 NSAction CF$UID 398 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 372 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 369 NSTitle CF$UID 397 Kendall's tau _popUpItemAction: $class CF$UID 381 NSAction CF$UID 401 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 372 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 369 NSTitle CF$UID 400 Euclidean distance _popUpItemAction: $class CF$UID 381 NSAction CF$UID 404 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 372 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 369 NSTitle CF$UID 403 City-block distance _popUpItemAction: $classes NSMenu NSObject $classname NSMenu $classes NSPopUpButtonCell NSMenuItemCell NSButtonCell %NSButtonCell NSActionCell NSCell NSObject $classname NSPopUpButtonCell $classes NSPopUpButton NSButton NSControl NSView NSResponder NSObject $classname NSPopUpButton $class CF$UID 82 NSCell CF$UID 410 NSEnabled NSFrame CF$UID 409 NSNextResponder CF$UID 365 NSSuperview CF$UID 365 NSvFlags 256 {{13, 178}, {67, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 411 NSControlView CF$UID 408 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Cluster $class CF$UID 82 NSCell CF$UID 414 NSEnabled NSFrame CF$UID 413 NSNextResponder CF$UID 365 NSSuperview CF$UID 365 NSvFlags 256 {{13, 104}, {80, 34}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 415 NSControlView CF$UID 412 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Calculate weights $class CF$UID 31 NSCell CF$UID 418 NSEnabled NSFrame CF$UID 417 NSNextResponder CF$UID 365 NSSuperview CF$UID 365 NSvFlags 256 {{65, 39}, {114, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 419 NSControlView CF$UID 416 NSSupport CF$UID 19 NSTextColor CF$UID 27 Similarity Metric $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 422 NSFrame CF$UID 441 NSNextResponder CF$UID 365 NSOffsets CF$UID 442 NSSubviews CF$UID 421 NSSuperview CF$UID 365 NSTitleCell CF$UID 443 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 422 $class CF$UID 214 NSFrame CF$UID 440 NSNextResponder CF$UID 420 NSSubviews CF$UID 423 NSSuperview CF$UID 420 $class CF$UID 212 NS.objects CF$UID 424 CF$UID 428 CF$UID 432 CF$UID 436 $class CF$UID 31 NSCell CF$UID 426 NSEnabled NSFrame CF$UID 425 NSNextResponder CF$UID 422 NSSuperview CF$UID 422 NSvFlags 256 {{12, 45}, {44, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 427 NSControlView CF$UID 424 NSSupport CF$UID 19 NSTextColor CF$UID 27 Cutoff $class CF$UID 31 NSCell CF$UID 430 NSEnabled NSFrame CF$UID 429 NSNextResponder CF$UID 422 NSSuperview CF$UID 422 NSvFlags 256 {{61, 43}, {53, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 431 NSControlView CF$UID 428 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 0.1 $class CF$UID 31 NSCell CF$UID 434 NSEnabled NSFrame CF$UID 433 NSNextResponder CF$UID 422 NSSuperview CF$UID 422 NSvFlags 256 {{11, 14}, {64, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 435 NSControlView CF$UID 432 NSSupport CF$UID 19 NSTextColor CF$UID 27 Exponent $class CF$UID 31 NSCell CF$UID 438 NSEnabled NSFrame CF$UID 437 NSNextResponder CF$UID 422 NSSuperview CF$UID 422 NSvFlags 256 {{80, 12}, {34, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 439 NSControlView CF$UID 436 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 1 {{2, 2}, {128, 85}} {{98, 106}, {132, 105}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 444 NSSupport CF$UID 19 NSTextColor CF$UID 445 Weight Options $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== {{2, 2}, {244, 232}} {{288, 142}, {248, 252}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 450 NSSupport CF$UID 19 NSTextColor CF$UID 451 Arrays $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 454 NSFrame CF$UID 510 NSNextResponder CF$UID 329 NSOffsets CF$UID 511 NSSubviews CF$UID 453 NSSuperview CF$UID 329 NSTitleCell CF$UID 512 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 454 $class CF$UID 214 NSFrame CF$UID 509 NSNextResponder CF$UID 452 NSSubviews CF$UID 455 NSSuperview CF$UID 452 $class CF$UID 212 NS.objects CF$UID 456 CF$UID 477 CF$UID 500 CF$UID 503 CF$UID 506 $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 458 NSFrame CF$UID 473 NSNextResponder CF$UID 454 NSOffsets CF$UID 474 NSSubviews CF$UID 457 NSSuperview CF$UID 454 NSTitleCell CF$UID 475 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 458 $class CF$UID 214 NSFrame CF$UID 472 NSNextResponder CF$UID 456 NSSubviews CF$UID 459 NSSuperview CF$UID 456 $class CF$UID 212 NS.objects CF$UID 460 CF$UID 463 CF$UID 466 CF$UID 469 $class CF$UID 31 NSCell CF$UID 462 NSEnabled NSFrame CF$UID 461 NSNextResponder CF$UID 458 NSSuperview CF$UID 458 NSvFlags 256 {{12, 45}, {44, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 427 NSControlView CF$UID 460 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 31 NSCell CF$UID 465 NSEnabled NSFrame CF$UID 464 NSNextResponder CF$UID 458 NSSuperview CF$UID 458 NSvFlags 256 {{61, 43}, {53, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 431 NSControlView CF$UID 463 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 31 NSCell CF$UID 468 NSEnabled NSFrame CF$UID 467 NSNextResponder CF$UID 458 NSSuperview CF$UID 458 NSvFlags 256 {{11, 14}, {64, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 435 NSControlView CF$UID 466 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 31 NSCell CF$UID 471 NSEnabled NSFrame CF$UID 470 NSNextResponder CF$UID 458 NSSuperview CF$UID 458 NSvFlags 256 {{80, 12}, {34, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 439 NSControlView CF$UID 469 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 {{2, 2}, {128, 85}} {{98, 106}, {132, 105}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 444 NSSupport CF$UID 19 NSTextColor CF$UID 476 $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== $class CF$UID 407 NSCell CF$UID 479 NSEnabled NSFrame CF$UID 478 NSNextResponder CF$UID 454 NSSuperview CF$UID 454 NSvFlags 256 {{11, 10}, {222, 22}} $class CF$UID 406 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 339 NSAltersState NSArrowPosition 1 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags -2076049856 NSCellFlags2 134349824 NSControlView CF$UID 477 NSKeyEquivalent CF$UID 480 NSMenu CF$UID 482 NSMenuItem CF$UID 481 NSPeriodicDelay 400 NSPeriodicInterval 75 NSPreferredEdge 3 NSSupport CF$UID 339 NSUsesItemFromMenu $class CF$UID 4 NS.string $class CF$UID 381 NSAction CF$UID 483 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 482 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSState 1 NSTarget CF$UID 479 NSTitle CF$UID 373 $class CF$UID 405 NSMenuItems CF$UID 485 NSTitle CF$UID 484 _popUpItemAction: $class CF$UID 4 NS.string OtherViews $class CF$UID 212 NS.objects CF$UID 481 CF$UID 486 CF$UID 488 CF$UID 490 CF$UID 492 CF$UID 494 CF$UID 496 CF$UID 498 $class CF$UID 381 NSAction CF$UID 487 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 482 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 479 NSTitle CF$UID 385 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 489 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 482 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 479 NSTitle CF$UID 388 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 491 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 482 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 479 NSTitle CF$UID 391 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 493 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 482 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 479 NSTitle CF$UID 394 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 495 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 482 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 479 NSTitle CF$UID 397 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 497 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 482 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 479 NSTitle CF$UID 400 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 499 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 482 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 479 NSTitle CF$UID 403 _popUpItemAction: $class CF$UID 82 NSCell CF$UID 502 NSEnabled NSFrame CF$UID 501 NSNextResponder CF$UID 454 NSSuperview CF$UID 454 NSvFlags 256 {{13, 178}, {67, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 411 NSControlView CF$UID 500 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 $class CF$UID 82 NSCell CF$UID 505 NSEnabled NSFrame CF$UID 504 NSNextResponder CF$UID 454 NSSuperview CF$UID 454 NSvFlags 256 {{13, 104}, {80, 34}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 415 NSControlView CF$UID 503 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 $class CF$UID 31 NSCell CF$UID 508 NSEnabled NSFrame CF$UID 507 NSNextResponder CF$UID 454 NSSuperview CF$UID 454 NSvFlags 256 {{65, 39}, {114, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 419 NSControlView CF$UID 506 NSSupport CF$UID 19 NSTextColor CF$UID 27 {{2, 2}, {244, 232}} {{20, 142}, {248, 252}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 513 NSSupport CF$UID 19 NSTextColor CF$UID 514 Genes $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== {{10, 33}, {556, 401}} Hierarchical $class CF$UID 227 NSColor CF$UID 22 NSIdentifier CF$UID 518 NSLabel CF$UID 579 NSTabView CF$UID 66 NSView CF$UID 519 $class CF$UID 4 NS.string 2 $class CF$UID 214 NSFrame CF$UID 673 NSNextResponder CF$UID 0 NSSubviews CF$UID 520 $class CF$UID 212 NS.objects CF$UID 521 CF$UID 598 CF$UID 668 $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 523 NSFrame CF$UID 594 NSNextResponder CF$UID 519 NSOffsets CF$UID 595 NSSubviews CF$UID 522 NSSuperview CF$UID 519 NSTitleCell CF$UID 596 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 523 $class CF$UID 214 NSFrame CF$UID 593 NSNextResponder CF$UID 521 NSSubviews CF$UID 524 NSSuperview CF$UID 521 $class CF$UID 212 NS.objects CF$UID 525 CF$UID 548 CF$UID 552 CF$UID 556 CF$UID 560 CF$UID 564 CF$UID 568 CF$UID 571 $class CF$UID 407 NSCell CF$UID 527 NSEnabled NSFrame CF$UID 526 NSNextResponder CF$UID 523 NSSuperview CF$UID 523 NSvFlags 256 {{11, 10}, {222, 22}} $class CF$UID 406 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 339 NSAltersState NSArrowPosition 1 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags -2076049856 NSCellFlags2 134349824 NSControlView CF$UID 525 NSKeyEquivalent CF$UID 528 NSMenu CF$UID 530 NSMenuItem CF$UID 529 NSPeriodicDelay 400 NSPeriodicInterval 75 NSPreferredEdge 3 NSSelectedIndex 6 NSSupport CF$UID 339 NSUsesItemFromMenu $class CF$UID 4 NS.string $class CF$UID 381 NSAction CF$UID 531 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 530 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSState 1 NSTarget CF$UID 527 NSTitle CF$UID 400 $class CF$UID 405 NSMenuItems CF$UID 533 NSTitle CF$UID 532 _popUpItemAction: $class CF$UID 4 NS.string OtherViews $class CF$UID 212 NS.objects CF$UID 534 CF$UID 536 CF$UID 538 CF$UID 540 CF$UID 542 CF$UID 544 CF$UID 529 CF$UID 546 $class CF$UID 381 NSAction CF$UID 535 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 530 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 527 NSTitle CF$UID 373 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 537 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 530 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 527 NSTitle CF$UID 385 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 539 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 530 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 527 NSTitle CF$UID 388 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 541 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 530 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 527 NSTitle CF$UID 391 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 543 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 530 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 527 NSTitle CF$UID 394 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 545 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 530 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 527 NSTitle CF$UID 397 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 547 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 530 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 527 NSTitle CF$UID 403 _popUpItemAction: $class CF$UID 82 NSCell CF$UID 550 NSEnabled NSFrame CF$UID 549 NSNextResponder CF$UID 523 NSSuperview CF$UID 523 NSvFlags 256 {{12, 275}, {129, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 551 NSControlView CF$UID 548 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Organize genes $class CF$UID 31 NSCell CF$UID 554 NSEnabled NSFrame CF$UID 553 NSNextResponder CF$UID 523 NSSuperview CF$UID 523 NSvFlags 256 {{14, 227}, {48, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 555 NSControlView CF$UID 552 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 10 $class CF$UID 31 NSCell CF$UID 558 NSEnabled NSFrame CF$UID 557 NSNextResponder CF$UID 523 NSSuperview CF$UID 523 NSvFlags 256 {{67, 229}, {149, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 559 NSControlView CF$UID 556 NSSupport CF$UID 19 NSTextColor CF$UID 27 number of clusters (k) $class CF$UID 31 NSCell CF$UID 562 NSEnabled NSFrame CF$UID 561 NSNextResponder CF$UID 523 NSSuperview CF$UID 523 NSvFlags 256 {{14, 187}, {78, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 563 NSControlView CF$UID 560 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 100 $class CF$UID 31 NSCell CF$UID 566 NSEnabled NSFrame CF$UID 565 NSNextResponder CF$UID 523 NSSuperview CF$UID 523 NSvFlags 256 {{97, 189}, {110, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 567 NSControlView CF$UID 564 NSSupport CF$UID 19 NSTextColor CF$UID 27 number of runs $class CF$UID 31 NSCell CF$UID 570 NSEnabled NSFrame CF$UID 569 NSNextResponder CF$UID 523 NSSuperview CF$UID 523 NSvFlags 256 {{66, 39}, {114, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 419 NSControlView CF$UID 568 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 573 NSFrame CF$UID 588 NSNextResponder CF$UID 523 NSOffsets CF$UID 589 NSSubviews CF$UID 572 NSSuperview CF$UID 523 NSTitleCell CF$UID 590 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 573 $class CF$UID 214 NSFrame CF$UID 587 NSNextResponder CF$UID 571 NSSubviews CF$UID 574 NSSuperview CF$UID 571 $class CF$UID 212 NS.objects CF$UID 575 $class CF$UID 288 NSBackgroundColor CF$UID 22 NSCellBackgroundColor CF$UID 46 NSCellClass CF$UID 585 NSCellSize CF$UID 583 NSCells CF$UID 577 NSEnabled NSFont CF$UID 19 NSFrame CF$UID 576 NSIntercellSpacing CF$UID 584 NSMatrixFlags 1143472128 NSNextResponder CF$UID 573 NSNumCols 1 NSNumRows 2 NSProtoCell CF$UID 586 NSSelectedCell CF$UID 578 NSSuperview CF$UID 573 NSvFlags 256 {{12, 12}, {101, 38}} $class CF$UID 212 NS.objects CF$UID 578 CF$UID 581 $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 278 NSButtonFlags 1211912703 NSButtonFlags2 0 NSCellFlags -2080244224 NSCellFlags2 0 NSContents CF$UID 579 NSControlView CF$UID 575 NSKeyEquivalent CF$UID 580 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 k-Means $class CF$UID 4 NS.string $class CF$UID 81 NSAlternateContents CF$UID 580 NSAlternateImage CF$UID 278 NSButtonFlags 1211912703 NSButtonFlags2 0 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 582 NSControlView CF$UID 575 NSKeyEquivalent CF$UID 580 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 NSTag 1 k-Medians {101, 18} {4, 2} NSActionCell $class CF$UID 81 NSAlternateImage CF$UID 278 NSButtonFlags 1211650559 NSButtonFlags2 0 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 287 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 400 NSPeriodicInterval 75 NSSupport CF$UID 19 {{2, 2}, {113, 59}} {{14, 83}, {117, 79}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 591 NSSupport CF$UID 19 NSTextColor CF$UID 592 Method $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== {{2, 2}, {244, 302}} {{20, 72}, {248, 322}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 513 NSSupport CF$UID 19 NSTextColor CF$UID 597 $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 600 NSFrame CF$UID 664 NSNextResponder CF$UID 519 NSOffsets CF$UID 665 NSSubviews CF$UID 599 NSSuperview CF$UID 519 NSTitleCell CF$UID 666 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 600 $class CF$UID 214 NSFrame CF$UID 663 NSNextResponder CF$UID 598 NSSubviews CF$UID 601 NSSuperview CF$UID 598 $class CF$UID 212 NS.objects CF$UID 602 CF$UID 625 CF$UID 629 CF$UID 632 CF$UID 635 CF$UID 638 CF$UID 641 CF$UID 644 $class CF$UID 407 NSCell CF$UID 604 NSEnabled NSFrame CF$UID 603 NSNextResponder CF$UID 600 NSSuperview CF$UID 600 NSvFlags 256 {{11, 10}, {222, 22}} $class CF$UID 406 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 339 NSAltersState NSArrowPosition 1 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags -2076049856 NSCellFlags2 134349824 NSControlView CF$UID 602 NSKeyEquivalent CF$UID 605 NSMenu CF$UID 607 NSMenuItem CF$UID 606 NSPeriodicDelay 400 NSPeriodicInterval 75 NSPreferredEdge 3 NSSelectedIndex 6 NSSupport CF$UID 339 NSUsesItemFromMenu $class CF$UID 4 NS.string $class CF$UID 381 NSAction CF$UID 608 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 607 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSState 1 NSTarget CF$UID 604 NSTitle CF$UID 400 $class CF$UID 405 NSMenuItems CF$UID 610 NSTitle CF$UID 609 _popUpItemAction: $class CF$UID 4 NS.string OtherViews $class CF$UID 212 NS.objects CF$UID 611 CF$UID 613 CF$UID 615 CF$UID 617 CF$UID 619 CF$UID 621 CF$UID 606 CF$UID 623 $class CF$UID 381 NSAction CF$UID 612 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 607 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 604 NSTitle CF$UID 373 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 614 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 607 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 604 NSTitle CF$UID 385 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 616 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 607 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 604 NSTitle CF$UID 388 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 618 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 607 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 604 NSTitle CF$UID 391 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 620 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 607 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 604 NSTitle CF$UID 394 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 622 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 607 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 604 NSTitle CF$UID 397 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 624 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 607 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 604 NSTitle CF$UID 403 _popUpItemAction: $class CF$UID 82 NSCell CF$UID 627 NSEnabled NSFrame CF$UID 626 NSNextResponder CF$UID 600 NSSuperview CF$UID 600 NSvFlags 256 {{12, 275}, {129, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 628 NSControlView CF$UID 625 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Organize arrays $class CF$UID 31 NSCell CF$UID 631 NSEnabled NSFrame CF$UID 630 NSNextResponder CF$UID 600 NSSuperview CF$UID 600 NSvFlags 256 {{14, 227}, {48, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 555 NSControlView CF$UID 629 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 31 NSCell CF$UID 634 NSEnabled NSFrame CF$UID 633 NSNextResponder CF$UID 600 NSSuperview CF$UID 600 NSvFlags 256 {{67, 229}, {149, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 559 NSControlView CF$UID 632 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 31 NSCell CF$UID 637 NSEnabled NSFrame CF$UID 636 NSNextResponder CF$UID 600 NSSuperview CF$UID 600 NSvFlags 256 {{14, 187}, {78, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 563 NSControlView CF$UID 635 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 31 NSCell CF$UID 640 NSEnabled NSFrame CF$UID 639 NSNextResponder CF$UID 600 NSSuperview CF$UID 600 NSvFlags 256 {{97, 189}, {110, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 567 NSControlView CF$UID 638 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 31 NSCell CF$UID 643 NSEnabled NSFrame CF$UID 642 NSNextResponder CF$UID 600 NSSuperview CF$UID 600 NSvFlags 256 {{66, 39}, {114, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 419 NSControlView CF$UID 641 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 646 NSFrame CF$UID 659 NSNextResponder CF$UID 600 NSOffsets CF$UID 660 NSSubviews CF$UID 645 NSSuperview CF$UID 600 NSTitleCell CF$UID 661 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 646 $class CF$UID 214 NSFrame CF$UID 658 NSNextResponder CF$UID 644 NSSubviews CF$UID 647 NSSuperview CF$UID 644 $class CF$UID 212 NS.objects CF$UID 648 $class CF$UID 288 NSBackgroundColor CF$UID 22 NSCellBackgroundColor CF$UID 46 NSCellClass CF$UID 656 NSCellSize CF$UID 654 NSCells CF$UID 650 NSEnabled NSFont CF$UID 19 NSFrame CF$UID 649 NSIntercellSpacing CF$UID 655 NSMatrixFlags 1143472128 NSNextResponder CF$UID 646 NSNumCols 1 NSNumRows 2 NSProtoCell CF$UID 657 NSSelectedCell CF$UID 651 NSSuperview CF$UID 646 NSvFlags 256 {{12, 12}, {101, 38}} $class CF$UID 212 NS.objects CF$UID 651 CF$UID 653 $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 278 NSButtonFlags 1211912703 NSButtonFlags2 0 NSCellFlags -2080244224 NSCellFlags2 0 NSContents CF$UID 579 NSControlView CF$UID 648 NSKeyEquivalent CF$UID 652 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 $class CF$UID 4 NS.string $class CF$UID 81 NSAlternateContents CF$UID 652 NSAlternateImage CF$UID 278 NSButtonFlags 1211912703 NSButtonFlags2 0 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 582 NSControlView CF$UID 648 NSKeyEquivalent CF$UID 652 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 NSTag 1 {101, 18} {4, 2} NSActionCell $class CF$UID 81 NSAlternateImage CF$UID 278 NSButtonFlags 1211650559 NSButtonFlags2 0 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 287 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 400 NSPeriodicInterval 75 NSSupport CF$UID 19 {{2, 2}, {113, 59}} {{14, 83}, {117, 79}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 591 NSSupport CF$UID 19 NSTextColor CF$UID 662 $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== {{2, 2}, {244, 302}} {{288, 72}, {248, 322}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 450 NSSupport CF$UID 19 NSTextColor CF$UID 667 $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== $class CF$UID 82 NSCell CF$UID 670 NSEnabled NSFrame CF$UID 669 NSNextResponder CF$UID 519 NSSuperview CF$UID 519 NSvFlags 256 {{233, 19}, {90, 32}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 99 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags 67239424 NSCellFlags2 137887744 NSContents CF$UID 671 NSControlView CF$UID 668 NSKeyEquivalent CF$UID 672 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Execute $class CF$UID 4 NS.string {{10, 33}, {556, 401}} $class CF$UID 227 NSColor CF$UID 22 NSIdentifier CF$UID 675 NSLabel CF$UID 815 NSTabView CF$UID 66 NSView CF$UID 676 $class CF$UID 4 NS.string 2 $class CF$UID 214 NSFrame CF$UID 814 NSNextResponder CF$UID 0 NSSubviews CF$UID 677 $class CF$UID 212 NS.objects CF$UID 678 CF$UID 683 CF$UID 751 $class CF$UID 82 NSCell CF$UID 680 NSEnabled NSFrame CF$UID 679 NSNextResponder CF$UID 676 NSSuperview CF$UID 676 NSvFlags 256 {{225, 14}, {106, 32}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 99 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags 67239424 NSCellFlags2 137887744 NSContents CF$UID 681 NSControlView CF$UID 678 NSKeyEquivalent CF$UID 682 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Make SOM $class CF$UID 4 NS.string $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 685 NSFrame CF$UID 747 NSNextResponder CF$UID 676 NSOffsets CF$UID 748 NSSubviews CF$UID 684 NSSuperview CF$UID 676 NSTitleCell CF$UID 749 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 685 $class CF$UID 214 NSFrame CF$UID 746 NSNextResponder CF$UID 683 NSSubviews CF$UID 686 NSSuperview CF$UID 683 $class CF$UID 212 NS.objects CF$UID 687 CF$UID 710 CF$UID 713 CF$UID 716 CF$UID 720 CF$UID 723 CF$UID 727 CF$UID 730 CF$UID 734 CF$UID 738 CF$UID 742 $class CF$UID 407 NSCell CF$UID 689 NSEnabled NSFrame CF$UID 688 NSNextResponder CF$UID 685 NSSuperview CF$UID 685 NSvFlags 256 {{11, 10}, {222, 22}} $class CF$UID 406 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 339 NSAltersState NSArrowPosition 1 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags -2076049856 NSCellFlags2 134349824 NSControlView CF$UID 687 NSKeyEquivalent CF$UID 690 NSMenu CF$UID 692 NSMenuItem CF$UID 691 NSPeriodicDelay 400 NSPeriodicInterval 75 NSPreferredEdge 3 NSSelectedIndex 6 NSSupport CF$UID 339 NSUsesItemFromMenu $class CF$UID 4 NS.string $class CF$UID 381 NSAction CF$UID 693 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 692 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSState 1 NSTarget CF$UID 689 NSTitle CF$UID 400 $class CF$UID 405 NSMenuItems CF$UID 695 NSTitle CF$UID 694 _popUpItemAction: $class CF$UID 4 NS.string OtherViews $class CF$UID 212 NS.objects CF$UID 696 CF$UID 698 CF$UID 700 CF$UID 702 CF$UID 704 CF$UID 706 CF$UID 691 CF$UID 708 $class CF$UID 381 NSAction CF$UID 697 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 692 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 689 NSTitle CF$UID 373 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 699 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 692 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 689 NSTitle CF$UID 385 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 701 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 692 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 689 NSTitle CF$UID 388 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 703 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 692 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 689 NSTitle CF$UID 391 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 705 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 692 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 689 NSTitle CF$UID 394 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 707 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 692 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 689 NSTitle CF$UID 397 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 709 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 692 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 689 NSTitle CF$UID 403 _popUpItemAction: $class CF$UID 82 NSCell CF$UID 712 NSEnabled NSFrame CF$UID 711 NSNextResponder CF$UID 685 NSSuperview CF$UID 685 NSvFlags 256 {{12, 275}, {129, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 551 NSControlView CF$UID 710 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 $class CF$UID 31 NSCell CF$UID 715 NSEnabled NSFrame CF$UID 714 NSNextResponder CF$UID 685 NSSuperview CF$UID 685 NSvFlags 256 {{14, 227}, {48, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 555 NSControlView CF$UID 713 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 31 NSCell CF$UID 718 NSEnabled NSFrame CF$UID 717 NSNextResponder CF$UID 685 NSSuperview CF$UID 685 NSvFlags 256 {{67, 229}, {38, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 719 NSControlView CF$UID 716 NSSupport CF$UID 19 NSTextColor CF$UID 27 XDim $class CF$UID 31 NSCell CF$UID 722 NSEnabled NSFrame CF$UID 721 NSNextResponder CF$UID 685 NSSuperview CF$UID 685 NSvFlags 256 {{14, 187}, {48, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 555 NSControlView CF$UID 720 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 31 NSCell CF$UID 725 NSEnabled NSFrame CF$UID 724 NSNextResponder CF$UID 685 NSSuperview CF$UID 685 NSvFlags 256 {{67, 189}, {38, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 726 NSControlView CF$UID 723 NSSupport CF$UID 19 NSTextColor CF$UID 27 YDim $class CF$UID 31 NSCell CF$UID 729 NSEnabled NSFrame CF$UID 728 NSNextResponder CF$UID 685 NSSuperview CF$UID 685 NSvFlags 256 {{66, 39}, {114, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 419 NSControlView CF$UID 727 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 31 NSCell CF$UID 732 NSEnabled NSFrame CF$UID 731 NSNextResponder CF$UID 685 NSSuperview CF$UID 685 NSvFlags 256 {{101, 130}, {139, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 733 NSControlView CF$UID 730 NSSupport CF$UID 19 NSTextColor CF$UID 27 Number of iterations $class CF$UID 31 NSCell CF$UID 736 NSEnabled NSFrame CF$UID 735 NSNextResponder CF$UID 685 NSSuperview CF$UID 685 NSvFlags 256 {{14, 128}, {82, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 737 NSControlView CF$UID 734 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 100000 $class CF$UID 31 NSCell CF$UID 740 NSEnabled NSFrame CF$UID 739 NSNextResponder CF$UID 685 NSSuperview CF$UID 685 NSvFlags 256 {{14, 88}, {61, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 741 NSControlView CF$UID 738 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 0.02 $class CF$UID 31 NSCell CF$UID 744 NSEnabled NSFrame CF$UID 743 NSNextResponder CF$UID 685 NSSuperview CF$UID 685 NSvFlags 256 {{80, 90}, {67, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 745 NSControlView CF$UID 742 NSSupport CF$UID 19 NSTextColor CF$UID 27 Initial tau {{2, 2}, {244, 302}} {{20, 72}, {248, 322}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 513 NSSupport CF$UID 19 NSTextColor CF$UID 750 $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 753 NSFrame CF$UID 810 NSNextResponder CF$UID 676 NSOffsets CF$UID 811 NSSubviews CF$UID 752 NSSuperview CF$UID 676 NSTitleCell CF$UID 812 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 753 $class CF$UID 214 NSFrame CF$UID 809 NSNextResponder CF$UID 751 NSSubviews CF$UID 754 NSSuperview CF$UID 751 $class CF$UID 212 NS.objects CF$UID 755 CF$UID 778 CF$UID 781 CF$UID 784 CF$UID 787 CF$UID 790 CF$UID 793 CF$UID 796 CF$UID 799 CF$UID 803 CF$UID 806 $class CF$UID 407 NSCell CF$UID 757 NSEnabled NSFrame CF$UID 756 NSNextResponder CF$UID 753 NSSuperview CF$UID 753 NSvFlags 256 {{11, 10}, {222, 22}} $class CF$UID 406 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 339 NSAltersState NSArrowPosition 1 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags -2076049856 NSCellFlags2 134349824 NSControlView CF$UID 755 NSKeyEquivalent CF$UID 758 NSMenu CF$UID 760 NSMenuItem CF$UID 759 NSPeriodicDelay 400 NSPeriodicInterval 75 NSPreferredEdge 3 NSSelectedIndex 6 NSSupport CF$UID 339 NSUsesItemFromMenu $class CF$UID 4 NS.string $class CF$UID 381 NSAction CF$UID 761 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 760 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSState 1 NSTarget CF$UID 757 NSTitle CF$UID 400 $class CF$UID 405 NSMenuItems CF$UID 763 NSTitle CF$UID 762 _popUpItemAction: $class CF$UID 4 NS.string OtherViews $class CF$UID 212 NS.objects CF$UID 764 CF$UID 766 CF$UID 768 CF$UID 770 CF$UID 772 CF$UID 774 CF$UID 759 CF$UID 776 $class CF$UID 381 NSAction CF$UID 765 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 760 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 757 NSTitle CF$UID 373 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 767 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 760 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 757 NSTitle CF$UID 385 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 769 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 760 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 757 NSTitle CF$UID 388 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 771 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 760 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 757 NSTitle CF$UID 391 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 773 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 760 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 757 NSTitle CF$UID 394 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 775 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 760 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 757 NSTitle CF$UID 397 _popUpItemAction: $class CF$UID 381 NSAction CF$UID 777 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 760 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTarget CF$UID 757 NSTitle CF$UID 403 _popUpItemAction: $class CF$UID 82 NSCell CF$UID 780 NSEnabled NSFrame CF$UID 779 NSNextResponder CF$UID 753 NSSuperview CF$UID 753 NSvFlags 256 {{12, 275}, {129, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 628 NSControlView CF$UID 778 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 $class CF$UID 31 NSCell CF$UID 783 NSEnabled NSFrame CF$UID 782 NSNextResponder CF$UID 753 NSSuperview CF$UID 753 NSvFlags 256 {{14, 227}, {48, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 555 NSControlView CF$UID 781 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 31 NSCell CF$UID 786 NSEnabled NSFrame CF$UID 785 NSNextResponder CF$UID 753 NSSuperview CF$UID 753 NSvFlags 256 {{67, 229}, {38, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 719 NSControlView CF$UID 784 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 31 NSCell CF$UID 789 NSEnabled NSFrame CF$UID 788 NSNextResponder CF$UID 753 NSSuperview CF$UID 753 NSvFlags 256 {{14, 187}, {48, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 555 NSControlView CF$UID 787 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 31 NSCell CF$UID 792 NSEnabled NSFrame CF$UID 791 NSNextResponder CF$UID 753 NSSuperview CF$UID 753 NSvFlags 256 {{67, 189}, {38, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 726 NSControlView CF$UID 790 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 31 NSCell CF$UID 795 NSEnabled NSFrame CF$UID 794 NSNextResponder CF$UID 753 NSSuperview CF$UID 753 NSvFlags 256 {{66, 39}, {114, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 419 NSControlView CF$UID 793 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 31 NSCell CF$UID 798 NSEnabled NSFrame CF$UID 797 NSNextResponder CF$UID 753 NSSuperview CF$UID 753 NSvFlags 256 {{101, 130}, {139, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 733 NSControlView CF$UID 796 NSSupport CF$UID 19 NSTextColor CF$UID 27 $class CF$UID 31 NSCell CF$UID 801 NSEnabled NSFrame CF$UID 800 NSNextResponder CF$UID 753 NSSuperview CF$UID 753 NSvFlags 256 {{14, 128}, {82, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 802 NSControlView CF$UID 799 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 20000 $class CF$UID 31 NSCell CF$UID 805 NSEnabled NSFrame CF$UID 804 NSNextResponder CF$UID 753 NSSuperview CF$UID 753 NSvFlags 256 {{14, 88}, {61, 22}} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags -1804468671 NSCellFlags2 71304192 NSContents CF$UID 741 NSControlView CF$UID 803 NSDrawsBackground NSSupport CF$UID 19 NSTextColor CF$UID 47 $class CF$UID 31 NSCell CF$UID 808 NSEnabled NSFrame CF$UID 807 NSNextResponder CF$UID 753 NSSuperview CF$UID 753 NSvFlags 256 {{80, 90}, {67, 17}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 745 NSControlView CF$UID 806 NSSupport CF$UID 19 NSTextColor CF$UID 27 {{2, 2}, {244, 302}} {{288, 72}, {248, 322}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 450 NSSupport CF$UID 19 NSTextColor CF$UID 813 $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== {{10, 33}, {556, 401}} SOMs $class CF$UID 227 NSColor CF$UID 22 NSIdentifier CF$UID 817 NSLabel CF$UID 862 NSTabView CF$UID 66 NSView CF$UID 818 $class CF$UID 4 NS.string 2 $class CF$UID 214 NSFrame CF$UID 861 NSNextResponder CF$UID 0 NSSubviews CF$UID 819 $class CF$UID 212 NS.objects CF$UID 820 CF$UID 829 CF$UID 833 CF$UID 848 $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 822 NSFrame CF$UID 824 NSNextResponder CF$UID 818 NSOffsets CF$UID 825 NSSubviews CF$UID 821 NSSuperview CF$UID 818 NSTitleCell CF$UID 826 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 822 $class CF$UID 214 NSFrame CF$UID 823 NSNextResponder CF$UID 820 NSSuperview CF$UID 820 {{2, 2}, {512, 300}} {{25, 58}, {516, 320}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 827 NSSupport CF$UID 19 NSTextColor CF$UID 828 Principal Component Analysis $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== $class CF$UID 82 NSCell CF$UID 831 NSEnabled NSFrame CF$UID 830 NSNextResponder CF$UID 818 NSSuperview CF$UID 818 NSvFlags 256 {{238, 79}, {90, 32}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 99 NSButtonFlags -2038284033 NSButtonFlags2 1 NSCellFlags 67239424 NSCellFlags2 137887744 NSContents CF$UID 671 NSControlView CF$UID 829 NSKeyEquivalent CF$UID 832 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 $class CF$UID 4 NS.string $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 835 NSFrame CF$UID 844 NSNextResponder CF$UID 818 NSOffsets CF$UID 845 NSSubviews CF$UID 834 NSSuperview CF$UID 818 NSTitleCell CF$UID 846 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 835 $class CF$UID 214 NSFrame CF$UID 843 NSNextResponder CF$UID 833 NSSubviews CF$UID 836 NSSuperview CF$UID 833 $class CF$UID 212 NS.objects CF$UID 837 $class CF$UID 82 NSCell CF$UID 839 NSEnabled NSFrame CF$UID 838 NSNextResponder CF$UID 835 NSSuperview CF$UID 835 NSvFlags 256 {{14, 165}, {146, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 840 NSControlView CF$UID 837 NSKeyEquivalent CF$UID 43 NSNormalImage CF$UID 841 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Apply PCA to genes $class CF$UID 377 NSClassName CF$UID 375 NSResourceName CF$UID 842 NSSwitch {{2, 2}, {213, 192}} {{46, 136}, {217, 212}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 513 NSSupport CF$UID 19 NSTextColor CF$UID 847 $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== $class CF$UID 220 NSBorderType 3 NSBoxType 0 NSContentView CF$UID 850 NSFrame CF$UID 857 NSNextResponder CF$UID 818 NSOffsets CF$UID 858 NSSubviews CF$UID 849 NSSuperview CF$UID 818 NSTitleCell CF$UID 859 NSTitlePosition 2 NSTransparent $class CF$UID 212 NS.objects CF$UID 850 $class CF$UID 214 NSFrame CF$UID 856 NSNextResponder CF$UID 848 NSSubviews CF$UID 851 NSSuperview CF$UID 848 $class CF$UID 212 NS.objects CF$UID 852 $class CF$UID 82 NSCell CF$UID 854 NSEnabled NSFrame CF$UID 853 NSNextResponder CF$UID 850 NSSuperview CF$UID 850 NSvFlags 256 {{14, 165}, {147, 18}} $class CF$UID 81 NSAlternateContents CF$UID 43 NSAlternateImage CF$UID 78 NSButtonFlags 1211912703 NSButtonFlags2 2 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 855 NSControlView CF$UID 852 NSKeyEquivalent CF$UID 43 NSPeriodicDelay 200 NSPeriodicInterval 25 NSSupport CF$UID 19 Apply PCA to arrays {{2, 2}, {213, 192}} {{304, 136}, {217, 212}} {0, 0} $class CF$UID 30 NSBackgroundColor CF$UID 44 NSCellFlags 67239424 NSCellFlags2 0 NSContents CF$UID 450 NSSupport CF$UID 19 NSTextColor CF$UID 860 $class CF$UID 26 NSColorSpace 3 NSWhite MCAwLjgwMDAwMDAxAA== {{10, 33}, {556, 401}} PCA $classes NSTabView NSView NSResponder NSObject $classname NSTabView $class CF$UID 31 NSCell CF$UID 866 NSEnabled NSFrame CF$UID 865 NSNextResponder CF$UID 13 NSSuperview CF$UID 13 NSvFlags 256 {{17, 0}, {562, 14}} $class CF$UID 30 NSBackgroundColor CF$UID 22 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 43 NSControlView CF$UID 864 NSSupport CF$UID 339 NSTextColor CF$UID 27 {{1, 9}, {596, 637}} {{0, 0}, {1440, 878}} {213, 129} {3.40282e+38, 3.40282e+38} $classes NSWindowTemplate NSObject $classname NSWindowTemplate $classes NSMutableSet NSSet NSObject $classname NSMutableSet $class CF$UID 212 NS.objects CF$UID 874 CF$UID 881 CF$UID 885 CF$UID 891 CF$UID 895 CF$UID 900 CF$UID 904 CF$UID 908 CF$UID 916 CF$UID 921 CF$UID 924 CF$UID 926 CF$UID 927 CF$UID 928 CF$UID 930 CF$UID 932 CF$UID 934 CF$UID 936 CF$UID 938 CF$UID 940 CF$UID 942 CF$UID 944 CF$UID 946 CF$UID 948 CF$UID 950 CF$UID 952 CF$UID 954 CF$UID 956 CF$UID 958 CF$UID 960 CF$UID 962 CF$UID 964 CF$UID 966 CF$UID 968 CF$UID 970 CF$UID 972 CF$UID 974 CF$UID 976 CF$UID 978 CF$UID 980 CF$UID 982 CF$UID 984 CF$UID 986 CF$UID 988 CF$UID 990 CF$UID 992 CF$UID 994 CF$UID 996 CF$UID 998 CF$UID 1000 CF$UID 1002 CF$UID 1004 CF$UID 1006 CF$UID 1008 CF$UID 1010 CF$UID 1012 CF$UID 1014 CF$UID 1016 CF$UID 1018 CF$UID 1020 CF$UID 1022 CF$UID 1024 CF$UID 1026 CF$UID 1028 CF$UID 1030 CF$UID 1032 CF$UID 1034 CF$UID 1036 CF$UID 1038 CF$UID 1040 CF$UID 1042 CF$UID 1044 CF$UID 1046 CF$UID 1048 CF$UID 1050 CF$UID 1056 CF$UID 1060 CF$UID 1065 CF$UID 1070 CF$UID 1075 CF$UID 1077 CF$UID 1079 CF$UID 1081 CF$UID 1083 CF$UID 1085 CF$UID 1087 CF$UID 1089 CF$UID 1091 CF$UID 1093 CF$UID 1095 CF$UID 1097 CF$UID 1099 $class CF$UID 880 NSLabel CF$UID 879 NSSource CF$UID 875 $class CF$UID 381 NSKeyEquiv CF$UID 878 NSKeyEquivModMask 1048576 NSMenu CF$UID 876 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 877 $class CF$UID 405 NSMenuItems CF$UID 1107 NSName CF$UID 1109 NSTitle CF$UID 1106 Minimize m $class CF$UID 4 NS.string performMiniaturize: $classes NSNibControlConnector NSNibConnector NSObject $classname NSNibControlConnector $class CF$UID 880 NSLabel CF$UID 884 NSSource CF$UID 882 $class CF$UID 381 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 876 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 883 Bring All to Front $class CF$UID 4 NS.string arrangeInFront: $class CF$UID 880 NSDestination CF$UID 2 NSLabel CF$UID 890 NSSource CF$UID 886 $class CF$UID 381 NSKeyEquiv CF$UID 889 NSKeyEquivModMask 1048576 NSMenu CF$UID 887 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 888 $class CF$UID 405 NSMenuItems CF$UID 1110 NSName CF$UID 1121 NSTitle CF$UID 411 Quit Cluster q $class CF$UID 4 NS.string terminate: $class CF$UID 880 NSDestination CF$UID 2 NSLabel CF$UID 894 NSSource CF$UID 892 $class CF$UID 381 NSKeyEquiv CF$UID 43 NSMenu CF$UID 887 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 893 About Cluster 3.0 $class CF$UID 4 NS.string orderFrontStandardAboutPanel: $class CF$UID 880 NSDestination CF$UID 2 NSLabel CF$UID 899 NSSource CF$UID 896 $class CF$UID 381 NSKeyEquiv CF$UID 898 NSKeyEquivModMask 1572864 NSMenu CF$UID 887 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 897 Hide Others h hideOtherApplications: $class CF$UID 880 NSDestination CF$UID 2 NSLabel CF$UID 903 NSSource CF$UID 901 $class CF$UID 381 NSKeyEquiv CF$UID 898 NSKeyEquivModMask 1048576 NSMenu CF$UID 887 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 902 Hide Cluster hide: $class CF$UID 880 NSDestination CF$UID 2 NSLabel CF$UID 907 NSSource CF$UID 905 $class CF$UID 381 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 887 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 906 Show All unhideAllApplications: $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 915 NSSource CF$UID 909 $class CF$UID 381 NSKeyEquiv CF$UID 912 NSKeyEquivModMask 1048576 NSMenu CF$UID 910 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 911 $class CF$UID 405 NSMenuItems CF$UID 1135 NSTitle CF$UID 1134 Open Data o $class CF$UID 5 NSClassName CF$UID 914 Controller FileOpen: $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 920 NSSource CF$UID 917 $class CF$UID 381 NSKeyEquiv CF$UID 919 NSKeyEquivModMask 1048576 NSMenu CF$UID 910 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 918 Save Data s FileSave: $class CF$UID 923 NSDestination CF$UID 864 NSLabel CF$UID 922 NSSource CF$UID 913 statusbar $classes NSNibOutletConnector NSNibConnector NSObject $classname NSNibOutletConnector $class CF$UID 923 NSDestination CF$UID 40 NSLabel CF$UID 925 NSSource CF$UID 913 FileMemo $class CF$UID 923 NSDestination CF$UID 60 NSLabel CF$UID 55 NSSource CF$UID 913 $class CF$UID 923 NSDestination CF$UID 63 NSLabel CF$UID 59 NSSource CF$UID 913 $class CF$UID 923 NSDestination CF$UID 108 NSLabel CF$UID 929 NSSource CF$UID 913 filterresult $class CF$UID 923 NSDestination CF$UID 103 NSLabel CF$UID 931 NSSource CF$UID 913 filteraccept $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 933 NSSource CF$UID 95 FilterApply: $class CF$UID 923 NSDestination CF$UID 111 NSLabel CF$UID 935 NSSource CF$UID 913 FilterPercent $class CF$UID 923 NSDestination CF$UID 198 NSLabel CF$UID 937 NSSource CF$UID 913 FilterStd $class CF$UID 923 NSDestination CF$UID 151 NSLabel CF$UID 939 NSSource CF$UID 913 FilterNumber $class CF$UID 923 NSDestination CF$UID 186 NSLabel CF$UID 941 NSSource CF$UID 913 FilterObservationValue $class CF$UID 923 NSDestination CF$UID 172 NSLabel CF$UID 943 NSSource CF$UID 913 FilterMaxMin $class CF$UID 923 NSDestination CF$UID 83 NSLabel CF$UID 945 NSSource CF$UID 913 FilterStdXB $class CF$UID 923 NSDestination CF$UID 87 NSLabel CF$UID 947 NSSource CF$UID 913 FilterObservationXB $class CF$UID 923 NSDestination CF$UID 91 NSLabel CF$UID 949 NSSource CF$UID 913 FilterMaxMinXB $class CF$UID 923 NSDestination CF$UID 74 NSLabel CF$UID 951 NSSource CF$UID 913 FilterPercentXB $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 953 NSSource CF$UID 103 FilterAccept: $class CF$UID 923 NSDestination CF$UID 236 NSLabel CF$UID 955 NSSource CF$UID 913 AdjustLogXB $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 957 NSSource CF$UID 259 AdjustApply: $class CF$UID 923 NSDestination CF$UID 548 NSLabel CF$UID 959 NSSource CF$UID 913 KMeansGeneXB $class CF$UID 923 NSDestination CF$UID 552 NSLabel CF$UID 961 NSSource CF$UID 913 KMeansGeneK $class CF$UID 923 NSDestination CF$UID 560 NSLabel CF$UID 963 NSSource CF$UID 913 KMeansGeneRuns $class CF$UID 923 NSDestination CF$UID 578 NSLabel CF$UID 965 NSSource CF$UID 913 KMeansGeneMean $class CF$UID 923 NSDestination CF$UID 525 NSLabel CF$UID 967 NSSource CF$UID 913 KMeansGeneMetric $class CF$UID 923 NSDestination CF$UID 625 NSLabel CF$UID 969 NSSource CF$UID 913 KMeansArrayXB $class CF$UID 923 NSDestination CF$UID 629 NSLabel CF$UID 971 NSSource CF$UID 913 KMeansArrayK $class CF$UID 923 NSDestination CF$UID 651 NSLabel CF$UID 973 NSSource CF$UID 913 KMeansArrayMean $class CF$UID 923 NSDestination CF$UID 602 NSLabel CF$UID 975 NSSource CF$UID 913 KMeansArrayMetric $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 977 NSSource CF$UID 668 KMeansExecute: $class CF$UID 923 NSDestination CF$UID 49 NSLabel CF$UID 979 NSSource CF$UID 913 JobName $class CF$UID 923 NSDestination CF$UID 635 NSLabel CF$UID 981 NSSource CF$UID 913 KMeansArrayRuns $class CF$UID 923 NSDestination CF$UID 710 NSLabel CF$UID 983 NSSource CF$UID 913 SOMGeneXB $class CF$UID 923 NSDestination CF$UID 713 NSLabel CF$UID 985 NSSource CF$UID 913 SOMGeneXDim $class CF$UID 923 NSDestination CF$UID 720 NSLabel CF$UID 987 NSSource CF$UID 913 SOMGeneYDim $class CF$UID 923 NSDestination CF$UID 734 NSLabel CF$UID 989 NSSource CF$UID 913 SOMGeneIters $class CF$UID 923 NSDestination CF$UID 738 NSLabel CF$UID 991 NSSource CF$UID 913 SOMGeneTau $class CF$UID 923 NSDestination CF$UID 687 NSLabel CF$UID 993 NSSource CF$UID 913 SOMGeneMetric $class CF$UID 923 NSDestination CF$UID 778 NSLabel CF$UID 995 NSSource CF$UID 913 SOMArrayXB $class CF$UID 923 NSDestination CF$UID 781 NSLabel CF$UID 997 NSSource CF$UID 913 SOMArrayXDim $class CF$UID 923 NSDestination CF$UID 787 NSLabel CF$UID 999 NSSource CF$UID 913 SOMArrayYDim $class CF$UID 923 NSDestination CF$UID 799 NSLabel CF$UID 1001 NSSource CF$UID 913 SOMArrayIters $class CF$UID 923 NSDestination CF$UID 803 NSLabel CF$UID 1003 NSSource CF$UID 913 SOMArrayTau $class CF$UID 923 NSDestination CF$UID 755 NSLabel CF$UID 1005 NSSource CF$UID 913 SOMArrayMetric $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1007 NSSource CF$UID 678 SOMExecute: $class CF$UID 923 NSDestination CF$UID 412 NSLabel CF$UID 1009 NSSource CF$UID 913 HierarchicalArrayWeightXB $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1011 NSSource CF$UID 412 HierarchicalArrayWeightXBChanged: $class CF$UID 923 NSDestination CF$UID 363 NSLabel CF$UID 1013 NSSource CF$UID 913 HierarchicalArrays $class CF$UID 923 NSDestination CF$UID 420 NSLabel CF$UID 1015 NSSource CF$UID 913 HierarchicalArrayWeight $class CF$UID 923 NSDestination CF$UID 456 NSLabel CF$UID 1017 NSSource CF$UID 913 HierarchicalGeneWeight $class CF$UID 923 NSDestination CF$UID 503 NSLabel CF$UID 1019 NSSource CF$UID 913 HierarchicalGeneWeightXB $class CF$UID 923 NSDestination CF$UID 452 NSLabel CF$UID 1021 NSSource CF$UID 913 HierarchicalGenes $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1023 NSSource CF$UID 503 HierarchicalGeneWeightXBChanged: $class CF$UID 923 NSDestination CF$UID 913 NSLabel CF$UID 1025 NSSource CF$UID 2 delegate $class CF$UID 923 NSDestination CF$UID 500 NSLabel CF$UID 1027 NSSource CF$UID 913 HierarchicalGeneXB $class CF$UID 923 NSDestination CF$UID 463 NSLabel CF$UID 1029 NSSource CF$UID 913 HierarchicalGeneCutoff $class CF$UID 923 NSDestination CF$UID 469 NSLabel CF$UID 1031 NSSource CF$UID 913 HierarchicalGeneExp $class CF$UID 923 NSDestination CF$UID 477 NSLabel CF$UID 1033 NSSource CF$UID 913 HierarchicalGeneMetric $class CF$UID 923 NSDestination CF$UID 408 NSLabel CF$UID 1035 NSSource CF$UID 913 HierarchicalArrayXB $class CF$UID 923 NSDestination CF$UID 428 NSLabel CF$UID 1037 NSSource CF$UID 913 HierarchicalArrayCutoff $class CF$UID 923 NSDestination CF$UID 436 NSLabel CF$UID 1039 NSSource CF$UID 913 HierarchicalArrayExp $class CF$UID 923 NSDestination CF$UID 367 NSLabel CF$UID 1041 NSSource CF$UID 913 HierarchicalArrayMetric $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1043 NSSource CF$UID 335 HierarchicalCentroid: $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1045 NSSource CF$UID 342 HierarchicalSingle: $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1047 NSSource CF$UID 352 HierarchicalAverage: $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1049 NSSource CF$UID 347 HierarchicalComplete: $class CF$UID 880 NSLabel CF$UID 1055 NSSource CF$UID 1051 $class CF$UID 381 NSKeyEquiv CF$UID 1054 NSKeyEquivModMask 1048576 NSMenu CF$UID 1052 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 1053 $class CF$UID 405 NSMenuItems CF$UID 1125 NSTitle CF$UID 1123 Cluster 3.0 Help ? showHelp: $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1059 NSSource CF$UID 1057 $class CF$UID 381 NSKeyEquiv CF$UID 878 NSKeyEquivModMask 1048576 NSMenu CF$UID 1052 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 1058 Read local manual ShowHelpManual: $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1064 NSSource CF$UID 1061 $class CF$UID 381 NSKeyEquiv CF$UID 1063 NSKeyEquivModMask 1048576 NSMenu CF$UID 1052 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 1062 Read online manual O ShowHelpDownload: $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1069 NSSource CF$UID 1066 $class CF$UID 381 NSKeyEquiv CF$UID 1068 NSKeyEquivModMask 1048576 NSMenu CF$UID 1052 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 1067 File format help f ShowFileFormatPanel: $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1074 NSSource CF$UID 1071 $class CF$UID 381 NSKeyEquiv CF$UID 1073 NSKeyEquivModMask 1048576 NSMenu CF$UID 1052 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 1072 About... a ShowAboutPanel: $class CF$UID 923 NSDestination CF$UID 276 NSLabel CF$UID 1076 NSSource CF$UID 913 AdjustMeanGenes $class CF$UID 923 NSDestination CF$UID 281 NSLabel CF$UID 1078 NSSource CF$UID 913 AdjustMedianGenes $class CF$UID 923 NSDestination CF$UID 309 NSLabel CF$UID 1080 NSSource CF$UID 913 AdjustMeanArrays $class CF$UID 923 NSDestination CF$UID 311 NSLabel CF$UID 1082 NSSource CF$UID 913 AdjustMedianArrays $class CF$UID 923 NSDestination CF$UID 289 NSLabel CF$UID 1084 NSSource CF$UID 913 AdjustNormalizeGenes $class CF$UID 923 NSDestination CF$UID 316 NSLabel CF$UID 1086 NSSource CF$UID 913 AdjustNormalizeArrays $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1088 NSSource CF$UID 269 AdjustCenterGenesXBChanged: $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1090 NSSource CF$UID 302 AdjustCenterArraysXBChanged: $class CF$UID 923 NSDestination CF$UID 269 NSLabel CF$UID 1092 NSSource CF$UID 913 AdjustCenterGenesXB $class CF$UID 923 NSDestination CF$UID 302 NSLabel CF$UID 1094 NSSource CF$UID 913 AdjustCenterArraysXB $class CF$UID 923 NSDestination CF$UID 852 NSLabel CF$UID 1096 NSSource CF$UID 913 PCAArrayXB $class CF$UID 923 NSDestination CF$UID 837 NSLabel CF$UID 1098 NSSource CF$UID 913 PCAGeneXB $class CF$UID 880 NSDestination CF$UID 913 NSLabel CF$UID 1100 NSSource CF$UID 829 PCAExecute: $class CF$UID 1137 NS.objects CF$UID 837 CF$UID 198 CF$UID 708 CF$UID 111 CF$UID 56 CF$UID 768 CF$UID 202 CF$UID 787 CF$UID 619 CF$UID 653 CF$UID 611 CF$UID 917 CF$UID 452 CF$UID 552 CF$UID 1071 CF$UID 685 CF$UID 168 CF$UID 517 CF$UID 886 CF$UID 248 CF$UID 727 CF$UID 68 CF$UID 770 CF$UID 503 CF$UID 1102 CF$UID 621 CF$UID 571 CF$UID 477 CF$UID 416 CF$UID 806 CF$UID 298 CF$UID 352 CF$UID 269 CF$UID 820 CF$UID 333 CF$UID 91 CF$UID 887 CF$UID 772 CF$UID 623 CF$UID 892 CF$UID 764 CF$UID 36 CF$UID 384 CF$UID 316 CF$UID 436 CF$UID 600 CF$UID 687 CF$UID 172 CF$UID 774 CF$UID 1111 CF$UID 250 CF$UID 70 CF$UID 460 CF$UID 790 CF$UID 778 CF$UID 393 CF$UID 529 CF$UID 776 CF$UID 573 CF$UID 713 CF$UID 186 CF$UID 913 CF$UID 1112 CF$UID 556 CF$UID 300 CF$UID 420 CF$UID 506 CF$UID 730 CF$UID 396 CF$UID 530 CF$UID 602 CF$UID 8 CF$UID 1115 CF$UID 60 CF$UID 644 CF$UID 816 CF$UID 481 CF$UID 176 CF$UID 224 CF$UID 95 CF$UID 710 CF$UID 399 CF$UID 822 CF$UID 629 CF$UID 273 CF$UID 40 CF$UID 72 CF$UID 575 CF$UID 753 CF$UID 829 CF$UID 482 CF$UID 363 CF$UID 302 CF$UID 63 CF$UID 402 CF$UID 232 CF$UID 422 CF$UID 848 CF$UID 486 CF$UID 463 CF$UID 691 CF$UID 329 CF$UID 793 CF$UID 13 CF$UID 1119 CF$UID 716 CF$UID 560 CF$UID 646 CF$UID 74 CF$UID 488 CF$UID 692 CF$UID 755 CF$UID 734 CF$UID 678 CF$UID 1122 CF$UID 534 CF$UID 309 CF$UID 365 CF$UID 281 CF$UID 1103 CF$UID 276 CF$UID 864 CF$UID 490 CF$UID 901 CF$UID 674 CF$UID 424 CF$UID 234 CF$UID 632 CF$UID 536 CF$UID 151 CF$UID 342 CF$UID 49 CF$UID 896 CF$UID 190 CF$UID 625 CF$UID 116 CF$UID 751 CF$UID 850 CF$UID 103 CF$UID 492 CF$UID 1129 CF$UID 676 CF$UID 259 CF$UID 306 CF$UID 525 CF$UID 538 CF$UID 781 CF$UID 668 CF$UID 66 CF$UID 905 CF$UID 1131 CF$UID 311 CF$UID 15 CF$UID 466 CF$UID 606 CF$UID 387 CF$UID 367 CF$UID 494 CF$UID 519 CF$UID 228 CF$UID 540 CF$UID 720 CF$UID 454 CF$UID 564 CF$UID 578 CF$UID 236 CF$UID 799 CF$UID 607 CF$UID 83 CF$UID 696 CF$UID 390 CF$UID 496 CF$UID 910 CF$UID 852 CF$UID 738 CF$UID 641 CF$UID 542 CF$UID 1120 CF$UID 833 CF$UID 759 CF$UID 698 CF$UID 498 CF$UID 648 CF$UID 521 CF$UID 428 CF$UID 635 CF$UID 408 CF$UID 544 CF$UID 1051 CF$UID 327 CF$UID 1108 CF$UID 581 CF$UID 456 CF$UID 875 CF$UID 760 CF$UID 700 CF$UID 1052 CF$UID 335 CF$UID 796 CF$UID 108 CF$UID 784 CF$UID 876 CF$UID 52 CF$UID 546 CF$UID 289 CF$UID 882 CF$UID 246 CF$UID 818 CF$UID 265 CF$UID 469 CF$UID 702 CF$UID 1057 CF$UID 500 CF$UID 723 CF$UID 613 CF$UID 412 CF$UID 568 CF$UID 347 CF$UID 835 CF$UID 1061 CF$UID 155 CF$UID 371 CF$UID 803 CF$UID 683 CF$UID 742 CF$UID 87 CF$UID 523 CF$UID 704 CF$UID 615 CF$UID 651 CF$UID 548 CF$UID 458 CF$UID 32 CF$UID 909 CF$UID 598 CF$UID 1066 CF$UID 230 CF$UID 372 CF$UID 706 CF$UID 432 CF$UID 638 CF$UID 766 CF$UID 617 CF$UID 331 CF$UID 267 CF$UID 1126 $class CF$UID 381 NSAction CF$UID 1105 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 1103 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSSubmenu CF$UID 876 NSTitle CF$UID 1104 $class CF$UID 405 NSMenuItems CF$UID 1128 NSName CF$UID 1136 NSTitle CF$UID 1127 Window submenuAction: $class CF$UID 4 NS.string Window $class CF$UID 212 NS.objects CF$UID 875 CF$UID 1108 CF$UID 882 $class CF$UID 381 NSIsDisabled NSIsSeparator NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 876 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 43 _NSWindowsMenu $class CF$UID 212 NS.objects CF$UID 892 CF$UID 1111 CF$UID 1112 CF$UID 1119 CF$UID 901 CF$UID 896 CF$UID 905 CF$UID 1120 CF$UID 886 $class CF$UID 381 NSIsDisabled NSIsSeparator NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 887 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 43 $class CF$UID 381 NSAction CF$UID 1114 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 887 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSSubmenu CF$UID 1115 NSTitle CF$UID 1113 Services submenuAction: $class CF$UID 405 NSMenuItems CF$UID 1117 NSName CF$UID 1118 NSTitle CF$UID 1116 $class CF$UID 4 NS.string Services $class CF$UID 212 NS.objects _NSServicesMenu $class CF$UID 381 NSIsDisabled NSIsSeparator NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 887 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 43 $class CF$UID 381 NSIsDisabled NSIsSeparator NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 887 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 43 _NSAppleMenu $class CF$UID 381 NSAction CF$UID 1124 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 1103 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSSubmenu CF$UID 1052 NSTitle CF$UID 1123 Help submenuAction: $class CF$UID 212 NS.objects CF$UID 1051 CF$UID 1057 CF$UID 1061 CF$UID 1066 CF$UID 1126 CF$UID 1071 $class CF$UID 381 NSIsDisabled NSIsSeparator NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 1052 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSTitle CF$UID 43 MainMenu $class CF$UID 212 NS.objects CF$UID 1129 CF$UID 1131 CF$UID 1102 CF$UID 1122 $class CF$UID 381 NSAction CF$UID 1130 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 1103 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSSubmenu CF$UID 887 NSTitle CF$UID 411 submenuAction: $class CF$UID 381 NSAction CF$UID 1133 NSKeyEquiv CF$UID 43 NSKeyEquivModMask 1048576 NSMenu CF$UID 1103 NSMixedImage CF$UID 378 NSMnemonicLoc 2147483647 NSOnImage CF$UID 374 NSSubmenu CF$UID 910 NSTitle CF$UID 1132 File submenuAction: $class CF$UID 4 NS.string File $class CF$UID 212 NS.objects CF$UID 909 CF$UID 917 _NSMainMenu $classes NSArray NSObject $classname NSArray $class CF$UID 1137 NS.objects CF$UID 835 CF$UID 72 CF$UID 692 CF$UID 72 CF$UID 13 CF$UID 760 CF$UID 198 CF$UID 753 CF$UID 607 CF$UID 648 CF$UID 607 CF$UID 910 CF$UID 329 CF$UID 523 CF$UID 1052 CF$UID 683 CF$UID 72 CF$UID 66 CF$UID 887 CF$UID 246 CF$UID 685 CF$UID 224 CF$UID 760 CF$UID 454 CF$UID 1103 CF$UID 607 CF$UID 523 CF$UID 454 CF$UID 365 CF$UID 753 CF$UID 230 CF$UID 333 CF$UID 267 CF$UID 818 CF$UID 331 CF$UID 72 CF$UID 1129 CF$UID 760 CF$UID 607 CF$UID 887 CF$UID 760 CF$UID 13 CF$UID 372 CF$UID 300 CF$UID 422 CF$UID 598 CF$UID 685 CF$UID 72 CF$UID 760 CF$UID 887 CF$UID 248 CF$UID 68 CF$UID 458 CF$UID 753 CF$UID 753 CF$UID 372 CF$UID 530 CF$UID 760 CF$UID 571 CF$UID 685 CF$UID 72 CF$UID 2 CF$UID 887 CF$UID 523 CF$UID 298 CF$UID 365 CF$UID 454 CF$UID 685 CF$UID 372 CF$UID 525 CF$UID 600 CF$UID 2 CF$UID 1112 CF$UID 13 CF$UID 600 CF$UID 66 CF$UID 482 CF$UID 172 CF$UID 66 CF$UID 72 CF$UID 685 CF$UID 372 CF$UID 820 CF$UID 600 CF$UID 267 CF$UID 13 CF$UID 70 CF$UID 573 CF$UID 751 CF$UID 818 CF$UID 477 CF$UID 329 CF$UID 300 CF$UID 13 CF$UID 372 CF$UID 230 CF$UID 420 CF$UID 818 CF$UID 482 CF$UID 458 CF$UID 692 CF$UID 327 CF$UID 753 CF$UID 8 CF$UID 887 CF$UID 685 CF$UID 523 CF$UID 644 CF$UID 72 CF$UID 482 CF$UID 687 CF$UID 753 CF$UID 685 CF$UID 676 CF$UID 1103 CF$UID 530 CF$UID 306 CF$UID 363 CF$UID 273 CF$UID 2 CF$UID 273 CF$UID 13 CF$UID 482 CF$UID 887 CF$UID 66 CF$UID 422 CF$UID 232 CF$UID 600 CF$UID 530 CF$UID 72 CF$UID 333 CF$UID 13 CF$UID 887 CF$UID 186 CF$UID 600 CF$UID 111 CF$UID 676 CF$UID 848 CF$UID 72 CF$UID 482 CF$UID 1103 CF$UID 674 CF$UID 230 CF$UID 300 CF$UID 523 CF$UID 530 CF$UID 753 CF$UID 519 CF$UID 13 CF$UID 887 CF$UID 1103 CF$UID 306 CF$UID 13 CF$UID 458 CF$UID 607 CF$UID 372 CF$UID 365 CF$UID 482 CF$UID 517 CF$UID 66 CF$UID 530 CF$UID 685 CF$UID 452 CF$UID 523 CF$UID 575 CF$UID 234 CF$UID 753 CF$UID 602 CF$UID 72 CF$UID 692 CF$UID 372 CF$UID 482 CF$UID 1131 CF$UID 850 CF$UID 685 CF$UID 600 CF$UID 530 CF$UID 887 CF$UID 818 CF$UID 760 CF$UID 692 CF$UID 482 CF$UID 646 CF$UID 519 CF$UID 422 CF$UID 600 CF$UID 365 CF$UID 530 CF$UID 1052 CF$UID 66 CF$UID 876 CF$UID 575 CF$UID 454 CF$UID 876 CF$UID 755 CF$UID 692 CF$UID 1122 CF$UID 333 CF$UID 753 CF$UID 72 CF$UID 753 CF$UID 1102 CF$UID 13 CF$UID 530 CF$UID 267 CF$UID 876 CF$UID 230 CF$UID 816 CF$UID 230 CF$UID 458 CF$UID 692 CF$UID 1052 CF$UID 454 CF$UID 685 CF$UID 607 CF$UID 365 CF$UID 523 CF$UID 333 CF$UID 833 CF$UID 1052 CF$UID 151 CF$UID 372 CF$UID 753 CF$UID 676 CF$UID 685 CF$UID 72 CF$UID 521 CF$UID 692 CF$UID 607 CF$UID 648 CF$UID 523 CF$UID 456 CF$UID 13 CF$UID 910 CF$UID 519 CF$UID 1052 CF$UID 228 CF$UID 367 CF$UID 692 CF$UID 422 CF$UID 600 CF$UID 760 CF$UID 607 CF$UID 329 CF$UID 265 CF$UID 1052 $class CF$UID 1137 NS.objects CF$UID 837 CF$UID 198 CF$UID 708 CF$UID 111 CF$UID 56 CF$UID 768 CF$UID 787 CF$UID 619 CF$UID 653 CF$UID 611 CF$UID 917 CF$UID 452 CF$UID 552 CF$UID 685 CF$UID 168 CF$UID 517 CF$UID 886 CF$UID 248 CF$UID 727 CF$UID 68 CF$UID 770 CF$UID 503 CF$UID 621 CF$UID 416 CF$UID 571 CF$UID 477 CF$UID 806 CF$UID 298 CF$UID 352 CF$UID 269 CF$UID 820 CF$UID 333 CF$UID 91 CF$UID 772 CF$UID 623 CF$UID 764 CF$UID 36 CF$UID 384 CF$UID 316 CF$UID 436 CF$UID 600 CF$UID 687 CF$UID 774 CF$UID 172 CF$UID 250 CF$UID 70 CF$UID 460 CF$UID 790 CF$UID 393 CF$UID 778 CF$UID 529 CF$UID 776 CF$UID 573 CF$UID 2 CF$UID 186 CF$UID 913 CF$UID 713 CF$UID 556 CF$UID 300 CF$UID 420 CF$UID 506 CF$UID 730 CF$UID 396 CF$UID 530 CF$UID 602 CF$UID 8 CF$UID 60 CF$UID 644 CF$UID 816 CF$UID 481 CF$UID 224 CF$UID 95 CF$UID 710 CF$UID 399 CF$UID 822 CF$UID 629 CF$UID 273 CF$UID 40 CF$UID 72 CF$UID 575 CF$UID 753 CF$UID 829 CF$UID 482 CF$UID 363 CF$UID 302 CF$UID 63 CF$UID 402 CF$UID 232 CF$UID 422 CF$UID 848 CF$UID 486 CF$UID 463 CF$UID 691 CF$UID 329 CF$UID 793 CF$UID 716 CF$UID 560 CF$UID 646 CF$UID 74 CF$UID 488 CF$UID 692 CF$UID 755 CF$UID 734 CF$UID 678 CF$UID 1122 CF$UID 534 CF$UID 309 CF$UID 365 CF$UID 281 CF$UID 1103 CF$UID 276 CF$UID 864 CF$UID 490 CF$UID 674 CF$UID 424 CF$UID 234 CF$UID 632 CF$UID 536 CF$UID 151 CF$UID 342 CF$UID 49 CF$UID 625 CF$UID 751 CF$UID 850 CF$UID 103 CF$UID 492 CF$UID 676 CF$UID 259 CF$UID 306 CF$UID 525 CF$UID 538 CF$UID 781 CF$UID 668 CF$UID 66 CF$UID 1131 CF$UID 311 CF$UID 15 CF$UID 466 CF$UID 606 CF$UID 387 CF$UID 367 CF$UID 494 CF$UID 519 CF$UID 228 CF$UID 540 CF$UID 720 CF$UID 454 CF$UID 564 CF$UID 578 CF$UID 236 CF$UID 799 CF$UID 607 CF$UID 83 CF$UID 696 CF$UID 390 CF$UID 496 CF$UID 910 CF$UID 852 CF$UID 738 CF$UID 641 CF$UID 542 CF$UID 833 CF$UID 759 CF$UID 698 CF$UID 498 CF$UID 648 CF$UID 521 CF$UID 428 CF$UID 635 CF$UID 408 CF$UID 544 CF$UID 1051 CF$UID 327 CF$UID 1108 CF$UID 581 CF$UID 456 CF$UID 760 CF$UID 700 CF$UID 1052 CF$UID 335 CF$UID 796 CF$UID 108 CF$UID 784 CF$UID 52 CF$UID 546 CF$UID 289 CF$UID 246 CF$UID 818 CF$UID 265 CF$UID 469 CF$UID 702 CF$UID 500 CF$UID 723 CF$UID 613 CF$UID 412 CF$UID 568 CF$UID 347 CF$UID 835 CF$UID 371 CF$UID 803 CF$UID 683 CF$UID 742 CF$UID 87 CF$UID 523 CF$UID 704 CF$UID 615 CF$UID 651 CF$UID 548 CF$UID 458 CF$UID 32 CF$UID 909 CF$UID 598 CF$UID 230 CF$UID 372 CF$UID 706 CF$UID 432 CF$UID 638 CF$UID 766 CF$UID 617 CF$UID 331 CF$UID 267 $class CF$UID 1137 NS.objects CF$UID 1141 CF$UID 1142 CF$UID 1143 CF$UID 1144 CF$UID 1145 CF$UID 1146 CF$UID 1147 CF$UID 1148 CF$UID 1149 CF$UID 1150 CF$UID 1151 CF$UID 1152 CF$UID 1144 CF$UID 1153 CF$UID 1154 CF$UID 1155 CF$UID 1156 CF$UID 1153 CF$UID 1157 CF$UID 1153 CF$UID 1158 CF$UID 1159 CF$UID 1160 CF$UID 1161 CF$UID 1162 CF$UID 1163 CF$UID 1164 CF$UID 1165 CF$UID 1166 CF$UID 1141 CF$UID 1162 CF$UID 1153 CF$UID 1167 CF$UID 1148 CF$UID 1143 CF$UID 1150 CF$UID 1157 CF$UID 1168 CF$UID 1159 CF$UID 1169 CF$UID 1153 CF$UID 1163 CF$UID 1160 CF$UID 1170 CF$UID 1161 CF$UID 1162 CF$UID 1161 CF$UID 1154 CF$UID 1148 CF$UID 1141 CF$UID 1171 CF$UID 1143 CF$UID 1153 CF$UID 1172 CF$UID 1173 CF$UID 914 CF$UID 1144 CF$UID 1161 CF$UID 1153 CF$UID 1162 CF$UID 1161 CF$UID 1174 CF$UID 1160 CF$UID 1175 CF$UID 1163 CF$UID 1104 CF$UID 1176 CF$UID 1177 CF$UID 1178 CF$UID 1150 CF$UID 1179 CF$UID 1180 CF$UID 1141 CF$UID 1171 CF$UID 1153 CF$UID 1144 CF$UID 1181 CF$UID 1144 CF$UID 1153 CF$UID 1181 CF$UID 1153 CF$UID 1180 CF$UID 1175 CF$UID 1182 CF$UID 1141 CF$UID 1183 CF$UID 1143 CF$UID 1162 CF$UID 1153 CF$UID 1152 CF$UID 1168 CF$UID 1144 CF$UID 1171 CF$UID 1153 CF$UID 1157 CF$UID 1161 CF$UID 1147 CF$UID 1153 CF$UID 1141 CF$UID 1146 CF$UID 1175 CF$UID 1163 CF$UID 1169 CF$UID 1180 CF$UID 1184 CF$UID 1150 CF$UID 1185 CF$UID 1153 CF$UID 1149 CF$UID 1186 CF$UID 1185 CF$UID 1187 CF$UID 1158 CF$UID 1188 CF$UID 1161 CF$UID 1153 CF$UID 1161 CF$UID 1168 CF$UID 1147 CF$UID 1189 CF$UID 1169 CF$UID 1141 CF$UID 1182 CF$UID 1153 CF$UID 1189 CF$UID 1148 CF$UID 1153 CF$UID 1180 CF$UID 1181 CF$UID 1163 CF$UID 1146 CF$UID 1144 CF$UID 1180 CF$UID 1190 CF$UID 1191 CF$UID 1149 CF$UID 1161 CF$UID 1154 CF$UID 1171 CF$UID 1146 CF$UID 1163 CF$UID 1160 CF$UID 1153 CF$UID 1192 CF$UID 1158 CF$UID 1147 CF$UID 1153 CF$UID 1154 CF$UID 1185 CF$UID 1141 CF$UID 1169 CF$UID 1175 CF$UID 1159 CF$UID 1150 CF$UID 1158 CF$UID 1171 CF$UID 1191 CF$UID 1141 CF$UID 1193 CF$UID 1157 CF$UID 1148 CF$UID 1182 CF$UID 1171 CF$UID 1168 CF$UID 1143 CF$UID 1181 CF$UID 1162 CF$UID 1144 CF$UID 1147 CF$UID 1141 CF$UID 1160 CF$UID 1191 CF$UID 1194 CF$UID 1191 CF$UID 1149 CF$UID 1162 CF$UID 1175 CF$UID 1146 CF$UID 1195 CF$UID 1180 CF$UID 1174 CF$UID 1161 CF$UID 1161 CF$UID 1174 CF$UID 1143 CF$UID 1159 CF$UID 1196 CF$UID 1153 CF$UID 1197 CF$UID 1169 CF$UID 1158 CF$UID 1141 CF$UID 1154 CF$UID 1168 CF$UID 1159 CF$UID 1157 CF$UID 1198 CF$UID 1153 CF$UID 1150 CF$UID 1193 CF$UID 1162 CF$UID 1164 CF$UID 1199 CF$UID 1153 CF$UID 1148 CF$UID 1146 CF$UID 1185 CF$UID 1141 CF$UID 1153 CF$UID 1154 CF$UID 1191 CF$UID 1177 CF$UID 1153 CF$UID 1175 CF$UID 1160 CF$UID 1154 CF$UID 1154 CF$UID 1168 CF$UID 1158 CF$UID 1177 CF$UID 1153 NSButton4 NSTextField111 NSMenuItem211 NSTextField NSTextField24 NSMenuItem11 NSTextField3 NSMenuItem1111 NSButtonCell1 NSMenuItem $class CF$UID 4 NS.string 3 NSBox11 NSView NSTextField21 NSTabViewItem111 1111 NSTextField22 NSMenuItem111 NSButton41 NSMenuItem11111 NSTextField2 NSBox NSPopUpButton NSTextField211 NSBox121 NSButton3 NSButton43 NSMenuItem1 NSTextField1 NSTextField4 NSMenuItem2 $class CF$UID 4 NS.string File's Owner NSTextField5 NSTextField23 PopUpList NSTextField25 NSBox3 NSTabViewItem11111 NSTabViewItem NSButton NSMatrix1 NSBox1 NSTextField26 $class CF$UID 4 NS.string 1 NSButtonCell $class CF$UID 4 NS.string MainMenu NSTextField11 NSTabViewItem1111 NSButton1 NSTabView $class CF$UID 4 NS.string NSTabViewItem1 NSTextField31 NSTabViewItem11 $class CF$UID 4 NS.string 2 NSBox21 NSBox12 NSButton2 NSButton42 $class CF$UID 1137 NS.objects $class CF$UID 1137 NS.objects $class CF$UID 1137 NS.objects CF$UID 727 CF$UID 927 CF$UID 611 CF$UID 806 CF$UID 1120 CF$UID 988 CF$UID 363 CF$UID 91 CF$UID 234 CF$UID 928 CF$UID 573 CF$UID 734 CF$UID 876 CF$UID 646 CF$UID 990 CF$UID 930 CF$UID 529 CF$UID 692 CF$UID 992 CF$UID 742 CF$UID 302 CF$UID 932 CF$UID 1066 CF$UID 613 CF$UID 552 CF$UID 463 CF$UID 994 CF$UID 864 CF$UID 494 CF$UID 934 CF$UID 833 CF$UID 422 CF$UID 996 CF$UID 540 CF$UID 198 CF$UID 469 CF$UID 704 CF$UID 936 CF$UID 560 CF$UID 772 CF$UID 998 CF$UID 72 CF$UID 1056 CF$UID 578 CF$UID 230 CF$UID 568 CF$UID 1000 CF$UID 1060 CF$UID 393 CF$UID 759 CF$UID 32 CF$UID 1002 CF$UID 517 CF$UID 1065 CF$UID 454 CF$UID 103 CF$UID 503 CF$UID 1004 CF$UID 1070 CF$UID 40 CF$UID 228 CF$UID 530 CF$UID 311 CF$UID 850 CF$UID 1006 CF$UID 1075 CF$UID 829 CF$UID 651 CF$UID 1126 CF$UID 615 CF$UID 753 CF$UID 1008 CF$UID 710 CF$UID 387 CF$UID 1077 CF$UID 496 CF$UID 265 CF$UID 523 CF$UID 1010 CF$UID 246 CF$UID 542 CF$UID 416 CF$UID 1079 CF$UID 706 CF$UID 774 CF$UID 1012 CF$UID 111 CF$UID 629 CF$UID 1014 CF$UID 396 CF$UID 760 CF$UID 751 CF$UID 635 CF$UID 1016 CF$UID 687 CF$UID 781 CF$UID 874 CF$UID 371 CF$UID 881 CF$UID 481 CF$UID 1018 CF$UID 66 CF$UID 1093 CF$UID 168 CF$UID 796 CF$UID 248 CF$UID 787 CF$UID 52 CF$UID 1020 CF$UID 625 CF$UID 1095 CF$UID 575 CF$UID 913 CF$UID 1071 CF$UID 600 CF$UID 617 CF$UID 1022 CF$UID 390 CF$UID 1097 CF$UID 236 CF$UID 1119 CF$UID 916 CF$UID 352 CF$UID 793 CF$UID 498 CF$UID 581 CF$UID 365 CF$UID 1024 CF$UID 544 CF$UID 15 CF$UID 708 CF$UID 1099 CF$UID 921 CF$UID 298 CF$UID 776 CF$UID 1026 CF$UID 885 CF$UID 424 CF$UID 668 CF$UID 891 CF$UID 316 CF$UID 1028 CF$UID 399 CF$UID 309 CF$UID 886 CF$UID 1030 CF$UID 74 CF$UID 281 CF$UID 68 CF$UID 432 CF$UID 372 CF$UID 482 CF$UID 1032 CF$UID 1122 CF$UID 924 CF$UID 653 CF$UID 408 CF$UID 716 CF$UID 1034 CF$UID 926 CF$UID 525 CF$UID 456 CF$UID 1081 CF$UID 619 CF$UID 835 CF$UID 1036 CF$UID 723 CF$UID 273 CF$UID 1083 CF$UID 87 CF$UID 852 CF$UID 1038 CF$UID 803 CF$UID 606 CF$UID 546 CF$UID 1085 CF$UID 755 CF$UID 730 CF$UID 1040 CF$UID 1103 CF$UID 1102 CF$UID 1087 CF$UID 816 CF$UID 1042 CF$UID 402 CF$UID 938 CF$UID 1089 CF$UID 190 CF$UID 738 CF$UID 887 CF$UID 486 CF$UID 331 CF$UID 1044 CF$UID 95 CF$UID 460 CF$UID 901 CF$UID 940 CF$UID 1091 CF$UID 820 CF$UID 60 CF$UID 696 CF$UID 909 CF$UID 1046 CF$UID 224 CF$UID 942 CF$UID 519 CF$UID 151 CF$UID 466 CF$UID 556 CF$UID 892 CF$UID 1048 CF$UID 678 CF$UID 306 CF$UID 944 CF$UID 683 CF$UID 621 CF$UID 329 CF$UID 1050 CF$UID 267 CF$UID 564 CF$UID 259 CF$UID 946 CF$UID 116 CF$UID 250 CF$UID 1051 CF$UID 172 CF$UID 607 CF$UID 896 CF$UID 500 CF$UID 948 CF$UID 602 CF$UID 2 CF$UID 571 CF$UID 764 CF$UID 644 CF$UID 950 CF$UID 36 CF$UID 506 CF$UID 367 CF$UID 289 CF$UID 1108 CF$UID 1129 CF$UID 641 CF$UID 952 CF$UID 452 CF$UID 232 CF$UID 488 CF$UID 49 CF$UID 954 CF$UID 534 CF$UID 698 CF$UID 1052 CF$UID 674 CF$UID 202 CF$UID 477 CF$UID 420 CF$UID 766 CF$UID 956 CF$UID 186 CF$UID 1111 CF$UID 958 CF$UID 70 CF$UID 108 CF$UID 412 CF$UID 623 CF$UID 648 CF$UID 327 CF$UID 1131 CF$UID 960 CF$UID 63 CF$UID 300 CF$UID 598 CF$UID 632 CF$UID 905 CF$UID 962 CF$UID 837 CF$UID 8 CF$UID 347 CF$UID 548 CF$UID 964 CF$UID 638 CF$UID 882 CF$UID 848 CF$UID 784 CF$UID 966 CF$UID 490 CF$UID 968 CF$UID 536 CF$UID 700 CF$UID 917 CF$UID 56 CF$UID 335 CF$UID 676 CF$UID 790 CF$UID 768 CF$UID 970 CF$UID 521 CF$UID 458 CF$UID 1112 CF$UID 1057 CF$UID 818 CF$UID 972 CF$UID 778 CF$UID 974 CF$UID 822 CF$UID 333 CF$UID 895 CF$UID 976 CF$UID 155 CF$UID 428 CF$UID 269 CF$UID 691 CF$UID 900 CF$UID 978 CF$UID 13 CF$UID 1061 CF$UID 904 CF$UID 713 CF$UID 436 CF$UID 980 CF$UID 276 CF$UID 384 CF$UID 492 CF$UID 83 CF$UID 875 CF$UID 908 CF$UID 982 CF$UID 538 CF$UID 702 CF$UID 720 CF$UID 770 CF$UID 910 CF$UID 342 CF$UID 984 CF$UID 799 CF$UID 685 CF$UID 1115 CF$UID 176 CF$UID 986 $class CF$UID 1137 NS.objects CF$UID 1204 CF$UID 1205 CF$UID 1206 CF$UID 1207 CF$UID 1208 CF$UID 1209 CF$UID 1210 CF$UID 1211 CF$UID 1212 CF$UID 1213 CF$UID 1214 CF$UID 1215 CF$UID 1216 CF$UID 1217 CF$UID 1218 CF$UID 1219 CF$UID 1220 CF$UID 1221 CF$UID 1222 CF$UID 1223 CF$UID 1224 CF$UID 1225 CF$UID 1226 CF$UID 1227 CF$UID 1228 CF$UID 1229 CF$UID 1230 CF$UID 1231 CF$UID 1232 CF$UID 1233 CF$UID 1234 CF$UID 1235 CF$UID 1236 CF$UID 1237 CF$UID 1238 CF$UID 1239 CF$UID 1240 CF$UID 1241 CF$UID 1242 CF$UID 1243 CF$UID 1244 CF$UID 1245 CF$UID 1246 CF$UID 1247 CF$UID 1248 CF$UID 1249 CF$UID 1250 CF$UID 1251 CF$UID 1252 CF$UID 1253 CF$UID 1254 CF$UID 1255 CF$UID 1256 CF$UID 1257 CF$UID 1258 CF$UID 1259 CF$UID 1260 CF$UID 1261 CF$UID 1262 CF$UID 1263 CF$UID 1264 CF$UID 1265 CF$UID 1266 CF$UID 1267 CF$UID 1268 CF$UID 1269 CF$UID 1270 CF$UID 1271 CF$UID 1272 CF$UID 1273 CF$UID 1274 CF$UID 1275 CF$UID 1276 CF$UID 1277 CF$UID 1278 CF$UID 1279 CF$UID 1280 CF$UID 1281 CF$UID 1282 CF$UID 1283 CF$UID 1284 CF$UID 1285 CF$UID 1286 CF$UID 1287 CF$UID 1288 CF$UID 1289 CF$UID 1290 CF$UID 1291 CF$UID 1292 CF$UID 1293 CF$UID 1294 CF$UID 1295 CF$UID 1296 CF$UID 1297 CF$UID 1298 CF$UID 1299 CF$UID 1300 CF$UID 1301 CF$UID 1302 CF$UID 1303 CF$UID 1304 CF$UID 1305 CF$UID 1306 CF$UID 1307 CF$UID 1308 CF$UID 1309 CF$UID 1310 CF$UID 1311 CF$UID 1312 CF$UID 1313 CF$UID 1314 CF$UID 1315 CF$UID 1316 CF$UID 1317 CF$UID 1318 CF$UID 1319 CF$UID 1320 CF$UID 1321 CF$UID 1322 CF$UID 1323 CF$UID 1324 CF$UID 1325 CF$UID 1326 CF$UID 1327 CF$UID 1328 CF$UID 1329 CF$UID 1330 CF$UID 1331 CF$UID 1332 CF$UID 1333 CF$UID 1334 CF$UID 1335 CF$UID 1336 CF$UID 1337 CF$UID 1338 CF$UID 1339 CF$UID 1340 CF$UID 1341 CF$UID 1342 CF$UID 1343 CF$UID 1344 CF$UID 1345 CF$UID 1346 CF$UID 1347 CF$UID 1348 CF$UID 1349 CF$UID 1350 CF$UID 1351 CF$UID 1352 CF$UID 1353 CF$UID 1354 CF$UID 1355 CF$UID 1356 CF$UID 1357 CF$UID 1358 CF$UID 1359 CF$UID 1360 CF$UID 1361 CF$UID 1362 CF$UID 1363 CF$UID 1364 CF$UID 1365 CF$UID 1366 CF$UID 1367 CF$UID 1368 CF$UID 1369 CF$UID 1370 CF$UID 1371 CF$UID 1372 CF$UID 1373 CF$UID 1374 CF$UID 1375 CF$UID 1376 CF$UID 1377 CF$UID 1378 CF$UID 1379 CF$UID 1380 CF$UID 1381 CF$UID 1382 CF$UID 1383 CF$UID 1384 CF$UID 1385 CF$UID 1386 CF$UID 1387 CF$UID 1388 CF$UID 1389 CF$UID 1390 CF$UID 1391 CF$UID 1392 CF$UID 1393 CF$UID 1394 CF$UID 1395 CF$UID 1396 CF$UID 1397 CF$UID 1398 CF$UID 1399 CF$UID 1400 CF$UID 1401 CF$UID 1402 CF$UID 1403 CF$UID 1404 CF$UID 1405 CF$UID 1406 CF$UID 1407 CF$UID 1408 CF$UID 1409 CF$UID 1410 CF$UID 1411 CF$UID 1412 CF$UID 1413 CF$UID 1414 CF$UID 1415 CF$UID 1416 CF$UID 1417 CF$UID 1418 CF$UID 1419 CF$UID 1420 CF$UID 1421 CF$UID 1422 CF$UID 1423 CF$UID 1424 CF$UID 1425 CF$UID 1426 CF$UID 1427 CF$UID 1428 CF$UID 1429 CF$UID 1430 CF$UID 1431 CF$UID 1432 CF$UID 1433 CF$UID 1434 CF$UID 1435 CF$UID 1436 CF$UID 1437 CF$UID 1438 CF$UID 1439 CF$UID 1440 CF$UID 1441 CF$UID 1442 CF$UID 1443 CF$UID 1444 CF$UID 1445 CF$UID 1446 CF$UID 1447 CF$UID 1448 CF$UID 1449 CF$UID 1450 CF$UID 1451 CF$UID 1452 CF$UID 1453 CF$UID 1454 CF$UID 1455 CF$UID 1456 CF$UID 1457 CF$UID 1458 CF$UID 1459 CF$UID 1460 CF$UID 1461 CF$UID 1462 CF$UID 1463 CF$UID 1464 CF$UID 1465 CF$UID 1466 CF$UID 1467 CF$UID 1468 CF$UID 1469 CF$UID 1470 CF$UID 1471 CF$UID 1472 CF$UID 1473 CF$UID 1474 CF$UID 1475 CF$UID 1476 CF$UID 1477 CF$UID 1478 CF$UID 1479 CF$UID 1480 CF$UID 1481 CF$UID 1482 CF$UID 1483 CF$UID 1484 CF$UID 1485 CF$UID 1486 CF$UID 1487 CF$UID 1488 CF$UID 1489 CF$UID 1490 CF$UID 1491 CF$UID 1492 CF$UID 1493 CF$UID 1494 CF$UID 1495 CF$UID 1496 CF$UID 1497 CF$UID 1498 CF$UID 1499 CF$UID 1500 CF$UID 1501 CF$UID 1502 CF$UID 1503 CF$UID 1504 CF$UID 1505 CF$UID 1506 CF$UID 1507 CF$UID 1508 CF$UID 1509 CF$UID 1510 CF$UID 1511 CF$UID 1512 CF$UID 1513 CF$UID 1514 CF$UID 1515 CF$UID 1516 CF$UID 1517 CF$UID 1518 CF$UID 1519 CF$UID 1520 CF$UID 1521 CF$UID 1522 CF$UID 1523 CF$UID 1524 CF$UID 1525 CF$UID 1526 CF$UID 1527 CF$UID 1528 CF$UID 1529 CF$UID 1530 CF$UID 1531 CF$UID 1532 CF$UID 1533 CF$UID 1534 CF$UID 1535 CF$UID 1536 CF$UID 1537 CF$UID 1538 CF$UID 1539 CF$UID 1540 CF$UID 1541 CF$UID 1542 592 396 535 634 149 649 761 235 251 397 452 620 24 550 650 398 439 574 651 622 892 399 865 547 446 821 652 392 830 410 961 791 653 438 240 836 599 411 448 631 654 231 871 455 208 450 655 872 752 642 199 656 214 874 831 237 817 657 875 201 207 445 894 985 658 897 937 551 867 538 641 775 606 772 898 820 299 441 776 264 444 771 899 603 623 789 239 537 797 765 633 643 532 837 607 638 37 766 39 824 838 210 906 242 637 265 632 203 839 534 987 453 222 868 553 533 840 754 988 274 144 226 391 644 876 454 767 846 435 198 880 989 393 303 881 848 139 812 555 142 896 849 753 895 136 850 232 889 209 814 768 835 851 103 394 546 773 576 852 395 432 834 900 541 962 853 580 888 901 234 986 854 630 554 878 902 640 619 855 29 19 903 218 856 877 412 904 405 621 57 826 386 857 236 819 134 413 905 941 205 591 72 859 211 414 215 241 822 447 58 860 577 893 415 588 545 213 870 301 449 273 416 408 266 111 243 540 145 823 417 539 1 451 626 536 418 200 825 755 891 92 56 548 422 829 250 827 202 423 433 608 106 216 407 833 790 628 430 244 143 556 230 238 764 879 542 212 83 557 206 305 543 544 150 558 972 21 390 431 559 552 5 984 629 561 832 562 437 590 75 204 388 217 639 627 563 434 816 131 861 219 565 635 567 942 387 146 568 406 813 887 585 152 570 2 863 153 613 815 571 890 762 828 233 23 223 645 436 605 598 624 81 389 646 625 587 130 409 648 $class CF$UID 212 NS.objects $class CF$UID 1137 NS.objects $class CF$UID 1137 NS.objects $classes NSIBObjectData NSObject $classname NSIBObjectData $top IB.objectdata CF$UID 1 $version 100000 cluster-1.52a/mac/English.lproj/MainMenu.nib/classes.nib0000644000100500010050000000700611356353440023005 0ustar mdehoonmdehoon{ IBClasses = ( { ACTIONS = { AdjustApply = id; AdjustCenterArraysXBChanged = id; AdjustCenterGenesXBChanged = id; FileOpen = id; FileSave = id; FilterAccept = id; FilterApply = id; HierarchicalArrayWeightXBChanged = id; HierarchicalAverage = id; HierarchicalCentroid = id; HierarchicalComplete = id; HierarchicalGeneWeightXBChanged = id; HierarchicalSingle = id; KMeansExecute = id; PCAExecute = id; SOMExecute = id; ShowAboutPanel = id; ShowFileFormatPanel = id; ShowHelpDownload = id; ShowHelpManual = id; }; CLASS = Controller; LANGUAGE = ObjC; OUTLETS = { AdjustCenterArraysXB = id; AdjustCenterGenesXB = id; AdjustLogXB = id; AdjustMeanArrays = id; AdjustMeanGenes = id; AdjustMedianArrays = id; AdjustMedianGenes = id; AdjustNormalizeArrays = id; AdjustNormalizeGenes = id; Columns = id; FileMemo = id; FilterMaxMin = id; FilterMaxMinXB = id; FilterNumber = id; FilterObservationValue = id; FilterObservationXB = id; FilterPercent = id; FilterPercentXB = id; FilterStd = id; FilterStdXB = id; HierarchicalArrayCutoff = id; HierarchicalArrayExp = id; HierarchicalArrayMetric = id; HierarchicalArrayWeight = id; HierarchicalArrayWeightXB = id; HierarchicalArrayXB = id; HierarchicalArrays = id; HierarchicalGeneCutoff = id; HierarchicalGeneExp = id; HierarchicalGeneMetric = id; HierarchicalGeneWeight = id; HierarchicalGeneWeightXB = id; HierarchicalGeneXB = id; HierarchicalGenes = id; JobName = id; KMeansArrayK = id; KMeansArrayMean = id; KMeansArrayMetric = id; KMeansArrayRuns = id; KMeansArrayXB = id; KMeansGeneK = id; KMeansGeneMean = id; KMeansGeneMetric = id; KMeansGeneRuns = id; KMeansGeneXB = id; PCAArrayXB = id; PCAGeneXB = id; Rows = id; SOMArrayIters = id; SOMArrayMetric = id; SOMArrayTau = id; SOMArrayXB = id; SOMArrayXDim = id; SOMArrayYDim = id; SOMGeneIters = id; SOMGeneMetric = id; SOMGeneTau = id; SOMGeneXB = id; SOMGeneXDim = id; SOMGeneYDim = id; filteraccept = id; filterresult = id; statusbar = id; }; SUPERCLASS = NSObject; }, {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; } ); IBVersion = 1; }cluster-1.52a/mac/English.lproj/MainMenu.nib/info.nib0000644000100500010050000000124311356353440022300 0ustar mdehoonmdehoon IBDocumentLocation 990 606 356 240 0 0 1440 878 IBEditorPositions 29 46 272 235 44 0 0 1440 878 IBFramework Version 489.0 IBOldestOS 3 IBOpenObjects 21 29 IBSystem Version 8S2167 IBUsesTextArchiving cluster-1.52a/mac/English.lproj/AboutPanel.nib/0000755000100500010050000000000012177164022021172 5ustar mdehoonmdehooncluster-1.52a/mac/English.lproj/AboutPanel.nib/keyedobjects.nib0000644000100500010050000003531612174112014024336 0ustar mdehoonmdehoon $archiver NSKeyedArchiver $objects $null $class CF$UID 64 NSAccessibilityConnectors CF$UID 61 NSAccessibilityOidsKeys CF$UID 62 NSAccessibilityOidsValues CF$UID 63 NSClassesKeys CF$UID 52 NSClassesValues CF$UID 53 NSConnections CF$UID 8 NSFontManager CF$UID 0 NSFramework CF$UID 5 NSNamesKeys CF$UID 47 NSNamesValues CF$UID 48 NSNextOid 11 NSObjectsKeys CF$UID 44 NSObjectsValues CF$UID 46 NSOidsKeys CF$UID 54 NSOidsValues CF$UID 55 NSRoot CF$UID 2 NSVisibleWindows CF$UID 6 $class CF$UID 4 NSClassName CF$UID 3 Controller $classes NSCustomObject NSObject $classname NSCustomObject IBCocoaFramework $class CF$UID 7 NS.objects $classes NSMutableSet NSSet NSObject $classname NSMutableSet $class CF$UID 35 NS.objects CF$UID 9 $class CF$UID 43 NSDestination CF$UID 10 NSLabel CF$UID 42 NSSource CF$UID 2 $class CF$UID 41 NSMaxSize CF$UID 40 NSMinSize CF$UID 39 NSScreenRect CF$UID 38 NSViewClass CF$UID 14 NSWTFlags 1886912512 NSWindowBacking 2 NSWindowClass CF$UID 13 NSWindowRect CF$UID 11 NSWindowStyleMask 3 NSWindowTitle CF$UID 12 NSWindowView CF$UID 16 {{538, 470}, {357, 260}} About Cluster 3.0 NSPanel $class CF$UID 15 NS.string View $classes NSMutableString NSString NSObject $classname NSMutableString $class CF$UID 37 NSFrame CF$UID 36 NSNextResponder CF$UID 0 NSSubviews CF$UID 17 $class CF$UID 35 NS.objects CF$UID 18 $class CF$UID 34 NSCell CF$UID 20 NSEnabled NSFrame CF$UID 19 NSNextResponder CF$UID 16 NSSuperview CF$UID 16 NSvFlags 256 {{17, 20}, {323, 220}} $class CF$UID 33 NSBackgroundColor CF$UID 25 NSCellFlags 67239424 NSCellFlags2 4194304 NSContents CF$UID 21 NSControlView CF$UID 18 NSSupport CF$UID 22 NSTextColor CF$UID 30 Cluster 3.0 using the C Clustering Library version 1.52 Cluster was originally written by Michael Eisen (eisen 'AT' rana.lbl.gov). Copyright 1998-99 Stanford University. Cluster version 3.0 for Mac OS X was created by Michiel de Hoon (mdehoon 'AT' gsc.riken.jp), together with Seiya Imoto and Satoru Miyano. University of Tokyo, Human Genome Center October 2002. $class CF$UID 24 NSName CF$UID 23 NSSize 13 NSfFlags 1044 LucidaGrande $classes NSFont NSObject $classname NSFont $class CF$UID 29 NSCatalogName CF$UID 26 NSColor CF$UID 28 NSColorName CF$UID 27 NSColorSpace 6 System controlColor $class CF$UID 29 NSColorSpace 3 NSWhite MC42NjY2NjY2OQA= $classes NSColor NSObject $classname NSColor $class CF$UID 29 NSCatalogName CF$UID 26 NSColor CF$UID 32 NSColorName CF$UID 31 NSColorSpace 6 controlTextColor $class CF$UID 29 NSColorSpace 3 NSWhite MAA= $classes NSTextFieldCell NSActionCell NSCell NSObject $classname NSTextFieldCell $classes NSTextField %NSTextField NSControl NSView NSResponder NSObject $classname NSTextField $classes NSMutableArray NSArray NSObject $classname NSMutableArray {{1, 1}, {357, 260}} $classes NSView NSResponder NSObject $classname NSView {{0, 0}, {1440, 878}} {213, 129} {3.40282e+38, 3.40282e+38} $classes NSWindowTemplate NSObject $classname NSWindowTemplate AboutPanel $classes NSNibOutletConnector NSNibConnector NSObject $classname NSNibOutletConnector $class CF$UID 45 NS.objects CF$UID 18 CF$UID 10 CF$UID 16 $classes NSArray NSObject $classname NSArray $class CF$UID 45 NS.objects CF$UID 16 CF$UID 2 CF$UID 10 $class CF$UID 45 NS.objects CF$UID 2 CF$UID 18 CF$UID 10 $class CF$UID 45 NS.objects CF$UID 49 CF$UID 50 CF$UID 51 File's Owner NSTextField2 Panel $class CF$UID 45 NS.objects $class CF$UID 45 NS.objects $class CF$UID 45 NS.objects CF$UID 18 CF$UID 10 CF$UID 2 CF$UID 16 CF$UID 9 $class CF$UID 45 NS.objects CF$UID 56 CF$UID 57 CF$UID 58 CF$UID 59 CF$UID 60 7 5 1 6 10 $class CF$UID 35 NS.objects $class CF$UID 45 NS.objects $class CF$UID 45 NS.objects $classes NSIBObjectData NSObject $classname NSIBObjectData $top IB.objectdata CF$UID 1 $version 100000 cluster-1.52a/mac/English.lproj/AboutPanel.nib/classes.nib0000644000100500010050000000044110762013662023321 0ustar mdehoonmdehoon{ IBClasses = ( { CLASS = Controller; LANGUAGE = ObjC; OUTLETS = {AboutPanel = id; }; SUPERCLASS = NSObject; }, {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; } ); IBVersion = 1; }cluster-1.52a/mac/English.lproj/AboutPanel.nib/info.nib0000644000100500010050000000103310762013662022615 0ustar mdehoonmdehoon IBDocumentLocation 94 216 356 240 0 0 1440 878 IBFramework Version 446.1 IBOldestOS 3 IBOpenObjects 5 IBSystem Version 8S2167 IBUsesTextArchiving cluster-1.52a/mac/Controller.h0000644000100500010050000000657411313221042016146 0ustar mdehoonmdehoon/* Controller */ #import @interface Controller : NSObject { IBOutlet id statusbar; IBOutlet id JobName; IBOutlet id FileMemo; IBOutlet id Rows; IBOutlet id Columns; IBOutlet id filterresult; IBOutlet id filteraccept; IBOutlet id FilterStdXB; IBOutlet id FilterPercentXB; IBOutlet id FilterObservationXB; IBOutlet id FilterMaxMinXB; IBOutlet id FilterStd; IBOutlet id FilterPercent; IBOutlet id FilterNumber; IBOutlet id FilterObservationValue; IBOutlet id FilterMaxMin; IBOutlet id AdjustLogXB; IBOutlet id AdjustNormalizeGenes; IBOutlet id AdjustNormalizeArrays; IBOutlet id AdjustCenterGenesXB; IBOutlet id AdjustMeanGenes; IBOutlet id AdjustMedianGenes; IBOutlet id AdjustCenterArraysXB; IBOutlet id AdjustMeanArrays; IBOutlet id AdjustMedianArrays; IBOutlet id HierarchicalGenes; IBOutlet id HierarchicalArrays; IBOutlet id HierarchicalGeneXB; IBOutlet id HierarchicalArrayXB; IBOutlet id HierarchicalGeneMetric; IBOutlet id HierarchicalArrayMetric; IBOutlet id HierarchicalGeneCutoff; IBOutlet id HierarchicalArrayCutoff; IBOutlet id HierarchicalGeneExp; IBOutlet id HierarchicalArrayExp; IBOutlet id HierarchicalGeneWeight; IBOutlet id HierarchicalArrayWeight; IBOutlet id HierarchicalGeneWeightXB; IBOutlet id HierarchicalArrayWeightXB; IBOutlet id KMeansGeneXB; IBOutlet id KMeansGeneK; IBOutlet id KMeansGeneMean; IBOutlet id KMeansGeneMetric; IBOutlet id KMeansGeneRuns; IBOutlet id KMeansArrayXB; IBOutlet id KMeansArrayK; IBOutlet id KMeansArrayMean; IBOutlet id KMeansArrayMetric; IBOutlet id KMeansArrayRuns; IBOutlet id SOMGeneXB; IBOutlet id SOMGeneIters; IBOutlet id SOMGeneTau; IBOutlet id SOMGeneMetric; IBOutlet id SOMGeneXDim; IBOutlet id SOMGeneYDim; IBOutlet id SOMArrayXB; IBOutlet id SOMArrayIters; IBOutlet id SOMArrayTau; IBOutlet id SOMArrayMetric; IBOutlet id SOMArrayXDim; IBOutlet id SOMArrayYDim; IBOutlet id PCAGeneXB; IBOutlet id PCAArrayXB; IBOutlet id FileFormatPanel; IBOutlet id AboutPanel; NSString* directory; int* use; int useRows; } - (void)UpdateInfo; - (void)FilterReset; - (char)GetMetric:(NSComboBox*)metricbox; - (void)HierarchicalExecute:(NSString*)method; - (IBAction)FileOpen:(id)sender; - (IBAction)FileSave:(id)sender; - (IBAction)ShowHelpManual:(id)sender; - (IBAction)ShowHelpDownload:(id)sender; - (IBAction)ShowFileFormatPanel:(id)sender; - (IBAction)ShowAboutPanel:(id)sender; - (IBAction)FilterApply:(id)sender; - (IBAction)FilterAccept:(id)sender; - (IBAction)AdjustApply:(id)sender; - (IBAction)AdjustCenterGenesXBChanged:(id)sender; - (IBAction)AdjustCenterArraysXBChanged:(id)sender; - (IBAction)HierarchicalGeneWeightXBChanged:(id)sender; - (IBAction)HierarchicalArrayWeightXBChanged:(id)sender; - (IBAction)HierarchicalCentroid:(id)sender; - (IBAction)HierarchicalSingle:(id)sender; - (IBAction)HierarchicalComplete:(id)sender; - (IBAction)HierarchicalAverage:(id)sender; - (IBAction)KMeansExecute:(id)sender; - (IBAction)KMeansExecute:(id)sender; - (IBAction)SOMExecute:(id)sender; - (IBAction)PCAExecute:(id)sender; - (void)InitDir; - (void)SaveDir:(NSString*)filename; @end @interface Controller(NSApplicationNotifications) -(void)applicationDidFinishLaunching:(NSNotification*)notification; @end cluster-1.52a/config.h.in0000644000100500010050000000422312174721406015141 0ustar mdehoonmdehoon/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `Xext' library (-lXext). */ #undef HAVE_LIBXEXT /* Define to 1 if you have the `Xm' library (-lXm). */ #undef HAVE_LIBXM /* Define to 1 if you have the `Xt' library (-lXt). */ #undef HAVE_LIBXT /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #undef HAVE_MALLOC /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define to 1 if the X Window System is missing or not being used. */ #undef X_DISPLAY_MISSING /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to rpl_malloc if the replacement function should be used. */ #undef malloc /* Define to `unsigned int' if does not define. */ #undef size_t cluster-1.52a/X11/0000755000100500010050000000000012414674264013474 5ustar mdehoonmdehooncluster-1.52a/X11/gui.c0000644000100500010050000032441212414674264014432 0ustar mdehoonmdehoon/* Standard C header files */ #include #include #include #include /* Motif header files */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Local header files */ #include "cluster.h" /* The C clustering library */ #include "data.h" /* Includes data handling and file reading/writing */ #include "gui.h" /* Declaration of the guimain function */ #define CMD_FILE_OPEN 0 #define CMD_FILE_SAVE 1 #define CMD_FILE_QUIT 2 #define CMD_HELP_HTMLHELP 0 #define CMD_HELP_MANUAL 1 #define CMD_HELP_DOWNLOAD 2 #define CMD_HELP_FILEFORMAT 3 #define CMD_HELP_ABOUT 4 #define ID_FILEMANAGER_INIT 101 #define ID_FILEMANAGER_SET_FILEMEMO 102 #define ID_FILEMANAGER_SET_JOBNAME 103 #define ID_FILEMANAGER_UPDATE_ROWS_COLUMNS 104 #define ID_FILTER_INIT 301 #define ID_FILTER_APPLY 311 #define ID_FILTER_ACCEPT 313 #define ID_FILTER_RESET 314 #define ID_FILTER_FREE 315 #define ID_ADJUST_INIT 401 #define ID_ADJUST_EXECUTE 402 #define ID_HIERARCHICAL_INIT 501 #define ID_HIERARCHICAL_CENTROID 513 #define ID_HIERARCHICAL_SINGLE 514 #define ID_HIERARCHICAL_COMPLETE 515 #define ID_HIERARCHICAL_AVERAGE 516 #define ID_KMEANS_INIT 601 #define ID_KMEANS_EXECUTE 602 #define ID_SOM_INIT 701 #define ID_SOM_EXECUTE 702 #define ID_SOM_UPDATE 703 #define ID_PCA_INIT 801 #define ID_PCA_EXECUTE 802 /*============================================================================*/ /* GUI utilities */ /*============================================================================*/ static void CreateMetricComboBox(Widget parent, int x, int y, char* name, char initial) { XmString xms; Widget label, combo; Arg args[5]; int n = 0; XmStringTable metrics = (XmStringTable)XtMalloc(8*sizeof(XmString*)); metrics[0] = XmStringCreateSimple("Correlation (uncentered)"); metrics[1] = XmStringCreateSimple("Correlation (centered)"); metrics[2] = XmStringCreateSimple("Absolute Correlation (uncentered)"); metrics[3] = XmStringCreateSimple("Absolute Correlation (centered)"); metrics[4] = XmStringCreateSimple("Spearman Rank Correlation"); metrics[5] = XmStringCreateSimple("Kendall's tau"); metrics[6] = XmStringCreateSimple("Euclidean distance"); metrics[7] = XmStringCreateSimple("City-block distance"); XtSetArg(args[n], XmNx, x+65); n++; XtSetArg(args[n], XmNy, y); n++; xms = XmStringCreateSimple("Similarity Metric"); XtSetArg(args[n], XmNlabelString, xms); n++; label = XmCreateLabel(parent, "", args, n); XtManageChild(label); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, x); n++; XtSetArg(args[n], XmNy, y+20); n++; XtSetArg(args[n], XmNitems, metrics); n++; XtSetArg(args[n], XmNitemCount, 8); n++; switch (initial) { case 'u': XtSetArg(args[n], XmNselectedPosition, 0); n++; break; case 'c': XtSetArg(args[n], XmNselectedPosition, 1); n++; break; case 'a': XtSetArg(args[n], XmNselectedPosition, 2); n++; break; case 'x': XtSetArg(args[n], XmNselectedPosition, 3); n++; break; case 's': XtSetArg(args[n], XmNselectedPosition, 4); n++; break; case 'k': XtSetArg(args[n], XmNselectedPosition, 5); n++; break; case 'e': XtSetArg(args[n], XmNselectedPosition, 6); n++; break; case 'b': XtSetArg(args[n], XmNselectedPosition, 7); n++; break; default : XtSetArg(args[n], XmNselectedPosition, 0); n++; break; } combo = XmCreateDropDownList(parent, name, args, n); XtManageChild(combo); for (n = 0; n < 8; n++) XmStringFree(metrics[n]); XtFree((char*)metrics); } static char GetMetric(Widget w) { int n = 0; Arg args[1]; int index; XtSetArg(args[n], XmNselectedPosition, &index); n++; XtGetValues(w, args, n); switch (index) { case 0: return 'u'; break; /* Uncentered correlation */ case 1: return 'c'; break; /* Centered correlation */ case 2: return 'x'; break; /* Absolute uncentered correlation */ case 3: return 'a'; break; /* Absolute centered correlation */ case 4: return 's'; break; /* Spearman rank correlation */ case 5: return 'k'; break; /* Kendall's tau */ case 6: return 'e'; break; /* Euclidean distance */ case 7: return 'b'; break; /* City-block distance */ /* The code will never get here. */ default: return 'e'; /* Euclidean distance is default. */ } } static int GetWidgetItemInt(Widget w, const char item[]) { int result; char* text; Widget textfield = XtNameToWidget(w, item); if (textfield==0) return 0; text = XmTextGetString(textfield); result = strtol(text, NULL, 0); /* returns 0 if failed */ XtFree(text); return result; } /*============================================================================*/ /* Status bar */ /*============================================================================*/ static Widget Statusbar(Widget w, char* message) { static Widget statusbar = NULL; if (!statusbar) { int n = 0; Arg args[2]; XtSetArg(args[n], XmNeditable, False); n++; XtSetArg(args[n], XmNmaxLength, 200); n++; statusbar = XmCreateTextField(w, "message", args, n); XtManageChild(statusbar); return statusbar; } else { XmTextSetString(statusbar, message); XmUpdateDisplay(statusbar); return NULL; } } /*============================================================================*/ /* Error messages */ /*============================================================================*/ static void ShowError(Widget parent, const char* message, const char* title) { Widget dialog; Arg args[2]; XmString message_string = XmStringCreateSimple((char*)message); /* Note: error is a const char*. XmStringCreateSimple wants a char* (without * the const), although it does not modify the string. So cast it to char*. */ XmString title_string = title ? XmStringCreateSimple((char*)title) : XmStringCreateSimple("Error"); int n = 0; XtSetArg(args[n], XmNmessageString, message_string); n++; XtSetArg(args[n], XmNdialogTitle, title_string); n++; dialog = XmCreateMessageDialog(parent, "", args, n); XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON)); XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON)); XtManageChild(dialog); XmStringFree(message_string); XmStringFree(title_string); } /*============================================================================*/ /* File manager functions */ /*============================================================================*/ static char* GetBaseName(Widget work) { Widget widget; char* jobname; char* directory; char* index; char* fullpath; int n; widget = XtNameToWidget(work,"Jobname"); jobname = XmTextGetString(widget); widget = XtNameToWidget(work,"FileMemo"); directory = XmTextGetString(widget); index = strrchr(directory,'/'); *(index+1) = '\0'; n = strlen(directory) + strlen(jobname) + 1; fullpath = malloc(n*sizeof(char)); if (fullpath) { strcpy(fullpath, directory); strcat(fullpath, jobname); } XtFree(directory); XtFree(jobname); return fullpath; } /*============================================================================*/ /* Callback functions --- Tab pages */ /*============================================================================*/ static void SOM(Widget w, XtPointer client_data, XtPointer call_data) { static Widget page = NULL; int* which = (int*) client_data; switch (*which) { case ID_SOM_INIT: { static int command = ID_SOM_EXECUTE; Arg args[5]; int n; Widget widget, frame; XmString xms; page = w; n = 0; XtSetArg(args[n], XmNx, 180); n++; widget = XmCreateLabel(page, "Calculate a Self-Organizing Map", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 50); n++; widget = XmCreateToggleButton(page, "Organize genes", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 80); n++; XtSetArg(args[n], XmNwidth, 60); n++; XtSetArg(args[n], XmNvalue, "4"); n++; widget = XmCreateText(page, "SOMGeneXDim", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 85); n++; XtSetArg(args[n], XmNy, 86); n++; widget = XmCreateLabel(page, "XDim", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 120); n++; XtSetArg(args[n], XmNwidth, 60); n++; XtSetArg(args[n], XmNvalue, "4"); n++; widget = XmCreateText(page, "SOMGeneYDim", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 85); n++; XtSetArg(args[n], XmNy, 126); n++; widget = XmCreateLabel(page, "YDim", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 160); n++; XtSetArg(args[n], XmNwidth, 100); n++; XtSetArg(args[n], XmNvalue, "100000"); n++; widget = XmCreateText(page, "SOMGeneIters", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 130); n++; XtSetArg(args[n], XmNy, 166); n++; widget = XmCreateLabel(page, "Number of iterations", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 200); n++; XtSetArg(args[n], XmNwidth, 80); n++; XtSetArg(args[n], XmNvalue, "0.02"); n++; widget = XmCreateText(page, "SOMGeneTau", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 110); n++; XtSetArg(args[n], XmNy, 206); n++; widget = XmCreateLabel(page, "Initial tau", args, n); XtManageChild(widget); CreateMetricComboBox(page, 20, 240, "GeneMetric", 'e'); n = 0; XtSetArg(args[n], XmNy, 30); n++; XtSetArg(args[n], XmNwidth, 255); n++; XtSetArg(args[n], XmNheight, 275); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Genes"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(frame, NULL, args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 50); n++; widget = XmCreateToggleButton(page, "Organize arrays", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 80); n++; XtSetArg(args[n], XmNwidth, 60); n++; XtSetArg(args[n], XmNvalue, "4"); n++; widget = XmCreateText(page, "SOMArrayXDim", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 355); n++; XtSetArg(args[n], XmNy, 86); n++; widget = XmCreateLabel(page, "XDim", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 120); n++; XtSetArg(args[n], XmNwidth, 60); n++; XtSetArg(args[n], XmNvalue, "4"); n++; widget = XmCreateText(page, "SOMArrayYDim", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 355); n++; XtSetArg(args[n], XmNy, 126); n++; widget = XmCreateLabel(page, "YDim", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 160); n++; XtSetArg(args[n], XmNwidth, 100); n++; XtSetArg(args[n], XmNvalue, "20000"); n++; widget = XmCreateText(page, "SOMArrayIters", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 400); n++; XtSetArg(args[n], XmNy, 166); n++; widget = XmCreateLabel(page, "Number of iterations", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 200); n++; XtSetArg(args[n], XmNwidth, 80); n++; XtSetArg(args[n], XmNvalue, "0.02"); n++; widget = XmCreateText(page, "SOMArrayTau", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 380); n++; XtSetArg(args[n], XmNy, 206); n++; widget = XmCreateLabel(page, "Initial tau", args, n); XtManageChild(widget); CreateMetricComboBox(page, 290, 240, "ArrayMetric", 'e'); n = 0; XtSetArg(args[n], XmNx, 280); n++; XtSetArg(args[n], XmNy, 30); n++; XtSetArg(args[n], XmNwidth, 255); n++; XtSetArg(args[n], XmNheight, 275); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Arrays"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(frame, NULL, args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 240); n++; XtSetArg(args[n], XmNy, 315); n++; widget = XmCreatePushButton(page, "Make SOM", args, n); XtManageChild(widget); XtAddCallback(widget, XmNactivateCallback, SOM, (XtPointer)&command); break; } case ID_SOM_EXECUTE: { const int Rows = GetRows(); const int Columns = GetColumns(); Widget button; Boolean ClusterGenes; Boolean ClusterArrays; int GeneXDim = GetWidgetItemInt(page, "SOMGeneXDim"); int GeneYDim = GetWidgetItemInt(page, "SOMGeneYDim"); int ArrayXDim = GetWidgetItemInt(page, "SOMArrayXDim"); int ArrayYDim = GetWidgetItemInt(page, "SOMArrayYDim"); int GeneIters = 0; int ArrayIters = 0; double GeneTau = 0.0; double ArrayTau = 0.0; char GeneMetric = 'e'; char ArrayMetric = 'e'; int n; char* path; char* filetag; FILE* GeneFile = NULL; FILE* ArrayFile = NULL; FILE* DataFile = NULL; int ok; Widget notebook = XtParent(page); Widget work = XtParent(notebook); if (Rows==0 || Columns==0) { Statusbar(NULL, "No data available"); return; } path = GetBaseName(work); if (!path) { Statusbar(NULL, "Memory allocation failure"); return; } button = XtNameToWidget(page,"Organize genes"); ClusterGenes = XmToggleButtonGetState(button); button = XtNameToWidget(page,"Organize arrays"); ClusterArrays = XmToggleButtonGetState(button); n = strlen(path) + strlen("_SOM") + strlen(".ext") + 1; if (ClusterGenes) { int dummy; dummy = GeneXDim; do n++; while (dummy/=10); dummy = GeneYDim; do n++; while (dummy/=10); n+=strlen("_G"); n++; /* For the '-' */ } if (ClusterArrays) { int dummy; dummy = ArrayXDim; do n++; while (dummy/=10); dummy = ArrayYDim; do n++; while (dummy/=10); n+=strlen("_A"); n++; /* For the '-' */ } path = realloc(path, n*sizeof(char)); strcat(path, "_SOM"); filetag = strchr(path, '\0'); if (ClusterGenes) filetag += sprintf(filetag, "_G%d-%d", GeneXDim, GeneYDim); if (ClusterArrays) filetag += sprintf(filetag, "_A%d-%d", ArrayXDim, ArrayYDim); sprintf(filetag, ".txt"); DataFile = fopen(path, "wt"); if (!DataFile) { free(path); Statusbar(NULL, "Error: Unable to open the output file"); return; } if (ClusterGenes) { double value; char* error; Widget widget = XtNameToWidget(page,"SOMGeneTau"); char* text = XmTextGetString(widget); value = strtod(text, &error); GeneTau = error ? value : 0; XtFree(text); widget = XtNameToWidget(page,"GeneMetric"); GeneMetric = GetMetric(widget); GeneIters = GetWidgetItemInt(page, "SOMGeneIters"); if ((GeneIters==0)||(GeneTau==0)||(GeneXDim==0)||(GeneYDim==0)) { Statusbar(NULL, "Error starting SOM: Check options"); fclose(DataFile); free(path); return; } sprintf(filetag, ".gnf"); GeneFile = fopen(path, "wt"); if (!GeneFile) { Statusbar(NULL, "Error: Unable to open the output file"); fclose(DataFile); free(path); return; } } if (ClusterArrays) { double value; char* error; Widget widget = XtNameToWidget(page,"SOMArrayTau"); char* text = XmTextGetString(widget); value = strtod(text, &error); ArrayTau = error ? value : 0; XtFree(text); widget = XtNameToWidget(page,"ArrayMetric"); ArrayMetric = GetMetric(widget); ArrayIters = GetWidgetItemInt(page, "SOMArrayIters"); if ((ArrayIters==0)||(ArrayTau==0)||(ArrayXDim==0)||(ArrayYDim==0)) { Statusbar(NULL, "Error starting SOM: Check options"); if (GeneFile) fclose(GeneFile); fclose(DataFile); free(path); return; } sprintf(filetag, ".anf"); ArrayFile = fopen(path, "wt"); if (!ArrayFile) { Statusbar(NULL, "Error: Unable to open the output file"); if (GeneFile) fclose(GeneFile); fclose(DataFile); free(path); return; } } free(path); Statusbar(NULL, "Calculating Self-Organizing Map"); ok = PerformSOM(GeneFile, GeneXDim, GeneYDim, GeneIters, GeneTau, GeneMetric, ArrayFile, ArrayXDim, ArrayYDim, ArrayIters, ArrayTau, ArrayMetric); if (GeneFile) fclose(GeneFile); if (ArrayFile) fclose(ArrayFile); if (!ok) { ShowError(w, "Memory allocation error", "Insufficient memory"); Statusbar(NULL, "Memory allocation error"); break; } ok = Save(DataFile, 0, 0); fclose(DataFile); if (!ok) { ShowError(w, "Error saving file", "Insufficient memory"); Statusbar(NULL, "Error saving to file"); break; } Statusbar(NULL, "Done making SOM"); break; } case ID_SOM_UPDATE: { const int Rows = GetRows(); const int Columns = GetColumns(); int n; int dim; Arg args[1]; char buffer[32]; Widget widget; /* Update SOM defaults to reflect new number of rows */ dim = 1 + (int)sqrt(sqrt(Rows)); /* pow causes a crash on AIX */ n = 0; sprintf(buffer,"%d",dim); XtSetArg(args[n], XmNvalue, buffer); n++; widget = XtNameToWidget(page,"SOMGeneXDim"); XtSetValues(widget, args, n); widget = XtNameToWidget(page,"SOMGeneYDim"); XtSetValues(widget, args, n); dim = 1 + (int)sqrt(sqrt(Columns)); /* pow causes a crash on AIX */ n = 0; sprintf(buffer,"%d",dim); XtSetArg(args[n], XmNvalue, buffer); n++; widget = XtNameToWidget(page,"SOMArrayXDim"); XtSetValues(widget, args, n); widget = XtNameToWidget(page,"SOMArrayYDim"); XtSetValues(widget, args, n); break; } } } static void FileManager(Widget w, XtPointer client_data, XtPointer call_data) { static Widget work = NULL; int* which = (int*) client_data; switch (*which) { case ID_FILEMANAGER_INIT: { Widget widget; Arg args[5]; int n = 0; XmString xmsempty = XmStringCreateSimple(""); XmString xmsmax = XmStringCreateSimple("xxxxxxxxx"); /* to calculate the size */ work = w; n = 0; XtSetArg(args[n], XmNx, 10); n++; XtSetArg(args[n], XmNy, 10); n++; widget = XmCreateLabel(work, "File loaded", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 10); n++; XtSetArg(args[n], XmNy, 100); n++; widget = XmCreateLabel(work, "Job name", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 10); n++; XtSetArg(args[n], XmNy, 140); n++; widget = XmCreateLabel(work, "Data set has", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 180); n++; XtSetArg(args[n], XmNy, 130); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_END); n++; XtSetArg(args[n], XmNrecomputeSize, False); n++; XtSetArg(args[n], XmNlabelString, xmsmax); n++; widget = XmCreateLabel(work, "rows", args, n); n = 0; XtSetArg(args[n], XmNlabelString, xmsempty); n++; XtSetValues(widget, args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 240); n++; XtSetArg(args[n], XmNy, 130); n++; widget = XmCreateLabel(work, "Rows", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 180); n++; XtSetArg(args[n], XmNy, 150); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_END); n++; XtSetArg(args[n], XmNrecomputeSize, False); n++; XtSetArg(args[n], XmNlabelString, xmsmax); n++; widget = XmCreateLabel(work, "columns", args, n); n = 0; XtSetArg(args[n], XmNlabelString, xmsempty); n++; XtSetValues(widget, args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 240); n++; XtSetArg(args[n], XmNy, 150); n++; widget = XmCreateLabel(work, "Columns", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 160); n++; XtSetArg(args[n], XmNy, 10); n++; XtSetArg(args[n], XmNwidth, 400); n++; XtSetArg(args[n], XmNheight, 80); n++; XtSetArg(args[n], XmNeditable, False); n++; widget = XmCreateText(work, "FileMemo", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 160); n++; XtSetArg(args[n], XmNy, 95); n++; XtSetArg(args[n], XmNwidth, 400); n++; XtSetArg(args[n], XmNeditable, True); n++; widget = XmCreateText(work, "Jobname", args, n); XtManageChild(widget); XmStringFree(xmsmax); XmStringFree(xmsempty); break; } case ID_FILEMANAGER_UPDATE_ROWS_COLUMNS: { int n; Arg args[1]; Widget widget; char buffer[32]; XmString xms; const int rows = GetRows(); const int columns = GetColumns(); widget = XtNameToWidget(work, "rows"); sprintf(buffer,"%d", rows); xms = XmStringCreateSimple(buffer); n = 0; XtSetArg(args[n], XmNlabelString, xms); n++; XtSetValues(widget, args, n); XmStringFree(xms); n = 0; widget = XtNameToWidget(work, "columns"); sprintf(buffer,"%d", columns); xms = XmStringCreateSimple(buffer); XtSetArg(args[n], XmNlabelString, xms); n++; XtSetValues(widget, args, n); XmStringFree(xms); break; } case ID_FILEMANAGER_SET_JOBNAME: { int n = 0; Arg args[1]; char* jobname = (char*)call_data; Widget widget = XtNameToWidget(work, "Jobname"); XtSetArg(args[n], XmNvalue, jobname); n++; XtSetValues(widget, args, n); break; } case ID_FILEMANAGER_SET_FILEMEMO: { int n = 0; Arg args[1]; char* filememo = (char*)call_data; Widget widget = XtNameToWidget(work, "FileMemo"); XtSetArg(args[n], XmNvalue, filememo); n++; XtSetValues(widget, args, n); break; } } } static void Filter(Widget w, XtPointer client_data, XtPointer call_data) { int* which = (int*) client_data; static int* use = NULL; static int useRows = 0; static Widget page = NULL; switch (*which) { case ID_FILTER_INIT: { Arg args[6]; int n; Widget widget, frame; XmString xms; static int apply_command = ID_FILTER_APPLY; static int accept_command = ID_FILTER_ACCEPT; page = w; n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 33); n++; widget = XmCreateToggleButton(page, "% Present >=", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 160); n++; XtSetArg(args[n], XmNy, 30); n++; XtSetArg(args[n], XmNwidth, 80); n++; XtSetArg(args[n], XmNvalue, "80"); n++; widget = XmCreateText(page, "FilterPercent", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 73); n++; widget = XmCreateToggleButton(page, "SD (Gene Vector)", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 160); n++; XtSetArg(args[n], XmNy, 70); n++; XtSetArg(args[n], XmNwidth, 80); n++; XtSetArg(args[n], XmNvalue, "2.0"); n++; widget = XmCreateText(page, "FilterStd", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 113); n++; widget = XmCreateToggleButton(page, "At least", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 97); n++; XtSetArg(args[n], XmNy, 110); n++; XtSetArg(args[n], XmNwidth, 50); n++; XtSetArg(args[n], XmNvalue, "1"); n++; widget = XmCreateText(page, "FilterNumber", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 150); n++; XtSetArg(args[n], XmNy, 117); n++; widget = XmCreateLabel(page, "observations with abs(Val) >=", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 340); n++; XtSetArg(args[n], XmNy, 110); n++; XtSetArg(args[n], XmNwidth, 80); n++; XtSetArg(args[n], XmNvalue, "2.0"); n++; widget = XmCreateText(page, "FilterObservationValue", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 153); n++; widget = XmCreateToggleButton(page, "MaxVal - MinVal >=", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 160); n++; XtSetArg(args[n], XmNy, 150); n++; XtSetArg(args[n], XmNwidth, 80); n++; XtSetArg(args[n], XmNvalue, "2.0"); n++; widget = XmCreateText(page, "FilterMaxMin", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 240); n++; XtSetArg(args[n], XmNy, 190); n++; widget = XmCreatePushButton(page, "Apply Filter", args, n); XtManageChild(widget); XtAddCallback(widget, XmNactivateCallback, Filter, (XtPointer)&apply_command); n = 0; XtSetArg(args[n], XmNx, 237); n++; XtSetArg(args[n], XmNy, 245); n++; XtSetArg(args[n], XmNsensitive, False); n++; widget = XmCreatePushButton(page, "Accept Filter", args, n); XtManageChild(widget); XtAddCallback(widget, XmNactivateCallback, Filter, (XtPointer)&accept_command); n = 0; XtSetArg(args[n], XmNx, 80); n++; XtSetArg(args[n], XmNy, 220); n++; XtSetArg(args[n], XmNwidth, 400); n++; XtSetArg(args[n], XmNheight, 20); n++; xms = XmStringCreateSimple(""); XtSetArg(args[n], XmNlabelString, xms); n++; XtSetArg(args[n], XmNrecomputeSize, False); n++; widget = XmCreateLabel(page, "FilterResult", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNwidth, 500); n++; XtSetArg(args[n], XmNheight, 270); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Filter Genes"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(frame, NULL, args, n); XtManageChild(widget); XmStringFree(xms); break; } case ID_FILTER_APPLY: { /* Filter data. Apply user selected criteria to flag (for subsequent * removal) rows that fail to pass tests. Note that filters are * assessed here and applied separately so the user can adjust * parameters to get appropriate number of rows passing */ Boolean bStd, bPercent, bAbsVal, bMaxMin; Widget label, button, textfield; Arg args[1]; int n = 0; const int Rows = GetRows(); char buffer[128]; char* text; char* errorchar; double value; double absVal, percent, std; int numberAbs; double maxmin; int Row; int command = ID_FILTER_RESET; XmString xms = XmStringGenerate("result", XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, NULL); label = XtNameToWidget(page,"FilterResult"); XtSetArg(args[n], XmNlabelString, xms); n++; XtSetValues(label, args, n); XmStringFree(xms); button = XtNameToWidget(page,"Accept Filter"); XtSetSensitive(button, True); button = XtNameToWidget(page,"SD (Gene Vector)"); bStd = XmToggleButtonGetState(button); button = XtNameToWidget(page,"% Present >="); bPercent = XmToggleButtonGetState(button); button = XtNameToWidget(page,"At least"); bAbsVal = XmToggleButtonGetState(button); button = XtNameToWidget(page,"MaxVal - MinVal >="); bMaxMin = XmToggleButtonGetState(button); /* Read information from the edit boxes */ textfield = XtNameToWidget(page,"FilterObservationValue"); text = XmTextGetString(textfield); value = strtod(text, &errorchar); absVal = (*errorchar==0) ? value : 0; XtFree(text); textfield = XtNameToWidget(page,"FilterPercent"); text = XmTextGetString(textfield); value = strtod(text, &errorchar); percent = (*errorchar==0) ? value : 0; XtFree(text); textfield = XtNameToWidget(page,"FilterStd"); text = XmTextGetString(textfield); value = strtod(text, &errorchar); std = (*errorchar==0) ? value : 0; XtFree(text); numberAbs = GetWidgetItemInt(page, "FilterNumber"); textfield = XtNameToWidget(page,"FilterMaxMin"); text = XmTextGetString(textfield); value = strtod(text, &errorchar); maxmin = (*errorchar==0) ? value : 0; XtFree(text); Filter(page, (XtPointer)&command, NULL); /* Store results in boolean use */ if (use) free(use); use = malloc(Rows*sizeof(int)); if (!use) { Statusbar(NULL, "Memory allocation failure"); return; } useRows = 0; for (Row = 0; Row < Rows; Row++) { sprintf(buffer, "Assessing filters for gene %d", Row); Statusbar(NULL, buffer); use[Row] = FilterRow(Row, bStd, bPercent, bAbsVal, bMaxMin, absVal, percent, std, numberAbs, maxmin); /* Count how many passed */ if (use[Row]) useRows++; } /* Tell user how many rows passed */ sprintf(buffer, "%d passed out of %d", useRows, Rows); xms = XmStringCreateSimple(buffer); label = XtNameToWidget(page, "FilterResult"); n = 0; XtSetArg(args[n], XmNlabelString, xms); n++; XtSetValues(label, args, n); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNsensitive, True); n++; button = XtNameToWidget(page, "Accept Filter"); XtSetValues(button, args, n); Statusbar(NULL, "Done Analyzing Filters"); break; } case ID_FILTER_ACCEPT: { /* Accept results of last filtering */ int update; int ok; XtSetSensitive(w, False); ok = SelectSubset(useRows, use); if (!ok) { ShowError(w, "Insufficient memory", "Failed to apply filtering"); Statusbar(NULL, "Filtering failed"); return; } update = ID_FILEMANAGER_UPDATE_ROWS_COLUMNS; FileManager(NULL, (XtPointer)&update, NULL); update = ID_SOM_UPDATE; SOM(w, (XtPointer)&update, NULL); break; } case ID_FILTER_RESET: { Arg args[1]; int n; Widget widget; XmString xms; n = 0; xms = XmStringCreateSimple(""); widget = XtNameToWidget(page, "FilterResult"); XtSetArg(args[n], XmNlabelString, xms); n++; XtSetValues(widget, args, n); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNsensitive, False); n++; widget = XtNameToWidget(page, "Accept Filter"); XtSetValues(widget, args, n); break; } case ID_FILTER_FREE: { if (use) free(use); break; } } } static void SwitchEnableDisable(Widget w, XtPointer client_data, XtPointer call_data) { const char* name = XtName(w); Widget box = NULL; Widget mean = NULL; Widget median = NULL; Widget page = XtParent(w); XmToggleButtonCallbackStruct* tbs = (XmToggleButtonCallbackStruct*) call_data; if (strcmp(name,"CenterGenes")==0) { box = XtNameToWidget(page,"CenterGenesBox"); mean = XtNameToWidget(box, "AdjustMeanGenes"); median = XtNameToWidget(box, "AdjustMedianGenes"); } else if (strcmp(name,"CenterArrays")==0) { box = XtNameToWidget(page,"CenterArraysBox"); mean = XtNameToWidget(box, "AdjustMeanArrays"); median = XtNameToWidget(box, "AdjustMedianArrays"); } else return; /* never get here */ if (tbs->set == XmUNSET) { XtSetSensitive(box, True); if (!XmToggleButtonGetState(mean) && !XmToggleButtonGetState(median)) XmToggleButtonSetState(mean,True,False); } else XtSetSensitive(box, False); } static void Adjust(Widget w, XtPointer client_data, XtPointer call_data) { static Widget page = 0; int* which = (int*) client_data; switch (*which) { case ID_ADJUST_INIT: { Arg args[6]; int n; Widget widget, frame, box; static int command = ID_ADJUST_EXECUTE; XmString xms; page = w; n = 0; XtSetArg(args[n], XmNx, 30); n++; XtSetArg(args[n], XmNy, 45); n++; widget = XmCreateToggleButton(page, "Log transform data", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 43); n++; XtSetArg(args[n], XmNwidth, 420); n++; XtSetArg(args[n], XmNheight, 28); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; xms = XmStringCreateSimple("Center genes"); XtSetArg(args[n], XmNx, 30); n++; XtSetArg(args[n], XmNy, 87); n++; XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateToggleButton(page, "CenterGenes", args, n); XtManageChild(widget); XmStringFree(xms); XtAddCallback(widget, XmNarmCallback, SwitchEnableDisable, NULL); n = 0; XtSetArg(args[n], XmNx, 40); n++; XtSetArg(args[n], XmNy, 110); n++; XtSetArg(args[n], XmNsensitive, False); n++; box = XmCreateRadioBox(page, "CenterGenesBox", args, n); XtManageChild(box); n = 0; xms = XmStringCreateSimple("Mean"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateToggleButton(box, "AdjustMeanGenes", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; xms = XmStringCreateSimple("Median"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateToggleButton(box, "AdjustMedianGenes", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; xms = XmStringCreateSimple("Normalize genes"); XtSetArg(args[n], XmNx, 30); n++; XtSetArg(args[n], XmNy, 169); n++; XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateToggleButton(page, "AdjustNormalizeGenes", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 85); n++; XtSetArg(args[n], XmNwidth, 200); n++; XtSetArg(args[n], XmNheight, 110); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "", args, n); XtManageChild(frame); n = 0; xms = XmStringCreateSimple("Center arrays"); XtSetArg(args[n], XmNx,250); n++; XtSetArg(args[n], XmNy, 87); n++; XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateToggleButton(page, "CenterArrays", args, n); XtManageChild(widget); XmStringFree(xms); XtAddCallback(widget, XmNarmCallback, SwitchEnableDisable, NULL); n = 0; XtSetArg(args[n], XmNx,260); n++; XtSetArg(args[n], XmNy, 110); n++; XtSetArg(args[n], XmNsensitive, False); n++; box = XmCreateRadioBox(page, "CenterArraysBox", args, n); XtManageChild(box); n = 0; xms = XmStringCreateSimple("Mean"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateToggleButton(box, "AdjustMeanArrays", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; xms = XmStringCreateSimple("Median"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateToggleButton(box, "AdjustMedianArrays", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; xms = XmStringCreateSimple("Normalize arrays"); XtSetArg(args[n], XmNx, 250); n++; XtSetArg(args[n], XmNy, 169); n++; XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateToggleButton(page, "AdjustNormalizeArrays", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx,240); n++; XtSetArg(args[n], XmNy, 85); n++; XtSetArg(args[n], XmNwidth, 200); n++; XtSetArg(args[n], XmNheight, 110); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 210); n++; XtSetArg(args[n], XmNwidth, 200); n++; XtSetArg(args[n], XmNheight, 110); n++; XtSetArg(args[n], XmNeditable, False); n++; XtSetArg(args[n], XmNvalue, "Order of Operations\n\nLog Transform\nCenter Genes\nNormalize Genes\nCenter Arrays\nNormalize Arrays"); n++; widget = XmCreateText(page, "", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 340); n++; XtSetArg(args[n], XmNy, 210); n++; widget = XmCreatePushButton(page, "Apply", args, n); XtManageChild(widget); XtAddCallback(widget, XmNactivateCallback, Adjust, (XtPointer)&command); n = 0; XtSetArg(args[n], XmNwidth, 440); n++; XtSetArg(args[n], XmNheight, 320); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Adjust Data"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(frame, NULL, args, n); XtManageChild(widget); XmStringFree(xms); break; } case ID_ADJUST_EXECUTE: { int ok; int bLogTransform; int GeneMeanCenter = False; int GeneMedianCenter = False; int GeneNormalize; int ArrayMeanCenter = False; int ArrayMedianCenter = False; int ArrayNormalize; Widget button; Statusbar(NULL, "Adjusting data"); button = XtNameToWidget(page,"Log transform data"); bLogTransform = XmToggleButtonGetState(button); if (bLogTransform) LogTransform(); button = XtNameToWidget(page, "CenterGenes"); if (XmToggleButtonGetState(button)) { Widget box = XtNameToWidget(page, "CenterGenesBox"); button = XtNameToWidget(box, "AdjustMeanGenes"); GeneMeanCenter = XmToggleButtonGetState(button); button = XtNameToWidget(box, "AdjustMedianGenes"); GeneMedianCenter = XmToggleButtonGetState(button); } button = XtNameToWidget(page,"AdjustNormalizeGenes"); GeneNormalize = XmToggleButtonGetState(button); ok = AdjustGenes(GeneMeanCenter, GeneMedianCenter, GeneNormalize); if (!ok) { ShowError(w, "Memory allocation error", "Insufficient memory"); Statusbar(NULL, "Memory allocation error"); return; } button = XtNameToWidget(page, "CenterArrays"); if (XmToggleButtonGetState(button)) { Widget box = XtNameToWidget(page, "CenterArraysBox"); button = XtNameToWidget(box, "AdjustMeanArrays"); ArrayMeanCenter = XmToggleButtonGetState(button); button = XtNameToWidget(box, "AdjustMedianArrays"); ArrayMedianCenter = XmToggleButtonGetState(button); } button = XtNameToWidget(page, "AdjustNormalizeArrays"); ArrayNormalize = XmToggleButtonGetState(button); ok = AdjustArrays(ArrayMeanCenter, ArrayMedianCenter, ArrayNormalize); if (!ok) { ShowError(w, "Memory allocation error", "Insufficient memory"); Statusbar(NULL, "Memory allocation error"); return; } Statusbar(NULL, "Done adjusting data"); break; } } } static void SwitchGeneWeight(Widget w, XtPointer client_data, XtPointer call_data) { Widget page = XtParent(w); XmToggleButtonCallbackStruct* tbs = (XmToggleButtonCallbackStruct*) call_data; Widget widget = XtNameToWidget(page,"GeneWeight"); if (tbs->set == XmUNSET) XtManageChild(widget); else XtUnmanageChild(widget); } static void SwitchArrayWeight(Widget w, XtPointer client_data, XtPointer call_data) { Widget page = XtParent(w); XmToggleButtonCallbackStruct* tbs = (XmToggleButtonCallbackStruct*) call_data; Widget widget = XtNameToWidget(page,"ArrayWeight"); if (tbs->set == XmUNSET) XtManageChild(widget); else XtUnmanageChild(widget); } static void KMeans(Widget w, XtPointer client_data, XtPointer call_data) { static Widget page = NULL; int* which = (int*) client_data; switch (*which) { case ID_KMEANS_INIT: { Arg args[5]; int n; Widget widget, frame, GeneMethod, ArrayMethod; XmString xms; static int command = ID_KMEANS_EXECUTE; page = w; n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 40); n++; widget = XmCreateToggleButton(page, "Organize genes", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 70); n++; XtSetArg(args[n], XmNwidth, 80); n++; XtSetArg(args[n], XmNvalue, "10"); n++; widget = XmCreateText(page, "KMeansGeneK", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 105); n++; XtSetArg(args[n], XmNy, 76); n++; widget = XmCreateLabel(page, "number of clusters (k)", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 145); n++; XtSetArg(args[n], XmNy, 116); n++; widget = XmCreateLabel(page, "number of runs", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 110); n++; XtSetArg(args[n], XmNwidth, 120); n++; XtSetArg(args[n], XmNvalue, "100"); n++; widget = XmCreateText(page, "KMeansGeneRuns", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 150); n++; XtSetArg(args[n], XmNwidth, 130); n++; XtSetArg(args[n], XmNheight, 80); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "GeneMethodFrame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; widget = XmCreateLabel(frame, "Method", args, n); XtManageChild(widget); n = 0; GeneMethod = XmCreateRadioBox(frame, "GeneMethod", args, n); XtManageChild(GeneMethod); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 20); n++; XtSetArg(args[n], XmNset, XmSET); n++; widget = XmCreateToggleButton(GeneMethod, "k-Means", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 40); n++; widget = XmCreateToggleButton(GeneMethod, "k-Medians", args, n); XtManageChild(widget); CreateMetricComboBox(page, 20, 240, "GeneMetric", 'e'); n = 0; XtSetArg(args[n], XmNwidth, 255); n++; XtSetArg(args[n], XmNheight, 295); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Genes"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(frame, NULL, args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 40); n++; widget = XmCreateToggleButton(page, "Organize arrays", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 70); n++; XtSetArg(args[n], XmNwidth, 80); n++; XtSetArg(args[n], XmNvalue, "10"); n++; widget = XmCreateText(page, "KMeansArrayK", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 375); n++; XtSetArg(args[n], XmNy, 76); n++; widget = XmCreateLabel(page, "number of clusters (k)", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 415); n++; XtSetArg(args[n], XmNy, 116); n++; widget = XmCreateLabel(page, "number of runs", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 110); n++; XtSetArg(args[n], XmNwidth, 120); n++; XtSetArg(args[n], XmNvalue, "100"); n++; widget = XmCreateText(page, "KMeansArrayRuns", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 150); n++; XtSetArg(args[n], XmNwidth, 130); n++; XtSetArg(args[n], XmNheight, 80); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "ArrayMethodFrame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; widget = XmCreateLabel(frame, "Method", args, n); XtManageChild(widget); n = 0; ArrayMethod = XmCreateRadioBox(frame, "ArrayMethod", args, n); XtManageChild(ArrayMethod); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 20); n++; XtSetArg(args[n], XmNset, XmSET); n++; widget = XmCreateToggleButton(ArrayMethod, "k-Means", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 40); n++; widget = XmCreateToggleButton(ArrayMethod, "k-Medians", args, n); XtManageChild(widget); CreateMetricComboBox(page, 290, 240, "ArrayMetric", 'e'); n = 0; XtSetArg(args[n], XmNx, 280); n++; XtSetArg(args[n], XmNwidth, 255); n++; XtSetArg(args[n], XmNheight, 295); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Arrays"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(frame, NULL, args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 245); n++; XtSetArg(args[n], XmNy, 315); n++; widget = XmCreatePushButton(page, "Execute", args, n); XtManageChild(widget); XtAddCallback(widget, XmNactivateCallback, KMeans, (XtPointer)&command); break; } case ID_KMEANS_EXECUTE: { const int Rows = GetRows(); const int Columns = GetColumns(); int n; int ok; char* path; char* filetag; FILE* outputfile; Boolean ClusterGenes; Boolean ClusterArrays; int kGenes = 0; int kArrays = 0; Widget widget, button; Widget notebook = XtParent(page); Widget work = XtParent(notebook); if (Rows==0 || Columns==0) { Statusbar(NULL, "No data available"); return; } button = XtNameToWidget(page,"Organize genes"); ClusterGenes = XmToggleButtonGetState(button); button = XtNameToWidget(page,"Organize arrays"); ClusterArrays = XmToggleButtonGetState(button); if (!ClusterGenes && !ClusterArrays) return; /* Nothing to do */ path = GetBaseName(work); if (!path) { Statusbar(NULL, "Memory allocation failure"); return; } n = strlen(path) + strlen("_K") + strlen(".ext") + 1; /* .ext represents the extension (kgg, kag, or cdt) */ if (ClusterGenes) { int dummy; kGenes = GetWidgetItemInt(page, "KMeansGeneK"); if (kGenes==0) { Statusbar(NULL, "Choose a nonzero number of clusters"); return; } if (Rows < kGenes) { Statusbar(NULL, "More clusters than genes available"); return; } n += strlen("_G"); dummy = kGenes; do n++; while (dummy/=10); } if (ClusterArrays) { int dummy; kArrays = GetWidgetItemInt(page, "KMeansArrayK"); if (kArrays==0) { Statusbar(NULL, "Choose a nonzero number of clusters"); return; } if (Columns < kArrays) { Statusbar(NULL, "More clusters than arrays available"); return; } n += strlen("_A"); dummy = kArrays; do n++; while (dummy/=10); } path = realloc(path, n*sizeof(char)); filetag = strchr(path,'\0'); Statusbar(NULL, "Executing k-means clustering"); if (ClusterGenes) { char method; char dist; int* NodeMap; int nTrials; int ifound; char buffer[256]; Widget frame = XtNameToWidget(page,"GeneMethodFrame"); widget = XtNameToWidget(frame, "GeneMethod"); button = XtNameToWidget(widget, "k-Means"); method = XmToggleButtonGetState(button) ? 'a' : 'm'; /* 'a' is average (mean), 'm' is median */ widget = XtNameToWidget(page,"GeneMetric"); dist = GetMetric(widget); NodeMap = malloc(Rows*sizeof(int)); if (!NodeMap) { Statusbar(NULL, "Memory allocation failure"); free(path); return; } nTrials = GetWidgetItemInt(page, "KMeansGeneRuns"); ifound = GeneKCluster(kGenes, nTrials, method, dist, NodeMap); if (ifound < 0) { Statusbar(NULL, "Memory allocation failure"); free(path); return; } sprintf(buffer, "Solution was found %d times", ifound); Statusbar(NULL, buffer); sprintf(filetag, "_K_G%d.kgg", kGenes); outputfile = fopen(path, "wt"); if (!outputfile) { Statusbar(NULL, "Error: Unable to open the output file"); free(NodeMap); free(path); return; } ok = SaveGeneKCluster(outputfile, kGenes, NodeMap); fclose(outputfile); free(NodeMap); if (!ok) { Statusbar(NULL, "Error: Failed to allocate memory while saving"); free(path); return; } } if (ClusterArrays) { char method; char dist; int* NodeMap; int nTrials; int ifound; char buffer[256]; Widget frame = XtNameToWidget(page,"ArrayMethodFrame"); widget = XtNameToWidget(frame, "ArrayMethod"); button = XtNameToWidget(widget, "k-Means"); method = XmToggleButtonGetState(button) ? 'a' : 'm'; /* 'a' is average, 'm' is median */ widget = XtNameToWidget(page,"ArrayMetric"); dist = GetMetric(widget); NodeMap = malloc(Columns*sizeof(int)); if (!NodeMap) { Statusbar(NULL, "Memory allocation failure"); free(path); return; } nTrials = GetWidgetItemInt(page, "KMeansArrayRuns"); ifound = ArrayKCluster(kArrays, nTrials, method, dist, NodeMap); if (ifound < 0) { Statusbar(NULL, "Memory allocation failure"); free(path); return; } sprintf(buffer, "Solution was found %d times", ifound); Statusbar(NULL, buffer); sprintf(filetag, "_K_A%d.kag", kArrays); outputfile = fopen(path, "wt"); if (!outputfile) { Statusbar(NULL, "Error: Unable to open the output file"); free(NodeMap); free(path); return; } ok = SaveArrayKCluster(outputfile, kArrays, NodeMap); fclose(outputfile); free(NodeMap); if (!ok) { Statusbar(NULL, "Error: Failed to allocate memory while saving"); free(path); return; } } /* Now write the data file */ filetag += sprintf(filetag, "_K"); if (ClusterGenes) filetag += sprintf(filetag, "_G%d", kGenes); if (ClusterArrays) filetag += sprintf(filetag, "_A%d", kArrays); sprintf(filetag,".cdt"); outputfile = fopen(path, "wt"); free(path); if (!outputfile) { Statusbar(NULL, "Error: Unable to open the output file"); return; } ok = Save(outputfile, 0, 0); fclose(outputfile); if (ok) Statusbar(NULL, "Done clustering"); else { ShowError(w, "Error saving file", "Insufficient memory"); Statusbar(NULL, "Error saving to file"); } break; } } } static void PCA(Widget w, XtPointer client_data, XtPointer call_data) { static Widget page = NULL; int* which = (int*) client_data; switch (*which) { case ID_PCA_INIT: { Arg args[5]; int n; Widget widget, frame; XmString xms; static int command = ID_PCA_EXECUTE; page = w; n = 0; XtSetArg(args[n], XmNx, 180); n++; widget = XmCreateLabel(page, "Principal Component Analysis", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 70); n++; widget = XmCreateToggleButton(page, "Apply PCA to genes", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNy, 30); n++; XtSetArg(args[n], XmNwidth, 255); n++; XtSetArg(args[n], XmNheight, 275); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Genes"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(frame, NULL, args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 70); n++; widget = XmCreateToggleButton(page, "Apply PCA to arrays", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 280); n++; XtSetArg(args[n], XmNy, 30); n++; XtSetArg(args[n], XmNwidth, 255); n++; XtSetArg(args[n], XmNheight, 275); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Arrays"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(frame, NULL, args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 240); n++; XtSetArg(args[n], XmNy, 315); n++; widget = XmCreatePushButton(page, "Execute", args, n); XtManageChild(widget); XtAddCallback(widget, XmNactivateCallback, PCA, (XtPointer)&command); break; } case ID_PCA_EXECUTE: { Boolean DoGenePCA; Boolean DoArrayPCA; Widget button; const char* error; const int Rows = GetRows(); const int Columns = GetColumns(); char* base; char* path = NULL; char* extension; FILE* coordinatefile; FILE* pcfile; Widget notebook = XtParent(page); Widget work = XtParent(notebook); button = XtNameToWidget(page, "Apply PCA to genes"); DoGenePCA = XmToggleButtonGetState(button); button = XtNameToWidget(page, "Apply PCA to arrays"); DoArrayPCA = XmToggleButtonGetState(button); if (Rows==0 || Columns==0) { Statusbar(NULL, "No data available"); return; } base = GetBaseName(work); if (base) path = realloc(base, strlen(base)+strlen("_pca_array.coords.txt")); if (!path) { Statusbar(NULL, "Memory allocation failure"); if (base) free(base); return; } extension = strchr(path, '\0'); if (DoGenePCA) { Statusbar(NULL, "Calculating PCA"); sprintf(extension, "_pca_gene.coords.txt"); coordinatefile = fopen(path, "wt"); sprintf(extension, "_pca_gene.pc.txt"); pcfile = fopen(path, "wt"); if (!coordinatefile || !pcfile) { Statusbar(NULL, "Error: Unable to open the output file"); if (coordinatefile) fclose(coordinatefile); if (pcfile) fclose(pcfile); free(path); return; } error = PerformGenePCA(coordinatefile, pcfile); fclose(coordinatefile); fclose(pcfile); if (error) { ShowError(w, error, "Error"); free(path); return; } Statusbar(NULL, "Finished Principal Component Analysis"); } if (DoArrayPCA) { Statusbar(NULL, "Calculating PCA"); sprintf(extension, "_pca_array.coords.txt"); coordinatefile = fopen(path, "wt"); sprintf(extension, "_pca_array.pc.txt"); pcfile = fopen(path, "wt"); if (!coordinatefile || !pcfile) { Statusbar(NULL, "Error: Unable to open the output file"); if (coordinatefile) fclose(coordinatefile); if (pcfile) fclose(pcfile); free(path); return; } error = PerformArrayPCA(coordinatefile, pcfile); fclose(coordinatefile); fclose(pcfile); if (error) { ShowError(w, error, "Error"); free(path); return; } Statusbar(NULL, "Finished Principal Component Analysis"); } free(path); break; } } } /*============================================================================*/ /* Callback functions --- Main dialog window */ /*============================================================================*/ static void OpenFile(Widget w, XtPointer client_data, XtPointer call_data) { char* filename = NULL; char** directory = (char**)client_data; char* result; struct stat filestat; FILE* inputfile; XmFileSelectionBoxCallbackStruct* cbs; XtUnmanageChild(w); cbs = (XmFileSelectionBoxCallbackStruct*) call_data; if (!cbs) return; filename = (char*)XmStringUnparse(cbs->value, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); if (!filename) return; if (stat(filename, &filestat) || S_ISDIR(filestat.st_mode)) { XtFree(filename); return; } /* Save the directory name based on the file name */ if (*directory) free(*directory); *directory = (char*)XmStringUnparse(cbs->dir, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); /* Open the file */ inputfile = fopen(filename, "rt"); if (!inputfile) Statusbar(NULL,"Error opening file"); /* Read file */ result = Load(inputfile); fclose(inputfile); if (result && strcmp(result, "ok")==0) { /* Extract job name from file name */ int command; char* jobname = strrchr(filename,'/') + 1; char* extension = strrchr(jobname,'.'); command = ID_FILEMANAGER_SET_FILEMEMO; FileManager(NULL, (XtPointer)&command, filename); if (extension) *extension = '\0'; command = ID_FILEMANAGER_SET_JOBNAME; FileManager(NULL, (XtPointer)&command, jobname); command = ID_FILEMANAGER_UPDATE_ROWS_COLUMNS; FileManager(NULL, (XtPointer)&command, NULL); command = ID_FILTER_RESET; Filter(NULL, (XtPointer)&command, NULL); command = ID_SOM_UPDATE; SOM(w, (XtPointer)&command, NULL); Statusbar(NULL, "Done loading data"); } else { char buffer[256]; int command; if (result) { ShowError(w, result, "Error in data file"); free(result); } else ShowError(w, "Insufficient memory", "Error reading file"); sprintf(buffer, "Error reading file %s", filename); Statusbar(NULL, buffer); command = ID_FILEMANAGER_SET_FILEMEMO; FileManager(NULL, (XtPointer)&command, ""); command = ID_FILEMANAGER_SET_JOBNAME; FileManager(NULL, (XtPointer)&command, ""); command = ID_FILEMANAGER_UPDATE_ROWS_COLUMNS; FileManager(NULL, (XtPointer)&command, NULL); } XtFree(filename); } static void SaveFile(Widget w, XtPointer client_data, XtPointer call_data) { int ok; char* filename = NULL; struct stat filestat; XmFileSelectionBoxCallbackStruct* cbs = NULL; FILE* outputfile; char** directory = (char**)client_data; XtUnmanageChild(w); cbs = (XmFileSelectionBoxCallbackStruct*) call_data; if (!cbs) return; filename = (char*)XmStringUnparse(cbs->value, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); if (*directory) free(*directory); *directory = (char*)XmStringUnparse(cbs->dir, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); if (!stat(filename, &filestat) && S_ISDIR(filestat.st_mode)) { Statusbar(NULL, "Error saving file: Directory selected"); return; } /* Save the data to file */ outputfile = fopen(filename, "wt"); free(filename); if (!outputfile) { Statusbar(NULL, "Error: Unable to open the output file"); return; } ok = Save(outputfile, 0, 0); fclose(outputfile); if (ok) Statusbar(NULL, "Finished saving file"); else { ShowError(w, "Insufficient memory", "Error saving file"), Statusbar(NULL, "Error saving to file"); } } static void Cancel(Widget w, XtPointer client_data, XtPointer call_data) { Statusbar(NULL, "Cancelled"); XtUnmanageChild(w); } /*============================================================================*/ /* Callback functions --- Menu */ /*============================================================================*/ static void MenuFile(Widget w, XtPointer client_data, XtPointer call_data) { static char* directory = NULL; int* which = (int*)client_data; switch (*which) { case CMD_FILE_OPEN: /* User will select a data file (*.txt) */ { Widget dialog, parent, widget; Arg args[4]; int n; XmString mask = XmStringCreateSimple("*.txt"); XmString title = XmStringCreateSimple("Select data file to open"); XmString initdir = XmStringCreateSimple(directory); n = 0; XtSetArg(args[n], XmNwidth, 300); n++; XtSetArg(args[n], XmNdirMask, mask); n++; XtSetArg(args[n], XmNdialogTitle, title); n++; XtSetArg(args[n], XmNdirectory, initdir); n++; parent = XtParent(w); dialog = XmCreateFileSelectionDialog(parent, "FileOpen", args, n); widget = XmSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON); XtUnmanageChild(widget); XmStringFree(mask); XmStringFree(title); XtAddCallback(dialog, XmNokCallback, OpenFile, &directory); XtAddCallback(dialog, XmNcancelCallback, Cancel, NULL); XtManageChild(dialog); Statusbar(NULL, "Opening file"); break; } case CMD_FILE_SAVE: { static Widget dialog = NULL; Arg args[4]; int n; char buffer[256]; XmString filename; Widget menubar = XtParent(XtParent(XtParent(w))); Widget main_w = XtParent(menubar); Widget work = XtNameToWidget(main_w,"work"); Widget widget = XtNameToWidget(work,"Jobname"); char* jobname = XmTextGetString(widget); sprintf(buffer,"%s.txt",jobname); XtFree(jobname); filename = XmStringCreateSimple(buffer); if (!dialog) { XmString mask = XmStringCreateSimple("*.txt"); XmString title = XmStringCreateSimple("Select file name to save to"); XmString initdir = XmStringCreateSimple(directory); n = 0; XtSetArg(args[n], XmNwidth, 300); n++; XtSetArg(args[n], XmNdirMask, mask); n++; XtSetArg(args[n], XmNdialogTitle, title); n++; XtSetArg(args[n], XmNdirectory, initdir); n++; dialog = XmCreateFileSelectionDialog(XtParent(w), "FileSave", args, n); XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON)); XmStringFree(mask); XmStringFree(title); XmStringFree(initdir); XtAddCallback(dialog, XmNokCallback, SaveFile, (XtPointer)&directory); XtAddCallback(dialog, XmNcancelCallback, Cancel, NULL); } n = 0; XtSetArg(args[n], XmNdirSpec, filename); n++; XtSetValues(dialog, args, n); XmStringFree(filename); XtManageChild(dialog); Statusbar(NULL, "Saving data to file"); break; } case CMD_FILE_QUIT: { int command; if (directory) free(directory); Free(); command = ID_FILTER_FREE; Filter(NULL, (XtPointer)&command, NULL); exit(0); break; } } return; } static void MenuHelp(Widget w, XtPointer client_data, XtPointer call_data) /* Note: In this function, PREFIX should be defined by a command line * definition. */ { int* item_no = (int*) client_data; switch (*item_no) { case CMD_HELP_HTMLHELP: { system("firefox "PREFIX"/cluster/html/index.html &"); break; } case CMD_HELP_MANUAL: { system("acroread "PREFIX"/cluster/doc/cluster3.pdf &"); break; } case CMD_HELP_DOWNLOAD: { system("firefox http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/manual/index.html &"); break; } case CMD_HELP_FILEFORMAT: { Arg args[6]; int n = 0; Widget dialog, widget; Pixmap pixmap; /* Text is split up for ANSI compliance */ char* helplines[12]; char* helptext; int nchars = 1; /* One for the final \0 */ XmString xms; helplines[0] = \ "The input for the clustering program is a tab-delimited text file.\n"; helplines[1] = \ "An example is shown below.\n\n"; helplines[2] = \ "The cells in red must appear in the file, although they can be any string.\n"; helplines[3] = \ "The cells in bold are headers for optional columns/rows.\n\n"; helplines[4] = \ "UNIQID: (string/number)\nThis column should contain unique identifiers for each gene.\n\n"; helplines[5] = \ "NAME: (string)\nA text description of each gene which will be used in display.\n\n"; helplines[6] = \ "EWEIGHT: (real number)\nA weight for each experiment that can be used to count certain experiments\nmore than others.\n\n"; helplines[7] = \ "GWEIGHT: (real number)\nA similar weight for each gene can be used when clustering arrays.\n\n"; helplines[8] = \ "GORDER: (real number)\nA value to be used for ordering nodes in display program\n\n"; helplines[9] = \ "EXPID: (string, e.g. EXP1, EXP2,...)\nA text description of each experiment that will be used in the display.\n\n"; helplines[10] = \ "DATA: (real number)\nData for a single gene in a single experiment. Any desired numerical transform\n"; helplines[11] = \ "(e.g. log) should be applied before clustering. Missing values are acceptable."; for (n=0; n<12; n++) nchars += strlen(helplines[n]); helptext = malloc(nchars*sizeof(char)); if (!helptext) { Statusbar(NULL, "Memory allocation failuere"); return; } helptext[0] = '\0'; for (n=0; n<12; n++) strcat(helptext, helplines[n]); n = 0; xms = XmStringCreateSimple("File Format"); XtSetArg(args[n], XmNdialogTitle, xms); n++; w = XtParent(w); dialog = XmCreateBulletinBoardDialog(w, "FileFormat", args, n); XtManageChild(dialog); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 60); n++; XtSetArg(args[n], XmNy, 10); n++; XtSetArg(args[n], XmNwidth, 500); n++; XtSetArg(args[n], XmNheight, 390); n++; XtSetArg(args[n], XmNeditable, False); n++; XtSetArg(args[n], XmNvalue, helptext); n++; widget = XmCreateText(dialog, "", args, n); XtManageChild(widget); free(helptext); n = 0; pixmap = XmGetPixmap(XtScreen(dialog),PREFIX"/cluster/format.xpm",0,0); XtSetArg(args[n], XmNx, 10); n++; XtSetArg(args[n], XmNy, 410); n++; XtSetArg(args[n],XmNlabelType, XmPIXMAP); n++; XtSetArg(args[n],XmNlabelPixmap, pixmap); n++; widget = XmCreateLabel(dialog, "LabelPixmap", args, n); XtManageChild(widget); break; } case CMD_HELP_ABOUT: { Arg args[3]; int n = 0; Widget dialog, widget; XmString xms = XmStringCreateSimple("About Cluster"); XtSetArg(args[n], XmNdialogTitle, xms); n++; w = XtParent(w); dialog = XmCreateBulletinBoardDialog(w, "About", args, n); XtManageChild(dialog); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 10); n++; XtSetArg(args[n], XmNy, 10); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; widget = XmCreateLabel(dialog, "Cluster 3.0\nusing the C Clustering Library version " CLUSTERVERSION ".\n\nCluster was originally written by Michael Eisen\n(eisen 'AT' rana.lbl.gov)\nCopyright 1998-99 Stanford University\n\nCluster version 3.0 for X11/Motif was created\nby Michiel de Hoon (mdehoon 'AT' gsc.riken.jp),\ntogether with Seiya Imoto and Satoru Miyano.\n\nType 'cluster --help' for information about\nrunning Cluster 3.0 as a command-line program.\n\nUniversity of Tokyo, Human Genome Center\nJune 2002", args, n); XtManageChild(widget); break; } } } static void Hierarchical(Widget w, XtPointer client_data, XtPointer call_data) { static Widget page = 0; int* which = (int*) client_data; switch (*which) { case ID_HIERARCHICAL_INIT: { Arg args[5]; int n; Widget widget, frame, geneweight, arrayweight; Widget GeneWeightPage, ArrayWeightPage; XmString xms; static int single_command = ID_HIERARCHICAL_SINGLE; static int complete_command = ID_HIERARCHICAL_COMPLETE; static int average_command = ID_HIERARCHICAL_AVERAGE; static int centroid_command = ID_HIERARCHICAL_CENTROID; page = w; n = 0; xms = XmStringCreateSimple("Cluster"); XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 40); n++; XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateToggleButton(page, "ClusterGenes", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; xms = XmStringCreateLocalized("Calculate\nweights"); XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 85); n++; XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateToggleButton(page, "CalculateGeneWeights", args, n); XtManageChild(widget); XmStringFree(xms); XtAddCallback(widget, XmNarmCallback, SwitchArrayWeight, NULL); CreateMetricComboBox(page, 20, 140, "GeneMetric", 'u'); n = 0; XtSetArg(args[n], XmNx, 120); n++; XtSetArg(args[n], XmNy, 30); n++; XtSetArg(args[n], XmNwidth, 130); n++; XtSetArg(args[n], XmNheight, 100); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; geneweight = XmCreateFrame(page, "GeneWeight", args, n); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Weight Options"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(geneweight,NULL,args,n); XtManageChild(widget); XmStringFree(xms); GeneWeightPage = XtCreateManagedWidget("GeneWeightPage",xmBulletinBoardWidgetClass,geneweight,NULL,0); n = 0; XtSetArg(args[n], XmNx, 10); n++; XtSetArg(args[n], XmNy, 16); n++; xms = XmStringCreateSimple("Cutoff"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(GeneWeightPage, "", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 55); n++; XtSetArg(args[n], XmNy, 10); n++; XtSetArg(args[n], XmNwidth, 65); n++; XtSetArg(args[n], XmNvalue, "0.1"); n++; widget = XmCreateText(GeneWeightPage, "GeneWeightCutoff", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 10); n++; XtSetArg(args[n], XmNy, 51); n++; xms = XmStringCreateSimple("Exponent"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(GeneWeightPage, "", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 70); n++; XtSetArg(args[n], XmNy, 45); n++; XtSetArg(args[n], XmNwidth, 50); n++; XtSetArg(args[n], XmNvalue, "1"); n++; widget = XmCreateText(GeneWeightPage, "GeneWeightExp", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNwidth, 255); n++; XtSetArg(args[n], XmNheight, 195); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Genes"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(frame,NULL,args,n); XtManageChild(widget); XmStringFree(xms); n = 0; xms = XmStringCreateSimple("Cluster"); XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 40); n++; XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateToggleButton(page, "ClusterArrays", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; xms = XmStringCreateLocalized("Calculate\nweights"); XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 85); n++; XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateToggleButton(page, "CalculateArrayWeights", args, n); XtAddCallback(widget, XmNarmCallback, SwitchGeneWeight, NULL); XmStringFree(xms); XtManageChild(widget); CreateMetricComboBox(page, 290, 140, "ArrayMetric", 'u'); n = 0; XtSetArg(args[n], XmNx, 390); n++; XtSetArg(args[n], XmNy, 30); n++; XtSetArg(args[n], XmNwidth, 130); n++; XtSetArg(args[n], XmNheight, 100); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; arrayweight = XmCreateFrame(page, "ArrayWeight", args, n); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Weight Options"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(arrayweight,NULL,args,n); XtManageChild(widget); XmStringFree(xms); ArrayWeightPage = XtCreateManagedWidget("ArrayWeightPage",xmBulletinBoardWidgetClass,arrayweight,NULL,0); n = 0; XtSetArg(args[n], XmNx, 10); n++; XtSetArg(args[n], XmNy, 16); n++; xms = XmStringCreateSimple("Cutoff"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(ArrayWeightPage, "", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 55); n++; XtSetArg(args[n], XmNy, 10); n++; XtSetArg(args[n], XmNwidth, 65); n++; XtSetArg(args[n], XmNvalue, "0.1"); n++; widget = XmCreateText(ArrayWeightPage, "ArrayWeightCutoff", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNx, 10); n++; XtSetArg(args[n], XmNy, 51); n++; xms = XmStringCreateSimple("Exponent"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(ArrayWeightPage, "", args, n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 70); n++; XtSetArg(args[n], XmNy, 45); n++; XtSetArg(args[n], XmNwidth, 50); n++; XtSetArg(args[n], XmNvalue, "1"); n++; widget = XmCreateText(ArrayWeightPage, "ArrayWeightExp", args, n); XtManageChild(widget); n = 0; XtSetArg(args[n], XmNwidth, 255); n++; XtSetArg(args[n], XmNheight, 195); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNx, 280); n++; XtSetArg(args[n], XmNwidth, 255); n++; XtSetArg(args[n], XmNheight, 195); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Arrays"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(frame,NULL,args,n); XtManageChild(widget); XmStringFree(xms); n = 0; XtSetArg(args[n], XmNx, 20); n++; XtSetArg(args[n], XmNy, 243); n++; widget = XmCreatePushButton(page, "Centroid linkage", args, n); XtManageChild(widget); XtAddCallback(widget, XmNactivateCallback, Hierarchical, (XtPointer)¢roid_command); n = 0; XtSetArg(args[n], XmNx, 160); n++; XtSetArg(args[n], XmNy, 243); n++; widget = XmCreatePushButton(page, "Single linkage", args, n); XtManageChild(widget); XtAddCallback(widget, XmNactivateCallback, Hierarchical, (XtPointer)&single_command); n = 0; XtSetArg(args[n], XmNx, 290); n++; XtSetArg(args[n], XmNy, 243); n++; widget = XmCreatePushButton(page, "Complete Linkage", args, n); XtManageChild(widget); XtAddCallback(widget, XmNactivateCallback, Hierarchical, (XtPointer)&complete_command); n = 0; XtSetArg(args[n], XmNx, 425); n++; XtSetArg(args[n], XmNy, 243); n++; widget = XmCreatePushButton(page, "Average Linkage", args, n); XtManageChild(widget); XtAddCallback(widget, XmNactivateCallback, Hierarchical, (XtPointer)&average_command); n = 0; XtSetArg(args[n], XmNx, 10); n++; XtSetArg(args[n], XmNy, 215); n++; XtSetArg(args[n], XmNwidth, 525); n++; XtSetArg(args[n], XmNheight, 70); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++; frame = XmCreateFrame(page, "Frame", args, n); XtManageChild(frame); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; xms = XmStringCreateSimple("Clustering method"); XtSetArg(args[n], XmNlabelString, xms); n++; widget = XmCreateLabel(frame,NULL,args,n); XtManageChild(widget); XmStringFree(xms); break; } case ID_HIERARCHICAL_CENTROID: case ID_HIERARCHICAL_SINGLE: case ID_HIERARCHICAL_COMPLETE: case ID_HIERARCHICAL_AVERAGE: { Widget widget, button; char method = 'e'; /* So the compiler won't complain about method * not being initialized */ int ok; const int Rows = GetRows(); const int Columns = GetColumns(); Boolean ClusterGenes; Boolean ClusterArrays; Boolean bCalculateGeneWeights; Boolean bCalculateArrayWeights; char genemetric; char arraymetric; char* path; char* extension; FILE* outputfile; Widget notebook = XtParent(page); Widget work = XtParent(notebook); if (Rows==0 || Columns==0) { Statusbar(NULL, "No data available"); return; } /* Find out what we need to do here */ button = XtNameToWidget(page,"ClusterGenes"); ClusterGenes = XmToggleButtonGetState(button); button = XtNameToWidget(page,"ClusterArrays"); ClusterArrays = XmToggleButtonGetState(button); if (!ClusterGenes && !ClusterArrays) return; /* Nothing to do here */ button = XtNameToWidget(page,"CalculateGeneWeights"); bCalculateGeneWeights = XmToggleButtonGetState(button); button = XtNameToWidget(page,"CalculateArrayWeights"); bCalculateArrayWeights = XmToggleButtonGetState(button); /* Find out which metrics to use */ widget = XtNameToWidget(page,"GeneMetric"); genemetric = GetMetric(widget); widget = XtNameToWidget(page,"ArrayMetric"); arraymetric = GetMetric(widget); path = GetBaseName(work); if (path) { char* p = realloc(path, strlen(path)+strlen(".ext")+1); if (!p) free(path); path = p; } if (!path) { Statusbar(NULL, "Memory allocation failure"); return; } extension = strchr(path, '\0'); if (bCalculateGeneWeights || bCalculateArrayWeights) /* This means calculating array weights, which will be used when * clustering genes */ { const char* error; double gene_cutoff = 0.0; double gene_exponent = 0.0; double array_cutoff = 0.0; double array_exponent = 0.0; Statusbar(NULL, "Calculating weights"); if (bCalculateGeneWeights) { char* text; Widget textfield; Widget arrayweight = XtNameToWidget(page,"ArrayWeight"); Widget arrayweightpage = XtNameToWidget(arrayweight,"ArrayWeightPage"); textfield = XtNameToWidget(arrayweightpage,"ArrayWeightCutoff"); text = XmTextGetString(textfield); array_cutoff = strtod(text, NULL); XtFree(text); textfield = XtNameToWidget(arrayweightpage,"ArrayWeightExp"); text = XmTextGetString(textfield); array_exponent = strtod(text, NULL); XtFree(text); } if (bCalculateArrayWeights) { char* text; Widget textfield; Widget geneweight = XtNameToWidget(page,"GeneWeight"); Widget geneweightpage = XtNameToWidget(geneweight,"GeneWeightPage"); textfield = XtNameToWidget(geneweightpage,"GeneWeightCutoff"); text = XmTextGetString(textfield); gene_cutoff = strtod(text, NULL); XtFree(text); textfield = XtNameToWidget(geneweightpage,"GeneWeightExp"); text = XmTextGetString(textfield); gene_exponent = strtod(text, NULL); XtFree(text); } error = CalculateWeights(gene_cutoff, gene_exponent, genemetric, array_cutoff, array_exponent, arraymetric); if (error) { free(path); ShowError(w, error, "Error"); return; } } switch (*which) { case ID_HIERARCHICAL_CENTROID: { method = 'c'; Statusbar(NULL, "Performing centroid linkage hierarchical clustering"); break; } case ID_HIERARCHICAL_SINGLE: { method = 's'; Statusbar(NULL, "Performing single linkage hierarchical clustering"); break; } case ID_HIERARCHICAL_COMPLETE: { method = 'm'; Statusbar(NULL, "Performing complete linkage hierarchical clustering"); break; } case ID_HIERARCHICAL_AVERAGE: { method = 'a'; Statusbar(NULL, "Performing average linkage hierarchical clustering"); break; } } if (ClusterGenes) { sprintf(extension, ".gtr"); outputfile = fopen(path, "wt"); if (!outputfile) { free(path); Statusbar(NULL, "Error: Unable to open the output file"); return; } ok = HierarchicalCluster(outputfile, genemetric, False, method); fclose(outputfile); if (!ok) { free(path); Statusbar(NULL, "Error: Insufficient memory"); return; } } if (ClusterArrays) { sprintf(extension, ".atr"); outputfile = fopen(path, "wt"); if (!outputfile) { free(path); Statusbar(NULL, "Error: Unable to open the output file"); return; } ok = HierarchicalCluster(outputfile, arraymetric, True, method); fclose(outputfile); if (!ok) { free(path); Statusbar(NULL, "Error: Insufficient memory"); return; } } Statusbar(NULL, "Saving the clustering result"); /* Now make output .cdt file */ sprintf(extension, ".cdt"); outputfile = fopen(path, "wt"); free(path); if (!outputfile) { Statusbar(NULL, "Error: Unable to open the output file"); return; } ok = Save(outputfile, ClusterGenes, ClusterArrays); fclose(outputfile); if (ok) Statusbar(NULL, "Done clustering"); else { ShowError(w, "Insufficient memory", "Error saving to file"); Statusbar(NULL, "Error saving to file"); } break; } } } static void InitTabpages(Widget work) { Widget notebook, page, scroller; Arg args[8]; int n = 0; int i; char* labels[] = {"Filter Data","Adjust Data", "Hierarchical", "k-Means", "SOMs", "PCA"}; char* names[] = {"FilterTab","AdjustTab", "HierarchicalTab", "KMeansTab", "SOMTab", "PCATab"}; XtSetArg(args[n], XmNx, 10); n++; XtSetArg(args[n], XmNy, 180); n++; XtSetArg(args[n], XmNwidth, 570); n++; XtSetArg(args[n], XmNheight, 380); n++; XtSetArg(args[n], XmNbindingType, XmNONE); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNbackPagePlacement, XmTOP_RIGHT); n++; XtSetArg(args[n], XmNbackPageSize, 0); n++; notebook = XmCreateNotebook(work,"tabs",args,n); /* Create the "pages" */ for (i = 0; i < 6; i++) { int command; Widget tab; page = XtCreateManagedWidget(names[i],xmBulletinBoardWidgetClass,notebook,NULL,0); switch (i) { case 0: command = ID_FILTER_INIT; Filter(page, (XtPointer)&command, NULL); break; case 1: command = ID_ADJUST_INIT; Adjust(page, (XtPointer)&command, NULL); break; case 2: command = ID_HIERARCHICAL_INIT; Hierarchical(page, (XtPointer)&command, NULL); break; case 3: command = ID_KMEANS_INIT; KMeans(page, (XtPointer)&command, NULL); break; case 4: command = ID_SOM_INIT; SOM(page, (XtPointer)&command, NULL); break; case 5: command = ID_PCA_INIT; PCA(page, (XtPointer)&command, NULL); break; } n = 0; XtSetArg(args[n], XmNnotebookChildType, XmMAJOR_TAB); n++; tab = XmCreatePushButton(notebook, labels[i], args, n); XtManageChild(tab); XtManageChild(page); } scroller = XtNameToWidget(notebook, "PageScroller"); XtUnmanageChild(scroller); XtManageChild(notebook); } static Widget CreateMenu(Widget main_w) /* The menu can be created more easily by using XmVaCreateSimplePulldownMenu. * However, XmVaCreateSimplePulldownMenu will cause client_data in the callback * function to be an int instead of a pointer to an int, which we use here. * Using an int directly may cause problems on 64-bit platforms, where the size * of XtPointer usually is not equal to the size of an int. */ { int n; Arg args[3]; Widget pulldown; Widget cascade; Widget menuitem; Atom atom; static int open_command = CMD_FILE_OPEN; static int save_command = CMD_FILE_SAVE; static int quit_command = CMD_FILE_QUIT; static int htmlhelp_command = CMD_HELP_HTMLHELP; static int manual_command = CMD_HELP_MANUAL; static int download_command = CMD_HELP_DOWNLOAD; static int fileformat_command = CMD_HELP_FILEFORMAT; static int about_command = CMD_HELP_ABOUT; XmString file_str = XmStringCreateLocalized("File"); XmString help_str = XmStringCreateLocalized("Help"); Widget top = XtParent(main_w); Widget menubar = XmVaCreateSimpleMenuBar(main_w, "menubar", NULL, 0); /* File Menu */ pulldown = XmCreatePulldownMenu(menubar, "file_menu", NULL, 0); n = 0; XtSetArg(args[n], XmNsubMenuId, pulldown); n++; XtSetArg(args[n], XmNlabelString, file_str); n++; XtSetArg(args[n], XmNmnemonic, 'F'); n++; cascade = XmCreateCascadeButton(menubar, "file_menu", args, n); XtManageChild(cascade); XmStringFree(file_str); menuitem = XtVaCreateManagedWidget("Open data file", xmPushButtonGadgetClass, pulldown, NULL); XtVaSetValues(menuitem, XmNmnemonic, 'O', NULL); XtAddCallback(menuitem, XmNactivateCallback, MenuFile, &open_command); menuitem = XtVaCreateManagedWidget("Save data file", xmPushButtonGadgetClass, pulldown, NULL); XtVaSetValues(menuitem, XmNmnemonic, 'S', NULL); XtAddCallback(menuitem, XmNactivateCallback, MenuFile, &save_command); XtVaCreateManagedWidget("", xmSeparatorGadgetClass, pulldown, NULL); menuitem = XtVaCreateManagedWidget("Quit", xmPushButtonGadgetClass, pulldown, NULL); XtVaSetValues(menuitem, XmNmnemonic, 'Q', NULL); XtAddCallback(menuitem, XmNactivateCallback, MenuFile, &quit_command); /* Help Menu */ pulldown = XmCreatePulldownMenu(menubar, "help_menu", NULL, 0); n = 0; XtSetArg(args[n], XmNsubMenuId, pulldown); n++; XtSetArg(args[n], XmNlabelString, help_str); n++; XtSetArg(args[n], XmNmnemonic, 'H'); n++; cascade = XmCreateCascadeButton(menubar, "help_menu", args, n); XtManageChild(cascade); XmStringFree(help_str); /* Tell the menubar that this is the help menu */ XtVaSetValues(menubar, XmNmenuHelpWidget, cascade, NULL); menuitem = XtVaCreateManagedWidget("Cluster 3.0 Help", xmPushButtonGadgetClass, pulldown, NULL); XtVaSetValues(menuitem, XmNmnemonic, 'H', NULL); XtAddCallback(menuitem, XmNactivateCallback, MenuHelp, &htmlhelp_command); menuitem = XtVaCreateManagedWidget("Read local manual", xmPushButtonGadgetClass, pulldown, NULL); XtVaSetValues(menuitem, XmNmnemonic, 'm', NULL); XtAddCallback(menuitem, XmNactivateCallback, MenuHelp, &manual_command); menuitem = XtVaCreateManagedWidget("Read online manual", xmPushButtonGadgetClass, pulldown, NULL); XtVaSetValues(menuitem, XmNmnemonic, 'o', NULL); XtAddCallback(menuitem, XmNactivateCallback, MenuHelp, &download_command); menuitem = XtVaCreateManagedWidget("File format help", xmPushButtonGadgetClass, pulldown, NULL); XtVaSetValues(menuitem, XmNmnemonic, 'F', NULL); XtAddCallback(menuitem, XmNactivateCallback, MenuHelp, &fileformat_command); XtVaCreateManagedWidget("", xmSeparatorGadgetClass, pulldown, NULL); menuitem = XtVaCreateManagedWidget("About", xmPushButtonGadgetClass, pulldown, NULL); XtVaSetValues(menuitem, XmNmnemonic, 'A', NULL); XtAddCallback(menuitem, XmNactivateCallback, MenuHelp, &about_command); XtManageChild(menubar); atom = XmInternAtom(XtDisplay(top),"WM_DELETE_WINDOW",False); XmAddWMProtocolCallback(top, atom, MenuFile, (XtPointer)&quit_command); return menubar; } int guimain(int argc, char *argv[]) { Widget work, statusbar; XtAppContext app; Arg args[2]; int n; int command; /* Initialize toolkit */ Widget top = XtVaAppInitialize(&app, "top", NULL, 0, &argc, argv, NULL, NULL); Widget main_w = XtCreateWidget("main", xmMainWindowWidgetClass,top,NULL,0); Widget menubar = CreateMenu(main_w); n = 0; XtSetArg(args[n], XmNwidth, 570); n++; XtSetArg(args[n], XmNheight, 570); n++; work = XtCreateManagedWidget("work",xmBulletinBoardWidgetClass,main_w,args,n); statusbar = Statusbar(main_w, NULL); XtVaSetValues(top, XmNtitle, "Gene Cluster 3.0", NULL); XtVaSetValues(main_w, XmNmenuBar, menubar, XmNworkWindow, work, XmNmessageWindow, statusbar, NULL); command = ID_FILEMANAGER_INIT; FileManager(work, (XtPointer)&command, NULL); InitTabpages(work); XtManageChild(main_w); XtRealizeWidget(top); XtAppMainLoop(app); /* If the code gets here, something is wrong => return error code */ return 1; } cluster-1.52a/X11/format.xpm0000644000100500010050000030244007560471504015513 0ustar mdehoonmdehoon/* XPM */ static char * format_xpm[] = { "609 162 17 1", " c None", ". c #000000", "+ c #800000", "@ c #008000", "# c #808000", "$ c #000080", "% c #800080", "& c #008080", "* c #808080", "= c #C0C0C0", "- c #FF0000", "; c #00FF00", "> c #FFFF00", ", c #0000FF", "' c #FF00FF", ") c #00FFFF", "! c #FFFFFF", "=================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================", "==*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************", "==*..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", "==*.!!!!!!!!!!!!!!!!!!!!!!!!!*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==", "==*.!========================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==", "==*.!========================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==", "==*.!========================*!==============================.===============================*!===========================......=============================*!=============================...==============================*!===========================.....==============================*!===========================.......============================*!============================......============================*!=============================....=============================*!===========================.=====.============================*!==============================.===============================*!==", "==*.!========================*!=============================.=.==============================*!===========================.=====.============================*!============================.===.=============================*!===========================.====.=============================*!===========================.==================================*!============================.=================================*!============================.====.============================*!===========================.=====.============================*!==============================.===============================*!==", "==*.!========================*!=============================.=.==============================*!===========================.=====.============================*!===========================.=====.============================*!===========================.=====.============================*!===========================.==================================*!============================.=================================*!===========================.======.===========================*!===========================.=====.============================*!==============================.===============================*!==", "==*.!========================*!=============================.=.==============================*!===========================.=====.============================*!===========================.==================================*!===========================.=====.============================*!===========================.==================================*!============================.=================================*!===========================.==================================*!===========================.=====.============================*!==============================.===============================*!==", "==*.!========================*!============================.===.=============================*!===========================......=============================*!===========================.==================================*!===========================.=====.============================*!===========================.......============================*!============================.....=============================*!===========================.==================================*!===========================.......============================*!==============================.===============================*!==", "==*.!========================*!============================.===.=============================*!===========================.=====.============================*!===========================.==================================*!===========================.=====.============================*!===========================.==================================*!============================.=================================*!===========================.===....===========================*!===========================.=====.============================*!==============================.===============================*!==", "==*.!========================*!===========================.......============================*!===========================.=====.============================*!===========================.==================================*!===========================.=====.============================*!===========================.==================================*!============================.=================================*!===========================.======.===========================*!===========================.=====.============================*!==============================.===============================*!==", "==*.!========================*!===========================.=====.============================*!===========================.=====.============================*!===========================.=====.============================*!===========================.=====.============================*!===========================.==================================*!============================.=================================*!===========================.======.===========================*!===========================.=====.============================*!==============================.===============================*!==", "==*.!========================*!==========================.=======.===========================*!===========================.=====.============================*!============================.===.=============================*!===========================.====.=============================*!===========================.==================================*!============================.=================================*!============================.====.============================*!===========================.=====.============================*!==============================.===============================*!==", "==*.!========================*!==========================.=======.===========================*!===========================......=============================*!=============================...==============================*!===========================.....==============================*!===========================.......============================*!============================.=================================*!=============================....=============================*!===========================.=====.============================*!==============================.===============================*!==", "==*.!========================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==", "==*.!========================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==", "==*.!========================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==============================================================*!==", "==*.*****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************", "==*.!!!!!!!!!!!!!!!!!!!!!!!!!*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.============.============*!!!--!!!--!!--!!!--!!--!!!!----!!!!--!!-----!!!!!!!!!!!!!!!!!!!=!!!..!!!..!!!!...!!!!...!!!...!!......!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!.....!!..!!!...!!!..!......!!..!!!!.....!!!..!!!..!.......=!!!!!.....!!!!!....!!!!......!!!.....!!!!......!!......!!!!!!!!=!!!-------!-!!!!!-!------!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-------!-!!!!!-!------!!!----!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-------!-!!!!!-!------!!!----!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-------!-!!!!!-!------!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-------!-!!!!!-!------!!!-----!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.===========..============*!!!--!!!--!!---!!--!!--!!!--!!--!!!--!!--!!--!!!!!!!!!!!!!!!!!!=!!!...!!..!!!!...!!!!...!!!...!!..!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!..!!!..!..!!!...!!!..!..!!!!!!..!!!..!!!..!!..!!!..!!!!..!!=!!!!..!!!..!!!..!!..!!!..!!!..!!..!!..!!!..!!!!!!..!!!..!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!-!!!--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!-!-!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!-!-!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!-!!!!--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!-!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.==========.=.============*!!!--!!!--!!---!!--!!--!!--!!!!--!!--!!--!!!--!!!!!!!!!!!!!!!!!=!!!...!!..!!!..!..!!!....!....!!..!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!..!!!!!!!!..!!...!!..!!..!!!!!!..!!..!!!!!!!!..!!!..!!!!..!!=!!!..!!!!!!!!..!!!!..!!..!!!..!!..!!!..!!..!!!!!!..!!!..!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!-!!-!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!-!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!-!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!-!!!!--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!-!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.============.============*!!!--!!!--!!----!--!!--!!--!!!!--!!--!!--!!!--!!!!!!!!!!!!!!!!!=!!!....!..!!!..!..!!!....!....!!..!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!..!!!!!!!!..!..!..!..!!..!!!!!!..!!..!!!!!!!!..!!!..!!!!..!!=!!!..!!!!!!!!..!!!!..!!..!!!..!!..!!!..!!..!!!!!!..!!!..!!!!!!!=!!!-!!!!!!!!!-!-!!!-!!!!!-!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!!-!-!!!-!!!!!-!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!!-!-!!!-!!!!!-!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!!-!-!!!-!!!!!-!!!-!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!!-!-!!!-!!!!!-!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.============.============*!!!--!!!--!!--!-!--!!--!!--!!!!--!!--!!--!!!--!!!!!!!!!!!!!!!!!=!!!..!.!..!!!..!..!!!..!.!.!..!!......!!!!!!!!!!!!!!!!!!!!!!!!!=!!!..!!!!!!!!..!..!..!..!!......!!..!!..!!!!!!!!.......!!!!..!!=!!!..!!!!!!!!..!!!!..!!..!!!..!!..!!!..!!......!!..!!!..!!!!!!!=!!!-------!!!!-!!!!-!!!!!-!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-------!!!!-!!!!-!!!!!-!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-------!!!!-!!!!-!!!!!-!!!---!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-------!!!!-!!!!-!!!!!-!!!-!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-------!!!!-!!!!-!!!!!-!-----!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.============.============*!!!--!!!--!!--!----!!--!!--!!!!--!!--!!--!!!--!!!!!!!!!!!!!!!!!=!!!..!....!!..!!!..!!..!.!.!..!!..!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!..!!....!!..!..!..!..!!..!!!!!!..!!..!!....!!..!!!..!!!!..!!=!!!..!!....!!..!!!!..!!......!!!..!!!..!!..!!!!!!......!!!!!!!!=!!!-!!!!!!!!!!-!!!!------!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!!!-!!!!------!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!!!-!!!!------!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!!!-!!!!------!!!-!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!!!-!!!!------!!-!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.============.============*!!!--!!!--!!--!!---!!--!!--!!!!--!!--!!--!!!--!!!!!!!!!!!!!!!!!=!!!..!!...!!..!!!..!!..!.!.!..!!..!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!..!!!!..!!..!..!..!..!!..!!!!!!..!!..!!!!..!!..!!!..!!!!..!!=!!!..!!!!..!!..!!!!..!!..!!..!!!..!!!..!!..!!!!!!..!!..!!!!!!!!=!!!-!!!!!!!!!-!-!!!-!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!!-!-!!!-!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!!-!-!!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!!-!-!!!-!!!!!!!!-!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!!-!-!!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.============.============*!!!--!!!--!!--!!---!!--!!--!!-!--!!--!!--!!!--!!!!!!!!!!!!!!!!!=!!!..!!...!!.......!!..!...!..!!..!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!..!!!!..!!!...!!!...!!!..!!!!!!..!!..!!!!..!!..!!!..!!!!..!!=!!!..!!!!..!!..!!!!..!!..!!!..!!..!!!..!!..!!!!!!..!!!..!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!!!------!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.============.============*!!!--!!!--!!--!!!--!!--!!!--!!--!!!--!!--!!--!!!!!!!!!!!!!!!!!!=!!!..!!!..!..!!!!!..!..!...!..!!..!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!..!!!..!!!...!!!...!!!..!!!!!!..!!!..!!!..!!..!!!..!!!!..!!=!!!!..!!!..!!!..!!..!!!..!!!..!!..!!..!!!..!!!!!!..!!!..!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!!!-!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-!!!!!!!!-!!!-!!-!!!!!!!-!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.============.============*!!!!-----!!!--!!!--!!--!!!!-----!!!--!!-----!!!!!!!!!!!!!!!!!!!=!!!..!!!..!..!!!!!..!..!!.!!..!!......!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!.....!!!!...!!!...!!!......!!..!!!!.....!!!..!!!..!!!!..!!=!!!!!.....!!!!!....!!!!..!!!!..!.....!!!!......!!..!!!!..!!!!!!=!!!-------!-!!!!!-!-!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-------!-!!!!!-!-!!!!!!!------!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-------!-!!!!!-!-!!!!!!!!----!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-------!-!!!!!-!-!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!-------!-!!!!!-!-!!!!!!!!----!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.**************************===================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================", "==*.!!!!!!!!!!!!!!!!!!!!!!!!!*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.==========....===========*!!!......!..!!!...!!!..!......!!..!!!!.....!!!..!!!..!........!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!!!!....!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!!!!....!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!", "==*.=========.====.==========*!!!..!!!!!..!!!...!!!..!..!!!!!!..!!!..!!!..!!..!!!..!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!.!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!.!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!..!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!..!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!..!!!!!=!!!", "==*.==============.==========*!!!..!!!!!!..!!...!!..!!..!!!!!!..!!..!!!!!!!!..!!!..!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!.!!!!!=!!!", "==*.==============.==========*!!!..!!!!!!..!..!..!..!!..!!!!!!..!!..!!!!!!!!..!!!..!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!", "==*.==============.==========*!!!......!!..!..!..!..!!......!!..!!..!!!!!!!!.......!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!...!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!...!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!", "==*.=============.===========*!!!..!!!!!!..!..!..!..!!..!!!!!!..!!..!!....!!..!!!..!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!", "==*.============.============*!!!..!!!!!!..!..!..!..!!..!!!!!!..!!..!!!!..!!..!!!..!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!", "==*.===========.=============*!!!..!!!!!!!...!!!...!!!..!!!!!!..!!..!!!!..!!..!!!..!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!", "==*.==========.==============*!!!..!!!!!!!...!!!...!!!..!!!!!!..!!!..!!!..!!..!!!..!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!.!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!.!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!", "==*.=========......==========*!!!......!!!...!!!...!!!......!!..!!!!.....!!!..!!!..!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!.!!!....!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!.!!!....!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!=!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.**************************===============================================================================================================================================================================================================================================================;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;===", "==*.!!!!!!!!!!!!!!!!!!!!!!!!!*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========....===========*!!!!!----!!!!-------!!-!!!!!-!!-------!!!!-!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!!!!....!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!!-!!!!-!!!-!!!!!!!!--!!!!-!!-!!!!!!!!!--!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!.!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!..!!!!!;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==============.==========*!!!-!!!!!!-!!-!!!!!!!!-!-!!!-!!-!!!!!!!!-!-!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!.!!!!!;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==============.==========*!!!-!!!!!!!!!-!!!!!!!!-!-!!!-!!-!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.===========...===========*!!!-!!!!!!!!!-------!!-!!-!!-!!-------!!!!-!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==============.==========*!!!-!!!----!!-!!!!!!!!-!!-!!-!!-!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==============.==========*!!!-!!!!!!-!!-!!!!!!!!-!!!-!-!!-!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==============.==========*!!!-!!!!!!-!!-!!!!!!!!-!!!-!-!!-!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!.!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!!-!!!!-!!!-!!!!!!!!-!!!!--!!-!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!.!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========....===========*!!!!!----!!!!-------!!-!!!!!-!!-------!!!!-!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!.!!......!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.**************************===============================================================================================================================================================================================================================================================;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;===", "==*.!!!!!!!!!!!!!!!!!!!!!!!!!*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=============.===========*!!!!!----!!!!-------!!-!!!!!-!!-------!!----!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!!!!....!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.============..===========*!!!!-!!!!-!!!-!!!!!!!!--!!!!-!!-!!!!!!!-!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!.!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.============..===========*!!!-!!!!!!-!!-!!!!!!!!-!-!!!-!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.===========.=.===========*!!!-!!!!!!!!!-!!!!!!!!-!-!!!-!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.===========.=.===========*!!!-!!!!!!!!!-------!!-!!-!!-!!-------!!!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========.==.===========*!!!-!!!----!!-!!!!!!!!-!!-!!-!!-!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========.==.===========*!!!-!!!!!!-!!-!!!!!!!!-!!!-!-!!-!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========......==========*!!!-!!!!!!-!!-!!!!!!!!-!!!-!-!!-!!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!.!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!!;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=============.===========*!!!!-!!!!-!!!-!!!!!!!!-!!!!--!!-!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!.!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!!!;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=============.===========*!!!!!----!!!!-------!!-!!!!!-!!-------!------!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!.!!......!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!......!!!;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.**************************===============================================================================================================================================================================================================================================================;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;===", "==*.!!!!!!!!!!!!!!!!!!!!!!!!!*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========.....==========*!!!!!----!!!!-------!!-!!!!!-!!-------!!----!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!!!!....!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========.==============*!!!!-!!!!-!!!-!!!!!!!!--!!!!-!!-!!!!!!!-!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!.!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========.==============*!!!-!!!!!!-!!-!!!!!!!!-!-!!!-!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.===============*!!!-!!!!!!!!!-!!!!!!!!-!-!!!-!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.....===========*!!!-!!!!!!!!!-------!!-!!-!!-!!-------!!!---!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!!.!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!...!!!!;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!-!!!----!!-!!!!!!!!-!!-!!-!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==============.==========*!!!-!!!!!!-!!-!!!!!!!!-!!!-!-!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!.!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==============.==========*!!!-!!!!!!-!!-!!!!!!!!-!!!-!-!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!.!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!!-!!!!-!!!-!!!!!!!!-!!!!--!!-!!!!!!!-!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!.!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========....===========*!!!!!----!!!!-------!!-!!!!!-!!-------!!----!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!.!!......!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.**************************===============================================================================================================================================================================================================================================================;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;===", "==*.!!!!!!!!!!!!!!!!!!!!!!!!!*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========....===========*!!!!!----!!!!-------!!-!!!!!-!!-------!!!!!-!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!!!!!!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!!-!!!!-!!!-!!!!!!!!--!!!!-!!-!!!!!!!!!!--!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!..!!!!;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.===============*!!!-!!!!!!-!!-!!!!!!!!-!-!!!-!!-!!!!!!!!!!--!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!..!!!!;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.===============*!!!-!!!!!!!!!-!!!!!!!!-!-!!!-!!-!!!!!!!!!-!-!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!.!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!.!!!!;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.=...===========*!!!-!!!!!!!!!-------!!-!!-!!-!!-------!!!-!-!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!.!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!.!!!!;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========..===.==========*!!!-!!!----!!-!!!!!!!!-!!-!!-!!-!!!!!!!!-!!-!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!.!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!.!!!!;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!-!!!!!!-!!-!!!!!!!!-!!!-!-!!-!!!!!!!!-!!-!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!.!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!.!!!!;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!-!!!!!!-!!-!!!!!!!!-!!!-!-!!-!!!!!!!------!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!......!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!......!!!;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!!-!!!!-!!!-!!!!!!!!-!!!!--!!-!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========....===========*!!!!!----!!!!-------!!-!!!!!-!!-------!!!!!-!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!.!!!!!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.**************************===============================================================================================================================================================================================================================================================;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;===", "==*.!!!!!!!!!!!!!!!!!!!!!!!!!*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========......==========*!!!!!----!!!!-------!!-!!!!!-!!-------!!-----!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!!!!!!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.....!!!;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=============.===========*!!!!-!!!!-!!!-!!!!!!!!--!!!!-!!-!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!!!;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=============.===========*!!!-!!!!!!-!!-!!!!!!!!-!-!!!-!!-!!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!!!;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.============.============*!!!-!!!!!!!!!-!!!!!!!!-!-!!!-!!-!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!.!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.============.============*!!!-!!!!!!!!!-------!!-!!-!!-!!-------!-----!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!.!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.....!!!!;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.===========.=============*!!!-!!!----!!-!!!!!!!!-!!-!!-!!-!!!!!!!-!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!.!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.===========.=============*!!!-!!!!!!-!!-!!!!!!!!-!!!-!-!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!.!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========.==============*!!!-!!!!!!-!!-!!!!!!!!-!!!-!-!!-!!!!!!!!!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!......!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========.==============*!!!!-!!!!-!!!-!!!!!!!!-!!!!--!!-!!!!!!!-!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========.==============*!!!!!----!!!!-------!!-!!!!!-!!-------!!----!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!.!!!!!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.**************************===============================================================================================================================================================================================================================================================;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;===", "==*.!!!!!!!!!!!!!!!!!!!!!!!!!*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========....===========*!!!!!----!!!!-------!!-!!!!!-!!-------!!----!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!!!!!!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;;;;;.;;;;.......;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!!-!!!!-!!!-!!!!!!!!--!!!!-!!-!!!!!!!-!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!-!!!!!!-!!-!!!!!!!!-!-!!!-!!-!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!..!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!-!!!!!!!!!-!!!!!!!!-!-!!!-!!-!!!!!!!-!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!.!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;;.;.;;;;;;.;;;;;;.;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========....===========*!!!-!!!!!!!!!-------!!-!!-!!-!!-------!-!---!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!.!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!...!!!!;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!-!!!----!!-!!!!!!!!-!!-!!-!!-!!!!!!!--!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!.!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!..!!!.!!!;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;;.;;;.;;;;;.;;;;;.;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!-!!!!!!-!!-!!!!!!!!-!!!-!-!!-!!!!!!!-!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!.!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.......;;;;.;;;;.......;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!-!!!!!!-!!-!!!!!!!!-!!!-!-!!-!!!!!!!-!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!......!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;;.;;.;;;;;.;;;;.;;;;.;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========.====.==========*!!!!-!!!!-!!!-!!!!!!!!-!!!!--!!-!!!!!!!-!!!!-!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!!!!!!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!.!!!;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.;;;;.;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.==========....===========*!!!!!----!!!!-------!!-!!!!!-!!-------!!----!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!.!!!!!!.!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....!!!!;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.....;;;.;;;;;;;.;;;.;;;.;;;;;;;.;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!!!", "==*.**************************===============================================================================================================================================================================================================================================================;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;===", "==*.!!!!!!!!!!!!!!!!!!!!!!!!!*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========================*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.==========....===========*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========.====.==========*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!", "==*.=========.====.==========*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=!!!"}; cluster-1.52a/X11/Makefile.am0000644000100500010050000000101610761551453015523 0ustar mdehoonmdehoon## Process this file with automake to produce Makefile.in noinst_LIBRARIES = libgui.a libgui_a_SOURCES = gui.c HTML = ../html/*.html IMAGE = ../html/images/*.png FILEFORMAT = format.xpm DOC = ../doc/cluster3.pdf htmldir = $(prefix)/cluster/html imagedir = $(prefix)/cluster/html/images docdir = $(prefix)/cluster/doc fileformatdir = $(prefix)/cluster dist_html_DATA = $(HTML) dist_image_DATA = $(IMAGE) dist_doc_DATA = $(DOC) dist_fileformat_DATA = $(FILEFORMAT) AM_CPPFLAGS = -I../src $(X_CFLAGS) -DPREFIX=\"$(prefix)\" cluster-1.52a/X11/Makefile.in0000644000100500010050000004537212177155022015544 0ustar mdehoonmdehoon# Makefile.in generated by automake 1.12.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = X11 DIST_COMMON = $(dist_doc_DATA) $(dist_fileformat_DATA) \ $(dist_html_DATA) $(dist_image_DATA) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libgui_a_AR = $(AR) $(ARFLAGS) libgui_a_LIBADD = am_libgui_a_OBJECTS = gui.$(OBJEXT) libgui_a_OBJECTS = $(am_libgui_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libgui_a_SOURCES) DIST_SOURCES = $(libgui_a_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(docdir)" "$(DESTDIR)$(fileformatdir)" \ "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(imagedir)" DATA = $(dist_doc_DATA) $(dist_fileformat_DATA) $(dist_html_DATA) \ $(dist_image_DATA) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = $(prefix)/cluster/doc dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = $(prefix)/cluster/html includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LIBRARIES = libgui.a libgui_a_SOURCES = gui.c HTML = ../html/*.html IMAGE = ../html/images/*.png FILEFORMAT = format.xpm DOC = ../doc/cluster3.pdf imagedir = $(prefix)/cluster/html/images fileformatdir = $(prefix)/cluster dist_html_DATA = $(HTML) dist_image_DATA = $(IMAGE) dist_doc_DATA = $(DOC) dist_fileformat_DATA = $(FILEFORMAT) AM_CPPFLAGS = -I../src $(X_CFLAGS) -DPREFIX=\"$(prefix)\" all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu X11/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu X11/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libgui.a: $(libgui_a_OBJECTS) $(libgui_a_DEPENDENCIES) $(EXTRA_libgui_a_DEPENDENCIES) -rm -f libgui.a $(libgui_a_AR) libgui.a $(libgui_a_OBJECTS) $(libgui_a_LIBADD) $(RANLIB) libgui.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` install-dist_docDATA: $(dist_doc_DATA) @$(NORMAL_INSTALL) @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-dist_docDATA: @$(NORMAL_UNINSTALL) @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) install-dist_fileformatDATA: $(dist_fileformat_DATA) @$(NORMAL_INSTALL) @list='$(dist_fileformat_DATA)'; test -n "$(fileformatdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(fileformatdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(fileformatdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(fileformatdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(fileformatdir)" || exit $$?; \ done uninstall-dist_fileformatDATA: @$(NORMAL_UNINSTALL) @list='$(dist_fileformat_DATA)'; test -n "$(fileformatdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(fileformatdir)'; $(am__uninstall_files_from_dir) install-dist_htmlDATA: $(dist_html_DATA) @$(NORMAL_INSTALL) @list='$(dist_html_DATA)'; test -n "$(htmldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ done uninstall-dist_htmlDATA: @$(NORMAL_UNINSTALL) @list='$(dist_html_DATA)'; test -n "$(htmldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(htmldir)'; $(am__uninstall_files_from_dir) install-dist_imageDATA: $(dist_image_DATA) @$(NORMAL_INSTALL) @list='$(dist_image_DATA)'; test -n "$(imagedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(imagedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(imagedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(imagedir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(imagedir)" || exit $$?; \ done uninstall-dist_imageDATA: @$(NORMAL_UNINSTALL) @list='$(dist_image_DATA)'; test -n "$(imagedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(imagedir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) $(DATA) installdirs: for dir in "$(DESTDIR)$(docdir)" "$(DESTDIR)$(fileformatdir)" "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(imagedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_docDATA install-dist_fileformatDATA \ install-dist_htmlDATA install-dist_imageDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_docDATA uninstall-dist_fileformatDATA \ uninstall-dist_htmlDATA uninstall-dist_imageDATA .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist ctags distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dist_docDATA \ install-dist_fileformatDATA install-dist_htmlDATA \ install-dist_imageDATA install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-dist_docDATA \ uninstall-dist_fileformatDATA uninstall-dist_htmlDATA \ uninstall-dist_imageDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cluster-1.52a/example/0000755000100500010050000000000012177164024014550 5ustar mdehoonmdehooncluster-1.52a/example/example.c0000644000100500010050000003542110445025360016347 0ustar mdehoonmdehoon/* This is an example program that makes use of the C Clustering Library. */ /* ========================================================================= */ #include #include /* The standard C libraries */ #include "cluster.h" /* The C Clustering Library */ /* ========================================================================= */ void show_data(int nrows, int ncols, double** data, int** mask) /* Print the data matrix */ { int i, j; printf("============== The gene expression data matrix ================\n"); for (j = 0; j < ncols; j++) printf("\tCol %d", j); printf ("\n"); for (i = 0; i < nrows; i++) { printf("Row %d", i); for (j = 0; j < ncols; j++) { if (mask[i][j]) printf("\t%5.2g",data[i][j]); else printf("\t"); /* mask[i][j]==0, so this data point is missing */ } printf("\n"); } printf("\n"); return; } /* ========================================================================= */ void example_mean_median(int nrows, int ncols, double** data, int** mask) { int i, j; double* temp = malloc(ncols*sizeof(double)); printf("============== Calculating the mean and median ================\n"); for (i = 0; i < nrows; i++) { double meanvalue; double medianvalue; int ndata = 0; for (j = 0; j < ncols; j++) { if (mask[i][j]) { temp[ndata] = data[i][j]; ndata++; } } meanvalue = mean(ndata, temp); medianvalue = median(ndata, temp); printf("row %2d:\t", i); printf("mean = %7.3f\t", meanvalue); printf("median = %7.3f\n", medianvalue); /* Note that the median routine changes the order of the elements in * the array temp. */ } printf("\n"); free(temp); } /* ========================================================================= */ double** example_distance_gene(int nrows, int ncols, double** data, int** mask) /* Calculate the distance matrix between genes using the Euclidean distance. */ { int i, j; double** distMatrix; double* weight = malloc(ncols*sizeof(double)); printf("============ Euclidean distance matrix between genes ============\n"); for (i = 0; i < ncols; i++) weight[i] = 1.0; distMatrix = distancematrix(nrows, ncols, data, mask, weight, 'e', 0); if (!distMatrix) { printf ("Insufficient memory to store the distance matrix\n"); free(weight); return NULL; } printf(" Gene:"); for(i=0; i 'Algorithm::Cluster', VERSION_FROM => 'perl/Cluster.pm', AUTHOR => 'John Nolan and Michiel de Hoon (mdehoon "AT" gsc.riken.jp)', ABSTRACT => 'Perl interface to the C Clustering Library', DIR => [ 'src', 'perl', ], ); cluster-1.52a/Makefile.in0000644000100500010050000006074012177155022015167 0ustar mdehoonmdehoon# Makefile.in generated by automake 1.12.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ TODO depcomp install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ cscope distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = X11 src DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DOCDIST = doc/cluster.pdf doc/cluster3.pdf doc/cluster.texinfo \ doc/cluster3.texinfo doc/structure.eps doc/Makefile WINDIST = windows/cluster.hhp windows/cluster.ico windows/cluster.iss \ windows/main.c windows/gui.c windows/format.bmp windows/Makefile \ windows/resources.h windows/resources.rc MACDIST = mac/main.m mac/Controller.h mac/Controller.m mac/cluster.icns \ mac/English.lproj/InfoPlist.strings \ mac/English.lproj/AboutPanel.nib/classes.nib \ mac/English.lproj/AboutPanel.nib/info.nib \ mac/English.lproj/AboutPanel.nib/keyedobjects.nib \ mac/English.lproj/FileFormatPanel.nib/classes.nib \ mac/English.lproj/FileFormatPanel.nib/info.nib \ mac/English.lproj/FileFormatPanel.nib/keyedobjects.nib \ mac/English.lproj/MainMenu.nib/classes.nib \ mac/English.lproj/MainMenu.nib/info.nib \ mac/English.lproj/MainMenu.nib/keyedobjects.nib \ mac/Cluster.xcodeproj/project.pbxproj mac/Makefile mac/Info.plist PYTHONDIST = setup.py python/MANIFEST.python python/__init__.py \ python/clustermodule.c python/test/README python/test/test_Cluster.py PERLDIST = perl/Artistic.txt perl/MANIFEST.perl \ Makefile.PL perl/Makefile.PL src/Makefile.PL \ perl/Cluster.pm perl/Record.pm perl/Cluster.xs \ perl/t/01_mean_median.t perl/t/02_tree.t \ perl/t/10_kcluster.t perl/t/11_clusterdistance.t perl/t/12_treecluster.t \ perl/t/13_somcluster.t perl/t/14_kmedoids.t perl/t/15_distancematrix.t \ perl/t/16_pca.t \ perl/examples/ex1_kcluster perl/examples/ex2_mean_median \ perl/examples/ex3_kcluster perl/examples/ex4_somcluster \ perl/examples/ex5_treecluster perl/examples/ex6_clusterdistance \ perl/examples/ex7_distancematrix perl/examples/ex8_kmedoids EXAMPLEDIST = example/example.c example/Makefile example/README HTMLDIST = html/mac.py html/Makefile DATADIST = data/README data/cyano.txt @MOTIF_TRUE@MAYBE_X11 = X11 SUBDIRS = $(MAYBE_X11) src EXTRA_DIST = $(WINDIST) $(MACDIST) $(PYTHONDIST) $(PERLDIST) $(DOCDIST) \ $(EXAMPLEDIST) $(HTMLDIST) $(DATADIST) all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then rm -f stamp-h1; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done cscopelist-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist-recursive cscopelist cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ cscopelist-recursive ctags-recursive install-am install-strip \ tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-cscope \ clean-generic cscope cscopelist cscopelist-recursive ctags \ ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-lzip \ dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \ distclean-generic distclean-hdr distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ info-am install install-am install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cluster-1.52a/doc/0000755000100500010050000000000012177164023013661 5ustar mdehoonmdehooncluster-1.52a/doc/cluster3.pdf0000755000100500010050000065740012177163661016146 0ustar mdehoonmdehoon%PDF-1.4 %äðíø 6 0 obj <> stream xÚE‘]KÃ0†ïýç2…5ËÉwðNÙqÈX‡‚xQÛŽºÔ¹•Ío“T%çƒ÷Í“sG@`ãA0ŒvÔ:¨pWÀ|‰ÀÕÊA±´£²”#õ¹ï†Ó¹ùÊra$”…D‘Ué3ÁÈPvÙ{ñ‹Ž ¨³ .é-):8€Tì¯ê`ë䀌:\[:s4†¡»>… /­¯ûŒr9ÍB‡ä*$’>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 10 0 obj <> stream xÚmQËnÛ0¼÷+öHÇMŠ×IÓ9UOi¬DÇDlR¥èþûjIH€@‡ÝÙÇì [>Z€V†v†#|îáö^gÔ0ýx­â‚J ýøL~Ä]n„&çFtÄ&×´R+2Ä ‹—ä_ö˜äæwÿŒ¢º*EÙJíö~󆼕”Ih¯#¿ß®Sï$l)‹Ôr?Û°‹iÄ»šü þÞsiö]jÓµÆTÐïý\³£ 8}²‡ŠÏˆì\=ÄE¼öpX9ÎÉç삎ü)öж–³Žj½DIù¶ˆzôö÷Ö-Ħȟ] M«”"ß2Ö4AcÀ ˜M6e_"âq:¸ì-oÆ÷{¶†¢9¦×zȇ:=¥ø’Ü<¯7û½«ÓoãüÕ1aÕ‚*NSÓ.­Ñf‡o+7…ZJIc¢fë#”üjÙ£e)]]{ˆ…(†›Š?üE AÜÕØ7 ñõ‚­xS¹N¨»´¿º+õWÌd—h1p×ÃÓ§ÿo1¶Û endstream endobj 11 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 14 0 obj <> stream xÚmTÝo›0ß_Á£# Æ@x]Õ®šÖN[³uÒ¶œÄ*Ø™¦Ù_¿;Ÿ£DÍ)Ü÷÷ý‰²(…_U<ªÊ:YÔQÓGï—ÑÕ-²4©Ó:Z®#!DRQ–'u-ÛŸ,›ý^~ŒbÁK”Ç<¹W,·z˜Åy•²ãwÜ*$2ÖK3ã›dGеuD\wÓ0*GVy’&³¸(ÊsqÊöè*CHëôFÙu‡ tz•¡+´DEY³{ÝÌxɶRu$¸ÑÃÑn¿ÕòÏH£^–ÑËäê´d£4Pa‹\žý‚‘”ô8ã H° yÁžf ιm%¦A“ éí,®Õ¿ÒL¨AÁÔW·ÅÌ<«ŽÁBžƒÁyÊ$åA÷JšR4„”6Š.» @4n{bµ¡ot\–3iZj"çEÂós Ô+ Ùb­‚gÔ@ÁùyXd}ÿxTÝ:þì6Ò迾ÞËÝ@Ôhé« ÔÙ†X#´G˜lÜê^™A[ƒ“jýÍÔIwÙ ÓíÈ/ʦ ÃUœÝLM§[@„ØV  J|©'Æ£y£}þC¼ê°;k}FeöÆyOmW¤“-Á‚Qúµ“ô¢dhÕ09¼ÀÅyPG*¦p$y‘²2 )˜¦×Ø#&Ä·r”8mYEoFÙÎÙÓj”î@‚‡©‡!hEd¿ªFï(WÈìì4j£˜^.ph=.+¦ºðÕy)Ø4ø¹- %øÒRq\Eâ^ÈêFO»&E½«%®ŠSê»Vû9í!nLyÚp ©Ë©]'›c§õ†èáyÁp°“ûüƒ]ŸÆM:•x“L$µ³2É„7;Ý›<Ç3„„ 3‚°×EÁ¤îäªÃZó°¨Ò¦µ> ‹’{Ùñù‘¾?æò“¦Cø:§~>QW敊‹Cu‚'‚ª{°§ÃÒãÿÊî±Þ"ÄæiÊ“Kü!¬ØVûC9[E~wt _>w^loõAÛk嫇t«óÛèSøÞCIÐóœÙçÚXªíf}y÷‹Òº² endstream endobj 15 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 19 0 obj <> stream xÚíZM—Ó6Ý÷WxéœS }ËꜶ‡ZrÚEéB{&*އvøõ•,ÙùRB`ÈÀLr²pÛ²uïÓ{÷=½è}„"h>(8\‚TFãiôd=zŽ#„2]E”r E„,eÅzð÷èWs1{QBqj¯J¨·—’Äê²È 4®®ì‘Åê7¹;Ìý`$BÊí`Ð »§¡A‚¦ñ/æz7ue†q¶7ÚŒän+7#ó•q3†½ù's3çî Ö§ðç6²˜@„·$„! ‰9b@ˆ?a!gñ‹Jeº¼þÑ÷"Z4y½üG•™ÿ’ý³˜7æ„û™©F˜Á©’Þš™íYq3éÇ%þüª'„p{…Pꦬ]A»Iš7'$~º|s¶2€Ä ½øÉZÖñ¬u•7l<謕zk%pd¨$1O%öT>×Þ>÷“IÆg2ïžLH·Jùn2‰'óñŠOÙM&‚¤éÙÛßîσø3¡C´ðüa 8ßàÏzV)¥q¬-uÔÄlUίªzªVBö‰XtR!ûóîÛ&I˜,ÝÇv\\äª|t‘gZ•Ž“¡‘_XÄÞ](1¢ •»)yÐðx‰öNà/­¹úãN“‡FRœ¼ÇzBÀCac³‘h¤®É X”` órÑeOõ¼Qå8ôFOu¡jÝØlãÆ¥.Ó\Íu>iZ£,¡¸{"·'‡ ñÏÝŠE0(ƒmކWe0éep€‹¶ýŒ[gq©æyæNT¥;6“Ü{mÝH®ê¹;ƒãqU×y±Ëî±`6ÙøºxmO•¥Kç±°okêÊz%½r|Y•ÉLÕjš7µ»)f+ˆlÙÀÚZ–Ð[MéûWoˆ ºˆƒÐnDÉöÔÚGgQMµaQÏãBg¹*7h|MÊ%Ø2k;“E]ÒŒ$À3ï„ÏÚè¾ ˜$PþÉ Ü'·|´,ÒCXð’gh\8æñMrY 3߯öç;ç¤ör—–~Îös‚e›œœõNáBÏç}F÷aÀh¬ŠEЧJ~.âÝ ‡6­cò™çp¨ŠñÂÆ÷ŽÇÞqgë._™Pú_h £¾äæ6°P°3gD‚Ò”¶¨¬HSê¥é°XÌû²–`&g:)õûEP“¢tÿ’‹€¤åðn"ˆ&ii/iÖy­ê±¨=V…sý+plÓÈyÆN4íýâJ_§h;,N:qÔ¸ÝÇÑ™#ä….ß ‹Õµ÷û@ú ‰n¹¬‹!¶\¯yÞÌ ï7`ý”á3ð]Áú]Ú1Ç@öXó=Xû ϰšÎмù2´?(#Y/"=Qê}üÁzã³; ?Ó3pÐÝÊŠom³Œô3Þ 0sÿ9HqœëëɧqF1%aqvÐ_»Zi¤:ˆ=îØ{Ugýæ¦o§0KâÕ¢™-÷ý¹.‚-ƒe~šé*Oë’؃¸ðˆ÷ØÒÛ‰jJ΂ñ¾2TÈÇË.”îÊIi_¾M:»OW—ÀÝo߆ {@tËÂd«·ˆÞ%Ó\•¾R¹–{™“‹ëªÖÍd ê `ôMŠy_: [öâà@…œ{ˆ»z¸J^ÕתÔ{8.Ô,X'p£¬ÉÏYí±C“ðvÑã݆ßÔ^Óë™ËmI«I‰ îUé÷w½Ù–ª¸™ë W‚€#ìóÞƒäŠC€»T²&㊠ÌwÆý¾(˾ ã„ûaä“û£;Œ«é´ï—+téÁÖE%¨]Œö³ºº®Õ4PÕáhéïkYÿxq~­ÉÑèÞãNYQb7‡Û.Gê{—mŸjçèüßî’,ΕèqïKÉ8ÝÆøÞ!‡ûÐnü¡8ËÝšxš°eͼ¨fSÛŒ[ç%lãïfïØxèñ²¾½óµ;R]”Ãr—™¥~ºOôe¡íâžMlãóM°uYÎNºéfÍž0_®câ4ʳQôÛÿFÙA endstream endobj 20 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 22 0 obj <> stream xÚ}UKÛ8 ¾÷Wø(µkÉïÞº}]`(ô²Ûƒb+±°¶•JÊdÒ_¿¤(Ϥ“¢ÈÁI‘©Lò=áI?ž´"i›>ïúdX’?vÉ›O"áEÞ}²;$¼Kx™÷u²ÿaï'yòʦYY–Œ¿M³ªªØç5-óÖ¤|ÇóàµYÓo»?“J4y]C¼+‚êͧ&ám.xÁ³è‘U_7žfu#0hYPPøÞý^‘d¢ËQFxóÙ¼®grAè ¶K;Á¬R_µºD“Ud:Ys´rqtò“ôOz¬éA*Þ ý`–ÓÙKÄ"çi ÐiÒCÐÃQ­Áš5 ¸)4’S#2C:Q7ì`, “óõ‡^t¥—$¬YPjÙ‡¿ß‘jу5ÒZ‰®dT':¦¬Þ2¸×ø,‚m)ŒŸ”%ï£Z DyÎå”w9<*ïÙnR÷¨c»àBÓ>7[4äJ‚±G¹êŠ|BsPM…):2Çú@¥ãõx ÐÏK ¥ì«(OËÌFýoÁKeŸÛÆ ÊÔŽP†à?¿ý]=ržÃ;_¥ `Hí­ |Ú²Š8Ñà }÷Ôf:ƾÍÑÞ[5©ÕéDIÜȶržªoVAó4µ°%ŠÐ¹ªì *å'Ú8:2©åDïq 9 gY «à/ê̺À€/Ä[÷qÂx£ÏHÃqYIOC„’óP²´ã=%N·ó4Ç¢éÙðDó¶ ;MìªpH¬"·]Ôã æYÑ«E¾«GO„!œæ?Ã…‘Ö5“z–û9ζ Í¿LM§ l¼<ý‚ÔI×°êœ9Ì|‰ ìõ~Ö&ì¬mtÿpÚ…Zi!üîæì ÙC$zud4­LGÄP¬¶>ݯš3d¶k%/B ø¥!a¯ÍlŽqãÂÙ Ç^É+¦\Ü…ƒ†9¿’O\yäSo 7܃?œ—¬ áõd#s ¹ á‚‹áìT\Èšý»äË«ÿÍì j endstream endobj 23 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 26 0 obj <> endobj 27 0 obj <> endobj 28 0 obj <>/Length 8883>> stream xœíÝK¬-{^ÐñÚg¢¨˜¨Q IӇ昃ÚçhÔ£LÎàLŒcÝàõ^l`÷¡¯í#­¶‡&Î02í#î£A¤yøB0$`|Lµo]êÖ®ú׿þõX«ê·ÖçÓÉîµjժתúîZµÖ>÷æ‹?øý‡÷λïÝÔÉþø×~ÃÞK@ÎÝÝÝ›7o>LöüÐì½<Œúßû…GÉþú×oñ´nnn>øùðã£7Þ¹y4Ò‡ƒ?¼Ñ»Ù›DoÐMõxz&÷áàÞÿæñhhoÚ7©çõ¿·€™ûø:þÊ­þìò[ ¿)¦Ö±·ým¹ä²-XÇGž~¹ _åÔË=¾õ–iý>Ö{`ó}¬·lë÷±Ñ-<\ EûØ`—^»õæ>½Ž‰GsûXj—ž\Ç#ûįúñt²ÿßOýÌÓ>ùÉ7ÏŸ¿©oÔ?ß¼y^ßø«ÿç«™‡Óì—³z´¡%»¿)$[²G·ðp$û:’}{ûéêƒR¿xñ¦ê´ûŒÉNïjÝÛêpJíßcë(ÙŸZv8IvoÙ${znžì?þu¿¦*öâÅ‹ûûûYãÿ©Ï~4ÏZ’ì»»O7án4'Ú‡MöŒ—³7éÔþ=¶Ž’ýø©eÛ_²{Ë&ÙÓë˜xôÉ.üT¯©gìYã·É^ð¬‰dwÓܪ“ݽۜhï˜ìÿño߯þ–¯ÿÖ“Ý[¶ÉìßcëøÑª­9œ$[²G·ðp${ûd×wÇÆ|ýêeužd÷=Ò l“ý~âó½G¿äcßœ<œf¿œ ú¹÷ÙîÄó×½77Ùÿõû¾«þÿ¯ø}ß±ìpúñúmíÜ¿úOoê_üÂ{í£Ÿøc%{0?^¶õ‡“dKöèÞhëÍN²‹“}{{[3–ì'OŸÕ?»Ó²*Ù÷÷ϛϫÎgõoú“¯oüߟ|xÖ¯þªwJ§Ù/gUýÜ¿èõoúݱûè9“Ýôúcè»ë{?ú?Ußþøùžv:_ü·ÖC¾æ¾_ýÃÿða!¿ö›>[=žûšdtï<‡Ó¢dHv.ùí/ÙÓë˜xôPÉ®Ó<íîî.Ÿìêq£{_•ì®îe“æ,;“ì_ú±¿ÕŽü¥·ô‹_ü\wj¿þ¶õ~请ãïú–ª³¡óÉþÙó™úÆo}ö—êŸÿýûë’V¿í÷|ªç§ÿÕ_n'øå¿÷Û›d7¾â÷ßÖ“øOÿâ®ò•ÏïêIÿäýÃvÿà;âŸ}ÇWýÁïªR‡Ó¥&{lî’=– Éž»nÿéuLÕÜî]¹ðd·ƒú‡Óð©e‡“d÷–M²§×1ñèÅ$»J]!©Ÿe÷Ý~ϯ9×&ûÿǿ݌ù%ûæ_îœb7òÉîÚ$Ù/ÿÆo¯F’ÝÕ&»>ËÎNWw–ÝêNçNNnJvÁ:JöÜ},±ýËÖ1äYö0Ù½‹$½¿¦Iže7Õn“Ýœe·Ûwò,{¸¡7¼0’<Ën—M²“ÛÿÑ„ŽŸìñ-<šŒÇsï? Ùíc£Ûz§^åüö/[Ç]’½ñµìûûçÕÃ×¹ß ºû%¿c&»™Ýû—á^™ìäÇ?òæøäåg$»üpztó(Éž¹ý%û ’Ý=óm Ï×'{ûoŒÔ7êSéî…‘VïOiƾä÷K¯Œ]©üX=¾0RM}Éïg~à3ÝG“Fêÿý—ïûÎfÈðãÇjêÂÈðK~m²«Éï£{§<œÆæÞßÑ%»7;É–ì¥_òË[ø§4ù¯Ž\à_?ö–mQ2$[²gìc½¹¯ßÇ${Ñ>¶æ¯3ÿ„õ9’Ýû¶_ó5íö{Ù’-Ù’½|ëÍ}ù>V¶ý%{dë˜ÞÝÝUešdÏ¿Mö‚gÍHöø´žïûë’-ÙEsŸÞÇnÿKJöØ:¦÷±Þ²]J²ÿî_xURß¹sYøÏBõÔ)¿Øª·l’ýhuÿ?·${Æ>Ö›ûò}¬lûï—ì±¹$ÙG6šìe$[²%{ù>Ö›ûò}¬lû0ÙýWÿñ¦ìd²÷^$FI6@’ †d„!Ùa,Oö“§ÏzÿHàæÎ0 €@¦“Ýû+ûz̦¤kzÚ{îØ¤$ «(Ù›÷T²X’ìÞYv{^ž×±d÷&ÕΨSÁk¶öÂH7¾å'ÅÉÒp8©5³¸ÿ¹÷gý7d$û25/^½7ì½ ÀÉF²! ÉF²!Œ£$ûÉÓgÝ»õtê!íÏÌ2MްøY˦‘dCJv²’}’ QHöÆSŽH²!Šã&»wa¤½r’-9BfH;°dœ‹'ÙÅ’ÝÞncš¼¢Ý‹ûä™qJ†ä¶Ç¥lˆâ@ÉÎtvøádr´Þ¤z¿’îMV²# “ì±z®9ƒ›éØ"]*Ɇ(â%»ðÂÈVC¦¶É%lˆ"F²«u?Vƒ‡C|ü(Ùp|GI6;’lˆB²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²‘lC²ñ¢@’ÍÃëº÷"¥$àI6@’ †d„!ÙaH6@’ †d„!ÙaHöeª_”½(r{{믯]óâí½À„Ïî}ÿƾx÷÷÷{/S§U²‘lˆA²y ÙÂá’ýäé³z sb%Ɇ$›’ !H6$B8t²ëÛÍfH{·Ò{V3ÂäÓ'ǼB’ !7Ù½v7í é>«ê¤y,è½&'{=$B¸œdê•g’Ý]Éë(Éëi÷ÑYÉÎ Éœe_-Ɇ$Û…‘’ !%ÙÕãëÑÝ!UñǽۅF†3ºB’ !(ÙìH²!ÉædC’ÍɆ$›’ !H6¼(…dóðºî½@)ɸ@’ †d„!ÙaH6@’ †d„!ÙaH6@’ †d„!ÙaH6@’ †d„!ÙPäÉÓgÝ»õq±×’pÍ$ŠÔÉîfºwÎC²¡ˆds’ E2Én¯™4CÚ‡’7*UXA²¡Èصì^»ëÛcɇ¹$ŠŒe%{øs8˜K²¡È&ÉNf‘l(RžìɪÍb'Lv÷Úß.;¨ƒ •ü8|´7¦Ý’ÅN›ìÂ7ƒ›´u8É.Ì™’=¼›sÉ.Þ>É~µw»J½y콩ÌL¤;Çü³’O8¦Ï²‡Ÿ§O>}ì#øäYv5øë†±Y;%Žoç³ìꃤf›àðïòFz~Ö¾XQìì’¿>=3‘±ñógâ¾* „³Ã7F–%{Ù…‘Éd»0²Ï÷²3W'&ŸUøeØjä@rÖÃy¿~C²Âl(Uòo0øP„“’l(Rø×¼’ÍII6)l±dsR’ E2§ÕÍÉ/¡¶£ ÿ.7ùm(égH²¡Èä?«ÐuÉ_ cío˜$ÙPätÉNþõ€X“$ÙPäœÉ›H6I~cd2Ùíuòd;×&C²¡Tò{ÙÉ«A¬ç^©|üHŠd„!ÙaH6@’ †d„!ÙaH6@’ †d„±A²ëGO¶x<²6ÙìN²Âl€0$ ÉC²Âl€0$ ŒyÉŽø5~cF²ƒž†¿óî{ŸÿÜû{/ÀfüÁzÄ^W¿²†÷÷÷{/ÈrÝ-ñN×Á×eßÅ;ÎÜ9¬kIvèíöBÜW¡uðuÙwñ2wŽL²hß(} º¾.û.ÞæúH¹$ûÉÓgÝ»õ¤ê!íÏYKÓÔÜ玹€ñà™›åàër„hJ6Û$;™×ábùd/`GýÞ˜åë²ÕÌ’fû²ö¶y{;sÂQ²ÀùÓ½ÛÑp`áì’s—ìƒ;I²»½kv©¶#ÍÝ»™ý¬wÒ=öÜäÔ[ÃeÉN>T2ò¶o${[k&{1ÉN¾¦å¿2OñBçɾH_Ëî½j¸?MîÖÉÝ.sþ›8¶#æÏ£7Lv~j’]2—Þo÷á/û­Ì]¼L²,ðÊd>šŸ»dÜ9β{ç¹ÉîýbÈ<”\ÃÂd'ç2vzUëíš #å³Ë?4|Ã4¶ÌÉçÎZ—äŽ1œÅØK–8‘¹›:9°0Ùc—l&5Ù“oKÞfNž¼'×°·#N¾ÉM®ÂØÜOýv¡üg•z£S8»üvHN9¿ñ“sœ¬ÒäÎÚòË?kSw·öØ“;ÆØ‡K;÷ZöäÎ3«Ú’Â>É.)]þö¾Éžœo&ÙOæ¿]X|–=<ÎK–¤äuÉçulŽ“ëR Þ¬t'2¶_õÖ1¿ ™ÕÌ/^rƒ,Höج'7Îä¯öá@ɾ<'Ovõx?nFȤ¡½=ùPò -Ov÷î‚dWÙƒ?$ç·Òðék’=¶`…K2¶Öå¿tç®K>C%çªùeÈmÛd—ŒY8÷YÉîÞ•ì sý8ù;¦ Sï¤/ùÄá,ò·Ï–ìÉÙ•<4¶eJæX¾.%¿i,íäÊ–oê5Éάæú+éUê\§°Ú’‚d?òdüZÁØä4·}»°íÇÝeN®ì䳆ۡ·)Æ&[¾.“礙¥\µä+8¹xÉ çU¾Àëϲókšâd‡pÉ.W¾»ŸÔÁÿbp–ƒ¯ËþþÐ_?’!Ù9’½¹ƒ¯Ë¢)ÙdHvÏÜ,_—#DS²Éìž¹Y¾.Gˆ¦d“q-Éý_¥®Ê‹/Æ~w^~²ɿݑl€‘l€0$ ÉC²Âl€0$ ÉC²Âl€0$ ÉC²Âl€0$ ÉC²Âl€0$ ÉC²ˆì'OŸuïÖËYi®™Ú‚§œZød'Ûº ܽ‘—Eà¤${bRÇqiÉîÆº¹ÐÑŒÐ^ôèÞ-<­>·7ñá8ÉY¬tôd×K0øúÕËæÆðês/ÙÝíS’'àÝ‘‡ì=79»äôÛÉ.Õííí)ª Ùõš÷¶óš<ËîU¸‘Ovïnþ¹ÝˆwÇN°ÞDåk „vwwwÕÉ›xy²ó)|nþ¢¹ëãpòáZ9åëJöä…‘êñeèüsË/Œ×C²—$»J]ßÈ”´;ΰàÉçŽM¿zÜ}àªH¶?­ÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉÂlÉ ~±ö^„²RN²*4»ËÞKqõrºœË#Ù•šÝåþþ~ïÙ^½J6å${ÕÄKÞ°ûŰždCC²×&;ÿ†ÝÛÞMH64${ƒdgR’9 Ÿ<}Vÿ¬·@ò‰Í£­±Ñ®DÜdßÜÜ47Þ¾}›"ÙÌ"Ùû$».rSááÞÉ»›8Å4O$h²ë:wK]ß‘lf‘ìCœeë¹K²qɆ†dï–ìV2”Éd÷*ß<ÔŽÖ»ÒÒal !ª-ÙÐì“=–ÈäµìäU”¶Å½4G¨ù›õ°ûÝÅ8¿ É®W®%›•${ÏdgNió§Þù 'GÈT~Ö‚í"h²e³9ÉÞóZöÜ cŸU–ŒPžlgÙ[‘l6'Ù1¾12ö¬jÎ…‘’díüº!ÙÐìC|üXÍ<Ë®:翳>~ìMç ßKÙDÐdW¾—ÍÖ${m²_¿z™Ç¹^ÜdO’lf‘ìU¯¯d4äJ’ Év¨ ÙÐl‡J’ Év¨Pò™A\’M9Év¨Pø™A\öC I¶CC²%C²%C²%C²%C²%C²%C²%C²%C²%C²%C²%C²%C²%C²%C²%C²%C²%C²%C²%C²%C²%;€úÅÚ{NÈ~H9Év¨Ðì.{/ÅIÔGÈévr.d;Thv—ûûû½d{õ(Ù”“ìU/yÃîÃz’ É^›ìüvo{7!ÙÐì ’IIæ€|òôYs£ÞÍÝæFÒðÑvH;vR+e浉S —ì›››æÆÛ·oóI6³Hö>Éîf«¹=+ÙÝ^'‡¯±&Ù…cÎ]ÎXÉ®£Ü–º{;ùd3‹dïŸìäÀ±Û½!ÛžÿN.ɬ'®­+Ù]’Ͷ$ûb“¼ðÒ ìN¹;NÉ’ôÆÎ¥w{ì!É–lì£\Ë®Ö%;se|ëᥘÌ–䯇±)Ìyl£ Mv¯×•d³šdï–ìÖXÝ2׸'¯ew?“¬>(õXÄ»ã g‘<ÅNN3³`×™ìa¯+Éf5ɾØdO^ë(ùÀ³ðd?¿W˜ìd¯+Éf5ÉÞÿZvÉE‰±§Ï‚\Ä›Ñ䂹0’4ÖëJ²YM²t-»^žìÞt2Ž]žN.ÃØÜ'?~ÌLüª’ݽ[w¹Wêvxå{ÙÌ$Ùk“ýúÕËü8§X…¹É;šËNö,’Í,’½jâõ╌vŠUˆ[íK.ÙÐl‡J’ Év¨ ÙÐl‡J%ŸÄ%Ù”“l‡J…ŸÄe?¤d;T€0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$ûê’]¯ø9gwùœyG:³Ãî·’}ÄW多MžyÕ/ÿé^AöuÎéÌŽ¼ßJö_•“j6ýýýýæUoÞÃîú¬tÎéÌŽ¼ßJöª‰—¼7<Ú/Éf’½ É^›ìü{þÒl6!Ù»ì ’Ùkó¯ý“§Ïê-™þä œúH»¹¹yûöms{“]ÿáÌ3êMyÖŒJF®Ç©öF{b3|ýʆKv½g67Úýsì!É{T²'ŽäÅÇU执;Ò†‡DˆdŸÿW¶ÉKp>Ùsc(V²»gÝÛɇ${ìÑ«NöðH‹žìF¸³ìËHvoÌ̳Æcîvˆ•ì.É›²dÏNvõøím÷èj†ôF鎟<ŸìÞªµw«‘•{ÊØoÄÉ‘‡#4f`8‹Þs»SHNpñêO&;¹:UªÑ³ª-Ù»ì}’=–’ä!Tr&žlIJe^ie²‡+›R8ÂpÊs§V ò?QKöðêäépùêOžeç>¹ý»õFšì^¯+ÉîLY²7KvwàØÉWáûâ Höp´îò™«›®üÀØô>ÿ3¹Ž½‰ä×%3…ä/ìüúæ_‚ŒˆÉöº’ìΔ%;—ìîÝò³ìîðÌí‹Ov•]ÙYçÝË’™ïšd¯\ý’§\íYv²×•dw¦,ÙéfÍMsÉ1™éÎÜe^éPFƦ¹xj“ÕËTu«dç_ëò æ~R¬dõº’ìΔ%{^²‡u‡7C’g@Ýq2瀅˼ÒA>~ÌW¬7ÁaËÆ¦Ögò,µ7…üYprñ&W?¿²É >1/\²»wë]´Wêvxå{Ùã^B²_¿z™çh¯½¿~¼0sS»þ‰XÉžåÈû­d¯šx½x%£êµ—ì˳ ¾+{]IöN$ûˆ¯ÊII6›ì]Hö_•“’l6!Ù»ì#¾*'Urý}C‡ÝõYéÌ;Ò™v¿•ì#¾*'Uxý}CW¸‘¯Áùw¤3;æ~+ÙG|U’$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²0$[²¨_¬½á„쇔“l‡JÍî²÷RœD}„œn'çòH¶C%€fw¹¿¿ß{A¶Wï’M9É^5ñ’7ì~1¬'ÙÐìµÉοa÷¶w’ ÉÞ Ù™”ŒOž>«×=?$©ü‰“ÌL*ùÜ g=W¸dßÜÜ47Þ¾}›H²™E²%»ô)’]¨Žr[êîíäC’Í,’½[²ëŸm×zwóºAÌı$Ùs—aÙ¬×:¼^‘Oö0Ð fÝ›ãØ¶Êˆ˜ìa¯+Éf5ÉÞùãÇÌÞÀ*›ìáíòÇn&»pÖWu–ìu%Ù¬&Ù’¯ùðîI“½lÖWu-{¬×•d³šdñK~c×ò—’ ¯N”,ìdOÎze¯«€ÉîÞ­»Ü+u;¼ò½lf’ìµÉ~ýêe~äz±’=‹d3‹d¯šx½x%£9 W’lhH¶C%Ɇ†d;TlhH¶C%€’Ï â’lÊI¶C%€ÂÏ â²RH²*@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-Ù@’-ÙQ]üòD^¼x1vXr|’-ÙQù“/?,9>ÉvÌG%Ù Hvt’í˜J²ìè$Û1•d/ ÙÑI¶c>*É^@²£“lÇ|T’½€dG'ÙŽù¨N·o¬…C’WŸ$Û…’$[²£:g²Û!ù“ÉOyøôäd·"ÙÑI¶dGu¶¿~œu½âü3‹dG'Ù’ÕÑ’½ùòNA²£“lÉŽÊ¿1²€dG'ÙŽù¨${ÉŽN²óQIö’d;棒ì$;:ÉvÌGUïwww{/E<’šdKvTï¼ûÞÞ‹•dÇ%Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’ „!Ù’U½oì½!½xñbì°äø$[²£:ݾqÁò‡%Ç'ÙŽù¨${ÉŽN²óQIö’d;棒ì$;:ÉvÌG%Ù Hvt’í˜J²ìè$Û1Õ¶ûF½?¼~õr«©ågÔ½[Ï´™õy@²£“lÉŽjódŸb†¸™QwH=Óz]îîîêáõÏ“†[²£“lÉŽjÃ}ãtç¹ÃÝllÇk†7á>Ýn)ÙÑI¶dGµm²‡¹l¯`´ŸÒ½èÑÒýMŒxó £Y†áÔÆ&µlM%;4ɖ쨶Ú7šb6SkO´ÛõíæbEáö¢GoÈð7AÕiqû £ùÙ>=9ñ5k-ÙÑI¶dGµa²Û=¡½ÝÛ=Úkͽ!ÝéôÎÓÇ.tô®e·óê&»˜™øš••ìÐ$[²£Ú0ÙÝ»ÉdWãW¥»Ï-OöpÈ0Ù™‰¯YYÉM²%;ªMöîÅF÷*DßeCÖ'{lâkÖW²C“lÉŽj«d%µûé_{¥;?¤{©dx}*É^@²£“lÇ|Tÿ?¤„d‡&Ù’Õ;ï¾·÷"D%ÙqI¶daH¶daH¶daH¶daH¶daH¶daH¶daH¶daH¶daH¶daH¶daH¶daH¶daH¶daH¶da\u²O1Y€“ºÒd×S>ÅdNí“ @K²Âl€0$ ÉC²Âl€0$ ÉC²Âl€0$ ÉC²ÂØ,Ùwww'[H>´A²ßy÷½“-¬M6»“l€0$ ÉC²Âl€0úÉ®ïï½HôÝÞÞ6‰î'ûõ«—{/´‰–l€£“l€0$ ÉC²Âl€0$ ÉC²Âl€0$ ÉC²Âl€0$ Œt²ëŸ{/ ‰dï½HŒú(ÙþbÇ÷ìçÏŸï½ùÿ Oª9 endstream endobj 29 0 obj <> endobj 30 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡©…™ž9DÜÈÐØPÏÒDÁÔØBÏÌÒBÁÌÔ\ÏÂÌ¢ÞBÁ%Ÿ+?H] endstream endobj 31 0 obj <> stream xÚmRMoÛ0 ½ïWð(µbÉ’míÖµËaØ¥€o[ª­Ì+õGýûQ¢Òm‘CÈGšïñ‰ð  ü ¨%Ô•áîßZØí%ˆ‚›Â@{Ñ€(¹ÑÐö¿ØÝ`Ï«›³¼,K&¿f¹RŠýô¶§?7Uìw!Ô{.HÉìÔ§ ÿ»-+¨³·«ÍÛ dŵF-¢ŒÐn_¨¹:hÈSG®P¦Œm2Ëu%¯¹kýžâÁ7¦¯Üß[xs"’ÔH¦t0c·?pïááS[òJ(N¾Ü‡q¹4ëìÁžð¯fŽ’#Êt=Åã”aaõ˜5†ÝQVp”¾ÁÊ¿4(ăSü…8,LÍ}â´¶£ú6õ—ië°ýxL:N.’o_NvK(a§L6Õsô¦@CJ.hEÀ’F-çuôÓB‰çÙ‡!/#­©+vðsêys>¦SOÁÕc@z1H›é½Ûo4q°‘"Èt„­aaX;¸% 8lSG*?¬Çcì:·,.æËh)ˆ"Âu¢i¯—NÏ{uËŠÝÆ­Þ—Wû´ðË]=|ùÕâ' endstream endobj 32 0 obj <>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 35 0 obj <> endobj 36 0 obj <> endobj 37 0 obj <>/Length 6632>> stream xœí]opU¶ï$ÈŸÌ%*⊈‚1øa«puµ ’èîjýð0±jñ•ZlÕÙKÜ2Ùû–Uúv,µj‰ ¼'bAÀGBŒ„éI$ÌûÍœäÌ¥{¦32齿Juu÷Üîœ{ûœ_Ÿ{ûœ{ã|>Ÿ¦   @œbF\Om­ætÆ=ü°ÿÈëõÕ×Ç¥§kø}Á_5Í÷Ùgš®÷^Úwþ¦“¸ã‚ƒ"Ù¡Ö6çÈ„‡RFGRØ{½»Ás%#e´cd ü÷Ã,IT¡ò飓&IŒ™Œ·Š ]úõbp¦ñJçã©É6JÕ/HHƒ’ÈßÚ"Ìí|ÂsÛȵ«_ÄÝÈÉñÕÔŒ8yRs8z~÷;ü%|ü1L½ç•WzÞz«·PVV®](нt© Ò‡øµkãÿ{ÃÉíí·.ÖÏöhTµ`Ú]ÿ9+½ßòh—W?mÜ4+=’¦¡Âÿ½èÁ[—Ó¨×Kµ_ê×»Aûg@Ï¢­ð‹ý_äÜ;~ÅOÆ÷[2v±(ï¹}áLLÿoɉ¯Kš¿[ñoC)IT(?ý-Ú ;ühèü»þ·0#­ð¡‰¶J) ¿kÛg°DˆóéúéÓã]®øßþöÆŒØâÏ÷׿vÄoÞÿë_ûè^±Â_àí·aü¸&¡ª Ûž5kz¶o‡ý‹'°+èÜß~ö */ê½~AÌëLüfnêètŽ“L¥\†_ÐŒ_]ÄýQ€.߸9¶s7`¸óþÅM}¿z6ÿÎäh+¢õ½µð¶±"á°·Ù³þÈ9ÿmÇÉø§üI$ö òCfò5èƒø– ‰û߯[:iÞôh˜ˆr2^ôzHBnLóc:á¯×*ãHL Òµ‹„ÆñÀ—Ø13Â; î'¢“Ѷ¼¨*þq„ž?ý©§¨Žº pü¾@n®vþ|¡Ctß_€ñ77û_×Áþ“EEØO8qB<ìqÜDõ"‹¢ªÒaF ’¨0ì ;06Ñöp¡ÞÕó ÒZ&Qº-ÌõÅgð+.~àªÉc’pˆ×2Þá(ÜpùŠ#q„·ëÆQ×ÌÙÒ®ÿ»¸þÈW"D^h*éè¡ï¼¶WÄ (% ÿ]»ù½D"-M‡êÐÄÜ% ¦øÇŸÞkÍ‚òSßÀ¥BSükñCƒ"¡5` ³+o{/»`hmüw¸<ÜþäM Uq†J²ÁU æ…ähíª —© ,9¸€‘/Úw¢V5_60BcGWú˜DÈC£yˣôŽ,’矰w/^ûÔ› w€;`°úâIr1n±òÖŒðî‚û—¤¥à!áapmñÀDF€zýǧe§¿ÅMB6íüæ¾ÂS?º,“Ø·nÙL¨ Ôº(c"Þî[â?B(ÓžfO´œ"#Ø[‹ j¡áÌó³ATSp"´íSñ‚‚*£5à΄”Ÿ›%ÖÙßAkS‡Ž*µõ§SÐt`Øüiw5Pc†d">Ü¿>–#ŒÝ0Ú  »5ôÎHÙ 'ܪs*ë£jy´€¨*½ŒÀ6OÿÆß#p»áð¡Ÿ/ÈSìÚ…~„ßAØ»—´Aí5/Cv§Ù® ´-2‚¡ò†DÏÌJÿzÐÔѵ¹¡™: hÊh]Yr&iøú;G[‘l¬ˆ5Â1‚È}d'䜇«ÑPŽ> ‰Ð8¢Ý†S$êÓê"2·uý/ä´qhê‘ù2x«“WÈoÖ qd$’–Ç[DT•ÐŒà;X²$ÎåŠ_»ÖWSƒŸèå4þÆÆ=f\·¡&ÐrTæËçgÓù3Ü*¼?_:p†<.~¡a‹g ¦G+û½÷TÇÁV¯ß9‚_ QIzFç­(# m8lxùD[kF²ŠX#F g ;•úP8Rþ¡a"ÍüîÆ>,нCû£C>Ç}œœmx^è U§¾_?T‚§ ÿ\dtCö4_ö÷úª#m…-´‚{7\/ͤ'‘·<ˆgDU Í€¯²²ç•W|çÏkN§ÿ›B /pÓÈ"}˜Ø»·§¸XTFÈU†umšÎ]¾1†=~§ƒšƒ:Z8ƒ‡&ÃI­ï[ý_- 4PŽhù\Æ}{º<ÚŠX0ÂPVÄ‘0ª —êËu7Ë?dŒ@Ã|hYÛrnü´^Þ» ¦Â½"9q˜è‰Œ‹zéÀ—¨¦Íç¤ÃÜbfF /P‘·¼AUT„’‚‚BŠ‚‘zz>¶[…)dd„kW'Ø-‚‚Š‚ˆ;xá¨3iìCã§áÀÛÕÞÐzz²cÂäd¿Mj®Ãöñ´ÞofMm-MÞ>$.N\<­w¶‹Å¨Œx†n%^%Â^F8¾ÙÙÃ#õضíêªU£ '=žžmÛ¯bgÕÊQ))ñvÈC×}ãž{B|ïØZÚ±~ݘ¡,Z@%¨=W7Ž5ÿtOz‚ù)H…šš®šÚ®pr~à¾63s$žQÜ‹•@ u¿r;Ç–)ß|¤¼:oF;û/.}wÙ–¥SžÀýÚú›Oø.(³hGžÞÙÆÅ^­ùCÙ±8ÌH¶?w[ÿá;OºùB.äLwm}ò5ƒp624xñ’K.×m†§.-@ùúÕ+wÎ?µøRŠ3;Ý÷Ï}·Û!š<Ø n…$°™Ý»ÆxtPTÔf^Bl*n‡E‘ü¢n€æÎ»¾ƒ±É¬6ÐT\€ZàРÇ_Ÿ÷Ø÷ûöÞŽ ÆÁžaùK§,,š—¢¹ù…sóQ¨üXìþ¤9ŽÄd2Z3#àLÙ± ° h‡{¾,õâó'=úì{ù¡^À³ïx;Ûð_èÂ'+×øúÖ'_Ï™¾LÜ峑ðtA¢™3GJûhEÀ¢Ïw—¾uÅlT¬¾£Fc—ÉÁZ ½‘ ŽšÉ–@[Ý–/¿œ•ˆ·hfæÑçB ‹¼GÇêh#ùZŒ} 7ͬP{<¢lÿ8ŒcÍ£·œZT‘—î˜8?mXàLÁ~-#<÷~ ú @D€QÃÓ÷-ü¬õt“÷k¾ð¥¼ÜèýšÝt1¨Ã"ÂÞ^ƒYw%G8›Ç3.,ôBmwËÉó*Ùì}ÐË•4\|8;))qNg¼®÷à]*’Âê|½¾þ:vÊËœ3gŽ´Oƈj€¿&2¾þøuø’Ðù^Fж¾³èÀ_ÀÛ4ê €ÈÝ/äK,„VŒÂ1ì°¾þªS²9ÙFM%:X·vŒØ}…wãvwB/mta¢û\°¸ L²ä#€ìÐk€]íÞ=ÎV1ûè ô­‘ÑÐ_ÀÓùâdêòž›Á`íä5ð¨·oÍè>€8DF(ÎÞÿH®áæë?|ã`óѺ_~ F7~´eͬ\ƒ› !*„4*Ö`{«…#U3ŒfÁA¨­íâCùI!\{Ї’³FЖÁÁüÅÅÁÜüšÐeÀ¶8ûel+>wW«FÇ*3Ù1¡êl5ˆD€íéÓÞùù›SËÁ­È?G( 7?Ô\ÖÅäÎp•Û±çl5;& ÅQATDV\òÉÑo,,lûs¹Ó®O'p¶×­î7ö! þXB³ð2ClO¸6ØÙa / >ÂÆcÑG#¯ÇnICƒ¼ø2tˆGµÀC¡3¨`Xº ü†GWáŽ<˜}Cë)”áÿNAÁ¬<úT1Ù1qÛ²7aÿ;OV¾Z³Eïl+x$oSö¿SIÝTû ÒäýWá&†aEÍnF@Ûa+ù—$x–¬ˆ¼ç jÃùŒë6[ƒÍµñ᪕£Ðª¢´ÚÍÂË ”Ag›Û‡+WŽBwì÷µÒÒ+0-XTÈ/¬2Ò¯¿Á‡hsƒžsuT„’‚‚BŠ‚PŒ   „b… #(((·ùpÙdÇDðojkÙù¹{þ¤Gés`IàËBÁ¬<Šb<Ô\wðÂ'tÄ “|oW;î w¶åÌpQÝÓ™”Œ38}úÉü¿x²>²³ Ÿå†KÖ cÛ¶«ç»ÍyDòT$¤„Ôþ|8,¾õ†kj:³:I…p*AçÎ8JŠó3Ǽô—9ë‰>:Â’7eo k7G(QpAFê´†ÖÓ¡øÜûØw$%{;ÛpJš@&o ¶œø€’õô} ßùù›tLˆ5#@—¯¸¼nݘÒÒ1ý†"íŸq%agX¤6l*nw»¯AñD¿8™Ê‘'ò¤ß„“A÷ô`çÈáþ°²á*¢B*6ZXfFðxzœÞjV VîCQ5¯aö=“î˜P4·fÉyG¯ÖüaϹêùis¼]m0Z-#P™º_~°þÃ7.ž‚Iß÷öB1öÙïœtc§ìÓt-¥Kà†`ü ú8S°ŸØáìšjrFbÍ«óu<<0%Ø ôçr'ÇS‡‚–”8Ð|sç}ê‹Ô˜ŠqëxàÁVŠ–áÑyyÒoÂIÈÛd!ÂU„‚2wïJÁ¾Ìµ`U§×ë6¥BrT˜ÂÏôІç^àŒÐè¶½þÃ×ÉVœ× –d™Z¶èï/”Á {òö§ڬŞ8<Ë`0[K;êëoP«På¥ã€?sœ¥$é7jœ|·»“Yf„«, ä›™9:cÖ–ýF[µ9|GïÈ"Ma?Ÿ:ÿÔe€Ig¤>ðbår̸yÕ¹êýy;psÊ€†×€-¼x àŠ“îŒñðD v1yV™ÛÚÚ®áËò¤ßX3Âpq´ðáX`r¿¿i¹ËF!-`Íìéc Ö.NjPoßÌœÚLoþmËÞ¤xgxÔ}p‡‚zÄ5(àLJÆ=Ñ_À…/å i-öŒ°|ùå•«F=㺠ï¨íÛ®ŠCù‚xÀ¢g%-îžð-õi ½é÷$pBž<é7á$ÔúFmäodB¸ŠˆÙ2çhÐTÔ#ÆkOd.šL…è@ã¯kG—2—´¾ò$Ydöœõa8/9À÷…Emb:'I’~c!áðÊ(3W„Sƒh®42z@6NiÙ/X%HNj€çð“ŠPRPPB1‚‚‚BŠ‚PŒ   „b… âîÈÕ;Û)^Ç–NyÂÛÕ~ßÛ q2ät‰”éwV5Š}¢ޤdšâ9gú²ªsáZ*ÆS?Su¬ÁãéY¾ÂS[Û•••¸{WŠ8>\Xè-}ëJzzž•[K;Š‹ÛuÝ·rå(ó@7~ÕSnÛ%­êL‰7,Ö°:_Ç#@S—”$Û5ï›5ĤžÆÆîukG—”8,JÊšÕŽ¿=[è¶X2®¡õ…'ÌʃYΟ4‡Âˆ2R§ÍO{”lÛ̪`1óêg­§irœé.Ü‚šœIc÷çî v`ê‰5#àùÕÖtíÞ=Ž–ågÚ^íÿÚ|ǶíW©@LŸEP„ž¢Ó—Ÿ¯ÖeØTÜ^ZÚ±nÝÛÕ­ºxɥǂ¬éË(eIêgh@R•U+GÍ÷½Á¢äij¸¯¶¡‘ÉÎ9HÙ¬Û†’þ^Œ¯q*¶k¬õ… BŒ+Ƀ³H¡4;;å)fg§5Z(Kb듯ñ%‹*òžž²7äØ'¾³]QÌdcxeÕ×ß ”§˜Š1ˆ0GrŠ®½jJ9cжp!æ:I`h@‹plIšÚØ9¶¥¥WH½-ÂX %ýŒç–ÜäýšC‰©Ë€C¼ð) V=à¼J‘_ðMê~å†?.ÀÍñ_(bšƒ”lÌkÀËÖ£ût½Ç°‘Ì0/ËAašyP¶Î€`fIB.î"BZQÈV•¡©ÍÕÛ:°],:Š™» Τ䃎RoÿVryáÊ³Ä 6B pªÎU<’Ë…mÌ}¤ØoɳVD@æíÛ¯šé@“@Mi}Qt¼i^pjsþ쟥BV:Ð#ˆÖßþ³ÖÓ¹q>Xr£·Ær~ʘ¤•`ß]¶ž…¸lÅçn\üf9S°Ÿ¼Éމè2€exí^Z‹=#ð@Oˆ@ç-²Aä*»ò¥‡ žµ]My…uJÂ;hrŽ)ÄÄ‚ÜFˆm^Ãö¦ ÑÎ)„ûšõG@C ˜øYDÔmQf±¤ŠPRPPB1‚‚‚BŠ‚PŒ   DÜÁ GIc)|Ø0 x¨¹[óGýÒU´o8)^%bháüùn§3ÎüÝÎãéÑuŸl£D8~üº9Ã0tj# r"†Ë î ÎæG©J´j }ƒ¤Ež‘#Ìñ(cýõQëËt¢òt­8­kÎtOÁÌšo ‹—\ ˜È!÷±–aP:@E ¡æÏ«v‰gþhG öׄavIøãáë£øàÐjFq´ìÒÒ) ‹æåc‡ ËUlö¯¼6Ç‘˜LFkfJgà%^²‰#”à,ªð/ U4×݈CІ¤Øq_”oâ–¯¸ìñøçÉ40ÂS‹/éz½ë E ;1O$WGïÁS7'1Âöpœ GÎØ%áÖJË—_vWvîÛ{»Ÿ|>¥0Âø½-p( _šŸ6,p¦`¿Š"‰bÆECÓ\¬<¡;Ýò  ÒA6´¿Vx qµšf7,ÒâõnRpJqµwA„pÁ¿”>3s„G÷…\ëIapaéT\ÜîtÆ“9ôŽ,¶Ñwà8Bž°€×k£‰•£e„œ.\Ž®AÃÅSMÞÑ›°~hÆ8»Áp^Îø3 „cZØË^{³Xøn|±úã× yÜ ±@8F þ¼¼æ2g:m*nÏÎJÄ™@ $)[ár±4i$Œ[K;ŠŠÚ ‹S —‰üÃ¥–A~œY¿n ŸÌL'ü„[-½o!3‹¹€ä™NŠ«Öt’¤lYäbI"a„ éä¡-§†¢BAmØß·÷vi× µN-Cíèuˆóƒ™éÄ?q⣹Ÿ±ÞÞ(f¢ƒa±¬5ä ¾ —[!„ýÚâr%Ñx(0Þ½0'-*í[Ä:µ »k½•”83Ó‰\ - #P^ÜI“2Ó‰(ÿ@šLö6ܳÍÊJ¤r¼ÀÞ¤2kD’ZF1È™Nô3‚yñhJ‚”3Ó‰úZ»w“|Ä8BÈcoÃxi îæ°†ˆIe2Oý.µŒzCGß÷gGäL'ú‰^€¹€´™Np¨Ü•\@Z¾òØ[È\,M& #„aq*Òš€Èö¤²~aH-ãºl-í(ì—lvǤ‚ŠPRP° Š‚‘º:_°[…)dd»ðÿÓÔ» endstream endobj 38 0 obj <> endobj 39 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡¡±‘ž%XØÈÔDÏÌÔ\ÁÜÌTÏÌÀDÁÐÔÒLÏÔ¢ÜBÁ%Ÿ+*» endstream endobj 41 0 obj <> endobj 42 0 obj <> endobj 43 0 obj <>/Length 9952>> stream xœíMpוÇ[Ø€1ÁO8“{Vqj¦$XÙ3UÂx3ÉbdÃ,`eX„,¬h!6L•¡*l`aS‹¦ÄÆTMa¬,âÙØàEì•-UMMf…Åb’Œãè=cŸb~¯ÿèøèö‡Zï=x/ñý—JÕïö½§OÜŸÛ÷œsûîß¿Ÿôæç{ûÖ¿u[‹ˆˆ.cÅŠ^µú?º­Åw}‘#"z‘»‹&3^¼xñ­·Þzï½÷jµEûöíÛ¸qão¼155Eù_|Áσ²÷å—_¶ÆÛ¶m£ZP¸yóæ7ß|³e…Œ'&æ&ÎÍýêtmÃ†Çøù/?þó~ð´êütcfæÞùwûûûWXÍ?ü½­[WÕëó;wÕ?qâ)šxÉÖ<¢GÀMüűoøß_ëYËí{òæää-nz’Þå­C«öìY£{Jáøøõ©é»ÖüÄñuü;tMwVÈyýIž©©;¶7I!šœ;7ç…ìÙ½†Cx­²rØFÔø©¨ÊÓHáààJ ´VTæ ô…œÔî=k^~BjXM=œcc_›ÈD1ÈÐ236 z+ÝÖºç²pôèÑ>úˆ.O߇Dô´#GŽˆÚÄèè(ñÚk¯µ)ÅÞyçz½Îɾúê«í+véÒ%ÎñÃ?ÔÏ6ã–-[¸Ž0ÇÛ»wï矞¤ÇQ)çJqu(ܰaC__ÛìB'j²ÍIZ!­¸ˆí\AcFú =axø õ“5OþaîÆ3IÚžÿÑ—¼¾VÏ´jòˆóÀѵöïo ¬¤?Ðäøñuƒ+%™g· ÑYp_xñOMBZuùãÛÇŽ}óÁošöãŸü™ r—¡ŒO?ù›Ë—o«Ò¡„- <ÓÓwµ ¢AÈá”›U«­à°†ªÏóÀ!jµ¾FãþØ¡¯yH…@½z…\9ªQ6rЪÊö˜™™w³­×ÔÔ¦näºÙú3bÂk0 ×…#8p@×÷Â… ª·cÇ(ïÌ™3 Õ^zé¥$åÓíÛ·s’¾°MxflÔçy{ÛS¨Gœg—'uhë*Œ ™²;¦§ïP“½õÆ}~Šy#!ö&tÏŸ_¯Ÿo_Ç¼Òæ®Á5ç&æ ¡ßý÷0Öà8n(lb¦™ îûýÿþí³ÿŸüöû2å°Ñ`LH*—õ Â±C_cõCC cáFߟ¼96v­¿¿×¡ÊÒŠ­Š˜‘ƒ‘„ˆU’÷ÿ¬Ñ3&éˆ$+'P•—´}R”@}éV…`ˆ½{÷šÁ•%£i3{ƒµefܲe ¤vàÀ;vÐm—5J§fäG[uhQ³³³¢¸££Gè3"GcÖ6UâÔ8Ó¤ù-¥.ËQW¬“ÔReàÍѧ3gÎu6mÚD9‚*3êYl4îól=óìíål_…&}K5ÙËFMcF v$ùÄñuú~Ñ#Àøš87ǨÃÛô«Ó5yp[+ÈFƒ\ôþKR6±h’~¿c[¤ƒ¹·sW>MšƒÓ»ðÒZ`Æ\9IúÅáˆTõ³‚&J}ex5:ÛS'UϿۯi¢¡¡o‰/øfŠp}%÷š´ÌŒ2÷Ôm5kZ½í¥K—èÑj+KžMRÖPOoAŸaFÎ}ìgGȇs/M³/ ÏÌÌÈkÇ®¯¯£½è”mØ2Œy°’Ô¡!IŸWøNs‘þÕJ¹ù:P“Ÿp]‹¶lÐ1¼dšŽ]wŠ?M×Z!7În÷”ÿ6%Âc`Õ¸ã4ô„åIöz±løYi@ŽWÕÏe{Ú˱쩳“’^>Õ¼ª®FuÌÖº¤&7‚.ߦÉ6ÒÚœJÖ ÚÏŽÍêègôôŽˆèEDOïî"2cDD/"2cwÑ|ŽˆˆˆøŽƒ×RdƈˆˆˆEø–'&æf®Þ³Š‚ÒÄÙåË·gfî)jú­ÀRaÃs±÷ǾÑ\¡I«Õú(ÑGå`¯6.;¯] y4§ñW÷'oö×VtÄe­^Ÿ?u#;ßzP±zk×hÜ7Žú–oêRãù})vMOßùÃïÿ.YpSHÒ8Ðà ‰Ô´k`àqvÕÒ3—›®Åö"_£ÝÈŒ‚<1lÓ¦(s)íÈà²7ƒ‘úk}2øä”ºˆ÷.9©þ|d-¤64ÔÜ… ¨ ã÷ÒÅ}SÓwÎ¥‘Î*ܹsV9TŠ\É,ЪÍs‹ˆˆÞ¿>>~ƒ sYoÏ<ûÇ•|»}êMÅ”¡FqÆŠ´u¦&fÝø©ë–ûÄ!ØØ¡¯–DfŒˆx8è%‹¹£}ôšbK3c ®¥A<ÿîzÙ™¢Îlr'ÁFÓÌŠåòbãh:"âQ¢×ÈÐkŠ-=šNÜ ŒòAQmÑÜO÷7ΛSê:)tØ›q_0óñÇ·Oÿ²æcï“ÈŒ½F@†T¬l&뵃öÖúû”¾A©¢t>°¬÷ÚI2âd½v”‹4ÉóÚKz— ˆˆˆNÁ÷²6¡þÞ)¯T¬Ìk'""""BˆÌ"2cDDDDˆÈŒ!"3FDDD„XäµãWe“‡ÍÄÄÜ/Ž}sõê½çž{Ln>Iê·hÕ††V·_k_¨DY$”§Þ×LÒ•ÞvlaI6jj1‡|Žß9üðù/¯¦®&í/™96öõø©é­SSwöÿ¬1=}>7Ú_zÄêiSŽtûñOþ|þÝõš4/óô¾|ùöÎ]³ªê·Í3±^ŸáůFFžTlµ u€`ý “é½ß¿K*QEDDD§ …tr,#Ñ‚¨»ê'ޝ›¹zo×®z›´sç,ÿÏŸ_oíH33«}f|òæþýFã¾ñUYt -7®[Œ¼œ·ÂºÔŠÌñ°!ÿçá]Í6£·¢µnªC¶ÞÀÀJcƒ6adÒ¦­C«:b36cš‡VùË2J”¬>®Ènxø Þ'ÁJ’ÙuÊ)Ôr½~4ͮÇ¿¬>Ñ&°€ÎMÌŒ¬87G§n?ÀŒî<>~³1Xݰ5`:tMÑtí+ÖÁàObe£ér›ZD'K™Sd3¦µF¥q:rVq´ u|ûœ×&ºÃŒ~p¿míy5íÚUW$¶‰ˆÒtMùwÆ^üSíóˆˆÁŒº4ÔŽ¡§9ØO?ù¾R²ª³·,MÖbG>€ ˆýÜ´’îÍMûÜI:ôöCloHúÓJI¼ÅŒžm;rbIM 9Ò;2¬T2™›¶ó¤“æÉ£aƈˆˆˆ!2cDDDDˆ&3ÞºÙkËÞ7æçÿ«Û:DDt}}Oõõýc·µøŽbÅŠè»ÿ~·ÕX„ùùßÞ¾Õkdñ¨Ù²jõt[‹ï."3FDô""3vMf¼xñâ[o½õÞ{ïÕjMš}ûömܸñ7ÞÐö_|a»FGG7oÞüÚk¯Yû©©©#GŽÔëõƒ¾úê«”=zô£>B2ÕŠ:ìýðÃՄýóÎ;4Ù¶måªc0fÔÄ·áÄñuÓÓw}.qJ’æJ„w÷ìY31170ðøààʱ±¯µ=5ugüÔ™™{[·®yýɬã¤5©×çÇ]SMͪ¿?ys|üƆ ÉÝš˜p5aïää-S){ ÓQHæ¿Iðù?5}W%##O¾2ü u^^UJêùŸ¬õmU“½èãÏ.. Q®W¬§®R R›ÌH§ûüóÏ}W­:ø›o¾éKDýýýtóÁÁÁ*B.]ºD:øöíÛ8ìm4{÷î½páBE•DAlÀ<^71R ð’â͸eËxŠR.zsM7lØ033Á¡ü¥KüòË/SM¤)lÚ´‰úÔá`œœˆ¢@WóÌ™3hÃ.´Ñ$ß®5 ©ãõ lFøÑžñx/[ƒÁv©¾~uºÖ\Û!]ÅÐ÷x Â:vìMÒSsxx5|„ Ï=˰ëüùõ<©Ú”±`RÅ;šJo_‡(ý¨/ГšŠ, *øB$ïß߀ïÐßÖ–°§„s1? µò«P—+¢ÊÐhÜïéǬJí0ãÙ³g¦ð]µtvêcùA$…ôV é¿l˜qSˆþ.[ Rƒ.vÞ±c,1;;[Q18'÷¸PrØàŸ}öY›Š±—HÉŽõ€áKHŠ#qþ\ */ÈŽˆSƒ€ÕŠ«ÆÁP”¶²a9¨… B£`ãÙÜ×ZG˜²Ã|3O.ªùVð ÿg®Þ ¤QŽQEbŽ1#Äd´˜U‰ãÊ6ÔÏ^ü“V^LOöMÊ™1I-ÁÝ»×ÐCr™ÖƘUåÈŒ-ã‡ÏùÊðjÞŽ½ÃŒY•ZfFº–ŽIçªÎŒ õèÚ+EôGÏ­H@vU’šAP¶ì§*$›¤VfÖÆQÀEœf²f,Q ®„¯üéû‘KqAm¤FUŒZœBfDo~J‚vqΪàwùí¾¾>ê¼ôÒKE'PÎŒ““7} v3V!ˆ€Ô9þé'ßg8¬|£1âøSž:a:]¹×²B‚ŸŒÊáVÌe ´K˜qáæÍ#?ËwÆŒü‡»>³+2c;謓pG¨ÔæhšNGG«ÎŒB®Áf0U„l4xMd”,˜¥Œ£‹ÌÀ, 0Î9äGÓð•˜FkS1#J¯Ø¢O[¢3Ž ìM¡–í3#2õEƒŒI‡lÆ;gOŸ®Ù'?F©ÙïŒYiú,ˆ]ÆöÏGÖjÔì‰æ™gÿÈœ ³%!X|ÃÃOè'Í1ý0Ù@Il=FÖ•KÚŒ+›ðfT¤Ã‡¿§oR‘[CdÆ\”p£`,'c“rˆ}¨ï¿j¼ˆ™Åˆ©âÇÁ\Ýô‘Q+ÛT ¾†Ð‡m}O¨BfļÔÐ8ivò&®\¹0#‡7¡[³~ýz¤ÓjGã“'OòSV®gFÄ"J§Ähú%ÜfÔ¸Ø&+ì{Ÿ?5aC3'úÌ7´u5•#чš2o_ORöô*Ñœ'Ûêë[§§¸mÛ¶*¾,‚:r’:NûyÑ¢òrˆ7¬SûBmgu.Bù9j»ú|®bFbÛ·o_4Ã|äÈ‘X˜ ×TÎ:Ê !ßšlÜ4%ªƒh©Éu9Ljƒ]4¡&2©C¡¹|³}áÂïÓ“8fÌÆ¨üçOS)RŪ¦bòÏ¿Û?=}×Èö¢~º¿ÑŸ.yȃ8~êúé_Ö&}k`àq¹Ú ½rá6Ÿígžý£­ß¸ÈDô2‰Ì½›œ¼É­ î€V"ê'§z}þù}É#š¤A«r‰]’å´LÓ”«7_æKwãErܱcÒØ çúttp‘¤.z]mä·ø<5É‚G ( iTaÆ¢s”bÊ(*žc‘b[¶lA*q v-ògT˜3Ô†–ÓBÞÚr?”ÇPÀŒJ9¡ÀA…ŠÅ©¬ˆ"±¡ê+úE®IÔ^Žî}“ ÌÈ{õãË·Å_ž)-Bšô úÃÔô]ý´ çÎÍYªúôwøð÷T«²A•œ,Ð%ÕWFfü ‚Buº¦åŒþçw?ð{¡Å¤¹lÑŠ^`ÆdÁË/¾$3ú±wÄS@±åͪâëGG¦?ª&MØ6“Ê$WŒ›N;Eš†Èª¢UÉ9ê',–TöÚ)RŒs7¯F?zþö;#/ 3ÿuY•$*´´­E&)Ér¹•ŸBîâ0•'ĶED.ÉŒ–[CÏÓåøø [ÆKFMøQë\ûè:»R>8Ï×Aøþý #_e‘ÈœDô2l9̬S7oÄzêjëµõ´´ž§K*0£r@dãC 6º|dÿ+g/6i)<Ù”Éõ6˜·E稈ÎNÖy¶\±$å@d†10;[PsÖ„b[cÆÑÑQ…Ý ™mÎD2Tf›#Zö¤3*ÖÅK™&>øÍÓü4›Q¦A±ø®ˆd-Q²‡Ò¨E¿¨Ž‚ö$$2ã_Š˜‘[Ék;>9ykzúŽ%Cêðø½øO_iñÒ–™Q©Ã’4Ì£bV›"f´,dl[ ¯%¥•Ðr“3£Gõ°Å%)Û§&+Œäx2V[z¹£é+W®ˆ)—ê”+y$»tÝjmïcF^¡¿œä}Rl¦±iÜÏbë3*Äxpàqø±iWžºaÁÈMSYAÐ~„Îq-‰™ «!P³Ñ¸™ñ/E£i¶yH¬šÙh]„%*æq}öïÿOiC[Mû8ŸŠµE£é[²%£éÜñu çè‡À-0c †øAÆÆBf4;1q hï"ÕWž’}µTzµ$ýˆ«Ê´Òmà(°¤OcįŒ ##Oö×V@sú¼‹m^e|üú~ÿw¾n Ä‹fÜéK¼fcÔ[öì^c30ÐÛПĩC‰ ²|ZÙ^üŠ:]ïHUQ#›ŒVT{/Œ¦e*ò2n:?´1#N„Âèeô;å®8n f`èòÑ4›©h3IÚ,5–5”.9ÇdaÚ$icjÈãÅTI:iž“kǼgPˆÆ~)‚“'OBˆÊ’fõE‹%^;~f]õ©ÃQlv<ûñþŒ<(Œ}0Ólú8på‘KMPˆ 3ÒÊ;÷lM3è$¯“ÃO«à9¼[Oà3Ñã¼v¼WVò×èµcÙr}SÊxçÐsÅí{íxûÎ4¬Ž¢sG)Gb;ŠÉª³ fGO^Dôôî."3FDô""3v‘#"z‘»‹ÈŒ½ˆÈŒÝE“ý'Òdq>È +­òןu—Ì\{éÒ%Z!QÓ$›(˘›,ž›¶¤°IšÝš¿Ü̬Êüj‰c•S¶(ßmî, …Ö\ Z&È[ýp>+m²8[-u¼'—úpßÐç¯õélƒšA¶]É´ŸJ ëOЧԵää¹ÍKó·©ü1‚Kµ©Ð;‰~ua—›¹Ö¦J|¡ú`nfèrQê§Ù]ôÜå&ÁMò2ÔŠjª(æ˜{ŽÕóu®óà¢%Íñ@±&3±ÒC¤k$iȳÎ07=::Z¾ÚÁ–-[,©¬åZjU’ùyæÌ¿4k²ØÓÛ÷Õ`1A+·ÔÒî79ysäõµJ0±s×ì§ŸüÚšOÏÄÄÜø©ëÁJéÅZäµó‹ÔÙͦ¤åâcÞ‘Õ' ýJÀ/K@}s®Ô¢ØÔœžºCù‰OÉýȦÝ%slìëf–ò”Ý´zbpˆ`Å[ÈA?5KûÃç¿´ Y›·¥[þø'V\šÁ7g{däIÅù3’ƒ”¿bEçøˆa‘ÑÓÓwNŸ®ùU(’…E{z':Uëõæû¦¿¿¯¢×N’öGõµƒÚª! }‘›w°FUlQºavi&²·ú ÑÌ€bÞŸæäÉ“Ga† –9ñØ·o,$žÉ=ÇêŠù:/^Ôò¨bɰ éÄFÓG…È®\¹‚NpªùCjUU‹Þ[î Yº7œ’–FÔ9ÿ-õ›O¸dÅÀ3ëJk%,9@4êó~y?­¬bméc‡®©ÓB7C[WÙ:ÎÙ™ßxõá;ÁÝRD b±c>çvR¶ŠVàªé—ýb—xÍ"Xï07œ1«’<ûP#.Î]d¦h©™ <8Çlý‡ ½EäÉîÜœ_é,I/2o‘É(a™PØ®îéM?§É‚ñ^Ðæ’]})¿U°àÒÔ©­‡VÖ‰6&,‘—b®"¦»` ø ͋α¢bA“;qãYŽ¢Œü™1I='© ˜NƧÇá*›¡×Zt ÒUÀ”oÚ´ ®T:2å›;¤E>zflŽõÐF¯¹ë5ÛOzcs`;°R‹‰[ÞojúލñÐYÖËòKõÃyf4f±aÝγZ,[LGsØ à¥e—ŠUp·× €ÌLã°6f¯W€ó=qü)Ue›g)Ï77Ç@F‰;̓sÌžÚÃFIÜ´zÄÓÛ U;(ïãì~KQÁ"Ñò…®èM,Ÿb=r[‰7sƒ5¤EsqzIt`Å‚:EѪù|ËŒÕB[bè¬=ŶƌJѨŒð£V ”!©Hm® «¦å‰]ÎŒ–HBD¦Î©ÅH}Ðô¿,¬|¯€èss##k-Ì&+¹ˆK—;š¶5Q_xñ+È Ê8vìH9×:ü®,s™—Þ¯æ75ÈÑ´ÿ¨êGÓåGÓæßž+ß7o.VëãK¾xÓ58Çì©=l1#šÌjîTO1£º-å]ËÌè³Ñ³J­Y±Ã†e1#•9·•ûåá4Æ\KÆMWQlIf ™1YˆÁ©¯IJál0F˜Ñ"TbE¿`3[Z3 ·–„#Š‹ÂŒP-ÿªŸöf[ÖhZy%|(KÓJ£ y¼4J\‰œzJÞØ±t v"Ã+ëÃEÌXñp%£i™uosâøº™«÷,E²xŽÈ_KiÕ”IÈA…ç6<æ ´Š£é \T«`sß\Æu•ÑtöýDwV_lÅ8ö µ㦓ԌÝÿ³Æé_Ö쥵$3ú!a…,w»¹±Ã†êr ‹´£_ciyìU—/Ÿ1æ*:Çe)–eF?H7TeF˜NeÙVb7$hejÆõHÈ~gÔ.U“5§j^ äe3KI«ÌhðÍ9º&šª4Ï=Çl“‡ %’à_¯õ¯Pj }OÐd:·¯Gríh²54=(C~Ifd(¦$~ší´Á)=œ.›ÐÿéU2J(NÉÐ{Y6cQ+ŒYT­¢1cÑ9.K1«ƒE,²â?tLj—1£’Aruô¥ÀnPæ2ÙwV_Éx¸ ¦Íé«§2ófàr(£]wŨ«òèè(ÿýÅ2fõX¹¦bm œ¤¦†yôë©»cI-9­Ì%ªfâ!prò–¤1l™š¾Ã¶}àÓ\ŠˆûË:³Xýpúé凰úÍQg½9êœJí,ßœ‹€Yêkì#ƒÍÒªzÒ§}û!¬@%C¶Ü77Ũ6å<ìecÍ‹Î1{ć Í,5-Çãë¸SAF ®-Ìøè); Þ¸¼Pí§Lì*sÓšlµ¾¦)ë»–O}°¤ûÉv¤Ç&O–µbhi`9Â!¶Z½¥ÇÎ…5):Çe)æg~”Vüã’¤ÄVq½éˆˆžFôôî."3FDô""3v‘#"z‘»‹ÈŒ½ˆÈŒÝEdƈˆ^DdÆî¢ÉŒšýñ+1ZТ‚m×èèèæÍ›½ƒ’|Kæ¦åÁ¤ÊšøæpŠ{É;óÌ85ugüÔ™™{š¦äرol2Qó¹Íj™©RvÑðòåÛýµ¾‘‘µæCóöøuÍMÛŒjnÍ`–ÖÏ>Ëq§Þ¸o²u7§lõm.ÛO¯+ÙÏöj ^“•6©ºüÛÑD07ìåa¸:s¯榓§zmWŸ›NR[gCƒ‰×ŠÈNõмoI•ü°ß%rr/<2”(–d–Íy`3Ê{Ñ<´ ¨å_´z¡-RœÕ¦M›JüÏœ9£ˆl¹@J²œ‰t­iø(ëÀÈeÏœyšm*(Æ\ˆ³1y"y_ïÞ³†måhPbˆ±C׆‡W+?B¶fn¬‹ü!Vu3t“ëLPG?-X™ é³~è–Ù¹«n®‹ÉŸÊ¿„VP-gÝ­Œ éÈú3ú½ ŒZÕ#10¨ê“˜TñgLR¿?•>}gÏž=˜¢:ÉsÈ"mí@%:¨èÒXä6xòäIþ8pÀ6*êÖ)”ø3*£„¿’˜ÑÒí(ÀYJóÑ Ñ\s"_V Ììì,M’…D;¼s¨f<›ûZ3f µTy²@ˆÍ`>·ŒŸgF…3[(ˆ%Yð¬J!ÛSÓwrk1£‚@|¹HÉ2c­Ö‡UkÁÎJ¡æ…û°öNþúŠÎ#–…¢˜$½ÑÏÿèË42ê~\^$x†ÿuµžù*̨§΢[Ña•Q¦:3ÊÏiEôGÏ rð¡(Ô¾†+ºÈŒ%10"Múß~gäÒ(EíÓò\/[:µ…¸i„hù@ÅÀ(iEÉڌƌE¤ þbðk±+ÉbfÌÏH”LEeXÁ`ÌfH\$r.3–ðudEê'„«HÙýý}HͶܨÏ3ˆ6–0¢PßrVUṏy©¡q’®Ê ®\¹²ÜüŒFß)`@Y T@”‚¦­gÓdúè@ŸÀJÉs³Ã&yñÅ>êY_ë(ܳ{êØ7¾ÜšEÌèøJ}jƒë\fÔòÁU22x6÷_"3¶Œ¢üŒuÊÞFcž·T×VÕ«d%J¢Ü ̨,Yömm¹ ÞiaF8*(ÉÏøP‘«˜VmU%EÌYUÕ3£eKjfGt™,ÄW–çôær°­ Z{n…•‹ÌaðsÓ<.I± ïø¹àrfL\>­ ` bwîšm~þë_a9½skú<]ÔOÒ섚ºOõx ª–ËŒJc¡,v ¹dÈÔá(Œµ5;´œ»ñÙœÞfŽ©‚f®{äÅÃÀíîïofùüà7Oó$´ÀŒ~5ç6™ÑP’Ö$5*ZyAêl[`™V“”|R{H(RÌ*ަm=­#áÛhÙV¨ÊK®T°’Üå F–-ºb…~­•Ü­âG¬‚r|yÙš~¥ˆ³ëÀC0MéøïŒ¦êûuTr—²ÉêY´€IDEd—ÖñëÒüu¬“¸åVüº+tCºØro1 °ý]ÝÓ/ Užt¼&­-PÓA)&ø =½#"zÑÓ»»ˆÌÑ‹ˆÌØ]ô3FDDDtÿÞ£GÎ endstream endobj 44 0 obj <> endobj 45 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡‰P,lda¢g`b¨`fd¨gij¨`hja¨gaQn¡à’Ï„'ý endstream endobj 46 0 obj <> stream xÚ­ËnÛFðÞ¯àqT wùNO‰c£)’i…AÝÚ\[Œù*IEv¿¾ó")Ûjz)„3»3³óž‘½¿<íðO{©ñÒ$÷³Ü+ïíÎ{ue<øy{»[Ogžý<övåêboûÉ ›m†Ê¼Þl£(R:[VíÝ÷x©ë@G5ÐÌ'¡²m)@ùå0NpÁ”¥ìæÏÝO^d?ŽA|"¢£WW¡§#?ŒÔa+ÛÔ4Df|½ÙƉ™_‘i¬ÞÍ"ŸÚx[ûš9w{·Ùš˜5Ɖ‘qr=CUËßÃHb¼¨Ao4›îGþNà 2¦ªDÚåƒkt¦.ÃàÚIÔT?n²HKL’?صpGÐàl9K·7ÛÒÕUSM®$“ЈÐ׈É=àk¡a;ä“îèiþôv˜ªâPÛñÛnhì„:Ä¡*ÝX Õ ™‚'H˜`u·ƒŽdD ~;hÁIô3ÅHì¬LøT™ÂŠ6"UNÁÈg&%d§I+÷Ð8ÔÉÚ…_K¾|DC,v’±'ïí›ð QýÐÝ ¶Á$L´ш@V;2ÓǪº±»–ˇÂÕ`u V¿iùÌ=ئ¯ÝË`˜Ù^ „2 sÃ(^ÍEä¶;]@¥ഗ뫪^16 ï]ݳPprÃgUûŒõG!ŠUƒ)–ªÆ+Í Á1Eñ¢è8÷lÕÒ $F]ŸI&IéÃZT]Ë(·;0Ò:'… T 4ö~)gËGKj³Àþ0ôçÓëPÙy¤~œ‘o1¤a…SõuƒlñÔC¤ì Z_d~@ÈLʽ0ÐjèÐð#aÔ$Ç(…ÈGw®eZ#‰G¯×‡¦•Ó•'eÈ!ÛlIÿílÀâž^ŽÌZü檻ÝðuƒI‹6ÈíµrþÄ)I5: °Í` Sƒùh‡Áâ«|¿'øf¨Êêou½!ºÚdFÞKYZÒ([ žªÆÝax02Hó"öMÕV­¿»¹¬9ŽGN‰šRÁ¨ºãZ½gʺºG';¾œ _Ó›—;o8[§Þ6ÑœWWöÞuÞ§³£dçs’\Ú¥„£„" =Š‘kŠçõ1  ò€+2QU)±¯Ð.BdâšJÕÝà\ËÜ@´ç2öúˆ\óðqäÛ»Žš½“f R•é:Tᄲ̰^¡!žé(–t>©%‰€vÜ]Ë(¶¼…ôº 0”ìHL?ÌdQKÞx2Ξ‰ÆBà#+òûjI¦”mÍ´xB(Hc>Ù{ŠCë¿4’÷ àX÷ @f#ÜÝòw:K¹$²É‚¹JÇÆËT£¾¨°Xg!Ëý(Ε~ÏÊ“«ëñ™29ž4w,ó$!  -í‹+¦‘O8i) ukª%ñlUgï[¦xDua©;áòöù—_¯øš&»ÈçY“$O*5:© [+î¨Î†ŠžƒÕya¬erÃéš=pj[iÂxcë~o·òÉ~iq@&ŽÁèõæÕUËi*½™$CS†õÌ -7yiàîf„Õbü—qL)Å>¸2qé0§Þ=f.Hpú Ùºvp¿¡MŸ¨8š§|¶‡Dì‡ –BæÆN.W”}p]¢£€”;?„c?Ãr{K~2#²L>[zÀgiêgùÜü r È Ÿýš-æäâùñç ¶.[lè3Îè7‚@_0Í,_ÔÙã|~ʵû¤Ú…õÿc5ÊhH“õñ‘ë‡+¢pýÄÉÀ±P@³¬îZËûuŠ+«¤:À®é§–˜§É²¼ &‹]ñÅ™U^öò·–³ÉF5®XQeùCÙ€H®övÝùÆ–e…;%7 y²ÁF¡ h3èu­‰Ì²’ÂÖ ¶ðucdŠN7Í…ñ|æ­ Røÿ,HÄç:óÓTv$ó) 4üR>©\hÜ-kü%—ñ–”Ÿì·ÔÞÊh8Eà¾ëÙ¯ÒÙÞJ#,Ý­=ÔøGí0 ÖnáêâäiVåý;þVÒe— "}&yhPE<ø¢'ûâTc¸e4ÐR±âPU“Í9R?¿ùxÉÐ:±bêÅbä\~ã B?êa·ØŒÿ[øŒ:LðÍÈ@!Vø‘ÒàÜꆤ=&ì<ør¿MV糦Žhæv 3ØO¢jæ°°Œ«ºfè†G#Ïÿ0€gµfÉ É™_dü-ÀŸ3úÓwÿÀ­Ý³ endstream endobj 47 0 obj <>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 50 0 obj <> endobj 51 0 obj <> endobj 52 0 obj <>/Length 1937>> stream xœí[‹E€k^|“(*¢ *ˆ³&‹IÌf/HÀxCü>y‰1&Ñ\tÔMŒQ_|ôQ¢A AÂ"ˆYÔÄ\ AQ%¢‚ï±v{Óéí®ª®™îžÓsöûv{»«Nª®¯kfv¶§sòûôðôškõ‚Eˤ3€èv»3VŸ:6)Teßþ³¬¾ó±;»¿ãþÞ |MqÕ j,ì¬rŽ€®ºCÎæg× òŽ…³Ö…ºCþÁ5Ó#ìxÿ¡©L/Ôwôº8b€UÂ:‚{Ã[t}9fê…¦w@Š~YxɬÆj¬Æj¬Æj¬ˆÕO.g¢jç~Ó«â•è‡ÕX=G¬Ž|©+ÑxȬþqâûóæ»_«¦ßLØ#Ÿ®KÆbÉû“"ß|ò¼ýuÙ£{°«ÕZýßÙ÷³uæÍ¶F«›Ün·®ÛT—Õ§n²› îßžŸÜ®€G§•^üÐ.»ýÝþµv{é#oc5V·Üê‘Ñ1û=û¾’재¾ô–g YÖ`µÃ!«Ó‚XÕ-·:§qNò>­þ÷‡½vë²ÏýsêËGÖü}rýõŠÛ×þub÷• _°ù;¶+mþê;^´µþ8²Ón_³dÃïßî¸véÆ4TºVÿzx›ÉpÊ-9 ú²›-X}öЖtÏü{·¥VÏôüëvçÄçÓ=‹Ví,ZmY¼z·s­žÜ÷\Zwùïb5V·ÄjsAæ„ìºÝç#ðÄê„Ôêkõ¹ãSJ_5ºÎÖýóè[fJìõ‰Õ «¯_¾Ùvï—¯Þ°Û7®Øšvøçi¥oºëUãY«Ï|±Ùþ¼í¾mµúøgìöèª7kuÑêÉר±Ç÷ÚÚ_dŸwX±ßÃjG@¬–°Ú¸Š›êku’MºV'¹¬¶kunBW´:»VÕÙµÚônu¬ÆêöX]ÃZÝB«ÏÚj7n½çuã_«OxiªoV熫¶`õ­nðy5Vc5VÞêÚ^OIŸWû¬6ÁWËú³ºñj™™¶Úî<}ðå™®^-3½Xmf¿ZfxŽÕí°:ÌP¾ ÅÐÖ)^ý<Î`5Vc5VcuV÷ _CaE­îv»&¬ÆjõV»{[¦_»¬þ`ýjÓ XÕX]“~YÝXí X«±z¸¬î?´¬ÐVh«´ÕÚÀjm`5€6°@X   ¬ÐVh«´ÕÚÀjmè±zdt,w“ä¦+Š3àÌÛ9P¾¬Šû#óéfL£I™˜’•¬ÎÞØî<>`âû\WÅ´ºÉô=ßí }eúk:2BZ²Ê)k›ÕáןÕáZu¸˜veJ Wµº=§Yd­ÎÕÍÍç9p–©¥õ@1㚈½¶ÞªÓÒ¨Õ¹[p×uâb² ”´ÕÙËgîRš»Î9/´á*á=ÉÎ4Bv§³¤/ç@Åžf‰o%‰1ßÙn1·bá3Rš¼¯ÅpsÙbÅ;Ñg#cšvŽR ŸÈá çž¾qŽìiéì,SL GmÀ³99·SÁyjc.ØïŒV¥b®ûÎ^‡(Æê˜L"»V?\7~ˆrá.øèõRU}nºìÃȱjboL²4²VÇlûÖ ç%Êx$ŒÕÅ4Â,m×w9 EŒNΜɗ~ ŠVûºì»üù¦D1Ÿø¹á“b—‹Å×ñÒiãÜSK›Õ¥Ácu¼xÅ£ñ=* Þ‡Õ¾†¤¬N·MÄõÑÜ™Os#<ÕÇ*§×ZÚ¬®ræj´º§sÙGõðPôÚ|_­`µ0ÖêóçÏKgÑãããvnaõàÁja«õ|2±°Z¬«¡v°Z˜œÕ¾û××wƒÕ¢`µ0Y«[~ÏÚH’^`µ X- À¡v°Z˜¦×jç'¼D~ŽOß-²VË‚ÕÂ4ºVû>ÿ)ò㚪€Õ‚`µ0Í­Õ¾‚+~´]½°V‹ƒÕÂ4·V¬6Í¿å «ÁjaDÖjÓ¤Õ¬Õâ`µ0"ku£À°Z¬¦Ñ×ÀE^-c­«…iúïÕƒÿËVV ‚ÕÂðÞ2¨¬†÷–Aí`µ0¬ÕP;X- ÿ³µƒÕÂðj«…I¬îv»Ò‰ÔVKÕÂX«W®\)ES`µX-Ì÷…ºÁjm`5€6°@X   ¬ÐVh«´ÕÚÀjm`5€6°@X  ‹VÛ-éd ¦¬VüÏ€s“ÿâ_7 endstream endobj 53 0 obj <> endobj 54 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡™¹žXØØÈLÏÄÂDÁÜÒBÏÈÔXÁÐÔÌ@ÏÔ¢ÜBÁ%Ÿ++² endstream endobj 57 0 obj <> endobj 58 0 obj <> endobj 59 0 obj <>/Length 2250>> stream xœíÝ=’ãÖ€QÎzÜUVf-Á¡ï§S… ´ Í„vfWÉëÓÅ* ðÁÜË{N0‚ø#Áþ ‚œ/¿þûŸ'Bú¢Ñai4@\ —FÄ¥Ñqi4@\ÍFÿíïÿxñ¦Ôôùùùßÿükõ®^£ÿú—??s«ø¿?üñO ”FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\ —F¿ _ Yt¾ntI£ßÄy§|ûöíè­6üòóOì.iô›¸4ú¼ûÞ`ƒFW¤Ñ…FW¤ÑÅaþøáÇéÍóìç1×;±9Áî¹ö-9£i£§;bõáOŸ–þS´cßõ~ÿ™-aóÁ>UçáÔyíq«#½Y„U}¿Y£û ÎØèëŒËF?걌¬}|™|ííþÉ"&¾wɵ½¼ÙŸ`zÇÑëtÊé7Io]àêfl½;÷ëïO&´V±ºÙ›ëZnÞꔫ÷.—ÜyêZ¯ÿ}¿‰Ïç +ò9CÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+ÒhÈB£+²S ®è¼#Þ`”F¼ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .~çrô&C>??}ΰœËw*½À†_~þÉ÷uTtiôׯ_Þ ç\®H£!.J£!…ãýñí;wq§V£¿|ùòýû÷C6 XÒè¢4RÐè¢4RˆÕèóðeà2æzó:f6×e‚ÍÙ7§,hÖèsš¯w]}³¼y¾¦|6%ð@=‹õ%¬³1Ó¹N“· >›`s±uL==v¾ wÆÌ–Sð`à}%nôò®Ùqw§ÑÓ ÐèÕ"O'Öh8ÊantzïMîŒéG—5~=¿Ðhxªê.Ûkç: …#ÏuÌÞÇ;MNV ¾g8<×±\QA;Þ3ì L§èøóÑÂç !.J£!.J£!.J£!.ÊN,4º¢óŽ.rÑh"ùé!Û°Ùè멌ñF;š¦C£‰hõËX.‡_½úžáiQç[Ïuœ¼gȈK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆkO£Ïó> endobj 61 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡©¹ž±%XÜÌÜRÏÀÂLÁÔÄLH[˜èYB”[(¸äs!-_& endstream endobj 62 0 obj <> stream xÚ}UKoÛ8¾ï¯à‘*J|èÁÞ¶M ´è¥€=4=0m±•DW’ãô²¿}9Êq°AÀçñ}ó`È/ÂIþ8iijÍZMö#y·#ÅGAxÉt©Éî@xK¸dº"»î}ß›Ójç,—RRñ6Ë•Rô‹7›Žo@«è}ÉÕl6¤fê’Ðý8/k¸@Ëά&û¾ûL”¨YU,¢Šª\qÎj¾˜ˆÿôvÇŠ¾BDQQÉJü)ËEKí´àyí- 1O”"6aÕÏ÷S&zá÷!„¨)†®©? ÁÞçq ëköàÑ#—ÙgÁñ‚—LÑÀ†OKÂí”LÓOdÉÓ*|$ãX`ƒ•:ºGðEÂâ6ºh"àÕ8„$è`—3ûÔšÑÏ¥ì*P6ª'k;Û]„×vž¯BHsL1\rïÜr $ÿ½±väy˜r^W$¯ÅÊæ©ø8JrçÉWœ,Ie©ê4Y¡a2R¿³£yš›Áx9‰e®G뿳¼Õ‚vÑ)JÁéÚ_^†²\z·‡ºõ`ÀéÅ H2v9ÀG¿ób;TCgAc6;è?(⤀Â>™ñª§ÞÎ×\nI¾ð1«jjÜGå‹þ> !Põ5qlo8VuZƒ~]Oo‹b6“aÃÃÀŽþ±èüe²--€;[ŸÖWJ%*Í™BÅý‹)eF­¶ÝŸ ä’Wä}õà§Å8æÆ…óÕÿüí™Ù³§âß±³½÷S±øÃz1³-ö¸ªÂ*›6ÅqÊevº†/kšx±ƒ(^Þ4Ï/wA•&3ìYV<í”LíÓiCí‚Ç5T’첟]Šu.Y}pKXB­oAKÁÚ ·…d!­Økü“›å=åZ·÷‚û¶X›(·%·•ží!L×´‡YS•†åª,¦î{xCZ¡èª8`Ô†9…ƒY"¤Ø|63M]Šå°vµéQMÁ¯O,\áæ€Ëö.¡>ÖÚŸÿ?ån:øy4k,v|a°ºþ¼â9½½2¢²Ýóÿlî«ïJÙ\W-Ûž…ÏÊ׿þþ©ÉJ endstream endobj 63 0 obj <>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 66 0 obj <> endobj 67 0 obj <> endobj 68 0 obj <>/Length 5046>> stream xœíݽ’ÛH{€QÌõxª¬ÌJ'S¨@—±Á†›mMæð ¾ËpàÐÙlhgv•}=cØØÂB@£Ñòmòœ@E‚`£Á‚i÷å¿ÿóß;BzÑh€°4 .ˆK£âÚhô?üã?Ýl*gùŸÿú{Oà¹F÷n±w¿üúÛßÿöÏ÷žÀ VÝh {ÿò¯ÿöÇ|||Ü{"ûM_ù¿ÊLß—ûN/ÎÖ ëaÝô©ôøU ÝŸÂ(ø¾ÜwzA¶NdÑøU ÑÁTð}¹ïô"l½éwÊ3ØÓè×/_§wûú%ãŸU›ŸuÖß0y€#/xתß—•Ôh2v6:ù¬¥ž®œbù°päïZ•àû¡’MF FgFÎ?4“9ò6ÇßñU`|úxûø‚Ì[wíÛ=ó¤åhåãÏÖ,ß—³&P%_ÉñÇ:{ÍÇÛ™3Œ’ ç_œéÝ醖 7—ܺFwN£§Ž¡1à ӻ™kvZ½öÜä;gt¤ÑɇJV>÷ ÁŽFŸëȰÓèäÏ´ü3òŠtþý¢Ñéèõèé:;Œ–Ðæqœ<Î2g¸É…kG^þLùÄFçGÓè’­Ì>ΗŸîg©^¦Ñ;&|°Ñ…æ·®ÑÁ]r=;ÛÔ6zöIyh6½ªF'·²vÕÝê Á‘kå›Ë?´üJ´6çäs«ö%y`,7±¶Å’ù/©}©“ ½–lfÓµÞüöWòÍqóô|6½ä‘·ù½5¹ k[¿ú AùeÊ.õU¦psù×!9rþÅOnq3C›3¬:òó¯z©§¯öÚ“ÆÚ—³­½½yðTeZ£›p£F—¤-û¾ÞÜn¦Ñ¯õ_vŸG/ߨ%3)ù¹ä{º¶ÅÍ}é_G¦ƒ¬W³}ÌÏ!³›ùé%_^Ûô拳ùY¾\¨ÑçüFw?¸Ã ™Œ·7J¾KË=½»£Ñ]öÝžëæ_¥åÓ4zmb…3YÛëòOÙÚ}Éw§äl4?‡|ÂÎmtÉš…[¯jôô®F?˜§øw†›*ÝJ‰f§uÉ'.7‘¿}³Fon®ä¡µW¦d‹åûRòѲc¶›;[þRitf7_ ïR'7…™Öè&áãçÑù=Í?qI£›ð.W~|_*ø¿Í«|_"üK?ÿÎ þ‰FŸ.ø¾D¨¤F“¡ÑïZ•àû¡’M†FG¼kU‚ïK„Jj4Ûè¦ÿ?,ÀSy{{[û°|ÀF4$ÿ…F£îI£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆ«±F¿~ù:½ÛO¯_2þyd´O¸Z{NNiG©g+ï«<À¥4 ®æ=­ópíbXa¼Ž1½[xâ¼|îlðå:ÉM®Ñý„– |ÿ6ÜX^Až5zºp|Jò{ºòrÀÙs“›KŽ?ÞHîð¨~ÿý÷+ª±Ñý®ÎŽÛÚ<žewoôìnþ¹ÓjO×YØ¿Då{ 4íýýý¹½6xy£óE^.)|nþ·kÜðœòá:8òƒ7zóZG÷ó¥äüs˯uÏC£ÿ”ot—ºd‘Içte²“Ï]¿û9ôÀSÑh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .&¢þ‡uï)\ÈqH9&¢áè¹÷,.Ñ¿%®;Èy<MDÃÑóññq¯?5šr]=Èæ:> ŽÓhhtõ ùïà¾ÉžB£a ÑÕƒäÛ‘y¾~ùÚÿ¹¶ã㣵՞D»~yyn|~~&—h4U4ºz}î<ìòòÆl…äÝS\1æEmtŸãišûÛË%M®ä”óèe.ïÒè°ÕÖhhtõ »=J–1ÙèYÖ‡‡ÆÕfOf+¬ÐD¦5]=ÈÁF¯51y=:yadŒï¬Å˺E¯×6½ ýt·×h£»ÅÕgæ ®äH£3'­ù“ë|Á“+d²^5±»h´ÑΣ9FWräztí5‡µ_0–¬PÞhçÑgÑhN§ÑÕƒÜæïu¬=««¹ÖQÒèhgІFWrÊï »Êóènr†[õ;ÃÙ87øÛ#§h´Ñ¿ÍÙ4ºzß¿å×ñ<®ÝFoÒhªht~z%«y¤Ñ0Ðh"Òhh4i4 4šˆJ®û·K£)§ÑDTxÝ¿]ŽC i4@\ —FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\MDýëÞS¸ãrMDÃÑsïY\¢K\wóx4šˆ†£çãããÞ9_j4å4ºzÍu|§Ñ0ÐèêAòßÁ}“=…FÃ@£«É·#ó|ýòu¸1ì{wíEH>:.LJ:(³­Sì­¹F¿¼¼ 7>??ói4U4ºz}žvj¸]Õèi “Ë8ÒèÂ5kçÙV£û ižÞN>¤ÑTÑèêAŽ7:¹píölɹg¸›3©zâñÕFm5zJ£9—FW¶ÑÉk)ÃÂéÈÓuJf2[¹•Ùíµ‡4Z£ÙA£«9ëztw¬Ñ™«ÛË:/¯®d®™$?ÖF¨ZyíE[j´Ñ³@wÍa]=ÈîFÖr–¹N½y=zú‹ÄîÿÓ¼Víé:ËM$O¢“cf&öœ^ºÓhÓèêAÂ6zóòEÉo) OçóxÂF'Ýi4‡itõ gý½Ž’‡–ë,Ïsw\—XÛÐæÄ\ëHZ t§Ñ¦ÑÕƒœx=z\^ÞèÙ8™ßï­]bNÎam뛿3Ì þTžÞíCùúOš­Üh£gî4z2²Fÿ¥¶ÑÓ…k§W…_u ÑËÕ¦#ä»Ö-^ºòâ¯M`6ùüŸÉ}œ ’ß—ÌÉOèüþæ-6zèN£'#kô_Ö²»y=]ž¹ýðî²;[uf½¯Ñ™íiôÁÝ/yÊÓžG'ÝiôddþSm‹KÞ„™ÐÔÎù P×:ÖÆÜ=Úfæ2=«ÑùŸuù€ùÉoj«Ñkî4z2²Fÿ)óÞX{ƒ½®ÿΰ[ù=áÚû-x£»ÅÎ.÷´Kíìì)ùlÍ\Ækm´Ù:›ç¡³òç¹Éémî~~g“>1¯¹FOïö‡è,ÍãòÎßNi¸Ñ?¾˯í‡íß>˜Ú¶â ­FW‰|Üjt~z%«…úakôãÙQÛƒî4úN4úñi4§Ðè»ÐèǧќB£ïB£_É5ô…=Ö9èÆÒ…=n5úñ^C?ѾÈÏàöÒÅ ŽÓhhtõ ùïà¾ÉžB£a ÑÕƒäÛ±ö|ýòu¶ËË%IåOÜ03Tò¹'nºVs~yyn|~~æÒhªhtõ Ùè«7]«­F÷Ó<½|H£©¢ÑÕƒìntÿç¸×³»yÓfjXÒèÚ9ìÛôñd·Õè)æ\]=ÈîŽKf— ÖB¹ö¬5™9L7´\¾cÓ3­Ñ0ÐèêAŽ\ëXþ™Ymy·[i_fÀÂ9¬ÕùȦ“Mlæ»ÑFÏÝi4‡itõ W4zš°1‘ÝÏç¼ËΞ•|ty "ßèe‘wlz¶Åµ×*£ÅF/Ýi4‡itõ g˜¹1[Øe½¼]þ;õ….ÜôSG'Ýi4‡itõ 7ht>ßË»—6zߦŸêzôZ ;æ0®䊿{·vé 9¸ð‚Cɪ½¹éƒîlôônâYšÇå¿M%®äÇ÷oùu¼k«ÑU4š*]§Ÿ^ÉjÞi4 4šˆ4MD &¢’ëþíÒhÊi4^÷o—ãB —FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\ —FÄ¥Ñqi4ÍxøÿÉáEÞÞÞÖއħÑ4ÃÿN{‡üûø4šfhôÝ:¦½ƒF·N£i†Fï Ñ­Óhš¡Ñ;htë4šfhôÝ:¦×¯_¾®ûžÒ?:½Û¯9¬¿cCitë4šf´Õè䣷/µF·N£iÆEÇÆ¾nj4·¡Ñ4ãfž^©&—LŸ5Ëî²ÂÓõ‡Ñf#OïžXpnFÓŒ+ŽYš—ÁM|y}yÙèñö²é…:…F·N£iF[ΟG/OϻɯOÜAnFÓŒ‹=½{ûF'W;q5ºuM3N?6ò%-\’¼‚¼£Ñ®u¤Ñ4ã–—äg˜$?òòéÉaϢѭÓhšq³gXu âöÿ,¥ŠF·N£iF´FŸþ÷ä® Ñ­Óhšá¿×±ƒF·N£i†Fï Ñ­Óhš¡Ñ;htë4šfhôÝ:¦ý±ñþþ~ïY´G£›¦Ñ4ã—_»÷Z¥ÑíÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .ˆK£âÒh€¸4 .¦ý±qï)4éíímí}H|M3®;6Xþ}H|M34znFÓ ÞA£[§Ñ4C£wÐèÖi4ÍÐè4ºuM34znFÓŒsþxøñýÛY£å74½ÛotØôm& Ñ­Óhšqz£¯8–å64]Òo´ß—÷÷÷~yÿ祥ÖèÖi4Í8ñظîLvy˜­xÃò¡Ô×–Ý:¦ç6zÙÇñ¢ÄîÍ%ÓëÓ%Óô'«=|B sX޶6Ô¾=Õè¦i4Í8ëØ9Œ6žJ ûÛÃõ‡Â%ãuŒÙ’eú»I|ÇOˆáÏñéÉÁìµF·N£iƉ„ñöìð¯Ï–LÇ™‰¯]»˜]·5mô°03ø‘Õè¦i4Í8±ÑÓ»ÉFwëW–§Ï-oôrɲљÁì¬F7M£iÆ)ÇÆôzÅ`zaa¬í¾%ǽ6ø‘ýÕè¦i4Í8«Ñk þÊn¼Z_2½ú±¼Æßâ´ÎËß./¶ìÞ_nšFÓŒ³Žå8ã’ñüzz:³dy­9¹‰µ-N·›œÀñ]ÖèÖi4ÍøoÁãTÝ:¦ÝEÕH£[§Ñ4#x cÒèÖi4ÍÐè4ºuM34znFÓŒå¿ô£„F7M£iÆ/¿þvï)´J£Û¥Ñqi4@\ —FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\ ×s5úŠa.õ,îG¾bX€«=E£i4@\ —FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\ —FÄ¥Ñqi4@\ûýþþ~åÄø?{ý˯¿]9%þRÝhîN£âÒh€¸4 ®ÿŠ)ˆ§ endstream endobj 69 0 obj <> endobj 70 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡©¹ž±%XÜÐÈÔ@ÏÄXÁÔÄLÏÂLÁÐÀÒBÏÌ¢ÜBÁ%Ÿ+*€ endstream endobj 72 0 obj <> stream xÚ•V]oì4}çWä)‘ˆ;v>@Jè^Á+¸ˆòà6Þ»AùX’lÛý÷Ìx&Ýlõ¶Ú‡;Çã™9Çcÿ2Hà'ƒ\yVŠ¢ nÛàûMpq¥™ˆ2)ƒÍ6E SQš`Sýþ°³ûÉ Qœ¦i¨¾Žb­uø®·UÝ}ú guxHÝfžICÛUlTÿÆ >²²“þÙüh• c Ü"óSWi µHu†1ÄŒˆ5„©hg´‰·&{C†mš>Ryx?ü©,ì8ÐáÔhpmów‘*BöûÉundg;;‘Uñ‚®Ÿµ³O×ݺa²uÇx7Öƒ«h°ú}C,€¨Á7V#¤B‹Û¡o‰‘#†Ü<¡Ê2ºI ­†3Ðía\‡È©92“8º‹ ä]7ö¦aäÓ=Íœ:²P3N¾FÇúðe‚ÿYB ™Ð®ƒcqèaŠ69e«s†ÉdI¬Ù,²/!Å<܈™AéyE±X`2!5/øvÍ£yÊß¿!‡¶”’¢œÝ‚mvõˆVÁŠÀZbÕü¤×}em IUDkgO È][£?8V4x8ÐÂ>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 76 0 obj <> endobj 77 0 obj <> endobj 78 0 obj <>/Length 1426>> stream xœíݱŽâV€aöyv¤Ýn·Þ'EÊt#º”)ò)R¦¤LºDJžg‚Ér|í‹1>Ç\çû „ïÛ̲¿.f€ÿùûaU¿üúÛÛÛÛ?ý±îfâÄ…ëƒÈˆ,@ ‘$²D ÈY€@" HdÉóòùëևЪÕÿ7‘FdÉs‰ìûûûÖGјãñx>ŸE¶]"Kžkdý ÎwyÌŸ¿Ùv‰,yDö^"»"KžAd/‹—‰Ë©ËƒÈî‚È’§Ù®#Œºþ~DvD–‘f&»"Kž¸™lDdGšœZ‘Ý‘%OÐLvYøž<²f²»!²ä šÉ–áë?Ù¿ŽŽôo5èf™ÑÁ«ÿå–û‹k=øEvD–<3ÙA[ËbŽ&¸<ÇZF¶»^Fy掿_"»"Kžˆ™l\dë3Ùr‚|è½>¶Ö½ÙYòÍdû‹ù‘]m•ûe&»"KžÕg²õÎ=‹º ²¯‰‰ìˆ,yVŸÉVRØÔ_øš:’›ù.ÏT¶¶ø®‰ìˆ,yÒÞñu׳øg~ƒ¯Èî€È’'í³ fFvÝ?·Z—™ìnˆ,yÒf²»!²; ²ä)g².ë—"»"K3Ù{‰ìˆ,y®‘=N[HKD¶u"KžKd___·>ŠöˆlÓD–R¶Œ >s6ósTã¾@wôÛs¯W*ߪû<¿!²Díéàz}$Ù‚]ϹIýûÉ˪vI]gñ¡²‘%V%(ÿÛÈNýt*²'Yb-ˆlwÛ©§Ø‡é³ ‡ÿ¦jjqt¤²Ç©Ùå`ãS·*×)?ƒ_ˆÈî†Èkêœìá[wædwtSSÏ ëÍzpwsæÝwÍÍ++O¥_a›#²ÄšŠÂÍÆ•#£+—1ªßª¿ým#;uwêçdE¶9"K¬ÐÈÎ,Qå9øV‘­LðÓõW؉,±yáë‘ê…ž.èN³.‹ìœ"»"K¬©)[ù¾22]ù0ñBÓèb} 7¶ÌwåV•ÊŽžÜp® i"K3$†‰,ÍYZ$²D ÈY€@" Hd‰,@ ‘$²D ÈY€@" Hd‰,@ ‘$²äùøéËևФãñøóO?n},$²ä¹DÖ?ß½.ûóù,²íYòˆì"Û:‘%È. ²­Yòˆì"Û:‘%È. ²­Yòˆì"Û:‘%Ϻ‘}ùüuõÇØÔŽú‹—^ws"Û:‘%O‘-7;µ£œÔŠlëD–<+F6.p"˺D–<Ñ‘íž×wƒ7Gú§ú#ƒÍŽf·»,·6µ©D¶u"Kžµ"Û¯^w½||¤ï®÷÷5XΦÙÖ‰,yÒ"[®ÖôçG¶>“-'ÅåÆÙÖ‰,yVŒlñ®ÈVFìÌ“¹wÙÖ‰,yV‰l=yëŽÌÙ£ÓÔ‰,yB#{Xé…¯r7³>u"ËAdÉô„ïøJ{GÃb"Û:‘%È. ²­Yò> endobj 80 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡©¡ž…XÜÄÈPÏÐÌDÁÔH›å õŒL!ê-\ò¹9 ) endstream endobj 82 0 obj <> endobj 83 0 obj <> endobj 84 0 obj <>/Length 6272>> stream xœíݽ²ãFz€aìõxª<™j² 7ØËP P™j² ø28tvÚ™]µ{?K D£ÉF7>O âÁi …~‡¿úÛÿþ÷@'Ra€ŽT §ÓWø_þõßzïBÿ¿ÿé½ @ç®ð-Á—‰×?þôÿþ­÷^­­TøDg——IðÍ/ÿù_¿þúëÇÇGïyÉüÿȤ¾»wœ­s(Ë ŸèìòD»1Vøì§ÃÓý1ÿïôݽƒl£¹«ð1gNιövÓ5*<ÑóMßÝ;ÂÖÏ~€]Ò•+üéów¹G½Ç_”Ý®8]®õÀú5&‰ |ëg?À.é­+ÜP:x¾¤¼ªø†®1ITøà[?ûvIÛžŸ÷ ¿Ÿú=}"Y÷²\áòNV¬pym/V8·¡§Ïâƒ;_ÿbd!4ÝKuo`d÷†Ùñ¹¸Ï§Ë…z#;\¾sæ?Î7”. nnuë*|@¡ BötÎ^?…|¢Â‹c:3ÏÜðÇq?¿¼º{‹5Lë_]Ïùè¡ ×õÊj/SáÜaüWðõ §*f*|Ý*\XsùWå½M¯¾:sæ;Ÿ[^¸‘R¸V¾y…‡ä°c…s Wÿ‘Žïð‹þ¶¼u> g*¼HØ9×Ûûr¿ çÖðÐ f§Û«¿ZìósHÄï·ò¯Òÿ•¹;õº‹[QÍêý™n"·ÅÈþ§+‰ï^aa°Â¹(«0«{\8=CÜlÜbUO!ËžÿøD…‡­j”ã˜ÞÍ?'s^ ˤoÞoå\]s䟢G+¼¹‡ÝoåýO¯òèãÂåÿÑåN÷öÑÇ…7gÁC!Váêp.¼8i=Zá'N!sŽô¢pÒU¾!å˯W¸\ùàòýüG%Wáùà܇@h7g¾’àqUÞ‡ÂÍ,ïÞêòD…s›Þ¼s6O;Ò…*| 5+\nnºäÅSÈG+<Ô[’ÛóùzÛZü*·õÅn?WáÂ-Ü¥éVÊ.¬v~+ž;._îC9Ru+ÜúCžÿ¨Â°K…ÛœB¾þêæ‡N%ööb…ãÿ;"Û\ÿê’á…Ç…#u{b¯žØ½Â®Fö³p3_TzXûW?x «ða½Zááþ°&ÛtùõSHŠ÷yîÄóZéßÃýŸ¹ÕgnõÇÜ Þ´ùž?t.œn(ÝV|‡_?.ßÒòS*|XW~ïܹ\c’xïÜÁ·~öì’Tø(®1ITøà[?ûvI*|ט$*|ð­Ÿý»$>ŠkL>øÖÏ~€]ÒÿWø€_‹qÌ©þœk|×°éË—/óÿYá+ à˜Ò?JT èI…zRa€žT 'èI…zRa€žT 'èI…zRa€žT 'èI…zRa€žT 'èI…zRa€žT §ƒVøÓçïÆÝÈýª0`sÍÓåçÖPÑY+üôzæKÊ«z:ôqG¬pùl·b…ËkSa ÓTxñHB:fº<ŽL//†¥?N›È­gð P[‡ ß6™.üë_þ<^È…u±0WáÅUž;.œŒO Wopa?ÿüóUìSáÛY,œ¶õb…sk˜DÎ…‡ÙéöꯆßïŸ'o?pB_¿~½Z…s+Ÿ÷n˜= ¯ð)r:,7rõ´zõêÀ›(‡ëÅ5¨Â¹hnVxz ÷¡G$Ê—U˜¼{…‡üëýfO£•Ÿå[lkñ«ÜÖ½ÉÀÙ½K…㜓-©ð’ -©0@O* Г ô¤Â=©0@O* Г ô¤Â=©0@O* Г ô¤Â=½o…}±°Ÿ‡Zô¾ž¾’ ®xèT > Va`'*¬ÂÀNT84X…¨ph° ;QáÐ`v¢Â¡Á* ìD…CƒU؉ ‡«0° Va`'*¼ZáÈçKøÌ  L…Cƒs¾íw኷›´ßM®A…Cƒ þøøÈ]ñ¶þÕ›ðéówã ì«înäFÁé¨phð¡*\¥wÕ£™[¡:C™ ‡«ðÓ+Ta(SáÐà¾-/L¿š–ÌNËoK¦ éÕÇMÌ̯¸z9ýÕ|ùbUéno®mõ6*¼w…çK¦€.–¤ƒs5O=_áê«›.\Èíöêžäv2w¿Á[QáÐàãWxqNºzõàÂ+\Þ“ù¯r÷¼ >x…ãWèºOT8²¶Õ{Þ– ‡_ Âm‘Pax” ‡W¯ðüÇÜ3W…¿ßW“7\x¬ ðhÆf|WÿýÈÝÕæn¼- ÎUxóó%ªÜgŽpa*¼ZÛÛîE®þÜMpÚoB…Cƒ}¦° Va`'*¬ÂÀNT84X…¨ph° ;QáÐ`v¢Â¡Á* ìD…CƒU؉ ‡«0° Va`'*¬ÂÀNT84X…¨ph° ;QámÁÏNxŽ œ€ ô¤Â=©0@O* Г ô¤Â=©0@O* Г ô¤Â=©0@O* Г ô¤Â=©0@Oï[áÛà=ö³{t>8XõP‹Þ·Â¾ñˆÔ£Ç§‰U¾ñ(4Øä!¥ÂT¡Â¡Á&)¦  6yH©0U¨ph°ÉCJ…©B…CƒMR*L*lòRaªPáÐ`“‡” S… ‡›<¤T˜*T84Øä!¥ÂT¡Â¡Á&)¦  6yH©0U¨phðêä‰|8‹On»°Zv ½9 ÎMžÛ~®x»Iûݺ«XaÒ;SáÐàÂäùøøÈ]ñ¶þÜMøôù»éòxc9ºv ½- ®;yn3g>a?ÄGÒ@÷ ;®A…Cƒw…I—lžPËôG] ‡¯N’ÛîE®Þkò¬ž%QQ­ ü@z‚ÓÞ‡¨ph°Â"å3Õ¨B…CƒMR*L*lòRaªPáÐ`“‡” S… ‡›<¤T˜*T84Øä!¥ÂT¡Â¡Á&)¦  6yH©0U¨ph°ÉCJ…©B…CƒMR*L*lòRaªPáÐྒྷç¶ÓeÓø8NWaÒ1©php¯Cvœ6·{gZòý÷ߦÐ1œ¨Â¤#SáÐà.ëx¿Ü.Ìïš~üéößÕOwµûù×…¥Â¤ƒSáÐàŽ“g~¿Lr÷Lz»öû߯¹*ì@:, n?ywÊøå|7VïœÅ°ñG“g'§¨°éøT84¸ïäY}R¥0y¦›¶úãÌ®iÉxKӉʪÓUØtL*|¢És»]_¿~çÀøßñ–Ž?Ž_ë0˜Ö3-™¦Ímá| «®]aR3*|¢?$Çɳøï8yæ#Ó…Óàá÷/×ñ8à¦ÓUxp ’ ‡ŸîI•é„e>yƉ1OR¦S˜ùLöüÿ}§¨ðà@:< î5yrÛLžÜ…iÍ‹%&Ï£NTaÒ‘©php¯¶Æó‹ù~¦Kææ·k¼÷3d6ž¹äþ4y‚ÎRáÁtl*Ü÷é…ù7¥oîsz§Í—L«J—Œ ƒMž‚Uxä@:& ö$/©ÓU˜cRáÐ`“‡” S… ‡›<¤T˜*T84Øä!¥ÂT¡Â¡Á&)¦  6yH©0U¨ph°ÉCJ…©B…CƒMR*L*lòRaªPáÐ`“‡” S… ‡›<¤T˜*T84Øä!¥ÂT¡Â¡Á}'Ï/k_‘@w§«°é˜T84¸×!;N›ñkÌGßÿý` É*ì@:2 îø · 󻿇ºý÷ãã#÷áÜ‹] îüôqݦeÜY*ì@:8 >ÝÕ–ä¶5óQ°q窰é°T84¸û—6¦ _`¾ø~ò‡&ÏK;ýfNQaÒñ©phð¹&Ïâ›iV¿¨f>~4}óy:rú3sðHâÌå+ì@jC…CƒO4y¦90ñ‹/ÓþøÒÜÅ’Å×…-F|ÉØ4Á¸v…Hͨphðé&Ïâ¿¿ÿ~Æ!󫃧åÃïß'æOÎÉ;TØÔ€ ‡ŸîI•éôd>Æ 0ÉMžñ$%wjcòLNQáÁtx*Ükòä¶™<¹ ÓšKÒ³ž!9µLž™UØtd*Üë¬ñß«òàù:s[’4\Ø*|äiuÓ…Ckqau嗤¡Ám&Ïb•Ǥ§*‹i“>b˜®1 ;·¸™ž©0©ð·í¡Í½s»SaSaæŽ Ó˜ ±Ât¤Â4¦Â*̦1Vaî¨0©° sG…iL…U˜;*Lc*¬ÂÜQaSaæŽ Ó˜ «0wT˜ÆTX…¹£Â4¦Â*̦1Vaî¨0©° sG…iL…U˜;*Lc*¬ÂÜQaSaæŽ Ó˜ /¿ñèQé÷r>½ªù:}¾p/*Lc*üj…G»)Á}©0©° sG…iL…×+¼øºÌ!óœóñ‹oSŠß:°:>wÝñò|ùbU¼H…iL…W*ùêøÅÚrßiŸŽI¿ê8÷Åõ‘ï«÷ öÕ©0©ðî^œDç¾…>²P…PaSá}+_U9¬*ÜŒ Ó˜ ÷¯°G$E…iL…¿­¾à÷õgç}Db¸°xqÝÍøªp-*Lc*üð{çôîÚT˜ÆT8Táò‰0W¢Â4¦Â>G‚;*Lc*¬ÂÜQaSáßö¯ÍÖ8¦1^¾R-þäÛCOÓ=½SaSáç?Íç• sX*Lc*œ­ðæ§ðD>vg¾¶\…ã÷“.QöêT˜ÆT8û™jéûÖ†â§ð,çÞ—{#FdCåMS… Ó˜ o|²åh3……Áó«¤?7´“®ZT˜ÆTxû\8]²yBúP…ú‹òVx Ó˜ ¯¿Fâ‰OáÉ ž/Ÿ.ÅG$žÛ4U¨0©pöõ›àk,â8ùÈžÂú‡û”S‘ Ó˜ {ïwT˜ÆTX…¹£Â4¦Â*̦1Vaî¨0©ðóŸ#Q~©YùŠÓeOÁµ¤Â4¦ÂßÒ÷ W¯ð‹×òr´–T˜ÆTø¦%¦1þV~ Æxañ=‹Wþ[¯2N߈œ{ð´ýÓ‹ Ó˜ g+yÇÚæ‘Wν#n1`ðÑ?=¨0©ð·E¤^¬ðâ„·ÜÕÏèYŒÙ¼Šþ©N…iL…¿-B6>á!w!w•BÙW÷­PáÂcå×cq Ó˜ ·«pá•å_Ev)²Dˆ#T˜ÆT¸ôzáÜòÏ="vnñ«È.­îƒgçž Â4¦ÂÞ;Ǧ1Vaî¨0©° sG…iL…U˜;'­ðm·{ïÂ)}ùò¥{Tø·ýKŸ7Û‰W)ßy+|ÆÝîë §b*üügª=‘T>¾“æì¤»Ý— ×Wñ;˜#½bù]ÄIsvÒÝîK…ë«[áÍÏÍI/¯þj¾ÂÕÿ®®v(¾H9]9µœ4g'Ýí¾T¸¾Š~èss"o#ν½¢ð®¶Õ­x#ÜÞNš³“îv_*\_Ý ÏÜ|gpaðü*‹Ë¹Ž¯®JÛ8iÎNºÛ}©p}; §K6OKW—ÌÜ|'ty+B¼Ÿ“æ¬ïnŸô™j®¯âk$žþ”œÍî)¯¡ð¹ΈÛPá'¨ð‹»ñî2¯~nNù)µÅøÅ’È#«k<;·~Ôs/þQáùn¨ðÑáx}*ü¨Ü‹Fés'Çy¶ù PáCWØio{*üò߈C¦Ñ»ÿÐ×A…U&*ü®²* ÿ¤Â)¿øgPáØn¼{…7ŸI{ÅsO\ì±'©pÜæÓΑ%vSáúž®ðpÿÒˆên]ž¦Âq… OKÊÏέ®¤®ïJ~å$šW¨ðë"ïcŠüjo*\ß+H”_º»øÓi¾<øâ*ó‡À¦­¯¾Êx.÷êŸÅs¯S>Ÿ{'u¨œÅj·ƒî~pªp}u+y³\ᯪէ V×–^}ó"›Õ>ÂS'u¨œÅt·ûRáú^|v®|R¬ð§µÏâÉUu¾?ÏUxus¹ÁDœ4g'Ýí¾T¸¾×_#ñií†p…z9Nù‘²ù‘ðç6Dê¤9;én÷¥Âõ¼Â‘‡†µhÆ3ÉÝ!Ž;iÎNºÛ}©p}Õ_/yî+þˆDðÙ¹x…ÓÍ¥WïþÈéœ4g·Ýþúõkï½8®¿IïsÚû¢“Vø‡ê½ gÕ=*| ;í­â¤æ¼Tø:¦ ¦1Vaî¨0©° sG…iì­+ü׿üyÝàÔT˜ÆÞ·Â·ÝØc¸¦¥÷­0À¨0@O* Г ô¤Â=©0@O* Г ô¤Â=]­Â{¬`Wש°7%'u‘ 0Qa€žT 'èI…zRa€žT 'èI…zRa€žT 'èI…zRa€žJþúõk¿xëþáÇŸúíÀ{Y©0]¨0@O* Г ôô¡U½® endstream endobj 85 0 obj <> endobj 86 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡©±¹ž¹ XÜÐÈÄXÏRÁÔÌXÏÐÂDÁÐÐÀPÏ¢ÜBÁ%Ÿ+* endstream endobj 88 0 obj <> stream xÚ¥VKÛ6¾÷WðHW|JÊ-Mº‡"-Ä·l´M? ==ºu}‡Ê–×ʦE°À.5œ™o8ß7ä’¯„“ ~8ÉÉMÉŠ’ljòËŠ<< Â3Vf%Yí/—¬ÔdµýLßìip]’J)©x“¤J)ú¡µÛc³ÿÙ[}ʸªÀg²Hj›m\lÿû6Ðsk›|YýF”0Lk¨ÅCäÁ”F[ª 06ΉÈi;úXAŸý‡mQГmÙlÜi²ÜmQ±¢Y*IOë{\¾ ±Ñ©…èîùØÇMÌ¿ñ±Ûì] ²ÃEm·Ž…ê]‘k{SÎá:ÓLßá‡ÇÚ÷-ùˆ½–„+&•‰½Ny!™1áÄ‚É$ÕFз³Æåš¾Ÿ÷~åŠ3SDœ|†ó‚ÓT«¢8I!i×ÖI*¤Á¦ ™GT4È`ì$´¹vÑ;l€Œ°8ÁŸ‚ºn×v5FÄÀÆ»µ§l –œzùˆv‡íj‡cÛôî`c ¶0"¿–86[×Ugßß š G­ybŽÍÀP#TÛ n‹ô±*`/zup}ô¼«ibÜÃ=<ªYS ?$)×L©€šË£ÏæÍÌLbÿÐî1å*)ílÓcÛ¼Ä/,ßrWælŠŽó×¹Se7±`[U³é ¦¿­Á>‚`1žWÃs&MLø÷+Џ½öÜ1iÕî§ÃqbX™+ï,J&Iá„8³b!¡a¢$'ºP”òY¾]dqû)a Te’Éòÿ²ñ΢Ì`ìö®ñC.Œ¤ŸknˆMµÛmóe¡>®Ì5©')+é§q=tv3`, Øø©K„¡Ï)Þ3t’HE ´ípL¯)ÔKzÓˆ>›„IÿÎâå…úŠÐøágлxÕÄ‹¼o§©±/¯S¬1ÌG| ¦ýyjõú1V¶H&Rô\Âí 3ÛYo8{(•O„úe8ƒ*^#T+–ñ¡¹œês`k`±i«±n"Ÿ˜umȧ·ú È‚Íø›1Œíj–:ŠÈ¸sG§Œtª{:å…Nµ@g¸>ÔQLæ\F6Õ÷ÙÔÿ™Í?àV´Õñ_Caâ`Þó”—þI»Ð¤5§¿Õp>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 91 0 obj <> stream xÚµYYܸ~ϯèG5âÖè ®}sœØ`m`×ä!“ޤ1ÖÑ%{{}ꢤžÖ8ûÅ#ÅbU±Žì×Cxà/ž¢4÷ô8êc”y+ ·Z桟æ²Õ CïÃÜNæÜ^puáé¶e6_I½¹¶ØÏ<Óóx­KäÞðh9´s'3ÃI_böHr0¥æI[êV}Òå4Œ"d²2Êß ùiG hEJæíÀì§FODzŠ³Ì‡£>Ái†|šS;Æiâٹ㊊_™I=ûeÖ#ªº;»µEœ*²ޝ¶ÀQg œ1Â*ôn< H†ú¬G=Õ;zÇ*ôÃð{Ї~ìæu»vçyª+Q>‰|u¥üÓ n¼6ŽD؇£ÏëR?¿ _Ñ¢û¦¶¨{–zà œy5Èl†Þò ØŠý0a¬cé$r¯4@øwª1.ò„ŽiÙœÈr¬(¶`Y†¾5f‘.#Ëwãä8Ÿ[ãt•_¨­êÎD,Íx‘ÃëÎ$è0NºÇ™ åÌ"‰_8¢ Ž3“Ûf˜ÛÊÙº·†e23ñ·k<Ím{áî#q¯Áî5¯v©°‹IâËâ^Vs`‘œ’|(ÁV—{2£36Ÿä{½š³)“ÞÐÓŽÐf×ôù|Ä%{ÇXX¹•ººz8þ°“ºrL§0õãøeâŠ^É[? ϼÑ4êÞ"sÙS¿—,™îýî=ßÕ|älÂÈì~]¾Â;?‚\åšÆ'w]­{w<V1ºÿ¿ ¹I踋“ñ3ç‚Õé+6ˆ Ô â?Ø"¢cFX¬ƒ"$þQˆE3R~HK#¢æxJÒH\ Šs1rð½1Ø öÆ›`+”%ª£å…|;Nîýõã[6å8,ÅÇ çþêËtbtaÆÁUŽHfȶ^I‘úžRû;8ž áí<Ö§Û ±Ù@o 8˜ÁNÜêõ4švÏ£dìÚZL8†ù¿-Nþκ¬QŒ$öÞ-ég´²ŽÙ¢cêM,Á·¦v2,ÕIv#};“á3ùZ”Ž™øû\÷5·`'°“Ť>Å…$wåA„7¨TÁÙ©Èg±±&q—Ñv)XÌäå6mͳ­åy¬¸°¼ºUbÂCJ‰­Ä ÀtIPxo-`šgQ1œC*)Ef9z˜±¥ cýq‚R:ŒÌ='rÝ?×'Åÿdñ´™^°:ó7:= Tå0ãö;ªéiUmÿÔŒõ 1+Î[˜'Ày¶;\Ûœ–¿b¹\b¦0°(0·Q"¯ÀYâ" íèbɈPØkª~{eqêýˆ.‡.d E£äªÌT²A*@è`>ÈÉëa5Á•ScúÏ<„‰‡œ °†§ úЉ¶“«åpF[`AB;5;qd5r_§Ÿ{3ÍUÍÀƒAmä­®CÆ>OLÁ¨6¢À¦gìÁšI˜Tf¬K4ˆeÉz6i¸œ ÐSö xx +E°ã+ýE‚]E*™1† Ò—¸y8ý§•MZûN +Bþ0°ƒFÄãnFùÕý/÷•»uüy§B$x«àiñ¬ CÜÚ~W<œqâe,%Hû¥x1~BŽèžØ1”Ûû¹ÎV€n¡|Áø)§~ &ÄÒ—+^{ èPކ¢¶˜mí†jù½æÆ™«ˆ $%Ói°ç#W·ãf#ñó›ó¦€€x_ýû´uÊ!๢0¦¬™–‡áRiÀÕñB^jwüÛiÚKŒAFÞÄ0.qÚk\Nÿagª”yäaÜ&ZjX†«‰ Ýõ’p÷ÛÂЬåJIÈ€5©Âbƒb„›¬-õ29¤-é£vCør‡LàV‰ Ò;JúpdlôÈ]ɱu&–é䨡° }ð]üÿüš©ÙSˆï.I¸ñ*Eé&Ó‡R_ÜÝ* 7“ÑU\ÞÔyéºzáBH+4K7Pš‚i, Üìý1ô™¸ŒMä×£Þ(1¢Æ€YäÙf½öAf£5Ãø™{FÀ.ŸD¼À¢4Å”!P4b(úóÝÉ I…c§'¤×)_ÈWègŠ|zɨÐA„Üuƒ°Þd”€¬ª1Xx½4l®ºg®‚B£e€( Œ¦¦+ Z=> -m3w˜(esž€Âsë>sG'§,Xç–2 tøêcA/dt ñ$« m¸z/I (™Ouº’ÖÓ8t<¿ph[.dܧâˆãuÛî@ëÖô5aqðô÷˜†Q°ïò¦‚=Dj”,Âm²ˆ!¯ m¸æñˆæ…ª-Ãi rÕ›Û<‹äœM {3°V/ ŽXH6pöV1m‘4²e£LÀ'¶Lïæd`cyÊÁdyÊž‰÷ÉÈx¶&ß+úl9)fån%˜ú%×Cjm\dÜ l%…spõ`jxD¬>roçò…§^¥òwÃF÷º½Xc¹7ɦ’2yÐô•àH&õZ‚ú¹ò‡ët7Ì/n±6J;Û‡ÊÃ\Ù†œp‚Ù†êʸ°t=Œ<ð@‡ŒÌqZs¹3‚Ã*fênþØÞ^ÄKá(œ±‹+$~.r!„/dôiû”²Y½S±Þ, îF ºÅ‚²ÆºL¿¼ÈÄ9ÁíÂײQRõÂ(LÔHmh„U‚Ÿ² ÷Øt·ù%…ÇuïʽiÇÅšpx¶üžZ,k¬;÷H‘ï!œ@¯aäáW'¦kÆåq4•ùM‚0ZðÄ O¸M[äÊøG1Ɉ÷E² tÙÀа;ñ}…û¬·Éûr©ƒ2&׈<^÷àóƒÛ€ÛäVy|u™±ÌŽÙÆÞ/ßîH¾$e‚Œ*`#'Û²Ç(0ðLK<ÑÏ”L 3®Ú57uùe6p_dA>7rð<:¼¬ð>­é¦Í¡Ýèõ= Gœ’²wŒóFtNÀ9è‚È¿äIÚÎb›Œ¯Âœ1–Z³޹‡o,Žš‡ð:õ+—†Œ~µÓ#Ö“"#$Ë4ÌrM[8V^Çr”ꑯ¿„ÛÛ+³,Cp}’ËÊrGšÃWœŒw#r# ѸpžIˆ%kj†ù¹á #,Üo;D¼tè€וc§…Zï(ïzg9nXO)ʯÞj°/X)„r+v"6­e±qpû³Ø†»ÄC”¯7¼ ÄÙ#‡Þ¶»jæû,qG£—™˜Sàîã~PZ’v̘oE‹sJ„‹“æ ÷$´ùÑŠÅÒ—ŸÐn(•¸_)ÿvøùOÿ: p< endstream endobj 92 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 94 0 obj <> stream xÚ½VKoã6¾÷WèH•"R´{Kƒ.¢-PÀ·¦Æ¢m¶’˜%¥ ¼¿¾3RvŸŠÝ…Î{>gœ}ÊxVÂgÈšº+Ú.ÛÙO»ìî£ÈxYte—ío3^Ý6Ûõ²‡“z™µÛäUU1ña“K)Ù¯Võf:þˆ\ÉžJ.ÐIœŠ©©Dÿ÷âgf¯fµùk÷K&E]l· †è+—œ5‡/$&‚àq‚peÃŽzÒN à\Š-{$¦Ó{;Ž#áq>i" { ï¨{£¢'§@Ï%‹Äu¢özÚ¥b¤Ly’™9~ãy´NSæ\„OUpÍÙg(;BpTfJ»ÌƒÑÎÁðî#uÙqĽÌr¸óàBUQmòm-ØïÖj0_Ôlì ¯ï ìxSÔU°{«œ‹ºa^Ï©–@BbTÇÉÌKOÌ/#‘ˆÚ•*XZ”Óþ¦´eŸ7Û-SâýÓ†ô“Š¢³èëÝÞËúŒ,½Ÿ­ Õ”×ÐÍ’%ãEYÎuÍ~³=à¡ëJrŠŽŒÞøYM{MìQÏÎì=‰  z¢ž7¢fgÄ¿cÜKèfÐÅ4¬û‡D¯f>ߤ˜Ô0DÃ)ÂJNù¥“ß$)ÌcóHÁžì!bŠh(€•dÐ/¤Ç©ÛHÿLœ¦vÑÜ:s411<¯ «{À«)[öx Éë¶ Jr¢H—8tpHÁßÕr]1êý·¶ 4k²ËÐSî^ HfóÉÄŠì ¶dH²c÷$õj|t²rFû˜Ô!Ù@Ç´P}hç(wƒ=gvjòöx#nN¿Jd‘"§™‡ÌËL# pšzR»ÌiGXžý×ÊÐi¼:è5Ç-‘²«Â vŠðØøÕ1åÙŒÚc¬ª„ÕÚèÄ_áYטü>ðTÿž¼.êBw§ñ¿£çcfö2ÌiwMÄTôÆÌמÔ}XtõÕ¢l½;;ÒqÃ>1Shx¾5÷aˆQh¼ç¯&­]•62M|’Ü^“—.m® žkŽ(ØÖG’€hØí,Õ¤;jã53¥*ƒÏÈÄTkäžÌR–D¯[ÑGßos¸½«ðÁeº;œ<°o1¶Ü²ûÃú×) 2D<þªpÈûxÉï&2׎ï6MXx…h’–š$î—7`º?ï²?~ø+%£½ endstream endobj 95 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 99 0 obj <> stream xÚÝZIÛʾçW07 °höJÒF.qò€à‡7‡™h‰3",‘c’š%¿>µts‘HÎØñ»:쥪ºªººêkßÄðA"ƒÄfQš»Sðç›àý/2q”ÅYpsˆ4*ÊLp³ÿWøé?tE³Ù*¥Bõa³ÕZ‡)Û.¯vÅûßÊSyÌ›²ÛÈ$|áA§"oÏMÑnþ}ó÷@KÕ˜h‰˜ÚÞÿb‘DRä¶uC¶’4Nm¶ÆÊ9.*&.‰žr™Ê[™DÚ­›C²4¼…nÚ?²p‡òêrç:»CîzNØsæqiøe¤ÂÂuå{÷V¶ü<Ô8ú‰Ç¶—º@¦aÝð[~-VyW>n¤ ‹ãË&Õá;P§ÐáÞ-ôvÃd‘kÇ×¢¢uÂÊÀ2‚-s_T(NjÂâù4Ñ–u…ß6Üç]Îo$(<»šŸŽ²V Nªbm¶6–¨ªÆuåþå”W~9Àè eÏQ¢—–[<á]}z8wnÒ áÔâäè—T_/¨-š²hÙ‰ê;~÷3eÍ54B£ˆ{ã§#ØË»èCS£åžIɰ(ï8¿s”:PT9ÇQБBgñŽc5;a$¦nˆ~g¿£¯/y[ìù•”ÏîàF~Fo-ò¦å :jšâ˜#ûy¯Y$Ôàµ2“á©FW”™B Ÿê ü†¾ÎÄß.ÝŽf]SîZ@¶Ä',¾¢HøüŒ“¼Œ8s$#jW /Êtì•íÆkÛj‹‹eW³»²¨œ°kÖ½©§w6üû 5xÿÐÖà³÷~¯6>$˜‘rej£Xº0ô<£}!"k\ÿŸ\¿÷C@tÝw3ô †›)u!e‰ÆnIÚò®%f(èH'A?âãf+¬¥%8ZöCå[‰}=ÿ¸d¤F*F*£jF-°n50ºŸSl¯ø¼ÚÏÙFª™7°+¦D!‘7.˜è’ËX­&RæGL4G ¦È¶Pra¨üx™±Ì"“½n!¹n¡l8 K}û“?ó¹-ùCî¡DOšÜÌÐN#95ØHš ‰T6Ró_o‚o4¥Á$2JRŒ…@X'hÈ"%û†cð[ð+ç,f’³ð4 ô…±6ƃX/³@Æ‘H¦c4¨!³Šý)J`·ÊäÁ1ÿœ¡Ác y‹dVåŒHÌfÜÒÅ An/MÄ\nc9ç'id@ :-j1¶”³>Cû·q_©]* 褰_-¨]jKNÌß ZfY\Ì â„4äzñØ¢žôªA¥„ˆ-&½•šW€&¨©ŽÆº6|B˜ðb‚Ë,i$¶é ö¹½w/~Tí)è&«=¿¯ê½ŸÖëýåš¶5<¨×»§½®øDaP›âÕHñ/sŠ×¨¦©â¯ÕaÜÞòÞäpxIàlq»m•ŽRNíŸ(_½\¶…Ð AQJZì)€iPîøï…E÷“Ò‹6 ”ir(9ÙÉyÈ#eHM~_pæé“ØÇÜæxöiYÍù8¼YKQHÝÜýÎ1?O“(MÝÀ×,§¹¥‘µƒó–Nr·^ÈÅ %ÞçÍÞŸ¥Ëý†ä]ã趸T'Þ É1Ï…h—wPž<ëŽPh|’|™¢rŒ÷7`Æ?”±âÄ.ѺÏË ‡k**‰„\I¶Ò(õYÒmø— js&}¡Mõ†„WM²©1§$2iÐx*»Ãœ/CüPoÉÚ–ùøLK¹3“É಺–ñù"ǵ¼Æçr-P—Aõßín7î\j.¶ƒgi¼’¦õ’5Å•guÓqÖ‡èk w졾‡ðD[àxä}>ìèÚå. `6Ù¹²[Žeå"m&ó¡Âï+ÊHø@éûp,«áR1á8LáÂXvÊê+¿æ\{ÖçÎw9R!"L—‚!NvôigÏl5( ¬]ݰéza$PáË{5ÃSÜhY´Ý¹áC¨}猗<.GÆ[òN*–]$‹´ß$X›ƒljG‡Àµü6Ôrv°ÂASÂÇ#&u?aKý¢˜0#?±â!Ÿ)>{¬Æ\b-.m˜ ó¶)8‰Á ½O¹Ç.`sÔ³nVµçÇt’±Æ©Ë8yÅ „Qz„f‡Å€1=2ï|6¨rïP•r—‰UÆ×ÈÌÀL‹~c2ð‚Èݱ葤ïsåuW쑪0nEÐGKñ«4…›»b×qKýàÂJ[v¸±á¨MÈ|ëH’²v IÂ.2>Éz8¹,1gHýsµ'hJhŒ9äÐÜ5yÕÞÕÍ©g”°'Z,㨠ªÑDÍ{žïß+Ýp¿®5OØÔ±+µÓñ%sG?¼LŽ~1ŸŠ4Ùê©Ýc_< Ä$ž 2bÐÈ,ßïù%qRÔ®ýÅ2p‰±¨ê3V¨G+cÃ"æ}­ ›®Õ/.Ö¢*"îêÈPv%¸ö*}*étÓñ>×´Qè!¯î BGˆò怎x&Ñâb#Cr9 e:ö›Þ¾‚èéOö7O‚'1á—³›¾/a{(ÈPûí§ü¾*»ó¾p‡­irøc»íú×è”ácÜÙÓ '¶/oÄÂ9ÝãòÚ€í0;?¶#|ÝòÛ]}v#®–€ÐdÍÔþc3ÿ.dbÃÈÆ†)JŇM*ž;—ÐP]Hà'DU|YHPÃLlBÛÄIxï®zh(úŽ´”™Ä>ÒÆˆ<æ˜sOP8jê€#ÿ8—â<‡ºÛâÈ1:>]œ“àt ñ=Ý<)K2­¿Ä€—¹ ¾Ðí÷ïËüXßó;ðtýòLW3ÉDs‹Ûf†1;Ä„õ]}ákiteã‘×hF*uX|;³öÃB¼R Yfr ²4W¥EÈ2]‚,3…ù3ø–B:AC†%¸oX‚,ý´Dû5-@–ê ˆ¥&Ä2[A,ÍKñ¿#–0 £ëwC–è ¯áÆ•Zc\E£ý´Ä"òu €Lj:g"¿bpÃk1·‘Æu(½Œ+J‚“õ”9|‹­ÞÁl9gç–.á¿ cœB|Ýr¤§TDÉ«jò³~–šT6ÒÓË‚žR¦ Ÿ œ«L"™¬a€:‚$^I¼z •¸óéPòa<§i›"”ºUÆc¥Ë«•Pb¿eµ æòU¢FˆDœÜXMÔ!P°§-«ãÑG7ƒ8¶œ‡–l©¥›Ù6)`¡ÔÝ!IÉË\ÃÈäÅ î6` D,9$6(_R­,Ïâ†Å7MËÈ$?é^&ûÙ÷2r¿ÀMÄ~‡³×w×Ñëw2c6 /µ†ËÍŒ¤ÄÄ Ð¶Šmû!çÒÝL h¥êÕ½®ß½ó¿ü°óËßÅù3ŠjÆ@±D×Ib÷ ‹Î/ðO[“€\zÅù Ò†ˆ …:âfQÊóÓ´ÔFúÿÑ÷¿ãbì§ø¾Yöý³ç…ÉÈTï[7L¤µäÿpáóKÞbE•‰t%°VqØæ§‚›î eŤÿ­eTX<ãUâúȹgÞ¶çSÑ^CÀdÊ6&j±r–O½)^iU=½«”—æB-PÕxYamâjš8O»‚ñ`þkòBàòŽ»úŠ?¦…'¶LÿxûBd×Õóÿ­±”u­ü·&JöÅ¿€Äjí/ °9Ò¾G4V8-±iR ã’±@füÿˆ2®~ûœüÃÿåÍ€bP“mE”IC._úrØ8XÙ`a8L‡Y`ë†_=CT™ Ö(ÏT¤˜dW°´³Êh&ñ¹I.«pO)_¼Á×÷tAë×?ü ¼. endstream endobj 100 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 102 0 obj <> stream xÚåZݓ۸ ï_á§Vž‰~‰’6¹}¸´™i;sÓNv¦u´¶v­«-ù$9ÿ}‚Ô‡Íõ:q.éÍÍ>˜)~hg¿ÌČߘ%r–˜Œ¥Ùlµ›ýx7{ùVÎgÏfw3‘΄bY<»[ÿ;z³É÷]ÑÌJ©HÝÌZëèÏeÛåÕªxù®Ü•Û¼)»¹L¢O´hWäí¡)Úùîþ6ÓR0àÊ-/!,mሠGvfU7M±Í»²®æ ™ÅÑ2Z2…½‹5ÑF‹–s"Õô+ðÇD÷‡Žž?”Û-‘ªÚ‘69²{?—iT%w{*»—öÒ§¢L$¨@ÉènSXaølʤ,Ç©?µæé”“æYT¶ô[ürÈ·4ìjø<ꀩ%¬ê¶¬Üw¶‹üd^=nçðøP¶ÚžêåÛxdP% K…3BåŒ-nX¬Ýôb]…ÓúýGŠUW7m€·à’ié^þà ÖŽY’ŒÕ”Wë')O£OFÀÅòÚ€GE¾B¹7¤¼¦ØêœþËê©"ÊñGŽ„ rY…d‰%KÌy=Åa=ËvŸ¯ Ú­Ûä÷yÛ­§6õáqCdM ÖMùXVŒ‹ÊZi’HƒÌð@¨n\à]Û¨l7`¼j&4SÚ xáøÐ¥íñ“óEldôS]-öy“F€Q;Ff|šÄó©? F2&”eyg5"âèÉQäÍC,’š¼ú/¦ ± 00Ñß Ðãvû§6Óʹޒ+8LÆ´„l`>¨8¯×eçœ7u®a™9D&‘¸Ø³©@Iä Rq–N‚ÙDyÚx› ˆÐtš®œ!ÈÀàˆmPOku •+‚¨Á›'µ7OëÁ¾Z¹n‰BGƩښúBÈ)‚óǼ¬ÚÎïÐmK85@“iXc8übÛ‚ùvu‚1šÃ³9Aƒµ·h°¨Èý;¸ãc5:ð3Ñ:ïrAÝÑ{1!ŠÅ6ŠYG’ùÉ¡¼O1Ò{•½ðPåZEoç)jbP|Ìwûmñ‚ØØH/Ñ¡i|kài4‚=°ßÍœ¹^cÈ‘bÀaêÉ+6cÒ_œ?¸i=æ!Xìoÿ‡àŪý¥'G€iéÝÞVŒ{ÇTá·=óW·5JGÓæª½“óo?³·>ògöޝÚ[ò`ZÅ2qÙîiÀä£Ýo'L¦G‡o¾Ü0™a:ÂŒx2!K1­û?€ø"ØéóÆ»ÐôÙw„þŽ{ËË@OA—œ9„8ƒÙÉt¢«ãè*áúº¡{KcÒ¿µi·ä›bç³$—ýbìÝ¥K±ìrr·$ÃÔþÙ0kžÁ»<÷ø*ÄÆçÃì¥áæ« F‡OþD°IΓ1#¿]¬¿†×ÄWYÎ|žå¾Ìçn‚>§!}OÆÊÿ©¦tÈÖw½ÛÁ¸ÏåЕ¸OŸøQ*‡ C¹+MQîÅ—äÑ¡µ]BFYŽüÐÔ»~më¶òI§h/N3[(V[j ×‡ký”39öøÆ-Êü,ѤüLcf¨hÂä×¶lòˆ)ãé¬_þè!I¢àõŽ[\åÍy³‚¿L|ê¯Ø|Ê$gK •ä¯1EGšiŠÇƒ­Ÿu¦°BIú Eg⨋•©ã„=¥„—:ƒá"2r/CÉ­ôÅ^ M@pk÷n¿ˆµ kräKï-¥5$õ™Ñg*U¨%‹ãðƒ— µ¸oÕÀÀ‰£¾5b{yïÛÿı7.³÷ 6«DŠJ2QAKšb}XQƒpÄ=F¨é‰Z{r˜v%=H(C¹ØœxB_üpS×ÂI}ÃSçMÓ' OÃW¢ã"H®LÓc–°‡_3´.àáТü8Ê[÷KË¡X «mÛÎÙàÒuã}{]¸ÓÀ¨ò™@!7LX¢Î4/3,öù¹¦¥`R\Ö´dÔ;ŸÔ’®J·‚€L;«6WY¶…›zSWõPP:Á—‘ÈR¾œ÷ÃŒ@Ü—ìçÚ):a*y®›ÂûK1á E¥ÚŽªL9X„/¢‡C€jˆì=LJÖúëjû‰V[ì!‰PòÞ¹…L2ÐʺhÜ+Öú‹©ó“Ùy‹qŒÏüL¦áK£®¦ƒ7Å‹$Á^ÔI/06GØÂ2zWëbeí ÏÄŸ,j5JÝOp4ã"2º›§Ê¶b3¹pãgÚcYÆ2sÞ fè+#ƽG8PŽŸKp—}^6- m°€¹¡·¢xŒÛŒ›_VŽºœ´5—Q(Ö'Cövj¸j¡àÔ£«¶ ±`J ·ë«ùBÓ›pÌ ^‘^Ó+AÉ~NBw¤^$ø^Xu ½#ÆÙÂÏ!ÇcòK$ø9˜NpÑå_ 7VdU¹V—äë&×yŸœacì!_.ÏPí£ÀWC¨Ù"$3ñåÚ R±xé5¥O!^ÂvüŒ~,ñû—Gïñ>1èÙ3ë£3§a“j_lÓWd–º ›E³$ûf¹ý šåö+šå…»p!&Ô­€«ÔËâ¿Ã\æ\)~dÿ*&ÔŸÒß± ¿™géÏñwðØSž5\jÒUÔù>÷ûN_é¾–Þ÷ÿ"éòÓQ—ßo‹›PïÈ<óÿó²äœ‡Ë{ísÃe°–±äª/%×µð.,f;Y– ¡O.Š3uÕ'—oÓw„ÐW _Õ’ÓW}¸Ð(„°!œB ÿráW ïò1ä ¯ã:e"¿ŽŸ\±ëýä4Z¨áì£0qT\§>L¼~mÄÿ«gJÓ‘Ž›xÒ` >Q¦¹F™ßÛ_ƒøîz{jo›q£âYu;ÝÞ^ª[}nã«t{åwÀKu‹0Tǘ;V·9¯î˜3óŒjS–¤G1 ص‡æîo ¸iWbƒýIíÞžúýmPáÙðß±½Âÿr7ûçþ¡ƒõ endstream endobj 103 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 105 0 obj <> stream xÚÅYQܸ ~ï¯ð[=@ìØ’,Û9ÜCš» i›‡lÑÝ>hÇÞßzìíÉfûëKŠ”ÇžÑÌ%(ÐbɦH‰Étð9HƒþÒ A®Ë¸(ƒí>øÃMðú½Ò$.“2¸¹Ò"He\fÁMõÏðÝÎ90ú9d—Ÿo‚ÏA,Ë"xD/§2ØBëXóƒ6øüB^¼”;/“*–j%^¬ÕòÙP¡Ï’±ÈN¶¯VÖÀ½$§'pàvsÁâÄTKY¬Ü„gy†f ×?xVGBe±Ä»¯ã‚ñ¼k¶èå;¸âª ›~³„ã޶f¬iTÙdYhÚÜÊ‘È %±”1Ä4?ÌxÙ;þi#DϦ{ ù_š»Á /í ª!+ÜÝozæÕßÓï57Kоqš]÷ƒÙ@ÖÏ’Bá0Ô[r3˜Þ÷ ìfdš„Oèûa?ŽÍ]Óbt×6º'…‹¶HŒOç8 ¯Ó=² ¿À¨þ|0-*IêðíHÏPÝvVÉ8£â’>áа6ÃÞ05r§HTÒí‡sS´³§!Í¥ îÛ=L#§…kJM5ø•øæà5õœ}êqr9g TÒtUMªq5$Lz|G‡;&šºî¼ûpqã«w…ó[L]çË!> wНWåî1¿†èÁB[·‘yŠ‘vQÉd,7Q¦Åœÿá8yvLøvfMaoL¬nðwÇ´?¶mSÕÖ¨0­#Ž‹‘Gñ’î¶Ð£Ytœ’ðë,ĉwä.°¾%ÛtõsË@ÅTUÍ9¿:íwè¶ä‡8›±ÈŽ_/7S·ö‘-b Þ8—ÚªÚb'ПÙ2¡ .G¬ÒU–NØ»ÄÄŒYZ•2EÉT$Þ Xbțɾžå•´‡æ…„^@ZIË$NÕüàBZ9RÁµ(8èBhÕ|ÇVJ—(¢H UCâJàWºùBÀòx3‘ΠòSy‹¸,–G¤Ô0Eƒ’$m.=ϧ´,ð ó l ô]æóƒKùÔ-+ÔÌ’ÇtÛ ¤|M³8b¤è„¨¤ù‡‡:gD.l#·9DÏœ5}úÔ¬3N®×Ò»:‰2ËmhÂ|Ή°qä{PЋGN†å\Îò8ÄBÎÆ£{ظˆ4Z'šIÞxñBnÃN$J˜7äùzíùù*jäP«<Ú´3-‡ ¤Ï—P™Ì”ÞøO‹øQNµ‡êŽÕ_Ÿ ÆŽ–tØ2ÄV·,¯j0¥·[`ÂÍTøa²Ç[„q×Z›÷ÕK¬lÒ•aßÙÈ£;ÊY4œYшq‚\ïUf2ôÆÁÉã¡Á2î…H»RzÛü»®^­À25û§¶>ßò—¢=q8ûbµ6L¬r£`Àɨ¢©GË-cYcÕ—“úg*¤kû‡h@,1¢AÁÚ-%Œ‡=b·¢˜a®'åáû¦Û¶‡Ês‚ûq…ä:[8Å÷ÓÎëBPæéoñUyч4f…™â2nø W;OŒ«ÅѵµßôjUtcýŽå” ô,ù¤òã}uþ2#uu†ÙbÅ·Ãù•°àpìüŸLò·®mXÌÕ§,0etgÈòNXѽÎO™6L¾(øR1³€¸ð@U3?x‹ðï˜l­]ð-Evi ͬ׎T;ö]åÖö´”yàýï¦m•½ r˜¢ó;l«;¥tødp­R—ò8Ò¬ò¸RYÈ{bOÈ¡\¸AN[î ²ñrrïGbv<#’¢šñw^ ùˆèð(øÀÑ3¡i{ôÖ†“Í™)ªf_w!¼=Íœ›‡p™‹‹ÝÃ"ÎÓ“&Î kl$!&-ÿÀX]Æ¿zÎ .,¯çZù?ÂÅÙoÈYãâ_½¿pý3?à͸´ÑǨBެث3jä,‹úE²\gEûÑâ„éÎÑ3á%4í#eÅÏÊ!c¾\u€·ªêÎsVm\ãlî>PPßMX¦ã·‚3?Xl^ÚÝêÅn¥w·Êy·ÇfÃzsÁÞŒˆ2Ó¹ ÙÙe¯?…G3šîëih¶Œ; ¿k&z9B`±ÛàZ2Þà =Øl.±j <ëIÙB§áÛc• 4Ï4à¸pµ‚]Ip×Nfˆëp=.[BÜ‚M뇸2)°©ðÝnwòÝdá—!nñßU£'bVÀ)Ä-çD2Ëð“Î*è®@oî½*ÇnÌuØ[\…½ÊÆC‹z)•½µ™A‰”’.—¬Z[H°Èð*OŽdK@iélý‡o¬"p0î¦ÁP™XqyjßÞÛo}øÜ¦$Í)éúöX£ž Ë/s=ë¾ÿq=‹"iS#‘úúƒ¡`®x¬Qzî=®Ox,Y}}ÒdÝ!U„í>6  DD½í¡/ ¹Ò­̃Ζ‚^<¯ƒ!byµ-¬]¬ï}ËQµòJW¸DÍÓë ,°—ý|˜|ÙdŠƒfI]å+Söwc=Ð÷,œxõÂ%ðAÊ‘!•WCÈŠcúëõü'OF\=éÌ€>Wêu·–Â"ãUl:÷yÿt Îƒ½€îxS±k6þò»ÿ]\æÚ endstream endobj 106 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 108 0 obj <> stream xÚ•UKoÔ0¾ó+|t¤&c'Ù€¸PàÀ ±–ƒ›uw-òØÆ-ÿž7Mµå`ÏxüyßLØ=,‡O°º`uÕd›†µ={·e× &ò¬É¶½cbÄ̚’m÷ßùÍQŸ¼™’TJÉåë$UJñ÷Öy=´æú«ím§'ë“¢æ¿É¨7ÚÍ“qÉí'¦ ‘j°„ ºë’ •IUáki4I8T;™•IZV¿Ñ];wÚÛáØuÉýÑÐf= ©×~²|JÎRÑd‚`¿Yÿņë!)*ôW‰š»S’nZ»Ë…2{Ô6@¶WoNÏ¢-&çIpÞœhgÂ]ìŽÖLzj1+GÛꎎÛn†;Sˆ­¦q†Ð SAÚ×Nö–œÙ‡`Ð}™ ªžÔÜt#¢>ÀªæÖÑêGZÛ±?ͨÎÞ€ö)Y(ížÆÅ>:{¾4ÞÑ‘{VÙ7P(íÝ8‘•îºóƒÓd°Bã@ Ê›[»_÷WN”Š¿¥*O›”–Ü.!U ÛcÅÌÁ§J““¶“£mpVˆ§ª›·ãCTŠPmwÜd‡,I7y³JgüzQƒ …“eª+‘6í Q ˜8 Á÷Úk@Û%ðD™ ¾=ÚpWòVÇËã7q»8@mF7÷@ž+”k ñ>îÌckNž¬B‰pƒIy°Î\ºî£3ig‡ŸIYr}Àš|EO¤}meúq®nBœý•D÷àN$“l4á£íÑhîéL÷ãÍ“Œµ † ¬à“¹Ÿm(JÖ]z«b[«U[o²*Ž”]žÑ \0‘U2š|~à—©ôϦ¤Êª:žß†&ñÆaâJàé¨õfUfeù˜¡µ¥ˆt„æbn!ù±'°eAœ‡õÌy¹Pˆ& È Ýk…4t¤»Ãm~ìIDþ cP˜Çj]‰…QaÌ¿È"Ð_Ž>ùä r° ü—ŠwƹóoY‘>çYx÷w2:þ‡Àè2¹r#³Jý%» þÓbÍ! hða˾¼ú:|å endstream endobj 109 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 112 0 obj <> endobj 113 0 obj <> endobj 114 0 obj <>/Length 5463>> stream xœíݱ’ã¸v`Îó¸«<Ùt² 7ØÇØ`ÃͶ:sèÀq‡Îú†vfWÙÏ3–W¾› €’ÈCâû‚-6‚tð7Éîéýòßÿùï!}‘ÑaÉh€¸dthÿðÙ{Oó?ÿõ{ŽGFÇu è3åÚ¯¿ýþ/ÿüO{¦6£rA7 µ£Œ9çL}ñ×ý·¿ýío{dnßš‰svbªÊè]ÐksÒÑÇ¿tÍ耗ÒûÖL³ÖýŒ>VXŒksÒ±¦½F،޷f"œ=à‡ÂHFU˜ö·¯ß¦ŸÚøålÿƒ–½Õ÷Ÿl6"¤¤Œ&GFµ"£Ÿë‘neô±ÎðCa´2£/‹pú奓ë²\±°§]=ž5w+¾0ÂÕoa<|Ü~üt’Ñw?Žg © \3ãÇ:›óq{Ü¿nÀ…³/WYáì•§Kž]FG¶>£“®ˆ¹iãòVüÝNV{¹çñ7òȳŽY¬\¿\ñÒõ£œíY¶Ì;ö3:ù™Ö?kz<£—'*|‡–ѧ+£ =—_ݽ&* ï‰]îíñŒží™¥êlÑ&O7{)yT²çr(θ"£‡Å·3:·sö­«uÀftå«å³ËèÈž–ѳerßZ¾Z\FáKßÈ#ØÝ7Už®š7¾î:úî\Ý­«äC棾f†Ì7ƒ»óŸ;ãr´­Ï£ïOSLËèø^u=»H¼j¶ÂÕÙò›ÄÕë2:×ËÞÈS2ºþ[f9g+¿{%÷Œr=,nG†Å Íݺº;É…€«üÍŠ\'5;uùì5ßË—;eôɼ<£ËA¶Ü³.PÆÃ¹*©Y]õoíÁ7òÜŸ6}·¨ö´e¹ÛѺëèòFrN*?ÁÙÀž•Ñ5-+ÏÞ”ÑÓ/eô™l—ѹÕX³–Ïèò€ËoaH=º}õ9Ö¯¥×Xñ<º&ûj®åË—Oÿ½Ž¦ï.? ¡\)-£ã{IFŸ‹òÚ °Çí»/-»êžu”#`ÚU9‡âsÉ'¾‘Þ2zÈg_®ñu£ò!ù NöêßNžº|ö\ÔÞ½k‘ÑgâßÎÕ×÷KkÚk„ƒÿÒÏ¿3$GFÏÉè RRF“#£ƒ:Ö´×RRF“#£ƒ:Ö´×RRF“SÊè£ÿLŽî”ðÿÃ|ÿþ=ùÍòNFŸ,&*ÜÐÈh€Éh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . W”Œ~ûúmÜ.œvt©RÅÉÆBdô¬ô­bR™l/bFC@×*U«l,zFÏ@® Æu2L‰ÌÚŒ{¬%žh™Ñc™Më-Y±³AqRm£Œ¾œf¹ó—ŸºnÌÊwXÔ÷Jçäš™î7’gç4þøãǯ*KtÈÄîr±$«Qqöé‘Ý.£/£œí{È=žþ qøûK2µ§m–^F[?TŽåýýýY]Y¢åŒžýôûn +ÎÓ{°D7ÍèÜ!…Œž¡pÕ\*—Ö³ú)_ äÂ:™Ñƒâì̃%.£—O3¦mšöX =Ø £s× 5=dJZqöã =|~¼s¼»?3ìR¨ŒR¿é¿¼MgON’ѰÎ6Ï:á’¹s2š®EÎh—Ì 2šÎEÎhd4“Ñ'£éšŒ&8M×d4ÁÉhº&£ NFÓ5Mp2š®Éh‚“ÑtMFœŒ¦k2šàd4]“Ñ'£éšŒ&8M×d4ÁÉhº&£ NFÓ5Mp2š®Éh‚“ÑtMFœŒ¦k2šàd4]“Ñ'£éšŒ&8M×d4ÁÉhº&£ î„}i|·åÄÕ.­D©wÎŒ¾Œ©Ðà2ÜÖpV{e´¥Òi3úãã#×àÒOno_¿Û×ñ_öÞG·cF+Qjô•Ñ_¾|ùñãGnÌjýúeå°N*ZF+Qf:ÊèKõ_þ[¿ ;—,€ƒ •ÑJ”¥3gôõ’äÿGógõkÀô¥qûz×™ÛN¾D4ûf´宓gôðgÅO«È?ìkZÓe°ü2w,ÑìžÑƒ¥èü=/Xžx‘’»rYÁEÈè‘eéÌ=|¾½{8k¹,ýe·…NØÒ±2zP¢ý‘ÑtípMod4]“Ñ'£éšŒ&8M×d4ÁÉè5 ¿¦êç*ÇrÖŒV¢§!£Ÿ©ü©tÖŒÎQ¢‡#£ŸÉ8­Dƒ;gFÿòóOå6å ܸ¶Éí>ÿÎéÿÛ4ÖC({e´¥Ò 3úÒyM³úÐô︆ϋ¤°¨ˆ`—ŒV¢Ô;aF¯¶,îiYjþmaÏKß­Žøwï”hWdôMa$áµ.€Áˆç4­DÏJF’¼¦hº‘Ìíq#Ó±2zP¢ý‘ÑŸäîûš~ 3;|ÖXõ‡rŽŒ”èyÉèçpéqP‡ËèÕ”èAÉèõÞR%’c9wF+ÑÑtíÜÍ Èhº&£ NFÓ5Mp2š®Éh‚“ÑtMFœŒ¦k2šàd4]“Ñ'£éšŒ&8M×d4ÁÉhº&£ NFÓ5Mp2š®Éh‚“ÑtMFœŒ¦k2šàd4]“Ñ'£éšŒ&8M×d4ÁÉhº&£ NFÓ5Mp2š®Éh‚“ÑtMFœŒ¦k2šàdô¦Þ¾~»nŒ“sÙS˜¨ë«å6w;)4«ý±e4[Š\¢2š—‹¼Öõ£DO&r‰#£¿|ù2nÿøñ£þ¼3—~ʇßmðÄ£žåzö}ÇPy¬ëG‰>ݾe¹Dѳí‘O1wì+úÜæðia×aä°®Ÿ®Jt›Sì[Æ‘Kôxýˆ€ àèÅ]cºÞ>ÿ¡÷«±ÒΑÑX¢Ûœ"NFG+Ñgôxw9~´×íq#Ù&·<¶pà´çé0Æ=³£jú)6÷ÒtÏòÝE3»Hy[üÿ8Æí“et´ÕêØÛì¨Ë8r‰5£sÕ6TT䲟Ù!ɇL Už.×OÍá5=ç&*‚åd)£R¢C¦ ›Îuô2Ž\¢'Ïèé!ÉkåþÊ2]Ž$¹ºrH»f´¹~rAòa_ò¯w˜ÑÓC¶,Ñš~Æý¹A&ßZÍ;Êõ“›ÌW‹\¢'Ïèò%IîØ'ftaOá*£©çƒftR‡½W‰6eôéË8r‰/£+‹xÈWRP(îú—r%òX×ÏÑKôËâévSÏç+ãÈ%z€Œ÷}³åºÏµ™u¸¬§äC~,ªì§ò¤¹ž“íC‰¼Öõsô-|3Xö\y®C—qä=FFG'ãŒd&òX×};ãò%]+ˆ0†œÈ `]?JôEögä•ѼÜåsÿkõÅ—Ñl/r‰Êh^îû÷ïMíe4‹\¢A3ú—Ÿªïœó‰ŸÑJ´s]gtåÛæÜ"g´eتD#f4ÔÛ%£¡žŒ¦k2šàd4]“Ñ'£éšŒ&8M×d4ÁÉhº&£ NFÓ5Mp2š®Éh‚“ÑtMFœŒ¦k2šàd4]“Ñ'£éšŒ&8M×d4ÁÉhº&£ NFÓ5Mp2š®Éh‚“ÑtMFœŒ¦k2šàd4]“Ñ'£éšŒ&8M×d4ÁÉhº&£ NFÓ5Mp2š®Éh‚“ÑtMFœŒ¦k2šà“ÑkFž•ÑO , £/í׌ê<žÑJ”—ŠžÑ¬ £â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£⊒Ño_¿Û×ó^öÐÚù³ºzâY¶ph!2z–V×/+#l÷¤ £§‹˜Ñ…•ÇnIF¯=£§/MÓp˜<™m/_šv5m?¤ž±ÌöɥиpF€¥2úršåÎ_~þéºÑ”ѳëÖäel®åðùawòÀìËÜé’g¹ÛòŒÉÉNã?þX}Q»]F_F9Û9ö°â::wq=*¤y¹óܹ¦A_8K¹ÿä/“Y7‹Àñ¼¿¿&£s‡´fôÏÐd·ÏÍèòYÊýΜR9ýj—ѳÇÇÉǾÃ"õꟊö,‡Ôô¬CF3gÈè¡øûÑÉt>ÿ.÷3ûOŸ ?3Ì]§' x·ÿéKÉ3§t’ŒÞ«Zàdôz.iW“ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 ®f´ÿ/ÉÌ÷ïß“ŸÐȌ͘±Vf¬ÕÝ3£]q ŸÐÈŒM™±Vf¬UÍŒMËè3³~Z™±Vf¬•ŒV 7ÖO+3ÖÊŒµ’ѪáÆúieÆZ™±V2Z5ÜX?­ÌX+3ÖJF«†ë§•keÆZÉhÕpcý´2c­ÌX+­n¬ŸVf¬•k%£UÃõÓÊŒµ2c­d´j¸±~Z™±Vf¬•Œ.uþöõÛ¸]á —žgÎö\¿\6ËþO_?㎣­ùÝ–»LÑÌê{ni=òf7žÆÇkl›O¶pꀫrÚ¸£ŒN†fMŸë>ª¦Ó"£§ƒ\1àÊŒ^}øS¬›±Õ¥•óHjl<'Èèu¯®&£k3ºžŒ¾zpýdôãúÉèò•ì«…]•ÓÆ2z~ÿ>ÍtÏu{¹svÔtÿðùžwZ‹ÉSÌ6–§Hv¾l3µAFçÞÑr´Ë)J>ÚxŠfž›ÑË"¿LÖRòÍ.{5OÏèävÓ<Ô>쪜6î=£—±ü–Uò¨B©-›%OQ¾zÊ´ðî6{]˜´àS4óÄŒ. f¶Q?W… Ük©±\ß=ûÝË…ÊÁ‡]•ÓÆ2úÛôËÊ…ñx2.9¶ÂQÓ6³w÷ºŸ¹W¦ÌrOaÌ»LÑL´Œž ~z`î}m¾;þåþäÝxŠfžûûÑ…"™ÕÕr̹ÁG›Æ 2zyöäJ\1ø°«rÚ¸¯Œ>šKÂ!Ì¿«m„“î2c»ÌO¥»c RcIOìWå´±Œ>ŒÜzÁŽëgÅh#œTFÓ-£7.¼­Êic}fÑÖO|f¬•k%£UÃõÓÊŒµ2c­d´j¸±~Z™±Vf¬•ŒV 7ÖO+3ÖÊŒµ’ѪáÆúieÆZ™±V2Z5ÜX?­ÌX+3ÖJF«†ë§•keÆZÉhÕpcý´2c­ÌX+­n¬ŸVf¬•k%£ÿòþþ^ßùéÕ¬36eÆZ™±V]gô¯¿ý^ßs'ÊÕ`Æ–ÌX+3֪ߌ8  —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â:LF¯Àñ £/í׌à¢g4+Èh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFÄ%£â’ÑqÉh€¸d4@\2 . —ŒˆKFĵ>£ßßß_90þÏšŒþõ·ß_9$nš3€}Éh€¸d4@\ÿ ~N…A endstream endobj 115 0 obj <> endobj 116 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡©¹ž±%XÜÐÈÄ@ÏÌDÁÔÄLÏÂLÁÐÐÀXÏÔ¢ÜBÁ%Ÿ+) endstream endobj 118 0 obj <> stream xÚuWÉŽÛF½ç+xl&‡û’›ãd#s‹shQ-©.r75cùëS5¤FÆÓ[±úu-¯JÁ— bøK‚* ª²‰ê&hûà§§àá1 ’8jâ&xÚI$YÔÁÓîoõá¨O“q›0Ë2•ÿ¸ ó>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 121 0 obj <> stream xڽˎã¸ñž¯ð-2ÐÖPõšÛf0“d± ‘K:µE·•‘¥^=¦g÷ëS/J”åÌÁX4Ð&«ŠÅb±žÔî×]´Sðí2½ËÒ"Ì‹Ýñ²ûËãîÝ'½‹TX¨b÷xÚEù.ŠÃ"Ù=Vÿ >œË×ÑöûCÇy¿?c‚Í4°n_n‚Ñ÷: Îmýëd‡ýÞ…ÀN“(!ØA€{kÂôöRÖ-3J“ íeàáS0ž»Áâ$ ÞêñÌàñ, áR6FWõ0–íÑ>í[ö–ÿëêÖV |F!ñ JµÝþ ó ²ïž{XO§`‚î$œdßÞÚ:…Ú@=«G‹r,*‚ƶ/HL6#W»Á`GYÞ]Qº1ú™ÄbXú†ÿ¬m“- æ“9é1ÄËRÁ£#p‹A,¦’›CÉ-èEÊÏÆEFF){òb+ÃþvMEJ„ấ~¨»và]èþ#º&ÉòµØKx7ït,_Àq¬Å„æør²pa. u¡$ mŒHá|`‡*"<0èVÇaÊõ £0Ú’T@ØX¹K‹3ü‚œÃ¬³U]ÂŒý²ï, Ó˜øþ³÷ » 'à ›Îgžâ†à¨nC€ü²Ò’Ì>pJ-™í\hc×3…c€—ÃP¿H–6’ó ç¥$X¹cJ¡(J8ãxö—ÒYø¶y3 êÀÍ4T0'×”7Ò©çã<ËÀsvœJHñKÂCÆœðÆ“‘œ¾q€é÷òrÂ]TÆÊªßúÐUU(=çG%’Æ* †òb4Ô—º GRbþRqp±cH”¥pYŒU9…ÇŽÉ (§¦íÕF øX—Íf/¬E6²_JØ÷+éDRF€²ü[‰ÓˆM~GG°uÀrÕ©ª… ­W3×88ŽS)ã¹~Ž\î;$1çµK㈳RJYéVñ‡ñ›ò•qRÀÀ»LF™†s¢`FÝ:ÎHZò—D&^W¼FN¸ðŽ©²f© §®¿ÐM kT6\Ó½X©¢ æ»ðë">wåy¦‚Ŭ Ì%x0nVdÆy–¹Â`|$ \Y?Q;–‹{§œí¸6¹I˜oVª‰šÍ#›Íc<*/‰ª”çk+IP~þõJºªD\µ ·è†I&bp>ÕºÌÜyÒ)ÀO¸ƒ½uD.ÛMp©‡AºW·4Å¡¦®O- = ÓóØCÔÝ2ƒƒµÒ’ hæfra/«P€ªì«m‰TÙ/õ|÷Êõ3*ZŸraÑêÂhÑú’R¸¤¿uË£€Dj4ý(õ6X^l0XçbƉáDß|ˆáÃgä{5ªóºf'$eˆqÅLÅóYGYvYk¾l3\ŠWjÕóŒ_ɲÅFD•r›—¯`N¶ ·‡xäg°ÏKéà2è©lIù7ãbl6_€M¿öµ„?@€…OÍèˆ({•ÿN³fžÂ}{ð Ë3)N²ln_Q€—ŽaÓ+SQP1¶9‹‹~QYžš$Ðê%ÊŸkPpÏ5‡JD¯LùD!¿¦.¾”‹·H‚ꊟ_{p¸88Œ;¾ç ž©0É¡wÒ¡âçã×Wh"¶ C½ ãehäaV…iîŸ÷¯`¥¸XC¥¤™J¼fÊäaæ^wßßh¶b‚ÑÔ(‘ÉÓ›|bBÿ•Ÿä›|²”'»œßá¼d–òñaý¡š8§®ú‹UþŠ]FfEOÑ9~7ÖøB®o é$ä$ ‹mn‰±<ÕŽ· ( S-îC3óØ«ê°Qž /œ¸R ÇܤÃoÓÜ“vÑ•m«¾{éKþ²&PL5Þ²Ìë t é˥僟Kþ™¤Ü«ëà )(Ôþ]ãK ËFuÚT6á¶)ø‰ÛÔzci tÂ]$üòg‘»I&ãÆ §c5Y) PlZàðGy(<<7T6îMÙÿ°"ßCæÅëÝéIqpºÚž?#n"À¶îÔÐl¬ü*¾¾ƒ£¶Ü0bLßJR|-Cêªkÿ<2á0!ÆTxBÂo—Tá{æ@©«}®«áJ^Œ\/…€Ù¨¶o§‚ØÚäSëe°“ç{ûø¸ûןþÂãð endstream endobj 122 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 124 0 obj <> stream xÚ­ZYÛF~ß_Á} Œ:ì‹d{±‰a;ÎAOà; ,Gꦨ1IÍñï·ª«yI-Ídöů«ëê¯(G_#%ðG™ˆ²Ô°ÜD«môãeôý[ñ„™ÄD—7Ï#.™ÑÑåúßñëMq×Ùf±”RÆêÕb©”Š_WûËúÇUÜÙÕBdñ¦.¿îm»øÏåÏ‘œ\â@xêÆ¾ËB'†ã>K¿f©@á*Æ™X,u*â€^YÀÏtü¡¬¿,`¬¸u3x*-yÆRéß×ð×#÷pZy8~pžÆÝƯ\—mWÔ+ß»^,EÛÏú€¬­ `ÚÑ@ÙÙmëeÓÙ„I˜^-á Ks?]Ôëè¬x ð lIîá8Û².·(å~K»zUå Àš “ ?É8Ùÿ®(›‡²E•ú@`e’{…ÀB:¿[´ÚÕ8ßem×~¶LH–ñ3ªV¢žÓÌÏèF³¬`àÉ&‰¯«ò‹3%I¶²$l³+½¬ÕÌYT¯g¹ ‰4ay6Uœâ$‹[ïtØ&M8j†CýzGÏ›}k¨3Q¸[cQ… ÄêüjoYT«}Ut´œÑ¹.¶œ ¨‰èÉTèmÑ5å#ºóx~¡Ð¶5së¹bF“$,ËÆèJ’>€¨~­,.&áäf0sï4Ý´%¸ÄRC´ZB> kÊí]e·Þ Eç–âxÑëÛ3Û ÞT§¬¥çuÑZr˜¥?Ãxn·&1'4>~xÿË¿°‰qq»kÊn³¥™«¸µ–f>–×í®¾ qn2yµ`¤áO`<ëNî@I•GPO¥­Ö~jØÙ>«ŽÆÚb°Ñì|ÜÄm÷UGm·¥Húx»wñXã_TbQÑ*Rßræ8¾)mS4”ÆË­Îg¾àà~³ÒoFÙd…»lè•›Â{ÌöQ:÷³]ƒ¾˜äñÖBûii¯ž®JorœÊ@ÓÞ±)<‡¶h¨íâ žäÕµûu_6äBÊ[\ jÙÞ‹ŒÄPøÀâ¯ûbÝ€—­Žå¼Ù5(‚ß§5+òl40y‚LâŸ,ÚzfÔ;b뱦vv;55†pÇΚDÜôt'Ð^Ñ8KCóÖÖ¾eïÀ(±¿.º‚Z­uz“Òpìäsbb7£L™R¦\^ÐÔqe;»ôï¢ýÝDáõ†ÑG÷jHŽ_”¥ŸõÞRͅϪXá¦_°'(%À¨·~.bâ.s¦ÕÀ0$1Œ×^Ú¿„cÀÅ>ÄÞ‡¹©ÍŒeãS®Yö—*ÌXœb2$ÇϲŒg.Òd¼)Ci>Âc&@±‡Ól‹Ç‘d ”`&â Xe:µ4ÒŽ¥Ôù”eè9ËÐ'Y†Y†ÎX†>Å2¤ÁËë,Ëàϲ e^Ì24dËüIJ/÷p‡ÁØ<ë<À/² Ešè­öá°#¢àBe¢3èQp7_;dìL‰."¢à"mc瀴àä๨Su?Ü/ 5º4@qö‡Yü ½Ð2#80»Ì”®39+¢…i>"ÌN <ïb©9ïbb¤ºO'œÔLÐ]iãeXÔ4„ Ÿ#½Wšq‚ß{щÈC𑇾ty8æ÷‚egsRž=w‚¿4îBõ¦Ð†iqè—šüòÓÂH ·›…„Ôüçû´Èý ŽÔ·XsûñÉ׎ö¦rváÙ™Ku“’k(Êv×­mî§"h©€¤kK3zÜ–÷xóõ'êßÏ7§ÖI à@°£¿A¬ÌÂiÜîæÄ2%²Ùù‘Õ¢侀u¡õDçù!%H:WDaÏm-9œMgs žzDÒ¡§~x-’ûúôÖ‚ü©ñ[T÷®¡÷€(ãUëâXþÍ1‰OôcSŒ¼FÖû» èVçª"äÌw¥;¿ôAƒä…D—ÜDMÏ'4ÄnßRÑ4^G  ”ª~-ØNއ4ªWâ0┸kŸNQ̉bò~-<ÿ::lY¯Ëûr½w´=E®{‡ #‚4ç5iêøÙ¾£êºÓh‡î‰hOõxF4†V<þŒŽ…D|GN ½#„UyóD#óc´„¶oûèš‚ò¬û¯¼|žsíƒûݧ7ïßýtˆO•Œßœ¾#°«Þ€GJ½ZàhF$õÔ¾<˜0 òÍŸÛè5é£)·cq3\*‡r@u5\P-¸"g¸¥ÜÏS‚D㺉ö †R•eô}Î¥ ¸µ} ¢¤LF‚³¿€úωg‰ƒÕñ¥óã=UªE+¹žty‹È_U\K€šèÌÆe ÷òÚ®/NU`FöÜRÅ¿ºX4-}@àÑMc+ÿ™Wx²9¿9¸â˜øÏÝ="õÓÿôÓjúþäõ¾fJ s¥ÌÀ…Ó)HßXJ— (¦ÒhXñÅ’§Y‹Ó'Óa©ƒe`iüŠ0_Íz‡Éq#™ ʸQÐ œ[ŽÝ …4}¶ÒÈÏV[ÿFË<´©™ÔÏ[æX™!,âdÚ2‡&™Zf²ÑÄ2XŒù+-CŠvÀEo_qÞ¾f¼‘ÊP‰¥Kò¸/ãô1· z‰Ð3óˆwÎð;û¨Ñ7—Ñ׈I“G×pð·7À²‡~}Œ~£ßœÀð†dÓ7“· æ„þ5  ¼@«ãš_úKƒ^)føÛ’?AÈþ`V‹2=w"p"9Ù„'‘æÇYJ–f(§1nÍX¬V–XÓˆo‘\’rà³Ò«ù6i5ƒ¸û¦ƒK¢ÀNΛ–î'ÃSç%2°‘:¬Ð†WI’¹H¹ÃÑJ0î#2x}˜øÏìé_ƒ„£äDƶ¤|?¸æ€}ä›3l•’o¦ð4^t)*8¸èÿèš4™HA$·æï€K‡tɦJÿÜQ¾@éú¥KHí°É¨t)(ÙWúðÚ¨ôÏÇJ7 :Ö¨ôû¬Òe’`d¼LéS|)=ßèü8Ñ-%Pj(1–™À”.°wîÛp*°$í¨Õ×Rr,0eÊ={†ÑÙ4°¾¡š®¥#íÕ©qjÆ:q‚!|}Dp»j¿­û—‡2 K'ÍüÆâLòø}¨[ú"OÉ®mËk÷j_Çó] ŒÅ¡ Üðþ¦a’Ê ã[sî‡xô¨w-ñ?”@ÕŸhd±¯×Pö  ý·íØ#Þìë2F…õûs•¾„Âô7>QH%üñÄôx2p>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 128 0 obj <> endobj 129 0 obj <> endobj 130 0 obj <>/Length 6170>> stream xœíݱ²£H{`Îõxª¼™7là ö26Øp³­“9tàËpàÐÙü¡ÙUöõŒU«ó³ènºÁ^!¤#½ýïÿg@dýGëWšöVß²eØ,ˆ‘šÑ‚€ÞÖšnô¹öðA¡·$ Gàð¿žÇä‚£zØÕú ™-÷Âß…~ó~yý¹I@Ï>[ © \3ýÃ:šó~¹_¿lÀ…½O²ÂÞ+w—Ü»€Žla@'·ZqÃÆå W–ûl'‹‡=]³þެ¹Ä1Ê”çÜô|(Gk¦-sÛŽ†}Æ€N>¦õ—˜ÖôtG…§g}IºÐsù¦ÞìÙPaxt¹·õ=Z3ŠÔÑ›ÜÝè¦äVɞˉPØã‚€î&Ïtnåèy«uÀ+ºòÖòÞtdÛôèî*NÙ’]Žÿܶɞݢ€½`,ÄÐt¯»#‹Ï §¯‹“#ÝTó‚ ÷¹=öÊ@—ϻʳøšÐÜ' sy- )[{ ºp’Us6Wsâ9{&ØÿwÍËÕòyâ4_zGÖtn`³wª<]5w|Ùôì\ÍÖUrÃ.óÚ¢¾fºÌ3Áìüçö8më5èÙâiÊhßKΠG§‡O­¹V8/›>C<½. s=¼èŽlÐõÏ—å­|êJ®é庛¼é&/efëjv’ éVù9Š\'5Ûuyï5OäÓ•úb^Ðå›®Y–&ýækÎGj­ú»¶òŽlû&aÓSEͰ‡-ËÝö–A—’sRù޶U@×´¬Ü{S@ÿ+ ¯d§€ÎŠ5Òú€.¸|ºÔåÚWß‘s}ü¼Æ‚kÐ5ÁWs_>oØüSMO-므w“D®?‰ÐñmÐÝçŠ|6(‡ýòìMÓn»ºKåãØU9š»âµÈ ïÈݺË_®ñs¡òÅAòìÕŸƒN÷\Îξ^ÐWâ/ ?©/î—:×´×›þ–Ï_’# ?Ð/6 "D¤€&G@Gt®i¯6 "D¤€&G@Gt®i¯6 "D¤€&'ÐgÿE’³»d@üEˆàëׯÉgÊR@_,#*¼”ÐGÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ¨ýå‡ûåÜNáX*Uœììø€սÀ˜T&û ÐгJÕ*; Ðý¥gƒþ éWBFmú5$64 è¾Ì†õ–¬ØÑB§8©¶G@?ö1]ùËÏ?=FµÛMŠ»KEsò€®é’{ç2þøãõ§ •%Úe2wz¤$«QqÞÓšÝ) C­ì{È]ƒ¾sØýýT%ÙÃ6Ó£­*çòþþ¾U@W–h9 GowϦ¹â¼¼•%º_@ç6)ôh…óårŸ\U¹´¶ê§|Kêd@wŠófV–h¬€ž^ĶiZã0¸ƒ:w¢PÐ]¦¤ç}œ> »ÏWŸ“/g€Î›„·* »Ô'ú§/;Åy'WhXfŸKk8Y¾9Í}Eh'Ëtš;‹ÐÐ hîL@œ€æ¾4Á hîK@œ€æ¾4Á hîK@œ€æ¾4Á hîK@œ€æ¾4Á hîK@œ€æ¾ô>Êß(Òú­¿•ßOÒú[Ò1¿öD@s_z˺¾ýìšòãÌ垀æ¾ônr¿9° tÓæš³л© èÂoæöýô_¥=ý±ÝB"çºn[þuÓ/©›Þ!Ù4÷% 7´à—s»ÏÑ™üy£Ö_žî¢f/É®fw·É¯÷–+G@s_zCå_ÎíR±›û5™îó™rÓo× ×Oÿ», ËO'ÝŠ_ïýMXÍ} è Õü4]9 Ë¿ V¹&ÙÛæð³“& ¹/½¡šI(\Ó%Žc:w½€€†,½¡•Ý5¾I8ê¤Ð[7ysoºröMÂéîº-Þ$Ð% 7´Ã$¬?cö¡: YzC/š„ä9ïšÞôÓ1]óyÇO‡ôUKÔ³Ôw èÇ€ cmWuT@_²Dô7 èoß¾å<úÉ ùWF¡^±­úz%* Ѓ½½}ÿþ=WýÉÏåTVœƒ„&ç èà%* ÐÍÛÛãßú€.¬œÐ'uê€.¬œÐ1Ý7 ŸçËCù3»¥=ûAÈérò&¢¹L@G(Q½À­ºû3‘‡éÜmTý¹¿>ªù'â¸p@ï_¢z»t¯?›Þðô$wÎÒÐÁ]8 »ÝK4H@¯ùb¹W›ÎÏ}ºû|e£o°Uõw©#aö;åÚÝí[¢qºü)Æ£$?=yë€îþþÉaƒo‘O/ê¹Äq §èh%*  Ó{”äÃz÷€žZö!ÓdÝw“ï[vícªL+ »Ø%* ËôGãþGrÎøgZ¼ÂQ}ÉÐeú£óšf‡—ÐW-ÑÂ$¬ÿ£Â5ôé0ö èä]É›4´ñmvÊMBòÒùtóBòÖ§s·o@þØb˜ÑÓ›4´Ðª èœ ô“€†6zCMü0I7÷·Ž5ô( G› hÎJ@oh}@Ï~ð\gÐý²kа„€Þ€v ¶$ 7$ 4lI@o¨éS³ú˜k, ›hNL@o¨õsÐ…hÎý­c´€î&vÎ}Ëqç4´Ð 2 þ’p´¹€æ¬ô†‚L‚€m. 9+½¡ “  G› hÎJ@o(È$èÑæš³Ð 2 5_x ô†‚LBå—E@C-½!“°€€†,½!“°€€†,½!“°€€†,½!“°€€†,½!“°€€†,½!“°€€†,½!“°€€†,½!“°€€†,½!“°€€nüÖÚi›šŸ(njÉQNБKT@/  k%÷a¶Y}‡ zàÕÎÐÁKT@/  kU¥€¾’SôÊf…–z7ºV¡XŸ •¿ÊÓ/ZŽ–»üËU^ê¤DÏÐ1ï¹»éüèZ³g Ú.ÔzrMrýt“íïE×èQƒ£Jô¤ýȯ}öõHI_7Zõ”˜ìmöô¤üÀe®²‡ËÓÓ“nò™Ãôþ è«–èyzŸo÷÷…ý ¨Ð ù<Öeª?WÓõÕ¿ò7äy©£ú’%* Ëô_*ÌxršºÌ[äËjºËœÈ¸ÄÍ}½Ðeú¯%güíííû÷ï¹êï22}õ7j9­ûi·…NØÓ¹º‹]¢¹Iˆ|)ïÕý̜粀þk@ÓÌÔãßr@s7§ èÈ }`(—÷þº€~N÷gæ<ô_zÌøð¹k8Y'­~^A@oH@O9ƒNèÐÝŸ‰³€{u@ÿòóOå6å¿H.<ÛäÖwŸ?[Ú¥Þ (¿YÁ!Ž èK–hÓç ¿I8Šš6Þ$LŒí€~t^Ó¬¾úsÏÉMoPÔÔ û;$ ¯Z¢k&ó¨ãÂ_&Dþ6»ä¿ÃfåêŸ]óÒ»@«Cz±à%* Ëô*…êO^¶[pýKFGs™€ŽP¢¾‹£L@¯5{köõcnK1+ »Ø%* ËôZ¹—{MïÀŒ65–Ρ\# »%zÒ€ž}ÃvCú΋Oêt½Ø%¦*ß°Ý€ÞIòƒAœËµzç9 Á hȺv@ïÌ$,  !K@oÈ$,  !K@oÈ$,  !K@oÈ$,  !K@oÈ$,  !K@oÈ$,  !K@oè1 Gá”4¤ è íÿG—! !A@œ€æ¾4Á hîK@œ€æ¾4Á hîK@œ€æ¾4Á hîK@œ€æ¾4Á hîK@œ€æ¾4Á hîK@œ€æ¾4Á hîK@œ€æ¾4Á èý|ùáÇçB?35¹Yêo-·™í¤Ð¬rÃÏB@(ÑhôN†Õóв[p6¹d­O è!%€ÞÉâzÚ°ú»ÏgFÃÿ.ÛéÙ è!%€ÞI²žúWˆÏÿöËÏ–£×£—Ÿ}Ëa'£öÃ=–«¿Ðù´ÛaËSÐCJ4 ½ŸÜ¾i½×ç^÷%O;In•Û¤rHÖ/›­=è%€>@eáæNOºÔiÈÊ꯲ú/@@ç(Ñ ôTÿìDeõ—f«þ—ö‡ B@ï$ùÊëÕßeÞ]©¬~¯ìçXJ4 ½Ÿ/ë.ð•_?&F{Ï­cµÛ`íöôáQãŒ\ýËúQ¢›S¢³{œÞ" GÙš‡0·í+úÜÐú]ô=rD®þeý(ÑÍw¡Dg÷8½)b@¯¡ú¯þ/Ÿ¿µý©/³kôJT‰N7?e@÷/*ûÇõ¹Ü/$ÛäÖ÷Û6ö<Æ´°†¯×F[z®ÙWùån®™ÎÀžF§'_&¿¬Ñ/_, •hù¦N‰Öm~¾€Î•ZWQŽÓ~F›$7ì2TÞ]7©éÂf·ª¹×…žs“ùjÓ×¹oû½R@+Q%Úo" ÓÕ?Ü$yö1]_Y£Ó‘TVöôðË 2y×jîQ®ŸÜd¾Zò_òÛ„oÐÃM”hn2_-r‰^9 Ë'#¹mw®þšÂ9Haï¹~r“ùj‘ßYÖU¢:]ý•ÜåËèÕÕÿ6¹\ØÔseõ×ß”›“ÝD®þeý(Q%* ¿ý5ŽÔ‡LßRo\t“:ȵu8-¦ä†]¾ú»IÝçê¯òŽ$ïT¹q®çdûÝD®þeý(Q%* ¿Í7 àzZLõoÒ}%šÛãô&]å,ÀQãŒ\ýËúQ¢/¢D {œÞ$ ÙÀãqÿ·êo¸Ðì/r‰ h^ëëׯMí4;‹\¢ú—Ÿªïœë‰ÐJôæîЕߜ͵Eh%J·W‰† h¨wH@C=Í} h‚ÐÜ—€&8Í} h‚ÐÜ—€&8Í} h‚ÐÜ—€&8Í} h‚ÐÜ—€&8Í} h‚ÐÜ—€&8Í} h‚ÐÜ—€&8Í} h‚ÐÜ—€&8Í} h‚ÐÜ—€&8Í} h‚ÐÜ—€&8Í} h‚ÐÜ—€&8Í} h‚ÐÜ—€&8Í} h‚ÐÜ—€&8Í} h‚;G@/ÌÚ* 7 LEèGûeƒƒëZ‰òR¡€4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P!úË?öËÏ>Öäö¾ ó­ºÚp/ûŒ 8µãzUÏÿVæ×á1×@@› Ð…••ÛîI@¯: ‡7 £°\ -Oov5lߥ.­ŒÖ6Éí¥Ð¸°G€©=ú±éÊ_~þé¹ÐУ3Öä l®e÷ùw2ýGÿÍí.¹—Ùþ“{LNpüñÇâ3Úú1ÄÑʾ‡gйÓê^!ÊËçö5LùÂ^Êý'÷ø˜ÌºYÎçýýýÛ¤5 »|€&»Ý6 Ë{)÷_Ø#pIåô«Ù »âç “ÑÜ}~Û-÷&áì盄¹3ôäû~³ýoJ+ôáœÏ¯  r2 ¼š€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA]- ýÂÈÈׯ_“OÏŒ˜±Vf¬ÕìŒõ.Ðε{…‡§gƆÌX+3ÖªfƆôe9xZ™±Vf¬•€V <­ÌX+3ÖJ@+…žVf¬•k% •ÂO+3ÖÊŒµÐJჃ§•keÆZ h¥ðÁÁÓÊŒµ2c­´RøààieÆZ™±VZ)|pð´2c­ÌX+­>8xZ™±Vf¬•€Î¶üòÃýrnx˽Þ}º|ûjaÊaã»ôèe{_1Ã5ÏåéÊÑVÃõÝç—ºÃBLîb´0ÝE²ói›¡:w¦£NQò¢ÐÎS4²m@O‹¤ÿo²–’wvÚC¨iÜ< “ËMóP?ø°Gå°ñ­zZ ÓGhú8%·*ÔÙ´Yråó¦ÜN ÷n·kÐ…I >E#ta0£…ú¹*TàQÓ¸¦ÆrY<»÷Ùs…ÊÁ‡=*‡ïÐÃÿVëÓ§pɱ¶¶Ý»×½Ã^1Ó5…12E#Ñz4øá†¹ûµó4nÐÉéÊÍÃÊÁ‡=*‡ïÐÓà€.lÞt13 sc>dŠF¢t®8ãLãÊ€þwvºÊó°`ðaÊaã›tk²te±2 kvQ^3ºWŠcM@G˜¢‘ ?űm@2ëØi\óÁÄ\ìÎ.o5ø°Gå°ñ]º›¼<­,”~rê“[%wÑU—B¹«Âšälïy zvüÓõÉãsç)ÙösÐ…"ÕÕt̹ÁG›Æzº÷䑸`ðaÊaãôeÔœ vaþÊ«r´vzÈŒ2?•fǤƒvžØ Êac}¹s󂞣°SÝ5Nc´€Þ¹ð^tT èËŠvðÄgÆZ™±VZ)|pð´2c­ÌX+­>8xZ™±Vf¬•€V <­ÌX+3ÖJ@+…žVf¬•k% •ÂO+3ÖÊŒµÐJჃ§•keÆZ h¥ðÁÁÓÊŒµ2c­´RøààieÆZ™±Vwè÷÷÷úÎ/¯æà1cCf¬•ku߀þõ·ßë{¾‰r)˜±)3ÖÊŒµºi@\†€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA# — àì¢ô£ý²Á\@è€` ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ 4@P ( ”€J@% ‚ÐA h€ ôûûû‹@×пþöû‹‡À‡¶€àX ( ”€êÿZûÉ¢ endstream endobj 131 0 obj <> endobj 132 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡©™¹ž¡XÜÐÈÈ6W05±Ð3±4V044ê3…¨·PpÉç B;Ó7 endstream endobj 133 0 obj <> stream xÚ½XÝÛ6 ß_áGhtÖ‡-{]¶®E7 +ŠºËt‰îέc§þèõö×%ǹ]‹E€H–(Šü‘")%ïždð㉉.*VVÉvŸüt™\< ÏX•UÉåuÂË„KVåÉåîïôé­9Œ¶_­¥”©ú~µVJ¥O›i€Áº½Áq•Žv»:½mëw“Vÿ\þš(Á°Ë®ÝØÚ®ì-ÜLwMœÇ[KµíMOìê­ihôtC 7W̱|v™ÕZó¬LÖEV2.Q³‹çû*ù¹K^ë(«T²–eɤäò¶Vk!uzW7 õì‡tÊ´, jþ\•2µõÍ-J9âX‘¾<Œu×z»Ú4Ý õ¯ Ñi·EúHë–fœÎØù±ï ²ºˆà`ZëEؤ¿P§·¦©ÿµaeöИ­ÝÛ–$q såTr2!ÒʪBé±¹ªGêl»‰Ö!°®3Õcý~ÛG`hž§W“§ köæ-RZÏr°-bã¸û¡{œï&ü(=–*Ë€ÒÓ]9HmÓ!ÝÝfÅVëBqÀßÏ×;kh !goëvGª˜-µ{jšíÔ˜—ƒk‚m„·M™Ž vÎ8ØÏ hÇŽÚ;´Ì¼€è­!¤¯žD¥wUX9˜½ï‘ÌØ3‡CSÛ[l»fÚ·~Ð ó¾ \ÓlVç:]™Á‚΢(R[ÁY À!,îhà÷LÖA÷ñ+®ib߻ݶc×4àœÛq ò÷õ¶n#ðïG¸Mo‰ÀЂ[„*¾ó 7ÒÛajF<¶g::*åØVyÚÌÒVòÌ&8fÐ 2¶ ˆR¸aà(°ÏQ÷IÛÏÜP+Œr8E– ÇüSÉ,ćŠÈqØšùè¹Î­èw—R€Õ‡ú¦ã—¡¸¹´%~Ÿ ŠË†mדÏ_<Ï—!ºàL‡èú›'XÆ·Š å§7i„:Îבå’é",_ùÛQëÎFáΜì|‡¢`úÓv`‘ÕkÎK¦5DhÁdù%jæ"_¨)t™>ñd\󪎬BaáÏQþ(dR°J+'®ž -ä·R9ª7Š©4“AZw¬Îùðê˜4w }ë¾Ëõà{<èû8&B‰IÖø£ ~x‚ ¦òDLQþÞdBDp/Y.!³ÊFê„B͖˲,æãÐã°XO³üS=üñjÍ!½‰pãªå)"®¦`¾’»DäU]«èx²Od–1UÎMòG(/–› Mõ…ª ' ,Ñ%nN£u@SFŒâüfÍ'8Ûˆ¶µÅØ“Í㈪µJ<x¦ò‚Ü‚æ°Ü'™—év»MÆe̬ iõmô8‚²4íÂõ ß¹šj—åʃ 4B‘¨)N}B«› ù4¸ú¶&—~wôu0=dh¨nˆá9׾ƀ™E„§œ\®;ÏdNþTM•P«–˰~,´¯& åe$ Û“Xô‚ìC\çZ¤¿w®Ñàfb_÷?# ¢¤a‘šÆ¡f²{¯µi®±fð]uƒ,‹t¨Ûm4sI…µÿ×<ÖuZ©—š( íÐTiæ¡~v,ò@•ntùU81°3CÂy„'ÍO l æXOÈœwçpFÇ ÊÉ;~ŒÊÝý(ÏœLE4ÏÊ…Íê8ža/0 \#C{€kÎÊoWO>>@P6Hu àyVÍG˜§éoÀ`+²ÆLUŸåaúÇ£pÁU8ºð RGC­g‡îP[”üè²Ôì ;<E•¾Æªß4“õóàzt¡Ð)òGè"ÀrüéíØÁAjC¬tÍÞÒ€šÏXÐÂ+刾†+(Ýݰ‹ˆ$„`ü|7ÿj¾ëͬqpaæ]ß*)yºnoõ®¹§âÞ ñPP©oRäˆõü BùÍEâêNõ7T%äDÎÕ&Pz²=E¤/û]x‹ÁÈyMíËiŽtj©ƒNŒ†>ÇÞzf˜Åqâ`êþ”%ÒøU,Bhôºód7¶ Óç“f~¡Á‹³›Þ Ÿ1ðaƒÞOzLƒBÑ­Ià}t˜ü~’ŸC‡tèÃåh/ñ ¤}]Û;Ïǽ¿ ‰'míâ‰éï=?¿Í4ÌJ‚fIÔÛ x”äLŸCç©/\q$‹ÅS†ÈÂÖ?ÞAh+wM—Ù"Ý™~WÅÐËPÚÈ"œwäpMíñѸ x³¾÷L÷;/Iãyw×';iÛ¹ÚrgCÿê»ÿXó1Ý endstream endobj 134 0 obj <>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 137 0 obj <> endobj 138 0 obj <> endobj 139 0 obj <>/Length 15818>> stream xœíyœTÕ™þO“Ô´²¹ ‹ht„ ¢´@b£Ã2( ÍqØ„ BwQ“€h% ã†lFApauLtˆ¬"£H4“aoópÈ‚’±ë÷å>Ôñô­ª[u««º)~sþ€Û·Î=÷Þ÷=ïû>Ï=ç¼'¯¼¼Ü‰DjÔ¨Á¿Æ)yyyüûå—_~ík_3gPÑkòvèíA¢‚”þMt•û«­¯ ú÷ÿ÷ÿæoþÆ=°O’gEoÅÍ™¢¢¢÷Þ{ï‹/¾øÛ¿ý[Nþõ¯åW]ü¸§áùõ.¼oÊÁ¯ýë¿ÿû¿OTÿ‡?ü!ÿþò—¿¼÷Þ{[·n=iÒ¤[n¹E‚¾ï¾û¶oß¾hÑ"þ¼ýöÛ‡ ²mÛ¶GydïÞ½ÿöoÿF…#FìÚµ«qãÆO=õu¦L™òꫯÒÚܹs/¸à‚ýû÷ÓìÿüÏÿð<'Ÿ)Ï+ÆÓãÆã²£GºJ¢H½ÙTUú–ºoôïÿþïßýîwÕüïÿþï6mÚüêW¿züñÇ©‰Lݵ×^‹æ W®\Ù±cÇ×^{ ½õÖ[Hö?þã?¨ùÆo ºÃ‡תUë†nà'.œ1cÆÐ¡CùiÓ¦MãÇïÕ«Wqqq³fÍh-O’uûxAAõ¸ø?øúñJUH(ËE¢ç¥8ÆÖñÿüÏÿüo|#ÀÊñ‹_ÐÇß}÷ÝË.»Œk9^²d - ú™3gÖ¯_ÿïþîïèÝÏ?ÿ¼ñ| ôÛßþV Þ|óÍô÷ 6p!–÷É'Ÿð+Jýþ÷¿ß¹sgŒƒúT8Õßi”ή»råï~÷»‰'ÞÿýÖÊÙU…œ²\|þ=•ÈGuy]‹V®¿þzäH7}ýõ×ùoƒd,X q!@*ë˜K~øáë®»Žjè wïÞ¨öÍo~# Zݺu1¸ Ö ‡Ã°\!šàWNÊÎeè]$#GÀKQíþáð*Æ Ãq žþùˆ¯E‹W_}õ=÷܃ŸyòÉ'¯¸âŠo¼q„ TnÛ¶íŠ+úöíû—¿ü¥N: .ä.\Ò°aCÜîèî»ï^³f Ò>~)OÞ†ÇÂq®Gf·¸PÇ$±ÈG¶tëXïm<›Ó±à€½£ÅH&j—:ÈSÓî;÷½ï­^½  ]ìµ,Чj‹û:ÁýÌu\®æÊ½‚X­zÜ«@bÄë‘}ŽñäOÖìõXÖïÿûŸyÅ8þÊjØõ`òi¹¥ž4xƒ­ ZŸZáZC± Æ½6ö¦'©S 6Gç&Ú/ÔúÖ­[GE»\‹æs…â…å „Vþ%ãôADúÓŸ®ºê*¢.ƒâ‰FV­Z…(:Ô§O°þ´iÓhó¢‹.jÕª6….€e ½šEbÐ š¥B°ŸUÇÔ;ï¼3hÐ (^UH. %uÞ@Œýö·¿=uêT$€|ðÁçÌ™CX&º‚VÁK ÎK>0þÅ«ƒ8ãrm“&M4Q] |Ìå/¾øb£FàO~ò€SB5@¬ÈúX;xzÁرckÖ¬©.–UÁeª¤Áèû“'OFdðŽ9ÞG¦?ð j Sƒý9e w~uà.ø .LÛx†ÀÞ¤nÞ¼™:7ÝtÓI’H èMØ“6èÏ5­_¿þ;ßùމº¿úî–7H>P­¥K—òúp7”AgïÖ­îY!G¬nN—‡ÊÑ,’)))ÁópLÇÇî¼óNnŠCwÝu°sçN~‚KcUAÖ mÏëqé;”Y³faªï¿ÿ>çõÝ)›rË| Å(8™?üá "kÞ¼9<Ò对æVË–-?Žb†úOÿôO˜ ³àZ*ïÞ½ÄñSO=UZZJ€Á­Aå¾õ­oíß¿nÁ%É­Á>%š˜?>wÝ·oŸ‹½„̲+¹Œ–P¼Á½ÊD¥á»Ä¢#‹ì} Æ8º·8Ê5Ä„j€7(D»èŠ3èYPP€JôX9ÊìRä q‘¾¿Æòå neËÝìRûAN Møž‰3¨\­`’úÔ‘s´. Þà ZÒŒ ÿMÔ¶\îf•ûôgϤ£*ð+ÿbSíÚµÞÈ›ËxͳÎ:롇¢ç]yå•T&Òž8qŸ>pàÀgžyæ¹çžC†aÆ—pôø}Î`²³gÏÆ…€*·lÙ’ŸŸÏ¯µjÕÚ±c$'ǪNð"ÖwéÒEð)KòÊj ÅÚ´i] À¾ñÆœžC‹ŠŠèÎè£k×®+W®¤H‰ÈL›ùÎòÊàÁƒÑ„ʆoÝwß}¸t W=´7>9ÞV <ð­¬]»¶¬¬ŒÛ@Œgb‘Hƒ7À©o¿ý6=šj¨mãÆ`MdÚºuëºuëŠ.¼ðÂyóæd9¦›ÞrË-€Ã>°Œ‰“ì>øàÏþó"Þ‡[êÐþ©ñ†°N \¼zõj7ÐçPxHc¼!âŒäp¼jÕ*À:ÆÀð¨jÉ’%ìDp´éÓ§=z”.ϵݻwoÚ´)ð8ô‡ûB[¨óª]»öÉñ†4œñkЙ"n¶„å ˆ C¸\ˆAp2=ìoƒ¸üñ-Z`Xð‰C‡¡Ü¤ƧCTCsï¾û.Öƒ¶>V¥+Œ7Ø»«ã”Ö¬Yc“(¡xƒû•Ô~Ðv?¬Z¥ªŽË¢|¸HNðä.>ÙlÖ«$ì¸=(·Ô ’úxƒqš¯rÄðñÕw‘«©È?bÇoªqÓÇŒƒéé ¸¼üÃ?¤e»IćʉŠ7ØÎnÿõñ;ââ6âc ¾Á׌Lðx:8vìì³Ï>¼³íâòZ¶liëk"S®Dˆ°¼áæ›oFîÔ)..&*Š;vìH ƒÀ?ÈŠj`VþýôÓO{öìIl(--mÕª¡xçθ~B¿Špð¯¿þ:Ç<N%ÉxÖ@mb¸ˆ3Ò¼cÏž=Ò¿tãäP ;ÞPRRB\¾$®{ëÀPâ°>_Ëùh¼3Ü'Ÿ|’k ÅÔÚ/ÔƒhA½œ$Ä~ë[ßÚ´i¡;è +¤ñÍ7ßÔøEFÄOœ„UôÕ¡¤žÒDXÞÀ[?üðÃÐ7œ3èˆ?¡fÐ.ÀÏóÏ?ÏU˜ ê9~üø¾}û–-[†Îˆtö×^{˯‡†gPóõ¯}Μ9›7oF÷6lаMÐxщlÝo|íÛ·_·nëàÁƒ6Ä?mK¼K4wKâ—Ð’¡_Ó—e ˆ?þñgŸ}6ãµ ¹³gÏVûhQ󚌧TT¨c´2jÔ(Ü]kÀ# 2q,¡kî *…˜èB“kóLHÞ€;uêo0`^€ôëÕ«›Ãû#S4‚‡Ã† ‚•9rä‰'ž x _ü½váÂ…4ÅOÈð€ 1‘Æß{õê4Þ€>1+„î"WYC­ZµhÝ7,šCÊÅLôSoŽŒÅ‡îä%µf?hûˆ…‹Í|.$hJÀêÕ«ñ_÷ÜsæqWÂ5üYjмã’¾¯„o°¾ù^¥€º»õ­ŒŠŠ ØŽoú^‡P€õägœÍŠ7ø.ÌsfF*N³3Þ]Š  ]úm*ºñHÒñþÅ ìh(Ê ˜óÎ;€Œ»¼ûî»izAhÊ”Œ²]Âò0Õ•`%\Ë€>¡ø}„ ,»wï^8\A0 P l%>vù“€1uêTNb¹„jDïSë©àƒG’°é“òóóÁà<ÍSâM0½¬Ë/£%õ ˆR`ÉàÍŸ“$Àÿú¯ÿׂ‘Ð ‚Ö¤áÇ3ªñÊ+¯p¾[·n?üáù¢îç|ÐxôçC rJªpà 7 ›sÏ=wÅŠR)¿ZSͺð2QÒo Ññáº`$uG‰^.À j¢S8p E‹&:‰šuÀÚD&¸5¬­]»v €ñkÄ®oHXÑ}_óÆŒX°GNB—.]ŠôAQï–uùe¨¤7OISŒŒÖ©yóò裪€‡ ˆb[·n=z4­iwါFŒA¯‡jO£×]wVÂqëÖ­Ñß©õ !š¹™ Ñ´‹„O¢l…Û ÉåÜC(Þ@µ.]ºLFŽI_Ö· ¼1q‚0ðÎ;ïŒ?¯¢%$¨ñþûï_uÕUè?öÌ3ÏpŒ›¢0ç /¼pþùç<†Å"¾õ öÆ6DÓñ}Ó÷&zö« šñ™>íåÐT¥4xƒ‹ñÝ¥‚쾎h?Áú¾=»Ÿf}è6H ˜dMË~t{;AÑÊ8šÎQêúxƒo2½¶úÎû®ryƒ¯¸z ÑDyŒ}à‹d¼X¥AQ¨!Ó΀`ªªd•7X~à[©8@äZX$x¼aãÆh‚\~Ò¬=*Øéb(#¶…Ó¹d›7ÐS㮋6Þ7óaÆ>|˜@á*~%h¼Áƺ?UåýyüN©OŸ>)9×Kg7|ðÁ‰ÖE÷èу˜ êå§_üâ ["|’õ ˆ›P®Ø`C´æ)¢»víZ\\ÌUZ´û¼Áò†H‚uÑtV0˜Š“à%7ÐÑq'Aã Hýúõ–¾IÊ“¼Ò¡C‡[o½dÆ;èr“;I²Íh<Ѻh¬ ³›ã'®V %Yíÿ„»$”xC~~~Æ wîÜi¢ËOr.Dg7¬‹.--]°`Aƒ æÏŸôèQL_¹*h¼ˆÄ½µ2WÃ>Ø 7Ö€¨Œš«rw™‰Éoˆ$^íþëcZA±»{óÍ7å”ìjà扣”‘F¢c ¹â”lÉ6oð­‹Ž¥n'H‚”¬|·))))**²=¶n{MÜÛŸ&% Þà‹%±fä;ãvvß"êØ›ñ†4Ô`¼xuâĉsÎ9GŸüÌéºÃòÍœ°*@´„ŸM›6Uâ‚(ÿ¨¹cÇþ¤qÀ.ÔáСCœ$–¤³.:¬ø•¦ñcô«ƒÓ–R„š§Ôºuk`þÌ™3á €|@œÈŽó7yÅò‰={öp~Ö¬YúÂÚ³gOÀn³fÍÔT:ë¢ÓPoŽavÜÀ¦%Ëš$Ó,éÍSÂb PÍ›7G¬^x!ÝÙaCPWÒ‘#G ÌÆ#Þ«V­¢Áºuë¢*ZЇÕtÖE§¡…,®m×®oˆüô)iÌS2Þ„;-Ÿ‚Ç]sÍ5È}Ñ¢EØ’¥#M~¼Biißæ«*((Ñ<òÈ#ZHs]tØØ ×ã*lü4Ñ©ó~E|ˆxàÀØDàyÂáÐÇwïÞèagPånݺQsìØ±tsÎ,_¾ü7¿ùÍsÏ=‡M,^¼Ø¤·.: 5&awØiö„Xù–7XØãfŠ1Ž%Ù¹¼që»7•´C¬‹«-Ȧ«¡Ó|Y¨yJ6ˆEä>Ÿf'–ùÞÝ7ön]t€p‘XŸX¢ýø®åóxIÍÑ ~=÷Ac—]¸fücI(Þà«£žîòáØ'Œ]³nkÆa–o(÷ÊŒ3FŽi_Iª®íСC^¼50±Å}õ‚žM7gß9’¹•,ayÃ-·ÜÂóoˆ¨x|ÏÙgŸ}ÞyçõêÕëðáÃʧ„2d±zèС*ý9}útú+!AÉ\d}ôÑ¥—^JlïÔ©ÓçŸþÆoÐlú¼üÛ¥K½‰Îð¬<œ…á©„h·¨û€:-¼’RËRRÆÉGê¼XŠôQ uÅŠt aî4'JwïÞgnÓ¦  hÍš5@U¢7z¥åW^yA¡`o ©U«h@"Ú§Ïô¯–Ÿ˜hæPT#<N)vZg܉~ü’ßTåþýûÀiVÂR…Li"ñä4,5iÒ„kéà°¬V !‚Gk×®½dÉ’M›6‚0ÎÐÍ·&E³êÕ«0‚?þ5¼üòË4~MŸ7ð(¨áF/Yƒæë•GóªpÃRJ¢-¢°áqÛ²áÃòE]¨€™`‰¸ 6l̘1#FŒ€ßAë° ]rðàÁÂÂBbä‰'}ôÑ–-[Ê)éÖh±U«V7n„ ¿úÕ¯Òç œ—!s'²äLllHE(>Mè*tܾ}{kgç¡xƒñ>B¼õÖ[ÄÂI“&QÿòË/Ç·ðx„ ìƒ^O§†àd°ªÙ³gÃ!î½÷Þ®]»"7xC½zõ41 ïôÙgŸåççc7X !äСCIÖ7«Ø¢\€66è•”üC³Q7ÑÆýI§qž!Ë UÂò†/¾øâ¬³Î2ñÖ5Ù¯ÙyÑay÷¼IL|—¤Tl"5‚ Ö©SÇâ×D>]^³fMeŸ€Á¸ŠèÂ3¸°2a…-©7øêć¸ö”½áŠÔyý쪫®*))±ÚyÚÈ·iÓ¦t—Ý»wk: Ü‚0>kÖ,*Ü/ŸÒرcA® Zˆùœ!¼¿ûî»iò˜µk×j’¾¯.T#@40œ‰Žù¼ÔL;^¨x±víÚIOÖTo :’*Ÿ’‰._Ðnà”Ѷm[HõâÅ‹©†ÅÄͧ„Ua¨mïÞ½$¸÷–-[ЕÓoà!‡"щzCYCQQ‘Ir\ð`¢ð\ú ð¸ûHŒé7¨Ë—GSÉ¿ôÒKÓ§O‡©U²p4ºÿ¼yóæÎ[î­.‰›O },\¸î‰`dãÇç8MÞ ç–SÂæ¬oo˜6mÚ¨Q£Rop+ÈSoý7Ïg¢³ö3Ž‘BñÞ„ÃÄ®ñ> ;.9pàÀ]wÝ…“Y±b ¸âŠ+Ø·o߸ù”x#Â^èÜsÏ…dpw¢&}Þà"%-½R¿ÆD#ÏZ\\lRëÂå÷‚Ò¿=öáΉŒÖ°¼AnSýÏN²ßW|«£ò)•;ë«}ihÒä š|é¦úàK õiÏJD}KÇ}˜/ã%ÔxƒËFc/ô ™äê»]lý“7ðùGm£¬.!ÔgŽ?^#Zî¿ÿ~4ŒÁ¢†DüÅ'û(ª)5¬\¹,‘´…´Kð†D½ÐWÁž9…|\f¡TÊW &jÈŸþ¹]M;šž4uêTbC*ÔG÷ UÿÚk¯ÍÏÏD‡±Œ3ß ò%Û¼xKdVÎ è%øI’‡Õx_è”Ê“?±†¤HÉÄK´§wð1 uð¡¸êçØÚ¯q>c˜,ÌwÊo0žæ{h¢cÇŽ\Bl=zt³fÍ‚ò°jñš5‹qÐJ@l01°LÅAÐC´ŠD‡Œl?0ÑѤ¼,lq–mÞ@Ëð†I“&ñ«f7Áph¨0(«íqþÖ¯_í|Sr‘ƒ=æ}è_0FÔŠì\$wÀJÊ´KVyCaa!aC!U᦮¿þzõ“äaµÏÑ¡Cþýãÿˆ~‚cC\p¦§L™",AwŽBž“ÈÚ‡µ“éï¬Yå Ö¦“ñó°ZkPÅH4aX@l(™®£3z2XôücÍ >ÛÝ741X0ãôM%{¼Á݇Ø%Fy©äaÕýúõCûöíKŠ”b‹%L”bŸãô)iðWpq»£¯…Øõ V &n>%÷s²#v^à ‰bCÀ»©õæÍ›_|ñÅ"îwë•/ayC¢ý¢9ÆÑ„µ£UïÞ½ ¤|Jq×7P?I>%ϿĢ{î¹GÉÂZƒ\¼õ3æŒXßh¿hð´€àÌ¿À!ê€_wíÚ•h}C¹7m)a>%;ûQÆ-¹_@lHTô+Pì¶Ûn‹DgónN)yJq÷‹†BÓ½¾Aƒð» /¼PË~L‚õ Ðæ$ù”ä—d ÈëSÂÉ4buÀp=öXÄIÕxZ•4x× ö‹VÞ$‘jв6 ×¸ëäÜ‚ò)É „ɈÏp 6¤m ¨'¨3§mˆN7Dì °„+Œ7îÁÄy@DÐ`gq×7D’æSÒý$/ZÄp¨‘^l  >kÈÒ×錔P¼Áð½bOÊè-Ð[Ç]ß`‚ó)}Yq×Oè5 ¨ŒS †¼ì|£Î`I}žRìês—¹ßÖYX\ƒ³ß„ŒxƒÎZkPz·ô¬}jðõ “5:–zI›7¸ŸsbuÏÇÎS²Ÿ æSÒ••TC$:­¯§ôAî%–¶p°uëÖâââ/«)Ã}XÞpc‚}ß X3fÌx饗x)‚-•5ÞhžR’|JöùLå¬Aš'þðpîh„·Á1:èÛ·ï|)±¦WB­‹Ž»ï›òg‘hž·_ô×ïû–$Ÿ’î—kà`Ô¨Q%%%g¼Ìšï¼~ýz¡fšÍHÕ4xC¢}ß`˜‘ù:Q@HKâÎSJ’OI7«¼5ÈëÑqxD{Òç1Þ›o¾Ù8óV«¸¤Á"ñö}£kÜFß3,Z'š§”$Ÿ’n–)k˜6mÚ¿ü˿Ԩ˜7œãyóæ•––9r„NdªO &üú†¸û¾5oÞû@JôôV­Z}üñÇ8[êôéÓ'Ñ<¥$ù”t³ŒÄêL:õÇ?þ±;cB –••Ù{Uã·¦°¼A.êóiΑtß7ý'Ÿ’½É„5hØÇ÷™þ ‘F 1 AæpÂËtI7˜Šß'\[Á8µuâ& ¶Z±—dž7h,Ú}ÎOš4‰•UZ‹×«×)™J¯‹ŽÛB¬†©Ç?O© ÔÀ-i¬VPP 4®oÓ¬tÅX©–7$Z]»vmï§Ÿ~ª/zx°éž={¦Ä†Î;=š^Ã[Z)V‘|ž’ÉšThDi½¡-¼XµBT~]´–⢃~ýú-[¶Œ?7oÞ¼{÷î]»vÒ5‰F_!nj„“d¿hÝ/KjÅWrïvíÚ­Y³†g}úé§3 Ë´J¦ÖECxÓ–-[vëÖ -ÒÇŸþyù™™3g.Z´èÕW_Etôú9s怩°žäó”L6­ 'OžL;P˜NƧ…*ayCy‚uÑô÷¡C‡òRwÜqØŸ^)£5„¾xñb8–¤sÉ„ p°¥$ûEë~ÙS÷€Wn¸á¬¡zÕ`Âó†¸ë¢1ñ:@Êp,¸þ'žxâÊ+¯,÷#nêÓÇq;ˆ›S¯O2OI7Ë*Rºÿþûé28%Ú¬¤+_Â~ë».:.Þý¤êVˆÌSªkÀ¡š4ˆmb†y§ÇPD(ÞàÖ‰õc‘Šò¹kÖËå°yó”Ê£Ó§ó¼yÄw ½6¸Z»v­´b÷ ¶ßDjà*ÚÔh8z5 †Aª¬„op‡,ó Äíï.×sßÔ–*ø4‰—¤OÏEjÚŒ2•þXo½õÖ¥K—'ZµjUÃ[Å^]ô-,o Óµ‘ r¸êª«`?eeeĹcÇŽ}þùçÿøÿ ÀÉh'ySÈPË›–,Y¢éIò°O MEÜC;+aëׯ'æØm4’¾¡IZ´h±sçN;ÔãÒÆj)©ó†Ã‡k·îÇ{L¦Œ ´úÞ{ïCá wC¾´©/ÛÓ§OçÚÛn»3ŠˆÉó°o'ÏDTàôsñÅÓÊÑ£GÝ­YƒK€5ÐxÙx;@To~Ö4x¤Ad—\r —C?µo†üH¸°<@Ñ+¯¼‚Îð½šC6Å&æÍ›Ø5Ñ… ó°–;Itè?úÑô)T]æg^Ñ¥‡”Œ7©„6yíãÇWoŠÖ4ÆLt}ƒdÕ¶m[Ä 1¦‚\õý Õ<0¬w„†¸Ë¦M›`C† I)«UvæÅd8¿oß>¼“vºJZ¬ÊŽì÷íêEJ¡x¿"hLaðàÁtd®Òú.¼ì²ËuȇéÝ={öDÖüËñ¬Y³oèì¸ì‰Ë“äaÕý¤ ´Ú¥Kôܾ}{ž`ãÆ÷ÝwwÒ³Û5\zé¥}ô‘¬ÁÔÕRÂò†D“”ì‹Dœ=’^‰›‡Õ®Õ)¬¡k×®GŽ"*¶¸±!¸„h:†‰–j' &äú†€…I±íø>zÛ’$ë©£¨SäB T ¢•¬Á}îJlØ»w¯ÍÍç¾›ÏYWA ËL‚õ ¾«|ÈL¼×LT'cj(.§%:q}·!Òà”"^,݈•ÆŨ²MᓆdS/ayC¢õ <3îzûöí‹-âOÂ,aÛ¶m%%%{öìY¾|9-# Ü ¯]hÖ¬ÙÇtøðá&:mI'imíÚµh^j0Þ7DzÍ_½b“CWB¶!J(Þàˆÿ&ÔúVÛ3‰fÇo¨¤SÂxm¦\ !ƒ6l # =½ÍkL…ØÝª Tr}ƒZ(÷Ò4úgÉÇÌ”ñ7Øù¶Zæ­Án£á¾!Ñ/Dl€Ÿë¼Rˆ'ÁXU:%>Ÿ’+V7½‡«k%>;‹uðÍwʺŒÇ‰ ¨—zðàA½N Îû ¡š5k;vL#VÙ^¸–7Ȳ‰À8}pΟþô':€/Z¶lI<@Ò† ûöí#~@p œœ5k1ƒx„å^Úhš;6ÂŽ;ˆ ÖE›lªÁDcƒÌB¶yàÀ^ÉE¨î†qÙ.¡Ö7@µ¦NJÌûÝï~÷àƒΙ3G3±µ?†6CÖ„ñÝ»wÃfÏž­uÑZú@¤3fLóæÍùu^~ùå`V”ˆ"ng‹7ÄUƒœ’[3â¥ûDîðRÈ„ä¢Õ¨á$²¤7Þ0yòd˜&¼ã#GŽhß…N:µk×:†Yö^|ñE9Ùr/(úÐLzN¢<°âŒ3€­8Ñ‹ˆ]mEc²£†ˆ· ¼¦Ã*%kúŽ6wEÙÈò™¨„å r÷;w^ºt)]7‚2 =zô@¸ø¤Iç¼²½Ñ¬ÖK×ðòñŽY|“&M„D «?q9²Ê0o0Ö ©Ä¸uëÖ)»*}düøñ_z›Ç¸‘­ ôŠ7/äþðŒG„oApxüÂÂBжmÛqãÆ!t8‚æ ¾ÿþûÄz:^ë™gžá7E;}úôùóŸÿ,0É}µµ%f…7øÔ —ÔV yÕªUµ%%%xF)ÀdgŸ†D%ìxƒ½ÊTÜîC'¿ŒîyS£âRQ·ð)ÛåI™ä &±5ð =ôšànAD95¦ª'xôÑGGm¢3ïí×ï¤7ª|ÉÔxƒ©¨Kߍޭéngâm‰‰Ä[]IkÐö{¾$§Dh²“'‰r–Ðhs,S1åS6J¦Æ8Ù¦M›o~ó› ,€÷¬X±‚.xèÐ!!8D›@[îܹsÛ·oÏ´ \ii)rPNç û¾¹B¬Œ5È!j‹%Sq£ñ‰'ò@À;ÚW}8jÐV}øS´´Ï“ÕRùñ†úõëiƒ&mð¡X¯ƒ¸ ãK–,¡ÌNº\¸p!r¿í¶Û:vìHƒD{HBˆ¿´’_X¹“8škï4B?¢Í7ß|SVBl°NIXèG½íÞ2!ç„%Sã 0ô}H h B ¨UÎM^2ç€U`@jŠkµ6t»yófíTU#îºèJ:%.A ndã±^¦  5¨jWQ¹Î¯yا/Y-™oؾ};œMˆ¬Q´  —`³h1ÆÄu/ ‚©ÿý÷ÓQL&­A-пèðlíwÞÉ‹NiÞµkWYY™ œ\»v­\Ò¾òÄÜ‹ «àswFÆêÕ«‡OG%Ä Â€¶Ü|¸û‰{ʲí”L†Æò*NÃõ}ÖŽ55—RØj‘€D>•oPJ,œ˜\#:QœîmÒ¾kÅ)iÎ=…eUî÷]Éñ†X°ëZˆ½‘o8(+¼ÁmAjp/äÀŠ5XÀ RÒ>–…ò“b{*÷ªL Å|u\h¢˜‰1‹òŠË„ª‚7¤¨—7äys2®¸âŠ „gZ%,oÞ/š€»§Z=ðþ ÚBåUçuˆÏëÖ­C Ûªà &¤xym$YØ9œiJ7d©üºhN‚°Ÿ}öÙ¾}û¾ú꫈iîܹóí·ßFÐB«ÐªŠ7nÜϨ Þ`BªÞ ½g„X`‚¶é 6Õ’©uÑtgeöìׯߕW^y饗¢ã}€4h|ÍxšàMçÏŸo›ª"Þ¢x BôYg H­š¬ayCy‚uÑ`ÿ#Fh7âoú /¨eè›Í79¸øâ‹5UÅTo0)«áÑG5j”©Ž&aÇ⮋¦:rÓ¦Mqú}îܹplÎ@#¨Œ/"< ³ .¸`ÇŽJwUE¼!”bÇtùéÆLâý¢#ÎæP±ó¬Üä“v&GÖyƒ ©í£˜W}ëRç ¾:±ðßD“jºÄ6˜„7Økü)áª0–l«e•ˆD7žseág˶ä”´8·<šÑ@;ÿ‰FD¢ÛSF¢™\3X*Ÿ‡U dxeåÿ¿öÚk Á¼!y>¥Ht zH ·¬§wòdÍš5y·þýûkàA²_;Ò•y…’©<¬b¿O«V­2f!W—7ðvAù”Üm4ø n,«‚mwœÖØe&v4;)ŽL¯¤1Þ‰—‡£“]ù” ɶr\Þ$Ÿ’ =‘gÂ÷ýô§?=vìXÕ8%ã9_ºäÙgŸÃÅ#!¦5kÖpw©'’…ùKayC@V€X‘&4> ±’D¼!I>%k¡Æƒóˆ f«oÔYUƒvœÖâãlÄ[¡›Ô{kØv¼Á¾]¹“‡Õ‚šD­ùxƒ…‚Éó)åy ‰ Ä¥l;% ˆâÙgŸµñrÁopBÙ)“ä$ã¬"opÑšæºëmMEµùZÈ È§dC´:N Ù)6pþ…SG^t,‡ˆ&Nœhó¡ÇªÁ÷(öswÞi¶_´ûqyC\Ræ“U¬ô­^ãóœòr‘’¤Y³o\lQ§¸æškÊÊÊP¤ÕŸI` 9±_´ÖIê³¼2útìØ‘´žPј‡$nó´{öìÁÄ]ßÀŸDæmÛ¶Bø“ ÈäÔºèòŠÛï4°è›F瑚›º$ šñ¬ÈÔ…•î…qÕ`<÷‹Öúz'²¾DDM›6…¸qÚ!Â!t‰7KÜŽ»¾° ðµq H×x+SˆçÖ7XÞ€°ÀÈ ž é‘ ŒC’‚ ƒ¹sç*õLpl0ñüÃÏN³ý¢y0ÅKp“&Møl íBˆ T®KûãB.»ì2Ú»¾AèpHMHœ‹kOò}O×h>/°íúõë¹ÿÒ\ê‰|LÅ•n\EHä”ÜÈ,—øåéº_4— kD¦?ñKèƒiÔ¨QQQQ×®]ñHü ‹ÖÆq×7HCÆ›@¦)e¸5Ä –ýj}C$º%ª#Bò3YÓ)¦6¢I;âsyh.Äâ`‚:×Ò²Ør:ìÝ©S'xÀzè!÷R¯^=ä ¦ÿÉO~‚&Ú´iƒ‹ïÞ½;ÂEâ‰Ö7ôìÙ“Žc¡9wÿj}ƒð»²m,[¶ œƒpš¬„oŠGÜw3Ñ[PP@×@y!ºÜÙü)ïôÞ/º<º¿›û¦r!¾ß\(åû"q&vø®:ÅÜF?+V¬@X¨aµW,RJEjMS •9TçãZC$wö‹6EìkÇJ/¶}ݪšÛŽ}ÿ°Né•W^ù ›×V€|YÞq¦sK¬Þ\{&Có”LÅ™z¦b´‹¥rî-ÜíMÜyJWƒŽ¬ê¼óήeé›]Š%,oØ¿¡[·nG]²d Mœ ¸~'§M›F›]tQ«V­´Û…Ö¦OŸþâ‹/þö·¿Õ„ âÏSʸŒ§|ШÉD?W唤¸¥òó”Ú¶m{ûí·¿ð (Cë¢7lØ Pü½ï}oÊ”)Zx (V!hˆw 3Å% "3$5Ä™™‘ 5Ï`°´vâÄ ; –†-™š§DwF”`¤Þ½{#k ³ŒÒýµG€vUߺu+ `&ve¡?РT[xg] ® ªÊ41‰J¦æ)¡è1}yРAœ™¹Ì_<ÌÄË­äJÀW5Dâe¸©ÆRùyJnI4]Ì׸‹nk8ËÜ3© œµ²Óýwºê*á nýؼb‰ö‹6ñè^æyƒ¼m‡@oÄÔ`»É¬Y³æÍ›g¥ÊR3øJ¦xШGÚ—wËÒ¾Gw¿h¢Hˆõ •Qƒ /yÓM7é+ˆ¸…ÇâÏ={öœ1¼¡  ¦¶páB䎬%M…ìb}CÚjp¿ÙØ€ä¦ôM lpÇwØ1µj)™â ¼#˜ÿ‚” f( †,,w¿h“úú†Ê¨ÁÎä–5œ’ýЭÚ÷­*“Å$zÎÊó §ÖØRajüúŸÿùŸ_ÿúש“h¿h“úú†Ê8% Ôè)\ø ¯h@i×®]û÷ïoß¾=Vâû\õ%#¼ýuéÒå’K.™0aµ×^ûé§ŸÞzë­¨¤°°0î~Ñú¬”êú†ÊÇ â^·n]^ÅõÃy^P›¬¡’¢¬LÉo0ñæ—`.q÷‹Ö…©®oH[ ¾Wzúé§ È¶elÅ€ N‡í÷T*ÉÜ`Ê.ROu]4•àÙË—/Ooû½€§ÏÝñߣثì‚q¦óøº¸û®“8ù§f‡[F‡5ˤ™RC®7ïß°mÛ6xíà¢Þ½{'oÐvJT1tèPn¨iöo¤$à×Ò¥KÁ9ÄñŒ¨ÁäøxC¢|J¨„À‹³UÎ¸ÅÆçÎK³‰ÆD#h„€o¼(_íû¦Lå‘èö{teË–iKŸL©ÁäøxCÜ|J<Ë–-‘,p*—ŸŸÏÉÉ“'£Dã ¢låã?†7 atöoˆD§‹a8+W®$6hÄÊ«!×ÇL‚|JˆOûðuêÔ‰3Èmþüù¿ùÍo"Þš¥Øñ.Ô‚M¹ "]VVÆO˜ÂÃ?|Š7`jÖ¬©EXÓË/¿¼víÚLYC®7DçSҼǢ¢":þ3Ï<Ó¨Q#ž*Ñx—ëÖ­K ÁiÇñIހꀒ6Ý N§„2rw¼Á—å1û7¸ÌÀê2îxƒ‰‚׈3uÚ–<µ®ÌÔ˜:u*ÖAÀzŒ7ìß`5áãq&f¼Áþká¬Kýtƒ RRl ¨j«\¥r-7mɉ’oðõzßþ >ƒHÔ¬õ öÀ>IІ 4ˆf<¯UZZúÜsÏÁï3´f-âÌ-<ÍKXÞ°ƒÀ(¼FºwïN` ¾«á  [åa%H¨80^ÜUvxpí\°ÿ~‚Í©ýt³X5à”PƒÇÒ3Îòᇠþ }W; H£„]߻贊’4m»mÛ¶o¿ýö'Ÿ|BF1Ð:º¯æÜkK\â9*µ¡ªM›6?¾W¯^ÅÅÅÍš5;¹¾A7‹«t :­ØÀ?lþþÄDÂsH ið†¸û7€;A7€(äNǯ]»öâÅ‹©(iÕªU ÝqãÆa è wïÞ¨¢ZE7pðëÉõ öf>5–Ñ$ÑØ+zÜ;và‘°D®WÄO1ÄV%ìxCÜýp)øœ6mÚŒ;–N=}útb~böìÙ´ Õ Õ Äô={öXDüú믣Cüš¶E~9TB­oøÄískX}ÇmÍó4aëéJC°"6@ßm6úœS@z¼ÁG}cùš‰áÒq}EhbÚºuPl@¾„S6À9¶nÝZ9ÿ妔©’Ò©š–7ÜtÓMú¸ o ½°¬¬Œ?> ö¿æšk-Z„¸o»í6€é®]»ˆÕÛ·o×”Ž9hÕª•öð1Žzùå—W¬XÁŸ{÷îEžÇŽ â À^@‘ëÑøÔúhóæÍð ¼…‰. ¥7«P!H ìtî¹çrLj·_4ìA)¡7LÍÚly4ó7[¿~½ÞÁnvžCÔ!,o : _+Ÿ’ñx5¡‘nÎ(` ›8ÿüó—,Y¢K4¤ÏãÐ.ËPÑŒº´´TûLIIÜ7ˆ7`/€%ߪ.+Ö»t!‡Btã Æë×ÊÛÆµà×—^zé©§žŒršÆ1Qú&/-5p€ãÂ8´%ž\›Qnݺ•.>|øp;º<µ.Z·‰¢õEÏ~/Š?®•äŠLHÞ€àºví >1b.Þx npJ:tˆxoоo—_~9}gŽèqAhåÑSï¼óN8„îE¤Ù²e ¾“™v’ðYƒ‰¦+‰ Ër÷ k(Þ`—/؈¢`;‘[Å…}#±ŸWƒx:ÐÔG{¸¢ÏQÌjBò†ØA…`°k¹[¬èbÿ4±¼Áû(GC@zÔÜ-iðWp>jæVp‰±;UÉ ‰7jtjôíÔÔU–€‹.º vüøq›õQ#É‘jšQ‘©–7$Êà Fû,àUË Œò°êNvœ£Ó®x&æ«V¤ZgÃgª¤Á" ò°ÞrË-Ë—/×xæb‡}8À5)9—L˜0φ7šøàÇPOAAmžÊÚç¤Û3Þ +7ðuyß¾¬ˆ§ KØñ†DyXñB(àž{î¡ãÓå/¹ä’sÎ9§¸¸ñB‡.P›Sv8Ñ·!C†ôêÕKÎSCûEOÊØ¦Òáb2Æ ÓX›}hûqñŒAJ©£íˆ3+»ÜÉÃêN[²Štª~rïè2ÊÊóÝ€Ø0fÌSùúZ93J¨õ ®Ovcd^L>Pã¬ÆÍ‹néó‘ŠóïÕN§TRRr÷ÝwŸ]> ¤Íbi—mÊcâ’-_#.ðùʤ™F°bg÷1%,oØ/):_xáhDÿþý ¤µlü º¥²‚’¿›à<¬Æûj„e¹a*§…*•_ßÂA1¯½öˆÜIP)lÎxš#ö™P”ž]·n]$”‡U7㙢 €5œ¡8nÉÔú»_4Ôìúë¯?ï¼ó,X€KW>%M¶òëŒ3¶lÙBýH@Vû1CÏÇU°is5–L­oرcÐÓx}Ò€g[¸p!7^~‡É“'k'uêÓå¿ï• <¬º“},»ý™j &Cëð?È‘ÇGßEœ>|8±áÀ¥¥¥ÈúöÛoÿË_þB ¢~AyXm§Ð:rôóï|ç àh%,oˆ% ±Æ©8Ñ”;»åäaå?N}þùçĆro·`âÕlÉÔúûÝûËèDqçÈ”çauy7ôe@Ö^¿úKÆÇÜãX†áNÜsu©ñWjÐeW_}uýúõÏŒoGqK¦Æúöí{ÇwÌ™3gÑ¢E´Ó¯_?@&î°tðàAÐ*m‚S²@¬¢¢"Pñãé§Ÿ¶)»ËÊÊ&NœøÕ<¥^¶8Öœ›q”^ÉÈxƒ:r§N–/_rEÜD`˜ŠÙ»w/¦(`­S§Ž¦yÆÇŽËI8ª…Uœä Öx,næ.“«B±T]ÉÔx½eеëÕ«wà 7äçç/^¼˜fçÎûÄOÜu×]wÞy'•ß{ï=¨²¦0RA½bZ;­MO¾oðÍ~¬Þ”GY-oÐIå·Òú›6ž±lÙ2ÔŒ¶š7o>pà@î‚ݬX±bäÈ‘ÅÅÅMš4ÁÈ0ޝÖ7hƇžIf]ÕZ22Þ€ñBÄŒŸýìgH#ÀV Ù¤Ü i¹aÆ=<í`%ÄLáñÇGa”qç)ÙhnâÍ^>ÃJFÆìWQ­f(Ù‚Ê6® ±-WØSÀÞÀÇP2ôʧo©äxƒïBkayçÏùØ_\´j,oPl°­Ø‹}ù›ÎŒ˜‘Þ`âÍúr…nÿt˜7˜¨5ø2¸ªØ[q9´Ô0QÉoH´_4@hÏž=@XåY½z5ò$‚xƒ”csf”G7¾r—Mž<ùÃ?ûlt®äŠ®÷·¾ïç?ÿ¹–¼¡ä\Þç ¾ý¢GpJ4{øðaœ èÖ­[Ó¦M“ðZGĈ7ø†}ÚÍœyÜ믿~ݺuÙ“N••LñÊŠ¥lsx5”l×ÚûÍV·|óÍ7ÿûßãòlNð3 Tž7¸xÔR}“b‚Ѫqó°<î$¯tèÐedBÕ\Òæ ±DÁÕ¥;áÖtÿMÈ©A®SÈUË¡k×® $ÈukËæ)ÀN ,¨Y³&±™:t¨°°È1kÖ,dðžò'œ[ñ†T¬Ú6÷ü™Q*?O „ZTT¤E ZEÂOšÁ‚ùÌ™3{ôèÁ…€"©-ˆ7¨Á0ëׯWFÝÿyCð<%©m8p`éÒ¥ôz»ÌJAZ†RÔ©S'ˆ7$«ïÖŒ 7+J–T5%Só”ñ»wïF¦’8eË–-ùùùZw_{òÉ'Û·oÿÖ[oQ{¢Zoèݾ‰åѤ–¹^Bñ†Hâ<¬°hDLÌÀBš endstream endobj 140 0 obj <> endobj 141 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚‰‘‰ž‰‘%XÜÜÂXÏÔÌPÁÐÐÐRÏÂDÁÐØØHÏÀ¢ÞBÁ%Ÿ+<Ý> endstream endobj 144 0 obj <> stream xÚ¥YKo举çWè¶20–%êAisÊîz’ìÁ›H‚8@è»[‰ZêÕc<òãS/Jl·;“À€U,«Èbñc;ø%H‚þ’@«@UTVÁî|÷ܽWAGU\û )ƒ$ªÝðøEÊ›u>l[Z^ì/ì`ÉŚ㤠;û„¿)`ïh&æs\A ÿ2›–#Joì™^ö¬t`RÒ²1Rs~÷ʬÚîÍÜNï¸õr´S‚vÜøgßtãõܧåì»æxß1\6òTþ©ûN[çÖì,‰î;Ës,ü 2"ƒý „øð–M±Q‰ö@ ¾¯ÏßHoþ«jôMY…Dfâê¬ Ï¥Œpï.ù ECF€+¨2[>vv™’8ë”ÉÅ;Üä«kÜIÅÖÀWôÝ®oçÅd²Ì)‘©üù(WïÅÌÑGI%¨bÕ±IÇ ¾»Á‘ªÑópÔWà®þ“´"È»„¬•_ì0víßÈ^€Ž@0Ä\…¦ €‡†1t¯–àð.ÕZTêRð)9Ǻ\;ÇÀ:ÍN—ËDüx[lÚ™Ä ‚¸‹q„”H¬787»NÄÓæm6÷[C!Z]xšäõ\ò«´ˆA $¹—9TÉn,œój±¿q9v‰l3 ãîQÚEù0â:ÀÁ˜^œ^¦œE¶\²h÷E0( *ór!ÎÕ"—Pȶa¥óŽö7YA»×À‚tfäï®íÇ7,†Ÿõ I•p÷{‚h~lúÖLŒ‰à.ã4Ì;Hî¥IÎ’þë£PÏh x†¹+2€Xv@ Œ¥Îu W°,õ°,×¾ƒ)O¿Ð«6‘Z¥:ÒÉ—\ Å Õ¨•AB Óe€\~;tlÎ0Ë?yÂù8ÀJkß+M‡1Ò1¤ŠJ »¦°%0E‰|>ô“u•g^«¼aª{)Ãz‘= D>È‘ý€ž5b¼âA2x…q\%èØXUFPá²(‰4œ‚B…?ÍoÜ^ï›V*ÏKÇbPè¨È¸˜]Ò…—À!=ÃùÌ_cü¹Fà DŒ ›cAÆ0Æáa<È8ûsšÖ¡ÈÝy3Ž Ý ÑKD¬^23ßV¾Ý8©{»ZÎwërBS–À&–YΖšì§‰e^q_(%¶äËNªáfÏ’œ<ñcÿÌÄ΋¨º1m`k St‚åPdÒuæÌéÅ\Û›šÇldmË‘ËãDL¥3Yp2š¯dfÐ< 8$<_¢ çKê&ÿùòrÞ‘dY˜}ÉE,k€ Á«ðÈ ¸]¯×â !ÑþibW“ÂòÜ_G¯(Ñ®ž6‚[©¨rÐò ú îäMƒPÅëâë,¦áÿµ˜Eóë±(Q²+å6Þ¦ùšô~‰ÛXÓg$å¨â½‡ÍÚL†©ÉÀ…E…-àÃ&8KïYÞ®C¡BçÇ`±x›¥®N1ÇoM‡¸€lÑž’ÿ µˆ ‹.ó€ÍÃ(2–°ØJß³I•Ÿ¯Îà«0…Äò^<³‚RÑWÉ»Måî7 F:AØÞ:ÑeP¥|±WÙ*ænÏÊÝžTǾ/Øóä”.ã;oêºÁÄžÞî*wJ_Wßm%fâ"Îש’+sTD/h@bf„ß üE>‰ºdĸ7‡}˜%9lžéa <ïu¤Œ]»RFø+ «´‚;7ɫٿ Ì×ðSÊeÈ4TÕ,Õ 3¹®×®x}®w|ÞVÈcO“ª‘9mÓý AšBEq ‡ýòH€î¸š3—YÈ ÄTúó¹ßè~†¶õ„»Y9Ç èk`G^{)#úŒÎ4^å¿ WP“+å=¹Ô Ÿ1—‘Ê¿zήÖw†” ®kÉ6M•Eô?,e Óõ]})î5ÁîÕ‹ÑÇt€w[Û¶9A¢T ‹³‡8¾"!×õ`%¿DŽ÷’CV4Nýð*½{þ^¼RÆTXÒYÅFÓ9#–U±iøV­¶.\Á­|qò5Ì3SL¹ŠJ¦Í”­,IðÉÈ}Sa_ßµ¯Lñ[!Š]X+*y\ŠåÝÌÿؾ~‰Ûõ`²ø²«¥‚œÿS3>ÝГ)ɲ}»Ø–Ôú@À‚ /ÃOWv'©ToʯÞ.®@l6¢ƒkÇ5ü¨ºÚ† Ø‚:æ)´>º”I¹ìp“®ÅÒýÃ}ò—_×B½„†ù¶N•Gºñß}øð×Lm)õSQúÖÉq—W›Ê3? ð°-µ`;½ÔJ j 8`;&÷=®¯&!ܨxzy(Ç 85/èd3J&’ªH_œl¬r&ŠŒFz)‰Ã?qAÐ2—ÑØãü Î1„Mëêª1ÎyœåþNE¡˜CúÈÇñÎËÎÓ`N©_®g$)ú´{KÆvÿüü›ÿgìƒ% endstream endobj 145 0 obj <>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 148 0 obj <> endobj 149 0 obj <> endobj 150 0 obj <>/Length 1143>> stream xœí›;H+A†'`¡…‚ "ð•ÂÂB!F´³ÒZ …Øi£`,ÄZ±“Xhe£ v>RYh!$ ¨¨ ¢‚`l„ˆ Þ?9ÞÍÜ<ö•™uï²?(³ãÙÙ™/³3çLŽžïïo檸<. u‰äñxD5¥¿oÑh´ººzpp°Ä'F"‘¹¹9¾"ùýþ»»;Q­1Ý€r>’«««æææœvÈfvv–þãÿ\)€Ð! ¢»š6¹2„³³³þþþÇÇGÜ8<< LèÉÍÍÍÚÚš25Ý‚ÑÄåÈÈoÆ2 ›šš¤²r]ãGK5ÊD`™Š(SÍòòr[[[(Ê¿… ©Têþþ¾µµufff~~^Ö+f% ¯×‹Å0l ØÚÚJ$3h}}½§§‡p(ïAágÌðW~&’¨&ýó[k‡(a$---@`ww—©®APYYÙ××_SÐŒ,???=Xÿ§§§“ɤÀ[ ÃèììÄ«±°°0>>ޱ,--ñ‘Œø2_Ûáw<ÇL ‡Ã>Ÿ—¶d^Nò­²€JÕ¯¬A²åÒ@ %6Eº½½ÒN)’H”tv©¦¦æõõ…`0x||¬²‹ܼx³îî#ºüqöFSÇb ÒÕÕE–•••oooŠ„᱿' ³ëëkò§•?mnn ¥k õƆâ<;;;Øés ›=Ÿïéé‰.ññÀy6œ'mÍÉúü ¥Y´ÇÓé/69Š6-ùAÿ8“Ž$0?¢w͘£hO ÏR”ýW„_–PIÊÂÛ·¸¸è@Lj~3É“ HCãE9à endstream endobj 151 0 obj <> endobj 152 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚±¡±ž‰‘ XÜÐÜLÏØÀPÁÐÐÜTÏØDÁÐÌØTÏÌ¢ÞBÁ%Ÿ+:”6 endstream endobj 153 0 obj <> stream xÚ•UMoœ0½÷Wø#/þrk“M¥REBU¥¶RÑâdiXHÀ›Uþ}maY…*©ö°ö̼7žçƒžE‰ýQ”2”ªœd9ÚìЧ­®¢ É“wˆfˆr’KTT?ðå¶|4ºbÎ9Q,„À—Í~°Æº½wvÞD,ÅÛ¶~Úë!úU|A‚QbéOBso‹ƒ167óžŸ &Q,)ÇK'S¬K s;…Û.Ší®Òà¬Cнnu_]Û½b¸6Þ뮟#¦°ö‘—ØûÓAP]éÖ¥0µ;€/ÏZËþÝ4ž™âÁ”½Z4äÿíKZ]g3åxN‰ÌBÑ7_¯Öô{ˆšëËá*ÊH’ [á)¿ÈO>cgï`O°6+±J^;i•“V$9þÓÕ­/LPŠõ³SÄé’aãL‰¯Õ¹Óõº ¶lf«a±tPF)á4œ‚Ü›~á Œ‘| 9ª®‡‹”‚¤rd,ßǘ„þö2TS‚«ïœPâP›í±.%œæ„¥ó+™wböº‰\»äÃ3üjò»ÆÉîîâ쑜ìݵ8¹ÝZ7zÒ !AÙV' õ®nÊÞŽ€M÷i†½3ˆ»sºŽW[2¯ê4=gÇôv²çé‰~Ž‹­4xA݇ƩcI¶~ðýtá3® t|~b&™{‘ܽ@«ë¥èªC·ðe§‘=«$*•½Iñçõ lT*ýFŒ Ï^Wfæ–s0;‚³dÌGðtŒÌà”ÍÁj‹9xJ6ÑX% }m©˜íÅÜS~îr¹<$)aìÿÆÎ2Ù†ZùÑû«}®{ôNI§ÞðzhûÄîM·+M½)›æ|½.+Xù§ÅQÆ­Y«õ<‡­naõ⚪ۻ¥Gßr:à¦Ñ¥ö8JÍoÏC¯‡G?¿][M_®¥rS ån*󶈮ßÇ/YèöÛŽbÔ8 endstream endobj 154 0 obj <>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 157 0 obj <> endobj 158 0 obj <> endobj 159 0 obj <>/Length 6572>> stream xœíݽr#¹†aðz¬*Of…R6ásl¸Ù–2‡|8t¦ íÌ®²¯Gno×¢ ü7Ð œÓxŸ`Šj‚ ó©IjÄÇþõæA:€@¤3HD:€D¤3FøÃÿ4{ 9ÿý÷?g/ð‘θÜÍÂãï‡úë_þ<{À'Ué,üÄÇr#@Ëš£nó@v£yóËßþþ믿¾¿¿¾ß¹ßhùß—Å•ÓYþ‰eÏ€­9ê6Ä(y{:?}žûæƒp…tVÑZ–=R´æ¨Û<£¤„f¥óÜoô¬GJ¤³D·y &[BO_žSå^•Üt†@¤³D·y †t®¸_ÒQ-é¼õ‰ûå6ÃÞ9 ýãNÕß{ÅZ/ÆAs { Þ í—ç†WO8z#›ÓÙ8;é}yºTNÙo«·çö²»Â†Ë£Ý/½­ˆ®êèþÎÂ5¦sôV çÎß°³Ö‹“4/;ß4Méì=O ÇDÛoâ)ž»Õß]þªhÆE×½­]a>Ãm4Á7"ŒWw’ð`æ;˜ªö«Ó9Ö¤32z_wOO2ç8m§œÅ3,ûee­W˜Y¹„âI-¬òÌ4µÑ™+Ï[Ï:wÎ_ˆî^~©üªÝ9ÿÓ1ßá½}ݹX<‡štî’sçÔ9ΡPËŸ ¹WÙË×¥sj†¹$\^~ÏS+©Ï»T:¤îÑt¼î\“Î5?“2?ЬbN¥n^“Ω;5G¾Ñ•Iç;¹6ó©éÀL-öœ‰ÔôUýC»ôÓ!:þP`Õ§s>Mõïld~¼Eï*º§ ™”ìOçš‘áýö§³û%é|ƒÒ¹¾·S—{B-¿àüC0±ÓÌY$™YXý·£þÜóèy«Qò+ó'þÎF}^›îtŽþ¼©?}&…;?ÍçrÜdÎÑìåâUá´¦îü¥;U>—MöõÇ$z¿õ{ž?ÁÌÜ*ÜSwÞj4§³‰=X“ø®Õœì÷Ÿ;‡÷ž¿ß<ÒY8þ¯à'õ•}©Eþ¯ ü_AD:B:ŸNE ‘Έt–è6Ä()!Ò‘ÎÝæ%%D:C d:ßà#9 „–tÿÙ(Àîõõ5ü1™KgùMÚ¥žÄÎ0é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î ‘¦t~úòl/§–œn+<ê ã©Ig¯Ch C±a ­é Œ±å‡ñîÎö}€m'ã¼â±Gh9ä…él+Ç-¡hz õ†#¥ó¶”ðà÷o_÷ ^•›  L,—£­å±¢÷u~þùçCõYYu&¸a›D Œz»·£UWIV:oÒ;hï+õº³ûV¡ùýŒ&š×î˜pÂíqöH0ÉÛÛ[C:WV]>½·¬‹QN½ÝFCÕU—ΩÉ3éì-5s¦œŸÚåK¨á&ùŸë©˜Ž¦³¡Þnª¡êêgÖ—Îákî˜CGh˜;97S?økÒÙ$ª”z»ÒùÿÜWœ£O*‹­bxWðÖf¥³‰ý2~ølÏPowD:e§¿²ÑƒÓäEÎ@™tæ4y)¤3P&$±Ò(#1é ”‘ÎtÊHgŒG:e¤3Æ#2Òã‘Î@éŒñHg ŒtÆx¤3PF:c<Ò(#1é ”‘ÎtÊHgŒG:e¤3Æ#2Òã‘Î@éŒñHg ŒtÆx¤3PF:c<Ò(#1é ”‘ÎtÊHgŒG:e¤3Æ##ƒ‹cèºÕ\ÎTB¤sdð¶îÌ€í!]·TÈ4 ©:xHçÈàmÝïïï©Û<©¥>}y¶—Só¨mγ¦B³1éLÕÁE:G§úäñx|||¤úÄ+hêûN&¦3U·,Ò928Ú'[“lÿÒ'kš•ÎTÝÊHçÈà½Oös–ýàÞ$¦©Oö'žîåwÄ~¹]ðnbdnè­äè½D'ô¬lX:ß ê¼DWâÞKjÙ #ƒmŸ˜ßÃm“~0Ó'Þ…p°ÉvH8mfªðªè‘̽xG83cÓÙ(¬ºèœ™ú‰Ž¡ä<¤sd°Û'–=£9·O¼Ó“šlõne>Ÿk¤²¸x/á„4‰58--U—™Ó›*?†’s‘ΑÁö@ïüewbŸ:rèÌ%5gý˜â-eäëÎ7«ºš•TÞËjHçÈ`÷ý÷uÀÝ”>)¾|‘¹êÄþ\ÖàwïTu5gñœAG‘ΑÁçþæiæ™]x$Ó'©†ûYœÞê­–>1 ßyzÕÕ¼²ab)|M¤sdð÷o_ócú—:æì€s³ HçÛTÝ!—$éYFͰ†¥FÏqN7æ^Vsu:k¯ºœ&‘Î@£ã‘Î@éŒñHg ŒtÆx¤3PF:c<Ò(#1é ”‘ÎtÊHgŒG:e¤3Æ#2Òã‘Î@éŒñHg ŒtÆx¤3PF:c<Ò(#1é ”‘ÎtÊHgŒG:e¤3Æ#2Òã‘Î@éŒñHg ŒtÆx¤3PF:c<Ò92øŠ5¤ÐÀ* øLîÖ¥µ êT #ƒ·u_±ŒÐ¶;×=jœh@:SuðΑÁÛºßß߯X‰g[}¢Â˜t¦êà"#ƒéxHgŒG:GÓ'ðÎtŽ >±OÇÇLJûå~a?x]Ÿ<}yNíóéSx_Å{ ïk̽«Ngª®sŠª®~æ¥ÓÙk ó9©÷Ëòû¤fžÊûêY’½mt’­¢7©º¥ª®~æ¥Óyö†{™>9º E}"$]T]Û2U]ý̤sW:ÛgUÛå°JÜk÷ÞH;{÷ˆ;Þ½Ó†1Þ³?·¬£Seî%uÞDïî:ë¤3UçmEô‚‘Zuõ3“νélJµ˜* ÌÈè÷xÛ˜âÚ2%žoƒü£ _A{:ﯳռîLÕ…wª¨êêg&O8wv/wö‰;ù)}’_[tBóù +\I´è£§E™%N{:墨ÔJnSuõ3“βҹ²âÛn•ªõâJx$3@ÑY éLÕu"#ƒå§³ýaÞÖ'5=ptLqm™S›b/åÈì!éLÕ-Uuõ3“Î]¿ïœy‚­N¯(í<î$î‘hyõŒ‰vˆ·÷xô^žêÞŸI¼ˆÞt6TÝJUW?3é\ÀÿÚª”ï™}BÕi§±êêg& è“z©fÐ$†t^•ºª«Ÿ™t. O´ 1éLŸÀC:c<Ò92øû·¯W,#Š>Qa@:SuðΑe\±† úD¾«Ó™ªCˆtÊ®Ng D:e¤3Æ#2Òã‘Î@éŒñHg ŒtÆx¤3PF:c<Ò(#1é ”‘ÎtÊHgŒG:e¤3Æ#2Òã‘ΑÁW¬Aò¢Í€¿‚Ôº4¨º6¤sdð¶î+–1ÝöÍà“µóD'U׌tŽ ö—vãû6»ÓßwŒªkF:GÓ'ðÎͨºf¤sd0}éÜŒªkF:GËì“Çã±â½ýr¿`\Ú''~æ˜Ô<„t¶ŽÖ!U׌tŽ –Ö'Ñð.×QÑ'›Äοi«Cª®é,³Oºw/Ó'—"­£uHÕ5##ƒeöÉ€tÞktûw»¼›Üªu¯Ýx#í<îMÜ#îx÷Nócì‘èb¼e¤î¥élžÎT] é,³OƤ³ùÜ!©Ò4N GF¸Ç+Ǥš6ºŒsφHgëŠt6T] é,³O†;»—;ûÄü¢>ñŽ˜³;dG:[;»—©ºé,³O4¦s¦+jîÑSÙ'Ñ;êD:[òÓy媫Ÿ™t>ÓÜt~ ^†›ø3\LtÁ¼²q…‘éLÕ‘Îþ`™}2à÷SOÙŒS”™>±ó¸“¸G¢µ[ã­*º˜è‚S³élþûÎT] 鬥OŽâm5#›QuÍHçÈ`úÒ¹U׌tŽ ¦Oà!›QuÍHçÈ`úÒ¹U׌tŽ þþíëË€>i3 ©:xHçÈ2®XƒôIƒ«Ó™ªCˆtÊ®Ng D:e¤3Æ#2Òã‘Î@éŒñHg ŒtÆx¤3PF:c<Ò(#1é ”‘ÎtÊHgŒG:e¤3Æ#2Òã‘Î@éŒñHg ŒtÆx¤3PF:c<Ò(#1é ”‘ÎtÊHgŒG:e¤3Æ#2Òã‘Î@éŒñHg ŒtÆx¤3PF:c<Òù˜§/ÏÞúÃ#5·:w<®67©º5‘ÎÇê{}¢¢t¦ênƒt>f«àí_û¼/ÃÁôÉ=LOgCÕ­‡t>&ß'û—öˆ½v¯ûü`÷ˆI÷¦œÎTÝ]‘ΑÁáÁïß¾îlÅ{ÿšÏ§áUÆi÷ªÌ‘Ôbn@ÝÛeW§3U7À UW?³ÖtÞ{ímó}âÞ¤²…2GÌo{Òö%{{{[¡O¨:Q©ºú™§sjpXú™—ùúûä–4þªÙ˜t¦ê®³HÕÕϼn:×?ýÌi~¼Â-Ò'T(‹T]ýÌwNçè‘è[.©Xöý™Eú„ªe‘ª«Ÿù†éŒ~wxn:£ŸÆ&»£Æ&µÓ¸Ã¤s×`4иä³vw˜tîŒw˜tÖNã“Î]ƒÑ@ã“ÎÚiÜaÒ¹k0hÜaÒY;;L:w F;L:k§q‡Iç®ÁámíeûGàY¤O®¨: ¬Ù"UW?óBé¼·Íö€í‘——C Å,Ò'çVÖi‘ª«Ÿy•tÞêváýýÝ|}}ÝD§Êü¯Ùü »EúäĪ£Àú-Ruõ3¯•Înçì¶IRjåæY¤ONOg ¬Ç"UW?óéœêœ]ªòÍcª?C£Eú䬪ó ìñxlÿ~||ì_R`•©ºú™IçróDOdLõa„Gì_ÀÉL2×"}rE:ïѼÛš«´HÕÕÏL:š'z‚“ÿS뙿÷¶Mææ-Ò'ÒyÍ‹Z¤êêg&sÍc>ŸkØ#ùæq' fþn¤œ¶Y¤O¦¿²aV-°¨Eª®~æ%ÒÙt¼i“9µÉ_Gç”ù·Õé ï ®Y`Q‹T]ýÌ ¥óþk§î²í3ßRÏôC¾yR­’9"¤é“sÓ™ë´HÕÕϼJ:›ßÛÆ½UxÄ•9é(ž¿ìÂ#&ûÄÓˆyÓf‘>9·ê(°N‹T]ýÌ ¥ó.<µAh‘>¹¢ê(°f‹T]ýÌË¥3jhÜa!éŒfw˜tîŒw˜tÖNã“Î]ƒÑ@ã“ÎÚiÜaÒ¹k0hÜaÒY;;L:w F;L:k§q‡Iç®Áh q‡Igí4î0éÜ5 4î0鬯&»£Æ&µÓ¸Ã¤s×`4иä³vw˜tîŒw˜tÖNã“Î]ƒÑ@ã“ÎÚiÜaÒ¹k0hÜaÒY;;L:w ok/óQö)‹ôÉUG5[¤êêg^(÷¶Ù?Ö~÷òòbh¡˜Eúäܪ£À:-Ruõ3¯’ÎûCÝ.¸Ÿ^ñúúº‰N•ù;åù?¿›‘ù8 Qé“«Žë·HÕÕϼV:7|°Pt¶Îæ©^õ4‹ôÉééLõX¤êêg^"iýPÎLó˜¦Ï¢×Ò<‹ôÉYU—ŠæVi‘ª«Ÿy¹t>úö&q"cÒÍSÿÁBÞÈðãîÃÉÇX¤O„¤ó‚µHÕÕÏL:š'ó‘É©´?ô¡œÞq4Ò”ë\¤O$¤óšµHÕÕϼ\:›#¯l˜ÏçöH¾yÜIòÍSùaãÛf‘>™žÎfÕ‹Z¤êêg^"MÇ›6™S›ü…p°‰¥î+uyŒEúD»‚kXÔ"UW?óBé¼ÿÚiø‘ÉÅ·Ô3ýož|“zŠÊ+EÓÓ™ë´HÕÕϼJ:›ßÛÆ½UxÄ•9¹(ž¿ìÂ#&ñ¦É>ñ4¼+XaúÿF¡À:-Ruõ3/”λðÔ¡Eú䊪£Àš-Ruõ3/—Ψ¡q‡…¤3šiÜaÒ¹k0hÜaÒY;;L:w F;L:k§q‡Iç®Áh q‡Igí4î0éÜ5 4î0鬯&»£Æ&µÓ¸Ã¤s×`4иä³vw˜tîŒw˜tÖNã“Î]ƒÑ@ã“ÎÚiÜaÒ¹k0hÜaÒY;;L:w F;L:k§q‡Iç®Áh q‡Igí4î0éÜ5 4î0鬯&»£Æ&µÓ¸Ã¤s×`4иä³vw˜tîŒw˜tÖNã“Î]ƒÑ@ã“ÎÚiÜaÒ92øŠ5ÀµBŸPuÒ¬Puõ3«Lg÷ÃpÛ÷ U'Ðí«®~f•é „®Ng D:e¤3Æ#2Òã‘Î@éŒñHg ŒtÆx¤3PF:c<Ò(#1é ”‘ÎtÊHgŒG:e¤3Æ#2Òã‘ÎÊ<}yÞ/ØmÜŽ¤¶Ô^›Sœ$3¬ò† ƒEY<©º)HgMÜ:»¢@Ú)s½]Z9©ºYHgMš+ïÄ>1ŸO Ü/ÛîTÒùºRu)¤³&ÑʳÏ"÷/íå}¤÷Ó{ŠjGº“xãÝ{Ì÷IfòpZw¤|¤sô Uw)ÒY™Ô+€ae»ÇSÏ £ƒÃI¢·JݤrIîÈËvë4+§³¡ê&!µª,ñÔYŒ‰­tö‰»¼Ê>Ñbñt¶¨º‘Hg­ú¤x¢QÙ'ù ÅÁ‹ô UGÕu"5‰>;»¢OLâ½—Ê>á9fÛMd¢êf!•yê{0ÿ3zÁ»÷Tç]›7R¸•ÓÙPu“ΈÓr~1Æâé< Uç"á‹>»\é|5ª.D:e¤3Æ#2Òã‘Î@éŒñHçÈà+ÖEÂj¹:©:œRu•§ó¶î+–¶’ Kq@:Su+;«ê*éNç÷÷÷+V‚ñÕ?þ41©ºÛ˜Uu•Hgˆ°}ß·Òªùöö¶—,éŒN³ª®é ö>©ùîÛ’%ÑiVÕU"!éŒñHçKiî“Çãá^ûññQy§Û ·Áû¿áñÊIzî;éLÕiG:XJOŸ´Õ_ê†õÉѫ֡4©:ÕHçK¡O–åöÉÓç?Ö¾³I:÷ßÑ÷¥Ñ¬ª«tçtvÚËöÙ¨ýÒ}êç>WŽÏÌ`bÏm½ ½;J]ÎO^\’FÞYÌSðiö²ðt¦ê™Uu•î“Îöª°7LÐÞ‘üµálÞ󹬽©»‹ÞKqò£‹Ô"|Ž™ú;¿¢ÒÙ^EÕÕl 4³ª®Ò}Ò¹æ,&Së©tGÏt2ešY@êVÅÉ£!\¤:ÑW£GXT:Suî"Õ™Uu•HçÚ³˜š9ëûĽ6Ó°údY¤3Æ#,…>YÖö}ÿ¥úoÛ“Î8Ŭª«D:C„×××CãIgô›Uu•§ó÷o_¯X´˜’ÎTÝâHç²Ê¿™{œÎTÌUWIk:¡«Ó‘Î@éŒñHg ŒtÆx¤3PF:c<Ò(#1é ”‘ÎtÊHgŒG:e¤3Æ#2Òã­’ÎWL‹¥4¤óu‹Á"îŸÎü7YœâP}Ru8ÅÍÓ`‘Î é ‘Î é ‘Î é ‘Î é ‘ΘãéËóì%\+ÕA@%Òsléüññ1{—x}}ÝšŠtF'Òsìé|¿ZÚ;ŠtF?ÒsÎ@éŒ9Hg tƤ3G:cÒÈ#1Gs:{¿Š'-Igœ…tÆ=é|Qð23錳ΘƒtòHgÌqn:Ûƒî…ý*;Ø;âγ_Þ¤n^‰tÆYHgÌqÊëÎ^¼'gÃä­?^U¿<Òg!1Çé¯lDÏ|w^‡ó„éìݼ~y¤3ÎB:cŽ«Ó9“Åá‘̹óQ¤3ÎB:cŽK_w>ú:†ù|~Í+€tÆçþ¾sû‚&›Ë¼+ˆéHgÌÁÿòHgÌA:y¤3æ <ÒsÎ@éŒ9Hg tÆ{:¿½½Í^ÈùHgœ‚tÆ[:¿¼¼Ì^ÅUHgô#1‡÷kË÷C:£é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î é ‘Î QK:¿½½]¿0XݱtþáÇŸ®_àÿ¤3`"Ò$"@¢ÿð1±ž endstream endobj 160 0 obj <> endobj 161 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡©™±ž…XÜÐÈÄXÏRÁÔÔ@ÏÐÈTÁÐÐÀPÏ¢ÜBÁ%Ÿ+)ø endstream endobj 162 0 obj <> stream xÚ•WKÛ6¾÷Wè(#QÔÃí©M»@{ º@MZ›^ ‘DG”v±ÿ¾óÒËv‚>ˆ3g†ß<| ’ †_:(ò½*÷Á¡ ~{ Þ?è ‰Õ>Þ§ )ƒ$Uû,x<þ~8W—Áö»(MÓÐü¼‹Œ1á‡fôÀ¬»gä›p°‡.ÂsW­ßý÷øW`t¢@]LJtL¼÷i•š¯‰D$2`‰&9£ô.Êr>ž­œ(V'òD婨ü|Gc¡ŠR¶£ÖVëŠlk-п6Ï®¯‡sK*þx –ÀDI\QÇ*3›÷m¢ƒß]ðñn˜¢´L”aÛ“³•NUœ\™¼V’«X_›\æáamrY„Õl2‘µ6Kûº½4ö¼Mœ„OãÀÜË.Òeè.cSõ´‡'׋wâ¯\$꺪yóµW;™=Šô^Å)Ä&U ƒâ©òõÎè8¬­Ð œá\ ÌyCP¸‘Ù~¨zá¿‚'Ì”£×4ö0Ô®cš¬Cåƒm=³>…V=+„_>ÛÎúO;Þ¨º£\àZ+êŒÎÛŽw:¤Çváx‚ !8ŒŽÅkŸðN½„Þ3õ)¼ó¨Y¦’òÛ:Á­Ôe†¡È)H¼¢=U‡ö |Íàäº81ÝÝÔ{Š?q% ¸¬ú‰×ÕC]5Í“=„ÁµLnïëçηʫƒ«Kn=Œ Õt²Ï÷‚ªÄ¼@_z2 ¸ö2‚‹¿ÌØ+Ð(ªbÍJ1=4ëíòšä»“ïY6—½"ìåþ:ÙÒb>ˆøA*÷Vû¦ÈBNz­ñ‘ÑÈ¿ëî€BE"ÒE<¡¹‹!@°Ñ­¥ÜDÚóƒõ8<ÖúÞi-ÙÈÒËüP·8Mu¡Löƒõ´­ JèHM©Ìï늛íöÂX"b³2ìš ïõ\¿ Û2›£l_µ²¢|¦øäñ6/PÌ5#B?ÓPnw¥«‚¢*‡¤VTk1Ë‹¯c¯UöuI‚ÁÎïK•oœ_[Šý~†gº¦ovº¸ÕVä6RCÝZ4Úz•"Ó¯¨1ÌWzײòŠk|äˆcÒw7U|±œzEÂE4ÕYèÇ–Ü\2P 7¤=“hÊfXÓ¡¥ UËwô”Œ(èDr›3–_#Z›kÄmŒž€à©&k)üy±y¤'A¦Zð‹2ô-)JnG—qA½MNÔ]4'*òVa@²ö¢©Bã_°GÙ#´öf]DÅN}·ÁÒ_¬%ŸqÅÓ®üÙ ¶¨<¡Se(ÚŽ®›V¾º£gß5twntšžÆF4×Ó×ó>5@ ¹»NvÈîP(E“‹7OóŽóòõ\Ïu>Ó\ý3¨žc/«­ÅÈ¡–Á0î‹$Oü¥ñ†ÕÝü ®™#ÊâtšjÅltШ,ó‹52¹˜ >,àõ‡‘Ê"´åªg&žÏ1¼)$î’ÒtSz£ÃÌ1d…3HIS5鿏XáŸÜHƒN–g៧I_-Â÷cTPå¹Ü:œ}S-aàp)Ø0Îð¢Q†Äu5ze6¤à4¢â|É_ËsPàÕö2rÑR`’›lCÞœmêÖ¯üƒÐJ›ìpÉÕ? ×ý È)ùÒ„ªGÇÜ%N@\ÏeÀ’¨Àªe¬áé 1U®´ä—L¤ ¡Ü&»t©tÎç›ìY#ŠÑ ^® ÔÔMR3¥0·:äχ™€¬5ð¶Ú§ ›ú3µñ†îázüóªNêe±~(·7oy!Ô:‚ž:²¿…ƒ)3° ÌÀw…ø_‡ÿìÊ”/‡n@PMò` SÖH³†)g×÷_Œ¾ýûüíñ€¯½3+åùÆY¼AÒÇilåðódÙñjŠ|j–qÓ-îçùz)'wþM,S“ü{ÿøÓÿã …¿ endstream endobj 163 0 obj <>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 165 0 obj <> stream xÚ­XKoÜF ¾÷W½T TcÍC¯ö”¦I›(RÀ@u‘ŒWò®j­´‘´qÝ__rÈÑJ¶Ø@±̓Ã×9| dÃO™ ²´ylÁO—ÁÅkÈXq\Þ2¤E\–†/÷ö8Vý&ÒZ‡æ‡MdŒ _6§ëv‡ë&«íFeá¾­?ªaó×åÛÀ()€]ì˜(éÖ"§B&ðÙÊí¼£Ôá°ïNM‰c^o"•‡m´ÝX•4÷v$Š]ÕV½mšûM®ÂïaMKØ­œ‹×É–\ä¬Å-ïÏmME¬x;:T¶HÀvf Š¶Í®ëëq éU,M[2­¥µÙg«Š ‘¥A®”äÊ¡kNcݵ@Ÿá°£‘¥Ïp‹ÐÓ~·n#fʧ ºú–õ0Úv[¡"EŒþaÞè 7Ø×à§ž.§ÞÚWó‡ªÆs%—W)4¢0A”¤ÂŽèùc@moð8ÜáÎì>cß5k×¢ ¡’çÝ‹ãº<¸—Þ_º™Žd"…JIãÜ1ËVÄH%R¯ÆèrŠƒ¯!1³Ð‡?ú­d-X§«pÍ@ðY¦ŸfàÕæÇU#´àu ­þƾ¶ ßo”м•Èhº_cTØÆã “Îè°hm¨GÈ<7v{vê]{¨èÎqMR”â¹±:ðѱãc´Ã~›(ˤ €åyYÎ`¸¯ø¶#ÈYj±N:)¾²}oÛ¦…Ncö nt•†w¸œä zyÑõD²…Ì<¸²k; âà:JÆï$Ë ::e%³¿gªó3K#—8N0;ñ8×(r=¹Yç&,íhiQ¦©hk9d¶¶LhÃ!ð¶»þ r’éò™‘B§Lõá݇_Þí>¼xgŶW¢*…ôÀù@¬.pYú|\㟇È|…©R¢ž)D†-xµtîÂÕZE gËïðò¦Ðq&T1wf×ïl[ÿ[•¨lœáýâ@®ªš%ˆÍ¬+8á º'§+~Ϻâ솾u÷Ž*>+ìf“zË•…§i¾ª ‚¬Ž½øU_J)L²Ôï«&ëX¨‰¡}þ:öÕ0e5ÚáË,D¼ÙâÖ1Ǥ„9&™ã&¬Þt¼—L£¼Ãœ ‚“äÛ4ÄL3fF‡.4˜óѺ†íXvyˆÍÑÛ9bKÍR§¤B}°F¥€1u;¬TB‡GR²~8ªþA „HPú1W¹ý˜î—(¯Y[#ã3\Psƒ!B©¸ÍPg‘U™ƒ*œ97à€q ŒJ³"|Ó>VÚ–eˆ‰~‘ÜhéÍh² "9Tdý$ I"nwká™@~æ³h’ ßæ—äC|&Ï–øuk¿$?›ËO]³à[püH@>šEÁÔ¼i@TH¿¹c©|6Ðr- ©ƒ¨‹EòkŶjí+²™ Z½§Ñ %ðعh U÷…þëb;¬ô€Ál<µ¯J$^ à9ÐwQŠ©*¦´ùò\³P‹˜6ͼHm[Žxœ8§yU½Û{t}èh#nIQd‹tÄN©òN=Õ÷Ü5øž 89 t¿YÆe™ÄõÕ¶;€=¥§b‹s¯Q¾:m›º¬¬3òÜcÓ&5 ÐÔ£³*ºcê\{pKB&#âý±ÿ¸+[.›ù©g?KÄÙÙVœqoâÎ-{ý<|ï"Éö퀒]ßWe8H@A¹ aƒO³…®\ÈEåÚ…~kžoA¡æø=Úº¿«ýê¶ò]FMÝÞnHýÛU+\=‡â5Ü¢ëŒÛÙ8›œñHcvŒÊ¨iS=Ýའv RÌCÀ£^”G×v=¼ÉÔ0¤ )>;ŸoÇ‹š‚p‰y‚qÛ ÁóÇéííûžþŽÚ­ÄSÛåÕ`…q«f’µªÔ›ñÞB0.PhÉ ‚lvOXP †]âsÚ 5Èy^X÷ôYø’åK|Áœt_ܱô™¥Y6%8M|?Cg~æá#Ë—W‹;˘×áõH¤5«Â01¢#øñ*Ï=ÅKfïÐ&³PоPkîhdǾ;«jtñ£ño‚ `øÈJŸgR‘ø:ùíZ;?#_”ŸHþŒr³K g_áVé¹öújCª±KتþÔ¶+ŠÏ#!Ò ö¢D>ã?ýŸB.…š¿ÖÏ•¥Ç6ƒ‹I¹¬F­Y"šY!åÏuð68g$Ïc3´ù±yfÁf‹ÔÄixÛÒëÒ ‹ÃÕâ,MŒü«ÂôYXY[îK1E¢æÉ·T £ªlL1«éb æò£ñ¹.@&ŸSz:¿5=á “Ó>w±SòQ×bá ßõ¹kSùÄZ‹ 17úB Cxk ˆ… ®‹C=ÐGé0Òtìh{¨d’‹T>ÙÕî^‘+“ã¿ç’5kp}†Ø¨%6z+â #’ìÉaE7}V€X vä_$îo°/¶ÐCz)µ^]¿ó¨Ó› endstream endobj 166 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 169 0 obj <> endobj 170 0 obj <> endobj 171 0 obj <>/Length 6155>> stream xœíݽ’ÜHvPôóˆOtéѤÁÇcÌñ6èÉ”¡ÇXC¦<®Iy£ˆÑó¬j¶fhä?U¸‰:Ç` Q‰D¢úæÇ,twÕÛßÿþ÷ÿûßÿˆêMR'©¢“ÔÑIjøÓ¿üë¿xvÓ I ¸Åô¹áç_~ýÏÿø÷@d+’úÜG»éåô2æ¬Ë\ÈÐõœ¾^ùëý÷ßþö·ïß¿?ù¼§_8-Z“úôG»qmÒј³.s!Cøk‰0ª{R?Ym-ß…¦¤ŽPÇíÆµIGcκ̅ á¯%B…Ÿ•Ôg—U$u\—¹!üµÔ+üÃOï¿ÿö#Ý9ÝÛ9m“ÝS"©©Ôq]æB†ð×R©ðiÔŽÛ³ü-íÏî)‘ÔTlOêéšbøÇ²â^”í¥™íjí±©ÅP¨Œpó%Œ‡Û½ö¤ØcOîÌZ¶_ËQX¥1©K;§Ïÿð~‰=4WB61ÓY–îÏŽ¤¤î®¤ÎÖưË.[[–ìOê¶Q/äÈC/¤”ÇÚÓ­¤^ür¦”Ôé‰*ß}I}Uá’ºÒsý¡Q=©ëÃ;0©ë½Iê–³ìY¢®²ö>uý5MúoÚ&=Ëæ¤n|´DRwáȤžèðÏÊžz:ßêk„Ò±ÙŸó ›’zöZ2m“]4x!‹w?ÚOW(ýV–Æœ=vÕµd+*=EéŒ-ãO;¹küILi¨-I½À)IMÅ1÷©Ke:¼/µR%µ¬+U¸mù¶8ÂÊÈ#\ÈlOi`‹§«?Ùžëé“=ãâ7eq„‹£ÍXzff‡›Ô--Sí÷©‹gUXKê.uKRoÕì\þb`sRgÿÈØ~^¢yTRï'Õ½AeBŽÛ‹¥Ým7 êA0íªžÑCy õœ Éž·ý9/]ìâQéó0{*Jݶ_KéºJÛÇPúÞõ•ÔÃÒ³]9°ñ¼Dão3Ú«ü¡‚ÿ]ß*Á¯%B…ûE*$u†¤>\ðk‰Pá’š I×e.d-*\RS!©ãºÌ… á¯%B…Kj*’:æÇsÀá‚$õó?ó…8>}úTú/s9©O¯`€Ë«¿¸‘Ôç“ÔÑIj€è$5@t’ :I ¤ˆNRD'©¢“ÔÑIj€è$5@t’ :I ¤ˆNRD'©ùã3|ÇíÒ‡ù¶Îïã>xg¥ÿñìé0Z.sÃÒ®6<ÙÑFø`e‚Ô¯n–¥€ØŸÔ;£gzx¥«ûC‹Á-%5u’úÕ5&B¨¤^lÖcR“•þìKÔ¯®¬÷ÙÍ„Òþ!IÉ´ål{È…Qé¡UãL“®”ÔÙQ•Æ™v>Ý3¶œ>ÙN/°žÔÙg2û,qU’úÕ-®.g¹SÊåìžìþU÷1f{îÙÃKãÌö–¦>ªJF§Ý¶4®˜½„–~¸*IýêתC²N,^ZSO{˜írkçÒCéIÓ®²c(Ejv£ÔãT•‡6'õâ0²ÏW"©_]eí6Ý^›ÔõoYG·4[\¿—.³%©WíÙvxËxVõÃUIêWWYÜ¥{WÐk“ºX=ôîGûžUÏáÚñHjIÍP¸á°xïbÖ²tçaÚ¸ÒI}0³‡f—ž¢ôB!{™¥K®< C’Ôi³Ò-Ù«[|±2ë¿ôqU’æž°PÝs ëè$©áOX¨u Iý‚$5@t’ :I ¤ˆNRD'©¢“ÔÑIj€è$5@t’ º’ÚûÑŸ¿ðæ¡¢'uå­/!•ÉCu–ÔPå­Vá'u鉇ܛ,§o¦üÈQóZ²oH=LÞK:û®ÜÙ '9ç'õméί_>ß7Jï=Ÿ}O÷¡üvò¥Éžîüå/yÜ¢¡±D‡Bøf?Ó ­FÅym;K4DRß®a¶sì¶ò!FÓö¥\žµI;¼]ÂÎñsºoß¾=:©Ktñ³µÆÃ³Ñ¬8¯j‰FIêR?‹7—mY¿oè~âÅÔKèÑý×-‡ès/o‰ö”Ôéýi›U{̇+91©K+†–¤ %­8¯çúI=¼¿C}-¹8?Q¼´.’z¨~ð´â¼ž—Hj¨;÷îÇ–Ï/BRC—ImùüR$5t™Ô¼I ’šè$5Hj¢“Ô ©‰NRƒ¤&:I ’šè$5Hj¢“Ô ©‰NRƒ¤&:I ’šè$5Hj¢“Ô ©‰NRƒ¤&:I ’šè$5Hj¢“Ô ©‰NRƒ¤&:I ’šè$5Hj¢“Ô ©‰NRƒ¤&º+'õmÿâ±æÃyI­Ditñ¤¾¬ràmЇ €Þ˜ÔJ”×Oêïß¿—¼RÀ‡Ÿ>ŽÛ¿ÿöcçÇ>êŠc›ÔJ”E/šÔoo,;€Y½*ßË ˜ÔJ”©WLêÛ¸ýk0Š–ÔJ”™—HêûòäÏýc ›¦Áýõætûn¶güò¶1;dÜS9p6’µgÉv8kÀÌéI} ;’éYJÃ&ëU’zøGÝOçÀP¾ X™³´ñPi·•®Ò‡²{*g™í±ò*‰ÔC‡%ší³RlÙ6ê³Å %õh\¼; f+‘–œ5¼_V”ryñ,i‡æ@]¤õR¢•>g]ÕÛ¨ÏE/‘ÔÃûW”cƒ§Áª=«)¥>ÛÛ,žˆÓ“z¸\‰¶Œ¤ñ, ¯“ÔÃ?˜>mpÊ4X¼ÅQyèÀéÇT„¤®U¢-«{+ëv/”Ô©µ¿¬ZyA—î©LƒÒi™.6®¿\Ö4( ’Ô©îJ´åîÇKülçŒ.žÔ_¿|®»ÏYXn<Ô‰I}™]%à‚»rRß:o9|ò˙Ã=ç, ç%uï%ºåó6WNjhä½ôNRƒ¤&:I ’šè$5Hj¢“Ô ©‰NRƒ¤&:I ’šè$5Hj¢“Ô ©‰NRƒ¤&:I ’šè$5Hj¢“Ô ©‰NRƒ¤&:I ’šè$5Hj¢“Ô ©‰îÊI}Û¿³çULÅ~øé\:c–í×Å“ú6²7º]ÿ!×Â)ÎýÄÛtF‰víúI]ùàçý_ù3¤‰/ìg“H‰vMRÃ4蚤&8I} Ó k’šà$õ.oo\àP~úøûo?Ò=·Ç=Ói{í’I}+Îû†½I½Ý}&ì™ã~¥®ë%õ¸†·•h×$õvI=¼¯òq{Vúf‰®—ÔS‹I=(Ñð$õF÷êo¹ûq·¸H™Mñ…ç¸m’<ޤ”hl’z£µI=,­PÒi0[×XÑ<Î…“Z‰^ƒ¤Þb¬þ‡®©Mƒ§¹jROïV+Ñ®Iê-ÆŸªß{Ð4x¾K&õ4¦‡C”¢DŸORï²ó·ô²‹Óàù®—Ô³˜”hç$õ.û}jÓà™.™ÔÓ/7ÿ–Þ¸G‰žKRÀuízIR¢]“ÔÇ0 º&© NRÃ4蚤&8I} Ó k’šà.žÔ_¿|ÞÙy;Ó _'&µ¥Å•“úÖùΞ×2 :uVR+Q]9©¡ÑYI $5Hj¢“Ô ©‰NRƒ¤&:I ’šè$5Hj¢“Ô ©‰NRƒ¤&:I ’šè$5Hj¢“Ô ©‰NRƒ¤&:I ’šè$5Hj¢»rRßöïìyS±_'¾?õƒÎ˜¥Dûuñ¤¾lgçn×ïmÚûuîg¾<è¤3J´k×Oj}Ä"ŸÎEp’ú¦A×$5ÁIêc˜]“Ô'©wy{ûã‡ê4øðÓÇßû‘î¹ý;î™6HÛóh—Lê[qÞ7”èHêíî3aÏ4÷+ýs]/©Ç5ĸ­D»&©·kLêá}•Û³Ò7Nt½¤žZLêA‰†'©7ºWËÝ»ÅEÊlzŒ/<Çm“äq$õ Dc“Ô­Mêai…’NƒÙºÆŠæq®šÔí/ûî”hX’z‹1 %õ5\5©ï×Ôƒ LRo1þTýÎ4褾S¢aIê]ŽZS§Û¦Á3]/©WýîÇH‰†%©wÙ™Ôãv:=Lƒgº^Rk~Ÿz¤DÃ’ÔÇð`]»dRÏ(Ñ®Iêc˜]“Ô'©atMRœ¤>†iÐ5IMpOê¯_>ïì¼iЯ“Z‰ÒâÊI}ë|gÏk™:+©•(®œÔÐ謤†F’$5ÑIjÔD'©AR¤IMt’$5ÑIjÔD'©AR¤IMt’$5ÑIjÔD'©AR¤IMt’$5ÑIjÔD'©AR¤IMt’$5ÑIjÔD'©AR¤IMt’$5ÑIjÔD'©AR¤IMt’$5ÑIjÔD'©AR¤IMtWNêÛþ=Gfæ謤V¢4ºxRßF¶³ó˜nO÷!Ow'&µ¥Åõ“úû÷ï;ûèv±¦ÁÎMj%Ê"IÝ%ÓàX’úpJôX’ºK¦Á±$õá”è±$õÁÞÞþ¸äé—÷qç!{§Á‡Ÿ>þþÛÒ—-6ò¸Á,ö¹Ù+'õ)%ª2×’Ô‡ÉÖîlû¨=íI}ûw¬˜çC©ŸmýœÛú?=©Ï*Q•¹–¤>XZ²ÓmI}Hÿ’ú$õþþ%õÂâLƒhI}«›±zÒi›û—ãöØrìmzÈtÏlÖ5¶™žwv®ôÒCÓ+š5˜u^礞žÔ*³¥2G’ú`ý&u¶M¥evÏtK›–!-UšÞÙ6Ùn%õXc“ú•+s$©0©‡5Å×Xj£çC¥ÛÙjäª3áÅ“úEÛøE•9,eô¤>X̤’—l‡¬\Ò³dÏ»vå2ëdq´ó!{–»WNêô·•ž™ÔƒÊ, uFR¬¯¤þ»­¶¶ÔŸkZ5Èì”xÙ¤žÅô&©U挤>XºB¹oLëxÿžý¿O=› •ù0>;vÈ­ƒ¦çª·Éž±tH:ŒtØ•cg“?}¢^9©§_Ž·ª§_nÛ³ù÷©Uf–¤î’?;ÖË&õã(ÑcIê.™Ç’Ô‡S¢Ç’Ô]2 Ž%©§D%©»dKRN‰ëâIýõËç‡eèĤV¢´¸rRß:ßÙsp¦ÁQÎJj%J£+'54:+©¡‘¤IMt’$5ÑIjÔD'©AR¤IMt’$5ÑIjÔD'©AR¤IMt’$5ÑIjÔD'©AR¤IMtWNêÛþ=ïg~váÄ÷§~ÐÛ)Ñ.\<©o#ÛÙù·'Å›©wáÜÏ|yÐI[(Ñ^\?©Oüè#PÔ‹—ýt.%Ú Iý@¦A/$õY ‘¤~ Ó ’ú¬ÐHR/x{{»oÜ.dñ¡Ùžú4øðÓÇßûÑòP©e¥Vé:©•è+Ô5·²ž–øt&¤¥{6Oƒm ÌŠÍúMj%ú"$uͪihôâE’:=P‰öBR×Tji¶¤$u¶s%‡¤®Ù6 Æ/Û§ÁL€YõÏ wÖ`Öa½¥izµ¤V¢Ý‘Ô5¦Át{Õ‚eº³4 ÆeÈð~!3ë°ÞÒ4H½TR+ÑIêšµÓ`ÖæØiPjÖÞᬣ×Ij%Ú)I]³ùëw§Áôe,£Ij%Ú/I½`öû§³êŸ=4=pík¦;K þÒrÖç´å0™,©~“zP¢¯AR??ëE×I½‡í…¤~ Ó ’ú¬ÐHR?iÐ I}Öh$©È4è…¤>k4ºxRýòygç;™]81©•(-®œÔ·Îwö|Ó ¾³’Z‰ÒèÊI ÎJjh$©AR¤IMt’$5ÑIjÔD'©AR¤IMt’$5ÑIjÔD'©AR¤IMt’$5ÑIjÔD'©Ï1~ˆ\ãç1g??´Ô¬åì¥O·kq½¹“Ô)%Ф>Aúù¡ÜÓlÕ4¸^ѧ$õŒFRŸ`sa8 †÷k¥é—ÛNÚ5I=£D£‘Ô'ÈÖøâñþå¸}o9{i9{e:¶œv2k?=c}T:O»¶ì—¤žQ¢ÑHês”n¦…;Ý_zI˜mœv’=ªtHã¦-öl=œ¤N)ÑP$õÉ+¸´`r “Ó`:¼ÆiÐ;I]¡D#Ô'Û0 ×Ó ¾±ØØ4ˆÓÿC)Ñ$õ ²/Ê1 †Âb§—–½ô8%¤>LJ}7ë/-³³³—&ÆÚ±ÍZvJR§”h(’úâz_J<‡¤>‘m!©/+û¢’,I} %ÚNRƒ¤&:I ’šè$5Hj¢»rRßöïì™Þ5÷YI­DyZ‰†NêÛÈvvN¿nEÙX`'&µ}eÏ,ÑèIýýû÷ýĪRùù—_{Ij%z‘KTRó$·oñ­`ZZ~ûöí^”’šgŠ\¢’š'¹OƒÆ²–Ô<_ä•ÔzXcÿ·oïÿ¦û·Žzʼn¸‹< ¶õŸ–èø­ß\¥§Õ¥Æ$r‰ö”Ô(ý ®=Ñ#ÎÕ£ÈÓ`[ÿ¥ÝóíÞŸÔŠm³È%*©#©ë¦ÓàÃû·“¿ßA¢ë¤Þù½–Ô'Š\¢}'uöõæxŸdºÀI6˜~YéaÈÝu™u8;Qi»Þùâz4[°|H>ûcÜî7©‡j…´|LJ¥:™öŸ=ãb±Íú­¥‰\¢=%õøP¶ÚÒRN—!-í§cH'U:U*§Ëže±óµƒìEúÒ²ôîÃWJêìwsXúާ=TZVj2ÛI¥Ù‹‹\¢=%uËšzm¡gPYZ&§Ã¨  tÔbçÙKHÙìMÀì»÷›Ô¥eï¨ýâl´‡rzvI½(r‰Jê|ûR›ö¤ÞϺR|¯R¿"ÿ¸f[ÿ-?QÜV`‹¯Õ²½-CR×E.Ñ‹$õøŠrÿÝC’ºt÷ãðt$ò4ØÖËoéõßp÷£þ‚oèöÅÙãD.Ñž’zúèìõ]Z…CáVàÛÒnÒ6‹K¤lã·äGF•Wµ¥6éú]‘§Á¶þ닉zA–Ú Õ[pé)†\I,v›]ž¹D»Ijzylë_‰^Lä•Ô}ZÕ^Ród‘K4tRýòygçt-~R+Ñ'©‡Æ·ôæÚ"'µexV‰ÆMjhtVRC#I ’šè$5Hj¢“Ô ©‰NRƒ¤&:I ’šè$5Hj¢“Ô ©‰NRƒ¤&º‹$õÎàÑIý žyÝ'µ?ÉåKj%Ê!úNjê$5@t’ :I ¤ˆNRD'©¢“ÔÑIj€è$5!¼æß~úô©4÷`JR ÖR}îÁ”¤&„¬%IM;IM/XK’šv’š^°–$5í$5!¼`-IjÚIjBxÁZ’Ô´“Ô„°ª–>üôñ÷ß~Ô÷´> endobj 173 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡©¹™ž¥XÜÐÈÄXÏRÁHšZš*êYX@”[(¸äs!+ endstream endobj 174 0 obj <> stream xÚ­XYoÛF~ï¯à[(À\“\ž-ú¦u€iDÔEBK+‰0E*<|ô×w®%i‹hZ 0`î1;óÍì·³³r¾:ãÃ_ड“&¹Êrgst~Z;—W¡ø*÷sg½s‚Ì ´Êcg½ýÃ}u(N½iWžÖÚ¾_yQ¹¯ª¡ƒÁ²Þãxäöf³ S÷P—_Ó­þ\¿q¢0P Î'%aHc—WÚ "¥£Íx"âE€$$9˜[yqºLµóÞµû¢.ÿb+iì¾-N¬û—µ3ùâ~âxqž¨0Bw.¯Žv~nœ÷‹ž&_¥™;³ [¡ÖµûáÝÛîzŽRF þMhV^˜¹[hvøMÝ ÇF„ë¢zììÒþPô2ÞntÍÑÜËp궦*z³%'}ðL«€w¡o$€ñÜ­’H"|+ósoåk™öަ¨…N Vlí“—šÿ#4’ƒúÞ À#K¯WYèšÄžþµ94µ!ÙPÖ„ó¦h«G òÌï.°CÈØ/ÈU’΃p(dŒd£âµAd©Û“&¹¡-1dºCGcŸÍÃwoêæXn¸3mö®ÝΈâWôlÀNèò ÁÅ;Y Äðh=yÉ­J1øº©†nÒìlOr‡’;y½1@5ÜP·æeÏí¥ÙÔ='v´e¹MÃa(JÞåiŠÑìÊã©eæáTÇ}Ùˆe¤, õÖÜŒÔ@y)3 °âŒ–[+ 1d‡­é6myý0@…oÁ<Š÷eUÜ-ŒÀìAæAŽ74·v üzä¶ðé‚{ç9ñô^°Zˆzª3äœ<Üt 7Å7Ò±»ÚÖÍñÂ" ×QH%¡BA@é-MÇý®*÷‡‘y¸r×6GlǤ('Àl£~¾¸Æô<_T @Gr²p夣™Öxr.Ä›qº¾-7= ÓŒƒ‰‰Û؃¸yÛëÀ¥¢âA>ø$\5Alš‚s9ö€F%Æ3Ìà`ZU'æ^Cg‹l6¢Eº¸þžNÇ›gô©ÍL´½U_ȯósÌ8˜¹Áä¸f8Òš¦Ýò•e¹ 3íkÇòLÓܽ?”첹ïDט(–¸ß dD@ä‚3zkº¡¢|wœB ~˃“oÃÓ {‹Äî­ÍØ88eì æ‚yؘ“Ø@¦ÈðPWå-¥pœŠLg°GÅ:ž)öm´`¦–4`D’ÎjSZ.ï4è"Ã…œ£1\JYØ›zÛñZÚ²þNz#«—.ÀòŽ|€ƒuô#QÍmúƒäŽœ)§”#ùâ_möm3œºJ¸¾¡ôÕ±ò]#uܘʄ —WÑì¦õb•çs}×~.ÜÈA¨’X®äû$[[XYCuÓ³iÎC¿/«ÊÊQº3,4U”£úÃ8¶úßÐ1€^”‡#†ò†BOÎmÈù„)Ðç ¡KpѱÀµUžÀ¢]ÁTàë¼Æ µÆjAÕ"PÛäiÄEN;P­òX =IÀd* ~\P)ßê‚©ŠÑÞ-¦ 3aW§*KŸ¡kË‘'<Íሧ`PnÂH§éD"Œ‘.{s”ö´Ulð¤D´º,«æJÐÍïkºå8™¯ƒÕÅÙuv[w0×J»•K»ª~”ý&òízõ?ównù ñ(íXn‹ñÐ[?ÇLÂBíPsæð•Às#ÈT>«$B8C0%ƒs€/ªdœ®€P{h³>LÀ99òÐËÊtîL¬•å囿æ·âhù–ÍÙ(ˆÔgÈRŸ_Ü{ŸöŸ_~,¼O…êúÅ8Ù%/0íC…Ët&X_–¬À!³/ 6° UG”£ï3¸Ã8?Îj_`Þ–.n$6<ÅÚÜf‘ÙKs¤½-¿ÐÙ°b mi¥Aòò_•DJ—ÁmKïÇ aj&B,b dX©Ø>Ø>.`ŠUªŸBC‘Ÿ>«ú–,èéÅ÷éÛú¡ÖjÍ nc)‹ð±’Oï³±ôêX–_ ðáÑÅs'Å`½å€‡Š%~?ñ·—á¬Üã‰b»¥Ë›’ ôùäÈkôzÙG¨ê­j_ïü C•££¿0Ãk`?æô%#a„¿&ˆ‘âÛFðG[Pã¾-ûÞÈgö:“‡Š}Ã$ל›¾á,NUÇ("5¯žÝµÊþòþ»¿ÌD›d endstream endobj 175 0 obj <>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 178 0 obj <> endobj 179 0 obj <> endobj 180 0 obj <>/Length 4188>> stream xœíݽ’#Ç•€ÑšçÑD,=Ñ& > šôí­¹Æ>† ™ë Í]OŠž‡BZd±~‰¿{3 çŒt¡…®ûu5z†øô¿ýï@’O* H…2©0DûÓü9ñÑÿù÷ÿK|tÖTBœÛÁúù¿ÿë?ÀÂv…s¿W·›ŸÍ£¬yÓadêþXÒ——~)ú—¿þϯ¿þ*Äýبpú÷êv—ïê­yÓadêþXr—×Ãs¢Â½YV¸‡³¤Ýù|úúõë@kÞt˜™º?–Üåõ0_*ÜîÂadêþXº­ðço¾ÿñ2˜óÛçÓzºý¾_ê¨poT¸ ‡9©ûcé¹ÂëÈnÞ¸¹};îMS…×ߥ7O‘{ߨïsu¢*+¼û.w¿|üÒٛûW¾i½·öý/¶l?–g-à&õsæòe]<ç—+lYðƒnül ÷¦µÂÏ:Ú¿™·ìöñ ·­úÊȽô@*WCOôÈnSáͯiûwAæ>™®ì¹þ©‹«×5WÏãû–½¾åuò>žV/†&VxïÆy…ïXð­¯ _]Ò_8îÍžn~þ-~ [Ÿšõ×¹öî»ùsâtW…?]®·Ù³Ä¹z-ÖþpõO­¿”{kÞ¼ïMDzyF­bï[Ö¿ÞÉ­OõæÞ‹rûµpã*|7¿.¼8éç [Ÿ÷]BV®aï»ìººÂÊÊ{8Å-{ »úpõçasÏõß|Ä«_”«+¼ºÚÍ;î=3íË›?Û{¸ybì=âzµÏªðü*<ºç\ /.šÎn׿Uêæ§.¿®Â{{È=õòêÏùÞJꇳ÷ÌÌ7Þ{īDz8ðË-õ¨-ޱ¾†ÊaÖ—·ù„ÜQ὇ž®ðú ¬<ÖîÍ“+|õü¨ŸÓëo~êr÷öKÈ;*¼·¼ø¹ZÍíW²wÔW÷¿·†G®…ë4®¡^ÃçV¸e˹[+<]ûžW¹ãîÍ«*Ü>Ã{?¯ú‚ë‡0m]6fÈzËÊÂÚ¿-»ºÿ½'çî×…[êvǪî{ª©på0{øûø*Ü›'TxúãiwÞ 2l—¯~j½Û©íùúÏwUïïT}}0à@6·ý9¯\FÕïµ~OÅÞnÛåê•ceµWmó+xuy›´~¬ößt-F…{óîÿvîÖŸæ^¤óov“Î¥Û;F…{£Â*üd‹ «poÞ½Â8ÌLÝ‹ «poT¸ ‡9©ûcQaîM©p‡o‹ÇÓI…O߇r—ñæ¾|ùrùFø‡ §Ÿ‡·øqD…B©0@&Ȥ™T “ dRa€L* I…2©0@&Ȥ™T “ dRa€L* I…2©0@&Ȥ™T “ dRa€L* I…2©0@&Ȥ™T Sf…?óíü—‡¾|vqKe?wo9_CãNµéMw¹c·À³$Wx>ü-¨?b?1Ú[É‹* $Rá µ¹°ó·®¹Ûcκ«ðù%‚Kn7^¶<p¾e¾Íüö½-÷0¿}q¯Ëç+iÄöõÏ÷¼ùÍ|Í7í|ñ ,®ò¸ÀK½¶Â§½¯oüáûïÎl¾.¼èÅ:›Ú¼}¾óÍ ÉÊ%çæ½ÖkÛÛòÖõW¶Ù[Õ´SÒÍCÞ[ye›½/°ðË/¿:=xé/xϺi'¬{o_»÷&¶Î·QÜ®CUø´ñâÆË}÷^žÿÊnZ½ÑòúÍ’§­|O¿oãAéãããÕn<ëê¾úÖ×ηÜtÖ°Â{W*¼ù.ñó÷^Íðb_ÿ^ý—¯žuó?V^m¸úÃÖä|ÇÃÕ¸‡ñ*¼~Ía¾ÍM·ŒÎ%Vxï|K…§³Ôù6ÞÝxþŠðæƒWGbòÛ¹Ñ Qáië/³¯z›œoƒPaÿÐŽ"÷‰G¸ì— «0ňvÙ;:VaŠ+ÌèTØ»Òa…u‡§ÂÎçOŸ~ûí·øyXŸî›7Ö÷fNF©ðÞY×òE¯8ðY×ó©®ÂÍÃiNÿ­Wø¾_<>-ŸíùÔL1D…u£Â·ÍÃùä|ãy¦ÛçaýÜæ-ó{U®86¢¾€ù§ÖkØÛlsÁ‹ÕN[?¨.néyû¬pûY·8aŽqÖÍ·\œf›çáâƒË½º=ñTøæy˜~€ù0Lû¯Ðmþ€¶¾qï–Ê<Ìes›ÊÖŸ­lÖ¸Úig’×·f^½ÿw>ëÖÛ×ÏŸÍm†8å&¾o..W(ñóÐøƒÞ‹*<ßI¥ËómöVØ•ž+|Q9ëöN§i´³nZ]ªïÝ«¾Í!Vá›_¡[\œU*<ÿcÊ<¬°¾ËÝ×ÂíÛTÙ>+<9명­l³·Â®¨ð=¿'™¿Nw¶9{µjŸ‡é/¢Uö¼¾±åŽWø¾#êv*º­ðÔvÖU¾è‡9ëêwÿ¼zqloUýPáþÍÍJ…/·ÌÏ’Å-•fU®4çû©_´.nùÜð{’õ‚¯ÎÃ|‡ÃÔw…×Þê¬Û‹ïÞ!Ì7èù”›T¸}ã¾ÿ®¾Mû!´œ¦-ŸŠ×Õb^¡· ßzÖÝt"rÖÝdÄ—ÂT¸iãÓòZ6{n…;ù6¾¾Ü8°®*üÎgÝÆ]¹ û??PtUá;ô|Å—«çgF…U˜bô O[ÛÁ{Nð¤Â*ÌÜ*ÌpT؇ôê ¿hÏ íM+|zÄŽ£z]…uìyÇ  G…2©0@&Ȥ™T “ dRa€L* I…2©0@&Ȥ™T “ dRa€L* I…2©0@&Ȥ™T “ dRa€L* I…2©0@&Ȥ™T “ dRa€L* I…2©0@&Ȥ™T “ dRa€L*ÌNçRö^èË—/—ùá ©0xʹԧÅüð†T˜¨0¦Â @…90f*Ì©0PaL…€ s`*ÌT˜Sa Â˜ 3æÀT˜¨0¦Â àîséó7ßÎÿx99û¡Â¨0x¤Â/*ï³ö¬Â¨0PaL…Às+|¹qþÁùS—·Ì÷sþø¼ÁÞÝÛ©0*Ìžòºð"£Ó¬§ë¶߲þÔM+TaT˜<ý‰Í+Ù³Es×ûYWxq÷›V¨Â¨0xu…+Í]ßR¹¾ƒ £Â ९ ßúúÃôÇëe¯Hð fÏýûÂwüvnªö×oçx„ 3ÿvŽSa Â˜ 3æÀT˜¨0¦Â @…90f*Ì©0PaL…€ s`*ÌT˜Sa Â˜ 3æÀT˜œÎ¥ìU¼Š ¿9f?þôsö^K…ß™ dRa€L* I…2©0@&Ȥ™T “ dRa€L* I…2©0@&Ȥ™T “ dRa€L* I…2©0@&Ȥ™T “ dRa€L* I…2©0@&È4@…Ü@纮ði'î ýV€:Ȥ™T “ dRa€L* I…2©0@&Ȥ™T “ dRa€L* I…2©0@&Ȥ™T “ dRa€L* I…2©0@&Ȥ™T “ dRa€Lµ ||ä- à]lWøÇŸ~Î[À{Ù¨0ñT “ dRa€LÿóÜ8 endstream endobj 181 0 obj <> endobj 182 0 obj <>>> stream xœ+T0Ð32²472T0AdNr.—~¹Bz1W¡‚¡©±¹ž¹ XÜÐÈÄXÏRÁÔÌXÏÐÂDÁÐÐÀPÏ¢ÜBÁ%Ÿ+* endstream endobj 183 0 obj <> stream xÚuWÛnä6 }ïWøÑdßÇîÛ6›[ ØKóR4}pl%#Ôc{%;—ýú’²ãÉÌ"@,‘E‘‡ï»y!þ"o{»¼ ŠÒ«Þo·ÞåMìEaP†¥wûàE…%A™y·Í?þÕ¾Fe6Û$Iüô×Í6MSÿª,„º{$yêªÞÄ;ßé›oÿðÒ8 à.d'q²mæA”ዽcÖ|ê6Û8‹üÁ¨'ÝO–f±ÿDÞ”±ºï¬èûùº/0Ë ¿ïÚWYÑwjÛèƒêhMÕŠð¯ÏºåÏâPÉÌNÀÖ›Q5ÎíüÛ½’UõdŒêhÁ(QGiP¦ø$;½ Îst„ÏH>¦Hµ83=üïüfª‘˜oâœBC ÇÁ“O >àæýó Ðä\IšùU×Ð ÷÷Z™ÊÈ-èš}àžêåžèâØçɈ}oô£–½àf²J|¨ßv¸ó­rÊ«=Å;‰k5ºÚà‚F¥•eq·)ã]ÙŸàwèGý´É°ðcATú÷äúUÆ‚bú²Úð8òÇ^dcõ™*1­ñ#WNÌÇ E³§ÁôrãÊŒšá‡p¶ºç{éǽLÝÙa èBt‚.+\é i¤SVP:iòRD ˜Àe]÷‡¡ÕvÏ'/hw¨_E{F©±£(Èp¥Æ0­äƒD—ÁqÂ÷…3íœïÉÒò“`–”œ™ÆUqZÄþƒé2Z àÓIzù>Nºq:gSÔ™†ÅáJ]Ï7„7ÉQÇÞXó9iS€0¥bQ†Ä'Á¿1@#¤ÌhHŸBB¦9㯙:Ñpµ¾6ÕXY5’£$œS¥ôÿüíãõ71—½s½’Ó=©¶qTÆ-µ\Эó sr. SŽ èGiïNú¶Ÿ5‡'þƒ„ÝtoØÖìŠ3x’´^“5VËÞâ·-ûiD®½Šµ,ügݒϲ¤ÜT"ãÄ&IÛÛw¢AêÊZ}ß*qÃD6.ËwP†°Ù¬(xëq EŠNÑV㲊¬O"·£™êqâ«Õ¾cèÄe-»¼IˆbA{Ôüà$ÞyÎNÒ E5ç±ÿ1Öz`Hw`B”&KÕØm({HžúPŒ¯V ï]ßzowEø·K³ ,¨é^Þ¢ÔûØ{_Ïößm•A¶ã V{Çeîöæt^.ŸäËÞ˜í@Û_®>“jVòyF sß„ Ì߈ô¨‡‹’“’ï 8Md8µLâ9Ò_ƒÇOo€ê uœƒŸ? ²Ã,\Õ£+tLÕK*T2aÒÀ·†öU¨³ÕÙiêξsgÏéìi¯ÎNVÌUø>ªNÍ;á}a¹_Ÿ Óõi×–ÉÖAË$ ÑBÒhÌoÀaj’·OìÈ=ÿÛôãG/æw~†ÑÝæ'ýûš˜Å>µºÒÀ…‰Xˆk'<•£ÖÜ[¥AÕGSu÷s@¯í¤zèEâ竤iæ«JAfx…@õìvr+ä3°€c£_–€Î7òg£ÇQu’ü\öô•iu§*#";DÈ›?m¸“ÈV|o¤”gU=öÆyB¦´|;ÊU¦Ü«€9­HNOÑ0`ÀLo' àÞP 0^Ö[>PZ 긴`» ª}@ ¯Nù2´•¦gk’Í]b£ eaŠÂI¹ppý↯b½Â]/¸§áßl СesI]ÌïGpÙŠ]vePæî]>ëÓ•¾²ùÙ~†±³8â§0Èg’оKÞ`´ä ÆuÕÉà^Þ^21ê}!pN(çªmõ`{ÝHË©¿L A§ÇŠ‹(ˆ“wç:ŽÚ)ƒh!+ûkY‚~I$øæ®oyïÞ=¹(C†ª¦·JZ”òû„o8LÖi‹i}†ÀÈ3—@:÷E Ú¾{TÖi‘aN/ïó•Ý‚ÓÅÏžye‚wIÝS’ÓxPZž«#’Ïo4¬×.A‘B‚"1S7$Ë~« ¶˜±+‹q¯Í™RÖ­.>É¥Ÿ¹fN»§_rv1EF—‚þ|]Í\@f ÷±“N¾ÎIâr˜FsÓ˜s˜ì–&©!Tä‰á(Ýþë/ÿ„Ö+K endstream endobj 184 0 obj <>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 186 0 obj <> stream xÚXmÛFþ~¿Âß"±:ï3ê·mn›nq]´Àöz@sèɲ6 K®$'Ù_r8#K¶¼í5 D3‡äðå!­Õï+¾bðÇWV¬¬ÉR—­ŠÃê›§ÕWߊgiƲÕÓóŠ»—i¦WO»_“wûü8”Ýz#¥LÔ×ëR*yWŸz VÍG¤«d(‹µ°É¾©~?•ýú¿O߯”à)ˆc^ˆPž¶ ÄÝ¿É{ Y’Ó£?UC¾­KÜñ¤®š2ïèMÑÖÂ$۪ɇªm€¨²¤}¦—Ã>œ8‚MEuÌëñÐq½.i›²A ‡>…d:ù®Åígü¯ü´޲{‹gTR5t¶íveÐ=´$½+w§¢ôWa« øˆ“‚z•ìªCÙô`^^Wšû‚tìÔ‘Q'»|ÈQŸaÉ©?åuýBô¶‰«‘õÐö­ªx™nÈé6¤uvi/mÃ¥ \šøònÁö®rpóü’1<¡Zå,Ð@÷VÎ$ŸÖ^@•7EI”cWöe4 è8<9DxIZUýøª!æ®ü˜ƒƒwDÏÃûSS~9ÖÞžkKÁMHýk®ÒL­6‚¥ŠX¼õÂÍò@8±”¸…GzŽ­÷XI›çöÔìHÐ6D‘˜ëâTCú¡Sðå°Êê#É¥T*†¶ë‰#?c-ZâÓft§/p—óuùÐU_À/B{) #é] t-DÌ "´¢í $ñž; Ð'Æ¡Ò+ÔKÝ•PÃp6ñí[¼ëgܨÄÛ©ÀëìoØ0Ç4ZÆ›?K)Õ`%6€¥’0=ðy¾gØâé:]æ„0Ä8ÍxØ^‡÷F~|S>·šÏx’õ 9‰±äÇwwo‰Nu{¬ŠP•Y® ï%æ ®|Fó?m‡./ŸÉ°î§¼Do±ñƒˆ¢­O‡x6÷2žØßÄ9Í¥™y+]iqÃ0jõ7í*Z˜´ú¶qH&ϼÁhCÚ}Þ—ÞM:fŽÆ–Ýp\Ã5Þ=¹¯lƒ›§Ø)%œ¶J^ÇS5ËÞ‹q !ì0Ðy½O´ p‰ ü¬Œë¹Î[ц9n‡Ól^c–àóœåÚ(_¸¾+ãj&‰ Wa\¸J]Â& -hŽM†Ñ\ëŸ(´Õ¾i-Ï\¨P'þ̹6 „g¯dGŒð›ª¹1EÛ}ì}\&Ïï§ _°PJ¸±üß.–s×(œYþïäE8{y¥ªl*ÍXUdG³ åÅDêìtZZ´L¦Lþ]»^¯*h4"âÈ©€ÑÉáGUW}„¼¬qç"$}Hê›·¢veœn1&Ÿ‰¸3ÏÆÎºáàtc¦ÑÿÓ‘®§AÐÝl޼¬¦³ß]2󆎅ÙémÔÍb熉IbÅy F"e×× 1Ø\õïŸ~z€ G0¨•ûÿüÈaÉ3†Kq^Êë"xÿxÌz½æL¢T ýŽV&ÑÛˆàP !5—’D¤®%ñ+Iò5I2Hâ×’6îR”}M’ ’6æZ”¹”¤^“¤ƒ$¶`“¼”äê`”{Ü݈fR4Ã…ŸâTüР¦ó””ÙtžB.?`*¹Yü©£͘^Ï0ÅÇ SgüÂ5 ì¨9 W8~‘ë³cW¹4é@x£ë¼e7Söñî‡{œù¬NÞÿrÿðþ»'À}m¤kWv°ç0š0nDæìi‘2¡…û“ÌŽk¥YÂSæÿ¼ŒdbRØ"*mDª˜b™ò7,µ†qm—ˆ‰±¬@¥V0ÇxT¥›i!ñµƒ×,ñ*|°b·Ê ®äo\jµ6FÁ ài˜dBqר‰µ¬Ò\I•1 ¢K!ÆÊ°ûgN,‹×ñú†ý:5ÎeZCqÑ_¸7še õ4˧8¥Ù8[šµ;üœ…›š¾<ÀªßÕ¤,?³‡/fþåÂÒW•™àI÷PV.}óã¹s,œÈ‰úßúKås9øMûÀØ6þR‰‘D(¤ßýëçûàYß>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 189 0 obj <> stream xÚíÙnÛFð½_Á·.Ñp³Çìe @£F‘‡üÖ)-Q‰TD:Nþ¾{Q¥¡UŘŒ±{w8œkçÚaö9£±¿4S,SÒ`m²Å6{{›½¾a%ؓݮ2ª3ʱÙíòOt½.w}µÏ Î9‚«¼t½yè,°nîP_-r¦Ðº©??T]þ×í» Å–ñD˜ð°" °¼™òX÷kKSPÔ¯«°¨êûªÉ™D_r!Q¹qýƒvõ“¡•`QïÊM€/Úí./˜Fmã(ÔÇ»uë¶ÛT7áõD޾ëtÑn¶ Î e ºÉ5Gûv;0®ƒr$+¬…h°ÐH ÎÙ …ŠRHÔ;8EËêß']Ý×mó*õÑÉV¤EÙ*ûʡڗ}ö^V·h÷õ}Ý Ì–e_†Õ¶ì÷õ×°.»ðÕn6AóîÊËýú†Bf°‘Ü3³'nƒ* ÜkBÊ),ÀƒÞ >‚¨s8óù-òâg€•θ}+°—GŒpè*A‚cÂÓ„³Œp@a­#ÒGBH‚ŒÆppÕYBbDJŽ%œb“¤…Ó„P’P¡BÄQn#Æî ³TŒhBg[yžÆÆIn•Ò:m+Ž9ŸFËÚ $J˜î¼^zžq…òùÞs¦Ôú¾Œq *iôDf°4csòy¡Œs¥TÚî6‰é‰:s.´È Zj¢C1J4»”C‰Y6’ZÁýYDOœ%L£ÅµM¯ÏüƒÎJm\KAL¢–qpKh,؈͓Rv}T¦®JÙàJÙ›„ (Å^É3Є^O[u™<*·±ž.“v[&2Ë%0ç\]OÍW\˜íóªBÉ \cj¾/ÞÈÌ.™1Þȼx³ç¤¥ºLNE˜$—ÊIól$“мp‹Êš÷¥û4aˆ¤êd2³'ô(™ÅDñ&AºàšaAmª2Ú/ êî…Œ3ÌØ”¦_M¸7ýêt6#^7ûÖ%²÷cƒÄþM’²7M:11FRÆ^ûXšÒá>{†”¤BÛCV|`?4þ¡ñÿgÏê6Õ„þó¸ÛT'½í6•pÝfàþk*ÉS'ÛËeyÛ³ªQ– §FÉfqT1Ï—Üp¤…8kt6~‚Cвmæ%LYÇÎP¥:1î¯ÕßÕˆÉxK—O¬[f"šÏ|¸BêT,0LùËÅBÁ´q}pÄ®C{ߺ©)3õë²V$Ñ¢ #âý²nÊÏ €7áïAGõÄŸý¬4Xã]{÷¾ÜVOb>8Ú§Ý¢ü䆸xÑZnî¿öÉXö¹$¼ós§î‚(eØ~É rS/ÝPÝìúc¹û6ÀÜl¾Ž`ÁnÆ?r?ÉgŠ"›åp^ôGÕ,ªWÎ(ÕŽ®ba íÐî¼±ª°Ù´å²Z†uFÛŽ§"Ã÷€é@eÕFÈêaoí7eSn¾uuçYŠû®«ï6ß"Æê@k_m[ÿ)À}j8š¼‡Q}ÇèþK‚[Å™wØÄ¯ jô5{J¿ßf~úVg¹ý endstream endobj 190 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 192 0 obj <> stream xÚÍXÝoãDç¯ð£#Õ®¿—'¨8B¸ð€®÷°q6ïloX¯/„øÛ™µã4.m9é@•êñì|üvfvçw'tø R{—mEIÞg=I5,n탃ú‡j­…>21æN’§ÜÁ7–0tÞÈèúÊÈ ¯·JƪÁ¼èÞc˜EDél=!3¡+´ÕÚ(-/£ØÓ‰M`Óœ¶I„az%1Ç…‹Sy@?²åì¡^‰¸ƒÔ“gûˆ•€ì…UMAœIÜ2=E é1$„±a9égÑìŒÙß\_¯UۉʯšÎï=£Þ•/JÿÝþú¯f#wJµ×Úš@s]²Ááéï7Û™¶© š»äÝÂ'(ãÀ°ŸûYB¯V”aè~ûëw¸ÜxÈRweÔHŒ4.¨oáÂVÐL6¼¢óŧÎMñy {<ÖdK DÄ~_\ò?Lü"aø2î:|)Êiµ×• n’dÓƒÏÆƒOݽ3Âè èj¿-àµ88Sn°ÁvÖ³¯j«ôÔÓ’áÊî¡‚²ì ˆãEÎvýÞ¦­±(Í!ç°ÇFivê±HªºæÕX_HôÜÍpce˜µÕªaa€¬1d$8d|¯Úúx·´rGiên¸†ÚZ‰UŸ”uª×娘œÙÌT#¹q™ãQêçÃý¯S|.­£ÌOR«øÊŽü0´áKw¼88ñGÇKÕn«û^KÞëyö½—A6â½|„K›«¶3p3Íø{¶j ååGYöF¬ëag§Pusé ‰Ïa?ŽNœ&#ŸG°¥7ªìÕǶO««©_rÀ0]úA|àtž{£öF÷ö) *ëÂaw6¤ßŽ]ã:‡¬žal»ª3L`B 3 ¸UÃ0`gÌGÆÇxRô7óýæÅ˜Eoh¦a>Å?=»…nЂº9ü#? §Ñ¾ª†#ŠlÚš1¸øÏ’Þ\"‘;ðš[‰,+HðF/ð^RøŒÀнg´h;¸±fb(ã ²lwÙâ KŒrr!}Õ¾}mxgÕ1»U—upfÍ?†È·ŽWÚ6/ sà°“”Í=š<ñð%Íu6'#WŠi†Ád/Lܹ÷²•ع|dã„«Nš›§®p1ŸÇ6û-ôº_H¥*Кj¤°Ö9¿ã3·cr9PÑÆ´}š›êùž\Øž¤Ë´¡µŠ5ÒÑÐX öTŠØ*‹åù™.9Â,ëFÔÕ’Ù“Pàå “\sÎ…ÐÎÜȰ¹â÷‰vœ‚>K&™L‹™›ÛsKD|î)UÝ76îܦ*µZ šÆ¸V¢ÿu­XÿÿûR™8òY*E¼8A²”sžÓJÉ’i$@)‚³)‘Ùö‰ XØ”€í\2´÷55¼Ÿ»NÆòyA­ôO]ÚïÔú¹wöWÓŸŠpò|µv#¤Û#s?6ˆq,µ-4d.™¦×üY OŸfOß°` b•eo 3øg’Í#Óøy¶V-«Çš&õ6ßÀ¥g¦—½ªß¾_¼}q¦ ¿_àbÜhKKA9w<ø،yuIh–Ü`Ü×ZÍT5“MùdÓ—3ð(ý‹4½ž»fä†Ã{­úûÃV\ ýÍn²ÃS=Þ"q|:-Û;‚gf®üp£¤°l°8‹Ô.7qÏ ya3„Ùjh­ „yfû¾Sðíˆ~x‚€§€'SÀ㇀'ÃO õù7ø7+çç/þÚ¹ÿÁ endstream endobj 193 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 195 0 obj <> stream xÚ½Xßsœ6~ï_Á[¸£€pä-qã‡vÚ¦ûg¦2èî4Aùaçò×G«gã|I;ž1Hˆýö[v¿]Ûù× _ÿNB$NÉ:u²Òywí¼¾¢Nà“ÔOë¬ $iä\çŸÜ˯;Ѭ¼0 ÝèÍÊcŒ¹õJIµ…Mæ^};ž‰7¼Å§—YU–\å¸(¤ø´nªmÃËÕçë_F¢ð ,MÌÞë«õÄ1Ïñ˜öšs^‰&?•mÆ?Ûw¦d¢„ÄÖæÇzåÑÄ™¼ñ&¬ƒ;™­ôö–ÔÝIÑðwdÆ ë>r´œC·Ý®ÒÖÖ®¥ÔUh­oÅ›Ï}ÇÓ! 0¤åœ›$ ­›6ÆÀ.›Ù tMǰ.D'<„ºqKþE–p¬/½›Ò±½[E:î[ûÖ›‹ ï‹NŸ˜ ©ž8מé\«cSo ¿-;7BÁ^×T2·˜ÑRL~&&‡{ø¥3d;PŸƒCnJ‚SõÎ ’i±E‡¤W}y« é©{Œ’(˜r˜I嵯SY§¥©D½0©¯M¯¬Åh «+‰2‹{7ŸÚÇ^)¸ˆ$=.m]*½ä9.ª ^gjèèÕ ƒç4!4>ú4ƒBhx£0½á÷­¦»(4 ±•ÙÎq ’œ ˜’x,ßÊoƪ±éà_ ¬ªæ€|6ŠÌ3± Ç’x È|i†~J¢ô(…êí‹%Ž2d§¯¼®‹=Þ~а™¬Í·ÑËK--FÎ*e+ öC÷­âž•ìl…L¾?µßD_'I2Wà®!e%¼æ/%ESÌo¸ZRp;!EÓ` •XR1¢ëtBêÈNÓ˜ ß·xjd\—2³Ÿ«=§! ¹¨ 'ë ÞÙŒä üã7Ü8„^/°Ølû¢/uûË*T@q(ï]ÕȯfÜÐksY ÕÊJM™’0 À¶‘ù\µF.}¦×=&ºÿ߈ھÑFŠ@3XHóþß÷¼{­”ùLZNøü,ÛºÀ‚À² Kµ©š’w{§½Ø^ìDQŸã‚yo[O† 渫՚º•nÌ0¨ÌŸŒ¡Ì§v …íªK-.þ™aD!IÆ~8'ÂA@ØPׯ4S¤ó–BMÉ þoª¢¨ "¦ ‰Õ#¶ÐÍNR7·FÒí«ºµYÞ 0°Ó¢äë”Ý`!xÔ¦ß`Là\¶W™æ_Þöͳ£îøüÓø{õd¼^Ð0‚ÓFÿVÃt(‘£sÓˆbq®ÒÓf6¼i±^l>ü.¶Œøm[}gÕâÞ ÀE/–à³óé}?x´¬'r]ÞꕕцëQÛþù¢HǧÁ~*çE0Z{y¿$ÿ’ÓFß÷Y!sÁÕ£ÂYàîú´åKÙ5ôn‹ÊDÉôù;üHG8OõðhhʆÂâ§0Κݣ±>ÕúÚÚÓzt²Gù‘òÀ¡=,«µôS¦4f„²gÁæº*#áÐz7 Þ`YÒò«ÅÅ)€o¼ÃÁ&ÕãÎÑŠÎvU¥gÃuèsðýµóçOߊL_N endstream endobj 196 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 198 0 obj <> stream xÚ­UKsÓ0¾ó+tCfjÇ–ßåzèÀ!Ð0ƒj+¶©#InÚÏ®¥4qkL–V»ß¾¾Ý_$"!ü"’3’geP”¤Ú’·k²ºd$ ƒ2,ÉzC¢‚DqP¦d]¥-ß¡RÃO€m×Ha_”¨†íV`wb±QOÝ“ÔÒ eW‘î¼4Cº£Ñ#ÝÏÙìùtNÏPìžÈe5Úh{õpži¿èöÕ5ÄñˆËt†)eqø4F«tÂy”ìQ…kwQ1BÚËc©àü¦níéïk.Û `“.7ƒª­ô³ts¬tg>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 201 0 obj <> stream xÚÉrãÆõž¯à-P•b_ì“­xâIÆŠ‡®‘Ë“6Ŷ€n¸Ñ sÈ·ç- Bå*èåí{sõÇ*\ð Wy´Ê³Ò/ÊUÝ®¾ß®6o¢UøeP®¶‡UX¬ÂØ/ÓÕvÿ›ww¬:+ÌÍ:Žc/ÿæf$‰w§oÖQáíÿC|¾‰2O4ºk…º‹‘÷V´i++µºùÏö_«$ }à娤³Í›læ~¦È{í@Ö ˆ\~³N³ˆxÆ!óÌSâO¸AžyrÅóR·`‚#¤üV:aéuF|–zèaè’{Âô@ ç{}à›»fèÁ·hàw|ÜÝ)leN|ð~h…‘uÕ0úÏ¢–L8FVªq÷ CE…ûϲ9‘ü 1x#do ½Øûˆ•yoŠÈœ(FAË»#º¦ªÅÙ(j/xyf`;ôÛ ×ëƒ wü©Y[©žxßÈA‹Ø D%~”52>21Ò£êGQõ£ƒÚC ]©C,ã$óNöþ¢õ;Y Õ TX}W×ÚìA0(|‹0ň˜{µn»FXG¦×ƒ©ÝºžÅ(lчˆà|ȇ²ç¯Ò(ú‹ƒD_CIeÁJ]k°cX€ o¯Ñœ/ªÑÕ5ËÒ;ݺ8,æ9D~¹L8ZÛ}³Ùì à*é˶÷‡µÕÏ'íWµÿ{·ù_»G­Õ¦×ûR±q¾Yð8Êü$u„}€p)ü2Ÿ‹ý½RgeJ1…«œ­š•™÷Ï÷¿ðâŽAÐʲA«!˜T| ~á£Ì³š¿BU»ÆsiNl!çŒÓ%¸£û÷Ésþµ½ßÃ]’DcµÄ+Ãl&!Þ¢_ñÔˆ?i(e¢° ½-²À R!ï&r è.«RXɆÃëÊ.8ôBJçЗ—ÿI ¾6O ž ƒø\ AÂ0Ìs” A ùxBîzÀMNÁG§UÓk^} ÂDíùÚŠ/êdG—./3ÌË4Ï0/3ÊKܰ·ß::OB SA Q¬8©¾NÒH@‘#—Z¢€4‰}”ŸA~ÜÞ¿ã£=;±¨#UdT3ˆbo‹¹¬§Öê\½ŒåCG1÷:YÛÁ8ò¨rƒµ‹˜jþþððáòv4i ‹ —lÈé UðfYÜ[$° 3bû]»?‚|Ó¹SOVwª]ðy:ëh½B‘_d¡õ t’ÔG(êN Ó{a»]K"‡óÒŒêµkC{MÃÅ –ÜAäSX.Fy–á\pQµ±õ¹ô‚¥Ÿ„GKñÈ—ñ>f$²s‘þQ4Ÿ±Cy=5—´§e®£b6¹ì“Ô¶òصв‚9Њ8à%5Qmžû£îÀrÅ”¶#±·Ji^}vè\õHr?‰æêݹÊzË£â̺8 RŽ“%‹"ôb †iàç—ÆÁB+Až%yÍ6q~Õ£<†ÁÄÍü0¡‹7À>½ûªÆEäýô¿±÷xË{žØxÍWlX<,M™÷»¨-Ÿ|?Ȇš%R¡²yƒ(Öa&^䇷<ùõÃT‘¹£ó“ûÏAÍyþÕñ;¬î„z2:ì+ì°Ù4}ÜrÐÏ[×Ôñ1ûàì뎽ÒñÃðì•™@-ªô_­^8Z~œ§~RÌómlsqÙbŽÎþKÁC×A¡Op/4¶ÚÉFZ÷ß ‚п q0‚çÒ}˨SRp[íÔлã‡ø.ý{ÏGÕ`u‹pÂãï®8´:ø¯$"w·Œ=ƒVûåÚ]&~8ÎæÐÅ_-¥H6sò«O˜` ”P>ÁÎ_,â0MlÏ=7pùŸå¬]òޝù!c»ÄõùîÒÌ/йIö²·Fî~‰"ÐÛÕ¿ÿöŽƒ”G endstream endobj 202 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 204 0 obj <> stream xÚ•Y[wÛ6~ß_¡G꜈%ð–<ùÖ$¾%Üz·uh ±¸& -I%qóçw3 )›vÓ£‚Àf¾™ùšýo&füÄ, gIœùi6[U³Ã«ÙO?‡3øYÍ®>ÏD:ÒÏ¢ÙÕúïh“o;ÝÌRJ/}=_(¥¼Ãâ¶,Ì]“o7ó0ñæ^ÎT(|X °Ód`û~ú9ž‰ÄE„ /Xd¡àÛ¡•Kç‹(÷”/¸¿«`¶_);í°1øá¯õ+ܘò>ÎÓÐó©ýÁ·‘—×kjš®ítA±wìS÷'²,»™Ã«ŠïäÛ¶4MQßÑh·ÑÔ¨õWj|ÅOš¦\ÓwÌçG‚wº6·¿݆ZÇ—ö4°Ъ ­VŪ1yÓäV}­ÏçÍF祟8m^æ,%Þ[]뎅E0’Ž”/K‡bB}Ør¯ÈšR~— }z!ÂÔO­‚I„ÈÓ¡lpûùª+à¡gQÎY›zk`Xxy¥»ìPÛdZo'¤ü0ë•yIñFzÿ™§àvÏA÷º(õƒÛ $õ՞âUª¼wÆbÈ EaHþˆ÷•é ·—®ÓzN»(,jóšDˆÐÀ @$­ç¤Yâ-ÝQðØ*Å0›—mÑ’4z >sz´U^–Ü„ÈåDž ¿+*½0ÍZ7ä$£©¦–þ¶mtÛ²ËIow9YnײËI¯,jðj·[|›Œª!è:KXׇ…)êϦ©ò‘eöИD~ÐûOú#a5ô„J’ï4ãàLüØR2ËÈR)YJA@»@$>Ï}p–S—®óÒ@håö©Ï£dN˜»gNšG֜ʚ3V‘÷#NM£­Ù5+MíU¹ƒ(m3â{µæsgC5zTÞè)]«dðúIU™~õŠœ H~ÜÇ£`ÊjXàÆƒ´Î±A¨H‚9 Ar¦“)’‘9úäÅ&ŽÍ6"õ–¬Ÿ²¬òšû†´$½+ŸgÚÜ»Üï }pBœ»Ô^„ù³ã,%Sïˆ,@‹ ~†’¸Ò«¬ €>q Â"å.ÉÔdñµXkòœÇ>µÍ;øP=í3 ÚPíÅ>ƒÎƶɉ €©w€C+üÖ÷ ØSã×åÁ”QEø©[:‹~Œ·€oÅhÒ4N‹©Èϲ±MßåMWÜ‘Å`Š ñ£PŸD?ê°çÈË;àˆÝ¦š äAìGÉ? ä ‚xo粒Ņ®s`VzgÖ¿!(³KïxwKÀlyä‹ñÓf³ô™#fr°èÁ<Œ¼áXv1ðTl„ã`ßmì89ĸHô'?©ïJMt™r‘s¼ó£²¸ „l_9ÛÑÆ(¾ôO}VÕÇ,AC¢ßA>q‡ öµÖÓlðKŸ\HoYܶÆÕ ŸÆ8Ï()~ìÎt‘Í·ÁË›3~—fQM•+B¤¾½FÎM½6c`„=0äc`¤™Ÿ¨ñÏÌÆÔÚ­r5:C– & iöXó@Ÿº Š¢Ï]agŸ BZ 3°§¹ŸG‰J;X{¡$=åÈn9%‡]^î*ÝŒ< Ÿó¬7„0ª±!0!„VŶÔ-½“{Û'\[,ø3#ÛÙŒˆdÝ}3è½yUæ:Šº-À'ô ¥²èú2çú3* ªÉUÑ®Œóh.1Þùc ‘¤î½€×Û·ÅZ¯Œ­S¢Ì{‹“AÑv±È…4è8¢¸ºB”oJv ïäÜ<› ²g쎮zjß["‰ì õdŒCŒ¼ñ*ÝâÉÓØ{ozHÛÁÕ5íè׺Xpô‰¯ÆöùbKç¦-:œÊ4æ#r•ɨo1Ø1¨ƒ¶Ã¡zz€copÅWÄ PÕËç'Øj(,†Id¡…ÏGÐ õb¢ˆæÿ=8ávÁ‰´x𑺮X/lO_WHEò*'åbj¶  P#ÒóùeYšº¨ì‹àÛ¨s/t[ÐÍ–£ ù}¸,‚î_\÷YÑAm@L€á)ø* ®ŠŽ×kïæPòÀ‰“8ëQ¹Î½OoL¬/€áßšrw‹’qB™1Æ|pœ÷5tˆÁ@};N~YÏ|iŠ ðä꠲ǔa„oö ÕR>åRèÄ\úúé>/†”_ʸR“Y„—>%TÓœNa¤3ô´„ÃPýa ÝÙËè_[þ¤{jd§N:wûJNw¬ýd`™»m†{ÔÝv äîÜÈû~žØúb¦Ƙbµ=ÒCÿdz ùf"tAÒŠ<ró0wõ3Nr¬îèùƒr+Gj…Sxä˜EOÆD𹻟L ly(É ÷%ÙÓ3¥ÊÇ¥@ø˜]¬Þâ0”‹wÅ@lÁââÑ–=ïîÞ^`¹ƒ¨„.¯”Šm P*¡ƒ<DZÉ{¢Ûnkð΀ °N7+*_:櫞ßÜxŸtŽŸv;ðä¶Eò'P¼¬¡5õâϬ[4€ÝêÇÝ­;¦Ì°üáãÈø“që õr_4'!uqÄ\?m> *!y°À ¼uŽL]S^…·¾B_Z'6€®€:®y‘¥•ˆ!ÂŽ% з•f‘þΩ9m¨¥²×aëÌ'…_Ûº8“Ûà÷ÿk¸ïÊ Bâl¹m¯qÀ@'4 ßÝjA‰s–øÍM?À J´_/ùÛçýò;Sæ•EaQ¶“”‹«œMEÝ/6çâ•‘L¼íÚ`úU1ñ¼¸ s¡^M}ßrÛ³0ôÎ3–«ÝºÐá×c^àÀ-°Ìwíp Íï'¼H/ð{¾óÅÞþÛŽãÑžìüpG7Á_Ñ>™à{8ïoEËi*_o(Wa/Z6 b¨°'—‘ðfVêRt\™ _>ñ艥p”b²e绲ä]œñgŽyÆ~ILj©ZÇ$‘£¿M+(èº-è†EBL,ÉWø­ õØÌ“‰NC£2¥^íJ{q Ôg ª¬ò•)ÍÝ Ø|ÏÝLp?{üo„xör¿§:À”þör߉§I6¥Löl˜°H‡¨ÿo‹‘wí6 ]ááÐÒ ]DŸs]¶<†VU"dŽò¦áæ1º±%˜k»Îü¹'ËKžò´s'A÷86bªÅS˜‚þíliJ(J’ñÕ`´ü>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 207 0 obj <> stream xÚU‘ËNÃ0E÷|Å,m©qýjœ°£] @‘PEY˜ÄM-¥NHR‰–ŸÇTä…GwÎ<| _À€úÃ@qPiN²Ê, ˜¯90JršC±–$_@Q½£Õ^w£éq"„@Ù-N¤”hi?ÛÖ½îö˜+tÂÅHΈo@§2Á&-‰b"ý4>e68È]=ó=ù=’poÈ$¤H»êHôz<ŸÛ(¾EꉄÜqJÙ“ËB =÷Ö•¶ÓM Ví¡Ã‰ß¬uÆa_>^tîœnNƒB]Û¼lŽƒ£uuHÔÆ™i} ‰w‚'Ìw×›a°­ fTzÔdÂæëüʾŒ‘TE–¶µÎÏ9èÑ–C„½¢Õ‚Ð?š©Hüû ±ÌÂd•Š¥d~_ÀËÍ/„éx endstream endobj 208 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 34 0 obj 75 endobj 111 0 obj 75 endobj 75 0 obj 74 endobj 177 0 obj 75 endobj 56 0 obj 74 endobj 147 0 obj 76 endobj 127 0 obj 74 endobj 40 0 obj 74 endobj 81 0 obj 75 endobj 25 0 obj 75 endobj 156 0 obj 75 endobj 65 0 obj 75 endobj 168 0 obj 74 endobj 136 0 obj 76 endobj 49 0 obj 75 endobj 3 0 obj <> endobj 8 0 obj <> endobj 211 0 obj <> endobj 12 0 obj <> endobj 16 0 obj <> endobj 212 0 obj <> endobj 21 0 obj <> endobj 24 0 obj <> endobj 213 0 obj <> endobj 33 0 obj <> endobj 48 0 obj <> endobj 214 0 obj <> endobj 210 0 obj <> endobj 64 0 obj <> endobj 74 0 obj <> endobj 216 0 obj <> endobj 90 0 obj <> endobj 93 0 obj <> endobj 217 0 obj <> endobj 96 0 obj <> endobj 101 0 obj <> endobj 218 0 obj <> endobj 104 0 obj <> endobj 107 0 obj <> endobj 110 0 obj <> endobj 219 0 obj <> endobj 215 0 obj <> endobj 120 0 obj <> endobj 123 0 obj <> endobj 221 0 obj <> endobj 126 0 obj <> endobj 135 0 obj <> endobj 222 0 obj <> endobj 146 0 obj <> endobj 155 0 obj <> endobj 223 0 obj <> endobj 164 0 obj <> endobj 167 0 obj <> endobj 224 0 obj <> endobj 220 0 obj <> endobj 176 0 obj <> endobj 185 0 obj <> endobj 226 0 obj <> endobj 188 0 obj <> endobj 191 0 obj <> endobj 227 0 obj <> endobj 194 0 obj <> endobj 197 0 obj <> endobj 228 0 obj <> endobj 200 0 obj <> endobj 203 0 obj <> endobj 206 0 obj <> endobj 229 0 obj <> endobj 225 0 obj <> endobj 209 0 obj <> endobj 2 0 obj <> endobj 1 0 obj <> endobj 230 0 obj [625 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 313 375 313 563 563 563 563 563 563 563 563 563 563 563 0 313 0 0 0 0 0 850 800 813 862 738 707 0 880 419 0 0 676 1067 880 845 769 0 839 625 782 0 850 1162 0 0 0 0 0 0 0 0 0 547 625 500 625 513 344 563 625 313 344 594 313 938 625 563 625 594 459 444 438 625 594 813 594 594 500] endobj 231 0 obj <> stream xÚ•X XgÒîq`ºEij’Øñ£o¼o<¹Aä¾™©p¸ï[@Eƒ‰Fš˜ÝD®‘5&­&Ùÿÿz0q“Ýç? y¦»¦ê«ë­·ZƘ™12™ÌjËZ—5«–OX´zᦩoIwfl o˜…t'˜‹¯3â2qDQ‹CÍF0Œ,h½2âéz tO/¯ý<˜1“ɸ°(pp˜6ÙÁá­EÁÞž^¡¶ö;ÇÙN5Ëq¢í[³løy{ïtó·]íêåáçJ?øÚºìôö°µŸãøÎ”)ááá“ÝüB&{¾;n¢m¸w¨—íZà0]¶Nþ¡¶ï¹ùyØöžzrï¿E~{C=‚mWìòö§§íkÉLì?›Y`¾L¶ÊlmŸ 27†ñcú3VÌf 3ˆÌ a†2<3ŒÎX36ÌkÌÌ›ÌHf3šÃŒeÆ1ã™IÌdf ãÀLe¦1Ó™·Gf&³YÄ,f–0NÌRf³œYÁ¬dV1«™÷˜÷gf ³–qaÖ1ë™ ÌFf³™Ù¸2sû02ÆŒ‰eN2Ÿ3OdeY²ë}Vöé’¿%¿b¶Öì´ùbóNÅp(ž²!ì'œÆÝékÓ×¥ïß,B,îö{»ßUËxË‹ýGõo±šnU>€9 kàüAý… jl;¸yð·C‡Üê8´žÈ{ 8ÌeXÃpvx¥µƒu“¹˜fÕmFüåÔ5´,7Èž=Ã]ÏäøD\ǧ’QOX4G‹œf!áP¸o|Lq»kBj+›No?;†(ÈDoÒ_³@uüâ¤b+u_BMÍ—Pi9Êè„¿à¶Z¯ñR’~&Nf­ðS²¡à(ÙtãÎR^2sÖ’¤dµR¸„¼x}þã;øÚ%¿3ëvîÙåYíÙ.ÔAIaFg…‹Èò°SŽŸâbþéœ"é“®QrÜw•oÙS¿k×_wwƒï±c†úÁJqAk´¿w9Pövû¦ZŽ,{ʇçTÒcÞ|¡«¼{bûrÜ#Tk÷p¤ïÛ< s ûŒ!°ÉföìàEö._ píø'jzOP…§ øO)äCÐKê·áx„_dq|Á3+¬¨N_^ \c`¥OОý;–œÞô”ÊNþs/æ“H"Œ›MFåÃùh)´Â‡… _rD±·‡[?<„{(S^‚ʵq9~ºÕ°‡[âoï(¼Pt0ßX |"÷ïÈçGzø”·ÝÖùúšZ6µZ»î¡õÙðO\vz{˜ õ æi)uwÑŽq0uŒ¸½{ŸT¢>Á NIŠ ÚžÖI‘ H NK•)B¥8¨;u5×LÈÎîÈMÏ.£‡Yc¹â"q0Ÿ¤R4èASÃOPMÅ&²äžÉ#GZÌI´Âª»™ÚüЀ•Fަ`ð7|C~¬{!¯zÞóÈN%nbqÖ­û•ðýÌ/HÿlUS{Ú¹Ž7Ét¬'ŸñX‰ËÙ§ås7/ÙµˆôU’qä?DWûfû*ïw«´êîŒ5âÆ2\QŽîFÙ´µ­òîøîé|%¤ïæ/r9±¬jØD2™Œ&»‰;Ž#ãPNÈ¢Z'k£”ñš¸2‘ð§Â ˜VârÑ«Éç4 ?^k?s鯓œp°¿Û!²X—M‹–«]=ÀSŠï¨“£pˆøu²é•“³X\‡öÔù=F&ââ¬$οçÅG8ž½W¼n¬s/Ý„Ò7j£×V¯mËöL•Fƒ×jÄ¢’^kœE}Ú€•ñÃȸÝsÉBŠöØzNñ0Ç}ž²¹)æÇ»Mœ±8 + ϵ*ü1Þ¼çgzœvªnsš•Tqý}©xUlÑ=—ï¹ß+£¨Ó¡ŽvÞ‡“Òô±ÁºÓìì {m,LÜ1AX‡u8RÓ zaéOmXý"§J±ÄØ«ô&ÅÏîîáüs£Â_m žž¶ào9Jõœ”›XòÜÈþá®* Ð/ ±ñÔQ³vxo’ã¾KÁzÆËX”º–Z@3£ÂS=ÜÜÆ‚'U†f=ˆ™ŠmÔ=ÖÖ'Ð(yaÆZu;þž%z6ÎÊ$§HòYœ-͇Q±EýlØM¯N%že­~9õò›cÛÅgÂ!¦tw%”w÷3ʺ½º^ŸŸ‘s¸b£ÂW½›Š‘­€£P—mMÜz¼ˆ¯oþQᣞ>öL%ºX¬ûµ_vx¶¦lŠ ²Ë9«7Ì4½ª©ÿ‹Ï,Ñéïgd7Óe­ÿB‘4ç} ÑJ 4/5ÌéYkM–оæßKÊ'ƒ‡ïx“ж…0dDCœèÃHP7<}&š,ßa1áWN¿?=©l* =S_„ E7k\Ôã¦4Ý-…™¥”o“ è^ƒÓ ²Ã(Gw‰Ñªðÿ`ábçB,RÝ"jÕ•7 PšT²?×]E÷y‹Ç,åN–BØ´Dî€\øÊ¿ÂÉÖ²6n7¨~:åYPAA*Z¹JK‰X%GdgøIŽ>[Ü ”vÿ™úД™'Ä× ¸¾CÚsé&„»ºWðdA¢¹Š½ »”=?¶²Å¥Å¥EeNÇ5Ó¤ ÏïС>bR¥ªÎ°uŸ»wÀ•?râTI+}:ÈåJØkCvûºn÷¥°ûDtõ5-¹QÞ(k¢;×R L½°/ŸñB$h4)±Iû—M¡•j8ñø9-Çá™çÔ)4Z“–ÁœÛáýÕåMùí· «_Oœ–PvÉ’7¾Ÿ‚cqj=r™Â¿º$YÒÓâi,÷úC¶³{KwÔ9QCoŽ™FlÉÈÇ3ÐFyÚK¸,:éÍìê$8¦Eº,ôtñnïmŠñ¤ò‡|¦„vø°¢©þÌ9}%´@[„au-'¹]êð]ƒ¬žÚLx 7a_©‡j%Jº±­Ý­Õ%4¸gŒ&ƒ‰íSœ€Ž?/.Œ‚d%õ?-9&hÅò0W*2Zƒ¯ŸQÖ™éZ´ÇÊKŽTádKífº(?”|#†dhþì>rrôGót%"ýž*ž}Vd û½N£WGÅ'ì‡0ngCÄÁŠÆÂ¶ÏÖÅDîA8aô«õþÔÖÝ‚*Ú„Ó¥mˆlkÀ·ÜhÀ˜Ã²úÛò\[ŽÃp"è Ý…hêOÿõŠ:ücsꊪ2Šui)”6Æpaû,(-¯ŠhpTàá^µ‹®ÄÖ½»D ¾9î­Þû÷Ex'¨*w—G†$¯…µœó§Ëp¾sç£|»¦.8ϵj%L£ìt¤hU™±M´Ø³´…¹ùöÓóÓá‹>€/îݧmÛÀiºò qå¯]‰Ùè嵆îºÖžgš.]„B¥é5ˆhaªÚU2Ü.õU-žã¿w?Iúc`Ëâh?Nƒ?(þµÒÏšbr•NÌk/_yx³ÈÜì¼t´ÍÍ ÍYfÒT P¨® § î±g·Ç¾ûž°b2tÒËŠè*ÞT¹Ç;8ÄkÍ¿«w¾;õTi~»zKÇUêu9ÞEƒÊËÉÍþlŒl:v¹ô¢k^UZ¢R“SÕj²‚Œ±Uì¿GŠzQóÅËH½ÆåæW”`â`™H™††‹‡hAÅVé>ƒšŽÓ+ 6Â!NžšWÀ™â'>êè žßŸ€çìŸß2Q>6×”×Þ¤îèý“wߥ‰}°ë_c`ëÒHŸÈ»K WÂظ:Ì•&¹‚Ìý]ëËü)ɲ[§.­Ø;÷?$ùyÌþVkÿ±ÐÁj/ïùÿ·3ü…&ž£ØùZ/ºäIï«j0€ò“)ÉTâ8}$F†?˜„SÑñÞc,YÓa€}o›àª´±¢ùx‰>†ÆÀâ€2OØ®ÜL ØÉKxI6q´A‚ægÔ½4Ž ¼®STïm –ýˆßà&ß'¯SÌß¾Ó‡;õ‡ŠÈúã™Äþè‰Î¢cÀ}zΙöæèE›V*U ªðm§pÙõÊäo-‹øÝŠ 3½:¶4,§ÔZù6y“Œ|2­•MБuê$G¶ÿ[dFJl~ŽsÌàV¾_Ç1i?÷Õñw¶)­Ä½‰yöì©“»p/oÈÄiØWˆŽKÚœ»auµ¡¸¥cc­«0¼¢Ýhªä 2óÏ©ú#N¾OŒí!YÓçù¹ô–bo¢\É´è£RÓâ’RÒŠvëéÈð#ã S›8po}JMŠ!9ššƒÁ{ׄM°ª(àQr™F»ÿ7¶ÅþƶtPVt°Ôú¸×G@¹øi”GÇœ2„—¸öÖ¯ÏY™û~.œà>½åÊA¿D¬É’–S´—Óša8¯LöÍkÿV9zJ£‚2®Qèâ¦ÐØ»ÚÛ§q{n‘zÖîvèÕëmg® nÙå~þ¾ïÃåÊ—³”ûÅçâ{¿OÒMì¼íïÍŸZ}ZÀ‡,qzµxvìeÿB\ã-Nû޼šªf¥”‹¼Q&&ŠV|faFÖE‰…yRæH™˜„@5)I Ӥē¾$ÇšðxØü´´‘,@ÿ5D….²¸¸gpö>]J¥Dñ²tÙe”ÒtöêîÞ%öç3‹Ó3ÏJºýÕ1àécÚÙì“cÒÿ&É·&,6™lT„¨!p“6S™slzâЍéÉ9!ê´$MÚ<²Æš0X*Ɇª—B +ø™dqRϠ̈ ‰ÙåÒd•=Çëç¤({¯ôQâ€úÌî7–aÚäægg}#¯ uÝÛ_ÒñJË%×Õ)IjõôqÖöØß¼õ¥A¿õ&‰/Yt kiÓNJš 6*ö¼Nõu­P+ì¾°™JЂ63ë š[£œ¼nî¦RTé.Cí¡N“Ì) ÒÔùÔ(«Ú/QÀë 2².IÑòV§¾Ê„¶]ŠVZZ²&fâ€5Ї¤L„Ðø;›2q‰ÅÕ=£Sb£ýSbm¶û8-Tˆ…8½N{(š8CH¹ŸoH˜÷Ö6·óÂmøè:%ª”B£Ø‚š8K.®ÇóÙ”º€ž+‡}ù§"ŽÌ§«ƒþûŠ6ZÞ\—‚Ô÷° q´Ë’l³¡Lû)Šq‹¹›"Ñn¯  œƒÂ*6OtÎÆe9y ²-“5Z ¬ßálKK”UZö,ÌË,ûj-­Ä~CÿkÕW8 endstream endobj 232 0 obj <> stream xÚ]‘Ënƒ0E÷þŠY¦ª* yK)@#!5m’J]3¤HÅX†,ò÷±“,º0>¾žÇÅdE^èv„àÓöªÄšVׇþb ϭau«ÆÛÉ}UWd»Ê¼WBðõ§ÙÛs¶Û‡òåx؆ ¨±ñ‡«Aˆnç"/¯Ãˆ]¡›âX{*8Œö “MÝŸð‰µ[£mõ&ǬtJy1æ;Ô#H‘$®\è-©¾ÆÁT m¥Ï(b)ˆ·ÛD ®ÿÝ­}Æ©Q?•q´ H)i#^G2\3¯¼¾b^{f}š;¦MÄsÏsæ…ô¹¿L=O™3Ï3çåÖuv÷p·Ë ò•=§d:²0M}Û”„YH<÷1õca¹q±/îËñ?óp³QkéÕÜÝ<øéZ!›Þp–[Ó–Ö endstream endobj 233 0 obj [583 556 556 833 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 778 278 389 389 0 778 278 333 278 500 500 500 500 500 500 500 500 500 500 500 278 278 0 778 0 0 0 750 708 722 764 681 653 785 750 361 514 778 625 917 750 778 681 778 736 556 722 750 750 1028 750 750 611 278 0 278 0 0 278 500 556 444 556 444 306 500 556 278 306 528 278 833 556 500 556 528 392 394 389 556 528 722 528 528 444 500 1000] endobj 234 0 obj <> stream xÚ­ztTÕÖÿ&™{¥Èxu"x'é"U@A¤HG¤·ÞHoCz2)“){fÒ{™ ™&! )@£ˆˆtÄÂSEðÜpò|ß¹I€÷_Ïçÿ­õ}YY³Vîœ{öÞ¿½÷oï}ND” %‰lؼpþ‚ã¬\3y’ð`º6>Su&ÛòC(~¨ˆ³ωù×mÞ¤(Qþ`òIý2Pøünðùùûº=e#1Ší¤IS'Nš4eApHtØvßÇ1c'Ïš5c‚ã”I“f9Î ô Ûîáä¸Ò-Â×+Ð-‚üà¸6Øc»WD´ã˜Ù¾!ï½óNddäD·Àð‰Áa>Œà¹=Â×qW¸WØ/OÇEÁAŽ»z9vë<±ûsAp`ˆ"Â+Ìqe°§WXÑ•î'%?h5ïm”ëPJÔ— ¤‚Dý(šb¨W¨¾TjeG ¤Qƒ){JJ½J±ÔkÔ딌r Þ †PC)ŽN FRoQ£¨ÑÔj,5ŽOM Þ¦&RïP“¨ÉÔj*5šN½KÍ fR³¨÷¨÷©ÙÔÔµ€ZH}D-¢SK¨¥Ô2j9µ‚ZI}L­¢>¡VSk¨µÔ:j=µÚHm¢6S[¨­T0¥¥Öõ¡D” uJ´]ôÏ>OÄgl^³ ³ùÂÖÁÖÝVa›m{^²B’M÷¥ë1³ï•¥¯Ô÷ý ï7ýúõóëW×ÿíþõ&ȳëg5P6p÷@~ÐÆAÿ¼fð]{_ûO¥#¥w_5±Û؎׼Öüº—l„¬ÚAä w˜ãoLxcïnHíÐ׆ƿüæÏÜ|®Rþ¾<Âq’cë0‡aÕÃG ϱlDƈ_Fº¼5ð­#£V²Žju‘רñ×ÀÊÛZQ†Yô´ywÜÿ^̯ãG²ˆ¶â¾ˆ‘ÜùôÀ~ÎEP”š¨ŽN€0&¢8²ª¦ÈTÑà»{-÷ ¸x¥©ƒ×f„331%Ç’ÙWñeÚY K¸ºNÄ`±Ô6öi¥—(a¿]FÞ/¿oÒ0T7€fòýzž6¯AŽkÑSÙÒn´~΄ê(=0::F™Á Ò‡U%k LÓv|{·{}§ÁlO¬XqoY‡ôºIÌhËJp—ãÿY^LcûäXùéM­N ñÀÓm%o7Æí‚†$S„»V ±Œ_eBÙÎÅ»N­k7÷Û„EÜaì ‘Ú¤ìVЧCú€—õþêEþÚGe+½®^mð/t%0ñhíˆÿaùXYìG̸ÿmÛ7\TAur²:6 B!:;®DÅØu~ó¸{u½zõ`wXÉÿö_‚ç©Ù¢N­jé-ê¿› k<¢ã"êÝL›y¿B ü¯âÆçÿcõÒ^£}ßtŠ«€ú´ª`Omr8D‚"?¶4]ª°òC¬¨Ø,j½¹ç,bA§«Å+ÐV3{¹Ÿ3¬‡‡ý÷´iþ²íjSGyý=c¥½µëu*å }Hÿ‘t›%*LIi©:ͺq΋]7$azÓÑGOù-t0m±7®œ·nn™ ê§L'sÞë™i7V<侃S{ëί:û)| gOn3]^¨… ¹¦9 VæVsmýi¡å`é{ÓÂC×÷Y³SQàÞ•eÁ ½—¯Y™ Ì̈Gåp}wÃÑvÆíâåå;Pû°§ö·Q…YÊ#wþ6{:|¿«otHhhIHg‚ÂÜÌL½A¯'¹d€xµüS¬X™˜ZÐ0©ꌼ›ß¢¾œ/ÃÆògkM¢‡'ÅèNeÁ†˜<Ùû£Õ€Þ4š¢Áù`#“¥6ª¸$˜¼ø,Ý„û$b1Ì€9yxÀ1l{¼½,˜Ìtc–üåÞ(–lÞŠŒ,\Q¢ëí*4púçIÀ¨Ôj•4 -‹þyÌ <°à¹Þx!„íz”U¥«3¹\¸ûå)$=Œúä#1Ü<;³íoFm&oÛ,æßF1,ª•–Éñ©ÔI ¡,2¢â9\‡ëèø(ˆŒ,ƒB9"Iâ!Êd‚²BŽŠ×wZN}¥P={.¼ÅãžÅŸ™›m0Èôz]¼–ìâ¤RQwc™õ*¢ÉF«NŠòP©Õ UìI\ºš&{ÃSÑí§b´î[^T^SSQQCÀ×ôtœ]Ì/ëtb3 ü™¼ä%ê$Mþûóei HŒ2'9+„ô\c.C^V˜;efQÓM”}SÌ»¢‹,\K»æûͶŸf»Á*˜ê>ÑQÚx>LŸÜ2wï{#ÂQø¶|ßµç3®ÀUûà‹¬'|b‰þIyîÁ)8ÙGËP¿K9¨ƒŽè²1¹ka.¬€a±ryÜ„5Î È&dÒhÝG\òè|•­C·rùTð&€6‘­Ú+™®"ÚG“8™óÔ¿‡ææï¡ž$°?=Y“×(¶¹Œž<ùÅjè rù!ÌB —^fŸ>F“wú(~ÔÜUsýÌQ5V“¹æÄqÖƒ À´SL–C¢vu¨KàÖíš0]Š.\› )ºT$1Ò.¥2 J¸}’‹Çâ¡‹‚\ä®ða‰ï©ú4«ö0 !¦ pÿx—I÷—"²ûá‡_9"n¬¸2¢¼_ô†•w#¸LF³Øi´V9Û i1¶CkëhyYC¿dÍo%°gÆrÉ$VRñé®í²YGj$HÿbÛm8êó3ZaF¯ß´?ôp«EÝ‘þίGÛXÔoÖ#Lq[Á5ÖÇ—Ai“ª.µ4ð« 25©rA5M™¼%r xÀ¶,§ò£–åüç—EÇ-?Þó!üS6G`Ær«%Ø´ê2&Lâ‡Ým-cqÎÙ‚ü¬Ì+P@ ô(cgc‘Âo2â‡åðι­ öçr‡i8f<–}4}gáí}ŸõÄ(úâ*!VŠØ‡*÷E’>@3ømì¶]êÝPœù¼õÂÅsp°Æsë*_ÆÇ~Ýx°T¤{SNLýÞ¼‰Dœ[òÃ,1Œôñê éka 3ì×%Oí7ç A¹ß«5ª<6wy33ÚEçTG„æ}¸qÖôŸÝäàdí¹ïôèÓpïÖN~¤à†e÷ç]8btõ§qˆm«¹XoÙÍìË®)±†)b“=—uÿ±È EþÄ ÈŒé/§pë`K´«³»s„|ÈàÁ‹l8éïg ¥uçIú€…mp6ºÀWÊ«í)¨'©Û^âœïŸ¾¶13·›Êuó+ î¥XÞîß9_±ùwÞíf|ô¡ð¦ýí§Qfé/þ²ô~T—˜%]èœåóRS^–ί¯!¦FûÍúõ!ƒø_¯ÏÒç²³„Ú„šÑÄfÑñηŠÐ5¶èyYêúIÒ[†ŠäüxÛ[°âä]—Ä=/PvÉ$ÿ7[ù¥&Qmç<1?¼s›V ÍŠ…XШÒâ±GײèMqëu„lwê÷¬íÚZ¡7Úf©”ƒQŸ«7´¡×e$GðÛ¤¥TÚ!p-„^ªÁøìÙÛ¦k%ë£éUŸ¥¬c°™Ï%]8¾b‹»ÎMD3j²Ú#ùMtòÁüG„›Ãø>,ÒÑu†¬$yPÿî†å[f`±ü‡döAÙùsð óý;7ðk\WŸ€ ÉeƒÒGÞUAKŸâú€ à‡JÃÝ;—Ã÷³.aq>³_eñ`‰“6«NŽ*Ñ'ôÃÖ‰Knœ5’ à­°v¾mµ?þ˜÷¯'…áþqô#‹=лx2úÍøÉ“ Y œ@¥KJÁ#ga0ãM»Ña9ñh;Ú¸û ‡Dpg’ 2ă¦˜b0–ËQ]YJN jB”›çɼ6Œô>^…§ã©Ø•ÈOk§È*BÜm^úH\ß9— ¨ Ÿ›ôÜ >4qh ú­ÁCÐd_¢NoàÜŽè¿Xñ2DxßÀž=—ºûžpú¡X£"ÔŽ‹þj…úGoø ½#F AcÞU®R6¼Š¨ôA@¤Lº"ÝN^QLWÙ_¨VBg¤éué*~B×YN¢^—L!d•ÉùƒtxLÂÁW·Eëç·Å D?§y×\Z˜¹+;gTŠHª»<wz¡{,rÅã s/ËñÛxv'Y8OB‹Ð24MEÎþÿßø*DùhÔ—7¿G#â\Šßœñ޼‡$÷T¢³ßA‹Q$:Ï¢9ÔQ×ý<æoøM9~ú/Eç/"GƒJX´³‡›ïHÐT¶Å 0…§ ÁŒ7<>oAÍ|Åþø#4ÁŒF·<~f•þ“B—ŠÙõ&lsP ƒ ãõ{ÐÐé8›ƒ9‰xذ9Šãþ‡>fS€«»B ¢ôZ½“ËnòW“±cSJ[QMy]“ü(˜ÝòV3-Q,ê{ä;ô* ñÌ¿!äŒÆžZÆY¡>³&‡‘þ¡,šPøÎ}`~-C‡s!O)O2s$©Ö»º‚„í?Gâþ©’4_Â)[> ;!ßlÌ5Ô€ ˜»ÈFßZþ#”À>¨¸r®0?aÉ-<šÃ_ü ž Æ $/tׂ癘‰hZúbh…úí{| –À2ðhñjñ9¦ÚÌ•’Õ™— '¥:Y—ªZèFzê”Ãñ÷®É¢Ïm©[WFÌvRð'UÛ¯ =‡¾<·¡RzýÊËXüªue‘çQ8éðÕÑ3W8ô>˜ñÌLg½ T¤v@F™më!ýTÐéR}×ÈkÜ[¦ˆϘ:L3Ì¿’§>œøi‚ïW¥îJ­ö.Íõ?fáæ3¸ ˜›±áà꣚sº]n ™ž˜H–c':RóÈD£7dåÞh¬;bÝ~Îçéä_¹ö3ê#—^„GKoÌ0ܽÉ@<«Ík5XPö”mwNìœÅv!IVI M/ªCã¡*!W[®%D0Øí?œó†º_¡­íq÷PçA‡ÂÝB–'–¦çª Œ„ ùâéÝE5™ õz™uZ2‹eñðqïOpÂ}-h ÇþKf@ãaˆÁäuÑp÷~ ’MÍ ºH×Á~!»}t[µÛ}·|^d· µ¼s˜UTÖ¹UÜ)âo°…U5_ GfZ]hàjC¨°¸]WJH0E£Òªðò®2¼–7¨ I118Ôœ‹°¹fxmuíÙüsb\¡Šëz&ËŠÊÐ@ 22 »gù=òJŸ…‹Ÿ #òJOìÍm"/P  ZÞ#ï É¢@¥I!òÆu¹Ëð4>A—®Í„ ‡]'¡²[Þb‚«Á]XÊ!ßÇü‘ Ë»æáé¼’L¡Y`üÓµ— =-ß9uuÊŒÉÆ¤ fd¥ Y|† ½×•ÙóСç)ó‚+:׈ùQük,zm3×#TCO“6Ìc+xôTC³‚ ”¤Õ¦*±Ï‘a­×Ó²!ݤhÉ^W_Í|ð X©÷&o”ÑÇ ,µ,­ÀVž‰Óâ#·ÒÐë[ uǺ“’Þ¦©"Q–cLÏÊCÑ· MÁ)µQ HTĸ #C½ñ"ìií¢è°#c‡õ¥öèÖm1ÿ;‹mcó³ Í"Ô·YŒ²±‘m÷lƒfüæqô¿|Û|;µ3™Åoz<øcÂ8ô¦ð.Ï=†Ú#Mö_›¨?†ÖñkÙʘ*.â“T*V¸T`´P˜.‡Ú¬¯Ï~–ß{^š–ž¦œ9÷]Uá¼·¾´ªR8÷Sšc¬Èß\ywò½6³}ëå­÷ÐŒó-ÒÀ#èö·lºG•Û`ÊÏ^—[K¯S)ýÔû38äD–mòiôlÚ\¼•4-‹œ–šb*«KMdèËO«Û¦¯ª?˜G\vð„ç¹7-Ý{d“æ#ÍŠÀ·‡mæ½ag9"¥ÚšË0©h&;šž°`»ó÷úCk½‰fe d¬4+ËùfäÝjÿô<*¾)CòXôG*m诲S·È»î[h½>»°ê#=XѺùâŽ~¿ýLf~騇XBºì9àêÍq1‹Üi’èú¼â¦ãDz+`?4„VxUº×€;xkW9ïðò[ÎàSÞ_F(%š|¢´ º{ûÝ7ÑÆ{ñÂá+(ˆE3n´árମÞÇ]£ „&´4²ºÒT²ë˹MàÁïŠ>ˆ“>Á¯>CÅ7jQÿÜÜ$ÐpÉ UkUA—%z“‘ß0u/š.ï¶XÑÊ;t[LDŸ'3Ê cìRγµÒ¥d”Kò¿ý«ý8€jp­\/Ü‚ ‹Y,ýy ¬>ûw[jTnƒÝhˆ­2&p«³ÂU0®2|Oh‹æ´@£átÍþr랺£P­qVç¼ÐBt¯Ñåh¾Ù¾ú&Jîè>µAl&{˲˜Ç¹xˆ§'ïμÍF(¸þic™wFâÁrbóOÆ!ÙíGâ²ÜCš`³J›â;r2$ÁfðØÑø)t@c‡Nö\VM»•m!›Ž{ß‹Ñ~‹úoŸ~ºïÏ/½ë6|ôî†a¦ÿŸKœ?¹ÜC—ÄJ 'Ýî;Ñš“·v"Øi_Ýy Í¿TßîrRú»…¡Ùiðh§ªôµE–ìüÕÍÀ|£#H¥ó KIŒö 3ž,¤ÃÎSSp‹¦ ˜ûçÏ_–CclcØÎ†Ý ¥Q§T§)!‘‰)H,Î-ËÚY’XëI’ÔEåæîVçf$­ØÄE‹>ƒ‹Ù˲#!.Ú|i'^ÖÈU1þ®àÁ,x¸Ù¡¾¿¾ÂA}üáMÕªWÃÇ®ª÷OßaâÝ‘ø<;jÑá#rhÛÓ¸ÏÈœ’ÜF60}ýÂÍcå=·€Ýá$B}Î#¯óbÔç[¶¨zýaCUe»v÷ËÛ¬ôoŽŸ;›·~ ‡ãé?[·‘ˆ×íbÐZnƒ5 !¾ÄÏ´f€Ëª/=þ×ÀÎň[[Ñ€§ö—ž~Ô!½>â?f±£°âó ]ósµú£†ŠúúKÕMré/éü¶6¬<8@bµV[Êk9+ØÍ\ü7>¼{_{íO–uÆÒ[Øy‚°óåiçäé˹4RÜB ŠÒM…PÅTF›‚ƒ£#C7>qé³s?Äìœø''s|EO8†¶ŠžvˆŸ¾¬ŽDVÍ®f]ó ÀÓçŽ]Öº¢¢bÔQdMµþ”¡¼¦FW#¬ñxÁR´X¦3¤e2I¿p:7ûìáVC¹PXƒ4 ì³Ò/´2]® 2>‘ ¦Ã°Œø74;EÄ‘â1ú¨sû¯XòŸ¯({/][fûž ¿Òƒdh}Àârú ÿ1ÿý¼˜n.‘ R‹XN×>Xs˜‹g¦b[<à£óäàe i!Od’à+zµg!ÍFO%ºÎ:ÃâÅÿY:BA{M²•>H¨v?û¾À”ÃÇá×ðà£Cÿ Zöšk# `ñ0ü£ƒá ñþ!NÀÌÿø©ý¾ºù͵ÖiàCž{ýiÇÓÛÒËè}ô‹úÐXþ"â¥û_ÆÀŸ1þDúaëo…‹ 0è4ºÈDe‚ËãÌ¥–üÚÚ€WNzy>ø,‰w%ÆrJ3ÿn™}%ìSm‰øTzy¢ ¬Y}#0›|=æp3ÀçDÔwš]zÒóÁLÖ3˜e€^_Vf bJËö¹íוèé¶/¾–ÑÀ]‰ù~µžÙnÙ$¨Öæ-)€“L}eËmõŒÉ†}rQ¯g|ü¥gzL#µ7!Q£NJVk¼ªÝ!ŽÀhçµd­|‹ƒ«ŒôNmhµêëx¢µŒ”çÑ&lE3M¢ßΣ7,b4Oø7šV<­“èf:ŽU3Šïp ÞOl¸P}áw"l=/ÐË{ üPÂ=ï8l[ŸçW?ä*;™F#_öû¢ñè—ýÆ"zÚÖÅóg¨´sè»Þo®€fŠ£çÀ$4“F‡}Õ5 RéàÞ Ã/æ§¡ÛlÎÎ’½÷EhƒtáÛ 1÷5êò"Èð”¬U«•oál¶Aµª‚îY­² JI3¨[«ñÐ ËÏBºª €”>$ËŒ7¤@¤ç¤ç p¸Rá¾âŸè[zÈZP/ˆSqŠ gC”ð~ƒÎ A mZÂ$œ#ƒjÕù:at¨j‘¤Û¤  ê‘ÖÅÚÜ„ U^`VÔtœ&›€LiBWþ|u·nê úî9òäkòý‘=þ]–oLt3dfþ‚d¿âÆt¥ðÈ¡ŒÝúöVQ>¯£f”ÈîÚ³ç`E¥µ¡¥è€ u¨6L´ ÂÎåÚ숅ؤ„4ÕÊ9²9¿$ ãN¦嘺Wë–jcw8õüËÈW ×Xõ³²·q¿­«?ÑJƒU_YÓª­²VaL- •¹¦îÌ×ߎ–e+ b &ÉÉq!Ât¶KÜ`®jÒíê9ÂŒ6DÔtƒ›¹ô¯ .½%槈+ÏÖÃsF;‚x«®8†°l’N›–8 ëdXŒÌê\m:A­²ʸmcž{ôSaúöEãºD²´„x?U‚b]ð¢å ”ï¨Rkz¶Š™Ê¨âˆHEB s«Ï!î,´œ¨8!t©`á_5‹Z-è32©½Á¿Åæä Îa R šÃɤ6Lj™¿–5’´cD‚k»$ ·óiñYDt“ j«È –ŒûîpÁŒÐHKé#ÒŒ¯ój”Íš»Ô ÚîY\÷Ãg±âg±ÂÃ?bÉC…™_P‚‚ò2ÍìžO[ûžïgÎéßÿ¼©ÿ®¯Í SÿWÐíWÿEv&· endstream endobj 235 0 obj <> stream xÚ]=oƒ0†wÿŠUÆt@H ‰!mU'R2‚}PKÅXÆ üûbƒ2t°õÜù½¿QQ—µV¢/; Ž:¥¥Åiœ­@h±WšÄ ¤nÂ-†Æ¨¸4棢÷û—âÂ1}½]«8‰Ý&¹.íq]òer8Ôº!Ë@ô½vœœ]àp’c‹GŸû´­Ò=n>ó‹j”äyho;‰Qâd¶Ñ=’ŒÒ²ªÊ jùïím«h;ñÓØ]ÉXÌò•ã•)=§žYà2pé5´,=W™×'IФgÏéÆ^“œ6.Âü}’ßÄ{ö´LÌÖ® Æ—ü‡”Ƨ÷f4¾*œ?Â7~& endstream endobj 236 0 obj [778 278 778 0 0 0 0 0 0 0 0 0 0 1000 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 0 0 278] endobj 237 0 obj <> stream xÚ-’_L[UÇÏi˸@éÔÐ ¢»½îA†.¬À’³Ì,èDÂøŸ4—KÛÑ?ÐÞQ‹Æ] Ò?¿–ÿm7GÓÎf³#È^ˆ/öê“&Mö`¢nç–ƒÓƒõá|O~'¿ü¾Ÿó=#ƒaŒMïõöö´õ½ÕÖÙÓ×d=>¹äyqýðÏâÝ2í5¤Æ¯Ó,zí”ßßðQw!\óò±êO2Eä¥c}ƒ‰~ïT†quM(’>Ñ%‰Þñ O¶Z[­Öæ¶ãÂiwÈÂY±Ahjm½xNh¶Z[…+nÉçm¡Ó&;$·Mf…KèñŠNI g/9dyüíóç@£Ííoôúì—Î §ìº%¿ä›”F„«^,|hsKBé"¥­Íë¿)K>¡Ó;"ù< º éªÑI4Šo0êȇ 8Œd4ˆ†ÑªÐ!Œ ¨µ£'øM| ÿ¦ûD—×"¦b†L©øè‹õdʼ–l6S–£ÍSA2°f1‘¯Iß3¼ÿLO®“ysÁŸ÷xü~'ï/òùφ¬æ´Î,&õZ@¯Õ‘‡f:Hn¥£‰¨›ž)˜MDS ¤Cµ”‰¢D£0[§$CI~‰tš Z"R1[ž[‚ºôÊjÊ Xˆ,Æ´…4õ=&¤£vqé‹Û‹KñÄÂ,s©™Õ[ü „ʙ?¥.µøTÅ»jq[Õ¾ËPÉ:LltŽF™«HÓô¦62G¢dˆ$Íu]6S™¶“n¢³è"D&í´›*4D;h°˜´ÈnŽü‘Å»Ú)½ÖÅ?o>8CÑ…æ3¯´ôׯÏyÖDçsÚh^s²$\OôdCûÛ êý ^^Œ3à% _ÖÞØŽ~\#0&Þpx¤èÍØ\,†Ïaz ’±½ð¶=Õ?¯@ìí/ŒmK[î=e ¸Ô °d’¬5þÁBÿúg#«,§ ŽŒ–㙵±õÉœ'é]ùùËGð=÷?•#§9s%*­0ƒ8ÑAñlÉ“SR°ÊÿOwâ?q„QmÁºúÍ·…ÍĽx‰»äÖ¾0°¡ìDR%7Fõ¬lН&À…`¯üýá±Û½ó¡=£Z™ZËM¦¿ši•íCðÇ~£:ìaAU©zÒR6g @0È¿¸P„`6 ™ oòç‹ïÜ;A_M•󕆋YcŲ±2n¬R+Õ*õ®ÑÈV5Ù¯ùO±Êf endstream endobj 238 0 obj [571 437 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 278 778 500 778 0 0 0 0 0 0 0 0 0 0 0 0 0 681 0 803 0 0 0 0 613 0 0 0 0 828 581 0 0 0 0 0 0 0 0 0 0 520 0 0 0 0 345 412 521 0 0 600 0 0 0 451 0 0 0 0 716 572 490] endobj 239 0 obj <> stream xÚmVitÕYŽ™$ÎB‹@¦0cÂaÉ$Nh›ãSr(d1d#8ŽDZ[ò"K–­Å²öe¤;’F»dË–ey߉›…„@B–†Â¦Ð†- ]áΘqiŸìC¡žŽfÞÜ÷Ýïûî½O€efb`ñ®í[7oØõÀÆ‚‚M«óÒOÖWóžo†§Íó¸;1Žpd—+änË$.mÎüOvÆ&X{szÍ^‚Vìë¥éõ>´,ªú –%dÍ_ª·$•µ¥ÊÒÆ¼¼‡Væå­Ù(«×($•UÊÜûË–ç®ÎÏ_û`îš¼¼üÜ µ IYi]nA©²ª}‚þÔäI*”šÜû×W)•õëV­R©T+KkVÊ•¿Zþ`®J¢¬ÊÝQÑP¡hª(Ïý¬N™ûdimEî\+ç~6Êj땊ÜYy…¢!^ø3ÁºÌ­Ø“ØN¬PPŽI2ê0¦ÊÀ…-ÁawbK1[­Â~Žåcë°Ç°ÍØl+öTú lV„ÝŠvc™˜;…]Ü-P žÍÈÈ 7d 3gæý.KvSÆM.¼zþýó.p.Ü-à¨ÅÜ›Æ$ûíË‚g_aû^r­Ü|Qt FRM !yuÿ/äóù…{ìsv›Ã.bW’‡“5Çp^Æ+**{‡„ȇ£ç޼5üOM5$«ò%…åÛž–—¾˜Ûdèä°—ì ž]Ÿuý5Ég© JŠ¥•²½`Ã]`Žp{}çß? €”µœ×a°5#ÇèoNÃÀôyZñÅì\\º&dwõ7¤êêêêR ýý©T?ÞòOw²¿¾&`7%…l -º 8\.U)dõ ù0¨7ô¸išœ¦]-$l¨zJ*5Á neLøâûì|bñt{y'7’|ıÂ鵜]ñùãasÐHPh·Þ:óí;À°‡í\úAÔêàá`0LBØÊ|3I–/æ(ÞÓùÍ΄à%î6!·eºXÄDÁ ô\D+X)ÊÆÿãÛ±]páÆ 9LDÁã÷Åñ aÕ¢0`  cdf^`cb½%¸Ñl6’`fl1+—äiñ ZZ¬v˜sfzÀ Q? ¸§ƒn÷¥(8æ _| #ØIi>%­}´6{™Õ*c:H7t@ÜÙî º¡sQ”¿}fDl*wZÖ®5Ínk'¹²¬Ðà‹ÿ­{Ãè,÷R~3a—ÝÚ,YUÂgñ_‘Õ‚´Ñ&š¢!€èr3íÓ±9LÓ÷ž(4Ñ>xу3ºƒ†ž”VQRI•4{™-)ò¬+Ü@9u.ŠÏœÙ.æå\‡¥ÝE+!‡¿=KežÃμ f2ÖT¦­^GåØŒ.5Ò9@z†GƆ³—!!3m$·»-IH€Ÿfûø«›NçLoyœ(Q;¸\†–½;ÄòÏtoœÿ)ŸÍßÄ/"aÝé}/èþ%›Ïè _¿bù^˜d—bR´ö"Oºñ•¶£(Nıñ“W#WÚ‡`€¦#±çÏŠn³åeÀÙ;f«r) oIFt1e—릫ÑW2»ëƒ’~8ÿñ⟿øèü>“€j‡æ» íñ¦õÖuh¸U¢µì^*àDfÌAÚuñ†è qA;=Ú‰ò+O°yÊÉ7§¾fõõ§žMMz¢t OÛ„¨•R5‡**Z=¨H°2”ßt :A-F½ÅŒ¤{ÿzâW¹ ¢Xl``xäM&'œŽÑŽì^ !¯£ê¥UÕ³1ÔÆ‹ñ÷;›HÐ*å;¯ãb>ƒ=e‹¥Ý“zB±$ÂiªdQ²9ªô7¨òšƒ v ÿ¡˜¦l†M`erœ0âÛ&Ê^$ ·-9Þ},|æõU=ª,,\­¡ùîíò¶yãh.…àõ­ý¿ ¶ u¥Nž~îèóàC­ÝíŠ8Q˶¹]àr;ñ½”¹ xsXÝÛÓŸ<< ÞOÈ`ŸeãÃ’Šò² JpN{ûÍdëkÂOΉ(M v\3·¢qÜð'hw䄯;ù™Ø—ô%™.o<ÐO{[Oþàǃ‡¤$ñ·40+]élŠG«N ‰ï |ObÕãÒE7$¦‚ÉŽÓGØ 8‹¿q`b#±жh•ö—îƒ} .7iš%-ÛÀç,Ú—Œ¿89x"¬G6QFý3ü3ÆNöü§Qÿ/Wþ?x·w„½ÃÛnŸòõz£}'RÉ€¿¿ç(ô@«†Z{cÈg êíë­($6CI‘Zf9^9T<‹Æ¬ÑHôO¡Fÿc4ñ˜¥âšé’ëT ^N~ù»íª;È^1ÉÐ8øðö– Ž0€ÆbUQÖb~§Un­uj@ènCÛ•»kkÐìax7NÂsø»$<à‹!#—Ž=xèevåðà(àÁ6*3…QfÕ–ð û Ï{£ê="'`bªgË[¶x޽Ú39òÁ{;œÄÏÔ·j y#zŸ-h »å°$uËå…òÝUUH£âú³$ôù½1|öý”-MSÜ™}ã²ý˜=#òõt]žRЩ—ÙU h˜e09Ô>ñ⶘„ØU» JÅ…§Cu€ß½ƒ)ÒØIt“p»ƒ#×.t£Ñ1jÞNBö‰C|nsAUi *_%4E»™d'ôá½]­B^½ï”êqƦ<¾È¡±òIÀ¿:ËŠºÓÞ"Íàt8­ÒÜǪ/o!94| áÖ£öqä“#sz`¯…'…œ–»YäMOÿœ&h¶™uN»¥Æ¡AZÔÛê÷óOˆºm¼Ðxlœ„ç⯌|Òö[tSJÌv»Éðýn§0É­ê²»4; _ójí9â0ŒÄûúôÏŠÊvË%uû ö{´‡Û ±H(Š¢&:Xï5)¥ÍE{Žz…ø ¾ú¼‡/nLrÃá([›ÌâKÃ7 2×&²çû³ÐÙ ¼³°Û—Í^ºå¿‚{”| endstream endobj 240 0 obj [272 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 509] endobj 241 0 obj <> stream xÚcd`aa`ddä ôŒtöÕvöõõ44‰Øäüîû5ígëi†2Œ?d™~È1ÿg‘{èÅòŸ‡I–á« ˆüÀ"_ €Hu ÁÄ"ÄÀÂÈÈQVÓm``¬g``äœ_PY”™žQ¢ ‘¬©`hii®£`d``©à˜›Z”™œ˜§à›X’‘š›Xää(ç'g¦–T*hØd””Xéë———ë%æëå¥Ûiê(”g–d(¥§•¥¦(¸åç•(ø%æ¦*@Ü®¡œós JKR‹|óSR‹ò™¬²Nägða`fb`d`aPbdýÑÁ÷}q÷ÆGo˜¿ûì]Q<¿8¯¼¸8oqùâó/–ãû1±qþ÷‹w§Ïÿž¹™ñû¦“î3_ûÓP´§¿wb÷Ž©Ýr]Ýé•U]5•]Å-]Ý•S»§îënj”ënïîl«ü­üç‚D{Mwgw+Géœö©rË»'.œ¼j×w‰ËÍÛr»£»[»Û;j€*ê»Û87¦ì“ÛÙ½xëä™ 6Ì8ÜÝÏ1¡½¿U®©»«½½º6¼Ì5¢›£¼nêFùîyý ûgõÏíîéžÞ},lþôõ ×oš9ëÈéM«wv/êžØ:©5­½¶°»œ£x^óÌe‹­^Q²2N.¤;.Åź±>-5­–ƒ¯lÁç©Ó¦}/XÀö;a*»‹ù|ÎI<\=<Ü ¹Îp/œÄÃóý¡—NÚÌ endstream endobj 242 0 obj [525 0 0 0 0 0 0 0 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 0 0 0 525 0 0 525 0 0 525 525 0 525 525 525 0 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 0 525 525 525 0 525 0 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 0 525 525 525 525 525 525 525 525 525 0 525 0 525] endobj 243 0 obj <> stream xÚY \Te׿ÃrçªÊxª÷^ÒRß\2MS3s7P,µLATd†mØA™3ìÈ:0ℹ+®¸ŒK5.ùfi½)½ZYÚòv®=ô}ß3,ÎôÕ·ðãwáÎóÜóœåþçœ;2ÆÁ‘ÉdÎÞ+ç,Z¶x왲h¤Ý—8JÏ0Ò³2éov’`/ wøÃÈr‡Ò+óŸ.–ëÝ!–ësô"6»22“'Nž0qâ¤y‘[â”ÁA*1ÿîñòô鯎ó˜4qât9áÊàþÞþª €p½ óX¹18@ç1ffJµeÆK/©Õê þá['D*gý}œ‡:Xä±<`k€2&`“ÇÂÈ•ÇRÿð^¥'ôþ™¾%Z ôðŽÜ Œ ÚÁ¼8d3‡™/[d·Øù=;?ÆßEÉ%2ITq{fãÄ fœf3”qeÌ0†gžb†3nŒ;ó4ó #2#˜˜QÌæïÌ‹Ì8f<3y‰™È¼ÌLb&3¯0S˜©Ì«Ì4f:3ƒ™É¼ÎÌbf3s™yÌ|f³YļÉx2^Ìbf ãÍ,eÞbÞf–1+f%³ŠYͼüˬaÞcÖ1~Ì›vŒŒ±£ D6_–)k–·“Ù-±«²`_åàèéèîîØÅF²Mì¯òy÷*w|ÀÜÙ®øû °A:qº4Xéüœs‚óM—é.Ÿñbj7tæÐè¡%®£]‹\ï)Ö(>Æû…áÏ<õÊS‡ž’†ÝÜÝÖ¸}ìþŠûÕ§Ç?]ù´ôŒîY×g«ž%óø[–3ÞÂ#²ÿd’η}{û[{Œ.ñ¹G‚‹’ "RrýʈŸ›.17¦ ê!¿J§çp9®ÿßw8mŒ‘æ‘ûÑåâUƒëÇ’Q¨ø<„¼)x³áŠcBg(«ªAŸ\œ­SêíŠ*Gæœ[iaY!TsyмQ Cæå4è>„f÷bØ!iDè- ²)žBŠ3v ˜OoÖê¼7­ÎóFæ¦õîuü…Ý•Q,D²[!K›¤æÈkÝJüÑ‘ü(§¶w~‰‚ §˜\Ot­2£Ö¬ø[$w>ü26D[R>CþD©aC2ÒBER-U«PyùE;[÷UNñÛíCs½^›ÿÖ«b$,.Š<Ÿ_THílVUÆ$†§mšöåtÀ¡?|ö‚â×G³¾'‹ïÛ/àt“ëÉÏPÓµÚLhþ‹/Çç¾¹}vCeJ~ýÉ„8nk•º¡Þ oé<õ"ÅçÓd0ñ¿Tt˜ûʾÿÜEì…´VÇûnàЃìã½`S‡Ú”] -È.à´y@tÅÇœFj ³õPÈ]8ì·N¾9gŠçòyT'£Ôn’4Ÿ¡i1X:“9dI0ÙÄŽÓ@H›^_Ò,äc;ŽÇ¹¦s†ªœ(ç,îÈlfe¤ ѱ¢¿<¢w·AuS9&\G1fö1c-½(`vós½užè<úÙÍ3ï­^îí7Wü,Œÿ¼ñPœánO½I§WgÎ`ùáw?‹¢ˆš³øm˜Í½x2E×{wpÃëÜ#7“´òÓ<;ͦ³ÿuïÌ’¥ =WL-ÇN¿€íÔ½æÕ]˜t“ûylàSÉ×ÇŒ…4ÔÅTæå瀞«‹3D)Õñá¡UóqºQHÅ5Ô¿˜IìÍãˆý¨iÔáìÝIHýûàœÐÚÇ‘çóø«>úäÎÕÎkâhRUªBJßLÈÖfCdå%@ç³rù4ÁBcèi¥2ÉáÏ\FÎ9ü™ß:’Ÿ¡—#—SÕ‹ ÊŠ ÊÒKR ÉW@kÁv]p ±É*Z è縗xºzIÉHJ‡XwUur¥P ¹ºòbKbýlBó-Y£bf韶G£ ƒ šÁÝF7 ¨ 3;%33’¸ðÐ ?²Uu4Ô(ÖþìˆSÙÚ‘Žjš{uP%þÈê E„²¬Éù™¹Ñ™'Eó:ö21;·2Ó˜d·ÍXe¶?/!Ÿ ¤Ï6м­éÖD³Oîp‹Ãï¢NÁW¦à‹Ä]$òî#¼¤ùNŽŽÄpdÀ2âBì-|‹Ñ&ô3¹>0ãpó!óZ³â·&>Ü*L{Y²«%cÔÂBb+º1‡Ë7@BÛn¨©î÷-'l(Ùûaö*¶´Fƒp]¾3sG°Ð=€MŒ‚ð0‹ÔÖ©É& —ñ¡ìË nJ=•v>†SÐ Ÿî8ZvºÆpº )¾Ä«øX+¨5щïÝqK«ÐêÔÀ¥°š8ˆ!K·=7ËÒÁ½kÂ˯+¥O³¿Ù`V$àDŠâk콃o¿·ÆwÙDq‹>¡ü‡íÕ&ØÇ}õÆmÚÿ?"aÇn²ÕЭ‘51 þàáÕ¡úð¦„ÝÀ]¬ûpOëVHSiíІséÙ›ã#áðI.BQZmr³Ê¨)ék¸]O\ÆÊË—÷±ù¦Ì/Ôð ·zýÛ3…HX“·±Ñ¿qÛ~m•V¯­ ÎBÜ"q“'€²…6îåÅ­{ÃM —€CîÚÝ..îO.Û°wKáëUœâÑŒ*ÿÒ€68â~¼ãèUBÅø‚°Üè’LC?׺õr-mãÓÃ7´­,õ¥‘°Ÿ=sªoöüb+§¸Ÿ§} *ßÞŸ# ft7£[?ǹýEx† IOçÊŸ¬œD÷nÍj¹•8çX½¹º'(To˜1ÅR@¨Ø¶²¾¿„ð68%ß°ž«W¯ò:ñ«€ß´X¨ï¯výÀ—;/=|xçºÎéFi·IV%%öÊîáRË3/ô>b„6q9—´*öŒõîZ6«m›>­ýEÉÝ­íO;ß§ëÖ宅fpo¤}Gq;Gå#­}‹M²Ik/EÒ#Jú‰r¦ œX?òUúÒŒÕÚHzH極¸F[V«¢]W*¨!5z{ÆZ²6Ë›ò!äk«3N­–<ÜljÔÌ^æo‚bQÇ^ë6äÕA)ÐiØ; ¹…§0)o/§có|O‘8]v¡² ézä·õGnäkñ3QåXcMò‘½´V µâ|2jŽr4Ôö1äH«[kYt"Ñ´íÐ;F[Íú¹WÌVP‰÷pÕd•£*úK–T¶ÅQz›ºÈhµ¬ïø¨GÍñ8-Õè^WcU¡6FÇsŽd±Rþ×5³ÎÓLGÒƒ”ô ·æ­EÞ³wXù}±<¬ u·€ž6 À¸Ç#Y›Ñ‡=~‰ÏÚ‘®N'Bz^jn&~ùû"·üÔ¢øà ú*жíØ^ÀõŸ©¡Yqúñs|OÐó¬JŽû}$gsïÙ[&Çõûãþ‡i?Óäc—MM®§Íë»ÐÛ¬ˆ‘ìZùš°£Ú=À5õ;ÉRóÓs9 “_]ù%y~ý 07ܘP'T@S±®Št:CN¹®Ì2žþãDØ|Qq„,ØN\Þ…±Ü‹^? Š˜v¸Pxd'—‚KùWå”¶b6ÅÆûZ†ï »?¡ã«v|!³(dD4¡cO³Y`V$â ÉG¯ÞäŸÛ_GÊÅCݬbhƒf¨ûü¤µRž’=øè2éûçDEâ{àÆ‘w®ËÏ=yñ“³s_»ÀkÁëAw ô,üÔ$»nÆ­]öÒf”ñM)$@jv†:3)víà¦Î»ò¯£M(ÇgŒ@š¨ ªÖÔWgÔ7_ ¾dö[äÙÉÄé›ÐÅÝßëûúqþï÷éÿÛ1>4{…ëý¬£}¥öOöI¬¢#¤yCåzÊ‘²±ãˆ‚ ùúÅS3:acS3‡¡óå+|§ÍšÿÖÕ®ï®\¾r©c…OÏžÇa&Ùi3ÖQXÎļ±Ú‘]ü=yŠ ;švñÎF!¥Ó#_×[Œ騏=#6ú•i‘´ºÏ>–ð§;Ï—_?wú œ€ Êâç{Šü¥À[b~pÇ $–GgT;ao~-¶âMm†Úʦó¯AÂk³Ö½"¬-ï1Ë’¦È…Q6Íh5kGÑbwçœ9}×wm>kFóg—]Süš‚œÏ¯ô?ròÌÁƒ'Ní_»j¹Ÿßjñå >7{ª¸{ׯÑrÔ’Ößd,­Ë+Ól©ÍØœ¾¶´¹6vçJ1Öh×'”U¯nüüÙ´â¬×‡TÄr ¤$¤EC8•+‹“çøÒ’ŸÂMùe)C‡ýr៴Ç{§1©Ð¿æeà°éé9‰tÊL.O)× òrÊóvp8ˆ\äGÏ>pP„ªâÖVC}e1\® aŠßìõ£{æ¦(XÚ$™7ð0ÿè3…7Á786–Ã¥jŸõ'³åý­µ.`~²çøÉòÈ·¢ÞÔëbK«Žãmv±½q»õÐ.4ÓºAzº2FØ‘\ ƒmº²£ÖÀŒ`¤l‡¦èšÈÈèèÈȚ覦šš&Á™Äšh­£¢váp‹ð_$‡'Â'±ObŽOug!¢‚¶„Ñl€äœÄ].õ]!פÒǨ¢ã#Þøöá ï£Ó%Aq_úé/ÎëEà Š@;Ú7ïÅ"]PîØf3ÐL°X2•ŒsÄ_zêeåÃŽnÍvœ`Åðš[ìçŸÐ@¾Ô;a÷(?Ð*>ì¿M]ýÑÖž=EÇ-Þæþ¶M†<Õ “ëÉNdùUÜB™ôŸÝ¢†8àB­¥Ÿ\ÆôEôn¯ 1(â"¹¢£kß‘}µåñ^ÑÈcûÃ~ã›þÏ-YtfBv’’"7% Nq+Â5[£¹'zö@Uñ)eÝa|+Tlü#E]ø_À©8ôÿ€'&²= ø´/úXøŒëi†b$&ü@ˆÃ„1d(Q|;íÐîÛïÐU þd ?ÇûÆý]¾|õÚ%¯‰¼gω҄/Y2ͧ¿fÜ¢‰žÿá“QQ%új„âAsvyÀS±é²ÖVoÆ…w‡PI+Û7ç¾ÃÁ‚n«^]\¡²Ñ¼šø,ŽóYÂ)>ÝÝ LbgÅâ-ra† 2ËmmÏöºÆõš “Ma&Å#'~g_Ûmîﺷi²3üŒ~K+Êkªé"¼ôKü= íº;Ò?O‚UÜæÍ!…µ°¢Dy3«j[ITßðbïP •ºÒöŽÀ“ÙMÔg“Z¿8**ÁÏ„7†æ÷îcÓO™Å“hz(-õaš ú§ÝfŸ¼ šþе$Ü%ÛÙ±^ÿäÖ®*0…hcâ­÷òTp³àD}_½ÐÆXü­•×…¡ 8Û"JSíÏE4˜âðåÉ¡3aW«€µ&XRÌŽ5o½.(b÷Á¾íMœó¶xÃ$«“¶ØKs© -6& °§‰%2rƒÈð†cÓvÙ‰ZÐåAWW¥Üå¿{c‡ð¡[^I¿C:̸¯çãcÞh ÅJÏ펆XÜï8×YÎÌ‘“ˤ#F­ÝñîÁ5P-H.lM—*¸³Ö— ¤FÞ×ø÷~ù÷øþÉw}¿¿!·~·'%£“×e×;ø“⟒§ô¾2±2AH̬ŒÌðȨ …CzqRiR™Ú [ 2A¯NŒˆ†8.¡"¡R(‚ü‚–¦†ÊrØEieÉeI†˜ÝÐM•µzCEs TqÎ)%Ò¼b|£„%q…rÓ@ó “““Ùi°0Ð!.Òi€T3쿜3~^ endstream endobj 244 0 obj [562 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 358 307 0 0 0 0 0 0 0 0 0 0 0 0 307 0 0 0 0 0 743 704 716 0 678 0 774 0 0 525 0 0 897 743 0 678 0 0 562 716 743 0 0 0 0 0 0 0 0 0 0 0 511 0 460 511 460 307 460 511 307 0 0 256 818 562 511 511 0 422 409 332 537 0 0 464 486 409] endobj 245 0 obj <> stream xÚ­X TSgÚ¾!š^-C+¦3÷"µŽÖ¥ÚÝ:mu¬µ¥cAÅRÐaGvH dßó&!{ ,!ìPpÅk±.mÕYj§N«¶3­vþÙÚ:ßM/çüÿ°3mgúŸöÌ—ä~÷}Ÿ÷yž÷}/‡˜1ƒàp81I)ëÒ¶&-Y·1õ…•+"ùikû‚ «g2÷Ì8Ì£ŠËÜ3ƒºž4㣣~Lœ-s"×Ùwá+ñÉÝ‘ë||¹çï±Ä ‡¬m€+^¾bÅCë*…u¢â¢ê„Ey‹V®ZõøÒ„‡V¬X•°¶¼@Tœ—S‘°1§º¨ <§ÿR–°¥2¯¸ º.aÑO‹ª«…O>ø X,^žS¾sy¥¨ðéÅKÄÅÕE › vˆj òž«¬¨Nx)§¼ a:öåÓ?ÖU– kª D +ó D8λ¢‰eœÕÄÚ¨õÄ"‰ØÈI!¶Dåy¼²"®$Š Ê‰â.âGD"q±€XH,"–ˉ‰•Ä#Ä£ÄcÄψg‰õÄsøîç‰"'/ÉD ±‰ØB¤[‰—‰t"ƒØFÜEpˆćç Ž'jQÔÜ”«grfÖó~Λ¼ÃBdÖ[³%³ß»³=zVtçž!c‚wýènêîßÎY9ç“Ø²ØOãJçRs¯óýó¶2Ææ4›l¿òë B÷]érDWÑ×ǯrQ?³€¶óÖ±{̓dñ/ïÞq„Žn¨mÔ7VÒ£-¥³YW#Û"ùy1UÐÛLƒZœ}—Ñk‹ÃjÇŸój¡žb5¼¶?6C1߇ݢ,5䃙”»%=Á¾¶Ñ·ÙÙ ¢XÖæ ÙùuËI¼z%Hnh¡Ïòžcê e†"#^[%¹L°ämöæ.Á:T$m?(ÙEý¢…}è~2%Ÿâ\G.z %óÛÁ6ŸÕáB#éSƒ”bÓxb|ŽAnÒé% 'å.h£bÐi¸ÅA3‡‹DçøAiGeiIyIU[}Ïphh òvkZs UÞŠE3?߉8qE›Ýüºµy›ÓÒõF“ ¤®QïhC³P,Šn‚½yy¢¢ŠÒNU¯Ëj!ãn ™Ì]üNi ²¸¬´¬ºEÜ7 Q1a)„PFˆy>À9þ¥¢™üìg² E&¥Ù\Á2ZÔ^ª»ßÖˆN´7A; ^ h,:K¡Bà¶ûÜ­¿B±$áyÙ'gŠw*²• Œ¢lÔÈ^Ûè®ÝÃщ´5i@J§ÑeêÉóæ Ù&)´:%YÆrùì•™l/&¼‡ôfí Å2×~_öaÜ †ÏLòÝ»0$šÍ»êÙPöØÓ÷³<šðP©šbzsÞ!•ržåPìyž4RF´‡z¡ž#˜ 2öÞɽ‚¸¿jŠuš @J¿¬3zŸ‡ÑèŽÏhxÿùCëÜ$›À¾Ëgïæ•ÍIƒÃæ±8.¡aZûáx´êÕ÷±QtL8«&^â >à†‡Ÿâ[-\f«Ù¥¢L µòçkÙ7µ¤Éæ²¥l «`ŸøûD¡4ÄA%G<*ÐÓ:ЂQó û;çÅ'€|üáS(‘†³Ýhåuáã½ä­ÝK¡¡J_ FRå;囥±•Œ ?‰qz=„††9á¤nø¤à[¬67XH¯Œ” E]½‰¥Š’؇q1_Mé"ê|À»à” iК4`2éðpDž`ml{ ›Õ…åS€’uµ’g%5Où$ï 2»†œ–!ˆGsxˆè.–¡InÜiÖ›Õ‘“¼ÐH5ƒ¥ÑÚÖ‰Ö l=:¨r²W¯‚:¹ QÓ`­¡ýáäà›¥avò`±8ý8Õæš’…˜ûo#þ<*à;:­žƒ@6y¡Íe°«é²bcivfvt¢Fb¥ü´‹×­æ&s‡ÑeÀ¤©¬yȤ,¯ÌÎOU¹tÕ›(ž†‰.ôðï÷ÿÇû 2¾S‘ýl>.âÇðëCý#îÁB/¶'«Ãæ%c˜`Mð?1²çæ§\fsÚÙçté÷B»[gÓÐ%…ÆâÌíYщjÅm|¼VÀš‚‘"9`*““;’5›×§B.uköYÍVür48ÜÝ#nª5¦ÀÓNæ§oÂÇo?"c¾˜ ¡0'Äyó‹Ÿr¿˜Ã0|× ËuÈ÷”*ëiv.¯ËDYÇÞ˜<+ØÂL˜‚»‹gãÿ­”æNú²-ŠL©QšëÔ£“¶…w…¦¥îÓZôf«©ü`Gc ŠgúÞ™ÉO­õ õC|Ø/3+ÌÁfçOž›®~üÔã0âôÈÛè辑èDgÄ:´ Þ.7 p6F!Îèl8Ä W3¿ã·œ?eë·6Ÿ¥uš %ÆÒÒâ²èD½$J·ÙMŸ0¹Ä˜j“Ö¤a£&_°ÉL«®Ål©ÅyÎùGžÎ“ ‰°ÒdT±‚É^,u‡üß=O>ã ÒÉ›ö‹©â±,ööÛZíAçBœð¼¹è-t‘äa»¾÷ohÖÕ Ø·hvü[}ë«Òˆ€3ºÏ¶gï¾=ß§¬Í$ÆzìK·¼Î»t¼êEÄ ‹ ²ŠòÓ%ɘ©±<܇±­èã mPÖnxö7,LñeæAþ[ÏZÄøž»Xþ¾ƒ†´àËB‡1¨óŽÊ'\ÆÖ:¯Ì[…䊧~òК5»?£ ÓÞkó‚Õb4c5èpÓ6™ ilÀ¤5±²tvƒƒr‚Åêòx}=ƒž¦‘­çN`{E\ôCKC¿v_Õ (¤°-í“ØËÜzk±¿~ö‘ï½óûk7û6¬¥ Ê¬5Ô˜e‚¯»b„v„VŽp™£ â;\V—Åeí…V ?ë”m¤‹K•bRâVl"å‘››Àj³µ   Xâ¸kßnדÜ® «Ka70"WFÚZ#FÚf³Z-OÏa4¿¯ñæuâ^†ÝÔ¤6é°¡ ÔEj6^éôTá;}|ÜvüÄÉãщn¼*h xR(³¡Ò¦o„fL¢H1½qyîÁf—ùö¿§wy‰±¬´äÛèýËJYþüË€LKþˆ† }Ðü ³Pðå{µV-]kÌÏËÍNÔÉÿ…zK&ç 4¥P*’¾ºá&…âWg^/ŠÂfæR™{¦`,". gÎĽƒþvšïÍ©Ýß}h»€ºÍ`;ÙQoWQ¥ -6ëɸ1ÉÒ–RÌ;.;›]Ê.|ìÐú·é¸wvÃÁ޽GÉ“ÈÉßÎnÒ”n|2â·kNÐp,„fµíï>sèØ> v§åÐ`2ëM:i¶2ˆFß rPÔ%”sËl`~ÀO×aó4‘R¯´³·+8z4{äEön–Ï&² ~áC4÷ý¿øí¯†2àÐ5ªµË2Ô¹U46AÃxïç=Gv¿ql×öæ1“?÷6Ë‚hÇ~Î4\ædx%ÿvÿŒ˜;e•Ùh^¤(ÌJ3HH¥šXµ* ŒF9˜7±rACHØ›ó¬§sþ^Àú]dJ_SöÒêT ÿtšÛ*=ROHÀh6ü%a­Æ0ñ."ý(i”?oÙŽ´¿;o€“<´cÏ‹‰ì} Ùõ+<öÉ·@”¤üåF=cÎ^Òä@O|jó¹·SX<Ÿ]%td ,Œ$„–ý¶cj8‹€¼¼ÇkõÜîIOñšckó_rxÇwã;LMÒr½l'ˆÉš6UKww`×ÜÎ\j1ˆØyÚâZ6JðBÄ@ÅW?žß69K±Q•««×ËÓ A›Òÿù=ó@íõìC;œ»#àÀ|ïÜ 21ALìñ«Â qŸ£Æùµ+Òuµ•ÅñyÛóp–C½—¯ZÉ&u{U]™,?o¤î*õ9\~³ý2â0I‚F?¦uã4­P­1TqŸÈú…}Ù¸À3Ø;ØEìüÇoÀ´þü8Øçó‘o f~&›¤)}é)Lë­¦Ë^Ž  Y‡»OÛäëîÇ5ôרvíTÛ.:õý˜Æ.šü@`6á) û™»¡ê€¦V›·Ñ?ˆæ9ûìAG‡=èÞm±¶ œ»„ådͬ¥ac{§,O^lTC-™ÕWxäÆ0ZlŸb! ±½k„ÂÅ›€¬5û1 »==®®Àø>4&È÷RƒÔóPTTVŽ—¤ÓÓñÇÿ.Í=uøÕœ÷âtÝÇÿêQÂ%ø(ÌÒKCOÓPÓÈyôŒÀÓsl'_-èÞ±¬˜]¬WM{·{¦{¨çÆ^¯¾š†Ê ­¤ü ¼D¿dÌ 2¿+÷ÄÍ!ô@#÷{=SÍï»dµBq¥( iôµ÷ãE æïçÜ|ýûC:gÒ(0ôbh §öÖQô6u·îj>¶i¥êÏ×z­HP¿^’Sùu±Æ„'¦0á Â3è¥3èe\Ôz´Ž?]‹¦£`õuô;0qÈCðJ´µ&uÛ$0éÌzÜN•®†åƒV§³}/zDð­÷ý5¼º)°ZéYåYš‹ií™ %Å¿Ð-ȆBWKË%yòÌ©/Ëb±Û.µ ÙJ¤F‰Aº†ÿ7Acíþ'¿žþq°´ö7w½}ù¿EÅU°-Y.ù¯…îº:n/¾K\ÆBüOR.>òe?YpnãûènÄÇ‹æO(ÖÁøù;B¿Â–܃¸ƒ'GÎÀÚ>Ú—•BCvÍ‚ÒäŠÔW23 r.ûr-:›I~‹ûv.öt1ßLFö­]ï¤{ûm}ƒÃ‘qoæ>È^‡ïxΞƖÝh¡ÀYß«8èN´-þ{òÑd:² +Š™>ÑwË^Rm%yºšï>ûî«@Žy6—Ò#dï¬xQ!Ê^ÿ ›T×\4Á°dpà«”èâ»~öblì^´ki ñ¯ãÙª²"¥±4òúÃ-éi 5ï9‘ä-¡žƒÂtir<¿½ä?(É8û§"Xª ¾v-¿p,{ùšöŠ}mû¯ã¾@€ÒùUc*ØJ– W/ j`“]zü¸öc¡·Ë›j«+ë3_š(ü%z`Å¢àƒ§ÚrÝdÜ­JG¡ ]®P½0¢òæ—4B<)õ]­=¾‡r÷¼ÀÎÊ]’FÅ}O¿!ëÃ=]SN½èZÀðcSiÂî¯o{‘ù’^ÍA‹¦§Ÿø©6!U­¡!Ÿ}XðØ?ßD]ùÊ+±ô¡¼=þ%ÕfM]ݶ¼5›BwËí¡ §?t›‘žA+ñ(âaîå[;ö"¯Æ/¦Êû‡ægì˜@_&µ\RYQžd¦úà g†þÐ}ÁÕaoÆV{¬$”½¼ˆ]¤ûŠÕºB½ŸLY­± [­J(˯Z_µÒÈG&*NRã0<Ð5жõ€®ý{Ì8äíþóŸjúMæ7ªuX÷GmE^rʧRq·A¨«©iJ-ç½Aä zÏsÎ2 ¹(ŒöóOO¹ îHÙtÓeS”l–ë¥P*¤GÑR߉çóµÙËÄj§ÉEûðí>W°¿{Ц ª†¼x+n¨W+¥Rö öqÁ–Ômk±`Tî©7L8>gsGïØ(Á¥lµˆý¬íÿ9‰æuy`Œ o4ÈëÒ·gƒ¤N±»¼IÑ(=h@ovº:ºû0mj‚Ì:/Úim òØï¡Ùî º££©Ù3DÏBá¹ÿ9L͆ endstream endobj 246 0 obj [833 0 0 389 389 0 0 278 333 278 0 500 500 500 0 0 500 500 500 500 500 0 0 0 778 0 0 0 756 0 722 767 0 0 786 0 0 0 0 600 950 783 750 683 0 0 556 694 0 756 0 756 756 0 280 0 280 0 0 0 486 556 444 556 467 306 500 556 278 0 528 278 833 556 500 0 0 428 394 390 556 528 722 528 528 444] endobj 247 0 obj <> stream xÚ­XiTTW¶¾EAÝë„ãÕ¤«Ð8Å8à‡h¢5à¥dFf(F™Š±ªvUÅ(¢3*P‚Z § ‰qèhF;¦’“ÎÐ}É!Ýï´Iº_¯õV¯õþܵ¨sï>{{ßù"ÆÖ–‰D£ö¸nqYëú’³ËÚNÖ–¸ÃÏyý™vÂsŒð¼Høƒ  lÿÀ0¢Ø±Ö§d4}2÷ÇXŸ³éCº|c+qqÉ'§Eóœœ:GF%Å„+gù½è¸`ùò¥s:9-w\â·/ÂÑeŸ28 |Ÿ’þæ¸3Ò/$@™ä8ke°Rµbþü„„„yûÂcçEƽúâÇ„e°ãŽ€Ø€˜øÇõ‘JG×}ᎃ9Ï|:G†GÅ)b]"ýb"h–ã¦3³Dslœl–Ø®bÖ0΢ ÌÛ¢]Œ»Èƒñdöq¡¶1ÃH˜aÌpfcÏŒfÆ2ã˜ñÌDf#e˜ÉŒŒ™ÊLchf.3™Ï81 ˜ÅÌf)³œYÁ¬d^eÖ2ÎÌëÌ:f=³yƒÙÈlb¶0.Œ+³•ÙÆìdÞdܘ]ÌnÆÙÃìe<˜¥6Œˆ±eÞÍ©DçD·DßÛ¸Û”‰ÇŠÛm×Ú6ÚÍ°ë•ØHb%ß°«Ù¸ñ\õ°EÃLÃþ:¼qø#6øtäꑞ#ŒüǨ°Q·í7Ù7Øÿc´eÌ”1Ác~ûÂØÎqÒq©ãÞ¯ß=aÜ„° |êDf⛂ھÿÎN3~öGLl½a]üޱà dÐÞ"î_Ý¿…/.‡BÈ窔¦ÊÒ +;[¥Øì¢Ü `s“û™¸#ñ%À½±t™Eæ?T\½òÞ9|IåЕÞy"±'ù"ô€¹¬ªxàå_FJ³3òr!“K>˜Z);ÅÆ®TXÆï/ÿx¾8Û|ʇؓq^~¡rá’ÉãKoœÛö[è«ï\Äé22†,ÿO_Ø R¢7ý¼£JôÅS1Þ'é<jôYÅ þêƒsW5 3Š7Á®TeÈ’%ç^†Œ#²pò:ç`‘L¼Iž;¹ê“%uÀ•J=hè4ð€â8”x}éþýŠO”Àe©ÔrÈ1¨Yw_¡QˆÈŠòêT§¥€ò¸Œu‘ì0œéÑë‘Ç) ¸pgGÉ.®A'Q¾"ƇùÜ9nÛcâT™ äp™¥Eß>Äço„^Úîìã×pNVGJŠŠèÇkŸŠJñ°›p-ÿ”žÍÒx0ËIŒáñ]Á­>>ÁÁ>>­Á]]­­]2{Aa›Eí8—ã±àƒäŸæ@$köK@Ò0ƒSŸÊè>ÜJsžäd¡NÁ†®¢¯û %P–äÂù^@l 6‚SžGöb÷Ôàè6`r,§(d»q„ßëóÇs!D¶qóTú.§`éÇÐ[É ”[Ûfx ]]_AÛÈi±ÖÏq,^ÂÌÑYœ†Ã*ŒÆð ‰:6{oúܬ—A )i¨}çZCmՑ󧪎ôœ5Yà‡6 >&öSVlXº­;¥öxGõYœŒ® .l8ÚVP ÜýÒ¾rØ™¸~Í|²ì•ªÒi‡¹$ÁÖºsF×;è€ÓÌpLY•èQ/.éb|AÐñ‡ò µGÃç?FÛz£¦4]®¦fåz&zfù‚+xŠ,ËÑ«õjàR 퀜œd ­FV ù†cé¡c7»kçËAÞáiþAÂ(ûŽÄvYôÕG¡•ëõ©ˆMÙ麲ωNêÄo?ÆÉ8vù=2B–û´ÞáÜ`‚øƒ¹ÇÖµ‹:ñ(G¹× v<@Ÿ±û0ÚTZ &¨Í®HŠR‡%‚/RÙnn¨é|+ôÖì…dõÒºÈA BÑ“Û8gν>“RÛ ¢örï“Gü~ˆoT5f™ Z¸+€#>”ST~˜!švY °Wž£ ìt†I(ı+\ŒcÅB”ð„/.=r $‚Í]´Á»@S¤®à’`b´³H Z ÚË})ž“%ëç«óÈX²Èn‡×/€ñ¥àº¬—…»…¸¨çúPѧ´ÞÏ1ïs1>XþbÛÑv¸Â=yµw:åº|Ž vÖ7|«78qÄîñVdQvû1Šd”¬«z‚«9²è>Ã~Ú¸Þžº s{SÛ÷%¦pÄfÿ·7ÚbZâ`·ÃÆ]Áo,÷½tG÷º;*m_ƒ£{Ìø7+æÏã ø¼ï`¯†hMtÞ֜蔨Œ¤È`È„ÒÔTPSMÛÙ¢lôŠRîÛtzÛ×pÉe4_,#¾²•àêåê 92í‹õßS=<¥«ëæV¥ñþؔר®‡÷átÃù†|Ó‘æ3`†Ê¢º0™V8Oµ`ƒÌ¾ÿ02}¸´Ot±®¸%ÞçËšàè±0H‘Ü’¤„AXx”É…»DÉWƒcG# ]>ð‰$=ÂÃŽA…ܾ?,øœEp« ‹úó™u*]$AdF“ào¥¹)Zu„:A£„+o›túç5µ”ªlÖ:t:½¡¸ÅRŒ”XÈsv˳áÏÐÑ~Ìô­—YrAØÁI*툫ľ?0Ã"ül]DšñÜþü(N’e‚F“•½}—Գýz#e¶;™O&x‹/‘Iè‰K¿ÂI?Ueë’åicmr6‘ÎÞ²^‡uÇû‚¯ä¼ áøÚòîÙ›–wÁ§ð™‹‰ÌÐ0e|½N_OK5RQzhQé{ÏãLqKÿZ^ñÕÀù cñJ&c0…8â0²LN¦þ2žþ…½ ×"š]k}жÃÔ¬±Þ¡;]"œéô÷7dXÐÍ" ¬oP©èŸ‡IüM‹$Pí ~sÀ{ä4ŽÁ®Ü˜!ó€e•wý¯i>ƒð|Óqµ÷Þ½Ò.ø>ßVM^ü}ºÊþ+2nÝ;î¦È(È2‘(I3+ã(¹g¥^_S¿’H—8G2ëé+ôµç¡méÁTPÉR O›—ž·y m}XuR{R»ö4tsWÇ|I¯¥šCê)ɺÑn +ž±žsCåm¬W«¯!–Ò{ÄÌWèÅjÎ7¯¡X~ÚË[9_7ÚYX—lh— e‰dà)¯ Œô¢UDÔ¥µe´Àh…è-k­èh®; ÇÀœÒ@÷ ÌéÀ-͸ÂÚÎ ¸õ‰X˜|Q×ø0ˆž§ó ¿`-kú_–à$œ|ú{ÓáDÈ•'ƒ&775Öu{¼MÉ–Úþ+òf[Ý9²€{ä¥Ü/SüÁ‚QfÑ×ÈÜÀqbô¦ð_Zf}/ÁaëJeȇ|­*;5¢9ŸÖÄú£ÇM';ƒO;ÏŸæK$²Û—ÉëéS i{gЗ,¶º}âiÆ9_ß6£ò¤¨Ç£ Åb\ð'>Z] ' ¦¨T§+Ï6']¡òeùö‡r8Õª*-+*Í?˜¯UkrAÅÅT&Õ×W©­Iiõ¥m R„ø5îɤÚ¶n•|Žø5)ÃüÔÔBeè÷´‡ÈyS ;¸½g^Åu¸à½¾›8LÂÉŒ?ñëáêÙsÐwó&¸ìq×õòÓÄ›ÿ°+ÙË¿û 3ΜyûTÒ#þž_^Õ33#L¦J9º £,øZ•èJYÄèNõ GYÈ(Ü©h—FÉŒ<.èi` óiü»4Ýx[vAáÆºŽð‚wȆ„^ôûñ-ÁõW•wcƒ]7oÑV÷Êð–lþ °4væ{‘OeõôöÑvƒÓmàºßŸ±25Ï$Œ¡>fƒ0‚/‚¾t™ÅIé;SÕî]RPqÓ¥÷HZQì`>‡ ÄPTÃ=Ó$^B=ÿN()/0~bU£P¯6)fϬ‚Rí!ÕºÙÒÕÈØ±–¹Gã°_gµF7¨±$®SÈôÔÄýt´ìQ}®¬ö’ÆdÕ]ž>­èS´•Þ'£í<’£ºkúú¦SƒÊ²Á 5Q˜…ËÑdÅÂ:a˜Õޝý†·ç êÎÑK;hs3@û2‰‘FÞÜŠó³j¸‹ÿ óyS²âb7¥Ç;Dze%ƒ 4º<]Eau´pͱµ!‘‰þŠ6¯ ²àìÍë'Á–ò\ <'Ìà‹ÊÀ…œ)’däº$8Sƒ]ø¸¼àz%$u€ÉÊ Ètˆ+‡#2ü@r½ì’¬—27’ÑÀ½)±Ï(¶£—©¤TB<¬e82#:Œ#G"Ó2r”l¸íÒª‘Ãt#íñó ÿÜÝá endstream endobj 248 0 obj [446 446 0 0 0 0 0 0 569 569 569 0 569 0 0 0 0 0 0 0 0 877 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 631 0 0 0 0 0 0 0 0 0 0 0 0 0 569 0 508 631 508 0 0 631 323 0 0 0 938 631 0 631 0 446 0 446 0 0 815] endobj 249 0 obj <> stream xÚµ• PWÇ»˜nXº„¸éO@ ‚Ç¢®Gc”#¨x”€Ãp 3; TÀ çÌ|Ü·ÎpŠ0ŠŠ1f5f  f5.»HŒ‘¢\˽¢¯Ç‡»ÛcÜ­Tm¶j«¶¶ºê«~]ý¾ïÿû¿÷½GööI’ÎÛ·„oˆ[h¯Pâ’Ï­9ü,‚ÿ)É¿idz"~¦ý›AΙ!DÂêj‹cÓmq¾'Ý{’¤Õ…þþËüüý—)”‡T‰²µÄ'ÎW°jUàbÉRÿU’ r©*1.&U£NÊcÔ E²C—(U’ø¬IP«•«—,Ñh4~1ò4?…J¶Îw±D“¨N„KÓ¤ª÷¥%›©jɶ¹Tb“ìg A ¹2]-UIB¥ªTAé4Òßn9±–ØAÄqv ¤œT*BMhÑŽ„1ƒp#Ü †`‰åÄFbñ±™ØJÛˆ÷ˆ0aV$±‹`ì’°^Oä>rÈn¶]œÈUÔ(ziÈþ¾C¤ƒY&þ„ZO©‡t¯sáÃq±éE¸‘DÔ-BÖ‡ã7vãÀož}+P4–ЕµPËA¹®8¯{!çh´P0 –¿ ϱ;¥¥%%PF×…\ö ëo‰ ùòŽÂQ JtåyÖüÏ\XŒ—bÂ÷ðaƒ è‚’¼j¶£îw"# Ù1H£‘„vá‡5f+m&¯L ž _‡¾dÙeîI¹zöç@ãLÀíAA€(e2~ÉáL<Äìƒmš±¬Oa îÀoà«ú«¦Ñ!Ó9ø\Ij kˆ, ‚å°6d‡hüßM[)°ðm– ‚þŠß‹ÐCët¦C_¤`âoˆZFµÂ0\5ÓSTd{³R™¸©¹–œ>‰ÜtÍÎó,RÊêNq¶D_£'Ï&-äà3”ûDÄ£`&Q¬K×nÏÖææ¯ƒ,Avˆø»Éó¯ûï|úÅgð˜FÓfßÁxzàò%»ú ª[;-My=;Ù“·o5÷ýÇ+kWs°’°K!:*]JÐ1^øÃkê©*ꀂYU #¥çO¡«ú‚ ÖB‡¶PßÝ©ŠØÅâŒÿüŸ úJèÄýÈ Q$š)Ø*ã_2iæD¹2-IÖ™nîjo;ÅâÅø=ÁìÁª|Á캦;Ûc1ôØÒ…iá<‡þ.táºW ¯)l ÖÁ‚¬ÈÊÝšÛ‘ÍaDíWì¤ “÷¿˜píÿÎô_³¿¶üßýþ¿IJâ( ò1ó³ºH4}õMˆÐI¼”ù>K UVÐ5nëtäð¹#×ùÆî\8„½Gß ¾_ü‘²‚n*öGª¼Í·2'._oÿèñÏ—ÍÁâ·Æ-ƒƒ÷tåÂ.M;ý.rÊîöðx9y¹Ùp„NjÏ>ÞÚÜp¢;ùÄ^v7D¤È×Ó†çb<÷G(ƒ[¥çú.èû2 µjº…$\ÛÅ;ZÐJáLwE’nÚÇs ò·`’(6Äú,ÒÑŠIÜBaûqõµ›?emGË»Éñ7Ãxëb½¦5ñÒº}Ã/Ÿª>YD[(¥îˆ!U.-’;Ï“Q=†Æ Há¼ÍÏZˆ‹=1ÚõeºJ(÷jn/1³J¦“d©òâTÛï-`‚ºÜcÚª$¡—õú|}á[ÂU´Õäƒ"(õj³@“0G› ãR’‹Rlsz¡jR‡Ÿy–g–ä6A”T–Õ!Ôë‰DØRžYšÓ^Â׊òÚEcäƒêQju•QŒcj(‹ÓèOÌ•ÎΣ ÎÓX'û@£³#ïáñó_¸ endstream endobj 250 0 obj [339 893 585 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 905 0 0 0 0 0 0 0 0 0 937 672 0 0 0 0 0 0 0 0 0 0 595 0 0 0 0 404 473 607 0 0 706 0 0 0 0 0 0 0 0 0 648 579] endobj 251 0 obj <> stream xÚ••ypõÇW–I~Ç„µrIvEÚ¡¡Í$:M„’ ‡9 ƹˆeGŽ/Ù²¬Ë’­[+iŸnëX¶$’/êà8§)Wp)Ò0¥d RÊÑ™v¦»fÝãgS:Óé_ýçíìowûyïû}ï'"ÊË ‘H´²ú‰ÇÉÿá®={ߺ¸°ƒ‚kËûæ7ñwüZ¿®Œ'Åü·ËÉkO”ÿ³¢lAˆn¿ G‚¿u1~¶j1~‡ÉÕD¹H„t&ß–-÷mÚ²åÞ]ênMó‰&­lCÃݲ{¶oߺQvï–-Ûe;UJMsƒ¢]¶G¡mRªZ|Ó&«îhhVj»elÒjÕ÷oÞl06)T]›:4'º{£ÌЬm’Pv)5zåqÙîŽv­ì)…J)[bß´wu¨Ô:­R#ÛÓq\©iǬË({Ѝ'šËÚ £ˆ VëˆUÄfb;q?ñSâ BNâm‘±,+Ö”o,å&ù²ï.ûóòAtœ÷VrŸ 5yn'·\Ä(‰¹ wË›]޶tu¶µvþŒ‚Lƨò«Uçù/s"Ž˜ß&žòƒ’d$¥l‰^’¬îN¸ µºí.°€9AÇiþK¼r… (•H¤(H[#ŽÐÂnTZÉÿ^濪Ή®ò‹yß|$ÂâC(c‰ÙHÐVÚ²°â[¥n øÀƒÌ¬#Af!œ ³g-LñÜ”hþ]þŠ$þBfòý §ýùÝg§Z=Í]û»*ÖÓ= ³°LŒºÀd{@N†öÚÑÂcR!ÊgYtA•°n™ÑºÞ$ä©<˜¼GøÎ„ԡ4©vx‘«—1Øú`D›qb,d¨9ÛãN&ŒJ««ÝGžë6V •ÂÊzÅ=ž^Æ Gž =AŽÂó¡1ÈÂ0d™~¦àË g óuSv¿>yȰl¡ÀãK¹•‚=l÷û€©w·¹Éë`,‹;1~K†ÌÃp0_ôçñ~CÐÏd™¼/³´_!… Bí:áÈ¢Êùûþ­åýü%É@.×_HÏ”NXb±HyuG¤FåélU¨þ£i˜õ Üàp;]·ƒv¹ÝBPHI)wÞ•ÂFòWõÏB„e¡àÖLªvzT¹æë*㚤pMBޏŽÛ,\—>'È-µŒwSe²€Þ¥cÔ s€Fýý¹Á|Åzœ7(²HoetŒoâIÎF‹}ù?B¡4âqTÉb/ñT‰«Ÿ½ñ˜ÿõüF‰?dÁž˜•4À6§Æçdz\°Þ$gÁå$Áåsû£T?Ù NW¡HÁ@ dÑάÄÕ¡3èŒgCk Æ#W(xe”+»§_m葹ÖÙcÜFÿ7Å¥i£µNýÈ!@jç0–9 Ȉ?ÊBþ$T¤ÁÑþ““ÙôK³?¿p’Àzûìu.G3ô ]¶g°8V8=Ùu²†<ÏÖ×Q4´´Õ›pÖ,É.â·¾ø­˜«¼ŒÅukÀ‹týö Ùû> Çú&Âùð@â|d8Rˆƒ‰™@ßèLéÔ…—ß4ç¯Ålo 6+lvFÍÙ–—þ×uõ €ôžT;#ÌöŸKŽÏ|ч²5ä6¨®U5¸ÞÞW¨‡:жY´ºÆÞø€úÆ"Áh1ý‹§DuØ"FG£KíRÛëiÎâ{éô/99ÖG4{ƒ»þ¹˜ |!±7·5ç ‚ ¦´¶£½«ñàEí‹äy˜>=TóZ÷)@Üò7¸ÛJ‹¼Ôb±=Výî½ÏVjÐ_ `dè“'νwnx™qÈ÷¶:¬нTÚÁÉÓåÙò 4´è”Ý3GÇð‡B¹\¸UµˆOa‡„ÂìðÕËg^4Yì>LÁzÐÑŒmõ;ìðÉOg–4øèÆØ;b|f¬”„GYåÌIi#m3zÝÎVÚ ß&uwµ «½6Žýh Gá­~ ^¼<ö^r"œ„,š­?ùÌ]Ïýwo ÿáÌ4N1Ûgë½åÐÑ–ÃB¥½ŽásãÈtëxçiº§`*=9fyÚ¦PT·5´Ô€ Ž€~½Ylñ‰öˆ]Ób8Z;Ûx…ü+p·^çnC•†¿+OrêÜ2¡.¾œ¼¹|k®bE´âfÅ-7pËD¨¢‚»¶æ_•ײ endstream endobj 252 0 obj <> stream xÚ]‘Qkƒ0…ßó+îcÇšè:"tZÁA·1[ºWM®N˜1D}è¿_¥+{Hørrnrsâ¥EVÈnïC¼Ä šN ã0kŽPcÛIBˆŽOëÊͼ¯ñÒC¥ÞªÁ;Ÿ³ÝkyŸö_Ô8sºÍb9^[×EV^Æ ûB6Ä1ð>͉ã¤/°Ù‰¡Æ;«½kº“-lNié”rVê{”ø$IÜqté‰GUqÔ•l‘ľŸ@œç A)þíÑp)©þ]iSkõ}%†éÂÏ–ÙüéìÆÏnü»2Ú¿X¦Žó­ápÕ3Ë«nkC¶è©å`ÑŸ ?Z?c¦ÃÑ•ÍCÖŽí“lø×ìù¬µ Åý‹Û&ÓI¼~¢”­rãJŒš endstream endobj 253 0 obj [597 597 736 736 0 0 0 0 0 0 0 0 0 0 0 0 792 792 0 0 0 0 0 0 0 0 0 0 0 0 0 0 875 875 0 0 0 0 0 0 0 0 0 0 0 0 0 0 875 875 875 875 0 0 0 0 0 0 0 0 0 0 0 0 1056 0 0 0 0 0 0 0 1444 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1056 1056 1056] endobj 254 0 obj <> stream xÚ}TmPTç¾—ýà†(IЭ˜¹ì®¦ƒ8¡ˆF4±Â$!!† ±i˜‚, -ŸËòý-_»÷ì. ‰:S;F#iMI+FSûÃÔÆNŠQ:ƶc,SlâxÞå\Û¾ˆàŸþØwßó¾ç<çyžóν^E14=ý¹/¾þä®”çßÜ«l-•ïˆ÷ ,Z`?YLÛ c«ô‚ôÈc|§ÑÖ«òU0óEÚ&˜‚QX.<.¬â„D!UxK° ¡^p =Â;ÂIá#á÷Â%á/b’ø²øVq¦ÃV˜oËq&æÙçöŽ<{îý@»Èʳ/¹¹-Ô˜àGuV1V|V—*¼)8ù\ÚE—èDè}b‡¸_ì»ÄnÑ/öˆ½bŸ¦MO/´$–ˆ7ƒœ:Q—¡ׯÔWêè/v>1 Æ(ãæ e_Ë5#²qjXÄä/t¬OD›¼Š¿ÉÒ¨Ñ×íñ[ ÃíuûìÇß8“‚A$`Ú^À`©†ý¸ Ÿ÷ùÀ^©§Ìõà†}ÍÑ V²$‘ý'î¤8 m@M¿¢ÜHµG²OdÒÓÐ_ÓÝ"=Ðÿ&ï¿ùÞŒ p,ÏÑ,«;˜s²t¤¥Ó õ 5íƒ& ´w´{ÝÇr?N»@A(PÚP ¨I´Œ†(™^r»Ý.pIM~è1/ø»o]»‹–?¢ýFŒâÀ8)4à”ï^‘ÚÂÛfOé©òÝÏMóBsN$_LæÈqØ›ˆ“À8Ñã8ƒ xú ®½víÔ).× >Mn¹ŽË­­¥tn­šj¨W­ØEÃÎ÷³>°÷5x¡¤þ.è±,íÊR§tì]™*MÀ"62+uáDÅ;¶²Ž7ô¹¡¤†EµïÙ/&_äÆÇQïešÕ4j§J ÓOÓÚøøÌL·ë;Í}æ~Nn`oà¹;,Xû ùNɈü°‹mœÖÜò“6±Ö®'QÚŽ+SÑB«ð|:ÎK¶ã7,£ðê9\ñ†ü ¯Ïë…Mp­¹– v»%åÕg(ˆIyŠÆ3èt)Å5S<ÐVPCÆÕ0ÜL·þDÑ·(â_Oø›=Ê Hó,raÓ:6!ϾÌ-ù1 £Íxë9ŒŽÆˆ¨o÷u+žjêšçMhóºþIÒ—´òiRz[¡¤4cY+ÔYàû í+!ïj?­¦Y*¢O[öi„5×Ìç\ïðá Œ¼oc8NáÙLðÁlÀ&½:=ÂÎ~gzdµé°â)6§‹¥Ä¢þ!¸Ä£ájx<‡-‹Ù |þöìØjÏÌFŒ‰,A=j"T_jnRÜоºÑCæÀ%ãuôFdzɯl)¬iK*¥u ©Ïq†íìò{}б:wf’ígV#«[.Ñ«Ò!cÖî]Òç[BeÃ!yÖõ•¬ÿ÷G¢¬ÿ†ïM¸/sðì'Ö¼@ÁåmëK(£ÏY'ûº«›£ï_­}:ZzÔœÀcáìC#>ÿ¨ó»?nþªúÊžC5ŸeÛÆûÐr> stream xÚU Pwß%$þµ{^£AÏl:ÒŽØQ{õü8GÁbý)T©E"D` ä;»o  ‰j´çWÕS®½¯7:õFm;jÏ9½;oæzÞ¹mgnçæ¾ÚéÝììÛÙ÷Þoï÷Þ#‰øx‚$É„é¹Ù;_)=3wëÒÔÉ'«3y×ßð„IÌÍ'¸Ü‚8N!âæÆ+„*¤q ‚œ÷=Á_Ïš´ž´Ï f:Ì&âIÕ4@jêò”ÔÔeé•z­º¸D§\T˜¬\ºr劗•ËRSW*×kTZuaA¹2³@W¢Òè„›2enE¡Z¥Ó+­)Ñé*W-YR[[›R ©J©Ð¯M~YY«Ö•(sTU*mªH™QQ®SfhTÊ)è)S—ô MeµN¥UfV©´åÚééÄDQH¨ˆâ¸2¢œÐŠ"‰H&Òˆ D†ðn±™È$¶¹Ä[Ävb1+Ž ‰x"D6Æ-Žƒ¸¯E·â½b±ø‰XBO˘vmã ª£¯DIL<M'6ËÚ¬.«ÂšvÐŒÃFÓÛ3åf30 kiÍ¿’؈ßÏðy¼žß‚y)þ!u>Šþìüooy,òZX›Âf MMýú Û¶½cÈ´”—^Á›(è¼ú>~öܵ{ãaé8Oð" ÌŒL¬± <à„6hq¡„ Dñ/¢x4JŽLÄD{¹Ç2÷pKÇM@A‰;*.q¬UQ:K“³ã0cB}’_y-5XhcVñz9Qr ›ÜQç‘Ûø]œ–”ÛJé¦U€ª%¶2ñ1×';ù1—&±í®N¶ ÕH¶6z‚¸XÛ6†ýrüžd/ß3唸]œPçhb}^$¯þÓ¿qÍø™ý¥Àa2kê„ì–`/ÞöóNŸg¸Ï º±ñŠ7nÎ5x«£Cýƒ ë}UlôØåŽ «‘=;)0Z¶Û…âÑ cø•Vþ™5‚Öþ¡þœâ 8ûQ['Êø‰±O1WG®»|l›çâW¹e6­Lu ªªÄPh_éà»°€“qƒWÀšÝÂ#¿;"?¼+ˆ¸ssdy´m?Ñ$’Ð`ï©ké‘Mü^ÊÏå)^òéº?áyïá™ím§M!臶6ܘsðM@»2aÏÿÏý’ê„qz¨äiMN ’Ü­×DÜ:\/dàêu¡<ÏXs<ŸÏ‹…s.ÿ骿àY¿Ä ÝjÐv›q÷’5Í•€ÞycD<Ç\]¨¥Ov /Ø5è.$×RPÍXì•“ôóûûqÎøçý8ÿ&Ùyñè(¹4ò¾ˆkçÒd6úp#4 æ¶†^_ÀöZGŠŰϠÖ½êp ÅËÖ.£@ÕUÙm0›U…ð¨»t]Mëöï†|´ù³·±ô!^t Çá™|"$+r%å¬!ƒàf#áðð¡˜-èÑÝ[w(4… ýc§Î€Oèª.þˆ¬¬°çç´¹¯Ä‚££þ!@g·P`²oÔÕ•ו*å±,%{ìý¾‘Ñþ£½pн‡–õjî Tw¢\b8MrÙŠ87¾"sõ€ ºÑ]á Åk°#«ö ÃÊÇñùÙF†ItÐv-8ÐÕN[%%´»Å¡õ+¿Üª²ÛÖb&U=Ê^r†C—éai’'*Þ©ƒ çÖ˜+Ð:Ö:Ö6æi?wþläh¬{ÐÉ@í èfÓ›j~¦²¾%L‹Ðn”€#rñi<ó1‰3þ*± ‘¬ßЯ©(­*.ï3„£CCQ¿”Ï‘é†flà°×.ûþ9ŸïûÌÃìeçÀ‰=ø$Y~- Pà§«ûŽ?É7A“#Ø'Âg„ø¿Ð1"üGhà}ü?ÿãižÐ ø÷2ÿ#~a³à3ÎTÌ—Ù4½UÍЖ ä­Lþ„–ðEzTšäþ?ØÍü¦îî®/ä-aÏqðO) ¶¯o8$àœ?…?¸+Â:|_æÿ’O0Mq›ø”ÜbàßÉ=Åžqyî1B%^¶ÃéEu’¬¦É1×9Œ_wüWÞ}p_øvZ½¥YµH²øBÈpe‘b ìÚQ•'`P4¹×zÉ;—pî%·˜[-s¶Oö>ò8Üfa il2 ¬÷B£Ð( ,ÝMº[0ÕE¬gMc¦÷› ©µžWì‚l¿ÏdºÁÝF`½ŽŸ'§MB ;²´Ø[n`Ù¾€ÇÝés»Ãê˜ñ¤°†^Œ=¾HA¬>¤÷—G¹·{óÛs;àbáþ~ïMHU@#Ý((ÂÔθÀz\~¼¼9Ä͉âHœ ÔÚÂ%ÉðBÉS6ø…’Þ*ÖJê_ÙñÒ‡£Zþ¹$Ÿ;ô”ÆÄÅ·ÍÅYˆF{F{¢NŸï3¤•4¥ Ãç¹AW¤T`<9DAÛ¶NJJ )ñ4‰Ÿæã —%ãeÿUª«ÚQSÃÏ–[ËÌyûö–––…‘‘ÆÄ„eâf{Ù–qüHþ ¾Æj~Ž½Úª2æBÊŠîû³°4~ú‰ÇË2òÃ+ðl¯ºX–Mt9[BBy²›ÜG)¡P­®”PäÒý¸¼Ã”ðûL‹Î¸ùL°]*Ü_NÇwžû;¬Çƒ˜ endstream endobj 257 0 obj [893] endobj 258 0 obj <> stream xÚcd`aa`ddä öŽrÕvö Ž4 ØÖüó–ayüsëi†2Œ?d™~È1ÿg‘{èÅòŸ‡I–á½ ˆ|Ã"_€Hu Á('ÄÀÂÈÈQZÕi``¬g``äœ_PY”™žQ¢ ‘¬©`hii®£`d``©à˜›Z”™œ˜§à›X’‘š›Xää(ç'g¦–T*hØd””Xéë———ë%æëå¥Ûiê(”g–d(¥§•¥¦(¸åç•(ø%æ¦*€Ý®&ós JKR‹|óSR‹ò€ŽbºŽa##‹Ö¾_ßËö0~gøiÁü³æ{™èìÅÝ‹—”tWÉÿyÁV]Ü]\´¨{Ž<_ñâŸöKØ~ËOg—ãbž¦úŸ‡sW÷®=Ü{æóð1ï÷‡"Ì.e× endstream endobj 259 0 obj [525 0 0 0 525 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 525 525 0 0 525 525 0 0 525 525 0 525 525 525 525 0 0 525 0 0 525] endobj 260 0 obj <> stream xÚTkLgawÇQ)‚qZ¨º³Öjy-˜øDªÅªå¡FliZØûbva¡ÈëÂî²ÈcÁ+, ZðQ«1‹Ö¬´X5µ1ÐÆ&VÛÔ~Ó M:Ë#‹ ?úçfßœ{î9çŽ …Žãž‘Ñû"vÆø†EEG<$u>ÛšÅØÿ‰±Ë1vήtcÅö ¡øi›ÒÝm%†áb/gÅ—ð{îé¬+ù² w)&ÄqRg4K¥ë¤Òà0¥*[“œ˜¤•¬_' Ú¼y£Ÿ$X*Ý,Ù‘&×$ÇË’(™6Iž&Óò7©’he|²\›-Y’¤Õª¶feeÈÒÒ”šÄÐu~’¬dm’ä€<]®É”'Hv)ZÉ^Yš\2K>`ö"L™¦ÊÐÊ5’(e‚\£à¹’áØ^L†Ëñd‡Õjy› A×d<©·µC;TÚ^XmŽë_÷Ýrè|L‡o VÜBË||uñ:EÑÔéx€Vøõìä¼¹Eœ_EOB½~{Üa+´iè (-.ÈQÇ}¢“zîwºþÕz÷îà(Ï`S: ùPV^äô 1È‹ÁÑ0KPh©Ó—™¬,$Ì-5ææªÞŽ¾10í3 §ëÎÞØ9tÄÆóSRËŒ¹äj—¿qC¢9Á@m.L_bºá£–›Í8øCÀ®aoS­:»2U«Ô¨[2mmbβ’â–zõ,ÆUÆâ:åm¨³Ï” Ü[®P#Œðàt Û3ÝÂ>ŽL/lܼMB'ÿ¤Š•yÇ2Ô‰ñÇ È9TÑ`ª¨!;Óë³sRóâwý ýb$…Kˆ¶žÿŽÝá=7\°knäIÌ.Éòéœðç=æ\îÍ9Ã=r-ç9£Î¾!@… ¥IŸ966-”´¥« ­¯vœºs¡§È[y" …å¥åE2®Î{¾jGëïÕZ/@4’|v¶‹£!.¾Ð˜ßŸR« $¨´%í 2ešØ)è FfºŒÿ¦5̳à“*d¨Ø9cúm3&Ý舵¿¢ š|î:³[±™Ÿ*¡²Ò –y–ËÉäã9PÁs¡x*UçêÚ[¯ \b€¼X­SÐPTžW~|jï3øÄ]Ô5,`Mè…„¡÷ü9/ÎóähŽ|¸ç´y Åhµ˜ËçS{b™Ñ¿ÿôèÛËwú‡®¢gÜàCÔ'£E»“€Í•ÇU„¥«ñ™©Î>ñðñK¨ˆï,©ÒÑÔâÜù´/ì‰4*mæS³ƒqn®AÆ'E^/Dðzå³^¯äæ 29Jïw> endobj 261 0 obj <> endobj 5 0 obj <> endobj 262 0 obj <> endobj 9 0 obj <> endobj 263 0 obj <> endobj 13 0 obj <> endobj 264 0 obj <> endobj 17 0 obj <> endobj 265 0 obj <> endobj 18 0 obj <> endobj 266 0 obj <> endobj 55 0 obj <> endobj 267 0 obj <> endobj 71 0 obj <> endobj 268 0 obj <> endobj 87 0 obj <> endobj 269 0 obj <> endobj 97 0 obj <> endobj 270 0 obj <> endobj 98 0 obj <> endobj 271 0 obj <> endobj 117 0 obj <> endobj 272 0 obj <> endobj 142 0 obj <> endobj 273 0 obj <> endobj 143 0 obj <> endobj 274 0 obj <> endobj xref 0 275 0000000000 65535 f 0000161202 00000 n 0000161050 00000 n 0000156537 00000 n 0000210902 00000 n 0000211219 00000 n 0000000015 00000 n 0000000361 00000 n 0000156614 00000 n 0000211546 00000 n 0000000457 00000 n 0000000921 00000 n 0000156767 00000 n 0000211875 00000 n 0000001009 00000 n 0000001876 00000 n 0000156847 00000 n 0000212193 00000 n 0000212511 00000 n 0000001965 00000 n 0000003579 00000 n 0000157003 00000 n 0000003706 00000 n 0000004629 00000 n 0000157083 00000 n 0000156420 00000 n 0000004717 00000 n 0000004759 00000 n 0000004790 00000 n 0000013868 00000 n 0000013899 00000 n 0000014186 00000 n 0000014687 00000 n 0000157239 00000 n 0000156245 00000 n 0000014798 00000 n 0000014840 00000 n 0000014871 00000 n 0000021697 00000 n 0000021728 00000 n 0000156382 00000 n 0000022015 00000 n 0000022057 00000 n 0000022088 00000 n 0000032234 00000 n 0000032265 00000 n 0000032551 00000 n 0000034475 00000 n 0000157319 00000 n 0000156518 00000 n 0000034597 00000 n 0000034639 00000 n 0000034670 00000 n 0000036802 00000 n 0000036833 00000 n 0000212821 00000 n 0000156323 00000 n 0000037120 00000 n 0000037162 00000 n 0000037193 00000 n 0000039638 00000 n 0000039669 00000 n 0000039955 00000 n 0000040840 00000 n 0000157569 00000 n 0000156459 00000 n 0000040982 00000 n 0000041024 00000 n 0000041055 00000 n 0000046296 00000 n 0000046327 00000 n 0000213139 00000 n 0000046614 00000 n 0000047810 00000 n 0000157649 00000 n 0000156284 00000 n 0000047961 00000 n 0000048003 00000 n 0000048034 00000 n 0000049655 00000 n 0000049686 00000 n 0000156401 00000 n 0000049972 00000 n 0000050014 00000 n 0000050045 00000 n 0000056512 00000 n 0000056543 00000 n 0000213455 00000 n 0000056830 00000 n 0000057921 00000 n 0000157805 00000 n 0000058084 00000 n 0000061018 00000 n 0000157885 00000 n 0000061147 00000 n 0000062170 00000 n 0000158041 00000 n 0000213763 00000 n 0000214078 00000 n 0000062268 00000 n 0000065347 00000 n 0000158122 00000 n 0000065497 00000 n 0000068003 00000 n 0000158282 00000 n 0000068133 00000 n 0000070752 00000 n 0000158365 00000 n 0000070903 00000 n 0000071773 00000 n 0000158448 00000 n 0000156264 00000 n 0000071881 00000 n 0000071924 00000 n 0000071957 00000 n 0000077616 00000 n 0000077649 00000 n 0000214402 00000 n 0000077939 00000 n 0000079563 00000 n 0000158711 00000 n 0000079707 00000 n 0000082457 00000 n 0000158794 00000 n 0000082577 00000 n 0000085263 00000 n 0000158955 00000 n 0000156362 00000 n 0000085415 00000 n 0000085458 00000 n 0000085491 00000 n 0000091857 00000 n 0000091890 00000 n 0000092179 00000 n 0000094006 00000 n 0000159038 00000 n 0000156498 00000 n 0000094172 00000 n 0000094215 00000 n 0000094248 00000 n 0000110263 00000 n 0000110296 00000 n 0000214720 00000 n 0000215029 00000 n 0000110587 00000 n 0000113233 00000 n 0000159199 00000 n 0000156342 00000 n 0000113414 00000 n 0000113457 00000 n 0000113490 00000 n 0000114826 00000 n 0000114859 00000 n 0000115150 00000 n 0000115972 00000 n 0000159282 00000 n 0000156439 00000 n 0000116087 00000 n 0000116130 00000 n 0000116163 00000 n 0000122931 00000 n 0000122964 00000 n 0000123254 00000 n 0000124877 00000 n 0000159443 00000 n 0000125011 00000 n 0000127007 00000 n 0000159526 00000 n 0000156478 00000 n 0000127128 00000 n 0000127171 00000 n 0000127204 00000 n 0000133555 00000 n 0000133588 00000 n 0000133877 00000 n 0000135670 00000 n 0000159781 00000 n 0000156303 00000 n 0000135847 00000 n 0000135890 00000 n 0000135923 00000 n 0000140307 00000 n 0000140340 00000 n 0000140630 00000 n 0000142296 00000 n 0000159864 00000 n 0000142429 00000 n 0000144576 00000 n 0000160025 00000 n 0000144678 00000 n 0000145936 00000 n 0000160108 00000 n 0000146068 00000 n 0000147951 00000 n 0000160269 00000 n 0000148062 00000 n 0000149313 00000 n 0000160352 00000 n 0000149425 00000 n 0000150228 00000 n 0000160513 00000 n 0000150337 00000 n 0000152519 00000 n 0000160596 00000 n 0000152618 00000 n 0000155660 00000 n 0000160679 00000 n 0000155770 00000 n 0000156144 00000 n 0000160942 00000 n 0000157475 00000 n 0000156693 00000 n 0000156927 00000 n 0000157163 00000 n 0000157399 00000 n 0000158617 00000 n 0000157729 00000 n 0000157965 00000 n 0000158205 00000 n 0000158531 00000 n 0000159687 00000 n 0000158877 00000 n 0000159121 00000 n 0000159365 00000 n 0000159609 00000 n 0000160848 00000 n 0000159947 00000 n 0000160191 00000 n 0000160435 00000 n 0000160762 00000 n 0000161249 00000 n 0000161612 00000 n 0000167366 00000 n 0000167752 00000 n 0000168167 00000 n 0000176454 00000 n 0000176794 00000 n 0000177044 00000 n 0000178061 00000 n 0000178312 00000 n 0000181369 00000 n 0000181492 00000 n 0000182134 00000 n 0000182481 00000 n 0000188558 00000 n 0000188871 00000 n 0000193557 00000 n 0000193856 00000 n 0000199111 00000 n 0000199330 00000 n 0000201534 00000 n 0000201705 00000 n 0000204005 00000 n 0000204370 00000 n 0000204634 00000 n 0000206497 00000 n 0000206646 00000 n 0000208753 00000 n 0000208776 00000 n 0000209178 00000 n 0000209313 00000 n 0000211033 00000 n 0000211367 00000 n 0000211694 00000 n 0000212007 00000 n 0000212325 00000 n 0000212643 00000 n 0000212953 00000 n 0000213270 00000 n 0000213585 00000 n 0000213894 00000 n 0000214228 00000 n 0000214535 00000 n 0000214849 00000 n 0000215164 00000 n trailer <> startxref 215350 %%EOF cluster-1.52a/doc/structure.eps0000754000100500010050000004406710506514243016444 0ustar mdehoonmdehoon%!PS-Adobe-3.0 EPSF-3.0 %%Creator: 0.43 %%Pages: 1 %%Orientation: Portrait %%BoundingBox: 64 113 366 399 %%HiResBoundingBox: 64.161544 113.46283 365.26474 398.19403 %%EndComments %%Page: 1 1 0 426 translate 0.8 -0.8 scale gsave [1 0 0 1 0 0] concat gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap newpath 186.176 328.523 moveto 186.176 333.648 182.023 337.801 176.898 337.801 curveto 77.9063 337.801 lineto 72.7773 337.801 68.625 333.648 68.625 328.523 curveto 68.625 309.187 lineto 68.625 304.062 72.7773 299.906 77.9063 299.906 curveto 176.898 299.906 lineto 182.023 299.906 186.176 304.062 186.176 309.187 curveto 186.176 328.523 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap newpath 186.176 383.262 moveto 186.176 388.387 182.023 392.543 176.898 392.543 curveto 77.9063 392.543 lineto 72.7813 392.543 68.625 388.387 68.625 383.262 curveto 68.625 363.926 lineto 68.625 358.801 72.7813 354.645 77.9063 354.645 curveto 176.898 354.645 lineto 182.023 354.645 186.176 358.801 186.176 363.926 curveto 186.176 383.262 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap newpath 186.176 438 moveto 186.176 443.125 182.023 447.281 176.898 447.281 curveto 77.9063 447.281 lineto 72.7773 447.281 68.625 443.125 68.625 438 curveto 68.625 418.664 lineto 68.625 413.539 72.7773 409.387 77.9063 409.387 curveto 176.898 409.387 lineto 182.023 409.387 186.176 413.539 186.176 418.664 curveto 186.176 438 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap newpath 186.176 492.738 moveto 186.176 497.863 182.023 502.02 176.898 502.02 curveto 77.9063 502.02 lineto 72.7773 502.02 68.625 497.863 68.625 492.738 curveto 68.625 473.402 lineto 68.625 468.277 72.7773 464.121 77.9063 464.121 curveto 176.898 464.121 lineto 182.023 464.121 186.176 468.277 186.176 473.402 curveto 186.176 492.738 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap newpath 315.105 421.125 moveto 315.105 431.375 311.742 439.687 307.594 439.687 curveto 227.488 439.687 lineto 223.344 439.687 219.98 431.375 219.98 421.125 curveto 219.98 382.457 lineto 219.98 372.207 223.344 363.895 227.488 363.895 curveto 307.594 363.895 lineto 311.742 363.895 315.105 372.207 315.105 382.457 curveto 315.105 421.125 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap newpath 359.215 645.539 moveto 359.215 650.664 354.348 654.82 348.344 654.82 curveto 232.418 654.82 lineto 226.418 654.82 221.551 650.664 221.551 645.539 curveto 221.551 626.207 lineto 221.551 621.082 226.418 616.926 232.418 616.926 curveto 348.344 616.926 lineto 354.348 616.926 359.215 621.082 359.215 626.207 curveto 359.215 645.539 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap newpath 186.176 645.539 moveto 186.176 650.664 182.023 654.82 176.898 654.82 curveto 77.9063 654.82 lineto 72.7773 654.82 68.625 650.664 68.625 645.539 curveto 68.625 626.207 lineto 68.625 621.082 72.7773 616.926 77.9063 616.926 curveto 176.898 616.926 lineto 182.023 616.926 186.176 621.082 186.176 626.207 curveto 186.176 645.539 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap newpath 444.004 507.375 moveto 444.004 512.5 439.848 516.656 434.723 516.656 curveto 335.73 516.656 lineto 330.602 516.656 326.449 512.5 326.449 507.375 curveto 326.449 488.039 lineto 326.449 482.914 330.602 478.762 335.73 478.762 curveto 434.723 478.762 lineto 439.848 478.762 444.004 482.914 444.004 488.039 curveto 444.004 507.375 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap newpath 186.176 586.539 moveto 186.176 591.664 182.023 595.82 176.898 595.82 curveto 77.9063 595.82 lineto 72.7773 595.82 68.625 591.664 68.625 586.539 curveto 68.625 567.207 lineto 68.625 562.082 72.7773 557.926 77.9063 557.926 curveto 176.898 557.926 lineto 182.023 557.926 186.176 562.082 186.176 567.207 curveto 186.176 586.539 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap newpath 317.617 586.539 moveto 317.617 591.664 314.199 595.82 309.984 595.82 curveto 228.574 595.82 lineto 224.359 595.82 220.945 591.664 220.945 586.539 curveto 220.945 567.207 lineto 220.945 562.082 224.359 557.926 228.574 557.926 curveto 309.984 557.926 lineto 314.199 557.926 317.617 562.082 317.617 567.207 curveto 317.617 586.539 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap newpath 186.176 328.523 moveto 186.176 333.648 182.023 337.801 176.898 337.801 curveto 77.9063 337.801 lineto 72.7773 337.801 68.625 333.648 68.625 328.523 curveto 68.625 309.187 lineto 68.625 304.062 72.7773 299.906 77.9063 299.906 curveto 176.898 299.906 lineto 182.023 299.906 186.176 304.062 186.176 309.187 curveto 186.176 328.523 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 1 1 1 setrgbcolor newpath 214.086 363.445 moveto 221.695 364.68 lineto 218.961 357.469 lineto 214.086 363.445 lineto closepath fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 1 1 1 setrgbcolor newpath 207.855 384.309 moveto 215.473 383.109 lineto 210.625 377.109 lineto 207.855 384.309 lineto closepath fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 189.383 339.426 moveto 217.23 361.566 lineto fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 1 setlinejoin 1 setlinecap newpath 189.383 339.426 moveto 217.23 361.566 lineto stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 215.043 363.109 moveto 220.109 363.867 lineto 218.23 359.102 lineto 215.043 363.109 lineto closepath fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 0 setlinejoin 0 setlinecap newpath 215.043 363.109 moveto 220.109 363.867 lineto 218.23 359.102 lineto 215.043 363.109 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 191.758 378.078 moveto 212.758 385.957 lineto fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 1 setlinejoin 1 setlinecap newpath 191.758 378.078 moveto 212.758 385.957 lineto stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 211.152 388.098 moveto 216.207 387.262 lineto 212.953 383.301 lineto 211.152 388.098 lineto closepath fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 0 setlinejoin 0 setlinecap newpath 211.152 388.098 moveto 216.207 387.262 lineto 212.953 383.301 lineto 211.152 388.098 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 189.383 462.5 moveto 217.23 440.359 lineto fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 1 setlinejoin 1 setlinecap newpath 189.383 462.5 moveto 217.23 440.359 lineto stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 215.043 438.816 moveto 220.109 438.059 lineto 218.23 442.824 lineto 215.043 438.816 lineto closepath fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 0 setlinejoin 0 setlinecap newpath 215.043 438.816 moveto 220.109 438.059 lineto 218.23 442.824 lineto 215.043 438.816 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 191.758 423.852 moveto 212.758 415.969 lineto fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 1 setlinejoin 1 setlinecap newpath 191.758 423.852 moveto 212.758 415.969 lineto stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 211.152 413.828 moveto 216.207 414.664 lineto 212.953 418.625 lineto 211.152 413.828 lineto closepath fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 0 setlinejoin 0 setlinecap newpath 211.152 413.828 moveto 216.207 414.664 lineto 212.953 418.625 lineto 211.152 413.828 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 311.508 442.773 moveto 334.504 469.918 lineto fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 1 setlinejoin 1 setlinecap newpath 311.508 442.773 moveto 334.504 469.918 lineto stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 332.059 471.008 moveto 336.883 472.734 lineto 335.969 467.695 lineto 332.059 471.008 lineto closepath fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 0 setlinejoin 0 setlinecap newpath 332.059 471.008 moveto 336.883 472.734 lineto 335.969 467.695 lineto 332.059 471.008 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 1 setlinejoin 1 setlinecap newpath 316.656 557.93 moveto 339.602 523.039 lineto stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 341.34 525.078 moveto 341.637 519.961 lineto 337.059 522.262 lineto 341.34 525.078 lineto closepath fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 0 setlinejoin 0 setlinecap newpath 341.34 525.078 moveto 341.637 519.961 lineto 337.059 522.262 lineto 341.34 525.078 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 1 setlinejoin 1 setlinecap newpath 354.676 612.121 moveto 370.453 524.594 lineto stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 372.852 525.789 moveto 371.117 520.965 lineto 367.809 524.879 lineto 372.852 525.789 lineto closepath fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 0 setlinejoin 0 setlinecap newpath 372.852 525.789 moveto 371.117 520.965 lineto 367.809 524.879 lineto 372.852 525.789 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 1 setlinejoin 1 setlinecap newpath 191.496 576.863 moveto 212.352 576.863 lineto stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 211.602 579.434 moveto 216.039 576.871 lineto 211.602 574.312 lineto 211.602 579.434 lineto closepath fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 0 setlinejoin 0 setlinecap newpath 211.602 579.434 moveto 216.039 576.871 lineto 211.602 574.312 lineto 211.602 579.434 lineto closepath stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 1 setlinejoin 1 setlinecap newpath 191.496 635.867 moveto 212.352 635.867 lineto stroke grestore gsave [1 0 0 1 12.07693 -265.6525] concat gsave 0.49803922 0.49803922 0.49803922 setrgbcolor newpath 211.602 638.434 moveto 216.039 635.875 lineto 211.602 633.312 lineto 211.602 638.434 lineto closepath fill grestore grestore gsave [1 0 0 1 12.07693 -265.6525] concat 0.49803922 0.49803922 0.49803922 setrgbcolor [] 0 setdash 2 setlinewidth 0 setlinejoin 0 setlinecap newpath 211.602 638.434 moveto 216.039 635.875 lineto 211.602 633.312 lineto 211.602 638.434 lineto closepath stroke grestore gsave [1 0 0 -1 83.312874 49.951481] concat gsave /newlatin1font {findfont dup length dict copy dup /Encoding ISOLatin1Encoding put definefont} def /CourierNewPSMT-ISOLatin1 /CourierNewPSMT newlatin1font 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (windows/gui.c) show grestore grestore gsave [1 0 0 -1 83.312874 63.105823] concat gsave /ArialMT-ISOLatin1 /ArialMT newlatin1font 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (Cluster 3.0 for Windows) show grestore grestore gsave [1 0 0 -1 83.483772 104.69196] concat gsave /CourierNewPSMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (mac/main.m) show grestore grestore gsave [1 0 0 -1 83.483772 117.84631] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (Cluster 3.0 for Mac OS X) show grestore grestore gsave [1 0 0 -1 83.195686 159.43198] concat gsave /CourierNewPSMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (X11/gui.c) show grestore grestore gsave [1 0 0 -1 83.195686 172.58632] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (Cluster 3.0 for Unix/Linux) show grestore grestore gsave [1 0 0 -1 83.195686 207.92334] concat gsave /CourierNewPSMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (src/command.c) show grestore grestore gsave [1 0 0 -1 83.195686 221.07768] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (Cluster 3.0,) show grestore grestore gsave [1 0 0 -1 83.195686 233.57768] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (command line version) show grestore grestore gsave [1 0 0 -1 83.60096 301.72586] concat gsave /CourierNewPSMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (perl/Cluster.pm) show grestore grestore gsave [1 0 0 -1 83.60096 314.8802] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (Algorithm::Cluster) show grestore grestore gsave [1 0 0 -1 83.60096 327.3802] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (Perl extension module) show grestore grestore gsave [1 0 0 -1 83.366585 359.73224] concat gsave /CourierNewPSMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (python/__init__.py) show grestore grestore gsave [1 0 0 -1 83.366585 372.88658] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (Pycluster/Bio.Cluster) show grestore grestore gsave [1 0 0 -1 83.366585 385.38658] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (Python extension module) show grestore grestore gsave [1 0 0 -1 237.21465 114.14387] concat gsave /CourierNewPSMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (src/data.h) show grestore grestore gsave [1 0 0 -1 237.21465 126.64387] concat gsave /CourierNewPSMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (src/data.c) show grestore grestore gsave [1 0 0 -1 237.21465 139.79821] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (Data management,) show grestore grestore gsave [1 0 0 -1 237.21465 152.29821] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (file parsing, and) show grestore grestore gsave [1 0 0 -1 237.21465 164.79821] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (command interface) show grestore grestore gsave [1 0 0 -1 236.7803 307.97342] concat gsave /CourierNewPSMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (perl/Cluster.xs) show grestore grestore gsave [1 0 0 -1 236.7803 321.12776] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (Perl / C interface) show grestore grestore gsave [1 0 0 -1 236.70798 365.98224] concat gsave /CourierNewPSMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (python/clustermodule.c) show grestore grestore gsave [1 0 0 -1 236.70798 379.13658] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (Python / C interface) show grestore grestore gsave [1 0 0 -1 352.87958 221.56821] concat gsave /CourierNewPSMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (src/cluster.h) show grestore grestore gsave [1 0 0 -1 352.87958 234.06821] concat gsave /CourierNewPSMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (src/cluster.c) show grestore grestore gsave [1 0 0 -1 352.87958 247.22255] concat gsave /ArialMT-ISOLatin1 findfont 10 scalefont setfont 0 0 0 setrgbcolor newpath 0 0 moveto (C Clustering Library) show grestore grestore grestore showpage cluster-1.52a/doc/cluster3.texinfo0000644000100500010050000022717712177163654017054 0ustar mdehoonmdehoon\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename . @settitle Cluster 3.0 for Windows, Mac OS X, Linux, Unix @c %**end of header @titlepage @title{Cluster 3.0 Manual} @subtitle{for Windows, Mac OS X, Linux, Unix} @author{Michael Eisen; updated by Michiel de Hoon} @c The following two commands start the copyright page. @page @vskip 0pt plus 1filll Software copyright @copyright{} Stanford University 1998-99 This manual was originally written by Michael Eisen. It is only partially complete and is a work in progress. The manual was updated in 2002 by Michiel de Hoon, University of Tokyo, Human Genome Center. @end titlepage @node Top, Contents @comment node-name, next, previous, up @noindent This is the manual for Cluster 3.0. Cluster was originally written by Michael Eisen while at Stanford University. We have modified the @tex $k$-means @end tex @html k-means @end html clustering algorithm in Cluster, and extended the algorithm for Self-Organizing Maps to include two-dimensional rectangular grids. The Euclidean distance and the city-block distance were added as new distance measures between gene expression data. The proprietary Numerical Recipes routines, which were used in the original version of Cluster/TreeView, have been replaced by open source software. Cluster 3.0 is available for Windows, Mac OS X, Linux, and Unix. @* @* @noindent November 5, 2002.@* Michiel de Hoon@* Human Genome Center, University of Tokyo. @menu * Introduction:: The purpose of Cluster/TreeView. * Data:: Loading, filtering and adjusting data in Cluster. * Distance:: The distance/similarity measures that are available in Cluster. * Cluster:: The various clustering algorithms implemented in Cluster. * Command:: A command-line (non-GUI) version of Cluster 3.0 is now available. * TreeView:: Visualize hierarchical clustering results with Java TreeView. * Development:: Information on how to compile Cluster from the source code. * Bibliography:: The bibliography provides references to background information on clustering techniques, as well as some examples of recent biological research in which clustering techniques are applied. * Contents:: @end menu @node Contents, Introduction, Top, Top @contents @node Introduction, Data, Contents, Top @chapter Introduction Cluster and TreeView are programs that provide a computational and graphical environment for analyzing data from DNA microarray experiments, or other genomic datasets. The program Cluster can organize and analyze the data in a number of different ways. TreeView allows the organized data to be visualized and browsed. This manual is intended as a reference for using the software, and not as a comprehensive introduction to the methods employed. Many of the methods are drawn from standard statistical cluster analysis. There are excellent textbooks available on cluster analysis which are listed in the bibliography at the end. The bibliography also contains citations for recent publications in the biological sciences, especially genomics, that employ methods similar to those used here. @node Data, Distance, Introduction, top @chapter Loading, filtering, and adjusting data @image{images/cluster} Data can be loaded into Cluster by choosing Load data file under the File menu. A number of options are provided for adjusting and filtering the data you have loaded. These functions are accessed via the Filter Data and Adjust Data tabs. @section Loading Data The first step in using Cluster is to import data. Currently, Cluster only reads tab-delimited text files in a particular format, described below. Such tab-delimited text files can be created and exported in any standard spreadsheet program, such as Microsoft Excel. An example datafile can be found under the File format help item in the Help menu. This contains all the information you need for making a Cluster input file. By convention, in Cluster input tables rows represent genes and columns represent samples or observations (e.g. a single microarray hybridization). For a simple timecourse, a minimal Cluster input file would look like this:@* @image{images/minifile} @* Each row (gene) has an identifier (in green) that always goes in the first column. Here we are using yeast open reading frame codes. Each column (sample) has a label (in blue) that is always in the first row; here the labels describe the time at which a sample was taken. The first column of the first row contains a special field (in red) that tells the program what kind of objects are in each row. In this case, YORF stands for yeast open reading frame. This field can be any alpha-numeric value. It is used in TreeView to specify how rows are linked to external websites. The remaining cells in the table contain data for the appropriate gene and sample. The 5.8 in row 2 column 4 means that the observed data value for gene YAL001C at 2 hours was 5.8. Missing values are acceptable and are designated by empty cells (e.g. YAL005C at 2 hours). It is possible to have additional information in the input file. A maximal Cluster input file would look like this:@* @image{images/maxifile} @* The yellow columns and rows are optional. By default, TreeView uses the ID in column 1 as a label for each gene. The NAME column allows you to specify a label for each gene that is distinct from the ID in column 1. The other rows and columns will be described later in this text. When Cluster 3.0 opens the data file, the number of columns in each row is checked. If a given row contains less or more columns than needed, an error message is displayed.@* @image{images/fileerror} @heading Demo data A demo datafile, which will be used in all of the examples here, is available at @uref{http://rana.lbl.gov/downloads/data/demo.txt} and is mirrored at @uref{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/demo.txt}. The datafile contains yeast gene expression data described in Eisen @emph{et al.} (1998) [see references at end]. Download this data and load it into Cluster. Cluster will give you information about the loaded datafile. @* @image{images/filemanager} @section Filtering Data @image{images/filter} The Filter Data tab allows you to remove genes that do not have certain desired properties from your dataset. The currently available properties that can be used to filter data are @itemize @bullet @item @strong{% Present >= X}. This removes all genes that have missing values in greater than @tex $\left(100-X\right)$ @end tex @html (100-X) @end html percent of the columns. @item @strong{SD (Gene Vector) >= X}. This removes all genes that have standard deviations of observed values less than @tex $X$. @end tex @html X. @end html @item @strong{At least X Observations with abs(Val) >= Y}. This removes all genes that do not have at least @tex $X$ @end tex @html X @end html observations with absolute values greater than @tex $Y$. @end tex @html Y. @end html @item @strong{MaxVal-MinVal >= X}. This removes all genes whose maximum minus minimum values are less than @tex $X$. @end tex @html X. @end html @end itemize These are fairly self-explanatory. When you press filter, the filters are not immediately applied to the dataset. You are first told how many genes would have passed the filter. If you want to accept the filter, you press Accept, otherwise no changes are made. @* @image{images/accept} @section Adjusting Data @image{images/adjust} From the Adjust Data tab, you can perform a number of operations that alter the underlying data in the imported table. These operations are @itemize @bullet @item @strong{Log Transform Data}: replace all data values @tex $x$ @end tex @html x @end html by @tex $\log_2 \left(x\right)$. @end tex @html log2 (x). @end html @item @strong{Center genes [mean or median]}: Subtract the row-wise mean or median from the values in each row of data, so that the mean or median value of each row is 0. @item @strong{Center arrays [mean or median]}: Subtract the column-wise mean or median from the values in each column of data, so that the mean or median value of each column is 0. @item @strong{Normalize genes}: Multiply all values in each row of data by a scale factor @tex $S$ @end tex @html S @end html so that the sum of the squares of the values in each row is 1.0 (a separate @tex $S$ @end tex @html S @end html is computed for each row). @item @strong{Normalize arrays}: Multiply all values in each column of data by a scale factor @tex $S$ @end tex @html S @end html so that the sum of the squares of the values in each column is 1.0 (a separate @tex $S$ @end tex @html S @end html is computed for each column). @end itemize These operations are not associative, so the order in which these operations is applied is very important, and you should consider it carefully before you apply these operations. The order of operations is (only checked operations are performed): @itemize @bullet @item Log transform all values. @item Center rows by subtracting the mean or median. @item Normalize rows. @item Center columns by subtracting the mean or median. @item Normalize columns. @end itemize @subsection Log transformation The results of many DNA microarray experiments are fluorescent ratios. Ratio measurements are most naturally processed in log space. Consider an experiment where you are looking at gene expression over time, and the results are relative expression levels compared to time 0. Assume at timepoint 1, a gene is unchanged, at timepoint 2 it is up 2-fold and at timepoint three is down 2-fold relative to time 0. The raw ratio values are 1.0, 2.0 and 0.5. In most applications, you want to think of 2-fold up and 2-fold down as being the same magnitude of change, but in an opposite direction. In raw ratio space, however, the difference between timepoint 1 and 2 is +1.0, while between timepoint 1 and 3 is -0.5. Thus mathematical operations that use the difference between values would think that the 2-fold up change was twice as significant as the 2-fold down change. Usually, you do not want this. In log space (we use log base 2 for simplicity) the data points become 0,1.0,-1.0.With these values, 2-fold up and 2-fold down are symmetric about 0. For most applications, we recommend you work in log space. @subsection Mean/Median Centering Consider a now common experimental design where you are looking at a large number of tumor samples all compared to a common reference sample made from a collection of cell-lines. For each gene, you have a series of ratio values that are relative to the expression level of that gene in the reference sample. Since the reference sample really has nothing to do with your experiment, you want your analysis to be independent of the amount of a gene present in the reference sample. This is achieved by adjusting the values of each gene to reflect their variation from some property of the series of observed values such as the mean or median. This is what mean and/or median centering of genes does. Centering makes less sense in experiments where the reference sample is part of the experiment, as it is many timecourses. Centering the data for columns/arrays can also be used to remove certain types of biases. The results of many two-color fluorescent hybridization experiments are not corrected for systematic biases in ratios that are the result of differences in RNA amounts, labeling efficiency and image acquisition parameters. Such biases have the effect of multiplying ratios for all genes by a fixed scalar. Mean or median centering the data in log-space has the effect of correcting this bias, although it should be noted that an assumption is being made in correcting this bias, which is that the average gene in a given experiment is expected to have a ratio of 1.0 (or log-ratio of 0). In general, I recommend the use of median rather than mean centering, as it is more robust against outliers. @subsection Normalization Normalization sets the magnitude (sum of the squares of the values) of a row/column vector to 1.0. Most of the distance metrics used by Cluster work with internally normalized data vectors, but the data are output as they were originally entered. If you want to output normalized vectors, you should select this option. A sample series of operations for raw data would be: @itemize @bullet @item Adjust Cycle 1) log transform @item Adjust Cycle 2) median center genes and arrays @item repeat (2) five to ten times @item Adjust Cycle 3) normalize genes and arrays @item repeat (3) five to ten times @end itemize This results in a log-transformed, median polished (i.e. all row-wise and column-wise median values are close to zero) and normal (i.e. all row and column magnitudes are close to 1.0) dataset. After performing these operations you should save the dataset. @node Distance, Cluster, Data, top @chapter Distance/Similarity measures The first choice that must be made is how similarity (or alternatively, distance) between gene expression data is to be defined. There are many ways to compute how similar two series of numbers are. Cluster provides eight options. @section Distance measures based on the Pearson correlation The most commonly used similarity metrics are based on Pearson correlation. The Pearson correlation coefficient between any two series of numbers @tex $x = \left\{ x_1, x_2, \ldots, x_n \right\}$ @end tex @html x = @{x1, x2, ..., xn@} @end html and @tex $y = \left\{y_1, y_2, \ldots, y_n \right\}$ @end tex @html y = @{y1, y2, ..., yn@} @end html is defined as @tex $$r = {1 \over n} \sum_{i=1}^n \left(x_i- \overline x \over \sigma_x\right) \left(y_i- \overline y \over \sigma_y\right),$$ @end tex @html
r =
1
n
n

i = 1
(
xi - x
σx
) (
yi - y
σy
)
@end html where @tex $\overline x$ @end tex @html x @end html is the average of values in @tex $x$, @end tex @html x @end html and @tex $\sigma_x$ @end tex @html σx @end html is the standard deviation of these values. There are many ways of conceptualizing the correlation coefficient. If you were to make a scatterplot of the values of @tex $x$ @end tex @html x @end html against @tex $y$ @end tex @html y @end html (pairing @tex $x_1$ @end tex @html x1 @end html with @tex $y_1$, $x_2$ @end tex @html y1, x2 @end html with @tex $y_2$, @end tex @html y2, @end html etc), then @tex $r$ @end tex @html r @end html reports how well you can fit a line to the values. The simplest way to think about the correlation coefficient is to plot @tex $x$ @end tex @html x @end html and @tex $y$ @end tex @html y @end html as curves, with @tex $r$ @end tex @html r @end html telling you how similar the shapes of the two curves are. The Pearson correlation coefficient is always between -1 and 1, with 1 meaning that the two series are identical, 0 meaning they are completely uncorrelated, and -1 meaning they are perfect opposites. The correlation coefficient is invariant under linear transformation of the data. That is, if you multiply all the values in @tex $y$ @end tex @html y @end html by 2, or add 7 to all the values in @tex $y$, @end tex @html y, @end html the correlation between @tex $x$ @end tex @html x @end html and @tex $y$ @end tex @html y @end html will be unchanged. Thus, two curves that have identical shape, but different magnitude, will still have a correlation of 1. Cluster actually uses four different flavors of the Pearson correlation. The textbook Pearson correlation coefficient, given by the formula above, is used if you select Correlation (centered) in the Similarity Metric dialog box. Correlation (uncentered) uses the following modified equations:@* @tex $$r = {1 \over n}\sum_{i=1}^{n} \left({x_i\over \sigma_x^{(0)}}\right)\left({y_i\over \sigma_y^{(0)}}\right),$$ @end tex @html
r =
1
n
n

i = 1
(
xi
σx(0)
) (
yi
σy(0)
)
@end html @* in which@* @tex $$\sigma_x^{(0)} = \sqrt{{1\over n}\sum_{i=1}^{n}\left(x_i\right)^2};$$ $$\sigma_y^{(0)} = \sqrt{{1\over n}\sum_{i=1}^{n}\left(y_i\right)^2}.$$ @end tex @html
σx(0) = (
1
n
n

i = 1
xi2 )
σy(0) = (
1
n
n

i = 1
yi2 )
@end html @* This is basically the same function, except that it assumes the mean is 0, even when it is not. The difference is that, if you have two vectors @tex $x$ @end tex @html x @end html and @tex $y$ @end tex @html y @end html with identical shape, but which are offset relative to each other by a fixed value, they will have a standard Pearson correlation (centered correlation) of 1 but will not have an uncentered correlation of 1. The uncentered correlation is equal to the cosine of the angle of two @tex $n$-dimensional @end tex @html n-dimensional @end html vectors @tex $x$ @end tex @html x @end html and @tex $y$, @end tex @html y, @end html each representing a vector in @tex $n$-dimensional @end tex @html n-dimensional @end html space that passes through the origin. Cluster provides two similarity metrics that are the absolute value of these two correlation functions, which consider two items to be similar if they have opposite expression patterns; the standard correlation coefficients consider opposite genes to be very distant. @section Non-parametric distance measures The Spearman rank correlation and Kendall's @tex $\tau$ @end tex @html τ @end html are two additional metrics, which are non-parametric versions of the Pearson correlation coefficient. These methods are more robust against outliers. The Spearman rank correlation calculates the correlation between the ranks of the data values in the two vectors. For example, if we have two data vectors@* @tex $$x = \left\{2.3, 6.7, 4.5, 20.8\right\};$$ $$y = \left\{2.1, 5.9, 4.4, 4.2\right\},$$ @end tex @html
x = @{2.3, 6.7, 4.5, 20.8@};
y = @{2.1, 5.9, 4.4, 4.2@},
@end html then we first replace them by their ranks:@* @tex $$x = \left\{1, 3, 2, 4\right\};$$ $$y = \left\{1, 4, 3, 2\right\}.$$ @end tex @html
x = @{1, 3, 2, 4@};
y = @{1, 4, 3, 2@}.
@end html Now we calculate the correlation coefficient in their usual manner from these data vectors, resulting in@* @tex $$r_{\rm Spearman} = 0.4.$$ @end tex @html
rSpearman = 0.4.
@end html In comparison, the regular Pearson correlation between these data is @tex $r = 0.2344$. @end tex @html r = 0.2344. @end html By replacing the data values by their ranks, we reduced the effect of the outlier 20.8 on the value of the correlation coefficient. The Spearman rank correlation can be used as a test statistic for independence between @tex $x$ and $y$. @end tex @html x and y. @end html For more information, see Conover (1980). Kendall's @tex $\tau$ @end tex @html τ @end html goes a step further by using only the relative ordering of @tex $x$ and $y$ @end tex @html x and y @end html to calculate the correlation (Snedecor & Cochran). To calculate Kendall's @tex $\tau$, @end tex @html τ, @end html consider all pairs of data points @tex $\left(x_i, y_i\right)$ and $\left(x_j, y_j\right)$. @end tex @html (xi, yi) and (xj, yj). @end html We call a pair concordant if @itemize @bullet @item @tex $x_i < x_j$ and $y_i < y_j$; or @end tex @html xi < xj and yi < yj; or @end html @item @tex $x_i > x_j$ and $y_i > y_j$, @end tex @html xi > xj and yi > yj, @end html @end itemize @noindent and discordant if @itemize @bullet @item @tex $x_i < x_j$ and $y_i > y_j$; or @end tex @html xi < xj and yi > yj; or @end html @item @tex $x_i > x_j$ and $y_i < y_j$. @end tex @html xi > xj and yi < yj. @end html @end itemize @noindent We can represent this by a table: @tex $$\matrix{ - & \left(2.3, 2.1\right) & \left(6.7, 5.9\right) & \left(4.5, 4.4\right) & \left(20.8, 4.2\right) \cr \left(2.3, 2.1\right) & - & << & << & << \cr \left(6.7, 5.9\right) & >> & - & >> & <> \cr \left(4.5, 4.4\right) & >> & << & - & <> \cr \left(20.8, 4.2\right) & >> & >< & >< & - \cr }$$ @end tex @html
- (2.3, 2.1) (6.7, 5.9) (4.5, 4.4) (20.8, 4.2)
(2.3, 2.1) - << << <<
(6.7, 5.9) >> - >> <>
(4.5, 4.4) >> << - <>
(20.8, 4.2) >> >< >< -
@end html From this table, we find that there are four concordant pairs and two discordant pairs: @tex $$n_{\rm c} = 4;$$ $$n_{\rm d} = 2;$$ @end tex @html
nc = 4;
nd = 2.
@end html Kendall's @tex $\tau$ @end tex @html τ @end html is calculated as@* @tex $$\tau = {N_{\rm c} - N_{\rm d}} \over {N\left(N-1\right)/2},$$ @end tex @html
τ =
nc-nd
n(n-1)/2
,
@end html which in this case evaluates as 0.33. In the C Clustering Library, the calculation of Kendall's @tex $\tau$ @end tex @html τ @end html is corrected for the possibility that two ranks are equal. As in case of the Spearman rank correlation, we may use Kendall's @tex $\tau$ @end tex @html τ @end html to test for independence between @tex $x$ and $y$. @end tex @html x and y. @end html @section Distance measures related to the Euclidean distance @subsection Euclidean distance A newly added distance function is the Euclidean distance, which is defined as @tex $$d\left(\underline{x},\underline{y}\right)= {1 \over n} \sum_{i=1}^n \left(x_i-y_i\right)^{2}.$$ @end tex @html
d =
1
n
n

i = 1
( xi - yi )2
@end html The Euclidean distance takes the difference between two gene expression levels directly. It should therefore only be used for expression data that are suitably normalized, for example by converting the measured gene expression levels to log-ratios. In the sum, we only include terms for which both @tex $x_i$ and $y_i$ @end tex @html xi and yi @end html are present, and divide by @tex $n$ @end tex @html n @end html accordingly. Unlike the correlation-based distance measures, the Euclidean distance takes the magnitude of changes in the gene expression levels into account. An example of the Euclidean distance applied to @tex $k$-means @end tex @html k-means @end html clustering can be found in De Hoon, Imoto, and Miyano (2002). @subsection City-block distance The city-block distance, alternatively known as the Manhattan distance, is related to the Euclidean distance. Whereas the Euclidean distance corresponds to the length of the shortest path between two points, the city-block distance is the sum of distances along each dimension: @tex $$d = \sum_{i=1}^n \left|x_i-y_i\right|.$$ @end tex @html
d =
1
n
n

i = 1
| xi - yi |
@end html This is equal to the distance you would have to walk between two points in a city, where you have to walk along city blocks. The city-block distance is a metric, as it satisfies the triangle inequality. Again we only include terms for which both @tex $x_i$ and $y_i$ @end tex @html xi and yi @end html are present, and divide by @tex $n$ @end tex @html n @end html accordingly. As for the Euclidean distance, the expression data are subtracted directly from each other, and we should therefore make sure that they are properly normalized. @section Missing values When either @tex $x$ @end tex @html x @end html or @tex $y$ @end tex @html y @end html has missing values, only observations present for both @tex $x$ @end tex @html x @end html and @tex $y$ @end tex @html y @end html are used in computing similarities. @section Calculating the distance matrix With any specified metric, the first step in the hierarchical clustering routines described below is to compute the distance (the opposite of similarity; for all correlation metrics distance = 1.0 - correlation) between all pairs of items to be clustered (e.g. the set of genes in the current dataset). This can often be time consuming, and, except for pairwise single-linkage clustering, memory intensive (the maximum amount of memory required is @tex $4 \times N \times N$ @end tex @html 4 x N x N @end html bytes, where @tex $N$ @end tex @html N @end html is the number of items being clustered). The algorithm for pairwise single-linkage hierarchical clustering is less memory-intensive (linear in @tex $N$). @end tex @html N). @end html @node Cluster, Command, Distance, top @chapter Clustering techniques The Cluster program provides several clustering algorithms. Hierarchical clustering methods organizes genes in a tree structure, based on their similarity. Four variants of hierarchical clustering are available in Cluster. In @tex $k$-means @end tex @html k-means @end html clustering, genes are organized into @tex $k$ @end tex @html k @end html clusters, where the number of clusters @tex $k$ @end tex @html k @end html needs to be chosen in advance. Self-Organizing Maps create clusters of genes on a two-dimensional rectangular grid, where neighboring clusters are similar. For each of these methods, one of the eight different distance meaures can be used. Finally, in Principal Component Analysis, clusters are organized based on the principal component axes of the distance matrix. @menu * Hierarchical:: Pairwise single-, maximum-, average-, and centroid-linkage hierarchical clustering @tex * KMeans:: $k$-means and $k$-medoids clustering @end tex @html * KMeans:: k-means and k-medoids clustering @end html clustering * SOM:: Self-Organizing Maps * PCA:: Principal Component Analysis @end menu @node Hierarchical, KMeans, , Cluster @section Hierarchical Clustering @image{images/hierarchical} The @dfn{Hierarchical Clustering} tab allows you to perform hierarchical clustering on your data. This is a powerful and useful method for analyzing all sorts of large genomic datasets. Many published applications of this analysis are given in the references section at the end. Cluster currently performs four types of binary, agglomerative, hierarchical clustering. The basic idea is to assemble a set of items (genes or arrays) into a tree, where items are joined by very short branches if they are very similar to each other, and by increasingly longer branches as their similarity decreases. The first step in hierarchical clustering is to calculate the distance matrix between the gene expression data. Once this matrix of distances is computed, the clustering begins. Agglomerative hierarchical processing consists of repeated cycles where the two closest remaining items (those with the smallest distance) are joined by a node/branch of a tree, with the length of the branch set to the distance between the joined items. The two joined items are removed from list of items being processed and replaced by a item that represents the new branch. The distances between this new item and all other remaining items are computed, and the process is repeated until only one item remains. Note that once clustering commences, we are working with items that are true items (e.g. a single gene) and items that are pseudo-items that contain a number of true items. There are a variety of ways to compute distances when we are dealing with pseudo-items, and Cluster currently provides four choices, which are called centroid linkage, single linkage, complete linkage, and average linkage. @strong{Note that in older versions of Cluster, centroid linkage was referred to as average linkage.} @subsection Centroid Linkage Clustering If you click Centroid Linkage Clustering, a vector is assigned to each pseudo-item, and this vector is used to compute the distances between this pseudo-item and all remaining items or pseudo-items using the same similarity metric as was used to calculate the initial similarity matrix. The vector is the average of the vectors of all actual items (e.g. genes) contained within the pseudo-item. Thus, when a new branch of the tree is formed joining together a branch with 5 items and an actual item, the new pseudo-item is assigned a vector that is the average of the 6 vectors it contains, and not the average of the two joined items (note that missing values are not used in the average, and a pseudo-item can have a missing value if all of the items it contains are missing values in the corresponding row/column). Note that from a theoretical perspective, Centroid Linkage Clustering is peculiar if it is used in combination with one of the distance measures that are based on the Pearson correlation. For these distance measures, the data vectors are implicitly normalized when calculating the distance (for example, by subtracting the mean and dividing by the standard deviation when calculating the Pearson correlation. However, when two genes are joined and their centroid is calculated by averaging their data vectors, no normalization is applied. This may lead to the surprising result that distances may decrease when we go up in the tree representing the hierarchical clustering result. For example, consider this data set: @tex $$\matrix{ & \rm Exp 1 & \rm Exp 2 & \rm Exp 3 & \rm Exp 4 \cr \rm Gene 1 & 0.96 & 0.07 & 0.97 & 0.98 \cr \rm Gene 2 & 0.50 & 0.28 & 0.29 & 0.77 \cr \rm Gene 3 & 0.08 & 0.96 & 0.51 & 0.51 \cr \rm Gene 4 & 0.14 & 0.19 & 0.41 & 0.51 \cr }$$ @end tex @html
Exp 1 Exp 2 Exp 3 Exp 4
Gene 1 0.96 0.07 0.97 0.98
Gene 2 0.50 0.28 0.29 0.77
Gene 3 0.08 0.96 0.51 0.51
Gene 4 0.14 0.19 0.41 0.51
@end html Performing pairwise centroid-linkage hierarchical clustering on this data set, using the Pearson distance as the distance measure, produces the clustering result @itemize @item Gene 1 joins Gene 2 at distance 0.47 @item (Gene 1, Gene 2) joins Gene 4 at distance 0.46 @item (Gene 1, Gene 2, Gene 4) joins Gene 3 at distance 1.62 @end itemize @noindent This may result in ill-formed dendrograms. For an example, see the Java TreeView manual. A solution is to use the Euclidean or the city-block distance, or to use one of the other hierarchical clustering routines, which don't suffer from this issue regardless of the distance measure being used. @subsection Single Linkage Clustering In Single Linkage Clustering the distance between two items @tex $x$ @end tex @html x @end html and @tex $y$ @end tex @html y @end html is the minimum of all pairwise distances between items contained in @tex $x$ @end tex @html x @end html and @tex $y$. @end tex @html y. @end html Unlike centroid linkage clustering, in single linkage clustering no further distances need to be calculated once the distance matrix is known. In Cluster 3.0, as of version 1.29 the implementation of single linkage clustering is based on the SLINK algorithm (see Sibson, 1973). Whereas this algorithm yields the exact same clustering result as conventional single-linkage hierarchical clustering, it is much faster and more memory-efficient (being linear in the memory requirements, compared to quadratic for the conventional algorithm). Hence, single-linkage hierarchical clustering can be used to cluster large gene expression data sets, for which centroid-, complete-, and average-linkage fail due to lack of memory. @subsection Complete Linkage Clustering In Complete Linkage Clustering the distance between two items @tex $x$ @end tex @html x @end html and @tex $y$ @end tex @html y @end html is the maximum of all pairwise distances between items contained in @tex $x$ @end tex @html x @end html and @tex $y$. @end tex @html y. @end html As in single linkage clustering, no other distances need to be calculated once the distance matrix is known. @subsection Average Linkage Clustering In average linkage clustering, the distance between two items @tex $x$ @end tex @html x @end html and @tex $y$ @end tex @html y @end html is the mean of all pairwise distances between items contained in @tex $x$ @end tex @html x @end html and @tex $y$. @end tex @html y. @end html @subsection Weighting Weighting: By default, all of the observations for a given item are treated equally. In some cases you may want to give some observations more weight than others. For example, if you have duplicate copies of a gene on your array, you might want to downweight each individual copy when computing distances between arrays. You can specify weights using the @samp{GWEIGHT} (gene weight) and @samp{EWEIGHT} (experiment weight) parameters in the input file. By default all weights are set to 1.0. Thus, the actual formula, with weights included, for the Pearson correlation of @tex $x = \left\{ x_1, x_2, \ldots, x_n \right\}$ @end tex @html x = @{x1, x2, ..., xn@} @end html and @tex $y = \left\{ y_1, y_2, \ldots, y_n \right\}$ @end tex @html y = @{y1, y2, ..., yn@} @end html with observation weights of @tex $w = \left\{ w_1, w_2, \ldots, w_n \right\}$ @end tex @html w = @{w1, w2, ..., wn@} @end html is @tex $$r = {1\over\sum_{i=1}^{N} w_i} \sum_{i=1}^{N} w_i \left({X_i-\overline{X} \over \sigma_X}\right) \left(Y_i-\overline{Y}\over\sigma_Y\right)$$ @end tex @html
r =
n

i = 1
wi (
xi - x
σx
) (
yi - y
σy
)
n

i = 1
wi
@end html Note that when you are clustering rows (genes), you are using column (array) weights. It is possible to compute weights as well based on a not entirely well understood function. If you want to compute weights for clustering genes, select the check box in the Genes panel of the Hierarchical Clustering tab. @* @image{images/weight} This will expose a Weight Options dialog box in the Arrays panel (I realize this placement is a bit counterintuitive, but it makes sense as you will see below). The idea behind the Calculate Weights option is to weight each row (the same idea applies to columns as well) based on the local density of row vectors in its vicinity, with a high density vicinity resulting in a low weight and a low density vicinity resulting in a higher weight. This is implemented by assigning a local density score @tex $L\left(i\right)$ @end tex @html L(i) @end html to each row @tex $i$. @end tex @html i. @end html @* @tex $$L\left(i\right) = \sum_{j\ {\rm with}\ d\left(i,j\right) < k} \left(k - d\left(i,j\right) \over k\right)^n,$$ @end tex @html
L(i) =

j with d(i,j) ≤ k
(
k - d(i,j)
k
) n


@end html where the cutoff @tex $k$ @end tex @html k @end html and the exponent @tex $n$ @end tex @html n @end html are user supplied parameters. The weight for each row is @tex $1/L$. @end tex @html 1/L. @end html Note that @tex $L\left(i\right)$ @end tex @html L(i) @end html is always at least 1, since @tex $d\left(i,i\right) = 0$. @end tex @html d(i,i) = 0. @end html Each other row that is within the distance @tex $k$ @end tex @html k @end html of row @tex $i$ @end tex @html i @end html increases @tex $L\left(i\right)$ @end tex @html L(i) @end html and decreases the weight. The larger @tex $d\left(i,j\right)$, @end tex @html d(i,j), @end html the less @tex $L\left(i\right)$ @end tex @html L(i) @end html is increased. Values of @tex $n$ @end tex @html n @end html greater than 1 mean that the contribution to @tex $L\left(i\right)$ @end tex @html L(i) @end html drops off rapidly as @tex $d\left(i,j\right)$ @end tex @html d(i,j) @end html increases. @subsection Ordering of Output File The result of a clustering run is a tree or pair of trees (one for genes one for arrays). However, to visualize the results in TreeView, it is necessary to use this tree to reorder the rows and/or columns in the initial datatable. Note that if you simply draw all of the node in the tree in the following manner, a natural ordering of items emerges: @* @image{images/order} Thus, any tree can be used to generate an ordering. However, the ordering for any given tree is not unique. There is a family of @tex $2^{N-1}$ @end tex @html 2N-1 @end html ordering consistent with any tree of @tex $N$ @end tex @html N @end html items; you can flip any node on the tree (exchange the bottom and top branches) and you will get a new ordering that is equally consistent with the tree. By default, when Cluster joins two items, it randomly places one item on the top branch and the other on the bottom branch. It is possible to guide this process to generate the best ordering consistent with a given tree. This is done by using the @samp{GORDER} (gene order) and @samp{EORDER} (experiment order) parameters in the input file, or by running a self-organizing map (see section below) prior to clustering. By default, Cluster sets the order parameter for each row/column to 1. When a new node is created, Cluster compares the order parameters of the two joined items, and places the item with the smaller order value on the top branch. The order parameter for a node is the average of the order parameters of its members. Thus, if you want the gene order produced by Cluster to be as close as possible (without violating the structure of the tree) to the order in your input file, you use the @samp{GORDER} column, and assign a value that increases for each row. Note that order parameters do not have to be unique. @subsection Output Files Cluster writes up to three output files for each hierarchical clustering run. The root filename of each file is whatever text you enter into the Job Name dialog box. When you load a file, Job Name is set to the root filename of the input file. The three output files are @file{@var{JobName}.cdt}, @file{@var{JobName}.gtr}, @file{@var{JobName}.atr} The @file{.cdt} (for clustered data table) file contains the original data with the rows and columns reordered based on the clustering result. It is the same format as the input files, except that an additional column and/or row is added if clustering is performed on genes and/or arrays. This additional column/row contains a unique identifier for each row/column that is linked to the description of the tree structure in the @file{.gtr} and @file{.atr} files. The @file{.gtr} (gene tree) and @file{.atr} (array tree) files are tab-delimited text files that report on the history of node joining in the gene or array clustering (note that these files are produced only when clustering is performed on the corresponding axis). When clustering begins each item to be clustered is assigned a unique identifier (e.g. @samp{GENE1X} or @samp{ARRY42X} --- the @samp{X} is a relic from the days when this was written in Perl and substring searches were used). These identifiers are added to the .cdt file. As each node is generated, it receives a unique identifier as well, starting is @samp{NODE1X}, @samp{NODE2X}, etc. Each joining event is stored in the @file{.gtr} or @file{.atr} file as a row with the node identifier, the identifiers of the two joined elements, and the similarity score for the two joined elements. These files look like:@* @image{images/tree} @multitable {NODEXX} {GENEXX} {GENEXX} {0.XX} @item @code{NODE1X} @tab @code{GENE1X} @tab @code{GENE4X} @tab @code{0.98} @item @code{NODE2X} @tab @code{GENE5X} @tab @code{GENE2X} @tab @code{0.80} @item @code{NODE3X} @tab @code{NODE1X} @tab @code{GENE3X} @tab @code{0.72} @item @code{NODE4X} @tab @code{NODE2X} @tab @code{NODE3X} @tab @code{0.60} @end multitable @* The @file{.gtr} and/or @file{.atr} files are automatically read in TreeView when you open the corresponding @file{.cdt} file. @page @node KMeans, SOM, Hierarchical, Cluster @tex @section The \math{k}-means Clustering Algorithm @end tex @html @section The k-means Clustering Algorithm @end html @image{images/kmeans} The @tex $k$-means @end tex @html k-means @end html clustering algorithm is a simple, but popular, form of cluster analysis. The basic idea is that you start with a collection of items (e.g. genes) and some chosen number of clusters @tex ($k$) @end tex @html (k) @end html you want to find. The items are initially randomly assigned to a cluster. The @tex $k$-means @end tex @html k-means @end html clustering proceeds by repeated application of a two-step process where @enumerate @item the mean vector for all items in each cluster is computed; @item items are reassigned to the cluster whose center is closest to the item. @end enumerate Since the initial cluster assignment is random, different runs of the @tex $k$-means @end tex @html k-means @end html clustering algorithm may not give the same final clustering solution. To deal with this, the @tex $k$-means @end tex @html k-means @end html clustering algorithms is repeated many times, each time starting from a different initial clustering. The sum of distances within the clusters is used to compare different clustering solutions. The clustering solution with the smallest sum of within-cluster distances is saved. The number of runs that should be done depends on how difficult it is to find the optimal solution, which in turn depends on the number of genes involved. Cluster therefore shows in the status bar how many times the optimal solution has been found. If this number is one, there may be a clustering solution with an even lower sum of within-cluster distances. The @tex $k$-means @end tex @html k-means @end html clustering algorithm should then be repeated with more trials. If the optimal solution is found many times, the solution that has been found is likely to have the lowest possible within-cluster sum of distances. We can then assume that the @tex $k$-means @end tex @html k-means @end html clustering procedure has then found the overall optimal clustering solution. It should be noted that generally, the @tex $k$-means @end tex @html k-means @end html clustering algorithm finds a clustering solution with a smaller within-cluster sum of distances than the hierarchical clustering techniques. The parameters that control @tex $k$-means @end tex @html k-means @end html clustering are @itemize @bullet @item the number of clusters @tex ($k$); @end tex @html (k); @end html @item the number of trials. @end itemize The output is simply an assignment of items to a cluster. The implementation here simply rearranges the rows and/or columns based on which cluster they were assigned to. The output data file is @file{@var{JobName}_K_GKg_AKa.cdt}, where @file{_GKg} is included if genes were organized, and @file{_AKa} is included if arrays were organized. Here, @file{Kg} and @file{Ka} represent the number of clusters for gene clustering and array clustering, respectively. This file contains the gene expression data, organized by cluster by rearranging the rows and columns. In addition, the files @file{@var{JobName}_K_GKg.kgg} and @file{@var{JobName}_K_AKa.kag} are created, containing a list of genes/arrays and the cluster they were assigned to. Whereas @tex $k$-means @end tex @html k-means @end html clustering as implemented in Cluster 3.0 allows any of the eight distance measures to be used, we recommend using the Euclidean distance or city-block distance instead of the distance measures based on the Pearson correlation, for the same reason as in case of pairwise centroid-linkage hierarchical clustering. The distance measures based on the Pearson correlation effectively normalize the data vectors when calculating the distance, whereas no normalization is used when calculating the cluster centroid. To use @tex $k$-means @end tex @html k-means @end html clustering with a distance measure based on the Pearson correlation, it is better to first normalize the data appropriately (using the "Adjust Data" tab) before running the @tex $k$-means @end tex @html k-means @end html algorithm. Cluster also implements a slight variation on @tex $k$-means @end tex @html k-means @end html clustering, known as @tex $k$-medians @end tex @html k-medians @end html clustering, in which the median instead of the mean of items in a node are used. In a theoretical sense, it is best to use @tex $k$-means @end tex @html k-means @end html with the Euclidean distance, and @tex $k$-medians @end tex @html k-medoids @end html with the city-block distance. @node SOM, PCA, KMeans, Cluster @section Self-Organizing Maps @image{images/som} Self-Organizing Maps (SOMs) is a method of cluster analysis that are somewhat related to @tex $k$-means @end tex @html k-means @end html clustering. SOMs were invented in by Teuvo Kohonen in the early 1980s, and have recently been used in genomic analysis (see Chu 1998, Tamayo 1999 and Golub 1999 in references). The Tamayo paper contains a simple explanation of the methods. A more detailed description is available in the book by Kohonen, Self-Organizing Maps, 1997. The current implementation varies slightly from that of Tamayo et al., in that it restricts the analysis one-dimensional SOMs along each axis, as opposed to a two-dimensional network. The one-dimensional SOM is used to reorder the elements on whichever axes are selected. The result is similar to the result of k-means clustering, except that, unlike in k-means clustering, the nodes in a SOM are ordered. This tends to result in a relatively smooth transition between groups. The options for SOMs are @itemize @bullet @item whether or not you will organize each axis; @item the number of nodes for each axis (the default is @tex $n^{1/4}$, @end tex @html n1/4, @end html where @tex $n$ @end tex @html n @end html is the number of items; the total number of clusters is then equal to the square root of the number of items); @item the number of iterations to be run. @end itemize The output file is of the form @file{@var{JobName}_SOM_GXg-Yg_AXa-Ya.txt}, where @file{GXg-Yg} is included if genes were organized, and @file{AXg-Yg} is included if arrays were organized. @file{X} and @file{Y} represent the dimensions of the corresponding SOM. Up to two additional files (@file{.gnf} and @file{.anf}) are written containing the vectors for the SOM nodes. In previous versions of Cluster, only one-dimensional SOMs were supported. The current version of the Cluster introduces two-dimensional SOMs. SOMs and hierarchical clustering: Our original use of SOMs (see Chu et al., 1998) was motivated by the desire to take advantage of the properties of both SOMs and hierarchical clustering. This was accomplished by first computing a one dimensional SOM, and using the ordering from the SOM to guide the flipping of nodes in the hierarchical tree. In Cluster, after a SOM is run on a dataset, the GORDER and/or EORDER fields are set to the ordering from the SOM so that, for subsequent hierarchical clustering runs, the output ordering will come as close as possible to the ordering in the SOM without violating the structure of the tree. @node PCA, , SOM, Cluster @section Principal Component Analysis @image{images/pca} Principal Component Analysis (PCA) is a widely used technique for analyzing multivariate data. A practical example of applying Principal Component Analysis to gene expression data is presented by Yeung and Ruzzo (2001). In essence, PCA is a coordinate transformation in which each row in the data matrix is written as a linear sum over basis vectors called principal components, which are ordered and chosen such that each maximally explains the remaining variance in the data vectors. For example, an @math{n \times 3} data matrix can be represented as an ellipsoidal cloud of @math{n} points in three dimensional space. The first principal component is the longest axis of the ellipsoid, the second principal component the second longest axis of the ellipsoid, and the third principal component is the shortest axis. Each row in the data matrix can be reconstructed as a suitable linear combination of the principal components. However, in order to reduce the dimensionality of the data, usually only the most important principal components are retained. The remaining variance present in the data is then regarded as unexplained variance. The principal components can be found by calculating the eigenvectors of the covariance matrix of the data. The corresponding eigenvalues determine how much of the variance present in the data is explained by each principal component. Before applying PCA, typically the mean is subtracted from each column in the data matrix. In the example above, this effectively centers the ellipsoidal cloud around its centroid in 3D space, with the principal components describing the variation of poins in the ellipsoidal cloud with respect to their centroid. In Cluster, you can apply PCA to the rows (genes) of the data matrix, or to the columns (microarrays) of the data matrix. In each case, the output consists of two files. When applying PCA to genes, the names of the output files are @file{@var{JobName}_pca_gene.pc.txt} and @file{@var{JobName}_pca_gene.coords.txt}, where the former contains contains the principal components, and the latter contains the coordinates of each row in the data matrix with respect to the principal components. When applying PCA to the columns in the data matrix, the respective file names are @file{@var{JobName}_pca_array.pc.txt} and @file{@var{JobName}_pca_array.coords.txt}. The original data matrix can be recovered from the principal components and the coordinates. As an example, consider this input file: @multitable {UNIQID} {EXPX} {EXPX} {EXPX} @item @code{UNIQID} @tab @code{EXP1} @tab @code{EXP2} @tab @code{EXP3} @item @code{GENE1} @tab @code{3} @tab @code{4} @tab @code{-2} @item @code{GENE2} @tab @code{4} @tab @code{1} @tab @code{-3} @item @code{GENE3} @tab @code{1} @tab @code{-8} @tab @code{7} @item @code{GENE4} @tab @code{-6} @tab @code{6} @tab @code{4} @item @code{GENE5} @tab @code{0} @tab @code{-3} @tab @code{8} @end multitable @noindent Applying PCA to the rows (genes) of the data in this input file generates a coordinate file containing @multitable {UNIQID} {GENEX} {1.000000} {+00.000000} {+00.000000} {+00.000000} @item @code{UNIQID} @tab @code{NAME} @tab @code{GWEIGHT} @tab @code{ 13.513398} @tab @code{10.162987} @tab @code{2.025283} @item @code{GENE1 } @tab @code{GENE1} @tab @code{1.000000} @tab @code{ 6.280326} @tab @code{-2.404095} @tab @code{-0.760157} @item @code{GENE2 } @tab @code{GENE2} @tab @code{1.000000} @tab @code{ 4.720801} @tab @code{-4.995230} @tab @code{ 0.601424} @item @code{GENE3 } @tab @code{GENE3} @tab @code{1.000000} @tab @code{ -8.755665} @tab @code{-2.117608} @tab @code{ 0.924161} @item @code{GENE4 } @tab @code{GENE4} @tab @code{1.000000} @tab @code{ 3.443490} @tab @code{ 8.133673} @tab @code{ 0.621082} @item @code{GENE5 } @tab @code{GENE5} @tab @code{1.000000} @tab @code{ -5.688953} @tab @code{ 1.383261} @tab @code{-1.386509} @end multitable @noindent where the first line shows the eigenvalues of the principal components, and a prinpical component file containing @multitable {00.000000} {+00.000000} {+00.000000} {+00.000000} @item @code{EIGVALUE} @tab @code{EXP1} @tab @code{EXP2} @tab @code{EXP3} @item @code{MEAN} @tab @code{ 0.400000} @tab @code{0.000000} @tab @code{ 2.800000} @item @code{13.513398} @tab @code{ 0.045493} @tab @code{0.753594} @tab @code{-0.655764} @item @code{10.162987} @tab @code{-0.756275} @tab @code{0.454867} @tab @code{ 0.470260} @item @code{2.025283} @tab @code{-0.652670} @tab @code{-0.474545} @tab @code{-0.590617} @end multitable @noindent with the eigenvalues of the principal components shown in the first column. From this principal component decomposition, we can regenerate the original data matrix as follows: @tex $$ \eqalign{ & \pmatrix{ 6.280326 & -2.404095 & -0.760157 \cr 4.720801 & -4.995230 & 0.601424 \cr -8.755665 & -2.117608 & 0.924161 \cr 3.443490 & 8.133673 & 0.621082 \cr -5.688953 & 1.383261 & -1.386509} \cdot \pmatrix{ 0.045493 & 0.753594 & -0.655764 \cr -0.756275 & 0.454867 & 0.470260 \cr -0.652670 & -0.474545 & -0.590617} \cr &+ \pmatrix{ 0.400000 & 0.000000 & 2.800000 \cr 0.400000 & 0.000000 & 2.800000 \cr 0.400000 & 0.000000 & 2.800000 \cr 0.400000 & 0.000000 & 2.800000 \cr 0.400000 & 0.000000 & 2.800000} = \pmatrix{ 3 & 4 & -2 \cr 4 & 1 & -3 \cr 1 & -8 & 7 \cr -6 & 6 & 4 \cr 0 & -3 & 8} } $$ @end tex @html

6.280326 -2.404095 -0.760157
4.720801 -4.995230 0.601424
-8.755665 -2.117608 0.924161
3.443490 8.133673 0.621082
-5.688953 1.383261 -1.386509


·
0.045493 0.753594 -0.655764
-0.756275 0.454867 0.470260
-0.652670 -0.474545 -0.590617


+
0.4 0.0 2.8
0.4 0.0 2.8
0.4 0.0 2.8
0.4 0.0 2.8
0.4 0.0 2.8


=
3 4 -2
4 1 -3
1 -8 7
-6 6 4
0 -3 8

@end html Note that the coordinate file @file{@var{JobName}_pca_gene.coords.txt} is a valid input file to Cluster 3.0. Hence, it can be loaded into Cluster 3.0 for further analysis, possibly after removing columns with low eigenvalues. @node Command, TreeView, Cluster, Top @chapter Running Cluster 3.0 as a command line program Cluster 3.0 can also be run as a command line program. This may be useful if you want to run Cluster 3.0 on a remote server, and also allows automatic processing a large number of data files by running a batch script. Note, however, that the Python and Perl interfaces to the C Clustering Library may be better suited for this task, as they are more powerful than the command line program (see the manual for the C Clustering Library at @uref{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/cluster.pdf}). The GUI version of Cluster 3.0 can be used as a command line program by applying the appropriate command line parameters. You can also compile Cluster 3.0 without GUI support (if you will be using it from the command line only) by downloading the source code from @uref{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster}, and running @* @code{configure --without-x} @* @code{make} @* @code{make install} @* The executable is called @code{cluster}. To run this program, execute @* @code{cluster [options]} @* in which the options consist of the following command line parameters: @table @code @item -f @var{filename} File loading @item -l Specifies to log-transform the data before clustering (default is no log-transform) @item -cg a|m Specifies whether to center each row (gene) in the data set: @* @code{a}: Subtract the mean of each row @* @code{m}: Subtract the median of each row @* (default is no centering) @item -ng Specifies to normalize each row (gene) in the data set (default is no normalization) @item -ca a|m Specifies whether to center each column (microarray) in the data set: @* @code{a}: Subtract the mean of each column @* @code{m}: Subtract the median of each column @* (default is no centering) @item -na Specifies to normalize each column (microarray) in the data set (default is no normalization) @item -u @var{jobname} Allows you to specify a different name for the output files (default is derived from the input file name) @item -g [0..9] Specifies the distance measure for gene clustering. 0 means no gene clustering; for the values 1 through 9, see below (default: 0) @item -e [0..9] Specifies the distance measure for microarray clustering. 0 means no microarray clustering; for the values 1 through 9, see below (default: 0) @item -m [msca] Specifies which hierarchical clustering method to use: @* @code{m}: Pairwise complete- (maximum-) linkage (default) @* @code{s}: Pairwise single-linkage @* @code{c}: Pairwise centroid-linkage @* @code{a}: Pairwise average-linkage @item -k @var{number} Specifies whether to run @tex $k$-means @end tex @html k-means @end html clustering instead of hierarchical clustering, and the number of clusters @tex $k$ to use (default: 0, no $k$-means clustering) @end tex @html k to use (default: 0, no k-means clustering) @end html @item -pg Specifies to apply Principal Component Analysis to genes instead of clustering @item -pa Specifies to apply Principal Component Analysis to arrays instead of clustering @item -s Specifies to calculate an SOM instead of hierarchical clustering @item -x @var{number} Specifies the horizontal dimension of the SOM grid (default: 2) @item -y @var{number} Specifies the vertical dimension of the SOM grid (default: 1) @item -v, --version Display version information @item -h, --help Display help information @end table For the command line options @option{-g}, @option{-e}, the following integers can be used to specify the distance measure: @table @code @item 0 No clustering @item 1 Uncentered correlation @item 2 Pearson correlation @item 3 Uncentered correlation, absolute value @item 4 Pearson correlation, absolute value @item 5 Spearman's rank correlation @item 6 Kendall's tau @item 7 Euclidean distance @item 8 City-block distance @end table By default, no clustering is done, allowing you to use @code{cluster} for normalizing a data set only. @node TreeView, Development, Command, Top @chapter TreeView TreeView is a program that allows interactive graphical analysis of the results from Cluster. TreeView reads in matching @file{*.cdt} and @file{*.gtr}, @file{*.atr}, @file{*.kgg}, or @file{*.kag} files produced by Cluster. We recommend using the Java program Java TreeView, which is based on the original TreeView. Java TreeView was written by Alok Saldanha at Stanford University; it can be downloaded from @uref{http://jtreeview.sourceforge.net/}. Java TreeView runs on Windows, Macintosh, Linux, and Unix computers, and can show both hierarchical and @tex $k$-means @end tex @html k-means @end html results. @node Development, Bibliography, TreeView, Top @chapter Code Development Information In previous versions of Cluster, the proprietary Numerical Recipes routines were heavily used. We have replaced these routines by the C clustering library, which was released under the Python License. Accordingly, the complete source code of Cluster is now open. It can be downloaded from @uref{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster}. We used the GNU C compiler in order to enable anybody to compile the code. No commercial compiler is required. The GNU C compiler is available at @uref{http://www.gnu.org}. There you can also find texinfo, which was used to generate the printed and the HTML documentation. To convert the picture files to EPS files for the printed documentation, we used @code{pngtopnm} and @code{pnmtops} of Netpbm, which can be found at @uref{http://netpbm.sourceforge.net}. The HTML Help file was generated using the HTML Help Workshop, which is freely available at @uref{http://msdn.microsoft.com, the Microsoft site}. The Windows Installer was created with the Inno Setup Compiler, which is available at @uref{http://www.innosetup.com}. For Mac OS X, we used the Project Builder and the Interface Builder, which are part of the Mac OS X Development Tools. The prebuilt package was created with PackageMaker, which is also part of Mac OS X. The project files needed to recompile Cluster 3.0 are included in the source code. From the command prompt, Cluster 3.0 can be recompiled by running @code{make} from the @code{mac} subdirectory; this produces a universal binary for PowerPC and Intel processors. For Cluster 3.0 on Linux/Unix, we used the Motif libraries that are installed on most Linux/Unix computers. The include files are typically located in @code{/usr/X11R6/include/Xm}. You will need a version of Motif that is compliant with Motif 2.1, such as Open Motif (@uref{http://www.opengroup.org}), which is available at @uref{http://www.motifzone.net}. To improve the portability of the code, we made use of GNU's automake and autoconf. The corresponding @code{Makefile.am} and @code{configure.ac} files are included in the source code distribution. @node Bibliography, , Development, Top @chapter Bibliography @noindent Brown, P. O., and Botstein, D. (1999). Exploring the new world of the genome with DNA microarrays. @emph{Nat Genet} @strong{21}, 33--37. @noindent Chu, S., DeRisi, J., Eisen, M., Mulholland, J., Botstein, D., Brown, P. O., and Herskowitz, I. (1998). The transcriptional program of sporulation in budding yeast [published erratum appears in @emph{Science} 1998 Nov 20; @strong{282} (5393):1421]. @emph{Science} @strong{282}, 699--705. @noindent Conover, W. J. (1980). @emph{Practical nonparametric statistics} (New York: Wiley). @noindent De Hoon, M., Imoto, S., and Miyano, S. (2002). Statistical analysis of a small set of time-ordered gene expression data using linear splines. @emph{Bioinformatics} @strong{18}, 1477--1485. @noindent De Hoon, M. J. L., Imoto, S., Nolan, J., and Miyano, S. (2004). Open source clustering software. @emph{Bioinformatics}, @strong{20} (9), 1453--1454. @noindent Eisen, M. B., Spellman, P. T., Brown, P. O., and Botstein, D. (1998). Cluster analysis and display of genome-wide expression patterns. @emph{Proc Natl Acad Sci USA} @strong{95}, 14863--14868. @noindent Hartigan, J. A. (1975). @emph{Clustering algorithms} (New York: Wiley). @noindent Jain, A. K., and Dubes, R. C. (1988). @emph{Algorithms for clustering data} (Englewood Cliffs, N.J.: Prentice Hall). @noindent Jardine, N., and Sibson, R. (1971). @emph{Mathematical taxonomy} (London, New York: Wiley). @noindent Kohonen, T. (1997). @emph{Self-organizing maps}, 2nd Edition (Berlin; New York: Springer). @noindent Sibson, R. (1973). SLINK: An optimally efficient algorithm for the single-link cluster method. @emph{The Computer Journal}, @strong{16} (1), 30--34. @noindent Sneath, P. H. A., and Sokal, R. R. (1973). @emph{Numerical taxonomy; the principles and practice of numerical classification} (San Francisco: W. H. Freeman). @noindent Snedecor, G. W. and Cochran, W. G. (1989). @emph{Statistical methods} (Ames: Iowa State University Press). @noindent Sokal, R. R., and Sneath, P. H. A. (1963). @emph{Principles of numerical taxonomy} (San Francisco: W. H. Freeman). @noindent Tamayo, P., Slonim, D., Mesirov, J., Zhu, Q., Kitareewan, S., Dmitrovsky, E., Lander, E., and Golub, T. (1999). Interpreting patterns of gene expression with self-organizing maps: Methods and application to hematopoietic differentiation. @emph{Proc. Natl. Acad. Sci. USA}, @strong{96}, 2907--2912. @noindent Tryon, R. C., and Bailey, D. E. (1970). @emph{Cluster analysis} (New York: McGraw-Hill). @noindent Tukey, J. W. (1977). @emph{Exploratory data analysis} (Reading, Mass.: Addison-Wesley Pub. Co.). @noindent Weinstein, J. N., Myers, T. G., OConnor, P. M., Friend, S. H., Fornace, A. J., Jr., Kohn, K. W., Fojo, T., Bates, S. E., Rubinstein, L. V., Anderson, N. L., Buolamwini, J. K., van Osdol, W. W., Monks, A. P., Scudiero, D. A., Sausville, E. A., Zaharevitz, D. W., Bunow, B., Viswanadhan, V. N., Johnson, G. S., Wittes, R. E., and Paull, K. D. (1997). An information-intensive approach to the molecular pharmacology of cancer. @emph{Science} @strong{275}, 343--349. @noindent Wen, X., Fuhrman, S., Michaels, G. S., Carr, D. B., Smith, S., Barker, J. L., and Somogyi, R. (1998). Large-scale temporal gene expression mapping of central nervous system development. @emph{Proc Natl Acad Sci USA} @strong{95}, 334--339. @noindent Yeung, K. Y., and Ruzzo, W. L. (2001). Principal Component Analysis for clustering gene expression data. @emph{Bioinformatics} @strong{17}, 763--774. @bye cluster-1.52a/doc/cluster.pdf0000644000100500010050000075322412177163717016063 0ustar mdehoonmdehoon%PDF-1.4 %äðíø 6 0 obj <> stream xÚMPËnƒ0¼÷+öhKÁÁOàÚ¨iR5‡(ôTõ@‰ÓX[!Њ¿/°4­|ØÏjgvàâáqH$&cie ÷9,×ĎΠ?O!â:e‚C~|%ùÙÒH&Š¬Æ¢Éªê®­mœÿ@üìÞ›¢éé[þ9\@²,Õð{Ì´§¥ãªà{ÔÀc–Å“n¢FGO9KÌ?i)É‹w_T$Ä6W׎M?þ NÈç4ÀgOEJ¹­¿¶®íÚi…ºîìÑ•E…àP:ëK»À‘MW‰GëC=‹¯¬§ÂáæéÆåZWL*3šŽ´™\+a˜D×;WRÉÉÙÙ ƒ;ZLj†ÊIð Äëz*cRàØ¶mø¥Š64ö»yʇ¿Œ9Ë29gl¸-ÌÏ3Þßý`||® endstream endobj 7 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 11 0 obj <> stream xÚmV[s¢H~ß_AíS[®*ûF#SÀšÚÝ‚$öFÁœTþýžKkÌh¥*Ý}®ß¹¢öŸfi&üYÚÄÖ&cߘúZµ×î íËÂÖ,ÓðM_+ž5kªéŽkž­›¿„3ÒÇÁñåØ|·MËýS|cºå–G‚ŶföL;P¨;Ù¼ð;–O]Ù½ãÃÏmÇÔjž|Û˪kË®+GöX˜-6åPgWcÃrÉÕ¬=Œì‰xïäËvdOÅ@"žkØÍp’©ˆöeá^„¦;†éhúIäoÓò”Ô§¸†çC±MÓÖáŸÇW²BÇ[Yïàײá€âòØÕMÏb•‰e;Ò^Û}ìÿsÊ$jX¾Ø“7ôQg*Þ:9 uÜràs \Ã%.ŸØEWíI¿}æ“S —¨|ïËA¶ÊNД»÷^öwð´m±<îKÅy¨›v__Wwu|löƒŽ™:ìsêŠU½‘U¹ãG^ɺ©jÒ‹u#¢ºëå€e{¿TuD1šÚ¢}}GV«¼¸úX·”±­ìÚב牲©7¥TVW²Ðõ×ãÝ–¡ye‘Kb™S}:vü;~~-ecÜ·åpËjøCµˆwÑ".Tr¬Zd¿©·-%ìý¿óí¥¯ŒN¾ÖñïáF“élB·}ÃöÉÎ#çf/ûžêdû¶°|W{J¢i‹Jµ>FF$Sì¹Ë6òù3¨¨e³aÝì‡N>Q¥ð=PÓÙ¾#úöyÀa{Ãü”]Í>ÏŠrè•vP÷ª T'¡ô›¶,}•Fä¶ÇÕÎ à¹s+²¦–r "´ðR6%(øâpìÜå}}b+… –x®›„s[wõÓ…¡—®T]¼¹CЦ8t-fà§ÜÔ–¶åpÈvbõiý€9&7í «Çv:åá@ÑÖeÇÙ(ÆŽ†ÃC+ò,ñ ‘¼é‰Ô[Ì.>!̾>+ÒŠüØ~7Ü„d\…£°}4›c;Êo†?UðIðѧí^í@¼Ý ´\\L¨Ø@ž×º,÷„h´HJA¨ÔBïê×aÝ¡¦é ú”Ày+/æTlÛݦ&YËÄY˜×fͯ ó)L ”µªÙs˜Žǧ¬p‡qK I%t(eÃò` §™ç ”êKð) Ü9îœÆr¢>]Í_šs§“ˆªNųÄÄC'ù«êþZߟÐbŽtÒ3K“"‹î×EšåL ’ù‰õø#‹–?—i<OBé‚ÏbÅyº(¾,ËA¦lÏ£üFéfq­ 3AóMPÌ‚¤ˆÂ\£bÉ·,|²9ß‹ωòŒ”“g4Þ1-Jfñz%Ž®€D«Ç8 Á¬ëN¯¸î„¢Dæ*̰³%0qó÷Q?Xˆò…R‹¨HÂ<¿Ã|t¦&)ŸáŸ!(_È—”V6ÕÄ5­_j‚”4;qÎ%AsIw¯´ã(¸Õ}°Y‚K~Üðÿ΢ ¦´¹zeá¬À—GŠxž<ü¶ü É‚sµ`à =pÁ\%ï’#Rœ£û_¥¾/üN7Z#O!KhÄŸ@ÍóuL‚\EøÖ/2ô𮸧9Zô¹QeSùÂŽGü«êÅ„¸TÍê•ß±æ÷eÙWž±r($—Ç„0 >(¢”ªë©™pÉ“`,’ð!ŽÂdò›Ê€MÅžæÓuÎö>ì++Avsˆ('¸ÒuÁãHèÌøÄ(èwxš$¡BŒož*¼Q¿áòöY÷1Ì”êl~ò´8©ÁàÝ(ÝÅøó íÛoÿó-Þ endstream endobj 12 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 17 0 obj <> stream xÚíZ[s›F~ï¯à­èA[öÎæ-uœiÚÉ4mÔö¡îÃZ`‹ дɯïYØl-²’:¾IãƒÑrd¾ïœï\–àïüà@’@ …b,×Á÷‹à»×$ÀR‘ c)`ŠÉŸa6ûkñ#,–ˆ`n͉ͪ9;¤]¶˜)êó<Í©dayaŽ<<)‹Åa“v‡Ú£fˆ2aŒE`£ˆµfðlŽ1aáX…MU‚™(L6Ë&KÝÍrt3†S.À†¹ùÜ,DwׇpqYB%¢Ò‚ƒÛsÊ1RŽѸý€´óðUV7ºX¦q›¢Å¼öÎÁ®zŽ ocˆ8³ÏJì‚qÀÌ)…ˆQX@¬sb‚ŒGQ¾Ò<) WºHò¬¸´â‘ø{ÐòˆYŒˆºnná~y^—ù¦Ùs°¥Œ¨rz°‡<‚]áÆ¦±ûß lëœ6­ÒÄNn:9 ÏàH›%¨-ÐáØtQÂB]\æéÙÌC¡ Åñ£$Ç]Ĥ·C'½n»ÙòVϕ걂󵔫i>tl‘~Õ‰¬®ÖÚŠB¥‹{Ìù³ÐÝ;HÎb6õ”åá§´Htžëj>®_!0œ©³3Ï—ñòµnV$F,ÞÓD£7>½‰ÃO£°z”}M¨¼Ýpdât³Ì³$uA™¸9€' A=68w¸KÄ]¨ˆm¢„#ÊMN²Æä¦óóܬ2\š??tù~'mô(Ÿwׇ`1è­Ø_npp¢óåÆä6×Vö5W2ŒÜàòy—[Žÿ1C†4-l-—oj¨H|](! 1ñ˜ÕÒ“±àó=¤7[¹1`Ìd *û×ëð1Â׊2yôû/È$#æä>ö Gç”3Äy0'4·´b7M~gæýºj2SÒuž/¡ÉÈ/Ë*kVkïXYAõñ¿gJÌñàÑX}cb³eBÆcbډߓγOSp,QÌŽ#âû DñuZò®GJEûñë¬H¶eÞÊ·ítlƒY•Yâ„Dˆð¥Ú7 ¡ÈåZì¶°°Bäþ&””Rc˜#€^'`m+]–ý•$Ó…·‘HÊG§H» cÑÞ ù È’)oeH’gÜøÆlhp1™Ö„­âåô­´¹$èÒƒУTQ#G±@§¹b;õ»¼j²µÎ»«í¸pjŠÍL {`“ Oˆ5ì™÷°oKð`ïV£»)¶e?xçG‘ ¹ÑòºãE‰Ça{3iÀ×d±‰úCÝ £ªh½äÓkòÎ#Çzø>fTÚ•¾±áÓ ê¶OVÝ^jYßÔÑ­î=Õõ¦òΫ$C êžJ¯WXx[nÖöÚ£–›Ù–û‡,­tµ4÷*[¶ùJöÍÇð¾Êµ–;Hȧƒ´¯ó–÷‚ܯóf}çýkzU¥µmɬǒPwº²€ÂgÐa×—Ì; ÂäCÛXÝCbާ¢™õýl·_]”Õº§GEøQyáÙÂÊ}kS¥©ë-¶ƒŠâ{Ôõm„$&-»rÕýɦ»Ÿá7´E‡‰Úwk»a æa/¤à O‘A²H´Ÿdq+YïÓübþsu©‹ì“òð­¾òŽ¥BR<¹êÚ#YàåÎɉkÐE±¿–+Ü oß o§ðÁeZ@¼5eå}v6|ñÃ<»Rú¤Ké§‹à—oþe endstream endobj 18 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 22 0 obj <> stream xÚí[[o£F~ï¯à¡Xªg™+3y¨´íªªZ5ÝuûÒöÅdƒŠÁÜlúë;Ã0€ãë$v67EŠíd˜ïܾs±÷‡½@ÿ`/$^(’Ê‹WÞ›…÷êñp€T ¼Å¹ÇEŠyXÿæÞbù‡Ÿ¦³¿?êUÔà Q&̪9#Ü,›½7ëälŽ1aþoUššÍiÈýú"±oNÛ—lSÕIÙýÿ§ôc•WöÃeZ_ØwgWõE‘Ÿ4·¥éÍqs7s›³«ØîbÖ2?Ê—ö¢7iÚýÛç Ï‹¥@$ÔÇ7[œè'¾„[/Çÿ£ù´ 'ÖhRÜ> ÛC±Ì)‘H„@Ì"!Ö;AàŸÍHèGeÖi‘[t)ñ£ìSQjPWU»Ÿì‡iˆè âžqyhÜ•V…r[FsŠ2B¡s'-{µ\M)¢´½øo`wŽÒþ{¾J¢¼22¤zïnÆ%"lïÍ–i·]Ü ;!ž0Ì1Ú}ã-cêqTYìž, ûÈ€ÜYË"]Þ6w!›Ú×àîÕÝE XƒÚ…lB™dK"¤uU?¤‰vù±qXieÖUõƒ®Š rßc‘#îüQ£ÖBL QJùï“u™TI>#¯û8bàÜÐ4ìçªÈ6& r$\‡®- 8¦§…Nih0qvbÏ~f”çE¹êN~ñe…¼ bÎ"ê2IÆý¨`ý#ÞÀtàD‡µ|Ð'lÎn&tsL÷8‚¡)#0 Àˆav ªô=*ªù‘º3T»iŸÜ ‹Ò -a£ÓM]£1~ŒâM Z É¡Œ P&¹àçiëç?$Ùùü—òS”§ÿuü­+0‚jñAU¬ÆM†+DŸF$€B©BŽÛP61k!~—æË^½šTK+eŸ%4¾<ÔZe( ˆ¼&TC´½T_d/ðW´_~ßÔ£À¹ÊÇáá-< ‹õ—iUGyÜâóq6׈$µq÷—3"ýDcÔøõÚ@ui~[ŽNgDn×Ýh7©ŒÃ=‚ÿ’ƒ('ÆA-(§Qo²¨ÞÕ›!JÔ_Eu™~.Y¯î"»:·ŽÂÇ5X ò‡}¬ á8&¡Ëžµ“ŽÓµsܧÅj­uDúEÞZýûë<Ê®ªtÄŒdOmÖqùgmhâ‘».ÈgñÞgMÐéè¿Nh³NùÚzÍ«ÅL_G¾ßÓär^£¼Z[3µëþ 0Ë’ DUs(ÀúXñ$ ±ëxîòé»qr»êÈ5pRyŸÄE¹nE{ïU ¶æ\/ùÖ´ Mð}„x‡ÔÊ“Uˆ$~5ÎÛ—ØîUŽÈQ¹Ý’Ž»qÞ»ìFü¢„ªnAÿp·¬ºÁŒŠ¨{@¬8â®Ìðè.Úæ]4FùAUU¦˜ýh¢! ª çA™@[Ôl9ÖE¶.,[‡@šDÒ‡j߆W[Ð)%€WŒ(e ÑÚÐÙÐÿ–ëïÐié'04rbúg÷ÌkEß#š„$¼$£äKíÄ#gpÉZ8’ÅØha¬a­Ma,2fùo›¯[op™T›¬M—÷5ž§X†,˜öÌœñ uUå·Ÿ£Õ:sU §»`%SŒ¡¦“T†ˆwø ¨‡O™2%•9i^Ì:Õôðù!zø3Š53ËFºø¯]oúäd¢i¯“K%¡à[[Í~M¸„#?lÏf¿êšýN6Úÿ䑿™Ö`ÖQ©?Œ„+Ì8œ¼ØËÀ^tVÁ¶¥”2T×É|Ÿœ'e¢£hËòë¢eÃe*qU}×öÏš³¢«9óeºJòJ»7—Ú5Q8†‹!9ZÕlœu•~¦Æq ÷5|òü&R¾0|ÂÆZ¹Z(»…!5RIa10…rçtÂk¡,@¡ÚkŠD~½)’†I0ÉáÀŒ“LÃg¦Iö& ‘¼©KøÚŒP¿u„„ãqÇÂö;‰ªg=_ì¾ËGK.àÊqèâ'£JÍžú°ÇäٟŰgvØ {| :è$Xì?è0ÿ~l„‘>ÂÜRcL À=+xvð ~¯ñÁFîÌýÖsØ'g\Œ»sþ2rˆ‰>‘’ˆ—‰.Çá ŸëDŸHßä3ó-&êe"ä !‚ŒëZ°_o>§YjKˆÔóMN Ö t¸»Ÿœñi(`ÜJÐ á£í¨c|â+ ,°ž¦:J#1žØZ ø;zjM¦cWÕÔ^Ò;줎I·9¨ˆ#úïž ›h¾]x¿~ó?# S endstream endobj 23 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 25 0 obj <> stream xÚå˜]oÚ0†ï÷+r騊‰¿íÝ­¨H›ZµS™6iÚEÒ6j>X[»_?'—QZ¶¢ Èñ‰Éy|ŽÏk¼ïòBýBžÀžà JåŹw<ö#졪PyãkRýyˆ@żñä+HÓÔÿ6þàDb/ÀÄ8˜!‚Ä”RàÂÇ$ÕuYåiq³¸c0R++ ×`n¼kÆW˜™Éíp'Q1óB(+Ç\,„Dm=×$íf‹³ù¬NªåÊõ'¤ímoýqn?„ëj'cÿI¹€ª„³4RPsÖK€Ø’3µœ‡Qϳ¨6!è(ˆld—IvœW7Q‘þjÆ8‹¦Ž8q( U«¾\„»û.}NH¨Å7bÔ(-&¤ú6YK€æ")LÖÖU™Nœ ËÇBžÑ–R¨Ú¬çbXþHvp'é¬ŽŠ¸¹ºò,ARûX€Ÿæ-Ѹõ­I‚rmUf®de†t?Ué(GQ»IqÙƒÁ—0ÄÓ`äQ]¥÷®$Ó»*"¯ ÉžH˜ÃP´ìÔ¦D’–ÝedªïGƒ÷Š´cZ%³yV;+4„|oìþa¹ºêTv¡Šp]eéžÜGù4K,Á¸MÓ²pa$ʽ6¾×bü“‹ƒ»Ä®sŒˆ^H(7¡ jß/>Œ õ|30,óišÙ< DÅÄ~Ѧ»¥+³!…¡Ðsú C@ƒ ;XKÓlôÒDzÊ0 ÁûBo˜YÖ‰—f; `h¯‡k»§éUUÖGëNk½x¨oIŽY*ˆ¿ˆ­A†&ú5N&SÄ+µ¬ýñË’Yôà*s±!²×²ôiaÎÄ6ÀHì]'³Ù޼ª2oÜã#--ÚÅSÛγ |yädúHÒ —Ê—}’³Ö.;>k¹\.tÙÌ©R¤n-Þ"›»n|¸tU¶Õ³(¶Cç—ÖðÅy#Pº$îÁRÕ•ˆ¶¡Êw£zš&Sç÷ƒO…STãP÷b~p'7—¨f+=uJñ$”QóHÔÈÃ2Ï­8Ñ6}o£Ã§UySE¹s ”î£ñ>û&gPvm€m'ÅŽÓ«,5QLo}‚ÀƒCriÅ¥ø¡~wÉÆU¾˜éµhÀþs2ö>¾ù ŸÍvA endstream endobj 26 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 28 0 obj <> stream xڵɒã¶õž¯Pùbªl±IpŸ9µÛÓIÆ™¤Û•C:ˆBKH“„† ­È{ÞRb‹]ñ¤fJU"–¼o[|\„‹~á"‹,-ü¼X”õ⻇ÅÍb~‹‡§E˜/ÂÈ/’ÅÃöŸÞz/j—«(мðÍrDZw×,Eæu­Y®à»íËN›fù¯‡?-b‘úIHðlHK7?¤‹0óE˜àå+±Š¿p`«$xið¥ð½¼tJ^°X‰ÜÇ1’WõÈÓÍ)Ë=mñ[xG½UÕ‰×z«¶¼ªþîT£xOýçÐ*kíle'yG6²:Ymýå*+Bï;wÙ®5ýÁ¡ã‹,otf§º=H )A„!‹p#™z„Fy`u­+Ùên)RïÄ@’ª¢¥ãR‘ªá8¦[>èX€Ñ„˜Zó„q¥ì·¬­§¾!YÊŠ$ ­ªdÇ4 ÇÃÕµDŸPñ‚H:Ø žLßl}¼;ñîûÁö &à,£(Š=ÛïvÊv–÷ˆsºÅQÅ@æ‰W‘ÅÖUx©ožƒ+dž±Á>QÆ~Õ©ÆDõ_{kü$ûÀå¿èM+ÛO´e ÉÓÒT•º¢)ñˆœ¾†[JY1MÀ`§IõÐíeçn¬•ª¼Ô •@ÊŠ¨^ dÂHEìÉjgÀ öµå9ßN;­âAm¬[*M]›E…3´tT ‰kgR ^6<5J•F{8ï˜nïÐã#/’×ÌD6[§XÃ_Ù¶l9Ögó{4^NtME{oÜ{/Þ{Ž®èBÅ`ÜÙŒ[…ŸŽçV e¶ÌAiâ ÿ£wº=j;(H nMoWßò ЕâIôÛ¹ytf^â[ý…Þj+wjUéæy™¤Œ—og˜Z1¹ól¯°õ<ÃvâÂm¯j%ûRÖóØ3?Í>Q¨÷ªzZýµÝÉFÿ:Êð½<ØOæï5 €ÞR†G¶i³-6/Jx·£g¦Ç”úi ˆ ?ŒØ,sá‘ѦHÄöüj2~‰8xétÒ´¼·Õ¶“Mé Ý+éÈýà¹b„gÿ‹0—þ—n€‚ö$žÒ»½#Ï\Þ#m¯¹¤ÙÏI&–‰%஀øMõ¹ÞÊbK¶Ö8÷Zš–â0ôÙ4{»±¦ê;Ç sQõn:øþ14|@½|i’~n†÷®Zr}Y1•.\ FKÀg¨½ÐOãùœ”  ä'‚­ ¥çAãXœlJt+<|ac.ÜÓ•c`x²“+ü Q]v¦µÿ‡³ùß*þô/¥kSiÁ iâ,­d"-8ËQ%Þ¤8K«pÒ*İz¶†ÜEqÌNv×iÖlÚ„æs~¾†8ËcSü²»?0-²­eóµ o­„˜ÀÎù ˜óŸU³!}m\~gè_wUÏ\•ºíYzRÈØ‹O¤çû¾¬ — ³<¸¾ÏÆïZ“VO«MÅUEûg§_‡í*B—$bæ'ÀDª!l!±i,ÂCGÀ´ûÞþtÇ£5¡çœW¡}C  ž Ř:£ä #M©akÀ­-ßD‚ó.¬¶pi}³vBH.„呟9!|óÍœ”¢³¶¡p1&á%9¿—”öv­¬©º Ò!MÆ‚ ð"?àrãÑ›Á¡…îþ}×ÞÜÜlLc¥ö5Üׯ:ó|2¾,ýn~«·joLscÍSw„Xv㓺#( ãA½KG¶Èü,½|樺4Åú ¿„_‰IOÐsà׎e ò"y–Ã8 àÆh8ë<9fÉt^¶.{È* ùöS_1èq¯šk§T¢ãgÔa­©y$ùcËV:Ê¥pZcë!ct›ÈBŠ,dYDf‰«Nݽ+ŽgÕ#²ÄOâ©zŽÇ£ ƒ¾iw³+ðE6в—<o+ÖDT$~^ò6‹?öÅv¸æ5ÜAŽ€ Ü WLÇ’0ðþÞoœ:’ ˜Ç˜ÆçøeÛoN¿%D"¦:q®Ýç¢\ÀùP:’4DžøÅDцãԘ‚Çz(«Ø~ZZÊ¡rÆ'–e£q‘|-:y¿|ܬàxû$Kj2dì%ð뼿0"œFäŒÖŒ“Áš¯¬“Ù–;TqÛ1¿¿ÿÇÝCµ4ç BÃŒðíQï~¯ðYžAáçÓBž|4žB©Ç²€KÞKI‹ScÜ*' N?—G$“ÂJZÅO«Ñ{ê’DÁØ[AøI?¦31‡‚KúùÄL'Ä´+D£é@a‚=™°p -!på$Æ—G 5e–Þ¶¯H«p-„ÜiÎ`x]–`)–wÈT‚¡Õ k÷9Óve#Ñ…ޤPï`¼µ. ß=÷fpÂi.öXS〱Ãà܆àÛ^l.'ì( ‰³s®ƒ§3¾ÜØØ|œ+rÁ³‹ ®šÄæbá‹â²™q3)zÑLЦÍ$Ê/¥åÒ;Å]?Üê›íÐA=×8NïÜ”‚äÚª Þk×ÄPT`ãø ½wÆUÆ<}œè¢ ' ‡÷W·_¹N-ýV?«‚õ[&æHdþFµÏÀØÉWÛ~.€‡/£’v¯ô‰«!Œ¤¾˜ô»ÚtÆ5Tî%dâ½k-à9L±ÌŒ¡JN¬L‹Ðl.ðûÇŸnqxw›…¡s€Æ •×»} íü¨S+>¶+„ƒ²ë®±î¨ºÄó^m©¹tEÝ}©dŸŽ§Ÿ÷F[‹9kî¦e/÷+žOTç± |ÿ°øÛþ 8¬Jú endstream endobj 29 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 31 0 obj <> stream xÚÅY_“ã¶ ï§ÐÛÉÓšá?QÒfòpÝ&3m:m2ÙF"âðQ*£Ôä,Ë£Í>úëMôÕw2œåxïû}x«@ߗͶ¨ëw^“,X¨S–{º[®ôÂÞ>N;i…,Ño·|«¼ß6uµµióqð·¡u÷Vî×.\¯ïêÖrƒÃó˜ÌH-™1a`¾±'-•SÅA_=Ó‹=ð„Ù; ëÀÈ¥žF”tR[‡±.žºTC›ÐË<\؉…‡Y%Á«ºt–Ôhûð´Û³øí‹ª±É‡Ã®+íãD²$^$˜µ"YB÷54!|Ÿ`[.J@f¡Ý”þh®jèyßQrhh¡s,NÂÔ¢”*QJMãË¡Gqí”û´oÊ}ÛT7D-ðéB#möXôã:O@¸«ÚCODP  USºj`ÉwŽóµ{L5ʉA½B¾å“2A®õoÕUæ2^ê3^?ví#‰Ü •õ¤"rW›Qq‡ÃºúàŠ5»GKÔ}éö²èÇ‚†aM”5‘TŽÓ`kB»Ø={ðÅO “ŽF[p¹®òII!rçŠÚÀ«…x%ÞÔn” ²ýÂO™/ýo㥠Ǥž%ðoo¢Sy=ð KD„Å?ã2ÚG",5ãDýýHו™`#•bFº€¹‹Å‰afÆÂ@¥›-±˜ÝˆFª‘ÅíÊ©§gÚ•éR/¢ˆ*ò?¿\²l¦\ž3~¿‘ê¿§’ÃÅ0à …d\\‚o¢ დ)ã?/a ¤_£´`J†À-T«KMT—} ï72 Y$9Þ¦/4RÍ@J8ï[wÿ†Z‚ŠšSã+ž0U`ºhû‰*ÐëqÍ2ù©¾ ¬«C·S" 1>Çz¤z-ëSk*©° XcWà"gO42¾Z`¼V+ .̮İ}.ãò“-u»—mõù ÍÖMÅC‰Ùžçxm”æ /¾Bà6E6îƒ ßÜ_¡à¥ßµÝPön:È0º£âv@æã½Á²žß`‚’Rëš=MVýiò+ÜuyèŠñ’nË­ÂI:¤«ÅõTô¬ï ›¢ªPX¡g—x$ìYXʱ±ŸH÷p²E>sSÄúLH€·ñ»M¤°$ü}O¯6q‡¼lᶦÌèÜaÅtKb°Ü葉IŽçÀ]µ—J~‘H¦J¡ò¬.æWÚå4y‹…T#r8c®á|‰ÝL\°í¢›KPßd¡Ÿ¿·QÆÌÊÛÑÒæ¤¹bIƒòÙøòÙ¨£6 U­ÆÒFY÷3³J&=•¿HG‡ÈŒ>S¡,ìÔÿÕâÕTf©;Tô†‹ñ-(Ra4ÕR2ƒ:‹®¶‚„aÓºÕ¶’ºñ[ùÝÇ¢ GAÑd°Ë¤±W¦AÕ÷n·¢!Âò¹Ø?Öd5{÷²d­ ±L|œËð¹¥I„AWƒÔ´±Ÿ8—ZxfÏp"lX <ëvô­Y¶ƒ!fwϳ1yÉï¦ÍÑj=_­Ow~´wm9óì× Œ°ƒŒ—ÀŒIu&9I®±Œ_'Z3“XÄr–¥ãÄg*» R@òE¯L.ÆÇ²ó¸¨ôÝÚ«ñ®ŽgÄ7ç*!*MbRPK9Áø8>‹ À‰þf Ö±3`øÿ˜dÙO@s(J\T£´õ³ +Jøû›<î¾ò0â¹^ð“ÍõôÕ† íâÙ5Xàþ1e½Ä‹d$ËYb-…=ü|œ8W²ŽT™¿Èž/ë!èd:d¡(럲˜yÃH5²@3 lßÒ‚eÆp娙Kš%S*[o oGÛÛͨ\“™—Л¨ŽÑ[(€!Jˆ êj]@o¢š¡'EvöVôe@ZÐ ÍOC 2úÜ9Fª9HéR©43ŒrƒuÎ%ŒFª#“‡¥¹ë ¢H¶Î„Lm,ß¼Éf– *èièË û9G ç]¿,]îúQÿm,#p¡Û!,#pºjÖaEC;lǨZùjHÃ…Ð? zà]QÓ`ÖÙ« pÉs«?~§ÿï8Ÿ«A j`ãPkj"QÐ_Ä!€¸^øóÂßZ”@[wI¡;T•gÛ¼@îânQ2H·YW.þ© ©Ë7 ö%€»Yúë‚•ñGÀnŸÚâEš¬ X ¯O³µ Á,ÊBC9G¦f=¶¥Z©Wýß©ã¾]ª}éæ7p*·‹ê§fÊ“}¹¯ÖÂRÿ=™ÂógôÇ?ý1ôõ° endstream endobj 32 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 37 0 obj <> stream xÚ­É’ã¶õž¯à-T¥E»|HìL•ã$¶ËSqª<>`$ª…˜"{HjºÛ_Ÿ·\$ª{²”Äò¼}}ˆD”ÂOD¹Œò¬LŠ2Ú¢?½>{##‘&eZFo‘("¡’ÒDo÷?Ç_íÃPu›­R*–Ÿo¶Zëøk×¶ÙU8ªãù٠®múÍ/oÿi™%ÆÀ1¸ZÑÐgoT$t¢t†Ûo=ÄV’Àd"6[“Éøk;XØ47ñÑ6ûÚ5÷~ƒ9~i´e"xéÛ#`¡E»æáâÙÕnh»>Ùls•/\Ïs'û+Íö¼È <\ÙÞ¡,iç–¿;[ïε*?L<Ã&žÁðûÍp¨½°u…ÉrጦŒhbÊ‹Tüå# q_5¾U==tU߃P°¯•0s²C瞀À̈ø›ÃÅ3$aÕ\°0Ix¶çYšŠ¸«>œ]çÞÀš%1ãìèeª=ɰ4O±…m¡{$Íøˆ[yâlÜ~:»¸3q®e¨‰50{èÚ“‡#Òrá ç6ë4úëÃŽ•_IìÍÅ'“vV°¨BcGƶï«=O0€ç9L<ÇáÀs)eüMÃ@m·'§ ý ý‡»Ã3¸Ã‹[¯êÜEhq0䀠ÐäTš]®-X_Uj&¾cÇõ N8úe$h쌖±-PÍg‡ûyí Y|๣õ[þ¼K…±Á— 1sf*IÜ%èKãÙÔöÕŠëÓ&Q6AÃ4h~×t®&C>ãï=mkfàF&…ðû~ùeºr°È Ü0$5¤V{?«t1g ß¾p°80"ôœÿN@bK'u®¯&ø¨ñ`Ä| ¡­,ç´{±^x/¥ä&â&õ€Žóß9"× ÔQš¤Ì|(“Ê~Ú”*®Üýqƒ^õÅH¦hå› Ù ¢ Ößö¶$Eü­Ø˜˜Œ½™Ïî÷ÆÄÖÕö}]ñvèf›ˆø+îUŸ!ètˆõÿêÞw¶{Þ€õÝ¡ô*0N0× •¼ÇäK¸¿³+æ9YÈË><ÔŽ¤iÒ”C7_n®Ìrsì/£4ŽÌVFùÁÃÕ€FUW§Š×zdÆ„£ ¶¦SIãJŠ8öж%^Ì 5?×K¾œI¾(ìÉ­hFžè`è®÷óÅÜÓD‹} @F`ô¹æõ`Ð[p-úæ*QÐ $nãñŽv¸¦„ht¤l\J…6ÁP¶ç¯;ø¯_Ý’ØíÎ] ×”HðTæ$%Kd9‘2¸S‰©¸¢fF¿‘¤Ù\ž¬yÆ!~&XÛ£ƒÈó¸in,?‚ dŠ¥Ðq̹꾢<ÍßÞ }‘¢æÆk!þøÀËlw² Ëþ•[»Øˆ# PJ€o«foëú÷kZ²ÐÖw©Òk¼›yõ’Ò¾ÝÙGÿ¼ æ[sZ‹0Eð÷yqÁ§ž™QE`TyŨ‚¢"L°ýÔõv_A€Ô ZħÊ6ä’¶ñ¨Ø®â ìÌwñvû‹lúô0©í'ùmÅ~ûoòP>ÜÄÿ@'nësտ潿; ”›‚1SÆ'·ëÚ±tà9HtYʽpUWûöTñBJþM¨_ áÓah±k'„h?b Fhƒ†RP6Û¡XÈ…ZŒ…;zzhgjÁéÌÄçž:&ýÄï~ïp­­Àç¬+iŽT&Ñ^ÓN¶ÿu…²Ldy<º1Õ<úã”À±³Þ}Ãùsî~Ïd¦Ñ;ÌÈžø…•ÚziQi®‘žgNR'"÷ ?»_~þ×/ëù“SQ|Çá’\íÊ©*MÒà‰´O9uÍ¿çyl“ªï|²€¦%Mî§½o£fWŸ÷U˜nøË^ËtKJÀXΙò%ª ^5<͆罯‰¿ß@ù n°g_§/æð˜Çè5²6‚á5 åý!›ûž4<ìIàr¥i„÷770lH ç. VØÕ ­3Té­IÊ¡©[A²HdÐŒ/iø(3{ª AAƒ~}ˆUÑc$ “¿uj’BE§H”"ÉÍ8PG?F?ðµÎ¿ â­Ç¦Y‰¶(¥ ª³Q$Õ™ââ"É‘*L²æŸ+Û>@·‹ -ô2¯9ÄÊ1BbaŠRøð%å ‹Ä(pýIÉ=­àÂB€ô@-pÑsóDŠFˆwiºZ‰±ød²d¶ ñt%5 ªhfR“ºH2ùšÔ¤,­bƒ@®ÖÉT³<éi¥-TªD‹@D=ÙÈ îBÙ—3ö>¯œ %©ù?±75¯ñW„ñ|Íß,_ò·4$øWø›Ã¬ùDþêŸ×ø‹.î’¿×”‚o)0¿‡d*É¥¿ü£Šyhà û´HŠàÚŸ¾Xç¥Tÿ!//½’ Ó”c rìÿ¡Ñ[Ì®°]R²Æ­ö°R舴Lò|a—•aãÑõ茊1yÑUã%Óถ«Ÿ±¬¾ãð7°p!)Æ¢ô¿°­b¡ãµGˆ/À¬²üÖv¨êåŠ.-+@5«i^–Fã½íö¾°ÄòY<ÞWo ­ ÊS¶&§ƒÒ+rÒÙ rZ^]A’JYffÁE@FˆW‘³€ÌÅ(ÀRC‚:öçÎoÌÅ84|þÈ¡ìX¬ë‡ÎŽ7ÄÆRQh™¸X;¼®V¥¦›jL•^‰Æ*ô@õ0ö¨, Õ:Ðíw溇šª¢ò†D^¢7½-heÅËb˜ù†WŹtÅYäbÌåŒp©Òºéö¤ä’šèc(sMYíüzJ§ˆœ'B4Y¤‰ žo•ÑÄb¬C2ng²‹t͘‹tÍÜÔœ¢t ¾•ÃZ†7üƒà±¶[ U*Õø*•¾©Àyí¾òu]³çâ÷oø¼ÇcE‡{ãT‰š?‘øG*÷uûÔI ÅU |Yí°E¯;ðõré]pr¼?7©¸©îm˜ACxÿÆïå»Èqñ‚©qƒ©ð¨>œ±ò£WÞ~«ºö޳e*$—wªMríEò­Ö¯×L%ÃÀý¢©ŒuÔMS‘âM…„'JŽÛ˜GåcQ±VîÊéþîªÜXTOš¥§b€5Þ³«5‡Z¯9²_F!ø$8ö+™·¡¤nŒ-߯˜ÕbŠ>Bˆõ,ÃS+›ä¸É•%]\c–AòéóÕtIAõ.fDý‘žÍòðXV ³I/ïËâFI‡°à¯zšÞ ²KÕ›Ó% „†òUQެ¡cü#^A>Ãýö³gM˜&üü5†LÒbýe#›¿±€Ú¤^I_¡JÖaHQK=×à¿·ôôKo|uÞWahé&²ô‚¯jÏC{‚>”üõ3/Ú…[7|cÔÁ•cÃßceøžìïÄ ÝŸßÓC)9ÎÏöæ‘nm ÙD—¢µ'L£#éN¶v¿Ñ¥–þEgÂ!JÃÑî£ó®y13>"É)‹"1gÂl%—ñOGWÀóxý½p¾Ý^»@ïÕ4^GÎÓM·j‡3†^qp…1¾ ¤–ÎÖ?ð`ÿøôû䎟½ý„ÀÙCöùi·œ?­ãL]ùĸg\ö®ƒl¹~¾~¼ÿ€&í¿~c#–C¿C4ûw›;y›2fç~ñÄû0)âšžº¦‡”€è%&ç—ez°hÛ¹¶Ý‡×Õ§™“½o€s{zJæ¿Sàk7ËÍ6÷¤,yÉG#Yº «ðh"X£ã÷ x~Ë*Â_/&øtÜù@ÀÿÌÿD° hÐ+zsó®j¿øëÍÞé1¦Üèï==³+=m6tH¯C n(~»ª¤$ÔÔ?üîßÍ™8, endstream endobj 38 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 40 0 obj <> stream xÚÍ]ã¶ñ½¿B}“3Oü(%ÈÃ¥íéS‚n€Ý<ðlíZ-ù$ùn7¿¾óAÊ”-ïí!)øA$g8œçËÉÇD&üdbUb‹J”U²9$ßß%oß«Df¢Êªäî!‘e"µ¨òänûŸôo;wë~µÖZ§ê›ÕÚ“þ½F×nj\5éé݌M׫_îþ™Uˆ<‡cp·¡¥·ïu"Ц@òk±6À"4%òÕ:/TúîÃÐíO#¶yúãJgiíú¡kqÁ¤›®ïë½ÃÃ<á˜ï,YËJH&ùý3°*‹tt¿6í#Žm:îj^tÓ1¸üi•ç©ÛŸ<°{ð;wþãJÙ‰ „Dl¼mÓÏ„ÂÐûLšvëb -‚O‡•*Ó«5¢ö ÀY™Ö#Â?#¸®ý¿Õ}G2¢TZH¾ ‡„5 wm-ð.túî”Ì.ÎÂ!"g¼p8m†iÿUÛ_8S]C\~CÓΰl:lÜȆ[öÝÈ£}ã©t~ƒãÏ0ö®yÜI&°oÚ:–° ?7ãŽá5Œ˜¾e"6p64cóÉk\+¸±«LÛúÑ͆}Ç[YiÊ+Íž¥‰•VÆÛƒÒê'”Õñ^Ó›I3ý…–Û…+Œm˜Õ¢ °uW‘uW…°Ú?«§ë‡Q&=Íäš‚’BŒç ¹ôA×R–BKøBÜ‘¾€éí̼¸Z“ñ×[žºÁ§õÆK|p³n38z­r¡,¸—&)De sW”ÀŠ(4¡¼ó(&V‘02™0î3%—ô$E´ ˆXQ–|Ÿe\ŽRé—¸iªôG¦ôGמƒÈ~ϯ&˜½=ÿ€‘¡Ì}\‚Á¦c¹ë§ G.<Ö­G©ŸŽ Ç@zósæ´o^küK¾j¬Ãn¼8* ˜tpd#¸Ð Þaxž'‘¼Ç4¹$ir…‘‡Íùx¶a4cönÝèüî°Ék".d´yx{h6}çúÞ­Àm?¼{çVQn^ñÄÈm8NHpämázBS+8Sû^A‹ùäDë"=£î– ó4£÷o½UáÀµûú~u;•Ó“ákH‰†Õ‹£êÂn–6#¯è–Ÿq’GÂlé¡î݇=Í-ÇnX%ðòGÆñRe¢ðŽóDâÒkcqeþ…lTf•°!4í0ÖÎï#=„tÏïëÇÓޱ놫€`8s|s7©Õu qËGc®>…ì+hã¥ÅHnn„í\  †GŸ8nƒKP·9ƒøy1@qÜfŒïØýi {Vè2ŠÔÿ¸K>&BWeò9‘i‹ú’ÂÊä¨LÑQ~aŸü+ù‰‹›ÓaÄ—ŠK…p{P9L\ƒù« H iç8¸­0ÃÀB†´¨*Âù÷Ÿ5&^|T³  …U›Éwrá o.O (eÈkÔÒm(ÔâÈÊYŽsCyÜù.š+¥*¸Ëb¦TcQ¼/(uÚ9Ki<—Z/[ˆBAfĆ}ŸfÓëÙ\7(‰6sIæJÁû1"Ÿ’=>®ÂWWÂf“,çm¨(*ãT8æRáüeEV+ª4t×_PTØöQÔómEYLzç¯ GÂÚ}/§£Ö¢6@>¡¯²Ñy2oH›EQ|QBó* µÛuÁ’_ 9 PÆÎœUð)ÄJP/›Éé¼RÝZ‹ÁK„|®y…6`ž"P³ÇRà¹k]j‘©Þ ‘2¤]Z|Yø•ßE 7¢ßVÙà“ÿ„ÞíÂmw“”ìÏûÌR”N ò)È#¾%g\¨Y±e,°bò™Ç|@6&@½Æ ;¬Õ>ÿN«}…ÑÚ¯0Ú\ P^,,Øh!Ò†…ŒŠÌµQd~·V¡µÂÄ€–vñ FKÛÐÄÍKF«ÉfË?ƒÍšÈfŸÛð›ÍoÚlpÞs>.ZÅÙj¿Yt˹¡ÛãÌ-Êá¸*ƒo¨jaÀõ‰¾¨ â<êµÒÎ{ò)7¥Õy&zY "Æb&Š™z‹O›ú8òF*µ–J¬ÇJäô¸§q•j×"{Ò`”/ôTç {úv¹ç3õbnÐX i^蕆®ë“PÊÅ!ָž &àP†Þí¼ — 8„Ô¹IÚPÆà Sƒw<öݱoÜXûj;+¸'6éKjH-¦V¤ñ­9ø:þP[™FTÕÜË€é0:*J-Ò÷«RsShaé‚-¼DãûÀ€Ïp¬Åx‰êør£™™ÁœëxÂñýÙ6²` uøP¦\¦ûîqÝ£²¨øãBáÓ:£…>­ñµ,¹¯Z;ÃGõb•écÏ-ÚD°Æe¬ ÍcË'Lw„-¢ë–2Buª„|©Ù ÈXmËòlÕ•o;ð¨fèBŸ†ÎîmާéÍÁ®m³åAKMxÀqðüt½™S­ÂÅ0}17šM7½gåÙs_ ÖI}Zû£ÎÅfq.6_[¶¾P‡ÞlÃóŽ¥/¶çe¨¹Y†þAíãv3,Ѳ¯-˜c–ÅÆö1‡ÞsSýV¡#ÿzvæÎ±ŠØÁ«SÚ?%¥Ëk¿§g~ŽTÔKFì×nc$2!›P&)…ïÎ"Ò ÿ°ÄW‡É߬{]à\\SNÀfÙú> 5’ãw°ØH¾zV¾‘|ëÏ ‚d³£tªøåTl]>\¥®Û=*»xJù?ªÔùŸ-éÿÙRá¯1unáq ¤Þ ØYˆŽ1¼û;ÿÍØõƒš¥¿¼®ûÉK¶û„|ë-ºKtk,M•GÇ¡KËðçiåK¬ÝŒ£¡×SåÝYÆiR9mаvþßÃ{Ž}wðè»@ñSSöÞ±a[ôÿ²R—¸eýZúÏðà~E,ÐI’HÚ5oU)!Õh*Î0à<£_ÝùÁÙ°p†ÌÀ®ßð Ü*ŽñæfXWO¯¼hI3…ï}¿¡,øé/ÿ÷¡ endstream endobj 41 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 43 0 obj <> stream xÚ½Ërä¸íž¯Ð)QWMs$’zprÚÌ>*Ù’§rˆs %ÚÖŽ,õJêqæïDuË^ﶺªI âME?Gi”À/ ¹¥‰ª§è/7Ñûïe”&Â$&º¹Ò2J•0YtSÿ'þøhO“G¥T,?ŽZëøÛfœlW9„êøþÜUSÓwãá¿7‹´ÌE–Á1¸;ó ÷ß«(ÕBéÙ™â¨Aéɤ(Ç,—ñ7wcßž'd\d1ðuÝA%1àj„é¸ê‡ÁµÏcÞ¡èItLH‰ë7#lIŠø¾Gñ“2žA÷pn-CÿqEìì0G ŽxTÆÏž„±¶£}µ»MRÝ1Ø2pÕ Ÿœσ#Ôylº‚³ elçûâUPx%RÒû—C–Ŷ={˸¿']ÓN0éÄšuDàX9eh×ÂUDGiDFª™*ÕQ.L¡‘*9Ф"פDÔÿ¿˜N‡Ü2‘÷™î6‘éŽAÒÏ"gHw¸¢,}›$Éá(¥ŒÚNÎr1¹J ¬ŸíÆüˆ.Ý<<âÁÓˆbúV±ë'š³äø_Bêl&{ÕÀ¯ìé~]Óbêy|dZ’Y ™7¨ ÇD]gÝ! a© ëwWžD Ÿk§«_­ H\9g³ÁäÙ'Ìà¾*‡‹ Œõ·öW¹q„2óâ¼êªò˜e)'7ÀÍ.ÂÝ‚!‹„§n/|å.li_vBy¸Îçþ¥ˆ?òÐB®q5 €ÿ{s7Øá+!'ìîî)1®ææe$,]Éìç9ðt†ÉTó•‘^M© €Amñ¢vÇ뫬忇ÃöMfžŒÜM  ²#ÏP}8.¨M~ÄMÛä%‹dI!ë ö­/\Y.-Ò.//ÂÒ…•s¶ïns}]Bî2Õ*„ïU6°ãÞC¡,D.ßðÊ)ƒüÓîÓ^oyߤ¯¿oÊð}³#/ÌÒ·?>í>[Ì*è —T¨ì/—åõþ+Ä O+E¦.^.¿ÅÆb÷ÛAF}VÊ–¡FëG×Õ°þ4;Dì1_´³ ”ÞÓÑ×%úéë C£ú^ŽwÐÍG`žàÇ‘0½U¤¾² €Ø*2»ü"ùí[o$ZK¨¤Œƒ@æJÝî¸ÀžF×R)eXßùº°î€Cý9Ô#D1« é‹NR_Ïp&é‰ãÚkì…›^Mó²õÔµñè±ýÔ¹ÚUØ áê4|¤¢@ˆŠ¯hƒŒOÐH€ Ú ÷èféFžy»‡¨ # (hûÒLHóB{ôî"È® ´;vn±›‡®ç¯FšJc¸7¨Ã¯v;ÜcÏA|®–Á—B|S/¼Õ±ã¢ðZJ“‰Â¼nEƒˆ(v (’¢ys¥àİ“ä "Šß¥Rø;³"þ°›î•Ùæfô-T¾ªÔ\¡:~A§*ÈjÈp¶zMËñ¼¼q¼cÛ‰f ÏM‹OÂÄï!ÐnO¿ó½±”Bæ×ÚVm{æô©&þSQ2÷’‰ÜkRèB³Çú “ ½éYøëcä—^& }´RP´<ëïn¢þáÿ2f"í endstream endobj 44 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 46 0 obj <> stream xÚÅkoãÆñ{?RÀ‘Gî._ôCrÉ¡W$èq¹| )ÚbM‘ IÙçþúÎkÉ•Dù\´haÀÜÇììì¼gäýáÅ^±—)/K‹0/¼jï}{ã½ý ¼8 ‹¨ðnî¼8÷b‰w³ýÍ¿+S=l­µ¯ÞmcŒÿ]3NeWÕ¸jü»cWMMß›ßoþꕆI×àé”–Þ~Ð^lBmRDD`€E`*Œ£M¤ÊÿþXµÍ¶.;@%þÖ^Äh\*#/ˆ‹0f7; EéÌ=Óù<Íš‘¿%~r޲±¯§¡©ÞÀ$Iýräífâͱœšñs›ZŽOö28Tv÷­ÅÞÕËŽ©ÔÞäÆ[±ò?vöœ%`ìï*óŸð_9ðóðA:Œ™í‡²Â½‡ t_¿AN+„OýšÇÛiêj– Ñ„Âpë[GRŸÆŒÌ]q§Y˜i/Ð*Ì2º|»Âî<ÌbêŸihU‰—…:§Å˜¿¿ñþðB]äÞ“§¢ _yµ÷œÈì´õ~ö~bÕsi±gâ(,„¸b@ÒiXd†H6¡*8Œ³Sía‘jV3z• Æó÷rd)ám9•k‘¥aþ²õWxLî«rD‹yQ”ÉׯÉÎE ï·ÓPVi;¾³êj"CA ýž×ërÖmX­®á³ÒEx"ð_7¹Æ ¢R°•]l·<Æ35°œ¶_> Fši Ã®O»r²#Áâ 7H´SÚS‡¡?Àð H<.u ]—ÿ¬åþ§]-ç#(ËeLáç§IB>Ç8Ò‘B Öë/åþÐÊ™[| ±-󫞌ãq &¼ŒÖç öu‰Þòì¾îj‹ÑÕºÜoëGŠÈí(úKªÛþ>Ð,ˆ]…qõþ—®m,«YÿivÔCÝ’+ nË‘É9 é0›“/z½sú„Iç§&îxvå¾¼Xm,™ó;ºf§ `)è×ù\zfŽ©˜#í4ì‡zž¡+8Ξ)ïÇiFeµ g"ÓÈßÏ›M‡žÁúxD+Îü8¹üO­É#Kx4bìK«°Ï8î¿«‡ò¶­‘Î<ó¿«ùÈ_z¾ªC~Üíû©§±ölž)¡ëzFòÙWQ¤ ˆÒÉûæÑJöH.yì(i.|…Íi·’GÉâjÉùNE )àiÎw7ûõÂuŒ zöX+î( #›ö` ÝÈ®ï!,&\ËìãÔ`Ð…Ya3û˜3û÷ëÈn[dOaþ= Þ™WäùzÉóu–ú•¤ÙŒ FNN«2‰Ü/[ œðŸ'ƒ˜àÌ“”åxâ2ÿDzW7±eçH' eÓ5òsK“|y2FhP¨_Qÿ©ôÈ%—Qyrí ÏÈ?ŒÑÇ­=ÛóQÁaÀIu÷åÐUçäÃ\[–z)"xÖ˜ÌÚ‡-\`ˆþa–Z¦ÇðöL“Ø>º&“É¥ˆ‰„—ÍÂË|©uÙòFE6ãw> ÙÃáSpÁ `ÙöèÎq8ÇÄ‹×m›}Ý¡·æ§*ñ¿AaÆzz0å‡;â< ÌHÉ{ IVvåMxgߌ#GØ~Ü$ ]í±&>D9g¬…ÍXü=ÏßÏÆÅóšÁÜå@K/Õ`~R Zñâà*§ñ¼ã'”ôß=KœÖ¢4ÚѾÑNÎÂa2‡×\/Hü€Eå¤<ügŒ×e2¾[MäbL4ƒ8Óâ¥"õ¢FM_¬QálµŠ."l%`‘ ¨™®•©rÌDQ¨õKeªþÿU©æ¬J5N•úµ¢ ±;U^+RÍX¤&_¹Ç©æê[L˜Û·¬WŸI†*PE¥Y¨9“J—¾ÔÍá!ùÔ4·ïI_)E½Cì8IÅJV9°È¸ùÓ>ðêºw¥Ë神Aϼ«P-Ð%*§ …}-H*ž0ÂÌ#—FxN­„û,¡ÖX/‹ÖÅðû™\üÌHÁ-–öœ|áð¬ËÔTÄðƒR§E—Ü¢ƒ½F*‘Óòxg«Û¢»xªÓ®Ë–v„ ØÖ¤:B[¨“kyÖÞ[p'±CϱCÛÀž”u„j.ëðf,ë.CòRâA&F%Þiëu‚æÉ&˜`K;yÁœ\kí”vxj †¥¤–Ï‚ÛnJ—K‡{K·– F”æ6 T’–muÄ¢†‹.Ë6·×K³[le =@’ø´Á!µ tüZ®Hm×Åhs×@F?0›ÊÚvåD]•¨h;ÖáíH–/\ …*±íú§$¾‘ÑšoÙ¶ ŽÉÅøvßTC_CI湸œ q£:˜…)o®Õ[$ 2,9î”1« •îQ’¥ hŸêÃÈÛ”ø)›øá¹ö¾ši·?[ïê'8o…ÙüV7ã9Q—ÔKg"±Ù@B]©Ç¦?Žm¸'ŽR„\ì•ß½s…†¿é\šŽ° ~¥6Ko×Äòû•ó#Ðu†hàWJ3´%öOúê“p endstream endobj 47 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 49 0 obj <> stream xÚÍZKsÛ6¾÷WèV*!Ä‹ “É¡mšN{j'¾9ž)#щtH*¶ÿ}wñ A ”¬ÄÉd2c ¯ûÂîb‘Ù§ÅðΛ©$#i6[ng¿^Ì^¼e3“,Îf×3šÎ('™œ]¬.£ßÖùmW4óç©&PóHÉ|8¡FrFàY”7e·Þ]¹4ím‘WH¶ˆ£úÚt™¹Ð1×fÄcZ¥]·k5OØS™žÛ¼lîÊÖn¹ª¨kêrµØ”Õǹ”Q~£GS‡YV7fm^ `ÈË‹·™g±ÏÔG;Á·Ibfõ½p¼¥±· Šüvž²¨SbÊqœÒh“w0ë9Š—ºÞØ—:´&Ìb€‰A¨«ÒnMX¡³VÖf'V$5·JÔ¬xìâÆ ­‰‹Ì ‹4Ê7°¶Ê»ò³&fó0Oy„\¦™1œÔ®ë¦+Úδý ÔÀŽ…Ùã¡‹­Uekæ"køíÜ6£ƒkzÖ£‘òÐzxꬡõà×£Z-èlSŒí†BƒQPÏXt·.7v¡~lêêÆp}€ëq J Rs@³À¢m~_nQ»íy828 äýY™UcŒ×Å5°Öâ$‡í³)o|`à€Lk(û*äl|¢Ñ‰¦‡­Ò~=W…>5·Ýfkø‘£š?kÓJ»öX±»¹ùÏçïfÎ/ Äǵ'œ'©æäï¦îênÎiôp ‹ã¨°KäžOP$ázŪÞ}Ø#æX<çI’õ²~È`2&jøu2Ž*mÐñZßà€É1pB£0ìª[Pñ‹~ØÒJ}vxvèI|J y¦¼÷]SÞƒÄÞâÓ³U] :Æ$@cÜÓxSTEkùê³l"qsO ÅýmS´-äöÆ’ mR•¦ti èva´¶ ’(õ”Ú=âÓ‰ÓcNÉÌÙ„ðp@gZ Ò »©n脉ÑIý*9¡bAÝW1gÜ©÷F»mô ‣r[.›:oÝ<´fŸZ8oŒeäh ´úr¿›²Å[¸$öq`*ÞŠÁuµ­8:ÿuóÄ ê_½°°)AÍÚº¼¬ôÅû:·ÊI)Ù“’ÁÃÌ_òèsÊ8W€m§·]ݘœ.qžbiÙsÓeèƒlòP™W-&÷0…5N IÜÝ´…ô½ ƒr.è2˜íÅO;ÓÔa\Aü¬à‘‡ö*x±ìi ZÇ(ËÏ÷3a»ãŒ0u"1»SGãHB„ð×Åü$™6ávèâF’I4„%šßÚ4Ç÷>œG¿އQPŠ<áx¼Dv &˜'¨TEåµ¥´²#ÜŒ$Æô’La¶­¹_Q –øçu0]aRöddЧåyY^]þwõúu2:””ž÷£*¨E˜JO{ñ®-û<Ú]ÐÖ…ÇO{cìÄ);#eùÖ‡Œ=d™@-~‰ŠûÉî)e*yˆŒ‘Ïvvë¼3¿´!3•ºüêjó]æ›ån“wv‚)Áw•µE¬£Šç±„}Rñ_®³tH2Êà„êgö ý¹JH<ªQN¤üþ ŸHHÜ"°D}}˜ÉŽÈ î9aÐøÌËÍë×ô§áü'•}”>e¶KýçDŠ@æÃ'RHÐ)$ä{ÅF}•7#}U kT.î µžïz`?žLÚRÇÕY"yJ39ZaÇý¨—®Ø×žÚð Ip»WP„}Ê¥Éo…WžtrJz9Ù¢6–ƒm>Í͵fX&&ìét„åJ éÎI3uèWäž‚ tqOná,?}‰:™r/"ŠêĆ~/QîùE±=³Ç…ûêÔÓëÑ2Úüíi“¸•ð”öXe²o¡LЀ~ø9çlNUëü÷Ï©ÒßÉ{Ä~=êÝ­qOË ê-ÁÛƒwk€ÏPuÇÁm‘·»Æ6J»óÌÞ9“Ñ»¢“wéˆ[ˆ„¹äbW χH²>D‡"+õ’¥7#Úû'å+[ÿæqf †ÞÃÐM|9T&¨—OB½'† Me_cRÓ•_ÏA„K` ­î¨Q¡O¶Ó‘ûÑøE'ø ®ø¯[âðuëe_ìH‰)üþb…Äî¼æÇóÏæÿÀÍÖ)ãÍ# í9›z ³ ï%ÝF¶÷£}„ÀWoW_HE’Çó·ýù3鎣ß/fÿüô?§D˜¸ endstream endobj 50 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 52 0 obj <> stream xÚÕY[oã¸~ï¯ð[åŘ+Þ¥¦À´ÛYlQô6yKTk+¶¶¶”•äÉL}ÏáE”lÊN¦ÓE,’‡çÎï0‹_t‘Â]h¶Ð*'Y¾X¿»]|ûž-hJò4_Ü>.h¶ œärq»¹K~¿+žú²]®8ç ûn¹B$ßW]_Ôë©"y<Öë¾jênùpûÇ…`ŠH ÇàîÌV"Èo%àLf&þa&¾}/Gçr’r·¯sÓc±$Ñ~ú×ö¤ŒdÂQ>ìš¶/»ÞÊùTTísÕ•v´™HûÓrÅtRöK¦’ç%Ë’²¬q†%å¾<À7ÌöÝYÕö·ß9VaWc÷¬÷ÇÌÓ½µŠJMÔbE3¢äKÔüôZ5ÿÔÔÛÿ;-?¾VËwQ¼²-¶¥=¿Á±#ZÊ ëØb0‚Ó ­+è+(gvj‘„]'V N1Òg¥S ©$¹Ñá>¥:bÊÐhVͪîÝ šŽ–°“Ä.éÛ¢îžPd$£nÝÛˆ‰WšÅA$N¨õÓ±ó( ®ºvž[vs“F¤šP¿â ˜LhgL1uŒ8sŒvޙָúÙ­3NíOÑöëPômõÉ~­›^ûõq_ôå†@¥Ò*ùK¿[Ù Í@M:¶FiâæÍIìO"èR­›ýñP»@³ð©ÎÖ«išSãF1u'B!þ^öÇ9j®hRìeĶ)H®Ñ¸évÉùùhçó¡l…¾Ob‘ª)>7Íñ§}L..×nÑýÒëÌèBY•SHö~5òÃ…ŒP¾\IÅœ&ZŽ5‘ómÜ 9ìf`Šc®‰«"S"½ž,ƒ)NÙªÞZúSÛ€2‡ÎÎV¥»c±ß¶Ä¾±ÄÁŽìO â"ÙŠ‹Ç(HUuc²Ñ"Þº±å·¨0|„†ðÙïñÀ£0Äaܵ¸uØQõF%Ë¥èñKÚ¸ô Ž pìlbò$S:y×Íp.~¸îWœ¦.ô)MºÏ‡C ¯1¥¨r)#ßÂhÈ[ø®:û[ì»æ„ Z“ëäý2×´À«=4­ÉV*ëÉev&icË_ÝVl›ºØ[²•Èÿ*Û9g@ë,Éma“ÀäIóh Çî64žÒ•{·Ê¨4äO0à¹øS¾³¡bÊ(ÊÓ–‘Ätî´ƒ®úÆ®3ò£ö®Ðí0Õ¶Zê3šÕÍyò\õ»á»ÅXóxÀ s§´v…Ñ=> š IJXã>ÇÌq¤Iù $Ö¹jÆ`ʇ |Ü;­ÈfÞ•ýýÉzÄKÉÄÜØSáаÂÖ Lgj"ÌØ|±%&_¿¹&Ò_cU¤eDø¼¨71”H_Ž2È}]5 .*'à¾1²¯ L¶H†Ò H›mzW=Üýü+Óp¦?Òƒ€l\ìSl¼ÈPXòø¡"j@ø‚†‹^p…BŸK†Ö\ Ý—‰6‘Œ&¿EÉäË$“Éó®ÚcM£èr·³³cŒ7G‰œK¢ò ~̉òˆõ&&8GÀ1Gœhå¦!†Už&nz'©«à¾Ô!i¸äŠI€Ä¸¨±Â¯œOâÁÕI1)Á#èD…+Á")OýP\ñý±Ÿ®©j¸66&NaÕÈ~¬›ÃÓ±7ajJ«!™Lýh2®®J8Ú”nm ÔÀËÜG8,êó D2˜%@4-T•ªõ8ÿPÕÕÁœ Ì%è¢ø+c¯¿¶MßôKN“Ï€8TªH O€—…Aß|3E_ƒ9v?‡ê©Ì¬¯Û湋%L†'mš³(;ž¬]ûŠ|ÎPÈp¨c8èá*³°Ü 툈ŒäôLÄ8;AC†ŠîŸ3ìnö­&õ$Š'àsjo‚ç²ÚîúX*ƒEïÞ8ô»+Ú¨¼špŸ’èÜ«ÍC/mãî—oã]Ôµ,Çî»v{DäÁÛw‘~43ï-!r¿N;:·ùàÅh'*O]jnk!Ó8ÚÒ¢ \úAá݈¿¶*Â2Û"Éf!ýsØ¥]ÙŽT‘#ÓáÈmYÜ-éùy8©TŸž uUãú-[ÜÑVžF ¬ù¿ö£Á¥z Iš]ò”Ò Ê©£8›±NX}O€…ÌÁBæQ%¬r};£ÁOœ ï'\að`ØBg€(£Ã‰‡jÝ6ªí,›ñÉ#?)£ñž÷ÐÿÊc— ®È˜œ+¸"Ô‘—=ó¸çå_ûÃPúë;P{sßSÁZo$ub$Ë¡äÉ6G8 ÷ö1±ðíÒv5<±(ÄÎrç܋ܷfî2·<…‹0Ã’øwhpÊ÷]Ìp\ໃ«ýÑë.êu™÷pùA4x/'þêZ;ÎÓW.f;}±¦+¼‹&a‡8Qå“hÃa·j¸Ê _côíìpúë1…ñ×§0O']ø$’4l ¤†KuÔ÷ ¼³u¦ï[IëqG¬3e#Oåâ"¿ÞB¤Q ;]1MMâùº=m›D•4ü÷$¼MÖQ/ÂRz½xLOv`ãnÔÀi¯ºòr’Qˆ7Æ®$Ù+àÃ;ÇØÅËzñ ªû×§¯(îL›× ¨ÐÀ/HL$Ú¾¿L3%Çë'~™GMM5‘¼s¾Ÿ1™ê²ßy*ƒ­¯úýË]–…&¹Šf \ cíû¹V$T§ô=NëÿÕxá ˆÒÿù%“_°Aº’¸ húÊ>ãæ†^Ñ4~29 úÒ™k¶Æÿ&žk¶®ÞA§}Ň'‹×>— BQxóŒnø !8y(‹îغAåv`Ò`åçL&Ê2b ,üÃ+ß."œ ÌGæ±Þ”(O]n"œ„ªºðN„ÿŸ2íû‰ìÃSüƒkžyšÛÆ/Ä=þ5"¾ ÀsFzùU¤™ÁÆÔnûÕ¿”è:ô endstream endobj 53 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 55 0 obj <> stream xÚSMoÔ0½ó+|t¤&µ'N@=ðU T@Ë 8¸‰·”MÛéÒÏŒítX$´{ß<ÏÇ›òƒpÂàljDÕmÑ´¤Û‘Wry-gEËZ²ÙÞ^mE6ýWúú^ï½±Y^–%ϳ\JIß Îë©3ˆJº]¦Îóä²ï›÷DŠº¨*(ƒ¯Û]^Ë“ô¹äª¨á€D`}c\%buÚ‡(ê5Ñ0ùÄàì„"æˆoõäö³3gRU¢hxâ½HñÓ‘sUuIr˜›Ç¹ßmÏÕã¼Pò?ë%ÚÕ;S$àmb\€¨BQzJÎhŸÔuð—µô6Ë!j|&jzÈDC™0Ò¤@±sºSDŸÂ½ö:ÞvÚÛág¼k›êuzì–Q{Ó¡Ó¼)ã#¤²‡Á™‹èƒ/'­¢ηZ–âø¢›Çe7%~h! ´²WhBÖò°ÁÑ1\ÉCCŸ_,¦V’>d5§z\Ì™L¡p³øè%ð[A÷ÐdCgP EÖÔÏx®£Ð=ð*ÞŸ­é#K»ˆéxLæ0>&dç G‡cEÌê»»õ®­ÕØÁcÖ”´ÈòZp4]ˆ “[ࣨ»ÁÄ.Ãhìt%;³›-”’JÑÁÅS£îYUS=ŒúvÄýª:Œ&UûŽÌh ÀŽS"§„%W<Œ„Œ_nnbôoá0{,ÞPVbúõõÔGtøw÷¸û$Tó$T0ÖX\4ÏVÛè—ÁÅðÖšÕ)o7äÓ³_â Ce endstream endobj 56 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 58 0 obj <> stream xÚ­YK㸾çWø(c­Dê¹9%ƒd‚, äÉA¶å61–䥤éžýõ©%ʲh`àƒÈb±X,«¾¢7¿oâM¿x“«Mž•aQnÍæ¯O›_>«M…eTnžN›¸ØÄ:,ÓÍÓñ¿ÁÇsuj»Ýi­ýëv—$IðϭʃÊf0]kÚg­.Ï5ùé·ÿ{úû&Qq#GDûås¶‰óPÅ).´–]º(âÓÛ]š)X@G7 äÉíK­£ÍN'a’˜; F™?ŸúGóÝklçj&C³ÅÙC'‹”¾iÊ<Ô…ìéÛ-Ê0Mdøp{°œ¬Õ”zæÞp®^l8‹ýØp£;ñ÷hú¡jµè¶* ¾oUÐiš4Ø©( KµÙÁ©Å|jn7Jã>à› ·±ÜͤSóvYS˜`zhLkšêâ‘ÇÁé dâ]A‘ývm'ˆôž¥÷w̧ã8TÙ›æËµ Q§¿Â*°éƒùÅI}äEö¨ÅÙ¡Smìk²I´™¥o’/-{)sCã£|X]ñâ$ø‡ÙÛÊþØ:øàfØZæ\ßrzš^Ya­PÃïÛ4 *s©ö—úWÙoâí·Àk¶‹ ´ * [Ìï¹ ³ô ³¥a¤dx×ÔUÛ³ ‡ykë¥wp³œ>qùó?šw/¯~âê9Þ_}§²0ƒ;¢T¨‰º‡£R*]œ¡R@~£ˆzîðD_°“°!uºKÔ™îs'°Fßmë#^¦¨@_\ïT•Qé÷2ê7oüU%ùZ7Þ óSÿFøÚjóÓŬ-w+!ËÅ)\[8«¡ÂV‰ "ÁaèD–x?E«ê™Eå·1 ù.å"6Û›eh¼´ãA§å èàî"_£Ëˆ@¾Õ„µÝ°Þ…Kv™Kv”:•ìÒbýZ5׋¤Æ—sÝ®‚4±]m7ÔÆ%=áÈMºzF1@ê;†Ñ’ÚØ7 ¬ æÆ ¾ŸŒâ½œ’lê"?ÄGZõ«ÃC…I}×T¯ äê0Ë×àÓo_·W§‰CÜ|蚦ká¶u$•±…Î…ãäìŽFKq$ȧš3†{ C6«·’b׃‡Ÿm7^{ôÔ8—§ édñ–¨ Y_¹E©.uÙ Ÿ~c‚¿õ”!"ñuÜ?ØâÛ=ESHïùÛš¦+¼Œ"+2¬a¡Õ5d^$÷½yn]FËÂD߃½à _ƒçº­¥ã¼°1ÛUÖ’»þèñ`ÑK) 04lî¦ÁÿÕYÜä[Øè;‘œzg>ºÄpL]Ü´pEÿ½Œ1_ž?ßEW´Î]tõHϸåήWRdWÃÇ–„Ò f‹úA çø¯“Õ>” ,:oÃÏÒüßµ¸ÅÒŽ’Gtâ0•]³í¤Z€û”-¡¡Þœ“µžÔï‡îzåÚçÈ#ÔÊB§ÑJ&ÁAÑCVmÄ2âžCõ28éz©õƒÐõŠ9SÁäQ# v–‘F‰ùjÐ䎿ޅK\8ƒèßµ"{ºy\ ©,…è6°àåd‚ åŲ"{÷0¶=£À8è»Ë(Ñ6cÿÀï©éúCsvDd$1-$ Q@ðC”'ª~­ãÀÈ[EÁb¢ŽgNyc׫^温!"t9Í?,‹ñ„©ÂD½Ò—åb/¥ |m-ùŠÁ$’šª•J{hž^ò Wb8&0õýaÆÉv²HÅŸÛÓdÄ™ãÃÊâüÄítœ‰Ÿ`;÷,Fਔ»»÷XÞ7âåûÆDÎÈš_dâ\pZ>eÿy!éøHd™×{eÈqZä‹h=;Ò¡€ $„$V*O<Eò œÓg†€@"Lž# *Þ#q“†ÀÀVÒ‹¡JH{>c&ÛCå\3T–ÕV»éü’‹Ë*µXNÿñåo®ÆMr@…§_RòÅÞ6üzŠÝþÜ—#·åUˆ;`Knï¶XD ¥»•}÷e‰8Oüp‹€°ÇèI6N? Šœ:-ÐÍñcG£)HüÂIÎËãùgp¾%‰Šiªë€ñÐA™vä"§ W -¦ÓÜYŒÅ9ù. `Çsè½Ð+eÏs)æ…ëc•ê"`p ¾³ ‰ÃFÒÏ£Û¬`åRŽåP¬ ^w¹„dfR‹äÑäÀQpqÏe*@Kƒ»yX’ƒçÎÖ¸¹L©g ’ €Í9Ä‘ë»W`bå™F&íÅ|£#»üp÷¶±ØÀ1nq™[¿š^XaR»Ž÷¼H ”5å ¤YuèÈAîRUN÷ —–«I®U0bÀŒvi³ei‡Öâ&´Oœ qôÃtÔV4m箃r1b85gÜâ[HOÁŽž6yœBGM»ó  n:™ðëòCÉ…CN2÷€‡QÎÿ„1ÿð…3+Êî¾ûÇe« ¹Ý©BŽ¿ïù4JÕ{$I%J]î3Ð¥€é-çj…þp @&ÿ?¤ó ™WžàÓ¾åñ{å ¥ÿ ã{1®_a€=m?Ú *¡ŸªŒá)~ëæ:8Ø)"ây‹qòŒãx¨sçÊÌ8öK,©Ë´]Ãp4ãÓ¶fïá;ÙÉâ^yõ] ™|Ë/­Àt$¿”XŠ»å–Ó+"5[–H¹=cäÁì.‹ù¨Ö5„«élM`FcU¨˜/—ª[ÓV÷LŠÛ #z™ûË'+= “Ý‚÷ž£ŸlBïØôþHB‰A‹×Ĭp5ÐϕȢü…Œ¿fJ<á}µ7ã¼AÖ\mdÊéTÏH94Çe¿ ¢??U«BãŠηÒ{+[I®©~Yž`Â¥Š•"îåÔ ¦õŠ>Ž.Ÿž6ÿúÓÿJÊ endstream endobj 59 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 61 0 obj <> stream xÚ½ËrãÆñž¯àt-Ƙ^ÞÚCâxS›JÊvE·•IØ€ €–•¯O÷t0$‡eoR[µ˜gwO¿»©Õ/+¹JàŸ\åj•g¥(ÊÕf·úËÕêÛj%Q&åêên%‹•Ô¢LWWõçèû‡êqj†u¬µŽôwëØý´VyT S;µ}×v÷´[mïû¡vãúæêï+£¤€‰#¥]ûö£^I#´ÉQÌGb´({N µŽÓLEÛ®&ÈyM 6ÛýHÔà¤éÖ:‰¦¡ok†î?#YŲ’à^!“öO—ìJGß ?傞®:Z½]ǪˆFÝ\'ÒtMM{mÇË-,ëf` ´ødYµ†ËÏ£XÇ…,£ëBEýÀ$—ÉZ¢”̲Þ”ŠDñv¼kªnd2‰fà×;X(Ë0¼k’ÔÀ -$ ôºÐ–ø­ðc<äéë=§ÕHWH0°€ÄШGè¿âC^lØÔì^˧Oqêè®gäMµY«,z 0u»kºξ,¡7eöMcóX ÕÔlŸ×pÙ ·›c“—ÑÐ߆®‘cEU÷UÛMúý´m›aæ¥2GÚNE£´Ez±hê–„ÐáÐÜò tŠÆ-Þ ér¬t!ŠÜ—ÜTVé k­ah)I_žäѧФ ßðP‘ jW1ãL}[1'–¥éQiºÐˆ @£'ðË샥NDrðàqªÓX)å:÷x7ç§Ã·nÇ©ê6ÍHÓ©ç¯Å†ç`4Ð5Ï»£cüä]–±£€åïùãKæÿho‡jxöuˆ}HóÛ RE:·ŸÚÎÎÐ${\ÿRm7û-(+/#>»îx‰æ;ÍÎ_-¬_Å Ö¯âk·òíŠ>‹n)£¶ãÈäºjâC¿®Á «í¾O=k5 9$2êú‰m@kû쌾dM0˜ÙÔó޵Öå„bæØ­¾Ä 23ÅB$îi)“v«ä‰9 [§ŠÞ¢Ñ ro€µµ›â×3äÅ0TxùÙ™Œôu-×Bk§k»j ùRU ã|-¼+MÒèÓ§èè|Ò]u®D’ñí6½Ú% L³fq"OœöÙŒÐУè`R‘: _8!W+D–ù,¶üTà™w³^å½q@ê «žèª ëKz™àßS¸šrÕùçöæó—›:‡ì’]/YÖ!² ³ÛËq}¹t¯àjïB˜J¡¢i€Œà±ƒO ÷ödÈÁå w®×ÌÖ‘¾c3Ñ ùe_m9í*/, ?:ÓÑš¡Gö#ÆÇ§vlÞ¡ÿãšèˆÍù2C€qÛ!ØÚ5 Åúsܪ†ûý­\cÈpTž‰Ü=b×Ló(”º›d1Ÿº#ÙQµÔÝ1%„—Ÿ‘Ÿ |RÙ®K%çŒÌ&Ö€6Ρ¢ÆÇ”9©KK1¢ízˆõ´´ÝÚ—ȹ٠u„ûšÍf? Mý. dLÅg!^×b¾ã=hh¦ý`SK©¢ä=æP xaS-©¹`-(Û©féh§ï0’àrWȉJå¥q°ºä®’]&®rýCޝøœË ÑþÄ@»žXÎŒ§~yaS˜G‹à/ ýpÅ9Ë™9XŽÊ÷¡Œ'–Æ`åå=? ýÑ bâ3° *ʉrc8ŸG€Æk»ò:i¶È¿›€7"uL@Ó´a=2æâÐ?… ¡ÛÖ>4}´M¿Ýïº@ˆ…:X÷ûÛmóÍ7!¨i±·A*@¢Zª^Ò ˆ6F¨£êg #“ìVÎ8ó—òÀÕ=õí ~¾¹€ y²P¹9LJì˜Ì0<#—³gcØïý‹êX5Áã|HBŠpšSë’h¹4i^ðù«M§˜-×JËÓI_¶2,¸”zÅÊÞAü¯L½hd¥A)~õ|yéð†<Ñ(í•êÊKs13JmÿÈðr4<œÚ~3Ï”û1Žsq¿í»{ü2—&ú¡:¸¸X,ßí5”ö=NÁì·õ©óçÈNÝžLèžlg»éè·¾„‘ìê§ /ˆ^šÇÁ¶ZºQ¶¯=¶Ôa·í WÂLJ¡³¯hË¥n 7a”¾¹Ã˜œé0–ž*Ó¥yššŒ¦¸4ËôÕPûûí×ãð¹÷_øxyq5œ¦a¼ÍQ\šží¼Rgå¶½|µÌ9ëÆqA)ÕHcJúäñßAhû³÷]?ìlsÓÆ$ú×cµáãô#‚Ð2¨EîÌÝ®Ï*¿kÊ¿lÿpµúùOÿÝ×, endstream endobj 62 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 64 0 obj <> stream xÚÍYK“ã¶¾çWèfʵ‚ñ&iלÇV%—8ÉÜfæS‰‰DŽIjÇ“_ŸÁôØõz+µU;Ä«ÑýõZü²` ÿØ"ç‹\—¤(Õ~ñÇ»Åwø‚QRÒrq÷´`Å‚ RªÅÝú>ûÓÖ/ƒ0UÒË)¤ÐÓßšB>!’}vD”¸È¢p{ KY3äA8Õð6cJ¿ÍeQžÉ`:Eùÿ”1.á¬&=œÁ9âö7& =•1Ç„áðŤ6Qδð{¥Š”˜œNr«˜Él‘ ¢Åi¶µÜ)³Áï¦]76jø¥—m ´·ö¶ZÉK€kS·õÃ×»Åâ «¾3}o,…W<@# Ç4fÏ1Çeˆ[®p¶ãg÷Èöõ‚LΊ3™…5­¿ˆ/²œ°bÊ,Ræ Ï&"18É`èR ä*Tìž}D>rþw ¯EêZ+ÚÎdm>X¹*å-’îB!8^(፮±~!K­¶¦Ošªž²ï̦['AfÑü“ªš3º…/vËeâ¨×oÌ7)ï/ˆ–“f-d ÄÒcç„B ÷É›¸:äÒê°Ãdëœ?R2®×«G(¿Üx_›·:+úhÿËxV¨Ñ4ÔhÎ re-/Âcò)Xâ<û°,øñg AÛrÌV·‚´¿$­¼hšF ©ò$˜BìZ 4~R‚ðçÆÁ‹ëêÞ3$„BB;FN®–µ¨E°x$”Í֬ĕ4Œh[ØÅÜáÖã¡·wå®ÑÌ•Á ÉmLÊ-@SÈ´Zë»ÃØ´¾uè-¿ÂPÁ´Üp8TU= O‡7.Ó®qÅqãí 2ƒ·•Î5øg_ï»þÕ›QTب¸¡îû®OJMc‰¡– LFƒÉØ(ïD™«H‘0]€ Ï"= ö,„þé, üYøæ.ŒÛ¹u ‘E¶µŸ6~z š±ÞãRԣ؅íÉÖa0ÔÈۇçl…5„a4mU‡cÝtü$Ét˜ÜŽÁZ`ið^zŒ¡öMD('t"BÊ’}òà‚X¤‹eJt¨'{²×Gñüx>âxD…Gyðyƒ+Jè,¿oŒ*-ú‡Ã¬áÕÁmf!.ö(T_>§ìºv3\7´ŸúnìÆ¥`Ùë³e5KÁ5ó«h.pÓ pç #GoB*ÍySˆ>—$)è”äÛzWC@ÏQ|“2ÖÝáç]îõUÔãLµjÚv™O°çÂÚZ¢$]_©nî/“†>ö˜ ÞvzWi"× páj¸’ˆî–?¤9°˜£¹á›èýæš²övÔ–œ=ú•*6¶/S‹ßúvk-îS‰ËžÑÀÝ|åè]“Â1 _³ï¸è Ÿ/+ ³{#vîÄÖ^ì)"®´B‘fÆY&¾Bé{ÉÍ!þã‘usÿ—€¬˜ÂG2F¡ã,O1£jŠ0Òþ™/JKn6Þ£ŽOvÅ%cø;¼î¡ì]1 [°$y̵ðñߺï\tULy³éZ³#§éônYØ‚Öu@ƒ™*8?cÀ\óT 5ÛMÌÚQ`ÖnÇPáû忟3ø§7›Íq)´DËBf¾¹ºøôäõo| È Yð=ç³Ç’Ô+¥,D<=ÔfÿÑ„'¢)u¨mؘްà\NOý#LºÒFG=ŒŽ=œ‘À¹ú—ƒsOíkÍCÍÏÝ  ç•ÇÙ öÊ´¿„}ê»=ú¹58û˜â~1û±ªºÞ¨»WÛÛ¼óLè¥l!Ùc(Äë¶ Þ½X¾Œ½ùuÀ9´iØi¯ð1ùš!ôöü|-ˆêyÕogÃè¼ø;Vxó*бS<Íe¨FÅåTuŸzÇŒ1Ï>r'Îs"Iˆœ)~•øòæÊ+ðØ_’b›ÿàBŸs½<ÆF^EÖŒóGuñn؇›O;|î¦\²ƒ¹÷kò€ÓëÚÊ vU°ˆ~šO? ¿Ûõæ{sE¤u®N£ø †\—Ÿ{åi—ÉçÚýËÝâø²hû¹ endstream endobj 65 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 68 0 obj <> stream xÚ•YI㸾çWø¨ÚqÑ69ÍV@ äÐéË–ËBkñhéšÎ¯ÏÛ(Q¶«ÒƒÊ\ßú‘Úý¾S»þÔ.×»<+ã¢ÜÚÝÏO»õN%q™”»§ÓN;eâ2Ý=?E¿œÝeª†‡½1&2?>ì­µÑ?t¹aª§ºïêî…g]óÒõtnLJÏOÛY­b`˜ehì‡Gl´·JÇÊÂ/È¢‰î?‰Ê…2 EÒq– «c??7•©$ 2…TÃÐã>&3#DŸ>ÿU(ÂÃïsƒ${Ѐb <>&êQ¶Œ*wÀ³Ÿ±WD‡fA9 —Úh:WØH¢qn™º?ñÀ±'ת‘‡Ÿöºˆª 9½â¿ªê˜á¢žªvKÝôÝ «ƦžÉz‘„g]w¤“%á1˜Ì´’bv¦¡¯1÷׺­º +ÆþäU­Bƒd*N½E:a9ÞѧձÕB÷9³S666#…kÆi¾Ûå}ÎÄæaŸf:z"™ó4úíü»¸Øð´e¬ ± •:/i%þ®+¹;òoÝ^šª%TG,¢ºãÉÉ3ùE~ø˜dìÿ½~Üð;à¹v'î `‚¾m¾ùÍÆú¥ó;’eo̓µ¹·ÎH>¥£Sß4½ø 8Á‘‰žqä·ßà&ñŒBø$N'änã­ éØ730÷^A9Ür¼jl]Ó°KñlÝí½ï܈Ï.E.¿‹Ë“W¥Ñ¯³llìêŠ"{ß}à‰E‡8 'Î""ÔëiÂÕ¡ïŽÛÝAr&Õ‰<ÏÕP­lnŽqͲmЂ‚¸")ÈEIN‚ÃÀ"µp/}TÂ@[9<šMl8v¬—QJ+ÛGŽÄLqÿr›?xŸÉ×Ĥ3EN†-Cþ@¿äËYþÔñž? wBÄÑi±qpÍanÄÄôÛœ’ ­áŒÅTÇ _wÂûÔžxnîØ"Õ3Ì2.Øeß{á×ãùDÞ›D­óy¨\ÊÔ¡o+ž­ÚËÌ×'¦Ð´‰òÖÀ1¯ œdùzzŒÈ hý~Ì_†Uò~îkÿ—;¥!_ƒö“#‹äëä–[ ̾›Æ2gsŒÌ8Õw´ÆÁé%¥*¡‡õ)zrJƒXçØÕeäî4p„ÁnA¹FgKJ"²0da0š–LA”ù¢d¢—•›0-Â̺™xšë¶XDéL>/@‚¸ ý¹~®§‘»"X5Ž«b&m]ÝIùÌ}Z.¸T¨ðgæNCßò°x˜¬Ï6ñA;ö— ’&D“•vxÆéN¬ò6T Ô;î•qi¾ß#¤t¬1Èö7`’q^Ð#F½P-áGÆ5ù”þtuý$ª:R&6p'³œ$“ø!'+N×XYE'Nš°¿…Y tê GÀGh׌Á8Ë«¡ç_œ¸7É(øAÕœ(£f>£Š©©0gyèìØå“f‹‘¹Z˜’~ïe¸1fhmàΰa±ðÝLÌåJ<¡Ktå#â0—6Hþ‚^¹ä@«ëù÷4x^í…mÅáhüº/È@ïÒ¸C… -)ÖrVÐùëÃÛy÷`À¯ô ²¬Åâ:-¤ø¦ˆë0ëü­¢hL%]¤máÎæî¬q´WÂ{%Qœ²Žð7ÄѸ©«›‘Pø!מLð•Ò×ðregdjœN 1ºVZ!X¥™¬bt}¹°§¸•FF†º§Æ±†òHá‰OŠMáØR)Âæ’;Ùÿ²È“’ÚŒ]êä;AŠF‹BÒüØaí’kœM8Ïã@ 5v#ßÜ>hpˤÀÛ. o8ìoàDˆ&Ñj~Ÿÿp˜ˆ‡Ã à¹,8ðš°w«?¡Ý£Ôˆ|å÷nÀ‰=R*ýÄZGjǼ^jvŒŽ»w5oKÓf‹æ©KÚ†ã¦:ÁÓ™}(Êí­§D\1ÎÍÄmʳð;:tú¯Ë«`á”ó«Né’ yýL¨F³··2Ÿr©§OÃr’áe¹cyâÜ›óðÝÛ@Vø£:Ì”!±·¹ƒ¥WÎ$O ÑÔ" .]L-ÔŠ º‹‘œßòP\æB°œfFâWÉã{aˆ‘³¼E˜1hðqäICðÛÝZÆãrö³œ·—wÔY~¨{¬»#ë>÷º‡Fã"ØÀÎâ‹òš˜â#sR*aª³¸ôœºáeö¨SRÂà¿_ ç¹Õ™Öþ¬ÒHb¦±*øâˆ1 ñ7¼x™Rrjéßø æÿRÜ=_Ü0Γ2à¿§˜Ò§u~[¾…¸nuoÚ×Mo\ÄVWWÁ£¼"‡+nŠ«Ð;¸a¨ƒÔîx¬ùåûŽ®) }‡²ËXûg/ ¶õ7Fêô'*¼" @ºWùÕ'|–M"è3!½Ý3ìQ+µ®-;yF²F¯°Ti¥@N9·•ßÛM ä ñk!â¶^`ÝÇo/ië Æ¤*b÷éáÆ‹_éC‹P˜tü³~þ€ÎÕç& OÐà¯|jûÉ£,@)ô'»¾½çÑõ'Cµ­ŽÉ}3Ú«’>ut”)¾SÔ‚Zç“ï¢Zþ"¢ÃJo¼á¿I®_7!b6*DÔòGïò(îoO»ýå†>E endstream endobj 69 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 71 0 obj <> stream xÚ½ZÝsã¶ï_¡·H7B|’Lç:Ó^rvÚiÚøÍöO¢%ö$Ò!©süßw   ÉRêËøAÄ‹Ýß.~ zöËŒÏøã³TÌR“³,Ÿ­ö³¿Ü̾û(fS‚3˜X1\Ù¾ï>r“œãJK7g©@a'þÔ6}Ó/$Ÿ??‚Ød^ºu a2[ò”ißøÒTkRàójwèeïæUÝûU“p‰`Z9Åj÷NYFs¦µ›÷- =!R& ¬æ$¶ÍSLšÈ˜Q×K[5»Ã¾Ž T6¸nŸvå»w1©:cwÓ×E_ÄT,ç/TŒ‹[Ê4A,Áœ°²/ºÏ—I%=cbUʤq“ŸÊj³í#¥Æ•iÒíýyc*>Îíۢ|;g?Ý…Î^m‹6*NæÙ—ý¶YÇv¬F³\!o]uýÅ~Ž{93,ÏC/»€©bjj1blpŒeL¼Qc$–mÛ´ÇÍ»×¶^=4‡z}<>lîŒæ%éE øLP^ús»9ìËSﮩ&Ì +Ý%<,Î3e'L.’1¬Ïf§ÀÖ~a_¦ò(>o¶%Ù¯Æü}Ø/D6ÿ´X³ϙÍþªùѲy¸®÷ú}ެ«Yâ‡YÄP g)"J3‘¿¥­NåÝœåç̤ç¡5“ͤt7“ÒÜš '´ ΀Um«ªé·§÷9eYÛµ/ú¶úЫ28Ñ~9;7µ¡™}°¤‰,™ Knʺìè¥ëá˜Ýaz½üõ±-»Njò1´Ar’+4¬ÑÇýdÍÿön:s ¥,Éιʤ, hqÂl8`-øÜ/jh8üíýëä(ì%…òŽÂè¨à~"„VÜW«¶)Ú¶À‰Ï‰ W~á(ë>ï¢ßÍeç(Ð2¥_¡ j< ¯ÊBÆ[ž3aSƒ³¬?û¢òäR;ÃÃ\o%sd%’Ç0äü¯%R"MuÓ»¾iË5=»À]>U]ù-u=m«]Ä)/Ý(…—)™ÊAÌŠdD“@o¡~ßÇ GzêÓm”°±T¾žÛ2/ã>*„s¦Ìu¡wMêƒ.QäIämÒBïšó/; §nêÑ N °KÏfuԚ®ï™|‚6lvÛ!‹›\#Vˆ¾-5Ë]éCνŽ1Œ¿>†AyjÆÁ'‘ SJ3Ý£6™B~“f)p§iíF$BžÉSÀ% ¿ÞÒ¸ þí!ÊÞ„òd.áè=o«ûÛÿÞ¿ŸÄpð’%ƒê¨a*=yLW,)=.«Ž·®”>dœ[w>È® _;ÆÎ'™+ôâoIïQÿdוYWdw‘Bëx™èÑØ¯:þ·û,c© ŽØ2p‚†ÅçÒÎÚÙ°d’žNT¥a„Ä#JŽp(Á0“þÿ§L~ÆùXšÆmÀ“Kêï œyÿž¿²Ó8ýÉôW¡¬—ªýZ„˜à ÂB´Óņž«z]­ónèi[î‘ûg|ÂV 'Íçw–Ý-h¼i饀¸Žè ½ %<«„Ç*ä÷1NKÀ°íèCÓîË5Ä`ʳÇiÆ\íó×Ðå“Jâ Ô"KtvgдiE íI¹S_û-šÿ ÍKôÏF$Ï$ag¼çJ{™xDqÁ€ Níe¯gÆÇâêÔuÔå5pHÒ͉l¿=¤áÎ=ú—~ü'ý7ÂÔ¦uØ­éÙ £F{¨Á-Ü”Èx­OìQÊñ.éOäœ(¢ôx+ ÆÀ)U¬p—Àø¤ÎQ™£:¢"&'Á*x'ب2Ï4„'Z€~ÖøWˆIÒKwsu³·Ø5˜ª¾²7& Q°LvÒ221#W>g9„Á3fšIl¹ rg­`¼@;²‚”ÙÄÝ2w|ÍÆŸ`ŒºŠÚMñ[ÆF•ìôÎ¥œOQ™•p,%Ž1ï Ò‰ßçñ-e¸Ohλ¹ÿ”`¹jSï¡@HhÇÂ0Ø1º5É"n…Îá#„JÈø •꜃3A0nç>4nÝá@Ï®èzêj˽/€­¤¾Ü»§š¦ºwò£ÝhÓ®}—ÛÇ$Í)DH/÷=Ò¶gjú[@›ùü#Ö!MôΙËtÌS$¡ÓÉ~š©O)Â¥>M)‚0Ý.há,¬wÏ4ÔU´Rc¨ŒaÌ3¨¿',£<£œ¥y Êt Ju”PåàÅ Œœ"I™¸®À>õ…@˜±ˆ;ýÅ!¸&_Æ ¤¦ý~žš Te`2Ø w—/¬Ëjm;°/mJ°Ô& °\2q‰Êcžû¦ø&^zsìžf–?Ú¡6ëŠôÉNèàQê‚>ûSú¨Q MIOªöáä$:¢A ªžlÞ¸k¨±zrÕùÐn’ËXeûfìä°úõêeÎ1=y 5¥Lxuƒ7¾^¤Á‡C½êí]!¶¼Añy0(6РH!ÕÑwè#vP´Åв,Èß_5m[ºÃªqŸœ&¹ÖÞòãÕpmÉ© Ë|›ŒªÐíUíhŠfpìX'jôe¡õ¼¨vøÐí¾@áåòùj’vÿ£úÔíó"x¦pZü\– Lv±%-&Qì•Æ­XÕ[|)"æÚ ØSt£Z(îǛٿÿð?ÀT® endstream endobj 72 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 74 0 obj <> stream xÚ½Z[ë¶~ï¯pßäà˜/"¥¤@Ú&@ MÛ};{[ÞŽ,9’œÍö×w†CJÔš¾œâ´X`%^4œÎåãЫ_W|•Â_±2º`y±ÚV~X}ýƒXñ”i±zدx¾â’Ùêa÷!ùËsy«~½‘R&ò›õF)•ü¼&)û±ë®­Û'-›§®¯Ççðþøð·•œÁÔ’á™íÛÈ¢`ªXm¬.ìHÝ•²Y–”ÃP?µ‡ªÅFìSI·Ç§Nê±ÊvÚØÑsÛœ`nxMm’®¥îî4Oã;»â×?pÈ&gB8¦ÜçõÎÍ • 2–r?‹<˺õ –7yžÍ1¨õy7fš¥Êï‹[²6B —eK¼Mü¶¨eˆ ‚|8ssmæ‡gÕTVB›I›ÆÃôŠ@¥³—aÃñYí×ï"æ‘ó9?}u#M,l,XBX YÄqÅ“7[gÉ{ê/éq¨]ÿ꺚†Üv[:h|-‰Îªf»=õ OL¡¦¾ëâˆ[âl¤Q̘… „ïH*x±RI•l¸ws˜ óÓ‚[ü4ü,%§’ ‚¢Ÿ©q&OíLi˜Vo‚ð‚”f…™£ð®«w1›4Ä4¦?KnÊ52“É'ÿ•…’= ú­¨q$Ké÷]pãŸ6‹é¡G[$ÚÑ’šOõoh“•íN=`U“Ù¢ï¡se9„ý‰šÿ™/ûLˆx6KåØ×¿Ó{i!¢öÐ^,å3·»¾žÑ1µŽ€­+KCÏ0S«™¤¤Ì4³ûéÔŒõ±©‚/›ƒðÅùŠs&Å¡ÜUhïÊZ Ú=@ù±sŠžØê}ôÅ©d+·¨ëgäë¦x ¡T²ï»õ—Ôæ;ù¿ö'Ž3¾g¢v’M;÷ç¾»q Ñé I‚«^Èœa~ñùO`”ÐzÄG‚eêBÌ] H>çÂwDôI™Qœìs¼‹¢ðp1XòÂN&ÁÓ@ø >Ñþbñ.ŸƒÇujöÔ)Ll«w7ù‡Žô´¬Õ¼MÑr”Ù(9-ÿdó¸~! –‰Ðh¿spóðAh9žú“½ŸEáY:oõUÓ t}ë‘¡ô0@°A…ñoJZ20űؑÊÊh±ªø’º¸ætÿC]„¹ÈÁ/—ÄÝü…ʪ/§“kaC% .ßE4“ÏÕ O +ŠsÕ¤Y˜RSíR*¢1™ù9z1'H»0b±<‡×á‚î-M¡l ýÏ¥›ðïªï´0ºÆ™|ùÔµeÃÎSÎÃ:—í”PÉPâþü¶&ó´=Çr[aTîСD(¶<³8™Å¾aìzLõø^º¾’}ùô4 õ}I@ Wp`Ûž_¯)I€û7&Zº+†IÚF/ Nb%€–Ƶª×ÂÂ1xxÑ$¤ø·¢eñh·aâà$p’‰¯ÙN{¼‚çŒ@¤æ€$‘È 5¬‘ÀwÕ¯'[ Ôλ´?ä wî,ié5]8òEÿ} ¶ á «¢Á=®d¿Ûn»~³‚£ÜtÂR~õƒCï3ëx@l^¯W~u‘lÚ-Aß8ü_#奴£î”¥hƒg‘@§—ö=uûžZX9¸Wÿ‘-¾êt.¾RsxîNÍŽÞç þÔ¢½ {Ö‹‰ˆ¾pKF)çx÷'Ú”hU4› ìïÙ[+5ÖJ³™y#¡;tÉ”É,TU™—‚rާ‚ÞJzœ•ð£Gð¾v××Ôž‹úðE«!îš‹š)æ’û5ÍÈ©XJÆSMhI¨nN-1ä*ëe&m(‰¥Ü@¡«9A ×x1wëÑz8çE–oNŽxtv‡M*¹T;ElˆŠ]Sh>à«×`í×Jn’+TØ÷Îûñó½Hƪ¢õº¡)AÑMC3pƒÕOñÍFZxڤ纞ÝËTÆF¼ÌP˜K¹våÀ•`kÐnš¯äá$º°ªvç™ÝŸ±•Gø²8å¦fq¥£áØú/Lø4´ž#x„k†‘eˆhžVÈÁ¤EZ¾qe¥r´¨úÜ„½Õ&v`Ðóßܶe˜áÿUyØ‚¿·äš¶biÝÔ\¸IÑö(swf¸ï‰ç"(ÁÿÔ=þî¥ãׄÜ"¼ñðMp€6Ù¿8”šqñ+¹H«@=®Ä¬æŠdc|Y‡ÆvʰiñÞ˜*›Õê8Ç@#õý˜¹4wãUŸÙ!ŸÌÌÅ_ ñ@/½Ç21h™Ó>-* QOã7”žÉr:G/ƒGußw8ó•ÈèÝCÖ&,c‚«¤ƒ„®ø)œ¯Z¹ú¯»õ2øc‚àåʼ̙÷q4§ÀŽ|€\K“¨ŽlJÛ°Žö%Oç™óEaN•ya çE×#Ùåc‹‚¾½æ›®oà›)èÛ!ç ›\° rÇ?üF }ãüÐöuN•?’ª¸X–Úžžå‚5è´ª’]e ®vëpªëž8rÉ,'ųTFEéÏrºeí§’æùâËJvã§ ©`üîŸ*ÜY@ù½Ó5ËûÉïVÿøÃŒóV endstream endobj 75 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 77 0 obj <> stream xÚ•WKoã6¾÷Wè(1W|ˆ’Ú[‹ º=µ…š‰Ž‰H¢«Çé¯ï ‡²åDÙ:ðAÃr8Ïoè蟈G üx”‰(ÓË‹¨j£Ÿvѧ{ñ„IíöÏ#.Y‘F»ú¯øçCyM¿ÙJ)cùÃf«”ŠÛˆ,.ûÑŽÖu¶{"iÙ<¹ÞއvØü½û5R‚3P˜x5\{Þ§{µ¸h«¸`\Ál~ßC³°3]š$˜NƒªÚMù>ìâÉb›’,“a›é{ׯ¨›ú1ˆ—Îo3É´Œ¶NØÌf+´Ž‡©E"‹ÝžµƲ«Ì°dgñ8°£iƒltg™íIZ5Óà#‹üÊtÓ°Öq¹G’Ì+–ÖçY°ÿyÅþ”%"ˆ·­)»áê2ÈÕ0ò$>l…7¼Ž­(ÅÒíªì`g‘Çx F—Š"žS»ˆSÒ§‚̃~y‘íÚcÙb^Œ áàš +(h:öÎ_UOÕ|‰íHT[( iú¥ ®lšá|ÝÛL'Kwž[S;[+!S)VÅŒ­•iš3•2Åzc•Ún\-Q¡YzÞ³wSW¯(’)Óâ[Eª¡o²¥{˜qê} 1§n#t|¢…ƒJÂ(B`©0pÇѶeC‹«¬ÀzÎ ­N¾Õƒbo/ HŠøKØP•ìuOß2HlWAn¡GLW½x/®2B¹MƒU´KwœF"ËþijC²ÚöG ²ØTX ³ÿ²ÉE -ÁœÃͯ°L°be\}§.¹ W6`†oH°h<€[+h( =ë7¹X½rGÆTö>lîVíMXš¯•ÇRˆÒ¯lÌH,sÍTº 4ö"âs½¿ìq­°s‘ÝšÖõ/3„7ÔƒUI%€LBR$«©ïM½ê€€{ÿ_K²…x zà‰ÙÞ-Ÿ»QF\1©´¯}¡s–çðÍp€¡ÉÒÍ6Õ†å±h(e¡º˜ÁšVøôÖ4¬Ñ‚qé5ÿyÌÁê—ˆxMƒDût8„ü…fÍ­<öy¢ª ÒšV{· îš³T}Üù¸ß­hQ@é›'Dm½ÅPç\-õeœ·Oœ ÈB%,W3åj AÂ&J”P©Ÿ#j™&\Íiò ¹ì‰ôÝ”è¬ÏSÕØÚÿµÎUvÄĽl}ÃÜÅå3 ÕåȨ:Á«f-_é¥YoœÅ˜üÕܧœåéDzFÚ°}T’x8U Ç8âr0â2IÎ8ì«`@ƒ»PÛmY@Ò‡‰KüP鹨}bóŒæá9>¥HŒtG_ê; ü[Ñ”ý@OÆã B·Ê/{ërDPR:ô °ŒüÕh¿z=Í )é\Ìþ;_{òÎ s¡šP½G€`É"£š‘Á=ˆE.Eü‹Cí0ëà¡CõØ^_¨Ôù€‹JKŠ<ˆÊã±±h2ɤ® Á}[”„DôÐ+$²áÌl뫎’ÉôF\ )‘3©—9šƒÙ;0->Z€¨íüìÇñïŽ{ʽkƒ”>à˜ëÍh+ÿê€÷çWkNG?Mœ¥h $P­#ðƒ 6†ççØþa™cÍ"@r4aš/°€i.{þÓ¬‡<Ë>zԌ˿@waÝÕ—[ü}$”áÒDõÞù‡ðEsôó.úý»ÿ¨©Ç endstream endobj 78 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 80 0 obj <> stream xÚµYKs㸾çWèHWYZ_{›líTf³ÙJ2NrÈäS°…X"½$5¶óëÓ/€Doj+I¹Ê£Ñh _?¸ùy“mRøË6•ÚTe³«›M{ÚüönóÍGµÉÒ]“6›»‡MVo²|×›»ýß“ïæy²ÃÍ6ÏóD{³ÕZ'¿sv0C{£ªäàZsäÙöxÔu7ÿ¸ûa£U¶†)±É*ûæc¹ÉªÊ Üh+$[ ²(¢Ó7Û¢Tóy:oPéË b©ÓÍVgMl®T±€Ð/’“=4ëd?âˆNÌ`yÊu;ØLÇ7^¾w_Ò,çá2™xðaèO¼d:X« ÄÊÓ|§r¹…§¹‹]ªdz{²¦IbYu(뎸ló´Þ©b³]e¬«OÜSÙÀ‘¯ÔSÖÇ[¼Îš&úÑÜÑ nÂs½1µ^3‘}}ì8º^&ž‡®Ceúžd³nú‚ÿ¬í˜Ó£íìÈDý0óbòÁmé0ixŒ“Ü;©­*’¶ïön‚ñjªR”TUÉ`Q$¡¶{¦FÁq’Gò‡~8q«à)ÃÝi°B2Nù΃Ý}ÃÜÜÓT O´¦ã†üú#è /銸Ó×[„Ì4Åâ[÷ðælëÅž¯¬É=K½°y|ý™i]-+ÜdOBMòêùqrGgG¶U“&?Ù× …¬ˆcÉdUÒ–K ³ë€¬çʚǩö®óÇŠ‡”[ ^oØ ‡Úc?ZÔL^T,4TdEòù|?ÚŸÏò®™xÞzdzÂl°˜{îx‰pųqË…ÌËG²,¿© üKûT´ÏÕQî͈áE¡j¡Ø4_±–*Ò’™µÄ¨tºÅcêäÌçsGžaÕW³Tž,>ödˆ•(ÔƒŒæ$­ù†àkèJ°klZÀLÃ"3l_i-&£šå’yFÔ®§Á´üN€.€œõ'‚*\*ûlÄ^“Ù0aÍ_º£{¢éwÌJ5yòýø×{£Þnžf"JIh×(zÁHv&b àÚ[géâWzë&¿ð­°½È~¼?=í$ÒÎÓñá=ËJòIð;Q)@ÄQé®ÂƒÇ š'Œ–œÀà Œ|œ\û(~¶_ù¶‘ÇB\¾Ëaäaz:]…ñ&–¨ì+ì‰ÇÖ*4$õ2ÞCxÒó» Ž€ˆH»Šsë˜9žïƒW —™‰¶S@øïXå‡ð‹7%|ý¤/7pódO¸¡¼áQICú©ã¢Ù,ùN~Â@ æt÷pioè¬Ññ6u€DH?åÑÞ®„=æÕÑÎg²ap˜‹j@öÖ{ɽÄÛ‚Cïdä躧pé@,&1°]õîv'Æ­ã®1èì.¯Zy™Ú•þPȉL€¶¹œq‹S¨‹gRø´ÈCíCô²ŽŸÈÁ„xuáä= ÃEõØ5#söAúe¤6LäŠÈhfQ°gN½×ì¬ùP¡i衱»î¡UÝøõ)[GŽ%ZseSL²…EÏ –³®ioËzùõúÓuh£6 LQ”X²‘4Rb¡ÐsA·3“ûJáÆ·º®’§ŽßyÇ]Ôòwªgx\I"ëÑ©Ž7ÖJ‹L‹Ðû¦å¥¼÷ºÈzp \J2\¬‡ ˆe‚™ &ÚýêbÓ]Wb#nþÿB€,5)ö-%û– Úø%æ™Ï€T”©÷^"pˆ²ˆ^b¦$åRÑK„®ßK1T:õÞæH'ΉBJžb»ƒ]™ä¥ìPqΧ€{¿›¤Èßc`¢é@WJwÍ 9„¤Ð®¥^«TrÅ%M°‡RŸs„ù’J7Ìp½.(ø‘zF¦Ñ&n}á2ª*áOøºq/3b ù^¢¬êŒeüˆWÉÉ1˜aä™T6 ”íúîËÍ-gkBE±,Þ÷< '’†ÅL NBE5 p檣,9XÙÿ±_­NœŸ±šsjRIDqQj&L£1f­Å ‘f¶$ÔªãÞÞ²XÑ( ©'âÿÛÎD‘øÞ—]+À7ÎÑw#œÞvíÛÊ ¯ÈÚãÖ—Ù^ ‹ëgÚŸDçË¢0 ˯ð}âÔy”üÏߌ…ª $.9o]Ôü-Ø%ÿ +ìYy—‡È>4V —…La)§l)ܬ$Ü$×8œÌÑýË^rÄ*!“°9ËÜÕgÏ£³ß.zú¥:›Ûú[B7Î)~{¤’IûFŽý:u ö“ú~¹+K¯ÞU5É÷SJä¤ê< ¹ ŸoI85ÇÔ·\‚à21†?q„çgªÖ—‘™ö±ˆ"³âÝÈ,;×Óõ8äVR{J³ESTÕ™üFŠ0€¶E•w_©òÁx8þ^øŸ-+\·w_ÝþL( K|õ±Ô zÿÁ‚ÆÖRtÖ_šÅðý¹úÄ]Æ©„‚ÁTàŠä÷hAË% ªõAÍÀêÑuToá¤þ ãQý·˦z$[»pù%Û.s)Ls› ~)[ïY`ñ¯‰BÝ26ÞØSæåeŽ_e‰|!MHZp}[Ê#ß;^c‡¯×Jˆ‚M¢`û¢DUaÂQ¬ëv~Ål^<DoÈŽ¬ [R‘¨B%@A„*ÏšE-Z½Züp…ïþª@W_-àf¾àù;˜`_YsèRF¡K•®–[z%d(/BXMŽ¿àIy¿ÓuüëϾb–ôóŸ~ú=ÞyÚ>úó/ÉŸw<ñÙÝ„žXÌÈš*ÿžEŸ¢ªZ²5ª¨äТ¥˜Åƒéã3Î2ŒÁà©§p5Rúám‹¡lÝüÁ@QeÞH€aVË߯=ˆ,‰lÓ {.­Ý=޳ê¨ÔU¼Sê ¡TÚHVQÄ!R“>§k!¹V ¦wn5‚ï)Æiôt±:‚OÅ/÷r)Ýbý¢ç)AšêÇÊdìg9qZyŽw.‚Õüå=ŠìÕwR»þþnó§ßü‡Jå£ endstream endobj 81 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 84 0 obj <> stream xÚ½ZK“㸠¾çWø¨NµµâC¢4sJR;•Mm¥6Iï)“ƒÚ¦med©Wí™¶]5œÎñÃ6•*z:¹ÕíäÀÉS0{ÁÔVeÉL–‡«óKm϶ÁUƒÝ“Éf ò –¿j¶²PÑpªznÕÕ3ìó?v¥†Ÿ<²ü1ö@Š—µn³:ªËîèfmãZöëKgû¾jÁ}9”ÜêíÐ?»‰ˆ­#ñ "’¤ø)£]Küþ€<°0@tp%O@K¹Yk)Ïg-õø]D‡²ªyd?Zn d8d¿îíß‘¢ejg{nQA8ÜÙ߯ª›TÜóŒ²Ù3•nlo0+>‡êlcêþá“Ú+¡qÂ$™Çº I:`™ŒþiQy°‡J`%IaÀ4ð'DVbW"ì¾­GTšÛséÈX E{’êDdýXØÖQ{àßkíâÌåV8 N«¯zÔżV!·ø9tÖ®‰6-ÙÖÞ¢€‘MâÀ€-—_Ó*žûß¶jú€šqÅ+šMËN\ –]ÁþÿöãóÌBŒ`¢_û±¬ëo¹Œyá«7h—å¥M;`#Ú¦þÆ]•ó5P:oÚðØB šzƒîÂÍ®äBq‰z–E%òÖOFÄ¡—È ƒü›,zÝ´²î[n[ð;œlÕq³¯Î¸oEzûÆ”>3w0º‡S-›ýüàHõo®‡4 f±M§Ñê±ejýІjr®Õ¹â'ñ˜#>Q‡:¸¼ppEV†‚\Æž+£sùeòc‰0Æ4ÑqUÉ?ýлÁ9Jºp8Ž8WòÿÞîmÀ™¤Œ á¦xÇÛžHmN&Š*5±ÑKuÚºnÉvY$%u°ã™ŽÕvý·¹^lžcXÛŠ,N5‘ùœCÈ8KU3°‘Öö0||&¾>U]?̞ĭKãE«‹Ümy_äO}?]u<Ýfð_ÐgÿåpߎϵCï!7ùäp¿XÁ_.ÌΰemÃ#ƒ_àÇ Cšœa$,§ƒ‘áTK$ë9ï¨dˆ½d ƒ'ÈUB{}ŠÔÅ7h,ñŠ{0Àß·,ð>B ðìaÚ˜YÐ7åh;_e¢OO ø»¸ˆn"Cf…çKw-T¬;¥Pà+âÂ'p¤ÄG—Ä%°.[žÖþ®°=žñp¼/â@êNZ«†X…/>žk[”í‘âà.E&x8 HÃÞ?>€ÅfÑü1«ŸŒÇÌ$þ’Fì(|N’$À´ä”â(,X<†%HP(’hÜ@9/ AF°ÖªKW/´–¤q2ií-¶!½×lça¶ª›¾>ö—:–ú}¥Aú–ûQ`w ^åÃUzóT|НIqV¼,^|ò8 ±l°ÞöEœ®2¨ 7&š<€£QÆ \Uj}ÊÄž—7ÕR{¢åàÞr0\~XäMŒX8š##ÖŸ@ #C‰ªYg øírQA.´!Ö ^áCÌE޼BV4؆çc§_·¬ìºÒa.œàh•=È4NÅì!6œ†`Fšg‚Æ5MH©r$J–ñP¾»Þ Mù º*: žˆ Š»+:7e* •4 ù ]zt}`Zg‡±kÜš2À¥£ÊäBò?84Þj_ˆ“vÊ¥™E*Ɉ-Ë Κó´’¹ÐuÑL%à(&uÁ$j—Y©è06;*غœeBôrl@53øCëŒqo—›h Ác’™Š¥¹­éƒõ£¾Uª¡,kJ×Õ¢äjñ,m¬ž§ZñV‘è³Ia›È\ÄÊ[Ëûvµus/*É€* ¶Š»Hff6šÉTµTëKžû^ʪ{­zš¡ý Ö“:ƒz Ö}–î*¥<ºY.§ÁÅ;G¹k«ý–-©q¢–†´¾ÎdÖ$Aj@¤„!K6lÉY4Ë)Ä*\qê%Å|ð\]õ5„Ü*öVDÎ ¼3³L$áË‘ öŽS-3ã.|)ûžó2WÈÁ/46ü;•(r))—*(»ã¸¼ö™§ëÄÉî¹Ïß y(–™ VâÍñ±i;Ld†h{×hÇŽ;/€‚ø–«8ËîÄ·Ä\åhÝÝkóˆPª «°Ÿ-øX¸ tOn#¾Ü$Ö†ÞÖ×î]¹«2¬t*èGÈ)²]åÄ‚éP`ó­4ÕиÉú)€¼OƒÏ¡A1˜ ‚&/ãË*àÜÕ1Ë’ê†÷t›C´ºÀÍ7˜Ò#› Ç­o;·Hdœ·[¼ïš¹¸íÜ÷’øNï&ßòå<ú}_Æ5%]¤6Èækb‚3°žûk÷– ì9“ä¡7¬^Dœû¬~¾‡è=^ÊÖxÅPÕ%$¤W~/ísz#„¥sý:#d/Â$&¼ÄðËD‡Ò=ý@C6ýüËïGÒðÍ+ÝÃ")ºyÅîÖÍ/ù×ïU;öx™ÎË]¬Ü», ‰f-²ð¢)ëIÓ9¿AõÜ7Cæú¨t'÷%`:r2ç\9VÛT$TG£‰@½vjç;<ëüDç*j`«±¯ôlœ]J*¡v:$)¥j¹3VQð…úž;é¶\>),VIaîÔCå›ôwx„Œ>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 87 0 obj <> stream xÚµYK“ã¶¾çWè¶Ô–I/‚\×’8NÖåržœfæ@K”ÄX"e’ò¬ÿ}ºÑ JÐk<[: ÀƇ~wsöëŒÍbø±™æ3dQšÍ»Ù_f_Çg,޲8›=¬f,1ejö°| þºÉ÷]ÑÌC!D ?ÌC)eð²hòf1ç:Ø”‹|K«‹í¡…­eµž??|?“œE@06dXfž}ýSH<ΞÚ=¡0ÜlüWSwu7,ø}dã °/*a< ™ŽaÞ蚢xOphQЃ§ ¬ºþ䨽#W‘T\ÕÔ/­çžF‰´{¾"‚gȉ8®Yj‹z{ØU>‚Rá5'—õáçmñþ½ªJÇí˼Ë}y”1—"Gˆ~r’!Ëhï.o¹…\ÐG/:‰D²#my)Êõ¦ój<ûñyDz g×äU»¯[Ÿ()5»ØäW>j¼×²l»3W¿ŸØ®è6õÒwa }Ÿ¨]€»¼kÊϾK§‘êuòiþת„VW³tă;ÿܬ»¢B³êzÅ”ÕÍÝØ”$Ê1ӞÒžãg„ÇãQgÏÚU6°º¿€ëBGࡵzØàxTTèr»9OƒŸç!ŒÑÐ¥bA½¢ M;àT3++úï6ƒ3÷:";µ. O"6Z JD)u¿ÐëÚ5!茉c<`\UÑÒK.@ó× % w¸P|Þ7EÛ–uEús Ÿýe 'u‘G¶!I Fiò–Ò½àçt§—$œhЀc ~†y¸€Ìœý¡f‚ìÃÿsò:¹"biv,bÁE/b<EÜc^5Ä…å®\4uÞ49nü½%2ÇhÁÞx$µË#þ^¸TØúVa_rL™‡8y.É1øy¥­:ôq‹„(šÑÀ,œ*³Ñ„./+Ì'̳®«çRrÄ%¢¡%‰àïdeBh m··]ÝK[O¾”mñ=zÙ”6ÒÅ.ÚSaBì²4…CSZå4$#Ê”¾Ei!¾>ÆAн zô†…H‹ëÎ4íi<{‰0Éä>£}öˆÑÁâÕ<„¸SõÎ&+‚G\_IV@ïôÅ8’DRNõ®ñ%ÙDÝpÚn†¸‘d aê·¡i±-z›³¯£)ãÿÇÃE]qúÄÙ•›úóŸTÝŸÝíÞ ûV AG&ÓÑ©|Mã²Z– Ðy»ô²âÒ)›¤+Tƒ<™<èiNëuC/9)ˆ=à(¡âãnÍ$ã1à¸4É-¤œ&ÃyŸ‚®êfW,Á5KτԒän™_Ón¬¿¤vË<€EœhÍÍ`jÜŠäªÏÍ-|Õ_y@þOd/å”§‚tg`ÄXm˜fÒQ&ˆ:¹à”_NG |£Tý\O*Õ!&Ÿkp\M—ŽËîŸöÄÀE È$ªe‚\w’#øë=2-=4vRÚ7нc’"@?…‡˜£¨ÜÆNF¼÷¡‡jY žªXz(Ipªƒ'ò)sb·ì«Cµè –´ÏVDœQ_dôÐùÚ ßi&žA¯Þ½Ã¯Je¯(õoQ©óm.ð¶üb¥ÏQë.*Z)•F¥B‹êŒÙ´Ã”Ö`SOï™»ÞÌìîóDT½ç^÷˜Þ»öÝçd»ãû¼lÈÿšú0m‹p[V¿Ì8§uq‚Ø#H¬êÄ‚|·{À]þ¹ÜQÛ%$hO&šVïöÛ¢+Bru2 k¨W\ãv>篺FŽWømnâ ³ Oz¤âK ]¼ 颠ÞFS—Ëc˜× µ—¯JÿßÛo$cwÙg¯ñi/RÇÇs‘m2®Ò¡ý ykÿéİ–Æ W˜¼3n“ Z¥ö4VØtb¿RïÑ#çÛoÐ0Sãcª`0 ;íÚPv KMUÝÑÀ`ùÍð½ÜæÀsØh×Pu›è4Ùç-*HÁ—$³LGYïüï?øê~ç‹a >ÙÃledÎï“’£D^}÷c×é1‰¿¼”Û­E½Ýš+À4Ó9%±2 apö È|Rq·ÂÂå^X¸BF€#W8ašEÚáäPw¤QKJOsq2r+îÛÐðp"XÈ·ëº)»ÍŽ–ËÊç!ÒtôW,X8^B(Û4‡sÍŽ{Náè!¢ Šcd:àßíˆÕX4Ï´u§ÙÄÑÃlp¡°¥Ýԇ풞N_)޳[ˆaê µ[Ã-œ4õ¡+«‚¶ä«‘Ó¯¨Úé\âVH[Û‘a·À=ÂéA¡£ƒÿØà$eƒSÒ·_=RÓÅÊ·l!úz(œÚ¹&J$ä—¨©…æ˜óy@Ç#¥·j¡Ýzù¿=Ìþý§ÿw„ÊØ endstream endobj 88 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 90 0 obj <> stream xÚ½YIãÆ¾çWèH#º6É1|o°{“{lŠj1‘Xm’êFÛðÏ[Š‹Ô¥e‚ `T$_U½å{k/~[È…€r‘ªEjó8Ëå~ñÍÝâËÔBŠ8ùân³ÙBê8Owë_£o·ÅS_µË•Ö:2ï—+cLôc]µE[.Umë²Øñ×rw耴n—Ÿîþº0JÆp  c” w_þ Å즕ÎóØä‹•fömÑtO®«<}2#OTœIà×_KOqÄz÷L¯©‰~j€;àùa¹v]¿åDzèªî®mÔo+\è¨A‰û¥Ê<9 ÔnÃ¥ÛöMǵ?¹*Xø¤¢Ö-•^ø¡î<ÉoÒìêÿåK mHaJ³«ä пdý‡YmßG]_´=j›ž7­ÛãÊD¿W­»_ÆlªeéÚ5Pí^—™ŠPb­üå@{/¤i»ž8!’b÷‚‚xókÇï¶E7]áΉó&ˆ‘K2/ ÀÂÿ&IÂü£ê-j ìò¼´.9T3 Ð@[M›>€ :ž@ú,r5)„itFÚįJ+¢¦z9ùÍnçhKYôÕ:€&™ØX[–¾­BŒ¨4NÄu}{(ÿÊß¼-z¾t]ue[?ÐeUÇ·“‚qÞQvÄoO]‡Ì.3‹tn÷™3­´È£ôÜ×®A³ê4úi’H$±•3‰ü!Á,ÈžzÊMQï:¾e}@\HÁ(¤W|ÜW{×¾úW3ÅCLPµ­k\ÒDuÏ„-Y» 0ª4ˆ;øéÇþüsHõ Q3¸2× ibðX—QYœƒÎÀF9QÁ§å*±*úöÐ{¿H’~½k1†,á‘– •ö~€r:»M °Ì–ÎãeåéV2%´;BB&b´š# «xc„€‹> 6Ä™ð0‚—Äþ<àâ×9÷xPë"M(rj Ku2²X%ƒ EÃ'{p3X1hKVË:´À)º$útSì^'i¬œ¤±à(õs½fn­AH‚òw¼tþŒ}]¶®hÛ‚vûÞõg:Ÿƒ%7±Õ„à ¼C¿ÉUôlWÓ4Vö–ójÏ\çö£z’87s_~âÔÓÕ}ýŒ" Ü"ä©Is"vU‡§ ¤y "À¯Ï ôÑñ+V , Ô§9‚6oüM}µŸNîùå ±B „»½^ª5› €-I&2 &æ"ù{R…fõŒ,åÅÌòBDõcãR¢~ø}íÏd}‡JI¢(×ü“Ý‚rã"œ¤Ó¡Q¢ª*§gW{­ûʱnúP9žÏìÔT»j_5}(}'2N÷zÇg~tëê‹Ð™J@ó¶ÈJÎdúwƒÆ‚ BËûfˆä·1xáÄü85Ôë3­‡'ûõÓýò«`¹«!kX5·Ù‡öñZD£šœG² Û,²˜ñáL¦¡ÂNÅvÈÉgQâFÛÍz¨¯Ba)ÕŸÊ)ä(m툂bÓ ðµ”ÔÐç \½l±“#¢¹³ 1;KÇ)4áÛÁmpnƒû7nIoOÚÎã˜Äéõ% ¯óËÅ¿„JHT sã­¬Ä"a%m,o6ßYGÑ*VéG1Xw]°t4Ƽ±šü­êŒÔÇ$PÍš ›¥Ñ÷cDEâ1á‡1þ:÷£…ÎHât¬ªû-vÆüùSÈZbª[)—Kßc£`\JZ*Gàý›Ž HœO]ðNŸÔocí@μvðÏKÝoƒUÅBÝnÓsZÑ7j%ÞU›> bâb¢¢YŸ ¹ý?rÚÖÛ«FOµ]é8–u3¶ÁœB¥ £Ž D³ɽÔB‡˜ U†Â·Xë‹b\ME±¶Iô/%Vĉ‘¾ô¨dë†ZH{ôp×Y60ƒ“ƒ ôǹz6™Ö`À•2Š4þH%á[8Ç%Ùg¦†•üóÊx¯ÂÞ' g”«’!¶ÃâVuäi,>þXÉ«|Ðhê¢:Ž”MSŸÕ}RØ\Û·+ì~ùçÕ1µ]ï5¸S‰AžQ $‹'ê­ýï¿TŽt¿¨¯¤ ŸúJ^ùFb¼0¥ -…ŸyÁàTÿë±þ?IsY2MË.Ôùzʼ›CSú!ÜÄ#¾ªÝ¸vïnœgçK¼ä *QE>,Cæ6“ôr.|?òz”ÿ!¹§Wò?˜ÎØÓ៫~WƒN:àü}pGÓŸÛBå5€øútÆòK%ŠÒ §ùÌå–óRõýß•˜:OÕ5·MðFfn™@0ð€åŠÃ)g UÜpº‘É»­;ìüà‹üÈyšÛPÿ/(‡9Ö›¢Ó;ø‰ó³úaü=  ¡1XrÂg”€ÿ¤Ót$hsiµ!ÿk›_ëäØ }†Õq¨1¶ñæ\—xÔoý €ËRØ<µýô4éŽ_Ð ~‡î°’&*úÅ´ñÀî©(+^Bä 6 Bê-‰p>Ò°(˜°'ž˜Áð ™kÌãÃk:NRû·‘èÆ$×B—™šžkUú­¹1¹fAüýÝâïù×IL endstream endobj 91 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 93 0 obj <> stream xÚÕYK“ܶ¾çWðÈqv`‚ R.œTT•¤lÇѤ|Ðê ¹3Œø‘œ]­}ºÑ Î`v#W.)UiA ÑèÇ×`‚Ï"øÇ2+X^û6øÓ.øömðˆQìžìþˆ˜3àéý1×sß¾Í.YÌSâÂ3ÿÞûÖ5ƒ©§É²÷Cýq³Å½´ÔUçA5v¬¢¯zªZ³€>ÈèĨ÷ÍyЙµé¨&©Áìë鬴›Ìfší[½ÎÑ |iúÃó&C°X&Eø¯ñ¬šæÙp£?Cµßj¹·VðYGpÃáܨÁÈ¡™æ†)<Òy{´þ±«N”†»£‘d­ šr°‚ó_¨³5w´<ïÑ*G"°fà«úpÄ­IÉwå å䜈6JÐÄ(˜¬µÁ)}0ÚžF)º­µãü[)Ò—Hz`i ŽÊãž…–ÃÃз¯ðA¯T!¡dk¡ýWˆ£ ;«å ~ü‰N8’³&{ÕìÁÁ“¡V´ ®0²ŒkÅÕ•}Û<™ô:gg¦ƒ€uŠÙOý@®l—Y½™Vš{`¨µ¹B ÁZ$Yø×\ç^# É—cˆ‘ŠrâȪ¼Ão ˆŽVÌ1€/”ýÜbZ1»ZèÍ9USµ•¦šF’¬6<·Â¬1Ì;æp¼KéA[œ[}>ëÄ©ýlþ’ãÅ ‘€B‹m½z5 J‡”æ“T°8ã’åê¡¶ Ü@и5Í RIR¦³½`ä3ÌÅ"o«Odp˜·NÈi#'”á Ò ; ˆ‘Û•†K>ëÙ²iæ'} 8qq7zê¨FK$€'$0Œ\&×áôâ:¶ˆ‚ W,M²B;~£Wô¹:gs-0j–#­S!nú²³fRÚŒüÙ ÎrÔ+6ýÜ¡Ö&p^•ÿÆ…¿Šð<ÎfžF'=bœZ2I:¹¤º.êѹ+«xîûn¬KÄTFv-üÎB‘D±(4x ¯‡š ÚÑ´A–Æi*0l†÷Qd[¬ÜiŽŠ¥û¢—ÿ² >,)òà :<ÎâÚ§4e‰ Z˜LóD¼ ~¡Æ‹ c…ÔZªŒ IEwÝšAñ8ˆ‰ø½G>ÎYï£DáäL,³’<ÝŠ,AŠ”‰ ÈKy,{Y¢k[Ä ˆ)[ÄIÎrþš-ªÙsŸ´VƒÃÙùl‹Râˆßô`ŒqWD)X’¼*âLås—kG#Z@†ü%He ÍbÉ7·oñH´ èœ-pÇ+ÃI ª­0e]3–’Eâ ñÚ>yjHtÓ%RÝ¿­8ëYÓ&Á¨¬öC¥Æj$:;½”(œ…”b•±EÀîZá¯Ø_éj3×tœI wè&N‹¡“/ÄܧœÀ„ÖéÔ˜`oê®R¦b=œ»ý4·Í¶~Í%Ê?Q 7>ÀÀý o@‚¿d9H‰1ÜWÄ¡‹#Á$Äg™ ówõ䃹.>3ÕK ¤±EZ{d–· ÷œæÎ—ìà©bNbði±=QéÜDU™Ä(£O'¦\žó^°ŒìÞyÔ” Lw\s5oލ8j~ç ©ÄI]GS¯9-'ë%LˆßëÖ‹L‰i¡Â ¥/#¦WÄmµnÛ@¢ÇM qÖœ+"2Åû2ÓE,‹_Žö3 Q(Ó`ަqÛרéž fçžK_M— ¡ }q-VPÏÐÒ‘‡KØåÂÉ1Ó›=qdzb‡r[Õufˆ‹\WÛ%5¸1Î)Æu7žëöïZò‚³ÈV‡ÎŸׂÛΙCbé'rÏ­&š £ƒXË%´\–]OSËS|Ø^ú¡ÚªÔÝaþz¬³Nè„;t5š5âbǦ3“a«JÓL êT—xÇÂÄúªé2ê®››·«ÎlÖÃöÓAÕ•îVéj®§;+ÀØ*ÝžbSy¡Nt¥&lTäÆ;ȉçv aòTOGÓŠ¦UÖçÑ‡á„³ÂÆÆ?}Pàxƒ‰™€ÝÒöÒ-ÒE,,S#«C‡Y-㺑Õ÷ÌÝÑÆ…# (Õ>wáT^ÝꎫÛ\2_»M•$ ý_“œ¾’—²X¸™ð†Ä+õŽ_ØÏÍŠª…“[õÅWë$¦°ÿ¯Zœ÷7–溅äHm'n–;³MDL/•»ôUÉäªÜ&Ü0\Šæ§pQݚ̦W 6õ¢}[(+}ŸÖ!p_Xø· G–½„Ü‹õ :‹“ßûZnÝwÁÿ …ÌgÏÅ$Õ ·À—úD»Lꛊ™¸å2»-ç?yô(ðX L¸´Í $USl¼—kÉZÑœExµ¡ËÅ_¹×ü~1 GŒgÏ))zÌŠq³‹Ò·¼„d”§ceSö}èá f”Å¥ä± ™i $+ë¬ÅŠt–HŒ\[že^^½w˜={T(ÎL¡É@ [æp(ñe ŸåG÷‚á ÕßµíÕÄD†ùÇ¡ó¼¡ëtŸ&x£¸|lá²4ô穞ïÀ©k‰ýLÆûÖ¾^]k íu’½†+òÖ8°ÏU0³ïñ~5U4­ßép šC?@Em±føokýþ‹KõD;MÏZÿF̉'•²D\´jôäKÍÙþ©°/æ…¬0<°£¬íO9HæÜü`ÊpaYÑ]+q™*mám|s÷I Ä]ÜfY¬­ñ|_~’˜šˆäRä®×ç•Æ"‰,tü-ϵæQbÀ'ì›(æÛÙ´%M˜76çŠ+›Þ~Øk›ŠÌ>œA³:”–†JCº. Éü⪉¯[µ«§b|·£FTr㡃b…­±Hýðl4a…@3è,œPÍØÓ éˆv`ôËÛÎn2 9y•ÇÝ–ÊhiK=§-m€Àìm€ÈßæÌe¢ö‡acïB4wTUõ›dvù&¹îëðæÅì™)¦µ²?æß"Æ.Ó/§šø¡Cl>ão2QèK¨¯´Uô±¯nN1ù»î,Ìy´jö,Ê»¡='Äù wöG//蓸mº}ßœÛÎÇP¤øæ0„ ÛŸ?6Õ7ßø¸BbÌ­3t`yDŒ—j8‚ˆ~v‚/ê´jüôß°‹€>~ÛÀbuc{ÂG÷Éà ff_šÞxÙ˜‚/´„ÊxÂOÝprÙ¢û«îùrêÒ'¢XªËW°{~ôùÚ«²\ÎÆ,9©³>Ñònÿ:a|Ý:Ÿ‹H0.W¿Õà;:p_¹Ä’ë^t–fŽø}ðBñWÛÀd¯£Òx Ê÷ÞÇî7ßÙ~û—?üêÔ* endstream endobj 94 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 96 0 obj <> stream xÚÕË’ÛÆñž¯à- Ka^xØ¥ƒâGÊ.˪Ôn|‘ö‘ ‰hôjýõîžž!rø’6Ž]<`Óèîéw7'¿Lø$„ŸÄbG)KÒÉ|3ùÇýäåwbÂC–†éä~9áÉ„K–êÉýâ]ðõ:Ûvy3I)ýåt¦” îòr9{Û¬²ªø­¨Vx¨‚7Ù¶>Üÿ0Q‚3Àšï…0ï^~Ç5b SŽ$ff¦€ a_7«Ý&¯¦’]k¿Q®ähÆcIÿ>ä±ÓCæ‹´¥]T#@Dˆ4 ¤jêÇÖƒF¤ÌÝà+{<ÑL‡ „8ƒq’Óý:Ùè0¨¦"v›©H‚Ó¬QxJó ^@S#P5»¢¢gGßó`‘u½Úd]S||›$ ò_vYiAk‚ì$#ÉpOr•WyKÑÃ3sÃpxüã¶ÉÛ¶¨+Ò<ìs˜ TÐè˜GI3?ªI?«šæu¹ÛT>M©˜…É9UE1¨òPSRœ Ø¤à#j6(8|vîsR¾Ú+J å…¨¨Á'Üoxà(nŠySgM“!àSKh†”eÔçTô¹*תlQï>”ù_øô.­öp(#w)ÆÏê,–èæGJ“‘“:¬öb­e}vYQÙ¤­àÖI):ácè 2ø'y‰”1à¶àmW7ù‚ÖÖqgE›¿ Wë¢ô(åXR8œr€SY3(ÅÖoP[Èß—>ÁIÅb˜Þù¤¯Y,/ǶÄáxð"ᜩè6×{ð¨qÀ‹×ò$ òöhá·;)˜ˆ-Ð&kÿ{Âîâ³a=bJí®õEéÈÜpÛ®÷a«xê^Øÿé:KXì4_x]R¨=jgf&㈅£ð´­Ûü‚‡ø=¬á(1D,Š??ͤgd2y^<ŠàÄMµècâ«WüÂMýõO¢o/€®¨Y¯eûZÁ@†p§³­‹jQÌÁæíÑã:»Çâ?á£rÞÄiðÞÔAï§t^7ôÑ ±êúË] ­ VWGaªßTrš ÷®]ÖÍ&_€Æ<9‘v8`‹¢›u~ɺ±Rñ°ë¶H­¹lMXQB»ªÜ²¯Ý•÷œ¿EñRýg<’'’lg/ˆ¾g€œs(ICpP Žå…_ þÝÕÇUS,N„rqc½d‹\«¦ÕÁÊ7/K+¦uÝ¿ÕT.eeùDo‹j_)ТÉçÉWäBÑÕ[ƒº.ëÕ“«§-š} å„Ûþ¡²}úÿÊöש9ï Lü $+ž±>º.ÛùÒ/gRŸ®)MoÂÄ -Ì 6¿Nµ²rgÎâ`i"fhk \l³&Ûä8#"É()9^߇RùâTØ·ÊTäZzRC\¾{û†Y¹çéÖPQ”¯-  7[Tº TšñQB\N$Ú\ÎÓ—(É’È+p1¶e¡õ¶€ž#d¡€Ø+ÆÍ’zDæ2 f 9l_*zóã`å%½øâmõw ÿ5YÚËûi"ÀnóŸ‹ü‘N¶M½uxM0åXq=¿s½î?zh\²îÌôhèå±ñòÈz¹²^n ijJÙçs»ù:k¼—Žú êOê­/}G1&ŸÀ™Â&Â=è¤ááÊw:ÜäY»k즰_  aG+!aßå¹GØÐjÇÜÚÜbÂÜ»j‘#?U¾ð`RPïýÁçÑ|Ð@|3â}¹«æF[¶xaJ3í¾œÏV^öu&Np¯Ÿ…ûünô 9Ò ½3­ûB “Ö‰Žÿ⌗‡Ð±Gžˆžºy:¬(λº±ÖŒÇá€Â*ßW¸-½¦¨ëŽa1J“椦úÖ¦I¦0žÚV¶±{Yƒjèàƒ#¹ˆ~TL›èŽóËatÇY=\ªµƒÉyÝ4ykÉW ;ï¬ép?÷´²Òœ&¤M],ZFØÀ£Q“ªǦ¡¨k’iK#ígv\¼á¤: lñÐá©p§nžX©q'ý©uIƒÖ°?hó9]ÖC6å͉aísÌø“Ò!2‰OhÝ3‰›¢:82)âÐNƒÇ0ݺh´°kÐaFÓª=8ÏÊÚ×i¸Ö°´/½a3ªTî×¾¾)MYè‚`[oÜÝ<#¥´Ÿr4õ®+*G²¦v¥¥mUwÄ”–t2§ù ¼Â!7F3Øn³¹}oŠ(\œ„BÙ¤ü!aäòZd5ªhF3Q„*wDYF!Nlwå‚Ö¶í¢Íˆû1pk°|vïAâ\ÔUrû µåïu  dqÒa馶2Šc‘¡€’¸ïn“«Ìì?T¸„€áé¯yŸŸþýã¾Q´`)ïl,òºõ‰I”–×È& ™Llg×CíØ8{‚剺•‹è²ŒTØÿOU ‹ŠJK¦èè94Êܘ‘mº‰ˆå¼Û5Í—£ßcLB›t ¡êgnjp8lN¿Ê|"ÎT²Ïª{OD䯑ñA/)&ûÿÌ`5JcÂòvŸmÛ¢µÂÉo±æ·XQ~ƒË'±¸0\×¢wð‹3Ös“ yq¼®¯iÂo@óé_\‰óãNðºk§_· ¿47£¾cD3 å\8*š.Žz¯]ñoÇÓó ù« ž¿½Ÿüëo¿Ýøs endstream endobj 97 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 99 0 obj <> stream xÚ¥UKÛ6¾÷WèH#>$J ré#E‹´E±Îi»F¢e²è’r›_Ÿ¡†JäZÁ.Pè@rÞóÍCÙ?Ë øX¦x¦ª†ÖMÖž²öÙ«w>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 102 0 obj <> stream xÚ­YKsä6¾ï¯è£:5­‘øÐ#{šÌÆ›ìe'S¾l­÷ «i7«ÔRG{<¿>J”[öæêƒøA>~dï~ߥ»~é.»<+ã¢ÜÕçÝO·»7b—&q™”»Û‡]ZìR—zw{üoôùT]FÓïRÊ(ûqPJE_zÛÖöR5ج¢ÏÝù²?ˆ<êZÓîEØ.¢OmÕ¼ vØÿïö_;%Òô'N«P®íãM¶KóX¤ç=°ÈAiÂÉeûƒÎÄj¾\ó|2¥ùdâæËÕz¾õš’ÝAq‘:­:QfÞü‚ÍÏQ¶Ïê –GwÑ—ÏŸîöÔå+ú<Û£i^¨kÌ‘ZGS£¶SkŸ u>t=DÝßmûHÕ3 NÍhŸö:‹ªÞV£q«»a/RÚ‹c5Vñþi}‚HTté«z´5®«æ[u¾4†*Ý}«Ë¥yq3a-X;V·¶N%ÁÖ9©±£ï£iŸéÒ›a°]»m&Å ŽÇ/ʲkÑ9ØtµŠ“ÿì ™ MÄjÕ)®¾Nß¿w$~‰$Iïö±›.Uq©`Ê,–…›ò×ÄÀz0É´µù€µ7ŒšÂmV뎶»?ÚíǾjØŸs5⪜¼eµÏ'K[‰U™ªFWq­ï°ë™gâã‰Õ²3@÷öÛl®ãà2ûî¹·ãhZŠçjà/…}c[SõÔ4Lgjt“?ía9.Isðlåö ;Ÿ°ÓÔc׳&ˆ”Æí@ޱ$t]eÁ€n,ÔjõhMo¨þ3=h» Ú@UF4¬Ü‚TVÏŽƒÚxªF’  íçê›=ƒ¡/ÜùíÒT¶Åè„ ͽ9C«‹k¬Bâ(—8°ý¤ÆmE8‚·Â Ï~‰¯Í¿Ù2ÂD•©ö)å"*•1¶¶äe\f l¾_ýE¬=îÝ%‰Ø@'(iÉ"çãJsÜ@¹®Z*Ü»­2TéÍëÃ]ð@§ašÆ^†Î݆£®¦›ŽT¨¸^–(ÒXÈWëZ[ÍŒ –d ù- 9È2‰eúw<õÆmIíÙ´ˆ"Î(ŒKUÀ8U”Ñí‰wò.IU?ŒT êõÖÙš] ¸ c%M×>š{!¸Qr%7ûéÃud8!UÊh0u‡AŽåÀ Unå¶ ?V­ÆÎFa…ͺ¡ež/0ê +RHŒ'Ûo¤â%<êĦqØNç™$uØ0œº~t–a3Z†›GîϕǛ±Ï)iéËJ$Ç0–| cÙÅ0ÊÍ1Œ­=zeû©7!…Ó¿¢Ï0Ù±ºÇ“NêtFèbÜ#²ŽC¾»Mž¡F„ADƒ^c.·ÔÑ/¼@Ä FY„À/Y}GÚ§Ú¼>86{;¢¹uZ²Ú jçAœ/K€WLŒ‰ÐÞµ¾4‹ž;ÜP²~1ýXùMÆYW‹Ö™3ü•í½nÍüR&šrSyêÈ^Á0¶ÐD è89z&XrñO]- ÷汩½âþ©åCa+TÀíMxƒ.8ëßVéQl¥æE‘p̳¹‹Y¨`Çr!yÇûéaKü:´uÈãpÒf2i=¸œmËãO®õ+*rɆ§z°iC¸[„²?—W’¡Yà5\6ß „TÒÌðD¼3¸§Èí}#>~2@q#TÐg!ËUÀ¨dOA¬bú ¹+4.ΠuwM Úh(œ‹-Pæ@X!¸ÝÈëÝ=ê=`š“W· u×LgT&4±`|Àƒ1”(bà’Â1ç•Ü|‡ÀJEL\‘ÂÝuÖ¢<œÎBÙ©rëƒÀ¨SŒ‹p¡‚ B"‚ DD®!¿§ô’*¬Ã&(ÔìæÆsWK_ùú:˜©$ÜËFÇ)…?Þ×Èú¶2;Žf¨{{Ïü2]Ìç—ÄÓ§u\/œˆ•b¯c[¾"eËž”ÉÙx‰g#§+¸™ÄÆnVdùnzæ=ØCfõ0µõèïnot@ê2`«žÌ^êjƒö kÁ ‡§¨|fkXÛð@%f*ÞàS€Çžš š‰-;šåX,¹¹(ô{l5‹RÊ…$‹nÀ&œÉ¼äÛ X"[£±Ì™ž/äóÕšæäÑc*¶.kBi ·&Ô6¯©XÖ„ƒ,dχøiÌ9`ôJ&túÃàÎ]XCl·üýLÄÒOhøÔÐwÛsõØÚq:šÍ~â»ãìù•%&âÁÖô䤿ò^øÒwc7îÁ‰/ø®›D[& ß^àÛŽÌðêêÎÕx¦$<ÊT¬½Ímß=[8WÄ™—ùàݸ©M&qêá®%·o)Tzq+Äù3 ýû!g£B¤d£¤â(—or 5?µ|7}GÑûóíî·¿ýS\ endstream endobj 103 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 105 0 obj <> stream xÚÅXË’ã4Ýó^:SXc=¬G ˜*Ø PaÕÝ ã(iW%vð£»úï¹z8¶ƒòj𢲰KV®®î¹çÙÑ_ŽRøáHHp…¤ŠŠ]ôÃ2úø™D8E*UÑraaŠT-W÷ñ§§|ßéf‘PJc~·Hcñ¯MYå>ßšaªwûEBD\WºZwfœÄßWùöµ-ÛÅãò—ˆŒ ~j£’ÌŽ%T)ÄT”0H†Ø'_*·TÝwû¾»³ÓÒ(„°Kèçµûø§Óœ±yî‚WMýÒúIl2‡R$¤ŸóúŽãDù§¨·ý®BMKÄJ‡P_CÂÇÝ“6©gª`®™ßBhIVéááN ÿ¼€pPÚ./!ˆËÌJn¡¢†ªË¸nVe•wºu˾”Ý“{Þèvogè¢sϺÚ=1!,XI$¦åÝO¡¥°ÄÎ…pÐB-º¸ÃL²9&õs¾ QˆŠÛñ€Ì=¦•f-ă FÎãÁihs‡,°ŸÓ¢8A‹gó€¤n|-à›VôÇr§«¶¬«»@Ñ292é>´Ÿ z¡ðD¡!Äãý F±,\ùìD奛¤‚œL°°µM0G˜yjbX˜É‡|VuÿçVøÊ¤ä÷s GjØø7|“Œ#6ƒâ‹wßꕃoh§²‚n á­ v‚-ì[Î(¦o` 90†ÝȘçk#GÆÐŒ ©1†Ïuë¤-Ðì²)q^‚äíõ”^ÄÙz2Dä¹z‚yò°‰A 9ŒzGìØà™uA§Ž PÆþµ%¼Ÿ€çðâu!ÀyÑònòò¤=¬„§Ý#ÁG+‘Yóvú1ïÊê!†²&phVSÚCÃÊ©tK„É‘„Í1$³+:6:‹ 8.y›6¥™Žu}y‹4§H÷”f{˜]:1b±.7®¡ŸpDÊ·½n‡ŽozÖ¯Svɯü’_cDØÍþB¸òþB2ç/öêüÅÞÛ^47«Úì竾èBEÃY†ŽßJجeÄxøHq@$Θ˜ßzí²&óyÊy—û5å¬l»}õè(«ìSwÊ[Ë"ð®*…@MÝožBJ1vkè¨ÏGŸE 4=?´ ¿|²8 ž,¤y¿z%èa«zØúz»}ínôpsz‰(>‚ŽÍ2Åâö eç «!'ÀwŸ$gGºƒ¬ºv°Â=¶ƒÓY¾ýA„O‚a ¦®EßÈÌ×ÎæöuEr”AÿjNëfÞïºë›Ê¯ž[ã„6Ò.w>ê<Þå×}UtåðÅ ±±ü{|ê.åÚ]Û¾€Zµë~k?8¤q‚çvzW7¯.,TÈ^äcôu^n[ÿç¼Z¹ÁÜ]¼=µeWºÃ¶‹S:·ÒûÈ ¬ÿéSœZpÆ~›7áÝ&Òkç+=º Yfðj›•G®^œ½ ›ƒj³ÑŠŸ–Ño_ý (R³ endstream endobj 106 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 108 0 obj <> stream xÚ…VKoã6¾÷WèV ˆ‘¢^½uì¡ÝÅv±z¨{`$Ú&VT¤d}g8”-Ǭ!g8Ïofü° …?”<(‹:©ê éƒÛàþ#XšÔil÷«–%ulÛÂÍQ>Y5Eq–eaù[ !ÂíQá…'9´cOÌ!âe8÷¯ÂÇ(zyuPƒš¤§èßíà,;©ÓÎ wwÿ±X™p–£ýØ‹Ä\äN®Œâ¼àÞn™Ÿí=DYŠv3Žv3Fvqi÷2Æ4ˆy…FP»S+êê¤VÔõípPè¬ÖÉé®-)©Ã 7Ýl qz8Ðõ'ý8É镘ÚÐålT럋:mµìôuVKî×+÷Ï’,÷Iü~#¾+¤àÑÙ€ï<èý8õt8!Y°°UÏZZeîðè³ü¾º—ãh‘ËCªôâó)«û±ëFLÇ Š> €­‡±´Ñ©ÕÆNúqƬ$P©ªô <ÈM 9øçÔþ0ë΢ç9 ú9âE¨²'IbwµŠ»ºÙjWÐ8EG%šœCËRÖÛ¿|Ï€EÆã Yø§lðtÔöY7hóˆ?¯x9Ÿ; UñÐ`<Ç^iCS¶Y]U»èœÐL©VÕÆÃiÀ= Ê«S]ÔnÀÀ×.7þ³îQ8Ÿ >ÂV«2@†i ¦¤¿¥;ŸŒÛXùôëC3»d¸@]/BW¬8Wåç –.–Â?..0 rè–ûž¦\Krr¶cýéºdÚ™bsòÖÜ.eb2öø=äiø»A<,xqÎ:Ò7³ŽŒ•§x|D¹W¤Ù›œ æ¶!JÒ§ýðÊ|‡ L‹¬49Ã%jî¬~ê b‹Ý‚}tT§%1u°šq8L³r™¶Ô³ëe„CC@¦,õ9üŒ$±CáuPÓ.¢K“Ë^9)"pš¹r½½ÕS¡\XÎFqæ¾5õÒµë4ã1ó…„<V³yèö±™Ÿ h¹§2•ùíí‹Bo—z¾Zzêv(F‚ŠÄiTãá'þ^¸ëÑiÈ’ôâ,=¼YQÿY oÜWËð†ñL åa|ýåFz$ endstream endobj 109 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 111 0 obj <> stream xÚ­XYã¸~ϯðÛÈA[#ºð»,°AlÎÓô<°%ÙVF–¼:ÆÛÿ>U¬’D»Õãî ðƒ)Y¬ã«ƒ\ý¾«~bËU¥~’®²ãêç‡ÕÇ_äJ~¤«‡ÝJ$+¡ü4\=ä_¼ûƒ9õE»Þ(¥¼äÓz£µöþÝ•õ§´× ¢Ýó_5t°~¢ÿ½|jMûLÄsÙhôÛshjË.„ŒvÍÔ9 ~.ÿ~¤ˆT*OÆë¯y£•ˆ})B”7XmT€Ê ¼ÉzFr’0YBÜóŸ+!|ÏÂK‡“„xžH}¯6"ñSeOq%Ž5K ›\‰IP×°æ#C?‘–σ•-V6ûB6˜žebÙÑÿÉ´}™ •i«gZ6tÅn¨ˆz>5`6'ºá†þŽÍz#/*>½o.è]Ö–§~¢2õÆj†`Æ~0ûÂÊÔ@Ù$¬ÍÖ2òFÈÈ(ðò¹=Ù ^d="á ¶à˜qº¬i–ÉÖ(òÊ(Ò5  o¦Ñ®mŽD#úäBí§äýˆ€ò°N¤‡z+0ˆù¶–±ÇHž =‹‡H6¸äû:ŒEö/hk@´‹£“t–´GK<ŸÀÈh3Âyèàü'Ÿ?¦];f«® ROMÛÓ!^› vÎ^-Cøoª®ÁQ4¹)œÝ¤¥¶8A2miv41{² ¡®´øÑ[ÐJjá1HƒbúþôéãÇóùì?Á~ZÓîÄ*öuÄû×whèÄ‚¥8Ê O?§Uœø¡rÎLǾ~ÆuÍ@®éÍPåd4ôÿÁ ÙõÝ~à‡äw.è8Ú—ß1ü1zcG\$™,+:Þ€#ÇÄŒ™à@pÒPmZˆõ¸Üæqü¾¿Ú5§ æe ±U=É*ý"ƒý8=Œ¶j Ò—~—“™¿m›Áá·,ÙýÐÖÝUîùn’eB5N Ç5äÑ'Š™®ÛŠ‘g›o?˜|l^výöCña*»HS•¹ez;ô ãUű°¡Õw”X1Œh[êl‹#?VW8rÙ†~ ¯Q ÌfTºÌÂÄ—úÍÌFL»ì*¤ç€ó—° ù X € u­?µûµUµ¥ Ú97Á¦ßâ”Ö?"^@†~4B!pËÊ?µ­-ʘzÒØË²·)9sÀå®4õöEmGÐ,þqj¡dPþƒo›X3‹–Wáúކfœëú¦µ/ŒÛ+Òys.m…£¨WÒ±\èj³¶1ޏ`sƒš×¶¼BJÖTñ¶¬ýknÈNNMyƒ=§8º]‹7Ö…+Ž.äy!߆Äe•ðãô:bfxfdX]d,±@{ÔÇR ²æ6 p*øP;²ø@&DzëlµƒLy¿î{½dN‘(ï—òë—ÿ|ÝnƒÁc=÷wwˆE½òBN |å1]º(ª,qÑ–\°á¡]_>¯)Gö­Í†KÞ…+t< ÎýG=Z¾Pd!Öš !8ƒ&¯€CSBp$o…[ðpröõc÷£$Û8Œˆ~¤6Dä{(}ÐýØî±Zã(3Þ¬éò‹XaL Í+X<ƒe‹+Ð@‹ ^5z”ø±œ®áŽ<¡e£1ù=¢ÿû`*~=¹ÖÌ6p£o NBrÏoe¢7;bªÅ·|ñ—²Ë‘ïÉÜl0ï锚ah/ ¦Ü)¿FÞ³%Ƭ¬bç°à›ê®ˆ^‰T¨Ìò…ÌËzez%ô,dý ‹Ž‡Ò»CG×ÉÚ²Â÷…¬¯¦ ÂŠ—²ŠWdUnlÊëÁä#—!Ú„vEZ‚Døò½™ÛvcoªL:ÐseŠ­¹"[™tÀ7oøï¡¢v´v¹ëxa?®OâªíBÆnŸ„ܧ>‰È%/ãŒv×´9wT 3–+ˆH#û2ȬÀÖß…9=/Á† LNɉ&VÐr4Gô>vrJDÈc¹½Cav‰ÓW h|w$5§wÉÑ|Ù±:ÂqöNJâ+ŽŽùí ôDR IÒ¼Øéðšó•òµsª5‘¾•¸õk_sW†¥¸æ¿Í^u¶¸bö’mõƒév¨i¢©íÛ'L5œ1@~æÄÕ=‘8Hü$Ä/HÉ9gAr/!å¯`9ÕAÓsŒ›ÿc£GW™[±4¿žÆÞø‰ O Å`º­P´3è¨û“ÜýMüË7®öêG·Û¿>¬þù§ÿN# endstream endobj 112 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 114 0 obj <> stream xÚ½XYÛ6~ï¯Ð[d bDŠºRø!Ùl€^A-Š¢Û®-¯‰Õ±ÑÑÍþû9¤%ÙtW4(š#ê›™oÒûèQ/„õRæ¥IN²ÜÛTÞÛ+ïÕ{æÑäaî]í<šy4"yì]mÿò/öâ¾/ÚUE‘Ÿ½^œsÿ÷NÖ·ê/î÷û×.ÌPÈÖ”7­hqñAö{|úù±ß7µÞ.†ÉßÂ5Qoñá­lÈ…]¡9‹|–­þ¾úðò Þ($qìbóuHS#Oõb$‰A%RðýízýB¼0’S $‘3úŠ€Ã+rƒÀªBÔß:i¬>ЄDɳ¡TK TÅVŠšhÉ ã$¯å$δÌûUù1c®1ÿ¬âØåPtfiçÀ”G3@,Wj¡ÐKÜɸßm"|’J ]±%.£Q’¢ÕÒ¥VÛÊ®w@ a›ˆPäî¶€xmµ>PU½+êA¾êM/ƒ¶op¼Y,óÍ úkôLEÉóqƒ¯7._ÇTyæîMÓ¶E)>'áNØç! ˆ›®)‡¾8bÒHsÓ.Ç›<ï°/x³¨W,õ!k:‘°/hÅOŸeů‹±[ˆñ·{à|ꢭDýÂDm+ê»/íÚ»…(ê­(K€†âÙT<&5â×aÄ]©Te”p*@H|¦‹…*\›Rn¹Ñf¢ÿÙ 7 Ñ\È^±ð1¸)íûšÞ!!-6gÎÎÀÜXyò¥Ød-{)@û§Ò¶åáFªô­³wÌLгN6ÓvCI58Žé&*}ãÓNÇén—?á(ÊÛF—0² âúß¹JdÄ(áɱ>ëõ‡¦.Z‘rz¨—ºbó0Uäšh Hä5Ä`wP;‚Ä€× ·M…Ï£@zf˜ëj £ÑÄQgø«Ú½{ü[§nøWY¡i“˜ìõ½è:W?ÀML;ÔæË¸±í á0±Ö=ŠR’Ò©îS£s~ÆèéA3+×!†ºéÊ¸Ï¸Ž±©ë¬¡jccã”nß ¥±òH8eéú‡#!GçÒwfÚ¶B‡žšªÜ ÎNü^€‚àIm.šj sª€x’úc» M“¡ZÁço0p̵¥ƒüA  ‚#J9%–Õ¡Ã9Imo¨zóÓ ,bkúÚ€ëú_íìõJL ;“Ù™hvÂß²/t$òÄ¿i 3Õ´¹X™K5ÕFz…p°èÕÈý²yTÞ׿ƒIœøèS 16pÕ†œšLCNÍ»y¾Ú_8cãË*ŨñÀv³'†ÔQÇ Wðµi›xa $BPNe^¦|0nkÔ¯E?´Š˜)‡î,¡¦ÏwçØ”€Ô[W{iºâyûÛêÝÌ’0G¼á¾,œ´aäàNß‚ §!9ÇÍEŸiezéÚ'ÏEÛcÌHÂîQïšÁÉc PÂF‚:r̨³,²>ÃuÑ>-Œ38ÓÊxl›³•ñ"r’M³Wé`$:’þCö¬N,ÇéA-¨<­Æƒä!´ô¿ Ž{iÃÏ¢TÍn‹ºxUÉMÛ!zPÏbFpìa ÈÛúÜA?=Ÿ5Þ”g weÏ'êBÖÁ쾡*$º=ÍØÎÇFž¨'wÍ}/+áU_|tã¡}¨§TL«8ãëÓ:º Âá´zÈêäL>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 117 0 obj <> stream xÚÅXKä¶¾çWè¨V´ø%ØC¼^# #¶'ÈafZ5gZp·ÔÖcgçß§ŠEJb·z€ ͗Ȫ¯ª¾*2ú#âQ ?å"ÊuÉŠ2ªOÑwÑw?‰ˆ§¬LËèî)âEÄ%+³èn¿;TçÑô»DJßï¥TüŸ¡iŸqHÅãÁÐÜ;÷wœX?Ïÿ³ùÐWý+M¾4ãZÿ~]k·Ë SÓW4Wµ{jüÐtìŸá¥±(wwÿy³•¼J2% ôVä}3ŒU[;¹ÞºMû¾z}ˆïïS–¾!Ñ8ãohR0ùøÆî\æLê(ý9鿬ò_ÊX±Ì­Oƒµ°Ï²bùêññaçäV+¹í”ÿöh?¤WýHðwOÐìAk»©øT}óéû {G|ÖØÞv*,sËek ý-Ö°'Òߤ¡/QFÝgMûíñ2ÐðÍÿv÷<@‰|\ËõG+lçéÖ‚MÈ“ŒåÁv'yÁŠ_á¶­X‰7Ú•be|®šþ¥\_!&Á@„òêT}jN¤8 ¥ñêrÐWÏf¦§2ðë䨴¿Ûг¡{_h×2>™ñÐÙšÃZ7ê$UlE 0Ň#æI[“÷Ýô|ð7:ç§­¤YáI}ìY‡çºr|åýßþà€GR#àÕŵû °:„­° È¤wW€¤%JcÕ£¯Îçcc‰ Ó:´­×(í< úæ¹i­ÙñþiZC –÷šÙWceMTÄ6paÉ,ªÍy¤Ïа†Óá´3œškÃ$ ²-ÍÀºäÛ…÷ÿ2x *Ücµ÷Moê.’…@„UV,9º×¨"Æ~ª¡¾p]T³¯Fã\íe´¬,KÕ×™Y3íÊZ Ïñ¥¹»€¥ïkõ4†÷߮ߛ>|̹BQ/nàæhN.@ÜKeC½.xóœßh5Ìmî™ér yýò—ÿRe‡ endstream endobj 118 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 120 0 obj <> stream xÚ­X[œ6~ï¯à‘©_0ª‘’U«ªªª¶š>eóÀ2ž [`²ÝþúûØŒI<˦­VÚ|n>ç;;ú3¢Q 4ÊY”Ë’eTŸ¢×»è›XDSR¦e´;D´ˆ('eíöoâ›cu?©a“pÎãâÅ&BÄŒM÷NñtT¸vcÚóôóúÏÍÝP ¸øÐLG|úõq:ö—ÁK\¸Vu{|xÝôäÆ­Ð’ñ˜§›·»ŸÀ^šiÓ’jƒÓ(°f .#t“d’Å¿«ûAªÛð4žÐ¢\Ä•þÉâc£À°zÃ)<ÖU‹‹µo>P}{žš¾³j}7VšÉÖWh±ÊòY(gK¡à“Y¨áiFüœµLÆ“Ú#ëÙyšÇ“–ú ÿõ¸†>Äź­ÆQ/¬™g'ÏrîJ¿ô{Ø “$s$ÚýŸKa”0j)vƒ a¤t$$§D°\‡)aœ°EøÇÃSá1IAxþ´õ Ò˜pO¬Ì/>’ÅB…¿µ"'¹\õϼµº N÷›„qßíGT4õ¨dršoð}œ†s=´R2ËuµÌ’ìÕXͨÍcƒ^Ý¡7ð¤ _H€ãç K€}¾¾dgYü^Yë‘2")x™k8i’ce¡;5"0y§ ¬ËO?ÓmbºñíæíElšÞÖ—[´ìÉÚ|¡Ÿ<BH……ÓÀd…7CR)òd1nqîD9øÁ>[ë¾jœt´µ¤ïwÑo_ý¡D§Ÿ endstream endobj 121 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 123 0 obj <> stream xÚµWËŽÛ6Ý÷+„l†,V$õÔS$A‚&(‚pWc/‰¶•ÈÒD’ãÌß÷’—²¥˜'i‹Æ‡‡÷qxé|v˜ãÃsbîÄQJ“ÔÉw΋…óëkî0Ÿ¦~ê,ÖK&h:‹âž¼Üf½l]OA’[× ‚€üÝ•õFu¤ßJ{i~ª}óã–Ú¬}ÄÁCÙo±õþ±ß6µ† á#ÇU8–Õ6^” }9Œ°” "˜»Z¼¾áˆ¯ïx†k¾¯ËÊzö[×e}÷l†ßUY›6Cneß¿kP€c3<¶!DeÛ6í-N{SçMÝ•Ð_÷ØÓ·RB4 -¥"Öhoê¢üRû¬Âuuãz_H½IR³‹Imb»=>ÐB®?™´p“|+¶ß‘¼ìߤ¦f‡ãb43}‚æ¹Òé´¾]][£i¼l0C}¼ºœ­h%×ýƒÿêùŽìËžVÑ%áÿ…#žÀ…ÉA6p—AêB"÷Ä!²Þ\·zäÑvé‚NéõK7¸té"Ø¢Ò2’)½x4¤PXªÊ[7íNˆ‰°>F‚:n%Fŵb ¦¾°òŠá½"¡…P)U ú#¡"C 2S–ä‚exbà»<«l§qdæ(Ųè8£ƒçûÞVCÅ” Û¨HR¥•y[ª*ÌW GSÓT>ÎÒ¡{±•6î`ÛSñPužïî‰(Gâz_ç}Ù˜Bª•ý¾­;ˉOþSµZGÍ\ØöõS†Å•Ñ®%p* ôš„rÈ*/Œ8yï n!FX¾ÅÙ–êíÜ š¹.8¡7?VåƒÚc‘o¶áQBYzÑ2Ì›ÆLöÀCQp\a½«i2ÄêH ö’YŸÍß5µ49¾ËºOãïƒ,7ÛþÔ Hæî¡éäÜ7×6î1ò”ãb~³»1(\qó9þÌê\î²¾-¿jp£{ç‚r-w•ÜI’£Œ!Õ×eò`pÍ'Ï 1É.«§ý±Ÿ·›½ÚœØaŒÃL½ÎFXú,¶‹E4„š2öµc>oÛ ÑiŒµ8+k<ôá©Ó”l¤~M¥|_ZxJ`vÀ·Úi¦Ê-¨·²5³Ôü›ÙÐ×õM«Ú-VfÞ¡ì$n…¥ íJÏò@k›lDL

>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 126 0 obj <> stream xÚÅXIsÛ6¾÷WðjÆD Ü’Ñ%N:Óe2íÔ=Y>À$aÌÅáGÿ>|àfS6å6éè x¿·/Ög‹Z.ü¨zVÄ$Š­$³Þ_Y?ÿâYÔ%±;‹Fe$ö­«íµ}y÷µ,WcÌŽÞ®ιýO¥ò½Þâv}xviþÒ¦úþüu[Šòˆ‡ª>àÓŸÇúPäíu>,| ÏD¾Å‡÷ª —Ý =f3ousõàå#¼‘ÆêpàÇk!o\2Ì–GØ×$Ríµ!óîZðN‘÷¤ÈW^h×Bå í¸åÌ·ô¾dåEvÝxx»r`×P6•Üšw2ǧD¤I“Šº•’ÞØªªy"+²rBßµÝÍ0À€N'¬×ŸŠ\ÎðD”Œ¤ðÀÕØó–Òa%”9•Ÿ‘=æ¬UIi´,ªªÉä–̨ÁA;4 œ/UD]мº/*ù’.>H°‚LåR#r#[íôlï¥ÙŠí¢Ä£L%e!ÊR¬¼À>¶‡¡á¨ŒrÐ@amLOóªæEï…ñž`^¯Ý—EÏ(@FöÆ. ë¡Ú¬Œ68'q8æµ—ö+¬'XÁg±R‚>ÅJO`e#¬Ì›‘lnÀÒ&Ë5è±Að1¤9“ˆ]âÅhl©MdbÃö´A-ÕVÂUå €ú8”ªünås[ì¥aH_× Ò„í¦#é"ÚMßž .¯À¿^¿©Þ̉¼“·‰¥÷B•ª2èu`M¥ó„‰d«3býó=¯G™2_U¦ãD“9¸³AïÓ6Zd÷)8«Ó™Êä%9Ÿ—Db/ µ5r÷Vq>V¡‘~it  Ü`)Ü8ÔAì<¸:3½›O¹b—ÕÐÃvMžÔ Rê)'d œð,ܧ §Ä÷§rNв”:#ù»9Ñœxg†ƒ@,D n+±µ‘Ä—Ö ÓÆ,‹Ý#Ñ.Ç{®Äš…xA›Æstô7æ÷ÝP}}•,Æj!Æ¿ïÁæÁ…E™‰üM…Þyúî{«ön!Àße¾i Ð<“û$êŠ‹Ëø\ #nGñn¾NŠW² ²ð±IRµ•"ŸF¢ÿØ·o¢¹Tµ¶Â£s›­î½¼Cƒì°ÍPˆû’Ò÷e¢.Õ×—b÷ÕÁÔÅ£` +|¹-‰Cû#´mЂÍ|–AF‰ºïŠZÌ| ”Ý“ó—J—bØ ÜêP4évRÕÏ\Ï!ytIõD³äyCÁü\@#­†Åܪj¶:'!}ôg!áñ¤#È·s]‰Kúza‰ä<> q¹ö^a1‘CíïÅ.¦} Ê=´y¹nêY.Ààº'ÕÝ B½˜¹"è/ÀV¶š¹ƒ»ž½ƒ.h$µGò¡ËÑœžh@"þ|áãù$ ‰n‚°…‹}=|u'jŸ¦O‹(ºÍH< ‹ž ÅUv°2u¿îÁüi}m¶p(”] MjÀ®dåѸl_HÚ È§>2s˜q„4 Ò®,²I½Á'¥3ÑáÂTpM4gÕÕ"Ï‹šôXúà ŽçpJm8xCnYàÌs6ïË>ÃI=Š6\›¢+LãEÞnz8ý4ƒÄôf/1ΨýpPm8˜Û´‚ôÃXAå!allSæƒ2QºÜFeq[uõ¡”²áÚN"èßÏìi½IEè—ë·ÌÁŸ÷ÿ?A”(U¢gGz‰S=CÙŽ éé%‡Q™ƒ1÷pPäép¸©ÜÕNŠc4t$½eºž¼2|í‰u?¨4é5D’È úÍê팕Lû›‰ñ¯» H)ŽûúbÔª‚j|Â#ìz.Œµx=Puo2›ßÐO>| ÷ Ã[77fxô¸²‚gðóUëE\«Ö‹|›~ÀåHµz»SmKÙM‡ô’ǤmÐÑ$°Wɤ©M‚I¸mÌO*¼]åøßŸ·&0 OE8…Ž$hZüOš¤iÿ‰.øï”ÝéŽÛÍœRÇ0=KØê›áIe¸{,eÍ{Ïi7SÄíG‚àƒCý²»î„RB&am$۞ŽC‘`V䎯ãùˆú¦ÝþxeýõÓ7§ÒY… endstream endobj 127 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 129 0 obj <> stream xÚ­YKs㸾çWèHU 1ă¹©=ìNí¦²•Jm%—8J†-f%ÒËÇxœ_Ÿn4@äñ¦R>@w£ñõ×ðæ× ßðÇ7FlŒ®YUoçÍ÷»ÍÇņ¬.êÍîaë —¬.7»ûfŸŽÍÓd‡m.¥Ìªo¶¹R*ûûØvØ¥²éhiì“ÿ9Í#È/ãj÷C3¼Ðàs;©õóËtì;·\ šEcMwOïÛž} #¼2“rû¯ÝOÁ™Þä ,NÉÝÑŽ †¨ Ðg°¾i¿< vÛ¾±ƒg‡~€Ž'üÈzÜÄMèÃDKRcsö Ü·ãÔtßn¦¡ýÂ@ea²ïF§ÈÇËÈqR(&xuš@`‰Æ>ÖšÚKž›-¬øâ¤rYLmr8N0qt¾+¸AOsí]Ϋìó¶,³æ4Û¿MÖvÔïLdv“4ÒŒÔ÷Ô µúYV?Ä'‰SNýxþß‚g{çG/<΃ßü‰†+œ…Ÿ·^^ Ø¥)@šaðö»gvSÜ·`¸´ƒíPf"°çµÍþä—óº<ôƒÆCs:¡æ×‡$”fR¾÷t8Îö~A=ú™¶í¬½'uÛ‰†O ,ÅüZ`=ø ¨9.†b¬4›\@غ%ÿj§y@s“4÷Gy­úÒ *ëè9¥Mö0w‡ ¢¿ªlp«ôÑ$ ç¢`Áî^’ëDÅ îEzð)„׿ía‚˜¯Tµì\јvcÔqèé|š¶ ð"Þœ^…•»ù¼w½÷nm'{N]© Ž@øy9‰ò”â RÞg};~ ¥ ÎêÕ•z>Z'¦ôÑntúël>cˆîÝNCp‚iHMÿO6‰Éz™üh;&_w=oݯ’G{÷¬‚5†[»·›Î|𮮜ÛY”Ù¹= ýrÇFêt:ÀÄä`¤ˆ´AàS"û¡9àø‘FgÓzàôÃÐúË8R_C’OM;<·£„»ù  ªÿÙíØ¡û¦צøãB ^@Úm\¹E%²fhÛÏ““¯X"ÿd¦T•¬6^óO7 ¦K/1´ÇÔ*’3¢Ü¢£*t¥žå‚¬ÒHÇNÁD¾ó6cÄ|ŒŽL‡œ! ð•^>ÆL ¹lÞ/ž‚pR…¾a]%˜ ùhÉ×– öQ8ÂQ’©E°aBõžà[„¸ÚY|† Ò¢Èþ€±ÿñ:ú`µfð %übIs°S°reïÃПSgV²`T‘°¦f¼Öô©Àqë“À]–µ’ñ?¢š|…jwÛ4®Ua„^ÃmhO>Õú»9-hB¾í¹Wæ)ÁtðOž‚U®XÍßë¡<í"Ι*oúHÝö‘`u½øˆ\h&L|îi¯Å[¦s1I\RqÅ“˜ÓDö7 M€Å ý[ $ö°•4aœröŠ a.¤úMØ®v¾)8¥UÉLQŽ TE: ÃÊàk6Â&©ûçË!‰Çt`[/ájChÀM|:y`p ’ÕbQq›ÔÇÞX}üûÓìé|UWÀó~òä­tXŽËžø†ýGkŸUwü§9†àÉ!€£îØ4Ûíâ,sM h×`e¬4¸à²Jž…ìƒ_Ó±™B˾Ðw °Ëg¡ å/@„#ÿ±CO-Wi`0 ÉÀ!z’£Bv´äBtݔá??ÚñhïÃF ¯, ÔE;¢åuŒ—òBEo9`¨B¥`¡j"ÿøKØrGßö ø+Í{94¥þ ÿÓ¬,Sü/q¯s!…þ²B¾í ‹ ŠPdßeÉ{›“d\8 ôšm™8&¡ê¨{áGK¸ëËm-_ÝVCÊ:yTÚQÇ1¨ü‚/$AÐjŒ Y׸‘æ`¾‹®«`XjZŠ4 «ÝR]ˆ¼ •æLJF_cô¡NzœÏ¾ ?И_U-ä?á|ÙEÌŸ‘K$Ž=> $^ŠZ¡%0ù‚˜ŠóÓL®êG ä¦Ô¾~âÞWôJëúr® ¦ÁÈÐëÄ„Q½Š¸à ˆ/›d0%–vïªååÛ^T®H¼øwþ¾IÈ]Á*æ'øBÅ>Ð$ù¸Ô SvWH±Kf =ZÜoY\XOÞ)¤fµ|[',eótÅKå«û\×¾ÃÆõ êzM-t\aœO͈"?÷—·¯µÅ9ö®dìšwŸpn \r•ª&®P®y% ü|º×!´U\Å c_C?—*¿–*?^U±¹22T®´‘¿ZÞ¤;åÛu¬‰ê•[e,Ü0ýv+Щ_)c%SU|ö¡pÅ´EXä‹  ³Gc¼$4Ö“DÀ2ëý¤¸RY ÁªU÷Gÿƒì‘^(ørÇɸ²Ð Ô,?o”*PÞ–òªVK­bO aJá)‡üRLÑn€÷î­T.Elm_·‚ÊûRáÁGn€b¨BO¿7J/8ÇSå雿@¥o–Úðn˘㳞Áª1[¿BÁò¾••®0—¥ÀˆhéLK‘|ý‚oU¹¤ñ÷)=Ê’Éw¥G wm<öóÉï~yô†ÿŸ„±ZºüxÚ¥ö´ Tî:’(°ÊΫ9PýunNþ€a_³z¡ »üw%mµT¯Î’ØáçþirIp¿õùYFÏϸ㚵.ÏÏ‘Úñã~òºAT˜5YhÙê0^eïuÖúU%òždüÖŽ>51D¾¢ŠÿS¡ ##%"°µ¢N¿êá"‹@©Šåß,¾·§é€K¡ ËÚ&þJ½º—ÊPÑ1Oü¦}ìð~Ømþò»ÿ¶C;à endstream endobj 130 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 132 0 obj <> stream xÚ½XKsÛ6¾÷Wðfj&D|%£Cã¦3}¤iµ—8˜‚$Ô©Tç×w J¤MÕr&éxƉÕâÛ÷.¼¿=î…ðǽ,ò²´`yá•[ïÕÂ{þ}äñaá-VÏ=³"ñË÷þåFî:Õ΂8ŽýüÅ,Bø]¯ñ“𻢽K÷¨öèû?ëëV¶w´y«» ­~½ë6MmÙ%ðRÒ¯hOÖKZ¼Ò »ìwxÅ~,f?ÞØã‚Å"E¼¡&²xsÏ‚$üwªZoÛµ¬õ'B“%þ¹3/ ž xð"f!ªy˜fÛr¤á@=£…'ãt¨£ÖKGŸ ÈÎ’Ä1~6ů`qêöKUUKÙÉ)6!«ÙÕ `^ùø«g¤ñ­47ó_šZ=sJWz½é†_ºVÖf×5 QÀ9gi Ϙq²{ýq òÌ#÷“úξr÷ªkÝur?Yx ÐÄ©M7¿PW3'ËÐÁB:(µéí®R[UÏ¢Ìï I&‰åCg0!í6µsúÞª²“õz_IçF˜õ OХ»ã#ÁR’óÛv½ÇÓcާµ`Í1ž¡zþ*äÙ„yx„ É< NHÝÛJ”£Èü²!ù%(Ö ß(²ŠÂ_«Ú®r_}ܵÊmE‡wguÁÿv£ZG…ô†–²ÿfº¦UKZ·Í,JýÛàVEGQÄÁÖVùkÙ6rì8fAxZ}ÏreSí·µeÍ&´žž²„Ÿ«Otè'è3ÊB¿Yá3?µàÔZµ†v̆¤·jÆ·]"Ñ_9Ï®¬îÉVÌw  )è‡ÕÜH@ÞÉxßëïÿú0Ÿ‡À3ÁDzÈ Çm]O°CœŠ˜Np â41Š_m( à!qO‚OÆìs›+&ŽI2eGà6• ð~e B‘¼sB3áRH2í± `{ŠsPv{Ì=ñz}Ý1n “8t×ï6´yMnN/{ƒdc¥ÆU)«RNg¥Ã˜ød]*Ï’pZã1H øH‚“JOócâÇXOã·qÎïÙ]ý½—•Kü÷%³Ù²·4ßò‹E顨‘Wä‚X€gCYÚa…÷ÖSÉC¨>ü!V~k<ŒÍhB{ðñÊ¥h=t1„4åEÈ¢â‰>AMĨ…xÌ;¶êå‘ov¿Åÿ¨¼Ô·í!äJÌíøÄfÉí¦iõ' ñB¼ª°JåÜU5 üÇBÛé²ß´•Á>©ÊѸÈ©@èEB­jEÿÛÕr¢i‰M ¥eqÈ_0]Ovž‚¡ëFzms…HAE äíjïöV6á;©;ÙÊ­:¶ÄùE²´÷Ó«ðФG£.7Ë{OÞÈÎA0Äœ2+®¬Y†ç¾{û†²Zƒ•»Í#”¿è)–j%÷UçÙJf1ì/A²ÄIEÂJöP"BE?¦G¤=•!~®ŽyGj;‰È¥_éÈHÂ(J¬„øås%©*úðz¦ú•{ž/fÖ5ÕŸZÝÙ®mÖ`ŠI·)2–‘ל¡úhÒ“-ú¢Ÿñ1™Û˜Ìü~d³1 nÜ 6µ«6]3JD´s?SœQ€Îð>&ÈR#AœZZôE›ð­öuÙé~¼˜!¶æ|qzZxJØÚIi~Q^L5\ƒÙÑÞeÓ¶ª²:~9¥¹T°èéŠòLòÚ@éœ"ÑuôƒfχûT…íÏÄ Æt#Š¢ ÈN)_ ÕÇÏÒâÿ‹Ñœ‰ñ TÙn¥MLvÌ–õÍ×6íÍ™Rõ*ú…™¨IIÂòGJRz¼ñy9„€â3EPgŠðz_Vz©d=ND_X¡×g¢¹Ô¢ƒëª±¶·%ꆲÇ6y§‚eÉðbåwÕí[+%Rn³„9‘¡3– WjúÁuœ…[Ëmœ·aLÛï*5u§Æ“¾oÿJWs£¶ caßÛLV³ …5]žß7Ý÷Àv÷‘Ÿ¾û¨i ^ÒÀ«»l…UgÇ¬Ú Pnp3Mu#i~2Ý}ãhæ¦5œ}2˜}ˆ¡vƒ[?}â¡Íˆeq¢yÊf4>h¨±>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 135 0 obj <> stream xÚ½YKsã6¾ï¯Ð-T•‰dª|Hf2U»µ¯$Þ½Ø>p$Zf"‘^RŠí¿Ýh€%ÈÖT¦R: ÀúõõC‹ÿ-ø"ƒ_±0ºdE¹Xí?Ü,¾ý$÷UÿJ‹ÏÍþ‘Fÿ~Ý?v­%—ÃdE_ÑZÕ®iðCÓ±~…—B&2_Þßüm!8Ó‹TÂ^Ò}^¯Ù25™J~¬VK¡8Kñ2黥0É3MV]‹³}Õ´¼™å‰~û© … 5Ó¤…ô_܆™”`ä×ñƧ$„`ÜïxS(r·¾ê–)\«ë×M[íkwµîaº¢¬êíG&WͲÂÝë¶y¹¿m^ï#×W3~²* ·nPéFÌ\è5O*Zåéù;n\A=ãrž–9¢YÓ€ ?«_žúz@?£ùè»)çŠ:äüÁãÊ9«šé;R^SÓ–)\(‹„³UnÊÁå<òX¤-B¤Å£sšV¦Xî=°y¹jb0Á(W£xÔ“ `U*mQO*ƒÁÎõ«`j™æZ$ŸšvMÁÒäŽL â"3Èð¿§ *gmܧð}± ”öCHe\ÒG¨¢+' ]5üFÃ뙸G’wɸ]%¸ûúŸ][_Í67ëð宆p¿¾þ¦ú†—ÅÌ»pît¡xQ¼îÝ.ð8¬ü»¹^Ó“"<§ÏÍPÓQ”v•né©’Žƒ¾õr¹¾Ù9—uÀªÛv­%ýÅIÀ9yZ£¼\ž£„z/Woê~ •ᑸw –…éB™Ubï0m× ˜ô2 |2ùëCäº wÌ ð¾·Íýí¯÷××YäâF15E-£5å6BVfLFED#S™Kôç@ Íà…ñò½G/¯s–Éàî×Ö}#Ç䆉)ññ>8apïòE²:x×v³KÐ*r· çå—Lj9ïYÈ— gФÔ.²˜#Ák"Æ™¾ LÙÌ3e„Ê*\òaÓ —l»v3 .ò<® qBñ xËs&Æð4ÐÚnïÒ·Båÿ›†z{5fùNoÅIÞÙ§ó£B‡@rV7È¥yA1âòPíæýõ Á•÷TþË“­¬êU$•MzKÔb¶JJaJ ¼BšdAÃvaWW-â•BQ`Þæc\äJc&lq8ª›Ÿg­:MÇO+2LŽÛ]tX38“(s–—¡tñFÇ{¤ÇÓøŠóõ´9fï)ôc Çî o™±99>]„̨,ÁçI©šþê¾%ã†A˜²ãbñЬ]KAïÆR°L3|Ø úàƒ¯ ff¥–-©­èKwKÅÇ[Ñ5UrËÍc?l¸óÝSÓTé3œlVÈSNøNDÀ‰‘Î~÷ÞT•¶÷aùÕ!Ì g*\_gáË;—` S¶=KíRjazGéÚÏõþÐãýŒ‚’FCTߢ%_&y7>|>ÚÕžò-˜õ–Ú<ý?9Ò¾`ÂOMŸbjúÎM©óSÌú:B• 1°æL_(¿³–Ydã! Dè¦ qmB Äè¿¡ žeŒ›·å•硼rsŠ>"ŸI¶„gl/Og\;Ï8¹stËQ穹¦<³XZò¬ƒ@e©#})\žÎZÏΰßÌ;⸅ü–,ȱȫ66SÐc …ѬÕÅTôfÑϪëa;Uo{©Ç¦Ç- áT¬’®¥#ûÇjïúØa'ú¡;´_³ }I JQ#P1Vû¾yÁ±¤Ê{ qP@à¶ß—PP@²ó¦Þ²?Q¼Ë2gÚû¼½öcíÇ3T®3ò~Ä"L0oÕµ9Ÿüè [\eX×νZ 9ÃÕ³!òøð÷%¦PS1¤Ê°ð-Á+mDQåüœÛÿYJå" Ž‚ˆ‚tâE`i^~9"Næüb•ÅÈòû˜¨ÿHÉß‚EÎYâ¢*ŒÇ/UXüÒ„-ªÐ³8’Óÿ‘3e ”?7Ž”Sæˆ.Åyí’¤ã?>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 138 0 obj <> stream xÚíXßoÛ6~ß_¡·È@¤I"õ«…Ò¬¶ÆfOI‰±µÈT*ÉuòßïŽGY’«4r–ÃPˆIÉûîîãñ(ë“å[üùVXq”ºIjeëÝ…õãÏå{nê¥ÖÅ­å'–ÏÜ4´.òKû|-î[Y/Ƙ¼Y8œsû¯¦P+âv»–$;7?å¶ù{ù‡â¦õ# wE»¦ÖíºRz»:­"™P95Þ•{ÞIü4`6‹×¿^fùÜe«WÛ ì‘m3›€&ÈuÇ݈æ_y~<?p£ÐÄ}ÿ´É¡Q[ ÜOc;«öZQ(:0F^HS{%•ní÷µlš¢RÔ7Qæ~hïÖ²6³p~CMÑ5mUËœÚuµ"{çìŠF’*:T ÚŽF>šՕÀŠE] ïyC’¬*·¥·v'¼éŸ?r®?‘ÀGø3ˆ=»ºÅßx«ÁÉp$Íš¬×nÆÝºÈpÒ»>O·´ïp“MÑ`JsÁÑe~¹€ðÄeñïeq}ù÷õréM¹Ë»äpŠ~ÔŒWÛ2ÏeRѦ;:,O°Ñ‰5giró$ø(t=6À¾Ô¹aBM»AÜ7GUí[šlOˆu0¦ª’¢%ÓÜ`œÛ1ä lö=ç ü»«‰³ÐdØÓGÛI+š”Cmƒ'H¯ÑVc«K]Ú:èR¤'½i3°€û# žtz”ôÙÏzäõlqXâÄ]~ÚŠÒ$úCËôýÙÅF4 $¾üÕN)]"ÏBÓ’¶Àf—à-ø"Âe@ŽÇ8/2Ó` ží”Ù²”Ã," ˜^Vje6c:¤£e`¯÷êéÂÀc'þŒft…Ç—ñ °K•˜áU:]Cc¬»‡ü¡÷XìÆ¼sßT¢pÙ¾ˆŠö4¦Q§–x Š’\N@Dc´x$©-èG»{"ŒX—.§ ”ÐÙÐQqÓÔˆ§ÒÓ`5¦ ÙU‡Ë`í¬äëÉ:‰‰›$#BM™Î4½S¼Í_@ï`½ƒˆ¡¿ñ‡è­CÆ‘a" ÷ôÆŽ¾º"ÖKÇôÆ…&+íé­§WË :s£½gwà#»ƒßÙýݦœŽÝï)¤Í?®«Þ—-Á¹Em^?GPµKxÑþµSŒÃ¢=½_ßì‡9f€+âeõçç¬ÓÈ>û¬+ßZ¬°r÷ôÍ Pù不`o_½SwÚ+(_ʸca$û[ýÎ$¯èb=ꇟ(F>‚—Pp¬òþú{2ƒwyõkZ¸}»UYK˜)œ{ŠPßB¯”›õ—£åI6ÙÐwÃpL鬪k‰/®JMÒ+×½ ˜‰@Ü4U¹m'>/ÂÐåÖtõëdèÚo‡w;/DÓPUÒ7 ýf.ª#A=¼È‰ÿⱎkfbìêQo„:1%J-ÔÝ·ŽìÝL€¿I•‹²<é>\&Ãé!êõŒfÆ'+I¯›ñvú3Ìx¡ r¦ ï·YYäR¨q"ze‡ÞÌDs^è\ÿèÜ”•޽þ4xG„ì°QÆ~aýùÃ?½öi‡ endstream endobj 139 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 141 0 obj <> stream xÚµXKsÛ6¾÷WðfjÆD‰_Éè8é´M§Ó‡{²|€%Øb-‘IEq}w± ªT,»ÉxÆøí»ß*øð †?d"ÈÒ‚åE0_o/ƒïYÁåmÀó€KV$Áåâ*¼Xê‡Î4“HJæ¯&‘R*ü«-«;œRa·4´vá«M ò»õ_Ê›F7´¸-»%~{ì–ueKàeN»hMW ¼-kvѯðBÈPf“ëËŸ¯òðæˆ5R °g1ïÅ_-ÁÒÔG‘®ÑUûP·ÆÉùêÇAêsRÿ¯ËÊ´)ÎÂò–žw¦24ªz®ËySë¦Ñ‘…¨oœ†N-·W7nËÍ$yhÈFð>¯«¶\˜Æ,D¦áO·#ø%W,‡ L§ñˆiÎ2éDÏá#\ £*+É\°,ñµÜ"fëÇ¡T|‡Š`ªØ×–ë[z¢%Z˜…M'mÛÙ5Ih"„`\þW~Dái¢œ&öÛOâ¶úŠ"fù@_O3« <‡t‹38oµYWV%‚‡ÀQqÁ_$8Ká¿bpmðì?L·i_¦ÂO“”‡zµÇYÆRew].K÷ÁÛM5ïʺ¢·Æžæ–Ü]Sá¢l;]ÍÝÍsáÔYÓOphªÁìÖjšè-Ðë$ˆ.©RLäLr ,gé$JR^èÕ|³Ò…C–¸Ãaà¡·µîšòó«ÞV™w°H:‚œÙï"ù^<ö 9y¸úŒÓÕ.GÁDêNž’ŠÃÌÂ…îô¹ó´nï§¿Ö•9'{nMy·ìö3Ò‹Êø|ÜôÌœÍ&#¾Œèû^ˆ9N8Îic!s¢èS ȘÏiÛ]p F£AS@É›æn³†Ã$»öhúÄP”§¦OüðS™ó— ›ãð­ÓeEsd–¢èU,ò¡Šðxn—¦qR}ΡîçÚ®†JcLCi¸¶ekèSTS`i]FùëAæ£rHS¢íyK+”ìÑlÄšÙ)â)ù©öÄx|†=EÛ¤%2–ÎÜÙt†+í’´·fÆ‰í²œ£Ð_99ÏŽ¬íðuÙbEÇœ Evò™$c"óª”}µ¡Qãn"EÌUõ„KÏÞ½ƆTtÙž”œž ï~µH"3S2qUÁ´Òõ«5-º¼C/›oÝcµÆÑÜÏû8Ñç0¨Q–ÄÇÈŠ`Š48jôƒ¯Òx@VøßÍÇ^9>y¨™¥½otÛBâ[|µ[úBÒ˜;ÒXìÒ ‰5æ>çH‰sì‰bq@‹¾j™'Š ”JNç‰>»âj2w|.µ|ÎyCAg¾®;k°îa=v1y Õ‡ŸÎ}N+ňõ`Òclƒ€P>¤±š(ŠgÆ^†§Âaaà EV=FÔïëêUé¯ç«ã<ÅÜõ ÜÓéÙül, r–ôr®á›×Mc0 ÔÕë1ÛQ/° Ð'"Ð7-xµs–ø4IK¬‡ ~gÚo‡ws"^ð¦ã †h‰¥ß ÕçYñÿa|n¬µ'bü™¤uݬuuÖÒí€Ôpÿ­]{"À¦ZèÕê¬'Ó¹/ž°¼Ïg³Xª±<Æâ^âõxiJ±Ï‘ æDÞoæ+è‘u5ÌD_Ùã7'¢¹(mÛóݬjë{KWï) {lãÝw¡ìOûnç‹í÷‰mÏ  òt¯ýô•’9Ê !/øƒ=VX!ìÈRv‡üð~jÀ÷ÃIÈœ2nÚ í;G\¹¡ëÒÙJ½ë›©¿Â^åè÷‹•å®–]\. ±°6k<Û}¬q,æ–ˆ‚+¸4YVô4ºï:PÄý2ä‘í© mÁ‹fœlØ! ÏR@`AfáŒb©‹ÜïÅzÛ¸Â<(ÅûC!²–ÚUäLS»{evížå-2|SõÍ·^?¬Æ Žríþ®8©]q¨ìHX9Xé³ָ°yœ…W׳ɹÝÂsÌ(NFœídâ±õŒ¹Gîß_¿÷/· endstream endobj 142 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 144 0 obj <> stream xÚ•XÝs¤6Ï_Aå%Le‘‘®ÊV¼®Üݦ.UÉ®÷î!Þ™‘=$ ÌcïÜ_ŸnµÄˆìxk¢Õê_Mð¿€1üx‹ —%+Ê Úïn‚‹ˆ€Ç¬ŒËàæ>àEÀVfÁÍú÷ðz£v£îWQ’$aqIÏOCÝ>ÐrÜh\¤á5½_7ûè§ïÿ®ïzÕˆæ©7´ýëaÜtí¥{©èQ©vMûïêŽ]»/‚§Y˜«Ï7?ƒ¼™'o^°"¢FfÕ÷êpþž²7ÄH¸…dŸoWŸ-_ç(K˜L‚ç¤øÍ¦èPÕõ½v Bvíz )Çnf€$\×èÚÊšc«Æ¾þboâIP²ø£u3¶xÎâÜܪØle©Ùzç¶2VóÉ:öã‚°"q4ñ**Ë2䫈Çqæö™N7Nêr¢Œ-EbŸâœ2'JGáNÈsÊ”(ÅDáNœ[%µd‚º¹çÌ&×g6¹>³É•e*w"ŒÀï.®ú‡ý=ÊÃÑY.õx."%ùæ6æù‚x\0™½,Ý ÿW‡ÐL4º“Œ¦êÖ¤GÜ3FEJüÌ í‡Ï§M]!ýæ„Òs ¾.9éNA*÷tÌïÌË‘|¾^¶¦àLú¶ü Ç}ßR\<®$}8žš,šÚljÁp¿o«±îZ dfѦ,~ö»F;Q¸oþÄdøø$|®–±¥z³ÄG2™O\(«»À[à•A '¯f·ueÂúb‘£d©x%Gñ+pÕã*Ëž55””¼8‰ ßè,–rpˆt)ЃøÜÈÆ_´ñsHÇ„pŠôY:0ü̪[ Š!{:¨•ƒ<å?¼ŸÖu»”ñþõÉbf!%Ë$F|…aþ6ñ¼—ÐN# Õé ÙáÞ¦wÔ^’ö"ì;4Ž,ªÏ3H—ÉßXôsb»ö xS?†¯Æg²öÎÏýé)´%@{Ñ ¼Œ™H¾Þ gÜ_mÓݼHUgùðAÍõ_)§ ÇÃQ¾˜ùÎåôϺP¶ÑÒOþ€þò1Ý,X¦ÆûµúC—$¥é@l³d$ã1ô=]_? óúB}榼ˆ·$Å”o½Šn8N导ACÐk€ÿÚ^gS‡ùX©¦‚VaD3,tR¼„~¶øÂJÁ¸K£ß“Rˆ‘ûÞYwãm¸tŸ9¼Îléž³êàó)±¯=‚œÚ¹.Y}..öjËÅI&›u¹<+M+' ×aÂXD]î¿`¢jVØäÒDuq³*±ëÿÔú)±7:`ó£›â!mžÅ÷ÔÇÙ»U”æÆ0‹4üç§÷ÑÐßi>%Á5âßï»Þ~ðfG<ñ¢é‹þ²ƒL߀ï>¶Š ™"ŠDþ„0Ò½>D¾¬O|O}=Ž+ D±C_’¥á/5…šÒ müTŽnÂÉ,"rÉJç·Í8î./.zÕ*ÖÜ5ì¡{\œÑŠc®&‰6u£i©Fºï#4Í`š5½}jëGÒo¨G,™´·lQ:¤¯±?RKédL:2›ú°Œ™ƒ•Í@°K“8,Ð`Ó.µªHì b¶Ç‘ÜÜ6KhösçÈ4†+£sWm‘Iš‰ÐܺªñƒØ%¬Àƒp°CDÀ|ù¾%’êÇsIãSZpô´DO§Ó¯<Öà]Ñ™3S(÷•¨¶|¢g‚ƒd »½É—Šø›\ˆ§§Tˆ/ûÁ)†æÁçc=ìUSÿ_»»ôK‚ FeþÁ é&Ȯݦµ»ÂeÒyÇÖt¢Šð£j֪ݨïzÿYQ[†Žvæ¡;»¾{èÕ–^CÄ01œÆ#0yDG ݾ¯4˜ìA³VKaR”SŒàø›K;a%4¨Oʯð”ª\g¹®‡]ãw¤›Z÷ª§ÓuEµ2”mÀ(s4¶‚*—óJ_ ´“èÏÅü»zaErü6ùmiÖâr¸?lA¦`œ’8Vk{¦ðÎH±œXÀó/8§Ùqˆ©5,eõˆ#½ð§¶+3çAÏ …Ìôu‹¹íXs O\øLgù1öf¶™|³¦¡8ND'©*dz¡Kê–‚ŒÆGc»ˆ>ÒSÑc)?D”8mb!ñ´`b"›Þ W!Äd,(¤;ú`îÅ¥Kg°˜ DFi12âÞžrwI{—cEOµô ´`<}…A3×ûxÎÃ8*K ÷£Žý0Úˆ‚"ç³ÊiÕÚ)Á5³“¸/ô­ù:ÍõÊþ‡[— ZĦñ¦âíÛ·–Ú£~<ýKø,s!ýRöÁ†G/Y¯dBÎÿ!ëvº½ ¿ÝÐ÷P…ÙøeüÖ¶`?Ý¿}óñTú$ endstream endobj 145 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 147 0 obj <> stream xÚåXK7¾ï¯’CZÀˆj>úeÀ#^8ØÝ<0»—L-‰’h÷Cé‡Ç“ÃþöT±H©[jÏhv_‚¦)²š¬úªê«bÏ~ñY|–ˆYg,ÍfëröÍílùFÌxȲ0›Ýngvl÷ÛÓžb¦F(u5T¬uEÖå§#Ü‚3ªrûq©éBRlžÉ§ñì›p¢Ã¾&ê%¢ê³!JJ1x8X÷]wx±\b<ßïu£YÝì–c¬Ÿ´$ “s  Vo{Ýhg¹ÇãÈ}o+L#`‰Jwä¹ùg /‘È:+€/MJœøYfBs!Xƣ̑di:L‘·[:ÊåØWþèÞ³µ0ƒ7y•³bU°]ýa ¦YíÒ™rë­8l¶S„íë1ð!Ë€V¢:Gun-Œk „/™rq?GïU]µ¹a¦lY¿èê÷5Ë×ìÝaùßr£÷u]AmÚv÷y£—®{ôOù sTžþnî(^B2 >¤ø¯'ôãüDJ? énÄ«üEÁ;½îˆimakÏÊö.ŠÚöœÇÒ`* Tƒm; Fµ5béHWˆñdJ]ÁbOj6»/• ÇM°Õ)vT€£¼ilÛ:!ÍØòëIç:ÿ‘ ކÜâ÷ƒQ‘ þB‚övâ§‚ a±¸‡T¸¡©û½)F‘OF—fÝÔGýZªŽy3ÑD¬ë¢/+»%›Â“p‚Z+ñ,óöýÓx"ÄéFü 5ÜZiW#4ˆ€Vu¡KmɧsÈÇqš‰ê¬jp(^éã~†úç3ë¤ .@œ$q[:€8o¸bÅ¥Ò´ØÜ€yJì€&·C•Ži´}ÿ³¹y÷ËË—á„^qÊWCwc܃ñµž³xh¤ÝtbGHádïtP–Oº«XQó³UMOíÊó…P™ÙÛë1Öu'êzÍÑ®7S.mSùx¨,dš0• Á2ŽZíú18w‚%9“~ïÕ•¾ª‰= ù$ÆOÏ yÌo³¹.è-¹gî/1­³Ê²H2dá…úÊüÚ»w¢Ê†¤tîó_õ¼µ>0L3w9ûþ§74°”Õ—sðÜŠîMë‰ÿ`<¾ÊK}%0Bþ™ÓÃ#Ô%½ é…Æ`À!F`À/†‚!âÁ4ªŠÖ/äšMA*8 ·÷Ðñ¦ºì9޵Ë׉ӵøªxPÔ ‰#¦ígIe?rypu)ÝÝk³Ûw×USèêˆUàŒ@¤tœìöØ7Il'gI&\Ò¸âmÆËp½]÷EÞù·öNrcð£ÁÚý²_˜`yTйmªwmXv„æ?zÁPO8ýÖ2ú 鯾2ò>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 150 0 obj <> stream xÚ½XY“ã´~çWä­ª±Æ²ä ª`n Pp›§Û<¨¥ãÛ^‚lOÏü{ÎÑ‘cg¢0IP]Õ±µg_V¬ø*‚?¾ÊâU–,/Ve³úænõú»xÅ#VDÅên»âùŠ V$«»Íÿ‚7;µ´Y‡Bˆ ÿrJ)ƒßúª}Ä% ;M{oÜO=öpþ°ÿcõ`”ùH›ÏÕ°£§Ÿ?»®µäx)éí©vCßT{3íð"ŒÖ¿ß}xåoŽXC üÄò}Ä3w,Y²³4öñˆî̈ҡ%ïÑ*Þ9ñ~‡¼I^{£·Ú ¸dtÙ>V-ý>ïªrgÁŽ.4Ui:eŒÂµ=-ö»n¬‰‡uç#ßÝöDP¹ßnöã@ÏÀ˜¬5[‡Y$ƒw[ºÜvƒåã9îu‹P”±%‹"uê’ÁF Š–ˆê+ŸÄ¸d…üœÈDîNT=ìõà>ÖyˆJ΄p7~êZí¡Ǭàîó(<ŒcP¶†3%—ê|l«?ªÍE:·\ “£ÔÔ@b{F™ªž„:öÚYjÕ‚‘ª é¶´øÛOï~y÷ítàwùTþÄg˜²4þ8Ë Î×[küI”u§6¾(³9grÒůº}ù´eÝžu`…Iü_—Ã+|âV“'QjÁè^»ï –‡qÐ=¾çA‰vŠhÐY iU•¥î­pìÖ=4µúM³\¤Lð¥ôQÖ’ŽV\ç1XA˜GQð>w†öõÕìÑpC «V°öš¬LaÃ¥ÙÙà¥îÃÁ¨¶ßv¦¡o 8~JõdÅlŸwó-e z5t$C¢åÑ9C2K ,Õ$$édÝ­Çr–ÊO<èõ<] ó– {&g9‹AÈiü¼Q  rGö›É`WiÂåZpx,UM«åªÏ0“! ¤?­=¬ÄË'G½õ)fV/“~ÈẬšö]¯o£Wä+†´±¹½in^¹0VõÃí¾¹_{¤fœ%b©µßוvqÊJ…ìÝ |ºü$A [ÎÙqA~EXUµâ#7÷‰+ŸY=ï¡ù©{úm@ðéY; Ô÷µyü è¡?›*g½^6Jø\äüVƒÜÀæ¬x!T£"xÔn©°®‹[‹ô˜Úô(0LM§œ»’ àÝ©Do H‘bæóÉ6eñ æÛÛÈ;ÍQ^tíˆËdܦC\Ͻ3ªPHȃّg GXáý«”~¬<Êç·ÀÊÏ` ¬`d§ÒƒÅ{0ÇzlZMU”q™~É“Jy±¸¸2•’~Î 6Ãy;¹ÛÁƒêª}Z'2PÚ1„ä(5 ‡¥t‰̶_þ•M_‹ÿöö¦¿ñ‰|’·«v÷ª2ÏU?Õ ëZ‡'LœDÓ#1g ~ý…(›ëQ6êCÕ`t›Ð•ä}h£æÍA‡“©¼œy5/åõ¼”®’5]µqrOþ¹«ë±Ú‚ÿ=þƒÜò8™Iz)Ü"à v\L/uE¼«ÚÒyØvlË¡êÚ³N(þN'´©ûŒA$¸“c9C¶4ºVˆï+ŸèRÉâ—!P"P=„ØÁIâ½µÂzt¯SÑí?‡w¼/hÓyŽ6SòÏ¡úð")þ»û 1þwOÝŒ2jozòÈÓOתV^ ðéB€?èv£êúfªñòåñd.Êï#!}1ŒEÓ /<†/”±¾…·cYW­ÚãHô7küáB4oªÁ¶€áCÝYÝÛ¾à‰ rÂæ¯Â ɲdÙŒýª‡Ñ´Ôc½_§ÜF‰þLˆ†R\¸ÁÎOâ\Ê¡ Ë!\0– ÛUÞ‚²`SA{7·jGeŠ£¾?µÑ\t2gºÁÜVÀt½›‡iV7…½jÐMï›I¤,¹BÄWåòœñ©íiﺇz7.dð¼ÓXË"P]ñ¡j*Ðc€—.žG JžJ¨ò %=ö´EñÅ5äºåe7ΓS‹€—·Ç]ì>SηÄm€m/r*½.øÚ õd‚ˆd«íé¨ïô`-ÑÀÛ²)Ià‹o±ëMqʃ»­+½íaŽr/Må’~OkŠ~¥¼aiC}¼è÷HCyà0I¤Ù¤7Ü&¾áaþØ‚‘”zªy´ä™ØÉ“Ôz;ø-19¤fûM$ä1mÌ층5]ã›bŠ)Jøv¨.'ÍzgÊøsêûÀ¿’¹‹vá‹GaG! !~. Éœ:€Ò÷Ÿ€§CvÓ«ç]U7åýQ¯.|–¤}ÚçRÌ),ôFÔÔ_ÊLÌsøÐ/4¾¾$èÇs® ýÒ¼wø”VßÞ­~ùâOã‘Ç endstream endobj 151 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 153 0 obj <> stream xÚ½XKsÛ6¾÷Wðfj&B Édthœd¦ÏI[wz¨{ )Øb-‘Iýﻋ ÊM§MG‘x,?ì~ûBð! A?¤,HEN²<(Áë‹àëw, É£<¸¸hИäIp±ý#<ßw½lWë8ŽÃìåjÍ9ëªú‡xØï¤ž;7û¡ƒõãüÕU[´÷zòSÕïôÓûû~×ÔJ\/¥Þ¥çŠz«^W 9·34gqÈéêÏ‹ï/Mc”Sk§a pF2¯Ö‰`áûU…²½nÚâ1;ÚI)' ŒHí¼õÉ$OÍüú ‹ºhi6­OœÈK–KÛV£¼rR›Ù9ÃÃN ÿ)±Ún7lÍúÄYžP’X/|òr 3/Ûv<‹+ƒeø¥ÇeØ£Ô×ÍPû€Ä9aöC›'€´²lZ¯>}‰Üšs_†µyê6ì…¦Kß‚:ïšNn"3Rß]·¡ÿšf”äðæÒÜ>H ávsVœ™õÛªë7gÒ¾VuÕWžÚn~jjy¹2à\_‰\yÅÝݾ’Y–»g„ÓÌ“ˆ³ Œ–qe%á‹¢)ÂÊ#Ïì£6ëÁÛ¢/ôTÙÔ+–†}QÕRù"]L«=l‰c’ææ³¿¸–t¡Å™YÑ\ƒ&á_²ì‰ÏMÖ1x’àÁš%„Sµå›öf8ÈzÓ°·æŽì –ã—M=@)#ºÆÈ §ìza5¤´2V, áðlCVsm7—èš C ]Èâ9 ࡨã5¸žqô‰§ÎøFn“Ùea…'ŠòðFš¡Ù¨¦UÙ6EÛ+&Â{5™†E+õ*TLJM3x7*‘[Á>á·×>þ¤bŠœ“o"l Æ²ÑQ)Ÿ@fáeØ6ˆëSgüusŽQ×õÓÖØs†uròœ+2ŒÅ°ÒXc+8ÒCíÁà%¸Ü~8ÔZç@ ‘»|œÈ# '²Å¼Ç¨xšbâ<øÄùT©K(Îó(QœÇÿ¾: òqífÌg½xiÈR » ¥û›¦… â §+³ìÎx"¦y¹-s(dQ"âÁõ“ª@t6w‚˜ìÒB}[cP¹ŽzheIs@û`ÉbRƒž„p¹…צÚ¤i~‚âÐÐraÌ,>mÛPªÎŸ»©>"YãñRªc6N|\A-öƒÔHšS„Óð)ãCçÎW•Šxyæ9ÕMÝ´*%]§Y4qÊæ)WLÃéªÓÃíPë¦Þß롦.%:H›:³º×SÆIwjà#Æ^iälMÌ‚¬]•Åd!ìYX›ÒVÑ/:é÷%å"Ïs%]A<[·²+ÛÊdŒNûõ®Áã|ÒîoR00ÉNçfòJ³``ª“×UñõòtJ|Nº0–D¾hfékÚ€BÙV‚ò5ôÝW>զɨÚçC9,¢+m×uƉ€Ú!"B·ïVY¬³¦jP¶y§³øCL£Ïž´5¨Â òñdPŸŠ\óñpèNÅva\|žÖ°‚}šŽ ˆ×öÔSý{ ðCëz¨KŒifQ3˘ú¡?N¼ì9¸ÁÖ¥ÏÖn;óÒFܶ•ûñy '8aŸ¡¹SÄ÷ (®:ÈØ½‹ráÞ%Ccl´‘è?VèÕB4çPz€Åï×WûFÙ^Õ’·š›7fg n7ó,ÀöX)8 Û–‡%Ö§\EïÄ– ›*R|™b¸ªÑÿSø† ßúéZ%GWÚÛõÿXÁAi›DÔ_ÚÆ Jiq|žº5ñœ ”4öO/l¥™â%Ó$ãªöaÉòçtQ®Ÿ'°yï€ï*Û¿93,×g†¡©UÀaºaÔÏG IøS¥4#Ô^XA©k¾¬Û Sëþ4NIJgˆ£tÎO(Ü ]Â!ˆQæ´ˆ¡nzïá&Ü'Lǘk:«¨ÚèØ¥Û5ÃÞhy"júàíc.Ÿ&ãÒ7æUõÅàzøë{(¡î¡ìÍ蚦L_…ŽêÒ©SËÿ®&.-¨^WàøGðx)§Ä²Úw‘O½}á½þ·H²ã˦5}¬œUý¿†"ÕìŠ0\õRy"áÛ‰¶01;º1€R‹“#u9—{ØCsÑëÞx/‹Î<¢õÕƒù HDø»º¼W¿½˜ºàˆ?h×»y¼Ò9›6cˆyÐÖsÛ|U¬N£ç¿1dTÕü áæ²ZÕer(Î5e¾?Ħxר/=ƦjVý¶JZ7ëÅúán/½¬ad´fè»ôN&Þü·ø|¡ŒÓ·ø ¦³‘Ÿ¾û›ñ@Ú8o/‚Ÿ¿úûRµ‘ endstream endobj 154 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 156 0 obj <> stream xÚµXKÛ6¾÷Wè¶23"E½ølS m‚´‰ÛK·®LÛldÉÑ£»›_ß!‡²)[®í4Å+R3óà<è}ö¨Àõæ%qFÒÌË7Þë¹÷üæÑ€dAæÍ—M=’,òæ‹?ü۵ض²žLÃ0ôÓ“)çÜÿ­QåJ¿â~»–H»µ¢k€G«îkQ?!ñAµk\ýòÔ®«Òˆ‹`“ãWHå¯UEn{ ÍXès6ùsþàåÞTcrЇÈwM, \½‰#Ð_óØT ËèêxSП¢þ¯JÀ§¾¨k1a‰ÿ¤·‰ŸW¥ÞµB•FUýΘBó)ö»Í„¥þýd l¿&TK|î8wz›·>Ö*×Â×(VŠ\˳»•,åóÊëêу^‹Æè3Ð@4Z•rAFL7E›LiD¢ôbãɺ®ês†›÷¡®ÊéÀÅ XÇ„‡¶ˆ~±PM+Ê\6¸]VõAxUÛVmD›ü ÈšªèZU•çTÌ.V±\V]¹¸XG ‡7°—VµéuSi¯‚µ™u¦5@éUƒ_†ß2jtc”ÄðŸt^JRÂ'Ó(fþ­(ò®-Ú(‰|²XNß×+Qª/;Ú;±3ˆÖ5!q8zb"‡1¢$ê-÷lLRF¸?y²(¢cb™ ÙfgÄÔ2¯ê1,!ß3‘¦ÚXÜw~[‹²ÙVœϬ×W ÏŒõÛ'³¥¨LDÂÈu7œõ¶Ý, Áî²õ'»(žÝÈ›»É¹ÈÉ­{LPÄz'ñдw ÕDÇžLgfbj|¡ák$Iêw6CÃ[Œ7M†Ôäã¶–Œ@ Š*ˆplgš’$³vþà:ÃÕ9L-GÇ"Šü¿rïXêòAH‡cžu…±Œ$;ÏŽJ3ÇöâU½ê6²œ„Ôo›“¥C9?L щ̰ £s.þ^BhlTi\¤¾Ò© ÈŒ\š,$'ŸÇþ“!Âñ¯%r錒ú {Ñ:£Oyû?.G ³$&ìólŒÀŽÓý¹ÓñCùdêßùu¥q=46¬§!ç$K5¦¶9m€uŸ©+t£Xi~ ÇXé ¬¡ƒ5d#Öƒ—wP¢‹nSjÐØU DîB«Y@Xv¢"žŠ L$ƒ4rYéHÙ¾t$Æx1–ŽÔ–xê„٠ﺪ՗ʴ­( ÝU¥ÔöKÀù÷ÄTžVå=‘émž˜€i˜5àE=‹0Á³Óôße…ãTºcª‚…j¬±û<·¸º6Ÿ2¶Í—ºKͯL™å1˜(â¾(:KÃ>Þ£y`±µØè“kå§.Š$ q§wAÈG0@Žês^»­…Р𮑠\·¸¿ûñý;\ˆb^n×}bÀøóžc!—¢+Z[œÒ€„™«/hYÍãF³c;rF"zÖŽš‹÷\ ʳ5ŒÓ‘2æô*š 5d,2ê7ïl( Yà‹7ª‘åMƒ\¶½>Ÿ˜Ð”¿+ù€lÛºZ+FÃ&KHríU{ŸŽÄL|e?§¥ ݯõM]5ÈÈ´µŸ‚/6_ÑŸREwç¢!A/zξÏF€Ë®Ì÷M爡qè‹Ó•óZܳÙM~3Þí í ]@- cä—c¦‹9aW¦‹@\ˆ@Ü›®ÜZÂ9`ûHpL{9Þk-Ö]ˆ¼)q,Õå ëàÿgÅǯ²âÃx­åš 1~´GUÔar“>Ј|ºÖµ×ñÓ…–åŠúM3R–`NIÏT¥˜=ÇËñ4_icy¡ oº¼P )Êa&úƽ¿Í­jÍåÉô¾¨ŒïM•ú„ÙcŸ22N’È2>ȶ«Í$Å!IÄÔ$‰æD†ÞÍÓóµêçûA®´aÞæ~Ûm 9zi±WZßh@4 Òƒ là7?ðkï“®ºŒÓ#‰sõ¥·öZV­TtÙ®pˆ²C€jÖ²ªÐ²Az¢ÿÖÙ×ôô“Àôƒ•ÝäçÎô”ÞÛ9"³ÝCîDâtå´ÔØ~èf”Óþz¦ã‚4Á\$ÒÁà˜˜Ñ‡Ójÿ+x¹À»IýA‰O°H7Rv“¨¡×ÿ"ÐŒNšêLwGó€;é%÷ýµ%Ý7Îå©þ8W ™#qLâ>,G‚C¯zºØ]×¹"àÒžãi\Bº CLU fÛ ͘ÚB4 }>ôŠšw@rg+Ó¦3çÝ›LŸâØåö]|0u…lßXØ{}[j»ÐÃû߃+CvpçûfîýúÝ??q)± endstream endobj 157 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 159 0 obj <> stream xÚ½YKoãȾçWè6`ö²l’tØÙAÎ^l8mw"‘I­íŸª®&Ù¤Z–;|`¿TÕõþª½úøã«L¬2]°¼Xm«ŸnW?ü"V?—/}Õ®c)e”ÿq+¥¢u¦~Â%õÏí}vŸý±ƒóãþ_Ì×¶lßióÕôÏ4úÛ{ÿÜÔ–\ “-ýŠöÊzGƒŸLÃ>;¼2Rrýpûg¸¯òî›ã]cò{åû„gîO|¹Ó)Èg¶Õ~¿+ûÒóÅOV1ˆÏIüëu,„ŠÊ¶-×"‹ÞiJ‚àhgUÝ™¦îh~9’錳fZ9ÖõÛSkvÆR1™¹C7*)Ëø@ãýzAc¦ ""ÇÃ×AçÍ#}fÛ6(ì{ ÎyÆä Âû5Ilñ›FOU]uƒ¶*|…OUè H-–B¡f=;ËW»ðPpRI֣Ι–רQ ÆŒe¿[‹ÓÅZ$UœÒÍ+ O}((ª¿£æ­›u´h‰O‘v>ª‘b…ÃJ_±?—[¤„nš%Qµ¯ÀO×BG}H¯š%¹»×y{¸3ï뫜eÃ1Udâß Ñ31 Ø e•´Ë¿Ð÷7ˆ×ÐÑ×g3¤!\ö4Y ô·† „iÁ¥¼}S?žb•¦ÑŸC¦'Tü ÙR°îyÝ¡nzW™r‰*´Òk{äÉP®ª­»4§K %¥åß¹£C6aãVÙu`7—mHÒÉßðPTWæNÃ6Éš1×L×Z¼ý’Éÿù‚ùŒn€¤²õ¼@+ÂÑl8¡ì\h2  ÛCUÖ4 ƒ <ÇåßfƒÁ¸ÒXä-ÆVÍœ7òÚâ¦ÃÜò«Â‚Ùá*f¦s.Q¤,-|—8vK‹Ž1¿°ãiÈcÀ|?kމé’A¿TÀö`,4“Ifá~©´âÈF7|çׯxu¿%ç†FpE¼3;‚#±‚Ø *TêD,Øl’Q<_Áøã.þ\¬ –¥¾a^m¤¢¶ wKÅÇ[Ñ5UâKÛ6›)>àVý£ê-Þ/S€Ö4 ¸ý1ˆfBPöW·ÏÆ1|<ÖÛÞ5œµ–Ú¼"Bœ_öU°G±Ñ÷†3|U°†#Rà˜BRëë{Ê«JP@‘Gâ ~ 4ãò ã) Î.P,l!CðS ®{;œòRœ[ç°dLä‰~Ö,ar¨ª”]´’rÞQtfÐM(_æÁ?G¯ t 0âWZõº¾5]ö­zJóÎŒ‰=õ³ùÔÏæ.L©©Íg-«P&ÐP²æLæß¨¿³M䬲q?¡èBƒ¨˜Î| „è` ž$Œgë+M}}¥ÙiöéLspÄëZcÅ êQµíQa×å^šÜ;ºÅh‡óÔÜ cžØ\ë{ʬ3—iL”¥´Ü¸=ñZÏxØßxÚÑŠOزd3BelË'‹ôXhaä÷°x~LI°{…NŽ¿Pk9´sô“é²»ÎÄ ~‚#ýsÙÓ¾•µtÐõ±9Ö» E]Ÿ Ϥޙ¬T4R!¢CÙ·æ Ç€¡á¨:{ýûm ]Õ#;7uðþD~!+Ë”é!äméµ×0>m‚{ò„Ë©øÏÈú¸ÔÓzæÎ<Üýû!ŒrR>…Ñ vîÅ„r–A-3 9K«g+ä’yHúÔÔ ©Bz”¶ ¨bþ‰st.üRAÁ‘WPN¸ ™ ¾ýæ„8yó «ÈG‘OJ¼¢Š¤eEÎYâ§E•gCúR¹M_šR‹Êõ¬Œ¤ôòà)=¥üˈ÷ì² Ke^;Œt JO™©lz` jÎ+ïæ#4ëegðŒÅ+èÙf¹"ó2M/dŸ]ãvúJ¶3]_Ö[7ûŠÍGTõøVöН0Uå°q3»ÔÐÂBþó¯i#‡À2Yes}ÓcØÀª_½«Þøæ.ypï`vAŒ êôa¬ ÎRRÛ|ª>9 ßç™ÌS¼¤d¨xˆ™W[TéùÚ'‚ XçHæ{¾¦©k;qRç%¡-ö†Ö¯ÄŒö *-œ ~êi€¯¸[jN]@O»rùú[Ngø¾äˆ9¸àÿ vÚ‘ýðÊ«LØæDMheúùvõ÷?ü°­Fj endstream endobj 160 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 162 0 obj <> stream xÚíXËrÛ6Ý÷+¸ 5!ă¯t¼pœd¦mm£®¢,`¶0¦H¤üøû\<(2S®=“v:Zˆ$@àœ{.üà ‚R¤I޲<(ÖÁ»Eðæ# p„ò(ÎLQ‹òKx¶â×P³9¥4ÌÞÎæŒ±ð¯VÖ—ú »•°mgî¯Ú´ÐÛþIž+®îmã­ìVöê÷ûnÕÔf¸n û–mãui/ÞÉõ-8'4dlöuñk@0J‚9Ä€,šzFÒ°ã²¶36u¥g´M-ì…¨ÄZØžf˜71öyÓ¥ ¤‡”®‡˜ÑÄ5¼¶cžÏæ0ž›@‰k%Z=Ev¢´@xëfò†"\sûWɶGû@’QêfúÒC¼1JéP€å¹kþ:ÂÃ{ûµ’„MËaíÙI-q ÀG`Ì)ÉP–sÐ ŽÆÍƒƒ\3óGÁ9Jü%ˆ¦¦×2ÂéX\Jâžv]Š;22Y4@|HBu¼õŸ‰·¹ÚW Iˆ•²n„±e!ܫͅýß¶z*jí‹ZÍÍ@"öfÓ>›9ë¹!³ÅXfcŒâx(é¢QJT\ã•W¡;R]Ÿˆ€Ÿ·Mµé\$nfqòjãnuý6ít¼ÇFl3/dÓIU(SGéúbQ¼{RÿÆc#×NÄØW<\­yýÊ)Š×W/Ú«‰uÉ«  Ùî™ß=FvÝ—e£µdÔ÷%€ ôx¢ÄD 6E%KÁë¡=s@Ï'¢9“ÆìïççUcr_èÛ++ÈÛ¨egî##Õ”Úë6ŸGlû½€e±–Ö·£4”öÿR˜Ó\™3ü¯e¡®7,ô³Ä¯±¡WîççöŒ÷pîk!°üôA‘&á/#ø)fZ{NN¢1yeó6„Úî†4#(-ËÄt1¥ñƒÜ¡dx‹ÊE#Ÿ 4»…‰ÖvX†ÊIÚåL3I0!„ L2Á˜ÿ”瘘¹Åmø’s Ÿré‰.z½s?mËÙHªæ°bàìï)h,/t//ŽŸÉØá*ß9 ôwú³K»Í}É;þ½üX½ªË.ˆ)ÖñÁº0Õß&^Ö3çŽùÖàÒÚcæ/®Ä.®#æ{Ž˜÷òü¾!’4ѵúdCôm³ÈÌWbŒËy$c(O}®ën¹¹ßtˆ6²Q¬8‚<àé–ç›7ˆäaôà¡gMî{ºrJò ~§ŠÉÿgœ‹àŸ¾ušS¼ endstream endobj 163 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 165 0 obj <> stream xÚ½XÝsܶï_Á7ó:"€ @6ã™Æj:uÚé4É%/–pw´ÄˆG*$Ï–ú×w ðHd2vçˆöûÛ‹~xÄàÇ#-"­Ê´(£í>z³Ž¾ù»ˆ8KKVFë/"ž¥e­wïâËs7Vý*ɲ,.þ²J¤”ñ/CÝ^㒌ǛŠö.ݧ9 @?íÿ«Þô¦ ÍOõxC£ÿ<Œ7]k¯Ëa²¥S´gÚ ÞÔ]zéwx)²Xæ«÷ë@^9“7cižG‰…„•ùŠqíèò¹^"U9è$»z_¿~µ}åèæúçï#:§ð¶ëûª1cݵß$H”LE”p•Êì…˜3%0›¡k£3öÇUžÇ¦9¸i÷¾Ócœ/¯|¡¼‡3å=´Ûª] ÃãUö=ÅW”êþYñÿ+ãp¦Œ?ß­©2ýÞ´¯‚QoÚÛ¯ý´·g øÏªÝ™¦ш¼˜“çiÁùËdàF•2OT€  øƒ*TgªðýaÛԻʴdSE\Y~Zá@½<|]µî`u×WÃà±Z$$xå”ïvf4)º:n/ló¨LKD,3š"›4ÐiN¨~ã—ò´,–+*Í´]ùk@ å2™§a«¤,ºP‡1Æbí¾òÔfœ(™£ÈÜWœRj¢ôþ„:¥”D)& âÔ*9¨¥" ê*'ΉM.Olryb“ï‚ÑVÀ½`ŸDRY¤ð[%¹ñÏf•±ø#•½Ú—Å:·ózæà‡f| S4î+p–]õ#D¤ƒùX]Å¿u›ÖìmïÁXç˜n ‚ž_¹Z…|–.üS_ú'NT÷#0¾@(d‹’¥YáÄsr” 1â”ØîÆ€LBI.Bœ ŸÇHxF×cÿUM™/ÅèÏ!N*UÚsº½¾~–¼˜Âžê›®q•³ülÊ‹|!s—xJžŒcÛåå1Ayô±äûÐõ„á° ÿ¹lãÁavR6¶&¢±ƒ“Š0¸ Fa}[ëU!à`õk]}"ìÝõÝuoö¿r-â·B‹B¤Ú[qŽ˜€ôZÄÖôô6°–LåÂZ3È…J`}±éQµ²t¥EràÑ¡Lñüw×VÏ?ºäh5›yàî}í¶­“v´Ðµ ˜VB «Ö̸è ^–Ÿ:/Š£a¾ֿŲFÌDŸ dÀ2óT¾õ%üÒšÊ×®6$ô.Ê©5QuDdh±ÿ ”õZãÓ2W\Ï¢ò¢þõÀí€#´æ¿UÛ1\° ž[WÁŠ2M}Àš+ãPs}¶N?»ýX>†xªê²õ­(x<Œ6?^ †(ž½TÚטÿpåaÀ†GÆ­ŒžÛÆ ndï³#ü’;`Û…ùAò„é:3:½Û;ÇÀ?ºÕÍ ¬Úwi°ßd…Mê/êðž‰,TBÈroí"^–Ç»jØöµ“ØQ¹BP¹¶G‹*ª~ª"°Bϳøm눬aqÔù˜WÎQVê´ðMÚm¨3Ŷ›¶“=ôƉxä}AÌ-6 bc>×5•‚#¦ðƒ­žìØêÑôq§‡k{àL°Û tüN”Ó¿†8±í–Âv o#Óẻ£éÚk'ÛØá4tUoGwO‹žsR€nM³=4f¤‰ pï0` –r˜[/^1ù,gkhLéËé]s ß›ºêMO½d½µý"H0•€«ªÿÝ=7¿M޵€ç äÌ™nkH¸ÁB²€h¹èÅñÑ¿=ª—ïóÉ5„=ÉcVŽØÓ„=é| 7ˆƒ W·Û=ªa$óÔ%"×ékσªD_ßÕøom¨•¢—FøÒ'ž„.l+þ2äJÉ—È•š¹¬*¥ˆý×ÐÇâ§§¶ì²<Æ©·Òþ“  ‹S)Ž”GœÂd© ¼ÀŽgY89Г%YRB ;Y§ÚƒÕ›k¶*5›ØGZšÌÁŒó§Àœ1(µ_ fUÒÿÁñtÏšd¹xT)†à-žƒ7çÇò™RSaá0Gwöº™ú<º…:þsyëï×Ñúã²§ß endstream endobj 166 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 168 0 obj <> stream xÚÍVMoã6½÷W¹„*lV¢¾p€Ý -°[»¨ÛK]ŒÄØBdÑ¥MÒ_ß’’¥XÎî!‡ÂSòÍ›á›!ßñàç; s’8£iæä{çÃÚùégæøͼÌYß;~êøÍ"g]üE®wüЊÆ]A@Òwî2 Cò‡*ë-N…¤Ý c»¶U§`ý`ÿµ¼kxólŒe»3£ÏÏíNÖ.‚Üì26^fð¡”ôº·ø H»¯?_?BŽ^æ#aÏY† Ó„SšÒÌ]F1#7O|¨_‘œWyWñ¶”µÅÇ ~Bã@C¬w¥‚MYL̔̿áCÞ[£Y»+Dš» ‡à gÁí8°xDcÑûéÔ`ÄQ^•õƒE„o…Á!!dPߜҽÄÜ¥1ÙŠZ ç4±i„¹=*÷.KH·7Sè4ž’„o ‡ñÜ%K Øö¢FŒV–B`².J CQw{!yoýEÀà¦Ë«²¼>å[”ªåu  u–‹Èñ¥ià|§Da,š0>c,7šse%‡vùb¤ŸÌ¡mÛæ Z0  /²™2NhšÎáò³¸=KSBÐÝM£qö~/÷eÅs!hï M¢ëƦ @ö”½±l+@’Ög6ÉdB½Ø:}˜ë0ÔcÖ¼ÜÃSÅÝäAßJVÞ ïfÒòJåÒ¢·k]–·ê ¡idcÇ¥n¿€¡ã˜VéÃP¢u°Šì¾úÀ•Zùžç}Ã?Tݺg/Ý/N¿myIþÎ÷6’8Èl#ÁQßHp¬Iz¯5’`¤ï1ÇÛO·¿°Û÷ìLCAE‡ñ+Fip—>l·s Ì£,=6–ž6ó.â€F“‹ø…`þÀÏ:I&]æfí|ùá?›& à endstream endobj 169 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 171 0 obj <> stream xÚ­XYoÛF~ï¯à[)ÀZñ>œ'Gi ±ãÀ6Ú )Š5¹²¶&¹ IYvúÛ;³³¤(‹ ‚Â0ཆ³ßܳ²¾Y®åÀŸkÅžG)KR++­·7Öâ½g¹KÔºYYnb¹>KCë&ÿÃ^®y݉f6÷}ßNOgó ìÛVV÷¸ØÝZÐÙÒ Å¦úáü£¼kxóL‡[Ù­iv5ób[4…axVÜ«ËÓSÃ`öçÍ+ð\˜$ˆõÞâ}d¹1óܱΠÉÜwP¤Kgó0òŒqh0Âdi†1FXï0ÂÂ`„ÙÕÌw#Þë¦Ì­¹›°Ô×÷Á¼¯Ë¹ùÌK™{쫹—Ķliä4ôúÁUdo^×8µ{rñÔ‰ª•ªÂeb«mkIq²4ÃHR\’âb 8€ q¸Ã Ÿéºj]iYÀï37ÒÈ/UÁ+²^‡ã`üÛJ>μ൲›NmpÏö’r¥šJòúàXÁ…'ºe³ù‡‘š–pmÄ‚ø¨Â|p™F|ÛÈF´¸ Gú³EÌ¡Þѧe)+Y"í¦dàzqlŸwt²•…ùºRf+Se- A‹ºQh}Ësÿ ¸ ‚ž÷¨AY6!sœPŸýrc}³P˜­ø,rʉYèY¥Dè³ýº°®­Ï‡ÑÄ, ‰(&ÞŽÈýÈV Ž1 RmZZ=’&Ð7Ú}º^G xZpÜ^sCwG†ûeç4Wfï7Yù˜0€»àm~º¦ñ÷?JmÛÍÓ )|_K0(ç“Qdõöúù¯rãàdl|!ÑÞÌð)üØ·eÕvMæÅÁtTÁ¾Žo/ÏNGè@ÜÄÀÇžPËçû­¬ õ3z¹Ú„Œö¹B–ÛªPË&0C>|CÑó -WÛNi©ë‚iˆ„Ò#Rȶkäݦà JNê',Ü“{ðÉN§Fã³/ßJ…BŸØšŠçÙ+^ÊBrS2c œZS-Õ°‹ÈM2ÄH{ƒwn ìRû¾o q:¡>g ¿¦lŸ_ð±‚ÛØÕÇì^Âáx7Üíî°}ç¼zh)gÒ‰PCÕ·hB6­x!ëò ?9»¤ív-zmè(Ú iX Ü@z~˜t2¡Ëïé^vGêÒ9–¶+pÑ’AI%1`÷,ë$eâëŽw‚NGÊ©H 9ÕÀl1:nÏÅ”s¤¹¢âª¿Œh…Ž€c‡0½7ô¼‚y3á~è¡{SÜÔu9a/h¤×PhýaW2².a©7vžÉÚìxC3sñ$2ˆ3N¯˜¼ŒÛÄŠ9'3;þî“w˜¢qg sY+ÄÖoúмÿ;.Ùç»2>’¸Xè〺) ˜c¥7^ª7F¥>Üo¼¡jdJY]çS‰ÒÓùð¨1°Yûê¸>4/úu£ÿxœ¹6U†±í“K0îdCÄ5*ÆÀ6žªVV{r£‡ýڳǎèŸïþ0¿RäJB2}%~”¡W†ØªòÇ8þ(CÃ-U×¼¦ì†/VB^eâµØöüJö鵸Ö-V¥àÕëñÊåÀmïÙ±(Ò?œ_tçªë_Ü׿d¨I_ÿ’#Qœ˜Š–À³‡*4êOÐø·ôÄuÎé5• ò Ð/#¼£Ê÷9à³Ï\f’A¢a~¬s^óP†UA=ÕjS¼9¥ºö¡&ϘW…É5}î1¹)—EÛ'o³šD}òN°"é7=s^õ/±ÅiÍXt˜ä¦ûøžªÀ…ÂV+À’½¢Që'ô.&+žé­h— ì'm„ç`j³Ž D<ÛAÄçð¾YËžm{Ø`ɲ.D) $ä¤CYÅyÍ[RE:hà%·6-Q™ƒárZ¢Ýô¨E‡I/'BKû½vÖ†Xˆ'ŽX°5‰S[®ön:šƒ¾²g9AÇ’¾iå}õצþjM˜. ™ß?|x–‰º3ÏýnÝhÿ ¢Á ‚±ŽO¦758øÕTä±´'™âöþymÇ=\7ÁžùIÔ£®òÉwó£!ƒ%§ $»‡¾À`¯Š„î›NÓ—ùÌ;OÖÿNC.ýˆ¢zÀÿÏ—ÞJzUÈÝgö²4ô6ŸúR5 endstream endobj 172 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 174 0 obj <> stream xÚÝVÝoÛ6ß_¡‡ ¡€XµdÉ–2lÀ,@‹XQÃP#SQŠôH*†QôÉ£dIuR´ÍSážî‹¼ßƒÿ‚8˜›_¬’`µ,¢¼Ê&¸^Ïn“ žGżÖUçA¼ˆŠ,Xoߢ›ï5‘ál±X â*œ¥iŠþV”ï,+Eº& »ñk•Ñïå/éÄòÂÕ5P…É ɼÃ?ØNH#l®®¼ƒðÝúE&qdÞ4w/IsÇ{v› Þ:ó*³Ô„“8½Ÿ%Ñ­äïï1kýÛ~ƒCÑßî7œgÖbfB!Ô Žrá-~‡ó╌€zÓ˜÷]\:ÓùÈl/ÅNâfjyM»ãY“’a¥¦Ϲ–h- {¯#e˰ÏÿØåì³6á¯>G£z¦Q‘³d-œÖ?5á&íñŠg‰ªå¥¦Â±3´ÇRª=a˜&=¦2êÒ0+#íe TJI°ö15VµÓ_"1½t3³c˜'È)d¾;@E1úÇŸbüà:ç¨"Û9 ´îúï‚M\‰9°qY¥|VA7E÷a–!Û^pg}ºM$‘]ÿž*Ñ÷¹(ro›æu]Së/Y î,ÍsŒç{÷dNMÚ“i+KP%$()r‰HL•à`‚n©TúÒJ2—rkÒÌýºÆžy´^DëovñbU¯I:VWÉRL»ÜñA^„ÜéÞ”¡kÑᘞ4‰JL`[I»3,¡‘À–>‘¦©)Ý^Áõ|×Ç Ôc°~°yü.™ÊOŠ‚õí“âaXœ}oVΆ@;¨Ü˜ñC »ç•éÁ¼€î·ÄiNد-1S(åvÀg…[¦ác8%’<ÄZÁh&En¡·tгjzV 3%€b{˜äˆ€– ™z{Ž¢uøw€ÜŽ&ÙtêÁ(v= {òÂïPÓÒ¾Åã·¿ÜÃÙ—¿×ú>l~uÿƒÐ7T>vjÿÚÝ⪲Ê|UV˾âðm±‚E”ðŠ~žJ°‡r[ð| …°J0^Áí(1ñÝÉNOãeÝkvg«HÕ2Ï«&ןoŠaáaËíµŸºxLtÿÁUx¢Ψƒ•¶ˆi;ÝM„IÔwÍå6’጗˜U¥ ç)Ú F(ÍŽ›ðóé I«N˶kk…›ñ–0 ô ¿¯ª½Å¯ùÑfÏHCÜ6Ò ;ÕÏEn¿DæêKÝý‹Òí–p=jìÿïãWì‡ð.MûÓ€°Àúè>ì§pÒËã/ß>^vOsûŸëàõOÿħ= endstream endobj 175 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 177 0 obj <> stream xÚW[oÛ6~߯ÐÆʀŊÝ2´@W¬ÀŠ ë6ï)Éc3‰]\J® ûï;‡‡’%GÉŠ±Dž¿sá§àsÀƒþx‰ K –Á¶~Ú¯?ˆ€Ç¬ˆ‹`sð<à’I°Ù]†ïïõ¾7vI)Ãâb)¥Â¿»²¹Ã%ö÷†öÞûŸêÐü¸ÿkycµ}¤ÍcÙßÓÓ§•ÈBc+oð]u×Zج/.¼Õõæc gSì"Q…[{ýA\1©RŒ5ò"‘‚ã'W0±Š’T„š[cM³5øÌ’°oéW[«W2»5.¨P7;/±’<<â¿6Ú•µiº²mtERµîm‰Æ(Š)bqñ‚qò? ´Ò$,ë}eÀÒJ¤aßÑZGüwî6G7ð–…4<Úñ8 Π}Xå"l-©™¯=­ýÏTèÕ¦°‹GÀ %ã”æ¶1g¡@’P¥Ëž¯œYÈ©mÝ®V´¾Õ ­ß¬"<:½ìÌUÌUcvd«*V愪)» d2R¤LrÓ÷¶=’øú¹¤¾&‚^¯\ÈTH¡‚HÆLJgìˆQÅÜyÆ'qBìi¹<•‹â©‘11ˆ”}gª[²OÖyØ´=¹ÑÞ1™˜¹ áŠçáÍ¡÷›$;É—‹µ¥e×csðCB¸3T„âjE‘ªÖ6 ñF\$LŠi–»Ïm fI„Ж[Ì¥KSd~³+·ºw2˜&ÝÓÓÑ'5Ý3KäaO+(Jm­ñº„Kã‘”ËS¤Ež1%'PGo/ãë¼Åáå £êÈ>÷Þ …ŸZO9S|jœ€Q±d2óö’/9…ZL’3§Xñ‚áØJÂwTÒ«ª©ëç©^űXªQx¢dØ5ÿW*ïö–¬— âÝ›;c;Zñ ']ÃåCO-5\J›âÙ†‹8`‘äÔv#Nñ··ÝlŠ ._Ò•^W½¬+–t¯›¾ »Ó½^Òu‡ñú.¸õiý¥ñOùÝz¥ºµêî°Ý–Ͷ¯—0•,US@‡à§ 8T‚CdÓSÌp–#ÎëéyÓ©¤ô’jIrf3ñ’éL2+p"þÒ,U’©|œ¥Ã§½4Kc–fC"®Ã£g:./žé8ŸÄã}Y™/€^œy×Ï “e/#\à™)ãtäßt3Ü„IF­™žü$yx{€j€›³£W7¤¿¬¸jËJßT†ÔʆÔØŽS3_÷ÔÐÛž|åÀ“»ºAõtÅ ÙË'a´¶¦-ˆîÊÝ)ÃÎÞ‰‚äaK óË#/º¯dʧ—x2P?õÙ'Cš†’£_œ4Ò‡µµ™¡žªÎaM° ­Ú){ƒw@àIuŸÚ¾ëía ʦ{Žn°öˆm^`¦‰7JâŸjÛ—#Ñ/$‰CÒ1pä ü40€P{KŒ“­á2ñÅyìÄÓìT®KöRV MÕF7žÂn§ìyÞXIƒ‘|b„ €w³ëy;@è +rWï0ºPzã(‡Pc®–nWèyfý*¯y1¿ˆG²4âÌb%¤«$R*¦=³ŒŸ4£,gaÄSŒð}Äê0ã1Aáˆò¥‘ÈËfÜ€îß/¾WàøâzÀ÷cÕbÇ×ԆDZIdx¯Gm¿B$i‰®p@TŒ³r¯­®ÿÁÿwáð™`É©îȲöA™zßÓJzR±> œ0úÐm¬{zrÓÜ76!á«jÆÎÜêC…¬È"L8„÷€_Iœx: lìÑ}ÛHªÆH ½Ñ„k÷‡ ™âEÌ8ÿF $˸èÓ¼ùB=^Ülí§-î:v Kc~!äÊÓO©¤¡ø¿’Ÿ°»½m÷T(¶zį6¶ä"qÙ?‡ÚwýàP ûÏÓ›«Ðãý4‰©ñ1ù)øæ­§ë—fç uyy½D!jÝ=Ì_½Z;šòî¾Qælo¡U÷mgæ²ñ‚Íf¯»³£ð%¹Úô÷íîÌ·öÎÞ|÷•’IÒ endstream endobj 178 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 180 0 obj <> stream xÚµXÝoœFï_ÁC*s’!°°|¸r¤4m¤T}hU÷)öÃöî¨ùp‹Uùß;³3ppæêså褃ý`vvö7¿™YëoË·<øùV,¬8JÝ$µ²ÊúñÊzý^X¾ç¦^j]­-?±üÀM¥u•´ßmÕ}¯Û•^¬œ0 í?»¢Þ`Wh÷[McïøQî:˜?ŽÿZܶªýBƒE¿¥·ßV"¶u[²À·å¦ia°º¸`«›«_¬Pø.èäM¤gú^¿—] –®ˆ-'„í3//ºž¹|CÏ3}vn¾õ,væÓΊºè Uù|òÇšë„%N>¸^ýðXJÅ[»¶_e¤ywN=¯tÛ6íÐX7»:¿^‘Q.©óŽ¿¸¶¿¿W­ª†^¿á°„—ú¸GXO„®ðÍzoÛÍ®Òõ*ðí¾ãÙáÄ œãÇnÒž/ØÍn$Ù°¹êO™Â`¶Í·pN^l·z­[]g›‰Ý7ôTÜÄC}À¿ÆÉ в+šZ•ôi¥ú¶øL³¦ÆY½‚3@ à¸ntÍoúó}«;BmTìŠÈ~Ø‚O¿íȸªe`v}Óêœ ß6FEç¡ę̀°UÍç_YÛ¨¶U+ÿ…A•#@‘wcTîh$kÊ]U9îÂ)8d_Ç\‘žzõ §ãjð9£Ò®ZŠ· (z 4kÚïÄtº²º¾à¥ï–”®7 /o1ðÝ8}æ+ÕÝ€5‘FS¬‰46Xçâ&c-9Ä~:` '¢)ðYÐùé šÃÌê¶„AìxØžþ›’ü‚ÖlY‰ªèú\!XùÃza·³­¼2~ýîú«óæcqÝ\^z 6ðCø,a;˜ tŠza pEÄ3y Tv²Ä’üÀsCŸ¿*:t©p²¡HÆËŠ€RþûôDìb/x¥CØ,žZæìlIE¹§ûk»pµËôÙÏ_–ƒkc á9£'×MOèWÔžÉÌFËòzµ—_oDážAêf ˆnøÐà‹~ÖˆÃgºÅƒ.6ÛþLj™cD’žªæ§á°9 gr-ösâ\CÖ¸6:r›e·Ä}Ô¹ëCÍ7ÆVø–©2Û•ªg¹Ò„^Šu.Á÷i9ºñ vý­£ÿÞ©r Wpże@AÜ %b- à  „œ ç@™9(!¥á9?hªžŸ (–_S¯Qž>lmIqÊäIàÊtjÕuêsC6á²-eâ†eô­ª»û¦ÓËôn{v ¼”½Ê“v©ëÉÌ€Lèð#Èø6Tà‹™ Z¼=ú‚Å-‡¥‰lŠžt¢*cLnf™º˜7x½ÇL@ÎCÌŽ& ð¯ïEn=¶‰‚Mökú{›@'…Sß >^1ÔóIG<§ƒVSƒ‚tˆC»2§÷Áœ¬‰1˜Ù §öY¶oÄa?ÓœŽz9¯Ç6'tæ”?iH¶ªÂä ¡v±Æg0¤¥øÚ´ôœ¤›žo"Žòv(9†Îã $Þä‹T¸I0O FÕ¿I:€!e8º>Äóx!­AÕë\XÌ`) /3¥¡=U:ñ1|yÇ5öi,'i’ôŒi4ešE ?©ùrʰC„Ÿ¨úRÉü=Ð÷‰‰|t,‘™y"pŠŠ ›hBB³t^ÀâÉié¼Si°1IËfõzAŒ+qZ¿àiC´nZIç4¨U†zo÷*ÒÛP惴=ÅÏõ˜$–ÐpôyS™*"'èÔ€4&‡fS#YA-øaMýD}¹06òœCJ7ì³/ýì$çY2ÊÞŸLè®qã2•ö§fåNÓšõâ…ï»þ,²TTétm‘¦™aàR’t ÝÞüüpÆäü 9Hiw5u4uùexË´Ià˜:žÝÓ“=yküé¢R³œœÎáÐdž†î®/ -,ùV¤³ê!ëÎÔ VÌ•î·M~BÚljâZ;„Wà™Œï´.#Õ¹ÔïÙ›+ă"$c˜Í«í`¨7øHX"_G˜ûŸ‹ã6ÏÙö™ZÌuã}ùÈ×jÊ AÑp~¿X²¤8ž©Du¢À/ë@¢Nèø©ÒeÝûUB1‘*¸1+vƒ•õƒ—…ÆËøòe¸Ý0Çoè2??¸\Üùì@° y1 š;Ç—ƒa®¡Ö# Çm M[ïê¬7·cfRó(¢²í¥P—xàYÓ¶ËÂæåÀv2âo;ú½>Î7{GþšîNÔÎn¤;}>ÿ/˱vÑ^;ñM´ëNÔîN@T[©úŒ]Ò…;Ž*ªý|eýþÝ¿Ød endstream endobj 181 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 183 0 obj <> stream xÚ­XYo7~ï¯Ðƒ‹¬€ˆáµ—ƒHSH -\ôÁöÃZ¢­…W»ÊqŒ¢ÿ½C¹Ë•¨ÔZÃáÌpøÍ lAáÇ)_¤IN²|±Þ-~¼\¼zÏŒ’œæ‹Ë»ËL<^\n®¢wÛbß«v¹BDùùr%¥ŒþêÊú^ɨß*œ{g?ÕÐý8ÿkyÛíN>–ý[¿/y©¶² ßV÷M “»ósË`ysùóBrF@&j$‰™{õ^z²®DNI,+ êpCwMYj)c_+N’زzñðÂRÌôN ¨ŽV®_T½)ªêEgÉ3<ŽõŽÔî)d€cb§_‡$Ï™hÅb’dÏ\=Sð‹a]•UÔhîMÙõE½V!98XN|­·Ï”ã]Ùë“~ZÝVÍr­µî>¤Z‰Œ¤È‘Î ‹÷ËLDu½Í6?-ã8*ªAuvê. m.¬ z“€¬œ“œY’—Ègtåº+†ªÇÎõÜ–r”úz‰¥cèÔ†„ ÌxFâä+-\Öe_°o@v ¼axAßj±X5û¾lê¢ÂÞ¾h‹Â‹ Ý‚-e·ú¨*ËÝ68ºöﮦjð{ '—E ;ZMlÝ™³&–[]ü†ßÂ]g´ÇLÞ¡Ó‚VüÍc©}ÕÒi»SÕ>)Ê¢nr®K­¬Úèc¥©–®F‚?=/T Ãà‹=ri‹zÓì°=¨gF>nËœ€íCª0Þ½ENb"2_sðS WÆ\Ç&œHg‚z_t]@} É¶CÝ!?Ÿ¯i˜c€¯w «„ɦ— ‘ò9¶¼óMŸå!‹K*ÅA‚²Ço·m†jƒmçMÆHð8K¢‹i"£ž-2ïDô„¶`b,ˆ,Š'*Ut¦É¢¦V8æ±ÿÃyæ\Ȧ«3m¨OåŒë¤óËê§Ƈá;ú0Î;°ÝhlÛÁn]_®êkØ€®›¸¶†a¶ûSõCk´“?fãG[S}HzÕåÖíw7Ôk¯Øk 7;U dUÙõc<²ñ¤UÊŠ FëΘÌ÷šáîô™³XèþÁ=eɱ¬’¸ù3Õ¶Ö_Â^¦¯Û—™¤ŽI}× uHÕÒq †<Á!ÌO„¼Ù~~Ìû¢úó fåÚêNÃøZa×à|M¤Ö_© SÛ¦³”•ªïïr è0æ€Çc„Þ9Rƒ "·Ø LÚÆ Gç¢êÁúMѾL¼2ÍÂcb4ó®l"#U©Âˉ†s’x1dnMJ‰pæü¢3Å„¹äEÊŒ™’ØÇÓGP Ø5  0aÌàSNX£…mpöq[®µ.N¹Y¸d ’LýC¾Wµzµ+×mã¤àÐ…»~]WÞ×'S¯Ó9öi7Ù瑹«ßÐ'/È §b눆€ìåÎ%ì#È{ZË™–b~Æ3Ý‚(Ï5Ühr"‡ð”p#›]’è%Œš%q$pB<’;\íÔ¦)7ZŒ4žbш䙷Œ  ÜÂcûÈTWŽ&ÎÈÉŠ’Ë)̧ 6ܯuvÈq –»½…¸ÑÞDxØ‘{‹R(¿ØYfé¡|²JQw(±ï«ºïçœ)K£5Ž÷NEõ¹Ð2Ùô\.M|‡*¨Ÿ´Ù‚±@§ÀÚ,­B°ÕÙ¦óÍœ‰hk°Õ¬¶#ëV½ÎÔõz‚M5övEß–ŸCéZJ'˜<35Õ?ãMþ7TSF²1ìP„ÂJ¯vû¡ó¸”ûŠ£: ‚%VÑu1˜ˆE3wëin WÃÑÌ+Wav,ާ¡Gª'm¦fÀމdƒIX BÂ,¾Ù˜*Tš@“&_eJRç¬æÑÇh,"Í}¥áp*›ÐA„´uxi! i7"#N¡w€*˱Œ8¨hDJDòÌ«B§g€}ÛØz¦­žôÛ 0_1]]¹Lw6*}o ƒò¾qoöK¿‹xj©?’½ù¿üåqž< éÕÕÍM€ Ç%£º©Î›sµ>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 186 0 obj <> stream xÚ­YK“ã¶¾çWèàUµÄăäÞg]N*I%ΤrÈæÀ!1m‰”Aʳþ÷éF$¨¡vÆU[S5ÄýüºÚý²ã» þø®Èw…®XYíšóî»÷ßç;ž±*«vO;^î¸`•Ú=´ÿM¾;Ö—ÉØ}*„HªûTJ™ü{ìúÉd:šûÎN×ÖÏóímm£Éçn:Rëû¼HŒ=ù¿= “çüûÿ=üe's΀¦ÌQ¢r7öþ{ÑšJž3.á ìänݧŒ~¥Š¹Ê™Vþ¨þR£_sžíRàœçÄ™Nz¤õzÆÿû4× ‰£H†'úNÝÙŒ´ÅAçV«»sVø»Þ¸W±ŒûéôlÚ¡kG:¹YIS'uMwþÖ UYOƒ…íïpºuƒ$=a@#µœ†”ç+xÌs êP:i;¢0Ö8Ö'ü”غo‡ó§=öáò¾›ºúDfè[è=Û§%—ÉŸŸ6TgŠU¥gÔoïÚ-yh¦DX7Òõ‡îWg3=°'Ë‚ ¯þu¯æjhÝnæ<Ö@V²J¾¢~Á™Î—kŒd&XVÄ2êý`½”ERôõ~ oT&Ö*΂@7Ç™Ž íOh l;ƒXÆ©kêÓÉûLׇ êÉßP†mù™xÊ5Û=áKZXyÃ¿ÐÆ@ü š†t4W™ç³1`g%\5Ð×óNëhZjÕÞœöñoôeV¥ïY•+Îõ[¬J±22*QVI?L¤fQ‚šuÌð¸fØé[;¼C…€ÝÕô‰}E£¯0BòZ°ˆF•kÑ(ïÁðõÒ€$ ŠüWy¬QE0+¨‚ñâ5óί²×~ œWleß„j•׆ôÚkmH}Gœo³.ÐÆ¢µ‘®=Å2—<ÈHè&úŽÇázj©½XtÌ/W'jé­ɦÿ“ïZë|ï7EΪ”9Ô«zTÓ6å¬?ìTK`(EB%@¥'jÂÏÎË…-DÈñBÈ6„Ä9Z%̓Imä½{âÆ”o¥ƒê~—Þа±öºÉ ‚aWò1L8IåUÉ”wM’ ²ŠTRÅ"Ä2qÐ'S¾9ô†þBYñä?”È`|*<7öYmú¨ X ó`¹Hú Ènð¸ÛB߀®°6f`¯9ê*Í!XKwÒfºZd°€äš» t/­¯>­W>]ûC&õ¬;ÍOÕ„ô§ÎI È)‘5k| A¹¶‚]ži&‚U|„¶å„R£.iá» ëÒL‡éoŒµƒÝ‚ÉDñÆ3ú§áÚo’-‰ÞflœE陿9º½à}%¦•Y|QLŠcå#w£ïásÇɤ>=ן»3 ‹†0Çœ«9[Ì<Ü·t@ìPé©ëv5ëÁP¥¾.«äl¦ãàH÷à’VOIݤ/6¼>’b@tIÌ\ UB:Ñ tEëвkÿJ¡†i÷Ž}rò-´Šåë׆%­Ûyi鎚|yX¢¢M™I¾¼°Rs6ÿ†ë8bÛO€cÄȱ£'¶|ÍzLŸ¯ÓbŒqzTâ¯Û¥_~';:™§éw&Z÷Ž‚ r¤êçëœ7ã?Å;zUÈXI¨ð”“[e4$HR¾dn¥‡bø»þXD\MÛ¯„E1WeÎÏJ‡Çˆ0€S)¨î ˜W‘áÝv¬‘6¸ç Zä‚+|Çëcïó—Xâ6*J`Òß]%? ÖDôZ‡tªUr0…Z”ÞtU2‰¾*ïH¢¯ç[ ¹©ü³å§™p/EÕª‚V!M(©ùÉ/ÔÉgWYWb`u‡ß«I–¥ Ð($ìãÃîŸø?¯ç= endstream endobj 187 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 189 0 obj <> stream xÚ½XM£F½çW Q A/ý ޲Êf³{ˆVQ9§õ*bp{L‚aíüúTÙØn{ÆÉ(š˜.^U¿ªW]LðW€ƒþpÀIÀóePo‚ïçÁ«÷$À)*Ó2˜¯\˜¢2 æËáÛuu/Å%”Ò°œE c,ümlº;õˆ…r-ÌÚ[{i·#ØïÖ?4·C5<šÅ‡F®ÍÝÏá¡Z ø¦½ëXÜÌf ú4ÿ1`#ˆ)Õ‘dT?KìÄÁˆ^éØv‘"¼ ,–à‡•ájè7úµWï³ÉyŽ8·¸©]ŸRP¢ŒÚeÙ{Þ~2»¾í:N'â ÛnnýÊ\)6£·ÈQîÞKŒ)^DžIª6o c0ÌHø°nZav]Gó«ìc?OžÝ1†sa`{œ!’?“ ÄÏƈå‡éôÒ’£œ `S‚O‘Ñ–å.Z/]˜#¨jc‚lqD(¸oX?ŸG {劄õ *i »2…܉_!•ûDÿÔ/…/U9Ê=ðžeᢖ±•„‚¹ï„.[¸“½¹Ž÷§"u³zô±L8JûV¬¤Ï=A%ÞUÊ)TœKÃÐÜ­½…ÊȾØ)¯p œÂѼlFYuµ–í‹wæIh‘"œ›äh«íh):mßh€tZ0Ûn¾îTFôí·ç^ŸÍTÚ’×ÞEHc“kfwI_DL8÷Ðߤ1¹ù´Ïnâ‰ÇäµJ…}r³Xt7ž§¿*Þ1t2®ùÁò}Œãòp u˜¦)âfƒï¾ˆz+m‡r\7£¹«{]ŽV€*`éÓe:U—¦‰žnÁì.ìöIð)DϦ!ÏõAÄÓ°’rhn·Røbâtß`/æ‚^ “ð+õÂËsz)Ž^à¤sÕÍ0W€ ‡â ¼§åQv‰0{²7•žÞdˆ¬TEhéÝØ h)föøH(–âiúnUY<šnº'•$|‘Ä£¿ŸÉÌ´oœie|‚r.=FÙÕíL^H'ˆ:ß!×½>_—£·½‘>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 192 0 obj <> stream xÚWÛnã6}ïWè!ÅJX‹+R7Ëi ¤AÛ¢(ZÀ}ŠƒB‘h›]Yr%:Þ è¿wHŽiÍØI –Èá™+gŽœ¿êðG”9i’‘iæ[燅óá#sh@² s+‡N’,vå{»Éw’·ž†¡›Í³@ø,JHùÁdjÜÇrºª›’‡æù{\’B!\ºté]kÀ`迲WÏûóRt2¯ ~m1Ά™†úì ‹ÅµúRÅ$‰lu¤0b·è˯rÐ_Ÿ0²Òe„g¥ÙÅ:„êR6ÁSêÊÆ¬äæ§‚Ü™feVžž˜-.ˆÕ‚mD÷|¥òº4d@ò‘’šP9𑏫¶ÙÐNÊL!ÛÊ9ò¾ÃKtÚÿ,•;*{:*ûÓó³Ù¯ åÏÁô¥Lè$ ¡õ>ŒPÙ[PÙ$Ôô2jøTŸN|¸ÙeÜn„{gâ21˸3Zq¯ÏìY3º¹h3çmg°õ­Š×k¹KNý¾—qïlޝœéàŠ‰×A\þ®G>®¿¿ôÌâ?fLÇjÀÑ ~w%î_ìÏW¢Ÿ‚ðï©Åt vTCm.êmÞqùgÅWR•–5_ç€Ù«€Ùù:P>³·×Õ:‘"Ó«±•…îzŸ·ÐK¡³JnnƒÖ”K“4³ód£0¸¢Kƒ+!±up)ÅÆPQ龞«þ„F™N_U>”Û–YÑÙ¦a¬hÝ ÞX #!½HÌ‚ÐjW:…¹Ø™©ù‹2KŽ4Ò'Yº/D†õÔ¤+òÊfBÈHš Œ!–ÁJI?Y‹½¼À€TÚfjx­xÐ4V“H°ù%Ò±¥ƒ7†å…PR`Lj©Ê¯°ê±v?L²QcØ×… ¶§–Ë}[Û¨Ý4 »\6ñiz:‚² ôÕvPàõðà‘1%#{' ¾Âh*#CDÓÈÝŸ…Rx,4ù‡ÕâøÒ_ó=ƒjX2%4{]dPV×iÝt£ÈÜ].ÚƒèðMÑûŠû*yu·ù±UIÚoÍ’"\ðŠÔ&_óã²á@긹¹m#J¿õgb•¯5ütà’‘þª~P‹–ä…ÚˆÔ§ˆx¨xÏíÛf¿ÞŒˆ~øœvK-EšÀ½&dI‰•ÉÑ‘ Ž[ä·;h^ÛQ‹Ä+y2Ê\æ(8Çùvw?±´ß¼û<|÷Î"vàb½‘¯”Ð^»]ÓS¶^6°ˆ–HJˆÜ©Y~%Ù¡äéPL¸ZÐ1„Xæt˜³øùÃùªpÉ’AJ­Çrfj êa‰iìÍüqáüþÍqÏ< endstream endobj 193 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 195 0 obj <> stream xÚµXßoÛ6~ß_ᇕˆ“(R²3t@×­@·=lhö”ä‘›«~d’¼¤ú¿ïŽw’eGnœ!…‹"§ïŽwœý=‹güâY&gYº‹å,/g?^̾{'gq$–Ñrvq;‹³8K=»X]o7殳ÍÜ5¶E%ôŽ@Ï )Óà~8<è=˜8·ÅEixíÚ®nìŠÚMí!†÷®µ,VñPéò¦6McPâ €y(HƒÖxȬ=¯‹mYy=‚Vù}Gz\KOS´5µP¸ ¹)&0w½˜iû©]ÛÖ6áÊ ªª7`åÚÎxÿ{ÌìS”6ãÉIPÔÃb gÖ´ž¦‘àmÝû`ʻžODËÞo}¼ø¹¯éqé§èXh=¼¼>{lí%AH„ú¨É ñÕd½ |-‚”¹ö3B-²„f¥~Öõ÷q*É5RþþAaH>v†\ ­¾œ:2*cà ‹Áƒju°ñKåõ;nÁ"”ˆbÍuÔuï \.˜vããÇÒ‹#M¶Ôè|T€Æ^¡!™Q@ç$ÐvÐY±wRÅc»k´[K¯” ÷ø¼èz=:ãô^¢Jœ<²·r_!7‘sJÓ~œòŸ˘EÎ&t¤b)yøÞºõ¦›Ð‘@¥§éèSµwuk'ÔPT÷jÀÂÔÛ¬«‰o$‰}pñ'ìèSú“H¨>¬1óU¤F¥N“¥°§?‘/™HäNñcð)(*²±g^½š‚¨w%ÉUà„Ì©C%ä{ëc×ï­X ±Ì°•VuÇ{ﺻªÁËõ£Eq5ß鯆-¶Ú­zUï­>¢Ã'³¼‘©gfÅQ9Ì ™ª±=2Õ>1ði*~>,v°Ï»eiƒ†oϰ¸ð£¬°gß ÕÀŠçx_a+7E¾-LÇzõÀü­ ð}:AŽóg&âžÏìß[(g¦ò@ ÙÞt@)!“À’YÄÐjPR e|@y (©5¾^MÇO(Ö_Q¯OÓ{[·xî]$B/Ǿ‚ ¶²ú29B6z!Ôâp™¦Hã,í$Ñ’³*ÒAa«µ?=#x¾ŒT_DjPIYà=ÖvôÆæÑ VG>-ÑJ.š}ÝT¾ÒŠÂ.’ ¹W8Ÿ‹QŸõÑÀÄ13»çßdÚ%q”ŠEúØ'ñ >Ù}3Þù:i‰Td 8=™ÈÏËt¨ÉFe~„ûжXQ»w'#¡MÈSý3íß4!œÈ´±µÔëÝÙg=v°;¡kp§Nôw.€Îž4ª†ÞT^¦´QÃ'Vø/Á|ékP#ç¢Ë³¸Ç©B"Îón*ÙO)øÉûAB%{ìáú`à*¿Õ¿pÍò¥mÍ~‚š¸)?*(FÝ->“þ\ˆM<îàsÿ¼Çò~ÇÁQ6‡N§0ÓÁÝ“Á":ùr)Å"Ù/ èŸÀÃq‚êT<‹$›8×*€z5×Õœz4Ðð>ÉìX|EÇÇÇJb¥£ gz¤L3”âg©ŽˆÃ?‚úB1s¤\çBHT6¤ºó…Äh³æó%ŸÃ¹úDã¹ n·UÞù ‹qÉÒŠ~ Ç}<Ú¯¶ZA1؃êÌöÅ Ø!ü¼Í ·²¦:`‰—Âqs"Ž·ÎÔ?…7EíKOtŸF¥c¡ž‹ª´Ý¦^=źèBÔæX˜(º¯U‡gB}7\}%j¸HØ8Û˜†„]Þ_9äwóý=ìKÒí©©qg\Ó_1Ù06,¤’ßÚ>BüRQQþ/€¥yp%2˶ yë ê¦ç?¼îlˆÕú•ÌÐGÍøùböÇ7ÿµ8€6 endstream endobj 196 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 199 0 obj <> stream xÚ­YK“ã¶¾çWè*SUK,‚ ¹©¤j³e§âò!N”\²9PfÄX"Ç|ìxòëÝHP‚f&ã-ˆGèn|ý‚6?oø&ßäb“«’å¦>oþ¼Û¼ÿNlxÂʤÜìî6¼Øð”•ÙfwøwôéX=ŒºßÆišFå‡m,¥Œþ94í=Éh6ã‘ZÛŠ<ÒýÉnøñtßõ0yþðÁn°ýÏîûœO‰á$SfìýwÒã5NË„erKGºÏ Ï-eæK%˜ÊìVßTßXŠ•Ü9щÂòõP5ýc3X«­PÑ—­(€óê^ǧ¦ýi›©ÚDP/ÂXÀbº‰á˜4}5§õ›8­u‹¼Ž}×.Ù—lÆiÁòøã,ãfOs;ˆ<£ óà†8ë_:WQ3зíFjT¸øË6Ë`×Sµ?ÙuÍ›6ŸiÐ}|РÙêša¬ÚZSï\}óË|rŸ€FSÆ ­Õ0˜• ƒ/MPn&Xæ”{¨Æ* ]!˜Ã³Ó°=’”Ü\d™³$})F÷øw=N} §æ„T<ªN“;'æö•4«vGT“Tyt7µõØt-öЍ7» Ô©‚øHà`bp×k¡` ·$Ý~ƒâÿ«ë‘mãBóÉÍ)3GuG÷\5­€'þÙR±ÂíÜNç½s Ý}›QŸ‡Ó…bJØu1‘òã sTm·•ƒÞLeÂY)ýë~<ê‘‘gÖå€9þtF+Ý› ‡@a8âšöë/΋ռø^·Ú-¾z$¯fY²V¡ï _Àý­ÓrsšŠ¬Û[AÚœ,²èÜÔ}Wõ½1¥§ °08éq#Ç2·¾Þ¦ 4ažbö*}ÁXAõƒc'1ºI8…Õ”åN–ß;†J"g™Ãø„fʨ-ÏhæHø§¸( `…¤„dÛm Ð6?€lõád]‡¥Hfѳ“€8ê ˆý¡;M6á€eåkGß»<Íx{ÜΑè5úýŽäpÏ´Ìä°È9 S%àÀØÙSŒh¦YN×áÀ‹9˜Á:÷ƒÛÊ<ž‹OØÕèZú‰;Á!§F¤_\ÎüO÷µÐ[šxap^9\³Mƒ`¬®ZÚÒîd—Ôuw~85ÃQÜA³¯^I‚Z¨¥†ÁPÞ™bÖO·~ëÎÁ —ÖŸõx´ú±fÖ’™U-õõ/ ¯¥ÒX34SõB†¨–e²¸¾zŠ»äM |1 ¬lPK 9ÃìˆÂ¹K˜ëì"¿R·ñ9æ ÜóªÎý«}„Âܘ^hørÏИ²Ø%4€96vo”jPÞÏqw©ÕÄ\«é“¯2†<2OR¯˜¤Ó :âU¤sÑ*¸_´¾,=od/ÞS«”ëtô½QzÂ=Îþ5Tž?+Nâb„…žæñY3W7ÞæßìHŸ |Ao§‰DØ4tñIvã53±¯™Éœ« 2 iAžn!aâî†c7tú\/!K¦Ó ÍØ AÌ$¥ÍyRøZ\·V+þyªN&Ü$E¾¿ì–ÒÊ4B/§ØkD<“$ã¿ê7¼á§Þ>¸ÎÝç7üÕ_dUK>èéÜM6«_?^\Ÿ€,ëµ·w™îŠ‹ä_ä릲ÿ/ð껯ÿçXº‚ÿGÐ\UÊ…ŽÌ{YÄîêÖÄ,$1*ÆFÐ^páQÎÿÕÙÑŽÁ½¹W>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 202 0 obj <> stream xÚWÛŽÛ6}ïWÁ+!#R7ËÅ.º 6@‹^Q÷ieŒLÛluq%Þ4È¿wHŽlÉVìMaÀÉÃáÜÎ eýcQ˃µbfÅQB¦‰•ÖwsëÍ;fQ$^bÍWZÔ'IhÍ—OöÛ ß¶¢v\ß÷ídæ¸AØ4²\«©Àn7¬½ÅG¾kXÿQ¾¯yýÁ,îe»1o¿:,¶E£À‡|]Õ°XÌf(ÀY̰F èäiMÂXϽyGC¥Ÿ—P¥¬‹7{˜>>ób› D‡=Ë<Ë¥1‰| Û5¨ùùáßè½ íjüP  7eµÔ¼ß}nÿlö3 ÜûRìSۛЉGüÔ¹&•}‰T6ñAj|]ªÿ%R]:qÈM®ËmrŸŒ_&&èÆœI_‹Å%ym-ÄU5çB5—uäú÷>Ûµ©}%r°Ñ®ªZð 39µ¿½á©cMÚ†*õ†HoØZƒxõ˜‹Bt£9ÐÝ÷gš–¯F¾‘¯_›i·w†Yû„ùÞg²O¢ Qz8lj·Í9ÜSô@Sï\Qßfç*6Ñÿ³‰mò®lòÇ6Q´Ò·h@ü €¡‰‘ÐqÈٿ‹|åþR¯y)ÿ5¥+íŸø¶™u5'îÉ  ”Še©©Š¬W²†p OBMÙ™oÆ*c$`gSë\j̈#xµ+³VV¥±XªÂ^QÕµÕ e6áÜDÈ40Ѭv¸™¯EÖòr½Ë9ºr]Ë%Kš„ªx¸,"~FÌþzËk^iwS°¨è0½@.yÛ‘õ«ÉÓb1¡(oþoo0ö½ëM{häµ5/›mÕõë@Ëgå!ŽŽ?¼(yzÄ—²95F 5çUàbiƒÂ‰‰%—]źPpûyhÂÙI?éÁp I4Õ‡=ÔëÊ@ŸËLÐ˘©ºYôÚpêÑx$±(#Qˆ9®äœà"áŸ+Q‹2j…®2OŽCÅ‹½ú«Ü¥-`ÏÍÖ‚·µ|6À¬2â²Ô\Qëú¦£×¢Ä7ñ¼­EÓhú©±Rº^À"{¿=ÎC¡öbçä5æ]ÓB?Y"ñ*­¢»—&+¾%fS!³ºâuÍ, :Dô„õY•ïŠRË!#QpU<öÒ8hþ]K¢~Xë8¨'Ç!Æazµµ‹ƒV+ó”Æ6±ucPÍÆxJ‡GMì72SžÙ¨aˆEEŸY£…lÔ½•@€À߯>sA5¿cÅo…>­CjN»Sau!Sgã•ά¢À÷¦.˜IøÔYâí+õ–ñ<ƒþÞ¢ÜP÷Š5Ĥ/æÓãÜúí«ÿQ² endstream endobj 203 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 205 0 obj <> stream xÚµYÛŽÛ8}Ÿ¯ðà ZÚŒDR·,²ÀL6fvƒ¹¤w_â<°%¶MD–z$y;=‹ý÷­b•,¹[Nܳ į§NëÂ^ü¾ˆ!ü‹©\¤I.²|Qì?\-ž½–‹(y˜/®nQ¶ˆ”ÈãÅUù.x¹5·½m—+¥T?_®´ÖÁ?;Wo°KýÖÒØKþ©öÌ?ŒÿÃ]·¦½§Á;×o©õËR¦m+ÞðûjÓ´0¸{þœ7X¾¿úi¡e$Sè‘Ä™ï{ö:ž`]©<:_¬4ˆ#ý¼;ë6ÛžçNåR©ˆ4ofß›ª›ÙPI!%Oº¸˜Ù%ÒB*ž°œ°âr¹’iHLÈX5ʶ¯*üRA×#<ÇÔ%ÏizlÄ¡ïÖÞØÖÖoazþ­ªõrÜ¿¦^ž–ßyAà¥Ì‚¾£#Mk=ðU¦D Ü€6#Ò¦éºýΖXÝüx3C@œ ±|}kêî¶éì‹á I&Ò ©ÂœÍ!ŒƒÊÖ¯ìPÍ ýö[×QË´­Aäh¡ vž±®§/VðvÄ饼F:o’“½‹¦ÚïjÒè*’©ÑTpW£Ý…ƒ¹†Aizƒ­(ØÐÐG¤D«yJ¢0Yò˜“è NÆ3£‘èô¸¡Ÿ˜5Ǽ˧ì9PM …Ý»m³¯Jjt2OÐ,ô”Ÿy~E80ÐgÜuÔëéLý@Ó ]:cŸ 3KEúYá2¡·†å#J·#…÷1õ4Fä"åi4à‚«BS\ë¿%ó”Ož)ª)w®ªÈE!YÀÞÍmê¦Å‹CHõÔER$1ü$B%äÂ(“ÛÏ{`E3¢‡„‡öú›g¸sµ t,wƒ¿*ØXîµô»sEÛ ç£/ð£,ŽwÌ8PŸõÎ OX¾Ì¥È5|{kZ³ûÏúç½B2Ö‡+àyÖa*T:åyÀP×ãZ/©‡@Cã4|OA§ð}¾ÂÓˆ£SˆãñÒê8œ!Ó#e7@É~r¿rêa[¶˜ Ô/d3õÇMëÊKÚ¾¾ÇÓÖCh~hÐßÈ,<hK#²„pbÃÑ ±ÂH“kè*]azÏ:N¡ÈY/è%ð·°UÅl! ÿÑÐæÆî @hüo¡m{8QŽð±ÃVc~ÑÚ¢7õf_™–2‹  O¾ÛºÜ>XûÖV7«ŸÛ©Ýœ™¨à¹¥|PB™ª€íûÏ«,=We®v}oöŸSÓÕ:ôózk­# óƒjÏc7þžkŽ'8¡¦ÀŸ²2švÛøûBÿ—¼l_½kj´ë$ Еb÷Æ‘jLrØ‚ÇÑþ›aüÙQðÑc¢´•ž‹…<Œ—5I¼”}²×N(íÙW>þK”[³Üø‰rÏDÈp¼²§YÖJ¨!¤ÜC¡%g+S{ŸLž¶ïlIùˆ7Eø}Ó­hÊ+×Ùú‚çsÞúìj™I0Vû/gï†l²é£h{Û6 ö‹™ÈPÒ§Ì»ŽÙX¯8Öã…€Ý Ú _Œ¾yupËKA=»/xcJ×õŸ“äûáÖÛk¤5)‰Íæ’P–>u}¸ô—€çŸoã´á’|B^´‡ç3RfX)=Í‘_³…”'CâÍeQÑ´­­¼*æø•9ç§ñ{aÎ<Û\wëz¦kz'ãÁRt~ ¤û3‘‚î8ÍÃpûT<çkíãŸbŽÑ%#:ùUØêÎD÷ö–¬Ú´;CÎ ƒ«©?F¿´gBû»­KÈP£KÿÿugÏ„ðj_T®´¦~à%¾×gâxéz‘W×Uã­wtfQWß摇•„Be€Nôüfû}‹ò¤®qùkÜð±©H4G Œ—Rˉo”Ó0Ü­£ðÀÔ8¸‡ËS4•/ŽD 99'ƳɫNÐÇq h'1Ñ8>Ú pÆwMž{2ê9¼Ã@׬J·³urø§Øi(T)F羘ž™/#¾?W.Óá)g( ±1ŸZ'ôÀ!¡¾ pIøÑ*29‹è\èäø-ÌïËx|’ÌàQŒgò À °áы˚J<,é0ßÇ$ꨖ€ò`ãHðEïT˜pÍõÌ«",xgôFcú÷”*oªˆ<A¸ê§V;Ç@>V×0sJ’˜1œ¡£8úÁ{åJÅCÐOègøð«Ã£˜ï\?¬iQ58Ëç·ã¾z¢üâ§xúj—)Lêã0^¾žƒÄçÛ ˜"XŸóAù„åúÁkÌž2…¾ˆÄÿ¤)ÇBOœD神žõ‘Ä÷ôSpÉÔ– qoy•'0×ãj,l©EBL†¦…)çû¹;Þþü†<·¯ÙrLro •¬rL¨ðòPDn8;?Ö¯>T,°ÖtÛÔc.®ð­ZÁ5'ß.3gN.P^"ƒ×XéûÔ8ùhh0Ùü×_ÛÆ•ÝÿFédk ˆŽõ‹hÁÜ‹½Ôúp¹"¢ûÝ= ð¿È$õ pð0BN F~¾UÁ‹¿Òï»wïß_Nß(úíL÷áxâÅÅåãç†ÑÀŽæîk¨Lg¦CU¼mÌ…Ìšf¾ºZüúÍÿ Z½ endstream endobj 206 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 208 0 obj <> stream xÚ½YIãÆ¾çWèÐFSÀ°ÌÚÉ f€‰ÀANÜöeÔŽÄn1‘È I¹mùï~¯^‘,ªK½ÄFÐ@³XËÛ—¯¨Õ¿W|•Á_Y±²¦`y±ÚW¹Y}ù­XñŒY±º¹[ñ|Å%+ôêf÷1ùj_~ªnJ)“âí:UJ%?öusS*ö­}å‡Sû§õ¿ÕŸº²û•êaO£ï×Â&Uwð?îÛoßzëÛ›¿®”à dÊœ$ºps_~«YSi5v•*PG¸}CW6ýç¶÷r½{OÏì;ž*SГ†›õŸÝJN½Ä›äj»+‡ò ½^meÿ¯ÍÚ“&·$ñ¶j†®­wý&ùâsÙ•GØF‡Æ]pÙ–‡íéPUO'cz’þ¥jÖÂ$Dœyš@èd÷D…dR9¢ºûÓŽHž ½ß­ rtmÊ-3´“q±,Ìhoz´Àsº|èºІ+l²m|ʺ¡X€9R¯(’ûªq£<©~ùÜU}_Ãn÷îm­¸NöUçwáþž†å8×mWíhܵh ‡ô¡v^Veã—Žuúػۮ-q¥@9Ö©yºm‡’÷´²m§cãH³ˆ5S²SÊ!¬ÌKí‰Aô{òÌUáýƒ¦¥§W€L(rG&0!æ‹I_rêÝsùÓ:—Iµ…ôÃ1™ÒžG&¬,#&†–¶† ÓAµƒ¦P†KÕ¡ó‘&>QšÚæ¾GÇjw¬9Süºiè" ¡i²¹Ì%†r ý}ý³k]Í*Þ‘P¦ËÃúA ³¯!äXX*ûjóÎWû–žJáBÐ[ûò¸l Ïy]¿¸Uþ}Öå?`q¥·5TXŠE^¬0xéÅÉ* ºb¯ð°[8VeC£M&Ï™• iÞ½¿.ci4Õì¿Èª]òF^»š¸™8·<ÃŒ8cv|3ŸúÐT4ÓEhSîÑ©¯Ÿùñq[Ç„éþ°ž¡Ï3ýº¶Çšºj¹{GOߘa䲞Çú¬YfS¾ú³Ü0ðqLÙž9Ð×;¨n;LTÈÝx¢r5WüIxg1A¬`þq1·ÈUèX:ÔòÁe*Z{ª­|’ŠÄ„öhË®šÁs„°aãðÄ{¿Y£&æ‚&BÆåcMøMD ‰š[^nêE†‰šYˆ/ªËò̃ýˆk ×8•"ˆ2ämUíTéCù¬J~^åîTõâÌbÑÄS7ûÚ3¼;5Û`¼uŽÚõªäP÷Ã(L¶hî‚É1m·]X?G@‚Ž3*E@ãR«/ØxÛˆæ¤È8“üBRr~!+¯bÒh¦tD£PšÔí !!AZñ5¡è0+aú1âÎgÄ=¼CÌH¢Ù@€ßŒ»v~Œ÷ôîBÈ‘©û(OŒÎHJÛ ÍäëgWJäætüäï{]†e*ÔyŒâ)¶#Fü…ž÷Ìâ òkÝÙùxôJ—31áC )ÄtaÁ!%3f1¾y5ª$½„×vÑ’a–¿Ò~ •ˆ¤ÿñ°ìDèPð¾ê1úOxƒgãöi{iÚKÛÇ5Jè…å`Ëd9,Áp‡ùq¢Aœˆ«¾BÓËÆÓ-&?\¦æ%Lyæ*ry¨³±¾PÒ˜(K“Gªª±iÌ‚‡;dhO[(?aÉ‘d‰7ÐòÞá 3µc-îÉ&Ÿoä‹¶~׎آí`;]iÛfW/‘ePrÏê`Ur±‚c1Ð2ìËÖ®¥¸wí©Ù½ÆüïóBý~T1}ÿA•CWÿBc÷éÀχWƒ.ÐÊ·6÷^7QY¡Àqó;Ë»”sÙ¢.oÂ+«†ê0ÁŒw«æ»Ä<Öét¼Óá½úòeÞ„xËšðÚ¾ÊÁ¯laü׿Ù"‚©ëTpoÓ2´^&}[ƒéE[Ó¾Ši9¶5-|[3®­iq¡­ |›xEYžsꉲYä“Ò¿§0¿ —é§j3çèĹ8«ÜŽET守*p*7‹f¦…½ÐÌd`”ÿo3+ð“S”. qý˜™²,ËŸ²\2ê§wÐ#ðëâÜÕˆ¤´Ë$ä/úÜæ ;~Û-˜SácÛjˆí~(›­û„—¢¤Ö2F8¬Gkמ†[’B4|7Çw×΂ÚÉ8í/¤A4;Z÷S9Z'Fk`$">;™Ï'K è<;þ[P³”ùõPýocŽópM6”£OO_þõò²% bíð7 úõañ…Ï»G¿}øoÃÁÏ$?ÞÞ¾‰ü‚md±ñúš¶}s³úûŸ~&BÀÅ endstream endobj 209 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 211 0 obj <> stream xÚÍXKoÛF¾÷WðÂ2äòí"Ò4ú8´¨{Š|XSkikjéðÛ(úß;³3)™®å "¹;»óí7OÒùâ„N¿ÐÉ„“¥…ŸN¹u¾?sÞ|NøEP8g—N˜;aä‰s¶úì~ØÈëN5 /Š"·8]xq»´Ú¬q(v»¢¹|©úäwó¿è‹F6w4y£» Ýýº™«šŠ7|_­ë&·§§¼Áâüì''¡˜‹$ ìØ›OÉ«e‰/2Ç‹á8ÂÊÝ(½Þt¤æí;ºžœ¼¶‹ǃ£…t´’4…û¢ŸÏGˆ®t{¨\ÍiߪnS¯$åœd×HÓ^×­ÚHÔ‹<ùD~¹ønØD¤~DÚØK÷”¦TËïG—û&8=åcïV¸ß^ËFno>FÐ!ÚõÁ)|߬û­2‹(t»–¥ã‰árt0/Ìü4&ÐA˜ÍØ7~š°¬d'Ydê®{\½ 2·Q—ªQs·«é*ùïÿjo¥e«k#+Zº•]£oI°¬ JuRëÐ8o'×Êðº½nT‹›Ð3} ·"uo6€ã¾IqmK¼Ë†íÚvu£V5Mm!z7š¬.\iØW¶ºljÙ4rÛßÑ$Xx€4x ¹¥™²®ú­±ûø3Vðˆ_/LüìX3le{u„D‘NÍ ŠÌš¯’Ù ù¡pé`¬/éªéhj­š–¤Ú e­ƒ7]"1|LÈeHgà ¶ºÅìåƒ}€Í/gN»w”WÖåÿÂSÿí½û¬ÏáïÏó·oƒÂ–åÌ“õþbftD‘/R–dv¢bnÿ(ðãWé½-ž(M²ù¥mÿn=‘ù‘7žI´q±M™99™ƒ˜Œ{éj_ù¯Éow…±¯ªÁë±V°ÌÎÉMÝQ Hzž8’•f«j¹÷7»;Š©x .SÑÓŽµ Ÿ `#‹Ÿ\uŽˆ‹4Þ‹‹4¡¸€«4|µÑat£ôaÂ1Ë&ÊÚ4†º1Ž0êí,oxAYû³‹]c©Â»RVe_ÉŽ÷MÜ!Õ·>yïãññàÁ£ÌcfG}ée5çV‘ðÅàwóþû":ô'‘Ì@OüI$BëOVýI$‰M=ɾàQv|eâý Zð´ü>Û ep[‰óÈOŠ)7²m¡®l®‰ç¹Lr?2Æ®ÐÏgˆâ,“KTAâVʬmo Ó%^» ¦¼›8T@XÆl›O|3áâaÂÓÂEÎÜ `G8>PŒ³û„ãBöŸáV¼>Ø´U qE÷#ߢ(,ß8:Ã7îð?çÛ¾t>Þ{ „Ú(¯Dàh:ËnÀJI}D¼BÏ4Ü(Mz·¡= ±ËÞ”}ë±Bõ½@¦¦ãôá׿'ñ¤œm²±áæo eÝ4 {šÚÌövë£'ª–Gª–-ÔÅŽÉúº°-EÏopT‚&_L^h$P0GâwÎsûŸxcpéN¼¸öHp¿ó»µl¶Òœð[;t%WdÎ@vu$²Ÿ•YAË:`êdÿ\Ô‘>öe¥WJšƒôðL0.Ž„ñAÛo wÞEUÛºkÜÕ㠒ПŠ¿Û=_²µ…Ž_Áp Ò8ȼc¼òΗ{……‹ïÈqY÷æ¹²ï±)ð‡I…ØÕ‚ñƒ›¢—t1¬ÃH§¯@êãQøØ šZ¯ø“ÖºJüN©:]òK=8àrañ}>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 214 0 obj <> stream xÚ­XKÛ6¾÷WèÐbe fŧ¤)¦ Т‡>¶§ì[k«µ¥­$gùï!‡zØô®·(X™äh4ó̓ýñ(?¥"JMβPéD½0ŠeÞÿ–“»$qÜK¹$”kê h7CvÍ¿qDt–_`߀ݤ:ñ;½ÿàè#ŽÈfû;œB©ñel§îWùñ¾-»Î[¾ä:eZNËu]ô…ç Tš­MæŽ6j"|åZá¦m|)=™ @$1á'ßÜ!ùÊ£SøÊ麉鰂t,hæ«oÝóÝ»ÛÛ§;å¾èþš ^]ÄÊj³í/)ÅL6™‰š!úGKR¹t•0m“‹oÆÓÙîË£duJç½Âç˜Ñ«;jUÉ´I½n7¤›ØÔCt:ÃsªmOòRÂeÃò×z ¼ I!«îʶt4!Éâ¾qÏ‚†#Í]®+°s¶Ø¹W= (¸j_.ªÚv\wL]âã¯IâÛ1Šô9°àÅ"⚢ÝõMë»*Ñ’¥§ùb,˜ÉÎh<Ù\¡¶ÕÑ‘ÇmVO˜ùZ|ŸG|mÖ?‘›iDžÚ8à³ áxüšÇ_Ú‰Á>+ç[¹±»J¡µJlxpâa üÙâPS)Ûo¶dľêð„!ƒ”a²”hzýyùí»êþýy{†á*9íl X®jåZ¹™4vò‰~™0åû9kT¢&}†ý(·Ç£»µ£âT TúŒR_·z¼ù¹‰+V²ãƒš âa·óiwN/޶…ºé]%~›ÉÊùÕÝîf1ê™KKgå¡ºêÆ—O7Þ!àÁ²@YÔå/( £f…a´+ xâ‰Õ>‡]ÎJ÷!œs0Ⱥs| ëÞ®’Bȳ“xþ¥w,Vøk5e>81Ü'0—¾OÈYÇeʸ?8”Š](¯¤)M8¡Þ6%”HB@«IB =I(”± ee0¡„Ö¶÷èyðz¢§'%é¯Ý¬5Þ½~жv=Üî¼™d:ŸbStlƒkÛlTK1•ß)„Û ”q*''±$§ªJt¼+뽤…Ž€ýŸýÖ^}$jšP2*°ˆY#rϽAê¦{ô’îÚ¹n:xÕƒ‚Ž>á'în)ñUŸ ¤ŠSgGHÔ™þËÃ2sŠ ¿“ñ›|Ä&­ÝtÄ<ýb–äý±|νUS@A»¿XÁßN²ÄÝœAóœÑÒ0¾F:;Í@:7káôU'L pj©ÏÀ™A;{Ò¹ŒIã¶ ÏÒ'Öxš–X/¶ ¹5.Bžúƒ;ˆ’Heû.œ¬F¦bq°dv&x¨üN0ô*{ÌÜÔH‡þ7ÒòŸnë r‡OBÞLîŸi=|DÂ"yø^×™òfÅ;f¼¾wÒÓ‹8´ú‡ëè×/þ t¾G endstream endobj 215 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 217 0 obj <> stream xÚ½XËrÛ6Ý÷+¸ðŒ©™Š!@$ÉÂõ$Ó×"mÝUÝLÁ6'|( •Äíôß{/p)B2¥(IÓÑ‚xã¾Ï‚· bø± ãA&‹(/‚² ¾»ž½â‹£".‚뻀åK¢" ®W„Wj=h³X&I‹¥"ü½¯Ú{áð ÝÜ}êMë·ó?W·F™G7ù¾\ëõ‚g¡65xYßw&›‹ :`ñçõà,™b+‰ävl™E$Š`)@ng~¸³3Ï^¥¾IÄ%m=[+£š¿£Ú~ÝõúŸ/bÚ²£8QšÒžoKs§_*ŠpUõƒjKÝ»îíbÉóP¨Çû6u‹3yx¯ÛqÑMh:» ¿Y¸Ieè¸RÕå¦Vƒ^E‹%‹ 6¯Å’ñ,Ê|“ˆ¥‡”a‡”“2hur–ð•Áq+6&©Ü:Ô2³ZJOË$áaS•¦SÆ(Ôï‘ι Ë®Þ4-¨‘Hb_®cðÉ­`71ËæœÇ#9:eÑ/ömréîïZ½,Q 0QIaËñ’TÝKªk芖4™x´‰[v·iË¡êZZÔ¹/yÝ-Ùôzu1£f޹cu,NÕñ¼<Ÿs¡5“[A‰RvÆhpJ6c`9‘|êÝêÄ»ÕmÞÈ\ï) ÕílÜÝíÕƒÓ%=9Î7'J ¾ƒ8…8€p¡œ|Ë}ø,Ë‘tr’Žéú¥ûmí¢Z™Fµç”ÊP]Þ8~ G¾9Q´Ÿt»Ru B¹å¹·ÙV2ø#•l¾ÚÀQ‘mëÍ¥¹ß`,€‡þc”âT8; Û>-qÚßÓ°/âÜZ¿ŠºÛÜî–« ÄÄF{ãV²“]¸_TpÞZ']À–_°‚B„|B¨h? ˜ôbÚy‰ôCgÆWeÚò}ÕÛT-±:ï"mI„IÀS5$ýȲ0®í9ó~ãˆbŸ‹ÂC 86¡ö¶(!dfMc5"¥Àêg÷tãFªA7SzûXÂ1ÓÇø;WÄ>5ŠÄÂS*ÏžæQšlafæª<ùÉm+ÄÓküËo Ï稘ÛÜô^Ô.sÍ«kTËöªÁÁ“q”á}yÄ“ýôÞ# ^~uÜÜã×ËòéÉ*‘‚ú¼Á¦‚ƒ¦-CHøT."®€Ê¸å}ùÓcÚB±tP¯Ùû—çðÃ꘯žœþÿþ—kœŸ®±-+.¿Ry\¶|4æÉ óÄ:Û÷R’ûãð>nã˜{yAƒ„¾´ËPÐ ÙZM;;wÉ»8Ší›{–|÷­úò:øå›ÞhË— endstream endobj 218 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 220 0 obj <> stream xÚ­XY“Û¸~ϯPm¹*TÊ„¼Æå­r¶Ö›ÙʱñÊɃÇ`óÐ’ÔŒ'[ÉoO7¼4íI¶ô h6}|ý‹_|À/Òp‘&9ËòŶ\üq½X½<`y/ÖûÏ7 žÉ,2_D©÷Oôê´­KÇ žÚáWEý‘d~–ÅNVùûö±µ?½[Æ áJ~n-Ì›ú¶‘%<~¡€$Ù¼>t äÃÔÖ§f«Ày·ªc•ê\ååC-<§ ¶³Anoº==ôãÄA«†òO‹vLÎ'ªe½•* ½Gåªgɪ|bU–³°' VÇ,è«ÞÇÎi5Ï¢÷èYŒÑ$`)ØäÜô¥\°0bŽ5öÎ,„Êõ/e“—R0¤'*o !.ª¡O<Ô¶­ Ó},B¦,"èwÀñZX{Ô¶³ØÄÒ¾ÿÁÄTé,;ÃöÍ(BÆD/tP)` l¢+ªBj²°}ÛÕ öZ¤IÐ'={ÜP¾>z’6Ô ØÔ°òâÔ3èSÓ‚Ù—†¶ggÆÁÊä ÆF˜ÒÕÙKç{õªhN:¡á×84è³w¼çTO¾`œx[€ùÎú"йIÀI 9,ÈÇëÂgö¿°9¸ÐâuFƒÈVˆÚ -[B…íhFºÄÄgÑàmí-GM“5z7”Ðô`Uì±îS÷Í — ŒÏÀþ’3â/:#Mð¿Å,»ñþàR: ÙÅóällf/œ p–%ÓôX_ÈÊ×Mê;ï¨<P³,MÑ䂘[KCS+9´ÔNnü*t©;µ³SêSG#[H+Ü,úÍã0(˜#ŒÛÆ Ôyz½E<4ísÀv"ø0 g ߬8š5]Ù9Yí9¥™H%1È6ÒHÏx½™1ÄÞE‹Ü×™<=‚† Øíµé ­Iü‹ñJ³mô‘ºÎc§Ä…î€w_œéQ gVÉyÔX)éj’î”HfrT˹pv:4‘g±wæ±¹w£ì„ñéBnŒ JZ±™—p¡w’y^ õ ÜCf:I¢ɔ㎴‚£Á±Ú•=ʺ?Åq·w¤Y˜äcâãý‰§q@-ƒF÷´£s‹DH9žn÷.JR3]¶ìäwõLJšÉ-ûp\ý§Ü©C]W«¶Þw÷pó]Yî×ÿGŽ#Ž×A{£‹ ˜B>ýFñÊE¯øW±«Ç­«ÿŽ<æüSƾ.Šýu?°Ø ·é{ž8Cãlf+äxê¼+°¤µ _‹f¹´>X–Òó¤dúí'ŠbjûÉ*8×õo¸àhŠ-½>Ãë"ïj-ßj¬øÀ+aÜ/ü{(…ç4EwõǪ·M=Ø×ÚËEcÝ:ê`uq*+£’¹üI~zš?KÙ~ü²?’læF|ltJ³ÛûWŠ÷/\U…*1)+€xœØ­Ž®Á¡yeŸs½ÂJŒ¶ž‚‹S`özOæ™OfECq©Ômk¾‚ù<"ïzï$ ¡È™øí™Â¯èî¿{¦ß¿{öáýË—«¦,JFrÑY‡™‘`yòÓ:°¯ƒ_Ñíƒ}ã2¸Î>pƒÓGfIŒ5ÕªzüâfÁ3M›úðáÍäü¾>U=W¯)ã7ÔŸiÒîóÜIpÃxDÃß0TŸÃÅF•æ¶éÀÿ€¥VޤœÝhBaÅf ËÓ'V3B—Þ}]=„ž .tÛÍïE#@†½Ð©Ò¿œlHf¼…º@CRJöP€¯ö 4ÆÓL1KÚÿöæõðÙ;9ÿß÷´ï׋¿ÿî¿sòï endstream endobj 221 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 223 0 obj <> stream xÚåYKÛ6¾÷WèÐ"2°bć^[l€4i€EÑ›S·F¢m5²äHr7‹¢ÿ½3J–cmÖ.¶AÂQäš~ó ‡ö>xÜ áǽDxIœ±4óò÷ݵ÷ô•ðxȲ0ó®—O=.Yy×ůþ‹µÞö¦]RJ?»\J)ÿmWÖ+ìR~¿64öÂ=ª]òãøå»V·w4x[ökjý¼‰oÚÊ-ø¼Z5- n./݋߮ð”à t ­&±²}O_©‰®â‚qO0GX¹›'N2šZ%X¹¥V¦6µÞ'65>ô0ž“ñ×ë²}…ò‡§¦GUv=µò¦FSz]Ödó^¨0]Þ–Û¾Û±lZjã¤5½¡6ÔºñKfؾēnTõfÁÐUܽÄÎȯ§Á¶5!%°Cúemí:°dܦB÷šZà'U™ çÎ'NˆÊùêëA œDLÅn¼5yÓ3—‹…úsðø_3.¡ÅÇÕ6àÉnf9²Ä íêÂ,g)‹µÙX„J™à—ˆ%ÉÉ`¹5åjÝ?Œô0[hÔ…Hý¾£Î~­qw8€£ur}CïN —]gŠÃá\Wù®Òý0kí$ € ®s÷VÖ4l>":‚Gp4´Ï4ŒßJ}ӣз¨Ÿ13`ÁÍêE¦… …à&?…›ôé)œ1žL6ë>ŒE§`LŽ£šƒX1`µG‚˜üÄd³4%ˆ¥'C ¬s”÷ ‰[°4mk‘’(Ÿ&Û¦Ý xޮˑa`‚ÝPéÖÍ®rÜ@߸希vÏf×ow=µiOQ: “Б¢ãW„yŒõ9¤$1Ë’ÇŠõØN ‹LÖúw©>•IEÝeqbÒ÷Oçc—´ ã(iA;¡Ã¤²#›³b‹(Þ”yÛè¶Õ¸ÎÝ"•þ ¶²Ì¡²Älm¹AHÄ𽊄àûE‰Ÿ˜u Y|^™ÿIîѵtt=¤”E×"ÌX(õH`¾]6 eš0‘ž†§ÓµâÙ”®•ºÆ&î>'t>ÙZêˆåG4âË@ÜÓµ{Ä푸“Ò:®Š89‚Ö=˜‰[˜â¹bÙã¦xó_`n€ @ý<~ÚÕå‡S¨ÛÅd×ÔÈJàuKZº£=q$„4_CÁ¤ ’èúíO¯ß¼~9<òdg³íJ™²Ú<_ÚÂOñȯ]X…ðEÏØ §¹1ü™nåÔV™bÉIB `8ŠüßMÞCæP2šEŠ“ø1й3î»=xåÝ®7½çåÐØ‡Jå9p« |«]cÓXV-J´ØvàyÁD6Ý¢ ö•ÍhH©àèW‹TøX¹‰ ¨ø£Þlï #r¨È2çPlY¥°1®pZÕ¬‚¾Õu%àu# ȉwØÆTüÞúûÇUa–¶U1½6˹’Y¸‡ÙIÌñJÄL$SãŸY3N ˜C(Ü(&P"yÅ2Æ9xHPëËNh:ΉëÒ´ºÍ’C3·çèÍ÷—3&ØOðéÀ&À; „o¶ºÕBø•Cµï®PiŒ[°m:WÏè^̤WÓ¯›âPî‰~2#YŒÇªQÎ8¹@Ex+1¾Y|;ó­»YúŒöweܾ5fÆe"aC½šûDÆä£ž¬ƒg¨ˆÛÅ·37‹Hq"øh¹$αÐÛmUwе!ŠpˆÁ“ä'×Mö@6_bL½Äœ‡g¡9ï¥Lž@jÇŒ6$’ǸÞ$Jž·«ž! ún&פx 7ü ‰fñrÍK~ƒ€´î S¿ÄÄfc­M{]C“óHlÏ#2LÜ9‰Ž¶ÞÝ–˜Âò§­ç| äs¤óÕU8w?”²dà® :1J¦ëmƒzÝvhT +Ɖ­¤«”‡ºb!4Õ•n;fܦû ª‰®ü]åD×ÃRÉy:oŽÕnS£ÒT£µîh5Qi®6¶ç–ŽËî[a05ÖC¸T•õûE5ÑÊ8ƒp9ʦN´9ð.Ùç“Ëû1}¾þWWOº's.üíî’·ºloËãñ¦º2Á‘G©æÀÍI4– çk¹9_ËþXnv›`HaM;ëxâèM0@åŸÛ’žmK~¾-¹+Ú¦,œß£/âw}¾®¶Âúƒþ‹ºñ©êf ’Øy®µÇ…¸ù¾Pœ\'@„-wu¾¿§™ B9 Âﯽ7_ý ¤¡œ endstream endobj 224 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 226 0 obj <> stream xÚµYKsÛ6¾÷WðÐN¨&@$qfÒ4íôqhSõT÷‰”Åš¤âúßwñ"Aªå´$KàÛ×·»pðW€ƒþp‘ cÊ‹`Û_¯ƒËoI€cTÄE°Þ8p‚Š4X—¿‡ïöü~¬Ä*J’$,®V¥4üm¨»[ùˆ†ã¾ÒkïÌGs@~Zÿ©Þ.õâC=îõ·ŸW$ +ј ß6·½€ÅöêÊl°úcýC@ F€)VHXªž]~K¬QRÄ(¥ADA¢änbœÉÔÕŠ –š­Êz¯¯_m_9Wû£ÔÊtÛ^ˆªácÝw¯}E$ˆ0C8}!~&¾úæ0S\¥iÈ›ƒùÙïôçäŠóñ²â=œ‰÷Ðm«NºQ…êLÞ¶M]V¼Ó6•os†ÿÙã›3Ѽ«G…Ѧé•ï·òçH‹ ™½ps\`® (KƒˆLlý¡Bª•Q` †K 1è”!–¨·Öû²,ÜARÈØ’¿òP¨Ýýƒ{µŽQb´Y‹ªòDòÙáýfsýYmG´ŠršO'çz©5ý`ÛëääugÀ±{6es°u‡vc‹”¥Ãz¬ÚÁ:gˆó^¤E±xŒ¬T§ýRVÃ…ŒhŒQE\aÂâa$"ížÎXøYxhW$7:©…–PA@#Ô_ͧûræy™M/ßV]e_~úèA×Wi«kjU^Àïö§NËÔi,48Ö:êDT'“4lë­è¹\…í * ð¢wÑAC4H& ßsñ{½:[ïFߊZ‚ÊC¥<ãZòž×⡌`Swwºëð?ª;i¾ñÂUeá.’cmùEœ«ƒINB>Žp.T‹Áøå6ò›j7ú(EEfDxWzv›HCÔ·{ß. F™òJ*—†’x‘b« ñÇŽ|EzP ôÑYFÌ¥ã2>ê'±r»c23‡Ãf²„Ù ír‚(s(QÒ˜cdõÓágLâð‹XF ïA*UU’â ¥q AÄH~'cÿòiôÁn\˜íˆ=bm5îûr)s˜GR²Ð‘\å“«»z¬9t”KáCWV;Û0¤2éœwnV¯=Ðvá‰û¥Ÿ9¦µNôå¨Û‚^ø*Pž9Ç®WBLñ—.»¾‰N‘©K·ëÞ“¤ó!´* ¯}‡á|æÔç4ŒX§N›ÚÆ7wÆÂ7&î­?—¬lÆ^8žßß7õÔSî Qr”²‹B)碣ü—¤'<{AQ¥ÿ¾~šür¼<º½†^^-”|äzÉi?ìô\w³´'&’e–~?¸f^ô;¹oXðn'©hž~ÞŠÛC ½A]Ýàær)èÌ=gÌr3Uùg¨É¯kk!ãîT§£‹E•¡ŸÈ;=Ëv±xáô5q°B"=µ<¼”km7h®K,DêBòÅD“ìKcBÓsbžÆÔ;>‚žtåçX·ÒøRv&‡EäCFñÙ”¥Knì–ÜÛ‹d½\1s©¦05S’èqJÍ @ÔßÔ-µ™ °äd7,´ÓËl˜€É5ê‡7òž®ì[éJSÛØ;䮬åÕ „M–'B<†0´±0·k0”X*U:Âq·µz¥z™lå‚s],‘ô§–°gœNSÍU0ò"sêۮתBŽ†ê‹¹j Ë#%fÉe}‚Cqèôƒ¾kõ£&Bu/ FzÔK&I÷jîû¸²w°R΂^®Þò¦yôõo¶lqÓïmùPùsI¥ÈËRÉ4œÏäÒ|Ï‘iì×û^ªó Óß”`ˆ¤éÖZ/ØÉ/ÈÀL‹¦®«êêtI|¹>§þy1udöÎ]ù¶ãk$2wu«ô~üòÅ?ÊÖ­á endstream endobj 227 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 229 0 obj <> stream xÚµXYsÛ6~ï¯àC:¡fB„ ÁËgšºÎLÚ¦WÔéCÕH‚%6<uÜ_ß]3ŸëÑ\äæà·.jú Þ¾Wéh°Yõ:¶Õ®ÃNÅ–Wy—sðþ!Í6i¸ÉQ»¥tG¸Ð먛ÍtwG«Z£và j·ºº’ãtµË·jäfÃ' /ò©ûƶ=†°ý³øØŸóóŸêJX¼’2:ì•r·f~BÂdê- Ád@!pˆ€wp;YPú æ  ·u©®GÀzFÜËFí3˜+Ÿá‘à2¼{õX 7 œò”Á3ïÏæi5 Ûr ·16Õ£÷d(°÷¿Çȉhšº±åsŠ<ÝÿŽøÄwTWuo-È×i5Xm,;ë†OÌUïÂ3¸Ómø!¼ÇÜOyÒn’¯¯°²ât*g õi¬7zÀf²w;Q‰çe¾iê#D×xÍ-;[¾«î:•JÞì-Ø'xÖö¥ªLs3íš)kõ `ò=¤>ty)·%ì徊ȳ ¨À4¤Ÿ…YYœFƒ}£Πàj^Þ:èO¼½Ô´êœÐ|œÓ7#Ú@ØœâÀ½àŦÇ3‘$2‰ä>Ã;Q\y?7;^åÿsoùÁ¦¨5RšÕœòFõß_xÃuÏH-¬ ú®tÖ@{ØêVû|þRþ³Ûù^}ÜamÏì›ÝÍm;j±Ã±ãýÑ‹áe[3Ò÷¾%åw™¯LÿáWµ‰ñjñbºB<¡0t¿ÅL­gËZèÒs3ß8ß%æfwó^¶u©ß¼Òa40rOœŒÍšP2‘ãLå“oÉ'˜Ã|’³2£Gc@ R°ƒeõC‰]l’¹@§£¯k§E%Ôâã¡ ˆrA˜ÙòŽ«™¼º(ûѦ¨–¾nN&|ÍŽ¦]¬¡”¡µø Û‚BšMðIsçjP›t¶U^._¿úû¥4 endstream endobj 230 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 232 0 obj <> stream xÚ½XmoÛ6þ¾_¡"±"Rï)R ë`/E·Õë—y™¶…ÈR&ÊKÓ_¿;iSµR;Å:ˆ%òD>w÷ÜñŽÞßóBøc^ƽ,-‚¼ðÊ÷ýÌ»¸á ƒ",¼ÙÒc¹Ç¢ H¼ÙâOÿõZÜ÷²›L£(ò‹ËÉ4ŽcÿU5+Šý~-iîµù©· äwó¿T·èiò¡ê×ôôë„g¾ìj³à«zÕv0¹¹¼4 LþšýäÅœ€)ÔHÒL]ܰñ…C°S#3A®_u«íF6“ˆù½2ßÄŽ~9ê6eYFZ~2»tâšiböî;ѨûVI#çš+„µ¢€‘¹~€}S5RžaîWKü-ü•4C…ßv4µ©Ê®]'&<õõdæ‹N’ÔídÊs_’á½$³ÈE‹RÿÇådž¥?À|uŽÀNóh@¢ç°‹÷ sîw-âzPó‰þxÅqPd®®„œ9À ï¬àÝQ¬,?°C¬ì ¬‘ƒ5â#ÖƒÁ¹_¶õvÓ hÄ@Œ]H‡„˜²" x¡9ÁO¥DóaÕU‹sÚ§yÄ—cä˜éXÉ¹ß û·ü¶K}`yä·Kú-e]+’]C`|lT³u‘”3_4 ’ü‡©¯J;Éýª¡_ŠMêdÙ‹fµ­…ÙÇB/¿5ÂëªÄµÖûoQïd½œ¾íV¢©>î¼ýFÜÓC¥Œ­E]ÂVýSÆÖFÔ¶f§»jª¾ÛÓ 'Z¾5¾¤`¢$öE½5sK€0Næ‡{щ´Içâ&wQdaZšÎÃ(ÁPYn‰¼½ hñ­’ zÒnq÷}÷ö =›þ0`Àø3+±K±­{Š@–‡AT¸ú‚f‰ÑŒóXkvhǘ ;jG”Š­”¢õ äÀ@ˆ)²ƒsHäÈaÄHCέ!޼1T²¦ëJÉæL‘”É𳉦¦|_É»ïÚ¸b”6EdÏŒÐjïÒ#”Á¶1™ë˜Ì|{èé˜Zãj¢¯ÚFÑxß² Ý›OÁ›ãü?U“E¥úcŠ,$,SGtV/üV4¥Á·Ü6%ê𤠑vçåçŽÍÓÃ÷¾º:+ÏFÀ',H¬œ©ʶëd­mübÌri &{¶á€8€¸Up~ôÆNtíyàXö«ÁÝž|)5mõÉFGàWõá‹lø¿BT'B|g¢Tt¡³FT wÏõësáîD€?ËfÇù™9’$ÈœGiZ‰ã$¾ÌÄòD ®·e]-¤h†Iè¿õ÷í‰`^W=Rðqz[·Úóútº#6ZhÁhwQÄAY ë%—ý¶C­²DÊt‚PO$ç]‹1[ër€…n†·N¯f¦´±¬¨«ZÀK•¿iš`Bkñ€'TkšªvuùžÀ-u¹ KQŽ‚OÆO5ÐÙ °Ì‡EMobQÊ¿·ºzÂMÛý’áøòP'èåá×¶0Õš)ÂãU0Jš?£ª‡…¼§ÓªYP Š»5ô!XVï>Ù:5[g è£ûžæƒ–ß- @×ÂË8kŒˆ/@.[¬WèX±¦»¸)Üf-„mSÃÔ£e¥íy°Ú[ °DýœÙÖ¹lµ:m&ƒº\j43O rˆVºÒ…Œ˜©bÐAèb”CÁÈ’As «Ùˆš ·¾ˆ½EÄ÷'(ºˆ$ZSl =dn l±‰ß ¥ªU³/­áº‘ úC*˜L“”û7•eK–˜íáÁ8Õ¼àмkwœ›~¢ ݈Þ<žïtó@J\Þ¹o./–»2ÛYã\½´G$Tùç‡\„ŽdÝ~" •̈äþvb ’è4NðfÄ‘ŸO^¸‹¤ŽB;ô`Y6äZno ¾µ¡›vƒØ’±\ˆ^ŒÝNähCÛÅl„OìaçËPwc{%=ÝpðÊÈR̹ýnCdŒùôŸcyôÌË®øÔÓuÏÓ#-Ç{là 1Pðš¤e˜=tÅ·’¢µ¦ i. R“²afH]K`}æNÉZnL)I&E×m³R˜•¡X½hŠ€w1;A7¨¬8wZ`Äд¦ùŽòÉàh¿ªèî¥9ße5SíL£˜Ì6}Ù )Ècà·Åh†* èŽ*Jl†¤!†\ϼ߾ù,–i endstream endobj 233 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 235 0 obj <> stream xÚÕXKoã6¾÷Wè°Ed`Í)Š’¶ÈÛ}-zh»é)ÎA±˜X­%¥’œlþ}‡R¦l:vÒb€EŠ#Îû›!ƒ¿Dð£AÊ‚Tä$˃eüx¼ùÌ‘<ʃ‹›€fIžåeøaUÜ ²›Íã8ó·³9ç<ü£¯š[õЇÃJâÚóXoz ×©®»¢{ÄŇjXáè×KC٭͆ï×·m‹õÛ·fƒÙÕÅÏg”€L‘–DdúÝ›ÏÜ‘uÎ)#”ÃÔašnÑÔP&®VŒˆÄlUËaÕ–†ÈU= æ :EÕ¿ÜÍæJÊe[rÙÃ,OÇ|¬ ¢&Z{–‹°ÐÒË¡ZâB-‹G‹Ð'L–‘4žHs~~VœyD–l1CVí”·âUVÈMø¹eÉÄ.³ú$fU¯©æqž$w­³ée‰¾Z|.‹õr³.¹KãQœÈF¹æÄçNôÒœ&Jâ½9tEÓßµ½<æÐØÖU£\GiXÝàóV6GʶêYWË®-º®P²ªà„UÃ|[tæ“k0TJ x˜/Û¦¯JÙÉ’@lÇ"üéÆ#L9‰Ø®çç‘Ï)N¬¼&”)Û6Æ1#iâjù SKY;7Rr:J…bòÈÕ–Û|*KôH°»VíôÐ/fJq@Æ ã}MèM˜£ 7šhÞGåÖú²‚y¢¯£ Ä—ÖžSšÅì·ÞÔV ŃM`«(§:üoüÇ$Æèû]›NÉ—òð~&hX¬7²?g)ôQ_]¬*ÃðfÓ,‡ªmpÖéÝÌ’I®«~°ÂP7Ä9Sb µ^YŠÈ¡H·ë˲ Ÿw2"¶±ãá’“8=ÂÃæÙ².ú¿<º³œXŒöæ4ƒdeì@ROUv²ú¨4ŽÆ®4sMãÄÇ{0sž…ì£zªÐÚf5¼†ÓxTT æ¼C×­«®­J\RL!$È…¥*«ZB”¶Ú³0×!¨·©z/OÝHH#S‹¿¡_ýšM}mª$D§ wu¶Y0æÆ>;#ºÑ42Ä”™?Á}»SȆñs(&û~ʳì3Qƒ>jˆ` P@ÍŒ²Ð`ó5=êp]ëZôøÑM»iÊg·A/GÌø½‡˜X¿x”„u1tÕW5a?´ìqü°‚F4Y!Ùý,á¦4ªT«Æ' MÙ¶‚ï˜“Øæšî»ºêÕ‰C¯`Û6db À@¿À‰¿’]¾ª®._ýyu %sú1Îø¶Û Ú3J’Ø5îsêÚÙ<‚Á1HXÑÕ'‰ë%Qlʼž”­Ä TÛ²•0S¶„.[zê+[ ‚tìdŸ»ÛœyólTúßï µ*y {)C]ðåYjA’g$ÏĤX%,=P¬bÇ(ß¶X9ßξØL¨ÆÀß`ï3ã)‰²§,ç4ÕS¹S 2œªåëÒÓL·;Û6='à!ætø`N¡ˆÞibP%4ÚE³4³ku’ å0‹#ஆÒ4úƒšéW-¾xÂ1ÜmýksÓñý]Ñ5ŽÏíáÃÜi𹿭šR~¥†ô>/¯^»uÊ!d'šë áYqæ¡T&Ù¡“>ºí{B!éœ'êòÅ¡_Ì~ðˆõè­`ÉöŠçØ)gôà¾#’ˆ¤¶Ÿ>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 238 0 obj <> stream xÚíWËnã6Ý÷+´hqDŠzeàÒt˜v}¸«º Z¦m!z¸”'ߡlÊ–'hÚM É+êœÃËÃKç/;>üa'&N¥(I¬t¾Ÿ9ï?û(õSg¶rpâॡ3[þáÞnضåbâAà¦×RêþÞäÕZvQ·Ýp=vk~Š®øýø×|!˜xÔƒ»¼Ýè§Ÿ'$v¹(Ì„7ź0X^_› &Î~t(Á0ù I”ª¾÷Ÿ©…Õ R…Ôñ(Ð!*nîãØD†6+‚¢ÐLUòvS/§Ó«‡+iófÀ}­«5oZ |Ër±Ë®Ù-ó¦eUf$XL<’¸¼•ÜvùÈ+9B\^ðžIä¶îÉ+ýŽÑ„Ü¿UëˆL Ñ|£‡’‡CIþ¹¬ïŸb¦‘{s¯—ˆ­ õ%,h›NÝ£°S?µD‘­^”F7ÇU‘#½*±REΘ›‘ýÌ­Ǫ̂"1{ÓƒìÄ:;{ÐhjPDž«‘Ä>"ŽotÉa"Zñf°‚Á ¨»êª¬Íë~™ëAŠèF×ðåõòDn¾çã†•ÍÆV6Ä( ‡)ÕBð‚I|£ét/CÀ.DÀM]t­Qâ~†.+:Ó¬WGÒ¾ÞîB¼°š&U¹àK³C_ ÕËTüo16büm 9¦ÁDɪ«FïÁª»×^Ú» þÄ«%+ €¦Ã;b”&ñB üB Ÿº¬È—œUC'ú—]\ˆæ6Wfÿè-ŠZ­}&›w:!{l£–€ÜÏÄÖB*5ÛŸ'lû̵ۢoû±›¯ôïšW\?ÕBÿ–y&j&S,d_´?itæãçºÜvVW ,l?Z‘ûe5‚?ÀT¦ÄéÔK¯ÅýÑü>‚‰´ÅJŸ†ABPÚ,wꀖR§%Å{T¦ì8°¡¾¶[è•J˜®¹+Ôy¿kæÉ$:Ä‚ppÊŸaB,&Ô0Qß~·âK ÚK ßhP Žá šÁ9ÌWte¥(ix Lå§XeT›üI±šûWÞvBâ‹)œPV'Ts&Ïb¥‰|k¶É͇%€P³5Geóe¤uÕ‰ÁI 4àäÛ|R„1Š¡¼‹ˆ{ËŠ¬“¶«R"ÍàÁB­’µ"ËaQM[oÕòQïïï¶L°R³œö›jáÄÎÕÃÖUaÓúק‡5WÞà}x£Žóh(K+x>ùp:à3ú`ÛIÂÃãÛ>À·í Ѩ¯ŸÏJ‘"ÒMÇ&IQÐ Þrl’íKpïc¿ú›s£jOl˜}ö)k¥Zp.Õ µNç/.Æ!†?loš}:/YËžN¹±îd`YãŸ-u÷Yôz†ŸÃO÷6ÚñÛ/"í“OL>íwÜ?{<‰#yý¸ØãmgÄô21^)/6¶O)Jc›«Æzpsÿ†XálÅŠ}X|¹‹Ûç$É©zÐi¹­Fb RÒX¹OÒ·kÛÛµííÚövm{»¶ þÿ×¶O3ç—oþŦ7 endstream endobj 239 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 241 0 obj <> stream xÚµYÝoÜ6¿¿bQ¤ˆ¶°‘¢(ÉA ¤½Mq(zwn_ê>È+z­F»r%mìÜ_3œ¡Díʱ´Øñsf8œß|pW®Ä*†ŸXer•é"Ê‹Õf·úörõê{¹qTÄÅêòf%ò•H¢"]]V¿ßÝ–wƒéÖa’$Aq¾•RÁ/}½ßâ †[Csßñ§9ô°~œÿW}Ý•Ý'𼝇[jý¼–Y`º† ¾m¶m“»ós&°þýòÇ•’"™b+IÛ±Wß‹å‹ Â†¼&TpiþÇ ‡n|2|\k”ÍÁô¼Ù?h¼ EéÄ­{Ø#TpsØo†ºÝS¯³Ôx OËB_c2‰¤“óEU÷C¹ß˜]9tõÃßLGpZ}†„ó dneו¨T˜H‚ö¿iе8xßÓèdƒîPÖ{Ò³p÷ Çzž ¡(ŠH)ø&È™_¯C¼†Á·7böt?|­*Øš=·ÌÃ]gúžýªÊ¯Oƒîx•ë°[ËÜÑîh¾›¶9ì¬6¡S3%Snp›Ÿ•:5/5ʆ-®Yž7à!cÿx ÒDdo?ÐÐÙÑQ¯b¡º~Xâ¶ì©ñ?ÓµÔ2Ù²¤†>Z2LD¦‘$ã*"!¢|¦Zÿ-×I|¤›ËÜ9²4ØøÐ>hûÐ L;õì'‰´òMwgá%ƒ¯ïÊ®ÜÑaÞ˜W)T{ªù£½Þ—;†î› ú¾|yvªD4–¬Ÿ/ÿí÷…å`%Ÿ_ªêm¹Z¿^ÕŒì ·"öV¤‘r0ê̦íª%]¥¨%Z^ôåGsÅzšØúØ ¸“™ªîÁ1‹<éP ó0P ­¦Yô E%9³vú>PAKðªhS 2I9-9[â¤#õq §$u%Ú‘ìðhEÁlaáÒöNƒ?µ{óô¥+Z³¡hïÌp N‚BEí¾Õª8ž £VÍ8ÈP‡¡Ç¡.ò|RÌ_†õ× @"=Ñ=ÂX&3«Ü”¼çæÔpt¸¶gf—Ö5a\ÕÒ¢’㸹__d^mÌY–çqýŒ>¯Žiüa6Ãb„ ¥H­©`œ¤Ôím·=`XM„UÞ£<Ú9¦¥6ò) ±È–ãØ» ùX€±)ŒÌEÐ6ŸMe$ó'‰*kö´ ¯ IzSQ«ä‘Áq».{nQ8Æ–u nˆ7`þ4ÛH¦0’+fÐñüÐ2wëölì1p¤ŠôŠ8·Ù´ÐQV‹ïš]^’•é7]Íó*ÎÎô˜ˆêyž”dœ'af—&Áû=/²ŠÅVëœ^áìȢÜå„N£ØYz¸3%¥¬~ŽvFÌ-8 18ÇÔ?+žÊ~Ä?ñsŽ¯ÑŸc÷8›Ç1r>°g1¡Æ 4üŽ+Y2êØŒZcFÔHu8Î4šv¿eÙ†—Åyð~`:èEÜZ´/ÅÓìgšÍ¡)c=Hæ½ ˜<Ƥ“U¼ñʺ#Ĥ^ÐÖ:æK,ÆK,¸~(‚ÛÚ@9IåB½¡’ ŸÝÊ‚©êKÝç¸ÑÑ¡Bm¶4½³]BÄ]Ê$“ÜeáÄ‚Gœ£Ï‚êËÀ÷ù躄=cF&ìe„=Ŷ…“3ÄÁW&vŽ’»Õ%"Óéjǃ.ª@[¯j¬­{{Óšn9àMŸ‹Ð…i-¾ ¹J‰9rUsXUJî[ÒÇâ»S-n ãÔi׎8Í,n4á&,N•œVN8…ΈS*Ðs¬UæÅƒ¾vÅ&jRA;j»™«¶ÈغÈØ"g`Ok©ãƒû9‰!×þb0ë‚®˜ø÷Ì“¯5LRy”*.Á[>o(­Ç ò‰\Scâà£;y ݱþ<º¥ŽÒôÙ‰*Rø‰Ž}(èAàÝC¹»kÜ#ßÞìó^¬@ÅôÍè ¾f¤Xdä:q’ÖŽ*֣Ћ£·‡"óŰ t†a'±å¨7õþÃ_n Ñ÷(Dò9s”9ÏlaÇvåC½cÙ9éü(ðCŸÉezœ<{«à-ó%ww‡MSWà(NýÏô–&¥¢tN¦?V çôf(sƒE\œœ¹©² æÔ ™¾·O¤ØµyL÷p†‡n¹±o­7¨¸ë¤ë—àšë)@¡4ãAJ= õ‡ñ5iSËDÚ‚+ 8:•iØhš›5>$æücübkè¢aj6û —8 †1ú  S^G×+¹ѱâM­5Cû¨â…‘ ×v¼ô¹t­wÍøÌªœ-(à„Z²­ª.·ô˜¦Àuµ]à†J ¸¡ìyAœ[žw>;#±Ç¬RežUb™&Ó¦\(­5©Ne·¢°°…­ ^|«Ä>Z¥õÀªdB›çÝ>§q;¶§/‡FAi4:ÈtËÞMjLöG‚ì—ì°S= yÔ iwP62¨,V?Ñíò)Ý‹õhhz44çQ0XŽæØF¯é¡ZúU‹Q Í¢Ä=Œl>•û6–jö4oîÖ•,ÏTn‡›ö@Beôè-µ÷W‚ϳÐSrã‰5¡Œ ªÑ<ȫʹíØNOÉSüP´ëÐócÀé¿/ççTÞ¿>5Àÿ—ó‚Ÿ\é‘÷)BáÅÞÜ_O½³¨ÐÞ¹Þÿôó/—ü,ÿÕ¨ñ¯¤`îáÚÆUðÝyDýHÞÑ útp†a|EODÕ›‹—ýKGóÝåêßÿø?krÖ endstream endobj 242 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 244 0 obj <> stream xÚµT[oÓ0~çWXS¥9¨ñlǹµÒ˜q=Ty‰×†¦I±Ó]þ=¹8]ÊÜŽPêøØßùÎñù>ð €ë>¾¢ ɼŽÀÙ[ F!AtHˆƒBDéwx±ä›JHËv†ËfŒÁ+•‹f‹Áj)ºØ…þË·ª>¿‹Ê®%—]ð.«–ÝêÒ¢>2×€çù¢”up=™hëGô0JPÍ ·L|Òî½u\m}Äfu9´=·ÖÉFâ~SI¡éMõ¦I)S{ÖD’.U ÓLUÓÙéöt¬‹’¼P›R‰éŒÄÖ«6/vÝÒue£ø­ˆáÏòºàëúôIòÀ‹r.…ÚæÕɸ˹EŸJMg£æ³É>~ [3Ôü{ûÔÜóaí½h™©¾ÃyÞ­)x¥‹×Ä`Œ Ë…24’9Žnõ° ”¤•!HÇôñ±ÏCžoB[Tòš³Ck9ó"5ÀR —ÄíY¢6n3BQà»÷-[g9—ùƒÐ.;…wí|vë„]÷ovo-@ÝX®s†{ôötÒ•”‹0Õa{-êIÓ¶§ª2ßVYYLLcO¿AT±UšÓS-M&_Ûq5 òN,Ý@´ÂŽÙ³BÜÅÐ(r#ŠæýçË«H¿f' TÝW'ÇäTÏl×íM#zÏ7†£¡¬Æ½ä¥,¥ñ(»)·E[fXíÔ_>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 247 0 obj <> stream xÚµXÝoã¸ï_!ôI"Z”(J Š{¹[ ÅÞ6‡¤(ЦŒLÇêÊ’OëÍ=ôoï ‡ú²•ìf‘…L©ùæÌt~w¸ãÃ;qàÄ2eIêd{ç§;gý>p¸ÏR?uî¶O²4rî6ÿv¯vêÐêzå…aèrÿrå !Ü«jÈ‹¼|DºpU¹¡ @ú„ÔÿÜýÍgÀÐ7lâÀÐÖï¥Ãcðyv‹'@—ÀìãþÊ‹d0GV ¦æZûŽ ¤†Íu¹ò‚@ºíNÓ /›¶î²6¯Ê†(𗸺¨VAì/,ÇhêÐNÄÖ€¿Ø ÜŸìˆXÚõϺn€ùánøë‚â ãýr­·Àƪ^˜ðµR ¡DB·_h .2Ÿºwý7Wö¯è¢q'Î?䵪ŸŒ2#&ø§˜gàü"רH*ÝcÞîp[U`ðîãíµwE㦅à¨zcgy™ÙMs}ÄZ ‚'ïÚSmŸß+/ ä¾¥ZcPªyoxƒ»{õiÆ;bßíä(t!ؾÏdbã º¶Êªr»-aªÒ¶õðe4á:è%. ‹û ›@÷ê‚hFVƒ¶˜¹ª(TK¾Ê¡6_¸™n¢hÕäü@¸w«l$.öc t&Æbê.#$ŒS8VÖo8ÙV5 ŒÇp@)€£›§vW•™”ëÈgÁ¥)¤vï«F·Ýž–œ‘²TöÛ²:?´È51Êkµ±ÂTC²6÷ØÓ»!Úü,ƒ¢„£Bð™÷g9Þ{Æ”-òƒ©_½`B~€òFvÅúF7&³ê• ƒqDz'ŽùlMüRb›šÝ|Xp†”LŠ™3˜Ý:\°PHS9ƒ8f1T. H]…Aø¼Š¤«òB=š–•]>¨º% ~¤Ž@ø)¯èW’¤ØÝäP·ó‡Ž²ß°7­`ÂPÑ_£³j-«ƒÊÓ'£Æ£Æ£‘¤XvÎJ†Ñ"<)AH€âÏMx“™¥0…h7´Ç&NìÞß—úøgZþØíÁÙ*hé¦7–îOÅ`¥ã<\¥|‹]8캾_ápøvy†íÎuBzÕQ6»ª+lžd·è›DW!Ÿ& &so¥¤YŠe">mÄôE@j œE,§~Á)FÄüÓßœ™ˆÄ‘#ÆEÜw7†éX•Ú,™ ­þ<ß¼Åf,_ÙŠY«jöøÇB–{a"Ÿ•‹m]í—ôƒ:nùíÚöp¹^?ÀP9Ë÷ ë¼¶úôT1•±ÿÖÿÛoô®ªÊuSmÛ£ªõº÷ݹa Ç6¹ËÀ\ÿ(zQŠÇ&§töÂ(B='êÞû\úrAãYþj:VØžñÐ =b“×:k«úi©å…xðÆùº`Ç2æw¨ýÓNüGè„ÌÄòÃPŸÂ±KϪÈr˜Ÿ À‚RFÑÄIЄA7Å€JûÕcn*|‘œ¯‰l\ŒÔ¡ #ÕD©céjÞÑô,$˜ḺIãU^#=鋨Y muÓ’¹¶šÖ÷)˜•ÛL•D­»¥ÐqhäI„Ÿw±‘¾” ôùDÏë-ö°À:) O€!RŽXKMøÓtÄm‡% ø¨=r1Úã7µÞWÔ°Aˆx)ÕÃÀÿa¥ùk©njŠ€â›ÆS½7ˆó!’CÛÅqÿÿϼÜFlˆpo¢g†6‹#j_®?ÿý–æ£{JÂoC¥íYè#9ȳi7~ÿX«ÃŽ`R!?ëóìËÍ%·U™M~µ{Ê~{d®þð JôѲ«œ³«æíNÅÿþ4õ`¯¸¢há!/‡“e3È´oàÛŸNµ2·Í €›¨-_l‡Ñx­ùýš^³PнòOƒ„[ÁüÎ/û›L|‹4ãiJ¸m(DG¸éÜ|³Nù›ã;¸˜#¨š¼Õ}ç#05¶fw)ûY æ~;ìøS «ê¥'.}G¼_-^°óÎ. Á›^V¡× ¯]ì]ÌK“t,ã81bÓÔG±8ŸŠÅù ÷±Hܾ8‚¯¡È+E_ÞU guïYYžÍ'Ú4‰Ô=ù<3áR:„ý¹%X”¼É‰úåÎùò,M¸st„Œ/ó€ÒÙi…sëü¶ø2ˆ ‚¥ôÊVYGGGW7Øeß}dÔ#?ê/í­tåp%#XeÀ®V¥^jŠè+@ëy0—¡£#,û.ü ‚yr,à×oU&2—‹·Á±©dAüƒqì·Úå'¯vòr£^‹iÓS4Àšd¬|ùµe–XãEÛ8Œ@ªqe­éa!4mÔ²5yJÞAQªræ›ØâdŠ­}O¶_1l¦Ýð’xN}=X§§ªþNÀz@Nݸ|Šuõuí·éú¾ ÌLÄÅüØmª½¶#óÖФݩ֎ f'šÝ9$éååÕð&ô}eÞ7‰’”‘{;p×_ÔþPØÉ =̤K/øÌáœùð䎈_-éÿ™7QŸ³¾cc’®­Í‚“â” —î¦#y§¡’iB7+Ѫ0»pKb‚’0™Ý D˜7[ê|&ù™ÉÌÓ»ÂìéôÅr,úžrÂßþÞ}ð·?ý²&z endstream endobj 248 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 251 0 obj <> endobj 252 0 obj <> endobj 253 0 obj <> stream xœV{TWŸ™Œ_L š™S­JE|ÕU‹§E¥ 1>PÔÊ’‡†$æ€!|Œ, ‰¯JQDm§.Öún­Çj•GµZݳºVYÖŶ»wÜ«çìM¢$íñì{Îü1÷ÞïÞïû~ßïûÝ+ÂB‚0‘H4x®Þbd£‚Y¯\’¶Ô35Uˆ #‚„‘Á¡BžNÄR›†äRl›TÄIƒ9iÈ?0TøÏ`áîßaU¢½¢#¢ŽK_¼£Õò9Ž^Â0´y-Cg³Z†ž»P¹"E‘LKV¤ÓÉŒŽ1ª´´Ò’¥eÕt*«ft&&†ÎÖi­o@«õ: kfõ:S=ÛD«h“Q³hS f ž…XÚÀóX“ ýÓ¬‰Î1ªtfFC›õ4«Sk-{4Ÿ­×™iƒQÖóÐ :J©7™Mj#k0ÓÈ£21É£y­ÊìñkbÑ2­ÏF–½Úâɦͬbu&Ú̘=~²ZÚ ZU!ò‹Ž2Yo«Ëñ{¥LŽÊ¨Ñ2&ï¹TüùÑY« m¡w¯ÞkÕïŸ5›mvœ‚Í˲˜è4½NO§Ò‹™‹Veüͤ¿Jÿ_Ý0 ^¨Sgè5s¼9¦µfÖ²^«*È›÷lj¶[ˆ%b31%ö6[„%aK°yØR,KÇæc˰ , ›ƒ­ÀX86KÀ†`QˆJX–/ Y‚$AÉAŸ¿|6$"Ä&$>‹¿ƒ7á=’…’6Éß Óñ€zB„F…Îz ½PÁg… åÃÉÐAîN„oˆ!‰Zm%Å[Šñ&‡½¡Þj/¤æãÀ!4‰ü30Èoy‡Óà]8ÜŸ °ø-váÈ#ǃ{¼¿ò$‹ûùHòˆ¦Éüfä•Ãð^&^à»(é?.ìÀñÎÚµÙº·ùcç±èO8Wžõûóë\9Vâ]äßÈ;~#ùâ9©Lãr - P,xAijîð»<øŠä†+HeYGÒ] Ž€Qãcá0øÚ£‰ òêUwÛiªÙµ³‰«#œVG™mó–òrùòUi¦9ÈRôN÷¯ èûnt÷ºjY5UU´ÃVÏõvGõ@BÎpÙ%Å6kÜ›¾`áEà&àe ”ˆwzCl°î@Pû1hÇá¸N«ÅÇ_ ÷N$脜¸( \X-ÀÁ fÂ\qZ€Å0¿EþQ/„òÁà¬0WÉ1cá`8´o Aø“Ç` Ç>†¯QY!¿þÿú¸éo5ãö“¾;·¡¼û×\¢¸#É^Á(TËÞo_¸/…›Ç)×e®Z³Zÿ§ fH`4@ÎÀˆo.í?ñ…ü£}uœ“¨-¯ÙhÛ´¥Ü&O_±. :ög ¥®K@ØßzAðý[ËÕòmìåuÑà)$‘#š|•,”ûZLäÁM™÷€AˆÍ ä!Ø8yÿܳ¦tœ|è¯@º¿äƒPŸH¹wƒ#ÀàžŸvZe•›·V–Ë5æÄ¢%‘´¦õ4ÜÀàïÿ—4üù—pPwQãm«N§;ÞƒoŒŸûóCódßá–L9ê"þR¢î!N# ðYO"I° ¢;  XAŠ®ª€p²}áREÞ¼è õ§§(p>V f ø¬³ËoÉÉīܥæóç¼ãF Ò"îR±+@´dýž;§€q> ÖÌè‚~¥¡ ¿ûL*>ßu`Øwq¸P©!°;QᔀÔ> endobj 255 0 obj <> endobj 256 0 obj <> stream xœUV XWîa˜î”ɈŠÎ xQAäAÀp ‚¢ Ana䯀Š>Œ‰‹Æ a@äD@ ê"È¥F $JÍrèxd×D“êɾÝ7l²ß×ß÷ª«û½ªú«ê¯Ç£tu(Ç®I‰Hôݨ•-97[‡›Ã?€e¿/Wg æP>gŸNAú|¤¯{n¶~‘4Mƒ†à2•âóxkB"×&%g§ÄÇÆ¥™.Üd¾d‰å_šwLwdÿùÅÔ=:5>VfºщIÉÒhYš_¼tGzªiP„,ÕÔÇ40:6=1"åÿ”E™û¬É–EnöuKŠZ›íï›—”žœ™‘%ݱÉf™©¥Õ*kŠZJÍ£¶Pþ”;å@YQfTåAͧ6Pë(jåI½KQ^ÔFÊ› ¦ÖSvTµ‰ZAm¦|)7*”ò£ÖRöÔ4êŠGM¡ )j*eAp¢t)1Ùt†zÌ[Ä‹àÒY¤“¨ÓÌ_ÀßÏï×uÐÍÔ½¤û›`… ™¶ wÒ¥ômÆ›9Ä\`ž³³Y[ö&ûû¤ÐI_NÑsЫ׻¦×«÷l2ò¨2àZRÍÈyU|X£–Š¬Æ¤\¨khµ5’ÃVg#çq2Hõâ$Á¨¥¬OãÓcRÁ¿è>HÀ?"œCƒ> ¸°L©~‡ì™Á‹ð%žÅY liðМK°ß“•‡fîE¹Ç²³®ÌÙýg— rTYPr¦¬¨°äL=äª fhÝ’sâäF=}Îðq¿±ðër ð+MñÔ3¿µ÷<é¬ôãÿôs¦ÌÐúö…N¡R·p±ðëa†¸‘ÖÇYöñª†ø\¼¾±ï«ÌÊØFŸJ7Äâ¹ÖX»a§QS˜ÓõÂ;'%+éÜ•ïG¸#Özc/LãVÅÓž«;ÜNJÆP{ˆL8=`>pö‡:Ðp>¥Ñ‘Ãà&lÅ7ÀNììæN ó¹¸éÁ@Ãj)18nÌ'ª X4&怆H ´æ”p\ 9J£G*x¤òS ¹GÓAIw£Euõ¬ðmÍ%yóÍYh8²Åª†rUÕ­g¡–̆è‹ÑÕ¡g¢g߬"þOö[e#¾Z¶á1‚á­ÇÃã¨ôWØõñ¸“°G„x=§.þ‰c³9ñjáRR¦®Øõé\Xúý]@“2M[ë…BжҤ«™^8ÚÌëxuûÞb•÷<—AGŽ!ðMÀsIŪøÜLu¶GãyØ gá, +Ä ?*oº-yt¿&³°K`)Þ)vÐÛŸ±>öÁîóÈb…­ÍHw{ײXi‘GJî®’7¢âf«ø#Óá" > 1dBÖ1ö•à‹´jÌDÄÝWæÿ`ý°‹9ž/1€*ÒÛ$h“¼á~>œ"mm§¤«å_\:ñ1:Z$îf²ŽïËßXçðí®[ÏMX?6ÄLPR½ ”¼§*yÅ'VïŠ ›¾‰®­«¾z¹¨ÝgaΪ><_Œ[Ǥ*š3Ñ…aFZ¶::†lµ%æŸóYòCr£n’Ncaw·–Wîhyå<ƒz‹/W–ÿôV>;ÈkåÌßgŒv$lub…Ý/˜ñ‚èiã-Q9}|ΆœàÂDÜÝ\éEÒ6ó]Ìbçåç<®„Jê¶·ïjCèŸ l2ƒÜ÷¿Ÿ!KO|?{3ŠFñ'Ó¾È*<ðù¡*v]°¸/ ‘Ý?±þòõÂN†,·žÁY¾¢ÑlŒ§»,³Ù8ÞRíŠÉÿ8®aöš[ψŽþây O!>¬ö±p¨‚©R‰"ëVî¹ =sË–nÛ¢O—dˆ÷~Xx¨–]FÇSº6ÀRÀ3:^+¶_1;/q,ò<#+Aµ3¯_©êº_#ÛxLü'k»·§Ÿ°1¿‡4Ÿ0±–‡ËË÷çÈÅ¥»O¦ v‚‡}Ú¬Ù–öÞ1\`HÊÓp]¼A’ï¬å0ßÏw÷üNcJ‡ÔH;äòcŸTˆ{˜}í9úbcóNÖJ?!Sˆá×o:ìÉè ²Ù^SÜO ÕRÝ•ó´sŠÔùk¯GÅñH«¸ÏDGÁ̼¯&8Ø-vÀ3l‚^¦HÀ{ë³Ôú8EeD&¦Ë2Ã÷ Õ(¸(®>ù˽Õù× ù^§·WF6yÄ ¡ïä 5uUè ê\\Žßkœ±¬4¡µ³;¶#Ä2_  o‹Ü¨£Ž÷»ö U\Æták®Ø71¦AvÞ—ï‰9Æ^³˜±ëúY,Tõ¡ÆòÆnÖM;ªÆë‘—¦C8W,XJãÅ'lÊ9|4Å‚q¦S‹å¼A§GBl$àk sw<)xûéóqâØŠÝµ¨å ¬ˆ/þÕÖ€ è<‡…b®€Ñöë¸ îÆt°7a¦±œOÆòz‘ÆÒ”Ö4XKÏéלõ¯kÁ8ðÚÑÕ5ÀKbo嘔`=¨M¯~N ÿ²Q´ÿÈat±² Ë$p‡Qy6a‘‹OzTœ859Ozd;@ŸøöR¥±½õI¡’tÅeäxÀz9Ù‡öø¥$†!OÖ²Óÿ×Ζs­·ÅŸ†”¥¶¢³èô±ò„ÁS„’ìNI‹OÜñÁÄ®®ji«­9-þì‹ã§Ù¿Ð»¥"p‡Oµøá@lKÖâ“ØË/h˜ á`ŒÃ¯&óß®ÉÚÇXxeü†Q­e%#ìý¡íN×Ýêh/1Ó*´¯wj¢¼µ¯Üæyp³¹GDFÀqb{D©'ò@á»¶ù°Â+™¿»Ö~hâ·Ž·Kï}æ²_‹ìi7ñ(¡K7p^þ‹×nNˆ’@% q±H51+|WÙü}Püî>‘uÎtð%703ÏÒŒàU܈`WqÍhð'ײŸiXɽ„Õš—‚‰Œ)¼+£P;ʇ u¨ÈùËb¶„û¦Y"lÌâ±,ÁBIˆ%ÄéϾÇ4T*sÒ}Ѱ„`¾ÔÜ*ì'†/þæûŒ8ÉèºQcá ì…è]›/v¿jÚ¾Âvcˆõ’°ë¿|(!x2ælBgOÜ+÷ÂçC0k4®iE¥D8ØYöUÓw³À`Õl‚Í\œð’ÄÃtþ•㥧JäuWKÛ«hw Í–F} IÍK<ì{”%T¢ oxCoDfßd3hݞ̰#l4ÓS}í‰ô™?¿ò!ˆüaö†W@÷èåÎ %W¬ûÇ·L¹:””O6ÉÎ˴ѧΤãŠåà+÷9G+ô'+>Ñ×,ПBQÿ] Rà endstream endobj 257 0 obj <> endobj 258 0 obj <> endobj 259 0 obj <> endobj 260 0 obj <>>> stream xœíX]o[7}¿¿â¾5jŠß}Ûv ,²ØnâÅö-P¯G…$»¶³Iþýž!9$%Ùnø±0‚hŽÈ3œ3Ã!©ßf)´NA«YÒßh,ûiõ&Ì×÷“6j›æO“6EiÃ|þáÍß'Ÿ`);+o¦ÌûQAx3ûàDr¶4B…Ù»(”tÍ^&£Œ0>4d7éä„“¶!:*!­iœÝ.^—©!Aj5q4DKöÆ0ëk^«½LmeÙMmíi±UÎn¯Ë™»éÃô¶£ÖZݨ’Õ¡Kd•ø¿-¤ÚƒD©é´h‰¯ÅÝ Ãp•Fyœ‘ø03ŸÃ§º:ÕÔ©È NEZL•²ÛÅér¦Ã‰:ÚY¡Í¨Ž6^˜ØÒZ‰¤º@ÕªÈPCiWÎn¯ƒH3\E2&aA½†Œ3"Æ®Rµ•*2¨T‘[åìvñºœéq¢’ôFx5ª$­Áw•¤QBÇ®Rµ•*2¨T‘qåìvñ:¨¤ådG•”"¤®6о«TíA¥Š *U¤ÅV9»]¼.gz•ð}VUÁ)$j¦A»‚ФÆÃÄÊ´kö2EÅcGvST •ª%–n36“üa>›Ö¢Qåù ‰PÁÍ6æ³Ãb.S[Sv¯¹Ø- J×íâp9V Š¢“RÏ9¶!.ŒÀ™×‰¢ñB†Ù¦$”óTzhx¾ÙˆÌa.Ä"C&œK ‰Ä%Sãlvõ FRQª¬nA¼ò£]2§Ç…C‰½²ðêÊ@uíŒplÌÙb­^—3=Ž7XW©!5".RŽ˜Ë¸«Ä¥ÞUâÍÀoælvS©!M%F8"æäˆÙkW‰WÖUâµ3±1g‹µ©tªG­%#Õ¡D9ú¼Å ’!B} …¸!ƒÌ*‡|¥ØlR_)jkŒP‰#¦Q*DjÙ³Ú씊œ‘D ™ƒ‘È?sb?i¡i¿¯lƒ£®ŒpÔµ·9k¥d³ø\Nµ8.£€c&Ù±Ol}‰ÞũҢúiÆv/#Fz1Â%ÁœÍ®^{ᦆ†ê‡2ŠÇ1šsFÌq±÷i¶{1ÒˈŽ9›]½.gzpŸF;Å6î*5¤F6O#FNòùØUŠ& ]¥¨)ç}LDÎmêœÍn*1ÒUjHˆ99böÚUâ•u•xíŒplÌÙì¦Ò©'gþŸ·ëgnר üÝ]O!†|š(j®‘:xTN ‘©\éHrG^O §“vÓû)x—{‰µèTœ!iaË1ë„¡ž°x:©”õ¾\¥N&Ï3o'Z®DÙ侂þ⊛XH¦@3êÁãðÀKLÍÿÀ¿_ÿм·À袔/Žnãû|ÉÕ˜¯)‹¡ë#@£yæ°Nfå(àW’ßb¤œI× zâxMª!†ˆ‘Þ”Û’‡ñï'ÝÈ‚oYt±X„§QX„ÎÙÆ±ëë $dädÖQÄ/ÄX"®YS>Ö8kÚzö|–ãgF9Ö¸'Aÿ!#ôvz̈6AX3f¤Îz4Ç_Éx”cƒ>ãÆ¤Ï=žâ§6hÂö(uàÆtÐs*ŒÙ¨sÍïWñ•óL{zÝeMòëLiI[—z½¡ëéìMœH¹­w|ó(ì!S¯,;OÒÛÊÉÒ™Ogñ¾céº ½åU9ë‚Íœ:ï„„Ž/3=AE\"HSqŒk%®|ž/¹y%¨³ä10ÿ6p2ç(— ;Š‚žstÃ3ŠÊŒÆh:‘“Ó¹rÆJê¸ ‡µË£,õŸ„æodvcpÈ£>¶‚ÏýàtÖQ /Ä8ưcéŽÑRÕ±\*P¶¡ô‚iŒµôóEFå·cƒ ¯ÓGHu¼™^†ñ±PœÏ¾IµÇ@œÃ9¬Òà6Òip‚úÒ¹©³ äk)ü+ýPZ>àÔÿm²x¸¥30~^öó—Óê žÁó%5 Q’x Q’MDßGs½ÜO¯>mW7ŸîW×·bùöòWÌR²NCehHvùzzõãîãýÃænFK™ßßÜÍÿ-Ó¾ý¦{‘wUƒçÌ5ízy5½Ú¯—Õ~½=ˆý1ùã?×Ëü¯·óÏ#å…ÄCKz9VêÉõýèzÿsØ~^½Þ>~ùqª¢SÑøû»eµÜì÷ëÃh¿ù}Öï0C­óæÝö°™ÿ·¹»ßÞŽ…1ÚFè}áè×MœÁÄíæn·ª„âvÿt(Ù]ßÜm>ì¿ÿ¾ï®ɼùü°9Óysõq·9QPÅàÐs/4ºXTEÁÛ/n«wﶇíûwâöËÓ©ÿéËRÜ®~ØÞˆó%dªg~‰s ÎZádÂã‰V@‚_­ÖâyîæÓâÿ_Ïz}½ÙoCÞow›ùv á×ßÍH¾jYÙ°Ü÷ëåTcƒf¾À©#œ=OÉçûg$!ÙWóO’KÝèF¢W5‹L§5Ìr>IŽçC2ôKÎ}j¬ee-rV]Fü™¢žkÈPo~½ýån}÷ƒÿv9ýÿ€FVZ endstream endobj 261 0 obj <> stream xÚ…VYä4~çWXËK¢¸9Vièe$ˆ]MK<™$Ý&‰³9¶i!øí”]N:}°­<ØU)—ëøüÙä ˆ_@"F¢0¡qB²š|·!«'FŸ&~B6[Ä$à4‘d“ÿæ¬÷i;ëqÎÀçzBg­ê¶¬Êf§õÂI› @õªµl~$‚úÆMÄÎ~H #ìÎÌŸ¶à2ô£Ë"G ÈÄûµÙP~ÖŠç! üûÁ(º %ÕàøkÙäÊe¡sè@“\¸ÌÒ]œû3Rš¹,v^]:éÎnûsÚÀ¼Ã5/ÚêˆI‚&®SÓ9Ù8L…X=ÉEuý¥aÛÖX¸²é‡´ªPØCûnµzQMŸ–´¬{:zƒz=*šfôÏvõo{¥šU¯¶Ã!íŠUV=tiõXíTWûÚ3;¿!Ÿä@D$¨Hˆ *Rϲ4rEžÉGÄ‚<Ç‚IʱWk܆¶mn3cÿ—Ù¶S:µ„c™y"œ÷¿<ã$Su¡Ãv ®2élöeê´ïǺ°Â°OœÍ-Õž!sÔŽ=Bt4L/yÂIc´PŽ’>ÎL€:‰³°/ðFmšœ@¹mš,¤>ÚCöÜõdÈ`eVô6ŽHÚ¬a²¶–nþÿSùÒ¥Ý[,m¶ZÛ-ƒh±'MgéíÛÅ÷¬‰$4àÆnãÆÜQR ÁÛÀxâtJCÔ”Ôesö;6qëa7ȧ¸A°qÃì¨Ë®ÆwSº‚‡ëÈtÀø½> ¿“^ u‡Ð³ëÒúýõeÝVö rÉ/Nb¦ªªÈ4xà$cn0銪øìJM\ú˜Ûß=ÄŸY‹ßý@T¦62²ôÚÌÐ^ZðV[¿jW€Ô¡t€ó‡¬VoäË@Ò;íF@ò_\O±Âj"5ô{”LרÔ-áäE‹ÖM^4Ù•ýÐÙ0šSk·ÊÒø¼jΔ§Œ ¡µäØD~1£€FOŒ3]3@”@/±¤¡ÔÍê©öÉ{5Ñ̲½œ™¾‰n1—!x2öYàKìNÑ.~ߌ–Ÿ¢eÎznÇᯠý벊ÍmßXº¥ûoïÑàÚ °í©îš Mãrà¸Z¥¹/Wð <6_›÷¨~(l«¦n/×môÅãP1¯ô£‹~£4 hF_àËËJa7³~ƒ“¿¯áüåž™þs¿¬°6ÍõYá +a´8¢ ¤8h8„–ŒxW ¢; p>c tgÏ{8qç´atŽ¿0¾ÄÐ}šçhj—Æ5É™šð…!cÊø²„DÄNGWDp*ñuй"Zk¯^(\ wÖ“)œ~ÑDô1&- 2é›ÒéÅk\6%|‹ºÌÖ¥>N$—ݨ`Ÿ8_càY“\ì–¿“„²èœ¿MðöyyöÎ4·´•¯±›¯­Ð8Ûeš{ Ç9Þ ‘fölZŒf÷ðø¨³ñé†(¬q˜·Ð¾d¸N1Ý6_ÚW)X¨-þÇþÜ,Á¤åù"ÖÆXNÐNå4ÂVº`zZ6ÓþŽ7é”ÃuʂӈÛö#^OyÙÁýªÕóðñ«ÿ@–<½ endstream endobj 262 0 obj <>/XObject<>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 264 0 obj <> stream xڵ˒۸ñž¯Ð‘ªA$‚¤÷äÄ'ö:©‘k½åÀ¡( =©ðáñì!ßž~ñ5¢ì­­Jé@ ÑºýÖâ? oáÂÏ[„þ"´±ŠâEzZü¸Y¬ßø ÏU±/6û…-<­â`±Ùý˹}HÎMV-WZkÇs_-WÆç¶<óc^nœ¤Ø1€úïÍ߯÷èÒ1¡!Øú^xFicñ¢• ¬ ÐâPa–«ÀúÎÛ¢n’£ÜÎí±­™˜håò`_ 䗼ؕKí:OµÜ4fÉ]¬¼Xy|Çæ!ƒ+b×É’:Ïê†'OK?t’¥9Ï hJþæLOz*‚Øc*JTà€©€ƒ€ Þ\Okk¹»a"¼[¢¸».A>r­<~Œ­#¼#ÞŒòHù¡iίÖëû²¨“\å§Zµ«¦||.U’ªÏçõO»ì¡,‹u]î›§¤ÊÖ©ðs)2í[e9x»TË•Ä! /ôB'ûš¥m“ܳš@\ec¦ÝÒr“JËÓÌm6RAwYš 7rî—+x”“£ävcpÙ<ðBRË—??}|Ëh¤”‘œú5Ð/9ÿ\•‡*9Ÿqè9›e¤’7ÀsT Ѽb2G/Ò냑>/¢éËp" çrÇ ÌtìÔùé||f”]Ù‚$Wé1O—¾uj²˜‘­oC4N÷÷HU peáñÞgÔ·²å«Yñ Ôü†!¨¬ˆ†ÊJlãkÆó|k£ÅÁ-ì+ ƒF¤Þ¸ÖK¡ÀÿéÜðe„ O'xü*²C$>c 7žœ=ó¤È2Ù‹Ä#äÁõìÒŠˆ6£}gߢYã蜠6áˆxÇ/#鱞ÓÂÖÉÔAÝÌ<Œ¾“%~ûj»ýÏ®ñM~Ìêíö®I p;vœ‹üKVÕyó¼ÝÞŽLq%g¨!o·ß~î(P±'÷ÿx†v‘$EÉ»³DèzƒµáÊ.ߺžÎª¬@Œ†1@iQž¡â〖s D‘0ÀÔ†=Ãqø_(p¤‡À𒣕îܳ½Z=dÇóœê$Í!$Œn¿äMùñ«/yö„Pß)÷‚…o޲4ŽW&»ÏMþS15>jžP…tZ%MôC=XI !¨E>D¥”âdÆ{z›ñ»†P¶Ñ[!¨Ù¦Ù ¾‡uÈ<$Å!›Ø—²Õn¤t(’yÂÐ2 \ßÉo—WYÚ”Õ3º<¹å"¯a•ž„ÉŽÀ\ìàˆóÿñ–i\ìàüz±3aeýú|†'¡§^‹4Ur>¯oˢɊ¦^ƒq~¸[ß^ÕAÈ{‡¤PÚ PÅa¾mã1÷0™æÛ6Žˆ‘ÐÅ£K<8{çCgëÖˆ\Åc0džc,%¡‘:CÍKþRïWû0 Ú«ó9K÷Gð»î|®.ú–iͪ}’ÊDö ˆ †Êƒ3™.Bár¡;ì;! ‘ï„ï'ÅßMF‡¬~Æ‘øöÛº}.½óݬ‡š ˜ý$XkT~ôýÂyN‡Fl5übб“s%¸XeÍ‹àbÿPpy—Ø l¿®¡Äþú»‹6~W!èÑÆsÎÜtªî3hé3øtàu7LBûFÈû²É÷<~+‹LYó=‚®ÆÙÛ¶êÚ.àûÁHÞû.«ëM.]ŒY9ÅPÉ„—dAÙQaפäÛ^D|¶Ô®™{QŠi?QV=²§e…Ã-’N ­ƤÉÅv^Q_©ú;î`ı/#Ý©²5Á7[N—5Zƒ[Û燶š Í}ßÂ/#:r¿S=tM Ý75 ­2®yÆMÒoöÒ½ÀE¯8i—Í·t¢K©z$WœHç5Ÿë*‡£ŠÝÖÕúX¦Éq}ß#Oî¤ø7!T§åI¸JÚ¯98 ‰<+ø*œˆ¾o`—¦“̨ۓ‰ÿ‹æIöàQû? F4_—‘çêIo"ùCïç>8§4öa¡ü 1€éoœr ˆ¸ŸÍ¹,ë=(¼5ãBÎã¶pßLÄÜ’ov'‡)°Hÿ^§u¢éØ.¯¶U'[úÖꩬzÕà‰2=¡WäÐJ¨‡¤º?õ…/¿ ǬŽÿ"ÐfŽU$ò/›Å?ÿô?¼< endstream endobj 265 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 267 0 obj <> stream xÚ…UMã6 ½÷Wè¨kÅ’å¯EÑCb‹öP4=µ{ÐØJ¬Æ¶\[Þt.ýíK‰JâÝLQä`’¢ÈÇ'’!NRøqR R5«jÒ äûÙ? ÂSV§59 ¯ÏX“Cû}êÔäô¼K²,£<}¿K¤”ôÉ“éÍxòvIÕØ¢˜ÎÞúñð‘‚3˜†0elûçŒpÉ2YøDItI$`ÁP”»$/ý0.Nõ1G™Ó§~](KQPKü⧱À`@»¥i¶§Y ¶֔$¼f“ßST<¦¡Q# ª_,J/»DTT£b¨nQ½×ÙÕ¡òãïPXÖi —ììX•P ¹Î,×L‹~b-ÿŠû×PÇŸ1Žoåa•–L鼎(в:Pê"P"Ep)ò饯 Ï/iv³C'×ÅàªqƎѨÎ;QPÔ @€ÿëWþ×ÖV#zl<†P›bŠPL¸+ªÍ›z{iRPG ð)EM»JPëåõMÐ󯥍 äÒ[=-áû¥Øf¹Ñ"êüŽéëÌññzó2«Ùh-yAÕ¬Q­‹‚Ö­npQgô73LðŒá µž¶ËØ[ÕzKÌå»ÎM”›P0ˆêÑÎ(ÜœŸâKÃ#yIÀÞh™ãlý«phÌuFáâ‘è—Å8&ß L•1QġÞï÷/v\”afXØš8{~µL5ì¯iÿïÐêÎÚq¿Ø£»û&>Åã f¢`2} N×1 ž‰LkVò-îI…¾<ûŽ÷ý=­èÔŒvì?°ÿ™rÙ‡ÙÚn+lm5žtt·èp»ÖšY7ÎFâ¾$Bäœeo,+ù6úñtã~ùµ°OЮ&vû—ádz_–ß½ÁOÎÊk6†;øÐáÈeÔ…‘›âô?Ɔ«XQnùcûÆŽGsZçXj’ÄÅ•üóØ%ƒ:ëÿ°†Ë×q{{¿Þ.<戴†–-³Ø² ôjq(‡¼QžÖ°@ »z»€DþU_Qñ#Ý׸GæuÑ!ª„y5ŸL¯OÚo…ª>§ˆ9! Yú³3(Üb>˜Â6÷ÞCÅ÷݉ÿu±|;ù8Ë»[W´Óð©®ýj»ÖÁ×:Ó—»ªž…œ?ȯß|Ë  endstream endobj 268 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 271 0 obj <> stream xÚ¥X[sÛ¶~?¿Boš‰Xoí“oãØŽ¹É´Çç– cŠTI*®ã?ß½"ÓIΜьK\öÛýv“¿&rÂONR5I“<ÈòÉb=9¼žüô«šÈ0ÈÃ|rýi"³‰Œ‚<ž\/ÿ#ími뻦ج¦*Óÿ^ŸM´’Ȇ$‘&Ô÷Ó¯ÉD¦’1Î1s"3 ˨g3EÒÍ´¿r8™© ?#ù¦ÆªWÓYiq5Í”¸ý. ÎXÕ’‡u×vƲp"Žî¾2Ïó›)¼ê8'oʺ±Õv+ÃÊ,Óë">Ä ¤o‘uQè=LU¯YðškÑØ¢3Ø¡(«mȋǰØ#ðøõ¶²ÄÈôEËVǹŸ#}lhGc^/‘t¼ùFßϔՎ«•Lž”R>–Çy§{:®WuEÑ<† sMikÂa5}É• k÷KÍMù 2Q<8¦ýBFC‚µ.6ãÞ4"{†ÂEBCH;Y:þæ-ØêxÍs ÐÀïÒ<ì™Ã9n.ª¿g”Q;ÿ÷ÉbK™YI”Ⱦ@s‘-„cÊ Xy‚áu i«‹).Î$ðtÖMWÜ–.4ò8ñ-ð¯“ñ6…íË-r:Ùp§³«ºM,t÷…Ìîíº‡5Ûÿmp*êùò .q§DªÕSªóWiÚ'iìÝÜÞ¶5Û“\,%ÓwDΘ§PP¿¹|û3Tü¬7Pù[<ò«éá zs…—³‘öÓ¡±‹ ÒÌÀ²î¹ÃÑáHákº“ÝrŒ(È=ß^¯\®ÅáÑÌĘÅùAhýƒé»L¾«ÿA>E;Íñ^šƒ)BÂD¦Y;¥fðüèžlÌÐ8âƒ/ЦW ‡\ ]/ç¿#÷ÈÇyBáÍIæyÂ×Á˜Ê®ÆeCÇrŒ*ò¨¿›¹kŠŠQŠ7u_HQP‘}WJ¥4˜¡@v|Kͦ´ Τ©£«ù¹2o×\†ÖÖPêýKJRLãèÛ¾¾#ˆ—é°€ wœ)à"¾ÇÑà|\ÀAÚ{Y8nvs}U`°¤»ÊNúÊnÈÓß*ä¾ÊÓô÷n|›'ÿ•«|)¿•}~»«óQO{uþþɲ°/§v¹»Ú¯>"q±x·›‰x˜Ú>Í>?ïöÏ»;ˆ†ªŽ. tBü¨5{PúbþM·'¾Çå@]7XÙCþÁ7v:Qß:™TY~n +Ði;±¸(Úóí$ ÅÁri!ØÎ>â™M‹ÐV¯¶·þ˜Qdz?e FYr/³¥uðñmÀÏ?w•çâ$ÏÛ/_j×ùÑIÏ‚Úç ¿8U¾Äña1ƒD@Ïeïö U<†M&{Wù¡8ýƒ~'Óï^°ô7pi=íÒ§“ëÉoÿú½>E• endstream endobj 272 0 obj <>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> endobj 250 0 obj 1930 endobj 3 0 obj <> endobj 8 0 obj <> endobj 13 0 obj <> endobj 19 0 obj <> endobj 24 0 obj <> endobj 276 0 obj <> endobj 275 0 obj <> endobj 27 0 obj <> endobj 30 0 obj <> endobj 33 0 obj <> endobj 39 0 obj <> endobj 42 0 obj <> endobj 278 0 obj <> endobj 277 0 obj <> endobj 45 0 obj <> endobj 48 0 obj <> endobj 51 0 obj <> endobj 54 0 obj <> endobj 57 0 obj <> endobj 280 0 obj <> endobj 279 0 obj <> endobj 60 0 obj <> endobj 63 0 obj <> endobj 66 0 obj <> endobj 70 0 obj <> endobj 73 0 obj <> endobj 282 0 obj <> endobj 281 0 obj <> endobj 274 0 obj <> endobj 76 0 obj <> endobj 79 0 obj <> endobj 82 0 obj <> endobj 86 0 obj <> endobj 89 0 obj <> endobj 285 0 obj <> endobj 284 0 obj <> endobj 92 0 obj <> endobj 95 0 obj <> endobj 98 0 obj <> endobj 101 0 obj <> endobj 104 0 obj <> endobj 287 0 obj <> endobj 286 0 obj <> endobj 107 0 obj <> endobj 110 0 obj <> endobj 113 0 obj <> endobj 116 0 obj <> endobj 119 0 obj <> endobj 289 0 obj <> endobj 288 0 obj <> endobj 122 0 obj <> endobj 125 0 obj <> endobj 128 0 obj <> endobj 131 0 obj <> endobj 134 0 obj <> endobj 291 0 obj <> endobj 290 0 obj <> endobj 283 0 obj <> endobj 137 0 obj <> endobj 140 0 obj <> endobj 143 0 obj <> endobj 146 0 obj <> endobj 149 0 obj <> endobj 294 0 obj <> endobj 293 0 obj <> endobj 152 0 obj <> endobj 155 0 obj <> endobj 158 0 obj <> endobj 161 0 obj <> endobj 164 0 obj <> endobj 296 0 obj <> endobj 295 0 obj <> endobj 167 0 obj <> endobj 170 0 obj <> endobj 173 0 obj <> endobj 176 0 obj <> endobj 179 0 obj <> endobj 298 0 obj <> endobj 297 0 obj <> endobj 182 0 obj <> endobj 185 0 obj <> endobj 188 0 obj <> endobj 191 0 obj <> endobj 194 0 obj <> endobj 300 0 obj <> endobj 299 0 obj <> endobj 292 0 obj <> endobj 197 0 obj <> endobj 201 0 obj <> endobj 204 0 obj <> endobj 207 0 obj <> endobj 210 0 obj <> endobj 303 0 obj <> endobj 302 0 obj <> endobj 213 0 obj <> endobj 216 0 obj <> endobj 219 0 obj <> endobj 222 0 obj <> endobj 225 0 obj <> endobj 305 0 obj <> endobj 304 0 obj <> endobj 228 0 obj <> endobj 231 0 obj <> endobj 234 0 obj <> endobj 237 0 obj <> endobj 240 0 obj <> endobj 307 0 obj <> endobj 306 0 obj <> endobj 243 0 obj <> endobj 246 0 obj <> endobj 249 0 obj <> endobj 309 0 obj <> endobj 263 0 obj <> endobj 266 0 obj <> endobj 269 0 obj <> endobj 310 0 obj <> endobj 308 0 obj <> endobj 301 0 obj <> endobj 273 0 obj <> endobj 2 0 obj <> endobj 1 0 obj <> endobj 311 0 obj <> stream xÚ]’1oƒ0…w~…ÇVU…! !R"†´QI¤ª1GŠTŒeÈß;_š¡øóÃïîɇ_T›J÷³ð÷vT5Ì¢ëuka/V8Á¹×^жWómçÞjhŒç»Æ¼5ÿ°ÿÚÛ§b—áóñP±h¡ã#‡«ÞöÕ¦¾N3 •îF‘¦žþVœf{ëv<Á#iï¶Ûë³x8µSê‹1?0€ž…ô²Ì• 8“[˜L£À6ú ^*e&Ò²Ì<Ðí¿o+vœ:õÝX> stream xÚ•XXT×¶>ã0sŽˆX&žÁÞ£7j 1Šb%¢XP,‚€T)R†3k¤wŠ€0Ѝ FML1Ýro¢F¯Ñk&³Ù$ïí3˜~ß{÷}ŒãÇ9›Uþ½Ö¿þ½eŒ #“Éì×¹o^ê²tŠ‹Û"Ï™ÏIOžß@rŸµ‰ìNUˆÏ0â³2qdQ‹CmF2ŒL;ˆ~3?¾o”¾'Ó¯gï fld2.:œœfMwrzÎ%,<."Ð? ÊqâŽIŽ3çÍ›3Õñ9'§yŽ Cü"wx‡:ºyGø…xGÑ_‚=ÂvúEÅ9N|1 **ü…3bbb¦{‡DN‹ðiÒTǘÀ¨Çµ~‘~Ñ~¾Ž®a¡Qޝx‡ø9öF=½÷?—°ð=Q~Žna¾~¡4Z;;Æž™ÐgªýBÅ2ÙÊ>«ek•Þ\"‚c˜Y?†cú2¶Lºf3Ä f†0CžÆ gTŒ3‚y†ÍŒaÆ2ã˜ñÌf3™™ÊLc¦3NÌLf3›ùó<3‡™ËÌc1.Ìbf ãÊ,e–1Ë™Ì*Æy…Y͸3kf³žÙÀld<™MÌfÆ‹Y؇‘16ŒV¶P¦•}Þç¥>ñ}rúêsO¾V^hckÓ`óbŸr2…•³Zö87•+è;´o`ß³¶Ãm“mOô[ÒOk×ßn¯Ý‡ýC쟱÷µÿtÀ¬çz ¼:hé CƒG6 ¾;äÈÐC½‡~Ïå9,vؽá.Ã辶«2U·GôaqS̶ïV€6¨()1 —+ÑB¦ :ØMÆv)YdU‘¥8špû÷¡¸}%P¢þùä»r¼†Fp•+.%£‘Û]«ƒà2µ UCèªãІØXÈb>›6“ç‰ QhµÖ,´%°O(#ì7áXd?ÄU€Ë8š<ÙðKòNrÜQÍëÃ2çÎ[’ž¡ÓA¦5÷Ò7pÄ…sëþ{n.ýãÅwe%Ø%§.æï’.+˜`µ5Vޱùc»Z|}wûø˜ƒ1·ìÅó$Çô£Gìq¹\Lí^ÇÓ<)`\UbQ’ YڌĻŸg«hV4%.®,¥T¨†Üâ¼rŠõy­Y|`–u¢&¢\,Ëü=À ’LR€¤OžD‹É˜lÀ„}xš‚ÈÒSDC| >† gÊ\̯…Vx'¡lN¡'¼¯INH ‰‰ O‰É XÄK'=r|ÐÍòÍ:®$rØ\¬¦ZyºòŽ–r=µD­a;ŒßÉO ƒÖÉJÐ/ Ãi‹ì: ;•‹F ⽕ÙÑéî )iéÎ@Ë}†²½õ_//Fù瞆{Ú:~BTD1yåÔ –„º–6Ó«t›‚s¾Ú•kînçË.jpÞàâ£!!$F•"ÕQ·Wœ+yÕ=‚>t‡v´É>Å>膣äX†7x´1^Û`aÔѰ<Çë ¥°¼pÇB›}¼CC½g<\pÞgÿz(À©ˆ¯ÉŒÆ/ß~>㮸¼KÔÄfžû ›ŽÄïo>TM#ªK9¸%¿ã؇Ümp QCHÖÖ ŸÝ»u~:­>FŸ¥ËȆtZv{ó F°"ŠJ‹¸‚Bú”ÉÅ%8“¿o™,.T6ès#„8š„6ÜïY­ÒàaJH2 Ûl|m@#Åt2KdbO>!Лæ'8§™¿¥-%5Þ«†*9N+øƒiPõð|p¬¥úÌq¨ãöA‰VÐS)™[ã7'{ÀZð*ÞR™nÌ6f§…”½jÒÉÆBrPFCAQIY[çM 5L{ÑÆê°ª,ð ®«ôhmÛîÆ!»â¶ÌþlöÃé÷oã@´Ÿ{‹ŒTï¯4MµH"1¿Ž¶Mm²È£?‘ã"ü™‡·sÞiz½¶ãô‘÷ Ú²ë#ü²âà œóoŒjÝo®ì|kÇÛ£É âìLÊ(”c ª¾ùÑqòeÒOˆ•°ãyeä-~%D¼žUh†«PÈီ3çÀü aþ l­‰v†­ÚÊE³x/¤©™#þÊt “öi¹ºb]ç­ÜE@Ñ¡4|\Y\˜÷9T‡Ë•„#£’âƒÝÝ —:6sËNCÐe¥ùù¥P€ÓÊÐæÝ+½ ‹·i®Wñ­«r±¿hÿ¶ÿÜaø”{4£“ȈÃâ“X߸ú²/QlŠu…az  'ÞºŠœ(ûÛ Ï&Ž,{ÄLJÕÑ0¯þ`¬»yrÛr|â4kwq¤ïßx^4ÇZ"ÁÓaþü—‰]Ÿ péø«'{#¨GÛ³füY‚|Hý6ñK(­'!ü ¢+šóL&håÚÂë‚vïÚ»}ÉYÏGtíôϱøÀRO„IóÉH¢¾÷2Ú ðZyë'Qnà'µoîÁ-”©/@ÝÚÜ䢣ìâ–„Nœ#ô:ýJz"÷WÖ#]6eÂî;´'œ¬=!nëžÇ§WéöEBè2Ó㈡çUz<è²#²³$ʉÓ(÷ß‚æÆKÖÁÆî?+Ρ„nÌíÂa*4)ß%NŠie«ñ>´·~ tÙT–ÜãyäÈ1ITÚw¥>_3cE†ãh»ÿŸ•é^ÄkžôÜ¥=Yœwíö=5|=÷#Ò¿Ç66]‡ÜÝ9WÉl¬'ïóX‡ËÙG&çMK|]H_5™D>çñ5ôb±o%a¶­ |°jûî.­7Öà úXdïà(ÑÐ!ïNéžÍ×AÎáe“Ëê‚I#ÓÉ8²“øà$2 uèŠ,Ú£me†!ABg›>9•L%üÆ™°fUy¼ÐtP€oÊ/8wáÊâ“p°¿÷²Ø˜ZHË’«c= àeðû4ɱ8D|–&Ùþ[’óX\‡iò»0šLÅÄ]MÜ΋÷q2{ ><¼±Ù§z3Hß„[¶.Û5“Ž…îh ^‡+NJvU8æ´ë(§G“I;É"ÊçNØq^y¯Ègºx+_Nñž"¸c:)q˜W”žëP†bŠ¢ç{ÎÝQšnÝ•Ôp3ý<5<‹¶ívæ{n÷®Q6Q ‡»nÃ)i¾8`óYö^ÁöE½>¥mŸ"¬Ãf£ÄYа¨Œô§>ì”S£Ç-Xeé5z•2dwd÷pþ‰EªsGµ«yBªÈU¬zbaÿðT‚ŠRðÐÖö4S·£ð8^%Çÿü”ÒñóO±#qpõ€6¥¿nx{Oj mzî Ûf|¡MʆJG›_wI%ÅxLÅm¥Å…·ÁÁ®¦ d[ˆ3DPl-Ôë÷§pz¶Ç–\Tàÿ Þ]ì£/д³s3!Ë!y3ì4l«ñKh?𕵋ÂÙõµ/¥Œîíœß…ÒÍYw5Ý5žBfêM2OÝ3µ.å+Gˆ÷yœó–.‡9d†š¨±‹6ÃU­9Ú‚‡ÍØfl5ÛŽ£†$ˆû¥Dži3_„×¹‡£o7¡Gñ«ÙÇÔì÷O·ý0;äöS…Vmíî”<—ÑŸÓg®ëkû®äNYeZN’:ôéú¤ÌMÁÑat²¦v—’Ñ•~™0tPŽªáI_l£–pNÎ<÷uúÙd>%…ÖÒÍ•½s/Ý‘c¾¸ŠŸX›}Ê¸Óæó÷…ûpk‹‰ ω}5p&È©S£;[ ù B:dëSS4›U¦MG&Sª³`&‘©aYÛ–²Ä3›2G=ÜS¢«.MjONý"±fQHÃñú*ȉ.²£([Q±’^.äƒÁPTX\\XÚÐðæÖëIoÑÁíôþ“'jøÊí‘5Ð ª£µùÅ~*Uµ/2?MPÆ:ï QVpÇw­ç 2E£¼j|ßþ;\•zsŠøÅU–¾,˜SHúHdÒý½Ö"нí!Ž~•Ú»y¨5öçVk U”w-Ê(3„…9Cm:¶‘êúìæ,ƒöp=ƒX2fübK\²pÄ›‚8÷/ý;“%ª'¤nE·t –dª©»ŸEÖÐÍðy¥¹E—«´(ƒu.¶Øê†ÒÂahJÎLTïž,¦(¾´(ƒtSÀ/h¢•8î°ØüS¿Â˜B}8TÐsU¡‰³ÖFßkúÇñ¿øü*cÞ à,ì&J8kCA¤d¹ä HT•Y©äÅžµ*²T V|-Ÿ~Á“­‹n°ÇCFö0Ä•¾üJ"ÖIà4Õêù‹©?qy{sÒkÁ¡ròó*p‘è­B—ï¼xëÓjØ—›_ÍY¥€Ä!â.Ñ‘GgŒ.*Í5šsöçäB3pû%lçCXðì^.,Sp@KÆOš¾ŠÏ%º>!œ¾¿Ïb¹@¶Sª6;; Û!B—©.\bkÐÔòO«6`“ÁBKèÌMUá2’£˜+i‡‡T;<²¾ŸB©Ý’aFŸFœm–D9úHÊ]ƒgø»‹Þ!£<ˆmæïÖ¸ÆͦvªÓ«ö› 멲å><æ7O½ƒ¥ì9k;‘;!ó‘úpª£¦“Û šo…ÓJSÔR~LT¯2PÁYÇÙ9~Úœ¸ Í>fz¼ø2-ß죸(2Ìâ3®?-Ý,Óúv¯àÉÂ4…†}'|Õ=ßv°•Õ•Õ5§7œM>J;@xrƒJ›‘ÓîPIî[b}‚¸}^ü¡“gª:èÛ@†,WÃ6X¹3ØkKJ,…'k©†ÌÎh‡·ÉÚéÙr©ÄãØ—/I†!ôúLmzlø²´mGN=~Þ€Ãqxþy]&-½^§ÏÎNJ€ÎûàÞS{é‰ë„Í[O\—PÍ’g¿žpf rùÂïS’<åQHñ¡$Nzó!ÛØ=ÕÛ›]©£ÑãgG2æÁóè > 'ª˜¹,ºæ),¬[:Q‹"=õÜá½_ñLò§ëy_ 'àµÚö–sçóêàtÆ™·ÓÔŠ2ÚУ_2ËZ¨ÏÔ»rÑwóuyР†éW¶žðîð(]#É—çÇ‘ÁÄñ‘NÁ)ÇŸT–'@†šæŸ‘´{Åòh/ºdœŸ9§n¶131µU·ªµÀPHì ›8{¼'ÝCY0Ò,CÅãÛÈÉ1DÇÓ£é÷Hùøý ³P F}ž.!%u/Ds;Zãö×¶•wóïXìDä~„Æývósšš¯A=­ÅÙÒ©lmÅçî^iŤƒ²–ëù$ﺇá þäîsôÌG·þì?>VÃéÐ6mQsE}n¥1;“Šç$.º,vÿþ²jS}\«· Ÿèè8Ÿz_zô爰î¥%j.òéÜþ ©ÛiŠÌp‹‚µœû{Ëp¾pãõ+|±¦9¢Ä«~%Ì¢};d4ùÚvZì†òâRûåñ³á£W_…nÝ×­[Áu¶úñâ/}œ´1 ` =Ó«üϵ_xÊÕÖÛ:ÑÖZ´«d¸Mê«&<ÏísŠôÆÃæÅ‰!œ¿Qþ¾Òß´br‘ª†KOï½Yd®v]8lŠ\ Æ?¿¶ÞÅXP<ý-=›ÐÝcd·Üz6ñ ôók <Ö{6YL–Óê;o­¾­F>‚Ʀ VÜÝD‰îônª—Ô…r¼‰fWRT\ø‘$Óvëb`çn^>.©ÏNSCVF–NGVñ*QÃþ5j¿ñ£§9Œ`+JÊKk«°?qRå§Q¤çRb ‘*µzãûÐxºÌz©ÂÆC $s²r’Ë8kfâýÓ½i…ü‰Þüó%`ï%%E¼îí½ÿäÝ7)äw}ÏÐ1;¶,Š¿¹´|%LnÑ^þ>Jâü«Õ§Ðü ~Ùµ3ï®Ýãüoàÿ?^³¿TÁ¿-p |ù?‹á-ñ¦)äIô|ˆLá]q²aOg„¤GFþð9ŽGaúmò ecϘAÜ™?TDÁcvñ‡OvUî½óî´kƹx®Tk@S|‚Ùö^È?~$Q‹/îáÍù8 û ‰Éé{!Žó1ïmh0W;½±ÉKx]½)ˆr%™ûgÿÈ-«));µˆñJ7 x«fˠ嘚•œž™V±3Òl™ d˜FãÀ=-™™æŒ\8šz4¼¹—œ Zð„Ua÷3jô†½¿È5ö¹f„šŠýÕªã¯ULgqP ¥v8¹ÛSås00o}ÑÊâÕÅp’{ï6˜”CÞc„!©@:ÖZ¥¤½¸œî&kÁ5²ï(âý;¤ÛjJ¯T²Eo¥~¢×ĉÙÜ®k¤…u=êâåÎs—….ïìòÐàÕðAÝÓùÃýŽxð‰øÊ¯ÓÇ“]°í痳Πx%®¿¡–ÂNø ô¡.ƒågxA‰ ›D6IdšDžJ˜4ÑžÏ/Ï-xWRTþTQù„SU%qCcmfº¤¨ô™)¤/)R*ÎJÚf „‡®ÝtÑ»,.î\k̬“äZ±°†Ê€®^ÛTuöçó+sòß”l‡ê’Àß'ÉzÂd OA’ÕvVÊhRª",¶+Þ°(#uîMtÍy6'm_RnjNFQ$d‚.;]Ÿ½€¬Q«¥µQº¥ä!Öµ8­gP~\®¤ÒŠéÔ<Á*ªO+ ÷H¿Jz./¿Šû…exGŠK >—hу¦ª0)¼j“”º.3]§›=I5û+:ž: Yo]ñ ‹Nd-mÇ ÚÄôô¹à aß2¡¥¹š$ú‹Þ—¯ò ¢B…ròŒÂ[£¬7~Mº¬k–H›@¶˜Å÷,²Z‰NÒÄ|^YnÁ ­@]Öo;a8!¡•¡Ï¦;±OE†âi'"iDa¡îÖ¸À¢[ϸLmbh¦Ö!z[ëÈ-$ç J 3GšB‚#£·tz¿%\‡×/SqGE´‰ý(݈óäâ*q2_HÇ=äqÕ)+Ÿ•ÉäezöÈûº¶“–7wGIZzØÔdÚeé1…P#ˆý”•¸Yá­LµÇƒ ÎIi¯-Ý q{MQ‰’lÍg-¶(ëw°ÐÎeuvý[›95v} vöb¿¡ÿ Q€Où endstream endobj 314 0 obj <> stream xÚ]’Oo‚0Æïý=º, -(jBHBF2·EôàÛG2JSðÀ·_ßV=ìyúãyÿõ%È«¢RÝDƒo3ˆ&ÚvJ‡›@/píá!•˜î'÷}£IïýÙô@ƒò\?Þ_óý³·Ó±ä1•ÐzÇqÖ@Ãû¹*êyœ ¯T;Ð$!”›pœÌL;9\àÙ—‘`:u¥‹S^;Rß´þ…ÔDIS—Žû–Ä aÔÓ¨+„±”&e™Pòß7;Š ¹´â§1ÖÊ­5 Yœ’„ÇV3¶³!g¼@íyˆžpíùõÆó ê­×È£ÂécW¹÷ç¨=_!™ç»Î¼Ž\Ã÷Ζ>3¡‰•8Xfç³D™/›Y°ÄQVXmk Xï°Ú'÷éðbpƒÏŠ›1öjÝšÝÒð~;Ï?A£Üó/§ž- endstream endobj 315 0 obj [833 0 0 0 0 0 0 0 0 0 583 556 556 833 833 0 0 0 0 0 0 500 0 0 0 0 0 0 0 0 0 0 0 500 0 0 0 778 278 389 389 0 778 278 333 278 500 500 500 500 500 500 500 500 500 500 500 278 278 0 778 0 0 0 750 708 722 764 681 653 785 750 361 514 778 625 917 750 778 681 778 736 556 722 750 750 1028 750 750 611 278 500 278 0 0 278 500 556 444 556 444 306 500 556 278 306 528 278 833 556 500 556 528 392 394 389 556 528 722 528 528 444 500] endobj 316 0 obj <> stream xÚ­zt×Òÿ ÙÚ Å€Å&2• „:5ô¦W\poÂÝ–‹¬2’Ü{– ²± -€é$^B'ÚKr×¹N¾ÿ]Û@þçååËyßãpöKwïÌüfæ73÷JDYYQ"‘¨×ü‹6.]8jî²ÕãÇ LvÇÆ_Um‰Öü@Š[ÄsÝx¹˜ËêmŠíìKžÔ¯½…çƒ>Âó]ò•`KY‹D’^QñÆy~a®ãÆM3nÜ„¹A‘!Û¼¼Ã쇻°?mÚ”ÑöÆ›f?Ûß#d›»k€ý2×0o×0ò‡Ÿýš@÷ma‘öç{‡…}0vlxxøWÿÐ1!^m¾-ÌÛ~µG¨GÈv­öóÂì—»ú{Øwh>¦ã97Ð?Hæb¿,p«GHÑø ÕÃêMêj¨xTŸÔì.(‘ZÔò§D=D=)%NÑC½Au§zR½(ª7Õ‡êKÙRRªÅRoRoQ2ÊŽêO  RÙi05„z—J £†S#¨‘Ô(j4õ5†K£ÆS¨‰Ô$j2õ>5…šJM£> >¤¦SÛ¨¨ÙÔj.5ú˜šO- R‹¨ÅÔj)µŒZN­ VR«¨ÕÔj-å@­£ÖS¨Ô&j3HmèF‰(+j…¨¯¨¹ÛbñL«QV³¬>·.³~"Y,©”<£? —Ѿt53„ñeüÆõî©=õHéùfÏ]=¿í5§W²µMJoIï€ÞßöYÙçǾª¾çmÇÚ^’Ž”ê7«_f¿vöЛáoM~«B6@v3ìpÿøþWû£Év øq`úÛÞNâúpÑÜ]ùEûÕöUƒº*tõìÁýÇ é9†´½[ÿî‹¡CO þîð=#zÂklÚ.Á×mT©è@Ûv1¿¼m9›œ§M‹‚(Ц$Çá¿} KI-蘤t(äÚK Ó!Sz0¤d1íöü#™Ú¬Ûë%6üu°ðÖ”f½8‡<Ï=º+æ×òCXD[pwÄHî}r`g„(HŽWGÆAV^Y]PZ^ï½k ·œ=RÔ kÒ‚€™õ˜’cÉt¿kø í¤„…œ]«?b0›jz±Ð •°OŽ® Ï×ß7ꪚ@ù~;=[›S/Ç5苬éÇ7[>çBU„¥ ƒ@PéC*5qñ ¦i¾µÃ¿=ˆ¾Wo²%V,}¸øœôºEÌØŸç&Ç;þ½.¼˜Æ¶‰Ñ:ò줷´:-ÄCL·–<¹Óô·êJÃÜ´ª@ˆf|*âJvì(ÜyjmËì1¸Ç,âþ†±¯TDêRe‡‚^ç¤y)Qï¯^ä§½TÖÒjÐéÕß|7Pó­üw¦‘—…Å>ÄŒG_ï¿ÄeA%T%&ª£ "3cŠTŒE/{XÛ¥W'v‡•üO¼­šMê$ج¶“Þ¦þ>xÜDXíVçZº˜÷ðÊ¿7^ÿ‹Õ‹ºŒ~z·ñWu)•[µ‰¡ŠÜèâ”WFÿÁ‚7ž´ ÿ{Þ¸õGo|  OÿíÍkrÜ€%ëìÿ«6<¾Ñò®vi*¢´Á‰à1éQ¦$â@É Xò¿8˜×ðÇ-¢óè71?‡?ÎZðo~´ð¡¼l;jô¶õT˜. éïè=þ{:tŸ‹wdPppQP=W ùÙéézƒ^O²Ï±j9ø&Ï]º,>žP‹†INS§åÜúuçк7ÿ³mÚŠ~€šD-·vŸAÌèt•¸m)êÅj¦/ñqXØw÷þ#M_ì¿Öx®¬îžž±ÐžZJ9EÔsˆ½ß"‡„”dfíH§.ëâ °½íŒè£§¿øÎ1û£oÍ[6{í \ÓçÖM7Ræ´%8˜I7—>á¾S{jϯ8ý | gNî0í¨™ º®9 ævSMÝi¬å`Ñ“Bƒ—Y“cÿže%õë<—¬^–ÌÔ°ÇGåpcWýÑVÆí|…ïhyäöCkÃ˰±ì×5¥¢''Åè6NfÁ†¨"ÜÙú¢U€Þ4g7šƒz£¾y¹`#“¡6ª¸¿`%–nÀÝⱦÀŒÜë¶>{ßYœ Lzª1CþzoM6oAF®*Q¯µÈzê=ùó`TjµJЖDþ0üžØðLO<÷Á¶qʪRÕé\6Üÿâ’FÝr‘n“4+žZ†ö5¡ý¥"ÞºIÌ¿‡¢XT#É/ÒÒˆ¾V’%ááËáZ\KÇF@xx äËùK ¥¥P’Ï@±C eÐ7:uÖ³gC›Ý_áY¹éÙ™ƒL¯×ÅÊaIàrgG•Š0ººËÜk×M6ZqR”ƒŠÅ¨­`OââU4Ù^ˆî¼£µGØêÐò€€ÐЀ€òÐêêòòj¾¦  ãü[b~q›#›–'àÏä$f)¹XP'hð?Ÿ#K‰@b”Y‰9\>¤f³…äS˜Úd&Qã-”yKÌ» ‹,\O¹î}iË÷Ó ]aÌ vã;?e|³RÇ7ÏÜóÁÅðƒp¾.Ûû]Íù´«pÁ^ø"»Vš#¿Wž†‡p ι̣%¨Çå,3Ô¹ȒáÙk`&,…Y°@¹$fôj'd’k°ì%® º$FÚú±å`ã–-™¾ÀøÑ¥d«Ö ¦½€öÒÄç|ý$uÆ»ÐÔtêùÒã59 ra›+è矴Øú9?1è¥WØÏÑ8Ä> Oídüulƒ­g°æ‹êr›+"+¼¹$!4t;>?Úp˜{>˜&‡7N_» ¯Å>2¥’|ÊHæiIšc"IñOvNˆINZŠíUƒ†ì@ÝüÌlÛ‚¬Þ†>|8ó¹Shú™½YyòKÏ͉ÇG ¹b¦)¢ÚRjª>ä1œå๼z`š)ÆË!^»*ØÙó6Mˆ.IªM†$]²i»R™EÜ^É͆#ðÀùÎr˜Uä}ª.Åb‚ÝL}Pi@¨o¬ó¸G‹ÙÈKפ%ËuÕMxâ¦ð…à[2Ë’ŒZò“IÑr|Ž„¤|. ÆÔôœÂ†£7 Ì[2# = [a##ý¼aE¨kèVÏà-0V‰:eÔu9ÀÔ™ËË£Ì>±ÞÉ[&Ÿ‰¬äÒ_óì{$•wèÌ¿³ãÖƒ&â¨ûhëÃÅ÷¥íH†n°å4JG}ê“2Ü¢2mcbÜÁɯ<ÆT¸3«ñ´ó'Sq?<³8X.ý—"fÞ#$þîŸäMé„ﱘ“¶/Ï á›Ô_f—‚ÿiUAä¸ÅÌÕš§÷IÊï˲bOØ›`3lŒòò_±%%¬3|ÊøÏ¯ˆŽ›¿{(æƒøl–ÀŒe VK° hóÔ%LˆÄ»Y›%ÆÂ¬3y¹éW!@é.QFOÇ"…Ïx<ÀËá]Óþý°/›;LÃ1ã±Ì£©;òïìý¬3FÑ?N "bõ¡°½¨boØ!éc4…ßÂnÙ©ÞȨŸ·\¸xvý\Voݼ›1Ű_5l%éá„ã†}0{ ‘§Çœø†s#}¾*`òÎ z¶ðgdýÝ­_8¨Wîóh‰(‹Î^ÒÄ seQïUüa¹ÝìYë§MžûÙ-NÖœýæ@§>õoïà‡nXüm½OGŒ.°¾4޼e† ]ÌÞÌê"Kh"Ú?që£nß Ù È—x™0ýÅn-lŠtqrs s…Y îûídÅIùš[vœdpŸØhØ~g"à|u ¬¡òÐî¼:âÚmEN¹¾©Ka 3uÛȉ\¿¢À.Šåmþ•cñU«åÝÆG³„7m(0Iüó—¥"ÚÅ, f,™œôºt~u1ÕÚK¯êCñ¿^Ÿ¡Ï1dfµ Ù5¡1M¢ãmï‰Ûæ¢ëlÁ˲Ôþ½¤« Èùïð:¶«`ÅÈÛÿ)‰yY lÚIþo´ð‹JE5m³Åü;mKÙ”’^±ÊZ›øl2á«ÖX!±iÛ@8gB[$¿…N>žó”psßE:ºÖq€C}$ëÞ_·dÓ,–?Hd—œ? —˜»coâ7¹ön~å’+¥—¼½œ–þLˆë#.Ô(Av÷ïýSw§]Æâ\f¾Æâ¾GmF­U •ô“–1 ç­Ÿ6„ à©°´½g±=þœ÷­#…áÑqô‹ÝÑûxý8Ç÷}¹‡H&+ýFrãQ²¤Ó=¬„ôn•k ±œ1K‘ºýôKŸØ´Ù¡,h§Ðµf4Ø,毵MgÛ÷¿r\ÙK+Ié¾ Í žÄ‹=òêäHw‡þ>û¥è) >£¸É(½KtO  æ5…˜#¢mÚÌ Kb) ±ðïv¸óý{ÞuÒþþ6OÑäNØ? 2 ähݘšö9GºoÝZ­¿ûûàEºïú¾Qé)_BK`+,M \Œ7Õ¡ÃÄ·kOs¿Àƒñ¥xØ_ºÖ·ÆáèpÙrü>ž€]±+š„'¢ÕriÌE¸^±ëÓ™kŸYÐ.K­÷Ä|ÿŒ­7ä\áÊ-oÍlðð˜ÞD®Àq¸Åѱâuˆð.ÁîÝ—;úžPú#¡X£ÔŠ þj… ú­+üÞ#… Ž1çW!›[§w« ¯»„i”Ó¹`a«k°»ñZÇVÁôt°Ÿ­0DVüv‹¨Y¡wÄèΎݸf§‚àu’iÍÝYQX¨Øë<ûŠ{ògpñËœËúLBk»~%Ýœgˆkœµ:G׉àA„×Ó?@œ7‰¥âךòCø),Zˆfgf9|Cog¡ƒ5¾äµ¶ £T“.= !:!!)ŸÃ­2táÿâ\š´pÝÐ"\–ž˜ñvþ[!œ°[Ànu»;Øv€í©þ{‰“­‰“ÝKy®ÓÉßáŽr؉òÝXÜÏfZgNñ;é]ÿWk‘xiÆÛÖ®_,±ùux—éöU|ù 1Rµ`M Mžñ*4t8Ó4ÔÖÔ FÐCà@¥œ¯×ÓHõ[·´¸´Äl°ËcfjÒµõ’éÛ/H^ß`üÿ ¯çË_‡gH‚tÉ‘8°ý´¬#˜;½QÅO«£˜¶ lb®NATúȯZR¥ºÝ^L{É_¨VD§¥èu©*~tûcYV¼^—L>d”Èùƒt%xNÂÁ[·Iëã³É D?Ç yûLZ˜¹+Ú¦TˆHª;?·y ‡,rÁ£s/Æ ð{xv#Y8CóÑb4 MDNþËŽÂý¿Eù( ýâÖ]4xÎÂÅøí)cå$¹»øø:ð\ŒÂÑyÍ žˆºñô‡áßâ·åøÅŠÎ_DޱhG'7ß“ ‰0h“#` O‚¯{~ÞŒz›øj³íñ§h´ k~þ4Ä"ý ].dJ±ÕE@Q ÊCö7>F'ãLfÄãAƒf(ŽûZ Ì?79åEèµ ›Ín‹ðU“±cCÒþ‚ê²ÚFùQ0¹æ¬bš#XÔýÈ7¨ QÌ¿ ä„FžZÌY .½:‹‘þ®,?ö0ÏJÝálÈQÊÌ *Wp„]¡gIœ‡)L«#&ÔJ*7wéõÌçßWæ+L8òÌ¥a䚌نj(æ>²Rãwç‡~€‡ËŸÆ±Ë¯~ W™ï±ä6Æáü žõÆ $/tÔ‚—™˜ŽhZú[!´@ݶÝ^à a1¸7{4{SíæjÑͪtȉ““R¨KVÍóŽ !=uÒáØGq×e‘g7Õ®-! f+)øãªlWŸE_œ]W!½ˆžñ2÷³,+ØzNÚ}yôÓ«úLxjº“^*R;ò ­D޶t’~2ètÉñÞ«eþÕnÍHÄ‹§L$‡©Gæ\ ÊQŽÿ’4Á*“w&Wy–gû€3oãÜ)\ÌL[wpÕQÍY]½.;‰LOL$Gʱ#É9d¢Ñ2r@o4Ö±l;ëutòo\ÿu“K/ÂÓE7§”Ü=É@<­ ÍnÕ›Qæ=”i·i›Æ¶#IVI M.¨E£ * [[¦%„1Ømûç. uÏ`ÿþçC;ýäﲜ8)¿85ÇP %$L À'Oî(ª‰­·:ɬÍ"Y4‹ßùáhGÜÝŒVs|ß¿dÖ^4„L^ç ÷!‰±² ‰AéZØ'd·—n³v›÷fƒ×«ì¤–µ ²ˆJÚ6‹ÛDüM6¿¡²ú áÈÌOë® ö_e·êÊ‚ &iTZ^Ò¾]†×ðU>)&»ê`6×ÌÍ.›NŒË÷@1í¿Ê2"Ò4yP†´´|Ææ×ÜNyÅ¿†ŠDäŸØ“ÝDž¿ÖOç°¤SÞ?t¥>*M‘7²ÝM†'ñqºTm:¤Ùí< ò\ nÂúP¹^¦eXÞ>Oæ•d Í㟮½ ©)¹žÈ±½MfL4&ä1##5MãÓdèƒöôÎí:?e^ñoyÛj1?”“Eo£-¦š]5÷„j¸Uç¨ qß îÕФ (%hµÉJ,Á3d˜EZcJ&¤Ú‘-Ú#àê­™~Ëôžäú”$—¢¥Ø"ÃSqJl¸ÿ–¡`Gz}‹¡¶áXGRÒ[ôQ•$ʲŒ©9èä)Cp’AmTƒÆâQ.ÂÈPg¼»[:G€z=lOÛny­=º}GÌÿÂßf>=•Z]þ òëòosaD¸”ª8µ OÃe2¼}’œMÜ›fWfNÝ×áØêºEïJ–Ó_@¦²0yâïdxýŸ2Iý‘&»QŽhÁ.þw‹è¼™_FªôÞ¶¬|ÁªH}o_+QväS²ÞyM%¹8^Òn׎“• ƒ$»¨4(ãxWI*%-s–G¼‡—*˜*¦>cÓ¯£›D¨{“eb#Û4ò×Ñ›ðÛ¿Çt[s/¡ÖðR[Âú Ôó’ðþŽÌü¶"ªÒ‹ ‡Ø•J§nr-ä§Ê¡&ã«3Ÿåv‹¦¤¦(§ÎÄÝW”;í©+®¬έÿ³ÿ j¢êĶD¿íþø÷Ñ#ÝÑÛ‚!¯TýªCIžŒ¯ÿ©’Äp¥)Ê‚|M÷Ç?Üo²m¹²ù!šrþ¢YêÝùšMu¯t=LÙ§ù7äÇCÖЫBTJõ¾49Ò„ò½¶6n,ÜL:¨ùŽ‹üK£*ªŠKÉš›R»E_Yw0‡ÄÏÁ['È=iéž#4k–úÏÚ²œ™‡œáˆ”s°¿©ä“Œ¦²ÃèÑs·9mr«;ÄÁ±–[hZºP”&e?Ø„<[l_œG…·¤1hß‹E_ÒxˆÒÚþ23y“¼ý‘™Öë3ó+0Òƒa-/‘ØèñÓˆEÒO°„´ü3ÀÅ1:’1âB¹Ñ„uô9…Çe–Ã>¨.÷¨p3®7ðÔ®pÚîçáãNàUÚ[F(&š¬TšQíóí®[hýÃXá¼ò À¢)7[ŽpYpFWçå¦QùC\^UQZ´ó‹™á¾cI{ч“þŒû=NºÖþ5¨gvvh¸DЪµª€1‹ã=Éüɯ›¸M–wX¬háí:,&¢ Ï“©Ï1v†åX[è“2Ê¥ùŸþh?ö£ê]*„û±wF`KŽ«Ï¾]æ•YaW"A«Œòßì¤pŒ«Ýܬ9ÍÐ`8]½¯Ì²»ö(ÔAKŒÅ)' ´Ùe´šc²­º…ÏuœÒZ¡46¸mÞÌól<`«'nàMF({âð˜ôÔÌØ!¸¯œØÜÿ瑈F6û¸$;É"جÒ&y °Üw†5øç ž±A';ïÎ&ÝÎ4‰Õ¹‡wÅh.?—E ýí'ŸìýókâÏÚu¿¿n‡éÿïjìO®}Ñe$±©ŽÝv Õ'oï@°Ã¶ª5ü2šs¹®Õù¤ô% A³ØIðt‡*õ5æÌÜUMÀÜ…aa¤§ÓùÆ„$Ňº™­,¤ÂŽ¢ÒÆÀfM 0Ο¿"‡†è†õ»êÓŠ>£N©NQB<•_˜]’±£(¾f+IRg•«›k­«‘ô…cæÏÿHÎ&óö¸˜Hðf¤møåyXÂWDùº€;3÷ÉZdƒºÿtø*u±‡7T­«ZË!\ YÝÄ»CðyvèüÃGä°wÃ^#sJrYÁd‡yGÈ;ï‡;ÂI„ºGçŨÛ×lPuúÆʊVí®×w„KéŸ.?{&Ça5‡cé?[·žˆ×ídÐî€Å¯>¶È§tLçQ zþÇÀéˆ[[P¯¶—_||Nú}Ì/g±½°âó, ]ÓK5ú£†òººN‹Ôiré©ün¶&¤,ÐOd ¶T™ËjEžÄ®¦ÂoùÐŽ}ݶþ¼øér=…G ;_ÉHÁžvJœ¼„K!•68¯ µ4*™ŠÈÒÀÀÈðàõÇO\þìì’˜mcþä˜/ï ÇàÑ‹s⯫%‘U½³I×ô °çôÙcWµ¬H»ˆ(uYS¥?e(«®ÖU kn[Ìþ‘‹þýÅo×Ít‹ÂdÛä¿ô ™ ³¸Œþ¿ÄÂ#fbïÎÎq‚9à踌‘Þø™4¨‚UÒƒFwþÀáµîÒ}ÿ Åÿ\¡—J\y¥Ä¾.%4J3?Î$"4¸ó–˜÷E>,ê7ìî…ûŽÄ"ByìO£H=èõãHÊá`ìȺ€sYÐþ½ð)ÔC#-ß[¹ÿ@Yì…=Š — Xà g…“sÀFár¡¯³„·k 1wU»Ç¤ÚõdÏuEÁ… •³\z£Ýû¥I»ô­†ŠÊÃÃ{§éÓé,:-ºÅáë×%päl%—>ž®Îá R XJW>X}˜‹ŸNÄÖ¸×ÇSfËÝÁ£4¨™<=±†/ïÒf¤™4•èßçS/ø÷Òù Úcœµôq\•Û™¦|g$~÷}<1Dñ/¡y©š1"?¢Á72PëäÌœå÷H¥èñå­K×[&­#€xéõç^Ü‘^A¢oXÔÆòW/Ý÷:þŒñÇÐOZî}-ÜJA§Ñ…ÇC0Xc*6çÖÔøU»pÒ+sÀka¬ 1–Sšø÷KlkÍ!Ÿ HsØ'Ò{h+ZÇšÔ7£a.³ÁÛ}7¼ND|£ÉÓ¥&¼œeSbèõ%%"¦¸d¯ë>]žÞÿ¯äpÄg|®OÍÖL×LTkræÁI¦®¢ù‡ºAÚxƒŸ>1‹¨×9ËþØ9ʦÚ¯Q'$ª5UnC`´ñX¸FÞ…• Fz¯&¸JõU,ÑZFÊó°RhASKE?GýÍb4[øÕ` Œ–†HtÓüíG¨Å7¸šÆ½Å×_¨ºp–;²–žíïá¹q/;ë–—ùÁ¸ÆŽ§Ñ×ýÆ>„h<ìu¿1Ÿž´yÁœ)ê­ú¦ë›« ™ Ç#é0æ¤ÇaoUµpUN:¸þdräcÅü$t‡ÍÚQ´çœÀ}aÚ]XèC”À} ºœ02É%jÕjå»8S†­P*¯cp¬h„b2YøëÖhÂÜõþÂò3ªÊó#¥ÉÒc )y©Y©ÙÂ8Þ)®X¸<ùt->dÉ«Ä)ˆ8E€“!Bx¿^gŠ„P6%nÎ’ G5ê\0ÇT6B)‘ Û  õè”Ö…Úì¸4UŽFÄdœ"JS„®:õåêÝÔëôCí!ÈÕäú"[ü‹,-Ö˜$èfHOËÿÕËžá†T¥ð‘];ôíª4¢\^/FM(žÝ¹{÷Áò K}sÁAë`­?¯×â„Ë´™q Ñ q)ªe3d3~Lf¯t;((È*íX­[¤ÞîØùû•/A¯;°â feïá›W­Ôn&Æ ƒE_QÝ¢-²VaLÎ#•©ºöÓ¯¾&ËTæELc‚„Qq§þ¸ÁTÙ¨ÛÙyži«î WSñm^A\z[ÌO$Wœ9¬/„—t4(ñ]aaÙ6%~(Öɰ™ÔÙÚT‚ZE”pÚF½ôè'ÂQ€7Ù.’¥ÄÅú¨âkç/¡|G[R3MPÈTD†…+âüZ¼qg ùDù ¡K3ßÏ$j1£ÏÈØØŸ—ÍÊœÃä%A$‡/’±q2ÓŸ•4´cD‚kÚ{% ?H±‹Í ª [dj\A¦ÆDÜ}»3f„FZBH‘fxµ˜W£LÖÔ®VÐ6 ?·䤛$Ø-—¶t?ßÔճçùÒž½¸îVSJ{¾îôûÕ¦_u endstream endobj 317 0 obj <> stream xÚ]‘Ánƒ0 †ï<…¦‰$k¡•R CãÐu­¶ib:¤¢@}ûáõ°C¢ÏÎoËùfe^êv„ðÝö²ÂšV+‹Cµ጗V\€jå8Gî–]m‚0Û׿­îÂÏ"{=|=fû꛳§Ó±à(l¼äx3bŽË¼º #v¥nzH’ ü˜:£½Áb«ú3>Pî`ÚV_`qÊ*—©®Æüb‡z¤©kÇýL²W8˜Z¢­õƒ„±’¢HÔêßö%çFþÔv– ÁE:1Ÿ˜±]L,çŽsÒ°<'. Òsîj#N¼ô¼$^y^ME®O¼#Ž=SŸhMšøeM¼ñ¼!ÞzM憟§¤oáw¿åÕÚÉ·g1¹Ñj¼/Îô†ªÜùNHŠ endstream endobj 318 0 obj [778 278 778 0 0 0 0 0 0 0 0 0 0 1000 0 500 0 778 0 0 778 778 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 389 389 278] endobj 319 0 obj <> stream xÚuTmlSU¾w­[eˆ¡¡‹ÒuÃ(Œ²É”`p‚Ž9Q`Rî®cíe¥ãcwmׯw]¿ÛMV[\ÐÉ”cÈ,üÑÀ/ý¡&£˜èáœîTô\.þÜûÞûžsîó<çyN.Ë(• ˲eì¨g×þWê›öØhF¶Xîï[ø;ú\Éà*¯*Â/*ð ¥îæNåꢕ Ã^&Õ·—JµîYZ™—h).}Ž)eÙ%ÚÊõ¯ïÜýíµ8“•3ó\߇UàûšŒfÞÂñfÞf£­ÑÜeåo}ðn´t¶¹^0óÂãÎjêê †Újƒ¡¦^B’zýn­~c]Ýæuúƒ¡N¿­—·š8£Eßdºù^£@³~ogâ‡~Í–nA8òÚ† v»½ÚØk«î³vm]»No7 Ýú=¼·ðú}Aÿž±—×ËVTËú¾Þ#G©H}S_oµÐ 3EK˜¥Ì2f9Û©d˜Ï+3Ízõ±~6À´2í,°£LSVİŒ’YË407Ø—Ù]ìWE/¢RñR­<¤ôa_Y>sì¯)ò«Ñ f2 ™Œ+ Š`·§a²¢ }ÜeoÞU }hL3m›²Xl6‹eÊ6==55­£ ñ,nʰh5¶+p9:§!­¨e(庠|xØ)V€;èOЍ•´i -¢è÷ƒ»\L8ºƒ©jA-ZÄ.ˆz"PžŠÅ“„/’Z´ñÀUÔˆµáÈÇãáÈh0‚¨*éŠé\àõŠ¢ªlá1çò·sì|.?—S,¼E¥¢ ÒŽŒÄCü”•#)2Ú‰yµ"¥t…æÂV HÚƒDä¤ͨ ¨ì!"q’FÒLú+ʰo>‹þʰóx…7Sà{5·ª³©¦ªòV-bþùíÖ=É…Ùª–.v>¿^‘oÑL~òÈÏ;²Ÿ8]o´²ÓǤ™?ŠÛ:ï ÷ŸÈàÎäÓd%ÅÎâó9®ÍøwM2 CJöÁN¯×_¸B&´ƒ.Ÿ\àŒ¸'Fð2®wa TɸdjÜŒ2( Å‘‚]¦€…ÙâO¥{ý¤™ˆD¢‡„7r> stream xÚy|åÖþlÊìÐdH;º"Ué ˆ:„ô¶éÉnzÛœMïu7½A½…"¡luC»rQŠŠŠ÷,¾ñ~ÿwSHüäû¾~aò›™wÞ9å9ÏyÎ aÌ̉Db±jíâµë×L\lgo?uŠñÊÌ¢4ì{¹ÒÜðc!1üÃÄ ˜†™ýƒa$%ƒé‘ù} ñøpñ8’ÆN¶dÌ$.PS¦LŸ!rWg›7w½e3uöì÷&ÙL›2e¶ÍBO'¹ë®^6v;ý]œþNr;ïÝNr/j-7Òl¼­tÙ“íÌÎáJ Ø0¦Œcΰ Çôaú2ý˜þÌÆ‚È b3–ŒŒÂðÌPfcÅX3Ù7˜Ì?f$3ŠÍŒaÆ2ã˜ñÌ›Ìf"3‰y›™Ì¼ÃLa¦2Ó™ÌLæ]æ=f.3™Ï,`1‹™%ÌRfó!ócË,gV0+;fó1³šù„Yìeì™uÌzf³‘ÙÄlf¶0[f;³Î„‘Pc70u’&¢É1“ÿ˜.7Í5›govÙìGó>æ‹ÍSÌï³+ØûÒ¥—¹-Üþ>ãúèóCßy}Õ}¯öÞ/£?ß_5@2À{À§s-êNòQŠQ,àé}­a¤F‚.OMñš¡…?ç˜혰^×4òN²ƒÚv';ª}+!öCJfò¡äOÕ×ÔŸªÏ¦ž‡s\{®Yu@©·w@€·wi@uuiiµ`wñ¤ä¿˜ðË ?Þûѽ Wù”“®™á ^‘)ÛóÈv+µ"%°* ­X]ÄáÜñ¿¯°-ŽjÅq­8J#i0l65˜à{ü?ÙÜhhpÑ–-Æqæ§z.8±ù(MkôËV€µ$x%E(È«1¯½:Ÿp—È?gCÈ8óÍ=²ad $@’ªê ¥&9·-¬~}Ý Ž Åïø_;6ÃZÌÒ^Òݺö÷[t—4–¯®hûF÷Ë­WejñÖðŸ…u€°ÑaëŠHn†ñD!uHw,UœIOÍ΄2®Ú¯((Ú9a›³.ÎG.’Û# y]-T ¤hQræ[h…&ï_ÈØ*NöŸs¸[º7á´²pcTL|„sþEUÚòÜF¾´¿AúfsÒB¨ðôy˜à$%&á+>€…à—NœëÁµš­É^¿ÎÀ©S‡Z²9‹Y-8ª[pt‹¤¡¹¥ùwúÏÔ°øå`>5;9 2¸bEQà±Áñ¤òÏ¥V Qªxˆå‚ ÃJ„rÈ(NÍáð›ßø[{.mÚ´gõÂ…«OŸn¼tK˜±„®:v¬¤*7·Ägûö`Ÿ‘¬3ÜáïìnÞ²Ùé“ó®=ÕtàâíΕÕÇ׿å{:nöŽ-ð¼6[Æ?µDäWédüÁǹ§ÑÑ-Ä×ÏGã_+d@š:¸TˆŽ!8qñÜm1ñQñÆ…)óË×£¥`1[ûÒ"¡ÞÔ`»Ž‡‚ØÔ\2èþ6´4ƒ§PÄáßæd¤B—¯ñõ";ˆÉ€ô;1µaÓ¹E·×–W™¦É»÷Ú¯7Åx‰ì·í‘Ëéõ74û' ŠA‘›–ˆ³ˆ¤€Ì„å0~ÉS4S àbÒƒ*jpZa–`ñHhXL_ÁW®k,¿0X‘ ÏdÿÁã˜Îë\÷hZwV…%C&pš¼âŠ"²Tjyч{}ó‘¹d•›‘—%Ôóš]´8¹RýÔXgÁ^77p‹ÀKm›ìK˜+VÊ,Ä¢ !ʉˋEÉj+Â¬Žˆ ƒ ëð:$à *ß$[𲎷½{a/u¿&é3U%gqW‹óZq>õ:¨ÕOc9£zêŒÂÑl.4¸ÐBŠÈh2Júª¦pÍF€K]œ+X‘¦³ˆ ÖZâVG«Ã€ )¼ÂnkXDBTbH<qŠ‚Ð¢ú矢‰n÷Áí»ü=Ýjä{…tÈPg$sXÞ*i6L15̦FôXp½§Š-KèîƒMñN ßèYéî$÷ðØSë[ ¢®N …úÒ_#¹h˜djpx9Ï(TdvÂ;bqáäë?—Yņ%Äp!¡¡2 Òó8‹H!S'9­ÇƒF^x‘ÇUcq1!fãÉp²œ¬zN†¡ š=Åá¸\ .$“Ÿ·ûâ›8NÿË­›­o‘ñäÍå¤ïú]zÙƒ)>à›÷W_€O¹[‹>'RÒé–enJMçfùqÙ‰)uu×! ¸/N;;ˆà©pñ p÷•«œUk^œìWrjï ö—3}²jíÊ)â.˜Ÿã{2--#4\y°Fî pŸöäˆÃ¾ùþ± {×·^²­¥MC‡ŒÎÐG#©iEy³éLä£ÃAEñä–['`aìØžà}Ô<;dîôœÍÃìÞØLWÁ›õƒø¤ð ޼ßÎñ(Ççæä¹”úÞ|ÎÔYžm[¯Ç$½ìßXk°æ]`{¬c€±¿ÅJ_íFJY·Øhw‘”HCÀ¿^(†Ô´ÌìªúÃÅ“ýqïø¢åï/ùø=ÑVdzŸOKËÌ ~Öø*<£wϺ¿Ípð/ÐTýûÙüŸI_ÁûÆœ­³<÷/T¶mÐÓDÛP>ŽüáÞCØ…‘iñô'B8¿â Ê MQm“ó§(>‡“ÄA½ Qh¶è”ü|û#;½˜2ÃØêàÈ¡ 9Ì/‡ÝMA:UzRº*HJú£Î8ÝtR†ªˆ6ƒ–˧ÿy÷ÜG gÚ®YLmÒu’cú ´,Nòd!YéJ|€˜pJpk(*ʩҰ߯E´7''C>g @¾fã C 8WwJƒ!`_”Twø™¬Ãmcz{=–уì `;¿ÈîxóÙæSÿºsaˆ5vÛ‰ÿò࿪:Þ¸{ïÞ!ýHÿ÷æÎ`͉Mÿò¥ˆZ¸b5,à&<žŽƒÑòû‡O¸½üÒB-7—Ôó³l›õº‹W¾ûþÂÊUËl×ί݂4¼ú m~‡{ VòQdм7'B48« SÓÒÒ¡ˆ+ÑøÊƒB=Ý‹—àJæé 6Óøb1ÕO"¦ãfÑ€³§!p¶èøaŽŒIåç¬ÿüÖƒëÍ7Ä£Pí_Té–»â@•¤‚xˆO ƒhÎ~ÝšY‚‘ÆÐ¶‡Ê fç2rÉìïüF)–rNdzF’¼ú’ìÙë—=^ÝnƇ¯s VÄÄ%*ciË4’oéOŸ¢ÙgžõNξޮÞE.M‚E³Ö°]ÓÉ»« a|NF^&í;eÁ¹aB4$&)£É=²Ë*:.<†ªºðÌÈìXü–8YåG§$Ñz/,É-¡„^Ï ‡ÐÖÊ7´Þk•0Ø›ìð)Ÿ»—ÒøPŠäV¹‡Òø^cãxA&ñùôŽ›‘àÿ`#ÜèFÈ{[³†&'+Ýh äÅäDeoщv»Du4paÁþ´ÛÑë±xˆØZzˆŒ5šhí_Q(dAŠ:?‹ëÐÅø›Î²¥íÄÓ©_ýn,èCÇÃÉ ÏÔ6ÖÀY®Qþ€Ø‘‘›m׺—+´Ýü˜Ÿ^Q}2ã pϺ{ˆàEƾÓ`·ÂÕf§ï£aÎ&‹ø¿Kç8ÝÖÒƒäXów͸”ê­1†>1Ù»Ø ¸÷—Ï$æ¤_ëœ[M?Á…×ÃÈ2‚ "ÃÈGäC´ Öhóèþ…šjoˆC!¢¢\Ü"]#Ìdp¾õìù¯b5*[Å­ ×ù­;/ß¹âü‘ãÇ>™3ÇaÍcúM‡ú»’*ƒ›)ê wùèJµx…¡ЮµR‚?Ä©"ã⢨Äô¬„"á9[\Né-œÅ²ßÌñ]¶l´¹s%Ör(Ÿ³E•P+B^|vDZ\J(¨9‹ ¼š½FôæÄÊØ©0PgìßéQ¡ßbd°”4p0ûM©›£»íq ‹ë¼ù«¥ÇÎB wsÕ=b*@Vé žÆ†&Vµ+YÙ 6LNßZII,š_n»#‚~˵9%œ-Éå‰ Q`¿©]ä°y÷êbW÷>¤Ç/.›‚»[nP­«JU¸Ü­z›f#µ—'fý|Ò¿8¹oÛíõƒH1šCåûÖ?Gà¦Ìü'à[~o/ÃùmùsRB“Ãjk­¦£Á+u’{z,Ö›^6 ßekXÚ® `_¡#‹Ã¢ ÎÄ3q±‰´ý$oPþ$EófbM8Òç2˜wÄn×Y>Ñã0ýqýV½ì':Þ³g3ƒØÙèÛº}`°Œh¤²v ÀaRGkØ¥%Âã®ÛaŽÕ+ÛQµžíä]­F¸)­‹ËvÚû° c´»Öv¤ÌÍø+y®ÇôÕ¦øVó8‚}íž#Ð S^³çàK÷¶+ÝzarOÿÝÀ9xºé$ôXI[Ê:tâËË ®Ö"éÇ*äÔ2*Ä#l1Û¼u=ps> €oõë±®ø&94=¢²+(vŒBB ÄG*\]jwì¤iî?†¼AlÉÊßh%õ/À‘ZMAueƒ©·§ødØ íº#ô„™v%az赎1zcf×Ûpue"ݨ–-¬èvƶç¹{í“ÙwgÇ 1°¼*SÓRÓ ð•æYùÙÖ§mw?ý®Û¬¶fS¬Á?xœ„öæûµt?ÊŸÓÛyxVÑ’ ΤÄKJ¥ÆÈidÇw¾ËX@|uö”}µ&­ÙÇØ‡Ê€óWåv»ó¾?x‰ªÔ„ô¤d®;6=ÆÑð,£^5³ùUÝ^¿Û#´Û•{zÎ ý»ª-EKP hœÔˆ¯ÑzJ…’Öf¬ ž5˜óÎÑ^q^\ur:æªÒ£Êå nmgúµP/¶+¥î];ßëDP ¸‹_µ4gÛUbŸžéŸç”›“› yŸ™™Ÿ’þ ¦çžãÔí¾ìkVJëÑ”S?ÖRx'(£}»Ý}܌Ը5†|Ä^EŠpö`±¢])ï9û½Ðrƒ·šÅ•í‰y.…I•`]››r@4¤WôˆÄ‘=ªh÷Nb»˜ªYU2.Æ9ãH`5m?v>ä(9¢õA;\YZ…GâHgŒé ×FœŽ8à<´À9'ò.ÕåÞƒÛÐ]`Ÿ»À*°ƒ%‘ë"×úNƒ±¼R‡–”JT4sPeä_än>züxá#"‰/hWö"ä{ðíÉ”f¿³?]¶~ýŽe©'ÔöM]daù@¶úz^†S(Dn°ß[½e³Ã'SÄÅ,Ú»óŸ5–èà0÷í÷¨²%K{‡³G¬÷ëMtce§ï°%P õÞ¥;é€íYâ^äY¶¸+埨7ruåê$O.Fµ'ÔNœà dF—EÔøk•9]£œåÙkXxÍéšì16a_÷uÌà6ìX=Wð†Í©»ªvV%I*N*J*vÎȧ"±2~”©¥#az~Vý!O]ØUà»ñ°M„«ÎG"òùdÌ+ædÏæïÌuj€“ÖgšN]°/¼î‘§é&%«NR¢cFhŒ§cú\JJ¦ æ¾+ÂG'l¿öãdS“žøç'v°RÖz´ê&$«×pì¬[LŒ›¸HúêÎ9´nWn¾‚&.üodk¤§ÛzŒ42í£'¾È¬í† ë—Ÿý·€?Ôyåu«~aÉÀï<}úà{(XÄh ût’bƒ¢sï¢2>3¶ó-4ˆóÉ¥ðõÁÄî°Nb㊢'¬­þ¶r? X{Q¶S!Ô€uÕ{YœÅ,ÝËÑ”‡äÔö_à{æ.ÛιëÏRô¨}Úö8M&½Íöú €C^¾ÃÇgǤ !&5*%ïÿù¡UZTfh)pš‚¢b2²Ó_½SIÓpþåH¾#îF"àIŽ&“zÛv’žÅ¤î/“þ‡q:{NÕ=ÕYž×ïhC;½,Ð`RÏ—zœJ:\ui/턨´˜=¤××Ý'cvŒ…EžÚ°r¡ª³Ô©Vk’óÕyÆIûŸg=–ˆ²“di"¸ &rË®,.È¡%ãd‰«ø÷¤´Nw‡8‡:ç0;Ç}Ehú¶ǦrFƒ´ˆ:4ïéz™ç¬x\Þ‰¶E= ìx{:´uj*YÓáG£ëiaHžüˆ28íç‘¢L±B\=8²Éì¦ôÒÅsWn]\4câÒåKç¹<#-ãzI•ò*ÇZ˸ðÂù˸í²eÍÅ`=Úë^üä†ìß‘¨Ä%üº'Ï]8vìì§G¶®_³}ûqª Ÿ¢:àßÜ÷7oPþ«® ­Öæ–§æ©Ó}Êb³+*Ë­) ®['FÂæ¤m®a9.%Û€{{ÉJq;ŠÜ ‚9a"âÀ\òåY àCˆäf¾XEGê!/Z¾ 1äôƪðŒ¥S[ÊÆ@8Ä$+èÀ‘™Ÿ¤dHMÎOÍæ°¹Â_pô˜ÅYõõšŠÂ,¸ \šÃÌí vŒïÐÏP06={š™ðÿlãѹÂGààÌáª× Z¹½×”1ÍïJÛq)ûôÖ3çò½?HÐîÎ…¾ÝkÛ™·»O-Ñéé2=m4-†á]”1ªW"ÌI ЫǞêIÌ(VöÌ zÍÿ¼`%Wºõ©6fÜü…ÁìÕæÓØW9Ç¡ío³ N¾.>N´Ú½ "Y‘¬N¡±Ëàªý‹ýB½>øãØýØÿ*W ¿¾æ}ìGhBUÐ!Ìäq JÍzÉÝɽ„KÞ%“ÌñEgP—÷ðaS»rs/vì¥ý7ße¿ºEùNç<Ùa|ßží=Ø¿jòÏÿêkGІR1Î÷:¿×«B†veÃ^gy®ûewQbË«jƒ 8÷ž^CZ¤Î]}ØiB xñC©¬©íðÉÃeù¡Ë¢”w§ýö_ýŸKâ©Fvšà ŽáÞ»û:F~Ù]wðTúp¯ì쀪ìKʺCøz(ØõWŠjù_À);þÿOT° û²«ºXø‚+h…8£•…“¡ã°Ùä7É`"ûqš É?¡¥@v’™üB»Û¿»víú«Ë§L¶[°P´ r¾c¬4ûîžq—ÊË"þo„OÆ™½¦KtõÙ“U¾Ó_K±úò–í~é­Žñ¾ŒZno°á;ÒP'Á§Æ±r eq³±,þÃ4¿€Ú2ޏoÞïEv"¿fóìÙ —·>ú¾UÿÕíãóm…W‰Á·õ¸ìì8ÊiýáÒO8@PûUWª)¬ÒD™%n„!ö+9Ù—û:K€˜ô þ.i™Ó«ò{Õ)Û™Ë:ŒÐyèdÏð ­5ÿÔ yšWꇹp«¬¯ûQøò=S|Õ¡É¡u]ŠRß-(”ªØíÚíL½~ß¶³ï¼ý^IeSÌWá°žÛ³ÇmаÖæÈïÄ'äøv©Û â6 Õ¹MÎçTÕ4;Óê¿>%ÊžÁo„׺§u@ä ݯ‰1Óh!ÊhV¯:›u}õýaöŒžæó$²¿p¾yëîѶbк¸%† Ivk¢ü›g+ºúuK7ìƒñz^í®…bàz·kZÔo×®ñSçD¸Ï…½õ–ýÊI;QïwS†ÃÙÕœEÂY¼­“”|L ‹¨µ½\èÓ“œj–HÈm"ÁÛæÕYñŠêjY”’ǹ®t¦ë(ƒœ½ts-.Ô£©NRhˆ45l3îo”´~")âGw/ƒ±‰ÝDΘ'± •á'"‡\IÌq(š·È€ÄØ]DH¢ðxf^Ù­8IŸž ‡XìKÞ$ƒÈLó]=W±O÷ í!~‹ÛÈ@sï€nïÓóŽ]lWß’}ð„}1q ßëa J¢µ±%“1Öªâõ9¨cqy™*H²•|v¸ÜËÞY¥HuZ&äq!ÅrŸÐßûv5 Oá8Z¥æt¤I‡;>3½äµÚ‹¸},dzԶžYª“¥äi JJ„Pk×R( ÙÒtÐ@w±ç³›)•ÒAO»ûUp(%³øÀÃäàÒ5éåuF<," ž›À››*gP8‡9+6%ш Šóó,OÊ+“P’˜¼Ž#s¤T-9œõ:â>öpu5ru´HF¤À~¨ãp¦*Ûש(Ø«®àþfÇ%ªáø†š-•+S]€ ¥%â[’@s(¨è«Ý8B7ØUà~Ô­»j+$pd™”jg2VÕaG‰àGMÁ]u:œ†jî‘”¾¸`áþ‚SêòNÇjýÔQ¢Ÿš˜$«š9 Cö_~Íòþ*ûÆ`kø'_¨( "!.>6ÎÓÛ7LI1“žž¤uðó Rx@VV(ä@zZFzmuea>dÓ1>/"/\¸ª º°¬HSPS Åt¦Ï1,ÎÂrX’!ÕõÕ÷Óõï¯ï?@èkâÝ¿¡tÈÿô^L‘ endstream endobj 322 0 obj [425 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 272] endobj 323 0 obj <> stream xÚcd`aa`ddäóö Óvöõõ44‰Øäüîû5íg놲Œ?ä˜~È3ÿg‘{èÅòŸ‡I–á§ ˆüÂ"ß €Hu ÁX)ÄÀÊÈÈÂ]YßW’Xj``¬g``äœ_PY”™žQ¢ ‘¬©`hii®£`d``©à˜›Z”™œ˜§à›X’‘š›Xää(ç'g¦–T*hØd””Xéë———ë%æëå¥Ûiê(”g–d(¥§•¥¦(¸åç•(ø%æ¦*@ܯ¡œós JKR‹|óSR‹ò€Nc’a°Rí ü Ì@'ÆTýèàûaÛ°àóAÆïºg˜¿oþÁ+úÝŠmÆšîÕ +º+å/g+éÎìŽ*ÌËënåhÐ9QnRwOß„‰ûïîï^ÒÍqMù÷ë¶šîÎîɆIµóåVuOXÖ7‹ƒïûâî7ŒÞ0÷Ù-º¢x~q^yqqÞâòÅ+æ/^,ÇW¶à‡óÔiÓ¾,`û0•]Ž‹Å|>ç$®î…\g¸NâáùþPî‘’” endstream endobj 324 0 obj [571 437 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 278 778 0 778 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 803 0 0 0 759 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 520 0 0 0 0 345 412 0 0 0 600 0 0 0 451 0 0 572 485 716 572 490] endobj 325 0 obj <> stream xÚu–{pSeÆOH©_i-ºkÖâ®çDF„¢0(£«ŒJÁr«–R[Jè-IÛÜš6—¶¹5I“¼¹6÷6išÞÒ¦WèBK»B¥âR\]fUÄÜÝÙa™eΩ§ëî)W]ýçÍœ“ï|ßï<ïó=ßaa))‹ÅÊ|5wó˹۟ڔ››³.{ñÎÆ*ÚùÍмa)õ0Fá,ŠXBqÙÔƒ)ø¥-)ÿÉXò0†±ÖÞ¿X—-g*ö¯ûë“LIÏù–Êb¥¦Ý§1zk•5<9¯.;ûÙ5ÙÙÏlKT2A%_Î]YºŠ»nÆõ«¹Ïdgoà¾TS.”òDÜ\žœ_Î<Â\TsóÄ¥‚r¹Š»r#_.—<·v­B¡Xë©]#–U¾°j5W!ó¹»ÊkËeõåeÜWÅ"9w¯¦œ{û-ÖÜþÙ$®‘ÔÉËeÜ\qY¹L´HükÖsK^À¶a»°2LÀa2¬ŽQ¡…eÁ–c÷bc¶{{Û‚mŶcyX>¶+Àö`…Ø/—`,,`G±‹¬ÇXrÖ»K$ì”Ҿô±¥_¤Šîyâž^¤LËN»NY2©?èâä·ï²¼G&β©6*…áîzP´2•~ŠfÓèôgO½r…\F® ï%×éê D‹éo9…¥£0üóÈ©CçgÃÀ>÷æTP¤Ø ((Ûñ¦´ P&•£í¤°wYä3=¹1õÎ J‚JU@” +Åo ÙÀĽàpy¼¿ÿd:}–ºŠþ¨Ekª‡–ºÖ†8> e’p“ué&›|ã8§¿¶[$ª­‰ºkûû»»ûqæ_úÍNò·7YdNœM–Ø9çdË„ ™X“áA¹ü>§Ãn·²ÛmM¼Äß.êt` 2º[Ü‹Ÿixæ|´¬“ޱ>£HöüzÊÌ zZÝ@ƒO‡[˜ÑãÂÛt8Kgn6ƒ´^sÀL-ÞàðùŒn­g!NÚ³~4!©äÜ^7!ØìÖ¹Þ&ÃYšV†Î`Ð`p›ÂF*NÛ³˜Òd4›À°Bç3p'8 ÔŠ2ç' 9ÏJ²æ-ÔÇÿx4yщÜA{‡üBÈ·|aÆ£&-(t~ð3¶@=ÔÅÚh³Ð) ;³h)ÕѵÙå°‚~(Ua`Æù Ã} ýа¾T]õœe…IgS2²x‰ÁçÐðèPÆ£îÄü»ŽØéhŽC Zíng€Ì¢z²\&°ºõ¤cáRV«ÚiõAÀéŽ2¨P‡$yð,ဈX£VŸ 4Ðb³X´‹èYú2kóF@ªÅaAp‰9g"q!‘ñ¨7±€”bˆàq¸ížsd4‹LO½ÍãÐØ\m’ņ P #3 ôÅÈõpP6ÜV£Õ({iŸZHhŒ$ éyÛ5è;: ŸlNJüŒá#º8õtœ¬8Ä¿À¦Bó/rû7ÂjƒÚÚl3™Aƒ´>h›võ¸E±Ö«ÆD}{™¤Ñ÷ÑOÒO<}"çS"G]³¼¼á4Œ@WWû`d4tÈo ®[‹¥I½Eµc? ‰¥7F@·£ÕA[ó ¬ê’7ö7ˆíi:Á`$—wIžšô~xƒ‰“Õd33[éï·iõëâìáY696¿”kj—K$R‰2¬îîèÀ_\ÈàûÁáïóÆÜaè@“Uc{ž.§7èýàÀý`w¸Ûû¾`2À*êõ-úfé^5ìÓK5B¨GEÃüé¯ÇÈÇ}wÞ,æFÕëÂm€ÔF=žp×iFÀµ4/îÿ’rÞ¢Ò\%EgØÔ# VGS¤V^#¯Q„ºúúzûpºøßë9ÊßÚ•&h•o µ­b¨]×!‘‰ê+KÇë¦ñ9¸v¼çW©%YîÓ%'šáìy|×]vØíÞŽžÓGNŸ޶ð[t-j†ã¶4,ò›Ù¶³ì˧8–F“ÌH6´11õ¶ÆìŽà”§'þ—,OÜww¹"Þ~»«-yüÊ_Mú*„äÒ4ì3ÈmZС¢þ£ÀÞï) xM˜Wø¾n_¼ãø!r Ì öoÂ×AáVµÜ|r²ŠAY¦W5šv@ º+¼Ý\ˆMŠ4Ì‚õf7¿[×Ižþ*ÄàÿíÚOÃ;\Ãäo\QïPtÎÓç %¦ºãÞÖþÞÃÐ mZ;Ô˜ëjAŠʾ¾D×èHÕ@¾J •âæÉÊÁ¢[4•J ÙÎÄæÿÓDÂÍåÿ£9GJìl€ñØ“œÀþéáŸ5vSžò5 z}hˆ€xpÊ;’ ±,g›ÿ€«ÍÝå?mò5âfښʗKèMÚ|[Kéó/Ú­Ÿ#àdâO½çƒß™uuÅÍÚóå±€|í6Ƭµ:‘©±be}.¢Õçeïàç`t2g¸•w¸Ygý³äƒ_³)>…8ïHÛU²Zi·) ëT„¤P‰xÛhV 9†Ãɾ?&?küìVé¿~¸«ÿîV‘é%FU 4ۉœË GÈ3äçǘ¨äîòïûfÿy–ÜÁì'¯rÜqÿØ] ´ j6*,Æ":Ï(5ÖXU æ(³›åù5ÕÌü<|!`Ð}pŠ\ð„™í1)+ü±}×&Gîê!Ó‰êz™¶ÊQöüñLÁø\ïÖó¦ø&ÎôÎ:H>Ó脤M-“ÝÃcò5t=Rx ¢UÒi>ŸÏX»H20C@¢5é £[ß¡¯HÞ¢3û¯’\e“_’'8žÞ®«sà†nèÔˆÍ ÔÞ2^|0:~lGX€ï~¾V.;÷¦_è±]4G¶ÈNxÁépø†ožëa‚§cİ“€jõæ šÛËç•0¡ ‡úP;Þ ÔWçm¬‘I«Š*&<çô+FËfݘ!9=‹î#˜„o±…Ü×j«•5 3îóÄ ·† ¥C—}ÏÆ”šºŸã 3gqëíVè¡Ádh´š›«[TL/$&É^zsVKã¾Wrè&[‰¼7|¹ýw®Àb~–?ÈP™^jT–>¢ÚEè™35§ðƒ0I$4»µ…¥ùRA¹¨š`¯S}°Bú}þ㷤ĥ—  ÷LT¼‡ß€WäR”Y§6!²&žJó÷àËRÖÇ2ÒZ3–Ù3Ò“Ë>Lïñdd—ø/Sˆœ endstream endobj 326 0 obj [358 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 743 704 716 0 678 0 774 743 0 525 0 0 897 743 0 678 0 729 562 716 743 0 0 0 0 0 0 0 0 0 0 0 511 460 460 511 460 307 460 511 307 307 460 256 818 562 511 511 0 422 409 332 537 0 0 464 486 409] endobj 327 0 obj <> stream xÚ­X XSgº>16•Ò ÆÚ;9H«­ZífmÇVÇZªVEµìÈ‘-’=_²‘„°„@Ø(¸‚ `-—vj¯¶ÅvfÚÚ{gë2èá>÷þœÛvÚ{ë3óä!<äáœó~ßû½ßûþa3g,+x×öM/Çn|lÃÖ˜M«V>ùUcüÖ?^yÿ!Âÿo,ÿ/føylÿ3yožùßA3~A¬¨y÷÷áwâ‹ûï ñÛƒ¯…3Y,²¤V®|rÅÊ•OlÈç—d¦g…/IY¾jÍšÕËŸX¹rMøúÜ´‚Ì”¤¼ð­IEi¹IEøœðù)™iE¥áK~•QTÄîñÇÁФÜÂùé/,].È,Êß‘V˜VP’–þr~^Qø¶¤Ü´ð)ì+¦~mÈÏ奄oÍOM+ÈÃ8ç.'ÖÏØHD²6[YÛ‰ì¤û ØÂLD‹ˆÅÄb)ñ±‚xœXEÿ03ƒO(ö/÷±Ð£Ÿ°ÇÆ×rõUz3î´Ag•ñ´ ‚Jé«ë©Ä«Ñµq@2ÉL6SÌH˜gÿ¶ñP,b¡¬ÓÕ2PÑJP€F¾‡YËÌÛò,«Ÿ<"h¸èE«n¢£Ÿ}Öÿ>ß~ì)ª²ACʪÁijƒQ_UG?‡ûô¦uu³Æ7÷°Ç_D®Þ`´ž´K@Ó‚NWYÍð263ObÁß-é*j£>áŒZD|ºryhµJüI5˜O0TÕ¿Žø”Þh°‚tH@Í«Ð(K„/ ‹Ÿò9ÎÒY»,ú.Có8ˆðæ¾D_[¡)Ô©t•;Ù¡ŠWú*C}ÚH[”PäD:§L¥pƒ¼’(Ôå̃]Ô©ñrÜ ×[\¸Ôšbûü¿œîø+(kn2TŸÒi‡z«ÚTIçdj²ãƒ"ä ÚÁE[9N¨Ó9u«Ä ­<¿ø ­47?15F’ä²5o¡0†›Ñ“ öÿÝ臘~ÉOµ“ø¼ÛßÞc+ô¤ÛÁ³ÑNNií¢uûXÇ}ìq‘ßϵvZ­—€l´A½]aPÐiÉšÔ”äÔ eÅ?Œð6FK1­œ7‘rꪰŸuÕäà··¸º÷˜ñÈÑcG‚",a*@ V U`¨ªyy)ÔÊÙĸ§® ûÿ®Òƒ¥ “ä÷{®üÑ/ö±nÉöwcÉZÚ,Ö> ]vh°)r:+]“¿?!(¢R2ͱƒS˜@­'@Qy€" ˜œ8@ ×íØÉá•3è ¸‡d¯§ÛÛ"p–h¶Ã ‘çR.Ó·á³÷<Ÿ’ÁßÎß8ËÇzëÛ_±¿÷ý¦â¥SF3ó9ŸÒRæó‰‹ÔNÿ°Ö£…BcÂ~tSÌŸpPâi’x-)—êJ+Í ÝÑmôuòMm2‡B/¡w´-à#˜«jQ˜¿ÒsF&¾4”ÂaN0YÌvÿìqþ˜Y8q釭ì9bìí=Öó­ LJ ¢É1)òÀ­½|ÞØ®'}ÝÔ°gi²³3s‚"T˜p©Mg£µVX¥V¡•33&¶PL”¿NY«Ó—à:çý½NË9D§ÕÈj¢•Ǩxíç×Éõ;(”=qÛT®×Ö@–¸ÞÔ0½Šz[Ð%k|ÁïØèmt•‹ç ôÐ_Ñì±H¼–ifè'×òÝL'‰{ÝwÇ >æ\8¸…AùÒ´„ŒÔ8ab¶ÜbF4äAƒ>–¿±ºÿÀö/Ld‡Õ`Á¯Nhòòa9 JõŠ]»róâŠ0‚Å%梈ãŸÀ»ä¯2óxLÝÏÇíîÈOྂj)DpŽŠ6Ð ÖTŠwJ÷«Å $×d_ëøÆjÑš+ðŽÕ©4’²¹Ù9@æjZ;ih16[ŒM¦“Ðç3Žï©ÇJ»€Ýge íE £ìñ9?0 U`óKãwR©o¿¤à–ÜǰðÏ,b=»‡ùfGéRŸSƒåVM]©]l/†tråÚGžX·îðW?Ó×ö°ýgüh’0«Þjh…: ¿jo¥ïÙv­g-Y¸Ø £±¾EâcÏtÞ™¨ÆyGÊÒíL$…eøwi ”TaBŒFƒA¯¯n9…¶5".Ýœ&œD°j+µJlGÝTeF¥ Û¦ˆS&L3&z`È80xn (Âæ·]åt9G9 äUUPƒ5P¬^LÏتâßûqõæfir²³~J½O0~*›á.\¹ÈؘîOið˜:Mž?ûSwãM, äÙP 2’ ‹¼ÍC¡€ÙYЊfà ²J=þ‡ÜZO"FÑ‹#¡ï£¿^àÚ÷ö”‚hôº|õ½Ža̵˜NY,Þ)|5ȃÐZCã}\kiÅNQU0‘e&/™:Ú'<‘]›çŽÍÌa–1‹Ÿéßøúþa8Ùxô yY¸û™hyöÖçb l¿üB g}hvýqïHÿÙc@žôÆ&Ñ Õ©´JŒ4#]îAŽ³Ð¬7ÿm6:?¾Š;L¶ÂÓ€L§Ñ-‘ST‡%­†šÓ…Œ Ô’ šÒidÉF®>ù.š‰f£GÑ#‹:ÅKƒÌ’ÌlR3Ì-Èj|†“¶CíˆciƒËÝ~´·»ȾêÙ4$ñ™¹y[$‰÷À*Ô{£ÏÃB3®¡¤[l¤ÿ^nœ;––ÙEM­ÍžÞ3‰=[˜û.Á,^raÓïÐüþì2Éírž7T.[¿ü u» ú†ijýºåôá+gõaCìÓº’§Iš.}’%¶ÿÜÝ•ÍTPå>~kÒ¸˜bâ®èv™›ÉíÍ\yζçc€üG֬Ф«Ï¯Uç4:õî߃žÇmâ\Eª^6’#·Þ6žn¸Ñ WÀBö8²%‚yx1³qÕég¾ø‰m–þæ ½Õ}–VÒìáž@Ï~i¬òh?s!³²è`tIò4Üô }hù¿7zXcèâuøq?äÔUOµœšßë]׬=ö¡Ãr£Ö)ÊU‰ A@×Ëj½^÷¡ÉMɼ¥PÀ,Pd–03¨Mí/À}uÑ9¿ž˜-Ù*KV–„É3+bÓAB£ÔÕaªi7é)­2âO”ôð¾‚cè€åp ˜ãýÛ°ËmhŒ?ú5útˆ[²Z§,ÉÏ KÙŸ‚£Oäßî¶:¡ŽtV6,ͧ¦ô”Žñ¾†ëo5\G,ÿfªÊ…ÅV5%6 ÉÕydèâv~["&x&3‹YÂ,|æT$Û×pâ˜ÃA^A5Üxf³<{ÛZ,¶]ÚëvNw Ù§¼çNöòMÛj9ý½Q»u¾~ä®EÆ,™ø„ÒiqòÇ[ÖVÞÀkgÑ^åêD ,m&¹Ñä±Öê;Ý'.]Ã"7ėа5™+N©ÈÔTB ™Ð–~úón´Ô49…ø¸MGÎç/²DçÂSè­n±6»‡Ž¡™0L~ãÙË{22rrILÿþ°BÐüó§^Oú0ÔÆÐÃÜïÞ*ÿ¾•\¬oÅ®êìrö\F/RÕí¸Æòõ4ïå™ÌR•lÊQôx“ÛºZ>ÒnWÑP(ÍSsŸ¥*²$ø%NSã© S›“ow¡G«x¡¿Wù‹¸^U\Âä¸å5vÞÔ\Únúí“Ø2ÆPÆ›û? @WÑ;¸½UµPCžÊ=±sÉnæÅô£Ao®õ^:zû©×P\JƒH#T‹–MÌ£*v§®Ý ¥ ¶jõ‡ìÆN¼wïLÊž’“¼ëpóJã-2ôKôàøn[±YRPXXXQ-hnöz¼¼)=æµ^ûÀ9Åô©ËnýóLw€¥Í`@ Têr Dã3­Z#ƲU`ëÙpª ‡w<]öOoÍ¿»b*ö#€äk›Ü44YÚô&S#ŽÀNÝØúª­©¦±±Õ7xáHÿYœÖ,R½.I¡Ê9Ya¶xÚê{[J»ãy»!1)3eÇ&‘(£ ÏžãqîqÖí7ï¾®yJ§V  œÜ}øÀi^/¸[ÞºC5—ï V>"«TÙFaRþ÷wcðøðä²PúÚ6‚vc •¡ Ü©Ñwžƒ£±ýì‰á«@öÞr|VVäi+73NJ«Ô©p¦’ZËÝ<ÔY, GÑSÔO^÷OHf,Ú½Ÿ·âräWcâ! öfe¾¦8“Ù‘é (å S*¶cbï¨@oòÔ_k8ã²ò¤Ó£¸ŽúÐXú¿Øúýò@_×^ÓÜ÷Þõ•ò×À¾¨ á¿ ºu:vsÇ5¶ßŒ|Ü/¶_}êŽ}/º´õ#t?ÂGô13nnêß;Ø[»ó\ÏÈé¼JÏ´%l§!±xQvT^Ìžø½œ`evûвÉ{û£Þfÿ™-T®IÕ‘3°Â¤²Ð­íƶÎîÀ‘Ë ˆ÷€¹š³¥¥ªö0ZLYʼÉlÍBsÑ´4[轘ž—)Žwü¼ê• Rä“ЏÖî‹7^ÿÑP-»e¥qÇ’ÁÀ×HÑÕ. {)öQ;:†µÔ‡¸ã€Ýnq†T“øK±ÞWsdp³=‹÷2¤Ç‰Š¥C© Yÿ%x´O"X&õ¼q­=ë ¹~Kq…¼±ÿÝÐo 8îIYŸ v‘ÙüçñŠ!Ú$0Áq,ô† gIQ~Yü¶áôß G{Qp?>Y[Ÿl#C¿É7§[áÙÜ8z“× =2{j¶ZÎÇ;Jj.k®kqœèO>²‰™üX,/ô[xኸ Gt F˜mpãöã¥âÄâ§ÎŽ™Â‡ úyNZ2Ã&]¹d%êòTæIꙩƒCà[Ž›œ ÌQZ-qX\WÊà_@'/-Ý—²nÞƒà­NÖ¸ü®é‰||­ÂɯÚÿ×`Ö›ð.²Ë]^.àý!ÿ5ÓG©JA[Y!ÌÏËÅ»4¾òd #]ðŽZM5ØÙÎfùWd0K”ßq6«¯õ‹IgÓÄÎ&ã‹Sn<¸bɧ†óÎñ† »£¹£~× eÃ]0ä©§æ&:x³ÆÃCgÇØþ<ÿ£ÜÝßGe Ú‘Ç‹¬½2añ›{­@>²‹y (€Ž˜Ÿ©¶õãÁ#Glo(JÁè${+H“ujék¢Í%ÏGáÃM!”ÕtXm^p‘-%抂‚’¬ÔãEý¼ÓÐÕ[×áÞqFÚä—èAw0¬ñŸŽKÅ1XÀw ÒÐl?aí¶w]´vÕ ¶¾~ ŸÜ¼P+Æ%”2I®¡›ýÿ"·Ôò§[y#®ó¡ß ñn³f}BûĽ&ϲޢ÷™­PK6Šì¥’TåÎØc™¯ãà÷é—Þ?ýÑÏ£ôfÃ?°uŠ ýE^JÔö S¡ßôƒ¯ÙéœTËeœ1ûeÖEÿb6Gǹ†O_[€6åm’¬*N²ja‹¤¶¬ ÒÖ'.TZ´VÚhrX=íÞpC½Ü#ë*·ƒ ÊË*¥"ó,³šÚ³o=ŒÌ6ù%1Æg©ilíëX¥õµ—kû?Ï¡ÍÕÐ:¯QW”ÆíËLˆ,[®SR%ÈA¥³X½mxlŠ=þ vTh¨õp˜$û,ߜѹ[PoÎÌÕî Ùh|þÿ+” ¸ endstream endobj 328 0 obj [525 525 0 0 0 525 525 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 525 0 0 0 0 525 0 525 0 0 0 525 525 0 0 0 0 0 0 0 0 0 0 0 525 525 525 525 525 525 525 525 525 0 525 525 525 525 525 525 0 525 525 525 525 525 525 525 525] endobj 329 0 obj <> stream xÚ•W PS×½!äz?mZRÛ\ÔWµŠ€ZµZkUüUQ«X­UTˆá#$>!Ÿ„ð $ @DüUíëÔNEEm«­ýh­[k§öÜ÷oæÝlâ_§fî›söY{íµ×>á¾¾‡Ã¹veäºMSÂWEF¬_?-ÌõîL¬`þó¯3†`^â0/û0".ó‚¯è^“$Àçe‚à,åzrG°OâÁH×óeö1òÙÑ„/‡Ce)KÂÂf„„…M—¤î‘&Æ'È‚&ż4mΜÙÁAÓÃÂæ-L‰“&ÆD‹ƒVEËâR¢eì‡ä HILbœlOФy 2YêÜÐÐÌÌÌè”Ý!iüüWƒƒ2e AëâvÇI3âbƒ–JIJ ÕÑ)qAÁ‡<þ'\’’š.‹“­’ÄÆIÅ,V¿`Î4ÎÛÄjâb='šJâI‡Ä3ŸMK}NrC¸¾Ó}ÀÛÅ»AÖ{mX5Jö›ìwÌïßÕÿö/ðGE7ž)âûòµ|LÛÐp4Šƒv¢q\Ô®HVoVd«Tº,dRyU™¶ãÈ÷ó‡Hº·nO‹OŠwd´‰ÊÁF=ÅG—8¿3a\&5 ÌÐÙ™y4¾Læ%@BB'˜i>8¾óa=‡ f>èKõ&0P5– Q6)Õ*¹4ja¸J®ËÐB ¥,Ívˆº »vŸ}éÀ¬À`Rž »$-PM##iu@{‹réY¤+¨ÆÉAÏÞAæK\Æm êÖé¯àkêÇ·®`>7û®–ÖgÛ›m M"¨T™Õ¦†Ã¼Ô§Ÿ&- a"ö›•‹kñ†@¹²¸”Ø5"t—Ü µPÚh¨,í‚rª1Ë$) ´[(œ7x®ÂÉa„Ì â‘5Ͱ¿54>HæH!É‚þ•œ; àa)OzƒºI‹ƒ]™Æ®üÇ1êÙ­¤¥y(©±¤"uh}=9o@ÌÓ‘uQ»Ü˜ Âpï/]áÅdNÚ3\ÁÝ1²È/1OO>(6IMyAXFÚÁ¦ý{*Šp"–4&ëÅ ­$Ñ w‘ïƒë?Ç>4ÎòäÐ4xH‚W ϓ֦¡¤äMF!ø¼×¼2&bÍü ô¸'yyԤłšÚ]WlíCuIƒ¹/Ðh#[zWÑÀr7ä‚*^¹,P“ ZÐ<^l´ë æÒvƒ…Bƒ("]"H7»P,ôPEò•ƒ"xÔÇe²çvº¿s!ÄÏ{§²ßWÌ^¾„›v½JC”ÌçУÀ?Û¡ÙÅ bŸþ¥ßˆî ÂzŸâ«œh¶ó“s=TŒz9âà×£1ÞLµ)låÝ%Šì¦(ê·’wä4¨µ™:õ ®È<™Zy*òžè#è5rÔ¦¶Ÿª¹q°v Z Yn¢Öݨ59ñ™i¹; €Úßx€†O¿2žÕ‰x,Õ[û¸¨šé°´²­è¦u‘§_ºÉ×Ôš–ZµpZ ØÀpÒ.mŸ =ƒ‹|ô‡Ñë *--‹úßÄCVr¯Ü^Ô Í`¨ù¥¬ÆññÙî3@?¼1ӦϢ]>sÑŽLßq™,ÄÔÔHEé VäÈâ¶§ojîæÞ¾KçÐ($¢Í°*5z^«*[Ûª] Íøí×pð¸I—§±P„§îÙDžäúXvkݹé¡ä)¹¥â™9u;[×€°Ãðxì{mÑ]ú$³uµéŠu(p7t¿G·±$Þ¤¬Ýzò:â|ÿÝ­þºel}ŠS 7+æ,Y¶Ù}©=çäÜîCm,†í(R°Ï_ —‚;ã@<œu–@Ìûvâ¡ç/Üv¸§ÓASœŸ¶csV4P«æwýLW÷ /]êéê'x}7 y Õ vày'ÅÚÖE† ÑSÀ~d‰M_YR_ÚÙÒ}ŒÛ; (Ë>ó3 !›žÛb”yIÉZeN(5ÞÃÃä{ø<ÏË8P“'æ’÷ô¢…gO÷¢¨^NMÏ¡>¤>ÇE)NA!Ûz…J™¬´lÕu£U¹O~¨Ÿo{†F•½ ¶Åb7VëMR[¡(›moóÞ¼Žu´ ¢‹·¤¤Ù+’€zåµé¡4Ä[“ ê,™b¤€ v[d3£òA:µäæJô"«ó!'—D‰Äh˜`KJç±ó=½ÎöïŠZµvÍjZŒL^ÓÍ©µtij±šá2PwïÂ’ˆWbB\Ó]t >Ä#ø§‹Âeï{YÖtïÒ7¡¥]ææÆ“§Ž9:Zž%¦¡H—«SÅ`Uà6¯]S½wµ£­e‡ô¥P'ülËþe¢°-c§d¨’7mçê9èÔC.3‘¹ h̲K’eiš-ÃÑÚÔÔ*ÂS <Ú+ò‡žâL$?FýîD„ƒ‰àqÿA9¤V+_¡rÛ¨Ãx‡=>CÜ5wyâ~¯ÁS΢½Ã­ð{l— ^&â1Ñí¤Ál´—Ÿ¸{5ðåex­îA›ú‡¿ùþñt¯ =Ò=ø^ôJù¦g¾á‘CYq˜¨3\TàHw-»î>JÚÔÆªÜÑðÉ‘ŽN *ktñ4è4º¢hl|Ú†ªþê+æþ²#P VŠmÕ¢HØS Ì;”T%)$æ§ÊÔÍé *É ¬ZhWßdxúæö_@¹¥8¨CÆ×)ø{šƒ¡ LO­ Éß-5dÂw.¡¶‹\ƈ*Èwþ•©xë†#1©Ë¿G#ù£ñ"œ‡£Ë·9û¿õÕÍO¯_> stream xÚµWipSW–~²lñzHD$HôÌ’4[À@*,!T0acì°†ÍÆK–lËûª]ï§]ò¾É›,y‹ KØ!@ 3À ÝI³$$t`º“éÎÐ÷ynªk®°»«·¤««f~詞Jçžs¾óïœ+¢"#)‘H4fËŠMÛ×$Í\¾!iýÜØð/¯oÀöÿAƒú(a"%¼ ^ŒbáùHÅ£vutÄ‹%š÷/äI¡±á磟„Ÿ“Ècœx)Ñù¥;vlì¼åjMQNÆtmÌ´}Ócæ.Z´`VÌ¼ØØE1ËTi9û’³b6$kÓÓTÉZò¢ŒIRïËHÓÅL[’®ÕjÏ™SPP0;Y•;[s`éôY1Úô˜Ä´Ü´œü´Ô˜•ê,mL|²*-f(ôÙC_ËÕ*Mž6-'fƒ:5-'‹D+™JÍ f‰¨ä±9#(*ŠE¦ÆPs©8j9õµ‚ZI­¢VSk¨µÔ:j=µŠ§6R Ô&*‰z›ÚLm¡¶RÛ¨íÔJA‰¨Hê#‘FÔ+º‘ñ1+~ÉFâ(£$eÄ #xš¢O>óìÈF^5iT zfô×£GÿvLÚØ™cÑO\‚uŒ`MjAoþ Ù…æ7‹så_ £_“þ«õŠÊg¶x3ÐYZ­JÓRÑü\­gà³Ä ¯8ÜÇeJ‰YÍYÁÈY圅 ‡š·„Ű·>¥SR¶N•oÇge+‰Ö_:Y纯1ÐÖ­ñ”½ k ˜|s÷'ã.YHâ>Žhï7(P´n¥2»Ò4®=U´Ê#Õ¸–4Áø«7>÷ÑYøÒ³ºs™ð,‹_8§œ&Y ›-Â’€BxIŒ¾ª¤¿Ÿ[Sé'Èkë¨Ñ;*]øÙ«24ózµ³Î Mò]U¹Â,”éð¤XÙ4wØ\à”{M5EŠ,`Uœ¡Ï•aê«ò*+˜@^\Z\Â@…Ç\mBÏ­•ᙫËLe&(”Wx+j.°A­Mz(KÆó f0ÉõîŠzEؼƒ‚x3û‰èŠ£u Rݼw¦XY«,´ÉivÕ¢ˆß¡±Õpe[š63«°:»OÑõ^·‡o¼$:‚bt±RÜ(ÑmŠB’1ƒK „:ÐG!‘ðä[1êAÿ.E¯KÐôÜcqoÙ<‘ÁßI8ƒµŒÓÓ-’k>c>FVÏæï—™3ÙŠÅ@çIÌʨ>û/`àÐMèžÊ{íµ¼‡Î—¬/wù°ó.òö@è—:»xÏi ïKî\Ö¼Á@™5C—š¿puz,Ðø ©C¥µ E~ÑÅOûob¡½$µd“­zƒª°¼”¸2ú›ðyOÙj\Ý­h<øéW^ðòªµIž¼PWk[@E5¹|¨ï|Uè‹ÁÛÐ7[¬,Ç‚–ËLxÔ˜M/ýuÉIÅ—p↧–^yT×B€¾Ð\}Ë^Ã{\ïÒx±SjV™•iûssÓ‹ÓÞ›8Ìh:*%ÕÎVú…Wühÿ‘w[Œ®•âq:J9Ž“[YKX鋵f ­EÓ¾(kžwØy›Ó=pº9u ýg@#¢ÑTôÌ‚›³˜8غ· €6&Hí`«oìê=8ô‘4“(6Ç$¯ÞŸ¤Ùô‚;N¼—wP*ÛQÏ×ýí¢ëw‘æ‘XxC/ÝÊšS@G‡Ai4½wuyp ~Gãç1ƒ%÷ÞüM8ƒF{=F›YaŽ5U\•xpÐ;6ô! M¼‰žÿŽ©…KlWú_äzý¶XøÙ?HõΔéê3NÄ‘ªŽÇ2<¿ŒG}¾âsÎ_t»uëdHê³AÏór»ÍÑv:¡ÂÙÉpÛ鵩µ¸â|åþYÛN]Ó†(šœ(êÔ³çZ}·5ÎÄ€X¶r8U Šó‹®ÜAî«báMT"m#ÇÙ›ì~¨F.é_Ž'â(òyGÞ[üßhìGHÒà`Ýz’?k1ëÞ™³¤Rô®Õ]aoAWŸ½Žv´HûÐüÇum@?€éDnò8£ECºé„„¨rúE¨/Ĉ¦J‘Dâ Eág$u_yN:ƒýò–Ž€?^¨³z¬jC¥Šèo~°­½¡ïHJsªb)¼–P<Û°ÇœiÜE/ ÷Ð/%›ñmãÞ XròúÜÖåú‚뎞ê i Šlòb[1­`›½6¬\8¥%^ú¬í¾-ª=ÛÙ‹zÎõ\ ^!NjfËÊ¡”®ô”6Õ4û:|¦žTÅØ[œ¡Òù2:ž1oé<Òê4õÅCÚ>x2ê´u« SÞÝôÚO·¡èÇhÚ{(Ær˜®H’dñÅí'ìèèÎ0·ý̓;÷èÛ‹[½wjHÑëpµT¹¯ñC<Î[mþÞÞ†. ÛŽ—¯c@oY¥M-L?P¨:#éì„c'h­éémílª‚[@ñââ_Mz‰!¼#0ˇz,áºXp¢ áÆ°C=ýñŽŽ•Š×`K|ÁAŽ—]B¿ù1B¾ú}ƒÌ”f1/š ÃÜËŸ³u´Ÿg ®®PÔv-´‘rØ›ÝÇÜÇ<Çœ=Þ“§N;ê{€>Ô\°“R¶R¿)ï$Ç”@üã Zç ku˜ GÐè'"´ò÷b40(–¶·ªÔ™¹²ZŠ;B]]!ž‹¥EÇ­·Z €¥Ï×ü)æÝ¸å/bîæÏÛÚÞ`Oí.€6†Œ'›½þŠ@É!q²_¸óÔá†G(ޏ¼F\ò³•YÄiS^ ììQà8IÊA Á‰À”M\^n²d1`+úšï_”é4q `†\ÐÖô»¼AuSy³ú`F½÷}õ%ÅÇpãZÝ÷lŒÐFr”Qv·( Éò9ª•r6³h¤ý«kUžë'Žñõ¼3$SYÓ€Õl°åEO5©¢j«õå –eiñäÙ!÷Ÿ)]Á¼Í™íø3Ìù†'öú[ÈêrúÖ¶íò;uPA”²Ä “¿lkéìæ:Ã;¡Ì•}Bþ´<ƒ¢nQª£ãÿ@Îþ^ím§Ùþ¿-ûàÏŸV4¸ÿºx°ó¯Øº6oÉÞcyð–ŏÍËJ³ s¾ÁcØõ_“àÿ‘¸ÿ·üîܧm‹ŠÑJIžS*‰ÍPrúXiVY‹LkTka+˜•²§Çuœe{Ãj÷ÏGµá‡ÎpÖ?¶××})st¸ú¡a¨Cø‡õ³²]ˆõ‹.ßAÇ? nä–"ñŸb OÆcȤ”Oùx!ŠDr$%Cú%®ÂF©zE3ðn Š9u熣è8’­Sék”‰o+·B¼%„fù…í"!çžåãÒõ:;Y‰|hŽ£­ª¨gÏ ²Œ'[ÀHôS$YòóéÌbHÚRYQuU†_~ X%wxãZò}¦Ì¸¯Ö ezÖÖÑy†í‹žZ%tJ^ù°™ÌÅËG7ÎÅ“g`É«Ld*ŸD1q¨èÑ1Ò¢‡Ò†ïðýìȇuçG(÷g3Èæã«l>ºP_^ëj»Ñ gsÃ…Ã’ÿŽ(1VA­j7Ö´·5»5­©Šu°cKîVƒ‚,¯5‰îŸCIçÄ áu©ÍžÏ´Ëê4(,d‹.-¯Ð“L{È £ñ”ýsßa £^Û\Ü© šNèé/W@<‘óÖ$ÅHh0¡Ñ\=8+@œÕZ¤Åd¬žd¡‹[á$»VK³ËY[ãtvd èœ_xr–’ö¢†¬`¶s³o·7© NÓ<ÜGÏ6݆X”³å¤õ^ή¨Þeo ÁËGƇÐBr?Cèl û)’a4ð"ë£r$%¯l™9ÇjÍ“}&Ù;¬E$”rùŒ»† â„B½![Mͧtޤ"ŽÌålC©65 èdÝ¡.ªxïÞ³äGDè9²Ã„x)–þ]m0š2¬ùùxœÌ¤4lÝ»'3S©#Ó4Ž «±“oâ—Ð7²°Õåáñ–?\!\€¾”vœé©îã‡ÏÈcÕ\žr·­dÈïIkC`'9sd§³šÈå’µZðì•mCmœÝÚ¼¼û(4+ˆ8h¸ml¶i+Ÿößmà­»N¥£ÃfÙTE HÐ4ÈáV³%å;xUØà2ØLîýò«ø×ŽB»¹ä5àð¸ªÑ4Ô/;{E`&YTƒÃíª¦‡FeTHT-| FdŸ‘šM¯Lײ5)©K¹áËUÀÖÉúO°ÕDº‚Fžlymr¨¯®÷x¾úZöát·ÎW9èôÅJŽô¿`kí8üǹ–…r«KsL;°ù¡ì Š8wêŒ3òa Ô¬†SØi«ˆžjV¹¹rå_R¢ÖX-É{†„ßÈô5ᆄªªº.ï!8/Í­aK†JdV^„:Ö@Nryºj„DÖûa|)m;ÜÕrÊFX ´–AÖŸXàîµdÊÍz< [ Z8²nƒC<MŠa*.‰ÕªöñÙaP¯€ÓìQÊïãÿ²éy" Dž¶Î)ÊÕffL (´—Õõ9ª;¡‰î(ð”ä©‹÷§ôe½¯¸ —¾u‘+Yž_XÞ€²ª\~ N©y{”ß­¹ 9útÿ¹ÿ_.µ- endstream endobj 332 0 obj [404 0 0 0 0 706 0 0 0 0 0 0 0 0 0 648 579] endobj 333 0 obj <> stream xÚeÑkH[gðsL\ßÙ4ÎRé öä|Ú,+6ëÖm- Yeg©6ÓUk.žÔ¨¹49¹¶æV™ÆDI¼ÅxI¼l5Ö¶J·V6†Û‡QÙ¦0ÆdЖMX¿”s$ƒíD؇±/x_xx~ãó1Ç],+«–|ôViEÅÇÅ™³]i_¿ÏÍÃØœ=žÅ<ö(ŸØ¹Àÿ[uð½¼L¾ÈÍäó×2ù&¼_c|GFÛçbñ;EbñéR­ÎªW]k¢ÉBÅ òí’’â“äi±¸„üPMéU ™†¬ÑM”ZFsV²J«PQ´•,ü ‰¦uï:e6›‹djC‘Ví܉“¤YE7‘—(¥7Qäy­†&?‘©)rß^´Ÿ¥ZµÎHSz²BÛHé5†óT˜³àv«Äj±Ï°ì, ÇøX¿šu4k›õ ÙBW‚%˜üç8Ã2·Éc¶ö²ó‡1­Ns]c ›â3ñDœHKÿòçwÚ=°¡º%êñŸ+ 1¶ƒ—hƒ®ŽN'ý~ƒ¼Ùމ`¢ol ŒÆ§&žö†|A_‚èâNua}ºÀf€ˆ@·ß78½³²pÐðÀ-莛ú $Ü“ì›p¶x³ç#Üà6wèÁ‹Œ£®ab†Ãþÿ@ÿ¼Ü?6x?0ˆbþ‰ÁTOÿL*±ôà‹}Õ]cA¥4Í»!sj;Ý[²Òüðÿl©\ÈÔçØþðè½Ð\ê%¬£Ýs#â TÕ¨íß_ŒÉA t«6*Û.ýë÷õŇ¾[[4Ýgäü·²]×®sÉ=FîŠc®Äò·Lù³H_Ýe~ÿƒÇô¼Ìw©š/×€Ô`Š¤Â¾ ˜mˆÖj ÊÚuz¸©™©åIÉcë æÀ7L^"ãq^O§Ãt¾òÓ*@ Süަ'Ÿ&^tëÞTz`ÆÛZÜ-X‘qäæÄDrly½|DAÔ‚¢ÙHYSõ³Ü`š_žÎUgø¢0t÷úÃSÛw×%ãÖ+"0;jÝ*$dJKÉg©ý~ÛÝä±_²‡ò{#Ü–ŠÞÙ'X> stream xÚ]‘ßkƒ0Çßý+î±c MêZ"t¶7\ǬÐW›œ0cˆöÁÿ~ù!mÙCÂ'ßÜ]rßóÓ|›‹vÿKõ¬ÄšVp…CQ á„çVx„oÙ8ŸìκZz~ZÔò³îücõñV¼?¦ÅîH‚§ê‘pl\Èa’t>çÛrFìrÑôÇ€ÿ­+£š`±áý Œ¶WU+ΰ¨ÒÒ*åEÊ_ìPŒxIbË÷'ÖsdÍPÕâŒ^ ÄY–x(ø¿;º”SÃ~j5‡ÍÄñ‹fBo:YÞtzOïâ—öÉh÷j˜XÎVšÃYßžu“R§§†—N_k~Ž4SJˆæ5q¼±Ì?6-ó¯Þ³‹RÚ;!k·q¦x¢ì¥É²ëX.Œ± endstream endobj 335 0 obj [458 458 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 736 736 0 0 0 0 0 0 0 0 0 0 0 0 792 792 0 0 0 0 0 0 0 0 0 0 0 0 0 0 875 875 0 0 0 0 0 0 0 0 0 0 0 0 0 0 875 875 875 875 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1444 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1000 0 0 1056 1056 1056] endobj 336 0 obj <> stream xÚ}T{P”׿ûà Ú %ó±»! Á EÔ@£i°©ÔJCŒŽô3‹» °°¬àò”çî~gwy-^FÉ´I“b£!VÚÌcÌÔ8|uÛŒ5N5ÆÉ¹»÷sÚ»° øOÿسçÞsîïœßïÜû D­&‚ ÄäíúùÖœmOlÉy.omjh'½JºS!iÞ ¼¬¡É„þH )tŠ®TÇó·Â×?Ù¹rKô܈b‰.‚$šÐ&Ø0Ÿ­ÄMÍÛ>w€ØÑæn5€Óëêt½·û̆£lý+©þG![«\maÆÜy/¶´€Übk»K?ï40ø FŸÁlÀ*1&`—¾ûx\ºï)^Æ|EÈ•¾;¦²÷­ìÙl$, û³p(/ðÞÄLvÌçã¬|b_4èx‘úzv•Í$( d‚ÿOň=lzÌþváÑ¢&/ ‚8Ø"·¤*ͽ¢¢‡$¶_4~-5²œ®yÅr´ðHÓ€@ljfαÓéu¿Y4›=˦±þÏØ(:`‹ØM–ÉN>Í22L&·Ëí—Øì‡ý onh¯âÌZ4““}]ºS9.Ýï izCpKwêtÀI´÷<âF\‘‹®îéÝštó …Ixi—ŽQÿ@âõy½Ð"\ÏÇÈUuËrÎó›XËbòz6UÀNV±´V–,”¨)%Ÿd×ÿÆ’¯³ø?âoõÈ# -H°Ø -¸¡¢ÓRp;— ê74–=‰×‚ÉÉŸômK¯ì©±¡uA„¯ëk&^d+N3¿2§§Y”,P6ÿJ‰bIìÒ lù3,j#²Ûå Ñ ƒ|èüîy=ž?œÃÌBù*NÇ“‡0­3Ó¹0ÿ‘ŽKÚk\˜c¨RÑ(¾Öì†Aƒ7ðÂ%zoÓ†žðnƒ:}ÝèŠ =è¶>eoàUô¸‚¯üî¿¶~Y{á—‡ëμ±A<¬eÑø†Fb…Z;Ȳ«]vÁ~8@'î¯R†”o›› ä¸~ÕÇ륀‘«øwÞµY ¼£c/Z˜¥ן½ˆµwßùx ÷P}WÒ~Ô5à‰ëoõ7ñ×ålt6Š1ÁI‰Ò€ÀŽIU`_êÞövÿÞ iÏGŽÀhM 8jõRP+G*»%Ín>1TwŸÒð³aÁN*—uµàƒÑ=]<Êû`œ™\È«žÔ½ätýÖ ¼¹˜þ'œŽ…±1ÔbjÆ´üã<95uÿdϲeü­R;¬ËîÃ/Vü^(õ½ endstream endobj 337 0 obj [446 446 0 0 0 0 0 0 569 569 569 0 0 0 0 0 0 0 0 0 0 877 0 0 0 843 0 0 0 0 0 0 0 0 0 874 0 0 0 0 768 0 0 631 0 843 0 0 0 0 0 0 0 0 0 0 0 569 0 508 0 508 0 569 0 323 0 0 323 938 631 0 0 0 0 0 446 0 0 0 600] endobj 338 0 obj <> stream xÚµV{TTu¿—Á¹WB|Î ¹Þ;> PS(]µÐBŠÅ|€†åƒÇ0 ÂL04€ˆ 03ß™!`xƒÃ{„ 0+Qs³l  ]ËpÍÆzÌm÷¸Õ÷Ž?«½S[ÇýgÏž³gϽç{îïœïãó}ü>ßKSÞÞMÓ¾áñ[£cŸ\³e¥ç¼BM¬w¾sMæPÂoia®—ÀI„ÙÞs)Š^4]”ÔS=òê4|@>7fPÞ4ÍjrÊBBYòp„J›™¦LÕȃ’‚å¡«W¯\"8$dµ<<]‘™–”!IФ*Ò4âa¿|«*)M¡É•…¥j4êG—-ÓjµKÒ³–ª2•kƒ—ȵišTùE–"ó%E² ý"OòɈl'lìÒ^=ø.\…Kð'ø¨áLËøHË«ðœÞÛ¼¹1ÎË! 6hCžÎNO(p ®×Eü•–àîi².£YÅ­ßbJVÉ´Ã(œq°w+™½PÈ)”Òf3Nµö÷à C«ïB—‚ „ºWx£OñÖ·7\ôð·X|K"X0Z–&5dë6èŠKÖÂAöé77úºôîïÁM§Ì»Df‘i+—/{îµÒêö#M®f}ßv®çÂû­CÀþíôšGyX¹OIJH‘¿®Œ b…©ßÙ“øøIzÌ­‘¸mx]ÖÐíYPÀ¿HZY™mÐÀ»ƒ‰ZV×íÈç¿’æk 3«êx?÷5páV—°ÎN qîHYI£¡2rÀ /9@ܽê¯ËÌÛê©@¯µÏÜ{ôRY…˜-³[ewðPe¶”WŸÀ©þØ/=K´ˆ …ÒU¨9%sÊ2béúÐP#êk™(ÐW:Xò–P#ÃYäãIÄ&õsÿ V]4>rS"Ä Ëe¸ÃO{³á„9ÀŨŒFUZ`y™ïB%SßVšÅƒ¾¬°´” yÇG˜^KÍe®Ý%7®7*SÖ[âE½væ²E—ÊßmfÒŒ…k¹,¥ÔÃÕ?b<%ÂÈbÖ«ûx\Íàdp9\Ql+„‚u*äþ¹oÔPïI14Å)ÖÏ]%V¨Ë‰gEœ+&pâ; ÚpX†ÑR|¥×þþ5ñ¾Nù»Ó”íÒÿ&x¨ ?VýÐæÝ@hòOVàai¹jˆósûh]îNzl‘ EX!{Ä®†cìè¹á çÀÙÐÆù–|si°MPy˜ÇíLØrÅ`4è •[ýŸ9¿ÊªGlFhèƒs sÆ/õJ„-Ø"ƒßÃÀÎþÄÞç7»$J¹q_k^g—ÝÞÅCSq‹ºÊÕq*€}û\ÊJ~?k|ưNºW+Ö`Å?2/pW`è–ÁòÄ.Åq`-·à&&-ŽÑÁó))0TÇ…-^©ÞõÜó½'98sâ2FUŠdQ®sâàDƒ“>>qt„²ÜbÝвêÃZGWK“ó:áAE-%ŒøÌø.gcpúÔÖ@W&CéÁì˜mû7ú&.Ä™ïÝàëà¸òÿ ±W9èÁ l“0GÖR ­_ì@Š“Ù ÈT2%`Î9…Tk¹±:Ÿ/c‰A·ÿÑÇó•ðìjIH2ƒAÖÜ)«Áy_¶ N…r›3=”Gº1òüån,è¦?º‚Û¯ôŸ“ˆP"e E®ì³ÀÞþðƒyÌíÉê|Ã9hn‚²²Ò28Àj5Õ7W·µå8’¸|ˆ3¼°'½5¡~7° Ÿˆ\ÃC²]éx±¸({/$Cõ…ÁŒ]ùÛ÷ÂvvzÅŠo&úœºÂA÷¡·b»7õl‚E J(6ï«Ìí†#ÐQYUQÅ¢—I _µðÐGíõM]Í.`ÿ ‹_âá$i_<˜§ÎUŠƒ¾Îû:N‡°ma;çÏ:ÍCŸóµ3뇉×öÎú Cãì%¨¾—Ér¤¥«³ö*d;œ¯pd yV¦d†m%;xRÇìÑA´È+?Úç2õyx`³Žñø#ó“G‡~ö–莖‘E…“”Ìù*ýþ®íßlúMÛh¼ÆûÝY+NqÐ('W|%îa|[öùž7å\ÄíQÇk/ĵ®ƒÕ°m—j;kº%%¿z&µ÷z>ÖÿÁö«gŒb¾ùääè˜-ö9Žäüïz"Ý‹T"ÔþóÿMüqÐ9…É.\%®^¿q”÷Jp§ÀË0ÄEBpCšÔš´ØÀªn6†x_Ó¼}þø;ãœç’>½/%9®5‹ìpKì5¹è/¨‘™Ìú*0ƒuô‚ÍÖ7Ø70nfÞ%êôdsº‡’š ÖBð,Ñüü¼§ÂüWÝÔÕ˜^†ò€†úŠ:‘¾R SJºÂœáÑ=ЙŽÓÉB³©²L`xbµ®0%)-å1£¸»-­–žî£¦nOF‡,Å•P‡kê›Æ.ûtø%1JI€Vc*³·™/ZN§ÉéÑ‚â M'ë§µ  ˜Qm³KIB ãò¿ÏQåë;Þè;…óñ^i÷,ÌšõO4'5 endstream endobj 339 0 obj [532] endobj 340 0 obj <> stream xÚcd`aa`dd r ÕvöuŠñ44‰Ùæýî“aùõ³õ‡4ÃÆ²L?䘈°È=ôbùÏÃ$ËÀÀðCD~å‘@¤ `¼,ÄÀÂÈÈQÑÐo``¬g``äœ_PY”™žQ¢ ‘¬©`hii®£`d``©à˜›Z”™œ˜§à›X’‘š›Xää(ç'g¦–T*hØd””Xéë———ë%æëå¥Ûiê(”g–d(¥§•¥¦(¸åç•(ø%æ¦*Àœ¯c8çç”–¤)øæ§¤åƘ t¤##˵|?V4¯ÿ>í;ÇÌõßý3~¿ômæw~æïÏ~jˆöLèØ=¡{^eWm×oþV‰†®òîî<ŽÊ¹ÝSä¦wÏíšÞõ[åÏ ‰öšîÎî6Ž¢y•Ëät/›1myïÄ…O> stream xÚ•U{TןaÙÙQɪØ9AMf6êñQ, VkÕŠÑ "ŠäÈ*ËcwvYVy( | €Â ˆ,øªÁšVÅi]$ñqÔÚø8©‘hcZsôNÏ¥çt–‡»¶é=gÏÝsçÞû»¿ï÷ý¾ï’„§'A’¤2zEÔûßñ Ššèü² çŠMÿ\#§â¤ø¦‡ÈÊÄ×=ß$rîDi$þ5Þ9~3Á9¾% c5Þ„'IÒ™Ù0ß/ 0T§7óšmIÕìÄ9ªy!! çªBT¿ISóšÄx­*<Þ¤N‹7H“TÕF]¢Fm0«f/N2ô‹üýM&“_|Z†ŸŽß¶dÎ\•IcHREª3Ô|¦ú#ÕJÖ ZŸ¦V “öþ Õ¥é5¯ ×}¤æµ[/_âäbIDñD¢‡†H‘ó²,‰¶¡$ÆáOÌ'ˉÄÛÄJb5±–—öGë‰ ÄFéÔ»Ä{D4áãA„±†ÐeÄ]2ƃðØäñl©¬Ã“ð|×ó–ÜG~ŠšA%RWAŠÏééôž1c”÷›Ð¯h±•DF‡ õ 6M£ÚÁÞ• 9ž†¦SÁž’ ©9,žŽ§+rS %¹j9$ͨ\H±wAg-«Dmò‚8[&J.€+ÔËJ@rÅ"¹ ]éeºô6m ϧ¤µ¥é²µw°Ê‹Mâfë0ÆZt˜©©¬¬†hØYi)ÇAjŸ‚}–Š| ³Íy™˜«  ¼Ö÷àð]; Á<9³!¯Ž-+Ý_ZÕû'+A-ùm/Ò÷ÊP„xƒÉë6A&Ы©l´Ú6‰Só ÅHå¤K³V¨ã~ jÛ¡£C/7ŠY¥ÔÞUé  9ƒÁ>5+4}¤fï N¬jVÔ¶IyÈæfQ9zéxûXV UTßf>G+ó„X餼8ÐÇï“rѺÈ\°9çé»Ëïá±,^ò¿¸ Ò ÒQ“Îý™j€N°ëZ2ÁÂÛ mÔÔ§·ewÝgýò˜5ÿ`FZqF~AQ¢Y§/rлZéI¹¹Ö¼*ÓÌr¤½N=:±iÓ–nD¡6šâ@“ùÏ2hò&Ê )­ÍlŸ¢³ð€†œH%[,É\˜âåÊДAKŒbˆ¯“=Z@ i’.ñ¡”…Z$<È^Êr8Mqœ¹yOÿ9¬Ô7f7³ÐUVú1”—–6•Õ””2ÝÝÐÅÓ´ë‹7ì 7Eo_³ VÑ+.E °vø¢üÓcÖä³Å'€¶ÙFnJSYN½º‘4ÉLÈJÚ¾Š€^ÿ¡ýÔ_t£×8'‘»yC¢q[&nF$ÓÆƒ…5ÀËîcԦ  ƒB¯œë@ ô:×MÅU%•Å¥%°{oBgIÐÍuí_΄-xiV-ÄÊYÈ M9ú´~ûŽ€h<î@û¤(ƒÄ+Ì^aÔK]NáEÔŽú„îu@¿åñøsžqè9ÙØLÇCîoÙ>—p ÔjäÃlŒ YºáúÃ'ýýWŸ¬Ÿu^¤º€¦Jrö£Æ>™øKÅ45Âq4&ì;<Ó~³°{ÿ}˜OþÚVQÜœÊeAaAa6¿aõî,†°K;oÑ¥˜ƒ÷g/Áд/š–òú…o’h—”ü âe¦Õdåy“‰ç­¦ÖV«µ•ÅËðÌË`^à~L¹ :]Ôg£ûÔPìàH)/¤²;Šö3h+?âÚŠgº ŽR8ûÉÑÃF[çZùÝ %Îíª™®rˆ»GݾÆá@yJÆè²§ ^Oøz¸¥æÏr%)-Xé6ÿÂÒyÝÈÏzíüÉÄhÔË4òœÏ&f‡~kañD ÄAªÖ’_bÏ3ÐiÃh-ÐÉá~EŠqùÞ0°R9´VqïØg§ïOÚÌb‹bûhh×ÿ¯-#Üž8P”Óqè ó}ì™vlQoÏ¢Cmâ«îëOp s–›ÕPõ·þžóBMr$‹w$(~z5R@‚59œ”Ê ‰O1‰€Ù’õ¼ù¾xñè òfq fBÃo>¸Ü÷ÕW—Ãü|×…rJÌ (p”²T$(óŒ‹dʦ?®íúùÀc4 _øýtn9ÄnÉßEwAÝ«Á v»ó\Ìf.öö:® Ëçù®ZµbÙÖûgGÌG"_Z{[†RÑ»wõ>[P^²wÛá¢J [ê5÷Ä×Gsï@dZìFúä°ùfºÀoâþ¥nº•¸™6ªÈUÕ 21XœÉÔC³.£ÐPÂ&ÚbÁ4^h Öp`ÓugÙÍ»¿Î=Yp'¢è­š$?v Ä·f^Û][TÍ Y&n†b³5Pu§Î¨?-’Z: äu€ƒñ„¦˜Êùuàcº½ÓþûöÅ•¥—™Šj@Ò¨Á:ÔˆnϬCqÏ—4NÇ0(ÈÍÓA_KG‹ôŒÌlHb¨¬œ‘=Àå”ße͵óOÛÿ!=pÉ)`ÌdK""w€þ5œµ@¿´›8å'\²Ê·Žu²È¦øïõÊÿOº[ìçp¢ÕzˆÞfƒC¯ö¼Ñ¤E<#ua_ùQ7æ²a$ظe3–<“·Øþc¥m¨‹HíÀW²c°\ãÖ3> stream xÚcd`aa`ddpõ÷ ÓvöuŠö14‰Ù8üî“aù÷³‰õ‡4ÃÆ²L?䘈°È½\’ÏÃ$ËÀÀð]D~á‘@¤*`Ü,ÄÀÂÈÈQÑÐo``¬g``äœ_PY”™žQ¢ ‘¬©`hii®£`d``©à˜›Z”™œ˜§à›X’‘š›Xää(ç'g¦–T*hØd””Xéë———ë%æëå¥Ûiê(”g–d(¥§•¥¦(¸åç•(ø%æ¦*À\¯c8çç”–¤)øæ§¤åƨt$+##Ëö|?./XºÿþwÁï ß/íZ5Ÿñ»ÊÓï¥O˜XüT=Ôq°bNGxIjfÒÚúæoß#ßýÍh£å„Éû$bØš#~;6yÿ–ë¶ìΛµ)ekÂöæu-‰¿'HDôûÏ­:Åqaʹ»’&Õ:wÚTÈw»¯³ù.Sß!±‹mò¾ïn3Ž×ê~ Ù}¢hSÉÒÔ­áÓò'rÄMõ˜ž¾®{{÷ž-§ßNå¨ýÃ*z¿fvPw^wb¶éoƾ†i?¦|[0uÛïØI컸¾óp¯ŸÆÃ#ÇÅb>Ÿ‡³‡‡ï‡°¡ï¯Û endstream endobj 345 0 obj [500 500 500 500 0 500 500 500 500 500] endobj 346 0 obj <> stream xÚ%R{LSg¿—zDqÔ‰ÃÛNq¾ êÑ eðb‡E ­Pú HAD”G[´>ŠP‚¼¬ €+¨èÔ0 ËæÔM¢›n‘eh–ÌÅœëîþØ-þóË÷œ“ó{’àó ’$çD'ÄÇíŒ]½%fsˆÄUXÃÖþkxwÜùˆ`üIf±Có_þb‚ Þù¸pj® ŸÏsá*Üóç|’¤ò‹LÉÚ ‰$t‹J]¨UdÉuâVŠCÂÂ6ŠC%’0q¤R¦UæŠc¤:¹L)ÕqŸñnÕ…LW(^!×éÔáÁÁARe^J›õùÊ@qB'ï’åÉ´‡dâ(U®N+UÊÄ3œƒfp‹J©Î×É´âU†L›K¤›„·žO>Ä|â—X@|H,$üˆEÄl7‚$øD6ÑMƒn{ܦxÛy÷øŒÑ›1–:˜)9€¾†¾í.»£E<ŒbÜ…`†ñú‘sèýÄÚvh+?[¨6æè!R´ª­ƒ7³XÊnÚÅ^Œö f!9ý—áò5ËéHuõ})<‡:u–Ùaú¨»€ž?Ó—À®®Ë©Õpg§$••™Z]æÌé•Ú úp^á:ôá1jfZx 5`¡:Ø\A)ì¯ÖÔ¦™M ƳT²‡œ­wwz˜û̧mæ†'p†ós‘GT°ÑÀú°À&ú}q êmNó=&€Ç\;:ñ^4ó”Óû /xøš¿éÔôçcËØ9±a4ìnÛuG–¤ŒK źOÅ¡éSHÒ€¼£òŠ]ûFXZ¯l‚~jl´ýÖOÝ ñ4ì<˜¥/¦X··Ûúµ}ùè½G¾-,ýö#ž\n<ó~}+Îuà[—çþ¸ýyø/«4 1i qšbui¡J¾Žƒ¢Zg¿`nmáâìÓufd©uÒ¯®îxõ;®¿ƒŽ ÀSl:êììÔ´#)M±DýMÛ`¸º}„ÚX"ÌýC§ñ<<ŒÀ KG½©÷kp@£¢A[m´q ƒŽ…l¥½K­ÌŽ˜j?iõ`SêÎÙHx^®÷òB¢Ïk=›¿¡ÙkVµ—7¾ðýÉ#š! endstream endobj 4 0 obj <> endobj 347 0 obj <> endobj 5 0 obj <> endobj 348 0 obj <> endobj 9 0 obj <> endobj 349 0 obj <> endobj 10 0 obj <> endobj 350 0 obj <> endobj 14 0 obj <> endobj 351 0 obj <> endobj 15 0 obj <> endobj 352 0 obj <> endobj 16 0 obj <> endobj 353 0 obj <> endobj 20 0 obj <> endobj 354 0 obj <> endobj 21 0 obj <> endobj 355 0 obj <> endobj 34 0 obj <> endobj 356 0 obj <> endobj 35 0 obj <> endobj 357 0 obj <> endobj 36 0 obj <> endobj 358 0 obj <> endobj 67 0 obj <> endobj 359 0 obj <> endobj 83 0 obj <> endobj 360 0 obj <> endobj 198 0 obj <> endobj 361 0 obj <> endobj 270 0 obj <> endobj 362 0 obj <> endobj xref 0 363 0000000000 65535 f 0000185928 00000 n 0000185776 00000 n 0000175852 00000 n 0000239085 00000 n 0000239420 00000 n 0000000015 00000 n 0000000393 00000 n 0000175929 00000 n 0000239746 00000 n 0000240075 00000 n 0000000489 00000 n 0000001960 00000 n 0000176008 00000 n 0000240385 00000 n 0000240702 00000 n 0000241020 00000 n 0000002058 00000 n 0000003660 00000 n 0000176088 00000 n 0000241338 00000 n 0000241658 00000 n 0000003797 00000 n 0000005642 00000 n 0000176168 00000 n 0000005792 00000 n 0000006731 00000 n 0000176413 00000 n 0000006849 00000 n 0000009052 00000 n 0000176493 00000 n 0000009179 00000 n 0000011582 00000 n 0000176573 00000 n 0000241975 00000 n 0000242291 00000 n 0000242614 00000 n 0000011720 00000 n 0000014803 00000 n 0000176653 00000 n 0000014985 00000 n 0000017553 00000 n 0000176733 00000 n 0000017714 00000 n 0000019701 00000 n 0000176980 00000 n 0000019829 00000 n 0000022650 00000 n 0000177060 00000 n 0000022810 00000 n 0000024937 00000 n 0000177140 00000 n 0000025077 00000 n 0000027366 00000 n 0000177220 00000 n 0000027525 00000 n 0000028166 00000 n 0000177300 00000 n 0000028285 00000 n 0000030819 00000 n 0000177547 00000 n 0000030935 00000 n 0000033449 00000 n 0000177627 00000 n 0000033598 00000 n 0000035781 00000 n 0000177707 00000 n 0000242922 00000 n 0000035911 00000 n 0000038680 00000 n 0000177787 00000 n 0000038840 00000 n 0000041293 00000 n 0000177867 00000 n 0000041433 00000 n 0000044075 00000 n 0000178209 00000 n 0000044226 00000 n 0000045581 00000 n 0000178289 00000 n 0000045720 00000 n 0000048562 00000 n 0000178369 00000 n 0000243250 00000 n 0000048669 00000 n 0000051614 00000 n 0000178449 00000 n 0000051753 00000 n 0000054062 00000 n 0000178529 00000 n 0000054192 00000 n 0000056472 00000 n 0000178776 00000 n 0000056642 00000 n 0000059487 00000 n 0000178856 00000 n 0000059679 00000 n 0000061998 00000 n 0000178936 00000 n 0000062138 00000 n 0000063038 00000 n 0000179017 00000 n 0000063159 00000 n 0000065857 00000 n 0000179100 00000 n 0000066007 00000 n 0000067266 00000 n 0000179352 00000 n 0000067407 00000 n 0000068672 00000 n 0000179435 00000 n 0000068781 00000 n 0000070857 00000 n 0000179518 00000 n 0000071027 00000 n 0000072749 00000 n 0000179601 00000 n 0000072911 00000 n 0000074958 00000 n 0000179684 00000 n 0000075097 00000 n 0000076827 00000 n 0000179939 00000 n 0000076958 00000 n 0000078502 00000 n 0000180022 00000 n 0000078633 00000 n 0000080287 00000 n 0000180105 00000 n 0000080396 00000 n 0000082715 00000 n 0000180188 00000 n 0000082857 00000 n 0000084660 00000 n 0000180271 00000 n 0000084810 00000 n 0000087041 00000 n 0000180621 00000 n 0000087202 00000 n 0000088812 00000 n 0000180704 00000 n 0000088973 00000 n 0000090636 00000 n 0000180787 00000 n 0000090786 00000 n 0000092840 00000 n 0000180870 00000 n 0000093023 00000 n 0000095083 00000 n 0000180953 00000 n 0000095193 00000 n 0000097158 00000 n 0000181208 00000 n 0000097288 00000 n 0000099219 00000 n 0000181291 00000 n 0000099370 00000 n 0000101165 00000 n 0000181374 00000 n 0000101316 00000 n 0000103405 00000 n 0000181457 00000 n 0000103536 00000 n 0000105025 00000 n 0000181540 00000 n 0000105166 00000 n 0000107167 00000 n 0000181795 00000 n 0000107329 00000 n 0000108667 00000 n 0000181878 00000 n 0000108777 00000 n 0000110624 00000 n 0000181961 00000 n 0000110741 00000 n 0000111797 00000 n 0000182044 00000 n 0000111887 00000 n 0000113501 00000 n 0000182127 00000 n 0000113651 00000 n 0000115580 00000 n 0000182382 00000 n 0000115699 00000 n 0000117673 00000 n 0000182465 00000 n 0000117835 00000 n 0000120182 00000 n 0000182548 00000 n 0000120343 00000 n 0000121698 00000 n 0000182631 00000 n 0000121820 00000 n 0000123242 00000 n 0000182714 00000 n 0000123375 00000 n 0000125296 00000 n 0000183064 00000 n 0000243560 00000 n 0000125405 00000 n 0000127699 00000 n 0000183147 00000 n 0000127864 00000 n 0000129134 00000 n 0000183230 00000 n 0000129263 00000 n 0000131312 00000 n 0000183313 00000 n 0000131462 00000 n 0000133477 00000 n 0000183396 00000 n 0000133628 00000 n 0000135325 00000 n 0000183651 00000 n 0000135434 00000 n 0000137466 00000 n 0000183734 00000 n 0000137595 00000 n 0000139313 00000 n 0000183817 00000 n 0000139474 00000 n 0000141819 00000 n 0000183900 00000 n 0000141980 00000 n 0000143764 00000 n 0000183983 00000 n 0000143895 00000 n 0000145850 00000 n 0000184238 00000 n 0000146012 00000 n 0000147701 00000 n 0000184321 00000 n 0000147842 00000 n 0000149588 00000 n 0000184404 00000 n 0000149739 00000 n 0000151664 00000 n 0000184487 00000 n 0000151795 00000 n 0000153044 00000 n 0000184570 00000 n 0000153185 00000 n 0000155480 00000 n 0000184825 00000 n 0000155621 00000 n 0000156361 00000 n 0000184908 00000 n 0000156461 00000 n 0000158637 00000 n 0000184991 00000 n 0000175830 00000 n 0000158756 00000 n 0000158799 00000 n 0000158832 00000 n 0000161410 00000 n 0000161720 00000 n 0000162081 00000 n 0000165067 00000 n 0000165384 00000 n 0000165798 00000 n 0000165843 00000 n 0000167985 00000 n 0000169285 00000 n 0000185152 00000 n 0000169419 00000 n 0000172080 00000 n 0000185235 00000 n 0000172179 00000 n 0000173121 00000 n 0000185318 00000 n 0000243886 00000 n 0000173231 00000 n 0000175719 00000 n 0000185668 00000 n 0000178114 00000 n 0000176324 00000 n 0000176248 00000 n 0000176889 00000 n 0000176813 00000 n 0000177456 00000 n 0000177380 00000 n 0000178023 00000 n 0000177947 00000 n 0000180526 00000 n 0000178685 00000 n 0000178609 00000 n 0000179261 00000 n 0000179183 00000 n 0000179845 00000 n 0000179767 00000 n 0000180432 00000 n 0000180354 00000 n 0000182969 00000 n 0000181114 00000 n 0000181036 00000 n 0000181701 00000 n 0000181623 00000 n 0000182288 00000 n 0000182210 00000 n 0000182875 00000 n 0000182797 00000 n 0000185573 00000 n 0000183557 00000 n 0000183479 00000 n 0000184144 00000 n 0000184066 00000 n 0000184731 00000 n 0000184653 00000 n 0000185479 00000 n 0000185074 00000 n 0000185401 00000 n 0000185975 00000 n 0000186386 00000 n 0000186757 00000 n 0000192807 00000 n 0000193210 00000 n 0000193650 00000 n 0000202145 00000 n 0000202514 00000 n 0000202774 00000 n 0000204186 00000 n 0000204561 00000 n 0000211869 00000 n 0000211954 00000 n 0000212450 00000 n 0000212695 00000 n 0000215280 00000 n 0000215531 00000 n 0000220479 00000 n 0000220718 00000 n 0000223760 00000 n 0000224009 00000 n 0000227732 00000 n 0000227793 00000 n 0000228860 00000 n 0000229227 00000 n 0000229523 00000 n 0000231336 00000 n 0000231559 00000 n 0000234032 00000 n 0000234055 00000 n 0000234638 00000 n 0000234859 00000 n 0000237006 00000 n 0000237029 00000 n 0000237582 00000 n 0000237639 00000 n 0000239234 00000 n 0000239567 00000 n 0000239894 00000 n 0000240207 00000 n 0000240516 00000 n 0000240834 00000 n 0000241152 00000 n 0000241472 00000 n 0000241790 00000 n 0000242107 00000 n 0000242440 00000 n 0000242744 00000 n 0000243057 00000 n 0000243382 00000 n 0000243694 00000 n 0000244017 00000 n trailer <> startxref 244202 %%EOF cluster-1.52a/doc/Makefile0000644000100500010050000000107711207455347015333 0ustar mdehoonmdehoonimagesrc = ../html/images figures = $(wildcard $(imagesrc)/*.png) all: cluster3.pdf cluster.pdf cluster3.pdf: cluster3.texinfo $(patsubst $(imagesrc)/%.png,images/%.eps,$(figures)) tex cluster3.texinfo dvipdfm cluster3 cluster.pdf: cluster.texinfo tex cluster.texinfo dvipdfm cluster $(patsubst $(imagesrc)/%.png,images/%.eps,$(figures)): images/%.eps: $(imagesrc)/%.png mkdir -p images pngtopnm $< | pnmtops -noturn -dpi=96 > $@ distdir: cluster3.pdf cluster.pdf clean: rm -rf *.dvi *.aux *.log *.tmp images \ *.fn *.ky *.pg *.tp *.vr *.cp *.toc *.pdf *.txt cluster-1.52a/doc/cluster.texinfo0000644000100500010050000056411112177163715016757 0ustar mdehoonmdehoon\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename . @settitle The C Clustering Library @c %**end of header @ifinfo This is the manual for the C Clustering Library. Copyright 2002-2006 Michiel Jan Laurens de Hoon. @end ifinfo @titlepage @title{The C Clustering Library} @subtitle{The University of Tokyo, Institute of Medical Science, Human Genome Center} @author{Michiel de Hoon, Seiya Imoto, Satoru Miyano} @c The following two commands start the copyright page. @page @vskip 0pt plus 1filll @today @* The C Clustering Library for cDNA microarray data. Copyright @copyright{} 2002-2005 Michiel Jan Laurens de Hoon @* This library was written at the Laboratory of DNA Information Analysis, Human Genome Center, Institute of Medical Science, University of Tokyo, 4-6-1 Shirokanedai, Minato-ku, Tokyo 108-8639, Japan.@* Contact: @email{mdehoon "AT" gsc.riken.jp}@* Permission to use, copy, modify, and distribute this software and its documentation with or without modifications and for any purpose and without fee is hereby granted, provided that any copyright notices appear in all copies and that both those copyright notices and this permission notice appear in supporting documentation, and that the names of the contributors or copyright holders not be used in advertising or publicity pertaining to distribution of the software without specific prior permission. THE CONTRIBUTORS AND COPYRIGHT HOLDERS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. @end titlepage @contents @node Introduction, Distance, , @chapter Introduction Clustering is widely used in gene expression data analysis. By grouping genes together based on the similarity between their gene expression profiles, functionally related genes may be found. Such a grouping suggests the function of presently unknown genes. The C Clustering Library is a collection of numerical routines that implement the clustering algorithms that are most commonly used. The routines can be applied both to genes and to arrays. The clustering algorithms are: @itemize @bullet @item Hierarchical clustering (pairwise centroid-, single-, complete-, and average-linkage); @item @emph{k}-means clustering; @item Self-Organizing Maps; @item Principal Component Analysis. @end itemize To measure the similarity or distance between gene expression data, eight distance measures are available: @itemize @bullet @item Pearson correlation; @item Absolute value of the Pearson correlation; @item Uncentered Pearson correlation (equivalent to the cosine of the angle between two data vectors); @item Absolute uncentered Pearson correlation (equivalent to the cosine of the smallest angle between two data vectors); @item Spearman's rank correlation; @item Kendall's @tex $\tau$; @end tex @html τ; @end html @item Euclidean distance; @item City-block distance. @end itemize This library was written in ANSI C and can therefore be easily linked to other C/C++ programs. @uref{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster,Cluster 3.0} is an example of such a program. This library may be particularly useful when called from a scripting language such as @uref{http://www.python.org,Python}, @uref{http://www.perl.org,Perl}, or @uref{http://www.ruby.org,Ruby}. The C Clustering Library contains wrappers for Python and Perl; interfaces to other scripting languages may be generated using @uref{http://www.swig.org,SWIG}. This manual contains a description of clustering techniques, their implementation in the C Clustering Library, the Python and Perl modules that give access to the C Clustering Library, and information on how to use the routines in the library from other C or C++ programs. @* The C Clustering Library was released under the Python License. @* @noindent @email{mdehoon "AT" gsc.riken.jp; mdehoon "AT" cal.berkeley.edu, Michiel de Hoon}, Seiya Imoto, Satoru Miyano@* Laboratory of DNA Information Analysis, Human Genome Center, Institute of Medical Science, University of Tokyo. @node Distance, Partitioning, Introduction, @chapter Distance functions In order to cluster gene expression data into groups with similar genes or microarrays, we should first define what exactly we mean by @dfn{similar}. In the C Clustering Library, eight distance functions are available to measure similarity, or conversely, distance: @table @samp @item c Pearson correlation coefficient; @item a Absolute value of the Pearson correlation coefficient; @item u Uncentered Pearson correlation (equivalent to the cosine of the angle between two data vectors); @item x Absolute uncentered Pearson correlation; @item s Spearman's rank correlation; @item k Kendall's @tex $\tau$; @end tex @html τ; @end html @item e Euclidean distance; @item b City-block distance. @end table The first six of these distance measures are related to the correlation coefficient, while the remaining three are related to the Euclidean distance. The characters in front of the distance measures are used as mnemonics to be passed to various routines in the C Clustering Library. One of the properties one would like to see in a distance function is that it satisfies the triangle inequality: @tex $$d\left(\underline{u},\underline{v}\right) \leq d\left(\underline{u},\underline{w}\right) + d\left(\underline{w},\underline{v}\right) \rm{\ for\ all\ } \underline{u}, \underline{v}, \underline{w}.$$ @end tex @html

d(u, v) <= d(u, w) + d(u, w) for all u, v, w.

@end html In everyday language, this equation means that the shortest distance between two points is a straight line. Correlation-based distance functions usually define the distance @emph{d} in terms of the correlation @emph{r} as @tex $$d=1-r.$$ @end tex @html

d = 1 - r.

@end html All correlation-based similarity measures are converted to a distance using this definition. Note that this distance function does not satisfy the triangle inequality. As an example, try @tex $$\underline{u}=\left(1,0,-1\right);$$ $$\underline{v}=\left(1,1,0\right).$$ $$\underline{w}=\left(0,1,1\right);$$ @end tex @html

u=(1,0,-1);
v=(1,1,0).
w=(0,1,1);

@end html Using the Pearson correlation, we find @tex $d\left(\underline{u},\underline{w}\right)$ @end tex @html d(u,w) @end html = 1.8660, while @tex $d\left(\underline{u},\underline{v}\right)+d\left(\underline{v},\underline{w}\right)$ @end tex @html d(u,v)+d(v,w) @end html = 1.6340. None of the distance functions based on the correlation coefficient satisfy the triangle inequality; this is a general characteristic of the correlation coefficient. The Euclidean distance and the city-block distance, which are @dfn{metrics}, do satisfy the triangle inequality. The correlation-based distance functions are sometimes called @dfn{semi-metric}. @section Data handling The input to the distance functions contains two arrays and two row or column indices, instead of two data vectors. This makes it easier to calculate the distance between two columns in the gene expression data matrix. If the distance functions would require two vectors, we would have to extract two columns from the matrix and save them in two vectors to be passed to the distance function. In order to specify if the distance between rows or between columns is to be calculated, each distance function has a flag @var{transpose}. If @code{@var{transpose}==0}, then the distance between two rows is calculated. Otherwise, the distance between two columns is calculated. @section Weighting For most of the distance functions available in the C Clustering Library, a weight vector can be applied. The weight vector contains weights for the elements in the data vector. If the weight for element @emph{i} is @tex $w_i$, @end tex @html wi, @end html then that element is treated as if it occurred @tex $w_i$ @end tex @html wi @end html times in the data. The weight do not have to be integers. For the Spearman rank correlation and Kendall's @tex $\tau$, @end tex @html τ, @end html discussed below, the weights do not have a well-defined meaning and are therefore not implemented. @section Missing Values Often in microarray experiments, some of the data values are missing. In the distance functions, we therefore use an additional matrix @var{mask} which shows which data values are missing. If @code{@var{mask}[i][j]==0}, then @code{@var{data}[i][j]} is missing, and is not included in the distance calculation. @section The Pearson correlation coefficient The Pearson correlation coefficient is defined as @tex $$r = {1 \over n} \sum_{i=1}^n \left( x_i -\bar{x} \over \sigma_x \right) \left( y_i -\bar{y} \over \sigma_y \right)$$ @end tex @html
r =
1
n
n

i = 1
(
xi - x
σx
) (
yi - y
σy
)
@end html in which @tex $\bar{x}, \bar{y}$ @end tex @html x, y @end html are the sample mean of @emph{x} and @emph{y} respectively, and @tex $\sigma_x, \sigma_y$ @end tex @html σx, σy @end html are the sample standard deviation of @emph{x} and @emph{y}. The Pearson correlation coefficient is a measure for how well a straight line can be fitted to a scatterplot of @emph{x} and @emph{y}. If all the points in the scatterplot lie on a straight line, the Pearson correlation coefficient is either @math{+1} or @math{-1}, depending on whether the slope of line is positive or negative. If the Pearson correlation coefficient is equal to zero, there is no correlation between @emph{x} and @emph{y}. The @dfn{Pearson distance} is then defined as @tex $$d_{\rm{P}} \equiv 1 - r.$$ @end tex @html
dP ≡ 1 - r.
@end html As the Pearson correlation coefficient lies between @math{-1} and @math{1}, the Pearson distance lies between @math{0} and @math{2}. Note that the Pearson correlation automatically centers the data by subtracting the mean, and normalizes them by dividing by the standard deviation. While such normalization may be useful in some situations (e.g., when clustering gene expression levels directly instead of gene expression ratios), information is being lost in this step. In particular, the magnitude of changes in gene expression is being ignored. This is in fact the reason that the Pearson distance does not satisfy the triangle inequality. @section Absolute Pearson correlation By taking the absolute value of the Pearson correlation, we find a number between zero and one. If the absolute value is one, all the points in the scatter plot lie on a straight line with either a positive or a negative slope. If the absolute value is equal to zero, there is no correlation between @emph{x} and @emph{y}. The distance is defined as usual as @tex $$d_{\rm{A}} \equiv 1 - \left|r\right|,$$ @end tex @html
dA ≡ 1 - |r|,

@end html where @emph{r} is the Pearson correlation coefficient. As the absolute value of the Pearson correlation coefficient lies between @math{0} @w{and @math{1}}, the corresponding distance lies between @math{0} and @math{1} as well. In the context of gene expression experiments, note that the absolute correlation is equal to one if the gene expression data of two genes/microarrays have a shape that is either exactly the same or exactly opposite. The absolute correlation coefficient should therefore be used with care. @section Uncentered correlation (cosine of the angle) In some cases, it may be preferable to use the @dfn{uncentered correlation} instead of the regular Pearson correlation coefficient. The uncentered correlation is defined as @tex $$r_{\rm{U}} = {1 \over n} \sum_{i=1}^{n} \left(x_i \over \sigma_x^{(0)} \right) \left(y_i \over \sigma_y^{(0)} \right),$$ @end tex @html
r =
1
n
n

i = 1
(
xi
σx(0)
) (
yi
σy(0)
)
@end html where @tex $$\sigma_x^{(0)} = \sqrt{{1\over n} \sum_{i=1}^{n}x_i^2};$$ $$\sigma_y^{(0)} = \sqrt{{1\over n} \sum_{i=1}^{n}y_i^2}.$$ @end tex @html
σx(0) = (
1
n
n

i = 1
xi2 )
σy(0) = (
1
n
n

i = 1
yi2 )
@end html This is the same expression as for the regular Pearson correlation coefficient, except that the sample means @tex $\bar{x}, \bar{y}$ @end tex @html x, y @end html are set equal to zero. The uncentered correlation may be appropriate if there is a zero reference state. For instance, in the case of gene expression data given in terms of log-ratios, a log-ratio equal to zero corresponds to the green and red signal being equal, which means that the experimental manipulation did not affect the gene expression. The distance corresponding to the uncentered correlation coefficient is defined as @tex $$d_{\rm{U}} \equiv 1 - r_{\rm{U}},$$ @end tex @html
dP ≡ 1 - r,
@end html where @tex $r_{\rm{U}}$ @end tex @html rU @end html is the uncentered correlation. As the uncentered correlation coefficient lies between @math{-1} and @math{1}, the corresponding distance lies between @math{0} and @math{2}. The uncentered correlation is equal to the cosine of the angle of the two data vectors in @emph{n}-dimensional space, and is often referred to as such. (From this viewpoint, it would make more sense to define the distance as the arc cosine of the uncentered correlation coefficient). @section Absolute uncentered correlation As for the regular Pearson correlation, we can define a distance measure using the absolute value of the uncentered correlation: @tex $$d_{\rm{AU}} \equiv 1 - \left|r_{@rm{U}}\right|,$$ @end tex @html
dAU ≡ 1 - |rU|,

@end html where @tex $r_{@rm{U}}$ @end tex @html rU @end html is the uncentered correlation coefficient. As the absolute value of the uncentered correlation coefficient lies between @math{0} @w{and @math{1}}, the corresponding distance lies between @math{0} and @math{1} as well. Geometrically, the absolute value of the uncentered correlation is equal to the cosine between the supporting lines of the two data vectors (i.e., the angle without taking the direction of the vectors into consideration). @section Spearman rank correlation The Spearman rank correlation is an example of a non-parametric similarity measure. It is useful because it is more robust against outliers than the Pearson correlation. To calculate the Spearman rank correlation, we replace each data value by their rank if we would order the data in each vector by their value. We then calculate the Pearson correlation between the two rank vectors instead of the data vectors. Weights cannot be suitably applied to the data if the Spearman rank correlation is used, especially since the weights are not necessarily integers. The calculation of the Spearman rank correlation in the C Clustering Library therefore does not take any weights into consideration. As in the case of the Pearson correlation, we can define a distance measure corresponding to the Spearman rank correlation as @tex $$d_{\rm{S}} \equiv 1 - r_{@rm{S}},$$ @end tex @html
dS ≡ 1 - rS,

@end html where @tex $r_{@rm{S}}$ @end tex @html rS @end html is the Spearman rank correlation. @tex @section Kendall's @math{\tau} @end tex @html @section Kendall's τ @end html @tex Kendall's @math{\tau} @end tex @html Kendall's τ @end html is another example of a non-parametric similarity measure. It is similar to the Spearman rank correlation, but instead of the ranks themselves only the relative ranks are used to calculate @tex @math{\tau} @end tex @html τ @end html (see Snedecor & Cochran). As in the case of the Spearman rank correlation, the weights are ignored in the calculation. We can define a distance measure corresponding to Kendall's @tex @math{\tau} @end tex @html τ @end html as @tex $$d_{\rm{K}} \equiv 1 - \tau.$$ @end tex @html
dK ≡ 1 - τ.

@end html As Kendall's @tex @math{\tau} @end tex @html τ @end html is defined such that it will lie between @math{-1} and @math{1}, the corresponding distance will be between @math{0} and @math{2}. @section Euclidean distance The Euclidean distance is a true metric, as it satisfies the triangle inequality. In this software package, we define the Euclidean distance as @tex $$d = {1 \over n} \sum_{i=1}^{n} \left(x_i-y_i\right)^{2}.$$ @end tex @html
d =
1
n
n

i = 1
( xi - yi )2
@end html Only those terms are included in the summation for which both @tex $x_i$ and $y_i$ @end tex @html xi and yi @end html are present. The denominator @tex $n$ @end tex @html n @end html is chosen accordingly. In this formula, the expression data @tex $x_i$ and $y_i$ @end tex @html xi and yi @end html are subtracted directly from each other. We should therefore make sure that the expression data are properly normalized when using the Euclidean distance, for example by converting the measured gene expression levels to log-ratios. Unlike the correlation-based distance functions, the Euclidean distance takes the magnitude of the expression data into account. It therefore preserves more information about the data and may be preferable. De Hoon, Imoto, Miyano (2002) give an example of the use of the Euclidean distance for @emph{k}-means clustering. @section City-block distance The city-block distance, alternatively known as the Manhattan distance, is related to the Euclidean distance. Whereas the Euclidean distance corresponds to the length of the shortest path between two points, the city-block distance is the sum of distances along each dimension. As gene expression data tend to have missing values, in the C Clustering Library we define the city-block distance as the sum of distances divided by the number of dimensions: @tex $$d = {1 \over n} \sum_{i=1}^n \left|x_i-y_i\right|.$$ @end tex @html
d =
1
n
1
n
n

i = 1
| xi - yi |
@end html This is equal to the distance you would have to walk between two points in a city, where you have to walk along city blocks. The city-block distance is a metric, as it satisfies the triangle inequality. As for the Euclidean distance, the expression data are subtracted directly from each other, and we should therefore make sure that they are properly normalized. @section Calculating the distance between clusters In the hierarchical clustering methods, the distance matrix between all genes/microarrays is first calculated, and at successive steps of the algorithm the new distance matrix is calculated from the previous distance matrix. In some cases, however, we would like to calculate the distance between clusters directly, given their members. For this purpose, the function @code{clusterdistance} can be used. This function can also be used to calculate the distance between two genes/microarrays by defining two clusters consisting of one gene/microarray each. While this function is not used internally in the C Clustering Library, it may be used by other C applications, and can also be called from Python (@xref{Using the C Clustering Library with Python: Pycluster and Bio.Cluster}) and Perl (@xref{Using the C Clustering Library with Perl: Algorithm::Cluster}). The distance between two clusters can be defined in several ways. The distance between the arithmetic means of the two clusters is used in pairwise centroid-linkage clustering and in @emph{k}-means clustering. For the latter, the distance between the medians of the two clusters can be used alternatively. The shortest pairwise distance between elements of the two clusters is used in pairwise single-linkage clustering, while the longest pairwise distance is used in pairwise maximum-linkage clustering. In pairwise average-linkage clustering, the distance between two clusters is defined as the average over the pairwise distances. @subsubheading Prototype @noindent @code{double clusterdistance (int @var{nrows}, int @var{ncolumns}, double** @var{data}, int** @var{mask}, double @var{weight}[], int @var{n1}, int @var{n2}, int @var{index1}[], int @var{index2}[], char @var{dist}, char @var{method}, int @var{transpose});} @subsubheading Arguments @itemize @bullet @item @code{int @var{nrows};} @* The number of rows in the @var{data} matrix, equal to the number of genes in the gene expression experiment. @item @code{int @var{ncolumns};} @* The number of columns in the @var{data} matrix, equal to the number of microarrays in the gene expression experiment. @item @code{double** @var{data};} @* The data array containing the gene expression data. Genes are stored row-wise, while microarrays are stored column-wise. Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{int** @var{mask};} @* This array shows which elements in the @var{data} array, if any, are missing. If @code{@var{mask}[i][j]==0}, then @code{@var{data}[i][j]} is missing. Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{double @var{weight}[];} @* The weights that are used to calculate the distance. Dimension: @code{[@var{ncolumns}]} if @code{@var{transpose}==0}; @code{[@var{nrows}]} if @code{@var{transpose}==1}. @item @code{int @var{n1};} @* The number of elements in the first cluster. @item @code{int @var{n2};} @* The number of elements in the second cluster. @item @code{int @var{index1}[];} @* Contains the indices of the elements belonging to the first cluster. Dimension: @code{[@var{n1}]}. @item @code{int @var{index2}[];} @* Contains the indices of the elements belonging to the second cluster. Dimension: @code{[@var{n2}]}. @item @code{char @var{dist};} @* Specifies which distance measure is used. @xref{Distance functions}. @item @code{char @var{method};} @* Specifies how the distance between clusters is defined: @table @samp @item a Distance between the two cluster centroids (arithmetic mean); @item m Distance between the two cluster centroids (median); @item s Shortest pairwise distance between elements in the two clusters; @item x Longest pairwise distance between elements in the two clusters; @item v Average over the pairwise distances between elements in the two clusters. @end table @item @code{int @var{transpose};} @* If @code{@var{transpose}==0}, the distances between rows in the data matrix are calculated. Otherwise, the distances between columns are calculated. @end itemize @subsubheading Return value @noindent The distance between two clusters (@code{double}). @section The distance matrix The first step in clustering problems is usually to calculate the distance matrix. This matrix contains all the distances between the items that are being clustered. As the distance functions are symmetric, the distance matrix is also symmetric. Furthermore, the elements on the diagonal are zero, as the distance of an item to itself is zero. The distance matrix can therefore be stored as a ragged array, with the number of columns in each row equal to the (zero-offset) row number. The distance between items @emph{i} and @emph{j} is stored in location @code{[i][j]} if @tex $j < i$, @end tex @html ji, @end html in @code{[j][i]} if @tex $j > i$, @end tex @html j > i, @end html while it is zero if @tex $j = i$. @end tex @html j = i. @end html Note that the first row of the distance matrix is empty. It is included for computational convenience, as including an empty row requires minimal storage. @subsubheading Prototype @noindent @code{double** distancematrix (int @var{nrows}, int @var{ncolumns}, double** @var{data}, int** @var{mask}, double @var{weight}[], char @var{dist}, int @var{transpose});} @subsubheading Arguments @itemize @bullet @item @code{int @var{nrows};} @* The number of rows in the data matrix, equal to the number of genes in the gene expression experiment. @item @code{int @var{ncolumns};} @* The number of columns in the data matrix, equal to the number of microarrays in the gene expression experiment. @item @code{double** @var{data};} @* The data array containing the gene expression data. Genes are stored row-wise, while microarrays are stored column-wise. Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{int** @var{mask};} @* This array shows which elements in the @var{data} array, if any, are missing. If @code{@var{mask}[i][j]==0}, then @code{@var{data}[i][j]} is missing. Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{double @var{weight}[];} @* The weights that are used to calculate the distance. Dimension: @code{[@var{ncolumns}]} if @code{@var{transpose}==0}; @code{[@var{nrows}]} if @code{@var{transpose}==1}. @item @code{char @var{dist};} @* Specifies which distance measure is used. @xref{Distance functions}. @item @code{int @var{transpose};} @* If @code{@var{transpose}==0}, the distances between the rows in the data matrix are calculated. Otherwise, the distances between the columns are calculated. @end itemize @subsubheading Return value @noindent A pointer to the distance matrix stored as a newly allocated ragged array. If insufficient memory is available to store the distance matrix, a NULL pointer is returned, and all memory allocated thus far is freed. @node Partitioning, Hierarchical, Distance, @chapter Partitioning algorithms Partitioning algorithms divide items into @emph{k} clusters such that the sum of distances over the items to their cluster centers is minimal. The number of clusters @emph{k} is specified by the user. In the C Clustering Library, three partitioning algorithms are available: @itemize @bullet @item @emph{k}-means clustering @item @emph{k}-medians clustering @item @emph{k}-medoids clustering @end itemize @noindent These algorithms differ in how the cluster center is defined. In @emph{k}-means clustering, the cluster center is defined as the mean data vector averaged over all items in the cluster. Instead of the mean, in @emph{k}-medians clustering the median is calculated for each dimension in the data vector. Finally, in @emph{k}-medoids clustering the cluster center is defined as the item which has the smallest sum of distances to the other items in the cluster. This clustering algorithm is suitable for cases in which the distance matrix is known but the original data matrix is not available, for example when clustering proteins based on their structural similarity. The expectation-maximization (EM) algorithm is commonly used to find the partitioning into @emph{k} groups. The first step in the EM algorithm is to create @emph{k} clusters and randomly assign items (genes or microarrays) to them. We then iterate: @itemize @bullet @item Calculate the centroid of each cluster; @item For each item, determine which cluster centroid is closest; @item Reassign the item to that cluster. @end itemize @noindent The iteration is stopped if no further item reassignments take place. As the initial assignment of items to clusters is done randomly, usually a different clustering solution is found each time the EM algorithm is executed. To find the optimal clustering solution, the @emph{k}-means algorithm is repeated many times, each time starting from a different initial random clustering. The sum of distances of the items to their cluster center is saved for each run, and the solution with the smallest value of this sum will be returned as the overall clustering solution. How often the EM algorithm should be run depends on the number of items being clustered. As a rule of thumb, we can consider how often the optimal solution was found. This number is returned by the partitioning algorithms as implemented in this library. If the optimal solution was found many times, it is unlikely that better solutions exist than the one that was found. However, if the optimal solution was found only once, there may well be other solutions with a smaller within-cluster sum of distances. @section Initialization The @emph{k}-means algorithm is initialized by randomly assigning items (genes or microarrays) to clusters. To ensure that no empty clusters are produced, we use the binomial distribution to randomly choose the number of items in each cluster to be one or more. We then randomly permute the cluster assignments to items such that each item has an equal probability to be in any cluster. Each cluster is thus guaranteed to contain at least one item. @section Finding the cluster centroid The centroid of a cluster can be defined in different ways. For @emph{k}-means clustering, the centroid of a cluster is defined as the mean over all items in a cluster for each dimension separately. For robustness against outliers, in @emph{k}-medians clustering the median is used instead of the mean. In @emph{k}-medoids clustering, the cluster centroid is the item with the smallest sum of distances to the other items in the cluster. The C Clustering Library provides routines to calculate the cluster mean, the cluster median, and the cluster medoid. @subsection Finding the cluster mean or median The routine @code{getclustercentroids} calculates the centroids of the clusters by calculating the mean or median for each dimension separately over all items in a cluster. Missing data values are not included in the calculation of the mean or median. Missing values in the cluster centroids are indicated in the array @var{cmask}. If for cluster @emph{i} the data values for dimension @emph{j} are missing for all items, then @code{@var{cmask}[i][j]} (or @code{@var{cmask}[j][i]} if @code{@var{transpose}==1}) is set equal to zero. Otherwise, it is set equal to one. The argument @var{method} determines if the means or medians are calculated. If a memory allocation error occurred, @code{getclustercentroids} returns 0; this can happen only if the cluster medians are being calculated. If no errors occur, @code{getclustercentroids} returns 1; @subsubheading Prototype @noindent @code{int getclustercentroids(int @var{nclusters}, int @var{nrows}, int @var{ncolumns}, double** @var{data}, int** @var{mask}, int @var{clusterid}[], double** @var{cdata}, int** @var{cmask}, int @var{transpose}, char @var{method});} @subsubheading Arguments @itemize @bullet @item @code{int @var{nclusters};} @* The number of clusters. @item @code{int @var{nrows};} @* The number of rows in the data matrix, equal to the number of genes in the gene expression experiment. @item @code{int @var{ncolumns};} @* The number of columns in the data matrix, equal to the number of microarrays in the gene expression experiment. @item @code{double** @var{data};} @* The data array containing the gene expression data. Genes are stored row-wise, while microarrays are stored column-wise. Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{int** @var{mask};} @* This array shows which elements in the @var{data} array, if any, are missing. If @code{@var{mask}[i][j]==0}, then @code{@var{data}[i][j]} is missing. Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{int @var{clusterid}[];} @* The cluster number to which each item belongs. Each element in this array should be between 0 and @code{@var{nclusters}-1} inclusive. Dimension: @code{[@var{nrows}]} if @code{@var{transpose}==0}, or @code{[@var{ncolumns}]} if @code{@var{transpose}==1}. @item @code{double** @var{cdata};} @* This matrix stores the centroid information. Space for this matrix should be allocated before calling @code{getclustercentroids}. Dimension: @code{[@var{nclusters}][@var{ncolumns}]} if @code{@var{transpose}==0} (row-wise clustering), or @code{[@var{nrows}][@var{nclusters}]} if @code{@var{transpose}==1} (column-wise clustering). @item @code{int** @var{cmask};} @* This matrix stores which values in @var{cdata} are missing. If @code{@var{cmask}[i][j]==0}, then @code{@var{cdata}[i][j]} is missing. Space for @var{cmask} should be allocated before calling @code{getclustercentroids}. Dimension: @code{[@var{nclusters}][@var{ncolumns}]} if @code{@var{transpose}==0} (row-wise clustering), or @code{[@var{nrows}][@var{nclusters}]} if @code{@var{transpose}==1} (column-wise clustering). @item @code{int @var{transpose};} @* This flag indicates whether row-wise (gene) or column-wise (microarray) clustering is being performed. If @code{@var{transpose}==0}, rows (genes) are being clustered. Otherwise, columns (microarrays) are being clustered. @item @code{char @var{method};} @* If @code{@var{method}=='a'}, the cluster centroids are calculated as the arithmetic mean over each dimension. For @code{@var{method}=='m'}, the cluster centroids are calculated as the median over each dimension. @end itemize @subsubheading Return value This routine returns 1 if successful, and 0 in case of a memory allocation error. @subsection Finding the cluster medoid The cluster medoid is defined as the item which has the smallest sum of distances to the other items in the cluster. The @code{getclustermedoids} routine calculates the cluster medoids, given to which cluster each item belongs. @subsubheading Prototype @noindent @code{void getclustermedoids(int @var{nclusters}, int @var{nelements}, double** @var{distance}, int @var{clusterid}[], int @var{centroids}[], double @var{errors}[]);} @subsubheading Arguments @itemize @bullet @item @code{int @var{nclusters};} @* The number of clusters. @item @code{int @var{nelements};} @* The total number of elements that are being clustered. @item @code{double** @var{distmatrix};} @* The distance matrix. The distance matrix is symmetric and has zeros on the diagonal. To save space, the distance matrix is stored as a ragged array. Dimension: @code{[@var{nelements}][]} as a ragged array. The number of columns in each row is equal to the row number (starting from zero). Accordingly, the first row always has zero columns. @item @code{int @var{clusterid}[];} @* The cluster number to which each element belongs. Dimension: [@var{nelements}]. @item @code{int @var{centroid}[];} @* For each cluster, the element of the item that was determined to be its centroid. Dimension: [@var{nclusters}]. @item @code{double @var{errors}[];} @* For each cluster, the sum of distances between the items belonging to the cluster and the cluster centroid. Dimension: [@var{nclusters}]. @end itemize @section The EM algorithm The EM algorithm as implemented in the C Clustering Library first randomly assigns items to clusters, followed by iterating to find a clustering solution with a smaller within-cluster sum of distances. During the iteration, first we find the centroids of all clusters, where the centroids are defined in terms of the mean, the median, or the medoid. The distances of each item to the cluster centers are calculated, and we determine for each item which cluster is closest. We then reassign the items to their closest clusters, and recalculate the cluster centers. All items are first reassigned before recalculating the cluster centroids. If unchecked, clusters may become empty if all their items are reassigned. For @emph{k}-means and @emph{k}-medians clustering, the EM routine therefore keeps track of the number of items in each cluster at all times, and prohibits the last remaining item in a cluster from being reassigned to a different cluster. For @emph{k}-medoids clustering, such a check is not needed, as the item that functions as the cluster centroid has a zero distance to itself, and will therefore not be reassigned to a different cluster. The EM algorithm terminates when no further reassignments take place. We noticed, however, that for some sets of initial cluster assignments, the EM algorithm fails to converge due to the same clustering solution reappearing periodically after a small number of iteration steps. In the EM algorithm as implemented in the C Clustering Library, the occurrence of such periodic solutions is checked for. After a given number of iteration steps, the current clustering result is saved as a reference. By comparing the clustering result after each subsequent iteration step to the reference state, we can determine if a previously encountered clustering result is found. In such a case, the iteration is halted. If after a given number of iterations the reference state has not yet been encountered, the current clustering solution is saved to be used as the new reference state. Initially, ten iteration steps are executed before resaving the reference state. This number of iteration steps is doubled each time, to ensure that periodic behavior with longer periods can also be detected. @section Finding the optimal solution @subsection @emph{k}-means and @emph{k}-medians The optimal solution is found by executing the EM algorithm repeatedly and saving the best clustering solution that was returned by it. This can be done automatically by calling the routine @code{kcluster}. The routine to calculate the cluster centroid and the distance function are selected based on the arguments passed to @code{kcluster}. The EM algorithm is then executed repeatedly, saving the best clustering solution that was returned by these routines. In addition, @code{kcluster} counts how often the EM algorithm found this solution. If it was found many times, we can assume that there are no other solutions possible with a smaller within-cluster sum of distances. If, however, the solution was found only once, it may well be that better clustering solutions exist. @subsubheading Prototype @noindent @code{void kcluster (int @var{nclusters}, int @var{nrows}, int @var{ncolumns}, double** @var{data}, int** @var{mask}, double @var{weight}[], int @var{transpose}, int @var{npass}, char @var{method}, char @var{dist}, int @var{clusterid}[], double* @var{error}, int* @var{ifound});} @subsubheading Arguments @itemize @bullet @item @code{int @var{nclusters};} @* The number of clusters @emph{k}. @item @code{int @var{nrows};} @* The number of rows in the data matrix, equal to the number of genes in the gene expression experiment. @item @code{int @var{ncolumns};} @* The number of columns in the data matrix, equal to the number of microarrays in the gene expression experiment. @item @code{double** @var{data};} @* The data array containing the gene expression data. Genes are stored row-wise, while microarrays are stored column-wise. Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{int** @var{mask};} @* This array shows which elements in the @var{data} array, if any, are missing. If @code{@var{mask}[i][j]==0}, then @code{@var{data}[i][j]} is missing. Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{double @var{weight}[];} @* The weights that are used to calculate the distance. Dimension: @code{[@var{ncolumns}]} if @code{@var{transpose}==0}; @code{[@var{nrows}]} if @code{@var{transpose}==1}. @item @code{int @var{transpose};} @* This flag indicates whether row-wise (gene) or column-wise (microarray) clustering is being performed. If @code{@var{transpose}==0}, rows (genes) are being clustered. Otherwise, columns (microarrays) are being clustered. @item @code{int @var{npass};} @* The number of times the EM algorithm should be run. If @code{@var{npass} > 0}, each run of the EM algorithm uses a different (random) initial clustering. If @code{@var{npass} == 0}, then the EM algorithm is run with an initial clustering specified by @var{clusterid}. Reassignment to a different cluster is prevented for the last remaining item in the cluster in order to prevent empty clusters. For @code{@var{npass}==0}, the EM algorithm is run only once, using the initial clustering as specified by @var{clusterid}. @item @code{char @var{method};} @* Specifies whether the arithmetic mean (@code{@var{method}=='a'}) or the median (@code{@var{method}=='m'}) should be used to calculate the cluster center. @item @code{char @var{dist};} @* Specifies which distance function should be used. The character should correspond to one of the distance functions that are available in the C Clustering Library. @xref{Distance functions}. @item @code{int @var{clusterid}[];} @* This array will be used to store the cluster number to which each item was assigned by the clustering algorithm. Space for @code{clusterid} should be allocated before calling @code{kcluster}. If @code{@var{npass}==0}, then the contents of @var{clusterid} on input is used as the initial assignment of items to clusters; on output, @var{clusterid} contains the optimal clustering solution found by the EM algorithm. Dimension: @code{[@var{nrows}]} if @code{@var{transpose}==0}, or @code{[@var{ncolumns}]} if @code{@var{transpose}==1}. @item @code{double* @var{error};} @* The sum of distances of the items to their cluster center after @emph{k}-means clustering, which can be used as a criterion to compare clustering solutions produced in different calls to @code{kcluster}. @item @code{int* @var{ifound};} @* Returns how often the optimal clustering solution was found. In case of an inconsistency in the input arguments (specifically, if @var{nclusters} is larger than the number of elements to be clustered), @code{*@var{ifound}} is set to 0. If a memory allocation error occurred, @code{*@var{ifound}} is set to -1. @end itemize @subsection @emph{k}-medoids The kmedoids routine performs k-medoids clustering on a given set of elements, using the distance matrix and the number of clusters passed by the user. Multiple passes are being made to find the optimal clustering solution, each time starting from a different initial clustering. @subsubheading Prototype @noindent @code{void kmedoids (int @var{nclusters}, int @var{nelements}, double** @var{distance}, int @var{npass}, int @var{clusterid}[], double* @var{error}, int* @var{ifound});} @subsubheading Arguments @itemize @bullet @item @code{int @var{nclusters};} @* The number of clusters to be found. @item @code{int @var{nelements};} @* The number of elements to be clustered. @item @code{double** @var{distmatrix};} @* The distance matrix. The distance matrix is symmetric and has zeros on the diagonal. To save space, the distance matrix is stored as a ragged array. Dimension: @code{[@var{nelements}][]} as a ragged array. The number of columns in each row is equal to the row number (starting from zero). Accordingly, the first row always has zero columns. @item @code{int @var{npass};} @* The number of times the EM algorithm should be run. If @code{@var{npass} > 0}, each run of the EM algorithm uses a different (random) initial clustering. If @code{@var{npass} == 0}, then the EM algorithm is run with an initial clustering specified by @var{clusterid}. @item @code{int @var{clusterid}[];} @* This array will be used to store the cluster number to which each item was assigned by the clustering algorithm. Space for @code{clusterid} should be allocated before calling @code{kcluster}. On input, if @code{@var{npass}==0}, then @var{clusterid} contains the initial clustering assignment from which the clustering algorithm starts; all numbers in @var{clusterid} should be between @code{0} and @code{@var{nelements}-1} inclusive. If @code{@var{npass}!=0}, @var{clusterid} is ignored on input. On output, @var{clusterid} contains the number of the cluster to which each item was assigned in the optimal clustering solution. The number of a cluster is defined as the item number of the centroid of the cluster. Dimension: @code{[@var{nelements}]}. @item @code{double* @var{error};} @* The sum of distances of the items to their cluster center after @emph{k}-means clustering, which can be used as a criterion to compare clustering solutions produced in different calls to @code{kmedoids}. @item @code{int* @var{ifound};} @* Returns how often the optimal clustering solution was found. In case of an inconsistency in the input arguments (specifically, if @var{nclusters} is larger than @var{nelements}), @var{ifound} is set to 0. If a memory allocation error occurred, @var{ifound} is set to -1. @end itemize @section Choosing the distance measure Whereas all eight distance measures are accepted for @emph{k}-means, @emph{k}-medians, and @emph{k}-medoids clustering, using a distance measure other than the Euclidean distance or city-block distance with @emph{k}-means or @emph{k}-medians is in a sense inconsistent. When using the distance measures based on the Pearson correlation, the data are effectively normalized when calculating the distance. However, no normalization is applied when calculating the centroid in the @emph{k}-means or @emph{k}-medians algorithm. From a theoretical viewpoint, it is best to use the Euclidean distance for the @emph{k}-means algorithm, and the city-block distance for @emph{k}-medians. @node Hierarchical, SOM, Partitioning, @chapter Hierarchical clustering Hierarchical clustering methods are inherently different from the @emph{k}-means clustering method. In hierarchical clustering, the similarity in the expression profile between genes or experimental conditions are represented in the form of a tree structure. This tree structure can be shown graphically by programs such as TreeView and Java TreeView, which has contributed to the popularity of hierarchical clustering in the analysis of gene expression data. The first step in hierarchical clustering is to calculate the distance matrix, specifying all the distances between the items to be clustered. Next, we create a node by joining the two closest items. Subsequent nodes are created by pairwise joining of items or nodes based on the distance between them, until all items belong to the same node. A tree structure can then be created by retracing which items and nodes were merged. Unlike the EM algorithm, which is used in @emph{k}-means clustering, the complete process of hierarchical clustering is deterministic. Several flavors of hierarchical clustering exist, which differ in how the distance between subnodes is defined in terms of their members. In the C Clustering Library, pairwise single, maximum, average, and centroid linkage are available. @itemize @bullet @item In pairwise single-linkage clustering, the distance between two nodes is defined as the shortest distance among the pairwise distances between the members of the two nodes. @item In pairwise maximum-linkage clustering, alternatively known as pairwise complete-linkage clustering, the distance between two nodes is defined as the longest distance among the pairwise distances between the members of the two nodes. @item In pairwise average-linkage clustering, the distance between two nodes is defined as the average over all pairwise distances between the elements of the two nodes. @item In pairwise centroid-linkage clustering, the distance between two nodes is defined as the distance between their centroids. The centroids are calculated by taking the mean over all the elements in a cluster. As the distance from each newly formed node to existing nodes and items need to be calculated at each step, the computing time of pairwise centroid-linkage clustering may be significantly longer than for the other hierarchical clustering methods. Another peculiarity is that (for a distance measure based on the Pearson correlation), the distances do not necessarily increase when going up in the clustering tree, and may even decrease. This is caused by an inconsistency between the centroid calculation and the distance calculation when using the Pearson correlation: Whereas the Pearson correlation effectively normalizes the data for the distance calculation, no such normalization occurs for the centroid calculation. @end itemize For pairwise single-, complete-, and average-linkage clustering, the distance between two nodes can be found directly from the distances between the individual items. Therefore, the clustering algorithm does not need access to the original gene expression data, once the distance matrix is known. For pairwise centroid-linkage clustering, however, the centroids of newly formed subnodes can only be calculated from the original data and not from the distance matrix. The implementation of pairwise single-linkage hierarchical clustering is based on the SLINK algorithm (R. Sibson, 1973), which is much faster and more memory-efficient than a straightforward implementation of pairwise single-linkage clustering. The clustering result produced by this algorithm is identical to the clustering solution found by the conventional single-linkage algorithm. The single-linkage hierarchical clustering algorithm implemented in this library can be used to cluster large gene expression data sets, for which conventional hierarchical clustering algorithms fail due to excessive memory requirements and running time. @section Representing a hierarchical clustering solution The result of hierarchical clustering consists of a tree of nodes, in which each node joins two items or subnodes. Usually, we are not only interested in which items or subnodes are joined at each node, but also in their similarity (or distance) as they are joined. To store one node in the hierarchical clustering tree, we make use of a struct @code{Node}, which has the following members: @itemize @bullet @item @code{int left;} @* First item or subnode. @item @code{int right;} @* Second item or subnode. @item @code{double distance;} @* The distance between the two items or subnodes that were joined. @end itemize @noindent Each item and subnode is represented by an integer. For hierarchical clustering of @math{n} items, we number the original items @math{@{0, @dots{}, n-1@}}, nodes are numbered @math{@{-1, @dots{}, -(n-1)@}}. Note that the number of nodes is one less than the number of items. A hierarchical clustering tree can now be written as an array of @code{Node} structs. The @code{treecluster} routine allocates this array, and returns a @code{Node*} pointer to the first element. The calling function is responsible for deallocating the @code{Node*} array. @section Performing hierarchical clustering: @code{treecluster} The @code{treecluster} routine implements pairwise single-, complete, average-, and centroid-linkage clustering. A pointer @var{distmatrix} to the distance matrix can be passed as one of the arguments to @code{treecluster}; if this pointer is @code{NULL}, the @code{treecluster} routine will calculate the distance matrix from the gene expression data using the arguments @var{data}, @var{mask}, @var{weight}, and @var{dist}. For pairwise single-, complete-, and average-linkage clustering, the @code{treecluster} routine ignores these four arguments if @var{distmatrix} is given, as the distance matrix by itself is sufficient for the clustering calculation. For pairwise centroid-linkage clustering, on the other hand, the arguments @var{data}, @var{mask}, @var{weight}, and @var{dist} are always needed, even if @var{distmatrix} is available. The @code{treecluster} routine will complete faster if it can make use of a previously calculated distance matrix passed as the @var{distmatrix} argument. Note, however, that newly calculated distances are stored in the distance matrix, and its elements may be rearranged during the clustering calculation. Therefore, in order to save the original distance matrix, it should be copied before @code{treecluster} is called. The memory that was allocated by the calling routine for the distance matrix will not be deallocated by @code{treecluster}, and should be deallocated by the calling routine after @code{treecluster} returns. If @var{distmatrix} is @code{NULL}, however, @code{treecluster} takes care both of the allocation and the deallocation of memory for the distance matrix. In that case, @code{treecluster} may fail if not enough memory can be allocated for the distance matrix, in which case @code{treecluster} returns @code{NULL}. @subsubheading Prototype @noindent @code{tree* treecluster (int @var{nrows}, int @var{ncolumns}, double** @var{data}, int** @var{mask}, double @var{weight}[], int @var{transpose}, char @var{dist}, char @var{method}, double** @var{distmatrix});} @subsubheading Arguments @itemize @bullet @item @code{int @var{nrows};} @* The number of rows in the @var{data} matrix, equal to the number of genes in the gene expression experiment. @item @code{int @var{ncolumns};} @* The number of columns in the @var{data} matrix, equal to the number of microarrays in the gene expression experiment. @item @code{double** @var{data};} @* The data array containing the gene expression data. Genes are stored row-wise, while microarrays are stored column-wise. Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{int** @var{mask};} @* This array shows which elements in the @var{data} array, if any, are missing. If @code{@var{mask}[i][j]==0}, then @code{@var{data}[i][j]} is missing. Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{double @var{weight}[];} @* The weights that are used to calculate the distance. Dimension: @code{[@var{ncolumns}]} if @code{@var{transpose}==0}; @code{[@var{nrows}]} if @code{@var{transpose}==1}. @item @code{int @var{transpose};} @* This flag indicates whether row-wise (gene) or column-wise (microarray) clustering is being performed. If @code{@var{transpose}==0}, rows (genes) are being clustered. Otherwise, columns (microarrays) are being clustered. @item @code{char @var{dist};} @* Specifies which distance measure is used. @xref{Distance functions}. @item @code{char @var{method};} @* Specifies which type of hierarchical clustering is used: @itemize @item @code{'s'}: pairwise single-linkage clustering @item @code{'m'}: pairwise maximum- (or complete-) linkage clustering @item @code{'a'}: pairwise average-linkage clustering @item @code{'c'}: pairwise centroid-linkage clustering @end itemize @item @code{double** distmatrix;} @* The distance matrix, stored as a ragged array. This argument is optional; if the distance matrix is not available, it can be passed as @code{NULL}. In that case, @code{treecluster} will allocate memory space for the distance matrix, calculate it from the gene expression data, and deallocate the memory space before returning. If the distance matrix happens to be available, the hierarchical clustering calculation can be completed faster by passing it as the @var{distmatrix} argument. Note that the contents of the distance matrix will be modified by the clustering algorithm in @code{treecluster}. The memory that was allocated for the distance matrix should be deallocated by the calling routine after @code{treecluster} returns. Dimension: Ragged array, @code{[@var{nrows}][]} if @code{@var{transpose}==0}, or @code{[@var{ncolumns}][]} if @code{@var{transpose}==1}. In both cases, the number of columns in each row is equal to the row number (starting from zero). Accordingly, the first row always has zero columns. @end itemize @subsubheading Return value A pointer to a newly allocated @code{tree} structure that describes the calculated hierarchical clustering solution. If @code{treecluster} fails due to a memory allocation error, it returns @code{NULL}. @section Cutting a hierarchical clustering tree: @code{cuttree} The tree structure generated by the hierachical clustering routine @code{treecluster} can be further analyzed by dividing the genes or microarrays into @emph{n} clusters, where @emph{n} is some positive integer less than or equal to the number of items that were clustered. This can be achieved by ignoring the top @tex $n-1$ @end tex @html n-1 @end html linking events in the tree structure, resulting in @emph{n} separated subnodes. The items in each subnode are then assigned to the same cluster. The routine @code{cuttree} determines to which cluster each item is assigned, based on the hierarchical clustering result stored in the tree structure. @subsubheading Prototype @noindent @code{void cuttree (int @var{nelements}, Node* @var{tree}, int @var{nclusters}, int @var{clusterid}[]);} @subsubheading Arguments @itemize @bullet @item @code{int @var{nelements};} @* The number of elements whose clustering results are stored in the hierarchical clustering result @var{tree}. @item @code{Node* @var{tree};} @* The hierarchical clustering solution. Each node @code{@var{tree}[@var{i}]} in the array describes one linking event, with @code{@var{tree}[@var{i}].left} and @code{@var{tree}[@var{i}].right} containing the numbers of the nodes that were joined. The original elements are numbered @{@code{0}, @dots{}, @code{@var{nelements}-1}@}, nodes are numbered @{@code{-1}, @dots{}, @code{-(@var{nelements}-1)}@}. Note that the number of nodes is one less than the number of elements. The @code{cuttree} function performs no error checking of the @var{tree} structure. Dimension: @code{[@var{nelements}-1]}. @item @code{int @var{nclusters};} @* The desired number of clusters. The number of clusters should be positive, and less than or equal to @var{nelements}. @item @code{int @var{clusterid}[];} @* The cluster number to which each element is assigned. Memory space for @var{clusterid} should be allocated before @code{cuttree} is called. Dimension: @code{[@var{nelements}]}. @end itemize @node SOM, PCA, Hierarchical, , @chapter Self-Organizing Maps Self-Organizing Maps (SOMs) were invented by Kohonen to describe neural networks (see for instance Kohonen, 1997). Tamayo (1999) first applied Self-Organizing Maps to gene expression data. SOMs organize items into clusters that are situated in some topology. Usually a rectangular topology is chosen. The clusters generated by SOMs are such that neighboring clusters in the topology are more similar to each other than clusters far from each other in the topology. The first step to calculate a SOM is to randomly assign a data vector to each cluster in the topology. If genes are being clustered, then the number of elements in each data vector is equal to the number of microarrays in the experiment. An SOM is then generated by taking genes one at a time, and finding which cluster in the topology has the closest data vector. The data vector of that cluster, as well as those of the neighboring clusters, are adjusted using the data vector of the gene under consideration. The adjustment is given by @tex $$\Delta \underline{x}_{\rm{cell}} = \tau \cdot \left(\underline{x}_{\rm{gene}} - \underline{x}_{\rm{cell}} \right).$$ @end tex @html

Δxcell = τ (xgene - xcell).

@end html The parameter @tex $\tau$ @end tex @html τ @end html is a parameter that decreases at each iteration step. We have used a simple linear function of the iteration step: @tex $$\tau = \tau_{\rm{init}} \cdot \left(1 - {i \over n}\right),$$ @end tex @html

τ = τinit (1 - i / n ),

@end html in which @tex $\tau_{\rm{init}}$ @end tex @html τinit @end html is the initial value of @tex $\tau$ @end tex @html τ @end html as specified by the user, @emph{i} is the number of the current iteration step, and @emph{n} is the total number of iteration steps to be performed. While changes are made rapidly in the beginning of the iteration, at the end of iteration only small changes are made. All clusters within a radius @emph{R} are adjusted to the gene under consideration. This radius decreases as the calculation progresses as @tex $$R = R_{\rm{max}} \cdot \left(1 - {i \over n}\right),$$ @end tex @html

R = Rmax (1 - i / n ),

@end html in which the maximum radius is defined as @tex $$R_{\rm{max}} = \sqrt{N_x^2 + N_y^2},$$ @end tex @html

Rmax = &sqrt; (Nx2 + Ny2),

@end html where @tex $\left(N_x, N_y\right)$ @end tex @html

(Nx, Ny)

@end html are the dimensions of the rectangle defining the topology. The routine @code{somcluster} carries out the complete SOM algorithm. First it initializes the random number generator. The distance function to be used is specified by @var{dist}. The node data are then initialized using the random number generator. The order in which genes or microarrays are used to modify the SOM is also randomized. The total number of iterations is specified by @var{niter}, given by the user. @subsubheading Prototype @noindent @code{void somcluster (int @var{nrows}, int @var{ncolumns}, double** @var{data}, int** @var{mask}, double @var{weight}[], int @var{transpose}, int @var{nxgrid}, int @var{nygrid}, double @var{inittau}, int @var{niter}, char @var{dist}, double*** @var{celldata}, int @var{clusterid}[][2]);} @subsubheading Arguments @itemize @bullet @item @code{int @var{nrows};} @* The number of rows in the data matrix, equal to the number of genes in the gene expression experiment. @item @code{int @var{ncolumns};} @* The number of columns in the data matrix, equal to the number of microarrays in the gene expression experiment. @item @code{double** @var{data};} @* The data array containing the gene expression data. Genes are stored row-wise, while microarrays are stored column-wise. Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{int** @var{mask};} @* This array shows which elements in the @var{data} array, if any, are missing. If @code{@var{mask}[i][j]==0}, then @code{@var{data}[i][j]} is missing. Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{double @var{weight}[];} @* The weights that are used to calculate the distance. Dimension: @code{[@var{ncolumns}]} if @code{@var{transpose}==0}; @code{[@var{nrows}]} if @code{@var{transpose}==1}. @item @code{int @var{transpose};} @* This flag indicates whether row-wise (gene) or column-wise (microarray) clustering is being performed. If @code{@var{transpose}==0}, rows (genes) are being clustered. Otherwise, columns (microarrays) are being clustered. @item @code{int @var{nxgrid};} @* The number of cells horizontally in the rectangular topology containing the clusters. @item @code{int @var{nygrid};} @* The number of cells vertically in the rectangular topology containing the clusters. @item @code{double @var{inittau};} @* The initial value for the parameter @tex $\tau$ @end tex @html τ @end html that is used in the SOM algorithm. A typical value for @var{inittau} is 0.02, which was used in Michael Eisen's Cluster/TreeView program. @item @code{int @var{niter};} @* The total number of iterations. @item @code{char @var{dist};} @* Specifies which distance measure is used. @xref{Distance functions}. @item @code{double*** @var{celldata};} @* The data vectors of the clusters in the rectangular topology that were found by the SOM algorithm. These correspond to the cluster centroids. The first dimension is the horizontal position of the cluster in the rectangle, the second dimension is the vertical position of the cluster in the rectangle, while the third dimension is the dimension along the data vector. The @code{somcluster} routine does not allocate storage space for the @var{celldata} array. Space should be allocated before calling @code{somcluster}. Alternatively, if @var{celldata} is equal to @code{NULL}, the @code{somcluster} routine allocates space for @var{celldata} and frees it before returning. In that case, @code{somcluster} does not return the data vectors of the clusters that were found. Dimension: @code{[@var{nxgrid}][@var{nygrid}][@var{ncolumns}]} if @code{@var{transpose}==0}, or @code{[@var{nxgrid}][@var{nygrid}][@var{nrows}]} if @code{@var{transpose}==1}. @item @code{int @var{clusterid}[][2];} @* Specifies the cluster to which a gene or microarray was assigned, using two integers to identify the horizontal and vertical position of a cell in the grid for each gene or microarray. Gene or microarrays are assigned to clusters in the rectangular grid by determining which cluster in the rectangular topology has the closest data vector. Space for the @var{clusterid} argument should be allocated before calling @code{somcluster}. If @var{clusterid} is @code{NULL}, the @code{somcluster} routine ignores this argument and does not return the cluster assignments. Dimension: @code{[@var{nrows}][2]} if @code{@var{transpose}==0}; @code{[@var{ncolumns}][2]} if @code{@var{transpose}==1}. @end itemize @node PCA, RNG, SOM, @chapter Principal Component Analysis Principal Component Analysis (PCA) is a widely used technique for analyzing multivariate data. A practical example of applying Principal Component Analysis to gene expression data is presented by Yeung and Ruzzo (2001). In essence, PCA is a coordinate transformation in which each row in the data matrix is written as a linear sum over basis vectors called principal components, which are ordered and chosen such that each maximally explains the remaining variance in the data vectors. For example, an @math{n \times 3} data matrix can be represented as an ellipsoidal cloud of @math{n} points in three dimensional space. The first principal component is the longest axis of the ellipsoid, the second principal component the second longest axis of the ellipsoid, and the third principal component is the shortest axis. Each row in the data matrix can be reconstructed as a suitable linear combination of the principal components. However, in order to reduce the dimensionality of the data, usually only the most important principal components are retained. The remaining variance present in the data is then regarded as unexplained variance. The principal components can be found by calculating the eigenvectors of the covariance matrix of the data. The corresponding eigenvalues determine how much of the variance present in the data is explained by each principal component. Before applying principal component analysis, typically the mean is subtracted from each column in the data matrix. In the example above, this effectively centers the ellipsoidal cloud around its centroid in 3D space, with the principal components describing the variation of points in the ellipsoidal cloud with respect to their centroid. The function @code{pca} below first uses the singular value decomposition to calculate the eigenvalues and eigenvectors of the data matrix. The singular value decomposition is implemented as a translation in C of the Algol procedure @code{svd} (Golub and Reinsch, 1970), which uses Householder bidiagonalization and a variant of the QR algorithm. The principal components, the coordinates of each data vector along the principal components, and the eigenvalues corresponding to the principal components are then evaluated and returned in decreasing order of the magnitude of the eigenvalue. If data centering is desired, the mean should be subtracted from each column in the data matrix before calling the @code{pca} routine. @subsubheading Prototype @noindent @code{int pca(int @var{nrows}, int @var{ncolumns}, double** @var{u}, double** @var{v}, double* @var{w});} @* applies Principal Component Analysis to the data matrix @var{u}. @subsubheading Arguments @itemize @bullet @item @code{int @var{nrows}} @* The number of rows in @code{@var{u}}. @item @code{int @var{ncolumns}} @* The number of columns in @code{u}. @item @code{double** @var{u};} @* On input: @code{@var{u}} is the rectangular matrix to which Principal Component Analysis is to be applied. The function assumes that the mean has already been subtracted of each column, and hence that the mean of each column is zero.@* On output: @* If @code{@var{nrows}} @math{\ge} @code{@var{ncolumns}}, then on output @code{@var{u}} contains the coordinates with respect to the principal components. @* If @code{@var{nrows}} < @code{@var{ncolumns}}, then on output @code{@var{u}} contains the principal component vectors. @* Dimension: @code{[@var{nrows}][@var{ncolumns}]}. @item @code{double** @var{v};} @* Unused on input. @* On output: @* If @code{@var{nrows}} @math{@ge} @code{@var{ncolumns}}, then on output @code{@var{v}} contains the principal component vectors. @* If @code{@var{nrows}} < @code{@var{ncolumns}}, then on output @code{@var{v}} contains the coordinates with respect to the principal components. @* Dimension: @code{[@var{n}][@var{n}]}, where @math{@var{n} = \min(@var{nrows}, @var{ncolumns})}. @item @code{double* @var{w};} @* Unused on input. @* On output: The eigenvalues corresponding to the the principal component vectors. @* Dimension: @code{[@var{n}]}, where @math{@var{n} = \min(@var{nrows}, @var{ncolumns})}. @end itemize If @code{@var{nrows}} @math{\ge} @code{@var{ncolumns}}, then on output the dot product @math{@var{u} \cdot @var{v}} reproduces the data originally passed in through @var{u}. If @code{@var{nrows}} < @code{@var{ncolumns}}, then on output the dot product @math{@var{v} \cdot @var{u}} reproduces the data originally passed in through @var{u}. @subsubheading Return value @noindent The function returns 0 if successful, -1 if memory allocation fails, and a positive integer if the singular value decomposition fails to converge. @node RNG, Python, PCA, @chapter The random number generator The random number generator in the C Clustering Library is used to initialize the @emph{k}-means/medians/medoids clustering algorithm and Self-Organizing Maps (SOMs), as well as to randomly select a gene or microarray in the calculation of a SOM. We need both a generator of uniform random deviates, and a generator whose deviates follow the binomial distribution. The latter can be built, given a uniform random number generator, using the BTPE algorithm by Kachitvichyanukul and Schmeiser (1988). The uniform random number generator in the C Clustering Library is described by L'Ecuyer (1988). The random number generator is initialized automatically during its first call. As the random number generator by L'Ecuyer uses a combination of two multiplicative linear congruential generators, two (integer) seeds are needed for initialization, for which we use the system-supplied random number generator @code{rand} (in the C standard library). We initialize this generator by calling @code{srand} with the epoch time in seconds, and use the first two random numbers generated by @code{rand} as seeds for the uniform random number generator in the C Clustering Library. @node Python, Perl, RNG, @chapter Using the C Clustering Library with Python: Pycluster and Bio.Cluster The C Clustering Library is particularly useful when used as a module to a scripting language. This chapter describes the routines in the C Clustering Library as seen from Python. To make the routines available to Python, install Pycluster (@pxref{Installing the C Clustering Library for Python}). From Python, then type @* @code{>>> from Pycluster import *} @* Pycluster is also available as part of @uref{http://www.biopython.org, Biopython}, in which case you should use @* @code{>>> from Bio.Cluster import *} @* This will give you access to the clustering routines in the C Clustering Library directly from Python. The function @* @noindent @code{>>> version()} @* returns the version number of the C Clustering Library as a string. @section Partitioning algorithms @subsection @emph{k}-means and @emph{k}-medians clustering: @code{kcluster} @noindent @code{@var{clusterid}, @var{error}, @var{nfound} = kcluster (data, nclusters=2, mask=None, weight=None, transpose=0, npass=1, method='a', dist='e', initialid=None)} @* implements the @emph{k}-means and @emph{k}-medians clustering algorithms. @subsubheading Arguments @itemize @bullet @item @code{data} @* Array containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. @item @code{nclusters} @* The number of clusters @emph{k}. @item @code{mask} @* Array of integers showing which data are missing. If @code{mask[i][j]==0}, then @code{data[i][j]} is missing. If @code{mask==None}, then there are no missing data. @item @code{weight} @* contains the weights to be used when calculating distances. If @code{weight==None}, then equal weights are assumed. @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{transpose==0}, genes (rows) are being clustered. If @code{transpose==1}, microarrays (columns) are clustered. @item @code{npass} @* The number of times the @emph{k}-means clustering algorithm is performed, each time with a different (random) initial condition. If @code{initialid} is given, the value of @code{npass} is ignored and the clustering algorithm is run only once, as it behaves deterministically in that case. @item @code{method} @* describes how the center of a cluster is found: @itemize @item @code{method=='a'}: arithmetic mean; @item @code{method=='m'}: median. @end itemize @noindent For other values of @code{method}, the arithmetic mean is used. @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @noindent @item @code{initialid} @* Specifies the initial clustering to be used for the EM algorithm. If @code{initialid==None}, then a different random initial clustering is used for each of the @code{npass} runs of the EM algorithm. If @code{initialid} is not @code{None}, then it should be equal to a 1D array containing the cluster number (between @code{0} and @code{nclusters-1}) for each item. Each cluster should contain at least one item. With the initial clustering specified, the EM algorithm is deterministic. @end itemize @subsubheading Return values @noindent This function returns a tuple @code{(@var{clusterid}, @var{error}, @var{nfound})}. @itemize @bullet @item @code{@var{clusterid}} @* An array containing the number of the cluster to which each gene/microarray was assigned. @item @code{@var{error}} @* The within-cluster sum of distances for the optimal clustering solution. @item @code{@var{nfound}} @* The number of times the optimal solution was found. @end itemize @subsection @emph{k}-medoids clustering: @code{kmedoids} @noindent @code{@var{clusterid}, @var{error}, @var{nfound} = kmedoids (distance, nclusters=2, npass=1, initialid=None)} @* implements the @emph{k}-medoids clustering algorithm. @subsubheading Arguments @itemize @bullet @item @code{distance} @* The matrix containing the distances between the elements. You can specify the distance matrix in three ways: @itemize @item as a 2D Numerical Python array (in which only the left-lower part of the array will be accessed): @* @code{distance = array([[0.0, 1.1, 2.3], @* @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ [1.1, 0.0, 4.5], @* @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ [2.3, 4.5, 0.0]])} @item as a 1D Numerical Python array containing consecutively the distances in the left-lower part of the distance matrix: @* @code{distance = array([1.1, 2.3, 4.5])} @item as a list containing the rows of the left-lower part of the distance matrix: @* @code{distance = [array([]), @* @ @ @ @ @ @ @ @ @ @ @ array([1.1]), @* @ @ @ @ @ @ @ @ @ @ @ array([2.3, 4.5]) @* @ @ @ @ @ @ @ @ @ @ ]} @end itemize These three expressions correspond to the same distance matrix. @item @code{nclusters} @* The number of clusters @emph{k}. @item @code{npass} @* The number of times the @emph{k}-medoids clustering algorithm is performed, each time with a different (random) initial condition. If @code{initialid} is given, the value of @code{npass} is ignored, as the clustering algorithm behaves deterministically in that case. @item @code{initialid} @* Specifies the initial clustering to be used for the EM algorithm. If @code{initialid==None}, then a different random initial clustering is used for each of the @code{npass} runs of the EM algorithm. If @code{initialid} is not @code{None}, then it should be equal to a 1D array containing the cluster number (between @code{0} and @code{nclusters-1}) for each item. Each cluster should contain at least one item. With the initial clustering specified, the EM algorithm is deterministic. @end itemize @subsubheading Return values @noindent This function returns a tuple @code{(@var{clusterid}, @var{error}, @var{nfound})}. @itemize @bullet @item @code{@var{clusterid}} @* An array containing the number of the cluster to which each item was assigned, where the cluster number is defined as the item number of the item representing the cluster centroid. @item @code{@var{error}} @* The within-cluster sum of distances for the optimal @emph{k}-medoids clustering solution. @item @code{@var{nfound}} @* The number of times the optimal solution was found. @end itemize @section Hierarchical clustering The pairwise single-, maximum-, average-, and centroid-linkage clustering methods are accessible through the function @code{treecluster}. The hierarchical clustering routines can be applied either on the original gene expression data, or (except for centroid-linkage clustering) on the distance matrix directly. The tree structure generated by @code{treecluster} can be cut in order to separate the elements into a given number of clusters. @subsection Representing a hierarchical clustering solution A hierarchical clustering solution is represented using two Python classes: @code{Node} and @code{Tree}. @subheading The class @code{Node} The Python class @code{Node} corresponds to the C struct @code{Node} described above. A @code{Node} object has three attributes: @itemize @bullet @item left @item right @item distance @end itemize @noindent Here, @code{left} and @code{right} are integers referring to the two items or subnodes that are joined at this node, and @code{distance} is the distance between them. The items being clustered are numbered from @code{0} to @code{(@emph{number of items} - 1)}, while clusters are numbered @code{-1} to @code{-(@emph{number of items}-1)}. To create a new @code{Node} object, we need to specify @code{left} and @code{right}; @code{distance} is optional. @noindent @code{>>> from Pycluster import * @* >>> Node(2,3) @* (2, 3): 0 @* >>> Node(2,3,0.91) @* (2, 3): 0.91 } The attributes @code{left}, @code{right}, and @code{distance} of an existing @code{Node} object can be modified directly: @noindent @code{>>> node = Node(4,5) @* >>> node.left = 6 @* >>> node.right = 2 @* >>> node.distance = 0.73 @* >>> node @* (6, 2): 0.73 @* } @noindent An error is raised if @code{left} and @code{right} are not integers, or if @code{distance} cannot be converted to a floating-point value. @subheading The class @code{Tree} The Python class @code{Tree} represents a full hierarchical clustering solution. A @code{Tree} object can be created from a list of @code{Node} objects: @noindent @code{>>> nodes = [Node(1,2,0.2), Node(0,3,0.5), Node(-2,4,0.6), Node(-1,-3,0.9)] @* >>> tree = Tree(nodes) @* >>> print tree @* (1, 2): 0.2 @* (0, 3): 0.5 @* (-2, 4): 0.6 @* (-1, -3): 0.9} The @code{Tree} initializer checks if the list of nodes is a valid hierarchical clustering result: @noindent @code{>>> nodes = [Node(1,2,0.2), Node(0,2,0.5)] @* >>> Tree(nodes) @* Traceback (most recent call last): @* File "", line 1, in ? @* cluster.error: Inconsistent tree} Individual nodes in a @code{Tree} object can be accessed using square brackets: @noindent @code{>>> nodes = [Node(1,2,0.2), Node(0,-1,0.5)] @* >>> tree = Tree(nodes) @* >>> tree[0] @* (1, 2): 0.2 @* >>> tree[1] @* (0, -1): 0.5 @* >>> tree[-1] @* (0, -1): 0.5} @noindent As a @code{Tree} object is read-only, we cannot change individual nodes in a @code{Tree} object. However, we can convert the tree to a list of nodes, modify this list, and create a new tree from this list: @noindent @code{>>> tree = Tree([Node(1,2,0.1), Node(0,-1,0.5), Node(-2,3,0.9)]) @* >>> print tree @* (1, 2): 0.1 @* (0, -1): 0.5 @* (-2, 3): 0.9 @* >>> nodes = tree[:] @* >>> nodes[0] = Node(0,1,0.2) @* >>> nodes[1].left = 2 @* >>> tree = Tree(nodes) @* >>> print tree @* (0, 1): 0.2 @* (2, -1): 0.5 @* (-2, 3): 0.9} @noindent This guarantees that any @code{Tree} object is always well-formed. A @code{Tree} object has two methods (@code{scale} and @code{cut}, described below). The @code{treecluster} function returns @code{Tree} objects. @subsection Performing hierarchical clustering: @code{treecluster} @noindent @code{@var{tree} = treecluster(data=None, mask=None, weight=None, transpose=0, method='m', dist='e', distancematrix=None)} @* implements the hierachical clustering methods. @subsubheading Arguments @itemize @bullet @item @code{data} @* Array containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. Either @code{data} or @code{distancematrix} should be @code{None}. @item @code{mask} @* Array of integers showing which data are missing. If @code{mask[i][j]==0}, then @code{data[i][j]} is missing. If @code{mask==None}, then there are no missing data. @item @code{weight} @* contains the weights to be used when calculating distances. If @code{weight==None}, then equal weights are assumed. @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{transpose==0}, genes (rows) are being clustered. If @code{transpose==1}, microarrays (columns) are clustered. @item @code{method} @* defines the linkage method to be used: @itemize @item @code{method=='s'}: pairwise single-linkage clustering @item @code{method=='m'}: pairwise maximum- (or complete-) linkage clustering @item @code{method=='c'}: pairwise centroid-linkage clustering @item @code{method=='a'}: pairwise average-linkage clustering @end itemize @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @item @code{distancematrix} @* The distance matrix. Either @code{data} or @code{distancematrix} should be @code{None}. If @code{data} is @code{None} and @code{distancematrix} is given, the arguments @code{mask}, @code{weights}, @code{transpose}, and @code{dist} are ignored. Note that pairwise single-, maximum-, and average-linkage clustering can be calculated from the distance matrix, but pairwise centroid-linkage cannot. If not @code{None}, @code{distancematrix} should correspond to a distance matrix, which can be specified in three ways: @itemize @item as a 2D Numerical Python array (in which only the left-lower part of the array will be accessed): @* @code{distance = array([[0.0, 1.1, 2.3], @* @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ [1.1, 0.0, 4.5], @* @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ [2.3, 4.5, 0.0]])} @item as a 1D Numerical Python array containing consecutively the distances in the left-lower part of the distance matrix: @* @code{distance = array([1.1, 2.3, 4.5])} @item as a list containing the rows of the left-lower part of the distance matrix: @* @code{distance = [array([]), @* @ @ @ @ @ @ @ @ @ @ @ array([1.1]), @* @ @ @ @ @ @ @ @ @ @ @ array([2.3, 4.5]) @* @ @ @ @ @ @ @ @ @ @ ]} @end itemize These three expressions correspond to the same distance matrix. As @code{treecluster} may shuffle the values in the distance matrix as part of the clustering algorithm, be sure to save this array in a different variable before calling @code{treecluster} if you need it later. @end itemize @subsubheading Return values @noindent This function returns a @code{Tree} object. This object contains @code{@emph{number of items} - 1} nodes, where the number of items is the number of genes if genes were clustered, or the number of microarrays if microarrays were clustered. Each node describes a pairwise linking event, where the node attributes @code{left} and @code{right} each contain the number of one gene/microarray or subnode, and @code{distance} the distance between them. Genes/microarrays are numbered from @code{0} to @code{(@emph{number of items} - 1)}, while clusters are numbered @code{-1} to @code{-(@emph{number of items}-1)}. @subsection Scaling a hierarchical clustering tree: @code{@var{tree}.scale} To display a hierarchical clustering solution with Java TreeView, it is better to scale all node distances such that they are between zero and one. This can be accomplished by calling the @code{scale} method on an existing @code{Tree} object. @noindent @code{@var{tree}.scale()} @* scales the distances in the hierarchical clustering tree such that they are all between zero and one. This function takes no arguments, and returns @code{None}. @subsection Cutting a hierarchical clustering tree: @code{@var{tree}.cut} @noindent @code{@var{clusterid} = @var{tree}.cut(nclusters=1)} @* groups the items into @code{nclusters} clusters based on the tree structure generated by the hierarchical clustering routine @code{treecluster}. @subsubheading Arguments @itemize @bullet @item @code{@var{tree}} @* The @code{Tree} object @code{@var{tree}} contains the hierarchical clustering result generated by @code{treecluster}. Each node in this tree describes a pairwise linking event, where the node attributes @code{left} and @code{right} contain the number of the two items or subnodes. Items are numbered from 0 to (@code{@emph{number of elements}} - 1), while clusters are numbered -1 to -(@code{@emph{number of elements}}-1). @item @code{nclusters} @* The desired number of clusters; @code{nclusters} should be positive, and less than or equal to the number of elements. @end itemize @subsubheading Return values @noindent This function returns the array @code{@var{clusterid}}. @itemize @bullet @item @code{@var{clusterid}} @* An array containing the number of the cluster to which each gene/microarray is assigned. @end itemize @section Self-Organizing Maps: @code{somcluster} @noindent @code{@var{clusterid}, @var{celldata} = somcluster(data, mask=None, weight=None, transpose=0, nxgrid=2, nygrid=1, inittau=0.02, niter=1, dist='e')} @* implements a Self-Organizing Map on a rectangular grid. @subsubheading Arguments @itemize @bullet @item @code{data} @* Array containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. @item @code{mask} @* Array of integers showing which data are missing. If @code{mask[i][j]==0}, then @code{data[i][j]} is missing. If @code{mask==None}, then there are no missing data. @item @code{weight} @* contains the weights to be used when calculating distances. If @code{weight==None}, then equal weights are assumed. @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{transpose==0}, genes (rows) are being clustered. If @code{transpose==1}, microarrays (columns) are clustered. @item @code{nxgrid, nygrid} @* The number of cells horizontally and vertically in the rectangular grid, on which the Self-Organizing Map is calculated. @item @code{inittau} @* The initial value for the parameter @tex $\tau$ @end tex @html τ @end html that is used in the SOM algorithm. The default value for @code{inittau} is 0.02, which was used in Michael Eisen's Cluster/TreeView program. @item @code{niter} @* The number of iterations to be performed. @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @end itemize @subsubheading Return values @noindent This function returns the tuple @code{@var{clusterid}, @var{celldata}}. @itemize @bullet @item @code{@var{clusterid}} @* An array with two columns, where the number of rows is equal to the number of genes or the number of microarrays depending on whether genes or microarrays are being clustered. Each row contains the @emph{x} and @emph{y} coordinates of the cell in the rectangular SOM grid to which the gene or microarray was assigned. @item @code{@var{celldata}} @* An array with dimensions (@code{nxgrid}, @code{nygrid}, @code{@emph{number of microarrays}}) if genes are being clustered, or (@code{nxgrid}, @code{nygrid}, @code{@emph{number of genes}}) if microarrays are being clustered. Each element @code{[ix][iy]} of this array is a 1D vector containing the gene expression data for the centroid of the cluster in the grid cell with coordinates (@var{ix,iy}). @end itemize @section Finding the cluster centroids: @code{clustercentroids} @noindent @code{cdata, cmask = clustercentroids(data, mask=None, clusterid=None, method='a', transpose=0)} @* calculates the cluster centroids. @subsubheading Arguments @itemize @bullet @* @item @code{data} @* Array containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. @item @code{mask} @* Array of integers showing which data are missing. If @code{mask[i][j]==0}, then @code{data[i][j]} is missing. If @code{mask==None}, then there are no missing data. @item @code{clusterid} @* Vector of integers showing to which cluster each element belongs. If @code{clusterid} is not given, then all elements are assumed to belong to the same cluster. @item @code{method} @* Specifies whether the arithmetic mean (@code{method=='a'}) or the median (@code{method=='m'}) is used to calculate the cluster center. @item @code{transpose} @* Determines if gene or microarray clusters are being considered. If @code{transpose==0}, then we are considering clusters of genes (rows). If @code{transpose==1}, then we are considering clusters of microarrays (columns). @end itemize @subsubheading Return values @noindent This function returns the tuple @code{@var{cdata}, @var{cmask}}. @itemize @bullet @item @code{@var{cdata}} @* A 2D array containing the centroid data. The dimensions of this array are @code{(@emph{number of clusters}, @emph{number of microarrays})} if genes were clustered, or @code{(@emph{number of genes}, @emph{number of clusters})} if microarrays were clustered. Each row (if genes were clustered) or column (if microarrays were clustered) contains the averaged gene expression data for corresponding to the centroid of one cluster that was found. @item @code{@var{cmask}} @* This matrix stores which values in @code{@var{cdata}} are missing. If @code{@var{cmask}[i][j]==0}, then @code{@var{cdata}[i][j]} is missing. The dimensions of this array are @code{(@emph{number of clusters}, @var{number of microarrays})} if genes were clustered, or @code{(@var{number of genes}, @var{number of clusters})} if microarrays were clustered. @end itemize @section The distance between two clusters: @code{clusterdistance} @noindent @code{@var{distance} = clusterdistance(data, mask=None, weight=None, index1=[0], index2=[0], method='a', dist='e', transpose=0)} @* calculates the distance between two clusters. @subsubheading Arguments @itemize @bullet @item @code{data} @* Array containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. @item @code{mask} @* Array of integers showing which data are missing. If @code{mask[i][j]==0}, then @code{data[i][j]} is missing. If @code{mask==None}, then there are no missing data. @item @code{weight} @* contains the weights to be used when calculating distances. If @code{weight==None}, then equal weights are assumed. @item @code{index1} @* is a list containing the indices of the elements belonging to the first cluster. A cluster containing only one element @var{i} can be represented as either a list @code{[@var{i}]}, or as an integer @code{@var{i}}. @item @code{index2} @* is a list containing the indices of the elements belonging to the second cluster. A cluster containing only one element @var{i} can be represented as either a list @code{[@var{i}]}, or as an integer @code{@var{i}}. @item @code{method} @* Specifies how the distance between clusters is defined: @itemize @item @code{method=='a'}: Distance between the two cluster centroids (arithmetic mean); @item @code{method=='m'}: Distance between the two cluster centroids (median); @item @code{method=='s'}: Shortest pairwise distance between elements in the two clusters; @item @code{method=='x'}: Longest pairwise distance between elements in the two clusters; @item @code{method=='v'}: Average over the pairwise distances between elements in the two clusters. @end itemize @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @item @code{transpose} @* Determines if gene or microarray clusters are being considered. If @code{transpose==0}, then we are considering clusters of genes (rows). If @code{transpose==1}, then we are considering clusters of microarrays (columns). @end itemize @subsubheading Return values @noindent This function returns the distance between the two clusters. @section Calculating the distance matrix: @code{distancematrix} @noindent @code{@var{matrix} = distancematrix(data, mask=None, weight=None, transpose=0, dist='e')} @* returns the distance matrix between gene expression data. @subsubheading Arguments @itemize @bullet @item @code{data} @* Array containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. @item @code{mask} @* Array of integers showing which data are missing. If @code{mask[i][j]==0}, then @code{data[i][j]} is missing. If @code{mask==None}, then there are no missing data. @item @code{weight} @* contains the weights to be used when calculating distances. If @code{weight==None}, then equal weights are assumed. @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{transpose==0}, genes (rows) are being clustered. If @code{transpose==1}, microarrays (columns) are clustered. @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @end itemize @subsubheading Return values @itemize @bullet @item @code{@var{matrix}} is a list of 1D arrays containing the distance matrix between the gene expression data. The number of columns in each row is equal to the row number. Hence, the first row has zero elements. An example of the return value is @* @code{@var{matrix} = [array([]), @* @ @ @ @ @ @ @ @ @ @ array([1.]), @* @ @ @ @ @ @ @ @ @ @ array([7., 3.]), @* @ @ @ @ @ @ @ @ @ @ array([4., 2., 6.])] @*} This corresponds to the distance matrix @tex $$ \pmatrix{ 0 & 1 & 7 & 4 \cr 1 & 0 & 3 & 2 \cr 7 & 3 & 0 & 6 \cr 4 & 2 & 6 & 0} $$ @end tex @html

[0., 1., 7., 4.]
[1., 0., 3., 2.]
[7., 3., 0., 6.]
[4., 2., 6., 0.];

@end html @end itemize @section Principal Component Analysis: @code{pca} @noindent @code{@var{columnmean, coordinates, components, eigenvalues} = pca(data)} @* applies Principal Component Analysis to the rectangular matrix @code{data}. @subsubheading Arguments @itemize @bullet @item @code{data} @* Array containing the data to which the Principal Component Analysis is to be applied. @end itemize @subsubheading Return values The function returns a tuple @var{columnmean}, @var{coordinates}, @var{components}, @var{eigenvalues}. @itemize @bullet @item @var{columnmean} @* Array containing the mean over each column in @code{data}. @item @var{coordinates} @* The coordinates of each row in @code{data} with respect to the principal components. @item @var{components} @* The principal components. @item @var{eigenvalues} @* The eigenvalues corresponding to each of the principal components. @end itemize The original matrix @code{data} can be recreated by calculating @code{@var{columnmean} + dot(@var{coordinates}, @var{components})}. @section Handling Cluster/TreeView-type files Cluster/TreeView are GUI-based codes for clustering gene expression data. They were originally written by @uref{http://rana.lbl.gov, Michael Eisen} while at Stanford University. Pycluster contains functions for reading and writing data files that correspond to the format specified for Cluster/TreeView. In particular, by saving a clustering result in that format, TreeView can be used to visualize the clustering results. We recommend using Alok Saldanha's @uref{http://jtreeview.sourceforge.net/, Java TreeView program}, which can display hierarchical as well as @emph{k}-means clustering results. @subsection The @code{Record} class An object of the class @code{Record} contains all information stored in a Cluster/TreeView-type data file. To store the information contained in the data file in a @code{Record} object, we first open the file and then read it: @code{ @noindent >>> import Pycluster @* >>> @var{handle} = open("mydatafile.txt") @* >>> @var{record} = Pycluster.read(@var{handle}) @* } This two-step process gives you some flexibility in the source of the data. For example, you can use @code{ @noindent >>> import gzip # Python standard library @* >>> @var{handle} = gzip.open("mydatafile.txt.gz") @* } to open a gzipped file, or @code{ @noindent >>> import urllib # Python standard library @* >>> @var{handle} = urllib.urlopen("http://somewhere.org/mydatafile.txt") @* } to open a file stored on the Internet before calling @code{read}. If you're using the C Clustering Library from Biopython, you should use: @code{ @noindent >>> from Bio import Cluster @* >>> @var{record} = Cluster.read(@var{handle}) @* } The @code{read} command reads the tab-delimited text file @code{mydatafile.txt} containing gene expression data in the format specified for Michael Eisen's Cluster/TreeView program. For a description of this file format, see the manual to Cluster/TreeView. It is available at @uref{http://rana.lbl.gov/manuals/ClusterTreeView.pdf, Michael Eisen's lab website} and at @uref{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/cluster3.pdf, our website}. A @code{Record} object stores the following information: @itemize @bullet @item @code{data} @* The data array containing the gene expression data. Genes are stored row-wise, while microarrays are stored column-wise. @item @code{mask} @* This array shows which elements in the @code{data} array, if any, are missing. If @code{mask[i,j]==0}, then @code{data[i,j]} is missing. If no data were found to be missing, @code{mask} is set to @code{None}. @item @code{geneid} @* This is a list containing a unique description for each gene (i.e., ORF numbers). @item @code{genename} @* This is a list containing a description for each gene (i.e., gene name). If not present in the data file, @code{genename} is set to @code{None}. @item @code{gweight} @* The weights that are to be used to calculate the distance in expression profile between genes. If not present in the data file, @code{gweight} is set to @code{None}. @item @code{gorder} @* The preferred order in which genes should be stored in an output file. If not present in the data file, @code{gorder} is set to @code{None}. @item @code{expid} @* This is a list containing a description of each microarray, e.g. experimental condition. @item @code{eweight} @* The weights that are to be used to calculate the distance in expression profile between microarrays. If not present in the data file, @code{eweight} is set to @code{None}. @item @code{eorder} @* The preferred order in which microarrays should be stored in an output file. If not present in the data file, @code{eorder} is set to @code{None}. @item @code{uniqid} @* The string that was used instead of UNIQID in the data file. @end itemize After loading a @code{Record} object, each of these attributes can be accessed and modified directly. For example, the data can be log-transformed by taking the logarithm of @code{@var{record}.data}. @subsection Performing hierarchical clustering @noindent @code{@var{tree} = @var{record}.treecluster(transpose=0, method='m', dist='e')} @* applies hierachical clustering to the data contained in the @code{Record} object. @subsubheading Arguments @itemize @bullet @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{transpose==0}, genes (rows) are being clustered. If @code{transpose==1}, microarrays (columns) are clustered. @item @code{method} @* defines the linkage method to be used: @itemize @item @code{method=='s'}: pairwise single-linkage clustering @item @code{method=='m'}: pairwise maximum- (or complete-) linkage clustering @item @code{method=='c'}: pairwise centroid-linkage clustering @item @code{method=='a'}: pairwise average-linkage clustering @end itemize @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @end itemize @subsubheading Return values @noindent This method returns a @code{Tree} object containing @code{@emph{number of items} - 1} nodes, where the number of items is the number of genes if genes were clustered, or the number of microarrays if microarrays were clustered. Each node describes a pairwise linking event, where the node attributes @code{left} and @code{right} each contain the number of one gene/microarray or subnode, and @code{distance} the distance between them. Genes/microarrays are numbered from @code{0} to @code{(@emph{number of items} - 1)}, while clusters are numbered @code{-1} to @code{-(@emph{number of items}-1)}. @subsection Performing @emph{k}-means or @emph{k}-medians clustering @noindent @code{@var{clusterid}, @var{error}, @var{nfound} = @var{record}.kcluster(nclusters=2, transpose=0, npass=1, method='a', dist='e', initialid=None)} @* applies @emph{k}-means or @emph{k}-medians clustering to the data contained in the @code{Record} object. @subsubheading Arguments @itemize @bullet @item @code{nclusters} @* The number of clusters @emph{k}. @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{transpose==0}, genes (rows) are being clustered. If @code{transpose==1}, microarrays (columns) are clustered. @item @code{npass} @* The number of times the @emph{k}-means clustering algorithm is performed, each time with a different (random) initial condition. If @code{initialid} is given, the value of @code{npass} is ignored and the clustering algorithm is run only once, as it behaves deterministically in that case. @item @code{method} @* describes how the center of a cluster is found: @itemize @item @code{method=='a'}: arithmetic mean; @item @code{method=='m'}: median. @end itemize @noindent For other values of @code{method}, the arithmetic mean is used. @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @noindent @item @code{initialid} @* Specifies the initial clustering to be used for the EM algorithm. If @code{initialid==None}, then a different random initial clustering is used for each of the @code{npass} runs of the EM algorithm. If @code{initialid} is not @code{None}, then it should be equal to a 1D array containing the cluster number (between @code{0} and @code{nclusters-1}) for each item. Each cluster should contain at least one item. With the initial clustering specified, the EM algorithm is deterministic. @end itemize @subsubheading Return values @noindent This function returns a tuple @code{(@var{clusterid}, @var{error}, @var{nfound})}. @itemize @bullet @item @code{@var{clusterid}} @* An array containing the number of the cluster to which each gene/microarray was assigned. @item @code{@var{error}} @* The within-cluster sum of distances for the optimal clustering solution. @item @code{@var{nfound}} @* The number of times the optimal solution was found. @end itemize @subsection Calculating a Self-Organizing Map @noindent @code{@var{clusterid}, @var{celldata} = @var{record}.somcluster(transpose=0, nxgrid=2, nygrid=1, inittau=0.02, niter=1, dist='e')} @* calculates a Self-Organizing Map on a rectangular grid, using the gene expression data in the @code{Record} object @var{record}. @subsubheading Arguments @itemize @bullet @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{transpose==0}, genes (rows) are being clustered. If @code{transpose==1}, microarrays (columns) are clustered. @item @code{nxgrid, nygrid} @* The number of cells horizontally and vertically in the rectangular grid, on which the Self-Organizing Map is calculated. @item @code{inittau} @* The initial value for the parameter @tex $\tau$ @end tex @html τ @end html that is used in the SOM algorithm. The default value for @code{inittau} is 0.02, which was used in Michael Eisen's Cluster/TreeView program. @item @code{niter} @* The number of iterations to be performed. @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @end itemize @subsubheading Return values @noindent This function returns the tuple @code{@var{clusterid}, @var{celldata}}. @itemize @bullet @item @code{@var{clusterid}} @* An array with two columns, where the number of rows is equal to the number of genes or the number of microarrays depending on whether genes or microarrays are being clustered. Each row contains the @emph{x} and @emph{y} coordinates of the cell in the rectangular SOM grid to which the gene or microarray was assigned. @item @code{@var{celldata}} @* An array with dimensions (@code{nxgrid}, @code{nygrid}, @code{@emph{number of microarrays}}) if genes are being clustered, or (@code{nxgrid}, @code{nygrid}, @code{@emph{number of genes}}) if microarrays are being clustered. Each element @code{[ix][iy]} of this array is a 1D vector containing the gene expression data for the centroid of the cluster in the grid cell with coordinates (@var{ix,iy}). @end itemize @subsection Finding the cluster centroid @noindent @code{@var{cdata}, @var{cmask} = @var{record}.clustercentroids(clusterid=None, method='a', transpose=0)} @* calculates the cluster centroids. @subsubheading Arguments @itemize @bullet @* @item @code{clusterid} @* Vector of integers showing to which cluster each element belongs. If @code{clusterid} is not given, then all elements are assumed to belong to the same cluster. @item @code{method} @* Specifies whether the arithmetic mean (@code{method=='a'}) or the median (@code{method=='m'}) is used to calculate the cluster center. @item @code{transpose} @* Determines if gene or microarray clusters are being considered. If @code{transpose==0}, then we are considering clusters of genes (rows). If @code{transpose==1}, then we are considering clusters of microarrays (columns). @end itemize @subsubheading Return values @noindent This function returns the tuple @code{@var{cdata}, @var{cmask}}. @itemize @bullet @item @code{@var{cdata}} @* A 2D array containing the centroid data. The dimensions of this array are @code{(@emph{number of clusters}, @emph{number of microarrays})} if genes were clustered, or @code{(@emph{number of genes}, @emph{number of clusters})} if microarrays were clustered. Each row (if genes were clustered) or column (if microarrays were clustered) contains the averaged gene expression data for corresponding to the centroid of one cluster that was found. @item @code{@var{cmask}} @* This matrix stores which values in @code{@var{cdata}} are missing. If @code{@var{cmask}[i][j]==0}, then @code{@var{cdata}[i][j]} is missing. The dimensions of this array are @code{(@emph{number of clusters}, @emph{number of microarrays})} if genes were clustered, or @code{(@emph{number of genes}, @emph{number of clusters})} if microarrays were clustered. @end itemize @subsection Calculating the distance between two clusters @noindent @code{@var{distance} = @var{record}.clusterdistance(index1=[0], index2=[0], method='a', dist='e', transpose=0)} @* calculates the distance between two clusters. @subsubheading Arguments @itemize @bullet @item @code{index1} @* is a list containing the indices of the elements belonging to the first cluster. A cluster containing only one element @var{i} can be represented as either a list @code{[@var{i}]}, or as an integer @code{@var{i}}. @item @code{index2} @* is a list containing the indices of the elements belonging to the second cluster. A cluster containing only one element @var{i} can be represented as either a list @code{[@var{i}]}, or as an integer @code{@var{i}}. @item @code{method} @* Specifies how the distance between clusters is defined: @itemize @item @code{method=='a'}: Distance between the two cluster centroids (arithmetic mean); @item @code{method=='m'}: Distance between the two cluster centroids (median); @item @code{method=='s'}: Shortest pairwise distance between elements in the two clusters; @item @code{method=='x'}: Longest pairwise distance between elements in the two clusters; @item @code{method=='v'}: Average over the pairwise distances between elements in the two clusters. @end itemize @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @item @code{transpose} @* Determines if gene or microarray clusters are being considered. If @code{transpose==0}, then we are considering clusters of genes (rows). If @code{transpose==1}, then we are considering clusters of microarrays (columns). @end itemize @subsubheading Return values @noindent This function returns the distance between the two clusters. @subsection Calculating the distance matrix @noindent @code{@var{matrix} = @var{record}.distancematrix(transpose=0, dist='e')} @* returns the distance matrix between gene expression data. @subsubheading Arguments @itemize @bullet @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{transpose==0}, genes (rows) are being clustered. If @code{transpose==1}, microarrays (columns) are clustered. @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @end itemize @subsubheading Return values @itemize @bullet @item @var{matrix} is a list of 1D arrays containing the distance matrix between the gene expression data. The number of columns in each row is equal to the row number. Hence, the first row has zero elements. An example of the return value is @* @code{@var{matrix} = [array([]), @* @ @ @ @ @ @ @ @ @ array([1.]), @* @ @ @ @ @ @ @ @ @ array([7., 3.]), @* @ @ @ @ @ @ @ @ @ array([4., 2., 6.])] @*} This corresponds to the distance matrix @tex $$ \pmatrix{ 0 & 1 & 7 & 4 \cr 1 & 0 & 3 & 2 \cr 7 & 3 & 0 & 6 \cr 4 & 2 & 6 & 0} $$ @end tex @html

[0., 1., 7., 4.]
[1., 0., 3., 2.]
[7., 3., 0., 6.]
[4., 2., 6., 0.];

@end html @end itemize @subsection Saving the clustering result @noindent @code{@var{record}.save(jobname, geneclusters, expclusters)} @* writes the text file @var{jobname}@code{.cdt}, @var{jobname}@code{.gtr}, @var{jobname}@code{.atr}, @var{jobname*}@code{.kgg}, and/or @var{jobname*}@code{.kag} for subsequent reading by the Java TreeView program. If @code{geneclusters} and @code{expclusters} are both @code{None}, this method only writes the text file @var{jobname}@code{.cdt}; this file can subsequently be read into a new @code{Record} object. @subsubheading Arguments @itemize @bullet @item @code{jobname} @* The string @code{jobname} is used as the base name for names of the files that are to be saved. @item @code{geneclusters} @* This argument describes the gene clustering result. In case of @emph{k}-means clustering, this is a 1D array containing the number of the cluster each gene belongs to. It can be calculated using @code{kcluster}. In case of hierarchical clustering, @code{geneclusters} is a @code{Tree} object. @item @code{expclusters} @* This argument describes the clustering result for the experimental conditions. In case of @emph{k}-means clustering, this is a 1D array containing the number of the cluster each experimental condition belongs to. It can be calculated using @code{kcluster}. In case of hierarchical clustering, @code{expclusters} is a @code{Tree} object. @end itemize @subsection Example calculation This is an example of a hierarchical clustering calculation, using single linkage clustering for genes and maximum linkage clustering for experimental conditions. As the Euclidean distance is being used for gene clustering, it is necessary to scale the node distances @code{genetree} such that they are all between zero and one. This is needed for the Java TreeView code to display the tree diagram correctly. To cluster the experimental conditions, the uncentered correlation is being used. No scaling is needed in this case, as the distances in @code{exptree} are already between zero and two. The example data @code{cyano.txt} can be found in the @code{data} subdirectory. @noindent @code{>>> from Pycluster import * @* >>> handle = open("cyano.txt") @* >>> record = read(handle) @* >>> genetree = record.treecluster(method='s') @* >>> genetree.scale() @* >>> exptree = record.treecluster(dist='u', transpose=1) @* >>> record.save("cyano_result", genetree, exptree) } @noindent This will create the files @code{cyano_result.cdt}, @code{cyano_result.gtr}, and @code{cyano_result.atr}. Similarly, we can save a @emph{k}-means clustering solution: @noindent @code{>>> from Pycluster import * @* >>> handle = open("cyano.txt") @* >>> record = read(handle) @* >>> (geneclusters, error, ifound) = record.kcluster(nclusters=5, npass=1000) @* >>> (expclusters, error, ifound) = record.kcluster(nclusters=2, npass=100, transpose=1) @* >>> record.save("cyano_result", geneclusters, expclusters) } @noindent This will create the files @code{cyano_result_K_G2_A2.cdt}, @code{cyano_result_K_G2.kgg}, and @code{cyano_result_K_A2.kag}. @node Perl, Building, Python, @chapter Using the C Clustering Library with Perl: Algorithm::Cluster Algorithm::Cluster is a Perl wrapper extension of the C Clustering Library written by John Nolan of the University of California, Santa Cruz. Algorithm::Cluster requires Perl 5.6.0 at a minimum. It will not compile properly with 5.005_03 or previous versions or Perl. It has been tested on Win32, Mac OS X, Linux, OpenBSD and Solaris. To install Algorithm::Cluster on UNIX, Linux, Mac OS X, or Cygwin, you can download the source code from @url{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster}. You will need an ANSI C compiler; GNU's free @code{gcc} compiler will do. Unpack the distribution and type the following familiar commands to compile, test and install the module: @* @code{perl Makefile.PL} @* @code{make} @* @code{make test} @* @code{make install} @* You can also use the CPAN shell from within Perl to download the module and install it. If you use ActiveState Perl on Windows, use the Perl Package Manager @code{ppm} to install Algorithm::Cluster by executing the following command from the DOS command prompt. @* @noindent @code{ppm install http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/Algorithm-Cluster.ppd} @* Algorithm::Cluster offers the following functions: @itemize @bullet @item @code{kcluster} @item @code{kmedoids} @item @code{treecluster} @item @code{somcluster} @item @code{clustercentroids} @item @code{clusterdistance} @item @code{distancematrix} @item @code{pca} @item @code{mean} @item @code{median} @end itemize You can also use Algorithm::Cluster to read expression data files and to write the clustering solution to a file; see below for details. @section Using named parameters Most of the interface functions in Algorithm::Cluster expect named parameters. This is implemented by passing a hash as a parameter to the function. For example, if a Perl function @code{sign_up()} accepts three named parameters, @code{name}, @code{program} and @code{class}, then you can invoke the function like this: @* @* @code{$return_value = sign_up( @* @ @ @ @ @ @ @ @ 'name' => 'Mr. Smith', @* @ @ @ @ @ @ @ @ 'program' => 'Biology', @* @ @ @ @ @ @ @ @ 'class' => 'Intro to Molecular Biology', @* ); } When the function parses its parameters, it will create a hash, on the fly, with three keys. The function can access the values by referring to the hash. This is convenient for several reasons. First, it means that you can pass the parameters in any order. Both invocations below are valid: @* @* @code{$return_value = sign _up( @* @ @ @ @ @ @ @ @ 'class' => 'Intro to Molecular Biology', @* @ @ @ @ @ @ @ @ 'name' => 'Ms. Jones', @* @ @ @ @ @ @ @ @ 'program' => 'Biology', @* ); @* $return_value = sign _up( @* @ @ @ @ @ @ @ @ 'name' => 'Miss Chen', @* @ @ @ @ @ @ @ @ 'program' => 'Biology', @* @ @ @ @ @ @ @ @ 'class' => 'Intro to Molecular Biology', @* );} If the function defines default values for parameters, you can also leave some parameters out, and the function will still know which parameter is which: @* @* @code{$return_value = sign_up( @* @ @ @ @ @ @ @ @ 'name' => 'Ms. Jones', @* );} You can define the hash on your own, and pass this to the function. This is useful if your function accepts a long list of parameters, and you intend to call it several times, (mostly) reusing the same values. You can implement your own defaults: @* @* @code{%student = ( @* @ @ @ @ @ @ @ @ 'name' => 'Mr. Smith', @* @ @ @ @ @ @ @ @ 'program' => 'Biology', @* @ @ @ @ @ @ @ @ 'class' => 'Intro to Molecular Biology', @* ); @* $return_value = sign_up(%student); @* @* $hash@{student@} = 'Ms. Jones'; @* $return_value = sign_up(%student); @* @* $hash@{student@} = 'Miss Chen'; @* $return_value = sign_up(%student); @* } @section References to arrays, and two-dimensional matrices Perl implements two-dimensional matrices using references. For example, a reference to a one-dimensional array (a row) can be defined like this: @* @* @code{$row = [ 1, 2 ];} @* In this example, @code{$row} itself is not an array, but a reference to the array (1, 2). (The square brackets indicate that we want to create a reference.) @code{$row->[0]} equals 1 and @code{$row->[1]} equals 2. @tex A $3 \times 2$ matrix of integers can be defined like this: @end tex @html A 3 × 2 matrix of integers can be defined like this: @end html @* @* @code{$row0 = [ 1, 2 ]; @* $row1 = [ 3, 4 ]; @* $row2 = [ 5, 6 ]; @* $data = [ $row0, $row1, $row2 ];} @* @* Or, more succinctly: @* @* @code{ $data = [ @* @ @ @ @ [ 1, 2 ], @* @ @ @ @ [ 3, 4 ], @* @ @ @ @ [ 5, 6 ], @* ];} @* @* In this example, @code{$data->[0]->[1]} equals 2, while @code{$data->[2]->[0]} equals 5. Many of the functions available in Algorithm::Cluster expect data to be in the form of a two dimensional array, like the example above. Some functions also return references to data structures like this. @section Partitioning algorithms @subsection The @emph{k}-means clustering algorithm: @code{kcluster} The function @code{kcluster()} implements the @emph{k}-means clustering algorithm. In the example invocation below, we have created @code{$param@{data@}} as an empty matrix, because that is the default value, but you must populate @code{$param@{data@}} with real data, in order to invoke @code{kcluster()} properly. @* @* @code{ my %param = ( @* @ @ @ @ @ @ @ @ nclusters => 2, @* @ @ @ @ @ @ @ @ data => [[]], @* @ @ @ @ @ @ @ @ mask => '', @* @ @ @ @ @ @ @ @ weight => '', @* @ @ @ @ @ @ @ @ transpose => 0, @* @ @ @ @ @ @ @ @ npass => 10, @* @ @ @ @ @ @ @ @ method => 'a', @* @ @ @ @ @ @ @ @ dist => 'e', @* @ @ @ @ @ @ @ @ initialid => [], @* ); @* my ($clusters, $error, $found) = kcluster(%param);} @subsubheading Arguments @itemize @bullet @item @code{data} @* A reference to a two-dimensional matrix containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. @item @code{nclusters} @* The number of clusters @emph{k}. @item @code{mask} @* A reference to a two-dimensional matrix of integers showing which data are missing. If @code{$param@{mask@}->[i]->[j]==0}, then @code{$param@{data@}->[i]->[j]} is missing. If @code{mask} is @code{''} (i.e., the null string, and not a reference at all), then there are no missing data. @item @code{weight} @* A reference to an array containing the weights to be used when calculating distances. If @code{weight} equals @code{''} (i.e., the null string, and not a reference at all), then equal weights are assumed. If @code{transpose==0}, the length of this array must equal the number of columns in the data matrix. If @code{transpose==1}, the length of the @code{weight} array should equal the number of rows in the data matrix. If @code{weight} has a different length, the entire array will be ignored. @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{$param@{transpose@}==0}, genes (rows) are being clustered. If @code{$param@{transpose@}==1}, microarrays (columns) are clustered. @item @code{npass} @* The number of times the @emph{k}-means clustering algorithm is performed, each time with a different (random) initial condition. If the argument @code{initialid} is given, the value of @code{npass} is ignored and the clustering algorithm is run only once, as it behaves deterministically in that case. @item @code{method} @* A one-character flag, indicating how the center of a cluster is found: @itemize @item @code{'a'}: arithmetic mean @item @code{'m'}: median @end itemize For any other values of method, the arithmetic mean is used. @item @code{dist} @* A one-character flag, defining the distance function to be used: @itemize @item @code{'c'}: correlation @item @code{'a'}: absolute value of the correlation @item @code{'u'}: uncentered correlation @item @code{'x'}: absolute uncentered correlation @item @code{'s'}: Spearman's rank correlation @item @code{'k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{'e'}: Euclidean distance @item @code{'b'}: City-block distance @end itemize For other values of @code{dist}, the default (Euclidean distance) is used. @item @code{initialid} @* An optional parameter defining the initial clustering to be used for the EM algorithm. If @code{initialid} is not specified, then a different random initial clustering is used for each of the @code{npass} runs of the EM algorithm. If @code{initialid} is specified, then it should be equal to a 1D array containing the cluster number (between @code{0} and @code{nclusters-1}) for each item. Each cluster should contain at least one item. With the initial clustering specified, the EM algorithm is deterministic. @end itemize @subsubheading Return values This function returns a list of three items: @var{$clusterid}, @var{$error}, @var{$nfound}. @itemize @bullet @item @var{$clusterid} @* A reference to an array whose length is equal to the number of rows in the data array. Each element in the @var{clusterid} array contains the number of the cluster to which each gene/microarray was assigned. @item @var{$error} @* The within-cluster sum of distances of the optimal clustering solution that was found. @item @var{$nfound} @* The number of times the optimal solution was found. @end itemize @subsection The @emph{k}-medoids algorithm: @code{kmedoids} The function @code{kmedoids()} implements the @emph{k}-means clustering algorithm. In the example invocation below, we have created the distance matrix @code{$param@{distances@}} as an empty matrix, because that is the default value, but you must populate @code{$param@{distances@}} with real data, in order to invoke @code{kmedoids()} properly. @* @* @code{ my %param = ( @* @ @ @ @ @ @ @ @ nclusters => 2, @* @ @ @ @ @ @ @ @ distances => [[]], @* @ @ @ @ @ @ @ @ npass => 10, @* @ @ @ @ @ @ @ @ initialid => [], @* ); @* my ($clusters, $error, $found) = kmedoids(%param);} @subsubheading Arguments @itemize @bullet @item @code{nclusters} @* The number of clusters @emph{k}. @item @code{distances} @* A list containing the distance matrix between the elements. An example of a distance matrix is: @* @code{$distances = [[], [1.1], [1.0, 4.5], [2.3, 1.8, 6.1]]; } @* @item @code{npass} @* The number of times the @emph{k}-medoids clustering algorithm is performed, each time with a different (random) initial condition. If @code{initialid} is given, the value of @var{npass} is ignored, as the clustering algorithm behaves deterministically in that case. @item @code{initialid} @* Specifies the initial clustering to be used for the EM algorithm. If @code{initialid} is not specified, then a different random initial clustering is used for each of the @code{npass} runs of the EM algorithm. If @code{initialid} is specified, then it should be equal to a 1D array containing the cluster number (between @code{0} and @code{nclusters-1}) for each item. Each cluster should contain at least one item. With the initial clustering specified, the EM algorithm is deterministic. @end itemize @subsubheading Return values This function returns a list of three items: @var{$clusterid}, @code{$error}, @code{$nfound}. @itemize @bullet @item @code{$clusterid} @* @var{$clusterid} is a reference to an array whose length is equal to the number of rows of the distance matrix. Each element in the @var{clusterid} array contains the number of the cluster to which each gene/microarray was assigned. The cluster number is defined as the number of the gene/microarray that is the centroid of the cluster. @item @code{$error} @* @code{$error} is the within-cluster sum of distances of the optimal clustering solution that was found. @item @code{$nfound} @* @code{$nfound} is the number of times the optimal solution was found. @end itemize @section Hierarchical clustering: @code{treecluster} The pairwise single-, maximum-, average-, and centroid-linkage clustering methods are accessible through the function @code{treecluster}. The hierarchical clustering routines can be applied either on the original gene expression data, or (except for centroid-linkage clustering) on the distance matrix directly. The tree structure generated by @code{treecluster} can be cut in order to separate the elements into a given number of clusters. @subsection Representing a hierarchical clustering solution A hierarchical clustering solution is represented using two Perl classes: @code{Node} and @code{Tree}. @subheading The class @code{Node} The Perl class @code{Node} corresponds to the C struct @code{Node} described above. A @code{Node} object has three attributes: @itemize @bullet @item left @item right @item distance @end itemize @noindent Here, @code{left} and @code{right} are integers referring to the two items or subnodes that are joined at this node, and @code{distance} is the distance between them. The items being clustered are numbered from @code{0} to @code{(@emph{number of items} - 1)}, while clusters are numbered @code{-1} to @code{-(@emph{number of items}-1)}. To create a new @code{Node} object, we need to specify @code{left}, @code{right}, and @code{distance}: @noindent @code{use Algorithm::Cluster; @* my $node = Algorithm::Cluster::Node->new(3, 4, 2.7); @* print "Left:", $node->left, "\n"; @* print "Right:", $node->right, "\n"; @* print "Distance:", $node->distance, "\n"; @* } @noindent Executing this code prints @noindent @code{Left:3 @* Right:4 @* Distance:2.7 @* } The attributes @code{left}, @code{right}, and @code{distance} of an existing @code{Node} object can be modified by using the @code{set_left}, @code{set_right}, and @code{set_distance} methods: @noindent @code{use Algorithm::Cluster; @* my $node = Algorithm::Cluster::Node->new(3, 4, 2.7); @* $node->set_left(2); @* $node->set_right(1); @* $node->set_distance(2.1); @* } @noindent @subheading The class @code{Tree} The Perl class @code{Tree} represents a full hierarchical clustering solution. A @code{Tree} object can be created from an array of @code{Node} objects: @noindent @code{use Algorithm::Cluster; @* my $node1 = Algorithm::Cluster::Node->new(1,2,3.1); @* my $node2 = Algorithm::Cluster::Node->new(-1,3,5.3); @* my $node3 = Algorithm::Cluster::Node->new(4,0,5.9); @* my $node4 = Algorithm::Cluster::Node->new(-2,-3,7.8); @* my @@nodes = [$node1,$node2,$node3,$node4]; @* my $tree = Algorithm::Cluster::Tree->new(@@nodes); } The @code{Tree} initializer checks if the list of nodes is a valid hierarchical clustering result: @noindent @code{use Algorithm::Cluster; @* my $node1 = Algorithm::Cluster::Node->new(1,2,0.3); @* my $node2 = Algorithm::Cluster::Node->new(1,3,0.7); @* my @@nodes = [$node1,$node2]; @* my $tree = Algorithm::Cluster::Tree->new(@@nodes); @* } results in the following error message: @noindent @code{the array of nodes passed to Algorithm::Cluster::Tree::new do not represent a valid tree} Individual nodes in a @code{Tree} object can be accessed using the @code{get} method. Continuing the previous example, the following code prints @code{0.7}: @noindent @code{my $node3 = $tree->get(1); @* print $node3->distance; @* } @noindent As a @code{Tree} object is read-only, we cannot change individual nodes in a @code{Tree} object. However, we can convert the tree to a list of nodes, modify this list, and create a new tree from this list: @noindent @code{use Algorithm::Cluster; @* my $node1 = Algorithm::Cluster::Node->new(0,1,0.3); @* my $node2 = Algorithm::Cluster::Node->new(2,3,0.7); @* my $node3 = Algorithm::Cluster::Node->new(-1,-2,0.9); @* my $nodes = [$node1, $node2, $node3]; @* my $tree = Algorithm::Cluster::Tree->new($nodes); @* my $i; @* my $n = $tree->length; @* my $node; @* my $nodes2 = []; @* for ($i = 0; $i < $n; $i++) @{ @* @ @ @ @ @ @ @ @ $nodes2->[$i] = $tree->get($i); @* @} @* $node = $nodes2->[1]; @* $node->set_left(-1); @* $node = $nodes2->[2]; @* $node->set_left(2); @* my $tree2 = Algorithm::Cluster::Tree->new($nodes2); @* } @noindent This guarantees that any @code{Tree} object is always well-formed. A @code{Tree} object has two methods (@code{scale} and @code{cut}, described below). The @code{treecluster} function returns @code{Tree} objects. @subsection Performing hierarchical clustering: @code{treecluster} The pairwise single-, maximum-, average-, and centroid-linkage clustering methods are accessible through the function @code{treecluster}. @* @code{my %param = ( @* @ @ @ @ @ @ @ @ data => [[]], @* @ @ @ @ @ @ @ @ mask => '', @* @ @ @ @ @ @ @ @ weight => '', @* @ @ @ @ @ @ @ @ transpose => 0, @* @ @ @ @ @ @ @ @ dist => 'e', @* @ @ @ @ @ @ @ @ method => 's', @* ); @* @* my @var{$tree} = Algorithm::Cluster::treecluster(%param); @* } @subsubheading Arguments @itemize @bullet @item @code{data} @* A reference to a two-dimensional matrix containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. It is also possible to pass a user-defined distance matrix as a lower-diagonal matrix, for example: @* @code{$data = [ @* @ @ @ @ @ @ @ @ @ [], @* @ @ @ @ @ @ @ @ @ [ 3.4], @* @ @ @ @ @ @ @ @ @ [ 4.3, 10.1], @* @ @ @ @ @ @ @ @ @ [ 3.7, 11.5, 1.0] @* @ @ @ @ @ @ @ @ ];} @* If the @code{data} argument has this form, it will be interpreted as a distance matrix instead of a raw data matrix, and the arguments @code{mask}, @code{weight}, @code{transpose}, and @code{dist} will be ignored. @item @code{mask} @* A referene to a two-dimensional matrix of integers showing which data are missing. If @code{$param@{mask@}->[i]->[j]==0}, then @code{$param@{data@}->[i]->[j]} is missing. If @code{mask} is @code{''} (i.e., the null string, and not a reference at all), then there are no missing data. @item @code{weight} @* A reference to an array containing the weights to be used when calculating distances. If @code{weight} equals @code{''} (i.e., the null string, and not a reference at all), then equal weights are assumed. If @code{transpose==0}, the length of this array must equal the number of columns in the data matrix. If @code{transpose==1}, the length of the @code{weight} array should equal the number of rows in the data matrix. If @code{weight} has a different length, the entire array will be ignored. @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{$param@{transpose@}==0}, genes (rows) are being clustered. If @code{$param@{transpose@}==1}, microarrays (columns) are clustered. @item @code{dist} @* A one-character flag, defining the distance function to be used: @itemize @item @code{'c'}: correlation @item @code{'a'}: absolute value of the correlation @item @code{'u'}: uncentered correlation @item @code{'x'}: absolute uncentered correlation @item @code{'s'}: Spearman's rank correlation @item @code{'k'}: Kendall's tau @item @code{'e'}: Euclidean distance @item @code{'b'}: City-block distance @end itemize @item @code{method} @* Specifies which type of hierarchical clustering is used: @itemize @item @code{'s'}: pairwise single-linkage clustering @item @code{'m'}: pairwise maximum- (or complete-) linkage clustering @item @code{'a'}: pairwise average-linkage clustering @item @code{'c'}: pairwise centroid-linkage clustering @end itemize Pairwise centroid-linkage clustering is not available if a user-defined distance matrix is passed via @code{data}. @end itemize @subsubheading Return values @noindent This function returns a @code{Tree} object. This object contains @code{@emph{number of items} - 1} nodes, where the number of items is the number of genes if genes were clustered, or the number of microarrays if microarrays were clustered. Each node describes a pairwise linking event, where the node attributes @code{left} and @code{right} each contain the number of one gene/microarray or subnode, and @code{distance} the distance between them. Genes/microarrays are numbered from @code{0} to @code{(@emph{number of items} - 1)}, while clusters are numbered @code{-1} to @code{-(@emph{number of items}-1)}. @subsection Scaling a hierarchical clustering tree: @code{@var{$tree}->scale} To display a hierarchical clustering solution with Java TreeView, it is better to scale all node distances such that they are between zero and one. This can be accomplished by calling the @code{scale} method on an existing @code{Tree} object. @noindent @code{@var{$tree}->scale} @* scales the distances in the hierarchical clustering tree such that they are all between zero and one. This function takes no arguments. @subsection Cutting a hierarchical clustering tree: @code{@var{$tree}.cut} @noindent @code{@var{$clusterid} = @var{$tree}->cut(@var{$nclusters})} @* groups the items into @code{@var{$nclusters}} clusters based on the tree structure generated by the hierarchical clustering routine @code{treecluster}. @subsubheading Arguments @itemize @bullet @item @code{@var{$tree}} @* The @code{Tree} object @code{@var{$tree}} contains the hierarchical clustering result generated by @code{treecluster}. Each node in this tree describes a pairwise linking event, where the node attributes @code{left} and @code{right} contain the number of the two items or subnodes. Items are numbered from 0 to (@code{@emph{number of elements}} - 1), while clusters are numbered -1 to -(@code{@emph{number of elements}}-1). @item @code{@var{$nclusters}} @* The desired number of clusters; @code{@var{$nclusters}} should be positive, and less than or equal to the number of elements. @end itemize @subsubheading Return values @noindent This function returns the anonymous array @code{@var{$clusterid}}. @itemize @bullet @item @code{@var{$clusterid}} @* An anonymous array containing the number of the cluster to which each gene/microarray is assigned. @end itemize @subheading Example @noindent @code{use Algorithm::Cluster; @* my $node1 = Algorithm::Cluster::Node->new(0,1,0.3); @* my $node2 = Algorithm::Cluster::Node->new(2,3,0.7); @* my $node3 = Algorithm::Cluster::Node->new(-1,-2,0.9); @* my $nodes = [$node1, $node2, $node3]; @* my $tree = Algorithm::Cluster::Tree->new($nodes); @* my $a = $tree->cut(3); @* my $i = 0; @* foreach (@@$a) @{ @* @ @ @ @ @ @ @ @ print "Element $i: Cluster $_\n"; @* @ @ @ @ @ @ @ @ $i++; @* @} @* } prints @* @noindent @code{Element 0: Cluster 2 @* Element 1: Cluster 2 @* Element 2: Cluster 0 @* Element 3: Cluster 1 @* } @section Self-Organizing Maps: @code{somcluster} The @code{somcluster()} function implements a Self-Organizing Map on a rectangular grid. @* @* @code{ my %param = ( @* @ @ @ @ @ @ @ @ data => [[]], @* @ @ @ @ @ @ @ @ mask => '', @* @ @ @ @ @ @ @ @ weight => '', @* @ @ @ @ @ @ @ @ transpose => 0, @* @ @ @ @ @ @ @ @ nxgrid => 10, @* @ @ @ @ @ @ @ @ nygrid => 10, @* @ @ @ @ @ @ @ @ niter => 100, @* @ @ @ @ @ @ @ @ dist => 'e', @* ); @* my ($clusterid) = Algorithm::Cluster::somcluster(%param);} @subsubheading Arguments @itemize @bullet @item @code{data} @* A reference to a two-dimensional matrix containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. @item @code{mask} @* A reference to a two-dimensional matrix of integers showing which data are missing. If @code{$param@{mask@}->[i]->[j]==0}, then @code{$param@{data@}->[i]->[j]} is missing. If @code{mask} is @code{''} (i.e., the null string, and not a reference at all), then there are no missing data. @item @code{weight} @* A reference to an array containing the weights to be used when calculating distances. If @code{weight} equals @code{''} (i.e., the null string, and not a reference at all), then equal weights are assumed. If @code{transpose==0}, the length of this array must equal the number of columns in the data matrix. If @code{transpose==1}, the length of the @code{weight} array should equal the number of rows in the data matrix. If @code{weight} has a different length, the entire array will be ignored. @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{$param@{transpose@}==0}, genes (rows) are being clustered. If @code{$param@{transpose@}==1}, microarrays (columns) are clustered. @item @code{nxgrid, nygrid} @* Both parameters are integers, indicating the number of cells horizontally and vertically in the rectangular grid, on which the Self-Organizing Map is calculated. @item @code{inittau} @* The initial value for the neighborhood function, as given by the parameter @tex $\tau$. @end tex @html τ. @end html The default value for @code{inittau} is 0.02, which was used in Michael Eisen's Cluster/TreeView program. @item @code{niter} @* The number of iterations to be performed. @item @code{dist} @* A one-character flag, defining the distance function to be used: @itemize @item @code{'c'}: correlation @item @code{'a'}: absolute value of the correlation @item @code{'u'}: uncentered correlation @item @code{'x'}: absolute uncentered correlation @item @code{'s'}: Spearman's rank correlation @item @code{'k'}: Kendall's tau @item @code{'e'}: Euclidean distance @item @code{'b'}: City-block distance @end itemize @end itemize @subsubheading Return values This function returns one value, @var{$clusterid}, which is a reference to a two-dimensional matrix. If @code{$param@{transpose@}==0}, then the number of rows in @var{$clusterid} equals the number of rows (genes) in the original data array; if @code{$param@{transpose@}==1}, then then the number of rows in @var{$clusterid} equals the number of columns (microarrays) in the original data array. Each row in the array @var{clusterid} contains the x and y coordinates of the cell in the rectangular SOM grid to which the gene or microarray was assigned. @section Finding the cluster centroids: @code{clustercentroids} @noindent @code{ my %param = ( @* @ @ @ @ @ @ @ @ data => [[]], @* @ @ @ @ @ @ @ @ mask => '', @* @ @ @ @ @ @ @ @ clusterid => undef, @* @ @ @ @ @ @ @ @ method => 'a', @* @ @ @ @ @ @ @ @ transpose => 0, @* ); @* my ($cdata, $cmask) = clustercentroids(%param) } @* calculates the cluster centroids. @subsubheading Arguments @itemize @bullet @* @item @code{data} @* Array containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. @item @code{mask} @* Array of integers showing which data are missing. If @code{$param@{mask@}->[$i]->[$j]==0}, then @code{$param@{data@}->[$i]->[$j]} is missing. If @code{mask} is @code{''}, then there are no missing data. @item @code{clusterid} @* Vector of integers showing to which cluster each element belongs. If @code{clusterid} is not given, then all elements are assumed to belong to the same cluster. @item @code{method} @* Specifies whether the arithmetic mean (@code{method=>'a'}) or the median (@code{method=>'m'}) is used to calculate the cluster center. @item @code{transpose} @* Determines if gene or microarray clusters are being considered. If @code{transpose==0}, then we are considering clusters of genes (rows). If @code{transpose==1}, then we are considering clusters of microarrays (columns). @end itemize @subsubheading Return values @noindent This function returns the list @code{@var{cdata}, @var{cmask}}. @itemize @bullet @item @code{@var{$cdata}} @* A 2D array containing the centroid data. The dimensions of this array are @code{(@emph{number of clusters}, @emph{number of microarrays})} if genes were clustered, or @code{(@emph{number of genes}, @emph{number of clusters})} if microarrays were clustered. Each row (if genes were clustered) or column (if microarrays were clustered) contains the averaged gene expression data for corresponding to the centroid of one cluster that was found. @item @code{@var{$cmask}} @* This matrix stores which values in @code{@var{$cdata}} are missing. If @code{@var{$cmask}[$i][$j]==0}, then @code{@var{$cdata}[$i][$j]} is missing. The dimensions of this array are @code{(@emph{number of clusters}, @var{number of microarrays})} if genes were clustered, or @code{(@var{number of genes}, @var{number of clusters})} if microarrays were clustered. @end itemize @section The distance between two clusters: @code{clusterdistance} The @code{clusterdistance} routine calculates the distance between two clusters, between a cluster and an item, or between two items. @* @code{ @* my %param = ( @* @ @ @ @ @ @ @ @ data => [[]], @* @ @ @ @ @ @ @ @ mask => '', @* @ @ @ @ @ @ @ @ weight => '', @* @ @ @ @ @ @ @ @ cluster1 => [], @* @ @ @ @ @ @ @ @ cluster2 => [], @* @ @ @ @ @ @ @ @ dist => 'e', @* @ @ @ @ @ @ @ @ method => 'a', @* @ @ @ @ @ @ @ @ transpose => 0, @* ); @* @* my ($distance) = Algorithm::Cluster::clusterdistance(%param); } @subsubheading Arguments @itemize @bullet @item @code{data} @* A reference to a two-dimensional matrix containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. @item @code{mask} @* A reference to a two-dimensional matrix of integers showing which data are missing. If @code{$param@{mask@}->[i]->[j]==0}, then @code{$param@{data@}->[i]->[j]} is missing. If @code{mask} is @code{''} (i.e., the null string, and not a reference at all), then there are no missing data. @item @code{weight} @* A reference to an array containing the weights to be used when calculating distances. If @code{weight} equals @code{''} (i.e., the null string, and not a reference at all), then equal weights are assumed. If @code{transpose==0}, the length of this array must equal the number of columns in the data matrix. If @code{transpose==1}, the length of the @code{weight} array should equal the number of rows in the data matrix. If @code{weight} has a different length, the entire array will be ignored. @item @code{cluster1} @* contains the indices of the elements belonging to the first cluster, or alternatively an integer to refer to a single item. @item @code{cluster2} @* contains the indices of the elements belonging to the second cluster, or alternatively an integer to refer to a single item. @item @code{dist} @* A one-character flag, defining the distance function to be used: @itemize @item @code{'c'}: correlation @item @code{'a'}: absolute value of the correlation @item @code{'u'}: uncentered correlation @item @code{'x'}: absolute uncentered correlation @item @code{'s'}: Spearman's rank correlation @item @code{'k'}: Kendall's tau @item @code{'e'}: Euclidean distance @item @code{'b'}: City-block distance @end itemize @item @code{method} @* A one-character flag, indicating how the center of a cluster is found: @itemize @item @code{'a'}: Distance between the two cluster centroids (arithmetic mean) @item @code{'m'}: Distance between the two cluster centroids (median) @item @code{'s'}: Shortest distance between elements in the two clusters @item @code{'x'}: Longest pairwise distance between elements in the two clusters @item @code{'v'}: Average over the pairwise distances between elements in the two clusters. @end itemize For any other values of @code{method}, the arithmetic mean is used. @item @code{transpose} @* Determines if the distance between genes or between microarrays should be calculated. If @code{$param@{transpose@}==0}, the function calculates the distance between the genes (rows) specified by @code{$param@{cluster1@}} and @code{$param@{cluster2@}}. If @code{$param@{transpose@}==1}, the function calculates the distance between the microarrays (columns) specified by @code{$param@{cluster1@}} and @code{$param@{cluster2@}}. @end itemize @subsubheading Return values The distance between the clusters indicated by @code{cluster1} and @code{cluster2}. @section Calculating the distance matrix: @code{distancematrix} The function @code{distancematrix()} calculates the distance matrix between the gene expression data and returns it as a ragged array. @* @code{ my %param = ( @* @ @ @ @ @ @ @ @ data => [[]], @* @ @ @ @ @ @ @ @ mask => '', @* @ @ @ @ @ @ @ @ weight => '', @* @ @ @ @ @ @ @ @ transpose => 0, @* @ @ @ @ @ @ @ @ dist => 'e', @* ); @* my $distancematrix = distancematrix(%param);} @subsubheading Arguments @itemize @bullet @item @code{data} @* A reference to a two-dimensional matrix containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. @item @code{mask} @* A reference to a two-dimensional matrix of integers showing which data are missing. If @code{$param@{mask@}->[i]->[j]==0}, then @code{$param@{data@}->[i]->[j]} is missing. If @code{mask} is @code{''} (i.e., the null string, and not a reference at all), then there are no missing data. @item @code{weight} @* A reference to an array containing the weights to be used when calculating distances. If @code{weight} equals @code{''} (i.e., the null string, and not a reference at all), then equal weights are assumed. If @code{transpose==0}, the length of this array must equal the number of columns in the data matrix. If @code{transpose==1}, the length of the @code{weight} array should equal the number of rows in the data matrix. If @code{weight} has a different length, the entire array will be ignored. @item @code{transpose} @* Determines if the distances between genes or microarrays should be calculated. If @code{$param@{transpose@}==0}, the distances between genes (rows) are calculated. If @code{$param@{transpose@}==1}, the distances are calculated between microarrays (columns). @item @code{dist} @* A one-character flag, defining the distance function to be used: @itemize @item @code{'c'}: correlation @item @code{'a'}: absolute value of the correlation @item @code{'u'}: uncentered correlation @item @code{'x'}: absolute uncentered correlation @item @code{'s'}: Spearman's rank correlation @item @code{'k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{'e'}: Euclidean distance @item @code{'b'}: City-block distance For other values of @code{dist}, the default (Euclidean distance) is used. @end itemize @end itemize @subsubheading Return values This function returns the @var{$distancematrix}, an array of rows containing the distance matrix between the gene expression data. The number of columns in each row is equal to the row number. Hence, the first row has zero elements. @section Principal Component Analysis: @code{pca} @noindent @code{my ($columnmean, $coordinates, $components, $eigenvalues) = pca($data);} @* applies Principal Component Analysis to the rectangular matrix @code{data}. @subsubheading Arguments @itemize @bullet @item @code{$data} @* A reference to a two-dimensional matrix containing the gene expression data, where genes are stored row-wise and microarray experiments column-wise. @end itemize @subsubheading Return values This function returns a list of four items: @code{@var{$columnmean}}, @code{@var{$coordinates}}, @code{@var{$components}}, @code{@var{$eigenvalues}}. @itemize @bullet @item @var{$columnmean} @* A reference to an array containing the mean over each column in @code{$data}. @item @var{$coordinates} @* A reference to an array containing the coordinates of each row in @code{$data} with respect to the principal components. @item @var{$components} @* A reference to an array containing the principal components. @item @var{$eigenvalues} @* A reference to an array containing the eigenvalues corresponding to each of the principal components. @end itemize @section Auxiliary functions @noindent @code{median($data)} @* Returns the median of the data. @code{$data} is a reference to a (one-dimensional) array of numbers. @noindent @code{mean($data)} @* Returns the mean of the data. @code{$data} is a reference to a (one-dimensional) array of numbers. @noindent @code{version()} @* Returns the version number of the C Clustering Library as a string. @section Handling Cluster/TreeView-type files Cluster/TreeView are GUI-based codes for clustering gene expression data. They were originlly written by Michael Eisen (@url{http://rana.lbl.gov}) while at Stanford University. Algorithm::Cluster contains functions for reading and writing data files in the format specifies for Cluster/TreeView. In particular, by saving a clustering result in that format, we can use TreeView to visualize the clustering results. We recommend using Alok Saldanha's Java TreeView program (@url{http://jtreeview.sourceforget.net}), which can display hierarchical as well as @emph{k}-means clustering clustering results. @subsection The @code{Record} class An object of the class @code{Record} contains all information stored in a Cluster/TreeView-type data file. To store the information contained in the data file in a @code{Record} object, we create a @code{Record} object, open the file, and then read the file contents into the @code{Record} object: @* @code{ @noindent use Algorithm::Cluster::Record; @* my @var{$record} = Algorithm::Cluster::Record->new(); @* open @var{INPUT}, "mydatafile.txt"; @* @var{$record}->read(*@var{INPUT}); @* } The @code{read} command reads the tab-delimited text file @code{mydatafile.txt} containing gene expression data in the format specified for Michael Eisen's Cluster/TreeView program. For a description of this file format, see the manual to Cluster/TreeView. It is available at @uref{http://rana.lbl.gov/manuals/ClusterTreeView.pdf, Michael Eisen's lab website} and at @uref{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/cluster3.pdf, our website}. A @code{Record} object stores the following information: @itemize @bullet @item @code{data} @* The data array containing the gene expression data. Genes are stored row-wise, while microarrays are stored column-wise. @item @code{mask} @* This array shows which elements in the @code{data} array, if any, are missing. If @code{@var{$record}@{mask@}[$i][$j]==0}, then @code{@var{$record}@{data@}[$i][$j]} is missing. If no data were found to be missing, @code{@var{$record}@{mask@}} remains @code{undef}. @item @code{geneid} @* This is a list containing a unique description for each gene (i.e., ORF numbers). @item @code{genename} @* This is a list containing a description for each gene (i.e., gene name). If not present in the data file, @code{@var{$record}@{genename@}} remains @code{undef}. @item @code{gweight} @* The weights that are to be used to calculate the distance in expression profile between genes. If not present in the data file, @code{@var{$record}@{gweight@}} remains @code{undef}. @item @code{gorder} @* The preferred order in which genes should be stored in an output file. If not present in the data file, @code{@var{$record}@{gorder@}} remains @code{undef}. @item @code{expid} @* This is a list containing a description of each microarray, e.g. experimental condition. @item @code{eweight} @* The weights that are to be used to calculate the distance in expression profile between microarrays. If not present in the data file, @code{@var{$record}@{eweight@}} remains @code{undef}. @item @code{eorder} @* The preferred order in which microarrays should be stored in an output file. If not present in the data file, @code{@var{$record}@{eorder@}} remains @code{undef}. @item @code{uniqid} @* The string that was used instead of UNIQID in the data file. @end itemize After loading a @code{Record} object, each of these attributes can be accessed and modified directly. For example, the data can be log-transformed by taking the logarithm of @code{@var{record}->{data}}. @subsection Performing hierarchical clustering @noindent @code{ my %param = ( @* @ @ @ @ @ @ @ @ transpose => 0, @* @ @ @ @ @ @ @ @ method => 'a', @* @ @ @ @ @ @ @ @ dist => 'e', @* ); @* my @var{$tree} = @var{$record}->treecluster(%param)}; @* applies hierachical clustering to the data contained in the @code{Record} object. @subsubheading Arguments @itemize @bullet @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{transpose==0}, genes (rows) are being clustered. If @code{transpose==1}, microarrays (columns) are clustered. @item @code{method} @* defines the linkage method to be used: @itemize @item @code{method=='s'}: pairwise single-linkage clustering @item @code{method=='m'}: pairwise maximum- (or complete-) linkage clustering @item @code{method=='c'}: pairwise centroid-linkage clustering @item @code{method=='a'}: pairwise average-linkage clustering @end itemize @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @end itemize @subsubheading Return values @noindent This function returns a @code{Tree} object. This object contains @code{@emph{number of items} - 1} nodes, where the number of items is the number of genes if genes were clustered, or the number of microarrays if microarrays were clustered. Each node describes a pairwise linking event, where the node attributes @code{left} and @code{right} each contain the number of one gene/microarray or subnode, and @code{distance} the distance between them. Genes/microarrays are numbered from @code{0} to @code{(@emph{number of items} - 1)}, while clusters are numbered @code{-1} to @code{-(@emph{number of items}-1)}. @subsection Performing @emph{k}-means or @emph{k}-medians clustering @noindent @code{ my %param = ( @* @ @ @ @ @ @ @ @ nclusters => 2, @* @ @ @ @ @ @ @ @ transpose => 0, @* @ @ @ @ @ @ @ @ npass => 1, @* @ @ @ @ @ @ @ @ method => 'a', @* @ @ @ @ @ @ @ @ dist => 'e', @* @ @ @ @ @ @ @ @ initialid => undef, @* ); @* my (@var{$clusterid}, @var{$error}, @var{$nfound}) = @var{$record}->kcluster(%param);} @* applies @emph{k}-means or @emph{k}-medians clustering to the data contained in the @code{Record} object. @subsubheading Arguments @itemize @bullet @item @code{nclusters} @* The number of clusters @emph{k}. @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{transpose==0}, genes (rows) are being clustered. If @code{transpose==1}, microarrays (columns) are clustered. @item @code{npass} @* The number of times the @emph{k}-means clustering algorithm is performed, each time with a different (random) initial condition. If @code{initialid} is given, the value of @code{npass} is ignored and the clustering algorithm is run only once, as it behaves deterministically in that case. @item @code{method} @* describes how the center of a cluster is found: @itemize @item @code{method=='a'}: arithmetic mean; @item @code{method=='m'}: median. @end itemize @noindent For other values of @code{method}, the arithmetic mean is used. @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @noindent @item @code{initialid} @* Specifies the initial clustering to be used for the EM algorithm. If @code{initialid==None}, then a different random initial clustering is used for each of the @code{npass} runs of the EM algorithm. If @code{initialid} is not @code{None}, then it should be equal to a 1D array containing the cluster number (between @code{0} and @code{nclusters-1}) for each item. Each cluster should contain at least one item. With the initial clustering specified, the EM algorithm is deterministic. @end itemize @subsubheading Return values @noindent This function returns three variables @code{(@var{$clusterid}, @var{$error}, @var{$nfound})}. @itemize @bullet @item @code{@var{$clusterid}} @* An array containing the number of the cluster to which each gene/microarray was assigned. @item @code{@var{$error}} @* The within-cluster sum of distances for the optimal clustering solution. @item @code{@var{$nfound}} @* The number of times the optimal solution was found. @end itemize @subsection Calculating a Self-Organizing Map @noindent @code{ my %param = ( @* @ @ @ @ @ @ @ @ transpose => 0, @* @ @ @ @ @ @ @ @ nxgrid => 2, @* @ @ @ @ @ @ @ @ nygrid => 1, @* @ @ @ @ @ @ @ @ inittau => 0.02, @* @ @ @ @ @ @ @ @ niter => 1, @* @ @ @ @ @ @ @ @ dist => 'e', @* ); @* my @@clusterid = @var{$record}->somcluster(%param);} @* calculates a Self-Organizing Map on a rectangular grid, using the gene expression data in the @code{Record} object @var{$record}. @subsubheading Arguments @itemize @bullet @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{transpose==0}, genes (rows) are being clustered. If @code{transpose==1}, microarrays (columns) are clustered. @item @code{nxgrid, nygrid} @* The number of cells horizontally and vertically in the rectangular grid, on which the Self-Organizing Map is calculated. @item @code{inittau} @* The initial value for the parameter @tex $\tau$ @end tex @html τ @end html that is used in the SOM algorithm. The default value for @code{inittau} is 0.02, which was used in Michael Eisen's Cluster/TreeView program. @item @code{niter} @* The number of iterations to be performed. @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @end itemize @subsubheading Return values @noindent This function returns an array with two columns, where the number of rows is equal to the number of genes or the number of microarrays depending on whether genes or microarrays are being clustered. Each row contains the @emph{x} and @emph{y} coordinates of the cell in the rectangular SOM grid to which the gene or microarray was assigned. @subsection Finding the cluster centroid @noindent @code{ my %param = ( @* @ @ @ @ @ @ @ @ clusterid => undef, @* @ @ @ @ @ @ @ @ method => 'a', @* @ @ @ @ @ @ @ @ transpose => 0, @* ); @* my (@var{$cdata}, @var{$cmask}) = @var{record}->clustercentroids(%param);} @* calculates the cluster centroids. @subsubheading Arguments @itemize @bullet @* @item @code{clusterid} @* Vector of integers showing to which cluster each element belongs. If @code{clusterid} is not given, then all elements are assumed to belong to the same cluster. @item @code{method} @* Specifies whether the arithmetic mean (@code{method=='a'}) or the median (@code{method=='m'}) is used to calculate the cluster center. @item @code{transpose} @* Determines if gene or microarray clusters are being considered. If @code{transpose==0}, then we are considering clusters of genes (rows). If @code{transpose==1}, then we are considering clusters of microarrays (columns). @end itemize @subsubheading Return values @noindent This function returns the list @code{@var{$cdata}, @var{$cmask}}. @itemize @bullet @item @code{@var{$cdata}} @* A 2D array containing the centroid data. The dimensions of this array are @code{(@emph{number of clusters}, @emph{number of microarrays})} if genes were clustered, or @code{(@emph{number of genes}, @emph{number of clusters})} if microarrays were clustered. Each row (if genes were clustered) or column (if microarrays were clustered) contains the averaged gene expression data for corresponding to the centroid of one cluster that was found. @item @code{@var{$cmask}} @* This matrix stores which values in @code{@var{cdata}} are missing. If @code{@var{$cmask}[$i][$j]==0}, then @code{@var{$cdata}[$i][$j]} is missing. The dimensions of this array are @code{(@emph{number of clusters}, @emph{number of microarrays})} if genes were clustered, or @code{(@emph{number of genes}, @emph{number of clusters})} if microarrays were clustered. @end itemize @subsection Calculating the distance between two clusters @noindent @code{ my %param = ( @* @ @ @ @ @ @ @ @ index1 => [], @* @ @ @ @ @ @ @ @ index2 => [], @* @ @ @ @ @ @ @ @ method => 'a', @* @ @ @ @ @ @ @ @ dist => 'e', @* @ @ @ @ @ @ @ @ transpose => 0, @* ); @* my @var{$distance} = @var{record}->clusterdistance(%param);} @* calculates the distance between two clusters. @subsubheading Arguments @itemize @bullet @item @code{index1} @* is a list containing the indices of the elements belonging to the first cluster, or alternatively an integer to refer to a single item. @item @code{index2} @* is a list containing the indices of the elements belonging to the second cluster, or alternatively an integer to refer to a single item. @item @code{method} @* Specifies how the distance between clusters is defined: @itemize @item @code{method=='a'}: Distance between the two cluster centroids (arithmetic mean); @item @code{method=='m'}: Distance between the two cluster centroids (median); @item @code{method=='s'}: Shortest pairwise distance between elements in the two clusters; @item @code{method=='x'}: Longest pairwise distance between elements in the two clusters; @item @code{method=='v'}: Average over the pairwise distances between elements in the two clusters. @end itemize @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @item @code{transpose} @* Determines if gene or microarray clusters are being considered. If @code{transpose==0}, then we are considering clusters of genes (rows). If @code{transpose==1}, then we are considering clusters of microarrays (columns). @end itemize @subsubheading Return values @noindent This function returns the distance between the two clusters. @subsection Calculating the distance matrix @noindent @code{ my %param = ( @* @ @ @ @ @ @ @ @ transpose => 0, @* @ @ @ @ @ @ @ @ dist => 'e', @* ); @* my @var{$matrix} = @var{record}->distancematrix(%param);} @* returns the distance matrix between gene expression data. @subsubheading Arguments @itemize @bullet @item @code{transpose} @* Determines if genes or microarrays are being clustered. If @code{transpose==0}, genes (rows) are being clustered. If @code{transpose==1}, microarrays (columns) are clustered. @item @code{dist} @* defines the distance function to be used: @itemize @item @code{dist=='c'}: correlation; @item @code{dist=='a'}: absolute value of the correlation; @item @code{dist=='u'}: uncentered correlation; @item @code{dist=='x'}: absolute uncentered correlation; @item @code{dist=='s'}: Spearman's rank correlation; @item @code{dist=='k'}: Kendall's @tex $\tau$; @end tex @html τ; @end html @item @code{dist=='e'}: Euclidean distance; @item @code{dist=='b'}: City-block distance. @end itemize @end itemize @subsubheading Return values This function returns the @var{$distancematrix}, an array of rows containing the distance matrix between the gene expression data. The number of columns in each row is equal to the row number. Hence, the first row has zero elements. @subsection Saving the clustering result @noindent @code{ my %param = ( @* @ @ @ @ @ @ @ @ jobname => '', @* @ @ @ @ @ @ @ @ geneclusters => [], @* @ @ @ @ @ @ @ @ expclusters => [], @* ); @* @var{$record}->save(%param);} @* writes the text file @var{jobname}@code{.cdt}, @var{jobname}@code{.gtr}, @var{jobname}@code{.atr}, @var{jobname*}@code{.kgg}, and/or @var{jobname*}@code{.kag} for subsequent reading by the Java TreeView program. If @code{geneclusters} and @code{expclusters} are both @code{None}, this method only writes the text file @var{jobname}@code{.cdt}; this file can subsequently be read into a new @code{Record} object. @subsubheading Arguments @itemize @bullet @item @code{jobname} @* The string @code{jobname} is used as the base name for names of the files that are to be saved. @item @code{geneclusters} @* This argument describes the gene clustering result. In case of @emph{k}-means clustering, this is a 1D array containing the number of the cluster each gene belongs to. It can be calculated using @code{kcluster}. In case of hierarchical clustering, @code{geneclusters} is a @code{Tree} object. @item @code{expclusters} @* This argument describes the clustering result for the experimental conditions. In case of @emph{k}-means clustering, this is a 1D array containing the number of the cluster each experimental condition belongs to. It can be calculated using @code{kcluster}. In case of hierarchical clustering, @code{expclusters} is a @code{Tree} object. @end itemize @subsection Example calculation This is an example of a hierarchical clustering calculation, using single linkage clustering for genes and maximum linkage clustering for experimental conditions. As the Euclidean distance is being used for gene clustering, it is necessary to scale the node distances @code{genetree} such that they are all between zero and one. This is needed for the Java TreeView code to display the tree diagram correctly. To cluster the experimental conditions, the uncentered correlation is being used. No scaling is needed in this case, as the distances in @code{exptree} are already between zero and two. The example data @code{cyano.txt} can be found in the @code{data} subdirectory. @noindent @code{use Algorithm::Cluster::Record; @* my $record = Algorithm::Cluster::Record->new(); @* open INPUT, "cyano.txt"; @* $record->read(*INPUT); @* my $genetree = $record->treecluster(method=>'s'); @* my $exptree = $record->treecluster(dist=>'u', transpose=>1); @* $record->save(jobname=>"cyano_result", geneclusters=>$genetree, expclusters=>$exptree); } @noindent This will create the files @code{cyano_result.cdt}, @code{cyano_result.gtr}, and @code{cyano_result.atr}. Similarly, we can save a @emph{k}-means clustering solution: @noindent @code{use Algorithm::Cluster::Record; @* my $record = Algorithm::Cluster::Record->new(); @* open INPUT, "cyano.txt"; @* $record->read(*INPUT); @* my ($geneclusters, $error, $ifound) = $record->kcluster(nclusters=>5, npass=>1000); @* my ($expclusters, $error, $ifound) = $record->kcluster(nclusters=>2, npass=>100, transpose=>1); @* $record->save(jobname=>"cyano_result", geneclusters=>$geneclusters, expclusters=>$expclusters); } @noindent This will create the files @code{cyano_result_K_G2_A2.cdt}, @code{cyano_result_K_G2.kgg}, and @code{cyano_result_K_A2.kag}. @node Building, , Perl, @chapter Compiling and linking In the instructions below, @code{@emph{}} refers to the version number. The C Clustering Library complies with the ANSI-C standard since version 1.04. As of version 1.06, the C Clustering Library makes use of @code{autoconf}/@code{automake} to make the installation process easier. To install the library for use with Python, use the @code{setup.py} script instead, as described below. To install the library for use with Perl, use the @code{Makefile.PL} script. @node Installing the C Clustering Library for Python @section Installing the C Clustering Library for Python Pycluster is available as part of the Biopython distribution and as a separate package. As of version 1.41, Pycluster uses the ``new'' Numerical Python (version 1.1.1 or later), which you should install before installing Pycluster. To install Pycluster as a separate package, download @code{Pycluster-@emph{}.tar.gz} from @url{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster}. Unpack this file: @* @code{gunzip Pycluster-@emph{}.tar.gz} @* @code{tar -xvf Pycluster-@emph{}.tar} @* and change to the directory @code{Pycluster-@emph{}}. Type @* @code{python setup.py install} @* from this directory. This will compile the library and install it for use with Python. To test your installation, you can run @code{python setup.py test} @* If the installation was successful, you can remove the directory @code{Pycluster-@emph{}}. For Python on Windows (run from a DOS command window, or with a graphical user interface such as IDLE, PyCrust, PyShell, or PythonWin), a binary installer is available from @url{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster}. Installation instructions for Biopython are available from the @uref{http://www.biopython.org, Biopython website}. @node Installing the C Clustering Library for Perl @section Installing the C Clustering Library for Perl To install the C Clustering Library for Perl, download @code{Algorithm-Cluster-@emph{}.tar.gz} from @uref{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster} or from CPAN. Next, unpack this file with @* @code{gunzip Algorithm-Cluster-@emph{}.tar.gz} @* @code{tar -xvf Algorithm-Cluster-@emph{}.tar} @* and change to the directory @code{Algorithm-Cluster-@emph{}}. Type @* @code{perl Makefile.PL} @* which will create a Makefile. To compile and install, type @* @code{make} @* @code{make install} @* from this directory. You can execute @* @code{make test} @* to run some scripts that test the Algorithm::Cluster module. Some example Perl scripts can be found in the @code{perl/examples} subdirectory. If the installation was successful, you can remove the directory @code{Algorithm-Cluster-@emph{}}. If you use ActiveState Perl on Windows, you can use the Perl Package Manager by executing @* @code{ppm install http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/Algorithm-Cluster.ppd} @* from the DOS command prompt. This assumes that you are using Perl 5.8 or 5.10 from ActiveState. @section Accessing the C Clustering Library from C/C++ To call the routines in the C Clustering Library from your own C or C++ program, simply collect the relevant source files and compile them together with your program. The figure below shows the dependency structure for the source files in the C Clustering Library. @image{structure} To use the routines in the C Clustering Library, put @* @code{#include } @* in your source code. If your program is written in C++, use @* @code{extern "C" @{} @* @code{#include } @* @code{@}} @* instead. To compile a C or C++ program with the C Clustering Library, add the relevant source files to the compile command. For example, a C program @code{myprogram.c} can be compiled and linked by @* @code{gcc -o myprogram myprogram.c cluster.c} @* An example C program that makes use of the C Clustering Library can be found in the @code{example} subdirectory. @section Installing Cluster 3.0 for Windows The easiest way to install Cluster 3.0 for Windows is to use the @uref{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster, Windows installer}. The executable @code{cluster.com} can be used both as a GUI and as a command line program. To start Cluster 3.0 as a GUI program, simply double-click on @code{cluster.com}. If you want to use Cluster 3.0 from the command prompt as a command line program, you may need to give the full path to the executable (e.g., @code{C:\Program Files\Stanford University\Cluster 3.0\cluster.com}; the exact path may be different on your computer). Type @code{cluster.com --help} for an overview of all command line options. If you want to compile Cluster 3.0 from the source, change to the @code{windows} directory, and type @code{make}. This will compile the C Clustering Library, the Cluster 3.0 GUI, the Windows help files and the documentation. To compile the GUI, you need an ANSI C compiler such as GNU @code{gcc}. To compile the resources needed for the GUI, you will need the GNU program @code{windres}. To generate the help files, you need the HTML Help SDK, which can be downloaded from Microsoft. You will also need GNU makeinfo. To generate the Windows installer, type @* @code{make clustersetup.exe} @* For this, you will need the Inno Setup Compiler, which can be downloaded from @uref{http://www.jrsoftware.org}. @section Installing Cluster 3.0 for Mac OS X Cluster 3.0 for Mac OS X can be installed most easily by using the prebuilt package that is available at @uref{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster}. After installing, you can start Cluster 3.0 as a GUI program by double-clicking on its icon. To run Cluster 3.0 as a command line program (e.g., from the Terminal), most likely you will need to give the full path to the executable (e.g., @code{/Applications/Cluster.app/Contents/MacOS/Cluster}). If you want to recompile Cluster 3.0, it is easiest to use the Project Builder and Interface Builder that are part of Mac OS X. The directory @code{mac} contains the project file that was used. @section Installing Cluster 3.0 for Linux/Unix Cluster 3.0 was ported to Linux/Unix using the Motif libraries. Motif is installed on most Linux/Unix computers. You will need a version compliant with Motif 2.1, such as Open Motif (@uref{http://www.opengroup.org}), which is available at @uref{http://www.motifzone.net}. Currently, LessTif (@uref{http://www.lesstif.org}) does not work correctly with Cluster 3.0. To install Cluster 3.0 on Linux/Unix, type @* @code{./configure} @* @code{make} @* @code{make install} @* This will create the executable @code{cluster} and install it in @code{/usr/local/bin}. Some auxiliary files will be installed in @code{/usr/local/cluster}. The executable can be used both as a GUI program and as a command line program. Type @* @code{cluster --help} @* for more information about running Cluster 3.0 as a command line program. @section Installing Cluster 3.0 as a command line program Cluster 3.0 can also be installed without GUI support. In this case, Cluster 3.0 can only be run as a command line program, in which the action taken by the program depends on the command line parameters. To install Cluster 3.0 as a command line program, the Motif libraries are not needed. Simply download the source code for the C Clustering Library from our website @uref{http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster}, unpack and untar the file, and change to the directory @code{cluster-@emph{}}. Then type @* @code{./configure --without-x} @* @code{make} @* @code{make install} @* For the last step, you may need superuser privileges. For more information about the command line options, check the Cluster 3.0 manual. @node Bibliography, , , @unnumbered Bibliography @noindent Brown, P. O., and Botstein, D. (1999). Exploring the new world of the genome with DNA microarrays. @emph{Nature Genetics} @strong{21} (Supplement 1), 33--37. @noindent De Hoon, M. J. L., Imoto, S., and Miyano, S. (2002). Statistical analysis of a small set of time-ordered gene expression data using linear splines. @emph{Bioinformatics} @strong{18} (11), 1477--1485. @noindent De Hoon, M. J. L., Imoto, S., Nolan, J., and Miyano, S. (2004). Open source clustering software. @emph{Bioinformatics}, @strong{20} (9), 1453--1454. @noindent Eisen, M. B., Spellman, P. T., Brown, P. O., and Botstein, D. (1998). Cluster analysis and display of genome-wide expression patterns. @emph{Proceedings of the National Academy of Science USA} @strong{95} (25), 14863--14868. @noindent Golub, G. H. and Reisch, C. (1971). Singular value decomposition and least squares solutions. In @emph{Handbook for Automatic Computation}, @strong{2}, (Linear Algebra) (J. H. Wilkinson and C. Reinsch, eds), 134--151. New York: Springer-Verlag. @noindent Hartigan, J. A. (1975). @emph{Clustering algorithms} (New York: Wiley). @noindent Jain, A. K. and Dubes, R. C. (1988). @emph{Algorithms for clustering data} (Englewood Cliffs, N.J.: Prentice Hall). @noindent Kachitvichyanukul, V. and Schmeiser, B. W. (1988). Binomial Random Variate Generation. @emph{Communications of the ACM} @strong{31} (2), 216--222. @noindent Kohonen, T. (1997). @emph{Self-organizing maps}, 2nd Edition (Berlin; New York: Springer-Verlag). @noindent L'Ecuyer, P. (1988) Efficient and Portable Combined Random Number Generators. @emph{Communications of the ACM} @strong{31} (6), 742--749,774. @noindent Sibson, R. (1973). SLINK: An optimally efficient algorithm for the single-link cluster method. @emph{The Computer Journal}, @strong{16} (1), 30--34. @noindent Snedecor, G. W. and Cochran, W. G. (1989). @emph{Statistical methods} (Ames, Iowa: Iowa State University Press). @noindent Tamayo, P., Slonim, D., Mesirov, J., Zhu, Q., Kitareewan, S., Dmitrovsky, E., Lander, E., and Golub, T. (1999). Interpreting patterns of gene expression with self-organizing maps: Methods and application to hematopoietic differentiation. @emph{Proceedings of the National Academy of Science USA}, @strong{96} (6), 2907--2912. @noindent Tryon, R. C., and Bailey, D. E. (1970). @emph{Cluster analysis} (New York: McGraw-Hill). @noindent Tukey, J. W. (1977). @emph{Exploratory data analysis} (Reading, Mass.: Addison-Wesley Pub. Co.). @noindent Yeung, K. Y., and Ruzzo, W. L. (2001). Principal Component Analysis for clustering gene expression data. @emph{Bioinformatics}, @strong{17} (9), 763--774. @bye cluster-1.52a/depcomp0000755000100500010050000004426711314437555014513 0ustar mdehoonmdehoon#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2009-04-28.21; # UTC # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free # Software Foundation, Inc. # 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, 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, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u="sed s,\\\\\\\\,/,g" depmode=msvisualcpp fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add `dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cluster-1.52a/configure0000755000100500010050000060264412177155026015042 0ustar mdehoonmdehoon#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for cluster 1.52. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='cluster' PACKAGE_TARNAME='cluster' PACKAGE_VERSION='1.52' PACKAGE_STRING='cluster 1.52' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="src/cluster.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS X_EXTRA_LIBS X_LIBS X_PRE_LIBS X_CFLAGS XMKMF RANLIB MOTIF_FALSE MOTIF_TRUE LIBOBJS EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking with_x ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP XMKMF' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures cluster 1.52 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/cluster] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of cluster 1.52:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-x use the X Window System Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor XMKMF Path to xmkmf, Makefile generator for X Window System Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF cluster configure 1.52 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by cluster $as_me 1.52, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.12' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='cluster' VERSION='1.52' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' ac_config_headers="$ac_config_headers config.h" # Checks for programs. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # Checks for header files. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_header_mongrel "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default" if test "x$ac_cv_header_float_h" = xyes; then : fi ac_fn_c_check_header_mongrel "$LINENO" "math.h" "ac_cv_header_math_h" "$ac_includes_default" if test "x$ac_cv_header_math_h" = xyes; then : fi ac_fn_c_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default" if test "x$ac_cv_header_stdio_h" = xyes; then : fi ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes; then : fi ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default" if test "x$ac_cv_header_string_h" = xyes; then : fi ac_fn_c_check_header_mongrel "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default" if test "x$ac_cv_header_time_h" = xyes; then : fi # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi # Checks for library functions. for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDLIB_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 $as_echo_n "checking for GNU libc compatible malloc... " >&6; } if ${ac_cv_func_malloc_0_nonnull+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_malloc_0_nonnull=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *malloc (); #endif int main () { return ! malloc (0); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_malloc_0_nonnull=yes else ac_cv_func_malloc_0_nonnull=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5 $as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } if test $ac_cv_func_malloc_0_nonnull = yes; then : $as_echo "#define HAVE_MALLOC 1" >>confdefs.h else $as_echo "#define HAVE_MALLOC 0" >>confdefs.h case " $LIBOBJS " in *" malloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;; esac $as_echo "#define malloc rpl_malloc" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt,exp,log in -lm" >&5 $as_echo_n "checking for sqrt,exp,log in -lm... " >&6; } if ${ac_cv_lib_m_sqrt_exp_log+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sqrt,exp,log (); int main () { return sqrt,exp,log (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_sqrt_exp_log=yes else ac_cv_lib_m_sqrt_exp_log=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt_exp_log" >&5 $as_echo "$ac_cv_lib_m_sqrt_exp_log" >&6; } if test "x$ac_cv_lib_m_sqrt_exp_log" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi # Check if we are building the GUI version or the command line version ac_config_files="$ac_config_files Makefile src/Makefile" if test "$with_x" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: Building command-line version of Cluster 3.0" >&5 $as_echo "$as_me: Building command-line version of Cluster 3.0" >&6;} if false; then MOTIF_TRUE= MOTIF_FALSE='#' else MOTIF_TRUE='#' MOTIF_FALSE= fi else { $as_echo "$as_me:${as_lineno-$LINENO}: Building GUI version of Cluster 3.0 using Motif" >&5 $as_echo "$as_me: Building GUI version of Cluster 3.0 using Motif" >&6;} if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 $as_echo_n "checking for X... " >&6; } # Check whether --with-x was given. if test "${with_x+set}" = set; then : withval=$with_x; fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else case $x_includes,$x_libraries in #( *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -f -r conftest.dir if mkdir conftest.dir; then cd conftest.dir cat >Imakefile <<'_ACEOF' incroot: @echo incroot='${INCROOT}' usrlibdir: @echo usrlibdir='${USRLIBDIR}' libdir: @echo libdir='${LIBDIR}' _ACEOF if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. for ac_var in incroot usrlibdir libdir; do eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && test -f "$ac_im_libdir/libX11.$ac_extension"; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ac_x_includes= ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /usr/lib64 | /lib | /lib64) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -f -r conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R7/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R7 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R7/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R7 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Xlib.h. # First, try using that file with no special directory specified. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # We can compile using X headers with no special include directory. ac_x_includes= else for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Xlib.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.i conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lX11 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { XrmInitialize () ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else LIBS=$ac_save_LIBS for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r "$ac_dir/libX11.$ac_extension"; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no case $ac_x_includes,$ac_x_libraries in #( no,* | *,no | *\'*) # Didn't find X, or a directory has "'" in its name. ac_cv_have_x="have_x=no";; #( *) # Record where we found X for the cache. ac_cv_have_x="have_x=yes\ ac_x_includes='$ac_x_includes'\ ac_x_libraries='$ac_x_libraries'" esac fi ;; #( *) have_x=yes;; esac eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 $as_echo "$have_x" >&6; } no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes\ ac_x_includes='$x_includes'\ ac_x_libraries='$x_libraries'" { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 $as_echo "libraries $x_libraries, headers $x_includes" >&6; } fi if test "$no_x" = yes; then # Not all programs may use this symbol, but it does not hurt to define it. $as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= else if test -n "$x_includes"; then X_CFLAGS="$X_CFLAGS -I$x_includes" fi # It would also be nice to do this for all -L options, not just this one. if test -n "$x_libraries"; then X_LIBS="$X_LIBS -L$x_libraries" # For Solaris; some versions of Sun CC require a space after -R and # others require no space. Words are not sufficient . . . . { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5 $as_echo_n "checking whether -R must be followed by a space... " >&6; } ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" ac_xsave_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } X_LIBS="$X_LIBS -R$x_libraries" else LIBS="$ac_xsave_LIBS -R $x_libraries" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } X_LIBS="$X_LIBS -R $x_libraries" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5 $as_echo "neither works" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_c_werror_flag=$ac_xsave_c_werror_flag LIBS=$ac_xsave_LIBS fi # Check for system-dependent libraries X programs must link with. # Do this before checking for the system-independent R6 libraries # (-lICE), since we may need -lsocket or whatever for X linking. if test "$ISC" = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" else # Martyn Johnson says this is needed for Ultrix, if the X # libraries were built with DECnet support. And Karl Berry says # the Alpha needs dnet_stub (dnet does not exist). ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XOpenDisplay (); int main () { return XOpenDisplay (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dnet_dnet_ntoa=yes else ac_cv_lib_dnet_dnet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet_stub $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dnet_stub_dnet_ntoa=yes else ac_cv_lib_dnet_stub_dnet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_xsave_LIBS" # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, # to get the SysV transport functions. # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) # needs -lnsl. # The nsl library prevents programs from opening the X display # on Irix 5.2, according to T.E. Dickey. # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" if test "x$ac_cv_func_gethostbyname" = xyes; then : fi if test $ac_cv_func_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } if ${ac_cv_lib_nsl_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_gethostbyname=yes else ac_cv_lib_nsl_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; } if ${ac_cv_lib_bsd_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_bsd_gethostbyname=yes else ac_cv_lib_bsd_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi fi fi # lieder@skyler.mavd.honeywell.com says without -lsocket, # socket/setsockopt and other routines are undefined under SCO ODT # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary # on later versions), says Simon Leinen: it contains gethostby* # variants that don't use the name server (or something). -lsocket # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect" if test "x$ac_cv_func_connect" = xyes; then : fi if test $ac_cv_func_connect = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } if ${ac_cv_lib_socket_connect+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char connect (); int main () { return connect (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_connect=yes else ac_cv_lib_socket_connect=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } if test "x$ac_cv_lib_socket_connect" = xyes; then : X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi fi # Guillermo Gomez says -lposix is necessary on A/UX. ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove" if test "x$ac_cv_func_remove" = xyes; then : fi if test $ac_cv_func_remove = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 $as_echo_n "checking for remove in -lposix... " >&6; } if ${ac_cv_lib_posix_remove+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lposix $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char remove (); int main () { return remove (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_posix_remove=yes else ac_cv_lib_posix_remove=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 $as_echo "$ac_cv_lib_posix_remove" >&6; } if test "x$ac_cv_lib_posix_remove" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat" if test "x$ac_cv_func_shmat" = xyes; then : fi if test $ac_cv_func_shmat = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 $as_echo_n "checking for shmat in -lipc... " >&6; } if ${ac_cv_lib_ipc_shmat+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lipc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shmat (); int main () { return shmat (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ipc_shmat=yes else ac_cv_lib_ipc_shmat=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 $as_echo "$ac_cv_lib_ipc_shmat" >&6; } if test "x$ac_cv_lib_ipc_shmat" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi fi fi # Check for libraries that X11R6 Xt/Xaw programs need. ac_save_LDFLAGS=$LDFLAGS test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to # check for ICE first), but we must link in the order -lSM -lICE or # we get undefined symbols. So assume we have SM if we have ICE. # These have to be linked with before -lX11, unlike the other # libraries we check for below, so use a different variable. # John Interrante, Karl Berry { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lICE $X_EXTRA_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char IceConnectionNumber (); int main () { return IceConnectionNumber (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ICE_IceConnectionNumber=yes else ac_cv_lib_ICE_IceConnectionNumber=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi LDFLAGS=$ac_save_LDFLAGS fi if test "$no_x" = "yes"; then as_fn_error $? "Failed to locate the X11 include files and libraries. Use --without-x if you want to build the command-line version of Cluster 3.0." "$LINENO" 5 fi LIBS="$X_PRE_LIBS -lX11 $X_LIBS $X_EXTRA_LIB $LIBS" CPPFLAGS="$X_CFLAGS $CPPFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XShapeQueryVersion in -lXext" >&5 $as_echo_n "checking for XShapeQueryVersion in -lXext... " >&6; } if ${ac_cv_lib_Xext_XShapeQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXext $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XShapeQueryVersion (); int main () { return XShapeQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xext_XShapeQueryVersion=yes else ac_cv_lib_Xext_XShapeQueryVersion=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_XShapeQueryVersion" >&5 $as_echo "$ac_cv_lib_Xext_XShapeQueryVersion" >&6; } if test "x$ac_cv_lib_Xext_XShapeQueryVersion" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBXEXT 1 _ACEOF LIBS="-lXext $LIBS" else as_fn_error $? "Failed to locate the Xext library. Use --without-x if you want to build the command-line version of Cluster 3.0." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XtMalloc in -lXt" >&5 $as_echo_n "checking for XtMalloc in -lXt... " >&6; } if ${ac_cv_lib_Xt_XtMalloc+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XtMalloc (); int main () { return XtMalloc (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xt_XtMalloc=yes else ac_cv_lib_Xt_XtMalloc=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xt_XtMalloc" >&5 $as_echo "$ac_cv_lib_Xt_XtMalloc" >&6; } if test "x$ac_cv_lib_Xt_XtMalloc" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBXT 1 _ACEOF LIBS="-lXt $LIBS" else as_fn_error $? "Failed to locate the Xt library. Use --without-x if you want to build the command-line version of Cluster 3.0." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XmStringCreateSimple in -lXm" >&5 $as_echo_n "checking for XmStringCreateSimple in -lXm... " >&6; } if ${ac_cv_lib_Xm_XmStringCreateSimple+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XmStringCreateSimple (); int main () { return XmStringCreateSimple (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xm_XmStringCreateSimple=yes else ac_cv_lib_Xm_XmStringCreateSimple=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xm_XmStringCreateSimple" >&5 $as_echo "$ac_cv_lib_Xm_XmStringCreateSimple" >&6; } if test "x$ac_cv_lib_Xm_XmStringCreateSimple" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBXM 1 _ACEOF LIBS="-lXm $LIBS" else as_fn_error $? "Failed to locate the Motif library. Use --without-x if you want to build the command-line version of Cluster 3.0." "$LINENO" 5 fi ac_fn_c_check_header_mongrel "$LINENO" "Xm/Xm.h" "ac_cv_header_Xm_Xm_h" "$ac_includes_default" if test "x$ac_cv_header_Xm_Xm_h" = xyes; then : else as_fn_error $? "Failed to locate the Motif header files. Use --without-x if you want to build the command-line version of Cluster 3.0. Otherwise, use CPPFLAGS to add the Motif header directory to the path. For example, if Xm.h is in /usr/X11R6/include/Xm, use ./configure CPPFLAGS=-I/usr/X11R6/include " "$LINENO" 5 fi if true; then MOTIF_TRUE= MOTIF_FALSE='#' else MOTIF_TRUE='#' MOTIF_FALSE= fi ac_config_files="$ac_config_files X11/Makefile" fi cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MOTIF_TRUE}" && test -z "${MOTIF_FALSE}"; then as_fn_error $? "conditional \"MOTIF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MOTIF_TRUE}" && test -z "${MOTIF_FALSE}"; then as_fn_error $? "conditional \"MOTIF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by cluster $as_me 1.52, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ cluster config.status 1.52 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "X11/Makefile") CONFIG_FILES="$CONFIG_FILES X11/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi cluster-1.52a/TODO0000644000100500010050000000016010475474277013617 0ustar mdehoonmdehoonGUI versions: ------------- Add SOM cluster result to output files Add GORDER/EORDER fields to SOM output files cluster-1.52a/INSTALL0000644000100500010050000001147311056014770014151 0ustar mdehoonmdehoonINSTALLATION ============ The installation procedure depends on the software package you want to use. Below you will find instructions for Cluster 3.0 for Windows, Mac OS X, and Unix/Linux, Cluster 3.0 as a command-line program, Pycluster (for Python), and Algorithm::Cluster (for Perl). Cluster 3.0 for Windows ----------------------- For Cluster 3.0 for Windows, download the Windows installer from our website (http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/clustersetup.exe). Run the installer, and you're done. If for some reason, you want to recompile Cluster 3.0 from the source, you can use the Makefile in the windows subdirectory. This makefile was used with Cygwin/Mingw under Windows, and may need to be modified for other systems. Type make in the windows subdirectory to compile the C Clustering Library, the Cluster 3.0 GUI, the Windows help files and the documentation. You will need an ANSI C compiler such as GNU gcc, as well as the GNU windres program to compile the resources for the GUI. To generate the help files, you will need the HTML Help SDK, which can be downloaded from Microsoft, as well as the GNU makeinfo program. To generate the Windows installer, type make clustersetup.exe For this, you will need the Inno Setup Compiler, which can be downloaded from http://www.jrsoftware.org. Cluster 3.0 for Mac OS X ------------------------ Cluster 3.0 can be installed most easily on Mac OS X by using the installer for Mac OS X, which is available at http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster. If you want to recompile Cluster 3.0, it is easiest to use Xcode and Interface Builder that are part of Mac OS X. The subdirectory mac contains the project file that was used to compile Cluster 3.0. Cluster 3.0 for Linux/Unix -------------------------- Cluster 3.0 was ported to Linux/Unix using the Motif libraries. These libraries are installed on most Linux/Unix computers. You will need a version compliant with Motif 2.1, such as OpenMotif (http://www.opengroup.org), which is available at http://www.motifzone.net. Cluster 3.0 can be installed on Unix/Linux by typing ./configure make make install This will create the executable cluster and install it in /usr/local/bin. Some auxiliary files are installed in /usr/local/cluster. The executable can be used as a GUI program and as a command line program. For more options, such as installing in a different directory, type ./configure --help Cluster 3.0 as a command line program ------------------------------------- Cluster 3.0 can also be built without GUI support. The executable can then only be used as a command line program. This can be useful if you do not want to install the Motif libraries, which are required for the GUI. To install Cluster 3.0 as a command line program, type ./configure --without-x make make install This will create the executable cluster and install it in /usr/local/bin. Some auxiliary files (such as the documentation) are installed in /usr/local/cluster. For more options, such as installing in a different directory, type ./configure --help Python ------ In the top directory (containing setup.py and also this INSTALL file), type python setup.py install You will need a fairly recent version of Python (2.0 or higher) and the Numerical Python package (NumPy version 1.1.1 or later), as well as an ANSI C compiler such as GNU gcc. You may need to log in as root the install Pycluster. If you do not have root access, do python setup.py install --prefix=/some/other/directory and set the environment variable PYTHONPATH=/some/other/directory/lib/python2.2/site-packages The exact command depends on which shell you are using; the exact path will depend on the version of Python you are using. Note that Pycluster is also available as a tarball containing only the source code needed for Pycluster. A Windows installer for Pycluster is available from our website (http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster). Biopython versions 1.11 and up also contain Pycluster. There, it is referred to as Bio.Cluster. See http://www.biopython.org. Perl ---- For Perl, type perl Makefile.PL make make test make install You will need Perl version 5.6 or newer. For the install step, you will need root access. If you do not have root priviliges, use perl Makefile.PL prefix=/some/other/directory to install the module in /some/other/directory/lib/perl5/. The subdirectory perl/examples contains some example Perl scripts that use Algorithm::Cluster. To install Algorithm::Cluster for Perl 5.8 and Perl 5.10 on Windows, you can use the precompiled package by executing ppm install http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/Algorithm-Cluster.ppd CONTACT ======= Michiel de Hoon, University of Tokyo, Human Genome Center (currently at the RIKEN Genomic Sciences Center) Email: mdehoon 'AT' gsc.riken.jp cluster-1.52a/COPYING0000644000100500010050000000172307705176162014162 0ustar mdehoonmdehoonLicense Information =================== The Open Source Clustering Software consists of several packages, which have different licenses. * Cluster 3.0 is a GUI-based program for Windows, Mac OS X, Linux, and Unix. It is based on Michael Eisen's Cluster/TreeView code. Cluster 3.0 is covered by Michael Eisen's original license, available at http://rana.lbl.gov/EisenSoftwareSource.htm. The command-line version of Cluster 3.0 is also covered by this license. * Pycluster is an extension module to the scripting language Python. It is covered by the Python License (same license as Python itself). * Algorithm::Cluster, the interface to the scripting language Perl. It was released under the Artistic License (same license as Perl itself). * The routines in the C Clustering Library can also be used directly by calling them from other C programs. In that case, the Python License applies. In all cases, copyright notices must be retained in their original form. cluster-1.52a/README0000644000100500010050000000475510761773361014017 0ustar mdehoonmdehoonOpen Source Clustering Software =============================== The Open Source Clustering Software consists of the most commonly used routines for clustering analysis of gene expression data. The software packages below all depend on the C Clustering Library, which is a library of routines for hierarchical (pairwise single-, complete-, maximum-, and average-linkage) clustering, k-means clustering, and Self-Organizing Maps on a 2D rectangular grid. The C Clustering Library complies with the ANSI C standard. Several packages are available as part of the Open Source Clustering Software: * Cluster 3.0 is a GUI-based program for Windows, based on Michael Eisen's Cluster/TreeView code. Cluster 3.0 was written for Microsoft Windows, and subsequently ported to Mac OS X (Cocoa) and Unix/Linux. Cluster 3.0 can also be used as a command line program. * Pycluster (or Bio.Cluster if used as part of Biopython) is an extension module to the scripting language Python. * Algorithm::Cluster is an extension module to the scripting language Perl. * The routines in the C Clustering Library can also be used directly by calling them from other C programs. INSTALLATION ============ See the INSTALL file in this directory. VIEWING CLUSTERING RESULTS ========================== We recommend using Java TreeView for visualizing clustering results. Java TreeView is a Java version of Michael Eisen's Treeview program with extended capabilities. In particular, it is possible to visualize k-means clustering results in addition to hierarchical clustering results. Java TreeView was written by Alok Saldanha at Stanford University; it can be downloaded at http://jtreeview.sourceforge.net. MANUAL ====== The routines in the C Clustering Library is described in the manual (cluster.pdf). This manual also describes how to use the routines from Python and from Perl. Cluster 3.0 has a separate manual (cluster3.pdf). Both of these manuals can be found in the doc subdirectory. They can also be downloaded from our website: http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/cluster.pdf; http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/cluster3.pdf. LITERATURE ========== M.J.L. de Hoon, S. Imoto, J. Nolan, and S. Miyano: "Open Source Clustering Software", Bioinformatics 20(9): 1453-1454 (2004). CONTACT ======= Michiel de Hoon University of Tokyo, Institute of Medical Science Human Genome Center, Laboratory of DNA Information Analysis Currently at RIKEN Genomic Sciences Center mdehoon 'AT' gsc.riken.jp