Distribution Fitting
In order to proceed further, first of all we need to investigate which distribution our data follows. As our problem statement is based on calculaing probability of scoring goals as home team and visitor team, therefore, we will consider Poisson distribution rather than any other distribution.
We worked on 3 cases to prove our consideration of Poisson distribution
Case 1. Assumptions for Poisson Distribution :
- K is the number of times a goal occurs during a match and K can take values 0, 1, 2, .
- The occurrence of scoring goals in one match does not affect the probability of scoring goals in the other match.
- That is, events occur independently.
- A team plays one match at a time. It cannot be participating in two matches at the same time.
- The probability of scoring a goal is proportional to the duration of the match.
As our data meets the aforementioned assumptions, hence, K (number of goals in a match) is a Poisson random variable, and the distribution is a Poisson distribution.
Case 2. The mean of goals scored is almost same as variance of goals scored when Bayern Munchen played as Home Team and as Visitor Team, this also favours poisson distribution.
Main_data_Bayern_home_goal<-Data_Club_as_Home[,6]
home_mean<- round(Main_data_Bayern_home_goal %>% mean(),2)
home_var<-round(Main_data_Bayern_home_goal %>% var(),2)
home_sum<-round(Main_data_Bayern_home_goal %>% sum(),2)
Main_data_Bayern_visitor_goal<-Data_Club_as_Visitor[,7]
visitor_mean<-round(Main_data_Bayern_visitor_goal %>% mean(),2)
visitor_var<-round(Main_data_Bayern_visitor_goal %>% var(),2)
visitor_sum<-Main_data_Bayern_visitor_goal %>% sum()
stats_data_home<-rbind(home_sum,home_mean,home_var)
stats_data_visitor<-rbind(visitor_sum,visitor_mean,visitor_var)
statistic_name<-c("Sum","Mean","Variance")
stats_data<-cbind(statistic_name,stats_data_home,stats_data_visitor) %>% as.data.frame()
colnames(stats_data)<-c("Statistic","As Home","As Visitor")
rownames(stats_data)<-1:3
stats_data
Case 3. We will compare Theoretical Distribution (using poisson function dpois,lambda=mean) and Empirical Distribution (by using probability formula, eg number of matches in which goals scored is 0/total number of matches….so on…till 10) as home team and visitor team separately.
—–> EMPIRICAL VS THEORETICAL DISTRIBUTION (AS HOME)
Empirical & Theoretical Probability Function as Home
Home_Team_data<-Data_Club_as_Home
plot_df_practical_home<-data.frame(c(0:10))
for (i in 1:11){
plot_df_practical_home[i,2]<-round((length(Home_Team_data[Home_Team_data$hgoal==i-1,6])/nrow(Home_Team_data))*100,2)
}
plot_df_theoretical_home<-data.frame(c(0:10))
for (i in 1:11){
plot_df_theoretical_home[i,2]<-round(dpois(i-1,home_mean)*100,2)
}
plot_df_theoretical_home_error<-data.frame(c(0:10))
for (i in 1:11){
plot_df_theoretical_home_error[i,2]<-(plot_df_theoretical_home[i,2]-plot_df_practical_home[i,2])^2
}
names(plot_df_theoretical_home)<-c("Goals","Theoretical Probability Scoring as Home")
names(plot_df_practical_home)<-c("Goals","Empirical Probability Scoring as Home")
names(plot_df_theoretical_home_error)<-c("Goals","Error Square")
df_plot_prac_theo_home<-cbind.data.frame(plot_df_practical_home,plot_df_theoretical_home$`Theoretical Probability Scoring as Home`,plot_df_theoretical_home_error$`Error Square`)
names(df_plot_prac_theo_home)<-c("Goals","Emp. Prob. Home","Theo. Prob. Home","Error Square")
df_plot_prac_theo_home
Comparison of Empirical & Theoretical Distribution As Home on single plot
plot(plot_df_practical_home$Goals,plot_df_practical_home[,2],ylim=c(0,60),ylab="Probability (%)",xlab="Number of Goals",type="l",col="black",lwd=2,main=paste(Home_Team," Empirical vs Theoretical Prob. Distribution (Home)"))
lines(plot_df_theoretical_home$Goals,plot_df_theoretical_home[,2],ylim=c(0,60),ylab="Probability (%)",xlab="Number of Goals",col="#0066ff",lwd=2)
legend('topright', c("Empirical Distribution","Theoretical Distribution") ,
lty=1, col=c( "black","#0066ff"), bty='n', cex=.75)
grid()
—–> EMPIRICAL VS THEORETICAL DISTRIBUTION (AS VISITOR)
Empirical & Theoretical Probability Function as Visitor
Visitor_Team_data<-Data_Club_as_Visitor
plot_prac_theo_visitor<-data.frame(c(0:10))
for (i in 1:11){
plot_prac_theo_visitor[i,2]<-round((length(Visitor_Team_data[Visitor_Team_data$hgoal==i-1,6])/nrow(Visitor_Team_data))*100,2)
}
for (i in 1:11){
plot_prac_theo_visitor[i,3]<-round(dpois(i-1,visitor_mean)*100,2)
}
for (i in 1:11){
plot_prac_theo_visitor[i,4]<-(plot_prac_theo_visitor[i,3]-plot_prac_theo_visitor[i,2])^2
}
names(plot_prac_theo_visitor)<-c("Goals","Emp. Prob. Visitor","Theo. Prob. Visitor","Error Square")
plot_prac_theo_visitor
Comparison of Empirical & Theoretical Distribution As Visitor on single plot
plot(plot_prac_theo_visitor$Goals,plot_prac_theo_visitor[,2],ylim=c(0,60),ylab="Probability (%)",xlab="Number of Goals",type="l",col="black",lwd=2,main=paste(Home_Team," Empirical vs Theoretical Prob. Distribution (Visitor)"))
lines(plot_prac_theo_visitor$Goals,plot_prac_theo_visitor[,3],ylim=c(0,60),ylab="Probability (%)",xlab="Number of Goals",col="#cc9900",lwd=2)
legend('topright', c("Empirical Distribution","Theoretical Distribution") ,
lty=1, col=c("black","#cc9900"), bty='n', cex=.75)
grid()
Error Analysis
Home_team_prob_Error<-round(df_plot_prac_theo_home[,4]%>%mean()%>%sqrt(),2)
Visitor_Team_prob_error<-round(plot_prac_theo_visitor[,4]%>%mean()%>%sqrt(),2)
Error_df<-cbind.data.frame(Home_team_prob_Error,Visitor_Team_prob_error)
names(Error_df)<-c("As Home Team","As Visitor Team")
rownames(Error_df)<-"Error %"
Error_df
As all 3 cases nearly favours Poisson Distribution, hence we will use Poisson Distribution for the interpretation of our problem statement.
Interpretation
Empirical Data Distribution (As Home vs As Visitor)
Home_Team<-"Bayern Munchen"
plot_df_practical<-data.frame(c(0:10))
for (i in 1:11){
plot_df_practical[i,2]<-round(dpois(i-1,home_mean)*100,2)
}
for (i in 1:11){
plot_df_practical[i,3]<-round(dpois(i-1,visitor_mean)*100,2)
}
names(plot_df_practical)<-c("Goals","Probability of Home Team Scoring","Probability of Visitor Team Scoring")
plot(plot_df_practical$Goals,plot_df_practical$`Probability of Home Team Scoring`,ylim=c(0,60),ylab="Probability (%)",xlab="Number of Goals",type="l",col="#0066ff",lwd=2,main=paste(Home_Team," Probability Distribution as Home v/s Visitor"))
lines(plot_df_practical$Goals,plot_df_practical$`Probability of Visitor Team Scoring`,ylim=c(0,60),ylab="Probability (%)",xlab="Number of Goals",col="#cc9900",lwd=2)
legend('topright', c("Probability As Home Team","Probability As Visitor Team") ,
lty=1, col=c("#0066ff","#cc9900"), bty='n', cex=.75)
grid()
Insights
Majorly 2 insights can be derived from the above plot,
- Bayern Munchen has more probability of scoring goals under 2 being a visitor team rather being as home team.
- As the number of goals crosses the 2 mark, Bayern Munchen has greater probability of scoring goals being a home team.
LS0tDQp0aXRsZTogIk1BVEgxMzI0IEFzc2lnbm1lbnQgMiINCnN1YnRpdGxlOiAiTW9kZWxsaW5nIHRoZSBEaXN0cmlidXRpb24gb2YgRm9vdGJhbGwgR29hbHMiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIyBQcm9ibGVtIFN0YXRlbWVudA0KDQpDb21wYXJpbmcgdGhlIHBlcmZvcm1hbmNlIG9mIENsdWIgIkJheWVybiBNdW5jaGVuIiBhcyBhIGhvbWUgdGVhbSBhbmQgYXMgYSB2aXNpdG9yIHRlYW0gdXNpbmcgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uIGZvciBnb2FscyBzY29yZWQuDQoNCiMjIExvYWQgUGFja2FnZXMNCg0KDQpgYGB7cn0NCmxpYnJhcnkocmVwbWlzKQ0KbGlicmFyeShkcGx5cikNCmBgYA0KDQojIyBEYXRhDQoNCioqIERhdGEgaGFzIGJlZW4gaW1wb3J0ZWQgZnJvbSBnaXRodWIgdXNpbmcgcGFja2FnZSAicmVwbWlzIg0KDQpgYGB7cn0NCnNvdXJjZV9kYXRhKCJodHRwczovL2dpdGh1Yi5jb20vamFsYXBpYy9lbmdzb2NjZXJkYXRhL2Jsb2IvbWFzdGVyL2RhdGEvZ2VybWFueS5yZGE/cmF3PVRydWUiKQ0KbWFpbl9kYXRhPC1hcy5kYXRhLmZyYW1lKGdlcm1hbnkpICAgICNkYXRhIHdpdGggMTYxMjAgcm93cyBmcm9tIDE5NjMtMjAxNg0KYGBgDQoNClZhcmlhYmxlIERlc2NyaXB0aW9uDQoNCjEuIGRhdGUgLSBkYXRlIG9mIG1hdGNoL3RpZQ0KMi4gU2Vhc29uIC0gc2Vhc29uIChlLmcuIDIwMTIgcmVmZXJzIHRvIDIwMTIvMTMgc2Vhc29uKQ0KMy4gaG9tZSAtIGhvbWUgdGVhbSAobm90ZSBmb3IgZ2FtZXMgcGxheWVkIGF0IG5ldXRyYWwgdmVudWVzIHRoaXMgaXNuJ3QgcmVsZXZhbnQpDQo0LiB2aXNpdG9yIC0gdmlzaXRpbmcgdGVhbSAobm90ZSBmb3IgZ2FtZXMgcGxheWVkIGF0IG5ldXRyYWwgdmVudWVzIHRoaXMgaXNuJ3QgcmVsZXZhbnQpDQo1LiBGVCAtIGZpbmFsIHNjb3JlLiB0aGlzIGlzIHRoZSBmaW5hbCBzY29yZSBldmVuIGFmdGVyIGV4dHJhIHRpbWUgKGkuZS4gbm90IGp1c3QgYWZ0ZXIgOTAgbWludXRlcykNCjYuIGhnb2FsIC0gbnVtYmVyIG9mIGdvYWxzIHNjb3JlZCBieSB0ZWFtIHdoZW4gcGxheWVkIGFzIGhvbWUgdGVhbQ0KNy4gdmdvYWwgLSBudW1iZXIgb2YgZ29hbHMgc2NvcmVkIGJ5IHRlYW0gd2hlbiBwbGF5ZWQgYXMgdmlzaXRvciB0ZWFtDQoNCg0KVHdvIERhdGFmcmFtZXMgYXJlIG1hZGUgYnkgZmlsdGVyaW5nIGltcG9ydGVkIGRhdGEgb24gaG9tZSBhbmQgdmlzaXRvciBjb2x1bW4gZm9yIEJheWVybiBNdW5jaGVuDQoNCmBgYHtyfQ0KSG9tZV9UZWFtPC0iQmF5ZXJuIE11bmNoZW4iDQpWaXNpdG9yX1RlYW08LSJCYXllcm4gTXVuY2hlbiINCkRhdGFfQ2x1Yl9hc19Ib21lPC1tYWluX2RhdGFbbWFpbl9kYXRhJGhvbWU9PUhvbWVfVGVhbSxdDQpEYXRhX0NsdWJfYXNfVmlzaXRvcjwtbWFpbl9kYXRhW21haW5fZGF0YSR2aXNpdG9yPT1WaXNpdG9yX1RlYW0sXQ0KYGBgDQoNCiMjIERpc3RyaWJ1dGlvbiBGaXR0aW5nDQoNCg0KSW4gb3JkZXIgdG8gcHJvY2VlZCBmdXJ0aGVyLCBmaXJzdCBvZiBhbGwgd2UgbmVlZCB0byBpbnZlc3RpZ2F0ZSB3aGljaCBkaXN0cmlidXRpb24gb3VyIGRhdGEgZm9sbG93cy4NCkFzIG91ciBwcm9ibGVtIHN0YXRlbWVudCBpcyBiYXNlZCBvbiBjYWxjdWxhaW5nIHByb2JhYmlsaXR5IG9mIHNjb3JpbmcgZ29hbHMgYXMgaG9tZSB0ZWFtIGFuZCB2aXNpdG9yIHRlYW0sDQp0aGVyZWZvcmUsIHdlIHdpbGwgY29uc2lkZXIgUG9pc3NvbiBkaXN0cmlidXRpb24gcmF0aGVyIHRoYW4gYW55IG90aGVyIGRpc3RyaWJ1dGlvbi4NCg0KV2Ugd29ya2VkIG9uIDMgY2FzZXMgdG8gcHJvdmUgb3VyIGNvbnNpZGVyYXRpb24gb2YgUG9pc3NvbiBkaXN0cmlidXRpb24NCg0KQ2FzZSAxLiBBc3N1bXB0aW9ucyBmb3IgUG9pc3NvbiBEaXN0cmlidXRpb24gOg0KDQoxLiBLIGlzIHRoZSBudW1iZXIgb2YgdGltZXMgYSBnb2FsIG9jY3VycyBkdXJpbmcgYSBtYXRjaCBhbmQgSyBjYW4gdGFrZSB2YWx1ZXMgMCwgMSwgMiwgLg0KMi4gVGhlIG9jY3VycmVuY2Ugb2Ygc2NvcmluZyBnb2FscyBpbiBvbmUgbWF0Y2ggZG9lcyBub3QgYWZmZWN0IHRoZSBwcm9iYWJpbGl0eSBvZiBzY29yaW5nIGdvYWxzIGluIHRoZSBvdGhlciBtYXRjaC4NCjMuIFRoYXQgaXMsIGV2ZW50cyBvY2N1ciBpbmRlcGVuZGVudGx5Lg0KNC4gQSB0ZWFtIHBsYXlzIG9uZSBtYXRjaCBhdCBhIHRpbWUuIEl0IGNhbm5vdCBiZSBwYXJ0aWNpcGF0aW5nIGluIHR3byBtYXRjaGVzIGF0IHRoZSBzYW1lIHRpbWUuDQo1LiBUaGUgcHJvYmFiaWxpdHkgb2Ygc2NvcmluZyBhIGdvYWwgaXMgcHJvcG9ydGlvbmFsIHRvIHRoZSBkdXJhdGlvbiBvZiB0aGUgbWF0Y2guDQoNCg0KQXMgb3VyIGRhdGEgbWVldHMgdGhlIGFmb3JlbWVudGlvbmVkIGFzc3VtcHRpb25zLCBoZW5jZSwgSyAobnVtYmVyIG9mIGdvYWxzIGluIGEgbWF0Y2gpIGlzIGEgUG9pc3NvbiByYW5kb20gdmFyaWFibGUsIGFuZCB0aGUgZGlzdHJpYnV0aW9uIGlzIGEgUG9pc3NvbiBkaXN0cmlidXRpb24uDQoNCkNhc2UgMi4gVGhlIG1lYW4gb2YgZ29hbHMgc2NvcmVkIGlzIGFsbW9zdCBzYW1lIGFzIHZhcmlhbmNlIG9mIGdvYWxzIHNjb3JlZCB3aGVuIEJheWVybiBNdW5jaGVuIHBsYXllZCBhcyBIb21lIFRlYW0gYW5kIGFzIFZpc2l0b3IgVGVhbSwgdGhpcyBhbHNvIGZhdm91cnMgcG9pc3NvbiBkaXN0cmlidXRpb24uDQoNCmBgYHtyfQ0KTWFpbl9kYXRhX0JheWVybl9ob21lX2dvYWw8LURhdGFfQ2x1Yl9hc19Ib21lWyw2XQ0KaG9tZV9tZWFuPC0gcm91bmQoTWFpbl9kYXRhX0JheWVybl9ob21lX2dvYWwgJT4lIG1lYW4oKSwyKQ0KaG9tZV92YXI8LXJvdW5kKE1haW5fZGF0YV9CYXllcm5faG9tZV9nb2FsICU+JSB2YXIoKSwyKQ0KaG9tZV9zdW08LXJvdW5kKE1haW5fZGF0YV9CYXllcm5faG9tZV9nb2FsICU+JSBzdW0oKSwyKQ0KTWFpbl9kYXRhX0JheWVybl92aXNpdG9yX2dvYWw8LURhdGFfQ2x1Yl9hc19WaXNpdG9yWyw3XQ0KdmlzaXRvcl9tZWFuPC1yb3VuZChNYWluX2RhdGFfQmF5ZXJuX3Zpc2l0b3JfZ29hbCAlPiUgbWVhbigpLDIpDQp2aXNpdG9yX3Zhcjwtcm91bmQoTWFpbl9kYXRhX0JheWVybl92aXNpdG9yX2dvYWwgJT4lIHZhcigpLDIpDQp2aXNpdG9yX3N1bTwtTWFpbl9kYXRhX0JheWVybl92aXNpdG9yX2dvYWwgJT4lIHN1bSgpDQpzdGF0c19kYXRhX2hvbWU8LXJiaW5kKGhvbWVfc3VtLGhvbWVfbWVhbixob21lX3ZhcikNCnN0YXRzX2RhdGFfdmlzaXRvcjwtcmJpbmQodmlzaXRvcl9zdW0sdmlzaXRvcl9tZWFuLHZpc2l0b3JfdmFyKQ0Kc3RhdGlzdGljX25hbWU8LWMoIlN1bSIsIk1lYW4iLCJWYXJpYW5jZSIpDQpzdGF0c19kYXRhPC1jYmluZChzdGF0aXN0aWNfbmFtZSxzdGF0c19kYXRhX2hvbWUsc3RhdHNfZGF0YV92aXNpdG9yKSAlPiUgYXMuZGF0YS5mcmFtZSgpDQpjb2xuYW1lcyhzdGF0c19kYXRhKTwtYygiU3RhdGlzdGljIiwiQXMgSG9tZSIsIkFzIFZpc2l0b3IiKQ0Kcm93bmFtZXMoc3RhdHNfZGF0YSk8LTE6Mw0Kc3RhdHNfZGF0YQ0KYGBgDQoNCkNhc2UgMy4gV2Ugd2lsbCBjb21wYXJlIFRoZW9yZXRpY2FsIERpc3RyaWJ1dGlvbiAodXNpbmcgcG9pc3NvbiBmdW5jdGlvbiBkcG9pcyxsYW1iZGE9bWVhbikgYW5kIEVtcGlyaWNhbCBEaXN0cmlidXRpb24gKGJ5IHVzaW5nIHByb2JhYmlsaXR5IGZvcm11bGEsIGVnIG51bWJlciBvZiBtYXRjaGVzIGluIHdoaWNoIGdvYWxzIHNjb3JlZCBpcyAwL3RvdGFsIG51bWJlciBvZiBtYXRjaGVzLi4uLnNvIG9uLi4udGlsbCAxMCkgYXMgaG9tZSB0ZWFtIGFuZCB2aXNpdG9yIHRlYW0gc2VwYXJhdGVseS4NCg0KDQoNCi0tLS0tPiBFTVBJUklDQUwgVlMgVEhFT1JFVElDQUwgRElTVFJJQlVUSU9OIChBUyBIT01FKQ0KDQoNCkVtcGlyaWNhbCAmIFRoZW9yZXRpY2FsIFByb2JhYmlsaXR5IEZ1bmN0aW9uIGFzIEhvbWUNCg0KYGBge3J9DQoNCkhvbWVfVGVhbV9kYXRhPC1EYXRhX0NsdWJfYXNfSG9tZQ0KcGxvdF9kZl9wcmFjdGljYWxfaG9tZTwtZGF0YS5mcmFtZShjKDA6MTApKQ0KDQpmb3IgKGkgaW4gMToxMSl7DQogIHBsb3RfZGZfcHJhY3RpY2FsX2hvbWVbaSwyXTwtcm91bmQoKGxlbmd0aChIb21lX1RlYW1fZGF0YVtIb21lX1RlYW1fZGF0YSRoZ29hbD09aS0xLDZdKS9ucm93KEhvbWVfVGVhbV9kYXRhKSkqMTAwLDIpDQp9DQoNCnBsb3RfZGZfdGhlb3JldGljYWxfaG9tZTwtZGF0YS5mcmFtZShjKDA6MTApKQ0KZm9yIChpIGluIDE6MTEpew0KICBwbG90X2RmX3RoZW9yZXRpY2FsX2hvbWVbaSwyXTwtcm91bmQoZHBvaXMoaS0xLGhvbWVfbWVhbikqMTAwLDIpDQp9DQoNCnBsb3RfZGZfdGhlb3JldGljYWxfaG9tZV9lcnJvcjwtZGF0YS5mcmFtZShjKDA6MTApKQ0KZm9yIChpIGluIDE6MTEpew0KICBwbG90X2RmX3RoZW9yZXRpY2FsX2hvbWVfZXJyb3JbaSwyXTwtKHBsb3RfZGZfdGhlb3JldGljYWxfaG9tZVtpLDJdLXBsb3RfZGZfcHJhY3RpY2FsX2hvbWVbaSwyXSleMg0KfQ0KDQpuYW1lcyhwbG90X2RmX3RoZW9yZXRpY2FsX2hvbWUpPC1jKCJHb2FscyIsIlRoZW9yZXRpY2FsIFByb2JhYmlsaXR5IFNjb3JpbmcgYXMgSG9tZSIpDQpuYW1lcyhwbG90X2RmX3ByYWN0aWNhbF9ob21lKTwtYygiR29hbHMiLCJFbXBpcmljYWwgUHJvYmFiaWxpdHkgU2NvcmluZyBhcyBIb21lIikNCm5hbWVzKHBsb3RfZGZfdGhlb3JldGljYWxfaG9tZV9lcnJvcik8LWMoIkdvYWxzIiwiRXJyb3IgU3F1YXJlIikNCmRmX3Bsb3RfcHJhY190aGVvX2hvbWU8LWNiaW5kLmRhdGEuZnJhbWUocGxvdF9kZl9wcmFjdGljYWxfaG9tZSxwbG90X2RmX3RoZW9yZXRpY2FsX2hvbWUkYFRoZW9yZXRpY2FsIFByb2JhYmlsaXR5IFNjb3JpbmcgYXMgSG9tZWAscGxvdF9kZl90aGVvcmV0aWNhbF9ob21lX2Vycm9yJGBFcnJvciBTcXVhcmVgKQ0KbmFtZXMoZGZfcGxvdF9wcmFjX3RoZW9faG9tZSk8LWMoIkdvYWxzIiwiRW1wLiBQcm9iLiBIb21lIiwiVGhlby4gUHJvYi4gSG9tZSIsIkVycm9yIFNxdWFyZSIpDQpkZl9wbG90X3ByYWNfdGhlb19ob21lDQpgYGANCg0KQ29tcGFyaXNvbiBvZiBFbXBpcmljYWwgJiBUaGVvcmV0aWNhbCBEaXN0cmlidXRpb24gQXMgSG9tZSBvbiBzaW5nbGUgcGxvdCAgICAgICAgICAgICAgICANCg0KYGBge3J9DQpwbG90KHBsb3RfZGZfcHJhY3RpY2FsX2hvbWUkR29hbHMscGxvdF9kZl9wcmFjdGljYWxfaG9tZVssMl0seWxpbT1jKDAsNjApLHlsYWI9IlByb2JhYmlsaXR5ICglKSIseGxhYj0iTnVtYmVyIG9mIEdvYWxzIix0eXBlPSJsIixjb2w9ImJsYWNrIixsd2Q9MixtYWluPXBhc3RlKEhvbWVfVGVhbSwiIEVtcGlyaWNhbCB2cyBUaGVvcmV0aWNhbCBQcm9iLiBEaXN0cmlidXRpb24gKEhvbWUpIikpDQpsaW5lcyhwbG90X2RmX3RoZW9yZXRpY2FsX2hvbWUkR29hbHMscGxvdF9kZl90aGVvcmV0aWNhbF9ob21lWywyXSx5bGltPWMoMCw2MCkseWxhYj0iUHJvYmFiaWxpdHkgKCUpIix4bGFiPSJOdW1iZXIgb2YgR29hbHMiLGNvbD0iIzAwNjZmZiIsbHdkPTIpDQpsZWdlbmQoJ3RvcHJpZ2h0JywgYygiRW1waXJpY2FsIERpc3RyaWJ1dGlvbiIsIlRoZW9yZXRpY2FsIERpc3RyaWJ1dGlvbiIpICwgDQogICBsdHk9MSwgY29sPWMoICJibGFjayIsIiMwMDY2ZmYiKSwgYnR5PSduJywgY2V4PS43NSkNCmdyaWQoKQ0KYGBgDQoNCg0KLS0tLS0+IEVNUElSSUNBTCBWUyBUSEVPUkVUSUNBTCBESVNUUklCVVRJT04gKEFTIFZJU0lUT1IpDQoNCg0KRW1waXJpY2FsICYgVGhlb3JldGljYWwgUHJvYmFiaWxpdHkgRnVuY3Rpb24gYXMgVmlzaXRvcg0KDQpgYGB7cn0NClZpc2l0b3JfVGVhbV9kYXRhPC1EYXRhX0NsdWJfYXNfVmlzaXRvcg0KcGxvdF9wcmFjX3RoZW9fdmlzaXRvcjwtZGF0YS5mcmFtZShjKDA6MTApKQ0KDQpmb3IgKGkgaW4gMToxMSl7DQogIHBsb3RfcHJhY190aGVvX3Zpc2l0b3JbaSwyXTwtcm91bmQoKGxlbmd0aChWaXNpdG9yX1RlYW1fZGF0YVtWaXNpdG9yX1RlYW1fZGF0YSRoZ29hbD09aS0xLDZdKS9ucm93KFZpc2l0b3JfVGVhbV9kYXRhKSkqMTAwLDIpDQp9DQoNCmZvciAoaSBpbiAxOjExKXsNCiAgcGxvdF9wcmFjX3RoZW9fdmlzaXRvcltpLDNdPC1yb3VuZChkcG9pcyhpLTEsdmlzaXRvcl9tZWFuKSoxMDAsMikNCn0NCmZvciAoaSBpbiAxOjExKXsNCiAgcGxvdF9wcmFjX3RoZW9fdmlzaXRvcltpLDRdPC0ocGxvdF9wcmFjX3RoZW9fdmlzaXRvcltpLDNdLXBsb3RfcHJhY190aGVvX3Zpc2l0b3JbaSwyXSleMg0KfQ0KbmFtZXMocGxvdF9wcmFjX3RoZW9fdmlzaXRvcik8LWMoIkdvYWxzIiwiRW1wLiBQcm9iLiBWaXNpdG9yIiwiVGhlby4gUHJvYi4gVmlzaXRvciIsIkVycm9yIFNxdWFyZSIpDQpwbG90X3ByYWNfdGhlb192aXNpdG9yDQpgYGANCg0KQ29tcGFyaXNvbiBvZiBFbXBpcmljYWwgJiBUaGVvcmV0aWNhbCBEaXN0cmlidXRpb24gQXMgVmlzaXRvciBvbiBzaW5nbGUgcGxvdCAgICAgICANCg0KYGBge3J9DQpwbG90KHBsb3RfcHJhY190aGVvX3Zpc2l0b3IkR29hbHMscGxvdF9wcmFjX3RoZW9fdmlzaXRvclssMl0seWxpbT1jKDAsNjApLHlsYWI9IlByb2JhYmlsaXR5ICglKSIseGxhYj0iTnVtYmVyIG9mIEdvYWxzIix0eXBlPSJsIixjb2w9ImJsYWNrIixsd2Q9MixtYWluPXBhc3RlKEhvbWVfVGVhbSwiIEVtcGlyaWNhbCB2cyBUaGVvcmV0aWNhbCBQcm9iLiBEaXN0cmlidXRpb24gKFZpc2l0b3IpIikpDQpsaW5lcyhwbG90X3ByYWNfdGhlb192aXNpdG9yJEdvYWxzLHBsb3RfcHJhY190aGVvX3Zpc2l0b3JbLDNdLHlsaW09YygwLDYwKSx5bGFiPSJQcm9iYWJpbGl0eSAoJSkiLHhsYWI9Ik51bWJlciBvZiBHb2FscyIsY29sPSIjY2M5OTAwIixsd2Q9MikNCmxlZ2VuZCgndG9wcmlnaHQnLCBjKCJFbXBpcmljYWwgRGlzdHJpYnV0aW9uIiwiVGhlb3JldGljYWwgRGlzdHJpYnV0aW9uIikgLCANCiAgIGx0eT0xLCBjb2w9YygiYmxhY2siLCIjY2M5OTAwIiksIGJ0eT0nbicsIGNleD0uNzUpDQpncmlkKCkNCmBgYA0KDQoNCkVycm9yIEFuYWx5c2lzDQoNCmBgYHtyfQ0KSG9tZV90ZWFtX3Byb2JfRXJyb3I8LXJvdW5kKGRmX3Bsb3RfcHJhY190aGVvX2hvbWVbLDRdJT4lbWVhbigpJT4lc3FydCgpLDIpDQpWaXNpdG9yX1RlYW1fcHJvYl9lcnJvcjwtcm91bmQocGxvdF9wcmFjX3RoZW9fdmlzaXRvclssNF0lPiVtZWFuKCklPiVzcXJ0KCksMikNCkVycm9yX2RmPC1jYmluZC5kYXRhLmZyYW1lKEhvbWVfdGVhbV9wcm9iX0Vycm9yLFZpc2l0b3JfVGVhbV9wcm9iX2Vycm9yKQ0KbmFtZXMoRXJyb3JfZGYpPC1jKCJBcyBIb21lIFRlYW0iLCJBcyBWaXNpdG9yIFRlYW0iKQ0Kcm93bmFtZXMoRXJyb3JfZGYpPC0iRXJyb3IgJSINCkVycm9yX2RmDQpgYGANCg0KDQpBcyBhbGwgMyBjYXNlcyBuZWFybHkgZmF2b3VycyBQb2lzc29uIERpc3RyaWJ1dGlvbiwgaGVuY2Ugd2Ugd2lsbCB1c2UgUG9pc3NvbiBEaXN0cmlidXRpb24gZm9yIHRoZSBpbnRlcnByZXRhdGlvbiBvZiBvdXIgcHJvYmxlbSBzdGF0ZW1lbnQuDQoNCg0KIyMgSW50ZXJwcmV0YXRpb24NCg0KRW1waXJpY2FsIERhdGEgRGlzdHJpYnV0aW9uIChBcyBIb21lIHZzIEFzIFZpc2l0b3IpDQoNCmBgYHtyfQ0KSG9tZV9UZWFtPC0iQmF5ZXJuIE11bmNoZW4iDQpwbG90X2RmX3ByYWN0aWNhbDwtZGF0YS5mcmFtZShjKDA6MTApKQ0KDQpmb3IgKGkgaW4gMToxMSl7DQogIHBsb3RfZGZfcHJhY3RpY2FsW2ksMl08LXJvdW5kKGRwb2lzKGktMSxob21lX21lYW4pKjEwMCwyKQ0KfQ0KDQpmb3IgKGkgaW4gMToxMSl7DQogIHBsb3RfZGZfcHJhY3RpY2FsW2ksM108LXJvdW5kKGRwb2lzKGktMSx2aXNpdG9yX21lYW4pKjEwMCwyKQ0KfQ0KDQpuYW1lcyhwbG90X2RmX3ByYWN0aWNhbCk8LWMoIkdvYWxzIiwiUHJvYmFiaWxpdHkgb2YgSG9tZSBUZWFtIFNjb3JpbmciLCJQcm9iYWJpbGl0eSBvZiBWaXNpdG9yIFRlYW0gU2NvcmluZyIpDQpwbG90KHBsb3RfZGZfcHJhY3RpY2FsJEdvYWxzLHBsb3RfZGZfcHJhY3RpY2FsJGBQcm9iYWJpbGl0eSBvZiBIb21lIFRlYW0gU2NvcmluZ2AseWxpbT1jKDAsNjApLHlsYWI9IlByb2JhYmlsaXR5ICglKSIseGxhYj0iTnVtYmVyIG9mIEdvYWxzIix0eXBlPSJsIixjb2w9IiMwMDY2ZmYiLGx3ZD0yLG1haW49cGFzdGUoSG9tZV9UZWFtLCIgUHJvYmFiaWxpdHkgRGlzdHJpYnV0aW9uIGFzIEhvbWUgdi9zIFZpc2l0b3IiKSkNCmxpbmVzKHBsb3RfZGZfcHJhY3RpY2FsJEdvYWxzLHBsb3RfZGZfcHJhY3RpY2FsJGBQcm9iYWJpbGl0eSBvZiBWaXNpdG9yIFRlYW0gU2NvcmluZ2AseWxpbT1jKDAsNjApLHlsYWI9IlByb2JhYmlsaXR5ICglKSIseGxhYj0iTnVtYmVyIG9mIEdvYWxzIixjb2w9IiNjYzk5MDAiLGx3ZD0yKQ0KbGVnZW5kKCd0b3ByaWdodCcsIGMoIlByb2JhYmlsaXR5IEFzIEhvbWUgVGVhbSIsIlByb2JhYmlsaXR5IEFzIFZpc2l0b3IgVGVhbSIpICwgDQogICBsdHk9MSwgY29sPWMoIiMwMDY2ZmYiLCIjY2M5OTAwIiksIGJ0eT0nbicsIGNleD0uNzUpDQpncmlkKCkNCmBgYA0KIyMjIEluc2lnaHRzDQoNCk1ham9ybHkgMiBpbnNpZ2h0cyBjYW4gYmUgZGVyaXZlZCBmcm9tIHRoZSBhYm92ZSBwbG90LA0KDQoxLiBCYXllcm4gTXVuY2hlbiBoYXMgbW9yZSBwcm9iYWJpbGl0eSBvZiBzY29yaW5nIGdvYWxzIHVuZGVyIDIgYmVpbmcgYSB2aXNpdG9yIHRlYW0gDQogICByYXRoZXIgYmVpbmcgYXMgaG9tZSB0ZWFtLg0KMi4gQXMgdGhlIG51bWJlciBvZiBnb2FscyBjcm9zc2VzIHRoZSAyIG1hcmssIEJheWVybiBNdW5jaGVuIGhhcyBncmVhdGVyIHByb2JhYmlsaXR5IG9mIA0KICAgc2NvcmluZyBnb2FscyBiZWluZyBhIGhvbWUgdGVhbS4NCg==