# my_folder <- 'P:/Nhansu/Du lieu cham cong - Theo doi ngay nghi/Du lieu cham cong/Hoi so/'
# files <- list.files(my_folder, pattern = "\\.xls$", full.names = T, recursive = T) # change here
# map_df(files, read_excel)->> cham_cong
cham_cong <- read_excel("D:/R/Rmarkdown/chamcong/chamcong.xlsx")

cham_cong <- cham_cong %>%
  set_names(c("day_name", "date", "time", "emp_code")) %>%
  mutate(date_time = paste(date, time) %>% dmy_hms(),
         date = date_time %>% as_date())  %>%
  group_by(emp_code, date) %>%
  summarise(max_time = max(date_time, na.rm = T),
         min_time = min(date_time, na.rm = T)) %>% 
  mutate(working_time = difftime(max_time, min_time, units = "hours") %>% as.numeric()) %>%
  ungroup()
#==============================================================================
# Tao bang calendar
#==============================================================================
df_date <- data.frame(date = ymd(20180101) %m+% days(1:303))

df_date %<>% mutate(day = day(date),
                   week_name = weekdays(date, abbreviate = T),
                   week_name = factor(week_name,
                                         levels = rev(c("Mon","Tue","Wed","Thu","Fri","Sat","Sun")),
                                         labels = rev(c("Mon","Tue","Wed","Thu","Fri","Sat","Sun"))),
                   week = week(date),
                   month = month(date),
                   month_name = month.abb[month],
                   month_name = factor(month_name,
                                          levels = c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"),
                                          labels = c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))) %>% 
  group_by(month_name) %>% 
  mutate(month_week = week - min(week) + 1) %>% 
  ungroup()
nnb_plot <- function(sb = 'SB11341'){
  df <- working_time %>% 
    filter(emp_code == sb) %>% 
    right_join(df_date, by = "date") %>% 
    mutate(pass_min_time = ymd_hms(paste(date, "08:15:00")),
           pass_max_time = case_when(week_name == "Sat" ~ ymd_hms(paste(date, "12:00:00")),
                                     TRUE ~ ymd_hms(paste(date, "17:00:00"))),
           pass_day = case_when(is.na(min_time) ~ "Absent",
                                min_time <= pass_min_time & max_time >= pass_max_time ~ "Ok",
                                TRUE ~ "Fail") %>% as.factor()) %>% 
    filter(week_name != "Sun")
  
  # df %>% mutate(pass_day = case_when(is.na(working_time) ~ "Absent",
  #                             week_name %in% "Sat" & working_time >= 4 ~ "Ok",
  #                             week_name != "Sat" & working_time >= 8 ~ "Ok",
  #                             TRUE ~ "Fail") %>% as.factor()) %>% 
  df %>% 
  ggplot(aes(x = month_week, y = week_name, fill = pass_day))+
  geom_tile() +
  scale_fill_manual(values = c("snow2", "brown3", "springgreen"))+
  facet_wrap(~month_name)+
  geom_text(aes(label = day))+
  labs(title = paste("Working hour by date of", sb),
       y = NULL,
       x = NULL)->> p
  
  p
  
}

1 Tổng số giờ làm việc theo ngày của tất cả cán bộ nhân viên hội sở

hoi_so %>% 
  ggplot(aes(x = month_week, y = week_name, fill = working_time))+
  geom_tile() +
  scale_fill_gradient(low = "white", high = "red") +
  facet_wrap(~month_name)+
  geom_text(aes(label = day))+
  labs(title = "Total working time of staff",
        y = NULL,
        x = NULL,
       caption = "Source: HR-SeABank",
       fill = "Working time")

2 Một số SB

2.1 SB11341

nnb_plot(sb = "SB11341")

2.2 SB10205

nnb_plot(sb = "SB10205")

2.3 SB10973

nnb_plot(sb = "SB10973")

2.4 SB10292

nnb_plot(sb = "SB10292")

2.5 SB10356

nnb_plot(sb = "SB10356")

2.6 SB10059

nnb_plot(sb = "SB10059")

2.7 SB11397

nnb_plot(sb = "SB11397")

2.8 SB11658

nnb_plot(sb = "SB11658")

2.9 SB11819

nnb_plot(sb = "SB11819")

2.10 BI

bi %>% 
  mutate(pass_min_time = ymd_hms(paste(date, "08:15:00")),
         pass_max_time = case_when(week_name == "Sat" ~ ymd_hms(paste(date, "12:00:00")),
                                   TRUE ~ ymd_hms(paste(date, "17:00:00"))),
         pass_day = case_when(is.na(min_time) ~ "Absent",
                              min_time <= pass_min_time & max_time >= pass_max_time ~ "Ok",
                              TRUE ~ "Fail") %>% as.factor()) %>% 
  filter(week_name != "Sun")%>% 
  filter(!is.na(emp_code)) %>% 
  ggplot(aes(x = month_week, y = week_name, fill = pass_day))+
  geom_tile() +
  scale_fill_manual(values = c("brown3", "springgreen"))+
  facet_wrap(~emp_name)+
  geom_text(aes(label = day))+
  labs(title = paste("Working hour by date of BI in", month.abb[month(first_date)]),
       y = NULL,
       x = NULL,
       fill = "Pass day")

LS0tDQp0aXRsZTogIkNo4bqlbSBjw7RuZyBjYWxlbmRhciINCmF1dGhvcjogIk5ndXnhu4VuIE5n4buNYyBCw6xuaCINCmRhdGU6ICIxMC8zMC8yMDE4Ig0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzDQogICAgdGhlbWU6ICJkZWZhdWx0Ig0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBubw0KICAgICAgc21vb3RoX3Njcm9sbDogbm8NCg0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFICkgIyBmaWcuY2FwID0gIlNvdXJjZTogQkkgLSBTZUFiYW5rIiwgIGZpZy5oZWlnaHQgPSA2LCBmaWcud2lkdGggPSA5DQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShsdWJyaWRhdGUpDQoNCnRoZW1lX25uYiA8LSB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAnc25vdzInLCBjb2xvdXIgPSAnc25vdzQnKSkNCg0KdGhlbWVfc2V0KHRoZW1lX25uYikNCmBgYA0KDQpgYGB7cn0NCiMgbXlfZm9sZGVyIDwtICdQOi9OaGFuc3UvRHUgbGlldSBjaGFtIGNvbmcgLSBUaGVvIGRvaSBuZ2F5IG5naGkvRHUgbGlldSBjaGFtIGNvbmcvSG9pIHNvLycNCiMgZmlsZXMgPC0gbGlzdC5maWxlcyhteV9mb2xkZXIsIHBhdHRlcm4gPSAiXFwueGxzJCIsIGZ1bGwubmFtZXMgPSBULCByZWN1cnNpdmUgPSBUKSAjIGNoYW5nZSBoZXJlDQojIG1hcF9kZihmaWxlcywgcmVhZF9leGNlbCktPj4gY2hhbV9jb25nDQpjaGFtX2NvbmcgPC0gcmVhZF9leGNlbCgiRDovUi9SbWFya2Rvd24vY2hhbWNvbmcvY2hhbWNvbmcueGxzeCIpDQoNCmNoYW1fY29uZyA8LSBjaGFtX2NvbmcgJT4lDQogIHNldF9uYW1lcyhjKCJkYXlfbmFtZSIsICJkYXRlIiwgInRpbWUiLCAiZW1wX2NvZGUiKSkgJT4lDQogIG11dGF0ZShkYXRlX3RpbWUgPSBwYXN0ZShkYXRlLCB0aW1lKSAlPiUgZG15X2htcygpLA0KICAgICAgICAgZGF0ZSA9IGRhdGVfdGltZSAlPiUgYXNfZGF0ZSgpKSAgJT4lDQogIGdyb3VwX2J5KGVtcF9jb2RlLCBkYXRlKSAlPiUNCiAgc3VtbWFyaXNlKG1heF90aW1lID0gbWF4KGRhdGVfdGltZSwgbmEucm0gPSBUKSwNCiAgICAgICAgIG1pbl90aW1lID0gbWluKGRhdGVfdGltZSwgbmEucm0gPSBUKSkgJT4lIA0KICBtdXRhdGUod29ya2luZ190aW1lID0gZGlmZnRpbWUobWF4X3RpbWUsIG1pbl90aW1lLCB1bml0cyA9ICJob3VycyIpICU+JSBhcy5udW1lcmljKCkpICU+JQ0KICB1bmdyb3VwKCkNCmBgYA0KDQpgYGB7cn0NCiM9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCiMgVGFvIGJhbmcgY2FsZW5kYXINCiM9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCmRmX2RhdGUgPC0gZGF0YS5mcmFtZShkYXRlID0geW1kKDIwMTgwMTAxKSAlbSslIGRheXMoMTozMDMpKQ0KDQpkZl9kYXRlICU8PiUgbXV0YXRlKGRheSA9IGRheShkYXRlKSwNCiAgICAgICAgICAgICAgICAgICB3ZWVrX25hbWUgPSB3ZWVrZGF5cyhkYXRlLCBhYmJyZXZpYXRlID0gVCksDQogICAgICAgICAgICAgICAgICAgd2Vla19uYW1lID0gZmFjdG9yKHdlZWtfbmFtZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gcmV2KGMoIk1vbiIsIlR1ZSIsIldlZCIsIlRodSIsIkZyaSIsIlNhdCIsIlN1biIpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gcmV2KGMoIk1vbiIsIlR1ZSIsIldlZCIsIlRodSIsIkZyaSIsIlNhdCIsIlN1biIpKSksDQogICAgICAgICAgICAgICAgICAgd2VlayA9IHdlZWsoZGF0ZSksDQogICAgICAgICAgICAgICAgICAgbW9udGggPSBtb250aChkYXRlKSwNCiAgICAgICAgICAgICAgICAgICBtb250aF9uYW1lID0gbW9udGguYWJiW21vbnRoXSwNCiAgICAgICAgICAgICAgICAgICBtb250aF9uYW1lID0gZmFjdG9yKG1vbnRoX25hbWUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJKYW4iLCAiRmViIiwgIk1hciIsICJBcHIiLCAiTWF5IiwgIkp1biIsICJKdWwiLCAiQXVnIiwgIlNlcCIsICJPY3QiLCAiTm92IiwgIkRlYyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiSmFuIiwgIkZlYiIsICJNYXIiLCAiQXByIiwgIk1heSIsICJKdW4iLCAiSnVsIiwgIkF1ZyIsICJTZXAiLCAiT2N0IiwgIk5vdiIsICJEZWMiKSkpICU+JSANCiAgZ3JvdXBfYnkobW9udGhfbmFtZSkgJT4lIA0KICBtdXRhdGUobW9udGhfd2VlayA9IHdlZWsgLSBtaW4od2VlaykgKyAxKSAlPiUgDQogIHVuZ3JvdXAoKQ0KDQpgYGANCg0KYGBge3IsaW5jbHVkZT1GQUxTRX0NCndvcmtpbmdfdGltZSA8LSBjaGFtX2NvbmcgJT4lIA0KICBtdXRhdGUoZW1wX25hbWUgPSBjYXNlX3doZW4oZW1wX2NvZGUgPT0gJ1NCMTEzNDEnIH4gJ0JpbmgnLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1wX2NvZGUgPT0gJ1NCMTAyMDUnIH4gJ1RyYW5nJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcF9jb2RlID09ICdTQjEwOTczJyB+ICdLaWVtJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcF9jb2RlID09ICdTQjEwMzU2JyB+ICdUaGFuaCcsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXBfY29kZSA9PSAnU0IxMDI5MicgfiAnR2lhbmcnLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1wX2NvZGUgPT0gJ1NCMTAwNTknIH4gJ1F1eW5oJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcF9jb2RlID09ICdTQjExNjU4JyB+ICdBbicsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXBfY29kZSA9PSAnU0IxMTM5NycgfiAnRHVuZycsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXBfY29kZSA9PSAnU0IxMTgxOScgfiAnRHV5JywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAiT3RoZXIiDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKSANCg0KDQoNCmhvaV9zbyA8LSB3b3JraW5nX3RpbWUgJT4lIA0KICBncm91cF9ieShkYXRlKSAlPiUgDQogIHN1bW1hcmlzZSh3b3JraW5nX3RpbWUgPSBzdW0od29ya2luZ190aW1lKSkgJT4lIA0KICB1bmdyb3VwKCklPiUgDQogIHJpZ2h0X2pvaW4oZGZfZGF0ZSkgJT4lIA0KICBmaWx0ZXIod2Vla19uYW1lICE9ICJTdW4iKQ0KDQojIEZpcnN0IGRhdGUgdGhpcyBtb250aA0KZmlyc3RfZGF0ZSA8LSByb2xsYmFjayhTeXMuRGF0ZSgpJW0tJSBkYXlzKDEwKSkgJW0rJSBkYXlzKDEpDQojZmlyc3RfZGF0ZSA8LSByb2xsYmFjayhTeXMuRGF0ZSgpKSAlbSslIGRheXMoMSkNCg0KYmkgPC0gd29ya2luZ190aW1lICU+JSANCiAgZmlsdGVyKGVtcF9jb2RlICAlaW4lIGMoJ1NCMTEzNDEnLCAnU0IxMDIwNScsICdTQjEwOTczJywgJ1NCMTAzNTYnLCAnU0IxMDI5MicsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAnU0IxMDA1OScsICdTQjExNjU4JywgJ1NCMTEzOTcnLCAnU0IxMTgxOScpKSAlPiUgDQogIHJpZ2h0X2pvaW4oZGZfZGF0ZSkgJT4lIA0KICBmaWx0ZXIod2Vla19uYW1lICE9ICJTdW4iLCBkYXRlID49IGZpcnN0X2RhdGUpDQogIA0KYGBgDQoNCmBgYHtyfQ0Kbm5iX3Bsb3QgPC0gZnVuY3Rpb24oc2IgPSAnU0IxMTM0MScpew0KICBkZiA8LSB3b3JraW5nX3RpbWUgJT4lIA0KICAgIGZpbHRlcihlbXBfY29kZSA9PSBzYikgJT4lIA0KICAgIHJpZ2h0X2pvaW4oZGZfZGF0ZSwgYnkgPSAiZGF0ZSIpICU+JSANCiAgICBtdXRhdGUocGFzc19taW5fdGltZSA9IHltZF9obXMocGFzdGUoZGF0ZSwgIjA4OjE1OjAwIikpLA0KICAgICAgICAgICBwYXNzX21heF90aW1lID0gY2FzZV93aGVuKHdlZWtfbmFtZSA9PSAiU2F0IiB+IHltZF9obXMocGFzdGUoZGF0ZSwgIjEyOjAwOjAwIikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiB5bWRfaG1zKHBhc3RlKGRhdGUsICIxNzowMDowMCIpKSksDQogICAgICAgICAgIHBhc3NfZGF5ID0gY2FzZV93aGVuKGlzLm5hKG1pbl90aW1lKSB+ICJBYnNlbnQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5fdGltZSA8PSBwYXNzX21pbl90aW1lICYgbWF4X3RpbWUgPj0gcGFzc19tYXhfdGltZSB+ICJPayIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAiRmFpbCIpICU+JSBhcy5mYWN0b3IoKSkgJT4lIA0KICAgIGZpbHRlcih3ZWVrX25hbWUgIT0gIlN1biIpDQogIA0KICAjIGRmICU+JSBtdXRhdGUocGFzc19kYXkgPSBjYXNlX3doZW4oaXMubmEod29ya2luZ190aW1lKSB+ICJBYnNlbnQiLA0KICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWVrX25hbWUgJWluJSAiU2F0IiAmIHdvcmtpbmdfdGltZSA+PSA0IH4gIk9rIiwNCiAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2Vla19uYW1lICE9ICJTYXQiICYgd29ya2luZ190aW1lID49IDggfiAiT2siLA0KICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gIkZhaWwiKSAlPiUgYXMuZmFjdG9yKCkpICU+JSANCiAgZGYgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtb250aF93ZWVrLCB5ID0gd2Vla19uYW1lLCBmaWxsID0gcGFzc19kYXkpKSsNCiAgZ2VvbV90aWxlKCkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJzbm93MiIsICJicm93bjMiLCAic3ByaW5nZ3JlZW4iKSkrDQogIGZhY2V0X3dyYXAofm1vbnRoX25hbWUpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gZGF5KSkrDQogIGxhYnModGl0bGUgPSBwYXN0ZSgiV29ya2luZyBob3VyIGJ5IGRhdGUgb2YiLCBzYiksDQogICAgICAgeSA9IE5VTEwsDQogICAgICAgeCA9IE5VTEwpLT4+IHANCiAgDQogIHANCiAgDQp9DQpgYGANCg0KDQojIFThu5VuZyBz4buRIGdp4budIGzDoG0gdmnhu4djIHRoZW8gbmfDoHkgY+G7p2EgdOG6pXQgY+G6oyBjw6FuIGLhu5kgbmjDom4gdmnDqm4gaOG7mWkgc+G7nw0KYGBge3J9DQpob2lfc28gJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtb250aF93ZWVrLCB5ID0gd2Vla19uYW1lLCBmaWxsID0gd29ya2luZ190aW1lKSkrDQogIGdlb21fdGlsZSgpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAid2hpdGUiLCBoaWdoID0gInJlZCIpICsNCiAgZmFjZXRfd3JhcCh+bW9udGhfbmFtZSkrDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBkYXkpKSsNCiAgbGFicyh0aXRsZSA9ICJUb3RhbCB3b3JraW5nIHRpbWUgb2Ygc3RhZmYiLA0KICAgICAgICB5ID0gTlVMTCwNCiAgICAgICAgeCA9IE5VTEwsDQogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IEhSLVNlQUJhbmsiLA0KICAgICAgIGZpbGwgPSAiV29ya2luZyB0aW1lIikNCg0KYGBgDQoNCiMgTeG7mXQgc+G7kSBTQiANCiMjIFNCMTEzNDENCmBgYHtyfQ0Kbm5iX3Bsb3Qoc2IgPSAiU0IxMTM0MSIpDQpgYGANCg0KIyMgU0IxMDIwNQ0KDQpgYGB7cn0NCm5uYl9wbG90KHNiID0gIlNCMTAyMDUiKQ0KYGBgDQoNCiMjIFNCMTA5NzMNCg0KYGBge3J9DQpubmJfcGxvdChzYiA9ICJTQjEwOTczIikNCmBgYA0KDQojIyBTQjEwMjkyDQpgYGB7cn0NCm5uYl9wbG90KHNiID0gIlNCMTAyOTIiKQ0KYGBgDQoNCiMjIFNCMTAzNTYNCmBgYHtyfQ0Kbm5iX3Bsb3Qoc2IgPSAiU0IxMDM1NiIpDQpgYGANCg0KIyMgU0IxMDA1OQ0KYGBge3J9DQpubmJfcGxvdChzYiA9ICJTQjEwMDU5IikNCmBgYA0KDQojIyBTQjExMzk3DQpgYGB7cn0NCm5uYl9wbG90KHNiID0gIlNCMTEzOTciKQ0KYGBgDQoNCiMjIFNCMTE2NTgNCg0KYGBge3J9DQpubmJfcGxvdChzYiA9ICJTQjExNjU4IikNCmBgYA0KDQojIyBTQjExODE5DQpgYGB7cn0NCm5uYl9wbG90KHNiID0gIlNCMTE4MTkiKQ0KYGBgDQoNCiMjIEJJDQpgYGB7cn0NCmJpICU+JSANCiAgbXV0YXRlKHBhc3NfbWluX3RpbWUgPSB5bWRfaG1zKHBhc3RlKGRhdGUsICIwODoxNTowMCIpKSwNCiAgICAgICAgIHBhc3NfbWF4X3RpbWUgPSBjYXNlX3doZW4od2Vla19uYW1lID09ICJTYXQiIH4geW1kX2htcyhwYXN0ZShkYXRlLCAiMTI6MDA6MDAiKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiB5bWRfaG1zKHBhc3RlKGRhdGUsICIxNzowMDowMCIpKSksDQogICAgICAgICBwYXNzX2RheSA9IGNhc2Vfd2hlbihpcy5uYShtaW5fdGltZSkgfiAiQWJzZW50IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbl90aW1lIDw9IHBhc3NfbWluX3RpbWUgJiBtYXhfdGltZSA+PSBwYXNzX21heF90aW1lIH4gIk9rIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAiRmFpbCIpICU+JSBhcy5mYWN0b3IoKSkgJT4lIA0KICBmaWx0ZXIod2Vla19uYW1lICE9ICJTdW4iKSU+JSANCiAgZmlsdGVyKCFpcy5uYShlbXBfY29kZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGhfd2VlaywgeSA9IHdlZWtfbmFtZSwgZmlsbCA9IHBhc3NfZGF5KSkrDQogIGdlb21fdGlsZSgpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiYnJvd24zIiwgInNwcmluZ2dyZWVuIikpKw0KICBmYWNldF93cmFwKH5lbXBfbmFtZSkrDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBkYXkpKSsNCiAgbGFicyh0aXRsZSA9IHBhc3RlKCJXb3JraW5nIGhvdXIgYnkgZGF0ZSBvZiBCSSBpbiIsIG1vbnRoLmFiYlttb250aChmaXJzdF9kYXRlKV0pLA0KICAgICAgIHkgPSBOVUxMLA0KICAgICAgIHggPSBOVUxMLA0KICAgICAgIGZpbGwgPSAiUGFzcyBkYXkiKQ0KYGBgDQoNCjxzY3JpcHQ+DQokKCAiaW5wdXQuaGlkZXNob3ciICkuZWFjaCggZnVuY3Rpb24gKCBpbmRleCwgYnV0dG9uICkgew0KICBidXR0b24udmFsdWUgPSAnSGlkZSBPdXRwdXQnOw0KICAkKCBidXR0b24gKS5jbGljayggZnVuY3Rpb24gKCkgew0KICAgIHZhciB0YXJnZXQgPSB0aGlzLm5leHRTaWJsaW5nID8gdGhpcyA6IHRoaXMucGFyZW50Tm9kZTsNCiAgICB0YXJnZXQgPSB0YXJnZXQubmV4dFNpYmxpbmcubmV4dFNpYmxpbmcubmV4dFNpYmxpbmcubmV4dFNpYmxpbmc7DQogICAgaWYgKCB0YXJnZXQuc3R5bGUuZGlzcGxheSA9PSAnYmxvY2snIHx8IHRhcmdldC5zdHlsZS5kaXNwbGF5ID09ICcnICkgew0KICAgICAgdGFyZ2V0LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7DQogICAgICB0aGlzLnZhbHVlID0gJ1Nob3cgT3V0cHV0JzsNCiAgICB9IGVsc2Ugew0KICAgICAgdGFyZ2V0LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOw0KICAgICAgdGhpcy52YWx1ZSA9ICdIaWRlIE91dHB1dCc7DQogICAgfQ0KICB9ICk7DQp9ICk7DQo8L3NjcmlwdD4=