phylobase/0000755000176200001440000000000013076514135012245 5ustar liggesusersphylobase/inst/0000755000176200001440000000000012436140014013210 5ustar liggesusersphylobase/inst/nexmlfiles/0000755000176200001440000000000012734240156015367 5ustar liggesusersphylobase/inst/nexmlfiles/comp_analysis.xml0000644000176200001440000001371112364507744020765 0ustar liggesusers phylobase/inst/nexusfiles/0000755000176200001440000000000013075412334015404 5ustar liggesusersphylobase/inst/nexusfiles/treeWithPolyExcludedData.nex0000644000176200001440000003226412347155416023044 0ustar liggesusers#NEXUS [written Wed Mar 10 11:51:23 EST 2010 by Mesquite version 2.72 (build 527) at francois-laptop/127.0.1.1] BEGIN TAXA; TITLE Taxa; DIMENSIONS NTAX=18; TAXLABELS Myrmecocystuscfnavajo Myrmecocystuscreightoni Myrmecocystusdepilis Myrmecocystuskathjuli Myrmecocystuskennedyi Myrmecocystusmendax Myrmecocystusmexicanus Myrmecocystusmimicus Myrmecocystusnavajo Myrmecocystusnequazcatl Myrmecocystusplacodops Myrmecocystusromainei Myrmecocystussemirufus Myrmecocystussnellingi Myrmecocystustenuinodis Myrmecocystustestaceus Myrmecocystuswheeleri Myrmecocystusyuma ; END; BEGIN CHARACTERS; TITLE testIncomplete; DIMENSIONS NCHAR=3; FORMAT DATATYPE = STANDARD GAP = - MISSING = ? SYMBOLS = "0 1 2"; CHARSTATELABELS 1 Test1 /test1A test1B, 2 Test2 /test2A test2B, 3 Test3 /test3A test3B test3C; MATRIX Myrmecocystuscfnavajo 1(0 1)(0 1 2) Myrmecocystuscreightoni ?(0 1)(0 1) Myrmecocystusdepilis 102 Myrmecocystuskathjuli 100 Myrmecocystuskennedyi 010 Myrmecocystusmendax 101 Myrmecocystusmexicanus 000 Myrmecocystusmimicus ??0 Myrmecocystusnavajo ?11 Myrmecocystusnequazcatl 100 Myrmecocystusplacodops 001 Myrmecocystusromainei 11(0 1 2) Myrmecocystussemirufus 001 Myrmecocystussnellingi 1?0 Myrmecocystustenuinodis 101 Myrmecocystustestaceus ??0 Myrmecocystuswheeleri 000 Myrmecocystusyuma 01? ; END; BEGIN TREES; Title 'Trees from "treepluscharV01.nex"'; LINK Taxa = Taxa; TRANSLATE 1 Myrmecocystuscfnavajo, 2 Myrmecocystuscreightoni, 3 Myrmecocystusdepilis, 4 Myrmecocystuskathjuli, 5 Myrmecocystuskennedyi, 6 Myrmecocystusmendax, 7 Myrmecocystusmexicanus, 8 Myrmecocystusmimicus, 9 Myrmecocystusnavajo, 10 Myrmecocystusnequazcatl, 11 Myrmecocystusplacodops, 12 Myrmecocystusromainei, 13 Myrmecocystussemirufus, 14 Myrmecocystussnellingi, 15 Myrmecocystustenuinodis, 16 Myrmecocystustestaceus, 17 Myrmecocystuswheeleri, 18 Myrmecocystusyuma; TREE bestML = (((((((((13:1.724765,11:1.724765):2.926053,6:4.650818):0.689044,(4:1.08387,17:1.08387):4.255993):0.198842,((8:2.708942,3:2.708942):2.027251,((12:2.193845,10:2.193845):2.257581,18:4.451425):0.284767):0.802512):0.506099,5:6.044804):4.524387,2:10.569191):0.836689,(14:2.770378,15:2.770378):8.635503):0.89482,16:12.300701):1.699299,(7:5.724923,(1:2.869547,9:2.869547):2.855375):8.275077); END; BEGIN ASSUMPTIONS; TYPESET * UNTITLED = unord: 1 - 3; EXSET * UNTITLED = 3; END; BEGIN MESQUITECHARMODELS; ProbModelSet * UNTITLED = 'Mk1 (est.)': 1 - 3; END; Begin MESQUITE; MESQUITESCRIPTVERSION 2; TITLE AUTO; tell ProjectCoordinator; timeSaved 1268239884091; getEmployee #mesquite.minimal.ManageTaxa.ManageTaxa; tell It; setID 0 9015005506118934442; endTell; getEmployee #mesquite.charMatrices.ManageCharacters.ManageCharacters; tell It; setID 0 2565950173085067248; checksumv 0 2 4144740407 null numChars 3 short true bits 7 states 7 sumSquaresStatesOnly 220.0 NumFiles 1 NumMatrices 1; endTell; getWindow; tell It; suppress; setResourcesState false false 155; setPopoutState 400; setExplanationSize 0; setAnnotationSize 0; setFontIncAnnot 0; setFontIncExp 0; setSize 1278 934; setLocation 1440 0; setFont SanSerif; setFontSize 10; getToolPalette; tell It; endTell; desuppress; endTell; getEmployee #mesquite.trees.BasicTreeWindowCoord.BasicTreeWindowCoord; tell It; makeTreeWindow #9015005506118934442 #mesquite.trees.BasicTreeWindowMaker.BasicTreeWindowMaker; tell It; suppressEPCResponse; setTreeSource #mesquite.trees.StoredTrees.StoredTrees; tell It; setTreeBlock 1; toggleUseWeights off; endTell; setAssignedID 630.1180487973731.4514395117633566598; getTreeWindow; tell It; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; setSize 1123 867; setLocation 1440 0; setFont SanSerif; setFontSize 10; getToolPalette; tell It; endTell; getTreeDrawCoordinator #mesquite.trees.BasicTreeDrawCoordinator.BasicTreeDrawCoordinator; tell It; suppress; setTreeDrawer #mesquite.trees.DiagonalDrawTree.DiagonalDrawTree; tell It; setNodeLocs #mesquite.trees.NodeLocsStandard.NodeLocsStandard; tell It; inhibitStretchToggle on; branchLengthsToggle off; toggleScale on; toggleBroadScale off; toggleCenter off; toggleEven off; endTell; setEdgeWidth 12; orientUp; endTell; setBackground White; setBranchColor Black; showNodeNumbers off; showBranchColors on; labelBranchLengths off; centerBrLenLabels on; showBrLensUnspecified on; showBrLenLabelsOnTerminals on; setBrLenLabelColor 0 0 255; setNumBrLenDecimals 6; desuppress; getEmployee #mesquite.trees.BasicDrawTaxonNames.BasicDrawTaxonNames; tell It; setColor Black; toggleColorPartition on; toggleShadePartition off; toggleShowFootnotes on; toggleNodeLabels on; toggleCenterNodeNames off; toggleShowNames on; namesAngle ?; endTell; endTell; setTreeNumber 1; setDrawingSizeMode 0; toggleLegendFloat on; scale 0; toggleTextOnTree off; showWindow; newAssistant #mesquite.ancstates.TraceCharacterHistory.TraceCharacterHistory; tell It; suspend ; setDisplayMode #mesquite.ancstates.ShadeStatesOnTree.ShadeStatesOnTree; tell It; toggleLabels off; toggleGray off; endTell; setHistorySource #mesquite.ancstates.RecAncestralStates.RecAncestralStates; tell It; getCharacterSource #mesquite.charMatrices.CharSrcCoordObed.CharSrcCoordObed; tell It; setCharacterSource #mesquite.charMatrices.StoredCharacters.StoredCharacters; tell It; setDataSet #2565950173085067248; endTell; endTell; setMethod #mesquite.parsimony.ParsAncestralStates.ParsAncestralStates; tell It; setModelSource #mesquite.parsimony.CurrentParsModels.CurrentParsModels; toggleMPRsMode off; endTell; endTell; setCharacter 1; setMapping 1; toggleShowLegend on; toggleGray off; toggleWeights on; setInitialOffsetX 4; setInitialOffsetY -191; setLegendWidth 142; setLegendHeight 191; resume ; endTell; endTell; desuppressEPCResponse; getEmployee #mesquite.trees.ColorBranches.ColorBranches; tell It; setColor Red; removeColor off; endTell; getEmployee #mesquite.ornamental.BranchNotes.BranchNotes; tell It; setAlwaysOn off; endTell; getEmployee #mesquite.ornamental.ColorTreeByPartition.ColorTreeByPartition; tell It; colorByPartition off; endTell; getEmployee #mesquite.ornamental.DrawTreeAssocDoubles.DrawTreeAssocDoubles; tell It; setOn on; setDigits 4; writeAsPercentage off; toggleCentred on; toggleHorizontal on; setFontSize 10; setOffset 0 0; endTell; getEmployee #mesquite.trees.TreeInfoValues.TreeInfoValues; tell It; panelOpen false; endTell; endTell; endTell; getEmployee #mesquite.charMatrices.BasicDataWindowCoord.BasicDataWindowCoord; tell It; showDataWindow #2565950173085067248 #mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindowMaker; tell It; getWindow; tell It; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; setSize 1123 867; setLocation 1440 0; setFont SanSerif; setFontSize 10; getToolPalette; tell It; endTell; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.arrow; colorCells #mesquite.charMatrices.NoColor.NoColor; colorRowNames #mesquite.charMatrices.TaxonGroupColor.TaxonGroupColor; colorColumnNames #mesquite.charMatrices.CharGroupColor.CharGroupColor; colorText #mesquite.charMatrices.NoColor.NoColor; setBackground White; toggleShowNames on; toggleShowTaxonNames on; toggleTight off; toggleThinRows off; toggleShowChanges on; toggleSeparateLines off; toggleShowStates on; toggleAutoWCharNames on; toggleAutoTaxonNames off; toggleShowDefaultCharNames off; toggleConstrainCW on; setColumnWidth 70; toggleBirdsEye off; toggleAllowAutosize on; toggleColorsPanel off; toggleDiagonal on; setDiagonalHeight 80; toggleLinkedScrolling on; toggleScrollLinkedTables off; endTell; hideWindow; getEmployee #mesquite.charMatrices.ColorCells.ColorCells; tell It; setColor Red; removeColor off; endTell; getEmployee #mesquite.categ.StateNamesStrip.StateNamesStrip; tell It; showStrip off; endTell; getEmployee #mesquite.charMatrices.AnnotPanel.AnnotPanel; tell It; togglePanel off; endTell; getEmployee #mesquite.charMatrices.CharReferenceStrip.CharReferenceStrip; tell It; showStrip off; endTell; getEmployee #mesquite.charMatrices.QuickKeySelector.QuickKeySelector; tell It; autotabOff; endTell; getEmployee #mesquite.categ.SmallStateNamesEditor.SmallStateNamesEditor; tell It; panelOpen true; endTell; endTell; showExtraDataWindow #2565950173085067248 #mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindowMaker; tell It; getWindow; tell It; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; setSize 1123 867; setLocation 1440 0; setFont SanSerif; setFontSize 10; getToolPalette; tell It; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.ibeam; endTell; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.ibeam; colorCells #mesquite.charMatrices.NoColor.NoColor; colorRowNames #mesquite.charMatrices.TaxonGroupColor.TaxonGroupColor; colorColumnNames #mesquite.charMatrices.CharGroupColor.CharGroupColor; colorText #mesquite.charMatrices.NoColor.NoColor; setBackground White; toggleShowNames on; toggleShowTaxonNames on; toggleTight off; toggleThinRows off; toggleShowChanges on; toggleSeparateLines off; toggleShowStates on; toggleAutoWCharNames on; toggleAutoTaxonNames off; toggleShowDefaultCharNames off; toggleConstrainCW on; toggleBirdsEye off; toggleAllowAutosize on; toggleColorsPanel off; toggleDiagonal on; setDiagonalHeight 80; toggleLinkedScrolling on; toggleScrollLinkedTables off; getInfoPanel; tell It; btspOpen true; apOpen true; fpOpen true; endTell; toggleInfoPanel off; endTell; showWindow; getWindow; tell It; forceAutosize; endTell; getEmployee #mesquite.charMatrices.ColorCells.ColorCells; tell It; setColor Red; removeColor off; endTell; getEmployee #mesquite.categ.StateNamesEditor.StateNamesEditor; tell It; makeWindow; tell It; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; setSize 1123 867; setLocation 1440 0; setFont SanSerif; setFontSize 10; getToolPalette; tell It; setTool mesquite.categ.StateNamesEditor.StateNamesWindow.ibeam; endTell; setActive; rowsAreCharacters on; toggleConstrainChar on; toggleConstrainCharNum 3; togglePanel off; toggleSummaryPanel off; endTell; showWindow; endTell; getEmployee #mesquite.categ.StateNamesStrip.StateNamesStrip; tell It; showStrip off; endTell; getEmployee #mesquite.charMatrices.AnnotPanel.AnnotPanel; tell It; togglePanel off; endTell; getEmployee #mesquite.charMatrices.CharReferenceStrip.CharReferenceStrip; tell It; showStrip off; endTell; getEmployee #mesquite.charMatrices.QuickKeySelector.QuickKeySelector; tell It; autotabOff; endTell; getEmployee #mesquite.categ.SmallStateNamesEditor.SmallStateNamesEditor; tell It; panelOpen true; endTell; endTell; endTell; getEmployee #mesquite.charMatrices.ManageCharacters.ManageCharacters; tell It; showCharacters #2565950173085067248 #mesquite.lists.CharacterList.CharacterList; tell It; setData 0; getWindow; tell It; newAssistant #mesquite.lists.DefaultCharOrder.DefaultCharOrder; newAssistant #mesquite.lists.CharListInclusion.CharListInclusion; newAssistant #mesquite.lists.CharListPartition.CharListPartition; newAssistant #mesquite.stochchar.CharListProbModels.CharListProbModels; getTable; tell It; columnWidth 1 101; endTell; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; setSize 1123 867; setLocation 1440 0; setFont SanSerif; setFontSize 10; getToolPalette; tell It; setTool mesquite.lists.CharacterList.CharacterListWindow.arrow; endTell; endTell; showWindow; getEmployee #mesquite.lists.CharListAnnotPanel.CharListAnnotPanel; tell It; togglePanel off; endTell; endTell; endTell; endTell; end; begin brownie; taxset all = 1 -18; END; phylobase/inst/nexusfiles/MultiLineTrees.nex0000644000176200001440000000505212347155416021035 0ustar liggesusers#NEXUS Begin trees; Translate 1 Acorus, 2 Protarum, 3 Biarum, 4 Helicodiceros, 5 Eminium, 6 Dracunculus, 7 Pinellia, 8 Peltandra, 9 Steudnera, 10 Remusatia, 11 Colocasia, 12 Arum, 13 Callopsis, 14 Spathicarpa, 15 Dieffenbachia, 16 Dracontium, 17 Anaphyllopsis, 18 Gonatopus, 19 Epipremnum, 20 Scindapsus, 21 Anadendrum, 22 Stenospermation, 23 Monstera, 24 Rhodospatha, 25 Holochlamys, 26 Heteropsis, 27 Amydrium, 28 Rhaphidophora, 29 Spathiphyllum, 30 Pothos, 31 Anthurium, 32 Cercestis, 33 Aglaonema1, 34 Montrichardia, 35 Philodendron, 36 Anubias, 37 Nephthytis, 38 Rhektophyllum, 39 Anchomanes, 40 Typhonodorum, 41 Typhonium, 42 Spirodela, 43 Landoltia, 44 Asterostigma, 45 Zantedeschia, 46 Calla, 47 Schismatoglottis, 48 Zamioculcas, 49 Culcasia, 50 Cyrtosperma, 51 Aglaonema, 52 Scaphispatha, 53 Chlorospatha, 54 Arophyton, 55 Jasarum, 56 Caladium, 57 Xanthosoma, 58 Hapaline, 59 Ambrosina, 60 Alocasia, 61 Pistia, 62 Homalomena, 63 Amorphophallus, 64 Alloschemone, 65 Arisaema, 66 Symplocarpus, 67 Orontium, 68 Lysichiton, 69 Gymnostachys ; tree PAUP_1 = [&U] (1:70,((((((((((((((((((((2:4,(((3:0,((4:1,12:0):0,(5:2,6:0):1):0):2,7:7):1, ((9:1,10:0):1,11:0):1):0):2,61:13):0,(60:3,65:4):1):1,41:3):5,59:20):1,8:4):0,40:8):4, ((((52:5,(53:2,54:6):6):2,58:7):1,((55:4,57:4):0,56:2):2):3,63:6):1):11,((32:2,37:1):3, (33:1,51:0):2):3):1,(35:0,62:2):9):1,34:9):3,(13:5,45:13):4):0,(36:5,(38:0,39:0):4):1):2, ((14:7,15:10):6,44:13):10):4,(46:17,47:6):3):3,(((16:1,17:1):0,50:1):13,(18:2,48:5):2):3):1,49:8):6, ((((19:4,20:1):1,(((21:4,(23:2,(25:5,29:3):3):0):1,28:2):0,27:2):0):1,(((22:3,64:11):0,26:3):1, 24:2):1):7,(30:6,31:31):4):11):11,(42:11,43:14):20):38,(69:17,((66:3,68:3):1,67:0):12):1):36); tree PAUP_2 = [&U] (1:70,((((((((((((((((((((2:4,(((3:0,((4:1,12:0):0,(5:2,6:0):1):0):2,7:7):1, ((9:1,10:0):1,11:0):1):0):2,61:13):0,(60:3,65:4):1):1,41:3):5,59:20):1,8:4):0,40:8):4, ((((52:5,(53:2,54:6):6):2,58:7):1,((55:4,57:4):0,56:2):2):3,63:6):1):11,((32:2,37:1):3, (33:1,51:0):2):3):1,(35:0,62:2):9):1,34:9):3,(13:5,45:13):4):0,(36:5,(38:0,39:0):4):1):2, ((14:7,15:10):6,44:13):10):4,(46:17,47:6):3):3,(((16:1,17:1):0,50:1):13,(18:2,48:5):2):3):1,49:8):6, ((((19:4,20:1):1,(((21:4,(23:2,(25:5,29:3):3):0):1,28:2):0,27:2):0):1,(((22:3,64:11):0,26:3):1, 24:2):1):7,(30:6,31:31):4):11):11,(42:11,43:14):20):38,(69:17,((66:3,68:3):1,67:0):12):1):36); End; phylobase/inst/nexusfiles/NastyLabels2.nex0000644000176200001440000002100012347155416020422 0ustar liggesusers#NEXUS begin data; dimensions ntax=17 nchar=432; format datatype=dna missing=?; matrix 'h uman' ctgactcctgaggagaagtctgccgttactgccctgtggggcaaggtgaacgtggatgaagttggtggtgaggccctgggcaggctgctggtggtctacccttggacccagaggttctttgagtcctttggggatctgtccactcctgatgctgttatgggcaaccctaaggtgaaggctcatggcaagaaagtgctcggtgcctttagtgatggcctggctcacctggacaacctcaagggcacctttgccacactgagtgagctgcactgtgacaagctgcacgtggatcctgagaacttcaggctcctgggcaacgtgctggtctgtgtgctggcccatcactttggcaaagaattcaccccaccagtgcaggctgcctatcagaaagtggtggctggtgtggctaatgccctggcccacaagtatcac t_arsier ctgactgctgaagagaaggccgccgtcactgccctgtggggcaaggtagacgtggaagatgttggtggtgaggccctgggcaggctgctggtcgtctacccatggacccagaggttctttgactcctttggggacctgtccactcctgccgctgttatgagcaatgctaaggtcaaggcccatggcaaaaaggtgctgaacgcctttagtgacggcatggctcatctggacaacctcaagggcacctttgctaagctgagtgagctgcactgtgacaaattgcacgtggatcctgagaatttcaggctcttgggcaatgtgctggtgtgtgtgctggcccaccactttggcaaagaattcaccccgcaggttcaggctgcctatcagaaggtggtggctggtgtggctactgccttggctcacaagtaccac 'b_ushbaby' ctgactcctgatgagaagaatgccgtttgtgccctgtggggcaaggtgaatgtggaagaagttggtggtgaggccctgggcaggctgctggttgtctacccatggacccagaggttctttgactcctttggggacctgtcctctccttctgctgttatgggcaaccctaaagtgaaggcccacggcaagaaggtgctgagtgcctttagcgagggcctgaatcacctggacaacctcaagggcacctttgctaagctgagtgagctgcattgtgacaagctgcacgtggaccctgagaacttcaggctcctgggcaacgtgctggtggttgtcctggctcaccactttggcaaggatttcaccccacaggtgcaggctgcctatcagaaggtggtggctggtgtggctactgccctggctcacaaataccac 'ha re' ctgtccggtgaggagaagtctgcggtcactgccctgtggggcaaggtgaatgtggaagaagttggtggtgagaccctgggcaggctgctggttgtctacccatggacccagaggttcttcgagtcctttggggacctgtccactgcttctgctgttatgggcaaccctaaggtgaaggctcatggcaagaaggtgctggctgccttcagtgagggtctgagtcacctggacaacctcaaaggcaccttcgctaagctgagtgaactgcattgtgacaagctgcacgtggatcctgagaacttcaggctcctgggcaacgtgctggttattgtgctgtctcatcactttggcaaagaattcactcctcaggtgcaggctgcctatcagaaggtggtggctggtgtggccaatgccctggctcacaaataccac 'ra\bbit' ctgtccagtgaggagaagtctgcggtcactgccctgtggggcaaggtgaatgtggaagaagttggtggtgaggccctgggcaggctgctggttgtctacccatggacccagaggttcttcgagtcctttggggacctgtcctctgcaaatgctgttatgaacaatcctaaggtgaaggctcatggcaagaaggtgctggctgccttcagtgagggtctgagtcacctggacaacctcaaaggcacctttgctaagctgagtgaactgcactgtgacaagctgcacgtggatcctgagaacttcaggctcctgggcaacgtgctggttattgtgctgtctcatcattttggcaaagaattcactcctcaggtgcaggctgcctatcagaaggtggtggctggtgtggccaatgccctggctcacaaataccac 'co''w' ctgactgctgaggagaaggctgccgtcaccgccttttggggcaaggtgaaagtggatgaagttggtggtgaggccctgggcaggctgctggttgtctacccctggactcagaggttctttgagtcctttggggacttgtccactgctgatgctgttatgaacaaccctaaggtgaaggcccatggcaagaaggtgctagattcctttagtaatggcatgaagcatctcgatgacctcaagggcacctttgctgcgctgagtgagctgcactgtgataagctgcatgtggatcctgagaacttcaagctcctgggcaacgtgctagtggttgtgctggctcgcaattttggcaaggaattcaccccggtgctgcaggctgactttcagaaggtggtggctggtgtggccaatgccctggcccacagatatcat 'sh"eep' ctgactgctgaggagaaggctgccgtcaccggcttctggggcaaggtgaaagtggatgaagttggtgctgaggccctgggcaggctgctggttgtctacccctggactcagaggttctttgagcactttggggacttgtccaatgctgatgctgttatgaacaaccctaaggtgaaggcccatggcaagaaggtgctagactcctttagtaacggcatgaagcatctcgatgacctcaagggcacctttgctcagctgagtgagctgcactgtgataagctgcacgtggatcctgagaacttcaggctcctgggcaacgtgctggtggttgtgctggctcgccaccatggcaatgaattcaccccggtgctgcaggctgactttcagaaggtggtggctggtgttgccaatgccctggcccacaaatatcac pig ctgtctgctgaggagaaggaggccgtcctcggcctgtggggcaaagtgaatgtggacgaagttggtggtgaggccctgggcaggctgctggttgtctacccctggactcagaggttcttcgagtcctttggggacctgtccaatgccgatgccgtcatgggcaatcccaaggtgaaggcccacggcaagaaggtgctccagtccttcagtgacggcctgaaacatctcgacaacctcaagggcacctttgctaagctgagcgagctgcactgtgaccagctgcacgtggatcctgagaacttcaggctcctgggcaacgtgatagtggttgttctggctcgccgccttggccatgacttcaacccgaatgtgcaggctgcttttcagaaggtggtggctggtgttgctaatgccctggcccacaagtaccac elephseal ttgacggcggaggagaagtctgccgtcacctccctgtggggcaaagtgaaggtggatgaagttggtggtgaagccctgggcaggctgctggttgtctacccctggactcagaggttctttgactcctttggggacctgtcctctcctaatgctattatgagcaaccccaaggtcaaggcccatggcaagaaggtgctgaattcctttagtgatggcctgaagaatctggacaacctcaagggcacctttgctaagctcagtgagctgcactgtgaccagctgcatgtggatcccgagaacttcaagctcctgggcaatgtgctggtgtgtgtgctggcccgccactttggcaaggaattcaccccacagatgcagggtgcctttcagaaggtggtagctggtgtggccaatgccctcgcccacaaatatcac rat ctaactgatgctgagaaggctgctgttaatgccctgtggggaaaggtgaaccctgatgatgttggtggcgaggccctgggcaggctgctggttgtctacccttggacccagaggtactttgatagctttggggacctgtcctctgcctctgctatcatgggtaaccctaaggtgaaggcccatggcaagaaggtgataaacgccttcaatgatggcctgaaacacttggacaacctcaagggcacctttgctcatctgagtgaactccactgtgacaagctgcatgtggatcctgagaacttcaggctcctgggcaatatgattgtgattgtgttgggccaccacctgggcaaggaattcaccccctgtgcacaggctgccttccagaaggtggtggctggagtggccagtgccctggctcacaagtaccac mouse ctgactgatgctgagaagtctgctgtctcttgcctgtgggcaaaggtgaaccccgatgaagttggtggtgaggccctgggcaggctgctggttgtctacccttggacccagcggtactttgatagctttggagacctatcctctgcctctgctatcatgggtaatcccaaggtgaaggcccatggcaaaaaggtgataactgcctttaacgagggcctgaaaaacctggacaacctcaagggcacctttgccagcctcagtgagctccactgtgacaagctgcatgtggatcctgagaacttcaggctcctaggcaatgcgatcgtgattgtgctgggccaccacctgggcaaggatttcacccctgctgcacaggctgccttccagaaggtggtggctggagtggccactgccctggctcacaagtaccac hamster ctgactgatgctgagaaggcccttgtcactggcctgtggggaaaggtgaacgccgatgcagttggcgctgaggccctgggcaggttgctggttgtctacccttggacccagaggttctttgaacactttggagacctgtctctgccagttgctgtcatgaataacccccaggtgaaggcccatggcaagaaggtgatccactccttcgctgatggcctgaaacacctggacaacctgaagggcgccttttccagcctgagtgagctccactgtgacaagctgcacgtggatcctgagaacttcaagctcctgggcaatatgatcatcattgtgctgatccacgacctgggcaaggacttcactcccagtgcacagtctgcctttcataaggtggtggctggtgtggccaatgccctggctcacaagtaccac marsupial ttgacttctgaggagaagaactgcatcactaccatctggtctaaggtgcaggttgaccagactggtggtgaggcccttggcaggatgctcgttgtctacccctggaccaccaggttttttgggagctttggtgatctgtcctctcctggcgctgtcatgtcaaattctaaggttcaagcccatggtgctaaggtgttgacctccttcggtgaagcagtcaagcatttggacaacctgaagggtacttatgccaagttgagtgagctccactgtgacaagctgcatgtggaccctgagaacttcaagatgctggggaatatcattgtgatctgcctggctgagcactttggcaaggattttactcctgaatgtcaggttgcttggcagaagctcgtggctggagttgcccatgccctggcccacaagtaccac duck tggacagccgaggagaagcagctcatcaccggcctctggggcaaggtcaatgtggccgactgtggagctgaggccctggccaggctgctgatcgtctacccctggacccagaggttcttcgcctccttcgggaacctgtccagccccactgccatccttggcaaccccatggtccgtgcccatggcaagaaagtgctcacctccttcggagatgctgtgaagaacctggacaacatcaagaacaccttcgcccagctgtccgagctgcactgcgacaagctgcacgtggaccctgagaacttcaggctcctgggtgacatcctcatcatcgtcctggccgcccacttcaccaaggatttcactcctgactgccaggccgcctggcagaagctggtccgcgtggtggcccacgctctggcccgcaagtaccac chicken tggactgctgaggagaagcagctcatcaccggcctctggggcaaggtcaatgtggccgaatgtggggccgaagccctggccaggctgctgatcgtctacccctggacccagaggttctttgcgtcctttgggaacctctccagccccactgccatccttggcaaccccatggtccgcgcccacggcaagaaagtgctcacctcctttggggatgctgtgaagaacctggacaacatcaagaacaccttctcccaactgtccgaactgcattgtgacaagctgcatgtggaccccgagaacttcaggctcctgggtgacatcctcatcattgtcctggccgcccacttcagcaaggacttcactcctgaatgccaggctgcctggcagaagctggtccgcgtggtggcccatgccctggctcgcaagtaccac xenlaev tggacagctgaagagaaggccgccatcacttctgtatggcagaaggtcaatgtagaacatgatggccatgatgccctgggcaggctgctgattgtgtacccctggacccagagatacttcagtaactttggaaacctctccaattcagctgctgttgctggaaatgccaaggttcaagcccatggcaagaaggttctttcagctgttggcaatgccattagccatattgacagtgtgaagtcctctctccaacaactcagtaagatccatgccactgaactgtttgtggaccctgagaactttaagcgttttggtggagttctggtcattgtcttgggtgccaaactgggaactgccttcactcctaaagttcaggctgcttgggagaaattcattgcagttttggttgatggtcttagccagggctataac xentrop tggacagctgaagaaaaagcaaccattgcttctgtgtgggggaaagtcgacattgaacaggatggccatgatgcattatccaggctgctggttgtttatccctggactcagaggtacttcagcagttttggaaacctctccaatgtctccgctgtctctggaaatgtcaaggttaaagcccatggaaataaagtcctgtcagctgttggcagtgcaatccagcatctggatgatgtgaagagccaccttaaaggtcttagcaagagccatgctgaggatcttcatgtggatcccgaaaacttcaagcgccttgcggatgttctggtgatcgttctggctgccaaacttggatctgccttcactccccaagtccaagctgtctgggagaagctcaatgcaactctggtggctgctcttagccatggctacttc ; end; begin mrbayes; [The following block illustrates how to set up two data partitions and use different models for the different partitions.] charset non_coding = 1-90 358-432; charset coding = 91-357; partition region = 2:non_coding,coding; set partition = region; [The following lines set a codon model for the second data partition (coding) and allows the non_coding and coding partitions to have different overall rates.] lset applyto=(2) nucmodel=codon; prset ratepr=variable; [Codon models are computationally complex so the following lines set the parameters of the MCMC such that only 1 chain is run for 100 generations and results are printed to screen and to file every tenth generation. To start this chain, you need to type 'mcmc' after executing this block. You need to run the chain longer to get adequate convergence.] mcmcp ngen=100 nchains=1 printfreq=10 samplefreq=10; end; phylobase/inst/nexusfiles/NastyLabels.nex0000644000176200001440000000175012347155416020352 0ustar liggesusers#NEXUS [Data from Gavin Thomas] BEGIN TAXA; DIMENSIONS NTAX = 11; TAXLABELS subterraneus Mus_musculus H._sapiens 'H. sapiens #429' 'Fred''s new sp.' 'rusticus (1)' '"shoal bass"' AMNION _23 x21.02 myType ; end; BEGIN CHARACTERS; DIMENSIONS NCHAR=1; FORMAT DATATYPE = STANDARD SYMBOLS="0 1"; CHARSTATELABELS 1 aCharacter / on off; MATRIX subterraneus 0 Mus_musculus 1 H._sapiens 0 'H. sapiens #429' 1 'Fred''s new sp.' 0 'rusticus (1)' 1 '"shoal bass"' 0 AMNION 1 _23 0 x21.02 1 myType 0 ; END; BEGIN TREES; TRANSLATE 1 subterraneus, 2 Mus_musculus, 3 H._sapiens, 4 'H. sapiens #429', 5 'Fred''s new sp.', 6 'rusticus (1)', 7 '"shoal bass"', 8 AMNION, 9 _23, 10 x21.02, 11 myType ; TREE * COMB = (1,(2,(3,(4,(5,(6,(7,(8,(9,(10,11)))))))))); end; phylobase/inst/nexusfiles/minNex.nex0000644000176200001440000000150612347155416017366 0ustar liggesusers#NEXUS BEGIN TAXA; DIMENSIONS NTAX=4; TAXLABELS spA spB spC spD ; END; BEGIN TREES; TRANSLATE 1 spA, 2 spB, 3 spC, 4 spD; TREE testTree = (1,(2,(3,4))); END; BEGIN CHARACTERS; TITLE 'TestContinuous'; DIMENSIONS NCHAR=3; FORMAT DATATYPE = CONTINUOUS; CHARSTATELABELS 1 char1, 2 char2, 3 char3; MATRIX spB 0.21 0.22 0.23 spA 0.11 0.12 0.13 spD 0.41 0.42 0.43 spC 0.31 0.32 0.33 ; END; BEGIN CHARACTERS; TITLE 'TestStd'; DIMENSIONS NCHAR=3; FORMAT DATATYPE = STANDARD MISSING = ? SYMBOLS = "0 1 2"; CHARSTATELABELS 1 char1 / state11 state12 state13, 2 char2 / state21 state22 state23, 3 char3 / state31 state32 state33; MATRIX spA 1 (0 1) ? spB 2 (1 2) 0 spC 0 (0 1 2) 1 spD 1 2 0 ; END; [BEGIN ASSUMPTIONS; EXSET * UNTITLED = 3; END;] phylobase/inst/nexusfiles/co1.nex0000644000176200001440000000156012347155416016612 0ustar liggesusers#NEXUS [ID: 0916634271] begin trees; [Note: This tree contains information on the topology, branch lengths (if present), and the probability of the partition indicated by the branch.] tree con_50_majrule = (Cow:0.143336,Seal:0.225087,((((((Carp:0.171296,Loach:0.222039)1.00:0.194575,Frog:0.237101)0.76:0.073060,Chicken:0.546258)1.00:0.204809,Human:0.533183)0.99:0.124549,(Mouse:0.134574,Rat:0.113163)1.00:0.154442)0.88:0.055934,Whale:0.145592)0.93:0.047441); [Note: This tree contains information only on the topology and branch lengths (mean of the posterior probability density).] tree con_50_majrule = (Cow:0.143336,Seal:0.225087,((((((Carp:0.171296,Loach:0.222039):0.194575,Frog:0.237101):0.073060,Chicken:0.546258):0.204809,Human:0.533183):0.124549,(Mouse:0.134574,Rat:0.113163):0.154442):0.055934,Whale:0.145592):0.047441); end; phylobase/inst/nexusfiles/noStateLabels.nex0000644000176200001440000000065112347155416020670 0ustar liggesusers#NEXUS BEGIN TAXA; DIMENSIONS NTAX=4; TAXLABELS spA spB spC spD ; END; BEGIN TREES; TRANSLATE 1 spA, 2 spB, 3 spC, 4 spD; TREE testTree = (1,(2,(3,4))); END; BEGIN CHARACTERS; TITLE 'TestStd'; DIMENSIONS NCHAR=3; FORMAT DATATYPE = STANDARD MISSING = ? SYMBOLS = "0 1 2"; CHARSTATELABELS 1 char1, 2 char2, 3 char3; MATRIX spA 1 0 1 spB 2 1 0 spC 0 1 2 spD 1 2 0 ; END; phylobase/inst/nexusfiles/treeWithDiscreteData.nex0000644000176200001440000002273612347155416022210 0ustar liggesusers#NEXUS [written Tue May 29 18:24:39 PDT 2007 by Mesquite version 1.06 (build g97) at cnidaria-1347.ucdavis.edu/169.237.66.185] BEGIN TAXA; DIMENSIONS NTAX=18; TAXLABELS Myrmecocystuscfnavajo Myrmecocystuscreightoni Myrmecocystusdepilis Myrmecocystuskathjuli Myrmecocystuskennedyi Myrmecocystusmendax Myrmecocystusmexicanus Myrmecocystusmimicus Myrmecocystusnavajo Myrmecocystusnequazcatl Myrmecocystusplacodops Myrmecocystusromainei Myrmecocystussemirufus Myrmecocystussnellingi Myrmecocystustenuinodis Myrmecocystustestaceus Myrmecocystuswheeleri Myrmecocystusyuma ; END; BEGIN CHARACTERS; TITLE Foraging; DIMENSIONS NCHAR=2; FORMAT DATATYPE = STANDARD GAP = - MISSING = ? SYMBOLS = " 0 1 2"; CHARSTATELABELS 1 time / diurnal crepuscular nocturnal, 2 subgenus / Endiodioctes Eremnocystus Myrmecocystus ; MATRIX Myrmecocystuscfnavajo 22 Myrmecocystuscreightoni 11 Myrmecocystusdepilis 00 Myrmecocystuskathjuli 00 Myrmecocystuskennedyi 00 Myrmecocystusmendax 00 Myrmecocystusmexicanus 22 Myrmecocystusmimicus 00 Myrmecocystusnavajo 22 Myrmecocystusnequazcatl 00 Myrmecocystusplacodops 00 Myrmecocystusromainei 00 Myrmecocystussemirufus 00 Myrmecocystussnellingi 11 Myrmecocystustenuinodis 11 Myrmecocystustestaceus 12 Myrmecocystuswheeleri 00 Myrmecocystusyuma 11 ; END; BEGIN TREES; TRANSLATE 1 Myrmecocystuscfnavajo, 2 Myrmecocystuscreightoni, 3 Myrmecocystusdepilis, 4 Myrmecocystuskathjuli, 5 Myrmecocystuskennedyi, 6 Myrmecocystusmendax, 7 Myrmecocystusmexicanus, 8 Myrmecocystusmimicus, 9 Myrmecocystusnavajo, 10 Myrmecocystusnequazcatl, 11 Myrmecocystusplacodops, 12 Myrmecocystusromainei, 13 Myrmecocystussemirufus, 14 Myrmecocystussnellingi, 15 Myrmecocystustenuinodis, 16 Myrmecocystustestaceus, 17 Myrmecocystuswheeleri, 18 Myrmecocystusyuma; TREE bestML = (((((((((13:1.724765,11:1.724765):2.926053,6:4.650818):0.689044,(4:1.08387,17:1.08387):4.255993):0.198842,((8:2.708942,3:2.708942):2.027251,((12:2.193845,10:2.193845):2.257581,18:4.451425):0.284767):0.802512):0.506099,5:6.044804):4.524387,2:10.569191):0.836689,(14:2.770378,15:2.770378):8.635503):0.89482,16:12.300701):1.699299,(7:5.724923,(1:2.869547,9:2.869547):2.855375):8.275077); END; BEGIN ASSUMPTIONS; TYPESET * UNTITLED (CHARACTERS = Foraging) = unord: 1 - 2; END; BEGIN MESQUITECHARMODELS; ProbModelSet * UNTITLED (CHARACTERS = 'Matrix in file "treepluscharV01.nex"') = Browniandefault: 1 - 32; ProbModelSet * UNTITLED (CHARACTERS = Foraging) = 'Mk1 (est.)': 1 - 2; END; Begin MESQUITE; MESQUITESCRIPTVERSION 2; TITLE AUTO; tell ProjectCoordinator; getEmployee #mesquite.minimal.ManageTaxa.ManageTaxa; tell It; setID 0 9015005506118934442; endTell; getEmployee #mesquite.charMatrices.ManageCharacters.ManageCharacters; tell It; setID 0 2565950173085067248; checksum 0 389122022; setID 1 1161953040649633474; checksum 1 3582198254; endTell; getEmployee #mesquite.charMatrices.BasicDataWindowCoord.BasicDataWindowCoord; tell It; showDataWindow #2565950173085067248 #mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindowMaker; tell It; getWindow; tell It; setSize 420 280; setLocation 400 156; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; endTell; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.arrow; colorCells #mesquite.charMatrices.NoColor.NoColor; setBackground White; toggleShowNames on; toggleTight off; toggleShowChanges on; toggleSeparateLines off; toggleShowStates on; toggleAutoWithCharNames on; toggleShowDefaultCharNames off; toggleConstrainCW on; toggleBirdsEye off; toggleColorsPanel off; birdsEyeWidth 2; toggleLinkedScrolling on; toggleScrollLinkedTables off; endTell; showWindow; getWindow; tell It; forceAutosize; endTell; getEmployee #mesquite.charMatrices.AnnotPanel.AnnotPanel; tell It; togglePanel off; endTell; getEmployee #mesquite.charMatrices.ColorCells.ColorCells; tell It; setColor Red; removeColor off; endTell; endTell; showDataWindow #1161953040649633474 #mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindowMaker; tell It; getWindow; tell It; getTable; tell It; rowNamesWidth 232; endTell; setSize 798 748; setLocation 348 22; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.ibeam; endTell; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.ibeam; colorCells #mesquite.charMatrices.NoColor.NoColor; setBackground White; toggleShowNames on; toggleTight off; toggleShowChanges on; toggleSeparateLines off; toggleShowStates on; toggleAutoWithCharNames on; toggleShowDefaultCharNames off; toggleConstrainCW on; toggleBirdsEye off; toggleColorsPanel off; birdsEyeWidth 2; toggleLinkedScrolling on; toggleScrollLinkedTables off; endTell; showWindow; getWindow; tell It; forceAutosize; endTell; getEmployee #mesquite.categ.StateNamesEditor.StateNamesEditor; tell It; makeWindow; tell It; setSize 314 400; setLocation 60 10; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; setTool mesquite.categ.StateNamesEditor.StateNamesWindow.ibeam; endTell; rowsAreCharacters on; toggleConstrainChar on; toggleConstrainCharNum 3; togglePanel off; endTell; showWindow; endTell; getEmployee #mesquite.categ.StateNamesStrip.StateNamesStrip; tell It; showStrip off; endTell; getEmployee #mesquite.charMatrices.AnnotPanel.AnnotPanel; tell It; togglePanel off; endTell; getEmployee #mesquite.charMatrices.ColorCells.ColorCells; tell It; setColor Red; removeColor off; endTell; getEmployee #mesquite.charMatrices.QuickKeySelector.QuickKeySelector; tell It; autotabOff; endTell; endTell; endTell; getEmployee #mesquite.trees.BasicTreeWindowCoord.BasicTreeWindowCoord; tell It; makeTreeWindow #9015005506118934442 #mesquite.trees.BasicTreeWindowMaker.BasicTreeWindowMaker; tell It; setTreeSource #mesquite.trees.StoredTrees.StoredTrees; tell It; setTreeBlock 1; toggleUseWeights off; endTell; setAssignedID 630.1180487973731.4514395117633566598; getTreeWindow; tell It; setSize 520 400; setLocation 60 10; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; endTell; setActive; getTreeDrawCoordinator #mesquite.trees.BasicTreeDrawCoordinator.BasicTreeDrawCoordinator; tell It; suppress; setTreeDrawer #mesquite.trees.DiagonalDrawTree.DiagonalDrawTree; tell It; setEdgeWidth 12; orientUp; getEmployee #mesquite.trees.NodeLocsStandard.NodeLocsStandard; tell It; stretchToggle off; branchLengthsToggle off; toggleScale on; toggleCenter off; toggleEven off; namesAngle ?; endTell; endTell; setBackground White; setBranchColor Black; showNodeNumbers off; labelBranchLengths off; desuppress; getEmployee #mesquite.trees.BasicDrawTaxonNames.BasicDrawTaxonNames; tell It; setColor Black; toggleColorPartition on; toggleShadePartition off; toggleNodeLabels on; toggleShowNames on; endTell; endTell; setTreeNumber 1; useSuggestedSize on; toggleTextOnTree off; newAssistant #mesquite.ancstates.TraceCharacterHistory.TraceCharacterHistory; tell It; suspend ; setDisplayMode #mesquite.ancstates.ShadeStatesOnTree.ShadeStatesOnTree; tell It; toggleLabels off; endTell; setHistorySource #mesquite.ancstates.RecAncestralStates.RecAncestralStates; tell It; getCharacterSource #mesquite.charMatrices.CharSrcCoordObed.CharSrcCoordObed; tell It; setCharacterSource #mesquite.charMatrices.StoredCharacters.StoredCharacters; tell It; setDataSet #1161953040649633474; endTell; endTell; setMethod #mesquite.parsimony.ParsAncestralStates.ParsAncestralStates; tell It; setModelSource #mesquite.parsimony.CurrentParsModels.CurrentParsModels; endTell; endTell; setCharacter 1; toggleShowLegend on; toggleGray off; toggleWeights on; setInitialOffsetX -162; setInitialOffsetY -177; setLegendWidth 142; setLegendHeight 177; resume ; endTell; endTell; showWindow; getEmployee #mesquite.ornamental.BranchNotes.BranchNotes; tell It; setAlwaysOn off; endTell; getEmployee #mesquite.trees.ColorBranches.ColorBranches; tell It; setColor Red; removeColor off; endTell; endTell; endTell; endTell; end; begin brownie; taxset all=1-18; end; phylobase/inst/nexusfiles/shorebird_underscore.nex0000644000176200001440000002642312347155416022347 0ustar liggesusers#NEXUS [Data from Gavin Thomas] BEGIN TAXA; DIMENSIONS NTAX = 71; TAXLABELS Catoptrophorus_semipalmatus Tringa_ochropus Tringa_stagnatilis Tringa_flavipes Tringa_nebularia Tringa_totanus Tringa_erythropus Tringa_melanoleuca Tringa_glareola Steganopus_tricolor Phalaropus_lobatus Phalaropus_fulicaria Micropalama_himantopus Eurynorhynchus_pygmeus Aphriza_virgata Calidris_canutus Calidris_tenuirostris Calidris_temminckii Calidris_maritima Calidris_ptilocnemis Calidris_mauri Calidris_alba Calidris_alpina Calidris_bairdii Calidris_minutilla Calidris_pusilla Calidris_minuta Calidris_ruficollis Calidris_subminuta Arenaria_interpres Arenaria_melanocephala Tringa_hypoleucos Tringa_macularia Limnodromus_griseus Gallinago_gallinago Coenocorypha_aucklandica Coenocorypha_pusilla Limosa_fedoa Limosa_haemastica Limosa_limosa Limosa_lapponica Bartramia_longicauda Numenius_tahitiensis Numenius_phaeopus Numenius_arquata Numenius_americanus Rostratula_benghalensis Jacana_spinosa Jacana_jacana Metopidius_indicus Actophilornis_africanus Pedionomus_torquatus Pluvialis_apricaria Pluvialis_dominica Eudromias_morinellus Charadrius_montanus Charadrius_vociferus Charadrius_wilsonia Charadrius_dubius Charadrius_hiaticula Charadrius_melodus Vanellus_vanellus Vanellus_lugubris Vanellus_armatus Recurvirostra_avosetta Haematopus_longirostris Haematopus_fuliginosus Haematopus_moquini Haematopus_ostralegus Haematopus_unicolor Haematopus_finschi ; END; BEGIN CHARACTERS; TITLE MassClutchSize; DIMENSIONS NCHAR=4; FORMAT DATATYPE = CONTINUOUS; CHARSTATELABELS 1 malemass, 2 femalemass, 3 eggmass, 4 clutchsize; MATRIX Actophilornis_africanus 143.2 260.7 8.6 4.00 Aphriza_virgata 186.3 216.3 22.4 4.00 Arenaria_interpres 108.0 113.0 17.9 3.50 Arenaria_melanocephala 113.6 124.2 17.3 4.00 Bartramia_longicauda 151.0 164.0 23.5 3.99 Calidris_alba 52.8 55.4 11.2 3.90 Calidris_alpina 41.0 45.1 10.7 3.90 Calidris_bairdii 39.3 39.7 9.6 4.00 Calidris_canutus 126.0 148.0 19.3 3.70 Calidris_maritima 67.6 76.3 13.3 3.90 Calidris_mauri 28.0 31.0 7.5 3.90 Calidris_minuta 24.0 27.1 6.3 3.80 Calidris_minutilla 20.3 22.2 6.4 3.90 Calidris_ptilocnemis 76.3 83.0 14.2 4.00 Calidris_pusilla 25.0 27.0 6.9 4.00 Calidris_ruficollis 25.7 26.6 8.3 4.00 Calidris_subminuta 29.0 32.0 7.5 4.00 Calidris_temminckii 24.3 27.8 5.8 4.00 Calidris_tenuirostris 156.0 174.0 22.0 4.00 Catoptrophorus_semipalmatus 273.0 301.4 39.5 4.00 Charadrius_dubius 38.3 39.2 7.7 3.90 Charadrius_hiaticula 63.5 64.7 10.9 3.80 Charadrius_melodus 54.9 55.6 9.4 3.30 Charadrius_montanus 102.0 114.0 16.5 3.00 Charadrius_vociferus 92.1 101.0 14.5 4.00 Charadrius_wilsonia 59.0 63.0 12.4 3.00 Coenocorypha_aucklandica 101.2 116.1 23.7 2.00 Coenocorypha_pusilla 75.9 85.4 16.1 2.10 Eudromias_morinellus 100.0 117.0 17.0 2.90 Eurynorhynchus_pygmeus 31.0 34.6 8.0 4.00 Gallinago_gallinago 111.0 128.0 16.5 3.90 Haematopus_finschi 517.0 554.0 44.2 2.33 Haematopus_fuliginosus 740.3 778.5 69.5 2.00 Haematopus_longirostris 602.3 626.3 49.0 2.50 Haematopus_moquini 668.0 730.0 55.8 1.70 Haematopus_ostralegus 500.0 536.0 46.7 2.80 Haematopus_unicolor 717.0 734.0 48.2 2.40 Jacana_jacana 108.3 142.8 9.7 3.50 Jacana_spinosa 86.9 145.4 8.3 4.00 Limnodromus_griseus 111.0 116.0 17.5 4.10 Limosa_fedoa 320.0 421.0 44.5 4.10 Limosa_haemastica 222.0 289.0 37.5 4.00 Limosa_lapponica 313.0 354.0 37.0 3.72 Limosa_limosa 264.0 315.0 39.0 3.90 Metopidius_indicus 176.2 282.4 11.9 4.00 Micropalama_himantopus 55.8 60.4 11.2 3.90 Numenius_americanus 640.1 758.6 73.0 4.00 Numenius_arquata 662.0 788.0 76.0 3.90 Numenius_phaeopus 368.0 398.0 50.0 3.90 Numenius_tahitiensis 378.0 489.0 54.8 4.00 Pedionomus_torquatus 54.0 72.4 10.0 3.60 Phalaropus_fulicaria 50.8 61.0 7.5 3.80 Phalaropus_lobatus 32.4 37.4 6.3 4.00 Pluvialis_apricaria 175.0 176.0 32.8 3.90 Pluvialis_dominica 145.0 146.0 26.0 4.00 Recurvirostra_avosetta 258.0 288.0 31.7 3.90 Rostratula_benghalensis 146.0 159.0 12.4 4.00 Steganopus_tricolor 50.2 68.1 9.4 4.00 Tringa_erythropus 142.0 161.0 24.5 4.00 Tringa_flavipes 80.0 83.7 17.4 4.00 Tringa_glareola 62.0 73.0 13.5 4.00 Tringa_hypoleucos 45.5 50.0 12.5 3.90 Tringa_macularia 36.9 48.0 9.0 4.00 Tringa_melanoleuca 164.0 176.0 27.9 3.70 Tringa_nebularia 172.0 175.0 30.5 3.90 Tringa_ochropus 75.0 85.0 15.5 3.90 Tringa_stagnatilis 67.1 76.0 14.0 4.00 Tringa_totanus 123.0 135.0 22.3 4.00 Vanellus_armatus 162.0 167.0 16.5 3.10 Vanellus_lugubris 109.5 113.0 13.7 3.00 Vanellus_vanellus 211.0 226.0 25.5 3.90 ; END; BEGIN CHARACTERS; TITLE MatingSystem; DIMENSIONS NCHAR=1; FORMAT DATATYPE = STANDARD SYMBOLS="0 1 2"; CHARSTATELABELS 1 matingSystem / Monogamous Polygynous Polyandrous; MATRIX Actophilornis_africanus 2 Aphriza_virgata 0 Arenaria_interpres 0 Arenaria_melanocephala 0 Bartramia_longicauda 0 Calidris_alba 2 Calidris_alpina 0 Calidris_bairdii 0 Calidris_canutus 0 Calidris_maritima 0 Calidris_mauri 0 Calidris_minuta 2 Calidris_minutilla 0 Calidris_ptilocnemis 0 Calidris_pusilla 0 Calidris_ruficollis 0 Calidris_subminuta 0 Calidris_temminckii 2 Calidris_tenuirostris 0 Catoptrophorus_semipalmatus 0 Charadrius_dubius 0 Charadrius_hiaticula 0 Charadrius_melodus 0 Charadrius_montanus 2 Charadrius_vociferus 0 Charadrius_wilsonia 0 Coenocorypha_aucklandica 1 Coenocorypha_pusilla 0 Eudromias_morinellus 2 Eurynorhynchus_pygmeus 0 Gallinago_gallinago 0 Haematopus_finschi 0 Haematopus_fuliginosus 0 Haematopus_longirostris 0 Haematopus_moquini 0 Haematopus_ostralegus 0 Haematopus_unicolor 0 Jacana_jacana 2 Jacana_spinosa 2 Limnodromus_griseus 0 Limosa_fedoa 0 Limosa_haemastica 0 Limosa_lapponica 0 Limosa_limosa 0 Metopidius_indicus 2 Micropalama_himantopus 0 Numenius_americanus 0 Numenius_arquata 0 Numenius_phaeopus 0 Numenius_tahitiensis 0 Pedionomus_torquatus 2 Phalaropus_fulicaria 2 Phalaropus_lobatus 2 Pluvialis_apricaria 0 Pluvialis_dominica 0 Recurvirostra_avosetta 0 Rostratula_benghalensis 2 Steganopus_tricolor 2 Tringa_erythropus 0 Tringa_flavipes 0 Tringa_glareola 0 Tringa_hypoleucos 0 Tringa_macularia 2 Tringa_melanoleuca 0 Tringa_nebularia 0 Tringa_ochropus 0 Tringa_stagnatilis 0 Tringa_totanus 0 Vanellus_armatus 0 Vanellus_lugubris 0 Vanellus_vanellus 1 ; END; BEGIN TREES; TRANSLATE 1 Catoptrophorus_semipalmatus, 2 Tringa_ochropus, 3 Tringa_stagnatilis, 4 Tringa_flavipes, 5 Tringa_nebularia, 6 Tringa_totanus, 7 Tringa_erythropus, 8 Tringa_melanoleuca, 9 Tringa_glareola, 10 Steganopus_tricolor, 11 Phalaropus_lobatus, 12 Phalaropus_fulicaria, 13 Micropalama_himantopus, 14 Eurynorhynchus_pygmeus, 15 Aphriza_virgata, 16 Calidris_canutus, 17 Calidris_tenuirostris, 18 Calidris_temminckii, 19 Calidris_maritima, 20 Calidris_ptilocnemis, 21 Calidris_mauri, 22 Calidris_alba, 23 Calidris_alpina, 24 Calidris_bairdii, 25 Calidris_minutilla, 26 Calidris_pusilla, 27 Calidris_minuta, 28 Calidris_ruficollis, 29 Calidris_subminuta, 30 Arenaria_interpres, 31 Arenaria_melanocephala, 32 Tringa_hypoleucos, 33 Tringa_macularia, 34 Limnodromus_griseus, 35 Gallinago_gallinago, 36 Coenocorypha_aucklandica, 37 Coenocorypha_pusilla, 38 Limosa_fedoa, 39 Limosa_haemastica, 40 Limosa_limosa, 41 Limosa_lapponica, 42 Bartramia_longicauda, 43 Numenius_tahitiensis, 44 Numenius_phaeopus, 45 Numenius_arquata, 46 Numenius_americanus, 47 Rostratula_benghalensis, 48 Jacana_spinosa, 49 Jacana_jacana, 50 Metopidius_indicus, 51 Actophilornis_africanus, 52 Pedionomus_torquatus, 53 Pluvialis_apricaria, 54 Pluvialis_dominica, 55 Eudromias_morinellus, 56 Charadrius_montanus, 57 Charadrius_vociferus, 58 Charadrius_wilsonia, 59 Charadrius_dubius, 60 Charadrius_hiaticula, 61 Charadrius_melodus, 62 Vanellus_vanellus, 63 Vanellus_lugubris, 64 Vanellus_armatus, 65 Recurvirostra_avosetta, 66 Haematopus_longirostris, 67 Haematopus_fuliginosus, 68 Haematopus_moquini, 69 Haematopus_ostralegus, 70 Haematopus_unicolor, 71 Haematopus_finschi ; TREE * UNTITLED = [&R] ((((((((1:19.701,(2:19.086,((3:13.762,4:13.762,5:13.762,6:13.762,(7:5.324,8:5.324):8.438):3.114,9:16.876):2.21):0.615):2.499,(10:3.42,(11:2.158,12:2.158):1.262):18.78):9.9,((13:17.413,14:17.413,(15:6.019,(16:3.798,17:3.798):2.221):11.394,(18:10.013,((19:2.588,20:2.588):6.989,(21:9.142,(22:8.707,((23:7.836,(24:7.4,(25:6.965,(26:3.483,27:3.483):3.482):0.435):0.436):0.435,(28:2.609,29:2.609):5.662):0.436):0.435):0.435):0.436):7.4):9.287,(30:5.68,31:5.68):21.02):5.4,(32:5.779,33:5.779):26.320999):2.3,(34:23.8,(35:22.8,(36:4.91,37:4.91):17.889999):1):10.6):2.6,(38:11.739,(39:9.303,(40:5.869,41:5.869):3.434):2.436):25.261):13.4,(42:20.299,(43:14.869,(44:10.15,(45:6.404,46:6.404):3.746):4.719):5.43):30.101):13.4,((47:43.3,((48:10.8,49:10.8):21.6,(50:19.845,51:19.845):12.555):10.9):8.8,52:52.099999):11.7):18.072,(((53:8.33,54:8.33):23.437001,((55:26.700001,(56:22.991999,((57:5.548,58:5.548):10.027,(59:12.882,(60:8.793,61:8.793):4.089):2.693):7.417):3.708):3,(62:22.961,63:22.960999,64:22.961):6.739):2.067):1.033,(65:19.1,(66:14.817,(67:12.849,(68:11.072,(69:4.283,70:4.283):6.789,71:11.072):1.777):1.968):4.283):13.7):49.071998); END; phylobase/inst/nexusfiles/treeWithUnderscoreLabels.nex0000644000176200001440000002275012347155416023104 0ustar liggesusers#NEXUS [written Tue May 29 18:24:39 PDT 2007 by Mesquite version 1.06 (build g97) at cnidaria-1347.ucdavis.edu/169.237.66.185] BEGIN TAXA; DIMENSIONS NTAX=18; TAXLABELS Myrmecocystuscfnavajo Myrmecocystus_creightoni Myrmecocystusdepilis Myrmecocystuskathjuli Myrmecocystuskennedyi Myrmecocystusmendax Myrmecocystusmexicanus Myrmecocystusmimicus Myrmecocystusnavajo Myrmecocystusnequazcatl Myrmecocystusplacodops Myrmecocystusromainei Myrmecocystussemirufus Myrmecocystussnellingi Myrmecocystustenuinodis Myrmecocystustestaceus Myrmecocystuswheeleri Myrmecocystusyuma ; END; BEGIN CHARACTERS; TITLE Foraging; DIMENSIONS NCHAR=2; FORMAT DATATYPE = STANDARD GAP = - MISSING = ? SYMBOLS = " 0 1 2"; CHARSTATELABELS 1 time_period / diurnal crepuscular nocturnal, 2 subgenus / Endiodioctes Eremnocystus Myrmecocystus ; MATRIX Myrmecocystuscfnavajo 22 Myrmecocystus_creightoni 11 Myrmecocystusdepilis 00 Myrmecocystuskathjuli 00 Myrmecocystuskennedyi 00 Myrmecocystusmendax 00 Myrmecocystusmexicanus 22 Myrmecocystusmimicus 00 Myrmecocystusnavajo 22 Myrmecocystusnequazcatl 00 Myrmecocystusplacodops 00 Myrmecocystusromainei 00 Myrmecocystussemirufus 00 Myrmecocystussnellingi 11 Myrmecocystustenuinodis 11 Myrmecocystustestaceus 12 Myrmecocystuswheeleri 00 Myrmecocystusyuma 11 ; END; BEGIN TREES; TRANSLATE 1 Myrmecocystuscfnavajo, 2 Myrmecocystus_creightoni, 3 Myrmecocystusdepilis, 4 Myrmecocystuskathjuli, 5 Myrmecocystuskennedyi, 6 Myrmecocystusmendax, 7 Myrmecocystusmexicanus, 8 Myrmecocystusmimicus, 9 Myrmecocystusnavajo, 10 Myrmecocystusnequazcatl, 11 Myrmecocystusplacodops, 12 Myrmecocystusromainei, 13 Myrmecocystussemirufus, 14 Myrmecocystussnellingi, 15 Myrmecocystustenuinodis, 16 Myrmecocystustestaceus, 17 Myrmecocystuswheeleri, 18 Myrmecocystusyuma; TREE bestML = (((((((((13:1.724765,11:1.724765):2.926053,6:4.650818):0.689044,(4:1.08387,17:1.08387):4.255993):0.198842,((8:2.708942,3:2.708942):2.027251,((12:2.193845,10:2.193845):2.257581,18:4.451425):0.284767):0.802512):0.506099,5:6.044804):4.524387,2:10.569191):0.836689,(14:2.770378,15:2.770378):8.635503):0.89482,16:12.300701):1.699299,(7:5.724923,(1:2.869547,9:2.869547):2.855375):8.275077); END; BEGIN ASSUMPTIONS; TYPESET * UNTITLED (CHARACTERS = Foraging) = unord: 1 - 2; END; BEGIN MESQUITECHARMODELS; ProbModelSet * UNTITLED (CHARACTERS = 'Matrix in file "treepluscharV01.nex"') = Browniandefault: 1 - 32; ProbModelSet * UNTITLED (CHARACTERS = Foraging) = 'Mk1 (est.)': 1 - 2; END; Begin MESQUITE; MESQUITESCRIPTVERSION 2; TITLE AUTO; tell ProjectCoordinator; getEmployee #mesquite.minimal.ManageTaxa.ManageTaxa; tell It; setID 0 9015005506118934442; endTell; getEmployee #mesquite.charMatrices.ManageCharacters.ManageCharacters; tell It; setID 0 2565950173085067248; checksum 0 389122022; setID 1 1161953040649633474; checksum 1 3582198254; endTell; getEmployee #mesquite.charMatrices.BasicDataWindowCoord.BasicDataWindowCoord; tell It; showDataWindow #2565950173085067248 #mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindowMaker; tell It; getWindow; tell It; setSize 420 280; setLocation 400 156; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; endTell; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.arrow; colorCells #mesquite.charMatrices.NoColor.NoColor; setBackground White; toggleShowNames on; toggleTight off; toggleShowChanges on; toggleSeparateLines off; toggleShowStates on; toggleAutoWithCharNames on; toggleShowDefaultCharNames off; toggleConstrainCW on; toggleBirdsEye off; toggleColorsPanel off; birdsEyeWidth 2; toggleLinkedScrolling on; toggleScrollLinkedTables off; endTell; showWindow; getWindow; tell It; forceAutosize; endTell; getEmployee #mesquite.charMatrices.AnnotPanel.AnnotPanel; tell It; togglePanel off; endTell; getEmployee #mesquite.charMatrices.ColorCells.ColorCells; tell It; setColor Red; removeColor off; endTell; endTell; showDataWindow #1161953040649633474 #mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindowMaker; tell It; getWindow; tell It; getTable; tell It; rowNamesWidth 232; endTell; setSize 798 748; setLocation 348 22; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.ibeam; endTell; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.ibeam; colorCells #mesquite.charMatrices.NoColor.NoColor; setBackground White; toggleShowNames on; toggleTight off; toggleShowChanges on; toggleSeparateLines off; toggleShowStates on; toggleAutoWithCharNames on; toggleShowDefaultCharNames off; toggleConstrainCW on; toggleBirdsEye off; toggleColorsPanel off; birdsEyeWidth 2; toggleLinkedScrolling on; toggleScrollLinkedTables off; endTell; showWindow; getWindow; tell It; forceAutosize; endTell; getEmployee #mesquite.categ.StateNamesEditor.StateNamesEditor; tell It; makeWindow; tell It; setSize 314 400; setLocation 60 10; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; setTool mesquite.categ.StateNamesEditor.StateNamesWindow.ibeam; endTell; rowsAreCharacters on; toggleConstrainChar on; toggleConstrainCharNum 3; togglePanel off; endTell; showWindow; endTell; getEmployee #mesquite.categ.StateNamesStrip.StateNamesStrip; tell It; showStrip off; endTell; getEmployee #mesquite.charMatrices.AnnotPanel.AnnotPanel; tell It; togglePanel off; endTell; getEmployee #mesquite.charMatrices.ColorCells.ColorCells; tell It; setColor Red; removeColor off; endTell; getEmployee #mesquite.charMatrices.QuickKeySelector.QuickKeySelector; tell It; autotabOff; endTell; endTell; endTell; getEmployee #mesquite.trees.BasicTreeWindowCoord.BasicTreeWindowCoord; tell It; makeTreeWindow #9015005506118934442 #mesquite.trees.BasicTreeWindowMaker.BasicTreeWindowMaker; tell It; setTreeSource #mesquite.trees.StoredTrees.StoredTrees; tell It; setTreeBlock 1; toggleUseWeights off; endTell; setAssignedID 630.1180487973731.4514395117633566598; getTreeWindow; tell It; setSize 520 400; setLocation 60 10; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; endTell; setActive; getTreeDrawCoordinator #mesquite.trees.BasicTreeDrawCoordinator.BasicTreeDrawCoordinator; tell It; suppress; setTreeDrawer #mesquite.trees.DiagonalDrawTree.DiagonalDrawTree; tell It; setEdgeWidth 12; orientUp; getEmployee #mesquite.trees.NodeLocsStandard.NodeLocsStandard; tell It; stretchToggle off; branchLengthsToggle off; toggleScale on; toggleCenter off; toggleEven off; namesAngle ?; endTell; endTell; setBackground White; setBranchColor Black; showNodeNumbers off; labelBranchLengths off; desuppress; getEmployee #mesquite.trees.BasicDrawTaxonNames.BasicDrawTaxonNames; tell It; setColor Black; toggleColorPartition on; toggleShadePartition off; toggleNodeLabels on; toggleShowNames on; endTell; endTell; setTreeNumber 1; useSuggestedSize on; toggleTextOnTree off; newAssistant #mesquite.ancstates.TraceCharacterHistory.TraceCharacterHistory; tell It; suspend ; setDisplayMode #mesquite.ancstates.ShadeStatesOnTree.ShadeStatesOnTree; tell It; toggleLabels off; endTell; setHistorySource #mesquite.ancstates.RecAncestralStates.RecAncestralStates; tell It; getCharacterSource #mesquite.charMatrices.CharSrcCoordObed.CharSrcCoordObed; tell It; setCharacterSource #mesquite.charMatrices.StoredCharacters.StoredCharacters; tell It; setDataSet #1161953040649633474; endTell; endTell; setMethod #mesquite.parsimony.ParsAncestralStates.ParsAncestralStates; tell It; setModelSource #mesquite.parsimony.CurrentParsModels.CurrentParsModels; endTell; endTell; setCharacter 1; toggleShowLegend on; toggleGray off; toggleWeights on; setInitialOffsetX -162; setInitialOffsetY -177; setLegendWidth 142; setLegendHeight 177; resume ; endTell; endTell; showWindow; getEmployee #mesquite.ornamental.BranchNotes.BranchNotes; tell It; setAlwaysOn off; endTell; getEmployee #mesquite.trees.ColorBranches.ColorBranches; tell It; setColor Red; removeColor off; endTell; endTell; endTell; endTell; end; begin brownie; taxset all=1-18; end; phylobase/inst/nexusfiles/testSubsetTaxa.nex0000644000176200001440000000066712547332570021122 0ustar liggesusers#NEXUS BEGIN TAXA; DIMENSIONS NTAX=6; TAXLABELS cnidaria porifera ctenophora protostomia deuterostomia xeno ; END; BEGIN TREES; TRANSLATE 1 deuterostomia, 2 protostomia, 3 porifera, 4 ctenophora, 5 cnidaria, 6 xeno; TREE hyp1 = (3,((4,5),(1,2))); TREE hyp2 = (3,(4,(6,(1,2)))); TREE hyp3 = (1,(2,(3,(4,(5,6))))); END; phylobase/inst/nexusfiles/treeWithContinuousData.nex0000644000176200001440000003623012347155416022606 0ustar liggesusers#NEXUS [written Tue May 29 18:24:39 PDT 2007 by Mesquite version 1.06 (build g97) at cnidaria-1347.ucdavis.edu/169.237.66.185] BEGIN TAXA; DIMENSIONS NTAX=18; TAXLABELS Myrmecocystuscfnavajo Myrmecocystuscreightoni Myrmecocystusdepilis Myrmecocystuskathjuli Myrmecocystuskennedyi Myrmecocystusmendax Myrmecocystusmexicanus Myrmecocystusmimicus Myrmecocystusnavajo Myrmecocystusnequazcatl Myrmecocystusplacodops Myrmecocystusromainei Myrmecocystussemirufus Myrmecocystussnellingi Myrmecocystustenuinodis Myrmecocystustestaceus Myrmecocystuswheeleri Myrmecocystusyuma ; END; BEGIN CHARACTERS; TITLE 'Morphology'; DIMENSIONS NCHAR=32; FORMAT DATATYPE = CONTINUOUS; CHARSTATELABELS 1 eyewidth, 2 eyelength, 3 headlength, 4 headwidth, 5 mesosomaprofilehaircount, 6 FLfemurlength, 7 FLtibialength, 8 MLfemurlength, 9 MLtibialength, 10 HLfemurlength, 11 HLtibialength, 12 mesosomalength, 13 scapelength, 14 funiculuslength, 15 mesosomamaxwidth, 16 mesosomaminwidth, 17 lneyewidth, 18 lneyelength, 19 lnheadlength, 20 lnheadwidth, 21 lnmesosomaprofilehaircount, 22 lnFLfemurlength, 23 lnFLtibialength, 24 lnMLfemurlength, 25 lnMLtibialength, 26 lnHLfemurlength, 27 lnHLtibialength, 28 lnmesosomalength, 29 lnscapelength, 30 lnfuniculuslength, 31 lnmesosomamaxwidth, 32 lnmesosomaminwidth ; MATRIX Myrmecocystuscfnavajo 0.347 0.433 1.338 1.052 39.0 1.434 1.246 1.515 1.409 2.007 2.126 1.962 1.63 2.464 0.836 0.417 -1.058430499 -0.837017551 0.291175962 0.050693114 3.663561646 0.360467742 0.21993842 0.415415439 0.342880233 0.69664107 0.75424228 0.673964361 0.488580015 0.901786046 -0.179126666 -0.874669057 Myrmecocystuscreightoni 0.1622 0.20655 0.82985 0.71865 0.0 0.8226 0.68895 0.7854 0.7704 1.0457 1.05835 1.11875 0.89955 1.4073 0.4955 0.28995 -1.819995314 -1.577954034 -0.187439126 -0.332990376 1.098612289 -0.198226599 -0.374805986 -0.242539085 -0.261554411 0.041684897 0.053820826 0.109048315 -0.106449058 0.340231802 -0.70254289 -1.243482504 Myrmecocystusdepilis 0.2345 0.279 1.2125 1.0218 24.0 1.25183 1.0856245 1.31244 1.278025 1.70082 1.77591 1.774585 1.335 2.049 0.7741235 0.438396 -1.453769132 -1.2784033 0.185730051 0.015758636 3.163968392 0.217906079 0.073480925 0.262244849 0.23828925 0.523667061 0.565922636 0.566419189 0.284385731 0.712661014 -0.266387722 -0.827757638 Myrmecocystuskathjuli 0.206 0.247 1.1235 0.951 19.5 1.35352 1.101125 1.39927 1.29104 1.708335 1.794895 1.70561 1.379 2.04 0.7319725 0.4122135 -1.579985164 -1.398768684 0.115861323 -0.05067484 2.890371758 0.299777539 0.092762585 0.334283576 0.252849066 0.529578184 0.581198779 0.53251657 0.319877422 0.710946449 -0.315164554 -0.88802496 Myrmecocystuskennedyi 0.219 0.277 1.2115 1.075 27.5 1.405 1.176 1.4625 1.456 1.8545 1.9205 1.8345 1.4375 2.1 0.7655 0.455 -1.518693975 -1.283737773 0.191857133 0.072285615 3.314020688 0.339154824 0.16141842 0.379143386 0.373863136 0.615804395 0.650805137 0.606659596 0.362132481 0.741737305 -0.267251876 -0.788424862 Myrmecocystusmendax 0.2721 0.3336 1.558 1.4531 85.0 1.8742 1.6042 1.994 1.935 2.6013 2.6829 2.5963 1.9381 2.9722 1.0311 0.5232 -1.301585633 -1.097812608 0.443402947 0.373699205 4.442651256 0.628181902 0.47262519 0.690142672 0.660107326 0.95601132 0.986898299 0.954087355 0.661708112 1.089302419 0.030626194 -0.647791479 Myrmecocystusmexicanus 0.4335 0.5285 1.602 1.2705 26.5 2.242 1.8555 2.4795 2.2075 3.0705 3.089 2.597 2.211 3.239 0.916 0.394 -0.837335004 -0.642862653 0.466427394 0.227429133 3.275540168 0.796749683 0.612629812 0.902886082 0.785535617 1.116397202 1.124535193 0.952838633 0.792756695 1.172973609 -0.096394475 -0.93952217 Myrmecocystusmimicus 0.2197 0.2733 1.141 1.036 30.0 1.23793 1.027 1.26786 1.1749 1.56482 1.63226 1.67201 1.264 1.881 0.708 0.384 -1.5154923 -1.297185186 0.131905071 0.035367144 3.401197382 0.21344063 0.026641931 0.23733044 0.161183038 0.447770801 0.489965558 0.514026496 0.234281296 0.63180355 -0.345311185 -0.957112726 Myrmecocystusnavajo 0.2805 0.3755 1.0525 0.795 18.5 1.168535 1.0180075 1.16102 1.12958 1.634705 1.65155 1.546225 1.3485 1.954 0.6263965 0.314671 -1.272519447 -0.980051192 0.050015872 -0.230223916 2.90855558 0.153682711 0.016748671 0.148877742 0.121090106 0.491448376 0.501633856 0.434955774 0.298626416 0.669236464 -0.468766381 -1.171358882 Myrmecocystusnequazcatl 0.238 0.295 1.058 1.118 49.0 1.51118 1.1793 1.60672 1.41636 1.95228 1.96042 2.01975 1.477 2.228 0.84806 0.486044 -1.435484605 -1.220779923 0.056380333 0.111541375 3.891820298 0.412890803 0.164921042 0.474194834 0.3480902 0.66899792 0.673158736 0.702973741 0.390013004 0.801104322 -0.164803891 -0.721456124 Myrmecocystusplacodops 0.2805 0.347 1.5425 1.4355 39.5 1.6688 1.474045 1.838315 1.761365 2.349265 2.418685 2.28195 1.8045 2.7645 0.955494 0.484641 -1.271539142 -1.058496944 0.433360292 0.360682154 3.675579114 0.512103438 0.387068202 0.606349823 0.563245783 0.852964487 0.881290662 0.824898518 0.589936973 1.015395403 -0.047278511 -0.724537171 Myrmecocystusromainei 0.229 0.271 1.164 1.067 27.0 1.31488 1.06962 1.369 1.278 1.74 1.78517 1.72 1.346 2.081 0.797 0.421 -1.474033275 -1.305636458 0.151862349 0.064850972 3.295836866 0.273745407 0.067303445 0.314080546 0.245296356 0.553885113 0.579513649 0.542324291 0.297137231 0.732848547 -0.2269006 -0.865122445 Myrmecocystussemirufus 0.2393 0.295 1.3424 1.2826 69.0 1.548 1.3236 1.626 1.611 2.074 2.272 2.0392 1.572 2.3424 0.8935 0.4917 -1.430037284 -1.220779923 0.294459057 0.248889268 4.234106505 0.436963775 0.280355297 0.486123011 0.476855104 0.72947911 0.820660501 0.712557574 0.452348694 0.851176045 -0.112608944 -0.709886505 Myrmecocystussnellingi 0.1626 0.2052 0.786 0.69185 17.0 0.7471 0.5778 0.71195 0.68865 0.95225 0.93645 1.02635 0.83555 1.3684 0.47505 0.2805 -1.819869438 -1.586743338 -0.244666624 -0.374320538 2.83148024 -0.296208766 -0.554168612 -0.349125994 -0.38004857 -0.051854551 -0.071457181 0.020580617 -0.182376816 0.309479365 -0.750825896 -1.272022688 Myrmecocystustenuinodis 0.16695 0.2165 0.80965 0.69565 15.5 0.82035 0.79215 0.82915 0.7881 1.02385 1.0765 1.0843 0.89445 1.37155 0.5079 0.2895 -1.794140731 -1.531128383 -0.212724354 -0.364765146 2.714672815 -0.201043311 -0.233005565 -0.188002646 -0.240303423 0.023136261 0.071803358 0.077801384 -0.1121299 0.313462769 -0.679348936 -1.244818912 Myrmecocystustestaceus 0.271 0.3475 1.0435 0.8825 23.5 1.11074 0.981997 1.145875 1.10783 1.527625 1.55838 1.505275 1.329 2.018 0.6360145 0.288181 -1.305643267 -1.057223576 0.041499168 -0.125900131 3.14578457 0.102786566 -0.021927567 0.135585284 0.099368885 0.423310977 0.441300868 0.408161226 0.283878423 0.701812041 -0.453369253 -1.244254341 Myrmecocystuswheeleri 0.197 0.259 1.153 0.981 32.0 1.34961 1.11238 1.43273 1.26582 1.62673 1.75947 1.77914 1.427 2.058 0.732 0.394545 -1.62455155 -1.350927217 0.142367241 -0.019182819 3.465735903 0.299815662 0.106501864 0.359581715 0.235720134 0.486571865 0.565012627 0.576130101 0.355574338 0.721734637 -0.311974765 -0.930022077 Myrmecocystusyuma 0.189 0.237 0.864 0.809 10.0 0.867184 0.783 0.878905 0.757646 1.0528 1.15593 1.14947 0.932 1.437 0.549142 0.319 -1.666008264 -1.439695138 -0.14618251 -0.211956362 2.302585093 -0.142504099 -0.244622583 -0.129078464 -0.277539021 0.051453282 0.144905215 0.139300967 -0.070422464 0.362557607 -0.599398219 -1.142564176 ; END; BEGIN TREES; TRANSLATE 1 Myrmecocystuscfnavajo, 2 Myrmecocystuscreightoni, 3 Myrmecocystusdepilis, 4 Myrmecocystuskathjuli, 5 Myrmecocystuskennedyi, 6 Myrmecocystusmendax, 7 Myrmecocystusmexicanus, 8 Myrmecocystusmimicus, 9 Myrmecocystusnavajo, 10 Myrmecocystusnequazcatl, 11 Myrmecocystusplacodops, 12 Myrmecocystusromainei, 13 Myrmecocystussemirufus, 14 Myrmecocystussnellingi, 15 Myrmecocystustenuinodis, 16 Myrmecocystustestaceus, 17 Myrmecocystuswheeleri, 18 Myrmecocystusyuma; TREE bestML = (((((((((13:1.724765,11:1.724765):2.926053,6:4.650818):0.689044,(4:1.08387,17:1.08387):4.255993):0.198842,((8:2.708942,3:2.708942):2.027251,((12:2.193845,10:2.193845):2.257581,18:4.451425):0.284767):0.802512):0.506099,5:6.044804):4.524387,2:10.569191):0.836689,(14:2.770378,15:2.770378):8.635503):0.89482,16:12.300701):1.699299,(7:5.724923,(1:2.869547,9:2.869547):2.855375):8.275077); END; BEGIN ASSUMPTIONS; TYPESET * UNTITLED (CHARACTERS = 'Morphology') = Squared: 1 - 32; END; Begin MESQUITE; MESQUITESCRIPTVERSION 2; TITLE AUTO; tell ProjectCoordinator; getEmployee #mesquite.minimal.ManageTaxa.ManageTaxa; tell It; setID 0 9015005506118934442; endTell; getEmployee #mesquite.charMatrices.ManageCharacters.ManageCharacters; tell It; setID 0 2565950173085067248; checksum 0 389122022; setID 1 1161953040649633474; checksum 1 3582198254; endTell; getEmployee #mesquite.charMatrices.BasicDataWindowCoord.BasicDataWindowCoord; tell It; showDataWindow #2565950173085067248 #mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindowMaker; tell It; getWindow; tell It; setSize 420 280; setLocation 400 156; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; endTell; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.arrow; colorCells #mesquite.charMatrices.NoColor.NoColor; setBackground White; toggleShowNames on; toggleTight off; toggleShowChanges on; toggleSeparateLines off; toggleShowStates on; toggleAutoWithCharNames on; toggleShowDefaultCharNames off; toggleConstrainCW on; toggleBirdsEye off; toggleColorsPanel off; birdsEyeWidth 2; toggleLinkedScrolling on; toggleScrollLinkedTables off; endTell; showWindow; getWindow; tell It; forceAutosize; endTell; getEmployee #mesquite.charMatrices.AnnotPanel.AnnotPanel; tell It; togglePanel off; endTell; getEmployee #mesquite.charMatrices.ColorCells.ColorCells; tell It; setColor Red; removeColor off; endTell; endTell; showDataWindow #1161953040649633474 #mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindowMaker; tell It; getWindow; tell It; getTable; tell It; rowNamesWidth 232; endTell; setSize 798 748; setLocation 348 22; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.ibeam; endTell; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.ibeam; colorCells #mesquite.charMatrices.NoColor.NoColor; setBackground White; toggleShowNames on; toggleTight off; toggleShowChanges on; toggleSeparateLines off; toggleShowStates on; toggleAutoWithCharNames on; toggleShowDefaultCharNames off; toggleConstrainCW on; toggleBirdsEye off; toggleColorsPanel off; birdsEyeWidth 2; toggleLinkedScrolling on; toggleScrollLinkedTables off; endTell; showWindow; getWindow; tell It; forceAutosize; endTell; getEmployee #mesquite.categ.StateNamesEditor.StateNamesEditor; tell It; makeWindow; tell It; setSize 314 400; setLocation 60 10; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; setTool mesquite.categ.StateNamesEditor.StateNamesWindow.ibeam; endTell; rowsAreCharacters on; toggleConstrainChar on; toggleConstrainCharNum 3; togglePanel off; endTell; showWindow; endTell; getEmployee #mesquite.categ.StateNamesStrip.StateNamesStrip; tell It; showStrip off; endTell; getEmployee #mesquite.charMatrices.AnnotPanel.AnnotPanel; tell It; togglePanel off; endTell; getEmployee #mesquite.charMatrices.ColorCells.ColorCells; tell It; setColor Red; removeColor off; endTell; getEmployee #mesquite.charMatrices.QuickKeySelector.QuickKeySelector; tell It; autotabOff; endTell; endTell; endTell; getEmployee #mesquite.trees.BasicTreeWindowCoord.BasicTreeWindowCoord; tell It; makeTreeWindow #9015005506118934442 #mesquite.trees.BasicTreeWindowMaker.BasicTreeWindowMaker; tell It; setTreeSource #mesquite.trees.StoredTrees.StoredTrees; tell It; setTreeBlock 1; toggleUseWeights off; endTell; setAssignedID 630.1180487973731.4514395117633566598; getTreeWindow; tell It; setSize 520 400; setLocation 60 10; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; endTell; setActive; getTreeDrawCoordinator #mesquite.trees.BasicTreeDrawCoordinator.BasicTreeDrawCoordinator; tell It; suppress; setTreeDrawer #mesquite.trees.DiagonalDrawTree.DiagonalDrawTree; tell It; setEdgeWidth 12; orientUp; getEmployee #mesquite.trees.NodeLocsStandard.NodeLocsStandard; tell It; stretchToggle off; branchLengthsToggle off; toggleScale on; toggleCenter off; toggleEven off; namesAngle ?; endTell; endTell; setBackground White; setBranchColor Black; showNodeNumbers off; labelBranchLengths off; desuppress; getEmployee #mesquite.trees.BasicDrawTaxonNames.BasicDrawTaxonNames; tell It; setColor Black; toggleColorPartition on; toggleShadePartition off; toggleNodeLabels on; toggleShowNames on; endTell; endTell; setTreeNumber 1; useSuggestedSize on; toggleTextOnTree off; newAssistant #mesquite.ancstates.TraceCharacterHistory.TraceCharacterHistory; tell It; suspend ; setDisplayMode #mesquite.ancstates.ShadeStatesOnTree.ShadeStatesOnTree; tell It; toggleLabels off; endTell; setHistorySource #mesquite.ancstates.RecAncestralStates.RecAncestralStates; tell It; getCharacterSource #mesquite.charMatrices.CharSrcCoordObed.CharSrcCoordObed; tell It; setCharacterSource #mesquite.charMatrices.StoredCharacters.StoredCharacters; tell It; setDataSet #1161953040649633474; endTell; endTell; setMethod #mesquite.parsimony.ParsAncestralStates.ParsAncestralStates; tell It; setModelSource #mesquite.parsimony.CurrentParsModels.CurrentParsModels; endTell; endTell; setCharacter 1; toggleShowLegend on; toggleGray off; toggleWeights on; setInitialOffsetX -162; setInitialOffsetY -177; setLegendWidth 142; setLegendHeight 177; resume ; endTell; endTell; showWindow; getEmployee #mesquite.ornamental.BranchNotes.BranchNotes; tell It; setAlwaysOn off; endTell; getEmployee #mesquite.trees.ColorBranches.ColorBranches; tell It; setColor Red; removeColor off; endTell; endTell; endTell; endTell; end; begin brownie; taxset all=1-18; end; phylobase/inst/nexusfiles/minSeq.nex0000644000176200001440000000023512347155416017362 0ustar liggesusers#NEXUS begin data; dimensions ntax=3 nchar=4; format datatype=dna missing=?; matrix seq1 atcg seq2 tcga seq3 cgat ; end; phylobase/inst/nexusfiles/test_min.nex0000644000176200001440000000045112547322474017752 0ustar liggesusers#NEXUS BEGIN TAXA; DIMENSIONS NTAX=4; TAXLABELS cnidaria porifera ctenophora protostomia ; END; BEGIN TREES; TRANSLATE 1 cnidaria, 2 protostomia, 3 porifera, 4 ctenophora; TREE hyp1 = ((1:5,2:5):3,(3:6,4:6):3); END; phylobase/inst/nexusfiles/treeWithSpecialCharacters.nex0000644000176200001440000000124712347155416023226 0ustar liggesusers#NEXUS BEGIN TAXA; DIMENSIONS NTAX=6; TAXLABELS Species_1 'Species 2' 'Species 3' 'Species/4' 'Species\5' 'Species"6' ; END; BEGIN CHARACTERS; TITLE TestCharacters; DIMENSIONS NCHAR=2; FORMAT DATATYPE = STANDARD GAP = - MISSING = ? SYMBOLS = " 0 1"; CHARSTATELABELS 1 character1 / state1.1 'state 1.2', 2 character2 / state2.1 'state 2 2'; MATRIX Species_1 01 'Species 2' 10 'Species 3' 11 'Species/4' 00 'Species\5' 01 'Species"6' ?1 ; END; BEGIN TREES; TRANSLATE 1 Species_1, 2 'Species 2', 3 'Species 3', 4 'Species/4', 5 'Species\5', 6 'Species"6'; TREE tree1 = ((((1,2),3),4),5); END; phylobase/inst/nexusfiles/newick.tre0000644000176200001440000000002612347155416017404 0ustar liggesusers(a:1,(b:2,c:3)xx:4)yy;phylobase/inst/nexusfiles/treeWithDiscAndContData.nex0000644000176200001440000003766712347155416022610 0ustar liggesusers#NEXUS [written Tue May 29 18:24:39 PDT 2007 by Mesquite version 1.06 (build g97) at cnidaria-1347.ucdavis.edu/169.237.66.185] BEGIN TAXA; DIMENSIONS NTAX=18; TAXLABELS Myrmecocystuscfnavajo Myrmecocystuscreightoni Myrmecocystusdepilis Myrmecocystuskathjuli Myrmecocystuskennedyi Myrmecocystusmendax Myrmecocystusmexicanus Myrmecocystusmimicus Myrmecocystusnavajo Myrmecocystusnequazcatl Myrmecocystusplacodops Myrmecocystusromainei Myrmecocystussemirufus Myrmecocystussnellingi Myrmecocystustenuinodis Myrmecocystustestaceus Myrmecocystuswheeleri Myrmecocystusyuma ; END; BEGIN CHARACTERS; TITLE Morphology; DIMENSIONS NCHAR=32; FORMAT DATATYPE = CONTINUOUS; CHARSTATELABELS 1 eyewidth, 2 eyelength, 3 headlength, 4 headwidth, 5 mesosomaprofilehaircount, 6 FLfemurlength, 7 FLtibialength, 8 MLfemurlength, 9 MLtibialength, 10 HLfemurlength, 11 HLtibialength, 12 mesosomalength, 13 scapelength, 14 funiculuslength, 15 mesosomamaxwidth, 16 mesosomaminwidth, 17 lneyewidth, 18 lneyelength, 19 lnheadlength, 20 lnheadwidth, 21 lnmesosomaprofilehaircount, 22 lnFLfemurlength, 23 lnFLtibialength, 24 lnMLfemurlength, 25 lnMLtibialength, 26 lnHLfemurlength, 27 lnHLtibialength, 28 lnmesosomalength, 29 lnscapelength, 30 lnfuniculuslength, 31 lnmesosomamaxwidth, 32 lnmesosomaminwidth ; MATRIX Myrmecocystuscfnavajo 0.347 0.433 1.338 1.052 39.0 1.434 1.246 1.515 1.409 2.007 2.126 1.962 1.63 2.464 0.836 0.417 -1.058430499 -0.837017551 0.291175962 0.050693114 3.663561646 0.360467742 0.21993842 0.415415439 0.342880233 0.69664107 0.75424228 0.673964361 0.488580015 0.901786046 -0.179126666 -0.874669057 Myrmecocystuscreightoni 0.1622 0.20655 0.82985 0.71865 0.0 0.8226 0.68895 0.7854 0.7704 1.0457 1.05835 1.11875 0.89955 1.4073 0.4955 0.28995 -1.819995314 -1.577954034 -0.187439126 -0.332990376 1.098612289 -0.198226599 -0.374805986 -0.242539085 -0.261554411 0.041684897 0.053820826 0.109048315 -0.106449058 0.340231802 -0.70254289 -1.243482504 Myrmecocystusdepilis 0.2345 0.279 1.2125 1.0218 24.0 1.25183 1.0856245 1.31244 1.278025 1.70082 1.77591 1.774585 1.335 2.049 0.7741235 0.438396 -1.453769132 -1.2784033 0.185730051 0.015758636 3.163968392 0.217906079 0.073480925 0.262244849 0.23828925 0.523667061 0.565922636 0.566419189 0.284385731 0.712661014 -0.266387722 -0.827757638 Myrmecocystuskathjuli 0.206 0.247 1.1235 0.951 19.5 1.35352 1.101125 1.39927 1.29104 1.708335 1.794895 1.70561 1.379 2.04 0.7319725 0.4122135 -1.579985164 -1.398768684 0.115861323 -0.05067484 2.890371758 0.299777539 0.092762585 0.334283576 0.252849066 0.529578184 0.581198779 0.53251657 0.319877422 0.710946449 -0.315164554 -0.88802496 Myrmecocystuskennedyi 0.219 0.277 1.2115 1.075 27.5 1.405 1.176 1.4625 1.456 1.8545 1.9205 1.8345 1.4375 2.1 0.7655 0.455 -1.518693975 -1.283737773 0.191857133 0.072285615 3.314020688 0.339154824 0.16141842 0.379143386 0.373863136 0.615804395 0.650805137 0.606659596 0.362132481 0.741737305 -0.267251876 -0.788424862 Myrmecocystusmendax 0.2721 0.3336 1.558 1.4531 85.0 1.8742 1.6042 1.994 1.935 2.6013 2.6829 2.5963 1.9381 2.9722 1.0311 0.5232 -1.301585633 -1.097812608 0.443402947 0.373699205 4.442651256 0.628181902 0.47262519 0.690142672 0.660107326 0.95601132 0.986898299 0.954087355 0.661708112 1.089302419 0.030626194 -0.647791479 Myrmecocystusmexicanus 0.4335 0.5285 1.602 1.2705 26.5 2.242 1.8555 2.4795 2.2075 3.0705 3.089 2.597 2.211 3.239 0.916 0.394 -0.837335004 -0.642862653 0.466427394 0.227429133 3.275540168 0.796749683 0.612629812 0.902886082 0.785535617 1.116397202 1.124535193 0.952838633 0.792756695 1.172973609 -0.096394475 -0.93952217 Myrmecocystusmimicus 0.2197 0.2733 1.141 1.036 30.0 1.23793 1.027 1.26786 1.1749 1.56482 1.63226 1.67201 1.264 1.881 0.708 0.384 -1.5154923 -1.297185186 0.131905071 0.035367144 3.401197382 0.21344063 0.026641931 0.23733044 0.161183038 0.447770801 0.489965558 0.514026496 0.234281296 0.63180355 -0.345311185 -0.957112726 Myrmecocystusnavajo 0.2805 0.3755 1.0525 0.795 18.5 1.168535 1.0180075 1.16102 1.12958 1.634705 1.65155 1.546225 1.3485 1.954 0.6263965 0.314671 -1.272519447 -0.980051192 0.050015872 -0.230223916 2.90855558 0.153682711 0.016748671 0.148877742 0.121090106 0.491448376 0.501633856 0.434955774 0.298626416 0.669236464 -0.468766381 -1.171358882 Myrmecocystusnequazcatl 0.238 0.295 1.058 1.118 49.0 1.51118 1.1793 1.60672 1.41636 1.95228 1.96042 2.01975 1.477 2.228 0.84806 0.486044 -1.435484605 -1.220779923 0.056380333 0.111541375 3.891820298 0.412890803 0.164921042 0.474194834 0.3480902 0.66899792 0.673158736 0.702973741 0.390013004 0.801104322 -0.164803891 -0.721456124 Myrmecocystusplacodops 0.2805 0.347 1.5425 1.4355 39.5 1.6688 1.474045 1.838315 1.761365 2.349265 2.418685 2.28195 1.8045 2.7645 0.955494 0.484641 -1.271539142 -1.058496944 0.433360292 0.360682154 3.675579114 0.512103438 0.387068202 0.606349823 0.563245783 0.852964487 0.881290662 0.824898518 0.589936973 1.015395403 -0.047278511 -0.724537171 Myrmecocystusromainei 0.229 0.271 1.164 1.067 27.0 1.31488 1.06962 1.369 1.278 1.74 1.78517 1.72 1.346 2.081 0.797 0.421 -1.474033275 -1.305636458 0.151862349 0.064850972 3.295836866 0.273745407 0.067303445 0.314080546 0.245296356 0.553885113 0.579513649 0.542324291 0.297137231 0.732848547 -0.2269006 -0.865122445 Myrmecocystussemirufus 0.2393 0.295 1.3424 1.2826 69.0 1.548 1.3236 1.626 1.611 2.074 2.272 2.0392 1.572 2.3424 0.8935 0.4917 -1.430037284 -1.220779923 0.294459057 0.248889268 4.234106505 0.436963775 0.280355297 0.486123011 0.476855104 0.72947911 0.820660501 0.712557574 0.452348694 0.851176045 -0.112608944 -0.709886505 Myrmecocystussnellingi 0.1626 0.2052 0.786 0.69185 17.0 0.7471 0.5778 0.71195 0.68865 0.95225 0.93645 1.02635 0.83555 1.3684 0.47505 0.2805 -1.819869438 -1.586743338 -0.244666624 -0.374320538 2.83148024 -0.296208766 -0.554168612 -0.349125994 -0.38004857 -0.051854551 -0.071457181 0.020580617 -0.182376816 0.309479365 -0.750825896 -1.272022688 Myrmecocystustenuinodis 0.16695 0.2165 0.80965 0.69565 15.5 0.82035 0.79215 0.82915 0.7881 1.02385 1.0765 1.0843 0.89445 1.37155 0.5079 0.2895 -1.794140731 -1.531128383 -0.212724354 -0.364765146 2.714672815 -0.201043311 -0.233005565 -0.188002646 -0.240303423 0.023136261 0.071803358 0.077801384 -0.1121299 0.313462769 -0.679348936 -1.244818912 Myrmecocystustestaceus 0.271 0.3475 1.0435 0.8825 23.5 1.11074 0.981997 1.145875 1.10783 1.527625 1.55838 1.505275 1.329 2.018 0.6360145 0.288181 -1.305643267 -1.057223576 0.041499168 -0.125900131 3.14578457 0.102786566 -0.021927567 0.135585284 0.099368885 0.423310977 0.441300868 0.408161226 0.283878423 0.701812041 -0.453369253 -1.244254341 Myrmecocystuswheeleri 0.197 0.259 1.153 0.981 32.0 1.34961 1.11238 1.43273 1.26582 1.62673 1.75947 1.77914 1.427 2.058 0.732 0.394545 -1.62455155 -1.350927217 0.142367241 -0.019182819 3.465735903 0.299815662 0.106501864 0.359581715 0.235720134 0.486571865 0.565012627 0.576130101 0.355574338 0.721734637 -0.311974765 -0.930022077 Myrmecocystusyuma 0.189 0.237 0.864 0.809 10.0 0.867184 0.783 0.878905 0.757646 1.0528 1.15593 1.14947 0.932 1.437 0.549142 0.319 -1.666008264 -1.439695138 -0.14618251 -0.211956362 2.302585093 -0.142504099 -0.244622583 -0.129078464 -0.277539021 0.051453282 0.144905215 0.139300967 -0.070422464 0.362557607 -0.599398219 -1.142564176 ; END; BEGIN CHARACTERS; TITLE Foraging; DIMENSIONS NCHAR=2; FORMAT DATATYPE = STANDARD GAP = - MISSING = ? SYMBOLS = " 0 1 2"; CHARSTATELABELS 1 time / diurnal crepuscular nocturnal, 2 subgenus / Endiodioctes Eremnocystus Myrmecocystus ; MATRIX Myrmecocystuscfnavajo 22 Myrmecocystuscreightoni 11 Myrmecocystusdepilis 00 Myrmecocystuskathjuli 00 Myrmecocystuskennedyi 00 Myrmecocystusmendax 00 Myrmecocystusmexicanus 22 Myrmecocystusmimicus 00 Myrmecocystusnavajo 22 Myrmecocystusnequazcatl 00 Myrmecocystusplacodops 00 Myrmecocystusromainei 00 Myrmecocystussemirufus 00 Myrmecocystussnellingi 11 Myrmecocystustenuinodis 11 Myrmecocystustestaceus 12 Myrmecocystuswheeleri 00 Myrmecocystusyuma 11 ; END; BEGIN TREES; TRANSLATE 1 Myrmecocystuscfnavajo, 2 Myrmecocystuscreightoni, 3 Myrmecocystusdepilis, 4 Myrmecocystuskathjuli, 5 Myrmecocystuskennedyi, 6 Myrmecocystusmendax, 7 Myrmecocystusmexicanus, 8 Myrmecocystusmimicus, 9 Myrmecocystusnavajo, 10 Myrmecocystusnequazcatl, 11 Myrmecocystusplacodops, 12 Myrmecocystusromainei, 13 Myrmecocystussemirufus, 14 Myrmecocystussnellingi, 15 Myrmecocystustenuinodis, 16 Myrmecocystustestaceus, 17 Myrmecocystuswheeleri, 18 Myrmecocystusyuma; TREE bestML = (((((((((13:1.724765,11:1.724765):2.926053,6:4.650818):0.689044,(4:1.08387,17:1.08387):4.255993):0.198842,((8:2.708942,3:2.708942):2.027251,((12:2.193845,10:2.193845):2.257581,18:4.451425):0.284767):0.802512):0.506099,5:6.044804):4.524387,2:10.569191):0.836689,(14:2.770378,15:2.770378):8.635503):0.89482,16:12.300701):1.699299,(7:5.724923,(1:2.869547,9:2.869547):2.855375):8.275077); END; BEGIN ASSUMPTIONS; TYPESET * UNTITLED (CHARACTERS = 'Morphology') = Squared: 1 - 32; END; Begin MESQUITE; MESQUITESCRIPTVERSION 2; TITLE AUTO; tell ProjectCoordinator; getEmployee #mesquite.minimal.ManageTaxa.ManageTaxa; tell It; setID 0 9015005506118934442; endTell; getEmployee #mesquite.charMatrices.ManageCharacters.ManageCharacters; tell It; setID 0 2565950173085067248; checksum 0 389122022; setID 1 1161953040649633474; checksum 1 3582198254; endTell; getEmployee #mesquite.charMatrices.BasicDataWindowCoord.BasicDataWindowCoord; tell It; showDataWindow #2565950173085067248 #mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindowMaker; tell It; getWindow; tell It; setSize 420 280; setLocation 400 156; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; endTell; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.arrow; colorCells #mesquite.charMatrices.NoColor.NoColor; setBackground White; toggleShowNames on; toggleTight off; toggleShowChanges on; toggleSeparateLines off; toggleShowStates on; toggleAutoWithCharNames on; toggleShowDefaultCharNames off; toggleConstrainCW on; toggleBirdsEye off; toggleColorsPanel off; birdsEyeWidth 2; toggleLinkedScrolling on; toggleScrollLinkedTables off; endTell; showWindow; getWindow; tell It; forceAutosize; endTell; getEmployee #mesquite.charMatrices.AnnotPanel.AnnotPanel; tell It; togglePanel off; endTell; getEmployee #mesquite.charMatrices.ColorCells.ColorCells; tell It; setColor Red; removeColor off; endTell; endTell; showDataWindow #1161953040649633474 #mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindowMaker; tell It; getWindow; tell It; getTable; tell It; rowNamesWidth 232; endTell; setSize 798 748; setLocation 348 22; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.ibeam; endTell; setTool mesquite.charMatrices.BasicDataWindowMaker.BasicDataWindow.ibeam; colorCells #mesquite.charMatrices.NoColor.NoColor; setBackground White; toggleShowNames on; toggleTight off; toggleShowChanges on; toggleSeparateLines off; toggleShowStates on; toggleAutoWithCharNames on; toggleShowDefaultCharNames off; toggleConstrainCW on; toggleBirdsEye off; toggleColorsPanel off; birdsEyeWidth 2; toggleLinkedScrolling on; toggleScrollLinkedTables off; endTell; showWindow; getWindow; tell It; forceAutosize; endTell; getEmployee #mesquite.categ.StateNamesEditor.StateNamesEditor; tell It; makeWindow; tell It; setSize 314 400; setLocation 60 10; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; setTool mesquite.categ.StateNamesEditor.StateNamesWindow.ibeam; endTell; rowsAreCharacters on; toggleConstrainChar on; toggleConstrainCharNum 3; togglePanel off; endTell; showWindow; endTell; getEmployee #mesquite.categ.StateNamesStrip.StateNamesStrip; tell It; showStrip off; endTell; getEmployee #mesquite.charMatrices.AnnotPanel.AnnotPanel; tell It; togglePanel off; endTell; getEmployee #mesquite.charMatrices.ColorCells.ColorCells; tell It; setColor Red; removeColor off; endTell; getEmployee #mesquite.charMatrices.QuickKeySelector.QuickKeySelector; tell It; autotabOff; endTell; endTell; endTell; getEmployee #mesquite.trees.BasicTreeWindowCoord.BasicTreeWindowCoord; tell It; makeTreeWindow #9015005506118934442 #mesquite.trees.BasicTreeWindowMaker.BasicTreeWindowMaker; tell It; setTreeSource #mesquite.trees.StoredTrees.StoredTrees; tell It; setTreeBlock 1; toggleUseWeights off; endTell; setAssignedID 630.1180487973731.4514395117633566598; getTreeWindow; tell It; setSize 520 400; setLocation 60 10; setFont SanSerif; setFontSize 10; onInfoBar; setExplanationSize 30; setAnnotationSize 20; setFontIncAnnot 0; setFontIncExp 0; getToolPalette; tell It; endTell; setActive; getTreeDrawCoordinator #mesquite.trees.BasicTreeDrawCoordinator.BasicTreeDrawCoordinator; tell It; suppress; setTreeDrawer #mesquite.trees.DiagonalDrawTree.DiagonalDrawTree; tell It; setEdgeWidth 12; orientUp; getEmployee #mesquite.trees.NodeLocsStandard.NodeLocsStandard; tell It; stretchToggle off; branchLengthsToggle off; toggleScale on; toggleCenter off; toggleEven off; namesAngle ?; endTell; endTell; setBackground White; setBranchColor Black; showNodeNumbers off; labelBranchLengths off; desuppress; getEmployee #mesquite.trees.BasicDrawTaxonNames.BasicDrawTaxonNames; tell It; setColor Black; toggleColorPartition on; toggleShadePartition off; toggleNodeLabels on; toggleShowNames on; endTell; endTell; setTreeNumber 1; useSuggestedSize on; toggleTextOnTree off; newAssistant #mesquite.ancstates.TraceCharacterHistory.TraceCharacterHistory; tell It; suspend ; setDisplayMode #mesquite.ancstates.ShadeStatesOnTree.ShadeStatesOnTree; tell It; toggleLabels off; endTell; setHistorySource #mesquite.ancstates.RecAncestralStates.RecAncestralStates; tell It; getCharacterSource #mesquite.charMatrices.CharSrcCoordObed.CharSrcCoordObed; tell It; setCharacterSource #mesquite.charMatrices.StoredCharacters.StoredCharacters; tell It; setDataSet #1161953040649633474; endTell; endTell; setMethod #mesquite.parsimony.ParsAncestralStates.ParsAncestralStates; tell It; setModelSource #mesquite.parsimony.CurrentParsModels.CurrentParsModels; endTell; endTell; setCharacter 1; toggleShowLegend on; toggleGray off; toggleWeights on; setInitialOffsetX -162; setInitialOffsetY -177; setLegendWidth 142; setLegendHeight 177; resume ; endTell; endTell; showWindow; getEmployee #mesquite.ornamental.BranchNotes.BranchNotes; tell It; setAlwaysOn off; endTell; getEmployee #mesquite.trees.ColorBranches.ColorBranches; tell It; setColor Red; removeColor off; endTell; endTell; endTell; endTell; end; begin brownie; taxset all=1-18; end; phylobase/inst/nexusfiles/treeRoundingError.nex0000644000176200001440000000056712347155416021615 0ustar liggesusers#NEXUS BEGIN TAXA; DIMENSIONS NTAX=4; TAXLABELS spA spB spC spD ; END; BEGIN CHARACTERS; TITLE 'Morphology'; DIMENSIONS NCHAR=1; FORMAT DATATYPE = CONTINUOUS; CHARSTATELABELS 1 testTest; MATRIX spA 0.6263965 spB 0.7741235 spC 1.0180075 spD 1.0856245 ; END; BEGIN TREES; TRANSLATE 1 spA, 2 spB, 3 spC, 4 spD; TREE testTree = (1,(2,(3,4))); END; phylobase/inst/nexusfiles/ExContData.Rdata0000644000176200001440000001076412347155416020371 0ustar liggesusers‹…Y 8TÛû—¹$…¤J*¥”¾)¥ˆsФ2‰ÑŒ!:E7ݯT*E)¡T*‘ÂÊ5÷B.‘Kîw3 †ÐoÏSÎñþûy¶5ûûÖúÖ»Þõ}ïÚ3,7X/“´–$ÂaI!‚°þQTÿ#„ßø-iìeäBcl 2ˆ‚È4Ü2 ¿eð[òëûÉ#PÐkü ; œ”fš{ÚAöÞp¤ãdé™f„wC®ºÆâCK¯B¾¨r#Á òÌ«×ØÛ¨A¾gfÌjk9È\:¿ÅëËäNæ~(†´Ž^L¨.¤}žù§ÎH߬2ùŽ0XËíßVØ I¼P›Æql~®Â+þ.ðïzýùÈ©XøtïÕb™¢ð™‹Âg Ž"ß(¨˜ý¹ÁÎPl|þN`(xÇ]P'd»êÿð¹F€l£ÛkfÃöÃI(1p}X*i5ø*†{b¡‚o/]Wïa/êlGIàp£oz=ZX<ÐMž•ôº×ŸÃ™‹€ž¼ ºCx &¿[XÝ_ýù_¡GËŠ‚ÖË7-×B —Æa6´4‡«5ÞùLÞr§Ã¼ ô:r'¸ L,ŽX€‹íw& 2°úð JgB?4d©)ÔC'-ð¾UÐeo£5y)0ù¼1wma3ËŒ%Ïë,œ? …ß²–ó.hü©mÒ>ç„Þ=tç 4¦fuæü€v>_ì¿x“Ëšq(´ðÌnc¸0 ŒÀ½0££íþóòc£íè#[ÇoWñÛ5üÖ„ßoî˜}ôyì–òÛ%üVß_ŸßñÛe‚q£|qÒ‚ðàÀàk‡ûTŠÇWè½¢7ÞtCï-BxzÔ&èÉ¿-•ÓlqŸúZgè•@w÷?ˆÎâr³?´!NDOd4ôq³AáhÅ7qåT]hj^ghÓI‚VÌìQDò`¥š‘“`B]¼†>Vä&êè~e‘ð:üW~áUv%}ô߈^‘h±žäŸ¬Ÿ¬àÑzdåšq.z“¿¯¬½q9¯3§KmÁ7ºí:订<3L͆nâ{@7ž”x*B£TMUáÙ|¨=º“ÊV×€þþwQOq8R`˜›¶auÐÃÇÇÜœ²ÆÛ²P€k_÷Ô„aSæmø‰ƒ7ºqúHŽÌSÄAèk÷ÜRÍ™ìÍš×Ö7öÏdÅjòNèå÷x3K¼rÃ4hW¶k1«‡~~]´hð 3M÷ä’XÐz–|ý…¹ tï8.6·r &R2Z¿~¾uœãFàÀÕ G CÚ—äzgdÃHoÊ[­>`GL¿¢¶®ØX®WK_$tãÁ×ϲ6=Û*üt ÞŽÖi_$e†GÞh^Z8+¡ß”FËo4JŒ¿è£-«Ôp¥9¬ø§=«Üˆ˜Pw¢ÐÇ]Ø<è–O9Lrwä=·=ö˜pŽ)=}úaLô“ç¾²gQðc‡•B|Ž# Š+IìüP Ç^ŠO+¯LÞ¨?Fë~®=Ç–ÔÂ÷¹lWAa8Š+DÞÀ|¿¤}gñgèäÉÔF`£ÏÝ×´ŽO±ÉW¹‚ò#ð÷Pómz¼¬—ðbžÙuȤ…Mò¼¾Ñýx ÅÕäÊÉÀÐül‘´èTKÀ™ñ„!§YwžèÂÐU§¡|Uø¹ç»íãlQèö‰f„»eÁ_W™]ÇŠ QÐÑO>_þX«¹B\œ.õʶ¯ÂØäQ=Å„„§l椢—»­à_ÛM”˜b—1áõ.x ‹˜húª.Ý’ðcËâX•h;:´û¸Ž’ ~¸t9k÷O²mðâ~øÍ|kÑæ‡´Fu±Û^?<èÝ7æÉ&°GóŒy°cÐhd°øyÏQ 2Ï4ÅDùù󓯜D^}üÊ/¾q;Õ(ø)ì1o£$ž7r<ž¡¯{lþz{mµ¸‰½\ùgB?_·; ¹ï ý£"í¸:×%AkB‘ß™ëвƒ z¹é4·â×ã ï˜Q€ÞQÝþµ<™™„‰©ñLü£\΂½Á'cæ[KŒÀ?—Gxeë‹FׇFÏLˆ§ ÿAFÈå^yÐwj›¾ÿCè­çndô²¸‚’†ðbœ’„IŒž˜ÿ|ü9ŠWÀWûhÞCg€£¦N†0}÷Ç>?ºš¨¡&7`TÄ ‘G» 4§‡Ñ˜ÐÂ+wh›cÿÀ³ ¾ûû¯Ûí·š}x+Tóç«rà"Ô`qÇt3 ÞfB¤¨tðßGZq¶qi„z)×(ýÓ2\Õ^"¿í±‡jÑÝ/þC¨I’îкØåĘ÷{eÁWl5·°¡Œ>~“y®¢å|®V±6í_œ¸€  ’—vêPxù¼Îàý©ðÌBn†C¡Ûå·7Äíá+ÿý©œ¿Ÿ_æ\+öx3† õ}§e8»Û"¶õjg‡ʈ]dÊh-ïG›‚ý8ñ³ÐÀÈ‚´™ûå÷\šQ¿áÕà Pÿ‡­;Ü?£¾þ¤˜ÓKDÑ`8ÇDªó âlõ—ŽQ‹DÃ3_;N–¶ÀÛ%Nî˲ÑPLnËz9?Ä®k]úA] µæÐ?šPÄìú»àQŒbÛ؈­Þ+ÀÕsvû³}¥¸ÿÎÑ’Yˆuõ![œuõwŸÑîB½÷ȧ"ç!v²1Öv×±V¢Yø:êê¤tw Æ÷ON«Š_ˆØçu‚çnD°õ]$ó= mýqôe$âøó~A.AÌVÒ†¸çQ½ÿ߯ò/½D­™_Åûg·¢.Ûëëíøõ^Xæ”Ë®\ ‹ò‰·Óá›]l²ÂsHŒTrÓΔÕJƒ2¬gð¡Ö¨KöŠ|Ì zö Bªëê¸Õ®†UY;%)M¥Äª¤5†ÌË›ªBg¢#B6 7¾¡Ok`»œPŽþ%=45 €(œ$« •_»Mrå| 0ôþ±óýzô|±d¬™×§Š;Ç—þ­ ¥ŠN·Ûü?Aik´¼„Šì–ö–µsE"—”Ú Tå‘óF \3YëçåBˆ¾#ŸZà —3B.¢ýÅG¦DëãævdW:*6­|m7•²«4Ö^F¥Öæ-Ëî¢j>ewN¤Cž*¹lÙú2ˆdÓÃNï2Dy‡µ‡åD:!×/HŒ€I;Üœ”Ú^‰MM߸—¹2WÿGßev5&_”„žHaR+üA·À$Ìó#%«0É=ÕoEöÁdgÓŸk_2Ä„¾|ÿæœ&yRmÓæ‚d`´N-x‹‰=®V¾RŒMŠ{LôQÇ0‰?¯MOÝr “Ô5s°´)ĤÍOÞf`âÞf½¹9WÀWEÿÊæì]; †4åÎV…úr÷;—CÑ’Ë~s_B‘޶øÇ›ƒc9)#É©rê­Ÿ¹g½€?)FÈË“PNÍ»Ð1Õ¥ˆÙ© CqL¬‹•B$ÊÚwtMO*ìU¼}á<ÊzŸuºå‚¼Û¾ê ëŸfÐâ3 Óý¤J§6mÉÊÖÔ§5¢å‰\,++Ž˜”¥Ç¿Ñß¹ªàhüõ¥‡6·Wɼ7ŠÉ(-`@ɤxRH0¼ú¶+y­'¼ÔÏuÑþÞ骜¦þ+è“y6»ýb ¤EîþêrŽJ‡ A:U }>Ï2÷GyE³¬ß «£› mÕ»ÈPw'²¸N|äÎg露2€kó¯šd-Nù¥_ª£O$Aƒ^Ò!i*4*>V|7%Ší™÷Cc T„$vþl4äÛ•‰Ëߪ†Ï™ÁÁ¾ý³àËô†-Öæ“¡j׊ÍÃ_Ñ¿G¡èý}(3ª .µ²@Ÿ¤üÌ%ŠQ‰µÂ¥;ž(SÎë˜\Q9$ÛTän /…öz7›'ŸCùÍ?꜂TgQ_Ñ3\U§rŒ5m¡VLuÒr‰3Р~ûÀ¬‡ðYûÙWË"È_4-oCïnH{féúÀò©T(ƒOäªêy{(Ù¤:Ó(®¤.{˜f¥û–ë¢Ï‰f±Vo¢2˸µ)‘â(?ÅHÏÝ¥â] `{h´ÌQ Tñ\ Å,Ô™s¢’~¦Tι_%ÀÕdU ¯$ m¦G´%eß@g`˜4¶Äjº·u_aBõœ‹b‰Jø±ñÛíS¯ &ù;5ä¶|w6NqMGÚ_.IOà‰µâãvïP¨‹yzPËp„YÅKÆlÑAO.>"­˜/'/%I>„Š?N·_ÕÖ·Tó‘/hÜR»ò¦“,T»×Õ…5Ó¸Z ¿~º›¡}ùYo·ŽiÐuýibqjokkŸí+…Z…¶»¬éP½û–/+š µªYoØ¡P{ÁnÅú­YÐpþ”Ω}_ åâz©·Ì<¨/"›ºü³ž^vqÑóè•©è[ðŠC·±m€oëŒG˜y`(ß³\¼šgˆyNj¤÷»¥¤ú p5æŸRqƒVòµ€'§¡óL­®ãÔ‹ð]ÒN'pë%¨u‰°OÖ²…zÓË×3OAí,•ÙþÁðÝæ­×›#BÐè“’å¶S’¿ÜÓÍô¢A%yÀ/¼o œôÝnLS,ÊÒ‹‡×­Ù!•rùP®¾ÝhKÀkè<îV·R®©½™gÔ%Û“fÿõë{í·žM]ý ¶&õXÜhX{ôÚJüöªž™%Éïª0×57ÔÁ^ª§ …ËíVœå@‘¨i½ÊzflõôJ\·.ó¡”.^û,.½Ç֕俣ÖêÁ³‰¹(!æÂ%[(\(ç“ -{6—¼ê ªÞUP¤ú’swÃS®¶µÅ.­¥d1±­©ÀrÎÜw•iäÓ<–A“²ûÚ¬ e¨×KPø£~ógzel‡&wŸœ,Í:h ;ÓpJuç®Ë’‚¦óêV^Pœ±;(òB(åŸ8Wy¹ ¾Èf̳ \ëNW î4ß `ü=«‚æÈª÷‡§ý7Ó=W Îí„"f@\À5¡[wC¹jBl½•N+k / Ã{ä=üQQ?Yhå…2T2ýºâMaT0ÅWéóÊ“RÐYÅDéʦSîªÓ6^tÄj%*˜~7/!5þ³F_>gjK?×ú5$®,Ñš‰*E ^‘ÐÛgf¿µ ŒŽýšÕïPaCL߈Wc©i·²/jZâž÷Õ¿{³L­$µ;½¶ÔtÒD)‰ {Pçý'UÊ‹ÌQë‘á›â‹bPÛ Å Ìé¨Ii¡¦ái?Ô½‰µï–hjÑÏȈ¹9 õ4lkÆŒÛF×Óô¹êiý¸vSÜ ÔÓ|ÈÀQTuÊ]ÍÅÎ× ¶áÍ}ÌG݉µŸ¨hüë²I4¢3Ùÿ GýqŒkœLö&¢Ø3ùÏø3•Ls$ÉDûq ®å÷1ÊxXwg¢+Ýå…Jv$Rè$ƒï—Þ¸õÙÙƒ>. ndPöSˆãÛ&ê¹m¢ž&õ4™ §ÌºqV)wÑuüJexÐ($ª‡û8³ÜØxg¢×ï«þe§Ð~·KRiÿâTŠgt •ö^¥Fm¿œA¥ý?ÜÊRi±Ë3ÿ— Ü<Ã<ó„½'b™gþoo¹_XÇo •ö_®§Ri³-ÿ+Ê¿øþÝ#`|\‚KÐ]iÿžäò|‡Ò6oº3™äBòvgx¸»“)tîz]©D’‹½‹ë˜wÚ8¯3™fOôâ»ǹŽNTÊ„ÎCŽdœú˜Sa|PŠ3΄û„>{²+…JqŸ0(§‚B#ýcœ“Fvó &Ô1Êǹ½=œ‰/ƒL£‘í½'J¢“)Ž ebfid*•Bs˜x0ƒLó Ð\ì)Ï »3ˆ$òÿ±-Îd/ ‰Hó˜˜ ÒÑ“èä2ឹƋ!‰JtËÁÿì‰ ¢ö:žBøÓ÷þ´¼õžyphylobase/inst/doc/0000755000176200001440000000000013076473202013766 5ustar liggesusersphylobase/inst/doc/phylobase.Rnw0000644000176200001440000005742213075432207016455 0ustar liggesusers\documentclass{article} %\VignetteEngine{knitr::knitr} %\VignetteIndexEntry{phylo4: classes and methods for phylogenetic trees and data} \usepackage[utf8]{inputenc} % for UTF-8/single quotes from sQuote() \usepackage{graphicx} \usepackage{array} \usepackage{url} %% Use a little bit more of the page %% borrowed from Rd.sty, of r-project.org \addtolength{\textheight}{12mm} \addtolength{\topmargin}{-9mm} % still fits on US paper \addtolength{\textwidth}{24mm} % still fits on US paper \setlength{\oddsidemargin}{10mm} \setlength{\evensidemargin}{\oddsidemargin} \newcommand{\code}[1]{{{\tt #1}}} \title{The \code{phylo4} S4 classes and methods} \author{Ben Bolker, Peter Cowan \& Fran\c{c}ois Michonneau} \date{\today} \begin{document} <>= library(knitr) opts_chunk$set( fig.keep='none', dev='pdf', fig.width=6, fig.height=6, latex.options.color="usenames,dvipsnames" ) @ \maketitle \tableofcontents \section{Introduction} This document describes the new \code{phylo4} S4 classes and methods, which are intended to provide a unifying standard for the representation of phylogenetic trees and comparative data in R. The \code{phylobase} package was developed to help both end users and package developers by providing a common suite of tools likely to be shared by all packages designed for phylogenetic analysis, facilities for data and tree manipulation, and standardization of formats. This standardization will benefit \emph{end-users} by making it easier to move data and compare analyses across packages, and to keep comparative data synchronized with phylogenetic trees. Users will also benefit from a repository of functions for tree manipulation, for example tools for including or excluding subtrees (and associated phenotypic data) or improved tree and data plotting facilities. \code{phylobase} will benefit \emph{developers} by freeing them to put their programming effort into developing new methods rather than into re-coding base tools. We (the \code{phylobase} developers) hope \code{phylobase} will also facilitate code validation by providing a repository for benchmark tests, and more generally that it will help catalyze community development of comparative methods in R. A more abstract motivation for developing \code{phylobase} was to improve data checking and abstraction of the tree data formats. \code{phylobase} can check that data and trees are associated in the proper fashion, and protects users and developers from accidently reordering one, but not the other. It also seeks to abstract the data format so that commonly used information (for example, branch length information or the ancestor of a particular node) can be accessed without knowledge of the underlying data structure (i.e., whether the tree is stored as a matrix, or a list, or a parenthesis-based format). This is achieved through generic \code{phylobase} functions which which retrieve the relevant information from the data structures. The benefits of such abstraction are multiple: (1) \emph{easier access to the relevant information} via a simple function call (this frees both users and developers from learning details of complex data structures), (2) \emph{freedom to optimize data structures in the future without breaking code.} Having the generic functions in place to ``translate'' between the data structures and the rest of the program code allows program and data structure development to proceed somewhat independently. The alternative is code written for specific data structures, in which modifications to the data structure requires rewriting the entire package code (often exacting too high a price, which results in the persistence of less-optimal data structures). (3) \emph{providing broader access to the range of tools in \code{phylobase}}. Developers of specific packages can use these new tools based on S4 objects without knowing the details of S4 programming. The base \code{phylo4} class is modeled on the the \code{phylo} class in \code{ape}. \code{phylo4d} and \code{multiphylo4} extend the \code{phylo4} class to include data or multiple trees respectively. In addition to describing the classes and methods, this vignette gives examples of how they might be used. \section{Package overview} The phylobase package currently implements the following functions and data structures: \begin{itemize} \item Data structures for storing a single tree and multiple trees: \code{phylo4} and \code{multiPhylo4}? \item A data structure for storing a tree with associated tip and node data: \code{phylo4d} \item A data structure for storing multiple trees with one set of tip data: \code{multiPhylo4d} \item Functions for reading nexus files into the above data structures \item Functions for converting between the above data structures and \code{ape phylo} objects as well as \code{ade4} \code{phylog} objects (although the latter are now deprecated \ldots) \item Functions for editing trees and data (i.e., subsetting and replacing) \item Functions for plotting trees and trees with data \end{itemize} \section{Using the S4 help system} The \code{S4} help system works similarly to the \code{S3} help system with some small differences relating to how \code{S4} methods are written. The \code{plot()} function is a good example. When we type \code{?plot} we are provided the help for the default plotting function which expects \code{x} and \code{y}. \code{R} also provides a way to smartly dispatch the right type of plotting function. In the case of an \code{ape phylo} object (a \code{S3} class object) \code{R} evaluates the class of the object and finds the correct functions, so the following works correctly. <>= library(ape) set.seed(1) ## set random-number seed rand_tree <- rcoal(10) ## Make a random tree with 10 tips plot(rand_tree) @ However, typing \code{?plot} still takes us to the default \code{plot} help. We have to type \code{?plot.phylo} to find what we are looking for. This is because \code{S3} generics are simply functions with a dot and the class name added. The \code{S4} generic system is too complicated to describe here, but doesn't include the same dot notation. As a result \code{?plot.phylo4} doesn't work, \code{R} still finds the right plotting function. <>= library(phylobase) # convert rand_tree to a phylo4 object rand_p4_tree <- as(rand_tree, "phylo4") plot(rand_p4_tree) @ All fine and good, but how to we find out about all the great features of the \code{phylobase} plotting function? \code{R} has two nifty ways to find it, the first is to simply put a question mark in front of the whole call: <>= `?`(plot(rand_p4_tree)) @ \code{R} looks at the class of the \code{rand\_p4\_tree} object and takes us to the correct help file (note: this only works with \code{S4} objects). The second ways is handy if you already know the class of your object, or want to compare to generics for different classes: <>= `?`(method, plot("phylo4")) @ More information about how \code{S4} documentation works can be found in the methods package, by running the following command. <>= help('Documentation', package="methods") @ \section{Trees without data} You can start with a tree --- an object of class \code{phylo} from the \code{ape} package (e.g., read in using the \code{read.tree()} or \code{read.nexus()} functions), and convert it to a \code{phylo4} object. For example, load the raw \emph{Geospiza} data: <>= library(phylobase) data(geospiza_raw) ## what does it contain? names(geospiza_raw) @ Convert the \code{S3} tree to a \code{S4 phylo4} object using the \code{as()} function: <>= (g1 <- as(geospiza_raw$tree, "phylo4")) @ The (internal) nodes appear with labels \verb++ because they are not defined: <>= nodeLabels(g1) @ You can also retrieve the node labels with \code{labels(g1,"internal")}). A simple way to assign the node numbers as labels (useful for various checks) is <<>>= nodeLabels(g1) <- paste("N", nodeId(g1, "internal"), sep="") head(g1, 5) @ The \code{summary} method gives a little extra information, including information on the distribution of branch lengths: <>= summary(g1) @ Print tip labels: <>= tipLabels(g1) @ (\code{labels(g1,"tip")} would also work.) You can modify labels and other aspects of the tree --- for example, to convert all the labels to lower case: <>= tipLabels(g1) <- tolower(tipLabels(g1)) @ You could also modify selected labels, e.g. to modify the labels in positions 11 and 13 (which happen to be the only labels with uppercase letters): <>= tipLabels(g1)[c(11, 13)] <- c("platyspiza", "pinaroloxias") @ Note that for a given tree, \code{phylobase} always return the \code{tipLabels} in the same order. Print node numbers (in edge matrix order): <>= nodeId(g1, type='all') @ Does it have information on branch lengths? <>= hasEdgeLength(g1) @ It does! What do they look like? <>= edgeLength(g1) @ Note that the root has \verb++ as its length. Print edge labels (also empty in this case --- therefore all \code{NA}): <>= edgeLabels(g1) @ You can also use this function to label specific edges: <>= edgeLabels(g1)["23-24"] <- "an edge" edgeLabels(g1) @ The edge labels are named according to the nodes they connect (ancestor-descendant). You can get the edge(s) associated with a particular node: <>= getEdge(g1, 24) # default uses descendant node getEdge(g1, 24, type="ancestor") # edges using ancestor node @ These results can in turn be passed to the function \code{edgeLength} to retrieve the length of a given set of edges: <>= edgeLength(g1)[getEdge(g1, 24)] edgeLength(g1)[getEdge(g1, 24, "ancestor")] @ Is it rooted? <>= isRooted(g1) @ Which node is the root? <>= rootNode(g1) @ Does it contain any polytomies? <>= hasPoly(g1) @ Is the tree ultrametric? <>= isUltrametric(g1) @ You can also get the depth (distance from the root) of any given node or the tips: <>= nodeDepth(g1, 23) depthTips(g1) @ \section{Trees with data} The \code{phylo4d} class matches trees with data, or combines them with a data frame to make a \code{phylo4d} (tree-with-data) object. Now we'll take the \emph{Geospiza} data from \verb+geospiza_raw$data+ and merge it with the tree. First, let's prepare the data: <>= g1 <- as(geospiza_raw$tree, "phylo4") geodata <- geospiza_raw$data @ However, since \emph{G. olivacea} is included in the tree but not in the data set, we will initially run into some trouble: <>= g2 <- phylo4d(g1, geodata) @ <>= geodata <- geospiza_raw$data @ To deal with \emph{G. olivacea} missing from the data, we have a few choices. The easiest is to use \code{missing.data="warn"} to allow \code{R} to create the new object with a warning (you can also use \code{missing.data="OK"} to proceed without warnings): <>= g2 <- phylo4d(g1, geodata, missing.data="warn") @ <>= g2 <- phylo4d(g1, geodata, missing.data="OK", extra.data="OK") @ Another way to deal with this would be to use \code{prune()} to drop the offending tip from the tree first: <>= g1sub <- prune(g1, "olivacea") g1B <- phylo4d(g1sub, geodata) @ The difference between the two objects is that the species \emph{G. olivacea} is still present in the tree but has no data (i.e., \verb+NA+) associated with it. In the other case, \textit{G. olivacea} is not included in the tree anymore. The approach you choose depends on the goal of your analysis. You can summarize the new object with the function \code{summary}. It breaks down the statistics about the traits based on whether it is associated with the tips for the internal nodes: <>= summary(g2) @ Or use \code{tdata()} to extract the data (i.e., \code{tdata(g2)}). By default, \code{tdata()} will retrieve tip data, but you can also get internal node data only (\code{tdata(tree, "internal")}) or --- if the tip and node data have the same format --- all the data combined (\code{tdata(tree, "allnode")}). If you want to plot the data (e.g. for checking the input), \code{plot(tdata(g2))} will create the default plot for the data --- in this case, since it is a data frame [\textbf{this may change in future versions but should remain transparent}] this will be a \code{pairs} plot of the data. \section{Subsetting} The \code{subset} command offers a variety of ways of extracting portions of a \code{phylo4} or \code{phylo4d} tree, keeping any tip/node data consistent. \begin{description} \item[tips.include]{give a vector of tips (names or numbers) to retain} \item[tips.exclude]{give a vector of tips (names or numbers) to drop} \item[mrca]{give a vector of node or tip names or numbers; extract the clade containing these taxa} \item[node.subtree]{give a node (name or number); extract the subtree starting from this node} \end{description} Different ways to extract the \emph{fuliginosa}-\emph{scandens} clade: <>= subset(g2, tips.include=c("fuliginosa", "fortis", "magnirostris", "conirostris", "scandens")) subset(g2, node.subtree=21) subset(g2, mrca=c("scandens", "fortis")) @ One could drop the clade by doing <>= subset(g2, tips.exclude=c("fuliginosa", "fortis", "magnirostris", "conirostris", "scandens")) subset(g2, tips.exclude=names(descendants(g2, MRCA(g2, c("difficilis", "fortis"))))) @ % This isn't implemented yet % Another approach is to pick the subtree graphically, by plotting the tree and % using \code{identify}, which returns the identify of the node you click on % with the mouse. % % <>= % plot(g1) % n1 <- identify(g1) % subset(g2,node.subtree=n1) % @ \section{Tree-walking} \code{phylobase} provides many functions that allows users to explore relationships between nodes on a tree (tree-walking and tree traversal). Most functions work by specifying the \code{phylo4} (or \code{phylo4d}) object as the first argument, the node numbers/labels as the second argument (followed by some additional arguments). \code{getNode} allows you to find a node based on its node number or its label. It returns a vector with node numbers as values and labels as names: <>= data(geospiza) getNode(geospiza, 10) getNode(geospiza, "pauper") @ If no node is specified, they are all returned, and if a node can't be found it's returned as a \verb+NA+. It is possible to control what happens when a node can't be found: <>= getNode(geospiza) getNode(geospiza, 10:14) getNode(geospiza, "melanogaster", missing="OK") # no warning getNode(geospiza, "melanogaster", missing="warn") # warning! @ \code{children} and \code{ancestor} give the immediate neighboring nodes: <>= children(geospiza, 16) ancestor(geospiza, 16) @ while \code{descendants} and \code{ancestors} can traverse the tree up to the tips or root respectively: <>= descendants(geospiza, 16) # by default returns only the tips descendants(geospiza, "all") # also include the internal nodes ancestors(geospiza, 20) ancestors(geospiza, 20, "ALL") # uppercase ALL includes self @ \code{siblings} returns the other node(s) associated with the same ancestor: <>= siblings(geospiza, 20) siblings(geospiza, 20, include.self=TRUE) @ \code{MRCA} returns the most common recent ancestor for a set of tips, and shortest path returns the nodes connecting 2 nodes: <>= MRCA(geospiza, 1:6) shortestPath(geospiza, 4, "pauper") @ \section{multiPhylo4 classes} \code{multiPhylo4} classes are not yet implemented but will be coming soon. \section{Examples} \subsection{Constructing a Brownian motion trait simulator} This section will describe a way of constructing a simulator that generates trait values for extant species (tips) given a tree with branch lengths, assuming a model of Brownian motion. We can use \code{as(tree,"phylo4vcov")} to coerce the tree into a variance-covariance matrix form, and then use \code{mvrnorm} from the \code{MASS} package to generate a set of multivariate normally distributed values for the tips. (A benefit of this approach is that we can very quickly generate a very large number of replicates.) This example illustrates a common feature of working with \code{phylobase} --- combining tools from several different packages to operate on phylogenetic trees with data. We start with a randomly generated tree using \code{rcoal()} from \code{ape} to generate the tree topology and branch lengths: <>= set.seed(1001) tree <- as(rcoal(12), "phylo4") @ Next we generate the phylogenetic variance-covariance matrix (by coercing the tree to a \code{phylo4vcov} object) and pick a single set of normally distributed traits (using \code{MASS:mvrnorm} to pick a multivariate normal deviate with a variance-covariance matrix that matches the structure of the tree). <>= vmat <- as(tree, "phylo4vcov") vmat <- cov2cor(vmat) library(MASS) trvec <- mvrnorm(1, mu=rep(0, 12), Sigma=vmat) @ The last step (easy) is to convert the \code{phylo4vcov} object back to a \code{phylo4d} object: <>= treed <- phylo4d(tree, tip.data=as.data.frame(trvec)) plot(treed) @ % \subsubsection{The hard way} % <>= % ## add node labels so we can match to data % nodeLabels(tree) <- as.character(nodeId(tree, "internal")) % ## ordering will make sure that we have ancestor value % ## defined before descendant % tree <- reorder(tree, "preorder") % edgemat <- edges(tree) % ## set aside space for values % nodevals <- numeric(nrow(edgemat)) % ## label data in edge matrix order % names(nodevals) <- labels(tree, "all")[nodeId(tree, "all")] % ## variance is proportional to edge length; drop first % ## element of edge length, which is NA % dvals <- rnorm(nrow(edgemat) - 1, sd=edgeLength(tree)[-1]^2) % ## indexing: ind[node number] gives position in edge matrix % ind <- order(nodeId(tree, "all")) % for (i in 2:nrow(edgemat)) { % ## value of ancestor node plus change % nodevals[i] <- nodevals[ind[edgemat[i, 1]]] + dvals[i - 1] % } % nodevals <- data.frame(nodevals) % treed2 <- phylo4d(tree, all.data=nodevals) % @ % ======================================== % = Table of commands, worth the effort? = % ======================================== % \begin{tabular}{>{\tt}ll} % \hline % \rm Method & Description\\ % \hline % tdata & Retrieve tip data\\ % plot & plot tree with data if present\\ % \hline % \end{tabular} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Appendices %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \appendix \section{Definitions/slots} This section details the internal structure of the \code{phylo4}, \code{multiphylo4} (coming soon!), \code{phylo4d}, and \code{multiphylo4d} (coming soon!) classes. The basic building blocks of these classes are the \code{phylo4} object and a dataframe. The \code{phylo4} tree format is largely similar to the one used by \code{phylo} class in the package \code{ape}\footnote{\url{http://ape.mpl.ird.fr/}}. We use ``edge'' for ancestor-descendant relationships in the phylogeny (sometimes called ``branches'') and ``edge lengths'' for their lengths (``branch lengths''). Most generally, ``nodes'' are all species in the tree; species with descendants are ``internal nodes'' (we often refer to these just as ``nodes'', meaning clear from context); ``tips'' are species with no descendants. The ``root node'' is the node with no ancestor (if one exists). \subsection{phylo4} Like \code{phylo}, the main components of the \code{phylo4} class are: \begin{description} \item[edge]{a 2-column matrix of integers, with $N$ rows for a rooted tree or $N-1$ rows for an unrooted tree and column names \code{ancestor} and \code{descendant}. Each row contains information on one edge in the tree. See below for further constraints on the edge matrix.} \item[edge.length]{numeric list of edge lengths (length $N$ (rooted) or $N-1$ (unrooted) or empty (length 0))} \item[tip.label]{character vector of tip labels (required), with length=\# of tips. Tip labels need not be unique, but data-tree matching with non-unique labels will cause an error} \item[node.label]{character vector of node labels, length=\# of internal nodes or 0 (if empty). Node labels need not be unique, but data-tree matching with non-unique labels will cause an error} \item[order]{character: ``preorder'', ``postorder'', or ``unknown'' (default), describing the order of rows in the edge matrix. , ``pruningwise'' and ``cladewise'' are accepted for compatibility with \code{ape}} \end{description} The edge matrix must not contain \code{NA}s, with the exception of the root node, which has an \code{NA} for \code{ancestor}. \code{phylobase} does not enforce an order on the rows of the edge matrix, but it stores information on the current ordering in the \code{@order} slot --- current allowable values are ``unknown'' (the default), ``preorder'' (equivalent to ``cladewise'' in \code{ape}) or ``postorder'' \footnote{see \url{http://en.wikipedia.org/wiki/Tree_traversal} for more information on orderings. (\code{ape}'s ``pruningwise'' is ``bottom-up'' ordering).}. The basic criteria for the edge matrix are similar to those of \code{ape}, as documented it's tree specification\footnote{\url{ape.mpl.ird.fr/misc/FormatTreeR_28July2008.pdf}}. This is a modified version of those rules, for a tree with $n$ tips and $m$ internal nodes: \begin{itemize} \item Tips (no descendants) are coded $1,\ldots, n$, and internal nodes ($\ge 1$ descendant) are coded $n + 1, \ldots , n + m$ ($n + 1$ is the root). Both series are numbered with no gaps. \item The first (ancestor) column has only values $> n$ (internal nodes): thus, values $\le n$ (tips) appear only in the second (descendant) column) \item all internal nodes [not including the root] must appear in the first (ancestor) column at least once [unlike \code{ape}, which nominally requires each internal node to have at least two descendants (although it doesn't absolutely prohibit them and has a \code{collapse.singles} function to get rid of them), \code{phylobase} does allow these ``singleton nodes'' and has a method \code{hasSingle} for detecting them]. Singleton nodes can be useful as a way of representing changes along a lineage; they are used this way in the \code{ouch} package. \item the number of occurrences of a node in the first column is related to the nature of the node: once if it is a singleton, twice if it is dichotomous (i.e., of degree 3 [counting ancestor as well as descendants]), three times if it is trichotomous (degree 4), and so on. \end{itemize} \code{phylobase} does not technically prohibit reticulations (nodes or tips that appear more than once in the descendant column), but they will probably break most of the methods. Disconnected trees, cycles, and other exotica are not tested for, but will certainly break the methods. We have defined basic methods for \code{phylo4}:\code{show}, \code{print}, and a variety of accessor functions (see help files). \code{summary} does not seem to be terribly useful in the context of a ``raw'' tree, because there is not much to compute. \subsection{phylo4d} The \code{phylo4d} class extends \code{phylo4} with data. Tip data, and (internal) node data are stored separately, but can be retrieved together or separately with \code{tdata(x,"tip")}, \code{tdata(x,"internal")} or \code{tdata(x,"all")}. There is no separate slot for edge data, but these can be stored as node data associated with the descendant node. % \subsection{multiphylo4} \end{document} phylobase/inst/doc/phylobase.pdf0000644000176200001440000061467513076473202016472 0ustar liggesusers%PDF-1.5 %ÐÔÅØ 3 0 obj << /Length 1719 /Filter /FlateDecode >> stream xÚÕXKÛ6¾çWøTH@¬ˆQÒ1›&E š zHzàÚÜ5±z’¼îæ×w”VòjÛKS “r†Ã™orº¹Û¤›Ÿ^¥/ŒWׯÞ|ÙF䉙Þ\ßnD‘&²Ì6F§I™i¿ù]\üÇõ/pÖÌÏ*™èÑ™ãá±ju8¶™‰ÊÆcŸt¼U©Œv•í{×óÂ6{œˆ¨vá·2ö}•o„HÊ,“(j[ÊD*³ÙÊ")JÉ"¯\ÜÒDWmu¯ë^3á#­×ñò]‹ë3þØÀòyô!.dÔÙækªÒX«,Úµ¾ç¿ú2Ú¦qö„JmJ‘¤yJ¨D댕x{ì|ÅR¼f©29¿BÂ+t¢´áWS&F›­–`ä’%¼k›X‰hp<„÷ËbS&¥‘S¸Œ6!ƒ=²èg`Ñеxk´?í¢PQš$“í·#•e¼'YÖGewø{Ù;R µHzÀ×=xwFé\ÊL— ûÜûæÙU4‚ò?®:ò¬ìWƒÓÎ^§YÞu\š¨s„uŽEäã-ØêО¶·ƒQež¦ ÅЍìŸDÍå(¡ŒˆŠ59†å|:ÝônðlpˆžÂLOG‹3yá½|©ÉöL¦¯îÙfRê<bíê‚k<ªÿñ€3Š>zÌZ²(J²j‡’…¼ÿÓÖÇÊõ«Ú+†àpA8–€aŠÊ ,(ŠTJq?tAz…á ¢+€§,¢sã)ô€R·„S:4tÖLî}O•ZˆÛ^ÄÛ üù]–/íÁó§\¹ù²-… F™¨º…(/µ^šúm¼5Ñ?º¯©ÐÇW÷oúª(ûi¡#¡Ÿ[z”4·ó[´sžKH¶h#vyý¾úþÃßøàßÖ<©—ÔôÒÖòÒÖP¤rˆ¯ÿBßÿ§[Ö¬œ]ÆËE) 0‡^¢ÔfªkB„Â&Baó¶ŒÎl…c³‚¥[(…ØJÑîTCM…É€dÈí®ßuþ†ö\8Jõ ' ”6.¼å"³Dš|­×™k¢TR–fÞê È§| —S«ƒÔ±Õ) Õy-‰Î‡Ðkð ÛẎé”ã–=°p ÁP^‹Jå%¦Ó]uÚsÂ/!²ûsFŸnƤ «¯i–rµ¨`¡˜z;¸=Ÿ8\Ódæ#eý’Ñœ‚W| °¦– ~~/‰oöOì‹—„Äv„v9|S¤Ù,$+UÿÁrQ«_, â)Ì‚×Ó)ï½ ™HD1…$pJÞðõº¤y’çæYâ;ÀÓ£ ÜÖa†˜K eTú°M±Âê>b§ :ÄÑ]gkܨ=,T)¡úÅø Õv”ÔØVP"Ðó2‡¢fˆ&óf…)˜Î%øqOßt d.θí.pM"ÉÌ5A—úGýÇwØDð «5_\tb£wg]æò£Ì°E M&¤K•Íþ ™8Þ_¿ú ¼>·¥ endstream endobj 16 0 obj << /Length 3137 /Filter /FlateDecode >> stream xÚ½ZI“£È¾Ï¯¨ð ELÑ$™0—‰qŒÛŸ&¦ËáƒÇ Rn2 Züëý¶dQ¡êöz¹‘ùÖï½—(º;ÜEw¿ÿ&’ço¾ùð1»ËÃ<Ó»‡ýŠ¢P›ô.ÍâÐ{÷PÝý%¨ÜÓ.Î×tçÝ=6úá×(Q»{£²àèw}øã‡q¾ØÍf¡J4œDÛœ¯M÷X ²ryl¢ÂXç~ásÝ4¼yÑ ·öEY7õXŒŽûeG§VÒ}Ú% ¬®«b¬»–Ç‘èWnŸû{OuU·Ù›½cú»¡»^–ﻉ¼»Wqê<†† ó$aú™á¶Ä-§¢ÿ oåI0ºa¾ÝÝ'hi+4Á©ëO\ëú¢i^yb<#OÔò¾aîèš3•ÅX4¯ÿ-ÊîtÂC/-¼#ÜÁðBA'×bSvìöÄF´¦v9=HŠßÚÝk tºñˆ2µA5ðHÝâS¿„´‰2anÌz§P\‘ç1ʃâqû¢ý8ž‘¤Á¤•ˆDKKD£NÞZÊuh£üëÌgagϸm1ðqcǧÕ'2xž‰./cUºW|Þ©@¬$"=’%ÄIfQ*ü§|”g—¸ÓiŒ‡§å:iôÎñ†­=Ðõ§bUn±ž&¡UökXÂÔ&~aY´|,1BüdÀ:áX4¹%1Š •æÒAÆz¡¹ö³²Ïó’Pé[Ÿ@c1‘fƱâöhÁûb8‚œÀ?L,Çʺѕ( ì]nN+6àGv컓¬-Ke]‹[ìäj0Ý»®¯\ÏJ…~×:"# /ã–‡´Zpd=;6è Õ‡»û4µÁO2)è­Á¹Ïƒ¼ACÙÒ–ûˆÉAkO&À‹ý>‚ ÐBOïZfÀ¢X*^Y·è@*8!—àVhJí €Ðùšÿs/ÅéÜ Ó¨ÞǾìâÙÆµ‡QÚ´ÿIüx‹D,}¹-çüÎdð8ÊÀ•±./ šš¬h=RsÌÀ!6Sh<àøKØx+»âæ¹t]ÁN:øÜ˜?7®:82DN•ظ´ ðæ•TŽ}–;.µ\ÊñÒ³©àŠª]â‰s<*{µ¡GÆ¡zà' Õ‚³…ŒüöõË·[œàXøÑÔÈjQæzD)X~tC=Ü£ÿW<Å*By‚EG$ §ü³`×è; a|o<öÝåpä%êr~tŒ›¯ƒ•úuûKKP80Nh‡J™5b>ëÉô²ìºÛ;››ÂR–‰Ùe¦ÇQÞ8œØQÁÒbaŒaaõ²À yí»\ëá('ù¨vª â¾Hæ¯]„Ì ®‚€Ñç‰ó€cu3Öà{ßÁqÚ’­)ò’¥Ž–¨¯ãÐd“ØÝ./jPƒþô~Âc„6Æã ô4 ¢*Ú‘G–ýF*KÂ(Šý‘Ou!,0C°ÁC^»¢\eÖô*±(0Ñ€«ÈæÈF `¿—Ђ€ËÉÁ tï±ÉVoâ=®ÅB«qEß’oc¯rcQ7ri 1ÉiÜ‹¬`ýÃô¬Tz^¬‰Úø†R®”½gO?… $cMÀ³;õ©¦„ z÷Élx¬>£ ™ˆbcñ+¸?ÁvýÑ—?s,Kr´H;ˆ¾U°Žm˜GS‚ð‡‚Ó`zÛÄÞnô @¹òÒšóÉ»!µŒ˜ö\ç¦(7I0õ«Ò<¢H~Ãs‚ô#¢%hε¼šI€%"+š•Ä3’L/ÖÂÔÈ-Ô÷j ŠC_œ¶ß©hˆs¬.0NQVøŒøÛéežÇc±!Áæ'Êdb+ñÆ >1éDÆKçd¯¡;¹g óØ«!L‰•CkÊZ ¢²k‚§%'>ñlF×·‹>‰ûñYJ/ÃÏ}=Ž(mìpúƒk˱exWò¬WA¾P4`)˜iÈ ÐÆîI¤Ê“ä$\Aº™ößPÌB¬bîï—šµO=ä€þ ¨çÑN$VûÏ…d¼'4˜¬JEXƒÎÞíI ´Å Bw{˜ñD×qïXc¬$ì•ýðJ11ƒ´Z„a·Cðð/±„ê©,£Òo@5é–!³2yÃó[µ Â4Ë×âúd¸æî/áè¿qe„#S(ÀÒKÔ–‹£ –Ls8Ôœã ßXî¯Ý.ë)'Šó8˜å½ÒŒQa–¬5c6B ã|.M›bxWJ !ÑöÀéJÅ3˜Aásôˆq]—Ç* ÓduþÛãã<ŒR³uü–±±*ò â¼af* Ó\Íf¶a±a”¬ï+Lµ!—aìÓûTðSË늪ª9»ÆCüÉ•ʾ~”»£»ûL“ôW†<ùQ>¹±–Ûlø{/°C uìIµxÏS}hÝ8Ê&!R&¥¨– ½£¹6å%pþ«ƒ¡Dꘘ _MHRys²èÚ€)rî %A†@ÜÄ@¿Š“àç ~?ïRÍ¥mÐCOøãú§°è:#¼¾ ³X-`áˆ`òÊùÐ=¦kŠjZøב•¤zéû9i¡!*(‚È0\!Ó¾kZÍ‘ýEb¹ÒŒ„:m¡î;diº¾þðÊË…Ó”‡FçþDÙ«w–òÈ—nö£¨W (‘Hµ¹æšB\O 4¡\÷Íl\»€_Äœ\¹dœBÅ©¯ðI;Çñ’‡P¯äçÛ%6Lô´Ý÷ïI¦ïþòÐjý¯Ëø‡›ºõ&òޤgéb4œ¦0K’4›¯)yq}¾2¨vN= [ZÐD³…ã·Å‚Iy±˜ÿ—XNèKoMk-"Ì8dvpã¬2º% ¨yÂÄævôDðžùòqG—xK`˜dл¢šdк—‹x)æo׌KÝÄb rAeðâóGE—ãoðæ]&™àÛ®XÈ’êLg]gwíLe/5 ,’‹ª‘ãÌTJë\ê"or‰ãRßé|]bã›(ç*Ôz•ÝCîr+å‚2ª$¿Úç°þNž/ùñ,AhâÐÚìꦗó€†5ÁKß\O¾O™]Q9ŸÛ"U‡ ² ™2É»dáëX;A]}”Òeàj Hz!Éûd»ŒôPÆ÷®ôèC)ŒJ-?Rßó…ÙM‹ð‡àÿ?r‡YÔT-x 0o®^Þˆ“?\:æ—§7z‡×?0þEΖ¾ò_æëÜtãûŒ-ÆæÀáï"®“®û҈ȮS/-©×Ÿ>Èú"Ð Ò žüÑ[Ã+ô§¯Ê¾6#·?f~ÚØ 3ÝÉÍøØ8øX4é÷É•º¿LÅ©ÂËܺ)zÌÔp–òhùT¹A”i6yþ'}ƒŒdƒ $áu§¸‚`jHòÓ‚îä¤w¢[c$…®´ëñ2dàÙÞïñWœ”n¹vÎ „—«ÛgŸyoÀXšÈ~A¤fΖ5\ò_î/Ó¨B‰oiÑhþ|ö‰5_Ë\Xó§–é’o>´àîA.˜2“"Dn ÿ|tòê³ >¾Î¸ý7 •e¡² ß#Á›õ´šËVÙŸ´aðO#¹½ú*B0¥ÿî>œ­x‚â8ÐbŸößKq¤rû’Ùjötü€ ûMâÂåǤoö¦êrØŒmÐÖC/o9ÎÂ8ûrš­æÏ'¯±'Œõî Ô|=ÿË6s¦/Îk©²áªØÚ ª•xËûé¯§Ú ;U=œ‹Ñ‹,ç(&ÔÏåëÚ¢¬72ú ÏYGØóö,þÂýbß/˜Vï›·3à%Ùœ’1‰Âèx¿ : ¨L…‰‰…gYækíå¢ß=|óO9ε endstream endobj 20 0 obj << /Length 2472 /Filter /FlateDecode >> stream xÚí[mÛ6þ¾¿Bh?DÖŒø"J îäp— ôÃ¥ mQpmzí®,¹’œíîÇß ‡’%YÛ6FífƒÁjøbr8œ·‡d¢à.ˆ‚¯®"ÿýÛÍÕË·i±L ܬEL*èT°D%ÁÍ2ø.ü>Š#3ûáæë—oEÖï,Xš¦0ëõ­¤.ƒáS™l{,rS׳¹Šâ°¼Íã8üÉ.O §,åÝàïŽÇΘТm·ïg±M¾7õS4kKDÚ~Õ¡Íñ¡ÔbŠ%µ|qU,‡c©p1›ó°¬ª-’íÏVûbÑlÊ¢¾†²a]¶?t=ù`žÅLiÌ9gYß«2ÏË™HÇMq7›K)Ç™H`ŠûšŠ ˜ ¸Ëg© Žt…[ÁàSÝSÕï`¯Ab–{×û¸úƒ{ÿãæêç+›<È&ã4Бf WÁb{…õŠ',A ¿ItPÙ`uõ¯æéÃÖ{ÎÞ‰L°Kü›iê;®|ç-kh-­i)H*hÿóÍmeªÇ“¶‰þß®oÿ/ôl-xg[S;Ûªa¿ê]Û†ÕÖ./±¾“æÐ©†bgð7n•p\Isð ,â´9t’"§©ò¼Ó"F•Ðóå[É{ ©–eqëA¿ü<¡ˆqˈ¨À–Ûy±ßÞÚªm;óVŽLfîY$ÒÄ(òõcSY{š¬²cEÕ¹ÝpëýËü¼ÖB³T‹Ò䟄…DŸš‰p1‘¥cùÆÜ[¢LßVˆvªé¨‡ „Gd¨m³«ÏªRcj0ðÊ»¼l.¡o¥ž¼mgÌ||”¯fJs¡˜H%I럔ŸaVY&¶‚$O¤œO@’+ºNu³ÉsZgacîÝT5÷þÛ”øM)ÅŠ¥]™}ÞL%ç\ƒR'íØOÌ/Yœuó¯m¾c”¿þ{–ªÐϱ6ÈÊ{'?}éÙÁ†ÇJƒ’ܘf| ¶[?BÆ{ÄÉ\Æ ó(j*N$3å“q¢Ö¦ñ”ѦòD޼A}O 5Ô¬Ê Vó„7ëMMuí÷–x_˜}=µÁ3ÆuöG¦]½³…­6‹zÄT½Ùî ƒ'vZ¨àᜄë.i£@ %ìN¬†qøqS)U o°®0[K”Y.íÒ¡…N§û£Ü¬'W .=9à95±X ‹­$\×uc·D£pñëÔ$ K*-JÁfmÙkÆÛzQmüNPÕÚVŒLF<¼Ý7¾fëâ…¯Ù‹|¿ô?!“@NœD_’*e*Ã4¢(ƒÛ€ ¯Tø¦&i’_eëi³Ê‹£dB¥'¤¥5‹ª1äß#½‘ÞõÄ<š³\úÓð7Ý#σv¸Wãá§£«ÍÝ'ô“#ç ”ÐÏëåsÀ˜2KY$âÆäàN5DóÏ 3ˆÁû§ÑåA¦3…[SŸòÆØÃ“ÇY€L–ÌÓ.+C+AÏ6W{Ó4f±vŠŽÅYÜ›;ûj6çÀnø¢cøÅÆíSœ Óu„;ôyèX*oéø itøÝšúý¤ë^µ©å‹–{Àò/^=±ê'd!@5B»¼³õÉzp®Þ¿79wË5Þ…{¹.Êâ½­z¨õÇC Ž1¦—§{OÝûáìhW«;õIaYS_X\Ÿ4Ï p2•¡j¥ÔsXuXϤ1_|´ÀöÔ“¹‹b@¯äϾÁKqŸ`Y¢MyÓ’è»C¶›†K¼‚²Wl]{é è•ðÛ˜nX7”À1 ›!¤i(9.ÛÁ ñ"ü½N^YãW@í+w %wãSv#§$U¹S—ivñp ¢inùXÚ4’wØæõÄD©`Jf¿žÑ°ðÚÔ4dÓ¡ï’*ŠÍŠp' B}lá;v èMƒpBŠ6QkU7¾yôÓ¯½ÛûN†>?ïmk¤ÒÖT÷~ŒÂ_ó *ŽN\ „½Ü7…Òs×ÖeîÉlî«ç‚ È0…§à1ãüs®Ð5@(ª½@â5þùhOy˜ÿÓ"ÇG=&Ƥ‡Keçis/ÜE¯¡;ÕÒ­‡¢=ØÒ9 ß6qÔ¥L‰îšç50[+e`·Q¼¢Ù~÷C,¡ík·½iðàznɸ;äɃoÁˆU\Ä °)QÜÇ51¥N™ø¦L8SZ §lóæÑ‘¦‚0ÒQÞ`Huæþ ʼn§¬‰;eÅâÞ]pÒö§'¸tñUwñc­])‡úuĸ’Û–Ž£¢l,A5À.1Ó㣸†Î$SØäÂ… Úƒ!ßàŽ'¢Ä!`N×A­²ÐáO‡· 5ÚƒÚ,"tгÕÕ²ÇÈ!¸BMËì„è¹Ý¬èûè¸ÞSÁä‘´=î‹6ûÁRÓÎÔ*xêœD„ªÜÝøyù+ š½§#×>œúâ¶h)ž+wöH‡±½ÊÞY-Ô®h.7°…ÒVö0?dµõsÌ"-ãéçÀ<˜…„'øŸ˜·¶Y—ËëKÀðKÅè3Âï‹BïgL¿)ѳ‰D/¶5„N°¢±Ü¢Ð©·|šiÍãòÇíÓà:c±ßzGÙ›¶¿D¤ñõ‡;ž¯åöfˆoúÒÎTH×T³3 ô~®ßÜÑÁD Hj’,ÞìÜvèP…¢è¢èî9:Ä5ñðnǬˆè€-þ,žÚñL3 ÍŸ]ý´«8‹q¸Ü~î.“øï¥3927¬8÷¢N X`Px­ÝvM}G•½€Eç^Ë_ϰ(À×ïañ%¢•HÜ“Dktå¡bÀÞ8XŽWa³ |³uÀ+¡‡R.Faais|èίKÜþƒ¯¡Ö>¾ Q7ïd÷öJÒÕìže!õ?_ï~¤ûx‚Øí»ñ©gª*ŸxÐ"²þÛºÃs|LBx±XuOÌnØò”žÒÂ! îDz;vM # j–Ô¸ñ2Ú×þ½R€o$+'c<:yÄ0w¨¡óç2ÑáýþàíØEÜ-°ÕäQÆ,ì/ûúW<¨èÒ`g»ç1„× ÿr myH¸ñˆŽP übŠ3© pdƒžHˆ Wɧá5½¿™K>o„úß:ýõˆÓþb¶»Üú%ä¥Û²~²R™^Ú&£Á+¯„ŲKʾ²³–]ï6ÿ°!%À.;£„gÛC/‘²ÿ?h:þ77¨> stream xÚíXmoÛ6þž_!¸û µÂW‘† ݰ(†¢[óeh‹±iG›"y’œ,ûõ;¾É±¥d²g 0Eêüðîx|ŽG”PÆ£ÝoêÕnß7?ÿp†"øA{Ø¿’,ÍLÿ^c¥ûÃKÿq†A#á( å2J±HæÑüúÌŒ3è  œpÕ:Zžýt°>‡ÙzJiA…érjžYêd÷AòÛ‹³ó×$‹20‚¤ÑÅ2ÂÈÀ¤Q*d"±ˆ.ч¸È/kUßM?]¼9JñûÏNöþ$ašˆ£õÕ]Q]ªFC5áXÛaÑg'çÎÈ…jÕSX¸ÒU³ÎÿR¿Öêöh#ay Ë%ƒg*½‘ûƒ yþšâ{«»gò‹Ó'<¾½R­{[Tºqo¹™We«òò›“®Å^î©YªkÐê¹,Íé¤_øËÝåû€?¹—I[k=ñï&ž'Þ‚ò˜gúó×ò>‹°$c ´¥‰€Öjû]UN‰ŒoÌC×]”²¸½ÒFŽõç~à°Ý«"¿QsÝ)¶Þ†—”Hˆ‘Kÿbœ Þ¾ú:@rïdePüö•ºªÚG•LÐÒ¾‚$ƒã¿g¢¼lu]ªâQ\1€+úþD,#áÊ\Ù”Jž‚› àfýhÅY‡èkhi—„p7\'ÌÇp÷¢À°h÷¹¶­Ù]ãõ%¸¤OÝeÆÛãqé.íç$ìþËpY?/ú„;w`—Þ_7˜8$ÎÈÀ~#é@¾á8‡ÄÃÀ~#b€Æñ°þË«?µpqåËS.ä唈Øéh­öKY12^˜ë-ÓWëµЪv·¹9 š78=ºOE3PÓc‘B+B©n÷弇›«M£»ë‚;QQë  ¿UXè³R/žCõ™¹ª{Õ?¨ÿ¯Ñ±4»Î×'¦ÄøÑ”&OS6Ö%›èOÂÁ"Bâ‰6$ÆÈBâ ‰"{ â@œžè¡Wsî9qû¥7ú—©¤qµqdÅ–çâñW§µ†šN»kÚíå¦ýdITÄ ßuD),QÚË¡”)Ó$•Ý}®­Î¢/'!L†/F1ÊIeø¯JìRÎH–&ˆxgE_9›üz]x-o%Ê<<åº;b0¹iòUù¸‰öÊzsmžžÅë@šœ` ¢_n '¸¬|†¹™r|ŸW17°WÚ6¿›ò!Þæ«ü(ŽðA— žšQLå}ÃŽ@ÎÿÍnus endstream endobj 27 0 obj << /Length 1522 /Filter /FlateDecode >> stream xÚíYKoã6¾çWÚ‹ Ä\ñ¡×¢½,Ð-ZtÙ—¢í±i›¨,©z$ñ¢?¾CeËN$.ìu€½hÈáh83$çãH!á"ò¼pHêÅnß‘_¼ =ò€¾ì-’ř鈕~Ì~±ôßW, =êe áQêEIc±7]]¾  I˜GÔ$(RÞüêó‹-z™·§”Nxbº7Ï,FÙ}&H¾Ÿ\½ýÀ2σÅÞd!0jb/NR’Òě̼߃¢œ©_ä­Ê›ÑŸ“Ÿ²}øÜÈŸ 3ýFá‚“5¬Ä#·÷xvžqÄ¢à»ñQs<7¶n–J6­:GØŽšƒf º"ðLQr—…úýOþ©]¸>Çb˜üÓì<›øú„ bñuѪº¹‡Žt‡s³qlÚ(»ÇܺԨêÔ¾|Òsr–¥8íI ½1¥$‹"ÌýK%/úÀÄi Ý02Y>êzŸ¹ÝaÑÅ.Ðé¤Í’2XRšâ’¾y32±ƒÜ`úh“±%‹©jڲƞš-ÉU±h—[AÒ®+‹iû›ÅièhL£$ æ]®º(9 ÂÐ ð˜F ’f•¢0tìVWO©eNl^Ö­nœJö¿Tr$+¹(t]6m½ÑË{½|£—ÿ™zÁ »:˜–ûzE¯—mõ¦Ÿ§7r/5SYÌTÑ+z¥t«4ƒ%ÞUzÚ­»õ¿ýï“‚dBÀþ‹enÿM–vóìÝ<˜ÌÌ5ÝÊ4Ýj%ë5Ê òŒÀÎêÅVª]–àrÌà™%ÁBß §L`²4ÈÍuÛæ Yê¡­[°“V²Õeq ‘ p¦y7ÓÅeA`D˜€54V¦â†W Ò$h—NýL›Å‰ÛÎÞ/½q"H,ÜjÆh¶™&ä<(熊ඖ¼4±$X➺æÝQÙätµÔ“Çå‡r*j¯œŠáPd}+§¼ˆ Âø£­}Á¥Ôà(Ù¤¶a‹· ÏfЛå:/ªP­žblkå°ê’=2$R«÷S·ºUåÌ)´šuÕgT§šŠ+1Ù8ìµð'µ¼‡Ã?uø:<õÿõ‚H \)ÈØt3@òLb†é¡XZá;Ykƒï$6ï†"fñ““bf»í0yaøÈÛ~Ôqî7-6>wĹüQÍ´ñ%­;ŽëÙ@åy ÁúöÒÖ•,6Ôö @}‡ÑŒn:i ‚_ œ®ÝÔº0(Ö"ô¶ ÷5J˜1€D¯˜ÈH˜íhËb’†â0ÄçÉ ’tׂêU|f;o©’ðÈ–2G¹£ÂÑè`‚5iØß"¾»ûXDø˜üaà»å.ï¾K™~ñöMh͉MMÍFã851|ÚÞ™žÏõTçvbN1•Ìs=“C*Yßuyg­µïT Ürå´Ë·>V²«TíÂ4…ö Ö7xßO[y“ËvÝTú‹™Q0HÖhPÔ]ȺÌË-·,s}'§JúT‘ôßO÷)'é¶Ô°Årã>UøpTýþüìêO¤¸ëÞäñ²Ëg˜Ê%fî{8XÿEzMÞ83hDwþÛ(…B¡3 T*Mcåê=_#Ñ!Et0 ب¦Á‚ª“Úñš …¦­“²P[Ái¼^Ö?Hæe#êA®ª\ÙZ Jž¹pJŒXwÕ­›'϶¥zlžuµ_ˆ¡«­‹L^šBèU"k*õ®„…k!Bé7À‹=šR"ÂèuÞþWj!¯ÞÃÙ¸Ô?KÏwçkì‚£wÂ% ÕX, ûZpaqdÀ¥ÄÖ6©Fåñ•¤âkSP@‹,ˆpf3𮊠ÖÈÃ\» P¿.pÁ¥„›‰ ò(E G–Á‘šå¸_BU¯,cÂRV³Ü7³$œ ŽiqФ²È×DvÑà­nÝ·µ®WYXqÕ•j[U„§GáŒ[?…œpƒá1'"¦èÄ1ÿ]þ 30m endstream endobj 30 0 obj << /Length 1601 /Filter /FlateDecode >> stream xÚíZßoÛ6~Ï_¡¥/60ªâO‰C·¡ÃÚ¡CQlE†aHú ØJlÔ±=ÙÙšaü޼£Ä(vZ³ãyÑ©3yGù}:9K¥ÒI’Å¢¾¼Ý&ñþ§£,[ ÈÍ~•Zc];Þún÷ÆÖqð(KxbóTê"1¹L ×ÉàêÈõ+ž§¹H¸N9Oê*¹8úuc6‹u—Ö¹Ì]SKwµm»`ùÃÉÑó×Â&‚&9¹Hxæ†1°)—7‹ùøŸòø0øËñOãx>ž–õl2û4.ÇûHä­æØ!”Ø?]Ä@¢R«TÂO­´ˆ#ïf˪Ϥ”½å¨\:Mõ.f5v•(.ÇõEÑ;Þ›’q]Uþ1v± 0Û*Ø%8ú|t3™—‹ Mcg´ÛB*–“¿Ý¥»Ü,кZ^×a¾Qµb¶Ü¦Zê0Æ-H¼o²q4¨ŸiQ^Ñ"ÌêaU§nX&[¤"O‡åÒúK ?—h>õ´†4Ž¿u}å®çþFU/ÐÐmß0m5¼$û«rY?E3»Túf¹´‰õ«“»LMðBv˜šÊSmíUª&T*´Æœ™Î†Õ›á~xÚvG+䟃Pã#m;íñº¼™W»çÛ]‚ÝYÆu9™8q°à°;kذ«ijgp°CöôN¡ÆI ’’¤"©I’9É‚¤í#‰ÌHr’¢È%JER“4$s’IOÐx‚Æ4žðdÕÅŸÕ..w÷T¨dGó šOÐ|"§Gô`ˆ ô;¸ý#bJEÈ1&Pyl @ìïL¨BÆ3”ªw^—Ó3aÿ¤š^.G‹ï°™*Ñ©SËô,‰V6嚸ۨ\¼.ñÖ?ÞýÕõ8+:ÛžÓ®?yÿÛ«Úßoˆ;Ã>ÿªÏ”ҽ߉ãâ§7¸£'}ÞCóÙGêôGÁcØÔ*ãÀ LgS[lñiO›D™ÎBöVOz%?ѹ£ Ì1Ô s,õœ9¦€zÁ[@Ý2Ǽ.2æXêœ9怺`B]2`÷0‰,6W*42eEÛ0…¶¡Á¥Êš;<ƒ§Ü˜I­³¦‘Ù@u ‘Þo`•ÝrE·®Èà2Œ·ªªd2¨‚© r¦IÍ*,‰‰VªéÖ,_7sìܪ‡ÚF4ÜÅ-9°Ãw/›åEk/”Ê›Ì xóXç>-ÍDð_ŽüÏYѪ¶µàY”#<Ê唌rM}n¸iŸ×Ddë22S&Ê )ÓD¯ã¥+Š,h‚Ê-Ùf}ɈJ)²WL”EYU%@€­ê1/Þ½üînÍÆ½B+ш:LÕ!$µTªá¤ܘ{k5mÙeRRufUgÊÉ‚`·ºš/û"ïÝš‚“ùÀÂ\QË·þmÀº®€Óðz¹"p¡›€`Ü ™»œàÁⱃ„Éá\TOð¾Þ¥†œÌóÞ÷üÝî‘ðuBw¬°¦€ØŽÕ „ìX`M9q+Ö±8àPê4ƒª4ïÃZX»WÖtу9ª̽Š`޽ÌÃÚ4½Ë©äÁšj‚%x° ªm šÊ‡ÊÃZ›‚‡¼‘m6©Í?”ý£_ÈÞìš§$ (¥z׋ª‹K×ÓA¨$œµh‡íÅ›ƒñYÆÕ ÇÅc`˜i®l÷?"Â/žàÆ$–¢°‡6§;ýJíóÑ=Ü¿%lòÜNqYp¼Û?AtÎØ'–ƒ,^ä8`Ç´4uä9¨#ÑA™êHu¼N\uOvÖœ„k[)kˆN‹Ä udVþ™UPEP}9UÏ`Pu æsž¯Há­ƒˆÆ÷ oB_> stream xÚíYmoÛ6þî_A¸_d`bÅWI†¢Ã’¡CQl™‹aÈúA•h[€#e’Ü!ÿ~GåØJÓÅ*œÙ…¾ˆäéør:>wÅ€ © v‹j¹ßvÅÕÏ“€À+å ^?Î'//#ÓXsMæ ˜¢<&:â4”!™gäÚ›¯ÌÌóL¶tµuòqæóЃ&4fÌ«QžTN¡HnLædiZVY^,±Ù”®ÄQ¯¼ÌÔÛwXKË¢0iƒ¿$Ejꦬ|PNM‘%Å z6ðŠÑ™/…ôþœEÒ+7³ó_ˆÏ$¥„’ÑX)4&…>¾Â[;0tÁ…€Äšgg©íxø.©ë²54Í“¦5„ÿäÍ {$XÜ&U“§›uR¡B}2ó½]Ç¡®_ͽS´ÚÅk_Ì'Ox> ŒÄ!*"JIÊ#IÒ›‰•KÒpª4© YL~;xM‡Ù{LíP„¶©„}ÆuûÂ+Øø;Hì0šh©i,`Ó\X q«­ì>·º»OЄiì.\²ïM£# Í@ÅðTŸúÂv_qåqù ưa–„‘].ìM4-é Aóå¥`;Ž‹š‹{1kÍÌÌ"Ù¬lljkPìâˆ{S”ÙpçG»·-}gžÏ!¨±È V ¦çM°}/æ½paÊ…Ïåô |*ììJw ñu¸1ÃÌ€¼e×­[—@u{Â{3š»Û£{å‡A°˜CSÆ6 D¨¹/ÂÁ§w˜~kñŽ…œê€÷ž%3uîZòe«ÝG8›h×÷ ÜqàÚV¾÷¤Ï¦÷uÞí#²G°{ìÚRÎÁ¹e×µ% Š{•©!GY¬˜#ª Í 4›ÊÕ>¶„Ù`ã8ªeá-;UŽ_«Ž_CÿŦH›¼,¬Í½ÏËy_+ì¶ŽÝ3oM±zÛêî.])ªÓì&©LSåæÓ {Ó®q VX.°L—ó8¢a ÷µÌ?Y2o äÐ5Òs};¯ÏPË>¤·‘PžPKð¾’ñç¶Üñs¾ Î׃¦z2¥YÌЬùáÄ’QŸvù¤¥Ñ_J8ö#ª¦Ù#êFÔ}ÅÙái”éÖ³Òîs ,hÏé>»¯òÿŽ%ÂÊ)P×75R³ÜýI­ð¿gÙ´¿…³ó^_BSÆ=¾&Õ`ïÈ׈М2¦Ñåy}U–öOø³å3á×|ÚÊüêýÅÿQACé0úÇ*Oí¹jå®&”Ý} Jrâí5H…ïËæÀËá\jwó>x¥¦¡j/áØ»ÃVÐ}÷5ÿ|¾Uð¾cê±ÜæhvJY÷'ħé%ß´ÄËÐ$wœx9z‡oo13¯ïšò&7õ9@›Ešr>¦åÇÝîTw/¹Jê_Á¹#°ËÊ—¯ßþ~JiùÍ~Ö•^S—7ë¦JnìÕô,`Ê ÙbÄé#8e’ÓÎëyýþÞ¹#XOBó@P1⋘jÍpá€PùÆ? endstream endobj 37 0 obj << /Length 1694 /Filter /FlateDecode >> stream xÚíkoÛ6ð{~…àˆ ÔœHêY¬_†¾°Öy†m™¶¹É’'Ñq³_¿;åH¶S$Æ’5EaÀ"OÇ{ñx¼;L†‘çýG³ÎÝãý›³ÀƒW4ªÈš1” Éq ECr?µŠ–Ð[¥KÓQªZ£ò/ÿQ¹åKU®q3G/w|G'Úã>±­àü¢§‡ˆAþwä7é ‡) ’ä´¹íIÞ÷{L!?Ì‘ý_|}§ãgãë7ÛÃJ9û÷{öy”Dþ|Sê…®ê6‡œ&F@ݘΖ«|Qé¦nMƒk÷¢îAlôh!e›©ª½É\’òŒ!§Îú´ã=fz>×….Q"»h—¥žåN¾uÞ\nÊMë°×­6&/6e§ð:߬Uó`ÒïoÀºÌÍU»Öÿ€<¡Ø°(Ù­«¼©ËúƒÎ;k×¥¾Ì •ÿÇò’·Þcè HÀ‡˜u ÌÀ@ƒÒÐÀiQ8h9gµ+…; 6Új›îã^çÆª>¬*(„¦‚•)$ègì†àÎ g½¼*ëpvH+„<*é°Š2oA†0Hà,˜b EÄR9€!ùpHòáå{†ÛrA”#°îBWcîCÔà~G`©VûëÑ (95µ“y“¯”[RwÂüe BÈh;‰Á i4t•–0”a§5Æ3Ôn‚rMP¥®n‚"è\3öÿT…¡9!˲!Ÿw5J·éd”ô¼,ij®E—©­¥¬42艓¦,ÊÒNœ7jq¿¦3r¸_²ÑáÎÈj2¥2ðÐ.aʤÌ:ô…"²4ùöéqßÊ$éÎ4êˆüÊîdû´P¤˜6N_ÚL§é h] :£¡ŠQ24ÛkÝ´æÙ¹Tæ¼¥2îˆaj¿iCñ)"¨øáDíŸ,ˆ£Ç_{Þ6w¼¹ö‰`aw-/NËâì0mÞƒ]ׂ_ONâqëÜœ¸ä“‹÷Îï)ü¬«â{û#ºOï[p ­§Uý 3G,%Ì!èÚþ#Šõ£O´î¿½$¶¼ ÔŸä9¹½í,—GéÁ'oÀC$˜ƒv3ä&a×mĸpö[—œ@N¦¨ÝÛà›$~«±‰|˜ŽÄ)¬Þe# ³À%☙ØôäHæ p®Ý:[Ä)T—E¹™©Î i¨J×:08èbcTÕ¦[êp–…²µÊ8%¶.»BèVcÖEKµÑP]QúÁeÄ(¤'«Ù¸¾·¶=qãÚïm½êr¦Þ\”ê1d<ì éc– ¥/IÏ2I×ð^ˆÏ%éèÕ7Ѹïø®B:µ\÷À‚õ_5 V•Ô¤¢ç¼n 2}I`¿ Ç'äÌ ÀF¯™«Tíôj­ïG€0r/c¨[×wÃÚÚ1.Ëz««Å±NöÔ\ÉV.8°aŒVn°Šêka:ª(IJŽ[¿Ûñx.;ç 1µß6!|¡?S9FãÀõ3ï™(C.ÉosÑpÆ»šv¥Û·ÅrrC;]AÔµ($®ï /sœ\ö ¹#¡¶DÚPÊÖº°µl˰¼ É'Uå­V­¡‰½ðqMóM{¬+3áB‚Ùö*a§ƒuÒ£mÞT£Cµy¥¿Øémùd‰·œ»á¹ÉŒñd×Ýy¤Úg<û‹FåFј̘Å~eÍ^G„Þ¸nUf»9ø°f¦ö5ð¨^!Ð~õFö«7¬u_½t“¹`³ã4ý˜¹¾ÿ2Á„LšÁ¾nèw¡lB¾¶™llOð–‚À)*ƒÄχLX–H$="Ü÷ÿ«GO­ endstream endobj 40 0 obj << /Length 1712 /Filter /FlateDecode >> stream xÚí]oÛ6ð=¿BH_l aù%Q Ö‡v]‹m±Š¡ÝƒlѶ6[òD¹©÷ëwäQ²ä(nì"Ý:ôÅ"ïŽ<Þ÷‘¦DÈ0h÷SÍûsÿùõÅ À÷¸U$‰;ï|õMðÑÔ18 X("Â8ˆ$#IÓÕ™…K¦ˆâŒˆ²ûè`vööè'ì}Sw[Úî/P>½:{ôœ'ABð(¸šŒZdD*&1SÁU¼Íùø÷«Ÿ>èf¡°¿I„¤{0  Þ_„<ýpq%ÔM&ûÀ—õb»,ev«»*ö†tÎŽϹ.³´NžÆTX!¢È c¤Ýîä[åÆäÅœX†÷-äã“°„ÃT&~c¤ìƒpóóë´*ο‚Ø <ŒÈ%@Ñ í~4¸àUš¨yðíÿ$›à$/ð;+«UZ?3Y_·Dðcü|ò®“Õ=p¯ ºN·kÝßÁ¹GB¬t—ã  FW Ý0^.Ëk{Û™a"tG.ÊL¤K+¿ (ëfå¦ÈúRÔÍ®öTF× ·r™L§ú4¼Ç¤ëëÒ£çq7åI’Hél'àëñ¤^èj|Ñõ˜«Q:æñh‹€º´_Z§KO’× „Õ‹Üt–•›e†ÓÉøvÐý6F[í%aN$JÈ”x˜uµ)´u“Æ]ûç—”Pë×HŒ;ËQV•ëæDžiù2¡‹Ì9£ÃäkÄ̪rµ#¶ŽqÁ#N¢8öþúÍ+m÷"‡ÉÊ€ÁïßÂÇPÿtu³Ô‡ŠNÙ^©çŠÐ(ü^ê£ ŒÐSâK=3›Éÿ¦ÚÛÀùZµþþŠ!æö&§þW‹â‘Úo1O¶Ü¿Vr ›Ìã:!ø(Ë]ªt1õ_:k[‚¯ÇXEÙHˆ­›…;|‰€†Ñè=­ BrÓ¬Ië½Õf\¦9´@®È Ú­ÉaH¸jËì «Bå;qÈáL!¥7Ësžž´ëš˜:_.q¸®´Y€·?RÞÌÕbÁ¡‚19X‹aÙdSã`‘V©3ÖvUVÚ‰6¾ ¨õº*ádÖÙbˆD ÆJã×dÚ{^‘dUöy‹Ñ¼t&ŒÊ’l›oªæDérkrCœ@MtuÅùm w G ñf³Z¥Uþ·Æ©ãg…¾ÆA'‚€¶íÏ6Å´Îá̬`„ªÖ|Èn{ÓZ"" ™U*8ïKÏrRéôOƒã¬t1^ìÁÔiCHMo^ch^EØWAŠi¤tÑÒÕn]¥yíU?g̼ª½®Ú;+às¿ãX €ho=ùÚs˜Ù¨ô»µèã_WZºÏûØ·Ðc3HJ&{=¶3ĉúö›ì»v·7Ù2° ¹÷Þ%ð/jç})‰Û—’îcD¸{?q¯ ¿Ø¦j® îß\.¶£KÿZa¬°Í³É9¶açè;â÷f³šØx·[Ù|ëŸ^l s6,™BH]ÃÿÎZ*#.…J.Î ÷V9´!¶ x³ÜBï4ø:/ˆßøÇ¥·âE~­³ÜÕ'Géı¢Ê:”ˆL?‘Û´çOO¦v¢$qØNbJiOAÍ„³„µ“8Âã\È.ü±\­Ó jÒÇÎûØåñû\×]îv ³*]ù±ÆxGDM?¥>šw:/®3îdéÞ̃¢£KÁÀ,öÉð•ÛŽ§ÊlÌ+oýéf¹ÒEƒ›@±~v02Ðú‚$*ô“.êUpØOÉA8Xí ×®§]JÂâįí!8t· X¬†ÀKæÜ8´‹ I¸hî"€3xÚ B06Œ J|†³%F YÆQ»Í|6‡¾dNãÃ\»‘jÙF¼=„ T$CN¤ ÃhÔfK—Zy%oõÙ ¸Å±8‡†%„Çü3™þ ÜWÃ6¯Û›Qƒ/ßÂÑÅâ¼,¶æÝƒŒIFbÞÝ£™íu›¥ï>Ÿ)œ{6ç¼ùóñk?Rp*ˆˆ™½îeJN褠_þ¹¿êÄ endstream endobj 43 0 obj << /Length 1954 /Filter /FlateDecode >> stream xÚíZMoã6¾çWéEb®Hês‹¶íÛ¢Ew‹¶zh{`dÚÖ–òŠòîèï ‡’%[v7iãfñc8ä3œO&“aäyAÿS/†}÷ùùÛ‹Àƒ)¾÷[Ų8Ã~ïc©÷‡ïMýÿ ' <îe “QêER2ž%^¾¾Àñ',"‰Ô«µ7¿øéÞ'ºÚ/¯/^|#2/ƒå"ö®çp2öâ$cq˜z×3ï7ÿ³Ï&SDÿZ}`ÐŒ’È)XœÄ“?®¿‡“O9gYíP¿yõ{À#Ó.àâ¸#>À"‘ÿ¦šió’Ú3Õ(6¯ÕZSÿ}Ñ,©Å%}‹²Ñu©VÔ+q-5U9£FDŸwª.ÔÍ ¦Ç÷>p"ÉÔû¢\ü0™†"üFÕfc 'c˜oVk]¶s7Z½ýÚ ì·¨Ê;óëQY½.ÊN²û+×?ÍÔøÝÐá¸iˆî§ Ûevº¹£âÓ³B•Dº÷dsÇOˆô$ô7êMÇçß=vYÏÊütsG¥Ôs0»"?ÉÔ}ü¸þòÇá4êÿÛùâ›´B–…¡7‚e<$!üXƒ—mŒÆSíD )XÀc`eitÕ¿ƒÄà‡uŸ½ÌX ‘¥%®ˆ±þÐÔ*o¨Ó,56BëôiùL³«‘íy2™d{û/Äø „‰lÉ‘! …ÿåÛVÏÕfÕŒí –$郠¾/V+Së¦.ô»‰H}í·V÷¦2 YšÆCOŒ»\–d©³i°øw¸ºÚP'G' ÒÌW+SÑÐB;¢DÊ64âH‰$  ¤. [U¹º#>ˆi½“=ôM­õÙÐe…/ÇEÂEÀG_ønïšvþÓzN_« 8Þ“\AœÔ†x)%aK-6ì:’¡¿T(†Næ0GZSÆ&84¯êµjhôORöÒ¶ä}žyµF~7E©Ýö‡äéT Ó£‚ƒ0g9$7± N†JKòÞ<æCy|7G½[-ÁÎ{ì(R!ëþíªjG–NJ):ë–f k&¥„ÃÜÏ' FK#Ç·µ,4Måí¦Á“Ž’ˆ$$Á-<€ÈÐvÇe‘rÇ|׬„Ÿ×Z5z{§.™Ë@<ÎÀñ΂¼lÉ ½kÞÝu@ꀘèkåTêäÊà5bÓeîÖŽK¥KXè¸Â޵Ó=îÿæ„ÔG*RðÁIµYZ^ià¯ÕDâíB¯ÚKU.4MÚ3Âw¾i6µCËi †w¸Pצ¨JË7ôoàpèa°m–Õf…zJðXkElCuinU­K\ÞŒè*Ô7qÜŃ?Zû!A„íÁØ5VgWjÌÝÆ¶BjµDµÙßOdà”D_•ˆa5§ý–ËÜ. Æ9(urWÚêºÁϹÝB1ÓüesctÓ ‚ïí É‚à,œ–\/Çâ#ø¼,êh,»‘h1žtRß²&¯7\Af ᢨ§èónÅ>”2À „ètÁb†/Ùº0ÃiÉ\¡kƒAU7­lIÕ¨+ãŒoívy·ªÂX:*0«‘¨d2d4Ûçþ xÉ¡â:¿‰wú}Ö·„Õ¨lÅJWܾ8r\˜F“Gd”nu)‘ؿ挻ŠØ–¾ÚÌôβt˜,„i——,Šmô ÉHò†¨£âq`w_ڜ̅£BC;¦zð䨰v¬¯½î¿½m¼ìωª'ÀÒí7w@KeU7æ5äfÎûf÷(6$F!ø(94ì¯ ò´ºË’0^ }iOÿö.Ⱥ/ Ü\Ê2ÙYÉ|³*EY5R—&âŽr: ‚Ô6Œä“ˆcâ«K3ÊKŠN­Ê¼tõäSyýßõþ“¨à)2Ûy` DƼˆ>.u"ìFg1Ñî}—QÆdì&:wÿwGÛÿ ”Tj@6~õ°m$¢Šc‹ÚD»3h·±5Ð~X}×Ôçšú\SŸkêsº¢¿á=Õ@t 3mr]ÎTÙ˜§¬kÈêÚ럿zõŒà|ú)Ϭ˜Ï‹¼X}Úá'I¡HØù¿ÌSÚýŸ'Zt(¾ñÿF%TßÔžRôx0øÏ(]ÿ][® endstream endobj 46 0 obj << /Length 1603 /Filter /FlateDecode >> stream xÚí]oÛ6ðÝ¿Bk*µ*R%ë€è†vXÖuö°î±dG«,yúHšýúÝñHY²å´uà¬]ƒâñtä}r\ke¹ÖWßÏ'O~à¡Å|Çó·æK‹¹.–ˆ¸ú¡5O¬?ìp:cŒö|ûv•¦³«©Çl™¿ËŠÕôÏù+Ø$¶b'\à®5ã̉8£Õ›‹ë¼<—uJ¤Q2`Ž+BX@„U9å‘}™%i=ù.³×²@Ì5Í–m±h²²Ð/› Ù$ó\­¼ÒoÚ:­ Q‰£k§ï7yY¥„¬Ò\ª.²¦;ŸÎ`ƒ´QÛà#M zS”êÊò[3-3Xĉƒ€$/‘VĶÄ!²°!ÞºÛÅ`m1"-’]⦒Jžªe«™3Ekÿ\Ö Qõ­ ”°¡]VïhvnÌ„õ†tZdËk͸]¤#ó"ðº`#Ðcþ¾»f†n <êXV#»2áD"nšìïê G0ϡΠ*óì|ö_é¢!„D•W:(Ä[—ùUmÞV«vªxiÊëv>¤ ´Y»FRí÷ª~’K„C;Íë>;ÏìÂí:]@" ³™ì3Õáá9~Ä÷-´,M*÷ÂzÏó;yžg×å:%¬L’ ],szÓçRSPŒXÛwbß2^¥ÍY™Œ$ž;AÔÙ¼Ÿ? [ ‚*` gj-'¿~²PŸ¦ð)©C/Äiàá3D»‹|cNÄAZé1€ÒçCʨJd#r*ýgGÛ¥.«´¬7Ù?RÅcø}¬Þxf(w¥ã㣘‰HÀÔ à˜qŽ»HÅl@ÃÜ;P‰Íã4Ôº!‹YDÎ}øpªŒ±‘í&¥J¹ã~¤àâvö:Möõøb‚”Ŧ~ìÃ3"Ê!j È)¾æ0 ?¦âP˜žð|Òw¦aÕ5]1—Zª—K8û¹¯Ú Û @g5¡·í9vViòÑ»Ík"•^íÔòhÒ@·¸åR¯Ø2î1\ÈâQCºK!ü²liº­Gõ…ÞPcåH¿9k8Ïžï÷š â|{·p¨AÂ.¤L7LdŒ²®³ó\÷cØxâhšnì~«R·ÄWêò‡Ð…ÜhKµy‡w7ÕH6zÆ ^ß @½„¾mò%ôk ¬úñN¿Qáˆð¾_ƒ~ÍçZWñŸŸk…dì—O„½lól•eù"QV f&–ßµ\YUÖM…*Ú‹²‡Q¸†œJ04Âs]›é‘ëÑÓ£¯ÇàÐj%d’-—Ù"ËUÅ` Åêb–H-ÁFV—mÞÖšzSgM#mnTº¹ÙQü…C=FzŒÁahN™ƒ¾Îes­|Uë–-˜…Œø:+$Ô®ò}&ÉÊ<»”‹”\ûŒ‡Ž8bÎ À àÀ7ÀA j¢ƒÂŠ:(6?¨(± ÀØê†-ˆë ÞA^ùÜ( 7VáÆ*ÜX…«ðX…wVáá.àFo¢ûœºâ^Vß_Ý]þá{õG¢?=±¸˜_iû¾sºô+ïíŠäõÈý¨yŸ²wz‘]§¹,Ê•¬›;¸Î§Ü0‡…rÀD»ƒÜª´ÎàzB¿xR—g'týà—Ÿ>ßo "Œ°ŽF¾®¬Tbwoðî±^ËÏñ'¹ ûQ6ÀKŽW²*nãµÓPï^¦{%Uøöìùw7¶žtí¾¯n÷Õí+¯n˜ìÿ¿ú&˜°Ýú¦ëÚ7GH¶,†+IšíhIú]WU5É u¦3q$_4ÒDœš<ӄʃhá§úcÃoêgqªèêClÆ®jú“&RÈui¶VßOw60"ã_N}ïààí¿>CÿìD±5óÇÉì˜È|1Ÿü Úðå endstream endobj 49 0 obj << /Length 1248 /Filter /FlateDecode >> stream xÚíYÝã&ß¿ÂÚ{q¤ g°ÁøÔ«´•î*U§èºMÕ‡¶¬M$ÇN}Ûí_ßÁà|8Ùä´iv›3 c˜á7(Œ¨çëE5ݬ»âúÇ‹Àƒ&ÊýþB KL}­h¥·Ù{KÿuA£ÀÃ^£r±ÅAä¥ó ÃpŒbâ‘{•ô&?ï­Ð~Æ>Ÿôã‹wŸHâ% aÞxâáÀ42Å b÷Æ™÷»ÿæÍ`H õ¿]}?øsüLÃc”PºjÇ4¦þèÊ4?ït8ñp„’(ò†„ ˜«H:SyVÉÂhñî_³+¢³þlåD‘Y‘MÛÂÒ.eR©ë²º§¯°“›ª¯Â}9†aä׳–}5ŸËL‰ÚU ©¦³‰ý›Á¾e¥Š©ý£`¿&÷3©ß»ù;•Ýðq¼½!(ሆqoCà€ Ê^ú†P –A•†æ›0+Ûg>¼uF˜'Ûyæëߥìú$aœ?Le©êñö ÁgP h_Ú-WŸÙÖbfG0 <ÆóHàƒÕMp¼Œ?±…È/ªU™—+¡ïƒJT¶?´Dx#ŸêÕKù6žÝ÷Õ¸o/®0½7¬ÃÂø¶ù(a}3ÒnÄxlµºD•;¢7¡ “tQbi*‹LµÞà <#|4ÀQÜÏvôE„—r©( ¨cìו0IÍ *-wÖ•tT³0eà×e_D-´¥`÷µ"•ÍÊÚ²+©-C¦µKAò»—?¢ û 5Ljóøœ@0/âáNG>ƒðq@˜ÅܨË#g€µ¤Ç¼6xâõ%¤Z:8pðzsgËLND“×¶Rɺ© m+e‘;™vÿ·„Ùÿ§>zî:tÆî )yÐ0"AàO wPü’‹ú®u4ÇÈÔd¢R•+& :Ù"“Å#ITؤ#ð`ÈB¹òáÈ––…ªJ]WÊ­Ä\L×8­j“&WSU”t ™a”U­Zp†"ÏU&6Fa«QZ"W†®ìt$®ŒïÓ±n!š…¬Ü´,DõµÉ›N·…Vu-Ò&ÏSàFâ®LN8ç|Qˆ‡Õ(1À­ä&k…v—à)—ÿ À¹.-¥Š4o2ÙÃ6UÔ²*DnkE +~€ÎhÒ èÈ=Aê7Qí=ŒUÊ–SY@#ã‹ÙÝÛ•ŽŽœ+­—?}°Åå-ôtiæþ½–_ʹ\7Ï‘ü'eY§«y íØ¼à-[t:šü±ÉÈÞ1òç„ÐÍé.Ä\:«çk3ÃG:$}ëñ÷õ¥^$8Ÿ×οIGðŽˆ;‚=ñŒœt#Xÿ}öõ×åëÏŸ;\}þüúrFŽp/yhí¦B»ð †o¤.j™ONýxäÌÛucìÀ)ÆÖÃÓ×þ tì7:w§ÕMù“~ìny@6ÏgîY-òK *÷¤Ö½š@Ñ­ó¶|¡µmIÍó[f™·ªžu/tܽÖi1wïsú½„ 4ŒУ¤wÆ8l³óýYÄWD ßv·sT{¥p§ äIf^ñÙEÿ“Ä ßèÍÚ•ÚÊö˜+3\æ¾)çx¢Ažy]üñõ¯O8Žý¾H bðĆñØíFLPÂô¿ü|0ï endstream endobj 52 0 obj << /Length 2081 /Filter /FlateDecode >> stream xÚíZÝÛ6ß¿BH_d fIê;¸{H‹ö€ôšúÐö+sm]dÉ¥äM¶èóAÙòGÒõömÁÖˆ’3Ùáo¨•"Š“ ㇛ï¾ûÇOÿº’tðl>™û÷+É@E&¢$Ò4™Œƒry…í±ÊD¦ ©Uàlp{õŸ“:MÙóqs}õõ÷º M§Áõm $v¦Aš"óàzü~õÕdšè$|£å@$“ß®ÿ æ˜*%Š$Ùò)™Èù˜ ¾óÚÇ»P bQÄq0ÕZ¤IÁýðÓ·¯Q‚¯¿ÏGJÂæÅY£ˆÇÙ~íšn2’,ì‰4\¶]ÏMe»\¶ ÓΖ¶™è<ô}¦)m×·Žßn™HCÃïõlí­Ÿ}¢ÂjÕ½„·4‚Á3Ï·h]oy½4\™~1¬Æ’¡©§Q!bU윥¢°i'Sjf;~/ÁþaÛ4°žE²ì+¤ç؇zÐ+¿KO%¿»>ŒÃD¥"‡ýÛC%µHÒÏ=¥È¢ _“‹”y÷?±$ÛóûGI=þÝðŽÖø|nÛnUýa^>j±4OáUB°JØD¿Uû´eõ˜Eȉ°ŸþXòWg–6L/`{õè5ÎdžܤŽqVœ_‘‡†×¾Cfþsòs‹§øÜ=N Uhx‹~sæÜmÚjðbeÖ+ë^| ·m¸©â¬©Ð[øæ‰ô“±‰sí:5z ñ<‘^ ëÁ˜!ÞƒsOãòÇ‘HÀ?Hþ$R Þr©p]÷Õ ¤îë6ä“%aY›®ClÔ18Ü9PÙ°9 {šlÉÐà$™‚?&$IÓ2‹Cã6جgâ#ABè®–«Ú.=˜´3æ¸YûÞ÷U]û&Âh~*€¢U3gºcôÖ6Âë°c‘©—li‘^•ÂÛå»Wï¶ióSêHä*òC„òƒ¾m›®wkD’s¶¢áÇ7®Eë¾o*Óp˲í«ÖÓ½3UÏdWÁ†h؃ˆùÀ–è„9$b^øzQ!uÃlÉÓiÇllØZºjcl2üx65Å©á7>ËF#P2`÷’QS¿0=SsÛXgzëÅñ ¡0wÄúõzèºÛ=ØB#à?^ÝŠ….«®cêï¡0 c˜e‰®“k~§òºq'a¢a'‰MO¶©¯Æªü<É#rÎ"KT$ẳGÂ*¢+Ý„ŠéHgÐçå‹×]ÙÞ½í®g(‰,͇±}Ë딬†u¥å.‡pCáãe«8Îü@ð}@» ‹¸iIªóŽró.Mïª\‚©<*ËvM›¾Dc'ñPÐIm±Ež ]Dƒ>Ë;×À$‡zÇpnÙÀvëÚåfú#“ÆJÈ(¸xýöíñÊWnxV†çÙanýä-K>¸=·~øŠVúŠVBŠ… 0Cn,7Œ@•L]ß{ÓR#íM—òú³ ±‚¤GùOi¿#5lÅT¤"_SCo.(b ?£¸yÍ|7ì ýUª¸gNúzÊ%ØbV+ךM¸@ËÐÃñŽÔ{ \¿û4I†ÑèîyÂß×ÈX"ã»úž96ö:ñwr< ¼ÕÆ‘Í$ï\“-}BsÜÁ‘)CgWuUbœ#â8ò)»-'t~ ¹»rÆÂ\]tÁ×ü~kM¿vvw!Ê­{çS†äDsô+H!|cg»\"©|÷.÷'Ï ²²U³Y¨çhnk/µw÷ÎÎÔÜ0«`“#ë¶W1иuæ¹ÛÎJúùœë=Ô'3à¸ñqûªôã 3ù‹¯À޾Ûô;3½ùëü…yØõƬqîJ”á>Èá³v‰®„ƒ+͸“³>v¬;4×ánhUˆLmŠ+[SclO§(¢Bí¤•#S&BÊͶ™Õ‘ÕɳqRËîE_xÉI¾Çp•À»Y~Z؆{V5³OpŸÃ•Ž pÕÞÝq&$œ„_î¬à8Ê…òàŽÑYðù ”Ùç¾ÿýÔ“®I´Æ^ŽBøtÇn²×¶-éÿ1}Ô¾àáUL÷dÝìášpžñ¢/-¸Ž¢Jæé^G]âff§p>ÉÅ"ÏüÂ(޽çŒ5-Ó#Ø!làú é *æG ‡Œkµmù–lË7dòåÑèÉ7öø½l=&, „bã$sE\4âÓIÓc˜o[Îà 8ϧµöA‡ÿÚ²gT¯ ɸ‰Uå-7ó }¢±C‚î7ŠQÉEo;Õ6ÐÍEÇ4Úâ£h2×BÆj\I¾úhš&"M¢ $K-ò|¯R)„ŸNùåx‰ ¬ sÍìÝБzô<šãÀ²½Bžòž é+¯é7­Œ-ùÇÆ¾)ÂéHA7ܘø°1ù î¡ø P©Rp ÄÅ*…2§ÈžÁ—Ô‡æÑ£RÛ˜«Œwú<ä ê9,Ð¥Þ…ŽZº4|vHû9ùl.ùºÿÜŽ‡f{ô^ò…x¼Wuu㌻¿„~xÿª¾;[>g¡˜Ï¾dzšï¡È)íÐÌ»×8Úõ¹ÕøçÙ‹p»zþ$Ÿ¦?ú/bOø"áÄÐx[Í—æìÑñ·ÎÌK_'hèyL£DÈáTôÑ¡*ú½‹< endstream endobj 56 0 obj << /Length 3182 /Filter /FlateDecode >> stream xÚ½Z[oÜÆ~ׯ`Õ‡®ïˆ3I§š¢q£ G@ì  vg%Æ\rMr%èï¹ñ¶K«–çEçrîç;gªÈÆANÍÝü]oþyð)€çWíúûÍÅõ«4ÈTæŒ nvÖ±2YàR£›7ÛàíêæÞ_­£(Z•yÛáÈ®ÚÎxî]‡>o?ÁSó·¢å/]ÍÏM]]™tõpe’•o:ùgþzóúú\6¹ÝYå¢H£‹÷ŸÊÚ>lê^;%4Ž•3¶_Yß^­c·úÝoäüÛ|ƒ—¾Ÿ’bWùÂI¤Òl~ãöüº†#a“ë^âÚçJŽÍð}ò ÕçÓÏ^ýãÍŇ „†²DEq8k”Õ&Øì/pÞêD%&0‰ éƒÝÅÏϦéyü~ëÕÓ¿ÃÚéß7bëss ñ£ \œ©XŒ½k¼ß~•NA2ðGø7s¼ôdÖo×±‰W]ÕI”œ_r:9Þ21ço&VƔۋ¯»ýJ9GLÀ˜×žLŽ«Â³Ì›;_~â—¶Ø0Á/ñyÔÊ u%ƒcë…[ò§%‰™P+ Áñ\dç$›LÙd°?R XpX°]Å=¾ãU~·$¥4SÆ &ŸdM8°fp;$`èL½Ð¥Ïi²@R°ž¬QìÚD*ÓzÎ×®Àt€Dë4 fõNGÖoïü%σüy>¯6¾íêf½õíÆWÛœ£¯j|™Sü»/-¯G!à'NîIêe}ç+–?ßÎÔÖ{ß{ßò–M^– ë€^´ ;§I¼m€ <\ãRÊØŠžNƒž ~+}u×Ý·—üF[¾Ê?¡T_à\BTTìØ ¶Kb©Ï¶NtMQ< W°•í6øMÁ”%>9%@té¶oøóÜÚ…Mxækùˆá^¤ñ$ÅÀì”j^2yÄU²­Þu^ÈjüÎ7BX=PÚú»¢»ß(/ã Š´üœÊ¨çª½|ájO<æUáçŽ7lJþŽÃ]Sïe²>v¨ïFÞ ¬x%ñ ’VÂw‰Ä@[øZ\¡Íò2"Ë¥§Õ[qPï9h$tKL¼”ÑŽu5EŠaϳêpTIYŽÞG‚éÈv¥”/v<æEÌÐGd¡ÅQײ¥r¼0C4õ`JÊÒ4ƒ¥΀›Fzµ¤‘­`#ïùWñžíash¨YãYÌ_ˆŸB­ó÷\$ûœÃ(¶$öI°~0ab{7ÆÙåć_’x’p)Šƒ±H»`ăé,W@l S„¼ûö Åœù®Ï ‰¦Q´2ëM]÷¿AºkŠ ‚ï´Ì[Q1‚¢—À“åcfsùŒ„S'6«™c² `´ñê/s·œ|JÖoÜ€9XÁøØÀþfh1B“_¶HÖüš‘võ´/LrÅ8¸¢â”ý„G:£ô%ˆ¦ãÞ7ˆÒmèVeù Gè‹ødÂè[lS<.)þRªZvN¾çÌSÎ)=kxæÄ°æ-KÎÆâ²ä)çU'iò´÷éPYk'î‡÷!!ëÓô@QLš&éìÝ€®A/P‚dæ¿‘¨H/¤êpÞæø xÂöR™ƒõE¬ï -[§ÂhLì?y“o:6ÊÞˆž$½†œ[L†7ð]CFÞòRŽÿp,Ö %0ÝçnXÀ,~ÿç³ @XŸ=»ò,_yT-mN\Vv²$Uñáè%•Þ¥ÿ…ÚZJªˆ €‹OÄSàÃx¤ZóYýo S ¡ Z%oΩt †½ø°o6Ðgé’ ö@¾L£1htlœj€Œh”pPŠ`šõÏ ¼N8DñAHõÁVÔ q²“""|îÁòpV‚‘\î»B~ P ƃH a­Yý4BZްµó*a®(ý+OÅlªÉ:¸…0X¼Œ–Y±X;µXÄ–€%—}'B ï˜Z¼3ÉH„X¶%Ä °)Q-A௳‰ºÙúæ #Q%cRžÁKŒG\OQQá,Ïq(Ã>ùB¸ÂrÝv¬ÞWœÏªK™=ný.?–8<îÁüÝ·Üß²NŠ4XÎÄópÇß$Y·¬h§Òø¤SEÙÖöiÐiÐFC\ÛÄZ†ó˜;ÐQu÷X´T^ØHŠ`àg@´[?ýØÈyùfãì";ÉÖ0FÀ ˆá¶( ‰å´aDœ30s¢è¡w1SnFà‰‘r:ý¡Òõ G=ô\ •fb.®¹sS„³„ÒâX…ñ@XÎocÜ gyŠÑýÝ@ÖG”á&|%ïwnl-97ÂãžH ý¡÷ÅØ=p`™-ò%Ò¡²bÊfÒ\ä RY2ÀÇ]NYÜ}ZÕ*µÑ0~qB*¢nóvAÅ1Àíl€6[– Ä8õÁÀ#Ýx~¡|A¥9 iªoÍ€$õ>‡Ïb;q_Hƒï(÷]ßÿÊ”;­P$D!µX&89”ÍOé¹à`slß7½h’Í9Tz4ýúÄß%CóoC`;‰gP>%£q–$68ô¿|ã Ô3È v—ß–BêÃU VV™9îõ0€ÿÈlvÞN›»¾¿0ãó¨GŸ§quòÏ€‡¨ÍYŽ„Nþ½€"¦dˆJ=ŠìƒwNd—A4)š—Œ4GGܬ¥E Hò“1äŸwX¨ç!'Mº§f±Ãê²¥k”¸7'þËA.ɆÆ’® [@~*rþÀÍÈ$Cƒ±i˜â!ÌrÜN¦ o˜%¹Ò溕íà# 2DâRý ¾ kùqè ÔFÒ‹ØòuE÷YB¸‚E‚Æ´›C˜±C‰¿—mØÕÎtG ß„t û¢'uà†Ò8«ãßÕ¢$ä[¢é· xÝ Ä¢»™ôó7-û|"= GiêUs,='‰AUa¨©D®câT¹1Uçœ@Trã¯Ô<§ ú¶Áì¸ÑXî4h ¤®›5uÅDSe¢Ïô&Ûy·kö¯)ýÿ^h +nöo ƒ-||M?$§Á#-ÝóeØâ)ƒ_.~æäÐY'I¤ ÕôS¢¶вùoQ 'KBÍjÖ± ¥Rñªû®;¼¼¾óU=ö‡RÍVíšk‘ÖôšµlwdÕSwÖé“—´Þ/£-„æ!S !¾RÅ{ ¥8øm‘«º¹»†‰âúLã·®ÉáÓX+àäfB’NÜ4‘¯-D¨}®nA)˜”à„±CMP^ÕgŸ–ºBü;ÊÙ`4:=žsJŒJÂ!w£?ã p¹ûqYSƒpÎ:Q\½cù_²˜ƒ-VpàP]Wï×ǃ,èižt¥O,C…Ù\eÑÙ„XÈ b_´›ëW”ÒQo~3ékøt,?™0LÕa»›Yûryr`ök@i*¸UÛS?ù«fÓk endstream endobj 64 0 obj << /Length 2208 /Filter /FlateDecode >> stream xÚ¥YYÛ8~ϯ0ò²2¶Í)êJ€v0°¯ÓÀ<$y`Ël[ˆ,yu¤Óÿ~¾bQ—­dfg_Ú<ŠU¬ª¯ªÃÝiî~}Þüþøøæ‡_¤Þå"OT²{|ÞI •ï’L‰T§»ÇãîCð1”éþÓã¦c?ü’-ŽÐ(º£},¯Ýþ©§â°nx|´]a룩÷* ú[’6ÒÀ´{X ÆÏÑù$™¸ž\^OçB¥“´÷ûƒLÒàý$ü“Ž?ïy±f.Ë «LH™<üMj/¶Ä%Ó ·mm*^©Ç‹uLJšù»-M—Gbbú1Tñ½`ŠX&#ܲÍhš¦¹·Ë½A*“" ³ÝAJ‘Ç1³ÞP:çzýOpTê¹ÖÿŸ£PDQ4 »—âF#ÁeÃRJ„I6[s2ø’I$²4iþ²Ê\-(É•‘ú³å…–Œœs€Ø´ÖÁMf²Î¶¥ó>(Ù/8œ rÛ“;l[]l½”|2rØ!'síÄM­ÐsÈSÃh‰5ÿÈcU4Òm×Ó$v¦3ua»¾i=¶@R4Õp©™âl¼-šºzå¥/ûø«¨¼\ -'±ÿ"ÕÃ-óC‘ )dáÃ’1>†$Í¡E—{GvGì‰lè¾q›U¾Ö²T/âNoÝ}*¹ˆ¤Z^µGsöéî%Jä™\™¹^ÙíHbÎ×£#Ê!kxu¶hjb¿út zì±cFÁ߯ŠsGzÌÉ•Žççpb¡• ëGa$d<Ù®!­è°jŒô¥/㉕~ÏC]ôelÄaèìG¿'ÛÓÞ(¼Ò<{г½®6®$£TÌ€¸ž_«æÉt°ˆQœâ‰ðÈø'—“@¡aϸ@ X¸2Ò¬^?^x޶·þtí/LÆs^•pªÒ›ÔƒD™ Ô,œÈ6ôÑPgî6Àð7'|C)’¹>7-s?ÚÞ¸ð4%Ó}BeÌ¢0ømVC'r•4ˆ´05|]äÉÐÙç¡âÆSzEŒ åÂWÞ‡¿Ó™HóÑç>Óµöг iÎGTÒ\ ™ú4Õéªá½ˆ¤IUÖÖœì{^„>¯«Š®é†Çq³ôl^èV.W¹Ýß0ºBªpÊ´ÍPœ7PÐè©Ü\9I|ÞÇq€ë}¿KˆÐ¼jå³MpyWö\ž^µ/¼A±åyÀN-Š¡m-¥äy—~ M®çUg,OR¦ìN“1;ÊŽ)[[™žÌ®}kSÏÞôCk×’½áoKÀtê"ÂÌו@Ô³ÿíýoG¿’T é“”übŸXË?;}ôe é›K3t¼éºa…gÕø³G{j­çññE3, L;cáÛÒÎ,áh]ý&äúÕu;Ñ}âçaê$»ay±¾×#¥˜û›~¸½ÕjîXNž‘ô‚¿Ûš®ÛHT±c×¢ –Ìþ<ˆ’h#ËF2 ¸+‘TMù¾uYø"ŒÅk;U(ÌZÛ—Å”¡NøããÛtêt°FiÏqä,ήìÊÜw1©ïb°ui\΄tSs®Jb!³›D훑|Œ 9B;¼)ͼVPEì]5EbÅÀÛZ‡qð4x:Ÿ»À@Sñz?™'g=µÖ|æá¥q]C.}p‡ó55”C"ãà§²C·zØ 2T~ŸNÀƒëѕ拿Õ´àŸÓhŠ!‰Œ†·—ýÚÀ†×ýó6ò®Ävð¼Q„#è õœÚŠžUø¶íMÉý6ŽŽªªÈ+¦Ôb¤‹Ú®ŠÉïû, ü‰©íJÇ•£¥üUó­ Æt'fäŽæ­›®¼ÕTĨP«®Bo¼˜¥ˆfªw[…E¤ÉÔstçæe£¬„( jnWï™$" §žëÚ–u¿Á%Y6fÞ Þ®`ÓÏW¬ð(îÇʈE‡-rm<Ö5Þëc‹æû'}ãVe-t“Õ•F±+? ·JÁhÓÓ¯.Ó¾Þ+¤C‘Î - ‰pè#©á%W„°òÄ!ÏtíméB‹H¦Vc lGáJ;Üçõ¬]á†ñZ¡l]³óòÖKD$=øv •xª®Ìãësa†ÎNÍÇØ´Œ Ç÷]aSÐÀ‡pO ÷À¼\ÑÎæLw,G‘¡ë*Yæsó¿…BTKxÿzÞGo ÷xo^Ê™ˆòù+ÄFäxHEë Ø`åBê©c-*ÓQYÒ`J¤Ênƒsœ‰ð–óã%gbÌ_gT¬ƒ£é }ìAF,¯,‹Ö\ùöÝ8ÑÝ~¼à§)Q/^pãa>âò-QE·žOg¯ïg”·Lß¼ÖLkÜK )‰n 5g|únåZjL-5MPÚƒœ±Ž¼Ô7xý¸”K³ÆÿBðÈsÿj#ÉD™Ègsö¤éþõá-ÊâÛñ»ÄÚ¸C¥âï¥xÙ/™"9{~ƒ3 l*´ºyómçY%â:Kh þÒŃX§`YIÆ‘•dü /I'#òjW¹€ÃȽ˜ˆÀO~Óƒ(J_´j'ø[· \ƒÞ9•¶&§:10´aW`˜9ôd±HÓ³0ô¸+ì|ï^rkMibþ$9}”ºë@@6 Z?CP[€×œDˆÇ¢ÿÇ€ŒWD??¾ùÒ¶0 endstream endobj 80 0 obj << /Length1 2050 /Length2 15736 /Length3 0 /Length 16981 /Filter /FlateDecode >> stream xÚŒõteÛ¶ Ç6*NVlÛ¶ŠµbÛFŶSIÅN*¬ØFŶ+¶^ö9çž½ïýÿÖÞk«µ¹æ×ýõÑû˜äÄJªô¦öÆ@ {;zf&€¨¼ˆ3€‰‰•‰‰Žœ\ÍÒÅø?r8r  “³¥½Ï?,D€F.Ÿ21#—OCy{;€Œ« €™ÀÌÁÃÌÉÃÄ`abâþC{'€˜‘›¥)@ž cot†#µwðt²4·pùÌó?¯*j377'ݿܶ@'K#;€¼‘‹Ðö3£‰‘ @ÕÞÄèâù¿BPñY¸¸8ð02º»»3Ù:3Ø;™ PÓÜ-],*@g “Ððe€‚‘-ð?ÔàÈj–ÎÿV¨Ú›¹¸9ŸK ó§‹«)Ð ð™ *-PtÚýÛXîßt€ÿ4ÀÌÀüßpÿñþ+¥Ý¿œLLìmŒì<-íÌf–6@€¢„ƒ‹‡ ÀÈÎô/C#gûO#7#K#ãOƒ•nV}2ü?g'KggK›¿82þæ³Íâv¦¢ö¶¶@;g¸¿ê³tš|öÝ“ñ?‡kmgïnçý?ÈÌÒÎÔì/¦®Œêv–Ž®@i±ÿØ|Šàþ–™]ìLLLœ\ #èabÁøW5O࿔̉?9øz;Ø;Ì>i}-Í€ŸpÞÎFn@€‹“+Ð×ûŸŠÿà˜™¦–&.c ¹¥ÜßÑ?Å@³ãÏów²ôè0}Ž3€é¯ßßô>'ÌÔÞÎÆóoó1£ØWMm¯´ÿ¡ü_¥ˆˆ½À›ž@ÏÂÎ`fæ`p~¾øþï8JF–ÿ©ã¾Òvföî—ûÙ§ÿ)Ùí?3@õŸ¡üïX öŸ“ Pý=èºLìL&ŸæÿÏãþ/—ÿSþW”ÿ×Aÿ¿I¸ÚØüKOõoƒÿ½‘­¥ç,>'×Õås äí?wÁîÿšjÿ½º"ö6¦ÿW'íbô¹ Âvæ6ÿm£¥³„¥ÐTÉÒÅÄâßãòo¹ú_‹fciT²w¶üëjÐ331ýÝçv™X^Ο3ù/ðsyþwJq;{Ó¿¶Œå󄜜Œ<á>ù±¼™?×Ñèñ¯)02ØÙ»|º>ÉùÌìàþ:Qv£ð_¢#®Ï1úqÅÿ‹8YŒÒÿE\LF¥¿Ñ§NõoÄ`Tû}fPÿ/âæ0ý>óÿ>ó™üýÕ FÓ@f#ð¿ð“,ã¿âo£Ùßð/dù·=ë_ÐíþÒÛ»:ýÃÿÓÄüð“…Å!Û' O‹Ïûðo‹O™å?à'5ëÀOn6ÿ€Ÿälÿ†ŸÊøw(öOW»Ïóþ‡þ“­ýßÙ?íÿ—ú³z‡¿ÕŸÍpøÜ%û´‹ù³ücþ¬Õùï|! Û?Ȱš;^9ÿ ùY‘³‘³Å?B|fù»ÝŸ«ÌèbáüGG?)¹¸ÛÿÃá3†ë?àgCÜþ?9¹ÿã¸>½=þ?Ã{þ]ͧ«Ðéß±ÿ×ü›¸:9}~þuC}.Çÿà}r€@  Üò‚½ oˆU}HÇc­0ž;ýþ$ÿù¾f:5½÷²Ó/×g$èêšì M§{ᔑ^”µ]qª;¡¢7ïÓÖFèð¶$åöŸWƒ•™ýv¸¥é/ƒSE§Â °øôjB>oŽ>Öà­ ]2äùŽ®\HJ…èîý’ å«ãa ûÊ5²ð¯å³ô1êѺ%¿É Œsæ±I \è `hÐ.=ßÝÏ¡åM}É$ÐÂùžÅ°{ko±Ä>Í{­Wª±8wãáhc€ß¡ÏPx‹¥Ê`-z—þˆÞä_Ì匈^ éOœ—ÕÀ!ñSÂv )£çÏ ëB'ëÎs7Ér²Ñ0™RPP5Àx‡’—Jš%U“Ž”äà[ú?½‘¨&jšÒþê!ì>û£ÞE㓇ÍÃs8iKxϾәãÇñúÅXa4#)™b²Aº¢ øevBµÀW\eÄ9¦±È[gࣀáǽ¸U¸Ï[Ý ž~x.,¥Éc¥Æ£¤‹ó·â®x‹¦ZŒ;ÌàiƒNîo»Ó.,ï¬I?9¯Bè¤Y°DÎ+r¸†eÒ7™æ1lñÕÁ4§•ŸMµÎˆñg‘æÞr:ÏËW•ÿ ±U¢¤bàõæ"2ü ¦'ð³÷¸þäòØó4«ãº‰%iëØfè35Í­ø/°¥Á4Ùܲ 'ÎÙw‘ãó£ ÒÌ ­t—3â6GS‚éq´ØVÈœÌÿÒmåV=Cz¡ç\ç¨Bò6]3JúüÓMМòô©-ë¯$u™à$‘Å÷ .SXÿ’É‹·5ààwZ 1Wë#'Ck0c5׸çòþÕMv¹èP×&CîRÙ1–O#QZx!÷ä‰Û¨Ú`ƒ’âDB¬™[’T£½øIÈÍ:rÄ¥…AßÇ«¢K»Ð2‹7W¡AQ–ˆ‘ë‡äf¥LJx…³sAP€¤"÷{–ËYêˆ;/ÍÌþ7vø.x DͽgæPUBâ÷°"š¦3<¨ß†xÑ\X‚Wlºê­øn-“,ØJ'ˆÓÀÒ¬ºôÜz\€Ø‡pèbÅ Ã: ¿î¹ãõ#ä€n[Pû²YèàYCIÄRàfoú´øâlÕ훆ļ®°…u}úÏjÈ-”l."(° ˆ‹ ¨®A‚i\e·n60¯ö¶ÅÛ@d€5XÎɦ±ÞÐr.ôßÅ„:•ùþÝÒÓU‘¡"KZTë[öª—1+$Ó.üØ=¶šF­wG ì£ÔE|”~¸N'ÝFdhg1-–à•-Zá*°×ýüíK«€@?0¯„U9iš>“’Ésfó¼ ;/–ôNFÀ³¹þ S÷%Íå’½z ‡5&™Ÿ(¶o²g© «¹wÁGG%s»N€=P:=¤<Ç©ùÁÅ¢Ú“x×ZcLu¸š3\þQÍbØH-écÝþt$ð!$–ªAÓÔY]ú‘ÿBïy.EÞg23ÁTæQ÷k¹ R…¤gr3›)ʦBÜ.~‹7É›'ÝH€žõp5—\Æ#èÅ¥ð?ÿÔ£Ó@cOßÿžfßÖ㎠øP‰ͯ;8ZKüôžß'ò3ט+`ºuF q!C¾¬öWctÚRÉš%œCìVzõÓEB¾ßÞ:óM&|ïb\&4¯¿)]þGñ¾YR·Ãd©Ïeµu‡ WgÓ-¡€%ü7¨o?ë€ý®†ì…ÙB|¡öZ ´£Ã‰ðÎ :9òß¶êøÙGè"À€²Z";{mVYÊ]ïY§N¡NOô[hº™:/Û{TL}.Ž2”UëMâsHCB$”y{8‘yÚ¦ýÆ"19:.Fw‡EDqYûÕïËÝQëb^CW]pa `»q+ã—"¶Îô·ÄI]ÁXM—1¾áPFÞÖ„&’ü*ÛõÞê¼,êêû2Œ,ñX]§aMf„ž¹™DûäâitÏÝ…ˆej‘ñÈKÝN¡óÀãè)A[€¸£ãrrÈ-›þÂÌèr׌XÞO|£WnN„Ý¢–îi晴’,´ mâFCz§›å8š‹vGР,ìÜ=üå¶¥È9QPóY8;cØoÏrmýŽq¸ÉCN‡VìúýÜàå * 2ȇUœ@Ì­ëx»zò³í©Zô¯ƒ)®Ã. þ©„«ß°Ø[¢vùI4]Dty „K!õ^¿‡$¬¿Ã3Ãq÷ôô‘Â(ð> S÷ûÂgÓ5nô.E™ŽÒ€úÇyu±ui Ù`¦£ÿer^@b2ª?-Ò-Q9|Ä 9ï,ñ¹:‡“<×$œ´hȯ)>-rLñ6‘Ni´¬Êœy= ôJÀ»":ë[’`Ÿ„z6ºÇÓ%7ûÁŠ^'úí¨ &vÐá½Y‘Ó.WÊZÇ *³cEdJ—[½Š‡]«QÿA®AÎ'‰ khr?^w{iØö!Ãb`;I¢šs\…³|ü6åÒh<°£ëÃ$\Ñ·¥Í÷äF[> U#'º×ž2I[J°Ê‡‘ŠÿäÅà!:»<˜GÔ¥^šâ»¬+½û͉(gôyKÆ!§{›ç`UL·lM•u‹ÚÃzFÀ£¥‚`ȸúü«ÔšÛ°šk 9.j§EMŒB.hÜÇ`þa¤2?ÑÍèdKu?—S|Üš|WADÄð‹u‘/¬xï>rS€î7)ÄÁ ‰Œ“s-”ÚpŸ5Ï© W¿}eT‹ ë.76 è¹¢|PÌc4YͶÉ®«Òdÿ^VôXÐÔù¯¯úK ôç ËT¾é¾ðóI 7 š–˜FE³!xü îÁ%‚ø¸~ãÙÚàl•€?š.P&rŠ@¼¸…Û*”?~";ü[…›$,º­zt{þsuBN@ªR$‰CšÈ¯œ¯Ë1+K†Eðuª‚ä-–>cQO.> :0_Œùžð8åùŸ²g9±œG¦íšpƒ¦Q~Δ»³°m ,†v›2ÿóÓ¡®y‚6g+)`=z[—¤atPî%GN!Xæ­êpI:@MãÆv8:A8Áxêõu—ÏÄDeñ†-žª øÎÄ`\–¶kE¬½+ÄUt€tÿîå¹`ó›ú㤰zy'[€>µܽ®nk?›ñf™¥Ä,Í—: g÷Ð+i‹‡µîáân5Dâ‰6ß¾÷r ¥,wïHRÙsTm…óšO|õbç½Û1BÓO´±ðÉö+Î ÿ!p—Á”üá€Iàãï&zW\s3ÙÞ•þ$X¾Ý×l‰—µä"Ð̬6 «N: ?_Ô)&U+Ë™O2ð¢+ÒU«&Ì;uw[z_"3N×g h-¸Â1ˆGJ>Ø|!iÆGn Ò/LEÇ xïO %û;k¿ h“ 7&b”5\Ì¢Å[ÁºTäÊaƒÞd—„È|–Å4«2¢æn• ô§SXi˜dïöûßÖ›©}çÀ«eŽåÍIfÉØŸ¹® :Í+DYD›8édsòçsa&Û'§¨óR¾±m <#­1“‚öÚ·U¤¶6caJi™ä(=,ùE43¾Ã]íé°½aŽpÌ%S[(þX1Âô!êÛ{¾ÅèçWÌRp£o¦EÜÁUvññ¹ï”ò[ &O‚¯¾[ U*ùà[ßñgû.ñ~æìK£õÖ·$ûê$ãÆÄAÏß/ƒ‹¯[h7¾'õçw«Ö}–œð òPnN…ÉK2/¿xýÞžH0[¹>9…]îψӆœ°3€Ñ"5Ô‘ú+µƒàÄÈwGN›Ê=KùEìŒVkë8"Œ;)!²ŠŒö¸+µãö–7àýé†ÕbWõl3ëP s Ult ÑŠš fî¬&‰|!­w?^Yï·}ÿ¸Ùt”ß‚Y¿cö¯f ™þŠJ1bíÕÎyY1¼‘Y“ž‡ª}¾B-ì¡xl†œ#¢i©ãVDV©/߆@BËdâîzÁ•8SHÇãTh[LÔ·+ÔÔ¶A©r©‰~¾ŠËê›®’7v“\¿«F1È”çQøp:†»ÏK¾á,e=ç’miDÌ(t.½ÛØÎr8²èJ‡ùo¥E·­Lt‘|2b¥î‡Ë‡Uà<’ál ‚ø½ÍÌY¶¿ ÛèE#΋½ù4:jhOîLˆ>¢"HAþ˳ë[¹–fš¼Ær­¯hÙÄÑÄXŽy×Q™ݰîÒÂÅÍŸ.cÿYÀj£V!f• G¢ýÔŸ¾mIƒ÷€ü×ÛË$‚ûºö3bª¹åœÔ •—ßbó¹zôá {J7fÔ”gn¯l‘S=â2þ“:Ü]¶Å¼`ßΜ⑜Àˆc€gg¼ú³‚ׂÓÇ3Ž+¬85œf5Ì&BÍA'/Ž6Œ µ‰hHRùoYîaéìI—h ó µífñ×rÜ Ö ›ƒ F“!ªJ–¢2)8˱ß-ƒL'ÈݸFÒÇ‚r,˜¸=ƒÁÉØ‹×´ úIS7ʳj]MºÿBƒ‘S~ØGó~èIw™&3àÝ› êÒÔç §÷P‚°Ê# û¬×ﮋÊnëœ1Ñõ¹d™Ó_‰0f‰Nzâ’ «›FŽ«Ù±æñ%¶°ózMòvß?Ò`ܨjÅêoWäŒ+Pý£Mw.–UªxW%³dú4Ô·ß=õV«>šÍ¿ÛúmeÖk³DmO󉂜öÞ–1ISVy,Bp´3¥Ú@^Íö̸n¾·›0T+—ƒX»‘ ÷R1Z»š#Pz­û¾˜Œ²x1ê1˜-*Ôþ$ï0ɧÃ4%XúâÓV;¹£ -SÑ)´~4˜*‰ùÀÀ žÁJ6‚ í")wDÒ¯3^¸¬íÜ\†¥Ù}õÇy?sz8[¾ò©æáiFÑ€TˆQìQ÷BY“2¾4’¬“Bª9'ã cs‘ëhB©‘1m‚ëþ£ -ºíØdÄ ›J7X…  šè g“ÃI™kk–OÑh?Ê<°]Æz`ù>Z†ºïJPhÛ³T˜ ÍËb戈¼œaþñÕ¦*ø…§„ÎÚ *`±cX~këþâ ¾TY¿Õ¥—ä+Çãh¿-³x>ȸ]¾ØÂaÛ[× ,“;|ñ˜`v6(«Ä¡ÒeÝÕÞëÔf˜[ƒ“|XßÁ <âæD7ºþüÉuŒˆÌºåúÊ…*æH—4ØIñ¸Ž¬Ã*p»í Õï²Àˆ>UÞÓ¢†À{ø'ñå'²(/f²ž˜X+Ó:ôw„ù"åW~¯€÷Ñb¥YQuÇDë|äà]Ò) ÁCëÖZxDjyØ«óI|ÂÚ!MiD"•¯œ—%šïík³ s' ƒµ§»L´B“ ójë jC‚·XÑE«Úe*<<ýZ¹p†]š }ÛÙ/jq>Èt¨ßLùrHck¦·ŽÕ+äSqM#f‹w)ŸJ¡íC¡¸0ôšqâž-ô©cŒ/! åÑìxìúOå)Z.Æ6;1êšØOE¨òŒ“Bˆ>ð ÉÞ ï³ä¡5ÿØË=F¨B2—#²U\N¯(Ï7Fâ†QŠÏïÄ…ny!²ïJ™KY ™Vİ\”.íçÊUQW-õüÂr²KkCœ”D^}»qe0—E±ªÅç8Gä÷öæ2¢$Òx•Ñ?d8ÏY|Z<@Ÿ a¦ðƒÁ™Nv®ˆøèŠÇÑ•ëÀž¾1ud|}1b.Ú”kqy#«ûJñ ÅQWúb†‰Ä]í¯©‹~¢ÁÌ!Õ߆Æe|P¦1ç¼£0»Ó wžÆÄIÑo)Ô¯ï'šm³‘¬’›©I5vFÞ;g:jÄ@·mò˜Ôµ}Îèt?žpJÕñUžåÂ"ƵÝlu;vuß|õ–r9øŠ(c 7[=ðà±"æ¯Mu+_b^SfpS® ™/Ê\à ™0¼„anQŸJ`Ø’»3Ò_°êøÃg@™Üܰ¿ ¬£ñ²‚ê>dEI, RO¡ñ5Î8ZbóÜà§×‡¯’=6 Žžd6“¹ØÈ](|Q&ñÒ®í½È…ã€ÜÜhÞ­qr¢µ)nH€ Ô¨˜|·ƒqq,dK=e@°Xi¯¬I"ÊÂMCw ††•¨iêî°B BSv0{Äh+Èbæ®#Gð¦ý¶+%ÖÏ#x»~cévê`L•[-¢É¸Q^"sf9ñ Ÿ‹GzåµÉó,óÏ?§¿“÷çoŽá–¹tþY–ÒÌ*2¸;Þ-ûÁoQÕ@¯cÒØÈ7½ž÷„€!õ[ß%Ó'w½-ß BPl¦†åCÃ[Œ4ñ#úç"eð÷Ž{žÉ@XI•Êñþ<]š·Nábœ˜ÕÆÐã"‰Ò½1Pq®¶™ÔÞåµf¤¥¦¬.XO½=l÷Èëìçâø°V<QŸ?¿Éhu*Wë ’½Ñ Ú©¶4E&‘½Ìã3^Š>4¢~=%ä>ôÀ-4IázO¥mœâK¶IL%÷Ýýsø¾ó ¢ŒzîAoA}O©’3¬¦&1S‘¶OS -uùlÁÞñ=”Œ ¼"¶ÿU= xúìÏ!ÊÁJ?¬Äöhë0Úä-º ù9îѵv£GœTÀK%3¬ÈR»³<=,„æfÀþÓ!oTê×Å€\[ÂLòìáP\½oj1CAÉÎiã¯õ¸0÷T7˜ÜúÞ #^«aÕÐYw•spaåI±Ó+cg5]±Ø¡08¢%šÄ1_Vñ-&cü#/´Î˜Œ[JQ^OëÓð¦“~·Ö A]’&g¢SaµSŽ®´¾Þ¬çåHAfÀ‚C뱈y€€r³Ù'h™+•xntC¸ÎÎ l3ïk7¢¦ÉóEåÇðÛØåÅÆG¥cÔƒZ²³|lÓî{Ε«Å°èÑ~ªE"Ýe›£tï· Yõ[€¿zæÃpmŽUI—Gxör+P•¾ho©–Ѧ4tÜ[˜ò[(bk1PÁµ½p‰æ Âö9†£v0~ ›@},zêS!>ÇÃèmèä_x€ÝᇀÕgà5W1á1Yf3&ž•*QX£ƒÍ´|‘Y 1èÅüðÒОqRm`…U°ü¿E0küšAwÅß÷®I}uÖÓ¸ýÝåc(uôü´Ó@ZZû<ÅÓ ñr?¬ÊBÐu"PD56 ºÿPÏi-$žÈ„!%W´¨µ„­TÉÑâq)¯X‡1ÜõúËù‹ 3Yívs¬üŠkë‘ ¹Dz§÷nɦ&&÷ÿÒÖ+Ö÷v5IϾ0Ͼh?î¬ ‹žibGy&ùŠß’ÎRÆÊþ@ð*})5ŸÚ»¤06„¼Ì©,L**Ž?œd ýe³p¾?B·É Ñë‹Ó~Lo/+[×h!,¢0ëFg0>Á¥BLõÓ‚¾ðš v`56Ò "ê– §g€ÿóxwæoÜëü;?#‡åÅ])I aÖ2”¦"˜ÏQ¬!&ÉX—·ÊÄ㱦ÎYEWÓw%­–/Ï߇忲¾— Sª‡ ¯1©ÞŸ´¿µF9‡ûcAyø±Îáp´ú6Rß~_é „Ulòk’ø‰]ð5¶bD•,VS1ÿcàú7¡Ÿ~¡=Gˆ{ Äa-Q#šôðt´$²Þ+Ñ„WbÌåWì ‡Pò^à‚i†8¶.‹|ÐT·sÚUXYì+\%…*2Rês‚±à4Ö$©öâ7g#P7“I`ò&áØÓq–œW‹áŽŠðÈÖ÷–³Ù@Ìn~’§×õ²hº} ñòÿ±²o`÷îªëÁ›—‰ñ®Îþª=9·•‚«€Øš´N ·!œaºJAîØ¯Á.} •’‰M)n¢°øj§ëÝ5¨‘Ú2–°}3,¶ýÎtˆ”AÔb),¸Û«M#í\CJ,R¬!Î>”X,™ïQÃQŽAxf.Î 0¤(He½½If:k.£òP)‹;f0ìú=wË_mк6âQx¡/ÅùUɳìMé!*¾P=Ƥ‘²{^­ær[¸Z"ƒð€rÿF1Òæ‘F–ÄPæDÒþ.P¨|‰†~øzTÖ/¦YG›Âo“‰§ly2F&ÿÙøÃ@>¶úDgi<¬D´%È÷iÚUÐJå°K4+\l®å1iáîF6Úôh.c¢‡CŽÃ#ŒdÌÌÖœø•éft÷ŠÖ¸H…½kVe›O[ÃJ†Ê™¢Ñú‹ ί” ªÊØAzÎ’[¸íЋ»’ã”aèð@’B(w‰t™9‹BE’Ħy ’Q_â× ¿³ tæDVÒX8V€ÍÌ]QF¦”ÏwIÇà ƒhš«çÁûð ¶;i£ÝçÖò}¥~ b…Q02~7¼…ÐA¬•ÍEÊ+”¢ÞP~‚hî™ Ó‘¡¾—iy汎ÎÔ¼Fðõ}I §\aVgü®º_ÿ¡ý(¡yKxñe¯ìœ”1p/˜^ÕlCÞO,•¼Xåìd;î3Ǚȟûr6JKaª2F(Fÿ´/d"ˆëg—)]N2ÝêuY’_º®ºh¡ÁÏ0ë{+—¿zß@×›Ó>ÄÚ_¡êÓ¦7±‘ùõŽWÏMb#gåN¼§³Hl9({…§fp²„xÒ6Í›è"ÝÁBµŒpê$ßÇ,¨ PœOÑ#™hnËÃêJÑègß1(Wp’»úJꀶí`È$òˆÝJ}ҫ롼`Ö Ý$TÂ#'Q6QVr›F6éÞjå¶I<=B •¹ôÇÓÆ_jéùÜ/\ Ž[ÖΈão)öË­ç/ó燓¸"ò±æPZòta4“aQZT#M2„œ6 §™Îiúß ŸÑÊ ¨BBrõ §>¦Ì—,y»ÅcžêÙ ;a(É,C@;Ú¿o«dÔŽ$è1µS9ïN¹²n§«dÆËÁÎ!D|^¿ 1NSß0Ÿo›&Dôê¢ð¹ZrÞ¤7lëFX˜\Á}àbН3ŸSÛWXpKɦ+daÏŸB ŽÍýN"2üH˜V|n‡„ªpxÀg~ƒ_’‡ë ÆÒog¿4~™Æ™­hw(²úÛò)çÔÜÙ ‚Èoc&$ŒÅÍÈE‰¯G6K•ª˜¨L{ì'>qŒõ‘=»—LˆüB:^óî‘PÕP'~ê*òQàûs€Ruu™wÜÆtò”åªoQáÉÆü’yÊzØ*œÒ£ZJÄdyŽÓCr2}®»Õ¦§½~„{gaÁ3Õׇǚ¯.‰ç¯cû!å±(·í’l}¾„?½Ï˜#u6úÆfxìæ¹Â. !l-Ž8ßອ¡Pãï ©¥0K ~h ™YØUJUÜgé3«‘Jb„²d½HEn.Úâ®ÐmÂ7ª‡%Ð[vc€ô23ÒÓ­0Ò°Ô„í¬ÆFX³™'i?ïD ‡ñ!é²#«Àù1 l…Gm»ÕyHŸËùk]Üt¶ððMF&AÞ’´½]™w-ѧ:"@®þí1;2ZƒpF9²{–5Õž$ê´}Ù–?û{rÑM¬ÉOE³3(ÈwƒP_w@U§£‡ËíœnWíi^/–ïzÚwÚÎÑ^n¢ E„Ì÷0{-Ž|¸ ½`‹,~ªyJ7•íRxÛ|ñµûRVz¬;ÒƒrwLÃóGS?ؽ ºñ¼ár½ Ê‚¼Æ°wJ\ð->´Å[R4ôv d<à „Áûñ¦° ©Eg–1òoÇF-¶Êˆç]DœW´.xÓ¸Ûè ­ŒMÍYøa¡¶’,Û­ËÍÔH*}à—YYÜVSZÀàv+¿ÈRu•àÐk)ñfo«ÆÎâÜýtËÞŽ$ãa´×]x±1&!𠢌NXé(ýÉ´D»|‰’Vi 8|އ1ª°z©8«L}-8¶5ú±ÌåÊ;÷†ò$¨ DÙq ]³”}òbÀ'©"Ÿ¶Á?NQDÏm­œè§‚³7Ï4O ëEQ·ñVV²õ‰j6ÍPwЩà4_õ¿w‚÷7Å™ ëg™Ù\v²Q¡ÿùæ=m­YUô+©kwõZÁâÁš}ÏjÊ*¨›“D„ >_,ÇÀ\x`k3uX0 M˜˜øw/všô”`ùr^¹µž²„^ì­5Ñc^ÑIW‰""Aè‚s{6JØLô*ú/$•ÓꎄÞÔÅbrØÈ™Y— kõKò¨É‚ ãÏ£VOSÝ> T’Ýã2ÇFcW€Ô­R¬«™E´ªýôÑ^y•'~gæUêy¯U)•:B–³) ¹ù†ÞJ zÚ›Y€UeÍ6f¡'D]±ë_4]æÇOçòR×$2£`)ÚAÌ÷l,‡R3jÂàÈ®`X°UßW.áÚO}iMßÉg-÷dj`t¯o0ÉZ tt$?N7n_KC?œJï³¯Ò ÁÍ’q$}g¤–‰~H¨bavN2J¨Y†¼§ýZ´Ù] ;? b+ý`¬‚·çHýe¤"ä¼g˜WÁ5ø:&?nÉ£Šª!%*J+K¥ùr™TÑöñ‚Ž>ù™haH" 6`ëEg{Ê„ä^\†¼Î"Ç©T²•½Ýx>{¨n¨LÚù$Êop ?ï±çæ@ûbêþÌÙ¹{?sЉ… ; Ô6Ôcëȃ–Æ®Û;ßl…ƒ=}’Òh—)$jš7³[cêLb<ܱ ð{•;“ »£‹¬§‹™º­A™SáÄ8/Ó—º§¶§{@a›ˆË¥¾9tÛ\ɯ†:iÝšŒ…^Ÿ¹ónõ=ÜÁ$Ý5dìûï@Öº@5ò¥q—%|~µ-ÕhÀ¥å‘š¨µmxá÷÷G·KÜÕ7d“ÿÍüôýQtÎY?‡Ô¾ó|K¢hà# šUpˆ~hÈ? õ‡}ï2üDQY3òÖÁï)Od²%ÝÔoûë›p>œÚ(èÃY=Ç®‡ìå—JÑ¡£.kœ»p¼é·hF&FŽ\Þuü”V[¯”¶Ê|ïŒ0 ˜ñÔ¯îQpžÄÀ¾+´[EµU ûîC%5ÀŸˆ-q/é&jªN¦k¨œÌå4­Éõ¼í^ÊIu°…‘½ƒ ß"m7*M»IÛåùyGqTÛ TCÎh9›‡yÝR$“f¹Fµ“¾ö]'ò›sóvöÌ×a7ö¥òŸ¿'@GŠõ¿Å_¼Y¢IrNÞ!q^n{£3ö½Ù–ÿÔØE¦E~£§óø̇Ac!Ò E××¹÷>çcʨ𡭆-ïÓÆØ?óB–»Ú€85âýù(Y_×VëP)Ëo]gÈç5Æ•½¥ê§T/WãÉ0Êl!ì¦äBeÄn½Å¼[1äc/‹(z£ ¬$@ÒÍA×j—ÑÈä1ªqöûpc"ðE„Ëþºº.^ì ¿ÉþšÿáËbdzM#²´¸,Ï 0©û#¥ózTQ Û#€Ô¬Åmv)K$…ä’ýNçm51EÈÇѺ2Í.ñ¾M®§·>+9а¬"ìu«ÔF°¥$°àäÑÅ-_YLÔI‡›y¤ÔýÑ2½Ú3(¸J¦¬3/ƶ‘?‰¥úÒ–Vq´CÑM°^ÿãϱ8¶bœâ[ëiþB&Dîè7 Þ-^q ¯6* )l#¥¾sŠ] @ —áÇûu 8Ô‹=eÖåC]R´&mÚë'òëóœjÛä^ɘ}E6I¹¸¯‹ƒ ÓVú3)07Ì ‡Z…¤·P÷séN˜kÚ`êæÛªLì#`ÆlzBE|š#Þ¥·vË ï¾îaš9‚"Y˜ÍO‘BÞ‡ Œ¼§{)ÓA5â9í1LCøgbB{PB_Ù‘Š" m~ÚWÛßSws°_ÿY‡ k”Ì?}A+'Qò"}ò¬¨‹MÐ9н †ªžBþ^‡ÇM|˜}Zøã;ÀЊíÁ{WÞÚÊÈêæ Üñ ƒè&W÷®¸¦½'äN×ð!îƽ~5Gh[†°d$à£BdÍ*úâ„X†Å@Óy Ų<Ü“OÓk­8“úb É{LF’9x«R`€74I0ÃýàŠNÄY¼+÷ñ]\£ä7›‡—]£4/’‰à â¿£ÑËm±/*‰z¬uo~ï=ò&\@?.öË OÇQ‹\ø@?Féž­´I¬îDâOë—ù¢ú¦èæûœ[=š÷»ú}Ô¾*ÙÛ|”{”ôë#£&¼aw¢M0Ø [칖ᜠ…åó5§ïz>lKjø’"ÓÁ˜öGü>Ïh7,¬mñúaiÚ»"”sà:?.2P‹q”tÚþ©±O5*aRT~=…`-qÁ0QsùU_Éšˆñ…Chվ̬è…àÖ2áb›Å£#o,—ÓWÔÞ§JD¤ÚÆÄ„é÷¦Ü¶Ê·YdívΖ…ÌæÃ¾"|Üv¶Cõ…L.’ó0Æáò˜’d25£Óßcê]xÇEƒ]º²ç¥!~Pñ~P-’L&TÕ{!nf.å¥0[Ø?òÓcÉÜY"y#@rÍ©ÑäÀ·‡<<"¸'b•¿ƒ—›žf¥ A)øõ¡ß±4S,ÐæøÈ Sšhœx;&wÓ³––*þÌÂŤcKtP$¸¾i2}ù©ÉI¢¢Ù¦­Qĸ ØŒYèŸ$U±-Î3­Ú;T¡Æ&®'¾øþõÑ¿DÁø•x…u¥‡L³C¼>õX~Ë»W­‹¹b´O¦¤)80(ƒ ‹p¼¦»*¾¯šÊ. ŽK4¾}Yò¾äëÇ,#|•%¬¶’ºîóAGÆžGÝÒl2ahY%W©ë˜·‰/Þ3•.4 b‘Ýòº‘ŸLï®b#“z]Ìg[‡N5¬DûE q%€ê%u™Ääþ¢‚Ž .Rý›sðð!Q©#ÀEmá ü‰Há—7Z’?Tsï€Ò`óCÅÐŒå¤q€@×Q»J¶ƒ61£@%Zêrò}åüeÓv±N­ÄrÇÙÿ-|qwWɺ1ɛ𩧔 ôUÝÿ¹H°YµÆë¹i@?O˜”ñkñÛ}i–‹_ ¶ÉËv>q6 v2»ñmD®[ÅÂàºâ$x»+µø±õm*µµÖ†G/B‹šÔ—¢ciª.ÿkwÛ:dD³‚oÝ?æé×8^¿ûUcWhpx]¶yäº#Wè¼xÑSek¿O¸ºÏÈ㮨ç>üaàãÈõ{É9åÛùæ0? Z¥‘Bº:¡ÛÏmìáÁ“Àh(ï où;D¬ònÀ ÖÛÛÏš¤ð µWU2îÀµÛ j²!æ§÷ý5h¥TªDð—ê [ĸÁÊ{ö6ø<«Ý€ÂÑÔç˜&Ý÷Ì1¾ß¿UJü/¹—XŠƒû§oo@‡`°¡$mÔÔš¦h Ð{Þæ_™œm¨ŸëÒñ±Í²ÿ`|Ì r1øòÌ2’^£MiÛr—#6ˆ‘ ¥Êÿ5MÚ•S2,lejH{4æ'e .‰·®Á²¡FǬž/·XˆvÒsk$ì€ü¥’Ðeæ "sƒX¤e‰Ÿ¾’‹ »Ý×/GÌ›kL{¥<Ø~¾pj´ÞÄAO’ÌÖïÇ`w¯ð¹È‹•àÇP ”ÍœépßäS<æ–l¤(YûÊÛL|òMˆ}ªpsB-¨5^,š’g›ãv¾;•)Êö yîVeQ[´Äsù“¶ Rºb”2‘‘{L¯jt™"jÅvèíwÔÕayVcU! Äê»Oe,ZȦCõXeG÷ê/Δ#iï®qœ{Êáèç ¼X='6ü%¹\ëàsèe7|=¨„qo ô¬d?ŸL·8Ô–mÛxˆ|úDC§+b”˜|ƒ HÜ+¤yÓhòMÆ4i¹±Õw›87W­À6–¥E";XnídC†2è¬Ï;cgA¢G„ƒq|K„ æ” oL¥CëÏ•¿gþ^ëf ®ê¢E ¨²6J0g·p»cUªlçrÍD]z ÍŸºJÄ\6U,ƒ«Do ¦‘KB oŠ%†}^kÞ´KV%Gߚśåi‹Îôt§2}°Jg7(›Âá&v}æÊ#›ÉM›¢¶œaž-î%Õk“£ÌNÚNþV0<ê˜æ ïZÚ]¢ËSÔ\ «Ë­-5žp%š‘yJ’C=šÒñ:Áé‹Â‰ôSzªs½˜X m:xö¹6‹#âú=áüü®0/hÈþæÏÍ7Åì©%üÛÄÖª˜}èï¤ØòÓÛV]±°î•Ù)<ƒ‘oG‚( óäœEõíÀk¿ i¬ì­²>[dÿ¼5„Ày2šÐÑͼ­a<ªÆ×Ò7× jF‡†¶~õ%ë.ÜFÊ4<ɧuñÕÛž,ÞoTéÇzGx!Œl+iШ-×*4Á§äx8¼i €²·#Òï}£ICÆÛëbÇàÀ'2ãA´I‚ ¦Ù7òˆ…Zf^‚h äJÒkTåsòé¯ÖaÕ3“ø^Ù)îBè.£g¯Š&YËav­¦ß—Ït.õ' ºŠ!L²¸Ã“Ìgì‚F>†ú£Sö˜4='RZT³Ef+7¬æólz ([ð }H?äCçö5hÈfÔ#¿À)¸X8‹¤|¬í6—Qûÿº\Úô‹˜ë-ÈHßøÀl7âqÞR;¥8ž!b­C|Vt°‚æ°ë¤OY °µ‰Ëæ}mäoŸ¨ç_Yeñ”Gm9}A#ó¹.¡t'¹¯tÁ_H{á) D!Ùß9ª•Ø‚L¬„WïÅ6W÷vÓÕƒäê!IÊV-nº7åO|•èœK.·v0`‰‡f7Ûá/#‹•w|ïÌÁc·•š>º7ÿß ÿÌx=˜8´Ï‚8òKl%Âd¬:ð¹ñ:yU{e ×Pô+l`â|‘½ ¨¤:¾’—gm3A1iÁMF1HJ ˆ stQšeï]›èKÚä"Ã"ñ8H›mRZ&„¶Ö¢ù¤¼Û jf¬,`ÈÂ#œ>x|= Ø"€¿¤qýNOæ/(Ç º­‚]£1Ís£xC¸ {†Ò´ô{m„Cœ"xÜj²ñ?Zœ@Ç÷’ªÇ<+~ÈŸ4v&Ýÿ¶¿u'‡Òå»0ƒšŠìƒØ-ÀææY®ºõD'°šëƧk‡_Ðþ; endstream endobj 82 0 obj << /Length1 2046 /Length2 13621 /Length3 0 /Length 14864 /Filter /FlateDecode >> stream xÚ¶P\Û- îîÒ¸»‚»;o  îîîîîî.àÁ!¸‡àÁ]Gîɹ÷ÿª÷ª«º÷˜>æšsí¦ QTa2¶1‰ÛX;2°02óDä„5YXÌÌlŒÌ̬pªfŽ– ÿÈá(ÔAöf6Ö¼ÿ²±ßd¢@Ç7C9k€´“%€… ÀÂÉËÂÅËÌ `efæù¡=/@èlf cHÛXƒà(DllÝìÍ>›:¾åùÏ#€ÚˆÀÂÃÃEÿ§;@È dof´ÈMAVo€–#3£Û… æ3ut´åebrqqaZ90ÚØæ§¡¸˜9š”A {g1àÊy èojŒpUS3‡¿*6&Ž.@{àM`if²vxsq²6ÙÞ²T¤d ¶ 뿌eÿ2 üÝ #Ë?áþöþ#™õŸÎ@##+[ µ›™õg€‰™%  .ËèèêHZÿa´t°yó:Í,†o–ˆ )€o ÿæç`dofëèÀè`fùG¦?¼µYÌÚXÄÆÊ díè÷G}¢fö £·¾»1ý}¸Ö6.ÖÿA&fÖÆ&Ð0v²eR³6³sI‰þmó&‚û-û rp033sqò@v«‘)Ó TÝlA*Yþ¿qðò°µ±˜¼Ñy™™€Þ~à<€Î €£½ÈËãߊÿFp,,c3#G€!è³™5ÜïèobÉ_øíüíÍ\ÚÌoãÇ`þãóÏ“îÛ„ÛX[ºý6ÿóˆ™4•4……Eèþ¦üRXØÆàÁÀÁ``å`°°°ñ¸8˜^ÿGhöwÌ¿}¥¬Ml<•ûÖ§ÿ”ìü÷ Pÿ½ 4€ÿŽ%oó6¹ õïA×aæ`6zûbù÷?]þÿ¦ü(ÿ×AÿߊÄ,-ÿÔSÿeðÿÑ­Ì,Ýþ¶x›\'Ç·-³yÛëÿ5ÕýµºÂ6–Æÿ«“r¾í‚õgËÚhæ næ 2V4s42ýk\þ’«ý±h–fÖ E³?® 3óÿèÞ¶ËÈâíúpx›É?U ·åùï”bÖF6Æl+'hotƒc~%V€ËÛ:ƒ\ÿœb£µã› àœÀÄÆîåä0 ý!ú q˜„#.“ÈoÄ `ýxLbÿ .6“Ô?ˆ›À¤ø½éT~#v“êoô–]íÄó–ø½å3üÞòýƒþè“ñ¿ € ô|kÓ_‡ô+€ÉÄì·ÛÐù_èmœìÿñÍäó¿à[Ù¦ÿ@ö·²MÝlMß.Çßo2³Á7.ÿ‚od,ÿߨXý†,ol~‡âxsµ~;üéßèÙüÎþæló_ê·êm«ßØÛ¾-–Í¿úÃòVþ¿È±¼Õêð;ßäü/2oæo÷Ï?!ß*r°:˜þ+Ä[–ßý}Ûk&GS{п:úFÉÑÅæ_o1œþßâü/øÆÉå_Çõæíú/øÞíOø_³oädoÿöøóvz[Œÿà?_7 +ÈniÞÆèC y}`Ç]­¾ ÃÎÄÇŠT%û¯NHÐI45™þ?ío„’†{QV·Ä¨¯—‰Ÿ=ŽÚ¡C¾$(µ?z>éÇ)Oí´Ã-Nb |/<jøFKÀ *¸ëùlç©îgñ¾ ¼Kš"×ΉI1ýÎ¥_µá[ùÊXðüŽÒn § üSù4C”Z¤Ž_É,EžaÖ)”#! -Ú™+òìõÍ ZÎ÷Wbé8:8¯ã(¶"­uÖèû9÷•ª¬ݸä¸Z8„ï¯ÑƦ(=„÷“¥±-¾pÎÅt™•Ùôð:÷'T‰¯yÌà4Ý>öŸ*Âyj0†òÁ±„Ëò¸¤Ôçüž!çwr5^Û2”u›2yú!µ´2­<°mCêbý†ý¥t¬‚åÁ‚½­ÓwNnrq™upŸMd2ì!ç!’:üú_½a–ŒŸDgTu#ƒ¿ÿH=Bµ¼Kì—ÒcR€øÄTd¤‘ š:øŒ[Ê 0ò <@­ƒ\øe=¢iº+ý‰Üö =d’”põ’§!Rð‘Kë«,s5V—îÈ„£­6‹eÕÄÐIûs«{½ƒ|)Q]T‹¡&¹§:mVcY&Ù¶©á4¿µ9Ï[Õé¶èl^á¨3®’äÞÀ˜AÉÅ^°y°:Ýõ šþãºÑruql£]¶olµ£¸ƒÜßàMõ!O ,Û1÷„¬abÓwšü[nä»g»xÏòJ´ÓÈÇsŒy'ÍŒ0çÓÌŸEåX· Æ8ì«ec.y p¶ ‡Ö«:ǽ×_ŒrÑä `K×ÃÐILxôùk¼`Ä Ënªø!wSÑ“šS¡w`Ø:¹ÝAïÔ`è¤qN ïq-Pqøøé%½«õ*†ÀÕøk¼QÑÖ¼i x°“%r0ôé¾Ï†@¥°ÞuÄZ¥›íÞOd±€Ù×%•_}ãת8[ø=ν©¨nµ EfU¼šJ/ åü‚—xÏSìüÑT¬[_“zÀ-6Xþ.šš¯dÛ˜cž/M“½²$æ AS$ªVŒHú&º¢³EgqVW3çK2QcuÆÓ’%mëì>ï'‚&~Ûa®›¤VÙ/ƒ‹ZÙƒ"Þ ƒ–×÷וáhíÆi,…ã¼L~€Ï$ôƒp_W½¢ò”&èΠyØÔ=IJQ–óGÕMÍ›ˆ\`$ˆß»ÙÑmìVœ#NK7&ùABÁî:ßš3ÙOÎ-gh*¢Ð°×šÌÓ)Øjê‡:z8’µc”µÈùLsEÖ\R¿Ÿ?²+ ¡'º˜vùHÞ³™‰yú7i#Y»ß&)cÞ‘Î<½×Ëe÷@ê·uWfÒ¸?@b€m÷+êKAî6%X™&”ƒL.¨:Z}÷´í2ZJ`³æE˜Ôòo ¿R–ï¬Ð MÁº0Ò±7¯ñO·¦~$« ÊÐj¼ë «q„Ðfþš8oH8QRp©esVf’[ÓÏï*R–¿f»ãð¾8«MBÖwI¡È”ÿ2gÆ&êjæ(·4 ¯lYúÙ4ŽÜ14î#'ÎH¯.zô¼•)”<À@tºGûë`ß”ÓÅCÙˆïãZµ³WƲ"˜HÑO˜iÚpO¡…”c™º«*¿ª¨’ëûÂo[ÞdQ>ú¨´Áº„ÙM:fg$˜÷Òãf™#v£©VÒ™€É×ÜP7Z•{p$¯›03 uN` 8ö¹U}°3Š»–¾žìܳü¡²]ú É -×°“¬BÇÄGCŸqïÓ'ýÒ°Ï"þR|çEðªî%'^N²Ér‹¾å¤\Ù23ðïOo÷Ú/¶ƒp»)"<..b =s hˆzEƒ Øò–v“dÈ“p1 öaÓ:ôl>õéÉÓ?ú²D±Û×g”_ÊzU›}ÇŒê +Xã(üžÜDuäQUx$Ï”¢:æ²ìM®$Jôžt88B’ȶ–œ1µƒ>}o¤ÁÜÃ’ÙV)Ò#hô¶nK«’ÃÓ|¤ç¦,à"“¿¤üH‚×sdÒ@ó[tûÞåÓÕSsYÉÞª$ãA³ôq,HC´Ã˜¿Ýt¸¬•a»”„gÈBTŒ—}5Œñ¬¼!³…$åì’‰B’%VÔýénˆTœ£l4}ëõêwBC-»(c¢ÀŠü£Úos@-?Û¨[ÃÐzýjï“yá„ \Ñæ©ja‰Åÿ…j½^òdagÊŸ!‘æ¾ëÑ©®Û‰Ã²Ñøz›½é Õ½ÌHÖ!$ëNUJ›²Òyï)h7R@#Lþ.B“ö b­<¤Ù¯SY“KñY¦ø°±D”‰1}à8Iî*â¦ð¡£îµ»¿ÎWì ÈʵDe¦4{ö£ý#,¹‡Òd¬9°ŒqŸ¡_ ªhÝ ŸF­nÅq"Û!ðè……æbû!ÅX`à0ò„lÃ{üopß0QË#VoÙ$¼ŠTÁq÷¨Ò—ób¬»É†ôøßÅLçÎSå2d´Bø®ù®ŠßuºÈ)¨ÆÖˆ:H§Ž*ái|è ð€†}ôûªºÖÙrÅZ­ŽW-ïðs:úñÙ§“B8`Ù4òb…œ`~ã’?g7ïÒæ@&e™T2ë{ Ò,r. µ‚uB¥Tmœ‹JºŽºùW;á`ÆÔE•‹¢ÔØ[FË\¥Ypóaq óœRÅF8–ÓvwCÖáê: ß59:+™–À¶AzÒU&6ï‚þš7É\ùL\=UGmö”)|Ãw×­“ ¤…› ­wÁ_9…˜zM»1”ÅyjsTç€ûü¡‹Œ3ùm΂žðÜdÍ$0/9&2g¾­Ì¿AÑ_¬‰§äú;¹|{à2_þsék(©¹&d»¦Ãûg9{¼ÅC±šÆã¬9Ù'Ò}’cZº p5¡°¸ï#ïèØÐº·\¹’Ï9Éð»^$—áC·È†ÐŸá‡“†Š°# ó[™~Jt5¬’$ouÊt 7¶æÈoì?vÒŒ Ä2ãÝòDóeØ  «¡-qU3ær”má7o)KÒŠx€¤8ê$è[”„®¨,ŸwKŽ*íR-’>&G2´X:‚£j:~HjÿªNß¾ÿ¢â,8]`vÐì²7íFölœþú®wôW0 …ÃÈOï ÷ û°»]êè_Ëp¼;@Ö/…Sè««A¹;[9óÙ0‚õ¼y–•߀»ÜûK_¦ÕÃMÚ¯¤Q;òV;ŠÆ¤Àù ÚN£N¯u?0\aAIx©=n7lš-œ¨~¹d <פ¸ù‰¦®Ùö5²a´%ô{IÑ®5b ‹|çwHWЇì`OA{âÝLª3ÛËU× dižV?»7¤ ‘±g66Œâ}9Æ}ËY3a—Ы´ˆ§öØëç]…ƒIkzYÓeI·,â%ùÍ `Öå<™ß:СMäû„? è79dd¨ÔcgíÒKÝÌÀëΧÆì_Ú(/ÄÙpŸ>£å­EPæËy-®”±åˆZ ™DéäØ;óÿ<ÿpkÖ&„¯ßy† g#®?•fdq-Ÿ1qGlmÿༀ9GÚž´’¿MNv‚Èy?åñò æ©bo³ºYGÜùZíXƒ¾Ë×òŽÂRûsã,ÊI9§wšü,æ*i|¼ž…¥Hý/7ä/«/Ä4“ÖÍsâ™ L`r(inU>ó{Þ—Zv_OÊ–‰Í¤òƒüÈ‹sDFU3h]Ê¿é>–ï%Ó\›å€ƒ;²ke$«ƒÍêZí„ù©Ï€Å-+<&øùV_wÐ|3{iƒ» `x'­6«mR«ªÉ5ËĈd‚á£JkÊõ‹[.Ÿýû!¬û>ïÖXÆù‹•½óu†âU4"|.Œ¡¯ëEû–þm{ñ¨l_k¼[EpyB@íÕwä)eA&“#%‘s¯ ã‘n˜¡…ïÅ-û†’š÷ìíÏ9S±×í‘&Š6-'¾]r3tzTô©H§œúL+¦‹ãÿ†™Â¦ÒÇÌ÷T¼¦_N¤CÜá§‚Ãçš·Ã7æÍ±aK×¼Ý3d=ì„tÀ”§MÉi"xÝåU¤e¸˜ëe÷'Æ6ÇÑL«NzOÊh½Â|Pd†Œñ‡’VÄò¦æ÷æÙ¤ì+ZsîÙÔ{%… €ì¤ù¢É±‡ÿÑô½ü´?Pe±¾Œ"ŠrsÞŠeõ³³Àž/;g—ŸäMÖÉËe“üÕsyþ¦;aéWŒ¥Nï;…mQàŽyân» ;×甿<.]”´é´Â¥ãóíZáèÚ6ámYYÓÿ4—³3‘B°‚/U– ¬Qƒ¨jü„TÃÝ›~'„]Zðš%ƒ΋¯Û_(LRþ [^ÀW3ü×Õ‚ãE·ŸâPoŠÀ9“aþ…‘r£_ð†u mÀÖEzw8ñª<²“¾jÖa:K31å)-$¨P^²ÄIÊóú>îuž¹¬‰ž<Ö[ú¬ª¢—³ZÍåZTláчpòìâè£xLßq.ò”6i+3êÖ3|Úµ–‡‡TßÕ1c  ÷è U³lcϸ>â³1¢w»O¬áÖ¾ŒÆlÅ‘Z®{ðøM~Ĉ|Vpþ ½`tj»÷Î’¿ùi¯jÃh« ¸’ŽÉR8wÊã½{Ð-Ãn.|§mÆÁWwYv‹{,–ÓcÞdîñÀ¡SÑóXhÙÙ Ö`…á`ˆDÔžÒ#qâ.{^¨áî×k³–yܵŽíìz\é7„¿ ·eV‡v7õuêªXåVPl&e£ #³ãMeQ,ŠÉÙõÜì%WT´å”uºœËŽ&_&¼ç0b×]^ëÙš +Yû¯çèdçZÞ»ä}mѬ…ý¹·T ˜Xt‘ÕÕìyºsUX!}¯vºk¹¿ßÆʧ Á–Ôu{Yì–nªb¶Q^ƒ"!.‘oM:ýÝÔNe2‰m!õ~GÝpÑ5cÄÎFØyfßMZ?§Ÿ+îW†Ûصþ©µøGöŸ¦NŠëåÃksš).§p?À] á©iRšŽ‡rÆ.*tî]>¬ÏjL°Öé-ãÜÅ‚#¹KÔœ<Ìäs§'*žŸÝL¾ê«¼’.ñ?2~6¸Áæ”Øƒ{:N"z2ÖC™Ù”úÅ‹ó5Äâ±Í¦=i½ù±)Oµ¦¥ç2ó# ¢Ï#ƒR¬*’7ßâ#9ìÿ<@¸´®Eʳ( .Ç{n9£ÆD¦Ì̵sêÞcÕÔ €Ÿa{Xjð¶:±€S.`(òiÙ²o—¬;rH^[~Ò*Ù©,g„Ð}éÑÅÎç#iÆ4¥ôyf˜hKb–[®³­øhÿ q@úÆ€*ùð鹤=™~ßx*D粋Ó&*õ¤fv±{¿ O¬—LbNeɤ±ÄMЗKS;%úÀMƒŠ³]Z¨ôQâZšé<¹·a4Iã¦W.â–/„œL¼P‹ïM.ngb\œÆXµ¸RÞo„J$VB‹¢© 4ÖÄî²sÛsºZY8wÎò¯FN]½ÛÄ3©±¾ŽÊ„'ä Úte¾žŸ›Í¤¿xßyO¤ÝÁPV=/5©Â&‚ÉâËó4Hx¤N|æ1=,·S7½Âu½™yµç)7mý>´K¸Y`ýuš^Æ›ouÔ5uÓÉ (Ov®d„Í=i}Ož¬­_ìß[õåÅ%8LM»GÎxïäH©3íeͤ1 z²É…÷DzQ$JÝ}¹/2h[8㮟6õäz§Ý%ŒÛ®e J8Iê)ˆdÖl×ãèÓ·¬m{°ˆd½5Dé<FŒ5$8«ëÝX  +0 5Ù!e$ŠêÉúO¹¦öØæì±PPâØI­'„’¥/—Ðð¡’6ˆ1?0zƒÇˆÊÌ®ÚøkO~(p1t½ì8 y ìÕ`²JêéÀO[ï`qü……!‚í¬ Ç!7wF§Çy»øýÖ4û['I£ŠÔº¬jk1¶ÿ«›?ƒ) :tùl cD¨®aµ³ý‡¯aWu›_Ücbñ¿(lg6µY¡tL±åØQÓ)²Â—^E¦-\Ñeèb<†9 &Gp¤B€#ÓÈZú¥Ëéi[b¶úŽÇõ·±:!ˆ¡ ú½˜vW4±¡‡]î-·˜H…ê½ á©›Uœw“.¾é© Y•ïw(ªéÖ´10èÊ aÌÿjŽEÔà±ýܧk%›Kù\ÙxV4å{hP —Ã¥F•%f"áç}{oêÃÆr8º1sF©ì‰DúþCÏë®çñy‰q¿F ´V¹¼_É´;®½(fìÅÕÒ«–ú;ÝÕˆ"ÿº<âÝ¢“—MQ4ÙV6.}eL޹c•ê:XM|žzx&£0zÛ—&þ§×÷}Úˆ3/ßóœ(ƒæUSu Oh6Z*ë¬Û“s‹áÍæ^¸qëÒüõîNß3Bq߬nãF{<|K_ýÙÌU_BA§Œ‚oÃvÃwcŒÓ~øµÔ¥S©’ý 7+Ø]8úÙ§E”ÑLm«~`aàØšOåoMð‹ÊEƒdüÞõ=/ãÃPÿgÐU³OR‚ÜYRÂbf£Ý…ÓkìØ½Z¾ˆó$)öc(£³P¬ dÅ€¹Æ &¯ü"­:Õ“õœ@Iœ•ÿHÐy¥‹8ÐÓÑ(o—Â,”ü2üAÜÀ}yÛð(äÔÒþnYsqøÆ* !€×Ÿ+6´Œç,/4t¨:ºch»ÜB$×ë°4»r} ×t 0“jÐý"^,á•fI „T°·-NŒÒj¨duN/"Œ¹˜žÍùids*, œ±4ºå+=–«{9Yð¡>_Áy– ByÒK]jíà©.çƒgKŒê^P:Ó^ÍtXfÛA¤ø6~wq€Mé‚JQ 9T„³Ì7ù¦õlßls]/BbpäŽöƒµÀøDs¶ Üã"ªÔWEOK¾ôÒàmk"é×!¤rà#©Š´¬áÃg*¬Ãí]XþSX¸Ñ'ã3çrT¬ôŒû(XÄmè FCÇÌÒC‡(_$g̼5‰(% ÄX9=ðÉ•|GDRÜcM Ï×ó™¤ü4ãB†%”àfÃý$H™W^žp9r¼ÈÆ šÁ™!s"eðàG­ÏX92þx,ÔB8póÑ`Öq ´2Òú\x 4¤.¸ï1zÈ¡u²”ãéP9V(ªõOçÜ]æÏqõ#u`«Dö€P¸JG]#T±ÎëóoÇ/æ¿$;) &™mñ–Â✛kyfٕÊ'£ õ‚±æLgØ­œ'Ômé¬È¨œ†Qš®zäÞnLÝÌÿ`®¤áêG¨&/äd‰dQ:fò8ÁÒ5Úk]àÂr8ðy÷ëÁÞÉ£Aå=¾”Âç\…#… È=HTš=¢ÝôŠºg}¤’tÔè uŽÐ©‡Üf?öA>ÚY)¼áê_=.Ò‘ ÛºMñ†Í«ØÏƃ‚½‡v`».¼!Ì ›¶¿~jVÂ!yu^*TJnwÆ®¼ïýj ƒÞ…¥w~úÒYÌ¢m žé1N]Hx'2¨x„KæÒ #˜Ù{Sè^ÿBsÖƒ2ÀP)sÌßN$ÿª¹ÊñË ¨®AËn3Ç]X¶èÿ™”­ÈF½f§>(î©s»­§Ç¹*Ž|†¡4——¬$4ŸÂQð©]ÕÒA·¶îŒû¯‘k4¯ë€Îbnˆ³t¦l=¬[)ÖvAõÎä Ae±~`Ô—KPÃcJžöë£u«Â¦ŠK€Ã–·pqÕMÞðÕ)ÆX(ÙÅèýŠL¼ûN6mw—·"u~N©DˆÈ6Uiß÷(%pýÈìXÎí‚åé^#Kä—ˆñΨg'O: &¥¥åʳëLøS¡þ…&2tg¥Z%™ÂÜC KÞÖ "k‘®‰pË£é}4C©âÅíÞé:/(–äQãaжÛ&ú97’ðaõë¢ðbíÑzaUõ«àw#½A Yùý²`<èîWêˆeKcJ@ªÄsor¢*÷'Û‘5ïr­þÉPZÇ ~ñAšµÎJ_)Š ± ÔµzÐýqm­/åªîæ†:ᦙpÂÌ­Õ©¤þb†KLÿî÷Þ,0S]IlÕwnŽËæ!Ç>%rkc3*ØýÜEŠ6I>‹…gp0¾O/™èÓºÊÎ[|Ï*^³ù+å„`ãÌ)Ùñ¸[Or#ï]¼Îyö£¹Œk˜9ÜS²0nŽÖ¬ä‚}hj&Üc¾1è|fª—Š9õ!íçÉIb 8HøÇîÓF.„õx0ä½tަ¡xTÚÚ¢-Y¦/nUdÙ‹2µsÑ´§¡ïØTѤkb÷ip÷SþËË+MýÚyùR¡tìyê)·•®Ñ‹ÀÖa6øaRÛ ìÑ@âu²6Q]_8õ!ÔòxíÜSPFYYa\Öñf —‹0ˆ(~kª€oÔ‘(.ì|=;¾$_…(è¼/œÎ2ÀìÓê‚J]¢±Y¾K rå!|ØTÉwcAUœÇâ±ú‰ìD=,[0öƒ¹ÑðØa‹Õ6Úäðf­ ;±Y›_ Æ‹‰úØ ûPj׎Þ.SÆ$ÔÓCÌ·7¬H3üþF˜0¿Œ{bZ÷d]›ìèì(!ö™~õlZAjìJ|ò"(`VÂz® Ĩ ¿+PèöãïuSWŽ‘ç-±^Æ„cRš—ï&r_Ýx63•ûså?|›±mdW¼`÷ æZù|¥eÕ(ˆV¼"óEýŠT;×RŒ†âfr ®3ç­Iu9X>g kïdÛè#Žù™‰ÖÃßZÍUê:â¼!Õ;DB0n ûÛ³üÈH¶Ÿóƒ].¤é!¸ú„¬=ÜdòÎ]r|)U­Ïû”¶5% 9Žö8Ÿêrdo§|QÑl~Fåéž¹6ð²Û' °¤\q|ž·AMËxŸœ€!‰˜ÍðRm™’ÌÊ6ù=[W_›bÆB[(jíö‡À~Õ;§Âö™i8œÙÕ /±úº7∙òÞÒ2‚äÙʸ‡ù¨qÌð³ß8XاÎâµ]úx·§ŠùLjYnÉu[l"°Ó=2LÌ!’|Çâ™t’à=ëç®O¨ù¹ã‡íÓ×ÄÌÂ^ºˆöðsã]OyòúWTBD®uUéÞlxÚŒ­wÌ­4ãxàO˜"YiærÛm0EV²¡Csà “D@Ëø#WÀfhM›×ëH$› ¦8—ÜhËŸÊÉŠi0Ý:߃ËÖñûXT>Xñ+g©p¸ qo¦¼ž³8cýHìëE߸Ôî[Î]¢ãq¾Ž¸¿â€þz0„%`AéÓ…Wuý(ÅaÐBa¼ 1—Z•€|´\³&µ%§½eÁÄ©ü£y7åXÿ6ùšÇ­L™Bײýj›Òß–{nsõÞkŠHŒöHÃòŸ 3—G†ÀwÏ…ÑIt6E¨ÇTÞU³½™R2hË\Æ/UGWÆâBzб~ÖˆtÙ Ôg©¯6-LyÈÎT+«þ#xÝS(ÉáeP.¶aÏåW Í̵AèìæA&HÏ, ˆã†_rÞ•CÅ…ã ñÚÒI² çä]|13["yzÏ\ª,î¾ ).é+¹Uä/N¡ ‹†œÝšß äCÇ­¢¸#ö.‡*œ«s/'³°#l)Šy¤Ý™Ý¤D¥‹Ÿ³ÇÁ>;%FE¼Ç:þbd„ÌÁytÃ㎖ìÊ;ÄkjÛŽ²vöb­%tN+#©™³ØbºnòMö ¨@oM¬ºdœÕ2)5©{‘DÙ EZ”ü¼<äg4ET»yG1½ÑŸ,çê›$(ò“/ÿþ’XnCǼDôüÚU¸< 0±+DŠÆŠ»!•z›ß°æ[ùmî¾¹\anÈqÅ5ßÀ{ß±ï6)´4ò·…PVþñˆ†­kˆÒV„c9~X¬ª¨÷p]9%쟫¡ ·;Ï^Ñr)2yoloÎgêõj&’ÅgÜ„GήH²…‰µ¤2rÔ.Cö¾g—Z§Ô~xïg:ql^%-¬­¤¦ÃõU9YK;xùb~4­Tu 8YË'sñ*¾f†æèv†«i^”ø]/l¬yp`KAGZˆY§0ß“„çSßFÝ?¡ P¤ð­åšÏÀÞ¹É`ƒ®úô±  ¸:¯ùÌ’û‰ï. p/³—G q—•‡ã|›DÏUùD¹MyZ«úUG(d-t€Ã!¬²(’zÍh`ÛNXKøjÒáç¾k)rÅÚ–P~ýpäç¬ñ ’ Ñëñ)- ¨ØÜŠ WÄòocÄD.5+Mo^œ­…@>_)bNo^9lí¤ì.O´ˆ§M`j Ø•¶ãj÷å87ê{x"ÐØG‡„7Чü‘ þ3F©šÇ8|›48zØÉÜÞ/ÙÛIB°–˜œÏ¾ö­ ×“ZVv}Z\‚Òú >ƒ æ$½rÌñÚôô®Šô½… “4V ‰¿i÷i:p8M¸âúf=Wˆ°&ü]3 •†Täû#˜Ô;9)LU…J<Ö#¢)8’ Àâϵ)>°]ýnvyKÒP #ã)דÁÔY„·ûÝ.j‰Æ¥®·¹¸&h©ë¶TUÍkÊm(²+ó>r;ƒŽ»˜uÜ JN/A=q.ëW^’É_[½ƒ~}ÿ¹gø}«®¦oè‰~È>¦tIöæ‘}4¶® ÉÕFÆ¡G›”€gçl}°”zVUGØ»œf¢,Œ!™.Ê—‰8ù%óKBá±ÏÂ°Š‹|P/5äÅør²ó£ «„Žªy*䦜f sNÀ,lp•£A½A<ê·+€(™¦ˆd³ËoÓGg#_/¶ Þ0g2²Ô„„Œáþˆ-jšŒ¡!æãüÜÍŠtñ¥^±VàóÕ+†‰@÷Úxí:æ5PŽ?+®:÷yVáKÊ àÃìš0{=úšP`È~B`µØó95¥R|žlZQÛdB%¬k‡ëÅr• þ¬c0)>‘ìIÕˆ Üè œ8?cvDáRé ]¿žŸêÏS3Íù¼H¾7Ø^ø¤hOúðâþÌ“Ù[ýÓlfJèÛ¯Ì, 2„:ŸH âÖ Ð«S³00¹­êDŸU£SXïæ±„?Jõ&Ñ¥’~}u^>ŸïˆÏSÁÍ^¹®’iz:=“µí½¡[ÙÔºžt糦ßî/\ü)»õýÀ'ŒþB—²–5q­¾“e5_‹l*XÔ8o”)SZx‹Z¨!ô¹D¥mô˜æ=5ù.35@°E+H ™}(®¡±›|Gnhc–³zš]´ùq:¸o1îtíGåR°R,YX-¿=í3 ™A!á;ôsz­·Tc\Áj:óESöØñZ?씢'^]OĪü”TrnŒÒžòFèëV£p$“:Û==Dí\ŽÌ¦QÖb|ýmšV·Yh7x~$ì^X¸ž/YdµÎ$é·¥¶f?¥>!‚en]¸Š¹“ž~Ü`H€zez¸´\¬¡J¤unœ&"áÅS÷¥¡0BÎþ„´øWß’…O£66`ß `é·‚c®ÔœÑ”áHÛ1×fwåÝìñkˆ8ø®öãZ–EoðQðL—œë#?@tóÜ Mâú§¿s=Ö¶‡÷.DÍgΑkl€eç“OȯÐQ„p÷}¼ÉãÔ×ÖFt]OŠÌ¸‡Ã<: J7mqÏÚ±|ä(Ý*nioq¥­Or“Ú.Õ¸ò¹€ÎvÞd«â“SºË(§æÀ¿F$½+¤ˆšN=×>8ð.z_û”%¨â÷jÓQ¼`Àô´ú`EÑNôïZ‡0 üeSA_q Ÿ¾ëÃ^sÓC;íi*±n[ô<‰È OŠ„uÏìkú©a¡SèÆX›Zå:áPÊf3´í~³/Ë‘îÁ×äÜ× Š}¿ä½>JÉ—1K] ofg¢)àðP¼©¾±U”?¬fNÓ¼`ñ—…}¤œ ÉÓ’ˆ=³ zê“_ª æ‚=!?e“]ÛÆ vÂÆíÎ2]ˆÌÕ÷sˆD»ãpFÒ÷ûö¥îœ†Ž Ř®†,¡îOò/\Gh}M»`-Ár–'Þ a.=k«€µ,"­Þâç¿íkZ+LPÒUÆ 2¶ˆ¼¦]¾ÃâͨJzY¤7IºóqÔÉo¹-^äLIcîc3¶p\ž~`ÑÞ‘MéÖ•Ã'üö$6ï„¢“(ø×Õ¾ýEáÊáèÑÜøoyvæÜ10Ü}1-Ñð÷Žrë4êÛX¡Ÿ´¨˜ºk‹p{𻑸‡éJäG /C½ë<ȸô†TŒíÅU=£cH  L.~*µ^s·”õ’d!'ÊTBÅXÆ]ày^/¿£É¾orë£^¤ÂCƒ›œ{ !cé”c×øäðOµi)…={7ÌÆ—WLýì¶ïî¹Ï%R"Yê?Úß~ ÔѲyDšzZ¡ÙÕ[aÀnèÚcéÝæ\„IxǨw7—§Ð')øœçp8ð*-ò´*Ý¿†ý UÇ?Ôþí;ÁÇq>¦¹ï¡×¾)[êM—&/ë «+ÉHôb¬föw„@/èÃxC·"0lÍ}¯ÞSXš¿¨dT›.Ý!Ô#l”Ç¡šum ÿ)-‡r¢C†ˆhJFyX‹ÙÐ6W¤‹‹™êÌDß“ýK t ÊyÀ™ÌجÌ8Íì*³ÃR4[:$&tÙËO§À»vÈ\ݱ´ïØZ%?vòèÃQGˆñ0fØ›T¹%„_¥Dž»¿Êø‹õ³ùiì4Õúý„¤]ʡٚѸÍZÏC ‘ öé&¶½€¼¹¨ïãÃÝ&ÍÐ@c–û‹¸´ ÖXu¤’0nAX^B°R'Ïx„ePÞø@*‘Ð0>$U$¾ºc<1Rq>UÔ9jÅüǽØ8Wø-Ðj5rUßkQ¼ã|±<8“3ÊbùeæQZ÷t"ßÐÁV8Œz ö±\©6Ô;h<5j=…ª}/”|Ñõ}›£™ó„ec+§}«šôgYÑ^ÎÂzÆø”–U“c¹×óì[Ú-„£½œšeç0Ž\Òâê†ïq³æ4+Ö~¹œ µ×ô›rƦ1Zž,lï³/|©–w^*ÉÊ60¢Ûˆ‹½€Óe ¸s~…‹²Üøñ¨!Q|¤¬Îcï™4'ø£U‹{ °:‡³ç“ɯÄiĹõɽÄÉEd^†}òdÁðÝ-æ:ÇèÏ 0í{BlýçVå{+€áói+FϦ î„Ñ)Ï ¼•–Þ !µ-Ô¬Ó5â}sS¦1ã$6š-u7ÕíŽ ß4Ó­‡c•8K¹D胺èºk}½h˜$R˜’02]úNÐëízΘáÓ4€GScžû)*~NFi Î÷WkNf¥3Í¥—ð¨K í§b5ΧïPÔ‚÷¥x`h)åžý$JkÜ>—Ïú­5@¿rµ¦G•ëØîzVA›Ƀ(DJ{$Wr¬U#‘:š¤†9ä¼é ÿq älKôõƒw)*-mC›ª[ÙøÎÈÞ¾¤’Ü©Pˆå›‰`œö ¦"¼2Ð À h\mgà'K„óËÜûÐKKj¡œHö5´™È>u•’¶hKkÙ…^Ñúr0ŠœhÂjïzap\áÝqDõ{Îx%Ì­¦ÏF¼PZÊlÊЂ–™­`NýÀ·|kSA¿äRÌ£ÓÔC5äƒpï?žR21»ƒ®cùDXú6FÎqÀ‡)q]OïÜçõvÊd=5 QÑË/Ëpô­Šr„Ӡ̾ÊyqµNûù¸ÊïÆÍW‹!– ¦bÎ1é!s G{RTF‹ÈÙú…Š‚ʵƒÖL¿¡¤ˆÄ ¯uóv§-IPýz6(•Í· }éÁ4/\´ç°õ¦Ä„}þºT=‹³“êƒjYŠœiã·Ý:/5×]„Ôñ ‡ˆuEjüHn¾O ¸]l†éŒ"±]Ü´1þi° —XRBP®a6Ú? ŠxÎ×W*=¶Qí°ÅÉ«_p( âBÛ–ðoû°4ÆN¯ÑáÅ3P•J&?H`eÓ¢Eå:å¾à¬}… õÁ-.ÐB°¤½&]¬}F«Ò×hÆpЩ®jŠÿ²Ç™c{Í?¶ÅÚ(}ôì7eÿµIôéû%ügî2x ¯@4È$`~“q =ÉAÀðbheíA\SYŒàWUzoô\¥w±ÿ‘ׯ³{&$»ì`{Ú°gMÕfên‰ uÅ!ÔVfcfœ×0\¿H}‚Ї!|ÑàáÇvçìÎj_1cš%lôPˆ–É©OE §¼)»9¥ŠÁþ •µÜIaá.½ ꜖.+¡¿ùžÝÊ •Cù»sÎâz…{ÄE¼ð¾“ÄpÅ’‹“õTç6aé£.5Wæ—o¨ÑÆ2:žÞßó*ȶ&iBÒ•^hêî!ó¿1 ÏÁUÒž †+½²U†î6ìÔÓøLeF.Çr»ögv'sÌqvKÊ›‰ðìÚèã'‡5Ì`ž‹¸ÁQû|µ’kp<Ô–ább ê ž2¦ªQû’«§z㵈z81aûve:ÀA>òµa…öãøšJlÛÕÕÕR?Ç}–\ìX¨«¡R^>¤ÎŒ®2¼ Ë<9ÜÅlK’ìÃÑɵ1¦2®Ý¥PW/cZX®€¨h ƒ~§d¢××J¿¹= â3¾Ù,h\êòV”jN] ‡håÈo³ïžênØòå¯â¶â1¼[cû2¼Ïš™æqçè-œ½m;¤×å×7UJÙæå–¤˜‡wySì4Oüðò‘„õcÜVB¥³7¤+ Ê ŽX{Nˆ…`²%©ÄŠÓlçé”bk1‡ƒˆ¼DŒT'æéD"[hs´ŠBö埑ò;­8$¡‚æ‘HÓéðû[§†œÅú¦Ï½¬icT­½Ét˜ç~ó§Ì¹½ʱ˜ý›šeuýc¦x²«%^ß­‡> stream xÚ¶TÓï6N·tçè†Ñ)Jw7Rc ±Á "H—‚ˆ€”4HH§H7ˆ4"RJ¾Óoè÷÷ÿŸó¾gçlŸë®ç¾žçºŸÏ8Y Œá58 )("”(ëjš˜ˆ@ ˜(JÀÉiEºCþupšAÞP8Löe„DÙT@HT¤.ÐòqˆˆD$eE¤d@€((óO ! PùBºB-8 âMÀ© ÷ @@]¨…þyð€y"22R¿ÒŠ ‚tAHˆjE0È` C!È€ÿ”à‘wA"=e……ýüü„@ÞBp„³¯ÀŠtA¼!_ˆ#à'i€Èò7!N€‰ Ôû/1Ü éB@(ƒ; y£r|`޵<ÀXS ï ý¬óW€àï݈‰ü[îï쟅 °_É 0îá ‚@aÎ'¨; ¯¦#„ôG @0ÇŸ wo8*ä ‚ºƒP¿zÔ  Å¿ zƒPO¤·7Ôý'IáŸePû¬ sT†{x@`Ho‚Ÿý©@0jã„ÿ9_7Üô/t‚Â~qôñ6…A½| š*¡L¿mÎ$@JIÉ ^ˆ?ØEøç&ž_N‘Ÿf‹ O¸'À Eu‚ ~‚¼A¾á úÓñ_D "p„‚‘ˆ3Fð»:Ê qú £$€€úîQ ~þ}²A‰Ìsøþë”…MÍ,,Ì5øÿáü¯WI îB­*(*&””HÊHBþ[Æý»?25aNp€Ì_Ý¢¶éŸŽ}ÿÏß# øo-=8J»Ïo©[%€`Ô—Èÿ³à¥üÿéüg•ÿ»Ôÿ·%5w÷_<Gü@P÷€¿CPâõA¢AŽØÿ†šCþ_]ˆ#ÔÇ㽚Hj aÎ(Q Šˆ Åÿ²C½Õ þG(ìòK#™MNœ;1€{C^2¨$ ð|¨1»¡.o”4¹ ¨)úﲪ00Üñ縉JH@(€ˆR”¨„êèQséñÿ%f€° ŽD¥PCNpÁÏ“•”+þ4ýBR’aßH ¬û/’›ü‹dP>Ðo$ vødÂà‘ʆ»£þcùÉSØñ(†ü QRF5ìòø#B ìô»âO÷AüáGå8ÿQ­ºü ÅQ]<] v€²Aÿ€(Þ®@9·? ŠûEïÞP'ü»²ª0ÌÇÃáç¤8ÿ± j …á¿[B•@½ þp£(yþ %QtP·’÷/Yü[Yæ§Ž’ç/þNE‘ýc+DP xÿQÌþ F1óù}P¨Ø_7¿7Žø³aß? je¿ßPE%à7Tl ñ·ÿHìƒ@ nê_—J·ÿà_¯Ä&˜Ÿ…ƒå"\k#Z¿W+2ø nŒŠõHšžÞø°ˆ$º£¯ atëѺ•2ˆçH§e« ¹(TÝÃÔÅDzÌ š(åç&£Ô&„KNIŽ¡KÿEèµ¼ž,ÑÏø!°‡>9öé‹å€>}ÖòSKNårã(8U(Ów«­m/}æò‚J|ýíY^êóð¯úî÷ eq¦ÚU€®áÑO µ:&~pkY6|9£¨l#·Ÿ™íUº%:¥N€¬=p`°,•’mé=wiÓ¾ÛŽÞ)ð2.—{ëXàåÀÙ¼fÊ}vvüÏŒt/cvu“hò¡º›[wVnQœC¥¬Z£¯øÇgRï‘ß³+Ýօцw^ÜÆCܶ«4ó—‡f'Š:—:öÄÏUz…ù^ÝE‡z„Ì.Þ0½j¹“[Ì(ÀCÞº$úîy 1y"k›´x®”9QgŒ`”Àè딲询x-ÑU–˜jyEÏ„ªýF={»Îò9}÷&K°bŒÖC}¥1ÄÙõ|ÇÜl }¸2P³˜òƒ Ñ%¹uÿ™Ž‚Ëb {÷зã^Ær§À0Ê4~òxz¹—›¾ZMðæÝd\=Þœ*¸©~“'žùfä³e’@‚”£Ûüqf³Y£ò3ø|»c>{I¢[-š®%šñKÂ!m¬2Ü0 §˜±YÝ’Avˆ/Þl·õ7oµ}“©~¬Ö,}¾6Éœ¶7)š…;|Ö‚ÃF beÕ zäóY²ÎŽržÂfr «ëNÉíÒ<ÒEÙ°‚Tït?Ct:ŸP~Ýo˜‘+jz²Òfò` Þ€W•ÏŸ lð½èÒ0Ø…ú?ˆÅȳö—L¬}éSCÑBåj‹¼\5qæVY)z åÂt; ÆÙ“XÜêã¨U1(Z\­’Ò~i1™Fvxë»Þ³‡ ¶<* ܪ±ô%!Á®„KÕMJ-ÙÏ`ÿì†Ñô-¬W…z·®LØõÛ¨ ÙÝlšÕf[Ã#-hõ>1רÒ]£~øÎÐ q:'D„öU¥3 ó­R¼Puä`'x·›6 ði‹aØ~±+÷þç^4êÓÑLçùظ´ýw Vî°³ÃùËYßÌ:ܲïaèïw†c‡*ý¢:RqÑc[nÎgEßÁæ˜ïöׯ8[ˆô¶ˆÊƒmŠZ/œ`é·°tÐò·_+¨`1dž(£5l¹†û?G–Hq ÑvD$|©:vbrB@ɶÅ盢¯ä8¬7õŽýÑ3ážì»0½Žq|'á¡ 'ÓBø.eïRùÍwðrq©X¨¦©n Ô}£“¥ªZ1E¤U×Þ*MöXOí›Nð]>©þ²Ýt¯§éªûš>f‹Á¸\ þ¦,#«¦öTk€ÊåV!œ™èº9N²G.œS={`ïl-úZÙ>ÍÆƒS\©RÊȧþû´X =…AR»$ËÜqÀ8#ÄÝ™.®Æb½–@S`Ü׿Bõv6JÕ2Ãøˆ’QÛj’þÔŸÈL1>`Äk˜ytñû·GòªIåÞ)i4&aIbN¸_ƒ|±Ý7>h½šR Uú î“+7qÖ”v¥¡Ì`qo_œXâ­;?nX•''¸5râg°L¡×•¯zÄòG7ÉÀü胲|Eù×'¿àgÙ£¦…>v«dÓÒ]%ž¯(á&'mÑHa´€JrLêåz1sïÓâo+™™—ýW:éß> ¶«qJ"„Ò®šŒÎæùÂKÃÇÃUù²–-lï/îb Ñð`úG †×Áù‘-2úÙÒTY>ô´: @ªÕÐ`+Fc$‡{€ßöÖMP€nV(hŠò‰‡…ÿФsº ßRb%(ï©ú1cùìŠå2mÁmöÏEÚw >å±Þ½s&2~ìK$³&­{ÌЈé·gb™¢_výQ·É*ùê ¦¶ŒS4eô… 1¼Yƒ‡ÚÑçÅ`œ‘Z^%/{ÿº>R¬ $!"ÿC‡Þy÷~7É»2æ½lâðâ¾ÚšÑçb ‘JGv Lœó~°²´;ïßÉá#˜0¿mDË‚c\B…ú<´«KâªuM¡lÇ/Mý˜»¶mYÚó‹N %ͱœp²'ß›7Z1FÚbøh;(àÅNßÁW‰ÇñùhÝ'ñ#ö8¤Œþe¬0aªÆ­È º^Ýc¾ïèÌ치6ŸÙö¾wîEéœRe² ²ŸÅÂr}³\¾ÆbÒEúá%Æí×74éìRÂ7Jjø®ä;‹KKZ êå+³Né'¹ö…õI”¾ˆÍÜ‘¥@#\Sœ0>¯Öf~Ùò©ä~§îê\|šÈA²M-¸¦;±×hÕE,Ïm5÷nÛÿÓ1‚æû‡{O (€ž –”jÔví» hß[Á™-­1„°Ò´ÉÔégöpzýª")¤ã²[»2Kc•?7¿F»Ô³˜?¯k<_|Y¹H ƒâ¡´K©ÆÏi)ô!MðwfW!–tHæÒ®&m¡ CÝ£“i®; Ò{\ˆd™âF!‰wAÒÓýUm8…9eý 8ì$v—jZ|w:1 œš¼·­]-%ØU4›ùáìïÁX&9²ö·í–RsûŽö’aÓ©ü4BVž’t&«VÏb!–Šx€*¡¥’ï¤9S²éeóáôȲêe]Á¿Í<%j5ŸS"{ªvAiÏDFQ;Bl%¥jŽþÑI³¹wÙð`G"2Ö₽W¸ÅÒðÌëöp¶%mècT;v^‚!-³[`† #WrÛÐñóÄgù£F+æ8.wÕÈc( x¢¤ßÑT­6W°y¿ÐfýV¥Õ”z¤fú¡ŽúëD:{×åÓõ“aötë Ö´Çç1v$ÛOÏ£‡ùµ_Ø]ÔXH/VÉš·ÈšS¶ –Wú.Ž™5WÑD‰ŸÄo5b Üj5<ŽGSi mIð#㨟R­Í)2dÔY —0%kjR;|A!AÕ½˜ò]ÀmäéÅ&ã1øR««ÓÉ §Hè$íd-4~æav*]é7ZQØxlgMDº8g¿êÓñVýвüCÔ)³"W׆æ{©œ"ͤòxâù®v‚à`)Aʾ0÷õ=h!Í:'-.Ó«‚y0Ž„óp Íû©‡·gäbC(Ñ2Ðò¬Ù$Ë ßkó,cNò­;Øa¹•œ»FehšóƒÇ;çˆ&·n¶çÊ,*õB_„¥˜þB}Q !7.LxplUÒ]~É&þµçÚ·çåÈ–B± ®Ï³Ð//ï×öÂ@íÑö££†Ô 'I%OnÓaH3ä­Ìbru&„ÈUqéû²ô£íf¶ í™ÆáCjÊ—•ë€pI¢'¶«ŒKzROz㱋­`h“>ºàƒà¯‚DeçI+×ðë³è±àÁ²6 Vº#[³C¦]W(¨Õ‚Küu#bÁrax…$3r/+FN2F@ࢆ‡ˆ¼aɺ­í’) Ÿ—§`ª ~ñÜÌ^¨MXÎ×gâ}%.‡µIγPX±^ҰЇ°O .ªM¡¨ÖÒÃRz8n¶Ìxºª†m~—<É/óò<0‡Iüùš:?‚SŠ9 öÌô%;ì®ÝaŒ0½ú•‚ü"³C×Î'Z/æëŒ™ù=­I}mGÞµê|¼u6È+¼Eçiävò´VËqŽo¬ÂÓï?ã÷ñ†ß®?ÀÛi% ò~%LloéºIjXÄ‘e—iR>ŽÖ唯¶ “'!\•ç ël X4ès)îS#ZàNÏÔÖ]ZÂ7rú?Š]]Ee\È<–;K¿Y©½t}(enÛF(0Œ9g–á¡M?àKÁßs"èl&!ÀJèÞìvµ>±ŸŸ‹ònÑ›ìmÄs¾»X€×›[8è¯ÞÜÏFM¼±Ë–&Gò²‹™Ù*I†×sûv&O9Â{‡å3+–ä)•¢•ê¨ WHŠÛ¤¡EUä'Z-ˆV³Ó¢þ3Õ‚Sä¡–R1¸%˜X¸2õhMú~€MhÇÍ%îægÂúQt t´¢6îå˜ipÌ>XÑ›ßu™lYW÷m Ç™³m„$4‰˜¨†Ô>Wã 7†õ®Àæ3ƒ×/È´¸7âSðijFÆêó¹}ƒ"0x؇Ú¿0sÏC“o2©dûº®Ë>º^¬Þ©¼/z,¥KÕ$s:8î³b­¡tÕnH¹ØôÅY¤)´5Sשµ½Ÿ™E…û9çÃË–5Ï銶aÊíÆ‚±%9!)K c£ØGÖ!‰Pó¶òrØsȓƑ=XSTÈ׌Þ:=®ÄãòDÉåµyÇ2IÀBr…Æýôë¼^„€Í ¶®Ý†±qQ‡zn³}\ÌmÁKQÒ8ÓÉU¿,e¢{½÷dzå-™C°L®äãâ¬sÆÏß<ð|Ÿãðg±jïÞ-zd` ¦«¯ŠØÁÛ~ûƒù0–­ílJ•áE³kå}"5ß…*FDO™¡¬]ÙÖí1k!Ý~Ó2€f÷Žáó~¾<ë‹éNWÂ(Y‹! zËcÁ:s¹u*?î×ìk)¤jAb•SK±ì•Ú¥¼â[4Ž£¬;×·NŒêz’ñȽÑYd®º™Ñ+ ñ©lî&.¤vªH%KËÍ€†úKEÁ«Ú¦u¹}«®$þþ@å‚È}u"ëšÝ^ð«Añtÿf{œûœõÂÇ€*yå_sCS{sµ¾€ñR•›¼ô{µ:™~ýhÃZµ·'=ß+#ãebáÕðˆä£Â`³¸râ§Óû–ƒiÞcvöÝÍ·WHå“ Ô¥h¡Ïã7ï–FÚ|)9ŒÙá~¼˜vZŬºøn+r÷ÐÊO¤òt¬ÿ~þ:ü6Úz/Í«xeäQ¦£þ®R~b5gÖu´ørR‰·[‹Ú﬎ýþ^‚›ÅðB«NsóÖþ<ŒîSw™lÅ í¤”ú×¶UÇû ,9¥7So?%–ÓªÕ|­ÄœÆµÏ™ŽœöÁޏ—„¥œˆµâÖ÷qî(¨±YéJc‡„«à!™w@hí Ã>nç£îcËm—=c–a`¦ÔÅÆlµ%X¼–=&ÄÕ´aÛµeø3E¤r NýeFi&2ÆeÍbŸ°²ø.Æ÷¯liw—KÆ;=[±" ôIÎÃË*9›ðÑèñšõƒX/¥¦†Õ¦lþ=yÜhFx ÔÅHÇèGãcZÙÛúmn…“7ó‘…Mó ½wŸ_g÷E)s,úžD¿yWcdÛW¦ÓŸ½ÿŽÇyåmÍ7öËwY‚¿K³ÛµspÎ,ºiímïØP={fܖϙϩǸ›ÓͼÒëOýÄ1â~ÍÄX€Ãç*àeÀ93—gJ™xˆWÕK ñždÃàF¿W.ôÀUî¤0¹OÔE]Ý,Als÷ê³_Œ”8øãÅ`rCN°ûBSUŠd)ó»þ }{K°SÜW¯? ]¿ªÔ.üb$‡ßðøC`ÓIjÿX¥€ÎR€?ÄC6Lˆˆæ¤kZ[Üöôr3“´)¹&#™æÞŒ{UÜæ±¨êçׇ¯†ÉæI‡©¤Ù 9FtÞq:C¸2éìŽZ!X[íQM «éìÔ*è ¡:é5XÖxmÅ¿Ìæ Ó¨…† Vâ{ݧn¥uòh½N‚¶•ñÞL½Âïo,¼¬{*‰l¼åÞ1 /oÍý´Ó7-ä|þrpöêᇌ%V™ŠŒî4Û»¤5²j`EiÌœu¾{hŽZñT*oãë4"cR"b½+ÖéÛ!Oß(CxÍ6$$žîcÓì€XQ¤í(ü4Ù”¥ÌÚßZ6Þé\y7ߨº´óaª¨Ž27¼Ä:ýåÈ&©‰ÅÎuE`…±°ÛÀr]–Í\²ÓPäz meµm+a¨mÏžžá¬MG²jÚÉÝçQÒáæÀ±a‘îšô¢ës4©èOBÜbîmç=çTs_·Îª'ÍftIöE…'‹W¬0>—uŒ„ío)S]2%?Žõ < sPXØ#¾¶A‡'JÅ·&êMtÒIÈ‹®Â5²öòk³²ì'–bžÊ8Í«ÑÛ¬¥1¬ ï–óf|2‚ï]&íE5Oìåv[V³ã-D´R|È1Ìmû±·Ax – À´ÅŽ˜qg¡câÇÌ*¾“} —4éT/gg­ÛÒ¥èZ²ÿKpÉyçM]ÇANt¿7Z§êÒt½×gf~ü€⚬ö½B1š£Ã2VM´Ï$*þìd¼_{žµ&¾ç8ïQâ…¬ ûÀç^¼d¤¤kN°gÿÃs·nDª¯ëaÃ4Ó®ˆË.C<_kFã‡×_ÒHnq„>h&[Jµ1’ók‹®P±Úâöy6¢ñ–ó$HžD³£øuŒmÌÎÎz(1™êÓ/ ‹Xùäk½}/Òõíbbà,Çùíš#Þ…GÓy·e?¦ ? YÔ¾%)¥$d};W,ÁB)!Zù¬c8½žÊÚ'Ì®8Ë«:I.M¦WM‡?V?W$ÃöÀX«° y¼‡·>‹('5ègºÿÞï$éEÚ£ËOÃêöŠ.ÛLIH yyo¹Ef¤šø¤&9ˆ5žøú»D+<Ÿ‚ ë¸*N¢á+S ÔL^+.çËDð¶òTèܘæ$[N/îhÆ®zd¼Q.ÃD®,ÕÙY´qåN¨±À›z»Kñg8Lú®±ûïJóðcÒ!ϲ¦Í&'?*ã*zLB5ð1s3®y,ËÌëI ó{£7eÕ IÒ› ìþ’-³å\+õ·‰T»gOÜG))¹$j<]ÚzËý¿çi—*åf{!ý‚|_LÊÊÇ>˜„Ï7WÖ'µD¥'ì6,9¥Ý©ò*Õø—Ž–¶<â&gŒCƼØòÐ5ÛªN[3ëmŸ«¿Ò‹w1›n±¤3©óäSã†yÎ>„7HN_¯”ó¿[¬K™éÁªé,¦1÷ ®eÊIt°5;ÒÓqxuŠ26(ÇÔÖ±w׭ݸ7cÌr¸ÁzjÖ¨†¿ÕëËì·jIöÞÊl=èq‘rfÛïsƒMnE+aa©G‰¡ÉŸk»ŠÐ:³ ‰oyFÃ"0» {Ô•ÄÎÛ˜ã@”^8㜇 ÆÇ²¶,iÄ{fGymôm½ß-âÅê6#ñÿ†ìƤ=ÚªÑ1ƒ5jóøtZW]VЍ9»ïÒÄMa½=á†/ ‹¿Úkg#õ¯îvDŽÄm‡ Ùè^²ÅTJŽÐ—Î¥43™.Ðg,*2N=Úæ•^‡éÞ8DËk’5@jÅcã§mŠB6î9Ë,õf¬Û¨~V&I@Å>ˆU§k[r+¤‚õ¬íGUÊ/±ñZÅšáU¹z¹*¼õ”@>*â¬>Êð|øÉ:¤£m>~®Ã†¡mœ[·_çÿUþ– ô¼ Ž9#–IVzB<‡E¿ãkå‚ÆÊ®ª~ííBö„Çó;bAŒçŠbË!çNC+[ û&Vçûb©«=cþ _\‡ç%Á^†_è-ÓlÌ&Çá“ÇÌ3ˆ<݃xêÊd;ÿÈl’ëÎ~ÐÂüVwI7ľ…% ×l y_]o'zy‰Ê+ù,)‡íŽWK5|ñÁ„ªDDCfƒGXÉE“ècÿÓüeYÖæh“d#{^Š1œì7¦¯¨ùìð>†çƒeo­ÝÀªZù{†^æG±È§²æ=¢ÀɸÙ®ì¹÷$æ-GуÍëâ‹9ιJk´]¯Oi'Ô;Érˆx÷ÓuòU¼îOóÞ¢8Wë Ó³]¹¬ßˆŸZÎN3 #k EwX9þñ‚¢ÕrzQYBÂÚXÒbNu§aCyy“öûUñtãã§ÜPÊcjvúX eÓniêâRÑñµm$F¼DS¼ñÔžÙ˜MžÚyÆAyÍ#*Vê©Á0ëJŒÓƢ燚Jz—L¾6H’ÃmËÙdtàг÷å÷špJë_ü8º’LÆŽº£ýCqÓÍ>~ªøD9׉¼šâƒ?ÑË2v—Ùž½j®žÆ÷ëÅl¥,‹Tñv)3÷øÂòo}OÆ"¢{úD»v·MðVCúV˜ûì],öîd6â%>,.ßy¢ê(/ ®E²*B΋¶•´ Kë2OÃ¹Žˆm“¸ˆ5pÝ;õixÁjëÜ1¯•ÇŸã¢ó)tÆ`½s[·¶ÎœÓJ‘'÷²>žõßqSúRˆë{x³_tëûsÊfÒ/åž$Þ­ãõf×Ö¬`þè»_Ýy—ûvW‚A掭žê××6{w-H€ì@§Ëæ‡_[kú”V}«K˜^28`O_ð2¶}h{÷¾ÑŒc,õ’ ޤå“C¿.Íùȵ‡99Ê"]/»ÙÊ8ñÎ;Úʸ’4†ŒLÓ±¤¾Z[sÌi¤ÒÝÊÃùÝ}Ô]ÚAõPN‰äႨ’î†N~õ\É]*~Ò8#<±h,lxÙ}iÉ]cε=âÙtíø9%u%Yv϶„¦‘<ÏZní¬Í гgüÚŠ´Š-TƒÉ‘ñyiÔ¤{ë­øÎì'Ù­¶¤-ì˜ú Á\. ;G§bw/‘ªé…e=ÕÔúÔµ÷’q€en]kDpÿN¦+äãÓ™ã×TêzQ¡µ =GvKSdžmú‹ø %îðëõ¦}ÕB#)ØÌPd/î 8QÖd 8Â`ªN‹—¸IÄRþìd¯îbfN­—ÒXŠ‘²P—Ì_‘Þ|´Òa­ "<þd"­#SµÕ\±GË]žV?™9šÅÖËn¶̇‡¦¿K÷é–P¿>ôÅÊÞ¥Ë ÖküæXpCî7†ppPk¦hñ8µ4ï÷"X‰ýßÝ «¹è°Ý5…0Î¥¼·ùTŽŸd %MxÓÓèK3š¡[D «ùíà@ÃZÿW .•§6h’­‚ï•Ø{Žf²BÁÅÏmÓ‰Øw9½MçßèÌ=åàÀM¢Î²Ù¹Ém®Ñ6½©6}­6‚E6„œõéÒÓ‹øªŽ:F ÿ¥Á,ÓóTvjy8ÌÊÃðå\älýÂ9HÇÙy'R—”ÂÍýURF<™ù—ýŠ:6+F)‹h¨Âv/„¤§T‡«ag¿FÑZ[çœ~f=g\iÐ ÍY?ö '¹˜©Hp¿˜H%ElÉþ½°8Ÿ endstream endobj 86 0 obj << /Length1 1480 /Length2 6904 /Length3 0 /Length 7906 /Filter /FlateDecode >> stream xÚwT”k×6Ò¡´(=HH3CIw§´ˆ30ÀP3ÌŒtwKw))HJ‹€’Ò¡HJH(ÝùÏ{¾óþÿZÿ¿žµæ¹÷µãÞûÞ×¾×3ì, øä­á¨ ÜÍâJµµÕA@(Ä ³³ÂЎпqbvc(ƒ;Kü/ E$ŒÆ`J`4ÆPî Ðxæ @¢ @ @ÿÛŽ”(]aÖm~€ÜŠ"fW„#<0[;4fŸ¿—N+.H\üïow€¼ ³;´Áh;¨fG+°#Ànƒ¢=þ‚SÊFH¸¹¹ñƒPüp¤­ /À †¶èCQP¤+Ôð«d€Ø ú§4~bv€¡ õ—Ânƒv#¡ ೂ:£0.Ïœ­¡Hfw€º@uþËXë/^ÀŸÃ€øAÿ ÷ÇûW ˜óog°•Ü vö€9Ûl`ŽP€®Š?ÚÍ ;[ÿ2;¢à°+æ†` ~§¨ÈëÀ˜ ÿÔ‡²BÂh? æø«F_a0Ǭìl­wr‚:£QÄ¿òS‚!¡V˜s÷øÓ\g¸›³×ß’ ÌÙÚæWÖÏFÎ0—gPu¥?6ˆøÌŠˆÅ‰‰ .¨»•À¯ =ÐßJÐ/SƒŽØ`Ê€úÀl ˜± ì  ‘Ï >^ÿ[ño‰XìÐÔæLüOt µùKÆô s˜1ô€¿žÿ¬Ì1 ³†;;zücþ»Å¦:*ÊF<JþRAîðâð Š  °àfáóï8Á°?yü/_ug8àW°_ùbêïœ]ÿ€óÏ„pþLŽ¡.ÀùÓŸE€V˜Ðÿ7ß»üßhþ+Êÿ“éÿ‘Ê3GÇßzο þ=Ø æèñÇCÝghÌhÃ1Ãàüߦ&пfWj {æôßZu43òζJó„ùÂá0” Ìjý†¶²û‹6áF¿Îæ }GÁ~]1/ ð¿t˜)³rÀ\#( 7ÿRQ˜‘Cÿnä/Šªç¡ìl·þ5}‚"¢0 ö Æ4#‰¼@˜1µ†ºÿf7@€ßŽÆ¸05ûlàHâ_~ Ðùý–DĘvÿØþºë0Çô7´TÀéCçb`""0ý†[ÿ†þ•­Õ3$SÎošaJù[þ}q@¡îP+â/“p+É`ûšà–“*yz7¾•A)¼í´“G‚|ƒO Ñ]Ê£‹ ÙYÓš¥*_:A*OíÛt\Nræ¦ö½–ß0×zñ1«¬Ù2Câ&¯nŒ'z3Ü›$kÄza’¢À$QŒìÂzÈEÞN$kmÛeÀNæ}¿¦ãs¢u‰ÊÖöª’,-qãßôÑM^у»÷s¿9=ZŠ~‘ª“qOSªõ”8Á­’|¡§¯w†¢“ñ}T€†kàÊ[(šBY²—AI˜ Òxæ%éEn±ëf¥D•JnÓº«lž+å¤FgÏnyoÓœ…3©ýe’M4è‡ç)#b†Z! ™—¿iý5'Œ§¡G&ñeÜ‘Sû0WþÑA#,DÓcz¼cdáâ™fªºÙPw0'¯v‚ôÕëå>uìïb\mB±›ïW¥P,+óÐdqmøØ½ìfsÌž9â 74K³k1”)šnöD!$tË–VaD*P÷½‡ ÐôÈËSøêå~k«Ç´Ke”s e´ç›gÛ µVéÕÑŠžnN‹GÞ•î‹æZ=NðBŸrÏ'‘Ÿ S±Ñp sΫ¶Èà˜»üÍ÷Ê¿.u†2½ÆŽ³Æ*ÑÉ+;; ùÔ oÁ"v- ˆ>Ûô¼ÜÄÎè#j=ñJÞ–4m³íyÙE‚-ó…÷zW¦9U×_CØI8p©/T?ÙÄMÝëÕÊó’¦y™Rœb1öleH;iYWŽÌ·ê+gì­@j½Þ õ„çÑ-ò M¹Q\cÕôã?o¶”Hò‹¿úžµy dKO·Ÿ%MÊlÖjÁ| ¹†[ÜÞQ`0.˜?ëì'¨ß3¹Çü“{¹>;óÃxoþX¥ÏœTÀ¾m-¸×ä­ó¶|LMæPÉçp‡ðkv|—i2iËÏÚjý㊠ÛRü6¤µ)K£ìmÙjS ñãzïf´meÆ´OÚ©y„õÀãÄ–˜*ÍŽÖ !ä%žŸ%âŠotÃfò)|>iAÜEï(ìi¼¾¿æ¬¿¿ÐÆh•«|ÃíéŸlãoàŠíIÏT5ˆG =îÇû4’±ãÙßD&é¶PÀ_ڠ£œ9ï<móŒLSŒÝ ûaRW#؇€g)g•Eà´ºËôÙL©½93c67T>zoŸ¡ßé+ÀsN²¼L³ÈH#Ÿu[ö|4“€¨9ÈÍÌVc1>ž °®g©÷—´~™oXHöED‚wéÌ•šÕJó9÷̤$çÐm‚GÑ•”ž·w ôÆæÝºdÀ.ÝÑPŒúYÓ &9Gˆ,txâ8^:|æ©^jÇ^ó"vŒÍ¡ÑñhŽÝâÀ‰Íœ<]|‰¯3(oåŽX«ßnæ4Ípè!Èk8€ŠŽÚ9/"v"GeÚ bøn Å?ôÛϼr¯­ÑMŽðövâ¾GÙâK}E gÇ[uó2²TÓ˵†yŸ{á[únc‹ÄaL™Ð¦mb=¢ˆæ5F†÷wi<Î6’úç…¡W§½ j¾÷Àϼ`sæÓN¹:’ÄU*†k ?ö(Ùã¥TªVÐ>Y÷iËbP39{ûÍçFÙÍ! ^2ã1y¯+_):ÁçW€ƒì¯}^ ¾Þ±þîeG#,IIðÔM©hGªw`MÚ‰³†Y›Ž<]k«“%DÜ„ I2Ô(t5É3BÏÏ™zoâŒÜ+×´Z_µ &>¹øxa‘.àf jüØæQàÿ…A…Ï–n4È.ò¯ñÏÑ|,$q7»¾WÊTuÄ trme¬N[…#ÊiÔ¾w±ö÷š-ÕÙ 4·‚„÷¯¥·?!Óߺz|­´{Êý^MóKµ÷“ƒÏ¦nTutÚ›ùB¼Üu‘®">ü¥…âEwªr[j)H¡¦ë>q8¢¯}4ƒ€[ÆU4ƒo£ ¾‹¶ûöG÷»¯·dÜæmH}S3©êÆuw¥|Gå㿬ÂÇ–y/BÍÂYçé ¤§AK¾é!]·/hìÌv YÖ¡=.Ã>M?˜3sm/Ïii;¦WZ]CÄYô]²? Jï–s°"²öINò¤CKºÎ¡bÆEüò"ä4î´Hvðn +ògZK³ÅAEŨ.¡ÉÜ0öRInɳSàìq|Œƒ@BG¥ÈáÍ£%§uŸ‰ªùæµL—B~?Ê1>°§‘Qw¨ñ¯ayÔÕ®×Zò¢'Þ(µê(s  æxf¨ÆÐëÓ=Â'ž—ÈFǘ‚•íñ¼²Aû  Ãêdc­ËQMoOÿÑý¥Ôïéz4A½‚õzˆ±t…ç¡évÃI ß–U³šÖº« !ËK×¼+„32È覶±Iiæÿw*S>ôZzÚzUy göÄn|p!V±”(TçØ9kù’±‰•ÛŒ¥¾I3ÂhÁ•ý8}ÜJ®Lj€¾Uhd%òã“â¢\T ¼K„¼Ç]KéS›|Zd½ße—Nã°>!@+êg–M·ûª gJà€s^ÍôdÖWØLLéÐÈ«hÔ­Ž/-1AßÎø‘s„U8LûÊf¯øp^_6ü8$] * ð|—²òYG¶±0ÊV¨PJ¢…-÷]¢Qæ097Åá¯JŸ3:z& 4GY'${g4'rVÓçÎs®ï(Ô\òQ8´¼mÊéNq(\<8«ÉTá5+7gQ uªýqóX;%!/›>”Èi\É §<¦=áÛ¿S±A‚ÿh&QþRÌIÞóËá÷,\ëVÉ{Ëé¾wñGJZó-G©·iU‹Hýu†s«b;ç½%š[¢äíòóÇã=––Ë­ö$Øw°¿yî}eTÄÎ}&Jÿäó~½Âêbât¼T߯ÊÃh6Ž}¹{÷º[:„V2«(Ð(Ïi¸¼3*ìêßA­™6gÛ‡ø¼$~ò­¦¸A°ÝwÊ”.@¬´¸xÛGäƒv.ÝLÇy-õ¢’¾ucèÒû¿WªUU˜ã 06?œ³˜fÚO‘0gëC#×ÇW6Ç.9¸˜¬–M¹4AE-Æ ‹kþÎ\Þkô¼þ ,Ó‘ ÈîîÀr©˜.á/¾þÝbï­ƒ¯ÖˆÜ÷Ÿ¯?ÜêW•î|Zf÷yƒË¡2³ F$‹?‘C=½sâ®zÍJH¶yW÷84ãqÔ–}å’ µáLËð-^6ðvþת3”MRm~Áç'NþV x5ϪaØÀê<®ÿ{å0Èv¯b…Ë~Gèå#ªMõüÌîñ4\ä»'_ë?~¼þv®…[º&,6#­ï d WTfÙL(ÞÆ¯~5Ùd‚w„ßwÀ4Ø+ŸÇLÎùÅ\{™vŠ‚Œˆœúh&îi@ùÈ„nrµãìа‡4ÃAÉSOåèZO¶«À~«ŸsÀ~ƒHÄówò;ØvÅHIÈ»pK]@¾)”ÈådT“y ]›~80ûf\²òøsÏÔ‹`'“¬u¾Ý:íEùAO”% â—ýå²Õ(Gm‘ˆjÀNÍYR o &ÓMPþP–ê¸5g÷DÕrãÌ$VÑÀÆ9·×ûÔHˆªÒ%£vüp{i_ï^Ùµk[Tã¡ýVŒlZîÙL¿<ãXê J¢Õ¼‡^RM°"ä]¬c[m5åòÖÃÂã(aþ× >4(ö³@O´…{·Ç—™½!ÌÈ^\\§RrºN{ódög Ý yÝ\ΊPÔG›jvΙsÄ ÒWµ{‚xi|ˆHÍmߪÈÒ‹ô3å}½õ¤TBÎM%)É7öU} gó_ÔWNQÔŒ/ëçÏåkmCU?éôDZu Ž_4O!)ùCg—L(Æ>UTÈ[ŒZ«¢–žEÆX¦ìQg9º”s šÏ¶¥ë@é³5×’€oÈ"@)Ç»$OcÒöH©oSX>ô5¸f–Öœ½–U>]Õ¤ÏÌäxó‘|Â&HÄf6-à>‰jÅÚüfjôâµK^7¶eðêXž¤<ÑH¬»§ Ç@Ýd8½¥\xäèP ‘sÖãÙÔvÎIˆô ­¤ þRïÃôvMsý³¦±ak™ÝbtN2BY¢Õ­/;g„FÙŠ’$1·ãu‡´úázD±FåÎǤG\úîÛs ëq8îD"#üÓv%¬„ÍJj´¹_€½ØVu¾ï›h4 o.…6nJ¸àÒt÷ÚyhÎÖ^©HJ™^ç‡\øvxï•5ÌSP Û.‹˜+·å;!-=ùµçËŽ¯Ù=€`_Ô÷D¥‡Š:šOêg÷Ve•YwõG“ïm,:°Îæ$Èäykp]¨=Á¥Ç§öáMu5’U’âòïOÙ6/ȼ,ØJ~»“ðúÛܺêpÅûD<¬† C¶5uí£E(¬ 1amF惘6Ö\iKQºn&ØË5|)ÈirVnÓ â¥Ü»áY¬vI_'’_ò¤VŽêН„Êû Ü}ñ„dÑã)¯´»Eôû2#¼·ÏÛç_ˆê†Ù+L/‰É†È_QÂ{ƒÏ`{à¡”ô¥ÀɤȂ5¾Nñvã¢P·\ +ï€ÁÞànÔ;>~lCÄ=¡^y9ŽU¹w?i¾ àã‡`·§ÀŽž£GèHÜI’÷yh¸Ôo« YœèIܹ¢tý›‚ o¼ùê0!’jýu–¢[dí`‚x°ââ¡?*ÕôèN"}À—åŽ{¡:DíSeÚ´åi•>~P9ÄÇÃÞu2žœç|­•‘²dbõêÆrPZ š¬¤bè£l¾Û"ôb¾Ø€C»Ñ#&ßT± ‰rºÔXÃC$ïv[3Ÿøø€¡<>‹(_Yt™ÑÑ&…/|u¢ÝgAgnžî{?͵’ñ\VσØ~!d8§`1Éï=Iš7_••9nðA­!.Eî–§o/vÖ5½Ö]èƒñÂrUžÇíý¹ ÑÕó‘m҄܆ÊÄ|ýÂâXÓFºÛ“?ˆ1ß®g®éz×h§qÞPô>á%§}Ì5d…›FÚMÏk5š¤ì:6lWÕ~BI7»a½î&¿`æf~®B´—ÊWÒñõÍ)…Ÿ'\$¨·p¦ìõkre¿Äó>ŽêÀÏøÝÅ'~ZMü²ÀÚY¾‰¥iKÅ›X\ †4ÅRB]Ó07Z…64ѵ eÝæ×ugsOpÿN±{ò¨‘6ïu¿­˜¦*µÅð KÀ$üÀ³È$hg &уoÒ³‡›ªù¦¥íbÒ×íû+”K˜áëV»@QäôÆžV"‡„‰idgKz<`ɶ´ NËZ&:" [“ ó–ܹÐÄ“- ±ù4÷mq׋æ d縖Çõ!ì#çÓðèÿ´5™HÑ[K=¾\iDº Äe¯z¹‰|¸×¿èí^ ¥e¸;§QÖªJÒ¸ÈÔsø>‡¨}gµCŒ®³wî­ÜàÓÏã”)ä<#-ùÑ+(nײ¶Ýì­Î/òì½¥ÞÃüãÉ@.ËÝW©zz=õëœlj"w“ß<-š ¤Öž¯„‡3Ѝr[Ê~ÒWÑ.¹µÐá51`»»h·™žÇvƹÂjé‘Y¿.hŠÿ©Ù¹Ii¦EìÑèBT«Ð^ÏÖ!wŸ6¼OtÅdsx0îLùv}·zÓ¶è ﹺá{¶°˜«AÌ/a[‰7ÔR°¦Õkc+»ó»Ž_ç_¨tÌJ4} ×-Xgcí$dQ’(ÁŠ¢À açÂ& ß]ÊÔvO¼ìí¹g¡•z&ËðÁš’ûL"l¸-hþÀóG³0‚¤â¡X 7?®«cª"uûÆ\K/¸Í}R¯ù3yЧANÊÏ7 /{¾v¥H[AK†›ò¢Ûß±|»{ä‰/­>Ïm6×xŠRaú´mè<á•GÀéFÞ˜9üæw%gä÷öÀQ…g^…ÝIЗ³Ž¢.ްöëÕñ þЍ¾ƶÙá°;ƒ…›=ŽIÆîB‡†Ù¥7ص žtøϱZ)¸DÜ„Á;gßà;07ï‡üÚçQ·éÀ噟`uS£5a®:^^›ìÓ|fÑK9|i<¹M”üp9†ùom@ïÌÜàˆ°”pkúœ;Ú֕µ³X(”Yó±¯$µîïÜ<Ç#Lø™½Ì÷ðÝ¢ÒãÍRücù]úÄš+‰Çƒbß±Meô“ éAð’1 (©Â>õÔÛa˜Ô6ÁöëÀ2_§T\cÊqÃô5‹Îwä Ƀ2[-w—„îÙn&n–~ò½Ð= ¹LxÄ_ÄG5I˜,Æ®)dD–áoûÈQ}X@A¥•ýdMö¦À«Ñœê-{¯,>\£©Åo ¸Ní]¬},‹šÅË+\ždQ^3yß6á:b¥r1®Ž©+Ó.»>ö»È)N„SV &‚EŒÄ¤$S(i8ÂZ<e ‡]ðu%ðjŸjËSù 5v¡b?ö{°dûmzS[ÞnœP|èÏÔ8f2(ÇÉ 4C<ƒâšÓ÷±uÜW ¥áwõx1Wz›N|á[ëCš^®f…gãFÀØÀêb ¬±Uºí…ÇàÐ~øã(ôù7‚rˆÀëN=êæý6}ÂÂ]iy^7r™…’æGDÃx£F™È"uƒ.Z¤ý‚Téæo‡[¼H X”êñ¨£‘V úx*«J$c|FèŠËþ1ï¢zgvôÓVЮój빋"㇔V W×d|z gCË”%R77´i 8~û n¨¹òD|äæz D j¯É6Üd½ƒj]„å­W~ãdh^ýRÀ,iN%$ì•´sâdø…CP Ø(Îw¦vÖ@9åGCW V¶£¬^»f`­Wî9Ók˜p–x7i#„¿úÙ^—â#õùI%J^øO¶®nuAc5¾Ý)ÞMqÁ"Å {µMVœCþ©GèÛ¢ ô´÷«¸ýÑrÜ6<­ ™ÞÜq>ëC³ïHÅç#Dgvåhp$Y~D=Ôçì¡ü%§ÍûÄ]"›©°JÄy|$t©C^Ð6©uG!Q>A \…/b4É‘híRÄ»øøþe]hñåùE‚‹dì­ÃìZí²BmÛ[éæí …ýÝ!\Ÿ§ ¿VY¬3…$‘ŠÍ?mƢ歉{"cŸ„3ÿsñ‘w Kâˆ4®â¸G‚¼¤¶î–£ï=“â½òaG-¹üÝ1Ú³aHv¥½Hhñ{;Vz£¸¡t©"®w£I6î…5Xj…¥ô§~¸šžM³•K«";¯òï _}ÔÑÊAøå[…Ü pÙÅÉ,>_zAóé‰Õ æó–o>=FÙjAÒ=ø§ÉvÁ}õ{Û_÷°Uy(z2ȳr͹–_º•¹Ä™*÷×-%ä7úÖÜXY™ô4ÓÒº¦½%älœÆÝF®”þM‡iv6Ñð¤d)½7uŽ€ÖP<ê¤ñîrYòX´‹¡¦b™5{àÛãû ´psH§Ó'^l?<èÏFÃëtõ€¤1jR£µ-èæÜkC¢:°ý¯÷‰€%¬"ÿ‰=>Ç endstream endobj 88 0 obj << /Length1 2602 /Length2 21542 /Length3 0 /Length 23031 /Filter /FlateDecode >> stream xÚŒ÷PœY׊âÁ]·à. îî\ww·@ ¸»wî<¸» n§33ß$óß[uNuý>Ëže{¿ %©¢ ƒ‰PÜÎÖ™…‘™ "§Ì `ffcdffE ¤Tµp¶þ#F T::YØÙòþa â4tÉD Avrv¶ik €…“—…‹—™ÀÊÌÌó?C;G^€¨¡«… @Ž mg tB ±³÷p´03wÑüï@cL `ááázû—;@Èèhalh 3t6Ú€ ­*vÆ@gÿ„ á7wv¶çebrssc4´qb´s4{OûàfálP:]&€_ä m€Wƈ@ P5·pú[®bgêìfè€ÖÆ@['‡‹­ Ð"¨HÉì¶ËþmððOo,Œ,ÿ†ûÇûW Û¿œ ílì m=,lͦÖ@€‚¸,£³»ó[€¡­É/CCk';¿¡«¡…µ¡Èà¯Ì âBJCPÿ”çdìhaïìÄèdaý«D¦_a@]³5±³±Ú:;!üÊOÔÂh j»Óß“µ²µs³õú˜ZØš˜þ*ÂÄÅžIÍÖÂÁ(%ú H„ð[ftp033sñ°€ »±9Ó¯ðªöÀ¿”,¿Ä  |¼ìí즠"€>¦@Ђ—“¡+àìèôñúSñ_„ÀÂ0±0vÍ,l~G‰¦cÐð-ÜÚÌ Ýc0ÿúüû¤ Z/;[kßæÍ—IFZFZD˜þïŠÿÕ Û¹¼Ø™ ¬Ì–_KÆzðùoEC‹ÒøÃWÊÖÔÀów¶ 6ý/c×€æŸÃA øo,y;ÐÖ4¿—\‡™ƒÙô‡åÿóªÿåòÿoÃEù[òÿ›¸‹µõ_jš¿ôÿ?jC k @Këâ :rv c`ûM5€Z9 ‰…‹ÍÿÕJ9‚‚­™õ¿m´p·pš(Z8›ÿ½-ËÕ~2k [ ¢“ůkÀÍÿÑŽ–±èêp­ä_* èäü—RÌÖØÎä×cåà::z €† B/ÐY4ºÿµÄ&F[;g TžÀÔÎá×D99LB¿D#N“ðoÄ`ù¸L¢¿€Iì_ÄÅ `ÿXL’¿€Iê71ÈþF ¹ßÄ ÿþEÜ ÅßÄ üT~#v“êoªOí7ñiüF ­Hgør1úX@ÈÑÐØ zG˜:ÿ–³ý+ÿ{ÏÿU€Bÿ‹8@ÁŒí¬A3þŸ„ý—ÄÆæ7á¯á3™üA”Àß@mþ‡…hcbèdþ{(¿|\@‡è6P‚ é[ÚüÔ<Óßäcúü¥´øÍËö ºþ‘È/½‹ãá@&f@PZ¿3bµßÜÃÞhû‡Hfñ•fùÁêjõÔ×?JÝsL¿#s€\mA§æwõ &[£_וÙüªÙîwŽ ˜vx±üêýo5ˆÃôŽ´ýÏäÙYþ‘þwîì bìA·šÝïI²ƒúcoíâôG|Äá÷Ð~! Ó_wÀ¿ûÃúKhç 41²þ/ûoÅ©ÙxþÑüWÌÂòøc\, žüÎ…ää´±øïvrü²ºþ14P'Ð éߢ@­v²þs÷XX@¥ÿ¦ÝôLÎæŽÀ?6ÔGg7»?@1\þ€ I»þA™¹ý±– o÷? (¼ÇÔ.ÏßÉ"yÿ¦úÏmiìâ™ó_ï3ÐUú?üׯ ÐhŒ°8ggÌlYÜvW-DàÆ°;þî;å®F -ƒ×¢c»Ë l"mUFàºãPâpêʶ͵àɳ×qK=lØ×x¥ÖGï'ýXå©ÝV„…I쉂c¡º~"xBUÁ=ïgoõ+ÈðNiÊnÅ<Œ;·> ÷ºþÒåÑй]¥½*NħÒi†(µO:E3”¹F™³¸d0Î Dptèçîof®o¾£gO¼’HÇÒ#øœD±z}Ø`¾Ÿõ\-Weuê£Àû€Ky>:Eå%|$3ïU\¸2°àÞÂ_H’ü6y…•ñ€5½ÊB9Ò¶©·Æut±ƒe''LM0€±_SÒ„©ïH¦€UÕª‰á\Ãf$:è0^m»Qï6µL&\â™®{Ì k™û7w{=Ö;¬ 0܆&½nÙîöÑ(è 4sc¡3׎XYæM'J†.uƒèÒJa¢¾]rMä~‚6 á÷ ¼~ÀgÙ*`fþÀ Ý >JxÊ‘ã}íSÑp.ß±1ƒ6o톮ôÄ)ÿjÔ™|~^€gÎ&fJ“›.Öý1wí3µ_-°a&¨”é|£›Q´ÄƒD6n‹cáb¢]J¢ww¾r8B'ÐÃòž'ŸñT½B­5†#_‰tç$’aì !`H8(¤çÆä`리LXëÐNýþ¼Â-\x8zS•+8÷c‡²v—“Bª„P$Ä—ÛíÙ^x#òªÂ®¤6MŸßh¨¾{Øëúòäö¶TJ”’ºpQ®_æ?Ì{QwA´°¯Ú_ûãu“?km»Â Rêj4eÆÞ2$¹~ûp“úÅ ¾0Šê]¹çXïüôØ6é·©m /ë "ö¾fǧTHëX*Òùmÿ´«õw4Ÿ"^L#š×ÔÜ„ê—kÒg€ë'C£PÂä°íl̘ïÇO$%Ôk²…ô˜¯sñY–[ž™‚$Ÿ›ßU:éÔ®a^󇔽ÓéÒ§XW;‚ŸÜ{âLÌžv—ÈU²,#H‹ÀÛ±¨¢œKÈ"ŸBeéÑÎJCû¹]èGKúÉ4D3Îø-l›–s¨ösÒ…2†"›X.i0o 5ÚÆË¤Šô›*FèžZéq0içR0ª^/.˜ÎòõÉÞÉ®ãÙ9ÉY‚ø«H¦’ñy372qŽ„Ïn*áÞU¯vJüãûãɈˆS¾ü™Ä,Ì%Þp©¯ü­‡6gõM÷ kÃæçk9Áë‡þp ÕÕéÃxW\IÇØˆú£9ÐÚ‰WÜîŠüì,³DWïœ'î$Á–Þ óq¦¶4û8ʸ°²=¦©‰€A[¤a×K:WÔN}÷¹ñÀ%ž{ñ5&¦ÔYw8ó×ùúu]Ý•T;]ÿVêk^õY]ÕÖÀžq$>ó:QÙ¥œô½\¶sùègW/ÎuÜ„9»^„c¶ÃpÞ»[È„LÕi-ÆÜ£aÚî·8#2^†á"„%²Úˆ‰<–iP"d¨C{Y˜¿«'WrJ)RPX?>”73ÄãlhwáÏdž#ïñáðdFç©X)ÍŒª<Ãn¥GñRߺØùÊ•³öáz®¹Ä¥æ„ÍpÒ¥µÒ}AîïA.›zåé/^èË—IÀ6¦Åý6q»©sn–í\A%P²=Ñ÷óÑFõØ­=~¯"ÇD^G¤9½`|IáfnB°PƒÕä€ÛTÖdºr›ÀîØw‡EéÓð;ÁšŸ?H™ãºµrí<ï)~ÜOÞúSöUtN c¹m®m²êÚ•ö®*õŸ¤Ì¿½q9ȶ9‡Áám`A[H2+ò༠ìZZ‰#ãÊÚr¨\ºQ•0¯®Ê’ð¼+æ9Â}7D·C3úÜ&õd.ÿP?çµ£€@Ia”u5žµÁ‚¶høÒE5D&wrdÓ'ؤ1Z[Pa³bDɼ˜M÷`v Û—¿ÏdzÝ›iÝN©(ÆšËK¬.D«",Ë´Ç_Š}ÊQ*’%”¿~›iÍWéõ­ ‘†üë‚&´­8L\$X X0·—ò‚]ZwŸ*ÍŽ¾Æ9„‘ЋŸŒ·¢>ÆÜ÷d ´õÂØvd¹ƒWNÿ²œ½ö[Cç,8A–ã\¦L0ñ ’„F6bòÔmã7rró“ýžWµ!mÊ_¿zN|÷ƒG·.½/#ë‘~_ „ZPþ¬!L賯Nµ¢2´l÷6÷,`­èL»»°½Ul&R¦<ç;_~×ÑL¼u€ø âÂ'ù«ˆ/à|›…&/å=?Àã*PŸÖéÚ"ø¾ä&n÷cc”B:u}ááoøŒ,"f¢~˜g¾Ñ>ÜG‰¥?.^h§ØÞ·5…äGQÓN6ÅÆÖv«È3Ïsò!ʉ' œÚ`»‚ùÄqIãžW>¡ðdÈéûõ`B‰ ŒiR†‘Æj+»z‰µ'âÅ «ÆF­ÛjÈÀ‰Ñkþ.™Â—lŒ‘1^:qtÝU¦/¥Ÿ”jàÇt”{ÄéJW,T±/¢ôä7&úùrA¡*”ªuò_e¸>WÁÑ+§Îh;¦? i]÷cüÐrú´Õ,"FÞ.h…)>üDWË;¹zùtþ]&¨köä'êÚ†÷à”ÇßH-n8Sæï¼&etiÓrõQu<å˜Ûf"ÕàjQÏ,ö4ªö^Pk:úͬ§2ÙêÛ&BJËæb#ÂÑ$ "Ôîç|›LC¨h'ò’oX_>׳J7Zë±=òÅþa [•¯ ·lX – ÞÒïõŽîºu&»¾òu/=þ'K …†£Ðë©S"fÏÀÕ¥í‡uHºÔÖw%·#N×çvé˜F‚^±sˆp¤""$‘^8ÆpŒ~OΈ÷˜ql7ŒìCÌœSL(¦tnªÆgÒ©dùí;¡Ð›ßXc y·ø¦×s<0÷%5Ò›Žzz»‘lê× {VŽ„e‡þdpiƒƒ8ºj»žëÕ7Ì'寛-°AHZÃ5s[$…E€»ãÚ‡×ôPÑõ½ɆH­¸·¶ž;,‡'IÊt%e¾?hŠODZ]8-[7Ô4½Stg÷— ÉÁò>‚Õxªç[– žÃDÕ cþɱxõ´w·)©Cö½LæŽ%i<õ‡1‡üO©ý{V.éVáç«'&ÈÓˆF3šŸ%îXJoQœßkWnqÅK8õ7ð’(SðèrbR…?ØxTÒZ4àE¸ZöÜhGÊö) ë) Zw»×éçÌkeòÖrÈUA­ï.cžEÀbD·V¼i ð+~d²,Ùè_Ì%õY3H8=¥Ò ô*Ý™SÒl¡€‘\/Ú3ê,UPÑï74˸¨Ex!¸`‹U昄ªÿóÄv% ¹CáiÛYHšAÙ6)2YZ [O?dÙ 3®Á7 {à3_”qõäbá°µsN`_c÷ IUl3Âû„ëN%ûØPü²<¿ï´]¡™÷ …—LQ|°*xÔHz-×¼;ÎPÒ5–‚G˜îeuAb4Ì#|ã_±–• ¢K¬T©[γPù²øclv\œ­eEXâ5ûcøÉ±ó}Ó…;‘“ž,"*ô]„ùŠ,½¾ÄÀaÖ1D¶2é$¹¥‘àDkš‹ï pÄ_ÃJ»L6öò2\àÏÀoÚÞå…5ÃɤŠ-ß«Ø]¢Ô|:ûûö{Ã`ª¦H¿%i%žݓ΀KÁÍhíÏÆ“¡<0.«j>!~L'¼8*¥Kà¯Ãr ¿úþÍeT[)TÖ¼T‹a7ÐWÅñÅà §¨%Q2;ÉGÌE¨ U2…£†"Èá·º>Eƒp—û1³7¨iXTÒ2,uÛ Ë+Ð}% a±çýÒä\UUî„Urå’uUR9ÿþRZõ%0†ÖtjGÜ3Ý i°I o[ÊLPE’*‰ÿº-î èj Æ)H¨³­^SÊÖeX!DêáѶÍ{ñ3˘4ßý:)ÐhBîeîã&“©ÛzRúñ·/ƒÛd%IhûÔ¦rNS°3$šjÏ>O7 MÍZ} Qzˆþ3ó”–cƒ¤’g‘ ’¯pÃcÑ$ú÷‘|aµã—~±[ÒÍ®¹(µº+ä‹°¥o–©EÌ8RùƒUpŸ‰Z|«î¾Œ¯ÀÍ„O3,¯÷gÀLò3Ž=´¶Ó¯—£¹ü ãÖTD¾l0?i«åe¹lÀæm áJTið•ZÊ:çÙo£†t·þ)÷ú»bÏȉWBŒXUÊÙ»q{Ã=Ä€óc+HƒÌ¦Óômû»¤ n ÇˤիDSc‡^zŽn_ÒçUÝÙÌ‚»®µ·àÎ9´{¼’—9 !}Ë4•ú@…€C"qõއIì÷å.} ¼á›}žAY!é’t(?«ýp]è#FžôÜÖÃÝø&åAé/¯ºÕÜÈö·RóxC ÍS:î›á;[ð-‘Åö¼¤àJL€éDгU³2ãqúõ³+µÿ  #:õ˜Êvhë袵Ç .W.L^0ZŸªL‰¡&ÅŽ›Ùp|£Bö„{$Ã`P¾”MÒk›%*‡lQ©T—qƒ·9qE¬§è†ÚDOŒ[«V}ûsùÞñ³ý¾‰‚þ –ÎËk¿E`Á ¸Ë ¾7Tù ÖÜJøA}Ú€Þ'Á)S–ÇÔ£áy.ú—!äíªñTƒéŽQ±¬ü7ünèCb¤\Ï=‹KYÃ`tË‘êýaÁÇüˆ]Ÿ~?÷7{gа©»¶aNÑ)̶t(^(UÖJ<¯"GÐ#ß7ïsÿ ±g¢Ê„<“1x0¨/¦ì1HÊ;]ív*øêú­u@Oçé#]ÖܳÒÈf±¼‘iýr[ÇZp–|Ôb‘|›çԕّ٘áNtŒK½xÎT*/†æƒÇjsiù$Ä]ÄÙÍ+»€&«nO {±dÚX^úüeš^÷¤ƒ,Ю6#EíÇ•/Òma\Ü$×ûÚ‚«TIÛ˜,ˆ¯ÅB\d‡^¢¡ÊüL¬ÎÏrýƒ?ïv¿ø?ZñHiþŒ3Í/ɘ‚Üzx~¤ÇXü¢)vR”„:Äx´IÚ5ÙKF'½¬Â…Òµ¤E\Gx}f¹ŒLD5½(t D_¶ÞÙÒ ‡¾„þî:I>w—‚ÓµV_U í#ù2n¥lò+ûxÑé¾@:ØõÍÉm⦅8މº„ìÜ[ú}l'¬r‰—‚ =¦æ‡ú^¨ápóOýoÊïï?—{‹–8 "±ÝÑÓÒ³äß[Òòk˜ìȵ…¿Ï~õÝnüP•žõNþúUóÏT‘ˆcÄ΀êÐТ)î3DJ~\‚¢tÙ÷6™›ïä㱪9M(â·:ûøÏ·z3ñDøˆ|©ð]ÞGÊQ¾@dI—ÎW¥þçÉêL%¶!#>wòæh¶+•QÞRK#´Ë”ÍÎÒ±°LïGr^O3ˆÕ×zðÜu«[`ÚÞÓnew7èú[gÞCrØu jïçNŠó¡¾•§*¦Æ°(‰Ð©‘Wê–º”œû9IÒ% ÊûCpAü g_þVE³{•¹†¿œ¶Õ|Cc& Ý´E\´Éüó2ãB*­ž ôqˆ­›Ïó[ÄðòÍbX“"à?«nµ£”¡ ž=37çlmÓ: Î?^^´69 >ãˆûê§»wGAªeyGRkÆ5 †K¾Q›Cå”BÔ!I Þ_¹yÿÄ;¬®ÿ1ü~ö ³ö÷2¯,¸36µ%Ï‹a—ñ SÈÑÅ‚kÅõâZ±˜pî7Oj…n´•çfß°fx7L,É [ªV°ÂÍa 3ÚœìZãd %¸>o“Ux+M†Aì•>ì>\z:y‡úä÷ÉÎÖ«`Dòú›–ÎÚ´õ±}ž;WAdí{‡;§]gÒ´ÿ$¡³R‡M\Ax‰m|²„ëÿtÿÆæ›s‡%ËÔ@ºÐ¾ãKVe×Tå Þ¨´kÏ[opøËú‰Dõµ˜˜ „”§t¥àzí•5~µnM^B¨À¥ecúÊøò­+Â*<¡wAÝuàQ¥Yd½s}ufª‡m«;zF%ýp0Ë4µt€On0åw´XŸâ·Cô0åI+zµ< ù C©p“ù„L¤D ˜Â|,àœž:߬/ߌ>GdȰãÓÈ0àͯjªì*FŽU •JPõa÷­<àÔMNб.LJ*ruãTÿÐÚÑf¨F“‹×Mþ¸•M¦{ÁJɯԲ·å»i®·I¼}8zRí—?H¾4èeòÅÞm*˜ÌâÁâˆÄŽÇ1~LÍËÖó›§ŠîÕ;EýíØTmJªöJ…òÊÚE· vÏ œ¥Œ&›ø‚¤ûóÉBzø•8û2ˆ•+"M|”Î+£s!­LÐ{*ôÍÝÈÚ͹äc$«qIar£ïÌ$¾÷ˆb|Ñ¥ÄC©PòÉÓâmX]?wLìîîÍûE<ÀEš$Ù”l·vFýwÞŽ¢˜kc‹P!Ã7ögƒYd{¿¼\ëÞqHà‹ô•;ñµÐ›À±„ ]kåAk¡ó1}™†–$Ô›1n²1O€8ãSƒtE ü Q±Ùž³?^®ÐuxÿÑøIÝò®0R鬅ønEz¹e”ø§ž£ÐÌÃU”‚¤cïƒx<ø½"ÁbRó*úѶahÀHq¦ñ3u€ö@)Giž˜äY0Ÿpcj?¹‡k5w•Küþe-Ý šC3%8/p°îÄ”ˆé©Ÿ+Lõp‚9#œdŠñP@¹ÊŸöžÑñîÓ C )‰sŽßíÙ€;xÍa^­7˜^)2x|ìõ¹m (Uîtï}33¸ëÕ*ÌOÅŽV1:ÁM !?]ó!Ûœ«%N8a†¼[ÄKb.]´5I’kô ´É–Ä´•œ™ˆ¶s>ÿëxHïžÕ悽i#Ò;$\µ]äÙ•ƒuª áTχ&¼Þà¢f7„¿Ÿy7¢¤ÃÊk,õ馎ÞÉ‚=j·M_ô}—%AG´I@AD’®HŽÆ‰D3œ­+?n*B‡%‚ÚªZaâGO½ÀÛ])6«ì˜RþNÅi@•C ü!™cX´K&6Ý«ñ òÌê댠Žï‰žS%̸±{xÄ ñJJ´ò£Ü'%<€`âJî;©-È!xqʆP¾êl†JIïYõ$4ŒD zÆ<£Ø·"i›r˜T~½ØÏ¥Zõs˜{ 78n.ò Â+¾Ò*$ËÉ–Ö×P>=AQ›âöM¢¨YâÜWGÁÏöóL™o(”,É =Y ëy!!š(äÒ/»c^áôtë¯ù`÷hÊff[ƒÊ=Ö|)~>ñ®”O5iBu¶ÁŪUز´\ŸùéõZ$0?B‘il)™TijµWo…yšàîO.iùMuê¡`ɺå«ëad¶GÓ7%#ã˜:j–2!ùx4±¦ùY6éF/P±ys$ú±ñ×»Kš“¬ƒP¯ó;°È3Ì£k¯=®Ôt!¾Ýßv³¡Àtiœ÷¼·©;/®¤]ºFh5AÇ. qæçG{ß Ù+¨‹‚“Ýî%+à¶Ã})ã*N¥Y‘z Õu°n$Ü?eÍ‚¿]{âCõ¶g±¹w2xIŸŒ°5>† F0nèËÈA½+'+ß±’Ž[|ùåâNù=àM!7ŸL½fÐ"é¶¢ ħðP^X*"ü@‘T¯©eÑRí{*Ÿ´jI{ò“ìjL ù{‘Æ9 ݺD”U¥{*®6{4v©éôÝÐstËÚ:y÷_-Ãä³âÞÖôà7Âð¾a;XQsÆ ùÜNjZbÖB DcƒŽ»|vM+»Hßíé.Ù«£›L?K}÷E¬­ÃæJ3‰ÑÙ í‹S»EÄØ(A9®„é§ô^%¥ìŒ\ m šPû…ŒûÂßoH¤–F¿v²¢¨à„.K×1Ô´2)AV‘¸IN³ÞÈtÒ#!,kùš ª~Lϼ4+02ƒœd®>Ýü‚œÝÛ˜„Æý¥‰uYw/‘( ²¼¬B‚LöÔó¶ÕZ-އ¤|zˆßDÀ]f{¡VøÇe2ÜÙ·˜åˆ‡uíÂô’8ACâ¶GÁÑ{á½Ø¥E‡ j|±ÔŸ¹i&%ó‘8™˜ž…EŽ6ƒµj"»\‡ñÚq>¼ô` I`›‘ âXÔëhC‰—z¬ZEª§6Ø}És¹µ§åú†«Í6j‘Â3$÷¸¶Ë—°c@³ñ©ÆÓMwÓcÎÌ©D§Ý<’E¨üm]eár‚¬´®›ÃånÍy> Å—¼< ™»8vŸÓhOxcÞÛÚÍNÇo“Ýë2A¹Çnš†&Ê<'¶ Ù9ßÚ¾XË+»òidŠq|;+NMIpß|ät)ðr[T¡µ¼ñÏN¤ÕÒ©¡œ6ðªßÈ-Ê 12–‘…âN¦! ¢§mC÷<;õ܆iP2 .¹ZG$-CÀ9IW9ÛM*ëA³¼Žâ²<ÒüÌÿ˜tl•ÚÑZøf6)Ð S'qž‹:åìÿ@‡ùt*áþåC:cC£æ·ÚÌä+²䀂زcA\|b«´Ýš¢\XÂÑÄ ùò°øÐmÖ`F ”6âîxOIJ!"çÌpê@0Íá-`‰èyè]f%ð<žËJlWåx²ò«ÍÌÔ°éŸåÇäæõÐÁͤÂ8hu^ó…7¨Æ$Å¿S[¥ýðÅÓÌ –T‹žÐ-›ô_BZ@ŽºnÍ®˜žÝóS=LÒE%'|±rÐãbãÖ›»ø™Ä^ÅÂGðÓÊLJŸðå-g—ÏÝtRCF¬6l+â¡rÑCžûg´šC½éÇï"·l†¯&{iN]]¹cç¿‹:CÂ>S`!È]ä …*£u£k#8â³.˜ü²ü² »~œ%Û”Ÿ#ä›öUÅŒ£^@©#l>Oéóv]™i f aäW=°YºUˆ¤"i3(‹9ÀZS‹Vé×/A]— •ŸÍ‘mØ]@¿B\·¤j££Øi)œ%L'&~f掋EUó|8Ÿ›`©±l?šLq-„ÉBø·\vD„ÆèQ¼ðήjß‹B€Vˆ°{7#5Òé¼@ Þj¹Ó¼,(éµø9Ž:¤KM›‹ŒHq’:vSHÜ ˜*p*@x¿×Íñ½l휅3er‡xêkf;ÆÄM‰Ê.@Na& ëòh´(ÞZ]ÁíÜF‰ä]CŒÙPüj)ùÔ¸N?Ô`rÝ©Ca~émKîÀ¥Ïâ rÆòC‚Y™Cƒ‡n)ÃT2¯áîfÍu?õÕåÄ•Ï2g¿‡Ó;G{ŠÑFAj”ÄidE‡GöQ ÁRÓû6#žè/à Œýy¦ž¹“òVî-§NB)_]üœ<îÍM}ÅŸfVT¶÷c1ã°šYÖWç+„[ÈÂ[‚à¶t–txβLu/ôúèkUÅë^à7cżµÁ›/-Ñ{èŠ6Œp ,îš'H|‘ˆ"w±Ì6f-´£™TÎÔV•(” ¶JŒÁ0Ϙ®ÀoDáN/0ͽÿQá0ÉAÞ¡…pJ@•}çÚv˜ ·W™w+Édd¤8š¼Á9¤ €hÈœgl8–e{ÛÅŒ­€ãé9ý íU¡«{þc $oŠJV)A(z:[y–“2¼!g NO"w~>Võž œJ@,nت+™¤¨EÉpkµÿµr¯Á”~Î톳 SVŸ‡Ù܉yøb{WdâÀ‡“OŸ£2aŽÖäo¥úZÁ½D¢ÚM"ezM…cqq8€`uHb0gщtùo &eÜNm «%™>ßó}.V¯ÙÆáßs>é+8ÖßTª è³ÿÎLŠåÅ‚H)ØÏ¼ðÓ‹ê芤!-ÃÛÑ£2¸-ø˜âŠöàè¶Ê´Uö…&hÅ?Žg¯ôÍ-ã\Œx·eß,ø„¯j« I$G|ÛçzÇéø»Z•Øuz4ðìLÕ9=F›¨ÓY «'Ö{Çì$»@—¡ü”§´ÏíK%"ÇýïŽÑ¶æZ5£¡­OË­éL«õ®c•Ú˜h*ø®šËJ4”wÌáï{u$æxnÜ"†i$ç9nÚ¹¶88¹Û]å¦ëÖ¸Ô8 b]‹àÝ@ù Ó’Û¬0;øZ«.ÖC;ŸŒk?<2¬¼/[ôû4]ºÙdjl¬›£}ÊFÝ&Ú9ÄânΟr ”?,ÔÀ´9´ŠF!_ÛôpM‰Í“àz<²ÚÉú]*zß˿ĄC¨óC¤¥}âGÉ;ódª‡^ Ù ó” ƒ"wºÌäå/ó'>86;‘ ªÑ_Ë‹Á2³‰ó¾9y)m ”ϵÓÓ‘~•Šýêñáy®¿$kü«ÀCô§‚TËïÏï?pÛ\݈%äø_¿Š#ú$Cè|ì@Gª|âß 2Àaöƒ·¸«:´1øzGygSM'B³ÔAJ\Rx c÷®¯óŽhU“.)Ÿw’í„òDŽ& ÓŽQ_ØrÓvwKºîصÙ+»”0(ÏÈ«±íƒ@aØE¢Ÿ¹@Û5{áû^-ÌÍ~ÐóÀ2ýpQ‘þXû©Ú-ö¾¤ÛŠÌËבøz$›É |몬›vuß)-]^AqhùfÒZÚ2¡©š–±©ƒgö«™ m] &7exŠÉ·s~J÷‹˜‰·ÍÑTøÏD¬ƒ=ï4Ÿ }:²3ÔúÕ8…ˆrw‰ü‰B2ä\ò9»?Ë/Â@ e´,8Y²áï[ìH-6B‘6V.oÂúB>~k…Xl*ZJ²é—l0º¥š½?¢=\‹/_”KÞ:šÏh’ªˆ2Èìv周‘Úx½¾%úI‘n™¬21Ó«¦¥…ð$<ºÂåSÕ.ÐuÛÁV¦ñiÜ *#5?ˬ7…uÁ†`lãéöŸi•q%»ƒGÅ·¨v.a!DKºàY[øòÜ-k¬î~g+Ø/Ñ3n!ø…¢IvÖï‘Ο§¶ª$y’:ôx‹¯‰áË‘(Š82®û¼Tûj)ñÝŸ[fâð]C#ãÊŽ(]óŠžiƒSÕ" J¾}u8]h÷p§ÕJq›)JÚ~ ên²‚{ºµzÐâ#g÷“7|N™‰B¸èÙeª˜Ä‡9ÊÖл¤ñ.«I:Ñgyšn|CÄb™}ri;W3¼…¸e§v‘‹ñ ß”1QIÙø#ˇ™ŽÃPÔ—;Ö¤NÈzQø4+%+Ñ.Qƒî×°õ›—9­¬ê›¢®àe­oÎá}뫎xˆ¦íEÅÝøW#eˆ×pQ«öO—Óx^ŽdßLQLàbR,ìOØsÑ×Ö‡²È´=| :{Æú¼ Áy;%Wæ^ŸSÝkñx±ò#KŒwG¢€Wª{çx…Anw^è(‡Ð‡·~y1 ñ³KœÞÛ Ø„Âȳ ôoô#Ç©V]WÇ5q‡m©²Çég§J2éuÙ<«;É6çFÒ‘ËBÚš«±WÞbõ­çÌ!œå*ª[ çNcõcÕ±/r˜à4Òt‡‘!?ÝhÖJVIo_ºâ6øã€Ô¸CøÂâ0*Û¦”(r?>þQóÚŸfHcÕ>p@¡‘ƒs>áÏòˆÔ—™w—\& ,Zëô»ÞFF#r†0\¬Ü:ò|”¦uÇÑ#ÓÿF¯ö$©œ" Úójž:´QéF…íHŒcYLË­IÄ}¬Äšx\ŒàóWþkÒÊ<©¸5\]Z¸ÒkéÚY\ÃØä>ª·46’sÊYXäbe;ß„w-ò»,{.5aüm‚2&D„*NÔhfax ¹¡F´ı^`;‹Y2ú)À4#›T }³™Î’bL}Ë‹N=ÊZùxP]]Ú§eh ïé„Ë>9’n..ý4=/å(¹É*Uû d$™Á|>Ñzg*Žàºò– AR©³¾¹¼MKì]òsu]tx\¢ï`äq1` Õ<ö™*y¹c(µv0jœ¼b™v\‹m¨Ñ¹axþË„…­7ôÇËá6óž\¦n™•¦¡^ö_Gëõ}N ¢Cü<͸fU;|>ÕöÁZ‚¨Š{û“ýÇ“c]4$;H=üYX›…>1™y×¶íé Vµ%žE³t· GÙÈx¨–ØCA7"pÙÅJN³c/Èô2±!5ì›f'ï^öPú¿ºtf9Æ3ü€¼]ÓõªÏwö-ðV‡Ä¡.P¡K%ÒÑ^s_­˜Wžó¡ÎùaZQß{{&*>̯Ú ß.]je]:|ŠÂÉñN%G{çÕU÷{‘GêUŸž5")=40f•ÑÞånH]`(¤03ID ?Ø>±ˆæ›öÃm¡æ‰ãH}“ØQ*ï–@å û5†ú=´Þ¢{¸X5 ŵ!tÀÊš®ë2?x ‘GÌqÝôС•—d/}:×Fq0Û=Gà9ì^í>Þ–™[mvnö²Oò§€›¡x :£Túp˜n)¾B‹èÎy¦ÙËd3›·A=úÆRî+ßÛ£—ý¥;Žü;ÏóÊ+!Þ.Óœ7nRÙeàu›ßÌÞH°Ä£âS›1Å ìB²xÁÃÁ"6Âêý$±@!ôñKsYnZÊñj¦ÓªšlÃä¥ofœƒ¾¾ÓŽä;ÉJó_®qªŠœ=ÛÀN/¼ªdQ>{OwPÓ½28 "ßÿ”>¤2 f:ˆÔß`̸ºÉj.Áù†)`b(·D˜½vŽõø!¿tÕÀµÌrÂpÙ^02ؾšôº¾b šÍI¹€ ʦ¼P\E*…Èõ — mo¼7Ç»áY>÷–†›cßÚ2ÎöàX=â‹Q’¹¨Êå±LÉ V.ˆÇïœÆÅ‹–ʰ]U˜# § ûâù<—Õ=1 ËÀÂy$|ˆrgØ,øT}åJÁáá;Œ²ixRi¨cí—ˆ¦ÚKà±F$4úþ¸$G%š¬ÓšöSáµ`ذSeÜ z¦š¥J¨æ•ò¾t’¸¸ùëæ8pƒ–×_Û€.´2cO2ÐF®¼Mîaû™*ÝSw+#À]K÷ÔÅý£>è_Á7[v :AÐ=^º-¹ˆ12A¡¨Rd4VµÖŒ´ä³¼ô—ß9›Ö^´)bí^ƒgüUŠ¿ÆIrC<𼟩åfJá›aN` ÈTq/Y•ß:%sín´é>]¾{k61ÃQ!Å‘áu®a¦Ä¨þ%z!*Ç¿[*Þ¶çmµ•a£9exh¬2Âû'ô‰3ÖÜ)šâ4‡hõ£@×a—S_-ÆÛŸbfó¾bÆ-'›“è¯@Bß7ˆ½¹ëœù_Õ¾29¾éǤ»/Å¥ÌÆ“Zïw! Ž^†:ûVÊ_1}ÇÿE€R¯¿û¢ÿ8Ô„ÐA9m!Ž,I’Lõ¶d4ú«ø3;–˜RNfNm›mÂz”£œÝC2¶%lÉ[ß´ñÍ$=!!pˆQjFnÀìÓÙ¶ç¥Fi¿0ºÜÜÁ"SˆÅòþ5b,b…|£@Ù>¡lîñúP/iÐ5Þ›’§‰³{õy¡ä[[¸³—$zÕÄ €.€Øý'Z1krÝ>-ÑîM;ýëЦ­¼ék‰]ƒ…Ò4ï[Â7½ê%ÖÍkÔùx[áãnŠbP©Â^/‚ú›wN"Íñ*Ü Ñ 0‰UŸãc¯¶B ñΊxâcä/jH]ÏçúVä“qw3=Ýì<1Œ—™¡:§“õ¾N¹nÖž™âÇv|·uïÐOcdÿ±_Ác 뤌×t°©ÁÅ«$4Ìeß©—Ú†êj&1ˆÌÔ€F«A‘·Þ+Sy6;'Ê6Ù±Y,@ š:v_mN"Ê×ʳRÈè­^æ1U.å=µŒâ +ªEÑ=Ý’WTž@>¼æ(˜åÃv†•FkêðÚ§«&z.ʽ$fÉ:H“âÚTÆ#·ÆÞhkLÖ7GþÓÜd 7Ÿ¯ÄOŸ’“õ­ ƒAŽW¼Í ÉàGHÀíð\Eg3ëÛåjäV_‹±Y 6ºoÖ9æ¹èô&šgý²Ìkgh°–ugäxlÅü;ÖpJ©&µºú*?ßWÓ7\¥yŠ·Û³v@Ÿ¡ NÂP„ Ðv³`[Ïз*¾j¹Z­ÜÖÍ@gW³ç8ãêv‰¯¶š–*áÚewå,$Îi!¥Z°ŽúÞ~RõÒîÔÕE‹¯{‹;*DÅîÐrO¥^´§Qbž²GÎp]8*¯ŸR¥â91iíýˆF~OäÁJj\ÜÒs‚]'G ‹ =u:ÇäwÉáIP(É;]ƒwÀÿå,&V8·5xl ØW‰§êwÔHÉÎâÀrä+wÓ¯´ñ¨\æh×/jÞ;ým?ưýîÃPGí„;ßlà]½ŸoÞ‰@%ë›b1h58:eÑþ4Ô‘Ÿ½F¬%þð#»*ùMêå»ñ) e,<.RînïûǶ'2‰LSNÂ4{CL–tÖúBÂÀ2øB.䯄y^Øàá¦ÇI -ûú/Ñò]øPšxœÜ^R&C7<·á¥×{Œñ'9 ’ÇÐú»àü oŠ*ñ¾-m«ýLNjËÚÞÆ|}ņg{öm9¥*À‰Ò"íz™Yæ7S5ñÐ>ô×î§ÕÕªºMÜêQ·yÇÖçœêîLÑŽ.ŸqÜ :‡|#?b$¯ýéjâSÚ~ÇWŒX$c:aCMð¯¼í¤ÅŸ½“Sf2ʃ«#3FÚK¢žZI?›g‰Öc”®Kn$aF"ØNaÆ›EU±{^YÒÂ(ß%ö úì÷¶F:yáã#*?>°öaŽ6Ÿ‘·’Ùé¼éïi h*ÅF „?ÆÖ¼i9"§2ò`ýŠ-EÏŽ4ºB Qû©B:ú>ë)`ñî³ïò8쵬J?8¾z7 —ÍäùˆùTjV}†<íN‰gjtú ²äÛLÄ•µ¸½Í,ä²<'ÏAò‡UõüUŽ·Xâ“ÓUiFë7^Žéó½ÑèÄÊV•S]·#AýM¶é #ñJ´Âä$á]&üï˜ÁR<ù–p E5¬fbV PV^L`fÏE#äÐà:LâÀžtÜÀÞ…w¥:åÒ™v<Å;_ñ*í¤Z‰¾Kt!yŽL¢__ZïFhäOþ¦Ÿó0èC›I Í´âh'Ùòx5çÑ![%ÆŠÒ“—cÈÐT2ø)äÝ;£NA9ÝÐ\2(1”su“ÒVóˆLãU+wȯÀ÷vã`Ò?kǺDzÎý2=kobG¿ÍÏVø¥Žxª8¿w¥âm‹¾¤UA›6޵/·Æ9‹l—="g×ì¬ÏûôscÒ]?Ï j@#Ü·E§SK’ͳөº"â8¬ßwÈ_ä#hRþŠŠI? 7yæÃÑ{ƒ»ÚB/̔ƬäÞÒ¢fSú¸ÞÓÀÀb„0}×ÌI®kò¡fÕ–J¹PW¶!ºw.¿·¦^Šþ§Š®¡I,É6Ì€¼0¦Ì)W\œçÛd`])»¸®Pнˆ^ѤsþzRÓ”žc;¶fA Ê“»ý“ß‘K¾Ù£­LD#q4¥t·HÁUˆBÚ ¾óÛãû„ƒóK¥«ÀbEÖN×|Ìm·%µ³“ÃWŸV×öב«ŒpîþýâþÌ›¦ ïÆ4\hËïëûD@[/$É(¾×MXή5tGÑ“í|WMu3sß0ÊôWw 6lj»ü'ÕÓ(è–»ëØAB÷¨tçx¿5åÌ&E‰¡:®ðŒ& ÁþÛ³hÃkaÎÑ·ds1bs/ö#[˜$ygñØ#*àGü‡¸~O?Ìpð”€!$ÃöýLÊ"î¯7¬ÐÚcŽA¯!ˆÞ<² 0jwí¦Ò±-ËØªç¹Æ‡ýTÌQÍ^î†-rÛ"¦ØO8>J2ßÃTÓXðÄn¹’.<̹æÀš'0B¤Õñºh÷­7ø©Ðïí-Lqg\z{¤š¯Ò0YS ­§ï »ÕZ*xÎÛ§4ס¬tP¯äøký¼  ©©øÌŽÓ;BÑ"!¦¹}'b‘åâXØSn{Ž®ôôÊé©4„šCSû]øsVêþ+ÌùÙ2#\a‚ ‰øI2“kÞÙy”oŒRgL¼Dþ¼rœ9k°ëDØ ºâ/æÑEWb—qÝ;XÖÓŒeld-O:©6ZÒF1=޾ ‚Í¥X±Ó"ð:BF½ÞÛ’Çt8e ç* pCùÞ->ˤaN—t£ùƒA‘tºˆ?%²\–Pô¾LlcÎAïNk(dšFf‹J-_úõ‹ž³±ÁáО†·1l¤÷ 0ïp….TE> X¹ÛpM9A¢ÓÜ3;¿/bàˆ…æš£Oû8òÑ×o¥?è£` 2öƽ®é¶›ˆuQ–vÆÏOþÔ%«©¯ŸOY÷hQeýã9އt¬Î[™ÉÃož²28=-Š­ÎQ¡25࿞nËÖ_Huß[õ@ë]æ4ô•܆wÛ ‚eéJMÒ^ÂpxCv\UkêüLÇæÅô÷yƒ}{@ÂcAºuãBÖîÍâ†û€ê¤ñ.H•®Rj™ó´f´õÈ_+z€4§…Â_?ÒyëÃ~†DsUt  B‡îÚé(R’¦‹ÈÁ—ÏTxóßz®ÉñU$àf7dÓ¬“§ZxYÚͰmDå©='R#±{Âï#ø\T}F žlúÐl¦9A½Ú±ÿjYªvRW]¢tˆ‘­–y¹æL¶QwúøÕ‰ê¹-æG*ŒœÀèÉ-9.FžnC'ƒVGZÿ} ûx3ôß-eØŒ¢´)Æ Ñ<þ}…Ö:MéŠÀ,_ö…¬oc!ѸV­Ê>®Y±ð<ȤÄ<rl‡mR6—¥Î„ eêÚ"2|CºK-ñ¨×~âfs¬ß²@Öƒo[ß6š„»ðÉ7ÏÒ²¡Cé®ä颫3)Û‘âw.Š”WÜÏ·†Sïq°r¢ÚÇE’"õ8­ ¾•³øÁ¤ž Òmü.«›á ­W¦LÁ` Þåh)ÑéIBOܴ̕a|¿ñlÝroM×±9…“°òpþv.±Âc;Ïõ†ÍpŤ8HtùtŒo`qÚ°Ê%´ûÞÔl7ç|Üpg_]8ÆôCæd^dšë`nÕiíÏQ’~ìé'ƒ¥s¢Þü¼»ÌrÅ>oØ6ÆXºÆÜL4ÍJìÖØ@îíQˆ¨Ùr¿<ðy Ÿþg š3…bšŠïª_ƒå…¦hÈðý9ÞvÁÏ:!hU€‡/uÏQÇ =ú¹ËÝZÐÃ7¯[yisYhßvBkë÷$SÁéú·°,hOQºóh†H;®iU{šÇWÙ±“(*-4’“&N5Ä7[&õǧLYd*…ùÓ _Eðk¢DíÙ5anKñ<õ\ú>%ˆ{ãPšÑå{ë럑a^Bkb¬0ëÝ›Õb¤MÖ±‹’߈%îí¨0dˆA¥$ ‰•WÞ°-–7V[Mû(1r'_ëcï2L%¦køÖÞËQ0—U2$êÒ~îÍöôZu˜ï5¶‡Ä½ È{ªß¯ÛAc€„4f…œ$Œ9°ûÀãŸúa’a¸D§Ò >Ó2ñâCË+nH¡lÕû:^ÿßè!?]Ï€J‘`åb‘hA‹T˜wâÇ~ Þkxµiýƒq-¿Ä?$<ÙRä³—³ÿþ'é?¢oP\3Êê©Aù7ä.d‰Ý  Hº4 K¼pw÷Sür]a;žl >/«ùy#Nj³¥s%éóC@®äC8SI¶éžu—Ù¹Ìc©d†‰CÄåS»"\+ãQæ¨7?!Ít%×oÇ€z µ>C)¨–…Rsì‰Q8¨‰¾%ìg}‚þ€}òM¤‹ç9öv¨…ô—'#©°<Én ÞîŸM£­•¯ƒ¨³Hj‹`©3Zo£ÃL3Z‡Ãáþj†d8%iªâ0¸òM»ß#úù} KmËcþ5s\²Áë…q/ª¿œc?â»+é·J|,ðeSÌ3&ñ óñp—:‘D~6"óô„ Õv[%Ѹ‘Ô¤FµÚiˆ'ÿkB‹ôùÂg¯d&Ç2@=ÑM3¹DIìtÕŽŒͪ:‹†ÑÎìJܯQLÕ©¤.äí™Ö~–`.YAø1ЋxK*ð~9U:þä‘ÁÔ8*$ˆµB"‰Ï*R“O·ÚÃØ•‚‚Ó$4G¤Æ{›óbªˆ!Bê+Ò DÓBæ-x§ÃÿÑàÔá¡;5Qìê3ÚξțæSXGÄÔ^[93¼éìMù\´#$dòÚ²Yiô‹âBê)fTˆ‚ʾ¨ˆ—°Üû ì< ÐZî3£ûç‘i1æÂ´•@Ø•`Ù†Ç3{]‚·Â惪l;bpʤr¼0 ¼³ŒTè]¼ð±¦¬“mȉ³Õ¬ÌRò¡Zè6Ã=ëÝaIç››`xg{`n¶“lpÜ˳¹$Åœàu=L¸sMιn®«ú"ÌáýN|B(_÷̽Íʼ„ˆLê&5Ü÷“^äñë‘è2òúL?“Õu½é[ƒÿQMÉch´eWy ³PµJ¦û¿&Mþƒâ jcŽÄ,“Û<¦!§©VšÒ‹Ê'_ÏÆÉ^×’ôöèq¼®826¯ª=$Yíc™›á™Œ`EÞEÖ»0¸„·ÀÀ¯\Ž*LDª†;vA•äQ){ô÷¨”•íÐnØäKǰŽëVÈÎMÄLÁöb#k…edû›1TRp š é]O¥-ÑHà-ìHœ`î*‡p0jt/Ÿg#?–€Øv%?›å¥r(«MA‚*%~P|¯g„3yãÌm ܪDŽ™9vƒ«ë×Ý[ñ–²„Ç–㬠<ÞzÀ¡˜k}TmÀ7tÍØš«×øcQÒn–D8$¯hª^‹x# <]“álΨ³'r=¶q‹»£—Ã.tbN²°q ³=){yG£n4ð€Áó~nZÆŽð@Ìõ=›m±ÀÅUœ_#O$hš-äœçü rëèíLÆ| ò~ ‚û¤¶{z,Ì;;Þ´¹60°–"zu_b£´d 0mm€8êóL¾Þö2`‘DèmçfN½9À„‚EHáz‹\r&;/¶ã·ÂôŠ ôy“ 'ä.׌xƒ V'V»ÔƒV踟mR“%ÝÛÅ5Ęëom~áig$*¾›Ù…g·Š`®o>ÕÖ†xæP²ëÀÉqØNfS ÷óä"›>:ûV¾¨÷bŽ4Ÿf˜™&úTriû×î•}15 ý)`Úd—€/Ö&@n”íG q 1„¡6Ç“lÇEÌU°fEŸÞ7Cžj¼6Ì\6ú^½ìœÛ¥’ZÀ=˜xP4×6jà„¤£!*õîk«£€-FÌ i–˜»/B„,T¶f#è{Xr¿Ó!xÌ-ˆŒ$£ó‘¸avB°ÅËWèTŠ9Îëv)ú$”² öÚ8·Š€L.rR«®ÇÓ´Aã¬íŒbض18q¦ÌQoëÈW“Ýþ›W¤= ÐD‡<09Ï[`ÀÅ… ØcÎ+ßçö­Þ&˜q:$Ñ~Æ¢1j2ßrof Bkañ"H×¼BsT_Ýâ¡–±`1Ü?í–%Ý»N¼yy8åo¸fš„Š€VÃÈð+;µtWJÉW¨úåè¾Êj—‚h¸¿LštåI´ÛeðfÃç™÷Ô$¿dLžË&À P“¤=Íg½Âù_ï43ÎÝpÙ<_ÇÍ HÖo«5Yü³øøï7¤ÓÒ@€„ß%ó8Ð(RµÞ~¾ÐsT¥Ïq+qZ¬´ þ+XxÉ|8Y,µ†‚`#qÎIíÍoÿ÷õ@_ƒŽ‡17‚$­7iÕß–ßþ³KH¥–JR\ãõhGÔÙYžŠuO nkB.V‘}íÊxó7;¶-IÛf¨f%G -^ÐLK|¸+Rĺ~1‡`þìž *øê² c@îíq Îk”uÅ9“Ã,[(S·ÕLðÞuo™YÛÛ¬&1²2‘‡N˜"ùG7A»ï_Öâ7“•ß>ŸÝ]¢Èô–ö Û0ÛMt‹„ö•§rɘcФDe˜4èÒÿLgŸIûÆÁ»ÃóÉMÐþŸi4œf%v¢gÉãd-gSf€6N Å4ÃéÂJ„©ìïFã#ŸÝjWi» E8Ï[iUÜt æ[§ô‡%€ˆz"û×LGâW„lsu¶ _'YkYFåxÇu¨:Ÿ,AžÁx%]a¡+l½Ô(R¦þ¹§–ÚøãfÕ€ØNwë ¯é¸¥Ë‰ùˆS(=„`¥¿…|bÖ$™~k žÁ‹µ‚%¶‚î)«n€2~Õr¼‘ è|Yé!/wnŠ¢I/WÒGRP=?4}._ׯ"W¡\SCŽè{F¯¼B‘#°Å “îÒL(gd × }ÜSbq €àÃç¸!Ú¢ÞZ¢ÍåMcϘ}vÖoJ«b„¿© Ú¡)‡ÄdÕ¥¤¯Šk¾–uk¾‰žQðƒ¯u~lœ'‘¹­â` <®{ƒ½è °µ;ÓÜG_ìY"E€ol€_aysšü†wÅø´ç ؃WÙÊÒvô9”Ü d„¿Ú´Ö^Ÿ€D”¼úX™ ˆB“½ëüù{ž~MÐ~!Ž#AÓÖj̹,w—!ö˜æÈ—/;¦üâ¡ØE|™g—j€¹©b©—<y‰§YÅéãN~=Ÿ™XG—;ɳžÇÉ l= ÔºŸÑä¡ ,#ףĥÛv‘Uƒ™ìoo€/SCîTÁräJÿš#ª|¯i 0–o­Pw*Ž~c­Ä•JÅ‚‘KˆåÙÞ¥¾óKVm:=ÖÙþù=J‹Ø€ˆA~ò¬N•¨q¿¸›Wvœ‹ê}É•¨…嶸Ú `þ]áÿpÔ°Ü•q n(særƒïÇÇö¦ñì4ÈIj˜_õ¯ù´Ù1ãV¯rQ$`©žZÿÚ5|¡ÿœeè®Þø¢u|BBSY ¶(ÑXÉŒyÌs ÝÆ>½‘Û¨!š½OϾLC%á£Ìù|BMÌv`doPYÒÆi„$;ÚÁ„ÇODÇ"C ¢2j<7-,D ±Íïìýư1Û:&&ß4œ­òS6œ ùÕ´9â& ÆV{Ò †ëÉZs^ ?·ìytÊÜòAÏGµøx½øý¢V¨ü 'ÄÅœ—;sê7/€_rRf³Ôõ¾3Þ5;2««2_í£ža d’d^4þðæ”XR©F[Õtö«Ø(å÷«øÊWòzÀ] Ú!ù‹Gº8¦6¦X}¦hÅjÃö -äå¬0˜— §Srõ#ûT_`òbUÀÐÕÄâ—[§†EŽw»’”W0…Öñk;Î)® ZÀîù&É#J¹zP/:]•ˆ3Á"Ï…ùÎÉ Tg÷Í)|_;fžw´¿ŸcÑì™$*·Á¶ü=¨s÷‰ùƒ«ºü¤Hl3«… ]Ê4y¶ÈfüL§*©‚º°×Réõ‘…Ú`§ªz®Åýœ‰ Ú!j2‹µgÒ .xsùÏ­Z¨½IÔkù-8î¡„c«£2ò+l*®ü‚æ*ŒÁÕÚY»_í-#ÙJé--aÈJÃŽé?'7%]f¦êwþêì¥Z8+F{(@¿™û9+ß2$9¼¦y˜9B˜Uë׿ =ê›Î‹˜ñtW§~§]/{nnrA¦v 6P#XºÏ‰:ÛÛ•_ÿj¯ÿJ·”©žr)—ÐL¿LqwZýjJS‡ ©q"í¾­¤’6ŸƒhL^¬½m”> stream xÚµPØ-Š܃CãKpww·Æi qw îÁ=¸<¸ 4¸.GfæÎ̽ÿW½W]E÷Ú{m;gí …ª‹˜¥“9HÚ ìÆÂÎ H(©³s€@NV ™†FÓÖÍô—™Fqµu ü‹ ™¹½Ø$ÍÜ^xJN`€¼»€ÀÎ#ÀÎ+8€@þÿ I3[K€+@Þ rE¦‘prö†ØZÛ¸½”ùÏO½€ŸŸ—ùp€˜#bka(™¹Ù€_*Z˜94œ,lAnÞÿ•‚^ÐÆÍÍY€ÍÓÓ“ÕÌÑ•Õ b-ÌÀ ð´u³¨ƒ\A%à÷Àe3GП“±"Ó4ml]ÿ´k8Y¹yšA@€ƒƒ­ìúá¶A/ÅrŠgøO²âŸfÀ_g`geÿ;Ý_ѿقÿ6³°prt6{Û‚­V¶ €Š´"«›—3À lù›hæàêôoæafë`fþBø£s3€´˜ÀìeÀ¿Æsµ€Ø:»¹²ºÚ:ü‘íwš—S–[J89:‚Àn®È¿û“´…€,^ŽÝ›íÏ›µ;y‚}ÿV¶`K«ßCXº;³im]ÜAr’Q^LÈÿجAnn ÈËϹ@^6l¿Ókz;ƒþp²ÿ6¿Làïëìä °zäokzùBöu5óÜ î ß;þ!³³,m-Üæ k[0ò?Ù_Ì «?ñËåCl½Àí±€¿?ÿ2z‘—¥ØÁûú÷˦$£©!®ÃôçÄûÄż¾,œ\nv?€—ðÿï,ªf¶uü'Tlåàÿ³Ù—SúOÃÝ?ý_»Áøï\ÊN/¢èÿѸ!hñò‡ýÿYé„üÿ üw–ÿ›Æÿ·!iw‡?Üôøÿ?n3G[ï¿/šuw{Ñ¿’ÓË€ÿ—ªúsg•@–¶îŽÿë•s3{Ù1°µÃßÇhë*më²Tµu³°ùS,Úµ~/™ƒ-¤êäjûûU°°ÿã{Ù, û——ÃõE‘¸@/‹óß%¥ÀN–¿7Œƒ›`˜y#_„ÄÁÍ ðeYEK×°±‚Ü^B/ãù¬œ È¿o”‡À&öÛô'â°‰ÿƒxl#^ €MúôâSúñ½øTÿFü/>³¿'ß rt~‘Ìï­ÿ›Ã`³øqp½ —upø'Žë·íe¿ÿ±°¿èŸ ô/øÂ°ù|Åö_ð¥ ûÁ—6þì/ƒÿ_2;ýSú¥¹—û_n›ó¿àKaÈ¿àKa׿!÷oòý;û˱ºýCx)íæéô/÷K§îÿ‚/Õ=ÿéå¥oäOú]½…;òòøý±œ/ºøþ㥼@ÈË NoÂìúnëň=Yö¦„æhöt2X|—!Ýî÷èˆi u9!k±´±~̯;RôW¢+ä¿|Ú›#;RÔ:üM’Ôgö:‘—>¿ž.9k"E"aÑÝ÷ûåâ§lÛÝ#OSàâ·®Z„së9(ãÕ4T¹:±°§¶_Ç£€òX9˧kü~ž¦Ð<÷ %‚ é+Fì3/Œù«ë9ìüégrù$&dÿã8ÎR_ýMŽø»/>kÕš®½„Ô„ú¤°WØ3´¾âéòø‹¾å¥‰Œ/¯»'·SÙè}ö”Õo!‡?ii¦è Ø`qåÞÆntÈ&;¾§HFàÊ=û*¿á%÷“·ÝÜ•Y%ÙöYÅ·‰[…¯ï>¿É瑯Q—1RÝ/­‰<ÀI ßD‹U¼g=ò‡¿n8b±6¾†ÛÒÆn*EÚÞ´mÓè|¸¦I1öÕkTnþ\Þg6Êãp‡Ñ÷ìÒ"Ûi¸gÒÕÒ‘Ð:¦¥%Dè ¾#-_…‰øíë¦\R÷kþvbx¢8ª´œ¬‚vÎU”£Æ½#†ìºƒÎ!OäÛ¨¡ï;¸•Z•Ïbu5|9X%H²ˆ ñw­0‘[“î¯e>o H®cGnÉGÅ?ÑG]èÔô_L~¼85*f ²VZkˆc *;¤âèç©$*žÎÆsó7à> ¼Wè`„÷û!öì; X‰ ª\bÞ Ì{pé‚Áî¶gx¥7ª =Ñ鞆GwÙ¢Ž½!ôÖS½rkƒÛ)‚y-üܰôÕù{°†v=´ˆ@Yïz¥Ù…%ÐfpÑ70PÐá ‡çÉD~ú}^¸5÷plHúè)ò]( 1¿LˆMPlÀôÉÅ<ƒ §Æ Z¸eOŒüÔ¾"™ ãÛ«âðAO:ö×à ceIâ±y˜9¬2ƒÍà./ýÓ%ɯ}æ²Xs5Þ¦(]’3D¬ ޵Æþðø¥:gD%È.G¥b²çºVÒ98*}cí^?°sòÚ|Ón•É !âö9%¹ðì-ßQµŠÁ‹î~'–ƒÇ×ÔÙjÁ#ÿfú1Îî—õ9©RÕ´a§2bõú9YƒˆvVù,¾×l¶.臱³mÙ¸jß;ŒÃ Þ¯ý"j™´¯³¹`õç2žJ˜ˆ¢Õépøy¶–äxŠÌøöè$s`f(ÉuÅçãmYwLß§-׌ÄÓqgÑDF’­ß›y8+kœ1Þm­4EH¸âÅÍzh›ÆûQÞ«U ¯xÿëô©ž¿ú·ië‘=þ€ºÏ‡n‡Z÷x>•Ft‘‘F+ò[¿Ä/×3ôER—2}Ã=¢ð¨X`ûìŸÐÉJÌP±ÊµðÀúŽ|^l“X>CÞTfU¤Á Bg5n©Vô€Ð/xïÓ8î+<çÔ³6õ|­›¶Ÿ8´#À®ŽrœÄºt–ÍìŠF>œ´7¹g1/Ɖbê-НÖäê°²AP$UoÔû´¡N´6ƒŽE(Êâ”–«g8¬qTVYqÃ5ySî?xN§2ˆ´Ã–J¼Ú(H×6Çå5Þ¶ÏΫ¸’Sm†¬Ü›Êx¶'CÒ[V²¹ì—Vî0¸•Â3k“Åo€Ä±¼Ñò9?‘Œ\ÓCë2kÛ¡KÕ†A{¤ Ýñ¬c±*—[ˆ¶Ë ù[õëKùø×Ì0Òâ‰ÆäwðÞñËD~¾ê!Eq<ƒÍyãâ ¼vr7DˆÁø‘A£™D¿šÌp£ßÓ >gŠòr¡ˆ>Cá}ç¢O&éb‚þ˜$7Í›µ¡s®žÝaòJó˜Ôõhy;%³À‰%I*bü!¡¥p.?‘‘¶ëÜy ²í÷¸Å ‚%+H0¶Áȶ=×0™ˆß#—p06F˜ð_ùÀâÂ/Ú1³z^Gmè|*C,hõ‹ñTФXàòo¨âÑïæ Úóu"Ö½I«ä‘eK)nåÊP_‘%èäþX3„°°§Õ‚·È,Mâ7Éø546 §:ÆŒ|Ï9 TYõ³m âU»w4ÑîÎD°—(¯·rÑaYNûÊãí„ȘéÌÄzmmç _!³q#N˜áà(u[>_ö¦%–~Gá)xíB~Š~Rß)ͪ4‡îKP±õ&K ¾7O®ñÄÑSžb’ÏÞ©Ãâ¡- >Î~HDñÆþNåŒq3] & ½´«gÕÜMCºŠ$8 ­ÂŠäÛ›Ï÷iÊ•qŠâ4Ư¹ RÇ,ÁñŠôÓ§0Âøè)e¶hÕ0ûc¬ÕÖñ9'Ž‹‹˜Í¼Vùù˜ŽèÝ5¬Âj?ç^7ÖùÏÆà*›iy±‘wYM]ÂÆï±ù=ò罉éäÝÚæj,•©N3BŠSçˆ÷ÍÔ½ (Â-)ºÕQ S³£²ZÏ ‚{vù÷ ð5j‡$-qì—ˆ’Í©ëïµÏG"*ÝÒ¹üm¸AIë²ÊQAÙ¹Rf•VDºÍR­i,‡¢&òˆlä°çe•ï+T^fPHã*šy¯´÷X:é[)ä[Zõ?zën u—SÕù,~]dýTq‡‡Ê} 5Í’"©ØÌmY–Ý;¬q±y_ÇFùö>óÀz²N•&å­ Úò{Oz¯WÁ¼Ø/‹£¡ÌñŽé¢G=Ë5ú0F¼[§8KÓ¨¢"1¥{Uó°ØpIRäa\²UKiô°ƒ5íØ¨<£ã ÝœÛg†QE ‰;­AKÓæžpÍÁ£‡¿“Ø„únžp‚ÚY";køˆ“i‚¾M)éK׊êƒöÛdçÂñ7 ÓŽ/ÛÀìøÁÆ Z>îj=1ú!ºÃä(vù,T¢:œÔ9¡q°ˆ”s|ü–™ VQŒaÝÝw:†O&\ˤýô ë˜Z,„-Öµßò c¥ô‡Ý˜Gáâ2TÛ^Â*äM5sùÜ`¬2b[>qî'Æýá° ¯Mp·(yŸÔŒ¤ê³pGˆWîjõظ ¼Ük†¢W)Œw[XdOµYë)Òç<°Õü<™2ðkË­%÷5éj/… ; knÐÒè[úh‰š¼Ãœ2+úÓˆiéCRwŒÄ*†OûËî¨~¬UÛ£pKÂLû%x嘼Þh¸&ñëîç"vEñúªil*ùÝFè–³Þ‹§ó6Rg|| Þ$jJ7\+IW_Q’Ò¬8íÒj_޽œDdÞÎm€nŒO€>V.O¦0j¼…'fŽ02M0”©°±r ¸ÍñÊ[² þ$ÕX×Éß³ç3 ÷‘®lø $£Ü£«ì,Î… åjdþÆ: š,ŽEQà[ì ^õJí„3ŽÙRú+ Ïì^w#©?GwM“´{ÓÎi¥¤`òƒE>X` /Üâ¢J¬fŒ¼ãåmd1Y¦†««QòØ@üNúýµ_S8­ë`ìj-.Å 5Ør:Ò Åk7,Lf¹Ÿá4ïD~óÞ$ü8Õ‰}Gp­³ &ªd­†,ÒK)Q®Ç¹û²Æ€ÚRRó»þæêì€Ý`ëfHŠ­Ÿ ë7)~Os ˜×!qDŸÄ­…¬ÑfŠ–,ë3˜’…G\žrÌÍÕIsD H&yûÏÕ$"vô@1Ê °nÑÄ9{ t'W88)X´OE‚åµ²XÅ–?¾5·Ð‰Ž±×ä=¼WpóàóJžT Y}ߊ>¦¿rþå‚\¼äxXjrftOUV)yEp"ÁÌ:|¥‘?ôiÜž¡Þ¤e)MŽQGu[A¤²~§ÙkàÈÑ™ÕvòÈ|gŒF­ž¯6ñT-ªÉ3Z%úæàû¶Œw:ÈÁh{ì)KÜùÞI|MÄl¨ Ú;uï/—ß·ü ÉÅd4–ö'"§AU%Þo bAx< H'r°;KÍI~%íA¢= V8[bÅD4¤Ó+ºŽ¿Ô‰Élj#ŽZðÛÇæ§EÌéB_·‚ðbl}Rë ·²¹£Õ°÷NØ b`ºI RB‚TÔÝAïñ…÷d§QJ} îëìT?Õ1Ûé| N}­¾RëÎÛì‚vÜykç耓řOñõŒ’vDg‹tˆiê>ÈGÑÈMMÔdW~§¥õîQeüM€ÿj9FÖ­¥pXÌ(Ñ«qô‰ô;4r뎈ðÐZN¥¿bò™°š(Õh|„©Ëµ  Ý[ñäyÔe2®Ç›¿NDz8®ï6áÓ\Ý tæ7ÍâU ©Jø‡=~5áø:2oÿë ‡öhåð ¨A†w1¾T.ý6¶¨fÕÇÖ‘tó@N¸qš¢ÐØöãˆO‘þü&n!ŒÄ)p%c—yÃ`Ÿ–5±¬D'ööýªº°Idž’±ÿ½Q„¥¢¸{½gæè-à‹Œ<#ÆéüG8 î„×°SO©­rl‚¨²hfìnæUÝàîÚ](Çz}I¿í¤w>‚†¤Ç+ff’«”÷í ß§Ö“° †ÈÑ"nû€/Oݹ’žÎ”UoìÎëÅàîk¦L5Ô ?èÁ¡7°Îz*oâÿ’hH²ßóÆ© Xw—¥:¤çCŸVæmx`l°Éá“¡X¿9H*Yù.%?Hs’"¥Ä…jxÊ‚ý%€'ˆ÷G—ÞW»fV%¡Aå9bœ"R×ñ¬ê˜ùâèÐð{ÁðÓZ~*?˙ڵH©›!3BˑщµÄàÄ_Í߸M'ÒŠ™7·ØæÏŒ!o¸EˆøÇ—Î0„Õr”eômC«7nr’¬3"œ…|#æL0Fßçe'…é?5»ëtÏ•úøekN4ïhË)íÔY1n‡ñôã!NX|«]1ÌÈQçžô`ñ¬eÜSÂXJˆº»HgÑ.*CµÙ- ‘· / Ì="U/ƒA´õÝ•¥jæ²A¡‡. ¶ èBæûȲ¿ø=¼{Wô–Þÿ8›à1zÿµf‚&ŠRFN˜jMCˆé©ó|T¡©O¬ï]vN”jô)SV2ò'|Á‚n‹ÉüÊYË}r²¤k®¹B§® Œú‰í 8üëÀvù©Ê ƸÅúž Eƒw­ƒq®ŒÖW¢KŽöVå|kã#8ahhüšÎú¢ ÆX¡ðïà ly[«8>¤…¨)V5ñ6–8÷¢µ¾¶ýÆ nÔ÷l#²bàî,BuìUœd†óÜqòiú™Ýúõ•ܶ»²¸,Ý1tÓY<þ¶N%^,….Ï<(K·ó‚-ÐßõÖ{27ë„~ÕŸŸ=ú¤ػ뺜5ˆp㽉ÿ­Þu¤XÍ;ʰ_â§Â8‡µÅ¥î¼H]€B¢åKÊû¡|&D<šøAä²Rð®ÙÌTeÂÏe'Ú2¾p}kŠóvn ƒzë;ۅ߬’ú}+‹i,ñfjÅž}¥{¿¡ü뀟A7z÷Jƒ‡ŸôN]ËÏóÁÖDï¤0Ž=SZÛú˜‚b/-Wštp$uÝÉq‹òdPÚÉÌ9”`@5h{ÑŒ ÅÅÛ [õU]/¾v±ƒ )°vš¡:^!Bw†ÔÜFpv?ì»þPb»éGM~v‚SÕ”÷ºË—Fš~ƒ3îÀw>›:J1ß„êS`/ÀÄÐkD¡³öÙwÙOƒq¯@óqÌqƒ_nÉÅŠ¤s—ì›ÙÌ ¯v=äÖnöÇ`ZQ` Õ°×±/r¡%æ¿_<Øßº¦ÙÈ2 OÊ7‹«P­§°£Q­hÆ@n‘ÑqHS žy—¹ÛrvWv ·–TAÛcã~EÛM&A7OsÏoa¨ŠJ)CO¹Ž:´]y÷ëª%bë~¬·7mÊ'Ž$6?ƒ‰2e7ˆ¸ w¥-´R{[6æ]òÕ aK»ÌJþ¬W̶FסfãälÕ´k"Ë€³F,BUŸDSc‹r,?¿ÈÁH}Î×G¢6²CÄ[¥CcuŸiS“ÊôÑ”r Œ4lŸ”cÏ!–-¼GKjܸv@¨î3#d…}˜Îpkm'¶–Bçi.®j)X·Sj<Ï™DQúžÅ¯âJ][ ƒdIewSåY "Ê降;¡§a5e½þ‰æÖ›‚lJp>•wpÝœfß³`€}fVAê¹›ATà;Ç]Üu•z˜§åÏ~OwFå‘[t{(/‹˜ÜwÏÚÅó}üÕ²ý.|õc%ÓXœçES?.~ɾ, e ÖÈB`Å¥ÅèŽI2œ1êÍ5×Ù(¤(R^/u^Æ3øL¶JèrHXwÎ!KIÆ¡6;#H@Îë/H±öæÕ0ᄊw¡’p·'ruZˆa_óù’%9Jh-µ¾iUs{"ÞÉ5¨Ñߍį²ÎjöÓƒUã"Ý—ÄÓM/ýÀwÚÝ»— "£fÊN.ÏÂCh–îéZ@.¿jüK±Ø@¿‰„züvÇw艹T°ƒNÇ·’§ã ƒ4*ñWÛÐI¶cÈ!=ÍëÖ ”òãî@2¶ª8-Á²6JªÏ8¦<‡1Þ€V®H•¢åÚ¨BÊ«4RV!Ø­9øóÅø<–Çä ÞžãsuNÌ7b*1|,1H¯ST#ÚÖÖqö§WÒýeÕ­q,æáØ ¡8—QE X•-Û,út"}¶`fš„bÆ”Fõ®‚éœy¿×Ý(„p  =ʘ¹dZ(§»-ŽSIFÌH")5WÙž $#äm¹:µ6RG¾noQ¹÷Wá) W ÁRŽÈôŽ~¯¸`4îò:íd0¨Õ4¥uÒÆŽ¨»‹áèˆ Q‘ä4j!©ÝÊöS\n©èÄ|<ºLÐXl¥ôÙå˳¨fäî§Â’»Te¥:ëäÝîœÄÁo‚L«½Å”FŒðõ¹1(/s»MS¤¥¿©£ŠÏ]¦„xMq+&¤i_vi@S,áÞw53ç¬gD Ý,×¶ûén Üý,Ö›ªÞf¶;Ûà×ýHÆñiy iKèSüÖã©CÜ4æcó«$IDá.cì…g¢Ï!Û(6”ÏÔq¸ š6ßÉVlç8æÂø¢?gïʘéšÏh,[\ÝõÄ6äâ•ÇÁt»W)FWžmJN«òØN9 îKk^l‘«ngÒ¬Lýn'ÓÏ^[֦ୠéÉš’ðägŒªN´—k!}•XÆÏ"fYx¦²)ySL­À®íRÀÉæ¦K†î‹x ½Îs©8ŒvLÏÉ%6«çôZGa†úï7gMˆu7JWdŽ_#¿o^½XÉPˆÝ×v]ì¹YáʬQϧ¹¾­_~((­ ¬íMµ=æaÍb×rÁÑòh»ð¾i¦Å;µ4͉‰ì; Ÿói€¼~;’¾"þ)@”âËÖ•ï7{ZF‹ôš1Ê£Ó©ïOEŒE¿þ´€å5Ââ„ÓDyÑO©Áq,ŠQй‰[$Àžgʈ= [ù<È8U9Ò1»ÞÿuŠzz1[—È÷cûu±0wpüÇeýÓ<(˜.¾¬¶è+ Ä/ÎÛðø÷—rÐ\½Ê$ë®…ÄNBBÿìv‡Páž«ªjCØ-Õå¡ó.[NÞÔ5ÛUkòêÜPAÎ;ÔªÂeÂïg,âHŠËÙfƒ9…ú­4Ja{úV.ÜGʯ¯–ॢÃ0 8Egµúú‹¯L'î¿ÐB…_Ë7zËg¡ýÑØ¸Éc]À±@È"æ7©ª>— ù?QóPDhe9,Rªmú<!k€¶µ.š4l(±‹AZg‰4Ö5ÕDhÆÍùpqÑý:Å ÜT¸E㋆ÿkôñaJ½%¡Á>¾Ð„Ñc­ä"åæÎN/šð@¹Ìy‡Â¥éC÷’ ›=Á7Xï%À å竌)®Ç¾·q°ïK[÷U¦w²¢kS[I?מ‹•&82¤³jŠaÞä¹Âû›0ŒP ÜÖûøõœl܉ú+ËQÿtŽº›¯ ÍŠ¤W ŸdM|¹´Ún¿G¡jâMfØÏ…¦LzßG8¸²æÅE<øNïW­Q}Á!\ÛóÅ?SŒô‘’`j çóÛ¾‹nÃgFm}>ŠÀ·Ø\1NàwNº½Ý¿ÂÁFÿaýFã d ‚%mª•®”$ƒ2#Õ¼fC×ý?Ì?ƒYsµiÙÕ&¶™{³ü“Lkç'ÅÌoh—só8»€-ÆÀ*OâOkzÍ1{ã0jƒË¨(0Iß×0,Hž'™òŽý^Y¹ë)ázÕHvÞR'v™¯ÜOq!nd@¹í¸.cMáçxJ 8†ý0ÀÈH%nŽ’í¦î“Á܃­ºagÁ½ñ5æý*DÝfòùËvÆa¾wÊ'䑆†ÂO´Hs>$TÓÌ ÑÖ—‰+»,W¢P Ád~‚°M±Š7½•³ü5)»Û.Ùô„“Cnq?À ² Ym …Ê 1­Pd‹Ô_”ó;ó÷mÓÁŸÐ½¯5u@UÉEg^P˜æ(Ow=1Ì^á·ªÖªôJ¹jl+2›úpÙí‘‘o>±È*]ʼ<,+¨w¨…tÅ! ËŒ‘C…žØUÛÚ ‰»0ST"³š$giP¼Nªy2DŸàÝ÷âsW¼±’œ˶”S­<î°g¶YÍ’Ë7 ª¢a¾; Œ9μßgðÕëñ²*uHüÁIòc=x_½žË]ÙŒá#ë Ìp–¶^ïû¦³J$ç´o™wU¾Eº¢›ÉÞHxŠK3“;¯÷¼a„• `Æßõ49*òµï|$ÓYO>(já%–Úù"Lið®1Ú~‘ÚäpþòŸp3ŒÐþ˜R'_ÞÔ4P}*DðÓ¦Iøû@ µÜ¶áG+R:ÕÄ!3Ð[«uÅ'"~ó݌ą/ŸK±R;Ùm Ç2{Þ‘'M<Ä‘`Jä ™­V•SjJ.}Ûî”qyµmMBh›Î§·9»M*\2 ‰¾Ål­Ö62\ˆîï9'Ɔ]å3tº˜Ñ)ÙæàÐ{ÎÒ¨êYÔ¶ƒ^í³Þ {Â5ÚÂb÷Mèghv²¢oHKíò+6G”r¬»ÐúC÷0Ïž5or:òNÎWC©<™Ï!Ã;w2D­ÄÓư²C]È»ùX”æmw¬ï“q9››²¸ßå?µÿ*ÓáNuÁKsõúèTçUçdó¹šñŽöì G[*¤‰qçI¸Í°ø±EWr¹»éÛoxõ¯F€6âhh‘iT‹mVEð6,Ž oVªì‰½ž|öê\Á–©} ™‹xâÙÉ·ÜÙ}„Ã…gŒ—HvŒó§œ¦DZ°~ž"ï¹ÈU‘è«åkÖÒÊSGvÙíx\䑃’Vtâm(ޤ·†7Ãl´B j~Üíʬ‚kpfÆÎû}qáÚ# EÑWH“ h(ýaNòŠ˜ƒ$íÙH%Aߎ>ø3»”Gv„Hí j„02„é9´ùAnšìf—=êCùµ½[ë$Mò‰Œ„¶”˜•È•îŸéS€·Æq:ܯˆxÃmæª ÊßOpï‰I@û"¤™Q &±2L=9#…RÂÉÞÏj{lå¸_Be•Èå0$º(eyI1s»|›×‹¥7£5|†9Óä¨MR¿rè'VO~E=êµv®Cèã­ÐÀ?ã'Ãrê$&ô4È«zø(ú óŒ£ÜP*yfg˜î‡¹.u÷ªÖ™ÛYÝH²'‰¿©¼»Èt9óijõ‹æ+¢¦"}íŸFòà·ÌAVv¹ ý½kÕ!½¹ž„XÔû©ÜÁ™ ²•)CSzØj8xùµŸ”ü%p ]3Xžš%c“@§ƒ:&c„w£PoÕ㱨7:Y\ø.¦br8vÂ,Á+±”¤ØÄ'ƒòð}õY(ºpùEutë‘[NÜ夗Ós*’ÖV¹Ÿe SÓ¡Œ.¤‹w£6“é^W²¦ë€ãD$øuí²ÞŸ½E!B k9Áãã9ËßðÙ* ß(lñÌ£¥ZE}­>KØ×Ý>i`é x>al­–X:$ cV£}=‚@]Œï×ûÆŸuÆ&Ô­Šº&¡/y_x+”žmñ8x ¯KrzmQÊbÚ%àü]l¬MCi»YÚÅt+œì£ò?]qx ÅïšláìrkÛKj‹‘SL[G.,³ …7y0Ĉþ€e%UÔ¶ué<‰ðI©ò{æ^ªe?Êf.…!S*Q5”®"ÍèOi»Ž¹~ŒXxàA=–š•dŠ&)°Hó†ý)ŠL“XëÛ¢ÍëÝüy4|>Ø;6×VøôeCÑVùÝ‹'w–ÜkPºUAx5-'‰xówŽ_œK¾¶X÷9ÔÍ9<ëBîXD™^Áv2%׉~÷Ÿ‚Wé>53¦j/;•zݷОQ¶ÝVwÓ 0þÜzcDÈØŸtÚPø2ž5r¸Í.))ÄT­®ÜAlôêþ„©ÓHŽýàn0ü*p`:5xd}‘¿äܵú“vç ji‰\’„U`qû¢—¼:˜é©wõ”Øn ë6|*t@‹tã¹w*ûx¢"ê >؈¿Fü™O“¨kQÌè}þXàÝ÷Y,²zÈå;Çê4´Ù+»SÀT)¯tX0»öx% ze "¶ïVe¾1Œ”s EãÒé¥êí ù }fÚ"¦Õž¡5«gÁýui‡¼„nXf—"´Ç»9œÓ’SR î#ššÝ|:H”CÚPüÝüm²£hÉjˆôž°óæù§wÒò”^ïæ’\R¿lëÅá>«^¾m<¨àíD=Œ!êÝkx’·øâU\^È÷Æ¢™_ö¤†+ùŒO]‹‘$p¯Ú$¸÷kÑ+WSÙ_Ñí;S÷Ñokà»´Ö½çCR]]©š$IJ:%\ĉ{BÍ4>á¶ß±®aìAKG4s¤‘` }u@LPÀ©-  ’²‡ŠôÊPÍ+ ¯½+û®½6» ÷“ÁVêÞhzþ”†õ)]^.Õîç7AúE:„LðÕ ¦Žñ&œaçç˜é®ÅÞ¹û‡£1/&4©'ÁGqéÞÝ¥qô¥Åbjà®·?ߨÊkêUUF“ÕohhÔé P¥ôGe•á1æE¨ëPÜýÄçåݨF@1Úý‘‡¨FQ…Ê7)攟iFx‚ïk¾éÝñ_¬Á$l:Ä©g}ÈOèÏKŒ½ö d|“~í¤Ø0…ùíüÖ‘yf?•ò0#áÉö„úÂ<¥MM b ÆÌCx•¬µþcÁ³þÌZõ‘ÆyŽ›Ï6Ý@KnWj »³×´¼ˆ‡0+%üæX}I˜ïs²¾ÕGÞÖ!Kµ…pÒ”`_p¼Ãwoî§T/€çžýI¨Â™ËÜkœ§q¹Òse3v9ßïÝÑI &M=ªnëŸV|¿H*v¡ß°½"Ù1^ cà럹‹¾@߉×G ¥SŽ=\0 Ìñ³wÖmËìhñ1bo½Vø„ÐÖIL\ÒSÇŒÛ1ðC¾U“kð"Ã%mß~­ÂÄ®xܨv'-¡€cØEØT9•ý$ƒ9üó‡ñ}0a±aÙÃÒDÔZ¬ÇýÑNC}Fáä+ÜxŽÆ5M Ö4·|K¼ÂK?œ^—^~üfŸöËŽ Çá;Et'ÄZøeÃô2]ríûRn¨Þ$éŒLð@¬Ú+ƒœ¼ªºCëah®98Ÿ€-7¨õIÆØ1E¢m¢Þ$d\T¾ÞÜ@®|#3çÛƒÂñ'¯±]úÔŽKíèöꎨPž62æW]8o,¢%#¡Ž…»ýZ'TFʲYã¨jÕ»éà>¾ì¾™m:Zù8¸l³ój­ý&„ü®êЂó(VçŠSЉÍ/Auß½*)øÔRfj·F~@Õ}Vùšun'E”¸@zˆ½êÿVE°I endstream endobj 92 0 obj << /Length1 1556 /Length2 8182 /Length3 0 /Length 9210 /Filter /FlateDecode >> stream xÚ¶T”k6Œ€€t J % ˆ„tww0ÀÀ0Cww* ÒJw ’ÒÝÝ¡Hw#êyÏ9ïûÿk}ßšµfžkÇõì½ïkßkè¨TÔYEÍá¦`)8̉•ƒ ÈWTãà\l@ ':Ä þËŒN§vp„Àaüÿ wƒœl §‡8E8 ç pp8^ñsððN ï?p~€ÈbPdÈÁa`Gt:q¸»ÄÒÊéá5ÿy0˜18øøxX~§DmÁ3  r²Û>¼Ñ ¨ÃÍ `'÷ÿ¢`°rr²ãggwuueÙ:²Á,…Y®'+€Øìà6üj ²ÿéŒ  aqücW‡[8¹‚À€b†9>d8ÃÌÁ€‡—ÔeÊv`ØŸ`…?,€¿fà`ãø›î¯ì_DØïd™ÜÖs‡À,( ,¥ÀæäæÄÁÌ‚ Žð‡| ™>ü®U€ü«=G3ˆ“#›#ú«Eö_4S–„™‹ÃmmÁ0'Gô_õI@Àfcwgÿs²60¸+Ìó/`™[üjÂÜÙŽ]±wËJüò`BÿÇf vp@>nØv3³bÿE¯ánþíäøe~èÀÛÓn°xhì ±?ü {:‚\À'g°·ç¿ÿÐ98æ3'€)ØCÿ‡ýÁ ¶øƒßâÐ>hüõùûÉðA^æpÔýŸðßçË®¡"%)&Æü§ã¿}bbp7€'+€•“à{É àyÉðþoä¯*€ÿ¤ÊÂ,à¾?Å>Lé?»üuþ í#࿹”à¢þѸhöðÅñÿ¬ôß)ÿÿÅòÓøÿ$å …þv3üöÿÜ [Ôý¯€Í:;=è_þ°°ÿ ÕÿÙYE°9ÄÙö½²N ‡=…YBÿ#ÄQ â6W8™YýË»æ¯%ƒB``¸#ä×­`åÿÇ÷°Yf67‡ãƒ"»À‹ó߯”„™ÁÍm'÷+ÈÁäŽ|'77À“ãaÍÁn¿5 `gƒÁRíy,àè¿N”— À®þËô½|Ñ߈ÀúñØÍþF¿je7ÿä°ƒÿ†Üœv ¸³Ã¿üÌVÿ‚¼vè¿à·í?ãö/øÀ ÿä°;þ ¾°;ý†ÿ53g‡‡«á·t¦öüûƒÝÀfè³Sp³×AÖ•A_.ËEŸ»²n ŽÓmj'1²zÎ:49_c£¾g,K Xv8}ßÛŽ»°.Ép&2Gyç¹ó¹5´ájã×­q¬Úèf#úÌq×ð‡ѪNò'd¬"ß¼îì½´üm>?j‘£Ë²wæÅVÉ!¸tív«ê,œ™ÚTýVöJã¶pŒ5Z3ÊÀ?o‚.Û4}’„ʼn• ÿÐ gâì|?søžR.–Ý{7šë£§Þ 盫IÅb NÇVRZR=r¤3üÑžb[ rO§=ó?EâÖ³õsæÜÉ¥ÏÈQ1mú}õ´’oC•Ø=_‰xáiêÿváç‚vè!õE¼-ò›v°®´[›`ƒ­*<¾Í Wï¼ÅërÒyOn4/…bê‡5l^úñ†È!‘_K/£0Æ›ÅÙM}æC[ó¡eŽdg¸ÃWÞ1]<]ìíe•qá÷Òs9Y¸çU’yšqSÛ¾% ™D£i$Å~m p5%¥¡¸v3¬õ1_Qq•fczÔ]Oº)Þì(ŠJ£\g5ñÂÛÒÆž/]ÿé.qì™gÉ»¨gØ¥ÐeˆZðÞaBû‹uíÉí³—þ[çLnkVc_–_†Ö˺&ØaõÅ dHðNêri=ÝrIé-½“¥`» ¾…,†iV*J}­e¹]ÞînÐnŽ õ;C[i¿tF_²ñÕ*œgÅíÆ¢¨ne’r6IËÝã±êýï©}á*Žß_#ÙZV”}IëÚŸs“T›ÚêCk#bñY 6ƒºúDøÌ¢ÛžÆ /÷G ûbÔ6D+»æ]Ñ“¥YÊN˜ƒøåò›åwŠ&•ÝpÇáÈzÿãACʤÅIèI¬AÆÝÇw±žÒ=}W8‚.³¬B½X|„øÝ·ø>"õ¨‘f¸É†ƒ†rÏ–Iúß4U >y‰žu4ã 9œ¦ÁÊ;Ká$Vj Iš[„FFä8’¤OJ,¡à³zº½Wm Œ_·%áôs‘Æ–ô]ÁäoÚJG÷zÆßj´@t&åa,ëšÕ7cá'rómÅÏ·ä–N ñ­v™T“aˆlùðiçó«Wx£‘CŽ®TÃñ2$øÊL|Š}cÔˆÙ.bQg¥«BŒy 0CoóÑ·ábsUÏ ?›`™\ñS2֯㣜œÉD•‚Ô½‰6‚} rHŒ>?Šà¨|Ùròý²v)›×˜jäÜSs2Å[^1{pä+Ô‹mê¯Ý~›L9]Úi@ù~‰ä"Œª¹ é‘þ“ÉÀƒÄ ›Kžé¯¬ÙŸ~¶"ý¬Q¶Hc¬@Ò·äe«Â’Õz.­uKO|ÚŽßzRC Vq1,F FjGcÕ¸ˆ‚‡½Ý²&o¼zÖ¢xz>ë¥)±”\4É4¸ÇÔ9{Ø6¦âfÛœQî@±M´É;̮ӧAJÄÓ¤$ÆîLˆéz©Ãéá£Ý§Yh4º°’€lW·µ€Ó(5^çëoår4SL®‹Ê6Ë$På8*¿A^ 0mÔ:CꟀ¨­ÔtýôÉíØ@Šâ»§¡ŽbWW=‡a7´]+ÇÍ]TŽbéÄão)-S6,Îàÿfvüf®:˜5[F`…m'œ·QBniVÏt¦ÊWzÂí©ò‹Æ}¤€àÞNÝ®uÁ¼®ÛiÑm,wÔz2ð¼–‘”íB¸`î~¥ÿõõ%JT^ŠÍÛùÁͦÄ'`>ÉâKA¿Q.³ãÆûEÞÊþêM4êöKK©©¬F3BW&Öúû÷ôH¹L±+Z$j-k\7Ygzô?œ‘£U7ð:·CîåI«ÒÌÑM’›Úø*Õ;¿ wÔнµ’Í]ñ¥° 64_l(Å|IˆOP2rVxö6Rðgîçó çÏ:C‚jð“ “<ÔïKé¥ZW“Ï>šÐ° yÔšòÌfÜÑ[—%Ea §…l·^ÞŒ®·7³Íp~`Ñ.É¥WÒ,Z¦{Ýq2Ì ”d,dbTIœÕϵ„V3M©/"œ\u»~IÓ#ŽƒªjO¸3Ý©œŽT$“#¹ƒ&¸¸µ¼ÕÞ¢OrCÚXÌŠíS»>©I•S¥®˜ÙrQäb<æ]?Ñ\ì;LÑ.—@öÎaÅÄz@2‰¡;™Z›2÷Ðú$¯97#@9i¶±û¡æJ‡¼‰ƒ]à²É­vGç^<%³^q?TGaºU¨ i1‰] 2ÐS‹ªèÊm¬;`ÿ!¾‰òÊ þt©%ØÚ´Am´qØ$+±ˆzÈÛ$†/.(ÂíC«:ý,§{æááô‹ÈØç¦ÓëÇ~ǪyêS{{ÕGtCrâ_e½Z߆«ë7—\[ɧ,o½ËÉ ÐA¾¿]™HÉ–WLý”˜ M´Ök«ËÞ°¸õµ)ñø~×Jrû³X<åßã°¨„Sa ·A «m¨I¦÷ \©½õyRdzÉ|ËV >W»‚ó:ÞŸ¸rjd­j®rJ ûö÷È~§T¶?Ó |?[²`Œqù{4ú,-™çã+cNEAí§/ä}i½F¦éYg ÷…ÒÔ*àN¼xO!TÖv™7êZØ*2šŸ©î ÏÛOÃÔ¿ÊŽpêÖ´ÝåÜÈ¿p‰b¿ŠÕ×IŒù‘,ë¢ú.Ÿ5Ǩæ;[+ã—w‚–*iŠãëŽÜwkpŸ>©e Öo¶l¡y7I~ ˜óÁŒ€Í—x($ ñß8æ™5H¢l& vº£{!èÝ+“2¯”l0‰ƒsRŒi2„œ½“ùø¬V øT“ð3îðhÈFÏt‡yíP5Ú—Mr ½¸ð4]nûpj_‰¨«3½-oGB“G|÷ÈWy¡µ€ÍPï8{)òõLŠHåþÆ=ßàx)‰Ë¼f¨Êkü€½…§‰W?1ÜÙ6Ûq',žiåN>C©_áÈCGòÈ™¥[¥ÈÔŽµ Ã÷Ú¡›OÒŠ¤P¿ágêT~ ü!žËWÐÞ¦”®úÜf¥h;D'ÍÚp®ë.œ¾’ß?Û¬XxKHêº>gT& þ8ÆúÉ¿.QX¸Z 3Z$­O>(þš¶Õ7;¥Ðéñ.CêØG|ô¸1îÚ%¢“V‹á«úÓ³‰P>ÙFd1´ñœ }vñØ k|eaZªT8AMY+²½'ËÏÅ h.†{±ÄˆKX/mckŽçXä&Ñœž©ûk* ‚»l·öŽZ}4N×7näE ñùäTóç{¡»ÀÃ9üWUé©gùˆxžÀà³ÆtÃU¤ ñZA>ÅCc­ºæ ¤J2ñu~O\°’\„†K4 é²ñ™ÉâÛ6Ûõ;[úy#%bX7ašÒµ™ GÃ=R wJÂÛݽôfÂäÆHµú“.XWf®¯=¬uÂj!–LÒÄ”ûDu[°È”0H×Ã$›Íj½:Jän|HÖá¥,Êݟ¦Xž’÷iz%Ÿ ‰•âî©Kº.Î?¦µ¾_ÒܧºÿôÛxü5bm’mHNŒ­ã¦Q‹>Ðx½mC~t¯'9'îcPd|äšæ‰Å1~ ú¤û)ÐYRìýý^!†Ö«íŠëf-Á]pù´§émöä­‹Þ;Ie$”†ð^ËÕG²$?p,¢~œèŒr®•²ÛóÕÚT¯T3˜»V0 «š…IÔûèOÖÚ0ձžO•ÒòGQÄ…k>¯(ù`ú3H’GÖ˜K t)Æ®ny}ÁàÑpî³0ÕÎ07[Ï»ïôÈÛ›ØÅR©g‹ï›¸([”Ïê †æÆó¨~fµBoÑÃUú)žâá2L×Ü%]:îS-²?Â\k TU8xl>-ñ!\l òx!Îm‘P-ðq ¼ú"f"BúàÈKK”ºùɎ죚ÓɵöOy¡èÖ±l‹5A×Sv_Sߺ-¯¹©GÛºâ Yï寿ðe™Äµª©Çw¹×Uê]BðXVpk 0qmEÛŸTÌøw"ߪÚàcúò)$öÞ~}“Y'Ò.çrƸ•h­£5žtûüF݃½kƒÖµ3Q2º0‚Pw*еs™“œè³fMù=®²E«T>PRSóõY¡Ê+Ž'ëŸs#H]¾¯ôÕ½ŒG¥l¶£v–g@…YyúƒqÏRLesL²Å©{„ürÖ/3…Ò🯪ŸŸrÓç¦Ú«)ÓS´R¸`Iã6åƒGh–&§ÖŽEûCVÏé”UbÐHÕt1Γæa5ÕÈdéVœÉ,QT^¨Å+ÒäÒù¬ÑüèŒDCÜQ>Ü È+øª÷¬áMŠQ÷i«>†É2„Bl.ö~°ÎH¡A‘ß·ü–Ö¾G³k å†%ƒÑô5hœþŒ”$ª’·ÖoIÙPÇÔ{ÿc}›Ýv‰”âlÁ*ö±émr‹ú[ꆇ,Â=»`B£ÈÁ£öƒ vÅÝ«¬¢W±d0ñƒŽåVbãöø.f²*Á µš;TÛ§_2Wp+Oâ8"¦Á%Ŧ¥ãÞ™ñ°F©·²Žwß„öœ‹+,aýÚS*âÄ‹J.Ëé NîÄøI”½±&Âòz ðä½Ã޳gN˜ƒÜ.Ê.`è Þëos”õ7ª¥ú¦&?k3¶¿¬ö{KºµØ)3ä¢H§YÀbÆÜcÎì” ê _>%ÍNñ!Z)K>ð‡ önºI˜TÛ«ºZäÛ%4IÎ×_Ò0ÈE‹Ð#y´ î‹QP™Ü1îå6[Üû+³Ãm?¹„ŸàX‡WWÂøGÀ?2>ŽÛÎí—Ô"s‡û‹§– a»oF Sv©Ó`Ö=ñS×åÊõì|±ÖŠî¤Èf¨<¾ÎJ…R2·kÙðß²ò¤ÔÇ·e½ÖMïFd;7y]–Zwib»šï"ød—¼qÞ'‰Q©x­~Ó%F«³ã³ý˜]Ñ”@=Htÿ"RŠ„—ír1ꇙpMêSªˆ1A”ŠÓŸ]k³†Oï¦CùûKó®«%ìã×vPns 'TwåLq‡RJ4RÇk0¿Z[€—tiÏòšè9öh†9u©ÐxÑÂJÖóñðÁŒô±¾ïänÙ7OešŸ±<.i'‰`üP˰©¯ªí/›ß"j[Í^ºáœˆ³3¹ 3´ºdÍ3š¨8qój.‰‡Tèrð}ÅÉœ¼vñÅñò²-Zª¼º¶2?Y*<ç»8×L`hˆã½ËJ,à Éã ŠÝ©õL^ý‚¢n«]õ-ÑÏ›:òÎAÒev3ŒæšlÎê(;­C£ª+§SÛÀ—ÜD.î“xýR,ìȾ§€9ÉÝ&ׂ´gŽ)`Ï'£ÌžJ•èÀÉž7@¥±ÕùãLnÑ}p»,®À’¼;ÀV° }-Ü™ÀbN˜Ì†ñª>*åuWyÜ6x}„Ck·ñê¡Ë9÷Í>ä\s‚'%.0ª8±j8+CûÚe/Q¾Ñ•!ŽJN]ýòÊèÕ`n´É•eü‡§‰¥Làðj͸j9¢T>ê€2êÞÁˆ>ⵕ壵¤ÛÃJu,OÃÆøÕA|¾žZÑSJ‘çE4lCA»h í†œ43ª¼G-ÈÙ‡ÀÂiºD7ÞXâô$ »“Û8Eê½;$u9{’cÛxíò¤4šÑ™ØŸzÁ*„¢…hÈ!™›]†µÕ¾v¡zˆº½°#6Ò6õ½gåÎ>«v3M½$Ê…­þ4E´úä`ØÝmˆ€šaž•ŒÈž£ÜpË xÇy e3òËó?ß9g_IN8ŸÉŽRÌLÍQʇüD?ÙŠ+Âi$îjÿáÆŠ;UpšcW&©ÖÅG¸OùÆéž¯ùmÀ«—jßÉÁÿûoå{*ärbSÿoæ`œúè’ߥ¬À·:Ê‹e^lKIÌD`¬$˜T(Q®!°½½oMB\8× y"ôÞHþÉéJ‡z†|2¾*µxî"°àÓšÒ4y»b‡v¤ª­ î—¼qíkšÀ€iØ`*~¿µšíÁ™Õ‹ÞoŠRïU':ÕqR«è„0[»î#êy`)f=lá¶­H—GÖãߣ"Z—Ý·q×o$›˜ˆïdžK%sŸƒ°ÙªŒŒdÚV¤4W3PíÕç`¼\áE¹À/˜î$&Oœ‘BžCºg´[Îñ(dLTðátØîx7'Zþeúù¹tÖ&@Š>(hÇOˆ»ªå ».ÈÚ‹Xš̘~càüè:`$ôÛ¥»ïÁe÷ñ‹Lù‰#u쨗oÔцëÏz*T¸íËü¥ž÷ϽÅW¼¼²!÷j2褴àße_®žI2d>+ò|7 ºñDñ=KÿSRíøñVjå~´sVö2Ãù€ JÞ4›å¼RT´Yg¢~è¾´\;X혘›m0ÊçëxuúÀK®|]y{òµ×߃Ö[f•"(ÏÂpº@ kPÁôtE›:DjÑZÏGòª³‰s:xƒÒóˆâÓÅiÊÐIÓg²JŸø“ Cºi. æàs¢mš>z1à°Ð!!K„R÷Ò-Ì’;Çö‘3©˜="ÆÜÊ,,s~yú ”_ýL ‘2°Lf˜WË5Ü,n?»Ç ·cFï-‘ÒUV¶Íì.Y',KÃŒítÐTÎæChˆˆx[ª›;êÓC¤ñ&ŽÕ€´øÂY‰í†ðO~<éÌrÞª#ÚòòŠÕ‚°÷ÞF4ùK%̧bÄ:ñ½78õCˆ¬wµ›å5g° ß,Vu¾É¾9Ø#ÂØ»Ø2À¤•ˆy ÞÁø.ÔÄùÃ)ÜBé›#‹<ȵŠþ{^A}†,—øÉœVÂHDÐÓ‰î4ªÞ.]5ø«)±.þ—OìœÄüûT3±%ºBƒ$³> çöõŸ`'¦ÉY úì‡âÊ]­ì§Ï¢_~J{þA@Úi…;°*Ê@û­Ñ>¡£Ä{åÝÈ<8½8‚5JäìmÆÊà®cìvñˆÓ0­¤e­¼æ3Ö{èëŒÐ·?RcE„Á¤€ ‘WV¨Ã,Á7é òkÃ^ϘB6…öpØfaûj¯Uoçb‘ ä5{ B:ÊËÕ±ï‘k åþ‰½>+À–¤$ˆ½AvjÈSgAqeíŠÑ섈¤îu›0 ±\íô—Í ç­PŽËOú7ã7\(?ç[¶. «çû á!Í5¯£ ¦’û}ŽÆ†‰†ñ-GðÔX¢1\ˆ¢ä¬Šy¸2=ê¶"ã}ç GS;òO¨Þ|ÏœXžiÜsÝ[¬,z/†¦…¸½ƒW*ÑÅ_+8.G¥Ç]žý®DR EâGýôÌÏdÛ«’ÝR^ës¬B ÿë†ô eØa÷Äj´>xý¬Ò÷ëᮣ¦•Òӊ؆y†¨lqME\j„\]Y4/âÌ R¨ôz{zÐBÈu¯œtøYZPG7Ì•CÖQÆã¤y-é½×ß(±šfçò@å;Æ^Ë€y~Õ+µQ«? ÌP‹/hXƒ¸w4¡†=¯Åá%ß%SâS#ÆÜ÷/é-¨jo­h¿œ„”i- vY7´Dh5Lê;›ÜÌߥ2’œÒºm&ŠÓw¢.—„|½¶ÄŸé.—®øü|ÄÙ5Gð5|ä•xJ\=é> ¶!ãOàã çpB€Ë<k×4Ó€{úáBvLN³H—nÁ†Ábí÷GžYSSV}V°î˦ҥ•X©ª_aËî†+Çpfº#y•ìñ¹fÐH7^rXn´S8Ý€5¤åÕ”"'²Od9ˆ ßs$ü,YÍÐó¿àŽÔŒö`øù8¨¨Â{²$óìήãò[Óu¯$ãáŒz©%#Õ ¸%ÌŽ{'~ß³Íl Ú¿•{ÜW¨'„fm6Ù¡¸ø!Hç†ÓMK¼ª92-=¸Ì]hz ÉBôE÷ ÷qìå·)Äž3²ÀgÎEß•)¶~¬fŒW¸œeHu0¬g^÷¹dYxy|îh÷Ï A¨\’Èi¾PŒ&>ô¼<— Ð?µÃ4O™Ϥe¢-D¹>£ùú³¦?T +R È ý1s<ñŒi£…‡ÕÚún!—|ù„H´1j³ VŸakŸC?u+ô ¬<Œ«‰è#1¬©Hcør+¦á}+MV,åk‘±žÆ»*è1aö³ðÞª¬„¡ï¯Â•â„ÿz†.è¹RÅûkžÕ¾¯Æè/úÍ íyãsoî>…蛥ùy©3²öË Ÿ¦¤ ÿ d¸™D(Úò¹ç`±¨5¯¶Š·1Û\5ø¦Ú Öó&ï›ï}-Û4[D>ˆÄÊq8ˆHN4LUqEàÇ’ÐDýî¸kë;ìèš d÷jgÃl»È¥ð,Ÿ-ê-ÝÏ–—™%ìcvß_«æÕÙ518ãÆûÆM/.|÷3Iÿe™J’vƒE£f·Y£Ré»Íë“Ùy47߬" ŒdØl%ÁèéõƨÚá a½q‚£Lq«%ëù»Þ9˜®s:zú„Ñ{qg¨À°È#h¹áŵÁñп3qÊz\„=ñZéLÿŽr#ïÌGásd¦f΂^y6øGG(cm†ßØc $6þJh7s¬ßï0m%pg|€m%¡^ªÓ RœðâÄÖ_œC'ü%îY–Q„Ê µ5Ãl´îoÍ'ß9®§?y×üCªág‰ê1ž™tiîlJñ§Éî–Ž;LËÏŠ@I•übRõØFïºdYEAYæ‚Û°9 ÈÖÆ+ÎW¤ûÛgDãÍq%q¨EúˆænÃ"xó+·÷ÝÊM–]|0éwî=ÝÿeÛ­ endstream endobj 94 0 obj << /Length1 1391 /Length2 6286 /Length3 0 /Length 7237 /Filter /FlateDecode >> stream xÚwTlÛ?JH¨0ºatwwƒ”0Æ€ l8lt7H—´„tˆ”¤AJKI4 H|SŸ÷}ÞçýÿÏù¾³s¶ûú]q_ñ»îsÆÎlh¯äw€¨ÃaH~! 4@EÏXŠÂ$ìì¦P¤äJÂnAxBá0éÿЫ $S!1fzp@ÛË $—’Â@ Ô¿ ái€*ÈêÐhÃaOv¸uvAbnù×ÀæIIIðýv(¹CP0Ð!] î˜Á 7€  … ÑÿÁ%ë‚DzH úøø€Ü=àgyn>€é0†xBÞGÀ¯rú wÈïÂHئ.PÏ?° Ü éB@À †À<1^0G€¹`¢¥ 0ð€Àþëþ1àüÕ€€Ð¿Ãýåý+öÛÃÝ=@04æ p‚ºAêºH’‚9þ2¹yÂ1þ oÔ ä€1ø8 ®daêû«:O0êôð„ºýªPðWL“Õ`Ž*pww éIò+?U(Æt-ø{¬®0¸ÌïÏÙ stúU‚£—‡  úÈ ¢¥ú—"ùs† b@ PBR y€ À.‚¿‚›¢= ¿•B¿`Lþ~p€¦HÔ ‚ù!ñóyCH„$Àï?ÿ”H„„ŽP0àq†ÂHþŽŽ!NdÌäPÀˆ!žøëóï“-†[Žp˜úoóßô44125áý]ð¿UÊÊpÀ_à„„¤D˜CÀ?£‚ eüÛW æHýIÓ¥%ìý×ô¹þZ nÀ?céÃ1Œ…¸þ&¸ P Æ| ýŸiþÛåÿÇî_Qþ‚ÿw>ê^nn¿µ\¿ÔÿäuCÿ¥ÇðÕ ‰á¾³°ÿ6µ€üYW=ˆ#ÔËý¿µZHf”`Înÿn"ÔSŠ‚8B‘`—?Tùƒ›ýZ07( b÷„þzPüB@àé0[vÅ<ž>þVA0KóÏ+Õ``¸ã¯í€š3bŒ$ð¬¡#õ›ÁA‰q`Ê 8Á$¿æ)*Ä‚Hä? ñÿ–ÿq5Ø À,Þoj`òú—ü{Ë!L2?Ë„?l ï8­Wºãÿ6*7žf‘ÅÍï7èô:'#Lç®Ë ]A|WJ|E±øYëDñÓ¥ßN[aT{ªÑËŸþvÉÆk/IæÆiûÆJv”ž¿½G|—ßTqÝÿò‘¿yˆ+nv·6{á#/I2ÃbªSŸ7¨ço+ÞEά­×‰ë^TNò'˜ÅÛ„”¿g/rÈ›¦c!@òß#â¹u€"ò}êVÁØ5“v2/IÀn‚H©ŸÕªpâÙ´ïRµ©°g=½Ý=Ü“[ï&8ü”73´oÏú=+]A¼Ëœ¦íùèž&ä¶É廦o|ŠØúö€ƒ}Lš‹žN—Z+.~¥]3Žœ9…@4ï`Q{¥õM¢ÍÁ“Ï zmà&шW=UƼî@}wöÁÎÊúDÓ(ÿ¶š<™H9RFƒ0^vMÆíPú5ñi©I:EñG…×R…c+óW3ëoœÆ3MÜ忊ÂÿYApê@;ÓIbézZ"gZÕÒHiÖ{K䇣Èú×H6ù­n/Ķ¥‘?Jª¤&®v§´Rµ•jo3på×°[²ùd2LUÖÈ=ÑÍ?¾LˉLÒg,è€M{PÍh}}±±&z}ô^¾ÂÍù…Q$+ìú!tI`ábŠ¡¿ì>Þ°T`ìçÑ ©×zžƒŒz¥$—¡º%Žÿ,µª { Zî*ÒÆlb•5ž•__i}ù}½æY’&_äHÂþ$#aÝÎJöÊ9ïЪûrgdäVSe„`¥  (hº ôQz´` ÁCNk5¡%â;ƒ>Î|:5ÁiÇdp÷y=É&™zD Vå>5î½fƤ(sJWjç9~ÁðêãmcÅI¦y·C,•ÁŽ1ßÐz"F;¼ÊZ(çŒÐ˜Ña¶ÄƒT‘vµ¶Ó©ÊýÝ ¸{Rl¸=Vߨ¦ѶnHÆDE!¥\]NÎ|<µN0û»I…P§Í’ü3­€£ïc ®hÖP=ýwÉÍâyfÕdfº¯ÇUúè‹ë@„~ ÅÊ—º9]ÚÐN$ ž”$CÆêÅj{ÀPJ 6±agྎ©Û®ÇŬ⼼-ýµÓ§y‹Éð £Çæ;i«Õ°ŠÀá9[ü-«$ûxÊâ½ÔHžuœ@ ÒM–|òB¢ÇâÁës?|î[‹pÊc/Íü,ó`Cv(­nÚrË2#[ûÉx}zúÌã©´'½ïûlI¬?7–‰DÖäÌÑå¦òÚ:'×oSY½§Œ¸ºy ÷ô©LÝ42 áÎm‘Œ«Å~Rzê÷–Gõ%¼Ö í°ƒ Íb…dÇÐï3]/Å™ s†4òb%ªoLêtÐID w9åÕ¨äÏA4îB^ ¡a·§Ec82lw6>dÕ9Ž\«/z¸oS¶šÝª#wi-œj,è¥gó)µ©Óv$”äí1)T“+ï¹s k6OfŸZP˜¬›)в ‹­:ƽðuò1ArÀv˜l î]vë$UöG× ø·ðû\É]ýÍ`¼Xš$ÙïÛ ÂdÔµpKŠZŒU²7tÎùqœNvœìe.ú޾l)šg\äîì^¸|Ž÷ä]åI¥7ãÏ­cZ!·ysÉu·WNÕÚ‘[ñb™|’ÁÍúl>%Fo>SIîLLŸíQ¦k ¹KÕú›[þwë‚:¹­Àû‹4³qrIécâ=pÞù”pB¼Þ;ákÖÝô`F ÷²x2ŸÍ˜<ó˜kôÖÇ"ÈDK¦~gÏÉŠ§¥¶ûêþ^U²¿5±U?øÜ%ÎÇÂË®÷ó´ø+kÚæ¹f’Dó~Û»–U­Â ì$5ío·¹cuŒÓÚ‚ü!r{ #ø•¸E1Øvá×Í@“Íð¡ ±öØ¡¹n÷AÔº|Æé¬&ƒ¼sJšúÆûÌÖŸCçç ñíϽñœ¾ù|4>O"e‰£%ä¦$ð¢ùê}cEͬ*»Ë&î……ÌN|>ä°æ†øK¶™Òòõ¸¤CW…·#è—èëhшv*YüïKËÃ)äT4Ø·3Zç{ð[•„Œ$C•øýWb„ì}kbš’2Ê.¬l(Šúû7 ¿ô{vg³¼pؾmkŒÎÎÎæ@ ¨)\tsL¦¹·«}ÅõÖå>eR]±p¶lf\õaúOì'Ì›ÎF1uP/;»ú2åÛ…ý÷Ƴ÷¯‰…å8’rùf–\*^ sí{<¿£â¤–"v®n;‡Î€¹øß}çHt›`\«;ãj£Ç°¾TYê…Ê5*8^Šäly›ø1;ÝÇ|R„Ø”cD:»S_ué²ñ¼ïRkòÅSËO&FÇßåoJÃaáUík=B¸èÊÚ*ñНk¿Ò~!µ±¶Ð´G$üã¡,³ ›pÕÓÌW_¶»ÅúÒzœ¯Í±Sú‰o¯ñS/çJjåëŒmŽsw ˜.òÊ#§’L3¶Ð,ý¤’Ê»«:ɵ5 Æ™’Ú/Êò„ÌÒGäù|5Ž’”Xbn­‡'{¦´Ñ9 Ón*ë—2öhÞw!dU~Î>JØ,yY’ýTÖ–¶{|á\ºpS#--Y¿^þWér>9eËíê+÷¢ÊÕ¬] B IVC^[<øõümy#ÞÝ]y¾UŸy”–àòÜ3¦…òã»yT†1«¸©ÔÓï"s à·fÈÕpº—6ŽÍe_Äsv(ø¹C«ÑÏç@šebùyý&a߆ª`µÝÿ”·èܾJr飢ÌkG«¢ C†Fœ;ËwPGœt«ÎJØÉ«l¸Þ=ÆÙq¨Råh«H†hj;Ÿòñ­ò®`¿Øê6^ñÜ•‰Ý+2]œb½ŒK÷$=ÖKc’ˆ-Ë'AM¹Ulã…»5Áû‘ÇxwúüËÄÛ²ý™Ö²“k<¦ÖÊl±ãäúè(@ÙŠoőǙüJî ‘Hiø{<­rç»fùbDaàš¾Ë ¥Î:ì/…·ø.Ê¿qoÐJCé‰úÀ.VÒnÝ[u“¡7dÕs$Þã òJÕuÛíôš <Ï} ·q½_BÁî(|]‹Ç{ëi߃¸O©r3T¥×Ãà iÃ-rõ¡ÞL}”ªíH,ãíW¼Ä–VÀ9Ôhö½m¼(k«À™Ð´ò/]Ù §G-âRI!Ê?ÔŸñÑi$J€ön÷šXÎ,¦üÜAÞ½ù 7ú»^7X^˜Ö‚õ™H5pc¡ÇV"¾¾©EëîýdüÛ¹ÁvË3>ª0i®Bv•öåý =h‹âþˆÍIžuÁ1ÉâIB 2}r•Fn3ÁLïf­lG3 œa‡›@¦óÊRÐä£Qµ0£~wÿÕŠE/çÎêÞœ.~o ¥tó꾑ÕO^vjâÇ;1<~·Çb§[cMbkKtf;p Ú_9à_Þ1”¨DÏtÅxx3º–›~x7kjÌËþVk©q‘9¦áÓi“:9ÀYcy+ϰ'NXÁ„ʿٽþóÕefñ®>²OZžNÍ`ÈR[{_ÿº$Å*1µrëZY“Ÿ+Ý1Iï1ý.v²ûsaxôêLã×›”¾‚Û%ç+"%«i’Kxz¸îic>yËÆYWR£ôÅô´¹åÎp%Š¥ùí±C–h ¨í}²éöõ”®÷²¤j¥Le;ß =ÑÙÆ}1P Ek­å—ex.Æ&FfìæàÚ«¤ý>\¬ôΣl<,,9ðÛ¹Dá¼´cèÂs(€XîQV CLP»ªØ¡’ŒO«îÀw³7?ú-¼ìÙjÙÌ "èöñYR×ú>ÁɈϕ™á5ŽFF˜Ü?ü,7Bj3éUÖ®œNøöë‘—Šw®‚æ,ñCäu –jA  ùõ|*¬ýoS©¿,c½¸““ÜEÓ†…&e_šo³Æ#m…ÅFÔ¾U³¶·¨<ã*Mwާ  óɈ#4øû—ÆRzÝÁk¾5kGÁkÜ"äI9{zß K5kò Qw^]›s¦” pMy֟ˬû¯Ø˜LçÞß™”²gÔÀ¿qÁfh1_±Ü;\˜sRc_bÀ@Ÿèá¨Zºä~ì;€_1óÆöcMdã‹™R|ßž(4^<”¹+‰aƒôñ±^;a¡ûĬèðE¥¥ykÑÙ§öÖœ6½‹âÛ²SžþâÙ§RŸ)£ñgtb¬÷Ÿ8Õf!dp¶Ñœâòô¥I^_I˜ œìáÄsºü ®ÂÙ7Ã\|´9e!Â>¤[²âEê0p¡óšR›ïóqã;ç4o´²_nÏ5òšºöÀoKÕf-H“¯ ZØœE{' Pà ƒ•ÄhÒÖû^9Ãr²Ux(Î}݇zR‰^`Ö,VçÌ7%-œ—½§žÐAɾá5­f¿WûkJyäóƒˆk©n02‡£‰ìAÎÑHh^(uœ~Ù‰ùØfÃB~ɘҀòMW^œWŠƒœcY‘ž¯Â"Û#ídÚ ³«[¨cpÙU\¶æI혗æÞ ¥e´ž fPÀs¸B¾Ð?(#ðïyo8ïÞðªG0Ú«n•UB‰Å¬ê5ws¸©Í¬jGó&^¸_0ñf$xæ}Ø¢*âj–~lÝ39ËËÀ·SÕ8󚑎Žo—È€ô«(ûJ>•&çÅÛJÁ[MWÍqÉx7â/Š{§ýùнåÚö¶"s™T¢+ssÑöâ–d†<­ëÇqSË=’„ìÔ~pQpšÐz»É¡r3³£!‘øN­»sxÍ´ð[îrAs…#Þµ¼^´poÛý‡A{d½ÖúÓŠé…ë&´j•öëˆCЫ«ðhs Šr%Kç‹L~\âxzØ;8]J\‹[‹…˜9ùÍ´à³³’]'ð.Ãb´ñvoe˜™ÉS{2rY¦3jf?úØ<²ñ^HohØ:—Jès/¥úWðèÇÝ6MÁ^Ö¤§égä«åNÐ Ÿªˆ²5U×Óó:"ŒöÚ'i‹©ez“ “>$Ÿ¨üþªäÍÛ½Ÿ ôSkç®A@;¶ØÇ=Ž›¡Ì²=»ÔúC7•‰ù'äÁ ƒø4³úä¬eýI‰ÏEÉÒä½ùxõ–…¶7z<×%îÖ †ÁW#ééûñ¡Õ‡QI­Î¥]VBÑ¥ƒ#ס\)nñ±Ÿå\Õ‚êªz„È¿äÎ-sJËpÏ,ÛŠ2ðíˆßöB7tç•@aó˜+ŽuɰcRX ½hó™ž|"Ì ”+S ·îI^b/>Ô:;75˜3ºIbvMÔŸ†^ä*U£áéù)ß]͹µ&}“ÑåfP¸ypæ’=ßæ‰7BÄô^¢é”ßÊu§A×Âå~ž]sB¢ìÎhø”ê./qù5ö² Í2CL£#ÕP(•ìÇ5¨Àö&ƒtýÔ([‘°*WHËe™\UÍ^Õ£¼:Ï•-oàVy7LŒþøH*€ÕB”ƒ€š¡âëäÏç›”t¸¢ dž+…ÁÛƒ¬G¬àÓÂ[‡cO˜kø µõ”xqî9ǾÉ/vu¸éÔ Çì‘Nó&k>ŽgÞþ™Ú]y!7* Q©Tp•WÁû|@#d‹->`&”ÅŸÅùÁ­ZÁ†(ÙìF5ÃJ¦ÙŽu_—õ§ä-9ªÚÑK4I߇ÂÀô ªýV‡ŸHÂÛ®­ £Û ?VRߺäü,´–e4íƒ4úÂ?$˜r²„à+mwÎ}²àÑXõG’šµa´-xšž‡ÝUªð2Oïî*(šâ„€ñÔkíWD­T ý‡Â/[[Uß®6%'¶u9.|_(Þ»êÃ{"_âarDaΚÚë%-ßéd?FÆb§œ‡¥1ûèwe’Ž¡UÄžŽ!>`=–ø9ªøT7Â\,nšqlçÎ\mM‰r|„xûÐ÷¯pËׇ‚Þ<¨K³ò´ ø•Sn?ø$«ÿVº§)«ôx$¡4»RŽHž.P-ôUªÙ\&³xŒx÷…Ý~FsÞêý‡‡Ü _<èµ@ß+gåÉs/=ÊÍDÓ†Õo¯ÓßâY‡:iù½vÔUÒOé "pÀ½ ÙTW¸©Ôjëà•7ã=ØRUòh)5ÉZDvLTOÙ´„ÆÔ²ŠÐï´®F¬\S‰Ú,”àlÖE*ÃûZß}ÎQ¯&}ü +ïrá@>e˜ó-¡c- Õ¡Ÿ™Ä ¥(tµSZ~Ò<ý<¬¾Ø“U¦ãƒÏÀ÷‘dlláÒŠØžÛÏB±RËms8àlàgXÅ4öŽQè´‡ÚÁäK’÷§=÷²×K¦wL˜_Ýød’b~ÕtzÕuœS¿£a+ŒS Š(£Œ$ôÇ=Rò}w3먥kù*,ëÇÓG=븺õù°Õ`TM ¾›mpÎq8—gÎ*T}0rîÙMˆ#ñ#*ï‘qeXwîNgt_0"Õ:¾Ÿuoói÷j¢Cn‚À ’4)á î9>3úXƒìË®²«=ÝC¦4 ×匈ÚÌ7åy]‚¬~ØJc×’ý&é-±º)Ëv_jÒ¥ `ñ~3],Æe,ñGL_X¸fFÞìè»åp‚i{.$àz^žF9e·9‚_©è•? OY7r> stream xÚvTlÛ?%1:”–I(ÍFƒÒÝRc ° ÆÈJ‰„¤‚¤´"Š„ ÍDJBBI)I%¤ù¦>ïû¼ÏûÿŸó}gçl÷õ»ú¾~×}ÆwÍØLDÅå ÓD!1"`Q>s8Æ öðYÂоpRþ?ôjhƒÇÔ!¼™ Ôõó‚%€`iy°Œ<äþeˆBËÕ!þp (P…„ùøÔPÞAh¸›;Ÿå_G ?T–““þíTAÀÐp( 4€`Üa|F(Ä h†‚Âa˜ „à¿åŽÁxË‹‰ˆB¾¢(´›¢€00ŽqšÂ|ah˜ ðW»@Cö»1QÐÜîû6C¹b hxÁ¡0¤/ÞÁéCñ¹f:ú@#oò±þaà_W‹‚ÿî/ï_àÈßÎ(…ð† ƒàH7 +Ü 4ÒÔÅb„¤Ë/Cˆ—/ ïñ‡À½ Îxƒß…C€š*&@¾¿¿ºó…¢áÞ_Q_¸×¯Å~…Á_²ÒE …@À_À¯úÔáhëAb¿Çê‰D ±ήp¤‹ë¯\ü¼Å,p?˜Žú_xð7æÃ¥@ Œó¡îb¿‚›yÃ~+Á¿`|ý¡Xo”7Ðß,î Ãÿ°¾ƒöƒ…bÿSñO ]àP ÐæGþŽŽ‡a®düäÑð@àmžx` è×çß'{<·\PH¯ ¿ÍWLÅZßÖBKèwÃÿV©ª¢Xq ˆ¸‹‹eð‡ÐF1†Àÿªô·¯Ò”ûS,þ–þU°ÿ_Óçÿk1€ÿŒeˆÂ3äÿ›àv )ÿþ?Óü·ËÿÝ¿¢ü/ÿïz4ý¼¼~kù©ÿ-÷ úKç«Ï}~ÿmjû³®0¸⿵:~Tn^ÿ¾D¸¯&<æb Ç@ÝÿPånñkÁ¼àH˜1ÊþëAŠ€A ÿÒá· ê‰4|ñ|ü­‚á—æŸ)5P”˯í—’BÐhH?b¼$Ä‚ñkè üÍ` ˜(…Á»ñí…]QhÀ¯yJÊÅðÏÒ/𷌟Æ û„GP¿å¤†ú¡ÑøÅûM |]ÿ’o9 ƒ&ÇQЛw=^Ý}{X­Â ²4 0·d•% ‚D7ûÓ¥ ¼È‰œE¨¤÷vÐ}^ÔàßWžâ:î¿yMÓ˜jÒtrê˜b:¼Ô˜ºònðéºJ Ž“‚CÄ\y9äÌ'Ä2“ø a«._¾Ÿ,q!ãa@—V` ®búCôø’Éò i=ÊÓŠ",ì"JGù œŸŒ±p“bD8ÉviG÷Fò/¸tS„¡$б¶sâ‰GcÁ_ž™‹û¶±ò²Ú²pï3|¾ŽU]ÍÐeþ„-+ž)µó+‰“øÜF`¯6¾@!s+ž"ûR©‡øÚ²ÛüÏVʆ>¤°VlÕTÆÓå3áÊ;UÞDRË+§ ý¼ž;t[ØqÎ †ºWÜ­§OeÔ_?º¼ ®ËsMAaÿF×úþ”?—â—ÖkFÕµh1j.jMƒ×a8W1ÄUvÁø}þ\îkðòö<€^¸£"®è”Â%UXס²ö;+‰ðΠ}¤C! x…™™í£ ;ÅZ¡XO÷ò"£€ÕæÏ>D;ž×…S—•Â}8ï…^åNE*” ŒYŦ ä¦fŒÝçblcà$.¡xàÙ™±Ÿî´ùÀöy}Z§Ø^’5e†`¿Rz-éhÙ×´%+œª%e+ålŒí}Õ+çv¸¬;Ì÷°¥Ú„~|··QR@³ åˆÑ¿áýÁãpc*Ë­¥²+ÉmÞpÏ”'í±¯NmÙµí•(ò­oµV;”ª†®÷Û§Û¢Œ{Í&HK>By·×èžS÷ú©»0EOH$šdª²Úš¹ùIR­æ–vÌ•4ÎÏÝ:ÏKO°\(°ž÷L—aÑÉ~£ÈÇ~º:r0qczÉüÑ…@yØe^¾ Ÿ¹‡Æ:<5" ©ƒ«–ž4¸ å™·£Ó9Œ¶³ºÒîáÛϦÜU¦ªg>ÊÓµò$£œÇýg˜@°»3®=Ú‚MÂŽ'(µwõÒ>Ôø…j0ÇVèJ 0{XçŽÿöEëñ l'øS›²Ë€zX5º%]½ÊÈ6¹L£Wt0ù³Âz*?ŸCY³˜¸e[³@C Û“oqÝ_ùgw6Û¬®¬d—8LÅA,N3qõæúˆ=1ƒ¯&Œ‰úßsDRëMp"^rõ¿,ÎÙ9 rXk÷W©y @iôkrUøsllZ×ëªõîZ½Î{JÖs<¦8¥ÖQѺ.5L•¶·}- `Äa-•êˆi¢«xÂ?ŸxoXRX¤(ÖñýíHS¹’˜iÜâF¦R¢z̧=£ƒþɃJò‘‚ü2ò@Í- ïþç¬W’ %Po竲"mF…@X!CÑã³Úpœâ`lì …üˆúnÝŽN€«ý‡5n_oddu¾x$˜+q¬ q:åQµN$¹?jkø^@ðb_/L0 ¢QéœpïÊÓÕ-žŒ×ùÑ$rl7÷¯IT. <6¢¡”‰ ýìP‹ðc×ÜÊ™è?Ž/H{V†î ½eé çEÌ5l™ô³ê)·F±,­ÝaÁ2îkW}W‹j¬G3ÍÊÛøN³,§d;Z¶‹Ç'BÅö¹¼œõ c5´)-2˜@Ά—Õù¤¢îÓÀPzÖ6 mÞ§uíe·O®§´B ôAÛ˜¥¾9ö©kç”,B‡P'Ê »·i´¾ØõHɽz\ ÷.…ì‘ä†q¿oN1ºà(èís‡aéØBótÇØi×6Ç”éëmÖ"lÛ蟗释_+i¹$¯“ká”ÐÅv!ÒÙe4zô`%,)Ÿ;³T…УªÉЕéÜ|‰{íþ€ì̹k¯ŸÉƒ°~¬ú€«…C*Wɦ=B±>Vªå7ž|á?cd±)&èqG‚Æ­ºLW“Ìæ•üަº¨Îˆ62mq\Õué±Iðäëű÷ “Í SùÝYë©ØZß «»ÈˆÈôV?z/-wî Rå“õ9~ŽÌd_ê@’¦céË©“/Iœ b"n0~#¯»A\Q‚“^Rúº´ŽlUɃÍÉ­~Ä%Üô‹ÍÖ8ˆÝ7 DJ²6zÎ.ó30f¿ñ’ÑU·æM/ÏÛiij֠«D¯gÉí{Ÿmöc6ƒ¾P°Í¢6i„ØÒsˆcæ‹z³ƒ¶ö ÀmõG•¢[˜aú,‘æ-Â>Ê8ûˆ®¸ãËoUc©•32–GHoÛî>·–gsd“y¹”]$âø2à@~…ÃÙ(súöwú-íçoÉFU¬‰¦4Ö›Òº.JZ¸åÝò¬õ)%Ðgí¬Q­\/èñl¤‘Þf\'áï¥å)y„¨h´˜O&_…·P5\ŒÚÎumÉOz5³™F/oiç±{Úÿ@{QšտР7zë0£¾5á¦ì¶”_ØÖÒmy.!-µpù½WšB܆t€¡¶;ë1¶YÖLŒ²Ù`ÈÆÁ`bZH¡ºÂ²‹Q›Ô*ßxhNâGÈ Q¾7∻©¸ÅÂEf¥îS kÏmKëÜítÑLó Í÷-¡è±º 76aùE¯Y\§j›‡Æø.÷DsíßÓ2˜3 UH4îÛVô"øº§OoîÝmóÎ[wñ€Š5Ö:còD~k–À#um±lV~ì8P™›G·Úg'%/gm1 ôˆ'2Ížuã±ß&²ò©ÍÙ¶m(KYl ÜÞ‡ÉW#~²ºÄG¾þʃG¨{¡»ÇîÑ86µ?íNPúJEºýP3­Ña Ût€ì¡7¹åÉîIðEÈ©Ž½­Ë³•Pm-ªeÙÅR—W¹*dûþÕæhæJÁoel-ÙA;WÎèè©ôòh¯ý(£U­®Kûø“dŠjV9rZ«dh†Ü—²R r ¢ M°R6J÷Y&)-½ãSU”ÀÎ ¼wŽÖé ëýÌÅ[ªè»L6³¹_Dz Tm£\vÔØS&u\¾JWÕiNœ Rdüti%òjHíõ—(.q…6Õ#¥­¢·íܦ±ôÕ€v7Ç^á°º“Ÿ>¢!@$êÃ`¦¹ôM¸’u¼óɨ/{¡˜Ÿ°Ü¶sb¢Ñ©‹zýApØúõT}ÛþÐ=ñh«ÝlzÑuÉÒÄ(Ñ­&¾~Áâ!Κ+}ê“!Û¶J5›weî&ZwŸS R«ß2^÷yØÅÍQë¶0¦ç!ýöP‘ó;“:[ž’±ãÅ6fUп«Ÿž¬Z¿_ÏI°?Cñ™c6&ÿ>‚…ÉŒT‘©]äIÂOHJ"ÕÍ; ·MÁÄKS…÷ÓöµÊʨºä¡;ÇÎ[ÑQœåøM¡¾ Æ/y™_L­iy8JŽ åŠ}ƒ%¿[Çq¿âq^  ÖÇæB ¢5à ŸÌ{ßÈ~—o?š‚ysÀq$ÎþÉ| ¶%ºY¼ÛÚÇžRሻʸÃ2›Üpî9Èÿ\ó@.Ê æžrØHq‹º„­I˜©N<»ÖŸù£ßwFö-…ÐÀâ—hêŒtxVÃ䚺̛Þ+ê§MGU»±¤c(×tw.O9A±“akì1Ȱ’,’®ÉQmé٤ꭅJ·u=#°Ø1¤ùÚæµ˜ÑT~'ݾçŸXåDcºM‹úÊ‚Àdd%ß½™ú5?Ž]¯„WD²<ë¯ðkŠ×}é >È–ÛéÑs°’Ñ¿ ä¯ýØê©½*‹ÆÝaÞPK¸ÒMêH~¯rmxñ#UóÝh°[§›°þ£ó÷Ku~u' –.(ó7Ž•¼Ñ¥ÑÀa}[µõço4stIÉ,¥<~ç°¢Õ/sd«‚· 餸PvÒ‹«¡q÷oݱ}]¦y¶w˜n/S—¹ˆ\½w–¾ÜJ£@'w° »ÊãôœeàÔ 3÷õ¡–Z<+7§óÀ´ƒß•žð5˜Vi!}MQˆÌFŒ]Í–é_Eš/“€÷ÇÁŸ3;ÚFÌꦟÜïêŸÅ%ÄLÓ/”—+4…¿(O×'?îîôYà ¤a¬µšó[y§OÔfž™Ÿ+Éï—, ³öœÇ9+, ‡¯4”AäÄAÎËhcŸºzNÆWöËy°’\i‡d~t[q×j©SJ0w–lô…y4¾ûGõŸ5È*…Ó*ÝZ£¿@(•owÞ}¼ÐÑp6Òj³•ÉÜ&3æ`ŠéþnàÔ2i-<Ù{€" .yLA5mh]vþù„”FÍl§ÐÛy¼o¤µç®g{„cÏ™_×5ÝVó»Nq&¦þ€§Ö2ÒwzU÷äîÚˆê Kv°Ñ€y†šý2|´[ìøÝ· «CmIŒ )¤Gí*¼›@z“pþi9Ù]§Ò˜Í›å+µ/}?=ãÄm´çèÒ’µx×u'»öGS3jõ„"¨9„4§wE)ùô>o^|²š¢¥™Z›±²½D•îå0¡+<3Md*I^1 έ} ü¢¸^:ÈÎØŒO¸©9tUk¼ôû³NùW¸ò"—ËW¬c‘!:o÷íûËŠ}ÄVXÀä1§¾ðC^gïŒðÞõ·,œ÷A<½)åÚšë;G57º?Ú0'½è.í+(êºò>²Ã¼ä†lS¯wúS oz©A„\—©Ê‰ùèq5g[12¹’ó8äu^O\%˜qÆwøÁJjô| ÀÄUzo¦:ÈØ5»Í6®!÷Â7{ý™fh&â/—QÔ~¶Ó-$þj¯ ÏÅÌ£QCWD¬$°w/2æËëpíã¢C ¾¸Óy‘ ÎØ pÛPõÌ×[}’þ¥.e\É3­í𤠓™;·7wZœ&scþm‡ 7£°ì,aÜÖá£?'¡3ëý,ÚžnóYß§ÄúæÕ©QÎXÞ뾂މG«5b÷ݧí¾\ÙæeF\·u7Œ »IVSÇóZEKZU©Ž ×-Æps¸Æt½„øtO(α|c0“fR¥™°]»¤}Ëüí ]—fÓÈÆô*oà”7#ÍÕrõaH9tº4ˆlâaÆØ³Â)€EÀéUQú“É~©eʘùBDÿÔ†WߊŸEÃß)"†ëS•ò¥äÎx©XeG½íÄ\a>“R&àH fªš‡h\¦êI÷Ïl+©©ì8×^¦´¾†}^(‘3Ñ_)¸ä1ÖtRO´% ͽ¼`û3å•À³$YïÈ’Û14k ý‚ü•ÜM·¯WúÊ÷ ?A?öÛ駈WÈ*«åF«©"}ÝÆØîîäô»"_•WhOÝr~5P ¡Ü žŒY`bx…ÿs<ødtZLS25yu+Záô3Ô˲gÌ?ŽžŽÑTqºŽö;¦&Û¬·ƒ¬µËù$«… ¦µ‰1›,À¡„öûcäü¡G^á»]So!aªEgÐ $V¨ ›å<¸›ê,{\‰NÒaõ(Y´»BÇ@ìþ†Âb؃¢X›°¯«<)MG?ÒdüôA»Àêòé+‹zŠ” ZL‰ã"µ “Q)¹¼Ô[Ê8ƒÜÇ‹¡)!‡K¶†MÝ?ׯñÌR›|l¦U«ÎÈÕi¼ [F±ÿ¤†ä’Ä/ðê‘Ý!r9±›crOçÉ~`!ÆÉµÎ—˜õ˜Å\éä, $¥SW9ï2„l²ˆt0Å@‹Ñ7º,Ñ-—ÂUšûá\l*º+—ù$)nM…•yŒ3:Š÷m¦YÕzT4¹u¶r}%ˆ_2›FÀÊÙ;¸;›g) „r©ñÐ]×^ç{1J³TKéuNRå¶("ûìý׬ÆâîÅbŸ¬Ö#¬¿ûO·¦ÚzO‰L µ¥ÞDêåÌÊ5èG´3&T 2U:5Š<S… ½$nÿ‘™½ÍRåú0­ýc× c—ðsëÝЭ6Ý(W/Ö¥–u•G?\÷\!Rêjt¼åÒo¼Ü’[ÎÒë%·Å ³8y æØ+KÎ .¼d5©e¼  Øò¸— òù´*–šŸ}+@"Öní‘uî¢JOköÉl§ö/63BRý££¦ÄÁ­I”¹g÷ò\š¥IDe4=Õ–ÅæÀºR.ÙË,°­Î—qÇlQ>‘Uo¹æ ü#ÍÙgÛfs »WC”íšùˆß‘EÃÔ7;y­÷e¡ª?n¸b©Šóy&W_Ù¾CS˜Ö$!óJBM›“Á3dªÁÔËk˜‡r>=^éX¡!×(Ú÷ôX\ÿŒ@zr?dÿ$Uêq &žölÑù~Ò¾FÕ=¹ÝXžvÍ „ÍtùJXˆ¡º÷óLssi[¾ï'CÚPºSÆ£âG°D^ΔÝe `]¨‘£XΔóvö»B‰Î1±9èšääxÅf ÞÌé ‡š;”óÎÛ|ªlʼ.u¼²ü뾩÷ß[AKl.väÅÓ‡ ¯ÿð¡'éÿ,™µŸÌ[(³´ñ¯éx§]Gú†Ù ɪ…¦RJª,—îýª¸à‹Ý¹^_U®LmLOõõäÏ×@mm!u¾Û0+£J–ä8 bCJÍ{#9rC„dù€ÛÜTÜMµhÄ3XNlæzVvbô\BŸ‹M&iÅ-çIwMæÛuS'=Ù—\v‡;[Séá® ÷ýü—Àð[U²L÷¨ƒ¢&ÞäbûìÞÏm¨G¿qxÞ ÖŸ¸kw—€®Z­EÓy{×ËÀ„0ø(WcßBÁŽÎô ‚jÙWªJ‘É9"¾©Üb£ˆUsˇ$ÌÚåÓ6ÌBmÞº¡f€ÙÞWï]V‰è²^›{gB_ª/y$µ‚f&6úªÆŽ·#µ­HTºLÜ\—N;-aìôe‰·?L'‰‘y/Rüóá” ŠÙÁ¬ï&º—ü†ú¼ºZ”ñø Ý’\t¦¾„ ­ð~ÞqÏ0Û亗¯«ìj˜?çFS Êéä«b`){†¦\X¢Ÿ`óE7JJ±&˜‰tZ0õÒ1;>&š»pú ÉC3»ÔšŒ Hºe1SfQì »#È5„z©×9<]ÂïéT~ü²F\-¸Â]òšÅ&¦Í÷KH‹Ä0zUŽ*1GìLFÙ? ¢#Ľ޽ Þ}Ó¯#jfðÈÎ(ör›A‰J«aûº¹Êóãã´i~ÚãroÑÛ_·,^òx„ñÐ*‰ÙðËÛÍJñŽãéÛj‡ðJBYÚŠ|E²†7Ž¥›ÆqÆiÆ^©öé7…¸Ü(7 •ØŠLÒ¹Ëkî¢{d×,«SU×ï"ÒEÔƒŒˆË≋ÃéˆÞœ?<¸ýNÑÓì×¥ùç6„ïïí?&fííJŸ­ŠêxPRwuÇTñm—åË[üÖWô4peS/Uò)pÏŠºr»9¼ß€ò¶kIͦ LH ö¯‰ö4…ZãÏBRXT%Ì¡WÎb¦ä[´gEs^0ˆôIHé^7›ôŽQß?;-k‘5Ì«’HÝQi 4~Qƒ#aÅ‘Bb•8ýÖá9—CÍF›Ó„‹±ÎÏ Ñ%?{º‚)åéh¼¯ôHÒ”Ì3à~·1üú¹B~ T;ô› “Oâù*x8µxhµ5/KK—wþùX¶4k‡õÎIÐø"G…]r¨†ì)ÁWžHÊý`àm›Ê,»õ¯ÇZÍbÕxý][¤ˆ£ª6Œd-ñ½{\·8ŒŠý˜˜äèu휫/ƒšöµ0R–àkº%x ³B›æ-Tú:Óß9qføf:ã¥]ƒ/‡½Ï’Ÿ™Ñ}æ»iÄÊ;)â'Ú±/Þ\ q˜žˆ)> zA1Ô—#·tUˆ Y6ˆÚU™Pا5{ì“3!h0Eø”<Ó£Û(xÕPÛ£Þ­Éå”´bZ„õ¬£Xëë·®¬ZüGæ/ endstream endobj 98 0 obj << /Length1 1736 /Length2 9661 /Length3 0 /Length 10762 /Filter /FlateDecode >> stream xÚ¶PØ-Š îÁwi\Bpw î6»www—ÁÝÝ%¸ @á‘™¹wfîÿUïUWuŸµ¶œ½Ï–jjre5f3;¤Ä™ÈÂÆSPå°±q°°±±#SS«[9ƒA²ÈÔš G'+;ÿ?äbŽ cçNÜØùEMÁu€ 7?‡Ÿ ÀÎÆÆ÷E;G~€¸±«•@ k9!S‹ÙÙ{8ZYX:¿ÜòŸ#€Î”äããaúà b r´25†Œ-A¶/7šƒjv¦V g¹ {kéìlÏÏÊêææÆblëÄbçhñŽž àfål P9]Af€ßémA$Æ‚L P·´rú“V³3wv3v^°•)âôbà19^î¨ÉÈ”ìA?•åÿT`üõ4 ð¿îþ²þíÈ ò‡±±©©­½1Äà b0·ƒJ’ò,ÎîÎLcˆÙoEc°“Ý‹½±«±ØØäEáÀ’"*ã—üþÊÎÉÔÑÊÞÙ‰ÅÉ ü;CÖßn^Yb&fgk ‚8;!ÿŽOÜÊdúòꬔÕbçñúóln13ÿ‚™‹=«ÄÊÁ$#þ—Æ …ü7grp±±±ñð ÈÝÔ’õ·su{ÐÂ?è—ø}¼ìíìæ/)€|¬ÌA/?È^NÆ® €³£ ÈÇ럂#d `feê 0YXAÿöþBƒÌÿÄ/•w´rè²½4Àöûóß“þKo™ÙAÀ«ÿQ\V%%u-Æ?þ¯HTÔÎàÅÌÁ `fçbÙxØs;Gäßõäã°ÿ¦þD¼V“ÿ¢ßñ°šý¬ @v«ù? €Õâ¿“ Àjéaoù²7þÖxá¬þù¬¶CàËeÿP~™V»À—Ëìÿöþ¢kÿ²² `¹óß,ð/öÏŽû/ÍýB¿ô™Ýß©ð½xsp±s™™€ÿ傃óoÁ¿½pðý%ù7 ¾X8þ¾äèôør÷?•_^ÛåðŧÛð_55uq|IÂù™{)øðër™"¯,Ù™ Y×uÜ׉¹1L ÎS¼O£göZqìty@{•L_›õaËñV$y´c}O‚îFx•ìÉëkkã«Ð¶D•öŸÞ†ñª³íÈŸgð†¦‹¾Š4 ’ 3« z?9xkØÀ¶BwËRç9¸ð¢)`ß» H¹7 V¬M„,¨ÖrË¡ÎXîL=2®²ÚP9§c•ú—È?×Ï|+šÈÒq¿dKï:‚¤‘ø'èÜã•Y•G&=˧]OF«ÝËÐ:™lµ.ûú¥!x+wÃÚ'ã)š*á¶ÔT‹L–ÞÜ|­ÓÚë§ W·Œ/™6ÃDw‡I! SÝóHfêq¢g”ÞŠس…êcÀúòN:«“"t‚Z1º]€—ÖäjQ ;Z§?¹'ÑdØlÕÀꔪºå¢í:Îê1è6É)¯y`s'P’ÌïCú\˱¯…J¢àz[F-¥xѵ<ˆÏ4WÒÉêk4~G‘y + §ÄÎÁ»g…ˆbÖ—‘ú`ºßiγ¿à_2qɾ<ù&~µÐG€öëËjy¿ð;. ÞV¯%r…q#ñ–¼ÿð¢­/œ Rëµ<©Å½òîÇ×x¾’㙞¸Ô*î1ƒ@ÞOaJ©¬ó&組¡]Ÿžœh"UÈ¡î&´¶ „ð.„¶¿¥W¨î Ž Ù{‹c»]&0ñ%%ž8½ÚGÉ ¨¯£6…ó…ÔV9Ð|’³n¡ž$ÍG!5­5qx]›¯·Q±úçÎY½ýWØ5 …â/ÆFgÍÙ#ZrÆ¿óÜ݆Sú»Ÿi@õwÚ¶ÅtÞY›ŽÚ4R¹ð· ¨Và¬GXI|ÑhÃh_ÌŸÂÈ}{Ú±Û´Èb Mó1m-„8În“ˆÏé]êñþö®ø¶äZ^ë.OB™ùµc±Tj»öùÇʘ %/Ñ¥ªeŠ€xGÊ8QÎ {<,càø•÷Êl/¢TVbéÑâYÖWœm¾Õú¥@œ+GÁ̧2Ö>F&f·V¾÷q÷<0>ÙË'k4̳¯ž‹;…­Ä-Å¿&çËßhx<©Û?ô8/ÿl‰ ÿnø˜ÌÎYöŘ{Ω,!ô 9‚R&€rÂj9Šj³Ao[äÊÞ‘*Î+©L}Ü–¦ ºٛ鞟mzáÉÁª§û®—þ‘œQ†îÁXG†¤To4u¿ýDH”Öyʹ“«ýé¨çv“ß‘àçB}nXŸ!‰j€Ò+X¸„“¼="bÞ™Fͼ¼ÖÜÝ ú®c7Bf ÝYøz|xàmk¨˜cã#Áö¹gáá~¢ølpö-ȧö„ŸQbJHÂ?¸ëÆïµ æUïê‰É-EðLƒº´¾<‚ž2ŽÈDæýlÂÜ€ÂdâBLr°]%Y®»|[Wdøœ¯Ë(©~`»áììêTh¾–Ñ áùfÒ ¢ÈaV»{è¡*"Ý‚um&é¬â®A™Õwì+¯é¿æ=¶•×àw7úzFºGqw—øÙ&ã½Òº•ÔŒHº“Pr— y@¶–´- ²¤'Ôí„Í'^œ äm &‰\=NñÚsyÕlZÈp P6Z59؆kVýò¾›Â.˜eÆ, ¶þ*b¾Ë÷©KóÑä:¿ ‹FýçšY½5'ù±fG[Ú>¨þÆ1BÇuA‡ ¤Y2'Ƭ³qö~Pªá‡ëó¸Û÷ø|h%¬N—ËQ>ÔÇQýÂÕÖZlé ÒDa‹ß"g笷?ôi@Sé+ŽÕÔá—ÄÕ tÒjJïYÛ;fÎIf¦ñïY(æÁ’·îïТ;+;?EÛ;µh‘Gs;0Ç) Óžc?寮nQ‡‡˜®ÚœÜG?ɨ¦ÂedÝci>SœYópdIŒ¹j"¤§ÓÁ¨œËÝ2ØE}ý–1ŸÀ²#`æE¿¸c(j‰ÈÈYu뢄ÂP_y³Ãÿ`›X,ð–„ÚéÃGrfäâÝQ^­ÌIF{Î[ëtÜ}¦[%ƒàÇbu{×hñ`ƒÔ8œWdQk¨×îTiŸÎÍÁ×ûî ñ„ù‡<½µ‚»„@5îwDޏ D¡žÎí-6ýgÔÔÂI­ô`±’Íñu2ì“^$vB?ø¡6C§g.ñ*ƒZ¡½-¤'kÞýѫއ›Rø×utØøˆ?æWT$\Ì©ÝûŽèl)¡¡EQèL´] õ§*¥I,†W Šìyò ªù?*®¨ˆàšAwœ…,.j'ø¦bCç;Ógxç§VÈ:2~Çkœ¨ùc„šÖnÕ•Bƒ=†¼ê´Ô†Ä’KE(ö*¿‚þ0"Ù‚F6Ÿêœ¬Óaœi{xÍZM—f x*é03Á0r°6ª•ÁkU½T3WLÂNõrÐ!Fª¥…Þ6ƒ»‡€IZ¼ž(äį  Ÿ3–8×ÔµcÑñù2žµ|8-A*¯Á½†<ÂI˜:Äå]¬Å"¦m 3ØPå"½zœ$Šó^dœÏgùp\7Uû=òµ½+‚äš\,(]Ù>ŽÐr;?IðŠ>ì«¥Ã2Ъ>æ ùów:KBú(i2œú¯` µ«Œ`ñRM@e˜£¯&dšjèÒ8ÙÇZQê %*±FH’äŸh؈3‡¤kóÍË(ðýøãrÛ*·1Ít$>Þ±¹ó/W I*Ý–yÈ]ø f~m,ÖiN·›ª#)J‘8VlÅ$%±ÐêЯ=³€q4ê¾r‚éâ³Usun îÀIJÿ$8j›ƒè¾ÒºÎŒàÚå+uäš»¨M|«æñIÏDcTöÔJ¹kH§G™Û3¦Y-oNúKÀ‘UäVgÛµ{wœúíá<åÔÈZÔŠÊq­!ÀE¶dO첤…ÛöÂè’Ëyû€­KDÞÔ]w×ñëºI%ð—P \v0`R$£4R‹=³AÿÙdmÃ&Âóü ƒÇ‹u)e†89ñ$k]ùíR/¸ ú:’BíèÖ€=ZÎ-Ôuᇈ€ÌæÜŠ`SPÿT™ÏòÀRàÊ©ñœ|Ê4 –P|à8³ók…ý§,„ê´@/ØÜõl7}G”*Š^> Z·¡ºóHëݾÞXñÇhÑ‚gâð-vÎQŠo’”E›rYÕòÏ ¢Ç¶åÄën(¦L£u–L¹o)ÍÛÝ©1’nÉsqæ%{ü<îV…BŒ¦ŒI½Rsj‰ fœyum]AÝ94²³ôsù¨ßÑá W¶.; ;®þCzoÀ>ÚØáÁ«;éÓÔš£uL5ïäZc\rÝÛ%QW9¾@N/ßÉZZ‰$|ðþmÉÖÆQ¾×Ü}5tŸ³ IùL.G ÖQv»À´ôp퉲ƒ'µáü$\€ŠG86 €Ø x1æ³p#09¥§––“®£ÆG,R¡Xxµ¿yuF­)~U^Ó–‰2wØêqF&À†WjmÄRNÖœ|B÷ƒ¯~}÷Ñ ‰¼4‰M 66…Uz òꥃݮYŒ~¶Ò»AOfúÊçÊ&3’û‹÷`oˆ?¢üb=Ò÷=ÉX é¹L=_0-Ñ3Ú\PÂ8NëÎ÷oSq.?÷¸5ÊA%ƒ~çR5¢]æØ>9…‰ðìG%’ŸQ ëÇ øÿù€ø¯ýšB–vª\ABé®y-:¿„iÏ{l=Ò¸ö…Iùísæp/ŽÚ5Œ<&‘Ù·óùÒO6*: Fåýº„ªC¹ˆ]½±ûÚÛ­ÍX!7´–!Ù?èì9ÀÚì©jãï÷Cß“)ÜÏÇÑGÓˆbóº'úÙãçMK•r~h£+c¡«Ö vÛW1öX™š<´SßÜë7é N‚÷tö*¥·yª*=Ç¥j@÷ð‰¦/Ç@óÑ0]©]úî4d“ɘ~6¹im\e´¯=c$mSÒõ«Ã/ÖmÕû½¦?X¦ýt"âÓè†Hk±ž\³œ•zÞòçÛÌfrúÙ^ô*?û.¼®<ú˜ ؼÛhØø51j¸öΈˆ!7¿h–¹.•à.\Æ|8Ÿ±ç–•—ÁjP̨¥x¢9%Ü£.#¤=r˜EèbÃM6ä¸mQÖfœŠ„çì øã‹‚`í/¡—/œ¾–<ÆÖRÏånÐK)!Eã…‹éuO&¼Ÿ½yŽûýŽN ±“± E.‡?±;½>sülCC9X˜ %‚T¯týĉœî0“W4Î#«Ý÷ãfòç¤l§áN¼iàäÛª™˜ÿu3¹µ§%U£¤ñ¬V«ÈWžC›A#Ey¡1½#¬uÝÙë÷¤H¿é\š1¦U19qÓ åEb²}si ÉžÚNšh^#ó&Ü£U2y2˜–½Â¶§ªh~ÚåcÄô±sÂ+Äu<=¡àpœ„µeSê}Ú‡&D:Ô·–ÎÏT=NêH9B-ÐÚÚ$ ¶ÔóÏl3­,Ç ¢ÖnÅÜ·Có\÷Ÿ.O ^ø_ÌooÌzš|бêiájÒ# ~õ£¯æÒí ^²56©9pb?ØeSÁM¡âì÷ Á(’áÓ~Ü-/·~{`)@EL¾JiÎSL ÝÛ »¼é#^KNWÒ\ʶ1äkÆEуʰýÖ·ôM­FºÚ×J‡ÿ.#6H¨Œ3×ü5-³º6k‘äÚ,±#•åZ£#Ïë Ò.qùMòÎê´©QìúÝrKòÊ• ä^¾á/ºmÇTêÊ^mFݯۓ[p~.]*Ûâ!)¬ {×ÀÁ¿ƒW}?‘ 1w¨.·î£C!&"f¨qW‚±Oá‹›£LHÝ¦Ž ÂkáZyåfVZW€ÅÑ(O,ÊV>±¿9•GÞÿëˆýU÷2ÀÏ}‚L~Hˆ1§œ¥f·&=Õ¡ùÍtL˜¸¡+2¥:N zQ'/ˆW>„Óûj¹¡ûBëq­Rß…“/ýšÏ/îðÐ5‹’­C4Ü‚[ýp¼¢p¶YC\]Ëš5·d¯€9¦µZÙf÷–·czrd 3?8ÂSù‹‘$£X†Úr/gÞ«<ž*_XÞàÑw–£80±ËÕŸ_c1 »ŽåÛùf¿Á ëý8جPú óJþÓ«nZL“y[…¦ÜêRPnc˜Ë$‹K˜qª9©—Ú¼ëÄÌÑV„ãùÚPœì¹´áżꥨ¥ŽÍk9Ë€Íø£ Œöd‰×ÅæXj^¨ÎÛ¨½‹íJ!¯H¤ùWéUÎà"£ØLçNZ–¥^â%o?\˜¹‰ÀÖMŸc¯çº™Ò<¥x½Ùr´!X\d?åÅ`ñÖçÔÒÕõÏl¦Ì–XÐí?úí. YÅ®~éåÛKü¬E»åãQØ9whÇž‘Ñw‹…q©ŸŸ($¦I.׉C—€l&%Wâ°É6çH¬¤a"ž×ã@øq}Nþ<)ÏŸœ:’0ÇCÔvÌÅšCT¤ê kÏ5,-Š´/sÞX71Z¹ñjåÌ¿Ü×…ó#G%ü™gñ~Áõ ¼5K «!öÙzõS·OÒwü(‘›U!r³«û"ZÁ¨zŠ„»÷‹Mw¡©w þ@ów9>(a‰ohLʰX:å›Þùƒte* >D…a^Ùóq×E*¡>e!<¨ù ÿÍ 2^ž_¥·ª¢&²ìyŸŸ‹¸Ä‰<‹‡.×–DkêÀ6~§ˆ’àNwŽfQ²[4³ŸŽ&,´½-ÍÊæÐUw¿Ú¡3bjÜ×ï­[òÖ¿P >cšùµn ûÅ›æÊf˜k:ÉwVöæ?§ï7˜ýØe«~ê}jïSKs[~…Ê5“bQ(îR›“ŸGŒ‘®à•i¡OÚ/møÔ=]§I(¾awñ¸Ø÷~-ìv¼ï2Ÿ‹#òÔ8Å‚ü°ÖÛMv‰À›‰#<ÿQ2õlÿÜÕ£ÊÉXrT¯¦@'Ö‰aºnŠ`1ß!…¥œ¹Û±B>c£ƒùkný´ØÙiM[Øs@d(U»îóù 8lÄdÕ\ò0;˜m©hnWÆz5åâ|$¡õ¼Ê1ÐŽÚ´×½"œ––©4?ýÑŒw—82¼^“ýˆ15‡’X u4„–¦w/'ºé$›s0Ó’Y"þœß`Ù¾ø×§û£?W쯭“WÌïýN¦r̺V>÷_пø|Ž"»óIÁšòí1iB;§x´¼xÍëKÕÈÛþš³§½=uõ$YùáRr0¥²å@vIæF©ûyv—"œoëH~qX‡©w9tïsRÐZ|z@gÑA²OPÀr*‰†~Xué÷ÑhÆ¢åô¯™ÖëÌ5 eŸ AþÀÊ:èôZxì)ü-#n ¯\#?¶Ó×ǘ!J¤…÷—ï«‹@»¾EÄ.è®ÈÓ›zû¶4oqbèƒVŸC1s´@ú2+Gö/ô&¡äj\[•wßû/‹úQX>¸Ee'$I Uüš­ö€—uÓÝöeeƒÑ7'áKÚ¸"‡QO ðÜ1`…še™ßxºØšŒ&Ä«"™ŸyGˆKœI(\` ºs9éµÇ‘¾Ã—©§Äsýµ–$3üœ)co£õdÒÎmôùâstþºâãˆEòfÒ­šîu:Lf²WÄåë)£Ìµ[Ø0 ¾ÆÅ‰œ¥™ÜÉ*FÁ€†™äÙ”Þ½ç(…zùäoþGË ý¸*ÀÂâ¯w¹dr-G ?œ ˆóàX(ºAÒ¥cëý–‹E1uŸ¼£èß3@Ý·{Ó~çœò/Öð…VªÄõØM€b+ÆD¼]“eM‹áÛîŸnŸTÙ$pky“í?äQHD{pH?V#\¹á5Nx0 âL q¬x[(’…ïÃee*V‚£è9ÒÈâŸ$$Ž¢âf‹òE™5•YÀ;“g|rñó肌EƒôRÓÖV O[ê·PÈp2¹ %am¾÷H‘nŒäÛ=åâb%©°;jBÔŸ4þ‡„4)xks¬”à¶®ñíÑöFb®½ÍX˜LÃP*ËS<+jKõ¬Ï_3ûR64™¢\'½çødtïX¬¢=ñ€ J­¸Šm<ÿ{’¯>SLÌàÈ0Ô“nÍ>Z2Ì[eû7= ÛøÂ”ªäÆìkøKaGN\{Ô×W4U("0)HÚ¯ÍÎô¾ÿ¬\ëYz[fd‘%ì@W»Õg{zœ:Ã=öš°¿‰1¨6Vó~¾îç_ï?X€˜e΂›yoòoO(GªÉóì4…”c‘…SpKªÛÌd¾¹úݴΚâ@DÞú:bÑr¯,g¶zN~äh¢¬I8L3‡ó¶ŒyØ*†ö9Ö_Ëíýx'VÏy6›n1Éà%‘Úg\6Ië7˜mÄú%?øÎˆD…‘ÏNc™ü\]òÄ•9×9ïWb °úøUÃźoͱAXí±,Ô)îeÒÉWOñMyTšÓðªÚr_¶sË×~ö5?Ü9eàÆ'ÍH„'°Þ 퀵1LíÀ8¥åwR<Á…‚±ËÚ!Ká !‹¾èÜÄ•º³Ý®ü½ÛSs‹Ô+[TFzÌš-k|¯åg,ê¡éR¡­·/wœ›6DÅ-á»NA Å8gÊëGãpW¹p1ÚdìàK…‰ß pÉ[  £Á'eeŽ À]DÌš â`ÜÔÐOÉù“mŸ¶ëá—Î~žˆðní<):l܈µ—ÒÊ#þe P´¿'&þ&˜9ØÔëúNÂÙì†ûTëa”˜W©cìv‘Ot¸rA–Z!ºoØ\2t+VF„„;r‰W ¤½é¥r5UûbºáÅMÂÙãõuεÐjàS"ìHé^s|(Ó"ñ|©U ©W¥©Í>F¥uןŸ®'²ùÁÇ2Æp¦e”õe» µ‰7TJ!&ðßù"ñ î„[ÑH_)@…_ï„gC0 ›C¼Ç™7Š‰ÊŽûK¿ÞŒ¬ø¿9ö×z{µ`?Ç$ÿEænu’ö´ÿD¬-yEþq#$¸(ßð‚c¹rO°(L&‹˜+êÀ7£ÃÔŠ_3îR(^Ži[©³º?W„ Sª[××ÏÑÞÇíëä¢O>s$JÅø^Õ“'¨b)ØH™# ºÑ:ÑNëHæõgëvv9•25’¥Ê¥ýœ’¤WFž[ƶB'¤‰g¤´êÁíJC#6F©‹+É Aìï˜KÇÚˆBßÕ‰´Ú…ò©>p¿ÇŠâÿÑ;Œâ‘CåÃ*˜†ÿüML­h·tºþyàýô-L‹Ï=»´×@V{‡WÝ'Ï]1}ŸÁ¯¢´ô¶ûå<× õÊžç[*¿ædldœŸPñ‡Eãe;+“( o`ÝÑTñ…ÙˆDÚeÈà'}a×§i¤7r[îï Ðpµ”b59œü|¶¿'·¡…¤§³=‘€/Æžt_ <ìn©ÏusÚ\ü%7¹ýôOÂPÌÙÌòÀêAGx\ ‡;µ±P9R*µ_Û”‹Oû1ÝŒMùŽløûaÓJ€¯Gõw£Ø÷eþê_Åw-o¹³öÂF³Cte¹(’²ì¾JS[‡®ÔVkˆõ¬‹e‹;3¢ÂÊ̱'~e áƒkm|¤*‹.`€qš€dÁœÞí<ÅiG®bÞ«©„PÀ'•?'ýv_êíÛt]—&ÞS ¬j“~÷! î\©]ž 8gé¹MÿwPE¢è# L´@(ÅP$… ‚-¬^Ü”éLíkÈ]ŸÈð—K®· ¶¼x¸éy‹!·ßŽðu{h7ô”UÇD9ãR|…â†êÖ¼CÌð(xÝîv\ÆeR>``K[:£¦?—-dË¿ï{PN$Çéê‡9Q1ö&§ŒÅ(×P­·¹šZ¸âBwÙ9<×¶d¡7]X;ݸªúÅÔ‚„øp˜RY:?LÁ9,‰{÷Þoì»è”SÉoÓbBó;¾àà¤n¯3v Û5ç2ÍÜ!ˆvµ‡Ö†ÌzušäÛ9&>x@¹Õëέ~’#Z(†®D³Š÷Þ€²8‚ÚHda«êyí+cÎò¨/•ñ$XçÜ6ÒÐ?eJsï)ºX´+$Û*…&¯Wõßö%ÖnSõÛI%µ ‹ ‚ö “÷9Ha‹3*b}'ܳOØ;Ý2imêÁ€¯€T¼A/ïz„iÐXc@öeoç,÷cýÁ#ȺÀØÃ‹çSÝæ-¯7w‰ªž¡ïëA’Œµöž\Ñ`•_Ë}l–ñÃcš1ñA°„5lµ]ê3QÙ·óS¯Kö¯ùžœxb.A=™¾XuÂv¿èjV°¨(ç·±Jv›Bú7åvq‡4{ßí¾‚£Áv¶±õ}OÑLsÀóE­g•¼a¿Ó¨FÉµÃ§Û 7o ^kr‘Z~3íçkpWæ‡ÁÛ·;uãÿ–.* Å-U¦)ysÆáF.äƒE³µ¢úM Œ°ø¤pN;Húé-­ðqܨøœ!™ôÒ%I‰Ó{®T&d”†þpK '¼píLR¬jŸ¬\•ÙÄлm!uÛØ¶Vy·Ù nv¨¯Iê]Õ§µÂ~ÿñïb endstream endobj 100 0 obj << /Length1 1445 /Length2 6393 /Length3 0 /Length 7378 /Filter /FlateDecode >> stream xÚxT“ÛÒ6"Ušô€ôz“Þ{ï$@ $HBï½HïM¤é]©R¤JéRTÀ/z<÷Þsÿ­ï[Y+y÷3ÏÌžÙóÌNVX™ô yåÁˆ ŽâàJµ Í€ PˆÄge5‚¢`¿q|VˆŠ€KþCÑbBcJö(4QhxÂBQI1I  JüMDxH”ì½ `€6@‡ ñYî¾P'gzŸ¿ N€€„„Ïow€¼Ä ²‡´íQÎ7ôŽ {À‚BP¾ÿÁñÐ…r—äç÷ööæ³wCò!<œd8yÞP”3À‚„xxAÀ€_%tìÝ JãÃg9C‘ Ž(o{ À  ‰vñ„ƒ!ôîCu-€®;þYë/àÏáøþî÷¯@Pøog{áæn÷…ÂŽP «¢Å‡òAñìáà_D{ö·÷²‡ÂìЄߩÛTäõöè ÿÔ‡y@ÝQH>$ö«Fþ_aÐǬ +"ÜÜ pÿW~JP}î¾üšë GxÃýÿ^9Bá`Ç_e€=ÝùáÐGžu¥?4„ÿoÌ ‚ˆ%DEEGˆÈ™ÿ×F¾î߯ß0º†@w„;À]$êAàû#í½ ”‡'$Ðÿ? ÿ\á ÀP àq‚Âñÿ CÿZ£ûïõXÑò½þõdV‡ùþ›þ»ÅüZºZÜJþ—QAáðç”ðJˆ¢11@à?ãèÙCÿäñ¾êpG@â¯tÑçôwÊ^4Àñg@8ÿŒ¥ƒ@+àø·Ð­€"@úMàÿ,÷ß.ÿ?•ÿŠò¿ ý¿3Rñ„Á~Û9þ"ü?v{7(Ì÷­\Oz ´èY€ÿ7Õò×èjCÀPO·ÿ¶ª£ìÑÓ wB+šW@˜(üEª@} `=( äü—jþÂÍ ‡è!Ð_7 Ú ü/zÈ@®è[‰–æo=CÿÜWB€ › ˆ(ÀÞÃÃÞÝkôJà/€žJ0Äç·˜ü|p í@×pDxàÿj¬€€ß}Fh£ñß €ßé×mñ€<òD7æ_ €†NæŸ(tƒÂ=‘¿äòôð@êo¡ÿ{ýûV€@| ü¥yH*ÂåED×e½<­7ï֜յžØdóÁÛÂSg-Ü\Õ™G vàÚûcYz‹•QÓó´\‡—>V¯òCW2Õ Qʃ ǼE#ßN_9AÀ§I±¬Ø Ò£}zb;KlKö4Óù«H±>¡çÛ%×=È ‰}€ ìœ„)“• _гùØœ‰e 5jnE’xÏÃ2ÛÓHÝxòó14ñB¡+žú›ï†ebÎ臯󇳄NŠ5ûëDk£È¨Éý4˜ ÆR‡©)Rò5Z‘l "犕ÉÌÔ¥nQl+Xvb+?f‹‡:S†…<›tCïê·x6"Dæ¥ úVNèl7óŒ¾ñÞoKuæ©ÏbQ`­cœfÕ Á û±)8=Ë?µgåæZ˜ïZâqƒÂ…l¶§î_Ú%ä¦ZgHÃć?>SÕƒ1¸9š¾»z˜ £a%ÓSÇÒarYó{ÀÃ÷õÙ ´ÚŒ1 ~¶Ûöºk´/úÁrHO1šlÖ»?°—Òª.rþ–Ô„KYÕ ¹€èµåL*Hš 6(,ÀÖëìQ•²“XœbN2".2"]0ÒÚÁÈÖ¹c.)2KBDæzXIÿü]èøSé°6é ñ`ÐòÔñ-%ýÏI$ wõû¾Ý¶Ivð8æijÑ,ì±p¶+×a×@ 'C[ö“¯vÌgBÅæW nŒƒmÉ*‚¬ ~$~Ý9k>*4“oŒ±€Å¦÷ÎoØ>§ï¶J¤Ë~9õ¹¿›=cÇG­ùû9ö1™Ã¨ªä0sD)¬º%I¤CñÃE¬±å½V×YžG߸cËÙ7Ë )áÍPw›Ýf#÷U”÷ˆÙ#%„6jµCØ$ü± bL‚•¿Šß#´Ÿjœ‡óa8;¶àoÂd5ßQï[²3Ôä#{ì½]žÔÂËóï¦:Œô¹Êé'e9íI³˜g?ØÒ7²aŒ*?)­‚µH1 œž3¨8|)« 䎆*^ZÊJ—û8ð"è¼çáÜŽ“÷óµ÷/`²t ®•æÃZ›`ƒšmë*·¨M’·ÐòÍ*Ý‘™D&õ»ñ/f_üعÿÕ€ôÆ5k*•Ó;þ%{ØSŽãAŠk¼œlö®ñÓ|ÿ€¯_õí…¶T*`X=§â>Ø5´¸%3¨T5SùоÚu©F¦w&+S7„Š£äá&ˆÆ¬e¯Ž‚Ï©²}éŒRéù Òcïex"†6Ê«{¬˜«¿µdäRMÜö2PÌX,ÅÎ×WrƧ&š•³å)¦Ë'îv½G™ààÛ‘W¿Ô³Á¬jÌñ^Ê%+«¨ù¹r€.„Â}~$3Ä„~65ÖSotôל¨|ƒ¤‰$8|c^×UtÀÿÙëUÒ¤eQûE†6-VÝ"¹ýµð¨´{WôØ5ž-{¥Ìñ ±41;—kËž5îË®¥¹sÍGˆy-PI/ë 7T‰ÓäJtRElŽ…2b¶Å;¢4¾úeÑáíºœM„5@±ÙíV¢È;ª%ßS üž‘ž:~òž²!Ur~öp³Ø?'g]!clo>ðûË¡¥¤ #»â©ïÊz½íðóÙçrÖ ñ´8Ø#öpêí[š1W®ºÒT7ÕróÆ€ÔŠ÷0žzåÇ+TÛ®˜os¸ˆÄðaY¾cÂù|ñ½ubqwÖ Ñf³ÀÒÊ¿uzbM*ËHÚlE¶³ED¼âO^_·áÌe2Ú±'<Å\«9\šj\£ í6d.’JÚ͸ò´Á0ŒÅ—9ÉU&].ö‚/çmàÕæ$5Lv1GN_T’Yóã¼á ô™‘+œÍä~L— %ºu] ²Ÿp‡,o4Í~œó¯"Ô© Ã8rfE~«út\Àh_XÓ)¡ Ûܪ1y·91Þk_™k}¶+;ÇC€ypâ€*‚¥e;“ˆ¦üÔñê³-Ç1ø4Þ(‘l°ÁÒ;`Òw¿¸ó*™ö¢ÝCô¢ë•Ti£EænïЦ×"ƒ„+/i"e³Zª¯»ÒÈ ͅú@ JòØ ÂºæCžƒŸª¢,3kXäC©7ÓnCæÑ„±R½]–íÖvÉŸÝo9Gº•,î–‚Ùkú·ziyÛ[^ bðÓX¿$F/õÒÆ/¾§"p‹¬³¸¢(Ö"Ÿ|y¶”;mžD/aÖÄåi©•¾íÐ|vÚRÀ™ý÷Q÷Â2ÈÜ7cðMgiaÞ-|2[íñøk;^¹F\à=œkZö³üɆ©óJ”aÅH 1XöCƒ6G¸yxäÀ…«Ži³ù˕һ ™Ÿ\—ûqW 8ÞÍMÚ.²’1寮?»EtbÄO‚¸…#f_®¦Ößê ¨(ò}B–ô΋ñÞwPrI!Ã@ºr3(ñí‹%¬Tí¡ýþÚszÊ}Ôb$Ö•$7jIO±é“—Îᳪh AÙgÂCÜÂëf"yªä—ñéÜ;õ›í&s_VãT+j`bašŽ´¦ä~+…¶Ò?T™ýÙ«„Ǣ̴e½÷û3¢Ž¨ýøß7¶,ùÍhõ[D´Ç*Ýbæ%þ¶T>po‰£±0üÞv*?¼]ƒÓøzz±M~3½ýU7 ÖÓ0¡v]d‰aꃜÐ.¦Ô‹åjz T&•9–õ`x»¾‹¾Ïp©&À)†W‘eN˜ê? cÒ/Þ„6U÷›ÈB{ïÝ‹õ;Ý è-•ÿtñ5ÊMío6qÞÎZ£~T>î¤8Jršr´ø²#÷–„ßíÎ-£Å•`þTPGÊ`vÔír=×A–DüÇäœúã"„Kñæ9™KQßœ7—Üõó/¾ô«çÁ”´Žô-°„B/Zôxሳ®“nö‡SæÝ«8ÞÏü—Dñ…b¡ñ\Ê"²ÀÑ_J‰™þÖŠU2,7X*wüœ˜¦b¸ž!:0fo»Ä½åÕùzð¦ôM-âD—€ Qß|\Ì“‰¾ý-“Ø ³×?¯.ÝÉaö„Ö¬äŸù˜Ëì’;+mŸë·Bé‚i6Ý_ž&2Œââ"S1E|ùÌ“°èfÞ<çü²MWlTt€QvÐ,,v­®sù\]ŒG úQU©>§_c|Ûš´o_iªÿ‰Õ/bö¾Æ‹öE³šâ>!”º/p çöìƒØAË´%ôáJ”߆¥º»×©pUW|mXÉö:òÐOÀÅàwKHg°%¹êh?›I~íÙ‘îÊ•äz³¢Eïˆù&¢_"•Í>ÕEŠ›ÞŸ¢}‡sê|ªS½&×^¨™fæ²I »ß’Åé¸<ý;Î;ðÃóÉ»sF]é¤ý9ÉËZ«DûG'Ÿl” ×–eǒȇOÞ· ö1}!_1Žþ‡‘ù盈Iľã´qÜÞ#½ÐÀ‹«™éŸñ¹èß3}"ºzý8»È\‰/å ‰›[i\øôÜNîò!<õ<¯¤\ªEHGÂÄò¾Î¤eÖ5g-Ò‘ó}âW© ¥ig¢ ò×:â0ù˜é¼!Î4Ô½Dz!O!›ónî'‡ш&¹ú†õÌП¶Ç{ò3ÁBåëúŸzL΂XŽ%”‹;(“]¤ñ[˪wŸø{ß®³%º(U9tším~¢³»™÷Y¾¢úÞZ÷£“ÇcÄŒ«/W¦…›qã¢K’§žë9Þ{§æ”gÞp°Pôl£ë6ÝS’rË”¯¼ì>t57üH :ë ö¹PeùYHQº7ÉXÔ>qw<½µ‚êýdÊ›œtP}CnJ˜ôýÚWŽLT·¹Æº«øpøw¼qb Ä;8ä––çú‚ÚºåúuØÔݲ ><“1czí–ù2*7£$2ýÉÌ1þ*áÎdÛƒY®ßõîë&{™NžjÓÑÚíl"ÌÁŠ7/]¬›îÁO…Ìd4Šüd—”B¤u.#ou;À éüQ9˜sÈ0/‰sí>îyãZá+t‰X»Äx9UÛè#LRò^o¿´. !è¦M¦Ø?õWN¥-íìºD½–CÊÇBa²¶ãLƒÊ?÷seque±Þ¯£À>9¶}¯#éTÄ6Í”;;ý!ôä<˦_÷4M;'Ûa­‚‚ßýôVóéS:£´G=*ÓâØ¶7sò¤©½ð}2ý·¸?‹Ý4ýÙü¤Îõà„ºlXBÅÆ')›öóŸ}a碼~dbt ~‚zH;ïzÂ'[)èFÍY06éxÖ^w±¶^|éû€c£ÎŽõ-I9S—>C>? ¹êÓ~渣PÍ]3çñøHyõÈ5ýÎIW“.AÿËw–Òä4Ãòe÷ÀrB Nk¡*šL¢½9º9 V.í@5º~šœO¥RŠàgkÙ·G<Ü»©ëÈ]® UHiHzc@‘HzTÆ*ûź¢Uf‡;'v-ç9ÎM¾-c.i1gÃGû÷¼Òæ»ÚÚøÍ„†¼ØZêF/W·„t0Z´,ÞFzžþ)”È®ŽÉúK½‚ÇܼOj+‹Œg5¨|5¾ÔcîÔœˆŠâ®îš1É«92Îñ `ZÚ\­&)'W\‰W÷8ÌÕy“ãavÏ¿JÙÍQìlËOá©I6=ºf®Fï Ö¼Þ©6ìßæ>l`c>KMăÿ”E¥âm¦šÒÒ‰ ¬û ®ïtV;¹Þ «ŠtgXßðB4ÎùÒy‘ªæ¢žscN“e¶ú¨í^Lˆ"Þ±¥ßÊŒã;g3Óã¯BoÙ £¿••æ5Ø»®×>°ØÜÁ!Ã}lUBº®#èêXlŠðÔzL²×tâµ¶×{¬¹l꟯=»"$»”P©}býMÒ”ZŠœÔ‹19’$û¶ÙºÔíÆÔ;±åfdI|zkêR²…LF%1¾»­HÊÏXçÆÖ›ÏÃS¥§Íânî^§Š4½Œ ñÑFÉøJ×Eqm„:(bõÙv£iå=Š`ì-—ƒeW§·¬Î. Gè´B1÷ËôÒØÄP(bÌsOU?)M'áw§Ó R­žœÌŸ¥¾¿7ÌÈìóê;¾úªÔ(Û«ÞÉŸªÂ,jÌW”ÙÁÁ<ã~¯©?¤f­ž–Þý‚ü´rîƒÐ°^[¨b÷¾ÕýÀø¸ µ?,Bz\l²>VÙÈ]CZÚZSûòŠ^,®Ñ–û|¾rÈwgkt ר0^QäJÕÃiÝg€Ddœ%):+ž- >©¹7/(ãƒjÕæ¢xAÖaQ޶×Ö*‡ ª<|c@øe²þå ÏzÂzPsÜô~¤îb MŒ_ü³ÄÚã;–=TSÙ‡.¶ñnØÃvºjɉ^J2GZi?ÍsH.B’dÏ#£6È,r„4cœ¢±+wKú*wˆÉäâójÒsìöç̬Cšvúš‹_oœx*Eå§Åž²…\ˆKð]Ï—wî8Ðx)€¸ƒ•{¹e FDÊbØ`gfíz2Sp§³;ê*;’²}¨ôÅdCcÝ Ð‘‹ ¢›eéÇj]1™PWÓﮥŕݘcfuìá/éË(ó‰)ú—¿XÐY×B€]–‘ DB$Ñ29hi¾dN£ØÍ2ÀÜÊb Ç:›8x9àxqÿAë“x·ö'üÑÔw‡¾t.$R”‚i¼¨›cFá˜gžß0z#ÜÉÎ>å0å(è=S‘EÜŸpÑ#–X?©eÎ{唦÷$~bpIï0ñLJÁF?I·2Mè[/—Â]¡ÆpOx'KëªúÑÞÏB[]ÈÝ[|Æl–—«va¼úü¥[ÚÙÅWÃ#{3õÍ·H>;obYÇ•9÷Þ¹þÔ¹Wm»'øpúòMæ76Ég]_U½åd~C µFÑM¥®\ «vŠzØÊ'BTYó¢NxÔœM;¿ÃÆtÿ‰¶‰ Å(Päç·«ú– ©„Œcf`e+€dêr åLÝRý³£È¥*ª¬?€¹¼iûì0y¿pxÄ’bV+ι3ÑüE#ç"BDÌ•bõ&ík0®ZªOÏDÀ²ésPªVðPE“tc3zñö›çò»í¢S÷#1ÜxV¦ yM-î%aMhÜgo­¿•®Ø|ï­³õ¤ÑV%Ër©+²ª·áÝo;« ŒcÒ\Šc¶ÙšþæôèFØà¨<Ä!åÎ,}3êZàËsUEÌ)Ží‡nÄÝÑýöeßîÞ(^¹{j¶Ûj…º(•b¦æµ"¿wý7rÜê÷£†oYžëÿ`˜VÔ:+>Mi£ôÉö¾ó±§Œ>R¥m%ï6asĦršÌ›¨€);lâA¯¬—ŒïêŒ,@ó8ÖGaÌ8fÕ,c—„Õjœ߸c”—Ïœ¤'X?…ÒÓÂ×–ü…˜9­ê™÷Î+Ý(ëEXÏGvQï“ Q³Š$½Jš º¸Ô¯¢ó8œä¼­ËLrÆú,÷‚ƒöãT¾}b°!–òª¹3¼®›ç5SG×"xË‹ßïû–QÛÊ÷1àÒr‡çy·,óü|'SçX°!5Ë®s"Y`ùÏvƒ‘rþÉÒ·}Mezc6e¾§ÔíøÊmþl7^ûŽ÷û/…~5©aæñC_±J›ORÇñm¹Êè·Gx¼à"ìånÏÍ=+Œ¾7˜ÛÌÙÁ잇£L2ËB?€M Tý]Ïlæž§ßçœËáõoÕMj¯×ÿ.HbPÑ×Dìózw1FïÌ[Ái*e½ëÚ𺳠y¡ –çp|î'ÕÞ­î;g¥¼pûÕØ^¬»G…«6A«Ž\„íåS¡ŒlXÿh,Êðb{€•>ô€s—ßÝ`øreéeó}ÁfOüleHªÈ%÷ÀR=²Üℼ¡½üköLJý4gÇõ†°{….ƒç€dj?\/j ’•õ V>2M?+ò¢¸ˆ« Jå=\ž ˆ‰à ©´6‚Œ“œ7T4lò±Dr†ÆxIpºMfD fáu3q¯¾iÇÓpÝë¯Ó)Â\º~?:ø@m§. ôjs¶«Õ÷‹‹“dIŸ÷¤÷ÅßÏi:¿|}¼Ç#/U_U‰ËàÏ—½ËY#´¶Gò5éðß(Îub¡¨Þ_«EªŠ}!ôxY†Ôlßòkð>…·Vk”3¨…¤Ü=ÃÔ©µê•µf?Ìßu¨éœd|É.©9cçíš4"ËLbz¿lû“à\-›¶þ2®=áC\TÊé ½æ å»Àµ^7 "ýcòÊžØhuÏjJ¡~ÁpkÏ’Tæ}¾…nI9ÃÓˆ¸4pXe®Âga®Î¾pLæÌ ¡ï…§ÀNcõ«ñ 9ë¸hßæ ¡Ý: N\ù0'ªÜF}'±U/Ë/1º¢F<à«xl6ó}ï»P<šHî/Ý<ÛÁyG’¨ÄQ’ÊÉ”*jÕ1¯£u 4Î…*é j¹ ƒ#éÖwC˜f(øx=?zXIˆÊ m¸°¬cNUèάpÈBÕ3Àa æõ*Ê9¥nC•<ðáNl²”%g`‘RÑ*1äšòIÊ> #×´Ú+‚¸ÙT“ û Ö¸Ú…ä+<ó•ÄõµZò[ïí[=ó¥Ý䘞CÁo?lr·4ŒHŸ*…–ck7§oiÎO­}‚&Xæ´SA“b|pZ–wpö—7 ÞÒTÀßÚK¹YuÇXHÍyìMÜ„¥» Ùž 7íÇÑ;&šÐ‘³82t|Š™—pÙèÌU²Ã³‡¾ .Õl-´§_Ï¡žK¥Ï½¨‹­˜ ¶€xeá0¾hý$Åèð88Ó˜fVµã£½vr`çmIòT¯ÞsÿÃÓ¸¡ì¡èAúNYHë2õa‹¨MU[«5I‰Ìäˆu‚NB`Ë÷by“åeeœ=œ ³íÒ"wë×Õ§ÒÇ_3ÚÃÒÊt|ø.…-ª–…·«:ÓHj1à À´Ž\/Ÿ9Ô³ºhMJ8CtÁw¹qúC ‹çd¶YÆœ¤ ¼ô„7ç‚¶_½ÃërÏv Ã穤¬m4 Å »GÏI+^ÈID—åݧN±Y -k®…uá¼þvñX8µ¤²l‡nkÍIÏyÀÎ43À«%X¾R8ØÝW1!S½þ¾g÷ºòˬ»àù§V×S ùEæ\ìÃØÍXNO©ë"˜EØ&J¿f=;ÿ¯ÕSV endstream endobj 102 0 obj << /Length1 1741 /Length2 11663 /Length3 0 /Length 12769 /Filter /FlateDecode >> stream xÚ´PœÛ¶-Œ»»w‡àÜ]ƒC5Ð '¸»„àÜ Ü nÁ!@p-çî}îÿW½WT5ߘ:æZc.zj mv)k°%Pì eçæàH«ê(rs¸¸x9¸¸xÐèéu@PGàìhôz@7ì,ü¯i7 ôÅ&c} T;”Üܼî×ÂÜÂ\\..¡ÿ‚Ý„2 k€*@ ì „ ÑKƒ]¼Ü@¶vЗ>ÿù0Y1¸…„ØþLH9Ý@VÎU ¨Ð饣•…#@lB½þ«“¨ê"ÌÉéééÉaáá»ÙŠ3³.`€ÍË@? ðåšÄ€º¹ý|þíøo„ÆÍ °YA–@[3Ú?Õ_Ì@›¿ðËý»ÞÞr½ÈÀõÇßÿ|™¼(ÌììèõOøŸWÌ)-¥£öF‰õï‘ÿÇùæ øÀ‡—ÀÎÃÏàææá¼|øýw Ðß<þ•«èlýE÷åœþCÙão 0ý½ Ì€ÿ®¥~Q.Àôйø¹¬^~¸ÿŸåþgÊÿŸÊÿ¨òúÿf$çîèø§Ÿé¯€ÿß äèõwÄ‹rÝ¡/[  ~ÙçÿªükuUÖ w§ÿíU„Z¼lƒ”³í‹¢Ù¹ù8¸øþ²ƒ r w@k ÔÊî/Õüe×ýcßAÎ@ 0ôÇ ó’ÅÅõ¿|/KfåðòŠ@^¤ù§ ø²CÿÝWÖÙ lýDzñð¿X¸¹Yx¡½Üõ âøp¿l¥5ðÝŸbpr8ƒ¡/)€—ý6`7´?.V€À)ÿ‡éO$$à´ø 8-ÿABN«ÿApå´þ|©üäpÚü ò8mÿùœvÿùø_—‹ÝË‹óOÄ‹ ô/øÂËá_ð…˜ã¿à 3§àËpþ«ÔËÖq‚ÿ_˜¹üÓûõ z#ø_£p¿°sû|¡ù|É€þ ¾0sÿ|aæñ/øÂÌóÈóÒÛûOø_whåîæöò ý¹l/üüçë ¾Z¡-έDBìëCÚoj¥È=ÙwÆyø0Ï£.Qô·eI=ö4ƒ¤Eo/x £¤ºgv£o×ñyJŸ› ˆ¸L×|3¢…‰Ûm,·Ø|'ñÄî!*î<»Ê]]Fæ¼ÎÖ¶D'-Z_=/%§™‰Ù\Ïvf³öåEZª¯«ìN›~q`ÀÇF#“ òbÀ…tHeuT¿©“šžéT¤ƒœKŽ%¿’Û¿Íåáß\*gƒmd`º(_fˆøÙûšLÙ|0M¿Ý+KrŸÀtÙòžÉòM[‚V$[q{ò\á|;VQ˶Eah~ ^z=ætU*÷%㦩K—Lé—¨ÅTbo^~ÆòÞŠ y|19TôþT¹©_!õ¹¸Ê¾*uÃSI¦:ÔìéŒb¶ÑLü& í Ÿyî)+ÔÑè`·8Û›ŽW[ZÁ09±ÈöóŽf«AÐ:Ý¢ö>ltzj쨳{ÊCÚ ½" ß×Çßä…@ù„éßî9Û9[¿â%qÂÔ“õYßåç¸/ûõG£Íä#úçÐz#sê,0¤ ©e“†ÓWÙæ‘ŠhÁ¾ËÜ)ÍôcëÅh¸ÉsHƒ(\‰÷CÝ/Ðsfšcö©~úsè+ݺo6‰Qè~ù®±¦Vl¡’•©> £¯{ýOÖ$¢”´»êËû<®èR.A 4tgõê1h©rõ5%aV¢ðÀœWTò¾.w/‚-7÷ëw÷/¬o‡Ù¤¬Ú*LºêÚé«£S+E¶á°Ä;ŸþZ±EІ)O9Ñ|Xökû}þ 2U!9ÞÒ]nyÀB1ÃX­¥óç©fÞò [rÆIä<ûmð9¯4Kæ †§‘u-ˆ÷¤W/:c—†•މË—#Eëú8Î|Aþmỉ U!CÓ‰+= ‹Ø|Ó%}òc.6ŠwR¡¯œý¡d‚C^Üwªõ‹ïÖœp&9¶ýïƒxF}5¾¤_KvžÐg &àwW$ZcøþúPµÈF¿¶Za’~k‚ØyÀËCugy¾_–ƒ¨‡÷yJÛ?Pýª¬ú3æO†óÇ}»uˆ¼MÃývâàX:Í”Ýq›èóç8=¼j;Ú¼TZò d‰‰¨|(‚Š4,¥möÌ-­GÞ‚e?U+?óÞó´Ä¢Ç÷òe5ÆœvSÎn&sï„ha³AÄö~‰“t·¹Ûýè˜C]¿­Ë&õ6Lª›Ê KÅOYJb’øÆ3áFíÌ…mÉ5m?íY CÕÖÓ¾ Ñ´ÒÃʰœÑ •·gámzyçJ…ÔaŠdq|¼h²5¥òÈØæÒ¿|,„izýš_8NB;Ç–§ù 67ŽõÂä¨s`ă¨2¬>fíp¡¿çIOÌC‹XÐÿÛøöF,`ùü†/œ1OäÕQW«ˆý–RðëÍB+8›:z¯¼„Ù+‰ÃTeê ÷yÆÔVÍQOøì D}厩ˆàŽjÊžŽ#á6_z™xXüûµÛ6n·a¾w/oʘ ™) Óýj¹WR™DyÍò¤& "B­æ£ä§@V¦¸¹™ypµ*.(Ñ+þÐ|è÷c¨_cyT‘ñIKÖnåËü=%E[ ¬3µËq¡¨­+ÆÑU±(I< Žçî +­ ¥~IJ}Â19„§PSD›|‡„ñ¶|ô#¤› \€ óå^z~¿o±­ü*p< ]Øo§CˆSuÑÄæ¨ É`ÑÑæ¼ýNnÜwÐg@—â>' ÓLÅ®åäyhîÜi+;à4MŸ¶Ö{ƒòÖb·HÉ»¡E!…+Þ={›0°nR»yÃihŽÌhËÌO0R¾/l\d‡k˜â&ßAÚꪛu볃µÊþÙhñÙÖ»¼z L:ñN2ÂD½ 2Wk¯IöRã²ñLß®±fa¬ÃÛD‡Pq!¿Ë{¹áç®Ê¸/´l­§ß›Ý¬Žâýj®j^— P>Ma÷!åž—¬ÎÒ3þ]¿ç `˜œ† át‹6L¯ *cdRCÁãd§¾çtb¢†ÈŸØz´?¸=±×哘óˆ’ ÓF⶘xwÀþ”Sd ì¢w¾ÿC*YÖ÷ ¶Q:Nš#l‚ ›€’Ü×ùTôÌZô#–«‚‹öeyÁ¯‘“¨œN3?»¢ŒÊj²KSaŽAÒ”›gžeÞW6® Óâ%&¼³§6\;jSЬGOåÔ›µnب†EYíe}z³·GXs«Oʬxv´B¡xå’-uU‚oÇÒZècÓG¬íû‰K~þÛ »¨WסTŸgNža'êð‰ÕNO”®ÌLǶDåp¡ÉýáÒÊ[HâÄ´qÚ롎I¤2Ÿ§nåèàòû¿@ñ€ ÎÕû±·ªÍÔy®·™SRª&96³»MïL(£A­7»§Îºâw'ï VèGZ™¦ºu$Iƒ3Æ80-¸U8=›¾,ÂB(TU<í_ÓJDz›ÛŠ‘#WÛ¬2£é$×Ëʇ܇3Ýe ‚Árä¶èÓü=¡òÄøF,êÀËIyC·¾ º¹ü]ÀIî…Êv÷À A‡`²ð¡ý+j–ÌŽE¸ ÇͱãQM/¶¯£/.n"FYgÅÍÊGÆ & QÔ çë麙4Gã~釅ÀuáÂÔ˜,F_öiHW(á?,pkT¦$… ˆ{/91VÏ»”ŽUü©€"õ¦Ÿ«€?Õ™êKY G•x< µ5 öÁ¥‰•î›ÿúÉD—Û0³ˆ’HëÇ©ˆu%žÏß½L8¸oQ¶`1Œ\{{0Æ¥xªPaŠø÷¶Ýkƒƒ?åX‚ÜRxçˆêËX Perw-xª<Ä9œÃ ÑÒâ73|°;qß4œp²ûí"ŽÛO]o«,…FZ~ܪi•¹…´¡Ðs)“­Ÿ qlµÇý²ì×)Èö‰bÓ t?BG §AëÌäÆë_ø‚{i¤¬‹«¸ìÝZš»¸ms»QÙ#‚éb,ËyÊ3ðŒX“ʈÄc_M*Œ_wÁ{ÌL£‹¤ó…“Ì0lÐ@M<:uyχ]ó[{€ëFI–”<·§­N ö‘Ü~®mfð3ðœµ7éOÐ=u©j kL´ë6>î÷üô»óÂCÒ¾ElüyÝL%U2¬øºÜ³Oí{ RˆŸÜеJkâHÔ±gôÐîÉ8ý ÕR«¾¼€C΂cŠ3KKÊeVÂÌL×66¸šAq!8=æˆ4hÎ? T°çÁœQaŒž±{è(•¦,úø)õ¥ÅY‘঳û¨WX©)ØŽÇ<¤Ì @ü;Â`Ö…ÆÐëNÛ§ÂÌôÇçƒNêzÛFÌ@F›> ×϶Hè|–rÑì=ôúŠq .M”æ‘yÓð›÷‡ÛïèÉ®XDäÝO5ôÜÔ©E0CyMµ aú4.K -7îÒµ-·‡‡Z|Iép&tÓìfLhÓÆ³–)×§°è1e(Þ‰Ïl¶í›†{šÙµ’ë›êõ51ßè¤2Íy4ø-ᇳd¦.Ô·Q}þ¥ò¸±Jû€Œ‘d‡ t[Š-ÎS’1¤9ì‹ß f&º0”yM=©ÞTÉ:'ltzeSB¸öcÇËFkŸ/ãŸq^=àóov®5—@CfG5]¿U-f|—w°ÿ½qìS”ê[¢õåîQý'ñ  ‡´”ÝOºAl&þ|/!qÁC)AAð6÷èMVmù×ÈÈ|íõ¯RÑé)ykm³p[­‰z1GË…°p‚þõ_ûŒ;Ìè}N¿—6ˆ30xS("f]Õbéßéuhßt¥bOô YWa¦“è¾Êø%a´_É_=üÌŠÙ¨øbX˜×Á8ÑÙ¦²æ¿›Ë›÷W=’ð¶ÉNmp•ÛX!mù2Þy<³ÄÒ§¦>Öžý€ÎÎÈaq)ç—;ιŃ縙áâÕüe86IàPÏ ô§ë²ÒÜãÚrï¯íÓ%ëDÞÀÙkøU‡$+1ï¡Ó+‹í[óYs:â´ß|ý¸wØhÑëx ‹ò¦YœŒPýgýÇ©‘‡½qw ~Ëxd¡µÍaøØF†™¿¥fÚl”´9»0±½pNß»ÏÒÅÓ»Gˆ@;eßz#î†qÕ iÞ7|Û g¾=cì¨Þ3”Ö)&!·µN¹ €¦õT cê¿~÷„|Ü~ÔÔT8<Á_l;pY†É7™,ÆNLšë¼Qèûu E¿ÿ«…Ãg…Û#a ´Qëþ•ÑçÈ27>{¨þI)x[󠈺åiì]:[«Ž|í/g‘¤³G]€$Õãª4ŒP³´Íæ|M×^˜DZî»·=¸Ix¥ß§Hd€3-0¡ëßQueÖƒ¨uÂøÕünE¶Ò]a°@áDepÂúq  Ó‘ö¿Ÿ»]|1gÝ{I`äýx½éú&–£ë>ÊêÜýPó~&É0û*haK'¾â†Œ$uxó&Ô[»t°’êuŒ¨«ŽjÔŸ'/‘í?U©2tü¼7†ä¨áTó· éd¹ÜEÒ™Í+ —‚oŽh R;"<ðN-ós6ñ~°²íJ¼;Ô“©éa!>€_߸õ­øçü&–xÛàRþ ›Üç /³GS5,/Ý$DÎUZfÊÙgh Ò GÙh`Y7õD&È3ò]N é+Ÿ€ /éËU iKßèÉN’*tœæ¶ ‘º­T|‡žä”¢íìgåCmîóŽÛJBŸ½Wõ»!…£)Ö2µˆ( wxYÆÖËÙIö̼ïVè0„Êê%w5NZÆ«Šü. Bu~ñI[IÃeþíTV²©^¡ÇÍ–ùæd®áÆAI¬‡ÈšaŒÐßµlX®iRýÉ+p2‡‘­û|joÊÝQλ·¼ Ø“Þ&.•­_KRhŠãÒ8$z¿%MÕÌp®8®¼u\eÈÚ# ËÔò×÷|C]x™t}ïl2(ȪÈïih¢à¿Rß!¢K3ôê2x=F”¤g¯õ”ï<3lb•e©ÿJÌÇ(û—îëx0« ýتØcí ‡¡­Ác8×ݯÂRÔ]ʦ¹Y+W#¡Õ)ïd‘…Øu³Z'ÛÉ‘ðÂðz8´ ~7i£K¬’¯«y]$‰¦»Âþº¸¼¿Øú…U‘¨a0zJ­oCê9xÜì$¥ö­=Peãr«þÑhÖpJeYýìSѵ—R¥f23E·,< ¨ÁP»£4ª:e-Â$)VÖ1Õs‘”ó[¤©0áîÄxÀI‘Cª-¾ó®³+åa:bDšÝ›×' ¦ö­ûKïb¦Å-%‚ê+“ÔCùÀ?.7Õ•JO¯‹~7<íź¥ÏLËÀG ‡ R:´>ñH„“èd ³Ýi~2ÜCUl½ßix#»¨ÔÉàÖnd‰J4R«®=(2ãï*'dõ•öæS…•U:é—¹ŒNk•¡"K®Á´Ñ.Üè?ìŒæO뵂 ”J†â,3òåèrñ‹¤[>"ÒŒ@GE+'.[ÖBøë‚¹ †ÍY§ô gR„X-ù­ç1©0`}yÌÐ@Ñ>O†þ+_4e‘ô:ä²)@5¦8ü»„Æ{ê[‚¸! LtÕ1©«Œ‘šë…¡(?,Ëç-^ÌÎNžåø3³)~é ÂoÐï²´ÑYÜ„Z W¦ ’´Áê!ŠøÄ–ŸT¶|TSõ|Žœ=Z𬓾Š6–!>ùvã²ùA&üÁoÙ2}M(k¤ó؈ÛßÌÂê Ó°¨Í4 §Û¦Ôü`1o”xXN@Î.Ö‹’F—iË9¿`V™••YÂé]ù~B¦­=&ƒª[F¢–DÖã\¼¿¼„|¸覊þÝ­þÔ a#G\òûã(ê ‡ÅQ“4õ¬ŒeÏ Å·L$Ù²wd‹öôG-S†G½'ÊúIÜç™±?Òöò9  ’yBüç·ž¢}štv+møß§Œ ? ˜w]³øoV¥ý}U¤´ôÌÈ ="•Â'ÒN ¤MŸyeÚ* È{’Ÿ±&˜îgd|ú—êHß“˜NÁlçàŠc)LÈuZõ/©ÉJŸþ˜ƒQíC’§N·BšRIê#à&jŒð¥^§¤(©Ú‘§9É^Ë»äÌäýÞÊ3i#ÛvEÌ 5cèBo¯¯6Þ JÏËÏzî$ÉL~²)÷$·4÷5~ øømX²'Ý$³4“í³í=™GÔ.ê?K.|ÀO<¶2%s‰é Z‰þ½ù™Ð^ ãÊÜrÓåÕ3 }Tð¯þn·1½øå“l–e¨ Ö°1³yÛgBØÕ€ßï™rCs&"¡Áo%†Þt}Í/F~ph»»K %PÍ(¡\…$ ã›Pž“–TEn“)³¯þDØ…¤ìpÕcÆã t;ù|±C-•Ã[zäk7‰¯‚3΀Šìîr’*¾„ä5íãÄ‹,—{³ïK±ÓÃòN>ï+¾?L2yâÎÃÿ€{Ðí¢ßŠû 6~ÒV öŽršÖ§½ö¹Å\s;"Ûêµ,@RÝ ü.’Áà.ã5ö:”ÙƒHêãQž,ó>|ãG-ØuÜY™ßpÔ¹ ìó¢Õó’?ǵ…™ºñ »¢4µýïØãÐ/ ò¬Æ>ŸÑaaݬžKB”Š'*wr–R¦Ûè©2‰™6ØhŒ€u¡¢ù]:õñü‰=µFbr©¬ŠñEBôV™'Êdón DžßžÔ•ïF®Âp¿?Ñ2CĹٖzól* ü0GÌUKÌd¼dSéÓ^—õÿ ÄGUXIz/hPdõ)Œ°®™ XÚæõýú"mÎ!£`YH¤´ý†C“ª½;i¬ê²TKØí¶³­›R7Un^ø­½ž<;`Ë"á>‘­3þd(¡—~†ËÆŠ/œ'EÕ»ûr…j}féçu ¤È„¦ÒmA¯ )ÓøÄGÇŠ®Þé]màeÄþx˜Tš`åäœþ˜W`6”úVZ¡jÍw §©û¨®ÚæE?_&«Œ£¯5ñCVyô·í~^œˆz[#ˆp¸É\3FÝB&YcÌiQÄÛÖ‘ôsóUÿ2((ë•8&)9–Q ú[%ç`¡ž¢oa€Ö|è¥-6ë²@©7µ|[3°FF»x·|m©{(ß°&!A*<ɯËO»•$Ã7y…ARöéqï+l#Mè[ùr2ŸÅ‰!6‹÷±G‰j€÷䊛ÝPÓÿHTæ2B4^·0.å’×Iò–„ï%Å Í "-²~ZþmÁ0S¨ ªga™G¾Ò½PCë;-yDn d„œg¯ÅĨG¬ìrìJ 27E‡0¿„‰†ÎaßÔ‚W @Ý#ï·`*¡×øeãtÓLÁk¤ãÐQ…4ÿVãëráY+FœV8­:jßczò§ûbŒÃÍN¦Għó ¢ÖŸÉ\rÝ€'ê\sí×îÞ±C{ü2_K({¶5Õ¿¡íô'³Ùµ‘ttG\Xú®\%"-H½á¶˜@›ôÉUƒÑ;Z€t.ó0Øhvm_‹öz⫱S5”˜ìHn4·ZæßõíŽ, ùµºîeî4åÊ.Û/ŸUGËüXõMºÿ¥ÅÏGO€Þ&ì™Á?*'—/Ûá-ìce22áã%XG11ó+çXžpÒ€~ì=©ša¬ž¬;ÁùÚ-wˆs¢6‰Y¢  žÆ(,p®Ov¯û"Iîkó˜òZò-UXÒÆÏÑqäBþ†ˆîUï_±ö|KUÑð¹”–½OÆËlÚ_üŠºj¬*Í<…í~JÙn³% -iH{bŸi(°(]óñEœÄƽF{Ô;1‘ŽÌÒŸRœõë¹s?gœt¼ÿÙ°xcߊ8Ÿ»—ÿSÞÒõmÀè~ŽEWþ Ê$³áÒHnŒo’b*›ß.&×ÁTíS­ßoÁ,¹ž7`õk–uD¾W¿hÚÇÅ…(™z¡« ýbÕ¹öïûWÞ~þõÁÉx°Ëà Ýpð5(r„g–[¤ÿv§9cQ2“jXañ+j[;eá{é5yºKéôüR@Ò,¹ô%WlkÕ¦oðûdCa#¾ÆvW¯o?¼¥ûÕóˆKÕgYkü¬0 àˆÃåyÈbK' ùúÄmrߨƒW_áý.ßV}f£§¯ÆuKPÄ‚_s{*Bª÷_Ê»ly/[Núå<+%Ï!}öX?›A{HúÇb,(Ž -åƒØ`5݈Ÿ[f ×7wª\49Ž&,À¾M*;jWóíí75@x26Ÿ°a3ÂGöq_š—¥×/›+áÀº[X~ Z‚1èäƒÊ­iîôx·mK…ù.qt /­•^£V}K©t-Wàu}P<†RÛ½&ü†(W›ÂÍ*‚6<žq²ø¥·`(RüHÀRÃ}½õ(𔽒8'îÜ !S}J´Õa\G¤9ë˜Ö_7á&šðVYBI@1—ª€úð¤G–|÷#ÒʔӲÁÐÅ8Qxlalu³%åíÝÎ(ã=ì®O^÷™¥ëíÓyÃäÆh[ôbàãr·©rtĵ.Kz7PzÕb:Áø^\…ÖÜí þ¾k•A¤×¿5E__«ö£¢¾ùª¾öþ,CÐÍ\3…É[b>g©„z÷Ökš£[ª*F ^<ù×è“•fyJ0ºBxÒs%O\¥ÖÙ|ºú3½* gßPöë(c2µözHaRb†Ãtžzê!„XÛÀê‡íþŸôÇc—µÚ"ã>æ ÛD¶ý¾h=›s¸W5ÉŒð‰ÍãÁøÕ{žJCåæ@tÂßK /²K;°R¨§ŒY¹×Ùû`žæG—²æƒ¥‹Š3žj¯¾ò>n 3~Ì ¸üß¡^#{wDÅ®¶¡ ÕË[Cï,gú94àÕeÝ"xšº¶WJ‹a™Õš‰œxÂAé¯:8í¼¬!hÛbomÜ厞šù8™TdÂŒËvk8ƃ’”°A?Ñ„n‰ø®/Î*ní‚›RH×>|¦ “† éHó§è‡qî\oÂÆ°œ 5~‹};r§À%ñÔ¬¶väH9å*Êç±PsÊ™“{‚xøŽÝçS\ô³%ã%í¯ðq]w[L ¶åõ•.¥¸2‰ –Sœg†‡W™Þ¼ÊMDzÆiU?S0»ŠÿaL¢µ€<®þ#Ena?,' ŽMZ#)CDÏ JñOƒñWPcHm:—ÅÍ:í1VéÄ,<öÊÝe¶Jn4Uå|åÛÉXYY‡œêEvoêˆö¤Xÿõ8û›Ò'ȇï­ÿ”=]­…ô{?>BCùA6Ài“UP#žÖÛ÷ñ¢ÝE¹\œ²¥+¥ƒÌIN’õ0­›÷í·„%m&l(¿Î <3áÌpgVaC…ú_ô£³yÊÛ%Q13K:©Ù”²‡q®îùÓá·k;“J>BD¨5ØÂz‹7 ª 8h)níýqý6—Ænj­‰sªfy{£¦ar½ÂÎ"ò…¾Rf³Íüø•V…q¸dJ'±êÀö½ñ}Ê—ÄÚ5ÇE׿†OèD­ç>Ö®,æJÃ#lä TþBÊâ4tGVÑU¾¶¦†u«ôq¹Î²9Nõ ¼ÉÄ·îÅŽ©Â^õ2pÚc“©Àö)ƒ܇yÑrúf¿Ñ´R¶v¹õ¬ª•WäØ.¬ÃTC¤¿Ì·Ž“”Õ›·sÙ¿Ãî¥c¶¤ió­úÕ¨>¸øª3™NièÖ:ù3Hf$êÊ»*4¤Õ²Ñ$ osÕ®rHeCùĦ¶»~,P‚múnÙ-aTöm’¨è´-nÁij*ç ,¸"Ƹ'aâ‘+|{Ϲ¬¥»­¢25&<îxéÇ5/ˆèäv„T¶ ãê+u¦@ºC'¯Òân¶dÚcÊmû³êéúÖ#í9Ÿç‰Â§³¥Sèu´‘ÙX€%$t5 ü—… Ö›Âã™@‘=ë³'M»€'þuz²Î##bHÑAêõB‘¨á) U\Âñ%X•ýL5F²×lœû:4{¯œÈz[ÓñŠò¾•i~äÉv8A Ðm½ÇŸh/§?Ý&\˜‡[¡Tlþàú~>[nqš¯js¡fÍ^_ÆŠb‚ ÓéSýyÒeñ‰‘9–fùTâ²9<å|–q†Þ•’é6ªåîj’¸_%R®¾uvð ÷™_«GúCF©yª®&š‘ÈxX6ˆ#YI·9{’¤hš<š»¶ÂŸï¼L˜$ÉóéQ±XXo~ù2· þ~~D¼É„uòÆOUÖÏI§Á(Ë uΖ;™kjù·ÊºŸ&F«ÆºÓØëZS¾sQϵÙózö¶HKV´ÛTß™Sè[Êû·l‚L(kÈa“8Ëü¢âyªûc`´1ðõ#ž FÄ0s-ú5F +‚YF~ÀÓW;&mW´+ÔïìG`ÀdFÆçríÁt'8[b"±“½!×Iã$aõî‰GÇõN" S°¹ nÃÚ¯Ó€šÁ~Ž÷0þ<žgt별v?ößÒaÓü˜èRþôþ–‡çìtÞ¶ìÍTÏ%ýv*-*OT¡~á¼JÉu.V3|Çàk @ú'±êËWSó¶‡^ë%M­Ô˜“Ù°‡¥5º.=˜V±ù<ž/5ÅYÖ~ )å ®šÐoV&Ö¿ùIŸ—‡é<—LíÔåç|T‰Gû9Ûœ›ôŽøAL’_oùðŽPc”÷Zé²1Y†~ŽŠ¡j‹…ªà¬C×­|©n¹PXØlp§=IµÈáX®„p3îPŽ–ÉMtÊ.ÍZ&»‚«[PÐae[‰£&Ù(5™är„¼ ¹´¤iBâOÅ&âì5\2ìšxœRŒ;°n4Ö!©„Úk¹4 Ja¶5)æf%_Ĉk¸S„ySü*Ë>z.ó>ÇøÔׯw!„«*àä•lM®GI¿1fäßM»pùjLùE×BÇûW'¨C¿ÓWïê!ô¤É!MýÙ&w`Ÿ}°9|Dnds¿B7¾Í Èv§V YÕÇ,œÇiÀ~À ÑòNñV&ÍâôþEî¡#·au£:q6Æ7)ݲŒÜü°™ÌQá/‡†"”¼bö”§A?K.‘õ•d;råÕ¾Ý2ðpÔІa™«ôЉ’úÃRO­6Ú©¯`uïÇ`ùógÌ™F…Ørä Z-c‚Ï·ÑT»™¼RO_)ñ¿ˆ¼&kT\Òi©r²iœÒàµêî²æÞ5ƒ\5,²0¼mUüdÙù¬M§ fÝM(ÅW¿—†gNg`&ƒtή=r¥ÍT(¿éûÝÏE¨7øRrWeHùB¿í~xwJü©©s[Γ§*%æ¹IÇÁ›ü³<.K BŽwfƒ˜¥bc>„¥Tìêå¾5ØcÖççj­Nx°B5è§ïü’ô­Øîƒ¥¥ƒ‡Uäd¢åNÓó(âNâ/j{ó|þä¡‘°W¾“o¥ŒhY«©…ØÊŽðˆ™)5åH5*2ruÃË[?( ±k¢+ö\:éÝû´f=»âó#T¾^¼ á…˦Øòh}Ì<A?“Ž“Å1­ª†Ro…!g þ¢¡µ8*T¤Æl9îZøiýÆŸã׊޺Âw‡iÈó1í-\ÜúÕm‚ë~ªX‰Y*õ4Ngk7™RmÚæƒ$žZfå¡yꑆz†á®|°Äw¦üýÞŸ4¿9of ¤—²+×Ic²ÏðD™†ž‰×¹´$b%ZpÌ"T‘=‚’ HmQ¼8ÎÉTý?©¹æyöyâP'PšíÛÔ;‹ÉAt= DVÉ©;ž ]®ª‡,wtZÕ);{7hKʽ¼`®ŠàáùfvÒ/4ÆR㪲…%$áÔ]Ì‚ryâõtU|jIxxÄ–[Í"#×e(+m~+tßU‚Ö#öf´Öî Û¼©¥‚ÔÚŽ°@‚ŽšÃAøâ[júÊ,Øó{Ôh;Œ“jxfòSüеï—lö›¼1kKÊ Kã6 ûG{)ÁéçVòš‡Ý2jµNÑ%/ »d‹SåH‚ÓîÍG¨f?ûù/¹–4_²m¶‰y””I¥Ù{ÕÝqÉÑ w¡¶iU¢ B ‰îHÚÊ—ÛTË»‹¤®ÎÇîÞ Î¥.Çë£Ò ¿íuùÎËþu“wß9"ßB(ø{¥×!ÝÈŽIæï†'ÉbtkoßýèTVÝò ¸¿Á:Z€ñ ü}øY`:e†›¾_lÒr%ÃY[õ &µ¬¸üÝhá˜Â³Î}Ó¢©›ùvtŒ‘Çä>pXJë]¬°¥¿ú“,S¸š–mñ¬jM| ì+o¿æ?Bºl ƒO‹¶³Õ• NÍÏžý=j0í1åZâkWS(·Í—µ2Ç9œ7SDש¿Ž6÷m¾ìïÉ`äÊ9¿2íšaò¸P|: ‰òw¼ªÙ,Tìñ%éu²˜=SñÌ{:«kÜ…oŒ|ÀÚ¹²“YX[…¸ÒñC•ùh«œ6ê³ÏÙÀ éwrPiä©àŽL÷|SÖ•Ðq7l&Ãbã/›BªrYÍ(b ;Ê7WÕøHÖzÈÅŒäI7Ä£hz‘¡6êz!JïqÙÅ-׃í¶Í8¾p1ðÒl¥ÁÈÊÄ…°Õz¨'c …·‡¤SoÕõÒn¿R´w5á‘ãëóKšQ:*õ"ÂñK-vXz<ª†1·éM—pzÕë”úbgí¢‹>9"¶b˜£§¶wæ4‘ìwÆß¿Òß4kÛ­’ÁSb”®+&¼Õ E¿ÚÂÿ¯œ÷=Ì S¼IC¸™T ç`L³ç†Œ¥®˜#2g_ÐøÁ%†ã#'­ÀO9 ³7ªBZ&ÔRM±ö“ÄíÑhe‹ 2Q¸9-´›ð)A¡/a¶âžx£H¶¶~XXØŽÉ0{N#œò«×q@¤4 /0EÂÍk#ëÉ~»¼b›: QY´U@fí²J5s¶~÷}K~p×àQü@z[ÞÑý’©nᇷÇéiAöÊf¥RØ=l`,C0†öiÇÌþûf«r!ž+÷ZLo}ËgÑ™‹‹ðÿVÜÓ_ endstream endobj 104 0 obj << /Length1 2571 /Length2 18256 /Length3 0 /Length 19747 /Filter /FlateDecode >> stream xÚŒ÷PÚÒ ãîN°àîîN ¸0ÁÝÝÝ`!¸»»;Á-Xp'XÐ79÷Ü“s¿ÿ¯z¯¨‚Ym«»w÷Þ¹²“ˆ©­1PÒÖÆ‰‰™• ¦ ®ÎÆ `eå`feeG¢¢R9Yÿ+G¢Ò:8‚lmøÿe!æ4rËÄœÀ† ¶6Yg+€›Ÿ‡Ÿ•ÀÎÊÊ÷_C[~€¸‘ È À µµ:"Q‰ÙÚ¹;€Ì-œÀ<ÿý 5¡°ñññ0þå±:€LŒl FN@k0£‰‘@ÍÖtrÿŸ´‚NNvü,,®®®ÌF֎̶æBtŒW“@ètpš~— P4²þ]3@Ýäø…š­™“«‘XL€6Ž`gS ÌP“‘(Ùmþc,ÿFÀßͰ1³ýîoïß@69™˜ØZÛÙ¸ƒlÌf + @IRžÙÉ͉`dcúÛÐÈÊÑìoäb²22ü•º@RD`®ðïúM@vNŽÌŽ «ß5²ün³„©˜­µ5ÐÆÉéw~â   ¸ïî,®¥­«ç‘ÈÆÔìw¦Îv,l@öÎ@ñ¿mÀ"¤?2s €‹•••—ƒ´ÝL,X~¨»ÛÿR²ýƒkðö´³µ˜ËzƒÌ€à?HžŽF.@€“ƒ3ÐÛóߊÿEHllS‰Àh²Aú,šýƒÏßäÐa€õ÷Ï?ŸôÀfjkcåþÇü¯#fQ—’”Ñeø»ä”¢¢¶nO&N;€‹ƒÀÍÇ ðþß(ÊF ¿³ø—§Œ™-€ï?É‚»ôß„]þžÚ¿×ƒð¿±mÁs Ðþs]V.Vð/¶ÿÏÃþ—Ëÿ¿ÿåÿuÌÿoF’ÎVVéiÿcðÿ£7²Y¹ÿmž[g'ð(Ø‚7Áæÿšjÿ³¸ @S³õÿÕÊ8wAÄÆÜêŸF‚%An@Se“‰Å_³ññ‡ß{f²*Û:‚~ß,&6VÖÿ£/—‰%øöpä_* xwþ—QÂÆÄÖô÷’±sqŒŒÜ‘XÁ“ÄÎÅðdo£)Ðí¯!°0ÛØ:]àê¼f¶H¿”› À"ò[ôÄ `ýƒx,b/€Eüâ°HüƒxX,’;€Eúâ°ÈüA`>¹?Ì'ÿùþ 0ŸâæSúñ‚ù”ÿ 6‹ÊfWýƒÀìj'xKþ p.þ 0»æ?ˆŒŒþT ö3rú£§füéŒL,àGÄì_VÿÈÿ³ÿ(Àµ˜üƒ¸ÀÁLl­Àð_ 'ço‰µõþß“Ábúä·ÍÔÖÊÊÈá_à,€‚‚-€ÿCÊý[oï Þ°?.àN™ýq§krùWŒßj[çs€MÌÿ@pâæFÿòàfÿ-¿À;«±øS¸çîv@›Y€e Apë-ÿÁ4’æ7Âê÷Büу»iý‚o>–?±¹À±lÀ‹ô§u`.gkãßW˜ù¿rßÉ,¶²Ç´ý—¸2»?j0‡øá´ùŸóædû[ú¿§Í > ;ðMgûçü¸Á}¿6Ž­ý?™qþÚ:Mÿ”ËÁ÷·ðc²qü-výuÕüÉä_½gWû§U\¿Ðå_­ç›;‚ß™?àdÿЀïk' à¿f\¹“«í¿À vþ3Ù`†¿¾@8šØ:ü;-ðºü ‚«rýÙÁAÿ•;˜Õý_Üz?ÝGò:ü'ƒÿ¹ MœÀ½wúë±_“ÿÅ}÷Ý€&HË ¶&AŸjƒÚï«Eˆ\™v'ßÍRíj¦Ñ1y.;t8? Á'ÓUel8ÜŠ$ôb¬íHÐÞ¼_!{ö­ÒñÕ1ÛFDÚÆ]k]µ÷ÆQ€#¾Þãíö*ø”YBYãÙ÷iêÄnÖmÏM­c°LâÌ ¾ 9» £‘‡j$þ¦›S±Š¯ÍQ·‡Ng„pEòÃ*³ýåÞ çiÞ¸v¯Ü£‡«+qƒ»UÒT¡ —1VÙ'“øSmÜr(´ôÆDžœ‚…‘R¹þû·ïeWM+ßÏ´Iž@N(„îßõ”æ=šb¾5g¨}8~×t t3§ý9ÔÈ·¹)U“8Bñ'BšK‹eeGP»v°à  /t Hbâ«ÎØ$un´ r/çÁüÝ-jÔ¸t ;K³¦0EŠ,*<ѧ‘Ñ«*É^asÕt¹’:½ð‰8AµY倿îWôØò¯ïnJ·uƉû—õªßú¤kÏöh/¹º WEÕ†Ö ùkR‹ëÄÏBdRc5ì¶Î Pð·+{ÿòîŒßèê›1ºYøÄlð<»2&MÖ°n³­t?è;2«Ð4KïfÝ<·§U™Š3.t²†Êì°‹]ggæÉ*ÞíÅý¾l?çð³€ÞKU§…×Ô4ó}‘ªÌ÷‘j¹9hë,«[ý5jÍ5?üÈõ!OÒ¦ü‹gkÉþ7ëçe$ŸëS»ˆVæÓG8â$å|dðB¾ò¼ÇSçYSxTRF‹`ˆY‹’e…|¬Éð®M¸ÏÆÙû4 õñFbѹŒ¬ý ×P›Ýjœ¨L{áV^„ï©$—ÇN¥#š“ÕR:}nžóÂYçÕU«£/%#{÷3{»ŽÓô·‘Ñ”•/QõYÂ×éÍÆY[/ôË$P”~H¦ƒ_ #(ÊÁ(Á™áüþ¹—%t1%^fÎKŽ£Ìðá~•a‹78ÝcÌ™¦öå¾+ÏÌâšøÙîË@ÔXpö‰§‡êôþ5o{“Žr&lLbÚ>ì͇µiÉÚ»¸¶$'‰©€oMëùïQgòýðÙû¾ÔJê« §0}Nþ|Õ[h¯ŸEþEÏfîz·ÏÞÇÉR˜›ÓÌÑõ¾l[·šÇcÕÈãh†ø.¼‰y3ý⧤„[€MëpéÝW˜¤‰ï;›OìÛóp &8q®l(ÑO÷ã~Æ92z¡Y=î͵ü1ã?PÍòJÖŽ"w. ‹ÍÌO¨ºìòA—dJ¤´4ž%±óµch®e/j{jÀL^ñ×˱¢í:ö©Éî=oÒ;É ?ÑùbÛÙèÖøSl}˜ÀžÔ3íÂ8äãåWšä¸Š4H%ÏÉ´ð>£­LÍaÿÇû)®õ¬ek‘¹a†\ÅQõÑ/ ™&xd¡†úêhH9Ê.HÔoª«wzŽÊãõîTU3KžŠÁèWq=ó½½9Ýb=¦Ü_¢;zŸPË_D«I³Ç ñ": UŠBÈä0®ž’<§òƒAe´ü ]¼Oá;Y&A‘é|Ù¶¬µùPbx.„9£oH QO›\1Kgþ@‚,Gƒ.·=‹J#”ƒ™%±©¬Èȯpà¡Æ!Å®Šöž[7gS˜éb^ïc4ßêÁ¯$³½EZìQÎÕ£U€Qi±ëø²b廉"ÊŠëí ¾¸8²æßŒ]É·SQÆÛûýGÕ¿%ATˆwCŒðkÚ“ëù‚ó\Û _ J`à£hv{ 7-ôázQÔÕceÊl¤ÃV?ó1;&®bîúr ±ÖovüÓün×4Ťvah´ï`Ê´ØZönËÂs?tÍ”³œ(=Àª#QRŸ{ÑÈ ð3‹€&äøò»Ü¤˜°]¶%žæ8Ý ¸HÃvcs—[Ÿ"2ú¯³‹L·­¸hŒÇŒ×íS¤o™J‰Õ¼[ˆŠŠ6wÚýRW°ðöΤMC5 IP×=æ‡s¦,ÐPÌð¶§>ôý)X[­è£]@»û±$¶³Zo[t?9ˆÚ”sO‘7ÓŽ ;$†ÂL”ì†1oB /¬«,,¬býo+E´+l].9 Ÿ–D>Å‘kÀü ´äzw4H©•w"]vý2æ…_Lð9ÄE¬*Rè±# Só=úÐP2p[^‰¼»ìÅc0o¨ï‹3ï‘,'C†ÔIÛ£å£$„Ê T¿@Ã=r¯ß #úÊ ÓýÈq0ðtÌN2Äöñ‹/a¤ô¬Ð¹ög~­5~UBûAЏC8Ɇc7yÐûýø”œu8¼¢/¸X¡¶Ø .½<.ñÂo$k¦Û‹Ët´Çx®Öâ$›º&y-¡Jɾz°4eHÓtjS…/C¤/)LðFlÆÄjcŒ‡Å@ òlxVÉÛ}Çì»Ó £ÂÆÚ:°]ã :IW·-x³ñæjÒ~u®ölsÀïù ýÊ'Qš³0'U¹åÏÉ·"´ihKhß9ÁP°åsˆæ¶«ì•eÆG¶X.Üýñ’ÙyXÔÍLÊXâ‰ÙUSà18Ý–±ÿ«¨¼¥¥\ƒ'<Ÿ‚¹ù#¤Õ¡Wu;‘ß74…a#ú/s”·á$].o×…Nx>œ˜úNô5—AÐ4Aá„Ú4+¢O§O²Eeìj~,{/^~ÕXC)ISt†cà{]AçäÁŒt—B§é}ÙØ@-öGí펠¨ðÝF³Uê5Hò*7Ñ~!ö-Ø |ߤí'B¶Þùkó½Ñ [Ê.‘±pܾÅ$n2äë¼VwðùYÖ~ø¡z¡¹h½ ör4߇gÉ#Ù*a ,;½^äØQ»I‹¨¥žÜÉî„âËP¼~Só‰yûß;åC„ëü ñŸøIå"*oò4_©Æ?&ÝÀP.…òãðÙíÔKê›fˆN’.ȪÒBrë0©ÓŸr’gEϸkAÒ(4<ÓB#W TŽ*`—)‹¼4‹÷S§0#Ž¢€Þ¥¾|,¢NPíì—:FÖ+f—÷; é‡à†A¹¶ ã¥Çe5Â0 ¼MI$Çoe k¸pÂhRˆ„þÈ éÑÁ¶AÉM‰Ûäýè¯)¸Áöi´ÍýÿLÙÉY„¬®¯ì—Èï2ºLæ©;«ضð¯_½»ô&i¨+¦ÝQ›`eN쪊aûN‡lúˆøöç¨ Ü„@›Ÿ²>VÇHÃe ž*d×KòÓAr« 4cŰpæçDÿÛcÑœ©Éá§E^¯µU©©ìïë纭Ò(H6ƒ[p&ìaUnd'áprÙÈ…ù7q·0[Rv1ðœÞ’ömâ SµÌÜ%›E¨uu<2r€ÁÞ€Ñ ºÔñèOLÁAý'JAÜ.7Îqï#Anõ&ƒë†«XÔÝûĨh2'GpX±„±+-B˜þ¨ljGj¦°×»Z”gÁ†t½73ý‹ü°xg]ɘzÈ÷ªXzÓ’2•ê–n™ŸÌ³¥M˜iù‘z¶Ï˲ˆ™£¦¡R© ìì»J¯…ð|Ë…ô=ÜW<õ&Lô2·¹m+›BZnò†¿—;I'ª¯‰=O-’•¦í·ýõxQâ¸77‰†ÙÊ; úy¾3ën,§¤HÞxÓßRý¢DÃz(}p2uÌÇ˃Tô0ilË(z à’ò™ð]êmÎŽØ#IæLˈ± #vôŒ=hº†ùw§Œ4EêKÓ…8 ž¡ ¹œ7ÞÉ’ª_=T$J‡áBòkm5áÙ4cOOy>Õ0ù£·ß? d;½~óV~:IrêÇÍ/’u«Kæ]žU%^ÝbÆ×õ5t^ÕÁ #"k(º¦:láè ‹} æéÕw° Q”%k8z‰œºJΕ¬°,¯E®ƒ½êTúÔ•Úñ¦rce¡^øf~Ú±Da^#5’®ô>-ågÏ&|©ì¥–ÆåX&oýI7[Ï3œé[Yy6­DÝk­‚ßÝý?ì‰M¿IÕúB”#®×:¶aíü9d’ûÑ[éP‚YݸAs¾Å'Ó€#B#¿þŒ0®žˆSõ"–¯ vºáèb µÄ6D65F³‡º ·ÅKS›öWÐÑ´´<âÈû½ÐIS¥¾/{£Aöš‘!FñW„UkøÙüŽøTð.¤ô ‚ãp¤i۟øetaÓ¹¢-æ×Ñ™t#~ý'5žÃía¬2W²¡áÅy.­¨$Ç#1B#@ò̆Ý Éõ¥!üi¤=°Ú'.ž-¿åùE‘7iì§þí} … Q’«Ýä§LÜÄy‹lwu47ÅÓ°õú…öè‚S´ç?}z¸¤º‘ƒ€¼qF“úÈDdˆ¦© VeꞤ îj ¥U¼üÈ83¸”ýœ€R‹À s–t·¶¼jÅ™ÓÁÙìÂWæbg8*þe8oí¼µdàåt~ „1vÎÞ‰¤«*“Á+[‚ï4Õ!w âP7 Ü&•”3¬ÆcoÕ=éuYÕ‘'H©†EWvssQj…aY“Rí_O_ä/ê“>Ö× ®|ÿ%žd¤·+däåÐι˜8ÿžð—igijOÒ¾KNÔQk·_ÜL•¡Éä2êÕ±lõcÚM-ѯôÀð]ñU7Þ¯ˆ½ `ÁYO9¤‚¨–º9F Ü \7žzžºQÚdX@XNÙ”næœyNaÛÜËÅÇB§$¶9n÷|’ p£‰€dg¤ñó´$ЂŸ¢&!IB0_@›3ÈdÏq⇬Ÿ+’‰¶Wc,¥Ø°Î )(bxˆüââ±v³sPà ‡—H¼‡ä–ç­&ü’±ôhšìVQö!Ï+UV‘±N¦’pßå€nŽªkèFËD×aŠlÍ]/?ùJî³h¨¤P4º¦r¿®½Ù£=UDè\ßÈ9ÁÜŒÁq8G©bq@©gÚsÅ{‘ú?$²?vó‹xû礿ù*ÿqN‰{ÿ‘ƒÊŸlj¾«>¾˜´÷’ס¢z R¶ÃÂSÝ àd¹L#Šš#戨ŒzSÔüœËÖ2ð ! QµÍÒÅŠÒ«twÂjowѤâ1ã`»#ý V—îâq¹Ÿ9x [¾äŒ5,–ߥµ —iÐT¹]à’¢ôÒoMà!åA¶ùD*슉]ç‡W&ݰ~£pÈ rÌœT«Üƒz×ûÍ}åQgîqN_œ©²šK>é»&¦ “Ð Þ|’Ì[¨éÛ,,Y¾3êt™Xèà·5€©ó˜Fú6QLH†â Ü5IMÓï)U-çtce覀 —Œ}asK.mÛ~ÛuœÄÅ9ußÌrC }ð7N¥z…æž–Ž'Âs0rËÓvÌ-Gô $x±›„¡Ór– ÂY íàŠÐ÷'·ÙÙAÐÅNcˆ´,:ýïw¼Ä 7 ôŒ¸wæ?Þ i63Bµ‹EF@@(á݆«œ„kïʈVm’ZÍÙ_bó¢ Œ0_M uÑ÷wÉ+Ü•ïgw%*ȦyÛÊeÊìÙÌ|²m&r7'¹âHè™öŠWí´'Ƽ(£y(A߃T{X°•YÐÐí‡_Õ-¨›GFëlh7œ| !®üò’ÄUPUL£È늮FÏ Áï…1JÝ<[z^⻕hTè†'0¥…cXgrW39Œ¾:?/¡0vÜÙ 1ö¿Ñ¶%é+ÎäØëNÓ~­1\²},Äm¼£h‡kÃSüYñ®–Œ”ÆU¾r—«öEò!„¦K»Â¤±™KfKÁ/bjÆùiøÊ@Œ™Æv)³àÓ~\êÄån·æzj,‚Œô×ã‚XÐ;Zô±ÔÜþo@åуÐÌŒ^}Þ¾Œ•K¥»òõò“iÔ¬)t€f«ÇŒë “¯|)U‡QÔxO°sQ•)M_¯ÚÇ@»Û7Ó„¡Ãà;ñvÜZdˆ40[þ•¥znn •¦m:óœP?MTHA&K̉@HŒæ œâ¨„³±,Œù ®V¥½­Ô‰We‰ƒj…-q§Ï4¶/XÐëqíÅeï¥>¼tÆæ½c£eŸ{@Eêà ±\çvò#du‘C+u«Á³x.±ÿÉ]þã‹'ÇÀ¤‡"÷¥@[uŠ„ð©œnMfà0ÿÁ7Å£œÜð;vT¢ÌüœŒRtv÷âXÓ§¹VÓ,ªJõg­9nèO?˜«j¶Âm… ̉ssÃ’3é‹4~r†§vÆüØ™ile>Ù>žtÙH¸ªyjÂ2Ø_¶Ü ì5éÞÅÓ½mÿN¿˜sš£A½Œ¾p‡ˆ‚_Ê\û¶'ìêÆ¨W•,£¡íáóÓü”#;(Ëé¶àû2N—õ;§É”¶»IšÚ÷«ûœVû„@si!IW9ÿsÌ/Ìö¬\Ý®ÁPiP± ¿†ú8w’ æ Yu?ÙQ ärîQoµlb™÷h×Éþ5ü¯ ‹ ÊÐÒÂÛ}ƒÅR"Ç0;µÍÙa«yçlSééBô”dn›Ð"ÏyÅ&vº°êPÌ™ÞO¶¾½ÛJ JžNÛõ rlê¿¢GâØ]Z…#¾¹%3ž|ÐãD"®¾h³Ô„ê!­ç-vLÆ“=ÙûQ|f/LßΪSà¶§RÇ3‚ÐÕ ¹$—£U[äæw{ª+ð–¦}t9äK,m{¯?éΆz³ðØŠûúd ÞâY@Ö yÝ òäq§í‹4&OvL±´ çcT' ì0êR–"à Î Ép1%½Ì•}H ⃠Ù7*ÁvI̤ÓÙR9Þ 4”þ›çWÿµ½h§G¿ Ë~Z¶¹Y¬°7]Ȱ¼±ñоƆCâ;ÁÕ´SJ®¿ÅpŠÇõcLl…=¹—?iרÍ>ñ®ŒGѯ¸¤DÞ{Œêžn·¥Þ‹°ÐÇ{¦–à“/y†g?‚ŽŠSa8†Ÿtê üà'”÷Ï~ŠÈ·C³ºÙ7_’²lŽ¡ç[»‰u׎hŠCËÄzK~¬ry©p0¸¹Ú‘›Jº÷¶ð¾qU)ïñ‘ßãtÕ|Ëyɪ߼¡^]t'A‚·0·?TQÚ*²rm^(.}" å Ž“\ÊXeÁúRtÚÕ´P*•&yx^"nŸƒO·åÈKÒ@sªT³ †oç.ýÊM6‰ŽÍQaY^C4ÿàô/QIêÄŒýj­ï'“u¼É2_8Pا1K×>V—‰Pè4Ò. »õ²‘ãù2¿t óACUQ>âê.|edë&â_dZ›.¶ÁÓº™`¸†œç‚=_êãºÎgsVzñ*jÍ|aÜP µbšÛ;„R¹þ¬·kÞEßâÔiY«ßÜ1n i¤îçû"‹þ±ÞŒùý—BJ1 5¸¹KŽ…wP›êÜ{S´Ûˆ—âÑÒÝAÒ¾½Ab<("£¹Ýæy=ð'–HÎp÷öyii¯™ ô¿¾ÚîëÓº@¨4á$¡ÀÊÓú)µ ø`n ïÕ}ª¸žIC lÅl´·ö7OîBÐúÜLÊì6ú±–âÂ~ g ź4IþûjTµô;Ùƒ’Œá,½µHž»>fÛï ɲ£›L„Âõ:Óª=KZ÷"êd…²K˜+·™=™•CˆbzuG÷g`e.÷¾‘nóµe!‡Š¶LÁ®òF!™Ã§Ãrªpç'ƒòؘºh:Œw´¾J¬#ˆªæE¬kPK Ñá´„3CJåKœ¡¤Û<ò‰€Œ©©®dø—õß0¼N·A"6`ïÝnäðf˜øÉ³v`¾¦\òN>ôÃÐÈc°‰ê|Ú•* ¸½ñ˜µ±mÌsJ“‹M6®‡Ù§=¦z¾K¥{¨ºi×*D7s÷ 1Pïè·dµ9#aÞ5LÓ:ÍøöF};»)ô¹ Þ–Lm‘6è@Í4H¦ÑÀÍý¬+qq4Ÿ¶v¸|›Z_›t°ùÉÐ;a%kh9ûþu`5ˆfJÃeíj2îu—GµøMOznÀ¢Å£8(Œ«¯åW4_fA;Fjr?»·†Õ¾Ë_rŠ¿â!çߺ&ç©N‹iá˜uÐù'”N½(Š’ó˜ƒÚùlL¾žSWàˆJ;–‹ÇgjtÒGf‘j*‰œzhäT`>Éç]3 ÷G½*ZÊn}s­áÌøEÕDƒÉ«ÅƸ÷I¡µÆÆ7VLÊ%æœÇJ¾E6t9J®3ÐêuxUñB&uPÅçÍЭø!ÏÌÁ§w¡h¤}íÑü²Ñ&pðô1!àRæý˜=¤nï“GÌãH¾>SÚšÞF1jê=÷Ìý÷«Hƒ¡ØLj[Ò÷”WÑ’Å´'šÄ|ßËÏMJ±ùïË”q«üë @HÏ!zèÛ‹Mo‘‘.#µaYÔ°ûâÅ‘sÕ_g©9ˆ–É\p=âYíkÇw¯&ØcóQ Ô%í¼û ;¦<äZËgÄW <›ü^¥2ˆ­¯T¾3}û(ìœ?Ñ!É÷fÁ!$¦ÀÛ“qVa²÷ s§®óÕ¡F ØWGÈ£&ölð—è®o§ã¯5?²õ+×lr¸Ý;W‘àsªûlüGp’æ…ãpE¿:y7è£å&øóÕéç®J×6—«!Éð›R9m¯°Õœ…ˆÓÚûÕUy;õ¶WX×0ee‹dµz1åÅÓè]œñŒŠÖÐjg›YX,Š$'õ¸Üõ”º\l©…kŠ m ¡¶†Ä'Õz[Ui±<$€R;ô‹8Æ›Z}=txóÛºQžXIªBECû5[ ¬o~ÀÞü1ã4a\Šƒø –U0¡^øŠ±" ¾å÷,c'²©“ )¿¨¦Œ”‘(<ñĶ´å ±3x1ÖsaÛiòk𿚼ÊL'Bý*C0óD­ø¦.˜Íò©Õxl.a€¨/WÒóœÜR«Ã^P`sã¼×L)Ÿ`éJŸP„ê$w×F˜O–>MAö»}k\½"K„;¯«®X¡È/"Sf°¤üc½œ¾Žò]íõ(:fÛÀ1Pή*Õ™á>¶º’énÔJ{¾@ôtxç&¶2º+)¦D/à÷/Õϳ¥––q#ÐOÁ½ÔlC§ˆ –0Š%oµõY§šÍ»XüRÞA†÷ž×|ó‡CÛ?¥ Ûf³Ï[ðx¢Ô%ô$%rÄäULïmTöËœÞRÏÍ«Íö«ByÈœÚ'N¡]ªR¢ laû6Òù ×VÄä rÜÆWE<9ÞQh—çrÙKS7&±¿ßF÷ô D”Gp鈓k.³ü8M4&h¸<½õ븰¬™Ÿ#ðn厤ú1ËçÑÎ_\嫌º¿ª¸¯_0£ÞÐ+•ÞÖ½Ò—nŸ¼—ËìíPÝfàr¨›ßnʱuZbN0„z;í,жÑŽr>ãjŠF¾ôà- ]š-ÍÏ.;š¿9bJÉø&XT¨1çet¯¹þ¡Bócj KÚìY˜m°¯‰¼R5Ü`Ðk‰gììsmº¤'A?Im½p¯…¢{ÿZR†ß}fld–ùz'¦éà)Cl Þ'ý0âÊk“H˜3n=þ£ºÃÞw6 )êqùwŸß Ny…ÈÈEÊåXeöÜž/ì•Býôd1‹ˆ¿«Ó~8¤ÉS/ K!®U´ŸrñºZàyL HMt]¸$ÑåC"Üœõ­Õ¯ B½Àðâ÷•-øJ*ÝdF†í@BÍf¾L+c_|«ðU@ âs$5UM蕌œõü¬QW aNI_Eð£mÑ“%à°+XÖ‚+çWT—rî8”µ/n™^Ïç*Êæäð€ÇXh¯—|d„_ˆ2pó’ßc!³…‰—[ÒzWóx)Úz†(û»8?˜çU]™¶,QÿÔÊlwËýéÊX¶è‘(FßoþdÀÚ‰ÚtòáÞåÝk ûÝêÐuÛTÉÙ>雺ÎOÃÚœ)þ&ˆÐÃG”­©*|A5—g>Ç6î§ù8†ª˜ íÛ¿˜G%š—S*!OJµ™Á[½1}Â4½^\Œ\ 1Ü#Iï hÚó>&Ã(+mîÜPÒ·äm—Yo™V‚$§HG$UDBÉÜOOÛ¹ËS;y NŽ£*I(ãmôÏÈ}ZŒü6únIêö[sŽÏÓUÝ‘ô–šßMê~öñz7ÙÖJO†€ ã§:îd¾çh4yoeç:@PKvö4ýÊДœ‡ uÃ~gNjƒÔzH`ÙŒAA¯LA\M‚2óXÏ‚dAÿˆy‡K.36µõ@Lý6bN›ý‚ÇÓqZß¿Q~~j>{òŠƒO‘ 7x'Ú•{–†Bõ  BŒ€1¨ÒúÝ® ¡ô]C?º@·Òäyuå#,Ó«ºÂãš#H7)Í{BzÉÿà™H°RÃö©/Q¿-.í’gkS´¨žOì¡èÀ«XaF-î§5þ‘á¸äŽç $„Áy3ë4nt@©‡}€b7–¦ëÛè·~UÊì¥ ûσÍ2a§Ã¡‘í–Ä~ö5t]ÖÄÛ-o›/äu-j‡Œ 7ÅgˆgŽŽþÖš}@ßYU^ò†ïP{%Ð>Ôùç{z•ÈLGv¦5ÑO!§º>Üm<¨gæûü©êÜÍaÓÎж3?´*duå>}Ð!ÜeœŠ®’>'ËQJ¸N—µFòOÊ'Ÿ°f¢L§k•gRyÀ—L*B|!xR  2ßo°ÑÇØ.÷¸A¶óaêÜiO6…òùpBlnÓ˜õŽ6ÃìT}š"ÕúÒ×"ÅdG£hdU§;Ø9‘¦Iÿ½¶Dh»—³ãhpþ¼û(ùñGÔ/=™¤ÛTzh:-ž7A#7dÌßÑÊ;îR1ß Ú´ît>i#•×Uìjùêâ¼°Úd¬Þžk:uš†H§à³ZZñÆ-ë»Ò¯<äaêºÛQLM ‹ r "Å>íº¿<¿p¦ªTžXÂß`ò³‹¤¨¡%©}½J7Áb\gw»£¥1ùEÆ_œCfÄ-K¨{´Eé<%êø‰RÑ¿”eâÉQÓÖÛógõ:z9^VʉÕ5ÙK¼}L:üÈòe&Ãûôä†ãOayY×61Ö§*G¦P¶ tƒ_,bs¼W"R6ÚÆN=ÎÌya™î7ÝiCÓ˜XÒÏ?¢M0Z%)-ˆØí ˆû/ºÆ¥klØuHËŠ4U 4à}Çm—¾<½§|­©åUÆAF/~­V”Èk¾IË¢Aå錭d9ÊÌöíÀfH!(É› R÷–U "Þ£C.gsKrÛ˜lÎøúÕBšöQé¨Á.«VœvÉ@®®Ôh°ch|©*¼ “ÅÉþÕÀjÍwR"ùÒÚ×ÉËdÄ€,Ê Pä{/1X¾Æ$÷^Ó,‘ÓàϘÑÂOø­­*#¯ÞNcMž‰Äv$PÈš.Zu"BIý‰Vo<¦÷ûÛÙëÙ½ËþW~­[À·È ãŸb‘iç}çªÄþû¯_ÏŠƒ»9ç?¢§éd}ßt¾þ"YÌ•è[òf‹bÆŽ?¥Ëå›Å Bä {ùó³ni„¯HKç½>Þ1à <³*Nô²È7NÇ„oÛÝ»ç‰HWðÞß¡M6úVÓjs¡«DÚÙûWˆúXkÍ>'?]ç‡=•lƒÖuJS­zbl’îÀ}Üüµým RÄ.¿Œ¥.£U%±Žý8úCŒD¯ŸŠXíZÀѬآÝz}=åw?zȬ÷ô{_ ‰Ôl«±F*vß[{-äõÄÁ“ýÏ5/m7ú .z÷X¶ Âp(åWñ f8Êš<Ä…0"7,ïäO“ÚWýGˆÞyÁ+G$’–ú¡%ò»]¸Š».Ñx°çhl†ܯ7ÏTf}¤{à‹b(ÜB7Øènõï1\`¥›ƒäùûŠââ_Ãõ…ÀhÑ’-Ó·xá@ëKÂ9WÏ(ÆPèÞ¨Ù÷û­3äÅã…oËÃHâF¯ËÙG¥[ýÝ>oó{êgd?Ö"†2r«‰l˜øD'Êæ­ß=ßùPIØ£-ùï+–lM«/ÚüôfLøðÅa([&Ô8—ͺŽ’8#ç•´M>3eøã…ˆé7¤âsWüɨ<ÓR Zì!Û·>|ÒË•^u+.*É›F9™ÞžPq'çue%m±>÷Åcï%=~\N›;ÏAYqE~ñD/Õy9)ÄA8³ °~ŸøêC98bŒ€æÔ-§ž“Wø¶(ÿ«CûÖY×­G7SdHãöÏìwòÖEÊ@«„ód9€Ë•{ÓwVIÊáÆ$žò¨´ãLÂ2ô‡“ ékR&jÕk)TƒëxeL-×ÔéÓK^emé8O„¯¸kX±]8Aê¬è3²—°Zu6‹³o(/îR…]Mgî½{Aã$Ÿi)Bcǵ›Ón4uSÐܯ>ë#ô—ëá¼ãÙki¶Â š¦K•”n4ƒCD²ëÐwâa‘-ŸÄ®£Ö,lXlýJØýSìAÂÈÖþÅ–wš¥6aU SWC¶»ªªIÒÿ™œ¹†Ú8ôæ#üw»réN„fŸï†5•cS:Ô'{RŠ Cðvê—·^¿)•ØD ²=¨F}*U˜CóoùB )^3S]òRƒÂ¥Û°oJSI£ü `¹-“«-2˜¥îj*OÃé:´Ÿ°çøÔd’ó†ûnûû0¨$9ûlˆ”°Ä¤ðß¿q9‘†N¨wEÛ´F«ðݱ¬y!ÝvÊŽ„8•ÿ"‘cÔ=gu¡§x[òæ;ôh…V,AÝa`¯‡/éI€ˆ+s<'/'dö,`3_g·Ëïq¹ïb‰ÄLÒ@á K›Ô÷®S˜ûúöœnHß/EôÞ¹°mú³¸^K&0F¸W£L2˜g“X¯²»¹.ÈL@Ù%± ë¾Y&Ф¬E=y[§@H–±Ù¡3øþ4–'Anð~æœÿrJ|‘M‚e.geQ䯥5Š®$ ö/N.â!™-ýÒ:éîOK¥š„5R…ÊœVqi›õN9ôç$7ýQwíÔiS4´^Ó_!O?{œ¢èŽè‹wN±rP9Õî¸Ëi õX#'è$+ïcÓM Ö¶=éA‡µBJ;#­ãOl«ñ…³Ôbé3ß»<‡×mòM¼À[ØÐ÷ðío¦8¸¹a†­y=©i"œwg-¹bÉù8ß9KÃ|ì£T'Ÿ€ßÞCÁQAYÊc—py†EŸ¦E[ÎŒ%—Â¥«Iv]¢¬v¾hL¶ÒÅmZçÖãÀ*bDj9]gêj Á(£ù5àŒ×)í±TÀCDÆKMl•lÄM.aŸ²¤»Uìㇵ^©HOÚ÷X2qÒçÉ?º?BÕa\º© |ô–†»‚y½ƒ ”è…¬ BÊx¿˜É~Ö’²Á¤b¾X0Ô¯T­®tYoèÚá »’)mRº“µâ³Ã‘î\ö5±>…œs’Aޥœ#*h@D;¡€my’PL¾âéѾt/¡ ¶Úq‘ˬá"—˜›Xš 1g:»{Ì£¨¢¡Mµ¿°ùfÌ"iä™Äò¼¡&gs»*a[P}œçÆóC»åÖ<’U¹Iƒ%?؉ՎqÛ!íûì{×rQ‡9œVvÛø9[MuÒ«>Ò„“¡Ãz¨½B¤#ä¼ XH=L ^5³¦B,ì ËÒ ;ÓùÌ›Dp¸ãr>|¹Ëâ€"(Ñ[’ºBÝbpÞöc¨ŠHv§Û_¤ÎÜj ɽ¿ħÛk4Èèî°¾åãºua®™Ñ­îù6¸§M¤¡£g“éý#T›ÞK0HWµÄhëùNø-Љ¶b¾¢,©¤ž3JO6{Ku[ªP4÷¾ ¶Iý3wñÓ¢i{ì°XÖ@œ1m‡/°UÕà²û‹fœSÝÜŸ\oiBÊ_ 0‘ÅÚQèzžé¡BYNW›Óÿ|Û0Ë,É>R°Ó l9a_€ È$(¢ÚGdwÃ"<”–ŠàÆtH4½ˆSßñ¯Eªð¶è8 šOì’‘©q2Ù>xŽ>Ý¡CÁ<âŒàu,“4ønAeJt›WkĆéŸÏ;•ˆ!rHSß//€6°… /ÔѺÜ<·H_YÂ…³É‚¦%S‚âÇ]n¥í¸½j¾ë÷÷ì7z/U+›”cVl–z»#Š´Ýo…w>®™jp£öÁ/»qÏm!\Y·¿Á­>ë”6}”F[«eN á/ñVçš¹+{23³N¹ÛW7GSû5ÊU4ºV¡Ðîø¬\þ9náCDôjݪ‘€?ô„>èþýà =.ç˺ [‡,.>¡ëKùÐΜ©‰É†Z`Ì‹\ä>>—6Õ—Çê >ÛÁ±»—‚û´É'ãþzV·G3ÃSn*’ öÌG¼Ëò•¤[ ¢rÂwݤV2Èöå®Y¼§ªÏ¯ˆÊQÊÁ»¸RƒÅ5Á¬§å¢]%ÁüGÚVb\f-r“ÉüT6­Ôt#È 8‚{Žåàx¢lp$ |gFSßö¥K!E¢NMhãu2]XX>.X¸»¤”Gc¢J—Äv§jwˆcSã…‘ðt»G4¶BI¿™rä=OÉî ]ž¤¬ýX…4Þ"™`‘O~Ný]À뤹‚¿²fyÓBô¥ˆÀõøùf¹Õ¾åj›x›là0[e­¯Ô{q 2íý}órD7‡RÔ%€¯¸y—ÜbÐ>{ÿ,éÛ¬îùûÃi|§m„ý_¢‡2×1S¼ OjEâä#dzNdüÂ2y,¡ RÈR!_rãä§+=x¤íâM,ºº4/Ó AŒ»Í.}ÏÕ€ŒÃ‘ ²Bîû¹kî!>dû¦zÖñ›o jñxŸŠK Kæ2^1щS•“ãsÂÜhcÅööìe«óWå <κU.0Fc ô¼=t8 ñ@{U›FÁ@èýÜÆ­uJ!ö„ž×‚'˜ûˆþ•üX^0¯fsD“0¦ljëôãâŠB2¸xòAÞòäçHo û ÜýDÚ©GNÛ-GœH5jè.ÄaPÛà–¸–Ý-³¼ŠUø;ùÈK¡ûºvV¬z‘ƒRë;Ô cèH 6‡çÇMö4…úàØðçH¼û \n.´8H$&´PS£;y=ÛÔžŠÄ„pÎù^$yçîÁü‚Çt!+¥7‘V%É`±1™‰å¨ÐÕ˜.Ìoñ½ÙNfÇÿ¦:©Nðþ©–0˜áú±.¯ó}>ÞùLp}3þ6Q ø•„ª‹+É5§2|#å”òCáXÏ´YGI*rÉ¡4_¬»»ø®8a°[„.ºTnvl†ÿÿT «ôr#¼pŸ;6ÐC³Rä+ï|¡ï2Ú$£©£tÚlv¤ ~œD§ íÎ Ž"aA B1#üŸlV,lžÖ]ã?&â—ø£P¢ßS1—cÙ”-ßHPvì(Õ3šÑí­ÿ4fØ% €©]¡7îI€¡°`Í ¾¢´óŒYýy¦QR¶.þè*ão³ òs6º‚ò·`îݾA ø£8€äá¤ÙÖéQY©¡òáÀ­«¾{åØL1Ÿp/OŽ”¾ˆê1·ÜŒF‚QŽàHKþê<&tþÙ6k»“—çE“¬G+«¿IQÈêtÝÜ.5ûÛØŽÄŒ·­KŒ‹ÆÃfÿfu$nû(P›Þ@}ød˜-ºO"#K?âXThú&DTe _– KB'ÑùÆÆ1°øÐ›â£úYÜ÷¨õ¡£HWä Ý»ÂßËYa½ûöá&xGøWÜwÿÚ­=ìéyî¿Ö}‘“ŽÕtVßÖ0Ž‹ÛPĘT”õ‚'8™€Y`Oɨ0‹þü8V×`lPLk½®+*Eº‘# þ?6¸ e¤(é@Ú¿!çsËGéïSFþør¿á$}õB¦kM~{Ë}ë3;qâAÁ ,ë¤I·Â¨@¤ƒÀ±³’e<™f`&e7²%g·ÒÙukàù†ÞŽSŒÌE’æ²²Ri {ÿÈý…[Qn~£0{Ö× «ÉÙmîŸ7³J&}³š·w»£'zîê ½í!sÚjó¡4)ð± pµÒ7…Û‡GÛXcé$Mä"ùÞlh™—1¨„|$pörPAœ˜ó0ttV…¶öÔ_>ÚÙ Ü üäxLÉET=PNf`†ž_2ʸªQé!0â…Üäöl[\S©Á%P´ø«©à4@'ÕOqÔUÓS¼)yʰ6?÷³ ì2Ò½œðö¡j ÄlÇ€±”I1 ë×Ú³ oLC£Ry^eöjµ ;"¯Õ"kfT,="² ^ÙJ8öÑg.-UšxKCÍ$™Æ0µ&‘Ùb'P·fL@ˆZ=ÖydGÂÁ;ˆj¿#œ+ù–7ÿ°`ƒDø>Xõ¹N xeÌeíIðIŠMéIªÿ1᤭¿‰Ý9Ë“q{|¯Ý‚íC«øËó~ý˜r"Áâ…R¡Ö©D)x*†=fFöT¯’æçÌ'$)h£V’«3@ð\9…‡Ùcl–c=U@©Ác† ÎëÓ|°Ðà† &ªóQÇæŽaÿÌù›¹–7 ÏÔ€gpîk‹ÊoÌ G'f]9Ú!;Ai]®¦O*Û9˜Ã¿‡ótZóðÝè"‚|Ó׈Tr¡ó òuØbÈÅ5hBSà ŴÔ'j›l[1’«"ýò¥©b‰6q~˜÷& z«[™­äoM¼cTצ {dŒë)`.œdä> YÇ©õVr<ï¯c=•Ë/ìÒx¦^ÞòðçÑÎ Yôþáṁ°*ìŒÎë`×NY8ØïŽ‹Lbú¥eiU\Ëý5ƒNÓA<¾ˆ_­0•Óx—Ô•æË~È/Ì„EVODl lO:/úüñM\õè²NÑØdÅ Ñ‘ý¤áÙ›:DKóÌ&Ä× ~yureŸÓuvEØ©_ ‹g…0ï¼ÍêX·ÆÐí^6&.’Ç€|tGA3Ю}d¬žÿûÓSÄ9ñA²Ø¨ÚᓾG´B¨$èú´A …bÆ71VýòÐ(^Vˆ¨xiÏ8”ÈûÇ¢Žwª¾õ[`VåX½b\¯ –ÇíFÌT¸^}š9˜ÎéçÇ È8&@í¢ ï«:’¢J³žPbŠ@TÕé ‚¥é¯CìÓ°­ìítíøîÀˆiè —‰Þ¼pYõ Ÿ¢N±b­v‰‰×þVü»¿Ý]ÿb»,!•}3¯~°[ïq@±LÍ8„Å  dhr:l³8¹ÎHjkˆy0 ÿÞ«ã~¥龡 ­º |‚…¢ÀÐÕRå&ƒ èJ2ò˜-²ó¡¬{ Ñû%n¥›ƒS¬xì‚o6 ò=@ßéq…)©¡Oà#©BZ_†Ÿ‡ïÑ!œsÞäPüúuI= ë/bXJ’î2#ÃIÍÁ ­–ú9sUΊ2´JÕƒLŸh3¶Áží”ÛÈCêZâòS0èè ²sÛ’@íÓÍ®+Õä@!@@ýw/™­} &A„ñ¬Áªæö;`‹èdø”ÿæ?¡LBËor;^mOÛ»]• èXp„´KÒ£R!º¶í{çã(w1·…Â=wýr it'!€ž™LêF¤{A£CFÿ¢#(½[l¿¬nøwêÄr¡*ë¤è!Y †:u'èJ¶á^Ù(BïÝOΦ\}Êï<ÇN=á&Ò ó†„tŠ¥JÐbè%|g!xÕ~uç-‰Æ,2Í3‡óñ€^ I|ºÚ”d˜Ø:œ¿C \ÁW›/܇»ï‹]å3=Ø´NÂÛÜ‚AÕ ñ&ùF”¥€²™@ÛW8]]rª‚°‘¼š^Ƥ#ÜœÒ% ømÍ£# {Ï,çY¶78DêœrÓí=yê‡;µ‡eYR”RY'¸ ôGÝ9…é*ødÈ¥F‹Ñó‹Â}/döËlÄÅ|ûi©wœ¿±%3©+äÖp]) "ºÜfÂárÄkíÌŽäÎ è)Bªñ çÊîç×WXj©5aÀ½Ú?_ϹÆ7cp´wÚ_FDvŸ±mUúÔRåGhšÆ".çö¶ï endstream endobj 106 0 obj << /Length1 1446 /Length2 2046 /Length3 0 /Length 2976 /Filter /FlateDecode >> stream xÚT 8TmNRL(mB>‡ìËlŒ-Ê"²DåScæŒ95ÎŒ33†PÙ¢*JÖ"Ÿ¾”µBeù*êSdùB Ê’lùcZþ3hýÿëúÿë\×9çyžûyÞçyßû~U]uÌ©LІ stX¼1`éèæF x¼.'bTTÜ üêǨì6Ä„@X" ™ƒú¬ÈèÈ„{. è}c‚1ñx£¯@&b X‘ *àˆì™0ÈÆ¨X2YAäKç ë|ýÔ)ÁÈÈ@{.0÷ˆB†G2‡ú¡+RÈ À•I@NÐO%ÔMèˇãñxX²ËD|7kh<ˆC\@6ˆ€T@02°ì.Œ†Å¨ntˆ=peÒ8<2¨ƒQ@˜¦pa*ˆèꀫàÄáy°Ã<@XØ€€%|+·-(ÁsÉd …éÇ"ÃAì Ð 8Ù8`9m€ S@2ƒÍDóÉdˆAöAs­“ópa>6X6– 13âeÐm¶†©–L??æ°1‚þ¬ ¤ û„[8Ü0“µhL¥ Æ rY8wòç‚vV Ô…ùîó9 Çêê ?Rè8ÁnA,p.H¸ÑBƒYL@CÇC!ˆ~0Álrp.ücàg C TˆÂ|@_Æ|¯ŽºAÚ¼ž?{ð(ý^ð|ûûe• 3‚¾Ã玷ÃÉÝÁÒRkaäoA f ¬Ctˆºz‰¨è‘€ÐŸ«8“¡….ðß3í`0šoÝ¥¯ ,0@}AÀϵ¶3QÞ‚€úwš{áIx ú"üßdŸKùoTùŸ4ÿµ#.ƒ1WŸüGœì1‚(o¹TŽLT ð¯Pp^¸Ž âúýµãQ-˜Ã¾Œo ±m @ê q(ô9nÌ»Ý:c@0èÌdC‚›Ð!àñ¿ÄPqQ ·¥ä\DµóóŠÖ0…IˆŒHÒÈBÂàQ&I$ ˜€ª‘ ΑÀaa&MÐéBÁŽ”Dp4&xç¼€£ÿ`8Æwå.Žùƒ‰¦³¾›D44gþÔ$…‹ ¨Rçx„NðÕž»@0¤`žµ2)›"÷GÞùPh.ÇÓék êIÔŽç‹zôZËôï·4™×ÍŽm7¯þçMìô«UCÄË_Jx®Ãðî 9k¼îÙõ;"4ŸíÆU¦3Cl.ñͶªªÝûtaªïºÑ2—‡<¾Y‹†´¶ÿû¾§i[MTËò§®ÑG—©ÝÆŠ/n8»l½¡¡®øâÈ ó´Š|‹"ó–*í”Ùcf #gäm¦Ï×<"’ºkŸ_Ñ‚^Ÿ—”`mã§ nN~{W_vÛ¾F E¥÷®õúÙõpþÈ0uöcç„=YšÛXéP×I)2 ))îµ}’w•ØÓ¼…ïæ2l©é»çTvÅs Ñü[Ýñ¦h‚³ú“]:Ö1‡,|óë's¶lÜÅ6»`ìYõ^í·†Ö6÷Fu ÝPBØjÒ—§…(ûô{þ»¬B‘˜¯ÇfÚCf.²ÌÒí·–Üì©[1Ž*elblcuÝë ³êÍÝ">»’ñ´Q…xÏ©¬¬—q»5 ‡ÿð¼îÕ2e"uŒ=`Ó§×—ÊBÉZa0/Ìͳ(«é.ã…íGÕ6ëë62Ÿ£l¨>«3µ“³^l ô¯=71cŸ-µ`x†o'jélíUºi²6:Æénº–UÓ}!ÌKáAŸyMÒáÑs²§U¦ß¦©v;.Õ¼©°H¶)µ¼7x÷¢Ê9öšOáÕ·L5?PÓúp¸Žá&ŠjUéµWFÛߌ˜Y?*Èf…µ¹d&ÚU„Ç¿­0ϽQ¬V?Tç‘h¯TÌî,xI¾)“i¦·c#Ûª/iЮø^¥#Õòì}ÿì–¿b…¬Lmw—G…¹ô̬RHíXR:x|QqÎ_W…¥6áÚ‡V»LR‹«zq˜¤’èÁqBôG)/ɸ(\ÿ,[-6þᆃg†3ïÝÞó\_f`‰Çâ£f‰{Û÷×…$ööm¯‰+-½D¢dåÓÖºçÉa¸ë…Ì ¹´¼8¿O§:n“x?]y…ä‰/g2¶ÉR@š}ö¤t„¼°ØÇ¥µ ž"ÔÉr §x Ì š“óûÍÇlƒiÞfS…CÔ°Û÷†‚"›¯:<9[þà-qQäçXGåŽ^Q› Æ”yø‡FÕ‡³Çê»›ÖÌZü^g]$~ùɱ¨ ›#ú«XzZ¹më¤N=w°X¢éžÐ:õ¥¿.ìix¶¯ºìókÒ„q‚½ lI¶¾7¼YN—šRÏ=Úú!XZ®N¾³òbز“£RÉ—™„¡¼¥¥öbÑM]£Îí}Ĩ/íâS¹iÞ܈¥†Î>%¼$a]*èžûöx\ˆ WŠOЩå·ó¿6ÂtŽ’;,휢»F%:ºðp¹¯$7ù">x·íO­ÉvÓAi½otQm÷ÌaÄGSÇ!WòñJý@ico~àߤ‡ã7¼qµ¦N»Ìtƒ3í1#2Ç~ÓÓ¾:V:8aø®”°XaøIDTbžðÉÃ_†Ç TBäS¬šµƒøúÕ§¶í½MË*Çb$¼lM:yÄäà5k ït)¡Ä¶<Ë3I±¨¹ª§;⥛ztöcgš_jTí$Ƭr«¾Í!öF3Kj£òÏž’Ë¡ÜÏØp9¹´‘tÇ_D¤.î°ø›ŒQÃ[1]®õ¼³>¦Øàí}0+佋¼P^ð£eŠA£yëk©~v"5Ó7–^¦d!íÕ!óÐïo•ò‰i2öåÚI…²—g¬· ¯“dÌøý3aPÒzkêCΑM-[J‰SCøæúwF©ž[¢…ßÿÝ¿tôYò‡Â”=%÷šG¤vOQ,íÇ.‡JŸ¯¹eºRÛŸ¶òY"I• `Ã¥»ÕĪâ²ßŽèµ^•VQP|Oè¼ Îq»_¨÷QcçŸWÆ% åm|MZƒ‡Vˆ.øØÁj¢+ÿö‹Ðº +?åv6³&zCÿàeÚÏf^Ÿ5QÀY«ælLETºˆ3û9í%Êoe¬ûh¼P«­µxºÕË=ìŒç™ñ~?\àmËΓ­¿ïJ/žé¤µi ËVt5cÌo½zØYað¡l$¢„8²¬H\Ö?E³K’:á¸(”.~C¾Rïyµü”˱¥ãÇÿ VïæH endstream endobj 108 0 obj << /Length1 1844 /Length2 5677 /Length3 0 /Length 6803 /Filter /FlateDecode >> stream xÚu 4ÔïÛ¾=¡)>‰mc'Ë û¾„bÌ Fc†™1ö,¡µY#{$dßÉVÙ×D²%ûNï´ü¾õýýÿç¼ï™sÌ\÷z]ÏsßÞ‹ÆÂʬR‹!ƒE@²€ª®‰‰4‰‹€@bt¼¼&(ùÛLÇk†ÄáQXŒì_ª8$Œ@²AaRœ.h¹¡°8–”KÉ‚@€$óŸ@,N€Âˆ( +ha1H<¯*ÖŇrp$Úüç'ÀÀ22RB?Óeg$‡a]ÁéLꇡc,…$xþ«¿¼#à"+*êîî.sÆ‹`qŠB€;Šà!ñH‰~ô`ÎÈ_ÊDèxGþ—ÝkOp‡áÉ€FÁ‘<)à ƒ@âRsÀXSÐwAb~ëü ~Ÿ ÿSîwöB(ÌÏdŽuvaÒ^Áo‘Þ “Œ ûƒdQø?"MBX4IÒ,?”‰"þ‚`@ù'^’„~žêŸRkû¿ 8 êð$Qqü BQÔ_DíÖ_Äý$QuþÁ$bñ$í¥(ö/H¢áò” ñt!M,ö/%`Ü_Dÿ'Ćáÿâ &Õø£“t«¢÷¿’2Üþ+©ÚϧÇâE‘$ÿ‚$Iî Iƒç¤X/$îWÜ ‡#=?w›4WÿÁ?ßi$Ò §ÂÂå‚œŠƒjöŠ”9Ü…g»Ä$N´n„mњϨ±?ªÊÝÏQn˜ ÿ:yjQ,ç¨ü–+èÖÍ> Წ£¥5ÔövÓB>=§öñ:nbsÚõõ–¶â„ëj…Q»û–R¿ÀY!×õÙÁ¤/ò—+ w Wñ•-‰0PtE„c“–g ªUNª-Ty©Ü?P§ÉƒßPêZ~pAýËׄ×oÄ S­ïó„ÈQŸ8N¸ho%-(ÆÏ7IžÓ¶íúygšÔØ¢ù·j‚øíðo b)¾ž¢ .™2×®aâ2áiCÛ^0Î½è‹ K|~ì–¦i܇{QAs=Ñ;=¸Ø—ï%vsji]×ÍÙ”*%o#ôÓ"_ÊÒðQÙ9zÎChÄ©"FߊM¬ws)‡ oi¾æ=V²öœâå©T]ÕéÐÂIÐp,Ñ:6q|rF#6Ôúïñ‘0KkÁ(¹e)Bbx'ì£ó}-¼Å®ÿýR8Åüõ”áYáàæ@ë«~PLÔñÄ꣸ Ôò pUc­F>œJž€É?'ôÂÇñ¸%4Yôi{˜ù@5w7²ˆXµþš9;›È9úsjM ³dÓóåÔÓúrtwÉ…¾Û>«ƒrµ˜<Ìê ´aO‚è#;Ùà|u…‹Qv²¯å¾,ö_S ¦·é€±>ª´¨|‘Òk¤ä‰¢´Ï£ÌÓ)ˆ9_æH˜ãïLK}`T¯½›¶Ð»Ý®ÛpÒ›µylte?w¸[p²HØ.º—Í>¬`ª=Ñn¿x¯rÙàÛtó Tø¤(³Óæ™®o¶õ’’øzðÐ2¡8ûj׈í²wp’"hLÏõÎ󷌣ä-K¼…Q„ió»„Ù–B‹IÃmëôárSví‹ÕÛÛ—u*V|õ’†ŠÙ64úP<‹e­JåñÖÑ’®4Ûçí»1 P½äU»­~k¨”sm¯ƒfˆ¼ë0h× u]»ÕÕ*òî0`@Ü˰Ã1ö Ü~×6Ð: öЬ‘ \Sd`œ­ª³>x-óÀÚíª hýY0Ö”+¬Vùåj¸Auy²í»RîÁ= ž®ºXçLh(¼Êµ‹IÛÈÇð„ü¨^ÆÎÕ Nçœ^{'&ÉãF7¹ÖÆjÈT zHOpõ²„ÍmÌ+_jJ£4•(þNlûõê« üiûÓËßl„>Ÿ)G®”?¼”U¥L {5åq×u …KËg¥C¨{`›ØíŠŽŠ+BŽÏß=£k Þ»|W ›J²µŸcˆ×‡jÚërÅŒQDÊ5¸9ùn‚tÀ@l®gâ¥W,F‚怤©òìç›l~ÕÆUÍ’õ;Vó« /ä?òœŒáŒŽ¹#Ð¥Éäf‹‡,€:ħWÞ8x¹#韆ÞTs&Òx\„æUß…´7½¾y(Öárƒ†¨ï¿9~²ˆc!ÝJ€õ‰ #.;Ï(¼è!o2\ûé÷JÉþšíŠ ó~„{&п8@Ø7ÌOb:ze¿žn8IK“­P=ö6¸1'©÷ëº`s§û<äF :*(û©üÛg†1ž;Î@ÛÐÊ®p1Ë<é1•y‰ë_•ëNýú™_ûÌÚÄ•–ÑG:£zÛU7ÇKš|b"6€z9~‘®†þk‰ÆQyë·V û’f^E9ó©Ä–k@Ô«®ÍLʨ|Sª‰OS Èp½à„Ü¡]㸱`’û¾Ê¼)a"êæ— îíe*'›¬AX!eÎôCKËK^n™˜cO£\ Ê{>ÖÓ¿Œ·œ_©b<ñ¡çÞ€–¯Æ‚z õÁÕoTçüŠˆM9þ¬m>V#èï'ŒÆ"ФÞC3¾åG ·m ( ž•ù¾âC¹—®_Lõþ X“]Êr"ŸÕ¡s·émbÆ:«š/D—Ô0‹È…u%¹U»MqnGø§°DQTô´Hu¢¹5Ó«©ÈÁ Tæ­J…gæ+—wz:yú“Ô¥„ñ]WÖ”ªë6ôÇò(R7—ÏYí‰mf)ž\Ó½š¬ÍÖa5ôè2„öå#‹Â‰¨¶À¥ …¬x‡ Óö¢Š¨³iZ´1ÉiÁ#ë¯njĎÑ[éYŠô:ð×–¸0ÑaÈ?{y«†0ÝL¿H¥yôù•‡KÃÜ>Îlø!|¸zà“j·:šÊ¥X’LítÂh*¨9ú¸ü¥MúÓ[„Õ§óóšéCV—'ç@ÉA›Âï°õ¼JO§ŒÜ®“¹\T΃Ö` ÓØ­¹n]K Ó¹],éU°<¢t—ó¢nSͪ¸ð†dWM0-ýS©ýÆàwJ+ßNßmŸ#ÞG¹\(©QlB¾Cª²ó_¾ËÆEí¡ŽìEò÷Ep·¯¦œº\ÂÉà €9‚*ìChµ>qßoûâq†¿kð9“{’"O¥íB („¦A”õFÈ÷“yÙÆc É…Y”Ý7Î.:n6+|®í4 1>ÎÒU šLGŸÚ-¢êø61ÍëÔU’ø] mѼ˜­fƒCæ"R~J=J»bËÛãzB/ˆÍë®·¡û+ã º ”ç«B+º^‹½\doP±è¢À†“ º“÷ð 熈[~ðõ¨›íç‰aÕõãüUû«wéÒêŽ Öe®_ì²uŽf¸­ùúÂ(ZD#¦vF’°~ñ¡ý½¡ìÁWÙmˆ©œr¼ø£­ Ê)N6ýg¤ß~ÉÈJPo}·ŒQ ªít¬5év¼ƒÝ–wXÝ*)ìÕ‰|bè_{Z ”qþc}hehÁ5e­Ÿb ã Ûd«>èÕÆôŒÉCS´µ¹â`†òé—¡iûÂj1e;›g ß¿æâøAq‰L쉖R—­ï¶¾EÂá}Š®Þ%Õ§lº.Èû%bU3Š‚«/iŸwÂfNømjд/ ¬…ОÞYZi1ȸ²êgá²a`lÕ>¾ùÁÅøöp­=§ÄÔñ6E4áۉϡ<¤¹ua/òÝ=2¾!‰¾¯z¬š½ÏCX„ЗYÙ;)§ÖWf¥Ó+©,øÝ­,²¶ûÝôwŒÇU ¾cùíÒçâ™iF¨ ä •³:‹0ýÂ!_orsÍtº:¾?(†Ÿæy}ë—ëQæXùSäz@låóJÃ\~úá²Ò g0èSEÜ„¬ã²ïÝF{NÚ¥ÁÆKaWýžx1.7]]Ôàð9¦‹4Ö×3v3º»i¾Ÿ¥Í°C7ýDøÜR’lj¤qu[¡òyÖ[ß ïô©üõ!ºÑäí÷ásÞiU~_›ÏÅÅ ê3ﵚM>+¾äa¾¹rÄkíkaK箑;)}Ùà «h®ô¥óz¶.ˆò]»öÙ™fÈtGÈsÿ7ŒžÑ_zåuò.¼T›b­‰'k:ûÀY¹6aoCa0ï0²-!®qì#Ô²Žp¶h¿ ×'!«äÛg˶+»6')ÇøÙY$ kóøãEØÙÌž½P?ßÛ²Mœ a?ºÏ$Ó½Žû>Õo&ƒ‡š}ñ¿×XÛ$lWãa¥ôˆ±X×ë_åž‹ùÆÓA3Ý‹#a¸šbû‰ÕÛ„âÅ’=c]{cND¨d¾ËèŽí™àÍšÌ-^Õˆ.ç[£t<(ôZS\ßNÙ5îY¢^Ÿ…ÑIeºó+ƒÃ³&.D½7»|WÐ)"3Ó—É3€·U×Ó|ò^Ù]“ãÖÓUÑÀ =ö{Ü»ï^:ÌUðœœg=L¨‘®ºc=B,ž4”ô ¸'ò¬Õ »"t’9j³i—;_¢®s×ò\/ô…Ú|U3§jÏÒ‰Ëá–Df!SørŠÂí7ø+rŸÛÕ _ê;ÂÄ·ÞMô² ›çl·w¦ÃVÏkbjXk¿v<£Ì„ ÜqJš+é˜ÛËçØ®Ö²ÊëÈë6Ø5íôî;Üÿ m™±¤µÇˆ¦’™Õ9:³¤Ø\_r¸CàQimëg°mÐÞ¾GWŠJMüªý(Î47©K¯Áì;[¸^¬û¸”怲Ô…\´ëJÃ>_ü7_*Íý[óîÞâL&/f&ÅòyÊAH{m¨OPa\:Ù®óùvO9yçwÌ…¯*’ ”9±Í-“ïì1+]Ç^&WÇä´ŸÒ|пY©Iö­Öš®™‚îR;®­Ù9¿5ŠÈåÏô". ø›[gï½;Ìñ†íÛíuíZD•ë¹Y¾•„ÙÛ&Ê&ÅÍ‘ƒŸS=±=) ŠpÒÌèkF[ºø_z¨1âÅ*{mùꇪ%‹Î%šDm{ª ñ©âžd¾¥/ŸÁFs<é½ÌTún—.ÆZs 6œzzºDbMÜ;¾/°nŒ®z%i¯Ð_ãXƒ`ϵ%BˆÓ4¤Ò·–64Óõ¦%º^¤0¿ ÷š¿ž*jõä´¿b ²W‡¤‹îiü&íõ0¢ìð¸zSúu¿îöñµQ)°'¯»#êŽ Ã !½-J”¬ËåNøÄ¼¬”Ì£˜2žúnyÅ›œ,º-V$Í™kú¡9uùÞUò=׵׋F©ֳ–òBúY‡ƒGBŒ‹úM©ƒ÷¬ ÄUbÌêònÜ™,-yqbÖªÇUv ð_ÌzÈŒyÃ|ÇZŽâ´ÐÛdÞm¥‰<_ïü}¥”…/Ãd+p‡;d[Û#kK 'ð•^ÌÐUã!ñSËЄHžð­{v®ˆ€j& L7}þ"—ÿ“1ñTf·©Ë£Áçr)ãg#àZÁª/ÛúíÑ»®G¶ô÷â-¡±‡y¦L[*ûkÕŸI^ ÁúvDŸnÁCÕ¯±œò®‰·Žê(·Vʺ5˜ÃÞíÁ•-Ä%3Ÿ¹Qñáæ.¡H?ê­_põXd8*,ÈÚ2¶å<}ñh;‡±†Î$k³Nù©N©Ç8×§!y÷ò+S†VÖA<-{‘˜E9&Fқ윬ˆ>é¦|‰ÜRp)§jcpÉÜ%Ý3qOé_HL& >J ž¨åxm¡Dí¼•Êcîª~eû\ýµo=éïZÞXwÏ ø4ÃÇr2TÏ ÐÚ†zçÑD+ SÃEÛLŸ>»OQú Tã8ÅÜï!Cn²Qz]ûläù¾øp uåKðM=šÏÝÖß2„”(Co?E"5Ž[$Ü.ÄØyPñlÙ^X;o}£‡!ñغÄñŽ¡µý5Ò¿Wúùj†™óÖÕZñA7AÏͪ{ý²`Ðæg¶„¬Kw9*áwš,µ?ù‹Äú–=çN¬R1ߊ±‹gjLŠÏo¥N­ìŽ’«éîáˆ`©%?€qʾ1£D³'¦äÒ0¾Ì÷1§={ÚÞ÷ÝÚÚÒ×™³Ä7”Í´“©x¾uhXlH›eñQóBÙ}­:å×|O0ÅjÜÊI9?LeÏõ6ûh2þ1Ë}¾…ë¹?|Þßú|ßiŸY†ÿ»ë”’«9·à ÿSSÃê>©% ˜à1“Þž§+$šî|ÃΆ¹Á;ÕAëÛã8—µ·6¦lk|Jçï]jR½!L­š·d_²ªÒb iÓCȥѮµœûý,nÒ+}ÅérèÖ€2Œk8|ú”¸<“p{š÷rNˆUÄúÜÄÑHkyñ@æúê:ñŒ±ÜádCTÖMQK‹Í]³‹Ùúê×èñ\þ9]g`-ã}o>€+õéăý«Ì¦GÚ½…ø)vÙ0Ý«ªöä é›)…"b›¯EÞ <±|âÃÇeÊÅkÿqö•¢9ºªFîN*‘¾¸ø‚'žœnަ2àÔ€*¤mô 5-ªÈ–¸* -$Èßã`m¨µjöF½g{@ö㦠Ќɞn»“¹õËq¹^iï¯ò·™T±Z³™•ó„Íœã¿Íûy¦uá­è©”©¼^¢ïæÉŸß_› ® ¯+2{ŸÑ’ýŠrÖ¹Nj‡?Á/}Iz·Ú¿D›Ï…ЦÊ0À 9éñ K–YªŽ°lu.ØœWãƒ÷rÚA|“mQuÔÝM!—Ÿ¦ÄF# a+qÃÖîæ‡‹a’â¶óÐéæÛd}N®[„åó5ú¥RÚþ«ª=Y„÷É6öDZ)}ŸÉl=ÓÎ7¿'¯Ô©SßÚ~®ÂZ܃m¼“Š™£g¡y¨nñQÙ{"Ú‘E®ÓjøÄ¬€[$»¼y©Ã߽߽ÃBÛZühØÛ^<ó"g¹mhyE¹àÅÙ4à (á¾}í)Ö)LµÑDcn®xL§EùÃ'“9fklŽf;&Y¦+Ђ¯›6¯¹6ó}™²HŽê‘&^†»†Ñ6²—Ú¥œ+›×@póPBš–Ì1.þÉý."§k f p»n±s¥õÞh•†Þ=1bmë‡ù©÷¨cU]ìÆ­å—V¯_‘²êžäšÕí‡è6wƒ›)ÅV¯œü|úˆ‰—q²”b%Œ·år«Ušsr–šy¶e—3*UƒKhŽ-id^(´üx0ƒ}‡¦UëzßÄSe¹JåB;£ßÆœ{ þºq d&‚7…º £Ÿ2õ…¼õÀx:Õ”/Ó>‡i#Ù ÐÚÄ…MDTju„‹#ÛÂáÑcîi|wduõúºïôjÊþaÇ®¼G|ÛiÁé«;«!æÓ¡¥1§’Ü/æ ·®Ä—NŒž×ãÉ7°Q[I¤=3+Õ}ö‹)¸Ø yÓèòÕÀƒóÂÔØ°zÊ;ôZ Þñ„Š$7é…ñ‹Vç¢ßqÛØq4ŽÅBK²·’Šüä_²ZÁÈ,G;꜎B[2•6_¨4yŽÛåo½—nü(Ñ<0ñÖ>ë6¼–þ»iXT·ÎÜҘë\'ÔÁœúÃÓä´ú:é Ñ»¬ëË«ýgÍ|?Á‚ÛZs7|† @š,]{2¹Ø°ÉåkUTz.±·Фi¦K4ç«<{y½ýx€7óÜl·OýÂûO‘®_a˳«ÄM=+U%Ü€:½À’Â×UDxí½ÃAØÿC‘‚E endstream endobj 112 0 obj << /Producer (pdfTeX-1.40.17) /Creator (TeX) /CreationDate (D:20170421171545-04'00') /ModDate (D:20170421171545-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016/Debian) kpathsea version 6.2.2) >> endobj 12 0 obj << /Type /ObjStm /N 80 /First 655 /Length 3559 /Filter /FlateDecode >> stream xÚí[Yo9~ׯèÇ],âæ}Á±3Îä>ì$N‚<(vÇÖŒm9’œc~ýÖA©ÙÝjÛ’`Ql²XÇWUd±©B²ˆÐØB)YHSh©  #U!Ca…)”.œÐ0_¸d®ð^ÊÁéŠET¾P¡ViX$‚&…”ÞÚRYYh[Hm`<‚- ô ·1€´Bº(è|€gƒ( ÐEç "„°R˜Yê€\ úh¡ ‹ZFS8PÓ‘S §Ñó„8ªÁz`¥½ô… ð­á  —QƒaÆT³,Õ…‰ Ÿ7 ˆ˜äõXsï4À7øô± ` Ю(Bù@0d¾ˆ4°mìŽ:(` @U¢¬‰€™T°†žEo;¤ ¾@¯DDÜ=bÔ>*H=ô4°-`F+ØAG[WXœ1A@©¬? `=|0ÐâDs,¬5(Ùat(¥G4€#qÄxT:Ì]ŒÇ8Á€Î=MÁ2i¸Áˆ•H€«¬Òh‰Ä^”ƒ»wåþ‹ª(_ «A¹3>ŸUç³i¡!N_ ÊWÕt|99¬¦´4ð´: ·Çß‹Ĭêã–O`ŠG²ß~#λÀ­¸{·(w!Ú Î`µN]„»Z~Þo¦n¸Ò ¢œúm¡>È)_LƇ{Õ¬ø6Üß-Êýêû¬ø8Wa©qÒu¬3™wž û@–ô›¨¯DGýð3Ô§ðí¨¿1úÊ´Õ‡ÞDý>¥çf­«§ïèioMÏ uÓPá£[gïÐ7Û<´Y/<×Õ³ã_m‚ž·™:¦ãv6Ry™ÛoCÏNùôÌNŠ[E¹s<³™öÙá¶ðMcÙÄŽÊþgƦzZÕÖÓŠéiõJ1|]5;`ÍFj^»5x¬û:Q qlC§l€~Äz1ù/ óñ€UㆻÎÙìÔF†çZ× äv-äjõ?X-· Ðv ® Y?(­Šv k©·TjM6«­qîóì&-óÉ[–e…Üò©å³pu± h¼ó¨³”ØWj ®8QãZ­·l¢ÔÇ­±0Ú蜆‘èÕVL4‰3qHý qU KIr©…ëŠl 8FäuKFc¸x ´Y_+ƒæf4 lwd%xØuD“Ó3‘†nÌgÉ ó øÕþË[ð¤£ÈZSÞc´P멵Bd=«&ÞLi(É<Žê1ã &“SŸä1- õ!™(æ]”LcRPÚ9EûÎyKt…Á`¤°AÃx4†¶ÔÀ/G «C=òV !¸1Òa6ÀWq“ÒÄQ àbœÅñ€šÇ‚ÃÌ2¨³l˜ÎA”ìAW!¶惋¨EÝâ\Y~}~êPö×ĪÏf®n)@lúÜ`ן´  ¢Ú¤e>yë]›3xƒ à!i ᤥT±…óÓÅ*ÒO*¦Ó)2ï0$ª*BÌ8W^Ÿ$@rÀ!áðhI˜’Ú‘O>‚IªH`bæ¨ä6ñˆº ?õÏÖcùUµ’Kzå¸?…g½”øš(ô|µs¨“qˆ˜!<ˆîWšþ‹SŸKqÁ-Vo:µ¼%hA³Yf/2Ž/CG=)ŠôŶ…¢-ARŠe{ŒZ°˜º—Så§O½¤¹L½eŠõ}TG æÊõ·i{“YP2³Yö|Þ¦í!à‰tÚqÕv:8Ò9I|xŒÖ&îT2žø[†S µoE**jCÛ½ b–¼‘õ3ïÑhçªæ‘\a›ÔL¡#î :?vH6ËpŸÛ:&ð@À IÓ¦Im´ˆ*·Zâ©­Dro;Ÿàh åM*Ò–«Å@ª …u“’(y|Îà£dYHͽœÊäÊ-IÌ9Prp™v}Ÿ´z¡EÒ–ê9ny„­ 2Ð¥‰ì‚‹V…tQxÑ‹XwqÌÐÊ(1GnÁë|!I  Å’Q¦~€]Þ&àRPв`)É•I j=áÅš»¬ß¶ÊÚ¹7Ù7©Η™7y4÷±ƒ£h>¾H+ÔLaèè5–ZòM>ËXqŸZŒ0È8Ê:í·æ­–h¼Ä=w¶·ÅjÚrØ{¼»Zü|61,‘¥4:ÏyÓõ6È$‘©¹_Sz6EÆaÑ»ZÛ´‰c¦Yw•Z|f[}Œ˜ôl'¬ÖtëÀ ,ƒ0<ñTÅãÛüûdÀÛ«ó–n]Ͳ=R]dS?h¼ú¢;<\'0¸ ÑEÂЩÔåÖ…ÚW('G#·Èò·b?Ñ7L™q´áõˆ-°WhÝ‚–çE= ¬ÉKõ#Ä}j!ÖŒ¶¸gЇñòN.n=! ŸW^Ñ'ÍK—õj Mør›x×süêgÁc“v® ~’ÞNQa‡-xmèeÎ<¼¡Ì9ÊDv¶&*méf)4­Tt`A\Ñ^óÌW&Þtÿ³fÁ©ðϽB¸Åƒ¥ëamp³W?!vGÝS1nåó´‚Æ,ÉžzZ± â¹¹èÒJýzŽÔÅšIb4ÿjÿÁ-&©¥W¶ÊÄVëe¤M€·mE/fp“ï…¸-:Øû0ñ¶¢W5‚Þ‡*|UÔZyz"<!á±$¡ùÄ•V§~À×'Vâk!–dRé¥O>b¬unM×2aÎFÐ{ݬ¯<¾BÍiÒZ§z!a㕹´6çI4øF>ì ¾«_Óã õûÕôp2º˜'ü‚ýÙð fî¿{ûþÍ»ÿí<Ý>&N‡ÇÓÂ0Å6½¯¿c]qGai,Á¢øã ¼7=Ä·ö.åÎðâjt|Á Jƒsw$N>œ OG‡÷ÎO«Øïͪ³7xŒʃ´jUàq2œà»úÿ”÷ÊûåïåÃòE¹Wî—¯Ëaù©<,ʪ$òòsùyÿ¾Våçñå¤<.OÊ“'Õy9*ÿ*O˳ò¼<Wå¸C{Q^T“Ñø¨œ”ÓrZ}ºéè{9=NOÊY9;™TU9û6./˯å·ò{ù£ü»šŒÿËìŽ@í ò?M\‡çÁ˃ííÆSõà©Oü¯A:Þž"^çv¹s¦?јj0_¿98xû€ùp¿':¥0ñoXÒ6º K)XâãK¥TË;’Œ¦ËÁÔ² æ“ò)@ÈŽOÇç ã÷ÃÓáÆfÁ?k /Ï>U“éèø|ä—Ëj:“/—ã ŠÎ@XgÞåùPŽ'á¸$.Í*P¾{¶ûè÷×åÓ‡}y®UÊsaÂ5q©¯ŠË K¯z±|ø ËãI5Û "ެ†‘n#?zühgŒ|Õg£sEÜÄFq£h™§Þnù¤ÆÎ³ò9¤á«”ˆoËwKŸ&ÃÿªÙiõy6ïs0̃Œ¡ª3¶:;Ât«¾\O³è»jsü³™ÌK¢ñÿK:P5HÉ~qz9-¿´öèÓ)‘ÏxE+–§ÕÙˆ¸áöÛ ô°J <}°¿·ý–b gÿ…ò–ößÂí„€½&vÁñ/ÀÑÃ3@s:®aÓJ{õóçû^¢M¡'çe§ðâvlr½6á&Lˆ{æ|Çä`¼z_¼ù>ˆgú·\+mkO½þä=Àµ÷®ïlS±¸é?jã{ okÀ½õÎo#z!ût FÏæÇ7ŸD§Õtʽ³Ñùå4·ÜUÌݹ·ÿlû˜»ß_®ØEÌ›[*W\è5÷AV5^^$›µñ,j7aXi3Û°ûðîØ½õïÃõ¯¥G¬]ÿ®SÏ<Î*š—YMÝl•¢æh ᤮m(€>7ê˜ãÉæ¥b {Œºµ ›NE“ç-u§#D¨uÝiÖ.­Z}yeõ*®ùüõ“v}O!CWSX…/ íæ®ï¯c4Æø¦U+íú÷wß¾Ù{MVõlû˜Õ_'âë–¸±QWlú»å#ˆZ®B²»\zÍp¼(É–äö¢€]æþK\߳׃–—Ÿfôˆƒ ÞöpZÑì¼™i`Š?X¢ÿW¹;šLghSQòd¸x^oGG³“)ì« o¿Æh ×7îVÞ¹ö·¤Û¶t­û¤‹Õ¥·oÊ-á¾-܆\8.IÂÝNoÝ`[²cvÙ0ÜÔ†›Õe·nNMÙ±o(-³;Ö²ýê²[W“–ìN¸ÙF¸IWËŽk8¼qch‰îÄš‰™h[‡š[Ãêf]ß’ìo,y ››ÕwKr'ÌtŸ«Ý[K»’m Ç_.¶¤‹LxžÛruÙí²²-»hÆ6LÕÒÕAÞªæÚÒ;±&uŸt½ºôvAÑ–î¯N²ùuN³æÁßÞ 9ãz„»% þ aŠ?C¸ÄB¡þ±šL?y<:šÈcøÃiúâß(Í_ü;REƒ×a®™»fFš¹4,Ò„ë¸ë>î–•a™‘Ó×1’v¾’°—~§“~fÑZ¹3„Âi|<` Ñ@óü >H endstream endobj 113 0 obj << /Type /XRef /Index [0 114] /Size 114 /W [1 3 1] /Root 111 0 R /Info 112 0 R /ID [<2BDABA1A460A9C10F6F189BE824C67B1> <2BDABA1A460A9C10F6F189BE824C67B1>] /Length 311 /Filter /FlateDecode >> stream xÚ%Ï».CÇñßï½RTU«uk]êZ­º¥®u ƒMÄ`bô ‰L£Å â¼€„xsòûwùäûûŸ““øs€¡Z›bIÌ‹‚(Š ±N—7c/o —pwØnk¢VÔ¡»-·¨#÷vó ‘¼³é>"ýn³^ˆÌ¹Ím D>n·&ÑH|6C¢™(UgX´åŠÍˆh%öolFEqøbsG´‹q\ý·±(J¢,VEBĉ³{¯CtŠ.Ñ-zDR¤D¯èýb@¤Å ÃÄŇ}o„xz´%~sVcdèÀ*Cf«OÇÉë˜U–|>²Ê‘ŸoVdåÊ*O'Z´š¤Szµš¢sâ·š¦s{j5Cç‹V³t¾£VsbWìÑåI®È%þI+® endstream endobj startxref 202630 %%EOF phylobase/tests/0000755000176200001440000000000012554024356013410 5ustar liggesusersphylobase/tests/testprune.R0000644000176200001440000000071412347155416015570 0ustar liggesuserslibrary(phylobase) library(ape) set.seed(1) r1 <- rcoal(5) ## trace("phylo4d", browser, signature = "phylo") ## untrace("phylo4d", signature = "phylo") tipdat <- data.frame(a=1:5,row.names=r1$tip.label) p1 <- phylo4d(r1,tip.data=tipdat,node.data=data.frame(a=6:9), match.data=FALSE) p2 <- prune(p1,1) summary(p2) ## from picante `phylo2phylog` <- function(phy, ...) { newick2phylog(write.tree(phy, multi.line = FALSE),...) } plot.phylo(as(p2,"phylo")) phylobase/tests/phylo4dtests.R0000644000176200001440000000170012347155416016201 0ustar liggesuserslibrary(phylobase) library(ape) tree.phylo <- read.tree(text="(((A,B)C,D),E);") #only one node is labelled tree <- as(tree.phylo, "phylo4") tree.phylo2 <- read.tree(text="(((A,B)C,D)F,E)G;") # all nodes labelled tree2 <- as(tree.phylo2, "phylo4") tip.data <- data.frame(size=c(1, 2, 3, 4)) rownames(tip.data) <- c("A", "B", "E", "D") treed <- phylo4d(tree, tip.data) dat2 <- data.frame(size=c(0,1,2), row.names=c("G", "F", "C")) try(phylo4d(tree, node.data=dat2), silent = TRUE) # error, cannot match data because no node labels on tree phylo4d(tree2, node.data=dat2) -> treed2 # OK tree labelled; has node data, no tip data plot(treed2) # works with a warning about no tip data to plot tipData(treed2, empty.columns=FALSE) #returns empty 4-row data.frame phylo4d(tree2, tip.data=tip.data, node.data=dat2) -> treed3 #node+tip data plot(treed3) # works tipData(treed3) #works, but returns tips only tdata(treed3, "all") print(tree) print(treed) phylobase/tests/phylosubtest.R0000644000176200001440000000070212347155416016301 0ustar liggesuserslibrary(phylobase) library(ape) data(geospiza) gtree <- extractTree(geospiza) stopifnot(identical(gtree,prune(gtree,character(0)))) stopifnot(identical(tdata(subset(geospiza)), tdata(subset(geospiza, tipLabels(geospiza))))) tr <- read.tree(text="(((spA:0.2,(spB:0.1,spC:0.1):0.15):0.5,spD:0.7):0.2,spE:1):0.4;") phyd <- as(tr, "phylo4d") tipData(phyd) <- 1:5 stopifnot(identical(phyd@data,subset(phyd,tipLabels(phyd))@data)) phylobase/tests/phylotorture.R0000644000176200001440000000777612347155416016336 0ustar liggesusers## torture-testing phylo4 objects. library(phylobase) library(ape) set.seed(10101) n <- 200 p1 <- vector("list", n) ## don't want to slow down R CMD check by doing this every time: ## n <- 10000 for (i in 1:n) { if (i <= n/2) { e <- matrix(sample(1:10, replace=TRUE, size=10), ncol=2) } else { e <- cbind(sample(rep(11:19, 2)), sample(1:19)) e <- rbind(c(0, sample(11:19, 1)), e) } p1[[i]] <- try(phylo4(e), silent=TRUE) } OKvals <- sapply(p1, class) != "try-error" ## table(sapply(p1[!OKvals], as.character)) # I think this is causing issues with ## R check because of different width of terminal/output, trying something simpler: message(unique(sapply(p1[!OKvals], as.character))) sort(unname(table(sapply(p1[!OKvals], as.character)))) if (sum(OKvals)) message("There are ", sum(OKvals), " valid trees...") if (any(OKvals)) { p2 <- p1[OKvals] length(p2) has.poly <- sapply(p2, hasPoly) has.sing <- sapply(p2, hasSingle) has.retic <- sapply(p2, hasRetic) message("number of trees with polytomies: ", sum(has.poly)) message("number of trees with singletons: ", sum(has.sing)) message("number of trees with reticulation: ", sum(has.retic)) if (any(has.sing)) { p4 <- p2[has.sing] plot(p4[[1]]) ## gives descriptive error t2 <- try(plot(collapse.singles(as(p2[[1]],"phylo")))) ## "incorrect number of dimensions" } if (any(!has.sing)) { ## first tree without singles -- HANGS! ## don't try the plot in an R session you care about ... p3 <- p2[!has.sing] ## plot(p2[[13]]) } } ## elements 8 and 34 are ## what SHOULD the rules for trees be? ## (a) reduce node numbers to 1 ... N ? ## (b) check: irreducible, non-cyclic, ... ? ## convert to matrix format for checking? reduce_nodenums <- function(e) { matrix(as.numeric(factor(e)),ncol=2) } # make an illegal phylo4 object, does it pass checks? # a disconnected node: t1 <- read.tree (text="((a,b), (c,(d, e)));") plot(t1) broke1 <- t1 broke1$edge[broke1$edge[,2] ==9, 1] <- 9 # disconnect the node, two subtrees, ((a, b), c) and (d,e) try(as(broke1, "phylo4") -> tree, silent=TRUE) # makes a phylo4 object with no warning try(phylo4(broke1$edge), silent=TRUE) # constructor makes a phylo4 object with no warning ## error message comes from ape, not phylo? -- AND ## error is about singles, not disconnected nodes ## print(try(plot(tree), silent=TRUE )) ## pdc couldn't get this to work, so temporarily commenting # root node value != ntips + 1: broke2 <- t1 broke2$edge[broke2$edge==6] <- 10 ## warning, but no error ## plot(broke2) ## seems to hang R CMD check?? ## generates error, but it's about wrong number of tips, not wrong value at root. message(try(as(broke2, "phylo4"), silent=TRUE)) ## error regarding number of tip labels vs edges and nodes message(try(phylo4(broke2$edge), silent=TRUE)) # switch root node value (6) with next internal node (7): broke3 <- broke2 broke3$edge[broke3$edge==7] <- 6 broke3$edge[broke3$edge==10] <- 7 ## both of the following now fail with ## "root node is not at position (nTips+1) try(as(broke3,"phylo4") -> tree3) # works with no error message try(phylo4(broke3$edge)) # works with no error message ## plot(tree3) # would work if we could create it? # tips have larger numbers than root node: broke4 <- t1 broke4$edge[broke4$edge==1] <- 11 broke4$edge[broke4$edge==2] <- 12 broke4$edge[broke4$edge==3] <- 13 broke4$edge[broke4$edge==4] <- 14 broke4$edge[broke4$edge==5] <- 15 message(try(as(broke4, "phylo4"), silent=TRUE)) message(try(phylo4(broke4$edge), silent=TRUE)) # print(try(plot(broke4), TRUE)) ## CAUSES R TO HANG! ### foo <- new('phylo4') foo@edge <- rcoal(10)$edge message(try(plot(foo))) foo@label <- c(rep('blah',10), rep("",9)) ##### ## tree with only 2 tips: will fail under previous versions ## with "Error in if (which(nAncest == 0) != nTips + 1) { : ## argument is of length zero" edge <- matrix(c(3, 1, 3, 2), byrow=TRUE, ncol=2) try(p2 <- phylo4(edge), silent=TRUE) phylobase/tests/plottest.R0000644000176200001440000000276112554022250015406 0ustar liggesuserslibrary(phylobase) library(ape) data(geospiza) g1 <- as(geospiza,"phylo4") g2 <- geospiza par(mfrow=c(1,2)) plot(g1, show.node.label=TRUE) ## be careful with this: works if par("fin")=c(5.56,6.77) ## fails if par("fin")=c(4.87,6.77) ##try(plot(g2,show.node.label=TRUE),silent=TRUE) ## Here, R was complaining about a lack of room to plot data ## so nothing abnormal. -- TJ plot(g2, show.node.label=TRUE) ## commented out since phylog objects are deprecated anyway ## g2B <- as(extractTree(g2), "phylog") ## Note the numbering differences! ## round trip g2C <- as(read.tree(text=write.tree(as(g1, "phylo"))), "phylo4") ## comes back in same order try(plot(g1, show.node.label=TRUE)) try(plot(g2C, show.node.label=TRUE)) g3 = subset(g2, tips.exclude=c("fuliginosa", "fortis", "magnirostris", "conirostris", "scandens")) plot(extractTree(g3)) ## phylo4 plot(g3) ## Playing with new ways of plotting if (FALSE) { if(require(MASS)){ dist1 <- cophenetic.phylo(as(g2, "phylo")) mdspos <- isoMDS(dist1)$points par(mfrow=c(2, 2)) plot(g1) ## plot(mdspos,type="n") ## text(mdspos[,1],mdspos[,2],abbreviate(rownames(mdspos))) ## cmdpos <- cmdscale(dist1) ## plot(cmdpos,type="n") ## text(cmdpos[,1],cmdpos[,2],abbreviate(rownames(mdspos))) } ## never mind, I don't know how to construct a useful ## 2D color space anyway ... } treePlot(g2,plot.at.tip=TRUE,tip.plot.fun= function(x,...) { grid::grid.points(seq(along=x),x)}) phylobase/tests/roundtrip.R0000644000176200001440000000223112347155416015561 0ustar liggesuserslibrary(phylobase) library(ape) ## set.seed(1) ## t0A <- rcoal(5) t0 <- read.tree(text="((t4:0.3210275554,(t2:0.2724586465,t3:0.2724586465):0.0485689089):0.1397952619,(t5:0.07551818331,t1:0.07551818331):0.385304634);") ## hack around variability in ape: ## read.tree() and rcoal() produce sets of ## elements in different orders t0 <- unclass(t0)[c("edge","edge.length","tip.label","Nnode")] class(t0) <- "phylo" ## phylo -> phylo4 -> phylo t1 <- as(t0,"phylo4") t5 <- as(t1,"phylo") stopifnot(identical(t0,t5)) ## phylo4 -> phylo4vcov -> phylo4 -> phylo t2<-as(t1,"phylo4vcov") t3<-as(t2,"phylo4") t4<-as(t3,"phylo") stopifnot(identical(t4$edge,t0$edge) && identical(t4$tip.label,t0$tip.label) && identical(t4$Nnode,t0$Nnode) && max(abs(t4$edge.length-t0$edge.length))<1e-10) ## UNROOTED t6 <- ape::unroot(t0) ## hack around ape conversion issues: ## unroot() converts integer to double storage.mode(t6$edge) <- "integer" storage.mode(t6$Nnode) <- "integer" t7 <- as(as(t6,"phylo4"),"phylo") stopifnot(identical(t6,t7)) ## EXPLICIT ROOT EDGE t8 <- t0 t8$root.edge <- 0.5 t9 <- as(as(t8,"phylo4"),"phylo") stopifnot(identical(t8,t9)) phylobase/tests/misctests.R0000644000176200001440000000566112553732764015571 0ustar liggesuserslibrary(phylobase) library(ape) set.seed(1) data(geospiza) ## make sure geospiza is properly formatted if(is.character(checkval <- checkPhylo4(geospiza))) stop(checkval) geospiza0 <- list(geospiza.tree=as(geospiza,"phylo"),geospiza.data=tipData(geospiza)) ## push data back into list form as in geiger t1 <- try(p1 <- phylo4d(geospiza0$geospiza.tree,geospiza0$geospiza.data)) ## Error in checkData(res, ...) : ## Tip data names are a subset of tree tip labels. p2 <- as(geospiza0$geospiza.tree,"phylo4") plot(p2) lab1 <- tipLabels(p2) lab2 <- rownames(geospiza0$geospiza.data) lab1[!lab1 %in% lab2] ## missing data lab2[!lab2 %in% lab1] ## extra data (none) p1 <- phylo4d(p2,geospiza0$geospiza.data, missing.data="warn") p1 <- phylo4d(p2,geospiza0$geospiza.data, missing.data="OK") plot(p1) plot(p1,show.node.label=TRUE) ## one way to deal with it: p1B <- prune(p1,tip="olivacea") ## or ... p1C <- stats::na.omit(p1) labels(p1C, "all") <- tolower(labels(p1C, "all")) ## trace("prune",browser,signature="phylo4d") r1 <- read.tree(text="((t4:0.3210275554,(t2:0.2724586465,t3:0.2724586465):0.0485689089):0.1397952619,(t5:0.07551818331,t1:0.07551818331):0.385304634);") ## trace("phylo4d", browser, signature = "phylo") ## untrace("phylo4d", signature = "phylo") tipdat <- data.frame(a=1:5, row.names=r1$tip.label) q1 <- phylo4d(r1,tip.data=tipdat, node.data=data.frame(a=6:9), match.data=FALSE) q2 <- prune(q1,1) summary(q2) tipdat2 <- tipdat row.names(tipdat2)[1] <- "s1" t1 <- try(q1 <- phylo4d(r1,tip.data=tipdat2)) plot(q2) plot(q2,type="cladogram") ## plot(p2,type="dotchart",labels.nodes=nodeLabels(p2)) ## trace("plot", browser, signature = c("phylo4d","missing")) tipLabels(q1) <- paste("q",1:5,sep="") nodeLabels(q1) <- paste("n",1:4,sep="") p3 <- phylo4d(r1,tip.data=tipdat,node.data=data.frame(b=6:9), match.data=FALSE) summary(p3) plot(p1) plot(subset(p1,tips.include=c("fuliginosa","fortis","magnirostris", "conirostris","scandens"))) ## better error? ## Error in phy$edge[, 2] : incorrect number of dimensions if(dev.cur() == 1) get(getOption("device"))() plot(subset(p2,tips.include=c("fuliginosa","fortis","magnirostris", "conirostris","scandens"))) plot(p2,show.node.label=TRUE) tree.owls <- read.tree(text="(((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3):6.3,Tyto_alba:13.5);") z <- as(tree.owls,"phylo4") example("phylo4d") obj1 <- obj2 <- obj3 <- phylo4d(z, data.frame(wing=1:4,color=factor(c("b","w","b","b")), tail=runif(4)*10), match.data=FALSE) obj2@data <- as.data.frame(obj2@data[,1]) obj3@data <- cbind(obj1@data,obj2@data) obj4 <- obj1 obj4@data[2,3] <- NA obj4@data[1,1] <- NA nodeLabels(obj4) <- character(0) obj5 <- obj1 tipData(obj4) <- subset(tipData(obj4),select=sapply(tipData(obj4),class)=="numeric") treePlot(obj4) E <- matrix(c( 8, 9, 9, 10, 10, 1, 10, 2, 9, 3, 9, 4, 8, 11, 11, 5, 11, 6, 11, 7, 0, 8), ncol=2,byrow=TRUE) P2 <- phylo4(E) phylobase/tests/testthat/0000755000176200001440000000000013076473202015246 5ustar liggesusersphylobase/tests/testthat/test.badnex.R0000644000176200001440000000055412347155416017620 0ustar liggesusers# # --- Test badnex.R --- # test_that("Malformed Nexus File should not work.", { if (Sys.getenv("RCMDCHECK") == FALSE) { pth <- file.path(getwd(), "..", "inst", "nexusfiles") } else { pth <- system.file(package="phylobase", "nexusfiles") } badFile <- file.path(pth, "badnex.nex") expect_error(readNexus(file=badFile)) }) phylobase/tests/testthat/test.phylobase.options.R0000644000176200001440000000137112347155416022035 0ustar liggesusers ### ### phylobase.options ### context("phylobase.options()") test_that("test of match.arg", { op <- phylobase.options() ## test match.arg expect_error(phylobase.options(retic="test")) no <- phylobase.options(retic="f") expect_equal(no$retic, "fail") phylobase.options(op) }) test_that("test of multiple arguments", { op <- phylobase.options() ## test multiple args no <- phylobase.options(retic="f", poly="f") expect_equal(no$retic, "fail") expect_equal(no$poly, "fail") phylobase.options(op) }) test_that("test some failures", { op <- phylobase.options() ## check some failures expect_error(phylobase.options(1)) expect_error(phylobase.options("foobar"="foo")) phylobase.options(op) }) phylobase/tests/testthat/test.class-phylo4d.R0000644000176200001440000003105612350623004021031 0ustar liggesusers# # --- Test class-phylo4d.R --- # ### Get all the test files if (Sys.getenv("RCMDCHECK") == FALSE) { pth <- file.path(getwd(), "..", "inst", "nexmlfiles") } else { pth <- system.file(package="phylobase", "nexmlfiles") } ## create ape::phylo version of a simple tree for testing nwk <- "((t1:0.1,t2:0.2)n7:0.7,(t3:0.3,(t4:0.4,t5:0.5)n9:0.9)n8:0.8)n6:0.6;" tr <- ape::read.tree(text=nwk) # create analogous phylo4 object with a full complement of valid slots ancestor <- as.integer(c(6,7,7,6,8,0,8,9,9)) descendant <- as.integer(c(7,1,2,8,3,6,9,4,5)) edge <- cbind(ancestor, descendant) nid.tip <- 1:5 nid.int <- 6:9 nid.all <- c(nid.tip, nid.int) lab.tip <- paste("t", nid.tip, sep="") lab.int <- paste("n", nid.int, sep="") lab.all <- c(lab.tip, lab.int) elen <- descendant/10 elab <- paste("e", ancestor, descendant, sep="-") phy <- phylo4(x=edge, tip.label=lab.tip, node.label=lab.int, edge.length=elen, edge.label=elab) # create altered version such that each slot is out of order with # respect to all others; methods should be able to handle this phy.alt <- phy phy.alt@label <- rev(phy@label) phy.alt@edge <- phy@edge[c(6:9, 1:5), ] phy.alt@edge.length <- phy@edge.length[c(7:9, 1:6)] phy.alt@edge.label <- phy@edge.label[c(8:9, 1:7)] # create data to add to phylo4 to create phylo4d, but with data rows out # of order set.seed(1) nid.tip.r <- sample(nid.tip) nid.int.r <- sample(nid.int) nid.all.r <- sample(c(nid.tip, nid.int)) allDt <- data.frame(a=letters[nid.all.r], b=10*nid.all.r) tipDt <- data.frame(c=letters[nid.tip.r], d=10*nid.tip.r) nodDt <- data.frame(c=letters[nid.int.r], e=10*nid.int.r) ## set row.names as numeric node IDs (may be changed in tests below) row.names(allDt) <- nid.all.r row.names(tipDt) <- nid.tip.r row.names(nodDt) <- nid.int.r ## NeXML files compFile <- file.path(pth, "comp_analysis.xml") stopifnot(file.exists(compFile)) #----------------------------------------------------------------------- context("test phylo4d class") test_that("phylo4d can be built from phylo4", { ## case 1: add data matching only on row position row.names(allDt) <- NULL row.names(tipDt) <- NULL row.names(nodDt) <- NULL ## these should fail because row.names don't match nodes expect_error(phylo4d(phy.alt, tip.data=tipDt, rownamesAsLabels=TRUE)) expect_error(phylo4d(phy.alt, node.data=nodDt)) ## brute force: no matching; with tip data phyd <- phylo4d(phy.alt, tip.data=tipDt, match.data=FALSE) expect_equal(phyd@data, data.frame(tipDt, row.names=nid.tip)) expect_equal(tdata(phyd, "tip"), data.frame(tipDt, row.names=lab.tip)) ## brute force: no matching; with node data phyd <- phylo4d(phy.alt, node.data=nodDt, match.data=FALSE) expect_equal(phyd@data, data.frame(nodDt, row.names=nid.int)) expect_equal(tdata(phyd, "internal"), data.frame(nodDt, row.names=lab.int)) ## brute force: no matching; with all.data phyd <- phylo4d(phy.alt, all.data=allDt, match.data=FALSE) expect_equal(phyd@data, data.frame(allDt, row.names=nid.all)) expect_equal(tdata(phyd, "all"), data.frame(allDt, row.names=lab.all)) ## brute force: no matching; with tip & node data ## no merging (data names don't match) phyd <- phylo4d(phy.alt, tip.data=tipDt["d"], node.data=nodDt["e"], match.data=FALSE) expect_equal(phyd@data, data.frame(rbind(data.frame(tipDt["d"], e=NA_real_), data.frame(d=NA_real_, nodDt["e"])), row.names=nid.all)) expect_equal(tdata(phyd, "tip"), data.frame(tipDt["d"], e=NA_real_, row.names=lab.tip)) expect_equal(tdata(phyd, "internal"), data.frame(d=NA_real_, nodDt["e"], row.names=lab.int)) ## brute force: no matching; with tip & node data ## merging (common data names) phyd <- phylo4d(phy.alt, tip.data=tipDt["c"], node.data=nodDt["c"], match.data=FALSE) expect_equal(phyd@data, data.frame(rbind(tipDt["c"], nodDt["c"]), row.names=nid.all)) expect_equal(tdata(phyd, "tip"), data.frame(c=factor(tipDt$c, levels=letters[nid.all]), row.names=lab.tip)) expect_equal(tdata(phyd, "internal"), data.frame(c=factor(nodDt$c, levels=letters[nid.all]), row.names=lab.int)) ## case 2: add data matching on numeric (node ID) row.names row.names(allDt) <- nid.all.r row.names(tipDt) <- nid.tip.r row.names(nodDt) <- nid.int.r ## match with node numbers, tip data phyd <- phylo4d(phy.alt, tip.data=tipDt) expect_equal(phyd@data, data.frame(tipDt[order(nid.tip.r),], row.names=nid.tip)) expect_equal(tdata(phyd, "tip"), data.frame(tipDt[order(nid.tip.r),], row.names=lab.tip)) ## match with node numbers, node data phyd <- phylo4d(phy.alt, node.data=nodDt) expect_equal(phyd@data, data.frame(nodDt[order(nid.int.r),], row.names=nid.int)) expect_equal(tdata(phyd, "internal"), data.frame(nodDt[order(nid.int.r),], row.names=lab.int)) ## match with node numbers, tip & node data, no merge phyd <- phylo4d(phy.alt, tip.data=tipDt["d"], node.data=nodDt["e"]) expect_equal(phyd@data, data.frame(rbind(data.frame( d=tipDt[order(nid.tip.r), "d"], e=NA_real_), data.frame(d=NA_real_, e=nodDt[order(nid.int.r), "e"])), row.names=nid.all)) expect_equal(tdata(phyd, "tip"), data.frame(d=tipDt[order(nid.tip.r), "d"], e=NA_real_, row.names=lab.tip)) expect_equal(tdata(phyd, "internal"), data.frame(d=NA_real_, e=nodDt[order(nid.int.r), "e"], row.names=lab.int)) ## match with node numbers, tip & all data phyd <- phylo4d(phy.alt, tip.data=tipDt, all.data=allDt) merged <- data.frame(merge(allDt[order(nid.all.r),], tipDt[order(nid.tip.r),], all=TRUE, by=0)[-1]) expect_equal(phyd@data, data.frame(merged, row.names=nid.all)) expect_equal(tdata(phyd, "all"), data.frame(merged, row.names=lab.all)) ## match with node numbers, node & all data phyd <- phylo4d(phy.alt, node.data=nodDt, all.data=allDt) merged <- data.frame(merge(allDt[order(nid.all.r),], nodDt[order(nid.int.r),], all=TRUE, by=0)[-1]) expect_equal(phyd@data, data.frame(merged, row.names=nid.all)) expect_equal(tdata(phyd, "all"), data.frame(merged, row.names=lab.all)) ## match with node numbers, tip, node & all data phyd <- phylo4d(phy.alt, tip.data=tipDt, node.data=nodDt, all.data=allDt) # merge alldata with common tip and node data m1 <- data.frame(merge(allDt, rbind(tipDt["c"], nodDt["c"]), all=TRUE, by=0)[-1]) # merge distinct columns of tipdata and nodedata m2 <- data.frame(merge(tipDt["d"], nodDt["e"], all=TRUE, by=0)[-1]) # ...now merge these together merged <- data.frame(merge(m1, m2, by=0)[-1]) expect_equal(phyd@data, data.frame(merged, row.names=nid.all)) expect_equal(tdata(phyd, "tip"), data.frame(merged[nid.tip,], row.names=lab.tip, check.names=FALSE)) expect_equal(tdata(phyd, "internal"), data.frame(merged[nid.int,], row.names=lab.int, check.names=FALSE)) expect_equal(tdata(phyd, "all"), data.frame(merged, row.names=lab.all)) ## as above, but without merging common tip and node column phyd <- phylo4d(phy.alt, tip.data=tipDt, node.data=nodDt, all.data=allDt, merge.data=FALSE) m3 <- data.frame(merge(tipDt, nodDt, all=TRUE, by=0, suffix=c(".tip", ".node"))[-1]) merged <- data.frame(merge(allDt, m3, by=0)[-1]) expect_equal(phyd@data, data.frame(merged, row.names=nid.all)) expect_equal(tdata(phyd, "tip"), data.frame(merged[nid.tip,], row.names=lab.tip, check.names=FALSE)) expect_equal(tdata(phyd, "internal"), data.frame(merged[nid.int,], row.names=lab.int, check.names=FALSE)) expect_equal(tdata(phyd, "all"), data.frame(merged, row.names=lab.all)) ## case 3: add data matching on character (label) row.names for tips row.names(tipDt) <- c(lab.tip, lab.int)[nid.tip.r] row.names(nodDt) <- c(lab.tip, lab.int)[nid.int.r] ## match with names, tip data phyd <- phylo4d(phy.alt, tip.data=tipDt) expect_equal(phyd@data, data.frame(tipDt[order(nid.tip.r),], row.names=nid.tip)) expect_equal(tdata(phyd, "tip"), data.frame(tipDt[order(nid.tip.r),], row.names=lab.tip)) ## case 4: add data matching on mixed rowname types (for tips and ## for internal nodes) row.names(allDt)[match(nid.tip.r, nid.all.r)] <- lab.tip[nid.tip.r] row.names(allDt)[match(nid.int.r, nid.all.r)] <- nid.int.r ## match with names for tips and numbers for nodes with all data phyd <- phylo4d(phy.alt, all.data=allDt) expect_equal(tdata(phyd, "all"), data.frame(allDt[match(nid.all, nid.all.r),], row.names=lab.all)) expect_equal(tdata(phyd, "tip"), data.frame(allDt[match(nid.tip, nid.all.r),], row.names=lab.tip)) expect_equal(tdata(phyd, "internal"), data.frame(allDt[match(nid.int, nid.all.r),], row.names=lab.int)) expect_equal(phyd@data, data.frame(allDt[match(nid.all, nid.all.r),], row.names=nid.all)) }) ## test.phylo4d.matrix <- function() { ## } # note: this method mostly does phylo4(phylo), then phylo4d(phylo4), # then addData methods, which are tested more thoroughly elsewhere; # focus here is on metadata and check.node.labels="asdata" arguments test_that("phylo4d can be built from phylo object", { # function(x, tip.data=NULL, node.data=NULL, all.data=NULL, # check.node.labels=c("keep", "drop", "asdata"), annote=list(), # metadata=list(), ...) ## show that method basically just wraps phylo4d("phylo4") phyd.tr <- phylo4d(tr, tip.data=tipDt, node.data=nodDt, all.data=allDt, match.data=TRUE, merge.data=TRUE) expect_true(class(phyd.tr)=="phylo4d") phyd.phy <- phylo4d(phy.alt, tip.data=tipDt, node.data=nodDt, all.data=allDt, match.data=TRUE, merge.data=TRUE) # reorder for edge order consistency, then test each slot (except # edge labels, b/c phylo object has none) phyd.tr <- reorder(phyd.tr) phyd.phy <- reorder(phyd.phy) expect_equal(edges(phyd.tr), edges(phyd.phy)) expect_equal(edgeLength(phyd.tr), edgeLength(phyd.phy)) expect_equal(nNodes(phyd.tr), nNodes(phyd.phy)) expect_equal(tipLabels(phyd.tr), tipLabels(phyd.phy)) expect_equal(nodeLabels(phyd.tr), nodeLabels(phyd.phy)) expect_equal(edgeOrder(phyd.tr), edgeOrder(phyd.phy)) expect_equal(phyd.tr@annote, phyd.phy@annote) # other misc checks expect_equal(phylo4d(phylo4(tr)), phylo4d(tr)) expect_equal(phylo4d(phylo4(tr, check.node.labels="drop")), phylo4d(tr, check.node.labels="drop")) ## ## metadata ## metadata <- list(x="metadata") phyd <- phylo4d(tr, metadata=metadata) expect_equal(metadata, phyd@metadata) ## ## check.node.labels ## # case 0: no node labels tr$node.label <- NULL phyd <- phylo4d(tr) expect_true(!hasNodeLabels(phyd)) # case 1: convert character labels as data tr$node.label <- paste("n", 1:4, sep="") phyd <- phylo4d(tr, check.node.labels="asdata") expect_true(!hasNodeLabels(phyd)) expect_equal(tdata(phyd, "internal")$labelValues, as.factor(tr$node.label)) # case 2: convert number-like characters labels to numeric data tr$node.label <- as.character(1:4) phyd <- phylo4d(tr, check.node.labels="asdata") expect_true(!hasNodeLabels(phyd)) expect_equal(tdata(phyd, "internal")$labelValues, as.numeric(tr$node.label)) # case 3: convert numeric labels to numeric data tr$node.label <- as.numeric(1:4) phyd <- phylo4d(tr, check.node.labels="asdata") expect_true(!hasNodeLabels(phyd)) expect_equal(tdata(phyd, "internal")$labelValues, tr$node.label) # case 4: non-unique labels can be converted to data tr$node.label <- rep(99, 4) phyd <- phylo4d(tr) expect_equal(unname(nodeLabels(phyd)), as.character(tr$node.label)) phyd <- phylo4d(tr, check.node.labels="asdata") expect_true(!hasNodeLabels(phyd)) expect_equal(tdata(phyd, "internal", label.type="column")$labelValues, tr$node.label) }) ## phylo4d->phylo4d is currently unallowed test_that("phylo4d to phylo4d throws error", { phyd <- phylo4d(phy) expect_error(phylo4d(phyd)) }) test_that("nexml to phylo4d", { nxml <- RNeXML::nexml_read(compFile) phy4d <- phylo4d(nxml) nxmldt <- RNeXML::get_characters(nxml) phy4d2 <- phylo4d(get_trees(nxml), nxmldt[sample(1:nrow(nxmldt)), ]) expect_true(all(tipLabels(phy4d) %in% paste("taxon", 1:10, sep="_"))) expect_equal(nEdges(phy4d), 19) expect_equal(phy4d, phy4d2) expect_equal(ncol(tdata(phy4d, "tip")), 2) expect_true(all(names(tdata(phy4d, "tip")) %in% c("log.snout.vent.length", "reef.dwelling"))) }) phylobase/tests/testthat/test.formatData.R0000644000176200001440000005274312522211420020427 0ustar liggesusers# # --- Test formatData.R --- # # create phylo4 object with a full complement of valid slots ancestor <- as.integer(c(6,7,7,6,8,0,8,9,9)) descendant <- as.integer(c(7,1,2,8,3,6,9,4,5)) edge <- cbind(ancestor, descendant) nid.tip <- 1:5 nid.int <- 6:9 nid.all <- c(nid.tip, nid.int) lab.tip <- paste("t", nid.tip, sep="") lab.int <- paste("n", nid.int, sep="") lab.all <- c(lab.tip, lab.int) elen <- descendant/10 elab <- paste("e", ancestor, descendant, sep="-") phy <- phylo4(x=edge, tip.label=lab.tip, node.label=lab.int, edge.length=elen, edge.label=elab) # create altered version such that each slot is out of order with # respect to all others; methods should be able to handle this phy.alt <- phy phy.alt@label <- rev(phy@label) phy.alt@edge <- phy@edge[c(6:9, 1:5), ] phy.alt@edge.length <- phy@edge.length[c(7:9, 1:6)] phy.alt@edge.label <- phy@edge.label[c(8:9, 1:7)] # create data to add to phylo4 to create phylo4d, but with data rows out # of order set.seed(1) nid.tip.r <- sample(nid.tip) nid.int.r <- sample(nid.int) nid.all.r <- sample(c(nid.tip, nid.int)) allDt <- data.frame(a=letters[nid.all.r], b=10*nid.all.r) tipDt <- data.frame(c=letters[nid.tip.r], d=10*nid.tip.r) nodDt <- data.frame(c=letters[nid.int.r], e=10*nid.int.r) ## set row.names as numeric node IDs (may be changed in tests below) row.names(allDt) <- nid.all.r row.names(tipDt) <- nid.tip.r row.names(nodDt) <- nid.int.r #----------------------------------------------------------------------- context("test formatData") ## function(phy, dt, type=c("tip", "internal", "all"), ## match.data=TRUE, rownamesAsLabels=FALSE, ## label.type=c("rownames", "column"), label.column=1, ## missing.data=c("fail", "warn", "OK"), ## extra.data=c("warn", "OK", "fail"), keep.all=TRUE test_that("works with data.frame", { ## vector data coerced to data.frame (colname dt) expect_equal(phylobase:::formatData(phy.alt, 1:5), phylobase:::formatData(phy.alt, data.frame(dt=1:5))) }) test_that("works with lists of vector", { ## list of vector data coerced to data.frame (colnames as given) expect_equal(phylobase:::formatData(phy.alt, list(a=1:5, b=6:10)), phylobase:::formatData(phy.alt, data.frame(a=1:5, b=6:10))) }) test_that("works factors", { ## factor data coerced to data.frame (colname dt) expect_equal(phylobase:::formatData(phy.alt, factor(letters[1:5])), phylobase:::formatData(phy.alt, data.frame(dt=letters[1:5]))) }) test_that("works with data.frame and 2 columns", { ## matrix data coerced to data.frame (colnames V1, V2) expect_equal(phylobase:::formatData(phy.alt, matrix(1:10, ncol=2)), phylobase:::formatData(phy.alt, data.frame(V1=1:5, V2=6:10))) }) test_that("works with data.frame colname as given", { ## matrix data coerced to data.frame (colname as given) expect_equal(phylobase:::formatData(phy.alt, matrix(1:10, ncol=2, dimnames=list(NULL, c("a", "b")))), phylobase:::formatData(phy.alt, data.frame(a=1:5, b=6:10))) }) test_that("fails with non-supported objects (i.e. a phylo4)", { ## error if dt is, say, a phylo4 object expect_error(phylobase:::formatData(phy.alt, phy.alt)) }) test_that("fails with column number is out of range", { ## error if column number is out of range expect_error(phylobase:::formatData(phy.alt, data.frame(a=1:5, lab=rev(nid.tip)), type="tip", match.data=FALSE, label.type="column", label.column=3)) }) test_that("fails with column name is wrong", { ## error if column name is wrong expect_error(phylobase:::formatData(phy.alt, data.frame(a=1:5, lab=rev(nid.tip)), type="tip", match.data=FALSE, label.type="column", label.column="foo")) }) ## ## matching options ## test_that("matching options work as expected", { ## don't match (purely positional) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, row.names=rev(nid.tip)), type="tip", match.data=FALSE), data.frame(a=c(1:5, rep(NA, 4)), row.names=nid.all)) ## match on rownames (node numbers) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, row.names=rev(nid.tip)), type="tip", match.data=TRUE), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, row.names=rev(nid.tip)), type="tip"), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) ## match on rownames (labels) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, row.names=rev(lab.tip)), type="tip", match.data=TRUE), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) ## match on rownames (mixed node numbers and labels) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, row.names=c(rev(lab.tip)[1:3], rev(nid.tip)[4:5])), type="tip", match.data=TRUE), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) ## but fails if rownamesAsLabels is TRUE expect_error(phylobase:::formatData(phy.alt, data.frame(a=1:5, row.names=c(rev(lab.tip)[1:3], rev(nid.tip)[4:5])), type="tip", match.data=TRUE, rownamesAsLabels=TRUE)) }) ## ## label.type="column" and label.column=2 ## test_that("label.type=column works", { ## should ignore label (purely positional) and retain a label col expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, lab=rev(nid.tip)), type="tip", match.data=FALSE, label.type="column", label.column=2), data.frame(a=c(1:5, rep(NA, 4)), lab=c(rev(nid.tip), rep(NA, 4)), row.names=nid.all)) ## match on label column (node numbers) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, lab=rev(nid.tip)), type="tip", match.data=TRUE, label.type="column", label.column=2), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, lab=rev(nid.tip)), type="tip", label.type="column", label.column=2), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) ## match on label column (labels) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, lab=rev(lab.tip)), type="tip", match.data=TRUE, label.type="column", label.column=2), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, lab=rev(lab.tip)), type="tip", match.data=TRUE, label.type="column", label.column="lab"), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) ## match on label column (mixed node numbers and labels) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, lab=c(rev(lab.tip)[1:3], rev(nid.tip)[4:5])), type="tip", match.data=TRUE, label.type="column", label.column=2), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) ## but fails if rownamesAsLabels is TRUE expect_error(phylobase:::formatData(phy.alt, data.frame(a=1:5, lab=c(rev(lab.tip)[1:3], rev(nid.tip)[4:5])), type="tip", match.data=TRUE, rownamesAsLabels=TRUE, label.type="column", label.column=2)) ## try to match internal nodes when type='tips' expect_error(phylobase:::formatData(phy.alt, data.frame(a=1:5, row.names=4:8), type="tip")) ## and vice versa expect_error(phylobase:::formatData(phy.alt, data.frame(a=6:9, row.names=1:4), type="internal")) }) ## ## missing.data ## test_that("behaves as expected with missing data", { ## force error conditions expect_error(phylobase:::formatData(phy.alt, data.frame(a=1:3), type="tip")) expect_error(phylobase:::formatData(phy.alt, data.frame(a=1:3), type="tip", missing.data="fail")) expect_warning(phylobase:::formatData(phy.alt, data.frame(a=1:3), type="tip", missing.data="warn")) ## missing data with matching expect_equal(phylobase:::formatData(phy.alt, data.frame(a=rev(nid.tip)[-1], row.names=rev(nid.tip)[-1]), type="tip", missing.data="OK"), data.frame(a=c(nid.tip[-5], rep(NA, 5)))) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=rev(nid.int)[-1], row.names=rev(nid.int)[-1]), type="internal", missing.data="OK"), data.frame(a=c(rep(NA, 5), nid.int[-4], NA))) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=rev(nid.all)[-1], row.names=rev(nid.all)[-1]), type="all", missing.data="OK"), data.frame(a=c(nid.all[-9], NA))) ## missing data without matching expect_equal(phylobase:::formatData(phy.alt, data.frame(a=rev(nid.tip)[-1]), type="tip", match.data=FALSE, missing.data="OK"), data.frame(a=c(rev(nid.tip)[-1], rep(NA, 5)))) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=rev(nid.int)[-1]), type="internal", match.data=FALSE, missing.data="OK"), data.frame(a=c(rep(NA, 5), rev(nid.int)[-1], NA))) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=rev(nid.all)[-1]), type="all", match.data=FALSE, missing.data="OK"), data.frame(a=c(rev(nid.all)[-1], NA))) }) ## ## extra.data ## test_that("works as expected with extra data", { ## force error conditions expect_error(phylobase:::formatData(phy.alt, data.frame(a=1:3), type="tip", missing.data="fail")) expect_warning(phylobase:::formatData(phy.alt, data.frame(a=0:5, row.names=0:5), type="tip", missing="warn"), "not found in the tree") expect_warning(phylobase:::formatData(phy.alt, data.frame(a=0:5, row.names=0:5), type="tip"), "not found in the tree") ## extra data with matching expect_equal(phylobase:::formatData(phy.alt, data.frame(a=c(0L, rev(nid.tip)), row.names=c(0, rev(nid.tip))), type="tip", extra.data="OK"), data.frame(a=c(nid.tip, rep(NA, 4)))) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=c(0L, rev(nid.int)), row.names=c(0, rev(nid.int))), type="internal", extra.data="OK"), data.frame(a=c(rep(NA, 5), nid.int))) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=c(0L, rev(nid.all)), row.names=c(0, rev(nid.all))), type="all", extra.data="OK"), data.frame(a=nid.all)) ## extra data without matching expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:15), type="tip", match.data=FALSE, extra.data="OK"), data.frame(a=c(1:5, rep(NA, 4)))) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:15), type="internal", match.data=FALSE, extra.data="OK"), data.frame(a=c(rep(NA, 5), 1:4))) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:15), type="all", match.data=FALSE, extra.data="OK"), data.frame(a=c(1:9))) }) test_that("works as expected with both missing & extra data", { ## allow both extra.data and missing.data expect_equal(phylobase:::formatData(phy.alt, data.frame(a=0:3, row.names=0:3), type="tip", extra.data="OK", missing.data="OK"), data.frame(a=c(1:3, rep(NA, 6)))) }) ## ## keep.all ## test_that("keep.all works", { ## keep all rows expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, row.names=nid.tip), type="tip", keep.all=TRUE), data.frame(a=c(1:5, rep(NA, 4)), row.names=nid.all)) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, row.names=nid.tip), type="tip"), data.frame(a=c(1:5, rep(NA, 4)), row.names=nid.all)) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=6:9, row.names=nid.int), type="internal", keep.all=TRUE), data.frame(a=c(rep(NA, 5), 6:9), row.names=nid.all)) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=6:9, row.names=nid.int), type="internal"), data.frame(a=c(rep(NA, 5), 6:9), row.names=nid.all)) ## only keep 'type' rows expect_equal(phylobase:::formatData(phy.alt, data.frame(a=1:5, row.names=nid.tip), type="tip", keep.all=FALSE), data.frame(a=c(1:5), row.names=nid.tip)) expect_equal(phylobase:::formatData(phy.alt, data.frame(a=6:9, row.names=nid.int), type="internal", keep.all=FALSE), data.frame(a=c(6:9), row.names=nid.int)) }) context("formatData with duplicated labels in object") test_that("formatData works with duplicated labels", { ## Saving default options op <- phylobase.options() ## Changing default options phylobase.options(allow.duplicated.labels="ok") ## Creating phylo4 object with duplicated labels phy.dup <- phy.alt tipLabels(phy.dup)[2] <- tipLabels(phy.dup)[1] ## vector data coerced to data.frame (colname dt) expect_equal(phylobase:::formatData(phy.dup, 1:5), phylobase:::formatData(phy.dup, data.frame(dt=1:5))) ## list of vector data coerced to data.frame (colnames as given) expect_equal(phylobase:::formatData(phy.dup, list(a=1:5, b=6:10)), phylobase:::formatData(phy.dup, data.frame(a=1:5, b=6:10))) ## factor data coerced to data.frame (colname dt) expect_equal(phylobase:::formatData(phy.dup, factor(letters[1:5])), phylobase:::formatData(phy.dup, data.frame(dt=letters[1:5]))) ## matrix data coerced to data.frame (colnames V1, V2) expect_equal(phylobase:::formatData(phy.dup, matrix(1:10, ncol=2)), phylobase:::formatData(phy.dup, data.frame(V1=1:5, V2=6:10))) ## matrix data coerced to data.frame (colname as given) expect_equal(phylobase:::formatData(phy.dup, matrix(1:10, ncol=2, dimnames=list(NULL, c("a", "b")))), phylobase:::formatData(phy.dup, data.frame(a=1:5, b=6:10))) ## error if dt is, say, a phylo4 object expect_error(phylobase:::formatData(phy.dup, phy.dup)) # # matching options # ## don't match (purely positional) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:5, row.names=rev(nid.tip)), type="tip", match.data=FALSE), data.frame(a=c(1:5, rep(NA, 4)), row.names=nid.all)) ## match on rownames (node numbers) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:5, row.names=rev(nid.tip)), type="tip", match.data=TRUE), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:5, row.names=rev(nid.tip)), type="tip"), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) ## match on rownames (labels) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=c(1,3,4,5), row.names=rev(lab.tip[-2])), type="tip", match.data=TRUE), data.frame(a=c(5,5,4,3,1, rep(NA, 4)), row.names=nid.all)) ## match on rownames (mixed node numbers and labels) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=c(1,2,3,4,5), row.names=c(rev(lab.tip)[1:3], rev(nid.tip)[4:5])), type="tip", match.data=TRUE), data.frame(a=c(5,4,3,2,1, rep(NA, 4)), row.names=nid.all)) ## but fails if rownamesAsLabels is TRUE expect_error(phylobase:::formatData(phy.dup, data.frame(a=1:5, row.names=c(rev(lab.tip)[1:3], rev(nid.tip)[4:5])), type="tip", match.data=TRUE, rownamesAsLabels=TRUE)) ## ## label.type="column" and label.column=2 ## ## should ignore label (purely positional) and retain a label col expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:5, lab=rev(nid.tip)), type="tip", match.data=FALSE, label.type="column", label.column=2), data.frame(a=c(1:5, rep(NA, 4)), lab=c(rev(nid.tip), rep(NA, 4)), row.names=nid.all)) ## match on label column (node numbers) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:5, lab=rev(nid.tip)), type="tip", match.data=TRUE, label.type="column", label.column=2), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:5, lab=rev(nid.tip)), type="tip", label.type="column", label.column=2), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) ## match on label column (labels) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:4, lab=rev(lab.tip[-2])), type="tip", match.data=TRUE, label.type="column", label.column=2), data.frame(a=as.integer(c(4, 4:1, rep(NA, 4))), row.names=nid.all)) ## match on label column (mixed node numbers and labels) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:5, lab=c(rev(lab.tip)[1:3], rev(nid.tip)[4:5])), type="tip", match.data=TRUE, label.type="column", label.column=2), data.frame(a=c(5:1, rep(NA, 4)), row.names=nid.all)) ## but fails if rownamesAsLabels is TRUE expect_error(phylobase:::formatData(phy.dup, data.frame(a=1:5, lab=c(rev(lab.tip)[1:3], rev(nid.tip)[4:5])), type="tip", match.data=TRUE, rownamesAsLabels=TRUE, label.type="column", label.column=2)) ## try to match internal nodes when type='tips' expect_error(phylobase:::formatData(phy.dup, data.frame(a=1:5, row.names=4:8), type="tip")) ## and vice versa expect_error(phylobase:::formatData(phy.dup, data.frame(a=6:9, row.names=1:4), type="internal")) ## ## missing.data ## ## force error conditions expect_error(phylobase:::formatData(phy.dup, data.frame(a=1:3), type="tip")) expect_error(phylobase:::formatData(phy.dup, data.frame(a=1:3), type="tip", missing.data="fail")) expect_warning(phylobase:::formatData(phy.dup, data.frame(a=1:3), type="tip", missing.data="warn")) ## missing data with matching expect_equal(phylobase:::formatData(phy.dup, data.frame(a=rev(nid.tip)[-1], row.names=rev(nid.tip)[-1]), type="tip", missing.data="OK"), data.frame(a=c(nid.tip[-5], rep(NA, 5)))) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=rev(nid.int)[-1], row.names=rev(nid.int)[-1]), type="internal", missing.data="OK"), data.frame(a=c(rep(NA, 5), nid.int[-4], NA))) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=rev(nid.all)[-1], row.names=rev(nid.all)[-1]), type="all", missing.data="OK"), data.frame(a=c(nid.all[-9], NA))) ## missing data without matching expect_equal(phylobase:::formatData(phy.dup, data.frame(a=rev(nid.tip)[-1]), type="tip", match.data=FALSE, missing.data="OK"), data.frame(a=c(rev(nid.tip)[-1], rep(NA, 5)))) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=rev(nid.int)[-1]), type="internal", match.data=FALSE, missing.data="OK"), data.frame(a=c(rep(NA, 5), rev(nid.int)[-1], NA))) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=rev(nid.all)[-1]), type="all", match.data=FALSE, missing.data="OK"), data.frame(a=c(rev(nid.all)[-1], NA))) ## ## extra.data ## ## force error conditions expect_error(phylobase:::formatData(phy.dup, data.frame(a=1:3), type="tip", missing.data="fail")) expect_warning(phylobase:::formatData(phy.dup, data.frame(a=0:5, row.names=0:5), type="tip", missing="warn")) expect_warning(phylobase:::formatData(phy.dup, data.frame(a=0:5, row.names=0:5), type="tip")) ## extra data with matching expect_equal(phylobase:::formatData(phy.dup, data.frame(a=c(0L, rev(nid.tip)), row.names=c(0, rev(nid.tip))), type="tip", extra.data="OK"), data.frame(a=c(nid.tip, rep(NA, 4)))) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=c(0L, rev(nid.int)), row.names=c(0, rev(nid.int))), type="internal", extra.data="OK"), data.frame(a=c(rep(NA, 5), nid.int))) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=c(0L, rev(nid.all)), row.names=c(0, rev(nid.all))), type="all", extra.data="OK"), data.frame(a=nid.all)) ## extra data without matching expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:15), type="tip", match.data=FALSE, extra.data="OK"), data.frame(a=c(1:5, rep(NA, 4)))) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:15), type="internal", match.data=FALSE, extra.data="OK"), data.frame(a=c(rep(NA, 5), 1:4))) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:15), type="all", match.data=FALSE, extra.data="OK"), data.frame(a=c(1:9))) ## allow both extra.data and missing.data expect_equal(phylobase:::formatData(phy.dup, data.frame(a=0:3, row.names=0:3), type="tip", extra.data="OK", missing.data="OK"), data.frame(a=c(1:3, rep(NA, 6)))) ## ## keep.all ## ## keep all rows expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:5, row.names=nid.tip), type="tip", keep.all=TRUE), data.frame(a=c(1:5, rep(NA, 4)), row.names=nid.all)) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:5, row.names=nid.tip), type="tip"), data.frame(a=c(1:5, rep(NA, 4)), row.names=nid.all)) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=6:9, row.names=nid.int), type="internal", keep.all=TRUE), data.frame(a=c(rep(NA, 5), 6:9), row.names=nid.all)) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=6:9, row.names=nid.int), type="internal"), data.frame(a=c(rep(NA, 5), 6:9), row.names=nid.all)) ## only keep 'type' rows expect_equal(phylobase:::formatData(phy.dup, data.frame(a=1:5, row.names=nid.tip), type="tip", keep.all=FALSE), data.frame(a=c(1:5), row.names=nid.tip)) expect_equal(phylobase:::formatData(phy.dup, data.frame(a=6:9, row.names=nid.int), type="internal", keep.all=FALSE), data.frame(a=c(6:9), row.names=nid.int)) ## restoring default options phylobase.options(op) }) phylobase/tests/testthat/test.readNCL.R0000644000176200001440000007035212552722142017624 0ustar liggesusers# # --- Test readNCL.R --- # ### Get all the test files if (Sys.getenv("RCMDCHECK") == FALSE) { pth <- file.path(getwd(), "..", "inst", "nexusfiles") } else { pth <- system.file(package="phylobase", "nexusfiles") } ## co1.nex -- typical output from MrBayes. Contains 2 identical trees, the first ## one having posterior probabilities as node labels co1File <- file.path(pth, "co1.nex") ## MultiLineTrees.nex -- 2 identical trees stored on several lines multiLinesFile <- file.path(pth, "MultiLineTrees.nex") ## treeWithDiscreteData.nex -- Mesquite file with discrete data treeDiscDt <- file.path(pth, "treeWithDiscreteData.nex") ## treeWithPolyExcludedData.nex -- Mesquite file with polymorphic and excluded ## characters treePolyDt <- file.path(pth, "treeWithPolyExcludedData.nex") ## treeWithContinuousData.nex -- Mesquite file with continuous characters treeContDt <- file.path(pth, "treeWithContinuousData.nex") ## treeWithDiscAndContData.nex -- Mesquite file with both discrete and ## continuous data treeDiscCont <- file.path(pth, "treeWithDiscAndContData.nex") ## noStateLabels.nex -- Discrete characters with missing state labels noStateLabels <- file.path(pth, "noStateLabels.nex") ## Newick trees newick <- file.path(pth, "newick.tre") ## Test with trees that don't include all the taxa listed in TAXA block treeSubset <- file.path(pth, "testSubsetTaxa.nex") ## Contains representation of data associated with continuous data ExContDataFile <- file.path(pth, "ExContData.Rdata") stopifnot(file.exists(co1File)) stopifnot(file.exists(treeDiscDt)) stopifnot(file.exists(multiLinesFile)) stopifnot(file.exists(treePolyDt)) stopifnot(file.exists(treeContDt)) stopifnot(file.exists(treeDiscCont)) stopifnot(file.exists(ExContDataFile)) stopifnot(file.exists(noStateLabels)) stopifnot(file.exists(treeSubset)) op <- phylobase.options() ## function (file, simplify=TRUE, type=c("all", "tree", "data"), ## char.all=FALSE, polymorphic.convert=TRUE, levels.uniform=TRUE, ## check.node.labels=c("keep", "drop", "asdata")) ## ########### CO1 -- MrBayes file -- tree only ## Tree properties ## Labels labCo1 <- c("Cow", "Seal", "Carp", "Loach", "Frog", "Chicken", "Human", "Mouse", "Rat", "Whale", NA, NA, NA, NA, NA, NA, NA, NA) names(labCo1) <- 1:18 ## Edge lengths eLco1 <- c(0.143336, 0.225087, 0.047441, 0.055934, 0.124549, 0.204809, 0.073060, 0.194575, 0.171296, 0.222039, 0.237101, 0.546258, 0.533183, 0.154442, 0.134574, 0.113163, 0.145592) names(eLco1) <- c("11-1", "11-2", "11-12", "12-13", "13-14", "14-15", "15-16", "16-17", "17-3", "17-4", "16-5", "15-6", "14-7", "13-18", "18-8", "18-9", "12-10") ## Node types nTco1 <- c("tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "internal", "internal", "internal", "internal", "internal", "internal", "internal", "internal") names(nTco1) <- 1:18 ## Label values lVco1 <- c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.93, 0.88, 0.99, 1.00, 0.76, 1.00, 1.00) context("readNCL can deal with simple NEXUS files (tree only)") test_that("file with 2 trees (warning normal)", { ## Read trees co1 <- suppressWarnings(readNCL(file=co1File, check.node.labels="asdata")) ## Tree 1 co1Tree1 <- co1[[1]] edgeNm <- paste(edges(co1Tree1)[, "ancestor"], edges(co1Tree1)[, "descendant"], sep = "-") expect_equal(labels(co1Tree1), labCo1) # check labels expect_equal(edgeLength(co1Tree1), eLco1[edgeNm]) # check edge lengths expect_equal(nodeType(co1Tree1), nTco1) # check node types expect_equal(as(co1Tree1, "data.frame")$labelValues, lVco1) # check label value ## Tree 2 co1Tree2 <- co1[[2]] expect_equal(labels(co1Tree2), labCo1) # check labels expect_equal(edgeLength(co1Tree2), eLco1[edgeNm]) # check edge lengths expect_equal(nodeType(co1Tree2), nTco1) # check node types }) test_that("test option simplify", { ## Check option simplify co1 <- readNCL(file=co1File, check.node.labels="asdata", simplify=TRUE) edgeNm <- paste(edges(co1)[, "ancestor"], edges(co1)[, "descendant"], sep = "-") expect_equal(length(co1), as.integer(1)) # make sure there is only one tree expect_equal(labels(co1), labCo1) # check labels expect_equal(edgeLength(co1), eLco1[edgeNm]) # check edge lengths expect_equal(nodeType(co1), nTco1) # check node type expect_equal(as(co1, "data.frame")$labelValues, lVco1) # check label values }) test_that("test option check.node.labels", { ## Check option check.node.labels phylobase.options(allow.duplicated.labels="fail") expect_error(readNCL(file=co1File, check.node.labels="keep")) # fail because labels aren't unique phylobase.options(op) phylobase.options(allow.duplicated.labels="ok") co1 <- readNCL(file=co1File, check.node.labels="keep", simplify=TRUE) expect_equal(nodeLabels(co1), setNames(c(NA, "0.93", "0.88", "0.99", "1.00", "0.76", "1.00", "1.00"), 11:18)) phylobase.options(op) co1 <- readNCL(file=co1File, check.node.labels="drop", simplify=TRUE) edgeNm <- paste(edges(co1)[, "ancestor"], edges(co1)[, "descendant"], sep = "-") expect_equal(labels(co1), labCo1) # check labels expect_equal(edgeLength(co1), eLco1[edgeNm]) # check edge lengths expect_equal(nodeType(co1), nTco1) # check node type expect_equal(as(co1, "data.frame")$labelValues, NULL) # check label values don't exist }) test_that("labelled root", { tmp_file <- tempfile() cat("(A:0.1,B:0.2,(C:0.3,D:0.4)E:0.5)F;", file = tmp_file) ape_tree <- as(ape::read.tree(file = tmp_file), "phylo4") ph4_tree <- readNewick(file = tmp_file) expect_equal(tipLabels(ape_tree), tipLabels(ph4_tree)) expect_equal(nodeLabels(ape_tree), nodeLabels(ph4_tree)) expect_equal(sort(edgeLength(ape_tree)), sort(edgeLength(ape_tree))) }) test_that("readNCL can handle multi line files", { ## ########### Mutli Lines -- tree only multiLines <- readNCL(file=multiLinesFile) ## load correct representation and make sure that the trees read ## match it ml <- rncl::read_nexus_phylo(file = multiLinesFile) ml1 <- as(ml[[1]], "phylo4") ml2 <- as(ml[[2]], "phylo4") expect_equal(tipLabels(multiLines[[1]]), tipLabels(ml1)) expect_equal(tipLabels(multiLines[[2]]), tipLabels(ml2)) expect_equivalent(sort(edgeLength(multiLines[[1]])), sort(edgeLength(ml1))) expect_equivalent(sort(edgeLength(multiLines[[2]])), sort(edgeLength(ml2))) expect_equal(nodeType(multiLines[[1]]), nodeType(ml1)) expect_equal(nodeType(multiLines[[2]]), nodeType(ml2)) }) ## ########### Tree + data -- file from Mesquite context("readNCL can handle files with tree & data") ## tree properties labTr <- c("Myrmecocystussemirufus", "Myrmecocystusplacodops", "Myrmecocystusmendax", "Myrmecocystuskathjuli", "Myrmecocystuswheeleri", "Myrmecocystusmimicus", "Myrmecocystusdepilis", "Myrmecocystusromainei", "Myrmecocystusnequazcatl", "Myrmecocystusyuma", "Myrmecocystuskennedyi", "Myrmecocystuscreightoni", "Myrmecocystussnellingi", "Myrmecocystustenuinodis", "Myrmecocystustestaceus", "Myrmecocystusmexicanus", "Myrmecocystuscfnavajo", "Myrmecocystusnavajo", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA) names(labTr) <- 1:35 eTr <- c(NA, 1.699299, 12.300701, 0.894820, 0.836689, 10.569191, 4.524387, 6.044804, 0.506099, 0.198842, 0.689044, 4.650818, 2.926053, 1.724765, 1.724765, 4.255993, 1.083870, 1.083870, 0.802512, 2.027251, 2.708942, 2.708942, 0.284767, 4.451425, 2.257581, 2.193845, 2.193845, 8.635503, 2.770378, 2.770378, 8.275077, 5.724923, 2.855375, 2.869547, 2.869547) names(eTr) <- c("0-19", "19-20", "20-15", "20-21", "21-22", "22-12", "22-23", "23-11", "23-24", "24-25", "25-26", "26-3", "26-27", "27-1", "27-2", "25-28", "28-4", "28-5", "24-29", "29-30", "30-6", "30-7", "29-31", "31-10", "31-32", "32-8", "32-9", "21-33", "33-13", "33-14", "19-34", "34-16", "34-35", "35-17", "35-18") nTtr <- c("tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "tip", "root", "internal", "internal", "internal", "internal", "internal", "internal", "internal", "internal", "internal", "internal", "internal", "internal", "internal", "internal", "internal", "internal") names(nTtr) <- 1:35 ## data to test against dtTest1 <- data.frame(time = factor(c(2,1,0,0,0,0,2,0,2,0,0,0,0,1,1,1,0,1)), subgenus = factor(c(2,1,0,0,0,0,2,0,2,0,0,0,0,1,1,2,0,1))) row.names(dtTest1) <- c("Myrmecocystuscfnavajo","Myrmecocystuscreightoni", "Myrmecocystusdepilis","Myrmecocystuskathjuli", "Myrmecocystuskennedyi","Myrmecocystusmendax", "Myrmecocystusmexicanus","Myrmecocystusmimicus", "Myrmecocystusnavajo","Myrmecocystusnequazcatl", "Myrmecocystusplacodops","Myrmecocystusromainei", "Myrmecocystussemirufus","Myrmecocystussnellingi", "Myrmecocystustenuinodis","Myrmecocystustestaceus", "Myrmecocystuswheeleri","Myrmecocystusyuma") dtTest2 <- dtTest1 levels(dtTest2$time) <- c("diurnal", "crepuscular", "nocturnal") levels(dtTest2$subgenus) <- c("Endiodioctes", "Eremnocystus", "Myrmecocystus") p4 <- "phylo4" p4d <- "phylo4d" attributes(p4) <- attributes(p4d) <- list(package="phylobase") test_that("readNCL can deal with the tree only", { ## Tree only tr <- readNCL(file=treeDiscDt, type="tree") tr2 <- rncl::read_nexus_phylo(file = treeDiscDt) tr2 <- as(tr2, "phylo4") expect_equal(labels(tr), labTr) # check labels expect_equal(nodeType(tr), nTtr) # check node types expect_equal(class(tr), p4) # check class expect_equal(edgeLength(tr), edgeLength(tr2)[names(edgeLength(tr))]) }) test_that("readNCL can deal with data only", { ## Data only dt1 <- readNCL(file=treeDiscDt, type="data", return.labels=FALSE, levels.uniform=FALSE) expect_equal(dt1, dtTest1) dt2 <- readNCL(file=treeDiscDt, type="data", return.labels=TRUE, levels.uniform=FALSE) expect_equal(dt2, dtTest2) }) test_that("readNCL can deal with tree + data", { ## Tree + Data trDt1 <- readNCL(file=treeDiscDt, type="all", return.labels=FALSE, levels.uniform=FALSE) expect_equal(labels(trDt1), labTr) # check labels expect_equivalent(sort(edgeLength(trDt1)), sort(eTr)) # check edge lengths expect_equal(nodeType(trDt1), nTtr) # check node types expect_equal(class(trDt1), p4d) # check class expect_equal(tdata(trDt1, type="tip")[rownames(dtTest1), ], dtTest1) trDt2 <- readNCL(file=treeDiscDt, type="all", return.labels=TRUE, levels.uniform=FALSE) expect_equal(labels(trDt2), labTr) # check labels expect_equivalent(sort(edgeLength(trDt2)), sort(eTr)) # check edge lengths expect_equal(nodeType(trDt2), nTtr) # check node types expect_equal(class(trDt2), p4d) # check class expect_equal(tdata(trDt2, type="tip")[rownames(dtTest2), ], dtTest2) }) ## ########## Tree + Data -- Test for polymorphic.convert, levels.uniform and char.all ## data to test against ## dtTest 3 -- levels.uniform=FALSE, return.labels=FALSE, polymorphic.convert=FALSE dtPoly1 <- data.frame(Test1=factor(c(0,0,1,1,0,NA,1,1,1,0,0,NA,1,1,NA,0,1, NA)), Test2=factor(c(0,0,0,0,0,NA,0,1,0,1,1,"{0,1}",NA,0,NA,0,"{0,1}",1)), Test3=factor(c(1,1,1,0,0,0,2,"{0,1,2}",0,NA,0,"{0,1}",0,1,0,0,"{0,1,2}",1)), row.names=c("Myrmecocystussemirufus","Myrmecocystusplacodops", "Myrmecocystusmendax","Myrmecocystuskathjuli", "Myrmecocystuswheeleri","Myrmecocystusmimicus", "Myrmecocystusdepilis","Myrmecocystusromainei", "Myrmecocystusnequazcatl","Myrmecocystusyuma", "Myrmecocystuskennedyi","Myrmecocystuscreightoni", "Myrmecocystussnellingi","Myrmecocystustenuinodis", "Myrmecocystustestaceus","Myrmecocystusmexicanus", "Myrmecocystuscfnavajo","Myrmecocystusnavajo")) ## dtPoly2 -- levels.uniform=FALSE, return.labels=FALSE, polymorphic.convert=TRUE dtPoly2 <- dtPoly1 dtPoly2[c(12,17),2] <- NA dtPoly2[c(8,12,17),3] <- NA dtPoly2$Test1 <- factor(dtPoly2$Test1) dtPoly2$Test2 <- factor(dtPoly2$Test2) dtPoly2$Test3 <- factor(dtPoly2$Test3) ## dtPoly3 -- levels.uniform=FALSE, return.labels=TRUE, polymorphic.convert=TRUE dtPoly3 <- dtPoly2 levels(dtPoly3$Test1) <- c("test1A", "test1B") levels(dtPoly3$Test2) <- c("test2A", "test2B") levels(dtPoly3$Test3) <- c("test3A", "test3B", "test3C") ## dtPoly4 -- levels.uniform=FALSE, return.labels=TRUE, polymorphic.convert=FALSE ## not yet implemented ## dtPoly5 -- levels.uniform=TRUE, return.labels=FALSE, polymorphic.convert=FALSE dtPoly5 <- dtPoly1 levels(dtPoly5$Test1) <- levels(dtPoly5$Test2) <- levels(dtPoly5$Test3) <- union(levels(dtPoly1$Test1), c(levels(dtPoly1$Test2), levels(dtPoly1$Test3))) ## dtPoly6 -- levels.uniform=TRUE, return.labels=FALSE, polymorphic.convert=TRUE dtPoly6 <- dtPoly2 levels(dtPoly6$Test1) <- levels(dtPoly6$Test2) <- levels(dtPoly6$Test3) <- union(levels(dtPoly2$Test1), c(levels(dtPoly2$Test2), levels(dtPoly2$Test3))) ## dtPoly7 -- levels.uniform=TRUE, return.labels=TRUE, polymorphic.convert=FALSE ## not yet implemented ## dtPoly8 -- levels.uniform=TRUE, return.labels=TRUE, polymorphic.convert=TRUE dtPoly8 <- dtPoly3 levels(dtPoly8$Test1) <- levels(dtPoly8$Test2) <- levels(dtPoly8$Test3) <- union(levels(dtPoly3$Test1), c(levels(dtPoly3$Test2), levels(dtPoly3$Test3))) ## dtPoly5F -- char.all=FALSE, levels.uniform=TRUE, return.labels=FALSE, polymorphic.convert=FALSE dtPoly5F <- dtPoly1[, 1:2] levels(dtPoly5F$Test1) <- levels(dtPoly5F$Test2) <- union(levels(dtPoly1$Test1), levels(dtPoly1$Test2)) ## dtPoly6F -- char.all=FALSE, levels.uniform=TRUE, return.labels=FALSE, polymorphic.convert=TRUE dtPoly6F <- dtPoly2[, 1:2] levels(dtPoly6F$Test1) <- levels(dtPoly6F$Test2) <- union(levels(dtPoly2$Test1), levels(dtPoly2$Test2)) ## dtPoly8F -- char.all=FALSE, levels.uniform=TRUE, return.labels=TRUE, polymorphic.convert=TRUE dtPoly8F <- dtPoly3[, 1:2] levels(dtPoly8F$Test1) <- levels(dtPoly8F$Test2) <- union(levels(dtPoly3$Test1), levels(dtPoly3$Test2)) test_that("char.all=TRUE, levels.uniform=FALSE, return.labels=FALSE, polymorphic.convert=FALSE", { trChr1 <- readNCL(file=treePolyDt, type="all", polymorphic.convert=FALSE, levels.uniform=FALSE, char.all=TRUE, return.labels=FALSE) expect_equal(labels(trChr1), labTr) # check labels expect_equivalent(sort(edgeLength(trChr1)), sort(eTr)) # check edge lengths expect_equal(nodeType(trChr1), nTtr) # check node types expect_equal(class(trChr1), p4d) # check class expect_equal(tdata(trChr1, "tip"), dtPoly1[tipLabels(trChr1), ]) }) test_that("char.all=TRUE, levels.uniform=FALSE, return.labels=FALSE, polymorphic.convert=TRUE", { trChr2 <- readNCL(file=treePolyDt, type="all", polymorphic.convert=TRUE, levels.uniform=FALSE, return.labels=FALSE, char.all=TRUE) expect_equal(labels(trChr2), labTr) # check labels expect_equivalent(sort(edgeLength(trChr2)), sort(eTr)) # check edge lengths expect_equal(nodeType(trChr2), nTtr) # check node types expect_equal(class(trChr2), p4d) # check class expect_equal(tdata(trChr2, "tip"), dtPoly2[tipLabels(trChr2), ]) }) test_that("char.all=TRUE, levels.uniform=FALSE, return.labels=TRUE, polymorphic.convert=TRUE", { trChr3 <- readNCL(file=treePolyDt, type="all", polymorphic.convert=TRUE, levels.uniform=FALSE, char.all=TRUE, return.labels=TRUE) expect_equal(labels(trChr3), labTr) # check labels expect_equivalent(sort(edgeLength(trChr3)), sort(eTr)) # check edge lengths expect_equal(nodeType(trChr3), nTtr) # check node types expect_equal(class(trChr3), p4d) # check class expect_equal(tdata(trChr3, "tip"), dtPoly3[tipLabels(trChr3), ]) }) test_that("char.all=TRUE, levels.uniform=FALSE, return.labels=TRUE, polymorphic.convert=FALSE is not yet implemented", { ## trChr4 <- expect_error(readNCL(file=treePolyDt, type="all", levels.uniform=FALSE, return.labels=TRUE, polymorphic.convert=FALSE)) }) test_that("char.all=TRUE, levels.uniform=TRUE, return.labels=FALSE, polymorphic.convert=FALSE", { trChr5 <- readNCL(file=treePolyDt, type="all", polymorphic.convert=FALSE, levels.uniform=TRUE, char.all=TRUE, return.labels=FALSE) expect_equal(labels(trChr5), labTr) # check labels expect_equivalent(sort(edgeLength(trChr5)), sort(eTr)) # check edge lengths expect_equal(nodeType(trChr5), nTtr) # check node types expect_equal(class(trChr5), p4d) # check class expect_equal(tdata(trChr5, "tip"), dtPoly5[tipLabels(trChr5), ]) }) test_that("char.all=TRUE, levels.uniform=TRUE, return.labels=FALSE, polymorphic.convert=TRUE", { trChr6 <- readNCL(file=treePolyDt, type="all", polymorphic.convert=TRUE, levels.uniform=TRUE, char.all=TRUE, return.labels=FALSE) expect_equal(labels(trChr6), labTr) # check labels expect_equivalent(sort(edgeLength(trChr6)), sort(eTr)) # check edge lengths expect_equal(nodeType(trChr6), nTtr) # check node types expect_equal(class(trChr6), p4d) # check class expect_equal(tdata(trChr6, "tip"), dtPoly6[tipLabels(trChr6), ]) }) test_that("char.all=TRUE, levels.uniform=TRUE, return.labels=TRUE, polymorphic.convert=FALSE is not yet implemented", { ## trChr7 <- expect_error(readNCL(file=treePolyDt, type="all", char.all=TRUE, levels.uniform=TRUE, return.labels=TRUE, polymorphic.convert=FALSE)) }) test_that("char.all=TRUE, levels.uniform=TRUE, return.labels=TRUE, polymorphic.convert=TRUE", { trChr8 <- readNCL(file=treePolyDt, type="all", char.all=TRUE, levels.uniform=TRUE, return.labels=TRUE, polymorphic.convert=TRUE) expect_equal(labels(trChr8), labTr) # check labels expect_equivalent(sort(edgeLength(trChr8)), sort(eTr)) # check edge lengths expect_equal(nodeType(trChr8), nTtr) # check node types expect_equal(class(trChr8), p4d) # check class expect_equal(tdata(trChr8, "tip"), dtPoly8[tipLabels(trChr8), ]) }) ## -- with char.all=FALSE test_that("char.all=FALSE, levels.uniform=FALSE, return.labels=FALSE, polymorphic.convert=FALSE", { trChr1F <- readNCL(file=treePolyDt, type="all", polymorphic.convert=FALSE, levels.uniform=FALSE, char.all=FALSE, return.labels=FALSE) expect_equal(labels(trChr1F), labTr) # check labels expect_equivalent(sort(edgeLength(trChr1F)), sort(eTr)) # check edge lengths expect_equal(nodeType(trChr1F), nTtr) # check node types expect_equal(class(trChr1F), p4d) # check class expect_equal(tdata(trChr1F, "tip"), dtPoly1[tipLabels(trChr1F), 1:2]) }) test_that("char.all=FALSE, levels.uniform=FALSE, return.labels=FALSE, polymorphic.convert=TRUE", { trChr2F <- readNCL(file=treePolyDt, type="all", polymorphic.convert=TRUE, levels.uniform=FALSE, return.labels=FALSE, char.all=FALSE) expect_equal(labels(trChr2F), labTr) # check labels expect_equivalent(sort(edgeLength(trChr2F)), sort(eTr)) # check edge lengths expect_equal(nodeType(trChr2F), nTtr) # check node types expect_equal(class(trChr2F), p4d) # check class expect_equal(tdata(trChr2F, "tip"), dtPoly2[tipLabels(trChr2F), 1:2]) }) test_that("char.all=FALSE, levels.uniform=FALSE, return.labels=TRUE, polymorphic.convert=TRUE", { trChr3F <- readNCL(file=treePolyDt, type="all", polymorphic.convert=TRUE, levels.uniform=FALSE, char.all=FALSE, return.labels=TRUE) expect_equal(labels(trChr3F), labTr) # check labels expect_equivalent(sort(edgeLength(trChr3F)), sort(eTr)) # check edge lengths expect_equal(nodeType(trChr3F), nTtr) # check node types expect_equal(class(trChr3F), p4d) # check class expect_equal(tdata(trChr3F, "tip"), dtPoly3[tipLabels(trChr3F), 1:2]) }) test_that("char.all=FALSE, levels.uniform=FALSE, return.labels=TRUE, polymorphic.convert=FALSE is not yet implemented", { ## trChr4F <- expect_error(readNCL(file=treePolyDt, type="all", levels.uniform=FALSE, return.labels=TRUE, polymorphic.convert=FALSE)) }) test_that("char.all=FALSE, levels.uniform=TRUE, return.labels=FALSE, polymorphic.convert=FALSE", { trChr5F <- readNCL(file=treePolyDt, type="all", polymorphic.convert=FALSE, levels.uniform=TRUE, char.all=FALSE, return.labels=FALSE) expect_equal(labels(trChr5F), labTr) # check labels expect_equivalent(sort(edgeLength(trChr5F)), sort(eTr)) # check edge lengths expect_equal(nodeType(trChr5F), nTtr) # check node types expect_equal(class(trChr5F), p4d) # check class expect_equal(tdata(trChr5F, "tip"), dtPoly5F[tipLabels(trChr5F), ]) }) test_that("char.all=FALSE, levels.uniform=TRUE, return.labels=FALSE, polymorphic.convert=TRUE", { trChr6F <- readNCL(file=treePolyDt, type="all", polymorphic.convert=TRUE, levels.uniform=TRUE, char.all=FALSE, return.labels=FALSE) expect_equal(labels(trChr6F), labTr) # check labels expect_equivalent(sort(edgeLength(trChr6F)), sort(eTr)) # check edge lengths expect_equal(nodeType(trChr6F), nTtr) # check node types expect_equal(class(trChr6F), p4d) # check class expect_equal(tdata(trChr6F, "tip"), dtPoly6F[tipLabels(trChr6F), ]) }) test_that("char.all=FALSE, levels.uniform=TRUE, return.labels=TRUE, polymorphic.convert=FALSE is not yet implemented", { ## trChr7F <- expect_error(readNCL(file=treePolyDt, type="all", char.all=FALSE, levels.uniform=TRUE, return.labels=TRUE, polymorphic.convert=FALSE)) }) test_that("char.all=FALSE, levels.uniform=TRUE, return.labels=TRUE, polymorphic.convert=TRUE", { trChr8F <- readNCL(file=treePolyDt, type="all", char.all=FALSE, levels.uniform=TRUE, return.labels=TRUE, polymorphic.convert=TRUE) expect_equal(labels(trChr8F), labTr) # check labels expect_equivalent(sort(edgeLength(trChr8F)), sort(eTr)) # check edge lengths expect_equal(nodeType(trChr8F), nTtr) # check node types expect_equal(class(trChr8F), p4d) # check class expect_equal(tdata(trChr8F, "tip"), dtPoly8F[tipLabels(trChr8F), ]) }) ## ########## Tree + Data -- test with continuous Characters test_that("test of readNCL with tree data, with continuous characters", { DtCont <- readNCL(file=treeContDt, type="data") trDtCont <- readNCL(file=treeContDt, type="all") load(ExContDataFile) expect_equal(DtCont, ExContData[rownames(DtCont), ]) expect_equal(tdata(trDtCont, "tip"), ExContData[tipLabels(trDtCont), ]) expect_equal(labels(trDtCont), labTr) # check labels expect_equivalent(sort(edgeLength(trDtCont)), sort(eTr)) # check edge lengths expect_equal(nodeType(trDtCont), nTtr) # check node types expect_equal(class(trDtCont), p4d) # check class }) ## ########## Tree + Data -- both types (Discrete & Continuous) test_that("tree + data for both types (discrete & continuous)", { dtDiscCont <- readNCL(file=treeDiscCont, type="data", levels.uniform=FALSE) trDtDiscCont <- readNCL(file=treeDiscCont, type="all", levels.uniform=FALSE) load(ExContDataFile) dtDiscContTest <- cbind(ExContData, dtTest2[rownames(ExContData), ]) expect_equal(dtDiscCont, dtDiscContTest[rownames(dtDiscCont), ]) expect_equal(tdata(trDtDiscCont, "tip"), dtDiscContTest[tipLabels(trDtDiscCont), ]) expect_equal(labels(trDtDiscCont), labTr) # check labels expect_equivalent(sort(edgeLength(trDtDiscCont)), sort(eTr)) # check edge lengths expect_equal(nodeType(trDtDiscCont), nTtr) # check node types expect_equal(class(trDtDiscCont), p4d) # check class }) ## ########### Check for proper handling of missing files test_that("readNCL can handle missing files", { expect_error(readNCL(file="foo.bar"), regexp="doesn't exist") }) ## ########### Check behavior in case of missing state labels test_that("readNCL warns in case of missing state labels", { expect_warning(readNCL(file=noStateLabels, return.labels=TRUE), regexp="state labels are missing") }) test_that("readNCL warns in case of missing state labels", { expect_warning(dtNoSt <- readNCL(file=noStateLabels, type="data", return.labels=TRUE), regexp="state labels are missing") expect_equal(dtNoSt$char1, factor(c(1,2,0,1))) }) ## ########### Newick files context("test with Newick files") ## Tree representation labNew <- c("a", "b", "c", NA, NA) names(labNew) <- 1:5 eLnew <- c(NA, 1, 4, 2, 3) names(eLnew) <- c("0-4", "4-1", "4-5", "5-2", "5-3") nTnew <- c("tip", "tip", "tip", "root", "internal") names(nTnew) <- 1:5 test_that("check.node.labels='drop' with readNCL", { newTr <- readNCL(file=newick, file.format="newick", check.node.labels="drop") expect_equal(labels(newTr), labNew) expect_equivalent(sort(edgeLength(newTr)), sort(eLnew)) expect_equal(nodeType(newTr), nTnew) }) test_that("check.node.labels='drop' with readNewick", { newTr <- readNewick(file=newick, check.node.labels="drop") expect_equal(labels(newTr), labNew) expect_equivalent(sort(edgeLength(newTr)), sort(eLnew)) expect_equal(nodeType(newTr), nTnew) }) test_that("check.node.labels='asdata' with readNCL", { newTr <- readNCL(file=newick, file.format="newick", check.node.labels="asdata") expect_equal(labels(newTr), labNew) expect_equal(tdata(newTr)$labelValues, factor(c(NA, NA, NA, "yy", "xx"))) }) test_that("check.node.labels='asdata' with readNewick", { newTr <- readNewick(file=newick, check.node.labels="asdata") expect_equal(labels(newTr), labNew) expect_equal(tdata(newTr)$labelValues, factor(c(NA, NA, NA, "yy", "xx"))) }) test_that("check.node.labels='keep' with readNCL", { labNew[4:5] <- c("yy", "xx") newTr <- readNCL(file=newick, file.format="newick", check.node.labels="keep") expect_equal(labels(newTr), labNew) }) test_that("check.node.labels='keep' with readNewick", { labNew[4:5] <- c("yy", "xx") newTr <- readNewick(file=newick, check.node.labels="keep") expect_equal(labels(newTr), labNew) }) ### Test with files where trees don't include all taxa ------------------------- context("Trees that don't contain all the taxa listed in the TAXA block") test_that("first tree is correct", { tr <- readNexus(file = treeSubset) expect_equivalent(rootNode(tr[[1]]), 6) expect_equivalent(rootNode(tr[[2]]), 6) expect_equivalent(rootNode(tr[[3]]), 7) expect_equivalent(tipLabels(tr[[1]]), c("porifera", "ctenophora", "cnidaria", "deuterostomia", "protostomia")) expect_equivalent(tipLabels(tr[[2]]), c("porifera", "ctenophora", "xeno", "deuterostomia", "protostomia")) expect_equivalent(tipLabels(tr[[3]]), c("deuterostomia", "protostomia", "porifera", "ctenophora", "cnidaria", "xeno")) } ) ### Test roundtrip with Myrmecus file ------------------------------------------ context("Compare output from rncl read file and phylobase") test_that("output from rncl::read_nexus_phylo and readNexus match", { tr_ape <- rncl::read_nexus_phylo(file = treeDiscDt) tr_ph4 <- readNexus(file = treeDiscDt, type = "tree") tr_ape <- as(tr_ape, "phylo4") expect_equal(edges(tr_ape)[order(edges(tr_ape)[, 1]), ], edges(tr_ph4)[order(edges(tr_ph4)[, 1]), ]) expect_equal(edgeLength(tr_ape), edgeLength(tr_ph4)[names(edgeLength(tr_ape))]) expect_equal(labels(tr_ape), labels(tr_ph4)) }) phylobase/tests/testthat/test.tbind.R0000644000176200001440000000016012347155416017450 0ustar liggesusers## # ## # --- Test tbind.R --- ## # ## test.tbind <- function() { ## # function(...,checkData=TRUE) ## } phylobase/tests/testthat/test.methods-oldclasses.R0000644000176200001440000000017112347155416022147 0ustar liggesusers# # --- Test methods-oldclasses.R --- # #test.reorder.phylo <- function() { # # function(x, order = 'cladewise') #} phylobase/tests/testthat/test.treePlot.R0000644000176200001440000000175512353076162020156 0ustar liggesusers## ## --- Test treePlot.R --- ## context("check that treePlot returns warnings when providing incorrectly formatted phylo4d objects.") test_that("phylo4d gives warning when there is no data", { phyd <- phylo4d(ape::rcoal(5), tip.data=data.frame()) expect_warning(plot(phyd), "tree has no tip data to plot") }) test_that("phylo4d gives warning when there is data but they can't be plotted", { phyd <- phylo4d(ape::rcoal(5), tip.data=data.frame(letters[1:5], letters[6:10])) expect_warning(plot(phyd), "only numeric data can be plotted at this time") }) ## test.treePlot <- function() { ## } ## test.plotOneTree <- function() { ## } ## test.phyloXXYY <- function() { ## # function(phy, tip.order = NULL) ## } ## test..bubLegendGrob <- function() { ## } ## test.drawDetails.bubLegend <- function() { ## } ## test.phylobubbles <- function() { ## } ## test.tip.data.plot <- function() { ## } ## test.plot.phylo4 <- function() { ## # signature(x='phylo4', y='missing') ## } phylobase/tests/testthat/test.treewalk.R0000644000176200001440000002552112547532046020176 0ustar liggesusers# # --- Test treewalk.R --- # # Create sample phylo4 tree for testing tr <- read.tree(text="(((spA:0.2,(spB:0.1,spC:0.1):0.15):0.5,spD:0.7):0.2,spE:1):0.4;") phytr <- as(tr, "phylo4") # create phylo4 object with a full complement of valid slots ancestor <- as.integer(c(6,7,7,6,8,0,8,9,9)) descendant <- as.integer(c(7,1,2,8,3,6,9,4,5)) edge <- cbind(ancestor, descendant) nid.tip <- 1:5 nid.int <- 6:9 nid.all <- c(nid.tip, nid.int) lab.tip <- paste("t", nid.tip, sep="") lab.int <- paste("n", nid.int, sep="") lab.all <- c(lab.tip, lab.int) eid <- paste(ancestor, descendant, sep="-") elen <- descendant/10 elab <- paste("e", eid, sep="") phy <- phylo4(x=edge, tip.label=lab.tip, node.label=lab.int, edge.length=elen, edge.label=elab) # create altered version such that each slot is out of order with # respect to all others; methods should be able to handle this phy.alt <- phy phy.alt@label <- rev(phy@label) phy.alt@edge <- phy@edge[c(6:9, 1:5), ] phy.alt@edge.length <- phy@edge.length[c(7:9, 1:6)] phy.alt@edge.label <- phy@edge.label[c(8:9, 1:7)] # update test targets for edge-related slots ancestor <- ancestor[c(6:9, 1:5)] descendant <- descendant[c(6:9, 1:5)] edge <- cbind(ancestor, descendant) eid <- eid[c(6:9, 1:5)] elen <- elen[c(6:9, 1:5)] elab <- elab[c(6:9, 1:5)] #----------------------------------------------------------------------- ## Note: we're not explicitly testing missing="warn" condition below; ## however, if "OK" and "fail" both work as expected, then so must "warn" #test.getNode <- function() { context("getNode") test_that("getNode works when nodes provided only has valid characters", { expect_that(getNode(phytr, "spA"), equals(c(spA=1))) expect_that(getNode(phytr, c("spA", "spC")), equals(c(spA=1, spC=3))) }) test_that("getNode works when nodes provided only has valid integers", { ans <- 4 names(ans) <- "spD" expect_that(getNode(phytr, 4), equals(ans)) ans <- c(4,6) names(ans) <- c("spD", NA) expect_that(getNode(phytr, c(4,6)), equals(ans)) }) test_that("getNode works when node includes only missing characters (names), but missing=OK", { ans <- rep(NA_integer_, 2) # return values should be NA names(ans) <- rep(NA, 2) # return values should have NA names expect_that(getNode(phytr, c("xxx", "yyy"), missing="OK"), equals(ans)) # now missing = "fail" expect_error(getNode(phytr, c("xxx", "yyy"), missing="fail")) }) test_that("getNode works wehn node includes only missing numbers (IDs), but missing=OK", { ans <- rep(NA_integer_, 3) # return values should be NA names(ans) <- rep(NA, 3) # return values should have NA names expect_that(getNode(phytr, c(-9, 0, 50), missing="OK"), equals(ans)) # now missing = "fail" expect_error(getNode(phytr, c(-9, 0, 50), missing="fail")) }) test_that("getNode works when node includes NAs, but missing = \"OK\"", { expect_true(is.na(getNode(phytr, NA_integer_, missing="OK"))) expect_true(is.na(getNode(phytr, NA_character_, missing="OK"))) }) test_that("getNode works when node includes mixture of valid values and NAs", { ans <- c(2, NA) names(ans) <- c("spB", NA) expect_that(getNode(phytr, c("spB", NA), missing="OK"), equals(ans)) expect_that(getNode(phytr, c(2, NA), missing="OK"), equals(ans)) }) test_that("getNode throws exception when node is neither integer-like nor character", expect_error(getNode(phytr, 1.5))) test_that("getNode works even when a tip is labeled as \"0\"", { phyTmp <- phytr tipLabels(phyTmp)[1] <- "0" ans <- 1 names(ans) <- "0" expect_that(getNode(phyTmp, "0"), equals(ans)) }) ## TODO context("ancestor function") ## TODO context("children function") context("descendants function") phytr <- phylo4(read.tree(text="((t3,t4),(t1,(t2,t5)));")) test_that("descendants() works with tips", { expect_identical(descendants(phytr, 5), setNames(5L, "t5")) expect_identical(descendants(phytr, 5, "tips"), setNames(5L, "t5")) expect_identical(descendants(phytr, 5, "children"), setNames(integer(0), character(0))) expect_identical(descendants(phytr, 5, "all"), setNames(5L, "t5")) expect_identical(descendants(phytr, 5, "ALL"), setNames(5L, "t5")) }) test_that("descendants() works when provided with a vector of nodes", { expect_identical(descendants(phytr, 5:7), list("5" = c(t5 = 5L), "6" = c(t3 = 1L, t4 = 2L, t1 = 3L, t2 = 4L, t5 = 5L), "7" = c(t3 = 1L, t4 = 2L))) expect_identical(descendants(phytr, 5:7, "tips"), list("5" = c(t5 = 5L), "6" = c(t3 = 1L, t4 = 2L, t1 = 3L, t2 = 4L, t5 = 5L), "7" = c(t3 = 1L, t4 = 2L))) expect_identical(descendants(phytr, 5:7, "children"), list("5" = setNames(integer(0), character(0)), "6" = setNames(c(7L, 8L), c(NA, NA)), "7" = c(t3 = 1L, t4 = 2L)) ) expect_identical(descendants(phytr, 5:7, "ALL"), list("5" = c(t5 = 5L), "6" = setNames(c(6L, 7L, 1L, 2L, 8L, 3L, 9L, 4L, 5L), c(NA, NA, "t3", "t4", NA, "t1", NA, "t2", "t5")), "7" = setNames(c(7L, 1L, 2L), c(NA, "t3", "t4"))) ) }) test_that("descendants() works with internal nodes", { expect_identical(descendants(phytr, 8), setNames(c(3L, 4L, 5L), c("t1", "t2", "t5"))) expect_identical(descendants(phytr, 8, "tips"), setNames(c(3L, 4L, 5L), c("t1", "t2", "t5"))) expect_identical(descendants(phytr, 8, "children"), setNames(c(3L, 9L), c("t1", NA))) expect_identical(descendants(phytr, 8, "all"), setNames(c(3L, 9L, 4L, 5L), c("t1", NA, "t2", "t5"))) expect_identical(descendants(phytr, 8, "ALL"), setNames(c(8L, 3L, 9L, 4L, 5L), c(NA, "t1", NA, "t2", "t5"))) }) ## TODO siblings # function(phy, node, include.self=FALSE) ## TODO ancestors # function (phy, node, type=c("all","parent","ALL")) ## TODO MRCA # function(phy, ...) ## TODO shortestPath # function(phy, node1, node2) context("test on getEdge with nodes as descendants") ## function(phy, node, type=c("descendant", "ancestor"), ## missing=c("warn", "OK", "fail")) test_that("getEdge works when node only has valid descendants, as characters", { expect_identical(getEdge(phy.alt, "t1"), setNames("7-1", 1)) expect_identical(getEdge(phy.alt, c("t1", "t3")), setNames(c("7-1", "8-3"), c(1,3))) }) test_that("getEdge works when node only has valid descendants, as integers", { expect_identical(getEdge(phy.alt, 1), setNames("7-1", 1)) expect_identical(getEdge(phy.alt, c(1,3)), setNames(c("7-1", "8-3"), c(1,3))) }) test_that("node includes only missing characters (labels), missing=OK", { expect_identical(getEdge(phy.alt, c("x", "y", "z"), missing="OK"), setNames(rep(NA, 3), rep(NA, 3))) }) test_that("node includes only missing characters (labels), missing=fail", { expect_error(getEdge(phy.alt, c("x", "y", "z"), missing="fail")) }) test_that("node includes only missing numbers (IDs), but missing=OK", expect_identical(getEdge(phy.alt, c(-9, 0, 50), missing="OK"), setNames(rep(NA, 3), rep(NA, 3)))) test_that("node includes only missing numbers (IDs), but missing=fail", expect_error(getEdge(phy, c(-9, 0, 50), missing="fail"))) test_that("node includes NAs, but missing = OK", { expect_true(is.na(getEdge(phy, NA_integer_, missing="OK"))) expect_true(is.na(getEdge(phy, NA_character_, missing="OK"))) }) test_that("node includes mixture of valid values and NAs", { expect_identical(getEdge(phy, c("t3", NA), missing="OK"), setNames(c("8-3", NA), c(3, NA))) expect_identical(getEdge(phy, c(3, NA), missing="OK"), setNames(c("8-3", NA), c(3, NA))) }) test_that("node is neither integer-like nor character", { expect_error(getEdge(phy, 1.5)) }) context("test on getEdge with nodes as ancestors") test_that("node only has valid ancestors, as characters", { expect_identical(getEdge(phy.alt, "n6", type="ancestor"), setNames(c("6-7", "6-8"), c(6, 6))) expect_identical(getEdge(phy.alt, c("n6", "n8"), type="ancestor"), setNames(c("6-7", "6-8", "8-9", "8-3"), c(6, 6, 8, 8))) }) test_that("node only has valid ancestors, as integers", { expect_identical(getEdge(phy.alt, 6, type="ancestor"), setNames(c("6-7", "6-8"), c(6, 6))) expect_identical(getEdge(phy.alt, c(6, 8), type="ancestor"), setNames(c("6-7", "6-8", "8-9", "8-3"), c(6, 6, 8, 8))) }) test_that("node includes only missing characters (labels), but missing=OK", { expect_identical(getEdge(phy.alt, c("x", "y", "z"), type="ancestor", missing="OK"), setNames(rep(NA, 3), rep(NA, 3))) }) test_that("node includes only tips (labels), but missing=OK", { expect_identical( getEdge(phy.alt, c("t1", "t3"), type="ancestor", missing="OK"), setNames(rep(NA, 2), c(1, 3))) }) test_that("node includes only tips (labels), now missing = fail", { expect_error(getEdge(phy.alt, c("x", "y", "z"), missing="fail")) expect_error(getEdge(phy.alt, c("t1", "t3"), type="ancestor", missing="fail")) }) test_that("node includes only missing numbers (IDs), but missing=OK", { expect_identical( getEdge(phy.alt, c(-9, 0, 50), type="ancestor", missing="OK"), setNames(rep(NA, 3), rep(NA, 3))) }) test_that("node includes only tips (labels), but missing=OK", { expect_identical( getEdge(phy.alt, c(1, 3), type="ancestor", missing="OK"), setNames(rep(NA, 2), c(1, 3))) }) test_that("node includes only tips (labels), but missing=fail", { expect_error(getEdge(phy.alt, c(-9, 0, 50), missing="fail")) expect_error(getEdge(phy.alt, c(1, 3), type="ancestor", missing="fail")) }) test_that("node includes NAs, but missing = OK", { expect_true(is.na(getEdge(phy.alt, NA_integer_, type="ancestor", missing="OK"))) expect_true(is.na(getEdge(phy.alt, NA_character_, type="ancestor", missing="OK"))) }) test_that("node includes mixture of valid values and NAs", { expect_identical( getEdge(phy.alt, c("t3", "n8", NA), type="ancestor", missing="OK"), setNames(c(NA, "8-9", "8-3", NA), c(3, 8, 8, NA))) expect_identical( getEdge(phy.alt, c(3, 8, NA), type="ancestor", missing="OK"), setNames(c(NA, "8-9", "8-3", NA), c(3, 8, 8, NA))) }) phylobase/tests/testthat/test.checkdata.R0000644000176200001440000000400612347155416020262 0ustar liggesusers# # --- Test checkdata.R --- # if (Sys.getenv("RCMDCHECK") == FALSE) { pth <- file.path(getwd(), "..", "inst", "nexusfiles") } else { pth <- system.file(package="phylobase", "nexusfiles") } ## co1.nex -- typical output from MrBayes. Contains 2 identical trees, the first ## one having posterior probabilities as node labels co1File <- file.path(pth, "co1.nex") # create phylo4 object with a full complement of valid slots ancestor <- as.integer(c(6,7,7,6,8,0,8,9,9)) descendant <- as.integer(c(7,1,2,8,3,6,9,4,5)) edge <- cbind(ancestor, descendant) nid.tip <- 1:5 nid.int <- 6:9 nid.all <- c(nid.tip, nid.int) lab.tip <- paste("t", nid.tip, sep="") lab.int <- paste("n", nid.int, sep="") lab.all <- c(lab.tip, lab.int) elen <- descendant/10 elab <- paste("e", ancestor, descendant, sep="-") phy <- phylo4(x=edge, tip.label=lab.tip, node.label=lab.int, edge.length=elen, edge.label=elab) op <- phylobase.options() context("test phylo4 validator/phylobase.options()") test_that("test polytomies", { phylobase.options(poly="fail") expect_error(readNexus(file=co1File, check.node.labels="drop")) phylobase.options(op) }) test_that("test retic", { phylobase.options(retic="fail") edgeRetic <- rbind(edge, c(6, 3)) expect_error(phy <- phylo4(x=edgeRetic)) phylobase.options(op) }) test_that("test multiroot", { phylobase.options(multiroot="fail") edgeMultiRoot <- rbind(edge, c(0, 7)) expect_error(phy <- phylo4(x=edgeMultiRoot)) phylobase.options(op) }) test_that("test singleton", { phylobase.options(singleton="fail") edgeSingleton <- cbind(c(9,7,7,6,6,8,8,10,10,0), 1:10) expect_error(phylo4(x=edgeSingleton)) phylobase.options(op) }) ## checkPhylo4Data <- function() { ## } ## formatData <- function() { ## # function(phy, dt, type=c("tip", "internal", "all"), ## # match.data=TRUE, label.type=c("rownames", "column"), ## # label.column=1, missing.data=c("fail", "warn", "OK"), ## # extra.data=c("warn", "OK", "fail"), rownamesAsLabels=FALSE) ## } phylobase/tests/testthat/test.treestruc.R0000644000176200001440000000124412347155416020374 0ustar liggesusers# # --- Test treestruc.R functions --- # context("tree structures") test_that("hasPoly", { # construct simple polytomy owls <- ape::read.tree(text = "((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3);") owls$edge <- matrix(c(4,4,4,1,2,3), ncol=2) owls$Nnode <- 1 owls$edge.length <- owls$edge.length[-4] tr <- as(owls, "phylo4") expect_true(hasPoly(tr)) # test against empty tree expect_true(!hasPoly(new("phylo4"))) }) test_that("hasSingle", { # test against empty tree expect_true(!hasSingle(new("phylo4"))) }) test_that("hasRetic", { # test against empty tree expect_true(!hasRetic(new("phylo4"))) }) phylobase/tests/testthat/test.phylo4.R0000644000176200001440000000030012347155416017563 0ustar liggesusers# # --- Test phylo4.R --- # # phylo4.R is mostly used to set generics, so no testing needed # one non-exported method: ## test..genlab <- function() { ## # use phylobase:::.genlab ## } phylobase/tests/testthat/test.subset.R0000644000176200001440000001416212347155416017664 0ustar liggesusers## ## --- Test subset.R --- ## ## create phylo4 object with a full complement of valid slots ancestor <- as.integer(c(6,7,7,6,8,0,8,9,9)) descendant <- as.integer(c(7,1,2,8,3,6,9,4,5)) edge <- cbind(ancestor, descendant) nid.tip <- 1:5 nid.int <- 6:9 nid.all <- c(nid.tip, nid.int) lab.tip <- paste("t", nid.tip, sep="") lab.int <- paste("n", nid.int, sep="") elen <- descendant/10 elab <- paste("e", ancestor, descendant, sep="-") phy <- phylo4(x=edge, tip.label=lab.tip, node.label=lab.int, edge.length=elen, edge.label=elab) ## create altered version such that each slot is out of order with ## respect to all others; methods should be able to handle this phy.alt <- phy phy.alt@label <- rev(phy@label) phy.alt@edge <- phy@edge[c(6:9, 1:5), ] phy.alt@edge.length <- phy@edge.length[c(7:9, 1:6)] phy.alt@edge.label <- phy@edge.label[c(8:9, 1:7)] ## now create phylo4d by adding data (with node IDs as row.names) phyd.alt <- as(phy.alt, "phylo4d") allDt <- data.frame(a=letters[nid.all], b=10*nid.all, row.names=nid.all) tdata(phyd.alt, "all") <- allDt ## create altered version such that data slots are out of order with ## respect to all others; methods should be able to handle this nid.tip.r <- c(2,5,4,3,1) nid.int.r <- c(8,7,9,6) nid.all.r <- c(nid.tip.r, nid.int.r) phyd.alt@data <- phyd.alt@data[rank(nid.all.r), ] #----------------------------------------------------------------------- context("subset and friends") ## Also be testing "[" phylo4 methods here test_that("subset on phylo4", { # subset 2 tips phy.sub2 <- subset(phy.alt, tips.include=c(2, 5)) expect_equal(tipLabels(phy.sub2), setNames(c("t2", "t5"), c("1", "2"))) expect_equal(nodeLabels(phy.sub2), setNames(c("n6"), c("3"))) expect_equal(edgeLength(phy.sub2), setNames(c(0.6, 0.9, 2.2), c("0-3", "3-1", "3-2"))) expect_equal(subset(phy.alt, tips.exclude=c(1, 3, 4)), phy.sub2) expect_equal(subset(phy.alt, tips.include=c("t2", "t5")), phy.sub2) expect_equal(subset(phy.alt, tips.exclude=c("t1", "t3", "t4")), phy.sub2) # subset 4 tips phy.sub4 <- subset(phy.alt, tips.include=c(1, 2, 4, 5)) expect_equal(tipLabels(phy.sub4), setNames(c("t1", "t2", "t4", "t5"), c("1", "2", "3", "4"))) expect_equal(nodeLabels(phy.sub4), setNames(c("n6", "n7", "n9"), c("5", "6", "7"))) expect_equal(edgeLength(phy.sub4), setNames(c(0.6, 0.4, 0.5, 0.7, 0.1, 0.2, 1.7), c("0-5", "7-3", "7-4", "5-6", "6-1", "6-2", "5-7"))) expect_equal(subset(phy.alt, tips.exclude=3), phy.sub4) expect_equal(subset(phy.alt, tips.include=c("t1", "t2", "t4", "t5")), phy.sub4) expect_equal(subset(phy.alt, tips.exclude="t3"), phy.sub4) # check variants that should all return the original object expect_equal(phy.alt, subset(phy.alt)) expect_equal(phy.alt, subset(phy.alt, tipLabels(phy.alt))) expect_equal(phy.alt, subset(phy.alt, seq_len(nTips(phy.alt)))) expect_equal(phy.alt, phy.alt[tipLabels(phy.alt)]) expect_equal(phy.alt, phy.alt[seq_len(nTips(phy.alt))]) expect_equal(phy.alt, phy.alt[TRUE]) # error if only one valid tip requested expect_error(subset(phy, tips.include="t1")) expect_error(suppressWarnings(subset(phy, tips.include=c("t1", "t999")))) # error if zero valid tips requested expect_error(suppressWarnings(subset(phy, tips.include="t999"))) # error if more than one subset criteria are supplied expect_error(subset(phyd, tips.include="t1", tips.exclude="t3")) }) ## Also testing "[" phylo4d methods here ##TODO get rid of some tests that are pretty much redundant with the ##above, and add tests focused more on tree data test_that("subset on phylo4d", { ## subset 2 tips phyd.sub2 <- subset(phyd.alt, tips.include=c(2, 5)) expect_equal(tipLabels(phyd.sub2), setNames(c("t2", "t5"), c("1", "2"))) expect_equal(nodeLabels(phyd.sub2), setNames(c("n6"), c("3"))) expect_equal(edgeLength(phyd.sub2), setNames(c(0.6, 0.9, 2.2), c("0-3", "3-1", "3-2"))) expect_equal(subset(phyd.alt, tips.exclude=c(1, 3, 4)), phyd.sub2) expect_equal(subset(phyd.alt, tips.include=c("t2", "t5")), phyd.sub2) expect_equal(subset(phyd.alt, tips.exclude=c("t1", "t3", "t4")), phyd.sub2) ## subset 4 tips phyd.sub4 <- subset(phyd.alt, tips.include=c(1, 2, 4, 5)) expect_equal(tipLabels(phyd.sub4), setNames(c("t1", "t2", "t4", "t5"), c("1", "2", "3", "4"))) expect_equal(nodeLabels(phyd.sub4), setNames(c("n6", "n7", "n9"), c("5", "6", "7"))) expect_equal(edgeLength(phyd.sub4), setNames(c(0.6, 0.4, 0.5, 0.7, 0.1, 0.2, 1.7), c("0-5", "7-3", "7-4", "5-6", "6-1", "6-2", "5-7"))) expect_equal(subset(phyd.alt, tips.exclude=3), phyd.sub4) expect_equal(subset(phyd.alt, tips.include=c("t1", "t2", "t4", "t5")), phyd.sub4) expect_equal(subset(phyd.alt, tips.exclude="t3"), phyd.sub4) ## check variants that should all return the original object expect_equal(phyd.alt, subset(phyd.alt)) expect_equal(phyd.alt, subset(phyd.alt, tipLabels(phyd.alt))) expect_equal(phyd.alt, subset(phyd.alt, seq_len(nTips(phyd.alt)))) expect_equal(phyd.alt, phyd.alt[tipLabels(phyd.alt)]) expect_equal(phyd.alt, phyd.alt[seq_len(nTips(phyd.alt))]) expect_equal(phyd.alt, phyd.alt[TRUE]) ## error if only one valid tip requested expect_error(subset(phyd.alt, tips.include="t1")) expect_error(suppressWarnings(subset(phyd.alt, tips.include=c("t1", "t999")))) ## error if zero valid tips requested expect_error(suppressWarnings(subset(phyd.alt, tips.include="t999"))) # subset tips that include an NA value ##TODO uncomment this after tdata is working right with scrambled order ## tdata(phyd.alt)["t5", "a"] <- NA ## tdata(phyd.sub2)["t5", "a"] <- NA ## expect_equal(phyd.sub2, subset(phyd.alt, tips.include=c(2, 5))) }) test_that("subset on extractTree", { # extract phylo4 from itself expect_equal(phy.alt, extractTree(phy.alt)) # extract phylo4 from phylo4d expect_equal(phy.alt, extractTree(phyd.alt)) }) phylobase/tests/testthat/test.class-phylo4.R0000644000176200001440000001010212350621330020652 0ustar liggesusers# # --- Test class-phylo4.R --- # ### Get all the test files if (Sys.getenv("RCMDCHECK") == FALSE) { pth <- file.path(getwd(), "..", "inst", "nexmlfiles") } else { pth <- system.file(package="phylobase", "nexmlfiles") } ## NeXML files compFile <- file.path(pth, "comp_analysis.xml") stopifnot(file.exists(compFile)) op <- phylobase.options() context("test phylo4 class") test_that("building from matrix works", { edge <- structure(c(6L, 7L, 8L, 8L, 9L, 9L, 7L, 6L, 7L, 8L, 1L, 9L, 2L, 3L, 4L, 5L), .Dim = c(8, 2)) edge.length <- c(0.2, 0.5, 0.2, 0.15, 0.1, 0.1, 0.7, 1) tip.label <- paste("t", 1:5, sep="") node.label <- paste("n", 1:4, sep="") edge.label <- paste("e", 1:8, sep="") order <- "preorder" annote <- list(x="annotation") phy <- phylo4(edge, edge.length=edge.length, tip.label=tip.label, node.label=node.label, edge.label=edge.label, order=order, annote=annote) ## test each slot expect_equal(edge, unname(edges(phy))) expect_equal(edge.length, unname(edgeLength(phy))) expect_equal(4L, nNodes(phy)) expect_equal(tip.label, unname(tipLabels(phy))) expect_equal(node.label, unname(nodeLabels(phy))) expect_equal(edge.label, unname(edgeLabels(phy))) expect_equal(order, edgeOrder(phy)) expect_equal(annote, phy@annote) ## test improper cases ## expect_error(phylo4(edge, edge.length=999)) # recycling is allowed? FM (20140506: yes) expect_error(phylo4(edge, tip.label=999)) expect_error(phylo4(edge, node.label=999)) ## expect_error(phylo4(edge, edge.label=999)) # recycling is allowed? FM (20140506: yes) expect_error(phylo4(edge, order="invalid order")) expect_error(phylo4(edge, annote="invalid annotation")) }) ## note: this method mostly just wraps phylo->phylo4 coercion, which is ## tested more thoroughly in runit.setAs-methods.R; focus here is on ## annote and check.node.labels arguments test_that("phylo4 can be built from phylo (tests on what's not done in setAs tests)", { tr <- ape::read.tree(text="(((t1:0.2,(t2:0.1,t3:0.1):0.15):0.5,t4:0.7):0.2,t5:1):0.4;") ## ## annote ## annote <- list(x="annotation") phy <- phylo4(tr, annote=annote) expect_equal(annote, phy@annote) ## ## check.node.labels ## # case 0: no node labels phy <- phylo4(tr) expect_true(!hasNodeLabels(phy)) # case 1: keep unique character labels tr$node.label <- paste("n", 1:4, sep="") phy <- phylo4(tr, check.node.labels="keep") expect_equal(tr$node.label, unname(nodeLabels(phy))) # keeping node labels should be the default expect_equal(phy, phylo4(tr)) # case 2: keep unique number-like character labels tr$node.label <- as.character(1:4) phy <- phylo4(tr, check.node.labels="keep") expect_equal(tr$node.label, unname(nodeLabels(phy))) # case 3: keep unique numeric labels, but convert to character tr$node.label <- as.numeric(1:4) phy <- phylo4(tr, check.node.labels="keep") expect_equal(as.character(tr$node.label), unname(nodeLabels(phy))) # case 4: must drop non-unique labels tr$node.label <- rep("x", 4) ## with options allow.duplicated.labels="fail" phylobase.options(allow.duplicated.labels="fail") expect_error(phylo4(tr)) expect_error(phylo4(tr, check.node.labels="keep")) phylobase.options(op) ## test dropping node labels phy <- phylo4(tr, check.node.labels="drop") expect_true(!hasNodeLabels(phy)) ## with options allow.duplicated.labels="ok" phylobase.options(allow.duplicated.labels="ok") phy <- phylo4(tr) expect_equal(unname(nodeLabels(phy)), tr$node.label) phy <- phylo4(tr, check.node.labels="keep") expect_equal(unname(nodeLabels(phy)), tr$node.label) phy <- phylo4(tr, check.node.labels="drop") expect_true(!hasNodeLabels(phy)) phylobase.options(op) }) test_that("nexml to phylo4", { nxml <- RNeXML::nexml_read(compFile) phy4 <- phylo4(nxml) expect_true(all(tipLabels(phy4) %in% paste("taxon", 1:10, sep="_"))) expect_equal(nEdges(phy4), 19) }) phylobase/tests/testthat/test.pdata.R0000644000176200001440000000052112347155416017442 0ustar liggesusers# # --- Test pdata.R --- # ## test.pdata <- function() { ## # function(data,type,comment,metadata) ## } ## test.check_pdata <- function() { ## } ## test.extract.pdata <- function() { ## # test "[" and "[[" ## } ## test.assign.pdata <- function() { ## # test "[<-" and "[[<-" ## } ## test.plot.pdata <- function() { ## } phylobase/tests/testthat/test.methods-phylo4.R0000644000176200001440000006212212553732474021242 0ustar liggesusers## ## --- Test methods-phylo4.R --- ## # create ape::phylo version of a simple tree for testing nwk <- "((t1:0.1,t2:0.2)n7:0.7,(t3:0.3,(t4:0.4,t5:0.5)n9:0.9)n8:0.8)n6:0.6;" tr <- read.tree(text=nwk) # create analogous phylo4 object with a full complement of valid slots ancestor <- as.integer(c(6,7,7,6,8,0,8,9,9)) descendant <- as.integer(c(7,1,2,8,3,6,9,4,5)) edge <- cbind(ancestor, descendant) nid.tip <- 1:5 nid.int <- 6:9 nid.all <- c(nid.tip, nid.int) lab.tip <- paste("t", nid.tip, sep="") lab.int <- paste("n", nid.int, sep="") lab.all <- c(lab.tip, lab.int) eid <- paste(ancestor, descendant, sep="-") elen <- descendant/10 elab <- paste("e", eid, sep="") phy <- phylo4(x=edge, tip.label=lab.tip, node.label=lab.int, edge.length=elen, edge.label=elab) # create altered version such that each slot is out of order with # respect to all others; methods should be able to handle this phy.alt <- phy phy.alt@label <- rev(phy@label) phy.alt@edge <- phy@edge[c(6:9, 1:5), ] phy.alt@edge.length <- phy@edge.length[c(7:9, 1:6)] phy.alt@edge.label <- phy@edge.label[c(8:9, 1:7)] # update test targets for edge-related slots ancestor <- ancestor[c(6:9, 1:5)] descendant <- descendant[c(6:9, 1:5)] edge <- cbind(ancestor, descendant) eid <- eid[c(6:9, 1:5)] elen <- elen[c(6:9, 1:5)] elab <- elab[c(6:9, 1:5)] op <- phylobase.options() #----------------------------------------------------------------------- context("nTips, depthTips, nNodes, nodeType") test_that("nTips works correctly", expect_that(nTips(phy.alt), equals(length(nid.tip))) ) test_that("depthTips works when there are edge lengths", { edgeLengthVec <- c(1.2, 1.8, 1.8, 2.1, 2.3) names(edgeLengthVec) <- tipLabels(phy.alt) expect_that(depthTips(phy.alt), equals(edgeLengthVec)) }) test_that("depthTips works when there are no edge lengths", { tmpPhy <- phy.alt edgeLength(tmpPhy) <- NA expect_true(is.null(depthTips(tmpPhy))) }) test_that("nTips works on ape objects", ## nTips phylo expect_equal(nTips(tr), 5)) test.nEdges.phylo4 <- function() { expect_identical(nEdges(phy.alt), nrow(edge)) } test_that("nNodes works as expected", expect_equal(nNodes(phy.alt), length(nid.int))) test_that("nodeType works as expected", expect_identical(nodeType(phy.alt), setNames(c(rep("tip", length(nid.tip)), "root", rep("internal", length(nid.int)-1)), c(nid.tip, nid.int)))) context("nodeId") test_that("nodeId works without arguments", expect_identical(nodeId(phy.alt), c(nid.tip, nid.int))) test_that("nodeId works with argument all", expect_identical(nodeId(phy.alt, "all"), c(nid.tip, nid.int))) test_that("nodeId works with argument tip", expect_identical(nodeId(phy.alt, "tip"), nid.tip)) test_that("nodeId works with argument internal", expect_identical(nodeId(phy.alt, "internal"), nid.int)) test_that("nodeId works woth argument root", expect_identical(nodeId(phy.alt, "root"), nid.int[1])) context("nodeDepth") allDepths <- c(1.2, 1.8, 1.8, 2.1, 2.3, 0.9, 1.0, 1.2, 1.6) names(allDepths) <- names(getNode(phy.alt)) test_that("nodeDepth works without arguments", { expect_equal(nodeDepth(phy.alt), allDepths) }) test_that("nodeDepth works with numeric argument", { expect_equal(nodeDepth(phy.alt, 1), allDepths[1]) }) test_that("nodeDepth works with character argument", { expect_equal(nodeDepth(phy.alt, "t1"), allDepths[1]) }) test_that("nodeDepth works with no branch length", { tmpPhy <- phy.alt edgeLength(tmpPhy) <- NA expect_true(is.null(nodeDepth(tmpPhy))) }) ############################################################################ ## nodeHeight ## ############################################################################ context("nodeHeight") tmp_nd_hgt_tree <- tempfile() cat("(((A:1,B:1):2,(C:1,D:1):2):4,((E:10,F:1):2,(G:3,H:7):2):4);", file = tmp_nd_hgt_tree) nd_hgt_tree <- readNewick(file = tmp_nd_hgt_tree) unlink(tmp_nd_hgt_tree) test_that("nodeHeight with 1 node", { expect_equal(nodeHeight(nd_hgt_tree, MRCA(nd_hgt_tree, c("A", "D")), "all_tip"), setNames(c(3, 3, 3, 3), c("A", "B", "C", "D"))) expect_equal(nodeHeight(nd_hgt_tree, MRCA(nd_hgt_tree, c("E", "H")), "min_tip"), c("F" = 3)) expect_equal(nodeHeight(nd_hgt_tree, MRCA(nd_hgt_tree, c("E", "H")), "max_tip"), c("E" = 12)) expect_equal(nodeHeight(nd_hgt_tree, MRCA(nd_hgt_tree, c("A", "D")), "root"), 4) }) test_that("nodeHeight with several nodes", { expect_equal(nodeHeight(nd_hgt_tree, c( MRCA(nd_hgt_tree, c("A", "D")), MRCA(nd_hgt_tree, c("A", "B"))), "all_tip"), list("10" = setNames(c(3, 3, 3, 3), c("A", "B", "C", "D")), "11" = c("A" = 1, "B" = 1))) expect_equal(nodeHeight(nd_hgt_tree, c( MRCA(nd_hgt_tree, c("E", "H")), MRCA(nd_hgt_tree, c("E", "F"))), "min_tip"), list("13" = c("F" = 3), "14" = c("F" = 1))) expect_equal(nodeHeight(nd_hgt_tree, c( MRCA(nd_hgt_tree, c("E", "H")), MRCA(nd_hgt_tree, c("E", "F"))), "max_tip"), list("13" = c("E" = 12), "14" = c("E" = 10))) expect_equal(nodeHeight(nd_hgt_tree, c( MRCA(nd_hgt_tree, c("A", "D")), MRCA(nd_hgt_tree, c("E", "F"))), "root"), c("10" = 4, "14" = 6)) }) test_that("nodeHeight for tips", { res <- as.list(rep(0, nTips(nd_hgt_tree))) for (i in seq_len(nTips(nd_hgt_tree))) names(res[[i]]) <- LETTERS[i] names(res) <- seq_len(nTips(nd_hgt_tree)) expect_equal(nodeHeight(nd_hgt_tree, nodeId(nd_hgt_tree, "tip"), "all_tip"), res) expect_equal(nodeHeight(nd_hgt_tree, nodeId(nd_hgt_tree, "tip"), "min_tip"), res) expect_equal(nodeHeight(nd_hgt_tree, nodeId(nd_hgt_tree, "tip"), "max_tip"), res) }) test_that("nodeHeight for mix of tips and internal nodes", { expect_equal(nodeHeight(nd_hgt_tree, c(1, 10), "all_tip"), list("1" = c("A" = 0), "10" = c("A" = 3, "B" = 3, "C" = 3, "D" = 3))) expect_equal(nodeHeight(nd_hgt_tree, c(1, 14), "min_tip"), list("1" = c("A" = 0), "14" = c("F" = 1))) expect_equal(nodeHeight(nd_hgt_tree, c(1, 14), "max_tip"), list("1" = c("A" = 0), "14" = c("E" = 10))) expect_equal(nodeHeight(nd_hgt_tree, c(5, 14), "root"), c("5" = 16, "14" = 6)) }) ############################################################################ ## edges ## ############################################################################ context("edges") test_that("edges works", expect_identical(edges(phy.alt), edge)) test_that("edges work with drop.root=TRUE option", expect_identical(edges(phy.alt, drop.root=TRUE), edge[edge[,1] != 0,])) context("edge order") test_that("edgeOrder works as expected", { expect_identical(edgeOrder(phy.alt), "unknown") expect_identical(edgeOrder(reorder(phy.alt, "preorder")), "preorder") expect_identical(edgeOrder(reorder(phy.alt, "postorder")), "postorder") }) context("edgeId") test_that("edgeId works with no argument", expect_identical(edgeId(phy.alt), eid)) test_that("edgeId works with argument all", expect_identical(edgeId(phy.alt, "all"), eid)) test_that("edgeId works with argument tip", expect_identical(edgeId(phy.alt, "tip"), eid[descendant %in% nid.tip])) test_that("edgeId works with argument internal", expect_identical(edgeId(phy.alt, "internal"), eid[!descendant %in% nid.tip])) test_that("edgeId works with argument root", expect_identical(edgeId(phy.alt, "root"), eid[ancestor == 0])) context("hasEdgeLength") test_that("hasEdgeLength works when edge lengths are present", expect_true(hasEdgeLength(phy.alt))) test_that("hasEdgeLength works when no edge lengths are present", { phy.alt@edge.length <- NA_real_ expect_true(!hasEdgeLength(phy.alt)) }) context("edgeLength") test_that("default works (all edge lengths)", expect_identical(edgeLength(phy.alt), setNames(elen, eid))) test_that("one edge length, by label", expect_equal(edgeLength(phy.alt, "t1"), c(`7-1`=0.1))) test_that("one edge length, by node ID", expect_equal(edgeLength(phy.alt, 1), c(`7-1`=0.1))) test_that("non-existent edge, by label", { ans <- structure(NA_real_, .Names = NA_character_) expect_equal(suppressWarnings(edgeLength(phy.alt, "xxx")), ans) }) test_that("non-existent edge, by number", { ans <- structure(NA_real_, .Names = NA_character_) expect_equal(suppressWarnings(edgeLength(phy.alt, 999)), ans) }) test_that("wrong number of edge lengths", { phy.tmp1 <- phy.alt phy.tmp1@edge.length <- phy.alt@edge.length[-1] expect_true(nzchar(checkPhylo4(phy.tmp1))) phy.tmp1 <- phy.alt phy.tmp1@edge.length <- c(phy.alt@edge.length, 1) expect_true(nzchar(checkPhylo4(phy.tmp1))) }) test_that("negative edge lengths", { phy.tmp1 <- phy.alt phy.tmp1@edge.length[3] <- -1 expect_true(nzchar(checkPhylo4(phy.tmp1))) }) test_that("edge incorrectly labeled", { phy.tmp1 <- phy.alt names(phy.tmp1@edge.length)[1] <- "9-10" expect_true(nzchar(checkPhylo4(phy.tmp1))) }) context("edgeLength <-") emptyVec <- numeric() attributes(emptyVec) <- list(names=character(0)) test_that("dropping all should produce empty slot", { edgeLength(phy.alt) <- numeric() expect_identical(edgeLength(phy.alt), setNames(rep(NA_real_, 9), edgeId(phy.alt, "all"))) expect_identical(phy.alt@edge.length, emptyVec) edgeLength(phy.alt) <- NA_real_ expect_identical(edgeLength(phy.alt), setNames(rep(NA_real_, 9), edgeId(phy.alt, "all"))) expect_identical(phy.alt@edge.length, emptyVec) }) test_that("vector with reversed names, get matched by default (complete replacement)", { edgeLength(phy.alt) <- numeric() revElen <- setNames(elen, rev(eid)) edgeLength(phy.alt) <- revElen expect_identical(edgeLength(phy.alt), revElen[edgeId(phy.alt, "all")]) }) test_that("vector with reversed names, but specify no matching (complete replacement)", { edgeLength(phy.alt) <- numeric() revElen <- setNames(elen, rev(eid)) edgeLength(phy.alt, use.names=FALSE) <- revElen elen1 <- elen expect_identical(edgeLength(phy.alt), setNames(elen1, edgeId(phy.alt, "all"))) }) test_that("vector with no names, should match to edgeId order (complete replacement)", { edgeLength(phy.alt) <- numeric() edgeLength(phy.alt) <- elen elen2 <- elen expect_identical(edgeLength(phy.alt), setNames(elen2, edgeId(phy.alt, "all"))) }) test_that("recycling applies if fewer the nEdges elements are supplied, \ (duplicate edge length are okay), (complete replacement)", { edgeLength(phy.alt) <- 1 expect_identical(edgeLength(phy.alt), setNames(rep(1, 9), edgeId(phy.alt, "all"))) }) edgeLength(phy.alt) <- elen test_that("replace an edge length using numeric index (partial replacement)", { edgeLength(phy.alt)[9] <- 83 expect_identical(edgeLength(phy.alt), setNames(c(elen[1:8], 83), edgeId(phy.alt, "all"))) }) test_that("back again, now using character index (partial replacement)", { edgeLength(phy.alt)["8-3"] <- 0.3 elen3 <- elen expect_identical(edgeLength(phy.alt), setNames(elen3, edgeId(phy.alt, "all"))) }) test_that("error to add length for edges that don't exist (partial replacement)", { expect_error(edgeLength(phy.alt)["fake"] <- 999) expect_error(edgeLength(phy.alt)[999] <- 999) }) test_that("NAs permitted only for root edge (or for *all* edges)", { edgeLength(phy.alt)[edgeId(phy.alt, "root")] <- NA expect_identical(edgeLength(phy.alt), setNames(c(NA, elen[2:9]), edgeId(phy.alt, "all"))) edgeLength(phy.alt) <- elen expect_error(edgeLength(phy.alt)["8-3"] <- NA) }) ## TODO sumEdgeLength.phylo4 ## function(phy, node) context("isRooted") test_that("isRooted works as expected", expect_true(isRooted(phy.alt))) context("rootNode") test_that("rootNode works as expected", expect_identical(rootNode(phy.alt), getNode(phy, nid.int[1]))) context("rootNode <-") test_that("rootNode <- is not yet implemented", expect_error(rootNode(phy.alt) <- 7)) context("labels") test_that("labels works as expected with no argument", expect_identical(labels(phy.alt), setNames(c(lab.tip, lab.int), c(nid.tip, nid.int)))) test_that("labels works as expected with argument all", expect_identical(labels(phy.alt, "all"), setNames(c(lab.tip, lab.int), c(nid.tip, nid.int)))) test_that("labels works as expected with argument tip", expect_identical(labels(phy.alt, "tip"), setNames(lab.tip, nid.tip))) test_that("labels works as expected with argument internal", expect_identical(labels(phy.alt, "internal"), setNames(lab.int, nid.int))) context("labels <-") test_that("dropping all should produce default tip labels, no internal labels", { labels(phy.alt) <- character() expect_identical(labels(phy.alt), setNames(c(paste("T", 1:5, sep=""), rep(NA, 4)), nid.all)) }) ## # ## # complete replacement ## # ## with names, not used test_that("vector with reversed names, but names not used (all) - complete replacement", { labels(phy.alt) <- character() labels(phy.alt) <- setNames(lab.all, rev(nid.all)) expect_identical(labels(phy.alt), setNames(lab.all, nid.all)) }) test_that("vector with reversed names, but names not used (tips) - complete replacement", { labels(phy.alt) <- character() labels(phy.alt, "tip") <- setNames(lab.tip, rev(nid.tip)) expect_identical(tipLabels(phy.alt), setNames(lab.tip, nid.tip)) }) test_that("vector with reversed names, but names not used (internal) - complete replacement", { labels(phy.alt) <- character() labels(phy.alt, "internal") <- setNames(lab.int, rev(nid.int)) expect_identical(nodeLabels(phy.alt), setNames(lab.int, nid.int)) }) ## with names, used test_that("vector with reversed names, but names used (all) - complete replacement", { labels(phy.alt) <- character() labels(phy.alt, use.names=TRUE) <- setNames(lab.all, rev(nid.all)) expect_identical(labels(phy.alt), setNames(rev(lab.all), nid.all)) }) test_that("vector with reversed names, but names used (tips) - complete replacement", { labels(phy.alt) <- character() labels(phy.alt, "tip", use.names=TRUE) <- setNames(lab.tip, rev(nid.tip)) expect_identical(tipLabels(phy.alt), setNames(rev(lab.tip), nid.tip)) }) test_that("vector with reversed names, but names used (internal) - complete replacement", { labels(phy.alt) <- character() labels(phy.alt, "internal", use.names=TRUE) <- setNames(lab.int, rev(nid.int)) expect_identical(nodeLabels(phy.alt), setNames(rev(lab.int), nid.int)) }) ## no names test_that("vector with no names, should match to nodeId order (all) - complete replacement", { labels(phy.alt) <- character() labels(phy.alt) <- lab.all expect_identical(labels(phy.alt), setNames(lab.all, nid.all)) }) test_that("vector with no names, should match to nodeId order (all) - complete replacement", { labels(phy.alt) <- character() labels(phy.alt, type="tip") <- lab.tip expect_identical(tipLabels(phy.alt), setNames(lab.tip, nid.tip)) }) test_that("vector with no names, should match to nodeId order (all) - complete replacement", { labels(phy.alt) <- character() labels(phy.alt, type="internal") <- lab.int expect_identical(nodeLabels(phy.alt), setNames(lab.int, nid.int)) }) ## partial replacement labels(phy.alt) <- lab.all test_that("replace a tip using numeric index", { labels(phy.alt)[5] <- "t5a" expect_identical(tipLabels(phy.alt), setNames(c(lab.tip[1:4], "t5a"), nid.tip)) }) test_that("and back again, now using character index", { labels(phy.alt)["5"] <- "t5" expect_identical(labels(phy.alt), setNames(lab.all, nid.all)) }) test_that("replace an internal node using numeric index", { labels(phy.alt)[9] <- "n9a" expect_identical(nodeLabels(phy.alt), setNames(c(lab.int[1:3], "n9a"), nid.int)) }) test_that("and back again, now using character index", { labels(phy.alt)["9"] <- "n9" expect_identical(labels(phy.alt), setNames(lab.all, nid.all)) }) test_that("error to produce duplicate tip or internal label", { phylobase.options(allow.duplicated.labels="fail") expect_error(labels(phy.alt)[1] <- "t2") expect_error(labels(phy.alt)[6] <- "n7") }) test_that("no error in allow.duplicated.labels is ok", { phylobase.options(allow.duplicated.labels="ok") labels(phy.alt)[1] <- "t2" labels(phy.alt)[6] <- "n7" expect_identical(tipLabels(phy.alt), setNames(c("t2", "t2", "t3", "t4", "t5"), nid.tip)) expect_identical(nodeLabels(phy.alt), setNames(c("n7", "n7", "n8", "n9"), nid.int)) }) test_that("error to add labels for nodes that don't exist", { expect_error(labels(phy.alt)["fake"] <- "xxx") expect_error(labels(phy.alt)[999] <- "xxx") }) context("nodeLabels") test_that("nodeLabels works as expected", expect_identical(nodeLabels(phy.alt), setNames(lab.int, nid.int))) context("hasNodeLabels") test_that("hasNodeLabels works as expected", { expect_true(hasNodeLabels(phy.alt)) nodeLabels(phy.alt) <- NA_character_ expect_true(!hasNodeLabels(phy.alt)) }) context("nodeLabels <-") test_that("dropping all should produce no internal labels", { nodeLabels(phy.alt) <- character() expect_true(!any(nid.int %in% names(phy.alt@label))) expect_identical(nodeLabels(phy.alt), setNames(rep(NA_character_, 4), nid.int)) }) labels(phy.alt) <- lab.all test_that("replace an internal node using numeric index", { nodeLabels(phy.alt)[4] <- "n9a" expect_identical(nodeLabels(phy.alt), setNames(c(lab.int[1:3], "n9a"), nid.int)) }) test_that("and back again, now using character index", { nodeLabels(phy.alt)["9"] <- "n9" expect_identical(labels(phy.alt), setNames(lab.all, nid.all)) }) test_that("error to produce duplicate internal label", { phylobase.options(allow.duplicated.labels="fail") expect_error(nodeLabels(phy.alt)["6"] <- "n7") }) test_that("duplicated labels work as expected", { phylobase.options(op) phylobase.options(allow.duplicated.labels="ok") nodeLabels(phy.alt)["6"] <- "n7" expect_identical(nodeLabels(phy.alt), setNames(c("n7", "n7", "n8", "n9"), nid.int)) expect_true(hasDuplicatedLabels(phy.alt)) ## NAs are not considered duplicated nodeLabels(phy.alt)[1:2] <- NA expect_true(!hasDuplicatedLabels(phy.alt)) phylobase.options(op) ## error to add labels for nodes that don't exist expect_error(nodeLabels(phy.alt)["fake"] <- "xxx") expect_error(nodeLabels(phy.alt)[999] <- "xxx") }) context("tipLabels") test_that("tipLabels works as expected", expect_identical(tipLabels(phy.alt), setNames(lab.tip, nid.tip))) context("tipLabels <-") test_that("dropping all tip labels should produce default labels", { tipLabels(phy.alt) <- character() expect_identical(tipLabels(phy.alt), setNames(paste("T", 1:5, sep=""), nid.tip)) }) labels(phy.alt) <- lab.all test_that("replace a tip using numeric index", { tipLabels(phy.alt)[5] <- "t5a" expect_identical(tipLabels(phy.alt), setNames(c(lab.tip[1:4], "t5a"), nid.tip)) }) test_that("and back again, now using character index", { tipLabels(phy.alt)["5"] <- "t5" expect_identical(labels(phy.alt), setNames(lab.all, nid.all)) }) test_that("error to produce duplicate tip or internal label", { phylobase.options(allow.duplicated.labels="fail") expect_error(tipLabels(phy.alt)[1] <- "t2") }) test_that("duplicated labels works as expected on tips", { phylobase.options(op) phylobase.options(allow.duplicated.labels="ok") tipLabels(phy.alt)[1] <- "t2" expect_identical(tipLabels(phy.alt), setNames(c("t2", "t2", "t3", "t4", "t5"), nid.tip)) expect_true(hasDuplicatedLabels(phy.alt)) tipLabels(phy.alt)[1:2] <- NA expect_true(!hasDuplicatedLabels(phy.alt)) phylobase.options(op) }) test_that("error to add labels for nodes that don't exist", { expect_error(tipLabels(phy.alt)["fake"] <- "xxx") expect_error(tipLabels(phy.alt)[999] <- "xxx") }) test_that("hasEdgeLabels works as expected", { expect_true(hasEdgeLabels(phy.alt)) phy.alt@edge.label <- NA_character_ expect_true(!hasEdgeLabels(phy.alt)) }) context("edgeLabels") test_that("edgeLabels works as expected", { expect_identical(edgeLabels(phy.alt), setNames(elab, eid)) }) test_that("edgeLabels returns named vector of NAs if edge labels are missing or NA", { phy.alt@edge.label <- NA_character_ expect_identical(edgeLabels(phy.alt), setNames(rep(NA_character_, 9), eid)) phy.alt@edge.label <- character() expect_identical(edgeLabels(phy.alt), setNames(rep(NA_character_, 9), eid)) }) test_that("if only some labels exists, should fill in NA for the others", { phy.alt@edge.label <- setNames(elab[-1], eid[-1]) expect_identical(edgeLabels(phy.alt), setNames(c(NA, elab[-1]), eid)) }) context("edgeLabels <-") test_that(" dropping all should produce empty slot", { edgeLabels(phy.alt) <- character() expect_identical(edgeLabels(phy.alt), setNames(rep(NA_character_, 9), eid)) }) test_that("vector with reversed names, which always get matched - complete replacement", { edgeLabels(phy.alt) <- character() edgeLabels(phy.alt) <- setNames(elab, rev(eid)) expect_identical(edgeLabels(phy.alt), setNames(rev(elab), eid)) }) test_that("vector with no names, should match to edgeId order - complete replacement", { edgeLabels(phy.alt) <- character() edgeLabels(phy.alt) <- elab expect_identical(edgeLabels(phy.alt), setNames(elab, eid)) }) test_that("recycling applies if fewer the nEdges elements are supplied\\ (duplicate edge labels are okay) - complete replacement.", { edgeLabels(phy.alt) <- "x" expect_identical(edgeLabels(phy.alt), setNames(rep("x", 9), eid)) }) edgeLabels(phy.alt) <- elab test_that("replace an edge label using numeric index - partial replacement", { edgeLabels(phy.alt)[9] <- "e8-3a" expect_identical(edgeLabels(phy.alt), setNames(c(elab[1:8], "e8-3a"), eid)) }) test_that("and back again, now using character index", { edgeLabels(phy.alt)["8-3"] <- "e8-3" expect_identical(edgeLabels(phy.alt), setNames(elab, eid)) }) test_that("error to add labels for edges that don't exist", { expect_error(edgeLabels(phy.alt)["fake"] <- "xxx") expect_error(edgeLabels(phy.alt)[999] <- "xxx") }) ## this is also the print method ## this mostly just wraps .phylo4ToDataFrame, which is tested elsewhere ## test.show.phylo4 <- function() { ## } ## test.names.phylo4 <- function() { ## #TODO? ## } ## test.head.phylo4 <- function() { ## #TODO? ## } ## test.tail.phylo4 <- function() { ## #TODO? ## } context("summary") test_that("summary works as expected", { phy.sum <- summary(phy.alt, quiet=TRUE) expect_identical(phy.sum$name, "phy.alt") expect_identical(phy.sum$nb.tips, length(nid.tip)) expect_identical(phy.sum$nb.nodes, length(nid.int)) expect_identical(phy.sum$mean.el, mean(elen)) expect_identical(phy.sum$var.el, var(elen)) expect_identical(phy.sum$sumry.el, summary(elen)) }) test_that("summary works as expected when root edge as no length", { ## now make root edge length NA edgeLength(phy.alt)[edgeId(phy.alt, "root")] <- NA phy.sum2 <- summary(phy.alt, quiet=TRUE) expect_identical(phy.sum2$mean.el, mean(edgeLength(phy.alt), na.rm=TRUE)) expect_identical(phy.sum2$var.el, var(edgeLength(phy.alt), na.rm=TRUE)) expect_identical(phy.sum2$sumry.el, summary(stats::na.omit(edgeLength(phy.alt)))) }) test_that("now remove edge lengths altogether", { phy.alt@edge.length[] <- NA phy.sum3 <- summary(phy.alt, quiet=TRUE) expect_true(is.null(phy.sum3$mean.el)) expect_true(is.null(phy.sum3$var.el)) expect_true(is.null(phy.sum3$sumry.el)) }) ## not an exported function -- called internally by reorder("phylo4") ## test.orderIndex <- function() { ## } ## test.reorder.phylo4 <- function() { ## ## TODO ## } context("isUltrametric") test_that("isUltrametric works as expected", { expect_true(!isUltrametric(phy.alt)) tmpPhy <- as(rcoal(10), "phylo4") expect_true(isUltrametric(tmpPhy)) tmpPhy <- phy.alt edgeLength(tmpPhy) <- NA expect_error(isUltrametric(tmpPhy)) }) phylobase.options(op) phylobase/tests/testthat/test.setAs-Methods.R0000644000176200001440000001456512350617600021036 0ustar liggesusers# # --- Test setAs-Methods.R --- # ### Get all the test files if (Sys.getenv("RCMDCHECK") == FALSE) { pth <- file.path(getwd(), "..", "inst", "nexmlfiles") } else { pth <- system.file(package="phylobase", "nexmlfiles") } # create ape::phylo version of a simple tree for testing nwk <- "((t1:0.1,t2:0.2)n7:0.7,(t3:0.3,(t4:0.4,t5:0.5)n9:0.9)n8:0.8)n6:0.6;" tr <- ape::read.tree(text=nwk) # create analogous phylo4 object with a full complement of valid slots ancestor <- as.integer(c(6,7,7,6,8,0,8,9,9)) descendant <- as.integer(c(7,1,2,8,3,6,9,4,5)) edge <- cbind(ancestor, descendant) nid.tip <- 1:5 nid.int <- 6:9 lab.tip <- paste("t", nid.tip, sep="") lab.int <- paste("n", nid.int, sep="") elen <- descendant/10 elab <- paste("e", ancestor, descendant, sep="-") phy <- phylo4(x=edge, tip.label=lab.tip, node.label=lab.int, edge.length=elen, edge.label=elab) # create altered version such that each slot is out of order with # respect to all others; methods should be able to handle this phy.alt <- phy phy.alt@label <- rev(phy@label) phy.alt@edge <- phy@edge[c(6:9, 1:5), ] phy.alt@edge.length <- phy@edge.length[c(7:9, 1:6)] phy.alt@edge.label <- phy@edge.label[c(8:9, 1:7)] ## NeXML files compFile <- file.path(pth, "comp_analysis.xml") stopifnot(file.exists(compFile)) #----------------------------------------------------------------------- context("setAs methods") test_that("phylo to phylo4", { # simple case as.phy <- as(tr, "phylo4") expect_true(class(as.phy)=="phylo4") expect_equal(tr$edge, unname(edges(as.phy, drop.root=TRUE))) expect_equal(tr$tip.label, unname(tipLabels(as.phy))) expect_equal(tr$node.label, unname(nodeLabels(as.phy))) # TODO: ape keeps the root edge length in $root.edge #expect_equal(tr$edge.length, unname(edgeLength(as.phy))) expect_equal("preorder", edgeOrder(as.phy)) ## test preservation of order attribute as.phy <- as(reorder(tr, "cladewise"), "phylo4") expect_equal("preorder", edgeOrder(as.phy)) as.phy <- as(reorder(tr, "pruningwise"), "phylo4") expect_equal("postorder", edgeOrder(as.phy)) ## test phylo import when only 2 tips tr2 <- ape::drop.tip(tr, 3:ape::Ntip(tr)) expect_equal(nTips(as(tr2, "phylo4")), 2) expect_equal(nNodes(as(tr2, "phylo4")), 1) ## simple roundtrip test phy <- as(tr, "phylo4") expect_equal(tr, as(phy, "phylo")) }) # note: this method mostly just wraps phylo->phylo4 coercion (tested # above) and phylo4d("phylo4") method (tested in runit.class-phylo4d.R) test_that("phylo to phylo4d", { expect_equal(as(tr, "phylo4d"), phylo4d(tr)) phyd <- as(tr, "phylo4d") expect_true(class(phyd)=="phylo4d") # simple roundtrip test phyd <- as(tr, "phylo4d") expect_warning(phyo <- as(phyd, "phylo")) expect_equal(tr, phyo) }) ## test.multiPhylo.As.multiPhylo4 <- function() { ## } ## test.multiPhylo4.As.multiPhylo <- function() { ## } test_that("nexml to phylo4", { nxml <- RNeXML::nexml_read(compFile) phy4 <- as(nxml, "phylo4") expect_true(all(tipLabels(phy4) %in% paste("taxon", 1:10, sep="_"))) expect_equal(nEdges(phy4), 19) }) test_that("nexml to phylo4d", { nxml <- RNeXML::nexml_read(compFile) phy4d <- as(nxml, "phylo4d") nxmldt <- RNeXML::get_characters(nxml) phy4d2 <- phylo4d(get_trees(nxml), nxmldt[sample(1:nrow(nxmldt)), ]) expect_true(all(tipLabels(phy4d) %in% paste("taxon", 1:10, sep="_"))) expect_equal(nEdges(phy4d), 19) expect_equal(phy4d, phy4d2) expect_equal(ncol(tdata(phy4d, "tip")), 2) expect_true(all(names(tdata(phy4d, "tip")) %in% c("log.snout.vent.length", "reef.dwelling"))) }) test_that("phylo4 to phylo", { ## phylo tree in unknown order expect_equal(suppressWarnings(as(phy, "phylo")), tr) # ...now check for warning for unknown order expect_warning(as(phy, "phylo")) # phylo tree in cladewise order tr.cladewise <- reorder(tr, "cladewise") phy.c <- as(tr.cladewise, "phylo4") expect_equal(as(phy.c, "phylo"), tr.cladewise) # phylo tree in pruningwise order tr.pruningwise <- reorder(tr, "pruningwise") phy.p <- as(tr.pruningwise, "phylo4") expect_equal(suppressWarnings(as(phy.p, "phylo")), tr.pruningwise) # after transforming the jumbled tree to phylo and back, edge matrix # and edge slots should still be in the original order, but node slots # should be back in nodeId order phy.r <- reorder(phy.alt) phy.roundtrip.r <- reorder(as(suppressWarnings(as(phy.alt, "phylo")), "phylo4")) expect_equal(edges(phy.roundtrip.r), edges(phy.r)) expect_equal(edgeLength(phy.roundtrip.r), edgeLength(phy.r)) expect_equal(labels(phy.roundtrip.r), labels(phy.r)) }) ## this coerce method is defined implicitly test_that("phylo to phylo4d", { ## phylo tree in unknown order phyd <- as(tr, "phylo4d") tipData(phyd) <- data.frame(x=1:5, row.names=tipLabels(phyd)) expect_equal(suppressWarnings(as(phyd, "phylo")), tr) ## ...now check for warning for unknown order expect_warning(as(phyd, "phylo")) ## phylo tree in cladewise order tr.cladewise <- reorder(tr, "cladewise") phyd <- as(tr.cladewise, "phylo4d") tipData(phyd) <- data.frame(x=1:5, row.names=tipLabels(phyd)) expect_equal(suppressWarnings(as(phyd, "phylo")), tr.cladewise) ## ...now check for warning for dropping data expect_warning(as(phyd, "phylo")) ## phylo tree in pruningwise order tr.pruningwise <- reorder(tr, "pruningwise") phyd <- as(tr.pruningwise, "phylo4d") tipData(phyd) <- data.frame(x=1:5, row.names=tipLabels(phyd)) expect_equal(suppressWarnings(as(phyd, "phylo")), tr.pruningwise) }) ##test.phylo4.As.phylog <- function() { ##} test_that("phylo4 to data.frame", { phy.show <- phylobase:::.phylo4ToDataFrame(phy.alt, "pretty") expect_equal(phy.show$label, c(lab.tip, lab.int)) expect_equal(phy.show$node, c(nid.tip, nid.int)) expect_equal(phy.show$ancestor, ancestor[match(c(nid.tip, nid.int), descendant)]) expect_equal(phy.show$edge.length, sort(elen)) expect_equal(phy.show$node.type, factor(unname(nodeType(phy)))) }) ## core functionality is already tested in test..phylo4ToDataFrame() test_that("phylo4 to data.frame", { ## rooted tree expect_true(is.data.frame(as(phy, "data.frame"))) ## unrooted tree tru <- ape::unroot(tr) phyu <- as(tru, "phylo4") # should probably check that this coercion results in something # *correct*, not just that it produces a data.frame expect_true(is.data.frame(as(phyu, "data.frame"))) }) phylobase/tests/testthat/test.prune.R0000644000176200001440000000066712347155416017515 0ustar liggesusers# # --- Test prune.R --- # data(geospiza) gtree <- extractTree(geospiza) context("prune") test_that("prune works on phylo4 objects", { # function(phy, tip, trim.internal = TRUE, subtree = FALSE, ...) expect_equal(gtree, prune(gtree, character(0))) }) test_that("prune works on phylo4d objects", { # function(phy, tip, trim.internal = TRUE, subtree = FALSE, ...) expect_equal(geospiza, prune(geospiza, character(0))) }) phylobase/tests/test-all.R0000644000176200001440000000005312436337710015256 0ustar liggesusers library(testthat) test_check("phylobase") phylobase/src/0000755000176200001440000000000013076473202013033 5ustar liggesusersphylobase/src/Makevars0000644000176200001440000000016713076473202014533 0ustar liggesusersPKG_CPPFLAGS=-I. -DHAVE_INTTYPES_H -DASSERTS_TO_EXCEPTIONS ## PKG_LIBS = `$(R_HOME)/bin/Rscript -e "Rcpp:::LdFlags()"` phylobase/src/phylobase_init.c0000644000176200001440000000711013076473202016207 0ustar liggesusers#include #include #include // for NULL #include /* FIXME: Check these declarations against the C/Fortran source code. */ /* .C calls */ extern void phyloxx(void *, void *, void *, void *, void *, void *); extern void reorderBinary(void *, void *, void *, void *, void *, void *, void *); extern void reorderRobust(void *, void *, void *, void *, void *, void *); /* .Call calls */ extern SEXP ancestors_c(SEXP, SEXP, SEXP); extern SEXP descendants_c(SEXP, SEXP, SEXP); extern SEXP phylobase_all_naC(SEXP); extern SEXP phylobase_any_naC(SEXP); extern SEXP phylobase_checkTreeCpp(SEXP, SEXP); extern SEXP phylobase_edgeIdCpp(SEXP, SEXP); extern SEXP phylobase_getAllNodesFast(SEXP); extern SEXP phylobase_getAllNodesSafe(SEXP); extern SEXP phylobase_getRange(SEXP, SEXP); extern SEXP phylobase_hasDuplicatedLabelsCpp(SEXP); extern SEXP phylobase_hasPolytomy(SEXP); extern SEXP phylobase_hasSingleton(SEXP); extern SEXP phylobase_isLabelName(SEXP, SEXP); extern SEXP phylobase_nb_naC(SEXP); extern SEXP phylobase_nRoots(SEXP); extern SEXP phylobase_nTipsFastCpp(SEXP); extern SEXP phylobase_nTipsSafe(SEXP); extern SEXP phylobase_tabulateTips(SEXP); extern SEXP phylobase_testEqInt(SEXP, SEXP); extern SEXP phylobase_tipsFast(SEXP); extern SEXP phylobase_tipsSafe(SEXP, SEXP); static const R_CMethodDef CEntries[] = { {"phyloxx", (DL_FUNC) &phyloxx, 6}, {"reorderBinary", (DL_FUNC) &reorderBinary, 7}, {"reorderRobust", (DL_FUNC) &reorderRobust, 6}, {NULL, NULL, 0} }; static const R_CallMethodDef CallEntries[] = { {"ancestors_c", (DL_FUNC) &ancestors_c, 3}, {"descendants_c", (DL_FUNC) &descendants_c, 3}, {"phylobase_all_naC", (DL_FUNC) &phylobase_all_naC, 1}, {"phylobase_any_naC", (DL_FUNC) &phylobase_any_naC, 1}, {"phylobase_checkTreeCpp", (DL_FUNC) &phylobase_checkTreeCpp, 2}, {"phylobase_edgeIdCpp", (DL_FUNC) &phylobase_edgeIdCpp, 2}, {"phylobase_getAllNodesFast", (DL_FUNC) &phylobase_getAllNodesFast, 1}, {"phylobase_getAllNodesSafe", (DL_FUNC) &phylobase_getAllNodesSafe, 1}, {"phylobase_getRange", (DL_FUNC) &phylobase_getRange, 2}, {"phylobase_hasDuplicatedLabelsCpp", (DL_FUNC) &phylobase_hasDuplicatedLabelsCpp, 1}, {"phylobase_hasPolytomy", (DL_FUNC) &phylobase_hasPolytomy, 1}, {"phylobase_hasSingleton", (DL_FUNC) &phylobase_hasSingleton, 1}, {"phylobase_isLabelName", (DL_FUNC) &phylobase_isLabelName, 2}, {"phylobase_nb_naC", (DL_FUNC) &phylobase_nb_naC, 1}, {"phylobase_nRoots", (DL_FUNC) &phylobase_nRoots, 1}, {"phylobase_nTipsFastCpp", (DL_FUNC) &phylobase_nTipsFastCpp, 1}, {"phylobase_nTipsSafe", (DL_FUNC) &phylobase_nTipsSafe, 1}, {"phylobase_tabulateTips", (DL_FUNC) &phylobase_tabulateTips, 1}, {"phylobase_testEqInt", (DL_FUNC) &phylobase_testEqInt, 2}, {"phylobase_tipsFast", (DL_FUNC) &phylobase_tipsFast, 1}, {"phylobase_tipsSafe", (DL_FUNC) &phylobase_tipsSafe, 2}, {NULL, NULL, 0} }; void R_init_phylobase(DllInfo *dll) { R_registerRoutines(dll, CEntries, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } phylobase/src/checkPhylo4.cpp0000644000176200001440000003027313076473202015721 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- #include #include // std::count_if #include // std::vector #include // template std::string NumberToString ( T Number ) { std::ostringstream ss; ss << Number; return ss.str(); } bool isZero(int i) { return (i == 0); } bool isOne(int i) { return ( i == 1); } bool isSupTwo(int i) { return (i > 2); } bool isEqual(int i, int j) { return (i == j); } Rcpp::IntegerVector getAnces(Rcpp::IntegerMatrix obj) { // returns the first column (ancestors) of the edge matrix Rcpp::IntegerMatrix::Column out = obj( Rcpp::_ , 0); return out; } Rcpp::IntegerVector getDesc(Rcpp::IntegerMatrix obj) { // returns the second column (descendants) of the edge matrix Rcpp::IntegerMatrix::Column out = obj( Rcpp::_ , 1); return out; } //[[Rcpp::export]] bool isLabelName(Rcpp::CharacterVector lblToCheck, Rcpp::CharacterVector lbl ) { Rcpp::CharacterVector noLbl = Rcpp::setdiff(lblToCheck, lbl); return noLbl.size() == 0; } //[[Rcpp::export]] int nRoots (Rcpp::IntegerVector ances) { int ans = std::count (ances.begin(), ances.end(), 0); return ans; } //[[Rcpp::export]] std::vector tabulateTips (Rcpp::IntegerVector ances) { // tabulates ancestor nodes that are not the root. int n = Rcpp::max(ances); std::vector ans(n); for (int i=0; i < ances.size(); i++) { int j = ances[i]; if (j > 0) { ans[j - 1]++; } } return ans; } //[[Rcpp::export]] int nTipsSafe (Rcpp::IntegerVector ances) { // count how many zeros are in the tabulated vector of ancestors // this gives the number of tips std::vector tabTips = tabulateTips(ances); int j = count_if (tabTips.begin(), tabTips.end(), isZero); return j; } //[[Rcpp::export]] int nTipsFastCpp (Rcpp::IntegerVector ances) { // if nodes are correctly numbered min(ances) - 1 = nb of tips // (after removing the root, which is equal to 0). int nroots = nRoots(ances); if (nroots > 0) { int whichRoot = Rcpp::which_min(ances); ances.erase(whichRoot); } int tmp = Rcpp::min(ances); return tmp - 1; } //[[Rcpp::export]] bool hasSingleton (Rcpp::IntegerVector ances) { std::vector tabTips = tabulateTips(ances); int j = count_if (tabTips.begin(), tabTips.end(), isOne); return j > 0; } //[[Rcpp::export]] bool hasPolytomy (Rcpp::IntegerVector ances) { std::vector tabTips = tabulateTips(ances); int j = count_if (tabTips.begin(), tabTips.end(), isSupTwo); return j > 0; } //[[Rcpp::export]] Rcpp::IntegerVector tipsSafe (Rcpp::IntegerVector ances, Rcpp::IntegerVector desc) { Rcpp::IntegerVector res = Rcpp::match(desc, ances); Rcpp::LogicalVector istip = Rcpp::is_na(res); int nedge = ances.size(); std::vector y(nedge); int j = 0; for(int i = 0; i < nedge; i++) { if (istip[i]) { y[j] = desc[i]; j++; } } Rcpp::IntegerVector ans(j); std::copy (y.begin(), y.begin()+j, ans.begin()); std::sort (ans.begin(), ans.end()); return ans; } //[[Rcpp::export]] Rcpp::IntegerVector tipsFast (Rcpp::IntegerVector ances) { int ntips = nTipsFastCpp(ances); Rcpp::IntegerVector ans = Rcpp::seq_len(ntips); return ans; } //[[Rcpp::export]] Rcpp::IntegerVector getAllNodesSafe (Rcpp::IntegerMatrix edge) { Rcpp::IntegerVector ans = Rcpp::as_vector(edge); Rcpp::IntegerVector tmp = Rcpp::unique(ans); std::sort(tmp.begin(), tmp.end()); return tmp; } //[[Rcpp::export]] Rcpp::IntegerVector getAllNodesFast (Rcpp::IntegerMatrix edge) { Rcpp::IntegerVector tmp = Rcpp::as_vector(edge); Rcpp::IntegerVector maxN = Rcpp::range(tmp); Rcpp::IntegerVector ans; if (maxN[0] == 0) { ans = Rcpp::seq_len(maxN[1] + 1); ans = ans - 1; } else { ans = Rcpp::seq_len(maxN[1]); } return ans; } // Rcpp::List testNodes (Rcpp::IntegerMatrix edge, bool rooted) { // Rcpp::IntegerVector allNodes = Rcpp::as_vector(edge); // allNodes = Rcpp::unique(allNodes); // std::sort (allNodes.begin(), allNodes.end()); // Rcpp::IntegerVector supposedNodes = getAllNodesFast(edge, rooted); // Rcpp::IntegerVector test = Rcpp::setdiff(supposedNodes, allNodes); // Rcpp::LogicalVector res = supposedNodes == allNodes; // return Rcpp::List::create(supposedNodes, allNodes, test, res); // } //[[Rcpp::export]] Rcpp::List testEqInt (Rcpp::IntegerVector x, Rcpp::IntegerVector y) { Rcpp::LogicalVector xy = x == y; Rcpp::LogicalVector yx = y == x; return Rcpp::List::create(xy, yx); } // Rcpp::IntegerVector getInternalNodes (Rcpp::IntegerMatrix edge, bool rooted) { // Rcpp::IntegerVector ances = getAnces(edge); // Rcpp::IntegerVector allNodes = getAllNodesFast(edge, rooted); // Rcpp::IntegerVector tips = tipsFast(ances); // Rcpp::IntegerVector intNodes = Rcpp::setdiff(allNodes, tips); // intNodes.erase(intNodes.begin()); // return intNodes; // } //[[Rcpp::export]] bool all_naC (Rcpp::NumericVector x) { return is_true(all(is_na(x))); } //[[Rcpp::export]] bool any_naC (Rcpp::NumericVector x) { return is_true(any(is_na(x))); } //[[Rcpp::export]] int nb_naC (Rcpp::NumericVector x) { return sum(is_na(x)); } //[[Rcpp::export]] Rcpp::NumericVector getRange(Rcpp::NumericVector x, const bool na_rm) { Rcpp::NumericVector out(2); out[0] = R_PosInf; out[1] = R_NegInf; int n = x.length(); for(int i = 0; i < n; ++i) { if (!na_rm && R_IsNA(x[i])) { out[0] = NA_REAL; out[1] = NA_REAL; return(out); } if (x[i] < out[0]) out[0] = x[i]; if (x[i] > out[1]) out[1] = x[i]; } return(out); } //[[Rcpp::export]] bool hasDuplicatedLabelsCpp (Rcpp::CharacterVector label) { return is_true(any(Rcpp::duplicated(na_omit(label)))); } Rcpp::CharacterVector edgeIdCppInternal (Rcpp::IntegerVector tmp1, Rcpp::IntegerVector tmp2) { Rcpp::CharacterVector tmpV1 = Rcpp::as< Rcpp::CharacterVector >(tmp1); Rcpp::CharacterVector tmpV2 = Rcpp::as< Rcpp::CharacterVector >(tmp2); int Ne = tmp1.size(); Rcpp::CharacterVector res(Ne); for (int i = 0; i < Ne; i++) { std::string tmpS1; tmpS1 = tmpV1[i]; std::string tmpS2; tmpS2 = tmpV2[i]; std::string tmpS; tmpS = tmpS1.append("-"); tmpS = tmpS.append(tmpS2); res[i] = tmpS; } return res; } //[[Rcpp::export]] Rcpp::CharacterVector edgeIdCpp (Rcpp::IntegerMatrix edge, std::string type) { Rcpp::IntegerVector ances = getAnces(edge); Rcpp::IntegerVector desc = getDesc(edge); int nedge; if (type == "tip" || type == "internal") { Rcpp::IntegerVector tips = tipsFast(ances); nedge = tips.size(); Rcpp::IntegerVector ans = match(tips, desc); if (type == "tip") { Rcpp::IntegerVector tmpAnces(nedge); Rcpp::IntegerVector tmpDesc(nedge); for (int j = 0; j < nedge; j++) { tmpAnces[j] = ances[ans[j]-1]; tmpDesc[j] = desc[ans[j]-1]; } Rcpp::CharacterVector c1(nedge); c1 = edgeIdCppInternal(tmpAnces, tmpDesc); return c1; } else if (type == "internal") { int allEdges = ances.size(); Rcpp::IntegerVector idEdge = Rcpp::seq_len(allEdges); Rcpp::IntegerVector intnd = Rcpp::setdiff(idEdge, ans); nedge = intnd.size(); Rcpp::IntegerVector tmpAnces(nedge); Rcpp::IntegerVector tmpDesc(nedge); for (int j = 0; j < nedge; j++) { tmpAnces[j] = ances[intnd[j]-1]; tmpDesc[j] = desc[intnd[j]-1]; } Rcpp::CharacterVector c1(nedge); c1 = edgeIdCppInternal(tmpAnces, tmpDesc); return c1; } } else { nedge = ances.size(); Rcpp::IntegerVector tmpAnces = ances; Rcpp::IntegerVector tmpDesc = desc; Rcpp::CharacterVector c1(nedge); c1 = edgeIdCppInternal(tmpAnces, tmpDesc); return c1; } return ""; } //[[Rcpp::export]] Rcpp::List checkTreeCpp(Rcpp::S4 obj, Rcpp::List opts) { std::string err, wrn; Rcpp::IntegerMatrix ed = obj.slot("edge"); int nrow = ed.nrow(); Rcpp::IntegerVector ances = getAnces(ed); //Rcpp::IntegerVector desc = getDesc(ed); int nroots = nRoots(ances); //bool rooted = nroots > 0; Rcpp::NumericVector edLength = obj.slot("edge.length"); Rcpp::CharacterVector edLengthNm = edLength.names(); Rcpp::CharacterVector label = obj.slot("label"); Rcpp::CharacterVector labelNm = label.names(); Rcpp::CharacterVector edLabel = obj.slot("edge.label"); Rcpp::CharacterVector edLabelNm = edLabel.names(); Rcpp::IntegerVector allnodesSafe = getAllNodesSafe(ed); Rcpp::IntegerVector allnodesFast = getAllNodesFast(ed); int nEdLength = edLength.size(); //int nLabel = label.size(); //int nEdLabel = edLabel.size(); int nEdges = nrow; bool hasEdgeLength = !all_naC(edLength); // check tips int ntipsSafe = nTipsSafe(ances); int ntipsFast = nTipsFastCpp(ances); bool testnTips = ntipsFast == ntipsSafe; if (! testnTips) { err.append("Tips incorrectly labeled. "); } //check internal nodes bool testNodes = Rcpp::all(allnodesSafe == allnodesFast).is_true() && // is both ways comparison needed? Rcpp::all(allnodesFast == allnodesSafe).is_true(); if (! testNodes) { err.append("Nodes incorrectly labeled. "); } // check edge lengths if (hasEdgeLength) { if (nEdLength != nEdges) { err.append("Number of edge lengths do not match number of edges. "); } // if (nb_naC(edLength) > nroots) { // not enough! -- best done in R // err.append("Only the root should have NA as an edge length. "); // } if (getRange(edLength, TRUE)[0] < 0) { err.append("Edge lengths must be non-negative. "); } Rcpp::CharacterVector edgeLblSupp = edgeIdCpp(ed, "all"); Rcpp::CharacterVector edgeLblDiff = Rcpp::setdiff(edLengthNm, edgeLblSupp); if ( edgeLblDiff.size() != 0 ) { err.append("Edge lengths incorrectly labeled. "); } } // check label names Rcpp::CharacterVector chrLabelNm = Rcpp::as(allnodesFast); int j = 0; while (j < nroots) { //remove root(s) chrLabelNm.erase(0); j++; } bool testLabelNm = isLabelName(labelNm, chrLabelNm); if (!testLabelNm) { err.append("Tip and node labels must be a named vector, the names must match the node IDs. "); err.append("Use tipLabels<- and/or nodeLabels<- to update them. "); } // check that tips have labels Rcpp::CharacterVector tiplabel(ntipsFast); std::copy (label.begin(), label.begin()+ntipsFast, tiplabel.begin()); bool emptyTipLabel = is_true(any(Rcpp::is_na(tiplabel))); if ( emptyTipLabel ) { err.append("All tips must have a label."); } // check edgeLabels Rcpp::CharacterVector chrEdgeLblNm = edgeIdCpp(ed, "all"); bool testEdgeLblNm = isLabelName(edLabelNm, chrEdgeLblNm); if (!testEdgeLblNm) { err.append("Edge labels are not labelled correctly. Use the function edgeLabels<- to update them. "); } // make sure that tips and node labels are unique if (hasDuplicatedLabelsCpp(label)) { std::string labOpt = opts["allow.duplicated.labels"]; if (labOpt == "fail") { err.append("Labels are not unique. "); } if (labOpt == "warn") { wrn.append("Labels are not unique. "); } } // check for polytomies if (hasPolytomy(ances)) { std::string msgPoly = "Tree includes polytomies. "; std::string polyOpt = opts["poly"]; if (polyOpt == "fail") { err.append(msgPoly); } if (polyOpt == "warn") { wrn.append(msgPoly); } } // check number of roots if (nroots > 1) { std::string msgRoot = "Tree has more than one root. "; std::string rootOpt = opts["multiroot"]; if (rootOpt == "fail") { err.append(msgRoot); } if (rootOpt == "warn") { wrn.append(msgRoot); } } // check for singletons if (hasSingleton(ances)) { std::string msgSing = "Tree contains singleton nodes. "; std::string singOpt = opts["singleton"]; if (singOpt == "fail") { err.append(msgSing); } if (singOpt == "warn") { wrn.append(msgSing); } } return Rcpp::List::create(err, wrn); } phylobase/src/reorderRobust.c0000644000176200001440000000306113076473202016040 0ustar liggesusers/* reorderRobust.c: Given a root node, reorder a tree either as postorder or preorder. Works on any valid tree, including those with singleton nodes and/or polytomies. Function inputs are derived from a phylo4 edge matrix. The new descendant node ordering is stored in descendantNew. */ #include typedef struct { int *descendantNew; int *ancestor; int *descendant; int nEdges; int index; } tree; void postorderRobust(tree*, int node); void preorderRobust(tree*, int node); void reorderRobust(int *descendantNew, int *root, int *ancestor, int *descendant, int *nEdges, int *order) { tree tr; tr.ancestor = ancestor; tr.descendant = descendant; tr.descendantNew = descendantNew; tr.nEdges = *nEdges; tr.index = 0; if (*order==0) { postorderRobust(&tr, *root); } else if (*order==1) { preorderRobust(&tr, *root); } else { error("invalid order type"); } } // postorder: continue traversing to the end, then record node void postorderRobust(tree *tr, int node) { for (int i=0; inEdges; i++) { if (tr->ancestor[i]==node) { postorderRobust(tr, tr->descendant[i]); } } tr->descendantNew[tr->index] = node; tr->index += 1; } // preorder: record node before continuing traversal void preorderRobust(tree *tr, int node) { tr->descendantNew[tr->index] = node; tr->index += 1; for (int i=0; inEdges; i++) { if (tr->ancestor[i]==node) { preorderRobust(tr, tr->descendant[i]); } } } phylobase/src/phyloXX.c0000644000176200001440000000471013076473202014614 0ustar liggesusers/* descendants.c: Identify all descendants of a given node. Function inputs are derived from a phylo4 edge matrix, which *must* be in preorder order. The isDescendant input vector should contain 1 for the immediate children of the node, and 0 otherwise. The function returns this vector updated to include all further descendants. */ // test1 <- function() { // for (i in edge[, 2]) { // dex <- edge[, 1] == i // cur <- edge[, 2] == i // xx[dex] <- phy@edge.length[dex] + xx[cur] // segs$v0x[dex] <- xx[cur] // } // return(list(segs=segs, xx=xx)) // } // test1out <- test1() // segs <- test1out$segs // xx <- test1out$xx // test2 <- function() { // for(i in rev((Ntips + 1):nEdges(phy))) { // dex <- edge[, 1] == i // cur <- edge[, 2] == i // yy[cur] <- segs$v0y[dex] <- mean(yy[dex]) // } // return(list(segs=segs, yy=yy)) // } // test2out <- test2() // segs <- test2out$segs // yy <- test2out$yy // segs$h0y <- segs$h1y <- segs$v1y <- yy #include // // void phyloyy(int *edge1, int *edge2, int *ntips, // int *numEdges, double *yy, double *v0y) // { // int i; // int k; // int j; // int cur; // int des; // int count; // double tmp; // double theMean; // Rprintf("test\n"); // for (i=*numEdges; i > *ntips ; i--) { // for (k=0; k<*numEdges; k++) { // if(i == edge2[k]) { // cur = k; // } // } // tmp=0; // count=0; // for (j=0; j<*numEdges; j++) { // if(i == edge1[j]) { // des = j; // tmp += yy[j]; // count += 1; // } // } // theMean = tmp / count; // yy[cur] = theMean; // for (j=0; j<*numEdges; j++) { // if(i == edge1[j]) { // v0y[j] = theMean; // } // } // // } // } void phyloxx(int *edge1, int *edge2, double *edgeLengths, int *numEdges, double *xx, double *v0x) { int j; int i; int k; int cur=0; for (i=0; i <*numEdges; i++) { for (k=0; k<*numEdges; k++) { if(edge2[i] == edge2[k]) { cur = k; } } for (j=0; j<*numEdges; j++) { if(edge2[i] == edge1[j]) { xx[j] = edgeLengths[j] + xx[cur]; v0x[j] = xx[cur]; } } } } phylobase/src/descendants.c0000644000176200001440000000311713076473202015474 0ustar liggesusers/* descendants.c: Identify all descendants of each node in the input vector. Function inputs are derived from a phylo4 edge matrix, which *must* be in preorder order. The isDescendant output is an indicator matrix of which nodes (rows, corresponding to the decendant vector) are descendants of each input node (columns, corresponding to the nodes vector). It will contain 1 for each descendant of the node, *including itself*, and 0 for all other nodes. Jim Regetz (NCEAS) */ #include #include SEXP descendants_c(SEXP nod, SEXP anc, SEXP des) { int numEdges = length(anc); int numNodes = length(nod); int* nodes = INTEGER(nod); int* ancestor = INTEGER(anc); int* descendant = INTEGER(des); int child = 0; SEXP isDescendant; PROTECT(isDescendant = allocMatrix(INTSXP, numEdges, numNodes)); for (int n=0; n #include SEXP ancestors_c(SEXP nod, SEXP anc, SEXP des) { int numEdges = length(anc); int numNodes = length(nod); int* nodes = INTEGER(nod); int* ancestor = INTEGER(anc); int* descendant = INTEGER(des); int parent = 0; SEXP isAncestor; PROTECT(isAncestor = allocMatrix(INTSXP, numEdges, numNodes)); for (int n=0; n typedef struct { int *descendantNew; int *ancestor; int *left; int *right; int nEdges; int index; } tree; void postorderBinary(tree*, int node); void preorderBinary(tree*, int node); void reorderBinary(int *descendantNew, int *root, int *ancestor, int *left, int *right, int *nEdges, int *order) { tree tr; tr.ancestor = ancestor; tr.left = left; tr.right = right; tr.descendantNew = descendantNew; tr.nEdges = *nEdges; tr.index = 0; if (*order==0) { postorderBinary(&tr, *root); } else if (*order==1) { preorderBinary(&tr, *root); } else { error("invalid order type"); } } // postorder: continue traversing to the end, then record node void postorderBinary(tree *tr, int node) { for (int i=0; inEdges; i++) { if (tr->ancestor[i]==node) { postorderBinary(tr, tr->left[i]); postorderBinary(tr, tr->right[i]); } } tr->descendantNew[tr->index] = node; tr->index += 1; } // preorder: record node first, then continue traversing void preorderBinary(tree *tr, int node) { tr->descendantNew[tr->index] = node; tr->index += 1; for (int i=0; inEdges; i++) { if (tr->ancestor[i]==node) { preorderBinary(tr, tr->left[i]); preorderBinary(tr, tr->right[i]); } } } phylobase/src/Makevars.win0000644000176200001440000000042013076473202015317 0ustar liggesusers## PKG_LIBS = -s $(shell Rscript -e 'Rcpp:::LdFlags()') -L"$(RHOME)/bin" -lR --no-export-all-symbols --add-stdcall-alias PKG_CXXFLAGS = -I. -DHAVE_INTTYPES_H -DASSERTS_TO_EXCEPTIONS ## PKG_LIBS = $(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" -e "Rcpp:::LdFlags()") phylobase/src/RcppExports.cpp0000644000176200001440000001737013076473202016040 0ustar liggesusers// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include using namespace Rcpp; // isLabelName bool isLabelName(Rcpp::CharacterVector lblToCheck, Rcpp::CharacterVector lbl); RcppExport SEXP phylobase_isLabelName(SEXP lblToCheckSEXP, SEXP lblSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::CharacterVector >::type lblToCheck(lblToCheckSEXP); Rcpp::traits::input_parameter< Rcpp::CharacterVector >::type lbl(lblSEXP); rcpp_result_gen = Rcpp::wrap(isLabelName(lblToCheck, lbl)); return rcpp_result_gen; END_RCPP } // nRoots int nRoots(Rcpp::IntegerVector ances); RcppExport SEXP phylobase_nRoots(SEXP ancesSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type ances(ancesSEXP); rcpp_result_gen = Rcpp::wrap(nRoots(ances)); return rcpp_result_gen; END_RCPP } // tabulateTips std::vector tabulateTips(Rcpp::IntegerVector ances); RcppExport SEXP phylobase_tabulateTips(SEXP ancesSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type ances(ancesSEXP); rcpp_result_gen = Rcpp::wrap(tabulateTips(ances)); return rcpp_result_gen; END_RCPP } // nTipsSafe int nTipsSafe(Rcpp::IntegerVector ances); RcppExport SEXP phylobase_nTipsSafe(SEXP ancesSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type ances(ancesSEXP); rcpp_result_gen = Rcpp::wrap(nTipsSafe(ances)); return rcpp_result_gen; END_RCPP } // nTipsFastCpp int nTipsFastCpp(Rcpp::IntegerVector ances); RcppExport SEXP phylobase_nTipsFastCpp(SEXP ancesSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type ances(ancesSEXP); rcpp_result_gen = Rcpp::wrap(nTipsFastCpp(ances)); return rcpp_result_gen; END_RCPP } // hasSingleton bool hasSingleton(Rcpp::IntegerVector ances); RcppExport SEXP phylobase_hasSingleton(SEXP ancesSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type ances(ancesSEXP); rcpp_result_gen = Rcpp::wrap(hasSingleton(ances)); return rcpp_result_gen; END_RCPP } // hasPolytomy bool hasPolytomy(Rcpp::IntegerVector ances); RcppExport SEXP phylobase_hasPolytomy(SEXP ancesSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type ances(ancesSEXP); rcpp_result_gen = Rcpp::wrap(hasPolytomy(ances)); return rcpp_result_gen; END_RCPP } // tipsSafe Rcpp::IntegerVector tipsSafe(Rcpp::IntegerVector ances, Rcpp::IntegerVector desc); RcppExport SEXP phylobase_tipsSafe(SEXP ancesSEXP, SEXP descSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type ances(ancesSEXP); Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type desc(descSEXP); rcpp_result_gen = Rcpp::wrap(tipsSafe(ances, desc)); return rcpp_result_gen; END_RCPP } // tipsFast Rcpp::IntegerVector tipsFast(Rcpp::IntegerVector ances); RcppExport SEXP phylobase_tipsFast(SEXP ancesSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type ances(ancesSEXP); rcpp_result_gen = Rcpp::wrap(tipsFast(ances)); return rcpp_result_gen; END_RCPP } // getAllNodesSafe Rcpp::IntegerVector getAllNodesSafe(Rcpp::IntegerMatrix edge); RcppExport SEXP phylobase_getAllNodesSafe(SEXP edgeSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerMatrix >::type edge(edgeSEXP); rcpp_result_gen = Rcpp::wrap(getAllNodesSafe(edge)); return rcpp_result_gen; END_RCPP } // getAllNodesFast Rcpp::IntegerVector getAllNodesFast(Rcpp::IntegerMatrix edge); RcppExport SEXP phylobase_getAllNodesFast(SEXP edgeSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerMatrix >::type edge(edgeSEXP); rcpp_result_gen = Rcpp::wrap(getAllNodesFast(edge)); return rcpp_result_gen; END_RCPP } // testEqInt Rcpp::List testEqInt(Rcpp::IntegerVector x, Rcpp::IntegerVector y); RcppExport SEXP phylobase_testEqInt(SEXP xSEXP, SEXP ySEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type x(xSEXP); Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type y(ySEXP); rcpp_result_gen = Rcpp::wrap(testEqInt(x, y)); return rcpp_result_gen; END_RCPP } // all_naC bool all_naC(Rcpp::NumericVector x); RcppExport SEXP phylobase_all_naC(SEXP xSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::NumericVector >::type x(xSEXP); rcpp_result_gen = Rcpp::wrap(all_naC(x)); return rcpp_result_gen; END_RCPP } // any_naC bool any_naC(Rcpp::NumericVector x); RcppExport SEXP phylobase_any_naC(SEXP xSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::NumericVector >::type x(xSEXP); rcpp_result_gen = Rcpp::wrap(any_naC(x)); return rcpp_result_gen; END_RCPP } // nb_naC int nb_naC(Rcpp::NumericVector x); RcppExport SEXP phylobase_nb_naC(SEXP xSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::NumericVector >::type x(xSEXP); rcpp_result_gen = Rcpp::wrap(nb_naC(x)); return rcpp_result_gen; END_RCPP } // getRange Rcpp::NumericVector getRange(Rcpp::NumericVector x, const bool na_rm); RcppExport SEXP phylobase_getRange(SEXP xSEXP, SEXP na_rmSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::NumericVector >::type x(xSEXP); Rcpp::traits::input_parameter< const bool >::type na_rm(na_rmSEXP); rcpp_result_gen = Rcpp::wrap(getRange(x, na_rm)); return rcpp_result_gen; END_RCPP } // hasDuplicatedLabelsCpp bool hasDuplicatedLabelsCpp(Rcpp::CharacterVector label); RcppExport SEXP phylobase_hasDuplicatedLabelsCpp(SEXP labelSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::CharacterVector >::type label(labelSEXP); rcpp_result_gen = Rcpp::wrap(hasDuplicatedLabelsCpp(label)); return rcpp_result_gen; END_RCPP } // edgeIdCpp Rcpp::CharacterVector edgeIdCpp(Rcpp::IntegerMatrix edge, std::string type); RcppExport SEXP phylobase_edgeIdCpp(SEXP edgeSEXP, SEXP typeSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerMatrix >::type edge(edgeSEXP); Rcpp::traits::input_parameter< std::string >::type type(typeSEXP); rcpp_result_gen = Rcpp::wrap(edgeIdCpp(edge, type)); return rcpp_result_gen; END_RCPP } // checkTreeCpp Rcpp::List checkTreeCpp(Rcpp::S4 obj, Rcpp::List opts); RcppExport SEXP phylobase_checkTreeCpp(SEXP objSEXP, SEXP optsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::S4 >::type obj(objSEXP); Rcpp::traits::input_parameter< Rcpp::List >::type opts(optsSEXP); rcpp_result_gen = Rcpp::wrap(checkTreeCpp(obj, opts)); return rcpp_result_gen; END_RCPP } phylobase/NAMESPACE0000644000176200001440000000353013075431305013461 0ustar liggesusers# Generated by roxygen2: do not edit by hand export("[") export("edgeLabels<-") export("edgeLength<-") export("labels<-") export("nodeData<-") export("nodeLabels<-") export("rootNode<-") export("tdata<-") export("tipData<-") export("tipLabels<-") export(MRCA) export(addData) export(ancestor) export(ancestors) export(checkPhylo4) export(children) export(depthTips) export(descendants) export(edgeId) export(edgeLabels) export(edgeLength) export(edgeOrder) export(edges) export(extractTree) export(getEdge) export(getNode) export(hasDuplicatedLabels) export(hasEdgeLabels) export(hasEdgeLength) export(hasNodeData) export(hasNodeLabels) export(hasPoly) export(hasRetic) export(hasSingle) export(hasTipData) export(internalEdges) export(isRooted) export(isUltrametric) export(nData) export(nEdges) export(nNodes) export(nTips) export(names) export(nodeData) export(nodeDepth) export(nodeHeight) export(nodeId) export(nodeLabels) export(nodeType) export(phylo4) export(phylo4d) export(phyloXXYY) export(phylobase.options) export(phylobubbles) export(plotOneTree) export(prune) export(readNCL) export(readNewick) export(readNexus) export(rootNode) export(shortestPath) export(siblings) export(sumEdgeLength) export(tdata) export(terminalEdges) export(tip.data.plot) export(tipData) export(tipLabels) export(treePlot) exportClasses(phylo4) exportClasses(phylo4d) exportClasses(phylo4vcov) exportMethods("[") exportMethods(head) exportMethods(labels) exportMethods(names) exportMethods(plot) exportMethods(print) exportMethods(reorder) exportMethods(show) exportMethods(subset) exportMethods(summary) exportMethods(tail) import(RNeXML) import(ape) import(grid) import(methods) import(stats) importFrom(Rcpp,evalCpp) importFrom(ade4,newick2phylog) importFrom(graphics,plot) importFrom(rncl,rncl) importFrom(utils,head) importFrom(utils,tail) useDynLib(phylobase, .registration = TRUE) phylobase/NEWS.md0000644000176200001440000002201213076470631013342 0ustar liggesusers## CHANGES in phylobase VERSION 0.8.4 * CRAN maintenance release ## CHANGES in phylobase VERSION 0.8.2 * Fix typo in examples of phylo4d methods. ## CHANGES IN phylobase VERSION 0.8.0 ### New features * Initial basic support for converting RNeXML objects in phylo4 and phylo4d format. * New methods: `internalEdges()`, `terminalEdges()` * `descendants()` has now a `"ALL"` argument to include self in results * New method: `nodeHeight()` provides a consistent and comprehensive way of calculating the distance between a node and either the root or the tips. (fix #3) * The replacement methods for `labels`, `tipLabels`, `nodeLabels`, `edgeLabels` now accept `NA` or `NULL` to remove labels (fix #2) ### Major changes * `readNexus` and `readNewick` now internally use the package `rncl` to parse files. They also use a different approach to reconstruct the edge matrix. These changes make file parsing faster. Objects created with this new approach may not exactly be identical to those created in previous versions as node numbering might differ, they should however be fully compatible with each others. * `readNexus` and `readNewick` can now parse tree files with trees containing a subset of the taxa listed in the TAXA Block. * Source code for the package is hosted on GitHub at https://github.com/fmichonneau/phylobase ### Minor changes * All tests done with testthat * `rootNode` returns the rootNode using the same format as `getNode()`. * All documentation is in Roxygen format * `hasPoly`, `hasRetic`, `hasSingle` are now methods instead of functions. ### Deprecated functions * `nodeDepth` and `depthTips` are now deprecated and are replaced by `nodeHeight` ### Bug fixes * Fix bug: `NA` in labels were considered duplicated by `checkPhylo4()`. * Fix bug #605 (R-forge) -- treePlot subsets numeric data for plotting. * Fix bug #4: `descendants()` behave like `ancestors()` when provided with a vector of nodes and is consistent across all arguments. ## CHANGES IN phylobase VERSION 0.6.8 * Not many user-visible changes, most are related to improving speeds during test of object validation (most tests done in C++) and to getNode that is used by many functions. * Changes to package structure to make it compatible with devtools (switching testing to testthat -- partial at this stage) and docs to roxygen format (partial at this stage). * Changes to package structure to comply with new Rcpp standards ## CHANGES IN phylobase VERSION 0.6.5 * Updates from cout/cerr to Rcpp::Rcout/Rcerr * Comments in Nexus tree strings are being removed before being processed by readNCL ## CHANGES IN phylobase VERSION 0.6.3 * Fixed bugs in getNode in cases where labels included regexpr metacharacters and when a tip was labelled 0 * New methods: depthTips, nodeDepth and isUltrametric ## CHANGES IN phylobase VERSION 0.6.2 * Improve handling of errors returned by NCL (NxsException) * Fix bug in case state labels are missing from the NEXUS file * Upgrade to NCL 2.1.14 ## CHANGES IN phylobase VERSION 0.6.1 * Fix bugs that prevented building on Windows 64-bit systems ## CHANGES IN phylobase VERSION 0.6 ### MAJOR CHANGES * Updated to the Nexus Class Library (NCL) 2.1.12. * Changed the way NCL is built during the installation process. * Complete rewrite of the function readNexus which brings many new functionalities. * Nodes labels do not have to be unique. ### NEW FEATURES * In readNexus, the option return.labels gives the state labels of the characters. * It is now possible to import several types of data blocks in a single NEXUS file with readNexus. * The function phylobase.options() provides global options to control the behavior of the phylo4/phylo4d validator. * The new method hasDuplicatedLabels() indicates whether any node labels are duplicated. * The new method nData() returns the number of datasets associated with a tree. * The column that contains the labels can now be specified by its name in the function formatData() ### MINOR CHANGES * The function getNode() has been modified to allow node matching in the case of non-unique labels. * Many new unit tests. ### BUG FIXES * Far too many to document. See the SVN log for details. ### KNOWN ISSUES * Unrooted trees are not supported by all functions, e.g. plot() and reorder(). * Factors are not supported by the default plotting method. ## CHANGES IN phylobase VERSION 0.5 ### MAJOR CHANGES * A var-cov matrix tree class, phylo4vcov, and methods for converting to and from other classes now exists. * Replaced separate the tip.label and node.label slots with a unified label slot in the phylo4 class definition. * Replaced separate the tip.data and node.data into a single data slot in the phylo4d class definition. * The phylo4 class grew a annotate slot. * The phylo4d class grew a metadata slot. * Added an order slot to the phylo4 class definition and updated as() methods to assign the proper order (if possible) when converting between ape and phylobase tree formats. * The Nnode slot was removed from the phylo4 class definition. * An explicit root edge has been added to the edge matrix with 0 as the ancestor and nTips(phy) + 1 as the rood node. * The edgeLabels() and edgeLength() accessors now return vectors with named elements in the same order as rows of the edge matrix, even when some/all values are missing. * The labels() accessor and nodeID() methods now always return labels in ascending order of node ID * Many function and argument names and defaults have been changed to make them more consistent most functions follow the getNode() pattern. * The plotting functions have been replaced (see below). * Now, data are matched against node numbers instead of node labels. * Tip and internal node labels have now internal names that are character strings of the node number they correspond to. Thus it is possible to store labels in any order and assignment of labels more robust. * We now use the RUnit package (not required for normal use) for adding unit tests. Adding unit tests to inst/unitTests/ is now preferred over the tests/ directory. * Numerous changes to pruning and tree subsetting code. It is considerably more robust and no longer relies on calls to APE. ### NEW FEATURES * Added a function nodeType() for identifying whether a node is root, tip or internal. * Changed nodeNumbers to nodeId() and extended it abilities. * Added method reorder() for converting edge matrices into preorder or postorder. * Added the edgeOrder accessor to get the order of a phylobase object. * Added a package help file accessible from ?phylobase. * Added labels()<- for assigning labels. * Added edgeLength()<- for assigning edgeLengths. * Added a phylo4() method for importing APE phylo objects. * Added a hasTipData() method. * Added a edgeId() method. * Created the addData() method for adding data to phylo4 objects. * Added tipData and nodeData getter/setter methods * If all node.labels are numerical values, they are automatically converted as data. Useful when importing consensus tree from MrBayes. * It is now possible to print tree objects in edge order using the edgeOrder argument in printphylo4(). * reorder(), descendants(), ancestors(), and portions of the plotting code have been recoded in C to improve performance. * Added a developer vignette to document and guide development of the phylobase package. * The previous plotting functions, based on base graphics, have been replaced with function based on the grid graphics device. * A S4 generic plot() function, calling treePlot() has been added it dispatches a plotting function based on object class and arguments. * Plots using grid based code can be inserted at the tree tips using the tip.plot.fun argument in plot() * The getNode() method has been enhanced to allow matching against specific node types, and if the requested node is missing, all nodes of specified type are returned. * Changed getEdge() to allow no node argument, which returns all edges appropriate for the given type. ### CHANGES * Node labels are, if not supplied, a vector of NA. * printphylo() is now deprecated, print() and summary() now alsow work on empty objects. * phylo4() is now and S4 generic with signature "matrix". * phylobase now uses a NAMESPACE file. * Legacy plotting code (0.4) can be found in the SVN repo tags directory. * The tdata default "type" argument changed to 'all'. * Row names now stored internally as numeric, not character. ### BUG FIXES * Far too many to document. See the SVN log for details. ### KNOWN ISSUES * Unrooted trees are not supported by all functions, e.g. plot() and reorder(). * Factors are not supported by the default plotting method. * The Nexus Class Library is build for the system default ARCH which may or may not be the architecture that R and the rest of the package is built with. If this occurs the package will fail to load. * Unique labels are required for internal nodes, this behavior will be changed in the future. phylobase/data/0000755000176200001440000000000012347155416013161 5ustar liggesusersphylobase/data/geospiza_raw.rda0000644000176200001440000000227412347155416016350 0ustar liggesusers‹ÝUkLWž}»ÊËõQ1-¯ Hƒ z²‰š"¦µvØ]Fgg–]^õ¶ZbÚÖˆ5ZSÀF|ÐhLE«Thh¥ÚŠA V±Á„JŒMcU¶wàÎÆÒ?ýÝßžÇ=÷¼öœ;+,/RES´NEÑjÌjhü£¢(c¦S¬(¹¸*f•›)ÇfÓÆm)µL5˜ Æ4#Èa˜Š!Ÿ‡a„cD`DbDD]8±‘m§˜1f˜‰/ñý_c¨&r¤Ô9RZ ñ¯&†C®Q®?H®C®'dRÔ6ÎIŽhr]¦c¦”] XÜÍ3¨qÁÓŒ<ÆŽï˜õòµØAÔ·H3o[:³¶ð»Ò“¨n^Èš¨OЦöæ×žF'.´¢+WJÐѸm;ÞŠÿ=Kh{yÑÆù9¨£¾'0ËÕ€º’ÍZÊ:Ñå×—¦4´ ¯æ«ò>,ØŽ{ÖU¿½*moο»yv3ÚU5°´)ì]?ý\Öæ£ߟoª° DfYÉA·×‹úyN¶|_³“Ôª"ÔHêo•ÝËsN%†htvÑíá$"Mq2s‹’Çí×YÅÉ*ƒde+(r ³Û9+Çû-ô.†ç9›ÅàbÜe^Þë¿à’8‡±zy.ÆëbÝÊùržñTŽ.Ñhí^TIs9'0n‘+8ÆŸ“ÈseŒ•e&ýûZq²郆(5¬ÍÁ>Hæ“xVpxJ”;¯ ¢M9ðp®$ž)fùÉž­<#)žýJWI%/NŒ×ø–iIûƒÁXóÂ@FT?ßÈø²·LûïìíNÌ“=»æî%LAëÚ<ÙÆÁÒŸº¥­` ýáã—âÛÁ¸¥-¦zÿ20Þo O?ÐÆ{aò@€éX[‰¢íÚ{}åÈ`lStޜÎíkŠ6‚>Ž)þÃ~ y4E ô7Ð`ç,Ð ‡ú6d>ýü'¬}[ N¥ìÀ ï¸ÚT²òlŸê.ÕõƒaÙæû"gÀ„©îÎÜ… _¯Û=3­ô=RÔÓå9þxT[uìõm³A½x÷Šs™i ½4;-w¸´™i¦TÍï yÌoº5ý8ÐéGš«Cš@]3TÑ=†|µ‹œ‘=@Ok™;øk¨Ö?îŸ{eè/ú,ïïÊjubãÑ´×€^íKÊRâ!_ÈHC/}çtfWèèj§Å>Ÿ²43³VU€*® 2«wP_ïi¿½ ¨èµ3úòÍhtD–ñ0T=Ï¥Å$žj<]ÐíŸÝJ(¯G†®î “Ñ#¼¼q¾õÇÝr4ºho¨.§Z¿´%ÜEgzÐ2]µ@å6æ¶XÊAg s.c×/¬ñ;reÖ¨qeÏúv|ÎâúúöeŸÒ{ŸÝNªÑ,Žw“ûêQÉhêátôp„cïGÉ‘;9c±#øš‹]ÑœïgSl^R.ÊLÑÑ`®7*U¦Ôt0œ›5HH¥ÊLÉj÷‡ z¡À{ ¼£àœ‰ÈÕéÄ k²sÖU‘CAØ+åVªƒlp»\Je€þì¿ÎËךRÿ]Ù¯_…JÔÞžg[nÛ±–vP‘—\5M¿È¿"üôphylobase/data/geospiza.rda0000644000176200001440000000300512347155416015470 0ustar liggesusers‹U}LGßÝ»ãøP¸µbZ@»ÀìŒJ"†¦¨é‘Z»Ü¬,»çíVmµ¦5j[#ÖhMñƒFc*Z¥J«@+ÕV еР&Vcl«¢Bg¹Ý9¼úG/y·¿7ûæ½7¿ùÍÎü‚6´$” Š BéÔSè$Sz—;$ÙÅ/åR7!àÞÎy8‚ÐE"l@Žl,4­}©?/ö 4=ºš÷õåhÞ~së…ÔéÐ융ööšÃ–wî}¼ š–ürAþš#~úôåiд¦#±aûhº×2Þº£šîF-íŸÝ Íû;R–20¢g륅ƒBÓÉ)¥'⬸^||[k‚ “¹²¿œ×apñ)ýJ‰€ÆkÍ` {4Š»ûêó@cÆc‡s]" >Ìl@ÐØu¾µbáalÿ<èLÓØ\-ˆºy$¿'â jŒLz‘Éú‰³Rw-­…drIÝôËõˆþvKçUHXß7/<4Då=H‚dï –ÄÔ£i× ©Î/®§ÔìG,î —ÒÁÃŽ o'ßÿ×{ºf_BéÖRHž.ËÚ½"*øÓUÖò†I•ÃÃùŽéËúìQqØËÑeåx} 'x} [x} YÏјAàÊR×hÖC^/çEIæÔ‘ §äöð²ê©âÊEÞ-É7 ³ICÁ²íQóCí¼ÓÉÛxG]œ ðv­J°‹sW{/žà’y‡C_G܇‹óºníý\óÔù®tuN/*ªµ9—9·$Hµ<‡{’¾š³9´Ýkx»´ø¡Õsü0C¬0?dý0Ó³üÐ_õWSöü¹ú'µÔ¤–˜ÔÒ’ZRRKIj I­yRkÔ§°r(, k†Â‚¡˜,Œ²1²`dÅ(#\sCaj(Ì …‰¡0/¦…¬P#!P¯¡¾oâ(ÑÔÏS¹ä¶¨F½}âóŠ•¢T#Äq¢(y”‹qÔågV«iQFWE eÙ&#AÛ*9åz|æÂ ‰.ãdõ¾õÙ¿B +•² phylobase/R/0000755000176200001440000000000013075432237012447 5ustar liggesusersphylobase/R/oldclasses-class.R0000644000176200001440000000036612347155416016040 0ustar liggesusers## This file contains the old class definitions needed ## better interoperation with other packages ## ape classes setOldClass("phylo") setOldClass("multiPhylo") ## setOldClass("multi.tree") ## obsolete ## ade4 classes setOldClass("phylog") phylobase/R/readNCL.R0000644000176200001440000004216012553766430014052 0ustar liggesusers### This file contains the source code for the functions: ### - readNCL (generic function) ### - readNexus (wrapper for readNCL importing Nexus files) ### - readNewick (wrapper for readNCL importing Newick files) ##' Create a \code{phylo4}, \code{phylo4d} or \code{data.frame} object ##' from a NEXUS or a Newick file ##' ##' \code{readNexus} reads a NEXUS file and outputs a \code{phylo4}, ##' \code{phylo4d} or \code{data.frame} object. ##' ##' \code{readNewick} reads a Newick file and outputs a \code{phylo4} ##' or \code{phylo4d} object. ##' ##' \code{readNexus} is used internally by both \code{readNexus} and ##' \code{readNewick} to extract data held in a tree files, ##' specifically in NEXUS files from DATA, CHARACTER or TREES ##' blocks. ##' ##' The \code{type} argument specifies which of these is returned: ##' ##' \describe{ ##' ##' \item{data}{will only return a \code{data.frame} of the contents ##' of all DATA and CHARACTER blocks.} ##' ##' \item{tree}{will only return a \code{phylo4} object of the ##' contents of the TREES block.} ##' ##' \item{all}{if only data or a tree are present in the file, this ##' option will act as the options above, returning either a ##' \code{data.frame} or a \code{phylo4} object respectively. If both ##' are present then a \code{phylo4d} object is returned containing ##' both.} ##' ##' } ##' ##' The function returns \code{NULL} if the \code{type} of ##' data requested is not present in the file, or if neither data nor ##' tree blocks are present. ##' ##' Depending on the context \code{readNexus} will call either the ##' \code{phylo4} or \code{phylo4d} constructor. The \code{phylo4d} ##' constructor will be used with \code{type="all"}, or if the option ##' \code{check.node.labels="asdata"} is invoked. ##' ##' \code{readNewick} imports Newick formatted tree files and will ##' return a \code{phylo4} or a \code{phylo4d} object if the option ##' \code{check.node.labels="asdata"} is invoked. ##' ##' For both \code{readNexus} and \code{readNewick}, the options for ##' \code{check.node.labels} can take the values: ##' ##' \describe{ ##' ##' \item{keep}{the node labels of the trees will be passed as node ##' labels in the \code{phylo4} object} ##' ##' \item{drop}{the node labels of the trees will be ignored in the ##' \code{phylo4} object} ##' ##' \item{asdata}{the node labels will be passed as data and a ##' \code{phylo4d} object will be returned.} ##' ##' } ##' ##' If you use the option \code{asdata} on a file with no node labels, ##' a warning message is issued, and is thus equivalent to the value ##' \code{drop}. ##' ##' For both \code{readNexus} and \code{readNewick}, additional ##' arguments can be passed to the constructors such as \code{annote}, ##' \code{missing.data} or \code{extra.data}. See the \sQuote{Details} ##' section of \code{\link{phylo4d-methods}} for the complete list of ##' options. ##' ##' @name Import Nexus and Newick files ##' @docType methods ##' @param file a NEXUS file for \code{readNexus} or a file that ##' contains Newick formatted trees for \code{readNewick}. ##' @param simplify If TRUE, if there are multiple trees in the file, ##' only the first one is returned; otherwise a list of ##' \code{phylo4(d)} objects is returned if the file contains multiple ##' trees. ##' @param type Determines which type of objects to return, if present ##' in the file (see Details). ##' @param spacesAsUnderscores In the NEXUS file format white spaces ##' are not allowed in taxa labels and are represented by ##' underscores. Therefore, NCL converts underscores found in taxa ##' labels in the NEXUS file into white spaces ##' (e.g. \code{species_1} will become \code{"species 1"}. If you ##' want to preserve the underscores, set as TRUE, the default). ##' @param char.all If \code{TRUE}, returns all characters, even those ##' excluded in the NEXUS file ##' @param polymorphic.convert If \code{TRUE}, converts polymorphic ##' characters to missing data ##' @param levels.uniform If \code{TRUE}, uses the same levels for all ##' characters ##' @param quiet If \code{FALSE} the output of the NCL interface is ##' printed. This is mainly for debugging purposes. This option ##' can considerably slow down the process if the tree is big or ##' there are many trees in the file. ##' @param check.node.labels Determines how the node labels in the ##' NEXUS or Newick files should be treated in the phylo4 object, ##' see Details for more information. ##' @param return.labels Determines whether state names (if ##' \code{TRUE}) or state codes should be returned. ##' @param file.format character indicating the format of the ##' specified file (either \dQuote{\code{newick}} or ##' \dQuote{\code{nexus}}). It's more convenient to just use ##' \code{readNexus} or \code{readNewick}. ##' @param check.names logical. If \sQuote{TRUE} then the names of the ##' characters from the NEXUS file are checked to ensure that they ##' are syntactically valid variable names and are not duplicated. ##' If necessary they are adjusted using \sQuote{make.names}. ##' @param convert.edge.length logical. If \code{TRUE} negative edge ##' lengths are replaced with 0. At this time \code{phylobase} ##' does not accept objects with negative branch lengths, this ##' workaround allows to import trees with negative branch ##' lengths. ##' @param \dots Additional arguments to be passed to phylo4 or ##' phylo4d constructor (see Details) ##' @return Depending on the value of \code{type} and the contents of ##' the file, one of: a \code{data.frame}, a \linkS4class{phylo4} ##' object, a \linkS4class{phylo4d} object or \code{NULL}. If ##' several trees are included in the NEXUS file and the option ##' \code{simplify=FALSE} a list of \linkS4class{phylo4} or ##' \linkS4class{phylo4d} objects is returned. ##' @note Underscores in state labels (i.e. trait or taxon names) will ##' be translated to spaces. Unless \code{check.names=FALSE}, trait ##' names will be converted to valid R names (see ##' \code{\link{make.names}}) on input to R, so spaces will be ##' translated to periods. ##' @author Brian O'Meara, Francois Michonneau, Derrick Zwickl ##' @seealso the \linkS4class{phylo4d} class, the \linkS4class{phylo4} ##' class ##' @export ##' @rdname readNexus ##' @aliases readNCL ##' @keywords misc readNCL <- function(file, simplify=FALSE, type=c("all", "tree","data"), spacesAsUnderscores = TRUE, char.all=FALSE, polymorphic.convert=TRUE, levels.uniform=FALSE, quiet=TRUE, check.node.labels=c("keep", "drop", "asdata"), return.labels=TRUE, file.format=c("nexus", "newick"), check.names=TRUE, convert.edge.length=FALSE, ...) { type <- match.arg(type) file.format <- match.arg(file.format) check.node.labels <- match.arg(check.node.labels) if (type == "all" || type == "data") { returnData <- TRUE } else { returnData <- FALSE } if (type == "all" || type == "tree") { returnTrees <- TRUE } else { returnTrees <- FALSE } ## GetNCL returns a list containing: ## $taxaNames: names of the taxa (from taxa block, implied or declared) ## $treeNames: the names of the trees ## $trees: a vector of (untranslated) Newick strings ## $dataTypes: data type for each character block of the nexus file (length = number of chr blocks) ## $nbCharacters: number of characters in each block (length = number of chr blocks) ## $charLabels: the labels for the characters, i.e. the headers of the data frame to be returned ## (length = number of chr blocks * sum of number of characters in each block) ## $nbStates: the number of states of each character (equals 0 for non-standard types, length = number ## of characters) ## $stateLabels: the labels for the states of the characters, i.e. the levels of the factors to be returned ## $dataChr: string that contains the data to be returned ncl <- rncl::rncl(file = file, file.format = file.format, spacesAsUnderscores = spacesAsUnderscores, char.all = char.all, polymorphic.convert = polymorphic.convert, levels.uniform = levels.uniform) ## Return Error message if (length(ncl) == 1 && names(ncl) == "ErrorMsg") { stop(ncl$ErrorMsg) } if (!quiet) message(ncl) ## Disclaimer if (!length(grep("\\{", ncl$dataChr)) && return.labels && !polymorphic.convert) { stop("At this stage, it's not possible to use the combination: ", "return.labels=TRUE and polymorphic.convert=FALSE for datasets ", "that contain polymorphic characters.") } if (returnData && length(ncl$dataChr)) { tipData <- vector("list", length(ncl$dataChr)) for (iBlock in 1:length(ncl$dataTypes)) { chrCounter <- ifelse(iBlock == 1, 0, sum(ncl$nbCharacters[1:(iBlock-1)])) if (ncl$dataTypes[iBlock] == "Continuous") { for (iChar in 1:ncl$nbCharacters[iBlock]) { i <- chrCounter + iChar tipData[[i]] <- eval(parse(text=ncl$dataChr[i])) names(tipData)[i] <- ncl$charLabels[i] } } else { if (ncl$dataTypes[iBlock] == "Standard") { iForBlock <- integer(0) for (iChar in 1:ncl$nbCharacters[iBlock]) { i <- chrCounter + iChar iForBlock <- c(iForBlock, i) lblCounterMin <- ifelse(i == 1, 1, sum(ncl$nbStates[1:(i-1)]) + 1) lblCounter <- seq(lblCounterMin, length.out=ncl$nbStates[i]) tipData[[i]] <- eval(parse(text=ncl$dataChr[i])) names(tipData)[i] <- ncl$charLabels[i] tipData[[i]] <- as.factor(tipData[[i]]) lbl <- ncl$stateLabels[lblCounter] if (return.labels) { if (any(nchar(gsub("\\s|_", "", lbl)) == 0)) { warning("state labels are missing for \'", ncl$charLabels[i], "\', the option return.labels is thus ignored.") } else { levels(tipData[[i]]) <- lbl } } } if (levels.uniform) { allLevels <- character(0) for (j in iForBlock) { allLevels <- union(allLevels, levels(tipData[[j]])) } for (j in iForBlock) { levels(tipData[[j]]) <- allLevels } } } else { warning("This datatype is not currently supported by phylobase") next ## FIXME: different datatypes in a same file isn't going to work } } } tipData <- data.frame(tipData, check.names=check.names) if (length(ncl$taxaNames) == nrow(tipData)) { rownames(tipData) <- ncl$taxaNames } else stop("phylobase doesn't deal with multiple taxa block at this time.") } else { tipData <- NULL } if (returnTrees && length(ncl$trees) > 0) { listTrees <- vector("list", length(ncl$trees)) for (i in 1:length(ncl$trees)) { isRooted <- is_rooted(ncl$parentVector[[i]]) edgeMat <- get_edge_matrix(ncl$parentVector[[i]], isRooted) edgeLgth <- get_edge_length(ncl$branchLengthVector[[i]], ncl$parentVector[[i]], isRooted) tipLbl <- ncl$taxonLabelVector[[i]] if (convert.edge.length) { edgeLgth[edgeLgth < 0] <- 0 } if (check.node.labels == "asdata" && !has_node_labels(ncl$nodeLabelsVector[[i]])) { warning("Could not use value \"asdata\" for ", "check.node.labels because there are no ", "labels associated with the tree") check.node.labels <- "drop" } if (has_node_labels(ncl$nodeLabelsVector[[i]]) && !identical(check.node.labels, "drop")) { nodeLbl <- ncl$nodeLabelsVector[[i]] rootNd <- attr(edgeMat, "root") nodeLbl[rootNd] <- nodeLbl[1] node_pos <- (length(tipLbl)+1):length(nodeLbl) nodeLbl <- nodeLbl[node_pos] if (identical(check.node.labels, "asdata")) { tr <- phylo4(x = edgeMat, edge.length = edgeLgth, tip.label = tipLbl) nodeDt <- label_to_data(nodeLbl, row.names = node_pos) tr <- phylo4d(tr, node.data = nodeDt) } else { tr <- phylo4(x = edgeMat, edge.length = edgeLgth, tip.label = tipLbl, node.label = nodeLbl) } } else { tr <- phylo4(x = edgeMat, edge.length = edgeLgth, tip.label = tipLbl) } listTrees[[i]] <- tr if (simplify) break } if (length(listTrees) == 1 || simplify) listTrees <- listTrees[[1]] } else { listTrees <- NULL } ### switch(type, "data" = { if (is.null(tipData)) { toRet <- NULL } else { toRet <- tipData } }, "tree" = { if (is.null(listTrees)) { toRet <- NULL } else { toRet <- listTrees } }, "all" = { if (is.null(tipData) && is.null(listTrees)) { toRet <- NULL } else if (is.null(tipData)) { toRet <- listTrees } else if (is.null(listTrees)) { toRet <- tipData } else { if (length(listTrees) > 1) { toRet <- lapply(listTrees, function(tr) addData(tr, tip.data=tipData, ...)) } else toRet <- addData(listTrees, tip.data=tipData, ...) } }) toRet } ## check if the implicit root is dichotomous is_rooted <- function(parentVector) { tab_edg <- table(parentVector) if (tabulate(parentVector)[which(parentVector == 0)] > 2) FALSE else TRUE } ## Returns the edge matrix from the parentVector (the i^th element is ## the descendant element of node i) get_edge_matrix <- function(parentVector, isRooted) { edgeMat <- cbind(ancestor = parentVector, descendant = 1:length(parentVector)) rootNd <- edgeMat[which(edgeMat[, 1] == 0), 2] if (!isRooted) { edgeMat <- edgeMat[-which(edgeMat[, 1] == 0), ] } attr(edgeMat, "root") <- rootNd edgeMat } ## Returns the edge lengths (missing are represented by -999) get_edge_length <- function(branchLengthVector, parentVector, isRooted) { edgeLgth <- branchLengthVector if (isRooted) { edgeLgth[which(parentVector == 0)] <- NA } else { edgeLgth <- edgeLgth[which(parentVector != 0)] } edgeLgth[edgeLgth == -999] <- NA edgeLgth } ## Tests whether there are node labels has_node_labels <- function(nodeLabelsVector) { any(nzchar(nodeLabelsVector)) } ##' @rdname readNexus ##' @aliases readNexus ##' @export readNexus <- function (file, simplify=FALSE, type=c("all", "tree", "data"), char.all=FALSE, polymorphic.convert=TRUE, levels.uniform=FALSE, quiet=TRUE, check.node.labels=c("keep", "drop", "asdata"), return.labels=TRUE, check.names=TRUE, convert.edge.length=FALSE, ...) { return(readNCL(file=file, simplify=simplify, type=type, char.all=char.all, polymorphic.convert=polymorphic.convert, levels.uniform=levels.uniform, quiet=quiet, check.node.labels=check.node.labels, return.labels=return.labels, file.format="nexus", check.names=check.names, convert.edge.length=convert.edge.length, ...)) } ##' @rdname readNexus ##' @aliases readNewick ##' @export readNewick <- function(file, simplify=FALSE, quiet=TRUE, check.node.labels=c("keep", "drop", "asdata"), convert.edge.length=FALSE, ...) { return(readNCL(file=file, simplify=simplify, quiet=quiet, check.node.labels=check.node.labels, file.format="newick", convert.edge.length=convert.edge.length, ...)) } phylobase/R/getNode-methods.R0000644000176200001440000001671212347155416015631 0ustar liggesusers## matching node labels with node numbers ... ## e.g. ## 14 tips, 13 int nodes ## N04 = nodeLabels[4] ## <-> node 18 ## x = n-nTips(phy) ## so: n = x+nTips(phy) ##' Node and Edge look-up functions ##' ##' Functions for retrieving node and edge IDs (possibly with corresponding ##' labels) from a phylogenetic tree. ##' ##' \code{getNode} and \code{getEdge} are primarily intended for looking up the ##' IDs either of nodes themselves or of edges associated with those nodes. Note ##' that they behave quite differently. With \code{getNode}, any input nodes are ##' looked up against tree nodes of the specified type, and those that match are ##' returned as numeric node IDs with node labels (if they exist) as element ##' names. With \code{getEdge}, any input nodes are looked up against edge ends ##' of the specified type, and those that match are returned as character edge ##' IDs with the corresponding node ID as element names. ##' ##' If \code{missing} is \dQuote{warn} or \dQuote{OK}, \code{NA} is returned for ##' any nodes that are unmatched for the specified type. This can provide a ##' mechanism for filtering a set of nodes or edges. ##' ##' \code{nodeId} provides similar output to \code{getNode} in the case when no ##' node is supplied, but it is faster and returns an unnamed vector of the ##' numeric IDs of all nodes of the specified node type. Similarly, ##' \code{edgeId} simply returns an unnamed vector of the character IDs of all ##' edges for which the descendant node is of the specified node type. ##' ##' @param x a \linkS4class{phylo4} object (or one inheriting from ##' \linkS4class{phylo4}, e.g. a \linkS4class{phylo4d} object) ##' @param node either an integer vector corresponding to node ID numbers, or a ##' character vector corresponding to node labels; if missing, all nodes ##' appropriate to the specified type will be returned by \code{getNode}, and ##' all edges appropriate to the specified type will be returned by ##' \code{getEdge}. ##' @param type (\code{getNode}) specify whether to return nodes matching "all" ##' tree nodes (default), only "tip" nodes, or only "internal" nodes; ##' (\code{nodeId, edgeId}) specify whether to return "all" tree nodes, or only ##' those corresponding to "tip", "internal", or "root" nodes; (\code{getEdge}) ##' specify whether to look up edges based on their descendant node ##' ("descendant") or ancestral node ("ancestor") ##' @param missing what to do if some requested node IDs or names are not in the ##' tree: warn, do nothing, or stop with an error ##' @return \item{list("getNode")}{returns a named integer vector of node IDs, ##' in the order of input nodes if provided, otherwise in nodeId order} ##' \item{list("getEdge")}{returns a named character vector of edge IDs, in the ##' order of input nodes if provide, otherwise in nodeId order} ##' \item{list("nodeId")}{returns an unnamed integer vector of node IDs, in ##' ascending order} \item{list("getEdge")}{returns an unnamed character vector ##' of edge IDs, in edge matrix order} ##' @keywords misc ##' @export ##' @rdname getNode-methods ##' @include phylo4-class.R ##' @examples ##' ##' data(geospiza) ##' nodeLabels(geospiza) <- LETTERS[1:nNodes(geospiza)] ##' plot(as(geospiza, "phylo4"), show.node.label=TRUE) ##' getNode(geospiza, 18) ##' getNode(geospiza, "D") ##' getEdge(geospiza, "D") ##' getEdge(geospiza, "D", type="ancestor") ##' ##' ## match nodes only to tip nodes, flagging invalid cases as NA ##' getNode(geospiza, c(1, 18, 999), type="tip", missing="OK") ##' ##' ## get all edges that descend from internal nodes ##' getEdge(geospiza, type="ancestor") ##' ##' ## identify an edge from its terminal node ##' getEdge(geospiza, c("olivacea", "B", "fortis")) ##' getNode(geospiza, c("olivacea", "B", "fortis")) ##' edges(geospiza)[c(26, 1, 11),] ##' ##' ## quickly get all tip node IDs and tip edge IDs ##' nodeId(geospiza, "tip") ##' edgeId(geospiza, "tip") ##' setGeneric("getNode", function(x, node, type=c("all", "tip", "internal"), missing=c("warn", "OK", "fail")) { standardGeneric("getNode") }) ##' @rdname getNode-methods ##' @aliases getNode,phylo4-method setMethod("getNode", signature(x="phylo4", node="ANY"), function(x, node, type=c("all", "tip", "internal"), missing=c("warn","OK","fail")) { type <- match.arg(type) missing <- match.arg(missing) ## if missing node arg, get all nodes of specified type if (missing(node)) { node <- nodeId(x, type) } if (length(node) == 0) { rval <- integer(0) names(rval) <- character(0) return(rval) } lblTmp <- labels(x, type) ## match node to tree if (is.character(node)) { ndTmp <- paste("^\\Q", node, "\\E$", sep="") irval <- lapply(ndTmp, function(ND) { grep(ND, lblTmp, perl=TRUE) }) irvalL <- sapply(irval, length) irval[irvalL == 0] <- 0 irval <- unlist(irval) } else if (is.numeric(node) && all(floor(node) == node, na.rm=TRUE)) { irval <- match(as.character(node), names(lblTmp)) } else { stop("Node must be a vector of class \'integer\' or \'character\'.") } ## node numbers rval <- names(lblTmp)[irval] rval[is.na(node)] <- NA # return NA for any NA_character_ inputs, not needed but ensure rval has correct length rval <- as.integer(rval) ## node labels nmNd <- lblTmp[irval] names(rval) <- nmNd ## deal with nodes that don't match if (any(is.na(rval))) { missnodes <- node[is.na(rval)] msg <- paste("Some nodes not found among", type, "nodes in tree:", paste(missnodes,collapse=", ")) if (missing=="fail") { stop(msg) } else if (missing=="warn") { warning(msg) } } return(rval) }) ##' @rdname getNode-methods ##' @aliases getEdge-methods ##' @export setGeneric("getEdge", function(x, node, type=c("descendant", "ancestor"), missing=c("warn", "OK", "fail")) { standardGeneric("getEdge") }) ##' @name getEdge ##' @rdname getNode-methods ##' @aliases getEdge,phylo4-method setMethod("getEdge", signature(x="phylo4", node="ANY"), function(x, node, type=c("descendant", "ancestor"), missing=c("warn", "OK", "fail")) { type <- match.arg(type) missing <- match.arg(missing) if (missing(node)) { if (type=="descendant") { node <- nodeId(x, "all") } else if (type=="ancestor") { node <- nodeId(x, "internal") } } node.id <- getNode(x, node, missing="OK") nd <- lapply(node.id, function(nid) { if (is.na(nid)) { res <- NA } else { res <- switch(type, descendant = edgeId(x)[edges(x)[,2] %in% nid], ancestor = edgeId(x)[edges(x)[,1] %in% nid]) ## hack to return NA for tip nodes when type='ancestor' if(length(res)==0) res <- NA names(res) <- rep(nid, length(res)) } names(res) <- rep(nid, length(res)) res }) ## warn or stop if necessary is.missing <- is.na(nd) if (missing!="OK" && any(is.missing)) { msg <- paste("Not all nodes are ", type, "s in this tree: ", paste(node[is.missing], collapse=", "), sep="") if (missing=="fail") { stop(msg) } else if (missing=="warn") { warning(msg) } } return(unlist(unname(nd))) }) phylobase/R/tdata-methods.R0000644000176200001440000001663412435455464015350 0ustar liggesusers##' Retrieving or updating tip and node data in phylo4d objects ##' ##' Methods to retrieve or update tip, node or all data associated with a ##' phylogenetic tree stored as a phylo4d object ##' ##' @param x A \code{phylo4d} object ##' @param type The type of data to retrieve or update: \dQuote{\code{all}} ##' (default) for data associated with both tip and internal nodes, ##' \dQuote{\code{tip}} for data associated with tips only, ##' \dQuote{\code{internal}} for data associated with internal nodes only. ##' @param label.type How should the tip/node labels from the tree be returned? ##' \dQuote{\code{row.names}} returns them as row names of the data frame, ##' \dQuote{\code{column}} returns them in the first column of the data frame. ##' This options is useful in the case of missing (\code{NA}) or non-unique ##' labels. ##' @param empty.columns Should columns filled with \code{NA} be returned? ##' @param merge.data if tip or internal node data are provided and data already ##' exists for the other type, this determines whether columns with common names ##' will be merged together (default TRUE). If FALSE, columns with common names ##' will be preserved separately, with \dQuote{.tip} and \dQuote{.node} appended ##' to the names. This argument has no effect if tip and node data have no ##' column names in common, or if type=\dQuote{all}. ##' @param clear.all If only tip or internal node data are to be replaced, ##' should data of the other type be dropped? ##' @param \dots For the \code{tipData} and \code{nodeData} accessors, ##' further arguments to be used by \code{tdata}. For the replacement ##' forms, further arguments to be used to control matching between ##' tree and data (see Details section of \code{\link{phylo4d-methods}}). ##' @param value a data frame (or object to be coerced to one) to replace the ##' values associated with the nodes specified by the argument \code{type} ##' @return \code{tdata} returns a data frame ##' @section Methods: \describe{ ##' \item{tdata}{\code{signature(object="phylo4d")}: retrieve or update data ##' associated with a tree in a \code{phylo4d} object} } ##' @author Ben Bolker, Thibaut Jombart, Francois Michonneau ##' @seealso \code{\link{phylo4d-methods}}, \code{\linkS4class{phylo4d}} ##' @export ##' @keywords methods ##' @include phylo4d-methods.R ##' @rdname tdata-methods ##' @examples ##' data(geospiza) ##' tdata(geospiza) ##' tipData(geospiza) <- 1:nTips(geospiza) ##' tdata(geospiza) setGeneric("tdata", function(x, ...) { standardGeneric("tdata") }) ##' @rdname tdata-methods ##' @aliases tdata,phylo4d-method setMethod("tdata", signature(x="phylo4d"), function(x, type=c("all", "tip", "internal"), label.type=c("row.names","column"), empty.columns=TRUE) { ## Returns data associated with the tree ## Note: the function checks for unique labels. It's currently unecessary ## but could be useful in the future if non-unique labels are allowed. type <- match.arg(type) label.type <- match.arg(label.type) ids <- nodeId(x, type) labs <- labels(x, type) ## replace any missing labels with node numbers labs[is.na(labs)] <- names(labs)[is.na(labs)] tdata <- x@data[match(ids, row.names(x@data)), , drop=FALSE] row.names(tdata) <- ids data.names <- labs[match(names(labs), rownames(tdata))] if (label.type == "row.names") { if (!any(duplicated(data.names)) && ## length(data.names) > 0 && !any(is.na(data.names)) ) { row.names(tdata) <- data.names } else { warning("Non-unique or missing labels found, ", "labels cannot be coerced to tdata row.names. ", "Use the label.type argument to include labels ", "as first column of data.") } } if (identical(label.type,"column")) { tdata <- data.frame(label=data.names, tdata) } ## remove empty columns (filled with NAs) if(!empty.columns) { emptyCol <- apply(tdata, 2, function(x) all(is.na(x))) tdata <- tdata[, !emptyCol, drop=FALSE] } tdata }) ##' @rdname tdata-methods ##' @aliases tdata<- ##' @export setGeneric("tdata<-", function(x, ..., value) { standardGeneric("tdata<-") }) ##' @name tdata<- ##' @rdname tdata-methods ##' @aliases tdata<-,phylo4d-method tdata<-,phylo4d,ANY-method setReplaceMethod("tdata", signature(x="phylo4d", value="ANY"), function(x, type = c("all", "tip", "internal"), merge.data = TRUE, clear.all = FALSE, ..., value) { type <- match.arg(type) ## format new data value <- formatData(x, value, type, keep.all=TRUE, ...) ## get old data to keep (if any) if (clear.all || type=="all") { keep <- NULL } else { if (type=="tip") { keep <- tdata(x, type="internal", empty.column=FALSE) keep <- formatData(x, keep, "internal", match.data=FALSE) } else if (type=="internal") { keep <- tdata(x, type="tip", empty.column=FALSE) keep <- formatData(x, keep, "tip", match.data=FALSE) } } ## create updated data updated.data <- switch(type, tip = .phylo4Data(x, tip.data=value, node.data=keep, merge.data=merge.data), internal = .phylo4Data(x, tip.data=keep, node.data=value, merge.data=merge.data), all = .phylo4Data(x, all.data=value, merge.data=merge.data)) ## try to arrange new columns after old columns kept <- names(updated.data) %in% names(keep) old.cols <- names(updated.data)[kept] new.cols <- names(updated.data)[!kept] x@data <- updated.data[c(old.cols, new.cols)] if(is.character(checkval <- checkPhylo4(x))) stop(checkval) return(x) }) ### Tip data wrappers ##' @rdname tdata-methods ##' @aliases tipData tipData-method ##' @export setGeneric("tipData", function(x, ...) { standardGeneric("tipData") }) ##' @name tipData ##' @rdname tdata-methods ##' @aliases tipData,phylo4d-method setMethod("tipData", signature(x="phylo4d"), function(x, ...) { tdata(x, type="tip", ...) }) ## tipData<- ##' @rdname tdata-methods ##' @aliases tipData<- ##' @export setGeneric("tipData<-", function(x, ..., value) { standardGeneric("tipData<-") }) ##' @name tipData<- ##' @rdname tdata-methods ##' @aliases tipData<-,phylo4d-method tipData<-,phylo4d,ANY-method setReplaceMethod("tipData", signature(x="phylo4d", value="ANY"), function(x, ..., value) { tdata(x, type="tip", ...) <- value if(is.character(checkval <- checkPhylo4(x))) stop(checkval) return(x) }) ### Node data wrappers ##' @rdname tdata-methods ##' @aliases nodeData nodeData-method ##' @export setGeneric("nodeData", function(x, ...) { standardGeneric("nodeData") }) ##' @name nodeData ##' @rdname tdata-methods ##' @aliases nodeData,phylo4d-method setMethod("nodeData", signature(x="phylo4d"), function(x, ...) { tdata(x, type="internal", ...) }) ## nodeData<- ##' @rdname tdata-methods ##' @aliases nodeData<- ##' @export setGeneric("nodeData<-", function(x, ..., value) { standardGeneric("nodeData<-") }) ##' @name nodeData<- ##' @rdname tdata-methods ##' @aliases nodeData<-,phylo4d-method nodeData<-,phylo4d,ANY-method setReplaceMethod("nodeData", signature(x="phylo4d", value="ANY"), function(x, ..., value) { tdata(x, type="internal", ...) <- value if(is.character(checkval <- checkPhylo4(x))) stop(checkval) return(x) }) phylobase/R/nodeId-methods.R0000644000176200001440000000625112347155416015443 0ustar liggesusers ##' nodeId methods ##' ##' These functions gives the node (\code{nodeId}) or edge ##' (\code{edgeId}) identity. ##' ##' \code{nodeId} returns the node in ascending order, and ##' \code{edgeId} in the same order as the edges are stored in the ##' edge matrix. ##' ##' @param x a \code{phylo4} or \code{phylo4d} object. ##' @param type a character vector indicating which subset of the ##' nodes or edges you are interested in. ##' @return \describe{ ##' \item{nodeId}{an integer vector indicating node numbers} ##' \item{edgeId}{a character vector indicating the edge identity} ##' } ##' @export ##' @docType methods ##' @rdname nodeId-methods ##' @include phylo4-class.R phylo4-methods.R phylo4-accessors.R root-methods.R ##' @examples ##' data(geospiza) ##' identical(nodeId(geospiza, "tip"), 1:nTips(geospiza)) ##' nodeId(geospiza, "internal") ##' edgeId(geospiza, "internal") ##' nodeId(geospiza, "root") setGeneric("nodeId", function(x, type=c("all", "tip", "internal", "root")) { standardGeneric("nodeId") }) ##' @rdname nodeId-methods ##' @aliases nodeId,phylo4-method setMethod("nodeId", signature(x="phylo4"), function(x, type=c("all", "tip","internal","root")) { type <- match.arg(type) E <- edges(x) ## Note: this implementation will still work even if tips are not ## 1:nTips and nodes are not (nTips+1):nNodes nid <- switch(type, ## all nodes appear at least once in the edge matrix ## twice slower: all = unique(as.vector(E)[as.vector(E) != 0]), ## but maybe should be used if tree is not "normal" all = { if (isRooted(x)) { res <- getAllNodesFast(x@edge)[-1] } else { res <- getAllNodesFast(x@edge) } res }, ## tips are nodes that do not appear in the ancestor column ## three times slower: setdiff(E[, 2], E[, 1]), tip = tipsFast(x@edge[,1]), ## internals are nodes that *do* appear in the ancestor column ## about 0.5 faster than: setdiff(getAllNodesFast(x@edge, isRooted(x)), tipsFast(x@edge[,1])), internal = unique(E[E[, 1] != 0, 1]), ## roots are nodes that have NA as ancestor root = if (!isRooted(x)) return(NA) else unname(E[E[, 1] == 0, 2])) return(sort(nid)) }) #### ----- edgeId ##' @rdname nodeId-methods ##' @aliases edgeId ##' @export setGeneric("edgeId", function(x, type=c("all", "tip", "internal", "root")) { standardGeneric("edgeId") }) ##' @rdname nodeId-methods ##' @aliases edgeId,phylo4-method setMethod("edgeId", signature(x="phylo4"), function(x, type=c("all", "tip", "internal", "root")) { type <- match.arg(type) edge <- edges(x) if (type=="tip") { isTip <- !(edge[, 2] %in% edge[, 1]) edge <- edge[isTip, , drop=FALSE] } else if (type=="internal") { isInt <- (edge[, 2] %in% edge[, 1]) edge <- edge[isInt, , drop=FALSE] } else if (type=="root") { isRoot <- edge[, 1] == 0 edge <- edge[isRoot, , drop=FALSE] } # else just use complete edge matrix if type is "all" id <- paste(edge[, 1], edge[, 2], sep="-") return(id) }) phylobase/R/pdata.R0000644000176200001440000001041512553730712013663 0ustar liggesusers## define class for traits ptypes <- c("multitype","binary","continuous","DNA","RNA","aacid", "other","unknown") ##' Class "pdata" ##' ##' Data class for phylo4d objects ##' ##' ##' @name pdata-class ##' @aliases ptypes pdata-class [<-,pdata-method [,pdata-method ##' [,pdata,ANY,ANY,ANY-method [[,pdata-method [[<-,pdata-method ##' [[,pdata,ANY,ANY-method [[,pdata,ANY,missing-method ##' @docType class ##' @section Objects from the Class: Objects can be created by calls of the form ##' \code{new("pdata", ...)}. ##' @author Ben Bolker ##' @keywords classes #### @export setClass("pdata", representation(data="data.frame", type="factor", comment="character", metadata="list"), prototype=list(data=data.frame(),type=factor(), comment=character(0),metadata=list())) ## pdata constructor ##' Constructor for pdata (phylogenetic data) class ##' ##' Combine data, type, comments, and metadata information to create a new pdata ##' object, or check such an object for consistency ##' ##' ##' @aliases pdata check_pdata ##' @param data a data frame ##' @param type a factor with levels as specified by \linkS4class{pdata}, the ##' same length as \code{ncol(data)} ##' @param comment a character vector, the same length as \code{ncol(data)} ##' @param metadata an arbitrary list ## @param object an object of class \code{pdata} ##' @return An object of class \code{pdata} ##' @author Ben Bolker ##' @seealso \linkS4class{pdata} ##' @keywords misc pdata <- function(data,type,comment,metadata) { nvar <- ncol(data) if (missing(type)) { type <- factor(rep("unknown",nvar),levels=ptypes) } if (length(type)==1) type <- rep(type,length.out=nvar) type <- factor(as.character(type),levels=ptypes) if (length(comment)==1) comment <- rep(comment,length.out=nvar) obj <- new("pdata",data=data,type=type,comment=comment,metadata) check_pdata(obj) obj } check_pdata <- function(object) { nvar <- ncol(object@data) badlevels <- levels(object@type)[!levels(object@type) %in% ptypes] if (length(badlevels)>0) stop(paste("bad levels in types:",paste(badlevels,collapse=","))) if (length(object@comment)>1 && length(object@comment)!=nvar) { stop("wrong number of comments") } if (length(object@type)>1 && length(object@type)!=nvar) { stop("wrong number of types") } } ## setMethod("[","pdata",function(x,i, j,...,drop=FALSE) { ## xd <- x@data[i,j,...,drop=drop] ## xd2 <- as.data.frame(xd) ## xd2 ## }) ## #### @exportMethod [<- ## setGeneric("[<-") ## setMethod("[<-","pdata",function(x,i, j,...,drop=FALSE,value) { ## "[<-"(x@data,i,j,...,drop=drop,value) ## }) ## ### @exportMethod [[ ## setGeneric("[[") ## setMethod("[[","pdata", ## function(x,i,j,...,exact=NA) { ## x@data[[i,j,...,exact=exact]] ## }) ## #### @exportMethod [[<- ## setGeneric("[[<-") ## setMethod("[[<-","pdata", ## function(x,i,j,...,exact=NA,value) { ## "[[<-"(x@data,i,j,...,exact=exact,value) ## }) ## setMethod("plot",signature(x="pdata",y="missing"), function(x,...){ ## return(plot(x@data, ...)) ## }) # end plot phylo4 ## od = data.frame(a=1:3,b=4:6) ## z = new("pdata", ## data=od,type=factor("a","b"), ## comment=c("",""),metadata=list()) ## z[2,] ## z[,"a"] ## z[[2]] ## test conflict resolution error ####### ### old code retrieved from misc/ folder ## setClass("pdata", representation(x="vector", y="vector")) ## setMethod("[","pdata",function(x,i, j,...,drop=TRUE)new("pdata",x=x@x[i],y=x@y[i])) # x <- new("pdata", x=c("a","b", "c", "d", "3"), y=c(1:5)) #>x[c(2,4)] #An object of class pdata #Slot "x": #[1] "b" "d" # #Slot "y": #[1] 2 4 # doesn't work #setClass("track", representation("list", comment="character", metadata="vector"), contains="list", prototype(list(), comment="", metadata=NA)) #setMethod("[","track",function(x,i, j,...,drop=TRUE)new("track", list(lapply(x, function(x, i, j, ..., drop=TRUE) x@.Data[i])))) # this works, how to incorporate into method above? #> lapply(x, function(x, i=2, j, ..., drop=TRUE) x@.Data[i]) #$x #[1] "b" #$y #[1] 2 # this works, but list structure is destroyed #> mapply(function(x, i, j, ..., drop=TRUE) x@.Data[i], x, 2) # x y #"b" "2" phylobase/R/phylo4-class.R0000644000176200001440000000270312353104030015077 0ustar liggesusers##' The phylo4 class ##' ##' Classes for phylogenetic trees ##' ##' @name phylo4-class ##' @docType class ##' @section Objects from the Class: Phylogenetic tree objects can be created by ##' calls to the \code{\link{phylo4}} constructor function. Translation ##' functions from other phylogenetic packages are also available. See ##' \code{\link{coerce-methods}}. ##' @author Ben Bolker, Thibaut Jombart ##' @seealso The \code{\link{phylo4-methods}} constructor, the ##' \code{\link{checkPhylo4}} function to check the validity of ##' \code{phylo4} objects. See also the \code{\link{phylo4d-methods}} ##' constructor and the \linkS4class{phylo4d} class. ##' @keywords classes ##' @include RcppExports.R checkdata.R ##' @export setClass("phylo4", representation(edge = "matrix", edge.length = "numeric", label = "character", edge.label = "character", order = "character", annote = "list"), prototype = list( edge = matrix(nrow = 0, ncol = 2, dimname = list(NULL, c("ancestor", "descendant"))), edge.length = numeric(0), label = character(0), edge.label = character(0), order = "unknown", annote = list() ), validity = checkPhylo4) phylobase/R/summary-methods.R0000644000176200001440000001742512554035550015737 0ustar liggesusers ##' Summary for phylo4/phylo4d objects ##' ##' Summary of information for the tree (\code{phylo4} only) and/or the ##' associated data (\code{phylo4d}). ##' ##' @name summary-methods ##' @docType methods ##' @param object a phylo4d object ##' @param quiet Should the summary be displayed on screen? ##' @param \dots optional additional elements (not in use) ##' ##' @return The \code{nodeType} method returns named vector which has ##' the type of node (internal, tip, root) for value, and the node number ##' for name ##' ##' The \code{summary} method invisibly returns a list with the ##' following components: \item{list("name")}{the name of the object} ##' ##' \item{list("nb.tips")}{the number of tips} ##' ##' \item{list("nb.nodes")}{the number of nodes} ##' ##' \item{list("mean.el")}{mean of edge lengths} ##' ##' \item{list("var.el")}{variance of edge lengths (estimate for population) } ##' ##' \item{list("sumry.el")}{summary (i.e. range and quartiles) of the ##' edge lengths} ##' ##' \item{list("degree")}{(optional) type of polytomy for each node: ##' \sQuote{node}, \sQuote{terminal} (all descendants are tips) or ##' \sQuote{internal} (at least one descendant is an internal node); ##' displayed only when there are polytomies} ##' ##' \item{list("sumry.tips")}{(optional) summary for the data ##' associated with the tips} ##' ##' \item{list("sumry.nodes")}{(optional) summary for the data ##' associated with the internal nodes} ##' ##' @author Ben Bolker, Thibaut Jombart, Francois Michonneau ##' @seealso \code{\link{phylo4d-methods}} constructor and ##' \code{\linkS4class{phylo4d}} class. ##' @keywords methods ##' @aliases summary ##' @include phylo4-methods.R ##' @include phylo4d-methods.R ##' @exportMethod summary ##' @examples ##' tOwls <- "(((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3):6.3,Tyto_alba:13.5);" ##' tree.owls <- ape::read.tree(text=tOwls) ##' P1 <- as(tree.owls, "phylo4") ##' P1 ##' summary(P1) ##' nodeType(P1) ##' ##' ## summary of a polytomous tree ##' E <- matrix(c( ##' 8, 9, ##' 9, 10, ##' 10, 1, ##' 10, 2, ##' 9, 3, ##' 9, 4, ##' 8, 11, ##' 11, 5, ##' 11, 6, ##' 11, 7, ##' 0, 8), ncol=2, byrow=TRUE) ##' ##' P2 <- phylo4(E) ##' nodeLabels(P2) <- as.character(nodeId(P2, "internal")) ##' plot(P2, show.node.label=TRUE) ##' sumryP2 <- summary(P2) ##' sumryP2 ##' setGeneric("summary") ##' @rdname summary-methods ##' @aliases summary,phylo4-method setMethod("summary", signature(object="phylo4"), function(object, quiet=FALSE) { res <- list() ## build the result object res$name <- deparse(substitute(object, sys.frame(-1))) res$nb.tips <- nTips(object) res$nb.nodes <- nNodes(object) if(hasEdgeLength(object)) { edge.length <- edgeLength(object) res$mean.el <- mean(edge.length, na.rm=TRUE) res$var.el <- stats::var(edge.length, na.rm=TRUE) if (isRooted(object) && is.na(edgeLength(object, rootNode(object)))) { root.index <- match(edgeId(object, "root"), names(edge.length)) res$sumry.el <- summary(edge.length[-root.index]) } else { res$sumry.el <- summary(edge.length) } } ## check for polytomies if (hasPoly(object)) { E <- edges(object) temp <- tabulate(E[,1][!is.na(E[, 1])]) degree <- temp[E[,1][!is.na(E[, 1])]] # contains the degree of the ancestor for all edges endsAtATip <- !(E[,2] %in% E[,1]) terminPoly <- (degree>2) & endsAtATip internPoly <- (degree>2) & !endsAtATip res$degree <- degree res$polytomy <- rep("none",nrow(E)) res$polytomy[terminPoly] <- "terminal" res$polytomy[internPoly] <- "internal" ## now just keep information about nodes (not all edges) nod <- unique(E[,1]) idx <- match(nod,E[,1]) res$degree <- res$degree[idx] names(res$degree) <- nodeLabels(object) res$polytomy <- res$polytomy[idx] names(res$polytomy) <- nodeLabels(object) } ## model info res$loglik <- attr(object, "loglik") res$para <- attr(object, "para") res$xi <- attr(object, "xi") ## if quiet, stop here if(quiet) return(invisible(res)) ## now, print to screen is !quiet cat("\n Phylogenetic tree :", res$name, "\n\n") cat(" Number of tips :", res$nb.tips, "\n") cat(" Number of nodes :", res$nb.nodes, "\n") ## cat(" ") if(hasEdgeLength(object)) { cat(" Branch lengths:\n") cat(" mean :", res$mean.el, "\n") cat(" variance :", res$var.el, "\n") cat(" distribution :\n") print(res$sumry.el) } else { cat(" Branch lengths : No branch lengths.\n") } if (hasPoly(object)) { cat("\nDegree of the nodes :\n") print(res$degree) cat("\n") cat("Types of polytomy:\n") print(res$polytomy) cat("\n") } if (!is.null(attr(object, "loglik"))) { cat("Phylogeny estimated by maximum likelihood.\n") cat(" log-likelihood:", attr(object, "loglik"), "\n\n") npart <- length(attr(object, "para")) for (i in 1:npart) { cat("partition ", i, ":\n", sep = "") print(attr(object, "para")[[i]]) if (i == 1) next else cat(" contrast parameter (xi):", attr(object,"xi")[i - 1], "\n") } } return(invisible(res)) }) ##' @rdname summary-methods ##' @aliases summary,phylo4d-method setMethod("summary", signature(object="phylo4d"), function(object, quiet=FALSE) { x <- object res <- summary(as(x, "phylo4"), quiet=quiet) res$name <- deparse(substitute(object, sys.frame(-1))) tips <- tdata(object, "tip") nodes <- tdata(object, "internal") if (!quiet) cat("\nComparative data:\n") if (nrow(tips) > 0) { if(!quiet) { cat("\nTips: data.frame with", nTips(object), "taxa and", ncol(tips), "variable(s) \n\n") } sumry.tips <- summary(tips) res$sumry.tips <- sumry.tips if (!quiet) print(sumry.tips) } else { if (!quiet) cat("\nObject contains no tip data.") } if (nrow(nodes) > 0) { if (!quiet) { cat("\nNodes: data.frame with", nNodes(object), "internal nodes and", ncol(nodes), "variables \n\n") } sumry.nodes <- summary(nodes) res$sumry.nodes <- sumry.nodes if (!quiet) print(sumry.nodes) } else { if(!quiet) cat("\nObject contains no node data.\n") } invisible(res) }) ##' @rdname summary-methods ##' @aliases nodeType ##' @export setGeneric("nodeType", function(object) { standardGeneric("nodeType") }) ##' @rdname summary-methods ##' @aliases nodeType,phylo4-method setMethod("nodeType", signature(object="phylo4"), function(object) { if(nTips(object) == 0) return(NULL) else { ## strip out the root ancestor nodesVect <- as.vector(edges(object)) nodesVect <- nodesVect[nodesVect != 0] ## get a sorted list of the unique nodes listNodes <- sort(unique(nodesVect)) t <- rep("internal", length(listNodes)) # FM: internal is default (I think it's safer) names(t) <- listNodes ## node number of real internal nodes iN <- names(table(edges(object)[,1])) ## node number that are not internal nodes (ie that are tips) tN <- names(t)[!names(t) %in% iN] t[tN] <- "tip" ## if the tree is rooted if(isRooted(object)) t[rootNode(object)] <- "root" return(t) } }) phylobase/R/phylo4d-accessors.R0000644000176200001440000000527112353104054016134 0ustar liggesusers ##' Tests for presence of data associated with trees stored as phylo4d objects ##' ##' Methods that test for the presence of data associated with trees stored as ##' \code{phylo4d} objects. ##' ##' \code{nData} tests for the presence of data associated with the object. ##' ##' \code{hasTipData} and \code{hasNodeData} tests for the presence of ##' data associated with the tips and the internal nodes ##' respectively. The outcome of the test is based on row names of the ##' data frame stored in the \code{data} slot. If no rows have names ##' from the set \code{nodeId(x, "tip")}, then \code{hasTipData} ##' returns FALSE. Likewise, if no rows have names from the set ##' \code{nodeId(x, "internal")}, then \code{hasNodeData} returns ##' FALSE. ##' ##' @param x a \code{phylo4d} object ##' @return \describe{ ##' ##' \item{\code{nData}}{returns the number of datasets (i.e., ##' columns) associated with the object.} ##' ##' \item{\code{hasTipData}, \code{hasNodeData}}{return \code{TRUE} ##' or \code{FALSE} depending whether data associated with the ##' tree are associated with either tips or internal nodes respectively.}} ##' @section Methods: \describe{ \item{hasNodeData}{\code{signature(object = ##' "phylo4d")}: whether tree has internal node data} ##' \item{hasTipData}{\code{signature(object = "phylo4d")}: whether tree has ##' data associated with its tips} } ##' @author Ben Bolker, Thibault Jombart, Francois Michonneau ##' @seealso \code{\link{phylo4d-methods}} constructor and ##' \code{\linkS4class{phylo4d}} class. ##' @rdname phylo4d-accessors ##' @aliases hasTipData ##' @keywords methods ##' @docType methods ##' @include phylo4d-class.R phylo4d-methods.R ##' @export ##' @examples ##' data(geospiza) ##' nData(geospiza) ## 5 ##' hasTipData(geospiza) ## TRUE ##' hasNodeData(geospiza) ## FALSE ##' setGeneric("hasTipData", function(x) { standardGeneric("hasTipData") }) ##' @rdname phylo4d-accessors ##' @aliases hasTipData-method,phylo4d-method setMethod("hasTipData", signature(x="phylo4d"), function(x) { ncol(tdata(x, type="tip", empty.columns=FALSE)) > 0 }) ##' @rdname phylo4d-accessors ##' @aliases hasNodeData-methods ##' @export setGeneric("hasNodeData", function(x) { standardGeneric("hasNodeData") }) ##' @rdname phylo4d-accessors ##' @aliases hasNodeData,phylo4d-method setMethod("hasNodeData", signature(x="phylo4d"), function(x) { ncol(tdata(x, type="internal", empty.columns=FALSE)) > 0 }) ##' @rdname phylo4d-accessors ##' @aliases nData ##' @export setGeneric("nData", function(x) { standardGeneric("nData") }) ##' @rdname phylo4d-accessors ##' @aliases nData,phylo4d-method setMethod("nData", signature(x="phylo4d"), function(x) { ncol(x@data) }) phylobase/R/phylomats-class.R0000644000176200001440000001204112435457156015721 0ustar liggesusers ##' matrix classes for phylobase ##' ##' Classes representing phylogenies as matrices ##' ##' ##' @name phylomat-class ##' @aliases phylo4vcov-class as_phylo4vcov ##' @docType class ##' @param from a \code{phylo4} object ##' @param \dots optional arguments, to be passed to \code{vcov.phylo} in ##' \code{ape} (the main useful option is \code{cor}, which can be set to ##' \code{TRUE} to compute a correlation rather than a variance-covariance ##' matrix) ##' @section Objects from the Class: These are square matrices (with rows and ##' columns corresponding to tips, and internal nodes implicit) with different ##' meanings depending on the type (variance-covariance matrix, distance matrix, ##' etc.). ##' @author Ben Bolker ##' @rdname phylomat-class ##' @keywords classes ##' @export ##' @examples ##' tree_string <- "(((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3):6.3,Tyto_alba:13.5);" ##' tree.owls <- ape::read.tree(text=tree_string) ##' o2 <- as(tree.owls,"phylo4") ##' ov <- as(o2,"phylo4vcov") ##' o3 <- as(ov,"phylo4") ##' ## these are not completely identical, but are ##' ## topologically identical ... ##' ##' ## edge matrices are in a different order: ##' ## cf. edges(o2) and edges(o3) ##' ## BUT the edge matrices are otherwise identical ##' o2edges <- edges(o2) ##' o3edges <- edges(o3) ##' identical(o2edges[order(o2edges[,2]),], ##' o3edges[order(o3edges[,2]),]) ##' ##' ## There is left/right ambiguity here in the tree orders: ##' ## in o2 the 5->6->7->1 lineage ##' ## (terminating in Strix aluco) ##' ## is first, in o3 the 5->6->3 lineage ##' ## (terminating in Athene noctua) is first. ##' ##' ## define class for phylogenetic var-cov matrices setClass("phylo4vcov", representation("matrix", edge.label="character", order="character")) ## phylo4 -> var-cov: simply wrap ape::vcv.phylo ## and add other slots as_phylo4vcov <- function(from,...) { m <- ape::vcv.phylo(as(from,"phylo"),...) new("phylo4vcov", m, edge.label=from@edge.label, order=from@order) } ##' @name phylomat-setAs ##' @rdname phylomat-class ##' @aliases setAs,phylo,phylo4vcov-method setAs("phylo4","phylo4vcov", function(from,to) { as_phylo4vcov(from)}) ##' @name phylomat-setAs ##' @rdname phylomat-class ##' @aliases setAs,phylo4vcov,phylo4-method setAs("phylo4vcov","phylo4", function(from,to) { matrix2tree <- function(v,reorder=TRUE) { ## no polytomies allowed va <- v tipnames <- rownames(v) ntip <- nrow(v) dimnames(v) <- list(as.character(1:ntip), as.character(1:ntip)) diag(va) <- 0 edgemat <- matrix(ncol=2,nrow=0) ## termlens <- diag(v)-colSums(va) edgelens <- numeric(0) ## maxnode <- ntip curnode <- 2*ntip ## one greater than total number of nodes ## can we do this in a different order? while (nrow(v)>1) { mva <- max(va) ## find pair with max shared evolution nextpr <- if (nrow(v)==2) c(1,2) else which(va==mva,arr.ind=TRUE)[1,] ## maxnode <- maxnode+1 ## new node curnode <- curnode-1 ## points to both of current identified nodes ## (indexed by names) edgemat <- rbind(edgemat, c(curnode,as.numeric(rownames(v)[nextpr[1]])), c(curnode,as.numeric(rownames(v)[nextpr[2]]))) ## descending edges are amount of *unshared* evolution edgelens <- c(edgelens, diag(v)[nextpr]-mva) ## this clade has total evolution = shared evolution diag(v)[nextpr] <- mva ## assign new node name rownames(v)[nextpr[1]] <- colnames(v)[nextpr[1]] <- curnode ## drop rows/cols from matrix v <- v[-nextpr[2],-nextpr[2],drop=FALSE] va <- va[-nextpr[2],-nextpr[2],drop=FALSE] } ## switch order of node numbers to put root in the right place: ## much plotting code seems to assume root = node # (ntips+1) ## browser() reorder <- FALSE if (reorder) { nn <- nrow(edgemat) nnode <- nn-ntip+1 newedge <- edgemat for (i in 2:nnode) { newedge[edgemat==(ntip+i)] <- nn-i+2 } edgemat <- newedge } list(edgemat=edgemat, edgelens=edgelens) } temptree <- matrix2tree(from) ## browser() ## add explicit root rootnode <- which(tabulate(temptree$edgemat[,2])==0) ## add root node to edge matrix and branch lengths temptree$edgemat <- rbind(temptree$edgemat, c(0, rootnode)) temptree$edgelens <- c(temptree$edgelens,NA) reorder(phylo4(temptree$edgemat,edge.length=temptree$edgelens, tip.label=rownames(from), edge.label=from@edge.label,order="unknown"), "preorder") }) phylobase/R/edgeLength-methods.R0000644000176200001440000002555212554174424016314 0ustar liggesusers ## TODO -- the behavior of edgeLength needs to be made more consistent ## with other functions like MRCA. The user should be able to specify a ## vector of nodes, of edges, or both. ##### This file contains ## hasEdgeLength ## edgeLength and edgeLength<- ## isUltrametric ## nodeDepth ## sumEdgeLength ##' edgeLength methods ##' ##' These functions give information about and allow replacement of edge lengths. ##' ##' The \code{edgeLength} function returns the edge length in the same ##' order as the edges in the matrix. ##' ##' @param x a \code{phylo4} or \code{phylo4d} object. ##' @param value a numeric vector indicating the new values for the edge lengths ##' @param node optional numeric or character vector indicating the ##' nodes for which edge ##' @param use.names should the the name attributes of \code{value} be ##' used to match the length to a given edge. ##' @param tol the tolerance to decide whether all the tips have the ##' same depth to test if the tree is ultrametric. Default is ##' \code{.Machine$double.eps^0.5}. ##' @param \dots optional arguments (none used at present). ##' @return \describe{ ##' ##' \item{hasEdgeLength}{whether or not the object has edge lengths ##' (logical)} ##' ##' \item{edgeLength}{a named vector of the edge length for the ##' object} ##' ##' \item{isUltrametric}{whether or not the tree is ultrametric (all ##' the tips are have the same depth (distance from the root) (logical)} ##' ##' \item{sumEdgeLength}{the sum of the edge lengths for a set of ##' nodes (intended to be used with \code{ancestors} or \code{descendants})} ##' ##' \item{nodeHeight}{the distance between a node and the root or the ##' tips. The format of the result will depend on the options and the ##' number of nodes provided, either a vector or a list.} ##' ##' \item{nodeDepth}{Deprecated, now replaced by \code{nodeHeight}. A ##' named vector indicating the \dQuote{depth} (the distance between ##' the root and a given node).} ##' ##' \item{depthTip}{Deprecated, now replaced by \code{nodeHeight}.} ##' ##' } ##' @seealso \code{ancestors}, \code{descendants}, \code{.Machine} for ##' more information about tolerance. ##' @export ##' @docType methods ##' @aliases hasEdgeLength ##' @rdname edgeLength-methods ##' @include phylo4-class.R ##' @include phylo4-methods.R ##' @include nodeId-methods.R ##' @examples ##' data(geospiza) ##' hasEdgeLength(geospiza) # TRUE ##' topoGeo <- geospiza ##' edgeLength(topoGeo) <- NULL ##' hasEdgeLength(topoGeo) # FALSE ##' ##' edgeLength(geospiza)[2] # use the position in vector ##' edgeLength(geospiza)["16-17"] # or the name of the edge ##' edgeLength(geospiza, 17) # or the descendant node of the edge ##' ##' ## The same methods can be used to update an edge length ##' edgeLength(geospiza)[2] <- 0.33 ##' edgeLength(geospiza)["16-17"] <- 0.34 ##' edgeLength(geospiza, 17) <- 0.35 ##' ##' ## Test if tree is ultrametric ##' isUltrametric(geospiza) # TRUE ##' ## indeed all tips are at the same distance from the root ##' nodeHeight(geospiza, nodeId(geospiza, "tip"), from="root") ##' ## compare distances from tips of two MRCA ##' nodeHeight(geospiza, MRCA(geospiza, c("pallida", "psittacula")), from="min_tip") ##' nodeHeight(geospiza, MRCA(geospiza, c("fortis", "difficilis")), from="min_tip") ##' ## or the same but from the root ##' nodeHeight(geospiza, MRCA(geospiza, c("pallida", "psittacula")), from="root") ##' nodeHeight(geospiza, MRCA(geospiza, c("fortis", "difficilis")), from="root") setGeneric("hasEdgeLength", function(x) { standardGeneric("hasEdgeLength") }) ##' @rdname edgeLength-methods ##' @aliases hasEdgeLength,phylo4-method setMethod("hasEdgeLength", signature(x="phylo4"), function(x) { !all(is.na(x@edge.length)) }) #### ----- edgeLength ##' @rdname edgeLength-methods ##' @aliases edgeLength ##' @export setGeneric("edgeLength", function(x, ...) { standardGeneric("edgeLength") }) ##' @rdname edgeLength-methods ##' @aliases edgeLength,phylo4-method setMethod("edgeLength", signature(x="phylo4"), function(x, node) { ## [JR: below, using match for ordering rather than direct character ## indexing b/c the latter is slow for vectors of a certain size] if (!missing(node)) { id <- getEdge(x, node) } else { id <- edgeId(x, "all") } elen <- x@edge.length[match(id, names(x@edge.length))] names(elen) <- id return(elen) }) ##' @rdname edgeLength-methods ##' @aliases edgeLength<- ##' @export setGeneric("edgeLength<-", function(x, use.names=TRUE, ..., value) { standardGeneric("edgeLength<-") }) ##' @name edgeLength<- ##' @rdname edgeLength-methods ##' @aliases edgeLength<-,phylo4-method edgeLength<-,phylo4,ANY-method setReplaceMethod("edgeLength", signature(x="phylo4", value="ANY"), function(x, use.names=TRUE, ..., value) { len <- .createEdge(value, x@edge, type="lengths", use.names) ## return empty vector if all values are NA if (all(is.na(len))) { emptyVec <- numeric() attributes(emptyVec) <- list(names=character(0)) x@edge.length <- emptyVec } else { x@edge.length <- len } if(is.character(checkval <- checkPhylo4(x))) stop(checkval) x }) ##### ------ depthTips ##' @rdname edgeLength-methods ##' @aliases depthTips ##' @export setGeneric("depthTips", function(x) { standardGeneric("depthTips") }) ##' @rdname edgeLength-methods ##' @aliases depthTips,phylo4-methods setMethod("depthTips", signature(x="phylo4"), function(x) { .Deprecated("nodeHeight") nodeDepth(x, 1:nTips(x)) }) ##### ----- nodeDepth ##' @rdname edgeLength-methods ##' @aliases nodeDepth ##' @export setGeneric("nodeDepth", function(x, node) { standardGeneric("nodeDepth") }) ##' @rdname edgeLength-methods ##' @aliases nodeDepth,phylo4-method setMethod("nodeDepth", signature(x="phylo4"), function(x, node) { .Deprecated("nodeHeight") if (!hasEdgeLength(x)) return(NULL) else { node <- getNode(x, node, missing="warn") node <- node[!is.na(node)] res <- sapply(node, function(n) sumEdgeLength(x, ancestors(x, n, "ALL"))) if (length(res) == 1) { res <- res[[1]] names(res) <- names(node) } res } }) ###### ----- nodeHeight ##' @param from The point of reference for calculating the height of ##' the node. \code{root} calculates the distance between the root of ##' the tree and the node. \code{all_tip} return the distance between ##' the node and all the tips descending from it. \code{min_tip} the ##' distance between the node and its closest tip. \code{max_tip} the ##' distance between the node and its farther tip. \code{min_tip} and ##' \code{max_tip} will be identical if the tree is ultrametric. If ##' more than one tip is equidistant from the node, the tip with the ##' lowest node id will be returned. ##' @rdname edgeLength-methods ##' @aliases nodeHeight ##' @export setGeneric("nodeHeight", function(x, node, from) { standardGeneric("nodeHeight") }) ##' @rdname edgeLength-methods ##' @aliases nodeHeight,phylo4-method setMethod("nodeHeight", signature(x = "phylo4"), function(x, node, from = c("root", "all_tip", "min_tip", "max_tip")) { from <- match.arg(from) if (!hasEdgeLength(x)) return(NULL) else { node <- getNode(x, node, missing = "warn") node <- node[!is.na(node)] tip_id <- nodeId(x, "tip") if (from != "root") { ## Get the full paths to the tips from the node res <- lapply(node, function(n) { if (n %in% tip_id) { ## tips are always at 0 tmp_res <- stats::setNames(0, tipLabels(x)[n]) } else { desc_pths <- descendants(x, n, "all") ## Get the paths in the other direction anc_pths <- lapply(desc_pths[desc_pths %in% tip_id], function(n) { ancestors(x, n, "ALL") }) ## Shortest paths for each tip pths <- lapply(anc_pths, function(anc_pth) { intersect(desc_pths, anc_pth) }) tmp_res <- sapply(pths, function(n) { sumEdgeLength(x, n) }) tmp_res <- switch(from, "all_tip" = tmp_res, "min_tip" = tmp_res[which.min(tmp_res)], "max_tip" = tmp_res[which.max(tmp_res)]) } tmp_res }) } else { res <- sapply(node, function(n) { sumEdgeLength(x, ancestors(x, n, "ALL")) }) } names(res) <- node if (length(res) == 1) { res <- res[[1]] } } res }) ###### ----- sumEdgeLength ##' @rdname edgeLength-methods ##' @aliases sumEdgeLength ##' @export setGeneric("sumEdgeLength", function(x, node) { standardGeneric("sumEdgeLength") }) ##' @rdname edgeLength-methods ##' @aliases sumEdgeLength,phylo4-method setMethod("sumEdgeLength", signature(x="phylo4"), function(x, node) { if(!hasEdgeLength(x)) NULL else { nd <- getNode(x, node) iEdges <- which(x@edge[,2] %in% nd) sumEdges <- sum(x@edge.length[iEdges], na.rm=TRUE) sumEdges } }) ###### ----- isUltrametric ##' @rdname edgeLength-methods ##' @aliases isUltrametric ##' @export setGeneric("isUltrametric", function(x, tol=.Machine$double.eps^.5) { standardGeneric("isUltrametric") }) ##' @rdname edgeLength-methods ##' @aliases isUltrametric,phylo4-method setMethod("isUltrametric", signature(x="phylo4"), function(x, tol=.Machine$double.eps^.5) { if (!hasEdgeLength(x)) { stop("The tree has no edge lengths.") } if (identical(all.equal.numeric(stats::var(nodeHeight(x, nodeId(x, "tip"), "root")), 0, tolerance=tol), TRUE)) { TRUE } else FALSE }) phylobase/R/labels-methods.R0000644000176200001440000002115512553731522015500 0ustar liggesusers ######################################################### ### Label accessors ######################################################### ##' Labels for phylo4/phylo4d objects ##' ##' Methods for creating, accessing and updating labels in ##' phylo4/phylo4d objects ##' ##' In phylo4/phylo4d objects, tips must have labels (that's why there ##' is no method for hasTipLabels), internal nodes and edges can have ##' labels. ##' ##' Labels must be provided as a vector of class \code{character}. The ##' length of the vector must match the number of elements they label. ##' ##' The option \code{use.names} allows the user to match a label to a ##' particular node. In this case, the vector must have names that ##' match the node numbers. ##' ##' The function \code{labels} is mostly intended to be used ##' internally. ##' ##' @name phylo4-labels ##' @aliases labels ##' @docType methods ##' @param x a phylo4 or phylo4d object. ##' @param object a phylo4 or phylo4d object. ##' @param type which type of labels: \code{all} (tips and internal nodes), ##' \code{tip} (tips only), \code{internal} (internal nodes only). ##' @param \dots additional optional arguments (not in use) ##' @param value a vector of class \code{character}, see Details for more ##' information. ##' @param use.names should the names of the vector used to create/update labels ##' be used to match the labels? See Details for more information. ##' @section Methods: \describe{ \item{labels}{\code{signature(object = ##' "phylo4")}: tip and/or internal node labels, ordered by node ID} ##' ##' \item{hasDuplicatedLabels}{\code{signature(object = "phylo4")}: are any ##' labels duplicated?} ##' ##' \item{tipLabels}{\code{signature(object = "phylo4")}: tip labels, ordered by ##' node ID} ##' ##' \item{hasNodeLabels}{\code{signature(object = "phylo4")}: whether tree has ##' (internal) node labels} \item{nodeLabels}{\code{signature(object = ##' "phylo4")}: internal node labels, ordered by node ID} ##' ##' \item{hasEdgeLabels}{\code{signature(object = "phylo4")}: whether tree has ##' (internal) edge labels} \item{edgeLabels}{\code{signature(object = ##' "phylo4")}: internal edge labels, ordered according to the edge matrix} } ##' @exportMethod labels ##' @rdname labels-methods ##' @include phylo4-class.R phylo4-methods.R phylo4-accessors.R nodeId-methods.R ##' @author Ben Bolker, Peter Cowan, Steve Kembel, Francois Michonneau ##' @return labels in ascending order. ##' @examples ##' ##' data(geospiza) ##' ##' ## Return labels from geospiza ##' tipLabels(geospiza) ##' ##' ## Internal node labels in geospiza are empty ##' nodeLabels(geospiza) ##' ##' ## Creating internal node labels ##' ndLbl <- paste("n", 1:nNodes(geospiza), sep="") ##' nodeLabels(geospiza) <- ndLbl ##' nodeLabels(geospiza) ##' ##' ## naming the labels ##' names(ndLbl) <- nodeId(geospiza, "internal") ##' ##' ## shuffling the labels ##' (ndLbl <- sample(ndLbl)) ##' ##' ## by default, the labels are attributed in the order ##' ## they are given: ##' nodeLabels(geospiza) <- ndLbl ##' nodeLabels(geospiza) ##' ##' ## but use.names puts them in the correct order ##' labels(geospiza, "internal", use.names=TRUE) <- ndLbl ##' nodeLabels(geospiza) setGeneric("labels") ##' @rdname labels-methods ##' @aliases labels,phylo4-method setMethod("labels", signature(object="phylo4"), function(object, type = c("all", "tip", "internal")) { type <- match.arg(type) ## [JR: below, using match for ordering rather than direct character ## indexing b/c the latter is slow for vectors of a certain size] label <- object@label id <- nodeId(object, type) lbl <- label[match(id, names(label))] # reassign names b/c any unmatched will be NA (could instead assign # names only to the unmatched ones, but this seems simpler) names(lbl) <- id return(lbl) }) ##' @rdname labels-methods ##' @export setGeneric("labels<-", function(x, type, use.names, ..., value) { standardGeneric("labels<-") }) ##' @rdname labels-methods setReplaceMethod("labels", signature(x="phylo4", type="ANY", use.names="ANY", value="ANY"), function(x, type = c("all", "tip", "internal"), use.names, ..., value) { ## Default options if(missing(type)) type <- "all" if (missing(use.names)) use.names <- FALSE type <- match.arg(type) ## generate new labels of the desired type new.label <- .createLabels(value, nTips(x), nNodes(x), use.names, type=type) ## replace existing labels and add new ones as needed old.label <- x@label old.index <- match(names(new.label), names(old.label)) isNew <- is.na(old.index) old.label[old.index[!isNew]] <- new.label[!isNew] updated.label <- c(old.label, new.label[isNew]) ## for efficiency, drop any NA labels x@label <- updated.label[!is.na(updated.label)] if(is.character(checkval <- checkPhylo4(x))) stop(checkval) else return(x) }) ##### -------- hasDuplicatedLabels ##' @rdname labels-methods ##' @aliases hasDuplicatedLabels ##' @export setGeneric("hasDuplicatedLabels", function(x, type) { standardGeneric("hasDuplicatedLabels") }) ##' @rdname labels-methods ##' @aliases hasDuplicatedLabels,phylo4,ANY-method setMethod("hasDuplicatedLabels", signature(x="phylo4", type="ANY"), function(x, type=c("all", "tip", "internal")) { ## Default options if (missing(type)) { type <- "all" } type <- match.arg(type) hasDuplicatedLabelsCpp(labels(x, type)) }) ##### --------- hasNodeLabels ##' @rdname labels-methods ##' @aliases hasNodeLabels ##' @export setGeneric("hasNodeLabels", function(x) { standardGeneric("hasNodeLabels") }) ##' @rdname labels-methods ##' @aliases hasNodeLabels,phylo4-method setMethod("hasNodeLabels", signature(x="phylo4"), function(x) { !all(is.na(nodeLabels(x))) }) ##### ---------- nodeLabels ##' @rdname labels-methods ##' @aliases nodeLabels ##' @export setGeneric("nodeLabels", function(x) { standardGeneric("nodeLabels") }) ##' @rdname labels-methods ##' @aliases nodeLabels,phylo4-method setMethod("nodeLabels", signature(x="phylo4"), function(x) { labels(x, type="internal") }) ##' @rdname labels-methods ##' @export setGeneric("nodeLabels<-", function(x, ..., value) { standardGeneric("nodeLabels<-") }) ##' @rdname labels-methods setReplaceMethod("nodeLabels", signature(x="phylo4", value="ANY"), function(x, ..., value) { labels(x, type="internal", ...) <- value if(is.character(checkval <- checkPhylo4(x))) stop(checkval) x }) ##### ---------- tipLabels ##' @rdname labels-methods ##' @aliases tipLabels ##' @export setGeneric("tipLabels", function(x) { standardGeneric("tipLabels") }) ##' @rdname labels-methods setMethod("tipLabels", signature(x="phylo4"), function(x) { labels(x, type="tip") }) ##' @rdname labels-methods ##' @export setGeneric("tipLabels<-", function(x, ..., value) { standardGeneric("tipLabels<-") }) ##' @rdname labels-methods setReplaceMethod("tipLabels", signature(x="phylo4", value="ANY"), function(x, ..., value) { labels(x, type="tip", ...) <- value if(is.character(checkval <- checkPhylo4(x))) stop(checkval) return(x) }) ##### ---------- hasEdgeLabels ##' @rdname labels-methods ##' @aliases hasEdgeLabels ##' @export setGeneric("hasEdgeLabels", function(x) { standardGeneric("hasEdgeLabels") }) ##' @rdname labels-methods setMethod("hasEdgeLabels", signature(x="phylo4"), function(x) { !all(is.na(x@edge.label)) }) ##### ---------- edgeLabels ##' @rdname labels-methods ##' @aliases edgeLabels ##' @export setGeneric("edgeLabels", function(x) { standardGeneric("edgeLabels") }) ##' @rdname labels-methods ##' @aliases edgeLabels,phylo4-method setMethod("edgeLabels", signature(x="phylo4"), function(x) { ## [JR: below, using match for ordering rather than direct character ## indexing b/c the latter is slow for vectors of a certain size] id <- edgeId(x, "all") lbl <- x@edge.label[match(id, names(x@edge.label))] names(lbl) <- id return(lbl) }) ##' @rdname labels-methods ##' @aliases edgeLabels<- ##' @export setGeneric("edgeLabels<-", function(x, ..., value) { standardGeneric("edgeLabels<-") }) ##' @rdname labels-methods setReplaceMethod("edgeLabels", signature(x="phylo4", value="ANY"), function(x, ..., value) { lbl <- .createEdge(value, x@edge, type="labels") x@edge.label <- lbl[!is.na(lbl)] if(is.character(checkval <- checkPhylo4(x))) stop(checkval) x }) phylobase/R/shortestPath-methods.R0000644000176200001440000000445212347155416016732 0ustar liggesusers .shortestPathInt <- function(phy, node1, node2){ ## some checks ## if (is.character(checkval <- checkPhylo4(x))) stop(checkval) # no need t1 <- getNode(phy, node1) t2 <- getNode(phy, node2) if(any(is.na(c(t1,t2)))) stop("wrong node specified") if(t1==t2) return(NULL) ## main computations comAnc <- MRCA(phy, t1, t2) # common ancestor desComAnc <- descendants(phy, comAnc, type="all") ancT1 <- ancestors(phy, t1, type="all") path1 <- intersect(desComAnc, ancT1) # path: common anc -> t1 ancT2 <- ancestors(phy, t2, type="all") path2 <- intersect(desComAnc, ancT2) # path: common anc -> t2 res <- union(path1, path2) # union of the path ## add the common ancestor if it differs from t1 or t2 if(!comAnc %in% c(t1,t2)){ res <- c(comAnc,res) } res <- getNode(phy, res) return(res) } ##' Finds the shortest path between two nodes in a tree ##' ##' Given two nodes (i.e, tips or internal nodes), this function ##' returns the shortest path between them (excluding \code{node1} and ##' \code{node2} as a vector of nodes. ##' @title shortestPath-methods ##' @param x a tree in the phylo4, phylo4d or phylo format ##' @param node1 a numeric or character (passed to \code{getNode}) ##' indicating the beginning from which the path should be calculated. ##' @param node2 a numeric or character (passed to \code{getNode}) ##' indicating the end of the path. ##' @return a vector of nodes indcating the shortest path between 2 nodes ##' @seealso getNode ##' @rdname shortestPath-methods ##' @docType methods ##' @include MRCA-methods.R ##' @export setGeneric("shortestPath", function(x, node1, node2) { standardGeneric("shortestPath") }) ##' @name shortestPath-phylo4 ##' @rdname shortestPath-methods ##' @aliases shortestPath,phylo4-method setMethod("shortestPath", signature(x="phylo4", node1="ANY", node2="ANY"), function(x, node1, node2) { .shortestPathInt(phy=x, node1=node1, node2=node2) }) ##' @name shortestPath-phylo ##' @rdname shortestPath-methods ##' @aliases shortestPath,phylo-method setMethod("shortestPath", signature(x="phylo", node1="ANY", node2="ANY"), function(x, node1, node2) { phy <- as(x, "phylo4") .shortestPathInt(phy=phy, node1=node1, node2=node2) }) phylobase/R/extractTree.R0000644000176200001440000000250712353103746015066 0ustar liggesusers## extract the phylo4 part of phylo4d; relies on implicit coerce method ##' Get tree from tree+data object ##' ##' Extracts a \code{phylo4} tree object from a \code{phylo4d} ##' tree+data object. ##' ##' \code{extractTree} extracts just the phylogeny from a tree+data ##' object. The phylogeny contains the topology (how the nodes are ##' linked together), the branch lengths (if any), and any tip and/or ##' node labels. This may be useful for extracting a tree from a ##' \code{phylo4d} object, and associating with another phenotypic ##' dataset, or to convert the tree to another format. ##' ##' @param from a \code{phylo4d} object, containing a phylogenetic ##' tree plus associated phenotypic data. Created by the ##' \code{phylo4d()} function. ##' @author Ben Bolker ##' @seealso \code{\link{phylo4-methods}}, ##' \code{\link{phylo4d-methods}}, \code{\link{coerce-methods}} for ##' translation functions. ##' @keywords methods ##' @export ##' @include setAs-methods.R ##' @examples ##' tree.phylo <- ape::read.tree(text = "((a,b),c);") ##' tree <- as(tree.phylo, "phylo4") ##' plot(tree) ##' tip.data <- data.frame(size = c(1, 2, 3), row.names = c("a", "b", "c")) ##' (treedata <- phylo4d(tree, tip.data)) ##' plot(treedata) ##' (tree1 <- extractTree(treedata)) ##' plot(tree1) ##' extractTree <- function(from) { as(from, "phylo4") } phylobase/R/checkdata.R0000644000176200001440000002723512554021250014500 0ustar liggesusers## REQUIRED for all trees ##' Validity checking for phylo4 objects ##' ##' Basic checks on the validity of S4 phylogenetic objects ##' ##' ##' @aliases checkPhylo4 checkTree checkPhylo4Data ##' @param object A prospective phylo4 or phylo4d object ##' @return As required by \code{\link[methods]{validObject}}, returns an error ##' string (describing problems) or TRUE if everything is OK. ##' @note ##' ##' These functions are only intended to be called by other phylobase functions. ##' ##' \code{checkPhylo4} is an (inflexible) wrapper for ##' \code{checkTree}. The rules for \code{phylo4} objects essentially ##' follow those for \code{phylo} objects from the \code{ape} package, ##' which are in turn defined in ##' \url{http://ape-package.ird.fr/misc/FormatTreeR_24Oct2012.pdf}. ##' These are essentially that: \itemize{ \item if the tree has edge ##' lengths defined, the number of edge lengths must match the number ##' of edges; \item the number of tip labels must match the number of ##' tips; \item in a tree with \code{ntips} tips and \code{nnodes} ##' (total) nodes, nodes 1 to \code{ntips} must be tips \item if the ##' tree is rooted, the root must be node number \code{ntips+1} and ##' the root node must be the first row of the edge matrix \item tip ##' labels, node labels, edge labels, edge lengths must have proper ##' internal names (i.e. internal names that match the node numbers ##' they document) \item tip and node labels must be unique } ##' ##' You can alter some of the default options by using the function ##' \code{phylobase.options}. ##' ##' For \code{phylo4d} objects, \code{checkTree} also calls ##' \code{checkPhylo4Data} to check the validity of the data associated with the ##' tree. It ensures that (1) the data associated with the tree have the correct ##' dimensions, (2) that the row names for the data are correct. ##' @author Ben Bolker, Steven Kembel, Francois Michonneau ##' @seealso the \code{\link{phylo4}} constructor and ##' \linkS4class{phylo4} class; the \code{\link{phylo4d-methods}} constructor ##' and the \linkS4class{phylo4d} class do checks for the data ##' associated with trees. See \code{\link{coerce-methods}} for ##' translation functions and \code{\link{phylobase.options} to change ##' some of the default options of the validator.} ##' @include RcppExports.R ##' @include phylo4-class.R ##' @include phylo4-methods.R ##' @export ##' @keywords misc checkPhylo4 <- function(object) { ct <- checkTree(object) if (class(object) == "phylo4d") ## checkPhyo4Data returns TRUE or fail cd <- checkPhylo4Data(object) return(ct) } checkTree <- function(object) { ## case of empty phylo4 object if(nrow(object@edge) == 0 && length(object@edge.length) == 0 && length(object@label) == 0 && length(object@edge.label) == 0) return(TRUE) ## get options opt <- phylobase.options() ## Storage of error/warning messages err <- wrn <- character(0) ## Matrix is integer if (!is.integer(object@edge)) { err <- c(err, "Edge matrix needs to be integer.") } ## Matrix doesn't have NAs if (any(is.na(object@edge))) { err <- c(err, "Edge matrix cannot have NAs at this time.", "This could only happen if singletons were allowed", "but this is not supported by phylobase yet.") } ## Having non-integer or NAs cause cryptic messages, so stop here ## if it's the case if (length(err)) return(err) ## Named slots if (is.null(attributes(object@label)$names)) { err <- c(err, "The label slot needs to be a named vector.") attributes(object@label) <- list(names=character(0)) } if (is.null(attributes(object@edge.length)$names)) { err <- c(err, "The edge.length slot needs to be a named vector.") attributes(object@edge.length) <- list(names=character(0)) } if (is.null(attributes(object@edge.label)$names)) { err <- c(err, "The edge.label slot needs to be a named vector.") attributes(object@edge.label) <- list(names=character(0)) } res <- checkTreeCpp(object, opts=opt) if (hasRetic(object)) { msg <- "Tree is reticulated." if (identical(opt$retic, "fail")) { err <- c(err, msg) } if (identical(opt$retic, "warn")) { wrn <- c(wrn, msg) } } if (hasEdgeLength(object) && any(is.na(edgeLength(object)))) { naElen <- names(which(is.na(object@edge.length))) if (! identical(naElen, edgeId(object, "root"))) err <- c(err, "Only the root can have NA as edge length. ") } if (!object@order %in% phylo4_orderings) { err <- c(err, paste("unknown order: allowed values are", paste(phylo4_orderings,collapse=","))) } err <- ifelse(nzchar(res[[1]]), c(err, res[[1]]), err) wrn <- ifelse(nzchar(res[[2]]), c(wrn, res[[2]]), wrn) if (!is.na(wrn)) { wrn <- paste(wrn, collapse=", ") warning(wrn) } if (!is.na(err)) { err <- paste(err, collapse=", ") return(err) #failures are returned as text } else { return(TRUE) } } ## checkTreeOld <- function(object) { ## ## case of empty phylo4 object ## if(nrow(object@edge) == 0 && length(object@edge.length) == 0 && ## length(object@label) == 0 && length(object@edge.label) == 0) ## return(TRUE) ## ## get options ## opt <- phylobase.options() ## ## Storage of error/warning messages ## err <- wrn <- character(0) ## ## Define variables ## nedges <- nEdges(object) ## ntips <- nTips(object) ## E <- edges(object) ## tips <- unique(sort(E[,2][!E[,2] %in% E[,1]])) ## nodes <- unique(sort(c(E))) ## intnodes <- nodes[!nodes %in% tips] ## nRoots <- length(which(E[,1] == 0)) ## ## Check edge lengths ## if (hasEdgeLength(object)) { ## if (length(object@edge.length) != nedges) ## err <- c(err, "edge lengths do not match number of edges") ## ##if(!is.numeric(object@edge.length)) # not needed ## ## err <- c(err, "edge lengths are not numeric") ## ## presumably we shouldn't allow NAs mixed ## ## with numeric branch lengths except at the root ## if (sum(is.na(object@edge.length)) > (nRoots + 1)) ## err <- c(err, "NAs in edge lengths") ## ## Strip root edge branch length (if set to NA) ## if (any(object@edge.length[!is.na(object@edge.length)] < 0)) ## err <- c(err, "edge lengths must be non-negative") ## ## Check edge length labels ## elen.msg <- "Use edgeLength<- to update them." ## if (is.null(names(object@edge.length))) { ## err <- c(err, paste("Edge lengths must have names matching edge IDs.", ## elen.msg)) ## } ## if (!all(names(object@edge.length) %in% edgeId(object, "all"))) { ## err <- c(err, paste("One or more edge lengths has an unmatched ID name.", ## elen.msg)) ## } ## } ## ## Make sure tips and ## if (!(all(tips==1:ntips) && all(nodes=(ntips+1):(ntips+length(intnodes))))) ## err <- c(err, "tips and nodes incorrectly numbered") ## ##careful - nAncest does not work for counting nRoots in unrooted trees ## nAncest <- tabulate(na.omit(E)[, 2],nbins=max(nodes)) ## bug fix from Jim Regetz ## nDesc <- tabulate(na.omit(E[,1])) ## nTips <- sum(nDesc==0) ## if (!all(nDesc[1:nTips]==0)) ## err <- c(err, "nodes 1 to nTips must all be tips") ## if (nRoots > 0) { ## if (sum(E[, 1] == 0) != 1) { ## err <- c(err, "for a rooted tree, edge matrix must contain (exactly one) explicit root edge with ancestor==0") ## } ## root.node <- unname(E[which(E[,1] == 0), 2]) ## } ## ## Check that nodes are correctly numbered ## if (!all(nDesc[(nTips+1):(nTips+nNodes(object))]>0)) ## err <- c(err, "nodes (nTips+1) to (nTips+nNodes) must all be internal nodes") ## ## how do we identify loops??? ## ## EXPERIMENTAL: could be time-consuming for large trees? ## if (FALSE) { ## Emat <- matrix(0,nrow=max(E),ncol=max(E)) ## Emat[E] <- 1 ## } ## if (!object@order %in% phylo4_orderings) { ## err <- c(err, paste("unknown order: allowed values are", ## paste(phylo4_orderings,collapse=","))) ## } ## ## make sure tip/node labels have internal names that match node IDs ## lab.msg <- "Use tipLabels<- (and nodeLabels<- if needed) to update them." ## if (is.null(names(object@label))) { ## err <- c(err, paste("Tip and node labels must have names matching node IDs.", ## lab.msg)) ## } else { ## if (!all(tips %in% names(na.omit(object@label)))) { ## err <- c(err, paste("All tips must have associated tip labels.", ## lab.msg)) ## } ## if (!all(names(object@label) %in% nodeId(object, "all"))) { ## err <- c(err, paste("One or more tip/node label has an unmatched ID name", ## lab.msg)) ## } ## } ## ## make sure edge labels have internal names that match the edges ## elab.msg <- "Use edgeLabels<- to update them." ## if(hasEdgeLabels(object)) { ## if (is.null(names(object@edge.label))) { ## err <- c(err, paste("Edge labels must have names matching edge IDs.", ## elab.msg)) ## } ## if (!all(names(object@edge.label) %in% edgeId(object, "all"))) { ## err <- c(err, paste("One or more edge labels has an unmatched ID name.", ## elab.msg)) ## } ## } ## ## make sure that tip and node labels are unique ## if (hasDuplicatedLabels(object)) { ## currmsg <- "Labels are not unique" ## if (opt$allow.duplicated.labels == "fail") ## err <- c(err, currmsg) ## if (opt$allow.duplicated.labels == "warn") ## wrn <- c(wrn, currmsg) ## } ## if (any(nDesc>2)) { ## currmsg <- "tree includes polytomies" ## if (opt$poly == "fail") ## err <- c(err, currmsg) ## if (opt$poly == "warn") ## wrn <- c(wrn, currmsg) ## } ## if (nRoots>1) { ## currmsg <- "tree has more than one root" ## if (opt$multiroot == "fail") ## err <- c(err, currmsg) ## if (opt$multiroot == "warn") ## wrn <- c(wrn,currmsg) ## } ## if (any(nDesc==1)) { ## currmsg <- "tree contains singleton nodes" ## if (opt$singleton == "fail") ## err <- c(err, currmsg) ## if (opt$singleton == "warn") ## wrn <- c(wrn, currmsg) ## } ## if (any(nAncest>1)) { ## currmsg <- paste("tree is reticulated [most functions in phylobase haven't", ## "been tested with reticulated trees]") ## if (opt$retic == "fail") ## err <- c(err, currmsg) ## if (opt$retic == "warn") ## wrn <- c(wrn, currmsg) ## } ## if (length(wrn) > 0) { ## wrn <- paste(wrn, collapse=", ") ## warning(wrn) ## } ## if (length(err) > 0) { ## err <- paste(err, collapse=", ") ## return(err) #failures are returned as text ## } ## else { ## return(TRUE) ## } ## } checkPhylo4Data <- function(object) { ## These are just some basic tests to make sure that the user does not ## alter the object in a significant way ## Check rownames if (nrow(object@data) > 0 && !all(row.names(object@data) %in% nodeId(object, "all"))) stop("The row names of tree data do not match the node numbers") return(TRUE) } phylobase/R/print-methods.R0000644000176200001440000001050013075431302015353 0ustar liggesusers ##' print a phylogeny ##' ##' Prints a phylo4 or phylo4d object in data.frame format with user-friendly ##' column names ##' ##' This is a user-friendly version of the tree representation, useful for ##' checking that objects were read in completely and translated correctly. The ##' phylogenetic tree is represented as a list of numbered nodes, linked in a ##' particular way through time (or rates of evolutionary change). The topology ##' is given by the pattern of links from each node to its ancestor. Also given ##' are the taxon names, node type (root/internal/tip) and phenotypic data (if ##' any) associated with the node, and the branch length from the node to its ##' ancestor. A list of nodes (descendants) and ancestors is minimally required ##' for a phylo4 object. ##' ##' @param x a \code{phylo4} tree or \code{phylo4d} tree+data object ##' @param object a \code{phylo4} or \code{phylo4d} object ##' @param edgeOrder in the data frame returned, the option 'pretty' returns the ##' internal nodes followed by the tips, the option 'real' returns the nodes in ##' the order they are stored in the edge matrix. ##' @param printall default prints entire tree. printall=FALSE returns the first ##' 6 rows ##' @param n for head() and tail(), the number of lines to print ##' @param \dots optional additional arguments (not in use) ##' @return A data.frame with a row for each node (descendant), sorted as ##' follows: root first, then other internal nodes, and finally tips.\cr The ##' returned data.frame has the following columns:\cr \item{label}{Label for the ##' taxon at the node (usually species name).} \item{node}{Node number, i.e. the ##' number identifying the node in edge matrix.} \item{ancestor}{Node number ##' of the node's ancestor.} \item{branch.length}{The branch length connecting ##' the node to its ancestor (NAs if missing).} \item{node.type}{"root", ##' "internal", or "tip". (internally generated)} \item{data}{phenotypic data ##' associated with the nodes, with separate columns for each variable.} ##' @note This is the default show() method for phylo4, phylo4d. It prints the ##' user-supplied information for building a phylo4 object. For a full ##' description of the phylo4 S4 object and slots, see \code{\link{phylo4}}. ##' @author Marguerite Butler, Thibaut Jombart \email{jombart@@biomserv.univ-lyon1.fr}, Steve Kembel ##' @include setAs-methods.R ##' @keywords methods ##' @examples ##' ##' ##' tree.phylo <- ape::read.tree(text="((a,b),c);") ##' tree <- as(tree.phylo, "phylo4") ##' ##plot(tree,show.node=TRUE) ## plotting broken with empty node labels: FIXME ##' tip.data <- data.frame(size=c(1,2,3), row.names=c("a", "b", "c")) ##' treedata <- phylo4d(tree, tip.data) ##' plot(treedata) ##' print(treedata) ##' ##' ##' @aliases print ##' @rdname print-methods setGeneric("print") ##' @rdname print-methods ##' @aliases print,phylo4-method ##' @exportMethod print setMethod("print", signature(x="phylo4"), function(x, edgeOrder=c("pretty", "real"), printall=TRUE) { if(!nrow(edges(x))) { msg <- paste("Empty \'", class(x), "\' object\n", sep="") cat(msg) } else { toRet <- .phylo4ToDataFrame(x, edgeOrder) if (printall) { print(toRet) } else { print(head(toRet)) } } }) ##' @rdname print-methods ##' @aliases show ##' @exportMethod show setGeneric("show") ##' @rdname print-methods ##' @aliases show,phylo4-method setMethod("show", signature(object="phylo4"), function(object) { print(object) }) ##' @rdname print-methods ##' @aliases names ##' @exportMethod names ##' @export setGeneric("names") ##' @rdname print-methods ##' @aliases names,phylo4-method setMethod("names", signature(x="phylo4"), function(x) { temp <- rev(names(attributes(x)))[-1] return(rev(temp)) }) ##' @rdname print-methods ##' @aliases head ##' @exportMethod head setGeneric("head") ##' @rdname print-methods ##' @aliases head,phylo4-method setMethod("head", signature(x="phylo4"), function(x, n=20) { head(as(x,"data.frame"),n=n) }) ##' @rdname print-methods ##' @aliases tail ##' @exportMethod tail setGeneric("tail") ##' @rdname print-methods ##' @aliases tail,phylo4-method setMethod("tail", signature(x="phylo4"), function(x, n=20) { tail(as(x, "data.frame"), n=n) }) phylobase/R/RcppExports.R0000644000176200001440000000400413075412132015051 0ustar liggesusers# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 isLabelName <- function(lblToCheck, lbl) { .Call('phylobase_isLabelName', PACKAGE = 'phylobase', lblToCheck, lbl) } nRoots <- function(ances) { .Call('phylobase_nRoots', PACKAGE = 'phylobase', ances) } tabulateTips <- function(ances) { .Call('phylobase_tabulateTips', PACKAGE = 'phylobase', ances) } nTipsSafe <- function(ances) { .Call('phylobase_nTipsSafe', PACKAGE = 'phylobase', ances) } nTipsFastCpp <- function(ances) { .Call('phylobase_nTipsFastCpp', PACKAGE = 'phylobase', ances) } hasSingleton <- function(ances) { .Call('phylobase_hasSingleton', PACKAGE = 'phylobase', ances) } hasPolytomy <- function(ances) { .Call('phylobase_hasPolytomy', PACKAGE = 'phylobase', ances) } tipsSafe <- function(ances, desc) { .Call('phylobase_tipsSafe', PACKAGE = 'phylobase', ances, desc) } tipsFast <- function(ances) { .Call('phylobase_tipsFast', PACKAGE = 'phylobase', ances) } getAllNodesSafe <- function(edge) { .Call('phylobase_getAllNodesSafe', PACKAGE = 'phylobase', edge) } getAllNodesFast <- function(edge) { .Call('phylobase_getAllNodesFast', PACKAGE = 'phylobase', edge) } testEqInt <- function(x, y) { .Call('phylobase_testEqInt', PACKAGE = 'phylobase', x, y) } all_naC <- function(x) { .Call('phylobase_all_naC', PACKAGE = 'phylobase', x) } any_naC <- function(x) { .Call('phylobase_any_naC', PACKAGE = 'phylobase', x) } nb_naC <- function(x) { .Call('phylobase_nb_naC', PACKAGE = 'phylobase', x) } getRange <- function(x, na_rm) { .Call('phylobase_getRange', PACKAGE = 'phylobase', x, na_rm) } hasDuplicatedLabelsCpp <- function(label) { .Call('phylobase_hasDuplicatedLabelsCpp', PACKAGE = 'phylobase', label) } edgeIdCpp <- function(edge, type) { .Call('phylobase_edgeIdCpp', PACKAGE = 'phylobase', edge, type) } checkTreeCpp <- function(obj, opts) { .Call('phylobase_checkTreeCpp', PACKAGE = 'phylobase', obj, opts) } phylobase/R/phylo4d-class.R0000644000176200001440000000235112353104130015243 0ustar liggesusers################################### ## phylo4d class ## extend: phylo with data ##' phylo4d class ##' ##' S4 class for phylogenetic tree and data. ##' ##' ##' @name phylo4d-class ##' @docType class ##' @section Objects from the Class: Objects can be created from various trees ##' and a data.frame using the constructor \code{phylo4d}, or using ##' \code{new("phylo4d", \dots{})} for empty objects. ##' @author Ben Bolker, Thibaut Jombart ##' @seealso \code{\link{coerce-methods}} for translation ##' functions. The \code{\link{phylo4d-methods}} constructor. See also ##' the \code{\link{phylo4-methods}} constructor, the ##' \linkS4class{phylo4} class, and the \code{\link{checkPhylo4}} ##' function to check the validity of \code{phylo4} trees. ##' @keywords classes ##' @export ##' @include phylo4-methods.R formatData.R ##' @examples ##' example(read.tree, "ape") ##' obj <- phylo4d(as(tree.owls.bis,"phylo4"), data.frame(wing=1:3)) ##' obj ##' names(obj) ##' summary(obj) setClass("phylo4d", representation(data="data.frame", metadata = "list"), prototype = list( data = data.frame(NULL), metadata = list()), validity = checkPhylo4, contains = "phylo4") phylobase/R/reorder-methods.R0000644000176200001440000001302412553731204015671 0ustar liggesusers ######################################################### ### Ordering ######################################################### ##' reordering trees within phylobase objects ##' ##' Methods for reordering trees into various traversal orders ##' ##' The \code{reorder} method takes a \code{phylo4} or \code{phylo4d} ##' tree and orders the edge matrix (i.e. \code{edges(x)}) in the ##' requested traversal order. Currently only two orderings are ##' permitted, and both require rooted trees. In \code{postorder}, a ##' node's descendants come before that node, thus the root, which is ##' ancestral to all nodes, comes last. In \code{preorder}, a node is ##' visited before its descendants, thus the root comes first. ##' ##' @name reorder-methods ##' @docType methods ##' @param x a \code{phylo4} or \code{phylo4d} object ##' @param order The desired traversal order; currently only ##' \dQuote{preorder} and \dQuote{postorder} are allowed for ##' \code{phylo4} and \code{phylo4d} objects. ##' @param \dots additional optional elements (not in use) ##' @return A \code{phylo4} or \code{phylo4d} object with the edge, ##' label, length and data slots ordered as \code{order}, which is ##' itself recorded in the order slot. ##' @note The \code{preorder} parameter corresponds to ##' \code{cladewise} in the \code{ape} package, and \code{postorder} ##' corresponds (almost) to \code{pruningwise}. ##' ##' @author Peter Cowan, Jim Regetz ##' @seealso \code{\link[ape]{reorder.phylo}} in the \code{ape} package. ##' \code{\link{ancestors}} \code{\link{ancestor}} \code{\link{siblings}} ##' \code{\link{children}} \code{\link{descendants}} ##' @keywords methods ##' @include phylo4-class.R ##' @include phylo4-methods.R ##' @exportMethod reorder ##' @aliases reorder ##' @examples ##' phy <- phylo4(ape::rtree(5)) ##' edges(reorder(phy, "preorder")) ##' edges(reorder(phy, "postorder")) setGeneric("reorder") ##' @rdname reorder-methods ##' @aliases reorder,phylo4-method setMethod("reorder", signature(x="phylo4"), function(x, order=c("preorder", "postorder")) { ## call orderIndex and use that index to order edges, labels and lengths order <- match.arg(order) index <- orderIndex(x, order) x@order <- order x@edge <- edges(x)[index, ] if(hasEdgeLabels(x)) { x@edge.label <- x@edge.label[index] } if(hasEdgeLength(x)) { x@edge.length <- x@edge.length[index] } x }) ## non exported function orderIndex <- function(x, order=c("preorder", "postorder")) { order <- match.arg(order) if(!isRooted(x)){ stop("Tree must be rooted to reorder") } ## get a root node free edge matrix edge <- edges(x, drop.root=TRUE) ## Sort edges -- ensures that starting order of edge matrix doesn't ## affect the order of reordered trees edge <- edge[order(edge[, 2]), ] # recast order argument as integer to pass to C if(order == 'postorder') { iOrder <- 0L } else if(order == 'preorder') { iOrder <- 1L } else {stop(paste("Method for", order, "not implemented"))} if (!hasPoly(x) & !hasSingle(x)) { # method 1: faster, but only works if all internal nodes have # exactly two children (true binary tree) # extract nodes, separating descendants into left (first # encountered) and right (second encountered) for each ancestor isFirst <- !duplicated(edge[, 1]) ancestor <- as.integer(edge[isFirst, 1]) left <- as.integer(edge[isFirst, 2]) right <- as.integer(edge[!isFirst, 2])[match(ancestor, edge[!isFirst, 1])] descendantNew <- rep(0L, nEdges(x)) root <- as.integer(rootNode(x)) nEdge <- as.integer(length(ancestor)) descendantReord <- .C("reorderBinary", descendantNew, root, ancestor, left, right, nEdge, iOrder)[[1]] } else { # method 2: not as fast, but robust to singletons and polytomies # extract ancestors and descendants ancestor <- as.integer(edge[,1]) descendant <- as.integer(edge[,2]) descendantNew <- rep(0L, nEdges(x)) root <- as.integer(rootNode(x)) nEdge <- as.integer(nrow(edge)) descendantReord <- .C("reorderRobust", descendantNew, root, ancestor, descendant, nEdge, iOrder)[[1]] } ## Original pure R implementation of the above: #### recursive functions are placed first and calls to those functions below ##postOrder <- function(node) { ## ## this function returns a vector of nodes in the post order traversal ## ## get the descendants ## traversal <- NULL ## ## edge -- defined above, outside this function ## ## extensive testing found this loop to be faster than apply() etc. ## for(i in edge[edge[, 1] == node, 2]) { ## traversal <- c(traversal, postOrder(i)) ## } ## c(traversal, node) ##} ##preOrder <- function(node) { ## ## see expanded code in comments of postOrder() ## ## only difference here is that we record current node, then descendants ## traversal <- NULL ## for(i in edge[edge[, 1] == node, 2]) { ## traversal <- c(traversal, preOrder(i)) ## } ## c(node, traversal) ##} ##if(order == 'postorder') { ## descendantReord <- postOrder(rootNode(x)) ##} else if(order == 'preorder') { ## descendantReord <- preOrder(rootNode(x)) ##} else {stop(paste("Method for", order, "not implemented"))} ## match the new node order to the old order to get an index index <- match(descendantReord, edges(x)[, 2]) } phylobase/R/phylo4-methods.R0000644000176200001440000001576112353104154015454 0ustar liggesusers ##' Create a phylogenetic tree ##' ##' \code{phylo4} is a generic constructor that creates a phylogenetic tree ##' object for use in phylobase methods. Phylobase contains functions for input ##' of phylogenetic trees and data, manipulation of these objects including ##' pruning and subsetting, and plotting. The phylobase package also contains ##' translation functions to forms used in other comparative phylogenetic method ##' packages. ##' ##' The minimum information necessary to create a phylobase tree object is a ##' valid edge matrix. The edge matrix describes the topology of the phylogeny. ##' Each row describes a branch of the phylogeny, with the (descendant) node ##' number in column 2 and its ancestor's node number in column 1. These numbers ##' are used internally and must be unique for each node. ##' ##' The labels designate either nodes or edges. The vector \code{node.label} ##' names internal nodes, and together with \code{tip.label}, name all nodes in ##' the tree. The vector \code{edge.label} names all branches in the tree. All ##' label vectors are optional, and if they are not given, internally-generated ##' labels will be assigned. The labels, whether user-specified or internally ##' generated, must be unique as they are used to join species data with ##' phylogenetic trees. ##' ##' \code{phylobase} also allows to create \code{phylo4} objects using ##' the function \code{phylo4()} from objects of the classes: ##' \code{phylo} (from \code{ape}), and \code{nexml} (from \code{RNeXML}). ##' ##' @name phylo4-methods ##' @docType methods ##' @param x a matrix of edges or an object of class \code{phylo} (see above) ##' @param edge A numeric, two-column matrix with as many rows as branches in ##' the phylogeny. ##' @param edge.length Edge (branch) length. (Optional) ##' @param tip.label A character vector of species names (names of "tip" nodes). ##' (Optional) ##' @param node.label A character vector of internal node names. (Optional) ##' @param edge.label A character vector of edge (branch) names. (Optional) ##' @param order character: tree ordering (allowable values are listed in ##' \code{phylo4_orderings}, currently "unknown", "preorder" (="cladewise" in ##' \code{ape}), and "postorder", with "cladewise" and "pruningwise" also ##' allowed for compatibility with \code{ape}) ##' @param check.node.labels if \code{x} is of class \code{phylo}, either "keep" ##' (the default) or "drop" node labels. This argument is useful if the ##' \code{phylo} object has non-unique node labels. ##' @param annote any additional annotation data to be passed to the new object ##' @param \dots optional arguments (none used at present). ##' @note Translation functions are available from many valid tree formats. See ##' \link{coerce-methods}. ##' @author phylobase team ##' @seealso \code{\link{coerce-methods}} for translation ##' functions. The \linkS4class{phylo4} class. See also the ##' \code{\link{phylo4d-methods}} constructor, and ##' \linkS4class{phylo4d} class. ##' @export ##' @aliases phylo4 ##' @rdname phylo4-methods ##' @include internal-constructors.R phylo4-class.R oldclasses-class.R ##' @examples ##' ##' # a three species tree: ##' mytree <- phylo4(x=matrix(data=c(4,1, 4,5, 5,2, 5,3, 0,4), ncol=2, ##' byrow=TRUE), tip.label=c("speciesA", "speciesB", "speciesC")) ##' mytree ##' plot(mytree) ##' ##' # another way to specify the same tree: ##' mytree <- phylo4(x=cbind(c(4, 4, 5, 5, 0), c(1, 5, 2, 3, 4)), ##' tip.label=c("speciesA", "speciesB", "speciesC")) ##' ##' # another way: ##' mytree <- phylo4(x=rbind(c(4, 1), c(4, 5), c(5, 2), c(5, 3), c(0, 4)), ##' tip.label=c("speciesA", "speciesB", "speciesC")) ##' ##' # with branch lengths: ##' mytree <- phylo4(x=rbind(c(4, 1), c(4, 5), c(5, 2), c(5, 3), c(0, 4)), ##' tip.label=c("speciesA", "speciesB", "speciesC"), edge.length=c(1, .2, ##' .8, .8, NA)) ##' plot(mytree) ##' setGeneric("phylo4", function(x, ...) { standardGeneric("phylo4")} ) ## ape orderings should be allowed for so we can import trees from ape ## e.g. during subsetting ##' @rdname phylo4-methods ##' @aliases phylo4_orderings phylo4_orderings <- c("unknown", "preorder", "postorder", "pruningwise", "cladewise") ##' @rdname phylo4-methods ##' @aliases phylo4,matrix-method setMethod("phylo4", "matrix", function(x, edge.length = NULL, tip.label = NULL, node.label = NULL, edge.label = NULL, order="unknown", annote = list()) { ## edge edge <- x mode(edge) <- "integer" if(ncol(edge) > 2) warning("The edge matrix has more than two columns, ", "only the first two columns are considered.") edge <- as.matrix(edge[, 1:2]) colnames(edge) <- c("ancestor", "descendant") ## create new phylo4 object and insert edge matrix res <- new("phylo4") res@edge <- edge ## get number of tips and number of nodes ## (these accessors work fine now that edge matrix exists) ntips <- nTips(res) nnodes <- nNodes(res) ## edge.length (drop elements if all are NA but keep the vector named) edge.length <- .createEdge(value=edge.length, edgeMat=edge, type="lengths", use.names=FALSE) if (all(is.na(edge.length))) { edge.length <- numeric() attributes(edge.length) <- list(names=character(0)) } ## edge.label (drop NA elements) edge.label <- .createEdge(value=edge.label, edgeMat=edge, type="labels", use.names=FALSE) edge.label <- edge.label[!is.na(edge.label)] ## tip.label (leave NA elements; let checkTree complain about it) tip.label <- .createLabels(value=tip.label, ntips=ntips, nnodes=nnodes, type="tip") ## node.label (drop NA elements) node.label <- .createLabels(node.label, ntips=ntips, nnodes=nnodes, type="internal") node.label <- node.label[!is.na(node.label)] ## populate the slots res@edge.length <- edge.length res@label <- c(tip.label, node.label) res@edge.label <- edge.label res@order <- order res@annote <- annote ## checkPhylo4 will return a character string if object is ## bad, otherwise TRUE if (is.character(checkval <- checkPhylo4(res))) stop(checkval) return(res) }) ##' @rdname phylo4-methods ##' @aliases phylo4,phylo-method setMethod("phylo4", c("phylo"), function(x, check.node.labels=c("keep", "drop"), annote=list()){ check.node.labels <- match.arg(check.node.labels) if (check.node.labels == "drop") x$node.label <- NULL res <- as(x, "phylo4") #TODO?: make default annote arg NULL, and only assign if !is.null; # then update phylo4d methods accordingly (same thing with metadata?) res@annote <- annote return(res) }) ##' @rdname phylo4-methods ##' @aliases nexml,phylo4-method setMethod("phylo4", c("nexml"), function(x) { tr <- RNeXML::get_trees_list(x) if (is.null(tr)) { new("phylo4") } else { if (length(tr) > 1) { warning("Only the first tree has been imported.") } phylo4(x=tr[[1]][[1]]) } }) phylobase/R/multiphylo4-class.R0000644000176200001440000000325512347155416016176 0ustar liggesusers## classes for holding multiple tree objects ##' multiPhylo4 and extended classes ##' ##' Classes for lists of phylogenetic trees. These classes and methods are ##' planned for a future version of \code{phylobase}. ##' ##' ##' @name multiPhylo-class ##' @aliases multiPhylo-class multiPhylo4-class multiPhylo4d-class tbind ##' @docType class ##' @keywords classes ## @export setClass("multiPhylo4", representation(phylolist = "list", tree.names = "character"), prototype = list(phylolist = list(), tree.names = character(0))) setClass("multiPhylo4d", representation(tip.data = "data.frame"), contains = "multiPhylo4") setMethod("initialize", "multiPhylo4", function(.Object, ...) { message("multiPhylo and multiphylo4d not yet implemented", "Try using a list of phylo4(d) objects and lapply().") }) ##' multiPhylo4 and extended classes ##' ##' Classes for lists of phylogenetic trees. These classes and methods are ##' planned for a future version of \code{phylobase}. ##' ##' ##' @name multiPhylo-class ##' @aliases multiPhylo-class multiPhylo4-class multiPhylo4d-class tbind ##' @docType class ##' @keywords classes setAs("multiPhylo", "multiPhylo4", function(from, to) { trNm <- names(from) if(is.null(trNm)) trNm <- character(0) newobj <- new("multiPhylo4", phylolist = lapply(from, function(x) as(x, "phylo4")), tree.names = trNm) newobj }) setAs("multiPhylo4", "multiPhylo", function(from, to) { y <- lapply(from@phylolist, function(x) as(x, "phylo")) names(y) <- from@tree.names if (hasTipData(from)) warning("discarded tip data") class(y) <- "multiPhylo" y }) phylobase/R/setAs-methods.R0000644000176200001440000002445513075414342015321 0ustar liggesusers ##' Converting between phylo4/phylo4d and other phylogenetic tree ##' formats ##' ##' Translation functions to convert between phylobase objects ##' (\code{phylo4} or \code{phylo4d}), and objects used by other ##' comparative methods packages in R: \code{ape} objects ##' (\code{phylo}, \code{multiPhylo}), \code{RNeXML} object ##' (\code{nexml}), \code{ade4} objects (\code{phylog}, \emph{now ##' deprecated}), and to \code{data.frame} representation. ##' ##' @name setAs ##' @docType methods ##' @section Usage: \code{as(object, class)} ##' @author Ben Bolker, Thibaut Jombart, Marguerite Butler, Steve ##' Kembel, Francois Michonneau ##' @seealso generic \code{\link[methods]{as}}, ##' \code{\link{phylo4-methods}}, \code{\link{phylo4d-methods}}, ##' \code{\link{extractTree}}, \code{nexml} class from the ##' \code{RNeXML} package, \code{\link[ade4]{phylog}} from the ##' \code{ade4} package and \code{\link[ape]{as.phylo}} from the ##' \code{ape} package. ##' @keywords methods ##' @rdname setAs-methods ##' @aliases as as-method as,phylo,phylo4-method ##' @include phylo4-methods.R ##' @include phylo4d-methods.R ##' @include oldclasses-class.R ##' @examples ##' tree_string <- "(((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3):6.3,Tyto_alba:13.5);" ##' tree.owls <- ape::read.tree(text=tree_string) ##' ## round trip conversion ##' tree_in_phylo <- tree.owls # tree is a phylo object ##' (tree_in_phylo4 <- as(tree.owls,"phylo4")) # phylo converted to phylo4 ##' identical(tree_in_phylo,as(tree_in_phylo4,"phylo")) ##' ## test if phylo, and phylo4 converted to phylo are identical ##' ## (no, because of dimnames) ##' ##' ## Conversion to phylog (ade4) ##' as(tree_in_phylo4, "phylog") ##' ##' ## Conversion to data.frame ##' as(tree_in_phylo4, "data.frame") ##' ##' ## Conversion to phylo (ape) ##' as(tree_in_phylo4, "phylo") ##' ##' ## Conversion to phylo4d, (data slots empty) ##' as(tree_in_phylo4, "phylo4d") setAs("phylo", "phylo4", function(from, to) { ## fixme SWK kludgy fix may not work well with unrooted trees ## TODO should we also attempt to get order information? ## BMB horrible kludge to avoid requiring ape explicitly ape_is.rooted <- function(phy) { if (!is.null(phy$root.edge)) TRUE else if (tabulate(phy$edge[, 1])[length(phy$tip.label) + 1] > 2) FALSE else TRUE } if (ape_is.rooted(from)) { tip.idx <- 1:nTips(from) if (nTips(from) < nrow(from$edge)) { int.idx <- (nTips(from)+1):dim(from$edge)[1] } else { int.idx <- NULL } root.node <- as.numeric(setdiff(unique(from$edge[,1]), unique(from$edge[,2]))) from$edge <- rbind(from$edge[tip.idx,],c(0,root.node), from$edge[int.idx,]) if (!is.null(from$edge.length)) { if (is.null(from$root.edge)) { from$edge.length <- c(from$edge.length[tip.idx], as.numeric(NA),from$edge.length[int.idx]) } else { from$edge.length <- c(from$edge.length[tip.idx], from$root.edge,from$edge.length[int.idx]) } } if (!is.null(from$edge.label)) { from$edge.label <- c(from$edge.label[tip.idx], NA, from$edge.label[int.idx]) } } newobj <- phylo4(from$edge, from$edge.length, unname(from$tip.label), node.label = from$node.label, edge.label = from$edge.label, order = "unknown") oldorder <- attr(from,"order") neworder <- if (is.null(oldorder)) { "unknown" } else if (!oldorder %in% phylo4_orderings) { stop("unknown ordering '", oldorder, "' in ape object") } else if (oldorder == "cladewise" || oldorder == "preorder") { "preorder" } else if (oldorder == "pruningwise" || oldorder == "postorder") { "postorder" } if (isRooted(newobj)) { if (neworder == "preorder") { newobj <- reorder(newobj, order="preorder") } if (neworder == "postorder") { newobj <- reorder(newobj, order="postorder") } } newobj@order <- neworder attr(from,"order") <- NULL attribs <- attributes(from) attribs$names <- NULL knownattr <- c("logLik", "origin", "para", "xi") known <- names(attribs)[names(attribs) %in% knownattr] unknown <- names(attribs)[!names(attribs) %in% c(knownattr, "class", "names")] if (length(unknown) > 0) { warning(paste("unknown attributes ignored: ", unknown, collapse = " ")) } for (i in known) attr(newobj, i) <- attr(from, i) newobj }) ##' @name setAs ##' @rdname setAs-methods ##' @aliases as,phylo,phylo4d-method setAs("phylo", "phylo4d", function(from, to) { phylo4d(as(from, "phylo4"), tip.data = data.frame()) }) ##' @name setAs ##' @rdname setAs-methods ##' @aliases as,nexml,phylo4-method setAs("nexml", "phylo4", function(from, to) { phylo4(from) }) ##' @name setAs ##' @rdname setAs-methods ##' @aliases as,nexml,phylo4d-method setAs("nexml", "phylo4d", function(from, to) { phylo4d(from) }) ####################################################### ## Exporting to ape ## BMB: adding an explicit as method, and the warning, ## here is a very bad idea, because ## even implicit conversions from phylo4d to phylo4 (e.g. ## to use inherited methods) will produce the warning ## setAs("phylo4d", "phylo4",function(from,to) { ## warning("losing data while coercing phylo4d to phylo") ## phylo4(from@edge, from@edge.length, from@tip.label, ## from@node.label,from@edge.label,from@order) ## }) ##' @name setAs ##' @rdname setAs-methods ##' @aliases as,phylo4,phylo-method setAs("phylo4", "phylo", function(from, to) { if(is.character(checkval <- checkPhylo4(from))) { stop(checkval) } if (inherits(from, "phylo4d")) warning("losing data while coercing phylo4d to phylo") phy <- list() ## Edge matrix (dropping root edge if it exists) edgemat <- unname(edges(from, drop.root=TRUE)) storage.mode(edgemat) <- "integer" phy$edge <- edgemat ## Edge lengths if(hasEdgeLength(from)) { edge.length <- edgeLength(from) if(isRooted(from)) { iRoot <- match(edgeId(from, "root"), names(edge.length)) phy$edge.length <- unname(edge.length[-iRoot]) } else { phy$edge.length <- unname(edge.length) } } ## Tip labels phy$tip.label <- unname(tipLabels(from)) ## nNodes phy$Nnode <- as.integer(nNodes(from)) ## Node labels if(hasNodeLabels(from)) { phy$node.label <- unname(nodeLabels(from)) } ## Root edge if(isRooted(from) && hasEdgeLength(from)) { root.edge <- unname(edgeLength(from,rootNode(from))) if(!is.na(root.edge)) { phy$root.edge <- root.edge } } ## Converting to class phylo class(phy) <- "phylo" ## Tree order ## TODO postorder != pruningwise -- though quite similar if (edgeOrder(from) == "unknown") { warning("trees with unknown order may be", " unsafe in ape") } else { attr(phy, "order") <- switch(edgeOrder(from), postorder = "unknown", preorder = "cladewise", pruningwise = "pruningwise") } phy }) ## BMB: redundant???? ## JR: updated (but untested) to reflect slot changes, in case this ever ## needs to come out of its commented hibernation ## setAs("phylo4d", "phylo", function(from, to) { ## y <- list(edge = edges(from, drop.root=TRUE), ## Nnode = nNodes(from), tip.label = tipLabels(from)) ## class(y) <- "phylo" ## if (hasEdgeLength(from)) ## y$edge.length <- edgeLength(from) ## if (hasNodeLabels(from)) ## y$node.label <- nodeLabels(from) ## #if (!is.na(from@root.edge)) ## # y$root.edge <- from@root.edge ## warning("losing data while coercing phylo4d to phylo") ## y ##}) ####################################################### ## Exporting to ade4 ##' @name setAs ##' @rdname setAs-methods ##' @aliases setAs,phylo4,phylog-method setAs("phylo4", "phylog", function(from, to) { x <- as(from, "phylo") xstring <- write.tree(x, file = "") warning("ade4::phylog objects are deprecated, please use the adephylo package instead") ade4::newick2phylog(xstring) }) ####################################################### ## Exporting to dataframe .phylo4ToDataFrame <- function(from, edgeOrder=c("pretty", "real")) { edgeOrder <- match.arg(edgeOrder) ## Check the phylo4 if (is.character(checkval <- checkPhylo4(from))) stop(checkval) ## The order of 'node' defines the order of all other elements if (edgeOrder == "pretty") { node <- nodeId(from, "all") ancestr <- ancestor(from, node) # ancestor returns an NA, replace this w/ 0 to construct names correctly ancestr[is.na(ancestr)] <- as.integer(0) } else { E <- edges(from) node <- E[, 2] ancestr <- E[, 1] } ## extract and reorder (as needed) other object slots nmE <- paste(ancestr, node, sep="-") edge.length <- edgeLength(from) edge.length <- edge.length[match(nmE, names(edge.length))] ndType <- nodeType(from) ndType <- ndType[match(node, names(ndType))] label <- labels(from, type="all") label <- label[match(node, names(label))] tDf <- data.frame(label, node, ancestor=ancestr, edge.length, node.type=ndType, row.names=node) tDf$label <- as.character(tDf$label) if (class(from) == "phylo4d") { dat <- tdata(from, "all", label.type="column") # get data ## reorder data to edge matrix order, drop labels (first column) if(nrow(dat) > 0 && ncol(dat) > 1) { dat <- dat[match(rownames(tDf), rownames(dat)), ] tDf <- cbind(tDf, dat[ ,-1 , drop=FALSE]) } else { cat("No data associated with the tree\n") } } tDf } ##' @name setAs ##' @rdname setAs-methods ##' @aliases setAs,phylo4,data.frame-method setAs(from = "phylo4", to = "data.frame", def=function(from) { d <- .phylo4ToDataFrame(from, edgeOrder="pretty") d }) phylobase/R/addData-methods.R0000644000176200001440000000744612554024214015561 0ustar liggesusers ##' Adding data to a phylo4 or a phylo4d object ##' ##' \code{addData} adds data to a \code{phylo4} (converting it in a ##' \code{phylo4d} object) or to a \code{phylo4d} object ##' ##' Rules for matching data to tree nodes are identical to those used ##' by the \code{\link{phylo4d-methods}} constructor. ##' ##' If any column names in the original data are the same as columns ##' in the new data, ".old" is appended to the former column names and ##' ".new" is appended to the new column names. ##' ##' The option \code{pos} is ignored (silently) if \code{x} is a ##' \code{phylo4} object. It is provided for compatibility reasons. ##' ##' @param x a phylo4 or a phylo4d object ##' @param tip.data a data frame (or object to be coerced to one) ##' containing only tip data ##' @param node.data a data frame (or object to be coerced to one) ##' containing only node data ##' @param all.data a data frame (or object to be coerced to one) ##' containing both tip and node data ##' @param merge.data if both \code{tip.data} and \code{node.data} are ##' provided, it determines whether columns with common names will be ##' merged together (default TRUE). If FALSE, columns with common ##' names will be preserved separately, with ".tip" and ".node" ##' appended to the names. This argument has no effect if ##' \code{tip.data} and \code{node.data} have no column names in ##' common. ##' @param pos should the new data provided be bound \code{before} or ##' \code{after} the pre-existing data? ##' @param \dots additional arguments to control how matching between ##' data and tree (see Details section of ##' \code{\link{phylo4d-methods}} for more details). ##' @return \code{addData} returns a \code{phylo4d} object. ##' @author Francois Michonneau ##' @seealso \code{\link{tdata}} for extracting or updating data and ##' \code{\link{phylo4d-methods}} constructor. ##' @keywords methods ##' @rdname addData-methods ##' @include phylo4d-class.R ##' @export ##' @examples ##' data(geospiza) ##' nDt <- data.frame(a=rnorm(nNodes(geospiza)), b=1:nNodes(geospiza), ##' row.names=nodeId(geospiza, "internal")) ##' t1 <- addData(geospiza, node.data=nDt) setGeneric("addData", function(x, ...) { standardGeneric("addData") }) ##' @rdname addData-methods ##' @aliases addData-methods addData,phylo4-method setMethod("addData", signature(x="phylo4d"), function(x, tip.data=NULL, node.data=NULL, all.data=NULL, merge.data=TRUE, pos=c("after", "before"), ...) { pos <- match.arg(pos) ## apply formatData to ensure data have node number rownames and ## correct dimensions tip.data <- formatData(phy=x, dt=tip.data, type="tip", ...) node.data <- formatData(phy=x, dt=node.data, type="internal", ...) all.data <- formatData(phy=x, dt=all.data, type="all", ...) ## combine data as needed new.data <- .phylo4Data(x=x, tip.data=tip.data, node.data=node.data, all.data=all.data, merge.data=merge.data) if (all(dim(new.data) == 0)) { return(x) } if (all(dim(x@data) == 0)) { x@data <- new.data return(x) } if (identical(pos, "after")) { new.data <- merge(x@data, new.data, by=0, all=TRUE, sort=FALSE, suffixes=c(".old", ".new")) } else { new.data <- merge(new.data, x@data, by=0, all=TRUE, sort=FALSE, suffixes=c(".new", ".old")) } row.names(new.data) <- new.data[["Row.names"]] x@data <- new.data[, -match("Row.names", names(new.data)), drop = FALSE] x }) ##' @rdname addData-methods ##' @aliases addData,phylo4d-method setMethod("addData", signature(x="phylo4"), function(x, tip.data=NULL, node.data=NULL, all.data=NULL, merge.data=TRUE, pos=c("after", "before"), ...) { phylo4d(x, tip.data=tip.data, node.data=node.data, all.data=all.data, merge.data=merge.data, ...) }) phylobase/R/MRCA-methods.R0000644000176200001440000000433612347155416014765 0ustar liggesusers ##' Most Recent Common Ancestor (MRCA) of 2 or more nodes. ##' ##' Given some nodes (i.e., tips and/or internal), this function ##' returns the node corresponding to the most recent common ancestor. ##' ##' If \code{phy} is a \code{phylo4} or \code{phylo4d} object, the ##' nodes can contain both numeric or character values that will be ##' used by \code{getNode} to retrieve the correct node. However, if ##' \code{phy} is a \code{phylo} object, the nodes must be a numeric ##' vector. ##' ##' With \code{phylo4} and \code{phylo4d} objects, if a single node is ##' provided, it will be returned. ##' ##' @title MRCA ##' @param phy a phylogenetic tree in phylo4, phylo4d or phylo format. ##' @param ... a vector of nodes ##' @return the node corresponding to the most recent common ancestor ##' @export ##' @include phylo4d-methods.R getNode-methods.R ##' @include oldclasses-class.R ##' @rdname MRCA ##' @examples ##' data(geospiza) ##' MRCA(geospiza, 1, 5) ##' MRCA(geospiza, "fortis", 11) ##' MRCA(geospiza, 2, 4, "fusca", 3) ##' geo <- as(geospiza, "phylo") ##' MRCA(geo, c(1,5)) setGeneric("MRCA", function(phy, ...) { standardGeneric("MRCA") }) ##' @rdname MRCA ##' @aliases MRCA,phylo4-method setMethod("MRCA", signature(phy = "phylo4"), function(phy, ...) { nodes <- list(...) ## if length==1 and first element is a vector, ## use it as the list if (length(nodes)==1 && length(nodes[[1]])>1) { nodes <- as.list(nodes[[1]]) } lNodes <- sapply(nodes, function(nd) { getNode(x=phy, node=nd, missing="fail") }) ## Correct behavior when the root is part of the nodes uniqueNodes <- unique(lNodes) root <- nodeId(phy, "root") if(root %in% uniqueNodes) { res <- getNode(phy, root) return(res) } ## Correct behavior in case of MRCA of identical taxa if(length(uniqueNodes) == 1) { res <- uniqueNodes[[1]] return(res) } else { ancests <- lapply(nodes, ancestors, phy=phy, type="ALL") res <- getNode(phy, max(Reduce(intersect, ancests))) return(res) } }) ##' @rdname MRCA ##' @aliases MRCA,phylo-method setMethod("MRCA", signature(phy = "phylo"), function(phy, ...) { ape::getMRCA(phy, ...) }) phylobase/R/ancestors.R0000644000176200001440000001745213075420241014574 0ustar liggesusers ##' Tree traversal and utility functions ##' ##' Functions for describing relationships among phylogenetic nodes (i.e. ##' internal nodes or tips). ##' ##' \code{ancestors} and \code{descendants} can take \code{node} vectors of ##' arbitrary length, returning a list of output vectors if the number of valid ##' input nodes is greater than one. List element names are taken directly from ##' the input node vector. ##' ##' If any supplied nodes are not found in the tree, the behavior currently ##' varies across functions. ##' \itemize{ ##' \item Invalid nodes are automatically omitted by \code{ancestors} ##' and \code{descendants}, with a warning. ##' ##' \item \code{ancestor} ##' will return \code{NA} for any invalid nodes, with a warning. ##' ##' \item Both \code{children} and \code{siblings} will return an empty ##' vector, again with a warning. ##' } ##' @param phy a \linkS4class{phylo4} object (or one inheriting from ##' \linkS4class{phylo4}, e.g. a \linkS4class{phylo4d} object) ##' @param node either an integer corresponding to a node ID number, or a ##' character corresponding to a node label; for \code{ancestors} and ##' \code{descendants}, this may be a vector of multiple node numbers or names ##' @param type (\code{ancestors}) specify whether to return just direct ##' ancestor ("parent"), all ancestor nodes ("all"), or all ancestor nodes ##' including self ("ALL"); (\code{descendants}) specify whether to return just ##' direct descendants ("children"), all extant descendants ("tips"), or all ##' descendant nodes ("all") or all descendant nodes including self ("ALL"). ##' @param include.self whether to include self in list of siblings ##' @param \dots a list of node numbers or names, or a vector of node numbers or ##' names ##' @return \describe{ ##' \item{\code{ancestors}}{ return a named vector (or a list ##' of such vectors in the case of multiple input nodes) of the ##' ancestors and descendants of a node} ##' ##' \item{\code{descendants}}{ return a named vector (or a list of ##' such vectors in the case of multiple input nodes) of the ancestors ##' and descendants of a node} ##' ##' \item{\code{ancestor}}{ \code{ancestor} is analogous to ##' \code{ancestors(\dots{}, type="parent")} (i.e. direct ancestor ##' only), but returns a single concatenated vector in the case of ##' multiple input nodes} ##' ##' \item{\code{children}}{is analogous to \code{descendants(\dots{}, ##' type="children")} (i.e. direct descendants only), but is not ##' currently intended to be used with multiple input nodes } ##' ##' \item{\code{siblings}}{ returns sibling nodes (children of the same ##' parent)} ##' } ##' @seealso \code{\link[ape]{mrca}}, in the ape package, gives a list of all ##' subtrees ##' @export ##' @rdname ancestors ##' @include phylo4-class.R ##' @include phylo4-methods.R ##' @include getNode-methods.R ##' @examples ##' ##' data(geospiza) ##' nodeLabels(geospiza) <- LETTERS[1:nNodes(geospiza)] ##' plot(as(geospiza, "phylo4"), show.node.label=TRUE) ##' ancestor(geospiza, "E") ##' children(geospiza, "C") ##' descendants(geospiza, "D", type="tips") ##' descendants(geospiza, "D", type="all") ##' ancestors(geospiza, "D") ##' MRCA(geospiza, "conirostris", "difficilis", "fuliginosa") ##' MRCA(geospiza, "olivacea", "conirostris") ##' ##' ## shortest path between 2 nodes ##' shortestPath(geospiza, "fortis", "fuliginosa") ##' shortestPath(geospiza, "F", "L") ##' ##' ## branch length from a tip to the root ##' sumEdgeLength(geospiza, ancestors(geospiza, "fortis", type="ALL")) ancestor <- function(phy,node) { node2 <- getNode(phy,node) ## r <- which(edges(phy)[,2]==node) r <- match(node2,edges(phy)[,2]) return(getNode(phy,edges(phy)[r,1],missing="OK")) } ##' @rdname ancestors ##' @aliases children ##' @export children <- function(phy,node) { node2 <- getNode(phy,node) r <- which(edges(phy)[,1]==node2) getNode(phy,edges(phy)[r,2]) } ##' @rdname ancestors ##' @aliases descendants ##' @export descendants <- function (phy, node, type=c("tips","children","all", "ALL")) { type <- match.arg(type) ## look up nodes, warning about and excluding invalid nodes oNode <- node node <- getNode(phy, node, missing="warn") isValid <- !is.na(node) node <- as.integer(node[isValid]) if (type == "children") { res <- lapply(node, function(x) children(phy, x)) names(res) <- node } else { ## edge matrix must be in preorder for the C function! if (phy@order=="preorder") { edge <- phy@edge } else { edge <- reorder(phy, order="preorder")@edge } ## extract edge columns ancestor <- as.integer(edge[, 1]) descendant <- as.integer(edge[, 2]) ## return indicator matrix of ALL descendants (including self) isDes <- .Call("descendants_c", node, ancestor, descendant) storage.mode(isDes) <- "logical" if (type == "all") { i <- match(intersect(node, nodeId(phy, "internal")), descendant) isDes[i, seq_along(node)] <- FALSE } ## if only tips desired, drop internal nodes if (type=="tips") { isDes[descendant %in% nodeId(phy, "internal"),] <- FALSE } res <- lapply(seq_along(node), function(n) { getNode(phy, descendant[isDes[,n]]) }) names(res) <- node } ## if just a single node, return as a single vector if (length(res)==1) res <- res[[1]] res ## Original pure R implementation of the above ## (note that it does not require preorder ordering) ##n <- nTips(phy) ##if (node <= n) { ## return(node) ##} ##l <- numeric() ##d <- children(phy, node) ##for (j in d) { ## if (j <= n) ## l <- c(l,j) ## else if (type=="all") l <- c(l,j, ## descendants(phy,j,type="all")) ## else l <- c(l, descendants(phy,j,type=type)) ##} } ##' @rdname ancestors ##' @aliases siblings ##' @export siblings <- function(phy, node, include.self=FALSE) { v <- children(phy,ancestor(phy,node)) if (!include.self) v <- v[v!=getNode(phy,node)] v } ##' @rdname ancestors ##' @aliases siblings ##' @export ancestors <- function (phy, node, type=c("all","parent","ALL")) { type <- match.arg(type) ## look up nodes, warning about and excluding invalid nodes oNode <- node node <- getNode(phy, node, missing="warn") isValid <- !is.na(node) node <- as.integer(node[isValid]) if (length(node) == 0) { return(NA) } if (type == "parent") { res <- lapply(node, function(x) ancestor(phy, x)) } else { ## edge matrix must be in postorder for the C function! if (phy@order=="postorder") { edge <- phy@edge } else { edge <- reorder(phy, order="postorder")@edge } ## extract edge columns ancestor <- as.integer(edge[, 1]) descendant <- as.integer(edge[, 2]) ## return indicator matrix of ALL ancestors (including self) isAnc <- .Call("ancestors_c", node, ancestor, descendant) storage.mode(isAnc) <- "logical" ## drop self if needed if (type=="all") { isAnc[cbind(match(node, descendant), seq_along(node))] <- FALSE } res <- lapply(seq_along(node), function(n) getNode(phy, descendant[isAnc[,n]])) } names(res) <- as.character(oNode[isValid]) ## if just a single node, return as a single vector if (length(res)==1) res <- res[[1]] res ## Original pure R implementation of the above ## (note that it does not require preorder ordering) ##if (node == rootNode(phy)) ## return(NULL) ##repeat { ## anc <- ancestor(phy, node) ## res <- c(res, anc) ## node <- anc ## if (anc == n + 1) ## break ##} } phylobase/R/phylo4-accessors.R0000644000176200001440000001111012347155416015770 0ustar liggesusers ##' Number of tips, nodes and edges found in a tree. ##' ##' Function to return the number of tips, nodes and edges found in a ##' tree in the \code{phylo4} or \code{phylo4d} format. ##' @title nTips, nNodes, nEdges ##' @aliases nTips ##' @param x a \code{phylo4} or \code{phylo4d} object ##' @return a numeric vector indicating the number of tips, nodes or ##' edge respectively. ##' @docType methods ##' @export ##' @include phylo4-class.R phylo4-methods.R ##' @include oldclasses-class.R ##' @rdname nTips-methods setGeneric("nTips", function(x) { standardGeneric("nTips") }) ##' @rdname nTips-methods ##' @aliases nTips,phylo4-method setMethod("nTips", signature(x="phylo4"), function(x) { E <- edges(x) if(nrow(E) == 0) return(0) else { ## at this time NAs are not allowed in edge matrix ## sum(tabulate(E[, 1]) == 0) nTipsFastCpp(E[, 1]) } }) ##' @rdname nTips-methods ##' @aliases nTips,phylo-method setMethod("nTips", signature(x="phylo"), function(x) { Ntip(x) }) ##' @rdname nTips-methods ##' @aliases nNodes ##' @export setGeneric("nNodes", function(x) { standardGeneric("nNodes") }) ##' @rdname nTips-methods ##' @aliases nNodes,phylo4-method setMethod("nNodes", signature(x="phylo4"), function(x) { E <- edges(x, drop.root=TRUE) if(nrow(E) == 0) { return(0) } else { return(length(unique(E[, 1]))) } }) ##' @rdname nTips-methods ##' @aliases nEdges ##' @export setGeneric("nEdges", function(x) { standardGeneric("nEdges") }) ##' @rdname nTips-methods ##' @aliases nEdges,phylo4-method setMethod("nEdges", signature(x="phylo4"), function(x) { nrow(x@edge) }) ######################################################### ### Edge accessors ######################################################### ##' Edges accessors ##' ##' Access or modify information about the edges. ##' ##' @param x a \code{phylo4} or \code{phylo4d} object. ##' @param drop.root logical (default FALSE), should the edge ##' connecting the root be included in the edge matrix? ##' @param \dots Optional arguments used by specific methods. (None ##' used at present). ##' @return \describe{ ##' \item{\code{edges}}{returns the edge matrix that represent the ##' ancestor-descendant relationships among the nodes of the tree.} ##' ##' \item{\code{edgeOrder}}{returns the order in which the edge matrix ##' is in.} ##' ##' \item{\code{internalEdges}}{returns a logical vector indicating ##' internal edges (edges that connect an internal node to ##' another). This vector is named with the \code{edgeId}}. ##' ##' \item{\code{terminalEdges}}{returns a logical vector indicating ##' terminal edges (edges that connect an internal node to a ##' tip). This vector is named with the \code{edgeId} }} ##' @author Ben Bolker, Francois Michonneau, Thibaut Jombart ##' @seealso reorder, edgeId ##' @examples ##' data(geospiza) ##' edges(geospiza) ##' edgeOrder(geospiza) ##' geoPost <- reorder(geospiza, "postorder") ##' edgeOrder(geoPost) ##' ## with a binary tree this should always be true ##' identical(!terminalEdges(geospiza), internalEdges(geospiza)) ##' @export ##' @docType methods ##' @rdname edges-accessors ##' @include phylo4-methods.R setGeneric("edges", function(x, ...) { standardGeneric("edges") }) ##' @rdname edges-accessors ##' @aliases edges,phylo4-method setMethod("edges", signature(x="phylo4"), function(x, drop.root=FALSE) { e <- x@edge if (drop.root) e <- e[e[, 1] != 0, ] e }) ##### -------- edgeOrder ##' @rdname edges-accessors ##' @aliases edgeOrder ##' @export setGeneric("edgeOrder", function(x, ...) { standardGeneric("edgeOrder") }) ##' @rdname edges-accessors ##' @aliases edgeOrder,phylo4-method setMethod("edgeOrder", signature(x="phylo4"), function(x) { x@order }) ##### -------- internalEdges ##' @rdname edges-accessors ##' @aliases internalEdges ##' @export setGeneric("internalEdges", function(x) { standardGeneric("internalEdges") }) ##' @rdname edges-accessors ##' @aliases internalEdges,phylo4-method setMethod("internalEdges", signature(x="phylo4"), function(x) { res <- edges(x)[, 2] %in% nodeId(x, "internal") names(res) <- edgeId(x, "all") res }) ##### -------- terminalEdges ##' @rdname edges-accessors ##' @aliases terminalEdges ##' @export setGeneric("terminalEdges", function(x) { standardGeneric("terminalEdges") }) ##' @rdname edges-accessors ##' @aliases terminalEdges,phylo4-method setMethod("terminalEdges", signature(x="phylo4"), function(x) { res <- edges(x)[, 2] %in% nodeId(x, "tip") names(res) <- edgeId(x, "all") res }) phylobase/R/formatData.R0000644000176200001440000002145412554174436014667 0ustar liggesusers##' Format data for use in phylo4d objects ##' ##' Associates data with tree nodes and applies consistent formatting ##' rules. ##' ##' ##' \code{formatData} is an internal function that should not be ##' called directly by the user. It is used to format data provided by ##' the user before associating it with a tree, and is called ##' internally by the \code{phylo4d}, \code{tdata}, and \code{addData} ##' methods. However, users may pass additional arguments to these ##' methods in order to control how the data are matched to nodes. ##' ##' Rules for matching rows of data to tree nodes are determined ##' jointly by the \code{match.data} and \code{rownamesAsLabels} ##' arguments. If \code{match.data} is TRUE, data frame rows will be ##' matched exclusively against tip and node labels if ##' \code{rownamesAsLabels} is also TRUE, whereas any all-digit row ##' names will be matched against tip and node numbers if ##' \code{rownamesAsLabels} is FALSE (the default). If ##' \code{match.data} is FALSE, \code{rownamesAsLabels} has no effect, ##' and row matching is purely positional with respect to the order ##' returned by \code{nodeId(phy, type)}. ##' ##' \code{formatData} (1) converts labels provided in the data into ##' node numbers, (2) makes sure that the data are appropriately ##' matched against tip and/or internal nodes, (3) checks for ##' differences between data and tree, (4) creates a data frame with ##' the correct dimensions given a tree. ##' ##' @param phy a valid \code{phylo4} object ##' @param dt a data frame, matrix, vector, or factor ##' @param type type of data to attach ##' @param match.data (logical) should the rownames of the data frame ##' be used to be matched against tip and internal node identifiers? ##' See details. ##' @param rownamesAsLabels (logical), should the row names of the ##' data provided be matched only to labels (TRUE), or should any ##' number-like row names be matched to node numbers (FALSE and ##' default) ##' @param label.type character, \code{rownames} or \code{column}: ##' should the labels be taken from the row names of \code{dt} or from ##' the \code{label.column} column of \code{dt}? ##' @param label.column if \code{label.type=="column"}, column ##' specifier (number or name) of the column containing tip labels ##' @param missing.data action to take if there are missing data or if ##' there are data labels that don't match ##' @param extra.data action to take if there are extra data or if ##' there are labels that don't match ##' @param keep.all (logical), should the returned data have rows for ##' all nodes (with NA values for internal rows when type='tip', and ##' vice versa) (TRUE and default) or only rows corresponding to the ##' type argument ##' @return \code{formatData} returns a data frame having node numbers ##' as row names. The data frame is also formatted to have the correct ##' dimension given the \code{phylo4} object provided. ##' @author Francois Michonneau ##' @seealso the \code{\link{phylo4d-methods}} constructor, the ##' \linkS4class{phylo4d} class. See \code{\link{coerce-methods}} for ##' translation functions. ##' @keywords misc formatData <- function(phy, dt, type=c("tip", "internal", "all"), match.data=TRUE, rownamesAsLabels=FALSE, label.type=c("rownames", "column"), label.column=1, missing.data=c("fail", "warn", "OK"), extra.data=c("warn", "OK", "fail"), keep.all=TRUE ) { ## determine whether to return rows for all nodes, or just 'type' type <- match.arg(type) if (keep.all) { ids.out <- nodeId(phy, "all") } else { ids.out <- nodeId(phy, type) } ## if null, return empty data frame with node numbers as row names if (is.null(dt)) { return(data.frame(row.names=ids.out)) } ## if vector, coerce to data.frame if (is.vector(dt) || is.factor(dt) || is.matrix(dt)) { dt <- as.data.frame(dt) } ## before proceeding, make sure that data provided are a data frame if (!is.data.frame(dt)) { stop(paste(deparse(substitute(dt)), "must be a vector, factor, matrix, or data frame")) } ## if lacking rows or columns, return a placeholder data frame with ## node numbers as row names if (any(dim(dt)==0)) { return(data.frame(row.names=ids.out)) } label.type <- match.arg(label.type) ## Make sure the column specified for the labels is appropriate if (label.type == "column") { if (is.numeric(label.column)) stopifnot(label.column %in% 1:ncol(dt)) else stopifnot(label.column %in% names(dt)) } missing.data <- match.arg(missing.data) extra.data <- match.arg(extra.data) if(match.data) { ## extract values to be matched to nodes ndNames <- switch(label.type, rownames = rownames(dt), column = dt[,label.column]) if (rownamesAsLabels) { ids.in <- lapply(ndNames, function(ndnm) { getNode(phy, as.character(ndnm), missing="OK") }) } else { ids.in <- lapply(ndNames, function(ndnm) { if (nchar(gsub("[0-9]", "", ndnm)) == 0) { getNode(phy, as.integer(ndnm), missing="OK") } else { getNode(phy, as.character(ndnm), missing="OK") } }) } ids.list <- ids.in ids.in <- unlist(ids.in) ## Make sure that data are matched to appropriate nodes if (type=="tip" && any(stats::na.omit(ids.in) %in% nodeId(phy, "internal"))) { stop("Your tip data are being matched to internal ", "nodes. Make sure that your data identifiers ", "are correct.") } if (type=="internal" && any(stats::na.omit(ids.in) %in% nodeId(phy, "tip"))) { stop("Your node data are being matched to tip ", "nodes. Make sure that your data identifiers ", "are correct.") } ## Check differences between tree and data mssng <- setdiff(nodeId(phy, type), ids.in) if(length(mssng) > 0 && missing.data != "OK") { ## provide label if it exists and node number otherwise mssng <- getNode(phy, mssng) mssng <- ifelse(is.na(names(mssng)), mssng, names(mssng)) msg <- "The following nodes are not found in the dataset: " msg <- paste(msg, paste(mssng, collapse=", ")) switch(missing.data, warn = warning(msg), fail = stop(msg)) } extra <- ndNames[is.na(ids.in)] if(length(extra) > 0 && extra.data != "OK") { msg <- "The following names are not found in the tree: " msg <- paste(msg, paste(extra, collapse=", ")) switch(extra.data, warn = warning(msg), fail = stop(msg)) } ## Format data to have correct dimensions ids.list <- ids.list[!is.na(ids.list)] dt <- dt[!is.na(ids.in), , drop=FALSE] if (hasDuplicatedLabels(phy)) { dtTmp <- array(, dim=c(length(ids.in[!is.na(ids.in)]), ncol(dt)), dimnames=list(ids.in[!is.na(ids.in)], names(dt))) dtTmp <- data.frame(dtTmp) j <- 1 for (i in 1:length(ids.list)) { for (k in 1:length(ids.list[[i]])) { dtTmp[j, ] <- dt[i, , drop=FALSE] j <- j + 1 } } dt <- dtTmp } rownames(dt) <- ids.in[!is.na(ids.in)] dt.out <- dt[match(ids.out, rownames(dt)), , drop=FALSE] rownames(dt.out) <- ids.out if(label.type == "column") { dt.out <- subset(dt.out, select=-eval(parse(text=label.column))) } } else { ## Check if too many or not enough rows in input data expected.nrow <- length(nodeId(phy, type)) diffNr <- nrow(dt) - expected.nrow if(nrow(dt) > expected.nrow && extra.data != "OK") { msg <- paste("There are", diffNr, "extra rows.") switch(extra.data, warn = warning(msg), fail = stop(msg)) } if(nrow(dt) < expected.nrow && missing.data != "OK") { msg <- paste("There are", abs(diffNr), "missing rows.") switch(missing.data, warn = warning(msg), fail = stop(msg)) } ## truncate rows of input data frame if necessary dt <- dt[1:min(nrow(dt), expected.nrow) ,, drop = FALSE] rownames(dt) <- nodeId(phy, type)[seq_len(nrow(dt))] dt.out <- dt[match(ids.out, rownames(dt)) ,, drop=FALSE] rownames(dt.out) <- ids.out } dt.out } phylobase/R/treePlot.R0000644000176200001440000007642012636203362014376 0ustar liggesusers##' Phylogeny plotting ##' ##' Plot \code{phylo4} or \code{phylo4d} objects, including associated data. ##' ##' ##' @name treePlot-methods ##' @aliases treePlot plot,ANY,ANY-method plot,pdata,missing-method ##' plot,phylo4,missing-method treePlot-method treePlot,phylo4,phylo4d-method ##' @docType methods ##' @details Currently, \code{treePlot} can only plot numeric values ##' for tree-associated data. The dataset will be subset to only ##' include columns of class \code{numeric}, \code{integer} or ##' \code{double}. If a \code{phylo4d} object is passed to the ##' function and it contains no data, or if the data is in a format ##' that cannot be plotted, the function will produce a warning. You ##' can avoid this by using the argument \code{plot.data=FALSE}. ##' @param phy A \code{phylo4} or \code{phylo4d} object ##' @param x A \code{phylo4} or \code{phylo4d} object ##' @param y (only here for compatibility) ##' @param type A character string indicating the shape of plotted tree ##' @param show.tip.label Logical, indicating whether tip labels should be shown ##' @param show.node.label Logical, indicating whether node labels should be ##' shown ##' @param tip.order If NULL the tree is plotted with tips in preorder, if "rev" ##' this is reversed. Otherwise, it is a character vector of tip labels, ##' indicating their order along the y axis (from top to bottom). Or, a numeric ##' vector of tip node IDs indicating the order. ##' @param plot.data Logical indicating whether \code{phylo4d} data should be ##' plotted ##' @param rot Numeric indicating the rotation of the plot in degrees ##' @param tip.plot.fun A function used to generate plot at the each tip of the ##' phylogenetic trees ##' @param edge.color A vector of colors in the order of \code{edges(phy)} ##' @param node.color A vector of colors indicating the colors of the node ##' labels ##' @param tip.color A vector of colors indicating the colors of the tip labels ##' @param edge.width A vector in the order of \code{edges(phy)} indicating the ##' widths of edge lines ##' @param newpage Logical indicating whether the page should be cleared before ##' plotting ##' @param plot.at.tip should the data plots be at the tip? (logical) ##' @param margins number of lines around the plot (similar to \code{par(mar)}). ##' @param \dots additional arguments ##' @return No return value, function invoked for plotting side effect ##' @section Methods: \describe{ \item{phy = "phylo4"}{plots a tree of class ##' \linkS4class{phylo4}} \item{phy = "phylo4d"}{plots a tree with one or more ##' quantitative traits contained in a \linkS4class{phylo4d} object.} } ##' @author Peter Cowan \email{pdc@@berkeley.edu}, Francois Michonneau ##' @seealso \code{\link{phylobubbles}} ##' @keywords methods ##' @export ##' @examples ##' ##' ## example of plotting two grid plots on the same page ##' library(grid) ##' data(geospiza) ##' geotree <- extractTree(geospiza) ##' grid.newpage() ##' pushViewport(viewport(layout=grid.layout(nrow=1, ncol=2), name="base")) ##' pushViewport(viewport(layout.pos.col=1, name="plot1")) ##' treePlot(geotree, newpage=FALSE) ##' popViewport() ##' ##' pushViewport(viewport(layout.pos.col=2, name="plot2")) ##' treePlot(geotree, newpage=FALSE, rot=180) ##' popViewport(2) `treePlot` <- function(phy, type = c('phylogram', 'cladogram', 'fan'), show.tip.label = TRUE, show.node.label = FALSE, tip.order = NULL, plot.data = is(phy, 'phylo4d'), rot = 0, tip.plot.fun = 'bubbles', plot.at.tip = TRUE, edge.color = 'black', node.color = 'black', # TODO what do with node.color parameter tip.color = 'black', edge.width = 1, # TODO line-type modification hack newpage = TRUE, margins = c(1.1, 1.1, 1.1, 1.1), # number of lines, same as par(mar) ... ) { ## TODO three dimensional histogram as example, compute values on full dataset ## then generate phylo4d object with summary data and plot ## TODO factors not handled in data plots ## TODO add symbols at the nodes, allow coloirng and sizing downViewport approach? ## TODO cladogram methods incorrect ## because we may reoder the tip, we need to update the phy objec if (!inherits(phy, 'phylo4')) stop('treePlot requires a phylo4 or phylo4d object') if (!isRooted(phy)) stop("treePlot function requires a rooted tree.") if (plot.data) { if (!hasTipData(phy)) { warning("tree has no tip data to plot") plot.data <- FALSE } else { ## if new plotting functions are developped that allow users to plot other type of data ## this needs to be removed/adjusted ## other checks are being made in phylobubbles() if (!any(sapply(tdata(phy, "tip"), function(x) class(x) %in% c("numeric", "double", "integer")))) { warning("only numeric data can be plotted at this time") plot.data <- FALSE } } } if (hasRetic(phy)) stop("treePlot requires non-reticulated trees.") if(newpage) grid::grid.newpage() type <- match.arg(type) Nedges <- nEdges(phy) Ntips <- nTips(phy) if(!is.null(tip.order) && length(tip.order) > 1) { ## if length of tip.order is more than 1 it can't be "rev" if(length(tip.order) != Ntips) {stop('tip.order must be the same length as nTips(phy)')} if(is.numeric(tip.order)) { tip.order <- tip.order } else { if(is.character(tip.order)) { tip.order <- as.numeric(names(tipLabels(phy))[match(tip.order, tipLabels(phy))]) } } tip.order <- rev(tip.order) } ## TODO remove the false cladogram option? if(!hasEdgeLength(phy) || type == 'cladogram') { edgeLength(phy) <- rep(1, Nedges) } xxyy <- phyloXXYY(phy, tip.order) if(type == 'cladogram') { xxyy$xx[edges(xxyy$phy)[, 2] <= Ntips] <- 1 } ## plotViewport is a convience function that provides margins in lines grid::pushViewport(grid::plotViewport(margins=margins)) if(!plot.data) { plotOneTree(xxyy, type, show.tip.label, show.node.label, edge.color, node.color, tip.color, edge.width, rot) } else { if(!is.function(tip.plot.fun)) { if(tip.plot.fun == "bubbles") { phylobubbles( type = type, show.node.label = show.node.label, rot = 0, edge.color = edge.color, node.color = node.color, # TODO what do with node.color parameter tip.color = tip.color, edge.width = edge.width, # TODO line-type modification hack newpage = TRUE, ..., XXYY = xxyy ) } else { stop(paste(tip.plot.fun, 'is neither a function or a recognized plot type')) } } else { ## from -- if(tip.plot.fun == "bubbles") ## plot.at.tip <- TRUE if (plot.at.tip) { tip.data.plot( xxyy = xxyy, type = type, show.tip.label = show.tip.label, show.node.label = show.node.label, rot = 0, tip.plot.fun = tip.plot.fun, edge.color = edge.color, node.color = node.color, # TODO what do with node.color parameter tip.color = tip.color, edge.width = edge.width, # TODO line-type modification hack newpage = TRUE, ... ) return(invisible()) } ## if (plot.at.tip) } ## else } ## else grid::upViewport() # margins } ##' Plot a phylo4 object ##' ##' Plots the phylogenetic tree contained in a \code{phylo4} or \code{phylo4d} ##' object. ##' ##' ##' @param xxyy A list created by the \code{\link{phyloXXYY}} function ##' @param type A character string indicating the shape of plotted tree ##' @param show.tip.label Logical, indicating whether tip labels should be shown ##' @param show.node.label Logical, indicating whether node labels should be ##' shown ##' @param edge.color A vector of colors in the order of \code{edges(phy)} ##' @param node.color A vector of colors indicating the colors of the node ##' labels ##' @param tip.color A vector of colors indicating the colors of the tip labels ##' @param edge.width A vector in the order of \code{edges(phy)} indicating the ##' widths of edge lines ##' @param rot Numeric indicating the rotation of the plot in degrees ##' @return Returns no values, function invoked for the plotting side effect. ##' @author Peter Cowan \email{pdc@@berkeley.edu} ##' @seealso \code{treePlot}, \code{\link{phyloXXYY}} ##' @export ##' @keywords methods ##' @examples ##' library(grid) ##' data(geospiza) ##' grid.newpage() ##' xxyy <- phyloXXYY(geospiza) ##' plotOneTree(xxyy, type = 'phylogram', ##' show.tip.label = TRUE, show.node.label = TRUE, ##' edge.color = 'black', node.color = 'orange', tip.color = 'blue', ##' edge.width = 1, rot = 0 ##' ) ##' ##' grid.newpage() ##' pushViewport(viewport(w = 0.8, h = 0.8)) ##' plotOneTree(xxyy, type = 'phylogram', ##' show.tip.label = TRUE, show.node.label = TRUE, ##' edge.color = 'black', node.color = 'orange', tip.color = 'blue', ##' edge.width = 1, rot = 0 ##' ) ##' popViewport() ##' plotOneTree <- function(xxyy, type, show.tip.label, show.node.label, edge.color, node.color, tip.color, edge.width, rot) { # TODO switch to phylobase abstractions phy <- xxyy$phy Nedges <- nEdges(phy) Nnodes <- nNodes(phy) Ntips <- nTips(phy) pedges <- edges(phy) tindex <- pedges[pedges[, 2] <= Ntips, 2] eindex <- xxyy$eorder segs <- xxyy$segs ## TODO check that colors are valid? if(length(edge.color) != Nedges) { edge.color <- rep(edge.color, length.out = Nedges) } edge.color <- edge.color[eindex] if(length(edge.width) != Nedges) { edge.width <- rep(edge.width, length.out = Nedges) } edge.width <- edge.width[eindex] ## TODO check that colors are valid? if(length(node.color) != Nnodes) { node.color <- rep(node.color, length.out = Nnodes) } if(show.tip.label) { ## calculate several lab dimesisions ## labw -- a vector of string widths ## adjlabw -- the max width for adjusting the size of viewports ## laboff -- a vector of half string widths for ## offsetting center justified labels, handy for vp rotation labw <- grid::stringWidth(tipLabels(phy)) adjlabw <- max(labw) + grid::unit(0.1, 'inches') laboff <- labw * 0.5 + grid::unit(0.1, 'inches') ## print(foo <<- laboff) treelayout <- grid.layout(nrow = 1, ncol = 2, widths = grid::unit.c(grid::unit(1, 'null', NULL), grid::convertUnit(adjlabw, 'inches')) ) tindex <- pedges[pedges[, 2] <= Ntips, 2] if(length(tip.color) != Ntips) { tip.color <- rep(tip.color, length.out = Ntips) } # keep labels horizontal unless plot is upwards or downwards lrot <- ifelse(rot %% 360 %in% c(90, 270), 0, -rot) } else { treelayout <- grid::grid.layout(nrow = 1, ncol = 1) } # grid.show.layout(treelayout) grid::pushViewport(grid::viewport( x = 0.5, y = 0.5, width = 1, height = 1, layout = treelayout, angle = rot, name = 'treelayout')) grid::pushViewport(grid::viewport( layout.pos.col = 1, name = 'tree')) if (type == "fan") { dseg <- grid::grid.segments( # draws diag lines x0 = segs$v0x, y0 = segs$v0y, x1 = segs$h1x, y1 = segs$h1y, name = "diag", gp = grid::gpar(col = edge.color, lwd = edge.width)) } else { vseg <- grid::grid.segments( # draws vertical lines x0 = segs$v0x, y0 = segs$v0y, x1 = segs$v1x, y1 = segs$v1y, name = "vert", gp = grid::gpar(col = edge.color, lwd = edge.width)) hseg <- grid::grid.segments( # draws horizontal lines x0 = segs$h0x, y0 = segs$h0y, x1 = segs$h1x, y1 = segs$h1y, name = "horz", gp = grid::gpar(col = edge.color, lwd = edge.width)) } grid::upViewport() # tree if(show.tip.label) { grid::pushViewport(grid::viewport(layout.pos.col = 1, name = 'tiplabelvp')) labtext <- grid::grid.text( tipLabels(phy)[tindex], x = grid::unit(xxyy$xx[pedges[, 2] %in% tindex], "native") + laboff[tindex], y = xxyy$yy[pedges[, 2] %in% tindex], rot = lrot, default.units = 'native', name = 'tiplabels', just = 'center', gp = grid::gpar(col = tip.color[tindex]) ) grid::upViewport() #tiplabelvp } # TODO probably want to be able to adjust the location of these guys if(show.node.label) { grid::pushViewport(grid::viewport(layout = treelayout, layout.pos.col = 1, name = 'nodelabelvp')) theLabels <- nodeLabels(phy)[match(pedges[pedges[, 2] > Ntips, 2], names(nodeLabels(phy)))] ## don't plot NAs theLabels[is.na(theLabels)] <- "" labtext <- grid::grid.text( theLabels, x = c(xxyy$xx[pedges[, 2] > Ntips]), y = c(xxyy$yy[pedges[, 2] > Ntips]), default.units = 'npc', name = 'nodelabels', rot = -rot, just = 'center', gp = grid::gpar(col = node.color) ) grid::upViewport() #nodelabelvp } grid::upViewport() # treelayout # grobTree(vseg, hseg, labtext) } ##' Calculate node x and y coordinates ##' ##' Calculates the node x and y locations for plotting a phylogenetic tree. ##' ##' The y coordinates of the tips are evenly spaced from 0 to 1 in pruningwise ##' order. Ancestor y nodes are given the mean value of immediate descendants. ##' The root is given the x coordinate 0 and descendant nodes are placed ##' according to the cumulative branch length from the root, with a maximum x ##' value of 1. ##' ##' @param phy A \code{phylo4} or \code{phylo4d} object. ##' @param tip.order A character vector of tip labels, indicating their order ##' along the y axis (from top to bottom). Or, a numeric vector of tip node IDs ##' indicating the order. ##' @return \item{yy}{Internal node and tip y coordinates} \item{xx}{Internal ##' node and tip x coordinates} \item{phy}{A \code{phylo4} or \code{phylo4d} ##' object} \item{segs}{A list of \code{h0x, h1x, v0x, v1x} and \code{h0y, h1y, ##' v0y, v1y} describing the start and end points for the plot line segments} ##' \item{torder}{The tip order provided as \code{tip.order} or if NULL the ##' preoder tip order} \item{eorder}{The an index of the reordered edges ##' compared to the result of \code{edges(phy)}} ##' @author Peter Cowan \email{pdc@@berkeley.edu} ##' @seealso \code{treePlot}, \code{\link{plotOneTree}} ##' @export ##' @keywords methods ##' @examples ##' ##' ##' data(geospiza) ##' coor <- phyloXXYY(geospiza) ##' plot(coor$xx, coor$yy, pch = 20) ##' ##' phyloXXYY <- function(phy, tip.order=NULL) { phy.orig <- phy ## initalize the output phy <- reorder(phy, 'preorder') pedges <- edges(phy) eindex <- match(pedges[,2], edges(phy.orig)[,2]) Nedges <- nrow(pedges) ## TODO switch to the accessor once stablized Ntips <- nTips(phy) tips <- pedges[, 2] <= Ntips xx <- numeric(Nedges) yy <- numeric(Nedges) treelen <- rep(NA, nEdges(phy)) segs <- list(v0x = treelen, v0y = treelen, v1x = treelen, v1y = treelen, h0x = treelen, h0y = treelen, h1x = treelen, h1y = treelen) ## Set root x value to zero and calculate x positions xx[1] <- 0 segs$v0x[1] <- segs$v1x[1] <- segs$h0x[1] <- 0 edge1 <- as.integer(pedges[,1]) edge2 <- as.integer(pedges[,2]) edgeLen <- edgeLength(phy) edgeLen[is.na(edgeLen)] <- 0 edgeLen <- as.numeric(edgeLen) nedges <- as.integer(nEdges(phy)) segsv0x <- as.numeric(rep.int(0, Nedges)) xPos <- .C("phyloxx", edge1, edge2, edgeLen, nedges, xx, segsv0x) xx <- xPos[[5]] segs$v0x <- xPos[[6]] ## Set y positions for terminal nodes and calculate remaining y positions if(!is.null(tip.order)) { if(length(tip.order) == 1 && tip.order == "rev") { yy[tips] <- seq(1, 0, length = Ntips) tip.order <- rev(edge2[edge2 <= Ntips]) } else { yy[tips][match(tip.order, edge2[tips])] <- seq(0, 1, length = Ntips) } } else { yy[tips] <- seq(0, 1, length = Ntips) tip.order <- edge2[edge2 <= Ntips] } segs$h0y[tips] <- segs$h1y[tips] <- yy[tips] segs$v1y[tips] <- segs$v0y[tips] <- yy[tips] phyloyy <- function() { for(i in rev((Ntips + 1):nEdges(phy))) { dex <- pedges[, 1] == i cur <- pedges[, 2] == i yy[cur] <- segs$v0y[dex] <- mean(yy[dex]) } return(list(segs=segs, yy=yy)) } yPos <- phyloyy() segs <- yPos$segs yy <- yPos$yy ## edgeLen[is.na(edgeLen)] <- 0 ## edgeLen <- as.numeric(edgeLen) ## ntips <- as.integer(nTips(phy)) ## yy <- as.numeric(yy) ## segsv0y <- as.numeric(yy) ## yPos <- .C("phyloyy", edge1, edge2, ## ntips, nedges, yy, segsv0y) segs$h0y <- segs$h1y <- segs$v1y <- yy ## scale the x values so they range from 0 to 1 Xmax <- max(xx) segs$v0x <- segs$v0x / Xmax xx <- xx / Xmax segs$h1x <- xx segs$v1x <- segs$h0x <- segs$v0x # TODO return an index vector instead of a second phy object list(xx = xx, yy = yy, phy = phy, segs = segs, torder=tip.order, eorder=eindex) } .bubLegendGrob <- function(tipdata, tipdataS) { grid::grob(tipdata=tipdata, tipdataS=tipdataS, cl='bubLegend') } drawDetails.bubLegend <- function(x, ...) { ## number of bubbles in legend leglen <- 4 ## the raw tip data tipdata <- x$tipdata ## the tip data as scaled for bubble plot ts <- x$tipdataS ## return to the bubble plot viewport to get properly scaled values ## this relies on having well named unique viewports grid::seekViewport("bubble_plots") ## retreive the min and max non-zero bubbles as numerics not units bubrange <- grid::convertUnit( grid::unit(c(min(ts[ts != 0], na.rm=TRUE), max(ts[ts != 0], na.rm=TRUE)), "native"), "mm", valueOnly=TRUE) grid::seekViewport("bubblelegend") ## grid.rect() ## Generate the sequence of legend bubble sizes and convert to grid mm units legcirS <- grid::unit(seq(bubrange[1], bubrange[2], length.out=leglen), "mm") ## get the corresponding sequence of actual data values legcir <- seq(min(tipdata[tipdata != 0], na.rm=TRUE), max(tipdata[tipdata != 0], na.rm=TRUE), length.out=leglen) ccol <- ifelse(legcir < 0, 'black', 'white') leftedge <- abs(grid::convertUnit(legcirS[1], 'npc', valueOnly=TRUE)) + 0.1 xloc <- seq(leftedge, 0.5, length.out=leglen) textsp <- grid::convertUnit(max(abs(legcirS)), axisFrom="y", axisTo="y", 'npc', valueOnly=TRUE) strsp <- grid::convertUnit(unit(1, "strheight", "TTT"), axisFrom="y", 'npc', valueOnly=TRUE) grid::grid.circle(x=xloc, y=0.9 - textsp - strsp, r=legcirS, gp = grid::gpar(fill=ccol), default.units = 'npc') grid::grid.text(as.character(signif(legcir, digits = 2)), x=xloc, y=0.75 - 2 * textsp - strsp, gp=grid::gpar(cex=0.75), default.units='npc' ) } ##' Bubble plots for phylo4d objects ##' ##' Plots either circles or squares corresponding to the magnitude of each cell ##' of a \code{phylo4d} object. ##' ##' ##' @param type the type of plot ##' @param place.tip.label A string indicating whether labels should be plotted ##' to the right or to the left of the bubble plot ##' @param show.node.label A logical indicating whether internal node labels ##' should be plotted ##' @param rot The number of degrees that the plot should be rotated ##' @param edge.color A vector of colors for the tree edge segments ##' @param node.color A vector of colors for the coloring the nodes ##' @param tip.color A vector of colors for the coloring the tip labels ##' @param edge.width A vector of line widths for the tree edges ##' @param newpage Logical to control whether the device is cleared before ##' plotting, useful for adding plot inside other plots ##' @param \dots Additional parameters passed to the bubble plotting functions ##' @param XXYY The out put from the phyloXXYY function ##' @param square Logical indicating whether the plot 'bubbles' should be ##' squares ##' @param grid A logical indicating whether a grey grid should be plotted ##' behind the bubbles ##' @author Peter Cowan \email{pdc@@berkeley.edu} ##' @export ##' @seealso \code{\link{phyloXXYY}}, \code{treePlot} ##' @keywords methods ##' @examples ##' ##' ##---- Should be DIRECTLY executable !! ---- ##' ##-- ==> Define data, use random, ##' ##-- or do help(data=index) for the standard data sets. ##' phylobubbles <- function(type = type, place.tip.label = "right", show.node.label = show.node.label, rot = 0, edge.color = edge.color, node.color = node.color, # TODO what do with node.color parameter tip.color = tip.color, edge.width = edge.width, # TODO line-type modification hack newpage = TRUE, ..., XXYY, square = FALSE, grid = TRUE) { ## TODO add legend command ## tys -- tip y coordinates ## nVars -- number of traits/characters ## maxr -- maximum circle radius, based on nVars or nTips ## torder -- the order of tips in the reordered edge matrix if(rot != 0) {stop("Rotation of bubble plots not yet implemented")} lab.right <- ifelse(place.tip.label %in% c("right", "both"), TRUE, FALSE) lab.left <- ifelse(place.tip.label %in% c("left", "both"), TRUE, FALSE) phy <- XXYY$phy tip.order <- XXYY$torder tipdata <- tdata(phy, type = "tip")[tip.order,, drop=FALSE] tipClass <- sapply(tipdata, function(x) class(x) %in% c("double", "integer", "numeric")) tipdata <- tipdata[, tipClass, drop=FALSE] tmin <- min(tipdata, na.rm = TRUE) tmax <- max(tipdata, na.rm = TRUE) pedges <- edges(phy) nVars <- ncol(tipdata) # number of bubble columns dlabwdth <- max(grid::stringWidth(colnames(tipdata))) * 1.2 if(grid::convertWidth(dlabwdth, 'cm', valueOnly=TRUE) < 2) {dlabwdth <- grid::unit(2, 'cm')} phyplotlayout <- grid::grid.layout(nrow = 2, ncol = 2, heights = grid::unit.c(grid::unit(1, 'null'), dlabwdth), widths = grid::unit(c(1, 1), c('null', 'null'), list(NULL, NULL))) grid::pushViewport(viewport(layout = phyplotlayout, name = 'phyplotlayout')) grid::pushViewport(viewport(layout.pos.row = 1:2, layout.pos.col = 2, height = grid::unit(1, 'npc') + grid::convertUnit(dlabwdth, 'npc'), name = 'bubbleplots', default.units = 'native')) # tip y coordinates tys <- XXYY$yy[pedges[, 2] <= nTips(phy)] tys <- tys[match(names(tipLabels(phy))[tip.order], XXYY$torder)] maxr <- ifelse(ncol(tipdata) > nTips(phy), 1 / ncol(tipdata), 1 / nTips(phy)) tipdataS <- apply(tipdata, 2, function(x) (maxr * x) / max(abs(x), na.rm = TRUE)) if(nVars == 1) { xpos <- 0.5 } else { xpos <- seq(0 + maxr + 0.02, 1 - maxr - 0.02, length.out = nVars) } ## rep coordinates for filling a matrix columnwise xrep <- rep(xpos, each = length(tys)) yrep <- rep(tys, nVars) ## color bubbles ccol <- ifelse(tipdata < 0, 'black', 'white') ## generate matrices of every x and y by filling the repd value columnwise ## then subset for datapoints that are NA naxs <- matrix(xrep, ncol = nVars) nays <- matrix(yrep, ncol = nVars) dnas <- is.na(tipdataS) naxs <- naxs[dnas] nays <- nays[dnas] ## set the NA points to zero so that grid.circle doesn't crash tipdataS[is.na(tipdataS)] <- 0 + 0.001 # workaround negative circles on PDF ## get label widths if(lab.right) { tiplabwidth <- max(grid::stringWidth(tipLabels(phy))) } else {tiplabwidth <- grid::unit(0, 'null', NULL)} ## 2x2 layout -- room at the bottom for data labels, and legend bublayout <- grid::grid.layout(nrow = 2, ncol = 2, widths = grid::unit.c(grid::unit(1, 'null', NULL), tiplabwidth), heights = grid::unit.c(grid::unit(1, 'null', NULL), dlabwdth)) grid::pushViewport(viewport( x = 0.5, y = 0.5, width = 0.95, height = 1, layout = bublayout, name = 'bublayout' )) grid::pushViewport(viewport( name = 'bubble_plots', layout = bublayout, layout.pos.col = 1, layout.pos.row = 1 )) if(grid) { ## draw light grey grid behind bubbles grid::grid.segments(x0 = 0, x1 = 1, y0 = tys, y1 = tys, gp = grid::gpar(col = 'grey')) grid::grid.segments(x0 = xpos, x1 = xpos, y0 = 0, y1 = 1, gp = grid::gpar(col = 'grey')) } if (length(naxs) > 0) { ## if ther are missing values plot Xs grid::grid.points(naxs, nays, pch = 4) } if(square) { ## alternative to circles ## to keep the squares square, yet resize nicely use the square npc sqedge <- grid::unit(unlist(tipdataS), 'snpc') grid::grid.rect(x = xrep, y = yrep, width = sqedge, height = sqedge, gp=grid::gpar(fill = ccol)) } else { ## plot bubbles grid::grid.circle(xrep, yrep, r = unlist(tipdataS), gp = grid::gpar(fill = ccol)) } grid::upViewport() ## push view ports for tip and data labels fixed locations if(lab.right) { grid::pushViewport(viewport( name = 'bubble_tip_labels', layout = bublayout, layout.pos.col = 2, layout.pos.row = 1 )) tt <- tipLabels(phy)[tip.order] # phy@tip.label grid::grid.text(tt, 0.1, tys, just = 'left') grid::upViewport() } grid::pushViewport(viewport( name = 'bubble_data_labels', layout = bublayout, layout.pos.col = 1, layout.pos.row = 2 )) ## ideas, for nicer sizing of the data labels ## data.label.space <- convertX(unit(1, 'npc'), "points", valueOnly = TRUE) ## data.label.fontsize <- data.label.space / ncol(tipdata) ## , gp=gpar(fontsize=data.label.fontsize)) ## offset the data labels from the bottom bubble datalaboffset <- grid::convertUnit(grid::unit(15, "mm"), 'npc', valueOnly=TRUE) grid::grid.text(colnames(tipdata), xpos, 1-datalaboffset, rot = 90, just = 'right') grid::upViewport(3) grid::pushViewport(viewport(layout.pos.row=2, layout.pos.col=1, name='bubblelegend')) yyy <- .bubLegendGrob(tipdata, tipdataS) grid::grid.draw(yyy) grid::upViewport() grid::pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 1, name = 'tree')) plotOneTree(XXYY, type, show.tip.label=lab.left, show.node.label, edge.color, node.color, tip.color, edge.width, rot) grid::upViewport(2) # to make a nice legend, return the biggest smallest and a scaling factor # translate the scale of the current vp to a fixed value ## ensure the min is not a zero (or NA) that's replaced by a zero ## print(convertUnit(bubscale, 'inches', valueOnly = TRUE)) ## return(list(max = max(tipdata, na.rm = TRUE), ## min = min(tipdata[tipdata != 0], na.rm = TRUE), ## has.na = length(naxs) > 0, ## bubscale = bubscale)) } ##' Plotting trees and associated data ##' ##' Plotting phylogenetic trees and associated data ##' ##' ##' @param xxyy A list created by the \code{\link{phyloXXYY}} function ##' @param type A character string indicating the shape of plotted tree ##' @param show.tip.label Logical, indicating whether tip labels should be shown ##' @param show.node.label Logical, indicating whether node labels should be ##' shown ##' @param rot Numeric indicating the rotation of the plot in degrees ##' @param tip.plot.fun A function used to plot the data elements of a ##' \code{phylo4d} object ##' @param edge.color A vector of colors in the order of \code{edges(phy)} ##' @param node.color A vector of colors indicating the colors of the node ##' labels ##' @param tip.color A vector of colors indicating the colors of the tip labels ##' @param edge.width A vector in the order of \code{edges(phy)} indicating the ##' widths of edge lines ##' @param \dots Additional parameters passed to \code{tip.plot.fun} ##' @return creates a plot on the current graphics device. ##' @author Peter Cowan ##' @export ##' @keywords methods tip.data.plot <- function( xxyy, type = c('phylogram', 'cladogram', 'fan'), show.tip.label = TRUE, show.node.label = FALSE, rot = 0, tip.plot.fun = grid.points, edge.color = 'black', node.color = 'black', # TODO what do with node.color parameter tip.color = 'black', edge.width = 1, # TODO line-type modification hack ...) { phy <- xxyy$phy tip.order <- xxyy$torder pedges <- edges(phy) Ntips <- nTips(phy) datalayout <- grid::grid.layout(ncol = 2, widths = grid::unit(c(1, 1/Ntips), c('null', 'null'))) # TODO this is done multiple times, grid::pushViewport(viewport(layout = datalayout, angle = rot, name = 'datalayout')) grid::pushViewport(viewport( yscale = c(-0.5 / Ntips, 1 + 0.5 / Ntips), xscale = c(0, 1 + 1 / Ntips), layout.pos.col = 1, name = 'data_plots')) ## TODO should plots float at tips, or only along edge? hc <- grid::convertY(grid::unit(1 / Ntips, 'snpc'), 'npc') for(i in 1:Ntips) { grid::pushViewport(viewport( y = xxyy$yy[pedges[, 2] == i], x = 1 + 1 / (2 * Ntips), # xxyy$xx[phy@edge[, 2] == i], height = hc, width = hc, # default.units = 'native', name = paste('data_plot', i), just = "center", angle = -rot )) #grid.rect() tvals <- tdata(phy, type = 'tip')[nodeId(phy,'tip'), , drop=FALSE] vals = t(tvals[i, ]) if (!all(is.na(vals))) tip.plot.fun(vals, ...) grid::upViewport() # loop viewports } plotOneTree(xxyy, type, show.tip.label, show.node.label, edge.color, node.color, tip.color, edge.width, rot) grid::upViewport(2) ## data_plot & datalayout } # phyloStripchart <- function() ##' @rdname treePlot-methods ##' @aliases plot ##' @exportMethod plot setGeneric('plot') ##' @rdname treePlot-methods ##' @aliases plot,phylo4-method setMethod('plot', signature(x='phylo4', y='missing'), function(x, y, ...) { treePlot(x, ...) }) phylobase/R/phylo4d-methods.R0000644000176200001440000004212512650436652015625 0ustar liggesusers###################### ## phylo4d constructor ###################### ## TEST ME ## '...' recognized args for data are tipdata and nodedata. ## other recognized options are those known by the phylo4 constructor ##' Combine a phylogenetic tree with data ##' ##' \code{phylo4d} is a generic constructor which merges a ##' phylogenetic tree with data frames to create a combined object of ##' class \code{phylo4d} ##' ##' You can provide several data frames to define traits associated ##' with tip and/or internal nodes. By default, data row names are ##' used to link data to nodes in the tree, with any number-like names ##' (e.g., \dQuote{10}) matched against node ID numbers, and any ##' non-number-like names (e.g., \dQuote{n10}) matched against node ##' labels. Alternative matching rules can be specified by passing ##' additional arguments (listed in the Details section); these ##' include positional matching, matching exclusively on node labels, ##' and matching based on a column of data rather than on row ##' names. ##' ##' Matching rules will apply the same way to all supplied data ##' frames. This means that you need to be consistent with the row ##' names of your data frames. It is good practice to use tip and ##' node labels (or node numbers if you use duplicated labels) when ##' you combine data with a tree. ##' ##' If you provide both \code{tip.data} and \code{node.data}, the ##' treatment of columns with common names will depend on the ##' \code{merge.data} argument. If TRUE, columns with the same name in ##' both data frames will be merged; when merging columns of different ##' data types, coercion to a common type will follow standard R ##' rules. If \code{merge.data} is FALSE, columns with common names ##' will be preserved independently, with \dQuote{.tip} and ##' \dQuote{.node} appended to the names. This argument has no effect ##' if \code{tip.data} and \code{node.data} have no column names in ##' common. ##' ##' If you provide \code{all.data} along with either of ##' \code{tip.data} and \code{node.data}, it must have distinct column ##' names, otherwise an error will result. Additionally, although ##' supplying columns with the same names \emph{within} data frames is ##' not illegal, automatic renaming for uniqeness may lead to ##' surprising results, so this practice should be avoided. ##' ##' @name phylo4d-methods ##' @aliases phylo4d ##' @param x an object of class \code{phylo4}, \code{phylo}, ##' \code{nexml} or a matrix of edges (see above) ##' @param tip.data a data frame (or object to be coerced to one) ##' containing only tip data (Optional) ##' @param node.data a data frame (or object to be coerced to one) ##' containing only node data (Optional) ##' @param all.data a data frame (or object to be coerced to one) ##' containing both tip and node data (Optional) ##' @param merge.data if both \code{tip.data} and \code{node.data} are ##' provided, should columns with common names will be merged together ##' (default TRUE) or not (FALSE)? See details. ##' @param metadata any additional metadata to be passed to the new object ##' @param edge.length Edge (branch) length. (Optional) ##' @param tip.label A character vector of species names (names of ##' "tip" nodes). (Optional) ##' @param node.label A character vector of internal node ##' names. (Optional) ##' @param edge.label A character vector of edge (branch) ##' names. (Optional) ##' @param order character: tree ordering (allowable values are listed ##' in \code{phylo4_orderings}, currently "unknown", "preorder" ##' (="cladewise" in \code{ape}), and "postorder", with "cladewise" ##' and "pruningwise" also allowed for compatibility with \code{ape}) ##' @param annote any additional annotation data to be passed to the ##' new object ##' @param check.node.labels if \code{x} is of class \code{phylo}, use ##' either \dQuote{keep} (the default) to retain internal node labels, ##' \dQuote{drop} to drop them, or \dQuote{asdata} to convert them to ##' numeric tree data. This argument is useful if the \code{phylo} ##' object has non-unique node labels or node labels with informative ##' data (e.g., posterior probabilities). ##' @param \dots further arguments to control the behavior of the ##' constructor in the case of missing/extra data and where to look ##' for labels in the case of non-unique labels that cannot be stored ##' as row names in a data frame (see Details). ##' @details This is the list of additional arguments that can be used ##' to control matching between the tree and the data: ##' ##' \itemize{ ##' ##' \item{match.data}{(logical) should the rownames of the data frame ##' be used to be matched against tip and internal node identifiers?} ##' ##' \item{rownamesAsLabels}{(logical), should the row names of the ##' data provided be matched only to labels (TRUE), or should any ##' number-like row names be matched to node numbers (FALSE and ##' default)} ##' ##' \item{label.type}{character, \code{rownames} or \code{column}: ##' should the labels be taken from the row names of \code{dt} or from ##' the \code{label.column} column of \code{dt}?} ##' ##' \item{label.column}{iff \code{label.type=="column"}, column ##' specifier (number or name) of the column containing tip labels} ##' ##' \item{missing.data}{action to take if there are missing data or if ##' there are data labels that don't match} ##' ##' \item{extra.data}{action to take if there are extra data or if ##' there are labels that don't match} ##' ##' \item{keep.all}{(logical), should the returned data have rows for ##' all nodes (with NA values for internal rows when type='tip', and ##' vice versa) (TRUE and default) or only rows corresponding to the ##' type argument} ##' ##' } ##' ##' Rules for matching rows of data to tree nodes are determined ##' jointly by the \code{match.data} and \code{rownamesAsLabels} ##' arguments. If \code{match.data} is TRUE, data frame rows will be ##' matched exclusively against tip and node labels if ##' \code{rownamesAsLabels} is also TRUE, whereas any all-digit row ##' names will be matched against tip and node numbers if ##' \code{rownamesAsLabels} is FALSE (the default). If ##' \code{match.data} is FALSE, \code{rownamesAsLabels} has no effect, ##' and row matching is purely positional with respect to the order ##' returned by \code{nodeId(phy, type)}. ##' ##' @return An object of class \linkS4class{phylo4d}. ##' @note Checking on matches between the tree and the data will be ##' done by the validity checker (label matches between data and tree ##' tips, number of rows of data vs. number of nodes/tips/etc.) ##' @section Methods: \describe{ \item{x = "phylo4"}{merges a tree of ##' class \code{phylo4} with a data.frame into a \code{phylo4d} ##' object} \item{x = "matrix"}{merges a matrix of tree edges similar ##' to the edge slot of a \code{phylo4} object (or to \$edge of a ##' \code{phylo} object) with a data.frame into a \code{phylo4d} ##' object} \item{x = "phylo"}{merges a tree of class \code{phylo} ##' with a data.frame into a \code{phylo4d} object } } ##' @author Ben Bolker, Thibaut Jombart, Steve Kembel, Francois ##' Michonneau, Jim Regetz ##' @seealso \code{\link{coerce-methods}} for translation ##' functions. The \linkS4class{phylo4d} class; \linkS4class{phylo4} ##' class and \link{phylo4} constructor. ##' @keywords misc ##' @export ##' @docType methods ##' @rdname phylo4d-methods ##' @include phylo4d-class.R ##' @include oldclasses-class.R ##' @examples ##' ##' treeOwls <- "((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3);" ##' tree.owls.bis <- ape::read.tree(text=treeOwls) ##' try(phylo4d(as(tree.owls.bis,"phylo4"),data.frame(wing=1:3)), silent=TRUE) ##' obj <- phylo4d(as(tree.owls.bis,"phylo4"),data.frame(wing=1:3), match.data=FALSE) ##' obj ##' print(obj) ##' ##' #### ##' ##' data(geospiza_raw) ##' geoTree <- geospiza_raw$tree ##' geoData <- geospiza_raw$data ##' ##' ## fix differences in tip names between the tree and the data ##' geoData <- rbind(geoData, array(, dim = c(1,ncol(geoData)), ##' dimnames = list("olivacea", colnames(geoData)))) ##' ##' ### Example using a tree of class 'phylo' ##' exGeo1 <- phylo4d(geoTree, tip.data = geoData) ##' ##' ### Example using a tree of class 'phylo4' ##' geoTree <- as(geoTree, "phylo4") ##' ##' ## some random node data ##' rNodeData <- data.frame(randomTrait = rnorm(nNodes(geoTree)), ##' row.names = nodeId(geoTree, "internal")) ##' ##' exGeo2 <- phylo4d(geoTree, tip.data = geoData, node.data = rNodeData) ##' ##' ### Example using 'merge.data' ##' data(geospiza) ##' trGeo <- extractTree(geospiza) ##' tDt <- data.frame(a=rnorm(nTips(trGeo)), row.names=nodeId(trGeo, "tip")) ##' nDt <- data.frame(a=rnorm(nNodes(trGeo)), row.names=nodeId(trGeo, "internal")) ##' ##' (matchData1 <- phylo4d(trGeo, tip.data=tDt, node.data=nDt, merge.data=FALSE)) ##' (matchData2 <- phylo4d(trGeo, tip.data=tDt, node.data=nDt, merge.data=TRUE)) ##' ##' ## Example with 'all.data' ##' nodeLabels(geoTree) <- as.character(nodeId(geoTree, "internal")) ##' rAllData <- data.frame(randomTrait = rnorm(nTips(geoTree) + nNodes(geoTree)), ##' row.names = labels(geoTree, 'all')) ##' ##' exGeo5 <- phylo4d(geoTree, all.data = rAllData) ##' ##' ## Examples using 'rownamesAsLabels' and comparing with match.data=FALSE ##' tDt <- data.frame(x=letters[1:nTips(trGeo)], ##' row.names=sample(nodeId(trGeo, "tip"))) ##' tipLabels(trGeo) <- as.character(sample(1:nTips(trGeo))) ##' (exGeo6 <- phylo4d(trGeo, tip.data=tDt, rownamesAsLabels=TRUE)) ##' (exGeo7 <- phylo4d(trGeo, tip.data=tDt, rownamesAsLabels=FALSE)) ##' (exGeo8 <- phylo4d(trGeo, tip.data=tDt, match.data=FALSE)) ##' ##' ## generate a tree and some data ##' set.seed(1) ##' p3 <- ape::rcoal(5) ##' dat <- data.frame(a = rnorm(5), b = rnorm(5), row.names = p3$tip.label) ##' dat.defaultnames <- dat ##' row.names(dat.defaultnames) <- NULL ##' dat.superset <- rbind(dat, rnorm(2)) ##' dat.subset <- dat[-1, ] ##' ##' ## create a phylo4 object from a phylo object ##' p4 <- as(p3, "phylo4") ##' ##' ## create phylo4d objects with tip data ##' p4d <- phylo4d(p4, dat) ##' ###checkData(p4d) ##' p4d.sorted <- phylo4d(p4, dat[5:1, ]) ##' try(p4d.nonames <- phylo4d(p4, dat.defaultnames)) ##' p4d.nonames <- phylo4d(p4, dat.defaultnames, match.data=FALSE) ##' ##' \dontrun{ ##' p4d.subset <- phylo4d(p4, dat.subset) ##' p4d.subset <- phylo4d(p4, dat.subset) ##' try(p4d.superset <- phylo4d(p4, dat.superset)) ##' p4d.superset <- phylo4d(p4, dat.superset) ##' } ##' ##' ## create phylo4d objects with node data ##' nod.dat <- data.frame(a = rnorm(4), b = rnorm(4)) ##' p4d.nod <- phylo4d(p4, node.data = nod.dat, match.data=FALSE) ##' ##' ##' ## create phylo4 objects with node and tip data ##' p4d.all1 <- phylo4d(p4, node.data = nod.dat, tip.data = dat, match.data=FALSE) ##' nodeLabels(p4) <- as.character(nodeId(p4, "internal")) ##' p4d.all2 <- phylo4d(p4, all.data = rbind(dat, nod.dat), match.data=FALSE) setGeneric("phylo4d", function(x, ...) { standardGeneric("phylo4d")} ) ## first arg is a phylo4 ##' @rdname phylo4d-methods ##' @aliases phylo4d,phylo4,phylo4-method setMethod("phylo4d", "phylo4", function(x, tip.data=NULL, node.data=NULL, all.data=NULL, merge.data=TRUE, metadata = list(), ...) { ## coerce tree to phylo4d res <- as(x, "phylo4d") ## apply formatData to ensure data have node number rownames and ## correct dimensions tip.data <- formatData(phy=x, dt=tip.data, type="tip", ...) node.data <- formatData(phy=x, dt=node.data, type="internal", ...) all.data <- formatData(phy=x, dt=all.data, type="all", ...) ## add any data res@data <- .phylo4Data(x=x, tip.data=tip.data, node.data=node.data, all.data=all.data, merge.data=merge.data) ## add any metadata res@metadata <- metadata return(res) }) ### first arg is a matrix of edges ##' @rdname phylo4d-methods ##' @aliases phylo4d,matrix,matrix-method setMethod("phylo4d", "matrix", function(x, tip.data=NULL, node.data=NULL, all.data=NULL, merge.data=TRUE, metadata=list(), edge.length=NULL, tip.label=NULL, node.label=NULL, edge.label=NULL, order="unknown", annote=list(), ...) { tree <- phylo4(x, edge.length=edge.length, tip.label=tip.label, node.label=node.label, edge.label=edge.label, order=order, annote=annote) res <- phylo4d(tree, tip.data, node.data, all.data, merge.data=merge.data, metadata=metadata, ...) return(res) }) label_to_data <- function(nlab.data, ...) { ## convert number-like labels to numeric, other keep as it is nlab.data.test <- gsub("[0-9]|\\.", "", nlab.data[!is.na(nlab.data)]) if (all(nchar(nlab.data.test) == 0 )) { nlab.data <- data.frame(labelValues=as.numeric(nlab.data), ...) } else { nlab.data <- data.frame(labelValues=nlab.data, ...) } nlab.data } ### first arg is a phylo ##' @rdname phylo4d-methods ##' @aliases phylo4d,phylo,phylo-method setMethod("phylo4d", "phylo", function(x, tip.data=NULL, node.data=NULL, all.data=NULL, check.node.labels=c("keep", "drop", "asdata"), annote=list(), metadata=list(), ...) { check.node.labels <- match.arg(check.node.labels) if (check.node.labels == "asdata") { # FIXME? use.node.names=TRUE won't work with this option b/c # node labels are dropped; assumes node.data (if any), phylo # node.label, and phylo4 internal nodes are in the same order? nlab.data <- x$node.label x$node.label <- NULL nlab.data[!nzchar(nlab.data)] <- NA ## convert number-like labels to numeric, other keep as it is nlab.data <- label_to_data(nlab.data) tree <- phylo4(x, check.node.labels="drop", annote=annote) res <- phylo4d(tree, tip.data=tip.data, node.data=node.data, all.data=all.data, metadata=metadata, ...) res <- addData(res, node.data=nlab.data, pos="before", match.data=FALSE) } else { tree <- phylo4(x, check.node.labels=check.node.labels, annote=annote) res <- phylo4d(tree, tip.data=tip.data, node.data=node.data, all.data=all.data, metadata=metadata, ...) } return(res) }) ### first arg is a phylo4d ##' @rdname phylo4d-methods ##' @aliases phylo4d,phylo4d,phylo4d-method setMethod("phylo4d", c("phylo4d"), function(x, ...) { stop("Your object is already a phylo4d object. If you want to modify", " the data attached to it look at the help for tdata()<-,") }) ### first arg is nexml ##' @rdname phylo4d-methods ##' @aliases nexml,phylo4d-method setMethod("phylo4d", c("nexml"), function(x) { tr <- RNeXML::get_trees_list(x) chr <- RNeXML::get_characters(x) if (is.null(tr[[1]])) { new("phylo4d") } else { if (length(tr) > 1) { warning("Only the first tree has been imported.") } phylo4d(x=tr[[1]][[1]], chr) } }) ### Core function that takes care of the data .phylo4Data <- function(x, tip.data=NULL, node.data=NULL, all.data=NULL, merge.data=TRUE) { ## Check validity of phylo4 object if (is.character(checkval <- checkPhylo4(x))) stop(checkval) ## Create placeholder data frames for any null data arguments if (is.null(tip.data)) tip.data <- formatData(x, NULL, "tip") if (is.null(node.data)) node.data <- formatData(x, NULL, "internal") if (is.null(all.data)) all.data <- formatData(x, NULL, "all") # don't allow all.data columns of same name as tip.data or node.data colnamesTipOrNode <- union(names(tip.data), names(node.data)) if (any(names(all.data) %in% colnamesTipOrNode)) { stop("all.data column names must be distinct from ", "tip.data and node.data column names") } ## combine common columns and move into all.data if merging, ## otherwise rename them colsToMerge <- intersect(names(tip.data), names(node.data)) if (merge.data && length(colsToMerge)>0) { ##TODO could really just index rows directly on 1:nTip and ## (nTip+1):(nTip+nNode) in the next two statements for speed, ## but this is more robust to changes in node numbering rules tip.rows <- tip.data[match(nodeId(x, "tip"), row.names(tip.data)), colsToMerge, drop=FALSE] node.rows <- node.data[match(nodeId(x, "internal"), row.names(tip.data)), colsToMerge, drop=FALSE] merge.data <- rbind(tip.rows, node.rows) all.data <- data.frame(all.data, merge.data) } else { names(tip.data)[names(tip.data) %in% colsToMerge] <- paste(colsToMerge, "tip", sep=".") names(node.data)[names(node.data) %in% colsToMerge] <- paste(colsToMerge, "node", sep=".") } ## now separate tips-only and nodes-only data tip.only.data <- tip.data[setdiff(names(tip.data), names(node.data))] node.only.data <- node.data[setdiff(names(node.data), names(tip.data))] ## combine all data complete.data <- data.frame(all.data, tip.only.data, node.only.data) ## drop any rows that only contain NAs if (ncol(complete.data)==0) { return(data.frame()) } else { empty.rows <- as.logical(rowSums(!is.na(complete.data))) return(complete.data[empty.rows, , drop=FALSE]) } } phylobase/R/tbind.R0000644000176200001440000000337512347155416013704 0ustar liggesusers## appropriate behavior ??? ## IF all missing data -- create multiPhylo4 ## IF some have data -- create multiPhylo4d (user can coerce to multiPhylo4) ## IF (checkData) then stop if all data not identical to first data ## ## need constructors for multiPhylo4, multiPhylo4d!! ## FIXME: need code to construct tree.names ... ## function to bind trees together into a multi-tree object tbind <- function(...,checkData=TRUE) { L <- list(...) namevec <- names(L) treeclasses <- c("multiPhylo4d","multiPhylo4","phylo4","phylo4d") tdataclasses <- c("multiPhylo4d","phylo4d") classes <- sapply(L,class) if (!all(classes %in% treeclasses)) { stop("all elements must be trees or multitrees") } hasData <- any(classes %in% tdataclasses) allData <- all(classes %in% tdataclasses) xfun <- function(x) { switch(class(x), phylo4=x, phylo4d=extractTree(x), multiPhylo4=x@phylolist, multiPhylo4d=suppressWarnings(as("multiPhylo4",x)@phylolist))} ## decompose multi-trees into lists treelist <- unlist(lapply(L,xfun)) if (hasData) alldat <- lapply(L[classes %in% tdataclasses], tdata, type="tip") hasNodeData <- sapply(L[classes %in% tdataclasses], hasNodeData) if (any(hasNodeData)) warning("internal node data discarded") if (checkData) { ident <- sapply(alldat,identical,y=alldat[[1]]) if (!all(ident)) stop(paste("tip data sets differ")) } ## ?? implement code to check which ones differ (taking ## null/multiple values in original set into account) if (hasData) return(new("multiPhylo4d",phylolist=treelist, tip.data=alldat[[1]])) return(new("multiPhylo4",phylolist=treelist)) } phylobase/R/phylobase.options.R0000644000176200001440000000374612347155416016266 0ustar liggesusers##' Set or return options of phylobase ##' ##' Provides a mean to control the validity of \code{phylobase} ##' objects such as singletons, reticulated trees, polytomies, etc. ##' ##' The parameter values set via a call to this function will remain ##' in effect for the rest of the session, affecting the subsequent ##' behavior of phylobase. ##' ##' @param \dots a list may be given as the only argument, or any ##' number of arguments may be in the \code{name=value} form, or no ##' argument at all may be given. See the Value and Details sections ##' for explanation. ##' @return A list with the updated values of the parameters. If ##' arguments are provided, the returned list is invisible. ##' @author Francois Michonneau (adapted from the package \code{sm}) ##' @keywords phylobase validator ##' @examples ##' \dontrun{ ##' phylobase.options(poly="fail") ##' # subsequent trees with polytomies will fail the validity check ##' } ##' ##' @export phylobase.options <- function (...) { if (nargs() == 0) return(.phylobase.Options) current <- .phylobase.Options temp <- list(...) if (length(temp) == 1 && is.null(names(temp))) { arg <- temp[[1]] switch(mode(arg), list = temp <- arg, character = return(.phylobase.Options[arg]), stop("invalid argument: ", sQuote(arg))) } if (length(temp) == 0) return(current) n <- names(temp) if (is.null(n)) stop("options must be given by name") if (!all(names(temp) %in% names(current))) stop("Option name invalid: ", sQuote(names(temp))) changed <- current[n] current[n] <- temp current <- lapply(current, function(foo) { foo <- match.arg(foo, c("warn", "fail", "ok")) }) if (!identical(current$retic, "fail")) { stop("Currently reticulated trees are not handled by phylobase.") } ## options are always global env <- asNamespace("phylobase") assign(".phylobase.Options", current, envir = env) invisible(current) } phylobase/R/subset-methods.R0000644000176200001440000003773513075431131015547 0ustar liggesusers################ ## subset phylo4 ################ ##' Methods for creating subsets of phylogenies ##' ##' Methods for creating subsets of phylogenies, based on pruning a ##' tree to include or exclude a set of terminal taxa, to include all ##' descendants of the MRCA of multiple taxa, or to return a subtree ##' rooted at a given node. ##' ##' The \code{subset} methods must be called using no more than one of ##' the four main subsetting criteria arguments (\code{tips.include}, ##' \code{tips.exclude}, \code{mrca}, or \code{node.subtree}). Each ##' of these arguments can be either character or numeric. In the ##' first case, they are treated as node labels; in the second case, ##' they are treated as node numbers. For the first two arguments, ##' any supplied tips not found in the tree (\code{tipLabels(x)}) will ##' be ignored, with a warning. Similarly, for the \code{mrca} ##' argument, any supplied tips or internal nodes not found in the ##' tree will be ignored, with a warning. For the \code{node.subtree} ##' argument, failure to provide a single, valid internal node will ##' result in an error. ##' ##' Although \code{prune} is mainly intended as the workhorse function ##' called by \code{subset}, it may also be called directly. In ##' general it should be equivalent to the \code{tips.exclude} form of ##' \code{subset} (although perhaps with less up-front error ##' checking). ##' ##' The "[" operator, when used as \code{x[i]}, is similar to the ##' \code{tips.include} form of \code{subset}. However, the indices ##' used with this operator can also be logical, in which case the ##' corresponding tips are assumed to be ordered as in \code{nodeId(x, ##' "tip")}, and recycling rules will apply (just like with a vector ##' or a matrix). With a \linkS4class{phylo4d} object 'x', ##' \code{x[i,j]} creates a subset of \code{x} taking \code{i} for a ##' tip index and \code{j} for the index of data variables in ##' \code{tdata(geospiza, "all")}. Note that the second index is ##' optional: \code{x[i, TRUE]}, \code{x[i,]}, and \code{x[i]} are all ##' equivalent. ##' ##' Regardless of which approach to subsetting is used, the argument ##' values must be such that at least two tips are retained. ##' ##' If the most recent common ancestor of the retained tips is not the ##' original root node, then the root node of the subset tree will be ##' a descendant of the original root. For rooted trees with non-NA ##' root edge length, this has implications for the new root edge ##' length. In particular, the new length will be the summed edge ##' length from the new root node back to the original root (including ##' the original root edge). As an alternative, see the examples for ##' a way to determine the length of the edge that was immediately ##' ancestral to the new root node in the original tree. ##' ##' Note that the correspondance between nodes and labels (and data in ##' the case of \linkS4class{phylo4d}) will be retained after all ##' forms of subsetting. Beware, however, that the node numbers (IDs) ##' will likely be altered to reflect the new tree topology, and ##' therefore cannot be compared directly between the original tree ##' and the subset tree. ##' ##' @name subset-methods ##' @docType methods ##' @param x an object of class \code{"phylo4"} or \code{"phylo4d"} ##' @param tips.include A vector of tips to include in the subset tree ##' @param tips.exclude A vector of tips to exclude from the subset ##' tree ##' @param mrca A vector of nodes for determining the most recent ##' common ancestor, which is then used as the root of the subset tree ##' @param node.subtree A single internal node specifying the root of ##' the subset tree ##' @param trim.internal A logical specifying whether to remove ##' internal nodes that no longer have tip descendants in the subset ##' tree ##' @param i (\code{[} method) An index vector indicating tips to ##' include ##' @param j (\code{[} method, phylo4d only) An index vector ##' indicating columns of node/tip data to include ##' @param drop (not in use: for compatibility with the generic method) ##' @param \dots optional additional parameters (not in use) ##' @return an object of class \code{"phylo4"} or \code{"phylo4d"} ##' @section Methods: \describe{ \item{x = "phylo4"}{subset tree} ##' \item{x = "phylo4d"}{subset tree and corresponding node and tip ##' data} } ##' @author Jim Regetz \email{regetz@@nceas.ucsb.edu}\cr Steven Kembel ##' \email{skembel@@berkeley.edu}\cr Damien de Vienne ##' \email{damien.de-vienne@@u-psud.fr}\cr Thibaut Jombart ##' \email{jombart@@biomserv.univ-lyon1.fr} ##' @keywords methods ##' @rdname subset-methods ##' @aliases subset ##' @examples ##' data(geospiza) ##' nodeLabels(geospiza) <- paste("N", nodeId(geospiza, "internal"), sep="") ##' geotree <- extractTree(geospiza) ##' ##' ## "subset" examples ##' tips <- c("difficilis", "fortis", "fuliginosa", "fusca", "olivacea", ##' "pallida", "parvulus", "scandens") ##' plot(subset(geotree, tips.include=tips)) ##' plot(subset(geotree, tips.include=tips, trim.internal=FALSE)) ##' plot(subset(geotree, tips.exclude="scandens")) ##' plot(subset(geotree, mrca=c("scandens","fortis","pauper"))) ##' plot(subset(geotree, node.subtree=18)) ##' ##' ## "prune" examples (equivalent to subset using tips.exclude) ##' plot(prune(geotree, tips)) ##' ##' ## "[" examples (equivalent to subset using tips.include) ##' plot(geotree[c(1:6,14)]) ##' plot(geospiza[c(1:6,14)]) ##' ##' ## for phylo4d, subset both tips and data columns ##' geospiza[c(1:6,14), c("wingL", "beakD")] ##' ##' ## note handling of root edge length: ##' edgeLength(geotree)['0-15'] <- 0.1 ##' geotree2 <- geotree[1:2] ##' ## in subset tree, edge of new root extends back to the original root ##' edgeLength(geotree2)['0-3'] ##' ## edge length immediately ancestral to this node in the original tree ##' edgeLength(geotree, MRCA(geotree, tipLabels(geotree2))) ##' @exportMethod subset setGeneric("subset") ##' @rdname subset-methods ## @aliases subset,phylo4-method setMethod("subset", "phylo4", function(x, tips.include=NULL, tips.exclude=NULL, mrca=NULL, node.subtree=NULL, ...) { ## FIXME: could eliminate NULL and make the test ## if (!missing) rather than if (!is.null) ## (might have to change next line?) if (sum(!sapply(list(tips.include, tips.exclude, mrca, node.subtree), is.null))>1) { stop("must specify at most one criterion for subsetting") } all.tips <- nodeId(x, "tip") if (!is.null(tips.include)) { nodes <- getNode(x, tips.include, missing="OK") is.valid.tip <- nodes %in% all.tips kept <- nodes[is.valid.tip] dropped <- setdiff(all.tips, kept) unknown <- tips.include[!is.valid.tip] } else if (!is.null(tips.exclude)) { nodes <- getNode(x, tips.exclude, missing="OK") is.valid.tip <- nodes %in% all.tips dropped <- nodes[is.valid.tip] kept <- setdiff(all.tips, dropped) unknown <- tips.exclude[!is.valid.tip] } else if (!is.null(mrca)) { nodes <- getNode(x, mrca, missing="OK") is.valid.node <- nodes %in% nodeId(x, "all") mnode <- MRCA(x, nodes[is.valid.node]) if (length(mnode)!=1) { stop("mrca must include at least one valid node") } kept <- descendants(x, mnode) dropped <- setdiff(all.tips, kept) unknown <- mrca[!is.valid.node] } else if (!is.null(node.subtree)) { node <- getNode(x, node.subtree, missing="OK") if (length(node)!=1 || !(node %in% nodeId(x, "internal"))) { stop("node.subtree must be a single valid internal node") } kept <- descendants(x, node) dropped <- setdiff(all.tips, kept) unknown <- numeric(0) } else { kept <- getNode(x, nodeId(x, "tip")) dropped <- numeric(0) unknown <- numeric(0) } if (length(unknown)>0) { warning("invalid nodes ignored: ", paste(unknown, collapse=", ")) } if (length(kept)<2) { stop("0 or 1 tips would remain after subsetting") } if (length(dropped)==0) return(x) return(prune(x, dropped, ...)) }) ############### # '[' operator ############### ## Consider using some combination of these for stricter argument ## checking? Not implementing now because extra arguments are just ## ignored, which is fairly common S4 method behavior: ## * in "[" methods for phylo4: ## if (nargs()>2) stop("unused arguments") ## * in "[" methods for both phylo4 and phylo4d: ## if (!missing(...)) stop("unused argument(s)") ##' @rdname subset-methods ##' @exportMethod "[" ##' @export setGeneric("[") ##### -------- phylo4 '[' methods ##' @rdname subset-methods ## @aliases [,phylo4,character,missing-method setMethod("[", signature(x="phylo4", i="character", j="missing", drop="missing"), function(x, i, j, ..., drop) { subset(x, tips.include=i) }) ##' @rdname subset-methods ## @aliases [,phylo4,numeric,missing-method setMethod("[", signature(x="phylo4", i="numeric", j="missing", drop="missing"), function(x, i, j, ..., drop) { subset(x, tips.include=i) }) ##' @rdname subset-methods ## @aliases [,phylo4,logical,missing-method setMethod("[", signature(x="phylo4", i="logical", j="missing", drop="missing"), function(x, i, j, ..., drop) { subset(x, tips.include=nodeId(x, "tip")[i]) }) ##' @rdname subset-methods ## @aliases [,phylo4,missing,missing-method setMethod("[", signature(x="phylo4", i="missing", j="missing", drop="missing"), function(x, i, j, ..., drop) { return(x) }) ##### -------- phylo4d '[' methods ##' @rdname subset-methods ## @aliases [,phylo4d,ANY,character,missing-method setMethod("[", signature(x="phylo4d", i="ANY", j="character", drop="missing"), function(x, i, j, ..., drop) { if (!missing(i)) x <- x[i] tdata(x, type="all") <- tdata(x, type="all")[j] return(x) }) ##' @rdname subset-methods ## @aliases [,phylo4d,ANY,numeric,missing-method setMethod("[", signature(x="phylo4d", i="ANY", j="numeric", drop="missing"), function(x, i, j, ..., drop) { if (!missing(i)) x <- x[i] tdata(x, type="all") <- tdata(x, type="all")[j] return(x) }) ##' @rdname subset-methods ## @aliases [,phylo4d,ANY,logical,missing-method setMethod("[", signature(x="phylo4d", i="ANY", j="logical", drop="missing"), function(x, i, j, ..., drop) { if (!missing(i)) x <- x[i] tdata(x, type="all") <- tdata(x, type="all")[j] return(x) }) ## borrow from Matrix package approach of trapping invalid usage ##' @rdname subset-methods ## @aliases [,phylo4,ANY,ANY,ANY-method setMethod("[", signature(x="phylo4", i="ANY", j="ANY", drop="ANY"), function(x, i, j, ..., drop) { stop("invalid argument(s)") }) ##### -------- prune ##' @rdname subset-methods ## @aliases prune ##' @export setGeneric("prune", function(x, ...) { standardGeneric("prune") }) ## return characters, sorted in NUMERIC order .chnumsort <- function(x) { as.character(sort(as.numeric(x))) } ##' @rdname subset-methods ## @aliases prune,phylo4-method setMethod("prune", "phylo4", function(x, tips.exclude, trim.internal=TRUE) { makeEdgeNames <- function(edge) { paste(edge[,1], edge[,2], sep="-") } ## drop tips and obsolete internal nodes from edge matrix tip.drop <- getNode(x, tips.exclude, missing="fail") tip.keep <- setdiff(nodeId(x, "tip"), tip.drop) nodes <- nodeId(x, "all") node.keep <- rep(FALSE, length(nodes)) node.keep[tip.keep] <- TRUE if (trim.internal) { if (edgeOrder(x) == "postorder") { edge.post <- edges(x) } else { edge.post <- edges(reorder(x, "postorder")) } for (i in seq_along(edge.post[,2])) { if (node.keep[edge.post[i,2]]) { node.keep[edge.post[i,1]] <- TRUE } } } else { node.keep[nodeId(x, "internal")] <- TRUE } edge.new <- edges(x)[edges(x)[,2] %in% nodes[node.keep], ] ## remove singletons edge.length.new <- edgeLength(x) edge.label.new <- edgeLabels(x) singletons <- which(tabulate(edge.new[edge.new[, 1] != 0, 1])==1) while (length(singletons)>0) { sing.node <- singletons[1] ## update edge matrix edges.drop <- which(edge.new==sing.node, arr.ind=TRUE)[,"row"] sing.edges <- edge.new[edges.drop,] edge.new[edges.drop[2], ] <- c(sing.edges[2,1], sing.edges[1,2]) edge.new <- edge.new[-edges.drop[1], ] ## update edge lengths and edge labels edge.names.drop <- makeEdgeNames(sing.edges) edge.name.new <- paste(sing.edges[2,1], sing.edges[1,2], sep="-") edge.length.new[edge.name.new] <- sum(edge.length.new[edge.names.drop]) edge.length.new <- edge.length.new[-match(edge.names.drop, names(edge.length.new))] edge.label.new[edge.name.new] <- NA edge.label.new <- edge.label.new[-match(edge.names.drop, names(edge.label.new))] singletons <- which(tabulate(edge.new[edge.new[, 1] != 0, 1])==1) } ## remove dropped elements from labels label.new <- labels(x)[names(labels(x)) %in% edge.new] ## subset and order edge.length and edge.label with respect to edge edge.names <- makeEdgeNames(edge.new) edge.length.new <- edge.length.new[edge.names] edge.label.new <- edge.label.new[edge.names] if (!trim.internal) { ## make sure now-terminal internal nodes are treated as tips tip.now <- setdiff(edge.new[,2], edge.new[,1]) tip.add <- tip.now[tip.now>nTips(x)] if (length(tip.add)>0) { ind <- match(tip.add, names(label.new)) ## node renumbering workaround to satisfy plot method newid <- sapply(tip.add, function(tip) descendants(x, tip)[1]) names(label.new)[ind] <- newid edge.new[match(tip.add, edge.new)] <- newid tip.now[match(tip.add, tip.now)] <- newid isTip <- edge.new %in% tip.now edge.new[isTip] <- match(edge.new[isTip], sort(unique.default(edge.new[isTip]))) } } ## renumber nodes in the edge matrix edge.new[] <- match(edge.new, sort(unique.default(edge.new))) - 1L ## update corresponding element names in the other slots edge.names <- makeEdgeNames(edge.new) names(edge.length.new) <- edge.names names(edge.label.new) <- edge.names label.new <- label.new[order(as.numeric(names(label.new)))] names(label.new) <- seq_along(label.new) ## update, check, then return the pruned phylo4 object x@edge <- edge.new ##TODO would prefer to leave out NA from edge.length slot, but can't x@edge.length <- edge.length.new x@edge.label <- edge.label.new[!is.na(edge.label.new)] x@label <- label.new[!is.na(label.new)] if(is.character(checkval <- checkPhylo4(x))) { stop(checkval) } else { return(x) } }) ##' @rdname subset-methods ## @aliases prune,phylo4d-method setMethod("prune", "phylo4d", function(x, tips.exclude, trim.internal=TRUE) { tree <- extractTree(x) phytr <- prune(tree, tips.exclude, trim.internal) ## create temporary phylo4 object with complete and unique labels tmpLbl <- .genlab("n", nTips(x)+nNodes(x)) tmpPhy <- tree labels(tmpPhy, "all") <- tmpLbl tmpPhytr <- prune(tmpPhy, getNode(x, tips.exclude), trim.internal) ## get node numbers to keep oldLbl <- labels(tmpPhy, "all") newLbl <- labels(tmpPhytr, "all") wasKept <- oldLbl %in% newLbl nodesToKeep <- as.numeric(names(oldLbl[wasKept])) ## subset original data, and update names allDt <- x@data[match(nodesToKeep, rownames(x@data)), , drop=FALSE] rownames(allDt) <- match(newLbl, oldLbl[wasKept]) phytr <- phylo4d(phytr, all.data=allDt, match.data=TRUE) phytr }) ## setMethod("prune","ANY", ## function(phy, tip, trim.internal = TRUE, subtree = FALSE, ## ,...) { ## if (class(phy)=="phylo") { ## ape::prune(phy, tip, trim.internal, subtree) ## } else stop("no prune method available for", ## deparse(substitute(phy)), ## "(class",class(phy),")") ## }) phylobase/R/root-methods.R0000644000176200001440000000320112347155416015214 0ustar liggesusers ##' Methods to test, access (and modify) the root of a phylo4 object. ##' ##' @rdname root-methods ##' @aliases isRooted ##' @docType methods ##' @param x a \code{phylo4} or \code{phylo4d} object. ##' @param value a character string or a numeric giving the new root. ##' @return \describe{ ##' \item{isRooted}{logical whether the tree is rooted} ##' \item{rootNode}{the node corresponding to the root} ##' } ##' @include phylo4-class.R phylo4-methods.R phylo4-accessors.R ##' @export ##' @author Ben Bolker, Francois Michonneau ##' @examples ##' data(geospiza) ##' isRooted(geospiza) ##' rootNode(geospiza) setGeneric("isRooted", function(x) { standardGeneric("isRooted") }) ##' @rdname root-methods ##' @aliases isRooted,phylo4-method setMethod("isRooted", signature(x="phylo4"), function(x) { ## hack to avoid failure on an empty object if(nTips(x) == 0) return(FALSE) any(edges(x)[, 1] == 0) }) ##' @rdname root-methods ##' @aliases rootNode ##' @export setGeneric("rootNode", function(x) { standardGeneric("rootNode") }) ##' @rdname root-methods ##' @aliases rootNode,phylo4-method setMethod("rootNode", signature(x="phylo4"), function(x) { if (!isRooted(x)) return(NA) rootnd <- unname(edges(x)[which(edges(x)[, 1] == 0), 2]) getNode(x, rootnd) }) ##' @rdname root-methods ##' @aliases rootNode<- ##' @export setGeneric("rootNode<-", function(x, value) { standardGeneric("rootNode<-") }) ##' @name rootNode<- ##' @rdname root-methods ##' @aliases rootNode<-,phylo4-method setReplaceMethod("rootNode", signature(x="phylo4"), function(x, value) { stop("Root node replacement not implemented yet") }) phylobase/R/zzz.R0000644000176200001440000000047612347155416013440 0ustar liggesusers ".phylobase.Options" <- list(retic = "fail", singleton = "warn", multiroot = "warn", poly = "ok", allow.duplicated.labels = "warn") .onAttach <- function(library, pkg) { ## we can't do this in .onLoad unlockBinding(".phylobase.Options", asNamespace("phylobase")) } phylobase/R/phylobase-package.R0000644000176200001440000001044513075432237016155 0ustar liggesusers ##' Utilities and Tools for Phylogenetics ##' ##' Base package for phylogenetic structures and comparative data. ##' ##' \code{phylobase} provides a set of functions to associate and ##' manipulate phylogenetic information and data about the ##' species/individuals that are in the tree. ##' ##' \code{phylobase} intends to be robust, fast and efficient. We hope ##' other people use the data structure it provides to develop new ##' comparative methods in R. ##' ##' With \code{phylobase} it is easy to ensure that all your data are ##' represented and associated with the tips or the internal nodes of ##' your tree. \code{phylobase} provides functions to: ##' \itemize{ ##' ##' \item prune (subset) your trees, find ancestor(s) a ##' descendant(s) ##' ##' \item find the most common recent ancestor of 2 nodes (MRCA) ##' ##' \item calculate the distance of a given node from the tip or ##' between two nodes in your tree ##' ##' \item robust functions to import data from NEXUS and Newick files ##' using the NEXUS Class Library (\url{https://github.com/mtholder/ncl/}) ##' } ##' ##' @section History: ##' ##' \code{phylobase} was started during a Hackathlon at NESCent on ##' December 10-14 2007. ##' ##' Peter Cowan was a Google Summer of Code fellow in 2008 and ##' developed all the code for plotting. ##' ##' In December 2008, a mini-virtual Hackathlon was organized to clean ##' up and make the code more robust. ##' ##' In the spring and summer of 2009, Jim Regetz made several ##' contributions that made the code faster (in particular with the ##' re-ordering parts), found many bugs, and wrote most of the testing ##' code. ##' ##' \code{phylobase} was first released on CRAN on November 1st, 2009 ##' with version 0.5. ##' ##' Since then, several releases have followed adding new ##' functionalities: better support of NEXUS files, creation of ##' \code{phylobase.options()} function that controls the \code{phylo4} ##' validator, rewrite of the validator in C++. ##' ##' Starting with 0.6.8, Francois Michonneau succeeds to Ben Bolker as ##' the maintainer of the package. ##' ##' @name phylobase-package ##' @aliases phylobase-package phylobase ##' @docType package ##' @section More Info: ##' See the help index \code{help(package="phylobase")} and run ##' \code{vignette("phylobase", "phylobase")} for further details and ##' examples about how to use \code{phylobase}. ##' @keywords package ##' ##' @useDynLib phylobase, .registration = TRUE ##' @import methods ##' @import ape ##' @import RNeXML ##' @import grid ##' @import stats ##' @importFrom Rcpp evalCpp ##' @importFrom graphics plot ##' @importFrom utils head tail ##' @importFrom ade4 newick2phylog ##' @importFrom rncl rncl ##' ##' @exportMethod print head tail reorder plot summary ##' ## exportMethod should only be used for generics defined outside the package! ## @exportMethod phylo4 phylo4d ## @exportMethod edges edgeId hasEdgeLength edgeLength edgeLength<- sumEdgeLength edgeOrder ## @exportMethod isRooted rootNode rootNode<- ## @exportMethod isUltrametric ## @exportMethod subset prune [ ## @exportMethod [<- [[ [[<- ## @exportMethod labels labels<- nodeLabels nodeLabels<- tipLabels tipLabels<- edgeLabels edgeLabels<- ## @exportMethod hasNodeLabels hasEdgeLabels hasDuplicatedLabels NULL ##' Data from Darwin's finches ##' ##' Phylogenetic tree and morphological data for Darwin's finches, in different ##' formats ##' ##' ##' @name geospiza ##' @aliases geospiza geospiza_raw ##' @docType data ##' @format \code{geospiza} is a \code{phylo4d} object; \code{geospiza_raw} is a ##' list containing \code{tree}, a \code{phylo} object (the tree), \code{data}, ##' and a data frame with the data (for showing examples of how to merge tree ##' and data) ##' @note Stolen from Luke Harmon's Geiger package, to avoid unnecessary ##' dependencies ##' @source Dolph Schluter via Luke Harmon ##' @keywords datasets ##' @examples ##' ##' data(geospiza) ##' plot(geospiza) ##' NULL ##' 'Owls' data from ape ##' ##' A tiny tree, for testing/example purposes, using one of the examples from ##' the \code{ape} package ##' ##' ##' @name owls4 ##' @docType data ##' @format This is the standard 'owls' tree from the \code{ape} package, in ##' \code{phylo4} format. ##' @source From various examples in the \code{ape} package ##' @keywords datasets ##' @examples ##' ##' data(owls4) ##' plot(owls4) ##' NULL phylobase/R/treestruc.R0000644000176200001440000000555312347155416014624 0ustar liggesusers ##' Test trees for polytomies, inline nodes (singletons), or reticulation ##' ##' Methods to test whether trees have (structural) polytomies, inline ##' nodes (i.e., nodes with a single descendant), or reticulation ##' (i.e., nodes with more than one ancestor). \code{hasPoly} only ##' check for structural polytomies (1 node has more than 2 ##' descendants) and not polytomies that result from having edges with ##' a length of 0. ##' ##' @aliases hasSingle ##' @param object an object inheriting from class \code{phylo4} ##' @return Logical value ##' @note Some algorithms are unhappy with structural polytomies (i.e., >2 ##' descendants from a node), with single-descendant nodes, or with ##' reticulation; these functions check those properties. We haven't bothered ##' to check for zero branch lengths: the consensus is that it doesn't come up ##' much, and that it's simple enough to test \code{any(edgeLength(x) == 0)} in ##' these cases. (Single-descendant nodes are used e.g. in OUCH, or in other ##' cases to represent events occurring along a branch.) ##' @author Ben Bolker ##' @rdname treeStructure-methods ##' @export ##' @keywords misc ##' @examples ##' ##' tree.owls.bis <- ape::read.tree(text="((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3);") ##' owls4 <- as(tree.owls.bis, "phylo4") ##' hasPoly(owls4) ##' hasSingle(owls4) ##' setGeneric("hasSingle", function(object) { standardGeneric("hasSingle") }) ##' @rdname treeStructure-methods ##' @aliases hasSingle,phylo4-method setMethod("hasSingle", signature(object="phylo4"), function(object) { if (nEdges(object) == 0) { return(FALSE) } ## This is about 3 times slower than using the C++ ## function tabulateTips ## degree <- tabulate(edges(object, drop.root=TRUE)[, 1]) degree <- tabulateTips(object@edge[, 1]) any(degree == 1) }) ##' @rdname treeStructure-methods ##' @aliases hasRetic ##' @export setGeneric("hasRetic", function(object) { standardGeneric("hasRetic") }) ##' @rdname treeStructure-methods ##' @aliases hasRetic,phylo4-method setMethod("hasRetic", signature(object="phylo4"), function(object) { if (nEdges(object)==0) { return(FALSE) } ## this is about the same (slightly faster on 10,000 tips) ## than using the C++ function ancest <- tabulate(edges(object)[, 2]) any(ancest > 1) }) ##' @rdname treeStructure-methods ##' @aliases hasPoly ##' @export setGeneric("hasPoly", function(object) { standardGeneric("hasPoly") }) ##' @rdname treeStructure-methods ##' @aliases hasPoly,phylo4-method setMethod("hasPoly", signature(object="phylo4"), function(object) { if (nEdges(object)==0) { return(FALSE) } ## This is about 3 times slower than using the C++ ## function tabulateTips ## degree <- tabulate(edges(object, drop.root=TRUE)[, 1]) degree <- tabulateTips(object@edge[, 1]) any(degree > 2) }) phylobase/R/internal-constructors.R0000644000176200001440000000507512347155416017165 0ustar liggesusers ##################### ## Labels constructor ##################### ## (formerly) recursive function to have labels of constant length ## base = a character string ## n = number of labels .genlab <- function(base, n) { if(n <= 0) return("") s <- seq(length.out=n) fw <- max(nchar(as.character(s))) numstr <- formatC(s, flag="0", width=fw) paste(base, numstr, sep="") } .createLabels <- function(value, ntips, nnodes, use.names = TRUE, type = c("all", "tip", "internal")) { type <- match.arg(type) ## set up final length of object to return lgthRes <- switch(type, tip=ntips, internal=nnodes, all=ntips+nnodes) ## create NA character vector of node labels res <- character(lgthRes) is.na(res) <- TRUE ## create internal names names(res) <- switch(type, tip = 1:ntips, internal = seq(from=ntips+1, length=lgthRes), all = 1:(ntips+nnodes)) ## Convert empty labels to NA value[!nzchar(value)] <- NA ## if no values are provided if(missing(value) || is.null(value) || all(is.na(value))) { ## tip labels can't be NULL if(!identical(type, "internal")) { tipLbl <- .genlab("T", ntips) res[1:ntips] <- tipLbl } } ## if labels are provided else { ## check that lengths match if(length(value) != lgthRes) stop("Number of labels does not match number of nodes.") ## check if vector 'value' has name, and if so match with node.label names if(use.names && !is.null(names(value))) { if(!all(names(value) %in% names(res))) stop("Names provided don't match internal labels names.") res[match(names(value), names(res))] <- value } else res[1:lgthRes] <- value } res } .createEdge <- function(value, edgeMat, type=c("lengths", "labels"), use.names=TRUE) { type <- match.arg(type) lgthRes <- nrow(edgeMat) res <- switch(type, lengths=numeric(lgthRes), labels=character(lgthRes)) is.na(res) <- TRUE names(res) <- paste(edgeMat[,1], edgeMat[,2], sep="-") if(!(missing(value) || is.null(value) || all(is.na(value)))) { if(use.names && !is.null(names(value))) { if(!all(names(value) %in% names(res))) stop("Names provided don't match internal edge labels names.") res[match(names(value), names(res))] <- value } else res[1:lgthRes] <- value } res } phylobase/vignettes/0000755000176200001440000000000013076473202014254 5ustar liggesusersphylobase/vignettes/phylobase.Rnw0000644000176200001440000005742213075432177016751 0ustar liggesusers\documentclass{article} %\VignetteEngine{knitr::knitr} %\VignetteIndexEntry{phylo4: classes and methods for phylogenetic trees and data} \usepackage[utf8]{inputenc} % for UTF-8/single quotes from sQuote() \usepackage{graphicx} \usepackage{array} \usepackage{url} %% Use a little bit more of the page %% borrowed from Rd.sty, of r-project.org \addtolength{\textheight}{12mm} \addtolength{\topmargin}{-9mm} % still fits on US paper \addtolength{\textwidth}{24mm} % still fits on US paper \setlength{\oddsidemargin}{10mm} \setlength{\evensidemargin}{\oddsidemargin} \newcommand{\code}[1]{{{\tt #1}}} \title{The \code{phylo4} S4 classes and methods} \author{Ben Bolker, Peter Cowan \& Fran\c{c}ois Michonneau} \date{\today} \begin{document} <>= library(knitr) opts_chunk$set( fig.keep='none', dev='pdf', fig.width=6, fig.height=6, latex.options.color="usenames,dvipsnames" ) @ \maketitle \tableofcontents \section{Introduction} This document describes the new \code{phylo4} S4 classes and methods, which are intended to provide a unifying standard for the representation of phylogenetic trees and comparative data in R. The \code{phylobase} package was developed to help both end users and package developers by providing a common suite of tools likely to be shared by all packages designed for phylogenetic analysis, facilities for data and tree manipulation, and standardization of formats. This standardization will benefit \emph{end-users} by making it easier to move data and compare analyses across packages, and to keep comparative data synchronized with phylogenetic trees. Users will also benefit from a repository of functions for tree manipulation, for example tools for including or excluding subtrees (and associated phenotypic data) or improved tree and data plotting facilities. \code{phylobase} will benefit \emph{developers} by freeing them to put their programming effort into developing new methods rather than into re-coding base tools. We (the \code{phylobase} developers) hope \code{phylobase} will also facilitate code validation by providing a repository for benchmark tests, and more generally that it will help catalyze community development of comparative methods in R. A more abstract motivation for developing \code{phylobase} was to improve data checking and abstraction of the tree data formats. \code{phylobase} can check that data and trees are associated in the proper fashion, and protects users and developers from accidently reordering one, but not the other. It also seeks to abstract the data format so that commonly used information (for example, branch length information or the ancestor of a particular node) can be accessed without knowledge of the underlying data structure (i.e., whether the tree is stored as a matrix, or a list, or a parenthesis-based format). This is achieved through generic \code{phylobase} functions which which retrieve the relevant information from the data structures. The benefits of such abstraction are multiple: (1) \emph{easier access to the relevant information} via a simple function call (this frees both users and developers from learning details of complex data structures), (2) \emph{freedom to optimize data structures in the future without breaking code.} Having the generic functions in place to ``translate'' between the data structures and the rest of the program code allows program and data structure development to proceed somewhat independently. The alternative is code written for specific data structures, in which modifications to the data structure requires rewriting the entire package code (often exacting too high a price, which results in the persistence of less-optimal data structures). (3) \emph{providing broader access to the range of tools in \code{phylobase}}. Developers of specific packages can use these new tools based on S4 objects without knowing the details of S4 programming. The base \code{phylo4} class is modeled on the the \code{phylo} class in \code{ape}. \code{phylo4d} and \code{multiphylo4} extend the \code{phylo4} class to include data or multiple trees respectively. In addition to describing the classes and methods, this vignette gives examples of how they might be used. \section{Package overview} The phylobase package currently implements the following functions and data structures: \begin{itemize} \item Data structures for storing a single tree and multiple trees: \code{phylo4} and \code{multiPhylo4}? \item A data structure for storing a tree with associated tip and node data: \code{phylo4d} \item A data structure for storing multiple trees with one set of tip data: \code{multiPhylo4d} \item Functions for reading nexus files into the above data structures \item Functions for converting between the above data structures and \code{ape phylo} objects as well as \code{ade4} \code{phylog} objects (although the latter are now deprecated \ldots) \item Functions for editing trees and data (i.e., subsetting and replacing) \item Functions for plotting trees and trees with data \end{itemize} \section{Using the S4 help system} The \code{S4} help system works similarly to the \code{S3} help system with some small differences relating to how \code{S4} methods are written. The \code{plot()} function is a good example. When we type \code{?plot} we are provided the help for the default plotting function which expects \code{x} and \code{y}. \code{R} also provides a way to smartly dispatch the right type of plotting function. In the case of an \code{ape phylo} object (a \code{S3} class object) \code{R} evaluates the class of the object and finds the correct functions, so the following works correctly. <>= library(ape) set.seed(1) ## set random-number seed rand_tree <- rcoal(10) ## Make a random tree with 10 tips plot(rand_tree) @ However, typing \code{?plot} still takes us to the default \code{plot} help. We have to type \code{?plot.phylo} to find what we are looking for. This is because \code{S3} generics are simply functions with a dot and the class name added. The \code{S4} generic system is too complicated to describe here, but doesn't include the same dot notation. As a result \code{?plot.phylo4} doesn't work, \code{R} still finds the right plotting function. <>= library(phylobase) # convert rand_tree to a phylo4 object rand_p4_tree <- as(rand_tree, "phylo4") plot(rand_p4_tree) @ All fine and good, but how to we find out about all the great features of the \code{phylobase} plotting function? \code{R} has two nifty ways to find it, the first is to simply put a question mark in front of the whole call: <>= `?`(plot(rand_p4_tree)) @ \code{R} looks at the class of the \code{rand\_p4\_tree} object and takes us to the correct help file (note: this only works with \code{S4} objects). The second ways is handy if you already know the class of your object, or want to compare to generics for different classes: <>= `?`(method, plot("phylo4")) @ More information about how \code{S4} documentation works can be found in the methods package, by running the following command. <>= help('Documentation', package="methods") @ \section{Trees without data} You can start with a tree --- an object of class \code{phylo} from the \code{ape} package (e.g., read in using the \code{read.tree()} or \code{read.nexus()} functions), and convert it to a \code{phylo4} object. For example, load the raw \emph{Geospiza} data: <>= library(phylobase) data(geospiza_raw) ## what does it contain? names(geospiza_raw) @ Convert the \code{S3} tree to a \code{S4 phylo4} object using the \code{as()} function: <>= (g1 <- as(geospiza_raw$tree, "phylo4")) @ The (internal) nodes appear with labels \verb++ because they are not defined: <>= nodeLabels(g1) @ You can also retrieve the node labels with \code{labels(g1,"internal")}). A simple way to assign the node numbers as labels (useful for various checks) is <<>>= nodeLabels(g1) <- paste("N", nodeId(g1, "internal"), sep="") head(g1, 5) @ The \code{summary} method gives a little extra information, including information on the distribution of branch lengths: <>= summary(g1) @ Print tip labels: <>= tipLabels(g1) @ (\code{labels(g1,"tip")} would also work.) You can modify labels and other aspects of the tree --- for example, to convert all the labels to lower case: <>= tipLabels(g1) <- tolower(tipLabels(g1)) @ You could also modify selected labels, e.g. to modify the labels in positions 11 and 13 (which happen to be the only labels with uppercase letters): <>= tipLabels(g1)[c(11, 13)] <- c("platyspiza", "pinaroloxias") @ Note that for a given tree, \code{phylobase} always return the \code{tipLabels} in the same order. Print node numbers (in edge matrix order): <>= nodeId(g1, type='all') @ Does it have information on branch lengths? <>= hasEdgeLength(g1) @ It does! What do they look like? <>= edgeLength(g1) @ Note that the root has \verb++ as its length. Print edge labels (also empty in this case --- therefore all \code{NA}): <>= edgeLabels(g1) @ You can also use this function to label specific edges: <>= edgeLabels(g1)["23-24"] <- "an edge" edgeLabels(g1) @ The edge labels are named according to the nodes they connect (ancestor-descendant). You can get the edge(s) associated with a particular node: <>= getEdge(g1, 24) # default uses descendant node getEdge(g1, 24, type="ancestor") # edges using ancestor node @ These results can in turn be passed to the function \code{edgeLength} to retrieve the length of a given set of edges: <>= edgeLength(g1)[getEdge(g1, 24)] edgeLength(g1)[getEdge(g1, 24, "ancestor")] @ Is it rooted? <>= isRooted(g1) @ Which node is the root? <>= rootNode(g1) @ Does it contain any polytomies? <>= hasPoly(g1) @ Is the tree ultrametric? <>= isUltrametric(g1) @ You can also get the depth (distance from the root) of any given node or the tips: <>= nodeDepth(g1, 23) depthTips(g1) @ \section{Trees with data} The \code{phylo4d} class matches trees with data, or combines them with a data frame to make a \code{phylo4d} (tree-with-data) object. Now we'll take the \emph{Geospiza} data from \verb+geospiza_raw$data+ and merge it with the tree. First, let's prepare the data: <>= g1 <- as(geospiza_raw$tree, "phylo4") geodata <- geospiza_raw$data @ However, since \emph{G. olivacea} is included in the tree but not in the data set, we will initially run into some trouble: <>= g2 <- phylo4d(g1, geodata) @ <>= geodata <- geospiza_raw$data @ To deal with \emph{G. olivacea} missing from the data, we have a few choices. The easiest is to use \code{missing.data="warn"} to allow \code{R} to create the new object with a warning (you can also use \code{missing.data="OK"} to proceed without warnings): <>= g2 <- phylo4d(g1, geodata, missing.data="warn") @ <>= g2 <- phylo4d(g1, geodata, missing.data="OK", extra.data="OK") @ Another way to deal with this would be to use \code{prune()} to drop the offending tip from the tree first: <>= g1sub <- prune(g1, "olivacea") g1B <- phylo4d(g1sub, geodata) @ The difference between the two objects is that the species \emph{G. olivacea} is still present in the tree but has no data (i.e., \verb+NA+) associated with it. In the other case, \textit{G. olivacea} is not included in the tree anymore. The approach you choose depends on the goal of your analysis. You can summarize the new object with the function \code{summary}. It breaks down the statistics about the traits based on whether it is associated with the tips for the internal nodes: <>= summary(g2) @ Or use \code{tdata()} to extract the data (i.e., \code{tdata(g2)}). By default, \code{tdata()} will retrieve tip data, but you can also get internal node data only (\code{tdata(tree, "internal")}) or --- if the tip and node data have the same format --- all the data combined (\code{tdata(tree, "allnode")}). If you want to plot the data (e.g. for checking the input), \code{plot(tdata(g2))} will create the default plot for the data --- in this case, since it is a data frame [\textbf{this may change in future versions but should remain transparent}] this will be a \code{pairs} plot of the data. \section{Subsetting} The \code{subset} command offers a variety of ways of extracting portions of a \code{phylo4} or \code{phylo4d} tree, keeping any tip/node data consistent. \begin{description} \item[tips.include]{give a vector of tips (names or numbers) to retain} \item[tips.exclude]{give a vector of tips (names or numbers) to drop} \item[mrca]{give a vector of node or tip names or numbers; extract the clade containing these taxa} \item[node.subtree]{give a node (name or number); extract the subtree starting from this node} \end{description} Different ways to extract the \emph{fuliginosa}-\emph{scandens} clade: <>= subset(g2, tips.include=c("fuliginosa", "fortis", "magnirostris", "conirostris", "scandens")) subset(g2, node.subtree=21) subset(g2, mrca=c("scandens", "fortis")) @ One could drop the clade by doing <>= subset(g2, tips.exclude=c("fuliginosa", "fortis", "magnirostris", "conirostris", "scandens")) subset(g2, tips.exclude=names(descendants(g2, MRCA(g2, c("difficilis", "fortis"))))) @ % This isn't implemented yet % Another approach is to pick the subtree graphically, by plotting the tree and % using \code{identify}, which returns the identify of the node you click on % with the mouse. % % <>= % plot(g1) % n1 <- identify(g1) % subset(g2,node.subtree=n1) % @ \section{Tree-walking} \code{phylobase} provides many functions that allows users to explore relationships between nodes on a tree (tree-walking and tree traversal). Most functions work by specifying the \code{phylo4} (or \code{phylo4d}) object as the first argument, the node numbers/labels as the second argument (followed by some additional arguments). \code{getNode} allows you to find a node based on its node number or its label. It returns a vector with node numbers as values and labels as names: <>= data(geospiza) getNode(geospiza, 10) getNode(geospiza, "pauper") @ If no node is specified, they are all returned, and if a node can't be found it's returned as a \verb+NA+. It is possible to control what happens when a node can't be found: <>= getNode(geospiza) getNode(geospiza, 10:14) getNode(geospiza, "melanogaster", missing="OK") # no warning getNode(geospiza, "melanogaster", missing="warn") # warning! @ \code{children} and \code{ancestor} give the immediate neighboring nodes: <>= children(geospiza, 16) ancestor(geospiza, 16) @ while \code{descendants} and \code{ancestors} can traverse the tree up to the tips or root respectively: <>= descendants(geospiza, 16) # by default returns only the tips descendants(geospiza, "all") # also include the internal nodes ancestors(geospiza, 20) ancestors(geospiza, 20, "ALL") # uppercase ALL includes self @ \code{siblings} returns the other node(s) associated with the same ancestor: <>= siblings(geospiza, 20) siblings(geospiza, 20, include.self=TRUE) @ \code{MRCA} returns the most common recent ancestor for a set of tips, and shortest path returns the nodes connecting 2 nodes: <>= MRCA(geospiza, 1:6) shortestPath(geospiza, 4, "pauper") @ \section{multiPhylo4 classes} \code{multiPhylo4} classes are not yet implemented but will be coming soon. \section{Examples} \subsection{Constructing a Brownian motion trait simulator} This section will describe a way of constructing a simulator that generates trait values for extant species (tips) given a tree with branch lengths, assuming a model of Brownian motion. We can use \code{as(tree,"phylo4vcov")} to coerce the tree into a variance-covariance matrix form, and then use \code{mvrnorm} from the \code{MASS} package to generate a set of multivariate normally distributed values for the tips. (A benefit of this approach is that we can very quickly generate a very large number of replicates.) This example illustrates a common feature of working with \code{phylobase} --- combining tools from several different packages to operate on phylogenetic trees with data. We start with a randomly generated tree using \code{rcoal()} from \code{ape} to generate the tree topology and branch lengths: <>= set.seed(1001) tree <- as(rcoal(12), "phylo4") @ Next we generate the phylogenetic variance-covariance matrix (by coercing the tree to a \code{phylo4vcov} object) and pick a single set of normally distributed traits (using \code{MASS:mvrnorm} to pick a multivariate normal deviate with a variance-covariance matrix that matches the structure of the tree). <>= vmat <- as(tree, "phylo4vcov") vmat <- cov2cor(vmat) library(MASS) trvec <- mvrnorm(1, mu=rep(0, 12), Sigma=vmat) @ The last step (easy) is to convert the \code{phylo4vcov} object back to a \code{phylo4d} object: <>= treed <- phylo4d(tree, tip.data=as.data.frame(trvec)) plot(treed) @ % \subsubsection{The hard way} % <>= % ## add node labels so we can match to data % nodeLabels(tree) <- as.character(nodeId(tree, "internal")) % ## ordering will make sure that we have ancestor value % ## defined before descendant % tree <- reorder(tree, "preorder") % edgemat <- edges(tree) % ## set aside space for values % nodevals <- numeric(nrow(edgemat)) % ## label data in edge matrix order % names(nodevals) <- labels(tree, "all")[nodeId(tree, "all")] % ## variance is proportional to edge length; drop first % ## element of edge length, which is NA % dvals <- rnorm(nrow(edgemat) - 1, sd=edgeLength(tree)[-1]^2) % ## indexing: ind[node number] gives position in edge matrix % ind <- order(nodeId(tree, "all")) % for (i in 2:nrow(edgemat)) { % ## value of ancestor node plus change % nodevals[i] <- nodevals[ind[edgemat[i, 1]]] + dvals[i - 1] % } % nodevals <- data.frame(nodevals) % treed2 <- phylo4d(tree, all.data=nodevals) % @ % ======================================== % = Table of commands, worth the effort? = % ======================================== % \begin{tabular}{>{\tt}ll} % \hline % \rm Method & Description\\ % \hline % tdata & Retrieve tip data\\ % plot & plot tree with data if present\\ % \hline % \end{tabular} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Appendices %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \appendix \section{Definitions/slots} This section details the internal structure of the \code{phylo4}, \code{multiphylo4} (coming soon!), \code{phylo4d}, and \code{multiphylo4d} (coming soon!) classes. The basic building blocks of these classes are the \code{phylo4} object and a dataframe. The \code{phylo4} tree format is largely similar to the one used by \code{phylo} class in the package \code{ape}\footnote{\url{http://ape.mpl.ird.fr/}}. We use ``edge'' for ancestor-descendant relationships in the phylogeny (sometimes called ``branches'') and ``edge lengths'' for their lengths (``branch lengths''). Most generally, ``nodes'' are all species in the tree; species with descendants are ``internal nodes'' (we often refer to these just as ``nodes'', meaning clear from context); ``tips'' are species with no descendants. The ``root node'' is the node with no ancestor (if one exists). \subsection{phylo4} Like \code{phylo}, the main components of the \code{phylo4} class are: \begin{description} \item[edge]{a 2-column matrix of integers, with $N$ rows for a rooted tree or $N-1$ rows for an unrooted tree and column names \code{ancestor} and \code{descendant}. Each row contains information on one edge in the tree. See below for further constraints on the edge matrix.} \item[edge.length]{numeric list of edge lengths (length $N$ (rooted) or $N-1$ (unrooted) or empty (length 0))} \item[tip.label]{character vector of tip labels (required), with length=\# of tips. Tip labels need not be unique, but data-tree matching with non-unique labels will cause an error} \item[node.label]{character vector of node labels, length=\# of internal nodes or 0 (if empty). Node labels need not be unique, but data-tree matching with non-unique labels will cause an error} \item[order]{character: ``preorder'', ``postorder'', or ``unknown'' (default), describing the order of rows in the edge matrix. , ``pruningwise'' and ``cladewise'' are accepted for compatibility with \code{ape}} \end{description} The edge matrix must not contain \code{NA}s, with the exception of the root node, which has an \code{NA} for \code{ancestor}. \code{phylobase} does not enforce an order on the rows of the edge matrix, but it stores information on the current ordering in the \code{@order} slot --- current allowable values are ``unknown'' (the default), ``preorder'' (equivalent to ``cladewise'' in \code{ape}) or ``postorder'' \footnote{see \url{http://en.wikipedia.org/wiki/Tree_traversal} for more information on orderings. (\code{ape}'s ``pruningwise'' is ``bottom-up'' ordering).}. The basic criteria for the edge matrix are similar to those of \code{ape}, as documented it's tree specification\footnote{\url{ape.mpl.ird.fr/misc/FormatTreeR_28July2008.pdf}}. This is a modified version of those rules, for a tree with $n$ tips and $m$ internal nodes: \begin{itemize} \item Tips (no descendants) are coded $1,\ldots, n$, and internal nodes ($\ge 1$ descendant) are coded $n + 1, \ldots , n + m$ ($n + 1$ is the root). Both series are numbered with no gaps. \item The first (ancestor) column has only values $> n$ (internal nodes): thus, values $\le n$ (tips) appear only in the second (descendant) column) \item all internal nodes [not including the root] must appear in the first (ancestor) column at least once [unlike \code{ape}, which nominally requires each internal node to have at least two descendants (although it doesn't absolutely prohibit them and has a \code{collapse.singles} function to get rid of them), \code{phylobase} does allow these ``singleton nodes'' and has a method \code{hasSingle} for detecting them]. Singleton nodes can be useful as a way of representing changes along a lineage; they are used this way in the \code{ouch} package. \item the number of occurrences of a node in the first column is related to the nature of the node: once if it is a singleton, twice if it is dichotomous (i.e., of degree 3 [counting ancestor as well as descendants]), three times if it is trichotomous (degree 4), and so on. \end{itemize} \code{phylobase} does not technically prohibit reticulations (nodes or tips that appear more than once in the descendant column), but they will probably break most of the methods. Disconnected trees, cycles, and other exotica are not tested for, but will certainly break the methods. We have defined basic methods for \code{phylo4}:\code{show}, \code{print}, and a variety of accessor functions (see help files). \code{summary} does not seem to be terribly useful in the context of a ``raw'' tree, because there is not much to compute. \subsection{phylo4d} The \code{phylo4d} class extends \code{phylo4} with data. Tip data, and (internal) node data are stored separately, but can be retrieved together or separately with \code{tdata(x,"tip")}, \code{tdata(x,"internal")} or \code{tdata(x,"all")}. There is no separate slot for edge data, but these can be stored as node data associated with the descendant node. % \subsection{multiphylo4} \end{document} phylobase/vignettes/auto/0000755000176200001440000000000013075416062015224 5ustar liggesusersphylobase/vignettes/auto/phylobase.el0000644000176200001440000000106613075416062017537 0ustar liggesusers(TeX-add-style-hook "phylobase" (lambda () (TeX-add-to-alist 'LaTeX-provided-package-options '(("inputenc" "utf8"))) (add-to-list 'LaTeX-verbatim-macros-with-braces-local "url") (add-to-list 'LaTeX-verbatim-macros-with-braces-local "path") (add-to-list 'LaTeX-verbatim-macros-with-delims-local "url") (add-to-list 'LaTeX-verbatim-macros-with-delims-local "path") (TeX-run-style-hooks "latex2e" "article" "art10" "inputenc" "graphicx" "array" "url") (TeX-add-symbols '("code" 1))) :latex) phylobase/vignettes/auto/developer.el0000644000176200001440000000061712435655374017551 0ustar liggesusers(TeX-add-style-hook "developer" (lambda () (TeX-add-to-alist 'LaTeX-provided-package-options '(("inputenc" "utf8") ("hyperref" "colorlinks=true" "bookmarks=true"))) (TeX-run-style-hooks "latex2e" "article" "art10" "inputenc" "graphicx" "hyperref" "url") (TeX-add-symbols '("code" 1) "pb") (LaTeX-add-labels "subversion"))) phylobase/MD50000644000176200001440000002014413076514135012556 0ustar liggesusers84c6d95134cc50dcd9ac67baea5a0349 *DESCRIPTION ed21a2787f823cbe19ebe293ca7c1e0e *NAMESPACE 86629d3905a161e0e6020647523e1581 *NEWS.md 5d7d5aaeacdcbb2b7c94e2a7a12c8283 *R/MRCA-methods.R 2d357445e1f4da60a9e24e6b0a4a91af *R/RcppExports.R ee8ad14745e24da2f0ab9ce624116e73 *R/addData-methods.R 386c93b93dcad28f8ac1f3a2fb179e07 *R/ancestors.R f60e16beb8a5551c2c08e486d963c2a7 *R/checkdata.R cf200a46cf69d04f04f6b31c80c75bb1 *R/edgeLength-methods.R 9edcd964c68d44867b019abe4105f093 *R/extractTree.R ad9a4f02a254be9bb954601faa4f58c8 *R/formatData.R c91b1a7bbcea7047e0370985bbcf4d44 *R/getNode-methods.R 182ac8ec6285e37b88a9da9c7e1106fa *R/internal-constructors.R 7bd80915399baa2675528dfed8b193e1 *R/labels-methods.R cb2282bb40632e8f7039991482938d11 *R/multiphylo4-class.R 97bef8bb049e23553a30e9c00f07d6f5 *R/nodeId-methods.R c0e2782404632e4e3420ac9520a7eb67 *R/oldclasses-class.R 016336404f44444178d488798ae5607c *R/pdata.R 871f687a6a4c9e2b3ca3c7ce787dcc4a *R/phylo4-accessors.R 4bebc32d3934dce824c054b0ce549be3 *R/phylo4-class.R be1814a94cc3b26b66451f236b67cedc *R/phylo4-methods.R 3a740fa03aa3940f253b321e006fa157 *R/phylo4d-accessors.R d28d5cb63f628bc8cf032d226857ceb1 *R/phylo4d-class.R 2c8a0217d8812d1e3702aa5cee53ae82 *R/phylo4d-methods.R f62ece881dccb58654574da40e536d3f *R/phylobase-package.R 6cfe1b8f4fa6b546480b9b0917e8884b *R/phylobase.options.R 0c1561e5ae25e50f5811a863450a878e *R/phylomats-class.R 97b55e8896ba2f87877ee9ee1a81a54a *R/print-methods.R 3c625fbec9acfd9826bf6a58c49f3da1 *R/readNCL.R c01c34a9709736825a787cd382300038 *R/reorder-methods.R af36b2ab79cdce9ab7f1c51b99a9120c *R/root-methods.R 874083ceb7ff2a63d4e31e2dfa9b3f6f *R/setAs-methods.R b12e60d130b8617e92ece7cd5e2faa08 *R/shortestPath-methods.R d566204cf9829a745739412ce5887963 *R/subset-methods.R ddb1f86ef610780a336bdf7473b1cb69 *R/summary-methods.R 957d6bb59eea50e691c3411bd7c8a455 *R/tbind.R 54333801e92f6320240187986cf19887 *R/tdata-methods.R 5baf1c1d1a6a5a7794363dde93257d4b *R/treePlot.R a3451a2d297b035ecf6561a4fdb3ae28 *R/treestruc.R 38747d50f18ac2b910afecf24ed1d92c *R/zzz.R 3b650f82480d8fb7eb2c702f8a9f97d1 *build/vignette.rds 7a03af7f836f7bff48f5b9dc83b28ca8 *data/geospiza.rda 8a843dd8cd966030b246f06adee0ac13 *data/geospiza_raw.rda 26e3cdf5f9480147fd9ef4a3f8b75c3b *data/owls4.rda a7c04f77c4e9ddd2a430207cbaea7281 *inst/doc/phylobase.Rnw 2770c634f5eee09c8e585babfe617139 *inst/doc/phylobase.pdf 7cfba1e69724dd93fe4a07525e419ed4 *inst/nexmlfiles/comp_analysis.xml 1fff9fa62be103e818e88abf156ffacb *inst/nexusfiles/ExContData.Rdata c05860e96ba5feab12b1269f43a43f1b *inst/nexusfiles/MultiLineTrees.nex a9a55d0e542ea83751c134892a17440f *inst/nexusfiles/NastyLabels.nex 72b184a406aa23c2e1711df4f3fd0275 *inst/nexusfiles/NastyLabels2.nex f8225a526530eabfaa8ea117e2a82aae *inst/nexusfiles/co1.nex f0289cdad66a374a438f582e2ab76a29 *inst/nexusfiles/minNex.nex f77c8d44a525dbb3b06c335110ad3547 *inst/nexusfiles/minSeq.nex 4d5d4d71cf83b54eed9811470482e8d2 *inst/nexusfiles/newick.tre 51849f725c9b6097be5f2b6453c33844 *inst/nexusfiles/noStateLabels.nex 9fec41c9d01e57b43dc8e55f1547096b *inst/nexusfiles/shorebird_underscore.nex d7eeca6e30d22f9a431822452109e922 *inst/nexusfiles/testSubsetTaxa.nex ee3bac96ca12af01b3c7610df8339f34 *inst/nexusfiles/test_min.nex 8c16a312ee724e2a94aecd5b2c6df0ee *inst/nexusfiles/treeRoundingError.nex 99b2fe340a17a7e8cac9cfb9bdbafe70 *inst/nexusfiles/treeWithContinuousData.nex 9d27abaf6517ea4ca9881bd9f8c0032a *inst/nexusfiles/treeWithDiscAndContData.nex 963e6a5568b7fae9291232b8abfd496c *inst/nexusfiles/treeWithDiscreteData.nex 6deabaca8bbfe8c34e60d06349f31398 *inst/nexusfiles/treeWithPolyExcludedData.nex b6390d9653d37f920612cbe3a8d38fe5 *inst/nexusfiles/treeWithSpecialCharacters.nex 4961bb5af89e1cfd63944af5d8ee8408 *inst/nexusfiles/treeWithUnderscoreLabels.nex 4fe0019675f205b3f5f2f535870769a8 *man/MRCA.Rd fde215307b04dc664d3b6cc0abec351c *man/addData-methods.Rd a1480ee4f6973a6d1ca820e5150bda6c *man/ancestors.Rd 9fca101e88ff5addffa7a211bc8d0e39 *man/checkPhylo4.Rd a1de42c72a5c8857aceaedd2aaec99f4 *man/edgeLength-methods.Rd 76750a52c8492b23eb5509f4f8fa729a *man/edges-accessors.Rd c5ff6259f85ca20555d80f07116c0e4e *man/extractTree.Rd 3f1988b025935317033b46fb0db0bc48 *man/formatData.Rd 3964c17050f1ae365332e0a176156cc4 *man/geospiza.Rd cb4dbc8feab494fe53f74e94162def14 *man/getNode-methods.Rd 8006f53114ff0b652716075f1322ddf9 *man/labels-methods.Rd 011b1c840e1f061613ecf356b2f97582 *man/multiPhylo-class.Rd b976ab5ef7d5d9d0a348ef16019820c3 *man/nTips-methods.Rd 5f5619026f03eb92dc7c5a76410ce13a *man/nodeId-methods.Rd a613eca88be01b8b404487661f041c8e *man/owls4.Rd d07a2bf017b1d937cdbec916190127b1 *man/pdata-class.Rd d88a1ee35365662fbeb5dbe4efe6bde3 *man/pdata.Rd 375b27916734c02363a64ee7c8dba307 *man/phylo4-class.Rd 691582be9ad3f0ef329b7c5abad71c0c *man/phylo4-methods.Rd 27cc410eb347b2f7b56d4c144004a383 *man/phylo4d-accessors.Rd 73b3b7b79cd7bc62c7e9d60a49642256 *man/phylo4d-class.Rd 02e448fb3fbfab2f134fed86c712f0d9 *man/phylo4d-methods.Rd ccb481d77f91417f5a2ff91a53a0670a *man/phyloXXYY.Rd 439961decd10191d8961540d9c4fb776 *man/phylobase-package.Rd 32b2159b920d7397b804da4944625b3c *man/phylobase.options.Rd 5b6744d99b4eafe8a388223af23ce26f *man/phylobubbles.Rd 6633d9159a49e59ce3f11e0afdc36ac9 *man/phylomat-class.Rd 4d54de3c810bb062762e6965108c3be2 *man/plotOneTree.Rd fb84e8cd95ad2561af081a69dc4794ce *man/print-methods.Rd d5418549836069cc4856be319ebf28b1 *man/readNexus.Rd b8bac1e95bc7e7ee47077875704aa7be *man/reorder-methods.Rd 7bd532f87a0e55f7ef75b7f0957a486a *man/root-methods.Rd fd538bced5e59b960e704577c3cc24be *man/setAs-methods.Rd 366c27b381f7c07f2a1498f18fee04eb *man/shortestPath-methods.Rd 31e45659a09b32a9226e1d2c00a6b93b *man/subset-methods.Rd d94fdf7044af2b4852dfd0dd84af84c0 *man/summary-methods.Rd 63edd06f255dd3cf3814f86267ed5e79 *man/tdata-methods.Rd e341698ddd150afd461b7fac0e6b1cfd *man/tip.data.plot.Rd c68c822072473542cf615360d46a9f24 *man/treePlot-methods.Rd 15201a7ee192e8a55b9cca1bd9093e7c *man/treeStructure-methods.Rd ed0d19722e28a7d316256f2c247be33e *src/Makevars 1e0cc7f2ea27756865f63d6758ca90a8 *src/Makevars.win a81e1490b4e64835c20a52bfd48c8171 *src/RcppExports.cpp 2ba5b488a78a904712cdefc6f87307f9 *src/ancestors.c c78cc56ae6c035ed9a0a584424eac960 *src/checkPhylo4.cpp 4b08d7daaf385bd79465aa3e0785967e *src/descendants.c 1b1d0ecd28d6eb26a29fc576091cc5c3 *src/phyloXX.c eaca9d3295c37dd10cfe242678bac37b *src/phylobase_init.c dc5efccf4d370c4c7b0801bcbfd74a9b *src/reorderBinary.c 1944dc3ac77930043bb7ccb02f3718cd *src/reorderRobust.c cb2ef3c2e0613221c053e3236b36debd *tests/misctests.R 9f8cda1294f43f665a0a96aa7b7f7977 *tests/phylo4dtests.R fd985e3b18ff2d41e3c213f8b9418f27 *tests/phylosubtest.R db2a0aaf0280429619fb99b2855c835e *tests/phylotorture.R 647bb8fbf0e8266427210598fc3fd21a *tests/plottest.R c08c45b2d046fc6386a34c9fe78aea51 *tests/roundtrip.R 0a268e814b425b9356091afae16a22dc *tests/test-all.R 38c287fa7b4426eab00c31412ff770be *tests/testprune.R c0345feb32ec3fb041e48f6a35c2d653 *tests/testthat/test.badnex.R bf3987b5a02228ef385fcb1550254ffa *tests/testthat/test.checkdata.R dabcabf70354afc578c5633231a4fb71 *tests/testthat/test.class-phylo4.R 871e4ed23cfc659f3df4a0648eaca39c *tests/testthat/test.class-phylo4d.R 7bfa9a811172037df31773779b89cdef *tests/testthat/test.formatData.R 1275c5c4b612317ed4e6c9f1a7e8eb15 *tests/testthat/test.methods-oldclasses.R fb3c95bcfb9297e8a1ec897e3db1ffce *tests/testthat/test.methods-phylo4.R 9dd09d9e64303c752ed57a7331543854 *tests/testthat/test.pdata.R e4d54b4db45a69a5e40811975cc44274 *tests/testthat/test.phylo4.R d38fa9feddccd722b1c56a4864dbfc9e *tests/testthat/test.phylobase.options.R e1d0fada9b7ed61564f9fb1570d02f4f *tests/testthat/test.prune.R d04b3ce36e78bf0b03ea97355b6bb3cc *tests/testthat/test.readNCL.R ea0cce4681edbf1067b681bd89327c50 *tests/testthat/test.setAs-Methods.R 37b1df7381866235003e027eff81e2c7 *tests/testthat/test.subset.R 7ce9e14f01d0b524e56ec238d90275e0 *tests/testthat/test.tbind.R 3286fe80846d087c46a36fcf380e42a7 *tests/testthat/test.treePlot.R 7020fbe04de6da74f575a83039235325 *tests/testthat/test.treestruc.R 521ece6dcb763bcbfd39c327fff884e2 *tests/testthat/test.treewalk.R f3f850c2fd5df4c58e5802d2e8ad01b5 *vignettes/auto/developer.el 58df4009f4e2c780dc5bcc1324f31bf4 *vignettes/auto/phylobase.el a7c04f77c4e9ddd2a430207cbaea7281 *vignettes/phylobase.Rnw phylobase/build/0000755000176200001440000000000013076473202013343 5ustar liggesusersphylobase/build/vignette.rds0000644000176200001440000000035113076473202015701 0ustar liggesusers‹uQË ¤¥>Zcbâð=yÒ«ñâÅ^Q¶¶I 4½ùåê¶¶FQ7YX˜v€cDñ ¥”øK:Çaˆ9ÃôH@Bœ§eZçêÄ Ä{Y9àªKvι1`—‚`S% K”f-~ 6;3«¡£nùÿ>¥Hpòf-Ï[èIÁü7ê@òŒ£­¡)šíÛo½ww$ã-Ô•Ò½æƒ3ì8Á&Ë¡ï{ÈìkAwëMWz{×Ã×ùþC­ª¸¿Ã´ù +w ÷¢í›;®£æeãD£¾ñý5C^õâphylobase/DESCRIPTION0000644000176200001440000000341113076514135013752 0ustar liggesusersPackage: phylobase Type: Package Title: Base Package for Phylogenetic Structures and Comparative Data Version: 0.8.4 Imports: ade4, ape (>= 3.0), Rcpp (>= 0.11.0), rncl (>= 0.6.0), grid, methods, stats, RNeXML LinkingTo: Rcpp Suggests: MASS, testthat (>= 0.8.1), knitr Author: R Hackathon et al. (alphabetically: Ben Bolker, Marguerite Butler, Peter Cowan, Damien de Vienne, Dirk Eddelbuettel, Mark Holder, Thibaut Jombart, Steve Kembel, Francois Michonneau, David Orme, Brian O'Meara, Emmanuel Paradis, Jim Regetz, Derrick Zwickl) Maintainer: Francois Michonneau Description: Provides a base S4 class for comparative methods, incorporating one or more trees and trait data. License: GPL (>= 2) URL: https://github.com/fmichonneau/phylobase BugReports: https://github.com/fmichonneau/phylobase/issues LazyData: true Collate: 'oldclasses-class.R' 'internal-constructors.R' 'phylo4-methods.R' 'RcppExports.R' 'checkdata.R' 'phylo4-class.R' 'getNode-methods.R' 'formatData.R' 'phylo4d-class.R' 'phylo4d-methods.R' 'MRCA-methods.R' 'addData-methods.R' 'ancestors.R' 'phylo4-accessors.R' 'root-methods.R' 'nodeId-methods.R' 'edgeLength-methods.R' 'setAs-methods.R' 'extractTree.R' 'labels-methods.R' 'multiphylo4-class.R' 'pdata.R' 'phylo4d-accessors.R' 'phylobase-package.R' 'phylobase.options.R' 'phylomats-class.R' 'print-methods.R' 'readNCL.R' 'reorder-methods.R' 'shortestPath-methods.R' 'subset-methods.R' 'summary-methods.R' 'tbind.R' 'tdata-methods.R' 'treePlot.R' 'treestruc.R' 'zzz.R' VignetteBuilder: knitr RoxygenNote: 6.0.1 NeedsCompilation: yes Packaged: 2017-04-21 21:15:46 UTC; francois Repository: CRAN Date/Publication: 2017-04-21 23:40:13 UTC phylobase/man/0000755000176200001440000000000013075423374013023 5ustar liggesusersphylobase/man/treeStructure-methods.Rd0000644000176200001440000000321313075412470017625 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/treestruc.R \docType{methods} \name{hasSingle} \alias{hasSingle} \alias{hasSingle,phylo4-method} \alias{hasRetic} \alias{hasRetic,phylo4-method} \alias{hasPoly} \alias{hasPoly,phylo4-method} \title{Test trees for polytomies, inline nodes (singletons), or reticulation} \usage{ hasSingle(object) \S4method{hasSingle}{phylo4}(object) hasRetic(object) \S4method{hasRetic}{phylo4}(object) hasPoly(object) \S4method{hasPoly}{phylo4}(object) } \arguments{ \item{object}{an object inheriting from class \code{phylo4}} } \value{ Logical value } \description{ Methods to test whether trees have (structural) polytomies, inline nodes (i.e., nodes with a single descendant), or reticulation (i.e., nodes with more than one ancestor). \code{hasPoly} only check for structural polytomies (1 node has more than 2 descendants) and not polytomies that result from having edges with a length of 0. } \note{ Some algorithms are unhappy with structural polytomies (i.e., >2 descendants from a node), with single-descendant nodes, or with reticulation; these functions check those properties. We haven't bothered to check for zero branch lengths: the consensus is that it doesn't come up much, and that it's simple enough to test \code{any(edgeLength(x) == 0)} in these cases. (Single-descendant nodes are used e.g. in OUCH, or in other cases to represent events occurring along a branch.) } \examples{ tree.owls.bis <- ape::read.tree(text="((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3);") owls4 <- as(tree.owls.bis, "phylo4") hasPoly(owls4) hasSingle(owls4) } \author{ Ben Bolker } \keyword{misc} phylobase/man/summary-methods.Rd0000644000176200001440000000473613075412470016455 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/summary-methods.R \docType{methods} \name{summary-methods} \alias{summary-methods} \alias{summary} \alias{summary,phylo4-method} \alias{summary,phylo4d-method} \alias{nodeType} \alias{nodeType,phylo4-method} \title{Summary for phylo4/phylo4d objects} \usage{ summary(object, ...) \S4method{summary}{phylo4}(object, quiet = FALSE) \S4method{summary}{phylo4d}(object, quiet = FALSE) nodeType(object) \S4method{nodeType}{phylo4}(object) } \arguments{ \item{object}{a phylo4d object} \item{\dots}{optional additional elements (not in use)} \item{quiet}{Should the summary be displayed on screen?} } \value{ The \code{nodeType} method returns named vector which has the type of node (internal, tip, root) for value, and the node number for name The \code{summary} method invisibly returns a list with the following components: \item{list("name")}{the name of the object} \item{list("nb.tips")}{the number of tips} \item{list("nb.nodes")}{the number of nodes} \item{list("mean.el")}{mean of edge lengths} \item{list("var.el")}{variance of edge lengths (estimate for population) } \item{list("sumry.el")}{summary (i.e. range and quartiles) of the edge lengths} \item{list("degree")}{(optional) type of polytomy for each node: \sQuote{node}, \sQuote{terminal} (all descendants are tips) or \sQuote{internal} (at least one descendant is an internal node); displayed only when there are polytomies} \item{list("sumry.tips")}{(optional) summary for the data associated with the tips} \item{list("sumry.nodes")}{(optional) summary for the data associated with the internal nodes} } \description{ Summary of information for the tree (\code{phylo4} only) and/or the associated data (\code{phylo4d}). } \examples{ tOwls <- "(((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3):6.3,Tyto_alba:13.5);" tree.owls <- ape::read.tree(text=tOwls) P1 <- as(tree.owls, "phylo4") P1 summary(P1) nodeType(P1) ## summary of a polytomous tree E <- matrix(c( 8, 9, 9, 10, 10, 1, 10, 2, 9, 3, 9, 4, 8, 11, 11, 5, 11, 6, 11, 7, 0, 8), ncol=2, byrow=TRUE) P2 <- phylo4(E) nodeLabels(P2) <- as.character(nodeId(P2, "internal")) plot(P2, show.node.label=TRUE) sumryP2 <- summary(P2) sumryP2 } \seealso{ \code{\link{phylo4d-methods}} constructor and \code{\linkS4class{phylo4d}} class. } \author{ Ben Bolker, Thibaut Jombart, Francois Michonneau } \keyword{methods} phylobase/man/root-methods.Rd0000644000176200001440000000173213075412470015734 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/root-methods.R \docType{methods} \name{isRooted} \alias{isRooted} \alias{isRooted,phylo4-method} \alias{rootNode} \alias{rootNode,phylo4-method} \alias{rootNode<-} \alias{rootNode<-} \alias{rootNode<-,phylo4-method} \title{Methods to test, access (and modify) the root of a phylo4 object.} \usage{ isRooted(x) \S4method{isRooted}{phylo4}(x) rootNode(x) \S4method{rootNode}{phylo4}(x) rootNode(x) <- value \S4method{rootNode}{phylo4}(x) <- value } \arguments{ \item{x}{a \code{phylo4} or \code{phylo4d} object.} \item{value}{a character string or a numeric giving the new root.} } \value{ \describe{ \item{isRooted}{logical whether the tree is rooted} \item{rootNode}{the node corresponding to the root} } } \description{ Methods to test, access (and modify) the root of a phylo4 object. } \examples{ data(geospiza) isRooted(geospiza) rootNode(geospiza) } \author{ Ben Bolker, Francois Michonneau } phylobase/man/phylo4-methods.Rd0000644000176200001440000001015013075412470016162 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/phylo4-methods.R \docType{methods} \name{phylo4-methods} \alias{phylo4-methods} \alias{phylo4} \alias{phylo4_orderings} \alias{phylo4,matrix-method} \alias{phylo4,phylo-method} \alias{phylo4,nexml-method} \alias{nexml,phylo4-method} \title{Create a phylogenetic tree} \format{An object of class \code{character} of length 5.} \usage{ phylo4(x, ...) phylo4_orderings \S4method{phylo4}{matrix}(x, edge.length = NULL, tip.label = NULL, node.label = NULL, edge.label = NULL, order = "unknown", annote = list()) \S4method{phylo4}{phylo}(x, check.node.labels = c("keep", "drop"), annote = list()) \S4method{phylo4}{nexml}(x) } \arguments{ \item{x}{a matrix of edges or an object of class \code{phylo} (see above)} \item{\dots}{optional arguments (none used at present).} \item{edge.length}{Edge (branch) length. (Optional)} \item{tip.label}{A character vector of species names (names of "tip" nodes). (Optional)} \item{node.label}{A character vector of internal node names. (Optional)} \item{edge.label}{A character vector of edge (branch) names. (Optional)} \item{order}{character: tree ordering (allowable values are listed in \code{phylo4_orderings}, currently "unknown", "preorder" (="cladewise" in \code{ape}), and "postorder", with "cladewise" and "pruningwise" also allowed for compatibility with \code{ape})} \item{annote}{any additional annotation data to be passed to the new object} \item{check.node.labels}{if \code{x} is of class \code{phylo}, either "keep" (the default) or "drop" node labels. This argument is useful if the \code{phylo} object has non-unique node labels.} \item{edge}{A numeric, two-column matrix with as many rows as branches in the phylogeny.} } \description{ \code{phylo4} is a generic constructor that creates a phylogenetic tree object for use in phylobase methods. Phylobase contains functions for input of phylogenetic trees and data, manipulation of these objects including pruning and subsetting, and plotting. The phylobase package also contains translation functions to forms used in other comparative phylogenetic method packages. } \details{ The minimum information necessary to create a phylobase tree object is a valid edge matrix. The edge matrix describes the topology of the phylogeny. Each row describes a branch of the phylogeny, with the (descendant) node number in column 2 and its ancestor's node number in column 1. These numbers are used internally and must be unique for each node. The labels designate either nodes or edges. The vector \code{node.label} names internal nodes, and together with \code{tip.label}, name all nodes in the tree. The vector \code{edge.label} names all branches in the tree. All label vectors are optional, and if they are not given, internally-generated labels will be assigned. The labels, whether user-specified or internally generated, must be unique as they are used to join species data with phylogenetic trees. \code{phylobase} also allows to create \code{phylo4} objects using the function \code{phylo4()} from objects of the classes: \code{phylo} (from \code{ape}), and \code{nexml} (from \code{RNeXML}). } \note{ Translation functions are available from many valid tree formats. See \link{coerce-methods}. } \examples{ # a three species tree: mytree <- phylo4(x=matrix(data=c(4,1, 4,5, 5,2, 5,3, 0,4), ncol=2, byrow=TRUE), tip.label=c("speciesA", "speciesB", "speciesC")) mytree plot(mytree) # another way to specify the same tree: mytree <- phylo4(x=cbind(c(4, 4, 5, 5, 0), c(1, 5, 2, 3, 4)), tip.label=c("speciesA", "speciesB", "speciesC")) # another way: mytree <- phylo4(x=rbind(c(4, 1), c(4, 5), c(5, 2), c(5, 3), c(0, 4)), tip.label=c("speciesA", "speciesB", "speciesC")) # with branch lengths: mytree <- phylo4(x=rbind(c(4, 1), c(4, 5), c(5, 2), c(5, 3), c(0, 4)), tip.label=c("speciesA", "speciesB", "speciesC"), edge.length=c(1, .2, .8, .8, NA)) plot(mytree) } \seealso{ \code{\link{coerce-methods}} for translation functions. The \linkS4class{phylo4} class. See also the \code{\link{phylo4d-methods}} constructor, and \linkS4class{phylo4d} class. } \author{ phylobase team } \keyword{datasets} phylobase/man/edges-accessors.Rd0000644000176200001440000000345513075412470016366 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/phylo4-accessors.R \docType{methods} \name{edges} \alias{edges} \alias{edges,phylo4-method} \alias{edgeOrder} \alias{edgeOrder,phylo4-method} \alias{internalEdges} \alias{internalEdges,phylo4-method} \alias{terminalEdges} \alias{terminalEdges,phylo4-method} \title{Edges accessors} \usage{ edges(x, ...) \S4method{edges}{phylo4}(x, drop.root = FALSE) edgeOrder(x, ...) \S4method{edgeOrder}{phylo4}(x) internalEdges(x) \S4method{internalEdges}{phylo4}(x) terminalEdges(x) \S4method{terminalEdges}{phylo4}(x) } \arguments{ \item{x}{a \code{phylo4} or \code{phylo4d} object.} \item{\dots}{Optional arguments used by specific methods. (None used at present).} \item{drop.root}{logical (default FALSE), should the edge connecting the root be included in the edge matrix?} } \value{ \describe{ \item{\code{edges}}{returns the edge matrix that represent the ancestor-descendant relationships among the nodes of the tree.} \item{\code{edgeOrder}}{returns the order in which the edge matrix is in.} \item{\code{internalEdges}}{returns a logical vector indicating internal edges (edges that connect an internal node to another). This vector is named with the \code{edgeId}}. \item{\code{terminalEdges}}{returns a logical vector indicating terminal edges (edges that connect an internal node to a tip). This vector is named with the \code{edgeId} }} } \description{ Access or modify information about the edges. } \examples{ data(geospiza) edges(geospiza) edgeOrder(geospiza) geoPost <- reorder(geospiza, "postorder") edgeOrder(geoPost) ## with a binary tree this should always be true identical(!terminalEdges(geospiza), internalEdges(geospiza)) } \seealso{ reorder, edgeId } \author{ Ben Bolker, Francois Michonneau, Thibaut Jombart } phylobase/man/addData-methods.Rd0000644000176200001440000000504413075412470016273 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/addData-methods.R \docType{methods} \name{addData} \alias{addData} \alias{addData,phylo4d-method} \alias{addData-methods} \alias{addData,phylo4-method} \alias{addData,phylo4-method} \alias{addData,phylo4d-method} \title{Adding data to a phylo4 or a phylo4d object} \usage{ addData(x, ...) \S4method{addData}{phylo4d}(x, tip.data = NULL, node.data = NULL, all.data = NULL, merge.data = TRUE, pos = c("after", "before"), ...) \S4method{addData}{phylo4}(x, tip.data = NULL, node.data = NULL, all.data = NULL, merge.data = TRUE, pos = c("after", "before"), ...) } \arguments{ \item{x}{a phylo4 or a phylo4d object} \item{\dots}{additional arguments to control how matching between data and tree (see Details section of \code{\link{phylo4d-methods}} for more details).} \item{tip.data}{a data frame (or object to be coerced to one) containing only tip data} \item{node.data}{a data frame (or object to be coerced to one) containing only node data} \item{all.data}{a data frame (or object to be coerced to one) containing both tip and node data} \item{merge.data}{if both \code{tip.data} and \code{node.data} are provided, it determines whether columns with common names will be merged together (default TRUE). If FALSE, columns with common names will be preserved separately, with ".tip" and ".node" appended to the names. This argument has no effect if \code{tip.data} and \code{node.data} have no column names in common.} \item{pos}{should the new data provided be bound \code{before} or \code{after} the pre-existing data?} } \value{ \code{addData} returns a \code{phylo4d} object. } \description{ \code{addData} adds data to a \code{phylo4} (converting it in a \code{phylo4d} object) or to a \code{phylo4d} object } \details{ Rules for matching data to tree nodes are identical to those used by the \code{\link{phylo4d-methods}} constructor. If any column names in the original data are the same as columns in the new data, ".old" is appended to the former column names and ".new" is appended to the new column names. The option \code{pos} is ignored (silently) if \code{x} is a \code{phylo4} object. It is provided for compatibility reasons. } \examples{ data(geospiza) nDt <- data.frame(a=rnorm(nNodes(geospiza)), b=1:nNodes(geospiza), row.names=nodeId(geospiza, "internal")) t1 <- addData(geospiza, node.data=nDt) } \seealso{ \code{\link{tdata}} for extracting or updating data and \code{\link{phylo4d-methods}} constructor. } \author{ Francois Michonneau } \keyword{methods} phylobase/man/owls4.Rd0000644000176200001440000000075713075412470014366 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/phylobase-package.R \docType{data} \name{owls4} \alias{owls4} \title{'Owls' data from ape} \format{This is the standard 'owls' tree from the \code{ape} package, in \code{phylo4} format.} \source{ From various examples in the \code{ape} package } \description{ A tiny tree, for testing/example purposes, using one of the examples from the \code{ape} package } \examples{ data(owls4) plot(owls4) } \keyword{datasets} phylobase/man/tdata-methods.Rd0000644000176200001440000000670513075412470016053 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/tdata-methods.R \docType{methods} \name{tdata} \alias{tdata} \alias{tdata,phylo4d-method} \alias{tdata<-} \alias{tdata<-} \alias{tdata<-,phylo4d-method} \alias{tdata<-,phylo4d,ANY-method} \alias{tipData} \alias{tipData-method} \alias{tipData} \alias{tipData,phylo4d-method} \alias{tipData<-} \alias{tipData<-} \alias{tipData<-,phylo4d-method} \alias{tipData<-,phylo4d,ANY-method} \alias{nodeData} \alias{nodeData-method} \alias{nodeData} \alias{nodeData,phylo4d-method} \alias{nodeData<-} \alias{nodeData<-} \alias{nodeData<-,phylo4d-method} \alias{nodeData<-,phylo4d,ANY-method} \title{Retrieving or updating tip and node data in phylo4d objects} \usage{ tdata(x, ...) \S4method{tdata}{phylo4d}(x, type = c("all", "tip", "internal"), label.type = c("row.names", "column"), empty.columns = TRUE) tdata(x, ...) <- value \S4method{tdata}{phylo4d}(x, type = c("all", "tip", "internal"), merge.data = TRUE, clear.all = FALSE, ...) <- value tipData(x, ...) \S4method{tipData}{phylo4d}(x, ...) tipData(x, ...) <- value \S4method{tipData}{phylo4d}(x, ...) <- value nodeData(x, ...) \S4method{nodeData}{phylo4d}(x, ...) nodeData(x, ...) <- value \S4method{nodeData}{phylo4d}(x, ...) <- value } \arguments{ \item{x}{A \code{phylo4d} object} \item{\dots}{For the \code{tipData} and \code{nodeData} accessors, further arguments to be used by \code{tdata}. For the replacement forms, further arguments to be used to control matching between tree and data (see Details section of \code{\link{phylo4d-methods}}).} \item{type}{The type of data to retrieve or update: \dQuote{\code{all}} (default) for data associated with both tip and internal nodes, \dQuote{\code{tip}} for data associated with tips only, \dQuote{\code{internal}} for data associated with internal nodes only.} \item{label.type}{How should the tip/node labels from the tree be returned? \dQuote{\code{row.names}} returns them as row names of the data frame, \dQuote{\code{column}} returns them in the first column of the data frame. This options is useful in the case of missing (\code{NA}) or non-unique labels.} \item{empty.columns}{Should columns filled with \code{NA} be returned?} \item{value}{a data frame (or object to be coerced to one) to replace the values associated with the nodes specified by the argument \code{type}} \item{merge.data}{if tip or internal node data are provided and data already exists for the other type, this determines whether columns with common names will be merged together (default TRUE). If FALSE, columns with common names will be preserved separately, with \dQuote{.tip} and \dQuote{.node} appended to the names. This argument has no effect if tip and node data have no column names in common, or if type=\dQuote{all}.} \item{clear.all}{If only tip or internal node data are to be replaced, should data of the other type be dropped?} } \value{ \code{tdata} returns a data frame } \description{ Methods to retrieve or update tip, node or all data associated with a phylogenetic tree stored as a phylo4d object } \section{Methods}{ \describe{ \item{tdata}{\code{signature(object="phylo4d")}: retrieve or update data associated with a tree in a \code{phylo4d} object} } } \examples{ data(geospiza) tdata(geospiza) tipData(geospiza) <- 1:nTips(geospiza) tdata(geospiza) } \seealso{ \code{\link{phylo4d-methods}}, \code{\linkS4class{phylo4d}} } \author{ Ben Bolker, Thibaut Jombart, Francois Michonneau } \keyword{methods} phylobase/man/shortestPath-methods.Rd0000644000176200001440000000207613075412470017443 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/shortestPath-methods.R \docType{methods} \name{shortestPath} \alias{shortestPath} \alias{shortestPath-phylo4} \alias{shortestPath,phylo4-method} \alias{shortestPath-phylo} \alias{shortestPath,phylo-method} \title{shortestPath-methods} \usage{ shortestPath(x, node1, node2) \S4method{shortestPath}{phylo4}(x, node1, node2) \S4method{shortestPath}{phylo}(x, node1, node2) } \arguments{ \item{x}{a tree in the phylo4, phylo4d or phylo format} \item{node1}{a numeric or character (passed to \code{getNode}) indicating the beginning from which the path should be calculated.} \item{node2}{a numeric or character (passed to \code{getNode}) indicating the end of the path.} } \value{ a vector of nodes indcating the shortest path between 2 nodes } \description{ Finds the shortest path between two nodes in a tree } \details{ Given two nodes (i.e, tips or internal nodes), this function returns the shortest path between them (excluding \code{node1} and \code{node2} as a vector of nodes. } \seealso{ getNode } phylobase/man/MRCA.Rd0000644000176200001440000000230713075412470014031 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MRCA-methods.R \docType{methods} \name{MRCA} \alias{MRCA} \alias{MRCA,phylo4-method} \alias{MRCA,phylo-method} \title{MRCA} \usage{ MRCA(phy, ...) \S4method{MRCA}{phylo4}(phy, ...) \S4method{MRCA}{phylo}(phy, ...) } \arguments{ \item{phy}{a phylogenetic tree in phylo4, phylo4d or phylo format.} \item{...}{a vector of nodes} } \value{ the node corresponding to the most recent common ancestor } \description{ Most Recent Common Ancestor (MRCA) of 2 or more nodes. } \details{ Given some nodes (i.e., tips and/or internal), this function returns the node corresponding to the most recent common ancestor. If \code{phy} is a \code{phylo4} or \code{phylo4d} object, the nodes can contain both numeric or character values that will be used by \code{getNode} to retrieve the correct node. However, if \code{phy} is a \code{phylo} object, the nodes must be a numeric vector. With \code{phylo4} and \code{phylo4d} objects, if a single node is provided, it will be returned. } \examples{ data(geospiza) MRCA(geospiza, 1, 5) MRCA(geospiza, "fortis", 11) MRCA(geospiza, 2, 4, "fusca", 3) geo <- as(geospiza, "phylo") MRCA(geo, c(1,5)) } phylobase/man/extractTree.Rd0000644000176200001440000000237413075412470015605 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/extractTree.R \name{extractTree} \alias{extractTree} \title{Get tree from tree+data object} \usage{ extractTree(from) } \arguments{ \item{from}{a \code{phylo4d} object, containing a phylogenetic tree plus associated phenotypic data. Created by the \code{phylo4d()} function.} } \description{ Extracts a \code{phylo4} tree object from a \code{phylo4d} tree+data object. } \details{ \code{extractTree} extracts just the phylogeny from a tree+data object. The phylogeny contains the topology (how the nodes are linked together), the branch lengths (if any), and any tip and/or node labels. This may be useful for extracting a tree from a \code{phylo4d} object, and associating with another phenotypic dataset, or to convert the tree to another format. } \examples{ tree.phylo <- ape::read.tree(text = "((a,b),c);") tree <- as(tree.phylo, "phylo4") plot(tree) tip.data <- data.frame(size = c(1, 2, 3), row.names = c("a", "b", "c")) (treedata <- phylo4d(tree, tip.data)) plot(treedata) (tree1 <- extractTree(treedata)) plot(tree1) } \seealso{ \code{\link{phylo4-methods}}, \code{\link{phylo4d-methods}}, \code{\link{coerce-methods}} for translation functions. } \author{ Ben Bolker } \keyword{methods} phylobase/man/geospiza.Rd0000644000176200001440000000133313075412470015126 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/phylobase-package.R \docType{data} \name{geospiza} \alias{geospiza} \alias{geospiza_raw} \title{Data from Darwin's finches} \format{\code{geospiza} is a \code{phylo4d} object; \code{geospiza_raw} is a list containing \code{tree}, a \code{phylo} object (the tree), \code{data}, and a data frame with the data (for showing examples of how to merge tree and data)} \source{ Dolph Schluter via Luke Harmon } \description{ Phylogenetic tree and morphological data for Darwin's finches, in different formats } \note{ Stolen from Luke Harmon's Geiger package, to avoid unnecessary dependencies } \examples{ data(geospiza) plot(geospiza) } \keyword{datasets} phylobase/man/phylomat-class.Rd0000644000176200001440000000335713075412470016255 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/phylomats-class.R \docType{class} \name{phylomat-class} \alias{phylomat-class} \alias{phylo4vcov-class} \alias{as_phylo4vcov} \alias{phylomat-setAs} \alias{setAs,phylo,phylo4vcov-method} \alias{phylomat-setAs} \alias{setAs,phylo4vcov,phylo4-method} \title{matrix classes for phylobase} \arguments{ \item{from}{a \code{phylo4} object} \item{\dots}{optional arguments, to be passed to \code{vcov.phylo} in \code{ape} (the main useful option is \code{cor}, which can be set to \code{TRUE} to compute a correlation rather than a variance-covariance matrix)} } \description{ Classes representing phylogenies as matrices } \section{Objects from the Class}{ These are square matrices (with rows and columns corresponding to tips, and internal nodes implicit) with different meanings depending on the type (variance-covariance matrix, distance matrix, etc.). } \examples{ tree_string <- "(((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3):6.3,Tyto_alba:13.5);" tree.owls <- ape::read.tree(text=tree_string) o2 <- as(tree.owls,"phylo4") ov <- as(o2,"phylo4vcov") o3 <- as(ov,"phylo4") ## these are not completely identical, but are ## topologically identical ... ## edge matrices are in a different order: ## cf. edges(o2) and edges(o3) ## BUT the edge matrices are otherwise identical o2edges <- edges(o2) o3edges <- edges(o3) identical(o2edges[order(o2edges[,2]),], o3edges[order(o3edges[,2]),]) ## There is left/right ambiguity here in the tree orders: ## in o2 the 5->6->7->1 lineage ## (terminating in Strix aluco) ## is first, in o3 the 5->6->3 lineage ## (terminating in Athene noctua) is first. } \author{ Ben Bolker } \keyword{classes} phylobase/man/tip.data.plot.Rd0000644000176200001440000000265713075412470016000 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/treePlot.R \name{tip.data.plot} \alias{tip.data.plot} \title{Plotting trees and associated data} \usage{ tip.data.plot(xxyy, type = c("phylogram", "cladogram", "fan"), show.tip.label = TRUE, show.node.label = FALSE, rot = 0, tip.plot.fun = grid.points, edge.color = "black", node.color = "black", tip.color = "black", edge.width = 1, ...) } \arguments{ \item{xxyy}{A list created by the \code{\link{phyloXXYY}} function} \item{type}{A character string indicating the shape of plotted tree} \item{show.tip.label}{Logical, indicating whether tip labels should be shown} \item{show.node.label}{Logical, indicating whether node labels should be shown} \item{rot}{Numeric indicating the rotation of the plot in degrees} \item{tip.plot.fun}{A function used to plot the data elements of a \code{phylo4d} object} \item{edge.color}{A vector of colors in the order of \code{edges(phy)}} \item{node.color}{A vector of colors indicating the colors of the node labels} \item{tip.color}{A vector of colors indicating the colors of the tip labels} \item{edge.width}{A vector in the order of \code{edges(phy)} indicating the widths of edge lines} \item{\dots}{Additional parameters passed to \code{tip.plot.fun}} } \value{ creates a plot on the current graphics device. } \description{ Plotting phylogenetic trees and associated data } \author{ Peter Cowan } \keyword{methods} phylobase/man/phylobubbles.Rd0000644000176200001440000000347413075412470016007 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/treePlot.R \name{phylobubbles} \alias{phylobubbles} \title{Bubble plots for phylo4d objects} \usage{ phylobubbles(type = type, place.tip.label = "right", show.node.label = show.node.label, rot = 0, edge.color = edge.color, node.color = node.color, tip.color = tip.color, edge.width = edge.width, newpage = TRUE, ..., XXYY, square = FALSE, grid = TRUE) } \arguments{ \item{type}{the type of plot} \item{place.tip.label}{A string indicating whether labels should be plotted to the right or to the left of the bubble plot} \item{show.node.label}{A logical indicating whether internal node labels should be plotted} \item{rot}{The number of degrees that the plot should be rotated} \item{edge.color}{A vector of colors for the tree edge segments} \item{node.color}{A vector of colors for the coloring the nodes} \item{tip.color}{A vector of colors for the coloring the tip labels} \item{edge.width}{A vector of line widths for the tree edges} \item{newpage}{Logical to control whether the device is cleared before plotting, useful for adding plot inside other plots} \item{\dots}{Additional parameters passed to the bubble plotting functions} \item{XXYY}{The out put from the phyloXXYY function} \item{square}{Logical indicating whether the plot 'bubbles' should be squares} \item{grid}{A logical indicating whether a grey grid should be plotted behind the bubbles} } \description{ Plots either circles or squares corresponding to the magnitude of each cell of a \code{phylo4d} object. } \examples{ ##---- Should be DIRECTLY executable !! ---- ##-- ==> Define data, use random, ##-- or do help(data=index) for the standard data sets. } \seealso{ \code{\link{phyloXXYY}}, \code{treePlot} } \author{ Peter Cowan \email{pdc@berkeley.edu} } \keyword{methods} phylobase/man/setAs-methods.Rd0000644000176200001440000000407013075412470016026 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/setAs-methods.R \docType{methods} \name{setAs} \alias{setAs} \alias{as} \alias{as-method} \alias{as,phylo,phylo4-method} \alias{setAs} \alias{as,phylo,phylo4d-method} \alias{setAs} \alias{as,nexml,phylo4-method} \alias{setAs} \alias{as,nexml,phylo4d-method} \alias{setAs} \alias{as,phylo4,phylo-method} \alias{setAs} \alias{setAs,phylo4,phylog-method} \alias{setAs} \alias{setAs,phylo4,data.frame-method} \title{Converting between phylo4/phylo4d and other phylogenetic tree formats} \description{ Translation functions to convert between phylobase objects (\code{phylo4} or \code{phylo4d}), and objects used by other comparative methods packages in R: \code{ape} objects (\code{phylo}, \code{multiPhylo}), \code{RNeXML} object (\code{nexml}), \code{ade4} objects (\code{phylog}, \emph{now deprecated}), and to \code{data.frame} representation. } \section{Usage}{ \code{as(object, class)} } \examples{ tree_string <- "(((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3):6.3,Tyto_alba:13.5);" tree.owls <- ape::read.tree(text=tree_string) ## round trip conversion tree_in_phylo <- tree.owls # tree is a phylo object (tree_in_phylo4 <- as(tree.owls,"phylo4")) # phylo converted to phylo4 identical(tree_in_phylo,as(tree_in_phylo4,"phylo")) ## test if phylo, and phylo4 converted to phylo are identical ## (no, because of dimnames) ## Conversion to phylog (ade4) as(tree_in_phylo4, "phylog") ## Conversion to data.frame as(tree_in_phylo4, "data.frame") ## Conversion to phylo (ape) as(tree_in_phylo4, "phylo") ## Conversion to phylo4d, (data slots empty) as(tree_in_phylo4, "phylo4d") } \seealso{ generic \code{\link[methods]{as}}, \code{\link{phylo4-methods}}, \code{\link{phylo4d-methods}}, \code{\link{extractTree}}, \code{nexml} class from the \code{RNeXML} package, \code{\link[ade4]{phylog}} from the \code{ade4} package and \code{\link[ape]{as.phylo}} from the \code{ape} package. } \author{ Ben Bolker, Thibaut Jombart, Marguerite Butler, Steve Kembel, Francois Michonneau } \keyword{methods} phylobase/man/plotOneTree.Rd0000644000176200001440000000341313075412470015546 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/treePlot.R \name{plotOneTree} \alias{plotOneTree} \title{Plot a phylo4 object} \usage{ plotOneTree(xxyy, type, show.tip.label, show.node.label, edge.color, node.color, tip.color, edge.width, rot) } \arguments{ \item{xxyy}{A list created by the \code{\link{phyloXXYY}} function} \item{type}{A character string indicating the shape of plotted tree} \item{show.tip.label}{Logical, indicating whether tip labels should be shown} \item{show.node.label}{Logical, indicating whether node labels should be shown} \item{edge.color}{A vector of colors in the order of \code{edges(phy)}} \item{node.color}{A vector of colors indicating the colors of the node labels} \item{tip.color}{A vector of colors indicating the colors of the tip labels} \item{edge.width}{A vector in the order of \code{edges(phy)} indicating the widths of edge lines} \item{rot}{Numeric indicating the rotation of the plot in degrees} } \value{ Returns no values, function invoked for the plotting side effect. } \description{ Plots the phylogenetic tree contained in a \code{phylo4} or \code{phylo4d} object. } \examples{ library(grid) data(geospiza) grid.newpage() xxyy <- phyloXXYY(geospiza) plotOneTree(xxyy, type = 'phylogram', show.tip.label = TRUE, show.node.label = TRUE, edge.color = 'black', node.color = 'orange', tip.color = 'blue', edge.width = 1, rot = 0 ) grid.newpage() pushViewport(viewport(w = 0.8, h = 0.8)) plotOneTree(xxyy, type = 'phylogram', show.tip.label = TRUE, show.node.label = TRUE, edge.color = 'black', node.color = 'orange', tip.color = 'blue', edge.width = 1, rot = 0 ) popViewport() } \seealso{ \code{treePlot}, \code{\link{phyloXXYY}} } \author{ Peter Cowan \email{pdc@berkeley.edu} } \keyword{methods} phylobase/man/subset-methods.Rd0000644000176200001440000001544013075427627016271 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/subset-methods.R \docType{methods} \name{subset-methods} \alias{subset-methods} \alias{subset} \alias{subset,phylo4-method} \alias{[} \alias{[,phylo4,character,missing,missing-method} \alias{[,phylo4,numeric,missing,missing-method} \alias{[,phylo4,logical,missing,missing-method} \alias{[,phylo4,missing,missing,missing-method} \alias{[,phylo4d,ANY,character,missing-method} \alias{[,phylo4d,ANY,numeric,missing-method} \alias{[,phylo4d,ANY,logical,missing-method} \alias{[,phylo4,ANY,ANY,ANY-method} \alias{prune} \alias{prune,phylo4-method} \alias{prune,phylo4d-method} \title{Methods for creating subsets of phylogenies} \usage{ subset(x, ...) \S4method{subset}{phylo4}(x, tips.include = NULL, tips.exclude = NULL, mrca = NULL, node.subtree = NULL, ...) "["(x, i, j, ..., drop = TRUE) \S4method{[}{phylo4,character,missing,missing}(x, i, j, ..., drop = TRUE) \S4method{[}{phylo4,numeric,missing,missing}(x, i, j, ..., drop = TRUE) \S4method{[}{phylo4,logical,missing,missing}(x, i, j, ..., drop = TRUE) \S4method{[}{phylo4,missing,missing,missing}(x, i, j, ..., drop = TRUE) \S4method{[}{phylo4d,ANY,character,missing}(x, i, j, ..., drop = TRUE) \S4method{[}{phylo4d,ANY,numeric,missing}(x, i, j, ..., drop = TRUE) \S4method{[}{phylo4d,ANY,logical,missing}(x, i, j, ..., drop = TRUE) \S4method{[}{phylo4,ANY,ANY,ANY}(x, i, j, ..., drop = TRUE) prune(x, ...) \S4method{prune}{phylo4}(x, tips.exclude, trim.internal = TRUE) \S4method{prune}{phylo4d}(x, tips.exclude, trim.internal = TRUE) } \arguments{ \item{x}{an object of class \code{"phylo4"} or \code{"phylo4d"}} \item{\dots}{optional additional parameters (not in use)} \item{tips.include}{A vector of tips to include in the subset tree} \item{tips.exclude}{A vector of tips to exclude from the subset tree} \item{mrca}{A vector of nodes for determining the most recent common ancestor, which is then used as the root of the subset tree} \item{node.subtree}{A single internal node specifying the root of the subset tree} \item{i}{(\code{[} method) An index vector indicating tips to include} \item{j}{(\code{[} method, phylo4d only) An index vector indicating columns of node/tip data to include} \item{drop}{(not in use: for compatibility with the generic method)} \item{trim.internal}{A logical specifying whether to remove internal nodes that no longer have tip descendants in the subset tree} } \value{ an object of class \code{"phylo4"} or \code{"phylo4d"} } \description{ Methods for creating subsets of phylogenies, based on pruning a tree to include or exclude a set of terminal taxa, to include all descendants of the MRCA of multiple taxa, or to return a subtree rooted at a given node. } \details{ The \code{subset} methods must be called using no more than one of the four main subsetting criteria arguments (\code{tips.include}, \code{tips.exclude}, \code{mrca}, or \code{node.subtree}). Each of these arguments can be either character or numeric. In the first case, they are treated as node labels; in the second case, they are treated as node numbers. For the first two arguments, any supplied tips not found in the tree (\code{tipLabels(x)}) will be ignored, with a warning. Similarly, for the \code{mrca} argument, any supplied tips or internal nodes not found in the tree will be ignored, with a warning. For the \code{node.subtree} argument, failure to provide a single, valid internal node will result in an error. Although \code{prune} is mainly intended as the workhorse function called by \code{subset}, it may also be called directly. In general it should be equivalent to the \code{tips.exclude} form of \code{subset} (although perhaps with less up-front error checking). The "[" operator, when used as \code{x[i]}, is similar to the \code{tips.include} form of \code{subset}. However, the indices used with this operator can also be logical, in which case the corresponding tips are assumed to be ordered as in \code{nodeId(x, "tip")}, and recycling rules will apply (just like with a vector or a matrix). With a \linkS4class{phylo4d} object 'x', \code{x[i,j]} creates a subset of \code{x} taking \code{i} for a tip index and \code{j} for the index of data variables in \code{tdata(geospiza, "all")}. Note that the second index is optional: \code{x[i, TRUE]}, \code{x[i,]}, and \code{x[i]} are all equivalent. Regardless of which approach to subsetting is used, the argument values must be such that at least two tips are retained. If the most recent common ancestor of the retained tips is not the original root node, then the root node of the subset tree will be a descendant of the original root. For rooted trees with non-NA root edge length, this has implications for the new root edge length. In particular, the new length will be the summed edge length from the new root node back to the original root (including the original root edge). As an alternative, see the examples for a way to determine the length of the edge that was immediately ancestral to the new root node in the original tree. Note that the correspondance between nodes and labels (and data in the case of \linkS4class{phylo4d}) will be retained after all forms of subsetting. Beware, however, that the node numbers (IDs) will likely be altered to reflect the new tree topology, and therefore cannot be compared directly between the original tree and the subset tree. } \section{Methods}{ \describe{ \item{x = "phylo4"}{subset tree} \item{x = "phylo4d"}{subset tree and corresponding node and tip data} } } \examples{ data(geospiza) nodeLabels(geospiza) <- paste("N", nodeId(geospiza, "internal"), sep="") geotree <- extractTree(geospiza) ## "subset" examples tips <- c("difficilis", "fortis", "fuliginosa", "fusca", "olivacea", "pallida", "parvulus", "scandens") plot(subset(geotree, tips.include=tips)) plot(subset(geotree, tips.include=tips, trim.internal=FALSE)) plot(subset(geotree, tips.exclude="scandens")) plot(subset(geotree, mrca=c("scandens","fortis","pauper"))) plot(subset(geotree, node.subtree=18)) ## "prune" examples (equivalent to subset using tips.exclude) plot(prune(geotree, tips)) ## "[" examples (equivalent to subset using tips.include) plot(geotree[c(1:6,14)]) plot(geospiza[c(1:6,14)]) ## for phylo4d, subset both tips and data columns geospiza[c(1:6,14), c("wingL", "beakD")] ## note handling of root edge length: edgeLength(geotree)['0-15'] <- 0.1 geotree2 <- geotree[1:2] ## in subset tree, edge of new root extends back to the original root edgeLength(geotree2)['0-3'] ## edge length immediately ancestral to this node in the original tree edgeLength(geotree, MRCA(geotree, tipLabels(geotree2))) } \author{ Jim Regetz \email{regetz@nceas.ucsb.edu}\cr Steven Kembel \email{skembel@berkeley.edu}\cr Damien de Vienne \email{damien.de-vienne@u-psud.fr}\cr Thibaut Jombart \email{jombart@biomserv.univ-lyon1.fr} } \keyword{methods} phylobase/man/phylo4d-class.Rd0000644000176200001440000000162413075412470015776 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/phylo4d-class.R \docType{class} \name{phylo4d-class} \alias{phylo4d-class} \title{phylo4d class} \description{ S4 class for phylogenetic tree and data. } \section{Objects from the Class}{ Objects can be created from various trees and a data.frame using the constructor \code{phylo4d}, or using \code{new("phylo4d", \dots{})} for empty objects. } \examples{ example(read.tree, "ape") obj <- phylo4d(as(tree.owls.bis,"phylo4"), data.frame(wing=1:3)) obj names(obj) summary(obj) } \seealso{ \code{\link{coerce-methods}} for translation functions. The \code{\link{phylo4d-methods}} constructor. See also the \code{\link{phylo4-methods}} constructor, the \linkS4class{phylo4} class, and the \code{\link{checkPhylo4}} function to check the validity of \code{phylo4} trees. } \author{ Ben Bolker, Thibaut Jombart } \keyword{classes} phylobase/man/nodeId-methods.Rd0000644000176200001440000000232413075412470016151 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nodeId-methods.R \docType{methods} \name{nodeId} \alias{nodeId} \alias{nodeId,phylo4-method} \alias{edgeId} \alias{edgeId,phylo4-method} \title{nodeId methods} \usage{ nodeId(x, type = c("all", "tip", "internal", "root")) \S4method{nodeId}{phylo4}(x, type = c("all", "tip", "internal", "root")) edgeId(x, type = c("all", "tip", "internal", "root")) \S4method{edgeId}{phylo4}(x, type = c("all", "tip", "internal", "root")) } \arguments{ \item{x}{a \code{phylo4} or \code{phylo4d} object.} \item{type}{a character vector indicating which subset of the nodes or edges you are interested in.} } \value{ \describe{ \item{nodeId}{an integer vector indicating node numbers} \item{edgeId}{a character vector indicating the edge identity} } } \description{ These functions gives the node (\code{nodeId}) or edge (\code{edgeId}) identity. } \details{ \code{nodeId} returns the node in ascending order, and \code{edgeId} in the same order as the edges are stored in the edge matrix. } \examples{ data(geospiza) identical(nodeId(geospiza, "tip"), 1:nTips(geospiza)) nodeId(geospiza, "internal") edgeId(geospiza, "internal") nodeId(geospiza, "root") } phylobase/man/phylo4d-accessors.Rd0000644000176200001440000000411613075412470016655 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/phylo4d-accessors.R \docType{methods} \name{hasTipData} \alias{hasTipData} \alias{hasTipData,phylo4d-method} \alias{hasTipData-method,phylo4d-method} \alias{hasNodeData} \alias{hasNodeData-methods} \alias{hasNodeData,phylo4d-method} \alias{nData} \alias{nData,phylo4d-method} \title{Tests for presence of data associated with trees stored as phylo4d objects} \usage{ hasTipData(x) \S4method{hasTipData}{phylo4d}(x) hasNodeData(x) \S4method{hasNodeData}{phylo4d}(x) nData(x) \S4method{nData}{phylo4d}(x) } \arguments{ \item{x}{a \code{phylo4d} object} } \value{ \describe{ \item{\code{nData}}{returns the number of datasets (i.e., columns) associated with the object.} \item{\code{hasTipData}, \code{hasNodeData}}{return \code{TRUE} or \code{FALSE} depending whether data associated with the tree are associated with either tips or internal nodes respectively.}} } \description{ Methods that test for the presence of data associated with trees stored as \code{phylo4d} objects. } \details{ \code{nData} tests for the presence of data associated with the object. \code{hasTipData} and \code{hasNodeData} tests for the presence of data associated with the tips and the internal nodes respectively. The outcome of the test is based on row names of the data frame stored in the \code{data} slot. If no rows have names from the set \code{nodeId(x, "tip")}, then \code{hasTipData} returns FALSE. Likewise, if no rows have names from the set \code{nodeId(x, "internal")}, then \code{hasNodeData} returns FALSE. } \section{Methods}{ \describe{ \item{hasNodeData}{\code{signature(object = "phylo4d")}: whether tree has internal node data} \item{hasTipData}{\code{signature(object = "phylo4d")}: whether tree has data associated with its tips} } } \examples{ data(geospiza) nData(geospiza) ## 5 hasTipData(geospiza) ## TRUE hasNodeData(geospiza) ## FALSE } \seealso{ \code{\link{phylo4d-methods}} constructor and \code{\linkS4class{phylo4d}} class. } \author{ Ben Bolker, Thibault Jombart, Francois Michonneau } \keyword{methods} phylobase/man/multiPhylo-class.Rd0000644000176200001440000000120213075412470016551 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/multiphylo4-class.R \docType{class} \name{multiPhylo-class} \alias{multiPhylo-class} \alias{multiPhylo4-class} \alias{multiPhylo4d-class} \alias{tbind} \alias{multiPhylo-class} \alias{multiPhylo4-class} \alias{multiPhylo4d-class} \alias{tbind} \title{multiPhylo4 and extended classes} \description{ Classes for lists of phylogenetic trees. These classes and methods are planned for a future version of \code{phylobase}. Classes for lists of phylogenetic trees. These classes and methods are planned for a future version of \code{phylobase}. } \keyword{classes} phylobase/man/edgeLength-methods.Rd0000644000176200001440000001116213075412470017015 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/edgeLength-methods.R \docType{methods} \name{hasEdgeLength} \alias{hasEdgeLength} \alias{hasEdgeLength,phylo4-method} \alias{edgeLength} \alias{edgeLength,phylo4-method} \alias{edgeLength<-} \alias{edgeLength<-} \alias{edgeLength<-,phylo4-method} \alias{edgeLength<-,phylo4,ANY-method} \alias{depthTips} \alias{depthTips,phylo4-method} \alias{depthTips,phylo4-methods} \alias{nodeDepth} \alias{nodeDepth,phylo4-method} \alias{nodeHeight} \alias{nodeHeight,phylo4-method} \alias{sumEdgeLength} \alias{sumEdgeLength,phylo4-method} \alias{isUltrametric} \alias{isUltrametric,phylo4-method} \title{edgeLength methods} \usage{ hasEdgeLength(x) \S4method{hasEdgeLength}{phylo4}(x) edgeLength(x, ...) \S4method{edgeLength}{phylo4}(x, node) edgeLength(x, use.names = TRUE, ...) <- value \S4method{edgeLength}{phylo4}(x, use.names = TRUE, ...) <- value depthTips(x) \S4method{depthTips}{phylo4}(x) nodeDepth(x, node) \S4method{nodeDepth}{phylo4}(x, node) nodeHeight(x, node, from) \S4method{nodeHeight}{phylo4}(x, node, from = c("root", "all_tip", "min_tip", "max_tip")) sumEdgeLength(x, node) \S4method{sumEdgeLength}{phylo4}(x, node) isUltrametric(x, tol = .Machine$double.eps^0.5) \S4method{isUltrametric}{phylo4}(x, tol = .Machine$double.eps^0.5) } \arguments{ \item{x}{a \code{phylo4} or \code{phylo4d} object.} \item{\dots}{optional arguments (none used at present).} \item{node}{optional numeric or character vector indicating the nodes for which edge} \item{use.names}{should the the name attributes of \code{value} be used to match the length to a given edge.} \item{value}{a numeric vector indicating the new values for the edge lengths} \item{from}{The point of reference for calculating the height of the node. \code{root} calculates the distance between the root of the tree and the node. \code{all_tip} return the distance between the node and all the tips descending from it. \code{min_tip} the distance between the node and its closest tip. \code{max_tip} the distance between the node and its farther tip. \code{min_tip} and \code{max_tip} will be identical if the tree is ultrametric. If more than one tip is equidistant from the node, the tip with the lowest node id will be returned.} \item{tol}{the tolerance to decide whether all the tips have the same depth to test if the tree is ultrametric. Default is \code{.Machine$double.eps^0.5}.} } \value{ \describe{ \item{hasEdgeLength}{whether or not the object has edge lengths (logical)} \item{edgeLength}{a named vector of the edge length for the object} \item{isUltrametric}{whether or not the tree is ultrametric (all the tips are have the same depth (distance from the root) (logical)} \item{sumEdgeLength}{the sum of the edge lengths for a set of nodes (intended to be used with \code{ancestors} or \code{descendants})} \item{nodeHeight}{the distance between a node and the root or the tips. The format of the result will depend on the options and the number of nodes provided, either a vector or a list.} \item{nodeDepth}{Deprecated, now replaced by \code{nodeHeight}. A named vector indicating the \dQuote{depth} (the distance between the root and a given node).} \item{depthTip}{Deprecated, now replaced by \code{nodeHeight}.} } } \description{ These functions give information about and allow replacement of edge lengths. } \details{ The \code{edgeLength} function returns the edge length in the same order as the edges in the matrix. } \examples{ data(geospiza) hasEdgeLength(geospiza) # TRUE topoGeo <- geospiza edgeLength(topoGeo) <- NULL hasEdgeLength(topoGeo) # FALSE edgeLength(geospiza)[2] # use the position in vector edgeLength(geospiza)["16-17"] # or the name of the edge edgeLength(geospiza, 17) # or the descendant node of the edge ## The same methods can be used to update an edge length edgeLength(geospiza)[2] <- 0.33 edgeLength(geospiza)["16-17"] <- 0.34 edgeLength(geospiza, 17) <- 0.35 ## Test if tree is ultrametric isUltrametric(geospiza) # TRUE ## indeed all tips are at the same distance from the root nodeHeight(geospiza, nodeId(geospiza, "tip"), from="root") ## compare distances from tips of two MRCA nodeHeight(geospiza, MRCA(geospiza, c("pallida", "psittacula")), from="min_tip") nodeHeight(geospiza, MRCA(geospiza, c("fortis", "difficilis")), from="min_tip") ## or the same but from the root nodeHeight(geospiza, MRCA(geospiza, c("pallida", "psittacula")), from="root") nodeHeight(geospiza, MRCA(geospiza, c("fortis", "difficilis")), from="root") } \seealso{ \code{ancestors}, \code{descendants}, \code{.Machine} for more information about tolerance. } phylobase/man/phylo4d-methods.Rd0000644000176200001440000002530313075412470016334 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/phylo4d-methods.R \docType{methods} \name{phylo4d-methods} \alias{phylo4d-methods} \alias{phylo4d} \alias{phylo4d,phylo4-method} \alias{phylo4d,phylo4,phylo4-method} \alias{phylo4d,matrix-method} \alias{phylo4d,matrix,matrix-method} \alias{phylo4d,phylo-method} \alias{phylo4d,phylo,phylo-method} \alias{phylo4d,phylo4d-method} \alias{phylo4d,phylo4d,phylo4d-method} \alias{phylo4d,nexml-method} \alias{nexml,phylo4d-method} \title{Combine a phylogenetic tree with data} \usage{ phylo4d(x, ...) \S4method{phylo4d}{phylo4}(x, tip.data = NULL, node.data = NULL, all.data = NULL, merge.data = TRUE, metadata = list(), ...) \S4method{phylo4d}{matrix}(x, tip.data = NULL, node.data = NULL, all.data = NULL, merge.data = TRUE, metadata = list(), edge.length = NULL, tip.label = NULL, node.label = NULL, edge.label = NULL, order = "unknown", annote = list(), ...) \S4method{phylo4d}{phylo}(x, tip.data = NULL, node.data = NULL, all.data = NULL, check.node.labels = c("keep", "drop", "asdata"), annote = list(), metadata = list(), ...) \S4method{phylo4d}{phylo4d}(x, ...) \S4method{phylo4d}{nexml}(x) } \arguments{ \item{x}{an object of class \code{phylo4}, \code{phylo}, \code{nexml} or a matrix of edges (see above)} \item{\dots}{further arguments to control the behavior of the constructor in the case of missing/extra data and where to look for labels in the case of non-unique labels that cannot be stored as row names in a data frame (see Details).} \item{tip.data}{a data frame (or object to be coerced to one) containing only tip data (Optional)} \item{node.data}{a data frame (or object to be coerced to one) containing only node data (Optional)} \item{all.data}{a data frame (or object to be coerced to one) containing both tip and node data (Optional)} \item{merge.data}{if both \code{tip.data} and \code{node.data} are provided, should columns with common names will be merged together (default TRUE) or not (FALSE)? See details.} \item{metadata}{any additional metadata to be passed to the new object} \item{edge.length}{Edge (branch) length. (Optional)} \item{tip.label}{A character vector of species names (names of "tip" nodes). (Optional)} \item{node.label}{A character vector of internal node names. (Optional)} \item{edge.label}{A character vector of edge (branch) names. (Optional)} \item{order}{character: tree ordering (allowable values are listed in \code{phylo4_orderings}, currently "unknown", "preorder" (="cladewise" in \code{ape}), and "postorder", with "cladewise" and "pruningwise" also allowed for compatibility with \code{ape})} \item{annote}{any additional annotation data to be passed to the new object} \item{check.node.labels}{if \code{x} is of class \code{phylo}, use either \dQuote{keep} (the default) to retain internal node labels, \dQuote{drop} to drop them, or \dQuote{asdata} to convert them to numeric tree data. This argument is useful if the \code{phylo} object has non-unique node labels or node labels with informative data (e.g., posterior probabilities).} } \value{ An object of class \linkS4class{phylo4d}. } \description{ \code{phylo4d} is a generic constructor which merges a phylogenetic tree with data frames to create a combined object of class \code{phylo4d} } \details{ You can provide several data frames to define traits associated with tip and/or internal nodes. By default, data row names are used to link data to nodes in the tree, with any number-like names (e.g., \dQuote{10}) matched against node ID numbers, and any non-number-like names (e.g., \dQuote{n10}) matched against node labels. Alternative matching rules can be specified by passing additional arguments (listed in the Details section); these include positional matching, matching exclusively on node labels, and matching based on a column of data rather than on row names. Matching rules will apply the same way to all supplied data frames. This means that you need to be consistent with the row names of your data frames. It is good practice to use tip and node labels (or node numbers if you use duplicated labels) when you combine data with a tree. If you provide both \code{tip.data} and \code{node.data}, the treatment of columns with common names will depend on the \code{merge.data} argument. If TRUE, columns with the same name in both data frames will be merged; when merging columns of different data types, coercion to a common type will follow standard R rules. If \code{merge.data} is FALSE, columns with common names will be preserved independently, with \dQuote{.tip} and \dQuote{.node} appended to the names. This argument has no effect if \code{tip.data} and \code{node.data} have no column names in common. If you provide \code{all.data} along with either of \code{tip.data} and \code{node.data}, it must have distinct column names, otherwise an error will result. Additionally, although supplying columns with the same names \emph{within} data frames is not illegal, automatic renaming for uniqeness may lead to surprising results, so this practice should be avoided. This is the list of additional arguments that can be used to control matching between the tree and the data: \itemize{ \item{match.data}{(logical) should the rownames of the data frame be used to be matched against tip and internal node identifiers?} \item{rownamesAsLabels}{(logical), should the row names of the data provided be matched only to labels (TRUE), or should any number-like row names be matched to node numbers (FALSE and default)} \item{label.type}{character, \code{rownames} or \code{column}: should the labels be taken from the row names of \code{dt} or from the \code{label.column} column of \code{dt}?} \item{label.column}{iff \code{label.type=="column"}, column specifier (number or name) of the column containing tip labels} \item{missing.data}{action to take if there are missing data or if there are data labels that don't match} \item{extra.data}{action to take if there are extra data or if there are labels that don't match} \item{keep.all}{(logical), should the returned data have rows for all nodes (with NA values for internal rows when type='tip', and vice versa) (TRUE and default) or only rows corresponding to the type argument} } Rules for matching rows of data to tree nodes are determined jointly by the \code{match.data} and \code{rownamesAsLabels} arguments. If \code{match.data} is TRUE, data frame rows will be matched exclusively against tip and node labels if \code{rownamesAsLabels} is also TRUE, whereas any all-digit row names will be matched against tip and node numbers if \code{rownamesAsLabels} is FALSE (the default). If \code{match.data} is FALSE, \code{rownamesAsLabels} has no effect, and row matching is purely positional with respect to the order returned by \code{nodeId(phy, type)}. } \note{ Checking on matches between the tree and the data will be done by the validity checker (label matches between data and tree tips, number of rows of data vs. number of nodes/tips/etc.) } \section{Methods}{ \describe{ \item{x = "phylo4"}{merges a tree of class \code{phylo4} with a data.frame into a \code{phylo4d} object} \item{x = "matrix"}{merges a matrix of tree edges similar to the edge slot of a \code{phylo4} object (or to \$edge of a \code{phylo} object) with a data.frame into a \code{phylo4d} object} \item{x = "phylo"}{merges a tree of class \code{phylo} with a data.frame into a \code{phylo4d} object } } } \examples{ treeOwls <- "((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3);" tree.owls.bis <- ape::read.tree(text=treeOwls) try(phylo4d(as(tree.owls.bis,"phylo4"),data.frame(wing=1:3)), silent=TRUE) obj <- phylo4d(as(tree.owls.bis,"phylo4"),data.frame(wing=1:3), match.data=FALSE) obj print(obj) #### data(geospiza_raw) geoTree <- geospiza_raw$tree geoData <- geospiza_raw$data ## fix differences in tip names between the tree and the data geoData <- rbind(geoData, array(, dim = c(1,ncol(geoData)), dimnames = list("olivacea", colnames(geoData)))) ### Example using a tree of class 'phylo' exGeo1 <- phylo4d(geoTree, tip.data = geoData) ### Example using a tree of class 'phylo4' geoTree <- as(geoTree, "phylo4") ## some random node data rNodeData <- data.frame(randomTrait = rnorm(nNodes(geoTree)), row.names = nodeId(geoTree, "internal")) exGeo2 <- phylo4d(geoTree, tip.data = geoData, node.data = rNodeData) ### Example using 'merge.data' data(geospiza) trGeo <- extractTree(geospiza) tDt <- data.frame(a=rnorm(nTips(trGeo)), row.names=nodeId(trGeo, "tip")) nDt <- data.frame(a=rnorm(nNodes(trGeo)), row.names=nodeId(trGeo, "internal")) (matchData1 <- phylo4d(trGeo, tip.data=tDt, node.data=nDt, merge.data=FALSE)) (matchData2 <- phylo4d(trGeo, tip.data=tDt, node.data=nDt, merge.data=TRUE)) ## Example with 'all.data' nodeLabels(geoTree) <- as.character(nodeId(geoTree, "internal")) rAllData <- data.frame(randomTrait = rnorm(nTips(geoTree) + nNodes(geoTree)), row.names = labels(geoTree, 'all')) exGeo5 <- phylo4d(geoTree, all.data = rAllData) ## Examples using 'rownamesAsLabels' and comparing with match.data=FALSE tDt <- data.frame(x=letters[1:nTips(trGeo)], row.names=sample(nodeId(trGeo, "tip"))) tipLabels(trGeo) <- as.character(sample(1:nTips(trGeo))) (exGeo6 <- phylo4d(trGeo, tip.data=tDt, rownamesAsLabels=TRUE)) (exGeo7 <- phylo4d(trGeo, tip.data=tDt, rownamesAsLabels=FALSE)) (exGeo8 <- phylo4d(trGeo, tip.data=tDt, match.data=FALSE)) ## generate a tree and some data set.seed(1) p3 <- ape::rcoal(5) dat <- data.frame(a = rnorm(5), b = rnorm(5), row.names = p3$tip.label) dat.defaultnames <- dat row.names(dat.defaultnames) <- NULL dat.superset <- rbind(dat, rnorm(2)) dat.subset <- dat[-1, ] ## create a phylo4 object from a phylo object p4 <- as(p3, "phylo4") ## create phylo4d objects with tip data p4d <- phylo4d(p4, dat) ###checkData(p4d) p4d.sorted <- phylo4d(p4, dat[5:1, ]) try(p4d.nonames <- phylo4d(p4, dat.defaultnames)) p4d.nonames <- phylo4d(p4, dat.defaultnames, match.data=FALSE) \dontrun{ p4d.subset <- phylo4d(p4, dat.subset) p4d.subset <- phylo4d(p4, dat.subset) try(p4d.superset <- phylo4d(p4, dat.superset)) p4d.superset <- phylo4d(p4, dat.superset) } ## create phylo4d objects with node data nod.dat <- data.frame(a = rnorm(4), b = rnorm(4)) p4d.nod <- phylo4d(p4, node.data = nod.dat, match.data=FALSE) ## create phylo4 objects with node and tip data p4d.all1 <- phylo4d(p4, node.data = nod.dat, tip.data = dat, match.data=FALSE) nodeLabels(p4) <- as.character(nodeId(p4, "internal")) p4d.all2 <- phylo4d(p4, all.data = rbind(dat, nod.dat), match.data=FALSE) } \seealso{ \code{\link{coerce-methods}} for translation functions. The \linkS4class{phylo4d} class; \linkS4class{phylo4} class and \link{phylo4} constructor. } \author{ Ben Bolker, Thibaut Jombart, Steve Kembel, Francois Michonneau, Jim Regetz } \keyword{misc} phylobase/man/pdata.Rd0000644000176200001440000000135313075412470014400 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pdata.R \name{pdata} \alias{pdata} \alias{check_pdata} \title{Constructor for pdata (phylogenetic data) class} \usage{ pdata(data, type, comment, metadata) } \arguments{ \item{data}{a data frame} \item{type}{a factor with levels as specified by \linkS4class{pdata}, the same length as \code{ncol(data)}} \item{comment}{a character vector, the same length as \code{ncol(data)}} \item{metadata}{an arbitrary list} } \value{ An object of class \code{pdata} } \description{ Combine data, type, comments, and metadata information to create a new pdata object, or check such an object for consistency } \seealso{ \linkS4class{pdata} } \author{ Ben Bolker } \keyword{misc} phylobase/man/reorder-methods.Rd0000644000176200001440000000346013075412470016413 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/reorder-methods.R \docType{methods} \name{reorder-methods} \alias{reorder-methods} \alias{reorder} \alias{reorder,phylo4-method} \title{reordering trees within phylobase objects} \usage{ reorder(x, ...) \S4method{reorder}{phylo4}(x, order = c("preorder", "postorder")) } \arguments{ \item{x}{a \code{phylo4} or \code{phylo4d} object} \item{\dots}{additional optional elements (not in use)} \item{order}{The desired traversal order; currently only \dQuote{preorder} and \dQuote{postorder} are allowed for \code{phylo4} and \code{phylo4d} objects.} } \value{ A \code{phylo4} or \code{phylo4d} object with the edge, label, length and data slots ordered as \code{order}, which is itself recorded in the order slot. } \description{ Methods for reordering trees into various traversal orders } \details{ The \code{reorder} method takes a \code{phylo4} or \code{phylo4d} tree and orders the edge matrix (i.e. \code{edges(x)}) in the requested traversal order. Currently only two orderings are permitted, and both require rooted trees. In \code{postorder}, a node's descendants come before that node, thus the root, which is ancestral to all nodes, comes last. In \code{preorder}, a node is visited before its descendants, thus the root comes first. } \note{ The \code{preorder} parameter corresponds to \code{cladewise} in the \code{ape} package, and \code{postorder} corresponds (almost) to \code{pruningwise}. } \examples{ phy <- phylo4(ape::rtree(5)) edges(reorder(phy, "preorder")) edges(reorder(phy, "postorder")) } \seealso{ \code{\link[ape]{reorder.phylo}} in the \code{ape} package. \code{\link{ancestors}} \code{\link{ancestor}} \code{\link{siblings}} \code{\link{children}} \code{\link{descendants}} } \author{ Peter Cowan, Jim Regetz } \keyword{methods} phylobase/man/getNode-methods.Rd0000644000176200001440000001013413075412470016332 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/getNode-methods.R \docType{methods} \name{getNode} \alias{getNode} \alias{getNode,phylo4-method} \alias{getEdge} \alias{getEdge-methods} \alias{getEdge} \alias{getEdge,phylo4-method} \title{Node and Edge look-up functions} \usage{ getNode(x, node, type = c("all", "tip", "internal"), missing = c("warn", "OK", "fail")) \S4method{getNode}{phylo4}(x, node, type = c("all", "tip", "internal"), missing = c("warn", "OK", "fail")) getEdge(x, node, type = c("descendant", "ancestor"), missing = c("warn", "OK", "fail")) \S4method{getEdge}{phylo4}(x, node, type = c("descendant", "ancestor"), missing = c("warn", "OK", "fail")) } \arguments{ \item{x}{a \linkS4class{phylo4} object (or one inheriting from \linkS4class{phylo4}, e.g. a \linkS4class{phylo4d} object)} \item{node}{either an integer vector corresponding to node ID numbers, or a character vector corresponding to node labels; if missing, all nodes appropriate to the specified type will be returned by \code{getNode}, and all edges appropriate to the specified type will be returned by \code{getEdge}.} \item{type}{(\code{getNode}) specify whether to return nodes matching "all" tree nodes (default), only "tip" nodes, or only "internal" nodes; (\code{nodeId, edgeId}) specify whether to return "all" tree nodes, or only those corresponding to "tip", "internal", or "root" nodes; (\code{getEdge}) specify whether to look up edges based on their descendant node ("descendant") or ancestral node ("ancestor")} \item{missing}{what to do if some requested node IDs or names are not in the tree: warn, do nothing, or stop with an error} } \value{ \item{list("getNode")}{returns a named integer vector of node IDs, in the order of input nodes if provided, otherwise in nodeId order} \item{list("getEdge")}{returns a named character vector of edge IDs, in the order of input nodes if provide, otherwise in nodeId order} \item{list("nodeId")}{returns an unnamed integer vector of node IDs, in ascending order} \item{list("getEdge")}{returns an unnamed character vector of edge IDs, in edge matrix order} } \description{ Functions for retrieving node and edge IDs (possibly with corresponding labels) from a phylogenetic tree. } \details{ \code{getNode} and \code{getEdge} are primarily intended for looking up the IDs either of nodes themselves or of edges associated with those nodes. Note that they behave quite differently. With \code{getNode}, any input nodes are looked up against tree nodes of the specified type, and those that match are returned as numeric node IDs with node labels (if they exist) as element names. With \code{getEdge}, any input nodes are looked up against edge ends of the specified type, and those that match are returned as character edge IDs with the corresponding node ID as element names. If \code{missing} is \dQuote{warn} or \dQuote{OK}, \code{NA} is returned for any nodes that are unmatched for the specified type. This can provide a mechanism for filtering a set of nodes or edges. \code{nodeId} provides similar output to \code{getNode} in the case when no node is supplied, but it is faster and returns an unnamed vector of the numeric IDs of all nodes of the specified node type. Similarly, \code{edgeId} simply returns an unnamed vector of the character IDs of all edges for which the descendant node is of the specified node type. } \examples{ data(geospiza) nodeLabels(geospiza) <- LETTERS[1:nNodes(geospiza)] plot(as(geospiza, "phylo4"), show.node.label=TRUE) getNode(geospiza, 18) getNode(geospiza, "D") getEdge(geospiza, "D") getEdge(geospiza, "D", type="ancestor") ## match nodes only to tip nodes, flagging invalid cases as NA getNode(geospiza, c(1, 18, 999), type="tip", missing="OK") ## get all edges that descend from internal nodes getEdge(geospiza, type="ancestor") ## identify an edge from its terminal node getEdge(geospiza, c("olivacea", "B", "fortis")) getNode(geospiza, c("olivacea", "B", "fortis")) edges(geospiza)[c(26, 1, 11),] ## quickly get all tip node IDs and tip edge IDs nodeId(geospiza, "tip") edgeId(geospiza, "tip") } \keyword{misc} phylobase/man/phylobase.options.Rd0000644000176200001440000000211513075412470016764 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/phylobase.options.R \name{phylobase.options} \alias{phylobase.options} \title{Set or return options of phylobase} \usage{ phylobase.options(...) } \arguments{ \item{\dots}{a list may be given as the only argument, or any number of arguments may be in the \code{name=value} form, or no argument at all may be given. See the Value and Details sections for explanation.} } \value{ A list with the updated values of the parameters. If arguments are provided, the returned list is invisible. } \description{ Provides a mean to control the validity of \code{phylobase} objects such as singletons, reticulated trees, polytomies, etc. } \details{ The parameter values set via a call to this function will remain in effect for the rest of the session, affecting the subsequent behavior of phylobase. } \examples{ \dontrun{ phylobase.options(poly="fail") # subsequent trees with polytomies will fail the validity check } } \author{ Francois Michonneau (adapted from the package \code{sm}) } \keyword{phylobase} \keyword{validator} phylobase/man/formatData.Rd0000644000176200001440000000646113075412470015376 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/formatData.R \name{formatData} \alias{formatData} \title{Format data for use in phylo4d objects} \usage{ formatData(phy, dt, type = c("tip", "internal", "all"), match.data = TRUE, rownamesAsLabels = FALSE, label.type = c("rownames", "column"), label.column = 1, missing.data = c("fail", "warn", "OK"), extra.data = c("warn", "OK", "fail"), keep.all = TRUE) } \arguments{ \item{phy}{a valid \code{phylo4} object} \item{dt}{a data frame, matrix, vector, or factor} \item{type}{type of data to attach} \item{match.data}{(logical) should the rownames of the data frame be used to be matched against tip and internal node identifiers? See details.} \item{rownamesAsLabels}{(logical), should the row names of the data provided be matched only to labels (TRUE), or should any number-like row names be matched to node numbers (FALSE and default)} \item{label.type}{character, \code{rownames} or \code{column}: should the labels be taken from the row names of \code{dt} or from the \code{label.column} column of \code{dt}?} \item{label.column}{if \code{label.type=="column"}, column specifier (number or name) of the column containing tip labels} \item{missing.data}{action to take if there are missing data or if there are data labels that don't match} \item{extra.data}{action to take if there are extra data or if there are labels that don't match} \item{keep.all}{(logical), should the returned data have rows for all nodes (with NA values for internal rows when type='tip', and vice versa) (TRUE and default) or only rows corresponding to the type argument} } \value{ \code{formatData} returns a data frame having node numbers as row names. The data frame is also formatted to have the correct dimension given the \code{phylo4} object provided. } \description{ Associates data with tree nodes and applies consistent formatting rules. } \details{ \code{formatData} is an internal function that should not be called directly by the user. It is used to format data provided by the user before associating it with a tree, and is called internally by the \code{phylo4d}, \code{tdata}, and \code{addData} methods. However, users may pass additional arguments to these methods in order to control how the data are matched to nodes. Rules for matching rows of data to tree nodes are determined jointly by the \code{match.data} and \code{rownamesAsLabels} arguments. If \code{match.data} is TRUE, data frame rows will be matched exclusively against tip and node labels if \code{rownamesAsLabels} is also TRUE, whereas any all-digit row names will be matched against tip and node numbers if \code{rownamesAsLabels} is FALSE (the default). If \code{match.data} is FALSE, \code{rownamesAsLabels} has no effect, and row matching is purely positional with respect to the order returned by \code{nodeId(phy, type)}. \code{formatData} (1) converts labels provided in the data into node numbers, (2) makes sure that the data are appropriately matched against tip and/or internal nodes, (3) checks for differences between data and tree, (4) creates a data frame with the correct dimensions given a tree. } \seealso{ the \code{\link{phylo4d-methods}} constructor, the \linkS4class{phylo4d} class. See \code{\link{coerce-methods}} for translation functions. } \author{ Francois Michonneau } \keyword{misc} phylobase/man/readNexus.Rd0000644000176200001440000001466113075412470015253 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/readNCL.R \docType{methods} \name{Import Nexus and Newick files} \alias{Import Nexus and Newick files} \alias{readNCL} \alias{readNexus} \alias{readNewick} \title{Create a \code{phylo4}, \code{phylo4d} or \code{data.frame} object from a NEXUS or a Newick file} \usage{ readNCL(file, simplify = FALSE, type = c("all", "tree", "data"), spacesAsUnderscores = TRUE, char.all = FALSE, polymorphic.convert = TRUE, levels.uniform = FALSE, quiet = TRUE, check.node.labels = c("keep", "drop", "asdata"), return.labels = TRUE, file.format = c("nexus", "newick"), check.names = TRUE, convert.edge.length = FALSE, ...) readNexus(file, simplify = FALSE, type = c("all", "tree", "data"), char.all = FALSE, polymorphic.convert = TRUE, levels.uniform = FALSE, quiet = TRUE, check.node.labels = c("keep", "drop", "asdata"), return.labels = TRUE, check.names = TRUE, convert.edge.length = FALSE, ...) readNewick(file, simplify = FALSE, quiet = TRUE, check.node.labels = c("keep", "drop", "asdata"), convert.edge.length = FALSE, ...) } \arguments{ \item{file}{a NEXUS file for \code{readNexus} or a file that contains Newick formatted trees for \code{readNewick}.} \item{simplify}{If TRUE, if there are multiple trees in the file, only the first one is returned; otherwise a list of \code{phylo4(d)} objects is returned if the file contains multiple trees.} \item{type}{Determines which type of objects to return, if present in the file (see Details).} \item{spacesAsUnderscores}{In the NEXUS file format white spaces are not allowed in taxa labels and are represented by underscores. Therefore, NCL converts underscores found in taxa labels in the NEXUS file into white spaces (e.g. \code{species_1} will become \code{"species 1"}. If you want to preserve the underscores, set as TRUE, the default).} \item{char.all}{If \code{TRUE}, returns all characters, even those excluded in the NEXUS file} \item{polymorphic.convert}{If \code{TRUE}, converts polymorphic characters to missing data} \item{levels.uniform}{If \code{TRUE}, uses the same levels for all characters} \item{quiet}{If \code{FALSE} the output of the NCL interface is printed. This is mainly for debugging purposes. This option can considerably slow down the process if the tree is big or there are many trees in the file.} \item{check.node.labels}{Determines how the node labels in the NEXUS or Newick files should be treated in the phylo4 object, see Details for more information.} \item{return.labels}{Determines whether state names (if \code{TRUE}) or state codes should be returned.} \item{file.format}{character indicating the format of the specified file (either \dQuote{\code{newick}} or \dQuote{\code{nexus}}). It's more convenient to just use \code{readNexus} or \code{readNewick}.} \item{check.names}{logical. If \sQuote{TRUE} then the names of the characters from the NEXUS file are checked to ensure that they are syntactically valid variable names and are not duplicated. If necessary they are adjusted using \sQuote{make.names}.} \item{convert.edge.length}{logical. If \code{TRUE} negative edge lengths are replaced with 0. At this time \code{phylobase} does not accept objects with negative branch lengths, this workaround allows to import trees with negative branch lengths.} \item{\dots}{Additional arguments to be passed to phylo4 or phylo4d constructor (see Details)} } \value{ Depending on the value of \code{type} and the contents of the file, one of: a \code{data.frame}, a \linkS4class{phylo4} object, a \linkS4class{phylo4d} object or \code{NULL}. If several trees are included in the NEXUS file and the option \code{simplify=FALSE} a list of \linkS4class{phylo4} or \linkS4class{phylo4d} objects is returned. } \description{ \code{readNexus} reads a NEXUS file and outputs a \code{phylo4}, \code{phylo4d} or \code{data.frame} object. } \details{ \code{readNewick} reads a Newick file and outputs a \code{phylo4} or \code{phylo4d} object. \code{readNexus} is used internally by both \code{readNexus} and \code{readNewick} to extract data held in a tree files, specifically in NEXUS files from DATA, CHARACTER or TREES blocks. The \code{type} argument specifies which of these is returned: \describe{ \item{data}{will only return a \code{data.frame} of the contents of all DATA and CHARACTER blocks.} \item{tree}{will only return a \code{phylo4} object of the contents of the TREES block.} \item{all}{if only data or a tree are present in the file, this option will act as the options above, returning either a \code{data.frame} or a \code{phylo4} object respectively. If both are present then a \code{phylo4d} object is returned containing both.} } The function returns \code{NULL} if the \code{type} of data requested is not present in the file, or if neither data nor tree blocks are present. Depending on the context \code{readNexus} will call either the \code{phylo4} or \code{phylo4d} constructor. The \code{phylo4d} constructor will be used with \code{type="all"}, or if the option \code{check.node.labels="asdata"} is invoked. \code{readNewick} imports Newick formatted tree files and will return a \code{phylo4} or a \code{phylo4d} object if the option \code{check.node.labels="asdata"} is invoked. For both \code{readNexus} and \code{readNewick}, the options for \code{check.node.labels} can take the values: \describe{ \item{keep}{the node labels of the trees will be passed as node labels in the \code{phylo4} object} \item{drop}{the node labels of the trees will be ignored in the \code{phylo4} object} \item{asdata}{the node labels will be passed as data and a \code{phylo4d} object will be returned.} } If you use the option \code{asdata} on a file with no node labels, a warning message is issued, and is thus equivalent to the value \code{drop}. For both \code{readNexus} and \code{readNewick}, additional arguments can be passed to the constructors such as \code{annote}, \code{missing.data} or \code{extra.data}. See the \sQuote{Details} section of \code{\link{phylo4d-methods}} for the complete list of options. } \note{ Underscores in state labels (i.e. trait or taxon names) will be translated to spaces. Unless \code{check.names=FALSE}, trait names will be converted to valid R names (see \code{\link{make.names}}) on input to R, so spaces will be translated to periods. } \seealso{ the \linkS4class{phylo4d} class, the \linkS4class{phylo4} class } \author{ Brian O'Meara, Francois Michonneau, Derrick Zwickl } \keyword{misc} phylobase/man/treePlot-methods.Rd0000644000176200001440000000725613075412470016556 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/treePlot.R \docType{methods} \name{treePlot-methods} \alias{treePlot-methods} \alias{treePlot} \alias{plot,ANY,ANY-method} \alias{plot,pdata,missing-method} \alias{plot,phylo4,missing-method} \alias{treePlot-method} \alias{treePlot,phylo4,phylo4d-method} \alias{plot} \alias{plot,phylo4,missing-method} \alias{plot,phylo4-method} \title{Phylogeny plotting} \usage{ treePlot(phy, type = c("phylogram", "cladogram", "fan"), show.tip.label = TRUE, show.node.label = FALSE, tip.order = NULL, plot.data = is(phy, "phylo4d"), rot = 0, tip.plot.fun = "bubbles", plot.at.tip = TRUE, edge.color = "black", node.color = "black", tip.color = "black", edge.width = 1, newpage = TRUE, margins = c(1.1, 1.1, 1.1, 1.1), ...) plot(x, y, ...) \S4method{plot}{phylo4,missing}(x, y, ...) } \arguments{ \item{phy}{A \code{phylo4} or \code{phylo4d} object} \item{type}{A character string indicating the shape of plotted tree} \item{show.tip.label}{Logical, indicating whether tip labels should be shown} \item{show.node.label}{Logical, indicating whether node labels should be shown} \item{tip.order}{If NULL the tree is plotted with tips in preorder, if "rev" this is reversed. Otherwise, it is a character vector of tip labels, indicating their order along the y axis (from top to bottom). Or, a numeric vector of tip node IDs indicating the order.} \item{plot.data}{Logical indicating whether \code{phylo4d} data should be plotted} \item{rot}{Numeric indicating the rotation of the plot in degrees} \item{tip.plot.fun}{A function used to generate plot at the each tip of the phylogenetic trees} \item{plot.at.tip}{should the data plots be at the tip? (logical)} \item{edge.color}{A vector of colors in the order of \code{edges(phy)}} \item{node.color}{A vector of colors indicating the colors of the node labels} \item{tip.color}{A vector of colors indicating the colors of the tip labels} \item{edge.width}{A vector in the order of \code{edges(phy)} indicating the widths of edge lines} \item{newpage}{Logical indicating whether the page should be cleared before plotting} \item{margins}{number of lines around the plot (similar to \code{par(mar)}).} \item{\dots}{additional arguments} \item{x}{A \code{phylo4} or \code{phylo4d} object} \item{y}{(only here for compatibility)} } \value{ No return value, function invoked for plotting side effect } \description{ Plot \code{phylo4} or \code{phylo4d} objects, including associated data. } \details{ Currently, \code{treePlot} can only plot numeric values for tree-associated data. The dataset will be subset to only include columns of class \code{numeric}, \code{integer} or \code{double}. If a \code{phylo4d} object is passed to the function and it contains no data, or if the data is in a format that cannot be plotted, the function will produce a warning. You can avoid this by using the argument \code{plot.data=FALSE}. } \section{Methods}{ \describe{ \item{phy = "phylo4"}{plots a tree of class \linkS4class{phylo4}} \item{phy = "phylo4d"}{plots a tree with one or more quantitative traits contained in a \linkS4class{phylo4d} object.} } } \examples{ ## example of plotting two grid plots on the same page library(grid) data(geospiza) geotree <- extractTree(geospiza) grid.newpage() pushViewport(viewport(layout=grid.layout(nrow=1, ncol=2), name="base")) pushViewport(viewport(layout.pos.col=1, name="plot1")) treePlot(geotree, newpage=FALSE) popViewport() pushViewport(viewport(layout.pos.col=2, name="plot2")) treePlot(geotree, newpage=FALSE, rot=180) popViewport(2) } \seealso{ \code{\link{phylobubbles}} } \author{ Peter Cowan \email{pdc@berkeley.edu}, Francois Michonneau } \keyword{methods} phylobase/man/pdata-class.Rd0000644000176200001440000000107613075412470015505 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pdata.R \docType{class} \name{pdata-class} \alias{pdata-class} \alias{ptypes} \alias{[<-,pdata-method} \alias{[,pdata-method} \alias{[,pdata,ANY,ANY,ANY-method} \alias{[[,pdata-method} \alias{[[<-,pdata-method} \alias{[[,pdata,ANY,ANY-method} \alias{[[,pdata,ANY,missing-method} \title{Class "pdata"} \description{ Data class for phylo4d objects } \section{Objects from the Class}{ Objects can be created by calls of the form \code{new("pdata", ...)}. } \author{ Ben Bolker } \keyword{classes} phylobase/man/labels-methods.Rd0000644000176200001440000001027213075412470016212 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/labels-methods.R \docType{methods} \name{phylo4-labels} \alias{phylo4-labels} \alias{labels} \alias{labels,phylo4-method} \alias{labels<-} \alias{labels<-,phylo4-method} \alias{hasDuplicatedLabels} \alias{hasDuplicatedLabels,phylo4-method} \alias{hasDuplicatedLabels,phylo4,ANY-method} \alias{hasNodeLabels} \alias{hasNodeLabels,phylo4-method} \alias{nodeLabels} \alias{nodeLabels,phylo4-method} \alias{nodeLabels<-} \alias{nodeLabels<-,phylo4-method} \alias{tipLabels} \alias{tipLabels,phylo4-method} \alias{tipLabels<-} \alias{tipLabels<-,phylo4-method} \alias{hasEdgeLabels} \alias{hasEdgeLabels,phylo4-method} \alias{edgeLabels} \alias{edgeLabels,phylo4-method} \alias{edgeLabels<-} \alias{edgeLabels<-,phylo4-method} \title{Labels for phylo4/phylo4d objects} \usage{ labels(object, ...) \S4method{labels}{phylo4}(object, type = c("all", "tip", "internal")) labels(x, type, use.names, ...) <- value \S4method{labels}{phylo4}(x, type = c("all", "tip", "internal"), use.names, ...) <- value hasDuplicatedLabels(x, type) \S4method{hasDuplicatedLabels}{phylo4}(x, type = c("all", "tip", "internal")) hasNodeLabels(x) \S4method{hasNodeLabels}{phylo4}(x) nodeLabels(x) \S4method{nodeLabels}{phylo4}(x) nodeLabels(x, ...) <- value \S4method{nodeLabels}{phylo4}(x, ...) <- value tipLabels(x) \S4method{tipLabels}{phylo4}(x) tipLabels(x, ...) <- value \S4method{tipLabels}{phylo4}(x, ...) <- value hasEdgeLabels(x) \S4method{hasEdgeLabels}{phylo4}(x) edgeLabels(x) \S4method{edgeLabels}{phylo4}(x) edgeLabels(x, ...) <- value \S4method{edgeLabels}{phylo4}(x, ...) <- value } \arguments{ \item{object}{a phylo4 or phylo4d object.} \item{\dots}{additional optional arguments (not in use)} \item{type}{which type of labels: \code{all} (tips and internal nodes), \code{tip} (tips only), \code{internal} (internal nodes only).} \item{x}{a phylo4 or phylo4d object.} \item{use.names}{should the names of the vector used to create/update labels be used to match the labels? See Details for more information.} \item{value}{a vector of class \code{character}, see Details for more information.} } \value{ labels in ascending order. } \description{ Methods for creating, accessing and updating labels in phylo4/phylo4d objects } \details{ In phylo4/phylo4d objects, tips must have labels (that's why there is no method for hasTipLabels), internal nodes and edges can have labels. Labels must be provided as a vector of class \code{character}. The length of the vector must match the number of elements they label. The option \code{use.names} allows the user to match a label to a particular node. In this case, the vector must have names that match the node numbers. The function \code{labels} is mostly intended to be used internally. } \section{Methods}{ \describe{ \item{labels}{\code{signature(object = "phylo4")}: tip and/or internal node labels, ordered by node ID} \item{hasDuplicatedLabels}{\code{signature(object = "phylo4")}: are any labels duplicated?} \item{tipLabels}{\code{signature(object = "phylo4")}: tip labels, ordered by node ID} \item{hasNodeLabels}{\code{signature(object = "phylo4")}: whether tree has (internal) node labels} \item{nodeLabels}{\code{signature(object = "phylo4")}: internal node labels, ordered by node ID} \item{hasEdgeLabels}{\code{signature(object = "phylo4")}: whether tree has (internal) edge labels} \item{edgeLabels}{\code{signature(object = "phylo4")}: internal edge labels, ordered according to the edge matrix} } } \examples{ data(geospiza) ## Return labels from geospiza tipLabels(geospiza) ## Internal node labels in geospiza are empty nodeLabels(geospiza) ## Creating internal node labels ndLbl <- paste("n", 1:nNodes(geospiza), sep="") nodeLabels(geospiza) <- ndLbl nodeLabels(geospiza) ## naming the labels names(ndLbl) <- nodeId(geospiza, "internal") ## shuffling the labels (ndLbl <- sample(ndLbl)) ## by default, the labels are attributed in the order ## they are given: nodeLabels(geospiza) <- ndLbl nodeLabels(geospiza) ## but use.names puts them in the correct order labels(geospiza, "internal", use.names=TRUE) <- ndLbl nodeLabels(geospiza) } \author{ Ben Bolker, Peter Cowan, Steve Kembel, Francois Michonneau } phylobase/man/phyloXXYY.Rd0000644000176200001440000000302513075412470015202 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/treePlot.R \name{phyloXXYY} \alias{phyloXXYY} \title{Calculate node x and y coordinates} \usage{ phyloXXYY(phy, tip.order = NULL) } \arguments{ \item{phy}{A \code{phylo4} or \code{phylo4d} object.} \item{tip.order}{A character vector of tip labels, indicating their order along the y axis (from top to bottom). Or, a numeric vector of tip node IDs indicating the order.} } \value{ \item{yy}{Internal node and tip y coordinates} \item{xx}{Internal node and tip x coordinates} \item{phy}{A \code{phylo4} or \code{phylo4d} object} \item{segs}{A list of \code{h0x, h1x, v0x, v1x} and \code{h0y, h1y, v0y, v1y} describing the start and end points for the plot line segments} \item{torder}{The tip order provided as \code{tip.order} or if NULL the preoder tip order} \item{eorder}{The an index of the reordered edges compared to the result of \code{edges(phy)}} } \description{ Calculates the node x and y locations for plotting a phylogenetic tree. } \details{ The y coordinates of the tips are evenly spaced from 0 to 1 in pruningwise order. Ancestor y nodes are given the mean value of immediate descendants. The root is given the x coordinate 0 and descendant nodes are placed according to the cumulative branch length from the root, with a maximum x value of 1. } \examples{ data(geospiza) coor <- phyloXXYY(geospiza) plot(coor$xx, coor$yy, pch = 20) } \seealso{ \code{treePlot}, \code{\link{plotOneTree}} } \author{ Peter Cowan \email{pdc@berkeley.edu} } \keyword{methods} phylobase/man/print-methods.Rd0000644000176200001440000000623413075423374016114 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/print-methods.R \docType{methods} \name{print} \alias{print} \alias{print,phylo4-method} \alias{show} \alias{show,phylo4-method} \alias{names} \alias{names,phylo4-method} \alias{head} \alias{head,phylo4-method} \alias{tail} \alias{tail,phylo4-method} \title{print a phylogeny} \usage{ print(x, ...) \S4method{print}{phylo4}(x, edgeOrder = c("pretty", "real"), printall = TRUE) show(object) \S4method{show}{phylo4}(object) names(x) \S4method{names}{phylo4}(x) head(x, ...) \S4method{head}{phylo4}(x, n = 20) tail(x, ...) \S4method{tail}{phylo4}(x, n = 20) } \arguments{ \item{x}{a \code{phylo4} tree or \code{phylo4d} tree+data object} \item{\dots}{optional additional arguments (not in use)} \item{edgeOrder}{in the data frame returned, the option 'pretty' returns the internal nodes followed by the tips, the option 'real' returns the nodes in the order they are stored in the edge matrix.} \item{printall}{default prints entire tree. printall=FALSE returns the first 6 rows} \item{object}{a \code{phylo4} or \code{phylo4d} object} \item{n}{for head() and tail(), the number of lines to print} } \value{ A data.frame with a row for each node (descendant), sorted as follows: root first, then other internal nodes, and finally tips.\cr The returned data.frame has the following columns:\cr \item{label}{Label for the taxon at the node (usually species name).} \item{node}{Node number, i.e. the number identifying the node in edge matrix.} \item{ancestor}{Node number of the node's ancestor.} \item{branch.length}{The branch length connecting the node to its ancestor (NAs if missing).} \item{node.type}{"root", "internal", or "tip". (internally generated)} \item{data}{phenotypic data associated with the nodes, with separate columns for each variable.} } \description{ Prints a phylo4 or phylo4d object in data.frame format with user-friendly column names } \details{ This is a user-friendly version of the tree representation, useful for checking that objects were read in completely and translated correctly. The phylogenetic tree is represented as a list of numbered nodes, linked in a particular way through time (or rates of evolutionary change). The topology is given by the pattern of links from each node to its ancestor. Also given are the taxon names, node type (root/internal/tip) and phenotypic data (if any) associated with the node, and the branch length from the node to its ancestor. A list of nodes (descendants) and ancestors is minimally required for a phylo4 object. } \note{ This is the default show() method for phylo4, phylo4d. It prints the user-supplied information for building a phylo4 object. For a full description of the phylo4 S4 object and slots, see \code{\link{phylo4}}. } \examples{ tree.phylo <- ape::read.tree(text="((a,b),c);") tree <- as(tree.phylo, "phylo4") ##plot(tree,show.node=TRUE) ## plotting broken with empty node labels: FIXME tip.data <- data.frame(size=c(1,2,3), row.names=c("a", "b", "c")) treedata <- phylo4d(tree, tip.data) plot(treedata) print(treedata) } \author{ Marguerite Butler, Thibaut Jombart \email{jombart@biomserv.univ-lyon1.fr}, Steve Kembel } \keyword{methods} phylobase/man/ancestors.Rd0000644000176200001440000000706613075412470015317 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ancestors.R \name{ancestor} \alias{ancestor} \alias{children} \alias{descendants} \alias{siblings} \alias{ancestors} \alias{siblings} \title{Tree traversal and utility functions} \usage{ ancestor(phy, node) children(phy, node) descendants(phy, node, type = c("tips", "children", "all", "ALL")) siblings(phy, node, include.self = FALSE) ancestors(phy, node, type = c("all", "parent", "ALL")) } \arguments{ \item{phy}{a \linkS4class{phylo4} object (or one inheriting from \linkS4class{phylo4}, e.g. a \linkS4class{phylo4d} object)} \item{node}{either an integer corresponding to a node ID number, or a character corresponding to a node label; for \code{ancestors} and \code{descendants}, this may be a vector of multiple node numbers or names} \item{type}{(\code{ancestors}) specify whether to return just direct ancestor ("parent"), all ancestor nodes ("all"), or all ancestor nodes including self ("ALL"); (\code{descendants}) specify whether to return just direct descendants ("children"), all extant descendants ("tips"), or all descendant nodes ("all") or all descendant nodes including self ("ALL").} \item{include.self}{whether to include self in list of siblings} \item{\dots}{a list of node numbers or names, or a vector of node numbers or names} } \value{ \describe{ \item{\code{ancestors}}{ return a named vector (or a list of such vectors in the case of multiple input nodes) of the ancestors and descendants of a node} \item{\code{descendants}}{ return a named vector (or a list of such vectors in the case of multiple input nodes) of the ancestors and descendants of a node} \item{\code{ancestor}}{ \code{ancestor} is analogous to \code{ancestors(\dots{}, type="parent")} (i.e. direct ancestor only), but returns a single concatenated vector in the case of multiple input nodes} \item{\code{children}}{is analogous to \code{descendants(\dots{}, type="children")} (i.e. direct descendants only), but is not currently intended to be used with multiple input nodes } \item{\code{siblings}}{ returns sibling nodes (children of the same parent)} } } \description{ Functions for describing relationships among phylogenetic nodes (i.e. internal nodes or tips). } \details{ \code{ancestors} and \code{descendants} can take \code{node} vectors of arbitrary length, returning a list of output vectors if the number of valid input nodes is greater than one. List element names are taken directly from the input node vector. If any supplied nodes are not found in the tree, the behavior currently varies across functions. \itemize{ \item Invalid nodes are automatically omitted by \code{ancestors} and \code{descendants}, with a warning. \item \code{ancestor} will return \code{NA} for any invalid nodes, with a warning. \item Both \code{children} and \code{siblings} will return an empty vector, again with a warning. } } \examples{ data(geospiza) nodeLabels(geospiza) <- LETTERS[1:nNodes(geospiza)] plot(as(geospiza, "phylo4"), show.node.label=TRUE) ancestor(geospiza, "E") children(geospiza, "C") descendants(geospiza, "D", type="tips") descendants(geospiza, "D", type="all") ancestors(geospiza, "D") MRCA(geospiza, "conirostris", "difficilis", "fuliginosa") MRCA(geospiza, "olivacea", "conirostris") ## shortest path between 2 nodes shortestPath(geospiza, "fortis", "fuliginosa") shortestPath(geospiza, "F", "L") ## branch length from a tip to the root sumEdgeLength(geospiza, ancestors(geospiza, "fortis", type="ALL")) } \seealso{ \code{\link[ape]{mrca}}, in the ape package, gives a list of all subtrees } phylobase/man/nTips-methods.Rd0000644000176200001440000000146313075412470016047 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/phylo4-accessors.R \docType{methods} \name{nTips} \alias{nTips} \alias{nTips,phylo4-method} \alias{nTips,phylo-method} \alias{nNodes} \alias{nNodes,phylo4-method} \alias{nEdges} \alias{nEdges,phylo4-method} \title{nTips, nNodes, nEdges} \usage{ nTips(x) \S4method{nTips}{phylo4}(x) \S4method{nTips}{phylo}(x) nNodes(x) \S4method{nNodes}{phylo4}(x) nEdges(x) \S4method{nEdges}{phylo4}(x) } \arguments{ \item{x}{a \code{phylo4} or \code{phylo4d} object} } \value{ a numeric vector indicating the number of tips, nodes or edge respectively. } \description{ Number of tips, nodes and edges found in a tree. } \details{ Function to return the number of tips, nodes and edges found in a tree in the \code{phylo4} or \code{phylo4d} format. } phylobase/man/checkPhylo4.Rd0000644000176200001440000000442413075412470015466 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/checkdata.R \name{checkPhylo4} \alias{checkPhylo4} \alias{checkTree} \alias{checkPhylo4Data} \title{Validity checking for phylo4 objects} \usage{ checkPhylo4(object) } \arguments{ \item{object}{A prospective phylo4 or phylo4d object} } \value{ As required by \code{\link[methods]{validObject}}, returns an error string (describing problems) or TRUE if everything is OK. } \description{ Basic checks on the validity of S4 phylogenetic objects } \note{ These functions are only intended to be called by other phylobase functions. \code{checkPhylo4} is an (inflexible) wrapper for \code{checkTree}. The rules for \code{phylo4} objects essentially follow those for \code{phylo} objects from the \code{ape} package, which are in turn defined in \url{http://ape-package.ird.fr/misc/FormatTreeR_24Oct2012.pdf}. These are essentially that: \itemize{ \item if the tree has edge lengths defined, the number of edge lengths must match the number of edges; \item the number of tip labels must match the number of tips; \item in a tree with \code{ntips} tips and \code{nnodes} (total) nodes, nodes 1 to \code{ntips} must be tips \item if the tree is rooted, the root must be node number \code{ntips+1} and the root node must be the first row of the edge matrix \item tip labels, node labels, edge labels, edge lengths must have proper internal names (i.e. internal names that match the node numbers they document) \item tip and node labels must be unique } You can alter some of the default options by using the function \code{phylobase.options}. For \code{phylo4d} objects, \code{checkTree} also calls \code{checkPhylo4Data} to check the validity of the data associated with the tree. It ensures that (1) the data associated with the tree have the correct dimensions, (2) that the row names for the data are correct. } \seealso{ the \code{\link{phylo4}} constructor and \linkS4class{phylo4} class; the \code{\link{phylo4d-methods}} constructor and the \linkS4class{phylo4d} class do checks for the data associated with trees. See \code{\link{coerce-methods}} for translation functions and \code{\link{phylobase.options} to change some of the default options of the validator.} } \author{ Ben Bolker, Steven Kembel, Francois Michonneau } \keyword{misc} phylobase/man/phylobase-package.Rd0000644000176200001440000000442113075412470016665 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/phylobase-package.R \docType{package} \name{phylobase-package} \alias{phylobase-package} \alias{phylobase} \title{Utilities and Tools for Phylogenetics} \description{ Base package for phylogenetic structures and comparative data. } \details{ \code{phylobase} provides a set of functions to associate and manipulate phylogenetic information and data about the species/individuals that are in the tree. \code{phylobase} intends to be robust, fast and efficient. We hope other people use the data structure it provides to develop new comparative methods in R. With \code{phylobase} it is easy to ensure that all your data are represented and associated with the tips or the internal nodes of your tree. \code{phylobase} provides functions to: \itemize{ \item prune (subset) your trees, find ancestor(s) a descendant(s) \item find the most common recent ancestor of 2 nodes (MRCA) \item calculate the distance of a given node from the tip or between two nodes in your tree \item robust functions to import data from NEXUS and Newick files using the NEXUS Class Library (\url{https://github.com/mtholder/ncl/}) } } \section{History}{ \code{phylobase} was started during a Hackathlon at NESCent on December 10-14 2007. Peter Cowan was a Google Summer of Code fellow in 2008 and developed all the code for plotting. In December 2008, a mini-virtual Hackathlon was organized to clean up and make the code more robust. In the spring and summer of 2009, Jim Regetz made several contributions that made the code faster (in particular with the re-ordering parts), found many bugs, and wrote most of the testing code. \code{phylobase} was first released on CRAN on November 1st, 2009 with version 0.5. Since then, several releases have followed adding new functionalities: better support of NEXUS files, creation of \code{phylobase.options()} function that controls the \code{phylo4} validator, rewrite of the validator in C++. Starting with 0.6.8, Francois Michonneau succeeds to Ben Bolker as the maintainer of the package. } \section{More Info}{ See the help index \code{help(package="phylobase")} and run \code{vignette("phylobase", "phylobase")} for further details and examples about how to use \code{phylobase}. } \keyword{package} phylobase/man/phylo4-class.Rd0000644000176200001440000000137413075412470015634 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/phylo4-class.R \docType{class} \name{phylo4-class} \alias{phylo4-class} \title{The phylo4 class} \description{ Classes for phylogenetic trees } \section{Objects from the Class}{ Phylogenetic tree objects can be created by calls to the \code{\link{phylo4}} constructor function. Translation functions from other phylogenetic packages are also available. See \code{\link{coerce-methods}}. } \seealso{ The \code{\link{phylo4-methods}} constructor, the \code{\link{checkPhylo4}} function to check the validity of \code{phylo4} objects. See also the \code{\link{phylo4d-methods}} constructor and the \linkS4class{phylo4d} class. } \author{ Ben Bolker, Thibaut Jombart } \keyword{classes}