knitr::opts_chunk$set(eval = TRUE, message = FALSE, warning = FALSE)
set.seed(1234)
library(tidyverse)
library(openintro)
library(infer)

Exercise 1

Describe the distribution of responses in this sample. How does it compare to the distribution of responses in the population. Hint: Although the sample_n function takes a random sample of observations (i.e. rows) from the dataset, you can still refer to the variables in the dataset with the same names. Code you presented earlier for visualizing and summarizing the population data will still be useful for the sample, however be careful to not label your proportion p since you’re now calculating a sample statistic, not a population parameters. You can customize the label of the statistics to indicate that it comes from the sample.

The distribution is similar to the actual population. It only differs by a small decimal in the benefits and doesn’t benefit groups.

set.seed(1234)
global_monitor <- tibble(
  scientist_work = c(rep("Benefits", 80000), rep("Doesn't benefit", 20000))
)

ggplot(global_monitor, aes(x = scientist_work)) +
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Do you believe that the work scientists do benefit people like you?"
  ) +
  coord_flip() 

global_monitor %>%
  count(scientist_work) %>%
  mutate(p = n /sum(n))
## # A tibble: 2 Ă— 3
##   scientist_work      n     p
##   <chr>           <int> <dbl>
## 1 Benefits        80000   0.8
## 2 Doesn't benefit 20000   0.2
set.seed(1234)

samp1 <- global_monitor %>%
  sample_n(50)

ggplot(samp1, aes(x = scientist_work)) +
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Do you believe that the work scientists do benefit people like you?"
  ) +
  coord_flip() 

samp1 %>%
  count(scientist_work) %>%
  mutate(p_hat = n /sum(n))
## # A tibble: 2 Ă— 3
##   scientist_work      n p_hat
##   <chr>           <int> <dbl>
## 1 Benefits           37  0.74
## 2 Doesn't benefit    13  0.26

Exercise 2

Would you expect the sample proportion to match the sample proportion of another student’s sample? Why, or why not? If the answer is no, would you expect the proportions to be somewhat different or very different? Ask a student team to confirm your answer.

I would expect the sample proportion to be similar to another student’s sample. If they used the same seed, then it would be the same. If they used a different seed, it would likely be different but similar. I would expect them to be similar because the original data was 80% to 20%, so the sample would probably be close to this. They are much more likely to get close to 80% for the Benefits group and close o 20% for the Doesn’t Benefit group. I confirmed my answer by running the sample again with a different seed. The results were 72% and 28%. This is similar to my sample.

set.seed(5678)

samp <- global_monitor %>%
  sample_n(50)

ggplot(samp, aes(x = scientist_work)) +
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Do you believe that the work scientists do benefit people like you?"
  ) +
  coord_flip() 

samp |>
  count(scientist_work) |>
  mutate(p_hat = n /sum(n))
## # A tibble: 2 Ă— 3
##   scientist_work      n p_hat
##   <chr>           <int> <dbl>
## 1 Benefits           36  0.72
## 2 Doesn't benefit    14  0.28

Exercise 3

Take a second sample, also of size 50, and call it samp2. How does the sample proportion of samp2 compare with that of samp1? Suppose we took two more samples, one of size 100 and one of size 1000. Which would you think would provide a more accurate estimate of the population proportion?

The sample proportion is similar to samp1. The two proportions are off by a few tenths of a percent. I would assume a sample of 1000 would be more accurate. I tested it below, and it turned out that the sample of size 1000 was more accurate. The results also are probably affected by the seed, but in this case, the sample of size 1000 was more accurate than 100.

set.seed(246)

samp2 <- global_monitor %>%
  sample_n(50)

ggplot(samp2, aes(x = scientist_work)) +
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Do you believe that the work scientists do benefit people like you?"
  ) +
  coord_flip() 

samp2 |>
  count(scientist_work) |>
  mutate(p_hat = n /sum(n))
## # A tibble: 2 Ă— 3
##   scientist_work      n p_hat
##   <chr>           <int> <dbl>
## 1 Benefits           41  0.82
## 2 Doesn't benefit     9  0.18
set.seed(500)

samp3 <- global_monitor %>%
  sample_n(100)

ggplot(samp3, aes(x = scientist_work)) +
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Do you believe that the work scientists do benefit people like you?"
  ) +
  coord_flip() 

samp3 |>
  count(scientist_work) |>
  mutate(p_hat = n /sum(n))
## # A tibble: 2 Ă— 3
##   scientist_work      n p_hat
##   <chr>           <int> <dbl>
## 1 Benefits           85  0.85
## 2 Doesn't benefit    15  0.15
set.seed(500)

samp4 <- global_monitor %>%
  sample_n(1000)

ggplot(samp4, aes(x = scientist_work)) +
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Do you believe that the work scientists do benefit people like you?"
  ) +
  coord_flip() 

samp4 |>
  count(scientist_work) |>
  mutate(p_hat = n /sum(n))
## # A tibble: 2 Ă— 3
##   scientist_work      n p_hat
##   <chr>           <int> <dbl>
## 1 Benefits          790  0.79
## 2 Doesn't benefit   210  0.21

Exercise 4

How many elements are there in sample_props50? Describe the sampling distribution, and be sure to specifically note its center. Make sure to include a plot of the distribution in your answer.

It has 14999 rows (elements), but it is supposed to have 15000. The distribution looks normally distributed. It is symmetrical with a bell curve. The center is at 0., which is the original proportion for the population.

sample_props50 <- global_monitor %>%
                    rep_sample_n(size = 50, reps = 15000, replace = TRUE) %>%
                    count(scientist_work) %>%
                    mutate(p_hat = n /sum(n)) %>%
                    filter(scientist_work == "Doesn't benefit")

length(sample_props50$scientist_work)
## [1] 15000
ggplot(data = sample_props50, aes(x = p_hat)) +
  geom_histogram(binwidth = 0.02) +
  labs(
    x = "p_hat (Doesn't benefit)",
    title = "Sampling distribution of p_hat",
    subtitle = "Sample size = 50, Number of samples = 15000"
  )

Exercise 5

To make sure you understand how sampling distributions are built, and exactly what the rep_sample_n function does, try modifying the code to create a sampling distribution of 25 sample proportions from samples of size 10, and put them in a data frame named sample_props_small. Print the output. How many observations are there in this object called sample_props_small? What does each observation represent?

There are 24 observations in the object. Each observation represents one repetition of taking a sample of 10 people and getting the proportion of people who said Doesn’t Benefit.

sample_props_small <- global_monitor %>%
                    rep_sample_n(size = 10, reps = 25, replace = TRUE) %>%
                    count(scientist_work) %>%
                    mutate(p_hat = n /sum(n)) %>%
                    filter(scientist_work == "Doesn't benefit")

ggplot(data = sample_props_small, aes(x = p_hat)) +
  geom_histogram(binwidth = 0.02) +
  labs(
    x = "p_hat (Doesn't benefit)",
    title = "Sampling distribution of p_hat",
    subtitle = "Sample size = 10, Number of samples = 25"
  )

Exercise 6

Use the app below to create sampling distributions of proportions of Doesn’t benefit from samples of size 10, 50, and 100. Use 5,000 simulations. What does each observation in the sampling distribution represent? How does the mean, standard error, and shape of the sampling distribution change as the sample size increases? How (if at all) do these values change if you increase the number of simulations? (You do not need to include plots in your answer.)

Each observation in the distribution represents the proportion in one sample of people who responded “Doesn’t Benefit.”

When the sample size increased from 10 to 50, the mean became the same as the population proportion, and the standard error decreased. Also, the shape of the distribution became much more normally distributed. When the sample size increased from 50 to 100, the mean remained the same (equal to the population proportion), and the standard error decreased. Also, the shape of the distribution stayed normally distributed.

Increasing the number of simulations barely changed the mean or standard error, but the distributions became more normally distributed with a higher number of simulations.

Exercise 7

Take a sample of size 15 from the population and calculate the proportion of people in this sample who think the work scientists do enhances their lives. Using this sample, what is your best point estimate of the population proportion of people who think the work scientists do enchances their lives?

The estimate I calculated from this sample was about 0.73.

set.seed(1234)

samp1 <- global_monitor %>%
  sample_n(15)

ggplot(samp1, aes(x = scientist_work)) +
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Do you believe that the work scientists do benefit people like you?"
  ) +
  coord_flip() 

samp1 %>%
  count(scientist_work) %>%
  mutate(p_hat = n /sum(n))
## # A tibble: 2 Ă— 3
##   scientist_work      n p_hat
##   <chr>           <int> <dbl>
## 1 Benefits           11 0.733
## 2 Doesn't benefit     4 0.267

Exercise 8

Since you have access to the population, simulate the sampling distribution of proportion of those who think the work scientists do enchances their lives for samples of size 15 by taking 2000 samples from the population of size 15 and computing 2000 sample proportions. Store these proportions in as sample_props15. Plot the data, then describe the shape of this sampling distribution. Based on this sampling distribution, what would you guess the true proportion of those who think the work scientists do enchances their lives to be? Finally, calculate and report the population proportion.

This sampling distribution is left-skewed.

I would guess that the true proportion is 0.80. The population proportion is actually 0.8034333.

sample_props15 <- global_monitor %>%
                    rep_sample_n(size = 15, reps = 2000, replace = TRUE) %>%
                    count(scientist_work) %>%
                    mutate(p_hat = n /sum(n)) %>%
                    filter(scientist_work == "Benefits")

ggplot(data = sample_props15, aes(x = p_hat)) +
  geom_histogram(binwidth = 0.02) +
  labs(
    x = "p_hat (Benefits)",
    title = "Sampling distribution of p_hat",
    subtitle = "Sample size = 15, Number of samples = 2000"
  )

mean(sample_props15$p_hat)
## [1] 0.7996333

Exercise 9

Change your sample size from 15 to 150, then compute the sampling distribution using the same method as above, and store these proportions in a new object called sample_props150. Describe the shape of this sampling distribution and compare it to the sampling distribution for a sample size of 15. Based on this sampling distribution, what would you guess to be the true proportion of those who think the work scientists do enchances their lives?

This sampling distribution is about normally distributed. It is much more normal than the distribution for a sample size of 15.

I would guess the true proportion of those who think scientists enhance lives is about 0.80.

sample_props150 <- global_monitor %>%
                    rep_sample_n(size = 150, reps = 2000, replace = TRUE) %>%
                    count(scientist_work) %>%
                    mutate(p_hat = n /sum(n)) %>%
                    filter(scientist_work == "Benefits")

ggplot(data = sample_props150, aes(x = p_hat)) +
  geom_histogram(binwidth = 0.02) +
  labs(
    x = "p_hat (Benefits)",
    title = "Sampling distribution of p_hat",
    subtitle = "Sample size = 150, Number of samples = 2000"
  )

Exercise 10

Of the sampling distributions from 2 and 3, which has a smaller spread? If you’re concerned with making estimates that are more often close to the true value, would you prefer a sampling distribution with a large or small spread?

The sampling distribution from exercise 9 has a smaller spread. I would prefer a sampling distribution with a small spread, because it is more likely to be more accurate. Distributions with a small spread have less of an error typically. Also, in the examples I have done, the population proportion was at the center of the distributions with less spread and with more spread, so it probably does not matter which one is used. Using a distribution with more spread will more likely contain the true proportion, but the center of the distribution might not be as accurate as one with less spread.

LS0tDQp0aXRsZTogIkxhYiA1YTogU2FtcGxpbmcgRGlzdHJpYnV0aW9ucyINCmF1dGhvcjogIkp1bGlhIEZlcnJpcyINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDogb3BlbmludHJvOjpsYWJfcmVwb3J0DQotLS0NCg0KYGBge3J9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFKQ0Kc2V0LnNlZWQoMTIzNCkNCmBgYA0KDQpgYGB7ciBsb2FkLXBhY2thZ2VzLCBtZXNzYWdlPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KG9wZW5pbnRybykNCmxpYnJhcnkoaW5mZXIpDQoNCmBgYA0KDQojIyBFeGVyY2lzZSAxDQoNCiMjIyBEZXNjcmliZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHJlc3BvbnNlcyBpbiB0aGlzIHNhbXBsZS4gSG93IGRvZXMgaXQgY29tcGFyZSB0byB0aGUgZGlzdHJpYnV0aW9uIG9mIHJlc3BvbnNlcyBpbiB0aGUgcG9wdWxhdGlvbi4gKipIaW50OioqIEFsdGhvdWdoIHRoZSBzYW1wbGVfbiBmdW5jdGlvbiB0YWtlcyBhIHJhbmRvbSBzYW1wbGUgb2Ygb2JzZXJ2YXRpb25zIChpLmUuIHJvd3MpIGZyb20gdGhlIGRhdGFzZXQsIHlvdSBjYW4gc3RpbGwgcmVmZXIgdG8gdGhlIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldCB3aXRoIHRoZSBzYW1lIG5hbWVzLiBDb2RlIHlvdSBwcmVzZW50ZWQgZWFybGllciBmb3IgdmlzdWFsaXppbmcgYW5kIHN1bW1hcml6aW5nIHRoZSBwb3B1bGF0aW9uIGRhdGEgd2lsbCBzdGlsbCBiZSB1c2VmdWwgZm9yIHRoZSBzYW1wbGUsIGhvd2V2ZXIgYmUgY2FyZWZ1bCB0byBub3QgbGFiZWwgeW91ciBwcm9wb3J0aW9uIGBwYCBzaW5jZSB5b3UncmUgbm93IGNhbGN1bGF0aW5nIGEgc2FtcGxlIHN0YXRpc3RpYywgbm90IGEgcG9wdWxhdGlvbiBwYXJhbWV0ZXJzLiBZb3UgY2FuIGN1c3RvbWl6ZSB0aGUgbGFiZWwgb2YgdGhlIHN0YXRpc3RpY3MgdG8gaW5kaWNhdGUgdGhhdCBpdCBjb21lcyBmcm9tIHRoZSBzYW1wbGUuDQoNClRoZSBkaXN0cmlidXRpb24gaXMgc2ltaWxhciB0byB0aGUgYWN0dWFsIHBvcHVsYXRpb24uIEl0IG9ubHkgZGlmZmVycyBieSBhIHNtYWxsIGRlY2ltYWwgaW4gdGhlIGJlbmVmaXRzIGFuZCBkb2Vzbid0IGJlbmVmaXQgZ3JvdXBzLg0KDQpgYGB7ciBleGVyY2lzZS0xfQ0Kc2V0LnNlZWQoMTIzNCkNCmdsb2JhbF9tb25pdG9yIDwtIHRpYmJsZSgNCiAgc2NpZW50aXN0X3dvcmsgPSBjKHJlcCgiQmVuZWZpdHMiLCA4MDAwMCksIHJlcCgiRG9lc24ndCBiZW5lZml0IiwgMjAwMDApKQ0KKQ0KDQpnZ3Bsb3QoZ2xvYmFsX21vbml0b3IsIGFlcyh4ID0gc2NpZW50aXN0X3dvcmspKSArDQogIGdlb21fYmFyKCkgKw0KICBsYWJzKA0KICAgIHggPSAiIiwgeSA9ICIiLA0KICAgIHRpdGxlID0gIkRvIHlvdSBiZWxpZXZlIHRoYXQgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBiZW5lZml0IHBlb3BsZSBsaWtlIHlvdT8iDQogICkgKw0KICBjb29yZF9mbGlwKCkgDQoNCmdsb2JhbF9tb25pdG9yICU+JQ0KICBjb3VudChzY2llbnRpc3Rfd29yaykgJT4lDQogIG11dGF0ZShwID0gbiAvc3VtKG4pKQ0KDQpzZXQuc2VlZCgxMjM0KQ0KDQpzYW1wMSA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgc2FtcGxlX24oNTApDQoNCmdncGxvdChzYW1wMSwgYWVzKHggPSBzY2llbnRpc3Rfd29yaykpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoDQogICAgeCA9ICIiLCB5ID0gIiIsDQogICAgdGl0bGUgPSAiRG8geW91IGJlbGlldmUgdGhhdCB0aGUgd29yayBzY2llbnRpc3RzIGRvIGJlbmVmaXQgcGVvcGxlIGxpa2UgeW91PyINCiAgKSArDQogIGNvb3JkX2ZsaXAoKSANCg0Kc2FtcDEgJT4lDQogIGNvdW50KHNjaWVudGlzdF93b3JrKSAlPiUNCiAgbXV0YXRlKHBfaGF0ID0gbiAvc3VtKG4pKQ0KYGBgDQoNCiMjIEV4ZXJjaXNlIDINCg0KIyMjIFdvdWxkIHlvdSBleHBlY3QgdGhlIHNhbXBsZSBwcm9wb3J0aW9uIHRvIG1hdGNoIHRoZSBzYW1wbGUgcHJvcG9ydGlvbiBvZiBhbm90aGVyIHN0dWRlbnQncyBzYW1wbGU/IFdoeSwgb3Igd2h5IG5vdD8gSWYgdGhlIGFuc3dlciBpcyBubywgd291bGQgeW91IGV4cGVjdCB0aGUgcHJvcG9ydGlvbnMgdG8gYmUgc29tZXdoYXQgZGlmZmVyZW50IG9yIHZlcnkgZGlmZmVyZW50PyBBc2sgYSBzdHVkZW50IHRlYW0gdG8gY29uZmlybSB5b3VyIGFuc3dlci4NCg0KSSB3b3VsZCBleHBlY3QgdGhlIHNhbXBsZSBwcm9wb3J0aW9uIHRvIGJlIHNpbWlsYXIgdG8gYW5vdGhlciBzdHVkZW50J3Mgc2FtcGxlLiBJZiB0aGV5IHVzZWQgdGhlIHNhbWUgc2VlZCwgdGhlbiBpdCB3b3VsZCBiZSB0aGUgc2FtZS4gSWYgdGhleSB1c2VkIGEgZGlmZmVyZW50IHNlZWQsIGl0IHdvdWxkIGxpa2VseSBiZSBkaWZmZXJlbnQgYnV0IHNpbWlsYXIuIEkgd291bGQgZXhwZWN0IHRoZW0gdG8gYmUgc2ltaWxhciBiZWNhdXNlIHRoZSBvcmlnaW5hbCBkYXRhIHdhcyA4MCUgdG8gMjAlLCBzbyB0aGUgc2FtcGxlIHdvdWxkIHByb2JhYmx5IGJlIGNsb3NlIHRvIHRoaXMuIFRoZXkgYXJlIG11Y2ggbW9yZSBsaWtlbHkgdG8gZ2V0IGNsb3NlIHRvIDgwJSBmb3IgdGhlIEJlbmVmaXRzIGdyb3VwIGFuZCBjbG9zZSBvIDIwJSBmb3IgdGhlIERvZXNuJ3QgQmVuZWZpdCBncm91cC4gSSBjb25maXJtZWQgbXkgYW5zd2VyIGJ5IHJ1bm5pbmcgdGhlIHNhbXBsZSBhZ2FpbiB3aXRoIGEgZGlmZmVyZW50IHNlZWQuIFRoZSByZXN1bHRzIHdlcmUgNzIlIGFuZCAyOCUuIFRoaXMgaXMgc2ltaWxhciB0byBteSBzYW1wbGUuDQoNCmBgYHtyIGV4ZXJjaXNlLTJ9DQpzZXQuc2VlZCg1Njc4KQ0KDQpzYW1wIDwtIGdsb2JhbF9tb25pdG9yICU+JQ0KICBzYW1wbGVfbig1MCkNCg0KZ2dwbG90KHNhbXAsIGFlcyh4ID0gc2NpZW50aXN0X3dvcmspKSArDQogIGdlb21fYmFyKCkgKw0KICBsYWJzKA0KICAgIHggPSAiIiwgeSA9ICIiLA0KICAgIHRpdGxlID0gIkRvIHlvdSBiZWxpZXZlIHRoYXQgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBiZW5lZml0IHBlb3BsZSBsaWtlIHlvdT8iDQogICkgKw0KICBjb29yZF9mbGlwKCkgDQoNCnNhbXAgfD4NCiAgY291bnQoc2NpZW50aXN0X3dvcmspIHw+DQogIG11dGF0ZShwX2hhdCA9IG4gL3N1bShuKSkNCmBgYA0KDQojIyBFeGVyY2lzZSAzDQoNCiMjIyBUYWtlIGEgc2Vjb25kIHNhbXBsZSwgYWxzbyBvZiBzaXplIDUwLCBhbmQgY2FsbCBpdCBzYW1wMi4gSG93IGRvZXMgdGhlIHNhbXBsZSBwcm9wb3J0aW9uIG9mIHNhbXAyIGNvbXBhcmUgd2l0aCB0aGF0IG9mIHNhbXAxPyBTdXBwb3NlIHdlIHRvb2sgdHdvIG1vcmUgc2FtcGxlcywgb25lIG9mIHNpemUgMTAwIGFuZCBvbmUgb2Ygc2l6ZSAxMDAwLiBXaGljaCB3b3VsZCB5b3UgdGhpbmsgd291bGQgcHJvdmlkZSBhIG1vcmUgYWNjdXJhdGUgZXN0aW1hdGUgb2YgdGhlIHBvcHVsYXRpb24gcHJvcG9ydGlvbj8NCg0KVGhlIHNhbXBsZSBwcm9wb3J0aW9uIGlzIHNpbWlsYXIgdG8gc2FtcDEuIFRoZSB0d28gcHJvcG9ydGlvbnMgYXJlIG9mZiBieSBhIGZldyB0ZW50aHMgb2YgYSBwZXJjZW50LiBJIHdvdWxkIGFzc3VtZSBhIHNhbXBsZSBvZiAxMDAwIHdvdWxkIGJlIG1vcmUgYWNjdXJhdGUuIEkgdGVzdGVkIGl0IGJlbG93LCBhbmQgaXQgdHVybmVkIG91dCB0aGF0IHRoZSBzYW1wbGUgb2Ygc2l6ZSAxMDAwIHdhcyBtb3JlIGFjY3VyYXRlLiBUaGUgcmVzdWx0cyBhbHNvIGFyZSBwcm9iYWJseSBhZmZlY3RlZCBieSB0aGUgc2VlZCwgYnV0IGluIHRoaXMgY2FzZSwgdGhlIHNhbXBsZSBvZiBzaXplIDEwMDAgd2FzIG1vcmUgYWNjdXJhdGUgdGhhbiAxMDAuDQoNCmBgYHtyIGV4ZXJjaXNlLTN9DQpzZXQuc2VlZCgyNDYpDQoNCnNhbXAyIDwtIGdsb2JhbF9tb25pdG9yICU+JQ0KICBzYW1wbGVfbig1MCkNCg0KZ2dwbG90KHNhbXAyLCBhZXMoeCA9IHNjaWVudGlzdF93b3JrKSkgKw0KICBnZW9tX2JhcigpICsNCiAgbGFicygNCiAgICB4ID0gIiIsIHkgPSAiIiwNCiAgICB0aXRsZSA9ICJEbyB5b3UgYmVsaWV2ZSB0aGF0IHRoZSB3b3JrIHNjaWVudGlzdHMgZG8gYmVuZWZpdCBwZW9wbGUgbGlrZSB5b3U/Ig0KICApICsNCiAgY29vcmRfZmxpcCgpIA0KDQpzYW1wMiB8Pg0KICBjb3VudChzY2llbnRpc3Rfd29yaykgfD4NCiAgbXV0YXRlKHBfaGF0ID0gbiAvc3VtKG4pKQ0KDQpzZXQuc2VlZCg1MDApDQoNCnNhbXAzIDwtIGdsb2JhbF9tb25pdG9yICU+JQ0KICBzYW1wbGVfbigxMDApDQoNCmdncGxvdChzYW1wMywgYWVzKHggPSBzY2llbnRpc3Rfd29yaykpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoDQogICAgeCA9ICIiLCB5ID0gIiIsDQogICAgdGl0bGUgPSAiRG8geW91IGJlbGlldmUgdGhhdCB0aGUgd29yayBzY2llbnRpc3RzIGRvIGJlbmVmaXQgcGVvcGxlIGxpa2UgeW91PyINCiAgKSArDQogIGNvb3JkX2ZsaXAoKSANCg0Kc2FtcDMgfD4NCiAgY291bnQoc2NpZW50aXN0X3dvcmspIHw+DQogIG11dGF0ZShwX2hhdCA9IG4gL3N1bShuKSkNCg0Kc2V0LnNlZWQoNTAwKQ0KDQpzYW1wNCA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgc2FtcGxlX24oMTAwMCkNCg0KZ2dwbG90KHNhbXA0LCBhZXMoeCA9IHNjaWVudGlzdF93b3JrKSkgKw0KICBnZW9tX2JhcigpICsNCiAgbGFicygNCiAgICB4ID0gIiIsIHkgPSAiIiwNCiAgICB0aXRsZSA9ICJEbyB5b3UgYmVsaWV2ZSB0aGF0IHRoZSB3b3JrIHNjaWVudGlzdHMgZG8gYmVuZWZpdCBwZW9wbGUgbGlrZSB5b3U/Ig0KICApICsNCiAgY29vcmRfZmxpcCgpIA0KDQpzYW1wNCB8Pg0KICBjb3VudChzY2llbnRpc3Rfd29yaykgfD4NCiAgbXV0YXRlKHBfaGF0ID0gbiAvc3VtKG4pKQ0KYGBgDQoNCiMjIEV4ZXJjaXNlIDQNCg0KIyMjIEhvdyBtYW55IGVsZW1lbnRzIGFyZSB0aGVyZSBpbiBzYW1wbGVfcHJvcHM1MD8gRGVzY3JpYmUgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiwgYW5kIGJlIHN1cmUgdG8gc3BlY2lmaWNhbGx5IG5vdGUgaXRzIGNlbnRlci4gTWFrZSBzdXJlIHRvIGluY2x1ZGUgYSBwbG90IG9mIHRoZSBkaXN0cmlidXRpb24gaW4geW91ciBhbnN3ZXIuDQoNCkl0IGhhcyAxNDk5OSByb3dzIChlbGVtZW50cyksIGJ1dCBpdCBpcyBzdXBwb3NlZCB0byBoYXZlIDE1MDAwLiBUaGUgZGlzdHJpYnV0aW9uIGxvb2tzIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiBJdCBpcyBzeW1tZXRyaWNhbCB3aXRoIGEgYmVsbCBjdXJ2ZS4gVGhlIGNlbnRlciBpcyBhdCAwLiwgd2hpY2ggaXMgdGhlIG9yaWdpbmFsIHByb3BvcnRpb24gZm9yIHRoZSBwb3B1bGF0aW9uLg0KDQpgYGB7ciBleGVyY2lzZS00fQ0Kc2FtcGxlX3Byb3BzNTAgPC0gZ2xvYmFsX21vbml0b3IgJT4lDQogICAgICAgICAgICAgICAgICAgIHJlcF9zYW1wbGVfbihzaXplID0gNTAsIHJlcHMgPSAxNTAwMCwgcmVwbGFjZSA9IFRSVUUpICU+JQ0KICAgICAgICAgICAgICAgICAgICBjb3VudChzY2llbnRpc3Rfd29yaykgJT4lDQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShwX2hhdCA9IG4gL3N1bShuKSkgJT4lDQogICAgICAgICAgICAgICAgICAgIGZpbHRlcihzY2llbnRpc3Rfd29yayA9PSAiRG9lc24ndCBiZW5lZml0IikNCg0KbGVuZ3RoKHNhbXBsZV9wcm9wczUwJHNjaWVudGlzdF93b3JrKQ0KDQpnZ3Bsb3QoZGF0YSA9IHNhbXBsZV9wcm9wczUwLCBhZXMoeCA9IHBfaGF0KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDIpICsNCiAgbGFicygNCiAgICB4ID0gInBfaGF0IChEb2Vzbid0IGJlbmVmaXQpIiwNCiAgICB0aXRsZSA9ICJTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgcF9oYXQiLA0KICAgIHN1YnRpdGxlID0gIlNhbXBsZSBzaXplID0gNTAsIE51bWJlciBvZiBzYW1wbGVzID0gMTUwMDAiDQogICkNCmBgYA0KDQojIyBFeGVyY2lzZSA1DQoNCiMjIyBUbyBtYWtlIHN1cmUgeW91IHVuZGVyc3RhbmQgaG93IHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgYXJlIGJ1aWx0LCBhbmQgZXhhY3RseSB3aGF0IHRoZSByZXBfc2FtcGxlX24gZnVuY3Rpb24gZG9lcywgdHJ5IG1vZGlmeWluZyB0aGUgY29kZSB0byBjcmVhdGUgYSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgKioyNSBzYW1wbGUgcHJvcG9ydGlvbnMqKiBmcm9tICoqc2FtcGxlcyBvZiBzaXplIDEwKiosIGFuZCBwdXQgdGhlbSBpbiBhIGRhdGEgZnJhbWUgbmFtZWQgc2FtcGxlX3Byb3BzX3NtYWxsLiBQcmludCB0aGUgb3V0cHV0LiBIb3cgbWFueSBvYnNlcnZhdGlvbnMgYXJlIHRoZXJlIGluIHRoaXMgb2JqZWN0IGNhbGxlZCBzYW1wbGVfcHJvcHNfc21hbGw/IFdoYXQgZG9lcyBlYWNoIG9ic2VydmF0aW9uIHJlcHJlc2VudD8NCg0KVGhlcmUgYXJlIDI0IG9ic2VydmF0aW9ucyBpbiB0aGUgb2JqZWN0LiBFYWNoIG9ic2VydmF0aW9uIHJlcHJlc2VudHMgb25lIHJlcGV0aXRpb24gb2YgdGFraW5nIGEgc2FtcGxlIG9mIDEwIHBlb3BsZSBhbmQgZ2V0dGluZyB0aGUgcHJvcG9ydGlvbiBvZiBwZW9wbGUgd2hvIHNhaWQgRG9lc24ndCBCZW5lZml0Lg0KDQpgYGB7ciBleGVyY2lzZS01fQ0Kc2FtcGxlX3Byb3BzX3NtYWxsIDwtIGdsb2JhbF9tb25pdG9yICU+JQ0KICAgICAgICAgICAgICAgICAgICByZXBfc2FtcGxlX24oc2l6ZSA9IDEwLCByZXBzID0gMjUsIHJlcGxhY2UgPSBUUlVFKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgY291bnQoc2NpZW50aXN0X3dvcmspICU+JQ0KICAgICAgICAgICAgICAgICAgICBtdXRhdGUocF9oYXQgPSBuIC9zdW0obikpICU+JQ0KICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoc2NpZW50aXN0X3dvcmsgPT0gIkRvZXNuJ3QgYmVuZWZpdCIpDQoNCmdncGxvdChkYXRhID0gc2FtcGxlX3Byb3BzX3NtYWxsLCBhZXMoeCA9IHBfaGF0KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDIpICsNCiAgbGFicygNCiAgICB4ID0gInBfaGF0IChEb2Vzbid0IGJlbmVmaXQpIiwNCiAgICB0aXRsZSA9ICJTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgcF9oYXQiLA0KICAgIHN1YnRpdGxlID0gIlNhbXBsZSBzaXplID0gMTAsIE51bWJlciBvZiBzYW1wbGVzID0gMjUiDQogICkNCmBgYA0KDQojIyBFeGVyY2lzZSA2DQoNCiMjIyBVc2UgdGhlIGFwcCBiZWxvdyB0byBjcmVhdGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBvZiBwcm9wb3J0aW9ucyBvZiAqRG9lc24ndCBiZW5lZml0KiBmcm9tIHNhbXBsZXMgb2Ygc2l6ZSAxMCwgNTAsIGFuZCAxMDAuIFVzZSA1LDAwMCBzaW11bGF0aW9ucy4gV2hhdCBkb2VzIGVhY2ggb2JzZXJ2YXRpb24gaW4gdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiByZXByZXNlbnQ/IEhvdyBkb2VzIHRoZSBtZWFuLCBzdGFuZGFyZCBlcnJvciwgYW5kIHNoYXBlIG9mIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gY2hhbmdlIGFzIHRoZSBzYW1wbGUgc2l6ZSBpbmNyZWFzZXM/IEhvdyAoaWYgYXQgYWxsKSBkbyB0aGVzZSB2YWx1ZXMgY2hhbmdlIGlmIHlvdSBpbmNyZWFzZSB0aGUgbnVtYmVyIG9mIHNpbXVsYXRpb25zPyAoWW91IGRvIG5vdCBuZWVkIHRvIGluY2x1ZGUgcGxvdHMgaW4geW91ciBhbnN3ZXIuKQ0KDQpFYWNoIG9ic2VydmF0aW9uIGluIHRoZSBkaXN0cmlidXRpb24gcmVwcmVzZW50cyB0aGUgcHJvcG9ydGlvbiBpbiBvbmUgc2FtcGxlIG9mIHBlb3BsZSB3aG8gcmVzcG9uZGVkICJEb2Vzbid0IEJlbmVmaXQuIg0KDQpXaGVuIHRoZSBzYW1wbGUgc2l6ZSBpbmNyZWFzZWQgZnJvbSAxMCB0byA1MCwgdGhlIG1lYW4gYmVjYW1lIHRoZSBzYW1lIGFzIHRoZSBwb3B1bGF0aW9uIHByb3BvcnRpb24sIGFuZCB0aGUgc3RhbmRhcmQgZXJyb3IgZGVjcmVhc2VkLiBBbHNvLCB0aGUgc2hhcGUgb2YgdGhlIGRpc3RyaWJ1dGlvbiBiZWNhbWUgbXVjaCBtb3JlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiBXaGVuIHRoZSBzYW1wbGUgc2l6ZSBpbmNyZWFzZWQgZnJvbSA1MCB0byAxMDAsIHRoZSBtZWFuIHJlbWFpbmVkIHRoZSBzYW1lIChlcXVhbCB0byB0aGUgcG9wdWxhdGlvbiBwcm9wb3J0aW9uKSwgYW5kIHRoZSBzdGFuZGFyZCBlcnJvciBkZWNyZWFzZWQuIEFsc28sIHRoZSBzaGFwZSBvZiB0aGUgZGlzdHJpYnV0aW9uIHN0YXllZCBub3JtYWxseSBkaXN0cmlidXRlZC4NCg0KSW5jcmVhc2luZyB0aGUgbnVtYmVyIG9mIHNpbXVsYXRpb25zIGJhcmVseSBjaGFuZ2VkIHRoZSBtZWFuIG9yIHN0YW5kYXJkIGVycm9yLCBidXQgdGhlIGRpc3RyaWJ1dGlvbnMgYmVjYW1lIG1vcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgd2l0aCBhIGhpZ2hlciBudW1iZXIgb2Ygc2ltdWxhdGlvbnMuDQoNCmBgYHtyIGV4ZXJjaXNlLTYsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0UsIHJlc3VsdHMgPSBUUlVFfQ0KIyBUaGlzIFIgY2h1bmsgd2lsbCBvbmx5IHJ1biBpbiBpbnRlcmFjdGl2ZSBtb2RlLg0Kc2hpbnlBcHAoDQogIHVpIDwtIGZsdWlkUGFnZSgNCiAgICANCiAgICAjIFNpZGViYXIgd2l0aCBhIHNsaWRlciBpbnB1dCBmb3IgbnVtYmVyIG9mIGJpbnMgDQogICAgc2lkZWJhckxheW91dCgNCiAgICAgIHNpZGViYXJQYW5lbCgNCiAgICAgICAgDQogICAgICAgIHNlbGVjdElucHV0KCJvdXRjb21lIiwNCiAgICAgICAgICAgICAgICAgICAgIk91dGNvbWUgb2YgaW50ZXJlc3Q6IiwNCiAgICAgICAgICAgICAgICAgICAgY2hvaWNlcyA9IGMoIkJlbmVmaXRzIiwgIkRvZXNuJ3QgYmVuZWZpdCIpLA0KICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZCA9ICJEb2Vzbid0IGJlbmVmaXQiKSwNCiAgICAgICAgDQogICAgICAgIG51bWVyaWNJbnB1dCgibl9zYW1wIiwNCiAgICAgICAgICAgICAgICAgICAgICJTYW1wbGUgc2l6ZToiLA0KICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwNCiAgICAgICAgICAgICAgICAgICAgIG1heCA9IG5yb3coZ2xvYmFsX21vbml0b3IpLA0KICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAzMCksDQogICAgICAgIA0KICAgICAgICBudW1lcmljSW5wdXQoIm5fcmVwIiwNCiAgICAgICAgICAgICAgICAgICAgICJOdW1iZXIgb2Ygc2FtcGxlczoiLA0KICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwNCiAgICAgICAgICAgICAgICAgICAgIG1heCA9IDMwMDAwLA0KICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAxNTAwMCksDQogICAgICAgIA0KICAgICAgICBocigpLA0KICAgICAgICANCiAgICAgICAgc2xpZGVySW5wdXQoImJpbndpZHRoIiwNCiAgICAgICAgICAgICAgICAgICAgIkJpbndpZHRoOiIsDQogICAgICAgICAgICAgICAgICAgIG1pbiA9IDAsIG1heCA9IDAuNSwNCiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAwLjAyLA0KICAgICAgICAgICAgICAgICAgICBzdGVwID0gMC4wMDUpDQogICAgICAgIA0KICAgICAgKSwNCiAgICAgIA0KICAgICAgIyBTaG93IGEgcGxvdCBvZiB0aGUgZ2VuZXJhdGVkIGRpc3RyaWJ1dGlvbg0KICAgICAgbWFpblBhbmVsKA0KICAgICAgICBwbG90T3V0cHV0KCJzYW1wbGluZ19wbG90IiksDQogICAgICAgIHRleHRPdXRwdXQoInNhbXBsaW5nX21lYW4iKSwNCiAgICAgICAgdGV4dE91dHB1dCgic2FtcGxpbmdfc2UiKQ0KICAgICAgKQ0KICAgICkNCiAgKSwNCiAgDQogIHNlcnZlciA8LSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0KSB7DQogICAgDQogICAgIyBjcmVhdGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uDQogICAgc2FtcGxpbmdfZGlzdCA8LSByZWFjdGl2ZSh7DQogICAgICBnbG9iYWxfbW9uaXRvciAlPiUNCiAgICAgICAgcmVwX3NhbXBsZV9uKHNpemUgPSBpbnB1dCRuX3NhbXAsIHJlcHMgPSBpbnB1dCRuX3JlcCwgcmVwbGFjZSA9IFRSVUUpICU+JQ0KICAgICAgICBjb3VudChzY2llbnRpc3Rfd29yaykgJT4lDQogICAgICAgIG11dGF0ZShwX2hhdCA9IG4gL3N1bShuKSkgJT4lDQogICAgICAgIGZpbHRlcihzY2llbnRpc3Rfd29yayA9PSBpbnB1dCRvdXRjb21lKQ0KICAgIH0pDQogICAgDQogICAgIyBwbG90IHNhbXBsaW5nIGRpc3RyaWJ1dGlvbg0KICAgIG91dHB1dCRzYW1wbGluZ19wbG90IDwtIHJlbmRlclBsb3Qoew0KICAgICAgDQogICAgICBnZ3Bsb3Qoc2FtcGxpbmdfZGlzdCgpLCBhZXMoeCA9IHBfaGF0KSkgKw0KICAgICAgICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IGlucHV0JGJpbndpZHRoKSArDQogICAgICAgIHhsaW0oMCwgMSkgKw0KICAgICAgICBsYWJzKA0KICAgICAgICAgIHggPSBwYXN0ZTAoInBfaGF0ICgiLCBpbnB1dCRvdXRjb21lLCAiKSIpLA0KICAgICAgICAgIHRpdGxlID0gIlNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiBwX2hhdCIsDQogICAgICAgICAgc3VidGl0bGUgPSBwYXN0ZTAoIlNhbXBsZSBzaXplID0gIiwgaW5wdXQkbl9zYW1wLCAiIE51bWJlciBvZiBzYW1wbGVzID0gIiwgaW5wdXQkbl9yZXApDQogICAgICAgICkgKw0KICAgICAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNikpDQogICAgfSkNCiAgICANCiAgICBnZ3Bsb3QoZGF0YSA9IHNhbXBsZV9wcm9wczUwLCBhZXMoeCA9IHBfaGF0KSkgKw0KICAgICAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAyKSArDQogICAgICBsYWJzKA0KICAgICAgICB4ID0gInBfaGF0IChEb2Vzbid0IGJlbmVmaXQpIiwNCiAgICAgICAgdGl0bGUgPSAiU2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHBfaGF0IiwNCiAgICAgICAgc3VidGl0bGUgPSAiU2FtcGxlIHNpemUgPSA1MCwgTnVtYmVyIG9mIHNhbXBsZXMgPSAxNTAwMCINCiAgICAgICkNCiAgICANCiAgICAjIG1lYW4gb2Ygc2FtcGxpbmcgZGlzdHJpYnV0aW9uDQogICAgb3V0cHV0JHNhbXBsaW5nX21lYW4gPC0gcmVuZGVyVGV4dCh7DQogICAgICBwYXN0ZTAoIk1lYW4gb2Ygc2FtcGxpbmcgZGlzdHJpYnV0aW9uID0gIiwgcm91bmQobWVhbihzYW1wbGluZ19kaXN0KCkkcF9oYXQpLCAyKSkNCiAgICB9KQ0KICAgIA0KICAgICMgbWVhbiBvZiBzYW1wbGluZyBkaXN0cmlidXRpb24NCiAgICBvdXRwdXQkc2FtcGxpbmdfc2UgPC0gcmVuZGVyVGV4dCh7DQogICAgICBwYXN0ZTAoIlNFIG9mIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiA9ICIsIHJvdW5kKHNkKHNhbXBsaW5nX2Rpc3QoKSRwX2hhdCksIDIpKQ0KICAgIH0pDQogIH0sDQogIA0KICBvcHRpb25zID0gbGlzdChoZWlnaHQgPSA5MDApIA0KKQ0KYGBgDQoNCiMjIEV4ZXJjaXNlIDcNCg0KIyMjIFRha2UgYSBzYW1wbGUgb2Ygc2l6ZSAxNSBmcm9tIHRoZSBwb3B1bGF0aW9uIGFuZCBjYWxjdWxhdGUgdGhlIHByb3BvcnRpb24gb2YgcGVvcGxlIGluIHRoaXMgc2FtcGxlIHdobyB0aGluayB0aGUgd29yayBzY2llbnRpc3RzIGRvIGVuaGFuY2VzIHRoZWlyIGxpdmVzLiBVc2luZyB0aGlzIHNhbXBsZSwgd2hhdCBpcyB5b3VyIGJlc3QgcG9pbnQgZXN0aW1hdGUgb2YgdGhlIHBvcHVsYXRpb24gcHJvcG9ydGlvbiBvZiBwZW9wbGUgd2hvIHRoaW5rIHRoZSB3b3JrIHNjaWVudGlzdHMgZG8gZW5jaGFuY2VzIHRoZWlyIGxpdmVzPw0KDQpUaGUgZXN0aW1hdGUgSSBjYWxjdWxhdGVkIGZyb20gdGhpcyBzYW1wbGUgd2FzIGFib3V0IDAuNzMuDQoNCmBgYHtyIGV4ZXJjaXNlLTd9DQpzZXQuc2VlZCgxMjM0KQ0KDQpzYW1wMSA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgc2FtcGxlX24oMTUpDQoNCmdncGxvdChzYW1wMSwgYWVzKHggPSBzY2llbnRpc3Rfd29yaykpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoDQogICAgeCA9ICIiLCB5ID0gIiIsDQogICAgdGl0bGUgPSAiRG8geW91IGJlbGlldmUgdGhhdCB0aGUgd29yayBzY2llbnRpc3RzIGRvIGJlbmVmaXQgcGVvcGxlIGxpa2UgeW91PyINCiAgKSArDQogIGNvb3JkX2ZsaXAoKSANCg0Kc2FtcDEgJT4lDQogIGNvdW50KHNjaWVudGlzdF93b3JrKSAlPiUNCiAgbXV0YXRlKHBfaGF0ID0gbiAvc3VtKG4pKQ0KDQoNCmBgYA0KDQojIyBFeGVyY2lzZSA4DQoNCiMjIyBTaW5jZSB5b3UgaGF2ZSBhY2Nlc3MgdG8gdGhlIHBvcHVsYXRpb24sIHNpbXVsYXRlIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgcHJvcG9ydGlvbiBvZiB0aG9zZSB3aG8gdGhpbmsgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBlbmNoYW5jZXMgdGhlaXIgbGl2ZXMgZm9yIHNhbXBsZXMgb2Ygc2l6ZSAxNSBieSB0YWtpbmcgMjAwMCBzYW1wbGVzIGZyb20gdGhlIHBvcHVsYXRpb24gb2Ygc2l6ZSAxNSBhbmQgY29tcHV0aW5nIDIwMDAgc2FtcGxlIHByb3BvcnRpb25zLiBTdG9yZSB0aGVzZSBwcm9wb3J0aW9ucyBpbiBhcyBzYW1wbGVfcHJvcHMxNS4gUGxvdCB0aGUgZGF0YSwgdGhlbiBkZXNjcmliZSB0aGUgc2hhcGUgb2YgdGhpcyBzYW1wbGluZyBkaXN0cmlidXRpb24uIEJhc2VkIG9uIHRoaXMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uLCB3aGF0IHdvdWxkIHlvdSBndWVzcyB0aGUgdHJ1ZSBwcm9wb3J0aW9uIG9mIHRob3NlIHdobyB0aGluayB0aGUgd29yayBzY2llbnRpc3RzIGRvIGVuY2hhbmNlcyB0aGVpciBsaXZlcyB0byBiZT8gRmluYWxseSwgY2FsY3VsYXRlIGFuZCByZXBvcnQgdGhlIHBvcHVsYXRpb24gcHJvcG9ydGlvbi4NCg0KVGhpcyBzYW1wbGluZyBkaXN0cmlidXRpb24gaXMgbGVmdC1za2V3ZWQuDQoNCkkgd291bGQgZ3Vlc3MgdGhhdCB0aGUgdHJ1ZSBwcm9wb3J0aW9uIGlzIDAuODAuIFRoZSBwb3B1bGF0aW9uIHByb3BvcnRpb24gaXMgYWN0dWFsbHkgMC44MDM0MzMzLg0KDQpgYGB7ciBleGVyY2lzZS04fQ0KDQpzYW1wbGVfcHJvcHMxNSA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgICAgICAgICAgICAgICAgICAgcmVwX3NhbXBsZV9uKHNpemUgPSAxNSwgcmVwcyA9IDIwMDAsIHJlcGxhY2UgPSBUUlVFKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgY291bnQoc2NpZW50aXN0X3dvcmspICU+JQ0KICAgICAgICAgICAgICAgICAgICBtdXRhdGUocF9oYXQgPSBuIC9zdW0obikpICU+JQ0KICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoc2NpZW50aXN0X3dvcmsgPT0gIkJlbmVmaXRzIikNCg0KZ2dwbG90KGRhdGEgPSBzYW1wbGVfcHJvcHMxNSwgYWVzKHggPSBwX2hhdCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAyKSArDQogIGxhYnMoDQogICAgeCA9ICJwX2hhdCAoQmVuZWZpdHMpIiwNCiAgICB0aXRsZSA9ICJTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgcF9oYXQiLA0KICAgIHN1YnRpdGxlID0gIlNhbXBsZSBzaXplID0gMTUsIE51bWJlciBvZiBzYW1wbGVzID0gMjAwMCINCiAgKQ0KDQptZWFuKHNhbXBsZV9wcm9wczE1JHBfaGF0KQ0KYGBgDQoNCiMjIEV4ZXJjaXNlIDkNCg0KIyMjIENoYW5nZSB5b3VyIHNhbXBsZSBzaXplIGZyb20gMTUgdG8gMTUwLCB0aGVuIGNvbXB1dGUgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiB1c2luZyB0aGUgc2FtZSBtZXRob2QgYXMgYWJvdmUsIGFuZCBzdG9yZSB0aGVzZSBwcm9wb3J0aW9ucyBpbiBhIG5ldyBvYmplY3QgY2FsbGVkIHNhbXBsZV9wcm9wczE1MC4gRGVzY3JpYmUgdGhlIHNoYXBlIG9mIHRoaXMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGFuZCBjb21wYXJlIGl0IHRvIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gZm9yIGEgc2FtcGxlIHNpemUgb2YgMTUuIEJhc2VkIG9uIHRoaXMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uLCB3aGF0IHdvdWxkIHlvdSBndWVzcyB0byBiZSB0aGUgdHJ1ZSBwcm9wb3J0aW9uIG9mIHRob3NlIHdobyB0aGluayB0aGUgd29yayBzY2llbnRpc3RzIGRvIGVuY2hhbmNlcyB0aGVpciBsaXZlcz8NCg0KVGhpcyBzYW1wbGluZyBkaXN0cmlidXRpb24gaXMgYWJvdXQgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuIEl0IGlzIG11Y2ggbW9yZSBub3JtYWwgdGhhbiB0aGUgZGlzdHJpYnV0aW9uIGZvciBhIHNhbXBsZSBzaXplIG9mIDE1Lg0KDQpJIHdvdWxkIGd1ZXNzIHRoZSB0cnVlIHByb3BvcnRpb24gb2YgdGhvc2Ugd2hvIHRoaW5rIHNjaWVudGlzdHMgZW5oYW5jZSBsaXZlcyBpcyBhYm91dCAwLjgwLg0KDQpgYGB7ciBleGVyY2lzZS05fQ0KDQpzYW1wbGVfcHJvcHMxNTAgPC0gZ2xvYmFsX21vbml0b3IgJT4lDQogICAgICAgICAgICAgICAgICAgIHJlcF9zYW1wbGVfbihzaXplID0gMTUwLCByZXBzID0gMjAwMCwgcmVwbGFjZSA9IFRSVUUpICU+JQ0KICAgICAgICAgICAgICAgICAgICBjb3VudChzY2llbnRpc3Rfd29yaykgJT4lDQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShwX2hhdCA9IG4gL3N1bShuKSkgJT4lDQogICAgICAgICAgICAgICAgICAgIGZpbHRlcihzY2llbnRpc3Rfd29yayA9PSAiQmVuZWZpdHMiKQ0KDQpnZ3Bsb3QoZGF0YSA9IHNhbXBsZV9wcm9wczE1MCwgYWVzKHggPSBwX2hhdCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAyKSArDQogIGxhYnMoDQogICAgeCA9ICJwX2hhdCAoQmVuZWZpdHMpIiwNCiAgICB0aXRsZSA9ICJTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgcF9oYXQiLA0KICAgIHN1YnRpdGxlID0gIlNhbXBsZSBzaXplID0gMTUwLCBOdW1iZXIgb2Ygc2FtcGxlcyA9IDIwMDAiDQogICkNCg0KYGBgDQoNCiMjIEV4ZXJjaXNlIDEwDQoNCiMjIyBPZiB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBmcm9tIDIgYW5kIDMsIHdoaWNoIGhhcyBhIHNtYWxsZXIgc3ByZWFkPyBJZiB5b3UncmUgY29uY2VybmVkIHdpdGggbWFraW5nIGVzdGltYXRlcyB0aGF0IGFyZSBtb3JlIG9mdGVuIGNsb3NlIHRvIHRoZSB0cnVlIHZhbHVlLCB3b3VsZCB5b3UgcHJlZmVyIGEgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIHdpdGggYSBsYXJnZSBvciBzbWFsbCBzcHJlYWQ/DQoNClRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gZnJvbSBleGVyY2lzZSA5IGhhcyBhIHNtYWxsZXIgc3ByZWFkLiBJIHdvdWxkIHByZWZlciBhIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiB3aXRoIGEgc21hbGwgc3ByZWFkLCBiZWNhdXNlIGl0IGlzIG1vcmUgbGlrZWx5IHRvIGJlIG1vcmUgYWNjdXJhdGUuIERpc3RyaWJ1dGlvbnMgd2l0aCBhIHNtYWxsIHNwcmVhZCBoYXZlIGxlc3Mgb2YgYW4gZXJyb3IgdHlwaWNhbGx5LiBBbHNvLCBpbiB0aGUgZXhhbXBsZXMgSSBoYXZlIGRvbmUsIHRoZSBwb3B1bGF0aW9uIHByb3BvcnRpb24gd2FzIGF0IHRoZSBjZW50ZXIgb2YgdGhlIGRpc3RyaWJ1dGlvbnMgd2l0aCBsZXNzIHNwcmVhZCBhbmQgd2l0aCBtb3JlIHNwcmVhZCwgc28gaXQgcHJvYmFibHkgZG9lcyBub3QgbWF0dGVyIHdoaWNoIG9uZSBpcyB1c2VkLiBVc2luZyBhIGRpc3RyaWJ1dGlvbiB3aXRoIG1vcmUgc3ByZWFkIHdpbGwgbW9yZSBsaWtlbHkgY29udGFpbiB0aGUgdHJ1ZSBwcm9wb3J0aW9uLCBidXQgdGhlIGNlbnRlciBvZiB0aGUgZGlzdHJpYnV0aW9uIG1pZ2h0IG5vdCBiZSBhcyBhY2N1cmF0ZSBhcyBvbmUgd2l0aCBsZXNzIHNwcmVhZC4NCg==