Introduction

Preliminary visual exploration of data. > Click code to see how it was done

The data comes from samples collected as spraints: Each of them was analysed under the microscope, bones and scales identified whenever possible. Fish bones were measured and gave us the size group of the individual.

The aim of the study is to show the variability of the otter diet, both in terms of size and biodiversity.

The studied locations are:

  • Bílina river (Upper and Lower)
  • Chomutvka river (Upper and Lower)
  • Přísečnice (A water reservoir for human consumption)
  • Lake Milada (A recently recovered mining area)

We would expect to find differences in predation between lakes and rivers, between upper and lower courses of the rivers, and also between the two lakes, as Milada was much more recently formed than Přísečnice.

Predation should reflect the size distribution and availability of each species, so we should be able to see differences in the size distribution between stocked fish (Salmonids) and wild fish, such as Gobio sp.

Libraries

Data tyding

Raw data

Original data in wide format: One column for each observation of species and each size category

# Data----

path <- here::here("data", "krusnehory.xlsx")

raw <- path %>%
  excel_sheets() %>%
  set_names() %>%
  map_df(read_excel, #join all sheets by row
         path = path,
         .id = "location") %>% #create new column with the name of the sheets
  clean_names()                #probably many errors, so better clean

head(raw)
## # A tibble: 6 x 213
##   location stretch month   season abramis alburnoides_bipuncta~ alburnus_alburn~
##   <chr>    <chr>   <chr>   <chr>    <dbl>                 <dbl>            <dbl>
## 1 Bílina   dolní   April   spring       0                     0                0
## 2 Bílina   dolní   August  summer       0                     0                0
## 3 Bílina   dolní   Februa~ winter       1                     4                4
## 4 Bílina   dolní   January winter       1                     0                0
## 5 Bílina   dolní   July    summer       0                     0                0
## 6 Bílina   dolní   March   spring       0                     0                0
## # ... with 206 more variables: anguilla_anguilla <dbl>,
## #   barbatula_barbatula <dbl>, barbus_barbus <dbl>, blicca_bjoerkna <dbl>,
## #   carassius <dbl>, cottus <dbl>, ctenopharyngodon <dbl>, cyprinidae <dbl>,
## #   cyprinus_carpio <dbl>, esox_lucius <dbl>, gobio <dbl>,
## #   gasterosseus_aculeatus <dbl>, gymnocephalus <dbl>,
## #   chondrostoma_nasus <dbl>, ictalurus_nebulosus <dbl>, ic_neb_5_10_cm <dbl>,
## #   ic_neb_10_15_cm <dbl>, lepomis_gibbosus <dbl>, leucaspius_delineatus <dbl>,
## #   leuciscus_cephalus <dbl>, leuciscus_leuciscus <dbl>, lota_lota <dbl>,
## #   misgurnus_fosilis <dbl>, neogobius_melanostomus <dbl>,
## #   oncorhynchus_mykkiss <dbl>, perca_fluviatilis <dbl>,
## #   phoxinus_phoxinus <dbl>, pseudorasbora_parva <dbl>, rhodeus_sericeus <dbl>,
## #   rutilus_rutilus <dbl>, salmonids <dbl>, salmo_trutta_fario <dbl>,
## #   scardinius_erythrophtalmus <dbl>, silurus_glanis <dbl>, tinca_tinca <dbl>,
## #   astacus <dbl>, molusca <dbl>, coleoptera <dbl>, odonata_larvae <dbl>,
## #   insecta <dbl>, anura <dbl>, aves <dbl>, mammalia <dbl>, caudata <dbl>,
## #   serpentes <dbl>, al_bi_5_10_cm <dbl>, al_bi_10_15_cm <dbl>,
## #   al_al_0_5_cm <dbl>, al_al_5_10_cm <dbl>, al_al_10_15_cm <dbl>,
## #   ba_ba_5_10_cm <dbl>, ba_ba_10_15_cm <dbl>, ba_ba_15_20_cm <dbl>,
## #   br_br_5_10_cm <dbl>, br_br_10_15_cm <dbl>, br_br_15_20_cm <dbl>,
## #   br_br_20_25_cm <dbl>, br_br_25_30_cm <dbl>, br_br_30_35_cm <dbl>,
## #   br_br_35_40_cm <dbl>, br_br_40_45_cm <dbl>, ca_5_10_cm <dbl>,
## #   ca_10_15_cm <dbl>, ca_15_20_cm <dbl>, ca_20_25_cm <dbl>, ca_25_30_cm <dbl>,
## #   ca_30_35_cm <dbl>, ca_35_40_cm <dbl>, cg_5_10_cm <dbl>, cg_10_15_cm <dbl>,
## #   cy_0_5_cm <dbl>, cy_5_10_cm <dbl>, cy_10_15_cm <dbl>, cy_15_20_cm <dbl>,
## #   cy_20_25_cm <dbl>, cy_25_30_cm <dbl>, cy_30_35_cm <dbl>, cy_35_40_cm <dbl>,
## #   cy_40_45_cm <dbl>, el_0_5_cm <dbl>, el_5_10_cm <dbl>, el_10_15_cm <dbl>,
## #   el_15_20_cm <dbl>, el_20_25_cm <dbl>, el_25_30_cm <dbl>, el_30_35_cm <dbl>,
## #   el_35_40_cm <dbl>, gg_0_5_cm <dbl>, gg_5_10_cm <dbl>, gg_10_15_cm <dbl>,
## #   gg_15_20_cm <dbl>, gy_5_10_cm <dbl>, gy_10_15_cm <dbl>,
## #   ch_na_5_10_cm <dbl>, ch_na_10_15_cm <dbl>, ch_na_15_20_cm <dbl>,
## #   ch_na_20_25_cm <dbl>, ch_na_25_30_cm <dbl>, ch_na_30_35_cm <dbl>,
## #   le_del_0_5_cm <dbl>, ...

Long format

Before the analysis we need to:

  • Pivot the data into long format (One row per observation).
  • Create new variables for “species” and “size”.
  • Fix typos and other small errors.
# What a mess. Let's try to tidy it. 
# 
# 1) separate all those columns with sizes from the species. 
# 2) pivot sizes into a single column
# 3) filter by initials, add a species column for the fish with size, one by one. FUck.

tidy_size <- raw %>%
  dplyr::select(location, stretch, month, season, contains("_cm")) %>%
  pivot_longer(
    cols = contains("cm"),
    names_to = "size",
    values_to = "number",
    values_drop_na = TRUE
  ) %>%                                #join later with new species column below
  
  # levels(as.factor(tidy_size$size)) # how many different sizes? jooooder
  
  
  # Better redo the following code nightmare with case_when()!!
  
  dplyr::mutate(species = ifelse(
    grepl("al_bi_", size),
    "Alburnoides bipunctatus",
    ifelse(
      grepl("al_al_", size),
      "Alburnus alburnus",
      ifelse(
        grepl("st_tr_", size),            #looks like a typing error
        "Salmo trutta m. fario",
        ifelse(
          grepl("ab_br_", size),
          "Abramis sp.",
          ifelse(
            grepl("ba_ba_", size),
            "Barbatula barbatula",
            ifelse(
              grepl("br_br_", size),
              "Barbus barbus",
              ifelse(
                grepl("ca_", size),
                "Carassius sp.",
                ifelse(
                  grepl("cg_", size),
                  "Ctenopharyngodon idella",
                  ifelse(
                    grepl("cy_", size),
                    "Cyprinus carpio",
                    ifelse(
                      grepl("ct_id_", size),
                      "Ctenopharyngodon idella",
                      ifelse(
                        grepl("ga_ac", size),
                        "Gasterosteus aculeatus",
                        ifelse(
                          grepl("ch_na_", size),
                          "Chondrostoma nasus",
                          ifelse(
                            grepl("el_", size),
                            "Esox lucius",
                            ifelse(
                              grepl("gg_", size),
                              "Gobio a Romanogobio sp.",
                              ifelse(
                                grepl("gy_", size),
                                "Gymnocephalus cernua",
                                ifelse(
                                  grepl("ic_neb_", size),
                                  "Ictalurus nebulosus",
                                  ifelse(
                                    grepl("le_ce_", size),
                                    "Squalius cephalus",
                                    ifelse(
                                      grepl("le_del_", size),
                                      "Leucaspius delineatus",
                                      ifelse(
                                        grepl("le_gi_", size),
                                        "Lepomis gibbosus",
                                        ifelse(
                                          grepl("le_le_", size),
                                          "Leuciscus leuciscus",
                                          ifelse(
                                            grepl("lo_lo_", size),
                                            "Lota lota",
                                            ifelse(
                                              grepl("mi_fo_", size),
                                              "Misgurnus fosilis",
                                              ifelse(
                                                grepl("neog_mel_", size),
                                                "Neogobius melanostomus",
                                                ifelse(
                                                  grepl("on_myk_", size),
                                                  "Oncorhynchus mykiss",
                                                  ifelse(
                                                    grepl("pf_", size),
                                                    "Perca fluviatilis",
                                                    ifelse(
                                                      grepl("ph_ph_", size),
                                                      "Phoxinus phoxinus",
                                                      ifelse(
                                                        grepl("pp_", size),
                                                        "Pseudorasbora parva",
                                                        ifelse(
                                                          grepl("rs_", size),
                                                          "Rhodeus sericeus",
                                                          ifelse(
                                                            grepl("rr_", size),
                                                            "Rutilus rutilus",
                                                            ifelse(
                                                              grepl("sa_", size),
                                                              "Salmonids",
                                                              ifelse(
                                                                grepl("se_", size),
                                                                "Scardinius erythrophtalmus",
                                                                ifelse(
                                                                  grepl("si_gl_", size),
                                                                  "Silurus glanis",
                                                                  ifelse(
                                                                    grepl("sl_tr_", size),
                                                                    "Salmo trutta m. fario",
                                                                    ifelse(
                                                                      grepl("st_luc_", size),
                                                                      "Stizostedion lucioperca",
                                                                      ifelse(grepl("tt_", size), "Tinca tinca", "error") #adding option for error in case I missed a name
                                                                    )
                                                                  )
                                                                )
                                                              )
                                                            )
                                                          )
                                                        )
                                                      )
                                                    )
                                                  )
                                                )
                                              )
                                            )
                                          )
                                        )
                                      )
                                    )
                                  )
                                )
                              )
                            )
                          )
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  ))

head(tidy_size)
## # A tibble: 6 x 7
##   location stretch month season size            number species                
##   <chr>    <chr>   <chr> <chr>  <chr>            <dbl> <chr>                  
## 1 Bílina   dolní   April spring ic_neb_5_10_cm       0 Ictalurus nebulosus    
## 2 Bílina   dolní   April spring ic_neb_10_15_cm      0 Ictalurus nebulosus    
## 3 Bílina   dolní   April spring al_bi_5_10_cm        0 Alburnoides bipunctatus
## 4 Bílina   dolní   April spring al_bi_10_15_cm       0 Alburnoides bipunctatus
## 5 Bílina   dolní   April spring al_al_0_5_cm         0 Alburnus alburnus      
## 6 Bílina   dolní   April spring al_al_5_10_cm        0 Alburnus alburnus
########################## PREVIOUS ATTEMPTS, DON'T RUN ######################


#   pivot_longer(
#     cols = Abramis:"Stizostedion lucioperca",
#     names_to = "species",
#     values_to = "numberPrey",
#     values_drop_na = TRUE
#   ) 
#   
# 
# 
#   
#   pivot_longer(
#     cols = contains("cm"),
#     names_to = "size",
#     values_to = "number",
#     values_drop_na = TRUE
#   ) %>%                      # nooooooooo! hay que hacerlo manual, cada size with its species
#   dplyr::filter(number > 0) %>%
#   dplyr::mutate(size = str_remove_all(size, "[*a-zA-Z]")) %>% #fuck regular expressions
#   dplyr::mutate (size = glue("{size}cm")) %>%  #had to install dev version of dplyr
#   dplyr::mutate(size = str_trim(size)) %>% #remove extra space
#   dplyr::mutate(size = fct_relevel(size, "5-10 cm", after = 1)) %>%
#   uncount(number) %>% # to get individual observations!!
#   pivot_longer(
#     cols = Abramis:"Stizostedion lucioperca",
#     names_to = "species",
#     values_to = "numberPrey",
#     values_drop_na = TRUE
#   ) 
# 
# glimpse(tidy)
# str(tidy)
# 
# colourCount = length(unique(tidy$size))
# getPalette = colorRampPalette(brewer.pal(9, "OrRd")[2:9])

The data is now in long format (Just need to “uncount” the “number” column in the next step). Now we need to:

  • Add the rest of the species without size measurements

  • To do that, we need to select them from raw and pivot them to get the number too.

  • Bind row to tidy_size

  • Clean the size variable

  • Rejoice

New variable size and renaming and reordering factor levels

# OK, kousek po kousku. Now we have to:
# 
# 4) add the rest of the species without size measurements
#    4.1)  To do that, we need to select them from raw and pivot them to get the number too.
#    
# 5) bind row to tidy_size
# 6) clean the size variable
# 7) Rejoice


extra_sp <- raw %>% 
  dplyr::select(location, stretch, month, season, anguilla_anguilla, cyprinidae, astacus:serpentes) %>%
  pivot_longer(
    cols = c("anguilla_anguilla", "cyprinidae", astacus:serpentes),
    names_to = "species",
    values_to = "number",
    values_drop_na = TRUE
  )

tidy_db <- bind_rows(tidy_size, extra_sp) %>% 
  dplyr::filter(number > 0) %>%
  dplyr::mutate(size = str_remove_all(size, "[*a-zA-Z_]")) %>%  
  dplyr::mutate(size = dplyr::recode(size, 
                                     "05" = "0-5 cm",
                                     "510" = "5-10 cm",
                                     "1015" = "10-15 cm",
                                     "1520" = "15-20 cm",
                                     "2025" = "20-25 cm",
                                     "2530" = "25-30 cm",
                                     "3035" = "30-35 cm",
                                     "35-40" = "35-40 cm",
                                     "4045" = "40-45 cm"
  )) %>% 
  dplyr::mutate(size = fct_relevel(size, "5-10 cm", after = 1)) %>%
  uncount(number) %>%                 # to get individual observations!!
  dplyr::mutate(species = str_to_sentence(species)) %>% 
  dplyr::mutate(species = dplyr::recode(species, 
                                        "Astacus" = "Astacoidea",
                                        "Anguilla_anguilla" = "Anguilla anguilla",
                                        "Salmo trutta m. fario" = "Salmonids",
                                        "Oncorhynchus mykiss" = "Salmonids",
                                        "Cyprinidae" = "Unidentified Cyprinidae",
                                        "Alburnoides bipunctatus" = "Alburnus alburnus",
                                        "Gobio a romanogobio sp." = "Gobio a Romanogobio sp."
  )) %>% # Trouts pooled into salmonids, Alburnoides into alburnus
  dplyr::mutate(stretch = dplyr::recode(stretch, 
                                        "dolní" = "Lower",
                                        "horní" = "Upper")) %>%
  dplyr::mutate(species = as.factor(species)) %>% 
  dplyr::mutate(stretch = as.factor(stretch)) %>% 
  dplyr::mutate(species = fct_relevel(species, "Aves", after = Inf)) %>% 
  dplyr::mutate(species = fct_relevel(species, "Insecta", after = Inf)) %>%
  dplyr::mutate(species = fct_relevel(species, "Mammalia", after = Inf)) %>%
  dplyr::mutate(species = fct_relevel(species, "Anura", after = Inf)) %>%
  dplyr::mutate(species = fct_relevel(species, "Serpentes", after = Inf)) %>%
  dplyr::mutate(species = fct_relevel(species, "Astacoidea", after = Inf)) %>%
  dplyr::mutate(season = dplyr::recode(season, 
                                       "winter" = "Winter",
                                       "spring" = "Spring",
                                       "summer" = "Summer",
                                       "autumn" = "Autumn")) %>% 
  dplyr::mutate(season = as.factor(season)) %>% 
  dplyr::mutate(season = fct_relevel(season, "Spring", "Summer", "Autumn", "Winter" )) %>% 
  dplyr::mutate(location = as.factor(location)) %>% 
  # Divide streams into Upper and lower and removing variable stretch
  dplyr::mutate(location = case_when(location == "Bílina" & stretch == "Upper" ~ "Horní Bílina",
          location == "Bílina" & stretch == "Lower" ~ "Dolní Bílina", 
          location == "Chomutovka" & stretch == "Lower" ~ "Dolní Chomutovka",
          location == "Chomutovka" & stretch == "Upper" ~ "Horní Chomutovka",
          location == "Prisecnice" ~ "Přísečnice",
          TRUE ~ "jezero Milada")) %>% 
  dplyr::mutate(location = as.factor(location)) %>% 
  dplyr::select(-stretch)
  


summary(tidy_db)
##              location      month              season          size    
##  Dolní Bílina    :522   Length:1725        Spring:420   5-10 cm :693  
##  Dolní Chomutovka:149   Class :character   Summer:399   10-15 cm:405  
##  Horní Bílina    :129   Mode  :character   Autumn:555   15-20 cm: 75  
##  Horní Chomutovka:173                      Winter:351   20-25 cm: 34  
##  jezero Milada   :386                                   25-30 cm: 12  
##  Přísečnice      :366                                   (Other) : 10  
##                                                         NA's    :496  
##                     species   
##  Salmonids              :310  
##  Gobio a Romanogobio sp.:255  
##  Perca fluviatilis      :220  
##  Anura                  :219  
##  Astacoidea             :154  
##  Unidentified Cyprinidae: 87  
##  (Other)                :480
head(tidy_db)
## # A tibble: 6 x 5
##   location     month season size     species                
##   <fct>        <chr> <fct>  <fct>    <fct>                  
## 1 Dolní Bílina April Spring 10-15 cm Cyprinus carpio        
## 2 Dolní Bílina April Spring 0-5 cm   Gobio a Romanogobio sp.
## 3 Dolní Bílina April Spring 0-5 cm   Gobio a Romanogobio sp.
## 4 Dolní Bílina April Spring 5-10 cm  Gobio a Romanogobio sp.
## 5 Dolní Bílina April Spring 5-10 cm  Gobio a Romanogobio sp.
## 6 Dolní Bílina April Spring 5-10 cm  Gobio a Romanogobio sp.
write.csv2(tidy_db,"dataShiny/tidy_db", row.names = FALSE)

Fish lumped in one category

lumped_fish <- tidy_db %>% 
  dplyr::mutate(species = case_when(
    species == "Aves" ~ "Aves",
    species == "Insecta" ~ 'Insecta',
    species == "Mammalia" ~ 'Mammalia',
    species == "Anura" ~ 'Anura',
    species == "Serpentes" ~ 'Serpentes',
    species == "Astacoidea" ~ 'Astacoidea',
    
    TRUE ~ 'Fish' ))


head(lumped_fish)
## # A tibble: 6 x 5
##   location     month season size     species
##   <fct>        <chr> <fct>  <fct>    <chr>  
## 1 Dolní Bílina April Spring 10-15 cm Fish   
## 2 Dolní Bílina April Spring 0-5 cm   Fish   
## 3 Dolní Bílina April Spring 0-5 cm   Fish   
## 4 Dolní Bílina April Spring 5-10 cm  Fish   
## 5 Dolní Bílina April Spring 5-10 cm  Fish   
## 6 Dolní Bílina April Spring 5-10 cm  Fish
write.csv2(lumped_fish,"dataShiny/lumped_fish", row.names = FALSE)

Diet: What do otters eat, in which proportion of species?

The category “Salmonids” includes Salmo trutta m.fario, Oncorhynchus mykiss and unidentified salmonids.

Identified prey

Number of individual prey found in spraints in each location

total_prey <- tidy_db %>% 
  dplyr::select(location, species) %>%
  dplyr::count(species, location) %>% 
  pivot_wider(names_from = location, values_from = n ) %>% 
  replace(is.na(.), 0)

kable(total_prey, align = "lccrr") %>% 
  kableExtra::kable_styling()
species Dolní Bílina Dolní Chomutovka Horní Chomutovka Horní Bílina jezero Milada Přísečnice
Abramis sp. 3 0 0 0 0 0
Alburnus alburnus 8 0 0 0 0 0
Anguilla anguilla 3 0 0 0 0 0
Barbatula barbatula 2 18 1 0 0 0
Barbus barbus 5 0 0 0 0 0
Carassius sp. 24 5 1 6 0 0
Ctenopharyngodon idella 0 1 3 0 1 0
Cyprinus carpio 59 5 2 0 2 0
Esox lucius 0 1 0 0 0 0
Gobio a Romanogobio sp. 200 21 1 0 1 32
Gymnocephalus cernua 2 0 0 0 21 0
Ictalurus nebulosus 1 0 0 0 0 0
Lepomis gibbosus 5 0 0 0 8 0
Lota lota 0 0 0 0 0 1
Perca fluviatilis 5 9 1 1 200 4
Phoxinus phoxinus 0 0 0 0 0 9
Pseudorasbora parva 31 13 0 0 0 0
Rutilus rutilus 26 3 2 1 2 5
Salmonids 1 7 119 57 5 121
Scardinius erythrophtalmus 4 1 0 1 32 0
Silurus glanis 4 1 0 0 2 2
Squalius cephalus 32 28 0 0 1 2
Tinca tinca 11 1 0 0 45 0
Unidentified Cyprinidae 39 14 4 4 22 4
Aves 7 2 0 0 5 0
Insecta 1 0 0 1 5 2
Mammalia 0 3 0 0 0 1
Anura 45 14 38 39 13 70
Serpentes 3 2 0 0 1 0
Astacoidea 1 0 1 19 20 113

Diet is very varied

Custom palette

#Create custom palette
# 
seed <- c("#ff0000", "#00ff00", "#0000ff")

species_v <- levels(tidy_db$species)

species_vector<- c(species_v, "Other")

# names(palette1) = species_vector

species_colors = setNames(object = createPalette(31, seed, prefix="mine"), nm = species_vector)

swatch(species_colors)

#print(species_colors)

Most Common Prey by season

(Lumping 5% less common)

tidy_db %>% 
  # group by location before lumping so that 0.05 applies to each separately
  dplyr::group_by(location) %>% 
  mutate(species = fct_lump_prop(species,0.05)) %>% 
  ungroup() %>% 
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Astacoidea", "Anura", after = Inf)) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%   
  dplyr::mutate(location = fct_relevel(location, "jezero Milada", after = 0)) %>%
  ggplot(aes(x = location, fill=species)) + 
  scale_fill_manual(values= species_colors) +
  facet_wrap(. ~ season)+
  geom_bar()+
  theme_bw() +
  scale_y_continuous("Identified prey") +
  scale_x_discrete("") +
  labs(fill = "Species") +
  #theme(axis.text.x = element_text(angle = 90)) +
  coord_flip() +
  labs(title = "Krusne Hory: Most common prey by season") +
  # scale_fill_brewer(palette = "Paired") +
  # scale_fill_discrete(drop=FALSE) +
  theme(axis.text.x = element_text(size = 10)) + 
  theme(axis.title.x = element_text(size = 15)) + 
  theme(axis.title.y = element_text(size = 15)) + 
  theme(plot.title = element_text(size = 15))+
  guides(fill = guide_legend(reverse = TRUE))

All together as proportion

Most common prey: All together as proportion (lumping 5% less common)

tidy_db %>% 
  # group by stretch and location before lumping so that 0.05 applies to each stretch separatedly
  dplyr::group_by(location) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  ungroup() %>%
 mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Astacoidea", "Anura", after = Inf)) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
 dplyr::mutate(location = fct_relevel(location, "jezero Milada", after = 0)) %>%
  ggplot(aes(x = location, fill=species)) +
  scale_fill_manual(values= species_colors) +
  #facet_grid(. ~ season)+
  scale_y_continuous("Proportion of species", labels = scales::percent) +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Species proportion") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Krusne Hory: Most common prey, year round") + 
  coord_flip()+
  guides(fill = guide_legend(reverse = TRUE))

All fish lumped together, as proportion

lumped_fish %>%
  mutate(species = fct_relevel(species,"Fish")) %>%
  dplyr::mutate(location = fct_relevel(location, "jezero Milada", after = 0)) %>%
  ggplot(aes(x = location, fill=species)) +
  #facet_grid(. ~ season)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion of species", labels = scales::percent) +
    scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Species proportion") +
  scale_fill_brewer(palette = "Paired") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Krusne Hory") +
  coord_flip() +
  guides(fill = guide_legend(reverse = TRUE))

All fish lumped together, as proportion, by season

lumped_fish %>%
  mutate(species = fct_relevel(species,"Fish")) %>%
  dplyr::mutate(location = fct_relevel(location, "jezero Milada", after = 0)) %>%
  ggplot(aes(x = location, fill=species)) +
  facet_wrap(. ~ season)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion of species", labels = scales::percent) +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Species proportion") +
  scale_fill_brewer(palette = "Paired") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Krusne Hory") +
  coord_flip()+
  guides(fill = guide_legend(reverse = TRUE))

Each location separately

Horní Bílina

Percentage of each prey in the diet

Plot with fixed scales

tidy_db %>%
  filter(location == "Horní Bílina") %>%
  dplyr::filter(season != "Winter") %>%
  mutate(species = fct_infreq(species)) %>%
  ggplot(aes(x = species, group = location, fill=species)) +
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat = "count", show.legend = FALSE) +
  #scale_fill_manual(values = species_colors) +
  geom_text(aes(
    label = scales::percent(..prop.., accuracy = 2L),
    y = ..prop..
  ), stat = "count", vjust = -0.1, hjust = -0.1, size = 3) +
  labs(y = "", x = "") +
  facet_wrap(~season) +
  coord_flip() +
  labs(title = "Horní Bílina: Otter diet by season") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L), limits = c(0, 0.6))

Dolní Bílina

Fixed scales

dBilina <- tidy_db %>%
  filter(location == "Dolní Bílina")

dBilina %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
 # dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop.., accuracy= 0.1),
                 y= ..prop.. ), stat= "count", vjust = 0, hjust = -0.1, size=3) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Dolní Bílina: Otter diet by season") +
  scale_y_continuous(labels = scales::percent_format(), limits = c(0, 0.65))

Fixed scales 0.05 lumped

dBilina <- tidy_db %>%
  filter(location == "Dolní Bílina")

dBilina %>%
  mutate(species = fct_lump_prop(species,0.05)) %>% 
 # dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = 0, hjust = -0.1, size=3) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Dolní Bílina: Otter diet by season") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L), limits = c(0, 0.6))

Přísečnice

Water reservoir for human consumption.

Percentage of each prey in the diet

pris <- tidy_db %>%
  filter(location == "Přísečnice")

Fixed scales

pris %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
 ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 1L),
                 y= ..prop.. ), stat= "count", vjust = 0, hjust = -0.1, size=3) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Přísečnice: Otter diet by season") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L), limits = c(0, 0.6))

Jezero Milada

Total proportions

Fixed scales

jez <- tidy_db %>%
  filter(location == "jezero Milada")


jez %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  #dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 0.1),
                 y= ..prop.. ), stat= "count", vjust = 0, hjust = -0.1, size= 3) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Jezero Milada: Otter diet by season") +
scale_y_continuous(labels = scales::percent_format(accuracy = 1L), limits = c(0,1))

Fixed scales 0.05 lumped

jez <- tidy_db %>%
  filter(location == "jezero Milada")


jez %>%
  mutate(species = fct_lump_prop(species,0.05)) %>% 
  #dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = 0, hjust = -0.1, size= 3) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Jezero Milada: Otter diet by season") +
scale_y_continuous(labels = scales::percent_format(accuracy = 1L), limits = c(0,1))

Dolní Chomutovka

Percentage of each prey in the diet

dCho <- tidy_db %>%
  filter(location == "Dolní Chomutovka")

Total proportions

Plot with fixed scales, not lumped

dCho %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  #dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  +  
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = 0, hjust = -0.1,size=2.5) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Dolní Chomutovka: Otter diet by season") +
scale_y_continuous(labels = scales::percent_format(accuracy = 1L), limits = c(0,0.6))

Horní Chomutovka

Percentage of each prey in the diet

hCho <- tidy_db %>%
  filter(location == "Horní Chomutovka")

Plot with fixed scales, not lumped

hCho %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  dplyr::filter(season != "Summer") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0, hjust = -0.1, size =3) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Horní Chomutovka: Otter diet by season") +
scale_y_continuous(labels = scales::percent_format(accuracy = 1L), limits = c(0,1))

SIZE

Diet by location and size

Plot all together just to see if the data looks right.

lumped_fish %>%
  drop_na(size) %>% 
  dplyr::filter(species == "Fish") %>%
 ggplot(aes(x = location, fill = size)) +
  #facet_grid(. ~ location)+
  geom_bar( position = "dodge")+
  scale_y_continuous("") +
  scale_x_discrete("") +
  labs(fill = "Size") +
  #theme(axis.text.x = element_text(angle = 90)) +
 # coord_flip() +
  labs(title = "Krusne Hory: Size distribution") +
  scale_fill_brewer(palette = "Paired") +
  scale_fill_discrete(drop=TRUE) +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))
## List of 2
##  $ axis.title.y:List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : num 15
##   ..$ hjust        : NULL
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi FALSE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ plot.title  :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : num 15
##   ..$ hjust        : NULL
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi FALSE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  - attr(*, "class")= chr [1:2] "theme" "gg"
##  - attr(*, "complete")= logi FALSE
##  - attr(*, "validate")= logi TRUE

Just salmonid size

tidy_db %>%
 dplyr::filter(species == "Salmonids") %>%
  ggplot(aes(x = species, fill = size)) +
  facet_grid(. ~ location)+
  geom_bar( position = "dodge")+
  scale_y_continuous("") +
  scale_x_discrete("", labels=NULL) +
  labs(fill = "Size") +
  #theme(axis.text.x = element_text(angle = 90)) +
 # coord_flip() +
  labs(title = "Krusne Hory: Size distribution of salmonids") +
  scale_fill_brewer(palette = "Paired") +
  scale_fill_discrete(drop=FALSE) +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = NULL) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

LS0tDQphdXRob3I6ICJGZXJuYW5kbyBNYXRlb3MtR29uesOhbGV6Ig0KZGF0ZTogTGFzdCB1cGRhdGUgImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogbm8NCiAgICAgIHNtb290aF9zY3JvbGw6IG5vDQogIG1kX2RvY3VtZW50Og0KICAgIHZhcmlhbnQ6IG1hcmtkb3duX2dpdGh1Yg0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCnRpdGxlOiAiUExPVFMgT3R0ZXIgRGlldDogS3J1xaFuw6kgaG9yeSBBdXR1bW4gMjAxOSINCg0KDQojIHRpdGxlOiAiT3R0ZXIgRGlldDogS3J1xaFuw6kgaG9yeSBBdXR1bW4gMjAxOSINCiMgYXV0aG9yOiAiRmVybmFuZG8gTWF0ZW9zLUdvbnrDoWxleiINCiMgZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIg0KIyBvdXRwdXQ6DQojICAgd29yZF9kb2N1bWVudDoNCiMgICAgIHRvYzogbm8NCiMgICAgIGZpZ19jYXB0aW9uOiB0cnVlDQojICAgICByZWZlcmVuY2VfZG9jeDogc3R5bGV3b3JkLmRvY3gNCiMgDQojICAgDQoNCmtuaXQ6IChmdW5jdGlvbihpbnB1dEZpbGUsIGVuY29kaW5nKSB7DQogIHJtYXJrZG93bjo6cmVuZGVyKGlucHV0RmlsZSwgZW5jb2RpbmcgPSBlbmNvZGluZywgb3V0cHV0X2RpciA9ICJSZXN1bHRzIikgfSkNCi0tLQ0KIyBJbnRyb2R1Y3Rpb24NCg0KUHJlbGltaW5hcnkgdmlzdWFsIGV4cGxvcmF0aW9uIG9mIGRhdGEuID4gQ2xpY2sgY29kZSB0byBzZWUgaG93IGl0IHdhcyBkb25lIA0KDQpUaGUgZGF0YSBjb21lcyBmcm9tIHNhbXBsZXMgY29sbGVjdGVkIGFzIHNwcmFpbnRzOiBFYWNoIG9mIHRoZW0gd2FzIGFuYWx5c2VkIHVuZGVyIHRoZSBtaWNyb3Njb3BlLCBib25lcyBhbmQgc2NhbGVzIGlkZW50aWZpZWQgd2hlbmV2ZXIgcG9zc2libGUuIEZpc2ggYm9uZXMgd2VyZSBtZWFzdXJlZCBhbmQgZ2F2ZSB1cyB0aGUgc2l6ZSBncm91cCBvZiB0aGUgaW5kaXZpZHVhbC4gIA0KDQpUaGUgYWltIG9mIHRoZSBzdHVkeSBpcyB0byBzaG93IHRoZSB2YXJpYWJpbGl0eSBvZiB0aGUgb3R0ZXIgZGlldCwgYm90aCBpbiB0ZXJtcyBvZiBzaXplIGFuZCBiaW9kaXZlcnNpdHkuICANCg0KVGhlIHN0dWRpZWQgbG9jYXRpb25zIGFyZTogIA0KDQoqIELDrWxpbmEgcml2ZXIgKFVwcGVyIGFuZCBMb3dlcikNCiogQ2hvbXV0dmthIHJpdmVyIChVcHBlciBhbmQgTG93ZXIpDQoqIFDFmcOtc2XEjW5pY2UgKEEgd2F0ZXIgcmVzZXJ2b2lyIGZvciBodW1hbiBjb25zdW1wdGlvbikNCiogTGFrZSBNaWxhZGEgKEEgcmVjZW50bHkgcmVjb3ZlcmVkIG1pbmluZyBhcmVhKSAgDQoNCldlIHdvdWxkIGV4cGVjdCB0byBmaW5kIGRpZmZlcmVuY2VzIGluIHByZWRhdGlvbiBiZXR3ZWVuIGxha2VzIGFuZCByaXZlcnMsIGJldHdlZW4gdXBwZXIgYW5kIGxvd2VyIGNvdXJzZXMgb2YgdGhlIHJpdmVycywgYW5kIGFsc28gYmV0d2VlbiB0aGUgdHdvIGxha2VzLCBhcyBNaWxhZGEgd2FzIG11Y2ggbW9yZSByZWNlbnRseSBmb3JtZWQgdGhhbiBQxZnDrXNlxI1uaWNlLiAgDQoNClByZWRhdGlvbiBzaG91bGQgcmVmbGVjdCB0aGUgc2l6ZSBkaXN0cmlidXRpb24gYW5kIGF2YWlsYWJpbGl0eSBvZiBlYWNoIHNwZWNpZXMsIHNvIHdlIHNob3VsZCBiZSBhYmxlIHRvIHNlZSBkaWZmZXJlbmNlcyBpbiB0aGUgc2l6ZSBkaXN0cmlidXRpb24gYmV0d2VlbiBzdG9ja2VkIGZpc2ggKFNhbG1vbmlkcykgYW5kIHdpbGQgZmlzaCwgc3VjaCBhcyBHb2JpbyBzcC4gIA0KDQoNCg0KDQoNCmBgYHtyIGdsb2JhbF9vcHRpb25zLCBlY2hvPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy5wYXRoPSdGaWdzLycsDQogICAgICAgICAgICAgICAgICAgICAgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFKQ0KDQpvcHRpb25zKGFsbG93X2h0bWxfaW5fYWxsX291dHB1dHM9VFJVRSkNCmBgYA0KDQoNCiMgTGlicmFyaWVzDQoNCmBgYHtyIGxpYnJhcmllcywgaW5jbHVkZT1GQUxTRX0NCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoImdhZGVuYnVpZS9yZWdleHBsYWluIikNCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInRpZHl2ZXJzZS9kcGx5ciIpDQojbGlicmFyeShkZXZ0b29scykNCiNpbnN0YWxsX2dpdGh1YigiaG9sdHp5L2VwdVJhdGUiKQ0KI2xpYnJhcnkoZXB1UmF0ZSkNCiNpbnN0YWxsIHRoZSBwYWNrYWdlcyBpZiBuZWNlc3NhcnkNCmlmKCFyZXF1aXJlKCJmcyIpKSBpbnN0YWxsLnBhY2thZ2VzKCJmcyIpDQppZighcmVxdWlyZSgicmVhZHhsIikpIGluc3RhbGwucGFja2FnZXMoInJlYWR4bCIpDQojcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoImphbnV6L3JtZHJpdmUiKQ0KI2xpYnJhcnkocmVnZXhwbGFpbikNCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInRpZHl2ZXJzZS9nb29nbGVkcml2ZSIpDQpsaWJyYXJ5KHJtZHJpdmUpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoYnJvb20pDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGhlcmUpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkocnN0YXRpeCkNCmxpYnJhcnkoZ2dtb3NhaWMpDQpsaWJyYXJ5KCJvZmZpY2VyIikNCmxpYnJhcnkoInJ2ZyIpDQpsaWJyYXJ5KGFyc2VuYWwpDQpsaWJyYXJ5KHNjYWxlcykNCmxpYnJhcnkoZ3JpZEV4dHJhKSANCmxpYnJhcnkoZ2dwdWJyKQ0KbGlicmFyeShmb3JtYXR0YWJsZSkNCmxpYnJhcnkoaW5mZXIpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KbGlicmFyeShncmlkKQ0KbGlicmFyeShqYW5pdG9yKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2x1ZSkNCmxpYnJhcnkoZnMpDQpsaWJyYXJ5KGdvb2dsZWRyaXZlKQ0KbGlicmFyeShSQ29sb3JCcmV3ZXIpDQpsaWJyYXJ5KHBhbHMpDQpsaWJyYXJ5KHN1bW1hcnl0b29scykNCmxpYnJhcnkoZ3JEZXZpY2VzKQ0KbGlicmFyeShQb2x5Y2hyb21lKQ0KDQojZWRpdCB0aGUgUiBwcm9maWxlIHNvIGl0IGxpa2VzIEN6ZWNoDQoNCiMgdXNldGhpczo6ZWRpdF9yX3Byb2ZpbGUoJ3Byb2plY3QnKQ0KIyANCiMgY29kZSB0byBlZGl0IHRoZSBycHJvZmlsZQ0KIyBpZiAoLlBsYXRmb3JtJE9TLnR5cGUgPT0gJ3dpbmRvd3MnKSB7DQojICAgU3lzLnNldGxvY2FsZShjYXRlZ29yeSA9ICdMQ19BTEwnLCdFbmdsaXNoX1VuaXRlZCBTdGF0ZXMuMTI1MCcpDQojIH0gZWxzZSB7DQojICAgU3lzLnNldGxvY2FsZShjYXRlZ29yeSA9ICdMQ19BTEwnLCdlbl9VUy5VVEYtOCcpDQojIH0NCg0KYGBgDQoNCg0KIyBEYXRhIHR5ZGluZw0KDQojIyBSYXcgZGF0YQ0KDQpPcmlnaW5hbCBkYXRhIGluICoqd2lkZSBmb3JtYXQqKjogDQpPbmUgY29sdW1uIGZvciBlYWNoIG9ic2VydmF0aW9uIG9mIHNwZWNpZXMgYW5kIGVhY2ggc2l6ZSBjYXRlZ29yeSANCg0KYGBge3IgcmF3ZGF0YX0NCiMgRGF0YS0tLS0NCg0KcGF0aCA8LSBoZXJlOjpoZXJlKCJkYXRhIiwgImtydXNuZWhvcnkueGxzeCIpDQoNCnJhdyA8LSBwYXRoICU+JQ0KICBleGNlbF9zaGVldHMoKSAlPiUNCiAgc2V0X25hbWVzKCkgJT4lDQogIG1hcF9kZihyZWFkX2V4Y2VsLCAjam9pbiBhbGwgc2hlZXRzIGJ5IHJvdw0KICAgICAgICAgcGF0aCA9IHBhdGgsDQogICAgICAgICAuaWQgPSAibG9jYXRpb24iKSAlPiUgI2NyZWF0ZSBuZXcgY29sdW1uIHdpdGggdGhlIG5hbWUgb2YgdGhlIHNoZWV0cw0KICBjbGVhbl9uYW1lcygpICAgICAgICAgICAgICAgICNwcm9iYWJseSBtYW55IGVycm9ycywgc28gYmV0dGVyIGNsZWFuDQoNCmhlYWQocmF3KQ0KYGBgDQoNCg0KDQojIyBMb25nIGZvcm1hdA0KDQpCZWZvcmUgdGhlIGFuYWx5c2lzIHdlIG5lZWQgdG86DQoNCi0gUGl2b3QgdGhlIGRhdGEgaW50byAqKmxvbmcgZm9ybWF0KiogKE9uZSByb3cgcGVyIG9ic2VydmF0aW9uKS4NCi0gQ3JlYXRlIG5ldyB2YXJpYWJsZXMgZm9yICJzcGVjaWVzIiBhbmQgInNpemUiLg0KLSBGaXggdHlwb3MgYW5kIG90aGVyIHNtYWxsIGVycm9ycy4NCg0KDQoNCmBgYHtyIHRpZHlpbmcsIGVjaG89VFJVRX0NCg0KIyBXaGF0IGEgbWVzcy4gTGV0J3MgdHJ5IHRvIHRpZHkgaXQuIA0KIyANCiMgMSkgc2VwYXJhdGUgYWxsIHRob3NlIGNvbHVtbnMgd2l0aCBzaXplcyBmcm9tIHRoZSBzcGVjaWVzLiANCiMgMikgcGl2b3Qgc2l6ZXMgaW50byBhIHNpbmdsZSBjb2x1bW4NCiMgMykgZmlsdGVyIGJ5IGluaXRpYWxzLCBhZGQgYSBzcGVjaWVzIGNvbHVtbiBmb3IgdGhlIGZpc2ggd2l0aCBzaXplLCBvbmUgYnkgb25lLiBGVWNrLg0KDQp0aWR5X3NpemUgPC0gcmF3ICU+JQ0KICBkcGx5cjo6c2VsZWN0KGxvY2F0aW9uLCBzdHJldGNoLCBtb250aCwgc2Vhc29uLCBjb250YWlucygiX2NtIikpICU+JQ0KICBwaXZvdF9sb25nZXIoDQogICAgY29scyA9IGNvbnRhaW5zKCJjbSIpLA0KICAgIG5hbWVzX3RvID0gInNpemUiLA0KICAgIHZhbHVlc190byA9ICJudW1iZXIiLA0KICAgIHZhbHVlc19kcm9wX25hID0gVFJVRQ0KICApICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2pvaW4gbGF0ZXIgd2l0aCBuZXcgc3BlY2llcyBjb2x1bW4gYmVsb3cNCiAgDQogICMgbGV2ZWxzKGFzLmZhY3Rvcih0aWR5X3NpemUkc2l6ZSkpICMgaG93IG1hbnkgZGlmZmVyZW50IHNpemVzPyBqb29vb2Rlcg0KICANCiAgDQogICMgQmV0dGVyIHJlZG8gdGhlIGZvbGxvd2luZyBjb2RlIG5pZ2h0bWFyZSB3aXRoIGNhc2Vfd2hlbigpISENCiAgDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGlmZWxzZSgNCiAgICBncmVwbCgiYWxfYmlfIiwgc2l6ZSksDQogICAgIkFsYnVybm9pZGVzIGJpcHVuY3RhdHVzIiwNCiAgICBpZmVsc2UoDQogICAgICBncmVwbCgiYWxfYWxfIiwgc2l6ZSksDQogICAgICAiQWxidXJudXMgYWxidXJudXMiLA0KICAgICAgaWZlbHNlKA0KICAgICAgICBncmVwbCgic3RfdHJfIiwgc2l6ZSksICAgICAgICAgICAgI2xvb2tzIGxpa2UgYSB0eXBpbmcgZXJyb3INCiAgICAgICAgIlNhbG1vIHRydXR0YSBtLiBmYXJpbyIsDQogICAgICAgIGlmZWxzZSgNCiAgICAgICAgICBncmVwbCgiYWJfYnJfIiwgc2l6ZSksDQogICAgICAgICAgIkFicmFtaXMgc3AuIiwNCiAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICBncmVwbCgiYmFfYmFfIiwgc2l6ZSksDQogICAgICAgICAgICAiQmFyYmF0dWxhIGJhcmJhdHVsYSIsDQogICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgIGdyZXBsKCJicl9icl8iLCBzaXplKSwNCiAgICAgICAgICAgICAgIkJhcmJ1cyBiYXJidXMiLA0KICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgZ3JlcGwoImNhXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICJDYXJhc3NpdXMgc3AuIiwNCiAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICBncmVwbCgiY2dfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAiQ3Rlbm9waGFyeW5nb2RvbiBpZGVsbGEiLA0KICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICBncmVwbCgiY3lfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICJDeXByaW51cyBjYXJwaW8iLA0KICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoImN0X2lkXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICJDdGVub3BoYXJ5bmdvZG9uIGlkZWxsYSIsDQogICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoImdhX2FjIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAiR2FzdGVyb3N0ZXVzIGFjdWxlYXR1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJjaF9uYV8iLCBzaXplKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkNob25kcm9zdG9tYSBuYXN1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiZWxfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVzb3ggbHVjaXVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiZ2dfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR29iaW8gYSBSb21hbm9nb2JpbyBzcC4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiZ3lfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHeW1ub2NlcGhhbHVzIGNlcm51YSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiaWNfbmViXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJY3RhbHVydXMgbmVidWxvc3VzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgibGVfY2VfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3F1YWxpdXMgY2VwaGFsdXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgibGVfZGVsXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGV1Y2FzcGl1cyBkZWxpbmVhdHVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJsZV9naV8iLCBzaXplKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGVwb21pcyBnaWJib3N1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoImxlX2xlXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxldWNpc2N1cyBsZXVjaXNjdXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgibG9fbG9fIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMb3RhIGxvdGEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoIm1pX2ZvXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNaXNndXJudXMgZm9zaWxpcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoIm5lb2dfbWVsXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5lb2dvYml1cyBtZWxhbm9zdG9tdXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgib25fbXlrXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT25jb3JoeW5jaHVzIG15a2lzcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgicGZfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBlcmNhIGZsdXZpYXRpbGlzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgicGhfcGhfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGhveGludXMgcGhveGludXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgicHBfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQc2V1ZG9yYXNib3JhIHBhcnZhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJyc18iLCBzaXplKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmhvZGV1cyBzZXJpY2V1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoInJyXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJ1dGlsdXMgcnV0aWx1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJzYV8iLCBzaXplKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNhbG1vbmlkcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgic2VfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjYXJkaW5pdXMgZXJ5dGhyb3BodGFsbXVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgic2lfZ2xfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2lsdXJ1cyBnbGFuaXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgic2xfdHJfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTYWxtbyB0cnV0dGEgbS4gZmFyaW8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoInN0X2x1Y18iLCBzaXplKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3Rpem9zdGVkaW9uIGx1Y2lvcGVyY2EiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShncmVwbCgidHRfIiwgc2l6ZSksICJUaW5jYSB0aW5jYSIsICJlcnJvciIpICNhZGRpbmcgb3B0aW9uIGZvciBlcnJvciBpbiBjYXNlIEkgbWlzc2VkIGEgbmFtZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICApDQogICAgICAgICAgICApDQogICAgICAgICAgKQ0KICAgICAgICApDQogICAgICApDQogICAgKQ0KICApKQ0KDQpoZWFkKHRpZHlfc2l6ZSkNCg0KDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFBSRVZJT1VTIEFUVEVNUFRTLCBET04nVCBSVU4gIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQoNCiMgICBwaXZvdF9sb25nZXIoDQojICAgICBjb2xzID0gQWJyYW1pczoiU3Rpem9zdGVkaW9uIGx1Y2lvcGVyY2EiLA0KIyAgICAgbmFtZXNfdG8gPSAic3BlY2llcyIsDQojICAgICB2YWx1ZXNfdG8gPSAibnVtYmVyUHJleSIsDQojICAgICB2YWx1ZXNfZHJvcF9uYSA9IFRSVUUNCiMgICApIA0KIyAgIA0KIyANCiMgDQojICAgDQojICAgcGl2b3RfbG9uZ2VyKA0KIyAgICAgY29scyA9IGNvbnRhaW5zKCJjbSIpLA0KIyAgICAgbmFtZXNfdG8gPSAic2l6ZSIsDQojICAgICB2YWx1ZXNfdG8gPSAibnVtYmVyIiwNCiMgICAgIHZhbHVlc19kcm9wX25hID0gVFJVRQ0KIyAgICkgJT4lICAgICAgICAgICAgICAgICAgICAgICMgbm9vb29vb29vbyEgaGF5IHF1ZSBoYWNlcmxvIG1hbnVhbCwgY2FkYSBzaXplIHdpdGggaXRzIHNwZWNpZXMNCiMgICBkcGx5cjo6ZmlsdGVyKG51bWJlciA+IDApICU+JQ0KIyAgIGRwbHlyOjptdXRhdGUoc2l6ZSA9IHN0cl9yZW1vdmVfYWxsKHNpemUsICJbKmEtekEtWl0iKSkgJT4lICNmdWNrIHJlZ3VsYXIgZXhwcmVzc2lvbnMNCiMgICBkcGx5cjo6bXV0YXRlIChzaXplID0gZ2x1ZSgie3NpemV9Y20iKSkgJT4lICAjaGFkIHRvIGluc3RhbGwgZGV2IHZlcnNpb24gb2YgZHBseXINCiMgICBkcGx5cjo6bXV0YXRlKHNpemUgPSBzdHJfdHJpbShzaXplKSkgJT4lICNyZW1vdmUgZXh0cmEgc3BhY2UNCiMgICBkcGx5cjo6bXV0YXRlKHNpemUgPSBmY3RfcmVsZXZlbChzaXplLCAiNS0xMCBjbSIsIGFmdGVyID0gMSkpICU+JQ0KIyAgIHVuY291bnQobnVtYmVyKSAlPiUgIyB0byBnZXQgaW5kaXZpZHVhbCBvYnNlcnZhdGlvbnMhIQ0KIyAgIHBpdm90X2xvbmdlcigNCiMgICAgIGNvbHMgPSBBYnJhbWlzOiJTdGl6b3N0ZWRpb24gbHVjaW9wZXJjYSIsDQojICAgICBuYW1lc190byA9ICJzcGVjaWVzIiwNCiMgICAgIHZhbHVlc190byA9ICJudW1iZXJQcmV5IiwNCiMgICAgIHZhbHVlc19kcm9wX25hID0gVFJVRQ0KIyAgICkgDQojIA0KIyBnbGltcHNlKHRpZHkpDQojIHN0cih0aWR5KQ0KIyANCiMgY29sb3VyQ291bnQgPSBsZW5ndGgodW5pcXVlKHRpZHkkc2l6ZSkpDQojIGdldFBhbGV0dGUgPSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwoOSwgIk9yUmQiKVsyOjldKQ0KDQoNCmBgYA0KDQpUaGUgZGF0YSBpcyBub3cgaW4gKipsb25nIGZvcm1hdCoqIChKdXN0IG5lZWQgdG8gInVuY291bnQiIHRoZSAibnVtYmVyIiBjb2x1bW4gaW4gdGhlIG5leHQgc3RlcCkuDQpOb3cgd2UgbmVlZCB0bzoNCg0KLSBBZGQgdGhlIHJlc3Qgb2YgdGhlIHNwZWNpZXMgd2l0aG91dCBzaXplIG1lYXN1cmVtZW50cw0KLSBUbyBkbyB0aGF0LCB3ZSBuZWVkIHRvIHNlbGVjdCB0aGVtIGZyb20gcmF3IGFuZCBwaXZvdCB0aGVtIHRvIGdldCB0aGUgbnVtYmVyIHRvby4NCg0KLSBCaW5kIHJvdyB0byB0aWR5X3NpemUNCi0gQ2xlYW4gdGhlIHNpemUgdmFyaWFibGUNCi0gUmVqb2ljZQ0KDQojIyBOZXcgdmFyaWFibGUgc2l6ZSBhbmQgcmVuYW1pbmcgYW5kIHJlb3JkZXJpbmcgZmFjdG9yIGxldmVscw0KDQoNCmBgYHtyIG1lcmdlX3NwZWNpZXMsIGVjaG89VFJVRX0NCg0KIyBPSywga291c2VrIHBvIGtvdXNrdS4gTm93IHdlIGhhdmUgdG86DQojIA0KIyA0KSBhZGQgdGhlIHJlc3Qgb2YgdGhlIHNwZWNpZXMgd2l0aG91dCBzaXplIG1lYXN1cmVtZW50cw0KIyAgICA0LjEpICBUbyBkbyB0aGF0LCB3ZSBuZWVkIHRvIHNlbGVjdCB0aGVtIGZyb20gcmF3IGFuZCBwaXZvdCB0aGVtIHRvIGdldCB0aGUgbnVtYmVyIHRvby4NCiMgICAgDQojIDUpIGJpbmQgcm93IHRvIHRpZHlfc2l6ZQ0KIyA2KSBjbGVhbiB0aGUgc2l6ZSB2YXJpYWJsZQ0KIyA3KSBSZWpvaWNlDQoNCg0KZXh0cmFfc3AgPC0gcmF3ICU+JSANCiAgZHBseXI6OnNlbGVjdChsb2NhdGlvbiwgc3RyZXRjaCwgbW9udGgsIHNlYXNvbiwgYW5ndWlsbGFfYW5ndWlsbGEsIGN5cHJpbmlkYWUsIGFzdGFjdXM6c2VycGVudGVzKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKA0KICAgIGNvbHMgPSBjKCJhbmd1aWxsYV9hbmd1aWxsYSIsICJjeXByaW5pZGFlIiwgYXN0YWN1czpzZXJwZW50ZXMpLA0KICAgIG5hbWVzX3RvID0gInNwZWNpZXMiLA0KICAgIHZhbHVlc190byA9ICJudW1iZXIiLA0KICAgIHZhbHVlc19kcm9wX25hID0gVFJVRQ0KICApDQoNCnRpZHlfZGIgPC0gYmluZF9yb3dzKHRpZHlfc2l6ZSwgZXh0cmFfc3ApICU+JSANCiAgZHBseXI6OmZpbHRlcihudW1iZXIgPiAwKSAlPiUNCiAgZHBseXI6Om11dGF0ZShzaXplID0gc3RyX3JlbW92ZV9hbGwoc2l6ZSwgIlsqYS16QS1aX10iKSkgJT4lICANCiAgZHBseXI6Om11dGF0ZShzaXplID0gZHBseXI6OnJlY29kZShzaXplLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMDUiID0gIjAtNSBjbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjUxMCIgPSAiNS0xMCBjbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwMTUiID0gIjEwLTE1IGNtIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTUyMCIgPSAiMTUtMjAgY20iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyMDI1IiA9ICIyMC0yNSBjbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjI1MzAiID0gIjI1LTMwIGNtIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMzAzNSIgPSAiMzAtMzUgY20iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIzNS00MCIgPSAiMzUtNDAgY20iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI0MDQ1IiA9ICI0MC00NSBjbSINCiAgKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKHNpemUgPSBmY3RfcmVsZXZlbChzaXplLCAiNS0xMCBjbSIsIGFmdGVyID0gMSkpICU+JQ0KICB1bmNvdW50KG51bWJlcikgJT4lICAgICAgICAgICAgICAgICAjIHRvIGdldCBpbmRpdmlkdWFsIG9ic2VydmF0aW9ucyEhDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IHN0cl90b19zZW50ZW5jZShzcGVjaWVzKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBkcGx5cjo6cmVjb2RlKHNwZWNpZXMsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBc3RhY3VzIiA9ICJBc3RhY29pZGVhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQW5ndWlsbGFfYW5ndWlsbGEiID0gIkFuZ3VpbGxhIGFuZ3VpbGxhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2FsbW8gdHJ1dHRhIG0uIGZhcmlvIiA9ICJTYWxtb25pZHMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPbmNvcmh5bmNodXMgbXlraXNzIiA9ICJTYWxtb25pZHMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDeXByaW5pZGFlIiA9ICJVbmlkZW50aWZpZWQgQ3lwcmluaWRhZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFsYnVybm9pZGVzIGJpcHVuY3RhdHVzIiA9ICJBbGJ1cm51cyBhbGJ1cm51cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdvYmlvIGEgcm9tYW5vZ29iaW8gc3AuIiA9ICJHb2JpbyBhIFJvbWFub2dvYmlvIHNwLiINCiAgKSkgJT4lICMgVHJvdXRzIHBvb2xlZCBpbnRvIHNhbG1vbmlkcywgQWxidXJub2lkZXMgaW50byBhbGJ1cm51cw0KICBkcGx5cjo6bXV0YXRlKHN0cmV0Y2ggPSBkcGx5cjo6cmVjb2RlKHN0cmV0Y2gsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkb2xuw60iID0gIkxvd2VyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaG9ybsOtIiA9ICJVcHBlciIpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gYXMuZmFjdG9yKHNwZWNpZXMpKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoc3RyZXRjaCA9IGFzLmZhY3RvcihzdHJldGNoKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiQXZlcyIsIGFmdGVyID0gSW5mKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiSW5zZWN0YSIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJNYW1tYWxpYSIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJBbnVyYSIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJTZXJwZW50ZXMiLCBhZnRlciA9IEluZikpICU+JQ0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiQXN0YWNvaWRlYSIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc2Vhc29uID0gZHBseXI6OnJlY29kZShzZWFzb24sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndpbnRlciIgPSAiV2ludGVyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzcHJpbmciID0gIlNwcmluZyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3VtbWVyIiA9ICJTdW1tZXIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImF1dHVtbiIgPSAiQXV0dW1uIikpICU+JSANCiAgZHBseXI6Om11dGF0ZShzZWFzb24gPSBhcy5mYWN0b3Ioc2Vhc29uKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKHNlYXNvbiA9IGZjdF9yZWxldmVsKHNlYXNvbiwgIlNwcmluZyIsICJTdW1tZXIiLCAiQXV0dW1uIiwgIldpbnRlciIgKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKGxvY2F0aW9uID0gYXMuZmFjdG9yKGxvY2F0aW9uKSkgJT4lIA0KICAjIERpdmlkZSBzdHJlYW1zIGludG8gVXBwZXIgYW5kIGxvd2VyIGFuZCByZW1vdmluZyB2YXJpYWJsZSBzdHJldGNoDQogIGRwbHlyOjptdXRhdGUobG9jYXRpb24gPSBjYXNlX3doZW4obG9jYXRpb24gPT0gIkLDrWxpbmEiICYgc3RyZXRjaCA9PSAiVXBwZXIiIH4gIkhvcm7DrSBCw61saW5hIiwNCiAgICAgICAgICBsb2NhdGlvbiA9PSAiQsOtbGluYSIgJiBzdHJldGNoID09ICJMb3dlciIgfiAiRG9sbsOtIELDrWxpbmEiLCANCiAgICAgICAgICBsb2NhdGlvbiA9PSAiQ2hvbXV0b3ZrYSIgJiBzdHJldGNoID09ICJMb3dlciIgfiAiRG9sbsOtIENob211dG92a2EiLA0KICAgICAgICAgIGxvY2F0aW9uID09ICJDaG9tdXRvdmthIiAmIHN0cmV0Y2ggPT0gIlVwcGVyIiB+ICJIb3Juw60gQ2hvbXV0b3ZrYSIsDQogICAgICAgICAgbG9jYXRpb24gPT0gIlByaXNlY25pY2UiIH4gIlDFmcOtc2XEjW5pY2UiLA0KICAgICAgICAgIFRSVUUgfiAiamV6ZXJvIE1pbGFkYSIpKSAlPiUgDQogIGRwbHlyOjptdXRhdGUobG9jYXRpb24gPSBhcy5mYWN0b3IobG9jYXRpb24pKSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoLXN0cmV0Y2gpDQogIA0KDQoNCnN1bW1hcnkodGlkeV9kYikNCg0KaGVhZCh0aWR5X2RiKQ0KDQp3cml0ZS5jc3YyKHRpZHlfZGIsImRhdGFTaGlueS90aWR5X2RiIiwgcm93Lm5hbWVzID0gRkFMU0UpDQoNCmBgYA0KDQoNCiMjIEZpc2ggbHVtcGVkIGluIG9uZSBjYXRlZ29yeQ0KDQpgYGB7ciBmaXNoLWx1bXBlZH0NCg0KbHVtcGVkX2Zpc2ggPC0gdGlkeV9kYiAlPiUgDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGNhc2Vfd2hlbigNCiAgICBzcGVjaWVzID09ICJBdmVzIiB+ICJBdmVzIiwNCiAgICBzcGVjaWVzID09ICJJbnNlY3RhIiB+ICdJbnNlY3RhJywNCiAgICBzcGVjaWVzID09ICJNYW1tYWxpYSIgfiAnTWFtbWFsaWEnLA0KICAgIHNwZWNpZXMgPT0gIkFudXJhIiB+ICdBbnVyYScsDQogICAgc3BlY2llcyA9PSAiU2VycGVudGVzIiB+ICdTZXJwZW50ZXMnLA0KICAgIHNwZWNpZXMgPT0gIkFzdGFjb2lkZWEiIH4gJ0FzdGFjb2lkZWEnLA0KICAgIA0KICAgIFRSVUUgfiAnRmlzaCcgKSkNCg0KDQpoZWFkKGx1bXBlZF9maXNoKQ0KDQp3cml0ZS5jc3YyKGx1bXBlZF9maXNoLCJkYXRhU2hpbnkvbHVtcGVkX2Zpc2giLCByb3cubmFtZXMgPSBGQUxTRSkNCg0KDQpgYGANCg0KIyBEaWV0OiBXaGF0IGRvIG90dGVycyBlYXQsIGluIHdoaWNoIHByb3BvcnRpb24gb2Ygc3BlY2llcz8NCg0KVGhlIGNhdGVnb3J5ICJTYWxtb25pZHMiIGluY2x1ZGVzIFNhbG1vIHRydXR0YSBtLmZhcmlvLCBPbmNvcmh5bmNodXMgbXlraXNzIGFuZCB1bmlkZW50aWZpZWQgc2FsbW9uaWRzLg0KDQojIyBJZGVudGlmaWVkIHByZXkNCg0KTnVtYmVyIG9mIGluZGl2aWR1YWwgcHJleSBmb3VuZCBpbiBzcHJhaW50cyBpbiBlYWNoIGxvY2F0aW9uDQoNCmBgYHtyIG51bWJlci10YWJsZX0NCg0KdG90YWxfcHJleSA8LSB0aWR5X2RiICU+JSANCiAgZHBseXI6OnNlbGVjdChsb2NhdGlvbiwgc3BlY2llcykgJT4lDQogIGRwbHlyOjpjb3VudChzcGVjaWVzLCBsb2NhdGlvbikgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gbG9jYXRpb24sIHZhbHVlc19mcm9tID0gbiApICU+JSANCiAgcmVwbGFjZShpcy5uYSguKSwgMCkNCg0Ka2FibGUodG90YWxfcHJleSwgYWxpZ24gPSAibGNjcnIiKSAlPiUgDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoKQ0KDQpgYGANCg0KIyMgRGlldCBpcyB2ZXJ5IHZhcmllZA0KDQojIyMgQ3VzdG9tIHBhbGV0dGUNCg0KYGBge3IgY3VzdG9tX3BhbGV0dGV9DQoNCiNDcmVhdGUgY3VzdG9tIHBhbGV0dGUNCiMgDQpzZWVkIDwtIGMoIiNmZjAwMDAiLCAiIzAwZmYwMCIsICIjMDAwMGZmIikNCg0Kc3BlY2llc192IDwtIGxldmVscyh0aWR5X2RiJHNwZWNpZXMpDQoNCnNwZWNpZXNfdmVjdG9yPC0gYyhzcGVjaWVzX3YsICJPdGhlciIpDQoNCiMgbmFtZXMocGFsZXR0ZTEpID0gc3BlY2llc192ZWN0b3INCg0Kc3BlY2llc19jb2xvcnMgPSBzZXROYW1lcyhvYmplY3QgPSBjcmVhdGVQYWxldHRlKDMxLCBzZWVkLCBwcmVmaXg9Im1pbmUiKSwgbm0gPSBzcGVjaWVzX3ZlY3RvcikNCg0Kc3dhdGNoKHNwZWNpZXNfY29sb3JzKQ0KI3ByaW50KHNwZWNpZXNfY29sb3JzKQ0KYGBgDQoNCg0KDQoNCg0KIyMgTW9zdCBDb21tb24gUHJleSBieSBzZWFzb24NCg0KKEx1bXBpbmcgNSUgbGVzcyBjb21tb24pDQoNCmBgYHtyIG51bWJlci1ieS1zcC1sZXNzLWNhdGVnb3JpZXMsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEwfQ0KDQoNCg0KdGlkeV9kYiAlPiUgDQogICMgZ3JvdXAgYnkgbG9jYXRpb24gYmVmb3JlIGx1bXBpbmcgc28gdGhhdCAwLjA1IGFwcGxpZXMgdG8gZWFjaCBzZXBhcmF0ZWx5DQogIGRwbHlyOjpncm91cF9ieShsb2NhdGlvbikgJT4lIA0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2Moc3BlY2llcykpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIkFzdGFjb2lkZWEiLCAiQW51cmEiLCBhZnRlciA9IEluZikpICU+JQ0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JSAgIA0KICBkcGx5cjo6bXV0YXRlKGxvY2F0aW9uID0gZmN0X3JlbGV2ZWwobG9jYXRpb24sICJqZXplcm8gTWlsYWRhIiwgYWZ0ZXIgPSAwKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGxvY2F0aW9uLCBmaWxsPXNwZWNpZXMpKSArIA0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9IHNwZWNpZXNfY29sb3JzKSArDQogIGZhY2V0X3dyYXAoLiB+IHNlYXNvbikrDQogIGdlb21fYmFyKCkrDQogIHRoZW1lX2J3KCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIklkZW50aWZpZWQgcHJleSIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBsYWJzKGZpbGwgPSAiU3BlY2llcyIpICsNCiAgI3RoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiS3J1c25lIEhvcnk6IE1vc3QgY29tbW9uIHByZXkgYnkgc2Vhc29uIikgKw0KICAjIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKw0KICAjIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1GQUxTRSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArIA0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKyANCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsgDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkrDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkNCg0KDQoNCmBgYA0KDQoNCg0KDQoNCg0KDQojIyBBbGwgdG9nZXRoZXIgYXMgcHJvcG9ydGlvbiANCg0KIyMgTW9zdCBjb21tb24gcHJleTogQWxsIHRvZ2V0aGVyIGFzIHByb3BvcnRpb24gKGx1bXBpbmcgNSUgbGVzcyBjb21tb24pDQoNCmBgYHtyIHByb3BzcC1tb3N0LWNvbW1vbiwgZWNobz1UUlVFLCBmaWcud2lkdGg9MTB9DQoNCg0KdGlkeV9kYiAlPiUgDQogICMgZ3JvdXAgYnkgc3RyZXRjaCBhbmQgbG9jYXRpb24gYmVmb3JlIGx1bXBpbmcgc28gdGhhdCAwLjA1IGFwcGxpZXMgdG8gZWFjaCBzdHJldGNoIHNlcGFyYXRlZGx5DQogIGRwbHlyOjpncm91cF9ieShsb2NhdGlvbikgJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KIG11dGF0ZShzcGVjaWVzID0gZmN0X3Jlb3JkZXIoc3BlY2llcywgZGVzYyhzcGVjaWVzKSkpICU+JQ0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiQXN0YWNvaWRlYSIsICJBbnVyYSIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJPdGhlciIsIGFmdGVyID0gSW5mKSkgJT4lDQogZHBseXI6Om11dGF0ZShsb2NhdGlvbiA9IGZjdF9yZWxldmVsKGxvY2F0aW9uLCAiamV6ZXJvIE1pbGFkYSIsIGFmdGVyID0gMCkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBsb2NhdGlvbiwgZmlsbD1zcGVjaWVzKSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9IHNwZWNpZXNfY29sb3JzKSArDQogICNmYWNldF9ncmlkKC4gfiBzZWFzb24pKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlByb3BvcnRpb24gb2Ygc3BlY2llcyIsIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArDQogIGxhYnMoZmlsbCA9ICJTcGVjaWVzIHByb3BvcnRpb24iKSArDQogICMgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgbGFicyh0aXRsZSA9ICJLcnVzbmUgSG9yeTogTW9zdCBjb21tb24gcHJleSwgeWVhciByb3VuZCIpICsgDQogIGNvb3JkX2ZsaXAoKSsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpKQ0KDQoNCg0KDQpgYGANCg0KDQoNCg0KDQojIyBBbGwgZmlzaCBsdW1wZWQgdG9nZXRoZXIsIGFzIHByb3BvcnRpb24gDQoNCg0KYGBge3IgcHJvcHNwZmlzaCwgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD0xMH0NCg0KDQoNCmx1bXBlZF9maXNoICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsIkZpc2giKSkgJT4lDQogIGRwbHlyOjptdXRhdGUobG9jYXRpb24gPSBmY3RfcmVsZXZlbChsb2NhdGlvbiwgImplemVybyBNaWxhZGEiLCBhZnRlciA9IDApKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbG9jYXRpb24sIGZpbGw9c3BlY2llcykpICsNCiAgI2ZhY2V0X2dyaWQoLiB+IHNlYXNvbikrDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1GQUxTRSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlByb3BvcnRpb24gb2Ygc3BlY2llcyIsIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKw0KICAgIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyhmaWxsID0gIlNwZWNpZXMgcHJvcG9ydGlvbiIpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArDQogICMgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgbGFicyh0aXRsZSA9ICJLcnVzbmUgSG9yeSIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpKQ0KDQoNCg0KDQpgYGANCg0KIyMgQWxsIGZpc2ggbHVtcGVkIHRvZ2V0aGVyLCBhcyBwcm9wb3J0aW9uLCBieSBzZWFzb24gDQoNCg0KYGBge3IgcHJvcHNwZmlzaC1zZWFzb24sIGVjaG89VFJVRSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9DQoNCg0KDQpsdW1wZWRfZmlzaCAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCJGaXNoIikpICU+JQ0KICBkcGx5cjo6bXV0YXRlKGxvY2F0aW9uID0gZmN0X3JlbGV2ZWwobG9jYXRpb24sICJqZXplcm8gTWlsYWRhIiwgYWZ0ZXIgPSAwKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGxvY2F0aW9uLCBmaWxsPXNwZWNpZXMpKSArDQogIGZhY2V0X3dyYXAoLiB+IHNlYXNvbikrDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1GQUxTRSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlByb3BvcnRpb24gb2Ygc3BlY2llcyIsIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArDQogIGxhYnMoZmlsbCA9ICJTcGVjaWVzIHByb3BvcnRpb24iKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKw0KICAjIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGxhYnModGl0bGUgPSAiS3J1c25lIEhvcnkiKSArDQogIGNvb3JkX2ZsaXAoKSsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpKQ0KDQoNCg0KDQpgYGANCg0KDQojIyBFYWNoIGxvY2F0aW9uIHNlcGFyYXRlbHkgDQoNCg0KIyBIb3Juw60gQsOtbGluYSANCg0KIyMgUGVyY2VudGFnZSBvZiBlYWNoIHByZXkgaW4gdGhlIGRpZXQNCg0KDQojIyMjIFBsb3Qgd2l0aCBmaXhlZCBzY2FsZXMNCg0KDQpgYGB7ciBzZWFzb25GaXhzY2FsZXMsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9DQoNCnRpZHlfZGIgJT4lDQogIGZpbHRlcihsb2NhdGlvbiA9PSAiSG9ybsOtIELDrWxpbmEiKSAlPiUNCiAgZHBseXI6OmZpbHRlcihzZWFzb24gIT0gIldpbnRlciIpICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9pbmZyZXEoc3BlY2llcykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzcGVjaWVzLCBncm91cCA9IGxvY2F0aW9uLCBmaWxsPXNwZWNpZXMpKSArDQogIGdlb21fYmFyKGFlcyh5ID0gLi5wcm9wLi4sIGZpbGwgPSBmYWN0b3IoLi54Li4pKSwgc3RhdCA9ICJjb3VudCIsIHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgI3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29sb3JzKSArDQogIGdlb21fdGV4dChhZXMoDQogICAgbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQoLi5wcm9wLi4sIGFjY3VyYWN5ID0gMkwpLA0KICAgIHkgPSAuLnByb3AuLg0KICApLCBzdGF0ID0gImNvdW50Iiwgdmp1c3QgPSAtMC4xLCBoanVzdCA9IC0wLjEsIHNpemUgPSAzKSArDQogIGxhYnMoeSA9ICIiLCB4ID0gIiIpICsNCiAgZmFjZXRfd3JhcCh+c2Vhc29uKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiSG9ybsOtIELDrWxpbmE6IE90dGVyIGRpZXQgYnkgc2Vhc29uIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSwgbGltaXRzID0gYygwLCAwLjYpKQ0KDQoNCg0KDQpgYGANCg0KDQojIERvbG7DrSBCw61saW5hIA0KDQoNCg0KDQojIyMgRml4ZWQgc2NhbGVzDQoNCmBgYHtyIGRCaWxpbmFzcDIsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTEyfQ0KZEJpbGluYSA8LSB0aWR5X2RiICU+JQ0KICBmaWx0ZXIobG9jYXRpb24gPT0gIkRvbG7DrSBCw61saW5hIikNCg0KZEJpbGluYSAlPiUNCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUgDQogIyBkcGx5cjo6ZmlsdGVyKHNlYXNvbiAhPSAiV2ludGVyIikgJT4lIA0KICAjZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUgDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2luZnJlcShzcGVjaWVzKSkgJT4lDQogIGdncGxvdCggYWVzKHg9IHNwZWNpZXMsIGdyb3VwID0gbG9jYXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArIA0KICANCiAgZ2VvbV9iYXIoYWVzKHkgPSAuLnByb3AuLiwgZmlsbCA9IGZhY3RvciguLnguLikpLCBzdGF0PSJjb3VudCIsIHNob3cubGVnZW5kID0gRkFMU0UpICArIA0KICBnZW9tX3RleHQoYWVzKCBsYWJlbCA9IHNjYWxlczo6cGVyY2VudCguLnByb3AuLiwgYWNjdXJhY3k9IDAuMSksDQogICAgICAgICAgICAgICAgIHk9IC4ucHJvcC4uICksIHN0YXQ9ICJjb3VudCIsIHZqdXN0ID0gMCwgaGp1c3QgPSAtMC4xLCBzaXplPTMpICsNCiAgbGFicyh5ID0gIiIsIHggPSIiKSArDQogIGZhY2V0X3dyYXAofiBzZWFzb24pICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJEb2xuw60gQsOtbGluYTogT3R0ZXIgZGlldCBieSBzZWFzb24iKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksIGxpbWl0cyA9IGMoMCwgMC42NSkpDQoNCg0KDQpgYGANCg0KIyMjIEZpeGVkIHNjYWxlcyAwLjA1IGx1bXBlZA0KDQpgYGB7ciBkQmlsaW5hc3AybHVtcGVkLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD04fQ0KZEJpbGluYSA8LSB0aWR5X2RiICU+JQ0KICBmaWx0ZXIobG9jYXRpb24gPT0gIkRvbG7DrSBCw61saW5hIikNCg0KZEJpbGluYSAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JSANCiAjIGRwbHlyOjpmaWx0ZXIoc2Vhc29uICE9ICJXaW50ZXIiKSAlPiUgDQogICNkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JSANCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfaW5mcmVxKHNwZWNpZXMpKSAlPiUNCiAgZ2dwbG90KCBhZXMoeD0gc3BlY2llcywgZ3JvdXAgPSBsb2NhdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsgDQogIA0KICBnZW9tX2JhcihhZXMoeSA9IC4ucHJvcC4uLCBmaWxsID0gZmFjdG9yKC4ueC4uKSksIHN0YXQ9ImNvdW50Iiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgICsgDQogIGdlb21fdGV4dChhZXMoIGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KC4ucHJvcC4uLGFjY3VyYWN5ID0gMkwpLA0KICAgICAgICAgICAgICAgICB5PSAuLnByb3AuLiApLCBzdGF0PSAiY291bnQiLCB2anVzdCA9IDAsIGhqdXN0ID0gLTAuMSwgc2l6ZT0zKSArDQogIGxhYnMoeSA9ICIiLCB4ID0iIikgKw0KICBmYWNldF93cmFwKH4gc2Vhc29uKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiRG9sbsOtIELDrWxpbmE6IE90dGVyIGRpZXQgYnkgc2Vhc29uIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSwgbGltaXRzID0gYygwLCAwLjYpKQ0KDQoNCg0KYGBgDQoNCg0KIyBQxZnDrXNlxI1uaWNlIA0KDQpXYXRlciByZXNlcnZvaXIgZm9yIGh1bWFuIGNvbnN1bXB0aW9uLg0KDQojIyBQZXJjZW50YWdlIG9mIGVhY2ggcHJleSBpbiB0aGUgZGlldA0KDQpgYGB7ciBwcmlzc3AsIGVjaG89VFJVRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MTB9DQoNCnByaXMgPC0gdGlkeV9kYiAlPiUNCiAgZmlsdGVyKGxvY2F0aW9uID09ICJQxZnDrXNlxI1uaWNlIikNCg0KDQpgYGANCg0KDQoNCg0KDQojIyMgRml4ZWQgc2NhbGVzDQoNCmBgYHtyIHByaXNEaWV0MiwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9OH0NCg0KcHJpcyAlPiUNCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoc2Vhc29uICE9ICJXaW50ZXIiKSAlPiUgDQogICNkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JSANCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfaW5mcmVxKHNwZWNpZXMpKSAlPiUNCiBnZ3Bsb3QoIGFlcyh4PSBzcGVjaWVzLCBncm91cCA9IGxvY2F0aW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyANCiAgDQogIGdlb21fYmFyKGFlcyh5ID0gLi5wcm9wLi4sIGZpbGwgPSBmYWN0b3IoLi54Li4pKSwgc3RhdD0iY291bnQiLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSAgKyANCiAgZ2VvbV90ZXh0KGFlcyggbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQoLi5wcm9wLi4sYWNjdXJhY3kgPSAxTCksDQogICAgICAgICAgICAgICAgIHk9IC4ucHJvcC4uICksIHN0YXQ9ICJjb3VudCIsIHZqdXN0ID0gMCwgaGp1c3QgPSAtMC4xLCBzaXplPTMpICsNCiAgbGFicyh5ID0gIiIsIHggPSIiKSArDQogIGZhY2V0X3dyYXAofiBzZWFzb24pICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJQxZnDrXNlxI1uaWNlOiBPdHRlciBkaWV0IGJ5IHNlYXNvbiIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCksIGxpbWl0cyA9IGMoMCwgMC42KSkNCmBgYA0KDQoNCg0KDQoNCiMgSmV6ZXJvIE1pbGFkYSANCg0KDQoNCg0KDQojIyBUb3RhbCBwcm9wb3J0aW9ucw0KDQoNCg0KIyMjIEZpeGVkIHNjYWxlcw0KDQpgYGB7ciBqZXpTZWFzb25GaXhlZCwgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTl9DQoNCmpleiA8LSB0aWR5X2RiICU+JQ0KICBmaWx0ZXIobG9jYXRpb24gPT0gImplemVybyBNaWxhZGEiKQ0KDQoNCmpleiAlPiUNCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUgDQogICNkcGx5cjo6ZmlsdGVyKHNlYXNvbiAhPSAiV2ludGVyIikgJT4lIA0KICAjZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUgDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2luZnJlcShzcGVjaWVzKSkgJT4lDQogIGdncGxvdCggYWVzKHg9IHNwZWNpZXMsIGdyb3VwID0gbG9jYXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArIA0KICANCiAgZ2VvbV9iYXIoYWVzKHkgPSAuLnByb3AuLiwgZmlsbCA9IGZhY3RvciguLnguLikpLCBzdGF0PSJjb3VudCIsIHNob3cubGVnZW5kID0gRkFMU0UpICArIA0KICBnZW9tX3RleHQoYWVzKCBsYWJlbCA9IHNjYWxlczo6cGVyY2VudCguLnByb3AuLixhY2N1cmFjeSA9IDAuMSksDQogICAgICAgICAgICAgICAgIHk9IC4ucHJvcC4uICksIHN0YXQ9ICJjb3VudCIsIHZqdXN0ID0gMCwgaGp1c3QgPSAtMC4xLCBzaXplPSAzKSArDQogIGxhYnMoeSA9ICIiLCB4ID0iIikgKw0KICBmYWNldF93cmFwKH4gc2Vhc29uKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiSmV6ZXJvIE1pbGFkYTogT3R0ZXIgZGlldCBieSBzZWFzb24iKSArDQpzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSwgbGltaXRzID0gYygwLDEpKQ0KYGBgDQoNCiMjIyBGaXhlZCBzY2FsZXMgMC4wNSBsdW1wZWQNCg0KYGBge3IgamV6U2Vhc29uZml4ZWRsdW1wZWQsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEwfQ0KDQpqZXogPC0gdGlkeV9kYiAlPiUNCiAgZmlsdGVyKGxvY2F0aW9uID09ICJqZXplcm8gTWlsYWRhIikNCg0KDQpqZXogJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUgDQogICNkcGx5cjo6ZmlsdGVyKHNlYXNvbiAhPSAiV2ludGVyIikgJT4lIA0KICAjZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUgDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2luZnJlcShzcGVjaWVzKSkgJT4lDQogIGdncGxvdCggYWVzKHg9IHNwZWNpZXMsIGdyb3VwID0gbG9jYXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArIA0KICANCiAgZ2VvbV9iYXIoYWVzKHkgPSAuLnByb3AuLiwgZmlsbCA9IGZhY3RvciguLnguLikpLCBzdGF0PSJjb3VudCIsIHNob3cubGVnZW5kID0gRkFMU0UpICArIA0KICBnZW9tX3RleHQoYWVzKCBsYWJlbCA9IHNjYWxlczo6cGVyY2VudCguLnByb3AuLixhY2N1cmFjeSA9IDJMKSwNCiAgICAgICAgICAgICAgICAgeT0gLi5wcm9wLi4gKSwgc3RhdD0gImNvdW50Iiwgdmp1c3QgPSAwLCBoanVzdCA9IC0wLjEsIHNpemU9IDMpICsNCiAgbGFicyh5ID0gIiIsIHggPSIiKSArDQogIGZhY2V0X3dyYXAofiBzZWFzb24pICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJKZXplcm8gTWlsYWRhOiBPdHRlciBkaWV0IGJ5IHNlYXNvbiIpICsNCnNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpLCBsaW1pdHMgPSBjKDAsMSkpDQpgYGANCg0KDQoNCiMgRG9sbsOtIENob211dG92a2ENCg0KIyMgUGVyY2VudGFnZSBvZiBlYWNoIHByZXkgaW4gdGhlIGRpZXQNCg0KYGBge3IgZENob3NwLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTEwfQ0KZENobyA8LSB0aWR5X2RiICU+JQ0KICBmaWx0ZXIobG9jYXRpb24gPT0gIkRvbG7DrSBDaG9tdXRvdmthIikNCg0KDQpgYGANCg0KDQoNCg0KIyMjIFRvdGFsIHByb3BvcnRpb25zDQoNCg0KDQojIyMgUGxvdCB3aXRoIGZpeGVkIHNjYWxlcywgbm90IGx1bXBlZA0KDQpgYGB7ciBkQ2hvc3BTZWFzb24sIGVjaG89VFJVRSwgZmlnLmhlaWdodD05LCBmaWcud2lkdGg9OX0NCg0KZENobyAlPiUNCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUgDQogICNkcGx5cjo6ZmlsdGVyKHNlYXNvbiAhPSAiV2ludGVyIikgJT4lIA0KICAjZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUgDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2luZnJlcShzcGVjaWVzKSkgJT4lDQogIGdncGxvdCggYWVzKHg9IHNwZWNpZXMsIGdyb3VwID0gbG9jYXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArIA0KICANCiAgZ2VvbV9iYXIoYWVzKHkgPSAuLnByb3AuLiwgZmlsbCA9IGZhY3RvciguLnguLikpLCBzdGF0PSJjb3VudCIsIHNob3cubGVnZW5kID0gRkFMU0UpICArICANCiAgZ2VvbV90ZXh0KGFlcyggbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQoLi5wcm9wLi4sYWNjdXJhY3kgPSAyTCksDQogICAgICAgICAgICAgICAgIHk9IC4ucHJvcC4uICksIHN0YXQ9ICJjb3VudCIsIHZqdXN0ID0gMCwgaGp1c3QgPSAtMC4xLHNpemU9Mi41KSArDQogIGxhYnMoeSA9ICIiLCB4ID0iIikgKw0KICBmYWNldF93cmFwKH4gc2Vhc29uKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiRG9sbsOtIENob211dG92a2E6IE90dGVyIGRpZXQgYnkgc2Vhc29uIikgKw0Kc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCksIGxpbWl0cyA9IGMoMCwwLjYpKQ0KDQpgYGANCg0KIyBIb3Juw60gQ2hvbXV0b3ZrYQ0KDQojIyBQZXJjZW50YWdlIG9mIGVhY2ggcHJleSBpbiB0aGUgZGlldA0KDQpgYGB7ciBoQ2hvLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEwfQ0KaENobyA8LSB0aWR5X2RiICU+JQ0KICBmaWx0ZXIobG9jYXRpb24gPT0gIkhvcm7DrSBDaG9tdXRvdmthIikNCg0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KIyMjIFBsb3Qgd2l0aCBmaXhlZCBzY2FsZXMsIG5vdCBsdW1wZWQNCg0KYGBge3IgaENob3NwU2Vhc29uLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9DQoNCmhDaG8gJT4lDQogICNtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiAhPSAiU3VtbWVyIikgJT4lIA0KICAjZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUgDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2luZnJlcShzcGVjaWVzKSkgJT4lDQogIGdncGxvdCggYWVzKHg9IHNwZWNpZXMsIGdyb3VwID0gbG9jYXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArIA0KICANCiAgZ2VvbV9iYXIoYWVzKHkgPSAuLnByb3AuLiwgZmlsbCA9IGZhY3RvciguLnguLikpLCBzdGF0PSJjb3VudCIsIHNob3cubGVnZW5kID0gRkFMU0UpICArIA0KICBnZW9tX3RleHQoYWVzKCBsYWJlbCA9IHNjYWxlczo6cGVyY2VudCguLnByb3AuLixhY2N1cmFjeSA9IDJMKSwNCiAgICAgICAgICAgICAgICAgeT0gLi5wcm9wLi4gKSwgc3RhdD0gImNvdW50Iiwgdmp1c3QgPSAtMCwgaGp1c3QgPSAtMC4xLCBzaXplID0zKSArDQogIGxhYnMoeSA9ICIiLCB4ID0iIikgKw0KICBmYWNldF93cmFwKH4gc2Vhc29uKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiSG9ybsOtIENob211dG92a2E6IE90dGVyIGRpZXQgYnkgc2Vhc29uIikgKw0Kc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCksIGxpbWl0cyA9IGMoMCwxKSkNCg0KYGBgDQoNCg0KIyBTSVpFDQoNCg0KIyMgRGlldCBieSBsb2NhdGlvbiBhbmQgc2l6ZQ0KDQpQbG90IGFsbCB0b2dldGhlciBqdXN0IHRvIHNlZSBpZiB0aGUgZGF0YSBsb29rcyByaWdodC4NCg0KYGBge3IgcGxvdF9hbGwsIGVjaG89VFJVRSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9DQoNCg0KbHVtcGVkX2Zpc2ggJT4lDQogIGRyb3BfbmEoc2l6ZSkgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKHNwZWNpZXMgPT0gIkZpc2giKSAlPiUNCiBnZ3Bsb3QoYWVzKHggPSBsb2NhdGlvbiwgZmlsbCA9IHNpemUpKSArDQogICNmYWNldF9ncmlkKC4gfiBsb2NhdGlvbikrDQogIGdlb21fYmFyKCBwb3NpdGlvbiA9ICJkb2RnZSIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIiIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBsYWJzKGZpbGwgPSAiU2l6ZSIpICsNCiAgI3RoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIyBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIktydXNuZSBIb3J5OiBTaXplIGRpc3RyaWJ1dGlvbiIpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1UUlVFKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCg0KDQoNCmBgYA0KDQojIEp1c3Qgc2FsbW9uaWQgc2l6ZQ0KDQpgYGB7ciBzaXplX3NhbG1vbmlkLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD05fQ0KDQp0aWR5X2RiICU+JQ0KIGRwbHlyOjpmaWx0ZXIoc3BlY2llcyA9PSAiU2FsbW9uaWRzIikgJT4lDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIGZpbGwgPSBzaXplKSkgKw0KICBmYWNldF9ncmlkKC4gfiBsb2NhdGlvbikrDQogIGdlb21fYmFyKCBwb3NpdGlvbiA9ICJkb2RnZSIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIiIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIiwgbGFiZWxzPU5VTEwpICsNCiAgbGFicyhmaWxsID0gIlNpemUiKSArDQogICN0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICMgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJLcnVzbmUgSG9yeTogU2l6ZSBkaXN0cmlidXRpb24gb2Ygc2FsbW9uaWRzIikgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlBhaXJlZCIpICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShkcm9wPUZBTFNFKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gTlVMTCkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCg0KDQpgYGANCg0KDQoNCg==