Introductory Statistics (CRN: 6896)



Objective

Today we learn about t-tests. From the beginning of the class, we have talked about the mean and standard deviation as meausures that allow us to model distributions (a bunch of data). The first tells us about the central tendency of the distribution (i.e., where most scores are likely to fall), and the latter tells us about the dipersion of the distribution (i.e., how disperse the scores are around the mean). With these two alone, we can get a sense of how likely or unlikely a data point is. For example, something tha tis more than 2 standard deivation above the mean is less likely thatn some thing that is 1 standard deviation above the mean and so on.

We also learned that becasue we can estiamte things about population from the sample, we need to qualify our estiamtes with a margin of error (or confidence interval). How did we do this? We used something called dsitribution of sample means. This is nothing but a the dstribution of the means of a bunch of samples we took from a population. This distrbution of sample means has a normal distrbution, which allows us to use what we know about normal distbutions and apply them to our data. That is, people have already figured out the probabilities of datapoint occouring at various distance form the mean (in standard deviation units). For example, we know that 68% of a datapoinst on an romal dsitbrution fall within 1 standard deviation below of above the mean. Or almsot 95% of data points are within 2 standard deviations around the mean. We can use this knowledge to estimate and qualify our etimate of the sample mean. To be pricelsy within the range that contain 95% of the data, the dta have tobe within 1.96 standard deviation above or below the mean. So we qualify our mean with a statement such as this: Mean, 95% CI[Mean - SE*1.96, Mean + SE*1.96]. This is a range of values that’s likely to include a population mean with a 95% degree of confidence.So there is a 5% chance that the true population mean falls outside this range.

SE is the standard deviation of the sample means dsitbution which we calcualte using the formula: \[SE =SD/\sqrt{sample\ size}\]

While the means and SD give us probabilities of different datapoints on a distribution, they do not tell us about how our data is related to other data. We like our models to be better than that. One way of doing this is by using correlations. A correaltion between two variables is an estimate of how much deviation of two variables from their means co-occours. So when one variable is close to it’s mean, the other one is also close to it’s mean, or whenone is far from the mean, the other one is also far from the mean. Whether both variables fall above or below their means determines the sign of the correlation (if one is above and other is below, the coreelation is negative). Correlation is standardized covariance and is calcualted using the formula: \[ r = \frac{cov_{x,y}}{SD(X) SD(Y)}\]

And covariance is: \[cov_{x,y} = \frac{\sum\limits_{i=1}^{n}{(x_i-\overline{x}) \cdot (y_i-\overline{y})} }{n-1}\]

Another way to model our data is to use group variables. Knowing which group a datapoint belongs to could help us imporve our estimate. For example, the data one whether a subject is a child or an adult could help us estimate their height better. One way to do this is to use correlation between age and height and show that older people are taller (age is associated with height). Another way is to group our age data and create an adult vs. child variable. In order to determine if two groups vary meaningfully on the basis of our goruping variable, we use something called t-test.

A t-test tells is whether difference between two mean is meaningful or not. That is, it tells us the probability of the difference between the means of two groups. If it is very low, then we can say the groups are important, and the difference between them is significant (should be incorporated in our model). If the probability is not that low, then the difference between the two means is not uncommon so there is nothing special about it. Adding it to our model is not going to help sus much.

There are broadly two types/uses of t-test:

  • Independent t-test: Compares two means based on independent data (e.g., data from different groups of people.

  • Dependent t-test: Compares two means based on related data. (e.g., data from the same people measured at different times, or data from ‘matched’ samples).

Independent t-test: To run a t-test, we calcualte the difference between means and standardize it. This gives us the t-value or t statistic, which has its own distbution, called the t-distribution. It is pretty much like the normal distribution but it becomes flatter as our sample size becomes smaller. At N = 30, t-distrbution is almost identical to a normal distribution.So we calculate what is called a \(t-statistics\). Using this distribution, we can find the probability of finding a mena difference of certain size in a sample of size n.

Let’s look at an example:

set.seed(123) # this function allows us to 'save' a randomizer's state so we can create the same random numbers each time
x<-rnorm(1000, mean = 1, sd = 2) #rnorm is function that creates random data with normal distribution, adn specified mean and SD
y<-rnorm(1000, mean = 2, sd = 2) #rnorm is function that creates random data with normal distribution, adn specified mean and SD
t.test(x,y)

    Welch Two Sample t-test

data:  x and y
t = -11.761, df = 1997.4, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1.2282127 -0.8771368
sample estimates:
mean of x mean of y 
 1.032256  2.084931 

We cretaed a 1000 datapoints with mean of 1 and SD of 2, and another 1000 datapoint with mean of 2 and sd of 2. Becasue the numbers are random, the means are not exactly 1 and 2 but very close. So what do results tell us? A few things:

  1. The mean of x is 1.032256
  2. The mean of y is 2.084931
  3. The mean difference is 1.052657, 95%CI[-1.2282127, -0.8771368]
  4. The t-value is 11.761
  5. Assumming the means of the two samples is the same, the probability of finding a difference of size 1.052675 between two samples is very very small (P < 2.2e-16). So we reject the null.

This is how we report this: There was a significant diffrence, t(1997) = -11.761, p < 2.2e-16, between x (M = 1.032256) and y (M = 2.084931).


Dependent or Paried t-test For paired t-test, we follow a similar logic (paired means we have two datapoints for each subject, or somehow the observations are matched). The only thing that change sin the command is that we set the paired to TRUE or T.

set.seed(123) # this function allows us to 'save' a randomizer's state so we can create the same random numbers each time
x<-rnorm(1000, mean = 1, sd = 2) #rnorm is function that creates random data with normal distribution, adn specified mean and SD
y<-rnorm(1000, mean = 2, sd = 2) #rnorm is function that creates random data with normal distribution, adn specified mean and SD
t.test(x,y, paired = T)

    Paired t-test

data:  x and y
t = -12.305, df = 999, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1.2205539 -0.8847956
sample estimates:
mean of the differences 
              -1.052675 

This results look a bit different. Here, we have mean of the differences instead of two different means. But the interpretation is the same: there is a significnat difference (M diff = 1.052675) between x and y, t(999) = 12.305, P < 2.2e-16.

Comapring to a specific mean: One other way to run t-test is to compare the mean of a distribution to a specific number. It’s essentially the same as the one’s we’ve looked at above, except it we get to set the value of the mean for one group. Let’s look at an example:

set.seed(123)
x<-rnorm(1000, mean = 1, sd = 2) #rnorm is function that creates random data with normal distribution, adn specified mean and SD
t.test(x, mu = 2)

    One Sample t-test

data:  x
t = -15.43, df = 999, p-value < 2.2e-16
alternative hypothesis: true mean is not equal to 2
95 percent confidence interval:
 0.9091771 1.1553344
sample estimates:
mean of x 
 1.032256 

By specifying the file mu as 2, we are telling R to compare the mean of x to 2. The results are similar to a dependent t-test. We report the results this way: The mean of x is significantly lower than 2, t(999) = 15.43, P < 2.2e-16.

Let’s load the happiness.csv dataset and answer some questions using t-test. This dataset contains:

variable name description
Country Name of the country.
Region Region the country belongs to.
Happiness Rank Rank of the country based on the Happiness Score.
Happiness Score A metric measured in 2015 by asking the sampled people the question: “How would you rate your happiness on a scale of 0 to 10 where 10 is the happiest.”
Standard Error The standard error of the happiness score.
Economy (GDP per Capita) The extent to which GDP contributes to the calculation of the Happiness Score.
FamilyThe extent to which Family contributes to the calculation of the Happiness Score
Health (Life Expectancy) The extent to which Life expectancy contributed to the calculation of the Happiness Score
Freedom The extent to which Freedom contributed to the calculation of the Happiness Score.
Trust (Government Corruption) The extent to which Perception of Corruption contributes to Happiness Score.
Generosity The extent to which Generosity contributed to the calculation of the Happiness Score.
Dystopia Residual The extent to which Dystopia Residual contributed to the calculation of the Happiness Score.

Description: The happiness scores and rankings use data from the Gallup World Poll. The scores are based on answers to the main life evaluation question asked in the poll. This question, known as the Cantril ladder, asks respondents to think of a ladder with the best possible life for them being a 10 and the worst possible life being a 0 and to rate their own current lives on that scale. The scores are from nationally representative samples for the years 2013-2016 and use the Gallup weights to make the estimates representative. The columns following the happiness score estimate the extent to which each of six factors – economic production, social support, life expectancy, freedom, absence of corruption, and generosity – contribute to making life evaluations higher in each country than they are in Dystopia, a hypothetical country that has values equal to the world’s lowest national averages for each of the six factors. They have no impact on the total score reported for each country, but they do explain why some countries rank higher than others.*

happiness<-read.csv("./happiness2015.csv")
head(happiness)

Some breakdown:

table(happiness$Region)

      Australia and New Zealand      Central and Eastern Europe                    Eastern Asia 
                              2                              29                               6 
    Latin America and Caribbean Middle East and Northern Africa                   North America 
                             22                              20                               2 
              Southeastern Asia                   Southern Asia              Sub-Saharan Africa 
                              9                               7                              40 
                 Western Europe 
                             21 

Let’s compare Central and Eastern Europe and Western Europe. We need to subsample our dataset:

with(happiness[happiness$Region %in% c("Central and Eastern Europe", "Western Europe"),], t.test(Happiness.Score~Region))

    Welch Two Sample t-test

data:  Happiness.Score by Region
t = -6.4974, df = 33.399, p-value = 2.127e-07
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1.7813088 -0.9320672
sample estimates:
mean in group Central and Eastern Europe             mean in group Western Europe 
                                5.332931                                 6.689619 

Note two things:

  1. I’m using the command with to subset my dataset and then, I ask for the t.test. Also, when subsetting, I’m asking R to select rows whose values in the column Region is c("Central and Eastern Europe", "Western Europe").

  2. I used the ~ to compare the two groups. This is becasue we have 1 column fro group names and 1 for the the happiness score. This is a matter of taste or how your dataset is designed. You cant switch between teh two. When you have to specific columns for each group, you can use t.test(x,y), and when you have one column for group variable (x) and one for the value you’re interested in comapring (y), you use t.test(y~x).

So our results suggest that Western europeans are happier than Central and Eastern Europeans, t(33.399) = 6.4974, p = 2.127e-07.

See if you can test the differenc ein happines scores between Middle East and Northern Africa and Central and Eastern Europe.

with(happiness[happiness$Region %in% c("Central and Eastern Europe", "Middle East and Northern Africa"),], t.test(Happiness.Score~Region))

    Welch Two Sample t-test

data:  Happiness.Score by Region
t = -0.27591, df = 26.075, p-value = 0.7848
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.6249620  0.4770241
sample estimates:
     mean in group Central and Eastern Europe mean in group Middle East and Northern Africa 
                                     5.332931                                      5.406900 

Interesting. The two region do not differ much in happiness. Sub-Saharan Africa and the Middle East and Northern Africa?

with(happiness[happiness$Region %in% c("Sub-Saharan Africa", "Middle East and Northern Africa"),], t.test(Happiness.Score~Region))

    Welch Two Sample t-test

data:  Happiness.Score by Region
t = 4.553, df = 24.98, p-value = 0.0001189
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 0.6594045 1.7487955
sample estimates:
mean in group Middle East and Northern Africa              mean in group Sub-Saharan Africa 
                                       5.4069                                        4.2028 

So happiness is even lower in Subsaharan Africa than the Middle East…

with(happiness[happiness$Region %in% c("Sub-Saharan Africa", "Western Europe"),], t.test(Family~Region))

    Welch Two Sample t-test

data:  Family by Region
t = -8.491, df = 58.961, p-value = 8.169e-12
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.5414887 -0.3349451
sample estimates:
mean in group Sub-Saharan Africa     mean in group Western Europe 
                        0.809085                         1.247302 

Please answer the following questions:

  • Overall, which one is more important, economic production or family?
with(happiness, t.test(x = Economy..GDP.per.Capita., y = Family))

    Welch Two Sample t-test

data:  Economy..GDP.per.Capita. and Family
t = -3.744, df = 275.62, p-value = 0.0002205
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.22110293 -0.06871454
sample estimates:
mean of x mean of y 
0.8461372 0.9910459 
  • Which one is more important for happiness in Subsharan Africa? Economic production or freedom?
  • Which one is more important for happiness in Western Europe? Economic production or freedom?
  • In Eastern Europe, is absence of corruption as important as freedom?
  • Is trust correlated with freedom?
LS0tCnRpdGxlOiAiTGFiIDciCm91dHB1dDogaHRtbF9ub3RlYm9vawpBdXRob3I6IE1vc3RhZmEgU2FsYXJpIFJhZAoKLS0tCgoKIyMjIEludHJvZHVjdG9yeSBTdGF0aXN0aWNzIChDUk46IDY4OTYpCgpcClwKCiMjIyMgT2JqZWN0aXZlCgpUb2RheSB3ZSBsZWFybiBhYm91dCB0LXRlc3RzLiBGcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGNsYXNzLCB3ZSBoYXZlIHRhbGtlZCBhYm91dCB0aGUgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIGFzIG1lYXVzdXJlcyB0aGF0IGFsbG93IHVzIHRvIG1vZGVsIGRpc3RyaWJ1dGlvbnMgKGEgYnVuY2ggb2YgZGF0YSkuIFRoZSBmaXJzdCB0ZWxscyB1cyBhYm91dCB0aGUgY2VudHJhbCB0ZW5kZW5jeSBvZiB0aGUgZGlzdHJpYnV0aW9uIChpLmUuLCB3aGVyZSBtb3N0IHNjb3JlcyBhcmUgbGlrZWx5IHRvIGZhbGwpLCBhbmQgdGhlIGxhdHRlciB0ZWxscyB1cyBhYm91dCB0aGUgZGlwZXJzaW9uIG9mIHRoZSBkaXN0cmlidXRpb24gKGkuZS4sIGhvdyBkaXNwZXJzZSB0aGUgc2NvcmVzIGFyZSBhcm91bmQgdGhlIG1lYW4pLiBXaXRoIHRoZXNlIHR3byBhbG9uZSwgd2UgY2FuIGdldCBhIHNlbnNlIG9mIGhvdyBsaWtlbHkgb3IgdW5saWtlbHkgYSBkYXRhIHBvaW50IGlzLiBGb3IgZXhhbXBsZSwgc29tZXRoaW5nIHRoYSB0aXMgbW9yZSB0aGFuIDIgc3RhbmRhcmQgZGVpdmF0aW9uIGFib3ZlIHRoZSBtZWFuIGlzIGxlc3MgbGlrZWx5IHRoYXRuIHNvbWUgdGhpbmcgdGhhdCBpcyAxIHN0YW5kYXJkIGRldmlhdGlvbiBhYm92ZSB0aGUgbWVhbiBhbmQgc28gb24uCgoKV2UgYWxzbyBsZWFybmVkIHRoYXQgYmVjYXN1ZSB3ZSBjYW4gZXN0aWFtdGUgdGhpbmdzIGFib3V0IHBvcHVsYXRpb24gZnJvbSB0aGUgc2FtcGxlLCB3ZSBuZWVkIHRvIHF1YWxpZnkgb3VyIGVzdGlhbXRlcyB3aXRoIGEgbWFyZ2luIG9mIGVycm9yIChvciBjb25maWRlbmNlIGludGVydmFsKS4gIEhvdyBkaWQgd2UgZG8gdGhpcz8gV2UgdXNlZCBzb21ldGhpbmcgY2FsbGVkIGRzaXRyaWJ1dGlvbiBvZiBzYW1wbGUgbWVhbnMuIFRoaXMgaXMgbm90aGluZyBidXQgYSB0aGUgZHN0cmlidXRpb24gb2YgdGhlIG1lYW5zIG9mIGEgYnVuY2ggb2Ygc2FtcGxlcyB3ZSB0b29rIGZyb20gYSBwb3B1bGF0aW9uLiBUaGlzIGRpc3RyYnV0aW9uIG9mIHNhbXBsZSBtZWFucyBoYXMgYSBub3JtYWwgZGlzdHJidXRpb24sIHdoaWNoIGFsbG93cyB1cyB0byB1c2Ugd2hhdCB3ZSBrbm93IGFib3V0IG5vcm1hbCBkaXN0YnV0aW9ucyBhbmQgYXBwbHkgdGhlbSB0byBvdXIgZGF0YS4gVGhhdCBpcywgcGVvcGxlIGhhdmUgYWxyZWFkeSBmaWd1cmVkIG91dCB0aGUgcHJvYmFiaWxpdGllcyBvZiBkYXRhcG9pbnQgb2Njb3VyaW5nIGF0IHZhcmlvdXMgZGlzdGFuY2UgZm9ybSB0aGUgbWVhbiAoaW4gc3RhbmRhcmQgZGV2aWF0aW9uIHVuaXRzKS4gRm9yIGV4YW1wbGUsIHdlIGtub3cgdGhhdCA2OCUgb2YgYSBkYXRhcG9pbnN0IG9uIGFuIHJvbWFsIGRzaXRicnV0aW9uIGZhbGwgd2l0aGluIDEgc3RhbmRhcmQgZGV2aWF0aW9uIGJlbG93IG9mIGFib3ZlIHRoZSBtZWFuLiBPciBhbG1zb3QgOTUlIG9mIGRhdGEgcG9pbnRzIGFyZSB3aXRoaW4gMiBzdGFuZGFyZCBkZXZpYXRpb25zIGFyb3VuZCB0aGUgbWVhbi4gV2UgY2FuIHVzZSB0aGlzIGtub3dsZWRnZSB0byBlc3RpbWF0ZSBhbmQgcXVhbGlmeSBvdXIgZXRpbWF0ZSBvZiB0aGUgc2FtcGxlIG1lYW4uIFRvIGJlIHByaWNlbHN5IHdpdGhpbiB0aGUgcmFuZ2UgdGhhdCBjb250YWluIDk1JSBvZiB0aGUgZGF0YSwgdGhlIGR0YSBoYXZlIHRvYmUgd2l0aGluIDEuOTYgc3RhbmRhcmQgZGV2aWF0aW9uIGFib3ZlIG9yIGJlbG93IHRoZSBtZWFuLiBTbyB3ZSBxdWFsaWZ5IG91ciBtZWFuIHdpdGggYSBzdGF0ZW1lbnQgc3VjaCBhcyB0aGlzOiBNZWFuLCA5NSUgQ0lbTWVhbiAtIFNFXCoxLjk2LCBNZWFuICsgU0UqMS45Nl0uIFRoaXMgaXMgYSByYW5nZSBvZiB2YWx1ZXMgdGhhdOKAmXMgbGlrZWx5IHRvIGluY2x1ZGUgYSBwb3B1bGF0aW9uIG1lYW4gd2l0aCBhIDk1JSBkZWdyZWUgb2YgY29uZmlkZW5jZS5TbyB0aGVyZSBpcyBhIDUlIGNoYW5jZSB0aGF0IHRoZSB0cnVlIHBvcHVsYXRpb24gbWVhbiBmYWxscyBvdXRzaWRlIHRoaXMgcmFuZ2UuIAoKCgpTRSBpcyB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSBzYW1wbGUgbWVhbnMgZHNpdGJ1dGlvbiB3aGljaCB3ZSBjYWxjdWFsdGUgdXNpbmcgdGhlIGZvcm11bGE6ICAkJFNFID1TRC9cc3FydHtzYW1wbGVcIHNpemV9JCQgCgoKV2hpbGUgdGhlIG1lYW5zIGFuZCBTRCBnaXZlIHVzIHByb2JhYmlsaXRpZXMgb2YgZGlmZmVyZW50IGRhdGFwb2ludHMgb24gYSBkaXN0cmlidXRpb24sIHRoZXkgZG8gbm90IHRlbGwgdXMgYWJvdXQgaG93IG91ciBkYXRhIGlzIHJlbGF0ZWQgdG8gb3RoZXIgZGF0YS4gV2UgbGlrZSBvdXIgbW9kZWxzIHRvIGJlIGJldHRlciB0aGFuIHRoYXQuIE9uZSB3YXkgb2YgZG9pbmcgdGhpcyBpcyBieSB1c2luZyBjb3JyZWxhdGlvbnMuIEEgY29ycmVhbHRpb24gYmV0d2VlbiB0d28gdmFyaWFibGVzIGlzIGFuIGVzdGltYXRlIG9mIGhvdyBtdWNoIGRldmlhdGlvbiBvZiB0d28gdmFyaWFibGVzIGZyb20gdGhlaXIgbWVhbnMgY28tb2Njb3Vycy4gU28gd2hlbiBvbmUgdmFyaWFibGUgaXMgY2xvc2UgdG8gaXQncyBtZWFuLCB0aGUgb3RoZXIgb25lIGlzIGFsc28gY2xvc2UgdG8gaXQncyBtZWFuLCBvciB3aGVub25lIGlzIGZhciBmcm9tIHRoZSBtZWFuLCB0aGUgb3RoZXIgb25lIGlzIGFsc28gZmFyIGZyb20gdGhlIG1lYW4uIFdoZXRoZXIgYm90aCB2YXJpYWJsZXMgZmFsbCBhYm92ZSBvciBiZWxvdyB0aGVpciBtZWFucyAgZGV0ZXJtaW5lcyB0aGUgc2lnbiBvZiB0aGUgY29ycmVsYXRpb24gKGlmIG9uZSBpcyBhYm92ZSBhbmQgb3RoZXIgaXMgYmVsb3csIHRoZSBjb3JlZWxhdGlvbiBpcyBuZWdhdGl2ZSkuIENvcnJlbGF0aW9uIGlzIHN0YW5kYXJkaXplZCBjb3ZhcmlhbmNlIGFuZCBpcyBjYWxjdWFsdGVkIHVzaW5nIHRoZSBmb3JtdWxhOiAkJCByID0gXGZyYWN7Y292X3t4LHl9fXtTRChYKSBTRChZKX0kJCAKCgpBbmQgY292YXJpYW5jZSBpczogJCRjb3Zfe3gseX0gPSBcZnJhY3tcc3VtXGxpbWl0c197aT0xfV57bn17KHhfaS1cb3ZlcmxpbmV7eH0pIFxjZG90ICh5X2ktXG92ZXJsaW5le3l9KX0gfXtuLTF9JCQKCgpBbm90aGVyIHdheSB0byBtb2RlbCBvdXIgZGF0YSBpcyB0byB1c2UgZ3JvdXAgdmFyaWFibGVzLiBLbm93aW5nIHdoaWNoIGdyb3VwIGEgZGF0YXBvaW50IGJlbG9uZ3MgdG8gY291bGQgaGVscCB1cyBpbXBvcnZlIG91ciBlc3RpbWF0ZS4gRm9yIGV4YW1wbGUsIHRoZSBkYXRhIG9uZSB3aGV0aGVyIGEgc3ViamVjdCBpcyBhIGNoaWxkIG9yIGFuIGFkdWx0IGNvdWxkIGhlbHAgdXMgZXN0aW1hdGUgdGhlaXIgaGVpZ2h0IGJldHRlci4gT25lIHdheSB0byBkbyB0aGlzIGlzIHRvIHVzZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIGFnZSBhbmQgaGVpZ2h0IGFuZCBzaG93IHRoYXQgb2xkZXIgcGVvcGxlIGFyZSB0YWxsZXIgKGFnZSBpcyBhc3NvY2lhdGVkIHdpdGggaGVpZ2h0KS4gQW5vdGhlciB3YXkgaXMgdG8gZ3JvdXAgb3VyIGFnZSBkYXRhIGFuZCBjcmVhdGUgYW4gYWR1bHQgdnMuIGNoaWxkIHZhcmlhYmxlLiBJbiBvcmRlciB0byBkZXRlcm1pbmUgaWYgdHdvIGdyb3VwcyB2YXJ5IG1lYW5pbmdmdWxseSBvbiB0aGUgYmFzaXMgb2Ygb3VyIGdvcnVwaW5nIHZhcmlhYmxlLCB3ZSB1c2Ugc29tZXRoaW5nIGNhbGxlZCB0LXRlc3QuIAoKQSB0LXRlc3QgdGVsbHMgaXMgd2hldGhlciBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIG1lYW4gaXMgbWVhbmluZ2Z1bCBvciBub3QuIFRoYXQgaXMsIGl0IHRlbGxzIHVzIHRoZSBwcm9iYWJpbGl0eSBvZiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBtZWFucyBvZiB0d28gZ3JvdXBzLiBJZiBpdCBpcyB2ZXJ5IGxvdywgdGhlbiB3ZSBjYW4gc2F5IHRoZSBncm91cHMgYXJlIGltcG9ydGFudCwgYW5kIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlbSBpcyBzaWduaWZpY2FudCAoc2hvdWxkIGJlIGluY29ycG9yYXRlZCBpbiBvdXIgbW9kZWwpLiBJZiB0aGUgcHJvYmFiaWxpdHkgaXMgbm90IHRoYXQgbG93LCB0aGVuIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3byBtZWFucyBpcyBub3QgdW5jb21tb24gc28gdGhlcmUgaXMgbm90aGluZyBzcGVjaWFsIGFib3V0IGl0LiBBZGRpbmcgaXQgdG8gb3VyIG1vZGVsIGlzIG5vdCBnb2luZyB0byBoZWxwIHN1cyBtdWNoLiAKXAoKKipUaGVyZSBhcmUgYnJvYWRseSB0d28gdHlwZXMvdXNlcyBvZiB0LXRlc3Q6KioKCiogSW5kZXBlbmRlbnQgdC10ZXN0OiBDb21wYXJlcyB0d28gbWVhbnMgYmFzZWQgb24gaW5kZXBlbmRlbnQgZGF0YSAoZS5nLiwgZGF0YSBmcm9tIGRpZmZlcmVudCBncm91cHMgb2YgcGVvcGxlLgoKCiogRGVwZW5kZW50IHQtdGVzdDogQ29tcGFyZXMgdHdvIG1lYW5zIGJhc2VkIG9uIHJlbGF0ZWQgZGF0YS4gKGUuZy4sIGRhdGEgZnJvbSB0aGUgc2FtZSBwZW9wbGUgbWVhc3VyZWQgYXQgZGlmZmVyZW50IHRpbWVzLCBvciBkYXRhIGZyb20g4oCYbWF0Y2hlZOKAmSBzYW1wbGVzKS4KCgoqKkluZGVwZW5kZW50IHQtdGVzdCoqOiBUbyBydW4gYSB0LXRlc3QsIHdlIGNhbGN1YWx0ZSB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG1lYW5zIGFuZCBzdGFuZGFyZGl6ZSBpdC4gVGhpcyBnaXZlcyB1cyB0aGUgdC12YWx1ZSBvciB0IHN0YXRpc3RpYywgd2hpY2ggaGFzIGl0cyBvd24gZGlzdGJ1dGlvbiwgY2FsbGVkIHRoZSB0LWRpc3RyaWJ1dGlvbi4gSXQgaXMgcHJldHR5IG11Y2ggbGlrZSB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBidXQgaXQgYmVjb21lcyBmbGF0dGVyIGFzIG91ciBzYW1wbGUgc2l6ZSBiZWNvbWVzIHNtYWxsZXIuIEF0ICpOID0gMzAqLCB0LWRpc3RyYnV0aW9uIGlzIGFsbW9zdCBpZGVudGljYWwgdG8gYSBub3JtYWwgZGlzdHJpYnV0aW9uLlNvIHdlIGNhbGN1bGF0ZSB3aGF0IGlzIGNhbGxlZCBhICR0LXN0YXRpc3RpY3MkLiBVc2luZyB0aGlzIGRpc3RyaWJ1dGlvbiwgd2UgY2FuIGZpbmQgdGhlIHByb2JhYmlsaXR5IG9mIGZpbmRpbmcgYSBtZW5hIGRpZmZlcmVuY2Ugb2YgY2VydGFpbiBzaXplIGluIGEgc2FtcGxlIG9mIHNpemUgbi4gCgoKTGV0J3MgbG9vayBhdCBhbiBleGFtcGxlOgoKYGBge3J9CnNldC5zZWVkKDEyMykgIyB0aGlzIGZ1bmN0aW9uIGFsbG93cyB1cyB0byAnc2F2ZScgYSByYW5kb21pemVyJ3Mgc3RhdGUgc28gd2UgY2FuIGNyZWF0ZSB0aGUgc2FtZSByYW5kb20gbnVtYmVycyBlYWNoIHRpbWUKeDwtcm5vcm0oMTAwMCwgbWVhbiA9IDEsIHNkID0gMikgI3Jub3JtIGlzIGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyByYW5kb20gZGF0YSB3aXRoIG5vcm1hbCBkaXN0cmlidXRpb24sIGFkbiBzcGVjaWZpZWQgbWVhbiBhbmQgU0QKeTwtcm5vcm0oMTAwMCwgbWVhbiA9IDIsIHNkID0gMikgI3Jub3JtIGlzIGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyByYW5kb20gZGF0YSB3aXRoIG5vcm1hbCBkaXN0cmlidXRpb24sIGFkbiBzcGVjaWZpZWQgbWVhbiBhbmQgU0QKdC50ZXN0KHgseSkKCmBgYAoKV2UgY3JldGFlZCBhIDEwMDAgZGF0YXBvaW50cyB3aXRoIG1lYW4gb2YgMSBhbmQgU0Qgb2YgMiwgYW5kIGFub3RoZXIgMTAwMCBkYXRhcG9pbnQgd2l0aCBtZWFuIG9mIDIgYW5kIHNkIG9mIDIuIEJlY2FzdWUgdGhlIG51bWJlcnMgYXJlIHJhbmRvbSwgdGhlIG1lYW5zIGFyZSBub3QgZXhhY3RseSAxIGFuZCAyIGJ1dCB2ZXJ5IGNsb3NlLiBTbyB3aGF0IGRvIHJlc3VsdHMgdGVsbCB1cz8gQSBmZXcgdGhpbmdzOgoKICgxKSBUaGUgbWVhbiBvZiB4IGlzIDEuMDMyMjU2CiAoMikgVGhlIG1lYW4gb2YgeSBpcyAyLjA4NDkzMQogKDMpIFRoZSBtZWFuIGRpZmZlcmVuY2UgaXMgMS4wNTI2NTcsIDk1JUNJWy0xLjIyODIxMjcsIC0wLjg3NzEzNjhdCiAoNCkgVGhlIHQtdmFsdWUgaXMgMTEuNzYxCiAoNSkgQXNzdW1taW5nIHRoZSBtZWFucyBvZiB0aGUgdHdvIHNhbXBsZXMgaXMgdGhlIHNhbWUsIHRoZSBwcm9iYWJpbGl0eSBvZiBmaW5kaW5nIGEgZGlmZmVyZW5jZSBvZiBzaXplIDEuMDUyNjc1IGJldHdlZW4gdHdvIHNhbXBsZXMgaXMgdmVyeSB2ZXJ5IHNtYWxsIChQIDwgMi4yZS0xNikuIFNvIHdlIHJlamVjdCB0aGUgbnVsbC4gIAogCiAKVGhpcyBpcyBob3cgd2UgcmVwb3J0IHRoaXM6IFRoZXJlIHdhcyBhIHNpZ25pZmljYW50IGRpZmZyZW5jZSwgKnQqKDE5OTcpID0gLTExLjc2MSwgKnAqIDwgMi4yZS0xNiwgYmV0d2VlbiB4ICgqTSogPSAxLjAzMjI1NikgYW5kIHkgKCpNKiA9IDIuMDg0OTMxKS4KCgpcCioqRGVwZW5kZW50IG9yIFBhcmllZCB0LXRlc3QqKgpGb3IgcGFpcmVkIHQtdGVzdCwgd2UgZm9sbG93IGEgc2ltaWxhciBsb2dpYyAocGFpcmVkIG1lYW5zIHdlIGhhdmUgdHdvIGRhdGFwb2ludHMgZm9yIGVhY2ggc3ViamVjdCwgb3Igc29tZWhvdyB0aGUgb2JzZXJ2YXRpb25zIGFyZSBtYXRjaGVkKS4gVGhlIG9ubHkgdGhpbmcgdGhhdCBjaGFuZ2Ugc2luIHRoZSBjb21tYW5kIGlzIHRoYXQgd2Ugc2V0IHRoZSBgcGFpcmVkYCB0byBgVFJVRWAgb3IgYFRgLgoKYGBge3J9CnNldC5zZWVkKDEyMykgIyB0aGlzIGZ1bmN0aW9uIGFsbG93cyB1cyB0byAnc2F2ZScgYSByYW5kb21pemVyJ3Mgc3RhdGUgc28gd2UgY2FuIGNyZWF0ZSB0aGUgc2FtZSByYW5kb20gbnVtYmVycyBlYWNoIHRpbWUKeDwtcm5vcm0oMTAwMCwgbWVhbiA9IDEsIHNkID0gMikgI3Jub3JtIGlzIGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyByYW5kb20gZGF0YSB3aXRoIG5vcm1hbCBkaXN0cmlidXRpb24sIGFkbiBzcGVjaWZpZWQgbWVhbiBhbmQgU0QKeTwtcm5vcm0oMTAwMCwgbWVhbiA9IDIsIHNkID0gMikgI3Jub3JtIGlzIGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyByYW5kb20gZGF0YSB3aXRoIG5vcm1hbCBkaXN0cmlidXRpb24sIGFkbiBzcGVjaWZpZWQgbWVhbiBhbmQgU0QKdC50ZXN0KHgseSwgcGFpcmVkID0gVCkKYGBgCgpUaGlzIHJlc3VsdHMgbG9vayBhIGJpdCBkaWZmZXJlbnQuIEhlcmUsIHdlIGhhdmUgbWVhbiBvZiB0aGUgZGlmZmVyZW5jZXMgaW5zdGVhZCBvZiB0d28gZGlmZmVyZW50IG1lYW5zLiBCdXQgdGhlIGludGVycHJldGF0aW9uIGlzIHRoZSBzYW1lOiB0aGVyZSBpcyBhIHNpZ25pZmljbmF0IGRpZmZlcmVuY2UgKCpNKiBkaWZmID0gMS4wNTI2NzUpIGJldHdlZW4geCBhbmQgeSwgKnQqKDk5OSkgPSAxMi4zMDUsICpQKiA8IDIuMmUtMTYuCgoKKipDb21hcHJpbmcgdG8gYSBzcGVjaWZpYyBtZWFuKio6Ck9uZSBvdGhlciB3YXkgdG8gcnVuIHQtdGVzdCBpcyB0byBjb21wYXJlIHRoZSBtZWFuIG9mIGEgZGlzdHJpYnV0aW9uIHRvIGEgc3BlY2lmaWMgbnVtYmVyLiBJdCdzIGVzc2VudGlhbGx5IHRoZSBzYW1lIGFzIHRoZSBvbmUncyB3ZSd2ZSBsb29rZWQgYXQgYWJvdmUsIGV4Y2VwdCBpdCB3ZSBnZXQgdG8gc2V0IHRoZSB2YWx1ZSBvZiB0aGUgbWVhbiBmb3Igb25lIGdyb3VwLiAgTGV0J3MgbG9vayBhdCBhbiBleGFtcGxlOgoKCmBgYHtyfQpzZXQuc2VlZCgxMjMpCng8LXJub3JtKDEwMDAsIG1lYW4gPSAxLCBzZCA9IDIpICNybm9ybSBpcyBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgcmFuZG9tIGRhdGEgd2l0aCBub3JtYWwgZGlzdHJpYnV0aW9uLCBhZG4gc3BlY2lmaWVkIG1lYW4gYW5kIFNECnQudGVzdCh4LCBtdSA9IDIpCmBgYAoKCkJ5IHNwZWNpZnlpbmcgdGhlIGZpbGUgYG11YCBhcyAyLCB3ZSBhcmUgdGVsbGluZyBSIHRvIGNvbXBhcmUgdGhlIG1lYW4gb2YgeCB0byAyLiBUaGUgcmVzdWx0cyBhcmUgc2ltaWxhciB0byBhIGRlcGVuZGVudCB0LXRlc3QuIFdlIHJlcG9ydCB0aGUgcmVzdWx0cyB0aGlzIHdheTogVGhlIG1lYW4gb2YgeCBpcyBzaWduaWZpY2FudGx5IGxvd2VyIHRoYW4gMiwgKip0KiooOTk5KSA9IDE1LjQzLCAqKlAqKiA8IDIuMmUtMTYuIAoKCkxldCdzIGxvYWQgdGhlIGBoYXBwaW5lc3MuY3N2YCBkYXRhc2V0IGFuZCBhbnN3ZXIgc29tZSBxdWVzdGlvbnMgdXNpbmcgdC10ZXN0LiBUaGlzIGRhdGFzZXQgY29udGFpbnM6ClwKCgp8dmFyaWFibGUgbmFtZSB8IGRlc2NyaXB0aW9ufAp8LS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLXwKfENvdW50cnkgICAgICAgIHxOYW1lIG9mIHRoZSBjb3VudHJ5LnwKfFJlZ2lvbiB8IFJlZ2lvbiB0aGUgY291bnRyeSBiZWxvbmdzIHRvLnwKfEhhcHBpbmVzcyBSYW5rIHwgUmFuayBvZiB0aGUgY291bnRyeSBiYXNlZCBvbiB0aGUgSGFwcGluZXNzIFNjb3JlLnwKfEhhcHBpbmVzcyBTY29yZSB8IEEgbWV0cmljIG1lYXN1cmVkIGluIDIwMTUgYnkgYXNraW5nIHRoZSBzYW1wbGVkIHBlb3BsZSB0aGUgcXVlc3Rpb246ICJIb3cgd291bGQgeW91IHJhdGUgeW91ciBoYXBwaW5lc3Mgb24gYSBzY2FsZSBvZiAwIHRvIDEwIHdoZXJlIDEwIGlzIHRoZSBoYXBwaWVzdC4ifAp8U3RhbmRhcmQgRXJyb3IgfCBUaGUgc3RhbmRhcmQgZXJyb3Igb2YgdGhlIGhhcHBpbmVzcyBzY29yZS58CnxFY29ub215IChHRFAgcGVyIENhcGl0YSkgfCBUaGUgZXh0ZW50IHRvIHdoaWNoIEdEUCBjb250cmlidXRlcyB0byB0aGUgY2FsY3VsYXRpb24gb2YgdGhlIEhhcHBpbmVzcyBTY29yZS58CnxGYW1pbHlUaGUgZXh0ZW50IHRvIHdoaWNoIHwgRmFtaWx5IGNvbnRyaWJ1dGVzIHRvIHRoZSBjYWxjdWxhdGlvbiBvZiB0aGUgSGFwcGluZXNzIFNjb3JlfAp8SGVhbHRoIChMaWZlIEV4cGVjdGFuY3kpIHwgVGhlIGV4dGVudCB0byB3aGljaCBMaWZlIGV4cGVjdGFuY3kgY29udHJpYnV0ZWQgdG8gdGhlIGNhbGN1bGF0aW9uIG9mIHRoZSBIYXBwaW5lc3MgU2NvcmV8CnxGcmVlZG9tIHwgVGhlIGV4dGVudCB0byB3aGljaCBGcmVlZG9tIGNvbnRyaWJ1dGVkIHRvIHRoZSBjYWxjdWxhdGlvbiBvZiB0aGUgSGFwcGluZXNzIFNjb3JlLnwKfFRydXN0IChHb3Zlcm5tZW50IENvcnJ1cHRpb24pIHwgVGhlIGV4dGVudCB0byB3aGljaCBQZXJjZXB0aW9uIG9mIENvcnJ1cHRpb24gY29udHJpYnV0ZXMgdG8gSGFwcGluZXNzIFNjb3JlLnwKfEdlbmVyb3NpdHkgfCBUaGUgZXh0ZW50IHRvIHdoaWNoIEdlbmVyb3NpdHkgY29udHJpYnV0ZWQgdG8gdGhlIGNhbGN1bGF0aW9uIG9mIHRoZSBIYXBwaW5lc3MgU2NvcmUufAp8RHlzdG9waWEgUmVzaWR1YWwgfCBUaGUgZXh0ZW50IHRvIHdoaWNoIER5c3RvcGlhIFJlc2lkdWFsIGNvbnRyaWJ1dGVkIHRvIHRoZSBjYWxjdWxhdGlvbiBvZiB0aGUgSGFwcGluZXNzIFNjb3JlLnwKCgoqKkRlc2NyaXB0aW9uOioqCipUaGUgaGFwcGluZXNzIHNjb3JlcyBhbmQgcmFua2luZ3MgdXNlIGRhdGEgZnJvbSB0aGUgR2FsbHVwIFdvcmxkIFBvbGwuIFRoZSBzY29yZXMgYXJlIGJhc2VkIG9uIGFuc3dlcnMgdG8gdGhlIG1haW4gbGlmZSBldmFsdWF0aW9uIHF1ZXN0aW9uIGFza2VkIGluIHRoZSBwb2xsLiBUaGlzIHF1ZXN0aW9uLCBrbm93biBhcyB0aGUgQ2FudHJpbCBsYWRkZXIsIGFza3MgcmVzcG9uZGVudHMgdG8gdGhpbmsgb2YgYSBsYWRkZXIgd2l0aCB0aGUgYmVzdCBwb3NzaWJsZSBsaWZlIGZvciB0aGVtIGJlaW5nIGEgMTAgYW5kIHRoZSB3b3JzdCBwb3NzaWJsZSBsaWZlIGJlaW5nIGEgMCBhbmQgdG8gcmF0ZSB0aGVpciBvd24gY3VycmVudCBsaXZlcyBvbiB0aGF0IHNjYWxlLiBUaGUgc2NvcmVzIGFyZSBmcm9tIG5hdGlvbmFsbHkgcmVwcmVzZW50YXRpdmUgc2FtcGxlcyBmb3IgdGhlIHllYXJzIDIwMTMtMjAxNiBhbmQgdXNlIHRoZSBHYWxsdXAgd2VpZ2h0cyB0byBtYWtlIHRoZSBlc3RpbWF0ZXMgcmVwcmVzZW50YXRpdmUuICoqVGhlIGNvbHVtbnMgZm9sbG93aW5nIHRoZSBoYXBwaW5lc3Mgc2NvcmUgZXN0aW1hdGUgdGhlIGV4dGVudCB0byB3aGljaCBlYWNoIG9mIHNpeCBmYWN0b3JzIOKAkyBlY29ub21pYyBwcm9kdWN0aW9uLCBzb2NpYWwgc3VwcG9ydCwgbGlmZSBleHBlY3RhbmN5LCBmcmVlZG9tLCBhYnNlbmNlIG9mIGNvcnJ1cHRpb24sIGFuZCBnZW5lcm9zaXR5IOKAkyBjb250cmlidXRlIHRvIG1ha2luZyBsaWZlIGV2YWx1YXRpb25zIGhpZ2hlciBpbiBlYWNoIGNvdW50cnkgdGhhbiB0aGV5IGFyZSBpbiBEeXN0b3BpYSwgYSBoeXBvdGhldGljYWwgY291bnRyeSB0aGF0IGhhcyB2YWx1ZXMgZXF1YWwgdG8gdGhlIHdvcmxk4oCZcyBsb3dlc3QgbmF0aW9uYWwgYXZlcmFnZXMgZm9yIGVhY2ggb2YgdGhlIHNpeCBmYWN0b3JzLioqICpUaGV5IGhhdmUgbm8gaW1wYWN0IG9uIHRoZSB0b3RhbCBzY29yZSByZXBvcnRlZCBmb3IgZWFjaCBjb3VudHJ5LCBidXQgdGhleSBkbyBleHBsYWluIHdoeSBzb21lIGNvdW50cmllcyByYW5rIGhpZ2hlciB0aGFuIG90aGVycy4qCgoKCgpgYGB7cn0gIApoYXBwaW5lc3M8LXJlYWQuY3N2KCIuL2hhcHBpbmVzczIwMTUuY3N2IikKaGVhZChoYXBwaW5lc3MpCmBgYAoKClNvbWUgYnJlYWtkb3duOgoKYGBge3J9CnRhYmxlKGhhcHBpbmVzcyRSZWdpb24pCmBgYAoKCkxldCdzIGNvbXBhcmUgKkNlbnRyYWwgYW5kIEVhc3Rlcm4gRXVyb3BlKiBhbmQgKldlc3Rlcm4gRXVyb3BlKi4gV2UgbmVlZCB0byBzdWJzYW1wbGUgb3VyIGRhdGFzZXQ6CgpgYGB7cn0Kd2l0aChoYXBwaW5lc3NbaGFwcGluZXNzJFJlZ2lvbiAlaW4lIGMoIkNlbnRyYWwgYW5kIEVhc3Rlcm4gRXVyb3BlIiwgIldlc3Rlcm4gRXVyb3BlIiksXSwgdC50ZXN0KEhhcHBpbmVzcy5TY29yZX5SZWdpb24pKQoKYGBgCgoKTm90ZSB0d28gdGhpbmdzOgoKKDEpIEknbSB1c2luZyB0aGUgY29tbWFuZCBgd2l0aGAgdG8gc3Vic2V0IG15IGRhdGFzZXQgYW5kIHRoZW4sIEkgYXNrIGZvciB0aGUgdC50ZXN0LiBBbHNvLCB3aGVuIHN1YnNldHRpbmcsIEknbSBhc2tpbmcgUiB0byBzZWxlY3Qgcm93cyB3aG9zZSB2YWx1ZXMgaW4gdGhlIGNvbHVtbiBgUmVnaW9uYCBpcyBgYygiQ2VudHJhbCBhbmQgRWFzdGVybiBFdXJvcGUiLCAiV2VzdGVybiBFdXJvcGUiKWAuCgooMikgSSB1c2VkIHRoZSBgfmAgdG8gY29tcGFyZSB0aGUgdHdvIGdyb3Vwcy4gVGhpcyBpcyBiZWNhc3VlIHdlIGhhdmUgMSBjb2x1bW4gZnJvIGdyb3VwIG5hbWVzIGFuZCAxIGZvciB0aGUgdGhlIGhhcHBpbmVzcyBzY29yZS4gVGhpcyBpcyBhIG1hdHRlciBvZiB0YXN0ZSBvciBob3cgeW91ciBkYXRhc2V0IGlzIGRlc2lnbmVkLiBZb3UgY2FudCBzd2l0Y2ggYmV0d2VlbiB0ZWggdHdvLiBXaGVuIHlvdSBoYXZlIHRvIHNwZWNpZmljIGNvbHVtbnMgZm9yIGVhY2ggZ3JvdXAsIHlvdSBjYW4gdXNlIGB0LnRlc3QoeCx5KWAsIGFuZCB3aGVuIHlvdSBoYXZlIG9uZSBjb2x1bW4gZm9yIGdyb3VwIHZhcmlhYmxlICh4KSBhbmQgb25lIGZvciB0aGUgdmFsdWUgeW91J3JlIGludGVyZXN0ZWQgaW4gY29tYXByaW5nICh5KSwgeW91IHVzZSBgdC50ZXN0KHl+eClgLgoKU28gb3VyIHJlc3VsdHMgc3VnZ2VzdCB0aGF0IFdlc3Rlcm4gZXVyb3BlYW5zIGFyZSBoYXBwaWVyIHRoYW4gQ2VudHJhbCBhbmQgRWFzdGVybiBFdXJvcGVhbnMsICp0KigzMy4zOTkpID0gNi40OTc0LCAqcCogPSAyLjEyN2UtMDcuIAoKU2VlIGlmIHlvdSBjYW4gdGVzdCB0aGUgZGlmZmVyZW5jIGVpbiBoYXBwaW5lcyBzY29yZXMgYmV0d2VlbiAqTWlkZGxlIEVhc3QgYW5kIE5vcnRoZXJuIEFmcmljYSogYW5kICpDZW50cmFsIGFuZCBFYXN0ZXJuIEV1cm9wZSouIAoKCmBgYHtyfQp3aXRoKGhhcHBpbmVzc1toYXBwaW5lc3MkUmVnaW9uICVpbiUgYygiQ2VudHJhbCBhbmQgRWFzdGVybiBFdXJvcGUiLCAiTWlkZGxlIEVhc3QgYW5kIE5vcnRoZXJuIEFmcmljYSIpLF0sIHQudGVzdChIYXBwaW5lc3MuU2NvcmV+UmVnaW9uKSkKCmBgYAoKSW50ZXJlc3RpbmcuIFRoZSB0d28gcmVnaW9uIGRvIG5vdCBkaWZmZXIgbXVjaCBpbiBoYXBwaW5lc3MuICpTdWItU2FoYXJhbiBBZnJpY2EqIGFuZCB0aGUgKk1pZGRsZSBFYXN0IGFuZCBOb3J0aGVybiBBZnJpY2EqPwoKYGBge3J9CndpdGgoaGFwcGluZXNzW2hhcHBpbmVzcyRSZWdpb24gJWluJSBjKCJTdWItU2FoYXJhbiBBZnJpY2EiLCAiTWlkZGxlIEVhc3QgYW5kIE5vcnRoZXJuIEFmcmljYSIpLF0sIHQudGVzdChIYXBwaW5lc3MuU2NvcmV+UmVnaW9uKSkKYGBgCgpTbyBoYXBwaW5lc3MgaXMgZXZlbiBsb3dlciBpbiBTdWJzYWhhcmFuIEFmcmljYSB0aGFuIHRoZSBNaWRkbGUgRWFzdC4uLgoKCmBgYHtyfQp3aXRoKGhhcHBpbmVzc1toYXBwaW5lc3MkUmVnaW9uICVpbiUgYygiU3ViLVNhaGFyYW4gQWZyaWNhIiwgIldlc3Rlcm4gRXVyb3BlIiksXSwgdC50ZXN0KEZhbWlseX5SZWdpb24pKQoKYGBgCgpQbGVhc2UgYW5zd2VyIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zOgoKIC0gT3ZlcmFsbCwgd2hpY2ggb25lIGlzIG1vcmUgaW1wb3J0YW50LCBlY29ub21pYyBwcm9kdWN0aW9uIG9yIGZhbWlseT8KIApgYGB7cn0Kd2l0aChoYXBwaW5lc3MsIHQudGVzdCh4ID0gRWNvbm9teS4uR0RQLnBlci5DYXBpdGEuLCB5ID0gRmFtaWx5KSkKCmBgYAogCgogLSBXaGljaCBvbmUgaXMgbW9yZSBpbXBvcnRhbnQgZm9yIGhhcHBpbmVzcyBpbiBTdWJzaGFyYW4gQWZyaWNhPyBFY29ub21pYyBwcm9kdWN0aW9uIG9yIGZyZWVkb20/CiAtIFdoaWNoIG9uZSBpcyBtb3JlIGltcG9ydGFudCBmb3IgaGFwcGluZXNzIGluIFdlc3Rlcm4gRXVyb3BlPyBFY29ub21pYyBwcm9kdWN0aW9uIG9yIGZyZWVkb20/CiAtIEluIEVhc3Rlcm4gRXVyb3BlLCBpcyBhYnNlbmNlIG9mIGNvcnJ1cHRpb24gYXMgaW1wb3J0YW50IGFzIGZyZWVkb20/IAogLSBJcyB0cnVzdCBjb3JyZWxhdGVkIHdpdGggZnJlZWRvbT8KIAoKCgo=