Aim

Global Problem: Loss of Biodiversity

The Earth is in the midst of a mass extinction; one of the most threatened groups of invertebrates is Amphibians. Already threatened by the environmental changes of the Anthropocene, habitat destruction, climate change, and pollution Amphibians also face what has been described as “the world’s worst plague” in the form of Chytridiomycosis caused by the parasitic fungi Batrachochytrium dendrobatidis (Bd) (Beebee, 2005). Bd is a generalist parasite that has been found in over 500 species of amphibian, and has been highly proliferative, found in 48% of locations surveyed (James, 2015). The first recorded case in North America was in 1961 and, thought to be carried by the frog X. laevis(Weldon, 2004).

Question and Problem

This project would explore the proposed origin, timeline, and path of infection of Bd in the US via map visualizations of the progress of the disease. - Does the sampling data coincide with the proposed origin of Bd? (Maine in the early 1960s) - What Amphibian families and species are the most affected by the disease? - Which areas have the highest sampling? Which areas have the highest rates of Bd? - Is there a pattern between sampling and Bd occurrence?

Locaion and Grain

This analysis will focus regionally on the US over a time scale of the introduction of Bd in to the US in the 1960’s to present day using states as the grain (coordinates were not included in data and some of the location data was vague).

Method

Data

Data was downloaded from Bd-maps.net, a database dedicated to documenting cases Bd in amphibians around the globe. Data was available for 45 out of 50 states (not data for CT, DE, ND, RI and SD).

Set up workspace and Load Data

Set Up

Load Librays and Set Working Direcotry

library(tidyverse)
library(lubridate)
library(reshape2)
library(fiftystater)
library(mapproj)
library(colorRamps)
require("knitr")

#opts_knit$set(root.dir = "/Users/lahuuki/Desktop/Bd")#mac
opts_knit$set(root.dir = "C:\\Users\\tuf48649\\Desktop\\Bd_2")#windows

Build State Data

To edit the data: - remove record (metadata) - specific location data was simplified to state as coodinates were not included in the downloaded data - dates were correctly formatted - fixed No. tested (it always is 1, should be sum of ve+ and ve-) - remove life stage as the data is mostly missing - remove method as it is not needed for this analysis

#build tibble to itterate trough data
no_data_states<- c("DE","ND","RI","SD","CT")
states <- read_csv("states.csv") %>% #list of state abrviations without states with no data used to iterate through data
  filter(!Abbreviation %in% no_data_states) %>% 
  rename(AB = Abbreviation) %>%
  mutate(file = paste("Bd_state_data/",AB ,".txt", sep = ""),
                      data = paste(AB,"_data",sep =""),
                      state = tolower(State)) %>%
  select(-State)
  


#read data files
for(i in 1:length(states$AB)){
  assign(states$data[i],read_csv(states$file[i]))
}

#function to correct data files, filter out unused data, fix NO. Tested

correct_state_data <- function(state){
  data <- eval(as.name(state$data))
  data %>% mutate(state = state$state, 
                  Tested = (`+ve`+`-ve`),
                  Prop_pos = (`+ve`/Tested),
                  Year = year(dmy(Year))) %>% 
  select(state, Year, `Taxa Group`, Taxon, Species, History,Tested,Prop_pos,`+ve`, `-ve`, `IUCN Status`) %>%
    rename(Order = `Taxa Group`, Family = Taxon)
}

for(i in 1:length(states$AB)){
  #print(states$AB[i])
  assign(states$data[i],correct_state_data(states[i,]))
}

All_data <- filter(AL_data, Order == "cant equal this") #define All_data for merging

for(i in 1:length(states$AB)){
  #print(i)
  All_data <- merge(All_data, eval(as.name(states$data[i])), all.x = T, all.y = T)
}

All_data <- as.tibble(All_data) #convert back to tibble

Preliminary Data Exploration

Summary

  • 1812 records from 1965 to 2010
  • Two Orders: Anura (frogs and toads) and Caudata (salamanders), no Gymnophiona
  • 14 Familys
  • 152 species
#Explore the data
range(All_data$Year)#find range of dates
[1] 1965 2010
#function to count unique values 
count_unique <- function(var){
  print(deparse(substitute(var)))
  length(unique(var))
}
count_unique(All_data$Order)
[1] "All_data$Order"
[1] 2
count_unique(All_data$Family)
[1] "All_data$Family"
[1] 14
count_unique(All_data$Species)
[1] "All_data$Species"
[1] 152

Distibution of Sampling Over time

The data is not evenly sampled over the years,with less than 100 test per year untill 2000 spiking in 2006. This makes sense as Bd was only discovered in 1998, and most of the earlier samples are from museum collections. This data collection also trails off in 2010 so does not provide infomation about the last 8 years of the disease. The wild diffrences in sampling numbers also throw off the proportion of positive results out of all samples, no clear trend can be observed.

#sampling over time
samples_by_year <- All_data %>%group_by(Year) %>%
  summarise(total_tested = sum(Tested),
                total_pos = sum(`+ve`),
                total_neg = sum(`-ve`),
                ave_prop = mean(Prop_pos))
#samples over time
ggplot(data = samples_by_year,aes(x = Year)) +
  geom_line(aes( y = total_tested,color = "Total")) +
  geom_line(aes( y = total_pos,color = "Positive Test"))+ annotate("text", x = 1998, y = 1500, label = "Discovered") + annotate("segment", x = 1998, xend = 1998, y = 0, yend = 3000, color = "red")

#proportion of positive results over time
ggplot(data = samples_by_year)+geom_point(aes(x = Year, y = ave_prop, color = total_tested), size = 2.5)+scale_color_gradient(low="blue", high="red") + annotate("text", x = 1998, y = 0.5, label = "Discovered") + annotate("segment", x = 1998, xend = 1998, y = 0, yend = 1, color = "red")

Distibution of Sampling Over Species

IUCN data is not consistant with species name. Distribution of sampling makes sense, favoring more abumdant species.

#distibution of sampling over familys
All_data %>%group_by(Order,Family) %>% 
  summarise(total_tested = sum(Tested),
                total_pos = sum(`+ve`),
                total_neg = sum(`-ve`),
                ave_prop = mean(Prop_pos))%>%
  ggplot() + geom_bar(aes(x= reorder(Family, total_tested), y =total_tested, fill = Order),stat = "identity") +coord_flip()

#distibution of sampling over species 
All_data %>%group_by(Order,Family, Species) %>% 
  summarise(total_tested = sum(Tested),
                total_pos = sum(`+ve`),
                total_neg = sum(`-ve`),
                ave_prop = mean(Prop_pos))%>%
  filter(total_tested >50) %>%
  ggplot() + geom_bar(aes(x= reorder(Species, total_tested), y =total_tested, fill = Family),stat = "identity") +coord_flip()

#distibution of sampling over IUCN status
All_data %>%group_by(`IUCN Status`, na.rm = T) %>% 
  summarise(total_tested = sum(Tested),
                total_pos = sum(`+ve`),
                total_neg = sum(`-ve`),
                ave_prop = mean(Prop_pos))%>%
  filter(total_tested >50) %>%
  ggplot() + geom_bar(aes(x= reorder(`IUCN Status`, total_tested), y =total_tested, fill = `IUCN Status`),stat = "identity")+ coord_flip()

Distribution of Sampling over States

Most states have limited sampling, most data is from the West-coast.

by_state <- All_data %>% group_by(state) %>% summarise(total_tested = sum(Tested),
                total_pos = sum(`+ve`),
                total_neg = sum(`-ve`),
                ave_prop = mean(Prop_pos))
plot_USA <- function(data, fill){
  ggplot(data, aes(map_id = state)) + 
  # map points to the fifty_states shape data
  geom_map(aes(fill = fill), map = fifty_states) + 
  expand_limits(x = fifty_states$long, y = fifty_states$lat) +
  coord_map() + 
  scale_x_continuous(breaks = NULL) + 
  scale_y_continuous(breaks = NULL) +
  labs(x = "", y = "") +
  scale_fill_gradientn(colours =  rainbow(7, s =0.5))+
  theme(legend.position = "bottom", 
        panel.background = element_blank())
}
plot_USA(by_state, by_state$total_pos)

Species Analysis

What Species has the most positive test?

Bufo boreas (Western Toad), the most hightly sampled species. Adjust for sampling bias by looking at the proportions of positive test results.

by_species <- All_data %>%group_by(Species,`IUCN Status` ) %>% 
  summarise(total_tested = sum(Tested),
                total_pos = sum(`+ve`),
                total_neg = sum(`-ve`),
                ave_prop = mean(Prop_pos))
by_species %>% filter(total_pos >10) %>%
  ggplot() + geom_bar(aes(x= reorder(Species, total_pos), y =total_pos, fill = `IUCN Status`),stat = "identity")+ coord_flip()+labs(x = "Species", y = "Positive Tests")

What Species has the highest proportion of positive test?

Rana sierrae (sierra nevada yellow-legged frog) an endangered frog native to the Sierra Nevadas. Followded by Cryptobranchus alleganiensis (Hellbender giant salamander) from the Applacia region (reported as near threatened on online IUCN). This pattern of high proportion positive test in more threatened species suggest that Bd has an impact on the species survival.

by_species %>% filter(total_pos >10) %>%
  ggplot() + geom_bar(aes(x= reorder(Species, ave_prop), y =ave_prop, fill = `IUCN Status`),stat = "identity")+ coord_flip()+labs(x = "Species", y = "Proportion Positive")

What Family has the most positive test?

-proportion skeewded by low sampling

by_family <- All_data %>%group_by(Family) %>% 
  summarise(total_tested = sum(Tested),
                total_pos = sum(`+ve`),
                total_neg = sum(`-ve`),
                ave_prop = mean(Prop_pos, na.rm = T))
by_family %>% filter(total_pos >10) %>%
  ggplot() + geom_bar(aes(x= reorder(Family, total_pos), y =total_pos, fill = Family),stat = "identity")+ coord_flip()+labs(x = "Family", y = "Positive Tests")

Geographical distibution Over Time

All data

Plot_all_pos_prop <- function(data){
  plot_USA(data, data$total_tested)
  plot_USA(data, data$total_pos)
  plot_USA(data, data$ave_prop)
}
by_state <- All_data %>% group_by(state) %>%
  summarise(total_tested = sum(Tested),
                total_pos = sum(`+ve`),
                ave_prop = mean(Prop_pos, na.rm = T))
require(cowplot)
all_total <-  plot_USA(by_state, by_state$total_tested) + ggtitle("Total test")
all_pos <-  plot_USA(by_state, by_state$total_pos) + ggtitle("Total Positive")
all_prop <-  plot_USA(by_state, by_state$ave_prop) + ggtitle("Prop Positive")
plot_grid(all_total,all_pos,all_prop, nrow=1)

1965-1997(pre-discovery)

year65_97 <- All_data %>% filter(Year < 1998)%>%
  group_by(state) %>%
  summarise(total_tested = sum(Tested),
                total_pos = sum(`+ve`),
                ave_prop = mean(Prop_pos, na.rm = T))
all_total <-  plot_USA(year65_97, year65_97$total_tested) + ggtitle("Total test")
all_pos <-  plot_USA(year65_97, year65_97$total_pos) + ggtitle("Total Positive")
all_prop <-  plot_USA(year65_97, year65_97$ave_prop) + ggtitle("Prop Positive")
plot_grid(all_total,all_pos,all_prop, nrow=1)

1998-2001

year98_01 <- All_data %>% filter(Year >= 1998 | Year <2002)%>%
  group_by(state) %>%
  summarise(total_tested = sum(Tested),
                total_pos = sum(`+ve`),
                ave_prop = mean(Prop_pos, na.rm = T))
all_total <-  plot_USA(year98_01, year98_01$total_tested) + ggtitle("Total test")
all_pos <-  plot_USA(year98_01, year98_01$total_pos) + ggtitle("Total Positive")
all_prop <-  plot_USA(year98_01, year98_01$ave_prop) + ggtitle("Prop Positive")
plot_grid(all_total,all_pos,all_prop, nrow=1)

2002-2005

year <- All_data %>% filter(Year >= 2002 | Year <2006)%>%
  group_by(state) %>%
  summarise(total_tested = sum(Tested),
                total_pos = sum(`+ve`),
                ave_prop = mean(Prop_pos, na.rm = T))
all_total <-  plot_USA(year, year$total_tested) + ggtitle("Total test")
all_pos <-  plot_USA(year, year$total_pos) + ggtitle("Total Positive")
all_prop <-  plot_USA(year, year$ave_prop) + ggtitle("Prop Positive")
plot_grid(all_total,all_pos,all_prop, nrow=1)

2006-2010

year <- All_data %>% filter(Year >2005)%>%
  group_by(state) %>%
  summarise(total_tested = sum(Tested),
                total_pos = sum(`+ve`),
                ave_prop = mean(Prop_pos, na.rm = T))
all_total <-  plot_USA(year, year$total_tested) + ggtitle("Total test")
all_pos <-  plot_USA(year, year$total_pos) + ggtitle("Total Positive")
all_prop <-  plot_USA(year, year$ave_prop) + ggtitle("Prop Positive")
plot_grid(all_total,all_pos,all_prop, nrow=1)

Conclusion

This data proved to be very messy. The sampling was very inconsistent over time and between states. The data showed that many frogs that have high rates of sampled Bd are threatened. Between states over time, the infection seems to move from the North East to the west coast it is hard to see a pattern of Bd spreading across the country. This data is top inconsistent to draw any of the solid conclusion. In an effort to control, the impact of Bd better sampling and documentation needs to implement.

Refrences

Aanensen, D. M., and M. Fisher. “Bd-Maps. www. bd-maps. net.” (2012).

Beebee, T. J. (2005). The amphibian decline crisis: a watershed for conservation biology? Biological Conservation, 125(3), 271-285.

Berger, L. a. (2005). Life cycle stages of the amphibian chytrid Batrachochytrium dendrobatidis. Diseases of aquatic organisms, 68, 51 - 63.

James, T. Y.-R. (2015). Disentangling host, pathogen, and environmental determinants of a recently emerged wildlife disease: lessons from the first 15 years of amphibian chytridiomycosis research. Ecology and Evolution.

Weldon, C. a. (2004). Origin of the amphibian chytrid fungus. Emerging infectious diseases, 10, 2100.

LS0tDQp0aXRsZTogIlRoZSBTcHJlYWQgYW5kIFByZXZhbGFuY2Ugb2YgQmQgaW4gQW1lcmljYW4gQW1waGJpYW5zIg0KYXV0aG9yOiBMb3VzaWUgSHV1a2kNCmRhdGU6IDUvMy8yMDE4DQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KI0FpbQ0KIyNHbG9iYWwgUHJvYmxlbTogTG9zcyBvZiBCaW9kaXZlcnNpdHkNClRoZSBFYXJ0aCBpcyBpbiB0aGUgbWlkc3Qgb2YgYSBtYXNzIGV4dGluY3Rpb247IG9uZSBvZiB0aGUgbW9zdCB0aHJlYXRlbmVkIGdyb3VwcyBvZiBpbnZlcnRlYnJhdGVzIGlzIEFtcGhpYmlhbnMuIEFscmVhZHkgdGhyZWF0ZW5lZCBieSB0aGUgZW52aXJvbm1lbnRhbCBjaGFuZ2VzIG9mIHRoZSBBbnRocm9wb2NlbmUsIGhhYml0YXQgZGVzdHJ1Y3Rpb24sIGNsaW1hdGUgY2hhbmdlLCBhbmQgcG9sbHV0aW9uICBBbXBoaWJpYW5zIGFsc28gZmFjZSB3aGF0IGhhcyBiZWVuIGRlc2NyaWJlZCBhcyAidGhlIHdvcmxkJ3Mgd29yc3QgcGxhZ3VlIiBpbiB0aGUgZm9ybSBvZiAgQ2h5dHJpZGlvbXljb3NpcyBjYXVzZWQgYnkgdGhlIHBhcmFzaXRpYyBmdW5naSBCYXRyYWNob2NoeXRyaXVtIGRlbmRyb2JhdGlkaXMgKEJkKSAoQmVlYmVlLCAyMDA1KS4gICBCZCBpcyBhIGdlbmVyYWxpc3QgcGFyYXNpdGUgdGhhdCBoYXMgYmVlbiBmb3VuZCBpbiBvdmVyIDUwMCBzcGVjaWVzIG9mIGFtcGhpYmlhbiwgYW5kIGhhcyBiZWVuIGhpZ2hseSBwcm9saWZlcmF0aXZlLCBmb3VuZCBpbiA0OCUgb2YgbG9jYXRpb25zIHN1cnZleWVkIChKYW1lcywgMjAxNSkuIFRoZSBmaXJzdCByZWNvcmRlZCBjYXNlIGluIE5vcnRoIEFtZXJpY2Egd2FzIGluIDE5NjEgYW5kLCB0aG91Z2h0IHRvIGJlIGNhcnJpZWQgYnkgdGhlIGZyb2cgWC4gbGFldmlzKFdlbGRvbiwgMjAwNCkuIA0KDQojUXVlc3Rpb24gYW5kIFByb2JsZW0NClRoaXMgcHJvamVjdCB3b3VsZCBleHBsb3JlIHRoZSBwcm9wb3NlZCBvcmlnaW4sIHRpbWVsaW5lLCBhbmQgcGF0aCBvZiBpbmZlY3Rpb24gb2YgQmQgaW4gdGhlIFVTIHZpYSBtYXAgdmlzdWFsaXphdGlvbnMgb2YgdGhlIHByb2dyZXNzIG9mIHRoZSBkaXNlYXNlLiANCi0gRG9lcyB0aGUgc2FtcGxpbmcgZGF0YSBjb2luY2lkZSB3aXRoIHRoZSBwcm9wb3NlZCBvcmlnaW4gb2YgQmQ/IChNYWluZSBpbiB0aGUgZWFybHkgMTk2MHMpIA0KLSBXaGF0IEFtcGhpYmlhbiBmYW1pbGllcyBhbmQgc3BlY2llcyBhcmUgdGhlIG1vc3QgYWZmZWN0ZWQgYnkgdGhlIGRpc2Vhc2U/DQotIFdoaWNoIGFyZWFzIGhhdmUgdGhlIGhpZ2hlc3Qgc2FtcGxpbmc/IFdoaWNoIGFyZWFzIGhhdmUgdGhlIGhpZ2hlc3QgcmF0ZXMgb2YgQmQ/IA0KLSBJcyB0aGVyZSBhIHBhdHRlcm4gYmV0d2VlbiBzYW1wbGluZyBhbmQgQmQgb2NjdXJyZW5jZT8NCg0KI0xvY2Fpb24gYW5kIEdyYWluDQpUaGlzIGFuYWx5c2lzIHdpbGwgZm9jdXMgcmVnaW9uYWxseSBvbiB0aGUgVVMgb3ZlciBhIHRpbWUgc2NhbGUgb2YgdGhlIGludHJvZHVjdGlvbiBvZiBCZCBpbiB0byB0aGUgVVMgaW4gdGhlIDE5NjAncyB0byBwcmVzZW50IGRheSB1c2luZyBzdGF0ZXMgYXMgdGhlIGdyYWluIChjb29yZGluYXRlcyB3ZXJlIG5vdCBpbmNsdWRlZCBpbiBkYXRhIGFuZCBzb21lIG9mIHRoZSBsb2NhdGlvbiBkYXRhIHdhcyB2YWd1ZSkuIA0KDQojTWV0aG9kDQojI0RhdGENCkRhdGEgd2FzIGRvd25sb2FkZWQgZnJvbSBCZC1tYXBzLm5ldCwgYSBkYXRhYmFzZSBkZWRpY2F0ZWQgdG8gZG9jdW1lbnRpbmcgY2FzZXMgQmQgaW4gYW1waGliaWFucyBhcm91bmQgdGhlIGdsb2JlLiBEYXRhIHdhcyBhdmFpbGFibGUgZm9yIDQ1IG91dCBvZiA1MCBzdGF0ZXMgKG5vdCBkYXRhIGZvciBDVCwgREUsIE5ELCBSSSBhbmQgU0QpLg0KDQoNCiMjU2V0IHVwIHdvcmtzcGFjZSBhbmQgTG9hZCBEYXRhDQojIyNTZXQgVXANCkxvYWQgTGlicmF5cyBhbmQgU2V0IFdvcmtpbmcgRGlyZWNvdHJ5DQpgYGB7ciAic2V0dXAifQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KGZpZnR5c3RhdGVyKQ0KbGlicmFyeShtYXBwcm9qKQ0KbGlicmFyeShjb2xvclJhbXBzKQ0KcmVxdWlyZSgia25pdHIiKQ0KDQojb3B0c19rbml0JHNldChyb290LmRpciA9ICIvVXNlcnMvbGFodXVraS9EZXNrdG9wL0JkIikjbWFjDQpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gIkM6XFxVc2Vyc1xcdHVmNDg2NDlcXERlc2t0b3BcXEJkXzIiKSN3aW5kb3dzDQpgYGANCg0KIyMjQnVpbGQgU3RhdGUgRGF0YQ0KVG8gZWRpdCB0aGUgZGF0YToNCi0gcmVtb3ZlIHJlY29yZCAobWV0YWRhdGEpDQotIHNwZWNpZmljIGxvY2F0aW9uIGRhdGEgd2FzIHNpbXBsaWZpZWQgdG8gc3RhdGUgYXMgY29vZGluYXRlcyB3ZXJlIG5vdCBpbmNsdWRlZCBpbiB0aGUgZG93bmxvYWRlZCBkYXRhDQotIGRhdGVzIHdlcmUgY29ycmVjdGx5IGZvcm1hdHRlZA0KLSBmaXhlZCBOby4gdGVzdGVkIChpdCBhbHdheXMgaXMgMSwgc2hvdWxkIGJlIHN1bSBvZiB2ZSsgYW5kIHZlLSkNCi0gcmVtb3ZlIGxpZmUgc3RhZ2UgYXMgdGhlIGRhdGEgaXMgbW9zdGx5IG1pc3NpbmcNCi0gcmVtb3ZlIG1ldGhvZCBhcyBpdCBpcyBub3QgbmVlZGVkIGZvciB0aGlzIGFuYWx5c2lzDQoNCmBgYHtyICJCdWlsZCBTdGF0ZSBEYXRhIiwgd2FybmluZ3MgPSBGQUxTRX0NCiNidWlsZCB0aWJibGUgdG8gaXR0ZXJhdGUgdHJvdWdoIGRhdGENCm5vX2RhdGFfc3RhdGVzPC0gYygiREUiLCJORCIsIlJJIiwiU0QiLCJDVCIpDQpzdGF0ZXMgPC0gcmVhZF9jc3YoInN0YXRlcy5jc3YiKSAlPiUgI2xpc3Qgb2Ygc3RhdGUgYWJydmlhdGlvbnMgd2l0aG91dCBzdGF0ZXMgd2l0aCBubyBkYXRhIHVzZWQgdG8gaXRlcmF0ZSB0aHJvdWdoIGRhdGENCiAgZmlsdGVyKCFBYmJyZXZpYXRpb24gJWluJSBub19kYXRhX3N0YXRlcykgJT4lIA0KICByZW5hbWUoQUIgPSBBYmJyZXZpYXRpb24pICU+JQ0KICBtdXRhdGUoZmlsZSA9IHBhc3RlKCJCZF9zdGF0ZV9kYXRhLyIsQUIgLCIudHh0Iiwgc2VwID0gIiIpLA0KICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBwYXN0ZShBQiwiX2RhdGEiLHNlcCA9IiIpLA0KICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gdG9sb3dlcihTdGF0ZSkpICU+JQ0KICBzZWxlY3QoLVN0YXRlKQ0KICANCg0KDQojcmVhZCBkYXRhIGZpbGVzDQpmb3IoaSBpbiAxOmxlbmd0aChzdGF0ZXMkQUIpKXsNCiAgYXNzaWduKHN0YXRlcyRkYXRhW2ldLHJlYWRfY3N2KHN0YXRlcyRmaWxlW2ldKSkNCn0NCg0KI2Z1bmN0aW9uIHRvIGNvcnJlY3QgZGF0YSBmaWxlcywgZmlsdGVyIG91dCB1bnVzZWQgZGF0YSwgZml4IE5PLiBUZXN0ZWQNCg0KY29ycmVjdF9zdGF0ZV9kYXRhIDwtIGZ1bmN0aW9uKHN0YXRlKXsNCiAgZGF0YSA8LSBldmFsKGFzLm5hbWUoc3RhdGUkZGF0YSkpDQogIGRhdGEgJT4lIG11dGF0ZShzdGF0ZSA9IHN0YXRlJHN0YXRlLCANCiAgICAgICAgICAgICAgICAgIFRlc3RlZCA9IChgK3ZlYCtgLXZlYCksDQogICAgICAgICAgICAgICAgICBQcm9wX3BvcyA9IChgK3ZlYC9UZXN0ZWQpLA0KICAgICAgICAgICAgICAgICAgWWVhciA9IHllYXIoZG15KFllYXIpKSkgJT4lIA0KICBzZWxlY3Qoc3RhdGUsIFllYXIsIGBUYXhhIEdyb3VwYCwgVGF4b24sIFNwZWNpZXMsIEhpc3RvcnksVGVzdGVkLFByb3BfcG9zLGArdmVgLCBgLXZlYCwgYElVQ04gU3RhdHVzYCkgJT4lDQogICAgcmVuYW1lKE9yZGVyID0gYFRheGEgR3JvdXBgLCBGYW1pbHkgPSBUYXhvbikNCn0NCg0KZm9yKGkgaW4gMTpsZW5ndGgoc3RhdGVzJEFCKSl7DQogICNwcmludChzdGF0ZXMkQUJbaV0pDQogIGFzc2lnbihzdGF0ZXMkZGF0YVtpXSxjb3JyZWN0X3N0YXRlX2RhdGEoc3RhdGVzW2ksXSkpDQp9DQoNCkFsbF9kYXRhIDwtIGZpbHRlcihBTF9kYXRhLCBPcmRlciA9PSAiY2FudCBlcXVhbCB0aGlzIikgI2RlZmluZSBBbGxfZGF0YSBmb3IgbWVyZ2luZw0KDQpmb3IoaSBpbiAxOmxlbmd0aChzdGF0ZXMkQUIpKXsNCiAgI3ByaW50KGkpDQogIEFsbF9kYXRhIDwtIG1lcmdlKEFsbF9kYXRhLCBldmFsKGFzLm5hbWUoc3RhdGVzJGRhdGFbaV0pKSwgYWxsLnggPSBULCBhbGwueSA9IFQpDQp9DQoNCkFsbF9kYXRhIDwtIGFzLnRpYmJsZShBbGxfZGF0YSkgI2NvbnZlcnQgYmFjayB0byB0aWJibGUNCmBgYA0KDQojI1ByZWxpbWluYXJ5IERhdGEgRXhwbG9yYXRpb24NCiMjI1N1bW1hcnkNCi0gMTgxMiByZWNvcmRzIGZyb20gMTk2NSB0byAyMDEwDQotIFR3byBPcmRlcnM6IEFudXJhIChmcm9ncyBhbmQgdG9hZHMpIGFuZCBDYXVkYXRhIChzYWxhbWFuZGVycyksIG5vIEd5bW5vcGhpb25hDQotIDE0IEZhbWlseXMNCi0gMTUyIHNwZWNpZXMNCg0KYGBge3J9DQojRXhwbG9yZSB0aGUgZGF0YQ0KcmFuZ2UoQWxsX2RhdGEkWWVhcikjZmluZCByYW5nZSBvZiBkYXRlcw0KI2Z1bmN0aW9uIHRvIGNvdW50IHVuaXF1ZSB2YWx1ZXMgDQpjb3VudF91bmlxdWUgPC0gZnVuY3Rpb24odmFyKXsNCiAgcHJpbnQoZGVwYXJzZShzdWJzdGl0dXRlKHZhcikpKQ0KICBsZW5ndGgodW5pcXVlKHZhcikpDQp9DQoNCmNvdW50X3VuaXF1ZShBbGxfZGF0YSRPcmRlcikNCmNvdW50X3VuaXF1ZShBbGxfZGF0YSRGYW1pbHkpDQpjb3VudF91bmlxdWUoQWxsX2RhdGEkU3BlY2llcykNCmBgYA0KIyMjRGlzdGlidXRpb24gb2YgU2FtcGxpbmcgT3ZlciB0aW1lDQpUaGUgZGF0YSBpcyBub3QgZXZlbmx5IHNhbXBsZWQgb3ZlciB0aGUgeWVhcnMsd2l0aCBsZXNzIHRoYW4gMTAwIHRlc3QgcGVyIHllYXIgdW50aWxsIDIwMDAgc3Bpa2luZyBpbiAyMDA2LiBUaGlzIG1ha2VzIHNlbnNlIGFzIEJkIHdhcyBvbmx5IGRpc2NvdmVyZWQgaW4gMTk5OCwgYW5kIG1vc3Qgb2YgdGhlIGVhcmxpZXIgc2FtcGxlcyBhcmUgZnJvbSBtdXNldW0gY29sbGVjdGlvbnMuIFRoaXMgZGF0YSBjb2xsZWN0aW9uIGFsc28gdHJhaWxzIG9mZiBpbiAyMDEwIHNvIGRvZXMgbm90IHByb3ZpZGUgaW5mb21hdGlvbiBhYm91dCB0aGUgbGFzdCA4IHllYXJzIG9mIHRoZSBkaXNlYXNlLiBUaGUgd2lsZCBkaWZmcmVuY2VzIGluIHNhbXBsaW5nIG51bWJlcnMgYWxzbyB0aHJvdyBvZmYgdGhlIHByb3BvcnRpb24gb2YgcG9zaXRpdmUgcmVzdWx0cyBvdXQgb2YgYWxsIHNhbXBsZXMsIG5vIGNsZWFyIHRyZW5kIGNhbiBiZSBvYnNlcnZlZC4NCmBgYHtyfQ0KI3NhbXBsaW5nIG92ZXIgdGltZQ0Kc2FtcGxlc19ieV95ZWFyIDwtIEFsbF9kYXRhICU+JWdyb3VwX2J5KFllYXIpICU+JQ0KICBzdW1tYXJpc2UodG90YWxfdGVzdGVkID0gc3VtKFRlc3RlZCksDQogICAgICAgICAgICAgICAgdG90YWxfcG9zID0gc3VtKGArdmVgKSwNCiAgICAgICAgICAgICAgICB0b3RhbF9uZWcgPSBzdW0oYC12ZWApLA0KICAgICAgICAgICAgICAgIGF2ZV9wcm9wID0gbWVhbihQcm9wX3BvcykpDQojc2FtcGxlcyBvdmVyIHRpbWUNCmdncGxvdChkYXRhID0gc2FtcGxlc19ieV95ZWFyLGFlcyh4ID0gWWVhcikpICsNCiAgZ2VvbV9saW5lKGFlcyggeSA9IHRvdGFsX3Rlc3RlZCxjb2xvciA9ICJUb3RhbCIpKSArDQogIGdlb21fbGluZShhZXMoIHkgPSB0b3RhbF9wb3MsY29sb3IgPSAiUG9zaXRpdmUgVGVzdCIpKSsgYW5ub3RhdGUoInRleHQiLCB4ID0gMTk5OCwgeSA9IDE1MDAsIGxhYmVsID0gIkRpc2NvdmVyZWQiKSArIGFubm90YXRlKCJzZWdtZW50IiwgeCA9IDE5OTgsIHhlbmQgPSAxOTk4LCB5ID0gMCwgeWVuZCA9IDMwMDAsIGNvbG9yID0gInJlZCIpDQoNCiNwcm9wb3J0aW9uIG9mIHBvc2l0aXZlIHJlc3VsdHMgb3ZlciB0aW1lDQpnZ3Bsb3QoZGF0YSA9IHNhbXBsZXNfYnlfeWVhcikrZ2VvbV9wb2ludChhZXMoeCA9IFllYXIsIHkgPSBhdmVfcHJvcCwgY29sb3IgPSB0b3RhbF90ZXN0ZWQpLCBzaXplID0gMi41KStzY2FsZV9jb2xvcl9ncmFkaWVudChsb3c9ImJsdWUiLCBoaWdoPSJyZWQiKSArIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDE5OTgsIHkgPSAwLjUsIGxhYmVsID0gIkRpc2NvdmVyZWQiKSArIGFubm90YXRlKCJzZWdtZW50IiwgeCA9IDE5OTgsIHhlbmQgPSAxOTk4LCB5ID0gMCwgeWVuZCA9IDEsIGNvbG9yID0gInJlZCIpDQpgYGANCiMjI0Rpc3RpYnV0aW9uIG9mIFNhbXBsaW5nIE92ZXIgU3BlY2llcw0KSVVDTiBkYXRhIGlzIG5vdCBjb25zaXN0YW50IHdpdGggc3BlY2llcyBuYW1lLiBEaXN0cmlidXRpb24gb2Ygc2FtcGxpbmcgbWFrZXMgc2Vuc2UsIGZhdm9yaW5nIG1vcmUgYWJ1bWRhbnQgc3BlY2llcy4NCmBgYHtyfQ0KDQojZGlzdGlidXRpb24gb2Ygc2FtcGxpbmcgb3ZlciBmYW1pbHlzDQpBbGxfZGF0YSAlPiVncm91cF9ieShPcmRlcixGYW1pbHkpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX3Rlc3RlZCA9IHN1bShUZXN0ZWQpLA0KICAgICAgICAgICAgICAgIHRvdGFsX3BvcyA9IHN1bShgK3ZlYCksDQogICAgICAgICAgICAgICAgdG90YWxfbmVnID0gc3VtKGAtdmVgKSwNCiAgICAgICAgICAgICAgICBhdmVfcHJvcCA9IG1lYW4oUHJvcF9wb3MpKSU+JQ0KICBnZ3Bsb3QoKSArIGdlb21fYmFyKGFlcyh4PSByZW9yZGVyKEZhbWlseSwgdG90YWxfdGVzdGVkKSwgeSA9dG90YWxfdGVzdGVkLCBmaWxsID0gT3JkZXIpLHN0YXQgPSAiaWRlbnRpdHkiKSArY29vcmRfZmxpcCgpDQoNCiNkaXN0aWJ1dGlvbiBvZiBzYW1wbGluZyBvdmVyIHNwZWNpZXMgDQpBbGxfZGF0YSAlPiVncm91cF9ieShPcmRlcixGYW1pbHksIFNwZWNpZXMpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX3Rlc3RlZCA9IHN1bShUZXN0ZWQpLA0KICAgICAgICAgICAgICAgIHRvdGFsX3BvcyA9IHN1bShgK3ZlYCksDQogICAgICAgICAgICAgICAgdG90YWxfbmVnID0gc3VtKGAtdmVgKSwNCiAgICAgICAgICAgICAgICBhdmVfcHJvcCA9IG1lYW4oUHJvcF9wb3MpKSU+JQ0KICBmaWx0ZXIodG90YWxfdGVzdGVkID41MCkgJT4lDQogIGdncGxvdCgpICsgZ2VvbV9iYXIoYWVzKHg9IHJlb3JkZXIoU3BlY2llcywgdG90YWxfdGVzdGVkKSwgeSA9dG90YWxfdGVzdGVkLCBmaWxsID0gRmFtaWx5KSxzdGF0ID0gImlkZW50aXR5IikgK2Nvb3JkX2ZsaXAoKQ0KDQoNCiNkaXN0aWJ1dGlvbiBvZiBzYW1wbGluZyBvdmVyIElVQ04gc3RhdHVzDQpBbGxfZGF0YSAlPiVncm91cF9ieShgSVVDTiBTdGF0dXNgLCBuYS5ybSA9IFQpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX3Rlc3RlZCA9IHN1bShUZXN0ZWQpLA0KICAgICAgICAgICAgICAgIHRvdGFsX3BvcyA9IHN1bShgK3ZlYCksDQogICAgICAgICAgICAgICAgdG90YWxfbmVnID0gc3VtKGAtdmVgKSwNCiAgICAgICAgICAgICAgICBhdmVfcHJvcCA9IG1lYW4oUHJvcF9wb3MpKSU+JQ0KICBmaWx0ZXIodG90YWxfdGVzdGVkID41MCkgJT4lDQogIGdncGxvdCgpICsgZ2VvbV9iYXIoYWVzKHg9IHJlb3JkZXIoYElVQ04gU3RhdHVzYCwgdG90YWxfdGVzdGVkKSwgeSA9dG90YWxfdGVzdGVkLCBmaWxsID0gYElVQ04gU3RhdHVzYCksc3RhdCA9ICJpZGVudGl0eSIpKyBjb29yZF9mbGlwKCkNCg0KYGBgDQojRGlzdHJpYnV0aW9uIG9mIFNhbXBsaW5nIG92ZXIgU3RhdGVzDQpNb3N0IHN0YXRlcyBoYXZlIGxpbWl0ZWQgc2FtcGxpbmcsIG1vc3QgZGF0YSBpcyBmcm9tIHRoZSBXZXN0LWNvYXN0Lg0KYGBge3J9DQpieV9zdGF0ZSA8LSBBbGxfZGF0YSAlPiUgZ3JvdXBfYnkoc3RhdGUpICU+JSBzdW1tYXJpc2UodG90YWxfdGVzdGVkID0gc3VtKFRlc3RlZCksDQogICAgICAgICAgICAgICAgdG90YWxfcG9zID0gc3VtKGArdmVgKSwNCiAgICAgICAgICAgICAgICB0b3RhbF9uZWcgPSBzdW0oYC12ZWApLA0KICAgICAgICAgICAgICAgIGF2ZV9wcm9wID0gbWVhbihQcm9wX3BvcykpDQoNCnBsb3RfVVNBIDwtIGZ1bmN0aW9uKGRhdGEsIGZpbGwpew0KICBnZ3Bsb3QoZGF0YSwgYWVzKG1hcF9pZCA9IHN0YXRlKSkgKyANCiAgIyBtYXAgcG9pbnRzIHRvIHRoZSBmaWZ0eV9zdGF0ZXMgc2hhcGUgZGF0YQ0KICBnZW9tX21hcChhZXMoZmlsbCA9IGZpbGwpLCBtYXAgPSBmaWZ0eV9zdGF0ZXMpICsgDQogIGV4cGFuZF9saW1pdHMoeCA9IGZpZnR5X3N0YXRlcyRsb25nLCB5ID0gZmlmdHlfc3RhdGVzJGxhdCkgKw0KICBjb29yZF9tYXAoKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gTlVMTCkgKyANCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IE5VTEwpICsNCiAgbGFicyh4ID0gIiIsIHkgPSAiIikgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvdXJzID0gIHJhaW5ib3coNywgcyA9MC41KSkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLCANCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkNCn0NCg0KcGxvdF9VU0EoYnlfc3RhdGUsIGJ5X3N0YXRlJHRvdGFsX3BvcykNCg0KDQpgYGANCg0KI1NwZWNpZXMgQW5hbHlzaXMNCiMjV2hhdCBTcGVjaWVzIGhhcyB0aGUgbW9zdCBwb3NpdGl2ZSB0ZXN0Pw0KQnVmbyBib3JlYXMgKFdlc3Rlcm4gVG9hZCksIHRoZSBtb3N0IGhpZ2h0bHkgc2FtcGxlZCBzcGVjaWVzLiBBZGp1c3QgZm9yIHNhbXBsaW5nIGJpYXMgYnkgbG9va2luZyBhdCB0aGUgcHJvcG9ydGlvbnMgb2YgcG9zaXRpdmUgdGVzdCByZXN1bHRzLiANCmBgYHtyfQ0KYnlfc3BlY2llcyA8LSBBbGxfZGF0YSAlPiVncm91cF9ieShTcGVjaWVzLGBJVUNOIFN0YXR1c2AgKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF90ZXN0ZWQgPSBzdW0oVGVzdGVkKSwNCiAgICAgICAgICAgICAgICB0b3RhbF9wb3MgPSBzdW0oYCt2ZWApLA0KICAgICAgICAgICAgICAgIHRvdGFsX25lZyA9IHN1bShgLXZlYCksDQogICAgICAgICAgICAgICAgYXZlX3Byb3AgPSBtZWFuKFByb3BfcG9zKSkNCg0KYnlfc3BlY2llcyAlPiUgZmlsdGVyKHRvdGFsX3BvcyA+MTApICU+JQ0KICBnZ3Bsb3QoKSArIGdlb21fYmFyKGFlcyh4PSByZW9yZGVyKFNwZWNpZXMsIHRvdGFsX3BvcyksIHkgPXRvdGFsX3BvcywgZmlsbCA9IGBJVUNOIFN0YXR1c2ApLHN0YXQgPSAiaWRlbnRpdHkiKSsgY29vcmRfZmxpcCgpK2xhYnMoeCA9ICJTcGVjaWVzIiwgeSA9ICJQb3NpdGl2ZSBUZXN0cyIpDQoNCmBgYA0KIyNXaGF0IFNwZWNpZXMgaGFzIHRoZSBoaWdoZXN0IHByb3BvcnRpb24gb2YgcG9zaXRpdmUgdGVzdD8NClJhbmEgc2llcnJhZSAoc2llcnJhIG5ldmFkYSB5ZWxsb3ctbGVnZ2VkIGZyb2cpIGFuIGVuZGFuZ2VyZWQgZnJvZyBuYXRpdmUgdG8gdGhlIFNpZXJyYSBOZXZhZGFzLiBGb2xsb3dkZWQgYnkgQ3J5cHRvYnJhbmNodXMgYWxsZWdhbmllbnNpcyAoSGVsbGJlbmRlciBnaWFudCBzYWxhbWFuZGVyKSBmcm9tIHRoZSBBcHBsYWNpYSByZWdpb24gKHJlcG9ydGVkIGFzIG5lYXIgdGhyZWF0ZW5lZCBvbiBvbmxpbmUgSVVDTikuIFRoaXMgcGF0dGVybiBvZiBoaWdoIHByb3BvcnRpb24gcG9zaXRpdmUgdGVzdCBpbiBtb3JlIHRocmVhdGVuZWQgc3BlY2llcyBzdWdnZXN0IHRoYXQgQmQgaGFzIGFuIGltcGFjdCBvbiB0aGUgc3BlY2llcyBzdXJ2aXZhbC4gDQpgYGB7cn0NCmJ5X3NwZWNpZXMgJT4lIGZpbHRlcih0b3RhbF9wb3MgPjEwKSAlPiUNCiAgZ2dwbG90KCkgKyBnZW9tX2JhcihhZXMoeD0gcmVvcmRlcihTcGVjaWVzLCBhdmVfcHJvcCksIHkgPWF2ZV9wcm9wLCBmaWxsID0gYElVQ04gU3RhdHVzYCksc3RhdCA9ICJpZGVudGl0eSIpKyBjb29yZF9mbGlwKCkrbGFicyh4ID0gIlNwZWNpZXMiLCB5ID0gIlByb3BvcnRpb24gUG9zaXRpdmUiKQ0KYGBgDQojI1doYXQgRmFtaWx5IGhhcyB0aGUgbW9zdCBwb3NpdGl2ZSB0ZXN0Pw0KLXByb3BvcnRpb24gc2tlZXdkZWQgYnkgbG93IHNhbXBsaW5nIA0KYGBge3J9DQpieV9mYW1pbHkgPC0gQWxsX2RhdGEgJT4lZ3JvdXBfYnkoRmFtaWx5KSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF90ZXN0ZWQgPSBzdW0oVGVzdGVkKSwNCiAgICAgICAgICAgICAgICB0b3RhbF9wb3MgPSBzdW0oYCt2ZWApLA0KICAgICAgICAgICAgICAgIHRvdGFsX25lZyA9IHN1bShgLXZlYCksDQogICAgICAgICAgICAgICAgYXZlX3Byb3AgPSBtZWFuKFByb3BfcG9zLCBuYS5ybSA9IFQpKQ0KDQpieV9mYW1pbHkgJT4lIGZpbHRlcih0b3RhbF9wb3MgPjEwKSAlPiUNCiAgZ2dwbG90KCkgKyBnZW9tX2JhcihhZXMoeD0gcmVvcmRlcihGYW1pbHksIHRvdGFsX3BvcyksIHkgPXRvdGFsX3BvcywgZmlsbCA9IEZhbWlseSksc3RhdCA9ICJpZGVudGl0eSIpKyBjb29yZF9mbGlwKCkrbGFicyh4ID0gIkZhbWlseSIsIHkgPSAiUG9zaXRpdmUgVGVzdHMiKQ0KDQpgYGANCiNHZW9ncmFwaGljYWwgZGlzdGlidXRpb24gT3ZlciBUaW1lDQojI0FsbCBkYXRhDQpgYGB7cn0NCg0KUGxvdF9hbGxfcG9zX3Byb3AgPC0gZnVuY3Rpb24oZGF0YSl7DQogIHBsb3RfVVNBKGRhdGEsIGRhdGEkdG90YWxfdGVzdGVkKQ0KICBwbG90X1VTQShkYXRhLCBkYXRhJHRvdGFsX3BvcykNCiAgcGxvdF9VU0EoZGF0YSwgZGF0YSRhdmVfcHJvcCkNCn0NCg0KYnlfc3RhdGUgPC0gQWxsX2RhdGEgJT4lIGdyb3VwX2J5KHN0YXRlKSAlPiUNCiAgc3VtbWFyaXNlKHRvdGFsX3Rlc3RlZCA9IHN1bShUZXN0ZWQpLA0KICAgICAgICAgICAgICAgIHRvdGFsX3BvcyA9IHN1bShgK3ZlYCksDQogICAgICAgICAgICAgICAgYXZlX3Byb3AgPSBtZWFuKFByb3BfcG9zLCBuYS5ybSA9IFQpKQ0KDQpyZXF1aXJlKGNvd3Bsb3QpDQphbGxfdG90YWwgPC0gIHBsb3RfVVNBKGJ5X3N0YXRlLCBieV9zdGF0ZSR0b3RhbF90ZXN0ZWQpICsgZ2d0aXRsZSgiVG90YWwgdGVzdCIpDQphbGxfcG9zIDwtICBwbG90X1VTQShieV9zdGF0ZSwgYnlfc3RhdGUkdG90YWxfcG9zKSArIGdndGl0bGUoIlRvdGFsIFBvc2l0aXZlIikNCmFsbF9wcm9wIDwtICBwbG90X1VTQShieV9zdGF0ZSwgYnlfc3RhdGUkYXZlX3Byb3ApICsgZ2d0aXRsZSgiUHJvcCBQb3NpdGl2ZSIpDQoNCnBsb3RfZ3JpZChhbGxfdG90YWwsYWxsX3BvcyxhbGxfcHJvcCwgbnJvdz0xKQ0KDQpgYGANCiMjMTk2NS0xOTk3KHByZS1kaXNjb3ZlcnkpDQpgYGB7cn0NCnllYXI2NV85NyA8LSBBbGxfZGF0YSAlPiUgZmlsdGVyKFllYXIgPCAxOTk4KSU+JQ0KICBncm91cF9ieShzdGF0ZSkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF90ZXN0ZWQgPSBzdW0oVGVzdGVkKSwNCiAgICAgICAgICAgICAgICB0b3RhbF9wb3MgPSBzdW0oYCt2ZWApLA0KICAgICAgICAgICAgICAgIGF2ZV9wcm9wID0gbWVhbihQcm9wX3BvcywgbmEucm0gPSBUKSkNCg0KYWxsX3RvdGFsIDwtICBwbG90X1VTQSh5ZWFyNjVfOTcsIHllYXI2NV85NyR0b3RhbF90ZXN0ZWQpICsgZ2d0aXRsZSgiVG90YWwgdGVzdCIpDQphbGxfcG9zIDwtICBwbG90X1VTQSh5ZWFyNjVfOTcsIHllYXI2NV85NyR0b3RhbF9wb3MpICsgZ2d0aXRsZSgiVG90YWwgUG9zaXRpdmUiKQ0KYWxsX3Byb3AgPC0gIHBsb3RfVVNBKHllYXI2NV85NywgeWVhcjY1Xzk3JGF2ZV9wcm9wKSArIGdndGl0bGUoIlByb3AgUG9zaXRpdmUiKQ0KDQpwbG90X2dyaWQoYWxsX3RvdGFsLGFsbF9wb3MsYWxsX3Byb3AsIG5yb3c9MSkNCmBgYA0KDQojIzE5OTgtMjAwMQ0KYGBge3J9DQp5ZWFyOThfMDEgPC0gQWxsX2RhdGEgJT4lIGZpbHRlcihZZWFyID49IDE5OTggfCBZZWFyIDwyMDAyKSU+JQ0KICBncm91cF9ieShzdGF0ZSkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF90ZXN0ZWQgPSBzdW0oVGVzdGVkKSwNCiAgICAgICAgICAgICAgICB0b3RhbF9wb3MgPSBzdW0oYCt2ZWApLA0KICAgICAgICAgICAgICAgIGF2ZV9wcm9wID0gbWVhbihQcm9wX3BvcywgbmEucm0gPSBUKSkNCg0KYWxsX3RvdGFsIDwtICBwbG90X1VTQSh5ZWFyOThfMDEsIHllYXI5OF8wMSR0b3RhbF90ZXN0ZWQpICsgZ2d0aXRsZSgiVG90YWwgdGVzdCIpDQphbGxfcG9zIDwtICBwbG90X1VTQSh5ZWFyOThfMDEsIHllYXI5OF8wMSR0b3RhbF9wb3MpICsgZ2d0aXRsZSgiVG90YWwgUG9zaXRpdmUiKQ0KYWxsX3Byb3AgPC0gIHBsb3RfVVNBKHllYXI5OF8wMSwgeWVhcjk4XzAxJGF2ZV9wcm9wKSArIGdndGl0bGUoIlByb3AgUG9zaXRpdmUiKQ0KDQpwbG90X2dyaWQoYWxsX3RvdGFsLGFsbF9wb3MsYWxsX3Byb3AsIG5yb3c9MSkNCmBgYA0KIyMyMDAyLTIwMDUNCmBgYHtyfQ0KeWVhciA8LSBBbGxfZGF0YSAlPiUgZmlsdGVyKFllYXIgPj0gMjAwMiB8IFllYXIgPDIwMDYpJT4lDQogIGdyb3VwX2J5KHN0YXRlKSAlPiUNCiAgc3VtbWFyaXNlKHRvdGFsX3Rlc3RlZCA9IHN1bShUZXN0ZWQpLA0KICAgICAgICAgICAgICAgIHRvdGFsX3BvcyA9IHN1bShgK3ZlYCksDQogICAgICAgICAgICAgICAgYXZlX3Byb3AgPSBtZWFuKFByb3BfcG9zLCBuYS5ybSA9IFQpKQ0KDQphbGxfdG90YWwgPC0gIHBsb3RfVVNBKHllYXIsIHllYXIkdG90YWxfdGVzdGVkKSArIGdndGl0bGUoIlRvdGFsIHRlc3QiKQ0KYWxsX3BvcyA8LSAgcGxvdF9VU0EoeWVhciwgeWVhciR0b3RhbF9wb3MpICsgZ2d0aXRsZSgiVG90YWwgUG9zaXRpdmUiKQ0KYWxsX3Byb3AgPC0gIHBsb3RfVVNBKHllYXIsIHllYXIkYXZlX3Byb3ApICsgZ2d0aXRsZSgiUHJvcCBQb3NpdGl2ZSIpDQoNCnBsb3RfZ3JpZChhbGxfdG90YWwsYWxsX3BvcyxhbGxfcHJvcCwgbnJvdz0xKQ0KYGBgDQoNCg0KIyMyMDA2LTIwMTANCmBgYHtyLCBoaWRlID0gVH0NCnllYXIgPC0gQWxsX2RhdGEgJT4lIGZpbHRlcihZZWFyID4yMDA1KSU+JQ0KICBncm91cF9ieShzdGF0ZSkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF90ZXN0ZWQgPSBzdW0oVGVzdGVkKSwNCiAgICAgICAgICAgICAgICB0b3RhbF9wb3MgPSBzdW0oYCt2ZWApLA0KICAgICAgICAgICAgICAgIGF2ZV9wcm9wID0gbWVhbihQcm9wX3BvcywgbmEucm0gPSBUKSkNCg0KYWxsX3RvdGFsIDwtICBwbG90X1VTQSh5ZWFyLCB5ZWFyJHRvdGFsX3Rlc3RlZCkgKyBnZ3RpdGxlKCJUb3RhbCB0ZXN0IikNCmFsbF9wb3MgPC0gIHBsb3RfVVNBKHllYXIsIHllYXIkdG90YWxfcG9zKSArIGdndGl0bGUoIlRvdGFsIFBvc2l0aXZlIikNCmFsbF9wcm9wIDwtICBwbG90X1VTQSh5ZWFyLCB5ZWFyJGF2ZV9wcm9wKSArIGdndGl0bGUoIlByb3AgUG9zaXRpdmUiKQ0KDQpwbG90X2dyaWQoYWxsX3RvdGFsLGFsbF9wb3MsYWxsX3Byb3AsIG5yb3c9MSkNCmBgYA0KI0NvbmNsdXNpb24NClRoaXMgZGF0YSBwcm92ZWQgdG8gYmUgdmVyeSBtZXNzeS4gVGhlIHNhbXBsaW5nIHdhcyB2ZXJ5IGluY29uc2lzdGVudCBvdmVyIHRpbWUgYW5kIGJldHdlZW4gc3RhdGVzLiBUaGUgZGF0YSBzaG93ZWQgdGhhdCBtYW55IGZyb2dzIHRoYXQgaGF2ZSBoaWdoIHJhdGVzIG9mIHNhbXBsZWQgQmQgYXJlIHRocmVhdGVuZWQuIEJldHdlZW4gc3RhdGVzIG92ZXIgdGltZSwgdGhlIGluZmVjdGlvbiBzZWVtcyB0byBtb3ZlIGZyb20gdGhlIE5vcnRoIEVhc3QgdG8gdGhlIHdlc3QgY29hc3QgaXQgaXMgaGFyZCB0byBzZWUgYSBwYXR0ZXJuIG9mIEJkIHNwcmVhZGluZyBhY3Jvc3MgdGhlIGNvdW50cnkuIFRoaXMgZGF0YSBpcyB0b3AgaW5jb25zaXN0ZW50IHRvIGRyYXcgYW55IG9mIHRoZSBzb2xpZCBjb25jbHVzaW9uLiBJbiBhbiBlZmZvcnQgdG8gY29udHJvbCwgdGhlIGltcGFjdCBvZiBCZCBiZXR0ZXIgc2FtcGxpbmcgYW5kIGRvY3VtZW50YXRpb24gbmVlZHMgdG8gaW1wbGVtZW50Lg0KDQojUmVmcmVuY2VzDQpBYW5lbnNlbiwgRC4gTS4sIGFuZCBNLiBGaXNoZXIuICJCZC1NYXBzLiB3d3cuIGJkLW1hcHMuIG5ldC4iICgyMDEyKS4NCg0KQmVlYmVlLCBULiBKLiAoMjAwNSkuIFRoZSBhbXBoaWJpYW4gZGVjbGluZSBjcmlzaXM6IGEgd2F0ZXJzaGVkIGZvciBjb25zZXJ2YXRpb24gYmlvbG9neT8gQmlvbG9naWNhbCBDb25zZXJ2YXRpb24sIDEyNSgzKSwgMjcxLTI4NS4NCg0KQmVyZ2VyLCBMLiBhLiAoMjAwNSkuIExpZmUgY3ljbGUgc3RhZ2VzIG9mIHRoZSBhbXBoaWJpYW4gY2h5dHJpZCBCYXRyYWNob2NoeXRyaXVtIGRlbmRyb2JhdGlkaXMuIERpc2Vhc2VzIG9mIGFxdWF0aWMgb3JnYW5pc21zLCA2OCwgNTEgLSA2My4NCg0KSmFtZXMsIFQuIFkuLVIuICgyMDE1KS4gRGlzZW50YW5nbGluZyBob3N0LCBwYXRob2dlbiwgYW5kIGVudmlyb25tZW50YWwgZGV0ZXJtaW5hbnRzIG9mIGEgcmVjZW50bHkgZW1lcmdlZCB3aWxkbGlmZSBkaXNlYXNlOiBsZXNzb25zIGZyb20gdGhlIGZpcnN0IDE1IHllYXJzIG9mIGFtcGhpYmlhbiBjaHl0cmlkaW9teWNvc2lzIHJlc2VhcmNoLiBFY29sb2d5IGFuZCBFdm9sdXRpb24uDQoNCldlbGRvbiwgQy4gYS4gKDIwMDQpLiBPcmlnaW4gb2YgdGhlIGFtcGhpYmlhbiBjaHl0cmlkIGZ1bmd1cy4gRW1lcmdpbmcgaW5mZWN0aW91cyBkaXNlYXNlcywgMTAsIDIxMDAuDQoNCg==