#Introduction This project analyzes WNBA 2025 box score data with the goal of building a regression model to predict team score for the team Mercury. The variables of interest include field goal percentage, total rebounds, three-point field goal percentage, and steals.

After finding the best predictive model, we will use it to estimate team score for a “median” game for team Mercury where all variables are set to their median values.

1 Data

The data set was first cleaned by removing non-representative data including the All-Star team and team USA. The data was then grouped by team to find the means and standard deviations of the variables being observed. A subset of the data was created for the Mercury team which was grouped by game outcome (win/loss) to compare performance differences between wins and losses.

The league-wide summary table provides context for overall performance, while the team-specific table highlights how team Mercury differs from the league.

summary %>%
  kbl(digits=2,caption = "WNBA 2025 Stats") %>%
  kable_classic(full_width = F, html_font = "Cambria")
WNBA 2025 Stats
team_name mean_score sd_score mean_fg_pct sd_fg_pct mean_rbds sd_rbds mean_3pt_pct sd_3pt_pct mean_steals sd_steals
Aces 85.52 9.56 45.27 5.82 33.78 5.88 35.27 7.08 6.80 2.67
Dream 76.93 10.59 41.28 6.78 35.95 4.41 30.83 9.32 7.14 2.82
Fever 84.50 10.17 45.56 5.38 35.10 5.49 35.00 8.99 5.88 2.29
Liberty 84.98 9.92 44.53 5.61 36.90 5.77 35.38 10.06 7.75 2.19
Lynx 82.36 11.39 45.21 6.34 33.15 5.06 37.80 9.43 8.36 3.17
Mercury 81.93 12.60 44.28 7.34 32.26 5.39 32.97 10.34 6.55 2.12
Mystics 79.30 8.69 43.36 4.82 31.85 4.66 36.64 8.69 7.28 2.24
Sky 77.40 9.62 42.44 5.22 36.60 5.57 31.74 11.62 7.00 3.30
Sparks 78.40 10.57 42.63 6.15 32.67 5.52 32.09 11.00 7.30 2.78
Storm 82.67 9.65 43.43 5.39 34.67 6.02 28.35 9.03 9.24 3.27
Sun 80.36 9.89 44.30 5.28 33.43 4.62 32.84 11.67 7.89 3.29
Wings 84.20 11.47 44.47 5.24 34.75 4.65 32.06 11.75 7.12 2.95
#Table for entire WNBA League

result %>%
  kbl(digits=2,caption = "WNBA 2025 Mercury Stats") %>%
  kable_classic(full_width = F, html_font = "Cambria")
WNBA 2025 Mercury Stats
result mean_score sd_score mean_fg_pct sd_fg_pct mean_rbds sd_rbds mean_3pt_pct sd_3pt_pct mean_steals sd_steals
Loss 75.65 12.42 40.68 6.66 31.39 5.25 29.33 9.99 6.13 1.82
Win 89.53 7.85 48.65 5.63 33.32 5.51 37.37 9.18 7.05 2.39
#Table for my WNBA team.

2 Box Plot

The following box plot was created to compare the distribution of team scores between wins and losses. The distributions show that higher scores are generally associated with wins, while lower scores are more common in losses. This suggests that teams with higher scoring capabilities will have higher win rates.

p = my_team %>%
  ggplot(aes(x = team_score, fill = result)) +
  geom_histogram(color = "#e9ecef", alpha = 0.6, position = "identity", binwidth = 4) +
  scale_fill_manual(values = c("#69b3a2", "#404080")) +
  labs(
    title = "Distribution of Team Scores",
    fill = "")

boxplot(team_score ~ result, data = my_team, notch = FALSE,
        col = c('lightblue','lightgreen'),
        main = "Points Scored by Game Result",
        xlab = "result", ylab = "Points")

3 First Order Models

A first-order multiple linear regression model (Model 1) was constructed using field goal percentage, total rebounds, three-point field goal percentage, and steals as predictors of team score.

Correlation coefficients and Variance Inflation Factor (VIF) values were used to determine if there was any multicollinearity in the variables. Since no pairs of variables exhibited extremely high correlation (|r| > 0.8) and VIF values were within acceptable limits, no variables were removed. As a result, Model 2 remained the same as Model 1.

model1 = lm(team_score~field_goal_pct+total_rebounds+
            three_point_field_goal_pct+steals, data = my_team)

cor_data = my_team %>%
  select(team_score, field_goal_pct, total_rebounds, 
         three_point_field_goal_pct, steals)

cor(cor_data)

vif(model1)

model2 = lm(team_score~field_goal_pct+total_rebounds+
            three_point_field_goal_pct+steals, data = my_team)

4 Interaction Model

A full interaction model (Model 3) was constructed including all interaction terms. Each interaction term was evaluated at the 15% significance level.

Only the interaction between field goal percentage and three-point field goal percentage was found to be statistically significant. All other interaction terms were removed, resulting in the reduced interaction model (Model 4), which retains all variables and the significant interaction term.

model3 = lm(team_score ~ (field_goal_pct + total_rebounds + 
                              three_point_field_goal_pct + steals)^2, 
                 data = my_team)

model4 = lm(team_score ~ field_goal_pct + total_rebounds + 
                    three_point_field_goal_pct + steals +
                    field_goal_pct:three_point_field_goal_pct,
                    data = my_team)

model4sum = summary(model4)

library(stargazer)
stargazer(model4, type="html")
Dependent variable:
team_score
field_goal_pct 1.510***
(0.345)
total_rebounds 0.036
(0.195)
three_point_field_goal_pct 0.934**
(0.385)
steals 1.282***
(0.442)
field_goal_pct:three_point_field_goal_pct -0.013
(0.009)
Constant -5.582
(17.205)
Observations 42
R2 0.810
Adjusted R2 0.784
Residual Std. Error 5.860 (df = 36)
F Statistic 30.693*** (df = 5; 36)
Note: p<0.1; p<0.05; p<0.01

\(~\) \(~\)

After all models were run and a reduction completed, my model is
team_score= -5.5822088 + 1.5104082 * field_goal_pct + 0.0358159 * total_rebounds + 0.9335949 * three_point_field_goal_pct + 1.2823549 * steals + -0.0130526 * field_goal_pct:three_point_field_goal_pct

This model significantly predicts team score, F(5,36) = 30.6931812, p<.0001, adjusted R^2= 0.7836022

5 Residual Analysis

Residual analysis was conducted to evaluate the assumptions of the regression model.

The histogram of residuals indicates that the residuals slightly skewn to the right but are approximately normally distributed. The residuals versus fitted plot shows no clear pattern and a consistent spread, suggesting that the assumption of linearity and constant variance is reasonable.

The studentized residual plot was used to identify potential outliers, with a majority of observations falling within acceptable bounds. The points that fell out of bounds are the 2024-08-15 game against chicago-sky and the 2024-06-09 game against dallas-wings.

The leverage plot indicates that two observations have relatively high leverage, suggesting they fall outside the normal range of the data. These points could influence the regression model and are notable. The points with high leverage are the 2024-07-01 game against connecticut-sun, the 2024-06-02 game against los-angeles-sparks, and the 2024-05-28 game against connecticut-sun.

The Cook’s distance plot identifies two observations with relatively high influence. These points have a notable impact on the fitted regression model and may disproportionately affect the estimated coefficients. The points with high impact include 2024-08-15 game against chicago-sky and 2024-05-25 game against dallas-wings. Despite the presence of these influential and high-leverage points, their small number means they do not substantially distort the overall model.

hist(residuals(model4),
     main = "Histogram of Residuals",
     xlab = "Residuals")

plot(fitted(model4), residuals(model4),
     main = "Residuals vs Fitted",
     xlab = "Fitted Values",
     ylab = "Residuals")
abline(h = 0)

plot(fitted(model4), rstudent(model4),
     main = "Studentized Residuals vs Fitted",
     xlab = "Fitted Values",
     ylab = "Studentized Residuals")
abline(h = 0)
abline(h = c(-2, 2), lty = 2)

plot(hatvalues(model4),
     main = "Leverage Values",
     ylab = "Leverage",
     xlab = "Observation")
abline(h = 2*mean(hatvalues(model4)), lty = 2)

plot(cooks.distance(model4),
     type = "h",
     main = "Cook's Distance",
     ylab = "Cook's Distance",
     xlab = "Observation")
abline(h = 4/length(cooks.distance(model4)), lty = 2)

#olsrr plots and more
#correlation cant correlate character variables, take out 
# Add diagnostic values to your dataset
my_team_diag = my_team %>%
  mutate(
    residuals = resid(model1),
    student_resid = rstudent(model1),
    leverage = hatvalues(model1),
    cooks = cooks.distance(model1)
  )

# Get sample size and number of predictors
n <- nrow(my_team_diag)
k <- length(coef(model1)) - 1

# 1. Outliers (studentized residuals)
outliers <- my_team_diag %>%
  filter(abs(student_resid) > 2) %>%
  select(game_date, opponent_team_slug, student_resid)

# 2. High leverage points
high_leverage <- my_team_diag %>%
  filter(leverage > 2 * (k + 1) / n) %>%
  select(game_date, opponent_team_slug, leverage)

# 3. Influential points (Cook's Distance)
influential <- my_team_diag %>%
  filter(cooks > 4 / n) %>%
  select(game_date, opponent_team_slug, cooks)

# View outliers, high leverage, influential points for analysis
outliers
high_leverage
influential

6 Prediction

The median values of each predictor variable were computed and used to estimate the team score for a “median” game using Model 4.

All median values fall within the experimental region and are therefore reliable.

I built the model to predict my teams points for a game in which they achieve the median value for each variable. The predicted score is 81.6448743, with 95% confidence interval (79.5058191,83.7839294)

LS0tDQp0aXRsZTogIklTUCBTdGF0aXN0aWNhbCBBbmFseXNpcyBSZXBvcnQiDQphdXRob3I6ICJEaXZhbiBkdSBUb2l0Ig0KZGF0ZTogImByIGZvcm1hdChTeXMuRGF0ZSgpLCAnJUIgJWQsICVZJylgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogMw0KICAgIGZpZ19oZWlnaHQ6IDMNCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMiB7IC8qIEhlYWRlciAyIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE2cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTRweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogQWRkIGRvdHMgYWZ0ZXIgbnVtYmVyZWQgaGVhZGVycyAqLw0KLmhlYWRlci1zZWN0aW9uLW51bWJlcjo6YWZ0ZXIgew0KICBjb250ZW50OiAiLiI7DQoNCmJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCi5oaWdobGlnaHRtZSB7IGJhY2tncm91bmQtY29sb3I6eWVsbG93OyB9DQoNCnAgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCn0NCmBgYA0KDQojSW50cm9kdWN0aW9uDQpUaGlzIHByb2plY3QgYW5hbHl6ZXMgV05CQSAyMDI1IGJveCBzY29yZSBkYXRhIHdpdGggdGhlIGdvYWwgb2YgYnVpbGRpbmcgYSByZWdyZXNzaW9uIG1vZGVsIHRvIHByZWRpY3QgdGVhbSBzY29yZSBmb3IgdGhlIHRlYW0gTWVyY3VyeS4gVGhlIHZhcmlhYmxlcyBvZiBpbnRlcmVzdCBpbmNsdWRlIGZpZWxkIGdvYWwgcGVyY2VudGFnZSwgdG90YWwgcmVib3VuZHMsIHRocmVlLXBvaW50IGZpZWxkIGdvYWwgcGVyY2VudGFnZSwgYW5kIHN0ZWFscy4gDQoNCkFmdGVyIGZpbmRpbmcgdGhlIGJlc3QgcHJlZGljdGl2ZSBtb2RlbCwgd2Ugd2lsbCB1c2UgaXQgdG8gZXN0aW1hdGUgdGVhbSBzY29yZSBmb3IgYSDigJxtZWRpYW7igJ0gZ2FtZSBmb3IgdGVhbSBNZXJjdXJ5IHdoZXJlIGFsbCB2YXJpYWJsZXMgYXJlIHNldCB0byB0aGVpciBtZWRpYW4gdmFsdWVzLg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GfQ0Kc2V0d2QoIkM6L1VzZXJzL0RpdmFuL0Rvd25sb2Fkcy9QZXJzb25hbCBGb2xkZXJzL1NwcmluZyAyMDI2L1NUQTMxOS0gQXBwbGllZCBTdGF0aXN0aWNzL1NUQTMxOSBQcm9qZWN0IEZpbGUiKQ0KDQpkYXRhPXJlYWQuY3N2KCJXTkJBXzIwMjVfYm94LXNjb3Jlcy5jc3YiLCBoZWFkZXI9VCkNCg0KbGlicmFyeShnZ3Bsb3QyKQ0KI2hpc3RvZ3JhbSBtYWRlIHVzaW5nIGdncGxvdDINCmxpYnJhcnkoY2FyKQ0KI1ZJRiBmdW5jdGlvbiBpbiB0aGUgY2FyIHBhY2thZ2UNCmxpYnJhcnkoZHBseXIpDQojc2VsZWN0IGZ1bmN0aW9uIGluIGRwbHlyDQpsaWJyYXJ5KG9sc3JyKQ0KI2NoZWNraW5nIGZvciB2aWYgYW5kIG1vZGVsIGFzc3VtcHRpb25zDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQojd2VsbCBmb3JtYXR0ZWQgZ3JhcGhzIGluIGthYmxlRXh0cmENCg0KYGBgDQoNCg0KDQpgYGB7ciB3cmFuZ2luZywgaW5jbHVkZT1GfQ0Kc3VtbWFyeShkYXRhKQ0KDQojQWxsIFdOQkEgdGVhbXMgaW5jbHVkZWQsIHJlbW92ZSBzY29yZXMgZnJvbSBBbGwgc3RhciBnYW1lDQpkYXRhID0gZGF0YSAlPiUgDQogIGZpbHRlcih0ZWFtX25hbWUgIT0gIlRlYW0gV05CQSIgJiB0ZWFtX25hbWUgIT0gIlRlYW0gVVNBIikNCg0KI0dyb3VwIGRhdGEgYnkgdGVhbSwgZmluZCBtZWFuIGFuZCBTVEQgb2YgYWxsIHZhcmlhYmxlDQpzdW1tYXJ5ID0gZGF0YSAlPiUNCiAgZ3JvdXBfYnkodGVhbV9uYW1lKSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fc2NvcmU9bWVhbih0ZWFtX3Njb3JlKSwgc2Rfc2NvcmU9c2QodGVhbV9zY29yZSksDQogICAgICAgICAgICBtZWFuX2ZnX3BjdD1tZWFuKGZpZWxkX2dvYWxfcGN0KSwgc2RfZmdfcGN0PXNkKGZpZWxkX2dvYWxfcGN0KSwNCiAgICAgICAgICAgIG1lYW5fcmJkcz1tZWFuKHRvdGFsX3JlYm91bmRzKSwgc2RfcmJkcz1zZCh0b3RhbF9yZWJvdW5kcyksDQogICAgICAgICAgICBtZWFuXzNwdF9wY3Q9bWVhbih0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCksIA0KICAgICAgICAgICAgc2RfM3B0X3BjdD1zZCh0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCksDQogICAgICAgICAgICBtZWFuX3N0ZWFscz1tZWFuKHN0ZWFscyksIHNkX3N0ZWFscz1zZChzdGVhbHMpKQ0KICANCiNTZWxlY3Qgb25seSB2YXJpYWJsZXMgd2UgbmVlZCBhbmQgZmlsdGVyIG9uIG15IHRlYW0NCg0KbXlfdGVhbSA9IGRhdGEgJT4lDQogICAgbXV0YXRlKHJlc3VsdCA9IGNhc2Vfd2hlbih0ZWFtX3dpbm5lciA9PSBUUlVFIH4gIldpbiIsdGVhbV93aW5uZXIgPT0gRkFMU0UgfiAiTG9zcyIpKSAlPiUNCiAgZmlsdGVyKHRlYW1fbmFtZSA9PSAiTWVyY3VyeSIpICU+JQ0KICBzZWxlY3QodGVhbV9uYW1lLCB0ZWFtX3Njb3JlLCBmaWVsZF9nb2FsX3BjdCwgdG90YWxfcmVib3VuZHMsDQogICAgICAgICB0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCwgc3RlYWxzLCB0ZWFtX3dpbm5lciwgZ2FtZV9kYXRlLA0KICAgICAgICAgb3Bwb25lbnRfdGVhbV9zbHVnLCByZXN1bHQpDQogIA0KICANCg0KDQojU3VtbWFyaXNlIGFsbCB2YXJpYWJsZXMgd2l0aCBtZWFuIGFuZCBzZA0KcmVzdWx0ID0gbXlfdGVhbSAlPiUNCiAgZ3JvdXBfYnkocmVzdWx0KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fc2NvcmU9bWVhbih0ZWFtX3Njb3JlKSwgc2Rfc2NvcmU9c2QodGVhbV9zY29yZSksDQogICAgICAgICAgICBtZWFuX2ZnX3BjdD1tZWFuKGZpZWxkX2dvYWxfcGN0KSwgc2RfZmdfcGN0PXNkKGZpZWxkX2dvYWxfcGN0KSwNCiAgICAgICAgICAgIG1lYW5fcmJkcz1tZWFuKHRvdGFsX3JlYm91bmRzKSwgc2RfcmJkcz1zZCh0b3RhbF9yZWJvdW5kcyksDQogICAgICAgICAgICBtZWFuXzNwdF9wY3Q9bWVhbih0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCksIA0KICAgICAgICAgICAgc2RfM3B0X3BjdD1zZCh0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCksDQogICAgICAgICAgICBtZWFuX3N0ZWFscz1tZWFuKHN0ZWFscyksIHNkX3N0ZWFscz1zZChzdGVhbHMpKQ0KDQoNCg0KYGBgDQoNCiMgRGF0YQ0KDQpUaGUgZGF0YSBzZXQgd2FzIGZpcnN0IGNsZWFuZWQgYnkgcmVtb3Zpbmcgbm9uLXJlcHJlc2VudGF0aXZlIGRhdGEgaW5jbHVkaW5nIHRoZSBBbGwtU3RhciB0ZWFtIGFuZCB0ZWFtIFVTQS4gVGhlIGRhdGEgd2FzIHRoZW4gZ3JvdXBlZCBieSB0ZWFtIHRvIGZpbmQgdGhlIG1lYW5zIGFuZCBzdGFuZGFyZCBkZXZpYXRpb25zIG9mIHRoZSB2YXJpYWJsZXMgYmVpbmcgb2JzZXJ2ZWQuDQpBIHN1YnNldCBvZiB0aGUgZGF0YSB3YXMgY3JlYXRlZCBmb3IgdGhlIE1lcmN1cnkgdGVhbSB3aGljaCB3YXMgZ3JvdXBlZCBieSBnYW1lIG91dGNvbWUgKHdpbi9sb3NzKSB0byBjb21wYXJlIHBlcmZvcm1hbmNlIGRpZmZlcmVuY2VzIGJldHdlZW4gd2lucyBhbmQgbG9zc2VzLg0KDQpUaGUgbGVhZ3VlLXdpZGUgc3VtbWFyeSB0YWJsZSBwcm92aWRlcyBjb250ZXh0IGZvciBvdmVyYWxsIHBlcmZvcm1hbmNlLCB3aGlsZSB0aGUgdGVhbS1zcGVjaWZpYyB0YWJsZSBoaWdobGlnaHRzIGhvdyB0ZWFtIE1lcmN1cnkgZGlmZmVycyBmcm9tIHRoZSBsZWFndWUuDQoNCmBgYHtyIFRhYmxlc30NCg0Kc3VtbWFyeSAlPiUNCiAga2JsKGRpZ2l0cz0yLGNhcHRpb24gPSAiV05CQSAyMDI1IFN0YXRzIikgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IEYsIGh0bWxfZm9udCA9ICJDYW1icmlhIikNCiNUYWJsZSBmb3IgZW50aXJlIFdOQkEgTGVhZ3VlDQoNCnJlc3VsdCAlPiUNCiAga2JsKGRpZ2l0cz0yLGNhcHRpb24gPSAiV05CQSAyMDI1IE1lcmN1cnkgU3RhdHMiKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gRiwgaHRtbF9mb250ID0gIkNhbWJyaWEiKQ0KDQojVGFibGUgZm9yIG15IFdOQkEgdGVhbS4NCg0KYGBgDQoNCiMgQm94IFBsb3QNCg0KVGhlIGZvbGxvd2luZyBib3ggcGxvdCB3YXMgY3JlYXRlZCB0byBjb21wYXJlIHRoZSBkaXN0cmlidXRpb24gb2YgdGVhbSBzY29yZXMgYmV0d2VlbiB3aW5zIGFuZCBsb3NzZXMuIFRoZSBkaXN0cmlidXRpb25zIHNob3cgdGhhdCBoaWdoZXIgc2NvcmVzIGFyZSBnZW5lcmFsbHkgYXNzb2NpYXRlZCB3aXRoIHdpbnMsIHdoaWxlIGxvd2VyIHNjb3JlcyBhcmUgbW9yZSBjb21tb24gaW4gbG9zc2VzLiBUaGlzIHN1Z2dlc3RzIHRoYXQgdGVhbXMgd2l0aCBoaWdoZXIgc2NvcmluZyBjYXBhYmlsaXRpZXMgd2lsbCBoYXZlIGhpZ2hlciB3aW4gcmF0ZXMuIA0KDQpgYGB7ciBHcmFwaHMsIEluY2x1ZGU9VCwgZmlnLndpZHRoPTUgLCBmaWcuaGVpZ2h0PTV9DQoNCnAgPSBteV90ZWFtICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSB0ZWFtX3Njb3JlLCBmaWxsID0gcmVzdWx0KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShjb2xvciA9ICIjZTllY2VmIiwgYWxwaGEgPSAwLjYsIHBvc2l0aW9uID0gImlkZW50aXR5IiwgYmlud2lkdGggPSA0KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM2OWIzYTIiLCAiIzQwNDA4MCIpKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIFRlYW0gU2NvcmVzIiwNCiAgICBmaWxsID0gIiIpDQoNCmJveHBsb3QodGVhbV9zY29yZSB+IHJlc3VsdCwgZGF0YSA9IG15X3RlYW0sIG5vdGNoID0gRkFMU0UsDQogICAgICAgIGNvbCA9IGMoJ2xpZ2h0Ymx1ZScsJ2xpZ2h0Z3JlZW4nKSwNCiAgICAgICAgbWFpbiA9ICJQb2ludHMgU2NvcmVkIGJ5IEdhbWUgUmVzdWx0IiwNCiAgICAgICAgeGxhYiA9ICJyZXN1bHQiLCB5bGFiID0gIlBvaW50cyIpDQoNCmBgYA0KDQojIEZpcnN0IE9yZGVyIE1vZGVscw0KDQpBIGZpcnN0LW9yZGVyIG11bHRpcGxlIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsIChNb2RlbCAxKSB3YXMgY29uc3RydWN0ZWQgdXNpbmcgZmllbGQgZ29hbCBwZXJjZW50YWdlLCB0b3RhbCByZWJvdW5kcywgdGhyZWUtcG9pbnQgZmllbGQgZ29hbCBwZXJjZW50YWdlLCBhbmQgc3RlYWxzIGFzIHByZWRpY3RvcnMgb2YgdGVhbSBzY29yZS4NCg0KQ29ycmVsYXRpb24gY29lZmZpY2llbnRzIGFuZCBWYXJpYW5jZSBJbmZsYXRpb24gRmFjdG9yIChWSUYpIHZhbHVlcyB3ZXJlIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIHRoZXJlIHdhcyBhbnkgbXVsdGljb2xsaW5lYXJpdHkgaW4gdGhlIHZhcmlhYmxlcy4gU2luY2Ugbm8gcGFpcnMgb2YgdmFyaWFibGVzIGV4aGliaXRlZCBleHRyZW1lbHkgaGlnaCBjb3JyZWxhdGlvbiAofHJ8ID4gMC44KSBhbmQgVklGIHZhbHVlcyB3ZXJlIHdpdGhpbiBhY2NlcHRhYmxlIGxpbWl0cywgbm8gdmFyaWFibGVzIHdlcmUgcmVtb3ZlZC4gQXMgYSByZXN1bHQsIE1vZGVsIDIgcmVtYWluZWQgdGhlIHNhbWUgYXMgTW9kZWwgMS4NCg0KYGBge3IgRmlyc3QgT3JkZXIgTW9kZWwsIHJlc3VsdHMgPSAnaGlkZScsIElubGN1ZGU9Rn0NCg0KDQptb2RlbDEgPSBsbSh0ZWFtX3Njb3JlfmZpZWxkX2dvYWxfcGN0K3RvdGFsX3JlYm91bmRzKw0KICAgICAgICAgICAgdGhyZWVfcG9pbnRfZmllbGRfZ29hbF9wY3Qrc3RlYWxzLCBkYXRhID0gbXlfdGVhbSkNCg0KY29yX2RhdGEgPSBteV90ZWFtICU+JQ0KICBzZWxlY3QodGVhbV9zY29yZSwgZmllbGRfZ29hbF9wY3QsIHRvdGFsX3JlYm91bmRzLCANCiAgICAgICAgIHRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0LCBzdGVhbHMpDQoNCmNvcihjb3JfZGF0YSkNCg0KdmlmKG1vZGVsMSkNCg0KbW9kZWwyID0gbG0odGVhbV9zY29yZX5maWVsZF9nb2FsX3BjdCt0b3RhbF9yZWJvdW5kcysNCiAgICAgICAgICAgIHRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0K3N0ZWFscywgZGF0YSA9IG15X3RlYW0pDQoNCmBgYA0KDQojIEludGVyYWN0aW9uIE1vZGVsDQoNCkEgZnVsbCBpbnRlcmFjdGlvbiBtb2RlbCAoTW9kZWwgMykgd2FzIGNvbnN0cnVjdGVkIGluY2x1ZGluZyBhbGwgaW50ZXJhY3Rpb24gdGVybXMuIEVhY2ggaW50ZXJhY3Rpb24gdGVybSB3YXMgZXZhbHVhdGVkIGF0IHRoZSAxNSUgc2lnbmlmaWNhbmNlIGxldmVsLg0KDQpPbmx5IHRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIGZpZWxkIGdvYWwgcGVyY2VudGFnZSBhbmQgdGhyZWUtcG9pbnQgZmllbGQgZ29hbCBwZXJjZW50YWdlIHdhcyBmb3VuZCB0byBiZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LiBBbGwgb3RoZXIgaW50ZXJhY3Rpb24gdGVybXMgd2VyZSByZW1vdmVkLCByZXN1bHRpbmcgaW4gdGhlIHJlZHVjZWQgaW50ZXJhY3Rpb24gbW9kZWwgKE1vZGVsIDQpLCB3aGljaCByZXRhaW5zIGFsbCB2YXJpYWJsZXMgYW5kIHRoZSBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiB0ZXJtLg0KDQpgYGB7ciBJbnRlcmFjdGlvbiBNb2RlbCwgcmVzdWx0cz0nYXNpcycsIEluY2x1ZGU9RiwgbWVzc2FnZT1GfQ0KDQptb2RlbDMgPSBsbSh0ZWFtX3Njb3JlIH4gKGZpZWxkX2dvYWxfcGN0ICsgdG90YWxfcmVib3VuZHMgKyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0ICsgc3RlYWxzKV4yLCANCiAgICAgICAgICAgICAgICAgZGF0YSA9IG15X3RlYW0pDQoNCm1vZGVsNCA9IGxtKHRlYW1fc2NvcmUgfiBmaWVsZF9nb2FsX3BjdCArIHRvdGFsX3JlYm91bmRzICsgDQogICAgICAgICAgICAgICAgICAgIHRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0ICsgc3RlYWxzICsNCiAgICAgICAgICAgICAgICAgICAgZmllbGRfZ29hbF9wY3Q6dGhyZWVfcG9pbnRfZmllbGRfZ29hbF9wY3QsDQogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBteV90ZWFtKQ0KDQptb2RlbDRzdW0gPSBzdW1tYXJ5KG1vZGVsNCkNCg0KbGlicmFyeShzdGFyZ2F6ZXIpDQpzdGFyZ2F6ZXIobW9kZWw0LCB0eXBlPSJodG1sIikNCg0KYGBgDQoNCiR+JA0KJH4kDQoNCkFmdGVyIGFsbCBtb2RlbHMgd2VyZSBydW4gYW5kIGEgcmVkdWN0aW9uIGNvbXBsZXRlZCwgbXkgbW9kZWwgaXMgIA0KdGVhbV9zY29yZT0gYHIgbW9kZWw0JGNvZWZmaWNpZW50c1sxXWAgKyBgciBtb2RlbDQkY29lZmZpY2llbnRzWzJdYCAqIGZpZWxkX2dvYWxfcGN0ICArIA0KYHIgbW9kZWw0JGNvZWZmaWNpZW50c1szXWAgKiB0b3RhbF9yZWJvdW5kcyArIGByIG1vZGVsNCRjb2VmZmljaWVudHNbNF1gICogdGhyZWVfcG9pbnRfZmllbGRfZ29hbF9wY3QgKyBgciBtb2RlbDQkY29lZmZpY2llbnRzWzVdYCAqIHN0ZWFscyArIGByIG1vZGVsNCRjb2VmZmljaWVudHNbNl1gICogZmllbGRfZ29hbF9wY3Q6dGhyZWVfcG9pbnRfZmllbGRfZ29hbF9wY3QNCg0KVGhpcyBtb2RlbCBzaWduaWZpY2FudGx5IHByZWRpY3RzIHRlYW0gc2NvcmUsIEYoYHIgbW9kZWw0c3VtJGZzdGF0aXN0aWNbMl1gLGByIG1vZGVsNHN1bSRmc3RhdGlzdGljWzNdYCkgPSBgciBtb2RlbDRzdW0kZnN0YXRpc3RpY1sxXWAsIHA8LjAwMDEsIGFkanVzdGVkIFJeMj0gYHIgbW9kZWw0c3VtJGFkai5yLnNxdWFyZWRgDQoNCiMgUmVzaWR1YWwgQW5hbHlzaXMNCg0KUmVzaWR1YWwgYW5hbHlzaXMgd2FzIGNvbmR1Y3RlZCB0byBldmFsdWF0ZSB0aGUgYXNzdW1wdGlvbnMgb2YgdGhlIHJlZ3Jlc3Npb24gbW9kZWwuIA0KDQpUaGUgaGlzdG9ncmFtIG9mIHJlc2lkdWFscyBpbmRpY2F0ZXMgdGhhdCB0aGUgcmVzaWR1YWxzIHNsaWdodGx5IHNrZXduIHRvIHRoZSByaWdodCBidXQgYXJlIGFwcHJveGltYXRlbHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuIFRoZSByZXNpZHVhbHMgdmVyc3VzIGZpdHRlZCBwbG90IHNob3dzIG5vIGNsZWFyIHBhdHRlcm4gYW5kIGEgY29uc2lzdGVudCBzcHJlYWQsIHN1Z2dlc3RpbmcgdGhhdCB0aGUgYXNzdW1wdGlvbiBvZiBsaW5lYXJpdHkgYW5kIGNvbnN0YW50IHZhcmlhbmNlIGlzIHJlYXNvbmFibGUuDQoNClRoZSBzdHVkZW50aXplZCByZXNpZHVhbCBwbG90IHdhcyB1c2VkIHRvIGlkZW50aWZ5IHBvdGVudGlhbCBvdXRsaWVycywgd2l0aCBhIG1ham9yaXR5IG9mIG9ic2VydmF0aW9ucyBmYWxsaW5nIHdpdGhpbiBhY2NlcHRhYmxlIGJvdW5kcy4gVGhlIHBvaW50cyB0aGF0IGZlbGwgb3V0IG9mIGJvdW5kcyBhcmUgdGhlIDIwMjQtMDgtMTUgZ2FtZSBhZ2FpbnN0IGNoaWNhZ28tc2t5IGFuZCB0aGUgMjAyNC0wNi0wOSBnYW1lIGFnYWluc3QJZGFsbGFzLXdpbmdzLg0KDQpUaGUgbGV2ZXJhZ2UgcGxvdCBpbmRpY2F0ZXMgdGhhdCB0d28gb2JzZXJ2YXRpb25zIGhhdmUgcmVsYXRpdmVseSBoaWdoIGxldmVyYWdlLCBzdWdnZXN0aW5nIHRoZXkgZmFsbCBvdXRzaWRlIHRoZSBub3JtYWwgcmFuZ2Ugb2YgdGhlIGRhdGEuIFRoZXNlIHBvaW50cyBjb3VsZCBpbmZsdWVuY2UgdGhlIHJlZ3Jlc3Npb24gbW9kZWwgYW5kIGFyZSBub3RhYmxlLiBUaGUgcG9pbnRzIHdpdGggaGlnaCBsZXZlcmFnZSBhcmUgdGhlIDIwMjQtMDctMDEJZ2FtZSBhZ2FpbnN0IGNvbm5lY3RpY3V0LXN1biwgdGhlIDIwMjQtMDYtMDIJZ2FtZSBhZ2FpbnN0IGxvcy1hbmdlbGVzLXNwYXJrcywgYW5kIHRoZSAyMDI0LTA1LTI4CWdhbWUgYWdhaW5zdCBjb25uZWN0aWN1dC1zdW4uDQoNClRoZSBDb29r4oCZcyBkaXN0YW5jZSBwbG90IGlkZW50aWZpZXMgdHdvIG9ic2VydmF0aW9ucyB3aXRoIHJlbGF0aXZlbHkgaGlnaCBpbmZsdWVuY2UuIFRoZXNlIHBvaW50cyBoYXZlIGEgbm90YWJsZSBpbXBhY3Qgb24gdGhlIGZpdHRlZCByZWdyZXNzaW9uIG1vZGVsIGFuZCBtYXkgZGlzcHJvcG9ydGlvbmF0ZWx5IGFmZmVjdCB0aGUgZXN0aW1hdGVkIGNvZWZmaWNpZW50cy4gVGhlIHBvaW50cyB3aXRoIGhpZ2ggaW1wYWN0IGluY2x1ZGUgMjAyNC0wOC0xNSBnYW1lIGFnYWluc3QJY2hpY2Fnby1za3kgYW5kIDIwMjQtMDUtMjUgZ2FtZSBhZ2FpbnN0IGRhbGxhcy13aW5ncy4gRGVzcGl0ZSB0aGUgcHJlc2VuY2Ugb2YgdGhlc2UgaW5mbHVlbnRpYWwgYW5kIGhpZ2gtbGV2ZXJhZ2UgcG9pbnRzLCB0aGVpciBzbWFsbCBudW1iZXIgbWVhbnMgdGhleSBkbyBub3Qgc3Vic3RhbnRpYWxseSBkaXN0b3J0IHRoZSBvdmVyYWxsIG1vZGVsLg0KDQpgYGB7ciBSZXNpZHVhbHMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnLGZpZy53aWR0aD01LGZpZy5oZWlnaHQ9NX0NCg0KaGlzdChyZXNpZHVhbHMobW9kZWw0KSwNCiAgICAgbWFpbiA9ICJIaXN0b2dyYW0gb2YgUmVzaWR1YWxzIiwNCiAgICAgeGxhYiA9ICJSZXNpZHVhbHMiKQ0KDQpwbG90KGZpdHRlZChtb2RlbDQpLCByZXNpZHVhbHMobW9kZWw0KSwNCiAgICAgbWFpbiA9ICJSZXNpZHVhbHMgdnMgRml0dGVkIiwNCiAgICAgeGxhYiA9ICJGaXR0ZWQgVmFsdWVzIiwNCiAgICAgeWxhYiA9ICJSZXNpZHVhbHMiKQ0KYWJsaW5lKGggPSAwKQ0KcGxvdChmaXR0ZWQobW9kZWw0KSwgcnN0dWRlbnQobW9kZWw0KSwNCiAgICAgbWFpbiA9ICJTdHVkZW50aXplZCBSZXNpZHVhbHMgdnMgRml0dGVkIiwNCiAgICAgeGxhYiA9ICJGaXR0ZWQgVmFsdWVzIiwNCiAgICAgeWxhYiA9ICJTdHVkZW50aXplZCBSZXNpZHVhbHMiKQ0KYWJsaW5lKGggPSAwKQ0KYWJsaW5lKGggPSBjKC0yLCAyKSwgbHR5ID0gMikNCnBsb3QoaGF0dmFsdWVzKG1vZGVsNCksDQogICAgIG1haW4gPSAiTGV2ZXJhZ2UgVmFsdWVzIiwNCiAgICAgeWxhYiA9ICJMZXZlcmFnZSIsDQogICAgIHhsYWIgPSAiT2JzZXJ2YXRpb24iKQ0KYWJsaW5lKGggPSAyKm1lYW4oaGF0dmFsdWVzKG1vZGVsNCkpLCBsdHkgPSAyKQ0KcGxvdChjb29rcy5kaXN0YW5jZShtb2RlbDQpLA0KICAgICB0eXBlID0gImgiLA0KICAgICBtYWluID0gIkNvb2sncyBEaXN0YW5jZSIsDQogICAgIHlsYWIgPSAiQ29vaydzIERpc3RhbmNlIiwNCiAgICAgeGxhYiA9ICJPYnNlcnZhdGlvbiIpDQphYmxpbmUoaCA9IDQvbGVuZ3RoKGNvb2tzLmRpc3RhbmNlKG1vZGVsNCkpLCBsdHkgPSAyKQ0KI29sc3JyIHBsb3RzIGFuZCBtb3JlDQojY29ycmVsYXRpb24gY2FudCBjb3JyZWxhdGUgY2hhcmFjdGVyIHZhcmlhYmxlcywgdGFrZSBvdXQgDQojIEFkZCBkaWFnbm9zdGljIHZhbHVlcyB0byB5b3VyIGRhdGFzZXQNCm15X3RlYW1fZGlhZyA9IG15X3RlYW0gJT4lDQogIG11dGF0ZSgNCiAgICByZXNpZHVhbHMgPSByZXNpZChtb2RlbDEpLA0KICAgIHN0dWRlbnRfcmVzaWQgPSByc3R1ZGVudChtb2RlbDEpLA0KICAgIGxldmVyYWdlID0gaGF0dmFsdWVzKG1vZGVsMSksDQogICAgY29va3MgPSBjb29rcy5kaXN0YW5jZShtb2RlbDEpDQogICkNCg0KIyBHZXQgc2FtcGxlIHNpemUgYW5kIG51bWJlciBvZiBwcmVkaWN0b3JzDQpuIDwtIG5yb3cobXlfdGVhbV9kaWFnKQ0KayA8LSBsZW5ndGgoY29lZihtb2RlbDEpKSAtIDENCg0KIyAxLiBPdXRsaWVycyAoc3R1ZGVudGl6ZWQgcmVzaWR1YWxzKQ0Kb3V0bGllcnMgPC0gbXlfdGVhbV9kaWFnICU+JQ0KICBmaWx0ZXIoYWJzKHN0dWRlbnRfcmVzaWQpID4gMikgJT4lDQogIHNlbGVjdChnYW1lX2RhdGUsIG9wcG9uZW50X3RlYW1fc2x1Zywgc3R1ZGVudF9yZXNpZCkNCg0KIyAyLiBIaWdoIGxldmVyYWdlIHBvaW50cw0KaGlnaF9sZXZlcmFnZSA8LSBteV90ZWFtX2RpYWcgJT4lDQogIGZpbHRlcihsZXZlcmFnZSA+IDIgKiAoayArIDEpIC8gbikgJT4lDQogIHNlbGVjdChnYW1lX2RhdGUsIG9wcG9uZW50X3RlYW1fc2x1ZywgbGV2ZXJhZ2UpDQoNCiMgMy4gSW5mbHVlbnRpYWwgcG9pbnRzIChDb29rJ3MgRGlzdGFuY2UpDQppbmZsdWVudGlhbCA8LSBteV90ZWFtX2RpYWcgJT4lDQogIGZpbHRlcihjb29rcyA+IDQgLyBuKSAlPiUNCiAgc2VsZWN0KGdhbWVfZGF0ZSwgb3Bwb25lbnRfdGVhbV9zbHVnLCBjb29rcykNCg0KIyBWaWV3IG91dGxpZXJzLCBoaWdoIGxldmVyYWdlLCBpbmZsdWVudGlhbCBwb2ludHMgZm9yIGFuYWx5c2lzDQpvdXRsaWVycw0KaGlnaF9sZXZlcmFnZQ0KaW5mbHVlbnRpYWwNCmBgYA0KDQojIFByZWRpY3Rpb24NCg0KVGhlIG1lZGlhbiB2YWx1ZXMgb2YgZWFjaCBwcmVkaWN0b3IgdmFyaWFibGUgd2VyZSBjb21wdXRlZCBhbmQgdXNlZCB0byBlc3RpbWF0ZSB0aGUgdGVhbSBzY29yZSBmb3IgYSDigJxtZWRpYW7igJ0gZ2FtZSB1c2luZyBNb2RlbCA0Lg0KDQpBbGwgbWVkaWFuIHZhbHVlcyBmYWxsIHdpdGhpbiB0aGUgZXhwZXJpbWVudGFsIHJlZ2lvbiBhbmQgYXJlIHRoZXJlZm9yZSByZWxpYWJsZS4NCg0KYGBge3IgUHJlZGljdGlvbixyZXN1bHRzID0gJ2hpZGUnLGluY2x1ZGU9Rn0NCg0KYXBwbHkobXlfdGVhbVssIGMoImZpZWxkX2dvYWxfcGN0IiwidG90YWxfcmVib3VuZHMiLA0KICAgICAgICAgICAgICAgICAgInRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0Iiwic3RlYWxzIildLA0KICAgICAgMiwgbWVkaWFuKQ0KDQpzdW1tYXJ5KG1vZGVsNCkNCg0KbmV3ZGF0YT1kYXRhLmZyYW1lKGZpZWxkX2dvYWxfcGN0PTQyLjk1LHRvdGFsX3JlYm91bmRzPTMzLA0KICAgICAgICAgICAgICAgICAgIHRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0PTMyLjcwLHN0ZWFscz03KQ0KDQpwcmVkaWN0aW9uPXByZWRpY3QobW9kZWw0LG5ld2RhdGEsIGludGVydmFsID0gImNvbmZpZGVuY2UiLCBsZXZlbD0uOTUpDQoNCmBgYA0KDQpJIGJ1aWx0IHRoZSBtb2RlbCB0byBwcmVkaWN0IG15IHRlYW1zIHBvaW50cyBmb3IgYSBnYW1lIGluIHdoaWNoIHRoZXkgYWNoaWV2ZSB0aGUgbWVkaWFuIHZhbHVlIGZvciBlYWNoIHZhcmlhYmxlLiBUaGUgcHJlZGljdGVkIHNjb3JlIGlzIGByIHByZWRpY3Rpb25bMV1gLCB3aXRoIDk1JSBjb25maWRlbmNlIGludGVydmFsIChgciBwcmVkaWN0aW9uWzJdYCxgciBwcmVkaWN0aW9uWzNdYCkg