As we have seen, simple linear regression seeks to model the relationship between the mean of the response y and a single predictor x.

You will have met simple linear regression in other statistics courses, so some of the material in this lecture should be revision.

Nonetheless, simple linear regression provides a friendly context to introduce notation, remind you of fundamental concepts, and take a first look at statistical modelling with R.

Pulse and Height

The following R code

## PulseData <- read.csv(file = "https://r-resources.massey.ac.nz/data/161251/pulse.csv",
##     header = TRUE)
head(PulseData)
  Height Pulse
1    160    68
2    167    80
3    162    84
4    175    80
5    177    80
6    185    80

Download pulse.csv

plot( Pulse~Height, data=PulseData)

with the more modern ggplot2 style:

library(ggplot2)
PulseData |>
    ggplot(mapping = aes(x = Height, y = Pulse)) + geom_point() + ylab("Resting pulse rate (beats per minute)") +
    xlab("Height (in centimeters) ")
unlabelled

Plot of resting pulse rate (beats per minute) versus height (in centimeters) for a sample of 50 hospital patients. Source: A Handbook of Small Data Sets by Hand, Daly, Lunn, McConway and Ostrowski.

The choice is yours; you need to choose what is best for your audience. If your audience is just you, then do what you find easier. If you’re wanting to look good when you’re delivering presentations, then you’ll benefit from getting to grips with the ggplot() way of working.

It is of interest to know whether pulse rate is truly dependent on height.

View pulse as response (y) variable and height as predictor (x) variable.

We can formally test whether this really is the case by using a simple linear regression model.

Note there is one observation (patient resting pulse 116) which is distant from the main bulk of data.

Basics of Simple Linear Regression: Data

Quantitative data occur in pairs: (x1,y1), …,(xn,yn).

yi denotes the response variable and xi the explanatory variable for the ith individual.

The aim is to estimate the mean response for any given value of the explanatory variable.

It therefore makes sense to think of x1,…,xn as fixed constants, while y1, …, yn are chance values taken by random variables Y1,…, Yn.

Basics of Simple Linear Regression: Model

Now recall that The linear regression model is

\[Y_i = \beta_0 + \beta_1 x_i + \varepsilon_i\]

where

A1. The expected value of the errors \(E[\varepsilon_i] = 0\) for i=1,…,n.

A2. The errors \(\varepsilon_1, \ldots ,\varepsilon_n\) are independent. N.B. A2 might be new to you. Near the end of the course we will consider what happens if this assumption is wrong.

A3. The error variance \(\mbox{var}(\varepsilon_i) = \sigma^2\) (an unknown constant) for i=1,…,n.

A4. The errors \(\varepsilon_1, \ldots ,\varepsilon_n\) are normally distributed.

N.B. We refer back to these four assumptions many times in this course; they will often be referred to using the shorthand A1 to A4.

The validity of the simple regression model given above and Assumption A1 implies that

\[E[Y_i] = \mu_i = \beta_0 + \beta_1 x_i\]

So we say that \(E[Y_i] = \mu_i\) is the expected value of Yi given (or conditional upon) xi.

Parameter Estimation

How do we estimate the parameters \(\beta_0\) and \(\beta_1\)?

The simplest method, which is optimal if the assumptions A1-A4 are correct, is to use the method of least squares.

Least squares estimates (LSEs) \(\hat{\beta_0}\) and \(\hat{\beta_1}\), are those values that minimize the sum of squares

\[\begin{aligned} SS(\beta_0, \beta_1) &=& \sum_{i=1}^n (y_i - \mu_i)^2\\ &=& \sum_{i=1}^n (y_i - \beta_0 - \beta_1 x_i)^2. \end{aligned}\]

It can be shown (using calculus) that \(\hat{\beta_0}\) and \(\hat{\beta_1}\) are given by

\[\hat{\beta_1} = \frac{s_{xy}}{s_{xx}}\] where

\(s_{xy} = \sum_{i=1}^n (x_i - \bar x)(y_i - \bar y)\);

\(s_{xx} = \sum_{i=1}^n (x_i - \bar x)^2\);

and \(\hat{\beta_0} = \bar y - \hat{\beta_1} \bar x \; .\)

The last formula implies that the least squares regression line goes through the centroid \(\left(\bar x, \bar y \right)\) of the data.

Properties of LSEs

Some maths shows sampling distributions of \(\hat{\beta_0}\) and \(\hat{\beta_1}\) are:

\[\hat{\beta_1} \sim N \left(\beta_1, \frac{\sigma^2}{s_{xx}} \right )\] and \[\hat{\beta_0} \sim N \left(\beta_0 , \, \sigma^2\left[\frac{1}{n} + \frac{\bar x^2}{s_{xx}}\right ] \right ) \; .\]

The details of the above formulas are not important. The practical point of the formulas is that

  1. the estimates are unbiased (centred on the right thing). This implies that random sampling should give you about the right answer (at least if we have a big enough dataset), and
  2. the estimates are normally distributed, which means we can calculate confidence intervals and hypothesis tests for \(\beta_0\) and \(\beta_1\).

The variance terms (second term within each of the N( , ) formulae) are given for completeness of your notes, but are not something we will need to calculate ourselves.

Class discussion

what do these sampling distributions tell us?

Just for illustration, let’s say that the model fitted to the population of data is \(Y_i = 1 + 2 x_i + \varepsilon_i\) (i=1,2,…,n) with \(\varepsilon \sim N(0,2^2)\)

To make our calculations a simpler task, let’s also say that the covariate Information we need is: Sample size n = 32, \(\bar{x} = \sqrt{2}\), and sxx = 64.

Question:

Calculate

  1. \(P(\hat{\beta_1} > 3)\); and
  2. \(P(\hat{\beta_0} < 0)\).

Answer to (i):

We are looking for \(P(\hat{\beta_1} > 3)\)

We know that the parameter is normally distributed so we will use the standard normal distribution to find the probability. Note that \(Z \sim N(0,1)\)

After inserting the values given above, this is equal to \(P \left ( Z > \frac{3 - \beta_1}{(\sigma/\sqrt{s_{xx}}) } \right )\)

Simplifying gives \(P \left ( Z > \frac{3 - 2}{(2/\sqrt{64}) } \right ) = P \left ( Z > \frac{1}{2/8} \right ) = P(Z > 4)\)

which is approximately zero.

Answer to (ii):

Your turn!

Estimating the Error Variance

In practice, we are almost certainly working with sample data, which means the error variance, \(\sigma^2\) is also an unknown parameter.

It is important to estimate it because its square root \(\sigma\) gives us information about the natural variation in the data i.e. about how far away the individual datapoints \(Y_i\) typically are from the central line \(E[Y] =\beta_0 + \beta_1 x\).

It can be estimated using the residual sum of squares (RSS), defined by

\[RSS = \sum_{i=1}^n (y_i - \hat{\mu_i})^2 = \sum_{i=1}^n (y_i - \hat{\beta_0} - \hat{\beta_1} x_i )^2 \; .\]

where \(\hat{\mu_i} = \hat{\beta_0} + \hat{\beta_1} x_i\) is the ith fitted value; \(e_i = y_i - \hat{\mu_i}\) is the ith residual.

Then an estimate of \(\sigma^2\) is given by

\[s^2 = \frac{1}{n-2} RSS.\]

N.B. We almost always use the notation \(\hat y_i\) instead of \(\hat{\mu_i}\), but don’t lose sight of the fact that we are estimating an average even if that average is changing according to the value of a predictor.

Revised Sampling Distributions

We have seen the term \(\sigma^2\) in a number of equations. This is not known, but must be estimated from our data. When we do not know this “true” variance, we use an estimate or “sample variance” instead. This means we must alter the sampling distribution too. This happened when you used sample data to find an interval estimate of the population mean or conducted a one sample test about the population mean.

Standardizing the normal sampling distribution of \(\hat{\beta_1}\) gives

\[\frac{\hat{\beta_1} - \beta_1}{\sigma/\sqrt{s_{xx}}} \sim N(0,1)\]

Replacing \(\sigma^2\) with the estimate s2 changes the sampling distribution of \(\hat{\beta_1}\):

\[\frac{\hat{\beta_1} - \beta_1}{SE(\hat{\beta_1})} \sim t(n-2)\]

where

The sampling distribution for \(\hat{\beta_1}\) forms the basis for testing hypotheses and constructing confidence intervals for \(\beta_1\).

For testing H0: \(\beta_1 = \beta_1^0\), against H1: \(\beta_1 \ne \beta_1^0\), use the test statistic

\[t = \frac{\hat{\beta_1} - \beta_1^0}{SE(\hat{\beta_1})}.\]

We find p-value corresponding to t. As usual, smaller P indicates more evidence against H0.

A \(100(1-\alpha)\%\) confidence interval for \(\beta_1\) is

\[\left (\hat{\beta_1} - t_{\alpha/2}(n-2) SE(\hat{\beta_1}), \, \hat{\beta_1} + t_{\alpha/2}(n-2) SE(\hat{\beta_1}) \right ) .\]

The t distribution

The t distribution is used for small samples when we do not know the population variance.

You’ll see that we still use the t distribution when samples are so large that it doesn’t actually matter. Why doesn’t it matter? Because the t distribution gets closer and closer to the normal distribution as the sample size increases.

unlabelled

Probability density functions for t distributions; As df =10,20,30, (light to dark blue), the curves get closer to the normal curve (black)

The “fatter” tails of the t distribution mean that the critical values we use in confidence intervals are larger for smaller sample sizes.

Back to the example

For the pulse and height data, it can be shown that the fitted regression line (i.e. the regression line with least squares estimates in place of the unknown model parameters) is

\[E[\mbox{Pulse}] = 46.907 + 0.2098~\mbox{Height}\]

Also, it can be shown that \(SE(\hat{\beta_1}) = 0.1354\).

Finally, recall that n=50.

Question: Do the data provide evidence the pulse rate depends on height?

Solution: To answer this question, we will test

The test statistic is

\[t = \frac{\hat{\beta_1} - \beta_1^0}{SE(\hat{\beta_1})} = \frac{0.2098}{0.1354} = 1.549\]

The (2-sided) P-value is \(P=P(|T| > 1.549) = 2 \times P(T > 1.549) = 2 \times 0.06398 = 0.128\), so we conclude that the data provide no evidence of a relationship between pulse rate and height.

LS0tDQp0aXRsZTogIkxlY3R1cmUgMzogU2ltcGxlIExpbmVhciBSZWdyZXNzaW9uIg0Kc3VidGl0bGU6IDE2MS4yNTEgUmVncmVzc2lvbiBNb2RlbGxpbmcNCmF1dGhvcjogIlByZXNlbnRlZCBieSBNYXR0aGV3IFBhd2xleSA8TS5QYXdsZXlAbWFzc2V5LmFjLm56PiIgIA0KZGF0ZTogIldlZWsgMSBvZiBTZW1lc3RlciAyLCBgciBsdWJyaWRhdGU6OnllYXIobHVicmlkYXRlOjpub3coKSlgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0aGVtZTogeWV0aQ0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgaHRtbF9ub3RlYm9vazoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIGlvc2xpZGVzX3ByZXNlbnRhdGlvbjoNCiAgICB3aWRlc2NyZWVuOiB0cnVlDQogICAgc21hbGxlcjogdHJ1ZQ0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQogIHNsaWR5X3ByZXNlbnRhdGlvbjogDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNCg0KDQoNCjwhLS0tIERhdGEgaXMgb24NCmh0dHBzOi8vci1yZXNvdXJjZXMubWFzc2V5LmFjLm56L2RhdGEvMTYxMjUxLw0KLS0tPg0KDQpgYGB7ciBzZXR1cCwgcHVybD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkoa25pdHIpDQpvcHRzX2NodW5rJHNldChkZXY9YygicG5nIiwgInBkZiIpKQ0Kb3B0c19jaHVuayRzZXQoZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NywgZmlnLnBhdGg9IkZpZ3VyZXMvIiwgZmlnLmFsdD0idW5sYWJlbGxlZCIpDQpvcHRzX2NodW5rJHNldChjb21tZW50PSIiLCBmaWcuYWxpZ249ImNlbnRlciIsIHRpZHk9VFJVRSkNCm9wdGlvbnMoa25pdHIua2FibGUuTkEgPSAnJykNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShicm9vbSkNCmBgYA0KDQoNCjwhLS0tIERvIG5vdCBlZGl0IGFueXRoaW5nIGFib3ZlIHRoaXMgbGluZS4gLS0tPg0KDQpgYGB7ciBleHRyYVBrZ3MsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KGdncGxvdDIpDQoNCmBgYA0KDQoNCg0KQXMgd2UgaGF2ZSBzZWVuLCBzaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb24gc2Vla3MgdG8gbW9kZWwgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSAgbWVhbiBvZiB0aGUgcmVzcG9uc2UgKnkqIGFuZCBhIHNpbmdsZSBwcmVkaWN0b3IgKngqLg0KDQpZb3Ugd2lsbCBoYXZlIG1ldCBzaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb24gaW4gb3RoZXIgc3RhdGlzdGljcyBjb3Vyc2VzLCAgc28gc29tZSBvZiB0aGUgbWF0ZXJpYWwgaW4gdGhpcyBsZWN0dXJlIHNob3VsZCBiZSByZXZpc2lvbi4NCg0KTm9uZXRoZWxlc3MsIHNpbXBsZSBsaW5lYXIgcmVncmVzc2lvbiBwcm92aWRlcyBhIGZyaWVuZGx5IGNvbnRleHQgdG8gIGludHJvZHVjZSBub3RhdGlvbiwgcmVtaW5kIHlvdSBvZiBmdW5kYW1lbnRhbCBjb25jZXB0cywgYW5kIHRha2UgYSAgZmlyc3QgbG9vayBhdCBzdGF0aXN0aWNhbCBtb2RlbGxpbmcgd2l0aCBSLg0KDQojIyBQdWxzZSBhbmQgSGVpZ2h0DQoNClRoZSBmb2xsb3dpbmcgUiBjb2RlDQoNCi0gcmVhZHMgdGhlIHB1bHNlIGRhdGEgaW50byBSIChmcm9tIGEgdGV4dCBmaWxlKTsgYW5kIHRoZW4gDQotIHByaW50cyBvdXQgdGhlIGZpcnN0IGZldyByb3dzIG9mIHRoZSBkYXRhIGZvciBzaW1wbGUgdmlld2luZy4NCg0KYGBge3IgZ2V0UHVsc2VEYXRhLCBlY2hvPS0xLCBldmFsPS0yfQ0KUHVsc2VEYXRhIDwtIHJlYWQuY3N2KGZpbGU9Ii4uLy4uL2RhdGEvcHVsc2UuY3N2IiwgaGVhZGVyPVQpDQpQdWxzZURhdGEgPC0gcmVhZC5jc3YoZmlsZT0iaHR0cHM6Ly9yLXJlc291cmNlcy5tYXNzZXkuYWMubnovZGF0YS8xNjEyNTEvcHVsc2UuY3N2IiwgaGVhZGVyPVRSVUUpDQpoZWFkKFB1bHNlRGF0YSkNCmBgYA0KDQpgciB4ZnVuOjplbWJlZF9maWxlKCIuLi8uLi9kYXRhL3B1bHNlLmNzdiIpYCANCg0KLSBXZSB3b3VsZCBub3JtYWxseSB0aGVuIGxvb2sgYXQgc29tZSBwbG90cy4gT25seSBvbmUgc2NhdHRlciBwbG90IGlzIHBvc3NpYmxlLiBXZSBjb3VsZCBkaXNwbGF5IGl0IHVzaW5nIGVpdGhlciBhIHNpbXBsZSBgcGxvdCgpYCwgb3IgYSBtb3JlIGZhbmN5IGBnZ3Bsb3QoKWAsIGJ1dCBpdCBpcyBlc3NlbnRpYWxseSB0aGUgc2FtZSBncmFwaC4gWW91IGNvdWxkIGNvbXBhcmUgdGhlIHJlc3VsdHMgb2YgdGhlIG9sZCBiYXNlIGdyYXBoaWNzIHN0eWxlOg0KDQpgYGByDQpwbG90KCBQdWxzZX5IZWlnaHQsIGRhdGE9UHVsc2VEYXRhKQ0KYGBgDQoNCndpdGggdGhlIG1vcmUgbW9kZXJuIGBnZ3Bsb3QyYCBzdHlsZToNCg0KDQpgYGB7ciBQdWxzZVBsb3QsIGZpZy5jYXA9IlBsb3Qgb2YgcmVzdGluZyBwdWxzZSByYXRlIChiZWF0cyBwZXIgbWludXRlKSB2ZXJzdXMgaGVpZ2h0IChpbiBjZW50aW1ldGVycykgZm9yIGEgc2FtcGxlIG9mIDUwIGhvc3BpdGFsIHBhdGllbnRzLiBTb3VyY2U6IEEgSGFuZGJvb2sgb2YgU21hbGwgRGF0YSBTZXRzIGJ5IEhhbmQsIERhbHksIEx1bm4sIE1jQ29ud2F5IGFuZCBPc3Ryb3dza2kuIn0NCmxpYnJhcnkoZ2dwbG90MikNClB1bHNlRGF0YSB8PiBnZ3Bsb3QobWFwcGluZyA9IGFlcyh4PUhlaWdodCwgeT1QdWxzZSkpICsgZ2VvbV9wb2ludCgpICsNCnlsYWIoIlJlc3RpbmcgcHVsc2UgcmF0ZSAoYmVhdHMgcGVyIG1pbnV0ZSkiKSArICB4bGFiKCJIZWlnaHQgKGluIGNlbnRpbWV0ZXJzKSAiKSANCmBgYA0KDQpUaGUgY2hvaWNlIGlzIHlvdXJzOyB5b3UgbmVlZCB0byBjaG9vc2Ugd2hhdCBpcyBiZXN0IGZvciB5b3VyIGF1ZGllbmNlLiBJZiB5b3VyIGF1ZGllbmNlIGlzIGp1c3QgeW91LCB0aGVuIGRvIHdoYXQgeW91IGZpbmQgZWFzaWVyLiBJZiB5b3UncmUgd2FudGluZyB0byBsb29rIGdvb2Qgd2hlbiB5b3UncmUgZGVsaXZlcmluZyAgcHJlc2VudGF0aW9ucywgdGhlbiB5b3UnbGwgYmVuZWZpdCBmcm9tIGdldHRpbmcgdG8gZ3JpcHMgd2l0aCB0aGUgYGdncGxvdCgpYCB3YXkgb2Ygd29ya2luZy4NCiAgDQpJdCBpcyBvZiBpbnRlcmVzdCB0byBrbm93IHdoZXRoZXIgcHVsc2UgcmF0ZSBpcyB0cnVseSBkZXBlbmRlbnQgb24gaGVpZ2h0Lg0KDQpWaWV3IHB1bHNlIGFzIHJlc3BvbnNlICgqeSopIHZhcmlhYmxlIGFuZCBoZWlnaHQgYXMgcHJlZGljdG9yICAoKngqKSB2YXJpYWJsZS4NCg0KV2UgY2FuIGZvcm1hbGx5IHRlc3Qgd2hldGhlciB0aGlzIHJlYWxseSBpcyB0aGUgY2FzZSBieSB1c2luZyBhIHNpbXBsZSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbC4NCg0KTm90ZSB0aGVyZSBpcyBvbmUgb2JzZXJ2YXRpb24gKHBhdGllbnQgcmVzdGluZyBwdWxzZSAxMTYpIHdoaWNoIGlzIGRpc3RhbnQgZnJvbSB0aGUgbWFpbiBidWxrIG9mIGRhdGEuDQoNCiMjIEJhc2ljcyBvZiBTaW1wbGUgTGluZWFyIFJlZ3Jlc3Npb246IERhdGENCg0KUXVhbnRpdGF0aXZlIGRhdGEgb2NjdXIgaW4gcGFpcnM6ICooeH4xfix5fjF+KSwgLi4uLCh4fm5+LHl+bn4pKi4NCg0KKnl+aX4qIGRlbm90ZXMgdGhlICoqcmVzcG9uc2UqKiB2YXJpYWJsZSBhbmQgKnh+aX4qIHRoZSBleHBsYW5hdG9yeSB2YXJpYWJsZSBmb3IgdGhlICppKl50aF4gaW5kaXZpZHVhbC4NCg0KVGhlIGFpbSBpcyB0byBlc3RpbWF0ZSB0aGUgKiptZWFuKiogcmVzcG9uc2UgZm9yIGFueSBnaXZlbiB2YWx1ZSBvZiB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGUuDQoNCkl0IHRoZXJlZm9yZSBtYWtlcyBzZW5zZSB0byB0aGluayBvZiAqeH4xfiwuLi4seH5ufiogYXMgZml4ZWQgY29uc3RhbnRzLCB3aGlsZSAqeX4xfiwgLi4uLCB5fm5+KiBhcmUgKipjaGFuY2UqKiB2YWx1ZXMgdGFrZW4gYnkgcmFuZG9tIHZhcmlhYmxlcyAqWX4xfiwuLi4sIFl+bn4qLg0KDQojIyBCYXNpY3Mgb2YgU2ltcGxlIExpbmVhciBSZWdyZXNzaW9uOiBNb2RlbA0KDQpOb3cgcmVjYWxsIHRoYXQgVGhlIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsIGlzDQoNCiQkWV9pID0gXGJldGFfMCArIFxiZXRhXzEgeF9pICsgXHZhcmVwc2lsb25faSQkIA0KDQp3aGVyZQ0KDQotICRcYmV0YV8wLCBcYmV0YV8xJCBhcmUgKipyZWdyZXNzaW9uIHBhcmFtZXRlcnMqKi4NCi0gJFx2YXJlcHNpbG9uXzEsIFxsZG90cyAsXHZhcmVwc2lsb25fbiQgYXJlIGVycm9yIHRlcm1zLCBhYm91dCAgd2hpY2ggd2UgbWFrZSB0aGUgZm9sbG93aW5nIGFzc3VtcHRpb25zLg0KDQoqKipBMSoqKi4gVGhlIGV4cGVjdGVkIHZhbHVlIG9mIHRoZSBlcnJvcnMgJEVbXHZhcmVwc2lsb25faV0gPSAwJCBmb3IgKmk9MSwuLi4sbiouDQoNCg0KKioqQTIqKiouIFRoZSBlcnJvcnMgJFx2YXJlcHNpbG9uXzEsIFxsZG90cyAsXHZhcmVwc2lsb25fbiQgYXJlIGluZGVwZW5kZW50LiBOLkIuICoqKkEyKioqIG1pZ2h0IGJlIG5ldyB0byB5b3UuIE5lYXIgdGhlIGVuZCBvZiB0aGUgY291cnNlIHdlIHdpbGwgY29uc2lkZXIgd2hhdCBoYXBwZW5zIGlmIHRoaXMgYXNzdW1wdGlvbiBpcyB3cm9uZy4gDQoNCioqKkEzKioqLiAgVGhlIGVycm9yIHZhcmlhbmNlICRcbWJveHt2YXJ9KFx2YXJlcHNpbG9uX2kpID0gXHNpZ21hXjIkIChhbiB1bmtub3duIGNvbnN0YW50KSBmb3IgKmk9MSwuLi4sbiouDQoNCioqKkE0KioqLiBUaGUgZXJyb3JzICRcdmFyZXBzaWxvbl8xLCBcbGRvdHMgLFx2YXJlcHNpbG9uX24kIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZC4NCg0KTi5CLiBXZSByZWZlciBiYWNrIHRvIHRoZXNlIGZvdXIgYXNzdW1wdGlvbnMgbWFueSB0aW1lcyBpbiB0aGlzIGNvdXJzZTsgdGhleSB3aWxsIG9mdGVuIGJlIHJlZmVycmVkIHRvIHVzaW5nIHRoZSBzaG9ydGhhbmQgICoqKkExKioqIHRvICoqKkE0KioqLg0KDQoNClRoZSB2YWxpZGl0eSBvZiB0aGUgc2ltcGxlIHJlZ3Jlc3Npb24gbW9kZWwgZ2l2ZW4gYWJvdmUgIGFuZCBBc3N1bXB0aW9uICoqKkExKioqIGltcGxpZXMgdGhhdA0KDQokJEVbWV9pXSA9IFxtdV9pID0gXGJldGFfMCArIFxiZXRhXzEgeF9pJCQNCg0KU28gd2Ugc2F5IHRoYXQgJEVbWV9pXSA9IFxtdV9pJCBpcyB0aGUgZXhwZWN0ZWQgdmFsdWUgb2YgKll+aX4qIGdpdmVuIChvciAgKipjb25kaXRpb25hbCB1cG9uKiopICp4fml+Ki4NCg0KDQojIyBQYXJhbWV0ZXIgRXN0aW1hdGlvbg0KDQpIb3cgZG8gd2UgZXN0aW1hdGUgdGhlIHBhcmFtZXRlcnMgJFxiZXRhXzAkIGFuZCAkXGJldGFfMSQ/IA0KDQpUaGUgc2ltcGxlc3QgbWV0aG9kLCB3aGljaCBpcyBvcHRpbWFsIGlmIHRoZSBhc3N1bXB0aW9ucyBBMS1BNCBhcmUgY29ycmVjdCwgaXMgdG8gdXNlIHRoZSBtZXRob2Qgb2YgbGVhc3Qgc3F1YXJlcy4NCg0KDQpMZWFzdCBzcXVhcmVzIGVzdGltYXRlcyAoTFNFcykgJFxoYXR7XGJldGFfMH0kIGFuZCAkXGhhdHtcYmV0YV8xfSQsIGFyZSB0aG9zZSB2YWx1ZXMgdGhhdCBtaW5pbWl6ZSB0aGUgc3VtIG9mIHNxdWFyZXMNCg0KJCRcYmVnaW57YWxpZ25lZH0gU1MoXGJldGFfMCwgXGJldGFfMSkgJj0mIFxzdW1fe2k9MX1ebiAoeV9pIC0gXG11X2kpXjJcXA0KJj0mIFxzdW1fe2k9MX1ebiAoeV9pIC0gXGJldGFfMCAtIFxiZXRhXzEgeF9pKV4yLg0KXGVuZHthbGlnbmVkfSQkDQoNCg0KSXQgY2FuIGJlIHNob3duICh1c2luZyBjYWxjdWx1cykgdGhhdCAkXGhhdHtcYmV0YV8wfSQgYW5kICRcaGF0e1xiZXRhXzF9JCBhcmUgZ2l2ZW4gYnkNCg0KJCRcaGF0e1xiZXRhXzF9ID0gXGZyYWN7c197eHl9fXtzX3t4eH19JCQgDQp3aGVyZQ0KDQokc197eHl9ID0gXHN1bV97aT0xfV5uICh4X2kgLSBcYmFyIHgpKHlfaSAtIFxiYXIgeSkkOw0KDQokc197eHh9ID0gXHN1bV97aT0xfV5uICh4X2kgLSBcYmFyIHgpXjIkOw0KDQphbmQgJFxoYXR7XGJldGFfMH0gPSBcYmFyIHkgLSBcaGF0e1xiZXRhXzF9IFxiYXIgeCBcOyAuJA0KDQpUaGUgbGFzdCBmb3JtdWxhIGltcGxpZXMgdGhhdCB0aGUgbGVhc3Qgc3F1YXJlcyByZWdyZXNzaW9uIGxpbmUgZ29lcyB0aHJvdWdoIHRoZSBjZW50cm9pZCAkXGxlZnQoXGJhciB4LCBcYmFyIHkgXHJpZ2h0KSQgb2YgdGhlIGRhdGEuIA0KDQoNCiMjIFByb3BlcnRpZXMgb2YgTFNFcw0KDQpTb21lIG1hdGhzIHNob3dzIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgb2YgJFxoYXR7XGJldGFfMH0kIGFuZCAkXGhhdHtcYmV0YV8xfSQgYXJlOg0KDQokJFxoYXR7XGJldGFfMX0gXHNpbSBOIFxsZWZ0KFxiZXRhXzEsICBcZnJhY3tcc2lnbWFeMn17c197eHh9fSBccmlnaHQgKSQkDQogYW5kDQokJFxoYXR7XGJldGFfMH0gXHNpbSBOIFxsZWZ0KFxiZXRhXzAgLCBcLCBcc2lnbWFeMlxsZWZ0W1xmcmFjezF9e259ICsgDQpcZnJhY3tcYmFyIHheMn17c197eHh9fVxyaWdodCBdIFxyaWdodCApIFw7IC4kJA0KDQpUaGUgZGV0YWlscyBvZiB0aGUgIGFib3ZlIGZvcm11bGFzIGFyZSBub3QgaW1wb3J0YW50LiAgVGhlICpwcmFjdGljYWwqIHBvaW50IG9mIHRoZSBmb3JtdWxhcyBpcyB0aGF0IA0KDQoxLiB0aGUgZXN0aW1hdGVzIGFyZSB1bmJpYXNlZCAoY2VudHJlZCBvbiB0aGUgcmlnaHQgdGhpbmcpLiBUaGlzIGltcGxpZXMgdGhhdCByYW5kb20gc2FtcGxpbmcgc2hvdWxkIGdpdmUgeW91IGFib3V0IHRoZSByaWdodCBhbnN3ZXIgKGF0IGxlYXN0IGlmIHdlIGhhdmUgYSBiaWcgZW5vdWdoIGRhdGFzZXQpLCAgIGFuZCANCjIuIHRoZSBlc3RpbWF0ZXMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLCB3aGljaCBtZWFucyB3ZSBjYW4gY2FsY3VsYXRlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFuZCBoeXBvdGhlc2lzIHRlc3RzIGZvciAkXGJldGFfMCQgYW5kICRcYmV0YV8xJC4NCg0KVGhlIHZhcmlhbmNlIHRlcm1zIChzZWNvbmQgdGVybSB3aXRoaW4gZWFjaCBvZiB0aGUgTiggLCApIGZvcm11bGFlKSBhcmUgZ2l2ZW4gZm9yIGNvbXBsZXRlbmVzcyBvZiB5b3VyIG5vdGVzLCBidXQgYXJlIG5vdCBzb21ldGhpbmcgd2Ugd2lsbCBuZWVkIHRvIGNhbGN1bGF0ZSBvdXJzZWx2ZXMuIA0KDQoNCg0KIyMjIENsYXNzIGRpc2N1c3Npb24NCg0KIHdoYXQgZG8gdGhlc2Ugc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyB0ZWxsIHVzPw0KDQoNCkp1c3QgZm9yIGlsbHVzdHJhdGlvbiwgbGV0J3Mgc2F5IHRoYXQgdGhlIG1vZGVsIGZpdHRlZCB0byB0aGUgcG9wdWxhdGlvbiBvZiBkYXRhIGlzICRZX2kgPSAxICsgMiB4X2kgKyBcdmFyZXBzaWxvbl9pJCAqKGk9MSwyLC4uLixuKSogd2l0aCAkXHZhcmVwc2lsb24gXHNpbSBOKDAsMl4yKSQNCg0KVG8gbWFrZSBvdXIgY2FsY3VsYXRpb25zIGEgc2ltcGxlciB0YXNrLCBsZXQncyBhbHNvIHNheSB0aGF0IHRoZSBjb3ZhcmlhdGUgSW5mb3JtYXRpb24gd2UgbmVlZCBpczogU2FtcGxlIHNpemUgKm4gPSAzMiosICRcYmFye3h9ID0gXHNxcnR7Mn0kLCBhbmQgKnN+eHh+ID0gNjQqLg0KDQoNCg0KIyMjIFF1ZXN0aW9uOiANCg0KQ2FsY3VsYXRlIA0KDQooaSkgJFAoXGhhdHtcYmV0YV8xfSA+IDMpJDsgYW5kDQooaWkpICRQKFxoYXR7XGJldGFfMH0gPCAwKSQuDQoNCg0KIyMjIEFuc3dlciB0byAoaSk6IA0KDQpXZSBhcmUgbG9va2luZyBmb3IgJFAoXGhhdHtcYmV0YV8xfSA+IDMpJA0KDQpXZSBrbm93IHRoYXQgdGhlIHBhcmFtZXRlciBpcyBub3JtYWxseSBkaXN0cmlidXRlZCBzbyB3ZSB3aWxsIHVzZSB0aGUgc3RhbmRhcmQgbm9ybWFsIGRpc3RyaWJ1dGlvbiB0byBmaW5kIHRoZSBwcm9iYWJpbGl0eS4gTm90ZSB0aGF0ICRaIFxzaW0gTigwLDEpJA0KDQpBZnRlciBpbnNlcnRpbmcgdGhlIHZhbHVlcyBnaXZlbiBhYm92ZSwgdGhpcyBpcyBlcXVhbCB0byAkUCBcbGVmdCAoIFogPiBcZnJhY3szIC0gXGJldGFfMX17KFxzaWdtYS9cc3FydHtzX3t4eH19KSB9IFxyaWdodCApJA0KDQpTaW1wbGlmeWluZyBnaXZlcyAkUCBcbGVmdCAoIFogPiBcZnJhY3szIC0gMn17KDIvXHNxcnR7NjR9KSB9IFxyaWdodCApID0gUCBcbGVmdCAoIFogPiBcZnJhY3sxfXsyLzh9IFxyaWdodCApID0gUChaID4gNCkkDQoNCndoaWNoIGlzIGFwcHJveGltYXRlbHkgemVyby4NCg0KDQojIyMgQW5zd2VyIHRvIChpaSk6IA0KDQpZb3VyIHR1cm4hDQoNCiMjIEVzdGltYXRpbmcgdGhlIEVycm9yIFZhcmlhbmNlDQoNCkluIHByYWN0aWNlLCB3ZSBhcmUgYWxtb3N0IGNlcnRhaW5seSB3b3JraW5nIHdpdGggc2FtcGxlIGRhdGEsIHdoaWNoIG1lYW5zIHRoZSBlcnJvciB2YXJpYW5jZSwgJFxzaWdtYV4yJCBpcyBhbHNvIGFuIHVua25vd24gcGFyYW1ldGVyLg0KDQpJdCBpcyBpbXBvcnRhbnQgdG8gZXN0aW1hdGUgaXQgYmVjYXVzZSBpdHMgc3F1YXJlIHJvb3QgJFxzaWdtYSQgZ2l2ZXMgdXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG5hdHVyYWwgdmFyaWF0aW9uIGluIHRoZSBkYXRhIGkuZS4gIGFib3V0IGhvdyBmYXIgYXdheSB0aGUgaW5kaXZpZHVhbCBkYXRhcG9pbnRzICRZX2kkIHR5cGljYWxseSBhcmUgZnJvbSB0aGUgY2VudHJhbCBsaW5lICAkRVtZXSA9XGJldGFfMCArIFxiZXRhXzEgeCQuDQoNCg0KSXQgY2FuIGJlIGVzdGltYXRlZCB1c2luZyB0aGUgKipyZXNpZHVhbCBzdW0gb2Ygc3F1YXJlcyAoUlNTKSoqLCBkZWZpbmVkIGJ5IA0KDQokJFJTUyA9IFxzdW1fe2k9MX1ebiAoeV9pIC0gXGhhdHtcbXVfaX0pXjIgPSBcc3VtX3tpPTF9Xm4gKHlfaSAtIFxoYXR7XGJldGFfMH0gLSBcaGF0e1xiZXRhXzF9IHhfaSApXjIgXDsgLiQkIA0KDQp3aGVyZSAkXGhhdHtcbXVfaX0gPSBcaGF0e1xiZXRhXzB9ICsgXGhhdHtcYmV0YV8xfSB4X2kkIGlzIHRoZSAqaSpedGheDQogKipmaXR0ZWQgdmFsdWUqKjsgJGVfaSA9IHlfaSAtIFxoYXR7XG11X2l9JCBpcyB0aGUgKmkqXnRoXiAgKipyZXNpZHVhbCoqLiANCg0KVGhlbiBhbiBlc3RpbWF0ZSBvZiAkXHNpZ21hXjIkIGlzIGdpdmVuIGJ5IA0KDQokJHNeMiA9IFxmcmFjezF9e24tMn0gUlNTLiQkDQoNCg0KTi5CLiBXZSBhbG1vc3QgYWx3YXlzIHVzZSB0aGUgbm90YXRpb24gJFxoYXQgeV9pJCAgaW5zdGVhZCBvZiAkXGhhdHtcbXVfaX0kLCBidXQgZG9uJ3QgbG9zZSBzaWdodCBvZiB0aGUgZmFjdCB0aGF0IHdlIGFyZSBlc3RpbWF0aW5nIGFuIGF2ZXJhZ2UgZXZlbiBpZiB0aGF0IGF2ZXJhZ2UgaXMgY2hhbmdpbmcgYWNjb3JkaW5nIHRvIHRoZSB2YWx1ZSBvZiBhIHByZWRpY3Rvci4gICAgDQogDQoNCiMjIFJldmlzZWQgU2FtcGxpbmcgRGlzdHJpYnV0aW9ucw0KDQpXZSBoYXZlIHNlZW4gdGhlIHRlcm0gJFxzaWdtYV4yJCBpbiBhIG51bWJlciBvZiBlcXVhdGlvbnMuIFRoaXMgaXMgbm90ICoqKmtub3duKioqLCBidXQgbXVzdCBiZSBlc3RpbWF0ZWQgZnJvbSBvdXIgZGF0YS4gV2hlbiB3ZSBkbyBub3Qga25vdyB0aGlzICJ0cnVlIiB2YXJpYW5jZSwgd2UgdXNlIGFuIGVzdGltYXRlIG9yICJzYW1wbGUgdmFyaWFuY2UiIGluc3RlYWQuIFRoaXMgbWVhbnMgd2UgbXVzdCBhbHRlciB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIHRvby4gVGhpcyBoYXBwZW5lZCB3aGVuIHlvdSB1c2VkIHNhbXBsZSBkYXRhIHRvIGZpbmQgYW4gaW50ZXJ2YWwgZXN0aW1hdGUgb2YgdGhlIHBvcHVsYXRpb24gbWVhbiBvciBjb25kdWN0ZWQgYSBvbmUgc2FtcGxlIHRlc3QgYWJvdXQgdGhlIHBvcHVsYXRpb24gbWVhbi4NCg0KDQpTdGFuZGFyZGl6aW5nIHRoZSBub3JtYWwgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mICRcaGF0e1xiZXRhXzF9JCBnaXZlcw0KDQokJFxmcmFje1xoYXR7XGJldGFfMX0gLSBcYmV0YV8xfXtcc2lnbWEvXHNxcnR7c197eHh9fX0gXHNpbSBOKDAsMSkkJA0KDQpSZXBsYWNpbmcgJFxzaWdtYV4yJCB3aXRoIHRoZSBlc3RpbWF0ZSAqc14yXiogY2hhbmdlcyB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mICRcaGF0e1xiZXRhXzF9JDoNCg0KJCRcZnJhY3tcaGF0e1xiZXRhXzF9IC0gXGJldGFfMX17U0UoXGhhdHtcYmV0YV8xfSl9IFxzaW0gdChuLTIpJCQgDQoNCndoZXJlDQoNCi0gdGhlIG5vdGF0aW9uICp0KG4tMikqIG9yIHNvbWV0aW1lcyAqdH5uLTJ+KiBzaWduaWZpZXMgYSAqdCotZGlzdHJpYnV0aW9uIHdpdGggKihuLTIpKiBkZWdyZWVzIG9mIGZyZWVkb20gKGRmKQ0KLSB0aGUgdGVybSAkU0UoXGhhdHtcYmV0YV8xfSkgPSBcZnJhY3tzfXtcc3FydHtzX3t4eH19fSQgaXMgdGhlICoqc3RhbmRhcmQgZXJyb3IqKiBvZiAkXGhhdHtcYmV0YV8xfSQ7IGkuZS4gdGhlDQogICAgICAgIChlc3RpbWF0ZWQpIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mDQogJFxoYXR7XGJldGFfMX0kLg0KDQoNClRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gZm9yICRcaGF0e1xiZXRhXzF9JCBmb3JtcyB0aGUgYmFzaXMgZm9yIHRlc3RpbmcNCiAgICBoeXBvdGhlc2VzIGFuZCBjb25zdHJ1Y3RpbmcgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yICRcYmV0YV8xJC4NCg0KRm9yIHRlc3RpbmcgKkh+MH4qOiAkXGJldGFfMSA9IFxiZXRhXzFeMCQsIGFnYWluc3QNCiAgICAqSH4xfio6ICRcYmV0YV8xIFxuZSBcYmV0YV8xXjAkLCB1c2UgdGhlIHRlc3Qgc3RhdGlzdGljDQoNCiQkdCA9IFxmcmFje1xoYXR7XGJldGFfMX0gLSBcYmV0YV8xXjB9e1NFKFxoYXR7XGJldGFfMX0pfS4kJA0KDQpXZSBmaW5kIHAtdmFsdWUgY29ycmVzcG9uZGluZyB0byAqdCouIEFzIHVzdWFsLCBzbWFsbGVyICpQKg0KICAgIGluZGljYXRlcyBtb3JlIGV2aWRlbmNlIGFnYWluc3QgKkh+MH4qLg0KDQpBICQxMDAoMS1cYWxwaGEpXCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yICRcYmV0YV8xJCBpcw0KDQokJFxsZWZ0IChcaGF0e1xiZXRhXzF9IC0gdF97XGFscGhhLzJ9KG4tMikgU0UoXGhhdHtcYmV0YV8xfSksIFwsIA0KICAgIFxoYXR7XGJldGFfMX0gKyB0X3tcYWxwaGEvMn0obi0yKSBTRShcaGF0e1xiZXRhXzF9KQ0KICAgXHJpZ2h0ICkgLiQkDQoNCiMjIFRoZSAqdCogZGlzdHJpYnV0aW9uDQoNClRoZSAqdCogZGlzdHJpYnV0aW9uIGlzIHVzZWQgZm9yIHNtYWxsIHNhbXBsZXMgd2hlbiB3ZSBkbyBub3Qga25vdyB0aGUgcG9wdWxhdGlvbiB2YXJpYW5jZS4NCg0KWW91J2xsIHNlZSB0aGF0IHdlIHN0aWxsIHVzZSB0aGUgKnQqIGRpc3RyaWJ1dGlvbiB3aGVuIHNhbXBsZXMgYXJlIHNvIGxhcmdlIHRoYXQgaXQgZG9lc24ndCBhY3R1YWxseSBtYXR0ZXIuIFdoeSBkb2Vzbid0IGl0IG1hdHRlcj8gQmVjYXVzZSB0aGUgKnQqIGRpc3RyaWJ1dGlvbiBnZXRzIGNsb3NlciBhbmQgY2xvc2VyIHRvIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIGFzIHRoZSBzYW1wbGUgc2l6ZSBpbmNyZWFzZXMuDQoNCmBgYHtyIFREaXN0cmlidXRpb25zLCBlY2hvPUZBTFNFLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD02LCBmaWcuY2FwPSJQcm9iYWJpbGl0eSBkZW5zaXR5IGZ1bmN0aW9ucyBmb3IgKnQqIGRpc3RyaWJ1dGlvbnM7IEFzIGRmID0xMCwyMCwzMCwgKGxpZ2h0IHRvIGRhcmsgYmx1ZSksIHRoZSBjdXJ2ZXMgZ2V0IGNsb3NlciB0byB0aGUgbm9ybWFsIGN1cnZlIChibGFjaykifQ0KeD0oLTM1MDozNTApLzEwMA0KeTEgPSBkbm9ybSh4KQ0KcGxvdCh4LCB5MSwgeWxhYj0iZih4KSIsIHR5cGU9ImwiKQ0KeTIgPSBkdCh4LGRmPTEwKQ0KbGluZXMoeCwgeTIsIGNvbD0ibGlnaHRibHVlIikNCnkzID0gZHQoeCxkZj0yMCkNCmxpbmVzKHgsIHkzLCBjb2w9ImJsdWUiKQ0KeTQgPSBkdCh4LGRmPTMwKQ0KbGluZXMoeCwgeTQsIGNvbD0iZGFya2JsdWUiKQ0KYGBgDQoNClRoZSAiZmF0dGVyIiB0YWlscyBvZiB0aGUgKnQqIGRpc3RyaWJ1dGlvbiBtZWFuIHRoYXQgdGhlICoqY3JpdGljYWwgdmFsdWVzKiogd2UgdXNlIGluIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFyZSBsYXJnZXIgZm9yIHNtYWxsZXIgc2FtcGxlIHNpemVzLg0KDQoNCiMjIEJhY2sgdG8gdGhlIGV4YW1wbGUNCg0KRm9yIHRoZSBwdWxzZSBhbmQgaGVpZ2h0IGRhdGEsIGl0IGNhbiBiZSBzaG93biB0aGF0IHRoZQ0KICAgIGZpdHRlZCByZWdyZXNzaW9uIGxpbmUgKGkuZS4gdGhlIHJlZ3Jlc3Npb24gbGluZSB3aXRoDQogICAgbGVhc3Qgc3F1YXJlcyBlc3RpbWF0ZXMgaW4gcGxhY2Ugb2YgdGhlIHVua25vd24gbW9kZWwgcGFyYW1ldGVycykgaXMNCg0KJCRFW1xtYm94e1B1bHNlfV0gPSA0Ni45MDcgKyAwLjIwOTh+XG1ib3h7SGVpZ2h0fSQkDQoNCi0gSGVuY2UgJFxoYXR7XGJldGFfMX0gPSAwLjIwOTgkLg0KDQpBbHNvLCBpdCBjYW4gYmUgc2hvd24gdGhhdCAkU0UoXGhhdHtcYmV0YV8xfSkgPSAwLjEzNTQkLg0KDQpGaW5hbGx5LCByZWNhbGwgdGhhdCAqbj01MCouDQoNClF1ZXN0aW9uOiBEbyB0aGUgZGF0YSBwcm92aWRlIGV2aWRlbmNlIHRoZSBwdWxzZSByYXRlIGRlcGVuZHMgb24gaGVpZ2h0Pw0KDQoNClNvbHV0aW9uOiBUbyBhbnN3ZXIgdGhpcyBxdWVzdGlvbiwgd2Ugd2lsbCB0ZXN0DQogICAgDQotICpIfjB+KjogJFxiZXRhXzEgPSAwJCwgdmVyc3VzDQogICAgDQotICpIfjF+KjogJFxiZXRhXzEgXG5lIDAkDQoNClRoZSB0ZXN0IHN0YXRpc3RpYyBpcw0KDQokJHQgPSBcZnJhY3tcaGF0e1xiZXRhXzF9IC0gXGJldGFfMV4wfXtTRShcaGF0e1xiZXRhXzF9KX0NCiAgICAgPSBcZnJhY3swLjIwOTh9ezAuMTM1NH0NCiAgICAgPSAxLjU0OSQkDQoNClRoZSAoMi1zaWRlZCkgKlAqLXZhbHVlIGlzICRQPVAofFR8ID4gMS41NDkpID0gMiBcdGltZXMgUChUID4gMS41NDkpID0gMiBcdGltZXMgMC4wNjM5OCA9IDAuMTI4JCwgc28gd2UgY29uY2x1ZGUgdGhhdCB0aGUgZGF0YSBwcm92aWRlIG5vIGV2aWRlbmNlIG9mIGEgcmVsYXRpb25zaGlwDQogICAgYmV0d2VlbiBwdWxzZSByYXRlIGFuZCBoZWlnaHQuDQo=