Packages

Loading packages:

library(lme4)
library(dplyr)
library(stargazer)
library(ggplot2)
library(ggeffects)
library(nnet)

Data

Loading the data:

load('/Users/davidhamad/Documents/Cand.Scient.Pol/2. Semester/Statistical models beyond linear regression - applied statistics for political scientists/11-12) Count outcomes/df_yoshinaka.rda')
df <- df_yoshinaka %>% as.data.frame()

Exercise 1

Question 1: Estimate a poisson model and report the results in a table.

Answer 1: The Poisson model estimates how many legislative reports each MEP handles per month, using log(months) as an offset to account for time on the committee. The predictors are ideological distance to the EP group (the main hypothesis), distance to the national party (a competing explanation), and committee expertise (a control). All three are significant: both distance variables are negative, and experts get about 25% more reports.

# Estimate Poisson model 
mod.pois <- glm(nreports ~ 
                  nom_dist1_ep +
                  nom_dist1_nat +
                  ctee_expert +
                  offset(log(months)),
                family = "poisson",
                data = df)
# Report in a table
stargazer(mod.pois,
          title = "Poisson regression of legislative reports per MEP",
          dep.var.labels = "Number of reports",
          covariate.labels = c("Distance to EP group",
                               "Distance to national party",
                               "Committee expert"),
          digits = 2,
          type = "text")

Poisson regression of legislative reports per MEP
======================================================
                               Dependent variable:    
                           ---------------------------
                                Number of reports     
------------------------------------------------------
Distance to EP group                -0.85***          
                                     (0.28)           
                                                      
Distance to national party           -0.94**          
                                     (0.44)           
                                                      
Committee expert                     0.22***          
                                     (0.05)           
                                                      
Constant                            -3.08***          
                                     (0.04)           
                                                      
------------------------------------------------------
Observations                           898            
Log Likelihood                      -1,868.37         
Akaike Inf. Crit.                   3,744.74          
======================================================
Note:                      *p<0.1; **p<0.05; ***p<0.01
(exp(coef(mod.pois)["ctee_expert"]) - 1) * 100
ctee_expert 
   24.97171 

Question 2: Calculate and plot the standardized residuals of the model against the fitted/predicted values.

Answer 2: The plot shows the standardized residuals (z) against the fitted values from the Poisson model. Most residuals lie between approximately −2 and +2, but several observations have z-values well above +5, with the most extreme reaching about +13. The spread also increases with the fitted values, which suggests that the Poisson assumption of equidispersion may not hold.

# Calculate fitted values and standardized residuals
df.plot <- data.frame(
  fitted = predict(mod.pois, type = "response"),
  z      = residuals(mod.pois, type = "pearson")
)
# Plot
ggplot(df.plot, aes(x = fitted, y = z)) +
  geom_point(alpha = 0.4) +
  labs(x = "Fitted values",
       y = "Standardized residuals (z)",
       title = "Standardized residuals vs. fitted values") +
  theme_minimal()


Question 3: Draw a horizontal line at y = 0 and two additional horizontal lines at ±2 (or 1.96). The standardized residuals are supposed to be in this bound. How does it look? Can you explain the high z values?

Answer 3: Most standardized residuals fall within the ±2 bound, but a substantial number of observations lie well above +2, with several reaching values between +5 and +13. The high z-values indicate that the model substantially underestimates the number of reports for the most productive MEPs. This is a sign of overdispersion. The variance of the data exceeds what the Poisson model assumes. Likely sources include omitted variables (such as activity, chair status, or committee fixed effects) that distinguish highly productive MEPs from the average, or positive contagion (the tendency for MEPs who already have one report to receive more).

# Plot
ggplot(df.plot, aes(x = fitted, y = z)) +
  geom_point(alpha = 0.4) +
  geom_hline(yintercept = 0, color = "black") +
  geom_hline(yintercept = c(-2, 2), color = "red", linetype = "dashed") +
  labs(x = "Fitted values",
       y = "Standardized residuals (z)",
       title = "Standardized residuals vs. fitted values") +
  theme_minimal()


Question 4: Use the instructions in Gelman and Hill (2007), p. 114 to calculate a measure of overdispersion.

Answer 4: Following Gelman & Hill (2007), the estimated overdispersion is calculated as the sum of squared standardized residuals divided by the expected value n − k. The sum of squared residuals is 2,725.72, compared to the expected value of 894, giving an overdispersion ratio of 3.05. Since any value above 2 is considered large, this confirms substantial overdispersion in the data. The Poisson model’s standard errors are therefore too small, and the reported significance levels are overstated. This motivates fitting a model that allows for greater variance, such as a quasi-Poisson or negative binomial.

# Standardized residuals (Pearson)
z <- residuals(mod.pois, type = "pearson")
# Sum of squared standardized residuals
sum_z2 <- sum(z^2)
# Expected value (n - k)
n <- length(z)
k <- length(mod.pois$coefficients)
# Overdispersion ratio
ratio <- sum_z2 / (n - k)
# Print results (1)
sum_z2
[1] 2725.72
# Print results (2)
n - k
[1] 894
# Print results (2)
ratio
[1] 3.048904

Exercise 2

Question 1: Create an effect plot where you illustrate the effect of ideology on influence. Remember that the poisson backtransformation only implies taking the exponent!

Answer 1: The figure shows the predicted number of legislative reports as a function of ideological distance to the EP group median, holding the other predictors at their typical values. The y-axis is on the response scale, obtained by exponentiating the linear predictor. MEPs at the group median are predicted to receive about 2 reports, while those at the largest observed distance are predicted to receive less than 1. The relationship is non-linear due to the exponential link, with the effect being most pronounced at small distances and flattening out at larger ones. The shaded area represents the 95% confidence interval, which widens at extreme values where fewer observations exist.

ggpredict(mod.pois, terms = "nom_dist1_ep") |>
  plot() +
  labs(x = "Distance to EP group median",
       y = "Predicted number of reports",
       title = "Effect of ideological distance to EP group on legislative reports")

LS0tCnRpdGxlOiAiRXZlbnQgY291bnQgbW9kZWxzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7Y3NzIFNldHVwLCBlY2hvPUZBTFNFfQpib2R5e3RleHQtYWxpZ246IEp1c3RpZnk7fQpoMS50aXRsZSB7Ym9yZGVyLWJvdHRvbTogM3B4IHNvbGlkIGJsYWNrOyBwYWRkaW5nLWJvdHRvbTogMTBweDt9CmBgYApgYGB7ciBTZXR0aW5nIHdvcmtpbmcgZGlyZWN0b3J5LCBlY2hvPUZBTFNFfQpzZXR3ZCgnL1VzZXJzL2RhdmlkaGFtYWQvRG9jdW1lbnRzL0NhbmQuU2NpZW50LlBvbC8yLiBTZW1lc3Rlci9TdGF0aXN0aWNhbCBtb2RlbHMgYmV5b25kIGxpbmVhciByZWdyZXNzaW9uIC0gYXBwbGllZCBzdGF0aXN0aWNzIGZvciBwb2xpdGljYWwgc2NpZW50aXN0cy8xMS0xMikgQ291bnQgb3V0Y29tZXMnKQpgYGAKCiMjIFBhY2thZ2VzCkxvYWRpbmcgcGFja2FnZXM6CgpgYGB7ciBMb2FkaW5nIHBhY2thZ2VzfQpsaWJyYXJ5KGxtZTQpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoc3RhcmdhemVyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2dlZmZlY3RzKQpsaWJyYXJ5KG5uZXQpCmBgYAoKLS0tCgojIyBEYXRhCkxvYWRpbmcgdGhlIGRhdGE6CgpgYGB7ciBMb2FkaW5nIHRoZSBkYXRhfQpsb2FkKCcvVXNlcnMvZGF2aWRoYW1hZC9Eb2N1bWVudHMvQ2FuZC5TY2llbnQuUG9sLzIuIFNlbWVzdGVyL1N0YXRpc3RpY2FsIG1vZGVscyBiZXlvbmQgbGluZWFyIHJlZ3Jlc3Npb24gLSBhcHBsaWVkIHN0YXRpc3RpY3MgZm9yIHBvbGl0aWNhbCBzY2llbnRpc3RzLzExLTEyKSBDb3VudCBvdXRjb21lcy9kZl95b3NoaW5ha2EucmRhJykKYGBgCgpgYGB7ciBSZW5hbWluZyB0aGUgZGF0YX0KZGYgPC0gZGZfeW9zaGluYWthICU+JSBhcy5kYXRhLmZyYW1lKCkKYGBgCgotLS0KCiMjIEV4ZXJjaXNlIDEKCioqUXVlc3Rpb24gMToqKiBFc3RpbWF0ZSBhIHBvaXNzb24gbW9kZWwgYW5kIHJlcG9ydCB0aGUgcmVzdWx0cyBpbiBhIHRhYmxlLgoKKipBbnN3ZXIgMToqKiBUaGUgUG9pc3NvbiBtb2RlbCBlc3RpbWF0ZXMgaG93IG1hbnkgbGVnaXNsYXRpdmUgcmVwb3J0cyBlYWNoIE1FUCBoYW5kbGVzIHBlciBtb250aCwgdXNpbmcgbG9nKG1vbnRocykgYXMgYW4gb2Zmc2V0IHRvIGFjY291bnQgZm9yIHRpbWUgb24gdGhlIGNvbW1pdHRlZS4gVGhlIHByZWRpY3RvcnMgYXJlIGlkZW9sb2dpY2FsIGRpc3RhbmNlIHRvIHRoZSBFUCBncm91cCAodGhlIG1haW4gaHlwb3RoZXNpcyksIGRpc3RhbmNlIHRvIHRoZSBuYXRpb25hbCBwYXJ0eSAoYSBjb21wZXRpbmcgZXhwbGFuYXRpb24pLCBhbmQgY29tbWl0dGVlIGV4cGVydGlzZSAoYSBjb250cm9sKS4gQWxsIHRocmVlIGFyZSBzaWduaWZpY2FudDogYm90aCBkaXN0YW5jZSB2YXJpYWJsZXMgYXJlIG5lZ2F0aXZlLCBhbmQgZXhwZXJ0cyBnZXQgYWJvdXQgMjUlIG1vcmUgcmVwb3J0cy4KCmBgYHtyIEVzdGltYXRpbmcgUG9pc3NvbiBtb2RlbH0KIyBFc3RpbWF0ZSBQb2lzc29uIG1vZGVsIAptb2QucG9pcyA8LSBnbG0obnJlcG9ydHMgfiAKICAgICAgICAgICAgICAgICAgbm9tX2Rpc3QxX2VwICsKICAgICAgICAgICAgICAgICAgbm9tX2Rpc3QxX25hdCArCiAgICAgICAgICAgICAgICAgIGN0ZWVfZXhwZXJ0ICsKICAgICAgICAgICAgICAgICAgb2Zmc2V0KGxvZyhtb250aHMpKSwKICAgICAgICAgICAgICAgIGZhbWlseSA9ICJwb2lzc29uIiwKICAgICAgICAgICAgICAgIGRhdGEgPSBkZikKYGBgCgpgYGB7ciBSZXBvcnRpbmcgUG9pc3NvbiBtb2RlbCBpbiBhIHRhYmxlfQojIFJlcG9ydCBpbiBhIHRhYmxlCnN0YXJnYXplcihtb2QucG9pcywKICAgICAgICAgIHRpdGxlID0gIlBvaXNzb24gcmVncmVzc2lvbiBvZiBsZWdpc2xhdGl2ZSByZXBvcnRzIHBlciBNRVAiLAogICAgICAgICAgZGVwLnZhci5sYWJlbHMgPSAiTnVtYmVyIG9mIHJlcG9ydHMiLAogICAgICAgICAgY292YXJpYXRlLmxhYmVscyA9IGMoIkRpc3RhbmNlIHRvIEVQIGdyb3VwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXN0YW5jZSB0byBuYXRpb25hbCBwYXJ0eSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ29tbWl0dGVlIGV4cGVydCIpLAogICAgICAgICAgZGlnaXRzID0gMiwKICAgICAgICAgIHR5cGUgPSAidGV4dCIpCmBgYAoKYGBge3IgQ29taXR0ZWUgZXhwZXJ0IGV4dHJhIGNhbGN1bGF0aW9ufQooZXhwKGNvZWYobW9kLnBvaXMpWyJjdGVlX2V4cGVydCJdKSAtIDEpICogMTAwCmBgYAoKLS0tCgoqKlF1ZXN0aW9uIDI6KiogQ2FsY3VsYXRlIGFuZCBwbG90IHRoZSBzdGFuZGFyZGl6ZWQgcmVzaWR1YWxzIG9mIHRoZSBtb2RlbCBhZ2FpbnN0IHRoZSBmaXR0ZWQvcHJlZGljdGVkIHZhbHVlcy4KCioqQW5zd2VyIDI6KiogVGhlIHBsb3Qgc2hvd3MgdGhlIHN0YW5kYXJkaXplZCByZXNpZHVhbHMgKHopIGFnYWluc3QgdGhlIGZpdHRlZCB2YWx1ZXMgZnJvbSB0aGUgUG9pc3NvbiBtb2RlbC4gTW9zdCByZXNpZHVhbHMgbGllIGJldHdlZW4gYXBwcm94aW1hdGVseSDiiJIyIGFuZCArMiwgYnV0IHNldmVyYWwgb2JzZXJ2YXRpb25zIGhhdmUgei12YWx1ZXMgd2VsbCBhYm92ZSArNSwgd2l0aCB0aGUgbW9zdCBleHRyZW1lIHJlYWNoaW5nIGFib3V0ICsxMy4gVGhlIHNwcmVhZCBhbHNvIGluY3JlYXNlcyB3aXRoIHRoZSBmaXR0ZWQgdmFsdWVzLCB3aGljaCBzdWdnZXN0cyB0aGF0IHRoZSBQb2lzc29uIGFzc3VtcHRpb24gb2YgZXF1aWRpc3BlcnNpb24gbWF5IG5vdCBob2xkLgoKYGBge3IgRml0dGVkIHZhbHVlcyBhbmQgc3RhbmRhcmRpemVkIHJlc2lkdWFsc30KIyBDYWxjdWxhdGUgZml0dGVkIHZhbHVlcyBhbmQgc3RhbmRhcmRpemVkIHJlc2lkdWFscwpkZi5wbG90IDwtIGRhdGEuZnJhbWUoCiAgZml0dGVkID0gcHJlZGljdChtb2QucG9pcywgdHlwZSA9ICJyZXNwb25zZSIpLAogIHogICAgICA9IHJlc2lkdWFscyhtb2QucG9pcywgdHlwZSA9ICJwZWFyc29uIikKKQpgYGAKCmBgYHtyIFBsb3QgZm9yIFEyIGluIEV4ZXJjaXNlIDF9CiMgUGxvdApnZ3Bsb3QoZGYucGxvdCwgYWVzKHggPSBmaXR0ZWQsIHkgPSB6KSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjQpICsKICBsYWJzKHggPSAiRml0dGVkIHZhbHVlcyIsCiAgICAgICB5ID0gIlN0YW5kYXJkaXplZCByZXNpZHVhbHMgKHopIiwKICAgICAgIHRpdGxlID0gIlN0YW5kYXJkaXplZCByZXNpZHVhbHMgdnMuIGZpdHRlZCB2YWx1ZXMiKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKLS0tCgoqKlF1ZXN0aW9uIDM6KiogRHJhdyBhIGhvcml6b250YWwgbGluZSBhdCB5ID0gMCBhbmQgdHdvIGFkZGl0aW9uYWwgaG9yaXpvbnRhbCBsaW5lcyBhdCDCsTIgKG9yIDEuOTYpLiBUaGUgc3RhbmRhcmRpemVkIHJlc2lkdWFscyBhcmUgc3VwcG9zZWQgdG8gYmUgaW4gdGhpcyBib3VuZC4gSG93IGRvZXMgaXQgbG9vaz8gQ2FuIHlvdSBleHBsYWluIHRoZSBoaWdoIHogdmFsdWVzPwoKKipBbnN3ZXIgMzoqKiBNb3N0IHN0YW5kYXJkaXplZCByZXNpZHVhbHMgZmFsbCB3aXRoaW4gdGhlIMKxMiBib3VuZCwgYnV0IGEgc3Vic3RhbnRpYWwgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyBsaWUgd2VsbCBhYm92ZSArMiwgd2l0aCBzZXZlcmFsIHJlYWNoaW5nIHZhbHVlcyBiZXR3ZWVuICs1IGFuZCArMTMuIFRoZSBoaWdoIHotdmFsdWVzIGluZGljYXRlIHRoYXQgdGhlIG1vZGVsIHN1YnN0YW50aWFsbHkgdW5kZXJlc3RpbWF0ZXMgdGhlIG51bWJlciBvZiByZXBvcnRzIGZvciB0aGUgbW9zdCBwcm9kdWN0aXZlIE1FUHMuIFRoaXMgaXMgYSBzaWduIG9mIG92ZXJkaXNwZXJzaW9uLiBUaGUgdmFyaWFuY2Ugb2YgdGhlIGRhdGEgZXhjZWVkcyB3aGF0IHRoZSBQb2lzc29uIG1vZGVsIGFzc3VtZXMuIExpa2VseSBzb3VyY2VzIGluY2x1ZGUgb21pdHRlZCB2YXJpYWJsZXMgKHN1Y2ggYXMgYWN0aXZpdHksIGNoYWlyIHN0YXR1cywgb3IgY29tbWl0dGVlIGZpeGVkIGVmZmVjdHMpIHRoYXQgZGlzdGluZ3Vpc2ggaGlnaGx5IHByb2R1Y3RpdmUgTUVQcyBmcm9tIHRoZSBhdmVyYWdlLCBvciBwb3NpdGl2ZSBjb250YWdpb24gKHRoZSB0ZW5kZW5jeSBmb3IgTUVQcyB3aG8gYWxyZWFkeSBoYXZlIG9uZSByZXBvcnQgdG8gcmVjZWl2ZSBtb3JlKS4KCmBgYHtyIFBsb3QgZm9yIFEzIGluIEV4ZXJjaXNlIDF9CiMgUGxvdApnZ3Bsb3QoZGYucGxvdCwgYWVzKHggPSBmaXR0ZWQsIHkgPSB6KSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjQpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBjKC0yLCAyKSwgY29sb3IgPSAicmVkIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogIGxhYnMoeCA9ICJGaXR0ZWQgdmFsdWVzIiwKICAgICAgIHkgPSAiU3RhbmRhcmRpemVkIHJlc2lkdWFscyAoeikiLAogICAgICAgdGl0bGUgPSAiU3RhbmRhcmRpemVkIHJlc2lkdWFscyB2cy4gZml0dGVkIHZhbHVlcyIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgotLS0KCioqUXVlc3Rpb24gNDoqKiBVc2UgdGhlIGluc3RydWN0aW9ucyBpbiBHZWxtYW4gYW5kIEhpbGwgKDIwMDcpLCBwLiAxMTQgdG8gY2FsY3VsYXRlIGEgbWVhc3VyZSBvZiBvdmVyZGlzcGVyc2lvbi4KCioqQW5zd2VyIDQ6KiogRm9sbG93aW5nIEdlbG1hbiAmIEhpbGwgKDIwMDcpLCB0aGUgZXN0aW1hdGVkIG92ZXJkaXNwZXJzaW9uIGlzIGNhbGN1bGF0ZWQgYXMgdGhlIHN1bSBvZiBzcXVhcmVkIHN0YW5kYXJkaXplZCByZXNpZHVhbHMgZGl2aWRlZCBieSB0aGUgZXhwZWN0ZWQgdmFsdWUgbiDiiJIgay4gVGhlIHN1bSBvZiBzcXVhcmVkIHJlc2lkdWFscyBpcyAyLDcyNS43MiwgY29tcGFyZWQgdG8gdGhlIGV4cGVjdGVkIHZhbHVlIG9mIDg5NCwgZ2l2aW5nIGFuIG92ZXJkaXNwZXJzaW9uIHJhdGlvIG9mIDMuMDUuIFNpbmNlIGFueSB2YWx1ZSBhYm92ZSAyIGlzIGNvbnNpZGVyZWQgbGFyZ2UsIHRoaXMgY29uZmlybXMgc3Vic3RhbnRpYWwgb3ZlcmRpc3BlcnNpb24gaW4gdGhlIGRhdGEuIFRoZSBQb2lzc29uIG1vZGVsJ3Mgc3RhbmRhcmQgZXJyb3JzIGFyZSB0aGVyZWZvcmUgdG9vIHNtYWxsLCBhbmQgdGhlIHJlcG9ydGVkIHNpZ25pZmljYW5jZSBsZXZlbHMgYXJlIG92ZXJzdGF0ZWQuIFRoaXMgbW90aXZhdGVzIGZpdHRpbmcgYSBtb2RlbCB0aGF0IGFsbG93cyBmb3IgZ3JlYXRlciB2YXJpYW5jZSwgc3VjaCBhcyBhIHF1YXNpLVBvaXNzb24gb3IgbmVnYXRpdmUgYmlub21pYWwuCgpgYGB7ciBQZWFyc29ufQojIFN0YW5kYXJkaXplZCByZXNpZHVhbHMgKFBlYXJzb24pCnogPC0gcmVzaWR1YWxzKG1vZC5wb2lzLCB0eXBlID0gInBlYXJzb24iKQpgYGAKCmBgYHtyIFNxdWFyZWQgc3RhbmRhcmRpemVkIHJlc2lkdWFsc30KIyBTdW0gb2Ygc3F1YXJlZCBzdGFuZGFyZGl6ZWQgcmVzaWR1YWxzCnN1bV96MiA8LSBzdW0oel4yKQpgYGAKCmBgYHtyIEV4cGVjdGVkIHZhbHVlfQojIEV4cGVjdGVkIHZhbHVlIChuIC0gaykKbiA8LSBsZW5ndGgoeikKayA8LSBsZW5ndGgobW9kLnBvaXMkY29lZmZpY2llbnRzKQpgYGAKCmBgYHtyIE92ZXJkaXNwZXJzaW9uIHJhdGlvfQojIE92ZXJkaXNwZXJzaW9uIHJhdGlvCnJhdGlvIDwtIHN1bV96MiAvIChuIC0gaykKYGBgCgpgYGB7ciBQcmludCByZXN1bHRzICgxKX0KIyBQcmludCByZXN1bHRzICgxKQpzdW1fejIKYGBgCgpgYGB7ciBQcmludCByZXN1bHRzICgyKX0KIyBQcmludCByZXN1bHRzICgyKQpuIC0gawpgYGAKCmBgYHtyIFByaW50IHJlc3VsdHMgKDMpfQojIFByaW50IHJlc3VsdHMgKDIpCnJhdGlvCmBgYAoKLS0tCgojIyBFeGVyY2lzZSAyCgoqKlF1ZXN0aW9uIDE6KiogQ3JlYXRlIGFuIGVmZmVjdCBwbG90IHdoZXJlIHlvdSBpbGx1c3RyYXRlIHRoZSBlZmZlY3Qgb2YgaWRlb2xvZ3kgb24gaW5mbHVlbmNlLiBSZW1lbWJlciB0aGF0IHRoZSBwb2lzc29uIGJhY2t0cmFuc2Zvcm1hdGlvbiBvbmx5IGltcGxpZXMgdGFraW5nIHRoZSBleHBvbmVudCEKCioqQW5zd2VyIDE6KiogVGhlIGZpZ3VyZSBzaG93cyB0aGUgcHJlZGljdGVkIG51bWJlciBvZiBsZWdpc2xhdGl2ZSByZXBvcnRzIGFzIGEgZnVuY3Rpb24gb2YgaWRlb2xvZ2ljYWwgZGlzdGFuY2UgdG8gdGhlIEVQIGdyb3VwIG1lZGlhbiwgaG9sZGluZyB0aGUgb3RoZXIgcHJlZGljdG9ycyBhdCB0aGVpciB0eXBpY2FsIHZhbHVlcy4gVGhlIHktYXhpcyBpcyBvbiB0aGUgcmVzcG9uc2Ugc2NhbGUsIG9idGFpbmVkIGJ5IGV4cG9uZW50aWF0aW5nIHRoZSBsaW5lYXIgcHJlZGljdG9yLiBNRVBzIGF0IHRoZSBncm91cCBtZWRpYW4gYXJlIHByZWRpY3RlZCB0byByZWNlaXZlIGFib3V0IDIgcmVwb3J0cywgd2hpbGUgdGhvc2UgYXQgdGhlIGxhcmdlc3Qgb2JzZXJ2ZWQgZGlzdGFuY2UgYXJlIHByZWRpY3RlZCB0byByZWNlaXZlIGxlc3MgdGhhbiAxLiBUaGUgcmVsYXRpb25zaGlwIGlzIG5vbi1saW5lYXIgZHVlIHRvIHRoZSBleHBvbmVudGlhbCBsaW5rLCB3aXRoIHRoZSBlZmZlY3QgYmVpbmcgbW9zdCBwcm9ub3VuY2VkIGF0IHNtYWxsIGRpc3RhbmNlcyBhbmQgZmxhdHRlbmluZyBvdXQgYXQgbGFyZ2VyIG9uZXMuIFRoZSBzaGFkZWQgYXJlYSByZXByZXNlbnRzIHRoZSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCwgd2hpY2ggd2lkZW5zIGF0IGV4dHJlbWUgdmFsdWVzIHdoZXJlIGZld2VyIG9ic2VydmF0aW9ucyBleGlzdC4KCmBgYHtyfQpnZ3ByZWRpY3QobW9kLnBvaXMsIHRlcm1zID0gIm5vbV9kaXN0MV9lcCIpIHw+CiAgcGxvdCgpICsKICBsYWJzKHggPSAiRGlzdGFuY2UgdG8gRVAgZ3JvdXAgbWVkaWFuIiwKICAgICAgIHkgPSAiUHJlZGljdGVkIG51bWJlciBvZiByZXBvcnRzIiwKICAgICAgIHRpdGxlID0gIkVmZmVjdCBvZiBpZGVvbG9naWNhbCBkaXN0YW5jZSB0byBFUCBncm91cCBvbiBsZWdpc2xhdGl2ZSByZXBvcnRzIikKYGBgCgo=