Introduction
Simple Linear Regression (SLR) is a statistical method used to model
the relationship between a single independent (predictor) variable
(\(X\)) and a dependent (response)
variable (\(Y\)). It assumes a linear
relationship between the two variables and is widely used for prediction
and inference.
Purpose of Simple Linear Regression
To quantify the relationship between \(X\) and \(Y\). For example, price vs. demand in
economics, drug dosage vs. effect in medicine, stress vs. material
strain in engineering, etc..
To predict the value of \(Y\)
for a given value of \(X\). For
example, we may want to use house footage to predict the house
price.
To test hypotheses about the relationship between \(X\) and \(Y\). For example, we may want to test
whether hours of study influence the course grade.
Structure of the Simple
Linear Regression Model
The simple linear regression (SLR) model is represented as
\[
Y=\beta_0 + \beta_1 X + \epsilon
\]
Where \(Y\) is a dependent variable
(response), \(X\) is an independent
variable (predictor) which is assumed to be
non-random. \(\beta_0\)
is the intercept (value of \(Y\) when
\(X = 0\)), \(\beta_1\) is the slope (the change in \(Y\) per unit change in \(X\)). \(\epsilon\) = ““residual** random error term
(assumed \(\epsilon \rightarrow
N(0,\sigma^2)\), see the assumptions of the linear regression
model in the subsequent section).
For example, the practical regression between price and demand is
expressed in the following.
\[
\text{price} = \beta_0 + \beta_1\times \text{demand} + \epsilon.
\]
With a given dataset, we can estimate \(\beta_0\) and \(\beta_1\) using the least squares method,
denoted respectively by \(b_0\) and
\(b_1\). The estimated regression line
(fitted model) is:
\[
\hat{Y} = b_0 + b_1 X.
\]
The estimated residuals are defined to be the
estimated value \(\hat{Y}\) and the
observed \(Y\) from the data set. In R,
we can extract estimated \(\hat{Y}\)
and residuals using R commands fitted(model.name)
and
`resid(model.name``
Example 1: Simple linear regression to assess the
relationship between study hours and course grade. We
us simulated data in the following R code
##
## Call:
## lm(formula = course_grade ~ study_hours, data = example.data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.38182 -0.58182 0.02727 0.45909 1.43636
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 54.7636 0.7155 76.54 9.46e-13 ***
## study_hours 2.4364 0.1007 24.20 9.07e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.9145 on 8 degrees of freedom
## Multiple R-squared: 0.9865, Adjusted R-squared: 0.9848
## F-statistic: 585.5 on 1 and 8 DF, p-value: 9.075e-09
The annotation of the output is depicted in the following.

The estimated Y, denoted by \(\hat{Y}\) (commonly called fitted Y) and
estimated residual \(e = Y - \hat{Y}\)
can be extracted from the above model in the following R code.
## Y Y.hat e.hat
## 1 60 59.63636 0.3636364
## 2 63 62.07273 0.9272727
## 3 65 64.50909 0.4909091
## 4 66 66.94545 -0.9454545
## 5 68 69.38182 -1.3818182
## 6 72 71.81818 0.1818182
## 7 74 74.25455 -0.2545455
## 8 76 76.69091 -0.6909091
## 9 79 79.12727 -0.1272727
## 10 83 81.56364 1.4363636
You see from the above output that
Y - Y.hat = e.hat
.
Assumptions of Simple
Linear Regression
For valid inference and predictions, SLR relies on the following
assumptions:
- Linearity: The relationship between \(X\) and \(Y\) is linear. This can be visually checked
by a simple scatter plot for SLR (i.e., with only one predictor
variable). We can check the linearity of the above example using the
following R code.

Independence: Errors (\(\epsilon\)) are independent (no
autocorrelation). This is hard to check in this level of statistics
course.
Homoscedasticity: Constant variance of errors across \(X\). Since \(X\) is assumed to be non-random, the
variance of \(Y\) is the same as the
residual \(\epsilon\). In practice, we
check whether the variance of the estimated residual errors \(e = Y - \hat{Y}\).

In the above grade-study example, we can plot the residual in the
following.

It turns out that the residuals does not have a
constant variance across the fitted values.
- Normality: Errors are normally distributed. There
are testing hypothesis procedures for normality. In practice, we only
use visual checks for normality. QQ-plot
(quantile-quantile plot) is a commonly used visual tool. It compares the
distribution of the estimated residuals with a set of true normally
distributed values. The following QQ-plot was generated
from R code.
The R functions qqnorm()
and qqline()
in
package {stats} can draw the qq-plot and the reference
line. The following code shows how to draw the QQ-plot and reference
line based on the above example.

Model Diagnostics
In practice, it is quite often to have different methods under
different assumptions to solve the same problem. The goals of an analyst
are to validate each individual model based on the related assumption
and then choose the best model to implement (report). The process of
validating a model is called model diagnosis.
As discussed in the previous section, most of the assumptions are
related to the residual errors. This section will focus on
residual analysis by analyzing the patterns in various
residual plots.
- Residual Plots - Residuals vs Fitted: Checking for
non-linearity & heteroscedasticity.

- Q-Q Plot: Check normality of residuals.

- Influence Measures - Cook’s Distance: Detects
influential observations that impact the regression model (line)
significantly. To read the plot of Cook’s distance, you need to have a
clear understanding of three definitions:
1. Outlier - an observation that lies an
abnormal distance from other values in the dataset.
2. Leverage - a measure of how far an
independent variable (X) deviates from its mean.
3. Influential Point - an observation that
significantly alters the regression coefficients if removed.
The following YouTube video explains these concepts clearly.
The following table explains the three concepts and diagnostic
measures.
Outlier |
Atypical Y value |
Residual magnitude |
Standardized residuals |
Leverage |
Extreme X value |
X position only |
leverage measure |
Influence |
Impact on model |
Both X and Y |
Cook’s Distance |
- Relationship Between Outliers, Leverage, and Influential
Points
The following table explains the relationship.
Normal point |
Low |
Small |
No |
Vertical outlier |
Low |
Large |
Minimal |
Good leverage point |
High |
Small |
No |
Bad leverage point |
High |
Large |
Yes |
- Graphical Illustration of These Concepts

Inference About
Regression Coefficients
We perform hypothesis tests to determine if the relationship is
statistically significant. Recall that the equation of the simple linear
regression model is
\[
Y = \beta_0 + \beta_1 X + \epsilon.
\] \(X\) is a numeric or binary
(has two possible distinct values, such as STEM-major
and
non-STEM-major
, yes
and no
,
disease
and disease-free
, etc.).
If the slope \(\beta_1 = 0\), the
above regression model is reduced to \(Y =
\beta_0 + \epsilon\), In this case, any changes in \(X\) will not influence
\(Y\). We call \(X\) and \(Y\) uncorrelated.
In practice, we only need to test whether \(\beta_1 = 0\) to assess the linear
relationship between \(Y\) and \(X\). As shown earlier, the output in R
provides hypothesis testing on both \(beta_0 =
0\) and \(\beta_1 = 0\)
respectively. The following screenshot from R linear regression provides
all the information for inference of regression coefficients.

NOTE: The degrees of freedom of the
t-test in linear regression is defined to be: df = n - #
coefficients!
t-test for Slope
(\(\beta_1\))
\[
H_0: \ \ \beta_1 = 0 \ \ \text{v.s.} \ \ \beta_1 \ne 0
\]
In the Course-grade and Study-time example, the
sample size = 10. The test Statistic for testing the above hypothesis is
defined as
\[
TS = \frac{b_1 - 0}{\text{SE}(b_1)} \rightarrow t_{10-2}
\]
We use the information in the output to evaluate the above test
statistic and obtain
\[
TS = \frac{2.4364 - 0}{0.1007} = 24.02.
\]
The p-value of the two-tailed test based on the distribution with 8
degrees of freedom is \(\text{p-value} =
P(TS>24.02) = 9.618379e-09 \approx 0\). We can use the
following R code to calculate the p-value.
## [1] 9.618379e-09
Using significance level \(\alpha =
0.05\), we fail to reject the null hypothesis
\(H_0: \beta = 0\). This implies that
study-hours influence the course grade significantly
since p-value \(\approx 0\) < the
significance level 0.05.
Remarks:
(1). pt(24.02, 8)
gives the left-tail
area. The right-tail area is
(1-pt(24.02, 8))
.

- We have learned from the previous introductory statistics that the
p-value of a two-tailed test is equal to two times the smaller tail
area.
Confidence Interval
for Slope
Using the information in the output, we can also construct the 95%
confidence interval of the slope. Recall that the confidence of the
population mean has the following general form.
\[
\bar{x} \pm CV\times \frac{s}{\sqrt{n}}
\]
The confidence interval of the slope (\(\beta_1\)) has a similar form given
below.
\[
b_1 \pm CV\times \text{SE}(b_1),
\]
Where \(b_1\) and \(\text{SE}(b_1)\) are given in the R output
(see the above screenshot). CV (critical value) is based on the
t-distribution with n - # coefficients
(in this study-time
and grade example, 10 -2 = 8). Let’s use a confidence level of 95%, the
critical value can be found using the R command
qt(0.975,8)
, which gives 2.306. The confidence level and
critical value are labeled on the following t-density curve.

Based on the above explanation, the 95% confidence interval of \(\beta_1\) is given by
\[
b_1 \pm CV\times \text{SE}(b_1) = 2.4364 \pm 2.306\times 0.1007 =
(2.204186, 2.668614).
\]
Summary
1. Structure
Models the relationship between one predictor (X) and one response
(Y).
Equation: \(Y = \beta_0 +
\beta_1 X + \epsilon\). Two regresson coefficients are intercept
\((\beta_0)\) and slope \((\beta_1)\). \(\epsilon\) is the random error.
2. Assumptions
Linearity: The Relationship between X and Y is
linear.
Independence: Residuals are uncorrelated (no
autocorrelation).
Homoscedasticity: Constant variance of residuals across
X.
Normality: Residuals are normally distributed (important
for inference).
3. Diagnostics
Residual plots: Check for patterns (non-linearity,
heteroscedasticity).
Q-Q plot: Assess normality of residuals.
Leverage/Cook’s distance: Identify influential points.
R-squared: Proportion of variance explained by X.
4. Interpretation
Slope (\(\beta_1\)):
Change in Y per unit increase in X.
Intercept (\(\beta_0\):
Expected Y when X = 0 (may not always be meaningful).
R-squared: between 0 and 1; higher = better fit (but
doesn’t imply causation).
5. Inference
Hypothesis test on \(\beta_1\): \(H_0: \beta_1 = 0 \ \ \text{v.s} \ \ H_a: \beta_1
\ne 0\). Use a t-test for significance.
Confidence interval of \(\beta_1\): Range for \(\beta_1\). \(b_1
\pm t_{\text{df}, \ \ 1-\alpha/2}\)
p-value: Probability of observing the slope under \(H_0: \beta_1 = 0\).
6. Key R Functions
Fit model: lm(Y ~ X, data)
Summarize: summary(model)
. need to understand
estimated regression coefficients, R-squared, p-values, etc.
Diagnostics:
- plot(model) (residual plots).
- qqnorm(resid(model)) (normality check).
Predictions: predict(model, newdata)
LS0tDQp0aXRsZTogIkxpbmVhciBSZWdyZXNzaW9uOiBSZXZpZXcsIEV4dGVuc2lvbiBhbmQgRGlhZ25vc2lzIg0KYXV0aG9yOiAiQ2hlbmcgUGVuZyINCmRhdGU6ICIgU1RBMjAwOiBTdGF0aXN0aWNzIElJIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogNQ0KICAgIGZpZ19oZWlnaHQ6IDQNCi0tLQ0KDQpgYGB7Y3NzIGVjaG8gPSBGQUxTRX0NCg0KZGl2I1RPQyBsaSB7DQogICAgbGlzdC1zdHlsZTpub25lOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCmgxLnRpdGxlIHsNCiAgZm9udC1zaXplOiAyNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDIwcHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IGRhcmtyZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgyIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBuYXZ5Ow0KICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMTZweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCmBgYA0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KICAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBGQUxTRSwgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IFRSVUUsICAgDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFKQ0KYGBgDQoNCiMgSW50cm9kdWN0aW9uDQoNClNpbXBsZSBMaW5lYXIgUmVncmVzc2lvbiAoU0xSKSBpcyBhIHN0YXRpc3RpY2FsIG1ldGhvZCB1c2VkIHRvIG1vZGVsIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBhIHNpbmdsZSBpbmRlcGVuZGVudCAocHJlZGljdG9yKSB2YXJpYWJsZSAoJFgkKSBhbmQgYSBkZXBlbmRlbnQgKHJlc3BvbnNlKSB2YXJpYWJsZSAoJFkkKS4gSXQgYXNzdW1lcyBhIGxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdHdvIHZhcmlhYmxlcyBhbmQgaXMgd2lkZWx5IHVzZWQgZm9yIHByZWRpY3Rpb24gYW5kIGluZmVyZW5jZS4NCg0KKipQdXJwb3NlIG9mIFNpbXBsZSBMaW5lYXIgUmVncmVzc2lvbioqDQoNCiogVG8gcXVhbnRpZnkgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuICRYJCBhbmQgJFkkLiAqRm9yIGV4YW1wbGUsIHByaWNlIHZzLiBkZW1hbmQgaW4gZWNvbm9taWNzLCBkcnVnIGRvc2FnZSB2cy4gZWZmZWN0IGluIG1lZGljaW5lLCBzdHJlc3MgdnMuIG1hdGVyaWFsIHN0cmFpbiBpbiBlbmdpbmVlcmluZywgZXRjLi4qDQoNCg0KKiBUbyBwcmVkaWN0IHRoZSB2YWx1ZSBvZiAkWSQgZm9yIGEgZ2l2ZW4gdmFsdWUgb2YgJFgkLiAqRm9yIGV4YW1wbGUsIHdlIG1heSB3YW50IHRvIHVzZSBob3VzZSBmb290YWdlIHRvIHByZWRpY3QgdGhlIGhvdXNlIHByaWNlLioNCg0KKiBUbyB0ZXN0IGh5cG90aGVzZXMgYWJvdXQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuICRYJCBhbmQgJFkkLiAqRm9yIGV4YW1wbGUsIHdlIG1heSB3YW50IHRvIHRlc3Qgd2hldGhlciBob3VycyBvZiBzdHVkeSBpbmZsdWVuY2UgdGhlIGNvdXJzZSBncmFkZS4qDQoNCg0KDQojIFN0cnVjdHVyZSBvZiB0aGUgU2ltcGxlIExpbmVhciBSZWdyZXNzaW9uIE1vZGVsDQoNClRoZSBzaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb24gKFNMUikgbW9kZWwgaXMgcmVwcmVzZW50ZWQgYXMNCg0KJCQNClk9XGJldGFfMCArIFxiZXRhXzEgWCArIFxlcHNpbG9uDQokJA0KIA0KV2hlcmUgJFkkIGlzIGEgZGVwZW5kZW50IHZhcmlhYmxlIChyZXNwb25zZSksICRYJCBpcyBhbiBpbmRlcGVuZGVudCB2YXJpYWJsZSAocHJlZGljdG9yKSA8Zm9udCBjb2xvciA9ICJyZWQiPioqd2hpY2ggaXMgYXNzdW1lZCB0byBiZSBub24tcmFuZG9tKio8L2ZvbnQ+LiAkXGJldGFfMCQgaXMgdGhlIGludGVyY2VwdCAodmFsdWUgb2YgJFkkIHdoZW4gJFggPSAwJCksICRcYmV0YV8xJCBpcyB0aGUgc2xvcGUgKHRoZSBjaGFuZ2UgaW4gJFkkIHBlciB1bml0IGNoYW5nZSBpbiAkWCQpLiAkXGVwc2lsb24kID0gIiJyZXNpZHVhbCoqIHJhbmRvbSBlcnJvciB0ZXJtIChhc3N1bWVkICRcZXBzaWxvbiBccmlnaHRhcnJvdyBOKDAsXHNpZ21hXjIpJCwgc2VlIHRoZSBhc3N1bXB0aW9ucyBvZiB0aGUgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgaW4gdGhlIHN1YnNlcXVlbnQgc2VjdGlvbikuDQoNCkZvciBleGFtcGxlLCB0aGUgcHJhY3RpY2FsIHJlZ3Jlc3Npb24gYmV0d2VlbiBwcmljZSBhbmQgZGVtYW5kIGlzIGV4cHJlc3NlZCBpbiB0aGUgZm9sbG93aW5nLg0KDQokJA0KXHRleHR7cHJpY2V9ID0gXGJldGFfMCArIFxiZXRhXzFcdGltZXMgXHRleHR7ZGVtYW5kfSArIFxlcHNpbG9uLg0KJCQNCg0KV2l0aCBhIGdpdmVuIGRhdGFzZXQsIHdlIGNhbiBlc3RpbWF0ZSAkXGJldGFfMCQgYW5kICRcYmV0YV8xJCB1c2luZyB0aGUgbGVhc3Qgc3F1YXJlcyBtZXRob2QsIGRlbm90ZWQgcmVzcGVjdGl2ZWx5IGJ5ICRiXzAkIGFuZCAkYl8xJC4gVGhlIGVzdGltYXRlZCByZWdyZXNzaW9uIGxpbmUgKGZpdHRlZCBtb2RlbCkgaXM6DQoNCiQkDQpcaGF0e1l9ID0gYl8wICsgYl8xIFguDQokJA0KDQpUaGUgKiplc3RpbWF0ZWQqKiByZXNpZHVhbHMgYXJlIGRlZmluZWQgdG8gYmUgdGhlIGVzdGltYXRlZCB2YWx1ZSAkXGhhdHtZfSQgYW5kIHRoZSBvYnNlcnZlZCAkWSQgZnJvbSB0aGUgZGF0YSBzZXQuIEluIFIsIHdlIGNhbiBleHRyYWN0IGVzdGltYXRlZCAkXGhhdHtZfSQgYW5kIHJlc2lkdWFscyB1c2luZyBSIGNvbW1hbmRzIGBmaXR0ZWQobW9kZWwubmFtZSlgIGFuZCBgcmVzaWQobW9kZWwubmFtZWBgDQoNCg0KDQoqKkV4YW1wbGUgMSoqOiAgU2ltcGxlIGxpbmVhciByZWdyZXNzaW9uIHRvIGFzc2VzcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gKnN0dWR5IGhvdXJzKiBhbmQgKmNvdXJzZSBncmFkZSouIFdlIHVzIHNpbXVsYXRlZCBkYXRhIGluIHRoZSBmb2xsb3dpbmcgUiBjb2RlDQoNCmBgYHtyfQ0KIyBkZWZpbmUgU2FtcGxlIGRhdGENCnN0dWR5X2hvdXJzIDwtIGMoMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExKQ0KY291cnNlX2dyYWRlIDwtIGMoNjAsIDYzLCA2NSwgNjYsIDY4LCA3MiwgNzQsIDc2LCA3OSwgODMpDQoNCiMgQ29tYmluZSBpbnRvIGEgZGF0YSBmcmFtZSB3aXRoIG5hbWU6IGV4YW1wbGUuZGF0YQ0KZXhhbXBsZS5kYXRhIDwtIGRhdGEuZnJhbWUoc3R1ZHlfaG91cnMsIGNvdXJzZV9ncmFkZSkNCg0KIyBGaXQgdGhlIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsLiBXZSBuYW1lIHRoZSBtb2RlbDogZXhhbXBsZS5tb2RlbA0KZXhhbXBsZS5tb2RlbCA8LSBsbShjb3Vyc2VfZ3JhZGUgfiBzdHVkeV9ob3VycywgZGF0YSA9IGV4YW1wbGUuZGF0YSkgDQoNCiMgVmlldyB0aGUgbW9kZWwgc3VtbWFyeQ0Kc3VtbWFyeShleGFtcGxlLm1vZGVsKQ0KYGBgDQpUaGUgYW5ub3RhdGlvbiBvZiB0aGUgb3V0cHV0IGlzIGRlcGljdGVkIGluIHRoZSBmb2xsb3dpbmcuDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI5MCUifQ0KaW5jbHVkZV9ncmFwaGljcygiaW1hZ2UvTTAyLVNMUi1vdXRwdXQucG5nIikNCmBgYA0KDQoNClRoZSBlc3RpbWF0ZWQgWSwgZGVub3RlZCBieSAkXGhhdHtZfSQgKGNvbW1vbmx5IGNhbGxlZCBmaXR0ZWQgWSkgYW5kIGVzdGltYXRlZCByZXNpZHVhbCAkZSA9IFkgLSBcaGF0e1l9JCBjYW4gYmUgZXh0cmFjdGVkIGZyb20gdGhlIGFib3ZlIG1vZGVsIGluIHRoZSBmb2xsb3dpbmcgUiBjb2RlLg0KDQpgYGB7cn0NCmZpdHRlZC5ZIDwtIGZpdHRlZChleGFtcGxlLm1vZGVsKSAgICAgICAgICAgIyBlc3RpbWF0ZWQgWQ0KZXN0aW1hdGVkLnJlc2lkIDwtIHJlc2lkKGV4YW1wbGUubW9kZWwpICAgICAjIGVzdGltYXRlZCByZXNpZHVhbCBlcnJvcg0KY2JpbmQoWSA9IGNvdXJzZV9ncmFkZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY29tYmluZSB0aHJlZSB2YXJpYWJsZXMgZm9yIGJhY2stdG8tYmFjayBjb21wYXJpc29uDQogICAgICBZLmhhdCA9IGZpdHRlZC5ZLA0KICAgICAgZS5oYXQgPSBlc3RpbWF0ZWQucmVzaWQpDQpgYGANCg0KWW91IHNlZSBmcm9tIHRoZSBhYm92ZSBvdXRwdXQgdGhhdCBgWSAtIFkuaGF0ID0gZS5oYXRgLg0KDQoNCiMgQXNzdW1wdGlvbnMgb2YgU2ltcGxlIExpbmVhciBSZWdyZXNzaW9uDQoNCkZvciB2YWxpZCBpbmZlcmVuY2UgYW5kIHByZWRpY3Rpb25zLCBTTFIgcmVsaWVzIG9uIHRoZSBmb2xsb3dpbmcgYXNzdW1wdGlvbnM6DQoNCiogKipMaW5lYXJpdHkqKjogVGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuICRYJCBhbmQgJFkkIGlzIGxpbmVhci4gVGhpcyBjYW4gYmUgdmlzdWFsbHkgY2hlY2tlZCBieSBhIHNpbXBsZSBzY2F0dGVyIHBsb3QgZm9yIFNMUiAoaS5lLiwgd2l0aCBvbmx5IG9uZSBwcmVkaWN0b3IgdmFyaWFibGUpLiBXZSBjYW4gY2hlY2sgdGhlIGxpbmVhcml0eSBvZiB0aGUgYWJvdmUgZXhhbXBsZSB1c2luZyB0aGUgZm9sbG93aW5nIFIgY29kZS4NCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NSwgZmlnLmhlaWdodD01fQ0KcGxvdChzdHVkeV9ob3VycywgY291cnNlX2dyYWRlLCBtYWluPSJDb3Vyc2UgR3JhZGUgdi5zLiBTdHVkeSBIb3VycyIpDQpgYGANCg0KDQoqICoqSW5kZXBlbmRlbmNlKio6IEVycm9ycyAoJFxlcHNpbG9uJCkgYXJlIGluZGVwZW5kZW50IChubyBhdXRvY29ycmVsYXRpb24pLiBUaGlzIGlzIGhhcmQgdG8gY2hlY2sgaW4gdGhpcyBsZXZlbCBvZiBzdGF0aXN0aWNzIGNvdXJzZS4gDQoNCiogSG9tb3NjZWRhc3RpY2l0eTogQ29uc3RhbnQgdmFyaWFuY2Ugb2YgZXJyb3JzIGFjcm9zcyAkWCQuIFNpbmNlICRYJCBpcyBhc3N1bWVkIHRvIGJlIG5vbi1yYW5kb20sIHRoZSB2YXJpYW5jZSBvZiAkWSQgaXMgdGhlIHNhbWUgYXMgdGhlIHJlc2lkdWFsICRcZXBzaWxvbiQuIEluIHByYWN0aWNlLCB3ZSBjaGVjayB3aGV0aGVyIHRoZSB2YXJpYW5jZSBvZiB0aGUgZXN0aW1hdGVkIHJlc2lkdWFsIGVycm9ycyAkZSA9IFkgLSBcaGF0e1l9JC4NCg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iODAlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoImltYWdlL00wMi1yZXNpZHVhbC1wYXR0ZXJucy5wbmciKQ0KYGBgDQoNCkluIHRoZSBhYm92ZSBncmFkZS1zdHVkeSBleGFtcGxlLCB3ZSBjYW4gcGxvdCB0aGUgcmVzaWR1YWwgaW4gdGhlIGZvbGxvd2luZy4NCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NSwgZmlnLmhlaWdodD01fQ0KIyBmaXR0ZWQuWSBhbmQgZXN0aW1hdGVkLnJlc2lkIHdlcmUgZGVmaW5lZCBlYXJsaWVyDQojIENhdXRpb246IFdoZW4geW91IHVzZSBhIHZhcmlhYmxlIGluIGFuYWx5c2lzIGFuZCBwbG90dGluZywgbWFrZSBzdXJlIGl0IGlzIGRlZmluZWQgZWFybGllci4NCiMgSW4gYW55IGZ1bmN0aW9uIGNhbGxzLCBhcmd1bWVudHMgbXVzdCBiZSBzZXBhcmF0ZWQgYnkgYSBjb21tYSENCnBsb3QoZml0dGVkLlksICAgICAgICAgICAgICAgICMgZml0dGVkIG9yIHByZWRpY3RlZCB2YWx1ZXMNCiAgICAgZXN0aW1hdGVkLnJlc2lkLCAgICAgICAgICMgZXN0aW1hdGVkIHJlc2lkdWFscw0KICAgICB4bGFiID0gIkZpdHRlZCBWYWx1ZXMiLCAgIyB0aGUgbGFiZWwgb2YgeC1heGlzDQogICAgIHlsYWIgPSAiUmVzaWR1YWxzIiwgICAgICAjIHRoZSBsYWJlbCBvZiB5LWxhYmVsDQogICAgIG1haW4gPSAiUmVzaWR1YWwgUGxvdCBFeGFtcGxlIExpbmVhciBNb2RlbCINCiAgICAgKQ0KYGBgDQoNCkl0IHR1cm5zIG91dCB0aGF0IHRoZSByZXNpZHVhbHMgKipkb2VzIG5vdCoqIGhhdmUgYSBjb25zdGFudCB2YXJpYW5jZSBhY3Jvc3MgdGhlIGZpdHRlZCB2YWx1ZXMuDQoNCg0KDQoqICoqTm9ybWFsaXR5Kio6IEVycm9ycyBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuIFRoZXJlIGFyZSB0ZXN0aW5nIGh5cG90aGVzaXMgcHJvY2VkdXJlcyBmb3Igbm9ybWFsaXR5LiBJbiBwcmFjdGljZSwgd2Ugb25seSB1c2UgdmlzdWFsIGNoZWNrcyBmb3Igbm9ybWFsaXR5LiAqKlFRLXBsb3QqKiAocXVhbnRpbGUtcXVhbnRpbGUgcGxvdCkgaXMgYSBjb21tb25seSB1c2VkIHZpc3VhbCB0b29sLiBJdCBjb21wYXJlcyB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBlc3RpbWF0ZWQgcmVzaWR1YWxzIHdpdGggYSBzZXQgb2YgdHJ1ZSBub3JtYWxseSBkaXN0cmlidXRlZCB2YWx1ZXMuIFRoZSBmb2xsb3dpbmcgKipRUS1wbG90Kiogd2FzIGdlbmVyYXRlZCBmcm9tIFIgY29kZS4gDQoNClRoZSBSIGZ1bmN0aW9ucyBgcXFub3JtKClgIGFuZCBgcXFsaW5lKClgIGluIHBhY2thZ2UgKip7c3RhdHN9KiogY2FuIGRyYXcgdGhlIHFxLXBsb3QgYW5kIHRoZSByZWZlcmVuY2UgbGluZS4gVGhlIGZvbGxvd2luZyBjb2RlIHNob3dzIGhvdyB0byBkcmF3IHRoZSBRUS1wbG90IGFuZCByZWZlcmVuY2UgbGluZSBiYXNlZCBvbiB0aGUgYWJvdmUgZXhhbXBsZS4gDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NX0NCiMgbmVlZCB0byBpbnN0YWxsIGFuZCBsb2FkIHRoZSBwYWNrYWdlIHtnZ3Bsb3QyfQ0KIyBTaW5jZSBwYWNrYWdlIHtzdGF0c30gY29tZXMgd2l0aCBiYXNlIFIsIHdlIGRvbid0IG5lZWQgdG8gaW5zdGFsbCBpdC4NCiMjDQpxcW5vcm0oZXN0aW1hdGVkLnJlc2lkKSAgICMgdGhlIHNldCBvZiBlc3RpbWF0ZWQgcmVzaWR1YWxzDQpxcWxpbmUoZXN0aW1hdGVkLnJlc2lkKSAgICMgZHJhdyB0aGUgcmVmZXJlbmNlIGxpbmUNCmBgYA0KDQojIE1vZGVsIERpYWdub3N0aWNzDQoNCkluIHByYWN0aWNlLCBpdCBpcyBxdWl0ZSBvZnRlbiB0byBoYXZlIGRpZmZlcmVudCBtZXRob2RzIHVuZGVyIGRpZmZlcmVudCBhc3N1bXB0aW9ucyB0byBzb2x2ZSB0aGUgc2FtZSBwcm9ibGVtLiBUaGUgZ29hbHMgb2YgYW4gYW5hbHlzdCBhcmUgdG8gdmFsaWRhdGUgZWFjaCBpbmRpdmlkdWFsIG1vZGVsIGJhc2VkIG9uIHRoZSByZWxhdGVkIGFzc3VtcHRpb24gYW5kIHRoZW4gY2hvb3NlIHRoZSBiZXN0IG1vZGVsIHRvIGltcGxlbWVudCAocmVwb3J0KS4gVGhlIHByb2Nlc3Mgb2YgdmFsaWRhdGluZyBhIG1vZGVsIGlzIGNhbGxlZCAqKm1vZGVsIGRpYWdub3NpcyoqLg0KDQpBcyBkaXNjdXNzZWQgaW4gdGhlIHByZXZpb3VzIHNlY3Rpb24sIG1vc3Qgb2YgdGhlIGFzc3VtcHRpb25zIGFyZSByZWxhdGVkIHRvIHRoZSByZXNpZHVhbCBlcnJvcnMuIFRoaXMgc2VjdGlvbiB3aWxsIGZvY3VzIG9uICoqcmVzaWR1YWwgYW5hbHlzaXMqKiBieSBhbmFseXppbmcgdGhlIHBhdHRlcm5zIGluIHZhcmlvdXMgcmVzaWR1YWwgcGxvdHMuDQoNCiogKipSZXNpZHVhbCBQbG90cyoqIC0gUmVzaWR1YWxzIHZzIEZpdHRlZDogQ2hlY2tpbmcgZm9yIG5vbi1saW5lYXJpdHkgJiBoZXRlcm9zY2VkYXN0aWNpdHkuDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI4MCUifQ0KaW5jbHVkZV9ncmFwaGljcygiaW1hZ2UvTTAyLVJlc2lkdWFsUGxvdFBhdHRlcm5zLnBuZyIpDQpgYGANCg0KKiAqKlEtUSBQbG90Kio6IENoZWNrIG5vcm1hbGl0eSBvZiByZXNpZHVhbHMuIA0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI4MCUifQ0KaW5jbHVkZV9ncmFwaGljcygiaW1hZ2UvTTAyLVFRUGxvdFBhdHRlcm5zLnBuZyIpDQpgYGANCg0KDQoqICoqSW5mbHVlbmNlIE1lYXN1cmVzIC0gQ29va+KAmXMgRGlzdGFuY2UqKjogRGV0ZWN0cyBpbmZsdWVudGlhbCBvYnNlcnZhdGlvbnMgdGhhdCBpbXBhY3QgdGhlIHJlZ3Jlc3Npb24gbW9kZWwgKGxpbmUpIHNpZ25pZmljYW50bHkuIFRvIHJlYWQgdGhlIHBsb3Qgb2YgQ29vaydzIGRpc3RhbmNlLCB5b3UgbmVlZCB0byBoYXZlIGEgY2xlYXIgdW5kZXJzdGFuZGluZyBvZiB0aHJlZSBkZWZpbml0aW9uczoNCg0KKioxLiBPdXRsaWVyKiogLSBhbiBvYnNlcnZhdGlvbiB0aGF0IGxpZXMgYW4gKiphYm5vcm1hbCBkaXN0YW5jZSoqIGZyb20gb3RoZXIgdmFsdWVzIGluIHRoZSBkYXRhc2V0LiANCg0KKioyLiBMZXZlcmFnZSoqIC0gYSBtZWFzdXJlIG9mIGhvdyBmYXIgYW4gKippbmRlcGVuZGVudCB2YXJpYWJsZSAoWCkqKiBkZXZpYXRlcyBmcm9tIGl0cyBtZWFuLg0KDQoqKjMuIEluZmx1ZW50aWFsIFBvaW50KiogLSBhbiBvYnNlcnZhdGlvbiB0aGF0IHNpZ25pZmljYW50bHkgYWx0ZXJzIHRoZSByZWdyZXNzaW9uIGNvZWZmaWNpZW50cyBpZiByZW1vdmVkLiANCg0KVGhlIGZvbGxvd2luZyBZb3VUdWJlIHZpZGVvIGV4cGxhaW5zIHRoZXNlIGNvbmNlcHRzIGNsZWFybHkuDQoNClwNCg0KPGNlbnRlcj48YSBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PXhjX1g5R0ZWdVZVIiB0YXJnZXQ9InBvcHVwIiANCiAgICAgICAgICAgICAgICAgICBvbmNsaWNrPSJ3aW5kb3cub3BlbignaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj14Y19YOUdGVnVWVScsDQogICAgICAgICAgICAgICAgICAgICAgJ25hbWUnLCd3aWR0aD04NTAsaGVpZ2h0PTUwMCcpIj48aW1nIHNyYyA9ICJodHRwczovL3Blbmdkc2NpLmdpdGh1Yi5pby9NQVQxMjFXNS9pbWcvVmlkZW9JY29uLnBuZyIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIxMjAiPjwvYT4NCjwvY2VudGVyPg0KDQpcDQoNClRoZSBmb2xsb3dpbmcgdGFibGUgZXhwbGFpbnMgdGhlIHRocmVlIGNvbmNlcHRzIGFuZCBkaWFnbm9zdGljIG1lYXN1cmVzLiANCg0KfCBDb25jZXB0ICAgICAgIHwgRGV0ZWN0cy4uLiAgICAgICAgICB8IERlcGVuZHMgb24uLi4gICAgICAgfCBEaWFnbm9zdGljIE1lYXN1cmUgICAgICAgICAgfA0KfDotLS0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tLS0tLS0tfDotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfA0KfCAqKk91dGxpZXIqKiAgIHwgQXR5cGljYWwgWSB2YWx1ZSAgICB8IFJlc2lkdWFsIG1hZ25pdHVkZSAgfCBTdGFuZGFyZGl6ZWQgcmVzaWR1YWxzICAgICAgfA0KfCAqKkxldmVyYWdlKiogIHwgRXh0cmVtZSBYIHZhbHVlICAgICB8IFggcG9zaXRpb24gb25seSAgICAgfCBsZXZlcmFnZSBtZWFzdXJlICAgICAgICAgICAgfA0KfCAqKkluZmx1ZW5jZSoqIHwgSW1wYWN0IG9uIG1vZGVsICAgICB8IEJvdGggWCBhbmQgWSAgICAgICAgfCBDb29r4oCZcyBEaXN0YW5jZSAgICAgICAgICAgICB8DQoNCg0KKiAqKlJlbGF0aW9uc2hpcCBCZXR3ZWVuIE91dGxpZXJzLCBMZXZlcmFnZSwgYW5kIEluZmx1ZW50aWFsIFBvaW50cyoqDQoNClRoZSBmb2xsb3dpbmcgdGFibGUgZXhwbGFpbnMgdGhlIHJlbGF0aW9uc2hpcC4NCg0KfCBTY2VuYXJpbyAgICAgICAgICAgICAgICB8IExldmVyYWdlIHwgUmVzaWR1YWwgfCBJbmZsdWVuY2UgfA0KfDotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLXw6LS0tLS0tLS0tfDotLS0tLS0tLS0tfA0KfCBOb3JtYWwgcG9pbnQgICAgICAgICAgICB8IExvdyAgICAgIHwgU21hbGwgICAgfCBObyAgICAgICAgfA0KfCBWZXJ0aWNhbCBvdXRsaWVyICAgICAgICB8IExvdyAgICAgIHwgTGFyZ2UgICAgfCBNaW5pbWFsICAgfA0KfCBHb29kIGxldmVyYWdlIHBvaW50ICAgICB8IEhpZ2ggICAgIHwgU21hbGwgICAgfCBObyAgICAgICAgfA0KfCBCYWQgbGV2ZXJhZ2UgcG9pbnQgICAgICB8IEhpZ2ggICAgIHwgTGFyZ2UgICAgfCBZZXMgICAgICAgfA0KDQoNCiogKipHcmFwaGljYWwgSWxsdXN0cmF0aW9uIG9mIFRoZXNlIENvbmNlcHRzKioNCg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iOTUlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoImltYWdlL00wMi1JbmZsdWVudGlhbExldmVyYWdlT3V0bGllci5wbmciKQ0KYGBgDQoNCg0KDQojIEluZmVyZW5jZSBBYm91dCBSZWdyZXNzaW9uIENvZWZmaWNpZW50cw0KDQpXZSBwZXJmb3JtIGh5cG90aGVzaXMgdGVzdHMgdG8gZGV0ZXJtaW5lIGlmIHRoZSByZWxhdGlvbnNoaXAgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gUmVjYWxsIHRoYXQgdGhlIGVxdWF0aW9uIG9mIHRoZSBzaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgaXMNCg0KJCQNClkgPSBcYmV0YV8wICsgXGJldGFfMSBYICsgXGVwc2lsb24uDQokJA0KJFgkIGlzIGEgbnVtZXJpYyBvciBiaW5hcnkgKGhhcyB0d28gcG9zc2libGUgZGlzdGluY3QgdmFsdWVzLCBzdWNoIGFzIGBTVEVNLW1ham9yYCBhbmQgYG5vbi1TVEVNLW1ham9yYCwgYHllc2AgYW5kIGBub2AsIGBkaXNlYXNlYCBhbmQgYGRpc2Vhc2UtZnJlZWAsIGV0Yy4pLiANCg0KSWYgdGhlIHNsb3BlICRcYmV0YV8xID0gMCQsIHRoZSBhYm92ZSByZWdyZXNzaW9uIG1vZGVsIGlzIHJlZHVjZWQgdG8gJFkgPSBcYmV0YV8wICsgXGVwc2lsb24kLCBJbiB0aGlzIGNhc2UsIGFueSBjaGFuZ2VzIGluICRYJCB3aWxsICoqbm90KiogaW5mbHVlbmNlICRZJC4gV2UgY2FsbCAkWCQgYW5kICRZJCB1bmNvcnJlbGF0ZWQuDQoNCkluIHByYWN0aWNlLCB3ZSBvbmx5IG5lZWQgdG8gdGVzdCB3aGV0aGVyICRcYmV0YV8xID0gMCQgdG8gYXNzZXNzIHRoZSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gJFkkIGFuZCAkWCQuIEFzIHNob3duIGVhcmxpZXIsIHRoZSBvdXRwdXQgaW4gUiBwcm92aWRlcyBoeXBvdGhlc2lzIHRlc3Rpbmcgb24gYm90aCAkYmV0YV8wID0gMCQgYW5kICRcYmV0YV8xID0gMCQgcmVzcGVjdGl2ZWx5LiBUaGUgZm9sbG93aW5nIHNjcmVlbnNob3QgZnJvbSBSIGxpbmVhciByZWdyZXNzaW9uIHByb3ZpZGVzIGFsbCB0aGUgaW5mb3JtYXRpb24gZm9yIGluZmVyZW5jZSBvZiByZWdyZXNzaW9uIGNvZWZmaWNpZW50cy4gIA0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI4NSUifQ0KaW5jbHVkZV9ncmFwaGljcygiaW1hZ2UvTTAyLVItbG0tT3V0cHV0LnBuZyIpDQpgYGANCg0KPGZvbnQgY29sb3IgPSAicmVkIj4qKlxjb2xvcntyZWR9Tk9URTogVGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSBvZiB0aGUgdC10ZXN0IGluIGxpbmVhciByZWdyZXNzaW9uIGlzIGRlZmluZWQgdG8gYmU6IGRmID0gbiAtICMgY29lZmZpY2llbnRzISoqPC9mb250Pg0KDQojIyB0LXRlc3QgZm9yIFNsb3BlICgkXGJldGFfMSQpDQoNCiQkIA0KSF8wOiBcIFwgXGJldGFfMSA9IDAgXCBcIFx0ZXh0e3Yucy59IFwgXCBcYmV0YV8xIFxuZSAwIA0KJCQNCg0KSW4gdGhlICoqQ291cnNlLWdyYWRlIGFuZCBTdHVkeS10aW1lKiogZXhhbXBsZSwgdGhlIHNhbXBsZSBzaXplID0gMTAuIFRoZSB0ZXN0IFN0YXRpc3RpYyBmb3IgdGVzdGluZyB0aGUgYWJvdmUgaHlwb3RoZXNpcyBpcyBkZWZpbmVkIGFzDQoNCiQkDQpUUyA9IFxmcmFje2JfMSAtIDB9e1x0ZXh0e1NFfShiXzEpfSBccmlnaHRhcnJvdyB0X3sxMC0yfQ0KJCQNCg0KV2UgdXNlIHRoZSBpbmZvcm1hdGlvbiBpbiB0aGUgb3V0cHV0IHRvIGV2YWx1YXRlIHRoZSBhYm92ZSB0ZXN0IHN0YXRpc3RpYyBhbmQgb2J0YWluDQoNCiQkDQpUUyA9IFxmcmFjezIuNDM2NCAtIDB9ezAuMTAwN30gPSAyNC4wMi4NCiQkDQogDQogVGhlIHAtdmFsdWUgb2YgdGhlIHR3by10YWlsZWQgdGVzdCBiYXNlZCBvbiB0aGUgZGlzdHJpYnV0aW9uIHdpdGggOCBkZWdyZWVzIG9mIGZyZWVkb20gaXMgJFx0ZXh0e3AtdmFsdWV9ID0gUChUUz4yNC4wMikgPSA5LjYxODM3OWUtMDkgXGFwcHJveCAwJC4gV2UgY2FuIHVzZSB0aGUgZm9sbG93aW5nIFIgY29kZSB0byBjYWxjdWxhdGUgdGhlIHAtdmFsdWUuDQogDQogDQpgYGB7cn0NCiBwLnZhbHVlIDwtIDIqKDEtcHQoIDI0LjAyLCA4KSkNCiBwLnZhbHVlDQpgYGANCiANClVzaW5nIHNpZ25pZmljYW5jZSBsZXZlbCAkXGFscGhhID0gMC4wNSQsIHdlIGZhaWwgdG8gKipyZWplY3QqKiB0aGUgbnVsbCBoeXBvdGhlc2lzICRIXzA6ICBcYmV0YSA9IDAkLiBUaGlzIGltcGxpZXMgdGhhdCBzdHVkeS1ob3VycyBpbmZsdWVuY2UgdGhlIGNvdXJzZSBncmFkZSAqKnNpZ25pZmljYW50bHkqKiBzaW5jZSBwLXZhbHVlICRcYXBwcm94IDAkIDwgdGhlIHNpZ25pZmljYW5jZSBsZXZlbCAwLjA1Lg0KIA0KIA0KICoqUmVtYXJrcyoqOiANCiANCiAoMSkuIGBwdCgyNC4wMiwgOClgIGdpdmVzIHRoZSAqKmxlZnQtdGFpbCBhcmVhKiouIFRoZSAqKnJpZ2h0LXRhaWwgYXJlYSoqIGlzIGAoMS1wdCgyNC4wMiwgOCkpYC4gDQogDQogDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iNzUlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoImltYWdlL00wMi10LWRlbnNpdHlDdXJ2ZS5wbmciKQ0KYGBgDQogDQogKDIpIFdlIGhhdmUgbGVhcm5lZCBmcm9tIHRoZSBwcmV2aW91cyBpbnRyb2R1Y3Rvcnkgc3RhdGlzdGljcyB0aGF0IHRoZSBwLXZhbHVlIG9mIGEgdHdvLXRhaWxlZCB0ZXN0IGlzIGVxdWFsIHRvIHR3byB0aW1lcyB0aGUgc21hbGxlciB0YWlsIGFyZWEuDQogDQoNCg0KIyMgQ29uZmlkZW5jZSBJbnRlcnZhbCBmb3IgU2xvcGUNCg0KVXNpbmcgdGhlIGluZm9ybWF0aW9uIGluIHRoZSBvdXRwdXQsIHdlIGNhbiBhbHNvIGNvbnN0cnVjdCB0aGUgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgdGhlIHNsb3BlLiBSZWNhbGwgdGhhdCB0aGUgY29uZmlkZW5jZSBvZiB0aGUgcG9wdWxhdGlvbiBtZWFuIGhhcyB0aGUgZm9sbG93aW5nIGdlbmVyYWwgZm9ybS4NCg0KJCQNClxiYXJ7eH0gXHBtIENWXHRpbWVzIFxmcmFje3N9e1xzcXJ0e259fQ0KJCQNCg0KVGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgdGhlIHNsb3BlICgkXGJldGFfMSQpIGhhcyBhIHNpbWlsYXIgZm9ybSBnaXZlbiBiZWxvdy4NCg0KJCQNCmJfMSBccG0gQ1ZcdGltZXMgXHRleHR7U0V9KGJfMSksDQokJA0KDQpXaGVyZSAkYl8xJCBhbmQgJFx0ZXh0e1NFfShiXzEpJCBhcmUgZ2l2ZW4gaW4gdGhlIFIgb3V0cHV0IChzZWUgdGhlIGFib3ZlIHNjcmVlbnNob3QpLiBDViAoY3JpdGljYWwgdmFsdWUpIGlzIGJhc2VkIG9uIHRoZSB0LWRpc3RyaWJ1dGlvbiB3aXRoIGBuIC0gIyBjb2VmZmljaWVudHNgIChpbiB0aGlzIHN0dWR5LXRpbWUgYW5kIGdyYWRlIGV4YW1wbGUsIDEwIC0yID0gOCkuIExldCdzIHVzZSBhIGNvbmZpZGVuY2UgbGV2ZWwgb2YgOTUlLCB0aGUgY3JpdGljYWwgdmFsdWUgY2FuIGJlIGZvdW5kIHVzaW5nIHRoZSBSIGNvbW1hbmQgYHF0KDAuOTc1LDgpYCwgd2hpY2ggZ2l2ZXMgMi4zMDYuIFRoZSBjb25maWRlbmNlIGxldmVsIGFuZCBjcml0aWNhbCB2YWx1ZSBhcmUgbGFiZWxlZCBvbiB0aGUgZm9sbG93aW5nIHQtZGVuc2l0eSBjdXJ2ZS4NCg0KIA0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGg9Ijc1JSJ9DQppbmNsdWRlX2dyYXBoaWNzKCJpbWFnZS9NMDItdC1jcml0aWNhbFZhbHVlLnBuZyIpDQpgYGANCg0KQmFzZWQgb24gdGhlIGFib3ZlIGV4cGxhbmF0aW9uLCB0aGUgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgJFxiZXRhXzEkIGlzIGdpdmVuIGJ5DQoNCiQkDQpiXzEgXHBtIENWXHRpbWVzIFx0ZXh0e1NFfShiXzEpID0gMi40MzY0IFxwbSAyLjMwNlx0aW1lcyAwLjEwMDcgPSAoMi4yMDQxODYsIDIuNjY4NjE0KS4NCiQkDQoNCg0KIyBTdW1tYXJ5DQoNCg0KDQoqKjEuIFN0cnVjdHVyZSoqDQoNCk1vZGVscyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gb25lIHByZWRpY3RvciAoWCkgYW5kIG9uZSByZXNwb25zZSAoWSkuDQoNCioqRXF1YXRpb24qKjogJFkgPSBcYmV0YV8wICsgXGJldGFfMSBYICsgXGVwc2lsb24kLiBUd28gcmVncmVzc29uIGNvZWZmaWNpZW50cyBhcmUgaW50ZXJjZXB0ICQoXGJldGFfMCkkIGFuZCBzbG9wZSAkKFxiZXRhXzEpJC4gJFxlcHNpbG9uJCBpcyB0aGUgcmFuZG9tIGVycm9yLg0KDQoqKjIuIEFzc3VtcHRpb25zKioNCg0KKiAqTGluZWFyaXR5KjogVGhlIFJlbGF0aW9uc2hpcCBiZXR3ZWVuIFggYW5kIFkgaXMgbGluZWFyLg0KDQoqICpJbmRlcGVuZGVuY2UqOiBSZXNpZHVhbHMgYXJlIHVuY29ycmVsYXRlZCAobm8gYXV0b2NvcnJlbGF0aW9uKS4NCg0KKiAqSG9tb3NjZWRhc3RpY2l0eSo6IENvbnN0YW50IHZhcmlhbmNlIG9mIHJlc2lkdWFscyBhY3Jvc3MgWC4NCg0KKiAqTm9ybWFsaXR5KjogUmVzaWR1YWxzIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZCAoaW1wb3J0YW50IGZvciBpbmZlcmVuY2UpLg0KDQoNCg0KKiozLiBEaWFnbm9zdGljcyoqDQoNClJlc2lkdWFsIHBsb3RzOiBDaGVjayBmb3IgcGF0dGVybnMgKG5vbi1saW5lYXJpdHksIGhldGVyb3NjZWRhc3RpY2l0eSkuDQoNClEtUSBwbG90OiBBc3Nlc3Mgbm9ybWFsaXR5IG9mIHJlc2lkdWFscy4NCg0KTGV2ZXJhZ2UvQ29va+KAmXMgZGlzdGFuY2U6IElkZW50aWZ5IGluZmx1ZW50aWFsIHBvaW50cy4NCg0KUi1zcXVhcmVkOiBQcm9wb3J0aW9uIG9mIHZhcmlhbmNlIGV4cGxhaW5lZCBieSBYLg0KDQoNCioqNC4gSW50ZXJwcmV0YXRpb24qKg0KDQoqICpTbG9wZSAoJFxiZXRhXzEkKSo6ICBDaGFuZ2UgaW4gWSBwZXIgdW5pdCBpbmNyZWFzZSBpbiBYLg0KDQoqICpJbnRlcmNlcHQgKCRcYmV0YV8wJCo6IEV4cGVjdGVkIFkgd2hlbiBYID0gMCAobWF5IG5vdCBhbHdheXMgYmUgbWVhbmluZ2Z1bCkuDQoNCiogKlItc3F1YXJlZDoqIGJldHdlZW4gMCBhbmQgMTsgaGlnaGVyID0gYmV0dGVyIGZpdCAoYnV0ICoqZG9lc27igJl0IGltcGx5IGNhdXNhdGlvbioqKS4NCg0KDQoNCioqNS4gSW5mZXJlbmNlKioNCg0KKiAqSHlwb3RoZXNpcyB0ZXN0IG9uICRcYmV0YV8xJCo6ICAkSF8wOiBcYmV0YV8xID0gMCBcIFwgXHRleHR7di5zfSBcIFwgSF9hOiBcYmV0YV8xIFxuZSAwJC4gIFVzZSBhIHQtdGVzdCBmb3Igc2lnbmlmaWNhbmNlLg0KDQoqICpDb25maWRlbmNlIGludGVydmFsIG9mICRcYmV0YV8xJCo6IFJhbmdlIGZvciAkXGJldGFfMSQuICAkYl8xIFxwbSB0X3tcdGV4dHtkZn0sIFwgXCAxLVxhbHBoYS8yfSQNCg0KKiAqcC12YWx1ZSo6IFByb2JhYmlsaXR5IG9mIG9ic2VydmluZyB0aGUgc2xvcGUgdW5kZXIgJEhfMDogXGJldGFfMSA9IDAkLiANCg0KDQoNCioqNi4gS2V5IFIgRnVuY3Rpb25zKioNCg0KKiBGaXQgbW9kZWw6IGBsbShZIH4gWCwgZGF0YSlgDQoNCiogU3VtbWFyaXplOiBgc3VtbWFyeShtb2RlbClgLiBuZWVkIHRvIHVuZGVyc3RhbmQgZXN0aW1hdGVkIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzLCBSLXNxdWFyZWQsIHAtdmFsdWVzLCBldGMuDQoNCiogRGlhZ25vc3RpY3M6DQoNCiAgKyBwbG90KG1vZGVsKSAocmVzaWR1YWwgcGxvdHMpLg0KICArIHFxbm9ybShyZXNpZChtb2RlbCkpIChub3JtYWxpdHkgY2hlY2spLg0KDQoqIFByZWRpY3Rpb25zOiBwcmVkaWN0KG1vZGVsLCBuZXdkYXRhKQ0KDQoNCg0KDQoNCg0K