library(tidyverse)
library(openintro)
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?

The distribution of the McDonald’s data has a center around 250, it is right-skewed, and it has a wide spread. The distribution of the Dairy Queen data has a center somewhere between 220 and 260, is slightly more symmetrical than the McDonald’s distribution, and has less spread than the McDonald’s distribution. The center for the Dairy Queen distribution is not obvious from the graph, but the mean was about 260, and the median was 220.

data("fastfood", package='openintro')
mcdonalds <- fastfood %>%
  filter(restaurant == "Mcdonalds")
dairy_queen <- fastfood %>%
  filter(restaurant == "Dairy Queen")
ggplot(mcdonalds, aes(x = cal_fat)) +
  geom_histogram(bins = 35)
ggplot(dairy_queen, aes(x = cal_fat)) +
  geom_histogram(bins = 35)

print("McDonald's")
## [1] "McDonald's"
mean(mcdonalds$cal_fat)
## [1] 285.614
median(mcdonalds$cal_fat)
## [1] 240
sd(mcdonalds$cal_fat)
## [1] 220.8993
var(mcdonalds$cal_fat)
## [1] 48796.49
summary(mcdonalds$cal_fat)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    50.0   160.0   240.0   285.6   320.0  1270.0
print("Dairy Queen")
## [1] "Dairy Queen"
mean(dairy_queen$cal_fat)
## [1] 260.4762
median(dairy_queen$cal_fat)
## [1] 220
sd(dairy_queen$cal_fat)
## [1] 156.4851
var(dairy_queen$cal_fat)
## [1] 24487.57
summary(dairy_queen$cal_fat)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     0.0   160.0   220.0   260.5   310.0   670.0

Exercise 2

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

The data does not appear to follow a normal distribution. The shape of the curve is similar to the shape of the bars, but the height of the curve is much lower than the height of the bars. I would not claim that this is nearly a 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`.

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.)

Not all of the points fall on the line as seen in the first Q-Q plot. Most of the middle values fall on the line, but the ones near both ends seem to stray.

This plot is more normally distributed than the plot for the real data. The second Q-Q plot below shows many values far from the line on the right side of the plot, indicating it is not normally distributed.

sim_norm <- rnorm(n = nrow(dairy_queen), mean = dqmean, sd = dqsd)
ggplot(mapping = aes(sample = sim_norm)) + 
  geom_line(stat = "qq") 

qqnorm(sim_norm)
qqline(sim_norm)

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

qqnorm(dairy_queen$cal_fat)
qqline(dairy_queen$cal_fat)

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?

Yes, it looks pretty similar to the plots created for the simulated data. I would say that this does provide evidence that the calories are nearly normal because the original data has a graph very similar to all the other plot, and most of the data points in each of the graphs fall along the line. It is not exactly normal, but it is pretty close.

openintro::qqnormsim(sample = cal_fat, data = dairy_queen)

Exercise 5

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

The data from McDonald’s does not resemble the other graphs. I would say it is not normally distributed because of the differences and because many of the data points in the original graph do not fall on the line.

openintro::qqnormsim(sample = cal_fat, data = mcdonalds)

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?

  1. If you were to randomly order an item from the Chick Fil-A menu, what is the probability of choosing an item with a cholesterol greater than 100 mg?

    Theoretical normal distribution probability: 0.3291412 Empirical distribution probability: 0.1486697 Difference (absolute value): 0.2180301

  2. If you were to randomly order an item from Subway, what is the probability of choosing an item that contained total carbs less than 20 g?

    Theoretical normal distribution probability: 0.1111111 Empirical distribution probability: 0.2291667 Difference (absolute value): 0.08049694

The second question had more similar results than the first question. This would typically indicate that the data about total carbs for Subway was closer to a normal distribution than the data about cholesterol for Chick Fil-A. However, the Q-Q plots show that the chick Fil-A data about cholesterol had an outlier that affected the normality of the data, and the Q-Q plot for Subway was not normal.

chickFilA <- fastfood |> filter(restaurant == "Chick Fil-A")
chmean <- mean(chickFilA$cholesterol)
chsd <- sd(chickFilA$cholesterol)
(chProb <- 1 - pnorm(q = 100, mean = chmean, sd = chsd))
## [1] 0.3291412
(chActualProb <- chickFilA |>
  filter(cholesterol > 100) |>
  summarise(percent = n() / nrow(chickFilA)))
## # A tibble: 1 Ă— 1
##   percent
##     <dbl>
## 1   0.111
subway <- fastfood |> filter(restaurant == "Subway")
smean <- mean(subway$total_carb)
ssd <- sd(subway$total_carb)
(subProb <- pnorm(q = 20, mean = smean, sd = ssd))
## [1] 0.1486697
(subActualProb <- subway |>
  filter(total_carb < 20) |>
  summarise(percent = n() / nrow(subway)))
## # A tibble: 1 Ă— 1
##   percent
##     <dbl>
## 1   0.229
chProb - chActualProb
##     percent
## 1 0.2180301
subProb - subActualProb
##       percent
## 1 -0.08049694
qqnorm(chickFilA$cholesterol)
qqline(chickFilA$cholesterol)

qqnorm(subway$total_carb)
qqline(subway$total_carb)

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?

Arby’s had the closest to normal distribution for sodium. I verified my assumption with the Shapiro-Wilk Test. The p-value for Arby’s was greater than 0.05, just like Burger King. Since it had a greater p-value than Arby’s I decided it was the most normal.

unique(fastfood$restaurant)
## [1] "Mcdonalds"   "Chick Fil-A" "Sonic"       "Arbys"       "Burger King"
## [6] "Dairy Queen" "Subway"      "Taco Bell"
sonic <- fastfood |> filter(restaurant == "Sonic")
arbys <-fastfood |> filter(restaurant == "Arbys")
bk <- fastfood |> filter(restaurant == "Burger King")
tacoBell <- fastfood |> filter(restaurant == "Taco Bell")

qqnorm(mcdonalds$sodium)
qqline(mcdonalds$sodium)

shapiro.test(mcdonalds$sodium)
## 
##  Shapiro-Wilk normality test
## 
## data:  mcdonalds$sodium
## W = 0.76922, p-value = 4.458e-08
qqnorm(chickFilA$sodium)
qqline(chickFilA$sodium)

shapiro.test(chickFilA$sodium)
## 
##  Shapiro-Wilk normality test
## 
## data:  chickFilA$sodium
## W = 0.86663, p-value = 0.002503
qqnorm(sonic$sodium)
qqline(sonic$sodium)

shapiro.test(sonic$sodium)
## 
##  Shapiro-Wilk normality test
## 
## data:  sonic$sodium
## W = 0.82286, p-value = 1.784e-06
qqnorm(arbys$sodium)
qqline(arbys$sodium)

shapiro.test(arbys$sodium)
## 
##  Shapiro-Wilk normality test
## 
## data:  arbys$sodium
## W = 0.97073, p-value = 0.1985
qqnorm(bk$sodium)
qqline(bk$sodium)

shapiro.test(bk$sodium)
## 
##  Shapiro-Wilk normality test
## 
## data:  bk$sodium
## W = 0.97291, p-value = 0.1331
qqnorm(dairy_queen$sodium)
qqline(dairy_queen$sodium)

shapiro.test(dairy_queen$sodium)
## 
##  Shapiro-Wilk normality test
## 
## data:  dairy_queen$sodium
## W = 0.84504, p-value = 4.715e-05
qqnorm(subway$sodium)
qqline(subway$sodium)

shapiro.test(subway$sodium)
## 
##  Shapiro-Wilk normality test
## 
## data:  subway$sodium
## W = 0.92175, p-value = 2.515e-05
qqnorm(tacoBell$sodium)
qqline(tacoBell$sodium)

shapiro.test(tacoBell$sodium)
## 
##  Shapiro-Wilk normality test
## 
## data:  tacoBell$sodium
## W = 0.95501, p-value = 0.000699

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?

This might be the case because of the different categories of food. Sandwiches probably have a range of sodium, fries probably have a different range of sodium, salads probably have a different range of sodium, and so on. Since different categories of food likely have ranges of sodium that don’ overlap much, the pattern appears step-wise.

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.

My guess was right-skewed because there seemed to be a tail to the right and above the line in the normal probability plot. The graph confirms this because it is right-skewed with the tail to the right.

qqnorm(mcdonalds$total_carb)
qqline(mcdonalds$total_carb)

ggplot(mcdonalds, aes(x = total_carb)) +
  geom_histogram(bins = 50)

LS0tDQp0aXRsZTogIkxhYiA0OiBQcm9iYWJpbGl0eSBEaXN0cmlidXRpb25zIg0Kc3VidGl0bGU6ICJEQVRBIDYwNiAtIFN0YXRpc3RpY3MgJiBQcm9iYWJpbGl0eSINCmF1dGhvcjogIkp1bGlhIEZlcnJpcyINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDogb3BlbmludHJvOjpsYWJfcmVwb3J0DQotLS0NCg0KYGBge3IgbG9hZC1wYWNrYWdlcywgbWVzc2FnZT1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShvcGVuaW50cm8pDQpsaWJyYXJ5KGdncGxvdDIpDQpgYGANCg0KIyMgRXhlcmNpc2UgMQ0KIyMjIE1ha2UgYSBwbG90IChvciBwbG90cykgdG8gdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb25zIG9mIHRoZSBhbW91bnQgb2YgY2Fsb3JpZXMgZnJvbSBmYXQgb2YgdGhlIG9wdGlvbnMgZnJvbSB0aGVzZSB0d28gcmVzdGF1cmFudHMuICBIb3cgZG8gdGhlaXIgY2VudGVycywgc2hhcGVzLCBhbmQgc3ByZWFkcyBjb21wYXJlPw0KDQpUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBNY0RvbmFsZCdzIGRhdGEgaGFzIGEgY2VudGVyIGFyb3VuZCAyNTAsIGl0IGlzIHJpZ2h0LXNrZXdlZCwgYW5kIGl0IGhhcyBhIHdpZGUgc3ByZWFkLiBUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBEYWlyeSBRdWVlbiBkYXRhIGhhcyBhIGNlbnRlciBzb21ld2hlcmUgYmV0d2VlbiAyMjAgYW5kIDI2MCwgaXMgc2xpZ2h0bHkgbW9yZSBzeW1tZXRyaWNhbCB0aGFuIHRoZSBNY0RvbmFsZCdzIGRpc3RyaWJ1dGlvbiwgYW5kIGhhcyBsZXNzIHNwcmVhZCB0aGFuIHRoZSBNY0RvbmFsZCdzIGRpc3RyaWJ1dGlvbi4gVGhlIGNlbnRlciBmb3IgdGhlIERhaXJ5IFF1ZWVuIGRpc3RyaWJ1dGlvbiBpcyBub3Qgb2J2aW91cyBmcm9tIHRoZSBncmFwaCwgYnV0IHRoZSBtZWFuIHdhcyBhYm91dCAyNjAsIGFuZCB0aGUgbWVkaWFuIHdhcyAyMjAuDQoNCmBgYHtyIHZpZXctZ2lybHMtY291bnRzLCBmaWcuc2hvdz0iaG9sZCIsIG91dC53aWR0aD0iNTAlIn0NCmRhdGEoImZhc3Rmb29kIiwgcGFja2FnZT0nb3BlbmludHJvJykNCm1jZG9uYWxkcyA8LSBmYXN0Zm9vZCAlPiUNCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIk1jZG9uYWxkcyIpDQpkYWlyeV9xdWVlbiA8LSBmYXN0Zm9vZCAlPiUNCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkRhaXJ5IFF1ZWVuIikNCmdncGxvdChtY2RvbmFsZHMsIGFlcyh4ID0gY2FsX2ZhdCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDM1KQ0KZ2dwbG90KGRhaXJ5X3F1ZWVuLCBhZXMoeCA9IGNhbF9mYXQpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbnMgPSAzNSkNCg0KcHJpbnQoIk1jRG9uYWxkJ3MiKQ0KbWVhbihtY2RvbmFsZHMkY2FsX2ZhdCkNCm1lZGlhbihtY2RvbmFsZHMkY2FsX2ZhdCkNCnNkKG1jZG9uYWxkcyRjYWxfZmF0KQ0KdmFyKG1jZG9uYWxkcyRjYWxfZmF0KQ0Kc3VtbWFyeShtY2RvbmFsZHMkY2FsX2ZhdCkNCg0KcHJpbnQoIkRhaXJ5IFF1ZWVuIikNCm1lYW4oZGFpcnlfcXVlZW4kY2FsX2ZhdCkNCm1lZGlhbihkYWlyeV9xdWVlbiRjYWxfZmF0KQ0Kc2QoZGFpcnlfcXVlZW4kY2FsX2ZhdCkNCnZhcihkYWlyeV9xdWVlbiRjYWxfZmF0KQ0Kc3VtbWFyeShkYWlyeV9xdWVlbiRjYWxfZmF0KQ0KYGBgDQoNCg0KIyMgRXhlcmNpc2UgMg0KIyMjIEJhc2VkIG9uIHRoZSB0aGlzIHBsb3QsIGRvZXMgaXQgYXBwZWFyIHRoYXQgdGhlIGRhdGEgZm9sbG93IGEgbmVhcmx5IG5vcm1hbCBkaXN0cmlidXRpb24/DQoNClRoZSBkYXRhIGRvZXMgbm90IGFwcGVhciB0byBmb2xsb3cgYSBub3JtYWwgZGlzdHJpYnV0aW9uLiBUaGUgc2hhcGUgb2YgdGhlIGN1cnZlIGlzIHNpbWlsYXIgdG8gdGhlIHNoYXBlIG9mIHRoZSBiYXJzLCBidXQgdGhlIGhlaWdodCBvZiB0aGUgY3VydmUgaXMgbXVjaCBsb3dlciB0aGFuIHRoZSBoZWlnaHQgb2YgdGhlIGJhcnMuIEkgd291bGQgbm90IGNsYWltIHRoYXQgdGhpcyBpcyBuZWFybHkgYSBub3JtYWwgZGlzdHJpYnV0aW9uLg0KDQpgYGB7ciB0cmVuZC1naXJsc30NCmRxbWVhbiA8LSBtZWFuKGRhaXJ5X3F1ZWVuJGNhbF9mYXQpDQpkcXNkICAgPC0gc2QoZGFpcnlfcXVlZW4kY2FsX2ZhdCkNCmdncGxvdChkYXRhID0gZGFpcnlfcXVlZW4sIGFlcyh4ID0gY2FsX2ZhdCkpICsNCiAgICAgICAgZ2VvbV9ibGFuaygpICsNCiAgICAgICAgZ2VvbV9oaXN0b2dyYW0oYWVzKHkgPSAuLmRlbnNpdHkuLikpICsNCiAgICAgICAgc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgYXJncyA9IGMobWVhbiA9IGRxbWVhbiwgc2QgPSBkcXNkKSwgY29sID0gInRvbWF0byIpDQpgYGANCg0KDQojIyBFeGVyY2lzZSAzDQojIyMgTWFrZSBhIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90IG9mIHNpbV9ub3JtLiAgRG8gYWxsIG9mIHRoZSBwb2ludHMgZmFsbCBvbiB0aGUgbGluZT8gIEhvdyBkb2VzIHRoaXMgcGxvdCBjb21wYXJlIHRvIHRoZSBwcm9iYWJpbGl0eSBwbG90IGZvciB0aGUgcmVhbCBkYXRhPyAoU2luY2Ugc2ltX25vcm0gaXMgbm90IGEgZGF0YSBmcmFtZSwgaXQgY2FuIGJlIHB1dCBkaXJlY3RseSBpbnRvIHRoZSBzYW1wbGUgYXJndW1lbnQgYW5kIHRoZSBkYXRhIGFyZ3VtZW50IGNhbiBiZSBkcm9wcGVkLikNCg0KTm90IGFsbCBvZiB0aGUgcG9pbnRzIGZhbGwgb24gdGhlIGxpbmUgYXMgc2VlbiBpbiB0aGUgZmlyc3QgUS1RIHBsb3QuIE1vc3Qgb2YgdGhlIG1pZGRsZSB2YWx1ZXMgZmFsbCBvbiB0aGUgbGluZSwgYnV0IHRoZSBvbmVzIG5lYXIgYm90aCBlbmRzIHNlZW0gdG8gc3RyYXkuIA0KDQpUaGlzIHBsb3QgaXMgbW9yZSBub3JtYWxseSBkaXN0cmlidXRlZCB0aGFuIHRoZSBwbG90IGZvciB0aGUgcmVhbCBkYXRhLiBUaGUgc2Vjb25kIFEtUSBwbG90IGJlbG93IHNob3dzIG1hbnkgdmFsdWVzIGZhciBmcm9tIHRoZSBsaW5lIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBwbG90LCBpbmRpY2F0aW5nIGl0IGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZC4NCg0KYGBge3IgcGxvdC1wcm9wLWJveXMtYXJidXRobm90fQ0Kc2ltX25vcm0gPC0gcm5vcm0obiA9IG5yb3coZGFpcnlfcXVlZW4pLCBtZWFuID0gZHFtZWFuLCBzZCA9IGRxc2QpDQpnZ3Bsb3QobWFwcGluZyA9IGFlcyhzYW1wbGUgPSBzaW1fbm9ybSkpICsgDQogIGdlb21fbGluZShzdGF0ID0gInFxIikgDQpxcW5vcm0oc2ltX25vcm0pDQpxcWxpbmUoc2ltX25vcm0pDQoNCmdncGxvdChkYXRhID0gZGFpcnlfcXVlZW4sIGFlcyhzYW1wbGUgPSBjYWxfZmF0KSkgKyANCiAgZ2VvbV9saW5lKHN0YXQgPSAicXEiKQ0KcXFub3JtKGRhaXJ5X3F1ZWVuJGNhbF9mYXQpDQpxcWxpbmUoZGFpcnlfcXVlZW4kY2FsX2ZhdCkNCmBgYA0KDQoNCiMjIEV4ZXJjaXNlIDQNCiMjIyBEb2VzIHRoZSBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdCBmb3IgdGhlIGNhbG9yaWVzIGZyb20gZmF0IGxvb2sgc2ltaWxhciB0byB0aGUgcGxvdHMgY3JlYXRlZCBmb3IgdGhlIHNpbXVsYXRlZCBkYXRhPyAgVGhhdCBpcywgZG8gdGhlIHBsb3RzIHByb3ZpZGUgZXZpZGVuY2UgdGhhdCB0aGUgY2Fsb3JpZXMgYXJlIG5lYXJseSBub3JtYWw/DQoNClllcywgaXQgbG9va3MgcHJldHR5IHNpbWlsYXIgdG8gdGhlIHBsb3RzIGNyZWF0ZWQgZm9yIHRoZSBzaW11bGF0ZWQgZGF0YS4gSSB3b3VsZCBzYXkgdGhhdCB0aGlzIGRvZXMgcHJvdmlkZSBldmlkZW5jZSB0aGF0IHRoZSBjYWxvcmllcyBhcmUgbmVhcmx5IG5vcm1hbCBiZWNhdXNlIHRoZSBvcmlnaW5hbCBkYXRhIGhhcyBhIGdyYXBoIHZlcnkgc2ltaWxhciB0byBhbGwgdGhlIG90aGVyIHBsb3QsIGFuZCBtb3N0IG9mIHRoZSBkYXRhIHBvaW50cyBpbiBlYWNoIG9mIHRoZSBncmFwaHMgZmFsbCBhbG9uZyB0aGUgbGluZS4gSXQgaXMgbm90IGV4YWN0bHkgbm9ybWFsLCBidXQgaXQgaXMgcHJldHR5IGNsb3NlLg0KDQpgYGB7ciBkaW0tcHJlc2VudH0NCm9wZW5pbnRybzo6cXFub3Jtc2ltKHNhbXBsZSA9IGNhbF9mYXQsIGRhdGEgPSBkYWlyeV9xdWVlbikNCmBgYA0KDQoNCiMjIEV4ZXJjaXNlIDUNCiMjIyBVc2luZyB0aGUgc2FtZSB0ZWNobmlxdWUsIGRldGVybWluZSB3aGV0aGVyIG9yIG5vdCB0aGUgY2Fsb3JpZXMgZnJvbSBNY0RvbmFsZCdzIG1lbnUgYXBwZWFyIHRvIGNvbWUgZnJvbSBhIG5vcm1hbCBkaXN0cmlidXRpb24uDQoNClRoZSBkYXRhIGZyb20gTWNEb25hbGQncyBkb2VzIG5vdCByZXNlbWJsZSB0aGUgb3RoZXIgZ3JhcGhzLiBJIHdvdWxkIHNheSBpdCBpcyBub3Qgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgYmVjYXVzZSBvZiB0aGUgZGlmZmVyZW5jZXMgYW5kIGJlY2F1c2UgbWFueSBvZiB0aGUgZGF0YSBwb2ludHMgaW4gdGhlIG9yaWdpbmFsIGdyYXBoIGRvIG5vdCBmYWxsIG9uIHRoZSBsaW5lLg0KDQpgYGB7ciBjb3VudC1jb21wYXJlfQ0Kb3BlbmludHJvOjpxcW5vcm1zaW0oc2FtcGxlID0gY2FsX2ZhdCwgZGF0YSA9IG1jZG9uYWxkcykNCmBgYA0KDQoNCiMjIEV4ZXJjaXNlIDYNCiMjIyBXcml0ZSBvdXQgdHdvIHByb2JhYmlsaXR5IHF1ZXN0aW9ucyB0aGF0IHlvdSB3b3VsZCBsaWtlIHRvIGFuc3dlciBhYm91dCBhbnkgb2YgdGhlIHJlc3RhdXJhbnRzIGluIHRoaXMgZGF0YXNldC4gIENhbGN1bGF0ZSB0aG9zZSBwcm9iYWJpbGl0aWVzIHVzaW5nIGJvdGggdGhlIHRoZW9yZXRpY2FsIG5vcm1hbCBkaXN0cmlidXRpb24gYXMgd2VsbCBhcyB0aGUgZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiAoZm91ciBwcm9iYWJpbGl0aWVzIGluIGFsbCkuICBXaGljaCBvbmUgaGFkIGEgY2xvc2VyIGFncmVlbWVudCBiZXR3ZWVuIHRoZSB0d28gbWV0aG9kcz8NCg0KMS4gSWYgeW91IHdlcmUgdG8gcmFuZG9tbHkgb3JkZXIgYW4gaXRlbSBmcm9tIHRoZSBDaGljayBGaWwtQSBtZW51LCB3aGF0IGlzIHRoZSBwcm9iYWJpbGl0eSBvZiBjaG9vc2luZyBhbiBpdGVtIHdpdGggYSBjaG9sZXN0ZXJvbCBncmVhdGVyIHRoYW4gMTAwIG1nPw0KDQogICAgVGhlb3JldGljYWwgbm9ybWFsIGRpc3RyaWJ1dGlvbiBwcm9iYWJpbGl0eTogMC4zMjkxNDEyDQogICAgRW1waXJpY2FsIGRpc3RyaWJ1dGlvbiBwcm9iYWJpbGl0eTogMC4xNDg2Njk3DQogICAgRGlmZmVyZW5jZSAoYWJzb2x1dGUgdmFsdWUpOiAwLjIxODAzMDENCg0KMi4gSWYgeW91IHdlcmUgdG8gcmFuZG9tbHkgb3JkZXIgYW4gaXRlbSBmcm9tIFN1YndheSwgd2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgb2YgY2hvb3NpbmcgYW4gaXRlbSB0aGF0IGNvbnRhaW5lZCB0b3RhbCBjYXJicyBsZXNzIHRoYW4gMjAgZz8NCg0KICAgIFRoZW9yZXRpY2FsIG5vcm1hbCBkaXN0cmlidXRpb24gcHJvYmFiaWxpdHk6IDAuMTExMTExMQ0KICAgIEVtcGlyaWNhbCBkaXN0cmlidXRpb24gcHJvYmFiaWxpdHk6IDAuMjI5MTY2Nw0KICAgIERpZmZlcmVuY2UgKGFic29sdXRlIHZhbHVlKTogMC4wODA0OTY5NAkNCiAgICANClRoZSBzZWNvbmQgcXVlc3Rpb24gaGFkIG1vcmUgc2ltaWxhciByZXN1bHRzIHRoYW4gdGhlIGZpcnN0IHF1ZXN0aW9uLiBUaGlzIHdvdWxkIHR5cGljYWxseSBpbmRpY2F0ZSB0aGF0IHRoZSBkYXRhIGFib3V0IHRvdGFsIGNhcmJzIGZvciBTdWJ3YXkgd2FzIGNsb3NlciB0byBhIG5vcm1hbCBkaXN0cmlidXRpb24gdGhhbiB0aGUgZGF0YSBhYm91dCBjaG9sZXN0ZXJvbCBmb3IgQ2hpY2sgRmlsLUEuIEhvd2V2ZXIsIHRoZSBRLVEgcGxvdHMgc2hvdyB0aGF0IHRoZSBjaGljayBGaWwtQSBkYXRhIGFib3V0IGNob2xlc3Rlcm9sIGhhZCBhbiBvdXRsaWVyIHRoYXQgYWZmZWN0ZWQgdGhlIG5vcm1hbGl0eSBvZiB0aGUgZGF0YSwgYW5kIHRoZSBRLVEgcGxvdCBmb3IgU3Vid2F5IHdhcyBub3Qgbm9ybWFsLg0KDQoNCmBgYHtyIHBsb3QtcHJvcC1ib3lzLXByZXNlbnR9DQpjaGlja0ZpbEEgPC0gZmFzdGZvb2QgfD4gZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkNoaWNrIEZpbC1BIikNCmNobWVhbiA8LSBtZWFuKGNoaWNrRmlsQSRjaG9sZXN0ZXJvbCkNCmNoc2QgPC0gc2QoY2hpY2tGaWxBJGNob2xlc3Rlcm9sKQ0KKGNoUHJvYiA8LSAxIC0gcG5vcm0ocSA9IDEwMCwgbWVhbiA9IGNobWVhbiwgc2QgPSBjaHNkKSkNCg0KKGNoQWN0dWFsUHJvYiA8LSBjaGlja0ZpbEEgfD4NCiAgZmlsdGVyKGNob2xlc3Rlcm9sID4gMTAwKSB8Pg0KICBzdW1tYXJpc2UocGVyY2VudCA9IG4oKSAvIG5yb3coY2hpY2tGaWxBKSkpDQoNCnN1YndheSA8LSBmYXN0Zm9vZCB8PiBmaWx0ZXIocmVzdGF1cmFudCA9PSAiU3Vid2F5IikNCnNtZWFuIDwtIG1lYW4oc3Vid2F5JHRvdGFsX2NhcmIpDQpzc2QgPC0gc2Qoc3Vid2F5JHRvdGFsX2NhcmIpDQooc3ViUHJvYiA8LSBwbm9ybShxID0gMjAsIG1lYW4gPSBzbWVhbiwgc2QgPSBzc2QpKQ0KDQooc3ViQWN0dWFsUHJvYiA8LSBzdWJ3YXkgfD4NCiAgZmlsdGVyKHRvdGFsX2NhcmIgPCAyMCkgfD4NCiAgc3VtbWFyaXNlKHBlcmNlbnQgPSBuKCkgLyBucm93KHN1YndheSkpKQ0KDQpjaFByb2IgLSBjaEFjdHVhbFByb2INCnN1YlByb2IgLSBzdWJBY3R1YWxQcm9iDQoNCnFxbm9ybShjaGlja0ZpbEEkY2hvbGVzdGVyb2wpDQpxcWxpbmUoY2hpY2tGaWxBJGNob2xlc3Rlcm9sKQ0KDQpxcW5vcm0oc3Vid2F5JHRvdGFsX2NhcmIpDQpxcWxpbmUoc3Vid2F5JHRvdGFsX2NhcmIpDQpgYGANCg0KDQojIyBFeGVyY2lzZSA3DQojIyMgTm93IGxldCdzIGNvbnNpZGVyIHNvbWUgb2YgdGhlIG90aGVyIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldC4gIE91dCBvZiBhbGwgdGhlIGRpZmZlcmVudCByZXN0YXVyYW50cywgd2hpY2ggb25lcycgZGlzdHJpYnV0aW9uIGlzIHRoZSBjbG9zZXN0IHRvIG5vcm1hbCBmb3Igc29kaXVtPw0KDQpBcmJ5J3MgaGFkIHRoZSBjbG9zZXN0IHRvIG5vcm1hbCBkaXN0cmlidXRpb24gZm9yIHNvZGl1bS4gSSB2ZXJpZmllZCBteSBhc3N1bXB0aW9uIHdpdGggdGhlIFNoYXBpcm8tV2lsayBUZXN0LiBUaGUgcC12YWx1ZSBmb3IgQXJieSdzIHdhcyBncmVhdGVyIHRoYW4gMC4wNSwganVzdCBsaWtlIEJ1cmdlciBLaW5nLiBTaW5jZSBpdCBoYWQgYSBncmVhdGVyIHAtdmFsdWUgdGhhbiBBcmJ5J3MgSSBkZWNpZGVkIGl0IHdhcyB0aGUgbW9zdCBub3JtYWwuDQoNCg0KYGBge3IgZmluZC1tYXgtdG90YWx9DQp1bmlxdWUoZmFzdGZvb2QkcmVzdGF1cmFudCkNCg0Kc29uaWMgPC0gZmFzdGZvb2QgfD4gZmlsdGVyKHJlc3RhdXJhbnQgPT0gIlNvbmljIikNCmFyYnlzIDwtZmFzdGZvb2QgfD4gZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkFyYnlzIikNCmJrIDwtIGZhc3Rmb29kIHw+IGZpbHRlcihyZXN0YXVyYW50ID09ICJCdXJnZXIgS2luZyIpDQp0YWNvQmVsbCA8LSBmYXN0Zm9vZCB8PiBmaWx0ZXIocmVzdGF1cmFudCA9PSAiVGFjbyBCZWxsIikNCg0KcXFub3JtKG1jZG9uYWxkcyRzb2RpdW0pDQpxcWxpbmUobWNkb25hbGRzJHNvZGl1bSkNCnNoYXBpcm8udGVzdChtY2RvbmFsZHMkc29kaXVtKQ0KDQpxcW5vcm0oY2hpY2tGaWxBJHNvZGl1bSkNCnFxbGluZShjaGlja0ZpbEEkc29kaXVtKQ0Kc2hhcGlyby50ZXN0KGNoaWNrRmlsQSRzb2RpdW0pDQoNCnFxbm9ybShzb25pYyRzb2RpdW0pDQpxcWxpbmUoc29uaWMkc29kaXVtKQ0Kc2hhcGlyby50ZXN0KHNvbmljJHNvZGl1bSkNCg0KcXFub3JtKGFyYnlzJHNvZGl1bSkNCnFxbGluZShhcmJ5cyRzb2RpdW0pDQpzaGFwaXJvLnRlc3QoYXJieXMkc29kaXVtKQ0KDQpxcW5vcm0oYmskc29kaXVtKQ0KcXFsaW5lKGJrJHNvZGl1bSkNCnNoYXBpcm8udGVzdChiayRzb2RpdW0pDQoNCnFxbm9ybShkYWlyeV9xdWVlbiRzb2RpdW0pDQpxcWxpbmUoZGFpcnlfcXVlZW4kc29kaXVtKQ0Kc2hhcGlyby50ZXN0KGRhaXJ5X3F1ZWVuJHNvZGl1bSkNCg0KcXFub3JtKHN1YndheSRzb2RpdW0pDQpxcWxpbmUoc3Vid2F5JHNvZGl1bSkNCnNoYXBpcm8udGVzdChzdWJ3YXkkc29kaXVtKQ0KDQpxcW5vcm0odGFjb0JlbGwkc29kaXVtKQ0KcXFsaW5lKHRhY29CZWxsJHNvZGl1bSkNCnNoYXBpcm8udGVzdCh0YWNvQmVsbCRzb2RpdW0pDQoNCmBgYA0KDQojIyBFeGVyY2lzZSA4DQojIyMgTm90ZSB0aGF0IHNvbWUgb2YgdGhlIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90cyBmb3Igc29kaXVtIGRpc3RyaWJ1dGlvbnMgc2VlbSB0byBoYXZlIGEgc3RlcC13aXNlIHBhdHRlcm4uIFdoeSBkbyB5b3UgdGhpbmsgdGhpcyBtaWdodCBiZSB0aGUgY2FzZT8NCg0KICBUaGlzIG1pZ2h0IGJlIHRoZSBjYXNlIGJlY2F1c2Ugb2YgdGhlIGRpZmZlcmVudCBjYXRlZ29yaWVzIG9mIGZvb2QuIFNhbmR3aWNoZXMgcHJvYmFibHkgaGF2ZSBhIHJhbmdlIG9mIHNvZGl1bSwgZnJpZXMgcHJvYmFibHkgaGF2ZSBhIGRpZmZlcmVudCByYW5nZSBvZiBzb2RpdW0sIHNhbGFkcyBwcm9iYWJseSBoYXZlIGEgZGlmZmVyZW50IHJhbmdlIG9mIHNvZGl1bSwgYW5kIHNvIG9uLiBTaW5jZSBkaWZmZXJlbnQgY2F0ZWdvcmllcyBvZiBmb29kIGxpa2VseSBoYXZlIHJhbmdlcyBvZiBzb2RpdW0gdGhhdCBkb24nIG92ZXJsYXAgbXVjaCwgdGhlIHBhdHRlcm4gYXBwZWFycyBzdGVwLXdpc2UuDQoNCiMjIEV4ZXJjaXNlIDkNCiMjIyBBcyB5b3UgY2FuIHNlZSwgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3RzIGNhbiBiZSB1c2VkIGJvdGggdG8gYXNzZXNzIG5vcm1hbGl0eSBhbmQgdmlzdWFsaXplIHNrZXduZXNzLiAgTWFrZSBhIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90IGZvciB0aGUgdG90YWwgY2FyYm9oeWRyYXRlcyBmcm9tIGEgcmVzdGF1cmFudCBvZiB5b3VyIGNob2ljZS4gIEJhc2VkIG9uIHRoaXMgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3QsIGlzIHRoaXMgdmFyaWFibGUgbGVmdCBza2V3ZWQsIHN5bW1ldHJpYywgb3IgcmlnaHQgc2tld2VkPyBVc2UgYSBoaXN0b2dyYW0gdG8gY29uZmlybSB5b3VyIGZpbmRpbmdzLg0KDQpNeSBndWVzcyB3YXMgcmlnaHQtc2tld2VkIGJlY2F1c2UgdGhlcmUgc2VlbWVkIHRvIGJlIGEgdGFpbCB0byB0aGUgcmlnaHQgYW5kIGFib3ZlIHRoZSBsaW5lIGluIHRoZSBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdC4gVGhlIGdyYXBoIGNvbmZpcm1zIHRoaXMgYmVjYXVzZSBpdCBpcyByaWdodC1za2V3ZWQgd2l0aCB0aGUgdGFpbCB0byB0aGUgcmlnaHQuDQoNCmBgYHtyfQ0KcXFub3JtKG1jZG9uYWxkcyR0b3RhbF9jYXJiKQ0KcXFsaW5lKG1jZG9uYWxkcyR0b3RhbF9jYXJiKQ0KDQpnZ3Bsb3QobWNkb25hbGRzLCBhZXMoeCA9IHRvdGFsX2NhcmIpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbnMgPSA1MCkNCg0KYGBgDQoNCg0K