Quick Review

Moderation (Process model 1)

“The moderator function of third variables, which partitions a focal independent variable into subgroups that establish its domains of maximal effectiveness regarding a given dependent variable” - Baron & Kenny, 1986.

For example, is success on a kindergarten entrance exam predicted by time to eat the marshmallow, but moderated by parenting style?

  • Permissive parents (no boundaries) vs Authoritative (strict).
    • Measurement scale from -3 to 3 (permissive to authoritative)

Moderation

Steps

Center

Marshmallow.Mod$Parents.C<-scale(Marshmallow.Mod$Parents,scale=F)[,]
Marshmallow.Mod$Time.C<-scale(Marshmallow.Mod$Time,scale=F)[,]

Regression models

Mod.1<-lm(Success~Time.C+Parents.C, data= Marshmallow.Mod)
Mod.2<-lm(Success~Time.C*Parents.C, data= Marshmallow.Mod)

Test simple slopes

  • Plot the results of each moderator to help us visualize the results
  • We must set our moderator levels (-1SD [Permissive] and +1SD [Authoritative])
Permissive<--sd(Marshmallow.Mod$Parents.C)
Authoritative<-+sd(Marshmallow.Mod$Parents.C)
  • Permissive: Parents.C = -1.7 score
  • Authoritative: Parents.C = 1.7 score

- To do this quickly we will use rockchalk package, but to do this by hand you have to recenter the data (which we covered a few weeks ago).

library(rockchalk)
m1ps <- plotSlopes(Mod.2, modx = "Parents.C", plotx = "Time.C", n=2, modxVals="std.dev")
m1psts <- testSlopes(m1ps)
knitr::kable(round(m1psts$hypotests,4))
## Values of Parents.C OUTSIDE this interval:
##        lo        hi 
## -2.793686 -1.583800 
## cause the slope of (b1 + b2*Parents.C)Time.C to be statistically significant
“Parents.C” slope Std. Error t value Pr(>|t|)
(m-sd) -1.7 0.8331 0.5734 1.4530 0.1473
(m+sd) 1.7 8.2879 0.6062 13.6712 0.0000

Summary

So what do these results tell us?

Review Mediation (Process Model 4)

“The mediator function of a third variable, which represents the generative mechanism through which the focal independent variable can influence the dependent variable of interest” - Baron & Kenny, 1986.

For example, do does children respect/trust in of authority figures to keep their promises intermediating in the causal chain for success.

Mediation

Test mediation

Steps, 1) Y~X [c path], 2) Med~X [a path], 3) Y~X+Med [b & c’ path]

library(mediation)
Model.2<-lm(Trust~Time, data= Marshmallow.Mod)
Model.3<-lm(Success~Trust+Time, data= Marshmallow.Mod)
Med.Boot.BCa <- mediate(Model.2, Model.3, boot = TRUE, 
                        boot.ci.type = "bca", sims=200, treat="Time", mediator="Trust")
summary(Med.Boot.BCa)
## 
## Causal Mediation Analysis 
## 
## Nonparametric Bootstrap Confidence Intervals with the BCa Method
## 
##                Estimate 95% CI Lower 95% CI Upper p-value    
## ACME              5.423        4.260         7.07  <2e-16 ***
## ADE              -0.363       -1.123         0.36    0.35    
## Total Effect      5.060        3.692         6.45  <2e-16 ***
## Prop. Mediated    1.072        0.949         1.27  <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Sample Size Used: 300 
## 
## 
## Simulations: 200

Summary

So what do these results tell us?

Moderated-Mediated

“…moderated mediation occurs when the strength of an indirect effect depends on the level of some variable, or in other words, when mediation relations are contingent on the level of a moderator” - see Preacher, Rucker, & Hayes (2007)

  • Moderation examines how subgroups influence the strength of the relationship between X to Y
  • Mediation is trying to figure out the intermediating factors involved in getting from X to Y
    • Moderated-Mediated is that effect of the mediator is moderated

Example

You collect 300 4-year-olds, give them the Marshmallow test (measure their time to eat the marshmallow). You operationalize success as how they did at the end of the year on kindergarten entrance exam. - You also measure how must trust they have in authority figures (proposed Mediator). - You also measure the parenting style of the high warmth parents (proposed Moderator) - Permissive parents (no boundaries) vs Authoritative (strict) - Measurement scale from -3 to 3 (permissive to authoritative) - What if trust is moderated by parenting styles - We expect mediator (trust) to be stronger for kids with authoritative than permissive parents (indirect path) - But it could also be possible that children from authoritative parents who last longer will show more success (direct path)

Model approaches

There are multiple ways to think what about testing a moderated mediation. Preacher, Rucker, & Hayes (2007) argue you can test the moderation on a, b, c’ pathways directly and that should be theorized moderation based on where you theorize it to be. Imai et al, (2010) have proposed a different framework that allows for generalized approach, but they instead of think about it moderating the direct and indirect path (not a or b)

Only the indirect pathway is moderated

Both a and b path are moderated

Process Model 58

Just a path is moderated

Process Model 7

Just b path is moderated

Process Model 14

Direct and indirect pathway are moderated

Process59

Process8

Process15

Analysis

Simulation below:

Moderation on Path a, b, c’

  • In this case, we think the direct (c’) and indirect path (a,b) is moderated by Parenting style. (Note this is Hayes’ process model 59)

Moderated Mediation

  • So we have to interact it in Model 2 (Mediator Model) and Model 3 (Outcome Model)

  • Model 2 from Kenny becomes, \(M ~ X*Mod\)

  • Model 3 from Kenny becomes, \(Y ~ M*Mod+X*Mod\)

  • Since we are going to be dealing with interactions, we should center our scores before analysis

  • Center:

Marshmallow.Mod$Parents.C<-scale(Marshmallow.Mod$Parents,scale=F)[,]
Marshmallow.Mod$Time.C<-scale(Marshmallow.Mod$Time,scale=F)[,]
Marshmallow.Mod$Trust.C<-scale(Marshmallow.Mod$Trust,scale=F)[,]
  • Regression models:
ModMed.Mediator<-lm(Trust~Parents.C*Time.C, data= Marshmallow.Mod)
ModMed.Outcome<-lm(Success~Trust.C*Parents.C+Time.C*Parents.C, data= Marshmallow.Mod)
  • Mediator and Outcome Models (Note difference in DV when reading table):
  • Plot the results of each moderator to help us visualize the results
  • We must set our moderator levels (-1SD [Permissive] and +1SD [Authoritative])
Permissive<--sd(Marshmallow.Mod$Parents.C)
Authoritative<-+sd(Marshmallow.Mod$Parents.C)
  • Permissive: Parents.C = -1.7 score
  • Authoritative: Parents.C = 1.7 score

Test Moderation on Path a, b, c’

  • In this mediation package we list the moderator as a covariate and set the levels we wish to test
    • Again, we can use the +/- 1SD from the mean (also we can use zero if wanted to see the average parent)
    • This allows us to view the impact of the moderator on the direct and indirect effect

Permissive Parents

  • We set the covariates = list(Parents.C = Permissive) in our mediation (remember we defined this above as having a Parents.C = -1.7 score)
library(mediation)
ModMed.Boot.BCa.1 <- mediate(ModMed.Mediator, ModMed.Outcome, 
                              covariates = list(Parents.C = Permissive), boot = TRUE, 
                              boot.ci.type = "bca", sims=200, treat="Time.C", mediator="Trust.C")
summary(ModMed.Boot.BCa.1)
plot(ModMed.Boot.BCa.1)
## 
## Causal Mediation Analysis 
## 
## Nonparametric Bootstrap Confidence Intervals with the BCa Method
## 
## (Inference Conditional on the Covariate Values Specified in `covariates')
## 
##                Estimate 95% CI Lower 95% CI Upper p-value    
## ACME              0.726        0.406         1.23  <2e-16 ***
## ADE               0.221       -0.451         0.92    0.54    
## Total Effect      0.947        0.233         1.80  <2e-16 ***
## Prop. Mediated    0.767        1.715       222.99  <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Sample Size Used: 300 
## 
## 
## Simulations: 200

  • No direct effect permissive parents, but there is an indirect effect:
    • For children of permissive parents, they are more successful if they have more trust

Authoritative Parents

  • We set the covariates = list(Parents.C = Authoritative) in our mediation (remember we defined this above as having a Parents.C = 1.7 score)
ModMed.Boot.BCa.2 <- mediate(ModMed.Mediator, ModMed.Outcome, 
                              covariates = list(Parents.C = Authoritative), boot = TRUE, 
                              boot.ci.type = "bca", sims=200, treat="Time.C", mediator="Trust.C")
summary(ModMed.Boot.BCa.2)
plot(ModMed.Boot.BCa.2)
## 
## Causal Mediation Analysis 
## 
## Nonparametric Bootstrap Confidence Intervals with the BCa Method
## 
## (Inference Conditional on the Covariate Values Specified in `covariates')
## 
##                Estimate 95% CI Lower 95% CI Upper p-value    
## ACME              7.843        6.633         9.49  <2e-16 ***
## ADE               0.561       -0.257         1.53    0.14    
## Total Effect      8.404        7.152        10.02  <2e-16 ***
## Prop. Mediated    0.933        0.834         1.03  <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Sample Size Used: 300 
## 
## 
## Simulations: 200

  • No direct effect authoritative parents, but there is an indirect effect:
    • For children of authoritative parents, they are more successful if they have more trust

Difference Direct/indirect effect

  • To get a significance test on if the moderator is causing a difference in the direct or indirect effects
      1. we must first run a third moderation (not accoutining for the covariate)
      1. use the test.modmed function at testing between the covariates, covariates.1 = list(Parents.C = Permissive) and covariates.2 = list(Parents.C = Authoritative)
ModMed.Boot.BCa.3 <- mediate(ModMed.Mediator, ModMed.Outcome, boot = TRUE, 
                              boot.ci.type = "bca", sims=200, treat="Time.C", mediator="Trust.C")
TestDiff<-test.modmed(ModMed.Boot.BCa.3, covariates.1 = list(Parents.C = Permissive),
            covariates.2 = list(Parents.C = Authoritative), sims = 200)
TestDiff
## 
##  Test of ACME(covariates.1) - ACME(covariates.2) = 0
## 
## data:  estimates from ModMed.Boot.BCa.3
## ACME(covariates.1) - ACME(covariates.2) = -7.1161, p-value < 2.2e-16
## alternative hypothesis: true ACME(covariates.1) - ACME(covariates.2) is not equal to 0
## 95 percent confidence interval:
##  -8.626936 -5.740560
## 
## 
##  Test of ADE(covariates.1) - ADE(covariates.2) = 0
## 
## data:  estimates from ModMed.Boot.BCa.3
## ADE(covariates.1) - ADE(covariates.2) = -0.34042, p-value = 0.61
## alternative hypothesis: true ADE(covariates.1) - ADE(covariates.2) is not equal to 0
## 95 percent confidence interval:
##  -1.6115384  0.7199354
  • Given the we did not have a direct effect to begin with, the difference in direct effect levels is not interesting
  • The difference in the indirect effect is significant (we have moderated mediation).
    • The negative value is that indirect effect for Permissive ACME) - Authoritative ACME = -7.12 and it was significantly different from 0. So the effect is bigger for Authoritative parenting as we predicted.

References

Baron, R. M., & Kenny, D. A. (1986). The moderator-mediator variable distinction in social psychological research: Conceptual, strategic, and statistical considerations. Journal of personality and social psychology, 51(6), 1173.

Preacher, K. J., Rucker, D. D., & Hayes, A. F. (2007). Addressing moderated mediation hypotheses: Theory, methods, and prescriptions. Multivariate behavioral research, 42(1), 185-227.

Imai, K., Keele, L., & Tingley, D. (2010). A general approach to causal mediation analysis. Psychological methods, 15(4), 309.

LS0tDQp0aXRsZTogJ01vZGVyYXRlZCBNZWRpYXRpb24nDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgZm9udHNpemU6IDhwdA0KICAgIGhpZ2hsaWdodDogdGV4dG1hdGUNCiAgICBudW1iZXJfc2VjdGlvbnM6IG5vDQogICAgdGhlbWU6IGZsYXRseQ0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBubw0KLS0tDQoNClxwYWdlYnJlYWsNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoY2FjaGUgPSBUUlVFKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKSAjU2hvdyBhbGwgc2NyaXB0IGJ5IGRlZmF1bHQNCmtuaXRyOjpvcHRzX2NodW5rJHNldChtZXNzYWdlID0gRkFMU0UpICNoaWRlIG1lc3NhZ2VzIA0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KHdhcm5pbmcgPSAgRkFMU0UpICNoaWRlIHBhY2thZ2Ugd2FybmluZ3MgDQprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLndpZHRoPTUpICNTZXQgZGVmYXVsdCBmaWd1cmUgc2l6ZXMNCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcuaGVpZ2h0PTMuNSkgI1NldCBkZWZhdWx0IGZpZ3VyZSBzaXplcw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy5hbGlnbj0nY2VudGVyJykgI1NldCBkZWZhdWx0IGZpZ3VyZQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy5zaG93ID0gImhvbGQiKSAjU2V0IGRlZmF1bHQgZmlndXJlDQprbml0cjo6b3B0c19jaHVuayRzZXQocmVzdWx0cyA9ICJob2xkIikgDQpgYGANCg0KIyBRdWljayBSZXZpZXcNCg0KIyMgTW9kZXJhdGlvbiAoUHJvY2VzcyBtb2RlbCAxKQ0KDQo+ICJUaGUgbW9kZXJhdG9yIGZ1bmN0aW9uIG9mIHRoaXJkIHZhcmlhYmxlcywgd2hpY2ggcGFydGl0aW9ucyBhIGZvY2FsIGluZGVwZW5kZW50IHZhcmlhYmxlIGludG8gc3ViZ3JvdXBzIHRoYXQgZXN0YWJsaXNoIGl0cyBkb21haW5zIG9mIG1heGltYWwgZWZmZWN0aXZlbmVzcyByZWdhcmRpbmcgYSBnaXZlbiBkZXBlbmRlbnQgdmFyaWFibGUiIC0gQmFyb24gJiBLZW5ueSwgMTk4Ni4NCg0KRm9yIGV4YW1wbGUsIGlzIHN1Y2Nlc3Mgb24gYSBraW5kZXJnYXJ0ZW4gZW50cmFuY2UgZXhhbSBwcmVkaWN0ZWQgYnkgdGltZSB0byBlYXQgdGhlIG1hcnNobWFsbG93LCBidXQgbW9kZXJhdGVkIGJ5ICoqcGFyZW50aW5nIHN0eWxlKio/IA0KDQotIFBlcm1pc3NpdmUgcGFyZW50cyAobm8gYm91bmRhcmllcykgdnMgQXV0aG9yaXRhdGl2ZSAoc3RyaWN0KS4gDQogICAgLSBNZWFzdXJlbWVudCBzY2FsZSBmcm9tIC0zIHRvIDMgKHBlcm1pc3NpdmUgdG8gYXV0aG9yaXRhdGl2ZSkNCg0KIVtNb2RlcmF0aW9uXShSZWdyZXNzaW9uQ2xhc3MvUHJvY2VzczEucG5nKQ0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kc2V0LnNlZWQoNDIpDQojIHBhdGggYSBzdHJlbmd0aA0KYT0uMw0KIyBwYXRoIGIgc3RyZW5ndGgNCmI9LjMNCiMgcGF0aCBjJyBzdHJlbmd0aA0KY3A9LjINCiMgIHBlb3BsZQ0KbiA8LSAzMDANCiMgTm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiB0aW1lIChtaW5zKQ0KWCA8LSBybm9ybShuLCA1LCAyKQ0KIyBNb2RlcmF0b3INCk1vZDwtcnVuaWYobiwgMCwgNikNCiMgTWVkaWF0b3INCk0gPC0gYSpYKk1vZCtybm9ybShuLCAwLCAzKQ0KIyBPdXIgZXF1YXRpb24gdG8gIGNyZWF0ZSBZDQpZIDwtIGNwKlgqTW9kICsgYipNICsgTSpNb2QgKyBybm9ybShuLCBzZD03KQ0KI0J1aWx0IG91ciBkYXRhIGZyYW1lDQpNYXJzaG1hbGxvdy5Nb2Q8LWRhdGEuZnJhbWUoU3VjY2Vzcz1ZLFRpbWU9WCxUcnVzdD1NLFBhcmVudHM9TW9kKQ0KYGBgDQoNCiMjIyBTdGVwcw0KDQojIyMjIENlbnRlcg0KYGBge3J9DQpNYXJzaG1hbGxvdy5Nb2QkUGFyZW50cy5DPC1zY2FsZShNYXJzaG1hbGxvdy5Nb2QkUGFyZW50cyxzY2FsZT1GKVssXQ0KTWFyc2htYWxsb3cuTW9kJFRpbWUuQzwtc2NhbGUoTWFyc2htYWxsb3cuTW9kJFRpbWUsc2NhbGU9RilbLF0NCmBgYA0KDQojIyMjIFJlZ3Jlc3Npb24gbW9kZWxzDQpgYGB7cn0NCk1vZC4xPC1sbShTdWNjZXNzflRpbWUuQytQYXJlbnRzLkMsIGRhdGE9IE1hcnNobWFsbG93Lk1vZCkNCk1vZC4yPC1sbShTdWNjZXNzflRpbWUuQypQYXJlbnRzLkMsIGRhdGE9IE1hcnNobWFsbG93Lk1vZCkNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9DQpsaWJyYXJ5KHN0YXJnYXplcikNCnN0YXJnYXplcihNb2QuMSwgTW9kLjIsdHlwZT0ibGF0ZXgiLA0KICAgICAgICAgIGludGVyY2VwdC5ib3R0b20gPSBGQUxTRSwgc2luZ2xlLnJvdz1UUlVFLCANCiAgICAgICAgICBub3Rlcy5hcHBlbmQgPSBGQUxTRSwgaGVhZGVyPUZBTFNFLA0KICAgICAgICAgIGNvdmFyaWF0ZS5sYWJlbHM9KCJJbnRlcmNlcHQiKSxmbG9hdD1UUlVFKQ0KYGBgDQoNCiMjIyMgVGVzdCBzaW1wbGUgc2xvcGVzDQoNCi0gUGxvdCB0aGUgcmVzdWx0cyBvZiBlYWNoIG1vZGVyYXRvciB0byBoZWxwIHVzIHZpc3VhbGl6ZSB0aGUgcmVzdWx0cw0KLSBXZSBtdXN0IHNldCBvdXIgbW9kZXJhdG9yIGxldmVscyAoLTFTRCBbUGVybWlzc2l2ZV0gYW5kICsxU0QgW0F1dGhvcml0YXRpdmVdKQ0KDQpgYGB7cn0NClBlcm1pc3NpdmU8LS1zZChNYXJzaG1hbGxvdy5Nb2QkUGFyZW50cy5DKQ0KQXV0aG9yaXRhdGl2ZTwtK3NkKE1hcnNobWFsbG93Lk1vZCRQYXJlbnRzLkMpDQpgYGANCg0KLSBQZXJtaXNzaXZlOiBQYXJlbnRzLkMgPSBgciByb3VuZChQZXJtaXNzaXZlLDIpYCBzY29yZQ0KLSBBdXRob3JpdGF0aXZlOiBQYXJlbnRzLkMgPSBgciByb3VuZChBdXRob3JpdGF0aXZlLDIpYCBzY29yZQ0KDQpgYGB7cixlY2hvPUZBTFNFLCBvdXQud2lkdGg9Jy40OVxcbGluZXdpZHRoJywgZmlnLndpZHRoPTMuNSwgZmlnLmhlaWdodD0zLjI1LGZpZy5zaG93PSdob2xkJyxmaWcuYWxpZ249J2NlbnRlcid9DQpsaWJyYXJ5KHNqUGxvdCkNCg0KcGxvdF9tb2RlbChNb2QuMiwgdHlwZSA9ICJwcmVkIiwNCiAgICAgICAgICAgdGVybXM9YygiVGltZS5DIiwiUGFyZW50cy5DIFstMS43LCAxLjddIiksDQogICAgICAgICAgIGNvbG9ycyA9IGMoInB1cnBsZSIsICJkYXJrZ3JlZW4iKSkrdGhlbWVfc2pwbG90MigpDQpgYGANCi0gVG8gZG8gdGhpcyBxdWlja2x5IHdlIHdpbGwgdXNlIHJvY2tjaGFsayBwYWNrYWdlLCBidXQgdG8gZG8gdGhpcyBieSBoYW5kICB5b3UgaGF2ZSB0byByZWNlbnRlciB0aGUgZGF0YSAod2hpY2ggd2UgY292ZXJlZCBhIGZldyB3ZWVrcyBhZ28pLg0KDQpgYGB7cn0NCmxpYnJhcnkocm9ja2NoYWxrKQ0KbTFwcyA8LSBwbG90U2xvcGVzKE1vZC4yLCBtb2R4ID0gIlBhcmVudHMuQyIsIHBsb3R4ID0gIlRpbWUuQyIsIG49MiwgbW9keFZhbHM9InN0ZC5kZXYiKQ0KbTFwc3RzIDwtIHRlc3RTbG9wZXMobTFwcykNCmtuaXRyOjprYWJsZShyb3VuZChtMXBzdHMkaHlwb3Rlc3RzLDQpKQ0KYGBgDQoNCiMjIyBTdW1tYXJ5DQpTbyB3aGF0IGRvIHRoZXNlIHJlc3VsdHMgdGVsbCB1cz8gDQoNCg0KIyMgUmV2aWV3IE1lZGlhdGlvbiAoUHJvY2VzcyBNb2RlbCA0KQ0KDQo+ICJUaGUgbWVkaWF0b3IgZnVuY3Rpb24gb2YgYSB0aGlyZCB2YXJpYWJsZSwgd2hpY2ggcmVwcmVzZW50cyB0aGUgZ2VuZXJhdGl2ZSBtZWNoYW5pc20gdGhyb3VnaCB3aGljaCB0aGUgZm9jYWwgaW5kZXBlbmRlbnQgdmFyaWFibGUgY2FuIGluZmx1ZW5jZSB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIG9mIGludGVyZXN0IiAtIEJhcm9uICYgS2VubnksIDE5ODYuDQoNCkZvciBleGFtcGxlLCBkbyBkb2VzIGNoaWxkcmVuIHJlc3BlY3QvdHJ1c3QgaW4gb2YgYXV0aG9yaXR5IGZpZ3VyZXMgdG8ga2VlcCB0aGVpciBwcm9taXNlcyBpbnRlcm1lZGlhdGluZyBpbiB0aGUgY2F1c2FsIGNoYWluIGZvciBzdWNjZXNzLiANCg0KIVtNZWRpYXRpb25dKFJlZ3Jlc3Npb25DbGFzcy9Qcm9jZXNzNC5wbmcpDQoNCiMjIyBUZXN0IG1lZGlhdGlvbg0KU3RlcHMsIDEpIFl+WCBbYyBwYXRoXSwgMikgTWVkflggW2EgcGF0aF0sIDMpIFl+WCtNZWQgW2IgJiBjJyBwYXRoXSAgDQoNCmBgYHtyLCBlY2hvPVRSVUV9DQpsaWJyYXJ5KG1lZGlhdGlvbikNCk1vZGVsLjI8LWxtKFRydXN0flRpbWUsIGRhdGE9IE1hcnNobWFsbG93Lk1vZCkNCk1vZGVsLjM8LWxtKFN1Y2Nlc3N+VHJ1c3QrVGltZSwgZGF0YT0gTWFyc2htYWxsb3cuTW9kKQ0KTWVkLkJvb3QuQkNhIDwtIG1lZGlhdGUoTW9kZWwuMiwgTW9kZWwuMywgYm9vdCA9IFRSVUUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgYm9vdC5jaS50eXBlID0gImJjYSIsIHNpbXM9MjAwLCB0cmVhdD0iVGltZSIsIG1lZGlhdG9yPSJUcnVzdCIpDQpzdW1tYXJ5KE1lZC5Cb290LkJDYSkNCmBgYA0KDQojIyBTdW1tYXJ5DQpTbyB3aGF0IGRvIHRoZXNlIHJlc3VsdHMgdGVsbCB1cz8gDQoNCg0KIyBNb2RlcmF0ZWQtTWVkaWF0ZWQNCg0KPiAiLi4ubW9kZXJhdGVkIG1lZGlhdGlvbiBvY2N1cnMgd2hlbiB0aGUgc3RyZW5ndGggb2YgYW4gaW5kaXJlY3QgZWZmZWN0IGRlcGVuZHMgb24gdGhlIGxldmVsIG9mIHNvbWUgdmFyaWFibGUsIG9yIGluIG90aGVyIHdvcmRzLCB3aGVuIG1lZGlhdGlvbiByZWxhdGlvbnMgYXJlIGNvbnRpbmdlbnQgb24gdGhlIGxldmVsIG9mIGEgbW9kZXJhdG9yIiAtIHNlZSBQcmVhY2hlciwgUnVja2VyLCAmIEhheWVzICgyMDA3KQ0KDQotIE1vZGVyYXRpb24gZXhhbWluZXMgaG93IHN1Ymdyb3VwcyBpbmZsdWVuY2UgdGhlIHN0cmVuZ3RoIG9mIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBYIHRvIFkNCi0gTWVkaWF0aW9uIGlzIHRyeWluZyB0byBmaWd1cmUgb3V0IHRoZSBpbnRlcm1lZGlhdGluZyBmYWN0b3JzIGludm9sdmVkIGluIGdldHRpbmcgZnJvbSBYIHRvIFkNCiAgICAtICpNb2RlcmF0ZWQtTWVkaWF0ZWQgaXMgdGhhdCBlZmZlY3Qgb2YgdGhlIG1lZGlhdG9yIGlzIG1vZGVyYXRlZCogDQoNCg0KIyMgRXhhbXBsZSANCllvdSBjb2xsZWN0IDMwMCA0LXllYXItb2xkcywgZ2l2ZSB0aGVtIHRoZSBNYXJzaG1hbGxvdyB0ZXN0IChtZWFzdXJlIHRoZWlyIHRpbWUgdG8gZWF0IHRoZSBtYXJzaG1hbGxvdykuIFlvdSBvcGVyYXRpb25hbGl6ZSBzdWNjZXNzIGFzIGhvdyB0aGV5IGRpZCBhdCB0aGUgZW5kIG9mIHRoZSB5ZWFyIG9uIGtpbmRlcmdhcnRlbiBlbnRyYW5jZSBleGFtLiANCi0gWW91IGFsc28gbWVhc3VyZSBob3cgbXVzdCB0cnVzdCB0aGV5IGhhdmUgaW4gYXV0aG9yaXR5IGZpZ3VyZXMgKHByb3Bvc2VkIE1lZGlhdG9yKS4gDQotIFlvdSBhbHNvIG1lYXN1cmUgdGhlIHBhcmVudGluZyBzdHlsZSBvZiB0aGUgaGlnaCB3YXJtdGggcGFyZW50cyAocHJvcG9zZWQgTW9kZXJhdG9yKQ0KICAgIC0gUGVybWlzc2l2ZSBwYXJlbnRzIChubyBib3VuZGFyaWVzKSB2cyBBdXRob3JpdGF0aXZlIChzdHJpY3QpDQogICAgICAgIC0gTWVhc3VyZW1lbnQgc2NhbGUgZnJvbSAtMyB0byAzIChwZXJtaXNzaXZlIHRvIGF1dGhvcml0YXRpdmUpDQotIFdoYXQgaWYgKnRydXN0KiBpcyBtb2RlcmF0ZWQgYnkgKnBhcmVudGluZyBzdHlsZXMqIA0KICAgIC0gV2UgZXhwZWN0IG1lZGlhdG9yICgqdHJ1c3QqKSB0byBiZSBzdHJvbmdlciBmb3Iga2lkcyB3aXRoIGF1dGhvcml0YXRpdmUgdGhhbiBwZXJtaXNzaXZlIHBhcmVudHMgKCoqaW5kaXJlY3QgcGF0aCoqKQ0KICAgIC0gQnV0IGl0IGNvdWxkIGFsc28gYmUgcG9zc2libGUgdGhhdCBjaGlsZHJlbiBmcm9tIGF1dGhvcml0YXRpdmUgcGFyZW50cyB3aG8gbGFzdCBsb25nZXIgd2lsbCBzaG93IG1vcmUgc3VjY2VzcyAoKipkaXJlY3QgcGF0aCoqKQ0KICAgIA0KICAgIA0KIyMgTW9kZWwgYXBwcm9hY2hlcw0KDQpUaGVyZSBhcmUgbXVsdGlwbGUgd2F5cyB0byB0aGluayB3aGF0IGFib3V0IHRlc3RpbmcgYSBtb2RlcmF0ZWQgbWVkaWF0aW9uLiBQcmVhY2hlciwgUnVja2VyLCAmIEhheWVzICgyMDA3KSBhcmd1ZSB5b3UgY2FuIHRlc3QgdGhlIG1vZGVyYXRpb24gb24gYSwgYiwgYycgcGF0aHdheXMgZGlyZWN0bHkgYW5kIHRoYXQgc2hvdWxkIGJlIHRoZW9yaXplZCBtb2RlcmF0aW9uIGJhc2VkIG9uIHdoZXJlIHlvdSB0aGVvcml6ZSBpdCB0byBiZS4gSW1haSBldCBhbCwgKDIwMTApIGhhdmUgcHJvcG9zZWQgYSBkaWZmZXJlbnQgZnJhbWV3b3JrIHRoYXQgYWxsb3dzIGZvciBnZW5lcmFsaXplZCBhcHByb2FjaCwgYnV0IHRoZXkgaW5zdGVhZCBvZiB0aGluayBhYm91dCBpdCBtb2RlcmF0aW5nIHRoZSBkaXJlY3QgYW5kIGluZGlyZWN0IHBhdGggKG5vdCBhIG9yIGIpDQoNCiMjIyBPbmx5IHRoZSBpbmRpcmVjdCBwYXRod2F5IGlzIG1vZGVyYXRlZA0KDQpCb3RoIGEgYW5kIGIgcGF0aCBhcmUgbW9kZXJhdGVkDQoNCiFbUHJvY2VzcyBNb2RlbCA1OF0oUmVncmVzc2lvbkNsYXNzL1Byb2Nlc3M1OC5wbmcpDQoNCkp1c3QgYSBwYXRoIGlzIG1vZGVyYXRlZA0KDQohW1Byb2Nlc3MgTW9kZWwgN10oUmVncmVzc2lvbkNsYXNzL1Byb2Nlc3M3LnBuZykNCg0KDQpKdXN0IGIgcGF0aCBpcyBtb2RlcmF0ZWQNCg0KIVtQcm9jZXNzIE1vZGVsIDE0XShSZWdyZXNzaW9uQ2xhc3MvUHJvY2VzczE0LnBuZykNCg0KDQojIyMgRGlyZWN0IGFuZCBpbmRpcmVjdCBwYXRod2F5IGFyZSBtb2RlcmF0ZWQNCg0KIVtQcm9jZXNzNTldKFJlZ3Jlc3Npb25DbGFzcy9Qcm9jZXNzNTkucG5nKQ0KDQohW1Byb2Nlc3M4XShSZWdyZXNzaW9uQ2xhc3MvUHJvY2VzczgucG5nKQ0KDQohW1Byb2Nlc3MxNV0oUmVncmVzc2lvbkNsYXNzL1Byb2Nlc3MxNS5wbmcpDQoNCg0KIyMgQW5hbHlzaXMgDQogICAgDQpTaW11bGF0aW9uIGJlbG93Og0KYGBge3IsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpzZXQuc2VlZCg0MikNCiMgcGF0aCBhIHN0cmVuZ3RoDQphPS4zDQojIHBhdGggYiBzdHJlbmd0aA0KYj0uMw0KIyBwYXRoIGMnIHN0cmVuZ3RoDQpjcD0uMg0KIyAgcGVvcGxlDQpuIDwtIDMwMA0KIyBOb3JtYWwgZGlzdHJpYnV0aW9uIG9mIHRpbWUgKG1pbnMpDQpYIDwtIHJub3JtKG4sIDUsIDIpDQojIE1vZGVyYXRvcg0KTW9kPC1ydW5pZihuLCAwLCA2KQ0KIyBNZWRpYXRvcg0KTSA8LSBhKlgqTW9kK3Jub3JtKG4sIDAsIDMpDQojIE91ciBlcXVhdGlvbiB0byAgY3JlYXRlIFkNClkgPC0gY3AqWCpNb2QgKyBiKk0gKyBNKk1vZCArIHJub3JtKG4sIHNkPTcpDQojQnVpbHQgb3VyIGRhdGEgZnJhbWUNCk1hcnNobWFsbG93Lk1vZDwtZGF0YS5mcmFtZShTdWNjZXNzPVksVGltZT1YLFRydXN0PU0sUGFyZW50cz1Nb2QpDQpgYGANCg0KIyMgTW9kZXJhdGlvbiBvbiBQYXRoIGEsIGIsIGMnICANCg0KLSBJbiB0aGlzIGNhc2UsIHdlIHRoaW5rIHRoZSBkaXJlY3QgKGMnKSBhbmQgaW5kaXJlY3QgcGF0aCAoYSxiKSBpcyBtb2RlcmF0ZWQgYnkgUGFyZW50aW5nIHN0eWxlLiAoKk5vdGUgdGhpcyBpcyBIYXllcycgcHJvY2VzcyBtb2RlbCA1OSopDQoNCiFbTW9kZXJhdGVkIE1lZGlhdGlvbl0oUmVncmVzc2lvbkNsYXNzL1Byb2Nlc3M1OS5wbmcpDQoNCi0gU28gd2UgaGF2ZSB0byBpbnRlcmFjdCBpdCBpbiBNb2RlbCAyIChNZWRpYXRvciBNb2RlbCkgYW5kIE1vZGVsIDMgKE91dGNvbWUgTW9kZWwpDQotIE1vZGVsIDIgZnJvbSBLZW5ueSBiZWNvbWVzLCAkTSB+IFgqTW9kJA0KLSBNb2RlbCAzIGZyb20gS2VubnkgYmVjb21lcywgJFkgfiBNKk1vZCtYKk1vZCQNCi0gU2luY2Ugd2UgYXJlIGdvaW5nIHRvIGJlIGRlYWxpbmcgd2l0aCBpbnRlcmFjdGlvbnMsIHdlIHNob3VsZCBjZW50ZXIgb3VyIHNjb3JlcyBiZWZvcmUgYW5hbHlzaXMNCg0KLSBDZW50ZXI6IA0KYGBge3J9DQpNYXJzaG1hbGxvdy5Nb2QkUGFyZW50cy5DPC1zY2FsZShNYXJzaG1hbGxvdy5Nb2QkUGFyZW50cyxzY2FsZT1GKVssXQ0KTWFyc2htYWxsb3cuTW9kJFRpbWUuQzwtc2NhbGUoTWFyc2htYWxsb3cuTW9kJFRpbWUsc2NhbGU9RilbLF0NCk1hcnNobWFsbG93Lk1vZCRUcnVzdC5DPC1zY2FsZShNYXJzaG1hbGxvdy5Nb2QkVHJ1c3Qsc2NhbGU9RilbLF0NCmBgYA0KDQotIFJlZ3Jlc3Npb24gbW9kZWxzOg0KYGBge3J9DQpNb2RNZWQuTWVkaWF0b3I8LWxtKFRydXN0flBhcmVudHMuQypUaW1lLkMsIGRhdGE9IE1hcnNobWFsbG93Lk1vZCkNCk1vZE1lZC5PdXRjb21lPC1sbShTdWNjZXNzflRydXN0LkMqUGFyZW50cy5DK1RpbWUuQypQYXJlbnRzLkMsIGRhdGE9IE1hcnNobWFsbG93Lk1vZCkNCmBgYA0KDQotIE1lZGlhdG9yIGFuZCBPdXRjb21lIE1vZGVscyAoKk5vdGUgZGlmZmVyZW5jZSBpbiBEViB3aGVuIHJlYWRpbmcgdGFibGUqKToNCg0KYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnfQ0KbGlicmFyeShzdGFyZ2F6ZXIpDQpzdGFyZ2F6ZXIoTW9kTWVkLk1lZGlhdG9yLCBNb2RNZWQuT3V0Y29tZSx0eXBlPSJsYXRleCIsDQogICAgICAgICAgaW50ZXJjZXB0LmJvdHRvbSA9IEZBTFNFLCBzaW5nbGUucm93PVRSVUUsIA0KICAgICAgICAgIG5vdGVzLmFwcGVuZCA9IEZBTFNFLCBoZWFkZXI9RkFMU0UsDQogICAgICAgICAgY292YXJpYXRlLmxhYmVscz0oIkludGVyY2VwdCIpLGZsb2F0PVRSVUUpDQpgYGANCg0KLSBQbG90IHRoZSByZXN1bHRzIG9mIGVhY2ggbW9kZXJhdG9yIHRvIGhlbHAgdXMgdmlzdWFsaXplIHRoZSByZXN1bHRzDQotIFdlIG11c3Qgc2V0IG91ciBtb2RlcmF0b3IgbGV2ZWxzICgtMVNEIFtQZXJtaXNzaXZlXSBhbmQgKzFTRCBbQXV0aG9yaXRhdGl2ZV0pDQoNCmBgYHtyfQ0KUGVybWlzc2l2ZTwtLXNkKE1hcnNobWFsbG93Lk1vZCRQYXJlbnRzLkMpDQpBdXRob3JpdGF0aXZlPC0rc2QoTWFyc2htYWxsb3cuTW9kJFBhcmVudHMuQykNCmBgYA0KDQotIFBlcm1pc3NpdmU6IFBhcmVudHMuQyA9IGByIHJvdW5kKFBlcm1pc3NpdmUsMilgIHNjb3JlDQotIEF1dGhvcml0YXRpdmU6IFBhcmVudHMuQyA9IGByIHJvdW5kKEF1dGhvcml0YXRpdmUsMilgIHNjb3JlDQoNCmBgYHtyLGVjaG89RkFMU0UsIG91dC53aWR0aD0nLjQ5XFxsaW5ld2lkdGgnLCBmaWcud2lkdGg9My41LCBmaWcuaGVpZ2h0PTMuMjUsZmlnLnNob3c9J2hvbGQnLGZpZy5hbGlnbj0nY2VudGVyJ30NCmxpYnJhcnkoc2pQbG90KQ0KDQpwbG90X21vZGVsKE1vZE1lZC5NZWRpYXRvciwgdHlwZSA9ICJwcmVkIiwNCiAgICAgICAgICAgdGVybXM9YygiVGltZS5DIiwiUGFyZW50cy5DIFstMS43LCAxLjddIiksDQogICAgICAgICAgIGNvbG9ycyA9IGMoInB1cnBsZSIsICJkYXJrZ3JlZW4iKSkrdGhlbWVfc2pwbG90MigpDQpwbG90X21vZGVsKE1vZE1lZC5PdXRjb21lLCB0eXBlID0gInByZWQiLA0KICAgICAgICAgICB0ZXJtcz1jKCJUaW1lLkMiLCJQYXJlbnRzLkMgWy0xLjcsIDEuN10iKSwNCiAgICAgICAgICAgY29sb3JzID0gYygicHVycGxlIiwgImRhcmtncmVlbiIpKSt0aGVtZV9zanBsb3QyKCkNCnBsb3RfbW9kZWwoTW9kTWVkLk91dGNvbWUsIHR5cGUgPSAicHJlZCIsDQogICAgICAgICAgIHRlcm1zPWMoIlRydXN0LkMiLCJQYXJlbnRzLkMgWy0xLjcsIDEuN10iKSwNCiAgICAgICAgICAgY29sb3JzID0gYygicHVycGxlIiwgImRhcmtncmVlbiIpKSt0aGVtZV9zanBsb3QyKCkNCmBgYA0KDQojIyBUZXN0IE1vZGVyYXRpb24gb24gUGF0aCBhLCBiLCBjJyAgDQotIEluIHRoaXMgbWVkaWF0aW9uIHBhY2thZ2Ugd2UgbGlzdCB0aGUgbW9kZXJhdG9yIGFzIGEgY292YXJpYXRlIGFuZCBzZXQgdGhlIGxldmVscyB3ZSB3aXNoIHRvIHRlc3QgDQogICAgLSBBZ2Fpbiwgd2UgY2FuIHVzZSB0aGUgKy8tIDFTRCBmcm9tIHRoZSBtZWFuIChhbHNvIHdlIGNhbiB1c2UgemVybyBpZiB3YW50ZWQgdG8gc2VlIHRoZSBhdmVyYWdlIHBhcmVudCkNCiAgICAtICoqVGhpcyBhbGxvd3MgdXMgdG8gdmlldyB0aGUgaW1wYWN0IG9mIHRoZSBtb2RlcmF0b3Igb24gdGhlIGRpcmVjdCBhbmQgaW5kaXJlY3QgZWZmZWN0KioNCg0KIyMjIFBlcm1pc3NpdmUgUGFyZW50cyANCi0gV2Ugc2V0IHRoZSBgY292YXJpYXRlcyA9IGxpc3QoUGFyZW50cy5DID0gUGVybWlzc2l2ZSlgIGluIG91ciBtZWRpYXRpb24gKHJlbWVtYmVyIHdlIGRlZmluZWQgdGhpcyBhYm92ZSBhcyBoYXZpbmcgYSBQYXJlbnRzLkMgPSBgciByb3VuZChQZXJtaXNzaXZlLDIpYCBzY29yZSkNCg0KYGBge3J9DQpsaWJyYXJ5KG1lZGlhdGlvbikNCk1vZE1lZC5Cb290LkJDYS4xIDwtIG1lZGlhdGUoTW9kTWVkLk1lZGlhdG9yLCBNb2RNZWQuT3V0Y29tZSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3ZhcmlhdGVzID0gbGlzdChQYXJlbnRzLkMgPSBQZXJtaXNzaXZlKSwgYm9vdCA9IFRSVUUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vdC5jaS50eXBlID0gImJjYSIsIHNpbXM9MjAwLCB0cmVhdD0iVGltZS5DIiwgbWVkaWF0b3I9IlRydXN0LkMiKQ0Kc3VtbWFyeShNb2RNZWQuQm9vdC5CQ2EuMSkNCnBsb3QoTW9kTWVkLkJvb3QuQkNhLjEpDQpgYGANCg0KLSBObyBkaXJlY3QgZWZmZWN0IHBlcm1pc3NpdmUgcGFyZW50cywgYnV0IHRoZXJlIGlzIGFuIGluZGlyZWN0IGVmZmVjdDogDQogICAgLSBGb3IgY2hpbGRyZW4gb2YgcGVybWlzc2l2ZSBwYXJlbnRzLCB0aGV5IGFyZSBtb3JlIHN1Y2Nlc3NmdWwgaWYgdGhleSBoYXZlIG1vcmUgdHJ1c3QgDQoNCiMjIyBBdXRob3JpdGF0aXZlIFBhcmVudHMNCi0gV2Ugc2V0IHRoZSBgY292YXJpYXRlcyA9IGxpc3QoUGFyZW50cy5DID0gQXV0aG9yaXRhdGl2ZSlgIGluIG91ciBtZWRpYXRpb24gKHJlbWVtYmVyIHdlIGRlZmluZWQgdGhpcyBhYm92ZSBhcyBoYXZpbmcgYSBQYXJlbnRzLkMgPSBgciByb3VuZChBdXRob3JpdGF0aXZlLDIpYCBzY29yZSkNCg0KYGBge3J9DQpNb2RNZWQuQm9vdC5CQ2EuMiA8LSBtZWRpYXRlKE1vZE1lZC5NZWRpYXRvciwgTW9kTWVkLk91dGNvbWUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY292YXJpYXRlcyA9IGxpc3QoUGFyZW50cy5DID0gQXV0aG9yaXRhdGl2ZSksIGJvb3QgPSBUUlVFLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb3QuY2kudHlwZSA9ICJiY2EiLCBzaW1zPTIwMCwgdHJlYXQ9IlRpbWUuQyIsIG1lZGlhdG9yPSJUcnVzdC5DIikNCnN1bW1hcnkoTW9kTWVkLkJvb3QuQkNhLjIpDQpwbG90KE1vZE1lZC5Cb290LkJDYS4yKQ0KYGBgDQoNCi0gTm8gZGlyZWN0IGVmZmVjdCBhdXRob3JpdGF0aXZlIHBhcmVudHMsIGJ1dCB0aGVyZSBpcyBhbiBpbmRpcmVjdCBlZmZlY3Q6IA0KICAgIC0gRm9yIGNoaWxkcmVuIG9mIGF1dGhvcml0YXRpdmUgcGFyZW50cywgdGhleSBhcmUgbW9yZSBzdWNjZXNzZnVsIGlmIHRoZXkgaGF2ZSBtb3JlIHRydXN0IA0KDQojIyMgRGlmZmVyZW5jZSBEaXJlY3QvaW5kaXJlY3QgZWZmZWN0IA0KLSBUbyBnZXQgYSBzaWduaWZpY2FuY2UgdGVzdCBvbiBpZiB0aGUgbW9kZXJhdG9yIGlzIGNhdXNpbmcgYSBkaWZmZXJlbmNlIGluIHRoZSBkaXJlY3Qgb3IgaW5kaXJlY3QgZWZmZWN0cyANCiAgICAtIGEpIHdlIG11c3QgZmlyc3QgcnVuIGEgdGhpcmQgbW9kZXJhdGlvbiAobm90IGFjY291dGluaW5nIGZvciB0aGUgY292YXJpYXRlKQ0KICAgIC0gYikgdXNlIHRoZSBgdGVzdC5tb2RtZWRgIGZ1bmN0aW9uIGF0IHRlc3RpbmcgYmV0d2VlbiB0aGUgY292YXJpYXRlcywgYGNvdmFyaWF0ZXMuMSA9IGxpc3QoUGFyZW50cy5DID0gUGVybWlzc2l2ZSlgIGFuZCBgY292YXJpYXRlcy4yID0gbGlzdChQYXJlbnRzLkMgPSBBdXRob3JpdGF0aXZlKWANCg0KYGBge3IsIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCk1vZE1lZC5Cb290LkJDYS4zIDwtIG1lZGlhdGUoTW9kTWVkLk1lZGlhdG9yLCBNb2RNZWQuT3V0Y29tZSwgYm9vdCA9IFRSVUUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vdC5jaS50eXBlID0gImJjYSIsIHNpbXM9MjAwLCB0cmVhdD0iVGltZS5DIiwgbWVkaWF0b3I9IlRydXN0LkMiKQ0KVGVzdERpZmY8LXRlc3QubW9kbWVkKE1vZE1lZC5Cb290LkJDYS4zLCBjb3ZhcmlhdGVzLjEgPSBsaXN0KFBhcmVudHMuQyA9IFBlcm1pc3NpdmUpLA0KICAgICAgICAgICAgY292YXJpYXRlcy4yID0gbGlzdChQYXJlbnRzLkMgPSBBdXRob3JpdGF0aXZlKSwgc2ltcyA9IDIwMCkNClRlc3REaWZmDQpgYGANCg0KLSBHaXZlbiB0aGUgd2UgZGlkIG5vdCBoYXZlIGEgZGlyZWN0IGVmZmVjdCB0byBiZWdpbiB3aXRoLCB0aGUgZGlmZmVyZW5jZSBpbiBkaXJlY3QgZWZmZWN0IGxldmVscyBpcyBub3QgaW50ZXJlc3RpbmcNCi0gVGhlIGRpZmZlcmVuY2UgaW4gdGhlIGluZGlyZWN0IGVmZmVjdCBpcyBzaWduaWZpY2FudCAod2UgaGF2ZSBtb2RlcmF0ZWQgbWVkaWF0aW9uKS4gDQogICAgLSBUaGUgbmVnYXRpdmUgdmFsdWUgaXMgdGhhdCBpbmRpcmVjdCBlZmZlY3QgZm9yIFBlcm1pc3NpdmUgQUNNRSkgLSBBdXRob3JpdGF0aXZlIEFDTUUgPSBgciByb3VuZChhcy5udW1lcmljKFRlc3REaWZmW1sxXV0kc3RhdGlzdGljKSwyKWAgYW5kIGl0IHdhcyBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIDAuIFNvIHRoZSBlZmZlY3QgaXMgYmlnZ2VyIGZvciBBdXRob3JpdGF0aXZlIHBhcmVudGluZyBhcyB3ZSBwcmVkaWN0ZWQuIA0KDQoNCiMgUmVmZXJlbmNlcw0KQmFyb24sIFIuIE0uLCAmIEtlbm55LCBELiBBLiAoMTk4NikuIFRoZSBtb2RlcmF0b3ItbWVkaWF0b3IgdmFyaWFibGUgZGlzdGluY3Rpb24gaW4gc29jaWFsIHBzeWNob2xvZ2ljYWwgcmVzZWFyY2g6IENvbmNlcHR1YWwsIHN0cmF0ZWdpYywgYW5kIHN0YXRpc3RpY2FsIGNvbnNpZGVyYXRpb25zLiAqSm91cm5hbCBvZiBwZXJzb25hbGl0eSBhbmQgc29jaWFsIHBzeWNob2xvZ3kqLCA1MSg2KSwgMTE3My4NCg0KUHJlYWNoZXIsIEsuIEouLCBSdWNrZXIsIEQuIEQuLCAmIEhheWVzLCBBLiBGLiAoMjAwNykuIEFkZHJlc3NpbmcgbW9kZXJhdGVkIG1lZGlhdGlvbiBoeXBvdGhlc2VzOiBUaGVvcnksIG1ldGhvZHMsIGFuZCBwcmVzY3JpcHRpb25zLiBNdWx0aXZhcmlhdGUgYmVoYXZpb3JhbCByZXNlYXJjaCwgNDIoMSksIDE4NS0yMjcuDQoNCkltYWksIEsuLCBLZWVsZSwgTC4sICYgVGluZ2xleSwgRC4gKDIwMTApLiBBIGdlbmVyYWwgYXBwcm9hY2ggdG8gY2F1c2FsIG1lZGlhdGlvbiBhbmFseXNpcy4gUHN5Y2hvbG9naWNhbCBtZXRob2RzLCAxNSg0KSwgMzA5Lg0KDQoNCjxzY3JpcHQ+DQogIChmdW5jdGlvbihpLHMsbyxnLHIsYSxtKXtpWydHb29nbGVBbmFseXRpY3NPYmplY3QnXT1yO2lbcl09aVtyXXx8ZnVuY3Rpb24oKXsNCiAgKGlbcl0ucT1pW3JdLnF8fFtdKS5wdXNoKGFyZ3VtZW50cyl9LGlbcl0ubD0xKm5ldyBEYXRlKCk7YT1zLmNyZWF0ZUVsZW1lbnQobyksDQogIG09cy5nZXRFbGVtZW50c0J5VGFnTmFtZShvKVswXTthLmFzeW5jPTE7YS5zcmM9ZzttLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsbSkNCiAgfSkod2luZG93LGRvY3VtZW50LCdzY3JpcHQnLCdodHRwczovL3d3dy5nb29nbGUtYW5hbHl0aWNzLmNvbS9hbmFseXRpY3MuanMnLCdnYScpOw0KDQogIGdhKCdjcmVhdGUnLCAnVUEtOTA0MTUxNjAtMScsICdhdXRvJyk7DQogIGdhKCdzZW5kJywgJ3BhZ2V2aWV3Jyk7DQoNCjwvc2NyaXB0Pg0KDQo=