1 Introduction

This project aims to predict a team score, by evaluating data collected for a specific Women’s National Basketball Association team, in the 2024 season. By using linear regression, I developed a model for the Chicago Sky, with the purpose of predicting a score based upon median values for the variables selected in the model.

1.1 Data Summary with Tables

Below are two tables displaying data for each team in the league (Table 1) and the Chicago Sky (Table 2).

Table 1 presents the mean scores (yellow columns) and standard deviations (blue columns) for each team in the league narrowed to the following variables: team score, field goal percentage, total rebounds, three point field goal percentage, and steals.

Table 2 presents data specific to the Chicago Sky, using the same variables as in Table 1 but separated by whether the Chicago Sky experienced a loss or win. It should be noted that there were only 40 observations due to the Chicago Sky not qualifying for the playoffs; their regular season recorded 13 wins and 27 losses in 2024.

#table for entire league; column colors using Chicago Sky hex color codes
means_sd_score%>%
  kbl(digits=2,caption="TABLE 1 - 2024 WNBA Team Stats")%>%
  kable_classic(full_width=F,html_font = "Cambria")%>%
  column_spec(2,background="#ffcd00")%>%
  column_spec(3,background="#418fde")%>%
  column_spec(4,background="#ffcd00")%>%
  column_spec(5,background="#418fde")%>%
  column_spec(6,background="#ffcd00")%>%
  column_spec(7,background="#418fde")%>%
  column_spec(8,background="#ffcd00")%>%
  column_spec(9,background="#418fde")%>%
  column_spec(10,background="#ffcd00")%>%
  column_spec(11,background="#418fde")
TABLE 1 - 2024 WNBA Team Stats
team_name mean_score sd_score mean_field sd_field mean_total sd_total mean_three sd_three 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 my team based on win/loss
my_team_win%>%
  kbl(digits=2,caption="TABLE 2 - 2024 Chicago Sky Team Stats by Win/Loss")%>%
  kable_classic(full_width=F,html_font = "Cambria")%>%
  row_spec(1,background="#418fde")%>%
  row_spec(2,background="#ffcd00")
TABLE 2 - 2024 Chicago Sky Team Stats by Win/Loss
Result mean_score sd_score mean_field sd_field mean_total sd_total mean_three sd_three mean_steals sd_steals
Loss 73.04 8.16 40.66 4.81 35.85 6.38 31.47 12.13 6.30 2.87
Win 86.46 4.99 46.15 4.05 38.15 2.97 32.28 10.94 8.46 3.76
#turn off full-width by putting full_width=F in parentheses after kable_styling(); can change style by looking online for different fonts and designs; digits=2 rounds to 2 decimals
df_hist= data%>%
  filter(team_name=="Sky") %>%
  mutate(Result=case_when(team_winner==T~"Win",team_winner==F~"Loss"))

2 Graphs

2.1 Histogram and Boxplot

The histogram below demonstrates the team score in a game versus the number of games obtaining that score, split by Loss or Win. Both histograms demonstrate a normal distribution.

The boxplot below demonstrates loss/win versus game points scored. The boxplots demonstrate overlap in score ranges and have normal distributions, with the boxes approximately centered in their respective distributions.

#histogram code using team_score as x-axis and number of games with that score on y-axis, 
#separated by win/loss (yellow/blue)
p=df_hist%>%
  ggplot(aes(x=team_score,fill=Result))+
    geom_histogram(color="#e9ecef",alpha=0.6,position='identity')+
    scale_fill_manual(values=c("#418fde", "#ffcd00"))+
    labs(title="2024 Chicago Sky - Team Score vs Number of Games",x="Team Score", 
         y = "Number of Games")

#boxplot of result vs game score separated by win/loss     
p

boxplot(team_score ~ Result, data = df_hist,
        col = c("#418fde","#ffcd00"),
        main="Points Scored by Game Result",
        xlab="Result", ylab="Points")

#just typing p will "call" object p, which is the graph and graph will appear below if you run p as an individual line

3 Models

3.1 First-Order Model

A first-order model was constructed using the previously selected variables (team score, field goal percentage, total rebounds, three point field goal percentage, and steals). No multicollinearity was noted (no r>|0.8|), and all variance inflation factors (VIF) were less than 2. As a result, no individual variables were removed from the first-order model. The adjusted R-squared was 66.8% with F(4,35)=20.61, p<.001.

3.2 Interaction Model

A second, interaction model was built adding the following variables to the first-order model: (field goal percentage * total rebounds), (field goal percentage * three point field goal percentage), (field goal percentage * steals), (total rebounds * three point field goal pct), (total rebounds * steals), and (three point field goal percentage * steals). No interaction term was found to be significant at the 15% significance level. The adjusted R-squared for the interaction model was 63.2% with F(10,29)=7.70, p<.001.

3.3 Model Utility Conclusion

Given no significant interaction terms, the first-order model was retained for further analysis and prediction.

My final model is team_score=-10.3752861 + 1.3421353 * field_goal_pct + 0.5554673 * total_rebounds + 0.1597494 * three_point_field_goal_pct + 0.7731366* steals.

This model significantly predicts team score, F(4,35) = 20.6121077, p<0.001, adjusted R-squared=0.6679394. See the table below for further analysis.

Dependent variable:
team_score
field_goal_pct 1.342***
(0.188)
total_rebounds 0.555***
(0.166)
three_point_field_goal_pct 0.160*
(0.087)
steals 0.773***
(0.279)
Constant -10.375
(10.685)
Observations 40
R2 0.702
Adjusted R2 0.668
Residual Std. Error 5.545 (df = 35)
F Statistic 20.612*** (df = 4; 35)
Note: p<0.1; p<0.05; p<0.01

4 Residual Analysis

Residual analysis was performed on the first-order model including a fitted values plot, a residual histogram, Studentized Residual, a graph of leverage, and a Cook’s D plot. The fitted values plot demonstrated constant variance, and the residual histogram demonstrated a normal distribution of the residuals. No outliers were noted in the Studentized Residual (threshold=|3|). With a leverage threshold of 0.25, four games were noted to have high leverage: September 19, 2024 versus the Connecticut Sun (Observation 1); August 25, 2024 versus the Las Vegas Aces (Observation 12); August 18, 2024 versus the Phoenix Mercury (Observation 14); May 25,2024 versus the Connecticut Sun (Observation 37). Two games had Cook’s D values greater than the threshold of 0.1: July 13, 2024 versus the New York Liberty (Observation 18) and June 4, 2024 versus the New York Liberty (Observation 33).

#residual analysis on model_1 as no interaction terms were significant
#includes versus fit, histogram, studentized residual, leverage (with threshold of 3), and Cook's D
ols_plot_resid_fit(model_1)

ols_plot_resid_hist(model_1)

ols_plot_resid_stud(model_1)

ols_plot_resid_lev(model_1, threshold = 3)

ols_plot_cooksd_chart(model_1)

5 Prediction

I built this model to predict my team’s points for a game in which they achieved the median value for each variable. The predicted team score is 78.5533285, with a 95% confidence interval of (76.7433284, 80.3633285).

LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgIzYiDQphdXRob3I6ICJSeSBCbG9vbWRhaGwiDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIHRoZW1lOiBsdW1lbg0KICBwZGZfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgZmlnX3dpZHRoOiAzDQogICAgZmlnX2hlaWdodDogMw0KICB3b3JkX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBrZWVwX21kOiB5ZXMNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0NCiNUT0M6OmJlZm9yZSB7DQogIGNvbnRlbnQ6ICJUYWJsZSBvZiBDb250ZW50cyI7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LXNpemU6IDEuMmVtOw0KICBkaXNwbGF5OiBibG9jazsNCiAgY29sb3I6IG5hdnk7DQogIG1hcmdpbi1ib3R0b206IDEwcHg7DQp9DQoNCg0KZGl2I1RPQyBsaSB7ICAgICAvKiB0YWJsZSBvZiBjb250ZW50ICAqLw0KICAgIGxpc3Qtc3R5bGU6dXBwZXItcm9tYW47DQogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOw0KICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7DQogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOw0KfQ0KDQpoMS50aXRsZSB7ICAgIC8qIGxldmVsIDEgaGVhZGVyIG9mIHRpdGxlICAqLw0KICBmb250LXNpemU6IDIycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQoNCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMTVweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGNvbG9yOiBuYXZ5Ow0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZ9DQpzZXR3ZCgifi9TVEEgMzE5IikNCg0KZGF0YT1yZWFkLmNzdigiV05CQV8yMDI1X2JveC1zY29yZXMuY3N2IiwgaGVhZGVyPVQpDQoNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGNhcikNCmxpYnJhcnkob2xzcnIpDQoja2FibGVFeHRyYSBpcyBwYWNrYWdlIGZvciBuaWNlIE1hcmtkb3duIHRhYmxlcw0KbGlicmFyeShrYWJsZUV4dHJhKQ0KDQpgYGANCg0KYGBge3Igd3JhbmdsaW5nLCBpbmNsdWRlPUZ9DQoNCg0Kc3VtbWFyeShkYXRhKQ0KDQojYWxsIHduYmEgdGVhbXMgaW5jbHVkZWQsIHJlbW92ZSBzY29yZXMgZnJvbSBhbGwtc3RhciBnYW1lDQpkYXRhPSBkYXRhICU+JQ0KICBmaWx0ZXIodGVhbV9uYW1lIT0iVGVhbSBXTkJBIiAmIHRlYW1fbmFtZSE9IlRlYW0gVVNBIikNCg0KI2dyb3VwIGRhdGEgYnkgdGVhbSwgZmluZCBtZWFuL3N0ZCBvZiBhbGwgdmFyaWFibGVzIChwYXJ0IGIgYW5kIGMpDQptZWFuc19zZF9zY29yZSA9IGRhdGEgJT4lDQogIGdyb3VwX2J5KHRlYW1fbmFtZSkgJT4lDQogIHN1bW1hcml6ZShtZWFuX3Njb3JlPW1lYW4odGVhbV9zY29yZSksIHNkX3Njb3JlPXNkKHRlYW1fc2NvcmUpLA0KICAgICAgICAgICAgbWVhbl9maWVsZD1tZWFuKGZpZWxkX2dvYWxfcGN0KSwgc2RfZmllbGQ9c2QoZmllbGRfZ29hbF9wY3QpLA0KICAgICAgICAgICAgbWVhbl90b3RhbD1tZWFuKHRvdGFsX3JlYm91bmRzKSwgc2RfdG90YWw9c2QodG90YWxfcmVib3VuZHMpLA0KICAgICAgICAgICAgbWVhbl90aHJlZT1tZWFuKHRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0KSwgc2RfdGhyZWU9c2QodGhyZWVfcG9pbnRfZmllbGRfZ29hbF9wY3QpLA0KICAgICAgICAgICAgbWVhbl9zdGVhbHM9bWVhbihzdGVhbHMpLCBzZF9zdGVhbHM9c2Qoc3RlYWxzKSkNCg0KI3BhcnQgZA0KI3NlbGVjdCBvbmx5IHZhcmlhYmxlcyB3ZSBuZWVkIGFuZCBmaWx0ZXIgb24gbXkgdGVhbQ0KbXlfdGVhbSA9IGRhdGEgJT4lDQogIHNlbGVjdCh0ZWFtX3Njb3JlLCBmaWVsZF9nb2FsX3BjdCwgdG90YWxfcmVib3VuZHMsIA0KICAgICAgICAgdGhyZWVfcG9pbnRfZmllbGRfZ29hbF9wY3QsIHN0ZWFscywgdGVhbV9uYW1lLCB0ZWFtX3dpbm5lcikgJT4lDQogIGZpbHRlcih0ZWFtX25hbWU9PSJTa3kiKSU+JQ0KICBtdXRhdGUoUmVzdWx0PWNhc2Vfd2hlbih0ZWFtX3dpbm5lcj09VH4iV2luIix0ZWFtX3dpbm5lcj09Rn4iTG9zcyIpKQ0KDQojZ3JvdXBzIGNhc2VzIGJ5IHdpbiB2IGxvc3MNCiNzdW1tYXJpemUgYWxsIHZhcmlhYmxlcyB3aXRoIG1lYW4gYW5kIHN0ZCBmb3IgbXkgdGVhbQ0KbXlfdGVhbV93aW4gPSBteV90ZWFtICU+JQ0KICBncm91cF9ieShSZXN1bHQpICU+JQ0KICBzdW1tYXJpemUobWVhbl9zY29yZT1tZWFuKHRlYW1fc2NvcmUpLCBzZF9zY29yZT1zZCh0ZWFtX3Njb3JlKSwNCiAgICAgICAgICAgIG1lYW5fZmllbGQ9bWVhbihmaWVsZF9nb2FsX3BjdCksIHNkX2ZpZWxkPXNkKGZpZWxkX2dvYWxfcGN0KSwNCiAgICAgICAgICAgIG1lYW5fdG90YWw9bWVhbih0b3RhbF9yZWJvdW5kcyksIHNkX3RvdGFsPXNkKHRvdGFsX3JlYm91bmRzKSwNCiAgICAgICAgICAgIG1lYW5fdGhyZWU9bWVhbih0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCksIHNkX3RocmVlPXNkKHRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0KSwNCiAgICAgICAgICAgIG1lYW5fc3RlYWxzPW1lYW4oc3RlYWxzKSwgc2Rfc3RlYWxzPXNkKHN0ZWFscykpDQoNCmBgYA0KDQojIEludHJvZHVjdGlvbg0KVGhpcyBwcm9qZWN0IGFpbXMgdG8gcHJlZGljdCBhIHRlYW0gc2NvcmUsIGJ5IGV2YWx1YXRpbmcgZGF0YSBjb2xsZWN0ZWQgZm9yIGEgc3BlY2lmaWMgV29tZW4ncyBOYXRpb25hbCBCYXNrZXRiYWxsIEFzc29jaWF0aW9uIHRlYW0sIGluIHRoZSAyMDI0IHNlYXNvbi4gIEJ5IHVzaW5nIGxpbmVhciByZWdyZXNzaW9uLCBJIGRldmVsb3BlZCBhIG1vZGVsIGZvciB0aGUgQ2hpY2FnbyBTa3ksIHdpdGggdGhlIHB1cnBvc2Ugb2YgcHJlZGljdGluZyBhIHNjb3JlIGJhc2VkIHVwb24gbWVkaWFuIHZhbHVlcyBmb3IgdGhlIHZhcmlhYmxlcyBzZWxlY3RlZCBpbiB0aGUgbW9kZWwuDQoNCiMjIERhdGEgU3VtbWFyeSB3aXRoIFRhYmxlcw0KDQpCZWxvdyBhcmUgdHdvIHRhYmxlcyBkaXNwbGF5aW5nIGRhdGEgZm9yIGVhY2ggdGVhbSBpbiB0aGUgbGVhZ3VlIChUYWJsZSAxKSBhbmQgdGhlIENoaWNhZ28gU2t5IChUYWJsZSAyKS4gIA0KDQpUYWJsZSAxIHByZXNlbnRzIHRoZSBtZWFuIHNjb3JlcyAoeWVsbG93IGNvbHVtbnMpIGFuZCBzdGFuZGFyZCBkZXZpYXRpb25zIChibHVlIGNvbHVtbnMpIGZvciBlYWNoIHRlYW0gaW4gdGhlIGxlYWd1ZSBuYXJyb3dlZCB0byB0aGUgZm9sbG93aW5nIHZhcmlhYmxlczogdGVhbSBzY29yZSwgZmllbGQgZ29hbCBwZXJjZW50YWdlLCB0b3RhbCByZWJvdW5kcywgdGhyZWUgcG9pbnQgZmllbGQgZ29hbCBwZXJjZW50YWdlLCBhbmQgc3RlYWxzLiANCg0KVGFibGUgMiBwcmVzZW50cyBkYXRhIHNwZWNpZmljIHRvIHRoZSBDaGljYWdvIFNreSwgdXNpbmcgdGhlIHNhbWUgdmFyaWFibGVzIGFzIGluIFRhYmxlIDEgYnV0IHNlcGFyYXRlZCBieSB3aGV0aGVyIHRoZSBDaGljYWdvIFNreSBleHBlcmllbmNlZCBhIGxvc3Mgb3Igd2luLiAgSXQgc2hvdWxkIGJlIG5vdGVkIHRoYXQgdGhlcmUgd2VyZSBvbmx5IDQwIG9ic2VydmF0aW9ucyBkdWUgdG8gdGhlIENoaWNhZ28gU2t5IG5vdCBxdWFsaWZ5aW5nIGZvciB0aGUgcGxheW9mZnM7IHRoZWlyIHJlZ3VsYXIgc2Vhc29uIHJlY29yZGVkIDEzIHdpbnMgYW5kIDI3IGxvc3NlcyBpbiAyMDI0Lg0KDQpgYGB7ciB0YWJsZXMsIGluY2x1ZGU9VCwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9N30NCiN0YWJsZSBmb3IgZW50aXJlIGxlYWd1ZTsgY29sdW1uIGNvbG9ycyB1c2luZyBDaGljYWdvIFNreSBoZXggY29sb3IgY29kZXMNCm1lYW5zX3NkX3Njb3JlJT4lDQogIGtibChkaWdpdHM9MixjYXB0aW9uPSJUQUJMRSAxIC0gMjAyNCBXTkJBIFRlYW0gU3RhdHMiKSU+JQ0KICBrYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGg9RixodG1sX2ZvbnQgPSAiQ2FtYnJpYSIpJT4lDQogIGNvbHVtbl9zcGVjKDIsYmFja2dyb3VuZD0iI2ZmY2QwMCIpJT4lDQogIGNvbHVtbl9zcGVjKDMsYmFja2dyb3VuZD0iIzQxOGZkZSIpJT4lDQogIGNvbHVtbl9zcGVjKDQsYmFja2dyb3VuZD0iI2ZmY2QwMCIpJT4lDQogIGNvbHVtbl9zcGVjKDUsYmFja2dyb3VuZD0iIzQxOGZkZSIpJT4lDQogIGNvbHVtbl9zcGVjKDYsYmFja2dyb3VuZD0iI2ZmY2QwMCIpJT4lDQogIGNvbHVtbl9zcGVjKDcsYmFja2dyb3VuZD0iIzQxOGZkZSIpJT4lDQogIGNvbHVtbl9zcGVjKDgsYmFja2dyb3VuZD0iI2ZmY2QwMCIpJT4lDQogIGNvbHVtbl9zcGVjKDksYmFja2dyb3VuZD0iIzQxOGZkZSIpJT4lDQogIGNvbHVtbl9zcGVjKDEwLGJhY2tncm91bmQ9IiNmZmNkMDAiKSU+JQ0KICBjb2x1bW5fc3BlYygxMSxiYWNrZ3JvdW5kPSIjNDE4ZmRlIikNCg0KI3RhYmxlIGZvciBteSB0ZWFtIGJhc2VkIG9uIHdpbi9sb3NzDQpteV90ZWFtX3dpbiU+JQ0KICBrYmwoZGlnaXRzPTIsY2FwdGlvbj0iVEFCTEUgMiAtIDIwMjQgQ2hpY2FnbyBTa3kgVGVhbSBTdGF0cyBieSBXaW4vTG9zcyIpJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aD1GLGh0bWxfZm9udCA9ICJDYW1icmlhIiklPiUNCiAgcm93X3NwZWMoMSxiYWNrZ3JvdW5kPSIjNDE4ZmRlIiklPiUNCiAgcm93X3NwZWMoMixiYWNrZ3JvdW5kPSIjZmZjZDAwIikNCiN0dXJuIG9mZiBmdWxsLXdpZHRoIGJ5IHB1dHRpbmcgZnVsbF93aWR0aD1GIGluIHBhcmVudGhlc2VzIGFmdGVyIGthYmxlX3N0eWxpbmcoKTsgY2FuIGNoYW5nZSBzdHlsZSBieSBsb29raW5nIG9ubGluZSBmb3IgZGlmZmVyZW50IGZvbnRzIGFuZCBkZXNpZ25zOyBkaWdpdHM9MiByb3VuZHMgdG8gMiBkZWNpbWFscw0KZGZfaGlzdD0gZGF0YSU+JQ0KICBmaWx0ZXIodGVhbV9uYW1lPT0iU2t5IikgJT4lDQogIG11dGF0ZShSZXN1bHQ9Y2FzZV93aGVuKHRlYW1fd2lubmVyPT1UfiJXaW4iLHRlYW1fd2lubmVyPT1GfiJMb3NzIikpDQpgYGANCg0KIyBHcmFwaHMNCg0KIyMgSGlzdG9ncmFtIGFuZCBCb3hwbG90DQpUaGUgaGlzdG9ncmFtIGJlbG93IGRlbW9uc3RyYXRlcyB0aGUgdGVhbSBzY29yZSBpbiBhIGdhbWUgdmVyc3VzIHRoZSBudW1iZXIgb2YgZ2FtZXMgb2J0YWluaW5nIHRoYXQgc2NvcmUsIHNwbGl0IGJ5IExvc3Mgb3IgV2luLiAgQm90aCBoaXN0b2dyYW1zIGRlbW9uc3RyYXRlIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gIA0KDQpUaGUgYm94cGxvdCBiZWxvdyBkZW1vbnN0cmF0ZXMgbG9zcy93aW4gdmVyc3VzIGdhbWUgcG9pbnRzIHNjb3JlZC4gIFRoZSBib3hwbG90cyBkZW1vbnN0cmF0ZSBvdmVybGFwIGluIHNjb3JlIHJhbmdlcyBhbmQgaGF2ZSBub3JtYWwgZGlzdHJpYnV0aW9ucywgd2l0aCB0aGUgYm94ZXMgYXBwcm94aW1hdGVseSBjZW50ZXJlZCBpbiB0aGVpciByZXNwZWN0aXZlIGRpc3RyaWJ1dGlvbnMuDQoNCg0KYGBge3IgZ3JhcGhzLCBpbmNsdWRlPVQsIG1lc3NhZ2U9RiwgZmlnLndpZHRoPTYsZmlnLmhlaWdodD03fQ0KI2hpc3RvZ3JhbSBjb2RlIHVzaW5nIHRlYW1fc2NvcmUgYXMgeC1heGlzIGFuZCBudW1iZXIgb2YgZ2FtZXMgd2l0aCB0aGF0IHNjb3JlIG9uIHktYXhpcywgDQojc2VwYXJhdGVkIGJ5IHdpbi9sb3NzICh5ZWxsb3cvYmx1ZSkNCnA9ZGZfaGlzdCU+JQ0KICBnZ3Bsb3QoYWVzKHg9dGVhbV9zY29yZSxmaWxsPVJlc3VsdCkpKw0KICAgIGdlb21faGlzdG9ncmFtKGNvbG9yPSIjZTllY2VmIixhbHBoYT0wLjYscG9zaXRpb249J2lkZW50aXR5JykrDQogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiM0MThmZGUiLCAiI2ZmY2QwMCIpKSsNCiAgICBsYWJzKHRpdGxlPSIyMDI0IENoaWNhZ28gU2t5IC0gVGVhbSBTY29yZSB2cyBOdW1iZXIgb2YgR2FtZXMiLHg9IlRlYW0gU2NvcmUiLCANCiAgICAgICAgIHkgPSAiTnVtYmVyIG9mIEdhbWVzIikNCg0KI2JveHBsb3Qgb2YgcmVzdWx0IHZzIGdhbWUgc2NvcmUgc2VwYXJhdGVkIGJ5IHdpbi9sb3NzICAgICANCnANCmJveHBsb3QodGVhbV9zY29yZSB+IFJlc3VsdCwgZGF0YSA9IGRmX2hpc3QsDQogICAgICAgIGNvbCA9IGMoIiM0MThmZGUiLCIjZmZjZDAwIiksDQogICAgICAgIG1haW49IlBvaW50cyBTY29yZWQgYnkgR2FtZSBSZXN1bHQiLA0KICAgICAgICB4bGFiPSJSZXN1bHQiLCB5bGFiPSJQb2ludHMiKQ0KI2p1c3QgdHlwaW5nIHAgd2lsbCAiY2FsbCIgb2JqZWN0IHAsIHdoaWNoIGlzIHRoZSBncmFwaCBhbmQgZ3JhcGggd2lsbCBhcHBlYXIgYmVsb3cgaWYgeW91IHJ1biBwIGFzIGFuIGluZGl2aWR1YWwgbGluZQ0KYGBgDQojIE1vZGVscw0KDQojIyBGaXJzdC1PcmRlciBNb2RlbA0KQSBmaXJzdC1vcmRlciBtb2RlbCB3YXMgY29uc3RydWN0ZWQgdXNpbmcgdGhlIHByZXZpb3VzbHkgc2VsZWN0ZWQgdmFyaWFibGVzICh0ZWFtIHNjb3JlLCBmaWVsZCBnb2FsIHBlcmNlbnRhZ2UsIHRvdGFsIHJlYm91bmRzLCB0aHJlZSBwb2ludCBmaWVsZCBnb2FsIHBlcmNlbnRhZ2UsIGFuZCBzdGVhbHMpLiAgTm8gbXVsdGljb2xsaW5lYXJpdHkgd2FzIG5vdGVkIChubyByPnwwLjh8KSwgYW5kIGFsbCB2YXJpYW5jZSBpbmZsYXRpb24gZmFjdG9ycyAoVklGKSB3ZXJlIGxlc3MgdGhhbiAyLiBBcyBhIHJlc3VsdCwgbm8gaW5kaXZpZHVhbCB2YXJpYWJsZXMgd2VyZSByZW1vdmVkIGZyb20gdGhlIGZpcnN0LW9yZGVyIG1vZGVsLiBUaGUgYWRqdXN0ZWQgUi1zcXVhcmVkIHdhcyA2Ni44JSB3aXRoIEYoNCwzNSk9MjAuNjEsIHA8LjAwMS4NCg0KIyMgSW50ZXJhY3Rpb24gTW9kZWwNCkEgc2Vjb25kLCBpbnRlcmFjdGlvbiBtb2RlbCB3YXMgYnVpbHQgYWRkaW5nIHRoZSBmb2xsb3dpbmcgdmFyaWFibGVzIHRvIHRoZSBmaXJzdC1vcmRlciBtb2RlbDogKGZpZWxkIGdvYWwgcGVyY2VudGFnZSAqIHRvdGFsIHJlYm91bmRzKSwgKGZpZWxkIGdvYWwgcGVyY2VudGFnZSAqIHRocmVlIHBvaW50IGZpZWxkIGdvYWwgcGVyY2VudGFnZSksIChmaWVsZCBnb2FsIHBlcmNlbnRhZ2UgKiBzdGVhbHMpLCAodG90YWwgcmVib3VuZHMgKiB0aHJlZSBwb2ludCBmaWVsZCBnb2FsIHBjdCksICh0b3RhbCByZWJvdW5kcyAqIHN0ZWFscyksIGFuZCAodGhyZWUgcG9pbnQgZmllbGQgZ29hbCBwZXJjZW50YWdlICogc3RlYWxzKS4gIE5vIGludGVyYWN0aW9uIHRlcm0gd2FzIGZvdW5kIHRvIGJlIHNpZ25pZmljYW50IGF0IHRoZSAxNSUgc2lnbmlmaWNhbmNlIGxldmVsLiBUaGUgYWRqdXN0ZWQgUi1zcXVhcmVkIGZvciB0aGUgaW50ZXJhY3Rpb24gbW9kZWwgd2FzIDYzLjIlIHdpdGggRigxMCwyOSk9Ny43MCwgcDwuMDAxLg0KDQojIyBNb2RlbCBVdGlsaXR5IENvbmNsdXNpb24NCkdpdmVuIG5vIHNpZ25pZmljYW50IGludGVyYWN0aW9uIHRlcm1zLCB0aGUgZmlyc3Qtb3JkZXIgbW9kZWwgd2FzIHJldGFpbmVkIGZvciBmdXJ0aGVyIGFuYWx5c2lzIGFuZCBwcmVkaWN0aW9uLg0KDQpgYGB7ciBmaXJzdCBvcmRlciBtb2RlbCwgcmVzdWx0cz0nYXNpcycsZWNobz1GLCBpbmNsdWRlPUZ9DQojZmlyc3Qtb3JkZXIgbW9kZWwgZm9yIG15IHRlYW0NCm1vZGVsXzE9bG0odGVhbV9zY29yZX5maWVsZF9nb2FsX3BjdCt0b3RhbF9yZWJvdW5kcyt0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCtzdGVhbHMsZGF0YT1teV90ZWFtKQ0KbW9kZWxfMXN1bT1zdW1tYXJ5KG1vZGVsXzEpDQoNCiNzZWxlY3Rpbmcgc3BlY2lmaWMgdmFyaWFibGVzIHRvIHJ1biBjb3JyZWxhdGlvbiBhbmFseXNpcyBvbg0KY29yX2RhdGE9bXlfdGVhbSAlPiUNCiAgc2VsZWN0KHRlYW1fc2NvcmUsZmllbGRfZ29hbF9wY3QsdG90YWxfcmVib3VuZHMsdGhyZWVfcG9pbnRfZmllbGRfZ29hbF9wY3Qsc3RlYWxzKQ0KDQojY29ycmVsYXRpb24gY29kZQ0KY29yKGNvcl9kYXRhKQ0KDQojdmFyaWFuY2UgaW5mbGF0aW9uIGZhY3RvciBjb2RlIHJ1biBvbiBtb2RlbF8xDQp2aWYobW9kZWxfMSkNCiNzdW1tYXJ5IHN0YXRzIG9uIG1vZGVsXzENCnN1bW1hcnkobW9kZWxfMSkNCg0KI25vIGhpZ2hseSBjb3JyZWxhdGVkIHBhaXJzIG5vdGVkLCBWSUZzIGFsbDwyDQoNCmBgYA0KDQpgYGB7ciBpbnRlcmFjdGlvbiBtb2RlbCwgaW5jbHVkZT1GfQ0KI21vZGVsXzIgaW5jbHVkZXMgbW9kZWxfMSB3aXRoIDYgaW50ZXJhY3Rpb24gZmFjdG9ycw0KbW9kZWxfMj1sbSh0ZWFtX3Njb3JlfmZpZWxkX2dvYWxfcGN0K3RvdGFsX3JlYm91bmRzK3RocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0K3N0ZWFscw0KICAgICAgICAgICArZmllbGRfZ29hbF9wY3QqdG90YWxfcmVib3VuZHMrZmllbGRfZ29hbF9wY3QqdGhyZWVfcG9pbnRfZmllbGRfZ29hbF9wY3QrZmllbGRfZ29hbF9wY3Qqc3RlYWxzK3RvdGFsX3JlYm91bmRzKnRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0K3RvdGFsX3JlYm91bmRzKnN0ZWFscyt0aHJlZV9wb2ludF9maWVsZF9nb2FsX3BjdCpzdGVhbHMsZGF0YT1teV90ZWFtKQ0KDQojc3VtbWFyeSBzdGF0cyBmb3IgbW9kZWxfMg0Kc3VtbWFyeShtb2RlbF8yKQ0KDQojbm8gc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb25zIHRvIHNpZ25pZmljYW5jZSBsZXZlbCBvZiAxNSUgbm90ZWQgc28gbW9kZWxfMSByZW1haW5zIG1vcmUgYXBwcm9wcmlhdGUNCmBgYA0KDQpNeSBmaW5hbCBtb2RlbCBpcyB0ZWFtX3Njb3JlPWByIG1vZGVsXzEkY29lZmZpY2llbnRbMV1gICsgYHIgbW9kZWxfMSRjb2VmZmljaWVudFsyXWAgKiBmaWVsZF9nb2FsX3BjdCArIGByIG1vZGVsXzEkY29lZmZpY2llbnRbM11gICogdG90YWxfcmVib3VuZHMgKyBgciBtb2RlbF8xJGNvZWZmaWNpZW50WzRdYCAqIHRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0ICsgYHIgbW9kZWxfMSRjb2VmZmljaWVudFs1XWAqIHN0ZWFscy4NCg0KVGhpcyBtb2RlbCBzaWduaWZpY2FudGx5IHByZWRpY3RzIHRlYW0gc2NvcmUsIEYoYHIgbW9kZWxfMXN1bSRmc3RhdGlzdGljWzJdYCxgciBtb2RlbF8xc3VtJGZzdGF0aXN0aWNbM11gKSA9IGByIG1vZGVsXzFzdW0kZnN0YXRpc3RpY1sxXWAsIHA8MC4wMDEsIGFkanVzdGVkIFItc3F1YXJlZD1gciBtb2RlbF8xc3VtJGFkai5yLnNxdWFyZWRgLiAgU2VlIHRoZSB0YWJsZSBiZWxvdyBmb3IgZnVydGhlciBhbmFseXNpcy4NCmBgYHtyLGluY2x1ZGU9VCwgZWNobz1GLCByZXN1bHRzPSdhc2lzJywgbWVzc2FnZT1GfQ0KbGlicmFyeShzdGFyZ2F6ZXIpDQpzdGFyZ2F6ZXIobW9kZWxfMSx0eXBlPSJodG1sIikNCmBgYA0KDQojIFJlc2lkdWFsIEFuYWx5c2lzDQoNClJlc2lkdWFsIGFuYWx5c2lzIHdhcyBwZXJmb3JtZWQgb24gdGhlIGZpcnN0LW9yZGVyIG1vZGVsIGluY2x1ZGluZyBhIGZpdHRlZCB2YWx1ZXMgcGxvdCwgYSByZXNpZHVhbCBoaXN0b2dyYW0sIFN0dWRlbnRpemVkIFJlc2lkdWFsLCBhIGdyYXBoIG9mIGxldmVyYWdlLCBhbmQgYSBDb29rJ3MgRCBwbG90LiBUaGUgZml0dGVkIHZhbHVlcyBwbG90IGRlbW9uc3RyYXRlZCBjb25zdGFudCB2YXJpYW5jZSwgYW5kIHRoZSByZXNpZHVhbCBoaXN0b2dyYW0gZGVtb25zdHJhdGVkIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiB0aGUgcmVzaWR1YWxzLiBObyBvdXRsaWVycyB3ZXJlIG5vdGVkIGluIHRoZSBTdHVkZW50aXplZCBSZXNpZHVhbCAodGhyZXNob2xkPXwzfCkuIFdpdGggYSBsZXZlcmFnZSB0aHJlc2hvbGQgb2YgMC4yNSwgZm91ciBnYW1lcyB3ZXJlIG5vdGVkIHRvIGhhdmUgaGlnaCBsZXZlcmFnZTogU2VwdGVtYmVyIDE5LCAyMDI0IHZlcnN1cyB0aGUgQ29ubmVjdGljdXQgU3VuIChPYnNlcnZhdGlvbiAxKTsgQXVndXN0IDI1LCAyMDI0IHZlcnN1cyB0aGUgTGFzIFZlZ2FzIEFjZXMgKE9ic2VydmF0aW9uIDEyKTsgQXVndXN0IDE4LCAyMDI0IHZlcnN1cyB0aGUgUGhvZW5peCBNZXJjdXJ5IChPYnNlcnZhdGlvbiAxNCk7IE1heSAyNSwyMDI0IHZlcnN1cyB0aGUgQ29ubmVjdGljdXQgU3VuIChPYnNlcnZhdGlvbiAzNykuIFR3byBnYW1lcyBoYWQgQ29vaydzIEQgdmFsdWVzIGdyZWF0ZXIgdGhhbiB0aGUgdGhyZXNob2xkIG9mIDAuMTogSnVseSAxMywgMjAyNCB2ZXJzdXMgdGhlIE5ldyBZb3JrIExpYmVydHkgKE9ic2VydmF0aW9uIDE4KSBhbmQgSnVuZSA0LCAyMDI0IHZlcnN1cyB0aGUgTmV3IFlvcmsgTGliZXJ0eSAoT2JzZXJ2YXRpb24gMzMpLg0KYGBge3IgcmVzaWR1YWxzLCBpbmNsdWRlPVQsZmlnLndpZHRoPTYsZmlnLmhlaWdodD03fQ0KI3Jlc2lkdWFsIGFuYWx5c2lzIG9uIG1vZGVsXzEgYXMgbm8gaW50ZXJhY3Rpb24gdGVybXMgd2VyZSBzaWduaWZpY2FudA0KI2luY2x1ZGVzIHZlcnN1cyBmaXQsIGhpc3RvZ3JhbSwgc3R1ZGVudGl6ZWQgcmVzaWR1YWwsIGxldmVyYWdlICh3aXRoIHRocmVzaG9sZCBvZiAzKSwgYW5kIENvb2sncyBEDQpvbHNfcGxvdF9yZXNpZF9maXQobW9kZWxfMSkNCm9sc19wbG90X3Jlc2lkX2hpc3QobW9kZWxfMSkNCm9sc19wbG90X3Jlc2lkX3N0dWQobW9kZWxfMSkNCm9sc19wbG90X3Jlc2lkX2xldihtb2RlbF8xLCB0aHJlc2hvbGQgPSAzKQ0Kb2xzX3Bsb3RfY29va3NkX2NoYXJ0KG1vZGVsXzEpDQpgYGANCg0KIyBQcmVkaWN0aW9uDQpgYGB7ciBwcmVkaWN0aW9uLCBpbmNsdWRlPUZ9DQpzdW1tYXJ5KGNvcl9kYXRhKQ0KI25ld2RhdGEgZnJhbWUgZm9yIG1lZGlhbiBvZiB2YXJpYWJsZXMgaW4gbW9kZWxfMQ0KbmV3ZGF0YT1kYXRhLmZyYW1lKGZpZWxkX2dvYWxfcGN0PTQyLjk1LHRvdGFsX3JlYm91bmRzPTM3LjAwLHRocmVlX3BvaW50X2ZpZWxkX2dvYWxfcGN0PTMzLjMwLHN0ZWFscz03KQ0KI3ByZWRpY3Rpb24gZm9yIHNjb3JlIGJhc2VkIG9uIG1lZGlhbiB2YWx1ZXMgb2YgdmFyaWFibGVzIGluIG1vZGVsXzENCnByZWRpY3Rpb249cHJlZGljdChtb2RlbF8xLG5ld2RhdGEsaW50ZXJ2YWw9ImNvbmZpZGVuY2UiLGxldmVsPS45NSkNCg0KI21vZGVsXzEgcHJlZGljdHMgc2NvcmUgb2YgODAgd2l0aCBhIDk1JSBDSVs3Nyw4MF0NCmBgYA0KSSBidWlsdCB0aGlzIG1vZGVsIHRvIHByZWRpY3QgbXkgdGVhbSdzIHBvaW50cyBmb3IgYSBnYW1lIGluIHdoaWNoIHRoZXkgYWNoaWV2ZWQgdGhlIG1lZGlhbiB2YWx1ZSBmb3IgZWFjaCB2YXJpYWJsZS4gVGhlIHByZWRpY3RlZCB0ZWFtIHNjb3JlIGlzIGByIHByZWRpY3Rpb25bMV1gLCB3aXRoIGEgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgKGByIHByZWRpY3Rpb25bMl1gLCBgciBwcmVkaWN0aW9uWzNdYCkuIA0KDQoNCg==