Example data: 634 older adults (age 80-100) self-reporting on 7 items assessing the Instrumental Activities of Daily Living (IADL) as follows:

  1. Housework (cleaning and laundry): 1=64%
  2. Bedmaking: 1=84%
  3. Cooking: 1=77%
  4. Everyday shopping: 1=66%
  5. Getting to places outside of walking distance: 1=65%
  6. Handling banking and other business: 1=73%
  7. Using the telephone 1=94%

Two versions of a response format were available:

Binary -> 0 = “needs help”, 1 = “does not need help”

Categorical -> 0 = “can’t do it”, 1=”big problems”, 2=”some problems”, 3=”no problems”

Higher scores indicate greater function. We will look at each response format in turn.

Package Installation and Loading

if (require(lavaan) == FALSE){
  install.packages("lavaan")
}
library(lavaan)

Data Import into R

The data are in a text file named adl.dat orignally used in Mplus (so no column names were included at the top of the file). The file contains more items than we will use, so we select only items above from the whole file.

#read in data file (Mplus file format so having to label columns)
adlData = read.table(file = "adl.dat", header = FALSE, na.strings = ".", col.names = c("case", paste0("dpa", 1:14), paste0("dia", 1:7), paste0("cpa", 1:14), paste0("cia", 1:7)))
#select Situations items and PersonID variables
iadlDataInit = adlData[c(paste0("cia", 1:7))]
#remove cases with all items missing
removeCases = which(apply(X = iadlDataInit, MARGIN = 1, FUN = function (x){ length(which(is.na(x)))}) == 7)
iadlData = iadlDataInit[-removeCases,]

Graded Response Model (2PL-ish version) using WLSMV probit model

grm2Psyntax = "
IADL =~ cia1 + cia2 + cia3 + cia4 + cia5 + cia6 + cia7
"
grm2Pestimates = cfa(model = grm2Psyntax, data = iadlData, ordered = c("cia1", "cia2", "cia3", "cia4", "cia5", "cia6", "cia7"), std.lv = TRUE, parameterization="theta")
lavaan WARNING: 18 bivariate tables have empty cells; to see them, use:
                  lavInspect(fit, "zero.cell.tables")
summary(grm2Pestimates, fit.measures = TRUE, rsquare = TRUE, standardized = TRUE)
lavaan (0.5-23.1097) converged normally after 105 iterations

                                                  Used       Total
  Number of observations                           546         634

  Estimator                                       DWLS      Robust
  Minimum Function Test Statistic               40.866      88.144
  Degrees of freedom                                14          14
  P-value (Chi-square)                           0.000       0.000
  Scaling correction factor                                  0.483
  Shift parameter                                            3.497
    for simple second-order correction (Mplus variant)

Model test baseline model:

  Minimum Function Test Statistic            48788.234   24684.141
  Degrees of freedom                                21          21
  P-value                                        0.000       0.000

User model versus baseline model:

  Comparative Fit Index (CFI)                    0.999       0.997
  Tucker-Lewis Index (TLI)                       0.999       0.995

  Robust Comparative Fit Index (CFI)                            NA
  Robust Tucker-Lewis Index (TLI)                               NA

Root Mean Square Error of Approximation:

  RMSEA                                          0.059       0.099
  90 Percent Confidence Interval          0.039  0.081       0.079  0.119
  P-value RMSEA <= 0.05                          0.211       0.000

  Robust RMSEA                                                  NA
  90 Percent Confidence Interval                                NA     NA

Standardized Root Mean Square Residual:

  SRMR                                           0.027       0.027

Weighted Root Mean Square Residual:

  WRMR                                           0.986       0.986

Parameter Estimates:

  Information                                 Expected
  Standard Errors                           Robust.sem

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  IADL =~                                                               
    cia1              3.450    0.301   11.470    0.000    3.450    0.960
    cia2              3.620    0.507    7.139    0.000    3.620    0.964
    cia3              3.026    0.292   10.361    0.000    3.026    0.949
    cia4              3.310    0.300   11.030    0.000    3.310    0.957
    cia5              2.360    0.190   12.412    0.000    2.360    0.921
    cia6              1.943    0.182   10.680    0.000    1.943    0.889
    cia7              1.044    0.135    7.724    0.000    1.044    0.722

Intercepts:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .cia1              0.000                               0.000    0.000
   .cia2              0.000                               0.000    0.000
   .cia3              0.000                               0.000    0.000
   .cia4              0.000                               0.000    0.000
   .cia5              0.000                               0.000    0.000
   .cia6              0.000                               0.000    0.000
   .cia7              0.000                               0.000    0.000
    IADL              0.000                               0.000    0.000

Thresholds:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    cia1|t1          -4.946    0.385  -12.838    0.000   -4.946   -1.377
    cia1|t2          -3.636    0.324  -11.233    0.000   -3.636   -1.012
    cia1|t3          -0.900    0.219   -4.111    0.000   -0.900   -0.251
    cia2|t1          -5.502    0.658   -8.356    0.000   -5.502   -1.465
    cia2|t2          -4.797    0.605   -7.928    0.000   -4.797   -1.277
    cia2|t3          -2.973    0.463   -6.421    0.000   -2.973   -0.792
    cia3|t1          -4.426    0.362  -12.226    0.000   -4.426   -1.389
    cia3|t2          -3.702    0.331  -11.175    0.000   -3.702   -1.162
    cia3|t3          -2.050    0.262   -7.821    0.000   -2.050   -0.643
    cia4|t1          -4.490    0.355  -12.647    0.000   -4.490   -1.298
    cia4|t2          -3.100    0.282  -10.977    0.000   -3.100   -0.897
    cia4|t3          -1.098    0.225   -4.881    0.000   -1.098   -0.317
    cia5|t1          -4.098    0.281  -14.607    0.000   -4.098   -1.599
    cia5|t2          -2.195    0.190  -11.578    0.000   -2.195   -0.856
    cia5|t3          -0.618    0.151   -4.089    0.000   -0.618   -0.241
    cia6|t1          -3.605    0.255  -14.125    0.000   -3.605   -1.650
    cia6|t2          -2.558    0.203  -12.628    0.000   -2.558   -1.171
    cia6|t3          -1.531    0.171   -8.974    0.000   -1.531   -0.701
    cia7|t1          -3.311    0.268  -12.345    0.000   -3.311   -2.291
    cia7|t2          -2.695    0.199  -13.556    0.000   -2.695   -1.864
    cia7|t3          -1.788    0.145  -12.304    0.000   -1.788   -1.237

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .cia1              1.000                               1.000    0.078
   .cia2              1.000                               1.000    0.071
   .cia3              1.000                               1.000    0.098
   .cia4              1.000                               1.000    0.084
   .cia5              1.000                               1.000    0.152
   .cia6              1.000                               1.000    0.209
   .cia7              1.000                               1.000    0.479
    IADL              1.000                               1.000    1.000

Scales y*:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    cia1              0.278                               0.278    1.000
    cia2              0.266                               0.266    1.000
    cia3              0.314                               0.314    1.000
    cia4              0.289                               0.289    1.000
    cia5              0.390                               0.390    1.000
    cia6              0.458                               0.458    1.000
    cia7              0.692                               0.692    1.000

R-Square:
                   Estimate
    cia1              0.922
    cia2              0.929
    cia3              0.902
    cia4              0.916
    cia5              0.848
    cia6              0.791
    cia7              0.521

Parameter estimates under WLSMV Theta Parameterization (Probit) for the 2PL version of polytomous responses

Factor loadings:

Latent Variables: Estimate Std.Err z-value P(>|z|) Std.lv Std.all IADL =~
cia1 3.450 0.301 11.470 0.000 3.450 0.960 cia2 3.620 0.507 7.139 0.000 3.620 0.964 cia3 3.026 0.292 10.361 0.000 3.026 0.949 cia4 3.310 0.300 11.030 0.000 3.310 0.957 cia5 2.360 0.190 12.412 0.000 2.360 0.921 cia6 1.943 0.182 10.680 0.000 1.943 0.889 cia7 1.044 0.135 7.724 0.000 1.044 0.722

Thresholds:
               Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
cia1|t1          -4.946    0.385  -12.838    0.000   -4.946   -1.377
cia1|t2          -3.636    0.324  -11.233    0.000   -3.636   -1.012
cia1|t3          -0.900    0.219   -4.111    0.000   -0.900   -0.251
cia2|t1          -5.502    0.658   -8.356    0.000   -5.502   -1.465
cia2|t2          -4.797    0.605   -7.928    0.000   -4.797   -1.277
cia2|t3          -2.973    0.463   -6.421    0.000   -2.973   -0.792
cia3|t1          -4.426    0.362  -12.226    0.000   -4.426   -1.389
cia3|t2          -3.702    0.331  -11.175    0.000   -3.702   -1.162
cia3|t3          -2.050    0.262   -7.821    0.000   -2.050   -0.643
cia4|t1          -4.490    0.355  -12.647    0.000   -4.490   -1.298
cia4|t2          -3.100    0.282  -10.977    0.000   -3.100   -0.897
cia4|t3          -1.098    0.225   -4.881    0.000   -1.098   -0.317
cia5|t1          -4.098    0.281  -14.607    0.000   -4.098   -1.599
cia5|t2          -2.195    0.190  -11.578    0.000   -2.195   -0.856
cia5|t3          -0.618    0.151   -4.089    0.000   -0.618   -0.241
cia6|t1          -3.605    0.255  -14.125    0.000   -3.605   -1.650
cia6|t2          -2.558    0.203  -12.628    0.000   -2.558   -1.171
cia6|t3          -1.531    0.171   -8.974    0.000   -1.531   -0.701
cia7|t1          -3.311    0.268  -12.345    0.000   -3.311   -2.291
cia7|t2          -2.695    0.199  -13.556    0.000   -2.695   -1.864
cia7|t3          -1.788    0.145  -12.304    0.000   -1.788   -1.237

Calculations

Logit = 1.7*probit, or Probit = Logit/1.7

IFA model: Probit(y=1) = –threshold + loading(Theta)

Threshold = expected probit of (y=0) for someone with Theta=0

When *-1, threshold \(\rightarrow\) intercept: expected probit for (y=1) instead

Loading = regression of item probit on Theta

For 4-category responses, the sub-models look like this: Probit(y= 0 vs 123) = -threshold$1 + loading(Theta) Probit(y= 01 vs 23) = -threshold$2 + loading(Theta) Probit y= 012 vs 3) = -threshold$3 + loading(Theta)

IRT model: Probit(y) = a(theta – difficulty) a = discrimination (rescaled slope) = loading b = difficulty (location on latent metric) = threshold/loading

For 4-category responses, the sub-models look like this: $1 Probit(y= 0 vs 123) = a(theta – difficulty$1) $2 Probit(y= 01 vs 23) = a(theta – difficulty$2) $3 Probit(y= 012 vs 3) = a(theta – difficulty$3)

Model Fit

LOCAL FIT VIA RAW RESIDUAL CORRELATIONS LEFTOVER POLYCHORIC CORRELATION (HOW FAR OFF FROM DATA)

With raw residuals, the scale is that of correlation (different from normalized)

resid(object = grm2Pestimates)
$type
[1] "raw"

$cov
     cia1   cia2   cia3   cia4   cia5   cia6   cia7  
cia1  0.000                                          
cia2  0.011  0.000                                   
cia3  0.011  0.019  0.000                            
cia4 -0.004 -0.029 -0.031  0.000                     
cia5 -0.032 -0.045 -0.073  0.030  0.000              
cia6 -0.034 -0.041 -0.032  0.016  0.038  0.000       
cia7 -0.033 -0.012  0.008  0.026 -0.024  0.032  0.000

$mean
cia1 cia2 cia3 cia4 cia5 cia6 cia7 
   0    0    0    0    0    0    0 

$th
      cia1|t1       cia1|t2       cia1|t3       cia2|t1       cia2|t2       cia2|t3       cia3|t1       cia3|t2       cia3|t3       cia4|t1       cia4|t2       cia4|t3       cia5|t1       cia5|t2       cia5|t3       cia6|t1       cia6|t2 
 4.442409e-07  2.380854e-07 -5.151503e-07  5.839083e-07  4.231467e-07 -5.816415e-07  8.124267e-08 -2.486851e-07  4.924815e-07 -8.218725e-08  1.260747e-07  2.750163e-07 -1.837495e-08 -2.242499e-08  1.384602e-07 -4.543028e-08  1.239583e-07 
      cia6|t3       cia7|t1       cia7|t2       cia7|t3 
-2.758846e-07  4.511172e-07  2.015248e-07  1.683076e-07 

Item Plots

lavaanCatItemPlot = function(lavObject, varname, sds = 3){
  output = inspect(object = lavObject, what = "est")
  if (!varname %in% rownames(output$lambda)) stop(paste(varname, "not found in lavaan object"))
  if (dim(output$lambda)[2]>1) stop("plots only given for one factor models")
  
  itemloading = output$lambda[which(rownames(output$lambda) == varname),1]
  itemthresholds = output$tau[grep(pattern = varname, x = rownames(output$tau))]
  
  factorname = colnames(output$lambda)
  factormean = output$alpha[which(rownames(output$alpha) == factorname)]
  factorvar = output$psi[which(rownames(output$psi) == factorname)]
  
  factormin = factormean - 3*sqrt(factorvar)
  factormax = factormean + 3*sqrt(factorvar)
  
  factorX = seq(factormin, factormax, .01)
  itemloc = which(lavObject@Data@ov$name == varname)      
  itemlevels = unlist(strsplit(x = lavObject@Data@ov$lnam[itemloc], split = "\\|"))  
  if (length(itemthresholds)>1){
    
    plotdata = NULL
    plotdata2 = NULL
    itemY = NULL
    itemY2 = NULL
    itemX = NULL
    itemText = NULL
    for (level in 1:length(itemthresholds)){
      
      itemY = pnorm(q = -1*itemthresholds[level] + itemloading*factorX)
      itemY2 = cbind(itemY2, pnorm(q = -1*itemthresholds[level] + itemloading*factorX))
      itemText = paste0("P(", varname, " > ", itemlevels[level], ")")
      itemText2 = paste0("P(", varname, " = ", itemlevels[level], ")")
      plotdata = rbind(plotdata, data.frame(factor = factorX, prob = itemY, plot = itemText))
      
      if (level == 1){
        plotdata2 = data.frame(factor = factorX, plot = itemText2, prob = matrix(1, nrow = dim(itemY2)[1], ncol=1) - itemY2[,level])
      } else if (level == length(itemthresholds)){
        plotdata2 = rbind(plotdata2, data.frame(factor = factorX, plot = itemText2, prob = itemY2[,level-1] - itemY2[,level]))
        plotdata2 = rbind(plotdata2, data.frame(factor = factorX, plot = paste0("P(", varname, " = ", itemlevels[level+1], ")"), prob = itemY2[,level]))                  
      } else {
        plotdata2 = rbind(plotdata2, data.frame(factor = factorX, plot = itemText2, prob = itemY2[,level-1] - itemY2[,level]))
      }
      
    }
    
    names(plotdata) = c(factorname , "Probability", "Cumulative")
    ggplot(data = plotdata, aes_string(x = factorname, y = "Probability", colour = "Cumulative")) + geom_line(size = 2)
    
    names(plotdata2) = c(factorname, "Response", "Probability")
    ggplot(data = plotdata2, aes_string(x = factorname, y = "Probability", colour = "Response")) + geom_line(size = 2)
  } else {
    
    itemY = pnorm(q = -1*itemthresholds[1] + itemloading*factorX)
    itemText2 = paste0("P(", varname, " = ", itemlevels[1], ")")
    plotdata = data.frame(factor = factorX, prob = itemY, plot = itemText2)
    
    names(plotdata) = c(factorname , "Probability", "Response")
    ggplot(data = plotdata, aes_string(x = factorname, y = "Probability", colour = "Response")) + geom_line(size = 2)
    
  }
}
lavaanCatItemPlot(lavObject = grm2Pestimates, varname = "cia2", sds = 3)

Graded Response Model (1PL-ish version) using WLSMV probit model

We can also set the item discriminations equal for a 1PL-like model:

grm1Psyntax = "
IADL =~ a*cia1 + a*cia2 + a*cia3 + a*cia4 + a*cia5 + a*cia6 + a*cia7
"
grm1Pestimates = cfa(model = grm1Psyntax, data = iadlData, ordered = c("cia1", "cia2", "cia3", "cia4", "cia5", "cia6", "cia7"), std.lv = TRUE, parameterization="theta")
lavaan WARNING: 18 bivariate tables have empty cells; to see them, use:
                  lavInspect(fit, "zero.cell.tables")
summary(grm1Pestimates, fit.measures = TRUE, rsquare = TRUE, standardized = TRUE)
lavaan (0.5-23.1097) converged normally after  32 iterations

                                                  Used       Total
  Number of observations                           546         634

  Estimator                                       DWLS      Robust
  Minimum Function Test Statistic              196.654     181.733
  Degrees of freedom                                20          20
  P-value (Chi-square)                           0.000       0.000
  Scaling correction factor                                  1.128
  Shift parameter                                            7.402
    for simple second-order correction (Mplus variant)

Model test baseline model:

  Minimum Function Test Statistic            48788.234   24684.141
  Degrees of freedom                                21          21
  P-value                                        0.000       0.000

User model versus baseline model:

  Comparative Fit Index (CFI)                    0.996       0.993
  Tucker-Lewis Index (TLI)                       0.996       0.993

  Robust Comparative Fit Index (CFI)                            NA
  Robust Tucker-Lewis Index (TLI)                               NA

Root Mean Square Error of Approximation:

  RMSEA                                          0.127       0.122
  90 Percent Confidence Interval          0.111  0.144       0.106  0.138
  P-value RMSEA <= 0.05                          0.000       0.000

  Robust RMSEA                                                  NA
  90 Percent Confidence Interval                                NA     NA

Standardized Root Mean Square Residual:

  SRMR                                           0.105       0.105

Weighted Root Mean Square Residual:

  WRMR                                           2.164       2.164

Parameter Estimates:

  Information                                 Expected
  Standard Errors                           Robust.sem

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  IADL =~                                                               
    cia1       (a)    2.852    0.154   18.566    0.000    2.852    0.944
    cia2       (a)    2.852    0.154   18.566    0.000    2.852    0.944
    cia3       (a)    2.852    0.154   18.566    0.000    2.852    0.944
    cia4       (a)    2.852    0.154   18.566    0.000    2.852    0.944
    cia5       (a)    2.852    0.154   18.566    0.000    2.852    0.944
    cia6       (a)    2.852    0.154   18.566    0.000    2.852    0.944
    cia7       (a)    2.852    0.154   18.566    0.000    2.852    0.944

Intercepts:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .cia1              0.000                               0.000    0.000
   .cia2              0.000                               0.000    0.000
   .cia3              0.000                               0.000    0.000
   .cia4              0.000                               0.000    0.000
   .cia5              0.000                               0.000    0.000
   .cia6              0.000                               0.000    0.000
   .cia7              0.000                               0.000    0.000
    IADL              0.000                               0.000    0.000

Thresholds:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    cia1|t1          -4.161    0.197  -21.096    0.000   -4.161   -1.377
    cia1|t2          -3.059    0.199  -15.404    0.000   -3.059   -1.012
    cia1|t3          -0.757    0.173   -4.382    0.000   -0.757   -0.251
    cia2|t1          -4.428    0.192  -23.062    0.000   -4.428   -1.465
    cia2|t2          -3.860    0.189  -20.430    0.000   -3.860   -1.277
    cia2|t3          -2.392    0.197  -12.172    0.000   -2.392   -0.792
    cia3|t1          -4.197    0.193  -21.701    0.000   -4.197   -1.389
    cia3|t2          -3.510    0.198  -17.755    0.000   -3.510   -1.162
    cia3|t3          -1.943    0.188  -10.340    0.000   -1.943   -0.643
    cia4|t1          -3.924    0.198  -19.846    0.000   -3.924   -1.298
    cia4|t2          -2.709    0.195  -13.921    0.000   -2.709   -0.897
    cia4|t3          -0.959    0.175   -5.485    0.000   -0.959   -0.317
    cia5|t1          -4.831    0.259  -18.655    0.000   -4.831   -1.599
    cia5|t2          -2.587    0.197  -13.150    0.000   -2.587   -0.856
    cia5|t3          -0.728    0.170   -4.274    0.000   -0.728   -0.241
    cia6|t1          -4.987    0.262  -19.018    0.000   -4.987   -1.650
    cia6|t2          -3.537    0.206  -17.180    0.000   -3.537   -1.171
    cia6|t3          -2.117    0.189  -11.208    0.000   -2.117   -0.701
    cia7|t1          -6.922    0.474  -14.594    0.000   -6.922   -2.291
    cia7|t2          -5.634    0.332  -16.985    0.000   -5.634   -1.864
    cia7|t3          -3.738    0.249  -15.017    0.000   -3.738   -1.237

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .cia1              1.000                               1.000    0.110
   .cia2              1.000                               1.000    0.110
   .cia3              1.000                               1.000    0.110
   .cia4              1.000                               1.000    0.110
   .cia5              1.000                               1.000    0.110
   .cia6              1.000                               1.000    0.110
   .cia7              1.000                               1.000    0.110
    IADL              1.000                               1.000    1.000

Scales y*:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    cia1              0.331                               0.331    1.000
    cia2              0.331                               0.331    1.000
    cia3              0.331                               0.331    1.000
    cia4              0.331                               0.331    1.000
    cia5              0.331                               0.331    1.000
    cia6              0.331                               0.331    1.000
    cia7              0.331                               0.331    1.000

R-Square:
                   Estimate
    cia1              0.890
    cia2              0.890
    cia3              0.890
    cia4              0.890
    cia5              0.890
    cia6              0.890
    cia7              0.890

Similarly, we can use the anova() function to compare model fit:

anova(grm1Pestimates, grm2Pestimates)
Scaled Chi Square Difference Test (method = "satorra.2000")

               Df AIC BIC   Chisq Chisq diff Df diff Pr(>Chisq)    
grm2Pestimates 14          40.866                                  
grm1Pestimates 20         196.654     67.889  3.9116  5.508e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
LS0tCnRpdGxlOiAiRVBTWSA5MDYvQ0xEUCA5NDggRXhhbXBsZSA2IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpFeGFtcGxlIGRhdGE6IDYzNCBvbGRlciBhZHVsdHMgKGFnZSA4MC0xMDApIHNlbGYtcmVwb3J0aW5nIG9uIDcgaXRlbXMgYXNzZXNzaW5nIHRoZSBJbnN0cnVtZW50YWwgQWN0aXZpdGllcyBvZiBEYWlseSBMaXZpbmcgKElBREwpIGFzIGZvbGxvd3M6CgoxLiBIb3VzZXdvcmsgKGNsZWFuaW5nIGFuZCBsYXVuZHJ5KTogMT02NCUKMi4gQmVkbWFraW5nOiAxPTg0JQozLiBDb29raW5nOiAxPTc3JQo0LiBFdmVyeWRheSBzaG9wcGluZzogMT02NiUKNS4gR2V0dGluZyB0byBwbGFjZXMgb3V0c2lkZSBvZiB3YWxraW5nIGRpc3RhbmNlOiAxPTY1JQo2LiBIYW5kbGluZyBiYW5raW5nIGFuZCBvdGhlciBidXNpbmVzczogMT03MyUJCjcuIFVzaW5nIHRoZSB0ZWxlcGhvbmUgMT05NCUKClR3byB2ZXJzaW9ucyBvZiBhIHJlc3BvbnNlIGZvcm1hdCB3ZXJlIGF2YWlsYWJsZToKCkJpbmFyeSAtPiAwID0g4oCcbmVlZHMgaGVscOKAnSwgMSA9IOKAnGRvZXMgbm90IG5lZWQgaGVscOKAnQoKQ2F0ZWdvcmljYWwgLT4gMCA9IOKAnGNhbuKAmXQgZG8gaXTigJ0sIDE94oCdYmlnIHByb2JsZW1z4oCdLCAyPeKAnXNvbWUgcHJvYmxlbXPigJ0sIDM94oCdbm8gcHJvYmxlbXPigJ0KCkhpZ2hlciBzY29yZXMgaW5kaWNhdGUgZ3JlYXRlciBmdW5jdGlvbi4gV2Ugd2lsbCBsb29rIGF0IGVhY2ggcmVzcG9uc2UgZm9ybWF0IGluIHR1cm4uCgojIyMgUGFja2FnZSBJbnN0YWxsYXRpb24gYW5kIExvYWRpbmcgCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1UUlVFfQppZiAocmVxdWlyZShsYXZhYW4pID09IEZBTFNFKXsKICBpbnN0YWxsLnBhY2thZ2VzKCJsYXZhYW4iKQp9CmxpYnJhcnkobGF2YWFuKQpgYGAKCiMjIyBEYXRhIEltcG9ydCBpbnRvIFIKVGhlIGRhdGEgYXJlIGluIGEgdGV4dCBmaWxlIG5hbWVkIGBgYGFkbC5kYXRgYGAgb3JpZ25hbGx5IHVzZWQgaW4gTXBsdXMgKHNvIG5vIGNvbHVtbiBuYW1lcyB3ZXJlIGluY2x1ZGVkIGF0IHRoZSB0b3Agb2YgdGhlIGZpbGUpLiBUaGUgZmlsZSBjb250YWlucyBtb3JlIGl0ZW1zIHRoYW4gd2Ugd2lsbCB1c2UsIHNvIHdlIHNlbGVjdCBvbmx5IGl0ZW1zIGFib3ZlIGZyb20gdGhlIHdob2xlIGZpbGUuCgpgYGB7ciBkYXRhLCBpbmNsdWRlPVRSVUV9CgojcmVhZCBpbiBkYXRhIGZpbGUgKE1wbHVzIGZpbGUgZm9ybWF0IHNvIGhhdmluZyB0byBsYWJlbCBjb2x1bW5zKQphZGxEYXRhID0gcmVhZC50YWJsZShmaWxlID0gImFkbC5kYXQiLCBoZWFkZXIgPSBGQUxTRSwgbmEuc3RyaW5ncyA9ICIuIiwgY29sLm5hbWVzID0gYygiY2FzZSIsIHBhc3RlMCgiZHBhIiwgMToxNCksIHBhc3RlMCgiZGlhIiwgMTo3KSwgcGFzdGUwKCJjcGEiLCAxOjE0KSwgcGFzdGUwKCJjaWEiLCAxOjcpKSkKCiNzZWxlY3QgU2l0dWF0aW9ucyBpdGVtcyBhbmQgUGVyc29uSUQgdmFyaWFibGVzCmlhZGxEYXRhSW5pdCA9IGFkbERhdGFbYyhwYXN0ZTAoImNpYSIsIDE6NykpXQoKI3JlbW92ZSBjYXNlcyB3aXRoIGFsbCBpdGVtcyBtaXNzaW5nCnJlbW92ZUNhc2VzID0gd2hpY2goYXBwbHkoWCA9IGlhZGxEYXRhSW5pdCwgTUFSR0lOID0gMSwgRlVOID0gZnVuY3Rpb24gKHgpeyBsZW5ndGgod2hpY2goaXMubmEoeCkpKX0pID09IDcpCgppYWRsRGF0YSA9IGlhZGxEYXRhSW5pdFstcmVtb3ZlQ2FzZXMsXQpgYGAKCiMjIyBHcmFkZWQgUmVzcG9uc2UgTW9kZWwgKDJQTC1pc2ggdmVyc2lvbikgdXNpbmcgV0xTTVYgcHJvYml0IG1vZGVsCgpgYGB7ciBncm0ycCwgaW5jbHVkZT1UUlVFfQpncm0yUHN5bnRheCA9ICIKSUFETCA9fiBjaWExICsgY2lhMiArIGNpYTMgKyBjaWE0ICsgY2lhNSArIGNpYTYgKyBjaWE3CiIKCmdybTJQZXN0aW1hdGVzID0gY2ZhKG1vZGVsID0gZ3JtMlBzeW50YXgsIGRhdGEgPSBpYWRsRGF0YSwgb3JkZXJlZCA9IGMoImNpYTEiLCAiY2lhMiIsICJjaWEzIiwgImNpYTQiLCAiY2lhNSIsICJjaWE2IiwgImNpYTciKSwgc3RkLmx2ID0gVFJVRSwgcGFyYW1ldGVyaXphdGlvbj0idGhldGEiKQpzdW1tYXJ5KGdybTJQZXN0aW1hdGVzLCBmaXQubWVhc3VyZXMgPSBUUlVFLCByc3F1YXJlID0gVFJVRSwgc3RhbmRhcmRpemVkID0gVFJVRSkKCmBgYAoKIyMjIyBQYXJhbWV0ZXIgZXN0aW1hdGVzIHVuZGVyIFdMU01WIFRoZXRhIFBhcmFtZXRlcml6YXRpb24gKFByb2JpdCkgZm9yIHRoZSAyUEwgdmVyc2lvbiBvZiBwb2x5dG9tb3VzIHJlc3BvbnNlcwoKIyMjIyMgRmFjdG9yIGxvYWRpbmdzOgoKTGF0ZW50IFZhcmlhYmxlczoKICAgICAgICAgICAgICAgICAgIEVzdGltYXRlICBTdGQuRXJyICB6LXZhbHVlICBQKD58enwpICAgU3RkLmx2ICBTdGQuYWxsCiAgSUFETCA9fiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgY2lhMSAgICAgICAgICAgICAgMy40NTAgICAgMC4zMDEgICAxMS40NzAgICAgMC4wMDAgICAgMy40NTAgICAgMC45NjAKICAgIGNpYTIgICAgICAgICAgICAgIDMuNjIwICAgIDAuNTA3ICAgIDcuMTM5ICAgIDAuMDAwICAgIDMuNjIwICAgIDAuOTY0CiAgICBjaWEzICAgICAgICAgICAgICAzLjAyNiAgICAwLjI5MiAgIDEwLjM2MSAgICAwLjAwMCAgICAzLjAyNiAgICAwLjk0OQogICAgY2lhNCAgICAgICAgICAgICAgMy4zMTAgICAgMC4zMDAgICAxMS4wMzAgICAgMC4wMDAgICAgMy4zMTAgICAgMC45NTcKICAgIGNpYTUgICAgICAgICAgICAgIDIuMzYwICAgIDAuMTkwICAgMTIuNDEyICAgIDAuMDAwICAgIDIuMzYwICAgIDAuOTIxCiAgICBjaWE2ICAgICAgICAgICAgICAxLjk0MyAgICAwLjE4MiAgIDEwLjY4MCAgICAwLjAwMCAgICAxLjk0MyAgICAwLjg4OQogICAgY2lhNyAgICAgICAgICAgICAgMS4wNDQgICAgMC4xMzUgICAgNy43MjQgICAgMC4wMDAgICAgMS4wNDQgICAgMC43MjIKCgojIyMjIyBUaHJlc2hvbGRzOiAKCiAgICAgICAgICAgICAgICAgICBFc3RpbWF0ZSAgU3RkLkVyciAgei12YWx1ZSAgUCg+fHp8KSAgIFN0ZC5sdiAgU3RkLmFsbAogICAgY2lhMXx0MSAgICAgICAgICAtNC45NDYgICAgMC4zODUgIC0xMi44MzggICAgMC4wMDAgICAtNC45NDYgICAtMS4zNzcKICAgIGNpYTF8dDIgICAgICAgICAgLTMuNjM2ICAgIDAuMzI0ICAtMTEuMjMzICAgIDAuMDAwICAgLTMuNjM2ICAgLTEuMDEyCiAgICBjaWExfHQzICAgICAgICAgIC0wLjkwMCAgICAwLjIxOSAgIC00LjExMSAgICAwLjAwMCAgIC0wLjkwMCAgIC0wLjI1MQogICAgY2lhMnx0MSAgICAgICAgICAtNS41MDIgICAgMC42NTggICAtOC4zNTYgICAgMC4wMDAgICAtNS41MDIgICAtMS40NjUKICAgIGNpYTJ8dDIgICAgICAgICAgLTQuNzk3ICAgIDAuNjA1ICAgLTcuOTI4ICAgIDAuMDAwICAgLTQuNzk3ICAgLTEuMjc3CiAgICBjaWEyfHQzICAgICAgICAgIC0yLjk3MyAgICAwLjQ2MyAgIC02LjQyMSAgICAwLjAwMCAgIC0yLjk3MyAgIC0wLjc5MgogICAgY2lhM3x0MSAgICAgICAgICAtNC40MjYgICAgMC4zNjIgIC0xMi4yMjYgICAgMC4wMDAgICAtNC40MjYgICAtMS4zODkKICAgIGNpYTN8dDIgICAgICAgICAgLTMuNzAyICAgIDAuMzMxICAtMTEuMTc1ICAgIDAuMDAwICAgLTMuNzAyICAgLTEuMTYyCiAgICBjaWEzfHQzICAgICAgICAgIC0yLjA1MCAgICAwLjI2MiAgIC03LjgyMSAgICAwLjAwMCAgIC0yLjA1MCAgIC0wLjY0MwogICAgY2lhNHx0MSAgICAgICAgICAtNC40OTAgICAgMC4zNTUgIC0xMi42NDcgICAgMC4wMDAgICAtNC40OTAgICAtMS4yOTgKICAgIGNpYTR8dDIgICAgICAgICAgLTMuMTAwICAgIDAuMjgyICAtMTAuOTc3ICAgIDAuMDAwICAgLTMuMTAwICAgLTAuODk3CiAgICBjaWE0fHQzICAgICAgICAgIC0xLjA5OCAgICAwLjIyNSAgIC00Ljg4MSAgICAwLjAwMCAgIC0xLjA5OCAgIC0wLjMxNwogICAgY2lhNXx0MSAgICAgICAgICAtNC4wOTggICAgMC4yODEgIC0xNC42MDcgICAgMC4wMDAgICAtNC4wOTggICAtMS41OTkKICAgIGNpYTV8dDIgICAgICAgICAgLTIuMTk1ICAgIDAuMTkwICAtMTEuNTc4ICAgIDAuMDAwICAgLTIuMTk1ICAgLTAuODU2CiAgICBjaWE1fHQzICAgICAgICAgIC0wLjYxOCAgICAwLjE1MSAgIC00LjA4OSAgICAwLjAwMCAgIC0wLjYxOCAgIC0wLjI0MQogICAgY2lhNnx0MSAgICAgICAgICAtMy42MDUgICAgMC4yNTUgIC0xNC4xMjUgICAgMC4wMDAgICAtMy42MDUgICAtMS42NTAKICAgIGNpYTZ8dDIgICAgICAgICAgLTIuNTU4ICAgIDAuMjAzICAtMTIuNjI4ICAgIDAuMDAwICAgLTIuNTU4ICAgLTEuMTcxCiAgICBjaWE2fHQzICAgICAgICAgIC0xLjUzMSAgICAwLjE3MSAgIC04Ljk3NCAgICAwLjAwMCAgIC0xLjUzMSAgIC0wLjcwMQogICAgY2lhN3x0MSAgICAgICAgICAtMy4zMTEgICAgMC4yNjggIC0xMi4zNDUgICAgMC4wMDAgICAtMy4zMTEgICAtMi4yOTEKICAgIGNpYTd8dDIgICAgICAgICAgLTIuNjk1ICAgIDAuMTk5ICAtMTMuNTU2ICAgIDAuMDAwICAgLTIuNjk1ICAgLTEuODY0CiAgICBjaWE3fHQzICAgICAgICAgIC0xLjc4OCAgICAwLjE0NSAgLTEyLjMwNCAgICAwLjAwMCAgIC0xLjc4OCAgIC0xLjIzNwoKIyMjIyBDYWxjdWxhdGlvbnMKCkxvZ2l0ID0gMS43KnByb2JpdCwgb3IgUHJvYml0ID0gTG9naXQvMS43CgpJRkEgbW9kZWw6IFByb2JpdCh5PTEpID0g4oCTdGhyZXNob2xkICsgbG9hZGluZyhUaGV0YSkKClRocmVzaG9sZCA9IGV4cGVjdGVkIHByb2JpdCBvZiAoeT0wKSBmb3Igc29tZW9uZSB3aXRoIFRoZXRhPTAKCldoZW4gKi0xLCB0aHJlc2hvbGQgJFxyaWdodGFycm93JCBpbnRlcmNlcHQ6IGV4cGVjdGVkIHByb2JpdCBmb3IgKHk9MSkgaW5zdGVhZAoKTG9hZGluZyA9IHJlZ3Jlc3Npb24gb2YgaXRlbSBwcm9iaXQgb24gVGhldGEKCkZvciA0LWNhdGVnb3J5IHJlc3BvbnNlcywgdGhlIHN1Yi1tb2RlbHMgbG9vayBsaWtlIHRoaXM6ClByb2JpdCh5PSAwIHZzIDEyMykgPSAtdGhyZXNob2xkJDEgKyBsb2FkaW5nKFRoZXRhKQpQcm9iaXQoeT0gMDEgdnMgMjMpID0gLXRocmVzaG9sZCQyICsgbG9hZGluZyhUaGV0YSkKUHJvYml0IHk9IDAxMiB2cyAzKSA9IC10aHJlc2hvbGQkMyArIGxvYWRpbmcoVGhldGEpCgoKSVJUIG1vZGVsOiBQcm9iaXQoeSkgPSBhKHRoZXRhIOKAkyBkaWZmaWN1bHR5KQphID0gZGlzY3JpbWluYXRpb24gKHJlc2NhbGVkIHNsb3BlKSA9IGxvYWRpbmcKYiA9IGRpZmZpY3VsdHkgKGxvY2F0aW9uIG9uIGxhdGVudCBtZXRyaWMpID0gdGhyZXNob2xkL2xvYWRpbmcKCkZvciA0LWNhdGVnb3J5IHJlc3BvbnNlcywgdGhlIHN1Yi1tb2RlbHMgbG9vayBsaWtlIHRoaXM6CiQxIFByb2JpdCh5PSAwIHZzIDEyMykgPSBhKHRoZXRhIOKAkyBkaWZmaWN1bHR5JDEpCiQyIFByb2JpdCh5PSAwMSB2cyAyMykgPSBhKHRoZXRhIOKAkyBkaWZmaWN1bHR5JDIpCiQzIFByb2JpdCh5PSAwMTIgdnMgMykgPSBhKHRoZXRhIOKAkyBkaWZmaWN1bHR5JDMpCgojIyMjIE1vZGVsIEZpdApMT0NBTCBGSVQgVklBIFJBVyBSRVNJRFVBTCBDT1JSRUxBVElPTlMKTEVGVE9WRVIgUE9MWUNIT1JJQyBDT1JSRUxBVElPTiAoSE9XIEZBUiBPRkYgRlJPTSBEQVRBKQoKV2l0aCByYXcgcmVzaWR1YWxzLCB0aGUgc2NhbGUgaXMgdGhhdCBvZiBjb3JyZWxhdGlvbiAoZGlmZmVyZW50IGZyb20gbm9ybWFsaXplZCkKCmBgYHtyIGdybTJwZml0LCBpbmNsdWRlPVRSVUV9CnJlc2lkKG9iamVjdCA9IGdybTJQZXN0aW1hdGVzKQpgYGAKCiMjIyMgSXRlbSBQbG90cwoKYGBge3IgaXRlbXBsb3QsIGluY2x1ZGU9VFJVRX0KbGF2YWFuQ2F0SXRlbVBsb3QgPSBmdW5jdGlvbihsYXZPYmplY3QsIHZhcm5hbWUsIHNkcyA9IDMpewogIG91dHB1dCA9IGluc3BlY3Qob2JqZWN0ID0gbGF2T2JqZWN0LCB3aGF0ID0gImVzdCIpCiAgaWYgKCF2YXJuYW1lICVpbiUgcm93bmFtZXMob3V0cHV0JGxhbWJkYSkpIHN0b3AocGFzdGUodmFybmFtZSwgIm5vdCBmb3VuZCBpbiBsYXZhYW4gb2JqZWN0IikpCiAgaWYgKGRpbShvdXRwdXQkbGFtYmRhKVsyXT4xKSBzdG9wKCJwbG90cyBvbmx5IGdpdmVuIGZvciBvbmUgZmFjdG9yIG1vZGVscyIpCiAgCiAgaXRlbWxvYWRpbmcgPSBvdXRwdXQkbGFtYmRhW3doaWNoKHJvd25hbWVzKG91dHB1dCRsYW1iZGEpID09IHZhcm5hbWUpLDFdCiAgaXRlbXRocmVzaG9sZHMgPSBvdXRwdXQkdGF1W2dyZXAocGF0dGVybiA9IHZhcm5hbWUsIHggPSByb3duYW1lcyhvdXRwdXQkdGF1KSldCiAgCiAgZmFjdG9ybmFtZSA9IGNvbG5hbWVzKG91dHB1dCRsYW1iZGEpCiAgZmFjdG9ybWVhbiA9IG91dHB1dCRhbHBoYVt3aGljaChyb3duYW1lcyhvdXRwdXQkYWxwaGEpID09IGZhY3Rvcm5hbWUpXQogIGZhY3RvcnZhciA9IG91dHB1dCRwc2lbd2hpY2gocm93bmFtZXMob3V0cHV0JHBzaSkgPT0gZmFjdG9ybmFtZSldCiAgCiAgZmFjdG9ybWluID0gZmFjdG9ybWVhbiAtIDMqc3FydChmYWN0b3J2YXIpCiAgZmFjdG9ybWF4ID0gZmFjdG9ybWVhbiArIDMqc3FydChmYWN0b3J2YXIpCiAgCiAgZmFjdG9yWCA9IHNlcShmYWN0b3JtaW4sIGZhY3Rvcm1heCwgLjAxKQogIGl0ZW1sb2MgPSB3aGljaChsYXZPYmplY3RARGF0YUBvdiRuYW1lID09IHZhcm5hbWUpICAgICAgCiAgaXRlbWxldmVscyA9IHVubGlzdChzdHJzcGxpdCh4ID0gbGF2T2JqZWN0QERhdGFAb3YkbG5hbVtpdGVtbG9jXSwgc3BsaXQgPSAiXFx8IikpICAKICBpZiAobGVuZ3RoKGl0ZW10aHJlc2hvbGRzKT4xKXsKCiAgICAKICAgIHBsb3RkYXRhID0gTlVMTAogICAgcGxvdGRhdGEyID0gTlVMTAogICAgaXRlbVkgPSBOVUxMCiAgICBpdGVtWTIgPSBOVUxMCiAgICBpdGVtWCA9IE5VTEwKICAgIGl0ZW1UZXh0ID0gTlVMTAogICAgZm9yIChsZXZlbCBpbiAxOmxlbmd0aChpdGVtdGhyZXNob2xkcykpewogICAgICAKICAgICAgaXRlbVkgPSBwbm9ybShxID0gLTEqaXRlbXRocmVzaG9sZHNbbGV2ZWxdICsgaXRlbWxvYWRpbmcqZmFjdG9yWCkKICAgICAgaXRlbVkyID0gY2JpbmQoaXRlbVkyLCBwbm9ybShxID0gLTEqaXRlbXRocmVzaG9sZHNbbGV2ZWxdICsgaXRlbWxvYWRpbmcqZmFjdG9yWCkpCiAgICAgIGl0ZW1UZXh0ID0gcGFzdGUwKCJQKCIsIHZhcm5hbWUsICIgPiAiLCBpdGVtbGV2ZWxzW2xldmVsXSwgIikiKQogICAgICBpdGVtVGV4dDIgPSBwYXN0ZTAoIlAoIiwgdmFybmFtZSwgIiA9ICIsIGl0ZW1sZXZlbHNbbGV2ZWxdLCAiKSIpCiAgICAgIHBsb3RkYXRhID0gcmJpbmQocGxvdGRhdGEsIGRhdGEuZnJhbWUoZmFjdG9yID0gZmFjdG9yWCwgcHJvYiA9IGl0ZW1ZLCBwbG90ID0gaXRlbVRleHQpKQogICAgICAKICAgICAgaWYgKGxldmVsID09IDEpewogICAgICAgIHBsb3RkYXRhMiA9IGRhdGEuZnJhbWUoZmFjdG9yID0gZmFjdG9yWCwgcGxvdCA9IGl0ZW1UZXh0MiwgcHJvYiA9IG1hdHJpeCgxLCBucm93ID0gZGltKGl0ZW1ZMilbMV0sIG5jb2w9MSkgLSBpdGVtWTJbLGxldmVsXSkKICAgICAgfSBlbHNlIGlmIChsZXZlbCA9PSBsZW5ndGgoaXRlbXRocmVzaG9sZHMpKXsKICAgICAgICBwbG90ZGF0YTIgPSByYmluZChwbG90ZGF0YTIsIGRhdGEuZnJhbWUoZmFjdG9yID0gZmFjdG9yWCwgcGxvdCA9IGl0ZW1UZXh0MiwgcHJvYiA9IGl0ZW1ZMlssbGV2ZWwtMV0gLSBpdGVtWTJbLGxldmVsXSkpCiAgICAgICAgcGxvdGRhdGEyID0gcmJpbmQocGxvdGRhdGEyLCBkYXRhLmZyYW1lKGZhY3RvciA9IGZhY3RvclgsIHBsb3QgPSBwYXN0ZTAoIlAoIiwgdmFybmFtZSwgIiA9ICIsIGl0ZW1sZXZlbHNbbGV2ZWwrMV0sICIpIiksIHByb2IgPSBpdGVtWTJbLGxldmVsXSkpICAgICAgICAgICAgICAgICAgCiAgICAgIH0gZWxzZSB7CiAgICAgICAgcGxvdGRhdGEyID0gcmJpbmQocGxvdGRhdGEyLCBkYXRhLmZyYW1lKGZhY3RvciA9IGZhY3RvclgsIHBsb3QgPSBpdGVtVGV4dDIsIHByb2IgPSBpdGVtWTJbLGxldmVsLTFdIC0gaXRlbVkyWyxsZXZlbF0pKQogICAgICB9CiAgICAgIAogICAgfQogICAgCiAgICBuYW1lcyhwbG90ZGF0YSkgPSBjKGZhY3Rvcm5hbWUgLCAiUHJvYmFiaWxpdHkiLCAiQ3VtdWxhdGl2ZSIpCiAgICBnZ3Bsb3QoZGF0YSA9IHBsb3RkYXRhLCBhZXNfc3RyaW5nKHggPSBmYWN0b3JuYW1lLCB5ID0gIlByb2JhYmlsaXR5IiwgY29sb3VyID0gIkN1bXVsYXRpdmUiKSkgKyBnZW9tX2xpbmUoc2l6ZSA9IDIpCiAgICAKICAgIG5hbWVzKHBsb3RkYXRhMikgPSBjKGZhY3Rvcm5hbWUsICJSZXNwb25zZSIsICJQcm9iYWJpbGl0eSIpCiAgICBnZ3Bsb3QoZGF0YSA9IHBsb3RkYXRhMiwgYWVzX3N0cmluZyh4ID0gZmFjdG9ybmFtZSwgeSA9ICJQcm9iYWJpbGl0eSIsIGNvbG91ciA9ICJSZXNwb25zZSIpKSArIGdlb21fbGluZShzaXplID0gMikKICB9IGVsc2UgewogICAgCiAgICBpdGVtWSA9IHBub3JtKHEgPSAtMSppdGVtdGhyZXNob2xkc1sxXSArIGl0ZW1sb2FkaW5nKmZhY3RvclgpCiAgICBpdGVtVGV4dDIgPSBwYXN0ZTAoIlAoIiwgdmFybmFtZSwgIiA9ICIsIGl0ZW1sZXZlbHNbMV0sICIpIikKICAgIHBsb3RkYXRhID0gZGF0YS5mcmFtZShmYWN0b3IgPSBmYWN0b3JYLCBwcm9iID0gaXRlbVksIHBsb3QgPSBpdGVtVGV4dDIpCiAgICAKICAgIG5hbWVzKHBsb3RkYXRhKSA9IGMoZmFjdG9ybmFtZSAsICJQcm9iYWJpbGl0eSIsICJSZXNwb25zZSIpCiAgICBnZ3Bsb3QoZGF0YSA9IHBsb3RkYXRhLCBhZXNfc3RyaW5nKHggPSBmYWN0b3JuYW1lLCB5ID0gIlByb2JhYmlsaXR5IiwgY29sb3VyID0gIlJlc3BvbnNlIikpICsgZ2VvbV9saW5lKHNpemUgPSAyKQogICAgCiAgfQp9CgpsYXZhYW5DYXRJdGVtUGxvdChsYXZPYmplY3QgPSBncm0yUGVzdGltYXRlcywgdmFybmFtZSA9ICJjaWEyIiwgc2RzID0gMykKYGBgCgojIyMgR3JhZGVkIFJlc3BvbnNlIE1vZGVsICgxUEwtaXNoIHZlcnNpb24pIHVzaW5nIFdMU01WIHByb2JpdCBtb2RlbAoKV2UgY2FuIGFsc28gc2V0IHRoZSBpdGVtIGRpc2NyaW1pbmF0aW9ucyBlcXVhbCBmb3IgYSAxUEwtbGlrZSBtb2RlbDoKCmBgYHtyIGdybTFwLCBpbmNsdWRlPVRSVUV9CmdybTFQc3ludGF4ID0gIgpJQURMID1+IGEqY2lhMSArIGEqY2lhMiArIGEqY2lhMyArIGEqY2lhNCArIGEqY2lhNSArIGEqY2lhNiArIGEqY2lhNwoiCgpncm0xUGVzdGltYXRlcyA9IGNmYShtb2RlbCA9IGdybTFQc3ludGF4LCBkYXRhID0gaWFkbERhdGEsIG9yZGVyZWQgPSBjKCJjaWExIiwgImNpYTIiLCAiY2lhMyIsICJjaWE0IiwgImNpYTUiLCAiY2lhNiIsICJjaWE3IiksIHN0ZC5sdiA9IFRSVUUsIHBhcmFtZXRlcml6YXRpb249InRoZXRhIikKc3VtbWFyeShncm0xUGVzdGltYXRlcywgZml0Lm1lYXN1cmVzID0gVFJVRSwgcnNxdWFyZSA9IFRSVUUsIHN0YW5kYXJkaXplZCA9IFRSVUUpCgpgYGAKClNpbWlsYXJseSwgd2UgY2FuIHVzZSB0aGUgYGFub3ZhKClgIGZ1bmN0aW9uIHRvIGNvbXBhcmUgbW9kZWwgZml0OgoKYGBge3IgY29tcGFyZSwgaW5jbHVkZT1UUlVFfQphbm92YShncm0xUGVzdGltYXRlcywgZ3JtMlBlc3RpbWF0ZXMpCmBgYA==