1 Introduction

We have discussed the relationship between two numerical variables using linear correlation coefficient and linear regression. We now explore the relationship between two categorical variables. The idea is to make an assumption (hypothesis) about the variable (s) and use the assumption to construct a frequency table (called the expected table). At the same time, we tabulated the data to obtain an observed table. The discrepancy between the expected table and the observed table can be used to make the inference about the relationship between categorical variables.

2 Epidemologic Study Designs

In descriptive statistics, we introduce frequency table and bar-chart to characterize the distribution. We also briefly introduced chi-square tests of independence of two categorical variables. We will review chi-square tests related tests and perform data analysis using R in the subsequent module 4.

To help you gain better understanding of various chisquare tests to assess the association between two categorical variables. For illustration, we focus on the case of two binary categorical variables. Some of concepts in the following can be generalized to case of categorical variables with multiple categories.

2.1 Study Designs for Data Collection

These three study designs are fundamental in epidemiology and clinical research in which two categorical variables are involved: outcome variable (such as disease status) and exposure variable (such as smoking status). Each has distinct strengths, weaknesses, and applications. Below is a structured comparison.

1. Cohort Study Design

A cohort study is a type of epidemiological study in which a group of people with a common characteristic is followed over time to find how many reach a certain health outcome of interest (disease, condition, event, death, or a change in health status or behavior). A

Cohort studies compare an exposed group of individuals to an unexposed (or less exposed) group of individuals to determine if the outcome of interest is associated with exposure. That is, cohort studies focus on the relationship between the outcome and exposure variables.

Data Collection in Cohort Studies is based on stratified sampling. That is, the entire population is divided into subpopulations according to the values of the outcome variable or the exposure variable. Sub-random samples are then taken from each subpopulation, respectively.

  • If the population is stratified by the outcome variable - the status of lung cancer, the two stratified samples are taken from cancer population and cancer-free population.
  • If the population is stratified by the exposure variable - the status of smoking, the two stratified samples are taken from smoking population and non-smoking population.

The combined sample is called stratified sample. There are two types of cohort studies: prospective and retrospective (or historical) cohorts.

  • Prospective studies follow a cohort into the future for a health outcome. This means, the exposure variable splits the population in exposed population and unexposed population. The two subsamples will be take from exposed population and unexposed population respectively and then follow up for some time to observe the outcome.

  • retrospective studies trace the cohort back in time for exposure information after the outcome has occurred. The retrospective cohort study is also called case-control study.

Caution:

2. Cross-sectional Study Design

A cross-sectional study design is a type of observational research method that analyzes data from a population, or a representative subset, at a single point in time. It is commonly used in epidemiology, public health, social sciences, and market research.

Most of statistical models were developed based on crodd-sectional data. For example, a researcher surveys 1,000 adults to assess the prevalence of hypertension and collects information about age, BMI, and smoking status at the time of the survey.

3. Randomized Controlled Trials

A Randomized Controlled Trial (RCT) is a prospective experimental study design considered the gold standard for evaluating the effectiveness of interventions (e.g., drugs, treatments, policies).

  • Randomization: Participants are randomly assigned to either an intervention group or a control group (e.g., placebo or standard treatment).

  • Control: A comparison group is used to measure the effect of the intervention.

  • Blinding (optional but common): Reduces bias. Can be:

    • Single-blind (participants unaware)

    • Double-blind (participants and researchers unaware)

  • Prospective: Follows participants forward in time after assignment.

Example: A clinical trial randomly assigns 200 patients with high blood pressure to receive either a new antihypertensive drug or a placebo. Blood pressure is monitored over 6 months to evaluate the drug’s effectiveness.


The following short YouTube video summarized the above major study designs.



3 Measures of Association

3.1 Contingency Tables

ontingency tables (also called cross-tabulations or crosstabs) are fundamental tools in statistics for analyzing relationships between categorical variables. They organize data into rows and columns to display frequency distributions, enabling researchers to identify patterns, test hypotheses, and measure associations.

Structure of Contingency Tables

The general structure of a contingency table depicted in the following:

Outcome (Yes) Outcome (No) Total
Exposure (yes) a b a + b
Exposure (No) c d c + c
Total a + c b +d a + b + c + d

We can see that a basic contingency table is an \(r \times c\) matrix where:
+ Rows (\(r\)): Represent categories of one variable.
+ Columns (\(c\)): Represent categories of another variable.
+ Cells: Contain frequency counts for each variable combination.

The above contingency table is essentially a two-way (or bivariate) frequency table. Similar to we did in introductory statistics (MAT121/125 at WCU), we can turn the above raw (ordinary) frequency table the corresponding relative bivariate frequency table in the following form, where T = a + b + c + d.

Outcome (Yes) Outcome (No) Total
Exposure (yes) a/T b/T (a + b)/T
Exposure (No) c/T d/T (c + c)/T
Total (a + c)/T (b +d)/T T= a + b + c + d


Important note on the layout of contingency table:Column names MUST be the distict values of OUTCOME variable and row names MUST be the distinct values of EXPOSURE variable!!!


The following YouTube video (https://www.youtube.com/watch?v=W95BgQCp_rQ) explains the above contingency table with an example.



3.2 Risk Measures of Association

For single categorical variable, we focus on the distribution using frequency tables and charts. In the case of two categorical variables, we focus primarily on the association between them. The basic analytic logic is to assess whether the association between the two categorical variables, if exists, we need to define numerical measures to measure the strength of the related association.

We have introduced different study designs for data collection. A dataset collected using Different study designs contains different amount information. This means that when analyzing a contingency table and defining measures of association, we need to know the study design associated with the contingency table.

Here are commonly used risk measures based on the following general 2-by-2 contingency table.

Disease (+) Disease (-) Total
Exposed (+) a b a+b
Unexposed (-) c d c+d
Total a+c b+d N=a+b+c+d

1. Absolute Risk Measures

  • Risk in Exposed (Attack Rate) is the probability of disease in exposed group which is defined by

\[ AR_\text{exp} = \frac{a}{a+b}. \]

  • Risk in Unexposed is the probability of disease in unexposed group which is defined by

\[ AR_\text{unexp} = \frac{c}{c+d}. \]

2. Relative Risk Measures

  • Risk Ratio (RR)

\[ RR = \frac{AR_{exp}}{AR_{unexp}} = \frac{a/(a+b)}{c/(c+d)} \]

  • Odds Ratio (OR)

\[ OR = \frac{a/b}{c/d} = \frac{ad}{bc}, \] where \(a/b\) is the odds of disease and \(c/d\) the odds of disease-free.

  • Interpretation

  • RR (OR) = 1: No association

  • RR (OR)> 1: Increased risk with exposure

  • RR (OR)< 1: Protective effect

  • When to use:

Design Primary Measure Formula
Case-Control Odds Ratio (OR) \(OR=ad/bc\)
Cohort Relative Risk (RR) \(RR=\frac{a/(a+b)}{c/(c+d)}\)
Cross-Sectional Prevalence Ratio \(\frac{\text{Prevalence}_1}{\text{Prevalence}_2}\)


The next excellent YouTube video (https://www.youtube.com/watch?v=Sec4fewyUig) discusses the two most commonly used measures of risk: relative risk (RR) and odds ratio (OR).



4 Chi-square Test of Independence

Let \(X\) and \(Y\) be two categorical variables with \(k\) and \(m\) categories respectively. Their relationship between \(X\) and \(Y\) is characterized by their joint distribution (table). For simplicity, we use the following two special categorical to explain the ideas of statistical testing of independence.

4.1 Independence of Two Categorical Variables

We use the following example to illustrate independence and dependence between two categorical variables.

Example 5. Joint probabilities and contingency tables. Let \(X =\) political preference (Democrat vs Republican) and \(Y =\)gender (Male and Female). Let’s assume their joint distribution to be of the following contingency table.

include_graphics("week02/twoWayContingencyTable.png")

The cell numbers are joint probabilities. For example, \(p_{12} = 0.2 = 20\%\) says \(20\%\) of the study population are male republicans. The row and column totals represent the percentage of male/female and democrats/republicans in the study population. Any observed data table is governed by the above joint distribution table.

Definition Two categorical variables are independent if and only if their joint probabilities are equal to the product of their corresponding marginal probabilities.

With this definition, we can see that \(X\) and \(Y\) with joint distribution specified in the above table (in Example 5) ar NOT independent since \(p_{11} =0.3 \ne 0.5\times 0.5 = 0.25\).

Example 6. We consider two variables \(X =\) preference of hair color (Blonde and Brunette) and \(Y =\) gender (Male and Female). Assume the joint distribution of the two variables is given by

include_graphics("week02/independenceContingencyTable.png")

Based on the definition of independence. The preference for hair color is independent of gender. Since all joint probabilities are equal to the product of their corresponding marginal probabilities.

\(0.45\times 0.40 = 0.18, 0.45 \times 0.60 = 0.27, 0.55 \times 0.40 = 0.22\), and \(0.55 \times 0.60 = 0.33.\)

4.2 Expected Table Under Independence Assumption (\(H_0\))

We construct the expected table under the null hypothesis of independence and the observed contingency table. For ease of interpretation, we use an example to illustrate the steps for obtaining the expected table.

Example 7. Consider the potential dependence between the attendance (good vs poor) and course grade (pass vs fail). We take 50 students from a population and obtain the following observed table.

include_graphics("week02/attendancePassFail.png")

Question: Whether the attendance is independent of class performance? \[ Ho: \ \ attendance \ is \ \ independent \ \ of \ the \ performance \] \[versus\]

\[ Ha: \ \ attendance \ is \ \ dependent \ of \ the \ performance \]

To obtain the expected table, we follow the next few steps.

  1. Estimate the marginal probabilities
include_graphics("week02/marginalTable.png")

           where marginal probabilities are calculated by Pr(Good) = 27/50 = 0.54, Pr(Poor) = 23/50 = 0.46, Pr(Pass) = 33/50 = 0.66, Pr(Fail) = 17/50 = 0.34.

  1. Estimate the joint probability under the null hypothesis of independence
include_graphics("week02/jointProb.png")

           where joint probabilities under the independence assumption (\(H_0\)) are calculated by taking the product of the corresponding marginal probabilities. For example, 0.54 \(\times\) 0.66 = 0.3564.

  1. Calculate Expected Table

          The expected frequencies are calculated in the following table (with detailed steps).

include_graphics("week02/expectedTable.png")


Remarks

  • For categorical variables with more than two categories, the expected table can be found using ** the same 3 steps** as those used in the above example.

  • The generic formula for calculate any expected frequency is given by

\[ \text{Expected Frequency} = \frac{\text{column total} \times \text{row total}}{\text{grand total}} \]

  • We use the above formula on the previous example. Find the expected frequency in the first column (Pass) and second row (Poor). The sample size is 50 (the grand total).

\[ 15.1 \approx \frac{33\times 23}{50}. \]

The following YouTube video (https://www.youtube.com/watch?v=S9XTAXn_qm4) gives another example on how to calculate the expected frequency manually.




4.3 Formulation of Chi-squares Test of Independence

The test statistic used to test the independence of two categorical variables is the same as that used in the goodness-of-fit test. That is the standardized “distance” between the observed and the expected table (under \(H_0\)).

color{red}Assume that the two categorical variables have \(k\) and \(m\) categories respectively, then the resulting test statistic has a chi-square distribution with \((k-1)\times(m-1)\) degrees of freedom.

Example 8. [Continuation of Example 7]. Test whether attendance and class performance.

Solution: We have found the expected table under \(H_0\) in Example 7, we put the observed and expected tables in the following.

include_graphics("week02/example08ExpObs.png")

The test statistic is given by

\[ TS = \frac{(25-18.82)^2}{17.82} + \frac{(2-9.18)^2}{9.18} + \frac{(8-15.18)^2}{15.18} + \frac{(15-7.82)^2}{7.82} = 17.75 \]

The test statistic has a chi-square distribution with \((2-1)\times (2-1) = 1\) degrees of freedom. The critical value at the significance level of 0.05 is found in the following figure.

include_graphics("week02/example08ChisqCV.png")

Since the test statistic is inside the rejection region, we reject the null hypothesis that attendance and class performance are independent.

Example 9. Do some college majors require more studying than others? The National Survey of Student Engagement asked a number of college freshmen what their major was and how many hours per week they spent studying, on average. A sample of 1000 of these students was chosen, and the numbers of students in each category are tabulated in the following two-way contingency table.

include_graphics("week02/example09Data.png")

Solution: The null and alternative hypotheses are given by

       Ho: studying time is INDEPENDENT on majors
                   versus
       Ha: studying time is DEPENDENT on majors.

Under the null hypothesis, we obtained the expected table using the same steps in Example 7 in the following.

include_graphics("week02/example09ExpTable.png")

The test statistic is given by

include_graphics("week02/example09TS.png")

The critical value and rejection region based on significance level 0.05 is given by

include_graphics("week02/example09CV.png")

Conclusion: Since the test statistic is inside the rejection region, we reject the null hypothesis and conclude that the studying time is dependent on the majors.

To conclude this section, watch the following YouTube video (https://www.youtube.com/watch?v=y5nxiL6civU) for another manually worked-out example of chisquared test of independence.



5 Practice Exercises

  1. Political Affiliation and Opinion

The following table based on the sample will be used to explore the relationship between Party Affiliation and Opinion on Tax Reform.

include_graphics("week02/practiceEx02Data.png")

Find the expected counts for all of the cells.

  1. Tire Quality

The operations manager of a company that manufactures tires wants to determine whether there are any differences in the quality of work among the three daily shifts. She randomly selects 496 tires and carefully inspects them. Each tire is either classified as perfect, satisfactory, or defective, and the shift that produced it is also recorded. The two categorical variables of interest are the shift and condition of the tire produced. The data can be summarized by the accompanying two-way table. Does the data provide sufficient evidence at the 5% significance level to infer that there are differences in quality among the three shifts?

include_graphics("week02/practiceEx03Data.png")

  1. Condiment preference and gender

A food services manager for a baseball park wants to know if there is a relationship between gender (male or female) and the preferred condiment on a hot dog. The following table summarizes the results. Test the hypothesis with a significance level of 10%.

include_graphics("week02/practiceEx04Data.png")

LS0tDQp0aXRsZTogIk1lYXN1cmVzIG9mIEFzc29jaWF0aW9uIGFuZCBDaGlzcXVhcmUgVGVzdCBvZiBJbmRlcGVuZGVuY2UiDQphdXRob3I6ICJDaGVuZyBQZW5nIg0KZGF0ZTogIlNUQTIwMCBTdGF0aXN0aWNzIElJICINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDUNCiAgICBmaWdfaGVpZ2h0OiA0DQotLS0NCg0KYGBgez1odG1sfQ0KDQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQpkaXYjVE9DIGxpIHsNCiAgICBsaXN0LXN0eWxlOm5vbmU7DQogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOw0KICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7DQogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOw0KfQ0KaDEudGl0bGUgew0KICBmb250LXNpemU6IDI0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgxIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDIwcHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgyIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE2cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCjwvc3R5bGU+DQpgYGANCg0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQoNCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCiMga25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSAiQzovVXNlcnMvNzVDUEVORy9PbmVEcml2ZSAtIFdlc3QgQ2hlc3RlciBVbml2ZXJzaXR5IG9mIFBBL0RvY3VtZW50cyIpDQojIGtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gIkM6XFxTVEE0OTBcXHcwNSIpDQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IFRSVUUsICAgDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFKQ0KYGBgDQoNCg0KDQpcDQoNCg0KIyBJbnRyb2R1Y3Rpb24NCg0KV2UgaGF2ZSBkaXNjdXNzZWQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHR3byBudW1lcmljYWwgdmFyaWFibGVzIHVzaW5nIGxpbmVhciBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBhbmQgbGluZWFyIHJlZ3Jlc3Npb24uIFdlIG5vdyBleHBsb3JlIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0d28gY2F0ZWdvcmljYWwgdmFyaWFibGVzLiBUaGUgaWRlYSBpcyB0byBtYWtlIGFuIGFzc3VtcHRpb24gKGh5cG90aGVzaXMpIGFib3V0IHRoZSB2YXJpYWJsZSAocykgYW5kIHVzZSB0aGUgYXNzdW1wdGlvbiB0byBjb25zdHJ1Y3QgYSBmcmVxdWVuY3kgdGFibGUgKGNhbGxlZCB0aGUgZXhwZWN0ZWQgdGFibGUpLiBBdCB0aGUgc2FtZSB0aW1lLCB3ZSB0YWJ1bGF0ZWQgdGhlIGRhdGEgdG8gb2J0YWluIGFuIG9ic2VydmVkIHRhYmxlLiBUaGUgZGlzY3JlcGFuY3kgYmV0d2VlbiB0aGUgZXhwZWN0ZWQgdGFibGUgYW5kIHRoZSBvYnNlcnZlZCB0YWJsZSBjYW4gYmUgdXNlZCB0byBtYWtlIHRoZSBpbmZlcmVuY2UgYWJvdXQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGNhdGVnb3JpY2FsIHZhcmlhYmxlcy4NCg0KDQojIEVwaWRlbW9sb2dpYyBTdHVkeSBEZXNpZ25zDQoNCkluIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MsIHdlIGludHJvZHVjZSBmcmVxdWVuY3kgdGFibGUgYW5kIGJhci1jaGFydCB0byBjaGFyYWN0ZXJpemUgdGhlIGRpc3RyaWJ1dGlvbi4gV2UgYWxzbyBicmllZmx5IGludHJvZHVjZWQgY2hpLXNxdWFyZSB0ZXN0cyBvZiBpbmRlcGVuZGVuY2Ugb2YgdHdvIGNhdGVnb3JpY2FsIHZhcmlhYmxlcy4gV2Ugd2lsbCByZXZpZXcgY2hpLXNxdWFyZSB0ZXN0cyByZWxhdGVkIHRlc3RzIGFuZCBwZXJmb3JtIGRhdGEgYW5hbHlzaXMgdXNpbmcgUiBpbiB0aGUgc3Vic2VxdWVudCBtb2R1bGUgNC4NCg0KVG8gaGVscCB5b3UgZ2FpbiBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZiB2YXJpb3VzIGNoaXNxdWFyZSB0ZXN0cyB0byBhc3Nlc3MgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gdHdvIGNhdGVnb3JpY2FsIHZhcmlhYmxlcy4gRm9yIGlsbHVzdHJhdGlvbiwgd2UgZm9jdXMgb24gdGhlIGNhc2Ugb2YgdHdvIGJpbmFyeSBjYXRlZ29yaWNhbCB2YXJpYWJsZXMuIFNvbWUgb2YgY29uY2VwdHMgaW4gdGhlIGZvbGxvd2luZyBjYW4gYmUgZ2VuZXJhbGl6ZWQgdG8gY2FzZSBvZiBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgd2l0aCBtdWx0aXBsZSBjYXRlZ29yaWVzLg0KDQojIyBTdHVkeSBEZXNpZ25zIGZvciBEYXRhIENvbGxlY3Rpb24NCg0KVGhlc2UgdGhyZWUgc3R1ZHkgZGVzaWducyBhcmUgZnVuZGFtZW50YWwgaW4gZXBpZGVtaW9sb2d5IGFuZCBjbGluaWNhbCByZXNlYXJjaCBpbiB3aGljaCB0d28gY2F0ZWdvcmljYWwgdmFyaWFibGVzIGFyZSBpbnZvbHZlZDogKipvdXRjb21lIHZhcmlhYmxlKiogKHN1Y2ggYXMgZGlzZWFzZSBzdGF0dXMpICBhbmQgKipleHBvc3VyZSB2YXJpYWJsZSoqIChzdWNoIGFzIHNtb2tpbmcgc3RhdHVzKS4gRWFjaCBoYXMgZGlzdGluY3Qgc3RyZW5ndGhzLCB3ZWFrbmVzc2VzLCBhbmQgYXBwbGljYXRpb25zLiBCZWxvdyBpcyBhIHN0cnVjdHVyZWQgY29tcGFyaXNvbi4NCg0KDQoqKjEuIENvaG9ydCBTdHVkeSBEZXNpZ24qKg0KDQpBIGNvaG9ydCBzdHVkeSBpcyBhIHR5cGUgb2YgZXBpZGVtaW9sb2dpY2FsIHN0dWR5IGluIHdoaWNoIGEgZ3JvdXAgb2YgcGVvcGxlIHdpdGggYSAqKmNvbW1vbiBjaGFyYWN0ZXJpc3RpYyoqIGlzICoqZm9sbG93ZWQgb3ZlciB0aW1lKiogdG8gZmluZCBob3cgbWFueSByZWFjaCBhIGNlcnRhaW4gaGVhbHRoICoqb3V0Y29tZSoqIG9mIGludGVyZXN0IChkaXNlYXNlLCBjb25kaXRpb24sIGV2ZW50LCBkZWF0aCwgb3IgYSBjaGFuZ2UgaW4gaGVhbHRoIHN0YXR1cyBvciBiZWhhdmlvcikuIEENCg0KKipDb2hvcnQgc3R1ZGllcyoqIGNvbXBhcmUgYW4gZXhwb3NlZCBncm91cCBvZiBpbmRpdmlkdWFscyB0byBhbiB1bmV4cG9zZWQgKG9yIGxlc3MgZXhwb3NlZCkgZ3JvdXAgb2YgaW5kaXZpZHVhbHMgdG8gZGV0ZXJtaW5lIGlmIHRoZSAqKm91dGNvbWUqKiBvZiBpbnRlcmVzdCBpcyBhc3NvY2lhdGVkIHdpdGggKipleHBvc3VyZSoqLiBUaGF0IGlzLCBjb2hvcnQgc3R1ZGllcyBmb2N1cyBvbiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIG91dGNvbWUgYW5kIGV4cG9zdXJlIHZhcmlhYmxlcy4gDQoNCioqRGF0YSBDb2xsZWN0aW9uIGluIENvaG9ydCBTdHVkaWVzKiogaXMgYmFzZWQgb24gc3RyYXRpZmllZCBzYW1wbGluZy4gVGhhdCBpcywgdGhlIGVudGlyZSBwb3B1bGF0aW9uIGlzIGRpdmlkZWQgaW50byBzdWJwb3B1bGF0aW9ucyBhY2NvcmRpbmcgdG8gdGhlIHZhbHVlcyBvZiB0aGUgb3V0Y29tZSB2YXJpYWJsZSBvciB0aGUgZXhwb3N1cmUgdmFyaWFibGUuIFN1Yi1yYW5kb20gc2FtcGxlcyBhcmUgdGhlbiB0YWtlbiBmcm9tIGVhY2ggc3VicG9wdWxhdGlvbiwgcmVzcGVjdGl2ZWx5LiANCg0KICArIElmIHRoZSBwb3B1bGF0aW9uIGlzIHN0cmF0aWZpZWQgYnkgdGhlIG91dGNvbWUgdmFyaWFibGUgLSB0aGUgc3RhdHVzIG9mIGx1bmcgY2FuY2VyLCB0aGUgdHdvIHN0cmF0aWZpZWQgc2FtcGxlcyBhcmUgdGFrZW4gZnJvbSBjYW5jZXIgcG9wdWxhdGlvbiBhbmQgY2FuY2VyLWZyZWUgcG9wdWxhdGlvbi4NCiAgKyBJZiB0aGUgcG9wdWxhdGlvbiBpcyBzdHJhdGlmaWVkIGJ5IHRoZSBleHBvc3VyZSB2YXJpYWJsZSAtIHRoZSBzdGF0dXMgb2Ygc21va2luZywgdGhlIHR3byBzdHJhdGlmaWVkIHNhbXBsZXMgYXJlIHRha2VuIGZyb20gc21va2luZyBwb3B1bGF0aW9uIGFuZCBub24tc21va2luZyBwb3B1bGF0aW9uLg0KDQpUaGUgY29tYmluZWQgc2FtcGxlIGlzIGNhbGxlZCBzdHJhdGlmaWVkIHNhbXBsZS4gVGhlcmUgYXJlIHR3byB0eXBlcyBvZiBjb2hvcnQgc3R1ZGllczogKipwcm9zcGVjdGl2ZSoqIGFuZCAqKnJldHJvc3BlY3RpdmUqKiAob3IgaGlzdG9yaWNhbCkgY29ob3J0cy4gDQoNCg0KKiAqKlByb3NwZWN0aXZlIHN0dWRpZXMqKiA8Zm9udCBjb2xvciA9ICJyZWQiPioqXGNvbG9ye3JlZH1mb2xsb3cqKjwvZm9udD4gYSBjb2hvcnQgaW50byB0aGUgZnV0dXJlIGZvciBhIGhlYWx0aCBvdXRjb21lLiBUaGlzIG1lYW5zLCB0aGUgZXhwb3N1cmUgdmFyaWFibGUgc3BsaXRzIHRoZSBwb3B1bGF0aW9uIGluIGV4cG9zZWQgcG9wdWxhdGlvbiBhbmQgdW5leHBvc2VkIHBvcHVsYXRpb24uIFRoZSB0d28gc3Vic2FtcGxlcyB3aWxsIGJlIHRha2UgZnJvbSBleHBvc2VkIHBvcHVsYXRpb24gYW5kIHVuZXhwb3NlZCBwb3B1bGF0aW9uIHJlc3BlY3RpdmVseSBhbmQgdGhlbiBmb2xsb3cgdXAgZm9yIHNvbWUgdGltZSB0byBvYnNlcnZlIHRoZSBvdXRjb21lLiANCg0KDQoqICoqcmV0cm9zcGVjdGl2ZSBzdHVkaWVzKiogdHJhY2UgdGhlIGNvaG9ydCA8Zm9udCBjb2xvciA9ICJyZWQiPioqXGNvbG9ye3JlZH1iYWNrKio8L2ZvbnQ+IDxmb250IGNvbG9yID0gImJsdWUiPipcY29sb3J7Ymx1ZX1pbiB0aW1lKjwvZm9udD4gZm9yIGV4cG9zdXJlIGluZm9ybWF0aW9uIGFmdGVyIHRoZSBvdXRjb21lIGhhcyBvY2N1cnJlZC4gIFRoZSByZXRyb3NwZWN0aXZlIGNvaG9ydCBzdHVkeSBpcyBhbHNvIGNhbGxlZCAqKmNhc2UtY29udHJvbCBzdHVkeSoqLg0KDQo8Zm9udCBjb2xvciA9ICJyZWQiPioqXGNvbG9ye3JlZH1DYXV0aW9uKio8L2ZvbnQ+OiANCg0KDQoNCioqMi4gQ3Jvc3Mtc2VjdGlvbmFsIFN0dWR5IERlc2lnbioqDQoNCkEgKipjcm9zcy1zZWN0aW9uYWwgc3R1ZHkgZGVzaWduKiogaXMgYSB0eXBlIG9mIG9ic2VydmF0aW9uYWwgcmVzZWFyY2ggbWV0aG9kIHRoYXQgYW5hbHl6ZXMgZGF0YSBmcm9tIGEgcG9wdWxhdGlvbiwgb3IgYSByZXByZXNlbnRhdGl2ZSBzdWJzZXQsIDxmb250IGNvbG9yID0gInJlZCI+KipcY29sb3J7cmVkfWF0IGEgc2luZ2xlIHBvaW50IGluIHRpbWUqKjwvZm9udD4uIEl0IGlzIGNvbW1vbmx5IHVzZWQgaW4gZXBpZGVtaW9sb2d5LCBwdWJsaWMgaGVhbHRoLCBzb2NpYWwgc2NpZW5jZXMsIGFuZCBtYXJrZXQgcmVzZWFyY2guIA0KDQoqKk1vc3Qgb2Ygc3RhdGlzdGljYWwgbW9kZWxzIHdlcmUgZGV2ZWxvcGVkIGJhc2VkIG9uIGNyb2RkLXNlY3Rpb25hbCBkYXRhKiouIEZvciBleGFtcGxlLCBhIHJlc2VhcmNoZXIgc3VydmV5cyAxLDAwMCBhZHVsdHMgdG8gYXNzZXNzIHRoZSBwcmV2YWxlbmNlIG9mIGh5cGVydGVuc2lvbiBhbmQgY29sbGVjdHMgaW5mb3JtYXRpb24gYWJvdXQgYWdlLCBCTUksIGFuZCBzbW9raW5nIHN0YXR1cyAqKmF0IHRoZSB0aW1lKiogb2YgdGhlIHN1cnZleS4NCg0KDQoNCioqMy4gUmFuZG9taXplZCBDb250cm9sbGVkIFRyaWFscyoqDQoNCkEgKipSYW5kb21pemVkIENvbnRyb2xsZWQgVHJpYWwgKFJDVCkqKiBpcyBhICoqcHJvc3BlY3RpdmUgZXhwZXJpbWVudGFsIHN0dWR5IGRlc2lnbioqIGNvbnNpZGVyZWQgdGhlIGdvbGQgc3RhbmRhcmQgZm9yIGV2YWx1YXRpbmcgdGhlIGVmZmVjdGl2ZW5lc3Mgb2YgaW50ZXJ2ZW50aW9ucyAoZS5nLiwgZHJ1Z3MsIHRyZWF0bWVudHMsIHBvbGljaWVzKS4gDQoNCiogKipSYW5kb21pemF0aW9uKio6IFBhcnRpY2lwYW50cyBhcmUgcmFuZG9tbHkgYXNzaWduZWQgdG8gZWl0aGVyIGFuIGludGVydmVudGlvbiBncm91cCBvciBhIGNvbnRyb2wgZ3JvdXAgKGUuZy4sIHBsYWNlYm8gb3Igc3RhbmRhcmQgdHJlYXRtZW50KS4NCg0KKiAqKkNvbnRyb2wqKjogQSBjb21wYXJpc29uIGdyb3VwIGlzIHVzZWQgdG8gbWVhc3VyZSB0aGUgZWZmZWN0IG9mIHRoZSBpbnRlcnZlbnRpb24uDQoNCiogKipCbGluZGluZyAob3B0aW9uYWwgYnV0IGNvbW1vbikqKjogUmVkdWNlcyBiaWFzLiBDYW4gYmU6DQoNCiAgKyBTaW5nbGUtYmxpbmQgKHBhcnRpY2lwYW50cyB1bmF3YXJlKQ0KDQogICsgRG91YmxlLWJsaW5kIChwYXJ0aWNpcGFudHMgYW5kIHJlc2VhcmNoZXJzIHVuYXdhcmUpDQoNCiogKipQcm9zcGVjdGl2ZSoqOiBGb2xsb3dzIHBhcnRpY2lwYW50cyBmb3J3YXJkIGluIHRpbWUgYWZ0ZXIgYXNzaWdubWVudC4NCg0KDQoqKkV4YW1wbGUqKjogIEEgY2xpbmljYWwgdHJpYWwgcmFuZG9tbHkgYXNzaWducyAyMDAgcGF0aWVudHMgd2l0aCBoaWdoIGJsb29kIHByZXNzdXJlIHRvIHJlY2VpdmUgZWl0aGVyIGEgbmV3IGFudGloeXBlcnRlbnNpdmUgZHJ1ZyBvciBhIHBsYWNlYm8uIEJsb29kIHByZXNzdXJlIGlzIG1vbml0b3JlZCBvdmVyIDYgbW9udGhzIHRvIGV2YWx1YXRlIHRoZSBkcnVnJ3MgZWZmZWN0aXZlbmVzcy4NCg0KXA0KDQpUaGUgZm9sbG93aW5nIHNob3J0IFlvdVR1YmUgdmlkZW8gc3VtbWFyaXplZCB0aGUgYWJvdmUgbWFqb3Igc3R1ZHkgZGVzaWducy4NCg0KDQoNClwNCjxjZW50ZXI+PGEgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1fZkpLZnVsbGRCTSIgdGFyZ2V0PSJwb3B1cCIgDQogICAgICAgICAgICAgICAgICAgb25jbGljaz0id2luZG93Lm9wZW4oJ2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9X2ZKS2Z1bGxkQk0nLA0KICAgICAgICAgICAgICAgICAgICAgICduYW1lJywnd2lkdGg9ODUwLGhlaWdodD01MDAnKSI+PGltZyBzcmMgPSAiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vTUFUMTIxVzUvaW1nL1ZpZGVvSWNvbi5wbmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMTIwIj48L2E+DQo8L2NlbnRlcj4NClwNCg0KDQojIE1lYXN1cmVzIG9mIEFzc29jaWF0aW9uDQoNCg0KIyMgQ29udGluZ2VuY3kgVGFibGVzDQoNCm9udGluZ2VuY3kgdGFibGVzIChhbHNvIGNhbGxlZCAqKmNyb3NzLXRhYnVsYXRpb25zKiogb3IgKipjcm9zc3RhYnMqKikgYXJlIGZ1bmRhbWVudGFsIHRvb2xzIGluIHN0YXRpc3RpY3MgZm9yIGFuYWx5emluZyByZWxhdGlvbnNoaXBzIGJldHdlZW4gY2F0ZWdvcmljYWwgdmFyaWFibGVzLiBUaGV5IG9yZ2FuaXplIGRhdGEgaW50byByb3dzIGFuZCBjb2x1bW5zIHRvIGRpc3BsYXkgZnJlcXVlbmN5IGRpc3RyaWJ1dGlvbnMsIGVuYWJsaW5nIHJlc2VhcmNoZXJzIHRvIGlkZW50aWZ5IHBhdHRlcm5zLCB0ZXN0IGh5cG90aGVzZXMsIGFuZCBtZWFzdXJlIGFzc29jaWF0aW9ucy4gIA0KDQoqKlN0cnVjdHVyZSBvZiBDb250aW5nZW5jeSBUYWJsZXMqKiAgDQoNClRoZSBnZW5lcmFsIHN0cnVjdHVyZSBvZiBhIGNvbnRpbmdlbmN5IHRhYmxlIGRlcGljdGVkIGluIHRoZSBmb2xsb3dpbmc6IA0KDQp8ICAgICAgICAgICAgICAgICAgIHwgKipPdXRjb21lIChZZXMpKip8ICoqT3V0Y29tZSAoTm8pKiogICB8ICoqVG90YWwqKiAgICAgIHwgIA0KfC0tLS0tLS0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tLS0tfDotLS0tLS0tLS0tLS0tLS0tLS0tfDotLS0tLS0tLS0tLS0tLS18ICANCnwgKipFeHBvc3VyZSAoeWVzKSoqfCBhICAgICAgICAgICAgICAgIHwgYiAgICAgICAgICAgICAgICAgIHwgYSArIGIgICAgICAgICAgfCAgDQp8ICoqRXhwb3N1cmUgKE5vKSoqIHwgYyAgICAgICAgICAgICAgICB8IGQgICAgICAgICAgICAgICAgICB8IGMgKyBjICAgICAgICAgIHwgIA0KfCAqKlRvdGFsKiogICAgICAgICB8IGEgKyBjICAgICAgICAgICAgfCBiICtkICAgICAgICAgICAgICAgfCBhICsgYiArIGMgKyBkICB8IA0KDQpXZSBjYW4gc2VlIHRoYXQgKiphIGJhc2ljIGNvbnRpbmdlbmN5IHRhYmxlKiogaXMgYW4gXCggciBcdGltZXMgYyBcKSBtYXRyaXggd2hlcmU6ICANCiAgKyAqKlJvd3MgKFwoIHIgXCkpKio6IFJlcHJlc2VudCBjYXRlZ29yaWVzIG9mIG9uZSB2YXJpYWJsZS4gIA0KICArICoqQ29sdW1ucyAoXCggYyBcKSkqKjogUmVwcmVzZW50IGNhdGVnb3JpZXMgb2YgYW5vdGhlciB2YXJpYWJsZS4gIA0KICArICoqQ2VsbHMqKjogQ29udGFpbiBmcmVxdWVuY3kgY291bnRzIGZvciBlYWNoIHZhcmlhYmxlIGNvbWJpbmF0aW9uLg0KDQoNClRoZSBhYm92ZSBjb250aW5nZW5jeSB0YWJsZSBpcyBlc3NlbnRpYWxseSBhIHR3by13YXkgKG9yIGJpdmFyaWF0ZSkgZnJlcXVlbmN5IHRhYmxlLiBTaW1pbGFyIHRvIHdlIGRpZCBpbiBpbnRyb2R1Y3Rvcnkgc3RhdGlzdGljcyAoTUFUMTIxLzEyNSBhdCBXQ1UpLCB3ZSBjYW4gdHVybiB0aGUgYWJvdmUgKipyYXcgKG9yZGluYXJ5KSBmcmVxdWVuY3kgdGFibGUqKiB0aGUgY29ycmVzcG9uZGluZyAqKnJlbGF0aXZlIGJpdmFyaWF0ZSBmcmVxdWVuY3kgdGFibGUqKiBpbiB0aGUgZm9sbG93aW5nIGZvcm0sIHdoZXJlIFQgPSBhICsgYiArIGMgKyBkLg0KDQoNCnwgICAgICAgICAgICAgICAgICAgfCAqKk91dGNvbWUgKFllcykqKnwgKipPdXRjb21lIChObykqKiAgIHwgKipUb3RhbCoqICAgICAgICB8ICANCnwtLS0tLS0tLS0tLS0tLS0tLS0tfDotLS0tLS0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tLS18ICANCnwgKipFeHBvc3VyZSAoeWVzKSoqfCBhL1QgICAgICAgICAgICAgIHwgYi9UICAgICAgICAgICAgICAgIHwgKGEgKyBiKS9UICAgICAgICB8ICANCnwgKipFeHBvc3VyZSAoTm8pKiogfCBjL1QgICAgICAgICAgICAgIHwgZC9UICAgICAgICAgICAgICAgIHwgKGMgKyBjKS9UICAgICAgICB8ICANCnwgKipUb3RhbCoqICAgICAgICAgfCAoYSArIGMpL1QgICAgICAgIHwgKGIgK2QpL1QgICAgICAgICAgIHwgVD0gYSArIGIgKyBjICsgZCB8IA0KDQpcDQoNCjxmb250IGNvbG9yID0gInJlZCI+KipJbXBvcnRhbnQgbm90ZSBvbiB0aGUgbGF5b3V0IG9mIGNvbnRpbmdlbmN5IHRhYmxlOioqPC9mb250Pjxmb250IGNvbG9yPSJyZWQiPipcY29sb3J7cmVkfUNvbHVtbiBuYW1lcyBNVVNUIGJlIHRoZSBkaXN0aWN0IHZhbHVlcyBvZiBPVVRDT01FIHZhcmlhYmxlIGFuZCByb3cgbmFtZXMgTVVTVCBiZSB0aGUgZGlzdGluY3QgdmFsdWVzIG9mIEVYUE9TVVJFIHZhcmlhYmxlISEhKjwvZm9udD4NCg0KXA0KDQpUaGUgZm9sbG93aW5nIFlvdVR1YmUgdmlkZW8gKDxodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PVc5NUJnUUNwX3JRPikgZXhwbGFpbnMgdGhlIGFib3ZlIGNvbnRpbmdlbmN5IHRhYmxlIHdpdGggYW4gZXhhbXBsZS4NCg0KXA0KPGNlbnRlcj48YSBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PVc5NUJnUUNwX3JRIiB0YXJnZXQ9InBvcHVwIiANCiAgICAgICAgICAgICAgICAgICBvbmNsaWNrPSJ3aW5kb3cub3BlbignaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1XOTVCZ1FDcF9yUScsDQogICAgICAgICAgICAgICAgICAgICAgJ25hbWUnLCd3aWR0aD04NTAsaGVpZ2h0PTUwMCcpIj48aW1nIHNyYyA9ICJodHRwczovL3Blbmdkc2NpLmdpdGh1Yi5pby9NQVQxMjFXNS9pbWcvVmlkZW9JY29uLnBuZyIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIxMjAiPjwvYT4NCjwvY2VudGVyPg0KXA0KDQoNCg0KIyMgUmlzayBNZWFzdXJlcyBvZiBBc3NvY2lhdGlvbg0KDQpGb3Igc2luZ2xlIGNhdGVnb3JpY2FsIHZhcmlhYmxlLCB3ZSBmb2N1cyBvbiB0aGUgZGlzdHJpYnV0aW9uIHVzaW5nIGZyZXF1ZW5jeSB0YWJsZXMgYW5kIGNoYXJ0cy4gSW4gdGhlIGNhc2Ugb2YgdHdvIGNhdGVnb3JpY2FsIHZhcmlhYmxlcywgd2UgZm9jdXMgcHJpbWFyaWx5IG9uIHRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIHRoZW0uIFRoZSBiYXNpYyBhbmFseXRpYyBsb2dpYyBpcyB0byBhc3Nlc3Mgd2hldGhlciB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiB0aGUgdHdvIGNhdGVnb3JpY2FsIHZhcmlhYmxlcywgaWYgZXhpc3RzLCB3ZSBuZWVkIHRvIGRlZmluZSBudW1lcmljYWwgbWVhc3VyZXMgdG8gbWVhc3VyZSB0aGUgc3RyZW5ndGggb2YgdGhlIHJlbGF0ZWQgYXNzb2NpYXRpb24uDQoNCldlIGhhdmUgaW50cm9kdWNlZCBkaWZmZXJlbnQgc3R1ZHkgZGVzaWducyBmb3IgZGF0YSBjb2xsZWN0aW9uLiBBIGRhdGFzZXQgY29sbGVjdGVkIHVzaW5nICoqRGlmZmVyZW50IHN0dWR5IGRlc2lnbnMqKiBjb250YWlucyAqKmRpZmZlcmVudCBhbW91bnQgaW5mb3JtYXRpb24qKi4gIFRoaXMgbWVhbnMgdGhhdCB3aGVuIGFuYWx5emluZyBhIGNvbnRpbmdlbmN5IHRhYmxlIGFuZCBkZWZpbmluZyBtZWFzdXJlcyBvZiBhc3NvY2lhdGlvbiwgd2UgbmVlZCB0byBrbm93IHRoZSBzdHVkeSBkZXNpZ24gYXNzb2NpYXRlZCB3aXRoIHRoZSBjb250aW5nZW5jeSB0YWJsZS4NCg0KSGVyZSBhcmUgY29tbW9ubHkgdXNlZCByaXNrIG1lYXN1cmVzIGJhc2VkIG9uIHRoZSBmb2xsb3dpbmcgZ2VuZXJhbCAyLWJ5LTIgY29udGluZ2VuY3kgdGFibGUuDQoNCg0KfCAgICAgICAgICAgICB8ICoqRGlzZWFzZSAoKykqKiB8ICoqRGlzZWFzZSAoLSkqKiB8ICoqVG90YWwqKiB8DQp8Oi0tLS0tLS0tLS0tLS0tLS0tfDotLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tfA0KfCAqKkV4cG9zZWQgKCspKiogIHwgYSAgICAgICAgICAgfCBiICAgICAgICAgICB8IGErYiAgICAgIHwNCnwgKipVbmV4cG9zZWQgKC0pKip8IGMgICAgICAgICAgIHwgZCAgICAgICAgICAgfCBjK2QgICAgICB8DQp8ICoqVG90YWwqKiAgICAgICAgfCBhK2MgICAgICAgICB8IGIrZCAgICAgICAgIHwgTj1hK2IrYytkfA0KDQoNCioqMS4gQWJzb2x1dGUgUmlzayBNZWFzdXJlcyoqDQoNCiogUmlzayBpbiBFeHBvc2VkIChBdHRhY2sgUmF0ZSkgaXMgdGhlIHByb2JhYmlsaXR5IG9mIGRpc2Vhc2UgaW4gZXhwb3NlZCBncm91cCB3aGljaCBpcyBkZWZpbmVkIGJ5DQoNCiQkDQpBUl9cdGV4dHtleHB9ID0gXGZyYWN7YX17YStifS4NCiQkDQoNCg0KKiBSaXNrIGluIFVuZXhwb3NlZCBpcyB0aGUgcHJvYmFiaWxpdHkgb2YgZGlzZWFzZSBpbiB1bmV4cG9zZWQgZ3JvdXAgd2hpY2ggaXMgZGVmaW5lZCBieQ0KDQokJA0KQVJfXHRleHR7dW5leHB9ID0gXGZyYWN7Y317YytkfS4NCiQkDQoNCioqMi4gUmVsYXRpdmUgUmlzayBNZWFzdXJlcyoqDQoNCiogUmlzayBSYXRpbyAoUlIpDQoNCiQkDQpSUiA9IFxmcmFje0FSX3tleHB9fXtBUl97dW5leHB9fSA9IFxmcmFje2EvKGErYil9e2MvKGMrZCl9DQokJA0KDQoNCiogT2RkcyBSYXRpbyAoT1IpDQoNCiQkDQpPUiA9IFxmcmFje2EvYn17Yy9kfSA9IFxmcmFje2FkfXtiY30sDQokJA0Kd2hlcmUgJGEvYiQgaXMgdGhlIG9kZHMgb2YgZGlzZWFzZSBhbmQgJGMvZCQgdGhlIG9kZHMgb2YgZGlzZWFzZS1mcmVlLg0KDQoNCiogKipJbnRlcnByZXRhdGlvbioqDQotIFJSIChPUikgPSAxOiBObyBhc3NvY2lhdGlvbg0KLSBSUiAoT1IpPiAxOiBJbmNyZWFzZWQgcmlzayB3aXRoIGV4cG9zdXJlDQotIFJSIChPUik8IDE6IFByb3RlY3RpdmUgZWZmZWN0DQoNCg0KDQoqICoqV2hlbiB0byB1c2UqKjoNCg0KfCAgIERlc2lnbiAgICAgICAgIHwgIFByaW1hcnkgTWVhc3VyZSAgICB8ICAJRm9ybXVsYQkgICAgIHwgDQp8Oi0tLS0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tLS0tLXwNCnxDYXNlLUNvbnRyb2wJICAgIHxPZGRzIFJhdGlvIChPUikJICAgfCAgJE9SPWFkL2JjJCAgIHwNCnxDb2hvcnQJICAgICAgfCBSZWxhdGl2ZSBSaXNrIChSUil8CSRSUj1cZnJhY3thLyhhK2IpfXtjLyhjK2QpfSR8DQp8Q3Jvc3MtU2VjdGlvbmFsfAlQcmV2YWxlbmNlIFJhdGlvIHwkXGZyYWN7XHRleHR7UHJldmFsZW5jZX1fMX17XHRleHR7UHJldmFsZW5jZX1fMn0kfA0KIA0KXA0KDQpUaGUgbmV4dCBleGNlbGxlbnQgWW91VHViZSB2aWRlbyAoPGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9U2VjNGZld3lVaWc+KSBkaXNjdXNzZXMgdGhlIHR3byBtb3N0IGNvbW1vbmx5IHVzZWQgbWVhc3VyZXMgb2YgcmlzazogcmVsYXRpdmUgcmlzayAoUlIpIGFuZCBvZGRzIHJhdGlvIChPUikuDQoNClwNCjxjZW50ZXI+PGEgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1TZWM0ZmV3eVVpZyIgdGFyZ2V0PSJwb3B1cCIgDQogICAgICAgICAgICAgICAgICAgb25jbGljaz0id2luZG93Lm9wZW4oJ2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9U2VjNGZld3lVaWcnLA0KICAgICAgICAgICAgICAgICAgICAgICduYW1lJywnd2lkdGg9ODUwLGhlaWdodD01MDAnKSI+PGltZyBzcmMgPSAiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vTUFUMTIxVzUvaW1nL1ZpZGVvSWNvbi5wbmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMTIwIj48L2E+DQo8L2NlbnRlcj4NClwNCg0KDQojIENoaS1zcXVhcmUgVGVzdCBvZiBJbmRlcGVuZGVuY2UNCg0KTGV0ICRYJCBhbmQgJFkkIGJlIHR3byBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgd2l0aCAkayQgYW5kICRtJCBjYXRlZ29yaWVzIHJlc3BlY3RpdmVseS4gVGhlaXIgcmVsYXRpb25zaGlwIGJldHdlZW4gJFgkIGFuZCAkWSQgaXMgY2hhcmFjdGVyaXplZCBieSB0aGVpciBqb2ludCBkaXN0cmlidXRpb24gKHRhYmxlKS4gRm9yIHNpbXBsaWNpdHksIHdlIHVzZSB0aGUgZm9sbG93aW5nIHR3byBzcGVjaWFsIGNhdGVnb3JpY2FsIHRvIGV4cGxhaW4gdGhlIGlkZWFzIG9mIHN0YXRpc3RpY2FsIHRlc3Rpbmcgb2YgaW5kZXBlbmRlbmNlLg0KDQoNCiMjIEluZGVwZW5kZW5jZSBvZiBUd28gQ2F0ZWdvcmljYWwgVmFyaWFibGVzDQoNCldlIHVzZSB0aGUgZm9sbG93aW5nIGV4YW1wbGUgdG8gaWxsdXN0cmF0ZSAqKmluZGVwZW5kZW5jZSoqIGFuZCAqKmRlcGVuZGVuY2UqKiBiZXR3ZWVuIHR3byBjYXRlZ29yaWNhbCB2YXJpYWJsZXMuDQoNCjxmb250IGNvbG9yID0gImRhcmtyZWQiPiAqKkV4YW1wbGUgNSoqLjwvZm9udD4gKkpvaW50IHByb2JhYmlsaXRpZXMgYW5kIGNvbnRpbmdlbmN5IHRhYmxlcy4qIExldCAkWCA9JCBwb2xpdGljYWwgcHJlZmVyZW5jZSAoRGVtb2NyYXQgdnMgUmVwdWJsaWNhbikgYW5kICRZID0kZ2VuZGVyIChNYWxlIGFuZCBGZW1hbGUpLiBMZXQncyAqKmFzc3VtZSoqIHRoZWlyIGpvaW50IGRpc3RyaWJ1dGlvbiB0byBiZSBvZiB0aGUgZm9sbG93aW5nICpjb250aW5nZW5jeSB0YWJsZSouDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzY1JSd9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDIvdHdvV2F5Q29udGluZ2VuY3lUYWJsZS5wbmciKQ0KYGBgDQoNClRoZSBjZWxsIG51bWJlcnMgYXJlIGpvaW50IHByb2JhYmlsaXRpZXMuIEZvciBleGFtcGxlLCAkcF97MTJ9ID0gMC4yID0gMjBcJSQgc2F5cyAkMjBcJSQgb2YgdGhlICpzdHVkeSBwb3B1bGF0aW9uKiBhcmUgbWFsZSByZXB1YmxpY2Fucy4gVGhlIHJvdyBhbmQgY29sdW1uIHRvdGFscyByZXByZXNlbnQgdGhlIHBlcmNlbnRhZ2Ugb2YgbWFsZS9mZW1hbGUgYW5kIGRlbW9jcmF0cy9yZXB1YmxpY2FucyBpbiB0aGUgc3R1ZHkgcG9wdWxhdGlvbi4gQW55IG9ic2VydmVkIGRhdGEgdGFibGUgaXMgKipnb3Zlcm5lZCoqIGJ5IHRoZSBhYm92ZSBqb2ludCBkaXN0cmlidXRpb24gdGFibGUuDQoNCioqRGVmaW5pdGlvbioqIFR3byBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgYXJlICoqaW5kZXBlbmRlbnQqKiBpZiBhbmQgb25seSBpZiB0aGVpciBqb2ludCBwcm9iYWJpbGl0aWVzIGFyZSBlcXVhbCB0byB0aGUgcHJvZHVjdCBvZiB0aGVpciBjb3JyZXNwb25kaW5nIG1hcmdpbmFsIHByb2JhYmlsaXRpZXMuIA0KDQpXaXRoIHRoaXMgZGVmaW5pdGlvbiwgd2UgY2FuIHNlZSB0aGF0ICRYJCBhbmQgJFkkIHdpdGggam9pbnQgZGlzdHJpYnV0aW9uIHNwZWNpZmllZCBpbiB0aGUgYWJvdmUgdGFibGUgKGluIEV4YW1wbGUgNSkgYXIgTk9UIGluZGVwZW5kZW50IHNpbmNlICRwX3sxMX0gPTAuMyBcbmUgMC41XHRpbWVzIDAuNSA9IDAuMjUkLiANCg0KPGZvbnQgY29sb3IgPSAiZGFya3JlZCI+ICoqRXhhbXBsZSA2KiouPC9mb250PiBXZSBjb25zaWRlciB0d28gdmFyaWFibGVzICRYID0kIHByZWZlcmVuY2Ugb2YgaGFpciBjb2xvciAoQmxvbmRlIGFuZCBCcnVuZXR0ZSkgYW5kICRZID0kIGdlbmRlciAoTWFsZSBhbmQgRmVtYWxlKS4gQXNzdW1lIHRoZSBqb2ludCBkaXN0cmlidXRpb24gb2YgdGhlIHR3byB2YXJpYWJsZXMgaXMgZ2l2ZW4gYnkNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMzUlJ30NCmluY2x1ZGVfZ3JhcGhpY3MoIndlZWswMi9pbmRlcGVuZGVuY2VDb250aW5nZW5jeVRhYmxlLnBuZyIpDQpgYGANCg0KQmFzZWQgb24gdGhlIGRlZmluaXRpb24gb2YgaW5kZXBlbmRlbmNlLiBUaGUgcHJlZmVyZW5jZSBmb3IgaGFpciBjb2xvciBpcyBpbmRlcGVuZGVudCBvZiBnZW5kZXIuIFNpbmNlICoqYWxsKiogam9pbnQgcHJvYmFiaWxpdGllcyBhcmUgZXF1YWwgdG8gdGhlIHByb2R1Y3Qgb2YgdGhlaXIgY29ycmVzcG9uZGluZyBtYXJnaW5hbCBwcm9iYWJpbGl0aWVzLg0KDQokMC40NVx0aW1lcyAwLjQwID0gMC4xOCwgMC40NSBcdGltZXMgMC42MCA9IDAuMjcsIDAuNTUgXHRpbWVzIDAuNDAgPSAwLjIyJCwgYW5kICQwLjU1IFx0aW1lcyAwLjYwID0gMC4zMy4kDQoNCg0KIyMgRXhwZWN0ZWQgVGFibGUgVW5kZXIgSW5kZXBlbmRlbmNlIEFzc3VtcHRpb24gKCoqJEhfMCQqKikNCg0KV2UgY29uc3RydWN0IHRoZSAqKmV4cGVjdGVkIHRhYmxlKiogdW5kZXIgdGhlICoqbnVsbCBoeXBvdGhlc2lzIG9mIGluZGVwZW5kZW5jZSoqIGFuZCB0aGUgKipvYnNlcnZlZCBjb250aW5nZW5jeSB0YWJsZSoqLiBGb3IgZWFzZSBvZiBpbnRlcnByZXRhdGlvbiwgd2UgdXNlIGFuIGV4YW1wbGUgdG8gaWxsdXN0cmF0ZSB0aGUgc3RlcHMgZm9yIG9idGFpbmluZyB0aGUgZXhwZWN0ZWQgdGFibGUuDQoNCg0KPGZvbnQgY29sb3IgPSAiZGFya3JlZCI+ICoqRXhhbXBsZSA3KiouPC9mb250PiAgQ29uc2lkZXIgdGhlIHBvdGVudGlhbCBkZXBlbmRlbmNlIGJldHdlZW4gdGhlIGF0dGVuZGFuY2UgKGdvb2QgdnMgcG9vcikgYW5kIGNvdXJzZSBncmFkZSAocGFzcyB2cyBmYWlsKS4gV2UgdGFrZSA1MCBzdHVkZW50cyBmcm9tIGEgcG9wdWxhdGlvbiBhbmQgb2J0YWluIHRoZSBmb2xsb3dpbmcgb2JzZXJ2ZWQgdGFibGUuDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzM1JSd9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDIvYXR0ZW5kYW5jZVBhc3NGYWlsLnBuZyIpDQpgYGANCg0KKipRdWVzdGlvbioqOiBXaGV0aGVyIHRoZSBhdHRlbmRhbmNlIGlzIGluZGVwZW5kZW50IG9mIGNsYXNzIHBlcmZvcm1hbmNlPw0KJCQNCkhvOiBcIFwgYXR0ZW5kYW5jZSBcIGlzIFwgXCBpbmRlcGVuZGVudCBcIFwgb2YgXCB0aGUgXCBwZXJmb3JtYW5jZQ0KJCQNCiQkdmVyc3VzJCQNCg0KJCQNCkhhOiBcIFwgYXR0ZW5kYW5jZSBcIGlzICBcIFwgZGVwZW5kZW50IFwgb2YgXCB0aGUgXCBwZXJmb3JtYW5jZQ0KJCQNCg0KVG8gb2J0YWluIHRoZSBleHBlY3RlZCB0YWJsZSwgd2UgZm9sbG93IHRoZSBuZXh0IGZldyBzdGVwcy4NCg0KMS4gRXN0aW1hdGUgdGhlIG1hcmdpbmFsIHByb2JhYmlsaXRpZXMNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnNTAlJ30NCmluY2x1ZGVfZ3JhcGhpY3MoIndlZWswMi9tYXJnaW5hbFRhYmxlLnBuZyIpDQpgYGANCg0KXCBcIFwgXCBcIFwgXCBcIFwgXCBcIHdoZXJlIG1hcmdpbmFsIHByb2JhYmlsaXRpZXMgYXJlIGNhbGN1bGF0ZWQgYnkgUHIoR29vZCkgPSAyNy81MCA9IDAuNTQsIFByKFBvb3IpID0gMjMvNTAgPSAwLjQ2LCBQcihQYXNzKSA9IDMzLzUwID0gMC42NiwgUHIoRmFpbCkgPSAxNy81MCA9IDAuMzQuDQoNCg0KMi4gRXN0aW1hdGUgdGhlIGpvaW50IHByb2JhYmlsaXR5IHVuZGVyIHRoZSBudWxsIGh5cG90aGVzaXMgb2YgaW5kZXBlbmRlbmNlDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzUwJSd9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDIvam9pbnRQcm9iLnBuZyIpDQpgYGANCg0KXCBcIFwgXCBcIFwgXCBcIFwgXCBcIHdoZXJlIGpvaW50IHByb2JhYmlsaXRpZXMgdW5kZXIgdGhlIGluZGVwZW5kZW5jZSBhc3N1bXB0aW9uICgkSF8wJCkgYXJlIGNhbGN1bGF0ZWQgYnkgdGFraW5nIHRoZSBwcm9kdWN0IG9mIHRoZSBjb3JyZXNwb25kaW5nIG1hcmdpbmFsIHByb2JhYmlsaXRpZXMuIEZvciBleGFtcGxlLCA8Zm9udCBjb2xvciA9ICJyZWQiPiAwLjU0ICRcdGltZXMkIDAuNjYgPSA8L2ZvbnQ+IDxmb250IGNvbG9yID0gImJsdWUiPjAuMzU2NDwvZm9udD4uDQoNCjMuIENhbGN1bGF0ZSBFeHBlY3RlZCBUYWJsZSANCg0KXCBcIFwgXCBcIFwgXCBcIFwgXCBUaGUgZXhwZWN0ZWQgZnJlcXVlbmNpZXMgYXJlIGNhbGN1bGF0ZWQgaW4gdGhlIGZvbGxvd2luZyB0YWJsZSAod2l0aCBkZXRhaWxlZCBzdGVwcykuDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzY1JSd9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDIvZXhwZWN0ZWRUYWJsZS5wbmciKQ0KYGBgDQoNClwNCg0KKipSZW1hcmtzKioNCg0KKiBGb3IgY2F0ZWdvcmljYWwgdmFyaWFibGVzIHdpdGggKiptb3JlIHRoYW4gdHdvIGNhdGVnb3JpZXMqKiwgdGhlIGV4cGVjdGVkIHRhYmxlIGNhbiBiZSBmb3VuZCB1c2luZyAqKiB0aGUgc2FtZSAzIHN0ZXBzKiogYXMgdGhvc2UgdXNlZCBpbiB0aGUgYWJvdmUgZXhhbXBsZS4gDQoNCiogVGhlIGdlbmVyaWMgZm9ybXVsYSBmb3IgY2FsY3VsYXRlIGFueSBleHBlY3RlZCBmcmVxdWVuY3kgaXMgZ2l2ZW4gYnkNCg0KPGZvbnQgY29sb3IgPSAicmVkIiBzaXplID0gND4NCiQkDQpcdGV4dHtFeHBlY3RlZCBGcmVxdWVuY3l9ID0gXGZyYWN7XHRleHR7Y29sdW1uIHRvdGFsfSBcdGltZXMgXHRleHR7cm93IHRvdGFsfX17XHRleHR7Z3JhbmQgdG90YWx9fQ0KJCQNCjwvZm9udD4NCg0KKiBXZSB1c2UgdGhlIGFib3ZlIGZvcm11bGEgb24gdGhlIHByZXZpb3VzIGV4YW1wbGUuIEZpbmQgdGhlIGV4cGVjdGVkIGZyZXF1ZW5jeSBpbiB0aGUgZmlyc3QgY29sdW1uIChgUGFzc2ApIGFuZCBzZWNvbmQgcm93IChgUG9vcmApLiBUaGUgc2FtcGxlIHNpemUgaXMgNTAgKHRoZSBncmFuZCB0b3RhbCkuDQoNCiQkDQoxNS4xIFxhcHByb3ggXGZyYWN7MzNcdGltZXMgMjN9ezUwfS4NCiQkDQoNClRoZSBmb2xsb3dpbmcgWW91VHViZSB2aWRlbyAoPGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9UzlYVEFYbl9xbTQ+KSBnaXZlcyBhbm90aGVyIGV4YW1wbGUgb24gaG93IHRvIGNhbGN1bGF0ZSB0aGUgZXhwZWN0ZWQgZnJlcXVlbmN5IG1hbnVhbGx5Lg0KDQoNClwNCjxjZW50ZXI+PGEgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1TOVhUQVhuX3FtNCIgdGFyZ2V0PSJwb3B1cCIgDQogICAgICAgICAgICAgICAgICAgb25jbGljaz0id2luZG93Lm9wZW4oJ2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9UzlYVEFYbl9xbTQnLA0KICAgICAgICAgICAgICAgICAgICAgICduYW1lJywnd2lkdGg9ODUwLGhlaWdodD01MDAnKSI+PGltZyBzcmMgPSAiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vTUFUMTIxVzUvaW1nL1ZpZGVvSWNvbi5wbmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMTIwIj48L2E+DQo8L2NlbnRlcj4NClwNCg0KDQpcDQoNCiMjIEZvcm11bGF0aW9uIG9mIENoaS1zcXVhcmVzIFRlc3Qgb2YgSW5kZXBlbmRlbmNlDQoNClRoZSB0ZXN0IHN0YXRpc3RpYyB1c2VkIHRvIHRlc3QgdGhlIGluZGVwZW5kZW5jZSBvZiB0d28gY2F0ZWdvcmljYWwgdmFyaWFibGVzIGlzIHRoZSBzYW1lIGFzIHRoYXQgdXNlZCBpbiB0aGUgZ29vZG5lc3Mtb2YtZml0IHRlc3QuIFRoYXQgaXMgdGhlIHN0YW5kYXJkaXplZCAiZGlzdGFuY2UiIGJldHdlZW4gdGhlIG9ic2VydmVkIGFuZCB0aGUgZXhwZWN0ZWQgdGFibGUgKHVuZGVyICRIXzAkKS4gDQoNCjxmb250IGNvbG9yID0gInJlZCIgc2l6ZSA9IDQ+Kipjb2xvcntyZWR9QXNzdW1lIHRoYXQgdGhlIHR3byBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgaGF2ZSAkayQgYW5kICRtJCBjYXRlZ29yaWVzIHJlc3BlY3RpdmVseSwgdGhlbiB0aGUgcmVzdWx0aW5nIHRlc3Qgc3RhdGlzdGljIGhhcyBhIGNoaS1zcXVhcmUgZGlzdHJpYnV0aW9uIHdpdGggJChrLTEpXHRpbWVzKG0tMSkkIGRlZ3JlZXMgb2YgZnJlZWRvbS4qKjwvZm9udD4NCg0KDQoNCjxmb250IGNvbG9yID0gImRhcmtyZWQiPiAqKkV4YW1wbGUgOCoqLjwvZm9udD4gW0NvbnRpbnVhdGlvbiBvZiAqKkV4YW1wbGUgNyoqXS4gVGVzdCB3aGV0aGVyICoqYXR0ZW5kYW5jZSoqIGFuZCAqKmNsYXNzIHBlcmZvcm1hbmNlKiouDQoNCioqU29sdXRpb24qKjogV2UgaGF2ZSBmb3VuZCB0aGUgZXhwZWN0ZWQgdGFibGUgdW5kZXIgJEhfMCQgaW4gKipFeGFtcGxlIDcqKiwgd2UgcHV0IHRoZSBvYnNlcnZlZCBhbmQgZXhwZWN0ZWQgdGFibGVzIGluIHRoZSBmb2xsb3dpbmcuDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzcwJSd9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDIvZXhhbXBsZTA4RXhwT2JzLnBuZyIpDQpgYGANCg0KVGhlIHRlc3Qgc3RhdGlzdGljIGlzIGdpdmVuIGJ5DQoNCiQkDQpUUyA9IFxmcmFjeygyNS0xOC44MileMn17MTcuODJ9ICsgXGZyYWN7KDItOS4xOCleMn17OS4xOH0gKyBcZnJhY3soOC0xNS4xOCleMn17MTUuMTh9ICsgXGZyYWN7KDE1LTcuODIpXjJ9ezcuODJ9ID0gMTcuNzUNCiQkDQoNClRoZSB0ZXN0IHN0YXRpc3RpYyBoYXMgYSBjaGktc3F1YXJlIGRpc3RyaWJ1dGlvbiB3aXRoICQoMi0xKVx0aW1lcyAoMi0xKSA9IDEkIGRlZ3JlZXMgb2YgZnJlZWRvbS4gVGhlIGNyaXRpY2FsIHZhbHVlIGF0IHRoZSBzaWduaWZpY2FuY2UgbGV2ZWwgb2YgMC4wNSBpcyBmb3VuZCBpbiB0aGUgZm9sbG93aW5nIGZpZ3VyZS4NCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnODUlJ30NCmluY2x1ZGVfZ3JhcGhpY3MoIndlZWswMi9leGFtcGxlMDhDaGlzcUNWLnBuZyIpDQpgYGANCg0KU2luY2UgdGhlIHRlc3Qgc3RhdGlzdGljIGlzIGluc2lkZSB0aGUgcmVqZWN0aW9uIHJlZ2lvbiwgd2UgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCBhdHRlbmRhbmNlIGFuZCBjbGFzcyBwZXJmb3JtYW5jZSBhcmUgaW5kZXBlbmRlbnQuDQoNCg0KDQo8Zm9udCBjb2xvciA9ICJkYXJrcmVkIj4gKipFeGFtcGxlIDkqKi48L2ZvbnQ+IERvIHNvbWUgY29sbGVnZSBtYWpvcnMgcmVxdWlyZSBtb3JlIHN0dWR5aW5nIHRoYW4gb3RoZXJzPyBUaGUgTmF0aW9uYWwgU3VydmV5IG9mIFN0dWRlbnQgRW5nYWdlbWVudCBhc2tlZCBhIG51bWJlciBvZiBjb2xsZWdlIGZyZXNobWVuIHdoYXQgdGhlaXIgbWFqb3Igd2FzIGFuZCBob3cgbWFueSBob3VycyBwZXIgd2VlayB0aGV5IHNwZW50IHN0dWR5aW5nLCBvbiBhdmVyYWdlLiBBIHNhbXBsZSBvZiAxMDAwIG9mIHRoZXNlIHN0dWRlbnRzIHdhcyBjaG9zZW4sIGFuZCB0aGUgbnVtYmVycyBvZiBzdHVkZW50cyBpbiBlYWNoIGNhdGVnb3J5IGFyZSB0YWJ1bGF0ZWQgaW4gdGhlIGZvbGxvd2luZyB0d28td2F5IGNvbnRpbmdlbmN5IHRhYmxlLg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aCA9ICc2MCUnfQ0KaW5jbHVkZV9ncmFwaGljcygid2VlazAyL2V4YW1wbGUwOURhdGEucG5nIikNCmBgYA0KDQoqKlNvbHV0aW9uKio6IFRoZSBudWxsIGFuZCBhbHRlcm5hdGl2ZSBoeXBvdGhlc2VzIGFyZSBnaXZlbiBieQ0KDQpgYGB7fQ0KICAgICAgIEhvOiBzdHVkeWluZyB0aW1lIGlzIElOREVQRU5ERU5UIG9uIG1ham9ycw0KICAgICAgICAgICAgICAgICAgIHZlcnN1cw0KICAgICAgIEhhOiBzdHVkeWluZyB0aW1lIGlzIERFUEVOREVOVCBvbiBtYWpvcnMuDQpgYGANCg0KDQpVbmRlciB0aGUgbnVsbCBoeXBvdGhlc2lzLCB3ZSBvYnRhaW5lZCB0aGUgZXhwZWN0ZWQgdGFibGUgdXNpbmcgdGhlIHNhbWUgc3RlcHMgaW4gRXhhbXBsZSA3IGluIHRoZSBmb2xsb3dpbmcuDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzU1JSd9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDIvZXhhbXBsZTA5RXhwVGFibGUucG5nIikNCmBgYA0KDQpUaGUgdGVzdCBzdGF0aXN0aWMgaXMgZ2l2ZW4gYnkNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnNjAlJ30NCmluY2x1ZGVfZ3JhcGhpY3MoIndlZWswMi9leGFtcGxlMDlUUy5wbmciKQ0KYGBgDQoNClRoZSBjcml0aWNhbCB2YWx1ZSBhbmQgcmVqZWN0aW9uIHJlZ2lvbiBiYXNlZCBvbiBzaWduaWZpY2FuY2UgbGV2ZWwgMC4wNSBpcyBnaXZlbiBieQ0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aCA9ICc4MCUnfQ0KaW5jbHVkZV9ncmFwaGljcygid2VlazAyL2V4YW1wbGUwOUNWLnBuZyIpDQpgYGANCg0KKipDb25jbHVzaW9uKio6IFNpbmNlIHRoZSB0ZXN0IHN0YXRpc3RpYyBpcyBpbnNpZGUgdGhlIHJlamVjdGlvbiByZWdpb24sIHdlIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIGFuZCBjb25jbHVkZSB0aGF0IHRoZSBzdHVkeWluZyB0aW1lIGlzIGRlcGVuZGVudCBvbiB0aGUgbWFqb3JzLg0KDQoNClRvIGNvbmNsdWRlIHRoaXMgc2VjdGlvbiwgd2F0Y2ggdGhlIGZvbGxvd2luZyBZb3VUdWJlIHZpZGVvICg8aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj15NW54aUw2Y2l2VT4pIGZvciBhbm90aGVyIG1hbnVhbGx5IHdvcmtlZC1vdXQgZXhhbXBsZSBvZiBjaGlzcXVhcmVkIHRlc3Qgb2YgaW5kZXBlbmRlbmNlLg0KDQpcDQoNCjxjZW50ZXI+PGEgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj15NW54aUw2Y2l2VSIgdGFyZ2V0PSJwb3B1cCIgDQogICAgICAgICAgICAgICAgICAgb25jbGljaz0id2luZG93Lm9wZW4oJ2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9eTVueGlMNmNpdlUnLA0KICAgICAgICAgICAgICAgICAgICAgICduYW1lJywnd2lkdGg9ODUwLGhlaWdodD01MDAnKSI+PGltZyBzcmMgPSAiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vTUFUMTIxVzUvaW1nL1ZpZGVvSWNvbi5wbmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMTIwIj48L2E+DQo8L2NlbnRlcj4NCg0KXA0KDQoNCiMgUHJhY3RpY2UgRXhlcmNpc2VzDQoNCg0KMS4gKipQb2xpdGljYWwgQWZmaWxpYXRpb24gYW5kIE9waW5pb24qKg0KDQpUaGUgZm9sbG93aW5nIHRhYmxlIGJhc2VkIG9uIHRoZSBzYW1wbGUgd2lsbCBiZSB1c2VkIHRvIGV4cGxvcmUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIFBhcnR5IEFmZmlsaWF0aW9uIGFuZCBPcGluaW9uIG9uIFRheCBSZWZvcm0uDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzM1JSd9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDIvcHJhY3RpY2VFeDAyRGF0YS5wbmciKQ0KYGBgDQoNCkZpbmQgdGhlIGV4cGVjdGVkIGNvdW50cyBmb3IgYWxsIG9mIHRoZSBjZWxscy4NCg0KDQoyLiAqKlRpcmUgUXVhbGl0eSoqDQoNClRoZSBvcGVyYXRpb25zIG1hbmFnZXIgb2YgYSBjb21wYW55IHRoYXQgbWFudWZhY3R1cmVzIHRpcmVzIHdhbnRzIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZXJlIGFyZSBhbnkgZGlmZmVyZW5jZXMgaW4gdGhlIHF1YWxpdHkgb2Ygd29yayBhbW9uZyB0aGUgdGhyZWUgZGFpbHkgc2hpZnRzLiBTaGUgcmFuZG9tbHkgc2VsZWN0cyA0OTYgdGlyZXMgYW5kIGNhcmVmdWxseSBpbnNwZWN0cyB0aGVtLiBFYWNoIHRpcmUgaXMgZWl0aGVyIGNsYXNzaWZpZWQgYXMgcGVyZmVjdCwgc2F0aXNmYWN0b3J5LCBvciBkZWZlY3RpdmUsIGFuZCB0aGUgc2hpZnQgdGhhdCBwcm9kdWNlZCBpdCBpcyBhbHNvIHJlY29yZGVkLiBUaGUgdHdvIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyBvZiBpbnRlcmVzdCBhcmUgdGhlIHNoaWZ0IGFuZCBjb25kaXRpb24gb2YgdGhlIHRpcmUgcHJvZHVjZWQuIFRoZSBkYXRhIGNhbiBiZSBzdW1tYXJpemVkIGJ5IHRoZSBhY2NvbXBhbnlpbmcgdHdvLXdheSB0YWJsZS4gRG9lcyB0aGUgZGF0YSBwcm92aWRlIHN1ZmZpY2llbnQgZXZpZGVuY2UgYXQgdGhlIDUlIHNpZ25pZmljYW5jZSBsZXZlbCB0byBpbmZlciB0aGF0IHRoZXJlIGFyZSBkaWZmZXJlbmNlcyBpbiBxdWFsaXR5IGFtb25nIHRoZSB0aHJlZSBzaGlmdHM/DQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzM1JSd9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDIvcHJhY3RpY2VFeDAzRGF0YS5wbmciKQ0KYGBgDQoNCjMuICoqQ29uZGltZW50IHByZWZlcmVuY2UgYW5kIGdlbmRlcioqDQoNCkEgZm9vZCBzZXJ2aWNlcyBtYW5hZ2VyIGZvciBhIGJhc2ViYWxsIHBhcmsgd2FudHMgdG8ga25vdyBpZiB0aGVyZSBpcyBhIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGdlbmRlciAobWFsZSBvciBmZW1hbGUpIGFuZCB0aGUgcHJlZmVycmVkIGNvbmRpbWVudCBvbiBhIGhvdCBkb2cuIFRoZSBmb2xsb3dpbmcgdGFibGUgc3VtbWFyaXplcyB0aGUgcmVzdWx0cy4gVGVzdCB0aGUgaHlwb3RoZXNpcyB3aXRoIGEgc2lnbmlmaWNhbmNlIGxldmVsIG9mIDEwJS4NCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMzUlJ30NCmluY2x1ZGVfZ3JhcGhpY3MoIndlZWswMi9wcmFjdGljZUV4MDREYXRhLnBuZyIpDQpgYGANCg0KDQoNCg0KDQoNCg0K