1 Read, Clean, Recode, Merge

2 Define functions for scoring

3 Define fuction for correlation table

# x is a matrix containing the data
# method : correlation method. "pearson"" or "spearman"" is supported
# removeTriangle : remove upper or lower triangle
# results :  if "html" or "latex"
  # the results will be displayed in html or latex format
corstars <-function(x, method=c("pearson", "spearman"), removeTriangle=c("upper", "lower"),
                     result=c("none", "html", "latex")){
  #Compute correlation matrix
  suppressMessages({
    require(Hmisc)
    require(knitr)
  })
  
    x <- as.matrix(x)
    correlation_matrix<-rcorr(x, type=method[1])
    R <- correlation_matrix$r # Matrix of correlation coeficients
    p <- correlation_matrix$P # Matrix of p-value 
    
    ## Define notions for significance levels; spacing is important.
    mystars <- ifelse(p < .0001, "****", ifelse(p < .001, "*** ", ifelse(p < .01, "**  ", ifelse(p < .05, "*   ", "    "))))
    
    ## trunctuate the correlation matrix to two decimal
    R <- format(round(cbind(rep(-1.11, ncol(x)), R), 2))[,-1]
    
    ## build a new matrix that includes the correlations with their apropriate stars
    Rnew <- matrix(paste(R, mystars, sep=""), ncol=ncol(x))
    diag(Rnew) <- paste(diag(R), " ", sep="")
    rownames(Rnew) <- colnames(x)
    colnames(Rnew) <- paste(colnames(x), "", sep="")
    
    ## remove upper triangle of correlation matrix
    if(removeTriangle[1]=="upper"){
      Rnew <- as.matrix(Rnew)
      Rnew[upper.tri(Rnew, diag = TRUE)] <- ""
      Rnew <- as.data.frame(Rnew)
    }
    
    ## remove lower triangle of correlation matrix
    else if(removeTriangle[1]=="lower"){
      Rnew <- as.matrix(Rnew)
      Rnew[lower.tri(Rnew, diag = TRUE)] <- ""
      Rnew <- as.data.frame(Rnew)
    }
    
    ## remove last column and return the correlation matrix
    Rnew <- cbind(Rnew[1:length(Rnew)-1])
    if (result[1]=="none") return(Rnew)
    else{
      if(result[1]=="html") print(knitr::kable(Rnew, format = "html")) 
      else print(knitr::kable(Rnew, format = "latex")) 
    }
} 

4 Scoring

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Recode and Score
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## 


Data$Totala_check <- ScoreLikert(Data[, sprintf("a%d", 1:25)], tonumeric = TRUE)
Data$Totalb_check <- ScoreLikert(Data[, sprintf("b%d", 1:33)], tonumeric = TRUE)
Data$Totalc_check <- ScoreLikert(Data[, sprintf("c%d", 1:25)], tonumeric = TRUE)

all.equal(Data$Totala_check, Data$Totala)
all.equal(Data$Totalb_check, Data$Totalb)
all.equal(Data$Totalc_check, Data$Totalc)
Data$aRCompPers <- ScoreLikert(Data[, c("a1", "a2", "a3", "a4", "a5", "a6", "a9", "a10", "a13", "a14", "a15", "a17", "a18", "a19", "a20", "a23", "a24")], 
                                    tonumeric = TRUE)
Data$aRAccept <- ScoreLikert(Data[, c("a7", "a8", "a11", "a12", "a16", "a21", "a22", "a25")], tonumeric = TRUE)

Data$bPS <- ScoreLikert(Data[, c("b1", "b2", "b3", "b4", "b5", "b6")], tonumeric = TRUE)
Data$bPV <- ScoreLikert(Data[, c("b7", "b8", "b9", "b10")], tonumeric = TRUE)
Data$bCS <- ScoreLikert(Data[, c("b12", "b13", "b14", "b15", "b16")], tonumeric = TRUE)        # exclude b11 because no variance
Data$pSS <- ScoreLikert(Data[, c("b17", "b18", "b19", "b20", "b21", "b22")], tonumeric = TRUE)
Data$bCF <- ScoreLikert(Data[, c("b23", "b24", "b25", "b26", "b27", "b28", "b29")], tonumeric = TRUE)
Data$bRS <- ScoreLikert(Data[, c("b30", "b31", "b32", "b33")], tonumeric = TRUE)

Data$cCP <- ScoreLikert(Data[, c("c24", "c12", "c11", "c25", "c10", "c23", "c17", "c16")], tonumeric = TRUE)
Data$cII <- ScoreLikert(Data[, c("c20", "c18", "c15", "c6", "c7", "c19", "c14")], tonumeric = TRUE)
Data$cAP <- ScoreLikert(Data[, c("c1", "c4", "c5", "c2", "c8")], tonumeric = TRUE)
Data$cC <- ScoreLikert(Data[, c("c22", "c13", "c21")], tonumeric = TRUE)
Data$cIS <- ScoreLikert(Data[, c("c3", "c9")], tonumeric = TRUE)

5 Descriptives

Descriptives
variable n min max median q1 q3 iqr mad mean sd se ci
Totala 108 97.00 167.00 138.00 129.00 148.00 19.00 13.34 138.19 13.54 1.30 2.58
Totalb 108 94.11 214.11 169.61 156.11 183.36 27.25 20.02 169.08 23.10 2.22 4.41
Totalc 108 66.00 121.00 100.00 92.00 105.00 13.00 10.38 98.10 10.87 1.05 2.07

6 Correlations

package 㤼㸱knitr㤼㸲 was built under R version 3.6.3
Inter-scale correlations
Totala Totalb
Totala
Totalb 0.64****
Totalc 0.78**** 0.58****
Inter-scale correlations
Totala_check Totalb_check Totalc_check aRCompPers aRAccept bPS bPV bCS pSS bCF bRS cCP cII cAP cC
Totala_check
Totalb_check 0.64****
Totalc_check 0.78**** 0.58****
aRCompPers 0.91**** 0.59**** 0.74****
aRAccept 0.81**** 0.49**** 0.58**** 0.49****
bPS 0.57**** 0.82**** 0.52**** 0.57**** 0.39****
bPV 0.38**** 0.56**** 0.31** 0.41**** 0.21* 0.52****
bCS 0.55**** 0.89**** 0.49**** 0.49**** 0.45**** 0.63**** 0.39****
pSS 0.58**** 0.88**** 0.55**** 0.55**** 0.43**** 0.73**** 0.48**** 0.74****
bCF 0.57**** 0.87**** 0.51**** 0.51**** 0.47**** 0.60**** 0.36*** 0.78**** 0.65****
bRS 0.42**** 0.81**** 0.37**** 0.35*** 0.38**** 0.55**** 0.37**** 0.66**** 0.62**** 0.69****
cCP 0.72**** 0.48**** 0.86**** 0.73**** 0.47**** 0.46**** 0.25* 0.39**** 0.49**** 0.39**** 0.33***
cII 0.60**** 0.36*** 0.81**** 0.55**** 0.48**** 0.30** 0.27** 0.29** 0.34*** 0.36*** 0.21* 0.54****
cAP 0.63**** 0.49**** 0.84**** 0.59**** 0.47**** 0.48**** 0.26** 0.42**** 0.44**** 0.42**** 0.34*** 0.68**** 0.59****
cC 0.59**** 0.54**** 0.71**** 0.54**** 0.46**** 0.52**** 0.19 0.47**** 0.55**** 0.47**** 0.32*** 0.58**** 0.41**** 0.60****
cIS 0.25** 0.34*** 0.37**** 0.20* 0.25** 0.17 0.14 0.38**** 0.28** 0.35*** 0.25** 0.13 0.22* 0.19* 0.21*
Max a
id Totala_check Totalb_check Totalc_check aRCompPers aRAccept bPS bPV bCS pSS bCF bRS cCP cII cAP cC cIS
101 167 214 121 117 50 36 22 35 42 49 28 40 35 25 15 6
30 165 201 119 115 50 37 20 31 40 43 28 40 32 22 15 10
64 164 180 103 114 50 34 19 28 31 46 20 35 27 19 15 7
29 157 185 109 112 45 35 21 29 33 41 24 36 31 25 12 5
40 157 195 114 111 46 36 22 29 35 44 27 38 30 22 15 9
80 157 190 113 111 46 33 20 28 37 43 27 38 32 23 14 6
Min a
id Totala_check Totalb_check Totalc_check aRCompPers aRAccept bPS bPV bCS pSS bCF bRS cCP cII cAP cC cIS
6 97 105 68 77 20 17 17 14 20 24 11 24 20 13 7 4
12 100 164 66 77 23 36 18 21 34 35 18 20 16 13 11 6
5 104 148 78 81 23 26 21 22 24 31 22 28 15 18 11 6
79 107 119 78 85 22 26 14 17 17 29 14 22 20 19 14 3
24 114 154 79 79 35 27 13 25 26 37 24 24 22 15 9 9
26 114 125 78 81 33 21 17 20 15 32 18 27 19 15 9 8
Max b
id Totala_check Totalb_check Totalc_check aRCompPers aRAccept bPS bPV bCS pSS bCF bRS cCP cII cAP cC cIS
101 167 214 121 117 50 36 22 35 42 49 28 40 35 25 15 6
35 129 211 105 99 30 40 22 33 40 46 28 34 25 22 14 10
104 148 211 108 105 43 37 22 32 42 48 28 36 29 23 14 6
43 149 207 115 109 40 39 19 32 40 47 28 36 33 24 14 8
51 151 207 111 111 40 36 22 33 40 49 25 36 30 22 14 9
Min b
id Totala_check Totalb_check Totalc_check aRCompPers aRAccept bPS bPV bCS pSS bCF bRS cCP cII cAP cC cIS
63 128 94 102 96 32 27 19 5 16 19 6 32 31 21 12 6
6 97 105 68 77 20 17 17 14 20 24 11 24 20 13 7 4
81 127 117 92 85 42 26 17 13 15 27 17 29 25 20 12 6
79 107 119 78 85 22 26 14 17 17 29 14 22 20 19 14 3
26 114 125 78 81 33 21 17 20 15 32 18 27 19 15 9 8
Max c
id Totala_check Totalb_check Totalc_check aRCompPers aRAccept bPS bPV bCS pSS bCF bRS cCP cII cAP cC cIS
101 167 214 121 117 50 36 22 35 42 49 28 40 35 25 15 6
30 165 201 119 115 50 37 20 31 40 43 28 40 32 22 15 10
96 155 205 118 111 44 41 20 31 37 48 26 38 31 25 15 9
43 149 207 115 109 40 39 19 32 40 47 28 36 33 24 14 8
53 147 186 115 111 36 33 19 30 36 40 26 37 30 24 14 10
Min c
id Totala_check Totalb_check Totalc_check aRCompPers aRAccept bPS bPV bCS pSS bCF bRS cCP cII cAP cC cIS
12 100 164 66 77 23 36 18 21 34 35 18 20 16 13 11 6
6 97 105 68 77 20 17 17 14 20 24 11 24 20 13 7 4
65 133 141 76 99 34 29 16 21 23 30 20 31 17 16 10 2
5 104 148 78 81 23 26 21 22 24 31 22 28 15 18 11 6
26 114 125 78 81 33 21 17 20 15 32 18 27 19 15 9 8
79 107 119 78 85 22 26 14 17 17 29 14 22 20 19 14 3
90 120 132 78 85 35 25 18 19 24 27 17 29 18 17 8 6

–>

6.1 Top and bottom values

Data_p <- 
  Data[, c(1, 103:118)] %>%
  dplyr::rename(id = Numar) %>%
  select(id, dplyr::everything())

##
max_a <-
  Data_p %>%
    dplyr::slice_max(Totala_check, n = 5)
max_a %>%   
  kableExtra::kbl(caption = "Max a", digits = 0) %>%
  kableExtra::kable_classic(full_width = F, html_font = "Times New Roman")
max_a <- max_a %>% dplyr::pull(id)

min_a <-
Data_p %>%
  dplyr::slice_min(Totala_check, n = 5)
min_a %>% 
  kableExtra::kbl(caption = "Min a", digits = 0) %>%
  kableExtra::kable_classic(full_width = F, html_font = "Times New Roman")
min_a <- min_a %>% dplyr::pull(id)
##

##
max_b <-
Data_p %>%
  dplyr::slice_max(Totalb_check, n = 5)
max_b %>%
  kableExtra::kbl(caption = "Max b", digits = 0) %>%
  kableExtra::kable_classic(full_width = F, html_font = "Times New Roman")
max_b <- max_b %>% dplyr::pull(id)

min_b <-
Data_p %>%
  dplyr::slice_min(Totalb_check, n = 5)
min_b %>% 
  kableExtra::kbl(caption = "Min b", digits = 0) %>%
  kableExtra::kable_classic(full_width = F, html_font = "Times New Roman")
min_b <- min_b %>% dplyr::pull(id)
##

##
max_c <-
Data_p %>%
  dplyr::slice_max(Totalc_check, n = 5)
max_c %>% 
  kableExtra::kbl(caption = "Max c", digits = 0) %>%
  kableExtra::kable_classic(full_width = F, html_font = "Times New Roman")
max_c <- max_c %>% dplyr::pull(id)

min_c <-
Data_p %>%
  dplyr::slice_min(Totalc_check, n = 5)
min_c %>% 
  kableExtra::kbl(caption = "Min c", digits = 0) %>%
  kableExtra::kable_classic(full_width = F, html_font = "Times New Roman")
min_c <- min_c %>% dplyr::pull(id)
##

mins <- unique(c(min_a, min_b, min_c))
maxs <- unique(c(max_a, max_b, max_c))

Data_p$min_max <- dplyr::case_when(Data_p$id %in% maxs ~ "red",
                                   Data_p$id %in% mins ~ "green",
                                   TRUE ~ "darkgrey")
                                    
Data_p_long <-
  Data_p %>%
  dplyr::select(id, min_max, Totala_check, Totalb_check, Totalc_check) %>%
  tidyr::pivot_longer(cols = c(Totala_check, Totalb_check, Totalc_check), names_to = "variable", values_to = "value")

Data_p_long %>%
  ggplot(aes(x = variable, y = value)) +
    geom_violin() +
    geom_point(size = 1, alpha = 0.6, colour = Data_p_long$min_max) +
    geom_line(aes(group = id), linetype = "11", colour = Data_p_long$min_max) +
    scale_colour_identity() + 
    theme_classic()

7 CFA

8 Session Info

 

A work by Claudiu Papasteri

 

LS0tDQp0aXRsZTogIjxicj4gUmVzaWxpZW5jZSAtIDMgc2NhbGVzIiANCnN1YnRpdGxlOiAiSW5pdGlhbCBBbmFseXNpcyINCmF1dGhvcjogIjxicj4gQ2xhdWRpdSBQYXBhc3RlcmkiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlbSAlWScpYCINCm91dHB1dDogDQogICAgaHRtbF9ub3RlYm9vazoNCiAgICAgICAgICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgICAgICAgICAgdG9jOiB0cnVlDQogICAgICAgICAgICB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgICAgICAgICAgdGhlbWU6IHNwYWNlbGFiDQogICAgICAgICAgICBoaWdobGlnaHQ6IHRhbmdvDQogICAgICAgICAgICBmb250LWZhbWlseTogQXJpYWwNCiAgICAgICAgICAgIGZpZ193aWR0aDogMTANCiAgICAgICAgICAgIGZpZ19oZWlnaHQ6IDkNCiAgICAjIHBkZl9kb2N1bWVudDogDQogICAgICAgICAgICAjIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgIyAgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICAjICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICAgICAgICAgICMgZm9udHNpemU6IDExcHQNCiAgICAgICAgICAgICMgZ2VvbWV0cnk6IG1hcmdpbj0xaW4NCiAgICAgICAgICAgICMgZmlnX3dpZHRoOiA3DQogICAgICAgICAgICAjIGZpZ19oZWlnaHQ6IDYNCiAgICAgICAgICAgICMgZmlnX2NhcHRpb246IHRydWUNCiAgICAjIGdpdGh1Yl9kb2N1bWVudDogDQogICAgICAgICAgICAjIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgIyB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgICMgaHRtbF9wcmV2aWV3OiBmYWxzZQ0KICAgICAgICAgICAgIyBmaWdfd2lkdGg6IDUNCiAgICAgICAgICAgICMgZmlnX2hlaWdodDogNQ0KICAgICAgICAgICAgIyBkZXY6IGpwZWcNCi0tLQ0KDQoNCjwhLS0gU2V0dXAgLS0+DQoNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIGtpbnRyIG9wdGlvbnMNCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCiAgY29tbWVudCA9ICIjIiwNCiAgY29sbGFwc2UgPSBUUlVFLA0KICBlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gVFJVRSwgY2FjaGUgPSBUUlVFICAgICAgICMgZWNobyA9IEZhbHNlIGZvciBnaXRodWJfZG9jdW1lbnQsIGJ1dCB3aWxsIGJlIGZvbGRlZCBpbiBodG1sX25vdGVib29rDQopDQoNCiMgR2VuZXJhbCBSIG9wdGlvbnMgYW5kIGluZm8NCnNldC5zZWVkKDExMSkgICAgICAgICAgICAgICAjIGluIGNhc2Ugd2UgdXNlIHJhbmRvbWl6ZWQgcHJvY2VkdXJlcyAgICAgICANCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAgICAgICAjIHBvc2l0aXZlIHZhbHVlcyBiaWFzIHRvd2FyZHMgZml4ZWQgYW5kIG5lZ2F0aXZlIHRvd2FyZHMgc2NpZW50aWZpYyBub3RhdGlvbg0KDQojIExvYWQgcGFja2FnZXMNCmlmICghcmVxdWlyZSgicGFjbWFuIikpIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQpwYWNrYWdlcyA8LSBjKA0KICAicGFwYWphIiwNCiAgInRpZHl2ZXJzZSIsICJwbHlyIiwgICAgICANCiAgInBzeWNoIiwgIlBlcmZvcm1hbmNlQW5hbHl0aWNzIiwgICAgICAgICAgDQogICJicm9vbSIsICJyc3RhdGl4IiwNCiAgInN1bW1hcnl0b29scyIsICJ0YWRhYXRvb2xib3giLCAgICAgICAgICAgDQogICJnZ3Bsb3QyIiwgImdncHViciIsICJzY2FsZXMiLCAgICAgICAgDQogICJyaW8iLA0KICAicHN5Y2hvIg0KICAjICwgLi4uDQopDQppZiAoIXJlcXVpcmUoInBhY21hbiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KcGFjbWFuOjpwX2xvYWQoY2hhciA9IHBhY2thZ2VzKQ0KDQojIFRoZW1lcyBmb3IgZ2dwbG90MiBwbG90aW5nIChoZXJlIHVzZWQgQVBBIHN0eWxlKQ0KdGhlbWVfc2V0KHRoZW1lX2FwYSgpKQ0KYGBgDQoNCg0KDQoNCg0KPCEtLSBSZXBvcnQgLS0+DQoNCg0KIyBSZWFkLCBDbGVhbiwgUmVjb2RlLCBNZXJnZQ0KDQpgYGB7ciByZWRfY2xlYW5fcmVjb2RlX21lcmdlLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdoaWRlJyx9DQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KIyBSZWFkLCBDbGVhbiwgUmVjb2RlLCBVbml0ZQ0KI35+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4NCg0KIyMgUmVhZCBmaWxlcw0KDQojIFJlYWQgY3VycmVudCBEYXRhDQpmb2xkZXIgPC0gIkM6L1VzZXJzL01paGFpL0Rlc2t0b3AvUiBOb3RlYm9va3Mvbm90ZWJvb2tzL1JlemlsaWVudGEtM3NjYWxlIg0KZmlsZSA8LSAiQkFaQSBERSBEQVRFIEZJTkFMQSBWQVJJQU5UQSBFWENFTCAoMSkueGxzeCINCnNldHdkKGZvbGRlcikNCg0Kc3VwcHJlc3NNZXNzYWdlcyh7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNvbWUgY29sdW1ucyBhcmUgcmVuYW1lZCBhbmQgdGhlIHdhcm5pbmcgYnJlYWtzIHBhbmRvYw0KRGF0YSA8LSByaW86OmltcG9ydChmaWxlLnBhdGgoZm9sZGVyLCBmaWxlKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoID0gIlNoZWV0MSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBza2lwID0gMCkNCn0pDQoNCmBgYA0KDQoNCiMgRGVmaW5lIGZ1bmN0aW9ucyBmb3Igc2NvcmluZw0KDQpgYGB7ciBkZWZfZnVuY19zY29yaW5nfQ0KIyMgRGVmaW5lIGZ1bmN0aW9uIHRoYXQgcmVjb2RlcyB0byBudW1lcmljLCBidXQgd2F0Y2hlcyBvdXQgdG8gY29lcmNpb24gdG8gbm90IGludHJvZHVjZSBOQXMNCmNvbHN0b251bWVyaWMgPC0gZnVuY3Rpb24oZGYpew0KICB0cnlDYXRjaCh7DQogICAgZGZfbnVtIDwtIGFzLmRhdGEuZnJhbWUoDQogICAgICBsYXBwbHkoZGYsDQogICAgICAgICAgICAgZnVuY3Rpb24oeCkgeyBhcy5udW1lcmljKGFzLmNoYXJhY3Rlcih4KSl9KSkgDQogIH0sd2FybmluZyA9IGZ1bmN0aW9uKHN0b3Bfb25fd2FybmluZykgew0KICAgIG1lc3NhZ2UoIlN0b3BlZCB0aGUgZXhlY3V0aW9uIG9mIG51bWVyaWMgY29udmVyc2lvbjogIiwgY29uZGl0aW9uTWVzc2FnZShzdG9wX29uX3dhcm5pbmcpKQ0KICB9KSANCn0NCg0KIyMgRGVmaW5lIGZ1bmN0aW9uIHRoYXQgc2NvcmVzIG9ubHkgcm93cyB3aXRoIGxlc3MgdGhhbiAxMCUgTkFzIChyZXR1cm5zIE5BIGlmIGFsbCBvciBhYm92ZSB0aHJlc2hvbGQgcGVyY2VudGFnZSBvZiByb3dzIGFyZSBOQSk7IGNhbiByZXZlcnNlIGNvZGUgaWYgdmVjdG9yIG9mIGNvbHVtbiBpbmRleGVzIGFuZCBtaW4sIG1heCBhcmUgcHJvdmlkZWQuDQpTY29yZUxpa2VydCA8LSBmdW5jdGlvbihkZiwgbmFwZXJjZW50ID0gLjEsIHRvbnVtZXJpYyA9IEZBTFNFLCByZXZlcnNlY29scyA9IE5VTEwsIG1pbiA9IE5VTEwsIG1heCA9IE5VTEwpIHsNCiAgcmV2ZXJzZV9saXN0IDwtIGxpc3QocmV2ZXJzZWNvbHMgPSByZXZlcnNlY29scywgbWluID0gbWluLCBtYXggPSBtYXgpDQogIHJldmVyc2VfY2hlY2sgPC0gIXNhcHBseShyZXZlcnNlX2xpc3QsIGlzLm51bGwpDQogIA0KICAjIFJlY29kZSB0byBudW1lcmljLCBidXQgd2F0Y2ggb3V0IHRvIGNvZXJjaW9uIHRvIG5vdCBpbnRyb2R1Y2UgTkFzDQogIGNvbHN0b251bWVyaWMgPC0gZnVuY3Rpb24oZGYpew0KICAgIHRyeUNhdGNoKHsNCiAgICAgIGRmX251bSA8LSBhcy5kYXRhLmZyYW1lKA0KICAgICAgICAgICAgICAgICAgICBsYXBwbHkoZGYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7IGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHgpKX0pKSANCiAgICAgIH0sd2FybmluZyA9IGZ1bmN0aW9uKHN0b3Bfb25fd2FybmluZykgew0KICAgICAgICBtZXNzYWdlKCJTdG9wZWQgdGhlIGV4ZWN1dGlvbiBvZiBudW1lcmljIGNvbnZlcnNpb246ICIsIGNvbmRpdGlvbk1lc3NhZ2Uoc3RvcF9vbl93YXJuaW5nKSkNCiAgICB9KSANCiAgfQ0KICANCiAgaWYodG9udW1lcmljKSBkZiA8LSBjb2xzdG9udW1lcmljKGRmKQ0KICANCiAgaWYoYWxsKHJldmVyc2VfY2hlY2spKXsNCiAgICBkZlsgLHJldmVyc2Vjb2xzXSA8LSAobWF4ICsgbWluKSAtIGRmWyAscmV2ZXJzZWNvbHNdDQogIH1lbHNlIGlmKGFueShyZXZlcnNlX2NoZWNrKSl7DQogICAgc3RvcCgiSW5zdWZpY2llbnQgaW5mbyBmb3IgcmV2ZXJzaW5nLiBQbGVhc2UgcHJvdmlkZTogIiwgcGFzdGUobmFtZXMocmV2ZXJzZV9saXN0KVshcmV2ZXJzZV9jaGVja10sIGNvbGxhcHNlID0gIiwgIikpDQogIH0NCiAgDQogIGlmZWxzZShyb3dTdW1zKGlzLm5hKGRmKSkgPiBuY29sKGRmKSAqIG5hcGVyY2VudCwNCiAgICAgICAgIE5BLA0KICAgICAgICAgcm93U3VtcyhkZiwgbmEucm0gPSBUUlVFKSAqIE5BIF4gKHJvd1N1bXMoIWlzLm5hKGRmKSkgPT0gMCkNCiAgKQ0KfQ0KYGBgDQoNCiMgRGVmaW5lIGZ1Y3Rpb24gZm9yIGNvcnJlbGF0aW9uIHRhYmxlDQoNCmBgYHtyfQ0KIyB4IGlzIGEgbWF0cml4IGNvbnRhaW5pbmcgdGhlIGRhdGENCiMgbWV0aG9kIDogY29ycmVsYXRpb24gbWV0aG9kLiAicGVhcnNvbiIiIG9yICJzcGVhcm1hbiIiIGlzIHN1cHBvcnRlZA0KIyByZW1vdmVUcmlhbmdsZSA6IHJlbW92ZSB1cHBlciBvciBsb3dlciB0cmlhbmdsZQ0KIyByZXN1bHRzIDogIGlmICJodG1sIiBvciAibGF0ZXgiDQogICMgdGhlIHJlc3VsdHMgd2lsbCBiZSBkaXNwbGF5ZWQgaW4gaHRtbCBvciBsYXRleCBmb3JtYXQNCmNvcnN0YXJzIDwtZnVuY3Rpb24oeCwgbWV0aG9kPWMoInBlYXJzb24iLCAic3BlYXJtYW4iKSwgcmVtb3ZlVHJpYW5nbGU9YygidXBwZXIiLCAibG93ZXIiKSwNCiAgICAgICAgICAgICAgICAgICAgIHJlc3VsdD1jKCJub25lIiwgImh0bWwiLCAibGF0ZXgiKSl7DQogICNDb21wdXRlIGNvcnJlbGF0aW9uIG1hdHJpeA0KICBzdXBwcmVzc01lc3NhZ2VzKHsNCiAgICByZXF1aXJlKEhtaXNjKQ0KICAgIHJlcXVpcmUoa25pdHIpDQogIH0pDQogIA0KICAgIHggPC0gYXMubWF0cml4KHgpDQogICAgY29ycmVsYXRpb25fbWF0cml4PC1yY29ycih4LCB0eXBlPW1ldGhvZFsxXSkNCiAgICBSIDwtIGNvcnJlbGF0aW9uX21hdHJpeCRyICMgTWF0cml4IG9mIGNvcnJlbGF0aW9uIGNvZWZpY2llbnRzDQogICAgcCA8LSBjb3JyZWxhdGlvbl9tYXRyaXgkUCAjIE1hdHJpeCBvZiBwLXZhbHVlIA0KICAgIA0KICAgICMjIERlZmluZSBub3Rpb25zIGZvciBzaWduaWZpY2FuY2UgbGV2ZWxzOyBzcGFjaW5nIGlzIGltcG9ydGFudC4NCiAgICBteXN0YXJzIDwtIGlmZWxzZShwIDwgLjAwMDEsICIqKioqIiwgaWZlbHNlKHAgPCAuMDAxLCAiKioqICIsIGlmZWxzZShwIDwgLjAxLCAiKiogICIsIGlmZWxzZShwIDwgLjA1LCAiKiAgICIsICIgICAgIikpKSkNCiAgICANCiAgICAjIyB0cnVuY3R1YXRlIHRoZSBjb3JyZWxhdGlvbiBtYXRyaXggdG8gdHdvIGRlY2ltYWwNCiAgICBSIDwtIGZvcm1hdChyb3VuZChjYmluZChyZXAoLTEuMTEsIG5jb2woeCkpLCBSKSwgMikpWywtMV0NCiAgICANCiAgICAjIyBidWlsZCBhIG5ldyBtYXRyaXggdGhhdCBpbmNsdWRlcyB0aGUgY29ycmVsYXRpb25zIHdpdGggdGhlaXIgYXByb3ByaWF0ZSBzdGFycw0KICAgIFJuZXcgPC0gbWF0cml4KHBhc3RlKFIsIG15c3RhcnMsIHNlcD0iIiksIG5jb2w9bmNvbCh4KSkNCiAgICBkaWFnKFJuZXcpIDwtIHBhc3RlKGRpYWcoUiksICIgIiwgc2VwPSIiKQ0KICAgIHJvd25hbWVzKFJuZXcpIDwtIGNvbG5hbWVzKHgpDQogICAgY29sbmFtZXMoUm5ldykgPC0gcGFzdGUoY29sbmFtZXMoeCksICIiLCBzZXA9IiIpDQogICAgDQogICAgIyMgcmVtb3ZlIHVwcGVyIHRyaWFuZ2xlIG9mIGNvcnJlbGF0aW9uIG1hdHJpeA0KICAgIGlmKHJlbW92ZVRyaWFuZ2xlWzFdPT0idXBwZXIiKXsNCiAgICAgIFJuZXcgPC0gYXMubWF0cml4KFJuZXcpDQogICAgICBSbmV3W3VwcGVyLnRyaShSbmV3LCBkaWFnID0gVFJVRSldIDwtICIiDQogICAgICBSbmV3IDwtIGFzLmRhdGEuZnJhbWUoUm5ldykNCiAgICB9DQogICAgDQogICAgIyMgcmVtb3ZlIGxvd2VyIHRyaWFuZ2xlIG9mIGNvcnJlbGF0aW9uIG1hdHJpeA0KICAgIGVsc2UgaWYocmVtb3ZlVHJpYW5nbGVbMV09PSJsb3dlciIpew0KICAgICAgUm5ldyA8LSBhcy5tYXRyaXgoUm5ldykNCiAgICAgIFJuZXdbbG93ZXIudHJpKFJuZXcsIGRpYWcgPSBUUlVFKV0gPC0gIiINCiAgICAgIFJuZXcgPC0gYXMuZGF0YS5mcmFtZShSbmV3KQ0KICAgIH0NCiAgICANCiAgICAjIyByZW1vdmUgbGFzdCBjb2x1bW4gYW5kIHJldHVybiB0aGUgY29ycmVsYXRpb24gbWF0cml4DQogICAgUm5ldyA8LSBjYmluZChSbmV3WzE6bGVuZ3RoKFJuZXcpLTFdKQ0KICAgIGlmIChyZXN1bHRbMV09PSJub25lIikgcmV0dXJuKFJuZXcpDQogICAgZWxzZXsNCiAgICAgIGlmKHJlc3VsdFsxXT09Imh0bWwiKSBwcmludChrbml0cjo6a2FibGUoUm5ldywgZm9ybWF0ID0gImh0bWwiKSkgDQogICAgICBlbHNlIHByaW50KGtuaXRyOjprYWJsZShSbmV3LCBmb3JtYXQgPSAibGF0ZXgiKSkgDQogICAgfQ0KfSANCg0KYGBgDQoNCg0KDQojIFNjb3JpbmcgDQoNCmBgYHtyIHNjb3JlX3NjYWxlcywgcmVzdWx0cz0naGlkZSd9DQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KIyBSZWNvZGUgYW5kIFNjb3JlDQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KIyMgDQoNCg0KRGF0YSRUb3RhbGFfY2hlY2sgPC0gU2NvcmVMaWtlcnQoRGF0YVssIHNwcmludGYoImElZCIsIDE6MjUpXSwgdG9udW1lcmljID0gVFJVRSkNCkRhdGEkVG90YWxiX2NoZWNrIDwtIFNjb3JlTGlrZXJ0KERhdGFbLCBzcHJpbnRmKCJiJWQiLCAxOjMzKV0sIHRvbnVtZXJpYyA9IFRSVUUpDQpEYXRhJFRvdGFsY19jaGVjayA8LSBTY29yZUxpa2VydChEYXRhWywgc3ByaW50ZigiYyVkIiwgMToyNSldLCB0b251bWVyaWMgPSBUUlVFKQ0KDQphbGwuZXF1YWwoRGF0YSRUb3RhbGFfY2hlY2ssIERhdGEkVG90YWxhKQ0KYWxsLmVxdWFsKERhdGEkVG90YWxiX2NoZWNrLCBEYXRhJFRvdGFsYikNCmFsbC5lcXVhbChEYXRhJFRvdGFsY19jaGVjaywgRGF0YSRUb3RhbGMpDQoNCkRhdGEkYVJDb21wUGVycyA8LSBTY29yZUxpa2VydChEYXRhWywgYygiYTEiLCAiYTIiLCAiYTMiLCAiYTQiLCAiYTUiLCAiYTYiLCAiYTkiLCAiYTEwIiwgImExMyIsICJhMTQiLCAiYTE1IiwgImExNyIsICJhMTgiLCAiYTE5IiwgImEyMCIsICJhMjMiLCAiYTI0IildLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvbnVtZXJpYyA9IFRSVUUpDQpEYXRhJGFSQWNjZXB0IDwtIFNjb3JlTGlrZXJ0KERhdGFbLCBjKCJhNyIsICJhOCIsICJhMTEiLCAiYTEyIiwgImExNiIsICJhMjEiLCAiYTIyIiwgImEyNSIpXSwgdG9udW1lcmljID0gVFJVRSkNCg0KRGF0YSRiUFMgPC0gU2NvcmVMaWtlcnQoRGF0YVssIGMoImIxIiwgImIyIiwgImIzIiwgImI0IiwgImI1IiwgImI2IildLCB0b251bWVyaWMgPSBUUlVFKQ0KRGF0YSRiUFYgPC0gU2NvcmVMaWtlcnQoRGF0YVssIGMoImI3IiwgImI4IiwgImI5IiwgImIxMCIpXSwgdG9udW1lcmljID0gVFJVRSkNCkRhdGEkYkNTIDwtIFNjb3JlTGlrZXJ0KERhdGFbLCBjKCJiMTIiLCAiYjEzIiwgImIxNCIsICJiMTUiLCAiYjE2IildLCB0b251bWVyaWMgPSBUUlVFKSAgICAgICAgIyBleGNsdWRlIGIxMSBiZWNhdXNlIG5vIHZhcmlhbmNlDQpEYXRhJHBTUyA8LSBTY29yZUxpa2VydChEYXRhWywgYygiYjE3IiwgImIxOCIsICJiMTkiLCAiYjIwIiwgImIyMSIsICJiMjIiKV0sIHRvbnVtZXJpYyA9IFRSVUUpDQpEYXRhJGJDRiA8LSBTY29yZUxpa2VydChEYXRhWywgYygiYjIzIiwgImIyNCIsICJiMjUiLCAiYjI2IiwgImIyNyIsICJiMjgiLCAiYjI5IildLCB0b251bWVyaWMgPSBUUlVFKQ0KRGF0YSRiUlMgPC0gU2NvcmVMaWtlcnQoRGF0YVssIGMoImIzMCIsICJiMzEiLCAiYjMyIiwgImIzMyIpXSwgdG9udW1lcmljID0gVFJVRSkNCg0KRGF0YSRjQ1AgPC0gU2NvcmVMaWtlcnQoRGF0YVssIGMoImMyNCIsICJjMTIiLCAiYzExIiwgImMyNSIsICJjMTAiLCAiYzIzIiwgImMxNyIsICJjMTYiKV0sIHRvbnVtZXJpYyA9IFRSVUUpDQpEYXRhJGNJSSA8LSBTY29yZUxpa2VydChEYXRhWywgYygiYzIwIiwgImMxOCIsICJjMTUiLCAiYzYiLCAiYzciLCAiYzE5IiwgImMxNCIpXSwgdG9udW1lcmljID0gVFJVRSkNCkRhdGEkY0FQIDwtIFNjb3JlTGlrZXJ0KERhdGFbLCBjKCJjMSIsICJjNCIsICJjNSIsICJjMiIsICJjOCIpXSwgdG9udW1lcmljID0gVFJVRSkNCkRhdGEkY0MgPC0gU2NvcmVMaWtlcnQoRGF0YVssIGMoImMyMiIsICJjMTMiLCAiYzIxIildLCB0b251bWVyaWMgPSBUUlVFKQ0KRGF0YSRjSVMgPC0gU2NvcmVMaWtlcnQoRGF0YVssIGMoImMzIiwgImM5IildLCB0b251bWVyaWMgPSBUUlVFKQ0KYGBgDQoNCg0KDQojIERlc2NyaXB0aXZlcw0KDQpgYGB7ciBkZXNjfQ0KRGF0YSAlPiUNCiAgZHBseXI6OnNlbGVjdChUb3RhbGEsIFRvdGFsYiwgVG90YWxjKSAlPiUNCiAgcnN0YXRpeDo6Z2V0X3N1bW1hcnlfc3RhdHModHlwZSA9ICJmdWxsIikgJT4lDQogIGthYmxlRXh0cmE6OmtibChjYXB0aW9uID0gIkRlc2NyaXB0aXZlcyIsIGRpZ2l0cyA9IDIpICU+JQ0KICBrYWJsZUV4dHJhOjprYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBGLCBodG1sX2ZvbnQgPSAiVGltZXMgTmV3IFJvbWFuIikNCmBgYA0KDQojIENvcnJlbGF0aW9ucw0KDQpgYGB7ciBjb3J9DQpEYXRhICU+JQ0KICBkcGx5cjo6c2VsZWN0KFRvdGFsYSwgVG90YWxiLCBUb3RhbGMpICU+JQ0KICBQZXJmb3JtYW5jZUFuYWx5dGljczo6Y2hhcnQuQ29ycmVsYXRpb24oKQ0KDQpEYXRhICU+JQ0KICBkcGx5cjo6c2VsZWN0KFRvdGFsYSwgVG90YWxiLCBUb3RhbGMpICU+JQ0KICBjb3JzdGFycyguLCByZXN1bHQgPSAibm9uZSIpICU+JQ0KICBrYWJsZUV4dHJhOjprYmwoY2FwdGlvbiA9ICJJbnRlci1zY2FsZSBjb3JyZWxhdGlvbnMiLCBkaWdpdHMgPSAyKSAlPiUNCiAga2FibGVFeHRyYTo6a2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gRiwgaHRtbF9mb250ID0gIlRpbWVzIE5ldyBSb21hbiIpDQpgYGANCg0KDQpgYGB7ciByZXN1bHRzPSdhc2lzJywgcm93cy5wcmludCA9IDIwfQ0KIyBjb3JzdGFycyhEYXRhWywgYygxMDM6MTE4KV0sIHJlc3VsdCA9ICJub25lIikNCg0KRGF0YVssIGMoMTAzOjExOCldICU+JQ0KICBjb3JzdGFycyguLCByZXN1bHQgPSAibm9uZSIpICU+JQ0KICBrYWJsZUV4dHJhOjprYmwoY2FwdGlvbiA9ICJJbnRlci1zY2FsZSBjb3JyZWxhdGlvbnMiLCBkaWdpdHMgPSAyKSAlPiUNCiAga2FibGVFeHRyYTo6a2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gRiwgaHRtbF9mb250ID0gIlRpbWVzIE5ldyBSb21hbiIpDQpgYGANCg0KPCEtLQ0KYGBge3J9DQpEYXRhICU+JQ0KICBkcGx5cjo6c2VsZWN0KFRvdGFsYSwgVG90YWxiLCBUb3RhbGMpICU+JQ0KICB0YWJwbG90Ojp0YWJsZXBsb3QoLiwgc29ydENvbCA9IFRvdGFsYSkNCmBgYA0KLS0+DQoNCiMjIFRvcCBhbmQgYm90dG9tIHZhbHVlcw0KDQpgYGB7ciwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OX0NCkRhdGFfcCA8LSANCiAgRGF0YVssIGMoMSwgMTAzOjExOCldICU+JQ0KICBkcGx5cjo6cmVuYW1lKGlkID0gTnVtYXIpICU+JQ0KICBzZWxlY3QoaWQsIGRwbHlyOjpldmVyeXRoaW5nKCkpDQoNCiMjDQptYXhfYSA8LQ0KICBEYXRhX3AgJT4lDQogICAgZHBseXI6OnNsaWNlX21heChUb3RhbGFfY2hlY2ssIG4gPSA1KQ0KbWF4X2EgJT4lICAgDQogIGthYmxlRXh0cmE6OmtibChjYXB0aW9uID0gIk1heCBhIiwgZGlnaXRzID0gMCkgJT4lDQogIGthYmxlRXh0cmE6OmthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IEYsIGh0bWxfZm9udCA9ICJUaW1lcyBOZXcgUm9tYW4iKQ0KbWF4X2EgPC0gbWF4X2EgJT4lIGRwbHlyOjpwdWxsKGlkKQ0KDQptaW5fYSA8LQ0KRGF0YV9wICU+JQ0KICBkcGx5cjo6c2xpY2VfbWluKFRvdGFsYV9jaGVjaywgbiA9IDUpDQptaW5fYSAlPiUgDQogIGthYmxlRXh0cmE6OmtibChjYXB0aW9uID0gIk1pbiBhIiwgZGlnaXRzID0gMCkgJT4lDQogIGthYmxlRXh0cmE6OmthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IEYsIGh0bWxfZm9udCA9ICJUaW1lcyBOZXcgUm9tYW4iKQ0KbWluX2EgPC0gbWluX2EgJT4lIGRwbHlyOjpwdWxsKGlkKQ0KIyMNCg0KIyMNCm1heF9iIDwtDQpEYXRhX3AgJT4lDQogIGRwbHlyOjpzbGljZV9tYXgoVG90YWxiX2NoZWNrLCBuID0gNSkNCm1heF9iICU+JQ0KICBrYWJsZUV4dHJhOjprYmwoY2FwdGlvbiA9ICJNYXggYiIsIGRpZ2l0cyA9IDApICU+JQ0KICBrYWJsZUV4dHJhOjprYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBGLCBodG1sX2ZvbnQgPSAiVGltZXMgTmV3IFJvbWFuIikNCm1heF9iIDwtIG1heF9iICU+JSBkcGx5cjo6cHVsbChpZCkNCg0KbWluX2IgPC0NCkRhdGFfcCAlPiUNCiAgZHBseXI6OnNsaWNlX21pbihUb3RhbGJfY2hlY2ssIG4gPSA1KQ0KbWluX2IgJT4lIA0KICBrYWJsZUV4dHJhOjprYmwoY2FwdGlvbiA9ICJNaW4gYiIsIGRpZ2l0cyA9IDApICU+JQ0KICBrYWJsZUV4dHJhOjprYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBGLCBodG1sX2ZvbnQgPSAiVGltZXMgTmV3IFJvbWFuIikNCm1pbl9iIDwtIG1pbl9iICU+JSBkcGx5cjo6cHVsbChpZCkNCiMjDQoNCiMjDQptYXhfYyA8LQ0KRGF0YV9wICU+JQ0KICBkcGx5cjo6c2xpY2VfbWF4KFRvdGFsY19jaGVjaywgbiA9IDUpDQptYXhfYyAlPiUgDQogIGthYmxlRXh0cmE6OmtibChjYXB0aW9uID0gIk1heCBjIiwgZGlnaXRzID0gMCkgJT4lDQogIGthYmxlRXh0cmE6OmthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IEYsIGh0bWxfZm9udCA9ICJUaW1lcyBOZXcgUm9tYW4iKQ0KbWF4X2MgPC0gbWF4X2MgJT4lIGRwbHlyOjpwdWxsKGlkKQ0KDQptaW5fYyA8LQ0KRGF0YV9wICU+JQ0KICBkcGx5cjo6c2xpY2VfbWluKFRvdGFsY19jaGVjaywgbiA9IDUpDQptaW5fYyAlPiUgDQogIGthYmxlRXh0cmE6OmtibChjYXB0aW9uID0gIk1pbiBjIiwgZGlnaXRzID0gMCkgJT4lDQogIGthYmxlRXh0cmE6OmthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IEYsIGh0bWxfZm9udCA9ICJUaW1lcyBOZXcgUm9tYW4iKQ0KbWluX2MgPC0gbWluX2MgJT4lIGRwbHlyOjpwdWxsKGlkKQ0KIyMNCg0KbWlucyA8LSB1bmlxdWUoYyhtaW5fYSwgbWluX2IsIG1pbl9jKSkNCm1heHMgPC0gdW5pcXVlKGMobWF4X2EsIG1heF9iLCBtYXhfYykpDQoNCkRhdGFfcCRtaW5fbWF4IDwtIGRwbHlyOjpjYXNlX3doZW4oRGF0YV9wJGlkICVpbiUgbWF4cyB+ICJyZWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhX3AkaWQgJWluJSBtaW5zIH4gImdyZWVuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+ICJkYXJrZ3JleSIpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCkRhdGFfcF9sb25nIDwtDQogIERhdGFfcCAlPiUNCiAgZHBseXI6OnNlbGVjdChpZCwgbWluX21heCwgVG90YWxhX2NoZWNrLCBUb3RhbGJfY2hlY2ssIFRvdGFsY19jaGVjaykgJT4lDQogIHRpZHlyOjpwaXZvdF9sb25nZXIoY29scyA9IGMoVG90YWxhX2NoZWNrLCBUb3RhbGJfY2hlY2ssIFRvdGFsY19jaGVjayksIG5hbWVzX3RvID0gInZhcmlhYmxlIiwgdmFsdWVzX3RvID0gInZhbHVlIikNCg0KRGF0YV9wX2xvbmcgJT4lDQogIGdncGxvdChhZXMoeCA9IHZhcmlhYmxlLCB5ID0gdmFsdWUpKSArDQogICAgZ2VvbV92aW9saW4oKSArDQogICAgZ2VvbV9wb2ludChzaXplID0gMSwgYWxwaGEgPSAwLjYsIGNvbG91ciA9IERhdGFfcF9sb25nJG1pbl9tYXgpICsNCiAgICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gaWQpLCBsaW5ldHlwZSA9ICIxMSIsIGNvbG91ciA9IERhdGFfcF9sb25nJG1pbl9tYXgpICsNCiAgICBzY2FsZV9jb2xvdXJfaWRlbnRpdHkoKSArIA0KICAgIHRoZW1lX2NsYXNzaWMoKQ0KYGBgDQoNCg0KIyBDRkENCg0KIyMgRGVmaW5lIGZ1bmN0aW9uDQoNCmBgYHtyIGZ1bmNfY2ZhfQ0KZmFzdF9jZmFfZnVuYyA8LSBmdW5jdGlvbihkYXRhLCBtb2RlbCwgbGF2X2VzdGltYXRvciA9ICJNTCIsIG9yZGVyZWRfdmFycyA9IEZBTFNFKXsNCiAgDQogIGlmKG9yZGVyZWRfdmFycyl7DQogICAgbW9kZWx2YXJzIDwtIGxhdmFhbjo6bGF2TmFtZXMobW9kZWwpICAgICAgICAgICAgICAjICEgZm9yIHNvbWUgcmVhc29uIGxpc3Qgb2YgbmFtZXMgaW4gb3JkZXJlZCBuZWVkcyB0byBtYXRjaCBvcmRlciBvZiBjb2x1bW5zIGluIGRhdGFmcmFtZSwgbm8gcHJvYmxlbSBoZXJlDQogICAgZGF0YSA8LSBhcy5kYXRhLmZyYW1lKGxhcHBseShkYXRhWywgbW9kZWx2YXJzXSwgb3JkZXJlZCkpICAgICAgICAgICAgICMgc3BlY2lhbGx5IGZvciBiaW5hcnkNCiAgfWVsc2V7DQogICAgbW9kZWx2YXJzIDwtIE5VTEwNCiAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGVzdGltYXRvciA9ICJNTCIgLy8gb3JkZXJlZCA9IG5hbWVzKGRhdGEpLCBlc3RpbWF0b3IgPSAiV0xTTVYiDQogIGNmYSA8LSBsYXZhYW46OmNmYShtb2RlbCA9IG1vZGVsLCBkYXRhID0gZGF0YSwgc3RkLmx2ID0gVFJVRSwgZXN0aW1hdG9yID0gbGF2X2VzdGltYXRvciwgb3JkZXJlZCA9IG1vZGVsdmFycykgICANCiAgc3VtbWFyeShjZmEsIGZpdC5tZWFzdXJlID0gVFJVRSwgc3RhbmRhcmRpemVkID0gVFJVRSkgJT4lIHByaW50KCkNCiAgZmNmYSA8LSBsYXZhYW46OmZpdE1lYXN1cmVzKGNmYSwgYygibmZpIiwgInRsaSIsICJjZmkiLCJybXNlYSIsICJybXNlYS5jaS5sb3dlciIsICJybXNlYS5jaS51cHBlciIsICJzcm1yIikpDQogIGZjZmEgJT4lIHByaW50KCkNCiAgc2VtUGxvdDo6c2VtUGF0aHMoY2ZhLCAic3RkIiwgY3VydmVQaXZvdCA9IFRSVUUsIHRocmVzaG9sZHMgPSBGQUxTRSwgbGF5b3V0PSJ0cmVlMiIpICMgZ3JhZmljDQogIHRleHQoMS4yLDEuMSxsYWJlbHM9cGFzdGUwKCdUTEk9Jywgcm91bmQoZmNmYVsidGxpIl0sIDMpLCAnXG4nLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICdDRkk9JywgIHJvdW5kKGZjZmFbImNmaSJdLCAzKSwgJ1xuJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICdORkk9Jywgcm91bmQoZmNmYVsibmZpIl0sIDMpLCAnXG4nLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1JNU0VBPScsIHJvdW5kKGZjZmFbInJtc2VhIl0sIDMpLCAnXG4nLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgJzk1JUNJPScsIHJvdW5kKGZjZmFbInJtc2VhLmNpLmxvd2VyIl0sIDMpLCAnLScsIHJvdW5kKGZjZmFbInJtc2VhLmNpLnVwcGVyIl0sIDMpLCAnXG4nLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1NSTVI9Jywgcm91bmQoZmNmYVsic3JtciJdLCAzKSAgKSAgICkNCiAgcHJpbnQoaGVhZChsYXZhYW46Om1vZGlmaWNhdGlvbmluZGljZXMoY2ZhKVtvcmRlcihsYXZhYW46Om1vZGlmaWNhdGlvbmluZGljZXMoY2ZhKSRtaSwgZGVjcmVhc2luZyA9IFRSVUUpLCBdLCAzMCkpICU+JSBwcmludCgpDQogIHNlbVRvb2xzOjpyZWxpYWJpbGl0eShjZmEpICU+JSBwcmludCgpDQp9DQpgYGANCg0KDQojIyBDRkEgV2FnbmlsZCAmIFlvdW5nDQoNCmBgYHtyIGNmYV9XJnl9DQptb2RlbF9XWSA8LSAnDQpSQ29tcFBlcnMgPX4gIGExICsgYTIgKyBhMyArIGE0ICsgYTUgKyBhNiArIGE5ICsgYTEwICsgYTEzICsgYTE0ICsgYTE1ICsgYTE3ICsgYTE4ICsgYTE5ICsgYTIwICsgYTIzICsgYTI0DQpSQWNjZXB0ID1+ICBhNyArIGE4ICsgYTExICsgYTEyICsgYTE2ICsgYTIxICsgYTIyICsgYTI1DQonDQoNCm1vZGVsX1dZXzFmIDwtICcNCkYgPX4gYTEgKyBhMiArIGEzICsgYTQgKyBhNSArIGE2ICsgYTcgKyBhOCArIGE5ICsgYTEwICsgYTExICsgYTEyICsgYTEzICsgYTE0ICsgYTE1ICsgYTE2ICsgYTE3ICsgYTE4ICsgYTE5ICsgYTIwICsgYTIxICsgYTIyICsgYTIzICsgYTI0ICsgYTI1DQonDQoNCmZhc3RfY2ZhX2Z1bmMoZGF0YSA9IERhdGEsIG1vZGVsID0gbW9kZWxfV1lfMWYpDQpgYGANCg0KIyMgQ0ZBIFdhZ25pbGQgJiBZb3VuZyAtIFNob3J0IDE0DQoNCmBgYHtyIGNmYV9XJnlfc2hvcnR9DQptb2RlbF9XWV9zaG9ydCA8LSAnDQpGID1+IGEyICsgYTYgKyBhNyArIGE4ICsgYTkgKyBhMTAgKyBhMTMgKyBhMTQgKyBhMTUgKyBhMTYgKyBhMTcgKyBhMTggKyBhMjEgKyBhMjMNCicNCg0KZmFzdF9jZmFfZnVuYyhkYXRhID0gRGF0YSwgbW9kZWwgPSBtb2RlbF9XWV9zaG9ydCkNCmBgYA0KDQoNCg0KDQoNCg0KIyMgQ0ZBIFJlc2lsaWVuY2UgU2NhbGUgZm9yIEFkdWx0cw0KDQpgYGB7ciBjZmFfUlNBfQ0KIyBBbmFsaXphIGZhY3RvcmlhbGEgYSBzY2FsZWkgbm9ydmVnaWVuZSBSU0EgZXZpZGVudGlhemEgNiBmYWN0b3JpOg0KIyAxLlBlcmNlcHRpYSBkZSBzaW5lIChpdGVtaWkgMSBsYSA2KQ0KIyAyLlBsYW5pZmljYXJlYSB2aWl0b3J1bHVpIChpdGVtaWkgNyBsYSAxMCkNCiMgMy5Db21wZXRlbnRhIHNvY2lhbGEgKGl0ZW1paSAxMSBsYSAxNikNCiMgNC5TdGlsIHN0cnVjdHVyYXQgKGl0ZW1paSAxNyBsYSAyMikNCiMgNS5Db2V6aXVuZWEgZmFtaWxpYWxhIChpdGVtaWkgMjMgbGEgMjkpDQojIDYuUmVzdXJzZWxlIHNvY2lhbGUgKGl0ZW1paSAzMCBsYSAzMykNCg0KIyBwYXN0ZShzcHJpbnRmKCJiJWQiLCAxOjYpLCBjb2xsYXBzZSA9ICIgKyAiKQ0KbW9kZWxfUlNBIDwtICcNCmJQUyA9fiBiMSArIGIyICsgYjMgKyBiNCArIGI1ICsgYjYNCmJQViA9fiBiNyArIGI4ICsgYjkgKyBiMTANCmJDUyA9fiBiMTIgKyBiMTMgKyBiMTQgKyBiMTUgKyBiMTYgICAgICAgICAgDQpwU1MgPX4gYjE3ICsgYjE4ICsgYjE5ICsgYjIwICsgYjIxICsgYjIyDQpiQ0YgPX4gYjIzICsgYjI0ICsgYjI1ICsgYjI2ICsgYjI3ICsgYjI4ICsgYjI5DQpiUlMgPX4gYjMwICsgYjMxICsgYjMyICsgYjMzDQonDQoNCm1vZGVsX1JTQV8xZiA8LSAnDQpGID1+IGIxICsgYjIgKyBiMyArIGI0ICsgYjUgKyBiNiArIGI3ICsgYjggKyBiOSArIGIxMCArIGIxMiArIGIxMyArIGIxNCArIGIxNSArIGIxNiArIGIxNyArIGIxOCArIGIxOSArIGIyMCArICAgICAjIGV4Y2x1ZGUgYjExIGJlY2F1c2Ugbm8gdmFyaWFuY2UNCiAgICAgYjIxICsgYjIyICsgYjIzICsgYjI0ICsgYjI1ICsgYjI2ICsgYjI3ICsgYjI4ICsgYjI5ICsgYjMwICsgYjMxICsgYjMyICsgYjMzIA0KJw0KDQpmYXN0X2NmYV9mdW5jKGRhdGEgPSBEYXRhLCBtb2RlbCA9IG1vZGVsX1JTQV8xZikNCmBgYA0KDQoNCiMjIyBDRkEgUmVzaWxpZW5jZSBTY2FsZSBmb3IgQWR1bHRzIC0gU2hvcnQgMTEgKEdlcm1hbikNCg0KYGBge3IgY2ZhX1JTQV9zaG9ydH0NCiMgdGhlIEdlcm1hbiBzaG9ydCB2ZXJzaW9uIGFscmVhZHkgZG9lc250J3QgaW5jbHVkZSBiMTEgd2hpY2ggaXMgbWlzc2luZyBpbiBvdXIgZGF0YQ0KDQojIHRlc3RfZGYgPC0gRGF0YQ0KIyB0ZXN0X2RmJGI4IDwtIDggLSB0ZXN0X2RmJGI4ICAgICMgdHJ5IHJldmVyc2UgY29kaW5nIGI4DQoNCm1vZGVsX1JTQV9zaG9ydCA8LSAnDQpGID1+IGIxICsgYjIgKyBiNCArIGI4ICsgYjkgKyBiMTAgKyBiMTUgKyBiMTYgKyBiMTkgKyBiMjAgKyBiMjQgDQonDQoNCmZhc3RfY2ZhX2Z1bmMoZGF0YSA9IERhdGEsIG1vZGVsID0gbW9kZWxfUlNBX3Nob3J0KQ0KYGBgDQoNCg0KIyMgQ0ZBIENvbm5vci1EYXZpZHNvbg0KDQpgYGB7ciBjZmFfQ0R9DQojIEFuYWxpemEgZmFjdG9yaWFsYSBsYSBzY2FsZWkgQ29ubm9yLURhdmlkc29uIHB1bmUgw65uIGV2aWRlbnRhIDUgZmFjdG9yaToNCiMgLUZhY3RvcnVsIDEg4oCTIENvbXBldGVudGEgcGVyc29uYWxhLCBzdGFuZGFyZGUgw65uYWx0ZSBzaSB0ZW5hY2l0YXRlDQojIFtpdGVtaWkgMjQsIDEyLCAxMSwgMjUsIDEwLCAyMywgMTcsIDE2XQ0KIyAtRmFjdG9ydWwgMiDigJMgw45uY3JlZGVyZWEgw65uIGludHVpdGlpbGUgc2FsZSwgdG9sZXJhbnRhIGZhdGEgZGUgYWZlY3RlbGUgbmVnYXRpdmUgc2kgZmF0YSBkZSBlZmVjdGVsZSBhY2NlbnR1YXJpaSBzdHJlc3VsdWkNCiMgW2l0ZW1paSAyMCwgMTgsIDE1LCA2LCA3LCAxOSwgMTRdDQojIC1GYWN0b3J1bCAzIOKAkyBBY2NlcHRhcmVhIHBveml0aXZhIGEgc2NoaW1iYXJpbG9yIHNpIHJlbGF0aWkgc2lndXJlL3NlY3VyZQ0KIyBbaXRlbWlpIDEsIDQsIDUsIDIsIDhdDQojIC1GYWN0b3J1bCA0IOKAkyBDb250cm9sdWwNCiMgW2l0ZW1paSAyMiwgMTMsIDIxXQ0KIyAtRmFjdG9ydWwgNSDigJMgSW5mbHVlbnRlbGUgc3Bpcml0dWFsZQ0KIyBbaXRlbWlpIDMsIDldDQoNCg0KIyBwYXN0ZShzcHJpbnRmKCJjJWQiLCBjKDI0LCAxMiwgMTEsIDI1LCAxMCwgMjMsIDE3LCAxNikpLCBjb2xsYXBzZSA9ICIgKyAiKQ0KbW9kZWxfQ0QgPC0gJw0KY0NQID1+IGMyNCArIGMxMiArIGMxMSArIGMyNSArIGMxMCArIGMyMyArIGMxNyArIGMxNg0KY0lJID1+IGMyMCArIGMxOCArIGMxNSArIGM2ICsgYzcgKyBjMTkgKyBjMTQNCmNBUCA9fiBjMSArIGM0ICsgYzUgKyBjMiArIGM4DQpjQyA9fiBjMjIgKyBjMTMgKyBjMjENCmNJUyA9fiBjMyArIGM5IA0KJw0KDQptb2RlbF9DRF8xZiA8LSAnDQpGID1+IGMxICsgYzIgKyBjMyArIGM0ICsgYzUgKyBjNiArIGM3ICsgYzggKyBjOSArIGMxMCArIGMxMSArIGMxMiArIGMxMyArIGMxNCArIGMxNSArIGMxNiArIGMxNyArIGMxOCArIGMxOSArIGMyMCArIGMyMSArIGMyMiArIGMyMyArIGMyNCArIGMyNQ0KJw0KDQpmYXN0X2NmYV9mdW5jKGRhdGEgPSBEYXRhLCBtb2RlbCA9IG1vZGVsX0NEXzFmKQ0KYGBgDQoNCg0KIyMjIENGQSBDb25ub3ItRGF2aWRzb24gLSBTaG9ydCAxMA0KDQpgYGB7ciBjZmFfQ0Rfc2hvcnR9DQptb2RlbF9DRF9zaG9ydCA8LSAnDQpGID1+IGMxICsgYzQgKyBjNiArIGM3ICsgYzggKyBjMTEgKyBjMTQgKyBjMTYgKyBjMTcgKyBjMTkNCicNCg0KZmFzdF9jZmFfZnVuYyhkYXRhID0gRGF0YSwgbW9kZWwgPSBtb2RlbF9DRF9zaG9ydCkNCmBgYA0KDQoNCjwhLS0gU2Vzc2lvbiBJbmZvIGFuZCBMaWNlbnNlIC0tPg0KDQo8YnI+DQoNCiMgU2Vzc2lvbiBJbmZvDQpgYGB7ciBzZXNzaW9uX2luZm8sIGVjaG8gPSBGQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQ0Kc2Vzc2lvbkluZm8oKSAgICANCmBgYA0KDQo8IS0tIEZvb3RlciAtLT4NCiZuYnNwOw0KPGhyIC8+DQo8cCBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyI+QSB3b3JrIGJ5IDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9DbGF1ZGl1UGFwYXN0ZXJpLyI+Q2xhdWRpdSBQYXBhc3Rlcmk8L2E+PC9wPg0KPHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxzcGFuIHN0eWxlPSJjb2xvcjogIzgwODA4MDsiPjxlbT5jbGF1ZGl1LnBhcGFzdGVyaUBnbWFpbC5jb208L2VtPjwvc3Bhbj48L3A+DQombmJzcDsNCg==