Data Import

df<-Complete_Summarized_Data_Bamboo
df

Inspect for NAs - Aligned Rank Transform won’t run otherwise!

which(is.na(df), arr.ind=TRUE)
     row col

Convert variables into factors

df$Location <- factor(df$Location)
df$Species <- factor(df$Species)

Check ANOVA assumptions

Run Shapiro-Wilk’s Test to test for normality.

df%>%shapiro_test(CWT, CD, MOE, MOR, MVS, GSG, FSPL, MaxStress)

Only CWT (Culm Wall Thickness) seems to satisfy the normality assumption. We can proceed with ANOVA for CWT; rest of the variables will be passed to ART (Aligned Rank Transformation) ANOVA, a non-parametric approach to factorial ANOVA.

Run a two-way ANOVA for Culm Wall Thickness

We now proceed to analyzing CWT using regular ANOVA. We detect a strong interaction effect for Species x Location.

lm.cwt <-lm(CWT ~ Species * Location + (1|Sample), data=df) 
anova(lm.cwt)
Analysis of Variance Table

Response: CWT
                 Df  Sum Sq Mean Sq F value    Pr(>F)    
Species           2 191.222  95.611 96.8085 < 2.2e-16 ***
Location          4  11.617   2.904  2.9406   0.02686 *  
Species:Location  6  49.245   8.208  8.3103 1.083e-06 ***
Residuals        65  64.196   0.988                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Run an ART ANOVA for CD, MOE, MOR, SpGrav, FSPL, MVS, and MaxStress

Now, we run ART-ANOVA for the rest of the variables in the data frame.

 lm.cd <- art(CD ~ Species * Location + (1|Sample), data=df)
anova(lm.cd)
Analysis of Variance of Aligned Rank Transformed Data

Table Type: Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df) 
Model: Mixed Effects (lmer)
Response: art(CD)

                         F Df Df.res     Pr(>F)    
1 Species           8.5699  2     63  0.0005105 ***
2 Location         10.7778  4     63 1.0176e-06 ***
3 Species:Location  9.5626  6     63 1.8359e-07 ***
---
Signif. codes:   0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
plot(cd.plot.fig)

Generate pairwise comparisons across Species within Location: Culm Diameter


  # 'Species' is a column in the data frame
unique_species <- unique(df$Species)

# Initialize an empty list to store the results for each species
cld_results_list <- list()

# Loop through each species
for (species in unique_species) {
  # Subset data for the current species
  subset_species <- filter(df, Species == species)
  
  # Fit an art model for the current species
  art_model <- art(formula = CD ~ Location, data = subset_species)
  
  # Perform contrasts for the main effects of Location using art.con()
  marginal <- art.con(art_model, "Location")
  
  # Convert to data frame
  marginal_df <- as.data.frame(marginal)
  
  # Perform post-hoc comparisons and store the results in the list
  cld_results_list[[species]] <- cldList(p.value ~ contrast, data = marginal_df)
}

# Access the results for a specific species
cld_results_list$"Tinik"
cld_results_list$"Giant"
cld_results_list$"Bolo"
lm.moe <- art(MOE ~ Species * Location + (1|Sample), data=df) 
anova(lm.moe)
Analysis of Variance of Aligned Rank Transformed Data

Table Type: Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df) 
Model: Mixed Effects (lmer)
Response: art(MOE)

                         F Df Df.res     Pr(>F)    
1 Species           6.0788  2     63  0.0038556  **
2 Location         14.1179  4     63 2.7956e-08 ***
3 Species:Location 15.2145  6     63 1.1100e-10 ***
---
Signif. codes:   0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
plot(moe.plot.fig)

# 'Species' is a column in the data frame
unique_species <- unique(df$Species)

# Initialize an empty list to store the results for each species
cld_results_list <- list()

# Loop through each species
for (species in unique_species) {
  # Subset data for the current species
  subset_species <- filter(df, Species == species)
  
  # Fit an art model for the current species
  art_model <- art(formula = MOE ~ Location, data = subset_species)
  
  # Perform contrasts for the main effects of Location using art.con()
  marginal <- art.con(art_model, "Location")
  
  # Convert to data frame
  marginal_df <- as.data.frame(marginal)
  
  # Perform post-hoc comparisons and store the results in the list
  cld_results_list[[species]] <- cldList(p.value ~ contrast, data = marginal_df)
}

# Access the results for a specific species
cld_results_list$"Tinik"
cld_results_list$"Giant"
cld_results_list$"Bolo"
lm.mor <- art(MOR ~ Species * Location + (1|Sample), data=df)
anova(lm.mor)
Analysis of Variance of Aligned Rank Transformed Data

Table Type: Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df) 
Model: Mixed Effects (lmer)
Response: art(MOR)

                         F Df Df.res     Pr(>F)    
1 Species           2.6638  2     63   0.077528   .
2 Location          9.3363  4     63 5.4538e-06 ***
3 Species:Location 10.8956  6     63 2.7399e-08 ***
---
Signif. codes:   0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
plot(mor.plot.fig)

# 'Species' is a column in the data frame
unique_species <- unique(df$Species)

# Initialize an empty list to store the results for each species
cld_results_list <- list()

# Loop through each species
for (species in unique_species) {
  # Subset data for the current species
  subset_species <- filter(df, Species == species)
  
  # Fit an art model for the current species
  art_model <- art(formula = MOR ~ Location, data = subset_species)
  
  # Perform contrasts for the main effects of Location using art.con()
  marginal <- art.con(art_model, "Location")
  
  # Convert to data frame
  marginal_df <- as.data.frame(marginal)
  
  # Perform post-hoc comparisons and store the results in the list
  cld_results_list[[species]] <- cldList(p.value ~ contrast, data = marginal_df)
}

# Access the results for a specific species
cld_results_list$"Tinik"
cld_results_list$"Giant"
cld_results_list$"Bolo"
lm.gsg <- art(GSG ~ Species * Location + (1|Sample), data=df)
anova(lm.gsg)
Analysis of Variance of Aligned Rank Transformed Data

Table Type: Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df) 
Model: Mixed Effects (lmer)
Response: art(GSG)

                         F Df Df.res    Pr(>F)   
1 Species          0.26865  2     63 0.7652786   
2 Location         4.71671  4     63 0.0021541 **
3 Species:Location 2.73439  6     63 0.0200236  *
---
Signif. codes:   0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
plot(gsg.plot.fig)

# 'Species' is a column in the data frame
unique_species <- unique(df$Species)

# Initialize an empty list to store the results for each species
cld_results_list <- list()

# Loop through each species
for (species in unique_species) {
  # Subset data for the current species
  subset_species <- filter(df, Species == species)
  
  # Fit an art model for the current species
  art_model <- art(formula = GSG ~ Location, data = subset_species)
  
  # Perform contrasts for the main effects of Location using art.con()
  marginal <- art.con(art_model, "Location")
  
  # Convert to data frame
  marginal_df <- as.data.frame(marginal)
  
  # Perform post-hoc comparisons and store the results in the list
  cld_results_list[[species]] <- cldList(p.value ~ contrast, data = marginal_df)
}

# Access the results for a specific species
cld_results_list$"Tinik"
cld_results_list$"Giant"
cld_results_list$"Bolo"
lm.fspl <- art(FSPL ~ Species * Location + (1|Sample), data=df)
anova(lm.fspl)
Analysis of Variance of Aligned Rank Transformed Data

Table Type: Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df) 
Model: Mixed Effects (lmer)
Response: art(FSPL)

                        F Df Df.res     Pr(>F)    
1 Species          1.1738  2     63  0.3158545    
2 Location         4.8432  4     63  0.0018062  **
3 Species:Location 7.8765  6     63 2.3921e-06 ***
---
Signif. codes:   0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
plot(fspl.plot.fig)

# 'Species' is a column in the data frame
unique_species <- unique(df$Species)

# Initialize an empty list to store the results for each species
cld_results_list <- list()

# Loop through each species
for (species in unique_species) {
  # Subset data for the current species
  subset_species <- filter(df, Species == species)
  
  # Fit an art model for the current species
  art_model <- art(formula = FSPL ~ Location, data = subset_species)
  
  # Perform contrasts for the main effects of Location using art.con()
  marginal <- art.con(art_model, "Location")
  
  # Convert to data frame
  marginal_df <- as.data.frame(marginal)
  
  # Perform post-hoc comparisons and store the results in the list
  cld_results_list[[species]] <- cldList(p.value ~ contrast, data = marginal_df)
}

# Access the results for a specific species
cld_results_list$"Tinik"
cld_results_list$"Giant"
cld_results_list$"Bolo"
lm.stress <- art(MaxStress ~ Species * Location + (1|Sample), data=df)
anova(lm.stress)
Analysis of Variance of Aligned Rank Transformed Data

Table Type: Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df) 
Model: Mixed Effects (lmer)
Response: art(MaxStress)

                        F Df Df.res     Pr(>F)    
1 Species          1.0516  2     63 0.35541314    
2 Location         8.1105  4     63 2.4316e-05 ***
3 Species:Location 5.5986  6     63 0.00010521 ***
---
Signif. codes:   0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
plot(stress.plot.fig)

# 'Species' is a column in the data frame
unique_species <- unique(df$Species)

# Initialize an empty list to store the results for each species
cld_results_list <- list()

# Loop through each species
for (species in unique_species) {
  # Subset data for the current species
  subset_species <- filter(df, Species == species)
  
  # Fit an art model for the current species
  art_model <- art(formula = MaxStress ~ Location, data = subset_species)
  
  # Perform contrasts for the main effects of Location using art.con()
  marginal <- art.con(art_model, "Location")
  
  # Convert to data frame
  marginal_df <- as.data.frame(marginal)
  
  # Perform post-hoc comparisons and store the results in the list
  cld_results_list[[species]] <- cldList(p.value ~ contrast, data = marginal_df)
}

# Access the results for a specific species
cld_results_list$"Tinik"
cld_results_list$"Giant"
cld_results_list$"Bolo"
LS0tCnRpdGxlOiAiTW9ycGhvbG9naWNhbCBhbmQgbWVjaGFuaWNhbCBwcm9wZXJ0aWVzIG9mIGluZGlnZW5vdXMgYmFtYm9vIHNwZWNpZXMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQod2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UpCmBgYAoKWyoqRGF0YSBJbXBvcnQqKl17c3R5bGU9ImZvbnQtc2l6ZTogMjBweDsifQoKYGBge3J9CmRmPC1Db21wbGV0ZV9TdW1tYXJpemVkX0RhdGFfQmFtYm9vCmRmCmBgYAoKSW5zcGVjdCBmb3IgTkFzIC0gQWxpZ25lZCBSYW5rIFRyYW5zZm9ybSB3b24ndCBydW4gb3RoZXJ3aXNlIQoKYGBge3J9CndoaWNoKGlzLm5hKGRmKSwgYXJyLmluZD1UUlVFKQpgYGAKCkNvbnZlcnQgdmFyaWFibGVzIGludG8gZmFjdG9ycwoKYGBge3J9CmRmJExvY2F0aW9uIDwtIGZhY3RvcihkZiRMb2NhdGlvbikKZGYkU3BlY2llcyA8LSBmYWN0b3IoZGYkU3BlY2llcykKYGBgCgpbKipDaGVjayBBTk9WQSBhc3N1bXB0aW9ucyoqXXtzdHlsZT0iZm9udC1zaXplOiAyMHB4OyJ9CgpSdW4gU2hhcGlyby1XaWxrJ3MgVGVzdCB0byB0ZXN0IGZvciBub3JtYWxpdHkuCgpgYGB7cn0KZGYlPiVzaGFwaXJvX3Rlc3QoQ1dULCBDRCwgTU9FLCBNT1IsIE1WUywgR1NHLCBGU1BMLCBNYXhTdHJlc3MpCmBgYAoKT25seSBDV1QgKEN1bG0gV2FsbCBUaGlja25lc3MpIHNlZW1zIHRvIHNhdGlzZnkgdGhlIG5vcm1hbGl0eSBhc3N1bXB0aW9uLiBXZSBjYW4gcHJvY2VlZCB3aXRoIEFOT1ZBIGZvciBDV1Q7IHJlc3Qgb2YgdGhlIHZhcmlhYmxlcyB3aWxsIGJlIHBhc3NlZCB0byBBUlQgKEFsaWduZWQgUmFuayBUcmFuc2Zvcm1hdGlvbikgQU5PVkEsIGEgbm9uLXBhcmFtZXRyaWMgYXBwcm9hY2ggdG8gZmFjdG9yaWFsIEFOT1ZBLgoKWyoqUnVuIGEgdHdvLXdheSBBTk9WQSBmb3IgQ3VsbSBXYWxsIFRoaWNrbmVzcyoqXXtzdHlsZT0iZm9udC1zaXplOiAyMHB4OyJ9CgpXZSBub3cgcHJvY2VlZCB0byBhbmFseXppbmcgQ1dUIHVzaW5nIHJlZ3VsYXIgQU5PVkEuIFdlIGRldGVjdCBhIHN0cm9uZyBpbnRlcmFjdGlvbiBlZmZlY3QgZm9yIFNwZWNpZXMgeCBMb2NhdGlvbi4KCmBgYHtyfQpsbS5jd3QgPC1sbShDV1QgfiBTcGVjaWVzICogTG9jYXRpb24gKyAoMXxTYW1wbGUpLCBkYXRhPWRmKSAKYW5vdmEobG0uY3d0KQpgYGAKClsqKlJ1biBhbiBBUlQgQU5PVkEgZm9yIENELCBNT0UsIE1PUiwgU3BHcmF2LCBGU1BMLCBNVlMsIGFuZCBNYXhTdHJlc3MqKl17c3R5bGU9ImZvbnQtc2l6ZTogMjBweDsifQoKTm93LCB3ZSBydW4gQVJULUFOT1ZBIGZvciB0aGUgcmVzdCBvZiB0aGUgdmFyaWFibGVzIGluIHRoZSBkYXRhIGZyYW1lLgoKYGBge3J9CiBsbS5jZCA8LSBhcnQoQ0QgfiBTcGVjaWVzICogTG9jYXRpb24gKyAoMXxTYW1wbGUpLCBkYXRhPWRmKQphbm92YShsbS5jZCkKcGxvdChjZC5wbG90LmZpZykKYGBgCgpHZW5lcmF0ZSBwYWlyd2lzZSBjb21wYXJpc29ucyBhY3Jvc3MgU3BlY2llcyB3aXRoaW4gTG9jYXRpb246IEN1bG0gRGlhbWV0ZXIKCmBgYHtyfQoKICAjICdTcGVjaWVzJyBpcyBhIGNvbHVtbiBpbiB0aGUgZGF0YSBmcmFtZQp1bmlxdWVfc3BlY2llcyA8LSB1bmlxdWUoZGYkU3BlY2llcykKCiMgSW5pdGlhbGl6ZSBhbiBlbXB0eSBsaXN0IHRvIHN0b3JlIHRoZSByZXN1bHRzIGZvciBlYWNoIHNwZWNpZXMKY2xkX3Jlc3VsdHNfbGlzdCA8LSBsaXN0KCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc3BlY2llcwpmb3IgKHNwZWNpZXMgaW4gdW5pcXVlX3NwZWNpZXMpIHsKICAjIFN1YnNldCBkYXRhIGZvciB0aGUgY3VycmVudCBzcGVjaWVzCiAgc3Vic2V0X3NwZWNpZXMgPC0gZmlsdGVyKGRmLCBTcGVjaWVzID09IHNwZWNpZXMpCiAgCiAgIyBGaXQgYW4gYXJ0IG1vZGVsIGZvciB0aGUgY3VycmVudCBzcGVjaWVzCiAgYXJ0X21vZGVsIDwtIGFydChmb3JtdWxhID0gQ0QgfiBMb2NhdGlvbiwgZGF0YSA9IHN1YnNldF9zcGVjaWVzKQogIAogICMgUGVyZm9ybSBjb250cmFzdHMgZm9yIHRoZSBtYWluIGVmZmVjdHMgb2YgTG9jYXRpb24gdXNpbmcgYXJ0LmNvbigpCiAgbWFyZ2luYWwgPC0gYXJ0LmNvbihhcnRfbW9kZWwsICJMb2NhdGlvbiIpCiAgCiAgIyBDb252ZXJ0IHRvIGRhdGEgZnJhbWUKICBtYXJnaW5hbF9kZiA8LSBhcy5kYXRhLmZyYW1lKG1hcmdpbmFsKQogIAogICMgUGVyZm9ybSBwb3N0LWhvYyBjb21wYXJpc29ucyBhbmQgc3RvcmUgdGhlIHJlc3VsdHMgaW4gdGhlIGxpc3QKICBjbGRfcmVzdWx0c19saXN0W1tzcGVjaWVzXV0gPC0gY2xkTGlzdChwLnZhbHVlIH4gY29udHJhc3QsIGRhdGEgPSBtYXJnaW5hbF9kZikKfQoKIyBBY2Nlc3MgdGhlIHJlc3VsdHMgZm9yIGEgc3BlY2lmaWMgc3BlY2llcwpjbGRfcmVzdWx0c19saXN0JCJUaW5payIKY2xkX3Jlc3VsdHNfbGlzdCQiR2lhbnQiCmNsZF9yZXN1bHRzX2xpc3QkIkJvbG8iCmBgYAoKCmBgYHtyfQpsbS5tb2UgPC0gYXJ0KE1PRSB+IFNwZWNpZXMgKiBMb2NhdGlvbiArICgxfFNhbXBsZSksIGRhdGE9ZGYpIAphbm92YShsbS5tb2UpCnBsb3QobW9lLnBsb3QuZmlnKQpgYGAKCmBgYHtyfQojICdTcGVjaWVzJyBpcyBhIGNvbHVtbiBpbiB0aGUgZGF0YSBmcmFtZQp1bmlxdWVfc3BlY2llcyA8LSB1bmlxdWUoZGYkU3BlY2llcykKCiMgSW5pdGlhbGl6ZSBhbiBlbXB0eSBsaXN0IHRvIHN0b3JlIHRoZSByZXN1bHRzIGZvciBlYWNoIHNwZWNpZXMKY2xkX3Jlc3VsdHNfbGlzdCA8LSBsaXN0KCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc3BlY2llcwpmb3IgKHNwZWNpZXMgaW4gdW5pcXVlX3NwZWNpZXMpIHsKICAjIFN1YnNldCBkYXRhIGZvciB0aGUgY3VycmVudCBzcGVjaWVzCiAgc3Vic2V0X3NwZWNpZXMgPC0gZmlsdGVyKGRmLCBTcGVjaWVzID09IHNwZWNpZXMpCiAgCiAgIyBGaXQgYW4gYXJ0IG1vZGVsIGZvciB0aGUgY3VycmVudCBzcGVjaWVzCiAgYXJ0X21vZGVsIDwtIGFydChmb3JtdWxhID0gTU9FIH4gTG9jYXRpb24sIGRhdGEgPSBzdWJzZXRfc3BlY2llcykKICAKICAjIFBlcmZvcm0gY29udHJhc3RzIGZvciB0aGUgbWFpbiBlZmZlY3RzIG9mIExvY2F0aW9uIHVzaW5nIGFydC5jb24oKQogIG1hcmdpbmFsIDwtIGFydC5jb24oYXJ0X21vZGVsLCAiTG9jYXRpb24iKQogIAogICMgQ29udmVydCB0byBkYXRhIGZyYW1lCiAgbWFyZ2luYWxfZGYgPC0gYXMuZGF0YS5mcmFtZShtYXJnaW5hbCkKICAKICAjIFBlcmZvcm0gcG9zdC1ob2MgY29tcGFyaXNvbnMgYW5kIHN0b3JlIHRoZSByZXN1bHRzIGluIHRoZSBsaXN0CiAgY2xkX3Jlc3VsdHNfbGlzdFtbc3BlY2llc11dIDwtIGNsZExpc3QocC52YWx1ZSB+IGNvbnRyYXN0LCBkYXRhID0gbWFyZ2luYWxfZGYpCn0KCiMgQWNjZXNzIHRoZSByZXN1bHRzIGZvciBhIHNwZWNpZmljIHNwZWNpZXMKY2xkX3Jlc3VsdHNfbGlzdCQiVGluaWsiCmNsZF9yZXN1bHRzX2xpc3QkIkdpYW50IgpjbGRfcmVzdWx0c19saXN0JCJCb2xvIgpgYGAKCmBgYHtyfQpsbS5tb3IgPC0gYXJ0KE1PUiB+IFNwZWNpZXMgKiBMb2NhdGlvbiArICgxfFNhbXBsZSksIGRhdGE9ZGYpCmFub3ZhKGxtLm1vcikKcGxvdChtb3IucGxvdC5maWcpCmBgYAoKYGBge3J9CiMgJ1NwZWNpZXMnIGlzIGEgY29sdW1uIGluIHRoZSBkYXRhIGZyYW1lCnVuaXF1ZV9zcGVjaWVzIDwtIHVuaXF1ZShkZiRTcGVjaWVzKQoKIyBJbml0aWFsaXplIGFuIGVtcHR5IGxpc3QgdG8gc3RvcmUgdGhlIHJlc3VsdHMgZm9yIGVhY2ggc3BlY2llcwpjbGRfcmVzdWx0c19saXN0IDwtIGxpc3QoKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzcGVjaWVzCmZvciAoc3BlY2llcyBpbiB1bmlxdWVfc3BlY2llcykgewogICMgU3Vic2V0IGRhdGEgZm9yIHRoZSBjdXJyZW50IHNwZWNpZXMKICBzdWJzZXRfc3BlY2llcyA8LSBmaWx0ZXIoZGYsIFNwZWNpZXMgPT0gc3BlY2llcykKICAKICAjIEZpdCBhbiBhcnQgbW9kZWwgZm9yIHRoZSBjdXJyZW50IHNwZWNpZXMKICBhcnRfbW9kZWwgPC0gYXJ0KGZvcm11bGEgPSBNT1IgfiBMb2NhdGlvbiwgZGF0YSA9IHN1YnNldF9zcGVjaWVzKQogIAogICMgUGVyZm9ybSBjb250cmFzdHMgZm9yIHRoZSBtYWluIGVmZmVjdHMgb2YgTG9jYXRpb24gdXNpbmcgYXJ0LmNvbigpCiAgbWFyZ2luYWwgPC0gYXJ0LmNvbihhcnRfbW9kZWwsICJMb2NhdGlvbiIpCiAgCiAgIyBDb252ZXJ0IHRvIGRhdGEgZnJhbWUKICBtYXJnaW5hbF9kZiA8LSBhcy5kYXRhLmZyYW1lKG1hcmdpbmFsKQogIAogICMgUGVyZm9ybSBwb3N0LWhvYyBjb21wYXJpc29ucyBhbmQgc3RvcmUgdGhlIHJlc3VsdHMgaW4gdGhlIGxpc3QKICBjbGRfcmVzdWx0c19saXN0W1tzcGVjaWVzXV0gPC0gY2xkTGlzdChwLnZhbHVlIH4gY29udHJhc3QsIGRhdGEgPSBtYXJnaW5hbF9kZikKfQoKIyBBY2Nlc3MgdGhlIHJlc3VsdHMgZm9yIGEgc3BlY2lmaWMgc3BlY2llcwpjbGRfcmVzdWx0c19saXN0JCJUaW5payIKY2xkX3Jlc3VsdHNfbGlzdCQiR2lhbnQiCmNsZF9yZXN1bHRzX2xpc3QkIkJvbG8iCmBgYAoKYGBge3J9CmxtLmdzZyA8LSBhcnQoR1NHIH4gU3BlY2llcyAqIExvY2F0aW9uICsgKDF8U2FtcGxlKSwgZGF0YT1kZikKYW5vdmEobG0uZ3NnKQpwbG90KGdzZy5wbG90LmZpZykKYGBgCgpgYGB7cn0KIyAnU3BlY2llcycgaXMgYSBjb2x1bW4gaW4gdGhlIGRhdGEgZnJhbWUKdW5pcXVlX3NwZWNpZXMgPC0gdW5pcXVlKGRmJFNwZWNpZXMpCgojIEluaXRpYWxpemUgYW4gZW1wdHkgbGlzdCB0byBzdG9yZSB0aGUgcmVzdWx0cyBmb3IgZWFjaCBzcGVjaWVzCmNsZF9yZXN1bHRzX2xpc3QgPC0gbGlzdCgpCgojIExvb3AgdGhyb3VnaCBlYWNoIHNwZWNpZXMKZm9yIChzcGVjaWVzIGluIHVuaXF1ZV9zcGVjaWVzKSB7CiAgIyBTdWJzZXQgZGF0YSBmb3IgdGhlIGN1cnJlbnQgc3BlY2llcwogIHN1YnNldF9zcGVjaWVzIDwtIGZpbHRlcihkZiwgU3BlY2llcyA9PSBzcGVjaWVzKQogIAogICMgRml0IGFuIGFydCBtb2RlbCBmb3IgdGhlIGN1cnJlbnQgc3BlY2llcwogIGFydF9tb2RlbCA8LSBhcnQoZm9ybXVsYSA9IEdTRyB+IExvY2F0aW9uLCBkYXRhID0gc3Vic2V0X3NwZWNpZXMpCiAgCiAgIyBQZXJmb3JtIGNvbnRyYXN0cyBmb3IgdGhlIG1haW4gZWZmZWN0cyBvZiBMb2NhdGlvbiB1c2luZyBhcnQuY29uKCkKICBtYXJnaW5hbCA8LSBhcnQuY29uKGFydF9tb2RlbCwgIkxvY2F0aW9uIikKICAKICAjIENvbnZlcnQgdG8gZGF0YSBmcmFtZQogIG1hcmdpbmFsX2RmIDwtIGFzLmRhdGEuZnJhbWUobWFyZ2luYWwpCiAgCiAgIyBQZXJmb3JtIHBvc3QtaG9jIGNvbXBhcmlzb25zIGFuZCBzdG9yZSB0aGUgcmVzdWx0cyBpbiB0aGUgbGlzdAogIGNsZF9yZXN1bHRzX2xpc3RbW3NwZWNpZXNdXSA8LSBjbGRMaXN0KHAudmFsdWUgfiBjb250cmFzdCwgZGF0YSA9IG1hcmdpbmFsX2RmKQp9CgojIEFjY2VzcyB0aGUgcmVzdWx0cyBmb3IgYSBzcGVjaWZpYyBzcGVjaWVzCmNsZF9yZXN1bHRzX2xpc3QkIlRpbmlrIgpjbGRfcmVzdWx0c19saXN0JCJHaWFudCIKY2xkX3Jlc3VsdHNfbGlzdCQiQm9sbyIKYGBgCgpgYGB7cn0KbG0uZnNwbCA8LSBhcnQoRlNQTCB+IFNwZWNpZXMgKiBMb2NhdGlvbiArICgxfFNhbXBsZSksIGRhdGE9ZGYpCmFub3ZhKGxtLmZzcGwpCnBsb3QoZnNwbC5wbG90LmZpZykKYGBgCgpgYGB7cn0KIyAnU3BlY2llcycgaXMgYSBjb2x1bW4gaW4gdGhlIGRhdGEgZnJhbWUKdW5pcXVlX3NwZWNpZXMgPC0gdW5pcXVlKGRmJFNwZWNpZXMpCgojIEluaXRpYWxpemUgYW4gZW1wdHkgbGlzdCB0byBzdG9yZSB0aGUgcmVzdWx0cyBmb3IgZWFjaCBzcGVjaWVzCmNsZF9yZXN1bHRzX2xpc3QgPC0gbGlzdCgpCgojIExvb3AgdGhyb3VnaCBlYWNoIHNwZWNpZXMKZm9yIChzcGVjaWVzIGluIHVuaXF1ZV9zcGVjaWVzKSB7CiAgIyBTdWJzZXQgZGF0YSBmb3IgdGhlIGN1cnJlbnQgc3BlY2llcwogIHN1YnNldF9zcGVjaWVzIDwtIGZpbHRlcihkZiwgU3BlY2llcyA9PSBzcGVjaWVzKQogIAogICMgRml0IGFuIGFydCBtb2RlbCBmb3IgdGhlIGN1cnJlbnQgc3BlY2llcwogIGFydF9tb2RlbCA8LSBhcnQoZm9ybXVsYSA9IEZTUEwgfiBMb2NhdGlvbiwgZGF0YSA9IHN1YnNldF9zcGVjaWVzKQogIAogICMgUGVyZm9ybSBjb250cmFzdHMgZm9yIHRoZSBtYWluIGVmZmVjdHMgb2YgTG9jYXRpb24gdXNpbmcgYXJ0LmNvbigpCiAgbWFyZ2luYWwgPC0gYXJ0LmNvbihhcnRfbW9kZWwsICJMb2NhdGlvbiIpCiAgCiAgIyBDb252ZXJ0IHRvIGRhdGEgZnJhbWUKICBtYXJnaW5hbF9kZiA8LSBhcy5kYXRhLmZyYW1lKG1hcmdpbmFsKQogIAogICMgUGVyZm9ybSBwb3N0LWhvYyBjb21wYXJpc29ucyBhbmQgc3RvcmUgdGhlIHJlc3VsdHMgaW4gdGhlIGxpc3QKICBjbGRfcmVzdWx0c19saXN0W1tzcGVjaWVzXV0gPC0gY2xkTGlzdChwLnZhbHVlIH4gY29udHJhc3QsIGRhdGEgPSBtYXJnaW5hbF9kZikKfQoKIyBBY2Nlc3MgdGhlIHJlc3VsdHMgZm9yIGEgc3BlY2lmaWMgc3BlY2llcwpjbGRfcmVzdWx0c19saXN0JCJUaW5payIKY2xkX3Jlc3VsdHNfbGlzdCQiR2lhbnQiCmNsZF9yZXN1bHRzX2xpc3QkIkJvbG8iCmBgYAoKYGBge3J9CmxtLnN0cmVzcyA8LSBhcnQoTWF4U3RyZXNzIH4gU3BlY2llcyAqIExvY2F0aW9uICsgKDF8U2FtcGxlKSwgZGF0YT1kZikKYW5vdmEobG0uc3RyZXNzKQpwbG90KHN0cmVzcy5wbG90LmZpZykKYGBgCgpgYGB7cn0KIyAnU3BlY2llcycgaXMgYSBjb2x1bW4gaW4gdGhlIGRhdGEgZnJhbWUKdW5pcXVlX3NwZWNpZXMgPC0gdW5pcXVlKGRmJFNwZWNpZXMpCgojIEluaXRpYWxpemUgYW4gZW1wdHkgbGlzdCB0byBzdG9yZSB0aGUgcmVzdWx0cyBmb3IgZWFjaCBzcGVjaWVzCmNsZF9yZXN1bHRzX2xpc3QgPC0gbGlzdCgpCgojIExvb3AgdGhyb3VnaCBlYWNoIHNwZWNpZXMKZm9yIChzcGVjaWVzIGluIHVuaXF1ZV9zcGVjaWVzKSB7CiAgIyBTdWJzZXQgZGF0YSBmb3IgdGhlIGN1cnJlbnQgc3BlY2llcwogIHN1YnNldF9zcGVjaWVzIDwtIGZpbHRlcihkZiwgU3BlY2llcyA9PSBzcGVjaWVzKQogIAogICMgRml0IGFuIGFydCBtb2RlbCBmb3IgdGhlIGN1cnJlbnQgc3BlY2llcwogIGFydF9tb2RlbCA8LSBhcnQoZm9ybXVsYSA9IE1heFN0cmVzcyB+IExvY2F0aW9uLCBkYXRhID0gc3Vic2V0X3NwZWNpZXMpCiAgCiAgIyBQZXJmb3JtIGNvbnRyYXN0cyBmb3IgdGhlIG1haW4gZWZmZWN0cyBvZiBMb2NhdGlvbiB1c2luZyBhcnQuY29uKCkKICBtYXJnaW5hbCA8LSBhcnQuY29uKGFydF9tb2RlbCwgIkxvY2F0aW9uIikKICAKICAjIENvbnZlcnQgdG8gZGF0YSBmcmFtZQogIG1hcmdpbmFsX2RmIDwtIGFzLmRhdGEuZnJhbWUobWFyZ2luYWwpCiAgCiAgIyBQZXJmb3JtIHBvc3QtaG9jIGNvbXBhcmlzb25zIGFuZCBzdG9yZSB0aGUgcmVzdWx0cyBpbiB0aGUgbGlzdAogIGNsZF9yZXN1bHRzX2xpc3RbW3NwZWNpZXNdXSA8LSBjbGRMaXN0KHAudmFsdWUgfiBjb250cmFzdCwgZGF0YSA9IG1hcmdpbmFsX2RmKQp9CgojIEFjY2VzcyB0aGUgcmVzdWx0cyBmb3IgYSBzcGVjaWZpYyBzcGVjaWVzCmNsZF9yZXN1bHRzX2xpc3QkIlRpbmlrIgpjbGRfcmVzdWx0c19saXN0JCJHaWFudCIKY2xkX3Jlc3VsdHNfbGlzdCQiQm9sbyIKYGBgCg==