Introductory Statistics (CRN: 6896)



Objective

Today we learn to work with correlations. So far, we’ve focused on accessing data in a dataset, describing variables, and calculating summary statistics (Mean, Median, SD, etc.). We’ve also learned to create crosstabs using the table command. These steps are critical to any data analysis project. But once we have grasp of the type of data we have and the distributions of different variables, we want to know how different variables relate to each other. Specifically, we want to ask questions and find their answers in the data.

The question of whether and how two or more variables are related could take multiple forms, but it’s all based on the same general idea: are changes in one variable related to changes in another variable? For continuous variables, the concept of change could be two or more going up and/or down at the same time. For mixed categorical-continuous variables, it could be whether a continuous variable has higher or lower means for different levels of a categorical variable. In either case we will follow a similar process: (1) find the amount of change (2) standardize it and convert it to a relevant test statistic (3) calculate the probability of finding a test statistic, given our sample size

Now there is a lot of variation on these three steps depending on the type of data or the goal of the analysis. But the basic premise is the same. And, in nearly all cases, we interpret the results of our analysis similarly: given certain assumptions, and assuming there is no relationship between our variables, what is the probability of finding a test statistics of a certain size (or more larger) in sample of a certain size.

Note: What we make of the relationship between variables depends on the nature of our data. Our interpretation depend on how the data was collected, it’s purpose, etc.

Today we’ll learn these concept and apply them to correlations. We’ll learn how to calculate correlations in R, what to make of the results, and how to report them.


Correlation - basics

By now we know two things that are important when describing a distribution of data: central tendency (where most numbers fall, for example the mean), and variability (how much do numbers vary around the measure of central tendency, for example, standard deviation). To calculate the variance, we use the process below:

  1. calculate sample mean
  2. calculate the difference between the mean and each score (deviation from the mean)
  3. square the deviations from the mean (squared differences)
  4. add up the squared differences and divide them by N-1 (N is your sample size)

Let’s look at an example:

sample.data<-c(1,2,2,4,4,5,4,9,6,4,3,1,6,8,3)
sample.data.mean<-mean(sample.data)
sample.data.deviation<-sample.data-sample.data.mean
sample.data.deviation.squared<-(sample.data.deviation)^2
sum(sample.data.deviation.squared)/(length(sample.data)-1)
[1] 5.552381

All of the above process can be summarized into one line:

var(sample.data)
[1] 5.552381

We also learned that taking the square root of variance (sqrt(variance)) gives us the standard deviation (sd()) which is in the same units as our data. Now we learn about a very similar concept: covariance. As the name implies, it’s something related to variance but there is the prefix co, which tells us that the it’s about joint variance. Instead of telling us to what extent a variable deviates from it’s mean, covariance tells us to what extent deviations of two variable from their means are related to each other. Let’s have a look at how it is calculated:

  1. calculate the mean for each variable
  2. calculate the difference between the mean and each score for each variable (deviation from the mean)
  3. multiply the deviations
  4. add up the multiplied deviations and divide them by N-1 (N is your sample size)

\[cov_{x,y} = \frac{\sum\limits_{i=1}^{n}{(x_i-\overline{x}) \cdot (y_i-\overline{y})} }{n-1}\]

As you can see, most of the steps are similar to calculating variance. Except, we instead of squaring deviations, we multiple the deviations for the two variable with one another. This is important: two variable should to have the same number of data points (same length) so we can calculate their covariance. If one variable is missing, then the deviation of the other variable cannot be multiplied by anything so it’ll have to be omitted. Let’s lookat an exmaple below:

x <- c(1,2,2,4,4,5,4,9,6,4,3,1,6,8,3)
y <- c(1,3,6,7,4,2,5,6,7,4,2,2,4,5,6)
x.mean <- mean(x)
y.mean <- mean(y)
x.deivation <- x - x.mean
y.deivation <- y - y.mean
sum(x.deivation * y.deivation) / (length(x)-1) # or it could be length(y). It doesn't make a difference because they have the same length
[1] 2.17619

This can be summarized into one line:

cov(x,y)
[1] 2.17619

But here’s a question: what does the number 2.17 mean? If you recall, the problem with variance was that it came in squared units and it was hard to interpret. With covariance, we have a similar problem. Although higher values mean the variables vary together more, it is hard to compare with the covariance between other variables. To comapre, we need common scale. Just as standard deviation gave us some common measure to compares things, we can standardize covariance to get a number that is more comparable across different sets of variables. How do we do this? We divide teh covariance by the standard deviations of the two variables:

\[ r = \frac{cov_{x,y}}{SD(X) SD(Y)}\] \(r\), or the Pearson correlation coefficient, is a standardized covariance. It has the following properties:

  1. is always between -1 and 1.
  2. it can be 1, which means the variables are fully correlated in the smae direction (they are essentially the same variable)
  3. it can be 0, which means there is no relationship between the x and y.
  4. it can be -1, which means the variables are fully correlated but in opposite directions (they are opposites)
  5. conventionally ±0.1 represent a small effect, ±0.3 is a medium effect and ±0.5 is a large effect (these depend on the topic of research)

When we standardize the covariance, we get:

cov(x,y)/(sd(x)*sd(y))
[1] 0.4749596

But the this can also be written as:

cor(x,y)
[1] 0.4749596

So the two variable x and y are correlated at 0.47. But what does this mean? Looking at the plot below might give us a sense:

plot(x,y)
abline(a = 1, cor(x,y)) # this command draws a line with the intercept a and slope of b. Here, the slope is the correlation coefficient. 
abline(a = 2, cor(x,y))
abline(a = 3, cor(x,y))

There seems to be a positive linear trend between x and y. They increase together (whne an x deviates from its mean, y also deviates from its mean). We know the slope of this line is the correlation line.

Pearson \(r\) is an estimate. So it has some error. Recall that for for sample means, we’d use \(SE = 1/\sqrt{n}\) to get a sense of how good our estimate is of the true population mean. For Pearson \(r\) too, we can calculate a standard error as seen below (n is the number of observations):

\[SE_r =\sqrt{\frac{1-r^2}{n-2}}\] Note: You do not need to memorize this. But it is important to see how different statistical methods follow a similar logic.

Recall that the mean and it’s standard error, allowed us to find the probability of a data point. Using z-scores, we would look on the normal distribution and find the percentiles. We could also calculate the 95% confidence intervals for the mean (95% CI [Mean - 1.96 * SE, Mean + 1.96 * SE]).

With \(r\) and it’s standard error read, we can do the same with Pearson’s r. The only difference is that we use a different distribution call t-distribution. This is pretty much like the normal distribution but it become flatter at lower number of data points. this is also not that important).So we calculate what is called a \(t-statistics\). The t statistics has its own distribution and probabilities so we can calculate the likelihood of finding a correlation of size r in a sample of size n. 

\[t=\frac{r}{SE_r} = \frac{r}{\sqrt{(1-r^2)/(N-2)}}\]

Doing this in r, we use the cor.test command:

cor.test(x,y)

    Pearson's product-moment correlation

data:  x and y
t = 1.946, df = 13, p-value = 0.0736
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.04929754  0.79403133
sample estimates:
      cor 
0.4749596 

As you can see, the correlation is the same as before. However, we get a other data which we can use in our reporting: \(r\) = 0.4749596, 95%CI[-0.04929754,0.79403133], \(t\)(13) = 1.946, P < 0.0736. Assuming x and y are unrelated, the likelihood of finding a t-value of 1.946 or larger in a sample of 13 people is 0.0736 or lower.

Let’s load a new dataset and look at some correlations. Load the data set telecom_churn.csv and answer the following questions:

Each row represents a customer and each column contains attributes related to customer as described in the column description. The variables are:

  • Churn: if customer canceled service, 0 if not
  • AccountWeeks: number of weeks customer has had active account
  • ContractRenewal: if customer recently renewed contract, 0 if not
  • Data: Plan1 if customer has data plan, 0 if not
  • Data Usage: gigabytes of monthly data usage
  • CustServCalls: number of calls into customer service
  • DayMins: average daytime minutes per month
  • DayCalls: average number of daytime calls
  • MonthlyCharge: average monthly bill
  • OverageFee: largest overage fee in last 12 months
  • RoamMins: average number of roaming minutes

Questions:

  1. Do people who speak more on the phone pay more per month? how strong is the relationship?
  2. What about people with dataplans? do they pay more? How so?
  3. Does overage fee increase monthly charge?
  4. What is the relationship between having a data plan and data usage?
  5. What is the relationship between customer service calls and customer churn?
  6. Do people who use talk more on their phone churn more or less?
LS0tCnRpdGxlOiAiTGFiIDYiCm91dHB1dDogaHRtbF9ub3RlYm9vawpBdXRob3I6IE1vc3RhZmEgU2FsYXJpIFJhZAoKLS0tCgoKIyMjIEludHJvZHVjdG9yeSBTdGF0aXN0aWNzIChDUk46IDY4OTYpCgpcClwKCiMjIyMgT2JqZWN0aXZlCgpUb2RheSB3ZSBsZWFybiB0byB3b3JrIHdpdGggY29ycmVsYXRpb25zLiBTbyBmYXIsIHdlJ3ZlIGZvY3VzZWQgb24gYWNjZXNzaW5nIGRhdGEgaW4gYSBkYXRhc2V0LCBkZXNjcmliaW5nIHZhcmlhYmxlcywgYW5kIGNhbGN1bGF0aW5nIHN1bW1hcnkgc3RhdGlzdGljcyAoTWVhbiwgTWVkaWFuLCBTRCwgZXRjLikuIFdlJ3ZlIGFsc28gbGVhcm5lZCB0byBjcmVhdGUgY3Jvc3N0YWJzIHVzaW5nIHRoZSBgdGFibGVgIGNvbW1hbmQuIFRoZXNlIHN0ZXBzIGFyZSBjcml0aWNhbCB0byBhbnkgZGF0YSBhbmFseXNpcyBwcm9qZWN0LiBCdXQgb25jZSB3ZSBoYXZlIGdyYXNwIG9mIHRoZSB0eXBlIG9mIGRhdGEgd2UgaGF2ZSBhbmQgdGhlIGRpc3RyaWJ1dGlvbnMgb2YgZGlmZmVyZW50IHZhcmlhYmxlcywgd2Ugd2FudCB0byBrbm93IGhvdyBkaWZmZXJlbnQgdmFyaWFibGVzIHJlbGF0ZSB0byBlYWNoIG90aGVyLiBTcGVjaWZpY2FsbHksIHdlIHdhbnQgdG8gYXNrIHF1ZXN0aW9ucyBhbmQgZmluZCB0aGVpciBhbnN3ZXJzIGluIHRoZSBkYXRhLgoKVGhlIHF1ZXN0aW9uIG9mIHdoZXRoZXIgYW5kIGhvdyAqdHdvIG9yIG1vcmUgdmFyaWFibGVzIGFyZSByZWxhdGVkKiBjb3VsZCB0YWtlIG11bHRpcGxlIGZvcm1zLCBidXQgaXQncyBhbGwgYmFzZWQgb24gdGhlIHNhbWUgZ2VuZXJhbCBpZGVhOiBhcmUgY2hhbmdlcyBpbiBvbmUgdmFyaWFibGUgcmVsYXRlZCB0byBjaGFuZ2VzIGluIGFub3RoZXIgdmFyaWFibGU/IEZvciBjb250aW51b3VzIHZhcmlhYmxlcywgdGhlIGNvbmNlcHQgb2YgKmNoYW5nZSogY291bGQgYmUgdHdvIG9yIG1vcmUgZ29pbmcgdXAgYW5kL29yIGRvd24gYXQgdGhlIHNhbWUgdGltZS4gRm9yIG1peGVkIGNhdGVnb3JpY2FsLWNvbnRpbnVvdXMgdmFyaWFibGVzLCBpdCBjb3VsZCBiZSB3aGV0aGVyIGEgY29udGludW91cyB2YXJpYWJsZSBoYXMgaGlnaGVyIG9yIGxvd2VyIG1lYW5zIGZvciBkaWZmZXJlbnQgbGV2ZWxzIG9mIGEgY2F0ZWdvcmljYWwgdmFyaWFibGUuIEluIGVpdGhlciBjYXNlIHdlIHdpbGwgZm9sbG93IGEgc2ltaWxhciBwcm9jZXNzOiAKICgxKSBmaW5kIHRoZSBhbW91bnQgb2YgY2hhbmdlIAogKDIpIHN0YW5kYXJkaXplIGl0IGFuZCBjb252ZXJ0IGl0IHRvIGEgcmVsZXZhbnQgdGVzdCBzdGF0aXN0aWMgCiAoMykgY2FsY3VsYXRlIHRoZSBwcm9iYWJpbGl0eSBvZiBmaW5kaW5nIGEgdGVzdCBzdGF0aXN0aWMsIGdpdmVuIG91ciBzYW1wbGUgc2l6ZSAKCgpOb3cgdGhlcmUgaXMgYSBsb3Qgb2YgdmFyaWF0aW9uIG9uIHRoZXNlIHRocmVlIHN0ZXBzIGRlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiBkYXRhIG9yIHRoZSBnb2FsIG9mIHRoZSBhbmFseXNpcy4gQnV0IHRoZSBiYXNpYyBwcmVtaXNlIGlzIHRoZSBzYW1lLiBBbmQsIGluIG5lYXJseSBhbGwgY2FzZXMsIHdlIGludGVycHJldCB0aGUgcmVzdWx0cyBvZiBvdXIgYW5hbHlzaXMgc2ltaWxhcmx5OiBnaXZlbiBjZXJ0YWluIGFzc3VtcHRpb25zLCBhbmQgYXNzdW1pbmcgdGhlcmUgaXMgbm8gcmVsYXRpb25zaGlwIGJldHdlZW4gb3VyIHZhcmlhYmxlcywgd2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgb2YgZmluZGluZyBhIHRlc3Qgc3RhdGlzdGljcyBvZiBhIGNlcnRhaW4gc2l6ZSAob3IgbW9yZSBsYXJnZXIpIGluIHNhbXBsZSBvZiBhIGNlcnRhaW4gc2l6ZS4KCioqTm90ZSoqOiBXaGF0IHdlIG1ha2Ugb2YgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHZhcmlhYmxlcyBkZXBlbmRzIG9uIHRoZSBuYXR1cmUgb2Ygb3VyIGRhdGEuIE91ciBpbnRlcnByZXRhdGlvbiBkZXBlbmQgb24gaG93IHRoZSBkYXRhIHdhcyBjb2xsZWN0ZWQsIGl0J3MgcHVycG9zZSwgZXRjLgoKVG9kYXkgd2UnbGwgbGVhcm4gdGhlc2UgY29uY2VwdCBhbmQgYXBwbHkgdGhlbSB0byBjb3JyZWxhdGlvbnMuIFdlJ2xsIGxlYXJuIGhvdyB0byBjYWxjdWxhdGUgY29ycmVsYXRpb25zIGluIFIsIHdoYXQgdG8gbWFrZSBvZiB0aGUgcmVzdWx0cywgYW5kIGhvdyB0byByZXBvcnQgdGhlbS4gCgpcCgoKKipDb3JyZWxhdGlvbiAtIGJhc2ljcyoqCgpCeSBub3cgd2Uga25vdyB0d28gdGhpbmdzIHRoYXQgYXJlIGltcG9ydGFudCB3aGVuIGRlc2NyaWJpbmcgYSBkaXN0cmlidXRpb24gb2YgZGF0YTogY2VudHJhbCB0ZW5kZW5jeSAod2hlcmUgbW9zdCBudW1iZXJzIGZhbGwsIGZvciBleGFtcGxlIHRoZSBtZWFuKSwgYW5kIHZhcmlhYmlsaXR5IChob3cgbXVjaCBkbyBudW1iZXJzIHZhcnkgYXJvdW5kIHRoZSBtZWFzdXJlIG9mIGNlbnRyYWwgdGVuZGVuY3ksIGZvciBleGFtcGxlLCBzdGFuZGFyZCBkZXZpYXRpb24pLiBUbyBjYWxjdWxhdGUgdGhlIHZhcmlhbmNlLCB3ZSB1c2UgdGhlIHByb2Nlc3MgYmVsb3c6CgogICgxKSBjYWxjdWxhdGUgc2FtcGxlICoqbWVhbioqCiAgKDIpIGNhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBtZWFuIGFuZCBlYWNoIHNjb3JlICgqKmRldmlhdGlvbiBmcm9tIHRoZSBtZWFuKiopCiAgKDMpIHNxdWFyZSB0aGUgZGV2aWF0aW9ucyBmcm9tIHRoZSBtZWFuICgqKnNxdWFyZWQgZGlmZmVyZW5jZXMqKikKICAoNCkgYWRkIHVwIHRoZSBzcXVhcmVkIGRpZmZlcmVuY2VzIGFuZCBkaXZpZGUgdGhlbSBieSAqTi0xKiAoTiBpcyB5b3VyIHNhbXBsZSBzaXplKQogIApMZXQncyBsb29rIGF0IGFuIGV4YW1wbGU6CgpgYGB7cn0Kc2FtcGxlLmRhdGEgPC0gYygxLDIsMiw0LDQsNSw0LDksNiw0LDMsMSw2LDgsMykKc2FtcGxlLmRhdGEubWVhbiA8LSBtZWFuKHNhbXBsZS5kYXRhKQpzYW1wbGUuZGF0YS5kZXZpYXRpb248LXNhbXBsZS5kYXRhIC0gc2FtcGxlLmRhdGEubWVhbgpzYW1wbGUuZGF0YS5kZXZpYXRpb24uc3F1YXJlZCA8LSAoc2FtcGxlLmRhdGEuZGV2aWF0aW9uKV4yCnN1bShzYW1wbGUuZGF0YS5kZXZpYXRpb24uc3F1YXJlZCkgLyAobGVuZ3RoKHNhbXBsZS5kYXRhKS0xKSAjIGxlbmd0aCBpcyB0aGUgZnVuY3Rpb24gdGhlIHRlbGxzIHVzIGhvdyBtYW55IGRhdGEgcG9pbnRzIGFyZSBpbiB0aGUgdmFyaWFibGUKYGBgCgpBbGwgb2YgdGhlIGFib3ZlIHByb2Nlc3MgY2FuIGJlIHN1bW1hcml6ZWQgaW50byBvbmUgbGluZToKCmBgYHtyfQp2YXIoc2FtcGxlLmRhdGEpCmBgYAoKV2UgYWxzbyBsZWFybmVkIHRoYXQgdGFraW5nIHRoZSBzcXVhcmUgcm9vdCBvZiB2YXJpYW5jZSAoYHNxcnQodmFyaWFuY2UpYCkgZ2l2ZXMgdXMgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiAoYHNkKClgKSB3aGljaCBpcyBpbiB0aGUgc2FtZSB1bml0cyBhcyBvdXIgZGF0YS4gTm93IHdlIGxlYXJuIGFib3V0IGEgdmVyeSBzaW1pbGFyIGNvbmNlcHQ6ICoqY292YXJpYW5jZSoqLiBBcyB0aGUgbmFtZSBpbXBsaWVzLCBpdCdzIHNvbWV0aGluZyByZWxhdGVkIHRvIHZhcmlhbmNlIGJ1dCB0aGVyZSBpcyB0aGUgcHJlZml4ICpjbyosIHdoaWNoIHRlbGxzIHVzIHRoYXQgdGhlIGl0J3MgYWJvdXQgam9pbnQgdmFyaWFuY2UuIEluc3RlYWQgb2YgdGVsbGluZyB1cyB0byB3aGF0IGV4dGVudCBhIHZhcmlhYmxlIGRldmlhdGVzIGZyb20gaXQncyBtZWFuLCBjb3ZhcmlhbmNlIHRlbGxzIHVzIHRvIHdoYXQgZXh0ZW50IGRldmlhdGlvbnMgb2YgdHdvIHZhcmlhYmxlIGZyb20gdGhlaXIgbWVhbnMgYXJlIHJlbGF0ZWQgdG8gZWFjaCBvdGhlci4gTGV0J3MgaGF2ZSBhIGxvb2sgYXQgaG93IGl0IGlzIGNhbGN1bGF0ZWQ6CgogICgxKSBjYWxjdWxhdGUgdGhlICoqbWVhbioqIGZvciBlYWNoIHZhcmlhYmxlCiAgKDIpIGNhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBtZWFuIGFuZCBlYWNoIHNjb3JlIGZvciBlYWNoIHZhcmlhYmxlICgqKmRldmlhdGlvbiBmcm9tIHRoZSBtZWFuKiopCiAgKDMpIG11bHRpcGx5IHRoZSBkZXZpYXRpb25zCiAgKDQpIGFkZCB1cCB0aGUgbXVsdGlwbGllZCBkZXZpYXRpb25zIGFuZCBkaXZpZGUgdGhlbSBieSAqTi0xKiAoTiBpcyB5b3VyIHNhbXBsZSBzaXplKQogIAogIAogICQkY292X3t4LHl9ID0gXGZyYWN7XHN1bVxsaW1pdHNfe2k9MX1ee259eyh4X2ktXG92ZXJsaW5le3h9KSBcY2RvdCAoeV9pLVxvdmVybGluZXt5fSl9IH17bi0xfSQkCgpBcyB5b3UgY2FuIHNlZSwgbW9zdCBvZiB0aGUgc3RlcHMgYXJlIHNpbWlsYXIgdG8gY2FsY3VsYXRpbmcgdmFyaWFuY2UuIEV4Y2VwdCwgd2UgaW5zdGVhZCBvZiBzcXVhcmluZyBkZXZpYXRpb25zLCB3ZSBtdWx0aXBsZSB0aGUgZGV2aWF0aW9ucyBmb3IgdGhlIHR3byB2YXJpYWJsZSB3aXRoIG9uZSBhbm90aGVyLiAqKlRoaXMgaXMgaW1wb3J0YW50OioqIHR3byB2YXJpYWJsZSBzaG91bGQgdG8gaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgZGF0YSBwb2ludHMgKHNhbWUgbGVuZ3RoKSBzbyB3ZSBjYW4gY2FsY3VsYXRlIHRoZWlyIGNvdmFyaWFuY2UuIElmIG9uZSB2YXJpYWJsZSBpcyBtaXNzaW5nLCB0aGVuIHRoZSBkZXZpYXRpb24gb2YgdGhlIG90aGVyIHZhcmlhYmxlIGNhbm5vdCBiZSBtdWx0aXBsaWVkIGJ5IGFueXRoaW5nIHNvIGl0J2xsIGhhdmUgdG8gYmUgb21pdHRlZC4gTGV0J3MgbG9va2F0IGFuIGV4bWFwbGUgYmVsb3c6CgpgYGB7cn0KeCA8LSBjKDEsMiwyLDQsNCw1LDQsOSw2LDQsMywxLDYsOCwzKQp5IDwtIGMoMSwzLDYsNyw0LDIsNSw2LDcsNCwyLDIsNCw1LDYpCngubWVhbiA8LSBtZWFuKHgpCnkubWVhbiA8LSBtZWFuKHkpCnguZGVpdmF0aW9uIDwtIHggLSB4Lm1lYW4KeS5kZWl2YXRpb24gPC0geSAtIHkubWVhbgpzdW0oeC5kZWl2YXRpb24gKiB5LmRlaXZhdGlvbikgLyAobGVuZ3RoKHgpLTEpICMgb3IgaXQgY291bGQgYmUgbGVuZ3RoKHkpLiBJdCBkb2Vzbid0IG1ha2UgYSBkaWZmZXJlbmNlIGJlY2F1c2UgdGhleSBoYXZlIHRoZSBzYW1lIGxlbmd0aApgYGAKClRoaXMgY2FuIGJlIHN1bW1hcml6ZWQgaW50byBvbmUgbGluZTogCgpgYGB7cn0KY292KHgseSkKYGBgCgpCdXQgaGVyZSdzIGEgcXVlc3Rpb246IHdoYXQgZG9lcyB0aGUgbnVtYmVyIDIuMTcgbWVhbj8gSWYgeW91IHJlY2FsbCwgdGhlIHByb2JsZW0gd2l0aCB2YXJpYW5jZSB3YXMgdGhhdCBpdCBjYW1lIGluIHNxdWFyZWQgdW5pdHMgYW5kIGl0IHdhcyBoYXJkIHRvIGludGVycHJldC4gV2l0aCBjb3ZhcmlhbmNlLCB3ZSBoYXZlIGEgc2ltaWxhciBwcm9ibGVtLiBBbHRob3VnaCBoaWdoZXIgdmFsdWVzIG1lYW4gdGhlIHZhcmlhYmxlcyB2YXJ5IHRvZ2V0aGVyIG1vcmUsIGl0IGlzIGhhcmQgdG8gY29tcGFyZSB3aXRoIHRoZSBjb3ZhcmlhbmNlIGJldHdlZW4gb3RoZXIgdmFyaWFibGVzLiBUbyBjb21hcHJlLCB3ZSBuZWVkIGNvbW1vbiBzY2FsZS4gSnVzdCBhcyBzdGFuZGFyZCBkZXZpYXRpb24gZ2F2ZSB1cyBzb21lIGNvbW1vbiBtZWFzdXJlIHRvIGNvbXBhcmVzIHRoaW5ncywgd2UgY2FuIHN0YW5kYXJkaXplIGNvdmFyaWFuY2UgdG8gZ2V0IGEgbnVtYmVyIHRoYXQgaXMgbW9yZSBjb21wYXJhYmxlIGFjcm9zcyBkaWZmZXJlbnQgc2V0cyBvZiB2YXJpYWJsZXMuIEhvdyBkbyB3ZSBkbyB0aGlzPyBXZSBkaXZpZGUgdGVoIGNvdmFyaWFuY2UgYnkgdGhlIHN0YW5kYXJkIGRldmlhdGlvbnMgb2YgdGhlIHR3byB2YXJpYWJsZXM6CgoKJCQgciA9IFxmcmFje2Nvdl97eCx5fX17U0QoWCkgU0QoWSl9JCQKJHIkLCBvciB0aGUgUGVhcnNvbiBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCwgaXMgYSBzdGFuZGFyZGl6ZWQgY292YXJpYW5jZS4gSXQgaGFzIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczoKCiAgKDEpIGlzIGFsd2F5cyBiZXR3ZWVuIC0xIGFuZCAxLgogICgyKSBpdCBjYW4gYmUgMSwgd2hpY2ggbWVhbnMgdGhlIHZhcmlhYmxlcyBhcmUgZnVsbHkgY29ycmVsYXRlZCBpbiB0aGUgc21hZSBkaXJlY3Rpb24gKHRoZXkgYXJlIGVzc2VudGlhbGx5IHRoZSBzYW1lIHZhcmlhYmxlKQogICgzKSBpdCBjYW4gYmUgMCwgd2hpY2ggbWVhbnMgdGhlcmUgaXMgbm8gcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHggYW5kIHkuCiAgKDMpIGl0IGNhbiBiZSAtMSwgd2hpY2ggbWVhbnMgdGhlIHZhcmlhYmxlcyBhcmUgZnVsbHkgY29ycmVsYXRlZCBidXQgaW4gb3Bwb3NpdGUgZGlyZWN0aW9ucyAodGhleSBhcmUgb3Bwb3NpdGVzKQogICg0KSBjb252ZW50aW9uYWxseSDCsTAuMSByZXByZXNlbnQgYSBzbWFsbCBlZmZlY3QsIMKxMC4zIGlzIGEgbWVkaXVtIGVmZmVjdCBhbmQgwrEwLjUgaXMgYSBsYXJnZSBlZmZlY3QgKHRoZXNlIGRlcGVuZCBvbiB0aGUgdG9waWMgb2YgcmVzZWFyY2gpCiAgCldoZW4gd2Ugc3RhbmRhcmRpemUgdGhlIGNvdmFyaWFuY2UsIHdlIGdldDoKCmBgYHtyfQpjb3YoeCx5KS8oc2QoeCkqc2QoeSkpCmBgYAoKQnV0IHRoZSB0aGlzIGNhbiBhbHNvIGJlIHdyaXR0ZW4gYXM6CgpgYGB7cn0KY29yKHgseSkKYGBgCgpTbyB0aGUgdHdvIHZhcmlhYmxlIHggYW5kIHkgYXJlIGNvcnJlbGF0ZWQgYXQgMC40Ny4gQnV0IHdoYXQgZG9lcyB0aGlzIG1lYW4/IExvb2tpbmcgYXQgdGhlIHBsb3QgYmVsb3cgbWlnaHQgZ2l2ZSB1cyBhIHNlbnNlOgoKYGBge3J9CnBsb3QoeCx5KQphYmxpbmUoYSA9IDEsIGNvcih4LHkpKSAjIHRoaXMgY29tbWFuZCBkcmF3cyBhIGxpbmUgd2l0aCB0aGUgaW50ZXJjZXB0IGEgYW5kIHNsb3BlIG9mIGIuIEhlcmUsIHRoZSBzbG9wZSBpcyB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQuIAphYmxpbmUoYSA9IDIsIGNvcih4LHkpKQphYmxpbmUoYSA9IDMsIGNvcih4LHkpKQpgYGAKClRoZXJlIHNlZW1zIHRvIGJlIGEgcG9zaXRpdmUgbGluZWFyIHRyZW5kIGJldHdlZW4geCBhbmQgeS4gVGhleSBpbmNyZWFzZSB0b2dldGhlciAod2huZSBhbiB4IGRldmlhdGVzIGZyb20gaXRzIG1lYW4sIHkgYWxzbyBkZXZpYXRlcyBmcm9tIGl0cyBtZWFuKS4gV2Uga25vdyB0aGUgc2xvcGUgb2YgdGhpcyBsaW5lIGlzIHRoZSBjb3JyZWxhdGlvbiBsaW5lLiAKCgpQZWFyc29uICRyJCBpcyBhbiBlc3RpbWF0ZS4gU28gaXQgaGFzIHNvbWUgZXJyb3IuIFJlY2FsbCB0aGF0IGZvciBmb3Igc2FtcGxlIG1lYW5zLCB3ZSdkIHVzZSAkU0UgPSAxL1xzcXJ0e259JCB0byBnZXQgYSBzZW5zZSBvZiBob3cgZ29vZCBvdXIgZXN0aW1hdGUgaXMgb2YgdGhlIHRydWUgcG9wdWxhdGlvbiBtZWFuLiBGb3IgUGVhcnNvbiAkciQgdG9vLCB3ZSBjYW4gY2FsY3VsYXRlIGEgc3RhbmRhcmQgZXJyb3IgYXMgc2VlbiBiZWxvdyAobiBpcyB0aGUgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyk6CgokJFNFX3IgPVxzcXJ0e1xmcmFjezEtcl4yfXtuLTJ9fSQkCioqTm90ZSoqOiBZb3UgZG8gbm90IG5lZWQgdG8gbWVtb3JpemUgdGhpcy4gQnV0IGl0IGlzIGltcG9ydGFudCB0byBzZWUgaG93IGRpZmZlcmVudCBzdGF0aXN0aWNhbCBtZXRob2RzIGZvbGxvdyBhIHNpbWlsYXIgbG9naWMuIAoKClJlY2FsbCB0aGF0IHRoZSBtZWFuIGFuZCBpdCdzIHN0YW5kYXJkIGVycm9yLCBhbGxvd2VkIHVzIHRvIGZpbmQgdGhlIHByb2JhYmlsaXR5IG9mIGEgZGF0YSBwb2ludC4gVXNpbmcgei1zY29yZXMsIHdlIHdvdWxkIGxvb2sgb24gdGhlIG5vcm1hbCBkaXN0cmlidXRpb24gYW5kIGZpbmQgdGhlIHBlcmNlbnRpbGVzLiBXZSBjb3VsZCBhbHNvIGNhbGN1bGF0ZSB0aGUgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGZvciB0aGUgbWVhbiAoOTUlIENJIFtNZWFuIC0gMS45NiAqIFNFLCBNZWFuICsgMS45NiAqIFNFXSkuIAoKV2l0aCAkciQgYW5kIGl0J3Mgc3RhbmRhcmQgZXJyb3IgcmVhZCwgd2UgY2FuIGRvIHRoZSBzYW1lIHdpdGggUGVhcnNvbidzIHIuIFRoZSBvbmx5IGRpZmZlcmVuY2UgaXMgdGhhdCB3ZSB1c2UgYSBkaWZmZXJlbnQgZGlzdHJpYnV0aW9uIGNhbGwgdC1kaXN0cmlidXRpb24uIFRoaXMgaXMgcHJldHR5IG11Y2ggbGlrZSB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBidXQgaXQgYmVjb21lIGZsYXR0ZXIgYXQgbG93ZXIgbnVtYmVyIG9mIGRhdGEgcG9pbnRzLiB0aGlzIGlzIGFsc28gbm90IHRoYXQgaW1wb3J0YW50KS5TbyB3ZSBjYWxjdWxhdGUgd2hhdCBpcyBjYWxsZWQgYSAkdC1zdGF0aXN0aWNzJC4gVGhlIHQgc3RhdGlzdGljcyBoYXMgaXRzIG93biBkaXN0cmlidXRpb24gYW5kIHByb2JhYmlsaXRpZXMgc28gd2UgY2FuIGNhbGN1bGF0ZSB0aGUgbGlrZWxpaG9vZCBvZiBmaW5kaW5nICBhIGNvcnJlbGF0aW9uIG9mIHNpemUgciBpbiBhIHNhbXBsZSBvZiBzaXplIG4uIAoKJCR0PVxmcmFje3J9e1NFX3J9ID0gXGZyYWN7cn17XHNxcnR7KDEtcl4yKS8oTi0yKX19JCQKCgpEb2luZyB0aGlzIGluIHIsIHdlIHVzZSB0aGUgYGNvci50ZXN0YCBjb21tYW5kOgoKYGBge3J9CmNvci50ZXN0KHgseSkKYGBgCgoKQXMgeW91IGNhbiBzZWUsIHRoZSBjb3JyZWxhdGlvbiBpcyB0aGUgc2FtZSBhcyBiZWZvcmUuIEhvd2V2ZXIsIHdlIGdldCBhIG90aGVyIGRhdGEgd2hpY2ggd2UgY2FuIHVzZSBpbiBvdXIgcmVwb3J0aW5nOiAkciQgPSAwLjQ3NDk1OTYsIDk1JUNJWy0wLjA0OTI5NzU0LDAuNzk0MDMxMzNdLCAkdCQoMTMpID0gMS45NDYsICpQKiA8IDAuMDczNi4gQXNzdW1pbmcgeCBhbmQgeSBhcmUgdW5yZWxhdGVkLCB0aGUgbGlrZWxpaG9vZCBvZiBmaW5kaW5nIGEgdC12YWx1ZSBvZiAxLjk0NiBvciBsYXJnZXIgaW4gYSBzYW1wbGUgb2YgMTMgcGVvcGxlIGlzIDAuMDczNiBvciBsb3dlci4KCgpMZXQncyBsb2FkIGEgbmV3IGRhdGFzZXQgYW5kIGxvb2sgYXQgc29tZSBjb3JyZWxhdGlvbnMuIExvYWQgdGhlIGRhdGEgc2V0IGB0ZWxlY29tX2NodXJuLmNzdmAgYW5kIGFuc3dlciB0aGUgZm9sbG93aW5nIHF1ZXN0aW9uczoKCgpgYGB7cn0KY2h1cm48LXJlYWQuY3N2KCJ0ZWxlY29tX2NodXJuLmNzdiIpCmhlYWQoY2h1cm4pCmBgYAoKRWFjaCByb3cgcmVwcmVzZW50cyBhIGN1c3RvbWVyIGFuZCBlYWNoIGNvbHVtbiBjb250YWlucyBhdHRyaWJ1dGVzIHJlbGF0ZWQgdG8gY3VzdG9tZXIgYXMgZGVzY3JpYmVkIGluIHRoZSBjb2x1bW4gZGVzY3JpcHRpb24uIFRoZSB2YXJpYWJsZXMgYXJlOgoKKiBDaHVybjogaWYgY3VzdG9tZXIgY2FuY2VsZWQgc2VydmljZSwgMCBpZiBub3QKKiBBY2NvdW50V2Vla3M6IG51bWJlciBvZiB3ZWVrcyBjdXN0b21lciBoYXMgaGFkIGFjdGl2ZSBhY2NvdW50CiogQ29udHJhY3RSZW5ld2FsOiAgaWYgY3VzdG9tZXIgcmVjZW50bHkgcmVuZXdlZCBjb250cmFjdCwgMCBpZiBub3QKKiBEYXRhOiBQbGFuMSBpZiBjdXN0b21lciBoYXMgZGF0YSBwbGFuLCAwIGlmIG5vdAoqIERhdGEgVXNhZ2U6IGdpZ2FieXRlcyBvZiBtb250aGx5IGRhdGEgdXNhZ2UKKiBDdXN0U2VydkNhbGxzOiBudW1iZXIgb2YgY2FsbHMgaW50byBjdXN0b21lciBzZXJ2aWNlCiogRGF5TWluczogYXZlcmFnZSBkYXl0aW1lIG1pbnV0ZXMgcGVyIG1vbnRoCiogRGF5Q2FsbHM6IGF2ZXJhZ2UgbnVtYmVyIG9mIGRheXRpbWUgY2FsbHMKKiBNb250aGx5Q2hhcmdlOiBhdmVyYWdlIG1vbnRobHkgYmlsbAoqIE92ZXJhZ2VGZWU6IGxhcmdlc3Qgb3ZlcmFnZSBmZWUgaW4gbGFzdCAxMiBtb250aHMKKiBSb2FtTWluczogYXZlcmFnZSBudW1iZXIgb2Ygcm9hbWluZyBtaW51dGVzCgoKKipRdWVzdGlvbnM6KioKCiAxLiBEbyBwZW9wbGUgd2hvIHNwZWFrIG1vcmUgb24gdGhlIHBob25lIHBheSBtb3JlIHBlciBtb250aD8gaG93IHN0cm9uZyBpcyB0aGUgcmVsYXRpb25zaGlwPwogMi4gV2hhdCBhYm91dCBwZW9wbGUgd2l0aCBkYXRhcGxhbnM/IGRvIHRoZXkgcGF5IG1vcmU/IEhvdyBzbz8KIDMuIERvZXMgb3ZlcmFnZSBmZWUgaW5jcmVhc2UgbW9udGhseSBjaGFyZ2U/CiA0LiBXaGF0IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBoYXZpbmcgYSBkYXRhIHBsYW4gYW5kIGRhdGEgdXNhZ2U/IAogNS4gV2hhdCBpcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gY3VzdG9tZXIgc2VydmljZSBjYWxscyBhbmQgY3VzdG9tZXIgY2h1cm4/CiA2LiBEbyBwZW9wbGUgd2hvIHVzZSB0YWxrIG1vcmUgb24gdGhlaXIgcGhvbmUgY2h1cm4gbW9yZSBvciBsZXNzPwoKCgoKCgoKCgoK