1 Problem 1

For this problem, we are asked to summarize and compare Asymptotic and Bootstrap Sampling distributions. We are asked to outline the key assumptions, practical applications, and discuss when and why to use one over the other.

Asymptotic and Bootstrap Sampling Distributions are both probability distributions that are used to estimate sample statistics, like means or standard deviations. They are both used when the distribution of any given population is unknown, or if you don’t have access to any more ways to gather data for whatever reason.

1.1 Asympotitic Distributions

Asymptotic Distributions rely on assumptions from the central limit theorem. The central limit theorem says that if we take a random sample from any given population, then we can say that as we continually increase the sample size (gather more data points), any distribution of a function of said sample should eventually be normally distributed.

Asymptotic Distributions are generally used if a sample size is “large” or when the sample resembles a distribution we are familiar with, like a normal, chi-square, etc.

1.2 Bootstrapped Distributions

Bootstrapping is a nonparametric resampling method in which samples are taken from a sample. In other words, if you have a sample, we treat that sample as our “population” and we would then randomly sample with replacement from that “population”. From there, we can take functions of theses new samples and use those as estimates.

Bootstrapping is generally used when the original sample is small or when data is more complex. There is one similarity with asymptotic distributions: as you take more and more samples, the sampling distribution of a given statistic will eventuall converge to a normal distribution.

2 Problem 2

For this problem, we are interested in analyzing sample means and variances via bootstrapping. To do this, we will use a data set that consists of the volume of coffee sold daily at two different coffee shops:

coffee <- c(2850, 3200, 2900, 3100, 2950, 7800, 8100, 7900, 3300, 3050, 4000, 4200, 3150, 3400, 7700, 8200, 3250, 4400, 3100, 4200, 4500, 4800, 4300, 8500, 8200, 8900, 8700, 3250, 3000, 4600, 4100, 8400, 8800, 3350, 4700, 3100, 8100, 3050, 8300, 4100, 3100, 8300, 8900, 8200, 4400, 4500, 3250, 4600, 8400, 3300, 4200, 4500, 4800, 4300, 8500)

2.1 Part A

I believe that we can use the central limit theorem to derive the asymptotic distribution of the sample mean because our sample size is greater than 30 (n = 55 in our case).

length(coffee)
[1] 55

2.2 Part B

For this part, we will do the bootstrap samples and calculate the sample means for each. They will then be plotted via a histogram. Afterwards we will generate and plot a kernel density estimate for the sample means.

Let’s start by generating and plotting the bootstrapped sampling distribution for the mean. For the sampling distribution, 1000 samples will be used. We will also plot a kernel density curve on the plot:

original.sample = sample(coffee,    # population of all coffee volume sales
55,                      # sample size = 55 
replace = FALSE          # sample without replacement
                 )                              
### Bootstrap sampling begins 
bt.sample.mean.vec = NULL      # define an empty vector to hold sample means of repeated samples.
for(i in 1:1000){              # starting for-loop to take bootstrap samples with n = 55
  ith.bt.sample = sample(x = original.sample, # Original sample with 55 Daily
                       size = 55,             # sample size = 55 MUST be equal to the sample size!!
                    replace = TRUE            # MUST use WITH REPLACEMENT!!
                       )                      # this is the i-th Bootstrap sample
  bt.sample.mean.vec[i] = mean(ith.bt.sample) # calculate the mean of i-th bootstrap sample and 
                                              # save it in the empty vector: sample.bt.mean.vec 
}
###

hist(bt.sample.mean.vec,                     # data from sample
     breaks = 14,                            # specify number of vertical bars
     probability = TRUE,
       xlab = "Bootstrapped Sample Means",      # change the label of x-axis
      # add a title to the histogram
        main = "Bootstrap Sampling Distribution of Sample Means",
          cex.main = 0.9, col = "lightblue"
       )   

lines(density(bt.sample.mean.vec, n = 1000), col = "red", lwd = 2)

# overlays the kernel density estimate for the sample mean

The histogram shape looks pretty normal, although slightly skewed. The kernel density (in red) looks rough, but does resemble a normal curve. Let’s call the kernel seperately and compare:

density(bt.sample.mean.vec, n = 1000)

Call:
    density.default(x = bt.sample.mean.vec, n = 1000)

Data: bt.sample.mean.vec (1000 obs.);   Bandwidth 'bw' = 69.4

       x              y            
 Min.   :4103   Min.   :6.470e-08  
 1st Qu.:4667   1st Qu.:2.124e-05  
 Median :5231   Median :2.768e-04  
 Mean   :5231   Mean   :4.426e-04  
 3rd Qu.:5796   3rd Qu.:8.520e-04  
 Max.   :6360   Max.   :1.268e-03  
mean(coffee)
[1] 5250

The actual sample mean is 5250. Even though the estimate for the mean will change every time you run a sample, it does stay relatively close to the mean (usually between 5220 and 5280). This seems to do a good job of estimating the sample mean.

2.3 Part C

For this part, we will repeat what we did in parts A and B to estimate the sample variance.

I still think that the central limit theorem can apply to estimate the sample variance. Our sample size isn’t changing (n = 55) and the amount of samples we will take won’t change either (samples = 1000).

Now for the bootstrapped samples and the kernel density estimate:

original.sample = sample(coffee,    # population of all daily coffee sales
                       55,                      # sample size = 55 values in the sample
                       replace = FALSE          # sample without replacement
                 )                              
### Bootstrap sampling begins 
bt.sample.var.vec = NULL      # define an empty vector to hold sample means of repeated samples.
for(i in 1:1000){              # starting for-loop to take bootstrap samples with n = 55
  ith.bt.sample = sample(x = original.sample, # Original sample with 55 WCU students' heights
                       size = 55,             # sample size = 55 MUST be equal to the sample size!!
                    replace = TRUE            # MUST use WITH REPLACEMENT!!
                       )                      # this is the i-th Bootstrap sample
  bt.sample.var.vec[i] = var(ith.bt.sample) # calculate the variance of i-th bootstrap sample and 
                                              # save it in the empty vector: sample.bt.var.vec 
}
###
hist(bt.sample.var.vec,                     # data used for histogram
     breaks = 14,                            # specify number of vertical bars
     probability = TRUE,
       xlab = "Bootstrap Sample Variance",      # change the label of x-axis
      # add a title to the histogram
        main="Bootstrap Sampling Distribution of Sample Variances",
          cex.main = 0.9,
       col.main = "navy", col = "lightblue")   
lines(density(bt.sample.var.vec), col = "red", lwd = 2)

Although it resembles a normal distribution, there seems to be a lot more skew compared to the sampling distribution of the mean. I believe some of the potential skew may be coming from just how the graph looks. I don’t think the skew is as bad as it looks.

density(bt.sample.var.vec, n = 1000)

Call:
    density.default(x = bt.sample.var.vec, n = 1000)

Data: bt.sample.var.vec (1000 obs.);    Bandwidth 'bw' = 1.245e+05

       x                 y            
 Min.   :1909410   Min.   :3.570e-11  
 1st Qu.:3075557   1st Qu.:5.538e-09  
 Median :4241705   Median :7.790e-08  
 Mean   :4241705   Mean   :2.142e-07  
 3rd Qu.:5407852   3rd Qu.:3.824e-07  
 Max.   :6573999   Max.   :7.415e-07  
var(coffee)
[1] 5030833

The actual sample variance is 5,030,833. The Kernel Density Estimate usually falls between 4,200,000 and 4,400,000. In rare cases, it may exceed 4,400,000. However, if we keep running the code, the peak of the histograms generated usually float around the 5,000,000 mark. So I think we did a good enough job estimating the sample variance as well.

LS0tDQp0aXRsZTogIlNUQSA1MDYgSG9tZXdvcmsgMzogUmVzYW1wbGluZyBNZXRob2RzIg0KYXV0aG9yOiAiSWFuIFZhbldyaWdodCINCmRhdGU6ICIwMi8xNS8yMDI2Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogMw0KICAgIGZpZ19oZWlnaHQ6IDMNCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICBsaWJyYXJ5KHBsb3RseSkNCn0NCg0KIyMgbGlicmFyeShsZWFwcykNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdSBjYW4gY2hvb3NlIHRvIGluY2x1ZGUgdGhlIHdhcm5pbmcgbWVzc2FnZXMgaW4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbiB0aGUgb3V0cHV0IGZpbGUuDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQ0KICAgICAgICAgICAgICAgICAgICAgICkgIA0KYGBgDQoNClwNCg0KIyBQcm9ibGVtIDENCkZvciB0aGlzIHByb2JsZW0sIHdlIGFyZSBhc2tlZCB0byBzdW1tYXJpemUgYW5kIGNvbXBhcmUgQXN5bXB0b3RpYyBhbmQgQm9vdHN0cmFwIFNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMuIFdlIGFyZSBhc2tlZCB0byBvdXRsaW5lIHRoZSBrZXkgYXNzdW1wdGlvbnMsIHByYWN0aWNhbCBhcHBsaWNhdGlvbnMsIGFuZCBkaXNjdXNzIHdoZW4gYW5kIHdoeSB0byB1c2Ugb25lIG92ZXIgdGhlIG90aGVyLg0KDQpBc3ltcHRvdGljIGFuZCBCb290c3RyYXAgU2FtcGxpbmcgRGlzdHJpYnV0aW9ucyBhcmUgYm90aCBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb25zIHRoYXQgYXJlIHVzZWQgdG8gZXN0aW1hdGUgc2FtcGxlIHN0YXRpc3RpY3MsIGxpa2UgbWVhbnMgb3Igc3RhbmRhcmQgZGV2aWF0aW9ucy4gVGhleSBhcmUgYm90aCB1c2VkIHdoZW4gdGhlIGRpc3RyaWJ1dGlvbiBvZiBhbnkgZ2l2ZW4gcG9wdWxhdGlvbiBpcyB1bmtub3duLCBvciBpZiB5b3UgZG9uJ3QgaGF2ZSBhY2Nlc3MgdG8gYW55IG1vcmUgd2F5cyB0byBnYXRoZXIgZGF0YSBmb3Igd2hhdGV2ZXIgcmVhc29uLg0KDQojIyBBc3ltcG90aXRpYyBEaXN0cmlidXRpb25zDQpBc3ltcHRvdGljIERpc3RyaWJ1dGlvbnMgcmVseSBvbiBhc3N1bXB0aW9ucyBmcm9tIHRoZSBjZW50cmFsIGxpbWl0IHRoZW9yZW0uIFRoZSBjZW50cmFsIGxpbWl0IHRoZW9yZW0gc2F5cyB0aGF0IGlmIHdlIHRha2UgYSByYW5kb20gc2FtcGxlIGZyb20gYW55IGdpdmVuIHBvcHVsYXRpb24sIHRoZW4gd2UgY2FuIHNheSB0aGF0IGFzIHdlIGNvbnRpbnVhbGx5IGluY3JlYXNlIHRoZSBzYW1wbGUgc2l6ZSAoZ2F0aGVyIG1vcmUgZGF0YSBwb2ludHMpLCBhbnkgZGlzdHJpYnV0aW9uIG9mIGEgZnVuY3Rpb24gb2Ygc2FpZCBzYW1wbGUgc2hvdWxkIGV2ZW50dWFsbHkgYmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuDQoNCkFzeW1wdG90aWMgRGlzdHJpYnV0aW9ucyBhcmUgZ2VuZXJhbGx5IHVzZWQgaWYgYSBzYW1wbGUgc2l6ZSBpcyAibGFyZ2UiIG9yIHdoZW4gdGhlIHNhbXBsZSByZXNlbWJsZXMgYSBkaXN0cmlidXRpb24gd2UgYXJlIGZhbWlsaWFyIHdpdGgsIGxpa2UgYSBub3JtYWwsIGNoaS1zcXVhcmUsIGV0Yy4gDQoNCiMjIEJvb3RzdHJhcHBlZCBEaXN0cmlidXRpb25zDQpCb290c3RyYXBwaW5nIGlzIGEgbm9ucGFyYW1ldHJpYyByZXNhbXBsaW5nIG1ldGhvZCBpbiB3aGljaCBzYW1wbGVzIGFyZSB0YWtlbiBmcm9tIGEgc2FtcGxlLiBJbiBvdGhlciB3b3JkcywgaWYgeW91IGhhdmUgYSBzYW1wbGUsIHdlIHRyZWF0IHRoYXQgc2FtcGxlIGFzIG91ciAicG9wdWxhdGlvbiIgYW5kIHdlIHdvdWxkIHRoZW4gcmFuZG9tbHkgc2FtcGxlIHdpdGggcmVwbGFjZW1lbnQgZnJvbSB0aGF0ICJwb3B1bGF0aW9uIi4gRnJvbSB0aGVyZSwgd2UgY2FuIHRha2UgZnVuY3Rpb25zIG9mIHRoZXNlcyBuZXcgc2FtcGxlcyBhbmQgdXNlIHRob3NlIGFzIGVzdGltYXRlcy4NCg0KQm9vdHN0cmFwcGluZyBpcyBnZW5lcmFsbHkgdXNlZCB3aGVuIHRoZSBvcmlnaW5hbCBzYW1wbGUgaXMgc21hbGwgb3Igd2hlbiBkYXRhIGlzIG1vcmUgY29tcGxleC4gVGhlcmUgaXMgb25lIHNpbWlsYXJpdHkgd2l0aCBhc3ltcHRvdGljIGRpc3RyaWJ1dGlvbnM6IGFzIHlvdSB0YWtlIG1vcmUgYW5kIG1vcmUgc2FtcGxlcywgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiBhIGdpdmVuIHN0YXRpc3RpYyB3aWxsIGV2ZW50dWFsbCBjb252ZXJnZSB0byBhIG5vcm1hbCBkaXN0cmlidXRpb24uDQoNCiMgUHJvYmxlbSAyDQpGb3IgdGhpcyBwcm9ibGVtLCB3ZSBhcmUgaW50ZXJlc3RlZCBpbiBhbmFseXppbmcgc2FtcGxlIG1lYW5zIGFuZCB2YXJpYW5jZXMgdmlhIGJvb3RzdHJhcHBpbmcuIFRvIGRvIHRoaXMsIHdlIHdpbGwgdXNlIGEgZGF0YSBzZXQgdGhhdCBjb25zaXN0cyBvZiB0aGUgdm9sdW1lIG9mIGNvZmZlZSBzb2xkIGRhaWx5IGF0IHR3byBkaWZmZXJlbnQgY29mZmVlIHNob3BzOg0KYGBge3J9IA0KY29mZmVlIDwtIGMoMjg1MCwgMzIwMCwgMjkwMCwgMzEwMCwgMjk1MCwgNzgwMCwgODEwMCwgNzkwMCwgMzMwMCwgMzA1MCwgNDAwMCwgNDIwMCwgMzE1MCwgMzQwMCwgNzcwMCwgODIwMCwgMzI1MCwgNDQwMCwgMzEwMCwgNDIwMCwgNDUwMCwgNDgwMCwgNDMwMCwgODUwMCwgODIwMCwgODkwMCwgODcwMCwgMzI1MCwgMzAwMCwgNDYwMCwgNDEwMCwgODQwMCwgODgwMCwgMzM1MCwgNDcwMCwgMzEwMCwgODEwMCwgMzA1MCwgODMwMCwgNDEwMCwgMzEwMCwgODMwMCwgODkwMCwgODIwMCwgNDQwMCwgNDUwMCwgMzI1MCwgNDYwMCwgODQwMCwgMzMwMCwgNDIwMCwgNDUwMCwgNDgwMCwgNDMwMCwgODUwMCkNCmBgYA0KDQojIyBQYXJ0IEENCkkgYmVsaWV2ZSB0aGF0IHdlIGNhbiB1c2UgdGhlIGNlbnRyYWwgbGltaXQgdGhlb3JlbSB0byBkZXJpdmUgdGhlIGFzeW1wdG90aWMgZGlzdHJpYnV0aW9uIG9mIHRoZSBzYW1wbGUgbWVhbiBiZWNhdXNlIG91ciBzYW1wbGUgc2l6ZSBpcyBncmVhdGVyIHRoYW4gMzAgKG4gPSA1NSBpbiBvdXIgY2FzZSkuDQpgYGB7cn0NCmxlbmd0aChjb2ZmZWUpDQpgYGANCg0KIyMgUGFydCBCDQpGb3IgdGhpcyBwYXJ0LCB3ZSB3aWxsIGRvIHRoZSBib290c3RyYXAgc2FtcGxlcyBhbmQgY2FsY3VsYXRlIHRoZSBzYW1wbGUgbWVhbnMgZm9yIGVhY2guIFRoZXkgd2lsbCB0aGVuIGJlIHBsb3R0ZWQgdmlhIGEgaGlzdG9ncmFtLiBBZnRlcndhcmRzIHdlIHdpbGwgZ2VuZXJhdGUgYW5kIHBsb3QgYSBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0ZSBmb3IgdGhlIHNhbXBsZSBtZWFucy4NCg0KTGV0J3Mgc3RhcnQgYnkgZ2VuZXJhdGluZyBhbmQgcGxvdHRpbmcgdGhlIGJvb3RzdHJhcHBlZCBzYW1wbGluZyBkaXN0cmlidXRpb24gZm9yIHRoZSBtZWFuLiBGb3IgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiwgMTAwMCBzYW1wbGVzIHdpbGwgYmUgdXNlZC4gV2Ugd2lsbCBhbHNvIHBsb3QgYSBrZXJuZWwgZGVuc2l0eSBjdXJ2ZSBvbiB0aGUgcGxvdDoNCmBgYHtyfQ0Kb3JpZ2luYWwuc2FtcGxlID0gc2FtcGxlKGNvZmZlZSwgICAgIyBwb3B1bGF0aW9uIG9mIGFsbCBjb2ZmZWUgdm9sdW1lIHNhbGVzDQo1NSwgICAgICAgICAgICAgICAgICAgICAgIyBzYW1wbGUgc2l6ZSA9IDU1IA0KcmVwbGFjZSA9IEZBTFNFICAgICAgICAgICMgc2FtcGxlIHdpdGhvdXQgcmVwbGFjZW1lbnQNCiAgICAgICAgICAgICAgICAgKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KIyMjIEJvb3RzdHJhcCBzYW1wbGluZyBiZWdpbnMgDQpidC5zYW1wbGUubWVhbi52ZWMgPSBOVUxMICAgICAgIyBkZWZpbmUgYW4gZW1wdHkgdmVjdG9yIHRvIGhvbGQgc2FtcGxlIG1lYW5zIG9mIHJlcGVhdGVkIHNhbXBsZXMuDQpmb3IoaSBpbiAxOjEwMDApeyAgICAgICAgICAgICAgIyBzdGFydGluZyBmb3ItbG9vcCB0byB0YWtlIGJvb3RzdHJhcCBzYW1wbGVzIHdpdGggbiA9IDU1DQogIGl0aC5idC5zYW1wbGUgPSBzYW1wbGUoeCA9IG9yaWdpbmFsLnNhbXBsZSwgIyBPcmlnaW5hbCBzYW1wbGUgd2l0aCA1NSBEYWlseQ0KICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gNTUsICAgICAgICAgICAgICMgc2FtcGxlIHNpemUgPSA1NSBNVVNUIGJlIGVxdWFsIHRvIHRoZSBzYW1wbGUgc2l6ZSEhDQogICAgICAgICAgICAgICAgICAgIHJlcGxhY2UgPSBUUlVFICAgICAgICAgICAgIyBNVVNUIHVzZSBXSVRIIFJFUExBQ0VNRU5UISENCiAgICAgICAgICAgICAgICAgICAgICAgKSAgICAgICAgICAgICAgICAgICAgICAjIHRoaXMgaXMgdGhlIGktdGggQm9vdHN0cmFwIHNhbXBsZQ0KICBidC5zYW1wbGUubWVhbi52ZWNbaV0gPSBtZWFuKGl0aC5idC5zYW1wbGUpICMgY2FsY3VsYXRlIHRoZSBtZWFuIG9mIGktdGggYm9vdHN0cmFwIHNhbXBsZSBhbmQgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzYXZlIGl0IGluIHRoZSBlbXB0eSB2ZWN0b3I6IHNhbXBsZS5idC5tZWFuLnZlYyANCn0NCiMjIw0KDQpoaXN0KGJ0LnNhbXBsZS5tZWFuLnZlYywgICAgICAgICAgICAgICAgICAgICAjIGRhdGEgZnJvbSBzYW1wbGUNCiAgICAgYnJlYWtzID0gMTQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc3BlY2lmeSBudW1iZXIgb2YgdmVydGljYWwgYmFycw0KICAgICBwcm9iYWJpbGl0eSA9IFRSVUUsDQogICAgICAgeGxhYiA9ICJCb290c3RyYXBwZWQgU2FtcGxlIE1lYW5zIiwgICAgICAjIGNoYW5nZSB0aGUgbGFiZWwgb2YgeC1heGlzDQogICAgICAjIGFkZCBhIHRpdGxlIHRvIHRoZSBoaXN0b2dyYW0NCiAgICAgICAgbWFpbiA9ICJCb290c3RyYXAgU2FtcGxpbmcgRGlzdHJpYnV0aW9uIG9mIFNhbXBsZSBNZWFucyIsDQogICAgICAgICAgY2V4Lm1haW4gPSAwLjksIGNvbCA9ICJsaWdodGJsdWUiDQogICAgICAgKSAgIA0KDQpsaW5lcyhkZW5zaXR5KGJ0LnNhbXBsZS5tZWFuLnZlYywgbiA9IDEwMDApLCBjb2wgPSAicmVkIiwgbHdkID0gMikNCiMgb3ZlcmxheXMgdGhlIGtlcm5lbCBkZW5zaXR5IGVzdGltYXRlIGZvciB0aGUgc2FtcGxlIG1lYW4NCmBgYA0KDQpUaGUgaGlzdG9ncmFtIHNoYXBlIGxvb2tzIHByZXR0eSBub3JtYWwsIGFsdGhvdWdoIHNsaWdodGx5IHNrZXdlZC4gVGhlIGtlcm5lbCBkZW5zaXR5IChpbiByZWQpIGxvb2tzIHJvdWdoLCBidXQgZG9lcyByZXNlbWJsZSBhIG5vcm1hbCBjdXJ2ZS4NCkxldCdzIGNhbGwgdGhlIGtlcm5lbCBzZXBlcmF0ZWx5IGFuZCBjb21wYXJlOg0KYGBge3J9DQpkZW5zaXR5KGJ0LnNhbXBsZS5tZWFuLnZlYywgbiA9IDEwMDApDQptZWFuKGNvZmZlZSkNCmBgYA0KVGhlIGFjdHVhbCBzYW1wbGUgbWVhbiBpcyA1MjUwLiBFdmVuIHRob3VnaCB0aGUgZXN0aW1hdGUgZm9yIHRoZSBtZWFuIHdpbGwgY2hhbmdlIGV2ZXJ5IHRpbWUgeW91IHJ1biBhIHNhbXBsZSwgaXQgZG9lcyBzdGF5IHJlbGF0aXZlbHkgY2xvc2UgdG8gdGhlIG1lYW4gKHVzdWFsbHkgYmV0d2VlbiA1MjIwIGFuZCA1MjgwKS4gVGhpcyBzZWVtcyB0byBkbyBhIGdvb2Qgam9iIG9mIGVzdGltYXRpbmcgdGhlIHNhbXBsZSBtZWFuLg0KDQojIyBQYXJ0IEMNCkZvciB0aGlzIHBhcnQsIHdlIHdpbGwgcmVwZWF0IHdoYXQgd2UgZGlkIGluIHBhcnRzIEEgYW5kIEIgdG8gZXN0aW1hdGUgdGhlIHNhbXBsZSB2YXJpYW5jZS4NCg0KSSBzdGlsbCB0aGluayB0aGF0IHRoZSBjZW50cmFsIGxpbWl0IHRoZW9yZW0gY2FuIGFwcGx5IHRvIGVzdGltYXRlIHRoZSBzYW1wbGUgdmFyaWFuY2UuIE91ciBzYW1wbGUgc2l6ZSBpc24ndCBjaGFuZ2luZyAobiA9IDU1KSBhbmQgdGhlIGFtb3VudCBvZiBzYW1wbGVzIHdlIHdpbGwgdGFrZSB3b24ndCBjaGFuZ2UgZWl0aGVyIChzYW1wbGVzID0gMTAwMCkuDQoNCk5vdyBmb3IgdGhlIGJvb3RzdHJhcHBlZCBzYW1wbGVzIGFuZCB0aGUga2VybmVsIGRlbnNpdHkgZXN0aW1hdGU6DQpgYGB7cn0NCm9yaWdpbmFsLnNhbXBsZSA9IHNhbXBsZShjb2ZmZWUsICAgICMgcG9wdWxhdGlvbiBvZiBhbGwgZGFpbHkgY29mZmVlIHNhbGVzDQogICAgICAgICAgICAgICAgICAgICAgIDU1LCAgICAgICAgICAgICAgICAgICAgICAjIHNhbXBsZSBzaXplID0gNTUgdmFsdWVzIGluIHRoZSBzYW1wbGUNCiAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZSA9IEZBTFNFICAgICAgICAgICMgc2FtcGxlIHdpdGhvdXQgcmVwbGFjZW1lbnQNCiAgICAgICAgICAgICAgICAgKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KIyMjIEJvb3RzdHJhcCBzYW1wbGluZyBiZWdpbnMgDQpidC5zYW1wbGUudmFyLnZlYyA9IE5VTEwgICAgICAjIGRlZmluZSBhbiBlbXB0eSB2ZWN0b3IgdG8gaG9sZCBzYW1wbGUgbWVhbnMgb2YgcmVwZWF0ZWQgc2FtcGxlcy4NCmZvcihpIGluIDE6MTAwMCl7ICAgICAgICAgICAgICAjIHN0YXJ0aW5nIGZvci1sb29wIHRvIHRha2UgYm9vdHN0cmFwIHNhbXBsZXMgd2l0aCBuID0gNTUNCiAgaXRoLmJ0LnNhbXBsZSA9IHNhbXBsZSh4ID0gb3JpZ2luYWwuc2FtcGxlLCAjIE9yaWdpbmFsIHNhbXBsZSB3aXRoIDU1IFdDVSBzdHVkZW50cycgaGVpZ2h0cw0KICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gNTUsICAgICAgICAgICAgICMgc2FtcGxlIHNpemUgPSA1NSBNVVNUIGJlIGVxdWFsIHRvIHRoZSBzYW1wbGUgc2l6ZSEhDQogICAgICAgICAgICAgICAgICAgIHJlcGxhY2UgPSBUUlVFICAgICAgICAgICAgIyBNVVNUIHVzZSBXSVRIIFJFUExBQ0VNRU5UISENCiAgICAgICAgICAgICAgICAgICAgICAgKSAgICAgICAgICAgICAgICAgICAgICAjIHRoaXMgaXMgdGhlIGktdGggQm9vdHN0cmFwIHNhbXBsZQ0KICBidC5zYW1wbGUudmFyLnZlY1tpXSA9IHZhcihpdGguYnQuc2FtcGxlKSAjIGNhbGN1bGF0ZSB0aGUgdmFyaWFuY2Ugb2YgaS10aCBib290c3RyYXAgc2FtcGxlIGFuZCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNhdmUgaXQgaW4gdGhlIGVtcHR5IHZlY3Rvcjogc2FtcGxlLmJ0LnZhci52ZWMgDQp9DQojIyMNCmhpc3QoYnQuc2FtcGxlLnZhci52ZWMsICAgICAgICAgICAgICAgICAgICAgIyBkYXRhIHVzZWQgZm9yIGhpc3RvZ3JhbQ0KICAgICBicmVha3MgPSAxNCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzcGVjaWZ5IG51bWJlciBvZiB2ZXJ0aWNhbCBiYXJzDQogICAgIHByb2JhYmlsaXR5ID0gVFJVRSwNCiAgICAgICB4bGFiID0gIkJvb3RzdHJhcCBTYW1wbGUgVmFyaWFuY2UiLCAgICAgICMgY2hhbmdlIHRoZSBsYWJlbCBvZiB4LWF4aXMNCiAgICAgICMgYWRkIGEgdGl0bGUgdG8gdGhlIGhpc3RvZ3JhbQ0KICAgICAgICBtYWluPSJCb290c3RyYXAgU2FtcGxpbmcgRGlzdHJpYnV0aW9uIG9mIFNhbXBsZSBWYXJpYW5jZXMiLA0KICAgICAgICAgIGNleC5tYWluID0gMC45LA0KICAgICAgIGNvbC5tYWluID0gIm5hdnkiLCBjb2wgPSAibGlnaHRibHVlIikgICANCmxpbmVzKGRlbnNpdHkoYnQuc2FtcGxlLnZhci52ZWMpLCBjb2wgPSAicmVkIiwgbHdkID0gMikNCmBgYA0KQWx0aG91Z2ggaXQgcmVzZW1ibGVzIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgdGhlcmUgc2VlbXMgdG8gYmUgYSBsb3QgbW9yZSBza2V3IGNvbXBhcmVkIHRvIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgdGhlIG1lYW4uIEkgYmVsaWV2ZSBzb21lIG9mIHRoZSBwb3RlbnRpYWwgc2tldyBtYXkgYmUgY29taW5nIGZyb20ganVzdCBob3cgdGhlIGdyYXBoIGxvb2tzLiBJIGRvbid0IHRoaW5rIHRoZSBza2V3IGlzIGFzIGJhZCBhcyBpdCBsb29rcy4gDQoNCmBgYHtyfQ0KZGVuc2l0eShidC5zYW1wbGUudmFyLnZlYywgbiA9IDEwMDApDQp2YXIoY29mZmVlKQ0KDQpgYGANClRoZSBhY3R1YWwgc2FtcGxlIHZhcmlhbmNlIGlzIDUsMDMwLDgzMy4gVGhlIEtlcm5lbCBEZW5zaXR5IEVzdGltYXRlIHVzdWFsbHkgZmFsbHMgYmV0d2VlbiA0LDIwMCwwMDAgYW5kIDQsNDAwLDAwMC4gSW4gcmFyZSBjYXNlcywgaXQgbWF5IGV4Y2VlZCA0LDQwMCwwMDAuIEhvd2V2ZXIsIGlmIHdlIGtlZXAgcnVubmluZyB0aGUgY29kZSwgdGhlIHBlYWsgb2YgdGhlIGhpc3RvZ3JhbXMgZ2VuZXJhdGVkIHVzdWFsbHkgZmxvYXQgYXJvdW5kIHRoZSA1LDAwMCwwMDAgbWFyay4gU28gSSB0aGluayB3ZSBkaWQgYSBnb29kIGVub3VnaCBqb2IgZXN0aW1hdGluZyB0aGUgc2FtcGxlIHZhcmlhbmNlIGFzIHdlbGwu