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 Ctrl+Shift+Enter.

### load libraries
library(adegenet)

### read in data -- GenePop format, converted to genind format
popdata <- read.genepop("Cor_striata_ssrgenotyper_06.pop.gen", ncode = 3L)

 Converting data from a Genepop .gen file to a genind object... 


File description:  SSR markers for Cor_striata_ssrgenotyper_05 
Duplicate individual names detected. Coercing them to be unique.

...done.
popdata
/// GENIND OBJECT /////////

 // 83 individuals; 19 loci; 79 alleles; size: 53.4 Kb

 // Basic content
   @tab:  83 x 79 matrix of allele counts
   @loc.n.all: number of alleles per locus (range: 2-5)
   @loc.fac: locus factor for the 79 columns of @tab
   @all.names: list of allele names for each locus
   @ploidy: ploidy of each individual  (range: 2-2)
   @type:  codom
   @call: read.genepop(file = "Cor_striata_ssrgenotyper_06.pop.gen", 
    ncode = 3L)

 // Optional content
   @pop: population of each individual (group size range: 16-26)
# /// GENIND OBJECT /////////                                             #
#                                                                         #
#  // 83 individuals; 19 loci; 79 alleles; size: 53.4 Kb                  #
#                                                                         #
#  // Basic content                                                       #
#    @tab:  83 x 79 matrix of allele counts                               #
#    @loc.n.all: number of alleles per locus (range: 2-5)                 #
#    @loc.fac: locus factor for the 79 columns of @tab                    #
#    @all.names: list of allele names for each locus                      #
#    @ploidy: ploidy of each individual  (range: 2-2)                     #
#    @type:  codom                                                        #
#    @call: read.genepop(file = "Cor_striata_ssrgenotyper_06.pop.gen",    #
#     ncode = 3L)                                                         #
#                                                                         #
# // Optional content                                                      #
#   @pop: population of each individual (group size range: 16-26)          #


### Just checking...
is.genind(popdata)
[1] TRUE
### define "populations"
pop(popdata) <- rep(c("vreelandii","striata","Sierra_Nevada","Coast_Cascades"), c(22,26,16,19))
pop(popdata)
 [1] vreelandii     vreelandii     vreelandii     vreelandii     vreelandii    
 [6] vreelandii     vreelandii     vreelandii     vreelandii     vreelandii    
[11] vreelandii     vreelandii     vreelandii     vreelandii     vreelandii    
[16] vreelandii     vreelandii     vreelandii     vreelandii     vreelandii    
[21] vreelandii     vreelandii     striata        striata        striata       
[26] striata        striata        striata        striata        striata       
[31] striata        striata        striata        striata        striata       
[36] striata        striata        striata        striata        striata       
[41] striata        striata        striata        striata        striata       
[46] striata        striata        striata        Sierra_Nevada  Sierra_Nevada 
[51] Sierra_Nevada  Sierra_Nevada  Sierra_Nevada  Sierra_Nevada  Sierra_Nevada 
[56] Sierra_Nevada  Sierra_Nevada  Sierra_Nevada  Sierra_Nevada  Sierra_Nevada 
[61] Sierra_Nevada  Sierra_Nevada  Sierra_Nevada  Sierra_Nevada  Coast_Cascades
[66] Coast_Cascades Coast_Cascades Coast_Cascades Coast_Cascades Coast_Cascades
[71] Coast_Cascades Coast_Cascades Coast_Cascades Coast_Cascades Coast_Cascades
[76] Coast_Cascades Coast_Cascades Coast_Cascades Coast_Cascades Coast_Cascades
[81] Coast_Cascades Coast_Cascades Coast_Cascades
Levels: vreelandii striata Sierra_Nevada Coast_Cascades
### set color scheme
mycol <- c("green","red","blue","magenta")

### Find clusters
grp <- find.clusters(popdata, max.n.clust = 40)
Choose the number PCs to retain (>= 1): 
70

Choose the number of clusters (>=2): 
4


# Choose the number PCs to retain (>= 1): 
6
[1] 6
# Choose the number of clusters (>=2): 
4
[1] 4
# Also, you can use K-means clustering to find the K with minimum BIC

maxK <- 10
myMat <- matrix(nrow=10, ncol=maxK)
colnames(myMat) <- 1:ncol(myMat)
for(i in 1:nrow(myMat)){
  grp <- find.clusters(popdata, n.pca = 40, choose.n.clust = FALSE,  max.n.clust = maxK)
  myMat[i,] <- grp$Kstat
}

library(reshape2)
my_df <- melt(myMat)
colnames(my_df)[1:3] <- c("Group", "K", "BIC")
my_df$K <- as.factor(my_df$K)
head(my_df)

# The K vs. BIC plot
library(ggplot2)
p1 <- ggplot(my_df, aes(x = K, y = BIC))
p1 <- p1 + geom_boxplot()
p1 <- p1 + theme_bw()
p1 <- p1 + xlab("Number of groups (K)")
p1



### conduct DAPC
vcf_dapc <- dapc(popdata, n.pca = 40, n.da = 5)

### IMPORTANT: find the optimal # of PCs to retain using the 'a-score' criterion
temp <- optim.a.score(vcf_dapc)

#* n = 6 PCs = optimal!

# Cross validation method to find # of PCs
xval = xvalDapc(x, popdata$pop, n.pca.max=10, training.set=0.9,
result="groupMean", center=TRUE, scale=FALSE,
n.rep=100, n.pca=NULL, parallel="snow", ncpus=4)

## Number of PCs with best stats
xval$`Number of PCs Achieving Highest Mean Success`
[1] "6"
xval$`Number of PCs Achieving Lowest MSE`
[1] "6"
xval$`Root Mean Squared Error by Number of PCs of PCA` # lower score = better
        1         2         3         4         5         6         7         8         9 
0.4553692 0.3415904 0.2653287 0.2372806 0.2394293 0.2171069 0.2399725 0.2683540 0.2729405 
# n = 6 is optimal

vcf_dapc <- dapc(popdata, n.pca = 6, n.da = 3)


### Set up the plots

par(mfrow=c(2,2))


### DAPC1 vs 2 scatter
scatter(vcf_dapc, col = mycol, xax = 1, yax = 2, cex = 2, scree.da=FALSE, legend = FALSE, grp = pop(popdata))

### DAPC1 vs 3 scatter
scatter(vcf_dapc, col = mycol, xax = 1, yax = 3, cex = 2, scree.da=FALSE, legend = FALSE, grp = pop(popdata))

### Check the assignment plot
assignplot(vcf_dapc)

### plot membership probabilities
compoplot(vcf_dapc, lab="",ncol=1,col=mycol)



### Check the assignment probabilities
vcf_dapc$posterior
     vreelandii      striata Sierra_Nevada Coast_Cascades
01 9.974121e-01 2.562859e-03  2.229775e-05   2.790531e-06
02 9.836707e-01 1.631574e-02  1.151232e-05   2.066385e-06
03 9.951732e-01 7.168806e-04  2.923958e-03   1.185970e-03
04 9.991581e-01 8.279254e-04  1.152511e-05   2.465796e-06
05 9.960866e-01 3.722849e-03  1.586008e-04   3.193386e-05
06 9.925980e-01 6.508818e-03  4.571851e-04   4.360287e-04
07 9.974144e-01 1.374501e-03  1.058555e-03   1.525455e-04
08 9.812357e-01 1.210021e-02  6.108413e-03   5.556350e-04
09 9.935677e-01 6.287667e-03  1.257137e-04   1.891051e-05
10 9.975242e-01 1.922359e-03  3.595750e-04   1.938372e-04
11 9.968004e-01 1.506981e-03  9.494023e-04   7.432622e-04
12 9.745108e-01 1.593976e-03  2.119615e-02   2.699117e-03
13 9.959507e-01 2.693725e-03  1.806502e-05   1.337540e-03
14 9.466390e-01 4.791197e-02  4.275496e-03   1.173504e-03
15 9.999519e-01 4.709102e-05  8.947801e-07   1.455936e-07
16 9.999335e-01 5.961780e-06  5.846728e-05   2.043389e-06
17 9.995833e-01 4.127272e-04  3.161820e-06   8.287303e-07
18 9.989755e-01 7.226615e-04  2.718374e-04   3.001371e-05
19 9.996291e-01 2.042762e-04  1.653108e-05   1.501196e-04
20 9.944081e-01 1.529872e-04  6.063812e-04   4.832535e-03
21 9.998298e-01 9.238262e-05  5.810996e-05   1.973636e-05
22 9.980853e-01 1.664336e-03  2.284965e-04   2.182366e-05
23 8.583211e-04 9.988143e-01  2.780648e-04   4.930454e-05
24 5.505424e-06 9.868915e-01  1.149674e-02   1.606281e-03
25 1.115745e-03 9.896314e-01  7.959476e-03   1.293336e-03
26 3.130501e-06 9.994634e-01  4.447302e-04   8.870109e-05
27 6.581053e-06 9.999572e-01  1.321002e-05   2.296007e-05
28 3.621743e-03 9.834368e-01  1.056225e-02   2.379201e-03
29 8.716107e-02 9.126106e-01  3.756916e-05   1.907739e-04
30 3.786664e-02 3.423360e-01  5.207161e-01   9.908125e-02
31 5.681910e-02 9.431574e-01  1.815083e-05   5.315766e-06
32 8.504543e-06 9.777165e-01  6.496302e-03   1.577865e-02
33 5.959656e-08 9.884949e-01  2.701515e-03   8.803572e-03
34 9.488265e-04 9.989581e-01  4.796705e-05   4.508890e-05
35 1.933376e-05 9.999083e-01  3.403341e-05   3.835658e-05
36 2.501089e-03 9.963032e-01  5.936696e-04   6.020365e-04
37 1.582462e-03 9.983459e-01  5.776404e-05   1.386092e-05
38 3.780107e-05 9.272055e-01  3.765915e-02   3.509751e-02
39 3.089380e-06 9.985815e-01  1.000912e-04   1.315354e-03
40 1.526724e-03 9.895842e-01  4.502488e-03   4.386609e-03
41 5.538462e-02 3.271245e-01  3.815614e-01   2.359295e-01
42 7.130729e-03 9.682674e-01  2.256578e-02   2.036133e-03
43 4.922562e-03 8.648565e-01  5.030829e-02   7.991268e-02
44 2.915569e-04 1.475365e-01  3.565981e-01   4.955738e-01
45 1.211246e-02 9.863630e-01  1.046228e-03   4.782855e-04
46 2.171461e-01 2.881199e-01  4.601810e-01   3.455305e-02
47 2.797097e-04 9.996525e-01  5.984944e-05   7.923706e-06
48 6.678008e-02 9.331791e-01  3.609320e-05   4.700592e-06
49 1.474207e-03 1.841226e-03  8.693747e-01   1.273098e-01
50 2.255127e-03 9.079017e-05  6.761054e-01   3.215486e-01
51 6.329561e-05 6.657456e-02  7.515070e-01   1.818551e-01
52 7.129823e-03 1.277739e-02  4.166816e-01   5.634112e-01
53 1.283601e-09 3.056550e-04  8.523536e-01   1.473407e-01
54 7.501967e-03 6.689090e-04  6.754045e-01   3.164246e-01
55 3.446915e-07 1.896756e-05  7.984569e-01   2.015237e-01
56 1.232552e-02 4.702590e-02  6.337580e-01   3.068906e-01
57 4.581971e-04 6.701903e-04  8.000963e-01   1.987753e-01
58 1.492893e-01 1.665184e-03  7.501147e-01   9.893086e-02
59 1.186108e-03 2.337363e-03  8.625986e-01   1.338780e-01
60 1.388710e-03 1.836502e-01  7.109125e-01   1.040486e-01
61 1.218061e-05 3.285729e-03  8.802327e-01   1.164694e-01
62 1.035940e-05 4.519179e-03  9.240388e-01   7.143169e-02
63 2.712556e-05 1.005242e-03  1.950664e-01   8.039012e-01
64 1.974106e-05 9.524927e-01  4.156201e-02   5.925541e-03
65 5.688090e-05 2.576573e-02  1.134915e-02   9.628282e-01
66 1.504331e-06 2.205096e-06  7.906236e-03   9.920901e-01
67 5.570653e-04 2.067271e-02  5.827805e-01   3.959897e-01
68 3.120024e-07 3.937502e-03  1.669734e-01   8.290888e-01
69 8.312522e-03 1.383599e-04  7.682951e-03   9.838662e-01
70 3.437176e-05 4.050840e-05  2.300734e-01   7.698518e-01
71 4.788450e-06 2.185469e-04  4.911611e-02   9.506606e-01
72 3.247094e-05 1.349341e-01  2.785740e-01   5.864595e-01
73 1.926218e-08 3.176804e-06  6.626536e-01   3.373432e-01
74 2.795884e-04 1.320117e-05  3.516034e-02   9.645469e-01
75 5.311797e-04 1.627101e-03  4.143621e-02   9.564055e-01
76 1.785439e-03 6.032308e-02  3.457368e-01   5.921546e-01
77 1.485950e-03 1.881471e-02  8.743752e-01   1.053242e-01
78 9.584477e-05 3.312604e-04  8.518155e-01   1.477574e-01
79 2.481726e-05 1.522989e-03  7.749375e-01   2.235147e-01
80 4.456778e-07 2.590137e-03  6.016363e-03   9.913931e-01
81 2.052966e-08 2.696593e-05  1.308309e-02   9.868899e-01
82 3.597931e-02 6.470976e-01  1.630050e-01   1.539181e-01
83 1.539109e-03 2.120743e-02  4.160299e-01   5.612235e-01
#####################################
###    ENTIRE CODE in Markdown    ###
#####################################
# ---
# title: "2021_06_02_Cor_striata_DAPC_SSRgenotyper"
# output: 
#   html_notebook: 
#     theme: spacelab
# #editor_options: 
# #  chunk_output_type: console
# editor_options: 
#   chunk_output_type: inline
# ---
# 
# This is an [R Markdown](http://rmarkdown.rstudio.com) 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 *Ctrl+Shift+Enter*. 
# 
# ```{r, include=TRUE}
# ### load libraries
# library(adegenet)
# 
# ### read in data -- GenePop format, converted to genind format
# popdata <- read.genepop("Cor_striata_ssrgenotyper_06.pop.gen", ncode = 3L)
# popdata
# 
# # /// GENIND OBJECT /////////                                             #
# #                                                                         #
# #  // 83 individuals; 19 loci; 79 alleles; size: 53.4 Kb                  #
# #                                                                         #
# #  // Basic content                                                       #
# #    @tab:  83 x 79 matrix of allele counts                               #
# #    @loc.n.all: number of alleles per locus (range: 2-5)                 #
# #    @loc.fac: locus factor for the 79 columns of @tab                    #
# #    @all.names: list of allele names for each locus                      #
# #    @ploidy: ploidy of each individual  (range: 2-2)                     #
# #    @type:  codom                                                        #
# #    @call: read.genepop(file = "Cor_striata_ssrgenotyper_06.pop.gen",    #
# #     ncode = 3L)                                                         #
# #                                                                       #
# # // Optional content                                                      #
# #   @pop: population of each individual (group size range: 16-26)          #
# 
# 
# ### Just checking...
# is.genind(popdata)
# 
# ### define "populations"
# pop(popdata) <- rep(c("vreelandii","striata","Sierra_Nevada","Coast_Cascades"), c(22,26,16,19))
# pop(popdata)
# 
# ### set color scheme
# mycol <- c("green","red","blue","magenta")
# 
# ### Find clusters
# grp <- find.clusters(popdata, max.n.clust = 40)
# 
# # Choose the number PCs to retain (>= 1): 
# 6
# # Choose the number of clusters (>=2): 
# 4
# 
# 
# # Also, you can use K-means clustering to find the K with minimum BIC
# 
# maxK <- 10
# myMat <- matrix(nrow=10, ncol=maxK)
# colnames(myMat) <- 1:ncol(myMat)
# for(i in 1:nrow(myMat)){
#   grp <- find.clusters(popdata, n.pca = 40, choose.n.clust = FALSE,  max.n.clust = maxK)
#   myMat[i,] <- grp$Kstat
# }
# 
# library(reshape2)
# my_df <- melt(myMat)
# colnames(my_df)[1:3] <- c("Group", "K", "BIC")
# my_df$K <- as.factor(my_df$K)
# head(my_df)
# 
# # The K vs. BIC plot
# library(ggplot2)
# p1 <- ggplot(my_df, aes(x = K, y = BIC))
# p1 <- p1 + geom_boxplot()
# p1 <- p1 + theme_bw()
# p1 <- p1 + xlab("Number of groups (K)")
# p1
# 
# 
# ### conduct DAPC
# vcf_dapc <- dapc(popdata, n.pca = 40, n.da = 5)
# 
# ### IMPORTANT: find the optimal # of PCs to retain using the 'a-score' criterion
# temp <- optim.a.score(vcf_dapc)
# #* n = 6 PCs = optimal!
# 
# # Cross validation method to find # of PCs
# xval = xvalDapc(x, popdata$pop, n.pca.max=10, training.set=0.9,
# result="groupMean", center=TRUE, scale=FALSE,
# n.rep=30, n.pca=NULL, parallel="snow", ncpus=2)
# ## Number of PCs with best stats
# xval$`Number of PCs Achieving Highest Mean Success`
# xval$`Number of PCs Achieving Lowest MSE`
# xval$`Root Mean Squared Error by Number of PCs of PCA` # lower score = better
# 
# vcf_dapc <- dapc(popdata, n.pca = 7, n.da = 5)
# 
# 
# ### Set up the plots
# 
# par(mfrow=c(2,2))
# 
# ### DAPC1 vs 2 scatter
# scatter(vcf_dapc, col = mycol, xax = 1, yax = 2, cex = 2, scree.da=FALSE, legend = FALSE, grp = pop(popdata))
# 
# ### DAPC1 vs 3 scatter
# scatter(vcf_dapc, col = mycol, xax = 1, yax = 3, cex = 2, scree.da=FALSE, legend = FALSE, grp = pop(popdata))
# 
# ### Check the assignment plot
# assignplot(vcf_dapc)
# 
# ### plot membership probabilities
# compoplot(vcf_dapc, lab="",ncol=1,col=mycol)
# 
# 
# ### Check the assignment probabilities
# vcf_dapc$posterior
# 
# ```

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+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 Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

LS0tDQp0aXRsZTogIjIwMjFfMDZfMDJfQ29yX3N0cmlhdGFfREFQQ19TU1JnZW5vdHlwZXIiDQpvdXRwdXQ6IA0KICBodG1sX25vdGVib29rOiANCiAgICB0aGVtZTogc3BhY2VsYWINCiNlZGl0b3Jfb3B0aW9uczogDQojICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQ0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQotLS0NCg0KVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gDQoNClRyeSBleGVjdXRpbmcgdGhpcyBjaHVuayBieSBjbGlja2luZyB0aGUgKlJ1biogYnV0dG9uIHdpdGhpbiB0aGUgY2h1bmsgb3IgYnkgcGxhY2luZyB5b3VyIGN1cnNvciBpbnNpZGUgaXQgYW5kIHByZXNzaW5nICpDdHJsK1NoaWZ0K0VudGVyKi4gDQoNCmBgYHtyLCBpbmNsdWRlPVRSVUV9DQojIyMgbG9hZCBsaWJyYXJpZXMNCmxpYnJhcnkoYWRlZ2VuZXQpDQoNCiMjIyByZWFkIGluIGRhdGEgLS0gR2VuZVBvcCBmb3JtYXQsIGNvbnZlcnRlZCB0byBnZW5pbmQgZm9ybWF0DQpwb3BkYXRhIDwtIHJlYWQuZ2VuZXBvcCgiQ29yX3N0cmlhdGFfc3NyZ2Vub3R5cGVyXzA2LnBvcC5nZW4iLCBuY29kZSA9IDNMKQ0KcG9wZGF0YQ0KDQojIC8vLyBHRU5JTkQgT0JKRUNUIC8vLy8vLy8vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIw0KIyAgLy8gODMgaW5kaXZpZHVhbHM7IDE5IGxvY2k7IDc5IGFsbGVsZXM7IHNpemU6IDUzLjQgS2IgICAgICAgICAgICAgICAgICAjDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMNCiMgIC8vIEJhc2ljIGNvbnRlbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIw0KIyAgICBAdGFiOiAgODMgeCA3OSBtYXRyaXggb2YgYWxsZWxlIGNvdW50cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjDQojICAgIEBsb2Mubi5hbGw6IG51bWJlciBvZiBhbGxlbGVzIHBlciBsb2N1cyAocmFuZ2U6IDItNSkgICAgICAgICAgICAgICAgICMNCiMgICAgQGxvYy5mYWM6IGxvY3VzIGZhY3RvciBmb3IgdGhlIDc5IGNvbHVtbnMgb2YgQHRhYiAgICAgICAgICAgICAgICAgICAgIw0KIyAgICBAYWxsLm5hbWVzOiBsaXN0IG9mIGFsbGVsZSBuYW1lcyBmb3IgZWFjaCBsb2N1cyAgICAgICAgICAgICAgICAgICAgICAjDQojICAgIEBwbG9pZHk6IHBsb2lkeSBvZiBlYWNoIGluZGl2aWR1YWwgIChyYW5nZTogMi0yKSAgICAgICAgICAgICAgICAgICAgICMNCiMgICAgQHR5cGU6ICBjb2RvbSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIw0KIyAgICBAY2FsbDogcmVhZC5nZW5lcG9wKGZpbGUgPSAiQ29yX3N0cmlhdGFfc3NyZ2Vub3R5cGVyXzA2LnBvcC5nZW4iLCAgICAjDQojICAgICBuY29kZSA9IDNMKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMNCiMJCQkJCQkJCQkJCQkJCQkJCQkgICMNCiMgLy8gT3B0aW9uYWwgY29udGVudCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMNCiMgICBAcG9wOiBwb3B1bGF0aW9uIG9mIGVhY2ggaW5kaXZpZHVhbCAoZ3JvdXAgc2l6ZSByYW5nZTogMTYtMjYpICAgICAgICAgICMNCg0KDQojIyMgSnVzdCBjaGVja2luZy4uLg0KaXMuZ2VuaW5kKHBvcGRhdGEpDQoNCiMjIyBkZWZpbmUgInBvcHVsYXRpb25zIg0KcG9wKHBvcGRhdGEpIDwtIHJlcChjKCJ2cmVlbGFuZGlpIiwic3RyaWF0YSIsIlNpZXJyYV9OZXZhZGEiLCJDb2FzdF9DYXNjYWRlcyIpLCBjKDIyLDI2LDE2LDE5KSkNCnBvcChwb3BkYXRhKQ0KDQojIyMgc2V0IGNvbG9yIHNjaGVtZQ0KbXljb2wgPC0gYygiZ3JlZW4iLCJyZWQiLCJibHVlIiwibWFnZW50YSIpDQoNCiMjIyBGaW5kIGNsdXN0ZXJzDQpncnAgPC0gZmluZC5jbHVzdGVycyhwb3BkYXRhLCBtYXgubi5jbHVzdCA9IDQwKQ0KDQojIENob29zZSB0aGUgbnVtYmVyIFBDcyB0byByZXRhaW4gKD49IDEpOiANCjYNCiMgQ2hvb3NlIHRoZSBudW1iZXIgb2YgY2x1c3RlcnMgKD49Mik6IA0KNA0KDQoNCiMgQWxzbywgeW91IGNhbiB1c2UgSy1tZWFucyBjbHVzdGVyaW5nIHRvIGZpbmQgdGhlIEsgd2l0aCBtaW5pbXVtIEJJQw0KDQptYXhLIDwtIDEwDQpteU1hdCA8LSBtYXRyaXgobnJvdz0xMCwgbmNvbD1tYXhLKQ0KY29sbmFtZXMobXlNYXQpIDwtIDE6bmNvbChteU1hdCkNCmZvcihpIGluIDE6bnJvdyhteU1hdCkpew0KICBncnAgPC0gZmluZC5jbHVzdGVycyhwb3BkYXRhLCBuLnBjYSA9IDQwLCBjaG9vc2Uubi5jbHVzdCA9IEZBTFNFLCAgbWF4Lm4uY2x1c3QgPSBtYXhLKQ0KICBteU1hdFtpLF0gPC0gZ3JwJEtzdGF0DQp9DQoNCmxpYnJhcnkocmVzaGFwZTIpDQpteV9kZiA8LSBtZWx0KG15TWF0KQ0KY29sbmFtZXMobXlfZGYpWzE6M10gPC0gYygiR3JvdXAiLCAiSyIsICJCSUMiKQ0KbXlfZGYkSyA8LSBhcy5mYWN0b3IobXlfZGYkSykNCmhlYWQobXlfZGYpDQoNCiMgVGhlIEsgdnMuIEJJQyBwbG90DQpsaWJyYXJ5KGdncGxvdDIpDQpwMSA8LSBnZ3Bsb3QobXlfZGYsIGFlcyh4ID0gSywgeSA9IEJJQykpDQpwMSA8LSBwMSArIGdlb21fYm94cGxvdCgpDQpwMSA8LSBwMSArIHRoZW1lX2J3KCkNCnAxIDwtIHAxICsgeGxhYigiTnVtYmVyIG9mIGdyb3VwcyAoSykiKQ0KcDENCg0KDQojIyMgY29uZHVjdCBEQVBDDQp2Y2ZfZGFwYyA8LSBkYXBjKHBvcGRhdGEsIG4ucGNhID0gNDAsIG4uZGEgPSA1KQ0KDQojIyMgSU1QT1JUQU5UOiBmaW5kIHRoZSBvcHRpbWFsICMgb2YgUENzIHRvIHJldGFpbiB1c2luZyB0aGUgJ2Etc2NvcmUnIGNyaXRlcmlvbg0KdGVtcCA8LSBvcHRpbS5hLnNjb3JlKHZjZl9kYXBjKQ0KIyogbiA9IDYgUENzID0gb3B0aW1hbCENCg0KIyBDcm9zcyB2YWxpZGF0aW9uIG1ldGhvZCB0byBmaW5kICMgb2YgUENzDQp4dmFsID0geHZhbERhcGMoeCwgcG9wZGF0YSRwb3AsIG4ucGNhLm1heD0xMCwgdHJhaW5pbmcuc2V0PTAuOSwNCnJlc3VsdD0iZ3JvdXBNZWFuIiwgY2VudGVyPVRSVUUsIHNjYWxlPUZBTFNFLA0Kbi5yZXA9MTAwLCBuLnBjYT1OVUxMLCBwYXJhbGxlbD0ic25vdyIsIG5jcHVzPTQpDQoNCiMjIE51bWJlciBvZiBQQ3Mgd2l0aCBiZXN0IHN0YXRzDQp4dmFsJGBOdW1iZXIgb2YgUENzIEFjaGlldmluZyBIaWdoZXN0IE1lYW4gU3VjY2Vzc2ANCnh2YWwkYE51bWJlciBvZiBQQ3MgQWNoaWV2aW5nIExvd2VzdCBNU0VgDQp4dmFsJGBSb290IE1lYW4gU3F1YXJlZCBFcnJvciBieSBOdW1iZXIgb2YgUENzIG9mIFBDQWAgIyBsb3dlciBzY29yZSA9IGJldHRlcg0KIyBuID0gNiBpcyBvcHRpbWFsDQoNCnZjZl9kYXBjIDwtIGRhcGMocG9wZGF0YSwgbi5wY2EgPSA2LCBuLmRhID0gMykNCg0KDQojIyMgU2V0IHVwIHRoZSBwbG90cw0KDQpwYXIobWZyb3c9YygyLDIpKQ0KDQojIyMgREFQQzEgdnMgMiBzY2F0dGVyDQpzY2F0dGVyKHZjZl9kYXBjLCBjb2wgPSBteWNvbCwgeGF4ID0gMSwgeWF4ID0gMiwgY2V4ID0gMiwgc2NyZWUuZGE9RkFMU0UsIGxlZ2VuZCA9IEZBTFNFLCBncnAgPSBwb3AocG9wZGF0YSkpDQoNCiMjIyBEQVBDMSB2cyAzIHNjYXR0ZXINCnNjYXR0ZXIodmNmX2RhcGMsIGNvbCA9IG15Y29sLCB4YXggPSAxLCB5YXggPSAzLCBjZXggPSAyLCBzY3JlZS5kYT1GQUxTRSwgbGVnZW5kID0gRkFMU0UsIGdycCA9IHBvcChwb3BkYXRhKSkNCg0KIyMjIENoZWNrIHRoZSBhc3NpZ25tZW50IHBsb3QNCmFzc2lnbnBsb3QodmNmX2RhcGMpDQoNCiMjIyBwbG90IG1lbWJlcnNoaXAgcHJvYmFiaWxpdGllcw0KY29tcG9wbG90KHZjZl9kYXBjLCBsYWI9IiIsbmNvbD0xLGNvbD1teWNvbCkNCg0KDQojIyMgQ2hlY2sgdGhlIGFzc2lnbm1lbnQgcHJvYmFiaWxpdGllcw0KdmNmX2RhcGMkcG9zdGVyaW9yDQoNCmBgYA0KYGBge3J9DQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIyMgICAgRU5USVJFIENPREUgaW4gTWFya2Rvd24gICAgIyMjDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIC0tLQ0KIyB0aXRsZTogIjIwMjFfMDZfMDJfQ29yX3N0cmlhdGFfREFQQ19TU1JnZW5vdHlwZXIiDQojIG91dHB1dDogDQojICAgaHRtbF9ub3RlYm9vazogDQojICAgICB0aGVtZTogc3BhY2VsYWINCiMgI2VkaXRvcl9vcHRpb25zOiANCiMgIyAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUNCiMgZWRpdG9yX29wdGlvbnM6IA0KIyAgIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCiMgLS0tDQojIA0KIyBUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCiMgDQojIFRyeSBleGVjdXRpbmcgdGhpcyBjaHVuayBieSBjbGlja2luZyB0aGUgKlJ1biogYnV0dG9uIHdpdGhpbiB0aGUgY2h1bmsgb3IgYnkgcGxhY2luZyB5b3VyIGN1cnNvciBpbnNpZGUgaXQgYW5kIHByZXNzaW5nICpDdHJsK1NoaWZ0K0VudGVyKi4gDQojIA0KIyBgYGB7ciwgaW5jbHVkZT1UUlVFfQ0KIyAjIyMgbG9hZCBsaWJyYXJpZXMNCiMgbGlicmFyeShhZGVnZW5ldCkNCiMgDQojICMjIyByZWFkIGluIGRhdGEgLS0gR2VuZVBvcCBmb3JtYXQsIGNvbnZlcnRlZCB0byBnZW5pbmQgZm9ybWF0DQojIHBvcGRhdGEgPC0gcmVhZC5nZW5lcG9wKCJDb3Jfc3RyaWF0YV9zc3JnZW5vdHlwZXJfMDYucG9wLmdlbiIsIG5jb2RlID0gM0wpDQojIHBvcGRhdGENCiMgDQojICMgLy8vIEdFTklORCBPQkpFQ1QgLy8vLy8vLy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIw0KIyAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMNCiMgIyAgLy8gODMgaW5kaXZpZHVhbHM7IDE5IGxvY2k7IDc5IGFsbGVsZXM7IHNpemU6IDUzLjQgS2IgICAgICAgICAgICAgICAgICAjDQojICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIw0KIyAjICAvLyBCYXNpYyBjb250ZW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMNCiMgIyAgICBAdGFiOiAgODMgeCA3OSBtYXRyaXggb2YgYWxsZWxlIGNvdW50cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjDQojICMgICAgQGxvYy5uLmFsbDogbnVtYmVyIG9mIGFsbGVsZXMgcGVyIGxvY3VzIChyYW5nZTogMi01KSAgICAgICAgICAgICAgICAgIw0KIyAjICAgIEBsb2MuZmFjOiBsb2N1cyBmYWN0b3IgZm9yIHRoZSA3OSBjb2x1bW5zIG9mIEB0YWIgICAgICAgICAgICAgICAgICAgICMNCiMgIyAgICBAYWxsLm5hbWVzOiBsaXN0IG9mIGFsbGVsZSBuYW1lcyBmb3IgZWFjaCBsb2N1cyAgICAgICAgICAgICAgICAgICAgICAjDQojICMgICAgQHBsb2lkeTogcGxvaWR5IG9mIGVhY2ggaW5kaXZpZHVhbCAgKHJhbmdlOiAyLTIpICAgICAgICAgICAgICAgICAgICAgIw0KIyAjICAgIEB0eXBlOiAgY29kb20gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMNCiMgIyAgICBAY2FsbDogcmVhZC5nZW5lcG9wKGZpbGUgPSAiQ29yX3N0cmlhdGFfc3NyZ2Vub3R5cGVyXzA2LnBvcC5nZW4iLCAgICAjDQojICMgICAgIG5jb2RlID0gM0wpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIw0KIyAjCQkJCQkJCQkJCQkJCQkJCQkJICAjDQojICMgLy8gT3B0aW9uYWwgY29udGVudCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMNCiMgIyAgIEBwb3A6IHBvcHVsYXRpb24gb2YgZWFjaCBpbmRpdmlkdWFsIChncm91cCBzaXplIHJhbmdlOiAxNi0yNikgICAgICAgICAgIw0KIyANCiMgDQojICMjIyBKdXN0IGNoZWNraW5nLi4uDQojIGlzLmdlbmluZChwb3BkYXRhKQ0KIyANCiMgIyMjIGRlZmluZSAicG9wdWxhdGlvbnMiDQojIHBvcChwb3BkYXRhKSA8LSByZXAoYygidnJlZWxhbmRpaSIsInN0cmlhdGEiLCJTaWVycmFfTmV2YWRhIiwiQ29hc3RfQ2FzY2FkZXMiKSwgYygyMiwyNiwxNiwxOSkpDQojIHBvcChwb3BkYXRhKQ0KIyANCiMgIyMjIHNldCBjb2xvciBzY2hlbWUNCiMgbXljb2wgPC0gYygiZ3JlZW4iLCJyZWQiLCJibHVlIiwibWFnZW50YSIpDQojIA0KIyAjIyMgRmluZCBjbHVzdGVycw0KIyBncnAgPC0gZmluZC5jbHVzdGVycyhwb3BkYXRhLCBtYXgubi5jbHVzdCA9IDQwKQ0KIyANCiMgIyBDaG9vc2UgdGhlIG51bWJlciBQQ3MgdG8gcmV0YWluICg+PSAxKTogDQojIDYNCiMgIyBDaG9vc2UgdGhlIG51bWJlciBvZiBjbHVzdGVycyAoPj0yKTogDQojIDQNCiMgDQojIA0KIyAjIEFsc28sIHlvdSBjYW4gdXNlIEstbWVhbnMgY2x1c3RlcmluZyB0byBmaW5kIHRoZSBLIHdpdGggbWluaW11bSBCSUMNCiMgDQojIG1heEsgPC0gMTANCiMgbXlNYXQgPC0gbWF0cml4KG5yb3c9MTAsIG5jb2w9bWF4SykNCiMgY29sbmFtZXMobXlNYXQpIDwtIDE6bmNvbChteU1hdCkNCiMgZm9yKGkgaW4gMTpucm93KG15TWF0KSl7DQojICAgZ3JwIDwtIGZpbmQuY2x1c3RlcnMocG9wZGF0YSwgbi5wY2EgPSA0MCwgY2hvb3NlLm4uY2x1c3QgPSBGQUxTRSwgIG1heC5uLmNsdXN0ID0gbWF4SykNCiMgICBteU1hdFtpLF0gPC0gZ3JwJEtzdGF0DQojIH0NCiMgDQojIGxpYnJhcnkocmVzaGFwZTIpDQojIG15X2RmIDwtIG1lbHQobXlNYXQpDQojIGNvbG5hbWVzKG15X2RmKVsxOjNdIDwtIGMoIkdyb3VwIiwgIksiLCAiQklDIikNCiMgbXlfZGYkSyA8LSBhcy5mYWN0b3IobXlfZGYkSykNCiMgaGVhZChteV9kZikNCiMgDQojICMgVGhlIEsgdnMuIEJJQyBwbG90DQojIGxpYnJhcnkoZ2dwbG90MikNCiMgcDEgPC0gZ2dwbG90KG15X2RmLCBhZXMoeCA9IEssIHkgPSBCSUMpKQ0KIyBwMSA8LSBwMSArIGdlb21fYm94cGxvdCgpDQojIHAxIDwtIHAxICsgdGhlbWVfYncoKQ0KIyBwMSA8LSBwMSArIHhsYWIoIk51bWJlciBvZiBncm91cHMgKEspIikNCiMgcDENCiMgDQojIA0KIyAjIyMgY29uZHVjdCBEQVBDDQojIHZjZl9kYXBjIDwtIGRhcGMocG9wZGF0YSwgbi5wY2EgPSA0MCwgbi5kYSA9IDUpDQojIA0KIyAjIyMgSU1QT1JUQU5UOiBmaW5kIHRoZSBvcHRpbWFsICMgb2YgUENzIHRvIHJldGFpbiB1c2luZyB0aGUgJ2Etc2NvcmUnIGNyaXRlcmlvbg0KIyB0ZW1wIDwtIG9wdGltLmEuc2NvcmUodmNmX2RhcGMpDQojICMqIG4gPSA2IFBDcyA9IG9wdGltYWwhDQojIA0KIyAjIENyb3NzIHZhbGlkYXRpb24gbWV0aG9kIHRvIGZpbmQgIyBvZiBQQ3MNCiMgeHZhbCA9IHh2YWxEYXBjKHgsIHBvcGRhdGEkcG9wLCBuLnBjYS5tYXg9MTAsIHRyYWluaW5nLnNldD0wLjksDQojIHJlc3VsdD0iZ3JvdXBNZWFuIiwgY2VudGVyPVRSVUUsIHNjYWxlPUZBTFNFLA0KIyBuLnJlcD0zMCwgbi5wY2E9TlVMTCwgcGFyYWxsZWw9InNub3ciLCBuY3B1cz0yKQ0KIyAjIyBOdW1iZXIgb2YgUENzIHdpdGggYmVzdCBzdGF0cw0KIyB4dmFsJGBOdW1iZXIgb2YgUENzIEFjaGlldmluZyBIaWdoZXN0IE1lYW4gU3VjY2Vzc2ANCiMgeHZhbCRgTnVtYmVyIG9mIFBDcyBBY2hpZXZpbmcgTG93ZXN0IE1TRWANCiMgeHZhbCRgUm9vdCBNZWFuIFNxdWFyZWQgRXJyb3IgYnkgTnVtYmVyIG9mIFBDcyBvZiBQQ0FgICMgbG93ZXIgc2NvcmUgPSBiZXR0ZXINCiMgDQojIHZjZl9kYXBjIDwtIGRhcGMocG9wZGF0YSwgbi5wY2EgPSA3LCBuLmRhID0gNSkNCiMgDQojIA0KIyAjIyMgU2V0IHVwIHRoZSBwbG90cw0KIyANCiMgcGFyKG1mcm93PWMoMiwyKSkNCiMgDQojICMjIyBEQVBDMSB2cyAyIHNjYXR0ZXINCiMgc2NhdHRlcih2Y2ZfZGFwYywgY29sID0gbXljb2wsIHhheCA9IDEsIHlheCA9IDIsIGNleCA9IDIsIHNjcmVlLmRhPUZBTFNFLCBsZWdlbmQgPSBGQUxTRSwgZ3JwID0gcG9wKHBvcGRhdGEpKQ0KIyANCiMgIyMjIERBUEMxIHZzIDMgc2NhdHRlcg0KIyBzY2F0dGVyKHZjZl9kYXBjLCBjb2wgPSBteWNvbCwgeGF4ID0gMSwgeWF4ID0gMywgY2V4ID0gMiwgc2NyZWUuZGE9RkFMU0UsIGxlZ2VuZCA9IEZBTFNFLCBncnAgPSBwb3AocG9wZGF0YSkpDQojIA0KIyAjIyMgQ2hlY2sgdGhlIGFzc2lnbm1lbnQgcGxvdA0KIyBhc3NpZ25wbG90KHZjZl9kYXBjKQ0KIyANCiMgIyMjIHBsb3QgbWVtYmVyc2hpcCBwcm9iYWJpbGl0aWVzDQojIGNvbXBvcGxvdCh2Y2ZfZGFwYywgbGFiPSIiLG5jb2w9MSxjb2w9bXljb2wpDQojIA0KIyANCiMgIyMjIENoZWNrIHRoZSBhc3NpZ25tZW50IHByb2JhYmlsaXRpZXMNCiMgdmNmX2RhcGMkcG9zdGVyaW9yDQojIA0KIyBgYGANCmBgYA0KDQpBZGQgYSBuZXcgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpJbnNlcnQgQ2h1bmsqIGJ1dHRvbiBvbiB0aGUgdG9vbGJhciBvciBieSBwcmVzc2luZyAqQ3RybCtBbHQrSSouDQoNCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ3RybCtTaGlmdCtLKiB0byBwcmV2aWV3IHRoZSBIVE1MIGZpbGUpLg0KDQpUaGUgcHJldmlldyBzaG93cyB5b3UgYSByZW5kZXJlZCBIVE1MIGNvcHkgb2YgdGhlIGNvbnRlbnRzIG9mIHRoZSBlZGl0b3IuIENvbnNlcXVlbnRseSwgdW5saWtlICpLbml0KiwgKlByZXZpZXcqIGRvZXMgbm90IHJ1biBhbnkgUiBjb2RlIGNodW5rcy4gSW5zdGVhZCwgdGhlIG91dHB1dCBvZiB0aGUgY2h1bmsgd2hlbiBpdCB3YXMgbGFzdCBydW4gaW4gdGhlIGVkaXRvciBpcyBkaXNwbGF5ZWQuDQo=