library(tidyverse)
library(openintro)
library(dplyr)
library(ggplot2)

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?

#Load "fastfood"dataset
data("fastfood", package='openintro')
head(fastfood)
## # A tibble: 6 × 17
##   restaurant item       calories cal_fat total_fat sat_fat trans_fat cholesterol
##   <chr>      <chr>         <dbl>   <dbl>     <dbl>   <dbl>     <dbl>       <dbl>
## 1 Mcdonalds  Artisan G…      380      60         7       2       0            95
## 2 Mcdonalds  Single Ba…      840     410        45      17       1.5         130
## 3 Mcdonalds  Double Ba…     1130     600        67      27       3           220
## 4 Mcdonalds  Grilled B…      750     280        31      10       0.5         155
## 5 Mcdonalds  Crispy Ba…      920     410        45      12       0.5         120
## 6 Mcdonalds  Big Mac         540     250        28      10       1            80
## # ℹ 9 more variables: sodium <dbl>, total_carb <dbl>, fiber <dbl>, sugar <dbl>,
## #   protein <dbl>, vit_a <dbl>, vit_c <dbl>, calcium <dbl>, salad <chr>
# create two new data sets, "mcdonalds" and "dairy_queen,"
mcdonalds <- fastfood %>%
  filter(restaurant == "Mcdonalds")
head(mcdonalds)
## # A tibble: 6 × 17
##   restaurant item       calories cal_fat total_fat sat_fat trans_fat cholesterol
##   <chr>      <chr>         <dbl>   <dbl>     <dbl>   <dbl>     <dbl>       <dbl>
## 1 Mcdonalds  Artisan G…      380      60         7       2       0            95
## 2 Mcdonalds  Single Ba…      840     410        45      17       1.5         130
## 3 Mcdonalds  Double Ba…     1130     600        67      27       3           220
## 4 Mcdonalds  Grilled B…      750     280        31      10       0.5         155
## 5 Mcdonalds  Crispy Ba…      920     410        45      12       0.5         120
## 6 Mcdonalds  Big Mac         540     250        28      10       1            80
## # ℹ 9 more variables: sodium <dbl>, total_carb <dbl>, fiber <dbl>, sugar <dbl>,
## #   protein <dbl>, vit_a <dbl>, vit_c <dbl>, calcium <dbl>, salad <chr>
dairy_queen <- fastfood %>%
  filter(restaurant == "Dairy Queen")
head(dairy_queen)
## # A tibble: 6 × 17
##   restaurant  item      calories cal_fat total_fat sat_fat trans_fat cholesterol
##   <chr>       <chr>        <dbl>   <dbl>     <dbl>   <dbl>     <dbl>       <dbl>
## 1 Dairy Queen 1/2 lb. …     1000     660        74      26         2         170
## 2 Dairy Queen 1/2 lb. …      800     460        51      20         2         135
## 3 Dairy Queen 1/4 lb. …      630     330        37      13         1          95
## 4 Dairy Queen 1/4 lb. …      540     270        30      11         1          70
## 5 Dairy Queen 1/4 lb. …      570     310        35      11         1          75
## 6 Dairy Queen Original…      400     160        18       9         1          65
## # ℹ 9 more variables: sodium <dbl>, total_carb <dbl>, fiber <dbl>, sugar <dbl>,
## #   protein <dbl>, vit_a <dbl>, vit_c <dbl>, calcium <dbl>, salad <chr>
hist(mcdonalds$cal_fat)

hist(dairy_queen$cal_fat)

These two histograms show distribution of cal_fat for Mcdonalds and Dairy_queen. McDonald’s has a higher fat calories compared to Dairy Queen. Both distributions are right-skewed, this means that there are few items with very high calories from fat in the data set. McDonald’s histogram increases in bin width of 200 calories, whereas Dairy Queen’s histogram increases in bin width of 100 calories.

Exercise 2

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

dqmean <- mean(dairy_queen$cal_fat)
dqsd   <- sd(dairy_queen$cal_fat)
ggplot(data = dairy_queen, aes(x = cal_fat)) +
        geom_blank() +
        geom_histogram(aes(y = ..density..)) +
        stat_function(fun = dnorm, args = c(mean = dqmean, sd = dqsd), col = "tomato")
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

The standard deviation measures the spread or variability of the data points around the mean (average fat calorie content). It quantifies how much individual values deviate from the mean value. The histogram closely resembles the curve and exhibits relatively few deviations, so, “calories from fat” data for Dairy Queen follows a nearly normal distribution.

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 data frame, it can be put directly into the sample argument and the data argument can be dropped.)

ggplot(data = dairy_queen, aes(sample = cal_fat)) + 
  geom_line(stat = "qq")

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

# Create a Q-Q plot for the simulated data
qqplot_sim_norm <- ggplot() +
  geom_qq(aes(sample = sim_norm)) +
  geom_qq_line() +
  labs(title = "Normal Q-Q Plot for Simulated Data")

qqplot_sim_norm

This Q-Q plot is to assess the normality of the “calories from fat” data in Dairy Queen and generate a random sample of normally distributed data using the ‘rnorm’ function. the “sim_norm” variable contains a random sample of data that follows a normal distribution with a mean and standard deviation matching those of the “calories from fat” data for Dairy queen. Most of the simulated data points mostly follow the line, QQ plot is approximately normal distributed.

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 the calories are nearly normal?

qqnormsim(sample = cal_fat, data = dairy_queen)

A multiple Q-Q plots are generated to compare the original data to several simulated normal data sets that helps us assess how well the original data conforms to a normal distribution in comparison to the simulated data.If the points in the Q-Q plot closely follow the reference line, the original data looks closely to the reference line as the simulated data Q-Q plots, Yes, the normal probability plot for cal-fat data looks similar to the plots created for the simulated data.

Exercise 5

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

dqmean1<- mean(mcdonalds$cal_fat)
dqsd1   <- sd(mcdonalds$cal_fat)
ggplot(data = mcdonalds, aes(x = cal_fat)) +
        geom_blank() +
        geom_histogram(aes(y = ..density..)) +
        stat_function(fun = dnorm, args = c(mean = dqmean1, sd = dqsd1), col = "tomato")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# Create a Q-Q plot for McDonald's data
ggplot(data = mcdonalds, aes(sample = cal_fat)) +
  geom_qq() +
  geom_qq_line() +
  labs(title = "Normal Q-Q Plot for Calories from Fat (McDonald's)")

qqnormsim(sample = cal_fat, data = mcdonalds)

The histogram somewhat resembles a normal distribution with appears to be uni-modal (one main peak). The cal_fat data from McDonald’s menus approximately follow a normal distribution, but, there are some deviations and non-normal characteristics (like right-skewed).

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?

Question 1. Calculates the theoretical probability that a Dairy Queen item has fewer than 600 calories from fat using the cumulative distribution function (CDF) of the normal distribution

Question 2. What is the empirical probability that a randomly chosen menu item from McDonald’s has between 200 and 600 calories from fat?

1 - pnorm(q = 600, mean = dqmean, sd = dqsd)
## [1] 0.01501523
dairy_queen %>% 
  filter(cal_fat < 600) %>%
  summarise(percent = n() / nrow(dairy_queen))
## # A tibble: 1 × 1
##   percent
##     <dbl>
## 1   0.952
mcdonalds %>% 
  filter(cal_fat >= 200 & cal_fat <= 600) %>%
  summarise(percent = n() / nrow(mcdonalds))
## # A tibble: 1 × 1
##   percent
##     <dbl>
## 1   0.561

Exercise 7

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

# Find mean and standard deviation for each restaurant
restaurant_summary <- fastfood %>%
  group_by(restaurant) %>%
  summarise(mean_sodium = mean(sodium), sd_sodium = sd(sodium))
restaurant_summary
## # A tibble: 8 × 3
##   restaurant  mean_sodium sd_sodium
##   <chr>             <dbl>     <dbl>
## 1 Arbys             1515.      664.
## 2 Burger King       1224.      500.
## 3 Chick Fil-A       1151.      727.
## 4 Dairy Queen       1182.      610.
## 5 Mcdonalds         1438.     1036.
## 6 Sonic             1351.      665.
## 7 Subway            1273.      744.
## 8 Taco Bell         1014.      474.
# Plot sodium distribution for each restaurant
ggplot(data = fastfood, aes(x = sodium)) +
  geom_histogram(aes(y = ..density..), bins = 20) +
  facet_wrap(~restaurant, scales = "free") +
  geom_density() +
  labs(title = "Sodium Distribution by Restaurant")

Arbys and Burger King restaurant’s distribution of sodium is the closest to normal.

Exercise 8

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

Some of the Sodium Distribution plots by Restaurant have a step wise pattern because type of data is discrete or categorical rather than continuous normal distribution.

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.

# create a new data set "Subway"
Subway <- fastfood %>%
  filter(restaurant == "Subway")
head(Subway)
## # A tibble: 6 × 17
##   restaurant item       calories cal_fat total_fat sat_fat trans_fat cholesterol
##   <chr>      <chr>         <dbl>   <dbl>     <dbl>   <dbl>     <dbl>       <dbl>
## 1 Subway     "6\" B.L.…      320      80         9       4         0          20
## 2 Subway     "Footlong…      640     160        18       8         0          40
## 3 Subway     "6\" BBQ …      430     160        18       6         0          50
## 4 Subway     "Footlong…      860     320        36      12         0         100
## 5 Subway     "6\" Big …      580     310        31      11         0          85
## 6 Subway     "Footlong…     1160     620        62      22         0         170
## # ℹ 9 more variables: sodium <dbl>, total_carb <dbl>, fiber <dbl>, sugar <dbl>,
## #   protein <dbl>, vit_a <dbl>, vit_c <dbl>, calcium <dbl>, salad <chr>
# Plot Total Carbohydrates distribution of Subway
ggplot(data = Subway, aes(x = sodium)) +
  geom_histogram(aes(y = ..density..), bins = 20) +
  facet_wrap(~restaurant, scales = "free") +
  geom_density() +
  labs(title = "Total Carbohydrates Distribution of Subway ")

# Create a Q-Q plot
ggplot(data = Subway, aes(sample = total_carb)) +
  geom_qq() +
  geom_qq_line() +
  labs(title = "Normal Q-Q Plot for Total Carbohydrates")

# Create a histogram
hist(Subway$total_carb)

According to the normal probability plot, we can clearly see that the “total carbohydrates” variable for Subway is right-skewed.

LS0tCnRpdGxlOiAiTGFiIDQ6IERpc3RyaWJ1dGlvbnMgb2YgUmFuZG9tIFZhcmlhYmxlcyAiCmF1dGhvcjogIkx3aW4gU2h3ZSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6IG9wZW5pbnRybzo6bGFiX3JlcG9ydAotLS0KCmBgYHtyIGxvYWQtcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KG9wZW5pbnRybykKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpgYGAKCiMjIyBFeGVyY2lzZSAxCgpNYWtlIGEgcGxvdCAob3IgcGxvdHMpIHRvIHZpc3VhbGl6ZSB0aGUgZGlzdHJpYnV0aW9ucyBvZiB0aGUgYW1vdW50IG9mIGNhbG9yaWVzIGZyb20gZmF0IG9mIHRoZSBvcHRpb25zIGZyb20gdGhlc2UgdHdvIHJlc3RhdXJhbnRzLiBIb3cgZG8gdGhlaXIgY2VudGVycywgc2hhcGVzLCBhbmQgc3ByZWFkcyBjb21wYXJlPwoKCmBgYHtyIHZpZXctZmlyc3QtZm9vZH0KI0xvYWQgImZhc3Rmb29kImRhdGFzZXQKZGF0YSgiZmFzdGZvb2QiLCBwYWNrYWdlPSdvcGVuaW50cm8nKQpoZWFkKGZhc3Rmb29kKQoKIyBjcmVhdGUgdHdvIG5ldyBkYXRhIHNldHMsICJtY2RvbmFsZHMiIGFuZCAiZGFpcnlfcXVlZW4sIgptY2RvbmFsZHMgPC0gZmFzdGZvb2QgJT4lCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIk1jZG9uYWxkcyIpCmhlYWQobWNkb25hbGRzKQoKZGFpcnlfcXVlZW4gPC0gZmFzdGZvb2QgJT4lCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkRhaXJ5IFF1ZWVuIikKaGVhZChkYWlyeV9xdWVlbikKCmhpc3QobWNkb25hbGRzJGNhbF9mYXQpCmhpc3QoZGFpcnlfcXVlZW4kY2FsX2ZhdCkKCmBgYAoKVGhlc2UgdHdvIGhpc3RvZ3JhbXMgc2hvdyBkaXN0cmlidXRpb24gb2YgY2FsX2ZhdCBmb3IgTWNkb25hbGRzIGFuZCBEYWlyeV9xdWVlbi4gTWNEb25hbGQncyBoYXMgYSBoaWdoZXIgZmF0IGNhbG9yaWVzIGNvbXBhcmVkIHRvIERhaXJ5IFF1ZWVuLiBCb3RoIGRpc3RyaWJ1dGlvbnMgYXJlIHJpZ2h0LXNrZXdlZCwgdGhpcyBtZWFucyB0aGF0IHRoZXJlIGFyZSBmZXcgaXRlbXMgd2l0aCB2ZXJ5IGhpZ2ggY2Fsb3JpZXMgZnJvbSBmYXQgaW4gdGhlIGRhdGEgc2V0LiBNY0RvbmFsZCdzIGhpc3RvZ3JhbSBpbmNyZWFzZXMgaW4gYmluIHdpZHRoIG9mIDIwMCBjYWxvcmllcywgd2hlcmVhcyBEYWlyeSBRdWVlbidzIGhpc3RvZ3JhbSBpbmNyZWFzZXMgaW4gYmluIHdpZHRoIG9mIDEwMCBjYWxvcmllcy4KCiMjIyBFeGVyY2lzZSAyCgpCYXNlZCBvbiB0aGUgdGhpcyBwbG90LCBkb2VzIGl0IGFwcGVhciB0aGF0IHRoZSBkYXRhIGZvbGxvdyBhIG5lYXJseSBub3JtYWwgZGlzdHJpYnV0aW9uPwoKYGBge3Igbm9ybWFsLWRpc3RyaWJ1dGlvbn0KZHFtZWFuIDwtIG1lYW4oZGFpcnlfcXVlZW4kY2FsX2ZhdCkKZHFzZCAgIDwtIHNkKGRhaXJ5X3F1ZWVuJGNhbF9mYXQpCmdncGxvdChkYXRhID0gZGFpcnlfcXVlZW4sIGFlcyh4ID0gY2FsX2ZhdCkpICsKICAgICAgICBnZW9tX2JsYW5rKCkgKwogICAgICAgIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pKSArCiAgICAgICAgc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgYXJncyA9IGMobWVhbiA9IGRxbWVhbiwgc2QgPSBkcXNkKSwgY29sID0gInRvbWF0byIpCmBgYAoKClRoZSBzdGFuZGFyZCBkZXZpYXRpb24gbWVhc3VyZXMgdGhlIHNwcmVhZCBvciB2YXJpYWJpbGl0eSBvZiB0aGUgZGF0YSBwb2ludHMgYXJvdW5kIHRoZSBtZWFuIChhdmVyYWdlIGZhdCBjYWxvcmllIGNvbnRlbnQpLiBJdCBxdWFudGlmaWVzIGhvdyBtdWNoIGluZGl2aWR1YWwgdmFsdWVzIGRldmlhdGUgZnJvbSB0aGUgbWVhbiB2YWx1ZS4gClRoZSBoaXN0b2dyYW0gY2xvc2VseSByZXNlbWJsZXMgdGhlIGN1cnZlIGFuZCBleGhpYml0cyByZWxhdGl2ZWx5IGZldyBkZXZpYXRpb25zLCBzbywgImNhbG9yaWVzIGZyb20gZmF0IiBkYXRhIGZvciBEYWlyeSBRdWVlbiBmb2xsb3dzIGEgbmVhcmx5IG5vcm1hbCBkaXN0cmlidXRpb24uCgoKIyMjIEV4ZXJjaXNlIDMKCk1ha2UgYSBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdCBvZiBzaW1fbm9ybS4gRG8gYWxsIG9mIHRoZSBwb2ludHMgZmFsbCBvbiB0aGUgbGluZT8gSG93IGRvZXMgdGhpcyBwbG90IGNvbXBhcmUgdG8gdGhlIHByb2JhYmlsaXR5IHBsb3QgZm9yIHRoZSByZWFsIGRhdGE/IChTaW5jZSBzaW1fbm9ybSBpcyBub3QgYSBkYXRhIGZyYW1lLCBpdCBjYW4gYmUgcHV0IGRpcmVjdGx5IGludG8gdGhlIHNhbXBsZSBhcmd1bWVudCBhbmQgdGhlIGRhdGEgYXJndW1lbnQgY2FuIGJlIGRyb3BwZWQuKQoKYGBge3IgUVEtcGxvdH0KZ2dwbG90KGRhdGEgPSBkYWlyeV9xdWVlbiwgYWVzKHNhbXBsZSA9IGNhbF9mYXQpKSArIAogIGdlb21fbGluZShzdGF0ID0gInFxIikKc2ltX25vcm0gPC0gcm5vcm0obiA9IG5yb3coZGFpcnlfcXVlZW4pLCBtZWFuID0gZHFtZWFuLCBzZCA9IGRxc2QpCgojIENyZWF0ZSBhIFEtUSBwbG90IGZvciB0aGUgc2ltdWxhdGVkIGRhdGEKcXFwbG90X3NpbV9ub3JtIDwtIGdncGxvdCgpICsKICBnZW9tX3FxKGFlcyhzYW1wbGUgPSBzaW1fbm9ybSkpICsKICBnZW9tX3FxX2xpbmUoKSArCiAgbGFicyh0aXRsZSA9ICJOb3JtYWwgUS1RIFBsb3QgZm9yIFNpbXVsYXRlZCBEYXRhIikKCnFxcGxvdF9zaW1fbm9ybQoKYGBgCgoKVGhpcyBRLVEgcGxvdCBpcyB0byBhc3Nlc3MgdGhlIG5vcm1hbGl0eSBvZiB0aGUgImNhbG9yaWVzIGZyb20gZmF0IiBkYXRhIGluIERhaXJ5IFF1ZWVuIGFuZCBnZW5lcmF0ZSBhIHJhbmRvbSBzYW1wbGUgb2Ygbm9ybWFsbHkgZGlzdHJpYnV0ZWQgZGF0YSB1c2luZyB0aGUgJ3Jub3JtJyBmdW5jdGlvbi4gdGhlICJzaW1fbm9ybSIgdmFyaWFibGUgY29udGFpbnMgYSByYW5kb20gc2FtcGxlIG9mIGRhdGEgdGhhdCBmb2xsb3dzIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiB3aXRoIGEgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIG1hdGNoaW5nIHRob3NlIG9mIHRoZSAiY2Fsb3JpZXMgZnJvbSBmYXQiIGRhdGEgZm9yIERhaXJ5IHF1ZWVuLiBNb3N0IG9mIHRoZSBzaW11bGF0ZWQgZGF0YSBwb2ludHMgbW9zdGx5IGZvbGxvdyB0aGUgbGluZSwgUVEgcGxvdCBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbCBkaXN0cmlidXRlZC4KCgojIyMgRXhlcmNpc2UgNAoKRG9lcyB0aGUgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3QgZm9yIHRoZSBjYWxvcmllcyBmcm9tIGZhdCBsb29rIHNpbWlsYXIgdG8gdGhlIHBsb3RzIGNyZWF0ZWQgZm9yIHRoZSBzaW11bGF0ZWQgZGF0YT8gVGhhdCBpcywgZG8gdGhlIHBsb3RzIHByb3ZpZGUgZXZpZGVuY2UgdGhhdCB0aGUgY2Fsb3JpZXMgYXJlIG5lYXJseSBub3JtYWw/CgpgYGB7ciBub3JtLXByb2J9CnFxbm9ybXNpbShzYW1wbGUgPSBjYWxfZmF0LCBkYXRhID0gZGFpcnlfcXVlZW4pCmBgYAoKQSBtdWx0aXBsZSBRLVEgcGxvdHMgYXJlIGdlbmVyYXRlZCB0byBjb21wYXJlIHRoZSBvcmlnaW5hbCBkYXRhIHRvIHNldmVyYWwgc2ltdWxhdGVkIG5vcm1hbCBkYXRhIHNldHMgdGhhdCBoZWxwcyB1cyBhc3Nlc3MgaG93IHdlbGwgdGhlIG9yaWdpbmFsIGRhdGEgY29uZm9ybXMgdG8gYSBub3JtYWwgZGlzdHJpYnV0aW9uIGluIGNvbXBhcmlzb24gdG8gdGhlIHNpbXVsYXRlZCBkYXRhLklmIHRoZSBwb2ludHMgaW4gdGhlIFEtUSBwbG90IGNsb3NlbHkgZm9sbG93IHRoZSByZWZlcmVuY2UgbGluZSwgdGhlIG9yaWdpbmFsIGRhdGEgbG9va3MgY2xvc2VseSB0byB0aGUgcmVmZXJlbmNlIGxpbmUgYXMgdGhlIHNpbXVsYXRlZCBkYXRhIFEtUSBwbG90cywKWWVzLCB0aGUgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3QgZm9yIGNhbC1mYXQgZGF0YSBsb29rcyBzaW1pbGFyIHRvIHRoZSBwbG90cyBjcmVhdGVkIGZvciB0aGUgc2ltdWxhdGVkIGRhdGEuCgojIyMgRXhlcmNpc2UgNQoKVXNpbmcgdGhlIHNhbWUgdGVjaG5pcXVlLCBkZXRlcm1pbmUgd2hldGhlciBvciBub3QgdGhlIGNhbG9yaWVzIGZyb20gTWNEb25hbGTigJlzIG1lbnUgYXBwZWFyIHRvIGNvbWUgZnJvbSBhIG5vcm1hbCBkaXN0cmlidXRpb24uCgpgYGB7ciBRUS1NY0RvbmFsZH0KZHFtZWFuMTwtIG1lYW4obWNkb25hbGRzJGNhbF9mYXQpCmRxc2QxICAgPC0gc2QobWNkb25hbGRzJGNhbF9mYXQpCmdncGxvdChkYXRhID0gbWNkb25hbGRzLCBhZXMoeCA9IGNhbF9mYXQpKSArCiAgICAgICAgZ2VvbV9ibGFuaygpICsKICAgICAgICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSkgKwogICAgICAgIHN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBkcW1lYW4xLCBzZCA9IGRxc2QxKSwgY29sID0gInRvbWF0byIpCgoKIyBDcmVhdGUgYSBRLVEgcGxvdCBmb3IgTWNEb25hbGQncyBkYXRhCmdncGxvdChkYXRhID0gbWNkb25hbGRzLCBhZXMoc2FtcGxlID0gY2FsX2ZhdCkpICsKICBnZW9tX3FxKCkgKwogIGdlb21fcXFfbGluZSgpICsKICBsYWJzKHRpdGxlID0gIk5vcm1hbCBRLVEgUGxvdCBmb3IgQ2Fsb3JpZXMgZnJvbSBGYXQgKE1jRG9uYWxkJ3MpIikKCnFxbm9ybXNpbShzYW1wbGUgPSBjYWxfZmF0LCBkYXRhID0gbWNkb25hbGRzKQoKYGBgCgpUaGUgaGlzdG9ncmFtIHNvbWV3aGF0IHJlc2VtYmxlcyBhIG5vcm1hbCBkaXN0cmlidXRpb24gd2l0aCBhcHBlYXJzIHRvIGJlIHVuaS1tb2RhbCAob25lIG1haW4gcGVhaykuIFRoZSBjYWxfZmF0IGRhdGEgZnJvbSBNY0RvbmFsZCdzIG1lbnVzIGFwcHJveGltYXRlbHkgZm9sbG93IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgYnV0LCB0aGVyZSBhcmUgc29tZSBkZXZpYXRpb25zIGFuZCBub24tbm9ybWFsIGNoYXJhY3RlcmlzdGljcyAobGlrZSByaWdodC1za2V3ZWQpLgoKCiMjIyBFeGVyY2lzZSA2CgpXcml0ZSBvdXQgdHdvIHByb2JhYmlsaXR5IHF1ZXN0aW9ucyB0aGF0IHlvdSB3b3VsZCBsaWtlIHRvIGFuc3dlciBhYm91dCBhbnkgb2YgdGhlIHJlc3RhdXJhbnRzIGluIHRoaXMgZGF0YXNldC4gQ2FsY3VsYXRlIHRob3NlIHByb2JhYmlsaXRpZXMgdXNpbmcgYm90aCB0aGUgdGhlb3JldGljYWwgbm9ybWFsIGRpc3RyaWJ1dGlvbiBhcyB3ZWxsIGFzIHRoZSBlbXBpcmljYWwgZGlzdHJpYnV0aW9uIChmb3VyIHByb2JhYmlsaXRpZXMgaW4gYWxsKS4gV2hpY2ggb25lIGhhZCBhIGNsb3NlciBhZ3JlZW1lbnQgYmV0d2VlbiB0aGUgdHdvIG1ldGhvZHM/CgojIyMjIFF1ZXN0aW9uIDEuIENhbGN1bGF0ZXMgdGhlIHRoZW9yZXRpY2FsIHByb2JhYmlsaXR5IHRoYXQgYSBEYWlyeSBRdWVlbiBpdGVtIGhhcyBmZXdlciB0aGFuIDYwMCBjYWxvcmllcyBmcm9tIGZhdCB1c2luZyB0aGUgY3VtdWxhdGl2ZSBkaXN0cmlidXRpb24gZnVuY3Rpb24gKENERikgb2YgdGhlIG5vcm1hbCBkaXN0cmlidXRpb24KCiMjIyMgUXVlc3Rpb24gMi4gV2hhdCBpcyB0aGUgZW1waXJpY2FsIHByb2JhYmlsaXR5IHRoYXQgYSByYW5kb21seSBjaG9zZW4gbWVudSBpdGVtIGZyb20gTWNEb25hbGQncyBoYXMgYmV0d2VlbiAyMDAgYW5kIDYwMCBjYWxvcmllcyBmcm9tIGZhdD8KCmBgYHtyIHBub3JtLWRpc3RyaWJ1dGlvbn0KMSAtIHBub3JtKHEgPSA2MDAsIG1lYW4gPSBkcW1lYW4sIHNkID0gZHFzZCkKCmRhaXJ5X3F1ZWVuICU+JSAKICBmaWx0ZXIoY2FsX2ZhdCA8IDYwMCkgJT4lCiAgc3VtbWFyaXNlKHBlcmNlbnQgPSBuKCkgLyBucm93KGRhaXJ5X3F1ZWVuKSkKCgptY2RvbmFsZHMgJT4lIAogIGZpbHRlcihjYWxfZmF0ID49IDIwMCAmIGNhbF9mYXQgPD0gNjAwKSAlPiUKICBzdW1tYXJpc2UocGVyY2VudCA9IG4oKSAvIG5yb3cobWNkb25hbGRzKSkKCmBgYAoKCiMjIyBFeGVyY2lzZSA3CgpOb3cgbGV04oCZcyBjb25zaWRlciBzb21lIG9mIHRoZSBvdGhlciB2YXJpYWJsZXMgaW4gdGhlIGRhdGEgc2V0LiBPdXQgb2YgYWxsIHRoZSBkaWZmZXJlbnQgcmVzdGF1cmFudHMsIHdoaWNoIG9uZXPigJkgZGlzdHJpYnV0aW9uIGlzIHRoZSBjbG9zZXN0IHRvIG5vcm1hbCBmb3Igc29kaXVtPwoKYGBge3Igc29kaXVtLWRpc3RyaWJ1dGlvbn0KIyBGaW5kIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBmb3IgZWFjaCByZXN0YXVyYW50CnJlc3RhdXJhbnRfc3VtbWFyeSA8LSBmYXN0Zm9vZCAlPiUKICBncm91cF9ieShyZXN0YXVyYW50KSAlPiUKICBzdW1tYXJpc2UobWVhbl9zb2RpdW0gPSBtZWFuKHNvZGl1bSksIHNkX3NvZGl1bSA9IHNkKHNvZGl1bSkpCnJlc3RhdXJhbnRfc3VtbWFyeQoKIyBQbG90IHNvZGl1bSBkaXN0cmlidXRpb24gZm9yIGVhY2ggcmVzdGF1cmFudApnZ3Bsb3QoZGF0YSA9IGZhc3Rmb29kLCBhZXMoeCA9IHNvZGl1bSkpICsKICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSwgYmlucyA9IDIwKSArCiAgZmFjZXRfd3JhcCh+cmVzdGF1cmFudCwgc2NhbGVzID0gImZyZWUiKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGxhYnModGl0bGUgPSAiU29kaXVtIERpc3RyaWJ1dGlvbiBieSBSZXN0YXVyYW50IikKCmBgYAoKQXJieXMgYW5kIEJ1cmdlciBLaW5nIHJlc3RhdXJhbnQncyBkaXN0cmlidXRpb24gb2Ygc29kaXVtIGlzIHRoZSBjbG9zZXN0IHRvIG5vcm1hbC4gCgoKIyMjIEV4ZXJjaXNlIDgKCk5vdGUgdGhhdCBzb21lIG9mIHRoZSBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdHMgZm9yIHNvZGl1bSBkaXN0cmlidXRpb25zIHNlZW0gdG8gaGF2ZSBhIHN0ZXAgd2lzZSBwYXR0ZXJuLiB3aHkgZG8geW91IHRoaW5rIHRoaXMgbWlnaHQgYmUgdGhlIGNhc2U/CgpTb21lIG9mIHRoZSBTb2RpdW0gRGlzdHJpYnV0aW9uIHBsb3RzIGJ5IFJlc3RhdXJhbnQgaGF2ZSBhIHN0ZXAgd2lzZSBwYXR0ZXJuIGJlY2F1c2UgdHlwZSBvZiBkYXRhIGlzIGRpc2NyZXRlIG9yIGNhdGVnb3JpY2FsIHJhdGhlciB0aGFuIGNvbnRpbnVvdXMgbm9ybWFsIGRpc3RyaWJ1dGlvbi4KCgojIyMgRXhlcmNpc2UgOQoKQXMgeW91IGNhbiBzZWUsIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90cyBjYW4gYmUgdXNlZCBib3RoIHRvIGFzc2VzcyBub3JtYWxpdHkgYW5kIHZpc3VhbGl6ZSBza2V3bmVzcy4gTWFrZSBhIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90IGZvciB0aGUgdG90YWwgY2FyYm9oeWRyYXRlcyBmcm9tIGEgcmVzdGF1cmFudCBvZiB5b3VyIGNob2ljZS4gQmFzZWQgb24gdGhpcyBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdCwgaXMgdGhpcyB2YXJpYWJsZSBsZWZ0IHNrZXdlZCwgc3ltbWV0cmljLCBvciByaWdodCBza2V3ZWQ/IFVzZSBhIGhpc3RvZ3JhbSB0byBjb25maXJtIHlvdXIgZmluZGluZ3MuCgpgYGB7ciBjYXJib2h5ZHJhdGVzfQojIGNyZWF0ZSBhIG5ldyBkYXRhIHNldCAiU3Vid2F5IgpTdWJ3YXkgPC0gZmFzdGZvb2QgJT4lCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIlN1YndheSIpCmhlYWQoU3Vid2F5KQoKIyBQbG90IFRvdGFsIENhcmJvaHlkcmF0ZXMgZGlzdHJpYnV0aW9uIG9mIFN1YndheQpnZ3Bsb3QoZGF0YSA9IFN1YndheSwgYWVzKHggPSBzb2RpdW0pKSArCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHkgPSAuLmRlbnNpdHkuLiksIGJpbnMgPSAyMCkgKwogIGZhY2V0X3dyYXAofnJlc3RhdXJhbnQsIHNjYWxlcyA9ICJmcmVlIikgKwogIGdlb21fZGVuc2l0eSgpICsKICBsYWJzKHRpdGxlID0gIlRvdGFsIENhcmJvaHlkcmF0ZXMgRGlzdHJpYnV0aW9uIG9mIFN1YndheSAiKQoKIyBDcmVhdGUgYSBRLVEgcGxvdApnZ3Bsb3QoZGF0YSA9IFN1YndheSwgYWVzKHNhbXBsZSA9IHRvdGFsX2NhcmIpKSArCiAgZ2VvbV9xcSgpICsKICBnZW9tX3FxX2xpbmUoKSArCiAgbGFicyh0aXRsZSA9ICJOb3JtYWwgUS1RIFBsb3QgZm9yIFRvdGFsIENhcmJvaHlkcmF0ZXMiKQoKIyBDcmVhdGUgYSBoaXN0b2dyYW0KaGlzdChTdWJ3YXkkdG90YWxfY2FyYikKCgpgYGAKCgpBY2NvcmRpbmcgdG8gdGhlIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90LCB3ZSBjYW4gY2xlYXJseSBzZWUgdGhhdCB0aGUgInRvdGFsIGNhcmJvaHlkcmF0ZXMiIHZhcmlhYmxlIGZvciBTdWJ3YXkgaXMgcmlnaHQtc2tld2VkLgoKCgoK