🔙 Home

Introduction

When you’ve run your statistical models and gathered all the numbers, how do you report them in-line in your text? In this tutorial, I will show you which numbers are most commonly reported in academic prose (e.g., in articles), and what the conventions are for formatting them in-line. This is certainly not the only way to report your statistics, but it is how I have done so and what I most commonly have seen in the literature. Please feel free to send me feedback or comments if you think there is a better way to report any of these tests!

library(lme4,ordinal)
# Load in three data sets to try out
# 1) dataBin = binomial data from a simulated forced-choice task
# 2) dataOrd = ordinal rating data from a simulated Likert scale task
# 3) dataCon = continuous numeric data from a simulated reaction time task

dataBin <- read.csv("data/binomial-data.csv",header=TRUE, stringsAsFactors = TRUE)
head(dataBin)

The dataset I’m using here has a binomial dependent variable selection (which is coded as hits with 1s and misses with 0s in the column called selectCode`). This data frame was designed to mimic a forced-choice task, such as selecting which of two sentences sounds more natural. There are two levels of the primary independent variable:

levels(dataBin$condition)
[1] "Baseline"  "Treatment"

In this simulated data set, the same task was carried out in three different experiments, which are labled as below:

levels(dataBin$experiment)
[1] "first"  "second" "third" 

Finally, let’s take a look at what our data look like. These graphs displays the selection of Options 1 and 2 by condition and experiment, and their interaction. This is not the only way to visualise this data, but it will be particularly helpful in the interpretation of interactions later on.

library(ggplot2)
ggplot(dataBin, aes(x=condition)) + geom_bar(aes(fill=selection),position="stack") + ggtitle("Selection across Condition only")

ggplot(dataBin, aes(x=experiment)) + geom_bar(aes(fill=selection),position="stack") + ggtitle("Selection across Experiment only")

ggplot(dataBin, aes(x=condition)) + geom_bar(aes(fill=selection),position="stack") + facet_wrap(~experiment) + ggtitle("Selection across Condition and Experiment")

Linear mixed effects models

Typically, I report my statistical calculations for comparison of mixed effects models, which requires both the summary of the maximal model and the results of the model comparison (next section, below). However, if you are going to report just the results of the mixed effects model, here are templates you might use.

Interpreting the estimate and standard error of binomial data can be tricky, but reporting it clearly is straightforward and very similar to reporting LMEMs from other types of data.

summary(lmer.bin)
Generalized linear mixed model fit by maximum likelihood (Laplace Approximation) ['glmerMod']
 Family: binomial  ( logit )
Formula: selectCode ~ condition + (1 | subject) + (1 | item)
   Data: dataBin

     AIC      BIC   logLik deviance df.resid 
  1947.8   1968.9   -969.9   1939.8     1436 

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-1.2987 -0.8944  0.7700  0.7700  1.1180 

Random effects:
 Groups  Name        Variance Std.Dev.
 item    (Intercept) 0        0       
 subject (Intercept) 0        0       
Number of obs: 1440, groups:  item, 24; subject, 20

Fixed effects:
                   Estimate Std. Error z value Pr(>|z|)    
(Intercept)         -0.2231     0.0750  -2.975  0.00293 ** 
conditionTreatment   0.7458     0.1076   6.934 4.08e-12 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr)
cndtnTrtmnt -0.697
optimizer (Nelder_Mead) convergence code: 0 (OK)
boundary (singular) fit: see ?isSingular

Template:

We find a main effect of Condition, with hits more likely to occur in the Treatment condition than in the Baseline condition (β=Estimate, SE=Std. Error, z(Number of obs.)=z value, p=Pr(>|z|)).

Example:

We find a main effect of Condition, with hits more likely to occur in the Treatment condition than in the Baseline condition (β=0.74, SE=0.11, z(1440)=6.93, p<0.0001).

The values reported are taken from the line containg the level of Condition that is being compared to our baseline (conveniently called Baseline in this example). This gets more complicated when there are more than two levels being compared. This is one reason why model comparison (below) may be a better choice.

LMER model comparison

Barr et al. (2013) and Bates et al. (2015) set out arguments for structuring and analysing your data using either maximally complex or parsimonious random effects structures. They further discuss how to analyse such models. By doing model comparison, what you are reporting is the contribution of a component of the model to the overall model fit. This is a slightly more conservative method of evaluating the significance of a given effect, which means there is a lower chance of false positives.

I personally think the most compelling reason to use this method for evaluating significance is that it allows you to easily report main effects when a condition has more than two levels.

To give a better idea of how model comparison might work for more complex experimental designs, this example will check for a main effect of Condition (Baseline vs Treatment) and of Experiment (First vs Second vs Third), as well as checking for an interaction of these two factors.

#
# description of the maximal model (used for reporting estimates and standard errors)
summary(lmer.bin.max)
Generalized linear mixed model fit by maximum likelihood (Laplace Approximation) ['glmerMod']
 Family: binomial  ( logit )
Formula: selectCode ~ condition * experiment + (1 | subject) + (1 | item)
   Data: dataBin

     AIC      BIC   logLik deviance df.resid 
  1662.1   1704.3   -823.0   1646.1     1432 

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-3.1688 -0.7435  0.3197  0.8767  1.9048 

Random effects:
 Groups  Name        Variance  Std.Dev. 
 item    (Intercept) 1.483e-02 1.218e-01
 subject (Intercept) 6.748e-10 2.598e-05
Number of obs: 1440, groups:  item, 24; subject, 20

Fixed effects:
                                    Estimate Std. Error z value Pr(>|z|)    
(Intercept)                           0.1677     0.1345   1.247   0.2124    
conditionTreatment                    0.9569     0.2046   4.676 2.93e-06 ***
experimentsecond                     -0.4030     0.1839  -2.192   0.0284 *  
experimentthird                      -0.7891     0.1878  -4.202 2.64e-05 ***
conditionTreatment:experimentsecond   1.5285     0.3233   4.728 2.27e-06 ***
conditionTreatment:experimentthird   -1.5761     0.2860  -5.511 3.56e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
                    (Intr) cndtnT exprmnts exprmntt cndtnTrtmnt:xprmnts
cndtnTrtmnt         -0.657                                             
exprmntscnd         -0.681  0.447                                      
exprmntthrd         -0.667  0.438  0.488                               
cndtnTrtmnt:xprmnts  0.388 -0.595 -0.569   -0.278                      
cndtnTrtmnt:xprmntt  0.438 -0.674 -0.320   -0.655    0.425             
optimizer (Nelder_Mead) convergence code: 0 (OK)
boundary (singular) fit: see ?isSingular

Because Experiment is a factor with three levels, we can see the estimates for Second and Third as they compare to the baseline, which is First because it is alphabetically first. It is difficult to interpret the interactions in this summary because it’s not necessarily clear what the intercept refers to because it is more abstract than in a 2 × 2 design.

Interaction effect

We can compare the maximal model directly to the depleted model with the interaction term removed. Notice that degrees of freedom = 2, since there are two levels in the Experiment factor, which complicates the model.

# evaluate the contribution of the interaction to the overall fit
anova(lmer.bin.max,lmer.bin.int)
Data: dataBin
Models:
lmer.bin.int: selectCode ~ condition + experiment + (1 | subject) + (1 | item)
lmer.bin.max: selectCode ~ condition * experiment + (1 | subject) + (1 | item)
             npar    AIC    BIC  logLik deviance  Chisq Df Pr(>Chisq)    
lmer.bin.int    6 1761.2 1792.8 -874.57   1749.2                         
lmer.bin.max    8 1662.1 1704.3 -823.04   1646.1 103.06  2  < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Template:

The interaction between Condition and Experiment was found to be significant, with both the Second and Third experiments differing from the First experiment (βSecond=Estimate, SE=Std. Error, βThird=Estimate, SE=Std. Error, χ²(Df)=Chisq, p=Pr(>Chisq)).

Example:

The interaction between Condition and Experiment was found to be significant, with both the Second and Third experiments differing from the First experiment (βSecond=1.53, SE=0.32, βThird=-1.58, SE=0.29, χ²(2)=103.1, p<0.0001).

Main effect of Factor 1 (Condition)

# evaluate the contribution of the main effect of condition to the overall fit
anova(lmer.bin.int,lmer.bin.con)
Data: dataBin
Models:
lmer.bin.con: selectCode ~ experiment + (1 | subject) + (1 | item)
lmer.bin.int: selectCode ~ condition + experiment + (1 | subject) + (1 | item)
             npar    AIC    BIC  logLik deviance  Chisq Df Pr(>Chisq)    
lmer.bin.con    5 1786.5 1812.8 -888.23   1776.5                         
lmer.bin.int    6 1761.2 1792.8 -874.57   1749.2 27.305  1  1.737e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Notice that we are comparing the depleted model with Condition removed to the depleted model with Interaction removed and not to the maximal model. This is because a comparison involving the maximal model will include both the contribution of the interaction and the main effect if we compare it directly.

Template:

A main effect of Condition obtains, with the Treatment condition more likely to result in a hit than the Baseline condition (β=Estimate, SE=Std. Error, χ²(Df)=Chisq, p=Pr(>Chisq)).

Example:

A main effect of Condition obtains, with the Treatment condition more likely to result in a hit than the Baseline condition (β=0.96, SE=0.20, χ²(1)=27.3, p<0.0001).

Main effect of Factor 2 (Experiment)

Finally, we can evaluate the contribution of the main effect of Experiment to the overall fit of the model.

# evaluate the contribution of the main effect of condition to the overall fit
anova(lmer.bin.int,lmer.bin.exp)
Data: dataBin
Models:
lmer.bin.exp: selectCode ~ condition + (1 | subject) + (1 | item)
lmer.bin.int: selectCode ~ condition + experiment + (1 | subject) + (1 | item)
             npar    AIC    BIC  logLik deviance  Chisq Df Pr(>Chisq)    
lmer.bin.exp    4 1947.8 1968.9 -969.90   1939.8                         
lmer.bin.int    6 1761.2 1792.8 -874.57   1749.2 190.66  2  < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

As before, we must compare this model against the model with the interaction term removed rather than the maximal model. The degrees of freedom again are 2 because of the three levels of the factor Experiment increasing the complexity of the comparison.

Template:

We observe a main effect of Experiment (χ²(Df)=Chisq, p=Pr(>Chisq)).

Example:

We observe a main effect of Experiment (χ²(2)=190.7, p<0.0001).

If we want to report in more detail about how the three different experiments relate to each other, we must do one more comparison. This is because the baseline for these summaries has been set at the alphabetically first level (conveniently, First). However, this means we have not compared the Second experiment to the Third experiment yet. To do so, we can run another model comparison, but then we will be “double dipping” into our data (i.e., running the same test on the same sample more than once). This inflates the chance of a false positive, so instead of setting the significance level (alpha) at 0.05, we divide that by the number of tests we’re running (two), to get α=0.025. This means a p-value must be below 0.025 to be considered significant. You can either specify the new alpha level and report the raw p-value or adjust the p-value and mention that it’s correct for whatever number of evaluations you’ve done.

Pairwise comparison of three levels within Factor 2

#
# summary of our releveled reference model
summary(lmer.bin.max2)
Generalized linear mixed model fit by maximum likelihood (Laplace Approximation) ['glmerMod']
 Family: binomial  ( logit )
Formula: selectCode ~ condition * expRelvl + (1 | subject) + (1 | item)
   Data: dataBin

     AIC      BIC   logLik deviance df.resid 
  1662.1   1704.3   -823.0   1646.1     1432 

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-3.1689 -0.7435  0.3197  0.8767  1.9048 

Random effects:
 Groups  Name        Variance Std.Dev.
 item    (Intercept) 0.01484  0.1218  
 subject (Intercept) 0.00000  0.0000  
Number of obs: 1440, groups:  item, 24; subject, 20

Fixed effects:
                                 Estimate Std. Error z value Pr(>|z|)    
(Intercept)                       -0.2353     0.1349  -1.744   0.0811 .  
conditionTreatment                 2.4854     0.2602   9.552  < 2e-16 ***
expRelvlfirst                      0.4030     0.1839   2.191   0.0284 *  
expRelvlthird                     -0.3861     0.1880  -2.054   0.0400 *  
conditionTreatment:expRelvlfirst  -1.5285     0.3233  -4.728 2.27e-06 ***
conditionTreatment:expRelvlthird  -3.1046     0.3281  -9.463  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
                    (Intr) cndtnT expRlvlf expRlvlt cndtnTrtmnt:xpRlvlf
cndtnTrtmnt         -0.519                                             
expRlvlfrst         -0.684  0.355                                      
expRlvlthrd         -0.669  0.346  0.490                               
cndtnTrtmnt:xpRlvlf  0.389 -0.775 -0.569   -0.279                      
cndtnTrtmnt:xpRlvlt  0.384 -0.764 -0.282   -0.572    0.615             
optimizer (Nelder_Mead) convergence code: 0 (OK)
boundary (singular) fit: see ?isSingular

First off, we can see that p-values for the releveled factor are much smaller than before. This suggests that while we already knew the First and Second experiment had closer estimates than the First and Third did, we now see that Second and Third may not actually significantly differ. This is likely part of the reason we find a significant interaction in our overall model comparison. To report these pair-wise comparisons, we go back to the description

Template:

Using a Bonferroni correction, we compensate for the second evaluation of the factor Experiment. This analysis suggests that the First and Third experiments significantly differ (β=Estimate, SE=Std. Error, z(Number of obs.)=z value, p=Pr(>|z|)*2), but after correction, there is no significant difference between either the First and Second experiments (β=Estimate, SE=Std. Error, z(Number of obs.)=z value, p=Pr(>|z|)*2) nor the Second and Third experiments (β=Estimate, SE=Std. Error, z(Number of obs.)=z value, p=Pr(>|z|)*2).

Example:

Using a Bonferroni correction, we compensate for the second evaluation of the factor Experiment. This analysis suggests that the First and Third experiments significantly differ (β=-0.79, SE=0.19, z(1440)=-4.20, p<0.0001), but after correction, there is no significant difference between either the First and Second experiments (β=-0.40, SE=0.19, z(1440)=-2.19, p=0.056) nor the Second and Third experiments (β=-0.39, SE=0.19, z(1140)=-2.05, p=0.08).

NB: In this example, I have multiplied the p-values by 2 to report the Bonferroni-corrected levels. You may also specify that a different alpha was used, but in my experience, fewer people are aware of how this works and thus it is simpler to correct the value rather than report a different alpha. Just be clear in your text what you’ve done.

anova(lmer.bin.int2,lmer.bin.exp2)
Data: dataBin
Models:
lmer.bin.exp2: selectCode ~ condition + (1 | subject) + (1 | item)
lmer.bin.int2: selectCode ~ condition + expRelvl + (1 | subject) + (1 | item)
              npar    AIC    BIC  logLik deviance  Chisq Df Pr(>Chisq)    
lmer.bin.exp2    4 1947.8 1968.9 -969.90   1939.8                         
lmer.bin.int2    6 1761.2 1792.8 -874.57   1749.2 190.66  2  < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Notice how this model comparison is identical to the one above. This is because they’re comparing the exact same thing. They should absolutely be identical. If they are not, it means you have altered your dataset in some way.

1-sample proportions tests

This test is used to test whether the proportion of hits in your binomial data (coded as 1s, with misses as 0s) differs from a baseline level. The benefit of this test is that you can set your own level against which you are testing your data.

If you want to see if you data differ from chance and chance is at 50%, you can specify p=0.5 in the prop.test() code. (You can read more about conducting and graphing in my 1-sample proportions tutorial, which can be forked on Kaggle.)

hits <- sum(dataBin$selectCode[dataBin$condition=="Treatment"])
len  <- length(dataBin$selectCode[dataBin$condition=="Treatment"])
prop.test(hits,len,p=0.5)

    1-sample proportions test with continuity correction

data:  hits out of len, null probability 0.5
X-squared = 46.513, df = 1, p-value = 9.104e-12
alternative hypothesis: true p is not equal to 0.5
95 percent confidence interval:
 0.5911739 0.6629988
sample estimates:
        p 
0.6277778 

With this output, we can report the estimate (β), χ² value, the degrees of freedom (df), the p-value, and the bounds of the 95% confidence interval (95%CI).

Template:

The Treatment condition significantly differs from the Baseline condition, with Option 1 selected more frequently than chance (β=sample estimate, χ²(df)=X-squared, p=p-value; 95%CI: CI lower boundCI upper bound).

Example:

The Treatment condition significantly differs from the Baseline condition, with Option 1 selected more frequently than chance (β=62.78%, χ²(1)=46.5, p<0.0001; 95%CI: 59.1%–66.30%).

If you have a few 1-sample proportions tests, the results can be easily reported in a table format as well.

Condition Estimate χ²(df=1) p-value 95% Confidence Interval
Baseline 0.4444 8.7 0.003 0.408–0.481
Treatment 0.6278 46.5 0.0001 0.591–0.663
LS0tCnRpdGxlOiAiUmVwb3J0aW5nIHN0YXRpc3RpY3MgaW4gcHJvc2UiCmF1dGhvcjogIkxhdXJlbiBNIEFja2VybWFuIgpkYXRlOiAiTGFzdCB1cGRhdGVkOiAwMyBNYXkgMjAxOCIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDIKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgaW5jbHVkZXM6IAogICAgICBpbl9oZWFkZXI6IGdvb2dsZV9hbmFseXRpY3MuaHRtbAotLS0KW/CflJkgSG9tZV0oaHR0cHM6Ly92ZXJiaW5nbm91bnMuZ2l0aHViLmlvL25vdGVib29rcy8pCgojIEludHJvZHVjdGlvbgoKV2hlbiB5b3UndmUgcnVuIHlvdXIgc3RhdGlzdGljYWwgbW9kZWxzIGFuZCBnYXRoZXJlZCBhbGwgdGhlIG51bWJlcnMsIGhvdyBkbyB5b3UgcmVwb3J0IHRoZW0gaW4tbGluZSBpbiB5b3VyIHRleHQ/IEluIHRoaXMgdHV0b3JpYWwsIEkgd2lsbCBzaG93IHlvdSB3aGljaCBudW1iZXJzIGFyZSBtb3N0IGNvbW1vbmx5IHJlcG9ydGVkIGluIGFjYWRlbWljIHByb3NlIChlLmcuLCBpbiBhcnRpY2xlcyksIGFuZCB3aGF0IHRoZSBjb252ZW50aW9ucyBhcmUgZm9yIGZvcm1hdHRpbmcgdGhlbSBpbi1saW5lLiBUaGlzIGlzIGNlcnRhaW5seSBub3QgdGhlIG9ubHkgd2F5IHRvIHJlcG9ydCB5b3VyIHN0YXRpc3RpY3MsIGJ1dCBpdCBpcyBob3cgSSBoYXZlIGRvbmUgc28gYW5kIHdoYXQgSSBtb3N0IGNvbW1vbmx5IGhhdmUgc2VlbiBpbiB0aGUgbGl0ZXJhdHVyZS4gUGxlYXNlIGZlZWwgZnJlZSB0byBzZW5kIG1lIGZlZWRiYWNrIG9yIGNvbW1lbnRzIGlmIHlvdSB0aGluayB0aGVyZSBpcyBhIGJldHRlciB3YXkgdG8gcmVwb3J0IGFueSBvZiB0aGVzZSB0ZXN0cyEKCmBgYHtyfQpsaWJyYXJ5KGxtZTQsb3JkaW5hbCkKIyBMb2FkIGluIHRocmVlIGRhdGEgc2V0cyB0byB0cnkgb3V0CiMgMSkgZGF0YUJpbiA9IGJpbm9taWFsIGRhdGEgZnJvbSBhIHNpbXVsYXRlZCBmb3JjZWQtY2hvaWNlIHRhc2sKIyAyKSBkYXRhT3JkID0gb3JkaW5hbCByYXRpbmcgZGF0YSBmcm9tIGEgc2ltdWxhdGVkIExpa2VydCBzY2FsZSB0YXNrCiMgMykgZGF0YUNvbiA9IGNvbnRpbnVvdXMgbnVtZXJpYyBkYXRhIGZyb20gYSBzaW11bGF0ZWQgcmVhY3Rpb24gdGltZSB0YXNrCgpkYXRhQmluIDwtIHJlYWQuY3N2KCJkYXRhL2Jpbm9taWFsLWRhdGEuY3N2IixoZWFkZXI9VFJVRSwgc3RyaW5nc0FzRmFjdG9ycyA9IFRSVUUpCmhlYWQoZGF0YUJpbikKYGBgCgpUaGUgZGF0YXNldCBJJ20gdXNpbmcgaGVyZSBoYXMgYSBiaW5vbWlhbCBkZXBlbmRlbnQgdmFyaWFibGUgYHNlbGVjdGlvbmAgKHdoaWNoIGlzIGNvZGVkIGFzIGhpdHMgd2l0aCBgMWBzIGFuZCBtaXNzZXMgd2l0aCBgMGBzIGluIHRoZSBjb2x1bW4gY2FsbGVkIHNlbGVjdENvZGVgKS4gVGhpcyBkYXRhIGZyYW1lIHdhcyBkZXNpZ25lZCB0byBtaW1pYyBhIGZvcmNlZC1jaG9pY2UgdGFzaywgc3VjaCBhcyBzZWxlY3Rpbmcgd2hpY2ggb2YgdHdvIHNlbnRlbmNlcyBzb3VuZHMgbW9yZSBuYXR1cmFsLiBUaGVyZSBhcmUgdHdvIGxldmVscyBvZiB0aGUgcHJpbWFyeSBpbmRlcGVuZGVudCB2YXJpYWJsZToKCmBgYHtyfQpsZXZlbHMoZGF0YUJpbiRjb25kaXRpb24pCmBgYAoKSW4gdGhpcyBzaW11bGF0ZWQgZGF0YSBzZXQsIHRoZSBzYW1lIHRhc2sgd2FzIGNhcnJpZWQgb3V0IGluIHRocmVlIGRpZmZlcmVudCBleHBlcmltZW50cywgd2hpY2ggYXJlIGxhYmxlZCBhcyBiZWxvdzoKCmBgYHtyfQpsZXZlbHMoZGF0YUJpbiRleHBlcmltZW50KQpgYGAKCkZpbmFsbHksIGxldCdzIHRha2UgYSBsb29rIGF0IHdoYXQgb3VyIGRhdGEgbG9vayBsaWtlLiBUaGVzZSBncmFwaHMgZGlzcGxheXMgdGhlIHNlbGVjdGlvbiBvZiBPcHRpb25zIDEgYW5kIDIgYnkgY29uZGl0aW9uIGFuZCBleHBlcmltZW50LCBhbmQgdGhlaXIgaW50ZXJhY3Rpb24uIFRoaXMgaXMgbm90IHRoZSBvbmx5IHdheSB0byB2aXN1YWxpc2UgdGhpcyBkYXRhLCBidXQgaXQgd2lsbCBiZSBwYXJ0aWN1bGFybHkgaGVscGZ1bCBpbiB0aGUgaW50ZXJwcmV0YXRpb24gb2YgaW50ZXJhY3Rpb25zIGxhdGVyIG9uLgoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKZ2dwbG90KGRhdGFCaW4sIGFlcyh4PWNvbmRpdGlvbikpICsgZ2VvbV9iYXIoYWVzKGZpbGw9c2VsZWN0aW9uKSxwb3NpdGlvbj0ic3RhY2siKSArIGdndGl0bGUoIlNlbGVjdGlvbiBhY3Jvc3MgQ29uZGl0aW9uIG9ubHkiKQpnZ3Bsb3QoZGF0YUJpbiwgYWVzKHg9ZXhwZXJpbWVudCkpICsgZ2VvbV9iYXIoYWVzKGZpbGw9c2VsZWN0aW9uKSxwb3NpdGlvbj0ic3RhY2siKSArIGdndGl0bGUoIlNlbGVjdGlvbiBhY3Jvc3MgRXhwZXJpbWVudCBvbmx5IikKZ2dwbG90KGRhdGFCaW4sIGFlcyh4PWNvbmRpdGlvbikpICsgZ2VvbV9iYXIoYWVzKGZpbGw9c2VsZWN0aW9uKSxwb3NpdGlvbj0ic3RhY2siKSArIGZhY2V0X3dyYXAofmV4cGVyaW1lbnQpICsgZ2d0aXRsZSgiU2VsZWN0aW9uIGFjcm9zcyBDb25kaXRpb24gYW5kIEV4cGVyaW1lbnQiKQpgYGAKCiMgTGluZWFyIG1peGVkIGVmZmVjdHMgbW9kZWxzCgpUeXBpY2FsbHksIEkgcmVwb3J0IG15IHN0YXRpc3RpY2FsIGNhbGN1bGF0aW9ucyBmb3IgY29tcGFyaXNvbiBvZiBtaXhlZCBlZmZlY3RzIG1vZGVscywgd2hpY2ggcmVxdWlyZXMgYm90aCB0aGUgc3VtbWFyeSBvZiB0aGUgbWF4aW1hbCBtb2RlbCBhbmQgdGhlIHJlc3VsdHMgb2YgdGhlIG1vZGVsIGNvbXBhcmlzb24gKG5leHQgc2VjdGlvbiwgYmVsb3cpLiBIb3dldmVyLCBpZiB5b3UgYXJlIGdvaW5nIHRvIHJlcG9ydCBqdXN0IHRoZSByZXN1bHRzIG9mIHRoZSBtaXhlZCBlZmZlY3RzIG1vZGVsLCBoZXJlIGFyZSB0ZW1wbGF0ZXMgeW91IG1pZ2h0IHVzZS4KCkludGVycHJldGluZyB0aGUgZXN0aW1hdGUgYW5kIHN0YW5kYXJkIGVycm9yIG9mIGJpbm9taWFsIGRhdGEgY2FuIGJlIHRyaWNreSwgYnV0IHJlcG9ydGluZyBpdCBjbGVhcmx5IGlzIHN0cmFpZ2h0Zm9yd2FyZCBhbmQgdmVyeSBzaW1pbGFyIHRvIHJlcG9ydGluZyBMTUVNcyBmcm9tIG90aGVyIHR5cGVzIG9mIGRhdGEuCgpgYGB7cn0KbG1lci5iaW4gPC0gZ2xtZXIoc2VsZWN0Q29kZSB+IGNvbmRpdGlvbiArICgxfHN1YmplY3QpICsgKDF8aXRlbSksIGRhdGE9ZGF0YUJpbiwgZmFtaWx5PSJiaW5vbWlhbCIpCnN1bW1hcnkobG1lci5iaW4pCmBgYAoKIyMjIyBUZW1wbGF0ZToKCj4gV2UgZmluZCBhIG1haW4gZWZmZWN0IG9mICpDb25kaXRpb24qLCB3aXRoIGhpdHMgbW9yZSBsaWtlbHkgdG8gb2NjdXIgaW4gdGhlICpUcmVhdG1lbnQqIGNvbmRpdGlvbiB0aGFuIGluIHRoZSAqQmFzZWxpbmUqIGNvbmRpdGlvbiAozrI9YEVzdGltYXRlYCwgU0U9YFN0ZC4gRXJyb3JgLCB6KGBOdW1iZXIgb2Ygb2JzLmApPWB6IHZhbHVlYCwgcD1gUHIoPnx6fClgKS4KCiMjIyMgRXhhbXBsZToKCj4gV2UgZmluZCBhIG1haW4gZWZmZWN0IG9mICpDb25kaXRpb24qLCB3aXRoIGhpdHMgbW9yZSBsaWtlbHkgdG8gb2NjdXIgaW4gdGhlICpUcmVhdG1lbnQqIGNvbmRpdGlvbiB0aGFuIGluIHRoZSAqQmFzZWxpbmUqIGNvbmRpdGlvbiAozrI9MC43NCwgU0U9MC4xMSwgeigxNDQwKT02LjkzLCBwPDAuMDAwMSkuCgpUaGUgdmFsdWVzIHJlcG9ydGVkIGFyZSB0YWtlbiBmcm9tIHRoZSBsaW5lIGNvbnRhaW5nIHRoZSBsZXZlbCBvZiBDb25kaXRpb24gdGhhdCBpcyBiZWluZyBjb21wYXJlZCB0byBvdXIgYmFzZWxpbmUgKGNvbnZlbmllbnRseSBjYWxsZWQgKkJhc2VsaW5lKiBpbiB0aGlzIGV4YW1wbGUpLiBUaGlzIGdldHMgbW9yZSBjb21wbGljYXRlZCB3aGVuIHRoZXJlIGFyZSBtb3JlIHRoYW4gdHdvIGxldmVscyBiZWluZyBjb21wYXJlZC4gVGhpcyBpcyBvbmUgcmVhc29uIHdoeSAqKm1vZGVsIGNvbXBhcmlzb24qKiAoYmVsb3cpIG1heSBiZSBhIGJldHRlciBjaG9pY2UuCgojIExNRVIgbW9kZWwgY29tcGFyaXNvbgoKQmFyciBldCBhbC4gKDIwMTMpIGFuZCBCYXRlcyBldCBhbC4gKDIwMTUpIHNldCBvdXQgYXJndW1lbnRzIGZvciBzdHJ1Y3R1cmluZyBhbmQgYW5hbHlzaW5nIHlvdXIgZGF0YSB1c2luZyBlaXRoZXIgbWF4aW1hbGx5IGNvbXBsZXggb3IgcGFyc2ltb25pb3VzIHJhbmRvbSBlZmZlY3RzIHN0cnVjdHVyZXMuIFRoZXkgZnVydGhlciBkaXNjdXNzIGhvdyB0byBhbmFseXNlIHN1Y2ggbW9kZWxzLiBCeSBkb2luZyBtb2RlbCBjb21wYXJpc29uLCB3aGF0IHlvdSBhcmUgcmVwb3J0aW5nIGlzIHRoZSBjb250cmlidXRpb24gb2YgYSBjb21wb25lbnQgb2YgdGhlIG1vZGVsIHRvIHRoZSBvdmVyYWxsIG1vZGVsIGZpdC4gVGhpcyBpcyBhIHNsaWdodGx5IG1vcmUgY29uc2VydmF0aXZlIG1ldGhvZCBvZiBldmFsdWF0aW5nIHRoZSBzaWduaWZpY2FuY2Ugb2YgYSBnaXZlbiBlZmZlY3QsIHdoaWNoIG1lYW5zIHRoZXJlIGlzIGEgbG93ZXIgY2hhbmNlIG9mIGZhbHNlIHBvc2l0aXZlcy4gCgpJIHBlcnNvbmFsbHkgdGhpbmsgdGhlIG1vc3QgY29tcGVsbGluZyByZWFzb24gdG8gdXNlIHRoaXMgbWV0aG9kIGZvciBldmFsdWF0aW5nIHNpZ25pZmljYW5jZSBpcyB0aGF0IGl0IGFsbG93cyB5b3UgdG8gZWFzaWx5IHJlcG9ydCBtYWluIGVmZmVjdHMgd2hlbiBhIGNvbmRpdGlvbiBoYXMgbW9yZSB0aGFuIHR3byBsZXZlbHMuCgpUbyBnaXZlIGEgYmV0dGVyIGlkZWEgb2YgaG93IG1vZGVsIGNvbXBhcmlzb24gbWlnaHQgd29yayBmb3IgbW9yZSBjb21wbGV4IGV4cGVyaW1lbnRhbCBkZXNpZ25zLCB0aGlzIGV4YW1wbGUgd2lsbCBjaGVjayBmb3IgYSBtYWluIGVmZmVjdCBvZiAqQ29uZGl0aW9uKiAoQmFzZWxpbmUgdnMgVHJlYXRtZW50KSBhbmQgb2YgKkV4cGVyaW1lbnQqIChGaXJzdCB2cyBTZWNvbmQgdnMgVGhpcmQpLCBhcyB3ZWxsIGFzIGNoZWNraW5nIGZvciBhbiBpbnRlcmFjdGlvbiBvZiB0aGVzZSB0d28gZmFjdG9ycy4KCmBgYHtyfQojIG1heGltYWwgbW9kZWwKbG1lci5iaW4ubWF4IDwtIGdsbWVyKHNlbGVjdENvZGUgfiBjb25kaXRpb24qZXhwZXJpbWVudCArICgxfHN1YmplY3QpICsgKDF8aXRlbSksIGRhdGE9ZGF0YUJpbiwgZmFtaWx5PSJiaW5vbWlhbCIpCiMKIyBtb2RlbCB3aXRoIGNvbnRyaWJ1dGlvbiBvZiB0aGUgaW50ZXJhY3Rpb24gcmVtb3ZlZApsbWVyLmJpbi5pbnQgPC0gZ2xtZXIoc2VsZWN0Q29kZSB+IGNvbmRpdGlvbitleHBlcmltZW50ICsgKDF8c3ViamVjdCkgKyAoMXxpdGVtKSwgZGF0YT1kYXRhQmluLCBmYW1pbHk9ImJpbm9taWFsIikKIwojIG1vZGVsIHdpdGggY29udHJpYnV0aW9uIG9mIGNvbmRpdGlvbiByZW1vdmVkCmxtZXIuYmluLmNvbiA8LSBnbG1lcihzZWxlY3RDb2RlIH4gZXhwZXJpbWVudCArICgxfHN1YmplY3QpICsgKDF8aXRlbSksIGRhdGE9ZGF0YUJpbiwgZmFtaWx5PSJiaW5vbWlhbCIpCiMKI21vZGVsIHdpdGggY29udHJpYnV0aW9uIG9mIGV4cGVyaW1lbnQgcmVtb3ZlZApsbWVyLmJpbi5leHAgPC0gZ2xtZXIoc2VsZWN0Q29kZSB+IGNvbmRpdGlvbiArICgxfHN1YmplY3QpICsgKDF8aXRlbSksIGRhdGE9ZGF0YUJpbiwgZmFtaWx5PSJiaW5vbWlhbCIpCiMKIyBkZXNjcmlwdGlvbiBvZiB0aGUgbWF4aW1hbCBtb2RlbCAodXNlZCBmb3IgcmVwb3J0aW5nIGVzdGltYXRlcyBhbmQgc3RhbmRhcmQgZXJyb3JzKQpzdW1tYXJ5KGxtZXIuYmluLm1heCkKYGBgCgpCZWNhdXNlICpFeHBlcmltZW50KiBpcyBhIGZhY3RvciB3aXRoIHRocmVlIGxldmVscywgd2UgY2FuIHNlZSB0aGUgZXN0aW1hdGVzIGZvciAqU2Vjb25kKiBhbmQgKlRoaXJkKiBhcyB0aGV5IGNvbXBhcmUgdG8gdGhlIGJhc2VsaW5lLCB3aGljaCBpcyAqRmlyc3QqIGJlY2F1c2UgaXQgaXMgYWxwaGFiZXRpY2FsbHkgZmlyc3QuIEl0IGlzIGRpZmZpY3VsdCB0byBpbnRlcnByZXQgdGhlIGludGVyYWN0aW9ucyBpbiB0aGlzIHN1bW1hcnkgYmVjYXVzZSBpdCdzIG5vdCBuZWNlc3NhcmlseSBjbGVhciB3aGF0IHRoZSBpbnRlcmNlcHQgcmVmZXJzIHRvIGJlY2F1c2UgaXQgaXMgbW9yZSBhYnN0cmFjdCB0aGFuIGluIGEgMiDDlyAyIGRlc2lnbi4gCgojIyBJbnRlcmFjdGlvbiBlZmZlY3QKCldlIGNhbiBjb21wYXJlIHRoZSBtYXhpbWFsIG1vZGVsIGRpcmVjdGx5IHRvIHRoZSBkZXBsZXRlZCBtb2RlbCB3aXRoIHRoZSBpbnRlcmFjdGlvbiB0ZXJtIHJlbW92ZWQuIE5vdGljZSB0aGF0IGRlZ3JlZXMgb2YgZnJlZWRvbSA9IGAyYCwgc2luY2UgdGhlcmUgYXJlIHR3byBsZXZlbHMgaW4gdGhlICpFeHBlcmltZW50KiBmYWN0b3IsIHdoaWNoIGNvbXBsaWNhdGVzIHRoZSBtb2RlbC4gCgpgYGB7cn0KIyBldmFsdWF0ZSB0aGUgY29udHJpYnV0aW9uIG9mIHRoZSBpbnRlcmFjdGlvbiB0byB0aGUgb3ZlcmFsbCBmaXQKYW5vdmEobG1lci5iaW4ubWF4LGxtZXIuYmluLmludCkKYGBgCgojIyMjIFRlbXBsYXRlOgoKPiBUaGUgaW50ZXJhY3Rpb24gYmV0d2VlbiAqQ29uZGl0aW9uKiBhbmQgKkV4cGVyaW1lbnQqIHdhcyBmb3VuZCB0byBiZSBzaWduaWZpY2FudCwgd2l0aCBib3RoIHRoZSBTZWNvbmQgYW5kIFRoaXJkIGV4cGVyaW1lbnRzIGRpZmZlcmluZyBmcm9tIHRoZSBGaXJzdCBleHBlcmltZW50ICjOsn5TZWNvbmR+PWBFc3RpbWF0ZWAsIFNFPWBTdGQuIEVycm9yYCwgzrJ+VGhpcmR+PWBFc3RpbWF0ZWAsIFNFPWBTdGQuIEVycm9yYCwgz4fCsihgRGZgKT1gQ2hpc3FgLCBwPWBQcig+Q2hpc3EpYCkuCgojIyMjIEV4YW1wbGU6Cgo+IFRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuICpDb25kaXRpb24qIGFuZCAqRXhwZXJpbWVudCogd2FzIGZvdW5kIHRvIGJlIHNpZ25pZmljYW50LCB3aXRoIGJvdGggdGhlIFNlY29uZCBhbmQgVGhpcmQgZXhwZXJpbWVudHMgZGlmZmVyaW5nIGZyb20gdGhlIEZpcnN0IGV4cGVyaW1lbnQgKM6yflNlY29uZH49MS41MywgU0U9MC4zMiwgzrJ+VGhpcmR+PS0xLjU4LCBTRT0wLjI5LCDPh8KyKDIpPTEwMy4xLCBwPDAuMDAwMSkuCgojIyBNYWluIGVmZmVjdCBvZiBGYWN0b3IgMSAoQ29uZGl0aW9uKQoKYGBge3J9CiMgZXZhbHVhdGUgdGhlIGNvbnRyaWJ1dGlvbiBvZiB0aGUgbWFpbiBlZmZlY3Qgb2YgY29uZGl0aW9uIHRvIHRoZSBvdmVyYWxsIGZpdAphbm92YShsbWVyLmJpbi5pbnQsbG1lci5iaW4uY29uKQpgYGAKCk5vdGljZSB0aGF0IHdlIGFyZSBjb21wYXJpbmcgdGhlIGRlcGxldGVkIG1vZGVsIHdpdGggKkNvbmRpdGlvbiogcmVtb3ZlZCB0byB0aGUgZGVwbGV0ZWQgbW9kZWwgd2l0aCAqSW50ZXJhY3Rpb24qIHJlbW92ZWQgYW5kICoqbm90KiogdG8gdGhlIG1heGltYWwgbW9kZWwuIFRoaXMgaXMgYmVjYXVzZSBhIGNvbXBhcmlzb24gaW52b2x2aW5nIHRoZSBtYXhpbWFsIG1vZGVsIHdpbGwgaW5jbHVkZSBib3RoIHRoZSBjb250cmlidXRpb24gb2YgdGhlIGludGVyYWN0aW9uIGFuZCB0aGUgbWFpbiBlZmZlY3QgaWYgd2UgY29tcGFyZSBpdCBkaXJlY3RseS4KCiMjIyMgVGVtcGxhdGU6Cgo+IEEgbWFpbiBlZmZlY3Qgb2YgKkNvbmRpdGlvbiogb2J0YWlucywgd2l0aCB0aGUgKlRyZWF0bWVudCogY29uZGl0aW9uIG1vcmUgbGlrZWx5IHRvIHJlc3VsdCBpbiBhIGhpdCB0aGFuIHRoZSAqQmFzZWxpbmUqIGNvbmRpdGlvbiAozrI9YEVzdGltYXRlYCwgU0U9YFN0ZC4gRXJyb3JgLCDPh8KyKGBEZmApPWBDaGlzcWAsIHA9YFByKD5DaGlzcSlgKS4KCiMjIyMgRXhhbXBsZToKCj4gQSBtYWluIGVmZmVjdCBvZiAqQ29uZGl0aW9uKiBvYnRhaW5zLCB3aXRoIHRoZSAqVHJlYXRtZW50KiBjb25kaXRpb24gbW9yZSBsaWtlbHkgdG8gcmVzdWx0IGluIGEgaGl0IHRoYW4gdGhlICpCYXNlbGluZSogY29uZGl0aW9uICjOsj0wLjk2LCBTRT0wLjIwLCDPh8KyKDEpPTI3LjMsIHA8MC4wMDAxKS4KCiMjIE1haW4gZWZmZWN0IG9mIEZhY3RvciAyIChFeHBlcmltZW50KQoKRmluYWxseSwgd2UgY2FuIGV2YWx1YXRlIHRoZSBjb250cmlidXRpb24gb2YgdGhlIG1haW4gZWZmZWN0IG9mICpFeHBlcmltZW50KiB0byB0aGUgb3ZlcmFsbCBmaXQgb2YgdGhlIG1vZGVsLgoKYGBge3J9CiMgZXZhbHVhdGUgdGhlIGNvbnRyaWJ1dGlvbiBvZiB0aGUgbWFpbiBlZmZlY3Qgb2YgY29uZGl0aW9uIHRvIHRoZSBvdmVyYWxsIGZpdAphbm92YShsbWVyLmJpbi5pbnQsbG1lci5iaW4uZXhwKQpgYGAKCkFzIGJlZm9yZSwgd2UgbXVzdCBjb21wYXJlIHRoaXMgbW9kZWwgYWdhaW5zdCB0aGUgbW9kZWwgd2l0aCB0aGUgaW50ZXJhY3Rpb24gdGVybSByZW1vdmVkIHJhdGhlciB0aGFuIHRoZSBtYXhpbWFsIG1vZGVsLiBUaGUgZGVncmVlcyBvZiBmcmVlZG9tIGFnYWluIGFyZSBgMmAgYmVjYXVzZSBvZiB0aGUgdGhyZWUgbGV2ZWxzIG9mIHRoZSBmYWN0b3IgKkV4cGVyaW1lbnQqIGluY3JlYXNpbmcgdGhlIGNvbXBsZXhpdHkgb2YgdGhlIGNvbXBhcmlzb24uCgojIyMjIFRlbXBsYXRlOgoKPiBXZSBvYnNlcnZlIGEgbWFpbiBlZmZlY3Qgb2YgKkV4cGVyaW1lbnQqICjPh8KyKGBEZmApPWBDaGlzcWAsIHA9YFByKD5DaGlzcSlgKS4KCiMjIyMgRXhhbXBsZToKCj4gV2Ugb2JzZXJ2ZSBhIG1haW4gZWZmZWN0IG9mICpFeHBlcmltZW50KiAoz4fCsigyKT0xOTAuNywgcDwwLjAwMDEpLgoKSWYgd2Ugd2FudCB0byByZXBvcnQgaW4gbW9yZSBkZXRhaWwgYWJvdXQgaG93IHRoZSB0aHJlZSBkaWZmZXJlbnQgZXhwZXJpbWVudHMgcmVsYXRlIHRvIGVhY2ggb3RoZXIsIHdlIG11c3QgZG8gb25lIG1vcmUgY29tcGFyaXNvbi4gVGhpcyBpcyBiZWNhdXNlIHRoZSBiYXNlbGluZSBmb3IgdGhlc2Ugc3VtbWFyaWVzIGhhcyBiZWVuIHNldCBhdCB0aGUgYWxwaGFiZXRpY2FsbHkgZmlyc3QgbGV2ZWwgKGNvbnZlbmllbnRseSwgKkZpcnN0KikuIEhvd2V2ZXIsIHRoaXMgbWVhbnMgd2UgaGF2ZSBub3QgY29tcGFyZWQgdGhlICpTZWNvbmQqIGV4cGVyaW1lbnQgdG8gdGhlICpUaGlyZCogZXhwZXJpbWVudCB5ZXQuIFRvIGRvIHNvLCB3ZSBjYW4gcnVuIGFub3RoZXIgbW9kZWwgY29tcGFyaXNvbiwgYnV0IHRoZW4gd2Ugd2lsbCBiZSAiZG91YmxlIGRpcHBpbmciIGludG8gb3VyIGRhdGEgKGkuZS4sIHJ1bm5pbmcgdGhlIHNhbWUgdGVzdCBvbiB0aGUgc2FtZSBzYW1wbGUgbW9yZSB0aGFuIG9uY2UpLiBUaGlzIGluZmxhdGVzIHRoZSBjaGFuY2Ugb2YgYSBmYWxzZSBwb3NpdGl2ZSwgc28gaW5zdGVhZCBvZiBzZXR0aW5nIHRoZSBzaWduaWZpY2FuY2UgbGV2ZWwgKGFscGhhKSBhdCAwLjA1LCB3ZSBkaXZpZGUgdGhhdCBieSB0aGUgbnVtYmVyIG9mIHRlc3RzIHdlJ3JlIHJ1bm5pbmcgKHR3byksIHRvIGdldCDOsT0wLjAyNS4gVGhpcyBtZWFucyBhIHAtdmFsdWUgbXVzdCBiZSBiZWxvdyAwLjAyNSB0byBiZSBjb25zaWRlcmVkIHNpZ25pZmljYW50LiBZb3UgY2FuIGVpdGhlciBzcGVjaWZ5IHRoZSBuZXcgYWxwaGEgbGV2ZWwgYW5kIHJlcG9ydCB0aGUgcmF3IHAtdmFsdWUgb3IgYWRqdXN0IHRoZSBwLXZhbHVlIGFuZCBtZW50aW9uIHRoYXQgaXQncyBjb3JyZWN0IGZvciB3aGF0ZXZlciBudW1iZXIgb2YgZXZhbHVhdGlvbnMgeW91J3ZlIGRvbmUuCgojIyBQYWlyd2lzZSBjb21wYXJpc29uIG9mIHRocmVlIGxldmVscyB3aXRoaW4gRmFjdG9yIDIKCmBgYHtyfQojIHNldCBhIG5ldyByZWZlcmVuY2UgbGV2ZWwgZm9yIHRoZSBmYWN0b3IgJ2V4cGVyaW1lbnQnCmRhdGFCaW4kZXhwUmVsdmwgPSByZWxldmVsKGRhdGFCaW4kZXhwZXJpbWVudCwgcmVmPSJzZWNvbmQiKQojCiMgbWF4aW1hbCBtb2RlbCB3aXRoIHJlbGV2ZWxlZCBleHBlcmltZW50IGZhY3RvcgpsbWVyLmJpbi5tYXgyIDwtIGdsbWVyKHNlbGVjdENvZGUgfiBjb25kaXRpb24qZXhwUmVsdmwgKyAoMXxzdWJqZWN0KSArICgxfGl0ZW0pLCBkYXRhPWRhdGFCaW4sIGZhbWlseT0iYmlub21pYWwiKQojCiMgbW9kZWwgd2l0aCBjb250cmlidXRpb24gb2YgdGhlIGludGVyYWN0aW9uIHJlbW92ZWQsIGFzIGEgYmFzZWxpbmUgZm9yIG91ciByZWxldmVsZWQgY29tcGFyaXNvbgpsbWVyLmJpbi5pbnQyIDwtIGdsbWVyKHNlbGVjdENvZGUgfiBjb25kaXRpb24rZXhwUmVsdmwgKyAoMXxzdWJqZWN0KSArICgxfGl0ZW0pLCBkYXRhPWRhdGFCaW4sIGZhbWlseT0iYmlub21pYWwiKQojCiNtb2RlbCB3aXRoIGNvbnRyaWJ1dGlvbiBvZiBleHBlcmltZW50IChyZWxldmVsZWQpIHJlbW92ZWQKbG1lci5iaW4uZXhwMiA8LSBnbG1lcihzZWxlY3RDb2RlIH4gY29uZGl0aW9uICsgKDF8c3ViamVjdCkgKyAoMXxpdGVtKSwgZGF0YT1kYXRhQmluLCBmYW1pbHk9ImJpbm9taWFsIikKIwojIHN1bW1hcnkgb2Ygb3VyIHJlbGV2ZWxlZCByZWZlcmVuY2UgbW9kZWwKc3VtbWFyeShsbWVyLmJpbi5tYXgyKQpgYGAKCkZpcnN0IG9mZiwgd2UgY2FuIHNlZSB0aGF0IHAtdmFsdWVzIGZvciB0aGUgcmVsZXZlbGVkIGZhY3RvciBhcmUgbXVjaCBzbWFsbGVyIHRoYW4gYmVmb3JlLiBUaGlzIHN1Z2dlc3RzIHRoYXQgd2hpbGUgd2UgYWxyZWFkeSBrbmV3IHRoZSAqRmlyc3QqIGFuZCAqU2Vjb25kKiBleHBlcmltZW50IGhhZCBjbG9zZXIgZXN0aW1hdGVzIHRoYW4gdGhlICpGaXJzdCogYW5kICpUaGlyZCogZGlkLCB3ZSBub3cgc2VlIHRoYXQgKlNlY29uZCogYW5kICpUaGlyZCogbWF5IG5vdCBhY3R1YWxseSBzaWduaWZpY2FudGx5IGRpZmZlci4gVGhpcyBpcyBsaWtlbHkgcGFydCBvZiB0aGUgcmVhc29uIHdlIGZpbmQgYSBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiBpbiBvdXIgb3ZlcmFsbCBtb2RlbCBjb21wYXJpc29uLiBUbyByZXBvcnQgdGhlc2UgcGFpci13aXNlIGNvbXBhcmlzb25zLCB3ZSBnbyBiYWNrIHRvIHRoZSBkZXNjcmlwdGlvbgoKIyMjIyBUZW1wbGF0ZToKCj4gVXNpbmcgYSBCb25mZXJyb25pIGNvcnJlY3Rpb24sIHdlIGNvbXBlbnNhdGUgZm9yIHRoZSBzZWNvbmQgZXZhbHVhdGlvbiBvZiB0aGUgZmFjdG9yICpFeHBlcmltZW50Ki4gVGhpcyBhbmFseXNpcyBzdWdnZXN0cyB0aGF0IHRoZSAqRmlyc3QqIGFuZCAqVGhpcmQqIGV4cGVyaW1lbnRzIHNpZ25pZmljYW50bHkgZGlmZmVyICjOsj1gRXN0aW1hdGVgLCBTRT1gU3RkLiBFcnJvcmAsIHooYE51bWJlciBvZiBvYnMuYCk9YHogdmFsdWVgLCBwPWBQcig+fHp8KSoyYCksIGJ1dCBhZnRlciBjb3JyZWN0aW9uLCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGJldHdlZW4gZWl0aGVyIHRoZSAqRmlyc3QqIGFuZCAqU2Vjb25kKiBleHBlcmltZW50cyAozrI9YEVzdGltYXRlYCwgU0U9YFN0ZC4gRXJyb3JgLCB6KGBOdW1iZXIgb2Ygb2JzLmApPWB6IHZhbHVlYCwgcD1gUHIoPnx6fCkqMmApIG5vciB0aGUgKlNlY29uZCogYW5kICpUaGlyZCogZXhwZXJpbWVudHMgKM6yPWBFc3RpbWF0ZWAsIFNFPWBTdGQuIEVycm9yYCwgeihgTnVtYmVyIG9mIG9icy5gKT1geiB2YWx1ZWAsIHA9YFByKD58enwpKjJgKS4KCiMjIyMgRXhhbXBsZToKCj4gVXNpbmcgYSBCb25mZXJyb25pIGNvcnJlY3Rpb24sIHdlIGNvbXBlbnNhdGUgZm9yIHRoZSBzZWNvbmQgZXZhbHVhdGlvbiBvZiB0aGUgZmFjdG9yICpFeHBlcmltZW50Ki4gVGhpcyBhbmFseXNpcyBzdWdnZXN0cyB0aGF0IHRoZSAqRmlyc3QqIGFuZCAqVGhpcmQqIGV4cGVyaW1lbnRzIHNpZ25pZmljYW50bHkgZGlmZmVyICjOsj0tMC43OSwgU0U9MC4xOSwgeigxNDQwKT0tNC4yMCwgcDwwLjAwMDEpLCBidXQgYWZ0ZXIgY29ycmVjdGlvbiwgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIGVpdGhlciB0aGUgKkZpcnN0KiBhbmQgKlNlY29uZCogZXhwZXJpbWVudHMgKM6yPS0wLjQwLCBTRT0wLjE5LCB6KDE0NDApPS0yLjE5LCBwPTAuMDU2KSBub3IgdGhlICpTZWNvbmQqIGFuZCAqVGhpcmQqIGV4cGVyaW1lbnRzICjOsj0tMC4zOSwgU0U9MC4xOSwgeigxMTQwKT0tMi4wNSwgcD0wLjA4KS4KCioqTkI6KiogSW4gdGhpcyBleGFtcGxlLCBJIGhhdmUgbXVsdGlwbGllZCB0aGUgcC12YWx1ZXMgYnkgMiB0byByZXBvcnQgdGhlIEJvbmZlcnJvbmktY29ycmVjdGVkIGxldmVscy4gWW91IG1heSBhbHNvIHNwZWNpZnkgdGhhdCBhIGRpZmZlcmVudCBhbHBoYSB3YXMgdXNlZCwgYnV0IGluIG15IGV4cGVyaWVuY2UsIGZld2VyIHBlb3BsZSBhcmUgYXdhcmUgb2YgaG93IHRoaXMgd29ya3MgYW5kIHRodXMgaXQgaXMgc2ltcGxlciB0byBjb3JyZWN0IHRoZSB2YWx1ZSByYXRoZXIgdGhhbiByZXBvcnQgYSBkaWZmZXJlbnQgYWxwaGEuIEp1c3QgYmUgY2xlYXIgaW4geW91ciB0ZXh0IHdoYXQgeW91J3ZlIGRvbmUuCgpgYGB7cn0KYW5vdmEobG1lci5iaW4uaW50MixsbWVyLmJpbi5leHAyKQpgYGAKCk5vdGljZSBob3cgdGhpcyBtb2RlbCBjb21wYXJpc29uIGlzIGlkZW50aWNhbCB0byB0aGUgb25lIGFib3ZlLiBUaGlzIGlzIGJlY2F1c2UgdGhleSdyZSBjb21wYXJpbmcgdGhlIGV4YWN0IHNhbWUgdGhpbmcuIFRoZXkgc2hvdWxkIGFic29sdXRlbHkgYmUgaWRlbnRpY2FsLiBJZiB0aGV5IGFyZSBub3QsIGl0IG1lYW5zIHlvdSBoYXZlIGFsdGVyZWQgeW91ciBkYXRhc2V0IGluIHNvbWUgd2F5LgoKIyAxLXNhbXBsZSBwcm9wb3J0aW9ucyB0ZXN0cwoKVGhpcyB0ZXN0IGlzIHVzZWQgdG8gdGVzdCB3aGV0aGVyIHRoZSBwcm9wb3J0aW9uIG9mIGhpdHMgaW4geW91ciBiaW5vbWlhbCBkYXRhIChjb2RlZCBhcyBgMWBzLCB3aXRoIG1pc3NlcyBhcyBgMGBzKSBkaWZmZXJzIGZyb20gYSBiYXNlbGluZSBsZXZlbC4gVGhlIGJlbmVmaXQgb2YgdGhpcyB0ZXN0IGlzIHRoYXQgeW91IGNhbiBzZXQgeW91ciBvd24gbGV2ZWwgYWdhaW5zdCB3aGljaCB5b3UgYXJlIHRlc3RpbmcgeW91ciBkYXRhLgoKSWYgeW91IHdhbnQgdG8gc2VlIGlmIHlvdSBkYXRhIGRpZmZlciBmcm9tIGNoYW5jZSBhbmQgY2hhbmNlIGlzIGF0IDUwJSwgeW91IGNhbiBzcGVjaWZ5IGBwPTAuNWAgaW4gdGhlIGBwcm9wLnRlc3QoKWAgY29kZS4gKFlvdSBjYW4gcmVhZCBtb3JlIGFib3V0IGNvbmR1Y3RpbmcgYW5kIGdyYXBoaW5nIGluIFtteSAxLXNhbXBsZSBwcm9wb3J0aW9ucyB0dXRvcmlhbF0oKSwgd2hpY2ggY2FuIGJlIFtmb3JrZWQgb24gS2FnZ2xlXShodHRwczovL3d3dy5rYWdnbGUuY29tL2xtYWNrZXJtYW4vcHJhY3RpY2UtYmlub21pYWwtZGF0YSkuKQoKYGBge3J9CmhpdHMgPC0gc3VtKGRhdGFCaW4kc2VsZWN0Q29kZVtkYXRhQmluJGNvbmRpdGlvbj09IlRyZWF0bWVudCJdKQpsZW4gIDwtIGxlbmd0aChkYXRhQmluJHNlbGVjdENvZGVbZGF0YUJpbiRjb25kaXRpb249PSJUcmVhdG1lbnQiXSkKcHJvcC50ZXN0KGhpdHMsbGVuLHA9MC41KQpgYGAKCldpdGggdGhpcyBvdXRwdXQsIHdlIGNhbiByZXBvcnQgdGhlIGVzdGltYXRlICjOsiksIM+HwrIgdmFsdWUsIHRoZSBkZWdyZWVzIG9mIGZyZWVkb20gKGRmKSwgdGhlIHAtdmFsdWUsIGFuZCB0aGUgYm91bmRzIG9mIHRoZSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCAoOTUlQ0kpLgoKIyMjIyBUZW1wbGF0ZToKCj4gVGhlICpUcmVhdG1lbnQqIGNvbmRpdGlvbiBzaWduaWZpY2FudGx5IGRpZmZlcnMgZnJvbSB0aGUgKkJhc2VsaW5lKiBjb25kaXRpb24sIHdpdGggT3B0aW9uIDEgc2VsZWN0ZWQgbW9yZSBmcmVxdWVudGx5IHRoYW4gY2hhbmNlICjOsj1gc2FtcGxlIGVzdGltYXRlYCwgz4fCsihgZGZgKT1gWC1zcXVhcmVkYCwgcD1gcC12YWx1ZWA7IDk1JUNJOiBgQ0kgbG93ZXIgYm91bmRgLS1gQ0kgdXBwZXIgYm91bmRgKS4KCiMjIyMgRXhhbXBsZToKCj4gVGhlICpUcmVhdG1lbnQqIGNvbmRpdGlvbiBzaWduaWZpY2FudGx5IGRpZmZlcnMgZnJvbSB0aGUgKkJhc2VsaW5lKiBjb25kaXRpb24sIHdpdGggT3B0aW9uIDEgc2VsZWN0ZWQgbW9yZSBmcmVxdWVudGx5IHRoYW4gY2hhbmNlICjOsj02Mi43OCUsIM+HwrIoMSk9NDYuNSwgcDwwLjAwMDE7IDk1JUNJOiA1OS4xJS0tNjYuMzAlKS4KCklmIHlvdSBoYXZlIGEgZmV3IDEtc2FtcGxlIHByb3BvcnRpb25zIHRlc3RzLCB0aGUgcmVzdWx0cyBjYW4gYmUgZWFzaWx5IHJlcG9ydGVkIGluIGEgdGFibGUgZm9ybWF0IGFzIHdlbGwuCgp8Q29uZGl0aW9ufEVzdGltYXRlfM+HwrIoZGY9MSl8cC12YWx1ZXw5NSUgQ29uZmlkZW5jZSBJbnRlcnZhbHwKfDotLS0tLS0tOnwtLS0tLS0tOnwtLS0tLS0tOnwtLS0tLS06fDotLS0tLS0tLS0tOnwKfCBCYXNlbGluZXwgIDAuNDQ0NHwgICAgIDguN3wgIDAuMDAzfDAuNDA4LS0wLjQ4MXwKfFRyZWF0bWVudHwgIDAuNjI3OHwgICAgNDYuNXwgMC4wMDAxfDAuNTkxLS0wLjY2M3wKCg==