In this R Markdown Notebook, I give a few examples on how to plot interactions and marginal effects. Many people, faculy and students alike, often come to the PRC Consultants to understand interactions in different models. This Notebook will outline one important element to interpretting interactions: visualizations.

In R, there are often times multiple packages to perform similar functions given that it is a de-centralized, open sourced software/language. Therefore, I will go through multiple different packages, each with their own pros and cons, to help give more options.

Moderation Effects

We include interactions in our model to test for moderation effects, which can be formally defined as:

If the effect of X on Y depends on M, a moderator effect takes place

## Installing different packages that we will be using throughout this demonstration 
install.packages("car") #An extremely useful/in-depth regression package 
trying URL 'https://cloud.r-project.org/bin/macosx/el-capitan/contrib/3.6/car_3.0-3.tgz'
Content type 'application/x-gzip' length 1590381 bytes (1.5 MB)
==================================================
downloaded 1.5 MB

The downloaded binary packages are in
    /var/folders/1f/vrdsjx2x7lj8kfqywtgw95_m0000gn/T//Rtmp4u0y2n/downloaded_packages
install.packages("stargazer") #Produces easy to read regression results
trying URL 'https://cloud.r-project.org/bin/macosx/el-capitan/contrib/3.6/stargazer_5.2.2.tgz'
Content type 'application/x-gzip' length 621898 bytes (607 KB)
==================================================
downloaded 607 KB

The downloaded binary packages are in
    /var/folders/1f/vrdsjx2x7lj8kfqywtgw95_m0000gn/T//Rtmp4u0y2n/downloaded_packages
install.packages("effects") #We will use this to create our interactions 
trying URL 'https://cloud.r-project.org/bin/macosx/el-capitan/contrib/3.6/effects_4.1-2.tgz'
Content type 'application/x-gzip' length 2833258 bytes (2.7 MB)
==================================================
downloaded 2.7 MB

The downloaded binary packages are in
    /var/folders/1f/vrdsjx2x7lj8kfqywtgw95_m0000gn/T//Rtmp4u0y2n/downloaded_packages
install.packages("ggplot2") #Our incredibly powerful and versatile graphing package 
Error in install.packages : Updating loaded packages
install.packages("sjPlot") #Marginal effects package
trying URL 'https://cloud.r-project.org/bin/macosx/el-capitan/contrib/3.6/sjPlot_2.7.2.tgz'
Content type 'application/x-gzip' length 1479163 bytes (1.4 MB)
==================================================
downloaded 1.4 MB

The downloaded binary packages are in
    /var/folders/1f/vrdsjx2x7lj8kfqywtgw95_m0000gn/T//Rtmp4u0y2n/downloaded_packages
install.packages("ggplot2")
trying URL 'https://cloud.r-project.org/bin/macosx/el-capitan/contrib/3.6/ggplot2_3.2.1.tgz'
Content type 'application/x-gzip' length 3973186 bytes (3.8 MB)
==================================================
downloaded 3.8 MB

The downloaded binary packages are in
    /var/folders/1f/vrdsjx2x7lj8kfqywtgw95_m0000gn/T//Rtmp4u0y2n/downloaded_packages
install.packages("sjmisc") #Marginal effects Package
trying URL 'https://cloud.r-project.org/bin/macosx/el-capitan/contrib/3.6/sjmisc_2.8.2.tgz'
Content type 'application/x-gzip' length 532576 bytes (520 KB)
==================================================
downloaded 520 KB

The downloaded binary packages are in
    /var/folders/1f/vrdsjx2x7lj8kfqywtgw95_m0000gn/T//Rtmp4u0y2n/downloaded_packages
install.packages("dplyr") #For data manipulation
Error in install.packages : Updating loaded packages
install.packages("corrplot") #Visualizing correlations
trying URL 'https://cloud.r-project.org/bin/macosx/el-capitan/contrib/3.6/corrplot_0.84.tgz'
Content type 'application/x-gzip' length 5452777 bytes (5.2 MB)
==================================================
downloaded 5.2 MB

The downloaded binary packages are in
    /var/folders/1f/vrdsjx2x7lj8kfqywtgw95_m0000gn/T//Rtmp4u0y2n/downloaded_packages
install.packages("dplyr")
trying URL 'https://cloud.r-project.org/bin/macosx/el-capitan/contrib/3.6/dplyr_0.8.3.tgz'
Content type 'application/x-gzip' length 6850794 bytes (6.5 MB)
==================================================
downloaded 6.5 MB

The downloaded binary packages are in
    /var/folders/1f/vrdsjx2x7lj8kfqywtgw95_m0000gn/T//Rtmp4u0y2n/downloaded_packages
install.packages("msm")
trying URL 'https://cloud.r-project.org/bin/macosx/el-capitan/contrib/3.6/msm_1.6.7.tgz'
Content type 'application/x-gzip' length 1531698 bytes (1.5 MB)
==================================================
downloaded 1.5 MB

The downloaded binary packages are in
    /var/folders/1f/vrdsjx2x7lj8kfqywtgw95_m0000gn/T//Rtmp4u0y2n/downloaded_packages
install.packages("jtools")
trying URL 'https://cloud.r-project.org/bin/macosx/el-capitan/contrib/3.6/jtools_2.0.1.tgz'
Content type 'application/x-gzip' length 2104486 bytes (2.0 MB)
==================================================
downloaded 2.0 MB

The downloaded binary packages are in
    /var/folders/1f/vrdsjx2x7lj8kfqywtgw95_m0000gn/T//Rtmp4u0y2n/downloaded_packages

For these examples, I will be using a sample dataset coming from my own research on LGBTI policy adoption from 1991-2018. In this first model, we will be predicting a country’s score on an LGBTI Policy Index based on being in the Global South/North, level of democracy, and percent of women in parliament.

Visualizing Correlations

Before starting, I first just want to visualize the correlations of the variables in my dataset

library(corrplot)
corrplot 0.84 loaded
M <- cor(lgbti_data[,2:10]) #dataset is called lgbti_data and I'm getting the correlations for all variables between the 2nd and the 10th variables (the 1st and last variable are strings)

#Plotting the correlations
corrplot(M, method = "color")

#Re-doing the plot but only keeping half of the matrix

corrplot(M, method = "color", type= "upper")

#This time, using the corrplot.mixed function, I'm going to also include the correlation coefficient itself in addition to the color visuals.

corrplot.mixed(M)

Categorical x Continuous Interactions

Now, we are going to move into detecting if we need interaction terms in our model through visual detection. The two variables we will be using are region (Global South vs. Global North) and the percent of women in parliament. These are categorical and continuous variables, respectively.

library(ggplot2)

#QPlot stands for "Quick Plot"

#First, we are going to see if there's any visual association between the percent of women in parliament and more progressive LGBTI policies
qplot(x = women_parliament, y = policy_index,  data = lgbti_data) +
  geom_smooth(method = "lm")  #this option is including the line of best fit


#Now, we are going to see if this association changes based on whether a country is in the Global North or the Global South

qplot(x = women_parliament, y = policy_index, facets = ~region, data = lgbti_data) +
  geom_smooth(method = "lm") + #this option is including the line of best fit
   theme_bw() #Removes the gray background 


#Alternatively, we can plot them on the same graph in case the side by side comparisons were too difficult to visually detect.

qplot(x = women_parliament, y = policy_index, data = lgbti_data, color = region) +
  geom_smooth(method = "lm") + 
   theme_bw()+ #Removes the gray background 
      theme(panel.grid.major=element_blank(),
      panel.grid.minor=element_blank(),
      legend.key = element_blank()) + #Removes the lines 
        xlab("Percent (%) of Women in Parliament") +  #changing the labels of the axes
        ylab("LGBTI Policy Index Score")

Based on this visual inspection, it appears that an interaction term is warranted because the slopes of the two lines are different. The effect of women in parliament on progressive LGBTI policies may be contingent, therefore, on the world region

Modeling Continuous x Categorical Interactions

#Predicting a county's score on the LGBTI Policy Index using women in parliament (continuous) and region (categorical)

lgbti.model.1 <- lm(policy_index ~
                      women_parliament +
                        region,
                         data = lgbti_data)

#Re-Running the model with the interaction
lgbti.model.2 <- lm(policy_index ~
                      women_parliament *    # using the astrisk (*) instead of the plus (+)
                        region,
                         data = lgbti_data)
library(stargazer)

Please cite as: 

 Hlavac, Marek (2018). stargazer: Well-Formatted Regression and Summary Statistics Tables.
 R package version 5.2.2. https://CRAN.R-project.org/package=stargazer 

# Now, we can look at the results from our models to see if there is indeed a significant interaction.


#R does not automatically report the results from a model, we must ask for them. There are a few ways of doing so, the built-in function is to type summary(x). The output isn't visually appealing, however, so I will be using the stargazer package that produces a more quality regression table.

stargazer(lgbti.model.1, lgbti.model.2,type="text", 
          column.labels = c("Main Effects", "Interaction"), 
          intercept.bottom = FALSE, 
          single.row=FALSE,     
          notes.append = FALSE, 
          header=FALSE) 
length of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changednumber of rows of result is not a multiple of vector length (arg 2)

=========================================================================================
                                                     Dependent variable:                 
                                    -----------------------------------------------------
                                                        policy_index                     
                                           Main Effects                Interaction       
                                                (1)                        (2)           
-----------------------------------------------------------------------------------------
Constant                                     2.399***                   1.056***         
                                              (0.097)                    (0.143)         
                                                                                         
women_parliament                             0.072***                   0.136***         
                                              (0.003)                    (0.006)         
                                                                                         
regionGlobal South                           -2.842***                  -1.128***        
                                              (0.083)                    (0.160)         
                                                                                         
women_parliament:regionGlobal South                                     -0.089***        
                                                                         (0.007)         
                                                                                         
-----------------------------------------------------------------------------------------
Observations                                   4,341                      4,341          
R2                                             0.332                      0.355          
Adjusted R2                                    0.332                      0.355          
Residual Std. Error                      2.377 (df = 4338)          2.336 (df = 4337)    
F Statistic                         1,078.067*** (df = 2; 4338) 796.457*** (df = 3; 4337)
=========================================================================================
Note:                                                         *p<0.1; **p<0.05; ***p<0.01

Plotting Categorical x Continuous Interactions using Interactions package

library(jtools) # for summ()

#Besides stargazer, the summ() command in the jtools package also allows for cleaner regression tables.
summ(lgbti.model.2)
MODEL INFO:
Observations: 4341
Dependent Variable: policy_index
Type: OLS linear regression 

MODEL FIT:
F(3,4337) = 796.46, p = 0.00
R² = 0.36
Adj. R² = 0.35 

Standard errors: OLS
----------------------------------------------------------------
                                     Est.   S.E.   t val.      p
--------------------------------- ------- ------ -------- ------
(Intercept)                          1.06   0.14     7.36   0.00
women_parliament                     0.14   0.01    22.59   0.00
regionGlobal South                  -1.13   0.16    -7.06   0.00
women_parliament:regionGlobal       -0.09   0.01   -12.50   0.00
South                                                           
----------------------------------------------------------------
library(interactions)

#Plotting the interactions with the Interaction package
interact_plot(lgbti.model.2, pred = women_parliament, modx = region)


#One thing you'll notice is that the default plot visuals are different for each package

Continuous x Continuous Interactions

Visually inspecting whether two continuous variables are moderating one another and, therefore, in need of an interaction in your model is a bit more difficult. One strategy is to convert one of the continuous variables into factor variables. For example, let’s say that the effect of women in pariament is conditioned on the level of democracy. Since democracy is continuous, I will covert it into three groups: mean and +/- 1 standard deviation from the mean.


#Loading dplyr for data manipulation
library(dplyr)

#I'm putting the democracy variable, polity2_vdem, into an object called "x," which I can then manipulate.

x <- lgbti_data$polity2_vdem

#Now, I am creating a new variable called "democracy" that will group countries together based on their value of x (the polity2_vdem variable)

lgbti_data$democracy <-
  case_when(x > mean(x)+sd(x) ~ "Strongly Democratic",
            x < mean(x)+sd(x) & x > mean(x)-sd(x) ~ "Average Level of Democracy",
            x < mean(x)-sd(x) ~ "Weakly Democratic")

# Seeing how many observations fall into each category
count(lgbti_data, democracy)

Now, we are going to plot this.

library(ggplot2)
lgbti_data %>%  # These symbols are operators that essentially mean "do the following function"
  ggplot() +
  aes(x = women_parliament, y = policy_index, group = democracy, color = democracy) +
  geom_point(color = "grey", alpha = .7) +
    geom_smooth(method = "lm") +
     theme_bw()+ #Removes the gray background 
      theme(panel.grid.major=element_blank(),
      panel.grid.minor=element_blank(),
      legend.key = element_blank()) + #Removes the lines 
        xlab("Percent (%) of Women in Parliament") +  #changing the labels of the axes
        ylab("LGBTI Policy Index Score")

Given that there are different slopes based on the level of democracy, it indeed appears that an interaction effect may again be warranted within our models. Next, we are going to go ahead and test for this.

#Running the model with an interaction
lgbti.model.3 <- lm(policy_index 
                      ~polity2_vdem +
                      women_parliament,
                         data =lgbti_data)

#Re-Running the model with an interaction
lgbti.model.4 <- lm(policy_index 
                      ~polity2_vdem *
                      women_parliament,
                         data =lgbti_data)

stargazer(lgbti.model.3, lgbti.model.4,type="text", 
          column.labels = c("Main Effects", "Interaction"), 
          intercept.bottom = FALSE, 
          single.row=FALSE,     
          notes.append = FALSE, 
          header=FALSE) 
length of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changednumber of rows of result is not a multiple of vector length (arg 2)

=====================================================================================
                                                Dependent variable:                  
                              -------------------------------------------------------
                                                   policy_index                      
                                     Main Effects                 Interaction        
                                          (1)                         (2)            
-------------------------------------------------------------------------------------
Constant                               -0.537***                   -0.174***         
                                        (0.063)                     (0.061)          
                                                                                     
polity2_vdem                           0.206***                     0.020**          
                                        (0.006)                     (0.009)          
                                                                                     
women_parliament                       0.085***                    0.057***          
                                        (0.003)                     (0.003)          
                                                                                     
polity2_vdem:women_parliament                                      0.011***          
                                                                   (0.0004)          
                                                                                     
-------------------------------------------------------------------------------------
Observations                             4,341                       4,341           
R2                                       0.358                       0.446           
Adjusted R2                              0.358                       0.446           
Residual Std. Error                2.331 (df = 4338)           2.165 (df = 4337)     
F Statistic                   1,209.942*** (df = 2; 4338) 1,164.134*** (df = 3; 4337)
=====================================================================================
Note:                                                     *p<0.1; **p<0.05; ***p<0.01

Continuous x Continuous Interaction: Plotting Simple Slopes based on Standard Deviations using Effects Package

Next, we are going to plot this interaction to better understand the effect of women in parliament and democracy on LGBTI policies. Because this is a continuous x continuous interaction, we are going to plot the effect of women in parliament at the mean and +/- one standard deviation around the mean

#Getting the standard deviation and means for women in parliament
women.sd <- c(mean(lgbti_data$women_parliament)-sd(lgbti_data$women_parliament),
           mean(lgbti_data$women_parliament),
           mean(lgbti_data$women_parliament)+sd(lgbti_data$women_parliament))

#rounding to two decimal places
women.sd <- round(women.sd, 2)

women.sd
[1]  5.15 16.57 27.98

#Now we are going to run the interaction using the effects package
library(effects)
Loading required package: carData
lattice theme set by effectsTheme()
See ?effectsTheme for details.
# Running the interaction at mean and +/- one standard deviation
interaction.sd <- effect(c("polity2_vdem*women_parliament"), lgbti.model.4,
                     xlevels=list(polity2_vdem=c(-3, 3, 9),
                                  women_parliament=c(5.1, 15.39, 27.69))) 
# put data in data frame 
interaction.sd <- as.data.frame(interaction.sd)

# Create factors of the different variables in your interaction 
interaction.sd$women <-factor(interaction.sd$women,
                        levels=c(5.1, 15.39, 27.69),
                        labels=c("1 SD Below Mean", "Mean", "1 SD Above Mean"))
                     
interaction.sd$democracy <-factor(interaction.sd$polity2_vdem,
              levels=c(-3, 3, 9),
              labels=c("Authoritarian", "Transition", "Democratic"))

Now making the plot


library(ggplot2)
# Time to plot the interaction
Plot.SD<-ggplot(data=interaction.sd, aes(x=women, y=fit, group=democracy))+
      geom_line(size=1, aes(color=democracy))+ #Can adjust the thickness of your lines
      geom_point(aes(colour = democracy), size=2)+ #Can adjust the size of your points
      geom_ribbon(aes(ymin=fit-se, ymax=fit+se),fill="gray",alpha=.6)+ #Can adjust your error bars
      ylim(-2,10)+ #Puts a limit on the y-axis
      ylab("LGBTI Policy Index: Predicted Values")+ #Adds a label to the y-axis
      xlab("Women in Parliament")+ #Adds a label to the x-axis
      ggtitle("Standard Deviation Plot")+ #Title
      theme_bw()+ #Removes the gray background 
      theme(panel.grid.major=element_blank(),
          panel.grid.minor=element_blank(),
          legend.key = element_blank())+ #Removes the lines 
     scale_fill_grey()

Plot.SD

Continuous x Continuous Interaction: Using sjPlot package

library(sjPlot)
Learn more about sjPlot with 'browseVignettes("sjPlot")'.
library(sjmisc)

Attaching package: ‘sjmisc’

The following objects are masked from ‘package:jtools’:

    %nin%, center
library(ggplot2)
plot_model(lgbti.model.4, type = "int", terms = c("women_parliament", "polity2_vdem")) + theme_bw() #Removes the gray background 

Still using the same package, we are now going to plot using the standard deviations similar to before


plot_model(lgbti.model.4, type = "int", mdrt.values = "meansd") + theme_bw() #Removes the gray background 

NA
NA

Continuous x Continuous Interaction: Using interactions package

#With this package, adding the plot.points = TRUE option includes the specific plot points and automatically color codes them spending on which category they fall into on the moderating variable (modx)

interact_plot(lgbti.model.4, pred = women_parliament, modx = polity2_vdem,
              plot.points = TRUE)

Continuous x Continuous Interactions: Calculating Marginal Effects

Next, we are going to compute the slope (the effect or Beta coefficient) for women in parliament on LGBTI Policy Index while holding the value of the moderator variable, democracy, constant at values running from -10 to 10. To do this, we will find the total coefficient for women in parliament in the model equation for each value of democracy.

library(msm)

lgbti.model.4$coef
                  (Intercept)                  polity2_vdem              women_parliament 
                  -0.17380034                    0.02039863                    0.05719045 
polity2_vdem:women_parliament 
                   0.01098982 
at.democracy <- seq(-10, 10, 2) #go from -10 to 10 by 2

slopes <- lgbti.model.4$coef[3] + lgbti.model.4$coef[4]*at.democracy

slopes
 [1] -0.052707742 -0.030728102 -0.008748463  0.013231176  0.035210816  0.057190455
 [7]  0.079170094  0.101149734  0.123129373  0.145109012  0.167088652
estmean<-coef(lgbti.model.4)
var<-vcov(lgbti.model.4)

SEs <- rep(NA, length(at.democracy))

for (i in 1:length(at.democracy)){
    j <- at.democracy[i]
    SEs[i] <- deltamethod (~ (x3) + (x4)*j, estmean, var)
}

upper <- slopes + 1.96*SEs
lower <- slopes - 1.96*SEs

cbind(at.democracy, slopes, upper, lower)
      at.democracy       slopes         upper        lower
 [1,]          -10 -0.052707742 -0.0409849244 -0.064430559
 [2,]           -8 -0.030728102 -0.0204095842 -0.041046620
 [3,]           -6 -0.008748463  0.0002464115 -0.017743337
 [4,]           -4  0.013231176  0.0210242690  0.005438084
 [5,]           -2  0.035210816  0.0419891190  0.028432512
 [6,]            0  0.057190455  0.0632358727  0.051145037
 [7,]            2  0.079170094  0.0848742446  0.073465944
 [8,]            4  0.101149734  0.1069734921  0.095325975
 [9,]            6  0.123129373  0.1295077404  0.116751005
[10,]            8  0.145109012  0.1523780945  0.137839930
[11,]           10  0.167088652  0.1754781758  0.158699127

#Now, we are going to plot it

plot(at.democracy, slopes, type = "l", lty = 1, ylim = c(-.1, 1), xlab = "Level of Democracy", ylab = "Marginal Effect of Women in Parliament")
points(at.democracy, upper, type = "l", lty = 2)
points(at.democracy, lower, type = "l", lty = 2)
points(at.democracy, rep(0, length(at.democracy)), type = "l", col = "gray")

NA
NA

Interpretting the above plot: What this plot demonstrates is the slope/effect/beto coefficient of women in parliament at diffferent values of democracy. For example, when democracy is -5, there is no effect for women in parliament. When democracy is 10, however, the effect of women in parliament goes up to .20. So when democracy is at 10, for every one percent increase in the amount of women in parliament, this is associated with a .20 increase on the LGBTI Policy Index.

Three-Way Interactions

# Three-Way Interaction

lgbti.model.5 <- lm(policy_index 
                      ~polity2_vdem +
                      women_parliament +
                      region,
                         data =lgbti_data)


lgbti.model.6 <- lm(policy_index 
                      ~polity2_vdem *
                      women_parliament *
                      region,
                         data =lgbti_data)

 stargazer(lgbti.model.5, lgbti.model.6,type="text", 
          column.labels = c("Main Effects", "Interaction"), 
          intercept.bottom = FALSE, 
          single.row=FALSE,     
          notes.append = FALSE, 
          header=FALSE) 
length of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changednumber of rows of result is not a multiple of vector length (arg 2)

======================================================================================================
                                                                  Dependent variable:                 
                                                 -----------------------------------------------------
                                                                     policy_index                     
                                                        Main Effects                Interaction       
                                                             (1)                        (2)           
------------------------------------------------------------------------------------------------------
Constant                                                  1.285***                   1.744***         
                                                           (0.098)                    (0.247)         
                                                                                                      
polity2_vdem                                              0.154***                   -0.115***        
                                                           (0.006)                    (0.030)         
                                                                                                      
women_parliament                                          0.070***                    0.022**         
                                                           (0.003)                    (0.010)         
                                                                                                      
regionGlobal South                                        -1.948***                  -1.954***        
                                                           (0.083)                    (0.254)         
                                                                                                      
polity2_vdem:women_parliament                                                        0.016***         
                                                                                      (0.001)         
                                                                                                      
polity2_vdem:regionGlobal South                                                      0.139***         
                                                                                      (0.031)         
                                                                                                      
women_parliament:regionGlobal South                                                   0.019*          
                                                                                      (0.010)         
                                                                                                      
polity2_vdem:women_parliament:regionGlobal South                                     -0.009***        
                                                                                      (0.001)         
                                                                                                      
------------------------------------------------------------------------------------------------------
Observations                                                4,341                      4,341          
R2                                                          0.430                      0.513          
Adjusted R2                                                 0.429                      0.512          
Residual Std. Error                                   2.197 (df = 4337)          2.031 (df = 4333)    
F Statistic                                      1,089.338*** (df = 3; 4337) 652.501*** (df = 7; 4333)
======================================================================================================
Note:                                                                      *p<0.1; **p<0.05; ***p<0.01
#Plotting using the sjPlot package
plot_model(lgbti.model.6, type = "pred", terms = c("polity2_vdem", "women_parliament[4.73, 15.75,26.77]", "region")) + theme_bw() #Removes the gray background 


#Plotting using interactions package

probe_interaction(lgbti.model.6, pred = women_parliament, modx = region, mod2 = polity2_vdem,
                  alpha = .1)
Johnson-Neyman intervals are not available for factor moderators.
███████████████████ While polity2_vdem (2nd moderator) = -3.16 (- 1 SD) ███████████████████ 

SIMPLE SLOPES ANALYSIS 

Slope of women_parliament when region = Global South: 

  Est.   S.E.   t val.      p
------ ------ -------- ------
  0.02   0.00     4.65   0.00

Slope of women_parliament when region = Global North: 

   Est.   S.E.   t val.      p
------- ------ -------- ------
  -0.03   0.01    -2.38   0.02

████████████████████ While polity2_vdem (2nd moderator) =  3.31 (Mean) ████████████████████ 

SIMPLE SLOPES ANALYSIS 

Slope of women_parliament when region = Global South: 

  Est.   S.E.   t val.      p
------ ------ -------- ------
  0.06   0.00    18.18   0.00

Slope of women_parliament when region = Global North: 

  Est.   S.E.   t val.      p
------ ------ -------- ------
  0.08   0.01    11.24   0.00

███████████████████ While polity2_vdem (2nd moderator) =  9.77 (+ 1 SD) ███████████████████ 

SIMPLE SLOPES ANALYSIS 

Slope of women_parliament when region = Global South: 

  Est.   S.E.   t val.      p
------ ------ -------- ------
  0.11   0.01    20.00   0.00

Slope of women_parliament when region = Global North: 

  Est.   S.E.   t val.      p
------ ------ -------- ------
  0.18   0.01    29.75   0.00

References

Interaction tutorials provided by University of Illinois-Chicago

Sebastian Sauer’s Blog

Guide to ggplot2

Kieran Healy’s Data Visualization Guide

LS0tCnRpdGxlOiAiUFJDIFN0YXRzIENvbnN1bHRhbnQgV29ya3Nob3A6IFBsb3R0aW5nIEludGVyYWN0aW9ucyIKYXV0aG9yOiAiUHJlcGFyZWQgYnkgS3Jpc3RvcGhlciBWZWxhc2NvIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KY2hvb3NlQ1JBTm1pcnJvcihncmFwaGljcz1GQUxTRSwgaW5kPTEpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKCmxpYnJhcnkoaGF2ZW4pCmxnYnRpX3BvbGljeSA8LSByZWFkX2R0YSgiL1VzZXJzL2tyaXN2ZWxhc2NvL0RvY3VtZW50cy9VVC1BdXN0aW4vU3RhdHMvUFJDIFN0YXRzIENvbnN1bHRpbmcvZGlzc2VydGF0aW9uX21hc3Rlcl9wb2xpY3lfdjMuZHRhIikKCmluc3RhbGwucGFja2FnZXMoInpvbyIpCmxpYnJhcnkoem9vKQpsZ2J0aV9kYXRhID0gc3Vic2V0KGxnYnRpX3BvbGljeSwgc2VsZWN0ID0gYygiY291bnRyeSIsInllYXIiLCAicG9saWN5X2luZGV4IiwgIndvbWVuX3BhcmxpYW1lbnQiLCAicG9saXR5Ml92ZGVtIiwiZV90b3RfbGluZ28iLCAiZV90b3RfZmFpYyIsICJnbG9iYWxfY29udGV4dCIsICJwb3B1bGF0aW9uX2RlbnNpdHlfbG4iLCAiZ2RwcGVyY2FwX2xuIiwgInJlZ2lvbiIpKQoKbGdidGlfZGF0YSA8LSB0cmFuc2Zvcm0obGdidGlfZGF0YSwgcG9saXR5Ml92ZGVtID0gbmEubG9jZihwb2xpdHkyX3ZkZW0pLCB3b21lbl9wYXJsaWFtZW50ID0gbmEubG9jZih3b21lbl9wYXJsaWFtZW50LCBwb2xpY3lfaW5kZXggPSBuYS5sb2NmKHBvbGljeV9pbmRleCkpKQpsZ2J0aV9kYXRhIDwtIG5hLm9taXQobGdidGlfZGF0YSkKCmxpYnJhcnkoZHBseXIpCmxnYnRpX2RhdGEkcmVnaW9uIDwtIHJlY29kZShsZ2J0aV9kYXRhJHJlZ2lvbiwgJ0FzaWEnID0gJ0dsb2JhbCBTb3V0aCcsICdMYXRpbiBBbWVyaWNhJyA9ICdHbG9iYWwgU291dGgnLCAnQWZyaWNhJz0gJ0dsb2JhbCBTb3V0aCcsICdPY2VhbmlhJyA9ICdHbG9iYWwgU291dGgnLCAnTm9ydGggQW1lcmljYScgPSAnR2xvYmFsIE5vcnRoJywgJ0V1cm9wZScgPSAnR2xvYmFsIE5vcnRoJykKCmxpYnJhcnkoa25pdHIpCmtuaXRyOjprYWJsZShsZ2J0aV9kYXRhKQpgYGAKCkluIHRoaXMgW1IgTWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pIE5vdGVib29rLCBJIGdpdmUgYSBmZXcgZXhhbXBsZXMgb24gaG93IHRvIHBsb3QgaW50ZXJhY3Rpb25zIGFuZCBtYXJnaW5hbCBlZmZlY3RzLiBNYW55IHBlb3BsZSwgZmFjdWx5IGFuZCBzdHVkZW50cyBhbGlrZSwgb2Z0ZW4gY29tZSB0byB0aGUgUFJDIENvbnN1bHRhbnRzIHRvIHVuZGVyc3RhbmQgaW50ZXJhY3Rpb25zIGluIGRpZmZlcmVudCBtb2RlbHMuIFRoaXMgTm90ZWJvb2sgd2lsbCBvdXRsaW5lIG9uZSBpbXBvcnRhbnQgZWxlbWVudCB0byBpbnRlcnByZXR0aW5nIGludGVyYWN0aW9uczogdmlzdWFsaXphdGlvbnMuCgpJbiBSLCB0aGVyZSBhcmUgb2Z0ZW4gdGltZXMgbXVsdGlwbGUgcGFja2FnZXMgdG8gcGVyZm9ybSBzaW1pbGFyIGZ1bmN0aW9ucyBnaXZlbiB0aGF0IGl0IGlzIGEgZGUtY2VudHJhbGl6ZWQsIG9wZW4gc291cmNlZCBzb2Z0d2FyZS9sYW5ndWFnZS4gVGhlcmVmb3JlLCBJIHdpbGwgZ28gdGhyb3VnaCBtdWx0aXBsZSBkaWZmZXJlbnQgcGFja2FnZXMsIGVhY2ggd2l0aCB0aGVpciBvd24gcHJvcyBhbmQgY29ucywgdG8gaGVscCBnaXZlIG1vcmUgb3B0aW9ucy4KCiMjIE1vZGVyYXRpb24gRWZmZWN0cwoKV2UgaW5jbHVkZSBpbnRlcmFjdGlvbnMgaW4gb3VyIG1vZGVsIHRvIHRlc3QgZm9yIG1vZGVyYXRpb24gZWZmZWN0cywgd2hpY2ggY2FuIGJlIGZvcm1hbGx5IGRlZmluZWQgYXM6CgoqSWYgdGhlIGVmZmVjdCBvZiBYIG9uIFkgZGVwZW5kcyBvbiBNLCBhIG1vZGVyYXRvciBlZmZlY3QgdGFrZXMgcGxhY2UqCgoKYGBge3IgZWNobz1UUlVFfQojIyBJbnN0YWxsaW5nIGRpZmZlcmVudCBwYWNrYWdlcyB0aGF0IHdlIHdpbGwgYmUgdXNpbmcgdGhyb3VnaG91dCB0aGlzIGRlbW9uc3RyYXRpb24gCmluc3RhbGwucGFja2FnZXMoImNhciIpICNBbiBleHRyZW1lbHkgdXNlZnVsL2luLWRlcHRoIHJlZ3Jlc3Npb24gcGFja2FnZSAKaW5zdGFsbC5wYWNrYWdlcygic3RhcmdhemVyIikgI1Byb2R1Y2VzIGVhc3kgdG8gcmVhZCByZWdyZXNzaW9uIHJlc3VsdHMKaW5zdGFsbC5wYWNrYWdlcygiZWZmZWN0cyIpICNXZSB3aWxsIHVzZSB0aGlzIHRvIGNyZWF0ZSBvdXIgaW50ZXJhY3Rpb25zIAppbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikgI091ciBpbmNyZWRpYmx5IHBvd2VyZnVsIGFuZCB2ZXJzYXRpbGUgZ3JhcGhpbmcgcGFja2FnZSAKaW5zdGFsbC5wYWNrYWdlcygic2pQbG90IikgI01hcmdpbmFsIGVmZmVjdHMgcGFja2FnZQppbnN0YWxsLnBhY2thZ2VzKCJzam1pc2MiKSAjTWFyZ2luYWwgZWZmZWN0cyBQYWNrYWdlCmluc3RhbGwucGFja2FnZXMoImRwbHlyIikgI0ZvciBkYXRhIG1hbmlwdWxhdGlvbgppbnN0YWxsLnBhY2thZ2VzKCJjb3JycGxvdCIpICNWaXN1YWxpemluZyBjb3JyZWxhdGlvbnMKaW5zdGFsbC5wYWNrYWdlcygibXNtIikKaW5zdGFsbC5wYWNrYWdlcygianRvb2xzIikKYGBgCgoKRm9yIHRoZXNlIGV4YW1wbGVzLCBJIHdpbGwgYmUgdXNpbmcgYSBzYW1wbGUgZGF0YXNldCBjb21pbmcgZnJvbSBteSBvd24gcmVzZWFyY2ggb24gTEdCVEkgcG9saWN5IGFkb3B0aW9uIGZyb20gMTk5MS0yMDE4LiBJbiB0aGlzIGZpcnN0IG1vZGVsLCB3ZSB3aWxsIGJlIHByZWRpY3RpbmcgYSBjb3VudHJ5J3Mgc2NvcmUgb24gYW4gTEdCVEkgUG9saWN5IEluZGV4IGJhc2VkIG9uIGJlaW5nIGluIHRoZSBHbG9iYWwgU291dGgvTm9ydGgsIGxldmVsIG9mIGRlbW9jcmFjeSwgYW5kIHBlcmNlbnQgb2Ygd29tZW4gaW4gcGFybGlhbWVudC4KCgoKIyMgVmlzdWFsaXppbmcgQ29ycmVsYXRpb25zCgoKQmVmb3JlIHN0YXJ0aW5nLCBJIGZpcnN0IGp1c3Qgd2FudCB0byB2aXN1YWxpemUgdGhlIGNvcnJlbGF0aW9ucyBvZiB0aGUgdmFyaWFibGVzIGluIG15IGRhdGFzZXQKCmBgYHtyIGVjaG89VFJVRX0KbGlicmFyeShjb3JycGxvdCkKCk0gPC0gY29yKGxnYnRpX2RhdGFbLDI6MTBdKSAjZGF0YXNldCBpcyBjYWxsZWQgbGdidGlfZGF0YSBhbmQgSSdtIGdldHRpbmcgdGhlIGNvcnJlbGF0aW9ucyBmb3IgYWxsIHZhcmlhYmxlcyBiZXR3ZWVuIHRoZSAybmQgYW5kIHRoZSAxMHRoIHZhcmlhYmxlcyAodGhlIDFzdCBhbmQgbGFzdCB2YXJpYWJsZSBhcmUgc3RyaW5ncykKCiNQbG90dGluZyB0aGUgY29ycmVsYXRpb25zCmNvcnJwbG90KE0sIG1ldGhvZCA9ICJjb2xvciIpCgpgYGAKCgpgYGB7ciBlY2hvPVRSVUV9CiNSZS1kb2luZyB0aGUgcGxvdCBidXQgb25seSBrZWVwaW5nIGhhbGYgb2YgdGhlIG1hdHJpeAoKY29ycnBsb3QoTSwgbWV0aG9kID0gImNvbG9yIiwgdHlwZT0gInVwcGVyIikKCmBgYAoKYGBge3IgZWNobz1UUlVFfQojVGhpcyB0aW1lLCB1c2luZyB0aGUgY29ycnBsb3QubWl4ZWQgZnVuY3Rpb24sIEknbSBnb2luZyB0byBhbHNvIGluY2x1ZGUgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IGl0c2VsZiBpbiBhZGRpdGlvbiB0byB0aGUgY29sb3IgdmlzdWFscy4KCmNvcnJwbG90Lm1peGVkKE0pCmBgYAoKCiMjIENhdGVnb3JpY2FsIHggQ29udGludW91cyBJbnRlcmFjdGlvbnMKCk5vdywgd2UgYXJlIGdvaW5nIHRvIG1vdmUgaW50byBkZXRlY3RpbmcgaWYgd2UgbmVlZCBpbnRlcmFjdGlvbiB0ZXJtcyBpbiBvdXIgbW9kZWwgdGhyb3VnaCB2aXN1YWwgZGV0ZWN0aW9uLiBUaGUgdHdvIHZhcmlhYmxlcyB3ZSB3aWxsIGJlIHVzaW5nIGFyZSByZWdpb24gKEdsb2JhbCBTb3V0aCB2cy4gR2xvYmFsIE5vcnRoKSBhbmQgdGhlIHBlcmNlbnQgb2Ygd29tZW4gaW4gcGFybGlhbWVudC4gVGhlc2UgYXJlIGNhdGVnb3JpY2FsIGFuZCBjb250aW51b3VzIHZhcmlhYmxlcywgcmVzcGVjdGl2ZWx5LgoKCmBgYHtyIGVjaG89VFJVRX0KbGlicmFyeShnZ3Bsb3QyKQoKI1FQbG90IHN0YW5kcyBmb3IgIlF1aWNrIFBsb3QiCgojRmlyc3QsIHdlIGFyZSBnb2luZyB0byBzZWUgaWYgdGhlcmUncyBhbnkgdmlzdWFsIGFzc29jaWF0aW9uIGJldHdlZW4gdGhlIHBlcmNlbnQgb2Ygd29tZW4gaW4gcGFybGlhbWVudCBhbmQgbW9yZSBwcm9ncmVzc2l2ZSBMR0JUSSBwb2xpY2llcwpxcGxvdCh4ID0gd29tZW5fcGFybGlhbWVudCwgeSA9IHBvbGljeV9pbmRleCwgIGRhdGEgPSBsZ2J0aV9kYXRhKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgICN0aGlzIG9wdGlvbiBpcyBpbmNsdWRpbmcgdGhlIGxpbmUgb2YgYmVzdCBmaXQKCmBgYAoKYGBge3IgZWNobz1UUlVFfQoKI05vdywgd2UgYXJlIGdvaW5nIHRvIHNlZSBpZiB0aGlzIGFzc29jaWF0aW9uIGNoYW5nZXMgYmFzZWQgb24gd2hldGhlciBhIGNvdW50cnkgaXMgaW4gdGhlIEdsb2JhbCBOb3J0aCBvciB0aGUgR2xvYmFsIFNvdXRoCgpxcGxvdCh4ID0gd29tZW5fcGFybGlhbWVudCwgeSA9IHBvbGljeV9pbmRleCwgZmFjZXRzID0gfnJlZ2lvbiwgZGF0YSA9IGxnYnRpX2RhdGEpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArICN0aGlzIG9wdGlvbiBpcyBpbmNsdWRpbmcgdGhlIGxpbmUgb2YgYmVzdCBmaXQKICAgdGhlbWVfYncoKSAjUmVtb3ZlcyB0aGUgZ3JheSBiYWNrZ3JvdW5kIApgYGAKCgpgYGB7ciBlY2hvPVRSVUV9CgojQWx0ZXJuYXRpdmVseSwgd2UgY2FuIHBsb3QgdGhlbSBvbiB0aGUgc2FtZSBncmFwaCBpbiBjYXNlIHRoZSBzaWRlIGJ5IHNpZGUgY29tcGFyaXNvbnMgd2VyZSB0b28gZGlmZmljdWx0IHRvIHZpc3VhbGx5IGRldGVjdC4KCnFwbG90KHggPSB3b21lbl9wYXJsaWFtZW50LCB5ID0gcG9saWN5X2luZGV4LCBkYXRhID0gbGdidGlfZGF0YSwgY29sb3IgPSByZWdpb24pICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArIAogICB0aGVtZV9idygpKyAjUmVtb3ZlcyB0aGUgZ3JheSBiYWNrZ3JvdW5kIAogICAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgcGFuZWwuZ3JpZC5taW5vcj1lbGVtZW50X2JsYW5rKCksCiAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCkpICsgI1JlbW92ZXMgdGhlIGxpbmVzIAogICAgICAgIHhsYWIoIlBlcmNlbnQgKCUpIG9mIFdvbWVuIGluIFBhcmxpYW1lbnQiKSArICAjY2hhbmdpbmcgdGhlIGxhYmVscyBvZiB0aGUgYXhlcwogICAgICAgIHlsYWIoIkxHQlRJIFBvbGljeSBJbmRleCBTY29yZSIpCmBgYAoKCkJhc2VkIG9uIHRoaXMgdmlzdWFsIGluc3BlY3Rpb24sIGl0IGFwcGVhcnMgdGhhdCBhbiBpbnRlcmFjdGlvbiB0ZXJtIGlzIHdhcnJhbnRlZCBiZWNhdXNlIHRoZSBzbG9wZXMgb2YgdGhlIHR3byBsaW5lcyBhcmUgZGlmZmVyZW50LiBUaGUgZWZmZWN0IG9mIHdvbWVuIGluIHBhcmxpYW1lbnQgb24gcHJvZ3Jlc3NpdmUgTEdCVEkgcG9saWNpZXMgbWF5IGJlIGNvbnRpbmdlbnQsIHRoZXJlZm9yZSwgb24gdGhlIHdvcmxkIHJlZ2lvbgoKCgojIE1vZGVsaW5nIENvbnRpbnVvdXMgeCBDYXRlZ29yaWNhbCBJbnRlcmFjdGlvbnMKCmBgYHtyIGVjaG89VFJVRX0KI1ByZWRpY3RpbmcgYSBjb3VudHkncyBzY29yZSBvbiB0aGUgTEdCVEkgUG9saWN5IEluZGV4IHVzaW5nIHdvbWVuIGluIHBhcmxpYW1lbnQgKGNvbnRpbnVvdXMpIGFuZCByZWdpb24gKGNhdGVnb3JpY2FsKQoKbGdidGkubW9kZWwuMSA8LSBsbShwb2xpY3lfaW5kZXggfgogICAgICAgICAgICAgICAgICAgICAgd29tZW5fcGFybGlhbWVudCArCiAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBsZ2J0aV9kYXRhKQoKI1JlLVJ1bm5pbmcgdGhlIG1vZGVsIHdpdGggdGhlIGludGVyYWN0aW9uCmxnYnRpLm1vZGVsLjIgPC0gbG0ocG9saWN5X2luZGV4IH4KICAgICAgICAgICAgICAgICAgICAgIHdvbWVuX3BhcmxpYW1lbnQgKiAgICAjIHVzaW5nIHRoZSBhc3RyaXNrICgqKSBpbnN0ZWFkIG9mIHRoZSBwbHVzICgrKQogICAgICAgICAgICAgICAgICAgICAgICByZWdpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gbGdidGlfZGF0YSkKYGBgCgoKYGBge3IgZWNobz1UUlVFfQpsaWJyYXJ5KHN0YXJnYXplcikKYGBgCgpgYGB7ciBlY2hvPVRSVUV9CgojIE5vdywgd2UgY2FuIGxvb2sgYXQgdGhlIHJlc3VsdHMgZnJvbSBvdXIgbW9kZWxzIHRvIHNlZSBpZiB0aGVyZSBpcyBpbmRlZWQgYSBzaWduaWZpY2FudCBpbnRlcmFjdGlvbi4KCgojUiBkb2VzIG5vdCBhdXRvbWF0aWNhbGx5IHJlcG9ydCB0aGUgcmVzdWx0cyBmcm9tIGEgbW9kZWwsIHdlIG11c3QgYXNrIGZvciB0aGVtLiBUaGVyZSBhcmUgYSBmZXcgd2F5cyBvZiBkb2luZyBzbywgdGhlIGJ1aWx0LWluIGZ1bmN0aW9uIGlzIHRvIHR5cGUgc3VtbWFyeSh4KS4gVGhlIG91dHB1dCBpc24ndCB2aXN1YWxseSBhcHBlYWxpbmcsIGhvd2V2ZXIsIHNvIEkgd2lsbCBiZSB1c2luZyB0aGUgc3RhcmdhemVyIHBhY2thZ2UgdGhhdCBwcm9kdWNlcyBhIG1vcmUgcXVhbGl0eSByZWdyZXNzaW9uIHRhYmxlLgoKc3RhcmdhemVyKGxnYnRpLm1vZGVsLjEsIGxnYnRpLm1vZGVsLjIsdHlwZT0idGV4dCIsIAogICAgICAgICAgY29sdW1uLmxhYmVscyA9IGMoIk1haW4gRWZmZWN0cyIsICJJbnRlcmFjdGlvbiIpLCAKICAgICAgICAgIGludGVyY2VwdC5ib3R0b20gPSBGQUxTRSwgCiAgICAgICAgICBzaW5nbGUucm93PUZBTFNFLCAgICAgCiAgICAgICAgICBub3Rlcy5hcHBlbmQgPSBGQUxTRSwgCiAgICAgICAgICBoZWFkZXI9RkFMU0UpIApgYGAKCgojIyMgUGxvdHRpbmcgQ2F0ZWdvcmljYWwgeCBDb250aW51b3VzIEludGVyYWN0aW9ucyB1c2luZyBJbnRlcmFjdGlvbnMgcGFja2FnZQoKYGBge3IgZWNobz1UUlVFfQpsaWJyYXJ5KGp0b29scykgIyBmb3Igc3VtbSgpCgojQmVzaWRlcyBzdGFyZ2F6ZXIsIHRoZSBzdW1tKCkgY29tbWFuZCBpbiB0aGUganRvb2xzIHBhY2thZ2UgYWxzbyBhbGxvd3MgZm9yIGNsZWFuZXIgcmVncmVzc2lvbiB0YWJsZXMuCnN1bW0obGdidGkubW9kZWwuMikKYGBgCgpgYGB7ciBlY2hvPVRSVUV9CmxpYnJhcnkoaW50ZXJhY3Rpb25zKQoKI1Bsb3R0aW5nIHRoZSBpbnRlcmFjdGlvbnMgd2l0aCB0aGUgSW50ZXJhY3Rpb24gcGFja2FnZQppbnRlcmFjdF9wbG90KGxnYnRpLm1vZGVsLjIsIHByZWQgPSB3b21lbl9wYXJsaWFtZW50LCBtb2R4ID0gcmVnaW9uKQoKI09uZSB0aGluZyB5b3UnbGwgbm90aWNlIGlzIHRoYXQgdGhlIGRlZmF1bHQgcGxvdCB2aXN1YWxzIGFyZSBkaWZmZXJlbnQgZm9yIGVhY2ggcGFja2FnZQpgYGAKCgoKCgoKCiMjIENvbnRpbnVvdXMgeCBDb250aW51b3VzIEludGVyYWN0aW9ucwoKClZpc3VhbGx5IGluc3BlY3Rpbmcgd2hldGhlciB0d28gY29udGludW91cyB2YXJpYWJsZXMgYXJlIG1vZGVyYXRpbmcgb25lIGFub3RoZXIgYW5kLCB0aGVyZWZvcmUsIGluIG5lZWQgb2YgYW4gaW50ZXJhY3Rpb24gaW4geW91ciBtb2RlbCBpcyBhIGJpdCBtb3JlIGRpZmZpY3VsdC4gT25lIHN0cmF0ZWd5IGlzIHRvIGNvbnZlcnQgb25lIG9mIHRoZSBjb250aW51b3VzIHZhcmlhYmxlcyBpbnRvIGZhY3RvciB2YXJpYWJsZXMuIEZvciBleGFtcGxlLCBsZXQncyBzYXkgdGhhdCB0aGUgZWZmZWN0IG9mIHdvbWVuIGluIHBhcmlhbWVudCBpcyBjb25kaXRpb25lZCBvbiB0aGUgbGV2ZWwgb2YgZGVtb2NyYWN5LiBTaW5jZSBkZW1vY3JhY3kgaXMgY29udGludW91cywgSSB3aWxsIGNvdmVydCBpdCBpbnRvIHRocmVlIGdyb3VwczogbWVhbiBhbmQgKy8tIDEgc3RhbmRhcmQgZGV2aWF0aW9uIGZyb20gdGhlIG1lYW4uCgoKYGBge3IgZWNobz1UUlVFfQoKI0xvYWRpbmcgZHBseXIgZm9yIGRhdGEgbWFuaXB1bGF0aW9uCmxpYnJhcnkoZHBseXIpCgojSSdtIHB1dHRpbmcgdGhlIGRlbW9jcmFjeSB2YXJpYWJsZSwgcG9saXR5Ml92ZGVtLCBpbnRvIGFuIG9iamVjdCBjYWxsZWQgIngsIiB3aGljaCBJIGNhbiB0aGVuIG1hbmlwdWxhdGUuCgp4IDwtIGxnYnRpX2RhdGEkcG9saXR5Ml92ZGVtCgojTm93LCBJIGFtIGNyZWF0aW5nIGEgbmV3IHZhcmlhYmxlIGNhbGxlZCAiZGVtb2NyYWN5IiB0aGF0IHdpbGwgZ3JvdXAgY291bnRyaWVzIHRvZ2V0aGVyIGJhc2VkIG9uIHRoZWlyIHZhbHVlIG9mIHggKHRoZSBwb2xpdHkyX3ZkZW0gdmFyaWFibGUpCgpsZ2J0aV9kYXRhJGRlbW9jcmFjeSA8LQogIGNhc2Vfd2hlbih4ID4gbWVhbih4KStzZCh4KSB+ICJTdHJvbmdseSBEZW1vY3JhdGljIiwKICAgICAgICAgICAgeCA8IG1lYW4oeCkrc2QoeCkgJiB4ID4gbWVhbih4KS1zZCh4KSB+ICJBdmVyYWdlIExldmVsIG9mIERlbW9jcmFjeSIsCiAgICAgICAgICAgIHggPCBtZWFuKHgpLXNkKHgpIH4gIldlYWtseSBEZW1vY3JhdGljIikKCiMgU2VlaW5nIGhvdyBtYW55IG9ic2VydmF0aW9ucyBmYWxsIGludG8gZWFjaCBjYXRlZ29yeQpjb3VudChsZ2J0aV9kYXRhLCBkZW1vY3JhY3kpCmBgYAoKTm93LCB3ZSBhcmUgZ29pbmcgdG8gcGxvdCB0aGlzLgoKYGBge3IgZWNobz1UUlVFfQpsaWJyYXJ5KGdncGxvdDIpCmxnYnRpX2RhdGEgJT4lICAjIFRoZXNlIHN5bWJvbHMgYXJlIG9wZXJhdG9ycyB0aGF0IGVzc2VudGlhbGx5IG1lYW4gImRvIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb24iCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0gd29tZW5fcGFybGlhbWVudCwgeSA9IHBvbGljeV9pbmRleCwgZ3JvdXAgPSBkZW1vY3JhY3ksIGNvbG9yID0gZGVtb2NyYWN5KSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJncmV5IiwgYWxwaGEgPSAuNykgKwogICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKwogICAgIHRoZW1lX2J3KCkrICNSZW1vdmVzIHRoZSBncmF5IGJhY2tncm91bmQgCiAgICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3I9ZWxlbWVudF9ibGFuaygpLAogICAgICBwYW5lbC5ncmlkLm1pbm9yPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKSkgKyAjUmVtb3ZlcyB0aGUgbGluZXMgCiAgICAgICAgeGxhYigiUGVyY2VudCAoJSkgb2YgV29tZW4gaW4gUGFybGlhbWVudCIpICsgICNjaGFuZ2luZyB0aGUgbGFiZWxzIG9mIHRoZSBheGVzCiAgICAgICAgeWxhYigiTEdCVEkgUG9saWN5IEluZGV4IFNjb3JlIikKYGBgCgoKCgpHaXZlbiB0aGF0IHRoZXJlIGFyZSBkaWZmZXJlbnQgc2xvcGVzIGJhc2VkIG9uIHRoZSBsZXZlbCBvZiBkZW1vY3JhY3ksIGl0IGluZGVlZCBhcHBlYXJzIHRoYXQgYW4gaW50ZXJhY3Rpb24gZWZmZWN0IG1heSBhZ2FpbiBiZSB3YXJyYW50ZWQgd2l0aGluIG91ciBtb2RlbHMuIE5leHQsIHdlIGFyZSBnb2luZyB0byBnbyBhaGVhZCBhbmQgdGVzdCBmb3IgdGhpcy4KCgpgYGB7ciBlY2hvPVRSVUV9CiNSdW5uaW5nIHRoZSBtb2RlbCB3aXRoIGFuIGludGVyYWN0aW9uCmxnYnRpLm1vZGVsLjMgPC0gbG0ocG9saWN5X2luZGV4IAogICAgICAgICAgICAgICAgICAgICAgfnBvbGl0eTJfdmRlbSArCiAgICAgICAgICAgICAgICAgICAgICB3b21lbl9wYXJsaWFtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9bGdidGlfZGF0YSkKCiNSZS1SdW5uaW5nIHRoZSBtb2RlbCB3aXRoIGFuIGludGVyYWN0aW9uCmxnYnRpLm1vZGVsLjQgPC0gbG0ocG9saWN5X2luZGV4IAogICAgICAgICAgICAgICAgICAgICAgfnBvbGl0eTJfdmRlbSAqCiAgICAgICAgICAgICAgICAgICAgICB3b21lbl9wYXJsaWFtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9bGdidGlfZGF0YSkKCnN0YXJnYXplcihsZ2J0aS5tb2RlbC4zLCBsZ2J0aS5tb2RlbC40LHR5cGU9InRleHQiLCAKICAgICAgICAgIGNvbHVtbi5sYWJlbHMgPSBjKCJNYWluIEVmZmVjdHMiLCAiSW50ZXJhY3Rpb24iKSwgCiAgICAgICAgICBpbnRlcmNlcHQuYm90dG9tID0gRkFMU0UsIAogICAgICAgICAgc2luZ2xlLnJvdz1GQUxTRSwgICAgIAogICAgICAgICAgbm90ZXMuYXBwZW5kID0gRkFMU0UsIAogICAgICAgICAgaGVhZGVyPUZBTFNFKSAKYGBgCgoKCiMjIyBDb250aW51b3VzIHggQ29udGludW91cyBJbnRlcmFjdGlvbjogUGxvdHRpbmcgU2ltcGxlIFNsb3BlcyBiYXNlZCBvbiBTdGFuZGFyZCBEZXZpYXRpb25zIHVzaW5nIEVmZmVjdHMgUGFja2FnZSAKCgpOZXh0LCB3ZSBhcmUgZ29pbmcgdG8gcGxvdCB0aGlzIGludGVyYWN0aW9uIHRvIGJldHRlciB1bmRlcnN0YW5kIHRoZSBlZmZlY3Qgb2Ygd29tZW4gaW4gcGFybGlhbWVudCBhbmQgZGVtb2NyYWN5IG9uIExHQlRJIHBvbGljaWVzLiBCZWNhdXNlIHRoaXMgaXMgYSBjb250aW51b3VzIHggY29udGludW91cyBpbnRlcmFjdGlvbiwgd2UgYXJlIGdvaW5nIHRvIHBsb3QgdGhlIGVmZmVjdCBvZiB3b21lbiBpbiBwYXJsaWFtZW50IGF0IHRoZSBtZWFuIGFuZCArLy0gb25lIHN0YW5kYXJkIGRldmlhdGlvbiBhcm91bmQgdGhlIG1lYW4KCgpgYGB7ciBlY2hvPVRSVUV9CiNHZXR0aW5nIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gYW5kIG1lYW5zIGZvciB3b21lbiBpbiBwYXJsaWFtZW50CndvbWVuLnNkIDwtIGMobWVhbihsZ2J0aV9kYXRhJHdvbWVuX3BhcmxpYW1lbnQpLXNkKGxnYnRpX2RhdGEkd29tZW5fcGFybGlhbWVudCksCiAgICAgICAgICAgbWVhbihsZ2J0aV9kYXRhJHdvbWVuX3BhcmxpYW1lbnQpLAogICAgICAgICAgIG1lYW4obGdidGlfZGF0YSR3b21lbl9wYXJsaWFtZW50KStzZChsZ2J0aV9kYXRhJHdvbWVuX3BhcmxpYW1lbnQpKQoKI3JvdW5kaW5nIHRvIHR3byBkZWNpbWFsIHBsYWNlcwp3b21lbi5zZCA8LSByb3VuZCh3b21lbi5zZCwgMikKCndvbWVuLnNkCgpgYGAKCgpgYGB7ciBlY2hvPVRSVUV9CgojTm93IHdlIGFyZSBnb2luZyB0byBydW4gdGhlIGludGVyYWN0aW9uIHVzaW5nIHRoZSBlZmZlY3RzIHBhY2thZ2UKbGlicmFyeShlZmZlY3RzKQoKIyBSdW5uaW5nIHRoZSBpbnRlcmFjdGlvbiBhdCBtZWFuIGFuZCArLy0gb25lIHN0YW5kYXJkIGRldmlhdGlvbgppbnRlcmFjdGlvbi5zZCA8LSBlZmZlY3QoYygicG9saXR5Ml92ZGVtKndvbWVuX3BhcmxpYW1lbnQiKSwgbGdidGkubW9kZWwuNCwKICAgICAgICAgICAgICAgICAgICAgeGxldmVscz1saXN0KHBvbGl0eTJfdmRlbT1jKC0zLCAzLCA5KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvbWVuX3BhcmxpYW1lbnQ9Yyg1LjEsIDE1LjM5LCAyNy42OSkpKSAKIyBwdXQgZGF0YSBpbiBkYXRhIGZyYW1lIAppbnRlcmFjdGlvbi5zZCA8LSBhcy5kYXRhLmZyYW1lKGludGVyYWN0aW9uLnNkKQoKIyBDcmVhdGUgZmFjdG9ycyBvZiB0aGUgZGlmZmVyZW50IHZhcmlhYmxlcyBpbiB5b3VyIGludGVyYWN0aW9uIAppbnRlcmFjdGlvbi5zZCR3b21lbiA8LWZhY3RvcihpbnRlcmFjdGlvbi5zZCR3b21lbiwKICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzPWMoNS4xLCAxNS4zOSwgMjcuNjkpLAogICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiMSBTRCBCZWxvdyBNZWFuIiwgIk1lYW4iLCAiMSBTRCBBYm92ZSBNZWFuIikpCiAgICAgICAgICAgICAgICAgICAgIAppbnRlcmFjdGlvbi5zZCRkZW1vY3JhY3kgPC1mYWN0b3IoaW50ZXJhY3Rpb24uc2QkcG9saXR5Ml92ZGVtLAogICAgICAgICAgICAgIGxldmVscz1jKC0zLCAzLCA5KSwKICAgICAgICAgICAgICBsYWJlbHM9YygiQXV0aG9yaXRhcmlhbiIsICJUcmFuc2l0aW9uIiwgIkRlbW9jcmF0aWMiKSkKYGBgCgoKCk5vdyBtYWtpbmcgdGhlIHBsb3QKYGBge3IgZWNobz1UUlVFfQoKbGlicmFyeShnZ3Bsb3QyKQojIFRpbWUgdG8gcGxvdCB0aGUgaW50ZXJhY3Rpb24KUGxvdC5TRDwtZ2dwbG90KGRhdGE9aW50ZXJhY3Rpb24uc2QsIGFlcyh4PXdvbWVuLCB5PWZpdCwgZ3JvdXA9ZGVtb2NyYWN5KSkrCiAgICAgIGdlb21fbGluZShzaXplPTEsIGFlcyhjb2xvcj1kZW1vY3JhY3kpKSsgI0NhbiBhZGp1c3QgdGhlIHRoaWNrbmVzcyBvZiB5b3VyIGxpbmVzCiAgICAgIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IGRlbW9jcmFjeSksIHNpemU9MikrICNDYW4gYWRqdXN0IHRoZSBzaXplIG9mIHlvdXIgcG9pbnRzCiAgICAgIGdlb21fcmliYm9uKGFlcyh5bWluPWZpdC1zZSwgeW1heD1maXQrc2UpLGZpbGw9ImdyYXkiLGFscGhhPS42KSsgI0NhbiBhZGp1c3QgeW91ciBlcnJvciBiYXJzCiAgICAgIHlsaW0oLTIsMTApKyAjUHV0cyBhIGxpbWl0IG9uIHRoZSB5LWF4aXMKICAgICAgeWxhYigiTEdCVEkgUG9saWN5IEluZGV4OiBQcmVkaWN0ZWQgVmFsdWVzIikrICNBZGRzIGEgbGFiZWwgdG8gdGhlIHktYXhpcwogICAgICB4bGFiKCJXb21lbiBpbiBQYXJsaWFtZW50IikrICNBZGRzIGEgbGFiZWwgdG8gdGhlIHgtYXhpcwogICAgICBnZ3RpdGxlKCJTdGFuZGFyZCBEZXZpYXRpb24gUGxvdCIpKyAjVGl0bGUKICAgICAgdGhlbWVfYncoKSsgI1JlbW92ZXMgdGhlIGdyYXkgYmFja2dyb3VuZCAKICAgICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvcj1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCkpKyAjUmVtb3ZlcyB0aGUgbGluZXMgCiAgICAgc2NhbGVfZmlsbF9ncmV5KCkKClBsb3QuU0QKYGBgCgoKIyMjIENvbnRpbnVvdXMgeCBDb250aW51b3VzIEludGVyYWN0aW9uOiBVc2luZyBzalBsb3QgcGFja2FnZQoKYGBge3IgZWNobz1UUlVFfQpsaWJyYXJ5KHNqUGxvdCkKbGlicmFyeShzam1pc2MpCmxpYnJhcnkoZ2dwbG90MikKcGxvdF9tb2RlbChsZ2J0aS5tb2RlbC40LCB0eXBlID0gImludCIsIHRlcm1zID0gYygid29tZW5fcGFybGlhbWVudCIsICJwb2xpdHkyX3ZkZW0iKSkgKyB0aGVtZV9idygpICNSZW1vdmVzIHRoZSBncmF5IGJhY2tncm91bmQgCgpgYGAKClN0aWxsIHVzaW5nIHRoZSBzYW1lIHBhY2thZ2UsIHdlIGFyZSBub3cgZ29pbmcgdG8gcGxvdCB1c2luZyB0aGUgc3RhbmRhcmQgZGV2aWF0aW9ucyBzaW1pbGFyIHRvIGJlZm9yZQoKCmBgYHtyIGVjaG89VFJVRX0KCnBsb3RfbW9kZWwobGdidGkubW9kZWwuNCwgdHlwZSA9ICJpbnQiLCBtZHJ0LnZhbHVlcyA9ICJtZWFuc2QiKSArIHRoZW1lX2J3KCkgI1JlbW92ZXMgdGhlIGdyYXkgYmFja2dyb3VuZCAKCgpgYGAKCiMjIyBDb250aW51b3VzIHggQ29udGludW91cyBJbnRlcmFjdGlvbjogVXNpbmcgaW50ZXJhY3Rpb25zIHBhY2thZ2UKCgpgYGB7ciBlY2hvPVRSVUV9CiNXaXRoIHRoaXMgcGFja2FnZSwgYWRkaW5nIHRoZSBwbG90LnBvaW50cyA9IFRSVUUgb3B0aW9uIGluY2x1ZGVzIHRoZSBzcGVjaWZpYyBwbG90IHBvaW50cyBhbmQgYXV0b21hdGljYWxseSBjb2xvciBjb2RlcyB0aGVtIHNwZW5kaW5nIG9uIHdoaWNoIGNhdGVnb3J5IHRoZXkgZmFsbCBpbnRvIG9uIHRoZSBtb2RlcmF0aW5nIHZhcmlhYmxlIChtb2R4KQoKaW50ZXJhY3RfcGxvdChsZ2J0aS5tb2RlbC40LCBwcmVkID0gd29tZW5fcGFybGlhbWVudCwgbW9keCA9IHBvbGl0eTJfdmRlbSwKICAgICAgICAgICAgICBwbG90LnBvaW50cyA9IFRSVUUpCmBgYAoKIyMjIENvbnRpbnVvdXMgeCBDb250aW51b3VzIEludGVyYWN0aW9uczogQ2FsY3VsYXRpbmcgTWFyZ2luYWwgRWZmZWN0cwoKTmV4dCwgd2UgYXJlIGdvaW5nIHRvIGNvbXB1dGUgdGhlIHNsb3BlICh0aGUgZWZmZWN0IG9yIEJldGEgY29lZmZpY2llbnQpIGZvciB3b21lbiBpbiBwYXJsaWFtZW50IG9uIExHQlRJIFBvbGljeSBJbmRleCB3aGlsZSBob2xkaW5nIHRoZSB2YWx1ZSBvZiB0aGUgbW9kZXJhdG9yIHZhcmlhYmxlLCBkZW1vY3JhY3ksIGNvbnN0YW50IGF0IHZhbHVlcyBydW5uaW5nIGZyb20gLTEwIHRvIDEwLiBUbyBkbyB0aGlzLCB3ZSB3aWxsIGZpbmQgdGhlIHRvdGFsIGNvZWZmaWNpZW50IGZvciB3b21lbiBpbiBwYXJsaWFtZW50IGluIHRoZSBtb2RlbCBlcXVhdGlvbiBmb3IgZWFjaCB2YWx1ZSBvZiBkZW1vY3JhY3kuCgoKYGBge3IgZWNobz1UUlVFfQpsaWJyYXJ5KG1zbSkKCmxnYnRpLm1vZGVsLjQkY29lZgoKYXQuZGVtb2NyYWN5IDwtIHNlcSgtMTAsIDEwLCAyKSAjZ28gZnJvbSAtMTAgdG8gMTAgYnkgMgoKc2xvcGVzIDwtIGxnYnRpLm1vZGVsLjQkY29lZlszXSArIGxnYnRpLm1vZGVsLjQkY29lZls0XSphdC5kZW1vY3JhY3kKCnNsb3BlcwoKZXN0bWVhbjwtY29lZihsZ2J0aS5tb2RlbC40KQp2YXI8LXZjb3YobGdidGkubW9kZWwuNCkKClNFcyA8LSByZXAoTkEsIGxlbmd0aChhdC5kZW1vY3JhY3kpKQoKZm9yIChpIGluIDE6bGVuZ3RoKGF0LmRlbW9jcmFjeSkpewoJaiA8LSBhdC5kZW1vY3JhY3lbaV0KCVNFc1tpXSA8LSBkZWx0YW1ldGhvZCAofiAoeDMpICsgKHg0KSpqLCBlc3RtZWFuLCB2YXIpCn0KCnVwcGVyIDwtIHNsb3BlcyArIDEuOTYqU0VzCmxvd2VyIDwtIHNsb3BlcyAtIDEuOTYqU0VzCgpjYmluZChhdC5kZW1vY3JhY3ksIHNsb3BlcywgdXBwZXIsIGxvd2VyKQpgYGAKCmBgYHtyIGVjaG89VFJVRX0KCiNOb3csIHdlIGFyZSBnb2luZyB0byBwbG90IGl0CgpwbG90KGF0LmRlbW9jcmFjeSwgc2xvcGVzLCB0eXBlID0gImwiLCBsdHkgPSAxLCB5bGltID0gYygtLjEsIDEpLCB4bGFiID0gIkxldmVsIG9mIERlbW9jcmFjeSIsIHlsYWIgPSAiTWFyZ2luYWwgRWZmZWN0IG9mIFdvbWVuIGluIFBhcmxpYW1lbnQiKQpwb2ludHMoYXQuZGVtb2NyYWN5LCB1cHBlciwgdHlwZSA9ICJsIiwgbHR5ID0gMikKcG9pbnRzKGF0LmRlbW9jcmFjeSwgbG93ZXIsIHR5cGUgPSAibCIsIGx0eSA9IDIpCnBvaW50cyhhdC5kZW1vY3JhY3ksIHJlcCgwLCBsZW5ndGgoYXQuZGVtb2NyYWN5KSksIHR5cGUgPSAibCIsIGNvbCA9ICJncmF5IikKCgpgYGAKCkludGVycHJldHRpbmcgdGhlIGFib3ZlIHBsb3Q6IFdoYXQgdGhpcyBwbG90IGRlbW9uc3RyYXRlcyBpcyB0aGUgc2xvcGUvZWZmZWN0L2JldG8gY29lZmZpY2llbnQgb2Ygd29tZW4gaW4gcGFybGlhbWVudCBhdCBkaWZmZmVyZW50IHZhbHVlcyBvZiBkZW1vY3JhY3kuIEZvciBleGFtcGxlLCB3aGVuIGRlbW9jcmFjeSBpcyAtNSwgdGhlcmUgaXMgbm8gZWZmZWN0IGZvciB3b21lbiBpbiBwYXJsaWFtZW50LiBXaGVuIGRlbW9jcmFjeSBpcyAxMCwgaG93ZXZlciwgdGhlIGVmZmVjdCBvZiB3b21lbiBpbiBwYXJsaWFtZW50IGdvZXMgdXAgdG8gLjIwLiBTbyB3aGVuIGRlbW9jcmFjeSBpcyBhdCAxMCwgZm9yIGV2ZXJ5IG9uZSBwZXJjZW50IGluY3JlYXNlIGluIHRoZSBhbW91bnQgb2Ygd29tZW4gaW4gcGFybGlhbWVudCwgdGhpcyBpcyBhc3NvY2lhdGVkIHdpdGggYSAuMjAgaW5jcmVhc2Ugb24gdGhlIExHQlRJIFBvbGljeSBJbmRleC4KCgojIFRocmVlLVdheSBJbnRlcmFjdGlvbnMKCmBgYHtyIGVjaG89VFJVRX0KIyBUaHJlZS1XYXkgSW50ZXJhY3Rpb24KCmxnYnRpLm1vZGVsLjUgPC0gbG0ocG9saWN5X2luZGV4IAogICAgICAgICAgICAgICAgICAgICAgfnBvbGl0eTJfdmRlbSArCiAgICAgICAgICAgICAgICAgICAgICB3b21lbl9wYXJsaWFtZW50ICsKICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPWxnYnRpX2RhdGEpCgoKbGdidGkubW9kZWwuNiA8LSBsbShwb2xpY3lfaW5kZXggCiAgICAgICAgICAgICAgICAgICAgICB+cG9saXR5Ml92ZGVtICoKICAgICAgICAgICAgICAgICAgICAgIHdvbWVuX3BhcmxpYW1lbnQgKgogICAgICAgICAgICAgICAgICAgICAgcmVnaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9bGdidGlfZGF0YSkKCiBzdGFyZ2F6ZXIobGdidGkubW9kZWwuNSwgbGdidGkubW9kZWwuNix0eXBlPSJ0ZXh0IiwgCiAgICAgICAgICBjb2x1bW4ubGFiZWxzID0gYygiTWFpbiBFZmZlY3RzIiwgIkludGVyYWN0aW9uIiksIAogICAgICAgICAgaW50ZXJjZXB0LmJvdHRvbSA9IEZBTFNFLCAKICAgICAgICAgIHNpbmdsZS5yb3c9RkFMU0UsICAgICAKICAgICAgICAgIG5vdGVzLmFwcGVuZCA9IEZBTFNFLCAKICAgICAgICAgIGhlYWRlcj1GQUxTRSkgCmBgYAoKYGBge3IgZWNobz1UUlVFfQojUGxvdHRpbmcgdXNpbmcgdGhlIHNqUGxvdCBwYWNrYWdlCnBsb3RfbW9kZWwobGdidGkubW9kZWwuNiwgdHlwZSA9ICJwcmVkIiwgdGVybXMgPSBjKCJwb2xpdHkyX3ZkZW0iLCAid29tZW5fcGFybGlhbWVudFs0LjczLCAxNS43NSwyNi43N10iLCAicmVnaW9uIikpICsgdGhlbWVfYncoKSAjUmVtb3ZlcyB0aGUgZ3JheSBiYWNrZ3JvdW5kIAoKYGBgCgoKYGBge3IgZWNobz1UUlVFfQoKI1Bsb3R0aW5nIHVzaW5nIGludGVyYWN0aW9ucyBwYWNrYWdlCgpwcm9iZV9pbnRlcmFjdGlvbihsZ2J0aS5tb2RlbC42LCBwcmVkID0gd29tZW5fcGFybGlhbWVudCwgbW9keCA9IHJlZ2lvbiwgbW9kMiA9IHBvbGl0eTJfdmRlbSwKICAgICAgICAgICAgICAgICAgYWxwaGEgPSAuMSkKYGBgCgoKCiMgUmVmZXJlbmNlcwpJbnRlcmFjdGlvbiB0dXRvcmlhbHMgcHJvdmlkZWQgYnkgW1VuaXZlcnNpdHkgb2YgSWxsaW5vaXMtQ2hpY2Fnb10oaHR0cHM6Ly9hZGVtb3MucGVvcGxlLnVpYy5lZHUvQ2hhcHRlcjEzLmh0bWwpCgpbU2ViYXN0aWFuIFNhdWVyJ3MgQmxvZ10oaHR0cHM6Ly9zZWJhc3RpYW5zYXVlci5naXRodWIuaW8vdmlzX2ludGVyYWN0aW9uX2VmZmVjdHMvKQoKW0d1aWRlIHRvIGdncGxvdDJdKGh0dHA6Ly9yLXN0YXRpc3RpY3MuY28vQ29tcGxldGUtR2dwbG90Mi1UdXRvcmlhbC1QYXJ0MS1XaXRoLVItQ29kZS5odG1sKQoKW0tpZXJhbiBIZWFseSdzIERhdGEgVmlzdWFsaXphdGlvbiBHdWlkZV0oaHR0cHM6Ly9zb2N2aXouY28vaW5kZXguaHRtbCNwcmVmYWNlKQ==