library(tidyverse)
library(openintro)
library(infer)
library("plotrix")

Exercise 1

What percent of the adults in your sample think climate change affects their local community? Hint: Just like we did with the population, we can calculate the proportion of those in this sample who think climate change affects their local community.

62 % of adults say YES

us_adults <- tibble(
  climate_change_affects = c(rep("Yes", 62000), rep("No", 38000))
)
ggplot(us_adults, aes(x = climate_change_affects)) + 
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Do you think climate change is affecting your local community?"
  ) +
  coord_flip()

us_adults %>%
  count(climate_change_affects) %>%
  mutate(p = n /sum(n))
## # A tibble: 2 × 3
##   climate_change_affects     n     p
##   <chr>                  <int> <dbl>
## 1 No                     38000  0.38
## 2 Yes                    62000  0.62
n <- 60
samp <- us_adults %>%
  sample_n(size = n)
summary(us_adults)
##  climate_change_affects
##  Length:100000         
##  Class :character      
##  Mode  :character
table(samp$climate_change_affects)
## 
##  No Yes 
##  24  36

Exercise 2

Would you expect another student’s sample proportion to be identical to yours? Would you expect it to be similar? Why or Why not?

No, another student’s sample proportion may be slightly different from mine because sample proportion, p (point estimates) will vary from one sample to another depending on the simulation. …

Exercise 3

In the interpretation above, we used the phrase “95% confident”. What does “95% confidence” mean? Getting a sense of the precision of the estimate, we compute a 95% confidence which is a range of value above and below the point estimate within which the true value in the proportion is likely to lie with 95% confidence. The other 5% is the possibility that the true value is not within the confidence interval.

samp %>%
  specify(response = climate_change_affects, success = "Yes") %>%
  generate(reps = 1000, type = "bootstrap") %>%
  calculate(stat = "prop") %>%
  get_ci(level = 0.95)
## # A tibble: 1 × 2
##   lower_ci upper_ci
##      <dbl>    <dbl>
## 1    0.467    0.717

Exercise 4

Does your confidence interval capture the true value proportion of US adults who think climate change affects their local community? If you are working on this lab in a classroom, does your neighbor’s interval capture this value?

No. the lower limit of the interval is 45% and upper limit for 95% confidence interval is 72 %.

Exercise 5

Each student should have gotten a slightly different confidence interval. What proportion of those intervals would you expect to capture the true population mean? Why?

It is expected that only +/- 0.01 range of interval may be different to capture the true population mean.

Exercise 6

Given a sample size of 60, 1000 bootstrap samples for each interval, and 50 confidence intervals constructed (the default values for the above app), what proportion of your confidence intervals include the true population proportion? Is this proportion exactly equal to the confidence level? If not, explain, why. Make sure to include your plot in your answer.

samp %>%
  specify(response = climate_change_affects, success = "Yes") %>%
  generate(reps = 1000, type = "bootstrap") %>%
  calculate(stat = "prop") %>%
  get_ci(level = 0.50)
## # A tibble: 1 × 2
##   lower_ci upper_ci
##      <dbl>    <dbl>
## 1    0.567     0.65
ggplot(samp, aes(x = climate_change_affects, y = "")) + 
  geom_point(colour = "black") +
  geom_smooth(method = "lm", se = TRUE, level = 0.50) +
  labs(title = "50% Confidence Interval") +
  theme_bw() +
  theme(plot.title = element_text(face = "bold",hjust = 0.5))
## `geom_smooth()` using formula = 'y ~ x'

Exercise 7

Choose a different confidence level than 95%. Would you expect a confidence interval at this level to me wider or narrower than the the confidence interval you calculated at the 95% confidence level? Explain your reasoning.

As the confidence level is higher, the range of confidence interval is wider that will capture “true p”.

samp %>%
  specify(response = climate_change_affects, success = "Yes") %>%
  generate(reps = 1000, type = "bootstrap") %>%
  calculate(stat = "prop") %>%
  get_ci(level = 0.90)
## # A tibble: 1 × 2
##   lower_ci upper_ci
##      <dbl>    <dbl>
## 1      0.5      0.7

Exercise 8

Using code from the infer package and data from the one sample you have (samp), find a confidence interval for the proportion of US Adults who think climate change is affecting their local community with a confidence level of your choosing (other than 95%) and interpret it.

us_adults <- tibble(
  climate_change_affects = c(rep("Yes", 62000), rep("No", 38000))
)
us_adults %>%
  specify(response = climate_change_affects, success = "Yes") %>%
  generate(reps = 1000, type = "bootstrap") %>%
  calculate(stat = "prop") %>%
  get_ci(level = 0.95)
## # A tibble: 1 × 2
##   lower_ci upper_ci
##      <dbl>    <dbl>
## 1    0.617    0.623

Exercise 9

Using the app, calculate 50 confidence intervals at the confidence level you chose in the previous question, and plot all intervals on one plot, and calculate the proportion of intervals that include the true population proportion. How does this percentage compare to the confidence level selected for the intervals?

us_adults <- tibble(
  climate_change_affects = c(rep("Yes", 62000), rep("No", 38000))
)
us_adults %>%
  specify(response = climate_change_affects, success = "Yes") %>%
  generate(reps = 1000, type = "bootstrap") %>%
  calculate(stat = "prop") %>%
  get_ci(level = 0.50)
## # A tibble: 1 × 2
##   lower_ci upper_ci
##      <dbl>    <dbl>
## 1    0.619    0.621
us_adults<-round(data.frame(x = 1:20,
                      y = runif(20, 20, 40),
                      lower = runif(20, 0, 20),
                      upper = runif(20, 40, 50)), 4)
plotCI(x = us_adults$x,           
       y = us_adults$y,
       li = us_adults$lower,
       ui = us_adults$upper)

Exercise 10

Lastly, try one or more (different) confidence level. First, state how you expect the width of this interval to compare to previous ones you calculated, then, calculate the bounds of the interval using the infer package and data from samp and interpret it. Finally, use the app to generate many intervals and calculate the proportion of intervals that are capture the true proportion.

samp <- tibble(
  climate_change_affects = c(rep("Yes", 62000), rep("No", 38000))
)
samp %>%
  specify(response = climate_change_affects, success = "Yes") %>%
  generate(reps = 1000, type = "bootstrap") %>%
  calculate(stat = "prop") %>%
  get_ci(level = 0.90)
## # A tibble: 1 × 2
##   lower_ci upper_ci
##      <dbl>    <dbl>
## 1    0.617    0.623
samp<-round(data.frame(x = 1:10,
                      y = runif(10, 10, 20),
                      lower = runif(10, 0, 10),
                      upper = runif(10, 20, 40)), 4)
ggplot(samp, aes(x, y)) + geom_point() + 
geom_errorbar(aes(ymin = lower, ymax = upper))

Exercise 11

Using the app, experiment with different sample sizes and comment on how the widths of intervals change as sample size changes (increases and decreases).

The widths of intervals increases, sample sizes decreases.

Exercise 12

Finally, given a sample size (say, 60), how does the width of the interval changes as you increase the number of bootstrap samples. Hint: Does changing the number of bootstrap samples affect the standard error?

No change in the width of the interval as the number of bootstrap samples increases.

LS0tCnRpdGxlOiAiTGFiIDVCOiBGb3VuZGF0aW9ucyBmb3Igc3RhdGlzdGljYWwgaW5mZXJlbmNlIC0gQ29uZmlkZW5jZSBJbnRlcnZhbHMiCmF1dGhvcjogIkx3aW4gTmFuZGFyIFNod2UiCmRhdGU6ICJBcHJpbC02IgpvdXRwdXQ6IG9wZW5pbnRybzo6bGFiX3JlcG9ydAotLS0KCmBgYHtyIGxvYWQtcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KG9wZW5pbnRybykKbGlicmFyeShpbmZlcikKbGlicmFyeSgicGxvdHJpeCIpCmBgYAoKIyMjIEV4ZXJjaXNlIDEKCldoYXQgcGVyY2VudCBvZiB0aGUgYWR1bHRzIGluIHlvdXIgc2FtcGxlIHRoaW5rIGNsaW1hdGUgY2hhbmdlIGFmZmVjdHMgdGhlaXIgbG9jYWwgY29tbXVuaXR5PwpIaW50OiBKdXN0IGxpa2Ugd2UgZGlkIHdpdGggdGhlIHBvcHVsYXRpb24sIHdlIGNhbiBjYWxjdWxhdGUgdGhlIHByb3BvcnRpb24gb2YgdGhvc2UgaW4gdGhpcyBzYW1wbGUgd2hvIHRoaW5rIGNsaW1hdGUgY2hhbmdlIGFmZmVjdHMgdGhlaXIgbG9jYWwgY29tbXVuaXR5LgoKNjIgJSBvZiBhZHVsdHMgc2F5IFlFUwoKYGBge3IgY29kZS1jaHVuay1sYWJlbH0KdXNfYWR1bHRzIDwtIHRpYmJsZSgKICBjbGltYXRlX2NoYW5nZV9hZmZlY3RzID0gYyhyZXAoIlllcyIsIDYyMDAwKSwgcmVwKCJObyIsIDM4MDAwKSkKKQpnZ3Bsb3QodXNfYWR1bHRzLCBhZXMoeCA9IGNsaW1hdGVfY2hhbmdlX2FmZmVjdHMpKSArIAogIGdlb21fYmFyKCkgKwogIGxhYnMoCiAgICB4ID0gIiIsIHkgPSAiIiwKICAgIHRpdGxlID0gIkRvIHlvdSB0aGluayBjbGltYXRlIGNoYW5nZSBpcyBhZmZlY3RpbmcgeW91ciBsb2NhbCBjb21tdW5pdHk/IgogICkgKwogIGNvb3JkX2ZsaXAoKQp1c19hZHVsdHMgJT4lCiAgY291bnQoY2xpbWF0ZV9jaGFuZ2VfYWZmZWN0cykgJT4lCiAgbXV0YXRlKHAgPSBuIC9zdW0obikpCm4gPC0gNjAKc2FtcCA8LSB1c19hZHVsdHMgJT4lCiAgc2FtcGxlX24oc2l6ZSA9IG4pCnN1bW1hcnkodXNfYWR1bHRzKQp0YWJsZShzYW1wJGNsaW1hdGVfY2hhbmdlX2FmZmVjdHMpCmBgYAoKIyMjIEV4ZXJjaXNlIDIKV291bGQgeW91IGV4cGVjdCBhbm90aGVyIHN0dWRlbnQncyBzYW1wbGUgcHJvcG9ydGlvbiB0byBiZSBpZGVudGljYWwgdG8geW91cnM/IFdvdWxkIHlvdSBleHBlY3QgaXQgdG8gYmUgc2ltaWxhcj8gV2h5IG9yIFdoeSBub3Q/CgpObywgYW5vdGhlciBzdHVkZW50J3Mgc2FtcGxlIHByb3BvcnRpb24gbWF5IGJlIHNsaWdodGx5IGRpZmZlcmVudCBmcm9tIG1pbmUgYmVjYXVzZSBzYW1wbGUgcHJvcG9ydGlvbiwgcCAocG9pbnQgZXN0aW1hdGVzKSB3aWxsIHZhcnkgZnJvbSBvbmUgc2FtcGxlIHRvIGFub3RoZXIgZGVwZW5kaW5nIG9uIHRoZSBzaW11bGF0aW9uLiAKLi4uCgojIyMgRXhlcmNpc2UgMwpJbiB0aGUgaW50ZXJwcmV0YXRpb24gYWJvdmUsIHdlIHVzZWQgdGhlIHBocmFzZSAiOTUlIGNvbmZpZGVudCIuIFdoYXQgZG9lcyAiOTUlIGNvbmZpZGVuY2UiIG1lYW4/IApHZXR0aW5nIGEgc2Vuc2Ugb2YgdGhlIHByZWNpc2lvbiBvZiB0aGUgZXN0aW1hdGUsIHdlIGNvbXB1dGUgYSA5NSUgY29uZmlkZW5jZSB3aGljaCBpcyBhIHJhbmdlIG9mIHZhbHVlIGFib3ZlIGFuZCBiZWxvdyB0aGUgcG9pbnQgZXN0aW1hdGUgd2l0aGluIHdoaWNoIHRoZSB0cnVlIHZhbHVlIGluIHRoZSBwcm9wb3J0aW9uIGlzIGxpa2VseSB0byBsaWUgd2l0aCA5NSUgY29uZmlkZW5jZS4gVGhlIG90aGVyIDUlIGlzIHRoZSBwb3NzaWJpbGl0eSB0aGF0IHRoZSB0cnVlIHZhbHVlIGlzIG5vdCB3aXRoaW4gdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwuCgpgYGB7ciBjb25maWRlbmNlLWludGVycHJldGF0aW9ufQpzYW1wICU+JQogIHNwZWNpZnkocmVzcG9uc2UgPSBjbGltYXRlX2NoYW5nZV9hZmZlY3RzLCBzdWNjZXNzID0gIlllcyIpICU+JQogIGdlbmVyYXRlKHJlcHMgPSAxMDAwLCB0eXBlID0gImJvb3RzdHJhcCIpICU+JQogIGNhbGN1bGF0ZShzdGF0ID0gInByb3AiKSAlPiUKICBnZXRfY2kobGV2ZWwgPSAwLjk1KQpgYGAKIyMjIEV4ZXJjaXNlIDQKRG9lcyB5b3VyIGNvbmZpZGVuY2UgaW50ZXJ2YWwgY2FwdHVyZSB0aGUgdHJ1ZSB2YWx1ZSBwcm9wb3J0aW9uIG9mIFVTIGFkdWx0cyB3aG8gdGhpbmsgY2xpbWF0ZSBjaGFuZ2UgYWZmZWN0cyB0aGVpciBsb2NhbCBjb21tdW5pdHk/IElmIHlvdSBhcmUgd29ya2luZyBvbiB0aGlzIGxhYiBpbiBhIGNsYXNzcm9vbSwgZG9lcyB5b3VyIG5laWdoYm9yJ3MgaW50ZXJ2YWwgY2FwdHVyZSB0aGlzIHZhbHVlPwoKTm8uIHRoZSBsb3dlciBsaW1pdCBvZiB0aGUgaW50ZXJ2YWwgaXMgNDUlIGFuZCB1cHBlciBsaW1pdCBmb3IgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgNzIgJS4KCiMjIyBFeGVyY2lzZSA1CkVhY2ggc3R1ZGVudCBzaG91bGQgaGF2ZSBnb3R0ZW4gYSBzbGlnaHRseSBkaWZmZXJlbnQgY29uZmlkZW5jZSBpbnRlcnZhbC4gV2hhdCBwcm9wb3J0aW9uIG9mIHRob3NlIGludGVydmFscyB3b3VsZCB5b3UgZXhwZWN0IHRvIGNhcHR1cmUgdGhlIHRydWUgcG9wdWxhdGlvbiBtZWFuPyBXaHk/CgpJdCBpcyBleHBlY3RlZCB0aGF0IG9ubHkgKy8tIDAuMDEgcmFuZ2Ugb2YgaW50ZXJ2YWwgbWF5IGJlIGRpZmZlcmVudCB0byBjYXB0dXJlIHRoZSB0cnVlIHBvcHVsYXRpb24gbWVhbi4KCiMjIyBFeGVyY2lzZSA2CkdpdmVuIGEgc2FtcGxlIHNpemUgb2YgNjAsIDEwMDAgYm9vdHN0cmFwIHNhbXBsZXMgZm9yIGVhY2ggaW50ZXJ2YWwsIGFuZCA1MCBjb25maWRlbmNlIGludGVydmFscyBjb25zdHJ1Y3RlZCAodGhlIGRlZmF1bHQgdmFsdWVzIGZvciB0aGUgYWJvdmUgYXBwKSwgd2hhdCBwcm9wb3J0aW9uIG9mIHlvdXIgY29uZmlkZW5jZSBpbnRlcnZhbHMgaW5jbHVkZSB0aGUgdHJ1ZSBwb3B1bGF0aW9uIHByb3BvcnRpb24/IElzIHRoaXMgcHJvcG9ydGlvbiBleGFjdGx5IGVxdWFsIHRvIHRoZSBjb25maWRlbmNlIGxldmVsPyBJZiBub3QsIGV4cGxhaW4sIHdoeS4gTWFrZSBzdXJlIHRvIGluY2x1ZGUgeW91ciBwbG90IGluIHlvdXIgYW5zd2VyLgoKCmBgYHtyIGNvbmZpZGVuY2UtbGV2ZWx9CnNhbXAgJT4lCiAgc3BlY2lmeShyZXNwb25zZSA9IGNsaW1hdGVfY2hhbmdlX2FmZmVjdHMsIHN1Y2Nlc3MgPSAiWWVzIikgJT4lCiAgZ2VuZXJhdGUocmVwcyA9IDEwMDAsIHR5cGUgPSAiYm9vdHN0cmFwIikgJT4lCiAgY2FsY3VsYXRlKHN0YXQgPSAicHJvcCIpICU+JQogIGdldF9jaShsZXZlbCA9IDAuNTApCmdncGxvdChzYW1wLCBhZXMoeCA9IGNsaW1hdGVfY2hhbmdlX2FmZmVjdHMsIHkgPSAiIikpICsgCiAgZ2VvbV9wb2ludChjb2xvdXIgPSAiYmxhY2siKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFLCBsZXZlbCA9IDAuNTApICsKICBsYWJzKHRpdGxlID0gIjUwJSBDb25maWRlbmNlIEludGVydmFsIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIixoanVzdCA9IDAuNSkpCmBgYAoKIyMjIEV4ZXJjaXNlIDcKQ2hvb3NlIGEgZGlmZmVyZW50IGNvbmZpZGVuY2UgbGV2ZWwgdGhhbiA5NSUuIFdvdWxkIHlvdSBleHBlY3QgYSBjb25maWRlbmNlIGludGVydmFsIGF0IHRoaXMgbGV2ZWwgdG8gbWUgd2lkZXIgb3IgbmFycm93ZXIgdGhhbiB0aGUgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgeW91IGNhbGN1bGF0ZWQgYXQgdGhlIDk1JSBjb25maWRlbmNlIGxldmVsPyBFeHBsYWluIHlvdXIgcmVhc29uaW5nLiAKCkFzIHRoZSBjb25maWRlbmNlIGxldmVsIGlzIGhpZ2hlciwgdGhlIHJhbmdlIG9mIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgd2lkZXIgdGhhdCB3aWxsIGNhcHR1cmUgInRydWUgcCIuCgpgYGB7ciBkaWZmZXJlbnQtaW50ZXJ2YWx9CnNhbXAgJT4lCiAgc3BlY2lmeShyZXNwb25zZSA9IGNsaW1hdGVfY2hhbmdlX2FmZmVjdHMsIHN1Y2Nlc3MgPSAiWWVzIikgJT4lCiAgZ2VuZXJhdGUocmVwcyA9IDEwMDAsIHR5cGUgPSAiYm9vdHN0cmFwIikgJT4lCiAgY2FsY3VsYXRlKHN0YXQgPSAicHJvcCIpICU+JQogIGdldF9jaShsZXZlbCA9IDAuOTApCmBgYAojIyMgRXhlcmNpc2UgOApVc2luZyBjb2RlIGZyb20gdGhlIGluZmVyIHBhY2thZ2UgYW5kIGRhdGEgZnJvbSB0aGUgb25lIHNhbXBsZSB5b3UgaGF2ZSAoc2FtcCksIGZpbmQgYSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgcHJvcG9ydGlvbiBvZiBVUyBBZHVsdHMgd2hvIHRoaW5rIGNsaW1hdGUgY2hhbmdlIGlzIGFmZmVjdGluZyB0aGVpciBsb2NhbCBjb21tdW5pdHkgd2l0aCBhIGNvbmZpZGVuY2UgbGV2ZWwgb2YgeW91ciBjaG9vc2luZyAob3RoZXIgdGhhbiA5NSUpIGFuZCBpbnRlcnByZXQgaXQuCgpgYGB7ciB1cy1hZHVsdH0KdXNfYWR1bHRzIDwtIHRpYmJsZSgKICBjbGltYXRlX2NoYW5nZV9hZmZlY3RzID0gYyhyZXAoIlllcyIsIDYyMDAwKSwgcmVwKCJObyIsIDM4MDAwKSkKKQp1c19hZHVsdHMgJT4lCiAgc3BlY2lmeShyZXNwb25zZSA9IGNsaW1hdGVfY2hhbmdlX2FmZmVjdHMsIHN1Y2Nlc3MgPSAiWWVzIikgJT4lCiAgZ2VuZXJhdGUocmVwcyA9IDEwMDAsIHR5cGUgPSAiYm9vdHN0cmFwIikgJT4lCiAgY2FsY3VsYXRlKHN0YXQgPSAicHJvcCIpICU+JQogIGdldF9jaShsZXZlbCA9IDAuOTUpCmBgYAojIyMgRXhlcmNpc2UgOQpVc2luZyB0aGUgYXBwLCBjYWxjdWxhdGUgNTAgY29uZmlkZW5jZSBpbnRlcnZhbHMgYXQgdGhlIGNvbmZpZGVuY2UgbGV2ZWwgeW91IGNob3NlIGluIHRoZSBwcmV2aW91cyBxdWVzdGlvbiwgYW5kIHBsb3QgYWxsIGludGVydmFscyBvbiBvbmUgcGxvdCwgYW5kIGNhbGN1bGF0ZSB0aGUgcHJvcG9ydGlvbiBvZiBpbnRlcnZhbHMgdGhhdCBpbmNsdWRlIHRoZSB0cnVlIHBvcHVsYXRpb24gcHJvcG9ydGlvbi4gSG93IGRvZXMgdGhpcyBwZXJjZW50YWdlIGNvbXBhcmUgdG8gdGhlIGNvbmZpZGVuY2UgbGV2ZWwgc2VsZWN0ZWQgZm9yIHRoZSBpbnRlcnZhbHM/CgpgYGB7ciB1cy1hZHVsdDJ9CnVzX2FkdWx0cyA8LSB0aWJibGUoCiAgY2xpbWF0ZV9jaGFuZ2VfYWZmZWN0cyA9IGMocmVwKCJZZXMiLCA2MjAwMCksIHJlcCgiTm8iLCAzODAwMCkpCikKdXNfYWR1bHRzICU+JQogIHNwZWNpZnkocmVzcG9uc2UgPSBjbGltYXRlX2NoYW5nZV9hZmZlY3RzLCBzdWNjZXNzID0gIlllcyIpICU+JQogIGdlbmVyYXRlKHJlcHMgPSAxMDAwLCB0eXBlID0gImJvb3RzdHJhcCIpICU+JQogIGNhbGN1bGF0ZShzdGF0ID0gInByb3AiKSAlPiUKICBnZXRfY2kobGV2ZWwgPSAwLjUwKQp1c19hZHVsdHM8LXJvdW5kKGRhdGEuZnJhbWUoeCA9IDE6MjAsCiAgICAgICAgICAgICAgICAgICAgICB5ID0gcnVuaWYoMjAsIDIwLCA0MCksCiAgICAgICAgICAgICAgICAgICAgICBsb3dlciA9IHJ1bmlmKDIwLCAwLCAyMCksCiAgICAgICAgICAgICAgICAgICAgICB1cHBlciA9IHJ1bmlmKDIwLCA0MCwgNTApKSwgNCkKcGxvdENJKHggPSB1c19hZHVsdHMkeCwgICAgICAgICAgIAogICAgICAgeSA9IHVzX2FkdWx0cyR5LAogICAgICAgbGkgPSB1c19hZHVsdHMkbG93ZXIsCiAgICAgICB1aSA9IHVzX2FkdWx0cyR1cHBlcikKCmBgYAoKIyMjIEV4ZXJjaXNlIDEwCkxhc3RseSwgdHJ5IG9uZSBvciBtb3JlIChkaWZmZXJlbnQpIGNvbmZpZGVuY2UgbGV2ZWwuIEZpcnN0LCBzdGF0ZSBob3cgeW91IGV4cGVjdCB0aGUgd2lkdGggb2YgdGhpcyBpbnRlcnZhbCB0byBjb21wYXJlIHRvIHByZXZpb3VzIG9uZXMgeW91IGNhbGN1bGF0ZWQsIHRoZW4sIGNhbGN1bGF0ZSB0aGUgYm91bmRzIG9mIHRoZSBpbnRlcnZhbCB1c2luZyB0aGUgaW5mZXIgcGFja2FnZSBhbmQgZGF0YSBmcm9tIHNhbXAgYW5kIGludGVycHJldCBpdC4gRmluYWxseSwgdXNlIHRoZSBhcHAgdG8gZ2VuZXJhdGUgbWFueSBpbnRlcnZhbHMgYW5kIGNhbGN1bGF0ZSB0aGUgcHJvcG9ydGlvbiBvZiBpbnRlcnZhbHMgdGhhdCBhcmUgY2FwdHVyZSB0aGUgdHJ1ZSBwcm9wb3J0aW9uLgoKYGBgIHtyIGNvbmZlZGVuY2UtbGV2ZWx9CnNhbXAgPC0gdGliYmxlKAogIGNsaW1hdGVfY2hhbmdlX2FmZmVjdHMgPSBjKHJlcCgiWWVzIiwgNjIwMDApLCByZXAoIk5vIiwgMzgwMDApKQopCnNhbXAgJT4lCiAgc3BlY2lmeShyZXNwb25zZSA9IGNsaW1hdGVfY2hhbmdlX2FmZmVjdHMsIHN1Y2Nlc3MgPSAiWWVzIikgJT4lCiAgZ2VuZXJhdGUocmVwcyA9IDEwMDAsIHR5cGUgPSAiYm9vdHN0cmFwIikgJT4lCiAgY2FsY3VsYXRlKHN0YXQgPSAicHJvcCIpICU+JQogIGdldF9jaShsZXZlbCA9IDAuOTApCnNhbXA8LXJvdW5kKGRhdGEuZnJhbWUoeCA9IDE6MTAsCiAgICAgICAgICAgICAgICAgICAgICB5ID0gcnVuaWYoMTAsIDEwLCAyMCksCiAgICAgICAgICAgICAgICAgICAgICBsb3dlciA9IHJ1bmlmKDEwLCAwLCAxMCksCiAgICAgICAgICAgICAgICAgICAgICB1cHBlciA9IHJ1bmlmKDEwLCAyMCwgNDApKSwgNCkKZ2dwbG90KHNhbXAsIGFlcyh4LCB5KSkgKyBnZW9tX3BvaW50KCkgKyAKZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IGxvd2VyLCB5bWF4ID0gdXBwZXIpKQpgYGAKCiMjIyBFeGVyY2lzZSAxMQpVc2luZyB0aGUgYXBwLCBleHBlcmltZW50IHdpdGggZGlmZmVyZW50IHNhbXBsZSBzaXplcyBhbmQgY29tbWVudCBvbiBob3cgdGhlIHdpZHRocyBvZiBpbnRlcnZhbHMgY2hhbmdlIGFzIHNhbXBsZSBzaXplIGNoYW5nZXMgKGluY3JlYXNlcyBhbmQgZGVjcmVhc2VzKS4KClRoZSB3aWR0aHMgb2YgaW50ZXJ2YWxzIGluY3JlYXNlcywgc2FtcGxlIHNpemVzIGRlY3JlYXNlcy4KCiMjIyBFeGVyY2lzZSAxMgpGaW5hbGx5LCBnaXZlbiBhIHNhbXBsZSBzaXplIChzYXksIDYwKSwgaG93IGRvZXMgdGhlIHdpZHRoIG9mIHRoZSBpbnRlcnZhbCBjaGFuZ2VzIGFzIHlvdSBpbmNyZWFzZSB0aGUgbnVtYmVyIG9mIGJvb3RzdHJhcCBzYW1wbGVzLiBIaW50OiBEb2VzIGNoYW5naW5nIHRoZSBudW1iZXIgb2YgYm9vdHN0cmFwIHNhbXBsZXMgYWZmZWN0IHRoZSBzdGFuZGFyZCBlcnJvcj8KCk5vIGNoYW5nZSBpbiB0aGUgd2lkdGggb2YgdGhlIGludGVydmFsIGFzIHRoZSBudW1iZXIgb2YgYm9vdHN0cmFwIHNhbXBsZXMgaW5jcmVhc2VzLgo=