Introduction and
Background
The dataset I am using for my analysis is an extensive collection of
metrics for every NBA player’s game-by-game performance across the
2022-2023 playoff season. It was published on the open-source data
science platform Kaggle (link can be found in references section below).
The original source for the data’s accuracy can be confirmed at
Basketball-reference.com, a well-established database for enthusiasts of
the sport. All statistical analysis will be conducted via the
programming language R.
As for the dataset’s contents, it is composed of all 217 players who
played some amount of time in the 2022-2023 postseason. It contained 30
variables, however only 10 played a role in my analysis, so I created a
reduced dataset which only contained the information pertinent to my
research question. An explanation and breakdown of the names and data
types for the variables used in my analysis is below:
“Player” = player’s name = character
“Pos” = player’s position on the court or in starting lineup =
character
“Tm” = team player plays for = character
“Age” = player’s age = integer
“PTS” = player’s points per game average = double
“AST” = player’s assists per game average = double
“TRB” = player’s rebounds per game average = double
“STL” = player’s steals per game average = double
“BLK” = player’s blocks per game average = double
“MP” = player’s minutes per game average = double
Using this dataset, I will be exploring the relationship that a
player’s impact on the game (measured via their average points,
rebounds, assists, steals and blocks) and circumstance (age, position
and team playing for) has on their playing time (measured by per minute
averages). I will refer to the five primary metrics of productivity
(points, rebounds, assists, steals and blocks) as the “five standard
statistics” of basketball.
I have previously analyzed this dataset and found there to be a
strong, positive and simply linear relationship between a player’s
average scoring output and his average playing time. Through linear
regression modeling and bootstrap sampling, I came to the conclusion
that for every additional point a player averages, his playing time
increases by about 1.4 minutes per game. And more broadly, I can say
that a scoring increase of one point per game will result in an increase
of about 1.3 to 1.55 extra minutes per game 95% of the time.
While I initially chose to focus in on the correlation between points
per game and minutes per game due to the overwhelming evidence that a
significant relationship between the two existed (available in
references for further detail), I now plan to expand upon the foundings
of my previous reporting. I will create multi-variate models to
determine how changes in a player’s other metrics, as well as their age,
position and team situation impact their average amount of playing
time.
Given the sufficient size of my dataset, over 200 players from the 16
teams which participated in the postseason, and the reliability of its
sourcing, I am confident that I will be able to come to empirically
justified conclusions.
Multiple Linear
Regression (MLR) Approach
The first modeling strategy I employed to understand what factors
correlated with an NBA player’s average playing time was a multiple
linear regression approach. Setting minutes played as my response and my
dataset’s other six quantitative variables as the predictors, I ran a
linear model which we will refer to as the “Base Regression Model.”
Base Model
The findings of this regression model were definitive. It reported
that per-game averages in the points, rebounds and steals categories
absolutely had a statistically significant correlation with how much
playing time a player got. Alternatively, it was found that not only did
a player’s age and per-game averages in blocks and assists not have a
correlatory impact on his playing time, but it was not particularly
close, especially for assists and blocks per game.
All that being said, I did not want to draw a definitive conclusion
solely from this base regression model, so I performed variable
screening and investigated for other noticeable weaknesses in the
model’s efficiency.
Base_Regression_Model = lm(MP ~ Age + PTS + AST + TRB + STL + BLK, data = Reduced_Playoff_Data)
summary(Base_Regression_Model)
# Base model: (p < 2.2e-16, F = 241.7 (6, 210) Adjusted R^2 = 0.8699
# Significant variables per base model:
# PTS, TRB, STL,
# PTS -> intercept = 0.84028, p < 2e-16
# TRB -> intercept = 1.20050, p = 1.50e-11
# STL -> intercept = 5.80856, p = 1.74e-08
kable(summary(Base_Regression_Model)$coef, digits = 4, align = 'c', caption ="Coefficients for the Base Regression Model")
Coefficients for the Base Regression Model
(Intercept) |
2.2897 |
2.0721 |
1.1050 |
0.2704 |
Age |
0.1002 |
0.0752 |
1.3312 |
0.1846 |
PTS |
0.8403 |
0.0806 |
10.4226 |
0.0000 |
AST |
-0.0107 |
0.2951 |
-0.0363 |
0.9711 |
TRB |
1.2005 |
0.1681 |
7.1400 |
0.0000 |
STL |
5.8086 |
0.9906 |
5.8636 |
0.0000 |
BLK |
-0.0235 |
0.9071 |
-0.0259 |
0.9794 |
Stepwise Regression
Models
Via R, I performed three types of model modification; forward
selection, backward selection and stepwise selection. Forward selection
consists of there being no predictors in the model, and then the most
contributive predictors being iteratively added until there is no more
statistically significant improvement to be made. Backward selection
takes the opposite approach, beginning with a complete linear model (our
base model in this case), and iteratively removing the least
contributive predictors until all that are left are statistically
significant. Lastly, stepwise selection uses a process that combines
elements of both. This process was done to simplify our regression model
and avoid the risk of overfitting that comes with a higher amount of
predictor variables.
All three processes resulted in the same end model; all listing PTS,
TRB and STL as the predictors which had a significant impact on a
player’s given minutes per game. All three models also cited a
significantly strong coefficient of determination, expressing that about
87% of variation in a player’s minutes per game comes from his metrics
in those three categories (points, rebounds and steals).
# Main takeaway: P value, F stat and adjusted R^2 for total models were identical for all three stepwise regression models, this is not very surprising due to how strong the p values were in the original base model.
# All three models also confirm our original model's findings which are that points, rebounds and assists have a significant relationship with a player's average minutes per game. All three models list the same intercepts and p values for all three of those variables, as well as the same intercept for the model of 4.95295 (p < 2e-16).
# Build a null (intercept-only) model using the same data and response
Null_Model = lm(MP ~ 1, data = Reduced_Playoff_Data)
Full_Model = Base_Regression_Model
# 1) Forward Selection
# Forward Model: (p < 2.2e-16, F = 485.5 (3, 213), adjusted R^2 = 0.8706)
# Significant variables per Forward Selection model:
# PTS, TRB, STL
# PTS -> intercept = 0.83937, p < 2e-16
# TRB -> intercept = 1.20058, p = 1.15e-14
# STL -> intercept = 5.85402, p = 3.49e-10
Forward_Model = step(
object = Null_Model,
scope = list(lower = formula(Null_Model), upper = formula(Full_Model)),
direction = "forward",
trace = 1
)
summary(Forward_Model)
# 2) Backward Selection
# Backward Model: (p < 2.2e-16, F = 485.5 (3, 213), adjusted R^2 = 0.8706)
# Significant variables per Backward Selection model:
# PTS, TRB, STL
# PTS -> intercept = 0.83937, p < 2e-16
# TRB -> intercept = 1.20058, p = 1.15e-14
# STL -> intercept = 5.85402, p = 3.49e-10
Backward_Model = step(
object = Full_Model,
direction = "backward",
trace = 1
)
summary(Backward_Model)
# 3) Stepwise Selection
# Stepwise Model: (p < 2.2e-16, F = 485.5 (3, 213), adjusted R^2 = 0.8706)
# Significant variables per Stepwise Selection model:
# PTS, TRB, STL
# PTS -> intercept = 0.83937, p < 2e-16
# TRB -> intercept = 1.20058, p = 1.15e-14
# STL -> intercept = 5.85402, p = 3.49e-10
Stepwise_Model = step(
object = Null_Model,
scope = list(lower = formula(Null_Model), upper = formula(Full_Model)),
direction = "both",
trace = 1
)
summary(Stepwise_Model)
(kable(summary(Forward_Model)$coef, digits = 5, caption ="Coefficients for all Three Stepwise Regression Models"))
Coefficients for all Three Stepwise Regression Models
(Intercept) |
4.95295 |
0.51403 |
9.63559 |
0 |
PTS |
0.83937 |
0.06584 |
12.74912 |
0 |
TRB |
1.20058 |
0.14456 |
8.30534 |
0 |
STL |
5.85402 |
0.88897 |
6.58518 |
0 |
Correlation Concerns
(Base Model)
To ensure that multicollinearity was not a harmful factor in the base
model, and hence also the stepwise model(s), I investigated using a
correlation matrix and a VIF bar graph.
As per the correlation matrix, there is a strong correlation between
AST and PTS (r ~ 0.819). However, assists per game do not report to be a
significant statistic relevant to predicting a player’s given playing
time in any of our regression models, therefore any theoretical threat
of multicollinearity posed by assists per game is not realized.
Looking at the VIF (variance inflation factor) chart, the only
potential concern at face value appears to be that of points per game,
which is hovering slighly above a value of 4. Given that the only other
variables in all of our models that were deemed significant (total
rebounds and steals per game) are both rated below a value of 3, we can
reasonably assess that an out-of-control coefficient variance is not a
great concern.
ggpairs(Quantitative_Predictor_Variables, title = "Correlation Matrix for Age and Player Stats") + theme(plot.title = element_text(hjust = 0.5))

barplot(vif(Base_Regression_Model), main = "VIF Values", horiz = FALSE, col = "steelblue")

Further Residual
Analysis (Base Model)
Given that there was no major multicollinearity issues present in our
base model, I then moved forward and performed residual analysis on both
the base model (seen below) and the stepwise model. Since a more
parsimonious model is more ideal for prediction and estimation, moving
forward I will be utilizing the stepwise model to draw ultimate
takeaways and conclusions.
# Histogram
Base_Model_Residuals = resid(Base_Regression_Model)
Base_Model_Predicted_Values = predict(Base_Regression_Model)
hist(Base_Model_Residuals,
main = "Base Model Errors",
xlab = "Model Residuals")

# Scatterplot
plot(Base_Model_Predicted_Values, Base_Model_Residuals,
main = "Base Model - Residual Analysis Scatterplot",
xlab = "Predicted minutes per game",
ylab = "Model Error (mins per game)")
abline(h=0)

# Residual Mean Calculation
mean(Base_Model_Residuals)
# QQ Plot
qqnorm(Base_Model_Residuals, main = "QQ Residuals", ylab = "Standardized Residuals")
qqline(Base_Model_Residuals)

# Scale-Location Plot
plot(Base_Regression_Model, which = 3)

# Residuals-Leverage Plot
plot(Base_Regression_Model, which = 5)

Further Residual
Analysis (Stepwise Models)
The findings of our residual analysis are not great. The residuals do
not appear normally distributed, as per the histogram and QQ plot, nor
do they appear to have a constant variance, as per the scatterplot and
scale-location plot. The residual-leverage plot also appears to show
anywhere from 2 to 5 observations that are both high leverage and high
residual, which can significantly impact a model’s efficacy.
# Histogram
Forward_Model_Residuals = resid(Forward_Model)
Forward_Model_Predicted_Values = predict(Forward_Model)
hist(Forward_Model_Residuals,
main = "Stepwise Models Errors",
xlab = "Model Residuals")

# Scatterplot
plot(Forward_Model_Predicted_Values, Forward_Model_Residuals,
main = "Stepwise Models - Residual Analysis Scatterplot",
xlab = "Predicted minutes per game",
ylab = "Model Error (mins per game)")
abline(h=0)

# Residual Mean Calculation
mean(Forward_Model_Residuals)
# QQ Plot
qqnorm(Forward_Model_Residuals, main = "QQ Residuals", ylab = "Standardized Residuals")
qqline(Forward_Model_Residuals)

# Scale-Location Plot
plot(Forward_Model, which = 3)

# Residuals-Leverage Plot
plot(Forward_Model, which = 5)

Analysis of Variance
(ANOVA) Model
To determine whether or not there was a correlation between a
player’s position on the court and team (our qualitative predictor
variables) and his playing time, I performed an ANOVA test. The findings
can be seen below and are definitive in suggesting that neither one of
those circumstantial factors has a significant relationship with a
player’s minutes per game.
ANOVA_model = aov(MP ~ Pos * Tm, data = Reduced_Playoff_Data)
summary(ANOVA_model)
ANOVA_Summary_Table = summary(ANOVA_model)[[1]]
# Print as markdown table
kable(ANOVA_Summary_Table, digits = 4, caption = "ANOVA Table: MP ~ Pos * Tm")
ANOVA Table: MP ~ Pos * Tm
Pos |
4 |
570.5512 |
142.6378 |
0.6560 |
0.6236 |
Tm |
15 |
628.6916 |
41.9128 |
0.1928 |
0.9996 |
Pos:Tm |
60 |
6748.6587 |
112.4776 |
0.5173 |
0.9977 |
Residuals |
137 |
29787.6867 |
217.4284 |
NA |
NA |
Checking ANOVA Model
Assumptions
Despite the findings of my ANOVA model being quite strong, I still
wanted to review the data to ensure that no fundamental assumptions for
proper ANOVA modeling were violated. The results of that review were
mixed.
I performed a series of Shapiro Wilk tests to determine if players’
recorded minutes per game were normally distributed when grouping these
observations, first by team and then by position. Regarding teams, five
of the sixteen did not give their players a normally distributed amount
of playing time. Those teams would be the Nets, Cavaliers, Nuggets,
Lakers and Sixers. And when grouped by position, the data showed that
playing time was certainly not distributed in a normal manner.
As for the ANOVA condition of variance equality, there was
overwhelming evidence that the variance of minutes per game was equal
across both teams and positions.
by(MP, Tm, shapiro.test)
by(MP, Pos, shapiro.test)
bartlett.test(MP ~ Tm, data = Reduced_Playoff_Data)
bartlett.test(MP ~ Pos, data = Reduced_Playoff_Data)
Kruskal-Wallis-H
Test
Given the mixed results of my ANOVA assumption check, I chose to
perform a nonparametric Kruskal-Wallis-H Test in order to ensure the
validity of my ANOVA model’s findings that a player’s team and position
status do not play a significant role in his playing time. The findings
of the Kruskal-Wallis-H Test were in alignment with the ANOVA model’s
results, reporting neither as a significant factor in predicting a
player’s minutes per game.
kruskal.test(MP ~ Tm, data = Reduced_Playoff_Data)
Kruskal-Wallis rank sum test
data: MP by Tm
Kruskal-Wallis chi-squared = 4.1147, df = 15, p-value = 0.9973
kruskal.test(MP ~ Pos, data = Reduced_Playoff_Data)
Kruskal-Wallis rank sum test
data: MP by Pos
Kruskal-Wallis chi-squared = 3.6124, df = 4, p-value = 0.461
Conclusion
Ultimately, the findings of today’s analysis can be summarized by the
statement that there is a great deal of evidence that scoring,
rebounding and stealing plays a role in how much playing time an NBA
player receives in the postseason. While alternatively, there is
practically no statistical evidence that a player’s assists’ average,
age, position on the court or team have such a relationship with minutes
played. While there was some slight variation between the base model,
pre-transformation stepwise model and post-transformation stepwise
model, it is safe to estimate the following. For every additional point
per game averaged, a player will receive an additional 0.84 minutes of
playing time. He may also receive an additional 1.2 minutes per game for
a one unit increase in rebounding average, and a boost of 5.8 minutes
per game for every additional steal averaged per game.
LS0tCnRpdGxlOiAiSG93IGFuIE5CQSBQbGF5ZXIncyBQbGF5c3R5bGUgYW5kIENpcmN1bXN0YW5jZSBBZmZlY3QgaGlzIFBsYXlpbmcgVGltZSIKYXV0aG9yOiAiQ2hyaXMgQmFobSIKZGF0ZTogIjIwMjUtMDktMjIiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogdHJ1ZQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlCiAgICB0b2NfZGVwdGg6IDQKICAgIGZpZ193aWR0aDogNgogICAgZmlnX2hlaWdodDogNAogICAgZmlnX2NhcHRpb246IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0aGVtZTogbHVtZW4KICAgIGhpZ2hsaWdodDogdGFuZ28KICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogNAogICAgZmlnX2NhcHRpb246IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogIHdvcmRfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogNAotLS0KCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0KZGl2I1RPQyBsaSB7ICAgICAvKiB0YWJsZSBvZiBjb250ZW50ICAqLwogICAgbGlzdC1zdHlsZTp1cHBlci1yb21hbjsKICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsKICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7CiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7Cn0KCmgxLnRpdGxlIHsgICAgLyogbGV2ZWwgMSBoZWFkZXIgb2YgdGl0bGUgICovCiAgZm9udC1zaXplOiAyNHB4OwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGNvbG9yOiBEYXJrUmVkOwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICBmb250LXNpemU6IDE4cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgY29sb3I6IERhcmtSZWQ7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICBmb250LXNpemU6IDE4cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgY29sb3I6IERhcmtCbHVlOwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAyMHB4OwogICAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBkYXJrcmVkOwogICAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoMiB7IC8qIEhlYWRlciAyIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE4cHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IG5hdnk7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE2cHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IG5hdnk7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE0cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBkYXJrcmVkOwogICAgdGV4dC1hbGlnbjogbGVmdDsKfQoKLyogQWRkIGRvdHMgYWZ0ZXIgbnVtYmVyZWQgaGVhZGVycyAqLwouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7CiAgY29udGVudDogIi4iOwp9CmBgYAoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCAKIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuCgppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsgICAgICAgICAgICAgICAgICAgICAgIyB1c2UgY29uZGl0aW9uYWwgc3RhdGVtZW50IHRvIGRldGVjdAogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpICAgICAgICAgICAgICAgICAgIyB3aGV0aGVyIGEgcGFja2FnZSB3YXMgaW5zdGFsbGVkIGluCiAgIGxpYnJhcnkoa25pdHIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdXIgbWFjaGluZS4gSWYgbm90LCBpbnN0YWxsIGl0IGFuZAp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBsb2FkIGl0IHRvIHRoZSB3b3JraW5nIGRpcmVjdG9yeS4KCmlmICghcmVxdWlyZSh0aWR5dmVyc2UpKSB7bGlicmFyeSh0aWR5dnNlcnNlKX0gCgppZiAoIXJlcXVpcmUoR0dhbGx5KSkge2xpYnJhcnkoR0dhbGx5KX0gCgppZiAoIXJlcXVpcmUoa2FibGVFeHRyYSkpIHtsaWJyYXJ5KGthYmxlRXh0cmEpfSAKCmlmICghcmVxdWlyZShnZ3Bsb3QyKSkge2xpYnJhcnkoZ2dwbG90Mil9IAoKaWYgKCFyZXF1aXJlKGNhcikpIHtsaWJyYXJ5KGNhcil9IAoKaWYgKCFyZXF1aXJlKGRwbHlyKSkge2xpYnJhcnkoZHBseXIpfSAKCmlmICghcmVxdWlyZSgic2NhbGVzIikpIHsKaW5zdGFsbC5wYWNrYWdlcygic2NhbGVzIikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCmxpYnJhcnkoInNjYWxlcyIpIAp9Cgprbml0cjo6b3B0c19jaHVuayRzZXQoCgllY2hvID0gVFJVRSwKCW1lc3NhZ2UgPSBGQUxTRSwKCXdhcm5pbmcgPSBGQUxTRSwKCWNvbW1lbnQgPSBOQSwKCXJlc3VsdHMgPSBUUlVFCikKICAgCmBgYAoKIyMgSW50cm9kdWN0aW9uIGFuZCBCYWNrZ3JvdW5kClRoZSBkYXRhc2V0IEkgYW0gdXNpbmcgZm9yIG15IGFuYWx5c2lzIGlzIGFuIGV4dGVuc2l2ZSBjb2xsZWN0aW9uIG9mIG1ldHJpY3MgZm9yIGV2ZXJ5IE5CQSBwbGF5ZXIncyBnYW1lLWJ5LWdhbWUgcGVyZm9ybWFuY2UgYWNyb3NzIHRoZSAyMDIyLTIwMjMgcGxheW9mZiBzZWFzb24uIEl0IHdhcyBwdWJsaXNoZWQgb24gdGhlIG9wZW4tc291cmNlIGRhdGEgc2NpZW5jZSBwbGF0Zm9ybSBLYWdnbGUgKGxpbmsgY2FuIGJlIGZvdW5kIGluIHJlZmVyZW5jZXMgc2VjdGlvbiBiZWxvdykuIFRoZSBvcmlnaW5hbCBzb3VyY2UgZm9yIHRoZSBkYXRhJ3MgYWNjdXJhY3kgY2FuIGJlIGNvbmZpcm1lZCBhdCBCYXNrZXRiYWxsLXJlZmVyZW5jZS5jb20sIGEgd2VsbC1lc3RhYmxpc2hlZCBkYXRhYmFzZSBmb3IgZW50aHVzaWFzdHMgb2YgdGhlIHNwb3J0LiBBbGwgc3RhdGlzdGljYWwgYW5hbHlzaXMgd2lsbCBiZSBjb25kdWN0ZWQgdmlhIHRoZSBwcm9ncmFtbWluZyBsYW5ndWFnZSBSLgoKQXMgZm9yIHRoZSBkYXRhc2V0J3MgY29udGVudHMsIGl0IGlzIGNvbXBvc2VkIG9mIGFsbCAyMTcgcGxheWVycyB3aG8gcGxheWVkIHNvbWUgYW1vdW50IG9mIHRpbWUgaW4gdGhlIDIwMjItMjAyMyBwb3N0c2Vhc29uLiBJdCBjb250YWluZWQgMzAgdmFyaWFibGVzLCBob3dldmVyIG9ubHkgMTAgcGxheWVkIGEgcm9sZSBpbiBteSBhbmFseXNpcywgc28gSSBjcmVhdGVkIGEgcmVkdWNlZCBkYXRhc2V0IHdoaWNoIG9ubHkgY29udGFpbmVkIHRoZSBpbmZvcm1hdGlvbiBwZXJ0aW5lbnQgdG8gbXkgcmVzZWFyY2ggcXVlc3Rpb24uIEFuIGV4cGxhbmF0aW9uIGFuZCBicmVha2Rvd24gb2YgdGhlIG5hbWVzIGFuZCBkYXRhIHR5cGVzIGZvciB0aGUgdmFyaWFibGVzIHVzZWQgaW4gbXkgYW5hbHlzaXMgaXMgYmVsb3c6CgotICAgIlBsYXllciIgPSBwbGF5ZXIncyBuYW1lID0gY2hhcmFjdGVyCgotICAgIlBvcyIgPSBwbGF5ZXIncyBwb3NpdGlvbiBvbiB0aGUgY291cnQgb3IgaW4gc3RhcnRpbmcgbGluZXVwID0gY2hhcmFjdGVyCgotICAgIlRtIiA9IHRlYW0gcGxheWVyIHBsYXlzIGZvciA9IGNoYXJhY3RlcgoKLSAgICJBZ2UiID0gcGxheWVyJ3MgYWdlID0gaW50ZWdlcgoKLSAgICJQVFMiID0gcGxheWVyJ3MgcG9pbnRzIHBlciBnYW1lIGF2ZXJhZ2UgPSBkb3VibGUKCi0gICAiQVNUIiA9IHBsYXllcidzIGFzc2lzdHMgcGVyIGdhbWUgYXZlcmFnZSA9IGRvdWJsZQoKLSAgICJUUkIiID0gcGxheWVyJ3MgcmVib3VuZHMgcGVyIGdhbWUgYXZlcmFnZSA9IGRvdWJsZQoKLSAgICJTVEwiID0gcGxheWVyJ3Mgc3RlYWxzIHBlciBnYW1lIGF2ZXJhZ2UgPSBkb3VibGUKCi0gICAiQkxLIiA9IHBsYXllcidzIGJsb2NrcyBwZXIgZ2FtZSBhdmVyYWdlID0gZG91YmxlCgotICAgIk1QIiA9IHBsYXllcidzIG1pbnV0ZXMgcGVyIGdhbWUgYXZlcmFnZSA9IGRvdWJsZQoKVXNpbmcgdGhpcyBkYXRhc2V0LCBJIHdpbGwgYmUgZXhwbG9yaW5nIHRoZSByZWxhdGlvbnNoaXAgdGhhdCBhIHBsYXllcidzIGltcGFjdCBvbiB0aGUgZ2FtZSAobWVhc3VyZWQgdmlhIHRoZWlyIGF2ZXJhZ2UgcG9pbnRzLCByZWJvdW5kcywgYXNzaXN0cywgc3RlYWxzIGFuZCBibG9ja3MpIGFuZCBjaXJjdW1zdGFuY2UgKGFnZSwgcG9zaXRpb24gYW5kIHRlYW0gcGxheWluZyBmb3IpIGhhcyBvbiB0aGVpciBwbGF5aW5nIHRpbWUgKG1lYXN1cmVkIGJ5IHBlciBtaW51dGUgYXZlcmFnZXMpLiBJIHdpbGwgcmVmZXIgdG8gdGhlIGZpdmUgcHJpbWFyeSBtZXRyaWNzIG9mIHByb2R1Y3Rpdml0eSAocG9pbnRzLCByZWJvdW5kcywgYXNzaXN0cywgc3RlYWxzIGFuZCBibG9ja3MpIGFzIHRoZSAiZml2ZSBzdGFuZGFyZCBzdGF0aXN0aWNzIiBvZiBiYXNrZXRiYWxsLgoKSSBoYXZlIHByZXZpb3VzbHkgYW5hbHl6ZWQgdGhpcyBkYXRhc2V0IGFuZCBmb3VuZCB0aGVyZSB0byBiZSBhIHN0cm9uZywgcG9zaXRpdmUgYW5kIHNpbXBseSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gYSBwbGF5ZXIncyBhdmVyYWdlIHNjb3Jpbmcgb3V0cHV0IGFuZCBoaXMgYXZlcmFnZSBwbGF5aW5nIHRpbWUuIFRocm91Z2ggbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWxpbmcgYW5kIGJvb3RzdHJhcCBzYW1wbGluZywgSSBjYW1lIHRvIHRoZSBjb25jbHVzaW9uIHRoYXQgZm9yIGV2ZXJ5IGFkZGl0aW9uYWwgcG9pbnQgYSBwbGF5ZXIgYXZlcmFnZXMsIGhpcyBwbGF5aW5nIHRpbWUgaW5jcmVhc2VzIGJ5IGFib3V0IDEuNCBtaW51dGVzIHBlciBnYW1lLiBBbmQgbW9yZSBicm9hZGx5LCBJIGNhbiBzYXkgdGhhdCBhIHNjb3JpbmcgaW5jcmVhc2Ugb2Ygb25lIHBvaW50IHBlciBnYW1lIHdpbGwgcmVzdWx0IGluIGFuIGluY3JlYXNlIG9mIGFib3V0IDEuMyB0byAxLjU1IGV4dHJhIG1pbnV0ZXMgcGVyIGdhbWUgOTUlIG9mIHRoZSB0aW1lLgoKV2hpbGUgSSBpbml0aWFsbHkgY2hvc2UgdG8gZm9jdXMgaW4gb24gdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gcG9pbnRzIHBlciBnYW1lIGFuZCBtaW51dGVzIHBlciBnYW1lIGR1ZSB0byB0aGUgb3ZlcndoZWxtaW5nIGV2aWRlbmNlIHRoYXQgYSBzaWduaWZpY2FudCByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdHdvIGV4aXN0ZWQgKGF2YWlsYWJsZSBpbiByZWZlcmVuY2VzIGZvciBmdXJ0aGVyIGRldGFpbCksIEkgbm93IHBsYW4gdG8gZXhwYW5kIHVwb24gdGhlIGZvdW5kaW5ncyBvZiBteSBwcmV2aW91cyByZXBvcnRpbmcuIEkgd2lsbCBjcmVhdGUgbXVsdGktdmFyaWF0ZSBtb2RlbHMgdG8gZGV0ZXJtaW5lIGhvdyBjaGFuZ2VzIGluIGEgcGxheWVyJ3Mgb3RoZXIgbWV0cmljcywgYXMgd2VsbCBhcyB0aGVpciBhZ2UsIHBvc2l0aW9uIGFuZCB0ZWFtIHNpdHVhdGlvbiBpbXBhY3QgdGhlaXIgYXZlcmFnZSBhbW91bnQgb2YgcGxheWluZyB0aW1lLgoKR2l2ZW4gdGhlIHN1ZmZpY2llbnQgc2l6ZSBvZiBteSBkYXRhc2V0LCBvdmVyIDIwMCBwbGF5ZXJzIGZyb20gdGhlIDE2IHRlYW1zIHdoaWNoIHBhcnRpY2lwYXRlZCBpbiB0aGUgcG9zdHNlYXNvbiwgYW5kIHRoZSByZWxpYWJpbGl0eSBvZiBpdHMgc291cmNpbmcsIEkgYW0gY29uZmlkZW50IHRoYXQgSSB3aWxsIGJlIGFibGUgdG8gY29tZSB0byBlbXBpcmljYWxseSBqdXN0aWZpZWQgY29uY2x1c2lvbnMuCmBgYHtyIERhdGFfUmVhZF9pbl9hbmRfQ2xlYW5pbmcsIGluY2x1ZGU9RkFMU0V9CgpEYXRhX1VybCA9ICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vQ2hyaXNCMjMyMy9TVEEzMjEvbWFpbi9QbGF5b2ZmX0RhdGEuY3N2IgpGdWxsX1BsYXlvZmZfRGF0YSA9IHJlYWRfZGVsaW0oRGF0YV9VcmwsIGRlbGltID0gIjsiLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKQpnbGltcHNlKEZ1bGxfUGxheW9mZl9EYXRhKQoKUmVkdWNlZF9QbGF5b2ZmX0RhdGEgPSBGdWxsX1BsYXlvZmZfRGF0YSAlPiUgZHBseXI6OnNlbGVjdChQbGF5ZXIsIFBvcywgVG0sIEFnZSwgUFRTLCBBU1QsIFRSQiwgU1RMLCBCTEssIE1QKQpnbGltcHNlKFJlZHVjZWRfUGxheW9mZl9EYXRhKQoKCgpQbGF5ZXIgPSBSZWR1Y2VkX1BsYXlvZmZfRGF0YSRQbGF5ZXIKUG9zID0gUmVkdWNlZF9QbGF5b2ZmX0RhdGEkUG9zClRtID0gUmVkdWNlZF9QbGF5b2ZmX0RhdGEkVG0KQWdlID0gUmVkdWNlZF9QbGF5b2ZmX0RhdGEkQWdlClBUUyA9IFJlZHVjZWRfUGxheW9mZl9EYXRhJFBUUwpBU1QgPSBSZWR1Y2VkX1BsYXlvZmZfRGF0YSRBU1QKVFJCID0gUmVkdWNlZF9QbGF5b2ZmX0RhdGEkVFJCClNUTCA9IFJlZHVjZWRfUGxheW9mZl9EYXRhJFNUTApCTEsgPSBSZWR1Y2VkX1BsYXlvZmZfRGF0YSRCTEsKTVAgPSBSZWR1Y2VkX1BsYXlvZmZfRGF0YSRNUAoKUXVhbnRpdGF0aXZlX1ByZWRpY3Rvcl9WYXJpYWJsZXMgPSBSZWR1Y2VkX1BsYXlvZmZfRGF0YVtjKCJBZ2UiLCAiUFRTIiwgIkFTVCIsICJUUkIiLCAiU1RMIiwgIkJMSyIpXQoKQ2F0ZWdvcmljYWxfUHJlZGljdG9yX1ZhcmlhYmxlcyA9IFJlZHVjZWRfUGxheW9mZl9EYXRhW2MoIlBvcyIsICJUbSIpXQoKIyBRdWFudGl0YXRpdmUgUHJlZGljdG9yOiBBZ2UsIFBUUywgQVNULCBUUkIsIFNUTCwgQkxLCiMgQ2F0ZWdvcmljYWwgUHJlZGljdG9yOiBQb3MsIFRtCgpBbGxfUHJlZGljdG9yX1ZhcmlhYmxlcyA9IGNiaW5kKFF1YW50aXRhdGl2ZV9QcmVkaWN0b3JfVmFyaWFibGVzLCBDYXRlZ29yaWNhbF9QcmVkaWN0b3JfVmFyaWFibGVzKQoKYGBgCgojIyBNdWx0aXBsZSBMaW5lYXIgUmVncmVzc2lvbiAoTUxSKSBBcHByb2FjaApUaGUgZmlyc3QgbW9kZWxpbmcgc3RyYXRlZ3kgSSBlbXBsb3llZCB0byB1bmRlcnN0YW5kIHdoYXQgZmFjdG9ycyBjb3JyZWxhdGVkIHdpdGggYW4gTkJBIHBsYXllcidzIGF2ZXJhZ2UgcGxheWluZyB0aW1lIHdhcyBhIG11bHRpcGxlIGxpbmVhciByZWdyZXNzaW9uIGFwcHJvYWNoLiBTZXR0aW5nIG1pbnV0ZXMgcGxheWVkIGFzIG15IHJlc3BvbnNlIGFuZCBteSBkYXRhc2V0J3Mgb3RoZXIgc2l4IHF1YW50aXRhdGl2ZSB2YXJpYWJsZXMgYXMgdGhlIHByZWRpY3RvcnMsIEkgcmFuIGEgbGluZWFyIG1vZGVsIHdoaWNoIHdlIHdpbGwgcmVmZXIgdG8gYXMgdGhlICJCYXNlIFJlZ3Jlc3Npb24gTW9kZWwuIgoKIyMjIEJhc2UgTW9kZWwKVGhlIGZpbmRpbmdzIG9mIHRoaXMgcmVncmVzc2lvbiBtb2RlbCB3ZXJlIGRlZmluaXRpdmUuIEl0IHJlcG9ydGVkIHRoYXQgcGVyLWdhbWUgYXZlcmFnZXMgaW4gdGhlIHBvaW50cywgcmVib3VuZHMgYW5kIHN0ZWFscyBjYXRlZ29yaWVzIGFic29sdXRlbHkgaGFkIGEgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBjb3JyZWxhdGlvbiB3aXRoIGhvdyBtdWNoIHBsYXlpbmcgdGltZSBhIHBsYXllciBnb3QuIEFsdGVybmF0aXZlbHksIGl0IHdhcyBmb3VuZCB0aGF0IG5vdCBvbmx5IGRpZCBhIHBsYXllcidzIGFnZSBhbmQgcGVyLWdhbWUgYXZlcmFnZXMgaW4gYmxvY2tzIGFuZCBhc3Npc3RzIG5vdCBoYXZlIGEgY29ycmVsYXRvcnkgaW1wYWN0IG9uIGhpcyBwbGF5aW5nIHRpbWUsIGJ1dCBpdCB3YXMgbm90IHBhcnRpY3VsYXJseSBjbG9zZSwgZXNwZWNpYWxseSBmb3IgYXNzaXN0cyBhbmQgYmxvY2tzIHBlciBnYW1lLgoKQWxsIHRoYXQgYmVpbmcgc2FpZCwgSSBkaWQgbm90IHdhbnQgdG8gZHJhdyBhIGRlZmluaXRpdmUgY29uY2x1c2lvbiBzb2xlbHkgZnJvbSB0aGlzIGJhc2UgcmVncmVzc2lvbiBtb2RlbCwgc28gSSBwZXJmb3JtZWQgdmFyaWFibGUgc2NyZWVuaW5nIGFuZCBpbnZlc3RpZ2F0ZWQgZm9yIG90aGVyIG5vdGljZWFibGUgd2Vha25lc3NlcyBpbiB0aGUgbW9kZWwncyBlZmZpY2llbmN5LgoKYGBge3IgQmFzZSBNb2RlbCBCdWlsZGluZywgcmVzdWx0cz0naGlkZSd9CkJhc2VfUmVncmVzc2lvbl9Nb2RlbCA9IGxtKE1QIH4gQWdlICsgUFRTICsgQVNUICsgVFJCICsgU1RMICsgQkxLLCBkYXRhID0gUmVkdWNlZF9QbGF5b2ZmX0RhdGEpCnN1bW1hcnkoQmFzZV9SZWdyZXNzaW9uX01vZGVsKQogIyBCYXNlIG1vZGVsOiAocCA8IDIuMmUtMTYsIEYgPSAyNDEuNyAoNiwgMjEwKSBBZGp1c3RlZCBSXjIgPSAwLjg2OTkKICMgU2lnbmlmaWNhbnQgdmFyaWFibGVzIHBlciBiYXNlIG1vZGVsOgogICMgUFRTLCBUUkIsIFNUTCwgCiAgIyBQVFMgLT4gaW50ZXJjZXB0ID0gMC44NDAyOCwgcCA8IDJlLTE2CiAgIyBUUkIgLT4gaW50ZXJjZXB0ID0gMS4yMDA1MCwgcCA9IDEuNTBlLTExCiAgIyBTVEwgLT4gaW50ZXJjZXB0ID0gNS44MDg1NiwgcCA9IDEuNzRlLTA4CgpgYGAKCmBgYHtyfQprYWJsZShzdW1tYXJ5KEJhc2VfUmVncmVzc2lvbl9Nb2RlbCkkY29lZiwgZGlnaXRzID0gNCwgYWxpZ24gPSAnYycsIGNhcHRpb24gPSJDb2VmZmljaWVudHMgZm9yIHRoZSBCYXNlIFJlZ3Jlc3Npb24gTW9kZWwiKQoKYGBgCgojIyMgU3RlcHdpc2UgUmVncmVzc2lvbiBNb2RlbHMKVmlhIFIsIEkgcGVyZm9ybWVkIHRocmVlIHR5cGVzIG9mIG1vZGVsIG1vZGlmaWNhdGlvbjsgZm9yd2FyZCBzZWxlY3Rpb24sIGJhY2t3YXJkIHNlbGVjdGlvbiBhbmQgc3RlcHdpc2Ugc2VsZWN0aW9uLiBGb3J3YXJkIHNlbGVjdGlvbiBjb25zaXN0cyBvZiB0aGVyZSBiZWluZyBubyBwcmVkaWN0b3JzIGluIHRoZSBtb2RlbCwgYW5kIHRoZW4gdGhlIG1vc3QgY29udHJpYnV0aXZlIHByZWRpY3RvcnMgYmVpbmcgaXRlcmF0aXZlbHkgYWRkZWQgdW50aWwgdGhlcmUgaXMgbm8gbW9yZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGltcHJvdmVtZW50IHRvIGJlIG1hZGUuIEJhY2t3YXJkIHNlbGVjdGlvbiB0YWtlcyB0aGUgb3Bwb3NpdGUgYXBwcm9hY2gsIGJlZ2lubmluZyB3aXRoIGEgY29tcGxldGUgbGluZWFyIG1vZGVsIChvdXIgYmFzZSBtb2RlbCBpbiB0aGlzIGNhc2UpLCBhbmQgaXRlcmF0aXZlbHkgcmVtb3ZpbmcgdGhlIGxlYXN0IGNvbnRyaWJ1dGl2ZSBwcmVkaWN0b3JzIHVudGlsIGFsbCB0aGF0IGFyZSBsZWZ0IGFyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LiBMYXN0bHksIHN0ZXB3aXNlIHNlbGVjdGlvbiB1c2VzIGEgcHJvY2VzcyB0aGF0IGNvbWJpbmVzIGVsZW1lbnRzIG9mIGJvdGguIFRoaXMgcHJvY2VzcyB3YXMgZG9uZSB0byBzaW1wbGlmeSBvdXIgcmVncmVzc2lvbiBtb2RlbCBhbmQgYXZvaWQgdGhlIHJpc2sgb2Ygb3ZlcmZpdHRpbmcgdGhhdCBjb21lcyB3aXRoIGEgaGlnaGVyIGFtb3VudCBvZiBwcmVkaWN0b3IgdmFyaWFibGVzLgoKQWxsIHRocmVlIHByb2Nlc3NlcyByZXN1bHRlZCBpbiB0aGUgc2FtZSBlbmQgbW9kZWw7IGFsbCBsaXN0aW5nIFBUUywgVFJCIGFuZCBTVEwgYXMgdGhlIHByZWRpY3RvcnMgd2hpY2ggaGFkIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIGEgcGxheWVyJ3MgZ2l2ZW4gbWludXRlcyBwZXIgZ2FtZS4gQWxsIHRocmVlIG1vZGVscyBhbHNvIGNpdGVkIGEgc2lnbmlmaWNhbnRseSBzdHJvbmcgY29lZmZpY2llbnQgb2YgZGV0ZXJtaW5hdGlvbiwgZXhwcmVzc2luZyB0aGF0IGFib3V0IDg3JSBvZiB2YXJpYXRpb24gaW4gYSBwbGF5ZXIncyBtaW51dGVzIHBlciBnYW1lIGNvbWVzIGZyb20gaGlzIG1ldHJpY3MgaW4gdGhvc2UgdGhyZWUgY2F0ZWdvcmllcyAocG9pbnRzLCByZWJvdW5kcyBhbmQgc3RlYWxzKS4KCmBgYHtyIFN0ZXB3aXNlIFJlZ3Jlc3Npb24gQnVpbGRpbmcsIHJlc3VsdHM9J2hpZGUnfQojIE1haW4gdGFrZWF3YXk6IFAgdmFsdWUsIEYgc3RhdCBhbmQgYWRqdXN0ZWQgUl4yIGZvciB0b3RhbCBtb2RlbHMgd2VyZSBpZGVudGljYWwgZm9yIGFsbCB0aHJlZSBzdGVwd2lzZSByZWdyZXNzaW9uIG1vZGVscywgdGhpcyBpcyBub3QgdmVyeSBzdXJwcmlzaW5nIGR1ZSB0byBob3cgc3Ryb25nIHRoZSBwIHZhbHVlcyB3ZXJlIGluIHRoZSBvcmlnaW5hbCBiYXNlIG1vZGVsLgojIEFsbCB0aHJlZSBtb2RlbHMgYWxzbyBjb25maXJtIG91ciBvcmlnaW5hbCBtb2RlbCdzIGZpbmRpbmdzIHdoaWNoIGFyZSB0aGF0IHBvaW50cywgcmVib3VuZHMgYW5kIGFzc2lzdHMgaGF2ZSBhIHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcCB3aXRoIGEgcGxheWVyJ3MgYXZlcmFnZSBtaW51dGVzIHBlciBnYW1lLiBBbGwgdGhyZWUgbW9kZWxzIGxpc3QgdGhlIHNhbWUgaW50ZXJjZXB0cyBhbmQgcCB2YWx1ZXMgZm9yIGFsbCB0aHJlZSBvZiB0aG9zZSB2YXJpYWJsZXMsIGFzIHdlbGwgYXMgdGhlIHNhbWUgaW50ZXJjZXB0IGZvciB0aGUgbW9kZWwgb2YgNC45NTI5NSAocCA8IDJlLTE2KS4KCgojIEJ1aWxkIGEgbnVsbCAoaW50ZXJjZXB0LW9ubHkpIG1vZGVsIHVzaW5nIHRoZSBzYW1lIGRhdGEgYW5kIHJlc3BvbnNlCk51bGxfTW9kZWwgPSBsbShNUCB+IDEsIGRhdGEgPSBSZWR1Y2VkX1BsYXlvZmZfRGF0YSkKCkZ1bGxfTW9kZWwgPSBCYXNlX1JlZ3Jlc3Npb25fTW9kZWwKCiMgMSkgRm9yd2FyZCBTZWxlY3Rpb24KICAjIEZvcndhcmQgTW9kZWw6IChwIDwgMi4yZS0xNiwgRiA9IDQ4NS41ICgzLCAyMTMpLCBhZGp1c3RlZCBSXjIgPSAwLjg3MDYpCiAgIyBTaWduaWZpY2FudCB2YXJpYWJsZXMgcGVyIEZvcndhcmQgU2VsZWN0aW9uIG1vZGVsOgogICAgIyBQVFMsIFRSQiwgU1RMCiAgICAjIFBUUyAtPiBpbnRlcmNlcHQgPSAwLjgzOTM3LCBwIDwgMmUtMTYKICAgICMgVFJCIC0+IGludGVyY2VwdCA9IDEuMjAwNTgsIHAgPSAxLjE1ZS0xNAogICAgIyBTVEwgLT4gaW50ZXJjZXB0ID0gNS44NTQwMiwgcCA9IDMuNDllLTEwCgogIEZvcndhcmRfTW9kZWwgPSBzdGVwKAogICAgb2JqZWN0ID0gTnVsbF9Nb2RlbCwKICAgIHNjb3BlID0gbGlzdChsb3dlciA9IGZvcm11bGEoTnVsbF9Nb2RlbCksIHVwcGVyID0gZm9ybXVsYShGdWxsX01vZGVsKSksCiAgICBkaXJlY3Rpb24gPSAiZm9yd2FyZCIsCiAgICB0cmFjZSA9IDEKICApCiAgc3VtbWFyeShGb3J3YXJkX01vZGVsKQoKIyAyKSBCYWNrd2FyZCBTZWxlY3Rpb24KICAjIEJhY2t3YXJkIE1vZGVsOiAocCA8IDIuMmUtMTYsIEYgPSA0ODUuNSAoMywgMjEzKSwgYWRqdXN0ZWQgUl4yID0gMC44NzA2KQogICMgU2lnbmlmaWNhbnQgdmFyaWFibGVzIHBlciBCYWNrd2FyZCBTZWxlY3Rpb24gbW9kZWw6CiAgICAjIFBUUywgVFJCLCBTVEwKICAgICMgUFRTIC0+IGludGVyY2VwdCA9IDAuODM5MzcsIHAgPCAyZS0xNgogICAgIyBUUkIgLT4gaW50ZXJjZXB0ID0gMS4yMDA1OCwgcCA9IDEuMTVlLTE0CiAgICAjIFNUTCAtPiBpbnRlcmNlcHQgPSA1Ljg1NDAyLCBwID0gMy40OWUtMTAKICBCYWNrd2FyZF9Nb2RlbCA9IHN0ZXAoCiAgICBvYmplY3QgPSBGdWxsX01vZGVsLAogICAgZGlyZWN0aW9uID0gImJhY2t3YXJkIiwKICAgIHRyYWNlID0gMQogICkKICBzdW1tYXJ5KEJhY2t3YXJkX01vZGVsKQogIAogIAojIDMpIFN0ZXB3aXNlIFNlbGVjdGlvbgogICMgU3RlcHdpc2UgTW9kZWw6IChwIDwgMi4yZS0xNiwgRiA9IDQ4NS41ICgzLCAyMTMpLCBhZGp1c3RlZCBSXjIgPSAwLjg3MDYpCiAgIyBTaWduaWZpY2FudCB2YXJpYWJsZXMgcGVyIFN0ZXB3aXNlIFNlbGVjdGlvbiBtb2RlbDoKICAgICMgUFRTLCBUUkIsIFNUTAogICAgIyBQVFMgLT4gaW50ZXJjZXB0ID0gMC44MzkzNywgcCA8IDJlLTE2CiAgICAjIFRSQiAtPiBpbnRlcmNlcHQgPSAxLjIwMDU4LCBwID0gMS4xNWUtMTQKICAgICMgU1RMIC0+IGludGVyY2VwdCA9IDUuODU0MDIsIHAgPSAzLjQ5ZS0xMAogIFN0ZXB3aXNlX01vZGVsID0gc3RlcCgKICAgIG9iamVjdCA9IE51bGxfTW9kZWwsCiAgICBzY29wZSA9IGxpc3QobG93ZXIgPSBmb3JtdWxhKE51bGxfTW9kZWwpLCB1cHBlciA9IGZvcm11bGEoRnVsbF9Nb2RlbCkpLAogICAgZGlyZWN0aW9uID0gImJvdGgiLAogICAgdHJhY2UgPSAxCiAgKQogIHN1bW1hcnkoU3RlcHdpc2VfTW9kZWwpCiAgCmBgYAoKYGBge3J9CihrYWJsZShzdW1tYXJ5KEZvcndhcmRfTW9kZWwpJGNvZWYsIGRpZ2l0cyA9IDUsIGNhcHRpb24gPSJDb2VmZmljaWVudHMgZm9yIGFsbCBUaHJlZSBTdGVwd2lzZSBSZWdyZXNzaW9uIE1vZGVscyIpKQpgYGAKCiMjIyBDb3JyZWxhdGlvbiBDb25jZXJucyAoQmFzZSBNb2RlbCkKVG8gZW5zdXJlIHRoYXQgbXVsdGljb2xsaW5lYXJpdHkgd2FzIG5vdCBhIGhhcm1mdWwgZmFjdG9yIGluIHRoZSBiYXNlIG1vZGVsLCBhbmQgaGVuY2UgYWxzbyB0aGUgc3RlcHdpc2UgbW9kZWwocyksIEkgaW52ZXN0aWdhdGVkIHVzaW5nIGEgY29ycmVsYXRpb24gbWF0cml4IGFuZCBhIFZJRiBiYXIgZ3JhcGguIAoKQXMgcGVyIHRoZSBjb3JyZWxhdGlvbiBtYXRyaXgsIHRoZXJlIGlzIGEgc3Ryb25nIGNvcnJlbGF0aW9uIGJldHdlZW4gQVNUIGFuZCBQVFMgKHIgfiAwLjgxOSkuIEhvd2V2ZXIsIGFzc2lzdHMgcGVyIGdhbWUgZG8gbm90IHJlcG9ydCB0byBiZSBhIHNpZ25pZmljYW50IHN0YXRpc3RpYyByZWxldmFudCB0byBwcmVkaWN0aW5nIGEgcGxheWVyJ3MgZ2l2ZW4gcGxheWluZyB0aW1lIGluIGFueSBvZiBvdXIgcmVncmVzc2lvbiBtb2RlbHMsIHRoZXJlZm9yZSBhbnkgdGhlb3JldGljYWwgdGhyZWF0IG9mIG11bHRpY29sbGluZWFyaXR5IHBvc2VkIGJ5IGFzc2lzdHMgcGVyIGdhbWUgaXMgbm90IHJlYWxpemVkLgoKTG9va2luZyBhdCB0aGUgVklGICh2YXJpYW5jZSBpbmZsYXRpb24gZmFjdG9yKSBjaGFydCwgdGhlIG9ubHkgcG90ZW50aWFsIGNvbmNlcm4gYXQgZmFjZSB2YWx1ZSBhcHBlYXJzIHRvIGJlIHRoYXQgb2YgcG9pbnRzIHBlciBnYW1lLCB3aGljaCBpcyBob3ZlcmluZyBzbGlnaGx5IGFib3ZlIGEgdmFsdWUgb2YgNC4gR2l2ZW4gdGhhdCB0aGUgb25seSBvdGhlciB2YXJpYWJsZXMgaW4gYWxsIG9mIG91ciBtb2RlbHMgdGhhdCB3ZXJlIGRlZW1lZCBzaWduaWZpY2FudCAodG90YWwgcmVib3VuZHMgYW5kIHN0ZWFscyBwZXIgZ2FtZSkgYXJlIGJvdGggcmF0ZWQgYmVsb3cgYSB2YWx1ZSBvZiAzLCB3ZSBjYW4gcmVhc29uYWJseSBhc3Nlc3MgdGhhdCBhbiBvdXQtb2YtY29udHJvbCBjb2VmZmljaWVudCB2YXJpYW5jZSBpcyBub3QgYSBncmVhdCBjb25jZXJuLgpgYGB7ciBDb3JyZWxhdGlvbiBDb25jZXJucyBCYXNlIE1vZGVsLCBmaWcuYWxpZ24gPSJjZW50ZXIifQpnZ3BhaXJzKFF1YW50aXRhdGl2ZV9QcmVkaWN0b3JfVmFyaWFibGVzLCB0aXRsZSA9ICJDb3JyZWxhdGlvbiBNYXRyaXggZm9yIEFnZSBhbmQgUGxheWVyIFN0YXRzIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKCmJhcnBsb3QodmlmKEJhc2VfUmVncmVzc2lvbl9Nb2RlbCksIG1haW4gPSAiVklGIFZhbHVlcyIsIGhvcml6ID0gRkFMU0UsIGNvbCA9ICJzdGVlbGJsdWUiKQpgYGAKCiMjIyBGdXJ0aGVyIFJlc2lkdWFsIEFuYWx5c2lzIChCYXNlIE1vZGVsKQpHaXZlbiB0aGF0IHRoZXJlIHdhcyBubyBtYWpvciBtdWx0aWNvbGxpbmVhcml0eSBpc3N1ZXMgcHJlc2VudCBpbiBvdXIgYmFzZSBtb2RlbCwgSSB0aGVuIG1vdmVkIGZvcndhcmQgYW5kIHBlcmZvcm1lZCByZXNpZHVhbCBhbmFseXNpcyBvbiBib3RoIHRoZSBiYXNlIG1vZGVsIChzZWVuIGJlbG93KSBhbmQgdGhlIHN0ZXB3aXNlIG1vZGVsLiBTaW5jZSBhIG1vcmUgcGFyc2ltb25pb3VzIG1vZGVsIGlzIG1vcmUgaWRlYWwgZm9yIHByZWRpY3Rpb24gYW5kIGVzdGltYXRpb24sIG1vdmluZyBmb3J3YXJkIEkgd2lsbCBiZSB1dGlsaXppbmcgdGhlIHN0ZXB3aXNlIG1vZGVsIHRvIGRyYXcgdWx0aW1hdGUgdGFrZWF3YXlzIGFuZCBjb25jbHVzaW9ucy4KYGBge3IgUmVzaWR1YWwgQW5hbHlzaXMgQmFzZSwgcmVzdWx0cz0naGlkZSd9CiMgSGlzdG9ncmFtCkJhc2VfTW9kZWxfUmVzaWR1YWxzID0gcmVzaWQoQmFzZV9SZWdyZXNzaW9uX01vZGVsKQpCYXNlX01vZGVsX1ByZWRpY3RlZF9WYWx1ZXMgPSBwcmVkaWN0KEJhc2VfUmVncmVzc2lvbl9Nb2RlbCkKaGlzdChCYXNlX01vZGVsX1Jlc2lkdWFscywKICAgICBtYWluID0gIkJhc2UgTW9kZWwgRXJyb3JzIiwKICAgICB4bGFiID0gIk1vZGVsIFJlc2lkdWFscyIpCgojIFNjYXR0ZXJwbG90CnBsb3QoQmFzZV9Nb2RlbF9QcmVkaWN0ZWRfVmFsdWVzLCBCYXNlX01vZGVsX1Jlc2lkdWFscywKICAgICBtYWluID0gIkJhc2UgTW9kZWwgLSBSZXNpZHVhbCBBbmFseXNpcyBTY2F0dGVycGxvdCIsCiAgICAgeGxhYiA9ICJQcmVkaWN0ZWQgbWludXRlcyBwZXIgZ2FtZSIsCiAgICAgeWxhYiA9ICJNb2RlbCBFcnJvciAobWlucyBwZXIgZ2FtZSkiKQphYmxpbmUoaD0wKQoKIyBSZXNpZHVhbCBNZWFuIENhbGN1bGF0aW9uCm1lYW4oQmFzZV9Nb2RlbF9SZXNpZHVhbHMpCgojIFFRIFBsb3QgCnFxbm9ybShCYXNlX01vZGVsX1Jlc2lkdWFscywgbWFpbiA9ICJRUSBSZXNpZHVhbHMiLCB5bGFiID0gIlN0YW5kYXJkaXplZCBSZXNpZHVhbHMiKQpxcWxpbmUoQmFzZV9Nb2RlbF9SZXNpZHVhbHMpCgojIFNjYWxlLUxvY2F0aW9uIFBsb3QKcGxvdChCYXNlX1JlZ3Jlc3Npb25fTW9kZWwsIHdoaWNoID0gMykKCiMgUmVzaWR1YWxzLUxldmVyYWdlIFBsb3QKcGxvdChCYXNlX1JlZ3Jlc3Npb25fTW9kZWwsIHdoaWNoID0gNSkKCmBgYAoKIyMjIEZ1cnRoZXIgUmVzaWR1YWwgQW5hbHlzaXMgKFN0ZXB3aXNlIE1vZGVscykKVGhlIGZpbmRpbmdzIG9mIG91ciByZXNpZHVhbCBhbmFseXNpcyBhcmUgbm90IGdyZWF0LiBUaGUgcmVzaWR1YWxzIGRvIG5vdCBhcHBlYXIgbm9ybWFsbHkgZGlzdHJpYnV0ZWQsIGFzIHBlciB0aGUgaGlzdG9ncmFtIGFuZCBRUSBwbG90LCBub3IgZG8gdGhleSBhcHBlYXIgdG8gaGF2ZSBhIGNvbnN0YW50IHZhcmlhbmNlLCBhcyBwZXIgdGhlIHNjYXR0ZXJwbG90IGFuZCBzY2FsZS1sb2NhdGlvbiBwbG90LiBUaGUgcmVzaWR1YWwtbGV2ZXJhZ2UgcGxvdCBhbHNvIGFwcGVhcnMgdG8gc2hvdyBhbnl3aGVyZSBmcm9tIDIgdG8gNSBvYnNlcnZhdGlvbnMgdGhhdCBhcmUgYm90aCBoaWdoIGxldmVyYWdlIGFuZCBoaWdoIHJlc2lkdWFsLCB3aGljaCBjYW4gc2lnbmlmaWNhbnRseSBpbXBhY3QgYSBtb2RlbCdzIGVmZmljYWN5LiAKYGBge3IgUmVzaWR1YWwgQW5hbHlzaXMgU3RlcHdpc2UsIHJlc3VsdHM9J2hpZGUnfQojIEhpc3RvZ3JhbQpGb3J3YXJkX01vZGVsX1Jlc2lkdWFscyA9IHJlc2lkKEZvcndhcmRfTW9kZWwpCkZvcndhcmRfTW9kZWxfUHJlZGljdGVkX1ZhbHVlcyA9IHByZWRpY3QoRm9yd2FyZF9Nb2RlbCkKaGlzdChGb3J3YXJkX01vZGVsX1Jlc2lkdWFscywKICAgICBtYWluID0gIlN0ZXB3aXNlIE1vZGVscyBFcnJvcnMiLAogICAgIHhsYWIgPSAiTW9kZWwgUmVzaWR1YWxzIikKCiMgU2NhdHRlcnBsb3QKcGxvdChGb3J3YXJkX01vZGVsX1ByZWRpY3RlZF9WYWx1ZXMsIEZvcndhcmRfTW9kZWxfUmVzaWR1YWxzLAogICAgIG1haW4gPSAiU3RlcHdpc2UgTW9kZWxzIC0gUmVzaWR1YWwgQW5hbHlzaXMgU2NhdHRlcnBsb3QiLAogICAgIHhsYWIgPSAiUHJlZGljdGVkIG1pbnV0ZXMgcGVyIGdhbWUiLAogICAgIHlsYWIgPSAiTW9kZWwgRXJyb3IgKG1pbnMgcGVyIGdhbWUpIikKYWJsaW5lKGg9MCkKCiMgUmVzaWR1YWwgTWVhbiBDYWxjdWxhdGlvbgptZWFuKEZvcndhcmRfTW9kZWxfUmVzaWR1YWxzKQoKIyBRUSBQbG90IApxcW5vcm0oRm9yd2FyZF9Nb2RlbF9SZXNpZHVhbHMsIG1haW4gPSAiUVEgUmVzaWR1YWxzIiwgeWxhYiA9ICJTdGFuZGFyZGl6ZWQgUmVzaWR1YWxzIikKcXFsaW5lKEZvcndhcmRfTW9kZWxfUmVzaWR1YWxzKQoKIyBTY2FsZS1Mb2NhdGlvbiBQbG90CnBsb3QoRm9yd2FyZF9Nb2RlbCwgd2hpY2ggPSAzKQoKIyBSZXNpZHVhbHMtTGV2ZXJhZ2UgUGxvdApwbG90KEZvcndhcmRfTW9kZWwsIHdoaWNoID0gNSkKYGBgCgojIyMgTUxSIGFuYWx5c2lzIHdpdGggQm94LUNveCB0cmFuc2Zvcm1hdGlvbgpHaXZlbiB0aGUgcmVzdWx0cyBvZiB0aGUgcmVzaWR1YWwgYW5hbHlzaXMgb24gbXkgc3RlcHdpc2UgbW9kZWwsIEkgdGhlbiBwZXJmb3JtZWQgYSBib3gtY294IHRyYW5zZm9ybWF0aW9uIG9mIG15IG1vZGVsLCB3aXRoIGEgbGFtYmEgdmFsdWUgb2YgMS4wNSwgdG8gaGVscCBtaXRpZ2F0ZSB0aGUgZXJyb3JzIHRoYXQgaW5jb25zaXN0ZW50IHJlc2lkdWFsIHZhcmlhbmNlIGFuZCBsYWNrIG9mIG5vcm1hbCBkaXN0cmlidXRpb24gbWlnaHQgYnJpbmcuIFRoZSByZXN1bHRzIHdlcmUgb25jZSBhZ2FpbiBkZWZpbml0aXZlLCBhbmQgaW4gYWxpZ25tZW50IHdpdGggdGhlIGJhc2UgbW9kZWwgYW5kIHRoZSBwcmUtdHJhbnNmb3JtYXRpb24gc3RlcHdpc2UgbW9kZWxzOyB0aGF0IGJlaW5nIHRoYXQgcG9pbnRzIHBlciBnYW1lLCByZWJvdW5kcyBwZXIgZ2FtZSBhbmQgc3RlYWxzIHBlciBnYW1lIHdlcmUgQUxMIGhpZ2hseSBzaWduaWZpY2FudCBmYWN0b3JzIGluIGVzdGltYXRpbmcgYSBwbGF5ZXIncyBtaW51dGVzIHBlciBnYW1lLgpgYGB7ciBCb3hjb3gsIHJlc3VsdHM9J2hpZGUnfQogIyBIYWQgMSBvYnNlcnZhdGlvbiB3aGVyZSBvdXIgcmVzcG9uc2UgdmFyaWFibGUgTVAgd2FzID0gMCwgd2hpY2ggZG9lcyBub3Qgd29yayB3aXRoIEJveC1Db3ggdHJhbnNmb3JtYXRpb24uCmxpYnJhcnkoTUFTUykKClJlZHVjZWRfUGxheW9mZl9EYXRhMiA9IFJlZHVjZWRfUGxheW9mZl9EYXRhW1JlZHVjZWRfUGxheW9mZl9EYXRhJE1QID4gMCwgXQoKRm9yd2FyZF9Nb2RlbDIgPSBsbShNUCB+IFBUUyArIFRSQiArIFNUTCwgZGF0YSA9IFJlZHVjZWRfUGxheW9mZl9EYXRhMikKCkJveGNveCA9IGJveGNveChGb3J3YXJkX01vZGVsMiwgbGFtYmRhID0gc2VxKC0yLCAyLCAwLjEpKQpsYW1iZGEgPSAxLjA1CgojIE1vZGlmeSBNUCB2YXJpYWJsZSBpbiBkYXRhc2V0IHdpdGggbGFtYmEgdHJhbnNmb3JtYXRpb24KUmVkdWNlZF9QbGF5b2ZmX0RhdGEyJE1QX2JjID0gaWYgKGxhbWJkYSA9PSAwKSB7CiAgbG9nKFJlZHVjZWRfUGxheW9mZl9EYXRhMiRNUCkKfSBlbHNlIHsKICAoUmVkdWNlZF9QbGF5b2ZmX0RhdGEyJE1QXmxhbWJkYSAtIDEpIC8gbGFtYmRhCn0KCkJveENveF9Nb2RlbCA9IGxtKE1QIH4gUFRTICsgVFJCICsgU1RMLCBkYXRhID0gUmVkdWNlZF9QbGF5b2ZmX0RhdGEyKQpzdW1tYXJ5KEJveENveF9Nb2RlbCkKYGBgCgpgYGB7cn0KKGthYmxlKHN1bW1hcnkoRm9yd2FyZF9Nb2RlbCkkY29lZiwgZGlnaXRzID0gNSwgY2FwdGlvbiA9IkNvZWZmaWNpZW50cyBmb3IgQm94LUNveCBUcmFuc2Zvcm1lZCBTdGVwd2lzZSBNb2RlbCIpKQpgYGAKIyMgQW5hbHlzaXMgb2YgVmFyaWFuY2UgKEFOT1ZBKSBNb2RlbApUbyBkZXRlcm1pbmUgd2hldGhlciBvciBub3QgdGhlcmUgd2FzIGEgY29ycmVsYXRpb24gYmV0d2VlbiBhIHBsYXllcidzIHBvc2l0aW9uIG9uIHRoZSBjb3VydCBhbmQgdGVhbSAob3VyIHF1YWxpdGF0aXZlIHByZWRpY3RvciB2YXJpYWJsZXMpIGFuZCBoaXMgcGxheWluZyB0aW1lLCBJIHBlcmZvcm1lZCBhbiBBTk9WQSB0ZXN0LiBUaGUgZmluZGluZ3MgY2FuIGJlIHNlZW4gYmVsb3cgYW5kIGFyZSBkZWZpbml0aXZlIGluIHN1Z2dlc3RpbmcgdGhhdCBuZWl0aGVyIG9uZSBvZiB0aG9zZSBjaXJjdW1zdGFudGlhbCBmYWN0b3JzIGhhcyBhIHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcCB3aXRoIGEgcGxheWVyJ3MgbWludXRlcyBwZXIgZ2FtZS4KCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30KQU5PVkFfbW9kZWwgPSBhb3YoTVAgfiBQb3MgKiBUbSwgZGF0YSA9IFJlZHVjZWRfUGxheW9mZl9EYXRhKQpzdW1tYXJ5KEFOT1ZBX21vZGVsKQpgYGAKCmBgYHtyfQpBTk9WQV9TdW1tYXJ5X1RhYmxlID0gc3VtbWFyeShBTk9WQV9tb2RlbClbWzFdXQoKIyBQcmludCBhcyBtYXJrZG93biB0YWJsZQprYWJsZShBTk9WQV9TdW1tYXJ5X1RhYmxlLCBkaWdpdHMgPSA0LCBjYXB0aW9uID0gIkFOT1ZBIFRhYmxlOiBNUCB+IFBvcyAqIFRtIikKYGBgCgojIyMgQ2hlY2tpbmcgQU5PVkEgTW9kZWwgQXNzdW1wdGlvbnMKRGVzcGl0ZSB0aGUgZmluZGluZ3Mgb2YgbXkgQU5PVkEgbW9kZWwgYmVpbmcgcXVpdGUgc3Ryb25nLCBJIHN0aWxsIHdhbnRlZCB0byByZXZpZXcgdGhlIGRhdGEgdG8gZW5zdXJlIHRoYXQgbm8gZnVuZGFtZW50YWwgYXNzdW1wdGlvbnMgZm9yIHByb3BlciBBTk9WQSBtb2RlbGluZyB3ZXJlIHZpb2xhdGVkLiBUaGUgcmVzdWx0cyBvZiB0aGF0IHJldmlldyB3ZXJlIG1peGVkLiAKCkkgcGVyZm9ybWVkIGEgc2VyaWVzIG9mIFNoYXBpcm8gV2lsayB0ZXN0cyB0byBkZXRlcm1pbmUgaWYgcGxheWVycycgcmVjb3JkZWQgbWludXRlcyBwZXIgZ2FtZSB3ZXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHdoZW4gZ3JvdXBpbmcgdGhlc2Ugb2JzZXJ2YXRpb25zLCBmaXJzdCBieSB0ZWFtIGFuZCB0aGVuIGJ5IHBvc2l0aW9uLiBSZWdhcmRpbmcgdGVhbXMsIGZpdmUgb2YgdGhlIHNpeHRlZW4gZGlkIG5vdCBnaXZlIHRoZWlyIHBsYXllcnMgYSBub3JtYWxseSBkaXN0cmlidXRlZCBhbW91bnQgb2YgcGxheWluZyB0aW1lLiBUaG9zZSB0ZWFtcyB3b3VsZCBiZSB0aGUgTmV0cywgQ2F2YWxpZXJzLCBOdWdnZXRzLCBMYWtlcnMgYW5kIFNpeGVycy4gQW5kIHdoZW4gZ3JvdXBlZCBieSBwb3NpdGlvbiwgdGhlIGRhdGEgc2hvd2VkIHRoYXQgcGxheWluZyB0aW1lIHdhcyBjZXJ0YWlubHkgbm90IGRpc3RyaWJ1dGVkIGluIGEgbm9ybWFsIG1hbm5lci4KCkFzIGZvciB0aGUgQU5PVkEgY29uZGl0aW9uIG9mIHZhcmlhbmNlIGVxdWFsaXR5LCB0aGVyZSB3YXMgb3ZlcndoZWxtaW5nIGV2aWRlbmNlIHRoYXQgdGhlIHZhcmlhbmNlIG9mIG1pbnV0ZXMgcGVyIGdhbWUgd2FzIGVxdWFsIGFjcm9zcyBib3RoIHRlYW1zIGFuZCBwb3NpdGlvbnMuCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30KYnkoTVAsIFRtLCBzaGFwaXJvLnRlc3QpCmJ5KE1QLCBQb3MsIHNoYXBpcm8udGVzdCkKCmJhcnRsZXR0LnRlc3QoTVAgfiBUbSwgZGF0YSA9IFJlZHVjZWRfUGxheW9mZl9EYXRhKQpiYXJ0bGV0dC50ZXN0KE1QIH4gUG9zLCBkYXRhID0gUmVkdWNlZF9QbGF5b2ZmX0RhdGEpCmBgYAoKIyMjIEtydXNrYWwtV2FsbGlzLUggVGVzdApHaXZlbiB0aGUgbWl4ZWQgcmVzdWx0cyBvZiBteSBBTk9WQSBhc3N1bXB0aW9uIGNoZWNrLCBJIGNob3NlIHRvIHBlcmZvcm0gYSBub25wYXJhbWV0cmljIEtydXNrYWwtV2FsbGlzLUggVGVzdCBpbiBvcmRlciB0byBlbnN1cmUgdGhlIHZhbGlkaXR5IG9mIG15IEFOT1ZBIG1vZGVsJ3MgZmluZGluZ3MgdGhhdCBhIHBsYXllcidzIHRlYW0gYW5kIHBvc2l0aW9uIHN0YXR1cyBkbyBub3QgcGxheSBhIHNpZ25pZmljYW50IHJvbGUgaW4gaGlzIHBsYXlpbmcgdGltZS4gVGhlIGZpbmRpbmdzIG9mIHRoZSBLcnVza2FsLVdhbGxpcy1IIFRlc3Qgd2VyZSBpbiBhbGlnbm1lbnQgd2l0aCB0aGUgQU5PVkEgbW9kZWwncyByZXN1bHRzLCByZXBvcnRpbmcgbmVpdGhlciBhcyBhIHNpZ25pZmljYW50IGZhY3RvciBpbiBwcmVkaWN0aW5nIGEgcGxheWVyJ3MgbWludXRlcyBwZXIgZ2FtZS4KYGBge3J9CmtydXNrYWwudGVzdChNUCB+IFRtLCBkYXRhID0gUmVkdWNlZF9QbGF5b2ZmX0RhdGEpCmtydXNrYWwudGVzdChNUCB+IFBvcywgZGF0YSA9IFJlZHVjZWRfUGxheW9mZl9EYXRhKQpgYGAKCiMjIENvbmNsdXNpb24KVWx0aW1hdGVseSwgdGhlIGZpbmRpbmdzIG9mIHRvZGF5J3MgYW5hbHlzaXMgY2FuIGJlIHN1bW1hcml6ZWQgYnkgdGhlIHN0YXRlbWVudCB0aGF0IHRoZXJlIGlzIGEgZ3JlYXQgZGVhbCBvZiBldmlkZW5jZSB0aGF0IHNjb3JpbmcsIHJlYm91bmRpbmcgYW5kIHN0ZWFsaW5nIHBsYXlzIGEgcm9sZSBpbiBob3cgbXVjaCBwbGF5aW5nIHRpbWUgYW4gTkJBIHBsYXllciByZWNlaXZlcyBpbiB0aGUgcG9zdHNlYXNvbi4gV2hpbGUgYWx0ZXJuYXRpdmVseSwgdGhlcmUgaXMgcHJhY3RpY2FsbHkgbm8gc3RhdGlzdGljYWwgZXZpZGVuY2UgdGhhdCBhIHBsYXllcidzIGFzc2lzdHMnIGF2ZXJhZ2UsIGFnZSwgcG9zaXRpb24gb24gdGhlIGNvdXJ0IG9yIHRlYW0gaGF2ZSBzdWNoIGEgcmVsYXRpb25zaGlwIHdpdGggbWludXRlcyBwbGF5ZWQuIFdoaWxlIHRoZXJlIHdhcyBzb21lIHNsaWdodCB2YXJpYXRpb24gYmV0d2VlbiB0aGUgYmFzZSBtb2RlbCwgcHJlLXRyYW5zZm9ybWF0aW9uIHN0ZXB3aXNlIG1vZGVsIGFuZCBwb3N0LXRyYW5zZm9ybWF0aW9uIHN0ZXB3aXNlIG1vZGVsLCBpdCBpcyBzYWZlIHRvIGVzdGltYXRlIHRoZSBmb2xsb3dpbmcuIEZvciBldmVyeSBhZGRpdGlvbmFsIHBvaW50IHBlciBnYW1lIGF2ZXJhZ2VkLCBhIHBsYXllciB3aWxsIHJlY2VpdmUgYW4gYWRkaXRpb25hbCAwLjg0IG1pbnV0ZXMgb2YgcGxheWluZyB0aW1lLiBIZSBtYXkgYWxzbyByZWNlaXZlIGFuIGFkZGl0aW9uYWwgMS4yIG1pbnV0ZXMgcGVyIGdhbWUgZm9yIGEgb25lIHVuaXQgaW5jcmVhc2UgaW4gcmVib3VuZGluZyBhdmVyYWdlLCBhbmQgYSBib29zdCBvZiA1LjggbWludXRlcyBwZXIgZ2FtZSBmb3IgZXZlcnkgYWRkaXRpb25hbCBzdGVhbCBhdmVyYWdlZCBwZXIgZ2FtZS4KCiMjIFJlZmVyZW5jZXM6Ck9yaWdpbmFsIERhdGFzZXQgU291cmNlOiA8aHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9kYXRhc2V0cy92aXZvdmluY28vMjAyMjIwMjMtbmJhLXBsYXllci1zdGF0cy1yZWd1bGFyPgoKRGF0YXNldCBEb3dubG9hZCBMaW5rIHZpYSBHaXRodWI6Cmh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9DaHJpc0IyMzIzL1NUQTMyMS9tYWluL1BsYXlvZmZfRGF0YS5jc3YgCgpNeSBQcmV2aW91cyBBbmFseXNpczogaHR0cHM6Ly9ycHVicy5jb20vQ2hyaXNfQmFobS8xMzQ0NDY4