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:
Sampled observations must be independent.
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.
Sampled observations must be independent.
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\).
LS0tDQp0aXRsZTogIkluZmVyZW5jZSBvbiBhIHBvcHVsYXRpb24gcHJvcG9ydGlvbiINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiA1DQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KYm9keSwgdGQgew0KICAgZm9udC1zaXplOiAxOHB4Ow0KfQ0KaDEgew0KICBmb250LXNpemU6IDMycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDIgew0KICBmb250LXNpemU6IDI4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDMgew0KICBmb250LXNpemU6IDI0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDQgew0KICBmb250LXNpemU6IDIwcHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KY29kZS5yew0KICBmb250LXNpemU6IDE2cHg7DQp9DQpwcmUgew0KICBmb250LXNpemU6IDE2cHgNCn0NCjwvc3R5bGU+DQoNCiMjIDEuMCBJbnRyb2R1Y3Rpb24NCg0KVGhlIFtHZW5lcmFsIFNvY2lhbCBTdXJ2ZXkgKEdTUyldKGh0dHA6Ly9nc3Mubm9yYy5vcmcvKSBpcyBhIHNvY2lvbG9naWNhbCBzdXJ2ZXkgdXNlZCB0byBjb2xsZWN0IGRhdGEgb24gYSB3aWRlIHZhcmlldHkgb2YgZGVtb2dyYXBoaWMgY2hhcmFjdGVyaXN0aWNzIGFuZCBhdHRpdHVkZXMgb2YgcmVzaWRlbnRzIG9mIHRoZSBVbml0ZWQgU3RhdGVzLiBUaGUgZGF0YSBoYXMgYmVlbiBjb2xsZWN0ZWQgc2luY2UgMTk3MiwgYXBwcm94aW1hdGVseSBldmVyeSAyIHllYXJzLCBieSB0aGUgW05hdGlvbmFsIE9waW5pb24gUmVzZWFyY2ggQ2VudGVyIChOT1JDKV0oaHR0cDovL3d3dy5ub3JjLm9yZy9QYWdlcy9kZWZhdWx0LmFzcHgpIGF0IHRoZSBVbml2ZXJzaXR5IG9mIENoaWNhZ28uIFRoZSBsYXRlc3QgZGF0YSBpcyBmcm9tIHRoZSBzcHJpbmcgb2YgMjAxNi4gVGhlIGRhdGEgZm9yIHRoZSBlYWNoIHllYXIgdGhlIHN1cnZleSB3YXMgY2FycmllZCBvdXQgY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwOi8vZ3NzLm5vcmMub3JnL2dldC10aGUtZGF0YS9zdGF0YSkgaW4gU1RBVEEgZm9ybWF0LCBhbmQgW2hlcmVdKGh0dHA6Ly9nc3Mubm9yYy5vcmcvZ2V0LXRoZS1kYXRhL3Nwc3MpIGluIFNQU1MgZm9ybWF0LiBUaGUgW0dTUyBDb2RlYm9va10oaHR0cDovL2dzcy5ub3JjLm9yZy9HZXQtRG9jdW1lbnRhdGlvbiksIGluIFBERiBmb3JtYXQsIGRvY3VtZW50cyB0aGUgc3VydmV5IGRhdGEgZm9yIGFsbCB5ZWFycy4gVGhlIFIgbm90ZWJvb2sgY2FuIGJlIGZvdW5kIGluIHRoZSBwcm9qZWN04oCZcyBbR2l0aHViIHBhZ2VdKGh0dHBzOi8vZ2l0aHViLmNvbS9jYXJsb3Nyb3Ivc3RhdC1pbmYtcHJvcG9ydGlvbnMpLg0KDQojIyAyLjAgVmFyaWFibGUgb2YgaW50ZXJlc3QNCg0KVGhpcyBub3RlYm9vayBpcyBhYm91dCBtYWtpbmcgaW5mZXJlbmNlcyBhYm91dCB0aGUgdHJ1ZSBwcm9wb3J0aW9uICRwJCBvZiBBbWVyaWNhbnMgd29ya2luZyBmdWxsIHRpbWUuIFRoZSB2YXJpYWJsZSB3YXMgY29kZWQgYXMgJFdSS1NUQVQkIGluIHRoZSBbR1NTIENvZGVib29rXShodHRwOi8vZ3NzLm5vcmMub3JnL2RvY3VtZW50cy9jb2RlYm9vay9HU1NfQ29kZWJvb2tfbWFpbmJvZHkucGRmKSwgb24gcGFnZSAxMTcuIFRoZSBzdXJ2ZXkgYXNrZWQ6ICoqIkxhc3Qgd2VlayB3ZXJlIHlvdSB3b3JraW5nIGZ1bGwgdGltZSwgcGFydCB0aW1lLCBnb2luZyB0byBzY2hvb2wsIGtlZXBpbmcgaG91c2UsIG9yIHdoYXQ/IioqDQoNCiMjIDMuMCBSZWFkaW5nIHRoZSBkYXRhDQoNClRoZSBSIGxpYnJhcnkgWyoqZm9yZWlnbioqXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZm9yZWlnbi9mb3JlaWduLnBkZikgYWxsb3dzIFIgdG8gcmVhZCBpbiBTVEFUQSBmaWxlcywgYW1vbmcgb3RoZXJzLiBXZSBjYW4gdGhlbiBnZXQgdGhlIHZhcmlhYmxlIHdlIHdhbnQgYXMgYSBzaW5nbGUgY29sdW1uIHZlY3Rvci4NCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KGZvcmVpZ24pICMgVXNlZCB0byByZWFkIFNUQVRBICgqLkRUQSkgZmlsZXMNCmdzczIwMTYgPC0gcmVhZC5kdGEoIkdTUzIwMTYuRFRBIikNCmdzczIwMTZfd3Jrc3RhdCA8LSBnc3MyMDE2JHdya3N0YXQNCnN1bW1hcnkoZ3NzMjAxNl93cmtzdGF0KQ0KYGBgDQoNCg0KIyMgNC4wICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyB3b3JrZWQNCg0KV2UgY2FuIGNvbXB1dGUgYSAkOTVcJSQgY29uZGlmZW5jZSBpbnRlcnZhbCBmb3IgdGhlIHRydWUgcHJvcG9ydGlvbiBvZiBBbWVyaWNhbnMgd2hvIHdvcmsgZnVsbC10aW1lLCAkcCQsIGJ5IHVzaW5nIHRoZSBbQ2VudHJhbCBMaW1pdCBUaGVvcmVtIChDTFQpXShodHRwOi8vd3d3LnN0YXQud21pY2guZWR1L3MxNjAvYm9vay9ub2RlNDMuaHRtbCkuIFRoZSBDTFQgc2F5cyB0aGF0IHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgYSBzdGF0aXN0aWMsIGluIHRoaXMgY2FzZSBhIHByb3BvcnRpb24sIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsLCB3aXRoIHRoZSB0cnVlIHBvcHVsYXRpb24gcHJvcG9ydGlvbiwgJHAkLCBhcyBpdHMgbWVhbiwgYW5kIHRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgc2FtcGxlLCAkU0U9XHNxcnR7XGZyYWN7cFxjZG90ICgxLXApfXtufX0kLCBhcyBpdHMgc3RhbmRhcmQgZGV2aWF0aW9uLCB3aGVyZSAkbiQgdGhlIHNpemUgb2YgZWFjaCBzYW1wbGUuIA0KDQokJA0KXGhhdHtwfVxzaW1cIE4obWVhbiA9IHAsIHNkPVxzcXJ0e1xmcmFje3BcY2RvdCAoMS1wKX17bn19KQ0KJCQNCg0KSWYgd2Ugd2VyZSBhYmxlIHRvIGRyYXcgbWFueSBzYW1wbGVzIG9mIGVxdWFsIHNpemUgb2YgdGhlIHByb3BvcnRpb24gb2YgQW1lcmljYW5zIHdobyB3b3JrIGZ1bGwtdGltZSwgYW5kIGNvbXB1dGVkIHRoZSBtZWFuIG9mIGVhY2ggc2FtcGxlLCB0aGUgQ0xUIHNheXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGF0IHByb3BvcnRpb24gaXMgYXBwcm94aW1hdGVseSBub3JtYWwuIFNpbmNlIHdlIHR5cGljYWxseSBkb24ndCBrbm93IHRoZSB0cnVlIHByb3BvcnRpb24gJHAkLCB3ZSB1c2UgdGhlIHBvaW50IGVzdGltYXRlICRcaGF0e3B9JCBhcyBhIHByb3h5IGZvciB0aGUgcHVycG9zZSBvZiBjb21wdXRpbmcgdGhlIHN0YW5kYXJkIGVycm9yICRTRSQgYW5kIHRoZSAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbC4NCg0KSW4gcmVhbGl0eSwgd2UgY2FuIG9ubHkgZHJhdyBvbmUgc2FtcGxlIGZyb20gdGhlIHBvcHVsYXRpb24uIFdlIHR5cGljYWxseSBkb24ndCBrbm93IHRoZSB0cnVlIHByb3BvcnRpb24gJHAkIG9mIHRoZSBwb3B1bGF0aW9uLiBXZSBhbHNvIGRvbid0IGtub3cgd2hlcmUgdGhlIHNhbXBsZSBwcm9wb3J0aW9uIHdlIGhhdmUgZHJhd24sICRcaGF0e3B9JCwgZmFsbHMgaW4gdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiwgYnV0IGZyb20gdGhlIENMVCwgd2UgZG8ga25vdyB0aGF0IHRoZSBwcm9wb3J0aW9ucyBvZiAkOTVcJSQgb2YgdGhlIHNhbXBsZXMgZHJhd24gd2lsbCBmYWxsIHdpdGhpbiAkMS45NlxjZG90IFxzcXJ0e1xmcmFje3BcY2RvdCAoMS1wKX17bn19PTEuOTZcY2RvdCBTRSQgb2YgJHAkLiBGb3IgJDk1XCUkIG9mIHRoZSBzYW1wbGVzIHdlIGRyYXcsIGFuIGludGVydmFsIHdpdGhpbiAkMS45NlxjZG90IFxzcXJ0e1xmcmFje1xoYXR7cH1cY2RvdCAoMS1caGF0e3B9KX17bn19PTEuOTZcY2RvdCBTRV97XGhhdHtwfX0kIG9mICRcaGF0e3B9JCB3aWxsIGluY2x1ZGUgdGhlIHRydWUgcHJvcG9ydGlvbiBvZiB0aGUgcG9wdWxhdGlvbi4gRm9yIGFueSBzYW1wbGUgd2hvc2UgcHJvcG9ydGlvbiBlc3RpbWF0ZSAkXGhhdHtwfSQgZmFsbHMgd2l0aGluICQxLjk2XGNkb3QgU0UkIG9mICRwJCwgd2hpY2ggd2lsbCBoYXBwZW4gJDk1XCUkIG9mIHRoZSB0aW1lLCB3ZSBhcmUgJDk1XCUkIGNvbmZpZGVudCB0aGF0IGFuIGludGVydmFsIGNlbnRlcmVkIGFyb3VuZCAkXGhhdHtwfSQgYW5kIHdpdGhpbiAkMS45NlxjZG90IFNFX3tcaGF0e3B9fSQgb2YgJFxoYXR7cH0kIHdpbGwgY29udGFpbiB0aGUgdHJ1ZSBwcm9wb3J0aW9uIG9mIHRoZSBwb3B1bGF0aW9uLg0KDQojIyMgNC4xIEFuIGV4YW1wbGUNCg0KSXQgaXMgbXVjaCBlYXNpZXIgdG8gdW5kZXJzdGFuZCB3aXRoIGFuIGFjdHVhbCBleGFtcGxlIGFuZCBhIHBsb3QuIFN1cHBvc2Ugd2UgaGF2ZSBhIHBvcHVsYXRpb24gd2l0aCBhIHRydWUgcHJvcG9ydGlvbiAkcD0wLjUkLCBhbmQgd2UgZHJhdyBhIHNhbXBsZSBvZiBzaXplICRuPTEwMCQuIFBlciB0aGUgQ0xULCB0aGUgZGlzdHJpYnV0aW9uIG9mIHNhbXBsZSBwcm9wb3J0aW9ucyB0YWtlbiBmcm9tIHRoYXQgcG9wdWxhdGlvbiBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbDogJFxoYXR7cH1cc2ltXCBOKG1lYW4gPSAwLjUsIHNkPVxzcXJ0e1xmcmFjezAuNVxjZG90ICgxLTAuNSl9ezEwMH19PTAuMDUpJC4gQW55IHNhbXBsZSBkcmF3biBmcm9tIHRoZSBwb3B1bGF0aW9uIHdob3NlIGVzdGltYXRlICRcaGF0e3B9JCBmYWxscyB3aXRoaW4gJCgwLjUtMS45NlxjZG90MC4wNSxcIDAuNSsxLjk2XGNkb3QwLjA1KT0oMC40MDIsXCAwLjU5OCkkIHdpbGwgaGF2ZSBhICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIHRoYXQgY29udGFpbnMgdGhlIHRydWUgcHJvcG9ydGlvbiwgJHA9MC41JC4gSWYgd2UgZHJhdyBhIHNhbXBsZSBmcm9tIHRoZSBwb3B1bGF0aW9uLCBhbmQgdGhlIHNhbXBsZSBwcm9wb3J0aW9uICRcaGF0e3B9PTAuNTgkLCB0aGUgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgY2VudGVyZWQgYXJvdW5kICRcaGF0e3B9PTAuNTgkIHdpbGwgY29udGFpbiB0aGUgdHJ1ZSBtZWFuICRwPTAuNSQuIFNpbmNlIHRoZSBwZXJzb24gdGFraW5nIHRoZSBzYW1wbGUgdHlwaWNhbGx5IGRvZXNuJ3Qga25vdyAkcCQsIHNoZSB3aWxsIHVzZSBoZXIgc2FtcGxlJ3MgJFxoYXR7cH0kIHRvIGNvbXB1dGUgJFNFX3tcaGF0e3B9fSQsIGZvciB0aGUgcHVycG9zZXMgb2YgY29tcHV0aW5nIHRoZSAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbC4gJFNFX3tcaGF0e3B9fSQgd2lsbCBiZTogJFNFX3tcaGF0e3B9fT1cc3FydHtcZnJhY3swLjU4XGNkb3QgKDEtMC41OCl9ezEwMH19PTAuMDQ5NCQsIGFuZCB0aGUgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgd2lsbCBiZTogJCgwLjU4LTEuOTZcY2RvdDAuMDQ5NCxcIDAuNTgrMS45NlxjZG90MC4wNDk0KT0oMC40ODMyLFwgMC42NzY4KSQsIHdoaWNoIGNvbnRhaW5zIHRoZSB0cnVlIHByb3BvcnRpb24gJHA9MC41JC4NCg0KYGBge3IsIGVjaG89RkFMU0V9DQojaHR0cDovL3d3dy5zdGF0bWV0aG9kcy5uZXQvYWR2Z3JhcGhzL3Byb2JhYmlsaXR5Lmh0bWwNCg0KbiA8LSAxMDANCnAgPC0gMC41MDsgc2UgPC0gc3FydChwICogKDEgLSBwKSAvIG4pDQoNCiMgeCA9IHAgKy8tIDQgc3RkX2RldidzDQp4IDwtIHNlcSgtNCw0LGxlbmd0aD0xMDAwKSpzZSArIHANCmh4IDwtIGRub3JtKHgsIHAgLHNlKQ0KDQp1cHBlcl9ib3VuZCA8LSBwICsgMS45NiAqIHNlIA0KbG93ZXJfYm91bmQgPC0gcCAtIDEuOTYgKiBzZSANCg0KcGxvdCh4LCBoeCwgdHlwZT0ibiIsIHhsYWIgPSAiIiwgeWxhYj0iIiwgbWFpbj0iU2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGEgcHJvcG9ydGlvbiIsIGF4ZXM9RkFMU0UpDQoNCmkgPC0geCA+PSB1cHBlcl9ib3VuZCAmIHggPD0gbWF4KHgpICMgaW5kZXhlcyBvZiB4IHdoZXJlIHggPj0gdXBwZXJfYm91bmQNCmxpbmVzKHgsIGh4KSAjIHBsb3RzIG5vcm1hbCBkaXN0cmlidXRpb24NCnBvbHlnb24oYyh1cHBlcl9ib3VuZCx4W2ldLG1heCh4KSksIGMoMCxoeFtpXSwwKSwgY29sPSJncmV5IikgIyBzaGFkZXMgYXJlYSBncmV5IHdoZXJlIHggPj0gbG93ZXJfYm91bmQNCg0KaiA8LSB4ID49IG1pbih4KSAmIHggPD0gbG93ZXJfYm91bmQgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA8PSB0aGFuIGxvd2VyX2JvdW5kDQpwb2x5Z29uKGMobWluKHgpLHhbal0sbG93ZXJfYm91bmQpLCBjKDAsaHhbal0sMCksIGNvbD0iZ3JleSIpICMgc2hhZGVzIGFyZWEgZ3JleSB3aGVyZSB4IDw9IGxvd2VyX2JvdW5kDQoNCmF4aXMoMSwgYXQ9c2VxKDAuMywgMC43LCAwLjAyKSwgcG9zPTApICMgZHJhd3MgYXhpcw0KYWJsaW5lKHY9cCkNCmdyaWQoKQ0KDQpwX2hhdCA8LSAwLjU4DQpzZV9wX2hhdCA8LSBzcXJ0KHBfaGF0ICogKDEgLSBwX2hhdCkgLyBuKQ0KYXhpcygxLCBhdD1jKHBfaGF0IC0gMS45NiAqIHNlX3BfaGF0LCBwX2hhdCwgcF9oYXQgKyAxLjk2ICogc2VfcF9oYXQpLCBwb3M9LTEuNSwgY29sID0gImJsdWUiLCBsd2QgPSAyLCBsd2QudGlja3MgPSAxKSANCg0KdGV4dCh4ID0gMC4zMiwgeSA9IDcsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUocCwgIiA9IDAuNSIpKSkNCnRleHQoeCA9IDAuMzIsIHkgPSA2LjQsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUobiwgIiA9IDEwMCIpKSkNCnRleHQoeCA9IDAuMzI3LCB5ID0gNS43LCBsYWJlbHMgPSBleHByZXNzaW9uKHBhc3RlKFNFLCAiID0gMC4wNSIpKSkNCnRleHQoeCA9IDAuMzIsIHkgPSA1LjAsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUoaGF0KHApLCAiID0wLjU4IikpKQ0KdGV4dCh4ID0gMC4zMzYsIHkgPSA0LjIsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUoU0VbaGF0KHApXSwgIiA9MC4wNDkzNCIpKSkNCmBgYA0KDQpJZiB3ZSBhcmUgdW5sdWNreSBhbmQgIGRyYXcgYSBzYW1wbGUgd2hvc2UgcHJvcG9ydGlvbiAkXGhhdHtwfSQgZmFsbHMgaW4gdGhlIHNoYWRlZCBhcmVhLCB3aGljaCBzaG91bGQgb25seSBoYXBwZW4gJDVcJSQgb2YgdGhlIHRpbWUsIGl0cyAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCB3aWxsIG5vdCBpbmNsdWRlIHRoZSB0cnVlIHByb3BvcnRpb24gJHA9MC41JC4NCg0KYGBge3IsIGVjaG89RkFMU0V9DQojaHR0cDovL3d3dy5zdGF0bWV0aG9kcy5uZXQvYWR2Z3JhcGhzL3Byb2JhYmlsaXR5Lmh0bWwNCg0KbiA8LSAxMDANCnAgPC0gMC41MDsgc2UgPC0gc3FydChwICogKDEgLSBwKSAvIG4pDQoNCiMgeCA9IHAgKy8tIDQgc3RkX2RldidzDQp4IDwtIHNlcSgtNCw0LGxlbmd0aD0xMDAwKSpzZSArIHANCmh4IDwtIGRub3JtKHgsIHAgLHNlKQ0KDQp1cHBlcl9ib3VuZCA8LSBwICsgMS45NiAqIHNlIA0KbG93ZXJfYm91bmQgPC0gcCAtIDEuOTYgKiBzZSANCg0KcGxvdCh4LCBoeCwgdHlwZT0ibiIsIHhsYWIgPSAiIiwgeWxhYj0iIiwgbWFpbj0iU2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGEgcHJvcG9ydGlvbiIsIGF4ZXM9RkFMU0UpDQoNCmkgPC0geCA+PSB1cHBlcl9ib3VuZCAmIHggPD0gbWF4KHgpICMgaW5kZXhlcyBvZiB4IHdoZXJlIHggPj0gdXBwZXJfYm91bmQNCmxpbmVzKHgsIGh4KSAjIHBsb3RzIGRpc3RyaWJ1dGlvbiAjIHBsb3RzIG5vcm1hbCBkaXN0cmlidXRpb24NCnBvbHlnb24oYyh1cHBlcl9ib3VuZCx4W2ldLG1heCh4KSksIGMoMCxoeFtpXSwwKSwgY29sPSJncmV5IikgIyBwbG90cyBhcmVhIHdoZXJlIHggPj0gbXUNCg0KaiA8LSB4ID49IG1pbih4KSAmIHggPD0gbG93ZXJfYm91bmQgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA8PSB0aGFuIGxvd2VyX2JvdW5kDQpwb2x5Z29uKGMobWluKHgpLHhbal0sbG93ZXJfYm91bmQpLCBjKDAsaHhbal0sMCksIGNvbD0iZ3JleSIpICMgc2hhZGVzIGFyZWEgZ3JleSB3aGVyZSB4IDw9IGxvd2VyX2JvdW5kDQoNCmF4aXMoMSwgYXQ9c2VxKDAuMywgMC43LCAwLjAyKSwgcG9zPTApICMgZHJhd3MgYXhpcw0KYWJsaW5lKHY9cCkNCmdyaWQoKQ0KDQpwX2hhdCA8LSAwLjM4DQpzZV9wX2hhdCA8LSBzcXJ0KHBfaGF0ICogKDEgLSBwX2hhdCkgLyBuKQ0KYXhpcygxLCBhdD1jKHBfaGF0IC0gMS45NiAqIHNlX3BfaGF0LCBwX2hhdCwgcF9oYXQgKyAxLjk2ICogc2VfcF9oYXQpLCBwb3M9LTEuNSwgY29sID0gInJlZCIsIGx3ZCA9IDIsIGx3ZC50aWNrcyA9IDEpIA0KDQp0ZXh0KHggPSAwLjMyLCB5ID0gNywgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShwLCAiID0gMC41IikpKQ0KdGV4dCh4ID0gMC4zMiwgeSA9IDYuNCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShuLCAiID0gMTAwIikpKQ0KdGV4dCh4ID0gMC4zMjcsIHkgPSA1LjcsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUoU0UsICIgPSAwLjA1IikpKQ0KdGV4dCh4ID0gMC4zMiwgeSA9IDUuMCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShoYXQocCksICIgPTAuMzgiKSkpDQp0ZXh0KHggPSAwLjMzNiwgeSA9IDQuMiwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShTRVtoYXQocCldLCAiID0wLjA0ODU0IikpKQ0KYGBgDQoNCiMjIyA0LjIgQ29uZGl0aW9ucyBmb3IgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwNCg0KVGhlIGNvbmRpdGlvbnMgZm9yIHRoZSB2YWxpZGl0eSBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBhcmU6DQoNCjEuIFNhbXBsZWQgb2JzZXJ2YXRpb25zIG11c3QgYmUgaW5kZXBlbmRlbnQuDQoNCjIuIFdlIGV4cGVjdCBhdCBsZWFzdCAxMCBzdWNjZXNzZXMgYW5kIDEwIGZhaWx1cmVzIGluIHRoZSBzYW1wbGUsIGkuZS4sICRuXGNkb3RcaGF0e3B9XGdlcTEwJCBhbmQgJG5cY2RvdCgxLVxoYXR7cH0pXGdlcTEwJC4NCg0KVGhlIGZpcnN0IGNyaXRlcmlhIGZvciB0aGlzIHJhbmRvbSBzYW1wbGUgY2FuIGJlIHZlcmlmaWVkIGJ5IGNoZWNraW5nIHRoYXQgdGhlIG9ic2VydmF0aW9ucyBjb21lIGZyb20gYSBzaW1wbGUgcmFuZG9tIHNhbXBsZSBhbmQgcmVwcmVzZW50IGxlc3MgdGhhbiAkMTBcJSQgb2YgdGhlIHBvcHVsYXRpb24uIFRoZSBwb3B1bGF0aW9uIGNvbnNpc3RzIG9mIEFtZXJpY2FucyB3aG8gd29yayBwYXJ0LXRpbWUgb3IgZnVsbC10aW1lLCBhbmQgdGhlIHNhbXBsZSBzaXplIGNhbiBiZSBjb21wdXRlZCBieSBSIGFzDQoNCmBgYHtyfQ0KbiA8LSBsZW5ndGgoZ3NzMjAxNl93cmtzdGF0KQ0KY2F0KCJTYW1wbGUgc2l6ZSBuID0iLCBuKQ0KYGBgDQoNCmFuZCBpdCBpcyBjZXJ0YWlubHkgbGVzcyB0aGFuICQxMFwlJCBvZiB0aGUgcG9wdWxhdGlvbi4gDQoNCkZvciB0aGUgc2Vjb25kIGNyaXRlcmlhLCBzaW5jZSB3ZSBkb24ndCBrbm93ICRwJCwgd2Ugd2lsbCB1c2Ugb3VyIHBvaW50IGVzdGltYXRlICRcaGF0e3B9JCwgd2hpY2ggY2FuIGJlIGNvbXB1dGVkIHVzaW5nIFI6DQoNCmBgYHtyfQ0KcF9oYXQgPC0gdGFibGUoZ3NzMjAxNiR3cmtzdGF0KVsid29ya2luZyBmdWxsdGltZSJdIC8gc3VtKHRhYmxlKGdzczIwMTZfd3Jrc3RhdCkpDQpwX2hhdCA8LSBhcy5udW1lcmljKHBfaGF0KQ0KY2F0KCJFc3RpbWF0ZSBvZiBwcm9wb3J0aW9uIHdvcmtpbmcgZnVsbC10aW1lID0iLCBwX2hhdCkNCmBgYA0KDQphbmQgc28gdGhlIG51bWJlciBvZiBzdWNjZXNzZXMgaXMNCg0KYGBge3J9DQpudW1iZXJfb2Zfc3VjY2Vzc2VzIDwtIGZsb29yKG4gKiBwX2hhdCkNCmNhdCgiTnVtYmVyIG9mIHN1Y2Nlc3NlczoiLCBudW1iZXJfb2Zfc3VjY2Vzc2VzKQ0KYGBgDQoNCmFuZCB0aGUgbnVtYmVyIG9mIGZhaWx1cmVzDQoNCmBgYHtyfQ0KbnVtYmVyX29mX2ZhaWx1cmVzIDwtIGZsb29yKG4gKiAoMSAtIHBfaGF0KSkNCmNhdCgiTnVtYmVyIG9mIGZhaWx1cmVzOiIsIG51bWJlcl9vZl9mYWlsdXJlcykNCmBgYA0KDQpib3RoIG9mIHdoaWNoIGFyZSBtdWNoIGdyZWF0ZXIgdGhhbiAkMTAkLg0KDQojIyMgNC4zIENyaXRpY2FsIHZhbHVlICR6XiokDQoNClRoZSAkel4qJCBjb3JyZXNwb25kaW5nIHRvIGEgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaW4gdGhlIFtzdGFuZGFyZCBub3JtYWwgZGlzdHJpYnV0aW9uXShodHRwczovL3d3dy5tYXRoc2lzZnVuLmNvbS9kYXRhL3N0YW5kYXJkLW5vcm1hbC1kaXN0cmlidXRpb24tdGFibGUuaHRtbCkgaXMgYXBwcm94aW1hdGVseSAxLjk2LiBXZSBjYW4gY29tcHV0ZSBpdCBtb3JlIGV4YWN0bHkgdXNpbmcgUjoNCg0KYGBge3J9DQp6X3N0YXIgPC0gcW5vcm0ocCA9IDAuMDI1LCBtZWFuID0gMCwgc2QgPSAxLCBsb3dlci50YWlsID0gRkFMU0UpDQpjYXQoInotdmFsdWUgY29ycmVzcG9uZGluZyB0byA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbDoiLCB6X3N0YXIpDQpgYGANCg0KIyMjIDQuNCBTdGFuZGFyZCBlcnJvciBvZiB0aGUgc2FtcGxlDQoNClRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgc2FtcGxlIGlzDQpgYGB7cn0NCnNlX3BfaGF0IDwtIHNxcnQocF9oYXQgKiAoMSAtIHBfaGF0KSAvIG4pDQpjYXQoIlN0YW5kYXJkIGVycm9yIFNFID0iLCBzZV9wX2hhdCkNCmBgYA0KDQojIyMgNC41IENvbmZpZGVuY2UgaW50ZXJ2YWwNCg0KQ29tcHV0aW5nIHRoZSBjb25maWRlbmNlIGludGVydmFsIGJvdW5kcw0KDQpgYGB7cn0NCmNvbmZfaW50X2xiIDwtIHBfaGF0IC0gel9zdGFyICogc2VfcF9oYXQNCmNvbmZfaW50X3ViIDwtIHBfaGF0ICsgel9zdGFyICogc2VfcF9oYXQNCmNhdCgiQ29uZmlkZW5jZSBpbnRlcnZhbCBsb3dlciBib3VuZDoiLCBjb25mX2ludF9sYiwgIlxuQ29uZmlkZW5jZSBpbnRlcnZhbCB1cHBlciBib3VuZDoiLCBjb25mX2ludF91YikNCmBgYA0KDQpIZW5jZSwgb3VyIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMNCiQkDQowLjQ2MTJccG0gMS45NlxjZG90IDAuMDA5Mz0oMC40NDMwLCAwLjQ3OTUpDQokJA0KDQpXZSBhcmUgJDk1XCUkIGNvbmZpZGVudCB0aGF0IHRoZSB0cnVlIHByb3BvcnRpb24gb2YgQW1lcmljYW5zIGVtcGxveWVkIGZ1bGwtdGltZSBpcyBiZXR3ZWVuICQwLjQ0MzAkIGFuZCAkMC40Nzk1JC4NCg0KIyMgNS4wIEh5cG90aGVzaXMgdGVzdGluZw0KDQpXZSBjYW4gdXNlIHRoZSBDTFQgYW5kIHRoZSBkYXRhIGNvbGxlY3RlZCB0byBjb25zdHJ1Y3QgYSBoeXBvdGhlc2lzIHRlc3RpbmcgZnJhbWV3b3JrLiBUaGUgaHlwb3RoZXNpcyB0ZXN0IGNvbnNpZGVycyB0d28gcG9zc2libGUgaW50ZXJwcmV0YXRpb25zIG9mIG91ciBkYXRhLCBhIG51bGwgaHlwb3RoZXNpcyAkSF8wJCwgYW5kIGFuIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgJEhfYSQuICRIXzAkIGJhc2ljYWxseSBzYXlzIHRoYXQgdGhlIHNhbXBsZWQgZGF0YSBjb3VsZCBoYXZlIGJlZW4gZHJhd24gc2ltcGx5IGJ5IGNoYW5jZSwgYW5kIHNvLCBpdCBpcyBtaXNsZWFkaW5nLiBUaGVyZSBpcyAibm90aGluZyBnb2luZyBvbiIuICRIX2EkIHRha2VzIHRoZSB2aWV3IHRoYXQgdGhlIGRhdGEgY29sbGVjdGVkIHJldmVhbHMgdGhhdCAic29tZXRoaW5nICppcyogZ29pbmcgb24iLiBXZSB3aWxsIGVpdGhlciByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBpbiBmYXZvciBvZiB0aGlzIGFsdGVybmF0aXZlLCBvciB3ZSB3aWxsIGZhaWwgdG8gcmVqZWN0IGl0IGFuZCBjb25jbHVkZSB0aGUgc2FtcGxlZCBkYXRhIGNvdWxkIGhhdmUgYmVlbiBkcmF3biBzaW1wbHkgYnkgY2hhbmNlLiBOb3RlIHRoYXQgZXZlbiBpZiB3ZSBmYWlsIHRvIHJlamVjdCAkSF8wJCwgdGhhdCBkb2VzIG5vdCBtZWFuIHdlIGFjY2VwdCBpdCBhcyB0aGUgZ3JvdW5kIHRydXRoLCBpdCdzIGp1c3QgdGhhdCB0aGUgZGF0YSB3ZSBoYXZlIGNvbGxlY3RlZCBkb2VzIG5vdCBhbGxvd3MgdXMgdG8gZGlzY2FyZCAkSF8wJC4NCg0KRm9yIGV4YW1wbGUsIGNhbiB0cnkgdG8gYW5zd2VyIHdoZXRoZXIgdGhlIHByb3BvcnRpb24gb2YgQW1lcmljYW5zIHdobyB3b3JrIGZ1bGwtdGltZSBpcyBncmVhdGVyIHRoYW4gMC40NS4gVGhlIGZyYW1ld29yayBmb3IgdGhlIGh5cG90aGVzaXMgdGVzdCB3b3VsZCBiZSBhcyBmb2xsb3dzOg0KDQokJA0KSF97MH06VGhlXCB0cnVlXCBwcm9wb3J0aW9uXCBvZlwgQW1lcmljYW5zXCB3aG9cIHdvcmtcIGZ1bGwtdGltZVwgaXNcIHBfMD0wLjQ1DQpcXA0KSF97YX06VGhlXCB0cnVlXCBwcm9wb3J0aW9uXCBvZlwgQW1lcmljYW5zXCB3aG9cIHdvcmtcIGZ1bGwtdGltZVwgaXNcIGdyZWF0ZXJcIHRoYW5cIHBfMD0wLjQ1DQokJA0KDQpUbyBwZXJmb3JtIHRoZSB0ZXN0LCB3ZSBhc3N1bWUgdGhhdCAkSF8wJCBpcyB0cnVlIGFuZCBhc2ssIGdpdmVuIHRoYXQgJEhfMCQgaXMgdHJ1ZSwgaG93IHByb2JhYmxlIGl0IGlzIHRvIG9ic2VydmUgZGF0YSBhcyBleHRyZW1lIG9yIG1vcmUgYXMgdGhlIG9uZSB3ZSBoYXZlLg0KDQojIyMgNS4xIFRoZSBudWxsIGh5cG90aGVzaXMgcHJvcG9ydGlvbiAkcF8wJA0KDQpTaW5jZSBpbiB0aGUgaHlwb3RoZXNpcyB0ZXN0IHdlIGFzc3VtZSB0aGF0ICRIXzAkIGlzIHRoZSB0cnV0aCBhbmQgdGhlIHRydWUgcHJvcG9ydGlvbiBvZiBBbWVyaWNhbnMgd2hvIHdvcmsgZnVsbC10aW1lIGlzICRwXzAgPSAwLjQ1JCwgd2Ugd2lsbCB1c2UgJHBfMCQgdG8gY29tcHV0ZSAkU0Vfe3BfMH0kLCB0aGUgc3RhbmRhcmQgZXJyb3IgdW5kZXIgdGhlIG51bGwgaHlwb3RoZXNpcy4NCmBgYHtyfQ0KcF9udWxsIDwtIDAuNDUNCnNlX3BfbnVsbCA8LSBzcXJ0KHBfbnVsbCAqICgxIC0gcF9udWxsKSAvIG4pDQpjYXQoIlN0YW5kYXJkIGVycm9yIHVuZGVyIHRoZSBudWxsIGh5cG90aGVzaXM6Iiwgc2VfcF9udWxsKQ0KYGBgDQoNCiMjIyA1LjIgQ29uZGl0aW9ucyBmb3IgaHlwb3RoZXNpcyB0ZXN0aW5nDQoNClRoZSBjb25kaXRpb25zIHRvIHBlcmZvcm0gdGhlIGh5cG90aGVzaXMgdGVzdCBhcmUgc2ltaWxhciB0byB0aGUgb25lcyB3ZSBjaGVja2VkIHRvIGNvbXB1dGUgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwuDQoNCjEuIFNhbXBsZWQgb2JzZXJ2YXRpb25zIG11c3QgYmUgaW5kZXBlbmRlbnQuDQoNCjIuIEVhY2ggc2FtcGxlIHNob3VsZCBoYXZlIGF0IGxlYXN0IDEwIHN1Y2Nlc3NzZXMgYW5kIDEwIGZhaWx1cmVzLiBXZSB1c2UgdGhlIG51bGwgaHlwb3RoZXNpcyBwcm9wb3J0aW9uICRwXzAkIHRvIGNvbXB1dGUgdGhlIG51bWJlcnMgb2Ygc3VjY2Vzc2VzIGFuZCBmYWlsdXJlcy4NCg0KJCQNCm5cY2RvdCBcaGF0e3BfMH1cZ2VxIDEwXFwgblxjZG90ICgxIC0gXGhhdHtwXzB9KVxnZXEgMTANCiQkDQoNClZlcmlmeWluZyB0aGUgc3VjY2Vzcy1mYWlsdXJlIGNvbmRpdGlvbnMgZm9yIGh5cG90aGVzaXMgdGVzdGluZw0KYGBge3J9DQpudW1iZXJfb2Zfc3VjY2Vzc2VzIDwtIGZsb29yKG4gKiBwX251bGwpDQpudW1iZXJfb2ZfZmFpbHVyZXMgPC0gZmxvb3IobiAqICgxIC0gcF9udWxsKSkNCmNhdCgiTnVtYmVyIG9mIHN1Y2Nlc3NlczoiLCBudW1iZXJfb2Zfc3VjY2Vzc2VzLCAiXG5OdW1iZXIgb2YgZmFpbHVyZXM6IiwgbnVtYmVyX29mX2ZhaWx1cmVzKQ0KYGBgDQoNClRoZSBzdWNjZXNzLWZhaWx1cmUgY29uZGl0aW9ucyBhcmUgc2F0aXNmaWVkLg0KDQojIyMgNS4zIFRoZSBwLXZhbHVlDQoNClRoZSBwLXZhbHVlIHF1YW50aWZpZXMgdGhlIHN0cmVuZ3RoIG9mIHRoZSBldmlkZW5jZSBhZ2FpbnN0IHRoZSBudWxsIGh5cG90aGVzaXMuIFdlIGNvbXB1dGUgaXQgYnkgYXNraW5nIG91cnNlbHZlcywgZ2l2ZW4gdGhhdCB0aGUgbnVsbCBoeXBvdGhlc2lzICRIXzAkIGlzIHRydWUsIHdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IG9mIG9ic2VydmluZyBkYXRhIGFzIGV4dHJlbWUgb3IgbW9yZSBhcyB0aGUgb25lIHdlIGhhdmUuDQoNCiQkDQpQKG9ic2VydmluZ1wgZGF0YVwgYXNcIGV4dHJlbWVcIG9yXCBtb3JlXCB8XCBIX3swfVwgaXNcIHRydWUpDQokJA0KDQpUaGF0IHByb2JhYmlsaXR5IGlzIHRoZSBwLXZhbHVlLiBUeXBpY2FsbHksIHdlIHVzZSBhICQ1XCUkIHNpZ25pZmljYW5jZSBsZXZlbCBhcyB0aGUgdGhyZXNob2xkIHRvIHJlamVjdCB0aGUgbnVsbC4gSWYgdGhlIHAtdmFsdWUgaXMgbGVzcyB0aGFuICQ1XCUkLCB3ZSByZWplY3QgdGhlIG51bGwgaW4gZmF2b3Igb2YgdGhlIGFsdGVybmF0aXZlLg0KDQpGb3Igb3VyIGh5cG90aGVzaXMgZnJhbWV3b3JrLCB1bmRlciAkSF8wJCBhbmQgdGhlIENMVCwgJFxoYXR7cH0kIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQsIHdpdGggJHAgPSBwXzAgPSAwLjQ1JCBhbmQgJFNFX3twX3swfX09MC4wMDkzJC4gV2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgb2YgZHJhd2luZyBhIHNhbXBsZSB3aXRoIGEgcHJvcG9ydGlvbiAkXGhhdHtwfT0wLjQ2MTI0JCBvciBoaWdoZXIsIGdpdmVuIHRoYXQgdGhlIG51bGwgaHlwb3RoZXNpcyBpcyB0cnVlPw0KDQokJA0KUChkcmF3aW5nXCBhXCBzYW1wbGVcIHdoZXJlXCB0aGVcIHByb3BvcnRpb25cIG9mXCBBbWVyaWNhbnNcXCBlbXBsb3llZFwgZnVsbC10aW1lXCBpc1wgMC40NjEyXCBvclwgaGlnaGVyXCB8XCBIX3swfVwgaXNcIHRydWUpDQpcXA0KUChcaGF0e3B9XCBcZ2VxXCAwLjQ2MTI0XCB8XCBwID0gIDAuNDUpDQokJA0KDQpXZSBjYW4gZG8gaXQgZ3JhcGhpY2FsbHk6DQpgYGB7cn0NCiNodHRwOi8vd3d3LnN0YXRtZXRob2RzLm5ldC9hZHZncmFwaHMvcHJvYmFiaWxpdHkuaHRtbA0KDQojIHggPSBwX251bGwgKy8tIDQgc3RkX2RldidzDQp4IDwtIHNlcSgtNCw0LGxlbmd0aD0xMDAwKSpzZV9wX251bGwgKyBwX251bGwNCmh4IDwtIGRub3JtKHgsIHBfbnVsbCAsc2VfcF9udWxsKQ0KDQpsYiA8LSBwX2hhdDsgdWIgPC0gbWF4KHgpIA0KDQpwbG90KHgsIGh4LCB0eXBlPSJuIiwgeGxhYj0iUHJvcG9ydGlvbiBvZiBBbWVyaWNhbnMgZW1wbG95ZWQgZnVsbC10aW1lIiwgeWxhYj0iIiwgbWFpbj0iU2FtcGxpbmcgZGlzdHJpYnV0aW9uIHVuZGVyIG51bGwgaHlwb3RoZXNpcyIsIGF4ZXM9RkFMU0UpDQoNCmkgPC0geCA+PSBsYiAmIHggPD0gdWIgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA+PSB0aGFuIGxiIGFuZCA8PSB0aGFuIHViDQpsaW5lcyh4LCBoeCkgIyBwbG90cyBub3JtYWwgZGlzdHJpYnV0aW9uDQpwb2x5Z29uKGMobGIseFtpXSx1YiksIGMoMCxoeFtpXSwwKSwgY29sPSJyZWQiKSAjIHNoYWRlcyBhcmVhIHdoZXJlIHggPj0gbGIgaW4gcmVkDQoNCmF4aXMoMSwgYXQ9c2VxKDAuNDEsIDQ5LCAwLjAwNSksIHBvcz0wKSAjIGRyYXdzIGF4aXMNCmFibGluZSh2PXBfbnVsbCkNCmdyaWQoKQ0KYGBgDQoNClRoYXQgcHJvYmFiaWxpdHkgaXMgdGhlIGFyZWEgdW5kZXIgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBzaGFkZWQgaW4gcmVkIGluIHRoZSBwbG90LiBJdCBjYW4gYmUgY29tcHV0ZWQgdXNpbmcgYHBub3JtKClgLg0KYGBge3J9DQphcmVhIDwtIHBub3JtKHEgPSBwX2hhdCwgbWVhbiA9IHBfbnVsbCwgc2QgPSBzZV9wX251bGwsIGxvd2VyLnRhaWwgPSBGQUxTRSkNCmNhdCgiT3VyIHAtdmFsdWU6IiwgYXJlYSkNCmBgYA0KDQpTbyBvdXIgW3AtdmFsdWVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1AtdmFsdWUpLCB0aGUgcHJvYmFiaWxpdHkgb2YgZHJhd2luZyBhIHNhbXBsZSB3aXRoICRcaGF0e3B9PTAuNDYxMjQzJCBvciBoaWdoZXIgdW5kZXIgdGhlIG51bGwgaHlwb3RoZXNpcywgaXMgYWJvdXQgJDAuMTEzJC4gVGhhdCBwcm9iYWJpbGl0eSBpcyBoaWdoLiBBdCB0aGUgJDVcJSQgc2lnbmlmaWNhbmNlIGxldmVsLCB3ZSBjYW4ndCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpczogYSBzYW1wbGUgcHJvcG9ydGlvbiBvZiAkXGhhdHtwfT0wLjQ2MTI0MyQgb3IgaGlnaGVyIGNvdWxkIGhhcHBlbiBzaW1wbHkgYnkgY2hhbmNlIGlmIHRoZSB0cnVlIHByb3BvcnRpb24gaXMgJDAuNDUkLg0KDQojIyBSZWZlcmVuY2VzDQoNCjEuIMOHZXRpbmtheWEtUnVuZGVsLCBNLiAqKipEYXRhIEFuYWx5c2lzIGFuZCBTdGF0aXN0aWNhbCBJbmZlcmVuY2UqKiouIFNwcmluZyAyMDE0LiBbQ291cnNlcmFdKHd3dy5jb3Vyc2VyYS5vcmcpLg0KDQoyLiBEaWV6LCBELiwgQmFyciwgQy4sIMOHZXRpbmtheWEtUnVuZGVsLCBNLiAqKipPcGVuSW50cm8gU3RhdGlzdGljcywgU2Vjb25kIEVkaXRpb24qKiouIFBERi4NCg0KMy4gTmF2aWRpLCBXLiAqKipTdGF0aXN0aWNzIGZvciBlbmdpbmVlcnMgYW5kIHNjaWVudGlzdHMsIFRoaXJkIEVkaXRpb24qKiouIE5ldyBZb3JrOiBNY0dyYXcgSGlsbCwgMjAxMS4NCg0KNC4gVUNMQSBJbnN0aXR1dGUgZm9yIERpZ2l0YWwgUmVzZXJhY2ggYW5kIEVkdWNhdGlvbiwgKioqSE9XIENBTiBJIElOQ0xVREUgR1JFRUsgTEVUVEVSUyBJTiBNWSBQTE9UIExBQkVMUz8gfCBSIENPREUgRlJBR01FTlRTKioqLiBSZXRyaWV2ZWQgZnJvbSBbaHR0cHM6Ly9zdGF0cy5pZHJlLnVjbGEuZWR1XShodHRwczovL3N0YXRzLmlkcmUudWNsYS5lZHUvci9jb2RlZnJhZ21lbnRzL2dyZWVrX2xldHRlcnMvKQ0KDQo1LiBLYWJhY29mZiwgUi4gKioqUHJvYmFiaWxpdHkgUGxvdHMqKiouIFJldHJpZXZlZCBmcm9tIFtodHRwOi8vd3d3LnN0YXRtZXRob2RzLm5ldF0oaHR0cDovL3d3dy5zdGF0bWV0aG9kcy5uZXQvYWR2Z3JhcGhzL3Byb2JhYmlsaXR5Lmh0bWwpDQoNCjYuIENhcmxvcyBDaW5lbGxpIGFuZCBUb20sICoqKkNvZGUgY2h1bmsgZm9udCBzaXplIGluIFJtYXJrZG93biB3aXRoIGtuaXRyIGFuZCBsYXRleCoqKi4gUmV0cmlldmVkIGZyb20gW2h0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb21dKGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzI1NjQ2MzMzL2NvZGUtY2h1bmstZm9udC1zaXplLWluLXJtYXJrZG93bi13aXRoLWtuaXRyLWFuZC1sYXRleCkNCg0KNy4gRHJld0NvbndheSBhbmQgQ2hyaXN0b3BoZXIgRHVCb2lzLCAqKipHZXR0aW5nIExhVGVYIGludG8gUiBQbG90cyoqKi4gUmV0cmlldmVkIGZyb20gW2h0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb21dKGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEzOTUxMDUvZ2V0dGluZy1sYXRleC1pbnRvLXItcGxvdHMp