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.
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:
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.
Measures of
Association
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:
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.
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.
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.
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
\[
RR = \frac{AR_{exp}}{AR_{unexp}} = \frac{a/(a+b)}{c/(c+d)}
\]
\[
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:
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).
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.
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.\)
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.
- 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.
- 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.
- 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.
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.
Practice Exercises
- 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.
- 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")

- 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