library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.3.3     ✓ purrr   0.3.4
## ✓ tibble  3.0.6     ✓ dplyr   1.0.4
## ✓ tidyr   1.1.2     ✓ stringr 1.4.0
## ✓ readr   1.4.0     ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(openintro)
## Loading required package: airports
## Loading required package: cherryblossom
## Loading required package: usdata
library(ggplot2)
library(patchwork)

Exercise 1 Make a plot (or plots) to visualize the distributions of the amount of calories from fat of the options from these two restaurants. How do their centers, shapes, and spreads compare?

fastfood <-fastfood
head(fastfood)
## # A tibble: 6 x 17
##   restaurant item  calories cal_fat total_fat sat_fat trans_fat cholesterol
##   <chr>      <chr>    <dbl>   <dbl>     <dbl>   <dbl>     <dbl>       <dbl>
## 1 Mcdonalds  Arti…      380      60         7       2       0            95
## 2 Mcdonalds  Sing…      840     410        45      17       1.5         130
## 3 Mcdonalds  Doub…     1130     600        67      27       3           220
## 4 Mcdonalds  Gril…      750     280        31      10       0.5         155
## 5 Mcdonalds  Cris…      920     410        45      12       0.5         120
## 6 Mcdonalds  Big …      540     250        28      10       1            80
## # … with 9 more variables: sodium <dbl>, total_carb <dbl>, fiber <dbl>,
## #   sugar <dbl>, protein <dbl>, vit_a <dbl>, vit_c <dbl>, calcium <dbl>,
## #   salad <chr>

#this filters the dataset into Mcdonalds and Dairy queen

mcdonalds <- fastfood %>%
filter(restaurant == "Mcdonalds")
dairy_queen <- fastfood %>%
filter(restaurant == "Dairy Queen")

#calculate 5 number summary for mcdonalds and dairy_queen cal_fat

mcsummary <- summary(mcdonalds$cal_fat)
dqsummary <- summary(dairy_queen$cal_fat)
print(mcsummary)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    50.0   160.0   240.0   285.6   320.0  1270.0
print(dqsummary)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     0.0   160.0   220.0   260.5   310.0   670.0

#calculate the means and sd for mcdonalds and dairy_queen fat content

mcmean <- mean(mcdonalds$cal_fat)
mcsd <- sd(mcdonalds$cal_fat)
print(mcmean)
## [1] 285.614
print(mcsd)
## [1] 220.8993
dqmean <- mean(dairy_queen$cal_fat)
dqsd <- sd(dairy_queen$cal_fat)
print(dqmean)
## [1] 260.4762
print(dqsd)
## [1] 156.4851

#generate boxplots for mcdonalds and dairy_queen fat_cal data

mcboxplot <-ggplot(mcdonalds, aes(x=cal_fat)) + 
  geom_boxplot() +ggtitle("distribution fat calories mcdonalds") + 
  geom_vline(xintercept=mcmean, col = "red", lwd = 2)
dqboxplot <-ggplot(dairy_queen, aes(x=cal_fat)) + 
  geom_boxplot() +ggtitle("distribution fat calories dairy_queen") +
  geom_vline(xintercept=dqmean, col = "red", lwd= 2)

#generate histogram dairy_queen fat_cal

dqhistogram <-ggplot(data = dairy_queen, aes(x = cal_fat)) +  
geom_blank() + 
geom_histogram(bins = 10, aes(y = ..density..)) +
stat_function(fun = dnorm, args = c(mean = dqmean, sd = dqsd), col = "tomato") +ggtitle("distribution fat calories dairy_queen") + geom_vline(xintercept=dqmean, col = "red")

#generate histogram mcdonalds fat_cal

mchistogram <-ggplot(data = mcdonalds, aes(x = cal_fat)) +
geom_blank() +
geom_histogram(bins = 10, aes(y = ..density..)) + 
stat_function(fun = dnorm, args = c(mean = mcmean, sd = mcsd), col = "tomato") +ggtitle("distribution of calories fat mcdonalds") + geom_vline(xintercept=mcmean, col = "red")
mcboxplot+dqboxplot

mchistogram + dqhistogram

###Answer Exercise 1 - how do their centers, shapes, and spreads compare? Comparing the boxplots and histograms for cal_fat dairy_queen and mcdonalds, we note the following trends: #both datasets have several outliers noted on the boxplots #the mean fat calories appear greater in the mcdonalds data vs the dairy queen data #the spread of the data for fat calories appears wider for mcdonalds vs the dairy queen data #both datasets are skewed to the right which may represent the effect of the outliers noted in the boxplots

Exercise 2 Based on the this plot, does it appear that the data follow a nearly normal distribution?

#construct a Q-Q plot or normal probability plot for both data sets

mcQQ <-ggplot(data = mcdonalds, aes(sample = cal_fat)) +
geom_line(stat = "qq") +  stat_qq()+stat_qq_line() +
ggtitle("normal prob plot fat-cal mcdonalds")
dqQQ <-ggplot(data = dairy_queen, aes(sample = cal_fat)) +
geom_line(stat = "qq") + stat_qq()+stat_qq_line() +
ggtitle("normal prob plot fat-cal dairy_queen")
 mcQQ + dqQQ

#Answer Exercise 2 - the above normal prob plots do not suggest that data sets are normally distributed. Rather they confirm the skew noted in the histogram plots from exercise 1

Exercise 3 Make a normal probability plot of sim_norm . Do all of the points fall on the line? How does this plot compare to the probability plot for the real data?

#(Since sim_norm is not a dataframe, it can be put directly into the sample argument and the data argument can be dropped.)

#now generate simulated normal distribution of dairy_queen

dqsim_norm <- rnorm(n = nrow(dairy_queen), mean = dqmean, sd = dqsd)

#now generate a normal probability plot for the dqsim_norm data

qqnormsim(sample = cal_fat, data = dairy_queen)

### Exercise 4 Does the normal probability plot for the calories from fat look similar to the plots created for the simulated data? That is, do the plots provide evidence that dairy_queen cal-fat data are nearly normal?

#ANS EX 4 The normal probability plots for fat_cal dairy_queen do not look similar to the normal probability plots from dqsim_norm data. The dqsim-norm probabilty plots appear normally distributed.

Exercise 5 Using the same technique, determine whether or not the calories from McDonald’s menu appear to come from a normal distribution.

#generate a simulated normal distribution from mcdonalds

mcsim_norm <- rnorm(n = nrow(mcdonalds), mean = dqmean, sd = dqsd)

#generate a normal probabilty plot for mcsim_norm

qqnormsim(sample = cal_fat, data = mcdonalds)

# Answer Exercise 5 - similar to exercise 4 , the fat_cal mcdonalds normal probability plots and the simulated mcsim_norm plots are dissimiliar.

#normal probabilities # calculate theoretical area under curve for dairy_queen fat_cal data Pr{y>600}

(1 - pnorm(q = 600, mean = dqmean, sd = dqsd))*100
## [1] 1.501523

#calculate empiric probability for actual data

dairy_queen %>%
filter(cal_fat > 600) %>%
summarise(percent = n() / nrow(dairy_queen))
## # A tibble: 1 x 1
##   percent
##     <dbl>
## 1  0.0476

Exercise 6 Write out two probability questions that you would like to answer about any of the restaurants in this dataset. Calculate those probabilities using both the theoretical normal distribution as well as the empirical distribution (four probabilities in all). Which one had a closer agreement between the two methods?

#what is theoretical probability for dairy_queen cal_fat dataset Pr(Y<600)

(pnorm(600,260.47,156.485))*100
## [1] 98.49863

#interpretation: for sample drawn randomly from the dairy_queen cal_fat dataset, there is a 98.4% chance that it is less than 600 calories

#what is the empiric probability for Pr{Y<600}

dairy_queen %>%
filter(cal_fat < 600) %>%
summarise(percent = n() / nrow(dairy_queen))
## # A tibble: 1 x 1
##   percent
##     <dbl>
## 1   0.952

#interpretation: 95.2% of data in dairy_queen cal_fat dataset are < 600 calories

#what is theoretical probability for mcdonalds cal_fat dataset Pr(Y<600)

(pnorm(600,mcmean,mcsd))*100
## [1] 92.26623

#interpretation: for sample drawn randomly from the dairy_queen cal_fat dataset, there is a 92.2% chance that it is less than 600 calories

#what is the empiric probability for Pr{Y<600}

mcdonalds %>%
filter(cal_fat < 600) %>%
summarise(percent = n() / nrow(mcdonalds))
## # A tibble: 1 x 1
##   percent
##     <dbl>
## 1   0.895

#interpretation: 89.4% of data in mcdonalds cal_fat dataset are < 600 calories

#the theoretical and empiric calculations more closely agreed for the dairy_queen cal_fat data set.

Exercise 7 Now let’s consider some of the other variables in the dataset. Out of all the different restaurants, which ones’ distribution is the closest to normal for sodium?

mcmean_sodium <- mean(mcdonalds$sodium)
mcsd_sodium <- sd(mcdonalds$sodium)
print(mcmean_sodium)
## [1] 1437.895
print(mcsd_sodium)
## [1] 1036.172
mchist_sodium <-ggplot(data = mcdonalds, aes(x = sodium)) +
geom_blank() +
geom_histogram(bins = 10, aes(y = ..density..)) + 
stat_function(fun = dnorm, args = c(mean = mcmean, sd = mcsd), col = "tomato") +ggtitle("distribution of sodium mcdonalds") + geom_vline(xintercept=mcmean_sodium, col = "red")
mcQQ <-ggplot(data = mcdonalds, aes(sample = sodium)) +
geom_line(stat = "qq") +  stat_qq()+stat_qq_line() +
ggtitle("normal prob plot sodium mcdonalds")
mchist_sodium + mcQQ

#interpretation the histogram and normal probablity plots for mcdonalds_sodium do not appear normal distributed. The data are heavily skewed to the right.

#now analyze dairy_queen_sodium data for normality.

dqmean_sodium <- mean(dairy_queen$sodium)
dqsd_sodium <- sd(dairy_queen$sodium)
print(mcmean_sodium)
## [1] 1437.895
print(mcsd_sodium)
## [1] 1036.172
dqhist_sodium <-ggplot(data = dairy_queen, aes(x = sodium)) +
geom_blank() +
geom_histogram(bins = 10, aes(y = ..density..)) + 
stat_function(fun = dnorm, args = c(mean = dqmean, sd = dqsd), col = "tomato") +ggtitle("distribution of sodium dairy_queen") + geom_vline(xintercept=dqmean_sodium, col = "red")
dqQQ <-ggplot(data = dairy_queen, aes(sample = sodium)) +
geom_line(stat = "qq") +  stat_qq()+stat_qq_line() +
ggtitle("normal prob plot sodium dairy_queen")
dqhist_sodium + dqQQ

#interpretation the histogram and normal probablity plots for dairy_queen_sodium do not appear normal distributed. The data are heavily skewed to the right.

Exercise 7 Now let’s consider some of the other variables in the dataset. Out of all the different restaurants, which ones’ distribution is the closest to normal for sodium?

library(tidyverse)
library(openintro)
library(ggplot2)
library(patchwork)
mcdonalds <- fastfood %>%
filter(restaurant == "Mcdonalds")
dairy_queen <- fastfood %>%
filter(restaurant == "Dairy Queen")
Subway <- fastfood %>%
  filter(restaurant == "Subway")
Sonic <-fastfood %>%
  filter(restaurant == "Sonic")
Burger_King <- fastfood %>%
  filter(restaurant == "Burger King")
Sonic <- fastfood %>%
  filter(restaurant == "Sonic")
Arbys <- fastfood %>% 
  filter(restaurant == "Arbys")
Chick_Fil_A <- fastfood %>%
  filter(restaurant == "Chick Fil-A")
TacoBell <- fastfood %>% 
  filter(restaurant == "Taco Bell")
dqhist_sodium <-ggplot(data = dairy_queen, aes(x = sodium)) +
geom_blank() +
geom_histogram(bins = 10, aes(y = ..density..)) + 
stat_function(fun = dnorm, args = c(mean = dqmean, sd = dqsd), col = "tomato") +ggtitle("distribution of sodium dairy_queen") + geom_vline(xintercept=dqmean_sodium, col = "red")
mcmean <- mean(mcdonalds$sodium)
mchist_sodium <-ggplot(data = mcdonalds, aes(x = sodium)) +
geom_blank() +
geom_histogram(bins = 10, aes(y = ..density..)) + 
stat_function(fun = dnorm, args = c(mean = mcmean, sd = dqsd), col = "tomato") +ggtitle("distribution of sodium mcdonalds") + geom_vline(xintercept=dqmean_sodium, col = "red")
sbmean_sodium <- mean(Subway$sodium)
sbsd_sodium <- sd(Subway$sodium)
sbhist_sodium <-ggplot(data = Subway, aes(x = sodium)) +
geom_blank() +
geom_histogram(bins = 10, aes(y = ..density..)) + 
stat_function(fun = dnorm, args = c(mean = sbmean_sodium, sd = sbsd_sodium), col = "tomato") +ggtitle("distribution of sodium Subway") + geom_vline(xintercept=sbmean_sodium, col = "red")
bkmean_sodium <- mean(Burger_King$sodium)
bksd_sodium <- sd(Burger_King$sodium)
bkhist_sodium <-ggplot(data = Burger_King, aes(x = sodium)) +
geom_blank() +
geom_histogram(bins = 10, aes(y = ..density..)) + 
stat_function(fun = dnorm, args = c(mean = bkmean_sodium, sd = bksd_sodium), col = "tomato") +ggtitle("distribution of sodium Burger king") + geom_vline(xintercept=bkmean_sodium, col = "red")
tbmean_sodium <- mean(TacoBell$sodium)
tbsd_sodium <- sd(TacoBell$sodium)
tbhist_sodium <-ggplot(data = TacoBell, aes(x = sodium)) +
geom_blank() +
geom_histogram(bins = 10, aes(y = ..density..)) + 
stat_function(fun = dnorm, args = c(mean = tbmean_sodium, sd = tbsd_sodium), col = "tomato") +ggtitle("distribution of sodium Taco Bell") + geom_vline(xintercept=tbmean_sodium, col = "red")
abmean_sodium <- mean(Arbys$sodium)
absd_sodium <- sd(Arbys$sodium)
abhist_sodium <-ggplot(data = Arbys, aes(x = sodium)) +
geom_blank() +
geom_histogram(bins = 10, aes(y = ..density..)) + 
stat_function(fun = dnorm, args = c(mean = abmean_sodium, sd = absd_sodium), col = "tomato") +ggtitle("distribution of sodium Arby's") + geom_vline(xintercept=sbmean_sodium, col = "red")
snmean_sodium <- mean(Sonic$sodium)
snsd_sodium <- sd(Sonic$sodium)
snhist_sodium <-ggplot(data = Sonic, aes(x = sodium)) +
geom_blank() +
geom_histogram(bins = 10, aes(y = ..density..)) + 
stat_function(fun = dnorm, args = c(mean = snmean_sodium, sd = snsd_sodium), col = "tomato") +ggtitle("distribution of sodium Sonic") + geom_vline(xintercept=snmean_sodium, col = "red")
cfmean_sodium <- mean(Chick_Fil_A$sodium)
cfsd_sodium <- sd(Chick_Fil_A$sodium)
cfhist_sodium <-ggplot(data = Chick_Fil_A, aes(x = sodium)) +
geom_blank() +
geom_histogram(bins = 10, aes(y = ..density..)) + 
stat_function(fun = dnorm, args = c(mean = cfmean_sodium, sd = cfsd_sodium), col = "tomato") +ggtitle("distribution of sodium ChickFil") + 
  geom_vline(xintercept=cfmean_sodium, col = "red")
dqhist_sodium + mchist_sodium + sbhist_sodium + bkhist_sodium + tbhist_sodium + 
  abhist_sodium + snhist_sodium + cfhist_sodium

mcQQ_sodium <-ggplot(data = mcdonalds, aes(sample = sodium)) +
geom_line(stat = "qq") +  stat_qq()+stat_qq_line() +
ggtitle("normal prob plot sodium mcdonalds")
dqQQ_sodium <-ggplot(data = dairy_queen, aes(sample = sodium)) +
geom_line(stat = "qq") +  stat_qq()+stat_qq_line() +
ggtitle("normal prob plot sodium dairy queen")
sbQQ_sodium <-ggplot(data = Subway, aes(sample = sodium)) +
geom_line(stat = "qq") +  stat_qq()+stat_qq_line() +
ggtitle("normal prob plot sodium Subway")
bkQQ_sodium <-ggplot(data = Burger_King, aes(sample = sodium)) +
geom_line(stat = "qq") +  stat_qq()+stat_qq_line() +
ggtitle("normal prob plot sodium burger king")
tbQQ_sodium <-ggplot(data = TacoBell, aes(sample =sodium)) +
geom_line(stat = "qq") +  stat_qq()+stat_qq_line() +
ggtitle("normal prob plot sodium taco bell")
abQQ_sodium <-ggplot(data = Arbys, aes(sample = sodium)) +
geom_line(stat = "qq") +  stat_qq()+stat_qq_line() +
ggtitle("normal prob plot sodium Arby's")
snQQ_sodium <-ggplot(data = Sonic, aes(sample = sodium)) +
geom_line(stat = "qq") +  stat_qq()+stat_qq_line() +
ggtitle("normal prob sodium Sonic")
ckQQ_sodium <-ggplot(data = Chick_Fil_A, aes(sample = sodium)) +
geom_line(stat = "qq") +  stat_qq()+stat_qq_line() +
ggtitle("normal prob plot sodium Chick Fil-A")
dqQQ_sodium + mcQQ_sodium + sbQQ_sodium + bkQQ_sodium + tbQQ_sodium + abQQ_sodium + snQQ_sodium + ckQQ_sodium

#from QQ plots analysis, distribution for sodium from Burger king, Taco bell, and Arby’s appear most normally distributed.

bksharpiro <-shapiro.test(rnorm(n=100, bkmean_sodium, bksd_sodium))
tbsharpiro <-shapiro.test((rnorm(n=100, tbmean_sodium, tbsd_sodium)))
absharpiro <-shapiro.test((rnorm(n=100, abmean_sodium, absd_sodium)))
print(bksharpiro)
## 
##  Shapiro-Wilk normality test
## 
## data:  rnorm(n = 100, bkmean_sodium, bksd_sodium)
## W = 0.98687, p-value = 0.4291
print(tbsharpiro)
## 
##  Shapiro-Wilk normality test
## 
## data:  (rnorm(n = 100, tbmean_sodium, tbsd_sodium))
## W = 0.98558, p-value = 0.3496
print(absharpiro)
## 
##  Shapiro-Wilk normality test
## 
## data:  (rnorm(n = 100, abmean_sodium, absd_sodium))
## W = 0.99323, p-value = 0.9016

#shapiro test analysis of burger king, taco bell, and arby’s sodium data notes all P value > 0.1. therefore we have no compelling evidence for nonnormality.

Exercise 8 Note that some of the normal probability plots for sodium distributions seem to have a stepwise pattern. why do you think this might be the case?

#Answer - the stepwise pattern in the normal prob plots may be due to outliers in the data near the right side of the plots

Exercise 9 As you can see, normal probability plots can be used both to assess normality and visualize skewness. Make a normal probability plot for the total carbohydrates from a restaurant of your choice. Based on this normal probability plot, is this variable left skewed, symmetric, or right skewed? Use a histogram to confirm your findings.

#assess the mcodonalds total_carbohydrate data for normality vs skewness. # generate mean and sd total_carb

mcmean_carb <- mean(mcdonalds$total_carb)
mcsd_carb <- sd(mcdonalds$total_carb)
print(mcmean_carb)
## [1] 48.78947
print(mcsd_carb)
## [1] 26.44248

#generate histogram total_carb

mchist_carb <-ggplot(data = mcdonalds, aes(x = total_carb)) +
geom_blank() +
geom_histogram(bins = 10, aes(y = ..density..)) + 
stat_function(fun = dnorm, args = c(mean = dqmean, sd = dqsd), col = "tomato") +ggtitle("distribution of total_carb mcdonalds") + geom_vline(xintercept=dqmean_sodium, col = "red")

#generate normal prob plot total_carb

mcQQ_carb <-ggplot(data = mcdonalds, aes(sample = total_carb)) +
geom_line(stat = "qq") +  stat_qq()+stat_qq_line() +
ggtitle("normal prob plot total_carb mcdonalds")
mchist_carb + mcQQ_carb

#interpretation - similiar to all prior data sets analyzed, the mcdonalds total_carb data is heavy skewed to the right.

LS0tCnRpdGxlOiAic2NvdHRfcmVocmlnX21hdGgyMTdfTm9ybWFsbGFiIgphdXRob3I6ICJBdXRob3IgTmFtZSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6IG9wZW5pbnRybzo6bGFiX3JlcG9ydAotLS0KCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShvcGVuaW50cm8pCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwYXRjaHdvcmspCmBgYAoKIyMjIEV4ZXJjaXNlIDEgIE1ha2UgYSBwbG90IChvciBwbG90cykgdG8gdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb25zIG9mIHRoZSBhbW91bnQgb2YgY2Fsb3JpZXMgZnJvbSBmYXQgb2YgdGhlIG9wdGlvbnMgZnJvbSB0aGVzZSB0d28gcmVzdGF1cmFudHMuIEhvdyBkbyB0aGVpciBjZW50ZXJzLCBzaGFwZXMsIGFuZCBzcHJlYWRzIGNvbXBhcmU/CgpgYGB7cn0KZmFzdGZvb2QgPC1mYXN0Zm9vZApgYGAKCmBgYHtyfQpoZWFkKGZhc3Rmb29kKQpgYGAKCiN0aGlzIGZpbHRlcnMgdGhlIGRhdGFzZXQgaW50byBNY2RvbmFsZHMgYW5kIERhaXJ5IHF1ZWVuCmBgYHtyfQptY2RvbmFsZHMgPC0gZmFzdGZvb2QgJT4lCmZpbHRlcihyZXN0YXVyYW50ID09ICJNY2RvbmFsZHMiKQpkYWlyeV9xdWVlbiA8LSBmYXN0Zm9vZCAlPiUKZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkRhaXJ5IFF1ZWVuIikKYGBgCiNjYWxjdWxhdGUgNSBudW1iZXIgc3VtbWFyeSBmb3IgbWNkb25hbGRzIGFuZCBkYWlyeV9xdWVlbiBjYWxfZmF0CmBgYHtyfQptY3N1bW1hcnkgPC0gc3VtbWFyeShtY2RvbmFsZHMkY2FsX2ZhdCkKZHFzdW1tYXJ5IDwtIHN1bW1hcnkoZGFpcnlfcXVlZW4kY2FsX2ZhdCkKcHJpbnQobWNzdW1tYXJ5KQpwcmludChkcXN1bW1hcnkpCmBgYAoKI2NhbGN1bGF0ZSB0aGUgbWVhbnMgYW5kIHNkIGZvciBtY2RvbmFsZHMgYW5kIGRhaXJ5X3F1ZWVuIGZhdCBjb250ZW50CmBgYHtyfQptY21lYW4gPC0gbWVhbihtY2RvbmFsZHMkY2FsX2ZhdCkKbWNzZCA8LSBzZChtY2RvbmFsZHMkY2FsX2ZhdCkKcHJpbnQobWNtZWFuKQpwcmludChtY3NkKQpgYGAKCgpgYGB7cn0KZHFtZWFuIDwtIG1lYW4oZGFpcnlfcXVlZW4kY2FsX2ZhdCkKZHFzZCA8LSBzZChkYWlyeV9xdWVlbiRjYWxfZmF0KQpwcmludChkcW1lYW4pCnByaW50KGRxc2QpCmBgYAoKCiNnZW5lcmF0ZSBib3hwbG90cyBmb3IgbWNkb25hbGRzIGFuZCBkYWlyeV9xdWVlbiBmYXRfY2FsIGRhdGEKYGBge3J9Cm1jYm94cGxvdCA8LWdncGxvdChtY2RvbmFsZHMsIGFlcyh4PWNhbF9mYXQpKSArIAogIGdlb21fYm94cGxvdCgpICtnZ3RpdGxlKCJkaXN0cmlidXRpb24gZmF0IGNhbG9yaWVzIG1jZG9uYWxkcyIpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PW1jbWVhbiwgY29sID0gInJlZCIsIGx3ZCA9IDIpCmBgYAoKCmBgYHtyfQpkcWJveHBsb3QgPC1nZ3Bsb3QoZGFpcnlfcXVlZW4sIGFlcyh4PWNhbF9mYXQpKSArIAogIGdlb21fYm94cGxvdCgpICtnZ3RpdGxlKCJkaXN0cmlidXRpb24gZmF0IGNhbG9yaWVzIGRhaXJ5X3F1ZWVuIikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdD1kcW1lYW4sIGNvbCA9ICJyZWQiLCBsd2Q9IDIpCmBgYAojZ2VuZXJhdGUgaGlzdG9ncmFtIGRhaXJ5X3F1ZWVuIGZhdF9jYWwKYGBge3J9CmRxaGlzdG9ncmFtIDwtZ2dwbG90KGRhdGEgPSBkYWlyeV9xdWVlbiwgYWVzKHggPSBjYWxfZmF0KSkgKyAgCmdlb21fYmxhbmsoKSArIApnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTAsIGFlcyh5ID0gLi5kZW5zaXR5Li4pKSArCnN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBkcW1lYW4sIHNkID0gZHFzZCksIGNvbCA9ICJ0b21hdG8iKSArZ2d0aXRsZSgiZGlzdHJpYnV0aW9uIGZhdCBjYWxvcmllcyBkYWlyeV9xdWVlbiIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PWRxbWVhbiwgY29sID0gInJlZCIpCmBgYAojZ2VuZXJhdGUgaGlzdG9ncmFtIG1jZG9uYWxkcyBmYXRfY2FsCmBgYHtyfQptY2hpc3RvZ3JhbSA8LWdncGxvdChkYXRhID0gbWNkb25hbGRzLCBhZXMoeCA9IGNhbF9mYXQpKSArCmdlb21fYmxhbmsoKSArCmdlb21faGlzdG9ncmFtKGJpbnMgPSAxMCwgYWVzKHkgPSAuLmRlbnNpdHkuLikpICsgCnN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBtY21lYW4sIHNkID0gbWNzZCksIGNvbCA9ICJ0b21hdG8iKSArZ2d0aXRsZSgiZGlzdHJpYnV0aW9uIG9mIGNhbG9yaWVzIGZhdCBtY2RvbmFsZHMiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD1tY21lYW4sIGNvbCA9ICJyZWQiKQpgYGAKCgpgYGB7cn0KbWNib3hwbG90K2RxYm94cGxvdApgYGAKCgoKYGBge3J9Cm1jaGlzdG9ncmFtICsgZHFoaXN0b2dyYW0KYGBgCgojIyNBbnN3ZXIgRXhlcmNpc2UgMSAtIGhvdyBkbyB0aGVpciBjZW50ZXJzLCBzaGFwZXMsIGFuZCBzcHJlYWRzIGNvbXBhcmU/ICBDb21wYXJpbmcgdGhlIGJveHBsb3RzIGFuZCBoaXN0b2dyYW1zIGZvciBjYWxfZmF0IGRhaXJ5X3F1ZWVuIGFuZCBtY2RvbmFsZHMsIHdlIG5vdGUgdGhlIGZvbGxvd2luZyB0cmVuZHM6CiNib3RoIGRhdGFzZXRzIGhhdmUgc2V2ZXJhbCBvdXRsaWVycyBub3RlZCBvbiB0aGUgYm94cGxvdHMKI3RoZSBtZWFuIGZhdCBjYWxvcmllcyBhcHBlYXIgZ3JlYXRlciBpbiB0aGUgbWNkb25hbGRzIGRhdGEgdnMgdGhlIGRhaXJ5IHF1ZWVuIGRhdGEKI3RoZSBzcHJlYWQgb2YgdGhlIGRhdGEgZm9yIGZhdCBjYWxvcmllcyBhcHBlYXJzIHdpZGVyIGZvciBtY2RvbmFsZHMgdnMgdGhlIGRhaXJ5IHF1ZWVuIGRhdGEKI2JvdGggZGF0YXNldHMgYXJlIHNrZXdlZCB0byB0aGUgcmlnaHQgd2hpY2ggbWF5IHJlcHJlc2VudCB0aGUgZWZmZWN0IG9mIHRoZSBvdXRsaWVycyBub3RlZCBpbiB0aGUgYm94cGxvdHMKCiMjIyBFeGVyY2lzZSAyIEJhc2VkIG9uIHRoZSB0aGlzIHBsb3QsIGRvZXMgaXQgYXBwZWFyIHRoYXQgdGhlIGRhdGEgZm9sbG93IGEgbmVhcmx5IG5vcm1hbCBkaXN0cmlidXRpb24/CgojY29uc3RydWN0IGEgUS1RIHBsb3Qgb3Igbm9ybWFsIHByb2JhYmlsaXR5IHBsb3QgZm9yIGJvdGggZGF0YSBzZXRzCmBgYHtyfQptY1FRIDwtZ2dwbG90KGRhdGEgPSBtY2RvbmFsZHMsIGFlcyhzYW1wbGUgPSBjYWxfZmF0KSkgKwpnZW9tX2xpbmUoc3RhdCA9ICJxcSIpICsgIHN0YXRfcXEoKStzdGF0X3FxX2xpbmUoKSArCmdndGl0bGUoIm5vcm1hbCBwcm9iIHBsb3QgZmF0LWNhbCBtY2RvbmFsZHMiKQpgYGAKCmBgYHtyfQpkcVFRIDwtZ2dwbG90KGRhdGEgPSBkYWlyeV9xdWVlbiwgYWVzKHNhbXBsZSA9IGNhbF9mYXQpKSArCmdlb21fbGluZShzdGF0ID0gInFxIikgKyBzdGF0X3FxKCkrc3RhdF9xcV9saW5lKCkgKwpnZ3RpdGxlKCJub3JtYWwgcHJvYiBwbG90IGZhdC1jYWwgZGFpcnlfcXVlZW4iKQpgYGAKCmBgYHtyfQogbWNRUSArIGRxUVEKYGBgCiNBbnN3ZXIgRXhlcmNpc2UgMiAtIHRoZSBhYm92ZSBub3JtYWwgcHJvYiBwbG90cyBkbyBub3Qgc3VnZ2VzdCB0aGF0IGRhdGEgc2V0cyBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuICBSYXRoZXIgdGhleSBjb25maXJtIHRoZSBza2V3IG5vdGVkIGluIHRoZSBoaXN0b2dyYW0gcGxvdHMgZnJvbSBleGVyY2lzZSAxIAoKCiMjIyBFeGVyY2lzZSAzIE1ha2UgYSBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdCBvZiBzaW1fbm9ybSAuIERvIGFsbCBvZiB0aGUgcG9pbnRzIGZhbGwgb24gdGhlIGxpbmU/IEhvdyBkb2VzIHRoaXMgcGxvdCBjb21wYXJlIHRvIHRoZSBwcm9iYWJpbGl0eSBwbG90IGZvciB0aGUgcmVhbCBkYXRhPyAKCiMoU2luY2Ugc2ltX25vcm0gaXMgbm90IGEgZGF0YWZyYW1lLCBpdCBjYW4gYmUgcHV0IGRpcmVjdGx5IGludG8gdGhlIHNhbXBsZSBhcmd1bWVudCBhbmQgdGhlIGRhdGEgYXJndW1lbnQgY2FuIGJlIGRyb3BwZWQuKQoKI25vdyBnZW5lcmF0ZSBzaW11bGF0ZWQgbm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiBkYWlyeV9xdWVlbgoKYGBge3J9CmRxc2ltX25vcm0gPC0gcm5vcm0obiA9IG5yb3coZGFpcnlfcXVlZW4pLCBtZWFuID0gZHFtZWFuLCBzZCA9IGRxc2QpCmBgYAoKI25vdyBnZW5lcmF0ZSBhIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90IGZvciB0aGUgZHFzaW1fbm9ybSBkYXRhCgpgYGB7cn0KcXFub3Jtc2ltKHNhbXBsZSA9IGNhbF9mYXQsIGRhdGEgPSBkYWlyeV9xdWVlbikKYGBgCiMjIyBFeGVyY2lzZSA0IERvZXMgdGhlIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90IGZvciB0aGUgY2Fsb3JpZXMgZnJvbSBmYXQgbG9vayBzaW1pbGFyIHRvIHRoZSBwbG90cyBjcmVhdGVkIGZvciB0aGUgc2ltdWxhdGVkIGRhdGE/IFRoYXQgaXMsIGRvIHRoZSBwbG90cyBwcm92aWRlIGV2aWRlbmNlIHRoYXQgZGFpcnlfcXVlZW4gY2FsLWZhdCBkYXRhIGFyZSBuZWFybHkgbm9ybWFsPyAgCgojQU5TIEVYIDQgVGhlIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90cyBmb3IgZmF0X2NhbCBkYWlyeV9xdWVlbiBkbyBub3QgbG9vayBzaW1pbGFyIHRvIHRoZSBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdHMgZnJvbSBkcXNpbV9ub3JtIGRhdGEuIFRoZSBkcXNpbS1ub3JtIHByb2JhYmlsdHkgcGxvdHMgYXBwZWFyIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLgoKIyMjIEV4ZXJjaXNlIDUgVXNpbmcgdGhlIHNhbWUgdGVjaG5pcXVlLCBkZXRlcm1pbmUgd2hldGhlciBvciBub3QgdGhlIGNhbG9yaWVzIGZyb20gTWNEb25hbGTigJlzIG1lbnUgYXBwZWFyIHRvIGNvbWUgZnJvbSBhIG5vcm1hbCBkaXN0cmlidXRpb24uCgojZ2VuZXJhdGUgYSBzaW11bGF0ZWQgbm9ybWFsIGRpc3RyaWJ1dGlvbiBmcm9tIG1jZG9uYWxkcwpgYGB7cn0KbWNzaW1fbm9ybSA8LSBybm9ybShuID0gbnJvdyhtY2RvbmFsZHMpLCBtZWFuID0gZHFtZWFuLCBzZCA9IGRxc2QpCmBgYAoKI2dlbmVyYXRlIGEgbm9ybWFsIHByb2JhYmlsdHkgcGxvdCBmb3IgbWNzaW1fbm9ybQpgYGB7cn0KcXFub3Jtc2ltKHNhbXBsZSA9IGNhbF9mYXQsIGRhdGEgPSBtY2RvbmFsZHMpCmBgYAojIEFuc3dlciBFeGVyY2lzZSA1IC0gc2ltaWxhciB0byBleGVyY2lzZSA0ICwgdGhlIGZhdF9jYWwgbWNkb25hbGRzIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90cyBhbmQgdGhlIHNpbXVsYXRlZCBtY3NpbV9ub3JtIHBsb3RzIGFyZSBkaXNzaW1pbGlhci4gIAoKCiNub3JtYWwgcHJvYmFiaWxpdGllcwojIGNhbGN1bGF0ZSB0aGVvcmV0aWNhbCBhcmVhIHVuZGVyIGN1cnZlIGZvciBkYWlyeV9xdWVlbiBmYXRfY2FsIGRhdGEgUHJ7eT42MDB9CmBgYHtyfQooMSAtIHBub3JtKHEgPSA2MDAsIG1lYW4gPSBkcW1lYW4sIHNkID0gZHFzZCkpKjEwMApgYGAKCiNjYWxjdWxhdGUgZW1waXJpYyBwcm9iYWJpbGl0eSBmb3IgYWN0dWFsIGRhdGEKYGBge3J9CmRhaXJ5X3F1ZWVuICU+JQpmaWx0ZXIoY2FsX2ZhdCA+IDYwMCkgJT4lCnN1bW1hcmlzZShwZXJjZW50ID0gbigpIC8gbnJvdyhkYWlyeV9xdWVlbikpCmBgYAoKIyMjIEV4ZXJjaXNlIDYgV3JpdGUgb3V0IHR3byBwcm9iYWJpbGl0eSBxdWVzdGlvbnMgdGhhdCB5b3Ugd291bGQgbGlrZSB0byBhbnN3ZXIgYWJvdXQgYW55IG9mIHRoZSByZXN0YXVyYW50cyBpbiB0aGlzIGRhdGFzZXQuIENhbGN1bGF0ZSB0aG9zZSBwcm9iYWJpbGl0aWVzIHVzaW5nIGJvdGggdGhlIHRoZW9yZXRpY2FsIG5vcm1hbCBkaXN0cmlidXRpb24gYXMgd2VsbCBhcyB0aGUgZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiAoZm91ciBwcm9iYWJpbGl0aWVzIGluIGFsbCkuIFdoaWNoIG9uZSBoYWQgYSBjbG9zZXIgYWdyZWVtZW50IGJldHdlZW4gdGhlIHR3byBtZXRob2RzPwoKI3doYXQgaXMgdGhlb3JldGljYWwgcHJvYmFiaWxpdHkgZm9yIGRhaXJ5X3F1ZWVuIGNhbF9mYXQgZGF0YXNldCBQcihZPDYwMCkgIApgYGB7cn0KKHBub3JtKDYwMCwyNjAuNDcsMTU2LjQ4NSkpKjEwMApgYGAKI2ludGVycHJldGF0aW9uOiBmb3Igc2FtcGxlIGRyYXduIHJhbmRvbWx5IGZyb20gdGhlIGRhaXJ5X3F1ZWVuIGNhbF9mYXQgZGF0YXNldCwgdGhlcmUgaXMgYSA5OC40JSBjaGFuY2UgdGhhdCBpdCBpcyBsZXNzIHRoYW4gNjAwIGNhbG9yaWVzCgojd2hhdCBpcyB0aGUgZW1waXJpYyBwcm9iYWJpbGl0eSBmb3IgUHJ7WTw2MDB9CmBgYHtyfQpkYWlyeV9xdWVlbiAlPiUKZmlsdGVyKGNhbF9mYXQgPCA2MDApICU+JQpzdW1tYXJpc2UocGVyY2VudCA9IG4oKSAvIG5yb3coZGFpcnlfcXVlZW4pKQpgYGAKI2ludGVycHJldGF0aW9uOiA5NS4yJSBvZiBkYXRhIGluIGRhaXJ5X3F1ZWVuIGNhbF9mYXQgZGF0YXNldCBhcmUgPCA2MDAgY2Fsb3JpZXMKCiN3aGF0IGlzIHRoZW9yZXRpY2FsIHByb2JhYmlsaXR5IGZvciBtY2RvbmFsZHMgY2FsX2ZhdCBkYXRhc2V0IFByKFk8NjAwKSAgCmBgYHtyfQoocG5vcm0oNjAwLG1jbWVhbixtY3NkKSkqMTAwCmBgYAojaW50ZXJwcmV0YXRpb246IGZvciBzYW1wbGUgZHJhd24gcmFuZG9tbHkgZnJvbSB0aGUgZGFpcnlfcXVlZW4gY2FsX2ZhdCBkYXRhc2V0LCB0aGVyZSBpcyBhIDkyLjIlIGNoYW5jZSB0aGF0IGl0IGlzIGxlc3MgdGhhbiA2MDAgY2Fsb3JpZXMKCiN3aGF0IGlzIHRoZSBlbXBpcmljIHByb2JhYmlsaXR5IGZvciBQcntZPDYwMH0KYGBge3J9Cm1jZG9uYWxkcyAlPiUKZmlsdGVyKGNhbF9mYXQgPCA2MDApICU+JQpzdW1tYXJpc2UocGVyY2VudCA9IG4oKSAvIG5yb3cobWNkb25hbGRzKSkKYGBgCiNpbnRlcnByZXRhdGlvbjogODkuNCUgb2YgZGF0YSBpbiBtY2RvbmFsZHMgY2FsX2ZhdCBkYXRhc2V0IGFyZSA8IDYwMCBjYWxvcmllcwoKI3RoZSB0aGVvcmV0aWNhbCBhbmQgZW1waXJpYyBjYWxjdWxhdGlvbnMgbW9yZSBjbG9zZWx5IGFncmVlZCBmb3IgdGhlIGRhaXJ5X3F1ZWVuIGNhbF9mYXQgZGF0YSBzZXQuCgojIyMgRXhlcmNpc2UgNyBOb3cgbGV04oCZcyBjb25zaWRlciBzb21lIG9mIHRoZSBvdGhlciB2YXJpYWJsZXMgaW4gdGhlIGRhdGFzZXQuIE91dCBvZiBhbGwgdGhlIGRpZmZlcmVudCByZXN0YXVyYW50cywgd2hpY2ggb25lc+KAmSBkaXN0cmlidXRpb24gaXMgdGhlIGNsb3Nlc3QgdG8gbm9ybWFsIGZvciBzb2RpdW0/CgoKYGBge3J9Cm1jbWVhbl9zb2RpdW0gPC0gbWVhbihtY2RvbmFsZHMkc29kaXVtKQptY3NkX3NvZGl1bSA8LSBzZChtY2RvbmFsZHMkc29kaXVtKQpwcmludChtY21lYW5fc29kaXVtKQpwcmludChtY3NkX3NvZGl1bSkKYGBgCgpgYGB7cn0KbWNoaXN0X3NvZGl1bSA8LWdncGxvdChkYXRhID0gbWNkb25hbGRzLCBhZXMoeCA9IHNvZGl1bSkpICsKZ2VvbV9ibGFuaygpICsKZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwLCBhZXMoeSA9IC4uZGVuc2l0eS4uKSkgKyAKc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgYXJncyA9IGMobWVhbiA9IG1jbWVhbiwgc2QgPSBtY3NkKSwgY29sID0gInRvbWF0byIpICtnZ3RpdGxlKCJkaXN0cmlidXRpb24gb2Ygc29kaXVtIG1jZG9uYWxkcyIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PW1jbWVhbl9zb2RpdW0sIGNvbCA9ICJyZWQiKQoKYGBgCgoKCmBgYHtyfQptY1FRIDwtZ2dwbG90KGRhdGEgPSBtY2RvbmFsZHMsIGFlcyhzYW1wbGUgPSBzb2RpdW0pKSArCmdlb21fbGluZShzdGF0ID0gInFxIikgKyAgc3RhdF9xcSgpK3N0YXRfcXFfbGluZSgpICsKZ2d0aXRsZSgibm9ybWFsIHByb2IgcGxvdCBzb2RpdW0gbWNkb25hbGRzIikKYGBgCgpgYGB7cn0KbWNoaXN0X3NvZGl1bSArIG1jUVEKYGBgCgoKI2ludGVycHJldGF0aW9uIHRoZSBoaXN0b2dyYW0gYW5kIG5vcm1hbCBwcm9iYWJsaXR5IHBsb3RzIGZvciBtY2RvbmFsZHNfc29kaXVtIGRvIG5vdCBhcHBlYXIgbm9ybWFsIGRpc3RyaWJ1dGVkLiAgVGhlIGRhdGEgYXJlIGhlYXZpbHkgc2tld2VkIHRvIHRoZSByaWdodC4KCiNub3cgYW5hbHl6ZSBkYWlyeV9xdWVlbl9zb2RpdW0gZGF0YSBmb3Igbm9ybWFsaXR5LgoKYGBge3J9CmRxbWVhbl9zb2RpdW0gPC0gbWVhbihkYWlyeV9xdWVlbiRzb2RpdW0pCmRxc2Rfc29kaXVtIDwtIHNkKGRhaXJ5X3F1ZWVuJHNvZGl1bSkKcHJpbnQobWNtZWFuX3NvZGl1bSkKcHJpbnQobWNzZF9zb2RpdW0pCmBgYAoKCmBgYHtyfQpkcWhpc3Rfc29kaXVtIDwtZ2dwbG90KGRhdGEgPSBkYWlyeV9xdWVlbiwgYWVzKHggPSBzb2RpdW0pKSArCmdlb21fYmxhbmsoKSArCmdlb21faGlzdG9ncmFtKGJpbnMgPSAxMCwgYWVzKHkgPSAuLmRlbnNpdHkuLikpICsgCnN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBkcW1lYW4sIHNkID0gZHFzZCksIGNvbCA9ICJ0b21hdG8iKSArZ2d0aXRsZSgiZGlzdHJpYnV0aW9uIG9mIHNvZGl1bSBkYWlyeV9xdWVlbiIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PWRxbWVhbl9zb2RpdW0sIGNvbCA9ICJyZWQiKQpgYGAKCmBgYHtyfQpkcVFRIDwtZ2dwbG90KGRhdGEgPSBkYWlyeV9xdWVlbiwgYWVzKHNhbXBsZSA9IHNvZGl1bSkpICsKZ2VvbV9saW5lKHN0YXQgPSAicXEiKSArICBzdGF0X3FxKCkrc3RhdF9xcV9saW5lKCkgKwpnZ3RpdGxlKCJub3JtYWwgcHJvYiBwbG90IHNvZGl1bSBkYWlyeV9xdWVlbiIpCmBgYAoKYGBge3J9CmRxaGlzdF9zb2RpdW0gKyBkcVFRCmBgYAojaW50ZXJwcmV0YXRpb24gdGhlIGhpc3RvZ3JhbSBhbmQgbm9ybWFsIHByb2JhYmxpdHkgcGxvdHMgZm9yIGRhaXJ5X3F1ZWVuX3NvZGl1bSBkbyBub3QgYXBwZWFyIG5vcm1hbCBkaXN0cmlidXRlZC4gIFRoZSBkYXRhIGFyZSBoZWF2aWx5IHNrZXdlZCB0byB0aGUgcmlnaHQuCgojIyMgRXhlcmNpc2UgNyBOb3cgbGV04oCZcyBjb25zaWRlciBzb21lIG9mIHRoZSBvdGhlciB2YXJpYWJsZXMgaW4gdGhlIGRhdGFzZXQuIE91dCBvZiBhbGwgdGhlIGRpZmZlcmVudCByZXN0YXVyYW50cywgd2hpY2ggb25lc+KAmSBkaXN0cmlidXRpb24gaXMgdGhlIGNsb3Nlc3QgdG8gbm9ybWFsIGZvciBzb2RpdW0/CgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkob3BlbmludHJvKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGF0Y2h3b3JrKQptY2RvbmFsZHMgPC0gZmFzdGZvb2QgJT4lCmZpbHRlcihyZXN0YXVyYW50ID09ICJNY2RvbmFsZHMiKQpkYWlyeV9xdWVlbiA8LSBmYXN0Zm9vZCAlPiUKZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkRhaXJ5IFF1ZWVuIikKU3Vid2F5IDwtIGZhc3Rmb29kICU+JQogIGZpbHRlcihyZXN0YXVyYW50ID09ICJTdWJ3YXkiKQpTb25pYyA8LWZhc3Rmb29kICU+JQogIGZpbHRlcihyZXN0YXVyYW50ID09ICJTb25pYyIpCkJ1cmdlcl9LaW5nIDwtIGZhc3Rmb29kICU+JQogIGZpbHRlcihyZXN0YXVyYW50ID09ICJCdXJnZXIgS2luZyIpClNvbmljIDwtIGZhc3Rmb29kICU+JQogIGZpbHRlcihyZXN0YXVyYW50ID09ICJTb25pYyIpCkFyYnlzIDwtIGZhc3Rmb29kICU+JSAKICBmaWx0ZXIocmVzdGF1cmFudCA9PSAiQXJieXMiKQpDaGlja19GaWxfQSA8LSBmYXN0Zm9vZCAlPiUKICBmaWx0ZXIocmVzdGF1cmFudCA9PSAiQ2hpY2sgRmlsLUEiKQpUYWNvQmVsbCA8LSBmYXN0Zm9vZCAlPiUgCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIlRhY28gQmVsbCIpCmBgYAoKYGBge3J9CmRxaGlzdF9zb2RpdW0gPC1nZ3Bsb3QoZGF0YSA9IGRhaXJ5X3F1ZWVuLCBhZXMoeCA9IHNvZGl1bSkpICsKZ2VvbV9ibGFuaygpICsKZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwLCBhZXMoeSA9IC4uZGVuc2l0eS4uKSkgKyAKc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgYXJncyA9IGMobWVhbiA9IGRxbWVhbiwgc2QgPSBkcXNkKSwgY29sID0gInRvbWF0byIpICtnZ3RpdGxlKCJkaXN0cmlidXRpb24gb2Ygc29kaXVtIGRhaXJ5X3F1ZWVuIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9ZHFtZWFuX3NvZGl1bSwgY29sID0gInJlZCIpCmBgYAoKYGBge3J9Cm1jbWVhbiA8LSBtZWFuKG1jZG9uYWxkcyRzb2RpdW0pCm1jaGlzdF9zb2RpdW0gPC1nZ3Bsb3QoZGF0YSA9IG1jZG9uYWxkcywgYWVzKHggPSBzb2RpdW0pKSArCmdlb21fYmxhbmsoKSArCmdlb21faGlzdG9ncmFtKGJpbnMgPSAxMCwgYWVzKHkgPSAuLmRlbnNpdHkuLikpICsgCnN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBtY21lYW4sIHNkID0gZHFzZCksIGNvbCA9ICJ0b21hdG8iKSArZ2d0aXRsZSgiZGlzdHJpYnV0aW9uIG9mIHNvZGl1bSBtY2RvbmFsZHMiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD1kcW1lYW5fc29kaXVtLCBjb2wgPSAicmVkIikKYGBgCgpgYGB7cn0Kc2JtZWFuX3NvZGl1bSA8LSBtZWFuKFN1YndheSRzb2RpdW0pCnNic2Rfc29kaXVtIDwtIHNkKFN1YndheSRzb2RpdW0pCmBgYAoKYGBge3J9CgpzYmhpc3Rfc29kaXVtIDwtZ2dwbG90KGRhdGEgPSBTdWJ3YXksIGFlcyh4ID0gc29kaXVtKSkgKwpnZW9tX2JsYW5rKCkgKwpnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTAsIGFlcyh5ID0gLi5kZW5zaXR5Li4pKSArIApzdGF0X2Z1bmN0aW9uKGZ1biA9IGRub3JtLCBhcmdzID0gYyhtZWFuID0gc2JtZWFuX3NvZGl1bSwgc2QgPSBzYnNkX3NvZGl1bSksIGNvbCA9ICJ0b21hdG8iKSArZ2d0aXRsZSgiZGlzdHJpYnV0aW9uIG9mIHNvZGl1bSBTdWJ3YXkiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD1zYm1lYW5fc29kaXVtLCBjb2wgPSAicmVkIikKYGBgCgpgYGB7cn0KYmttZWFuX3NvZGl1bSA8LSBtZWFuKEJ1cmdlcl9LaW5nJHNvZGl1bSkKYmtzZF9zb2RpdW0gPC0gc2QoQnVyZ2VyX0tpbmckc29kaXVtKQpgYGAKCmBgYHtyfQpia2hpc3Rfc29kaXVtIDwtZ2dwbG90KGRhdGEgPSBCdXJnZXJfS2luZywgYWVzKHggPSBzb2RpdW0pKSArCmdlb21fYmxhbmsoKSArCmdlb21faGlzdG9ncmFtKGJpbnMgPSAxMCwgYWVzKHkgPSAuLmRlbnNpdHkuLikpICsgCnN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBia21lYW5fc29kaXVtLCBzZCA9IGJrc2Rfc29kaXVtKSwgY29sID0gInRvbWF0byIpICtnZ3RpdGxlKCJkaXN0cmlidXRpb24gb2Ygc29kaXVtIEJ1cmdlciBraW5nIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9YmttZWFuX3NvZGl1bSwgY29sID0gInJlZCIpCmBgYAoKCmBgYHtyfQp0Ym1lYW5fc29kaXVtIDwtIG1lYW4oVGFjb0JlbGwkc29kaXVtKQp0YnNkX3NvZGl1bSA8LSBzZChUYWNvQmVsbCRzb2RpdW0pCmBgYAoKYGBge3J9CnRiaGlzdF9zb2RpdW0gPC1nZ3Bsb3QoZGF0YSA9IFRhY29CZWxsLCBhZXMoeCA9IHNvZGl1bSkpICsKZ2VvbV9ibGFuaygpICsKZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwLCBhZXMoeSA9IC4uZGVuc2l0eS4uKSkgKyAKc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgYXJncyA9IGMobWVhbiA9IHRibWVhbl9zb2RpdW0sIHNkID0gdGJzZF9zb2RpdW0pLCBjb2wgPSAidG9tYXRvIikgK2dndGl0bGUoImRpc3RyaWJ1dGlvbiBvZiBzb2RpdW0gVGFjbyBCZWxsIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9dGJtZWFuX3NvZGl1bSwgY29sID0gInJlZCIpCmBgYAoKYGBge3J9CmFibWVhbl9zb2RpdW0gPC0gbWVhbihBcmJ5cyRzb2RpdW0pCmFic2Rfc29kaXVtIDwtIHNkKEFyYnlzJHNvZGl1bSkKYGBgCgpgYGB7cn0KYWJoaXN0X3NvZGl1bSA8LWdncGxvdChkYXRhID0gQXJieXMsIGFlcyh4ID0gc29kaXVtKSkgKwpnZW9tX2JsYW5rKCkgKwpnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTAsIGFlcyh5ID0gLi5kZW5zaXR5Li4pKSArIApzdGF0X2Z1bmN0aW9uKGZ1biA9IGRub3JtLCBhcmdzID0gYyhtZWFuID0gYWJtZWFuX3NvZGl1bSwgc2QgPSBhYnNkX3NvZGl1bSksIGNvbCA9ICJ0b21hdG8iKSArZ2d0aXRsZSgiZGlzdHJpYnV0aW9uIG9mIHNvZGl1bSBBcmJ5J3MiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD1zYm1lYW5fc29kaXVtLCBjb2wgPSAicmVkIikKYGBgCgpgYGB7cn0Kc25tZWFuX3NvZGl1bSA8LSBtZWFuKFNvbmljJHNvZGl1bSkKc25zZF9zb2RpdW0gPC0gc2QoU29uaWMkc29kaXVtKQpgYGAKCmBgYHtyfQpzbmhpc3Rfc29kaXVtIDwtZ2dwbG90KGRhdGEgPSBTb25pYywgYWVzKHggPSBzb2RpdW0pKSArCmdlb21fYmxhbmsoKSArCmdlb21faGlzdG9ncmFtKGJpbnMgPSAxMCwgYWVzKHkgPSAuLmRlbnNpdHkuLikpICsgCnN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBzbm1lYW5fc29kaXVtLCBzZCA9IHNuc2Rfc29kaXVtKSwgY29sID0gInRvbWF0byIpICtnZ3RpdGxlKCJkaXN0cmlidXRpb24gb2Ygc29kaXVtIFNvbmljIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9c25tZWFuX3NvZGl1bSwgY29sID0gInJlZCIpCmBgYAoKYGBge3J9CmNmbWVhbl9zb2RpdW0gPC0gbWVhbihDaGlja19GaWxfQSRzb2RpdW0pCmNmc2Rfc29kaXVtIDwtIHNkKENoaWNrX0ZpbF9BJHNvZGl1bSkKYGBgCgpgYGB7cn0KY2ZoaXN0X3NvZGl1bSA8LWdncGxvdChkYXRhID0gQ2hpY2tfRmlsX0EsIGFlcyh4ID0gc29kaXVtKSkgKwpnZW9tX2JsYW5rKCkgKwpnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTAsIGFlcyh5ID0gLi5kZW5zaXR5Li4pKSArIApzdGF0X2Z1bmN0aW9uKGZ1biA9IGRub3JtLCBhcmdzID0gYyhtZWFuID0gY2ZtZWFuX3NvZGl1bSwgc2QgPSBjZnNkX3NvZGl1bSksIGNvbCA9ICJ0b21hdG8iKSArZ2d0aXRsZSgiZGlzdHJpYnV0aW9uIG9mIHNvZGl1bSBDaGlja0ZpbCIpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PWNmbWVhbl9zb2RpdW0sIGNvbCA9ICJyZWQiKQpgYGAKCmBgYHtyfQpkcWhpc3Rfc29kaXVtICsgbWNoaXN0X3NvZGl1bSArIHNiaGlzdF9zb2RpdW0gKyBia2hpc3Rfc29kaXVtICsgdGJoaXN0X3NvZGl1bSArIAogIGFiaGlzdF9zb2RpdW0gKyBzbmhpc3Rfc29kaXVtICsgY2ZoaXN0X3NvZGl1bQpgYGAKCmBgYHtyfQptY1FRX3NvZGl1bSA8LWdncGxvdChkYXRhID0gbWNkb25hbGRzLCBhZXMoc2FtcGxlID0gc29kaXVtKSkgKwpnZW9tX2xpbmUoc3RhdCA9ICJxcSIpICsgIHN0YXRfcXEoKStzdGF0X3FxX2xpbmUoKSArCmdndGl0bGUoIm5vcm1hbCBwcm9iIHBsb3Qgc29kaXVtIG1jZG9uYWxkcyIpCmBgYAoKYGBge3J9CmRxUVFfc29kaXVtIDwtZ2dwbG90KGRhdGEgPSBkYWlyeV9xdWVlbiwgYWVzKHNhbXBsZSA9IHNvZGl1bSkpICsKZ2VvbV9saW5lKHN0YXQgPSAicXEiKSArICBzdGF0X3FxKCkrc3RhdF9xcV9saW5lKCkgKwpnZ3RpdGxlKCJub3JtYWwgcHJvYiBwbG90IHNvZGl1bSBkYWlyeSBxdWVlbiIpCmBgYAoKYGBge3J9CnNiUVFfc29kaXVtIDwtZ2dwbG90KGRhdGEgPSBTdWJ3YXksIGFlcyhzYW1wbGUgPSBzb2RpdW0pKSArCmdlb21fbGluZShzdGF0ID0gInFxIikgKyAgc3RhdF9xcSgpK3N0YXRfcXFfbGluZSgpICsKZ2d0aXRsZSgibm9ybWFsIHByb2IgcGxvdCBzb2RpdW0gU3Vid2F5IikKYGBgCgpgYGB7cn0KYmtRUV9zb2RpdW0gPC1nZ3Bsb3QoZGF0YSA9IEJ1cmdlcl9LaW5nLCBhZXMoc2FtcGxlID0gc29kaXVtKSkgKwpnZW9tX2xpbmUoc3RhdCA9ICJxcSIpICsgIHN0YXRfcXEoKStzdGF0X3FxX2xpbmUoKSArCmdndGl0bGUoIm5vcm1hbCBwcm9iIHBsb3Qgc29kaXVtIGJ1cmdlciBraW5nIikKYGBgCgpgYGB7cn0KdGJRUV9zb2RpdW0gPC1nZ3Bsb3QoZGF0YSA9IFRhY29CZWxsLCBhZXMoc2FtcGxlID1zb2RpdW0pKSArCmdlb21fbGluZShzdGF0ID0gInFxIikgKyAgc3RhdF9xcSgpK3N0YXRfcXFfbGluZSgpICsKZ2d0aXRsZSgibm9ybWFsIHByb2IgcGxvdCBzb2RpdW0gdGFjbyBiZWxsIikKYGBgCgpgYGB7cn0KYWJRUV9zb2RpdW0gPC1nZ3Bsb3QoZGF0YSA9IEFyYnlzLCBhZXMoc2FtcGxlID0gc29kaXVtKSkgKwpnZW9tX2xpbmUoc3RhdCA9ICJxcSIpICsgIHN0YXRfcXEoKStzdGF0X3FxX2xpbmUoKSArCmdndGl0bGUoIm5vcm1hbCBwcm9iIHBsb3Qgc29kaXVtIEFyYnkncyIpCmBgYAoKYGBge3J9CnNuUVFfc29kaXVtIDwtZ2dwbG90KGRhdGEgPSBTb25pYywgYWVzKHNhbXBsZSA9IHNvZGl1bSkpICsKZ2VvbV9saW5lKHN0YXQgPSAicXEiKSArICBzdGF0X3FxKCkrc3RhdF9xcV9saW5lKCkgKwpnZ3RpdGxlKCJub3JtYWwgcHJvYiBzb2RpdW0gU29uaWMiKQpgYGAKCmBgYHtyfQpja1FRX3NvZGl1bSA8LWdncGxvdChkYXRhID0gQ2hpY2tfRmlsX0EsIGFlcyhzYW1wbGUgPSBzb2RpdW0pKSArCmdlb21fbGluZShzdGF0ID0gInFxIikgKyAgc3RhdF9xcSgpK3N0YXRfcXFfbGluZSgpICsKZ2d0aXRsZSgibm9ybWFsIHByb2IgcGxvdCBzb2RpdW0gQ2hpY2sgRmlsLUEiKQpgYGAKCmBgYHtyfQpkcVFRX3NvZGl1bSArIG1jUVFfc29kaXVtICsgc2JRUV9zb2RpdW0gKyBia1FRX3NvZGl1bSArIHRiUVFfc29kaXVtICsgYWJRUV9zb2RpdW0gKyBzblFRX3NvZGl1bSArIGNrUVFfc29kaXVtCmBgYAoKI2Zyb20gUVEgcGxvdHMgYW5hbHlzaXMsIGRpc3RyaWJ1dGlvbiBmb3Igc29kaXVtIGZyb20gQnVyZ2VyIGtpbmcsIFRhY28gYmVsbCwgYW5kIEFyYnkncyBhcHBlYXIgbW9zdCBub3JtYWxseSBkaXN0cmlidXRlZC4KCmBgYHtyfQpia3NoYXJwaXJvIDwtc2hhcGlyby50ZXN0KHJub3JtKG49MTAwLCBia21lYW5fc29kaXVtLCBia3NkX3NvZGl1bSkpCmBgYAoKYGBge3J9CnRic2hhcnBpcm8gPC1zaGFwaXJvLnRlc3QoKHJub3JtKG49MTAwLCB0Ym1lYW5fc29kaXVtLCB0YnNkX3NvZGl1bSkpKQpgYGAKCmBgYHtyfQphYnNoYXJwaXJvIDwtc2hhcGlyby50ZXN0KChybm9ybShuPTEwMCwgYWJtZWFuX3NvZGl1bSwgYWJzZF9zb2RpdW0pKSkKYGBgCgpgYGB7cn0KcHJpbnQoYmtzaGFycGlybykKcHJpbnQodGJzaGFycGlybykKcHJpbnQoYWJzaGFycGlybykKYGBgCgojc2hhcGlybyB0ZXN0IGFuYWx5c2lzIG9mIGJ1cmdlciBraW5nLCB0YWNvIGJlbGwsIGFuZCBhcmJ5J3Mgc29kaXVtIGRhdGEgbm90ZXMgYWxsIFAgdmFsdWUgPiAwLjEuIHRoZXJlZm9yZSB3ZSBoYXZlIG5vIGNvbXBlbGxpbmcgZXZpZGVuY2UgZm9yIG5vbm5vcm1hbGl0eS4gCgoKIyMjIEV4ZXJjaXNlIDggTm90ZSB0aGF0IHNvbWUgb2YgdGhlIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90cyBmb3Igc29kaXVtIGRpc3RyaWJ1dGlvbnMgc2VlbSB0byBoYXZlIGEgc3RlcHdpc2UgcGF0dGVybi4gd2h5IGRvIHlvdSB0aGluayB0aGlzIG1pZ2h0IGJlIHRoZSBjYXNlPwojQW5zd2VyIC0gdGhlIHN0ZXB3aXNlIHBhdHRlcm4gaW4gdGhlIG5vcm1hbCBwcm9iIHBsb3RzIG1heSBiZSBkdWUgdG8gb3V0bGllcnMgaW4gdGhlIGRhdGEgbmVhciB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgcGxvdHMKCgojIyMgRXhlcmNpc2UgOSBBcyB5b3UgY2FuIHNlZSwgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3RzIGNhbiBiZSB1c2VkIGJvdGggdG8gYXNzZXNzIG5vcm1hbGl0eSBhbmQgdmlzdWFsaXplIHNrZXduZXNzLiBNYWtlIGEgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3QgZm9yIHRoZSB0b3RhbCBjYXJib2h5ZHJhdGVzIGZyb20gYSByZXN0YXVyYW50IG9mIHlvdXIgY2hvaWNlLiBCYXNlZCBvbiB0aGlzIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90LCBpcyB0aGlzIHZhcmlhYmxlIGxlZnQgc2tld2VkLCBzeW1tZXRyaWMsIG9yIHJpZ2h0IHNrZXdlZD8gVXNlIGEgaGlzdG9ncmFtIHRvIGNvbmZpcm0geW91ciBmaW5kaW5ncy4KCiNhc3Nlc3MgdGhlIG1jb2RvbmFsZHMgdG90YWxfY2FyYm9oeWRyYXRlIGRhdGEgZm9yIG5vcm1hbGl0eSB2cyBza2V3bmVzcy4KIyBnZW5lcmF0ZSBtZWFuIGFuZCBzZCB0b3RhbF9jYXJiCmBgYHtyfQptY21lYW5fY2FyYiA8LSBtZWFuKG1jZG9uYWxkcyR0b3RhbF9jYXJiKQptY3NkX2NhcmIgPC0gc2QobWNkb25hbGRzJHRvdGFsX2NhcmIpCnByaW50KG1jbWVhbl9jYXJiKQpwcmludChtY3NkX2NhcmIpCmBgYAojZ2VuZXJhdGUgaGlzdG9ncmFtIHRvdGFsX2NhcmIKYGBge3J9Cm1jaGlzdF9jYXJiIDwtZ2dwbG90KGRhdGEgPSBtY2RvbmFsZHMsIGFlcyh4ID0gdG90YWxfY2FyYikpICsKZ2VvbV9ibGFuaygpICsKZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwLCBhZXMoeSA9IC4uZGVuc2l0eS4uKSkgKyAKc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgYXJncyA9IGMobWVhbiA9IGRxbWVhbiwgc2QgPSBkcXNkKSwgY29sID0gInRvbWF0byIpICtnZ3RpdGxlKCJkaXN0cmlidXRpb24gb2YgdG90YWxfY2FyYiBtY2RvbmFsZHMiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD1kcW1lYW5fc29kaXVtLCBjb2wgPSAicmVkIikKYGBgCiNnZW5lcmF0ZSBub3JtYWwgcHJvYiBwbG90IHRvdGFsX2NhcmIKYGBge3J9Cm1jUVFfY2FyYiA8LWdncGxvdChkYXRhID0gbWNkb25hbGRzLCBhZXMoc2FtcGxlID0gdG90YWxfY2FyYikpICsKZ2VvbV9saW5lKHN0YXQgPSAicXEiKSArICBzdGF0X3FxKCkrc3RhdF9xcV9saW5lKCkgKwpnZ3RpdGxlKCJub3JtYWwgcHJvYiBwbG90IHRvdGFsX2NhcmIgbWNkb25hbGRzIikKYGBgCgpgYGB7cn0KbWNoaXN0X2NhcmIgKyBtY1FRX2NhcmIKYGBgCgojaW50ZXJwcmV0YXRpb24gLSBzaW1pbGlhciB0byBhbGwgcHJpb3IgZGF0YSBzZXRzIGFuYWx5emVkLCB0aGUgbWNkb25hbGRzIHRvdGFsX2NhcmIgZGF0YSBpcyBoZWF2eSBza2V3ZWQgdG8gdGhlIHJpZ2h0LiAgCgoKCgoKCg==