1 Introduction

The purpose of this report is to build a multiple linear regression model that predicts the points scored by the 2024 Minnesota Lynx for a game in which they attain the median values of field goal percentage, total rebounds, three-point field goal percentage, and steals. This report sources its data from the 2024 WNBA box scores data set, which includes a variety of statistics from each team and game during the 2024 WNBA season. The following sections present summaries of the relevant league-wide and Lynx-specific statistics, supporting plots of points scored by game outcome, a description of the model building process, a residual analysis, and a final prediction.

2 Tables

The following tables summarize the mean and standard deviation of team score and the predictors mentioned above. The first table presents these statistics for every WNBA team (excluding Team WNBA and Team USA), while the second table displays the same statistics isolated to the Minnesota Lynx and sorted by game result. One notices in the second table that, on average, the Lynx score substantially more points and shoot at a higher percentage in wins than in losses. This trend is further illustrated by the box plot and histograms presented in the next section.

# 3 Table for 2c

summary_score %>% 
  kbl(caption = "2024 WNBA League Stats by Team", digits = 2) %>% 
  kable_classic(position = "center", full_width = F, html_font = "Cambria")
2024 WNBA League Stats by Team
team_name mean_score sd_score mean_fg sd_fg mean_reb sd_reb mean_3pt sd_3pt mean_stl sd_stl
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
# 3 Table for 2d

my_team_by_result %>% 
  mutate(team_winner = ifelse(team_winner == TRUE, "Win", "Loss")) %>% 
  kbl(caption = "2024 Minnesota Lynx Stats by Game Result", digits = 2) %>% 
  kable_classic(position = "center", full_width = F, html_font = "Cambria")
2024 Minnesota Lynx Stats by Game Result
team_winner mean_score sd_score mean_fg sd_fg mean_reb sd_reb mean_3pt sd_3pt mean_stl sd_stl
Loss 71.80 9.59 40.13 5.76 32.00 3.44 32.69 10.0 7.07 2.37
Win 86.53 9.18 47.21 5.41 33.61 5.54 39.82 8.5 8.87 3.32

\(~\)

3 Graphs

The box plot below shows the distribution of points scored by game result. As expected, the plot shows a clear discrepancy in points scored between wins and losses, with wins having a higher median team score than losses. The amount of spread in points scored appears to be approximately equal for wins and losses, though losses seem to exhibit a slight left skew. The two histograms given below show the separate distributions of points scored in wins and losses. Both distributions appear to be approximately normal, with the discrepancy in points scored between wins and losses indicated by the difference in central values between the histograms.

boxplot(team_score ~ result, data = df_hist,
        col = c("lightblue","lightgreen"),
        main = "Team Score by Game Result",
        xlab = "Result", ylab = "Team Score")

wins = df_hist$team_score[df_hist$result == "Win"]
losses = df_hist$team_score[df_hist$result == "Loss"]

par(mfrow = c(1, 2))

hist(wins,
     col = "lightgreen",
     main = "Team Score in Games Won",
     xlab = "Team Score",
     ylab = "Frequency",
     breaks = 10)

hist(losses,
     col = "lightblue",
     main = "Team Score in Games Lost",
     xlab = "Team Score",
     ylab = "Frequency",
     breaks = 10)

4 Models

Four multiple linear regression models were considered during the model building process. The first was the full first-order model, involving all of the predictors mentioned above: field goal percentage, total rebounds, three-point field goal percentage, and steals. The correlation matrix showed that no pairs of predictors were highly correlated, i.e., that each correlation coefficient \(r\) satisfied \(\lvert r \rvert < 0.8\). Additionally, the VIF values for all predictors fell between 1 and 2, indicating a lack of significant multicollinearity in the model. Given the lack of highly correlated pairs, the second model retained all of the predictors in the full first-order model (i.e., model 2 is identical to model 1).

The third model was the full interaction model. This model involved ten terms in total, four of which being the first-order terms and the remaining six being interaction terms. At the 15% significance level, all of the interaction terms were nonsignificant and were therefore removed. The resulting fourth model involved only the first-order terms. Though the total rebounds term did not significantly contribute to this model at the 15% significance level (\(p = 0.262\)), it was retained as removing it did not improve the adjusted \(R^2\) value.

The final model is summarized as follows: \[ \text{team_score} = 4.73 + 1.18 * \text{fg_pct} + 0.22 * \text{total_rebounds} + 0.3 * \text{three_point_fg_pct} + 0.67 * \text{steals} \]

This model significantly predicts team score: \(F(4, 48) = 24.94\), \(p < 0.0001\), \({R_a}^2 = 0.65\).

See the table below for the results.

stargazer(model4, digits = 3, type = "html")
Dependent variable:
team_score
field_goal_pct 1.176***
(0.182)
total_rebounds 0.220
(0.194)
three_point_field_goal_pct 0.305**
(0.118)
steals 0.674**
(0.298)
Constant 4.730
(11.165)
Observations 53
R2 0.675
Adjusted R2 0.648
Residual Std. Error 6.755 (df = 48)
F Statistic 24.941*** (df = 4; 48)
Note: p<0.1; p<0.05; p<0.01

\(~\)

The following plots are evaluated to assess the validity of the final model. The histogram of residuals given below appears approximately normal, so the assumption of normality is met. The residuals versus fitted values plot features a fairly uniform scatter about the line \(y = 0\), so the assumption of constant variance is also met.

One observes that the studentized residuals plot does not detect any outliers, while the diagnostics plot indicates that observations 13, 41, and 52 have high leverage. Moreover, the Cook’s distance plot points to observations 11, 13, 33, 41, and 52 as being influential. Observation 11 corresponds to the Minnesota Lynx vs. Phoenix Mercury playoff game that took place on September 25, 2024; observation 13 to the Minnesota Lynx vs. Los Angeles Sparks game on September 19, 2024; observation 33 to the Minnesota Lynx vs. Connecticut Sun game on July 4, 2024; observation 41 to the Minnesota Lynx vs. Los Angeles Sparks game on June 14, 2024; and observation 52 to the Minnesota Lynx vs. Seattle Storm game on May 17, 2024. Based on the diagnostics and the Cook’s distance plots, it appears that observation 52 has a relatively large influence on the model.

ε = resid(model4)
y_hat = predict(model4)
hist(ε,
     col = "lightblue",
     main = "Histogram of Residuals")

plot(y_hat,ε)
abline(h=0)
title(main = "Versus Fits")

ols_plot_resid_stud(model4)

ols_plot_resid_lev(model4, threshold=3)

ols_plot_cooksd_bar(model4)

5 Prediction

This model predicts the points scored by the Minnesota Lynx for a game in which they achieve the median value of each of the predictors. The predicted team score in such a game is \(82.07\) with 95% confidence interval \((80.12, 84.01)\). The experimental region of the model is given below:

field_goal_pct: [28.60, 59.40]

total_rebounds: [24.00, 45.00]

three_point_field_goal_pct: [15.80, 57.90]

steals: [4.00, 18.00]

LS0tCnRpdGxlOiAiU1RBMzE5IEFzc2lnbm1lbnQgIzcgLSAyMDI0IE1pbm5lc290YSBMeW54IFJlcG9ydCIKYXV0aG9yOiAiVGhvbWFzIFBldm90byIKZGF0ZTogIk1heSA0LCAyMDI2IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDogCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA0CiAgICB0b2NfZmxvYXQ6IHllcwogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICAgIHRvY19jb2xsYXBzZWQ6IHllcwogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKICAgIHNtb290aF9zY3JvbGw6IHllcwogICAgdGhlbWU6IGx1bWVuCiAgcGRmX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICBmaWdfd2lkdGg6IDMKICAgIGZpZ19oZWlnaHQ6IDMKICB3b3JkX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIGtlZXBfbWQ6IHllcwplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCmBgYCB7Y3NzLCBlY2hvID0gRkFMU0V9CiNUT0M6OmJlZm9yZSB7CiAgY29udGVudDogIlRhYmxlIG9mIENvbnRlbnRzIjsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LXNpemU6IDEuMmVtOwogIGRpc3BsYXk6IGJsb2NrOwogIGNvbG9yOiBuYXZ5OwogIG1hcmdpbi1ib3R0b206IDEwcHg7Cn0KCgpkaXYjVE9DIGxpIHsgICAgIC8qIHRhYmxlIG9mIGNvbnRlbnQgICovCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOwogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOwogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsKICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsKfQoKaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8KICBmb250LXNpemU6IDIycHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgY29sb3I6IERhcmtSZWQ7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsKfQoKaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICBmb250LXNpemU6IDE1cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsKICBjb2xvcjogbmF2eTsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogIGZvbnQtc2l6ZTogMThweDsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7CiAgY29sb3I6IERhcmtCbHVlOwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAyMHB4OwogICAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBkYXJrcmVkOwogICAgdGV4dC1hbGlnbjogbGVmdDsKfQoKaDIgeyAvKiBIZWFkZXIgMiAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAxOHB4OwogICAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBuYXZ5OwogICAgdGV4dC1hbGlnbjogbGVmdDsKfQoKaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAxNnB4OwogICAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBuYXZ5OwogICAgdGV4dC1hbGlnbjogbGVmdDsKfQoKaDQgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAxNHB4OwogIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogZGFya3JlZDsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCi8qIEFkZCBkb3RzIGFmdGVyIG51bWJlcmVkIGhlYWRlcnMgKi8KLmhlYWRlci1zZWN0aW9uLW51bWJlcjo6YWZ0ZXIgewogIGNvbnRlbnQ6ICIuIjsKCmJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9CgouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQoKcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0KCn0KCmBgYAoKYGBgIHtyIHNldHVwLCBpbmNsdWRlID0gRn0KCiMgU2V0IHdvcmtpbmcgZGlyZWN0b3J5CgpzZXR3ZCgnL1VzZXJzL3Rob21hc3Bldm90by9EZXNrdG9wL1NwcmluZyAyMDI2L1NUQTMxOS9SIFByb2plY3RzJykKCiMgTGlicmFyeSBzdGF0ZW1lbnRzCgpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoY2FyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkob2xzcnIpCmxpYnJhcnkoc3RhcmdhemVyKQoKYGBgCgpgYGAge3Igd3JhbmdsaW5nLCBpbmNsdWRlID0gRn0KCmRhdGEgPC0gcmVhZC5jc3YoIldOQkFfMjAyNV9ib3gtc2NvcmVzLmNzdiIpCgpzdW1tYXJ5KGRhdGEpCgojIDJhIEFsbCBXTkJBIHRlYW1zIGluY2x1ZGVkLCByZW1vdmUgc2NvcmVzIGZyb20gYWxsIHN0YXIgZ2FtZQoKZGF0YSA9IGRhdGEgJT4lCiAgZmlsdGVyKHRlYW1fbmFtZSAhPSJUZWFtIFdOQkEiICYgdGVhbV9uYW1lICE9IlRlYW0gVVNBIikKCiMgMmMgR3JvdXAgZGF0YSBieSB0ZWFtLCBmaW5kIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBnaXZlbiB2YXJpYWJsZXMKCnN1bW1hcnlfc2NvcmUgPSBkYXRhICU+JSAKICBncm91cF9ieSh0ZWFtX25hbWUpICU+JSAKICBzdW1tYXJpc2UobWVhbl9zY29yZT1tZWFuKHRlYW1fc2NvcmUpLHNkX3Njb3JlPXNkKHRlYW1fc2NvcmUpLAogICAgICAgICAgICBtZWFuX2ZnPW1lYW4oZmllbGRfZ29hbF9wY3QpLHNkX2ZnPXNkKGZpZWxkX2dvYWxfcGN0KSwKICAgICAgICAgICAgbWVhbl9yZWI9bWVhbih0b3RhbF9yZWJvdW5kcyksc2RfcmViPXNkKHRvdGFsX3JlYm91bmRzKSwKICAgICAgICAgICAgbWVhbl8zcHQ9bWVhbih0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCksc2RfM3B0PXNkKHRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0KSwKICAgICAgICAgICAgbWVhbl9zdGw9bWVhbihzdGVhbHMpLHNkX3N0bD1zZChzdGVhbHMpKQoKIyAyYiAmIDJkIFNlbGVjdCBuZWVkZWQgdmFyaWFibGVzIGFuZCBmaWx0ZXIgdG8gTWlubmVzb3RhIEx5bngKCm15X3RlYW0gPSBkYXRhICU+JSAKICBzZWxlY3QodGVhbV9zY29yZSwgZmllbGRfZ29hbF9wY3QsIHRvdGFsX3JlYm91bmRzLCB0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCwgc3RlYWxzLCB0ZWFtX25hbWUsIHRlYW1fd2lubmVyKSAlPiUgCiAgZmlsdGVyKHRlYW1fbmFtZSA9PSAiTHlueCIpCgojIEdyb3VwcyBjYXNlcyBieSB3aW4gdnMuIGxvc3M7IHN1bW1hcml6ZSBhbGwgdmFyaWFibGVzIHdpdGggbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uCgogbXlfdGVhbV9ieV9yZXN1bHQgPSBteV90ZWFtICU+JSAKICBncm91cF9ieSh0ZWFtX3dpbm5lcikgJT4lIAogIHN1bW1hcmlzZShtZWFuX3Njb3JlPW1lYW4odGVhbV9zY29yZSksIHNkX3Njb3JlPXNkKHRlYW1fc2NvcmUpLAogICAgICAgICAgIG1lYW5fZmc9bWVhbihmaWVsZF9nb2FsX3BjdCksIHNkX2ZnPXNkKGZpZWxkX2dvYWxfcGN0KSwKICAgICAgICAgICAgbWVhbl9yZWI9bWVhbih0b3RhbF9yZWJvdW5kcyksIHNkX3JlYj1zZCh0b3RhbF9yZWJvdW5kcyksCiAgICAgICAgICAgbWVhbl8zcHQ9bWVhbih0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCksIHNkXzNwdD1zZCh0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCksCiAgICAgICAgICAgbWVhbl9zdGw9bWVhbihzdGVhbHMpLCBzZF9zdGw9c2Qoc3RlYWxzKSkKCiMgQ2hhbmdlIFRSVUUgYW5kIEZBTFNFIHRvICJXaW4iIGFuZCAiTG9zcyIgZm9yIGJveHBsb3QKIApkZl9oaXN0ID0gZGF0YSAlPiUgCiAgZmlsdGVyKHRlYW1fbmFtZSA9PSAiTHlueCIpICU+JSAKICBtdXRhdGUocmVzdWx0ID0gY2FzZV93aGVuKAogICAgdGVhbV93aW5uZXIgPT0gIlRSVUUiIH4gIldpbiIsCiAgICB0ZWFtX3dpbm5lciA9PSAiRkFMU0UiIH4gIkxvc3MiKSkKCmBgYAoKIyBJbnRyb2R1Y3Rpb24KClRoZSBwdXJwb3NlIG9mIHRoaXMgcmVwb3J0IGlzIHRvIGJ1aWxkIGEgbXVsdGlwbGUgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgdGhhdCBwcmVkaWN0cyB0aGUgcG9pbnRzIHNjb3JlZCBieSB0aGUgMjAyNCBNaW5uZXNvdGEgTHlueCBmb3IgYSBnYW1lIGluIHdoaWNoIHRoZXkgYXR0YWluIHRoZSBtZWRpYW4gdmFsdWVzIG9mIGZpZWxkIGdvYWwgcGVyY2VudGFnZSwgdG90YWwgcmVib3VuZHMsIHRocmVlLXBvaW50IGZpZWxkIGdvYWwgcGVyY2VudGFnZSwgYW5kIHN0ZWFscy4gVGhpcyByZXBvcnQgc291cmNlcyBpdHMgZGF0YSBmcm9tIHRoZSAyMDI0IFdOQkEgYm94IHNjb3JlcyBkYXRhIHNldCwgd2hpY2ggaW5jbHVkZXMgYSB2YXJpZXR5IG9mIHN0YXRpc3RpY3MgZnJvbSBlYWNoIHRlYW0gYW5kIGdhbWUgZHVyaW5nIHRoZSAyMDI0IFdOQkEgc2Vhc29uLiBUaGUgZm9sbG93aW5nIHNlY3Rpb25zIHByZXNlbnQgc3VtbWFyaWVzIG9mIHRoZSByZWxldmFudCBsZWFndWUtd2lkZSBhbmQgTHlueC1zcGVjaWZpYyBzdGF0aXN0aWNzLCBzdXBwb3J0aW5nIHBsb3RzIG9mIHBvaW50cyBzY29yZWQgYnkgZ2FtZSBvdXRjb21lLCBhIGRlc2NyaXB0aW9uIG9mIHRoZSBtb2RlbCBidWlsZGluZyBwcm9jZXNzLCBhIHJlc2lkdWFsIGFuYWx5c2lzLCBhbmQgYSBmaW5hbCBwcmVkaWN0aW9uLgogCiMgVGFibGVzCgpUaGUgZm9sbG93aW5nIHRhYmxlcyBzdW1tYXJpemUgdGhlIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0ZWFtIHNjb3JlIGFuZCB0aGUgcHJlZGljdG9ycyBtZW50aW9uZWQgYWJvdmUuIFRoZSBmaXJzdCB0YWJsZSBwcmVzZW50cyB0aGVzZSBzdGF0aXN0aWNzIGZvciBldmVyeSBXTkJBIHRlYW0gKGV4Y2x1ZGluZyBUZWFtIFdOQkEgYW5kIFRlYW0gVVNBKSwgd2hpbGUgdGhlIHNlY29uZCB0YWJsZSBkaXNwbGF5cyB0aGUgc2FtZSBzdGF0aXN0aWNzIGlzb2xhdGVkIHRvIHRoZSBNaW5uZXNvdGEgTHlueCBhbmQgc29ydGVkIGJ5IGdhbWUgcmVzdWx0LiBPbmUgbm90aWNlcyBpbiB0aGUgc2Vjb25kIHRhYmxlIHRoYXQsIG9uIGF2ZXJhZ2UsIHRoZSBMeW54IHNjb3JlIHN1YnN0YW50aWFsbHkgbW9yZSBwb2ludHMgYW5kIHNob290IGF0IGEgaGlnaGVyIHBlcmNlbnRhZ2UgaW4gd2lucyB0aGFuIGluIGxvc3Nlcy4gVGhpcyB0cmVuZCBpcyBmdXJ0aGVyIGlsbHVzdHJhdGVkIGJ5IHRoZSBib3ggcGxvdCBhbmQgaGlzdG9ncmFtcyBwcmVzZW50ZWQgaW4gdGhlIG5leHQgc2VjdGlvbi4KCmBgYCB7ciB0YWJsZXMsIGZpZy53aWR0aCA9IDIsIGZpZy5oZWlnaHQgPSAyLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30KCiMgMyBUYWJsZSBmb3IgMmMKCnN1bW1hcnlfc2NvcmUgJT4lIAogIGtibChjYXB0aW9uID0gIjIwMjQgV05CQSBMZWFndWUgU3RhdHMgYnkgVGVhbSIsIGRpZ2l0cyA9IDIpICU+JSAKICBrYWJsZV9jbGFzc2ljKHBvc2l0aW9uID0gImNlbnRlciIsIGZ1bGxfd2lkdGggPSBGLCBodG1sX2ZvbnQgPSAiQ2FtYnJpYSIpCgojIDMgVGFibGUgZm9yIDJkCgpteV90ZWFtX2J5X3Jlc3VsdCAlPiUgCiAgbXV0YXRlKHRlYW1fd2lubmVyID0gaWZlbHNlKHRlYW1fd2lubmVyID09IFRSVUUsICJXaW4iLCAiTG9zcyIpKSAlPiUgCiAga2JsKGNhcHRpb24gPSAiMjAyNCBNaW5uZXNvdGEgTHlueCBTdGF0cyBieSBHYW1lIFJlc3VsdCIsIGRpZ2l0cyA9IDIpICU+JSAKICBrYWJsZV9jbGFzc2ljKHBvc2l0aW9uID0gImNlbnRlciIsIGZ1bGxfd2lkdGggPSBGLCBodG1sX2ZvbnQgPSAiQ2FtYnJpYSIpCgpgYGAKJH4kCgojIEdyYXBocwogIApUaGUgYm94IHBsb3QgYmVsb3cgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiBwb2ludHMgc2NvcmVkIGJ5IGdhbWUgcmVzdWx0LiBBcyBleHBlY3RlZCwgdGhlIHBsb3Qgc2hvd3MgYSBjbGVhciBkaXNjcmVwYW5jeSBpbiBwb2ludHMgc2NvcmVkIGJldHdlZW4gd2lucyBhbmQgbG9zc2VzLCB3aXRoIHdpbnMgaGF2aW5nIGEgaGlnaGVyIG1lZGlhbiB0ZWFtIHNjb3JlIHRoYW4gbG9zc2VzLiBUaGUgYW1vdW50IG9mIHNwcmVhZCBpbiBwb2ludHMgc2NvcmVkIGFwcGVhcnMgdG8gYmUgYXBwcm94aW1hdGVseSBlcXVhbCBmb3Igd2lucyBhbmQgbG9zc2VzLCB0aG91Z2ggbG9zc2VzIHNlZW0gdG8gZXhoaWJpdCBhIHNsaWdodCBsZWZ0IHNrZXcuIFRoZSB0d28gaGlzdG9ncmFtcyBnaXZlbiBiZWxvdyBzaG93IHRoZSBzZXBhcmF0ZSBkaXN0cmlidXRpb25zIG9mIHBvaW50cyBzY29yZWQgaW4gd2lucyBhbmQgbG9zc2VzLiBCb3RoIGRpc3RyaWJ1dGlvbnMgYXBwZWFyIHRvIGJlIGFwcHJveGltYXRlbHkgbm9ybWFsLCB3aXRoIHRoZSBkaXNjcmVwYW5jeSBpbiBwb2ludHMgc2NvcmVkIGJldHdlZW4gd2lucyBhbmQgbG9zc2VzIGluZGljYXRlZCBieSB0aGUgZGlmZmVyZW5jZSBpbiBjZW50cmFsIHZhbHVlcyBiZXR3ZWVuIHRoZSBoaXN0b2dyYW1zLgoKYGBgIHtyIGJveHBsb3QsIGZpZy53aWR0aCA9IDQsIGZpZy5oZWlnaHQgPSA0LCBmaWcuYWxpZ24gPSAnY2VudGVyJ30KCmJveHBsb3QodGVhbV9zY29yZSB+IHJlc3VsdCwgZGF0YSA9IGRmX2hpc3QsCiAgICAgICAgY29sID0gYygibGlnaHRibHVlIiwibGlnaHRncmVlbiIpLAogICAgICAgIG1haW4gPSAiVGVhbSBTY29yZSBieSBHYW1lIFJlc3VsdCIsCiAgICAgICAgeGxhYiA9ICJSZXN1bHQiLCB5bGFiID0gIlRlYW0gU2NvcmUiKQoKYGBgCmBgYCB7ciBoaXN0b2dyYW1zLCBmaWcuaGVpZ2h0ID0gNCwgZmlnLmFsaWduID0gJ2NlbnRlcid9Cgp3aW5zID0gZGZfaGlzdCR0ZWFtX3Njb3JlW2RmX2hpc3QkcmVzdWx0ID09ICJXaW4iXQpsb3NzZXMgPSBkZl9oaXN0JHRlYW1fc2NvcmVbZGZfaGlzdCRyZXN1bHQgPT0gIkxvc3MiXQoKcGFyKG1mcm93ID0gYygxLCAyKSkKCmhpc3Qod2lucywKICAgICBjb2wgPSAibGlnaHRncmVlbiIsCiAgICAgbWFpbiA9ICJUZWFtIFNjb3JlIGluIEdhbWVzIFdvbiIsCiAgICAgeGxhYiA9ICJUZWFtIFNjb3JlIiwKICAgICB5bGFiID0gIkZyZXF1ZW5jeSIsCiAgICAgYnJlYWtzID0gMTApCgpoaXN0KGxvc3NlcywKICAgICBjb2wgPSAibGlnaHRibHVlIiwKICAgICBtYWluID0gIlRlYW0gU2NvcmUgaW4gR2FtZXMgTG9zdCIsCiAgICAgeGxhYiA9ICJUZWFtIFNjb3JlIiwKICAgICB5bGFiID0gIkZyZXF1ZW5jeSIsCiAgICAgYnJlYWtzID0gMTApCgpgYGAKCiMgTW9kZWxzCgpgYGAge3IgZmlyc3Qtb3JkZXIgbW9kZWwsIGluY2x1ZGUgPSBGfQoKbW9kZWwxID0gbG0odGVhbV9zY29yZSB+IGZpZWxkX2dvYWxfcGN0ICsgdG90YWxfcmVib3VuZHMgKyB0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCArIHN0ZWFscywgZGF0YSA9IG15X3RlYW0pCgpzdW1tYXJ5KG1vZGVsMSkKCmNvcl9kYXRhID0gbXlfdGVhbSAlPiUgCiAgc2VsZWN0KHRlYW1fc2NvcmUsZmllbGRfZ29hbF9wY3QsIHRvdGFsX3JlYm91bmRzLCB0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCwgc3RlYWxzKQoKY29yKGNvcl9kYXRhKQoKdmlmKG1vZGVsMSkKCiMgVGhlcmUgYXJlIG5vIGhpZ2hseSBjb3JyZWxhdGVkIHBhaXJzIGluIHRoZSBmaXJzdC1vcmRlciBtb2RlbCwgc28gbW9kZWwgMiBpcyB0aGUgc2FtZSBhcyBtb2RlbCAxLgoKYGBgCgpgYGAge3IgaW50ZXJhY3Rpb24gbW9kZWwsIGluY2x1ZGUgPSBGfQoKbW9kZWwzID0gbG0odGVhbV9zY29yZSB+IGZpZWxkX2dvYWxfcGN0ICsgdG90YWxfcmVib3VuZHMgKyB0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCArIHN0ZWFscyArIGZpZWxkX2dvYWxfcGN0ICogdG90YWxfcmVib3VuZHMgKyBmaWVsZF9nb2FsX3BjdCAqIHRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0ICsgZmllbGRfZ29hbF9wY3QgKiBzdGVhbHMgKyB0b3RhbF9yZWJvdW5kcyAqIHRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0ICsgdG90YWxfcmVib3VuZHMgKiBzdGVhbHMgKyB0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCAqIHN0ZWFscywgZGF0YSA9IG15X3RlYW0pCgpzdW1tYXJ5KG1vZGVsMykKCm1vZGVsNCA9IGxtKHRlYW1fc2NvcmUgfiBmaWVsZF9nb2FsX3BjdCArIHRvdGFsX3JlYm91bmRzICsgdGhyZWVfcG9pbnRfZmllbGRfZ29hbF9wY3QgKyBzdGVhbHMsIGRhdGEgPSBteV90ZWFtKQoKbW9kZWw0X3N1bW1hcnkgPSBzdW1tYXJ5KG1vZGVsNCkKCm1vZGVsNF9zdW1tYXJ5CgpgYGAKCkZvdXIgbXVsdGlwbGUgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWxzIHdlcmUgY29uc2lkZXJlZCBkdXJpbmcgdGhlIG1vZGVsIGJ1aWxkaW5nIHByb2Nlc3MuIFRoZSBmaXJzdCB3YXMgdGhlIGZ1bGwgZmlyc3Qtb3JkZXIgbW9kZWwsIGludm9sdmluZyBhbGwgb2YgdGhlIHByZWRpY3RvcnMgbWVudGlvbmVkIGFib3ZlOiBmaWVsZCBnb2FsIHBlcmNlbnRhZ2UsIHRvdGFsIHJlYm91bmRzLCB0aHJlZS1wb2ludCBmaWVsZCBnb2FsIHBlcmNlbnRhZ2UsIGFuZCBzdGVhbHMuIFRoZSBjb3JyZWxhdGlvbiBtYXRyaXggc2hvd2VkIHRoYXQgbm8gcGFpcnMgb2YgcHJlZGljdG9ycyB3ZXJlIGhpZ2hseSBjb3JyZWxhdGVkLCBpLmUuLCB0aGF0IGVhY2ggY29ycmVsYXRpb24gY29lZmZpY2llbnQgJHIkIHNhdGlzZmllZCAkXGx2ZXJ0IHIgXHJ2ZXJ0IDwgMC44JC4gQWRkaXRpb25hbGx5LCB0aGUgVklGIHZhbHVlcyBmb3IgYWxsIHByZWRpY3RvcnMgZmVsbCBiZXR3ZWVuIDEgYW5kIDIsIGluZGljYXRpbmcgYSBsYWNrIG9mIHNpZ25pZmljYW50IG11bHRpY29sbGluZWFyaXR5IGluIHRoZSBtb2RlbC4gR2l2ZW4gdGhlIGxhY2sgb2YgaGlnaGx5IGNvcnJlbGF0ZWQgcGFpcnMsIHRoZSBzZWNvbmQgbW9kZWwgcmV0YWluZWQgYWxsIG9mIHRoZSBwcmVkaWN0b3JzIGluIHRoZSBmdWxsIGZpcnN0LW9yZGVyIG1vZGVsIChpLmUuLCBtb2RlbCAyIGlzIGlkZW50aWNhbCB0byBtb2RlbCAxKS4gCgpUaGUgdGhpcmQgbW9kZWwgd2FzIHRoZSBmdWxsIGludGVyYWN0aW9uIG1vZGVsLiBUaGlzIG1vZGVsIGludm9sdmVkIHRlbiB0ZXJtcyBpbiB0b3RhbCwgZm91ciBvZiB3aGljaCBiZWluZyB0aGUgZmlyc3Qtb3JkZXIgdGVybXMgYW5kIHRoZSByZW1haW5pbmcgc2l4IGJlaW5nIGludGVyYWN0aW9uIHRlcm1zLiBBdCB0aGUgMTUlIHNpZ25pZmljYW5jZSBsZXZlbCwgYWxsIG9mIHRoZSBpbnRlcmFjdGlvbiB0ZXJtcyB3ZXJlIG5vbnNpZ25pZmljYW50IGFuZCB3ZXJlIHRoZXJlZm9yZSByZW1vdmVkLiBUaGUgcmVzdWx0aW5nIGZvdXJ0aCBtb2RlbCBpbnZvbHZlZCBvbmx5IHRoZSBmaXJzdC1vcmRlciB0ZXJtcy4gVGhvdWdoIHRoZSB0b3RhbCByZWJvdW5kcyB0ZXJtIGRpZCBub3Qgc2lnbmlmaWNhbnRseSBjb250cmlidXRlIHRvIHRoaXMgbW9kZWwgYXQgdGhlIDE1JSBzaWduaWZpY2FuY2UgbGV2ZWwgKCRwID0gMC4yNjIkKSwgaXQgd2FzIHJldGFpbmVkIGFzIHJlbW92aW5nIGl0IGRpZCBub3QgaW1wcm92ZSB0aGUgYWRqdXN0ZWQgJFJeMiQgdmFsdWUuCgpUaGUgZmluYWwgbW9kZWwgaXMgc3VtbWFyaXplZCBhcyBmb2xsb3dzOiAgXFsgXHRleHR7dGVhbV9zY29yZX0gPSBgciByb3VuZChtb2RlbDQkY29lZmZpY2llbnRzWzFdLCAyKWAgKyBgciByb3VuZChtb2RlbDQkY29lZmZpY2llbnRzWzJdLCAyKWAgKiBcdGV4dHtmZ19wY3R9ICsgYHIgcm91bmQobW9kZWw0JGNvZWZmaWNpZW50c1szXSwgMilgICogXHRleHR7dG90YWxfcmVib3VuZHN9ICsgYHIgcm91bmQobW9kZWw0JGNvZWZmaWNpZW50c1s0XSwgMilgICogXHRleHR7dGhyZWVfcG9pbnRfZmdfcGN0fSArIGByIHJvdW5kKG1vZGVsNCRjb2VmZmljaWVudHNbNV0sIDIpYCAqIFx0ZXh0e3N0ZWFsc30gXF0KClRoaXMgbW9kZWwgc2lnbmlmaWNhbnRseSBwcmVkaWN0cyB0ZWFtIHNjb3JlOiBcKCBGKGByIHJvdW5kKG1vZGVsNF9zdW1tYXJ5JGZzdGF0aXN0aWNbMl0sIDIpYCwgYHIgcm91bmQobW9kZWw0X3N1bW1hcnkkZnN0YXRpc3RpY1szXSwgMilgKSA9IGByIHJvdW5kKG1vZGVsNF9zdW1tYXJ5JGZzdGF0aXN0aWNbMV0sIDIpYCBcKSwgXChwIDwgMC4wMDAxXCksIFwoIHtSX2F9XjIgPSBgciByb3VuZChtb2RlbDRfc3VtbWFyeSRhZGouci5zcXVhcmVkLCAyKWAgXCkuCgpTZWUgdGhlIHRhYmxlIGJlbG93IGZvciB0aGUgcmVzdWx0cy4KCjxkaXYgYWxpZ249ImNlbnRlciI+CmBgYCB7ciBmaW5hbCBtb2RlbCwgcmVzdWx0cyA9ICdhc2lzJ30KCnN0YXJnYXplcihtb2RlbDQsIGRpZ2l0cyA9IDMsIHR5cGUgPSAiaHRtbCIpCgpgYGAKPC9kaXY+CgokfiQKClRoZSBmb2xsb3dpbmcgcGxvdHMgYXJlIGV2YWx1YXRlZCB0byBhc3Nlc3MgdGhlIHZhbGlkaXR5IG9mIHRoZSBmaW5hbCBtb2RlbC4gVGhlIGhpc3RvZ3JhbSBvZiByZXNpZHVhbHMgZ2l2ZW4gYmVsb3cgYXBwZWFycyBhcHByb3hpbWF0ZWx5IG5vcm1hbCwgc28gdGhlIGFzc3VtcHRpb24gb2Ygbm9ybWFsaXR5IGlzIG1ldC4gVGhlIHJlc2lkdWFscyB2ZXJzdXMgZml0dGVkIHZhbHVlcyBwbG90IGZlYXR1cmVzIGEgZmFpcmx5IHVuaWZvcm0gc2NhdHRlciBhYm91dCB0aGUgbGluZSAkeSA9IDAkLCBzbyB0aGUgYXNzdW1wdGlvbiBvZiBjb25zdGFudCB2YXJpYW5jZSBpcyBhbHNvIG1ldC4gCgpPbmUgb2JzZXJ2ZXMgdGhhdCB0aGUgc3R1ZGVudGl6ZWQgcmVzaWR1YWxzIHBsb3QgZG9lcyBub3QgZGV0ZWN0IGFueSBvdXRsaWVycywgd2hpbGUgdGhlIGRpYWdub3N0aWNzIHBsb3QgaW5kaWNhdGVzIHRoYXQgb2JzZXJ2YXRpb25zIDEzLCA0MSwgYW5kIDUyIGhhdmUgaGlnaCBsZXZlcmFnZS4gTW9yZW92ZXIsIHRoZSBDb29rJ3MgZGlzdGFuY2UgcGxvdCBwb2ludHMgdG8gb2JzZXJ2YXRpb25zIDExLCAxMywgMzMsIDQxLCBhbmQgNTIgYXMgYmVpbmcgaW5mbHVlbnRpYWwuIE9ic2VydmF0aW9uIDExIGNvcnJlc3BvbmRzIHRvIHRoZSBNaW5uZXNvdGEgTHlueCB2cy4gUGhvZW5peCBNZXJjdXJ5IHBsYXlvZmYgZ2FtZSB0aGF0IHRvb2sgcGxhY2Ugb24gU2VwdGVtYmVyIDI1LCAyMDI0OyBvYnNlcnZhdGlvbiAxMyB0byB0aGUgTWlubmVzb3RhIEx5bnggdnMuIExvcyBBbmdlbGVzIFNwYXJrcyBnYW1lIG9uIFNlcHRlbWJlciAxOSwgMjAyNDsgb2JzZXJ2YXRpb24gMzMgdG8gdGhlIE1pbm5lc290YSBMeW54IHZzLiBDb25uZWN0aWN1dCBTdW4gZ2FtZSBvbiBKdWx5IDQsIDIwMjQ7IG9ic2VydmF0aW9uIDQxIHRvIHRoZSBNaW5uZXNvdGEgTHlueCB2cy4gTG9zIEFuZ2VsZXMgU3BhcmtzIGdhbWUgb24gSnVuZSAxNCwgMjAyNDsgYW5kIG9ic2VydmF0aW9uIDUyIHRvIHRoZSBNaW5uZXNvdGEgTHlueCB2cy4gU2VhdHRsZSBTdG9ybSBnYW1lIG9uIE1heSAxNywgMjAyNC4gQmFzZWQgb24gdGhlIGRpYWdub3N0aWNzIGFuZCB0aGUgQ29vaydzIGRpc3RhbmNlIHBsb3RzLCBpdCBhcHBlYXJzIHRoYXQgb2JzZXJ2YXRpb24gNTIgaGFzIGEgcmVsYXRpdmVseSBsYXJnZSBpbmZsdWVuY2Ugb24gdGhlIG1vZGVsLgoKYGBgIHtyIHJlc2lkdWFscywgZmlnLndpZHRoID0gNSwgZmlnLmhlaWdodCA9IDUsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQoKzrUgPSByZXNpZChtb2RlbDQpCnlfaGF0ID0gcHJlZGljdChtb2RlbDQpCmhpc3QozrUsCiAgICAgY29sID0gImxpZ2h0Ymx1ZSIsCiAgICAgbWFpbiA9ICJIaXN0b2dyYW0gb2YgUmVzaWR1YWxzIikKCnBsb3QoeV9oYXQszrUpCmFibGluZShoPTApCnRpdGxlKG1haW4gPSAiVmVyc3VzIEZpdHMiKQoKb2xzX3Bsb3RfcmVzaWRfc3R1ZChtb2RlbDQpCgpvbHNfcGxvdF9yZXNpZF9sZXYobW9kZWw0LCB0aHJlc2hvbGQ9MykKCm9sc19wbG90X2Nvb2tzZF9iYXIobW9kZWw0KQoKYGBgCgojIFByZWRpY3Rpb24KCmBgYCB7ciBwcmVkaWN0aW9uLCBpbmNsdWRlID0gRn0KCnN1bW1hcnkoY29yX2RhdGEpCgojIE5ldyBkYXRhIGZyYW1lIGZvciBtZWRpYW4gdmFsdWVzIG9mIHZhcmlhYmxlcwoKbmV3ZGF0YSA9IGRhdGEuZnJhbWUoZmllbGRfZ29hbF9wY3QgPSA0NS4yMCwgdG90YWxfcmVib3VuZHMgPSAzMi4wMCwgdGhyZWVfcG9pbnRfZmllbGRfZ29hbF9wY3QgPSAzOC41LCBzdGVhbHMgPSA4LjAwMCkKCiMgUHJlZGljdCB0ZWFtIHNjb3JlIGZvciBhIGdhbWUgdGhhdCB1c2VzIGFib3ZlIG1lZGlhbiB2YWx1ZXMKCnByZWRpY3Rpb24gPSBwcmVkaWN0KG1vZGVsNCwgbmV3ZGF0YSwgaW50ZXJ2YWwgPSAiY29uZmlkZW5jZSIsIGxldmVsID0gLjk1KQoKYGBgCgpUaGlzIG1vZGVsIHByZWRpY3RzIHRoZSBwb2ludHMgc2NvcmVkIGJ5IHRoZSBNaW5uZXNvdGEgTHlueCBmb3IgYSBnYW1lIGluIHdoaWNoIHRoZXkgYWNoaWV2ZSB0aGUgbWVkaWFuIHZhbHVlIG9mIGVhY2ggb2YgdGhlIHByZWRpY3RvcnMuIFRoZSBwcmVkaWN0ZWQgdGVhbSBzY29yZSBpbiBzdWNoIGEgZ2FtZSBpcyBcKCBgciByb3VuZChwcmVkaWN0aW9uWzFdLCAyKWBcKSB3aXRoIDk1JSBjb25maWRlbmNlIGludGVydmFsIFwoKGByIHJvdW5kKHByZWRpY3Rpb25bMl0sIDIpYCwgYHIgcm91bmQocHJlZGljdGlvblszXSwgMilgKVwpLiBUaGUgZXhwZXJpbWVudGFsIHJlZ2lvbiBvZiB0aGUgbW9kZWwgaXMgZ2l2ZW4gYmVsb3c6CiAKPGRpdiBhbGlnbj0iY2VudGVyIj4KCmZpZWxkX2dvYWxfcGN0OiBbMjguNjAsIDU5LjQwXQoKdG90YWxfcmVib3VuZHM6IFsyNC4wMCwgNDUuMDBdCgp0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdDogWzE1LjgwLCA1Ny45MF0KCnN0ZWFsczogWzQuMDAsIDE4LjAwXQoKPC9kaXY+CgoKCg==