Results

All Mens Divisions: Wins vs Total Fights

Heavyweight vs Flyweight Activity

Competition time vs bout number

Between 2005 to 2022, Flyweights accumulated significantly more competition time (seconds) for the same number of bouts fought. This is a consequence of there being less stopages and thus more fights going the full distance to a decision.

Between 2005 to 2022, there was no significant difference between the amount of significant strikes landed by Flyweights vs Heavyweights. This result is suprising, as it’s assumed that flyweights have more activity and therefore significant strikes in competition time.

Heavyweight vs Flyweight Outcomes

The above box plots describe the different spread of fight outcomes (submission, decision, knockout or disqualification) between Heavyweight and Flyweight divisions.

Between 2005 to 2022, Heavyweights accumulated significantly more knockdowns than Flyweights for the same amount of competition time (seconds).

Between 2005 to 2022, Heavyweights accumulated significantly more knockouts for the same amount of competition time compared to Flyweights.



# Set up ------------------------------------------------------------------

library(ggplot2)
library(dplyr)
library(gganimate)
library(purrr)
library(gapminder)
library(lubridate)
library(gifski)

getwd()
setwd("./mmadata_up_to_20220622")

mma <- read.csv("masterdataframe.csv")


Mens_division <- c("Heavyweight", "Light Heavyweight", "Middleweight", "Welterweight", "Lightweight","Featherweight","Bantamweight","Flyweight")


column_names <- data.frame(colnames(mma))


mma$POSixTime <- as.POSIXct(mma$date, format="%Y-%m-%d")

mma$count <- 1



# Total Fight time by fighter ---------------------------------------------


fight_time <- mma %>%
  filter(POSixTime > "2005-01-01")%>%
  group_by(fighter, division) %>%
  summarise(total_comp_time = sum(total_comp_time),count = sum(count))%>%
  filter(division %in% c("Flyweight", "Heavyweight"))
  


plot_1<-
  ggplot(fight_time, 
       aes(x = total_comp_time,
           y = count,
           color = division),
       size = 3)+
  geom_point()+
  geom_smooth(formula = y ~ x, method = "lm")+ 
  coord_cartesian(xlim=c(0, 15000), ylim = c(0,20))+
  labs(x= "Total Competition Time (seconds)", y= "Number of bouts", title = "Number of bouts vs competition time")



# Significant strikes by fight time ---------------------------------------


fight_sig_strikes <- mma %>%
  filter(POSixTime > "2005-01-01")%>%
  group_by(fighter, division) %>%
  summarise(total_comp_time = sum(total_comp_time),sig_strikes_landed = sum(sig_strikes_landed))%>%
  filter(division %in% c("Flyweight", "Heavyweight"))



plot_2<-
  ggplot(fight_sig_strikes, 
       aes(x = total_comp_time,
           y = sig_strikes_landed,
           color = division),
       size = 3)+
  geom_point()+
  geom_smooth(formula = y ~ x, method = "lm")+ 
  coord_cartesian(xlim=c(0, 15000), ylim = c(0,1000))+
  labs(x= "Total Competition Time (seconds)", y= "Number of bouts", title = "Number of signifcant strikes vs competition time")




# knockdowns by fight time --------------------------------------



fight_kd <- mma %>%
  filter(POSixTime > "2005-01-01")%>%
  group_by(fighter, division) %>%
  summarise(total_comp_time = sum(total_comp_time),knockdowns = sum(knockdowns))%>%
  filter(division %in% c("Flyweight", "Heavyweight"))



plot_3<-
  ggplot(fight_kd, 
       aes(x = total_comp_time,
           y = knockdowns,
           color = division),
       size = 3)+
  geom_point()+
  geom_smooth(formula = y ~ x, method = "lm")+
  labs(x= "Total Competition Time (seconds)", y= "Number of knockdowns", title = "Number of knockdowns vs competition time")+
  coord_cartesian(xlim=c(0, 15000), ylim = c(0,15))





# KO's by fight time ----------------------------------------------------------


ko_count <- mma%>%
  filter(method == "KO/TKO")%>%
  filter(division %in% c("Flyweight", "Heavyweight"))%>%
  group_by(fighter, division)%>%
  summarise(KO = sum(count))

fight_ko <- mma %>%
  filter(POSixTime > "2005-01-01")%>%
  group_by(fighter, division) %>%
  summarise(total_comp_time = sum(total_comp_time))%>%
  filter(division %in% c("Flyweight", "Heavyweight"))%>%
  inner_join(ko_count)



plot_4<-
  ggplot(fight_ko, 
       aes(x = total_comp_time,
           y = KO,
           color = division),
       size = 3)+
  geom_point()+
  geom_smooth(formula = y ~ x, method = "lm")+ 
  coord_cartesian(xlim=c(0, 15000), ylim = c(0,15))+
  labs(x= "Total Competition Time (seconds)", y= "Number of knockouts", title = "Number of knockouts vs competition time")




# Method of victory boxplots ----------------------------------------------

# Box plots facet wrapped (by finish type) for DEC,SUB,KO/TKO
# Each point representing fighter, y = count of finished, x = HW or FW



# lookup to aggregate decisions

method_2 <-
  data.frame(unique(mma$method))%>%
  mutate(method_2 = c("Submission","KO/TKO","Decision","Decision","Decision","Decision","Disqualification"))

colnames(method_2)<-(c("method","method_2"))




method_count <- mma%>%
  inner_join(method_2)%>%
  filter(POSixTime > "2005-01-01")%>%
  filter(division %in% c("Flyweight", "Heavyweight"))%>%
  group_by(fighter, division, method_2)%>%
  summarise(method_3 = sum(count))


plot_5 <-
  ggplot(method_count, aes(x = division, y = method_3, colour = method_2))+
    geom_jitter(color = "azure4", size =0.7)+
    geom_boxplot(aes(alpha = 0.8))+
    facet_wrap(~method_2)+
    labs(x = "Weight division", y = "Number of fights", title = "Number of finishes by method and weight division")+
    theme(legend.position = "none")





# Longest win streak ------------------------------------------------------

#xy scatter with x = number of fights, y = number of wins and z = time(year) and size = cumulative win streak


#column names for input df

gganimate_col_names <- c("year","fighter","division","total_fights","streak_to_date")



#year column for time lapse
mma$year_month <- format(mma$POSixTime,"%m-%Y")
as.Date(mma$year_month)


#count win streak by year

#sort old to recent
sort(mma$POSixTime,decreasing = T)


# for a given fighter, check $result, if 1: sum to previous count, if 0: reset to 0.


winstreak <- 
  mma %>% group_by(fighter) %>%
  mutate(winstreak = accumulate(result, ~ifelse(.y == 0, .y, .x + .y)))%>%
  mutate(fights_to_date = cumsum(count))%>%
  mutate(wins_to_date = cumsum(result))%>%
  select(c("POSixTime",
           "year_month",
           "fighter",
           "fights_to_date",
           "wins_to_date", 
           "winstreak",
           "division"))



winstreak_animate <- mma%>%
  inner_join(winstreak[,c("POSixTime",
                          "fighter",
                          "winstreak",
                          "fights_to_date",
                          "wins_to_date")], 
             by = c("fighter" = "fighter", 
                    "POSixTime"="POSixTime"))%>%
  select(c("POSixTime",
           "year_month" ,
           "fighter",
           "fights_to_date",
           "wins_to_date",
           "winstreak",
           "division"))%>%
  filter(division %in% Mens_division)


#date fixing

winstreak_animate2 <- winstreak_animate%>%
  mutate(Date2 = floor_date(as_date(POSixTime),"month"))

plot_6 <-
  ggplot(winstreak_animate2, 
         aes(x = fights_to_date, 
             y = wins_to_date, 
             colour = division,
             size = winstreak))+
  geom_point()+
  labs(x = "Fights to date", 
       y = "Wins to date", 
       title = "Number of finishes by method and weight division")+
  transition_time(Date2)

#plot_6_animated <- 
  animate(plot_6, fps =3, renderer = gifski_renderer())

anim_save("mma_xy_scatter.gif", plot_6_animated)
warnings()
LS0tDQp0aXRsZTogIlVGQyBGaWdodCBPdXRjb21lcyBBbmFseXNpcyINCmF1dGhvcjoNCi0gbmFtZTogR2VvcmdlIEFrb21mcmFoDQotIG5hbWU6IGh0dHBzOi8vd3d3LmxpbmtlZGluLmNvbS9pbi9nZW9yZ2UtYWtvbWZyYWgvLw0KZGF0ZTogIjE5LzA4LzIwMjIiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCmFic3RyYWN0OiBUaGlzIHJlcG9ydCBzdW1tYXJpc2VzIG1peGVkIG1hcnRpYWwgYXJ0cyAoTU1BKSBkYXRhIGZyb20gYm91dHMgdW5kZXIgdGhlDQogIFVsdGltYXRlIEZpZ2h0aW5nIENoYW1waW9uc2hpcCAoVUZDKSBwcm9tb3Rpb24uIFRoYXQgZGF0YSB1c2VkIHdhcyBUaGlzIGFuYWx5c2lzDQogIGFuZCB2aXN1YWxpc2lvbiBoYXMgYmVlbiBjb25kdWN0ZWQgdXNpbmcgRFBMWVIgYW5kIEdHUExPVDIuIHNjcmFwZWQgZnJvbSB1ZmNzdGF0cy5jb20NCiAgYW5kIG1hZGUgcHVibGljbHkgYXZhaWxhYmxlIHRocm91Z2gga2FnZ2xlLmNvbS4gKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvZGFubWNpbmVybmV5L21tYS1kaWZmZXJlbnRpYWxzLWFuZC1lbG8/cmVzb3VyY2U9ZG93bmxvYWQpLg0KLS0tDQoNCiMjIFJlc3VsdHMgey50YWJzZXR9DQoNCiMjIyBBbGwgTWVucyBEaXZpc2lvbnM6IFdpbnMgdnMgVG90YWwgRmlnaHRzDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZScsZmlnLmtlZXA9J2FsbCd9DQoNCmBgYA0KIVtdKGZpbGUyYjc0NmVjMjc1YmYuZ2lmKQ0KDQoNCg0KIyMjIEhlYXZ5d2VpZ2h0IHZzIEZseXdlaWdodCBBY3Rpdml0eQ0KDQoNCioqQ29tcGV0aXRpb24gdGltZSB2cyBib3V0IG51bWJlcioqDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZScsZmlnLmtlZXA9J2FsbCd9DQoNCnByaW50KHBsb3RfMSkNCmBgYA0KDQpCZXR3ZWVuIDIwMDUgdG8gMjAyMiwgRmx5d2VpZ2h0cyBhY2N1bXVsYXRlZCBzaWduaWZpY2FudGx5IG1vcmUgY29tcGV0aXRpb24gdGltZSAoc2Vjb25kcykgZm9yIHRoZSBzYW1lIG51bWJlciBvZiBib3V0cyBmb3VnaHQuIFRoaXMgaXMgYSBjb25zZXF1ZW5jZSBvZiB0aGVyZSBiZWluZyBsZXNzIHN0b3BhZ2VzIGFuZCB0aHVzIG1vcmUgZmlnaHRzIGdvaW5nIHRoZSBmdWxsIGRpc3RhbmNlIHRvIGEgZGVjaXNpb24uDQoNCg0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZScsZmlnLmtlZXA9J2FsbCd9DQoNCg0KcHJpbnQocGxvdF8yKQ0KYGBgDQoNCkJldHdlZW4gMjAwNSB0byAyMDIyLCB0aGVyZSB3YXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBhbW91bnQgb2Ygc2lnbmlmaWNhbnQgc3RyaWtlcyBsYW5kZWQgYnkgRmx5d2VpZ2h0cyB2cyBIZWF2eXdlaWdodHMuIFRoaXMgcmVzdWx0IGlzIHN1cHJpc2luZywgYXMgaXQncyBhc3N1bWVkIHRoYXQgZmx5d2VpZ2h0cyBoYXZlIG1vcmUgYWN0aXZpdHkgYW5kIHRoZXJlZm9yZSBzaWduaWZpY2FudCBzdHJpa2VzIGluIGNvbXBldGl0aW9uIHRpbWUuIA0KDQoNCiMjIyBIZWF2eXdlaWdodCB2cyBGbHl3ZWlnaHQgT3V0Y29tZXMNCg0KYGBge3IsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJyxmaWcua2VlcD0nYWxsJ30NCg0KcHJpbnQocGxvdF81KQ0KYGBgDQoNClRoZSBhYm92ZSBib3ggcGxvdHMgZGVzY3JpYmUgdGhlIGRpZmZlcmVudCBzcHJlYWQgb2YgZmlnaHQgb3V0Y29tZXMgKHN1Ym1pc3Npb24sIGRlY2lzaW9uLCBrbm9ja291dCBvciBkaXNxdWFsaWZpY2F0aW9uKSBiZXR3ZWVuIEhlYXZ5d2VpZ2h0IGFuZCBGbHl3ZWlnaHQgZGl2aXNpb25zLiANCg0KYGBge3IsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPUZBTFNFLCByZXN1bHRzPSdoaWRlJyxmaWcua2VlcD0nYWxsJ30NCg0KcHJpbnQocGxvdF8zKQ0KYGBgDQoNCkJldHdlZW4gMjAwNSB0byAyMDIyLCBIZWF2eXdlaWdodHMgYWNjdW11bGF0ZWQgc2lnbmlmaWNhbnRseSBtb3JlIGtub2NrZG93bnMgdGhhbiBGbHl3ZWlnaHRzIGZvciB0aGUgc2FtZSBhbW91bnQgb2YgY29tcGV0aXRpb24gdGltZSAoc2Vjb25kcykuIA0KDQoNCg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9RkFMU0UsIHJlc3VsdHM9J2hpZGUnLGZpZy5rZWVwPSdhbGwnfQ0KDQpwcmludChwbG90XzQpDQpgYGANCkJldHdlZW4gMjAwNSB0byAyMDIyLCBIZWF2eXdlaWdodHMgYWNjdW11bGF0ZWQgc2lnbmlmaWNhbnRseSBtb3JlIGtub2Nrb3V0cyBmb3IgdGhlIHNhbWUgYW1vdW50IG9mIGNvbXBldGl0aW9uIHRpbWUgY29tcGFyZWQgdG8gRmx5d2VpZ2h0cy4gDQoNCmBgYHtyfQ0KDQoNCiMgU2V0IHVwIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ2FuaW1hdGUpDQpsaWJyYXJ5KHB1cnJyKQ0KbGlicmFyeShnYXBtaW5kZXIpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoZ2lmc2tpKQ0KDQpnZXR3ZCgpDQpzZXR3ZCgiLi9tbWFkYXRhX3VwX3RvXzIwMjIwNjIyIikNCg0KbW1hIDwtIHJlYWQuY3N2KCJtYXN0ZXJkYXRhZnJhbWUuY3N2IikNCg0KDQpNZW5zX2RpdmlzaW9uIDwtIGMoIkhlYXZ5d2VpZ2h0IiwgIkxpZ2h0IEhlYXZ5d2VpZ2h0IiwgIk1pZGRsZXdlaWdodCIsICJXZWx0ZXJ3ZWlnaHQiLCAiTGlnaHR3ZWlnaHQiLCJGZWF0aGVyd2VpZ2h0IiwiQmFudGFtd2VpZ2h0IiwiRmx5d2VpZ2h0IikNCg0KDQpjb2x1bW5fbmFtZXMgPC0gZGF0YS5mcmFtZShjb2xuYW1lcyhtbWEpKQ0KDQoNCm1tYSRQT1NpeFRpbWUgPC0gYXMuUE9TSVhjdChtbWEkZGF0ZSwgZm9ybWF0PSIlWS0lbS0lZCIpDQoNCm1tYSRjb3VudCA8LSAxDQoNCg0KDQojIFRvdGFsIEZpZ2h0IHRpbWUgYnkgZmlnaHRlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KDQpmaWdodF90aW1lIDwtIG1tYSAlPiUNCiAgZmlsdGVyKFBPU2l4VGltZSA+ICIyMDA1LTAxLTAxIiklPiUNCiAgZ3JvdXBfYnkoZmlnaHRlciwgZGl2aXNpb24pICU+JQ0KICBzdW1tYXJpc2UodG90YWxfY29tcF90aW1lID0gc3VtKHRvdGFsX2NvbXBfdGltZSksY291bnQgPSBzdW0oY291bnQpKSU+JQ0KICBmaWx0ZXIoZGl2aXNpb24gJWluJSBjKCJGbHl3ZWlnaHQiLCAiSGVhdnl3ZWlnaHQiKSkNCiAgDQoNCg0KcGxvdF8xPC0NCiAgZ2dwbG90KGZpZ2h0X3RpbWUsIA0KICAgICAgIGFlcyh4ID0gdG90YWxfY29tcF90aW1lLA0KICAgICAgICAgICB5ID0gY291bnQsDQogICAgICAgICAgIGNvbG9yID0gZGl2aXNpb24pLA0KICAgICAgIHNpemUgPSAzKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX3Ntb290aChmb3JtdWxhID0geSB+IHgsIG1ldGhvZCA9ICJsbSIpKyANCiAgY29vcmRfY2FydGVzaWFuKHhsaW09YygwLCAxNTAwMCksIHlsaW0gPSBjKDAsMjApKSsNCiAgbGFicyh4PSAiVG90YWwgQ29tcGV0aXRpb24gVGltZSAoc2Vjb25kcykiLCB5PSAiTnVtYmVyIG9mIGJvdXRzIiwgdGl0bGUgPSAiTnVtYmVyIG9mIGJvdXRzIHZzIGNvbXBldGl0aW9uIHRpbWUiKQ0KDQoNCg0KIyBTaWduaWZpY2FudCBzdHJpa2VzIGJ5IGZpZ2h0IHRpbWUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCg0KZmlnaHRfc2lnX3N0cmlrZXMgPC0gbW1hICU+JQ0KICBmaWx0ZXIoUE9TaXhUaW1lID4gIjIwMDUtMDEtMDEiKSU+JQ0KICBncm91cF9ieShmaWdodGVyLCBkaXZpc2lvbikgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9jb21wX3RpbWUgPSBzdW0odG90YWxfY29tcF90aW1lKSxzaWdfc3RyaWtlc19sYW5kZWQgPSBzdW0oc2lnX3N0cmlrZXNfbGFuZGVkKSklPiUNCiAgZmlsdGVyKGRpdmlzaW9uICVpbiUgYygiRmx5d2VpZ2h0IiwgIkhlYXZ5d2VpZ2h0IikpDQoNCg0KDQpwbG90XzI8LQ0KICBnZ3Bsb3QoZmlnaHRfc2lnX3N0cmlrZXMsIA0KICAgICAgIGFlcyh4ID0gdG90YWxfY29tcF90aW1lLA0KICAgICAgICAgICB5ID0gc2lnX3N0cmlrZXNfbGFuZGVkLA0KICAgICAgICAgICBjb2xvciA9IGRpdmlzaW9uKSwNCiAgICAgICBzaXplID0gMykrDQogIGdlb21fcG9pbnQoKSsNCiAgZ2VvbV9zbW9vdGgoZm9ybXVsYSA9IHkgfiB4LCBtZXRob2QgPSAibG0iKSsgDQogIGNvb3JkX2NhcnRlc2lhbih4bGltPWMoMCwgMTUwMDApLCB5bGltID0gYygwLDEwMDApKSsNCiAgbGFicyh4PSAiVG90YWwgQ29tcGV0aXRpb24gVGltZSAoc2Vjb25kcykiLCB5PSAiTnVtYmVyIG9mIGJvdXRzIiwgdGl0bGUgPSAiTnVtYmVyIG9mIHNpZ25pZmNhbnQgc3RyaWtlcyB2cyBjb21wZXRpdGlvbiB0aW1lIikNCg0KDQoNCg0KIyBrbm9ja2Rvd25zIGJ5IGZpZ2h0IHRpbWUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KDQoNCmZpZ2h0X2tkIDwtIG1tYSAlPiUNCiAgZmlsdGVyKFBPU2l4VGltZSA+ICIyMDA1LTAxLTAxIiklPiUNCiAgZ3JvdXBfYnkoZmlnaHRlciwgZGl2aXNpb24pICU+JQ0KICBzdW1tYXJpc2UodG90YWxfY29tcF90aW1lID0gc3VtKHRvdGFsX2NvbXBfdGltZSksa25vY2tkb3ducyA9IHN1bShrbm9ja2Rvd25zKSklPiUNCiAgZmlsdGVyKGRpdmlzaW9uICVpbiUgYygiRmx5d2VpZ2h0IiwgIkhlYXZ5d2VpZ2h0IikpDQoNCg0KDQpwbG90XzM8LQ0KICBnZ3Bsb3QoZmlnaHRfa2QsIA0KICAgICAgIGFlcyh4ID0gdG90YWxfY29tcF90aW1lLA0KICAgICAgICAgICB5ID0ga25vY2tkb3ducywNCiAgICAgICAgICAgY29sb3IgPSBkaXZpc2lvbiksDQogICAgICAgc2l6ZSA9IDMpKw0KICBnZW9tX3BvaW50KCkrDQogIGdlb21fc21vb3RoKGZvcm11bGEgPSB5IH4geCwgbWV0aG9kID0gImxtIikrDQogIGxhYnMoeD0gIlRvdGFsIENvbXBldGl0aW9uIFRpbWUgKHNlY29uZHMpIiwgeT0gIk51bWJlciBvZiBrbm9ja2Rvd25zIiwgdGl0bGUgPSAiTnVtYmVyIG9mIGtub2NrZG93bnMgdnMgY29tcGV0aXRpb24gdGltZSIpKw0KICBjb29yZF9jYXJ0ZXNpYW4oeGxpbT1jKDAsIDE1MDAwKSwgeWxpbSA9IGMoMCwxNSkpDQoNCg0KDQoNCg0KIyBLTydzIGJ5IGZpZ2h0IHRpbWUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQoNCmtvX2NvdW50IDwtIG1tYSU+JQ0KICBmaWx0ZXIobWV0aG9kID09ICJLTy9US08iKSU+JQ0KICBmaWx0ZXIoZGl2aXNpb24gJWluJSBjKCJGbHl3ZWlnaHQiLCAiSGVhdnl3ZWlnaHQiKSklPiUNCiAgZ3JvdXBfYnkoZmlnaHRlciwgZGl2aXNpb24pJT4lDQogIHN1bW1hcmlzZShLTyA9IHN1bShjb3VudCkpDQoNCmZpZ2h0X2tvIDwtIG1tYSAlPiUNCiAgZmlsdGVyKFBPU2l4VGltZSA+ICIyMDA1LTAxLTAxIiklPiUNCiAgZ3JvdXBfYnkoZmlnaHRlciwgZGl2aXNpb24pICU+JQ0KICBzdW1tYXJpc2UodG90YWxfY29tcF90aW1lID0gc3VtKHRvdGFsX2NvbXBfdGltZSkpJT4lDQogIGZpbHRlcihkaXZpc2lvbiAlaW4lIGMoIkZseXdlaWdodCIsICJIZWF2eXdlaWdodCIpKSU+JQ0KICBpbm5lcl9qb2luKGtvX2NvdW50KQ0KDQoNCg0KcGxvdF80PC0NCiAgZ2dwbG90KGZpZ2h0X2tvLCANCiAgICAgICBhZXMoeCA9IHRvdGFsX2NvbXBfdGltZSwNCiAgICAgICAgICAgeSA9IEtPLA0KICAgICAgICAgICBjb2xvciA9IGRpdmlzaW9uKSwNCiAgICAgICBzaXplID0gMykrDQogIGdlb21fcG9pbnQoKSsNCiAgZ2VvbV9zbW9vdGgoZm9ybXVsYSA9IHkgfiB4LCBtZXRob2QgPSAibG0iKSsgDQogIGNvb3JkX2NhcnRlc2lhbih4bGltPWMoMCwgMTUwMDApLCB5bGltID0gYygwLDE1KSkrDQogIGxhYnMoeD0gIlRvdGFsIENvbXBldGl0aW9uIFRpbWUgKHNlY29uZHMpIiwgeT0gIk51bWJlciBvZiBrbm9ja291dHMiLCB0aXRsZSA9ICJOdW1iZXIgb2Yga25vY2tvdXRzIHZzIGNvbXBldGl0aW9uIHRpbWUiKQ0KDQoNCg0KDQojIE1ldGhvZCBvZiB2aWN0b3J5IGJveHBsb3RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyBCb3ggcGxvdHMgZmFjZXQgd3JhcHBlZCAoYnkgZmluaXNoIHR5cGUpIGZvciBERUMsU1VCLEtPL1RLTw0KIyBFYWNoIHBvaW50IHJlcHJlc2VudGluZyBmaWdodGVyLCB5ID0gY291bnQgb2YgZmluaXNoZWQsIHggPSBIVyBvciBGVw0KDQoNCg0KIyBsb29rdXAgdG8gYWdncmVnYXRlIGRlY2lzaW9ucw0KDQptZXRob2RfMiA8LQ0KICBkYXRhLmZyYW1lKHVuaXF1ZShtbWEkbWV0aG9kKSklPiUNCiAgbXV0YXRlKG1ldGhvZF8yID0gYygiU3VibWlzc2lvbiIsIktPL1RLTyIsIkRlY2lzaW9uIiwiRGVjaXNpb24iLCJEZWNpc2lvbiIsIkRlY2lzaW9uIiwiRGlzcXVhbGlmaWNhdGlvbiIpKQ0KDQpjb2xuYW1lcyhtZXRob2RfMik8LShjKCJtZXRob2QiLCJtZXRob2RfMiIpKQ0KDQoNCg0KDQptZXRob2RfY291bnQgPC0gbW1hJT4lDQogIGlubmVyX2pvaW4obWV0aG9kXzIpJT4lDQogIGZpbHRlcihQT1NpeFRpbWUgPiAiMjAwNS0wMS0wMSIpJT4lDQogIGZpbHRlcihkaXZpc2lvbiAlaW4lIGMoIkZseXdlaWdodCIsICJIZWF2eXdlaWdodCIpKSU+JQ0KICBncm91cF9ieShmaWdodGVyLCBkaXZpc2lvbiwgbWV0aG9kXzIpJT4lDQogIHN1bW1hcmlzZShtZXRob2RfMyA9IHN1bShjb3VudCkpDQoNCg0KcGxvdF81IDwtDQogIGdncGxvdChtZXRob2RfY291bnQsIGFlcyh4ID0gZGl2aXNpb24sIHkgPSBtZXRob2RfMywgY29sb3VyID0gbWV0aG9kXzIpKSsNCiAgICBnZW9tX2ppdHRlcihjb2xvciA9ICJhenVyZTQiLCBzaXplID0wLjcpKw0KICAgIGdlb21fYm94cGxvdChhZXMoYWxwaGEgPSAwLjgpKSsNCiAgICBmYWNldF93cmFwKH5tZXRob2RfMikrDQogICAgbGFicyh4ID0gIldlaWdodCBkaXZpc2lvbiIsIHkgPSAiTnVtYmVyIG9mIGZpZ2h0cyIsIHRpdGxlID0gIk51bWJlciBvZiBmaW5pc2hlcyBieSBtZXRob2QgYW5kIHdlaWdodCBkaXZpc2lvbiIpKw0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KDQoNCg0KDQojIExvbmdlc3Qgd2luIHN0cmVhayAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KI3h5IHNjYXR0ZXIgd2l0aCB4ID0gbnVtYmVyIG9mIGZpZ2h0cywgeSA9IG51bWJlciBvZiB3aW5zIGFuZCB6ID0gdGltZSh5ZWFyKSBhbmQgc2l6ZSA9IGN1bXVsYXRpdmUgd2luIHN0cmVhaw0KDQoNCiNjb2x1bW4gbmFtZXMgZm9yIGlucHV0IGRmDQoNCmdnYW5pbWF0ZV9jb2xfbmFtZXMgPC0gYygieWVhciIsImZpZ2h0ZXIiLCJkaXZpc2lvbiIsInRvdGFsX2ZpZ2h0cyIsInN0cmVha190b19kYXRlIikNCg0KDQoNCiN5ZWFyIGNvbHVtbiBmb3IgdGltZSBsYXBzZQ0KbW1hJHllYXJfbW9udGggPC0gZm9ybWF0KG1tYSRQT1NpeFRpbWUsIiVtLSVZIikNCmFzLkRhdGUobW1hJHllYXJfbW9udGgpDQoNCg0KI2NvdW50IHdpbiBzdHJlYWsgYnkgeWVhcg0KDQojc29ydCBvbGQgdG8gcmVjZW50DQpzb3J0KG1tYSRQT1NpeFRpbWUsZGVjcmVhc2luZyA9IFQpDQoNCg0KIyBmb3IgYSBnaXZlbiBmaWdodGVyLCBjaGVjayAkcmVzdWx0LCBpZiAxOiBzdW0gdG8gcHJldmlvdXMgY291bnQsIGlmIDA6IHJlc2V0IHRvIDAuDQoNCg0Kd2luc3RyZWFrIDwtIA0KICBtbWEgJT4lIGdyb3VwX2J5KGZpZ2h0ZXIpICU+JQ0KICBtdXRhdGUod2luc3RyZWFrID0gYWNjdW11bGF0ZShyZXN1bHQsIH5pZmVsc2UoLnkgPT0gMCwgLnksIC54ICsgLnkpKSklPiUNCiAgbXV0YXRlKGZpZ2h0c190b19kYXRlID0gY3Vtc3VtKGNvdW50KSklPiUNCiAgbXV0YXRlKHdpbnNfdG9fZGF0ZSA9IGN1bXN1bShyZXN1bHQpKSU+JQ0KICBzZWxlY3QoYygiUE9TaXhUaW1lIiwNCiAgICAgICAgICAgInllYXJfbW9udGgiLA0KICAgICAgICAgICAiZmlnaHRlciIsDQogICAgICAgICAgICJmaWdodHNfdG9fZGF0ZSIsDQogICAgICAgICAgICJ3aW5zX3RvX2RhdGUiLCANCiAgICAgICAgICAgIndpbnN0cmVhayIsDQogICAgICAgICAgICJkaXZpc2lvbiIpKQ0KDQoNCg0Kd2luc3RyZWFrX2FuaW1hdGUgPC0gbW1hJT4lDQogIGlubmVyX2pvaW4od2luc3RyZWFrWyxjKCJQT1NpeFRpbWUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlnaHRlciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICJ3aW5zdHJlYWsiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlnaHRzX3RvX2RhdGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAid2luc190b19kYXRlIildLCANCiAgICAgICAgICAgICBieSA9IGMoImZpZ2h0ZXIiID0gImZpZ2h0ZXIiLCANCiAgICAgICAgICAgICAgICAgICAgIlBPU2l4VGltZSI9IlBPU2l4VGltZSIpKSU+JQ0KICBzZWxlY3QoYygiUE9TaXhUaW1lIiwNCiAgICAgICAgICAgInllYXJfbW9udGgiICwNCiAgICAgICAgICAgImZpZ2h0ZXIiLA0KICAgICAgICAgICAiZmlnaHRzX3RvX2RhdGUiLA0KICAgICAgICAgICAid2luc190b19kYXRlIiwNCiAgICAgICAgICAgIndpbnN0cmVhayIsDQogICAgICAgICAgICJkaXZpc2lvbiIpKSU+JQ0KICBmaWx0ZXIoZGl2aXNpb24gJWluJSBNZW5zX2RpdmlzaW9uKQ0KDQoNCiNkYXRlIGZpeGluZw0KDQp3aW5zdHJlYWtfYW5pbWF0ZTIgPC0gd2luc3RyZWFrX2FuaW1hdGUlPiUNCiAgbXV0YXRlKERhdGUyID0gZmxvb3JfZGF0ZShhc19kYXRlKFBPU2l4VGltZSksIm1vbnRoIikpDQoNCnBsb3RfNiA8LQ0KICBnZ3Bsb3Qod2luc3RyZWFrX2FuaW1hdGUyLCANCiAgICAgICAgIGFlcyh4ID0gZmlnaHRzX3RvX2RhdGUsIA0KICAgICAgICAgICAgIHkgPSB3aW5zX3RvX2RhdGUsIA0KICAgICAgICAgICAgIGNvbG91ciA9IGRpdmlzaW9uLA0KICAgICAgICAgICAgIHNpemUgPSB3aW5zdHJlYWspKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBsYWJzKHggPSAiRmlnaHRzIHRvIGRhdGUiLCANCiAgICAgICB5ID0gIldpbnMgdG8gZGF0ZSIsIA0KICAgICAgIHRpdGxlID0gIk51bWJlciBvZiBmaW5pc2hlcyBieSBtZXRob2QgYW5kIHdlaWdodCBkaXZpc2lvbiIpKw0KICB0cmFuc2l0aW9uX3RpbWUoRGF0ZTIpDQoNCiNwbG90XzZfYW5pbWF0ZWQgPC0gDQogIGFuaW1hdGUocGxvdF82LCBmcHMgPTMsIHJlbmRlcmVyID0gZ2lmc2tpX3JlbmRlcmVyKCkpDQoNCmFuaW1fc2F2ZSgibW1hX3h5X3NjYXR0ZXIuZ2lmIiwgcGxvdF82X2FuaW1hdGVkKQ0Kd2FybmluZ3MoKQ0KDQpgYGANCg0K