1.0 Introduction

The General Social Survey (GSS) is a sociological survey used to collect data on a wide variety of demographic characteristics and attitudes of residents of the United States. The data has been collected since 1972, approximately every 2 years, by the National Opinion Research Center (NORC) at the University of Chicago. The latest data is from the spring of 2016. The data for the each year the survey was carried out can be found here in STATA format, and here in SPSS format. The GSS Codebook, in PDF format, documents the survey data for all years. The R notebook can be found in the project’s Github page.

2.0 Variable of interest

This notebook is about making inferences about the true proportion \(p\) of Americans working full time. The variable was coded as \(WRKSTAT\) in the GSS Codebook, on page 117. The survey asked: “Last week were you working full time, part time, going to school, keeping house, or what?”

3.0 Reading the data

The R library foreign allows R to read in STATA files, among others. We can then get the variable we want as a single column vector.

library(foreign) # Used to read STATA (*.DTA) files
gss2016 <- read.dta("GSS2016.DTA")
gss2016_wrkstat <- gss2016$wrkstat
summary(gss2016_wrkstat)
working fulltime working parttime temp not working unempl, laid off          retired 
            1321              345               57              118              574 
          school    keeping house            other               NA              IAP 
              76              284               89                0                0 
            NA's 
               3 

4.0 \(95\%\) confidence interval of the average number of hours worked

We can compute a \(95\%\) condifence interval for the true proportion of Americans who work full-time, \(p\), by using the Central Limit Theorem (CLT). The CLT says that the sampling distribution of a statistic, in this case a proportion, is approximately normal, with the true population proportion, \(p\), as its mean, and the standard error of the sample, \(SE=\sqrt{\frac{p\cdot (1-p)}{n}}\), as its standard deviation, where \(n\) the size of each sample.

\[ \hat{p}\sim\ N(mean = p, sd=\sqrt{\frac{p\cdot (1-p)}{n}}) \]

If we were able to draw many samples of equal size of the proportion of Americans who work full-time, and computed the mean of each sample, the CLT says the distribution of that proportion is approximately normal. Since we typically don’t know the true proportion \(p\), we use the point estimate \(\hat{p}\) as a proxy for the purpose of computing the standard error \(SE\) and the \(95\%\) confidence interval.

In reality, we can only draw one sample from the population. We typically don’t know the true proportion \(p\) of the population. We also don’t know where the sample proportion we have drawn, \(\hat{p}\), falls in the sampling distribution, but from the CLT, we do know that the proportions of \(95\%\) of the samples drawn will fall within \(1.96\cdot \sqrt{\frac{p\cdot (1-p)}{n}}=1.96\cdot SE\) of \(p\). For \(95\%\) of the samples we draw, an interval within \(1.96\cdot \sqrt{\frac{\hat{p}\cdot (1-\hat{p})}{n}}=1.96\cdot SE_{\hat{p}}\) of \(\hat{p}\) will include the true proportion of the population. For any sample whose proportion estimate \(\hat{p}\) falls within \(1.96\cdot SE\) of \(p\), which will happen \(95\%\) of the time, we are \(95\%\) confident that an interval centered around \(\hat{p}\) and within \(1.96\cdot SE_{\hat{p}}\) of \(\hat{p}\) will contain the true proportion of the population.

4.1 An example

It is much easier to understand with an actual example and a plot. Suppose we have a population with a true proportion \(p=0.5\), and we draw a sample of size \(n=100\). Per the CLT, the distribution of sample proportions taken from that population is approximately normal: \(\hat{p}\sim\ N(mean = 0.5, sd=\sqrt{\frac{0.5\cdot (1-0.5)}{100}}=0.05)\). Any sample drawn from the population whose estimate \(\hat{p}\) falls within \((0.5-1.96\cdot0.05,\ 0.5+1.96\cdot0.05)=(0.402,\ 0.598)\) will have a \(95\%\) confidence interval that contains the true proportion, \(p=0.5\). If we draw a sample from the population, and the sample proportion \(\hat{p}=0.58\), the \(95\%\) confidence interval centered around \(\hat{p}=0.58\) will contain the true mean \(p=0.5\). Since the person taking the sample typically doesn’t know \(p\), she will use her sample’s \(\hat{p}\) to compute \(SE_{\hat{p}}\), for the purposes of computing the \(95\%\) confidence interval. \(SE_{\hat{p}}\) will be: \(SE_{\hat{p}}=\sqrt{\frac{0.58\cdot (1-0.58)}{100}}=0.0494\), and the \(95\%\) confidence interval will be: \((0.58-1.96\cdot0.0494,\ 0.58+1.96\cdot0.0494)=(0.4832,\ 0.6768)\), which contains the true proportion \(p=0.5\).

If we are unlucky and draw a sample whose proportion \(\hat{p}\) falls in the shaded area, which should only happen \(5\%\) of the time, its \(95\%\) confidence interval will not include the true proportion \(p=0.5\).

4.2 Conditions for the confidence interval

The conditions for the validity of the confidence interval are:

  1. Sampled observations must be independent.

  2. We expect at least 10 successes and 10 failures in the sample, i.e., \(n\cdot\hat{p}\geq10\) and \(n\cdot(1-\hat{p})\geq10\).

The first criteria for this random sample can be verified by checking that the observations come from a simple random sample and represent less than \(10\%\) of the population. The population consists of Americans who work part-time or full-time, and the sample size can be computed by R as

n <- length(gss2016_wrkstat)
cat("Sample size n =", n)
Sample size n = 2867

and it is certainly less than \(10\%\) of the population.

For the second criteria, since we don’t know \(p\), we will use our point estimate \(\hat{p}\), which can be computed using R:

p_hat <- table(gss2016$wrkstat)["working fulltime"] / sum(table(gss2016_wrkstat))
p_hat <- as.numeric(p_hat)
cat("Estimate of proportion working full-time =", p_hat)
Estimate of proportion working full-time = 0.461243

and so the number of successes is

number_of_successes <- floor(n * p_hat)
cat("Number of successes:", number_of_successes)
Number of successes: 1322

and the number of failures

number_of_failures <- floor(n * (1 - p_hat))
cat("Number of failures:", number_of_failures)
Number of failures: 1544

both of which are much greater than \(10\).

4.3 Critical value \(z^*\)

The \(z^*\) corresponding to a \(95\%\) confidence interval in the standard normal distribution is approximately 1.96. We can compute it more exactly using R:

z_star <- qnorm(p = 0.025, mean = 0, sd = 1, lower.tail = FALSE)
cat("z-value corresponding to 95% confidence interval:", z_star)
z-value corresponding to 95% confidence interval: 1.959964

4.4 Standard error of the sample

The standard error of the sample is

se_p_hat <- sqrt(p_hat * (1 - p_hat) / n)
cat("Standard error SE =", se_p_hat)
Standard error SE = 0.009309953

4.5 Confidence interval

Computing the confidence interval bounds

conf_int_lb <- p_hat - z_star * se_p_hat
conf_int_ub <- p_hat + z_star * se_p_hat
cat("Confidence interval lower bound:", conf_int_lb, "\nConfidence interval upper bound:", conf_int_ub)
Confidence interval lower bound: 0.4429958 
Confidence interval upper bound: 0.4794902

Hence, our confidence interval is \[ 0.4612\pm 1.96\cdot 0.0093=(0.4430, 0.4795) \]

We are \(95\%\) confident that the true proportion of Americans employed full-time is between \(0.4430\) and \(0.4795\).

5.0 Hypothesis testing

We can use the CLT and the data collected to construct a hypothesis testing framework. The hypothesis test considers two possible interpretations of our data, a null hypothesis \(H_0\), and an alternative hypothesis \(H_a\). \(H_0\) basically says that the sampled data could have been drawn simply by chance, and so, it is misleading. There is “nothing going on”. \(H_a\) takes the view that the data collected reveals that “something is going on”. We will either reject the null hypothesis in favor of this alternative, or we will fail to reject it and conclude the sampled data could have been drawn simply by chance. Note that even if we fail to reject \(H_0\), that does not mean we accept it as the ground truth, it’s just that the data we have collected does not allows us to discard \(H_0\).

For example, can try to answer whether the proportion of Americans who work full-time is greater than 0.45. The framework for the hypothesis test would be as follows:

\[ H_{0}:The\ true\ proportion\ of\ Americans\ who\ work\ full-time\ is\ p_0=0.45 \\ H_{a}:The\ true\ proportion\ of\ Americans\ who\ work\ full-time\ is\ greater\ than\ p_0=0.45 \]

To perform the test, we assume that \(H_0\) is true and ask, given that \(H_0\) is true, how probable it is to observe data as extreme or more as the one we have.

5.1 The null hypothesis proportion \(p_0\)

Since in the hypothesis test we assume that \(H_0\) is the truth and the true proportion of Americans who work full-time is \(p_0 = 0.45\), we will use \(p_0\) to compute \(SE_{p_0}\), the standard error under the null hypothesis.

p_null <- 0.45
se_p_null <- sqrt(p_null * (1 - p_null) / n)
cat("Standard error under the null hypothesis:", se_p_null)
Standard error under the null hypothesis: 0.009291242

5.2 Conditions for hypothesis testing

The conditions to perform the hypothesis test are similar to the ones we checked to compute the confidence interval.

  1. Sampled observations must be independent.

  2. Each sample should have at least 10 successses and 10 failures. We use the null hypothesis proportion \(p_0\) to compute the numbers of successes and failures.

\[ n\cdot \hat{p_0}\geq 10\\ n\cdot (1 - \hat{p_0})\geq 10 \]

Verifying the success-failure conditions for hypothesis testing

number_of_successes <- floor(n * p_null)
number_of_failures <- floor(n * (1 - p_null))
cat("Number of successes:", number_of_successes, "\nNumber of failures:", number_of_failures)
Number of successes: 1290 
Number of failures: 1576

The success-failure conditions are satisfied.

5.3 The p-value

The p-value quantifies the strength of the evidence against the null hypothesis. We compute it by asking ourselves, given that the null hypothesis \(H_0\) is true, what is the probability of observing data as extreme or more as the one we have.

\[ P(observing\ data\ as\ extreme\ or\ more\ |\ H_{0}\ is\ true) \]

That probability is the p-value. Typically, we use a \(5\%\) significance level as the threshold to reject the null. If the p-value is less than \(5\%\), we reject the null in favor of the alternative.

For our hypothesis framework, under \(H_0\) and the CLT, \(\hat{p}\) is approximately normally distributed, with \(p = p_0 = 0.45\) and \(SE_{p_{0}}=0.0093\). What is the probability of drawing a sample with a proportion \(\hat{p}=0.46124\) or higher, given that the null hypothesis is true?

\[ P(drawing\ a\ sample\ where\ the\ proportion\ of\ Americans\\ employed\ full-time\ is\ 0.4612\ or\ higher\ |\ H_{0}\ is\ true) \\ P(\hat{p}\ \geq\ 0.46124\ |\ p = 0.45) \]

We can do it graphically:

#http://www.statmethods.net/advgraphs/probability.html
# x = p_null +/- 4 std_dev's
x <- seq(-4,4,length=1000)*se_p_null + p_null
hx <- dnorm(x, p_null ,se_p_null)
lb <- p_hat; ub <- max(x) 
plot(x, hx, type="n", xlab="Proportion of Americans employed full-time", ylab="", main="Sampling distribution under null hypothesis", axes=FALSE)
i <- x >= lb & x <= ub # indexes of x where x >= than lb and <= than ub
lines(x, hx) # plots normal distribution
polygon(c(lb,x[i],ub), c(0,hx[i],0), col="red") # shades area where x >= lb in red
axis(1, at=seq(0.41, 49, 0.005), pos=0) # draws axis
abline(v=p_null)
grid()

That probability is the area under the sampling distribution shaded in red in the plot. It can be computed using pnorm().

area <- pnorm(q = p_hat, mean = p_null, sd = se_p_null, lower.tail = FALSE)
cat("Our p-value:", area)
Our p-value: 0.1131268

So our p-value, the probability of drawing a sample with \(\hat{p}=0.461243\) or higher under the null hypothesis, is about \(0.113\). That probability is high. At the \(5\%\) significance level, we can’t reject the null hypothesis: a sample proportion of \(\hat{p}=0.461243\) or higher could happen simply by chance if the true proportion is \(0.45\).

References

  1. Çetinkaya-Rundel, M. Data Analysis and Statistical Inference. Spring 2014. Coursera.

  2. Diez, D., Barr, C., Çetinkaya-Rundel, M. OpenIntro Statistics, Second Edition. PDF.

  3. Navidi, W. Statistics for engineers and scientists, Third Edition. New York: McGraw Hill, 2011.

  4. UCLA Institute for Digital Reserach and Education, HOW CAN I INCLUDE GREEK LETTERS IN MY PLOT LABELS? | R CODE FRAGMENTS. Retrieved from https://stats.idre.ucla.edu

  5. Kabacoff, R. Probability Plots. Retrieved from http://www.statmethods.net

  6. Carlos Cinelli and Tom, Code chunk font size in Rmarkdown with knitr and latex. Retrieved from https://stackoverflow.com

  7. DrewConway and Christopher DuBois, Getting LaTeX into R Plots. Retrieved from https://stackoverflow.com

LS0tDQp0aXRsZTogIkluZmVyZW5jZSBvbiBhIHBvcHVsYXRpb24gcHJvcG9ydGlvbiINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiA1DQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KYm9keSwgdGQgew0KICAgZm9udC1zaXplOiAxOHB4Ow0KfQ0KaDEgew0KICBmb250LXNpemU6IDMycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDIgew0KICBmb250LXNpemU6IDI4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDMgew0KICBmb250LXNpemU6IDI0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDQgew0KICBmb250LXNpemU6IDIwcHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KY29kZS5yew0KICBmb250LXNpemU6IDE2cHg7DQp9DQpwcmUgew0KICBmb250LXNpemU6IDE2cHgNCn0NCjwvc3R5bGU+DQoNCiMjIDEuMCBJbnRyb2R1Y3Rpb24NCg0KVGhlIFtHZW5lcmFsIFNvY2lhbCBTdXJ2ZXkgKEdTUyldKGh0dHA6Ly9nc3Mubm9yYy5vcmcvKSBpcyBhIHNvY2lvbG9naWNhbCBzdXJ2ZXkgdXNlZCB0byBjb2xsZWN0IGRhdGEgb24gYSB3aWRlIHZhcmlldHkgb2YgZGVtb2dyYXBoaWMgY2hhcmFjdGVyaXN0aWNzIGFuZCBhdHRpdHVkZXMgb2YgcmVzaWRlbnRzIG9mIHRoZSBVbml0ZWQgU3RhdGVzLiBUaGUgZGF0YSBoYXMgYmVlbiBjb2xsZWN0ZWQgc2luY2UgMTk3MiwgYXBwcm94aW1hdGVseSBldmVyeSAyIHllYXJzLCBieSB0aGUgW05hdGlvbmFsIE9waW5pb24gUmVzZWFyY2ggQ2VudGVyIChOT1JDKV0oaHR0cDovL3d3dy5ub3JjLm9yZy9QYWdlcy9kZWZhdWx0LmFzcHgpIGF0IHRoZSBVbml2ZXJzaXR5IG9mIENoaWNhZ28uIFRoZSBsYXRlc3QgZGF0YSBpcyBmcm9tIHRoZSBzcHJpbmcgb2YgMjAxNi4gVGhlIGRhdGEgZm9yIHRoZSBlYWNoIHllYXIgdGhlIHN1cnZleSB3YXMgY2FycmllZCBvdXQgY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwOi8vZ3NzLm5vcmMub3JnL2dldC10aGUtZGF0YS9zdGF0YSkgaW4gU1RBVEEgZm9ybWF0LCBhbmQgW2hlcmVdKGh0dHA6Ly9nc3Mubm9yYy5vcmcvZ2V0LXRoZS1kYXRhL3Nwc3MpIGluIFNQU1MgZm9ybWF0LiBUaGUgW0dTUyBDb2RlYm9va10oaHR0cDovL2dzcy5ub3JjLm9yZy9HZXQtRG9jdW1lbnRhdGlvbiksIGluIFBERiBmb3JtYXQsIGRvY3VtZW50cyB0aGUgc3VydmV5IGRhdGEgZm9yIGFsbCB5ZWFycy4gVGhlIFIgbm90ZWJvb2sgY2FuIGJlIGZvdW5kIGluIHRoZSBwcm9qZWN04oCZcyBbR2l0aHViIHBhZ2VdKGh0dHBzOi8vZ2l0aHViLmNvbS9jYXJsb3Nyb3Ivc3RhdC1pbmYtcHJvcG9ydGlvbnMpLg0KDQojIyAyLjAgVmFyaWFibGUgb2YgaW50ZXJlc3QNCg0KVGhpcyBub3RlYm9vayBpcyBhYm91dCBtYWtpbmcgaW5mZXJlbmNlcyBhYm91dCB0aGUgdHJ1ZSBwcm9wb3J0aW9uICRwJCBvZiBBbWVyaWNhbnMgd29ya2luZyBmdWxsIHRpbWUuIFRoZSB2YXJpYWJsZSB3YXMgY29kZWQgYXMgJFdSS1NUQVQkIGluIHRoZSBbR1NTIENvZGVib29rXShodHRwOi8vZ3NzLm5vcmMub3JnL2RvY3VtZW50cy9jb2RlYm9vay9HU1NfQ29kZWJvb2tfbWFpbmJvZHkucGRmKSwgb24gcGFnZSAxMTcuIFRoZSBzdXJ2ZXkgYXNrZWQ6ICoqIkxhc3Qgd2VlayB3ZXJlIHlvdSB3b3JraW5nIGZ1bGwgdGltZSwgcGFydCB0aW1lLCBnb2luZyB0byBzY2hvb2wsIGtlZXBpbmcgaG91c2UsIG9yIHdoYXQ/IioqDQoNCiMjIDMuMCBSZWFkaW5nIHRoZSBkYXRhDQoNClRoZSBSIGxpYnJhcnkgWyoqZm9yZWlnbioqXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZm9yZWlnbi9mb3JlaWduLnBkZikgYWxsb3dzIFIgdG8gcmVhZCBpbiBTVEFUQSBmaWxlcywgYW1vbmcgb3RoZXJzLiBXZSBjYW4gdGhlbiBnZXQgdGhlIHZhcmlhYmxlIHdlIHdhbnQgYXMgYSBzaW5nbGUgY29sdW1uIHZlY3Rvci4NCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KGZvcmVpZ24pICMgVXNlZCB0byByZWFkIFNUQVRBICgqLkRUQSkgZmlsZXMNCmdzczIwMTYgPC0gcmVhZC5kdGEoIkdTUzIwMTYuRFRBIikNCmdzczIwMTZfd3Jrc3RhdCA8LSBnc3MyMDE2JHdya3N0YXQNCnN1bW1hcnkoZ3NzMjAxNl93cmtzdGF0KQ0KYGBgDQoNCg0KIyMgNC4wICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyB3b3JrZWQNCg0KV2UgY2FuIGNvbXB1dGUgYSAkOTVcJSQgY29uZGlmZW5jZSBpbnRlcnZhbCBmb3IgdGhlIHRydWUgcHJvcG9ydGlvbiBvZiBBbWVyaWNhbnMgd2hvIHdvcmsgZnVsbC10aW1lLCAkcCQsIGJ5IHVzaW5nIHRoZSBbQ2VudHJhbCBMaW1pdCBUaGVvcmVtIChDTFQpXShodHRwOi8vd3d3LnN0YXQud21pY2guZWR1L3MxNjAvYm9vay9ub2RlNDMuaHRtbCkuIFRoZSBDTFQgc2F5cyB0aGF0IHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgYSBzdGF0aXN0aWMsIGluIHRoaXMgY2FzZSBhIHByb3BvcnRpb24sIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsLCB3aXRoIHRoZSB0cnVlIHBvcHVsYXRpb24gcHJvcG9ydGlvbiwgJHAkLCBhcyBpdHMgbWVhbiwgYW5kIHRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgc2FtcGxlLCAkU0U9XHNxcnR7XGZyYWN7cFxjZG90ICgxLXApfXtufX0kLCBhcyBpdHMgc3RhbmRhcmQgZGV2aWF0aW9uLCB3aGVyZSAkbiQgdGhlIHNpemUgb2YgZWFjaCBzYW1wbGUuIA0KDQokJA0KXGhhdHtwfVxzaW1cIE4obWVhbiA9IHAsIHNkPVxzcXJ0e1xmcmFje3BcY2RvdCAoMS1wKX17bn19KQ0KJCQNCg0KSWYgd2Ugd2VyZSBhYmxlIHRvIGRyYXcgbWFueSBzYW1wbGVzIG9mIGVxdWFsIHNpemUgb2YgdGhlIHByb3BvcnRpb24gb2YgQW1lcmljYW5zIHdobyB3b3JrIGZ1bGwtdGltZSwgYW5kIGNvbXB1dGVkIHRoZSBtZWFuIG9mIGVhY2ggc2FtcGxlLCB0aGUgQ0xUIHNheXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGF0IHByb3BvcnRpb24gaXMgYXBwcm94aW1hdGVseSBub3JtYWwuIFNpbmNlIHdlIHR5cGljYWxseSBkb24ndCBrbm93IHRoZSB0cnVlIHByb3BvcnRpb24gJHAkLCB3ZSB1c2UgdGhlIHBvaW50IGVzdGltYXRlICRcaGF0e3B9JCBhcyBhIHByb3h5IGZvciB0aGUgcHVycG9zZSBvZiBjb21wdXRpbmcgdGhlIHN0YW5kYXJkIGVycm9yICRTRSQgYW5kIHRoZSAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbC4NCg0KSW4gcmVhbGl0eSwgd2UgY2FuIG9ubHkgZHJhdyBvbmUgc2FtcGxlIGZyb20gdGhlIHBvcHVsYXRpb24uIFdlIHR5cGljYWxseSBkb24ndCBrbm93IHRoZSB0cnVlIHByb3BvcnRpb24gJHAkIG9mIHRoZSBwb3B1bGF0aW9uLiBXZSBhbHNvIGRvbid0IGtub3cgd2hlcmUgdGhlIHNhbXBsZSBwcm9wb3J0aW9uIHdlIGhhdmUgZHJhd24sICRcaGF0e3B9JCwgZmFsbHMgaW4gdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiwgYnV0IGZyb20gdGhlIENMVCwgd2UgZG8ga25vdyB0aGF0IHRoZSBwcm9wb3J0aW9ucyBvZiAkOTVcJSQgb2YgdGhlIHNhbXBsZXMgZHJhd24gd2lsbCBmYWxsIHdpdGhpbiAkMS45NlxjZG90IFxzcXJ0e1xmcmFje3BcY2RvdCAoMS1wKX17bn19PTEuOTZcY2RvdCBTRSQgb2YgJHAkLiBGb3IgJDk1XCUkIG9mIHRoZSBzYW1wbGVzIHdlIGRyYXcsIGFuIGludGVydmFsIHdpdGhpbiAkMS45NlxjZG90IFxzcXJ0e1xmcmFje1xoYXR7cH1cY2RvdCAoMS1caGF0e3B9KX17bn19PTEuOTZcY2RvdCBTRV97XGhhdHtwfX0kIG9mICRcaGF0e3B9JCB3aWxsIGluY2x1ZGUgdGhlIHRydWUgcHJvcG9ydGlvbiBvZiB0aGUgcG9wdWxhdGlvbi4gRm9yIGFueSBzYW1wbGUgd2hvc2UgcHJvcG9ydGlvbiBlc3RpbWF0ZSAkXGhhdHtwfSQgZmFsbHMgd2l0aGluICQxLjk2XGNkb3QgU0UkIG9mICRwJCwgd2hpY2ggd2lsbCBoYXBwZW4gJDk1XCUkIG9mIHRoZSB0aW1lLCB3ZSBhcmUgJDk1XCUkIGNvbmZpZGVudCB0aGF0IGFuIGludGVydmFsIGNlbnRlcmVkIGFyb3VuZCAkXGhhdHtwfSQgYW5kIHdpdGhpbiAkMS45NlxjZG90IFNFX3tcaGF0e3B9fSQgb2YgJFxoYXR7cH0kIHdpbGwgY29udGFpbiB0aGUgdHJ1ZSBwcm9wb3J0aW9uIG9mIHRoZSBwb3B1bGF0aW9uLg0KDQojIyMgNC4xIEFuIGV4YW1wbGUNCg0KSXQgaXMgbXVjaCBlYXNpZXIgdG8gdW5kZXJzdGFuZCB3aXRoIGFuIGFjdHVhbCBleGFtcGxlIGFuZCBhIHBsb3QuIFN1cHBvc2Ugd2UgaGF2ZSBhIHBvcHVsYXRpb24gd2l0aCBhIHRydWUgcHJvcG9ydGlvbiAkcD0wLjUkLCBhbmQgd2UgZHJhdyBhIHNhbXBsZSBvZiBzaXplICRuPTEwMCQuIFBlciB0aGUgQ0xULCB0aGUgZGlzdHJpYnV0aW9uIG9mIHNhbXBsZSBwcm9wb3J0aW9ucyB0YWtlbiBmcm9tIHRoYXQgcG9wdWxhdGlvbiBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbDogJFxoYXR7cH1cc2ltXCBOKG1lYW4gPSAwLjUsIHNkPVxzcXJ0e1xmcmFjezAuNVxjZG90ICgxLTAuNSl9ezEwMH19PTAuMDUpJC4gQW55IHNhbXBsZSBkcmF3biBmcm9tIHRoZSBwb3B1bGF0aW9uIHdob3NlIGVzdGltYXRlICRcaGF0e3B9JCBmYWxscyB3aXRoaW4gJCgwLjUtMS45NlxjZG90MC4wNSxcIDAuNSsxLjk2XGNkb3QwLjA1KT0oMC40MDIsXCAwLjU5OCkkIHdpbGwgaGF2ZSBhICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIHRoYXQgY29udGFpbnMgdGhlIHRydWUgcHJvcG9ydGlvbiwgJHA9MC41JC4gSWYgd2UgZHJhdyBhIHNhbXBsZSBmcm9tIHRoZSBwb3B1bGF0aW9uLCBhbmQgdGhlIHNhbXBsZSBwcm9wb3J0aW9uICRcaGF0e3B9PTAuNTgkLCB0aGUgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgY2VudGVyZWQgYXJvdW5kICRcaGF0e3B9PTAuNTgkIHdpbGwgY29udGFpbiB0aGUgdHJ1ZSBtZWFuICRwPTAuNSQuIFNpbmNlIHRoZSBwZXJzb24gdGFraW5nIHRoZSBzYW1wbGUgdHlwaWNhbGx5IGRvZXNuJ3Qga25vdyAkcCQsIHNoZSB3aWxsIHVzZSBoZXIgc2FtcGxlJ3MgJFxoYXR7cH0kIHRvIGNvbXB1dGUgJFNFX3tcaGF0e3B9fSQsIGZvciB0aGUgcHVycG9zZXMgb2YgY29tcHV0aW5nIHRoZSAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbC4gJFNFX3tcaGF0e3B9fSQgd2lsbCBiZTogJFNFX3tcaGF0e3B9fT1cc3FydHtcZnJhY3swLjU4XGNkb3QgKDEtMC41OCl9ezEwMH19PTAuMDQ5NCQsIGFuZCB0aGUgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgd2lsbCBiZTogJCgwLjU4LTEuOTZcY2RvdDAuMDQ5NCxcIDAuNTgrMS45NlxjZG90MC4wNDk0KT0oMC40ODMyLFwgMC42NzY4KSQsIHdoaWNoIGNvbnRhaW5zIHRoZSB0cnVlIHByb3BvcnRpb24gJHA9MC41JC4NCg0KYGBge3IsIGVjaG89RkFMU0V9DQojaHR0cDovL3d3dy5zdGF0bWV0aG9kcy5uZXQvYWR2Z3JhcGhzL3Byb2JhYmlsaXR5Lmh0bWwNCg0KbiA8LSAxMDANCnAgPC0gMC41MDsgc2UgPC0gc3FydChwICogKDEgLSBwKSAvIG4pDQoNCiMgeCA9IHAgKy8tIDQgc3RkX2RldidzDQp4IDwtIHNlcSgtNCw0LGxlbmd0aD0xMDAwKSpzZSArIHANCmh4IDwtIGRub3JtKHgsIHAgLHNlKQ0KDQp1cHBlcl9ib3VuZCA8LSBwICsgMS45NiAqIHNlIA0KbG93ZXJfYm91bmQgPC0gcCAtIDEuOTYgKiBzZSANCg0KcGxvdCh4LCBoeCwgdHlwZT0ibiIsIHhsYWIgPSAiIiwgeWxhYj0iIiwgbWFpbj0iU2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGEgcHJvcG9ydGlvbiIsIGF4ZXM9RkFMU0UpDQoNCmkgPC0geCA+PSB1cHBlcl9ib3VuZCAmIHggPD0gbWF4KHgpICMgaW5kZXhlcyBvZiB4IHdoZXJlIHggPj0gdXBwZXJfYm91bmQNCmxpbmVzKHgsIGh4KSAjIHBsb3RzIG5vcm1hbCBkaXN0cmlidXRpb24NCnBvbHlnb24oYyh1cHBlcl9ib3VuZCx4W2ldLG1heCh4KSksIGMoMCxoeFtpXSwwKSwgY29sPSJncmV5IikgIyBzaGFkZXMgYXJlYSBncmV5IHdoZXJlIHggPj0gbG93ZXJfYm91bmQNCg0KaiA8LSB4ID49IG1pbih4KSAmIHggPD0gbG93ZXJfYm91bmQgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA8PSB0aGFuIGxvd2VyX2JvdW5kDQpwb2x5Z29uKGMobWluKHgpLHhbal0sbG93ZXJfYm91bmQpLCBjKDAsaHhbal0sMCksIGNvbD0iZ3JleSIpICMgc2hhZGVzIGFyZWEgZ3JleSB3aGVyZSB4IDw9IGxvd2VyX2JvdW5kDQoNCmF4aXMoMSwgYXQ9c2VxKDAuMywgMC43LCAwLjAyKSwgcG9zPTApICMgZHJhd3MgYXhpcw0KYWJsaW5lKHY9cCkNCmdyaWQoKQ0KDQpwX2hhdCA8LSAwLjU4DQpzZV9wX2hhdCA8LSBzcXJ0KHBfaGF0ICogKDEgLSBwX2hhdCkgLyBuKQ0KYXhpcygxLCBhdD1jKHBfaGF0IC0gMS45NiAqIHNlX3BfaGF0LCBwX2hhdCwgcF9oYXQgKyAxLjk2ICogc2VfcF9oYXQpLCBwb3M9LTEuNSwgY29sID0gImJsdWUiLCBsd2QgPSAyLCBsd2QudGlja3MgPSAxKSANCg0KdGV4dCh4ID0gMC4zMiwgeSA9IDcsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUocCwgIiA9IDAuNSIpKSkNCnRleHQoeCA9IDAuMzIsIHkgPSA2LjQsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUobiwgIiA9IDEwMCIpKSkNCnRleHQoeCA9IDAuMzI3LCB5ID0gNS43LCBsYWJlbHMgPSBleHByZXNzaW9uKHBhc3RlKFNFLCAiID0gMC4wNSIpKSkNCnRleHQoeCA9IDAuMzIsIHkgPSA1LjAsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUoaGF0KHApLCAiID0wLjU4IikpKQ0KdGV4dCh4ID0gMC4zMzYsIHkgPSA0LjIsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUoU0VbaGF0KHApXSwgIiA9MC4wNDkzNCIpKSkNCmBgYA0KDQpJZiB3ZSBhcmUgdW5sdWNreSBhbmQgIGRyYXcgYSBzYW1wbGUgd2hvc2UgcHJvcG9ydGlvbiAkXGhhdHtwfSQgZmFsbHMgaW4gdGhlIHNoYWRlZCBhcmVhLCB3aGljaCBzaG91bGQgb25seSBoYXBwZW4gJDVcJSQgb2YgdGhlIHRpbWUsIGl0cyAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCB3aWxsIG5vdCBpbmNsdWRlIHRoZSB0cnVlIHByb3BvcnRpb24gJHA9MC41JC4NCg0KYGBge3IsIGVjaG89RkFMU0V9DQojaHR0cDovL3d3dy5zdGF0bWV0aG9kcy5uZXQvYWR2Z3JhcGhzL3Byb2JhYmlsaXR5Lmh0bWwNCg0KbiA8LSAxMDANCnAgPC0gMC41MDsgc2UgPC0gc3FydChwICogKDEgLSBwKSAvIG4pDQoNCiMgeCA9IHAgKy8tIDQgc3RkX2RldidzDQp4IDwtIHNlcSgtNCw0LGxlbmd0aD0xMDAwKSpzZSArIHANCmh4IDwtIGRub3JtKHgsIHAgLHNlKQ0KDQp1cHBlcl9ib3VuZCA8LSBwICsgMS45NiAqIHNlIA0KbG93ZXJfYm91bmQgPC0gcCAtIDEuOTYgKiBzZSANCg0KcGxvdCh4LCBoeCwgdHlwZT0ibiIsIHhsYWIgPSAiIiwgeWxhYj0iIiwgbWFpbj0iU2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGEgcHJvcG9ydGlvbiIsIGF4ZXM9RkFMU0UpDQoNCmkgPC0geCA+PSB1cHBlcl9ib3VuZCAmIHggPD0gbWF4KHgpICMgaW5kZXhlcyBvZiB4IHdoZXJlIHggPj0gdXBwZXJfYm91bmQNCmxpbmVzKHgsIGh4KSAjIHBsb3RzIGRpc3RyaWJ1dGlvbiAjIHBsb3RzIG5vcm1hbCBkaXN0cmlidXRpb24NCnBvbHlnb24oYyh1cHBlcl9ib3VuZCx4W2ldLG1heCh4KSksIGMoMCxoeFtpXSwwKSwgY29sPSJncmV5IikgIyBwbG90cyBhcmVhIHdoZXJlIHggPj0gbXUNCg0KaiA8LSB4ID49IG1pbih4KSAmIHggPD0gbG93ZXJfYm91bmQgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA8PSB0aGFuIGxvd2VyX2JvdW5kDQpwb2x5Z29uKGMobWluKHgpLHhbal0sbG93ZXJfYm91bmQpLCBjKDAsaHhbal0sMCksIGNvbD0iZ3JleSIpICMgc2hhZGVzIGFyZWEgZ3JleSB3aGVyZSB4IDw9IGxvd2VyX2JvdW5kDQoNCmF4aXMoMSwgYXQ9c2VxKDAuMywgMC43LCAwLjAyKSwgcG9zPTApICMgZHJhd3MgYXhpcw0KYWJsaW5lKHY9cCkNCmdyaWQoKQ0KDQpwX2hhdCA8LSAwLjM4DQpzZV9wX2hhdCA8LSBzcXJ0KHBfaGF0ICogKDEgLSBwX2hhdCkgLyBuKQ0KYXhpcygxLCBhdD1jKHBfaGF0IC0gMS45NiAqIHNlX3BfaGF0LCBwX2hhdCwgcF9oYXQgKyAxLjk2ICogc2VfcF9oYXQpLCBwb3M9LTEuNSwgY29sID0gInJlZCIsIGx3ZCA9IDIsIGx3ZC50aWNrcyA9IDEpIA0KDQp0ZXh0KHggPSAwLjMyLCB5ID0gNywgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShwLCAiID0gMC41IikpKQ0KdGV4dCh4ID0gMC4zMiwgeSA9IDYuNCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShuLCAiID0gMTAwIikpKQ0KdGV4dCh4ID0gMC4zMjcsIHkgPSA1LjcsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUoU0UsICIgPSAwLjA1IikpKQ0KdGV4dCh4ID0gMC4zMiwgeSA9IDUuMCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShoYXQocCksICIgPTAuMzgiKSkpDQp0ZXh0KHggPSAwLjMzNiwgeSA9IDQuMiwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShTRVtoYXQocCldLCAiID0wLjA0ODU0IikpKQ0KYGBgDQoNCiMjIyA0LjIgQ29uZGl0aW9ucyBmb3IgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwNCg0KVGhlIGNvbmRpdGlvbnMgZm9yIHRoZSB2YWxpZGl0eSBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBhcmU6DQoNCjEuIFNhbXBsZWQgb2JzZXJ2YXRpb25zIG11c3QgYmUgaW5kZXBlbmRlbnQuDQoNCjIuIFdlIGV4cGVjdCBhdCBsZWFzdCAxMCBzdWNjZXNzZXMgYW5kIDEwIGZhaWx1cmVzIGluIHRoZSBzYW1wbGUsIGkuZS4sICRuXGNkb3RcaGF0e3B9XGdlcTEwJCBhbmQgJG5cY2RvdCgxLVxoYXR7cH0pXGdlcTEwJC4NCg0KVGhlIGZpcnN0IGNyaXRlcmlhIGZvciB0aGlzIHJhbmRvbSBzYW1wbGUgY2FuIGJlIHZlcmlmaWVkIGJ5IGNoZWNraW5nIHRoYXQgdGhlIG9ic2VydmF0aW9ucyBjb21lIGZyb20gYSBzaW1wbGUgcmFuZG9tIHNhbXBsZSBhbmQgcmVwcmVzZW50IGxlc3MgdGhhbiAkMTBcJSQgb2YgdGhlIHBvcHVsYXRpb24uIFRoZSBwb3B1bGF0aW9uIGNvbnNpc3RzIG9mIEFtZXJpY2FucyB3aG8gd29yayBwYXJ0LXRpbWUgb3IgZnVsbC10aW1lLCBhbmQgdGhlIHNhbXBsZSBzaXplIGNhbiBiZSBjb21wdXRlZCBieSBSIGFzDQoNCmBgYHtyfQ0KbiA8LSBsZW5ndGgoZ3NzMjAxNl93cmtzdGF0KQ0KY2F0KCJTYW1wbGUgc2l6ZSBuID0iLCBuKQ0KYGBgDQoNCmFuZCBpdCBpcyBjZXJ0YWlubHkgbGVzcyB0aGFuICQxMFwlJCBvZiB0aGUgcG9wdWxhdGlvbi4gDQoNCkZvciB0aGUgc2Vjb25kIGNyaXRlcmlhLCBzaW5jZSB3ZSBkb24ndCBrbm93ICRwJCwgd2Ugd2lsbCB1c2Ugb3VyIHBvaW50IGVzdGltYXRlICRcaGF0e3B9JCwgd2hpY2ggY2FuIGJlIGNvbXB1dGVkIHVzaW5nIFI6DQoNCmBgYHtyfQ0KcF9oYXQgPC0gdGFibGUoZ3NzMjAxNiR3cmtzdGF0KVsid29ya2luZyBmdWxsdGltZSJdIC8gc3VtKHRhYmxlKGdzczIwMTZfd3Jrc3RhdCkpDQpwX2hhdCA8LSBhcy5udW1lcmljKHBfaGF0KQ0KY2F0KCJFc3RpbWF0ZSBvZiBwcm9wb3J0aW9uIHdvcmtpbmcgZnVsbC10aW1lID0iLCBwX2hhdCkNCmBgYA0KDQphbmQgc28gdGhlIG51bWJlciBvZiBzdWNjZXNzZXMgaXMNCg0KYGBge3J9DQpudW1iZXJfb2Zfc3VjY2Vzc2VzIDwtIGZsb29yKG4gKiBwX2hhdCkNCmNhdCgiTnVtYmVyIG9mIHN1Y2Nlc3NlczoiLCBudW1iZXJfb2Zfc3VjY2Vzc2VzKQ0KYGBgDQoNCmFuZCB0aGUgbnVtYmVyIG9mIGZhaWx1cmVzDQoNCmBgYHtyfQ0KbnVtYmVyX29mX2ZhaWx1cmVzIDwtIGZsb29yKG4gKiAoMSAtIHBfaGF0KSkNCmNhdCgiTnVtYmVyIG9mIGZhaWx1cmVzOiIsIG51bWJlcl9vZl9mYWlsdXJlcykNCmBgYA0KDQpib3RoIG9mIHdoaWNoIGFyZSBtdWNoIGdyZWF0ZXIgdGhhbiAkMTAkLg0KDQojIyMgNC4zIENyaXRpY2FsIHZhbHVlICR6XiokDQoNClRoZSAkel4qJCBjb3JyZXNwb25kaW5nIHRvIGEgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaW4gdGhlIFtzdGFuZGFyZCBub3JtYWwgZGlzdHJpYnV0aW9uXShodHRwczovL3d3dy5tYXRoc2lzZnVuLmNvbS9kYXRhL3N0YW5kYXJkLW5vcm1hbC1kaXN0cmlidXRpb24tdGFibGUuaHRtbCkgaXMgYXBwcm94aW1hdGVseSAxLjk2LiBXZSBjYW4gY29tcHV0ZSBpdCBtb3JlIGV4YWN0bHkgdXNpbmcgUjoNCg0KYGBge3J9DQp6X3N0YXIgPC0gcW5vcm0ocCA9IDAuMDI1LCBtZWFuID0gMCwgc2QgPSAxLCBsb3dlci50YWlsID0gRkFMU0UpDQpjYXQoInotdmFsdWUgY29ycmVzcG9uZGluZyB0byA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbDoiLCB6X3N0YXIpDQpgYGANCg0KIyMjIDQuNCBTdGFuZGFyZCBlcnJvciBvZiB0aGUgc2FtcGxlDQoNClRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgc2FtcGxlIGlzDQpgYGB7cn0NCnNlX3BfaGF0IDwtIHNxcnQocF9oYXQgKiAoMSAtIHBfaGF0KSAvIG4pDQpjYXQoIlN0YW5kYXJkIGVycm9yIFNFID0iLCBzZV9wX2hhdCkNCmBgYA0KDQojIyMgNC41IENvbmZpZGVuY2UgaW50ZXJ2YWwNCg0KQ29tcHV0aW5nIHRoZSBjb25maWRlbmNlIGludGVydmFsIGJvdW5kcw0KDQpgYGB7cn0NCmNvbmZfaW50X2xiIDwtIHBfaGF0IC0gel9zdGFyICogc2VfcF9oYXQNCmNvbmZfaW50X3ViIDwtIHBfaGF0ICsgel9zdGFyICogc2VfcF9oYXQNCmNhdCgiQ29uZmlkZW5jZSBpbnRlcnZhbCBsb3dlciBib3VuZDoiLCBjb25mX2ludF9sYiwgIlxuQ29uZmlkZW5jZSBpbnRlcnZhbCB1cHBlciBib3VuZDoiLCBjb25mX2ludF91YikNCmBgYA0KDQpIZW5jZSwgb3VyIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMNCiQkDQowLjQ2MTJccG0gMS45NlxjZG90IDAuMDA5Mz0oMC40NDMwLCAwLjQ3OTUpDQokJA0KDQpXZSBhcmUgJDk1XCUkIGNvbmZpZGVudCB0aGF0IHRoZSB0cnVlIHByb3BvcnRpb24gb2YgQW1lcmljYW5zIGVtcGxveWVkIGZ1bGwtdGltZSBpcyBiZXR3ZWVuICQwLjQ0MzAkIGFuZCAkMC40Nzk1JC4NCg0KIyMgNS4wIEh5cG90aGVzaXMgdGVzdGluZw0KDQpXZSBjYW4gdXNlIHRoZSBDTFQgYW5kIHRoZSBkYXRhIGNvbGxlY3RlZCB0byBjb25zdHJ1Y3QgYSBoeXBvdGhlc2lzIHRlc3RpbmcgZnJhbWV3b3JrLiBUaGUgaHlwb3RoZXNpcyB0ZXN0IGNvbnNpZGVycyB0d28gcG9zc2libGUgaW50ZXJwcmV0YXRpb25zIG9mIG91ciBkYXRhLCBhIG51bGwgaHlwb3RoZXNpcyAkSF8wJCwgYW5kIGFuIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgJEhfYSQuICRIXzAkIGJhc2ljYWxseSBzYXlzIHRoYXQgdGhlIHNhbXBsZWQgZGF0YSBjb3VsZCBoYXZlIGJlZW4gZHJhd24gc2ltcGx5IGJ5IGNoYW5jZSwgYW5kIHNvLCBpdCBpcyBtaXNsZWFkaW5nLiBUaGVyZSBpcyAibm90aGluZyBnb2luZyBvbiIuICRIX2EkIHRha2VzIHRoZSB2aWV3IHRoYXQgdGhlIGRhdGEgY29sbGVjdGVkIHJldmVhbHMgdGhhdCAic29tZXRoaW5nICppcyogZ29pbmcgb24iLiBXZSB3aWxsIGVpdGhlciByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBpbiBmYXZvciBvZiB0aGlzIGFsdGVybmF0aXZlLCBvciB3ZSB3aWxsIGZhaWwgdG8gcmVqZWN0IGl0IGFuZCBjb25jbHVkZSB0aGUgc2FtcGxlZCBkYXRhIGNvdWxkIGhhdmUgYmVlbiBkcmF3biBzaW1wbHkgYnkgY2hhbmNlLiBOb3RlIHRoYXQgZXZlbiBpZiB3ZSBmYWlsIHRvIHJlamVjdCAkSF8wJCwgdGhhdCBkb2VzIG5vdCBtZWFuIHdlIGFjY2VwdCBpdCBhcyB0aGUgZ3JvdW5kIHRydXRoLCBpdCdzIGp1c3QgdGhhdCB0aGUgZGF0YSB3ZSBoYXZlIGNvbGxlY3RlZCBkb2VzIG5vdCBhbGxvd3MgdXMgdG8gZGlzY2FyZCAkSF8wJC4NCg0KRm9yIGV4YW1wbGUsIGNhbiB0cnkgdG8gYW5zd2VyIHdoZXRoZXIgdGhlIHByb3BvcnRpb24gb2YgQW1lcmljYW5zIHdobyB3b3JrIGZ1bGwtdGltZSBpcyBncmVhdGVyIHRoYW4gMC40NS4gVGhlIGZyYW1ld29yayBmb3IgdGhlIGh5cG90aGVzaXMgdGVzdCB3b3VsZCBiZSBhcyBmb2xsb3dzOg0KDQokJA0KSF97MH06VGhlXCB0cnVlXCBwcm9wb3J0aW9uXCBvZlwgQW1lcmljYW5zXCB3aG9cIHdvcmtcIGZ1bGwtdGltZVwgaXNcIHBfMD0wLjQ1DQpcXA0KSF97YX06VGhlXCB0cnVlXCBwcm9wb3J0aW9uXCBvZlwgQW1lcmljYW5zXCB3aG9cIHdvcmtcIGZ1bGwtdGltZVwgaXNcIGdyZWF0ZXJcIHRoYW5cIHBfMD0wLjQ1DQokJA0KDQpUbyBwZXJmb3JtIHRoZSB0ZXN0LCB3ZSBhc3N1bWUgdGhhdCAkSF8wJCBpcyB0cnVlIGFuZCBhc2ssIGdpdmVuIHRoYXQgJEhfMCQgaXMgdHJ1ZSwgaG93IHByb2JhYmxlIGl0IGlzIHRvIG9ic2VydmUgZGF0YSBhcyBleHRyZW1lIG9yIG1vcmUgYXMgdGhlIG9uZSB3ZSBoYXZlLg0KDQojIyMgNS4xIFRoZSBudWxsIGh5cG90aGVzaXMgcHJvcG9ydGlvbiAkcF8wJA0KDQpTaW5jZSBpbiB0aGUgaHlwb3RoZXNpcyB0ZXN0IHdlIGFzc3VtZSB0aGF0ICRIXzAkIGlzIHRoZSB0cnV0aCBhbmQgdGhlIHRydWUgcHJvcG9ydGlvbiBvZiBBbWVyaWNhbnMgd2hvIHdvcmsgZnVsbC10aW1lIGlzICRwXzAgPSAwLjQ1JCwgd2Ugd2lsbCB1c2UgJHBfMCQgdG8gY29tcHV0ZSAkU0Vfe3BfMH0kLCB0aGUgc3RhbmRhcmQgZXJyb3IgdW5kZXIgdGhlIG51bGwgaHlwb3RoZXNpcy4NCmBgYHtyfQ0KcF9udWxsIDwtIDAuNDUNCnNlX3BfbnVsbCA8LSBzcXJ0KHBfbnVsbCAqICgxIC0gcF9udWxsKSAvIG4pDQpjYXQoIlN0YW5kYXJkIGVycm9yIHVuZGVyIHRoZSBudWxsIGh5cG90aGVzaXM6Iiwgc2VfcF9udWxsKQ0KYGBgDQoNCiMjIyA1LjIgQ29uZGl0aW9ucyBmb3IgaHlwb3RoZXNpcyB0ZXN0aW5nDQoNClRoZSBjb25kaXRpb25zIHRvIHBlcmZvcm0gdGhlIGh5cG90aGVzaXMgdGVzdCBhcmUgc2ltaWxhciB0byB0aGUgb25lcyB3ZSBjaGVja2VkIHRvIGNvbXB1dGUgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwuDQoNCjEuIFNhbXBsZWQgb2JzZXJ2YXRpb25zIG11c3QgYmUgaW5kZXBlbmRlbnQuDQoNCjIuIEVhY2ggc2FtcGxlIHNob3VsZCBoYXZlIGF0IGxlYXN0IDEwIHN1Y2Nlc3NzZXMgYW5kIDEwIGZhaWx1cmVzLiBXZSB1c2UgdGhlIG51bGwgaHlwb3RoZXNpcyBwcm9wb3J0aW9uICRwXzAkIHRvIGNvbXB1dGUgdGhlIG51bWJlcnMgb2Ygc3VjY2Vzc2VzIGFuZCBmYWlsdXJlcy4NCg0KJCQNCm5cY2RvdCBcaGF0e3BfMH1cZ2VxIDEwXFwgblxjZG90ICgxIC0gXGhhdHtwXzB9KVxnZXEgMTANCiQkDQoNClZlcmlmeWluZyB0aGUgc3VjY2Vzcy1mYWlsdXJlIGNvbmRpdGlvbnMgZm9yIGh5cG90aGVzaXMgdGVzdGluZw0KYGBge3J9DQpudW1iZXJfb2Zfc3VjY2Vzc2VzIDwtIGZsb29yKG4gKiBwX251bGwpDQpudW1iZXJfb2ZfZmFpbHVyZXMgPC0gZmxvb3IobiAqICgxIC0gcF9udWxsKSkNCmNhdCgiTnVtYmVyIG9mIHN1Y2Nlc3NlczoiLCBudW1iZXJfb2Zfc3VjY2Vzc2VzLCAiXG5OdW1iZXIgb2YgZmFpbHVyZXM6IiwgbnVtYmVyX29mX2ZhaWx1cmVzKQ0KYGBgDQoNClRoZSBzdWNjZXNzLWZhaWx1cmUgY29uZGl0aW9ucyBhcmUgc2F0aXNmaWVkLg0KDQojIyMgNS4zIFRoZSBwLXZhbHVlDQoNClRoZSBwLXZhbHVlIHF1YW50aWZpZXMgdGhlIHN0cmVuZ3RoIG9mIHRoZSBldmlkZW5jZSBhZ2FpbnN0IHRoZSBudWxsIGh5cG90aGVzaXMuIFdlIGNvbXB1dGUgaXQgYnkgYXNraW5nIG91cnNlbHZlcywgZ2l2ZW4gdGhhdCB0aGUgbnVsbCBoeXBvdGhlc2lzICRIXzAkIGlzIHRydWUsIHdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IG9mIG9ic2VydmluZyBkYXRhIGFzIGV4dHJlbWUgb3IgbW9yZSBhcyB0aGUgb25lIHdlIGhhdmUuDQoNCiQkDQpQKG9ic2VydmluZ1wgZGF0YVwgYXNcIGV4dHJlbWVcIG9yXCBtb3JlXCB8XCBIX3swfVwgaXNcIHRydWUpDQokJA0KDQpUaGF0IHByb2JhYmlsaXR5IGlzIHRoZSBwLXZhbHVlLiBUeXBpY2FsbHksIHdlIHVzZSBhICQ1XCUkIHNpZ25pZmljYW5jZSBsZXZlbCBhcyB0aGUgdGhyZXNob2xkIHRvIHJlamVjdCB0aGUgbnVsbC4gSWYgdGhlIHAtdmFsdWUgaXMgbGVzcyB0aGFuICQ1XCUkLCB3ZSByZWplY3QgdGhlIG51bGwgaW4gZmF2b3Igb2YgdGhlIGFsdGVybmF0aXZlLg0KDQpGb3Igb3VyIGh5cG90aGVzaXMgZnJhbWV3b3JrLCB1bmRlciAkSF8wJCBhbmQgdGhlIENMVCwgJFxoYXR7cH0kIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQsIHdpdGggJHAgPSBwXzAgPSAwLjQ1JCBhbmQgJFNFX3twX3swfX09MC4wMDkzJC4gV2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgb2YgZHJhd2luZyBhIHNhbXBsZSB3aXRoIGEgcHJvcG9ydGlvbiAkXGhhdHtwfT0wLjQ2MTI0JCBvciBoaWdoZXIsIGdpdmVuIHRoYXQgdGhlIG51bGwgaHlwb3RoZXNpcyBpcyB0cnVlPw0KDQokJA0KUChkcmF3aW5nXCBhXCBzYW1wbGVcIHdoZXJlXCB0aGVcIHByb3BvcnRpb25cIG9mXCBBbWVyaWNhbnNcXCBlbXBsb3llZFwgZnVsbC10aW1lXCBpc1wgMC40NjEyXCBvclwgaGlnaGVyXCB8XCBIX3swfVwgaXNcIHRydWUpDQpcXA0KUChcaGF0e3B9XCBcZ2VxXCAwLjQ2MTI0XCB8XCBwID0gIDAuNDUpDQokJA0KDQpXZSBjYW4gZG8gaXQgZ3JhcGhpY2FsbHk6DQpgYGB7cn0NCiNodHRwOi8vd3d3LnN0YXRtZXRob2RzLm5ldC9hZHZncmFwaHMvcHJvYmFiaWxpdHkuaHRtbA0KDQojIHggPSBwX251bGwgKy8tIDQgc3RkX2RldidzDQp4IDwtIHNlcSgtNCw0LGxlbmd0aD0xMDAwKSpzZV9wX251bGwgKyBwX251bGwNCmh4IDwtIGRub3JtKHgsIHBfbnVsbCAsc2VfcF9udWxsKQ0KDQpsYiA8LSBwX2hhdDsgdWIgPC0gbWF4KHgpIA0KDQpwbG90KHgsIGh4LCB0eXBlPSJuIiwgeGxhYj0iUHJvcG9ydGlvbiBvZiBBbWVyaWNhbnMgZW1wbG95ZWQgZnVsbC10aW1lIiwgeWxhYj0iIiwgbWFpbj0iU2FtcGxpbmcgZGlzdHJpYnV0aW9uIHVuZGVyIG51bGwgaHlwb3RoZXNpcyIsIGF4ZXM9RkFMU0UpDQoNCmkgPC0geCA+PSBsYiAmIHggPD0gdWIgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA+PSB0aGFuIGxiIGFuZCA8PSB0aGFuIHViDQpsaW5lcyh4LCBoeCkgIyBwbG90cyBub3JtYWwgZGlzdHJpYnV0aW9uDQpwb2x5Z29uKGMobGIseFtpXSx1YiksIGMoMCxoeFtpXSwwKSwgY29sPSJyZWQiKSAjIHNoYWRlcyBhcmVhIHdoZXJlIHggPj0gbGIgaW4gcmVkDQoNCmF4aXMoMSwgYXQ9c2VxKDAuNDEsIDQ5LCAwLjAwNSksIHBvcz0wKSAjIGRyYXdzIGF4aXMNCmFibGluZSh2PXBfbnVsbCkNCmdyaWQoKQ0KYGBgDQoNClRoYXQgcHJvYmFiaWxpdHkgaXMgdGhlIGFyZWEgdW5kZXIgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBzaGFkZWQgaW4gcmVkIGluIHRoZSBwbG90LiBJdCBjYW4gYmUgY29tcHV0ZWQgdXNpbmcgYHBub3JtKClgLg0KYGBge3J9DQphcmVhIDwtIHBub3JtKHEgPSBwX2hhdCwgbWVhbiA9IHBfbnVsbCwgc2QgPSBzZV9wX251bGwsIGxvd2VyLnRhaWwgPSBGQUxTRSkNCmNhdCgiT3VyIHAtdmFsdWU6IiwgYXJlYSkNCmBgYA0KDQpTbyBvdXIgW3AtdmFsdWVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1AtdmFsdWUpLCB0aGUgcHJvYmFiaWxpdHkgb2YgZHJhd2luZyBhIHNhbXBsZSB3aXRoICRcaGF0e3B9PTAuNDYxMjQzJCBvciBoaWdoZXIgdW5kZXIgdGhlIG51bGwgaHlwb3RoZXNpcywgaXMgYWJvdXQgJDAuMTEzJC4gVGhhdCBwcm9iYWJpbGl0eSBpcyBoaWdoLiBBdCB0aGUgJDVcJSQgc2lnbmlmaWNhbmNlIGxldmVsLCB3ZSBjYW4ndCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpczogYSBzYW1wbGUgcHJvcG9ydGlvbiBvZiAkXGhhdHtwfT0wLjQ2MTI0MyQgb3IgaGlnaGVyIGNvdWxkIGhhcHBlbiBzaW1wbHkgYnkgY2hhbmNlIGlmIHRoZSB0cnVlIHByb3BvcnRpb24gaXMgJDAuNDUkLg0KDQojIyBSZWZlcmVuY2VzDQoNCjEuIMOHZXRpbmtheWEtUnVuZGVsLCBNLiAqKipEYXRhIEFuYWx5c2lzIGFuZCBTdGF0aXN0aWNhbCBJbmZlcmVuY2UqKiouIFNwcmluZyAyMDE0LiBbQ291cnNlcmFdKHd3dy5jb3Vyc2VyYS5vcmcpLg0KDQoyLiBEaWV6LCBELiwgQmFyciwgQy4sIMOHZXRpbmtheWEtUnVuZGVsLCBNLiAqKipPcGVuSW50cm8gU3RhdGlzdGljcywgU2Vjb25kIEVkaXRpb24qKiouIFBERi4NCg0KMy4gTmF2aWRpLCBXLiAqKipTdGF0aXN0aWNzIGZvciBlbmdpbmVlcnMgYW5kIHNjaWVudGlzdHMsIFRoaXJkIEVkaXRpb24qKiouIE5ldyBZb3JrOiBNY0dyYXcgSGlsbCwgMjAxMS4NCg0KNC4gVUNMQSBJbnN0aXR1dGUgZm9yIERpZ2l0YWwgUmVzZXJhY2ggYW5kIEVkdWNhdGlvbiwgKioqSE9XIENBTiBJIElOQ0xVREUgR1JFRUsgTEVUVEVSUyBJTiBNWSBQTE9UIExBQkVMUz8gfCBSIENPREUgRlJBR01FTlRTKioqLiBSZXRyaWV2ZWQgZnJvbSBbaHR0cHM6Ly9zdGF0cy5pZHJlLnVjbGEuZWR1XShodHRwczovL3N0YXRzLmlkcmUudWNsYS5lZHUvci9jb2RlZnJhZ21lbnRzL2dyZWVrX2xldHRlcnMvKQ0KDQo1LiBLYWJhY29mZiwgUi4gKioqUHJvYmFiaWxpdHkgUGxvdHMqKiouIFJldHJpZXZlZCBmcm9tIFtodHRwOi8vd3d3LnN0YXRtZXRob2RzLm5ldF0oaHR0cDovL3d3dy5zdGF0bWV0aG9kcy5uZXQvYWR2Z3JhcGhzL3Byb2JhYmlsaXR5Lmh0bWwpDQoNCjYuIENhcmxvcyBDaW5lbGxpIGFuZCBUb20sICoqKkNvZGUgY2h1bmsgZm9udCBzaXplIGluIFJtYXJrZG93biB3aXRoIGtuaXRyIGFuZCBsYXRleCoqKi4gUmV0cmlldmVkIGZyb20gW2h0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb21dKGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzI1NjQ2MzMzL2NvZGUtY2h1bmstZm9udC1zaXplLWluLXJtYXJrZG93bi13aXRoLWtuaXRyLWFuZC1sYXRleCkNCg0KNy4gRHJld0NvbndheSBhbmQgQ2hyaXN0b3BoZXIgRHVCb2lzLCAqKipHZXR0aW5nIExhVGVYIGludG8gUiBQbG90cyoqKi4gUmV0cmlldmVkIGZyb20gW2h0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb21dKGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEzOTUxMDUvZ2V0dGluZy1sYXRleC1pbnRvLXItcGxvdHMp