In this handout, I use ChatGPT 4.0 and the KeyMate.AI Search plugin to synthesize the information from the textbook, give examples, and create R code. All prompts are exact, but some of the output may be modified for correctness.

Hanck, Arnold, Gerber, and Schmelzer (2023). Introduction to Econometrics with R. https://www.econometrics-with-r.org/index.html. This book is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Prompt

Synthesize the information in these websites. Include all relevant formulas and definitions.

https://www.econometrics-with-r.org/3.1-estimation-of-the-population-mean.html

https://www.econometrics-with-r.org/3.2-potsm.html

https://www.econometrics-with-r.org/3.3-hypothesis-tests-concerning-the-population-mean.html

3.1 Estimation of the Population Mean

  • Population Mean (μ): The average of all possible observations in a population.
  • Sample Mean (x̄): The average of observations in a sample.
  • Central Limit Theorem: For a sufficiently large sample size, the distribution of the sample mean will be approximately normally distributed, regardless of the population’s distribution.
  • Standard Error (SE): Measures the dispersion of the sample mean. It is calculated as: \[ SE = \frac{σ}{\sqrt{n}} \] Where:
    • \(σ\) is the population standard deviation.
    • \(n\) is the sample size.
  • Confidence Interval: Gives an estimated range of values which is likely to include the population mean. It is calculated as: \[ x̄ ± z \times SE \] Where:
    • \(z\) is the z-value corresponding to the desired confidence level.

3.2 Point of Symmetry and the Median

  • Point of Symmetry (POS): A value for which the distribution of the data is symmetric. For a normal distribution, the POS is equal to the mean.
  • Median: The value that separates the higher half from the lower half of a data sample. For a symmetric distribution, the median is equal to the POS.
  • Skewness: A measure of the asymmetry of the distribution of a dataset. Positive skewness indicates that the tail on the right side is longer than the left side, and vice versa.
  • Kurtosis: Measures the “tailedness” of the distribution. High kurtosis indicates a distribution with tails heavier than a normal distribution, and low kurtosis indicates a distribution with tails lighter than a normal distribution.

3.3 Hypothesis Tests Concerning the Population Mean

  • Null Hypothesis (H0): A statement that there is no effect or no difference. It is a starting point for statistical significance testing.
  • Alternative Hypothesis (H1): A statement that indicates the presence of an effect or difference.
  • Test Statistic: A standardized value that is calculated from sample data during a hypothesis test. It helps in deciding whether to reject the null hypothesis.
  • P-value: The probability of observing a test statistic as extreme as, or more extreme than, the statistic computed from the sample, given that the null hypothesis is true.
  • Decision Rule: If the p-value is less than the chosen significance level (α), then the null hypothesis is rejected in favor of the alternative hypothesis.
  • Type I Error: Occurs when the null hypothesis is true, but it is rejected.
  • Type II Error: Occurs when the null hypothesis is false, but it is not rejected.

This synthesis provides an overview of the concepts related to the estimation of the population mean, point of symmetry, median, and hypothesis testing concerning the population mean.

Prompt

Go into more detail about the population mean, standard error, and confidence intervals.

Population Mean (μ)

The population mean, denoted by \(\mu\), represents the average of all possible observations in a population. For instance, consider an economic variable like the hourly earnings of college graduates. To precisely calculate \(\mu\), one would need to interview every working graduate in the economy. However, due to time and cost constraints, this is often not feasible. Instead, a random sample is drawn, and the sample mean is used as an estimator for the population mean.

Standard Error (SE)

The standard error measures the dispersion or variability of the sample mean. It provides an indication of how much the sample mean is expected to vary from the true population mean. The formula for the standard error is: \[ SE = \frac{σ}{\sqrt{n}} \] Where:

  • \(σ\) is the population standard deviation.
  • \(n\) is the sample size.

The standard error is crucial because it helps in determining the precision of the sample mean as an estimate of the population mean. A smaller SE indicates that the sample mean is a more precise estimator of the population mean.

Confidence Interval

A confidence interval provides a range of values within which the true population mean is likely to fall, with a certain level of confidence. The formula for a confidence interval (for large sample sizes) is: \[ x̄ ± z \times SE \] Where:

  • \(x̄\) is the sample mean.
  • \(z\) is the z-value corresponding to the desired confidence level (e.g., 1.96 for a 95% confidence level).
  • \(SE\) is the standard error.

The width of the confidence interval provides insight into the precision of the estimate. A narrower confidence interval indicates a more precise estimate of the population mean. Conversely, a wider interval suggests more uncertainty.

In the context of the provided content, consider hourly earnings of college graduates. If we were to draw a sample and calculate the sample mean, the standard error would give us an idea of how much this sample mean might vary from the true average earnings of all college graduates. Using this standard error, we can then construct a confidence interval to estimate a range within which the true average earnings likely fall.

In summary, while the population mean provides an overall average, the standard error and confidence intervals offer insights into the reliability and precision of estimates derived from sample data.

Prompt

Create a couple real-world, economics related examples of creating hypothesis tests concerning the population mean.

Example 1: Average Household Income

Background: A government agency believes that the average annual household income in a particular city is $50,000. A local economist thinks that this figure is outdated and that the average income has increased due to recent economic growth in the region.

Hypothesis Test:

  • Null Hypothesis (H0): The average annual household income \(\mu\) is $50,000. ( H0: = $50,000 )

  • Alternative Hypothesis (H1): The average annual household income \(\mu\) is greater than $50,000. ( H1: > $50,000 )

Procedure:

  1. Collect a random sample of annual incomes from households in the city.
  2. Calculate the sample mean and standard error.
  3. Conduct a one-tailed t-test to determine if the sample mean is significantly greater than $50,000.
  4. If the p-value is less than a significance level (e.g., 0.05), reject the null hypothesis.

Example 2: Unemployment Rate

Background: A recent report suggests that the national unemployment rate is 6%. An economist believes that in a specific state, due to recent layoffs in major industries, the unemployment rate is higher than the national average.

Hypothesis Test:

  • Null Hypothesis (H0): The unemployment rate \(\mu\) in the state is 6%. \(H0: \mu = 6\%\)

  • Alternative Hypothesis (H1): The unemployment rate \(\mu\) in the state is greater than 6%. \(H1: \mu > 6\%\)

Procedure:

  1. Collect a random sample of employment statuses from residents of the state.
  2. Calculate the sample unemployment rate.
  3. Conduct a one-tailed z-test or t-test (depending on sample size and variance known) to determine if the sample unemployment rate is significantly greater than 6%.
  4. If the p-value is less than a significance level (e.g., 0.05), reject the null hypothesis.

In both examples, the hypothesis tests help in making informed decisions based on sample data and provide insights into the economic conditions of the region or state in question.

Prompt

Create some example problems where students must calculate the z-statistic and conduct a hypothesis test from data.

Example 1: Exam Scores

Background: The national average score for a standardized exam is known to be 500 with a standard deviation of 100. A school believes that its students, on average, score above the national average. To test this claim, they randomly select 36 students and find that their average score is 520.

Problem:

  1. State the null and alternative hypotheses.
  2. Calculate the z-statistic.
  3. Using a significance level of 0.05, conduct a hypothesis test to determine if the school’s claim is valid.

Solution:

    • Null Hypothesis (H0): \(\mu = 500\)
    • Alternative Hypothesis (H1): \(\mu > 500\)
  1. \(z = \frac{x̄ - \mu}{\frac{σ}{\sqrt{n}}}\)

    \(z = \frac{520 - 500}{\frac{100}{\sqrt{36}}} = \frac{20}{10} = 2\)

  2. For a one-tailed test at a significance level of 0.05, the critical z-value is approximately 1.645. Since 2 > 1.645, we reject the null hypothesis. The school’s claim is valid.

Example 2: Soda Can Filling

Background: A soda company claims that their machine fills cans with an average of 12 ounces of soda. A quality control team suspects that the machine is not filling to that level. They randomly select 49 cans and find that the average fill is 11.95 ounces with a standard deviation of 0.3 ounces.

Problem:

  1. State the null and alternative hypotheses.
  2. Calculate the z-statistic.
  3. Using a significance level of 0.05, conduct a hypothesis test to determine if the machine is filling cans with less than 12 ounces of soda.

Solution:

    • Null Hypothesis (H0): \(\mu = 12\)
    • Alternative Hypothesis (H1): \(\mu < 12\)
  1. \(z = \frac{x̄ - \mu}{\frac{σ}{\sqrt{n}}}\)

    \(z = \frac{11.95 - 12}{\frac{0.3}{\sqrt{49}}} = \frac{-0.05}{0.0429} \approx -1.165\)

  2. For a one-tailed test at a significance level of 0.05, the critical z-value is approximately -1.645. Since -1.165 > -1.645, we fail to reject the null hypothesis. The machine appears to be filling cans correctly.

Prompt

Go into more detail about the difference between the student t-distribution and t-statistics from the normal distribution and z-statistics.

Normal Distribution and Z-statistics:

  1. Normal Distribution: It is a bell-shaped, symmetrical distribution described by its mean (μ) and standard deviation (σ). The total area under its curve is 1. The standard normal distribution has a mean of 0 and a standard deviation of 1.

  2. Z-statistic (or Z-score): It represents the number of standard deviations an observation (or sample mean) is away from the population mean. It’s calculated as: \[ Z = \frac{X - μ}{σ} \] Where:

    • \(X\) is the observation (or sample mean).
    • \(μ\) is the population mean.
    • \(σ\) is the population standard deviation.
  3. When to Use: The z-statistic is used when:

    • The population standard deviation (σ) is known.
    • The sample size is large (typically \(n > 30\)), even if σ is unknown.
    • The underlying data is approximately normally distributed.

Student’s t-distribution and t-statistics:

  1. Student’s t-distribution: It is similar in shape to the normal distribution but has heavier tails. This makes it more accommodating to potential outliers. The exact shape of the t-distribution depends on a parameter called “degrees of freedom,” often denoted by \(df\). As \(df\) increases, the t-distribution approaches the normal distribution.

  2. T-statistic: It’s used when estimating the population mean from a sample, especially when the sample size is small or the population standard deviation is unknown. It’s calculated as: \[ t = \frac{x̄ - μ}{s/√n} \] Where:

    • \(x̄\) is the sample mean.
    • \(μ\) is the population mean (or hypothesized value).
    • \(s\) is the sample standard deviation.
    • \(n\) is the sample size.
  3. When to Use: The t-statistic and t-distribution are used when:

    • The population standard deviation (σ) is unknown.
    • The sample size is small (typically \(n ≤ 30\)).
    • The underlying data is approximately normally distributed or if the sample size is sufficiently large to invoke the Central Limit Theorem.

Key Differences:

  1. Standard Deviation: For z-statistics, the population standard deviation is used, while for t-statistics, the sample standard deviation is used.

  2. Distribution Shape: The t-distribution has thicker tails compared to the normal distribution. This accounts for the increased variability expected with smaller samples.

  3. Sample Size: Z-statistics are typically used for larger samples (or when the population standard deviation is known), while t-statistics are used for smaller samples.

  4. Degrees of Freedom: The t-distribution requires the specification of degrees of freedom, which is typically \(df = n - 1\) for a single sample. The concept of degrees of freedom doesn’t apply to the normal distribution.

In summary, while both the z and t distributions are foundational in inferential statistics, they are used in different scenarios based on the known information and sample size. The t-distribution provides a more conservative approach (due to its thicker tails) when dealing with smaller samples or unknown population standard deviations.

Prompt

Go into detail about the difference between one-sample, two-sample, and paired t-tests.

1. One-sample t-test:

Purpose: Used to test if the mean of a single sample is significantly different from a known or hypothesized population mean.

Hypotheses:

  • Null Hypothesis (H0): The sample mean is equal to the population mean. \(H0: \mu = \mu_0\)
  • Alternative Hypothesis (H1): The sample mean is not equal to the population mean. \(H1: \mu \neq \mu_0\)

Example: Suppose a manufacturer claims that a type of battery lasts 100 hours on average. You take a sample of batteries, test them, and want to see if the average lifespan differs from the claimed 100 hours.

2. Two-sample t-test (Independent t-test):

Purpose: Used to compare the means of two independent samples to see if they come from populations with the same mean.

Hypotheses:

  • Null Hypothesis (H0): The means of the two populations are equal. \(H0: \mu_1 = \mu_2\)
  • Alternative Hypothesis (H1): The means of the two populations are not equal. \(H1: \mu_1 \neq \mu_2\)

Example: Imagine you want to test if there’s a difference in average test scores between students taught by two different teachers. You would collect scores from a sample of students from each teacher’s class and then compare the means using the two-sample t-test.

3. Paired t-test (Dependent t-test):

Purpose: Used to compare the means of the same group at two different times or under two different conditions. The observations are paired, meaning each observation in one sample corresponds to an observation in the other sample.

Hypotheses:

  • Null Hypothesis (H0): The mean difference between paired observations is zero. \(H0: \mu_d = 0\)
  • Alternative Hypothesis (H1): The mean difference between paired observations is not zero. \(H1: \mu_d \neq 0\)

Example: Consider a clinical trial where you want to test the effectiveness of a new drug. Patients’ health metrics are measured before taking the drug and after completing the treatment. Since the measurements before and after are from the same individuals, the data is paired.

Key Differences:

  • Data Structure:

    • One-sample t-test works with a single sample.
    • Two-sample t-test works with two independent samples.
    • Paired t-test works with two related (paired) samples.
  • Application:

    • One-sample is used when comparing a sample mean to a known or hypothesized population mean.
    • Two-sample is used when comparing the means of two independent groups.
    • Paired is used when comparing the means of the same group under two different scenarios or at two different times.
  • Assumptions: All three tests assume that the data is approximately normally distributed. The two-sample t-test also assumes that the variances of the two groups are equal (homogeneity of variances), unless you’re doing a variation of the test that doesn’t make this assumption (Welch’s t-test).

Prompt

Create some examples of using R to conduct hypothesis testing of means.

Example 1: One-sample t-test

Suppose we have a sample of exam scores from 10 students, and we want to test if the average score is different from 75.

# Sample data
scores <- c(78, 82, 74, 69, 77, 83, 72, 76, 80, 71)

# One-sample t-test
t.test(scores, mu = 75)

    One Sample t-test

data:  scores
t = 0.80579, df = 9, p-value = 0.4411
alternative hypothesis: true mean is not equal to 75
95 percent confidence interval:
 72.83115 79.56885
sample estimates:
mean of x 
     76.2 

Example 2: Two-sample t-test

Imagine we have exam scores from two different classes, and we want to test if there’s a significant difference in their means.

# Sample data
class1_scores <- c(78, 82, 74, 69, 77, 83, 72, 76, 80, 71)
class2_scores <- c(85, 88, 84, 86, 87, 89, 83, 84, 82, 81)

# Two-sample t-test
t.test(class1_scores, class2_scores)

    Welch Two Sample t-test

data:  class1_scores and class2_scores
t = -5.1137, df = 14.024, p-value = 0.0001568
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -12.348348  -5.051652
sample estimates:
mean of x mean of y 
     76.2      84.9 

Example 3: Paired t-test

Suppose we measure the blood pressure of 5 patients before and after a treatment, and we want to test if the treatment had a significant effect.

# Sample data
before_treatment <- c(150, 165, 155, 142, 138)
after_treatment <- c(145, 160, 152, 140, 135)

# Paired t-test
t.test(before_treatment, after_treatment, paired = TRUE)

    Paired t-test

data:  before_treatment and after_treatment
t = 6, df = 4, p-value = 0.003883
alternative hypothesis: true mean difference is not equal to 0
95 percent confidence interval:
 1.934133 5.265867
sample estimates:
mean difference 
            3.6 

Example 4: One-sample z-test (using external package)

For large samples, we might prefer a z-test. Suppose we have a large sample of weights from a factory, and we want to test if the average weight is different from 50 grams. (Note: R doesn’t have a built-in function for the one-sample z-test, so we’ll use the z.test function from the BSDA package.)

# Install and load the BSDA package
install.packages("BSDA")
also installing the dependencies ‘proxy’, ‘e1071’

trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/proxy_0.4-27.zip'
Content type 'application/zip' length 179924 bytes (175 KB)
downloaded 175 KB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/e1071_1.7-13.zip'
Content type 'application/zip' length 653294 bytes (637 KB)
downloaded 637 KB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/BSDA_1.2.1.zip'
Content type 'application/zip' length 901430 bytes (880 KB)
downloaded 880 KB
package ‘proxy’ successfully unpacked and MD5 sums checked
package ‘e1071’ successfully unpacked and MD5 sums checked
package ‘BSDA’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\rselby\AppData\Local\Temp\RtmpYT4aIL\downloaded_packages
library(BSDA)
Loading required package: lattice

Attaching package: ‘BSDA’

The following object is masked from ‘package:datasets’:

    Orange
# Sample data (assuming a large sample)
weights <- rnorm(1000, mean = 50.5, sd = 5)  # Generating random data around 50.5 with sd = 5

# One-sample z-test
z.test(weights, mu = 50, sigma.x = sd(weights))

    One-sample z-Test

data:  weights
z = 3.6077, p-value = 0.0003089
alternative hypothesis: true mean is not equal to 50
95 percent confidence interval:
 50.25829 50.87274
sample estimates:
mean of x 
 50.56552 
LS0tDQp0aXRsZTogIklFUiBDaGFwdGVycyAzLjEtMy4zIFN1bW1hcnkiDQphdXRob3I6ICJEci4gU2VsYnktTGVhY2giDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sgDQotLS0NCg0KPHN0eWxlPg0KICAgIC8qIFN0eWxpbmcgZm9yIGgxIGhlYWRlcnMgKi8NCiAgICBoMSB7DQogICAgICAgIGZvbnQtd2VpZ2h0OiBib2xkOyAgICAgICAvKiBCb2xkICovDQogICAgICAgIGNvbG9yOiBkYXJrYmx1ZTsgICAgICAgIC8qIERhcmsgYmx1ZSBjb2xvciAqLw0KICAgIH0NCiAgICAvKiBTdHlsaW5nIGZvciBoMiBoZWFkZXJzICovDQogICAgaDIgew0KICAgICAgICBmb250LXdlaWdodDogYm9sZDsgDQogICAgfQ0KDQogICAgLyogU3R5bGluZyBmb3IgaDMgaGVhZGVycyAqLw0KICAgIGgzIHsNCiAgICAgICAgZm9udC1zdHlsZTogaXRhbGljOyAgICAgLyogSXRhbGljICovDQogICAgfQ0KPC9zdHlsZT4NCg0KDQpJbiB0aGlzIGhhbmRvdXQsIEkgdXNlIENoYXRHUFQgNC4wIGFuZCB0aGUgS2V5TWF0ZS5BSSBTZWFyY2ggcGx1Z2luIHRvIHN5bnRoZXNpemUgdGhlIGluZm9ybWF0aW9uIGZyb20gdGhlIHRleHRib29rLCBnaXZlIGV4YW1wbGVzLCBhbmQgY3JlYXRlIFIgY29kZS4gQWxsIHByb21wdHMgYXJlIGV4YWN0LCBidXQgc29tZSBvZiB0aGUgb3V0cHV0IG1heSBiZSBtb2RpZmllZCBmb3IgY29ycmVjdG5lc3MuIA0KDQpIYW5jaywgQXJub2xkLCBHZXJiZXIsIGFuZCBTY2htZWx6ZXIgKDIwMjMpLiBJbnRyb2R1Y3Rpb24gdG8gRWNvbm9tZXRyaWNzIHdpdGggUi4gaHR0cHM6Ly93d3cuZWNvbm9tZXRyaWNzLXdpdGgtci5vcmcvaW5kZXguaHRtbC4gVGhpcyBib29rIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBDcmVhdGl2ZSBDb21tb25zIEF0dHJpYnV0aW9uLU5vbkNvbW1lcmNpYWwtU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLg0KDQojIyBQcm9tcHQNClN5bnRoZXNpemUgdGhlIGluZm9ybWF0aW9uIGluIHRoZXNlIHdlYnNpdGVzLiBJbmNsdWRlIGFsbCByZWxldmFudCBmb3JtdWxhcyBhbmQgZGVmaW5pdGlvbnMuIA0KDQpodHRwczovL3d3dy5lY29ub21ldHJpY3Mtd2l0aC1yLm9yZy8zLjEtZXN0aW1hdGlvbi1vZi10aGUtcG9wdWxhdGlvbi1tZWFuLmh0bWwNCg0KaHR0cHM6Ly93d3cuZWNvbm9tZXRyaWNzLXdpdGgtci5vcmcvMy4yLXBvdHNtLmh0bWwNCg0KaHR0cHM6Ly93d3cuZWNvbm9tZXRyaWNzLXdpdGgtci5vcmcvMy4zLWh5cG90aGVzaXMtdGVzdHMtY29uY2VybmluZy10aGUtcG9wdWxhdGlvbi1tZWFuLmh0bWwNCg0KIyMjIDMuMSBFc3RpbWF0aW9uIG9mIHRoZSBQb3B1bGF0aW9uIE1lYW4NCg0KLSAqKlBvcHVsYXRpb24gTWVhbiAozrwpKio6IFRoZSBhdmVyYWdlIG9mIGFsbCBwb3NzaWJsZSBvYnNlcnZhdGlvbnMgaW4gYSBwb3B1bGF0aW9uLg0KLSAqKlNhbXBsZSBNZWFuICh4zIQpKio6IFRoZSBhdmVyYWdlIG9mIG9ic2VydmF0aW9ucyBpbiBhIHNhbXBsZS4NCi0gKipDZW50cmFsIExpbWl0IFRoZW9yZW0qKjogRm9yIGEgc3VmZmljaWVudGx5IGxhcmdlIHNhbXBsZSBzaXplLCB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBzYW1wbGUgbWVhbiB3aWxsIGJlIGFwcHJveGltYXRlbHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQsIHJlZ2FyZGxlc3Mgb2YgdGhlIHBvcHVsYXRpb24ncyBkaXN0cmlidXRpb24uDQotICoqU3RhbmRhcmQgRXJyb3IgKFNFKSoqOiBNZWFzdXJlcyB0aGUgZGlzcGVyc2lvbiBvZiB0aGUgc2FtcGxlIG1lYW4uIEl0IGlzIGNhbGN1bGF0ZWQgYXM6DQogIFxbIFNFID0gXGZyYWN7z4N9e1xzcXJ0e259fSBcXQ0KICBXaGVyZToNCiAgLSBcKCDPgyBcKSBpcyB0aGUgcG9wdWxhdGlvbiBzdGFuZGFyZCBkZXZpYXRpb24uDQogIC0gXCggbiBcKSBpcyB0aGUgc2FtcGxlIHNpemUuDQotICoqQ29uZmlkZW5jZSBJbnRlcnZhbCoqOiBHaXZlcyBhbiBlc3RpbWF0ZWQgcmFuZ2Ugb2YgdmFsdWVzIHdoaWNoIGlzIGxpa2VseSB0byBpbmNsdWRlIHRoZSBwb3B1bGF0aW9uIG1lYW4uIEl0IGlzIGNhbGN1bGF0ZWQgYXM6DQogIFxbIHjMhCDCsSB6IFx0aW1lcyBTRSBcXQ0KICBXaGVyZToNCiAgLSBcKCB6IFwpIGlzIHRoZSB6LXZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGRlc2lyZWQgY29uZmlkZW5jZSBsZXZlbC4NCg0KIyMjIDMuMiBQb2ludCBvZiBTeW1tZXRyeSBhbmQgdGhlIE1lZGlhbg0KDQotICoqUG9pbnQgb2YgU3ltbWV0cnkgKFBPUykqKjogQSB2YWx1ZSBmb3Igd2hpY2ggdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGF0YSBpcyBzeW1tZXRyaWMuIEZvciBhIG5vcm1hbCBkaXN0cmlidXRpb24sIHRoZSBQT1MgaXMgZXF1YWwgdG8gdGhlIG1lYW4uDQotICoqTWVkaWFuKio6IFRoZSB2YWx1ZSB0aGF0IHNlcGFyYXRlcyB0aGUgaGlnaGVyIGhhbGYgZnJvbSB0aGUgbG93ZXIgaGFsZiBvZiBhIGRhdGEgc2FtcGxlLiBGb3IgYSBzeW1tZXRyaWMgZGlzdHJpYnV0aW9uLCB0aGUgbWVkaWFuIGlzIGVxdWFsIHRvIHRoZSBQT1MuDQotICoqU2tld25lc3MqKjogQSBtZWFzdXJlIG9mIHRoZSBhc3ltbWV0cnkgb2YgdGhlIGRpc3RyaWJ1dGlvbiBvZiBhIGRhdGFzZXQuIFBvc2l0aXZlIHNrZXduZXNzIGluZGljYXRlcyB0aGF0IHRoZSB0YWlsIG9uIHRoZSByaWdodCBzaWRlIGlzIGxvbmdlciB0aGFuIHRoZSBsZWZ0IHNpZGUsIGFuZCB2aWNlIHZlcnNhLg0KLSAqKkt1cnRvc2lzKio6IE1lYXN1cmVzIHRoZSAidGFpbGVkbmVzcyIgb2YgdGhlIGRpc3RyaWJ1dGlvbi4gSGlnaCBrdXJ0b3NpcyBpbmRpY2F0ZXMgYSBkaXN0cmlidXRpb24gd2l0aCB0YWlscyBoZWF2aWVyIHRoYW4gYSBub3JtYWwgZGlzdHJpYnV0aW9uLCBhbmQgbG93IGt1cnRvc2lzIGluZGljYXRlcyBhIGRpc3RyaWJ1dGlvbiB3aXRoIHRhaWxzIGxpZ2h0ZXIgdGhhbiBhIG5vcm1hbCBkaXN0cmlidXRpb24uDQoNCiMjIyAzLjMgSHlwb3RoZXNpcyBUZXN0cyBDb25jZXJuaW5nIHRoZSBQb3B1bGF0aW9uIE1lYW4NCg0KLSAqKk51bGwgSHlwb3RoZXNpcyAoSDApKio6IEEgc3RhdGVtZW50IHRoYXQgdGhlcmUgaXMgbm8gZWZmZWN0IG9yIG5vIGRpZmZlcmVuY2UuIEl0IGlzIGEgc3RhcnRpbmcgcG9pbnQgZm9yIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSB0ZXN0aW5nLg0KLSAqKkFsdGVybmF0aXZlIEh5cG90aGVzaXMgKEgxKSoqOiBBIHN0YXRlbWVudCB0aGF0IGluZGljYXRlcyB0aGUgcHJlc2VuY2Ugb2YgYW4gZWZmZWN0IG9yIGRpZmZlcmVuY2UuDQotICoqVGVzdCBTdGF0aXN0aWMqKjogQSBzdGFuZGFyZGl6ZWQgdmFsdWUgdGhhdCBpcyBjYWxjdWxhdGVkIGZyb20gc2FtcGxlIGRhdGEgZHVyaW5nIGEgaHlwb3RoZXNpcyB0ZXN0LiBJdCBoZWxwcyBpbiBkZWNpZGluZyB3aGV0aGVyIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzLg0KLSAqKlAtdmFsdWUqKjogVGhlIHByb2JhYmlsaXR5IG9mIG9ic2VydmluZyBhIHRlc3Qgc3RhdGlzdGljIGFzIGV4dHJlbWUgYXMsIG9yIG1vcmUgZXh0cmVtZSB0aGFuLCB0aGUgc3RhdGlzdGljIGNvbXB1dGVkIGZyb20gdGhlIHNhbXBsZSwgZ2l2ZW4gdGhhdCB0aGUgbnVsbCBoeXBvdGhlc2lzIGlzIHRydWUuDQotICoqRGVjaXNpb24gUnVsZSoqOiBJZiB0aGUgcC12YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIGNob3NlbiBzaWduaWZpY2FuY2UgbGV2ZWwgKM6xKSwgdGhlbiB0aGUgbnVsbCBoeXBvdGhlc2lzIGlzIHJlamVjdGVkIGluIGZhdm9yIG9mIHRoZSBhbHRlcm5hdGl2ZSBoeXBvdGhlc2lzLg0KLSAqKlR5cGUgSSBFcnJvcioqOiBPY2N1cnMgd2hlbiB0aGUgbnVsbCBoeXBvdGhlc2lzIGlzIHRydWUsIGJ1dCBpdCBpcyByZWplY3RlZC4NCi0gKipUeXBlIElJIEVycm9yKio6IE9jY3VycyB3aGVuIHRoZSBudWxsIGh5cG90aGVzaXMgaXMgZmFsc2UsIGJ1dCBpdCBpcyBub3QgcmVqZWN0ZWQuDQoNClRoaXMgc3ludGhlc2lzIHByb3ZpZGVzIGFuIG92ZXJ2aWV3IG9mIHRoZSBjb25jZXB0cyByZWxhdGVkIHRvIHRoZSBlc3RpbWF0aW9uIG9mIHRoZSBwb3B1bGF0aW9uIG1lYW4sIHBvaW50IG9mIHN5bW1ldHJ5LCBtZWRpYW4sIGFuZCBoeXBvdGhlc2lzIHRlc3RpbmcgY29uY2VybmluZyB0aGUgcG9wdWxhdGlvbiBtZWFuLg0KDQojIyBQcm9tcHQNCkdvIGludG8gbW9yZSBkZXRhaWwgYWJvdXQgdGhlIHBvcHVsYXRpb24gbWVhbiwgc3RhbmRhcmQgZXJyb3IsIGFuZCBjb25maWRlbmNlIGludGVydmFscy4gDQoNCiMjIyBQb3B1bGF0aW9uIE1lYW4gKM68KQ0KVGhlIHBvcHVsYXRpb24gbWVhbiwgZGVub3RlZCBieSBcKCBcbXUgXCksIHJlcHJlc2VudHMgdGhlIGF2ZXJhZ2Ugb2YgYWxsIHBvc3NpYmxlIG9ic2VydmF0aW9ucyBpbiBhIHBvcHVsYXRpb24uIEZvciBpbnN0YW5jZSwgY29uc2lkZXIgYW4gZWNvbm9taWMgdmFyaWFibGUgbGlrZSB0aGUgaG91cmx5IGVhcm5pbmdzIG9mIGNvbGxlZ2UgZ3JhZHVhdGVzLiBUbyBwcmVjaXNlbHkgY2FsY3VsYXRlIFwoIFxtdSBcKSwgb25lIHdvdWxkIG5lZWQgdG8gaW50ZXJ2aWV3IGV2ZXJ5IHdvcmtpbmcgZ3JhZHVhdGUgaW4gdGhlIGVjb25vbXkuIEhvd2V2ZXIsIGR1ZSB0byB0aW1lIGFuZCBjb3N0IGNvbnN0cmFpbnRzLCB0aGlzIGlzIG9mdGVuIG5vdCBmZWFzaWJsZS4gSW5zdGVhZCwgYSByYW5kb20gc2FtcGxlIGlzIGRyYXduLCBhbmQgdGhlIHNhbXBsZSBtZWFuIGlzIHVzZWQgYXMgYW4gZXN0aW1hdG9yIGZvciB0aGUgcG9wdWxhdGlvbiBtZWFuLg0KDQojIyMgU3RhbmRhcmQgRXJyb3IgKFNFKQ0KVGhlIHN0YW5kYXJkIGVycm9yIG1lYXN1cmVzIHRoZSBkaXNwZXJzaW9uIG9yIHZhcmlhYmlsaXR5IG9mIHRoZSBzYW1wbGUgbWVhbi4gSXQgcHJvdmlkZXMgYW4gaW5kaWNhdGlvbiBvZiBob3cgbXVjaCB0aGUgc2FtcGxlIG1lYW4gaXMgZXhwZWN0ZWQgdG8gdmFyeSBmcm9tIHRoZSB0cnVlIHBvcHVsYXRpb24gbWVhbi4gVGhlIGZvcm11bGEgZm9yIHRoZSBzdGFuZGFyZCBlcnJvciBpczoNClxbIFNFID0gXGZyYWN7z4N9e1xzcXJ0e259fSBcXQ0KV2hlcmU6DQoNCi0gXCggz4MgXCkgaXMgdGhlIHBvcHVsYXRpb24gc3RhbmRhcmQgZGV2aWF0aW9uLg0KLSBcKCBuIFwpIGlzIHRoZSBzYW1wbGUgc2l6ZS4NCg0KVGhlIHN0YW5kYXJkIGVycm9yIGlzIGNydWNpYWwgYmVjYXVzZSBpdCBoZWxwcyBpbiBkZXRlcm1pbmluZyB0aGUgcHJlY2lzaW9uIG9mIHRoZSBzYW1wbGUgbWVhbiBhcyBhbiBlc3RpbWF0ZSBvZiB0aGUgcG9wdWxhdGlvbiBtZWFuLiBBIHNtYWxsZXIgU0UgaW5kaWNhdGVzIHRoYXQgdGhlIHNhbXBsZSBtZWFuIGlzIGEgbW9yZSBwcmVjaXNlIGVzdGltYXRvciBvZiB0aGUgcG9wdWxhdGlvbiBtZWFuLg0KDQojIyMgQ29uZmlkZW5jZSBJbnRlcnZhbA0KQSBjb25maWRlbmNlIGludGVydmFsIHByb3ZpZGVzIGEgcmFuZ2Ugb2YgdmFsdWVzIHdpdGhpbiB3aGljaCB0aGUgdHJ1ZSBwb3B1bGF0aW9uIG1lYW4gaXMgbGlrZWx5IHRvIGZhbGwsIHdpdGggYSBjZXJ0YWluIGxldmVsIG9mIGNvbmZpZGVuY2UuIFRoZSBmb3JtdWxhIGZvciBhIGNvbmZpZGVuY2UgaW50ZXJ2YWwgKGZvciBsYXJnZSBzYW1wbGUgc2l6ZXMpIGlzOg0KXFsgeMyEIMKxIHogXHRpbWVzIFNFIFxdDQpXaGVyZToNCg0KLSBcKCB4zIQgXCkgaXMgdGhlIHNhbXBsZSBtZWFuLg0KLSBcKCB6IFwpIGlzIHRoZSB6LXZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGRlc2lyZWQgY29uZmlkZW5jZSBsZXZlbCAoZS5nLiwgMS45NiBmb3IgYSA5NSUgY29uZmlkZW5jZSBsZXZlbCkuDQotIFwoIFNFIFwpIGlzIHRoZSBzdGFuZGFyZCBlcnJvci4NCg0KVGhlIHdpZHRoIG9mIHRoZSBjb25maWRlbmNlIGludGVydmFsIHByb3ZpZGVzIGluc2lnaHQgaW50byB0aGUgcHJlY2lzaW9uIG9mIHRoZSBlc3RpbWF0ZS4gQSBuYXJyb3dlciBjb25maWRlbmNlIGludGVydmFsIGluZGljYXRlcyBhIG1vcmUgcHJlY2lzZSBlc3RpbWF0ZSBvZiB0aGUgcG9wdWxhdGlvbiBtZWFuLiBDb252ZXJzZWx5LCBhIHdpZGVyIGludGVydmFsIHN1Z2dlc3RzIG1vcmUgdW5jZXJ0YWludHkuDQoNCkluIHRoZSBjb250ZXh0IG9mIHRoZSBwcm92aWRlZCBjb250ZW50LCBjb25zaWRlciBob3VybHkgZWFybmluZ3Mgb2YgY29sbGVnZSBncmFkdWF0ZXMuIElmIHdlIHdlcmUgdG8gZHJhdyBhIHNhbXBsZSBhbmQgY2FsY3VsYXRlIHRoZSBzYW1wbGUgbWVhbiwgdGhlIHN0YW5kYXJkIGVycm9yIHdvdWxkIGdpdmUgdXMgYW4gaWRlYSBvZiBob3cgbXVjaCB0aGlzIHNhbXBsZSBtZWFuIG1pZ2h0IHZhcnkgZnJvbSB0aGUgdHJ1ZSBhdmVyYWdlIGVhcm5pbmdzIG9mIGFsbCBjb2xsZWdlIGdyYWR1YXRlcy4gVXNpbmcgdGhpcyBzdGFuZGFyZCBlcnJvciwgd2UgY2FuIHRoZW4gY29uc3RydWN0IGEgY29uZmlkZW5jZSBpbnRlcnZhbCB0byBlc3RpbWF0ZSBhIHJhbmdlIHdpdGhpbiB3aGljaCB0aGUgdHJ1ZSBhdmVyYWdlIGVhcm5pbmdzIGxpa2VseSBmYWxsLg0KDQpJbiBzdW1tYXJ5LCB3aGlsZSB0aGUgcG9wdWxhdGlvbiBtZWFuIHByb3ZpZGVzIGFuIG92ZXJhbGwgYXZlcmFnZSwgdGhlIHN0YW5kYXJkIGVycm9yIGFuZCBjb25maWRlbmNlIGludGVydmFscyBvZmZlciBpbnNpZ2h0cyBpbnRvIHRoZSByZWxpYWJpbGl0eSBhbmQgcHJlY2lzaW9uIG9mIGVzdGltYXRlcyBkZXJpdmVkIGZyb20gc2FtcGxlIGRhdGEuDQoNCg0KIyMgUHJvbXB0IA0KQ3JlYXRlIGEgY291cGxlIHJlYWwtd29ybGQsIGVjb25vbWljcyByZWxhdGVkIGV4YW1wbGVzIG9mIGNyZWF0aW5nIGh5cG90aGVzaXMgdGVzdHMgY29uY2VybmluZyB0aGUgcG9wdWxhdGlvbiBtZWFuLg0KDQojIyMgRXhhbXBsZSAxOiBBdmVyYWdlIEhvdXNlaG9sZCBJbmNvbWUNCg0KKipCYWNrZ3JvdW5kKio6IEEgZ292ZXJubWVudCBhZ2VuY3kgYmVsaWV2ZXMgdGhhdCB0aGUgYXZlcmFnZSBhbm51YWwgaG91c2Vob2xkIGluY29tZSBpbiBhIHBhcnRpY3VsYXIgY2l0eSBpcyAkNTAsMDAwLiBBIGxvY2FsIGVjb25vbWlzdCB0aGlua3MgdGhhdCB0aGlzIGZpZ3VyZSBpcyBvdXRkYXRlZCBhbmQgdGhhdCB0aGUgYXZlcmFnZSBpbmNvbWUgaGFzIGluY3JlYXNlZCBkdWUgdG8gcmVjZW50IGVjb25vbWljIGdyb3d0aCBpbiB0aGUgcmVnaW9uLg0KDQoqKkh5cG90aGVzaXMgVGVzdCoqOg0KDQotICoqTnVsbCBIeXBvdGhlc2lzIChIMCkqKjogVGhlIGF2ZXJhZ2UgYW5udWFsIGhvdXNlaG9sZCBpbmNvbWUgXCggXG11IFwpIGlzICQ1MCwwMDAuDQogIFwoIEgwOiBcbXUgPSAkNTAsMDAwIFwpDQogIA0KLSAqKkFsdGVybmF0aXZlIEh5cG90aGVzaXMgKEgxKSoqOiBUaGUgYXZlcmFnZSBhbm51YWwgaG91c2Vob2xkIGluY29tZSBcKCBcbXUgXCkgaXMgZ3JlYXRlciB0aGFuICQ1MCwwMDAuDQogIFwoIEgxOiBcbXUgPiAkNTAsMDAwIFwpDQoNCioqUHJvY2VkdXJlKio6DQoNCjEuIENvbGxlY3QgYSByYW5kb20gc2FtcGxlIG9mIGFubnVhbCBpbmNvbWVzIGZyb20gaG91c2Vob2xkcyBpbiB0aGUgY2l0eS4NCjIuIENhbGN1bGF0ZSB0aGUgc2FtcGxlIG1lYW4gYW5kIHN0YW5kYXJkIGVycm9yLg0KMy4gQ29uZHVjdCBhIG9uZS10YWlsZWQgdC10ZXN0IHRvIGRldGVybWluZSBpZiB0aGUgc2FtcGxlIG1lYW4gaXMgc2lnbmlmaWNhbnRseSBncmVhdGVyIHRoYW4gJDUwLDAwMC4NCjQuIElmIHRoZSBwLXZhbHVlIGlzIGxlc3MgdGhhbiBhIHNpZ25pZmljYW5jZSBsZXZlbCAoZS5nLiwgMC4wNSksIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzLg0KDQojIyMgRXhhbXBsZSAyOiBVbmVtcGxveW1lbnQgUmF0ZQ0KDQoqKkJhY2tncm91bmQqKjogQSByZWNlbnQgcmVwb3J0IHN1Z2dlc3RzIHRoYXQgdGhlIG5hdGlvbmFsIHVuZW1wbG95bWVudCByYXRlIGlzIDYlLiBBbiBlY29ub21pc3QgYmVsaWV2ZXMgdGhhdCBpbiBhIHNwZWNpZmljIHN0YXRlLCBkdWUgdG8gcmVjZW50IGxheW9mZnMgaW4gbWFqb3IgaW5kdXN0cmllcywgdGhlIHVuZW1wbG95bWVudCByYXRlIGlzIGhpZ2hlciB0aGFuIHRoZSBuYXRpb25hbCBhdmVyYWdlLg0KDQoqKkh5cG90aGVzaXMgVGVzdCoqOg0KDQotICoqTnVsbCBIeXBvdGhlc2lzIChIMCkqKjogVGhlIHVuZW1wbG95bWVudCByYXRlIFwoIFxtdSBcKSBpbiB0aGUgc3RhdGUgaXMgNiUuDQogIFwoIEgwOiBcbXUgPSA2XCUgXCkNCiAgDQotICoqQWx0ZXJuYXRpdmUgSHlwb3RoZXNpcyAoSDEpKio6IFRoZSB1bmVtcGxveW1lbnQgcmF0ZSBcKCBcbXUgXCkgaW4gdGhlIHN0YXRlIGlzIGdyZWF0ZXIgdGhhbiA2JS4NCiAgXCggSDE6IFxtdSA+IDZcJSBcKQ0KDQoqKlByb2NlZHVyZSoqOg0KDQoxLiBDb2xsZWN0IGEgcmFuZG9tIHNhbXBsZSBvZiBlbXBsb3ltZW50IHN0YXR1c2VzIGZyb20gcmVzaWRlbnRzIG9mIHRoZSBzdGF0ZS4NCjIuIENhbGN1bGF0ZSB0aGUgc2FtcGxlIHVuZW1wbG95bWVudCByYXRlLg0KMy4gQ29uZHVjdCBhIG9uZS10YWlsZWQgei10ZXN0IG9yIHQtdGVzdCAoZGVwZW5kaW5nIG9uIHNhbXBsZSBzaXplIGFuZCB2YXJpYW5jZSBrbm93bikgdG8gZGV0ZXJtaW5lIGlmIHRoZSBzYW1wbGUgdW5lbXBsb3ltZW50IHJhdGUgaXMgc2lnbmlmaWNhbnRseSBncmVhdGVyIHRoYW4gNiUuDQo0LiBJZiB0aGUgcC12YWx1ZSBpcyBsZXNzIHRoYW4gYSBzaWduaWZpY2FuY2UgbGV2ZWwgKGUuZy4sIDAuMDUpLCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4NCg0KSW4gYm90aCBleGFtcGxlcywgdGhlIGh5cG90aGVzaXMgdGVzdHMgaGVscCBpbiBtYWtpbmcgaW5mb3JtZWQgZGVjaXNpb25zIGJhc2VkIG9uIHNhbXBsZSBkYXRhIGFuZCBwcm92aWRlIGluc2lnaHRzIGludG8gdGhlIGVjb25vbWljIGNvbmRpdGlvbnMgb2YgdGhlIHJlZ2lvbiBvciBzdGF0ZSBpbiBxdWVzdGlvbi4NCg0KIyMgUHJvbXB0DQpDcmVhdGUgc29tZSBleGFtcGxlIHByb2JsZW1zIHdoZXJlIHN0dWRlbnRzIG11c3QgY2FsY3VsYXRlIHRoZSB6LXN0YXRpc3RpYyBhbmQgY29uZHVjdCBhIGh5cG90aGVzaXMgdGVzdCBmcm9tIGRhdGEuIA0KDQojIyMgRXhhbXBsZSAxOiBFeGFtIFNjb3Jlcw0KDQoqKkJhY2tncm91bmQqKjogVGhlIG5hdGlvbmFsIGF2ZXJhZ2Ugc2NvcmUgZm9yIGEgc3RhbmRhcmRpemVkIGV4YW0gaXMga25vd24gdG8gYmUgNTAwIHdpdGggYSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgMTAwLiBBIHNjaG9vbCBiZWxpZXZlcyB0aGF0IGl0cyBzdHVkZW50cywgb24gYXZlcmFnZSwgc2NvcmUgYWJvdmUgdGhlIG5hdGlvbmFsIGF2ZXJhZ2UuIFRvIHRlc3QgdGhpcyBjbGFpbSwgdGhleSByYW5kb21seSBzZWxlY3QgMzYgc3R1ZGVudHMgYW5kIGZpbmQgdGhhdCB0aGVpciBhdmVyYWdlIHNjb3JlIGlzIDUyMC4NCg0KKipQcm9ibGVtKio6DQoNCjEuIFN0YXRlIHRoZSBudWxsIGFuZCBhbHRlcm5hdGl2ZSBoeXBvdGhlc2VzLg0KMi4gQ2FsY3VsYXRlIHRoZSB6LXN0YXRpc3RpYy4NCjMuIFVzaW5nIGEgc2lnbmlmaWNhbmNlIGxldmVsIG9mIDAuMDUsIGNvbmR1Y3QgYSBoeXBvdGhlc2lzIHRlc3QgdG8gZGV0ZXJtaW5lIGlmIHRoZSBzY2hvb2wncyBjbGFpbSBpcyB2YWxpZC4NCg0KKipTb2x1dGlvbioqOg0KDQoxLiANCiAgIC0gKipOdWxsIEh5cG90aGVzaXMgKEgwKSoqOiBcKCBcbXUgPSA1MDAgXCkNCiAgIC0gKipBbHRlcm5hdGl2ZSBIeXBvdGhlc2lzIChIMSkqKjogXCggXG11ID4gNTAwIFwpDQoyLiANCiAgIFwoIHogPSBcZnJhY3t4zIQgLSBcbXV9e1xmcmFje8+DfXtcc3FydHtufX19IFwpDQogICANCiAgIFwoIHogPSBcZnJhY3s1MjAgLSA1MDB9e1xmcmFjezEwMH17XHNxcnR7MzZ9fX0gPSBcZnJhY3syMH17MTB9ID0gMiBcKQ0KMy4gDQogICBGb3IgYSBvbmUtdGFpbGVkIHRlc3QgYXQgYSBzaWduaWZpY2FuY2UgbGV2ZWwgb2YgMC4wNSwgdGhlIGNyaXRpY2FsIHotdmFsdWUgaXMgYXBwcm94aW1hdGVseSAxLjY0NS4gU2luY2UgMiA+IDEuNjQ1LCB3ZSByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4gVGhlIHNjaG9vbCdzIGNsYWltIGlzIHZhbGlkLg0KDQojIyMgRXhhbXBsZSAyOiBTb2RhIENhbiBGaWxsaW5nDQoNCioqQmFja2dyb3VuZCoqOiBBIHNvZGEgY29tcGFueSBjbGFpbXMgdGhhdCB0aGVpciBtYWNoaW5lIGZpbGxzIGNhbnMgd2l0aCBhbiBhdmVyYWdlIG9mIDEyIG91bmNlcyBvZiBzb2RhLiBBIHF1YWxpdHkgY29udHJvbCB0ZWFtIHN1c3BlY3RzIHRoYXQgdGhlIG1hY2hpbmUgaXMgbm90IGZpbGxpbmcgdG8gdGhhdCBsZXZlbC4gVGhleSByYW5kb21seSBzZWxlY3QgNDkgY2FucyBhbmQgZmluZCB0aGF0IHRoZSBhdmVyYWdlIGZpbGwgaXMgMTEuOTUgb3VuY2VzIHdpdGggYSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgMC4zIG91bmNlcy4NCg0KKipQcm9ibGVtKio6DQoNCjEuIFN0YXRlIHRoZSBudWxsIGFuZCBhbHRlcm5hdGl2ZSBoeXBvdGhlc2VzLg0KMi4gQ2FsY3VsYXRlIHRoZSB6LXN0YXRpc3RpYy4NCjMuIFVzaW5nIGEgc2lnbmlmaWNhbmNlIGxldmVsIG9mIDAuMDUsIGNvbmR1Y3QgYSBoeXBvdGhlc2lzIHRlc3QgdG8gZGV0ZXJtaW5lIGlmIHRoZSBtYWNoaW5lIGlzIGZpbGxpbmcgY2FucyB3aXRoIGxlc3MgdGhhbiAxMiBvdW5jZXMgb2Ygc29kYS4NCg0KKipTb2x1dGlvbioqOg0KDQoxLiANCiAgDQogICAtICoqTnVsbCBIeXBvdGhlc2lzIChIMCkqKjogXCggXG11ID0gMTIgXCkNCiAgIC0gKipBbHRlcm5hdGl2ZSBIeXBvdGhlc2lzIChIMSkqKjogXCggXG11IDwgMTIgXCkNCjIuIA0KICAgXCggeiA9IFxmcmFje3jMhCAtIFxtdX17XGZyYWN7z4N9e1xzcXJ0e259fX0gXCkNCiAgIA0KICAgXCggeiA9IFxmcmFjezExLjk1IC0gMTJ9e1xmcmFjezAuM317XHNxcnR7NDl9fX0gPSBcZnJhY3stMC4wNX17MC4wNDI5fSBcYXBwcm94IC0xLjE2NSBcKQ0KMy4gDQogICBGb3IgYSBvbmUtdGFpbGVkIHRlc3QgYXQgYSBzaWduaWZpY2FuY2UgbGV2ZWwgb2YgMC4wNSwgdGhlIGNyaXRpY2FsIHotdmFsdWUgaXMgYXBwcm94aW1hdGVseSAtMS42NDUuIFNpbmNlIC0xLjE2NSA+IC0xLjY0NSwgd2UgZmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4gVGhlIG1hY2hpbmUgYXBwZWFycyB0byBiZSBmaWxsaW5nIGNhbnMgY29ycmVjdGx5Lg0KDQojIyBQcm9tcHQNCkdvIGludG8gbW9yZSBkZXRhaWwgYWJvdXQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgc3R1ZGVudCB0LWRpc3RyaWJ1dGlvbiBhbmQgdC1zdGF0aXN0aWNzIGZyb20gdGhlIG5vcm1hbCBkaXN0cmlidXRpb24gYW5kIHotc3RhdGlzdGljcy4gDQoNCiMjIyBOb3JtYWwgRGlzdHJpYnV0aW9uIGFuZCBaLXN0YXRpc3RpY3M6DQoNCjEuICoqTm9ybWFsIERpc3RyaWJ1dGlvbioqOiBJdCBpcyBhIGJlbGwtc2hhcGVkLCBzeW1tZXRyaWNhbCBkaXN0cmlidXRpb24gZGVzY3JpYmVkIGJ5IGl0cyBtZWFuICjOvCkgYW5kIHN0YW5kYXJkIGRldmlhdGlvbiAoz4MpLiBUaGUgdG90YWwgYXJlYSB1bmRlciBpdHMgY3VydmUgaXMgMS4gVGhlIHN0YW5kYXJkIG5vcm1hbCBkaXN0cmlidXRpb24gaGFzIGEgbWVhbiBvZiAwIGFuZCBhIHN0YW5kYXJkIGRldmlhdGlvbiBvZiAxLg0KDQoyLiAqKlotc3RhdGlzdGljIChvciBaLXNjb3JlKSoqOiBJdCByZXByZXNlbnRzIHRoZSBudW1iZXIgb2Ygc3RhbmRhcmQgZGV2aWF0aW9ucyBhbiBvYnNlcnZhdGlvbiAob3Igc2FtcGxlIG1lYW4pIGlzIGF3YXkgZnJvbSB0aGUgcG9wdWxhdGlvbiBtZWFuLiBJdCdzIGNhbGN1bGF0ZWQgYXM6DQogICBcWyBaID0gXGZyYWN7WCAtIM68fXvPg30gXF0NCiAgIFdoZXJlOg0KICANCiAgIC0gXCggWCBcKSBpcyB0aGUgb2JzZXJ2YXRpb24gKG9yIHNhbXBsZSBtZWFuKS4NCiAgIC0gXCggzrwgXCkgaXMgdGhlIHBvcHVsYXRpb24gbWVhbi4NCiAgIC0gXCggz4MgXCkgaXMgdGhlIHBvcHVsYXRpb24gc3RhbmRhcmQgZGV2aWF0aW9uLg0KDQozLiAqKldoZW4gdG8gVXNlKio6IFRoZSB6LXN0YXRpc3RpYyBpcyB1c2VkIHdoZW46DQogIA0KICAgLSBUaGUgcG9wdWxhdGlvbiBzdGFuZGFyZCBkZXZpYXRpb24gKM+DKSBpcyBrbm93bi4NCiAgIC0gVGhlIHNhbXBsZSBzaXplIGlzIGxhcmdlICh0eXBpY2FsbHkgXCggbiA+IDMwIFwpKSwgZXZlbiBpZiDPgyBpcyB1bmtub3duLg0KICAgLSBUaGUgdW5kZXJseWluZyBkYXRhIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuDQoNCiMjIyBTdHVkZW50J3MgdC1kaXN0cmlidXRpb24gYW5kIHQtc3RhdGlzdGljczoNCg0KMS4gKipTdHVkZW50J3MgdC1kaXN0cmlidXRpb24qKjogSXQgaXMgc2ltaWxhciBpbiBzaGFwZSB0byB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBidXQgaGFzIGhlYXZpZXIgdGFpbHMuIFRoaXMgbWFrZXMgaXQgbW9yZSBhY2NvbW1vZGF0aW5nIHRvIHBvdGVudGlhbCBvdXRsaWVycy4gVGhlIGV4YWN0IHNoYXBlIG9mIHRoZSB0LWRpc3RyaWJ1dGlvbiBkZXBlbmRzIG9uIGEgcGFyYW1ldGVyIGNhbGxlZCAiZGVncmVlcyBvZiBmcmVlZG9tLCIgb2Z0ZW4gZGVub3RlZCBieSBcKCBkZiBcKS4gQXMgXCggZGYgXCkgaW5jcmVhc2VzLCB0aGUgdC1kaXN0cmlidXRpb24gYXBwcm9hY2hlcyB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCg0KMi4gKipULXN0YXRpc3RpYyoqOiBJdCdzIHVzZWQgd2hlbiBlc3RpbWF0aW5nIHRoZSBwb3B1bGF0aW9uIG1lYW4gZnJvbSBhIHNhbXBsZSwgZXNwZWNpYWxseSB3aGVuIHRoZSBzYW1wbGUgc2l6ZSBpcyBzbWFsbCBvciB0aGUgcG9wdWxhdGlvbiBzdGFuZGFyZCBkZXZpYXRpb24gaXMgdW5rbm93bi4gSXQncyBjYWxjdWxhdGVkIGFzOg0KICAgXFsgdCA9IFxmcmFje3jMhCAtIM68fXtzL+KImm59IFxdDQogICBXaGVyZToNCiAgDQogICAtIFwoIHjMhCBcKSBpcyB0aGUgc2FtcGxlIG1lYW4uDQogICAtIFwoIM68IFwpIGlzIHRoZSBwb3B1bGF0aW9uIG1lYW4gKG9yIGh5cG90aGVzaXplZCB2YWx1ZSkuDQogICAtIFwoIHMgXCkgaXMgdGhlIHNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb24uDQogICAtIFwoIG4gXCkgaXMgdGhlIHNhbXBsZSBzaXplLg0KDQozLiAqKldoZW4gdG8gVXNlKio6IFRoZSB0LXN0YXRpc3RpYyBhbmQgdC1kaXN0cmlidXRpb24gYXJlIHVzZWQgd2hlbjoNCiAgIC0gVGhlIHBvcHVsYXRpb24gc3RhbmRhcmQgZGV2aWF0aW9uICjPgykgaXMgdW5rbm93bi4NCiAgIC0gVGhlIHNhbXBsZSBzaXplIGlzIHNtYWxsICh0eXBpY2FsbHkgXCggbiDiiaQgMzAgXCkpLg0KICAgLSBUaGUgdW5kZXJseWluZyBkYXRhIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgb3IgaWYgdGhlIHNhbXBsZSBzaXplIGlzIHN1ZmZpY2llbnRseSBsYXJnZSB0byBpbnZva2UgdGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbS4NCg0KIyMjIEtleSBEaWZmZXJlbmNlczoNCjEuICoqU3RhbmRhcmQgRGV2aWF0aW9uKio6IEZvciB6LXN0YXRpc3RpY3MsIHRoZSBwb3B1bGF0aW9uIHN0YW5kYXJkIGRldmlhdGlvbiBpcyB1c2VkLCB3aGlsZSBmb3IgdC1zdGF0aXN0aWNzLCB0aGUgc2FtcGxlIHN0YW5kYXJkIGRldmlhdGlvbiBpcyB1c2VkLg0KDQoyLiAqKkRpc3RyaWJ1dGlvbiBTaGFwZSoqOiBUaGUgdC1kaXN0cmlidXRpb24gaGFzIHRoaWNrZXIgdGFpbHMgY29tcGFyZWQgdG8gdGhlIG5vcm1hbCBkaXN0cmlidXRpb24uIFRoaXMgYWNjb3VudHMgZm9yIHRoZSBpbmNyZWFzZWQgdmFyaWFiaWxpdHkgZXhwZWN0ZWQgd2l0aCBzbWFsbGVyIHNhbXBsZXMuDQoNCjMuICoqU2FtcGxlIFNpemUqKjogWi1zdGF0aXN0aWNzIGFyZSB0eXBpY2FsbHkgdXNlZCBmb3IgbGFyZ2VyIHNhbXBsZXMgKG9yIHdoZW4gdGhlIHBvcHVsYXRpb24gc3RhbmRhcmQgZGV2aWF0aW9uIGlzIGtub3duKSwgd2hpbGUgdC1zdGF0aXN0aWNzIGFyZSB1c2VkIGZvciBzbWFsbGVyIHNhbXBsZXMuDQoNCjQuICoqRGVncmVlcyBvZiBGcmVlZG9tKio6IFRoZSB0LWRpc3RyaWJ1dGlvbiByZXF1aXJlcyB0aGUgc3BlY2lmaWNhdGlvbiBvZiBkZWdyZWVzIG9mIGZyZWVkb20sIHdoaWNoIGlzIHR5cGljYWxseSBcKCBkZiA9IG4gLSAxIFwpIGZvciBhIHNpbmdsZSBzYW1wbGUuIFRoZSBjb25jZXB0IG9mIGRlZ3JlZXMgb2YgZnJlZWRvbSBkb2Vzbid0IGFwcGx5IHRvIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uLg0KDQpJbiBzdW1tYXJ5LCB3aGlsZSBib3RoIHRoZSB6IGFuZCB0IGRpc3RyaWJ1dGlvbnMgYXJlIGZvdW5kYXRpb25hbCBpbiBpbmZlcmVudGlhbCBzdGF0aXN0aWNzLCB0aGV5IGFyZSB1c2VkIGluIGRpZmZlcmVudCBzY2VuYXJpb3MgYmFzZWQgb24gdGhlIGtub3duIGluZm9ybWF0aW9uIGFuZCBzYW1wbGUgc2l6ZS4gVGhlIHQtZGlzdHJpYnV0aW9uIHByb3ZpZGVzIGEgbW9yZSBjb25zZXJ2YXRpdmUgYXBwcm9hY2ggKGR1ZSB0byBpdHMgdGhpY2tlciB0YWlscykgd2hlbiBkZWFsaW5nIHdpdGggc21hbGxlciBzYW1wbGVzIG9yIHVua25vd24gcG9wdWxhdGlvbiBzdGFuZGFyZCBkZXZpYXRpb25zLg0KDQojIyBQcm9tcHQNCkdvIGludG8gZGV0YWlsIGFib3V0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gb25lLXNhbXBsZSwgdHdvLXNhbXBsZSwgYW5kIHBhaXJlZCB0LXRlc3RzLiANCg0KIyMjIDEuIE9uZS1zYW1wbGUgdC10ZXN0Og0KDQoqKlB1cnBvc2UqKjogVXNlZCB0byB0ZXN0IGlmIHRoZSBtZWFuIG9mIGEgc2luZ2xlIHNhbXBsZSBpcyBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIGEga25vd24gb3IgaHlwb3RoZXNpemVkIHBvcHVsYXRpb24gbWVhbi4NCg0KKipIeXBvdGhlc2VzKio6DQoNCi0gKipOdWxsIEh5cG90aGVzaXMgKEgwKSoqOiBUaGUgc2FtcGxlIG1lYW4gaXMgZXF1YWwgdG8gdGhlIHBvcHVsYXRpb24gbWVhbi4gXCggSDA6IFxtdSA9IFxtdV8wIFwpDQotICoqQWx0ZXJuYXRpdmUgSHlwb3RoZXNpcyAoSDEpKio6IFRoZSBzYW1wbGUgbWVhbiBpcyBub3QgZXF1YWwgdG8gdGhlIHBvcHVsYXRpb24gbWVhbi4gXCggSDE6IFxtdSBcbmVxIFxtdV8wIFwpDQoNCioqRXhhbXBsZSoqOiBTdXBwb3NlIGEgbWFudWZhY3R1cmVyIGNsYWltcyB0aGF0IGEgdHlwZSBvZiBiYXR0ZXJ5IGxhc3RzIDEwMCBob3VycyBvbiBhdmVyYWdlLiBZb3UgdGFrZSBhIHNhbXBsZSBvZiBiYXR0ZXJpZXMsIHRlc3QgdGhlbSwgYW5kIHdhbnQgdG8gc2VlIGlmIHRoZSBhdmVyYWdlIGxpZmVzcGFuIGRpZmZlcnMgZnJvbSB0aGUgY2xhaW1lZCAxMDAgaG91cnMuDQoNCiMjIyAyLiBUd28tc2FtcGxlIHQtdGVzdCAoSW5kZXBlbmRlbnQgdC10ZXN0KToNCg0KKipQdXJwb3NlKio6IFVzZWQgdG8gY29tcGFyZSB0aGUgbWVhbnMgb2YgdHdvIGluZGVwZW5kZW50IHNhbXBsZXMgdG8gc2VlIGlmIHRoZXkgY29tZSBmcm9tIHBvcHVsYXRpb25zIHdpdGggdGhlIHNhbWUgbWVhbi4NCg0KKipIeXBvdGhlc2VzKio6DQoNCi0gKipOdWxsIEh5cG90aGVzaXMgKEgwKSoqOiBUaGUgbWVhbnMgb2YgdGhlIHR3byBwb3B1bGF0aW9ucyBhcmUgZXF1YWwuIFwoIEgwOiBcbXVfMSA9IFxtdV8yIFwpDQotICoqQWx0ZXJuYXRpdmUgSHlwb3RoZXNpcyAoSDEpKio6IFRoZSBtZWFucyBvZiB0aGUgdHdvIHBvcHVsYXRpb25zIGFyZSBub3QgZXF1YWwuIFwoIEgxOiBcbXVfMSBcbmVxIFxtdV8yIFwpDQoNCioqRXhhbXBsZSoqOiBJbWFnaW5lIHlvdSB3YW50IHRvIHRlc3QgaWYgdGhlcmUncyBhIGRpZmZlcmVuY2UgaW4gYXZlcmFnZSB0ZXN0IHNjb3JlcyBiZXR3ZWVuIHN0dWRlbnRzIHRhdWdodCBieSB0d28gZGlmZmVyZW50IHRlYWNoZXJzLiBZb3Ugd291bGQgY29sbGVjdCBzY29yZXMgZnJvbSBhIHNhbXBsZSBvZiBzdHVkZW50cyBmcm9tIGVhY2ggdGVhY2hlcidzIGNsYXNzIGFuZCB0aGVuIGNvbXBhcmUgdGhlIG1lYW5zIHVzaW5nIHRoZSB0d28tc2FtcGxlIHQtdGVzdC4NCg0KIyMjIDMuIFBhaXJlZCB0LXRlc3QgKERlcGVuZGVudCB0LXRlc3QpOg0KDQoqKlB1cnBvc2UqKjogVXNlZCB0byBjb21wYXJlIHRoZSBtZWFucyBvZiB0aGUgc2FtZSBncm91cCBhdCB0d28gZGlmZmVyZW50IHRpbWVzIG9yIHVuZGVyIHR3byBkaWZmZXJlbnQgY29uZGl0aW9ucy4gVGhlIG9ic2VydmF0aW9ucyBhcmUgcGFpcmVkLCBtZWFuaW5nIGVhY2ggb2JzZXJ2YXRpb24gaW4gb25lIHNhbXBsZSBjb3JyZXNwb25kcyB0byBhbiBvYnNlcnZhdGlvbiBpbiB0aGUgb3RoZXIgc2FtcGxlLg0KDQoqKkh5cG90aGVzZXMqKjoNCg0KLSAqKk51bGwgSHlwb3RoZXNpcyAoSDApKio6IFRoZSBtZWFuIGRpZmZlcmVuY2UgYmV0d2VlbiBwYWlyZWQgb2JzZXJ2YXRpb25zIGlzIHplcm8uIFwoIEgwOiBcbXVfZCA9IDAgXCkNCi0gKipBbHRlcm5hdGl2ZSBIeXBvdGhlc2lzIChIMSkqKjogVGhlIG1lYW4gZGlmZmVyZW5jZSBiZXR3ZWVuIHBhaXJlZCBvYnNlcnZhdGlvbnMgaXMgbm90IHplcm8uIFwoIEgxOiBcbXVfZCBcbmVxIDAgXCkNCg0KKipFeGFtcGxlKio6IENvbnNpZGVyIGEgY2xpbmljYWwgdHJpYWwgd2hlcmUgeW91IHdhbnQgdG8gdGVzdCB0aGUgZWZmZWN0aXZlbmVzcyBvZiBhIG5ldyBkcnVnLiBQYXRpZW50cycgaGVhbHRoIG1ldHJpY3MgYXJlIG1lYXN1cmVkIGJlZm9yZSB0YWtpbmcgdGhlIGRydWcgYW5kIGFmdGVyIGNvbXBsZXRpbmcgdGhlIHRyZWF0bWVudC4gU2luY2UgdGhlIG1lYXN1cmVtZW50cyBiZWZvcmUgYW5kIGFmdGVyIGFyZSBmcm9tIHRoZSBzYW1lIGluZGl2aWR1YWxzLCB0aGUgZGF0YSBpcyBwYWlyZWQuDQoNCiMjIyBLZXkgRGlmZmVyZW5jZXM6DQoNCi0gKipEYXRhIFN0cnVjdHVyZSoqOiANCiAgDQogIC0gT25lLXNhbXBsZSB0LXRlc3Qgd29ya3Mgd2l0aCBhIHNpbmdsZSBzYW1wbGUuDQogIC0gVHdvLXNhbXBsZSB0LXRlc3Qgd29ya3Mgd2l0aCB0d28gaW5kZXBlbmRlbnQgc2FtcGxlcy4NCiAgLSBQYWlyZWQgdC10ZXN0IHdvcmtzIHdpdGggdHdvIHJlbGF0ZWQgKHBhaXJlZCkgc2FtcGxlcy4NCg0KLSAqKkFwcGxpY2F0aW9uKio6DQogDQogIC0gT25lLXNhbXBsZSBpcyB1c2VkIHdoZW4gY29tcGFyaW5nIGEgc2FtcGxlIG1lYW4gdG8gYSBrbm93biBvciBoeXBvdGhlc2l6ZWQgcG9wdWxhdGlvbiBtZWFuLg0KICAtIFR3by1zYW1wbGUgaXMgdXNlZCB3aGVuIGNvbXBhcmluZyB0aGUgbWVhbnMgb2YgdHdvIGluZGVwZW5kZW50IGdyb3Vwcy4NCiAgLSBQYWlyZWQgaXMgdXNlZCB3aGVuIGNvbXBhcmluZyB0aGUgbWVhbnMgb2YgdGhlIHNhbWUgZ3JvdXAgdW5kZXIgdHdvIGRpZmZlcmVudCBzY2VuYXJpb3Mgb3IgYXQgdHdvIGRpZmZlcmVudCB0aW1lcy4NCg0KLSAqKkFzc3VtcHRpb25zKio6DQogIEFsbCB0aHJlZSB0ZXN0cyBhc3N1bWUgdGhhdCB0aGUgZGF0YSBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiBUaGUgdHdvLXNhbXBsZSB0LXRlc3QgYWxzbyBhc3N1bWVzIHRoYXQgdGhlIHZhcmlhbmNlcyBvZiB0aGUgdHdvIGdyb3VwcyBhcmUgZXF1YWwgKGhvbW9nZW5laXR5IG9mIHZhcmlhbmNlcyksIHVubGVzcyB5b3UncmUgZG9pbmcgYSB2YXJpYXRpb24gb2YgdGhlIHRlc3QgdGhhdCBkb2Vzbid0IG1ha2UgdGhpcyBhc3N1bXB0aW9uIChXZWxjaCdzIHQtdGVzdCkuDQoNCg0KIyMgUHJvbXB0DQpDcmVhdGUgc29tZSBleGFtcGxlcyBvZiB1c2luZyBSIHRvIGNvbmR1Y3QgaHlwb3RoZXNpcyB0ZXN0aW5nIG9mIG1lYW5zLiANCg0KIyMjIEV4YW1wbGUgMTogT25lLXNhbXBsZSB0LXRlc3QNCg0KU3VwcG9zZSB3ZSBoYXZlIGEgc2FtcGxlIG9mIGV4YW0gc2NvcmVzIGZyb20gMTAgc3R1ZGVudHMsIGFuZCB3ZSB3YW50IHRvIHRlc3QgaWYgdGhlIGF2ZXJhZ2Ugc2NvcmUgaXMgZGlmZmVyZW50IGZyb20gNzUuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgZGF0YQ0Kc2NvcmVzIDwtIGMoNzgsIDgyLCA3NCwgNjksIDc3LCA4MywgNzIsIDc2LCA4MCwgNzEpDQoNCiMgT25lLXNhbXBsZSB0LXRlc3QNCnQudGVzdChzY29yZXMsIG11ID0gNzUpDQpgYGANCg0KIyMjIEV4YW1wbGUgMjogVHdvLXNhbXBsZSB0LXRlc3QNCg0KSW1hZ2luZSB3ZSBoYXZlIGV4YW0gc2NvcmVzIGZyb20gdHdvIGRpZmZlcmVudCBjbGFzc2VzLCBhbmQgd2Ugd2FudCB0byB0ZXN0IGlmIHRoZXJlJ3MgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZWlyIG1lYW5zLg0KDQpgYGB7Un0NCiMgU2FtcGxlIGRhdGENCmNsYXNzMV9zY29yZXMgPC0gYyg3OCwgODIsIDc0LCA2OSwgNzcsIDgzLCA3MiwgNzYsIDgwLCA3MSkNCmNsYXNzMl9zY29yZXMgPC0gYyg4NSwgODgsIDg0LCA4NiwgODcsIDg5LCA4MywgODQsIDgyLCA4MSkNCg0KIyBUd28tc2FtcGxlIHQtdGVzdA0KdC50ZXN0KGNsYXNzMV9zY29yZXMsIGNsYXNzMl9zY29yZXMpDQpgYGANCg0KIyMjIEV4YW1wbGUgMzogUGFpcmVkIHQtdGVzdA0KDQpTdXBwb3NlIHdlIG1lYXN1cmUgdGhlIGJsb29kIHByZXNzdXJlIG9mIDUgcGF0aWVudHMgYmVmb3JlIGFuZCBhZnRlciBhIHRyZWF0bWVudCwgYW5kIHdlIHdhbnQgdG8gdGVzdCBpZiB0aGUgdHJlYXRtZW50IGhhZCBhIHNpZ25pZmljYW50IGVmZmVjdC4NCg0KYGBge1J9DQojIFNhbXBsZSBkYXRhDQpiZWZvcmVfdHJlYXRtZW50IDwtIGMoMTUwLCAxNjUsIDE1NSwgMTQyLCAxMzgpDQphZnRlcl90cmVhdG1lbnQgPC0gYygxNDUsIDE2MCwgMTUyLCAxNDAsIDEzNSkNCg0KIyBQYWlyZWQgdC10ZXN0DQp0LnRlc3QoYmVmb3JlX3RyZWF0bWVudCwgYWZ0ZXJfdHJlYXRtZW50LCBwYWlyZWQgPSBUUlVFKQ0KYGBgDQoNCiMjIyBFeGFtcGxlIDQ6IE9uZS1zYW1wbGUgei10ZXN0ICh1c2luZyBleHRlcm5hbCBwYWNrYWdlKQ0KDQpGb3IgbGFyZ2Ugc2FtcGxlcywgd2UgbWlnaHQgcHJlZmVyIGEgei10ZXN0LiBTdXBwb3NlIHdlIGhhdmUgYSBsYXJnZSBzYW1wbGUgb2Ygd2VpZ2h0cyBmcm9tIGEgZmFjdG9yeSwgYW5kIHdlIHdhbnQgdG8gdGVzdCBpZiB0aGUgYXZlcmFnZSB3ZWlnaHQgaXMgZGlmZmVyZW50IGZyb20gNTAgZ3JhbXMuIChOb3RlOiBSIGRvZXNuJ3QgaGF2ZSBhIGJ1aWx0LWluIGZ1bmN0aW9uIGZvciB0aGUgb25lLXNhbXBsZSB6LXRlc3QsIHNvIHdlJ2xsIHVzZSB0aGUgYHoudGVzdGAgZnVuY3Rpb24gZnJvbSB0aGUgYEJTREFgIHBhY2thZ2UuKQ0KDQpgYGB7Un0NCiMgSW5zdGFsbCBhbmQgbG9hZCB0aGUgQlNEQSBwYWNrYWdlDQppbnN0YWxsLnBhY2thZ2VzKCJCU0RBIikNCmxpYnJhcnkoQlNEQSkNCg0KIyBTYW1wbGUgZGF0YSAoYXNzdW1pbmcgYSBsYXJnZSBzYW1wbGUpDQp3ZWlnaHRzIDwtIHJub3JtKDEwMDAsIG1lYW4gPSA1MC41LCBzZCA9IDUpICAjIEdlbmVyYXRpbmcgcmFuZG9tIGRhdGEgYXJvdW5kIDUwLjUgd2l0aCBzZCA9IDUNCg0KIyBPbmUtc2FtcGxlIHotdGVzdA0Kei50ZXN0KHdlaWdodHMsIG11ID0gNTAsIHNpZ21hLnggPSBzZCh3ZWlnaHRzKSkNCmBgYA0KDQo=