Introduction
The data from the CRD (Completely Randomized Design) were analyzed
using a one-way ANOVA procedure. Since the treatment is a factor with
different groups (representing different doses), it influences the
response variable. One-way ANOVA, also called one-factor ANOVA, focuses
on testing whether there is a treatment effect. In statistical terms,
this is equivalent to testing the null hypothesis:
\[
H_0: \mu_1 = \mu_2 = \cdots = \mu_t.
\]
Under this null hypothesis, the variance between treatments and the
variance within treatments are approximately the same. Thus, we assess
the equality of means across treatments by analyzing these variances, as
summarized in the classical ANOVA table.
The key information \(MS_B\) and
\(MS_W\) used to construct the test
statistic are based on the \(SS_B\) and
\(SS_W\) extracted from the total sum
of squares.
\[
SS_T = SS_B + SS_W.
\]
Two fundamental assumptions for the one-way ANOVA analysis are
- Populations are normally distributed
- Variances of treatment groups are equal
Under the null hypothesis \(H_0: \mu_1 =
\mu_2 = \cdots = \mu_t\)
\[
F = \frac{SS_B/t-1}{SS_W/n-t} \rightarrow F_{t-1, \ n-t}
\]
Where \(t\) is the number of
treatment groups and \(n\) is the
sample size.
The RBD designs add one additional factor variable. We are interested
in assessing the effects of both the additional factor and the treatment
effect. If the RBD has replicates, we also assess the potential
interaction effect. Because of the additional factor, the decomposition
of the total sum of squares becomes more complex, although the logic and
mathematical derivation are the same as the one-way ANOVA.
Before discussing the construction of ANOVA for replicated RBD data,
we first look at an example to see what practical questions we can
answer based on the data collected from a replicated RBD.
Plant Grouth: a botanist wants to know whether or
not plant growth is influenced by sunlight
exposure and watering frequency. She plants 40
seeds and lets them grow for two months under different conditions for
sunlight exposure and watering frequency. After two months, she records
the height of each plant. The results are shown below:

Clearly, this is a balanced RBD with replications. The data structure
required for analysis with software programs will be discussed
later.
Two-way ANOVA
Two-way ANOVA is used to analyze the effects of two independent
categorical variables (factors) on a continuous dependent variable while
also assessing the interaction between these factors. Unlike one-way
ANOVA, which examines only one factor, two-way ANOVA allows researchers
to determine whether the two factors independently influence the outcome
and whether their combined effect (interaction) is significant.
Two-Way ANOVA Table
Structure
Because two factors are involved in the analysis, the mathematical
decomposition of the total square into more components for testing the
above three hypotheses is much more complex than the one-way ANOVA;
algebra is not difficult. We will not derive the
components in the ANOVA table based on the raw data values. Instead, we
focus on the structure of the ANOVA table and how to use the key
statistics in the table to test the above hypotheses. We use software
programs to generate the ANOVA table. We first introduce some notations
to help understand the ANOVA table.
- Number of categories in factor A: \(a\)
- Number of categories in factor B: \(b\)
- Total sample size: \(N\)
- Total Sum of Squares: \(SST\)
- Sum of Squares for Factor A: \(SSA\) (Variation due to factor
A).
- Sum of Squares for Factor B: \(SSB\) (Variation due to factor
B).
- Sum of Squares for Interaction between Factor A and Factor
B: \(SSAB\) (Variation due to
the interaction between Factor A and Factor
B).
- Residual Sum of Squares: \(SSE\) (Unexplained variation - error).
Mathematically
\[
SST = SSA + SSB + SSAB + SSE
\]
Each Sum of Squares has its own degrees of
freedom. Next, we list the degrees of freedom os each of the
sum of squares:
- DF.A = \(a - 1\)
- DF.B = \(b - 1\)
- DF.AB = \((a-b)\times (b-1)\)
(interaction term)
- DF.E = \(N - ab\)
- DF.T = \(N - 1\)
Note that \(N -1 = (a-1) + (b-1) +
(a-1)(b-1) + N - ab\).
With the above notations, we introduce the two-way ANOVA table.

The first three rows of the table contain information related to
testing the above three hypotheses. In one-way ANOVA, we used the
F-distribution to find the p-value for a statistical decision under some
assumptions as mentioned in the first section. We also need to make some
assumptions in order to specify the distributions of F statistics. Next,
we discuss the assumptions of two-way ANOVA and testing the
hypotheses.
Assumptions of
Two-Way ANOVA
As we know, in the one-way ANOVA table, the F value follows an F
distribution under some assumptions. In the two-way ANOVA, we also need
the following assumptions to make inferences about the three F
statistics:
Normality: The dependent variable should be
normally distributed within each combination of factor
levels.
Homogeneity of Variance (Homoscedasticity): The
variances across groups defined by each combination of factor
levels should be equal. In practice, we usually perform a
formal test to check this assumption.
Independence of Observations: Data points should
be independent, meaning the measurement of one subject does not
influence another. This assumption is hard to test for
independence.. We usually justify the data collection
process.
Random Sampling: Data should be collected using
a random sampling method. This is justified by the data collection
process.
Violations of these assumptions may require transformations or
non-parametric alternatives like the Kruskal-Wallis test.
Assume that all the above assumptions are met. Next, we discuss the
distribution of the test statistics for testing the three
hypotheses.
- Effect of Factor A: under the following null
hypothesis,
\[
H_0: \text{All levels of Factor A have the same mean effect.}
\] The test statistic
\[
F_A = \frac{MS_A}{SS_E} \rightarrow F_{a-1,\ n-ab }.
\]
The p-value can be found from \(F_{a-1,\
n-ab }\).
- Effect of Factor B: under the following null
hypothesis,
\[
H_0: \text{All levels of Factor B have the same mean effect.}
\] The test statistic
\[
F_B = \frac{MS_B}{MS_E} \rightarrow F_{b-1, \ n - ab}
\]
The p-value can be found from \(F_{b-1,\
n-ab }\).
- Interactive Effect between Factor A and
Factor B: under the following null hypothesis,
\[
H_0: \text{There is no interaction between Factor A and Factor B.}
\] The test statistic
\[
F_{AB} = \frac{MS_{AB}}{MS_E} \rightarrow F_{(a-b)(b-1), n -ab}
\] The p-value can be found from \(F_{(a-1)(b-1),\ n-ab }\).
Remarks: understanding
the structure of the ANOVA table is crucial.
If the first two columns are given, you are expected to derive
the rest of the columns, including the p-values in the last column,
using the R command pf(F, df1, df2, lower.tail = FALSE)
(F
table is not recommended).
The interaction effect is not available if working with RBD data
with no replicates.
Performing ANOVA
Using R
The R function aov()
will be used to perform an ANOVA
test. If the given data table is in wide format, we need to reformat it
into a long table. This involves placing all response values in a single
column and using two separate columns to label each response value with
its associated factors.
The R function rep()
is useful for generating patterned
data. Its syntax is rep(data.value, times = n)
, which means
it replicates data.value
n times.
The data.value
argument can be either a single
value or a vector of values. Below are some
examples demonstrating how to use rep()
to create patterned
data.
rep(5, times = 3) # replicate 5 three times
| [1] 5 5 5
rep("a", 9) # replicate lowercase letter "a" 9 times
| [1] "a" "a" "a" "a" "a" "a" "a" "a" "a"
rep(c(1,3,5), 3) # replicate vector (1,3,5) three times
| [1] 1 3 5 1 3 5 1 3 5
rep(rep(c("A", "B"), 2), 3) # nested replicate rep(c("A", "B")) three times
| [1] "A" "B" "A" "B" "A" "B" "A" "B" "A" "B" "A" "B"
Next, we work on the wide table in the example given in Section
1.
## first, define 4 column vectors
None = c(4.8, 4.4, 3.2, 3.9, 4.4, 4.4, 4.2, 3.8, 3.7, 3.9)
Low = c(5.0, 5.2, 5.6, 4.3, 4.8, 4.9, 5.3, 5.7, 5.4, 4.8)
Medium = c(6.4, 6.2, 4.7, 5.5, 5.8, 5.8, 6.2, 6.3, 6.5, 5.5)
High = c(6.3, 6.4, 5.6, 4.8, 5.8, 6.0, 4.9, 4.6, 5.6, 5.5)
## Place the above values in a single column
growth <- c(None, Low, Medium, High)
## define sunlight labels
sunlight <- c(rep("None", length(None)), rep("Low", length(Low)),
rep("Medium", length(Medium)), rep("High", length(High)))
## Watering patterns
## The inner rep() returns the pattern of first column
## The outer rep() replicate the rest of the columns
watering <-rep(c(rep("Daily", 5), rep("Weekly", 5)),4)
## Store variables in a data frame
growthData <- data.frame(growth = growth, sunlight = sunlight, watering = watering)
## check the data frame
#growthData
We now perform the ANOVA using the data frame.
# We fit an ANOVA with an interactive effect
growth.aov <- aov(growth ~ sunlight*watering, data = growthData)
summary(growth.aov)
| Df Sum Sq Mean Sq F value Pr(>F)
| sunlight 3 18.765 6.255 23.049 3.9e-08 ***
| watering 1 0.000 0.000 0.001 0.976
| sunlight:watering 3 1.011 0.337 1.242 0.311
| Residuals 32 8.684 0.271
| ---
| Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Formal Summary of
ANOVA: Two formats of write-up are recommended.
Format 1
The above two-way ANOVA revealed a significant main effect of
sunlight (\(F(3, 32) =
23.049\)), \(p \approx 0\)),
indicating that the plant heights (growth) were significantly higher
when exposed to more sunlight. Neither the main effect of
watering frequency (\(F(1,
32) = 0.01, p = 0.976\)) nor the sunlight and
watering frequency interaction (\(F(1,32) =1.242, p = 0.311\)) was
statistically significant.
Format 2
A two-way ANOVA was conducted, yielding the following findings:
Watering Frequency: No significant effect on
plant growth (F(1, 32) = 0.01, p = 0.976).
Sunlight Exposure: Significant effect on plant
growth (F(3, 32) = 23.049, p < 0.001). We will conduct a
post-hoc comparison (e.g., Tukey’s HSD) would determine which sunlight
levels differ.
Interaction (Watering × Sunlight): No
significant interaction (F(3, 32) = 1.242, p = 0.311),
indicating that the effect of sunlight does not depend on watering
frequency.
Post-hoc Test
The interpretation of post hoc tests becomes more complex when two or
more factors are included in an ANOVA, especially when interaction
effects are present. In such cases, it is often useful to create line
plots showing the means of the primary factor at each level of the
secondary factor. As an illustrative example, we will use the data frame
created in the previous section to calculate the means of groups defined
by the combination of watering
and sunlight
.
The R function aggregate()
can be used to compute these
group means. In general, aggregate()
is used to summarize
the values within groups using descriptive statistics such as the mean,
variance, maximum, minimum, etc. The syntax of aggregate() is shown
below.

## We use the data frame "growthData" created in the previous section
grp.means <- aggregate(growth ~ watering + sunlight, data = growthData, mean)
## checking the resulting table
#grp.means
## split into daily means and weekly means
## using which() to find the rows in which watering is "Daily" and "Weekly" respectively
daily.id <- which(grp.means$watering == "Daily")
weekly.id <- which(grp.means$watering == "Weekly")
## subset of means of sunlight at its individual levels
daily.avg <- grp.means[daily.id, 3]
weekly.avg <- grp.means[weekly.id, 3]
### draw line plots of
We have not formally introduced the R base plot function with
details. Next, we briefly introduce the base R function
plot()
:
plot(x, y, type = "b", xaxt = "n", xlab = "Category", ylab = "Value", main = "Custom X-Axis Labels")
where * x
horizontal x-axis * y
vertical
y-axis * type = "b"
draws both points and lines. *
xlab=
the label of x-axis * ylab =
the label
of y-axis * main=
the title of the plot *
xaxt = "n"
suppresses the default x-axis. *
axis(side = 1, ...)
adds a customized horizontal axis.
The code below draws a line plot of the mean sunlight levels for each
watering level.
# Custom tick mark positions and labels
x.ticks <- c(1,2,3,4) # tick marks / location of tick labels
x.labels <- c("None", "Low", "Medium", "High")
# Create the plot without x-axis (xaxt = "n")
plot(c(1,2,3,4), weekly.avg,
type = "b",
xaxt = "n",
xlab = "Sunlight",
ylab = "Length (growth)",
col = "red", # color of the line graph
lty = 1, # line type. 1 = solid line
main = "Mean Length across Sunlight Level")
## Add a line plot of weekly watering
lines(c(1,2,3,4), daily.avg,
col = "blue",
lty = 1)
# Add custom x-axis
axis(side = 1, at = x.ticks, labels = x.labels)
## Add a legend to specify the watering level
legend("bottomleft", # location for the legend
c("Weekly", "Daily"), # names of line plot, Caution: keep the order of the names!
lty = c(1,1),
col = c("red", "blue"),
bty = "n" # don't include the box of the legend
)

If the two line graphs are
parallel (i.e., there is NO intersection), the factors
watering
and sunlight
do not have an
interactive effect!. Otherwise, the two factors do have an interactive
effect!
Graphical Interpretations:
- Main Effect interpret
sunlight
patterns
(trends) at each watering
level:
- When watered weekly, the plant grew best with medium
sunlight and poorest with the high
sunlight.
- The same growth patterns were observed when watering daily.
- Interactive effect cross comparison between
watering frequencies
- The plants grew better with
Low
and Medium
sunlight when watered weekly
- However, the plant grew better with
None
and
High
sunlight when watered daily
The following subsections provide detailed numerical comparisons with
differences and associated confidence intervals.
ANOVA with No
Interactive Effect
If there is no interaction effect, we interpret the main effects of
the factor variables independently. In the plant growth
analysis, the key factor is sunlight, and the secondary
factor is watering. We compare the main effects of the
key and secondary factors separately. For example:
- Sunlight (Key Factor): Compare mean outcomes across
sunlight levels, ignoring watering. “High
sunlight yields higher growth than low sunlight, averaged over all
watering levels.

The above line plot shows that the growth rate generally
decreases as sunlight increases, except at the medium sunlight level, at
which the rate peaks.
- Watering (Secondary Factor): Compare means across
watering levels, ignoring sunlight. Frequent
watering increases growth, but this effect is smaller than sunlight’s
effect.

The plot above shows that the plant grew better when watered
daily.
ANOVA with
Interactive Effect
After finishing the ANOVA test, we report multiple comparisons
between groups associated with the significant factors.
If a two-way ANOVA reveals a significant interaction effect, it means
the impact of one factor (e.g., Sunlight Exposure) depends on the level
of the other factor (e.g., Watering Frequency). To interpret this
interaction properly, we must:
Compare groups within combinations (e.g.,
“Daily + Low Sunlight
”
vs. “Weekly + Medium Sunlight
”).
Control for inflated Type I error rates (false positives) due to
multiple comparisons by using simultaneous
methods such as Tukey’s HSD to adjust p-values to
maintain the family-wise error rate (FWER) at a set level (e.g.,
5%).
In the above plant growth dataset, the ANOVA test
suggests insignificance of the interactive effect between
sunlight and watering. The only
significant factor is sunlight. For illustration, we
perform simultaneous comparisons for individual factors
and their interactions using Tukey’s HSD.
The general idea in interpreting multiple comparisons is to focus on
the key factor (such as sunlight) and break down the secondary factor
(watering)
anova.interact <- aov(growth ~ sunlight*watering, data = growthData)
TukeyHSD(anova.interact) # Compare sunlight levels within Daily watering
| Tukey multiple comparisons of means
| 95% family-wise confidence level
|
| Fit: aov(formula = growth ~ sunlight * watering, data = growthData)
|
| $sunlight
| diff lwr upr p adj
| Low-High -0.45 -1.0811999 0.1811999 0.2353814
| Medium-High 0.34 -0.2911999 0.9711999 0.4730539
| None-High -1.48 -2.1111999 -0.8488001 0.0000023
| Medium-Low 0.79 0.1588001 1.4211999 0.0095962
| None-Low -1.03 -1.6611999 -0.3988001 0.0005862
| None-Medium -1.82 -2.4511999 -1.1888001 0.0000000
|
| $watering
| diff lwr upr p adj
| Weekly-Daily -0.005 -0.3405535 0.3305535 0.975975
|
| $`sunlight:watering`
| diff lwr upr p adj
| Low:Daily-High:Daily -0.80 -1.86724928 0.26724928 0.2626201
| Medium:Daily-High:Daily -0.06 -1.12724928 1.00724928 0.9999996
| None:Daily-High:Daily -1.64 -2.70724928 -0.57275072 0.0005069
| High:Weekly-High:Daily -0.46 -1.52724928 0.60724928 0.8523023
| Low:Weekly-High:Daily -0.56 -1.62724928 0.50724928 0.6873529
| Medium:Weekly-High:Daily 0.28 -0.78724928 1.34724928 0.9884511
| None:Weekly-High:Daily -1.78 -2.84724928 -0.71275072 0.0001516
| Medium:Daily-Low:Daily 0.74 -0.32724928 1.80724928 0.3529276
| None:Daily-Low:Daily -0.84 -1.90724928 0.22724928 0.2118374
| High:Weekly-Low:Daily 0.34 -0.72724928 1.40724928 0.9657630
| Low:Weekly-Low:Daily 0.24 -0.82724928 1.30724928 0.9954055
| Medium:Weekly-Low:Daily 1.08 0.01275072 2.14724928 0.0456827
| None:Weekly-Low:Daily -0.98 -2.04724928 0.08724928 0.0905656
| None:Daily-Medium:Daily -1.58 -2.64724928 -0.51275072 0.0008466
| High:Weekly-Medium:Daily -0.40 -1.46724928 0.66724928 0.9217373
| Low:Weekly-Medium:Daily -0.50 -1.56724928 0.56724928 0.7925032
| Medium:Weekly-Medium:Daily 0.34 -0.72724928 1.40724928 0.9657630
| None:Weekly-Medium:Daily -1.72 -2.78724928 -0.65275072 0.0002546
| High:Weekly-None:Daily 1.18 0.11275072 2.24724928 0.0219109
| Low:Weekly-None:Daily 1.08 0.01275072 2.14724928 0.0456827
| Medium:Weekly-None:Daily 1.92 0.85275072 2.98724928 0.0000450
| None:Weekly-None:Daily -0.14 -1.20724928 0.92724928 0.9998578
| Low:Weekly-High:Weekly -0.10 -1.16724928 0.96724928 0.9999854
| Medium:Weekly-High:Weekly 0.74 -0.32724928 1.80724928 0.3529276
| None:Weekly-High:Weekly -1.32 -2.38724928 -0.25275072 0.0073419
| Medium:Weekly-Low:Weekly 0.84 -0.22724928 1.90724928 0.2118374
| None:Weekly-Low:Weekly -1.22 -2.28724928 -0.15275072 0.0161418
| None:Weekly-Medium:Weekly -2.06 -3.12724928 -0.99275072 0.0000134
The above simultaneous multiple comparisons are presented in the form
of confidence intervals for the differences, as well as adjusted
p-values to ensure that the overall p-value is not inflated. As the
number of combinations of factor levels increases, interpreting the
confidence intervals becomes more difficult. To aid interpretation, we
provide a visual representation of the outputted confidence
intervals.
The first two plots correspond to the first two sets of confidence
intervals. The interpretation of these confidence tables and figures is
straightforward. However, the number of intervals associated with
interaction effects increases as the number of factor levels grows,
making interpretation more complex. In the plant growth example, the two
factors result in 28 different group comparisons! Practically meaningful
comparisons focus on differences in growth rates under the same sunlight
conditions but with different watering frequencies.
par(mai=c(1.5,3,1,1)) # Makes room on the plot for the group names
plot(TukeyHSD(anova.interact), # name of the TukeyHSD() object
cex.lab = 0.6, # adjust the font size of the labels of the
# vertical axis
las = 1)



The line segments represent confidence intervals. The middle bar
indicates the estimated difference, and the two ends represent the lower
and upper bounds of the confidence interval. The vertical dashed line
represents zero. That is, if a line segment intersects the vertical
dashed line, the confidence interval includes zero. This implies that
the difference is not statistically significant. Therefore, we conclude
that there is no significant difference between the two means associated
with the underlying groups.
The across comparison we should focus on is highlighted in the
following figure.

Among all confidence intervals, the following intervals should be
reported.
None:Weekly-None:Daily |
-0.14 |
-1.20724928 |
0.92724928 |
0.9998578 |
Low:Weekly-Low:Daily |
0.24 |
-0.82724928 |
1.30724928 |
0.9954055 |
Medium:Weekly-Medium:Daily |
0.34 |
-0.72724928 |
1.40724928 |
0.9657630 |
High:Weekly-High:Daily |
-0.46 |
-1.52724928 |
0.60724928 |
0.8523023 |
LS0tDQp0aXRsZTogIlR3by13YXkgQU5PVkEgQW5hbHl6aW5nIFJhbmRvbWl6ZWQgQmxvY2sgRGVzaWduIg0KYXV0aG9yOiAiQ2hlbmcgUGVuZyINCmRhdGU6ICJTVEEyMDAgU3RhdGlzdGljcyBJSSAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIHRoZW1lOiBsdW1lbg0KICBwZGZfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgZmlnX3dpZHRoOiA1DQogICAgZmlnX2hlaWdodDogNA0KLS0tDQoNCmBgYHs9aHRtbH0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KZGl2I1RPQyBsaSB7DQogICAgbGlzdC1zdHlsZTpub25lOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCmgxLnRpdGxlIHsNCiAgZm9udC1zaXplOiAyNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMiB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQo8L3N0eWxlPg0KYGBgDQoNCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQojIGtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gIkM6L1VzZXJzLzc1Q1BFTkcvT25lRHJpdmUgLSBXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSBvZiBQQS9Eb2N1bWVudHMiKQ0KIyBrbml0cjo6b3B0c19rbml0JHNldChyb290LmRpciA9ICJDOlxcU1RBNDkwXFx3MDUiKQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBUUlVFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gInwiKQ0KYGBgDQoNClwNCg0KDQojIEludHJvZHVjdGlvbg0KDQpUaGUgZGF0YSBmcm9tIHRoZSBDUkQgKENvbXBsZXRlbHkgUmFuZG9taXplZCBEZXNpZ24pIHdlcmUgYW5hbHl6ZWQgdXNpbmcgYSBvbmUtd2F5IEFOT1ZBIHByb2NlZHVyZS4gU2luY2UgdGhlIHRyZWF0bWVudCBpcyBhIGZhY3RvciB3aXRoIGRpZmZlcmVudCBncm91cHMgKHJlcHJlc2VudGluZyBkaWZmZXJlbnQgZG9zZXMpLCBpdCBpbmZsdWVuY2VzIHRoZSByZXNwb25zZSB2YXJpYWJsZS4gT25lLXdheSBBTk9WQSwgYWxzbyBjYWxsZWQgb25lLWZhY3RvciBBTk9WQSwgZm9jdXNlcyBvbiB0ZXN0aW5nIHdoZXRoZXIgdGhlcmUgaXMgYSB0cmVhdG1lbnQgZWZmZWN0LiBJbiBzdGF0aXN0aWNhbCB0ZXJtcywgdGhpcyBpcyBlcXVpdmFsZW50IHRvIHRlc3RpbmcgdGhlIG51bGwgaHlwb3RoZXNpczoNCg0KJCQNCkhfMDogXG11XzEgPSBcbXVfMiA9IFxjZG90cyA9IFxtdV90Lg0KJCQNCg0KVW5kZXIgdGhpcyBudWxsIGh5cG90aGVzaXMsIHRoZSB2YXJpYW5jZSBiZXR3ZWVuIHRyZWF0bWVudHMgYW5kIHRoZSB2YXJpYW5jZSB3aXRoaW4gdHJlYXRtZW50cyBhcmUgYXBwcm94aW1hdGVseSB0aGUgc2FtZS4gVGh1cywgd2UgYXNzZXNzIHRoZSBlcXVhbGl0eSBvZiBtZWFucyBhY3Jvc3MgdHJlYXRtZW50cyBieSBhbmFseXppbmcgdGhlc2UgdmFyaWFuY2VzLCBhcyBzdW1tYXJpemVkIGluIHRoZSBjbGFzc2ljYWwgQU5PVkEgdGFibGUuDQoNClRoZSBrZXkgaW5mb3JtYXRpb24gJE1TX0IkIGFuZCAkTVNfVyQgdXNlZCB0byBjb25zdHJ1Y3QgdGhlIHRlc3Qgc3RhdGlzdGljIGFyZSBiYXNlZCBvbiB0aGUgJFNTX0IkIGFuZCAkU1NfVyQgZXh0cmFjdGVkIGZyb20gdGhlIHRvdGFsIHN1bSBvZiBzcXVhcmVzLg0KDQokJA0KU1NfVCA9IFNTX0IgKyBTU19XLg0KJCQNCg0KVHdvIGZ1bmRhbWVudGFsIGFzc3VtcHRpb25zIGZvciB0aGUgb25lLXdheSBBTk9WQSBhbmFseXNpcyBhcmUNCg0KKiBQb3B1bGF0aW9ucyBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQNCiogVmFyaWFuY2VzIG9mIHRyZWF0bWVudCBncm91cHMgYXJlIGVxdWFsDQoNClVuZGVyIHRoZSBudWxsIGh5cG90aGVzaXMgJEhfMDogXG11XzEgPSBcbXVfMiA9IFxjZG90cyA9IFxtdV90JA0KDQokJA0KRiA9IFxmcmFje1NTX0IvdC0xfXtTU19XL24tdH0gXHJpZ2h0YXJyb3cgRl97dC0xLCBcIG4tdH0NCiQkDQoNCldoZXJlICR0JCBpcyB0aGUgbnVtYmVyIG9mIHRyZWF0bWVudCBncm91cHMgYW5kICRuJCBpcyB0aGUgc2FtcGxlIHNpemUuDQoNClwNCg0KVGhlIFJCRCBkZXNpZ25zIGFkZCBvbmUgYWRkaXRpb25hbCBmYWN0b3IgdmFyaWFibGUuIFdlIGFyZSBpbnRlcmVzdGVkIGluIGFzc2Vzc2luZyB0aGUgZWZmZWN0cyBvZiBib3RoIHRoZSBhZGRpdGlvbmFsIGZhY3RvciBhbmQgdGhlIHRyZWF0bWVudCBlZmZlY3QuIElmIHRoZSBSQkQgaGFzIHJlcGxpY2F0ZXMsIHdlIGFsc28gYXNzZXNzIHRoZSBwb3RlbnRpYWwgaW50ZXJhY3Rpb24gZWZmZWN0LiBCZWNhdXNlIG9mIHRoZSBhZGRpdGlvbmFsIGZhY3RvciwgdGhlIGRlY29tcG9zaXRpb24gb2YgdGhlIHRvdGFsIHN1bSBvZiBzcXVhcmVzIGJlY29tZXMgbW9yZSBjb21wbGV4LCBhbHRob3VnaCB0aGUgbG9naWMgYW5kIG1hdGhlbWF0aWNhbCBkZXJpdmF0aW9uIGFyZSB0aGUgc2FtZSBhcyB0aGUgb25lLXdheSBBTk9WQS4gDQoNCg0KQmVmb3JlIGRpc2N1c3NpbmcgdGhlIGNvbnN0cnVjdGlvbiBvZiBBTk9WQSBmb3IgcmVwbGljYXRlZCBSQkQgZGF0YSwgd2UgZmlyc3QgbG9vayBhdCBhbiBleGFtcGxlIHRvIHNlZSB3aGF0IHByYWN0aWNhbCBxdWVzdGlvbnMgd2UgY2FuIGFuc3dlciBiYXNlZCBvbiB0aGUgZGF0YSBjb2xsZWN0ZWQgZnJvbSBhIHJlcGxpY2F0ZWQgUkJELg0KDQoqKlBsYW50IEdyb3V0aCoqOiBhIGJvdGFuaXN0IHdhbnRzIHRvIGtub3cgd2hldGhlciBvciBub3QgKipwbGFudCBncm93dGgqKiBpcyBpbmZsdWVuY2VkIGJ5ICoqc3VubGlnaHQgZXhwb3N1cmUqKiBhbmQgKip3YXRlcmluZyBmcmVxdWVuY3kqKi4gU2hlIHBsYW50cyA0MCBzZWVkcyBhbmQgbGV0cyB0aGVtIGdyb3cgZm9yIHR3byBtb250aHMgdW5kZXIgZGlmZmVyZW50IGNvbmRpdGlvbnMgZm9yIHN1bmxpZ2h0IGV4cG9zdXJlIGFuZCB3YXRlcmluZyBmcmVxdWVuY3kuIEFmdGVyIHR3byBtb250aHMsIHNoZSByZWNvcmRzIHRoZSBoZWlnaHQgb2YgZWFjaCBwbGFudC4gVGhlIHJlc3VsdHMgYXJlIHNob3duIGJlbG93Og0KDQoNCmBgYHtyIGVjaG8gPSBGQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGg9IjUwJSJ9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDQvMndheWFub3ZhLWV4YW1wbGUucG5nIikNCmBgYA0KDQpDbGVhcmx5LCB0aGlzIGlzIGEgYmFsYW5jZWQgUkJEIHdpdGggcmVwbGljYXRpb25zLiBUaGUgZGF0YSBzdHJ1Y3R1cmUgcmVxdWlyZWQgZm9yIGFuYWx5c2lzIHdpdGggc29mdHdhcmUgcHJvZ3JhbXMgd2lsbCBiZSBkaXNjdXNzZWQgbGF0ZXIuDQoNClwNCg0KIyBIeXBvdGhlc2VzIGFuZCBUZXN0aW5nIE1ldGhvZHMNCg0KV2Ugd2lsbCBmb3JtdWxhdGUgdGhlIGh5cG90aGVzZXMgYmFzZWQgb24gdGhlIHByYWN0aWNhbCBxdWVzdGlvbnMgdG8gYmUgYWRkcmVzc2VkIGJhc2VkIG9uIHJlcGxpY2F0ZWQgUkJEIGRhdGEgYW5kIHNldCB1cCB0aGUgdHdvLXdheSBBTk9WQSB0YWJsZSBmb3IgdGVzdGluZyB0aGUgaHlwb3RoZXNpcywgYWxvbmcgd2l0aCB0aGUgZnVuZGFtZW50YWwgYXNzdW1wdGlvbnMgcmVxdWlyZWQgZm9yIHRoZSB0d28td2F5IEFOT1ZBLg0KDQojIyBTZXR0aW5nIFVwIEh5cG90aGVzZXMNCg0KQXMgd2Ugc2VlIGluIHRoZSAqKlBsYW50IEdyb3d0aCoqIGV4YW1wbGUsIHRoZSBwcmFjdGljYWwgcXVlc3Rpb24gaXMgd2hldGhlciAqKnN1bmxpZ2h0IGV4cG9zdXJlKiogYW5kICoqd2F0ZXJpbmcgZnJlcXVlbmN5KiogYWZmZWN0ICoqcGxhbnQgZ3Jvd3RoKiouIFRoZSBwcmFjdGljYWwgcXVlc3Rpb24gaGFzIHNldmVyYWwgc3ViLXF1ZXN0aW9ucyBmcm9tIGFuIGFuYWx5dGljYWwgcG9pbnQgb2Ygdmlldy4gRm9yIGNvbnZlbmllbmNlLCBsZXQgY2FsbCAqKnN1bmxpZ2h0IGV4cG9zdXJlKiogPGZvbnQgY29sb3IgPSAicmVkIj4qKlxjb2xvcntyZWR9RmFjdG9yIEEqKjwvZm9udD4gYW5kICoqd2F0ZXJpbmcgZnJlcXVlbmN5KiogPGZvbnQgY29sb3IgPSAicmVkIj4qKlxjb2xvcntyZWR9RmFjdG9yIEIqKjwvZm9udD4uIFRoZSByZWxhdGVkIGh5cG90aGVzZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBvcmlnaW5hbCBwcmFjdGljYWwgcXVlc3Rpb24gYXJlDQoNCg0KKiAqKk1haW4gRWZmZWN0IG9mIEZhY3RvciBBKio6DQoNCiQkDQpIXzA6IFx0ZXh0e0FsbCBsZXZlbHMgb2YgRmFjdG9yIEEgaGF2ZSB0aGUgc2FtZSBtZWFuIGVmZmVjdC59IFwgXCBcdGV4dHt2c30gXCBcIEhfYTogXHRleHR7QXQgbGVhc3Qgb25lIGxldmVsIG9mIEZhY3RvciBBIGhhcyBhIGRpZmZlcmVudCBtZWFuIGVmZmVjdC59DQokJA0KDQoqICoqTWFpbiBFZmZlY3Qgb2YgRmFjdG9yIEIqKjoNCg0KJCQgDQpIXzA6IFx0ZXh0e0FsbCBsZXZlbHMgb2YgRmFjdG9yIEIgaGF2ZSB0aGUgc2FtZSBtZWFuIGVmZmVjdC59IFwgXCBcdGV4dHt2c30gXCBcIEhfYTogXHRleHR7QXQgbGVhc3Qgb25lIGxldmVsIG9mIEZhY3RvciBCIGhhcyBhIGRpZmZlcmVudCBtZWFuIGVmZmVjdC59DQokJA0KDQoqICoqSW50ZXJhY3Rpb24gRWZmZWN0IChBIMOXIEIpKio6DQoNCiQkDQpIXzA6IFx0ZXh0e1RoZXJlIGlzIG5vIGludGVyYWN0aW9uIGJldHdlZW4gRmFjdG9yIEEgYW5kIEZhY3RvciBCLn0gXCBcIFx0ZXh0e3ZzfSBcIFwgSF9hOiBcdGV4dHtUaGVyZSBpcyBhIHNpZ25pZmljYW50IGludGVyYWN0aW9uIGVmZmVjdC59DQokJA0KDQojIFR3by13YXkgQU5PVkENCg0KVHdvLXdheSBBTk9WQSBpcyB1c2VkIHRvIGFuYWx5emUgdGhlIGVmZmVjdHMgb2YgdHdvIGluZGVwZW5kZW50IGNhdGVnb3JpY2FsIHZhcmlhYmxlcyAoZmFjdG9ycykgb24gYSBjb250aW51b3VzIGRlcGVuZGVudCB2YXJpYWJsZSB3aGlsZSBhbHNvIGFzc2Vzc2luZyB0aGUgaW50ZXJhY3Rpb24gYmV0d2VlbiB0aGVzZSBmYWN0b3JzLiBVbmxpa2Ugb25lLXdheSBBTk9WQSwgd2hpY2ggZXhhbWluZXMgb25seSBvbmUgZmFjdG9yLCB0d28td2F5IEFOT1ZBIGFsbG93cyByZXNlYXJjaGVycyB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgdHdvIGZhY3RvcnMgaW5kZXBlbmRlbnRseSBpbmZsdWVuY2UgdGhlIG91dGNvbWUgYW5kIHdoZXRoZXIgdGhlaXIgY29tYmluZWQgZWZmZWN0IChpbnRlcmFjdGlvbikgaXMgc2lnbmlmaWNhbnQuIA0KDQojIyBUd28tV2F5IEFOT1ZBIFRhYmxlIFN0cnVjdHVyZQ0KDQpCZWNhdXNlIHR3byBmYWN0b3JzIGFyZSBpbnZvbHZlZCBpbiB0aGUgYW5hbHlzaXMsIHRoZSBtYXRoZW1hdGljYWwgZGVjb21wb3NpdGlvbiBvZiB0aGUgdG90YWwgc3F1YXJlIGludG8gbW9yZSBjb21wb25lbnRzIGZvciB0ZXN0aW5nIHRoZSBhYm92ZSB0aHJlZSBoeXBvdGhlc2VzIGlzIG11Y2ggbW9yZSBjb21wbGV4IHRoYW4gdGhlIG9uZS13YXkgQU5PVkE7IGFsZ2VicmEgaXMgbm90ICoqZGlmZmljdWx0KiouIFdlIHdpbGwgbm90IGRlcml2ZSB0aGUgY29tcG9uZW50cyBpbiB0aGUgQU5PVkEgdGFibGUgYmFzZWQgb24gdGhlIHJhdyBkYXRhIHZhbHVlcy4gSW5zdGVhZCwgd2UgZm9jdXMgb24gdGhlIHN0cnVjdHVyZSBvZiB0aGUgQU5PVkEgdGFibGUgYW5kIGhvdyB0byB1c2UgdGhlIGtleSBzdGF0aXN0aWNzIGluIHRoZSB0YWJsZSB0byB0ZXN0IHRoZSBhYm92ZSBoeXBvdGhlc2VzLiBXZSB1c2Ugc29mdHdhcmUgcHJvZ3JhbXMgdG8gZ2VuZXJhdGUgdGhlIEFOT1ZBIHRhYmxlLiBXZSBmaXJzdCBpbnRyb2R1Y2Ugc29tZSBub3RhdGlvbnMgdG8gaGVscCB1bmRlcnN0YW5kIHRoZSBBTk9WQSB0YWJsZS4NCg0KKiBOdW1iZXIgb2YgY2F0ZWdvcmllcyBpbiAqKmZhY3RvciBBKio6ICRhJA0KKiBOdW1iZXIgb2YgY2F0ZWdvcmllcyBpbiAqKmZhY3RvciBCKio6ICRiJA0KKiBUb3RhbCBzYW1wbGUgc2l6ZTogJE4kDQoqICoqVG90YWwgU3VtIG9mIFNxdWFyZXMqKjogJFNTVCQNCiogKipTdW0gb2YgU3F1YXJlcyBmb3IgRmFjdG9yIEEqKjogJFNTQSQgKFZhcmlhdGlvbiBkdWUgdG8gKipmYWN0b3IgQSoqKS4NCiogKipTdW0gb2YgU3F1YXJlcyBmb3IgRmFjdG9yIEIqKjogJFNTQiQgKFZhcmlhdGlvbiBkdWUgdG8gKipmYWN0b3IgQioqKS4NCiogKipTdW0gb2YgU3F1YXJlcyBmb3IgSW50ZXJhY3Rpb24gYmV0d2VlbiBGYWN0b3IgQSBhbmQgRmFjdG9yIEIqKjogJFNTQUIkICAoVmFyaWF0aW9uIGR1ZSB0byB0aGUgaW50ZXJhY3Rpb24gYmV0d2VlbiAqKkZhY3RvciBBKiogYW5kICoqRmFjdG9yIEIqKikuDQoqICoqUmVzaWR1YWwgU3VtIG9mIFNxdWFyZXMqKjogJFNTRSQgKFVuZXhwbGFpbmVkIHZhcmlhdGlvbiAtIGVycm9yKS4NCg0KTWF0aGVtYXRpY2FsbHkNCg0KJCQNClNTVCA9IFNTQSArIFNTQiArIFNTQUIgKyBTU0UNCiQkDQoNCkVhY2ggKipTdW0gb2YgU3F1YXJlcyoqIGhhcyBpdHMgb3duICoqZGVncmVlcyBvZiBmcmVlZG9tKiouIE5leHQsIHdlIGxpc3QgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSBvcyBlYWNoIG9mIHRoZSAqKnN1bSBvZiBzcXVhcmVzKio6DQoNCiogREYuQSA9ICRhIC0gMSQNCiogREYuQiA9ICRiIC0gMSQNCiogREYuQUIgPSAkKGEtYilcdGltZXMgKGItMSkkIChpbnRlcmFjdGlvbiB0ZXJtKQ0KKiBERi5FID0gJE4gLSBhYiQNCiogREYuVCA9ICROIC0gMSQNCg0KTm90ZSB0aGF0ICROIC0xID0gKGEtMSkgKyAoYi0xKSArIChhLTEpKGItMSkgKyBOIC0gYWIkLg0KDQpXaXRoIHRoZSBhYm92ZSBub3RhdGlvbnMsIHdlIGludHJvZHVjZSB0aGUgdHdvLXdheSBBTk9WQSB0YWJsZS4NCg0KYGBge3IgZWNobyA9IEZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iODAlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoIndlZWswNC9Ud29XYXktQU5PVkEucG5nIikNCmBgYA0KDQpUaGUgZmlyc3QgdGhyZWUgcm93cyBvZiB0aGUgdGFibGUgY29udGFpbiBpbmZvcm1hdGlvbiByZWxhdGVkIHRvIHRlc3RpbmcgdGhlIGFib3ZlIHRocmVlIGh5cG90aGVzZXMuIEluIG9uZS13YXkgQU5PVkEsIHdlIHVzZWQgdGhlIEYtZGlzdHJpYnV0aW9uIHRvIGZpbmQgdGhlIHAtdmFsdWUgZm9yIGEgc3RhdGlzdGljYWwgZGVjaXNpb24gdW5kZXIgc29tZSBhc3N1bXB0aW9ucyBhcyBtZW50aW9uZWQgaW4gdGhlIGZpcnN0IHNlY3Rpb24uIFdlIGFsc28gbmVlZCB0byBtYWtlIHNvbWUgYXNzdW1wdGlvbnMgaW4gb3JkZXIgdG8gc3BlY2lmeSB0aGUgZGlzdHJpYnV0aW9ucyBvZiBGIHN0YXRpc3RpY3MuIE5leHQsIHdlIGRpc2N1c3MgdGhlIGFzc3VtcHRpb25zIG9mIHR3by13YXkgQU5PVkEgYW5kIHRlc3RpbmcgdGhlIGh5cG90aGVzZXMuDQoNClwNCg0KIyMgQXNzdW1wdGlvbnMgb2YgVHdvLVdheSBBTk9WQQ0KDQpBcyB3ZSBrbm93LCBpbiB0aGUgb25lLXdheSBBTk9WQSB0YWJsZSwgdGhlIEYgdmFsdWUgZm9sbG93cyBhbiBGIGRpc3RyaWJ1dGlvbiB1bmRlciBzb21lIGFzc3VtcHRpb25zLiBJbiB0aGUgdHdvLXdheSBBTk9WQSwgd2UgYWxzbyBuZWVkIHRoZSBmb2xsb3dpbmcgYXNzdW1wdGlvbnMgdG8gbWFrZSBpbmZlcmVuY2VzIGFib3V0IHRoZSB0aHJlZSBGIHN0YXRpc3RpY3M6DQoNCiogKipOb3JtYWxpdHkqKjogVGhlIGRlcGVuZGVudCB2YXJpYWJsZSBzaG91bGQgYmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgd2l0aGluICoqZWFjaCBjb21iaW5hdGlvbiBvZiBmYWN0b3IgbGV2ZWxzKiouDQoNCiogKipIb21vZ2VuZWl0eSBvZiBWYXJpYW5jZSAoSG9tb3NjZWRhc3RpY2l0eSkqKjogVGhlIHZhcmlhbmNlcyBhY3Jvc3MgZ3JvdXBzIGRlZmluZWQgYnkgKiplYWNoIGNvbWJpbmF0aW9uIG9mIGZhY3RvciBsZXZlbHMqKiBzaG91bGQgYmUgZXF1YWwuIEluIHByYWN0aWNlLCB3ZSB1c3VhbGx5IHBlcmZvcm0gYSBmb3JtYWwgdGVzdCB0byBjaGVjayB0aGlzIGFzc3VtcHRpb24uDQoNCiogKipJbmRlcGVuZGVuY2Ugb2YgT2JzZXJ2YXRpb25zKio6IERhdGEgcG9pbnRzIHNob3VsZCBiZSBpbmRlcGVuZGVudCwgbWVhbmluZyB0aGUgbWVhc3VyZW1lbnQgb2Ygb25lIHN1YmplY3QgZG9lcyBub3QgaW5mbHVlbmNlIGFub3RoZXIuICoqVGhpcyBhc3N1bXB0aW9uIGlzIGhhcmQgdG8gdGVzdCBmb3IgaW5kZXBlbmRlbmNlLioqLiBXZSB1c3VhbGx5IGp1c3RpZnkgdGhlIGRhdGEgY29sbGVjdGlvbiBwcm9jZXNzLg0KDQoqICoqUmFuZG9tIFNhbXBsaW5nKio6IERhdGEgc2hvdWxkIGJlIGNvbGxlY3RlZCB1c2luZyBhIHJhbmRvbSBzYW1wbGluZyBtZXRob2QuIFRoaXMgaXMganVzdGlmaWVkIGJ5IHRoZSBkYXRhIGNvbGxlY3Rpb24gcHJvY2Vzcy4NCg0KDQpWaW9sYXRpb25zIG9mIHRoZXNlIGFzc3VtcHRpb25zIG1heSByZXF1aXJlIHRyYW5zZm9ybWF0aW9ucyBvciBub24tcGFyYW1ldHJpYyBhbHRlcm5hdGl2ZXMgbGlrZSB0aGUgS3J1c2thbC1XYWxsaXMgdGVzdC4gDQoNClwNCg0KQXNzdW1lIHRoYXQgYWxsIHRoZSBhYm92ZSBhc3N1bXB0aW9ucyBhcmUgbWV0LiBOZXh0LCB3ZSBkaXNjdXNzIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHRlc3Qgc3RhdGlzdGljcyBmb3IgdGVzdGluZyB0aGUgdGhyZWUgaHlwb3RoZXNlcy4NCg0KXA0KDQoqIEVmZmVjdCBvZiAqKkZhY3RvciBBKio6IHVuZGVyIHRoZSBmb2xsb3dpbmcgbnVsbCBoeXBvdGhlc2lzLA0KDQokJA0KSF8wOiBcdGV4dHtBbGwgbGV2ZWxzIG9mIEZhY3RvciBBIGhhdmUgdGhlIHNhbWUgbWVhbiBlZmZlY3QufSANCiQkDQpUaGUgdGVzdCBzdGF0aXN0aWMNCg0KJCQNCkZfQSA9IFxmcmFje01TX0F9e1NTX0V9IFxyaWdodGFycm93IEZfe2EtMSxcIG4tYWIgfS4NCiQkDQoNClRoZSBwLXZhbHVlIGNhbiBiZSBmb3VuZCBmcm9tICRGX3thLTEsXCBuLWFiIH0kLg0KDQpcDQoNCiogRWZmZWN0IG9mICoqRmFjdG9yIEIqKjogdW5kZXIgdGhlIGZvbGxvd2luZyBudWxsIGh5cG90aGVzaXMsDQoNCiQkIA0KSF8wOiBcdGV4dHtBbGwgbGV2ZWxzIG9mIEZhY3RvciBCIGhhdmUgdGhlIHNhbWUgbWVhbiBlZmZlY3QufSANCiQkDQpUaGUgdGVzdCBzdGF0aXN0aWMNCg0KJCQNCkZfQiA9IFxmcmFje01TX0J9e01TX0V9IFxyaWdodGFycm93IEZfe2ItMSwgXCBuIC0gYWJ9DQokJA0KDQpUaGUgcC12YWx1ZSBjYW4gYmUgZm91bmQgZnJvbSAkRl97Yi0xLFwgbi1hYiB9JC4NCg0KXA0KDQoqIEludGVyYWN0aXZlIEVmZmVjdCBiZXR3ZWVuICoqRmFjdG9yIEEqKiBhbmQgKipGYWN0b3IgQioqOiB1bmRlciB0aGUgZm9sbG93aW5nIG51bGwgaHlwb3RoZXNpcywNCg0KJCQNCkhfMDogXHRleHR7VGhlcmUgaXMgbm8gaW50ZXJhY3Rpb24gYmV0d2VlbiBGYWN0b3IgQSBhbmQgRmFjdG9yIEIufSANCiQkDQpUaGUgdGVzdCBzdGF0aXN0aWMNCg0KJCQNCkZfe0FCfSA9IFxmcmFje01TX3tBQn19e01TX0V9IFxyaWdodGFycm93IEZfeyhhLWIpKGItMSksIG4gLWFifQ0KJCQNClRoZSBwLXZhbHVlIGNhbiBiZSBmb3VuZCBmcm9tICRGX3soYS0xKShiLTEpLFwgbi1hYiB9JC4NCg0KXA0KDQo8Zm9udCBjb2xvciA9ICJyZWQiPioqXGNvbG9ye3JlZH1SZW1hcmtzKio8L2ZvbnQ+OiB1bmRlcnN0YW5kaW5nIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIEFOT1ZBIHRhYmxlIGlzIGNydWNpYWwuIA0KDQoqIElmIHRoZSBmaXJzdCB0d28gY29sdW1ucyBhcmUgZ2l2ZW4sIHlvdSBhcmUgZXhwZWN0ZWQgdG8gZGVyaXZlIHRoZSByZXN0IG9mIHRoZSBjb2x1bW5zLCBpbmNsdWRpbmcgdGhlIHAtdmFsdWVzIGluIHRoZSBsYXN0IGNvbHVtbiwgdXNpbmcgdGhlIFIgY29tbWFuZCBgcGYoRiwgZGYxLCBkZjIsIGxvd2VyLnRhaWwgPSBGQUxTRSlgIChGIHRhYmxlIGlzIG5vdCByZWNvbW1lbmRlZCkuDQoNCiogVGhlIGludGVyYWN0aW9uIGVmZmVjdCBpcyBub3QgYXZhaWxhYmxlIGlmIHdvcmtpbmcgd2l0aCBSQkQgZGF0YSB3aXRoIG5vIHJlcGxpY2F0ZXMuDQoNClwNCg0KIyMgUGVyZm9ybWluZyBBTk9WQSBVc2luZyBSDQoNClRoZSBSIGZ1bmN0aW9uIGBhb3YoKWAgd2lsbCBiZSB1c2VkIHRvIHBlcmZvcm0gYW4gQU5PVkEgdGVzdC4gSWYgdGhlIGdpdmVuIGRhdGEgdGFibGUgaXMgaW4gd2lkZSBmb3JtYXQsIHdlIG5lZWQgdG8gcmVmb3JtYXQgaXQgaW50byBhIGxvbmcgdGFibGUuIFRoaXMgaW52b2x2ZXMgcGxhY2luZyBhbGwgcmVzcG9uc2UgdmFsdWVzIGluIGEgc2luZ2xlIGNvbHVtbiBhbmQgdXNpbmcgdHdvIHNlcGFyYXRlIGNvbHVtbnMgdG8gbGFiZWwgZWFjaCByZXNwb25zZSB2YWx1ZSB3aXRoIGl0cyBhc3NvY2lhdGVkIGZhY3RvcnMuIA0KDQpUaGUgUiBmdW5jdGlvbiBgcmVwKClgIGlzIHVzZWZ1bCBmb3IgZ2VuZXJhdGluZyBwYXR0ZXJuZWQgZGF0YS4gSXRzIHN5bnRheCBpcyBgcmVwKGRhdGEudmFsdWUsIHRpbWVzID0gbilgLCB3aGljaCBtZWFucyBpdCAqKnJlcGxpY2F0ZXMqKiBgZGF0YS52YWx1ZWAgKm4qIHRpbWVzLiBUaGUgYGRhdGEudmFsdWVgIGFyZ3VtZW50IGNhbiBiZSBlaXRoZXIgYSAqKnNpbmdsZSB2YWx1ZSoqIG9yIGEgKip2ZWN0b3Igb2YgdmFsdWVzKiouIEJlbG93IGFyZSBzb21lIGV4YW1wbGVzIGRlbW9uc3RyYXRpbmcgaG93IHRvIHVzZSBgcmVwKClgIHRvIGNyZWF0ZSBwYXR0ZXJuZWQgZGF0YS4NCg0KDQpgYGB7cn0NCnJlcCg1LCB0aW1lcyA9IDMpICAgIyByZXBsaWNhdGUgNSB0aHJlZSB0aW1lcw0KcmVwKCJhIiwgOSkgICAgICAgICAjIHJlcGxpY2F0ZSBsb3dlcmNhc2UgbGV0dGVyICJhIiA5IHRpbWVzDQpyZXAoYygxLDMsNSksIDMpICAgICMgcmVwbGljYXRlIHZlY3RvciAoMSwzLDUpIHRocmVlIHRpbWVzDQpyZXAocmVwKGMoIkEiLCAiQiIpLCAyKSwgMykgIyBuZXN0ZWQgcmVwbGljYXRlIHJlcChjKCJBIiwgIkIiKSkgdGhyZWUgdGltZXMNCmBgYA0KDQpOZXh0LCB3ZSB3b3JrIG9uIHRoZSB3aWRlIHRhYmxlIGluIHRoZSBleGFtcGxlIGdpdmVuIGluIFNlY3Rpb24gMS4NCg0KYGBge3J9DQojIyBmaXJzdCwgZGVmaW5lIDQgY29sdW1uIHZlY3RvcnMNCk5vbmUgPSBjKDQuOCwgNC40LCAzLjIsIDMuOSwgNC40LCA0LjQsIDQuMiwgMy44LCAzLjcsIDMuOSkNCkxvdyA9IGMoNS4wLCA1LjIsIDUuNiwgNC4zLCA0LjgsIDQuOSwgNS4zLCA1LjcsIDUuNCwgNC44KQ0KTWVkaXVtID0gYyg2LjQsIDYuMiwgNC43LCA1LjUsIDUuOCwgNS44LCA2LjIsIDYuMywgNi41LCA1LjUpDQpIaWdoID0gYyg2LjMsIDYuNCwgNS42LCA0LjgsIDUuOCwgNi4wLCA0LjksIDQuNiwgNS42LCA1LjUpDQojIyBQbGFjZSB0aGUgYWJvdmUgdmFsdWVzIGluIGEgc2luZ2xlIGNvbHVtbg0KZ3Jvd3RoIDwtIGMoTm9uZSwgTG93LCBNZWRpdW0sIEhpZ2gpDQojIyBkZWZpbmUgc3VubGlnaHQgbGFiZWxzDQpzdW5saWdodCA8LSBjKHJlcCgiTm9uZSIsIGxlbmd0aChOb25lKSksIHJlcCgiTG93IiwgbGVuZ3RoKExvdykpLA0KICAgICAgICAgICAgICByZXAoIk1lZGl1bSIsIGxlbmd0aChNZWRpdW0pKSwgcmVwKCJIaWdoIiwgbGVuZ3RoKEhpZ2gpKSkNCiMjIFdhdGVyaW5nIHBhdHRlcm5zDQojIyBUaGUgaW5uZXIgcmVwKCkgcmV0dXJucyB0aGUgcGF0dGVybiBvZiBmaXJzdCBjb2x1bW4NCiMjIFRoZSBvdXRlciByZXAoKSByZXBsaWNhdGUgdGhlIHJlc3Qgb2YgdGhlIGNvbHVtbnMNCndhdGVyaW5nIDwtcmVwKGMocmVwKCJEYWlseSIsIDUpLCByZXAoIldlZWtseSIsIDUpKSw0KSANCiMjIFN0b3JlIHZhcmlhYmxlcyBpbiBhIGRhdGEgZnJhbWUNCmdyb3d0aERhdGEgPC0gZGF0YS5mcmFtZShncm93dGggPSBncm93dGgsIHN1bmxpZ2h0ID0gc3VubGlnaHQsIHdhdGVyaW5nID0gd2F0ZXJpbmcpDQojIyBjaGVjayB0aGUgZGF0YSBmcmFtZQ0KI2dyb3d0aERhdGENCmBgYA0KDQpXZSBub3cgcGVyZm9ybSB0aGUgQU5PVkEgdXNpbmcgdGhlIGRhdGEgZnJhbWUuDQoNCmBgYHtyfQ0KIyBXZSBmaXQgYW4gQU5PVkEgd2l0aCBhbiBpbnRlcmFjdGl2ZSBlZmZlY3QNCmdyb3d0aC5hb3YgPC0gYW92KGdyb3d0aCB+IHN1bmxpZ2h0KndhdGVyaW5nLCBkYXRhID0gZ3Jvd3RoRGF0YSkNCnN1bW1hcnkoZ3Jvd3RoLmFvdikNCmBgYA0KDQo8Zm9udCBjb2xvciA9ICJyZWQiIHNpemUgPSA0PioqXGNvbG9ye3JlZH1Gb3JtYWwgU3VtbWFyeSBvZiBBTk9WQSoqOjwvZm9udD4gVHdvIGZvcm1hdHMgb2Ygd3JpdGUtdXAgYXJlIHJlY29tbWVuZGVkLg0KDQoqKkZvcm1hdCAxKioNCg0KVGhlIGFib3ZlIHR3by13YXkgQU5PVkEgcmV2ZWFsZWQgYSBzaWduaWZpY2FudCBtYWluIGVmZmVjdCBvZiAqKnN1bmxpZ2h0KiogKCRGKDMsIDMyKSA9IDIzLjA0OSQpLCAkcCBcYXBwcm94IDAkKSwgaW5kaWNhdGluZyB0aGF0IHRoZSBwbGFudCBoZWlnaHRzIChncm93dGgpIHdlcmUgc2lnbmlmaWNhbnRseSBoaWdoZXIgd2hlbiBleHBvc2VkIHRvIG1vcmUgc3VubGlnaHQuIE5laXRoZXIgdGhlIG1haW4gZWZmZWN0IG9mICoqd2F0ZXJpbmcgZnJlcXVlbmN5KiogKCRGKDEsIDMyKSA9IDAuMDEsIHAgPSAwLjk3NiQpIG5vciB0aGUgKipzdW5saWdodCoqIGFuZCAqKndhdGVyaW5nIGZyZXF1ZW5jeSoqIGludGVyYWN0aW9uICgkRigxLDMyKSA9MS4yNDIsIHAgPSAwLjMxMSQpIHdhcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50Lg0KDQoNCioqRm9ybWF0IDIqKg0KDQpBIHR3by13YXkgQU5PVkEgd2FzIGNvbmR1Y3RlZCwgeWllbGRpbmcgdGhlIGZvbGxvd2luZyBmaW5kaW5nczoNCg0KKiAqKldhdGVyaW5nIEZyZXF1ZW5jeSoqOiBObyBzaWduaWZpY2FudCBlZmZlY3Qgb24gcGxhbnQgZ3Jvd3RoIChGKDEsIDMyKSA9IDAuMDEsICpwKiA9IDAuOTc2KS4NCg0KKiAqKlN1bmxpZ2h0IEV4cG9zdXJlKio6IFNpZ25pZmljYW50IGVmZmVjdCBvbiBwbGFudCBncm93dGggKEYoMywgMzIpID0gMjMuMDQ5LCAqcCogPCAwLjAwMSkuIFdlIHdpbGwgY29uZHVjdCBhIHBvc3QtaG9jIGNvbXBhcmlzb24gKGUuZy4sIFR1a2V54oCZcyBIU0QpIHdvdWxkIGRldGVybWluZSB3aGljaCBzdW5saWdodCBsZXZlbHMgZGlmZmVyLg0KDQoqICoqSW50ZXJhY3Rpb24gKFdhdGVyaW5nIMOXIFN1bmxpZ2h0KSoqOiBObyBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiAoRigzLCAzMikgPSAxLjI0MiwgKnAqID0gMC4zMTEpLCBpbmRpY2F0aW5nIHRoYXQgdGhlIGVmZmVjdCBvZiBzdW5saWdodCBkb2VzIG5vdCBkZXBlbmQgb24gd2F0ZXJpbmcgZnJlcXVlbmN5Lg0KDQoNCiMgUG9zdC1ob2MgVGVzdA0KDQpUaGUgaW50ZXJwcmV0YXRpb24gb2YgcG9zdCBob2MgdGVzdHMgYmVjb21lcyBtb3JlIGNvbXBsZXggd2hlbiB0d28gb3IgbW9yZSBmYWN0b3JzIGFyZSBpbmNsdWRlZCBpbiBhbiBBTk9WQSwgZXNwZWNpYWxseSB3aGVuIGludGVyYWN0aW9uIGVmZmVjdHMgYXJlIHByZXNlbnQuIEluIHN1Y2ggY2FzZXMsIGl0IGlzIG9mdGVuIHVzZWZ1bCB0byBjcmVhdGUgbGluZSBwbG90cyBzaG93aW5nIHRoZSBtZWFucyBvZiB0aGUgcHJpbWFyeSBmYWN0b3IgYXQgZWFjaCBsZXZlbCBvZiB0aGUgc2Vjb25kYXJ5IGZhY3Rvci4gQXMgYW4gaWxsdXN0cmF0aXZlIGV4YW1wbGUsIHdlIHdpbGwgdXNlIHRoZSBkYXRhIGZyYW1lIGNyZWF0ZWQgaW4gdGhlIHByZXZpb3VzIHNlY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBtZWFucyBvZiBncm91cHMgZGVmaW5lZCBieSB0aGUgY29tYmluYXRpb24gb2YgYHdhdGVyaW5nYCBhbmQgYHN1bmxpZ2h0YC4gVGhlIFIgZnVuY3Rpb24gYGFnZ3JlZ2F0ZSgpYCBjYW4gYmUgdXNlZCB0byBjb21wdXRlIHRoZXNlIGdyb3VwIG1lYW5zLiBJbiBnZW5lcmFsLCBgYWdncmVnYXRlKClgIGlzIHVzZWQgdG8gc3VtbWFyaXplIHRoZSB2YWx1ZXMgd2l0aGluIGdyb3VwcyB1c2luZyBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIHN1Y2ggYXMgdGhlIG1lYW4sIHZhcmlhbmNlLCBtYXhpbXVtLCBtaW5pbXVtLCBldGMuIFRoZSBzeW50YXggb2YgYWdncmVnYXRlKCkgaXMgc2hvd24gYmVsb3cuDQoNCg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI5NSUifQ0KaW5jbHVkZV9ncmFwaGljcygid2VlazA0L0FnZ3JlZ2F0ZVN5bnRheC5wbmciKQ0KYGBgDQoNCmBgYHtyfQ0KIyMgV2UgdXNlIHRoZSBkYXRhIGZyYW1lICJncm93dGhEYXRhIiBjcmVhdGVkIGluIHRoZSBwcmV2aW91cyBzZWN0aW9uIA0KZ3JwLm1lYW5zIDwtIGFnZ3JlZ2F0ZShncm93dGggfiB3YXRlcmluZyArIHN1bmxpZ2h0LCBkYXRhID0gZ3Jvd3RoRGF0YSwgbWVhbikNCiMjIGNoZWNraW5nIHRoZSByZXN1bHRpbmcgdGFibGUNCiNncnAubWVhbnMNCiMjIHNwbGl0IGludG8gZGFpbHkgbWVhbnMgYW5kIHdlZWtseSBtZWFucw0KIyMgdXNpbmcgd2hpY2goKSB0byBmaW5kIHRoZSByb3dzIGluIHdoaWNoIHdhdGVyaW5nIGlzICJEYWlseSIgYW5kICJXZWVrbHkiIHJlc3BlY3RpdmVseQ0KZGFpbHkuaWQgPC0gd2hpY2goZ3JwLm1lYW5zJHdhdGVyaW5nID09ICJEYWlseSIpDQp3ZWVrbHkuaWQgPC0gd2hpY2goZ3JwLm1lYW5zJHdhdGVyaW5nID09ICJXZWVrbHkiKQ0KIyMgc3Vic2V0IG9mIG1lYW5zIG9mIHN1bmxpZ2h0IGF0IGl0cyBpbmRpdmlkdWFsIGxldmVscw0KZGFpbHkuYXZnIDwtIGdycC5tZWFuc1tkYWlseS5pZCwgM10NCndlZWtseS5hdmcgPC0gZ3JwLm1lYW5zW3dlZWtseS5pZCwgM10NCiMjIyBkcmF3IGxpbmUgcGxvdHMgb2YNCmBgYA0KDQoNCldlIGhhdmUgbm90IGZvcm1hbGx5IGludHJvZHVjZWQgdGhlIFIgYmFzZSBwbG90IGZ1bmN0aW9uIHdpdGggZGV0YWlscy4gTmV4dCwgd2UgYnJpZWZseSBpbnRyb2R1Y2UgdGhlIGJhc2UgUiBmdW5jdGlvbiBgcGxvdCgpYDoNCg0KDQpgYGB7fQ0KcGxvdCh4LCB5LCB0eXBlID0gImIiLCB4YXh0ID0gIm4iLCB4bGFiID0gIkNhdGVnb3J5IiwgeWxhYiA9ICJWYWx1ZSIsIG1haW4gPSAiQ3VzdG9tIFgtQXhpcyBMYWJlbHMiKQ0KYGBgDQp3aGVyZQ0KKiBgeGAgaG9yaXpvbnRhbCB4LWF4aXMNCiogYHlgIHZlcnRpY2FsIHktYXhpcyANCiogYHR5cGUgPSAiYiJgIGRyYXdzIGJvdGggcG9pbnRzIGFuZCBsaW5lcy4NCiogYHhsYWI9YCB0aGUgbGFiZWwgb2YgeC1heGlzDQoqIGB5bGFiID1gIHRoZSBsYWJlbCBvZiB5LWF4aXMNCiogYG1haW49YCB0aGUgdGl0bGUgb2YgdGhlIHBsb3QNCiogYHhheHQgPSAibiJgIHN1cHByZXNzZXMgdGhlIGRlZmF1bHQgeC1heGlzLg0KKiBgYXhpcyhzaWRlID0gMSwgLi4uKWAgYWRkcyBhIGN1c3RvbWl6ZWQgaG9yaXpvbnRhbCBheGlzLg0KDQpUaGUgY29kZSBiZWxvdyBkcmF3cyBhIGxpbmUgcGxvdCBvZiB0aGUgbWVhbiBzdW5saWdodCBsZXZlbHMgZm9yIGVhY2ggd2F0ZXJpbmcgbGV2ZWwuDQoNCmBgYHtyfQ0KIyBDdXN0b20gdGljayBtYXJrIHBvc2l0aW9ucyBhbmQgbGFiZWxzDQp4LnRpY2tzIDwtIGMoMSwyLDMsNCkgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRpY2sgbWFya3MgLyBsb2NhdGlvbiBvZiB0aWNrIGxhYmVscw0KeC5sYWJlbHMgPC0gYygiTm9uZSIsICJMb3ciLCAiTWVkaXVtIiwgIkhpZ2giKQ0KDQojIENyZWF0ZSB0aGUgcGxvdCB3aXRob3V0IHgtYXhpcyAoeGF4dCA9ICJuIikNCnBsb3QoYygxLDIsMyw0KSwgd2Vla2x5LmF2ZywgDQogICAgIHR5cGUgPSAiYiIsDQogICAgIHhheHQgPSAibiIsIA0KICAgICB4bGFiID0gIlN1bmxpZ2h0IiwgDQogICAgIHlsYWIgPSAiTGVuZ3RoIChncm93dGgpIiwgDQogICAgIGNvbCA9ICJyZWQiLCAgICAgICAgICAjIGNvbG9yIG9mIHRoZSBsaW5lIGdyYXBoDQogICAgIGx0eSA9IDEsICAgICAgICAgICAgICAjIGxpbmUgdHlwZS4gMSA9IHNvbGlkIGxpbmUNCiAgICAgbWFpbiA9ICJNZWFuIExlbmd0aCBhY3Jvc3MgU3VubGlnaHQgTGV2ZWwiKQ0KIyMgQWRkIGEgbGluZSBwbG90IG9mIHdlZWtseSB3YXRlcmluZw0KbGluZXMoYygxLDIsMyw0KSwgZGFpbHkuYXZnLCANCiAgICAgIGNvbCA9ICJibHVlIiwNCiAgICAgIGx0eSA9IDEpDQojIEFkZCBjdXN0b20geC1heGlzDQpheGlzKHNpZGUgPSAxLCBhdCA9IHgudGlja3MsIGxhYmVscyA9IHgubGFiZWxzKQ0KIyMgQWRkIGEgbGVnZW5kIHRvIHNwZWNpZnkgdGhlIHdhdGVyaW5nIGxldmVsDQpsZWdlbmQoImJvdHRvbWxlZnQiLCAgICAgICAgICAgICAgIyBsb2NhdGlvbiBmb3IgdGhlIGxlZ2VuZA0KICAgICAgIGMoIldlZWtseSIsICJEYWlseSIpLCAgICAgICMgbmFtZXMgb2YgbGluZSBwbG90LCBDYXV0aW9uOiBrZWVwIHRoZSBvcmRlciBvZiB0aGUgbmFtZXMhDQogICAgICAgbHR5ID0gYygxLDEpLA0KICAgICAgIGNvbCA9IGMoInJlZCIsICJibHVlIiksDQogICAgICAgYnR5ID0gIm4iICAgICAgICAgICAgICAgICAgIyBkb24ndCBpbmNsdWRlIHRoZSBib3ggb2YgdGhlIGxlZ2VuZA0KICAgICAgICkNCmBgYA0KDQo8Zm9udCBjb2xvciA9ICJyZWQiIHNpemUgPSA0PioqXGNvbG9ye3JlZH0gSWYgdGhlIHR3byBsaW5lIGdyYXBocyBhcmUgcGFyYWxsZWwgKGkuZS4sIHRoZXJlIGlzIE5PIGludGVyc2VjdGlvbiksIHRoZSBmYWN0b3JzIGB3YXRlcmluZ2AgYW5kIGBzdW5saWdodGAgZG8gbm90IGhhdmUgYW4gaW50ZXJhY3RpdmUgZWZmZWN0IS4gT3RoZXJ3aXNlLCB0aGUgdHdvIGZhY3RvcnMgZG8gaGF2ZSBhbiBpbnRlcmFjdGl2ZSBlZmZlY3QhKio8L2ZvbnQ+DQoNCg0KKipHcmFwaGljYWwgSW50ZXJwcmV0YXRpb25zKio6DQoNCiogKk1haW4gRWZmZWN0KiBpbnRlcnByZXQgYHN1bmxpZ2h0YCBwYXR0ZXJucyAodHJlbmRzKSBhdCBlYWNoIGB3YXRlcmluZ2AgbGV2ZWw6DQogICsgV2hlbiB3YXRlcmVkIHdlZWtseSwgdGhlIHBsYW50IGdyZXcgYmVzdCB3aXRoICoqbWVkaXVtIHN1bmxpZ2h0KiogYW5kIHBvb3Jlc3Qgd2l0aCB0aGUgKipoaWdoIHN1bmxpZ2h0KiouDQogICsgVGhlIHNhbWUgZ3Jvd3RoIHBhdHRlcm5zIHdlcmUgb2JzZXJ2ZWQgd2hlbiB3YXRlcmluZyBkYWlseS4NCiogKipJbnRlcmFjdGl2ZSBlZmZlY3QqKiBjcm9zcyBjb21wYXJpc29uIGJldHdlZW4gKip3YXRlcmluZyBmcmVxdWVuY2llcyoqDQogICsgVGhlIHBsYW50cyBncmV3IGJldHRlciB3aXRoIGBMb3dgIGFuZCBgTWVkaXVtYCBzdW5saWdodCB3aGVuICoqd2F0ZXJlZCB3ZWVrbHkqKg0KICArIEhvd2V2ZXIsIHRoZSBwbGFudCBncmV3IGJldHRlciB3aXRoIGBOb25lYCBhbmQgYEhpZ2hgIHN1bmxpZ2h0IHdoZW4gKip3YXRlcmVkIGRhaWx5KioNCg0KDQpUaGUgZm9sbG93aW5nIHN1YnNlY3Rpb25zIHByb3ZpZGUgZGV0YWlsZWQgbnVtZXJpY2FsIGNvbXBhcmlzb25zIHdpdGggZGlmZmVyZW5jZXMgYW5kIGFzc29jaWF0ZWQgY29uZmlkZW5jZSBpbnRlcnZhbHMuDQoNCiMjIEFOT1ZBIHdpdGggTm8gSW50ZXJhY3RpdmUgRWZmZWN0DQoNCklmIHRoZXJlIGlzIG5vIGludGVyYWN0aW9uIGVmZmVjdCwgd2UgaW50ZXJwcmV0IHRoZSBtYWluIGVmZmVjdHMgb2YgdGhlIGZhY3RvciB2YXJpYWJsZXMgaW5kZXBlbmRlbnRseS4gSW4gdGhlICoqcGxhbnQgZ3Jvd3RoKiogYW5hbHlzaXMsIHRoZSBrZXkgZmFjdG9yIGlzICoqc3VubGlnaHQqKiwgYW5kIHRoZSBzZWNvbmRhcnkgZmFjdG9yIGlzICoqd2F0ZXJpbmcqKi4gV2UgY29tcGFyZSB0aGUgbWFpbiBlZmZlY3RzIG9mIHRoZSBrZXkgYW5kIHNlY29uZGFyeSBmYWN0b3JzIHNlcGFyYXRlbHkuIEZvciBleGFtcGxlOg0KDQoNCiogKipTdW5saWdodCAoS2V5IEZhY3RvcikqKjogQ29tcGFyZSBtZWFuIG91dGNvbWVzIGFjcm9zcyBzdW5saWdodCBsZXZlbHMsIGlnbm9yaW5nIHdhdGVyaW5nLiAiPGZvbnQgY29sb3IgPSAiYmx1ZSI+Klxjb2xvcntibHVlfUhpZ2ggc3VubGlnaHQgeWllbGRzIGhpZ2hlciBncm93dGggdGhhbiBsb3cgc3VubGlnaHQsIGF2ZXJhZ2VkIG92ZXIgYWxsIHdhdGVyaW5nIGxldmVscy4qPC9mb250Pg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NH0NCiMgQ3VzdG9tIHRpY2sgbWFyayBwb3NpdGlvbnMgYW5kIGxhYmVscw0KeC50aWNrcyA8LSBjKDEsMiwzLDQpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aWNrIG1hcmtzIC8gbG9jYXRpb24gb2YgdGljayBsYWJlbHMNCngubGFiZWxzIDwtIGMoIk5vbmUiLCAiTG93IiwgIk1lZGl1bSIsICJIaWdoIikNCiMgc3VubGlnaHQgbWVhbnMsIGlnbm9yaW5nDQpzdW4uZ3JwLm1lYW5zIDwtIGFnZ3JlZ2F0ZShncm93dGggfiBzdW5saWdodCwgZGF0YSA9IGdyb3d0aERhdGEsIG1lYW4pDQoNCiMgQ3JlYXRlIHRoZSBwbG90IHdpdGhvdXQgeC1heGlzICh4YXh0ID0gIm4iKQ0KcGxvdChjKDEsMiwzLDQpLCBzdW4uZ3JwLm1lYW5zJGdyb3d0aCwgDQogICAgIHR5cGUgPSAiYiIsDQogICAgIHhheHQgPSAibiIsIA0KICAgICB4bGFiID0gIlN1bmxpZ2h0IiwgDQogICAgIHlsYWIgPSAiTGVuZ3RoIChncm93dGgpIiwgDQogICAgIGNvbCA9ICJwdXJwbGUiLCAgICAgICAgICAjIGNvbG9yIG9mIHRoZSBsaW5lIGdyYXBoDQogICAgIGx0eSA9IDEsICAgICAgICAgICAgICAjIGxpbmUgdHlwZS4gMSA9IHNvbGlkIGxpbmUNCiAgICAgbWFpbiA9ICJNZWFuIExlbmd0aCBhY3Jvc3MgU3VubGlnaHQgTGV2ZWwiKQ0KIyBBZGQgY3VzdG9tIHgtYXhpcw0KYXhpcyhzaWRlID0gMSwgYXQgPSB4LnRpY2tzLCBsYWJlbHMgPSB4LmxhYmVscykNCmBgYA0KDQpUaGUgYWJvdmUgbGluZSBwbG90IHNob3dzIHRoYXQgKip0aGUgZ3Jvd3RoIHJhdGUgZ2VuZXJhbGx5IGRlY3JlYXNlcyBhcyBzdW5saWdodCBpbmNyZWFzZXMsIGV4Y2VwdCBhdCB0aGUgbWVkaXVtIHN1bmxpZ2h0IGxldmVsLCBhdCB3aGljaCB0aGUgcmF0ZSBwZWFrcyoqLg0KDQpcDQoNCiogKipXYXRlcmluZyAoU2Vjb25kYXJ5IEZhY3RvcikqKjogQ29tcGFyZSBtZWFucyBhY3Jvc3Mgd2F0ZXJpbmcgbGV2ZWxzLCBpZ25vcmluZyBzdW5saWdodC4gPGZvbnQgY29sb3IgPSAiYmx1ZSI+Klxjb2xvcntibHVlfUZyZXF1ZW50IHdhdGVyaW5nIGluY3JlYXNlcyBncm93dGgsIGJ1dCB0aGlzIGVmZmVjdCBpcyBzbWFsbGVyIHRoYW4gc3VubGlnaHQncyBlZmZlY3QuKjwvZm9udD4NCg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NH0NCiMgQ3VzdG9tIHRpY2sgbWFyayBwb3NpdGlvbnMgYW5kIGxhYmVscw0KeC50aWNrcyA8LSBjKDEsMikgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRpY2sgbWFya3MgLyBsb2NhdGlvbiBvZiB0aWNrIGxhYmVscw0KeC5sYWJlbHMgPC0gYygiRGFpbHkiLCAiV2Vla2x5IikNCiMgc3VubGlnaHQgbWVhbnMsIGlnbm9yaW5nDQpzdW4uZ3JwLm1lYW5zIDwtIGFnZ3JlZ2F0ZShncm93dGggfiB3YXRlcmluZywgZGF0YSA9IGdyb3d0aERhdGEsIG1lYW4pDQoNCiMgQ3JlYXRlIHRoZSBwbG90IHdpdGhvdXQgeC1heGlzICh4YXh0ID0gIm4iKQ0KcGxvdChjKDEsMiksIHN1bi5ncnAubWVhbnMkZ3Jvd3RoLCANCiAgICAgdHlwZSA9ICJiIiwNCiAgICAgeGF4dCA9ICJuIiwgDQogICAgIHhsYWIgPSAiV2F0ZXJpbmciLCANCiAgICAgeWxhYiA9ICJMZW5ndGggKGdyb3d0aCkiLCANCiAgICAgY29sID0gIm9yYW5nZTMiLCAgICAgICAgICAjIGNvbG9yIG9mIHRoZSBsaW5lIGdyYXBoDQogICAgIGx0eSA9IDEsICAgICAgICAgICAgICAjIGxpbmUgdHlwZS4gMSA9IHNvbGlkIGxpbmUNCiAgICAgbWFpbiA9ICJNZWFuIExlbmd0aCBhY3Jvc3MgV2F0ZXJpbmcgRnJlcXVlbmN5IikNCiMgQWRkIGN1c3RvbSB4LWF4aXMNCmF4aXMoc2lkZSA9IDEsIGF0ID0geC50aWNrcywgbGFiZWxzID0geC5sYWJlbHMpDQpgYGANCg0KVGhlIHBsb3QgYWJvdmUgc2hvd3MgdGhhdCAqKnRoZSBwbGFudCBncmV3IGJldHRlciB3aGVuIHdhdGVyZWQgZGFpbHkqKi4NCg0KXA0KDQojIyBBTk9WQSB3aXRoIEludGVyYWN0aXZlIEVmZmVjdA0KDQpBZnRlciBmaW5pc2hpbmcgdGhlIEFOT1ZBIHRlc3QsIHdlIHJlcG9ydCBtdWx0aXBsZSBjb21wYXJpc29ucyBiZXR3ZWVuIGdyb3VwcyBhc3NvY2lhdGVkIHdpdGggdGhlICoqc2lnbmlmaWNhbnQgZmFjdG9ycyoqLiBJZiBhIHR3by13YXkgQU5PVkEgcmV2ZWFscyBhIHNpZ25pZmljYW50IGludGVyYWN0aW9uIGVmZmVjdCwgaXQgbWVhbnMgdGhlIGltcGFjdCBvZiBvbmUgZmFjdG9yIChlLmcuLCBTdW5saWdodCBFeHBvc3VyZSkgZGVwZW5kcyBvbiB0aGUgbGV2ZWwgb2YgdGhlIG90aGVyIGZhY3RvciAoZS5nLiwgV2F0ZXJpbmcgRnJlcXVlbmN5KS4gVG8gaW50ZXJwcmV0IHRoaXMgaW50ZXJhY3Rpb24gcHJvcGVybHksIHdlIG11c3Q6DQoNCiogQ29tcGFyZSBncm91cHMgKip3aXRoaW4gY29tYmluYXRpb25zKiogKGUuZy4sICJgRGFpbHkgKyBMb3cgU3VubGlnaHRgIiB2cy4gImBXZWVrbHkgKyBNZWRpdW0gU3VubGlnaHRgIikuDQoNCiogQ29udHJvbCBmb3IgaW5mbGF0ZWQgVHlwZSBJIGVycm9yIHJhdGVzIChmYWxzZSBwb3NpdGl2ZXMpIGR1ZSB0byAqKm11bHRpcGxlIGNvbXBhcmlzb25zKiogYnkgdXNpbmcgKipzaW11bHRhbmVvdXMgbWV0aG9kcyoqIHN1Y2ggYXMgVHVrZXkncyBIU0QgdG8gYWRqdXN0ICpwKi12YWx1ZXMgdG8gbWFpbnRhaW4gdGhlIGZhbWlseS13aXNlIGVycm9yIHJhdGUgKEZXRVIpIGF0IGEgc2V0IGxldmVsIChlLmcuLCA1JSkuDQoNCkluIHRoZSBhYm92ZSAqKnBsYW50IGdyb3d0aCoqIGRhdGFzZXQsIHRoZSBBTk9WQSB0ZXN0IHN1Z2dlc3RzIGluc2lnbmlmaWNhbmNlIG9mIHRoZSBpbnRlcmFjdGl2ZSBlZmZlY3QgYmV0d2VlbiAqKnN1bmxpZ2h0KiogYW5kICoqd2F0ZXJpbmcqKi4gVGhlIG9ubHkgc2lnbmlmaWNhbnQgZmFjdG9yIGlzICoqc3VubGlnaHQqKi4gRm9yIGlsbHVzdHJhdGlvbiwgd2UgcGVyZm9ybSAqKnNpbXVsdGFuZW91cyBjb21wYXJpc29ucyoqIGZvciBpbmRpdmlkdWFsIGZhY3RvcnMgYW5kIHRoZWlyIGludGVyYWN0aW9ucyB1c2luZyBUdWtleSdzIEhTRC4NCg0KDQpUaGUgZ2VuZXJhbCBpZGVhIGluIGludGVycHJldGluZyBtdWx0aXBsZSBjb21wYXJpc29ucyBpcyB0byBmb2N1cyBvbiB0aGUga2V5IGZhY3RvciAoc3VjaCBhcyBzdW5saWdodCkgYW5kIGJyZWFrIGRvd24gdGhlIHNlY29uZGFyeSBmYWN0b3IgKHdhdGVyaW5nKQ0KDQoNCmBgYHtyfQ0KYW5vdmEuaW50ZXJhY3QgPC0gYW92KGdyb3d0aCB+IHN1bmxpZ2h0KndhdGVyaW5nLCBkYXRhID0gZ3Jvd3RoRGF0YSkgIA0KVHVrZXlIU0QoYW5vdmEuaW50ZXJhY3QpICAjIENvbXBhcmUgc3VubGlnaHQgbGV2ZWxzIHdpdGhpbiBEYWlseSB3YXRlcmluZyANCmBgYA0KDQpUaGUgYWJvdmUgc2ltdWx0YW5lb3VzIG11bHRpcGxlIGNvbXBhcmlzb25zIGFyZSBwcmVzZW50ZWQgaW4gdGhlIGZvcm0gb2YgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIHRoZSBkaWZmZXJlbmNlcywgYXMgd2VsbCBhcyBhZGp1c3RlZCBwLXZhbHVlcyB0byBlbnN1cmUgdGhhdCB0aGUgb3ZlcmFsbCBwLXZhbHVlIGlzIG5vdCBpbmZsYXRlZC4gQXMgdGhlIG51bWJlciBvZiBjb21iaW5hdGlvbnMgb2YgZmFjdG9yIGxldmVscyBpbmNyZWFzZXMsIGludGVycHJldGluZyB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbHMgYmVjb21lcyBtb3JlIGRpZmZpY3VsdC4gVG8gYWlkIGludGVycHJldGF0aW9uLCB3ZSBwcm92aWRlIGEgdmlzdWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBvdXRwdXR0ZWQgY29uZmlkZW5jZSBpbnRlcnZhbHMuIA0KDQpUaGUgZmlyc3QgdHdvIHBsb3RzIGNvcnJlc3BvbmQgdG8gdGhlIGZpcnN0IHR3byBzZXRzIG9mIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLiBUaGUgaW50ZXJwcmV0YXRpb24gb2YgdGhlc2UgY29uZmlkZW5jZSB0YWJsZXMgYW5kIGZpZ3VyZXMgaXMgc3RyYWlnaHRmb3J3YXJkLiBIb3dldmVyLCB0aGUgbnVtYmVyIG9mIGludGVydmFscyBhc3NvY2lhdGVkIHdpdGggaW50ZXJhY3Rpb24gZWZmZWN0cyBpbmNyZWFzZXMgYXMgdGhlIG51bWJlciBvZiBmYWN0b3IgbGV2ZWxzIGdyb3dzLCBtYWtpbmcgaW50ZXJwcmV0YXRpb24gbW9yZSBjb21wbGV4LiBJbiB0aGUgcGxhbnQgZ3Jvd3RoIGV4YW1wbGUsIHRoZSB0d28gZmFjdG9ycyByZXN1bHQgaW4gMjggZGlmZmVyZW50IGdyb3VwIGNvbXBhcmlzb25zISBQcmFjdGljYWxseSBtZWFuaW5nZnVsIGNvbXBhcmlzb25zIGZvY3VzIG9uIGRpZmZlcmVuY2VzIGluIGdyb3d0aCByYXRlcyB1bmRlciB0aGUgc2FtZSBzdW5saWdodCBjb25kaXRpb25zIGJ1dCB3aXRoIGRpZmZlcmVudCB3YXRlcmluZyBmcmVxdWVuY2llcy4gIA0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9OH0NCnBhcihtYWk9YygxLjUsMywxLDEpKSAgICAgICAgICAgIyBNYWtlcyByb29tIG9uIHRoZSBwbG90IGZvciB0aGUgZ3JvdXAgbmFtZXMNCnBsb3QoVHVrZXlIU0QoYW5vdmEuaW50ZXJhY3QpLCAgIyBuYW1lIG9mIHRoZSBUdWtleUhTRCgpIG9iamVjdA0KICAgICBjZXgubGFiID0gMC42LCAgICAgICAgICAgICAjIGFkanVzdCB0aGUgZm9udCBzaXplIG9mIHRoZSBsYWJlbHMgb2YgdGhlIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHZlcnRpY2FsIGF4aXMNCiAgICAgbGFzID0gMSkgDQpgYGANCg0KVGhlIGxpbmUgc2VnbWVudHMgcmVwcmVzZW50IGNvbmZpZGVuY2UgaW50ZXJ2YWxzLiBUaGUgbWlkZGxlIGJhciBpbmRpY2F0ZXMgdGhlIGVzdGltYXRlZCBkaWZmZXJlbmNlLCBhbmQgdGhlIHR3byBlbmRzIHJlcHJlc2VudCB0aGUgbG93ZXIgYW5kIHVwcGVyIGJvdW5kcyBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbC4gVGhlIHZlcnRpY2FsIGRhc2hlZCBsaW5lIHJlcHJlc2VudHMgemVyby4gVGhhdCBpcywgaWYgYSBsaW5lIHNlZ21lbnQgaW50ZXJzZWN0cyB0aGUgdmVydGljYWwgZGFzaGVkIGxpbmUsIHRoZSBjb25maWRlbmNlIGludGVydmFsIGluY2x1ZGVzIHplcm8uIFRoaXMgaW1wbGllcyB0aGF0IHRoZSBkaWZmZXJlbmNlIGlzIG5vdCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LiBUaGVyZWZvcmUsIHdlIGNvbmNsdWRlIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gbWVhbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSB1bmRlcmx5aW5nIGdyb3Vwcy4NCg0KDQpUaGUgYWNyb3NzIGNvbXBhcmlzb24gd2Ugc2hvdWxkIGZvY3VzIG9uIGlzIGhpZ2hsaWdodGVkIGluIHRoZSBmb2xsb3dpbmcgZmlndXJlLg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI3NSUifQ0KaW5jbHVkZV9ncmFwaGljcygid2VlazA0L0ludGVyYWN0aW9uQ0ktUGxhbnRHcm93dGgucG5nIikNCmBgYA0KDQoNCkFtb25nIGFsbCBjb25maWRlbmNlIGludGVydmFscywgdGhlIGZvbGxvd2luZyBpbnRlcnZhbHMgc2hvdWxkIGJlIHJlcG9ydGVkLg0KDQp8ICoqR3JvdXAgRGlmZmVyZW5jZSoqICAgICB8ICoqZGlmZioqIHwgICoqbG93ZXIgQ0kqKiB8ICoqdXBwZXIgQ0kqKiAgfCAqKnAtdmFsdWUqKnwNCnw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXw6LS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tfDotLS0tLS0tLS18DQp8IE5vbmU6V2Vla2x5LU5vbmU6RGFpbHkgICAgIHwgLTAuMTQgfCAtMS4yMDcyNDkyOCAgfCAwLjkyNzI0OTI4IHwgMC45OTk4NTc4fCANCnwgTG93OldlZWtseS1Mb3c6RGFpbHkgICAgICAgfCAgMC4yNCB8IC0wLjgyNzI0OTI4ICB8IDEuMzA3MjQ5MjggfCAwLjk5NTQwNTV8IA0KfCBNZWRpdW06V2Vla2x5LU1lZGl1bTpEYWlseSB8ICAwLjM0IHwgLTAuNzI3MjQ5MjggIHwgMS40MDcyNDkyOCB8IDAuOTY1NzYzMHwgDQp8IEhpZ2g6V2Vla2x5LUhpZ2g6RGFpbHkgICAgIHwgLTAuNDYgfCAtMS41MjcyNDkyOCAgfCAwLjYwNzI0OTI4IHwgMC44NTIzMDIzfCANCg0KDQpcDQoNCiMgQ29uY2x1ZGluZyBSZW1hcmtzIGFuZCBQcmFjdGljZSBFeGVyY2lzZQ0KDQpXZSBoYXZlIGRpc2N1c3NlZCB0aGUgdHdvLXdheSBBTk9WQSBtZXRob2QgZm9yIGFuYWx5emluZyBhICoqcmVwbGljYXRlZCByYW5kb21pemVkIGJsb2NrIGRlc2lnbioqLCB3aXRob3V0IGZvY3VzaW5nIG9uIG1hdGhlbWF0aWNhbCBkZXJpdmF0aW9ucy4gSW5zdGVhZCwgd2UgZW1waGFzaXplZCB1bmRlcnN0YW5kaW5nIHRoZSB1bmRlcmx5aW5nIGNvbmNlcHRzIGFuZCBsb2dpYyBvZiB0aGUgdHdvLXdheSBBTk9WQSwgYXMgd2VsbCBhcyB1c2luZyB0aGUgUiBzb2Z0d2FyZSB0byBhbmFseXplIGRhdGEgZnJvbSByZWFsLXdvcmxkIHByb2JsZW1zLiBUaGUgUiBjb2RlIGFuZCBjb21tYW5kcyBwcm92aWRlZCBpbiB0aGlzIGFuZCBwcmV2aW91cyBub3RlcyBhcmUgcmVhZHkgdG8gYmUgYXBwbGllZCB0byBvdGhlciByZWFsLXdvcmxkIGRhdGEgYW5kIHByYWN0aWNhbCBhcHBsaWNhdGlvbnMuDQoNCg0KVGhlIGZvbGxvd2luZyBZb3VUdWJlIHZpZGVvIHByb3ZpZGVzIGFub3RoZXIgZXhhbXBsZSB1c2luZyBSICg8aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1uUnR2NmJvRU90az4pLg0KDQpcDQoNCjxjZW50ZXI+PGEgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1uUnR2NmJvRU90ayIgdGFyZ2V0PSJwb3B1cCIgDQogICAgICAgICAgICAgICAgICAgb25jbGljaz0id2luZG93Lm9wZW4oJ2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9blJ0djZib0VPdGsnLA0KICAgICAgICAgICAgICAgICAgICAgICduYW1lJywnd2lkdGg9ODUwLGhlaWdodD01MDAnKSI+PGltZyBzcmMgPSAiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vTUFUMTIxVzUvaW1nL1ZpZGVvSWNvbi5wbmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMTIwIj48L2E+DQo8L2NlbnRlcj4NCg0KXA0KDQo8Zm9udCBjb2xvcj0icmVkIiBzaXplPSI0Ij4qKlxjb2xvcntyZWR9Q0FVVElPTioqPC9mb250PjogVGhlIG9uZS13YXkgYW5kIHR3by13YXkgQU5PVkEgbWV0aG9kcyBpbnRyb2R1Y2VkIGluIHRoaXMgYW5kIHByZXZpb3VzIG5vdGVzIGFyZSBiYXNlZCBvbiB0aGUgYXNzdW1wdGlvbiBvZiAqKmluZGVwZW5kZW50IG9ic2VydmF0aW9ucyoqLiBIb3dldmVyLCBpbiBtb3JlIGNvbXBsZXggZXhwZXJpbWVudGFsIGRlc2lnbnMsIG1lYXN1cmVtZW50cyBvZiB0aGUgKipzYW1lIGNoYXJhY3RlcmlzdGljKiogbWF5IGJlIHRha2VuIGZyb20gdGhlICoqc2FtZSBzdWJqZWN0KiogPGZvbnQgY29sb3IgPSAiYmx1ZSI+KipcY29sb3J7Ymx1ZX1tdWx0aXBsZSB0aW1lcyoqPC9mb250Pi4gU3VjaCBkYXRhIG11c3QgYmUgYW5hbHl6ZWQgdXNpbmcgPGZvbnQgY29sb3IgPSAicmVkIj4qKlxjb2xvcntyZWR9cmVwZWF0ZWQgbWVhc3VyZXMgQU5PVkEqKjwvZm9udD4gLSB3aGljaCBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgQU5PVkEgdXNlZCBmb3IgYSByZXBsaWNhdGVkIFJCRCE8L2ZvbnQ+DQoNClwNCg0KRmluYWxseSwgYXMgYW4gZXhlcmNpc2UgdG8gZW5oYW5jZSB5b3VyIHVuZGVyc3RhbmRpbmcgb2YgdGhlIG1ldGhvZG9sb2d5IGFuZCB0byBwcmFjdGljZSB5b3VyIFIgc2tpbGxzIGZvciBmdXR1cmUgcmVhbC13b3JsZCBhcHBsaWNhdGlvbnMsIHdlIGVuY291cmFnZSB5b3UgdG8gdXNlIHRoZSBmb2xsb3dpbmcgKipyZWFjdGlvbiB0aW1lIGRhdGFzZXQqKiwgY29sbGVjdGVkIGZyb20gYSByZXBsaWNhdGVkIHJhbmRvbWl6ZWQgYmxvY2sgZGVzaWduIChSQkQpIGV4cGVyaW1lbnQsIHRvIHBlcmZvcm0gYSBjb21wcmVoZW5zaXZlIEFOT1ZBIGFuYWx5c2lzIGFuZCBwb3N0IGhvYyB0ZXN0cy4gVGhlIG9iamVjdGl2ZSBvZiB0aGUgcmVwbGljYXRlZCBSQkQgaXMgdG8gYXNzZXNzIHRoZSBlZmZlY3RzIG9mIGBiZWVyYCBhbmQgYGNhZmZlaW5lYCBvbiBgcmVzcG9uc2UgdGltZWAuDQoNCg0KYGBge3IgZWNobyA9IEZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iNzAlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoIndlZWswNC9SZXBsaWNhdGVSQkQtd29ya2luZ0RhdGEucG5nIikNCmBgYA0KDQoNCg0KDQo=