Start Using the neg.twocors Function

From the negligible R package


Test for Evaluating Negligible Effects of Two Independent or Dependent Correlation Coefficients: Based on Counsell & Cribbie (2015)

Introduction

Goal

This function evaluates whether the difference between two correlation coefficients can be considered statistically and practically negligible according to a predefined interval. i.e., minimally meaningful effect size (MMES)/smallest effect size of interest (SESOI). The effect size tested is the difference between two correlation coefficients (i.e., r1 - r2).

Background

Unlike the most common null hypothesis significance tests looking to detect a difference or the existence of an effect statistically different than zero, in negligible effect testing, the hypotheses are flipped: In essence, \(H_0\) states that the effect is non-negligible, whereas \(H_1\) states that the effect is in fact statistically and practically negligible.

The statistical tests are based on Anderson-Hauck (1983) and Schuirmann’s (1987) Two One-Sided Test (TOST) equivalence testing procedures; namely addressing the question of whether the estimated effect size (and its associated uncertainty) of a difference between two correlation coefficients (i.e., \(r_1\) and \(r_2\)) is smaller than the what the user defines as negligible effect size. Defining what is considered negligible effect is done by specifying the negligible (equivalence) interval: its upper (eiu) and lower (eil) bounds.

The negligible (equivalence) interval should be set based on the context of the research. Because the two correlations (and, therefore their difference) are in standardized units, setting eil and eiu is a matter of determining what is the smallest difference between the two correlations that can be considered of practical significance. For example, if the user determines that the smallest effect of interest is 0.1 – that is, any difference between the two correlation coefficient larger than 0.1 is meaningful in this context - then eil will be set to eil = -0.1 and eiu = 0.1. Therefore, any observable difference that is larger than -0.1 and smaller than 0.1, will be considered practically negligible.

Instructions

There are two main approaches to using neg.twocors:

  • The first (and more recommended) is by inserting a dataset (with the data = argument) into the function. If the user/s have access to the dataset, they should use the following set of arguments:
    • data = a data.frame or matrix which includes the variables in \(r_1\) and \(r_2\)
    • r1v1 = the name of the 1st variable included in the 1st correlation coefficient (r1, variable 1)
    • r1v2 = the name of the 2nd variable included in the 1st correlation coefficient (r1, variable 2)
    • r2v1 = the name of the 1st variable included in the 2nd correlation coefficient (r2, variable 1)
    • r2v2 =the name of the 2nd variable included in the 2st correlation coefficient (r2, variable 2)
    • dep = (if applicable) are the correlation coefficients dependent (overlapping)?
    • bootstrap = (optional) logical, default is TRUE, incorporating bootstrapping when calculating regression coefficients, SE, and CIs
    • nboot = (optional) 1000 is the default. indicate if other number of bootstrapping iterations is desired
    • seed = (optional) to reproduce previous analyses using bootstrapping, the user can set their seed of choice
  • This function also accommodates cases where no dataset is available. In this case, users should use the following set of arguments instead:
    • r1 = entered 1st correlation coefficient manually, without a dataset
    • n1 = entered sample size associated with r1 manually, without a dataset
    • r2 = entered 2nd correlation coefficient manually, without a dataset
    • n2 = entered sample size associated with r2 manually, without a dataset
    • r3 = (if applicable). if the correlation coefficients are dependent and no datasets were entered, specify the correlation between the two, non-intersecting variables (e.g. if \(r_1\) = \(r_{12}\) and \(r_2\) = \(r_{13}\), then \(r_3\) = \(r_{23}\))

In either situation, users must specify the negligible interval bounds (eiu = and eil =).

Other optional arguments and features include:

  • alpha = desired alpha level, defualt is .05
  • test = AH is the default based on recommendation in Counsell & Cribbie (2015), TOST is an additional (albeit, more conservative) option.
  • plots = logical, plotting the results. TRUE is set as default
  • saveplots = FALSE for no, png and jpeg for different formats

Independent vs. Dependent Correlation Coefficients

This function accommodates both independent and dependent correlations. A user might want to compare two independent correlations. For example, the correlation between \(X\) and \(Y\) in one group (e.g., Control group; \(r_{XYC}\)) with the correlation between X and Y in a different, independent group (e.g., Treatment group; \(r_{XYT}\)). The ‘independent correlations’ setting (i.e., dep = FALSE) is the default in this function. However, in other cases, a user might want to compare two dependent correlation coefficients. That is, the two correlations share a common variable (i.e., same variable values). For example, the correlation between \(X\) and \(Y\) in one group (e.g., Treatment group; \(r_{XYT}\)) with the correlation between \(X\) and \(B\) in the same group (e.g., Treatment group; \(r_{XBT}\)). Because values in variable \(X\) are shared among the two correlations, the two correlations (e.g., \(r_{XYT}\) and \(r_{XBT}\)) are not independent from one another, but, in fact, dependent.

To compare two dependent correlation coefficients, users need only to specify dep = TRUE. **If no dataset is entered into the function, users should also use the argument r3 =, which will hold the correlation between the two non-shared variables. In the example above (i.e., \(r_{XYT}\) and \(r_{XBT}\)), the two non-shared variables are \(Y\) and \(B\). In this case, \(r_3 = r_{YBT}\). If dep = TRUE is entered into the function, test statistics and p*-values will be calculated differently to account for the shared variable. The negligible testing methods for comparing dependent correlations in this function are based on Williams’s (1959) modification to Hotelling’s (1931) test for comparing overlapping dependent correlations. For more details see Counsell and Cribbie (2015).

Applied Examples

Example 1A: Data available, Independent Coefficients

Say you want to assess whether the difference between two independent correlation coefficients is negligible. The first coefficient depicts the correlation between Automatic Thoughts (labeled atqpost.total, the first variable in the first correlation; r1v1) and Oriented Perfectionism (labeled mpshfpost.oop, the second variable in the first correlation; r1v2). Their correlation is \(r_1 = 0.224\). The second coefficient depicts the correlation between Concern Over Mistakes (labeled mpsfpost.cm, the first variable in the second correlation; r1v2) and Depression (labeled cesdpost.total, the second variable in the second correlation; r2v2). Their correlation is \(r_2 = 0.517\).

Let’s consider the equivalence interval to be [-.15, .15]. Thus, we will set eil = -.15 and eiu = .15.

Finally, because the two coefficients are independent, we will set dep = FALSE.

Putting It All Together (when data is available; independent coefficients)

library(negligible) # load the package

neg.twocors(data=perfectionism,
            r1v1=atqpost.total, # Automatic Thoughts Questionnaire
            r1v2=mpshfpost.oop, # Oriented Perfectionism
            
            r2v1=mpsfpost.cm, # Concern Over Mistakes 
            r2v2=cesdpost.total, # CESD Depression Scale
            eiu=.15, # upper bound of SESOI (standardized) 
            eil=-.15,  # lower bound of SESOI (standardized)
            seed = 123,
            dep=FALSE) # correlation coefficients are NOT dependent


Test for Evaluating Negligible Difference Between Two Correlation Coefficients 

*** Comparison of Independent Correlation Coefficients ***

Correlation coefficients:
 Variables: atqpost.total & mpshfpost.oop, r1 = 0.224
 Variables: mpsfpost.cm & cesdpost.total, r2 = 0.517
**********************

Correlation coefficients' difference and confidence interval using 1000 bootstrap iterations (seed=123):
 r1-r2 = -0.293, 95% CI: [-0.54, -0.055]
 std. error = 0.133
**********************

AH-ρ: Counsell-Cribbie Test for Comparing Two Independent Correlation Coefficients
Equivalence Interval: Lower = -0.15, Upper = 0.15
p value = 0.858
NHST Decision: The null hypothesis that the difference between the two correlation coefficients is non-negligible (i.e., beyond the equivalence interval), was NOT rejected: There is insufficient evidence that the difference between the two correlation coefficients is negligible in the population. Be sure to interpret the magnitude (and precision) of the effect size.


*Note that NHST decisions using the AH-ρ and AH-ρ procedures may not match KTOST-ρ and TOST-ρ-D results or the Symmetric CI Approach at 100*(1-2α)% illustrated in the plot. 

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

Proportional Distance 

Proportional distance: -1.955 
95% confidence interval for the proportional distance: (-3.603, -0.369)

*Note that the confidence interval for the proportional distance may not be precise with small sample sizes 
******************* 

In Example 1A above, we used the neg.twocors function with access to the raw data.

The results were NOT statistically significant, \(r_1 - r_2 = -0.293, \ 95\% \ CI \ [-0.528, -0.054], \ p = 0.858\) indicating that the null hypothesis that the difference between the two correlation coefficients is non-negligible (i.e., beyond the equivalence interval), was NOT rejected. Thus, there is insufficient evidence that the difference between the two correlation coefficients is negligible in the population.

Example 1B: Data Available, Dependent Coefficients

Now, say you want to evaluate the difference between two correlation coefficients, similar to Example 1A. However, unlike in the previous example, here, the two correlations are dependent because the data yielding both coefficients use the same varible: the first coefficient depicts the correlation between Anxiety (labeled baipre.total) at pretest and Depression at pretest (labeled cesdpre.total). The second coefficient depicts the association of the same variable of Anxiety at pretest with another variable, Automatic Thoughts at pretest (atqpre.total),

Let’s consider the same equivalence interval: eil = -1.5 and eiu = 1.5.

Importantly, because the two coefficients are dependent, we will set dep = TRUE.

Putting It All Together (when data is available; dependent variables)

library(negligible) # load the package

neg.twocors(data = perfectionism,
            r1v1 = baipre.total, # Anxiety
            r1v2 = cesdpre.total, # Depression
            r2v1 = baipre.total,  # Same anxiety
            r2v2 = atqpre.total, # Automatic thoughts
            eiu = .15, # upper bound of SESOI (standardized) 
            eil= -.15,  # lower bound of SESOI (standardized)
            seed = 123,
            dep=T) # correlation coefficients are NOT dependent


Test for Evaluating Negligible Difference Between Two Correlation Coefficients 

*** Comparison of Dependent Correlation Coefficients ***

Correlation coefficients:
 Variables: baipre.total & cesdpre.total, r1 = 0.702
 Variables: baipre.total & atqpre.total, r2 = 0.661
 r3 = 0.8183588
**********************

Correlation coefficients' difference and confidence interval using 1000 bootstrap iterations (seed=123):
 r1-r2 = 0.042, 95% CI: [-0.12, 0.206]
 std. error = 0.084
**********************

AH-ρ-D: Counsell-Cribbie Test for Comparing Two Dependent Correlation Coefficients
Equivalence Interval: Lower = -0.15, Upper = 0.15
p value < 0.001
NHST Decision: The null hypothesis that the difference between the two correlation coefficients is non-negligible (i.e., beyond the specified equivalence interval), can be rejected. A negligible difference between the two correlation coefficients in the population can be concluded. Be sure to interpret the magnitude (and precision) of the effect size.


*Note that NHST decisions using the AH-ρ and AH-ρ procedures may not match KTOST-ρ and TOST-ρ-D results or the Symmetric CI Approach at 100*(1-2α)% illustrated in the plot. 

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

Proportional Distance 

Proportional distance: 0.277 
95% confidence interval for the proportional distance: (-0.799, 1.375)

*Note that the confidence interval for the proportional distance may not be precise with small sample sizes 
******************* 

Here, the difference between the two correlation coefficients is statistically and practically negligible, \(r_1 - r_2 = 0.042, \ 95 \% \ CI \ [-0.12, 0.206], \ p < 0.001\) suggesting that the null hypothesis that the difference between the two correlation coefficients is non-negligible (i.e., beyond the specified equivalence interval), can be rejected. A negligible difference between the two correlation coefficients in the population can be concluded!

Example 2: No Dataset Available

Suppose you do not have access to the full data. Still, you might look at the reported results in a research article and gather the required details: Say you observe that \(r_1 = 0.22\) with a sample size of \(n=825\), \(r_2 = 0.18\) with a sample size of \(n=789\).

Let’s consider the same equivalence interval: eil = -.15 and eiu = .15.

Putting It All Together (when data is NOT available)

neg.twocors(r1=0.22, # first coefficient
            n1=825, # sample size for 1st coefficient
            r2=0.18, # second coefficient
            n2=789, # sample size for 2nd coefficient
            eiu=.15,
            eil=-0.15, 
            dep=FALSE)


Test for Evaluating Negligible Difference Between Two Correlation Coefficients 

*** Comparison of Independent Correlation Coefficients ***

Correlation coefficients:
 r1 = 0.22
 r2 = 0.18
**********************

Correlation coefficients' raw difference:
 r1-r2 =0.04, 95% CI [-0.039, 0.119]
 std. error = 0.048
**********************

AH-ρ: Counsell-Cribbie Test for Comparing Two Independent Correlation Coefficients
Equivalence Interval: Lower = -0.15, Upper = 0.15
p value = 0.011
NHST Decision: The null hypothesis that the difference between the two correlation coefficients is non-negligible (i.e., beyond the specified equivalence interval), can be rejected. A negligible difference between the two correlation coefficients in the population can be concluded. Be sure to interpret the magnitude (and precision) of the effect size.


*Note that NHST decisions using the AH-ρ and AH-ρ procedures may not match KTOST-ρ and TOST-ρ-D results or the Symmetric CI Approach at 100*(1-2α)% illustrated in the plot. 

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

Proportional Distance 

Proportional distance: 0.267 
95% confidence interval for the proportional distance: (-0.258, 0.791)

*Note that the confidence interval for the proportional distance may not be precise with small sample sizes 
******************* 

Results from the negligible effect testing indicate that the difference between the two correlation coefficients is indeed negligible, \(r_1 - r_2 = 0.04, \ 95 \% \ CI \ [-0.039, 0.119], \ p = 0.011\) suggesting that the null hypothesis that the difference between the two correlation coefficients is non-negligible (i.e., beyond the specified equivalence interval), can be rejected. A negligible difference between the two correlation coefficients in the population can be concluded!

LS0tDQp0aXRsZTogIlN0YXJ0IFVzaW5nIHRoZSBgbmVnLnR3b2NvcnNgIEZ1bmN0aW9uIg0Kc3VidGl0bGU6IHwgDQogICAgRnJvbSB0aGUgW2BuZWdsaWdpYmxlYF0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL25lZ2xpZ2libGUvaW5kZXguaHRtbCkgUiBwYWNrYWdlIVtdKEc6L015IERyaXZlL1Jlc2VhcmNoL0NyaWJiaWUgTGFiL25lZ2xpZ2libGUgVmlnbmV0dGVzL1RlbXBsYXRlL25lZy5sb2dvLnBuZyl7d2lkdGg9MTAlfSAgDQphdXRob3I6ICJbVWRpIEFsdGVyXSINCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSlgIg0Kb3V0cHV0Og0KICBybWRmb3JtYXRzOjpyb2JvYm9vazoNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQotLS0NCg0KYGBge3Igc2V0dXAsIGVjaG89RkFMU0UsIGNhY2hlPUZBTFNFLCBtZXNzYWdlcz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNpbnN0YWxsLnBhY2thZ2VzKCJybWRmb3JtYXRzIikNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KHJtZGZvcm1hdHMsIHdhcm4uY29uZmxpY3RzPUZBTFNFKSkNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KGtuaXRyLCB3YXJuLmNvbmZsaWN0cz1GQUxTRSkpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeSh0aWR5dmVyc2UsIHdhcm4uY29uZmxpY3RzPUZBTFNFKSkNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KHBsb3RseSwgd2Fybi5jb25mbGljdHM9RkFMU0UpKQ0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkocmVhZHhsLCB3YXJuLmNvbmZsaWN0cz1GQUxTRSkpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShwbG90bHksIHdhcm4uY29uZmxpY3RzPUZBTFNFKSkNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KE1ldEJyZXdlciwgd2Fybi5jb25mbGljdHM9RkFMU0UpKQ0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkoZ2dhbmltYXRlLCB3YXJuLmNvbmZsaWN0cz1GQUxTRSkpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShkcGx5ciwgd2Fybi5jb25mbGljdHM9RkFMU0UpKQ0KDQojIyBHbG9iYWwgb3B0aW9ucw0Kb3B0aW9ucyhtYXgucHJpbnQ9Ijc1IikNCm9wdHNfY2h1bmskc2V0KGVjaG89VFJVRSwNCgkgICAgICAgICAgICAgY2FjaGU9VFJVRSwNCiAgICAgICAgICAgICAgIHByb21wdD1GQUxTRSwNCiAgICAgICAgICAgICAgIGNvbW1lbnQ9TkEsDQogICAgICAgICAgICAgICBtZXNzYWdlPUZBTFNFLA0KICAgICAgICAgICAgICAgd2FybmluZz1GQUxTRSkNCm9wdHNfa25pdCRzZXQod2lkdGg9NzUpDQpgYGANCg0KPGJyLz4NCg0KVGVzdCBmb3IgRXZhbHVhdGluZyBOZWdsaWdpYmxlIEVmZmVjdHMgb2YgVHdvIEluZGVwZW5kZW50IG9yIERlcGVuZGVudA0KQ29ycmVsYXRpb24gQ29lZmZpY2llbnRzOiBCYXNlZCBvbiBDb3Vuc2VsbCAmIENyaWJiaWUgKDIwMTUpDQoNCiMgSW50cm9kdWN0aW9uDQoNCiMjIEdvYWwNCg0KVGhpcyBmdW5jdGlvbiBldmFsdWF0ZXMgd2hldGhlciB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHR3byBjb3JyZWxhdGlvbg0KY29lZmZpY2llbnRzIGNhbiBiZSBjb25zaWRlcmVkIHN0YXRpc3RpY2FsbHkgYW5kIHByYWN0aWNhbGx5IG5lZ2xpZ2libGUNCmFjY29yZGluZyB0byBhIHByZWRlZmluZWQgaW50ZXJ2YWwuIGkuZS4sIG1pbmltYWxseSBtZWFuaW5nZnVsIGVmZmVjdA0Kc2l6ZSAoTU1FUykvc21hbGxlc3QgZWZmZWN0IHNpemUgb2YgaW50ZXJlc3QgKFNFU09JKS4gVGhlIGVmZmVjdCBzaXplDQp0ZXN0ZWQgaXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gY29ycmVsYXRpb24gY29lZmZpY2llbnRzIChpLmUuLA0KcjEgLSByMikuDQoNCiMjIEJhY2tncm91bmQNCg0KVW5saWtlIHRoZSBtb3N0IGNvbW1vbiBudWxsIGh5cG90aGVzaXMgc2lnbmlmaWNhbmNlIHRlc3RzIGxvb2tpbmcgdG8NCmRldGVjdCBhIGRpZmZlcmVuY2Ugb3IgdGhlIGV4aXN0ZW5jZSBvZiBhbiBlZmZlY3Qgc3RhdGlzdGljYWxseQ0KZGlmZmVyZW50IHRoYW4gemVybywgaW4gbmVnbGlnaWJsZSBlZmZlY3QgdGVzdGluZywgdGhlIGh5cG90aGVzZXMgYXJlDQpmbGlwcGVkOiBJbiBlc3NlbmNlLCAkSF8wJCBzdGF0ZXMgdGhhdCB0aGUgZWZmZWN0IGlzIG5vbi1uZWdsaWdpYmxlLA0Kd2hlcmVhcyAkSF8xJCBzdGF0ZXMgdGhhdCB0aGUgZWZmZWN0IGlzIGluIGZhY3Qgc3RhdGlzdGljYWxseSBhbmQNCnByYWN0aWNhbGx5IG5lZ2xpZ2libGUuDQoNClRoZSBzdGF0aXN0aWNhbCB0ZXN0cyBhcmUgYmFzZWQgb24gQW5kZXJzb24tSGF1Y2sgKDE5ODMpIGFuZA0KU2NodWlybWFubidzICgxOTg3KSBUd28gT25lLVNpZGVkIFRlc3QgKFRPU1QpIGVxdWl2YWxlbmNlIHRlc3RpbmcNCnByb2NlZHVyZXM7IG5hbWVseSBhZGRyZXNzaW5nIHRoZSBxdWVzdGlvbiBvZiB3aGV0aGVyIHRoZSBlc3RpbWF0ZWQNCmVmZmVjdCBzaXplIChhbmQgaXRzIGFzc29jaWF0ZWQgdW5jZXJ0YWludHkpIG9mIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIHR3bw0KY29ycmVsYXRpb24gY29lZmZpY2llbnRzIChpLmUuLCAkcl8xJCBhbmQgJHJfMiQpIGlzIHNtYWxsZXIgdGhhbiB0aGUNCndoYXQgdGhlIHVzZXIgZGVmaW5lcyBhcyBuZWdsaWdpYmxlIGVmZmVjdCBzaXplLiBEZWZpbmluZyB3aGF0IGlzDQpjb25zaWRlcmVkIG5lZ2xpZ2libGUgZWZmZWN0IGlzIGRvbmUgYnkgc3BlY2lmeWluZyB0aGUgbmVnbGlnaWJsZQ0KKGVxdWl2YWxlbmNlKSBpbnRlcnZhbDogaXRzIHVwcGVyIChgZWl1YCkgYW5kIGxvd2VyIChgZWlsYCkgYm91bmRzLg0KDQpUaGUgbmVnbGlnaWJsZSAoZXF1aXZhbGVuY2UpIGludGVydmFsIHNob3VsZCBiZSBzZXQgYmFzZWQgb24gdGhlIGNvbnRleHQNCm9mIHRoZSByZXNlYXJjaC4gQmVjYXVzZSB0aGUgdHdvIGNvcnJlbGF0aW9ucyAoYW5kLCB0aGVyZWZvcmUgdGhlaXINCmRpZmZlcmVuY2UpIGFyZSBpbiBzdGFuZGFyZGl6ZWQgdW5pdHMsIHNldHRpbmcgYGVpbGAgYW5kIGBlaXVgIGlzIGENCm1hdHRlciBvZiBkZXRlcm1pbmluZyB3aGF0IGlzIHRoZSBzbWFsbGVzdCBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3bw0KY29ycmVsYXRpb25zIHRoYXQgY2FuIGJlIGNvbnNpZGVyZWQgb2YgcHJhY3RpY2FsIHNpZ25pZmljYW5jZS4gRm9yDQpleGFtcGxlLCBpZiB0aGUgdXNlciBkZXRlcm1pbmVzIHRoYXQgdGhlIHNtYWxsZXN0IGVmZmVjdCBvZiBpbnRlcmVzdCBpcw0KMC4xIC0tIHRoYXQgaXMsIGFueSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3byBjb3JyZWxhdGlvbiBjb2VmZmljaWVudA0KbGFyZ2VyIHRoYW4gMC4xIGlzIG1lYW5pbmdmdWwgaW4gdGhpcyBjb250ZXh0IC0gdGhlbiBgZWlsYCB3aWxsIGJlIHNldA0KdG8gYGVpbCA9IC0wLjFgIGFuZCBgZWl1ID0gMC4xYC4gVGhlcmVmb3JlLCBhbnkgb2JzZXJ2YWJsZSBkaWZmZXJlbmNlDQp0aGF0IGlzIGxhcmdlciB0aGFuIC0wLjEgKmFuZCogc21hbGxlciB0aGFuIDAuMSwgd2lsbCBiZSBjb25zaWRlcmVkDQpwcmFjdGljYWxseSBuZWdsaWdpYmxlLg0KDQojIEluc3RydWN0aW9ucw0KDQpUaGVyZSBhcmUgdHdvIG1haW4gYXBwcm9hY2hlcyB0byB1c2luZyBgbmVnLnR3b2NvcnNgOg0KDQotICAgVGhlIGZpcnN0IChhbmQgbW9yZSByZWNvbW1lbmRlZCkgaXMgYnkgaW5zZXJ0aW5nIGEgZGF0YXNldCAod2l0aCB0aGUNCiAgICBgZGF0YSA9YCBhcmd1bWVudCkgaW50byB0aGUgZnVuY3Rpb24uIElmIHRoZSB1c2VyL3MgaGF2ZSBhY2Nlc3MgdG8NCiAgICB0aGUgZGF0YXNldCwgdGhleSBzaG91bGQgdXNlIHRoZSBmb2xsb3dpbmcgc2V0IG9mIGFyZ3VtZW50czoNCiAgICAtICAgYGRhdGEgPWAgYSBkYXRhLmZyYW1lIG9yIG1hdHJpeCB3aGljaCBpbmNsdWRlcyB0aGUgdmFyaWFibGVzIGluDQogICAgICAgICRyXzEkIGFuZCAkcl8yJA0KICAgIC0gICBgcjF2MSA9YCB0aGUgbmFtZSBvZiB0aGUgMXN0IHZhcmlhYmxlIGluY2x1ZGVkIGluIHRoZSAxc3QNCiAgICAgICAgY29ycmVsYXRpb24gY29lZmZpY2llbnQgKHIxLCB2YXJpYWJsZSAxKQ0KICAgIC0gICBgcjF2MiA9YCB0aGUgbmFtZSBvZiB0aGUgMm5kIHZhcmlhYmxlIGluY2x1ZGVkIGluIHRoZSAxc3QNCiAgICAgICAgY29ycmVsYXRpb24gY29lZmZpY2llbnQgKHIxLCB2YXJpYWJsZSAyKQ0KICAgIC0gICBgcjJ2MSA9YCB0aGUgbmFtZSBvZiB0aGUgMXN0IHZhcmlhYmxlIGluY2x1ZGVkIGluIHRoZSAybmQNCiAgICAgICAgY29ycmVsYXRpb24gY29lZmZpY2llbnQgKHIyLCB2YXJpYWJsZSAxKQ0KICAgIC0gICBgcjJ2MiA9YHRoZSBuYW1lIG9mIHRoZSAybmQgdmFyaWFibGUgaW5jbHVkZWQgaW4gdGhlIDJzdA0KICAgICAgICBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCAocjIsIHZhcmlhYmxlIDIpDQogICAgLSAgIGBkZXAgPWAgKGlmIGFwcGxpY2FibGUpIGFyZSB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnRzDQogICAgICAgIGRlcGVuZGVudCAob3ZlcmxhcHBpbmcpPw0KICAgIC0gICBgYm9vdHN0cmFwID1gIChvcHRpb25hbCkgbG9naWNhbCwgZGVmYXVsdCBpcyBgVFJVRWAsDQogICAgICAgIGluY29ycG9yYXRpbmcgYm9vdHN0cmFwcGluZyB3aGVuIGNhbGN1bGF0aW5nIHJlZ3Jlc3Npb24NCiAgICAgICAgY29lZmZpY2llbnRzLCBTRSwgYW5kIENJcw0KICAgIC0gICBgbmJvb3QgPWAgKG9wdGlvbmFsKSAxMDAwIGlzIHRoZSBkZWZhdWx0LiBpbmRpY2F0ZSBpZiBvdGhlcg0KICAgICAgICBudW1iZXIgb2YgYm9vdHN0cmFwcGluZyBpdGVyYXRpb25zIGlzIGRlc2lyZWQNCiAgICAtICAgYHNlZWQgPWAgKG9wdGlvbmFsKSB0byByZXByb2R1Y2UgcHJldmlvdXMgYW5hbHlzZXMgdXNpbmcNCiAgICAgICAgYm9vdHN0cmFwcGluZywgdGhlIHVzZXIgY2FuIHNldCB0aGVpciBzZWVkIG9mIGNob2ljZQ0KICAgICAgICANCiAgICAgICAgDQogICAgICAgIA0KICAgICAgICANCi0gICBUaGlzIGZ1bmN0aW9uIGFsc28gYWNjb21tb2RhdGVzIGNhc2VzIHdoZXJlIG5vIGRhdGFzZXQgaXMgYXZhaWxhYmxlLg0KICAgIEluIHRoaXMgY2FzZSwgdXNlcnMgc2hvdWxkIHVzZSB0aGUgZm9sbG93aW5nIHNldCBvZiBhcmd1bWVudHMNCiAgICBpbnN0ZWFkOg0KICAgIC0gICBgcjEgPWAgZW50ZXJlZCAxc3QgY29ycmVsYXRpb24gY29lZmZpY2llbnQgbWFudWFsbHksIHdpdGhvdXQgYSBkYXRhc2V0DQogICAgLSAgIGBuMSA9YCBlbnRlcmVkIHNhbXBsZSBzaXplIGFzc29jaWF0ZWQgd2l0aCByMSBtYW51YWxseSwgd2l0aG91dCBhIGRhdGFzZXQNCiAgICAtICAgYHIyID1gIGVudGVyZWQgMm5kIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IG1hbnVhbGx5LCB3aXRob3V0IGEgZGF0YXNldA0KICAgIC0gICBgbjIgPWAgZW50ZXJlZCBzYW1wbGUgc2l6ZSBhc3NvY2lhdGVkIHdpdGggcjIgbWFudWFsbHksIHdpdGhvdXQgYSBkYXRhc2V0DQogICAgLSAgIGByMyA9YCAoaWYgYXBwbGljYWJsZSkuIGlmIHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgYXJlIGRlcGVuZGVudCBhbmQgbm8gZGF0YXNldHMgd2VyZSBlbnRlcmVkLCBzcGVjaWZ5IHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSB0d28sIG5vbi1pbnRlcnNlY3RpbmcgdmFyaWFibGVzIChlLmcuIGlmICRyXzEkID0gJHJfezEyfSQgYW5kICRyXzIkID0gJHJfezEzfSQsIHRoZW4gJHJfMyQgPSAkcl97MjN9JCkNCiAgICAgDQoNCkluIGVpdGhlciBzaXR1YXRpb24sIHVzZXJzIG11c3Qgc3BlY2lmeSB0aGUgbmVnbGlnaWJsZSBpbnRlcnZhbCBib3VuZHMgKGBlaXUgPWAgYW5kIGBlaWwgPWApLiANCiAgICAgICAgDQpPdGhlciBvcHRpb25hbCBhcmd1bWVudHMgYW5kIGZlYXR1cmVzIGluY2x1ZGU6IA0KDQogLSAgYGFscGhhID1gIGRlc2lyZWQgYWxwaGEgbGV2ZWwsIGRlZnVhbHQgaXMgLjA1DQogLSAgYHRlc3QgPWAgYEFIYCBpcyB0aGUgZGVmYXVsdCBiYXNlZCBvbiByZWNvbW1lbmRhdGlvbiBpbiBDb3Vuc2VsbCAmIENyaWJiaWUgKDIwMTUpLCBgVE9TVGAgaXMgYW4gYWRkaXRpb25hbCAoYWxiZWl0LCBtb3JlIGNvbnNlcnZhdGl2ZSkgb3B0aW9uLg0KIC0gIGBwbG90cyA9YCBsb2dpY2FsLCBwbG90dGluZyB0aGUgcmVzdWx0cy4gYFRSVUVgIGlzIHNldCBhcyBkZWZhdWx0DQogLSAgYHNhdmVwbG90cyA9YCBgRkFMU0VgIGZvciBubywgYHBuZ2AgYW5kIGBqcGVnYCBmb3IgZGlmZmVyZW50IGZvcm1hdHMNCiAgICAgICAgDQojIyBJbmRlcGVuZGVudCB2cy4gRGVwZW5kZW50IENvcnJlbGF0aW9uIENvZWZmaWNpZW50cw0KDQoNClRoaXMgZnVuY3Rpb24gYWNjb21tb2RhdGVzIGJvdGggaW5kZXBlbmRlbnQgYW5kIGRlcGVuZGVudCBjb3JyZWxhdGlvbnMuIEEgdXNlciBtaWdodCB3YW50IHRvIGNvbXBhcmUgdHdvIGluZGVwZW5kZW50IGNvcnJlbGF0aW9ucy4gRm9yIGV4YW1wbGUsIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuICRYJCBhbmQgJFkkIGluIG9uZSBncm91cCAoZS5nLiwgQ29udHJvbCBncm91cDsgJHJfe1hZQ30kKSB3aXRoIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIFggYW5kIFkgaW4gYSBkaWZmZXJlbnQsIGluZGVwZW5kZW50IGdyb3VwIChlLmcuLCBUcmVhdG1lbnQgZ3JvdXA7ICRyX3tYWVR9JCkuIFRoZSAnaW5kZXBlbmRlbnQgY29ycmVsYXRpb25zJyBzZXR0aW5nIChpLmUuLCBgZGVwID0gRkFMU0VgKSBpcyB0aGUgZGVmYXVsdCBpbiB0aGlzIGZ1bmN0aW9uLiBIb3dldmVyLCBpbiBvdGhlciBjYXNlcywgYSB1c2VyIG1pZ2h0IHdhbnQgdG8gY29tcGFyZSB0d28gZGVwZW5kZW50IGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cy4gVGhhdCBpcywgdGhlIHR3byBjb3JyZWxhdGlvbnMgc2hhcmUgYSBjb21tb24gdmFyaWFibGUgKGkuZS4sIHNhbWUgdmFyaWFibGUgdmFsdWVzKS4gRm9yIGV4YW1wbGUsIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuICRYJCBhbmQgJFkkIGluIG9uZSBncm91cCAoZS5nLiwgVHJlYXRtZW50IGdyb3VwOyAkcl97WFlUfSQpIHdpdGggdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gJFgkIGFuZCAkQiQgaW4gdGhlIHNhbWUgZ3JvdXAgKGUuZy4sIFRyZWF0bWVudCBncm91cDsgJHJfe1hCVH0kKS4gQmVjYXVzZSB2YWx1ZXMgaW4gdmFyaWFibGUgJFgkIGFyZSBzaGFyZWQgYW1vbmcgdGhlIHR3byBjb3JyZWxhdGlvbnMsIHRoZSB0d28gY29ycmVsYXRpb25zIChlLmcuLCAkcl97WFlUfSQgYW5kICRyX3tYQlR9JCkgYXJlIG5vdCBpbmRlcGVuZGVudCBmcm9tIG9uZSBhbm90aGVyLCBidXQsIGluIGZhY3QsIGRlcGVuZGVudC4gDQoNCg0KDQpUbyBjb21wYXJlIHR3byBkZXBlbmRlbnQgY29ycmVsYXRpb24gY29lZmZpY2llbnRzLCB1c2VycyBuZWVkIG9ubHkgdG8gc3BlY2lmeSBgZGVwID0gVFJVRWAuICoqSWYgbm8gZGF0YXNldCBpcyBlbnRlcmVkIGludG8gdGhlIGZ1bmN0aW9uLCB1c2VycyBzaG91bGQgYWxzbyB1c2UgdGhlIGFyZ3VtZW50IGByMyA9YCwgd2hpY2ggd2lsbCBob2xkIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSB0d28gbm9uLXNoYXJlZCB2YXJpYWJsZXMqLiBJbiB0aGUgZXhhbXBsZSBhYm92ZSAoaS5lLiwgJHJfe1hZVH0kIGFuZCAkcl97WEJUfSQpLCB0aGUgdHdvIG5vbi1zaGFyZWQgdmFyaWFibGVzIGFyZSAkWSQgYW5kICRCJC4gSW4gdGhpcyBjYXNlLCAkcl8zID0gcl97WUJUfSQuIElmIGBkZXAgPSBUUlVFYCBpcyBlbnRlcmVkIGludG8gdGhlIGZ1bmN0aW9uLCB0ZXN0IHN0YXRpc3RpY3MgYW5kICpwKi12YWx1ZXMgd2lsbCBiZSBjYWxjdWxhdGVkIGRpZmZlcmVudGx5IHRvIGFjY291bnQgZm9yIHRoZSBzaGFyZWQgdmFyaWFibGUuIFRoZSBuZWdsaWdpYmxlIHRlc3RpbmcgbWV0aG9kcyBmb3IgY29tcGFyaW5nIGRlcGVuZGVudCBjb3JyZWxhdGlvbnMgaW4gdGhpcyBmdW5jdGlvbiBhcmUgYmFzZWQgb24gV2lsbGlhbXMncyAoMTk1OSkgbW9kaWZpY2F0aW9uIHRvIEhvdGVsbGluZydzICgxOTMxKSB0ZXN0IGZvciBjb21wYXJpbmcgb3ZlcmxhcHBpbmcgZGVwZW5kZW50IGNvcnJlbGF0aW9ucy4gRm9yIG1vcmUgZGV0YWlscyBzZWUgQ291bnNlbGwgYW5kIENyaWJiaWUgKDIwMTUpLiANCg0KDQojIEFwcGxpZWQgRXhhbXBsZXMNCg0KDQoNCiMjIEV4YW1wbGUgMUE6IERhdGEgYXZhaWxhYmxlLCBJbmRlcGVuZGVudCBDb2VmZmljaWVudHMNCg0KDQoNClNheSB5b3Ugd2FudCB0byBhc3Nlc3Mgd2hldGhlciB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHR3byBpbmRlcGVuZGVudCBjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgaXMgbmVnbGlnaWJsZS4gVGhlIGZpcnN0IGNvZWZmaWNpZW50IGRlcGljdHMgdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gQXV0b21hdGljIFRob3VnaHRzIChsYWJlbGVkIGBhdHFwb3N0LnRvdGFsYCwgdGhlIGZpcnN0IHZhcmlhYmxlIGluIHRoZSBmaXJzdCBjb3JyZWxhdGlvbjsgYHIxdjFgKSBhbmQgT3JpZW50ZWQgUGVyZmVjdGlvbmlzbSAobGFiZWxlZCBgbXBzaGZwb3N0Lm9vcGAsIHRoZSBzZWNvbmQgdmFyaWFibGUgaW4gdGhlIGZpcnN0IGNvcnJlbGF0aW9uOyBgcjF2MmApLiBUaGVpciBjb3JyZWxhdGlvbiBpcyAkcl8xID0gMC4yMjQkLiBUaGUgc2Vjb25kIGNvZWZmaWNpZW50IGRlcGljdHMgdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gQ29uY2VybiBPdmVyIE1pc3Rha2VzIChsYWJlbGVkIGBtcHNmcG9zdC5jbWAsIHRoZSBmaXJzdCB2YXJpYWJsZSBpbiB0aGUgc2Vjb25kIGNvcnJlbGF0aW9uOyBgcjF2MmApIGFuZCBEZXByZXNzaW9uIChsYWJlbGVkIGBjZXNkcG9zdC50b3RhbGAsIHRoZSBzZWNvbmQgdmFyaWFibGUgaW4gdGhlIHNlY29uZCBjb3JyZWxhdGlvbjsgYHIydjJgKS4gVGhlaXIgY29ycmVsYXRpb24gaXMgJHJfMiA9IDAuNTE3JC4NCg0KTGV0J3MgY29uc2lkZXIgdGhlIGVxdWl2YWxlbmNlIGludGVydmFsIHRvIGJlIFstLjE1LCAuMTVdLiBUaHVzLCB3ZSB3aWxsIHNldCBgZWlsID0gLS4xNWAgYW5kIGBlaXUgPSAuMTVgLg0KDQpGaW5hbGx5LCBiZWNhdXNlIHRoZSB0d28gY29lZmZpY2llbnRzIGFyZSBpbmRlcGVuZGVudCwgd2Ugd2lsbCBzZXQgYGRlcCA9IEZBTFNFYC4NCg0KDQojIyMgUHV0dGluZyBJdCBBbGwgVG9nZXRoZXIgKHdoZW4gZGF0YSBpcyBhdmFpbGFibGU7IGluZGVwZW5kZW50IGNvZWZmaWNpZW50cykNCg0KDQoNCmBgYHtyfQ0KDQpsaWJyYXJ5KG5lZ2xpZ2libGUpICMgbG9hZCB0aGUgcGFja2FnZQ0KDQpuZWcudHdvY29ycyhkYXRhPXBlcmZlY3Rpb25pc20sDQogICAgICAgICAgICByMXYxPWF0cXBvc3QudG90YWwsICMgQXV0b21hdGljIFRob3VnaHRzIFF1ZXN0aW9ubmFpcmUNCiAgICAgICAgICAgIHIxdjI9bXBzaGZwb3N0Lm9vcCwgIyBPcmllbnRlZCBQZXJmZWN0aW9uaXNtDQogICAgICAgICAgICANCiAgICAgICAgICAgIHIydjE9bXBzZnBvc3QuY20sICMgQ29uY2VybiBPdmVyIE1pc3Rha2VzIA0KICAgICAgICAgICAgcjJ2Mj1jZXNkcG9zdC50b3RhbCwgIyBDRVNEIERlcHJlc3Npb24gU2NhbGUNCiAgICAgICAgICAgIGVpdT0uMTUsICMgdXBwZXIgYm91bmQgb2YgU0VTT0kgKHN0YW5kYXJkaXplZCkgDQogICAgICAgICAgICBlaWw9LS4xNSwgICMgbG93ZXIgYm91bmQgb2YgU0VTT0kgKHN0YW5kYXJkaXplZCkNCiAgICAgICAgICAgIHNlZWQgPSAxMjMsDQogICAgICAgICAgICBkZXA9RkFMU0UpICMgY29ycmVsYXRpb24gY29lZmZpY2llbnRzIGFyZSBOT1QgZGVwZW5kZW50DQoNCg0KYGBgDQoNCkluIEV4YW1wbGUgMUEgYWJvdmUsIHdlIHVzZWQgdGhlIGBuZWcudHdvY29yc2AgZnVuY3Rpb24gd2l0aCBhY2Nlc3MgdG8gdGhlIHJhdyBkYXRhLiANCg0KDQpUaGUgcmVzdWx0cyB3ZXJlIE5PVCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LCAkcl8xIC0gcl8yID0gLTAuMjkzLCBcIDk1XCUgXCBDSSBcICBbLTAuNTI4LCAtMC4wNTRdLCBcIHAgPSAwLjg1OCQgaW5kaWNhdGluZyB0aGF0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gY29ycmVsYXRpb24gY29lZmZpY2llbnRzIGlzIG5vbi1uZWdsaWdpYmxlIChpLmUuLCBiZXlvbmQgdGhlIGVxdWl2YWxlbmNlIGludGVydmFsKSwgd2FzIE5PVCByZWplY3RlZC4gVGh1cywgdGhlcmUgaXMgaW5zdWZmaWNpZW50IGV2aWRlbmNlIHRoYXQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyBpcyBuZWdsaWdpYmxlIGluIHRoZSBwb3B1bGF0aW9uLg0KDQoNCiMjIEV4YW1wbGUgMUI6IERhdGEgQXZhaWxhYmxlLCBEZXBlbmRlbnQgQ29lZmZpY2llbnRzDQoNCg0KTm93LCBzYXkgeW91IHdhbnQgdG8gZXZhbHVhdGUgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gY29ycmVsYXRpb24gY29lZmZpY2llbnRzLCBzaW1pbGFyIHRvIEV4YW1wbGUgMUEuIEhvd2V2ZXIsIHVubGlrZSBpbiB0aGUgcHJldmlvdXMgZXhhbXBsZSwgaGVyZSwgdGhlIHR3byBjb3JyZWxhdGlvbnMgYXJlIGRlcGVuZGVudCBiZWNhdXNlIHRoZSBkYXRhIHlpZWxkaW5nIGJvdGggY29lZmZpY2llbnRzIHVzZSB0aGUgc2FtZSB2YXJpYmxlOiB0aGUgZmlyc3QgY29lZmZpY2llbnQgZGVwaWN0cyB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiBBbnhpZXR5IChsYWJlbGVkIGBiYWlwcmUudG90YWxgKSBhdCBwcmV0ZXN0IGFuZCBEZXByZXNzaW9uIGF0IHByZXRlc3QgKGxhYmVsZWQgYGNlc2RwcmUudG90YWxgKS4gVGhlIHNlY29uZCBjb2VmZmljaWVudCBkZXBpY3RzIHRoZSBhc3NvY2lhdGlvbiBvZiB0aGUgc2FtZSB2YXJpYWJsZSBvZiBBbnhpZXR5IGF0IHByZXRlc3Qgd2l0aCBhbm90aGVyIHZhcmlhYmxlLCBBdXRvbWF0aWMgVGhvdWdodHMgYXQgcHJldGVzdCAoYGF0cXByZS50b3RhbGApLA0KDQoNCkxldCdzIGNvbnNpZGVyIHRoZSBzYW1lIGVxdWl2YWxlbmNlIGludGVydmFsOiBgZWlsID0gLTEuNWAgYW5kIGBlaXUgPSAxLjVgLg0KDQpJbXBvcnRhbnRseSwgYmVjYXVzZSB0aGUgdHdvIGNvZWZmaWNpZW50cyBhcmUgZGVwZW5kZW50LCB3ZSB3aWxsIHNldCBgZGVwID0gVFJVRWAuDQoNCg0KIyMjIFB1dHRpbmcgSXQgQWxsIFRvZ2V0aGVyICh3aGVuIGRhdGEgaXMgYXZhaWxhYmxlOyBkZXBlbmRlbnQgdmFyaWFibGVzKQ0KDQpgYGB7cn0NCg0KbGlicmFyeShuZWdsaWdpYmxlKSAjIGxvYWQgdGhlIHBhY2thZ2UNCg0KbmVnLnR3b2NvcnMoZGF0YSA9IHBlcmZlY3Rpb25pc20sDQogICAgICAgICAgICByMXYxID0gYmFpcHJlLnRvdGFsLCAjIEFueGlldHkNCiAgICAgICAgICAgIHIxdjIgPSBjZXNkcHJlLnRvdGFsLCAjIERlcHJlc3Npb24NCiAgICAgICAgICAgIHIydjEgPSBiYWlwcmUudG90YWwsICAjIFNhbWUgYW54aWV0eQ0KICAgICAgICAgICAgcjJ2MiA9IGF0cXByZS50b3RhbCwgIyBBdXRvbWF0aWMgdGhvdWdodHMNCiAgICAgICAgICAgIGVpdSA9IC4xNSwgIyB1cHBlciBib3VuZCBvZiBTRVNPSSAoc3RhbmRhcmRpemVkKSANCiAgICAgICAgICAgIGVpbD0gLS4xNSwgICMgbG93ZXIgYm91bmQgb2YgU0VTT0kgKHN0YW5kYXJkaXplZCkNCiAgICAgICAgICAgIHNlZWQgPSAxMjMsDQogICAgICAgICAgICBkZXA9VCkgIyBjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgYXJlIE5PVCBkZXBlbmRlbnQNCg0KDQpgYGANCg0KDQpIZXJlLCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gY29ycmVsYXRpb24gY29lZmZpY2llbnRzIGlzIHN0YXRpc3RpY2FsbHkgYW5kIHByYWN0aWNhbGx5IG5lZ2xpZ2libGUsICRyXzEgLSByXzIgPSAwLjA0MiwgXCA5NSBcJSBcIENJIFwgWy0wLjEyLCAwLjIwNl0sIFwgcCA8ICAwLjAwMSQgc3VnZ2VzdGluZyB0aGF0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gY29ycmVsYXRpb24gY29lZmZpY2llbnRzIGlzIG5vbi1uZWdsaWdpYmxlIChpLmUuLCBiZXlvbmQgdGhlIHNwZWNpZmllZCBlcXVpdmFsZW5jZSBpbnRlcnZhbCksIGNhbiBiZSByZWplY3RlZC4gQSBuZWdsaWdpYmxlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyBpbiB0aGUgcG9wdWxhdGlvbiBjYW4gYmUgY29uY2x1ZGVkIQ0KDQoNCg0KDQojIyBFeGFtcGxlIDI6IE5vIERhdGFzZXQgQXZhaWxhYmxlDQoNCg0KU3VwcG9zZSB5b3UgZG8gbm90IGhhdmUgYWNjZXNzIHRvIHRoZSBmdWxsIGRhdGEuIFN0aWxsLCB5b3UgbWlnaHQgbG9vayBhdCB0aGUgcmVwb3J0ZWQgcmVzdWx0cyBpbiBhIHJlc2VhcmNoIGFydGljbGUgYW5kIGdhdGhlciB0aGUgcmVxdWlyZWQgZGV0YWlsczogU2F5IHlvdSBvYnNlcnZlIHRoYXQgJHJfMSA9IDAuMjIkIHdpdGggYSBzYW1wbGUgc2l6ZSBvZiAkbj04MjUkLCAkcl8yID0gMC4xOCQgd2l0aCBhIHNhbXBsZSBzaXplIG9mICRuPTc4OSQuIA0KDQpMZXQncyBjb25zaWRlciB0aGUgc2FtZSBlcXVpdmFsZW5jZSBpbnRlcnZhbDogYGVpbCA9IC0uMTVgIGFuZCBgZWl1ID0gLjE1YC4NCg0KDQoNCg0KIyMjIFB1dHRpbmcgSXQgQWxsIFRvZ2V0aGVyICh3aGVuIGRhdGEgaXMgTk9UIGF2YWlsYWJsZSkNCg0KDQpgYGB7cn0NCm5lZy50d29jb3JzKHIxPTAuMjIsICMgZmlyc3QgY29lZmZpY2llbnQNCiAgICAgICAgICAgIG4xPTgyNSwgIyBzYW1wbGUgc2l6ZSBmb3IgMXN0IGNvZWZmaWNpZW50DQogICAgICAgICAgICByMj0wLjE4LCAjIHNlY29uZCBjb2VmZmljaWVudA0KICAgICAgICAgICAgbjI9Nzg5LCAjIHNhbXBsZSBzaXplIGZvciAybmQgY29lZmZpY2llbnQNCiAgICAgICAgICAgIGVpdT0uMTUsDQogICAgICAgICAgICBlaWw9LTAuMTUsIA0KICAgICAgICAgICAgZGVwPUZBTFNFKQ0KYGBgDQoNCg0KDQoNClJlc3VsdHMgZnJvbSB0aGUgbmVnbGlnaWJsZSBlZmZlY3QgdGVzdGluZyBpbmRpY2F0ZSB0aGF0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3byBjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgaXMgaW5kZWVkIG5lZ2xpZ2libGUsICRyXzEgLSByXzIgPSAwLjA0LCBcIDk1IFwlIFwgQ0kgXCBbLTAuMDM5LCAwLjExOV0sIFwgcCA9ICAwLjAxMSQgc3VnZ2VzdGluZyB0aGF0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gY29ycmVsYXRpb24gY29lZmZpY2llbnRzIGlzIG5vbi1uZWdsaWdpYmxlIChpLmUuLCBiZXlvbmQgdGhlIHNwZWNpZmllZCBlcXVpdmFsZW5jZSBpbnRlcnZhbCksIGNhbiBiZSByZWplY3RlZC4gQSBuZWdsaWdpYmxlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyBpbiB0aGUgcG9wdWxhdGlvbiBjYW4gYmUgY29uY2x1ZGVkIQ0K