Start Using the neg.cor() Function

From the negligible R package


Introduction

What is the purpose/goal of neg.cor()?

The function neg.cor can help us determine whether two variables have a negligible association with one another. To see how it’s used, let’s first load the negligible package (if you don’t have it installed, you will have to install it first). Let’s load the psych package too, for some descriptives.

library(negligible)
library(psych)

What is the theory behind neg.cor()?

The function will compare the confidence interval around a correlation to something called an equivalence interval. If the confidence interval around the correlation is completely contained within the equivalence interval. we have evidence to say that the correlation between the variables is so small that we can call it unimportant, meaningless, etc.

We are going to be using the dataset mtcars that is already pre-loaded in R. We can investigate whether the weight of a car (in 1000lbs) and its 1/4 mile time are negligibly correlated with one another. Let’s take some descriptives (make sure nothing looks odd, the variables are continuous, etc.) and plot their correlation.

describe(mtcars$wt)
   vars  n mean   sd median trimmed  mad  min  max range skew kurtosis   se
X1    1 32 3.22 0.98   3.33    3.15 0.77 1.51 5.42  3.91 0.42    -0.02 0.17
describe(mtcars$qsec)
   vars  n  mean   sd median trimmed  mad  min  max range skew kurtosis   se
X1    1 32 17.85 1.79  17.71   17.83 1.42 14.5 22.9   8.4 0.37     0.34 0.32
plot(mtcars$wt, mtcars$qsec)

Null and Alternate Hypotheses of the Procedure

\(H_{01}: eiL \ge \rho\) | \(H_{02}: eiU \le \rho\)

\(H_{11}: eiL < \rho\) | \(H_{12}: eiU > \rho\)

Using neg.cor()

Now let’s use the function. To do this, we will need to set an equivalence interval (in our function, this is going to be using the eiL and eiU arguments). This is going to be the smallest correlation we would consider to be important. Ideally, this would be informed by theory, but for our first example below, let’s go with 0.4. This means that anything larger than 0.4 is going to be too important of an association to deem negligible. Further, this also means that anything smaller than -0.4 is going to be too important of an association to be deemed negligible. The arguments we need are as follows:

Required arguments (no default)

v1: the first variable we are interested in comparing,

v2: the second variable we are interested in comparing,

eiU: the top of our equivalence interval (0.4 in our first example),

eiL: the bottom of our equivalence interval (-0.4 in our first example),

Optional arguments (has a default)

alpha: the optional argument for the alpha level (.05),

data: the optional argument for the data frame, and

seed: the optional argument so that you can reproduce the results (for all of the examples, we will go with seed = 1, so if you rerun this, you should get the same values in your output).

Examples

Example 1

neg.cor(v1 = mtcars$wt, v2  = mtcars$qsec, eiU = 0.4, eiL = -0.4, alpha = 0.05,
        seed = 1)
---- Equivalence Based Test of Lack of Association with Resampling ----

Random Seed = 1 
Pearson's r: -0.1747159 

Equivalence Interval: Lower = -0.4 , Upper = 0.4 

# of Resamples: 10000 
Bootstrapped 90% Confidence Interval (5th Percentile, 95th Percentile):(-0.354694,-0.01043371)

The null hypothesis that the correlation between v1 and v2 falls outside of the equivalence interval can be rejected. A negligible association CAN be concluded. Be sure to interpret the magnitude (and precision) of the effect size. 

**********************
Proportional Distance (PD): -0.4367897 
0.95 % CI for PD: ( -0.9971597 , 0.04958426 ) 
**********************

Let’s interpet the output. -0.17 is the correlation between weight of the car and time to 1/4 mile. The equivalence interval is -0.4 to 0.4 as we had defined before. The confidence interval (computed through 1000 boostraps) is -0.35 to -0.01. Note the relationship between each bound of the confidence interval and the corresponding bound of the equivalence interval: the upper bound of the confidence interval is within the equivalence interval (-.01 is smaller than 0.40) and the lower bound of the confidence interval is within the equivalence interval (-0.35 is larger than -0.4). Because the confidence interval is completely contained within the equivalence interval, we can reject the null hypothesis that the variables are not negligibly associated (i.e., we have evidence of a negligible association). We can see this is stated in the text output as well is in the second part of the plot where the confidence interval is within the two * symbols denoting the equivalence interval.

We also get some output for the proportional distance, an effect size used for equivalence testing. Our proportional distance is -0.44 with a 95% confidence interval of (-1.00, 0.05). This suggests that the observed correlation of -.17 is at approximately 44% of the distance away from 0 to the lower bound.

Example 2

There were multiple ways we could have run this function. Let’s rerun it, but this time, we won’t use the $ and instead put variable names into v1 and v2, the dataset name will go into the data argument (that we did not use previously). The results below are identical to what we had above (note this is also because we set the same seed).

neg.cor(v1 = wt, v2  = qsec, eiU = 0.4, eiL = -0.4, alpha = 0.05, seed = 1, data = mtcars)
---- Equivalence Based Test of Lack of Association with Resampling ----

Random Seed = 1 
Pearson's r: -0.1747159 

Equivalence Interval: Lower = -0.4 , Upper = 0.4 

# of Resamples: 10000 
Bootstrapped 90% Confidence Interval (5th Percentile, 95th Percentile):(-0.354694,-0.01043371)

The null hypothesis that the correlation between v1 and v2 falls outside of the equivalence interval can be rejected. A negligible association CAN be concluded. Be sure to interpret the magnitude (and precision) of the effect size. 

**********************
Proportional Distance (PD): -0.4367897 
0.95 % CI for PD: ( -0.9971597 , 0.04958426 ) 
**********************

Example 3

For completeness, let’s demonstrate what a failure to detect a negligible association would look like. Let’s change our equivalence interval but keep everything else the same as we had it before. Let’s make our equivalence interval (-0.3, 0.3) instead of (-0.4, 0.4). Everything else will stay the same.

neg.cor(v1 = wt, v2  = qsec, eiU = 0.3, eiL = -0.3, alpha = 0.05, seed = 1, data = mtcars)
---- Equivalence Based Test of Lack of Association with Resampling ----

Random Seed = 1 
Pearson's r: -0.1747159 

Equivalence Interval: Lower = -0.3 , Upper = 0.3 

# of Resamples: 10000 
Bootstrapped 90% Confidence Interval (5th Percentile, 95th Percentile):(-0.354694,-0.01043371)

The null hypothesis that the correlation between v1 and v2 falls outside of the equivalence interval cannot be rejected. A negligible association CANNOT be concluded. Be sure to interpret the magnitude (and precision) of the effect size. 

**********************
Proportional Distance (PD): -0.5823863 
0.95 % CI for PD: ( -1.329546 , 0.06611235 ) 
**********************

Let’s look at the output. Our correlation between time to 1/4 mile and weight hasn’t changed (this makes sense because we are still looking at the relationship between the same two variables) and neither has our 90% bootstrapped confidence interval (we might have seen some slight changes in the confidence interval had we not kept our seed set to 1).

Our test decision, however, is different than before. Even though the upper bound of the confidence interval (-0.01) is within the equivalence interval, the lower bound of the confidence interval (-0.35) is not (-0.35 is smaller than -0.30).

For an illustration of this, look at the figure output above. In the bottom part of the figure, you can see that the -0.35 is outside of the range defined by the equivalence interval (the equivalence interval is defined by the stars, *). Because we need both parts of the confidence interval to be completely contained in the equivalence interval, we fail to reject the null hypothesis and fail to detect a negligible association, as can be seen in the decision.

The proportional distance is also different here, because the equivalence interval has changed.

Extractable Elements

A number of elements of the output can be extracted, including:

corxy The correlation between the two variables

q1 Lower bound of the confidence interval for the correlation

q2 Upper bound of the confidence interval for the correlation

eiL Lower bound of the negligible effect (equivalence) interval

eiU Upper bound of the negligible effect (equivalence) interval

decis_rs NHST decision

PD Proportional distance

CIPLL Lower bound of the 1-alpha CI for the PD

CIPDU Upper bound of the 1-alpha CI for the PD

alpha Nominal Type I error rate

LS0tDQp0aXRsZTogIlN0YXJ0IFVzaW5nIHRoZSBgbmVnLmNvcigpYCBGdW5jdGlvbiINCnN1YnRpdGxlOiB8IA0KICAgIEZyb20gdGhlIFtgbmVnbGlnaWJsZWBdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9uZWdsaWdpYmxlL2luZGV4Lmh0bWwpIFIgcGFja2FnZSFbXShHOi9NeSBEcml2ZS9SZXNlYXJjaC9DcmliYmllIExhYi9uZWdsaWdpYmxlIFZpZ25ldHRlcy9UZW1wbGF0ZS9uZWcubG9nby5wbmcpe3dpZHRoPTEwJX0gIA0KYXV0aG9yOiAiW05hdGFseSBCZXJpYmlza3kgYW5kIFJvYiBDcmliYmllXSINCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSlgIg0Kb3V0cHV0Og0KICBybWRmb3JtYXRzOjpyb2JvYm9vazoNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQotLS0NCg0KYGBge3Igc2V0dXAsIGVjaG89RkFMU0UsIGNhY2hlPUZBTFNFLCBtZXNzYWdlcz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNpbnN0YWxsLnBhY2thZ2VzKCJybWRmb3JtYXRzIikNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KHJtZGZvcm1hdHMsIHdhcm4uY29uZmxpY3RzPUZBTFNFKSkNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KGtuaXRyLCB3YXJuLmNvbmZsaWN0cz1GQUxTRSkpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeSh0aWR5dmVyc2UsIHdhcm4uY29uZmxpY3RzPUZBTFNFKSkNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KHBsb3RseSwgd2Fybi5jb25mbGljdHM9RkFMU0UpKQ0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkocmVhZHhsLCB3YXJuLmNvbmZsaWN0cz1GQUxTRSkpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShwbG90bHksIHdhcm4uY29uZmxpY3RzPUZBTFNFKSkNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KE1ldEJyZXdlciwgd2Fybi5jb25mbGljdHM9RkFMU0UpKQ0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkoZ2dhbmltYXRlLCB3YXJuLmNvbmZsaWN0cz1GQUxTRSkpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShkcGx5ciwgd2Fybi5jb25mbGljdHM9RkFMU0UpKQ0KDQojIyBHbG9iYWwgb3B0aW9ucw0Kb3B0aW9ucyhtYXgucHJpbnQ9Ijc1IikNCm9wdHNfY2h1bmskc2V0KGVjaG89VFJVRSwNCgkgICAgICAgICAgICAgY2FjaGU9VFJVRSwNCiAgICAgICAgICAgICAgIHByb21wdD1GQUxTRSwNCiAgICAgICAgICAgICAgIGNvbW1lbnQ9TkEsDQogICAgICAgICAgICAgICBtZXNzYWdlPUZBTFNFLA0KICAgICAgICAgICAgICAgd2FybmluZz1GQUxTRSkNCm9wdHNfa25pdCRzZXQod2lkdGg9NzUpDQpgYGANCg0KPGJyLz4NCg0KIyMgKipJbnRyb2R1Y3Rpb24qKg0KDQoNCg0KIyMjICoqV2hhdCBpcyB0aGUgcHVycG9zZS9nb2FsIG9mIGBuZWcuY29yKClgPyoqDQoNCg0KVGhlIGZ1bmN0aW9uIG5lZy5jb3IgY2FuIGhlbHAgdXMgZGV0ZXJtaW5lIHdoZXRoZXIgdHdvIHZhcmlhYmxlcyBoYXZlIGEgbmVnbGlnaWJsZSBhc3NvY2lhdGlvbiB3aXRoIG9uZSBhbm90aGVyLiBUbyBzZWUgaG93IGl0J3MgdXNlZCwgbGV0J3MgZmlyc3QgbG9hZCB0aGUgbmVnbGlnaWJsZSBwYWNrYWdlIChpZiB5b3UgZG9uJ3QgaGF2ZSBpdCBpbnN0YWxsZWQsIHlvdSB3aWxsIGhhdmUgdG8gaW5zdGFsbCBpdCBmaXJzdCkuIExldCdzIGxvYWQgdGhlIHBzeWNoIHBhY2thZ2UgdG9vLCBmb3Igc29tZSBkZXNjcmlwdGl2ZXMuDQoNCmBgYHtyfQ0KDQpsaWJyYXJ5KG5lZ2xpZ2libGUpDQpsaWJyYXJ5KHBzeWNoKQ0KDQpgYGANCg0KDQojIyMgKipXaGF0IGlzIHRoZSB0aGVvcnkgYmVoaW5kIGBuZWcuY29yKClgPyoqDQoNClRoZSBmdW5jdGlvbiB3aWxsIGNvbXBhcmUgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgYXJvdW5kIGEgY29ycmVsYXRpb24gdG8gc29tZXRoaW5nIGNhbGxlZCBhbiBlcXVpdmFsZW5jZSBpbnRlcnZhbC4gSWYgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgYXJvdW5kIHRoZSBjb3JyZWxhdGlvbiBpcyBjb21wbGV0ZWx5IGNvbnRhaW5lZCB3aXRoaW4gdGhlIGVxdWl2YWxlbmNlIGludGVydmFsLiB3ZSBoYXZlIGV2aWRlbmNlIHRvIHNheSB0aGF0IHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSB2YXJpYWJsZXMgaXMgc28gc21hbGwgdGhhdCB3ZSBjYW4gY2FsbCBpdCB1bmltcG9ydGFudCwgbWVhbmluZ2xlc3MsIGV0Yy4NCg0KV2UgYXJlIGdvaW5nIHRvIGJlIHVzaW5nIHRoZSBkYXRhc2V0IG10Y2FycyB0aGF0IGlzIGFscmVhZHkgcHJlLWxvYWRlZCBpbiBSLiBXZSBjYW4gaW52ZXN0aWdhdGUgd2hldGhlciB0aGUgd2VpZ2h0IG9mIGEgY2FyIChpbiAxMDAwbGJzKSBhbmQgaXRzIDEvNCBtaWxlIHRpbWUgYXJlIG5lZ2xpZ2libHkgY29ycmVsYXRlZCB3aXRoIG9uZSBhbm90aGVyLiBMZXQncyB0YWtlIHNvbWUgZGVzY3JpcHRpdmVzIChtYWtlIHN1cmUgbm90aGluZyBsb29rcyBvZGQsIHRoZSB2YXJpYWJsZXMgYXJlIGNvbnRpbnVvdXMsIGV0Yy4pIGFuZCBwbG90IHRoZWlyIGNvcnJlbGF0aW9uLg0KDQpgYGB7cn0NCg0KZGVzY3JpYmUobXRjYXJzJHd0KQ0KZGVzY3JpYmUobXRjYXJzJHFzZWMpDQpwbG90KG10Y2FycyR3dCwgbXRjYXJzJHFzZWMpDQpgYGANCg0KIyMjIyAqTnVsbCBhbmQgQWx0ZXJuYXRlIEh5cG90aGVzZXMgb2YgdGhlIFByb2NlZHVyZSoNCg0KJEhfezAxfTogZWlMIFxnZSBccmhvJCB8DQokSF97MDJ9OiBlaVUgXGxlIFxyaG8kDQoNCiRIX3sxMX06IGVpTCA8IFxyaG8kIHwNCiRIX3sxMn06IGVpVSA+IFxyaG8kDQoNCg0KIyMjICoqVXNpbmcgYG5lZy5jb3IoKWAqKg0KDQpOb3cgbGV0J3MgdXNlIHRoZSBmdW5jdGlvbi4gVG8gZG8gdGhpcywgd2Ugd2lsbCBuZWVkIHRvIHNldCBhbiBlcXVpdmFsZW5jZSBpbnRlcnZhbCAoaW4gb3VyIGZ1bmN0aW9uLCB0aGlzIGlzIGdvaW5nIHRvIGJlIHVzaW5nIHRoZSBlaUwgYW5kIGVpVSBhcmd1bWVudHMpLiBUaGlzIGlzIGdvaW5nIHRvIGJlIHRoZSBzbWFsbGVzdCBjb3JyZWxhdGlvbiB3ZSB3b3VsZCBjb25zaWRlciB0byBiZSBpbXBvcnRhbnQuIElkZWFsbHksIHRoaXMgd291bGQgYmUgaW5mb3JtZWQgYnkgdGhlb3J5LCBidXQgZm9yIG91ciBmaXJzdCBleGFtcGxlIGJlbG93LCBsZXQncyBnbyB3aXRoIDAuNC4gVGhpcyBtZWFucyB0aGF0IGFueXRoaW5nIGxhcmdlciB0aGFuIDAuNCBpcyBnb2luZyB0byBiZSB0b28gaW1wb3J0YW50IG9mIGFuIGFzc29jaWF0aW9uIHRvIGRlZW0gbmVnbGlnaWJsZS4gRnVydGhlciwgdGhpcyBhbHNvIG1lYW5zIHRoYXQgYW55dGhpbmcgc21hbGxlciB0aGFuIC0wLjQgaXMgZ29pbmcgdG8gYmUgdG9vIGltcG9ydGFudCBvZiBhbiBhc3NvY2lhdGlvbiB0byBiZSBkZWVtZWQgbmVnbGlnaWJsZS4gVGhlIGFyZ3VtZW50cyB3ZSBuZWVkIGFyZSBhcyBmb2xsb3dzOg0KDQojIyMjICpSZXF1aXJlZCBhcmd1bWVudHMgKG5vIGRlZmF1bHQpKg0KDQoqdjEqOiB0aGUgZmlyc3QgdmFyaWFibGUgd2UgYXJlIGludGVyZXN0ZWQgaW4gY29tcGFyaW5nLA0KDQoqdjIqOiB0aGUgc2Vjb25kIHZhcmlhYmxlIHdlIGFyZSBpbnRlcmVzdGVkIGluIGNvbXBhcmluZywNCg0KKmVpVSo6IHRoZSB0b3Agb2Ygb3VyIGVxdWl2YWxlbmNlIGludGVydmFsICgwLjQgaW4gb3VyIGZpcnN0IGV4YW1wbGUpLA0KDQoqZWlMKjogdGhlIGJvdHRvbSBvZiBvdXIgZXF1aXZhbGVuY2UgaW50ZXJ2YWwgKC0wLjQgaW4gb3VyIGZpcnN0IGV4YW1wbGUpLA0KDQoNCiMjIyMgKk9wdGlvbmFsIGFyZ3VtZW50cyAoaGFzIGEgZGVmYXVsdCkqDQoNCiphbHBoYSo6IHRoZSBvcHRpb25hbCBhcmd1bWVudCBmb3IgdGhlIGFscGhhIGxldmVsICguMDUpLCANCg0KKmRhdGEqOiB0aGUgb3B0aW9uYWwgYXJndW1lbnQgZm9yIHRoZSBkYXRhIGZyYW1lLCBhbmQNCg0KKnNlZWQqOiB0aGUgb3B0aW9uYWwgYXJndW1lbnQgc28gdGhhdCB5b3UgY2FuIHJlcHJvZHVjZSB0aGUgcmVzdWx0cyAoZm9yIGFsbCBvZiB0aGUgZXhhbXBsZXMsIHdlIHdpbGwgZ28gd2l0aCBzZWVkID0gMSwgc28gaWYgeW91IHJlcnVuIHRoaXMsIHlvdSBzaG91bGQgZ2V0IHRoZSBzYW1lIHZhbHVlcyBpbiB5b3VyIG91dHB1dCkuDQoNCg0KDQojIyAqKkV4YW1wbGVzKioNCg0KIyMjICoqRXhhbXBsZSAxKioNCg0KYGBge3J9DQpuZWcuY29yKHYxID0gbXRjYXJzJHd0LCB2MiAgPSBtdGNhcnMkcXNlYywgZWlVID0gMC40LCBlaUwgPSAtMC40LCBhbHBoYSA9IDAuMDUsDQogICAgICAgIHNlZWQgPSAxKQ0KYGBgDQpMZXTigJlzIGludGVycGV0IHRoZSBvdXRwdXQuIC0wLjE3IGlzIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHdlaWdodCBvZiB0aGUgY2FyIGFuZCB0aW1lIHRvIDEvNCBtaWxlLiBUaGUgZXF1aXZhbGVuY2UgaW50ZXJ2YWwgaXMgLTAuNCB0byAwLjQgYXMgd2UgaGFkIGRlZmluZWQgYmVmb3JlLiBUaGUgY29uZmlkZW5jZSBpbnRlcnZhbCAoY29tcHV0ZWQgdGhyb3VnaCAxMDAwIGJvb3N0cmFwcykgaXMgLTAuMzUgdG8gLTAuMDEuIE5vdGUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGVhY2ggYm91bmQgb2YgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgYW5kIHRoZSBjb3JyZXNwb25kaW5nIGJvdW5kIG9mIHRoZSBlcXVpdmFsZW5jZSBpbnRlcnZhbDogdGhlIHVwcGVyIGJvdW5kIG9mIHRoZSBjb25maWRlbmNlIGludGVydmFsIGlzIHdpdGhpbiB0aGUgZXF1aXZhbGVuY2UgaW50ZXJ2YWwgKC0uMDEgaXMgc21hbGxlciB0aGFuIDAuNDApIGFuZCB0aGUgbG93ZXIgYm91bmQgb2YgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgd2l0aGluIHRoZSBlcXVpdmFsZW5jZSBpbnRlcnZhbCAoLTAuMzUgaXMgbGFyZ2VyIHRoYW4gLTAuNCkuIEJlY2F1c2UgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgY29tcGxldGVseSBjb250YWluZWQgd2l0aGluIHRoZSBlcXVpdmFsZW5jZSBpbnRlcnZhbCwgd2UgY2FuIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgdGhlIHZhcmlhYmxlcyBhcmUgbm90IG5lZ2xpZ2libHkgYXNzb2NpYXRlZCAoaS5lLiwgd2UgaGF2ZSBldmlkZW5jZSBvZiBhIG5lZ2xpZ2libGUgYXNzb2NpYXRpb24pLiBXZSBjYW4gc2VlIHRoaXMgaXMgc3RhdGVkIGluIHRoZSB0ZXh0IG91dHB1dCBhcyB3ZWxsIGlzIGluIHRoZSBzZWNvbmQgcGFydCBvZiB0aGUgcGxvdCB3aGVyZSB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBpcyB3aXRoaW4gdGhlIHR3byAqIHN5bWJvbHMgZGVub3RpbmcgdGhlIGVxdWl2YWxlbmNlIGludGVydmFsLg0KDQpXZSBhbHNvIGdldCBzb21lIG91dHB1dCBmb3IgdGhlIHByb3BvcnRpb25hbCBkaXN0YW5jZSwgYW4gZWZmZWN0IHNpemUgdXNlZCBmb3IgZXF1aXZhbGVuY2UgdGVzdGluZy4gT3VyIHByb3BvcnRpb25hbCBkaXN0YW5jZSBpcyAtMC40NCB3aXRoIGEgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgKC0xLjAwLCAwLjA1KS4gVGhpcyBzdWdnZXN0cyB0aGF0IHRoZSBvYnNlcnZlZCBjb3JyZWxhdGlvbiBvZiAtLjE3IGlzIGF0IGFwcHJveGltYXRlbHkgNDQlIG9mIHRoZSBkaXN0YW5jZSBhd2F5IGZyb20gMCB0byB0aGUgbG93ZXIgYm91bmQuDQoNCg0KIyMjICoqRXhhbXBsZSAyKioNCg0KVGhlcmUgd2VyZSBtdWx0aXBsZSB3YXlzIHdlIGNvdWxkIGhhdmUgcnVuIHRoaXMgZnVuY3Rpb24uIExldOKAmXMgcmVydW4gaXQsIGJ1dCB0aGlzIHRpbWUsIHdlIHdvbuKAmXQgdXNlIHRoZSAkIGFuZCBpbnN0ZWFkIHB1dCB2YXJpYWJsZSBuYW1lcyBpbnRvIHYxIGFuZCB2MiwgdGhlIGRhdGFzZXQgbmFtZSB3aWxsIGdvIGludG8gdGhlIGRhdGEgYXJndW1lbnQgKHRoYXQgd2UgZGlkIG5vdCB1c2UgcHJldmlvdXNseSkuIFRoZSByZXN1bHRzIGJlbG93IGFyZSBpZGVudGljYWwgdG8gd2hhdCB3ZSBoYWQgYWJvdmUgKG5vdGUgdGhpcyBpcyBhbHNvIGJlY2F1c2Ugd2Ugc2V0IHRoZSBzYW1lIHNlZWQpLg0KDQpgYGB7cn0NCm5lZy5jb3IodjEgPSB3dCwgdjIgID0gcXNlYywgZWlVID0gMC40LCBlaUwgPSAtMC40LCBhbHBoYSA9IDAuMDUsIHNlZWQgPSAxLCBkYXRhID0gbXRjYXJzKQ0KYGBgDQoNCiMjIyAqKkV4YW1wbGUgMyoqDQoNCkZvciBjb21wbGV0ZW5lc3MsIGxldOKAmXMgZGVtb25zdHJhdGUgd2hhdCBhIGZhaWx1cmUgdG8gZGV0ZWN0IGEgbmVnbGlnaWJsZSBhc3NvY2lhdGlvbiB3b3VsZCBsb29rIGxpa2UuIExldOKAmXMgY2hhbmdlIG91ciBlcXVpdmFsZW5jZSBpbnRlcnZhbCBidXQga2VlcCBldmVyeXRoaW5nIGVsc2UgdGhlIHNhbWUgYXMgd2UgaGFkIGl0IGJlZm9yZS4gTGV04oCZcyBtYWtlIG91ciBlcXVpdmFsZW5jZSBpbnRlcnZhbCAoLTAuMywgMC4zKSBpbnN0ZWFkIG9mICgtMC40LCAwLjQpLiBFdmVyeXRoaW5nIGVsc2Ugd2lsbCBzdGF5IHRoZSBzYW1lLg0KDQoNCmBgYHtyfQ0KbmVnLmNvcih2MSA9IHd0LCB2MiAgPSBxc2VjLCBlaVUgPSAwLjMsIGVpTCA9IC0wLjMsIGFscGhhID0gMC4wNSwgc2VlZCA9IDEsIGRhdGEgPSBtdGNhcnMpDQpgYGANCg0KTGV04oCZcyBsb29rIGF0IHRoZSBvdXRwdXQuIE91ciBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRpbWUgdG8gMS80IG1pbGUgYW5kIHdlaWdodCBoYXNu4oCZdCBjaGFuZ2VkICh0aGlzIG1ha2VzIHNlbnNlIGJlY2F1c2Ugd2UgYXJlIHN0aWxsIGxvb2tpbmcgYXQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBzYW1lIHR3byB2YXJpYWJsZXMpIGFuZCBuZWl0aGVyIGhhcyBvdXIgOTAlIGJvb3RzdHJhcHBlZCBjb25maWRlbmNlIGludGVydmFsICh3ZSBtaWdodCBoYXZlIHNlZW4gc29tZSBzbGlnaHQgY2hhbmdlcyBpbiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBoYWQgd2Ugbm90IGtlcHQgb3VyIHNlZWQgc2V0IHRvIDEpLg0KDQpPdXIgdGVzdCBkZWNpc2lvbiwgaG93ZXZlciwgaXMgZGlmZmVyZW50IHRoYW4gYmVmb3JlLiBFdmVuIHRob3VnaCB0aGUgdXBwZXIgYm91bmQgb2YgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgKC0wLjAxKSBpcyB3aXRoaW4gdGhlIGVxdWl2YWxlbmNlIGludGVydmFsLCB0aGUgbG93ZXIgYm91bmQgb2YgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgKC0wLjM1KSBpcyBub3QgKC0wLjM1IGlzIHNtYWxsZXIgdGhhbiAtMC4zMCkuDQoNCkZvciBhbiBpbGx1c3RyYXRpb24gb2YgdGhpcywgbG9vayBhdCB0aGUgZmlndXJlIG91dHB1dCBhYm92ZS4gSW4gdGhlIGJvdHRvbSBwYXJ0IG9mIHRoZSBmaWd1cmUsIHlvdSBjYW4gc2VlIHRoYXQgdGhlIC0wLjM1IGlzIG91dHNpZGUgb2YgdGhlIHJhbmdlIGRlZmluZWQgYnkgdGhlIGVxdWl2YWxlbmNlIGludGVydmFsICh0aGUgZXF1aXZhbGVuY2UgaW50ZXJ2YWwgaXMgZGVmaW5lZCBieSB0aGUgc3RhcnMsICopLiBCZWNhdXNlIHdlIG5lZWQgYm90aCBwYXJ0cyBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCB0byBiZSBjb21wbGV0ZWx5IGNvbnRhaW5lZCBpbiB0aGUgZXF1aXZhbGVuY2UgaW50ZXJ2YWwsIHdlIGZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgYW5kIGZhaWwgdG8gZGV0ZWN0IGEgbmVnbGlnaWJsZSBhc3NvY2lhdGlvbiwgYXMgY2FuIGJlIHNlZW4gaW4gdGhlIGRlY2lzaW9uLg0KDQpUaGUgcHJvcG9ydGlvbmFsIGRpc3RhbmNlIGlzIGFsc28gZGlmZmVyZW50IGhlcmUsIGJlY2F1c2UgdGhlIGVxdWl2YWxlbmNlIGludGVydmFsIGhhcyBjaGFuZ2VkLg0KDQoNCiMjICoqRXh0cmFjdGFibGUgRWxlbWVudHMqKg0KDQpBIG51bWJlciBvZiBlbGVtZW50cyBvZiB0aGUgb3V0cHV0IGNhbiBiZSBleHRyYWN0ZWQsIGluY2x1ZGluZzoNCg0KKmNvcnh5KiBUaGUgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgdHdvIHZhcmlhYmxlcw0KDQoqcTEqIExvd2VyIGJvdW5kIG9mIHRoZSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgY29ycmVsYXRpb24NCg0KKnEyKiBVcHBlciBib3VuZCBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIGNvcnJlbGF0aW9uDQoNCiplaUwqIExvd2VyIGJvdW5kIG9mIHRoZSBuZWdsaWdpYmxlIGVmZmVjdCAoZXF1aXZhbGVuY2UpIGludGVydmFsDQoNCiplaVUqIFVwcGVyIGJvdW5kIG9mIHRoZSBuZWdsaWdpYmxlIGVmZmVjdCAoZXF1aXZhbGVuY2UpIGludGVydmFsDQoNCipkZWNpc19ycyogTkhTVCBkZWNpc2lvbg0KDQoqUEQqIFByb3BvcnRpb25hbCBkaXN0YW5jZQ0KDQoqQ0lQTEwqIExvd2VyIGJvdW5kIG9mIHRoZSAxLWFscGhhIENJIGZvciB0aGUgUEQNCg0KKkNJUERVKiBVcHBlciBib3VuZCBvZiB0aGUgMS1hbHBoYSBDSSBmb3IgdGhlIFBEDQoNCiphbHBoYSogTm9taW5hbCBUeXBlIEkgZXJyb3IgcmF0ZQ==