Mediation

  • Baron & Kenny, 1986 (citations as of 4/13/20 =91,339)

  • An extremely common and popular method in social, but now used throughout psychology

  • Baron & Kenny define moderator and mediator for us:

“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”

“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”

  • In short, the mediator explains why X->Y, and it’s through M
  • Having one mediator is called simple mediation.

Simple Mediation

Preacher & Hayes, 2008 explain this figure as:

“X’s causal effect into its indirect effect on Y through M and its direct effect on Y (path c’). Path c’ a represents the effect of X on the proposed mediator, whereas path b is the effect of M on Y partialling out the effect of X. The indirect effect of X on Y through M can then be quantified as the product of a and b (i.e., ab)”

  • The mediation is trying to explain the direct path seen in the total effect (the analysis without the mediation term)

Total Effect

  • So we can connect the total effect back the simple moderation: \[c = c' + ab\]

\[total = direct + indirect\]

Hypothetical Example of Simple Mediation

  • Children with the ability to delay gratification tend to be more successful in life (Marshmallow test)

    • You hypothesize that it is their respect/trust in of authority figures to keep their promises that is intermediating in the causal chain for success in later life
  • You collect 268 4-year-olds, give them the Marshmallow test (measure their time to eat the marshmallow). Rather than waiting 20 years, you operationalize success as how they did at the end of the year on a kindergarten entrance exam. You also measure how must trust they have in authority figures (1-10 scale through an established battery for children)

  • Simulation below

set.seed(42)
# For simulation of mediation steps see Hallgren, 2013
# path a strength
a=.4
# path b strength
b=.4
# path c' strength
cp=.01
# people
n <- 268
# Normal distribution of time (mins)
X <- rnorm(n, 5, 2)
# Mediator
M <- a*X+rnorm(n, 0, 1)
# Our equation to  create Y
Y <- cp*X + b*M + rnorm(n, sd=1)
#Built our data frame
Marshmallow.Data<-data.frame(Time=X,Trust=M,Success=Y)
  • Graph of results
library(GGally)
library(ggplot2)
DiagPlot <- ggpairs(Marshmallow.Data,  
              lower = list(continuous = "smooth"))
DiagPlot+theme_bw()

Baron and Kenny Steps to testing mediation

Step 1: Test Y~X

  • Is there a relationship? If yes you can proceed (if not stop as you have no total effect path to try to mediate)
Model.1<-lm(Success~Time, data= Marshmallow.Data)
Dependent variable:
Success
Intercept 0.027 (0.169)
Time 0.143*** (0.032)
Observations 268
R2 0.070
Adjusted R2 0.067
Residual Std. Error 1.010 (df = 266)
F Statistic 20.096*** (df = 1; 266)
Note: p<0.1; p<0.05; p<0.01

Step 2: Test M~X

  • Is there a relationship? If yes you can proceed (if not stop as you have no path a)
Model.2<-lm(Trust~Time, data= Marshmallow.Data)
Dependent variable:
Trust
Intercept 0.305* (0.168)
Time 0.334*** (0.032)
Observations 268
R2 0.296
Adjusted R2 0.294
Residual Std. Error 1.001 (df = 266)
F Statistic 112.073*** (df = 1; 266)
Note: p<0.1; p<0.05; p<0.01

Step 3: Test Y ~ M + X

  • Is there a relationship? If yes you can proceed (if not stop as you have no path b)
  • X is here as a control for M to predict X (some people say leave it out, Kenny says to leave it in)
Model.3<-lm(Success~Trust+Time, data= Marshmallow.Data)
Dependent variable:
Success
Intercept -0.086 (0.159)
Trust 0.369*** (0.058)
Time 0.019 (0.035)
Observations 268
R2 0.195
Adjusted R2 0.189
Residual Std. Error 0.942 (df = 265)
F Statistic 32.059*** (df = 2; 265)
Note: p<0.1; p<0.05; p<0.01

Step 4: Test X ~ Y + M

  • Establish complete mediation
  • Reverse path: M is here as a control for Y to predict X
  • If there is complete mediation path c’ will go to zero
  • If there is partial mediation path c’ will remain (but should get smaller) if paths a and b were meaningful
Model.4<-lm(Time~Success+Trust, data= Marshmallow.Data)
Dependent variable:
Time
Intercept 3.212*** (0.192)
Success 0.058 (0.106)
Trust 0.864*** (0.093)
Observations 268
R2 0.297
Adjusted R2 0.292
Residual Std. Error 1.632 (df = 265)
F Statistic 56.039*** (df = 2; 265)
Note: p<0.1; p<0.05; p<0.01

Interpretation

  • So we have complete mediation, the c’ prime path went to nearly zero
  • In this case, time was not significant, but it could be with larger samples…
  • The variance of time was explained by the mediator, path ab
    • but how do we test the significance of the mediator, path ab?

Significance of indirect path

  • Well in our case, both path a and b were strong and significant (joint significance)
  • Joint significance is an indirect test of the indirect path and is mostly holds up more modern methods (but you probably cannot publish just by showing significance on paths a and b)
  • We need a direct test the significance of the indirect path (ab)
  • The Baron and Kenny method was to use the Sobel’s test, which estimates the SE on terms ab of our equation, \(c = c' + ab\) and tests it against zero
  • Sobel assumes of paths a and b as independent, it’s very conservative and very low powered (see http://davidakenny.net/cm/mediate.htm for details)
  • There are other tests, but Sobel was the most common in its day
library(bda)
mediation.test(Marshmallow.Data$Trust,Marshmallow.Data$Time,Marshmallow.Data$Success)
##                Sobel       Aroian      Goodman
## z.value 5.478920e+00 5.461111e+00 5.496905e+00
## p.value 4.279292e-08 4.731637e-08 3.865154e-08
  • Bootstrapping has replaced the Sobel’s test so we will focus on using that test in the examples
  • There are two types of bootstrapping, BCa and percentile methods (remember we covered them last semester)
    • BCa can be a bit anti-conservative but more powerful, percentile method is less powerful more conservative

Mediation package in R

  • You will only need Model.2 (M~X) and Model.3 (Y~M+X) from above
    • The language changes a bit in the way we talk about these things as this package can handle larger designs with control variables and many different types of regressions:
      • linear, generalized, and mixed, mixture, censored and survival
        • Note: I did 200 simulations for time, but 2000 is best if you are doing BCa.

BCa Method

library(mediation)
Med.Boot.BCa <- mediate(Model.2, Model.3, boot = TRUE, 
                        boot.ci.type = "bca", sims=200, treat="Time", mediator="Trust")
summary(Med.Boot.BCa)
plot(Med.Boot.BCa)
## 
## Causal Mediation Analysis 
## 
## Nonparametric Bootstrap Confidence Intervals with the BCa Method
## 
##                Estimate 95% CI Lower 95% CI Upper p-value    
## ACME             0.1235       0.0833         0.17  <2e-16 ***
## ADE              0.0194      -0.0413         0.08    0.53    
## Total Effect     0.1429       0.0863         0.20  <2e-16 ***
## Prop. Mediated   0.8644       0.5986         1.81  <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Sample Size Used: 268 
## 
## 
## Simulations: 200

  • ACME: Average Causal Mediation Effects (ACME) [total effect - direct effect]
  • ADE: Average Direct Effects [total effect - indirect effect]
  • Total Effect = Direct (ADE) + Indirect (ACME)
  • These are unstandardized effects
  • Prop. Mediated: Conceptually ACME / Total effect

Percentile Method

  • By changing the code we can get percentile method over BCa
Med.Boot.perc <- mediate(Model.2, Model.3, boot = TRUE, 
                         boot.ci.type = "perc", sims=200, treat="Time", mediator="Trust")
summary(Med.Boot.perc)
plot(Med.Boot.perc)
## 
## Causal Mediation Analysis 
## 
## Nonparametric Bootstrap Confidence Intervals with the Percentile Method
## 
##                Estimate 95% CI Lower 95% CI Upper p-value    
## ACME             0.1235       0.0861         0.17  <2e-16 ***
## ADE              0.0194      -0.0387         0.08    0.54    
## Total Effect     0.1429       0.0859         0.20  <2e-16 ***
## Prop. Mediated   0.8644       0.5703         1.40  <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Sample Size Used: 268 
## 
## 
## Simulations: 200

  • These results match Baron and Kenny and the process macro in SPSS
  • The benefit here is you test mediator in GLM or mixed (cannot be done so easily in SPSS)

Partial Mediation

  • When the direct effect and indirect effect are both true
  • Many times you don’t have the power for complete mediation and you might think its partial mediation
    • Kenny suggests using Hayes (2013) recommendation: never concluding that it’s complete
  • Below I have created a well-powered (power = .80) examine both the direct and indirect effects
set.seed(42)
# path a strength
a=.4
# path b strength
b=.4
# path c' strength
cp=.2
# people
n <- 177
# Normal distribution of time (mins)
X <- rnorm(n, 5, 2)
# Mediator
M <- a*X+rnorm(n, 0, 1)
# Our equation to  create Y
Y <- cp*X + b*M + rnorm(n, sd=1)
#Built our data frame
Marshmallow.Data.Part<-data.frame(Time=X,Trust=M,Success=Y)
  • Graph of results
DiagPlot.2 <- ggpairs(Marshmallow.Data.Part,  
              lower = list(continuous = "smooth"))
DiagPlot.2+theme_bw()

  • Regression Models
Part.Model.2<-lm(Trust~Time, data= Marshmallow.Data.Part)
Part.Model.3<-lm(Success~Trust+Time, data= Marshmallow.Data.Part)
  • Outcome Model
Dependent variable:
Success
Intercept 0.108 (0.213)
Trust 0.408*** (0.086)
Time 0.172*** (0.054)
Observations 177
R2 0.358
Adjusted R2 0.351
Residual Std. Error 1.055 (df = 174)
F Statistic 48.519*** (df = 2; 174)
Note: p<0.1; p<0.05; p<0.01
  • Mediation Analysis
Part.Med.Boot.BCa <- mediate(Part.Model.2, Part.Model.3, boot = TRUE,
                             boot.ci.type = "bca", sims=200, 
                             treat="Time", mediator="Trust")
summary(Part.Med.Boot.BCa)
plot(Part.Med.Boot.BCa,xlim=c(0,.5))
## 
## Causal Mediation Analysis 
## 
## Nonparametric Bootstrap Confidence Intervals with the BCa Method
## 
##                Estimate 95% CI Lower 95% CI Upper p-value    
## ACME             0.1726       0.0956         0.25  <2e-16 ***
## ADE              0.1724       0.0738         0.28  <2e-16 ***
## Total Effect     0.3450       0.2665         0.43  <2e-16 ***
## Prop. Mediated   0.5002       0.2644         0.75  <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Sample Size Used: 177 
## 
## 
## Simulations: 200

Partial Mediation with Binary Mediator

  • What if your mediator is binary (GLM)? Medation package lets us test this.
  • Simulation below of when the direct effect and indirect effect are both true
set.seed(42)
# path a strength
a=.5
# path b strength
b=3
# path c' strength
cp=.2
# people
n <- 1000
# Normal distribution of time (mins)
X <- rnorm(n, 5, 2)
# Mediator
z =  a*scale(X,scale=F) + rnorm(n, 0, .2)         
pr = 1/(1+exp(-z)) # pass through an inv-logit function
M = rbinom(n,1,pr)
# Our equation to  create Y
Y <- cp*X + b*M + rnorm(n, sd=1.5)
#Built our data frame
Marshmallow.Data.Bi<-data.frame(Time=X,Trust=M,Success=Y)
  • Graph of results
DiagPlot.3 <- ggpairs(Marshmallow.Data.Bi,  
              lower = list(continuous = "smooth"))
DiagPlot.3+theme_bw()

  • Regression Models
Bi.Model.2<-glm(Trust~Time, data= Marshmallow.Data.Bi,
                binomial(link = "logit"))
Bi.Model.3<-lm(Success~Trust+Time, data= Marshmallow.Data.Bi)
  • Plot Moderator Model
plot_model(Bi.Model.2, type = "pred", axis.lim=c(0,1),
           terms=c("Time"))+theme_sjplot2()

  • Outcome Model
Dependent variable:
Success
Intercept -0.058 (0.131)
Trust 3.127*** (0.108)
Time 0.192*** (0.027)
Observations 1,000
R2 0.565
Adjusted R2 0.564
Residual Std. Error 1.549 (df = 997)
F Statistic 646.417*** (df = 2; 997)
Note: p<0.1; p<0.05; p<0.01
  • Mediation Analysis
Bi.Med.Boot.BCa <- mediate(Bi.Model.2, Bi.Model.3, boot = TRUE,
                             boot.ci.type = "perc", sims=200, 
                             treat="Time", mediator="Trust")
summary(Bi.Med.Boot.BCa)
plot(Bi.Med.Boot.BCa,xlim=c(0,1))
## 
## Causal Mediation Analysis 
## 
## Nonparametric Bootstrap Confidence Intervals with the Percentile Method
## 
##                Estimate 95% CI Lower 95% CI Upper p-value    
## ACME             0.0969       0.0601         0.21  <2e-16 ***
## ADE              0.1919       0.1407         0.24  <2e-16 ***
## Total Effect     0.2888       0.2419         0.42  <2e-16 ***
## Prop. Mediated   0.3357       0.2241         0.54  <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Sample Size Used: 1000 
## 
## 
## Simulations: 200

Power Analysis for Mediation

  • When you plan to run mediation, you must carefully think about the power you might need.
  • Because the M is collinear X you will need more subjects than you would normally think
  • Kenny has worked out an easy app to estimate power for simple designs
  • For larger designs, you need to build custom Monte-Carlo simulation,
    • To help simplify the Monte-Carlo simulation process you can use a shiny package built by Schoemann et al., 2017.
#library(shiny)
#runGitHub("mc_power_med", "schoam4")
  • For this GUI you will need the correlations and \(SD\) between the terms
    • Here is code you can run to get that information
    • the apply function lets you calcuate \(SD\) across columns
apply(Marshmallow.Data.Part, 2, sd)
cor(Marshmallow.Data.Part)
##     Time    Trust  Success 
## 1.988666 1.250198 1.308786 
##              Time     Trust   Success
## Time    1.0000000 0.6727299 0.5242426
## Trust   0.6727299 1.0000000 0.5660804
## Success 0.5242426 0.5660804 1.0000000

Structural Equation Models [SEM] approach to Regression [Notes on SEM from Ryne Estabrook]

SEM is a unique method in that it uses visual diagrams as one way to describe a model.

  • A path diagram contains all information required to specify a structural equation model.
  • It contains (labeled), circles, squares, and arrows.

Path diagrams

Path diagrams are a way to present structural equation models. One uses specific shapes to represent variables and their relationships with one another.

There are two types of variables:

  • Manifest variables (directly measured or observed) are represented by squares.

Other things you might see: - Triangles, which represent constants and typically are labeled “1”. - Diamonds, which deal with special functions (thresholds).

Relationships between variables are expressed as lines (paths) with one or two arrow heads.

Arrows

Two-headed arrows represent covariances or variances.

  • If the heads of the arrow point to different variables, it’s a covariance.
  • If both heads point to the same variable, it’s a variance (Cov(X,X)=Var(X)).

Correlation is a special type of covariance. If you want results in terms of correlations, request standardized results or make adjustment to your model.

One-headed arrows represent regressions.

  • The variable pointed to is the dependent variable,
  • regressed on the independent variable.

Regression in SEM

Regular regression (with a path diagram)

library(semPlot)
C.Path<-lm(Success~Time, data= Marshmallow.Data.Part)
summary(C.Path)
semPaths(C.Path, "est",
         edge.label.cex = 1,
         rotation=2,
         residuals=FALSE,
         sizeMan=10,
         color=c("blue"),
         edge.color="black",
         fade=FALSE)
## 
## Call:
## lm(formula = Success ~ Time, data = Marshmallow.Data.Part)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2.5266 -0.6639 -0.0146  0.7010  3.2600 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.05317    0.22524   0.236    0.814    
## Time         0.34502    0.04237   8.144 6.96e-14 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.118 on 175 degrees of freedom
## Multiple R-squared:  0.2748, Adjusted R-squared:  0.2707 
## F-statistic: 66.32 on 1 and 175 DF,  p-value: 6.958e-14

In the Laavan package (http://lavaan.ugent.be/tutorial/est.html) you write out the equations: \(Y = B_1X_1+B_0\), \(Y = Slope*X+Intercept\). I will call slope \(c\), as this would be the direct pathway in mediation. This model with fit will default to MLE (like in GLM) and we will bootstrap.

For the bootstrap there are two options:

  • (se = “bootstrap”) which bootstraps to get standard errors
  • (test = “bootstrap”) bootstrap based p-value

But the results should match our regression above closely. Also we can force the model to fit to fit via least squares (but we will keep it ML).

library(lavaan)
# parameters
C.lavaan <- ' # regressions
              Success ~ c*Time
              
              #Intercept
               Success ~ 1
            '

# fit model with ML
C.Fit.ML <- sem(model = C.lavaan,
            data = Marshmallow.Data.Part,
            estimator = "ML",
            se = "bootstrap",
            bootstrap = 200)

# view summary
summary(C.Fit.ML,
        fit.measures = FALSE,
        standardize = TRUE,
        rsquare = TRUE)
## lavaan 0.6-12 ended normally after 11 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                         3
## 
##   Number of observations                           177
## 
## Model Test User Model:
##                                                       
##   Test statistic                                 0.000
##   Degrees of freedom                                 0
## 
## Parameter Estimates:
## 
##   Standard errors                            Bootstrap
##   Number of requested bootstrap draws              200
##   Number of successful bootstrap draws             200
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   Success ~                                                             
##     Time       (c)    0.345    0.041    8.407    0.000    0.345    0.524
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .Success           0.053    0.221    0.241    0.810    0.053    0.041
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .Success           1.235    0.136    9.065    0.000    1.235    0.725
## 
## R-Square:
##                    Estimate
##     Success           0.275

Plot

You can plot model estimated values.

library(semPlot)
semPaths(C.Fit.ML, "est",       
         edge.label.cex = 1,
         rotation=2,
         residuals=FALSE,
         sizeMan=10,
         color=c("blue"),
         edge.color="black",
         fade=FALSE)

Intercept is a constant

You dont need to solve of the intercept (and we can plot standardized values)

# parameters
C.lavaan.2 <- ' # regressions
              Success ~ c*Time
            '

# fit model with ML
C.Fit.ML.2 <- sem(model = C.lavaan.2,
            data = Marshmallow.Data.Part,
            estimator = "ML",
            se = "bootstrap",
            bootstrap = 200)

# view summary
summary(C.Fit.ML.2,
        fit.measures = FALSE,
        standardize = TRUE,
        rsquare = TRUE)
## lavaan 0.6-12 ended normally after 1 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                         2
## 
##   Number of observations                           177
## 
## Model Test User Model:
##                                                       
##   Test statistic                                 0.000
##   Degrees of freedom                                 0
## 
## Parameter Estimates:
## 
##   Standard errors                            Bootstrap
##   Number of requested bootstrap draws              200
##   Number of successful bootstrap draws             200
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   Success ~                                                             
##     Time       (c)    0.345    0.041    8.390    0.000    0.345    0.524
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .Success           1.235    0.120   10.253    0.000    1.235    0.725
## 
## R-Square:
##                    Estimate
##     Success           0.275
semPaths(C.Fit.ML.2, "std", 
         edge.label.cex = 1,
         rotation=2,
         residuals=FALSE,
         sizeMan=10,
         color=c("blue"),
         edge.color="black",
         fade=FALSE)

Review Mediation using Mediation package

library(mediation)
Part.Model.2<-lm(Trust~Time, data= Marshmallow.Data.Part)
Part.Model.3<-lm(Success~Trust+Time, data= Marshmallow.Data.Part)

Part.Med.Boot.BCa <- mediate(Part.Model.2, Part.Model.3, boot = TRUE,
                             boot.ci.type = "bca", sims=200, 
                             treat="Time", mediator="Trust")
summary(Part.Med.Boot.BCa)
## 
## Causal Mediation Analysis 
## 
## Nonparametric Bootstrap Confidence Intervals with the BCa Method
## 
##                Estimate 95% CI Lower 95% CI Upper p-value    
## ACME             0.1726       0.0934         0.24  <2e-16 ***
## ADE              0.1724       0.0926         0.29  <2e-16 ***
## Total Effect     0.3450       0.2645         0.42  <2e-16 ***
## Prop. Mediated   0.5002       0.2796         0.74  <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Sample Size Used: 177 
## 
## 
## Simulations: 200

Mediation through SEM

For details on the package see here: http://lavaan.ugent.be/tutorial/syntax1.html

Note: := below assignes paramaters on the fly.

library(lavaan)

# parameters
hayes4 <- ' # direct effect
              Success ~ c*Time
              direct := c

            # regressions
              Trust ~ a*Time
              Success ~ b*Trust

            # indirect effect (a*b)
              indirect := a*b

            # total effect
              total := c + (a*b)

            # Prop
              prop := indirect/total'
 
# fit model
sem4 <- sem(model = hayes4,
            data = Marshmallow.Data.Part,
            se = "bootstrap",
            bootstrap = 200)
# fit measures
summary(sem4,
        fit.measures = FALSE,
        standardize = TRUE,
        rsquare = TRUE)
## lavaan 0.6-12 ended normally after 1 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                         5
## 
##   Number of observations                           177
## 
## Model Test User Model:
##                                                       
##   Test statistic                                 0.000
##   Degrees of freedom                                 0
## 
## Parameter Estimates:
## 
##   Standard errors                            Bootstrap
##   Number of requested bootstrap draws              200
##   Number of successful bootstrap draws             200
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   Success ~                                                             
##     Time       (c)    0.172    0.052    3.309    0.001    0.172    0.262
##   Trust ~                                                               
##     Time       (a)    0.423    0.034   12.467    0.000    0.423    0.673
##   Success ~                                                             
##     Trust      (b)    0.408    0.091    4.471    0.000    0.408    0.390
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .Success           1.093    0.118    9.237    0.000    1.093    0.642
##    .Trust             0.851    0.091    9.319    0.000    0.851    0.547
## 
## R-Square:
##                    Estimate
##     Success           0.358
##     Trust             0.453
## 
## Defined Parameters:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##     direct            0.172    0.052    3.300    0.001    0.172    0.262
##     indirect          0.173    0.041    4.169    0.000    0.173    0.262
##     total             0.345    0.042    8.253    0.000    0.345    0.524
##     prop              0.500    0.124    4.040    0.000    0.500    0.500

Plot

semPaths(sem4, "std",        
         edge.label.cex = 1,
         rotation=2,
         residuals=FALSE,
         sizeMan=10,
         color=c("blue"),
         edge.color="black",
         fade=FALSE)

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.

Hallgren, K. A. (2013). Conducting simulation studies in the R programming environment. Tutorials in quantitative methods for psychology, 9(2), 43.

Preacher, K. J., & Hayes, A. F. (2008). Asymptotic and resampling strategies for assessing and comparing indirect effects in multiple mediator models. Behavior research methods, 40(3), 879-891.

Schoemann, A. M., Boulton, A. J., & Short, S. D. (2017). Determining power and sample size for simple and complex mediation models. Social Psychological and Personality Science, 8(4), 379-386.

LS0tDQp0aXRsZTogJ01lZGlhdGlvbicNCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBmb250c2l6ZTogOHB0DQogICAgaGlnaGxpZ2h0OiB0ZXh0bWF0ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0aGVtZTogZmxhdGx5DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IG5vDQotLS0NCg0KXHBhZ2VicmVhaw0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChjYWNoZSA9IFRSVUUpDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpICNTaG93IGFsbCBzY3JpcHQgYnkgZGVmYXVsdA0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KG1lc3NhZ2UgPSBGQUxTRSkgI2hpZGUgbWVzc2FnZXMgDQprbml0cjo6b3B0c19jaHVuayRzZXQod2FybmluZyA9ICBGQUxTRSkgI2hpZGUgcGFja2FnZSB3YXJuaW5ncyANCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcud2lkdGg9NCkgI1NldCBkZWZhdWx0IGZpZ3VyZSBzaXplcw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy5oZWlnaHQ9My41KSAjU2V0IGRlZmF1bHQgZmlndXJlIHNpemVzDQprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLmFsaWduPSdjZW50ZXInKSAjU2V0IGRlZmF1bHQgZmlndXJlDQprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLnNob3cgPSAiaG9sZCIpICNTZXQgZGVmYXVsdCBmaWd1cmUNCmtuaXRyOjpvcHRzX2NodW5rJHNldChyZXN1bHRzID0gImhvbGQiKSANCmBgYA0KDQoNCiMgTWVkaWF0aW9uDQotIEJhcm9uICYgS2VubnksIDE5ODYgKGNpdGF0aW9ucyBhcyBvZiA0LzEzLzIwID05MSwzMzkpDQogICAgLSBTZWUgS2VubnkncyB3ZWJzaXRlIGZvciB1c2VmdWwgaW5mb3JtYXRpb246IGh0dHA6Ly9kYXZpZGFrZW5ueS5uZXQvY20vbWVkaWF0ZS5odG0NCi0gQW4gZXh0cmVtZWx5IGNvbW1vbiBhbmQgcG9wdWxhciBtZXRob2QgaW4gc29jaWFsLCBidXQgbm93IHVzZWQgdGhyb3VnaG91dCBwc3ljaG9sb2d5DQoNCi0gQmFyb24gJiBLZW5ueSBkZWZpbmUgbW9kZXJhdG9yIGFuZCBtZWRpYXRvciBmb3IgdXM6DQoNCj4gIlRoZSBtb2RlcmF0b3IgZnVuY3Rpb24gb2YgdGhpcmQgdmFyaWFibGVzLCB3aGljaCBwYXJ0aXRpb25zIGEgZm9jYWwgaW5kZXBlbmRlbnQgdmFyaWFibGUgaW50byBzdWJncm91cHMgdGhhdCBlc3RhYmxpc2ggaXRzIGRvbWFpbnMgb2YgbWF4aW1hbCBlZmZlY3RpdmVuZXNzIHJlZ2FyZGluZyBhIGdpdmVuIGRlcGVuZGVudCB2YXJpYWJsZSINCg0KPiAiVGhlIG1lZGlhdG9yIGZ1bmN0aW9uIG9mIGEgdGhpcmQgdmFyaWFibGUsIHdoaWNoIHJlcHJlc2VudHMgdGhlIGdlbmVyYXRpdmUgbWVjaGFuaXNtIHRocm91Z2ggd2hpY2ggdGhlIGZvY2FsIGluZGVwZW5kZW50IHZhcmlhYmxlIGNhbiBpbmZsdWVuY2UgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSBvZiBpbnRlcmVzdCINCg0KLSBJbiBzaG9ydCwgdGhlIG1lZGlhdG9yIGV4cGxhaW5zIHdoeSBYLT5ZLCBhbmQgaXQncyB0aHJvdWdoIE0NCi0gSGF2aW5nIG9uZSBtZWRpYXRvciBpcyBjYWxsZWQgc2ltcGxlIG1lZGlhdGlvbi4NCg0KIVtTaW1wbGUgTWVkaWF0aW9uXShSZWdyZXNzaW9uQ2xhc3MvRmlndXJlMS5wbmcpDQoNClByZWFjaGVyICYgSGF5ZXMsIDIwMDggZXhwbGFpbiB0aGlzIGZpZ3VyZSBhczogDQoNCj4gIlgncyBjYXVzYWwgZWZmZWN0IGludG8gaXRzIGluZGlyZWN0IGVmZmVjdCBvbiBZIHRocm91Z2ggTSBhbmQgaXRzIGRpcmVjdCBlZmZlY3Qgb24gWSAocGF0aCBjJykuIFBhdGggYycgYSByZXByZXNlbnRzIHRoZSBlZmZlY3Qgb2YgWCBvbiB0aGUgcHJvcG9zZWQgbWVkaWF0b3IsIHdoZXJlYXMgcGF0aCBiIGlzIHRoZSBlZmZlY3Qgb2YgTSBvbiBZIHBhcnRpYWxsaW5nIG91dCB0aGUgZWZmZWN0IG9mIFguIFRoZSBpbmRpcmVjdCBlZmZlY3Qgb2YgWCBvbiBZIHRocm91Z2ggTSBjYW4gdGhlbiBiZSBxdWFudGlmaWVkIGFzIHRoZSBwcm9kdWN0IG9mIGEgYW5kIGIgKGkuZS4sIGFiKSINCg0KLSBUaGUgbWVkaWF0aW9uIGlzIHRyeWluZyB0byBleHBsYWluIHRoZSAqKmRpcmVjdCBwYXRoKiogc2VlbiBpbiB0aGUgKip0b3RhbCBlZmZlY3QqKiAodGhlIGFuYWx5c2lzIHdpdGhvdXQgdGhlIG1lZGlhdGlvbiB0ZXJtKQ0KDQohW1RvdGFsIEVmZmVjdF0oUmVncmVzc2lvbkNsYXNzL0ZpZ3VyZTIucG5nKQ0KDQotIFNvIHdlIGNhbiBjb25uZWN0IHRoZSB0b3RhbCBlZmZlY3QgYmFjayB0aGUgc2ltcGxlIG1vZGVyYXRpb246DQokJGMgPSBjJyArIGFiJCQNCg0KJCR0b3RhbCA9IGRpcmVjdCArIGluZGlyZWN0JCQNCg0KIyBIeXBvdGhldGljYWwgRXhhbXBsZSBvZiBTaW1wbGUgTWVkaWF0aW9uDQotIENoaWxkcmVuIHdpdGggdGhlIGFiaWxpdHkgdG8gZGVsYXkgZ3JhdGlmaWNhdGlvbiB0ZW5kIHRvIGJlIG1vcmUgc3VjY2Vzc2Z1bCBpbiBsaWZlIChNYXJzaG1hbGxvdyB0ZXN0KQ0KICAgIC0gWW91IGh5cG90aGVzaXplIHRoYXQgaXQgaXMgdGhlaXIgcmVzcGVjdC90cnVzdCBpbiBvZiBhdXRob3JpdHkgZmlndXJlcyB0byBrZWVwIHRoZWlyIHByb21pc2VzIHRoYXQgaXMgaW50ZXJtZWRpYXRpbmcgaW4gdGhlIGNhdXNhbCBjaGFpbiBmb3Igc3VjY2VzcyBpbiBsYXRlciBsaWZlDQotIFlvdSBjb2xsZWN0IDI2OCA0LXllYXItb2xkcywgZ2l2ZSB0aGVtIHRoZSBNYXJzaG1hbGxvdyB0ZXN0IChtZWFzdXJlIHRoZWlyIHRpbWUgdG8gZWF0IHRoZSBtYXJzaG1hbGxvdykuIFJhdGhlciB0aGFuIHdhaXRpbmcgMjAgeWVhcnMsIHlvdSBvcGVyYXRpb25hbGl6ZSBzdWNjZXNzIGFzIGhvdyB0aGV5IGRpZCBhdCB0aGUgZW5kIG9mIHRoZSB5ZWFyIG9uIGEga2luZGVyZ2FydGVuIGVudHJhbmNlIGV4YW0uIFlvdSBhbHNvIG1lYXN1cmUgaG93IG11c3QgdHJ1c3QgdGhleSBoYXZlIGluIGF1dGhvcml0eSBmaWd1cmVzICgxLTEwIHNjYWxlIHRocm91Z2ggYW4gZXN0YWJsaXNoZWQgYmF0dGVyeSBmb3IgY2hpbGRyZW4pDQoNCi0gU2ltdWxhdGlvbiBiZWxvdw0KDQpgYGB7ciBkYXRhfQ0Kc2V0LnNlZWQoNDIpDQojIEZvciBzaW11bGF0aW9uIG9mIG1lZGlhdGlvbiBzdGVwcyBzZWUgSGFsbGdyZW4sIDIwMTMNCiMgcGF0aCBhIHN0cmVuZ3RoDQphPS40DQojIHBhdGggYiBzdHJlbmd0aA0KYj0uNA0KIyBwYXRoIGMnIHN0cmVuZ3RoDQpjcD0uMDENCiMgcGVvcGxlDQpuIDwtIDI2OA0KIyBOb3JtYWwgZGlzdHJpYnV0aW9uIG9mIHRpbWUgKG1pbnMpDQpYIDwtIHJub3JtKG4sIDUsIDIpDQojIE1lZGlhdG9yDQpNIDwtIGEqWCtybm9ybShuLCAwLCAxKQ0KIyBPdXIgZXF1YXRpb24gdG8gIGNyZWF0ZSBZDQpZIDwtIGNwKlggKyBiKk0gKyBybm9ybShuLCBzZD0xKQ0KI0J1aWx0IG91ciBkYXRhIGZyYW1lDQpNYXJzaG1hbGxvdy5EYXRhPC1kYXRhLmZyYW1lKFRpbWU9WCxUcnVzdD1NLFN1Y2Nlc3M9WSkNCmBgYA0KDQotIEdyYXBoIG9mIHJlc3VsdHMNCmBgYHtyIHBsb3R0ZXIsZmlnLndpZHRoPTQuMjUsZmlnLmhlaWdodD0zLjc1fQ0KbGlicmFyeShHR2FsbHkpDQpsaWJyYXJ5KGdncGxvdDIpDQpEaWFnUGxvdCA8LSBnZ3BhaXJzKE1hcnNobWFsbG93LkRhdGEsICANCiAgICAgICAgICAgICAgbG93ZXIgPSBsaXN0KGNvbnRpbnVvdXMgPSAic21vb3RoIikpDQpEaWFnUGxvdCt0aGVtZV9idygpDQpgYGANCg0KIyMgQmFyb24gYW5kIEtlbm55IFN0ZXBzIHRvIHRlc3RpbmcgbWVkaWF0aW9uDQojIyMgU3RlcCAxOiBUZXN0IFl+WA0KLSBJcyB0aGVyZSBhIHJlbGF0aW9uc2hpcD8gSWYgeWVzIHlvdSBjYW4gcHJvY2VlZCAoaWYgbm90IHN0b3AgYXMgeW91IGhhdmUgbm8gdG90YWwgZWZmZWN0IHBhdGggdG8gdHJ5IHRvIG1lZGlhdGUpDQoNCmBgYHtyfQ0KTW9kZWwuMTwtbG0oU3VjY2Vzc35UaW1lLCBkYXRhPSBNYXJzaG1hbGxvdy5EYXRhKQ0KYGBgDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJ30NCmxpYnJhcnkoc3RhcmdhemVyKQ0Kc3RhcmdhemVyKE1vZGVsLjEsdHlwZT0iaHRtbCIsDQogICAgICAgICAgaW50ZXJjZXB0LmJvdHRvbSA9IEZBTFNFLCBzaW5nbGUucm93PVRSVUUsIA0KICAgICAgICAgIG5vdGVzLmFwcGVuZCA9IEZBTFNFLCBoZWFkZXI9RkFMU0UsDQogICAgICAgICAgY292YXJpYXRlLmxhYmVscz0oIkludGVyY2VwdCIpLGZsb2F0PVRSVUUpDQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0V9DQpsaWJyYXJ5KHNqUGxvdCkNCnBsb3RfbW9kZWwoTW9kZWwuMSwgdHlwZSA9ICJwcmVkIiwNCiAgICAgICAgICAgdGVybXM9YygiVGltZSIpKSt0aGVtZV9zanBsb3QyKCkNCmBgYA0KDQoNCiMjIyBTdGVwIDI6IFRlc3QgTX5YDQotIElzIHRoZXJlIGEgcmVsYXRpb25zaGlwPyBJZiB5ZXMgeW91IGNhbiBwcm9jZWVkIChpZiBub3Qgc3RvcCBhcyB5b3UgaGF2ZSBubyBwYXRoIGEpDQoNCmBgYHtyfQ0KTW9kZWwuMjwtbG0oVHJ1c3R+VGltZSwgZGF0YT0gTWFyc2htYWxsb3cuRGF0YSkNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9DQpzdGFyZ2F6ZXIoTW9kZWwuMix0eXBlPSJodG1sIiwNCiAgICAgICAgICBpbnRlcmNlcHQuYm90dG9tID0gRkFMU0UsIHNpbmdsZS5yb3c9VFJVRSwgDQogICAgICAgICAgbm90ZXMuYXBwZW5kID0gRkFMU0UsIGhlYWRlcj1GQUxTRSwNCiAgICAgICAgICBjb3ZhcmlhdGUubGFiZWxzPSgiSW50ZXJjZXB0IiksZmxvYXQ9VFJVRSkNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCnBsb3RfbW9kZWwoTW9kZWwuMiwgdHlwZSA9ICJwcmVkIiwNCiAgICAgICAgICAgdGVybXM9YygiVGltZSIpKSt0aGVtZV9zanBsb3QyKCkNCmBgYA0KDQojIyMgU3RlcCAzOiBUZXN0IFkgfiBNICsgWA0KLSBJcyB0aGVyZSBhIHJlbGF0aW9uc2hpcD8gSWYgeWVzIHlvdSBjYW4gcHJvY2VlZCAoaWYgbm90IHN0b3AgYXMgeW91IGhhdmUgbm8gcGF0aCBiKQ0KLSBYIGlzIGhlcmUgYXMgYSBjb250cm9sIGZvciBNIHRvIHByZWRpY3QgWCAoc29tZSBwZW9wbGUgc2F5IGxlYXZlIGl0IG91dCwgS2Vubnkgc2F5cyB0byBsZWF2ZSBpdCBpbikNCg0KYGBge3J9DQpNb2RlbC4zPC1sbShTdWNjZXNzflRydXN0K1RpbWUsIGRhdGE9IE1hcnNobWFsbG93LkRhdGEpDQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnfQ0Kc3RhcmdhemVyKE1vZGVsLjMsdHlwZT0iaHRtbCIsDQogICAgICAgICAgaW50ZXJjZXB0LmJvdHRvbSA9IEZBTFNFLCBzaW5nbGUucm93PVRSVUUsIA0KICAgICAgICAgIG5vdGVzLmFwcGVuZCA9IEZBTFNFLCBoZWFkZXI9RkFMU0UsDQogICAgICAgICAgY292YXJpYXRlLmxhYmVscz0oIkludGVyY2VwdCIpLGZsb2F0PVRSVUUpDQpgYGANCg0KIyMjIFN0ZXAgNDogVGVzdCBYIH4gWSArIE0NCi0gRXN0YWJsaXNoIGNvbXBsZXRlIG1lZGlhdGlvbg0KLSBSZXZlcnNlIHBhdGg6IE0gaXMgaGVyZSBhcyBhIGNvbnRyb2wgZm9yIFkgdG8gcHJlZGljdCBYDQotIElmIHRoZXJlIGlzICpjb21wbGV0ZSogbWVkaWF0aW9uIHBhdGggYycgd2lsbCBnbyB0byB6ZXJvDQotIElmIHRoZXJlIGlzICpwYXJ0aWFsKiBtZWRpYXRpb24gcGF0aCBjJyB3aWxsIHJlbWFpbiAoYnV0IHNob3VsZCBnZXQgc21hbGxlcikgaWYgcGF0aHMgYSBhbmQgYiB3ZXJlIG1lYW5pbmdmdWwNCg0KYGBge3IsIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCk1vZGVsLjQ8LWxtKFRpbWV+U3VjY2VzcytUcnVzdCwgZGF0YT0gTWFyc2htYWxsb3cuRGF0YSkNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9DQpzdGFyZ2F6ZXIoTW9kZWwuNCx0eXBlPSJodG1sIiwNCiAgICAgICAgICBpbnRlcmNlcHQuYm90dG9tID0gRkFMU0UsIHNpbmdsZS5yb3c9VFJVRSwgDQogICAgICAgICAgbm90ZXMuYXBwZW5kID0gRkFMU0UsIGhlYWRlcj1GQUxTRSwNCiAgICAgICAgICBjb3ZhcmlhdGUubGFiZWxzPSgiSW50ZXJjZXB0IiksZmxvYXQ9VFJVRSkNCmBgYA0KDQojIyBJbnRlcnByZXRhdGlvbg0KLSBTbyB3ZSBoYXZlIGNvbXBsZXRlIG1lZGlhdGlvbiwgdGhlIGMnIHByaW1lIHBhdGggd2VudCB0byBuZWFybHkgemVybyANCi0gSW4gdGhpcyBjYXNlLCB0aW1lIHdhcyBub3Qgc2lnbmlmaWNhbnQsIGJ1dCBpdCBjb3VsZCBiZSB3aXRoIGxhcmdlciBzYW1wbGVzLi4uDQotIFRoZSB2YXJpYW5jZSBvZiB0aW1lIHdhcyBleHBsYWluZWQgYnkgdGhlIG1lZGlhdG9yLCBwYXRoIGFiDQogICAgLSBidXQgaG93IGRvIHdlIHRlc3QgdGhlIHNpZ25pZmljYW5jZSBvZiB0aGUgbWVkaWF0b3IsIHBhdGggYWI/DQoNCiMjIFNpZ25pZmljYW5jZSBvZiBpbmRpcmVjdCBwYXRoDQotIFdlbGwgaW4gb3VyIGNhc2UsIGJvdGggcGF0aCBhIGFuZCBiIHdlcmUgc3Ryb25nIGFuZCBzaWduaWZpY2FudCAoam9pbnQgc2lnbmlmaWNhbmNlKSANCi0gSm9pbnQgc2lnbmlmaWNhbmNlIGlzIGFuIGluZGlyZWN0IHRlc3Qgb2YgdGhlIGluZGlyZWN0IHBhdGggYW5kIGlzIG1vc3RseSBob2xkcyB1cCBtb3JlIG1vZGVybiBtZXRob2RzIChidXQgeW91IHByb2JhYmx5IGNhbm5vdCBwdWJsaXNoIGp1c3QgYnkgc2hvd2luZyBzaWduaWZpY2FuY2Ugb24gcGF0aHMgYSBhbmQgYikNCi0gV2UgbmVlZCBhIGRpcmVjdCB0ZXN0IHRoZSBzaWduaWZpY2FuY2Ugb2YgdGhlIGluZGlyZWN0IHBhdGggKGFiKQ0KLSBUaGUgQmFyb24gYW5kIEtlbm55IG1ldGhvZCB3YXMgdG8gdXNlIHRoZSBTb2JlbCdzIHRlc3QsIHdoaWNoIGVzdGltYXRlcyB0aGUgU0Ugb24gdGVybXMgYWIgb2Ygb3VyIGVxdWF0aW9uLCAkYyA9IGMnICsgYWIkIGFuZCB0ZXN0cyBpdCBhZ2FpbnN0IHplcm8NCi0gU29iZWwgYXNzdW1lcyBvZiBwYXRocyBhIGFuZCBiIGFzIGluZGVwZW5kZW50LCBpdCdzIHZlcnkgY29uc2VydmF0aXZlIGFuZCB2ZXJ5IGxvdyBwb3dlcmVkIChzZWUgaHR0cDovL2RhdmlkYWtlbm55Lm5ldC9jbS9tZWRpYXRlLmh0bSBmb3IgZGV0YWlscykNCi0gVGhlcmUgYXJlIG90aGVyIHRlc3RzLCBidXQgU29iZWwgd2FzIHRoZSBtb3N0IGNvbW1vbiBpbiBpdHMgZGF5DQoNCmBgYHtyfQ0KbGlicmFyeShiZGEpDQptZWRpYXRpb24udGVzdChNYXJzaG1hbGxvdy5EYXRhJFRydXN0LE1hcnNobWFsbG93LkRhdGEkVGltZSxNYXJzaG1hbGxvdy5EYXRhJFN1Y2Nlc3MpDQpgYGANCg0KLSBCb290c3RyYXBwaW5nIGhhcyByZXBsYWNlZCB0aGUgU29iZWwncyB0ZXN0IHNvIHdlIHdpbGwgZm9jdXMgb24gdXNpbmcgdGhhdCB0ZXN0IGluIHRoZSBleGFtcGxlcw0KLSBUaGVyZSBhcmUgdHdvIHR5cGVzIG9mIGJvb3RzdHJhcHBpbmcsIEJDYSBhbmQgcGVyY2VudGlsZSBtZXRob2RzIChyZW1lbWJlciB3ZSBjb3ZlcmVkIHRoZW0gbGFzdCBzZW1lc3RlcikNCiAgICAtIEJDYSBjYW4gYmUgYSBiaXQgYW50aS1jb25zZXJ2YXRpdmUgYnV0IG1vcmUgcG93ZXJmdWwsIHBlcmNlbnRpbGUgbWV0aG9kIGlzIGxlc3MgcG93ZXJmdWwgbW9yZSBjb25zZXJ2YXRpdmUgDQoNCiMjIE1lZGlhdGlvbiBwYWNrYWdlIGluIFINCi0gWW91IHdpbGwgb25seSBuZWVkIE1vZGVsLjIgKE1+WCkgYW5kIE1vZGVsLjMgKFl+TStYKSBmcm9tIGFib3ZlDQogICAgLSBUaGUgbGFuZ3VhZ2UgY2hhbmdlcyBhIGJpdCBpbiB0aGUgd2F5IHdlIHRhbGsgYWJvdXQgdGhlc2UgdGhpbmdzIGFzIHRoaXMgcGFja2FnZSBjYW4gaGFuZGxlIGxhcmdlciBkZXNpZ25zIHdpdGggY29udHJvbCB2YXJpYWJsZXMgYW5kIG1hbnkgZGlmZmVyZW50IHR5cGVzIG9mIHJlZ3Jlc3Npb25zOiANCiAgICAgICAgLSBsaW5lYXIsIGdlbmVyYWxpemVkLCBhbmQgbWl4ZWQsIG1peHR1cmUsIGNlbnNvcmVkIGFuZCBzdXJ2aXZhbA0KICAgICAgICAgICAgLSBOb3RlOiBJIGRpZCAyMDAgc2ltdWxhdGlvbnMgZm9yIHRpbWUsIGJ1dCAyMDAwIGlzIGJlc3QgaWYgeW91IGFyZSBkb2luZyBCQ2EuDQoNCiMjIyBCQ2EgTWV0aG9kICAgICAgICAgICAgDQpgYGB7ciwgZWNobz1UUlVFfQ0KbGlicmFyeShtZWRpYXRpb24pDQpNZWQuQm9vdC5CQ2EgPC0gbWVkaWF0ZShNb2RlbC4yLCBNb2RlbC4zLCBib290ID0gVFJVRSwgDQogICAgICAgICAgICAgICAgICAgICAgICBib290LmNpLnR5cGUgPSAiYmNhIiwgc2ltcz0yMDAsIHRyZWF0PSJUaW1lIiwgbWVkaWF0b3I9IlRydXN0IikNCnN1bW1hcnkoTWVkLkJvb3QuQkNhKQ0KcGxvdChNZWQuQm9vdC5CQ2EpDQpgYGANCg0KLSBBQ01FOiBBdmVyYWdlIENhdXNhbCBNZWRpYXRpb24gRWZmZWN0cyAoQUNNRSkgWyp0b3RhbCBlZmZlY3QgLSBkaXJlY3QgZWZmZWN0Kl0NCi0gQURFOiBBdmVyYWdlIERpcmVjdCBFZmZlY3RzIFsqdG90YWwgZWZmZWN0IC0gaW5kaXJlY3QgZWZmZWN0Kl0NCi0gVG90YWwgRWZmZWN0ID0gRGlyZWN0IChBREUpICsgSW5kaXJlY3QgKEFDTUUpIA0KLSBUaGVzZSBhcmUgdW5zdGFuZGFyZGl6ZWQgZWZmZWN0cw0KLSBQcm9wLiBNZWRpYXRlZDogIENvbmNlcHR1YWxseSAqQUNNRSAvIFRvdGFsIGVmZmVjdCoNCg0KIyMjIFBlcmNlbnRpbGUgTWV0aG9kDQotIEJ5IGNoYW5naW5nIHRoZSBjb2RlIHdlIGNhbiBnZXQgcGVyY2VudGlsZSBtZXRob2Qgb3ZlciBCQ2ENCg0KYGBge3IsIGVjaG89VFJVRX0NCk1lZC5Cb290LnBlcmMgPC0gbWVkaWF0ZShNb2RlbC4yLCBNb2RlbC4zLCBib290ID0gVFJVRSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgYm9vdC5jaS50eXBlID0gInBlcmMiLCBzaW1zPTIwMCwgdHJlYXQ9IlRpbWUiLCBtZWRpYXRvcj0iVHJ1c3QiKQ0Kc3VtbWFyeShNZWQuQm9vdC5wZXJjKQ0KcGxvdChNZWQuQm9vdC5wZXJjKQ0KYGBgDQoNCi0gVGhlc2UgcmVzdWx0cyBtYXRjaCBCYXJvbiBhbmQgS2VubnkgYW5kIHRoZSBwcm9jZXNzIG1hY3JvIGluIFNQU1MNCi0gVGhlIGJlbmVmaXQgaGVyZSBpcyB5b3UgdGVzdCBtZWRpYXRvciBpbiBHTE0gb3IgbWl4ZWQgKGNhbm5vdCBiZSBkb25lIHNvIGVhc2lseSBpbiBTUFNTKQ0KDQojIFBhcnRpYWwgTWVkaWF0aW9uDQotIFdoZW4gdGhlIGRpcmVjdCBlZmZlY3QgYW5kIGluZGlyZWN0IGVmZmVjdCBhcmUgYm90aCB0cnVlDQotIE1hbnkgdGltZXMgeW91IGRvbid0IGhhdmUgdGhlIHBvd2VyIGZvciBjb21wbGV0ZSBtZWRpYXRpb24gYW5kIHlvdSBtaWdodCB0aGluayBpdHMgcGFydGlhbCBtZWRpYXRpb24NCiAgICAtICoqS2Vubnkgc3VnZ2VzdHMgdXNpbmcgSGF5ZXMgKDIwMTMpIHJlY29tbWVuZGF0aW9uOiBuZXZlciBjb25jbHVkaW5nIHRoYXQgaXQncyBjb21wbGV0ZSoqIA0KLSBCZWxvdyBJIGhhdmUgY3JlYXRlZCBhIHdlbGwtcG93ZXJlZCAocG93ZXIgPSAuODApIGV4YW1pbmUgYm90aCB0aGUgZGlyZWN0IGFuZCBpbmRpcmVjdCBlZmZlY3RzIA0KDQpgYGB7cn0NCnNldC5zZWVkKDQyKQ0KIyBwYXRoIGEgc3RyZW5ndGgNCmE9LjQNCiMgcGF0aCBiIHN0cmVuZ3RoDQpiPS40DQojIHBhdGggYycgc3RyZW5ndGgNCmNwPS4yDQojIHBlb3BsZQ0KbiA8LSAxNzcNCiMgTm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiB0aW1lIChtaW5zKQ0KWCA8LSBybm9ybShuLCA1LCAyKQ0KIyBNZWRpYXRvcg0KTSA8LSBhKlgrcm5vcm0obiwgMCwgMSkNCiMgT3VyIGVxdWF0aW9uIHRvICBjcmVhdGUgWQ0KWSA8LSBjcCpYICsgYipNICsgcm5vcm0obiwgc2Q9MSkNCiNCdWlsdCBvdXIgZGF0YSBmcmFtZQ0KTWFyc2htYWxsb3cuRGF0YS5QYXJ0PC1kYXRhLmZyYW1lKFRpbWU9WCxUcnVzdD1NLFN1Y2Nlc3M9WSkNCmBgYA0KDQotIEdyYXBoIG9mIHJlc3VsdHMNCmBgYHtyLGZpZy53aWR0aD00LjI1LGZpZy5oZWlnaHQ9My43NX0NCkRpYWdQbG90LjIgPC0gZ2dwYWlycyhNYXJzaG1hbGxvdy5EYXRhLlBhcnQsICANCiAgICAgICAgICAgICAgbG93ZXIgPSBsaXN0KGNvbnRpbnVvdXMgPSAic21vb3RoIikpDQpEaWFnUGxvdC4yK3RoZW1lX2J3KCkNCmBgYA0KDQotIFJlZ3Jlc3Npb24gTW9kZWxzDQpgYGB7cn0NClBhcnQuTW9kZWwuMjwtbG0oVHJ1c3R+VGltZSwgZGF0YT0gTWFyc2htYWxsb3cuRGF0YS5QYXJ0KQ0KUGFydC5Nb2RlbC4zPC1sbShTdWNjZXNzflRydXN0K1RpbWUsIGRhdGE9IE1hcnNobWFsbG93LkRhdGEuUGFydCkNCmBgYA0KDQotIE91dGNvbWUgTW9kZWwNCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJ30NCnN0YXJnYXplcihQYXJ0Lk1vZGVsLjMsdHlwZT0iaHRtbCIsDQogICAgICAgICAgaW50ZXJjZXB0LmJvdHRvbSA9IEZBTFNFLCBzaW5nbGUucm93PVRSVUUsIA0KICAgICAgICAgIG5vdGVzLmFwcGVuZCA9IEZBTFNFLCBoZWFkZXI9RkFMU0UsDQogICAgICAgICAgY292YXJpYXRlLmxhYmVscz0oIkludGVyY2VwdCIpLGZsb2F0PVRSVUUpDQpgYGANCg0KLSBNZWRpYXRpb24gQW5hbHlzaXMNCmBgYHtyfQ0KUGFydC5NZWQuQm9vdC5CQ2EgPC0gbWVkaWF0ZShQYXJ0Lk1vZGVsLjIsIFBhcnQuTW9kZWwuMywgYm9vdCA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb3QuY2kudHlwZSA9ICJiY2EiLCBzaW1zPTIwMCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWF0PSJUaW1lIiwgbWVkaWF0b3I9IlRydXN0IikNCnN1bW1hcnkoUGFydC5NZWQuQm9vdC5CQ2EpDQpwbG90KFBhcnQuTWVkLkJvb3QuQkNhLHhsaW09YygwLC41KSkNCmBgYA0KDQojIFBhcnRpYWwgTWVkaWF0aW9uIHdpdGggQmluYXJ5IE1lZGlhdG9yDQotIFdoYXQgaWYgeW91ciBtZWRpYXRvciBpcyBiaW5hcnkgKEdMTSk/IE1lZGF0aW9uIHBhY2thZ2UgbGV0cyB1cyB0ZXN0IHRoaXMuDQotIFNpbXVsYXRpb24gYmVsb3cgb2Ygd2hlbiB0aGUgZGlyZWN0IGVmZmVjdCBhbmQgaW5kaXJlY3QgZWZmZWN0IGFyZSBib3RoIHRydWUNCg0KYGBge3IsIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCnNldC5zZWVkKDQyKQ0KIyBwYXRoIGEgc3RyZW5ndGgNCmE9LjUNCiMgcGF0aCBiIHN0cmVuZ3RoDQpiPTMNCiMgcGF0aCBjJyBzdHJlbmd0aA0KY3A9LjINCiMgcGVvcGxlDQpuIDwtIDEwMDANCiMgTm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiB0aW1lIChtaW5zKQ0KWCA8LSBybm9ybShuLCA1LCAyKQ0KIyBNZWRpYXRvcg0KeiA9ICBhKnNjYWxlKFgsc2NhbGU9RikgKyBybm9ybShuLCAwLCAuMikgICAgICAgICANCnByID0gMS8oMStleHAoLXopKSAjIHBhc3MgdGhyb3VnaCBhbiBpbnYtbG9naXQgZnVuY3Rpb24NCk0gPSByYmlub20obiwxLHByKQ0KIyBPdXIgZXF1YXRpb24gdG8gIGNyZWF0ZSBZDQpZIDwtIGNwKlggKyBiKk0gKyBybm9ybShuLCBzZD0xLjUpDQojQnVpbHQgb3VyIGRhdGEgZnJhbWUNCk1hcnNobWFsbG93LkRhdGEuQmk8LWRhdGEuZnJhbWUoVGltZT1YLFRydXN0PU0sU3VjY2Vzcz1ZKQ0KYGBgDQoNCi0gR3JhcGggb2YgcmVzdWx0cw0KYGBge3IsZmlnLndpZHRoPTQuMjUsZmlnLmhlaWdodD0zLjc1fQ0KRGlhZ1Bsb3QuMyA8LSBnZ3BhaXJzKE1hcnNobWFsbG93LkRhdGEuQmksICANCiAgICAgICAgICAgICAgbG93ZXIgPSBsaXN0KGNvbnRpbnVvdXMgPSAic21vb3RoIikpDQpEaWFnUGxvdC4zK3RoZW1lX2J3KCkNCmBgYA0KDQotIFJlZ3Jlc3Npb24gTW9kZWxzDQpgYGB7cn0NCkJpLk1vZGVsLjI8LWdsbShUcnVzdH5UaW1lLCBkYXRhPSBNYXJzaG1hbGxvdy5EYXRhLkJpLA0KICAgICAgICAgICAgICAgIGJpbm9taWFsKGxpbmsgPSAibG9naXQiKSkNCkJpLk1vZGVsLjM8LWxtKFN1Y2Nlc3N+VHJ1c3QrVGltZSwgZGF0YT0gTWFyc2htYWxsb3cuRGF0YS5CaSkNCmBgYA0KDQotIFBsb3QgTW9kZXJhdG9yIE1vZGVsDQpgYGB7cn0NCnBsb3RfbW9kZWwoQmkuTW9kZWwuMiwgdHlwZSA9ICJwcmVkIiwgYXhpcy5saW09YygwLDEpLA0KICAgICAgICAgICB0ZXJtcz1jKCJUaW1lIikpK3RoZW1lX3NqcGxvdDIoKQ0KYGBgDQoNCi0gT3V0Y29tZSBNb2RlbA0KYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnfQ0Kc3RhcmdhemVyKEJpLk1vZGVsLjMsdHlwZT0iaHRtbCIsDQogICAgICAgICAgaW50ZXJjZXB0LmJvdHRvbSA9IEZBTFNFLCBzaW5nbGUucm93PVRSVUUsIA0KICAgICAgICAgIG5vdGVzLmFwcGVuZCA9IEZBTFNFLCBoZWFkZXI9RkFMU0UsDQogICAgICAgICAgY292YXJpYXRlLmxhYmVscz0oIkludGVyY2VwdCIpLGZsb2F0PVRSVUUpDQpgYGANCg0KLSBNZWRpYXRpb24gQW5hbHlzaXMNCmBgYHtyfQ0KQmkuTWVkLkJvb3QuQkNhIDwtIG1lZGlhdGUoQmkuTW9kZWwuMiwgQmkuTW9kZWwuMywgYm9vdCA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb3QuY2kudHlwZSA9ICJwZXJjIiwgc2ltcz0yMDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVhdD0iVGltZSIsIG1lZGlhdG9yPSJUcnVzdCIpDQpzdW1tYXJ5KEJpLk1lZC5Cb290LkJDYSkNCnBsb3QoQmkuTWVkLkJvb3QuQkNhLHhsaW09YygwLDEpKQ0KYGBgDQoNCiMgUG93ZXIgQW5hbHlzaXMgZm9yIE1lZGlhdGlvbg0KLSBXaGVuIHlvdSBwbGFuIHRvIHJ1biBtZWRpYXRpb24sIHlvdSBtdXN0IGNhcmVmdWxseSB0aGluayBhYm91dCB0aGUgcG93ZXIgeW91IG1pZ2h0IG5lZWQuIA0KLSBCZWNhdXNlIHRoZSBNIGlzIGNvbGxpbmVhciBYIHlvdSB3aWxsIG5lZWQgbW9yZSBzdWJqZWN0cyB0aGFuIHlvdSB3b3VsZCBub3JtYWxseSB0aGluayANCi0gS2VubnkgaGFzIHdvcmtlZCBvdXQgYW4gZWFzeSBhcHAgdG8gZXN0aW1hdGUgcG93ZXIgZm9yIHNpbXBsZSBkZXNpZ25zDQogICAgLSBodHRwczovL2RhdmlkYWtlbm55LnNoaW55YXBwcy5pby9NZWRQb3dlci8NCi0gRm9yIGxhcmdlciBkZXNpZ25zLCB5b3UgbmVlZCB0byBidWlsZCBjdXN0b20gTW9udGUtQ2FybG8gc2ltdWxhdGlvbiwNCiAgICAtIFRvIGhlbHAgc2ltcGxpZnkgdGhlIE1vbnRlLUNhcmxvIHNpbXVsYXRpb24gcHJvY2VzcyB5b3UgY2FuIHVzZSBhIHNoaW55IHBhY2thZ2UgYnVpbHQgYnkgU2Nob2VtYW5uIGV0IGFsLiwgMjAxNy4NCg0KYGBge3IsIGV2YWw9RkFMU0V9DQojbGlicmFyeShzaGlueSkNCiNydW5HaXRIdWIoIm1jX3Bvd2VyX21lZCIsICJzY2hvYW00IikNCmBgYA0KDQotIEZvciB0aGlzIEdVSSB5b3Ugd2lsbCBuZWVkIHRoZSBjb3JyZWxhdGlvbnMgYW5kICRTRCQgYmV0d2VlbiB0aGUgdGVybXMNCiAgICAtIEhlcmUgaXMgY29kZSB5b3UgY2FuIHJ1biB0byBnZXQgdGhhdCBpbmZvcm1hdGlvbg0KICAgIC0gdGhlIGFwcGx5IGZ1bmN0aW9uIGxldHMgeW91IGNhbGN1YXRlICRTRCQgYWNyb3NzIGNvbHVtbnMgDQogICAgDQpgYGB7cn0NCmFwcGx5KE1hcnNobWFsbG93LkRhdGEuUGFydCwgMiwgc2QpDQpjb3IoTWFyc2htYWxsb3cuRGF0YS5QYXJ0KQ0KYGBgDQogICAgDQojIFN0cnVjdHVyYWwgRXF1YXRpb24gTW9kZWxzIFtTRU1dIGFwcHJvYWNoIHRvIFJlZ3Jlc3Npb24gW05vdGVzIG9uIFNFTSBmcm9tIFJ5bmUgRXN0YWJyb29rXQ0KU0VNIGlzIGEgdW5pcXVlIG1ldGhvZCBpbiB0aGF0IGl0IHVzZXMgdmlzdWFsIGRpYWdyYW1zIGFzIG9uZSB3YXkgdG8gZGVzY3JpYmUgYSBtb2RlbC4NCg0KLSBBICoqcGF0aCBkaWFncmFtKiogY29udGFpbnMgYWxsIGluZm9ybWF0aW9uIHJlcXVpcmVkIHRvIHNwZWNpZnkgYSBzdHJ1Y3R1cmFsIGVxdWF0aW9uIG1vZGVsLg0KLSBJdCBjb250YWlucyAobGFiZWxlZCksIGNpcmNsZXMsIHNxdWFyZXMsIGFuZCBhcnJvd3MuDQoNCiMjIFBhdGggZGlhZ3JhbXMNClBhdGggZGlhZ3JhbXMgYXJlIGEgd2F5IHRvIHByZXNlbnQgc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbHMuIE9uZSB1c2VzIHNwZWNpZmljIHNoYXBlcyB0byByZXByZXNlbnQgdmFyaWFibGVzIGFuZCB0aGVpciByZWxhdGlvbnNoaXBzIHdpdGggb25lIGFub3RoZXIuDQoNClRoZXJlIGFyZSB0d28gdHlwZXMgb2YgdmFyaWFibGVzOg0KDQotIE1hbmlmZXN0IHZhcmlhYmxlcyAoZGlyZWN0bHkgbWVhc3VyZWQgb3Igb2JzZXJ2ZWQpIGFyZSByZXByZXNlbnRlZCBieSAqc3F1YXJlcyouDQoNCk90aGVyIHRoaW5ncyB5b3UgbWlnaHQgc2VlOg0KLSBUcmlhbmdsZXMsIHdoaWNoIHJlcHJlc2VudCAqKmNvbnN0YW50cyoqIGFuZCB0eXBpY2FsbHkgYXJlIGxhYmVsZWQg4oCcMSIuDQotIERpYW1vbmRzLCB3aGljaCBkZWFsIHdpdGggc3BlY2lhbCBmdW5jdGlvbnMgKHRocmVzaG9sZHMpLg0KDQpSZWxhdGlvbnNoaXBzIGJldHdlZW4gdmFyaWFibGVzIGFyZSBleHByZXNzZWQgYXMgbGluZXMgKHBhdGhzKSB3aXRoICpvbmUqIG9yICp0d28qIGFycm93IGhlYWRzLg0KDQojIyMgQXJyb3dzDQoNCioqVHdvLWhlYWRlZCBhcnJvd3MgcmVwcmVzZW50IGNvdmFyaWFuY2VzIG9yIHZhcmlhbmNlcy4qKg0KDQotIElmIHRoZSBoZWFkcyBvZiB0aGUgYXJyb3cgcG9pbnQgdG8gZGlmZmVyZW50IHZhcmlhYmxlcywgaXTigJlzIGEgY292YXJpYW5jZS4NCi0gSWYgYm90aCBoZWFkcyBwb2ludCB0byB0aGUgc2FtZSB2YXJpYWJsZSwgaXTigJlzIGEgdmFyaWFuY2UgKENvdihYLFgpPVZhcihYKSkuDQoNCkNvcnJlbGF0aW9uIGlzIGEgc3BlY2lhbCB0eXBlIG9mIGNvdmFyaWFuY2UuIElmIHlvdSB3YW50IHJlc3VsdHMgaW4gdGVybXMgb2YgY29ycmVsYXRpb25zLCByZXF1ZXN0IHN0YW5kYXJkaXplZCByZXN1bHRzIG9yIG1ha2UgYWRqdXN0bWVudCB0byB5b3VyIG1vZGVsLg0KDQoqKk9uZS1oZWFkZWQgYXJyb3dzIHJlcHJlc2VudCByZWdyZXNzaW9ucy4qKg0KDQotIFRoZSB2YXJpYWJsZSBwb2ludGVkIHRvIGlzIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUsDQotIHJlZ3Jlc3NlZCBvbiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGUuDQoNCiMjIFJlZ3Jlc3Npb24gaW4gU0VNDQoNClJlZ3VsYXIgcmVncmVzc2lvbiAod2l0aCBhIHBhdGggZGlhZ3JhbSkNCg0KYGBge3J9DQpsaWJyYXJ5KHNlbVBsb3QpDQpDLlBhdGg8LWxtKFN1Y2Nlc3N+VGltZSwgZGF0YT0gTWFyc2htYWxsb3cuRGF0YS5QYXJ0KQ0Kc3VtbWFyeShDLlBhdGgpDQpzZW1QYXRocyhDLlBhdGgsICJlc3QiLA0KICAgICAgICAgZWRnZS5sYWJlbC5jZXggPSAxLA0KICAgICAgICAgcm90YXRpb249MiwNCiAgICAgICAgIHJlc2lkdWFscz1GQUxTRSwNCiAgICAgICAgIHNpemVNYW49MTAsDQogICAgICAgICBjb2xvcj1jKCJibHVlIiksDQogICAgICAgICBlZGdlLmNvbG9yPSJibGFjayIsDQogICAgICAgICBmYWRlPUZBTFNFKQ0KYGBgDQoNCkluIHRoZSBMYWF2YW4gcGFja2FnZSAoaHR0cDovL2xhdmFhbi51Z2VudC5iZS90dXRvcmlhbC9lc3QuaHRtbCkgeW91IHdyaXRlIG91dCB0aGUgZXF1YXRpb25zOiAkWSA9IEJfMVhfMStCXzAkLCAkWSA9IFNsb3BlKlgrSW50ZXJjZXB0JC4gSSB3aWxsIGNhbGwgc2xvcGUgJGMkLCBhcyB0aGlzIHdvdWxkIGJlIHRoZSBkaXJlY3QgcGF0aHdheSBpbiBtZWRpYXRpb24uIFRoaXMgbW9kZWwgd2l0aCBmaXQgd2lsbCBkZWZhdWx0IHRvICpNTEUqIChsaWtlIGluIEdMTSkgYW5kIHdlIHdpbGwgYm9vdHN0cmFwLiANCg0KRm9yIHRoZSBib290c3RyYXAgdGhlcmUgYXJlIHR3byBvcHRpb25zOg0KDQotIChzZSA9ICJib290c3RyYXAiKSB3aGljaCBib290c3RyYXBzIHRvIGdldCBzdGFuZGFyZCBlcnJvcnMNCi0gKHRlc3QgPSAiYm9vdHN0cmFwIikgYm9vdHN0cmFwIGJhc2VkIHAtdmFsdWUNCg0KQnV0IHRoZSByZXN1bHRzIHNob3VsZCBtYXRjaCBvdXIgcmVncmVzc2lvbiBhYm92ZSBjbG9zZWx5LiBBbHNvIHdlIGNhbiBmb3JjZSB0aGUgbW9kZWwgdG8gZml0IHRvIGZpdCB2aWEgbGVhc3Qgc3F1YXJlcyAoYnV0IHdlIHdpbGwga2VlcCBpdCBNTCkuIA0KDQpgYGB7cn0NCmxpYnJhcnkobGF2YWFuKQ0KIyBwYXJhbWV0ZXJzDQpDLmxhdmFhbiA8LSAnICMgcmVncmVzc2lvbnMNCiAgICAgICAgICAgICAgU3VjY2VzcyB+IGMqVGltZQ0KICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgI0ludGVyY2VwdA0KICAgICAgICAgICAgICAgU3VjY2VzcyB+IDENCiAgICAgICAgICAgICcNCg0KIyBmaXQgbW9kZWwgd2l0aCBNTA0KQy5GaXQuTUwgPC0gc2VtKG1vZGVsID0gQy5sYXZhYW4sDQogICAgICAgICAgICBkYXRhID0gTWFyc2htYWxsb3cuRGF0YS5QYXJ0LA0KICAgICAgICAgICAgZXN0aW1hdG9yID0gIk1MIiwNCiAgICAgICAgICAgIHNlID0gImJvb3RzdHJhcCIsDQogICAgICAgICAgICBib290c3RyYXAgPSAyMDApDQoNCiMgdmlldyBzdW1tYXJ5DQpzdW1tYXJ5KEMuRml0Lk1MLA0KICAgICAgICBmaXQubWVhc3VyZXMgPSBGQUxTRSwNCiAgICAgICAgc3RhbmRhcmRpemUgPSBUUlVFLA0KICAgICAgICByc3F1YXJlID0gVFJVRSkNCmBgYA0KDQojIyMgUGxvdA0KWW91IGNhbiBwbG90IG1vZGVsIGVzdGltYXRlZCB2YWx1ZXMuDQoNCmBgYHtyfQ0KbGlicmFyeShzZW1QbG90KQ0Kc2VtUGF0aHMoQy5GaXQuTUwsICJlc3QiLCAgICAgICANCiAgICAgICAgIGVkZ2UubGFiZWwuY2V4ID0gMSwNCiAgICAgICAgIHJvdGF0aW9uPTIsDQogICAgICAgICByZXNpZHVhbHM9RkFMU0UsDQogICAgICAgICBzaXplTWFuPTEwLA0KICAgICAgICAgY29sb3I9YygiYmx1ZSIpLA0KICAgICAgICAgZWRnZS5jb2xvcj0iYmxhY2siLA0KICAgICAgICAgZmFkZT1GQUxTRSkNCmBgYA0KDQojIyMgSW50ZXJjZXB0IGlzIGEgY29uc3RhbnQNCllvdSBkb250IG5lZWQgdG8gc29sdmUgb2YgdGhlIGludGVyY2VwdCAoYW5kIHdlIGNhbiBwbG90IHN0YW5kYXJkaXplZCB2YWx1ZXMpDQoNCmBgYHtyfQ0KIyBwYXJhbWV0ZXJzDQpDLmxhdmFhbi4yIDwtICcgIyByZWdyZXNzaW9ucw0KICAgICAgICAgICAgICBTdWNjZXNzIH4gYypUaW1lDQogICAgICAgICAgICAnDQoNCiMgZml0IG1vZGVsIHdpdGggTUwNCkMuRml0Lk1MLjIgPC0gc2VtKG1vZGVsID0gQy5sYXZhYW4uMiwNCiAgICAgICAgICAgIGRhdGEgPSBNYXJzaG1hbGxvdy5EYXRhLlBhcnQsDQogICAgICAgICAgICBlc3RpbWF0b3IgPSAiTUwiLA0KICAgICAgICAgICAgc2UgPSAiYm9vdHN0cmFwIiwNCiAgICAgICAgICAgIGJvb3RzdHJhcCA9IDIwMCkNCg0KIyB2aWV3IHN1bW1hcnkNCnN1bW1hcnkoQy5GaXQuTUwuMiwNCiAgICAgICAgZml0Lm1lYXN1cmVzID0gRkFMU0UsDQogICAgICAgIHN0YW5kYXJkaXplID0gVFJVRSwNCiAgICAgICAgcnNxdWFyZSA9IFRSVUUpDQoNCmBgYA0KYGBge3J9DQpzZW1QYXRocyhDLkZpdC5NTC4yLCAic3RkIiwgDQogICAgICAgICBlZGdlLmxhYmVsLmNleCA9IDEsDQogICAgICAgICByb3RhdGlvbj0yLA0KICAgICAgICAgcmVzaWR1YWxzPUZBTFNFLA0KICAgICAgICAgc2l6ZU1hbj0xMCwNCiAgICAgICAgIGNvbG9yPWMoImJsdWUiKSwNCiAgICAgICAgIGVkZ2UuY29sb3I9ImJsYWNrIiwNCiAgICAgICAgIGZhZGU9RkFMU0UpDQpgYGANCg0KDQojIyBSZXZpZXcgTWVkaWF0aW9uIHVzaW5nIE1lZGlhdGlvbiBwYWNrYWdlDQoNCmBgYHtyfQ0KbGlicmFyeShtZWRpYXRpb24pDQpQYXJ0Lk1vZGVsLjI8LWxtKFRydXN0flRpbWUsIGRhdGE9IE1hcnNobWFsbG93LkRhdGEuUGFydCkNClBhcnQuTW9kZWwuMzwtbG0oU3VjY2Vzc35UcnVzdCtUaW1lLCBkYXRhPSBNYXJzaG1hbGxvdy5EYXRhLlBhcnQpDQoNClBhcnQuTWVkLkJvb3QuQkNhIDwtIG1lZGlhdGUoUGFydC5Nb2RlbC4yLCBQYXJ0Lk1vZGVsLjMsIGJvb3QgPSBUUlVFLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib290LmNpLnR5cGUgPSAiYmNhIiwgc2ltcz0yMDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVhdD0iVGltZSIsIG1lZGlhdG9yPSJUcnVzdCIpDQpzdW1tYXJ5KFBhcnQuTWVkLkJvb3QuQkNhKQ0KYGBgDQoNCiMjIE1lZGlhdGlvbiB0aHJvdWdoIFNFTQ0KRm9yIGRldGFpbHMgb24gdGhlIHBhY2thZ2Ugc2VlIGhlcmU6IGh0dHA6Ly9sYXZhYW4udWdlbnQuYmUvdHV0b3JpYWwvc3ludGF4MS5odG1sDQoNCk5vdGU6IDo9IGJlbG93IGFzc2lnbmVzIHBhcmFtYXRlcnMgb24gdGhlIGZseS4gDQoNCmBgYHtyfQ0KbGlicmFyeShsYXZhYW4pDQoNCiMgcGFyYW1ldGVycw0KaGF5ZXM0IDwtICcgIyBkaXJlY3QgZWZmZWN0DQogICAgICAgICAgICAgIFN1Y2Nlc3MgfiBjKlRpbWUNCiAgICAgICAgICAgICAgZGlyZWN0IDo9IGMNCg0KICAgICAgICAgICAgIyByZWdyZXNzaW9ucw0KICAgICAgICAgICAgICBUcnVzdCB+IGEqVGltZQ0KICAgICAgICAgICAgICBTdWNjZXNzIH4gYipUcnVzdA0KDQogICAgICAgICAgICAjIGluZGlyZWN0IGVmZmVjdCAoYSpiKQ0KICAgICAgICAgICAgICBpbmRpcmVjdCA6PSBhKmINCg0KICAgICAgICAgICAgIyB0b3RhbCBlZmZlY3QNCiAgICAgICAgICAgICAgdG90YWwgOj0gYyArIChhKmIpDQoNCiAgICAgICAgICAgICMgUHJvcA0KICAgICAgICAgICAgICBwcm9wIDo9IGluZGlyZWN0L3RvdGFsJw0KIA0KIyBmaXQgbW9kZWwNCnNlbTQgPC0gc2VtKG1vZGVsID0gaGF5ZXM0LA0KICAgICAgICAgICAgZGF0YSA9IE1hcnNobWFsbG93LkRhdGEuUGFydCwNCiAgICAgICAgICAgIHNlID0gImJvb3RzdHJhcCIsDQogICAgICAgICAgICBib290c3RyYXAgPSAyMDApDQojIGZpdCBtZWFzdXJlcw0Kc3VtbWFyeShzZW00LA0KICAgICAgICBmaXQubWVhc3VyZXMgPSBGQUxTRSwNCiAgICAgICAgc3RhbmRhcmRpemUgPSBUUlVFLA0KICAgICAgICByc3F1YXJlID0gVFJVRSkNCmBgYA0KDQojIFBsb3QNCmBgYHtyfQ0Kc2VtUGF0aHMoc2VtNCwgInN0ZCIsICAgICAgICANCiAgICAgICAgIGVkZ2UubGFiZWwuY2V4ID0gMSwNCiAgICAgICAgIHJvdGF0aW9uPTIsDQogICAgICAgICByZXNpZHVhbHM9RkFMU0UsDQogICAgICAgICBzaXplTWFuPTEwLA0KICAgICAgICAgY29sb3I9YygiYmx1ZSIpLA0KICAgICAgICAgZWRnZS5jb2xvcj0iYmxhY2siLA0KICAgICAgICAgZmFkZT1GQUxTRSkNCmBgYA0KDQojIFJlZmVyZW5jZXMNCkJhcm9uLCBSLiBNLiwgJiBLZW5ueSwgRC4gQS4gKDE5ODYpLiBUaGUgbW9kZXJhdG9yLW1lZGlhdG9yIHZhcmlhYmxlIGRpc3RpbmN0aW9uIGluIHNvY2lhbCBwc3ljaG9sb2dpY2FsIHJlc2VhcmNoOiBDb25jZXB0dWFsLCBzdHJhdGVnaWMsIGFuZCBzdGF0aXN0aWNhbCBjb25zaWRlcmF0aW9ucy4gKkpvdXJuYWwgb2YgcGVyc29uYWxpdHkgYW5kIHNvY2lhbCBwc3ljaG9sb2d5KiwgNTEoNiksIDExNzMuDQoNCkhhbGxncmVuLCBLLiBBLiAoMjAxMykuIENvbmR1Y3Rpbmcgc2ltdWxhdGlvbiBzdHVkaWVzIGluIHRoZSBSIHByb2dyYW1taW5nIGVudmlyb25tZW50LiAqVHV0b3JpYWxzIGluIHF1YW50aXRhdGl2ZSBtZXRob2RzIGZvciBwc3ljaG9sb2d5KiwgOSgyKSwgNDMuDQoNClByZWFjaGVyLCBLLiBKLiwgJiBIYXllcywgQS4gRi4gKDIwMDgpLiBBc3ltcHRvdGljIGFuZCByZXNhbXBsaW5nIHN0cmF0ZWdpZXMgZm9yIGFzc2Vzc2luZyBhbmQgY29tcGFyaW5nIGluZGlyZWN0IGVmZmVjdHMgaW4gbXVsdGlwbGUgbWVkaWF0b3IgbW9kZWxzLiAqQmVoYXZpb3IgcmVzZWFyY2ggbWV0aG9kcyosIDQwKDMpLCA4NzktODkxLg0KDQpTY2hvZW1hbm4sIEEuIE0uLCBCb3VsdG9uLCBBLiBKLiwgJiBTaG9ydCwgUy4gRC4gKDIwMTcpLiBEZXRlcm1pbmluZyBwb3dlciBhbmQgc2FtcGxlIHNpemUgZm9yIHNpbXBsZSBhbmQgY29tcGxleCBtZWRpYXRpb24gbW9kZWxzLiAqU29jaWFsIFBzeWNob2xvZ2ljYWwgYW5kIFBlcnNvbmFsaXR5IFNjaWVuY2UqLCA4KDQpLCAzNzktMzg2Lg0KDQo8c2NyaXB0Pg0KICAoZnVuY3Rpb24oaSxzLG8sZyxyLGEsbSl7aVsnR29vZ2xlQW5hbHl0aWNzT2JqZWN0J109cjtpW3JdPWlbcl18fGZ1bmN0aW9uKCl7DQogIChpW3JdLnE9aVtyXS5xfHxbXSkucHVzaChhcmd1bWVudHMpfSxpW3JdLmw9MSpuZXcgRGF0ZSgpO2E9cy5jcmVhdGVFbGVtZW50KG8pLA0KICBtPXMuZ2V0RWxlbWVudHNCeVRhZ05hbWUobylbMF07YS5hc3luYz0xO2Euc3JjPWc7bS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShhLG0pDQogIH0pKHdpbmRvdyxkb2N1bWVudCwnc2NyaXB0JywnaHR0cHM6Ly93d3cuZ29vZ2xlLWFuYWx5dGljcy5jb20vYW5hbHl0aWNzLmpzJywnZ2EnKTsNCg0KICBnYSgnY3JlYXRlJywgJ1VBLTkwNDE1MTYwLTEnLCAnYXV0bycpOw0KICBnYSgnc2VuZCcsICdwYWdldmlldycpOw0KDQo8L3NjcmlwdD4NCg==