Start Using the neg.indvars() Function

From the negligible R package


Introduction

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

The purpose of the neg.indvars function is to evaluate if multiple population variances can be considered negligibly different (i.e., practically equivalent). For example, imagine that you are running a two independent samples t test and you want to test the assumption that the population variances are equal. You could use the neg.indvars to evaluate that assumption. .

library(negligible)
library(psych)

What is the theory behind neg.indvars()?

Mara and Cribbie (2017) proposed the use of a negligible effect testing based homogeneity of variance (HOV) test that was derived from Wellek’s (2010) one-way test of population mean equivalence and Levene’s HOV test. With this test, the research hypothesis (negligible difference in population variances) is aligned with the alternative hypothesis, not the null hypothesis. More specifically, the null hypothesis specifies that the difference in the variances falls outside of or at the bounds of an a priori determined interval (based on the smallest practically significant difference in population variances), whereas, the alternative hypothesis declares that the difference among the variances of the groups falls within this interval (i.e., a negligible difference in population variances). The test statistic quantifies the standardized squared Euclidian distance, and thus, the interval is one-sided.

Wellek (2010) suggests liberal and conservative interval bound values of epsilon (eps) = .50 and eps = .25, respectively. See Wellek, 2010, pp. 16, 17, 22, for details.

Kim, Y. J. & Cribbie, R. A. (2018). The variance homogeneity assumption and the traditional ANOVA: Exploring a better gatekeeper. British Journal of Mathematical and Statistical Psychology, 71, 1-12. DOI: 10.1111/bmsp.12103. New York: CRC Press

Mara, C. & Cribbie, R. A. (2017). Equivalence of population variances: Synchronizing the objective and analysis. Journal of Experimental Education, 86, 442-457. DOI: 10.1080/00220973.2017.1301356

Wellek, S. (2010). Testing statistical hypotheses of equivalence and noninferiority (2nd Ed.). Boca Raton, FL: CRC Press.

Null and Alternate Hypotheses of the Procedure

The null hypothesis specifies that the difference in the variances is non-negligible, while the alternate hypothesis states that the difference in the variances is negligible.

\(H_{0}: \psi^{*2} \ge \epsilon^2\)

\(H_{1}: \psi^{*2} \lt \epsilon^2\)

Using neg.indvars()

Now let’s use the function. To do this, we will need to set a negligible effect interval (in our function, this is going to be using the eps argument). This is going to be the smallest Euclidian distance that we would consider to be important. As discussed above, Wellek (2010) suggests liberal and conservative interval bound values of eps = .50 and eps = .25, respectively. Note that the default eps is .50.

The basic set-up of the function looks like this:

neg.indvars(dv, iv, eps = 0.5, alpha = 0.05, na.rm = TRUE, data = NULL)

Required arguments (no default)

dv - dependent/outcome variable (numeric)

iv - independent/predictor variable (factor)

Optional arguments (has a default)

eps - Wellek (2010) suggests conservative (eps = .25) and liberal (eps = .50) bounds for the test of negligible difference in independent population variances. The default is eps = .50, but any value could be used. See Mara & Cribbie (2017) or Wellek (2010).

alpha - nominal Type I error rate (\(\alpha\)). The default is .05, but any value can be used (e.g., .01, .10, .06)

na.rm - should cases with missing values be deleted. Right now the function only works with na.rm=TRUE if there are missing values.

data - name of the dataset where the dv and iv reside

Examples

Example 1

Let’s look at an example using the mtcars dataset from R. Our outcome variable is miles/gallon (mpg) and our predictor is number of cylinders in the vehicle (cyl). In this example, we want to know if the difference in the population variances of mpg across cyl (4, 6, 8) is negligible (i.e., are the population variances of mpg across cyl equivalent). We will use the default \(\alpha\) = .05.

d <- mtcars # open the dataset and store it in the object d
names(d) # look at the variable names
 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
[11] "carb"
d$cyl <- factor(d$cyl) #make the variable cyl a factor
tapply(d$mpg, d$cyl, var) # explore the variances of mpg at each level of cyl
        4         6         8 
20.338545  2.112857  6.553846 

Now, let’s apply the neg.vars function to see if we can reject the null hypothesis that the population variances are non-negligibly different. We will use the liberal cut-off for eps (.5).

library(negligible)
neg.indvars(dv = mpg, iv = cyl, eps = .5, alpha = .05,
            na.rm = TRUE, data = d)
-- Equivalence of Population Variances --
-- Independent Groups --

Group Variances:  
 4 6 8 
 20.33855 2.112857 6.553846 

Group Standard Deviations:  
 4.509828 1.453567 2.560048 

Group Median Absolute Deviations:  
 6.52344 1.92738 1.55673 

**********************

Ratio of Largest to Smallest Variances:  
 9.626086 

**********************

Epsilon Value (establish the Equivalence Interval):  
 0.5 

Levene-Wellek-Welch (LWW) Statistic:  
 1.147718 

Critical Value for LWW:  
 0.03458143 

NHST Decision:  
 The null hypothesis that the differences between the population variances falls outside the equivalence interval cannot be rejected. A negligible difference among the population variances cannot be concluded. Be sure to interpret the magnitude (and precision) of the effect size. 

**********************

The LWW (Levene-Wellek-Welch) statistic must be less than the critical value to reject the null hypothesis. In this case, LWW = 1.148 > LWW(crit) = .035, so we cannot reject Ho. There is a lack of support for the contention that the population variances are negligibly different.

Example 2

In this example, we will enter the data directly instead of calling the data from a dataset (i.e., no data argument). We will also use the conservative, instead of liberal, bound for eps (i.e., .25). In this example we are checking to see if the variances in the incomes (in 000s of dollars) of males and females can be considered negligible. We will use \(\alpha\) = .10.

group <- rep(c("male", "female"),each=10)
group <- factor(group)
income <- c(52,43,75,63,45,102,142,65,79,44,54,121,102,54,62,44,29,55,74,81)
library(negligible)
neg.indvars(dv = income, iv = group, eps = .25, alpha = .10)
-- Equivalence of Population Variances --
-- Independent Groups --

Group Variances:  
 female male 
 762.4889 970.2222 

Group Standard Deviations:  
 27.6132 31.14839 

Group Median Absolute Deviations:  
 22.239 25.2042 

**********************

Ratio of Largest to Smallest Variances:  
 1.272441 

**********************

Epsilon Value (establish the Equivalence Interval):  
 0.25 

Levene-Wellek-Welch (LWW) Statistic:  
 0.001602909 

Critical Value for LWW:  
 0.003030741 

NHST Decision:  
 The null hypothesis that the differences between the population variances falls outside the equivalence interval can be rejected. A negligible difference among the population variances can be concluded. Be sure to interpret the magnitude (and precision) of the effect size. 

**********************

In this example, the LWW statistic (0.0016) is less than the critical LWW value (0.0030), and thus we can reject the null hypothesis that the differences in the variances is non-negligible (and conclude that the difference in the population variances is negligible).

Extractable Elements

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

vars: Sample variances

sds: Sample standard deviations

mads: Sample median absolute deviations

ratio: Ratio of the largest to smallest variance

eps: Epsilon (e) can be described as the minimum difference in the variances that one would consider non-negligible.

LWW_md: Levene-Wellek-Welch statistic based on the median.

crit_LWW_md Critical value for the Levene-Wellek-Welch statistic based on the median.

alpha Nominal Type I error rate

LS0tDQp0aXRsZTogIlN0YXJ0IFVzaW5nIHRoZSBgbmVnLmluZHZhcnMoKWAgRnVuY3Rpb24iDQpzdWJ0aXRsZTogfCANCiAgICBGcm9tIHRoZSBbYG5lZ2xpZ2libGVgXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvbmVnbGlnaWJsZS9pbmRleC5odG1sKSBSIHBhY2thZ2UhW10oRzovTXkgRHJpdmUvUmVzZWFyY2gvQ3JpYmJpZSBMYWIvbmVnbGlnaWJsZSBWaWduZXR0ZXMvVGVtcGxhdGUvbmVnLmxvZ28ucG5nKXt3aWR0aD0xMCV9ICANCmF1dGhvcjogIltSb2IgQ3JpYmJpZV0oaHR0cHM6Ly9jcmliYmllLmluZm8ueW9ya3UuY2EvKSINCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSlgIg0Kb3V0cHV0Og0KICBybWRmb3JtYXRzOjpyb2JvYm9vazoNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQotLS0NCg0KYGBge3Igc2V0dXAsIGVjaG89RkFMU0UsIGNhY2hlPUZBTFNFLCBtZXNzYWdlcz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNpbnN0YWxsLnBhY2thZ2VzKCJybWRmb3JtYXRzIikNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KHJtZGZvcm1hdHMsIHdhcm4uY29uZmxpY3RzPUZBTFNFKSkNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KGtuaXRyLCB3YXJuLmNvbmZsaWN0cz1GQUxTRSkpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeSh0aWR5dmVyc2UsIHdhcm4uY29uZmxpY3RzPUZBTFNFKSkNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KHBsb3RseSwgd2Fybi5jb25mbGljdHM9RkFMU0UpKQ0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkocmVhZHhsLCB3YXJuLmNvbmZsaWN0cz1GQUxTRSkpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShwbG90bHksIHdhcm4uY29uZmxpY3RzPUZBTFNFKSkNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KE1ldEJyZXdlciwgd2Fybi5jb25mbGljdHM9RkFMU0UpKQ0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkoZ2dhbmltYXRlLCB3YXJuLmNvbmZsaWN0cz1GQUxTRSkpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShkcGx5ciwgd2Fybi5jb25mbGljdHM9RkFMU0UpKQ0KDQojIyBHbG9iYWwgb3B0aW9ucw0Kb3B0aW9ucyhtYXgucHJpbnQ9Ijc1IikNCm9wdHNfY2h1bmskc2V0KGVjaG89VFJVRSwNCgkgICAgICAgICAgICAgY2FjaGU9VFJVRSwNCiAgICAgICAgICAgICAgIHByb21wdD1GQUxTRSwNCiAgICAgICAgICAgICAgIGNvbW1lbnQ9TkEsDQogICAgICAgICAgICAgICBtZXNzYWdlPUZBTFNFLA0KICAgICAgICAgICAgICAgd2FybmluZz1GQUxTRSkNCm9wdHNfa25pdCRzZXQod2lkdGg9NzUpDQpgYGANCg0KPGJyLz4NCg0KIyMgKipJbnRyb2R1Y3Rpb24qKg0KDQoNCg0KIyMjICoqV2hhdCBpcyB0aGUgcHVycG9zZS9nb2FsIG9mIGBuZWcuaW5kdmFycygpYD8qKg0KDQoNClRoZSBwdXJwb3NlIG9mIHRoZSBuZWcuaW5kdmFycyBmdW5jdGlvbiBpcyB0byBldmFsdWF0ZSBpZiBtdWx0aXBsZSBwb3B1bGF0aW9uIHZhcmlhbmNlcyBjYW4gYmUgY29uc2lkZXJlZCAqbmVnbGlnaWJseSogZGlmZmVyZW50IChpLmUuLCBwcmFjdGljYWxseSBlcXVpdmFsZW50KS4gRm9yIGV4YW1wbGUsIGltYWdpbmUgdGhhdCB5b3UgYXJlIHJ1bm5pbmcgYSB0d28gaW5kZXBlbmRlbnQgc2FtcGxlcyAqdCogdGVzdCBhbmQgeW91IHdhbnQgdG8gdGVzdCB0aGUgYXNzdW1wdGlvbiB0aGF0IHRoZSBwb3B1bGF0aW9uIHZhcmlhbmNlcyBhcmUgZXF1YWwuIFlvdSBjb3VsZCB1c2UgdGhlIG5lZy5pbmR2YXJzIHRvIGV2YWx1YXRlIHRoYXQgYXNzdW1wdGlvbi4gLg0KDQpgYGB7cn0NCg0KbGlicmFyeShuZWdsaWdpYmxlKQ0KbGlicmFyeShwc3ljaCkNCg0KYGBgDQoNCg0KIyMjICoqV2hhdCBpcyB0aGUgdGhlb3J5IGJlaGluZCBgbmVnLmluZHZhcnMoKWA/KioNCg0KTWFyYSBhbmQgQ3JpYmJpZSAoMjAxNykgcHJvcG9zZWQgdGhlIHVzZSBvZiBhDQpuZWdsaWdpYmxlIGVmZmVjdCB0ZXN0aW5nIGJhc2VkIGhvbW9nZW5laXR5IG9mIHZhcmlhbmNlIChIT1YpIHRlc3QgdGhhdCB3YXMgZGVyaXZlZCBmcm9tIFdlbGxla+KAmXMgKDIwMTApIG9uZS13YXkgdGVzdCBvZiBwb3B1bGF0aW9uIG1lYW4gZXF1aXZhbGVuY2UgYW5kIExldmVuZeKAmXMgSE9WIHRlc3QuIFdpdGggdGhpcyB0ZXN0LCB0aGUgcmVzZWFyY2ggaHlwb3RoZXNpcyAobmVnbGlnaWJsZSBkaWZmZXJlbmNlIGluIHBvcHVsYXRpb24gdmFyaWFuY2VzKSBpcyBhbGlnbmVkIHdpdGggdGhlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMsIG5vdCB0aGUgbnVsbCBoeXBvdGhlc2lzLiBNb3JlIHNwZWNpZmljYWxseSwgdGhlIG51bGwgaHlwb3RoZXNpcyBzcGVjaWZpZXMgdGhhdCB0aGUgZGlmZmVyZW5jZSBpbiB0aGUgdmFyaWFuY2VzIGZhbGxzIG91dHNpZGUgb2Ygb3IgYXQgdGhlIGJvdW5kcyBvZiBhbiBhIHByaW9yaSBkZXRlcm1pbmVkIGludGVydmFsIChiYXNlZCBvbiB0aGUgc21hbGxlc3QgcHJhY3RpY2FsbHkgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiBwb3B1bGF0aW9uIHZhcmlhbmNlcyksIHdoZXJlYXMsIHRoZSBhbHRlcm5hdGl2ZSBoeXBvdGhlc2lzIGRlY2xhcmVzIHRoYXQgdGhlIGRpZmZlcmVuY2UgYW1vbmcgdGhlIHZhcmlhbmNlcyBvZiB0aGUgZ3JvdXBzIGZhbGxzIHdpdGhpbiB0aGlzIGludGVydmFsIChpLmUuLCBhIG5lZ2xpZ2libGUgZGlmZmVyZW5jZSBpbiBwb3B1bGF0aW9uIHZhcmlhbmNlcykuIFRoZSB0ZXN0IHN0YXRpc3RpYyBxdWFudGlmaWVzIHRoZSBzdGFuZGFyZGl6ZWQgc3F1YXJlZCBFdWNsaWRpYW4gZGlzdGFuY2UsIGFuZCB0aHVzLCB0aGUgaW50ZXJ2YWwgaXMgb25lLXNpZGVkLg0KDQpXZWxsZWsgKDIwMTApIHN1Z2dlc3RzIGxpYmVyYWwgYW5kIGNvbnNlcnZhdGl2ZSBpbnRlcnZhbCBib3VuZCB2YWx1ZXMgb2YgZXBzaWxvbiAoZXBzKSA9IC41MCBhbmQgZXBzID0gLjI1LCByZXNwZWN0aXZlbHkuIFNlZSBXZWxsZWssIDIwMTAsIHBwLiAxNiwgMTcsIDIyLCBmb3IgZGV0YWlscy4NCg0KDQpLaW0sIFkuIEouICYgQ3JpYmJpZSwgUi4gQS4gKDIwMTgpLiBUaGUgdmFyaWFuY2UgaG9tb2dlbmVpdHkgYXNzdW1wdGlvbiBhbmQgdGhlIHRyYWRpdGlvbmFsIEFOT1ZBOiBFeHBsb3JpbmcgYSBiZXR0ZXIgZ2F0ZWtlZXBlci4gQnJpdGlzaCBKb3VybmFsIG9mIE1hdGhlbWF0aWNhbCBhbmQgU3RhdGlzdGljYWwgUHN5Y2hvbG9neSwgNzEsIDEtMTIuIERPSTogMTAuMTExMS9ibXNwLjEyMTAzLiBOZXcgWW9yazogQ1JDIFByZXNzDQoNCk1hcmEsIEMuICYgQ3JpYmJpZSwgUi4gQS4gKDIwMTcpLiBFcXVpdmFsZW5jZSBvZiBwb3B1bGF0aW9uIHZhcmlhbmNlczogU3luY2hyb25pemluZyB0aGUgb2JqZWN0aXZlIGFuZCBhbmFseXNpcy4gSm91cm5hbCBvZiBFeHBlcmltZW50YWwgRWR1Y2F0aW9uLCA4NiwgNDQyLTQ1Ny4gRE9JOg0KMTAuMTA4MC8wMDIyMDk3My4yMDE3LjEzMDEzNTYgIA0KDQpXZWxsZWssIFMuICgyMDEwKS4gVGVzdGluZyBzdGF0aXN0aWNhbCBoeXBvdGhlc2VzIG9mIGVxdWl2YWxlbmNlIGFuZCBub25pbmZlcmlvcml0eSAoMm5kIEVkLikuIEJvY2EgUmF0b24sIEZMOiBDUkMgUHJlc3MuIA0KDQoNCiMjIyMgKk51bGwgYW5kIEFsdGVybmF0ZSBIeXBvdGhlc2VzIG9mIHRoZSBQcm9jZWR1cmUqDQoNClRoZSBudWxsIGh5cG90aGVzaXMgc3BlY2lmaWVzIHRoYXQgdGhlIGRpZmZlcmVuY2UgaW4gdGhlIHZhcmlhbmNlcyBpcyBub24tbmVnbGlnaWJsZSwgd2hpbGUgdGhlIGFsdGVybmF0ZSBoeXBvdGhlc2lzIHN0YXRlcyB0aGF0IHRoZSBkaWZmZXJlbmNlIGluIHRoZSB2YXJpYW5jZXMgaXMgbmVnbGlnaWJsZS4gDQoNCiRIX3swfTogXHBzaV57KjJ9IFxnZSBcZXBzaWxvbl4yJCANCg0KJEhfezF9OiBccHNpXnsqMn0gXGx0IFxlcHNpbG9uXjIkIA0KDQoNCiMjIyAqKlVzaW5nIGBuZWcuaW5kdmFycygpYCoqDQoNCk5vdyBsZXQncyB1c2UgdGhlIGZ1bmN0aW9uLiBUbyBkbyB0aGlzLCB3ZSB3aWxsIG5lZWQgdG8gc2V0IGEgbmVnbGlnaWJsZSBlZmZlY3QgaW50ZXJ2YWwgKGluIG91ciBmdW5jdGlvbiwgdGhpcyBpcyBnb2luZyB0byBiZSB1c2luZyB0aGUgKmVwcyogYXJndW1lbnQpLiBUaGlzIGlzIGdvaW5nIHRvIGJlIHRoZSBzbWFsbGVzdCBFdWNsaWRpYW4gZGlzdGFuY2UgdGhhdCB3ZSB3b3VsZCBjb25zaWRlciB0byBiZSBpbXBvcnRhbnQuIEFzIGRpc2N1c3NlZCBhYm92ZSwgV2VsbGVrICgyMDEwKSBzdWdnZXN0cyBsaWJlcmFsIGFuZCBjb25zZXJ2YXRpdmUgaW50ZXJ2YWwgYm91bmQgdmFsdWVzIG9mICplcHMqID0gLjUwIGFuZCAqZXBzKiA9IC4yNSwgcmVzcGVjdGl2ZWx5LiBOb3RlIHRoYXQgdGhlIGRlZmF1bHQgKmVwcyogaXMgLjUwLg0KDQoNCiMjIyMgVGhlIGJhc2ljIHNldC11cCBvZiB0aGUgZnVuY3Rpb24gbG9va3MgbGlrZSB0aGlzOg0KbmVnLmluZHZhcnMoZHYsIGl2LCBlcHMgPSAwLjUsIGFscGhhID0gMC4wNSwgbmEucm0gPSBUUlVFLCBkYXRhID0gTlVMTCkNCg0KIyMjIyAqUmVxdWlyZWQgYXJndW1lbnRzIChubyBkZWZhdWx0KSoNCg0KKmR2KiAtIGRlcGVuZGVudC9vdXRjb21lIHZhcmlhYmxlIChudW1lcmljKQ0KDQoqaXYqIC0gaW5kZXBlbmRlbnQvcHJlZGljdG9yIHZhcmlhYmxlIChmYWN0b3IpDQoNCg0KIyMjIyAqT3B0aW9uYWwgYXJndW1lbnRzIChoYXMgYSBkZWZhdWx0KSoNCg0KKmVwcyogLSBXZWxsZWsgKDIwMTApIHN1Z2dlc3RzIGNvbnNlcnZhdGl2ZSAoKmVwcyogPSAuMjUpIGFuZCBsaWJlcmFsICgqZXBzKiA9IC41MCkgYm91bmRzIGZvciB0aGUgdGVzdCBvZiBuZWdsaWdpYmxlIGRpZmZlcmVuY2UgaW4gaW5kZXBlbmRlbnQgcG9wdWxhdGlvbiB2YXJpYW5jZXMuIFRoZSBkZWZhdWx0IGlzICplcHMqID0gLjUwLCBidXQgYW55IHZhbHVlIGNvdWxkIGJlIHVzZWQuIFNlZSBNYXJhICYgQ3JpYmJpZSAoMjAxNykgb3IgV2VsbGVrICgyMDEwKS4NCg0KKmFscGhhKiAtIG5vbWluYWwgVHlwZSBJIGVycm9yIHJhdGUgKCRcYWxwaGEkKS4gVGhlIGRlZmF1bHQgaXMgLjA1LCBidXQgYW55IHZhbHVlIGNhbiBiZSB1c2VkIChlLmcuLCAuMDEsIC4xMCwgLjA2KQ0KDQoqbmEucm0qIC0gc2hvdWxkIGNhc2VzIHdpdGggbWlzc2luZyB2YWx1ZXMgYmUgZGVsZXRlZC4gUmlnaHQgbm93IHRoZSBmdW5jdGlvbiBvbmx5IHdvcmtzIHdpdGggbmEucm09VFJVRSBpZiB0aGVyZSBhcmUgbWlzc2luZyB2YWx1ZXMuDQoNCipkYXRhKiAtIG5hbWUgb2YgdGhlIGRhdGFzZXQgd2hlcmUgdGhlICpkdiogYW5kICppdiogcmVzaWRlDQoNCg0KDQoNCiMjICoqRXhhbXBsZXMqKg0KDQojIyMgKipFeGFtcGxlIDEqKg0KDQpMZXQncyBsb29rIGF0IGFuIGV4YW1wbGUgdXNpbmcgdGhlICoqbXRjYXJzKiogZGF0YXNldCBmcm9tIFIuIE91ciBvdXRjb21lIHZhcmlhYmxlIGlzIG1pbGVzL2dhbGxvbiAobXBnKSBhbmQgb3VyIHByZWRpY3RvciBpcyBudW1iZXIgb2YgY3lsaW5kZXJzIGluIHRoZSB2ZWhpY2xlIChjeWwpLiBJbiB0aGlzIGV4YW1wbGUsIHdlIHdhbnQgdG8ga25vdyBpZiB0aGUgZGlmZmVyZW5jZSBpbiB0aGUgcG9wdWxhdGlvbiB2YXJpYW5jZXMgb2YgbXBnIGFjcm9zcyBjeWwgKDQsIDYsIDgpIGlzIG5lZ2xpZ2libGUgKGkuZS4sIGFyZSB0aGUgcG9wdWxhdGlvbiB2YXJpYW5jZXMgb2YgKm1wZyogYWNyb3NzICpjeWwqIGVxdWl2YWxlbnQpLiBXZSB3aWxsIHVzZSB0aGUgZGVmYXVsdCAkXGFscGhhJCA9IC4wNS4gDQoNCmBgYHtyfQ0KZCA8LSBtdGNhcnMgIyBvcGVuIHRoZSBkYXRhc2V0IGFuZCBzdG9yZSBpdCBpbiB0aGUgb2JqZWN0IGQNCm5hbWVzKGQpICMgbG9vayBhdCB0aGUgdmFyaWFibGUgbmFtZXMNCmQkY3lsIDwtIGZhY3RvcihkJGN5bCkgI21ha2UgdGhlIHZhcmlhYmxlIGN5bCBhIGZhY3Rvcg0KdGFwcGx5KGQkbXBnLCBkJGN5bCwgdmFyKSAjIGV4cGxvcmUgdGhlIHZhcmlhbmNlcyBvZiBtcGcgYXQgZWFjaCBsZXZlbCBvZiBjeWwNCmBgYA0KDQpOb3csIGxldCdzIGFwcGx5IHRoZSBuZWcudmFycyBmdW5jdGlvbiB0byBzZWUgaWYgd2UgY2FuIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgdGhlIHBvcHVsYXRpb24gdmFyaWFuY2VzIGFyZSBub24tbmVnbGlnaWJseSBkaWZmZXJlbnQuIFdlIHdpbGwgdXNlIHRoZSBsaWJlcmFsIGN1dC1vZmYgZm9yICplcHMqICguNSkuDQoNCmBgYHtyfQ0KbGlicmFyeShuZWdsaWdpYmxlKQ0KbmVnLmluZHZhcnMoZHYgPSBtcGcsIGl2ID0gY3lsLCBlcHMgPSAuNSwgYWxwaGEgPSAuMDUsDQogICAgICAgICAgICBuYS5ybSA9IFRSVUUsIGRhdGEgPSBkKQ0KYGBgDQoNClRoZSBMV1cgKExldmVuZS1XZWxsZWstV2VsY2gpIHN0YXRpc3RpYyBtdXN0IGJlIGxlc3MgdGhhbiB0aGUgY3JpdGljYWwgdmFsdWUgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuIEluIHRoaXMgY2FzZSwgTFdXID0gMS4xNDggPiBMV1coY3JpdCkgPSAuMDM1LCBzbyB3ZSBjYW5ub3QgcmVqZWN0ICpIbyouIFRoZXJlIGlzIGEgbGFjayBvZiBzdXBwb3J0IGZvciB0aGUgY29udGVudGlvbiB0aGF0IHRoZSBwb3B1bGF0aW9uIHZhcmlhbmNlcyBhcmUgbmVnbGlnaWJseSBkaWZmZXJlbnQuDQoNCg0KIyMjICoqRXhhbXBsZSAyKioNCg0KSW4gdGhpcyBleGFtcGxlLCB3ZSB3aWxsIGVudGVyIHRoZSBkYXRhIGRpcmVjdGx5IGluc3RlYWQgb2YgY2FsbGluZyB0aGUgZGF0YSBmcm9tIGEgZGF0YXNldCAoaS5lLiwgbm8gKmRhdGEqIGFyZ3VtZW50KS4gV2Ugd2lsbCBhbHNvIHVzZSB0aGUgY29uc2VydmF0aXZlLCBpbnN0ZWFkIG9mIGxpYmVyYWwsIGJvdW5kIGZvciAqZXBzKiAoaS5lLiwgLjI1KS4gSW4gdGhpcyBleGFtcGxlIHdlIGFyZSBjaGVja2luZyB0byBzZWUgaWYgdGhlIHZhcmlhbmNlcyBpbiB0aGUgaW5jb21lcyAoaW4gMDAwcyBvZiBkb2xsYXJzKSBvZiBtYWxlcyBhbmQgZmVtYWxlcyBjYW4gYmUgY29uc2lkZXJlZCBuZWdsaWdpYmxlLiBXZSB3aWxsIHVzZSAkXGFscGhhJCA9IC4xMC4gDQoNCmBgYHtyfQ0KZ3JvdXAgPC0gcmVwKGMoIm1hbGUiLCAiZmVtYWxlIiksZWFjaD0xMCkNCmdyb3VwIDwtIGZhY3Rvcihncm91cCkNCmluY29tZSA8LSBjKDUyLDQzLDc1LDYzLDQ1LDEwMiwxNDIsNjUsNzksNDQsNTQsMTIxLDEwMiw1NCw2Miw0NCwyOSw1NSw3NCw4MSkNCmxpYnJhcnkobmVnbGlnaWJsZSkNCm5lZy5pbmR2YXJzKGR2ID0gaW5jb21lLCBpdiA9IGdyb3VwLCBlcHMgPSAuMjUsIGFscGhhID0gLjEwKQ0KYGBgDQoNCkluIHRoaXMgZXhhbXBsZSwgdGhlIExXVyBzdGF0aXN0aWMgKDAuMDAxNikgaXMgbGVzcyB0aGFuIHRoZSBjcml0aWNhbCBMV1cgdmFsdWUgKDAuMDAzMCksIGFuZCB0aHVzIHdlIGNhbiByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHRoZSBkaWZmZXJlbmNlcyBpbiB0aGUgdmFyaWFuY2VzIGlzIG5vbi1uZWdsaWdpYmxlIChhbmQgY29uY2x1ZGUgdGhhdCB0aGUgZGlmZmVyZW5jZSBpbiB0aGUgcG9wdWxhdGlvbiB2YXJpYW5jZXMgaXMgbmVnbGlnaWJsZSkuDQoNCg0KIyMgKipFeHRyYWN0YWJsZSBFbGVtZW50cyoqDQoNCkEgbnVtYmVyIG9mIGVsZW1lbnRzIG9mIHRoZSBvdXRwdXQgY2FuIGJlIGV4dHJhY3RlZCwgaW5jbHVkaW5nOg0KDQoNCip2YXJzKjogU2FtcGxlIHZhcmlhbmNlcw0KDQoqc2RzKjogU2FtcGxlIHN0YW5kYXJkIGRldmlhdGlvbnMNCg0KKm1hZHMqOiBTYW1wbGUgbWVkaWFuIGFic29sdXRlIGRldmlhdGlvbnMNCg0KKnJhdGlvKjogUmF0aW8gb2YgdGhlIGxhcmdlc3QgdG8gc21hbGxlc3QgdmFyaWFuY2UNCg0KKmVwcyo6IEVwc2lsb24gKGUpIGNhbiBiZSBkZXNjcmliZWQgYXMgdGhlIG1pbmltdW0gZGlmZmVyZW5jZSBpbiB0aGUgdmFyaWFuY2VzIHRoYXQgb25lIHdvdWxkIGNvbnNpZGVyIG5vbi1uZWdsaWdpYmxlLg0KDQoqTFdXX21kKjogTGV2ZW5lLVdlbGxlay1XZWxjaCBzdGF0aXN0aWMgYmFzZWQgb24gdGhlIG1lZGlhbi4NCg0KKmNyaXRfTFdXX21kKiBDcml0aWNhbCB2YWx1ZSBmb3IgdGhlIExldmVuZS1XZWxsZWstV2VsY2ggc3RhdGlzdGljIGJhc2VkIG9uIHRoZSBtZWRpYW4uDQoNCiphbHBoYSogTm9taW5hbCBUeXBlIEkgZXJyb3IgcmF0ZQ==