This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Cmd+Shift+Enter.

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Cmd+Option+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Cmd+Shift+K to preview the HTML file).

First I imported the .csv master sheet and read the data into R Studio

library(ggplot2) #Load the plotting library
library(DescTools)
setwd("~/Desktop/GarlicMustard")
data <- read.csv('Garlic_LimitingNutrient_MingoParkSoils.csv')
head(data)
names(data)
[1] "Treatment"                                      "Plant.ID.Code."                                
[3] "Third.Leaf.Length..mm....4.13.2015."            "Fourth.Leaf..mm....4.24.2015"                  
[5] "Fourth.Leaf.Length..mm..at.Harvest...5.7.2015"  "Number.of.Emerged.Leaves.at.Harvest...5.7.2015"
[7] "Harvest.Notes...5.7.2015."                      "ShootWeight"                                   
[9] "RootWeight"                                    

Next I generated subset the data for each treatment, starting with ‘RO Water’ and generated the average, sd, and se of each treatment. After generating these treatments I combined them into a vector that was then written to a .csv file.

#***change Treatment*** subset data to get averages, Standard deviation, std error
sub = subset(data, Treatment == "RO Water")
#calculate avg, stdev, stderror
avg <- mean(sub$ShootWeight) 
stdev <- sd(sub$ShootWeight)
se <- MeanSE(sub$ShootWeight)
# create a vector to store all data. ***change treatment name***
results <- c("RO Water", avg, stdev, se)
# put vector into matrix and write output to CSV
output1 <- as.matrix(t(results))
write.table(output1, file = "shootweightavg1.csv", sep = ",", col.names = FALSE, append = TRUE) # repeat for all data

I repeated this for Phosphorus…

#***change Treatment*** subset data to get averages, Standard deviation, std error
sub = subset(data, Treatment == "Phosphorus")
#calculate avg, stdev, stderror
avg <- mean(sub$ShootWeight) 
stdev <- sd(sub$ShootWeight)
se <- MeanSE(sub$ShootWeight)
# create a vector to store all data. ***change treatment name***
results <- c("Phosphorus", avg, stdev, se)
# put vector into matrix and write output to CSV
output1 <- as.matrix(t(results))
write.table(output1, file = "shootweightavg1.csv", sep = ",", col.names = FALSE, append = TRUE) # repeat for all data

Then for Nitrogen…

#***change Treatment*** subset data to get averages, Standard deviation, std error
sub = subset(data, Treatment == "Nitrogen")
#calculate avg, stdev, stderror
avg <- mean(sub$ShootWeight) 
stdev <- sd(sub$ShootWeight)
se <- MeanSE(sub$ShootWeight)
# create a vector to store all data. ***change treatment name***
results <- c("Nitrogen", avg, stdev, se)
# put vector into matrix and write output to CSV
output1 <- as.matrix(t(results))
write.table(output1, file = "shootweightavg1.csv", sep = ",", col.names = FALSE, append = TRUE) # repeat for all data

And lastly for Nitrogen +Phosphorus…

#***change Treatment*** subset data to get averages, Standard deviation, std error
sub = subset(data, Treatment == "Nitrogen +Phosphorus")
#calculate avg, stdev, stderror
avg <- mean(sub$ShootWeight) 
stdev <- sd(sub$ShootWeight)
se <- MeanSE(sub$ShootWeight)
# create a vector to store all data. ***change treatment name***
results <- c("Nitrogen +Phosphorus", avg, stdev, se)
# put vector into matrix and write output to CSV
output1 <- as.matrix(t(results))
write.table(output1, file = "shootweightavg1.csv", sep = ",", col.names = FALSE, append = TRUE) # repeat for all data

Next I wanted to import the data from the .csv file that I had just created.

#read in the calculated values and give columns names
shootavgdata <- read.csv("shootweightavg1.csv", header = FALSE)
head(shootavgdata)

I then wanted to label the columns the way that I had written them in the vector above for output. I then double checked to make sure that the names matched up with the correct columns

# Name Columns
colnames(shootavgdata)[2] <- "Treatment"
colnames(shootavgdata)[3] <- "AverageShootWeight"
colnames(shootavgdata)[4] <- "Standard Deviation"
colnames(shootavgdata)[5] <- "se"
head(shootavgdata)

Lastly I wanted to create a bar chart that represented what was in ‘shootweightavg1.csv’ using ggplot. Most of the resources I used to aid in the creation of this plot were found with the “R for Data Science” manual (http://r4ds.had.co.nz/data-visualisation.html#geometric-objects) and using the “ggplot2 data visualization cheatsheet” (https://www.rstudio.com/wp-content/uploads/2015/03/ggplot2-cheatsheet.pdf), and a little help with refining the error bars from the “R Cookbook” (http://www.cookbook-r.com/Graphs/Plotting_means_and_error_bars_(ggplot2)/)

#create plot
ggplot(data = shootavgdata, mapping = aes(x = Treatment, y = AverageShootWeight)) +
  geom_col(width = 0.5) +
  ggtitle("Average Shoot Weight After Fertilizer Addition on High Phosphorus Soil")+
  scale_x_discrete(limits=c("RO Water","Phosphorus","Nitrogen +Phosphorus", "Nitrogen")) +
  scale_y_continuous("Average Shoot Weight (G)") +
  geom_errorbar(aes(ymin = AverageShootWeight-se, ymax = AverageShootWeight+se),
                  size=.3,width=.2)

This graph helps to illustrate that on our urban soil from Mingo Park, hypothesized to be P rich, that additions of Phosphorus fertilizer provided no significant gain in average shoot weight for garlic mustard. On the other hand, the addition of N to the Mingo soils caused an increase in average shoot weight, suggesting that these soils may in fact be N limited.

Now to repeat with the roots

#*****************************************************
#Root data
#Had to create separate data sheet with only Rootdata
data <- read.csv('MingoParkLimNut_roots.csv')
head(data)
names(data)
[1] "Treatment"                                      "Plant.ID.Code."                                
[3] "Third.Leaf.Length..mm....4.13.2015."            "Fourth.Leaf..mm....4.24.2015"                  
[5] "Fourth.Leaf.Length..mm..at.Harvest...5.7.2015"  "Number.of.Emerged.Leaves.at.Harvest...5.7.2015"
[7] "Harvest.Notes...5.7.2015."                      "ShootWeight"                                   
[9] "RootWeight"                                    

Now calculate the averages for each of the treatments. Starting with RO Water

sub = subset(data, Treatment == "RO Water")
sub
#calculate avg, stdev, stderror
avg <- mean(sub$RootWeight) 
stdev <- sd(sub$RootWeight)
se <- MeanSE(sub$RootWeight)
# create a vector to store all data. ***change treatment name***
results <- c("RO Water", avg, stdev, se)
# put vector into matrix and write output to CSV
output1 <- as.matrix(t(results))
write.table(output1, file = "rootweightavg2.csv", sep = ",", col.names = FALSE, append = TRUE) # repeat for all data

Next Phosphorus…

sub = subset(data, Treatment == "Phosphorus")
sub
#calculate avg, stdev, stderror
avg <- mean(sub$RootWeight) 
stdev <- sd(sub$RootWeight)
se <- MeanSE(sub$RootWeight)
# create a vector to store all data. ***change treatment name***
results <- c("Phosphorus", avg, stdev, se)
# put vector into matrix and write output to CSV
output1 <- as.matrix(t(results))
write.table(output1, file = "rootweightavg2.csv", sep = ",", col.names = FALSE, append = TRUE) # repeat for all data

Then to Nitrogen…

sub = subset(data, Treatment == "Nitrogen")
sub
#calculate avg, stdev, stderror
avg <- mean(sub$RootWeight) 
stdev <- sd(sub$RootWeight)
se <- MeanSE(sub$RootWeight)
# create a vector to store all data. ***change treatment name***
results <- c("Nitrogen", avg, stdev, se)
# put vector into matrix and write output to CSV
output1 <- as.matrix(t(results))
write.table(output1, file = "rootweightavg2.csv", sep = ",", col.names = FALSE, append = TRUE) # repeat for all data

and lastly Nitrogen +Phosphorus…

sub = subset(data, Treatment == "Nitrogen +Phosphorus")
sub
#calculate avg, stdev, stderror
avg <- mean(sub$RootWeight) 
stdev <- sd(sub$RootWeight)
se <- MeanSE(sub$RootWeight)
# create a vector to store all data. ***change treatment name***
results <- c("Nitrogen +Phosphorus", avg, stdev, se)
# put vector into matrix and write output to CSV
output1 <- as.matrix(t(results))
write.table(output1, file = "rootweightavg2.csv", sep = ",", col.names = FALSE, append = TRUE) # repeat for all data

Then we read in the values from the .csv we just created

#read in the calculated values and give columns names
rootavgdata <- read.csv("rootweightavg2.csv", header = FALSE)
head(rootavgdata)
# Name Columns
colnames(rootavgdata)[2] <- "Treatment"
colnames(rootavgdata)[3] <- "AverageRootWeight"
colnames(rootavgdata)[4] <- "Standard Deviation"
colnames(rootavgdata)[5] <- "se"
head(rootavgdata)

Then again I made the graph using ggplot2.

#create plot
ggplot(data = rootavgdata, mapping = aes(x = Treatment, y = AverageRootWeight)) +
  geom_col(width = 0.5) +
  ggtitle("Average Root Weight After Fertilizer Addition on High Phosphorus Soil")+
  scale_x_discrete(limits=c("RO Water","Phosphorus","Nitrogen +Phosphorus", "Nitrogen")) +
  scale_y_continuous("Average Root Weight (G)") +
  geom_errorbar(aes(ymin = AverageRootWeight-se, ymax = AverageRootWeight+se), #http://www.cookbook-r.com/Graphs/Plotting_means_and_error_bars_(ggplot2)/
                size=.3,width=.2)

Now to combine this data together I put it in a .csv file titled ‘RootShootCombMingoParkLimNut.csv’

rootshoot <- read.csv("RootShootCombMingoParkLimNut.csv", header = FALSE)
head(rootshoot)
# Name Columns
colnames(rootshoot)[2] <- "Treatment"
colnames(rootshoot)[3] <- "AverageWeight"
colnames(rootshoot)[4] <- "Standard Deviation"
colnames(rootshoot)[5] <- "se"
head(rootshoot)
rootshoot

Now make the graph the same way as we did above with ggplot2.

#create plot
ggplot(data = rootshoot, mapping = aes(x = Treatment, y = AverageWeight)) +
  geom_col(width = 0.5) +
  ggtitle("Average Weight After Fertilizer Addition on High Phosphorus Soil")+
  scale_x_discrete(labels = abbreviate, limits=c("RO Water Shoot","RO Water Root", "Phosphorus Shoot","Phosphorus Root", "Nitrogen + Phosphorus Shoot", "Nitrogen + Phosphorus Root", "Nitrogen Shoot", "Nitrogen Root")) +
  scale_y_continuous("Average Root Weight (G)") +
  geom_errorbar(aes(ymin = AverageWeight-se, ymax = AverageWeight+se), #http://www.cookbook-r.com/Graphs/Plotting_means_and_error_bars_(ggplot2)/
                size=.3,width=.2)

LS0tCnRpdGxlOiAiTWluZ28gUGFyayBHYXJsaWMgTXVzdGFyZCBMaW1pdGluZyBOdXRyaWVudCBHcmFwaCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ21kK1NoaWZ0K0VudGVyKi4gCgpBZGQgYSBuZXcgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpJbnNlcnQgQ2h1bmsqIGJ1dHRvbiBvbiB0aGUgdG9vbGJhciBvciBieSBwcmVzc2luZyAqQ21kK09wdGlvbitJKi4KCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ21kK1NoaWZ0K0sqIHRvIHByZXZpZXcgdGhlIEhUTUwgZmlsZSkuCgpGaXJzdCBJIGltcG9ydGVkIHRoZSAuY3N2IG1hc3RlciBzaGVldCBhbmQgcmVhZCB0aGUgZGF0YSBpbnRvIFIgU3R1ZGlvCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpICNMb2FkIHRoZSBwbG90dGluZyBsaWJyYXJ5CmxpYnJhcnkoRGVzY1Rvb2xzKQpzZXR3ZCgifi9EZXNrdG9wL0dhcmxpY011c3RhcmQiKQpkYXRhIDwtIHJlYWQuY3N2KCdHYXJsaWNfTGltaXRpbmdOdXRyaWVudF9NaW5nb1BhcmtTb2lscy5jc3YnKQpoZWFkKGRhdGEpCm5hbWVzKGRhdGEpCmBgYApOZXh0IEkgZ2VuZXJhdGVkIHN1YnNldCB0aGUgZGF0YSBmb3IgZWFjaCB0cmVhdG1lbnQsIHN0YXJ0aW5nIHdpdGggJ1JPIFdhdGVyJyBhbmQgZ2VuZXJhdGVkIHRoZSBhdmVyYWdlLCBzZCwgYW5kIHNlIG9mIGVhY2ggdHJlYXRtZW50LiBBZnRlciBnZW5lcmF0aW5nIHRoZXNlIHRyZWF0bWVudHMgSSBjb21iaW5lZCB0aGVtIGludG8gYSB2ZWN0b3IgdGhhdCB3YXMgdGhlbiB3cml0dGVuIHRvIGEgLmNzdiBmaWxlLgpgYGB7cn0KIyoqKmNoYW5nZSBUcmVhdG1lbnQqKiogc3Vic2V0IGRhdGEgdG8gZ2V0IGF2ZXJhZ2VzLCBTdGFuZGFyZCBkZXZpYXRpb24sIHN0ZCBlcnJvcgpzdWIgPSBzdWJzZXQoZGF0YSwgVHJlYXRtZW50ID09ICJSTyBXYXRlciIpCiNjYWxjdWxhdGUgYXZnLCBzdGRldiwgc3RkZXJyb3IKYXZnIDwtIG1lYW4oc3ViJFNob290V2VpZ2h0KSAKc3RkZXYgPC0gc2Qoc3ViJFNob290V2VpZ2h0KQpzZSA8LSBNZWFuU0Uoc3ViJFNob290V2VpZ2h0KQojIGNyZWF0ZSBhIHZlY3RvciB0byBzdG9yZSBhbGwgZGF0YS4gKioqY2hhbmdlIHRyZWF0bWVudCBuYW1lKioqCnJlc3VsdHMgPC0gYygiUk8gV2F0ZXIiLCBhdmcsIHN0ZGV2LCBzZSkKIyBwdXQgdmVjdG9yIGludG8gbWF0cml4IGFuZCB3cml0ZSBvdXRwdXQgdG8gQ1NWCm91dHB1dDEgPC0gYXMubWF0cml4KHQocmVzdWx0cykpCndyaXRlLnRhYmxlKG91dHB1dDEsIGZpbGUgPSAic2hvb3R3ZWlnaHRhdmcxLmNzdiIsIHNlcCA9ICIsIiwgY29sLm5hbWVzID0gRkFMU0UsIGFwcGVuZCA9IFRSVUUpICMgcmVwZWF0IGZvciBhbGwgZGF0YQpgYGAKSSByZXBlYXRlZCB0aGlzIGZvciBQaG9zcGhvcnVzLi4uCmBgYHtyfQojKioqY2hhbmdlIFRyZWF0bWVudCoqKiBzdWJzZXQgZGF0YSB0byBnZXQgYXZlcmFnZXMsIFN0YW5kYXJkIGRldmlhdGlvbiwgc3RkIGVycm9yCnN1YiA9IHN1YnNldChkYXRhLCBUcmVhdG1lbnQgPT0gIlBob3NwaG9ydXMiKQojY2FsY3VsYXRlIGF2Zywgc3RkZXYsIHN0ZGVycm9yCmF2ZyA8LSBtZWFuKHN1YiRTaG9vdFdlaWdodCkgCnN0ZGV2IDwtIHNkKHN1YiRTaG9vdFdlaWdodCkKc2UgPC0gTWVhblNFKHN1YiRTaG9vdFdlaWdodCkKIyBjcmVhdGUgYSB2ZWN0b3IgdG8gc3RvcmUgYWxsIGRhdGEuICoqKmNoYW5nZSB0cmVhdG1lbnQgbmFtZSoqKgpyZXN1bHRzIDwtIGMoIlBob3NwaG9ydXMiLCBhdmcsIHN0ZGV2LCBzZSkKIyBwdXQgdmVjdG9yIGludG8gbWF0cml4IGFuZCB3cml0ZSBvdXRwdXQgdG8gQ1NWCm91dHB1dDEgPC0gYXMubWF0cml4KHQocmVzdWx0cykpCndyaXRlLnRhYmxlKG91dHB1dDEsIGZpbGUgPSAic2hvb3R3ZWlnaHRhdmcxLmNzdiIsIHNlcCA9ICIsIiwgY29sLm5hbWVzID0gRkFMU0UsIGFwcGVuZCA9IFRSVUUpICMgcmVwZWF0IGZvciBhbGwgZGF0YQpgYGAKVGhlbiBmb3IgTml0cm9nZW4uLi4KYGBge3J9CiMqKipjaGFuZ2UgVHJlYXRtZW50KioqIHN1YnNldCBkYXRhIHRvIGdldCBhdmVyYWdlcywgU3RhbmRhcmQgZGV2aWF0aW9uLCBzdGQgZXJyb3IKc3ViID0gc3Vic2V0KGRhdGEsIFRyZWF0bWVudCA9PSAiTml0cm9nZW4iKQojY2FsY3VsYXRlIGF2Zywgc3RkZXYsIHN0ZGVycm9yCmF2ZyA8LSBtZWFuKHN1YiRTaG9vdFdlaWdodCkgCnN0ZGV2IDwtIHNkKHN1YiRTaG9vdFdlaWdodCkKc2UgPC0gTWVhblNFKHN1YiRTaG9vdFdlaWdodCkKIyBjcmVhdGUgYSB2ZWN0b3IgdG8gc3RvcmUgYWxsIGRhdGEuICoqKmNoYW5nZSB0cmVhdG1lbnQgbmFtZSoqKgpyZXN1bHRzIDwtIGMoIk5pdHJvZ2VuIiwgYXZnLCBzdGRldiwgc2UpCiMgcHV0IHZlY3RvciBpbnRvIG1hdHJpeCBhbmQgd3JpdGUgb3V0cHV0IHRvIENTVgpvdXRwdXQxIDwtIGFzLm1hdHJpeCh0KHJlc3VsdHMpKQp3cml0ZS50YWJsZShvdXRwdXQxLCBmaWxlID0gInNob290d2VpZ2h0YXZnMS5jc3YiLCBzZXAgPSAiLCIsIGNvbC5uYW1lcyA9IEZBTFNFLCBhcHBlbmQgPSBUUlVFKSAjIHJlcGVhdCBmb3IgYWxsIGRhdGEKYGBgCkFuZCBsYXN0bHkgZm9yIE5pdHJvZ2VuICtQaG9zcGhvcnVzLi4uCmBgYHtyfQojKioqY2hhbmdlIFRyZWF0bWVudCoqKiBzdWJzZXQgZGF0YSB0byBnZXQgYXZlcmFnZXMsIFN0YW5kYXJkIGRldmlhdGlvbiwgc3RkIGVycm9yCnN1YiA9IHN1YnNldChkYXRhLCBUcmVhdG1lbnQgPT0gIk5pdHJvZ2VuICtQaG9zcGhvcnVzIikKI2NhbGN1bGF0ZSBhdmcsIHN0ZGV2LCBzdGRlcnJvcgphdmcgPC0gbWVhbihzdWIkU2hvb3RXZWlnaHQpIApzdGRldiA8LSBzZChzdWIkU2hvb3RXZWlnaHQpCnNlIDwtIE1lYW5TRShzdWIkU2hvb3RXZWlnaHQpCiMgY3JlYXRlIGEgdmVjdG9yIHRvIHN0b3JlIGFsbCBkYXRhLiAqKipjaGFuZ2UgdHJlYXRtZW50IG5hbWUqKioKcmVzdWx0cyA8LSBjKCJOaXRyb2dlbiArUGhvc3Bob3J1cyIsIGF2Zywgc3RkZXYsIHNlKQojIHB1dCB2ZWN0b3IgaW50byBtYXRyaXggYW5kIHdyaXRlIG91dHB1dCB0byBDU1YKb3V0cHV0MSA8LSBhcy5tYXRyaXgodChyZXN1bHRzKSkKd3JpdGUudGFibGUob3V0cHV0MSwgZmlsZSA9ICJzaG9vdHdlaWdodGF2ZzEuY3N2Iiwgc2VwID0gIiwiLCBjb2wubmFtZXMgPSBGQUxTRSwgYXBwZW5kID0gVFJVRSkgIyByZXBlYXQgZm9yIGFsbCBkYXRhCmBgYApOZXh0IEkgd2FudGVkIHRvIGltcG9ydCB0aGUgZGF0YSBmcm9tIHRoZSAuY3N2IGZpbGUgdGhhdCBJIGhhZCBqdXN0IGNyZWF0ZWQuCmBgYHtyfQojcmVhZCBpbiB0aGUgY2FsY3VsYXRlZCB2YWx1ZXMgYW5kIGdpdmUgY29sdW1ucyBuYW1lcwpzaG9vdGF2Z2RhdGEgPC0gcmVhZC5jc3YoInNob290d2VpZ2h0YXZnMS5jc3YiLCBoZWFkZXIgPSBGQUxTRSkKaGVhZChzaG9vdGF2Z2RhdGEpCmBgYApJIHRoZW4gd2FudGVkIHRvIGxhYmVsIHRoZSBjb2x1bW5zIHRoZSB3YXkgdGhhdCBJIGhhZCB3cml0dGVuIHRoZW0gaW4gdGhlIHZlY3RvciBhYm92ZSBmb3Igb3V0cHV0LiBJIHRoZW4gZG91YmxlIGNoZWNrZWQgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIG5hbWVzIG1hdGNoZWQgdXAgd2l0aCB0aGUgY29ycmVjdCBjb2x1bW5zCmBgYHtyfQojIE5hbWUgQ29sdW1ucwpjb2xuYW1lcyhzaG9vdGF2Z2RhdGEpWzJdIDwtICJUcmVhdG1lbnQiCmNvbG5hbWVzKHNob290YXZnZGF0YSlbM10gPC0gIkF2ZXJhZ2VTaG9vdFdlaWdodCIKY29sbmFtZXMoc2hvb3RhdmdkYXRhKVs0XSA8LSAiU3RhbmRhcmQgRGV2aWF0aW9uIgpjb2xuYW1lcyhzaG9vdGF2Z2RhdGEpWzVdIDwtICJzZSIKaGVhZChzaG9vdGF2Z2RhdGEpCmBgYApMYXN0bHkgSSB3YW50ZWQgdG8gY3JlYXRlIGEgYmFyIGNoYXJ0IHRoYXQgcmVwcmVzZW50ZWQgd2hhdCB3YXMgaW4gJ3Nob290d2VpZ2h0YXZnMS5jc3YnIHVzaW5nIGdncGxvdC4gTW9zdCBvZiB0aGUgcmVzb3VyY2VzIEkgdXNlZCB0byBhaWQgaW4gdGhlIGNyZWF0aW9uIG9mIHRoaXMgcGxvdCB3ZXJlIGZvdW5kIHdpdGggdGhlICJSIGZvciBEYXRhIFNjaWVuY2UiIG1hbnVhbCAoaHR0cDovL3I0ZHMuaGFkLmNvLm56L2RhdGEtdmlzdWFsaXNhdGlvbi5odG1sI2dlb21ldHJpYy1vYmplY3RzKSBhbmQgdXNpbmcgdGhlICJnZ3Bsb3QyIGRhdGEgdmlzdWFsaXphdGlvbiBjaGVhdHNoZWV0IiAoaHR0cHM6Ly93d3cucnN0dWRpby5jb20vd3AtY29udGVudC91cGxvYWRzLzIwMTUvMDMvZ2dwbG90Mi1jaGVhdHNoZWV0LnBkZiksIGFuZCBhIGxpdHRsZSBoZWxwIHdpdGggcmVmaW5pbmcgdGhlIGVycm9yIGJhcnMgZnJvbSB0aGUgIlIgQ29va2Jvb2siIChodHRwOi8vd3d3LmNvb2tib29rLXIuY29tL0dyYXBocy9QbG90dGluZ19tZWFuc19hbmRfZXJyb3JfYmFyc18oZ2dwbG90MikvKQpgYGB7cn0KI2NyZWF0ZSBwbG90CmdncGxvdChkYXRhID0gc2hvb3RhdmdkYXRhLCBtYXBwaW5nID0gYWVzKHggPSBUcmVhdG1lbnQsIHkgPSBBdmVyYWdlU2hvb3RXZWlnaHQpKSArCiAgZ2VvbV9jb2wod2lkdGggPSAwLjUpICsKICBnZ3RpdGxlKCJBdmVyYWdlIFNob290IFdlaWdodCBBZnRlciBGZXJ0aWxpemVyIEFkZGl0aW9uIG9uIEhpZ2ggUGhvc3Bob3J1cyBTb2lsIikrCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHM9YygiUk8gV2F0ZXIiLCJQaG9zcGhvcnVzIiwiTml0cm9nZW4gK1Bob3NwaG9ydXMiLCAiTml0cm9nZW4iKSkgKwogIHNjYWxlX3lfY29udGludW91cygiQXZlcmFnZSBTaG9vdCBXZWlnaHQgKEcpIikgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBBdmVyYWdlU2hvb3RXZWlnaHQtc2UsIHltYXggPSBBdmVyYWdlU2hvb3RXZWlnaHQrc2UpLAogICAgICAgICAgICAgICAgICBzaXplPS4zLHdpZHRoPS4yKQpgYGAKVGhpcyBncmFwaCBoZWxwcyB0byBpbGx1c3RyYXRlIHRoYXQgb24gb3VyIHVyYmFuIHNvaWwgZnJvbSBNaW5nbyBQYXJrLCBoeXBvdGhlc2l6ZWQgdG8gYmUgUCByaWNoLCB0aGF0IGFkZGl0aW9ucyBvZiBQaG9zcGhvcnVzIGZlcnRpbGl6ZXIgcHJvdmlkZWQgbm8gc2lnbmlmaWNhbnQgZ2FpbiBpbiBhdmVyYWdlIHNob290IHdlaWdodCBmb3IgZ2FybGljIG11c3RhcmQuIE9uIHRoZSBvdGhlciBoYW5kLCB0aGUgYWRkaXRpb24gb2YgTiB0byB0aGUgTWluZ28gc29pbHMgY2F1c2VkIGFuIGluY3JlYXNlIGluIGF2ZXJhZ2Ugc2hvb3Qgd2VpZ2h0LCBzdWdnZXN0aW5nIHRoYXQgdGhlc2Ugc29pbHMgbWF5IGluIGZhY3QgYmUgTiBsaW1pdGVkLiAKCk5vdyB0byByZXBlYXQgd2l0aCB0aGUgcm9vdHMKYGBge3J9CiMqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgojUm9vdCBkYXRhCiNIYWQgdG8gY3JlYXRlIHNlcGFyYXRlIGRhdGEgc2hlZXQgd2l0aCBvbmx5IFJvb3RkYXRhCmRhdGEgPC0gcmVhZC5jc3YoJ01pbmdvUGFya0xpbU51dF9yb290cy5jc3YnKQpoZWFkKGRhdGEpCm5hbWVzKGRhdGEpCmBgYApOb3cgY2FsY3VsYXRlIHRoZSBhdmVyYWdlcyBmb3IgZWFjaCBvZiB0aGUgdHJlYXRtZW50cy4gU3RhcnRpbmcgd2l0aCBSTyBXYXRlcgpgYGB7cn0Kc3ViID0gc3Vic2V0KGRhdGEsIFRyZWF0bWVudCA9PSAiUk8gV2F0ZXIiKQpzdWIKI2NhbGN1bGF0ZSBhdmcsIHN0ZGV2LCBzdGRlcnJvcgphdmcgPC0gbWVhbihzdWIkUm9vdFdlaWdodCkgCnN0ZGV2IDwtIHNkKHN1YiRSb290V2VpZ2h0KQpzZSA8LSBNZWFuU0Uoc3ViJFJvb3RXZWlnaHQpCiMgY3JlYXRlIGEgdmVjdG9yIHRvIHN0b3JlIGFsbCBkYXRhLiAqKipjaGFuZ2UgdHJlYXRtZW50IG5hbWUqKioKcmVzdWx0cyA8LSBjKCJSTyBXYXRlciIsIGF2Zywgc3RkZXYsIHNlKQojIHB1dCB2ZWN0b3IgaW50byBtYXRyaXggYW5kIHdyaXRlIG91dHB1dCB0byBDU1YKb3V0cHV0MSA8LSBhcy5tYXRyaXgodChyZXN1bHRzKSkKd3JpdGUudGFibGUob3V0cHV0MSwgZmlsZSA9ICJyb290d2VpZ2h0YXZnMi5jc3YiLCBzZXAgPSAiLCIsIGNvbC5uYW1lcyA9IEZBTFNFLCBhcHBlbmQgPSBUUlVFKSAjIHJlcGVhdCBmb3IgYWxsIGRhdGEKYGBgCk5leHQgUGhvc3Bob3J1cy4uLgpgYGB7cn0Kc3ViID0gc3Vic2V0KGRhdGEsIFRyZWF0bWVudCA9PSAiUGhvc3Bob3J1cyIpCnN1YgojY2FsY3VsYXRlIGF2Zywgc3RkZXYsIHN0ZGVycm9yCmF2ZyA8LSBtZWFuKHN1YiRSb290V2VpZ2h0KSAKc3RkZXYgPC0gc2Qoc3ViJFJvb3RXZWlnaHQpCnNlIDwtIE1lYW5TRShzdWIkUm9vdFdlaWdodCkKIyBjcmVhdGUgYSB2ZWN0b3IgdG8gc3RvcmUgYWxsIGRhdGEuICoqKmNoYW5nZSB0cmVhdG1lbnQgbmFtZSoqKgpyZXN1bHRzIDwtIGMoIlBob3NwaG9ydXMiLCBhdmcsIHN0ZGV2LCBzZSkKIyBwdXQgdmVjdG9yIGludG8gbWF0cml4IGFuZCB3cml0ZSBvdXRwdXQgdG8gQ1NWCm91dHB1dDEgPC0gYXMubWF0cml4KHQocmVzdWx0cykpCndyaXRlLnRhYmxlKG91dHB1dDEsIGZpbGUgPSAicm9vdHdlaWdodGF2ZzIuY3N2Iiwgc2VwID0gIiwiLCBjb2wubmFtZXMgPSBGQUxTRSwgYXBwZW5kID0gVFJVRSkgIyByZXBlYXQgZm9yIGFsbCBkYXRhCmBgYApUaGVuIHRvIE5pdHJvZ2VuLi4uCmBgYHtyfQpzdWIgPSBzdWJzZXQoZGF0YSwgVHJlYXRtZW50ID09ICJOaXRyb2dlbiIpCnN1YgojY2FsY3VsYXRlIGF2Zywgc3RkZXYsIHN0ZGVycm9yCmF2ZyA8LSBtZWFuKHN1YiRSb290V2VpZ2h0KSAKc3RkZXYgPC0gc2Qoc3ViJFJvb3RXZWlnaHQpCnNlIDwtIE1lYW5TRShzdWIkUm9vdFdlaWdodCkKIyBjcmVhdGUgYSB2ZWN0b3IgdG8gc3RvcmUgYWxsIGRhdGEuICoqKmNoYW5nZSB0cmVhdG1lbnQgbmFtZSoqKgpyZXN1bHRzIDwtIGMoIk5pdHJvZ2VuIiwgYXZnLCBzdGRldiwgc2UpCiMgcHV0IHZlY3RvciBpbnRvIG1hdHJpeCBhbmQgd3JpdGUgb3V0cHV0IHRvIENTVgpvdXRwdXQxIDwtIGFzLm1hdHJpeCh0KHJlc3VsdHMpKQp3cml0ZS50YWJsZShvdXRwdXQxLCBmaWxlID0gInJvb3R3ZWlnaHRhdmcyLmNzdiIsIHNlcCA9ICIsIiwgY29sLm5hbWVzID0gRkFMU0UsIGFwcGVuZCA9IFRSVUUpICMgcmVwZWF0IGZvciBhbGwgZGF0YQpgYGAKYW5kIGxhc3RseSBOaXRyb2dlbiArUGhvc3Bob3J1cy4uLgpgYGB7cn0Kc3ViID0gc3Vic2V0KGRhdGEsIFRyZWF0bWVudCA9PSAiTml0cm9nZW4gK1Bob3NwaG9ydXMiKQpzdWIKI2NhbGN1bGF0ZSBhdmcsIHN0ZGV2LCBzdGRlcnJvcgphdmcgPC0gbWVhbihzdWIkUm9vdFdlaWdodCkgCnN0ZGV2IDwtIHNkKHN1YiRSb290V2VpZ2h0KQpzZSA8LSBNZWFuU0Uoc3ViJFJvb3RXZWlnaHQpCiMgY3JlYXRlIGEgdmVjdG9yIHRvIHN0b3JlIGFsbCBkYXRhLiAqKipjaGFuZ2UgdHJlYXRtZW50IG5hbWUqKioKcmVzdWx0cyA8LSBjKCJOaXRyb2dlbiArUGhvc3Bob3J1cyIsIGF2Zywgc3RkZXYsIHNlKQojIHB1dCB2ZWN0b3IgaW50byBtYXRyaXggYW5kIHdyaXRlIG91dHB1dCB0byBDU1YKb3V0cHV0MSA8LSBhcy5tYXRyaXgodChyZXN1bHRzKSkKd3JpdGUudGFibGUob3V0cHV0MSwgZmlsZSA9ICJyb290d2VpZ2h0YXZnMi5jc3YiLCBzZXAgPSAiLCIsIGNvbC5uYW1lcyA9IEZBTFNFLCBhcHBlbmQgPSBUUlVFKSAjIHJlcGVhdCBmb3IgYWxsIGRhdGEKYGBgClRoZW4gd2UgcmVhZCBpbiB0aGUgdmFsdWVzIGZyb20gdGhlIC5jc3Ygd2UganVzdCBjcmVhdGVkCmBgYHtyfQojcmVhZCBpbiB0aGUgY2FsY3VsYXRlZCB2YWx1ZXMgYW5kIGdpdmUgY29sdW1ucyBuYW1lcwpyb290YXZnZGF0YSA8LSByZWFkLmNzdigicm9vdHdlaWdodGF2ZzIuY3N2IiwgaGVhZGVyID0gRkFMU0UpCmhlYWQocm9vdGF2Z2RhdGEpCiMgTmFtZSBDb2x1bW5zCmNvbG5hbWVzKHJvb3RhdmdkYXRhKVsyXSA8LSAiVHJlYXRtZW50Igpjb2xuYW1lcyhyb290YXZnZGF0YSlbM10gPC0gIkF2ZXJhZ2VSb290V2VpZ2h0Igpjb2xuYW1lcyhyb290YXZnZGF0YSlbNF0gPC0gIlN0YW5kYXJkIERldmlhdGlvbiIKY29sbmFtZXMocm9vdGF2Z2RhdGEpWzVdIDwtICJzZSIKaGVhZChyb290YXZnZGF0YSkKYGBgClRoZW4gYWdhaW4gSSBtYWRlIHRoZSBncmFwaCB1c2luZyBnZ3Bsb3QyLgpgYGB7cn0KI2NyZWF0ZSBwbG90CmdncGxvdChkYXRhID0gcm9vdGF2Z2RhdGEsIG1hcHBpbmcgPSBhZXMoeCA9IFRyZWF0bWVudCwgeSA9IEF2ZXJhZ2VSb290V2VpZ2h0KSkgKwogIGdlb21fY29sKHdpZHRoID0gMC41KSArCiAgZ2d0aXRsZSgiQXZlcmFnZSBSb290IFdlaWdodCBBZnRlciBGZXJ0aWxpemVyIEFkZGl0aW9uIG9uIEhpZ2ggUGhvc3Bob3J1cyBTb2lsIikrCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHM9YygiUk8gV2F0ZXIiLCJQaG9zcGhvcnVzIiwiTml0cm9nZW4gK1Bob3NwaG9ydXMiLCAiTml0cm9nZW4iKSkgKwogIHNjYWxlX3lfY29udGludW91cygiQXZlcmFnZSBSb290IFdlaWdodCAoRykiKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IEF2ZXJhZ2VSb290V2VpZ2h0LXNlLCB5bWF4ID0gQXZlcmFnZVJvb3RXZWlnaHQrc2UpLCAjaHR0cDovL3d3dy5jb29rYm9vay1yLmNvbS9HcmFwaHMvUGxvdHRpbmdfbWVhbnNfYW5kX2Vycm9yX2JhcnNfKGdncGxvdDIpLwogICAgICAgICAgICAgICAgc2l6ZT0uMyx3aWR0aD0uMikKYGBgCk5vdyB0byBjb21iaW5lIHRoaXMgZGF0YSB0b2dldGhlciBJIHB1dCBpdCBpbiBhIC5jc3YgZmlsZSB0aXRsZWQgJ1Jvb3RTaG9vdENvbWJNaW5nb1BhcmtMaW1OdXQuY3N2JwoKYGBge3J9CnJvb3RzaG9vdCA8LSByZWFkLmNzdigiUm9vdFNob290Q29tYk1pbmdvUGFya0xpbU51dC5jc3YiLCBoZWFkZXIgPSBGQUxTRSkKaGVhZChyb290c2hvb3QpCiMgTmFtZSBDb2x1bW5zCmNvbG5hbWVzKHJvb3RzaG9vdClbMl0gPC0gIlRyZWF0bWVudCIKY29sbmFtZXMocm9vdHNob290KVszXSA8LSAiQXZlcmFnZVdlaWdodCIKY29sbmFtZXMocm9vdHNob290KVs0XSA8LSAiU3RhbmRhcmQgRGV2aWF0aW9uIgpjb2xuYW1lcyhyb290c2hvb3QpWzVdIDwtICJzZSIKaGVhZChyb290c2hvb3QpCnJvb3RzaG9vdApgYGAKTm93IG1ha2UgdGhlIGdyYXBoIHRoZSBzYW1lIHdheSBhcyB3ZSBkaWQgYWJvdmUgd2l0aCBnZ3Bsb3QyLgpgYGB7cn0KI2NyZWF0ZSBwbG90CmdncGxvdChkYXRhID0gcm9vdHNob290LCBtYXBwaW5nID0gYWVzKHggPSBUcmVhdG1lbnQsIHkgPSBBdmVyYWdlV2VpZ2h0KSkgKwogIGdlb21fY29sKHdpZHRoID0gMC41KSArCiAgZ2d0aXRsZSgiQXZlcmFnZSBXZWlnaHQgQWZ0ZXIgRmVydGlsaXplciBBZGRpdGlvbiBvbiBIaWdoIFBob3NwaG9ydXMgU29pbCIpKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYWJicmV2aWF0ZSwgbGltaXRzPWMoIlJPIFdhdGVyIFNob290IiwiUk8gV2F0ZXIgUm9vdCIsICJQaG9zcGhvcnVzIFNob290IiwiUGhvc3Bob3J1cyBSb290IiwgIk5pdHJvZ2VuICsgUGhvc3Bob3J1cyBTaG9vdCIsICJOaXRyb2dlbiArIFBob3NwaG9ydXMgUm9vdCIsICJOaXRyb2dlbiBTaG9vdCIsICJOaXRyb2dlbiBSb290IikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoIkF2ZXJhZ2UgUm9vdCBXZWlnaHQgKEcpIikgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBBdmVyYWdlV2VpZ2h0LXNlLCB5bWF4ID0gQXZlcmFnZVdlaWdodCtzZSksICNodHRwOi8vd3d3LmNvb2tib29rLXIuY29tL0dyYXBocy9QbG90dGluZ19tZWFuc19hbmRfZXJyb3JfYmFyc18oZ2dwbG90MikvCiAgICAgICAgICAgICAgICBzaXplPS4zLHdpZHRoPS4yKQpgYGAKCg==