Difference in Differences Regressions - Data from Snow 1855

See “Causality in the Time of Cholera” working paper at https://papers.ssrn.com/abstract=3262234 and my John Snow project website

This notebook is licensed under the BSD 2-Clause License

Introduction

This notebook performs linear and count regressions for 1849 versus 1854 data and builds on the discussion and data in the notebook “Snow1855_SimpleDiD_QRCT” - read that first.

For a brief introduction to Snow’s work, see:

  • Snow’s original 1855 monograph (it is masterful): Snow, John. 1855. On the Mode of Communication of Cholera. 2nd ed. London: John Churchill. http://archive.org/details/b28985266.
  • The best popular exposition I have found: Johnson, Steven. 2007. The Ghost Map: The Story of London’s Most Terrifying Epidemic–and How It Changed Science, Cities, and the Modern World. Reprint edition. New York: Riverhead Books.
  • Another good popular version: Hempel, Sandra. 2007. The Strange Case of the Broad Street Pump: John Snow and the Mystery of Cholera. First edition. Berkeley: University of California Press.
  • Tufte’s classic discussion of Snow’s mapping (a topic I don’t cover here): Tufte, Edward R. 1997. Visual Explanations: Images and Quantities, Evidence and Narrative. 1st edition. Graphics Press.
  • Biography: Vinten-Johansen, Peter, Howard Brody, Nigel Paneth, Stephen Rachman, and Michael Russell Rip. 2003. Cholera, Chloroform and the Science of Medicine: A Life of John Snow. Oxford; New York: Oxford University Press. Linked on-line resources https://johnsnow.matrix.msu.edu/snowworks.php

This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code. The results are also saved in a self-contained html document with the suffix .nb.html. If you want pure r code (for example to run outside RStudio) you can easily extract code with the command knit(‘notebook.Rmd’,tangle=TRUE) which will save a file ‘notebook.R’ under your working directory.

Try executing the chunk below by clicking the Run button within the chunk or by placing your cursor inside it and pressing Cmd+Shift+Enter.

NB: We need the data and some of the calculations from the notebook ‘Snow1855_SimpleDiD_QRCT.Rmd’ so we execute this little hack to extract the R code from that sheet, write a new .R file, and then source that here

# Copyright (c) 2019, Thomas Coleman
#
#  -------  Licensed under BSD 2-Clause "Simplified" License  -------
#
# Results and discussion in "Causality in the Time of Cholera: John Snow as a Prototype 
# for Causal Inference (Working Paper)" available at SSRN: https://papers.ssrn.com/abstract=3262234
library(knitr)
options(scipen=5)
knit('Snow1855_SimpleDiD_QRCT.Rmd', tangle=TRUE)
source('Snow1855_SimpleDiD_QRCT.R') 
# The following libraries are used for the Negative Binomial regression and the robust standard error analysis
#install.packages("sandwich")
#install.packages("lmtest")
library("MASS")
library("sandwich") 
library("lmtest") 

Difference-in-Differences Framework

The basic difference-in-differences structure can be displayed in a table like:

Sub-districts 1849 Mortality (rate) 1854 Mortality (rate) Diff 1854 less 1849
First 12 Southwark-supplied \(\mu\) \(\mu + \delta 54\) \(\delta 54\)
Next 16 jointly-supplied \(\mu + \gamma\) \(\mu + \delta 54 + \gamma + \beta\) \(\delta 54 + \beta\)
Diff next-16 less first-12 \(\gamma\) \(\gamma + \beta\) \(\beta\)
# The diff-in-diffs table (levels) from the notebook 'Snow1855_SimpleDiD_QRCT.Rmd'
kable(diff_in_diffs_Level,digits=2,caption="Diff-in-Diffs, Levels (rate per 10,000)",format='pandoc')

Diff-in-Diffs, Levels (rate per 10,000)
level 1849 level 1854 col diffs
first 12 Southwark-only 134.86 146.61 11.75
next 16 Jointly-supplied 130.10 84.86 -45.24
row diffs -4.76 -61.75 -56.99

kable(diff_in_diffs_Log,digits=3,caption="Diff-in-Diffs, Levels (rate per 10,000)",format='pandoc')
Diff-in-Diffs, Levels (rate per 10,000)
log 1849 log 1854 col diffs
first 12 Southwark-only -4.306 -4.223 0.084
next 16 Jointly-supplied -4.342 -4.769 -0.427
row diffs -0.036 -0.547 -0.511

This table looks very simple, and with a population of over 450,000 (167654 in the “first-12” and 300149 in the “next-16”) we would think the estimate of -0.511 would be precisely estimated. In fact, we can run a Poisson regrssion, a count regression which seems the right way to fit this table and test for the statistical significance of the diff-in-diffs coefficient.

regdatasimple <- data.frame("deaths" = c(comparecounts1849_1854[1:2,]), "pop1851" = c(comparepop1849_1854[1:2,]))
regdatasimple$supplier <- c("SouthwarkVauxhall","SouthwarkVauxhall_Lambeth","SouthwarkVauxhall","SouthwarkVauxhall_Lambeth")
regdatasimple$year <- c("1849","1849","1854","1854")
pois1simple <- glm(deaths ~ supplier * year + offset(log(pop1851)), family=poisson, data=regdatasimple) 
summary(pois1simple)

Call:
glm(formula = deaths ~ supplier * year + offset(log(pop1851)), 
    family = poisson, data = regdatasimple)

Deviance Residuals: 
[1]  0  0  0  0

Coefficients:
                                           Estimate Std. Error  z value Pr(>|z|)    
(Intercept)                                -4.30610    0.02103 -204.755  < 2e-16 ***
supplierSouthwarkVauxhall_Lambeth          -0.03593    0.02643   -1.359  0.17400    
year1854                                    0.08354    0.02914    2.867  0.00414 ** 
supplierSouthwarkVauxhall_Lambeth:year1854 -0.51088    0.03870  -13.201  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for poisson family taken to be 1)

    Null deviance: 4.9099e+02  on 3  degrees of freedom
Residual deviance: 8.4466e-13  on 0  degrees of freedom
AIC: 46.995

Number of Fisher Scoring iterations: 2

The diff-in-diffs coffficient is supplierSouthwarkVauxhall_Lambeth:year1854 with the same value (in log terms) as the table above: -0.511 (in ratio terms - the increase in mortality for Southwark & Vauxhall customers versus Lambeth customers - this is 1.667). This appears to be very significant, with z value -13.2. But we would be wrong to rely on this regression.

We can see the reason when we examine the original data (Snow’s Table XII): there is considerable variation across sub-districts. Looking only at the first two sub-districts in 1849, for example, St. Saviour, Southwark has mortality of 143.6 while St. Olave, Southwark has mortality of 195.9. We cannot simply highlight and exploit the difference between the aggregate “first-12” and “next-16” sub-districts (the diff-in-diffs coefficient -0.5109) while ignoring the variability across and within sub-districts. We need some statistical framework to incorporate and analyze the variability both within and across sub-districts.

tablexii[,c(1,2,3,4,6,7)]

For a reasonable statistical framework we can consider the following equation, which puts the difference-in-differences table above into equation form but also allows multiple sub-districts - each sub-district having its own rate, etc.:

\(ln(Rate) = \mu + \delta 54*I(54) + \gamma*I(joint) + \beta*I(54)*I(joint) + \epsilon\)

  • an overall constant (\(\mu\))
  • a difference for 1854 (\(\delta54\))
  • a difference for joint “next 16” region (\(\gamma\))
  • an interaction for 1854 and joint (\(\beta\))

For various reasons we want to run this as linear-in-logs rather than linear-in-rates.

Formatting the regression data

To run this as a regression we need to take the death counts from Table XII (deaths by sub-district), combine with population from Table VIII for calculating rates, incorporate proper indicator variables, and then stack the data. Our original data (the .csv files read in above) have a variable “supplier” that acts as indicator for “first-12” (Southwark-only supply) versus “next-16” (jointly-supplied) sub-districts and another (“lambethdegree”) that serves as an indicator for “Southwark-only”, “less-Lambeth” and “more-Lambeth” supply. We need to construct a year factor (1849 versus 1854). The stacking an indicator construction is executed with the following code chunk.

x1 <- subset(tableviii,supplier == "SouthwarkVauxhall" | supplier == "SouthwarkVauxhall_Lambeth")
x1849 <- x1[c("subDistrict","pop1851","supplier","lambethdegree")]
x1 <- subset(tablexii,supplier == "SouthwarkVauxhall" | supplier == "SouthwarkVauxhall_Lambeth")
x1849$deaths <- x1$deaths1849
x1849$rate <- 10000 * x1$deaths1849 / x1849$pop1851
x1849$seq <- c(seq(1,length(x1849$deaths)))
#x1849$dum1854 <- 0
xyear <- factor(c(rep(1849,28),rep(1854,28)))
x1849$year <- xyear[1:28]
x1854 <- x1849
#x1849$lambethdegree <- "dirty"
x1854$deaths <- x1$deaths1854
x1854$rate <- 10000 * x1$deaths1854 / x1849$pop1851
x1854$seq <- c(seq(1,length(x1849$deaths)))
#x1854$dum1854 <- 1
x1854$year <- xyear[29:56]
regdata <- rbind(x1849,x1854)
regdata

Linear Regressions

We can start out by running a linear regression (linear in logs). The following code chunk executes three linear regressions but only displays the first: with Lambeth-supplier (“supplier” or “first-12” vs “next-16”) and year indicators.

# Linear-in-logs with Lambeth ("supplier" or "first-12" vs "next-16") and year indicators
lin1single <- lm(log(rate/10000) ~ supplier * year, data=regdata) 
lin1singlerobustse <- coeftest(lin1single, vcov = vcovHC(lin1single))
summary(lin1single)

Call:
lm(formula = log(rate/10000) ~ supplier * year, data = regdata)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.9897 -0.1435  0.1538  0.3184  0.8443 

Coefficients:
                                           Estimate Std. Error t value Pr(>|t|)    
(Intercept)                                -4.50256    0.16643 -27.053   <2e-16 ***
supplierSouthwarkVauxhall_Lambeth           0.07770    0.22017   0.353   0.7256    
year1854                                    0.07392    0.23537   0.314   0.7547    
supplierSouthwarkVauxhall_Lambeth:year1854 -0.56665    0.31137  -1.820   0.0745 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.5765 on 52 degrees of freedom
Multiple R-squared:  0.1288,    Adjusted R-squared:  0.07852 
F-statistic: 2.562 on 3 and 52 DF,  p-value: 0.06473
# Linear-in-logs with two Lambeth indicators ("first-12" vs "next-16 split into less_lambeth" and "more_lambeth") and year indicators
lin1both <- lm(log(rate/10000) ~ lambethdegree * year, data=regdata) 
lin1bothrobustse <- coeftest(lin1both, vcov = vcovHC(lin1both))
# Linear-in-logs with sub-district fixed effects and Lambeth ("supplier" or "first-12" vs "next-16") and year indicators
lin2both <- lm(log(rate/10000) ~ subDistrict + lambethdegree * year, data=regdata) 
lin2bothrobustse <- coeftest(lin2both, vcov = vcovHC(lin2both))

The coefficient we are interested in is the last: supplierSouthwarkVauxhall_Lambeth:year1854: the coefficient \(\beta\) in the equation above. This calculates the average Lambeth effect, averaged across the sub-districts. The standard errors measure the precision of our estimated average based on the variation across sub-districts.

But here is an important puzzle: why is the coefficient -0.567 not the same as the calculated Lambeth effect in the table above (-0.511)? The reason is that the linear regressios are not correct, and this leads to our next topic.

Poisson Count Regressions

The linear-in-logs regression above looks correct but it is not: we have implicitely assumed that the error term \(\epsilon\) is normal and this cannot be correct. To see why, re-write the regression equation (using the fact that Rate = Count/Population so that ln(Rate) = ln(Count)-ln(Population)) as

\(ln(Count) = \mu + \delta 54*I(54) + \gamma*I(joint) + \beta*I(54)*I(joint) + \epsilon + ln(Population)\)

Count is the number of deaths and can only take non-negative integer values, so the error \(\epsilon\) cannot be Normal. It can, however, be Poisson. (For a discussion of the Poisson distribution and Poisson and Negative Binomial regression see my working paper at https://papers.ssrn.com/abstract=3262234 and the references therein.) There are various routines in R and other statstical packages for running regression assuming that the error \(\epsilon\) is Poisson (or other count distributions such as Negative Binomial).

The following code chunk runs Poisson regressions. The various combinations of single versus two Lambeth (treatment) effects and fixed effects are discussed in my working paper at https://papers.ssrn.com/abstract=3262234

# Poisson with single "Lambeth effect" and same rate for all sub-districts (no sub-district fixed effects)
pois1single <- glm(deaths ~ supplier * year 
    + offset(log(pop1851)), family=poisson, data=regdata) 
pois1singlerobustse <- coeftest(pois1single, vcov = vcovHC(pois1single))
#summary(pois1single)
#logLik(pois1single)
# Poisson with two "Lambeth effects" and same rate for all sub-districts (no sub-district fixed effects)
pois1both <- glm(deaths ~ lambethdegree * year 
    + offset(log(pop1851)), family=poisson, data=regdata) 
pois1bothrobustse <- coeftest(pois1both, vcov = vcovHC(pois1both))
#summary(pois1both)
#logLik(pois1both)
# Poisson with single "Lambeth effect" and different rates by sub-district (fixed effects)
pois2single <- glm(deaths ~ subDistrict + supplier * year 
    + offset(log(pop1851)), family=poisson, data=regdata) 
pois2singlerobustse <- coeftest(pois2single, vcov = vcovHC(pois2single))
#summary(pois2single)
#logLik(pois2single)
# Poisson with two "Lambeth effects" and different rates by sub-district (fixed effects)
pois2both <- glm(deaths ~ subDistrict + supplier * year 
    + offset(log(pop1851)), family=poisson, data=regdata) 
pois2bothrobustse <- coeftest(pois2both, vcov = vcovHC(pois2both))
#summary(pois2both)
#logLik(pois2both)
# NB: The robust standard errors approach I found at:
#  https://stat.ethz.ch/pipermail/r-help/2008-May/161591.html
#Then click on "Next message:" for the second. Unfortunately, 
#at that point the thread broke 
# So to continue, next take: 
#  https://stat.ethz.ch/pipermail/r-help/2008-May/161640.html
#and thereafter continue to click on "Next message:" until the 
#thread runs out. 
# Also cf https://stats.stackexchange.com/questions/117052/replicating-statas-robust-option-in-r
# NB: STATA seems to use HC1 for robust BUT with n-1 instead of n-k (see "sandwich.pdf" and 
#   https://stats.stackexchange.com/questions/89999/how-to-replicate-statas-robust-binomial-glm-for-proportion-data-in-r)
# Display the regression for the single Lambeth effect here:
summary(pois1single)

Call:
glm(formula = deaths ~ supplier * year + offset(log(pop1851)), 
    family = poisson, data = regdata)

Deviance Residuals: 
     Min        1Q    Median        3Q       Max  
-12.1542   -3.0953    0.0306    2.7398   10.2518  

Coefficients:
                                           Estimate Std. Error  z value Pr(>|z|)    
(Intercept)                                -4.30610    0.02103 -204.755  < 2e-16 ***
supplierSouthwarkVauxhall_Lambeth          -0.03593    0.02643   -1.359  0.17400    
year1854                                    0.08354    0.02914    2.867  0.00414 ** 
supplierSouthwarkVauxhall_Lambeth:year1854 -0.51088    0.03870  -13.201  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for poisson family taken to be 1)

    Null deviance: 2032.6  on 55  degrees of freedom
Residual deviance: 1541.6  on 52  degrees of freedom
AIC: 1937.4

Number of Fisher Scoring iterations: 4

This regession is for a single Lambeth effect. Now the coefficient for the Lambeth effect (-0.511) matches exactly the value for \(\beta\) calculated in the table above.

It appears that this estimated Lambeth or treatment effect is very highly significant: z value = -13.2. But this is wrong. This is discussed in more detail in another notebook (and my working paper), but suffice to say here that the Poisson regression does not fit the data very well. In the statistics literature this is termed “overdispersion”. The diagnostic tool we can use is the “Residual Deviance”. It is approximately chi-squared distributed and the probability of observing a value as large as we see here (1542) is tiny.

The result of the overdispersion for the Poisson regression is that the true standard errors are much larger than reported in the regression. One way to handle this is to use robust standard errors. The code chunk above calculates robust standard errors and the comments in the code chunk have links to more discussion.

Negative Binomial Count Regressions

Another way to handle the overdispersion (again, discussed in more detail in another notebook and my working paper) is to allow the counts (specifically the error term \(\epsilon\)) to be Negative Binomial distributed. Once again, R has routines for this, in the MASS package.

# Negative Binomial with single "Lambeth effect" 
nb1single <- glm.nb(deaths ~ supplier * year 
    + offset(log(pop1851)), data=regdata) 
nb1singlerobustse <- coeftest(nb1single, vcov = vcovHC(nb1single))
#summary(nb1single)
#logLik(nb1single)
#print(coeftest(nb1single, vcov = vcovHC(nb1single)))
# Negative Binomial with two "Lambeth effects" 
nb1both <- glm.nb(deaths ~ lambethdegree * year 
    + offset(log(pop1851)), data=regdata) 
nb1bothrobustse <- coeftest(nb1both, vcov = vcovHC(nb1both))
#summary(nb1both)
#logLik(nb1both)
#print(coeftest(nb1both, vcov = vcovHC(nb1both)))
# Negative Binomial with two "Lambeth effects" and sub-district fixed effects
nb2both <- glm.nb(deaths ~ subDistrict + lambethdegree * year 
    + offset(log(pop1851)), data=regdata) 
nb2bothrobustse <- coeftest(nb2both, vcov = vcovHC(nb2both))
#summary(nb2both)
#logLik(nb2both)
#print(coeftest(nb2both, vcov = vcovHC(nb2both)))
# Show results for the Negative Binomial with one Lambeth effect
summary(nb1single)

Call:
glm.nb(formula = deaths ~ supplier * year + offset(log(pop1851)), 
    data = regdata, init.theta = 4.956204025, link = log)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-3.2718  -0.5282   0.0652   0.4958   1.8326  

Coefficients:
                                           Estimate Std. Error z value Pr(>|z|)    
(Intercept)                                -4.33237    0.13169 -32.898   <2e-16 ***
supplierSouthwarkVauxhall_Lambeth          -0.03182    0.17386  -0.183   0.8548    
year1854                                    0.05734    0.18616   0.308   0.7581    
supplierSouthwarkVauxhall_Lambeth:year1854 -0.50027    0.24612  -2.033   0.0421 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for Negative Binomial(4.9562) family taken to be 1)

    Null deviance: 71.825  on 55  degrees of freedom
Residual deviance: 59.764  on 52  degrees of freedom
AIC: 657.19

Number of Fisher Scoring iterations: 1

              Theta:  4.956 
          Std. Err.:  0.973 

 2 x log-likelihood:  -647.185 

The negative binomial is reasonably good at fitting the observed sub-district variability: the Residual Deviance is now 59.8 which is small enough to not reject this regression. As a result we can have some confidence that the standard errors reported are realistic. For this regression the single Lambeth effect is modestly significant, with a z value of -2.03.

Two “Lambeth effects”

Snow noted that four of the “next-16” jointly-supplied sub-districts had a higher proportion of Lambeth customers than the others: “In certain sub-districts, where I know that the supply of the Lambeth Water Company is more general than elsewhere, as Christchurch, London Road, Waterloo Road 1st, and Lambeth Church 1st, the decrease of mortality in 1854 as compared with 1849 is greatest, as might be expected.” (Snow 1855 p. 89) We can incorporate this by having two indicator variables, the variable “lambethdegree” with “less Lambeth” and “more Lambeth”.

# Show results for the Negative Binomial with two Lambeth effects
summary(nb1both)

Call:
glm.nb(formula = deaths ~ lambethdegree * year + offset(log(pop1851)), 
    data = regdata, init.theta = 5.57218113, link = log)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-3.4384  -0.5744   0.0754   0.5203   1.5608  

Coefficients:
                                   Estimate Std. Error z value Pr(>|z|)    
(Intercept)                        -4.33210    0.12443 -34.815  < 2e-16 ***
lambethdegreeless_Lambeth          -0.06426    0.17551  -0.366  0.71427    
lambethdegreemore_Lambeth           0.05911    0.24787   0.238  0.81151    
year1854                            0.05740    0.17589   0.326  0.74415    
lambethdegreeless_Lambeth:year1854 -0.33838    0.24839  -1.362  0.17310    
lambethdegreemore_Lambeth:year1854 -1.13213    0.35350  -3.203  0.00136 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for Negative Binomial(5.5722) family taken to be 1)

    Null deviance: 80.122  on 55  degrees of freedom
Residual deviance: 59.991  on 50  degrees of freedom
AIC: 654.94

Number of Fisher Scoring iterations: 1

              Theta:  5.57 
          Std. Err.:  1.11 

 2 x log-likelihood:  -640.943 

The effect for “more Lambeth” is large (-1.132, ratio effect 3.102) and highly significant (z value -3.203). When we introduce the population data published in 1856 (another notebook and my working paper) we find an even stronger Lambeth effect.

Creating Tables for Results

To summarize the results I create tables in the following code chunk to summarize the regressions. I don’t display these tables but you can if you wish.

# Regression table for linear, with robust SEs for poisson
regtablelin <- matrix(0,nrow=14,ncol=5)
colnames(regtablelin) <- c("Linear Single","Poiss1 Single robust","NB1 Single","Linear Both","NB1 Both")
rownames(regtablelin) <- c("Treat less Lamb","SE", "z value","p-value","treat (ratio)",
    "Treat more Lamb","SE","z value", "p-value","treat (ratio)","theta","region1","region2","time")
# Populate the table from the regressions
regtablelin[c(1,2,3,4),1] <- summary(lin1single)$coefficients[4,c(1,2,3,4)]
regtablelin[c(1,2,3,4),2] <- summary(pois1single)$coefficients[4,c(1,2,3,4)]
regtablelin[c(1,2,3,4),3] <- summary(nb1single)$coefficients[4,c(1,2,3,4)]
regtablelin[c(1,2,3,4),4] <- summary(lin1both)$coefficients[5,c(1,2,3,4)]
regtablelin[c(6,7,8,9),4] <- summary(lin1both)$coefficients[6,c(1,2,3,4)]
regtablelin[c(1,2,3,4),5] <- summary(nb1both)$coefficients[5,c(1,2,3,4)]
regtablelin[c(6,7,8,9),5] <- summary(nb1both)$coefficients[6,c(1,2,3,4)]
regtablelin[11,3] <- nb1single$theta
regtablelin[11,5] <- nb1both$theta
# Calculate the treatment effect as a ratio (exponentiate)
regtablelin[5,] <- exp(-regtablelin[1,])
regtablelin[10,c(4,5)] <- exp(-regtablelin[6,c(4,5)])
# Now the control (region & time) effects
regtablelin[c(12,14),1] <- lin1single$coefficients[c(2,3)]
regtablelin[c(12,14),2] <- pois1singlerobustse[c(2,3),1]
regtablelin[c(12,14),3] <- nb1single$coefficients[c(2,3)]
regtablelin[c(12,13,14),4] <- lin1both$coefficients[c(2,3,4)]
regtablelin[c(12,13,14),5] <- nb1both$coefficients[c(2,3,4)]
# Create table with regression results (diff-in-diffs estimate) using robust SEs
# for all except the NB1 (Negative Binomial without sub-district fixed effects)
regtablepoiss <- matrix(0,nrow=19,ncol=5)
colnames(regtablepoiss) <- c("Poiss Single","Poiss Single FE","NB1 Single","NB1 Both","NB2 Both")
rownames(regtablepoiss) <- c("Treat less Lamb","SE","z value","p-value",
    "robust SE","z value","treat (ratio)",
    "Treat more Lamb","SE","z value","p-value",
    "robust SE","z value","treat (ratio)",
    "theta","resid dev","region1","region2","time")
# Populate the table from the regressions
regtablepoiss[c(1,2,3,4),1] <- summary(pois1single)$coefficients[4,c(1,2,3,4)] # coeff, SE, t-ratio, p-value
regtablepoiss[c(5,6),1] <- pois1singlerobustse[4,c(2,3)]             # robust SE, t-ratio
regtablepoiss[16,1] <- pois1single$deviance
# Now the control (region & time) effects
regtablepoiss[c(17,19),1] <- summary(pois1single)$coefficients[c(2,3),1] 
regtablepoiss[c(1,2,3,4),2] <- summary(pois2single)$coefficients[30,c(1,2,3,4)]  # Lambeth effect is at end
regtablepoiss[c(5,6),2] <- pois2singlerobustse[30,c(2,3)]     
regtablepoiss[16,2] <- pois2single$deviance
regtablepoiss[19,2] <- summary(pois2single)$coefficients[29,1]    # time effect
regtablepoiss[c(1,2,3,4),3] <- summary(nb1single)$coefficients[4,c(1,2,3,4)]
regtablepoiss[c(5,6),3] <- nb1singlerobustse[4,c(2,3)]
regtablepoiss[15,3] <- nb1single$theta
regtablepoiss[16,3] <- nb1single$deviance
regtablepoiss[c(17,19),3] <- nb1single$coefficients[c(2,3)]
regtablepoiss[c(1,2,3,4),4] <- summary(nb1both)$coefficients[5,c(1,2,3,4)] # coeff, SE, t-ratio, p-value for 1st Lambeth effect
regtablepoiss[c(5,6),4] <- nb1bothrobustse[5,c(2,3)]
regtablepoiss[c(8,9,10,11),4] <- summary(nb1both)$coefficients[6,c(1,2,3,4)] # coeff, SE, t-ratio, p-value for 2nd Lambeth effect
regtablepoiss[c(12,13),4] <- nb1bothrobustse[6,c(2,3)]
regtablepoiss[15,4] <- nb1both$theta
regtablepoiss[16,4] <- nb1both$deviance
regtablepoiss[c(17,18,19),4] <- nb1both$coefficients[c(2,3,4)]
regtablepoiss[c(1,2,3,4),5] <- summary(nb2both)$coefficients[30,c(1,2,3,4)]
regtablepoiss[c(5,6),5] <- nb2bothrobustse[30,c(2,3)]
regtablepoiss[c(8,9,10,11),5] <- summary(nb2both)$coefficients[31,c(1,2,3,4)]
regtablepoiss[c(12,13),5] <- nb2bothrobustse[31,c(2,3)]
regtablepoiss[15,5] <- nb2both$theta
regtablepoiss[16,5] <- nb2both$deviance
regtablepoiss[19,5] <- summary(nb2both)$coefficients[29]
# Calculate the treatment effect as a ratio (exponentiate)
regtablepoiss[7,] <- exp(-regtablepoiss[1,])
regtablepoiss[14,c(4,5)] <- exp(-regtablepoiss[8,c(4,5)])
regtablelin <- as.data.frame(regtablelin)
regtablepoiss <- as.data.frame(regtablepoiss)
#regtablelin
#regtablepoiss


Digression on Binomial, Poisson, and Negative Binomial

For more detail on count regressions see my working paper “Causality in the Time of Cholera” working paper at https://papers.ssrn.com/abstract=3262234 and references there. But here are some notes

For binomial:

  • Rate = Count / n = Mean / n = p
  • Mean = count = n*p
  • Variance(count) = n*p*(1-p) => Std dev = sqrt(n*p*(1-p)) ~ sqrt(count) = sqrt(n*p) (since p is small for this application)
  • Std dev (rate) ~ sqrt(count)/n = sqrt(p)*sqrt(n)/n = sqrt(p) / sqrt(n)

For Poisson (which is good approx to binomial for low intensities):

  • Rate = count / n = rate
  • Mean(count) = count = n*rate
  • Variance(count) = n*rate => Std dev = sqrt(n*rate) = sqrt(count)
  • Std dev (rate) = sqrt(count)/n = sqrt(rate)*sqrt(n)/n = sqrt(rate) / sqrt(n)

Mixing with Gamma(k,k):

  • Gamma(a,b): Mean=a/b, Var=a/b^2
  • Gamma(k,k): Mean=1, Var=1/k
  • Poisson(mu) mixed with Gamma(k,k) -> Mean = mu & variance mu/k or mu + mu^2/k ?

It looks like for the R glm.nb the variance is mu + mu^2/theta ?? I think this is

  • mean = rate * pop
  • variance = mean + mean^2 / theta = rate*pop + (rate*pop)^2/theta
  • => stdev of rate = sqrt(variance(count)) / pop = sqrt(rate/pop + rate^2/theta)

Example:

  • Estimate neg binom const = -4.35 => rate=exp(-4.35)=.012907, theta = 5.51
  • For pop = 20,000:
  • Poisson stdev(rate) = sqrt(.0129/20000) = .0008 (8 per 10,000)
  • Neg binom stdev(rate) = sqrt(.0129/20000 + .0129^2/5) = .005828 (58 per 10,000)
LS0tCnRpdGxlOiAiSm9obiBTbm93IFByb2plY3QgLSBEaUQgUmVncmVzc2lvbnMiCmF1dGhvcjogIltUaG9tYXMgQ29sZW1hbl0oaHR0cDovL3d3dy5oaWxlcnVuLm9yZy9lY29uKSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQojIERpZmZlcmVuY2UgaW4gRGlmZmVyZW5jZXMgUmVncmVzc2lvbnMgLSBEYXRhIGZyb20gU25vdyAxODU1CgojIyMjIFNlZSAiQ2F1c2FsaXR5IGluIHRoZSBUaW1lIG9mIENob2xlcmEiIHdvcmtpbmcgcGFwZXIgYXQgaHR0cHM6Ly9wYXBlcnMuc3Nybi5jb20vYWJzdHJhY3Q9MzI2MjIzNCBhbmQgbXkgW0pvaG4gU25vdyBwcm9qZWN0IHdlYnNpdGVdKGh0dHA6Ly93d3cuaGlsZXJ1bi5vcmcvZWNvbi9wYXBlcnMvc25vdykKCiMjIyMgVGhpcyBub3RlYm9vayBpcyBsaWNlbnNlZCB1bmRlciB0aGUgW0JTRCAyLUNsYXVzZSBMaWNlbnNlXShodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL0JTRC0yLUNsYXVzZSkKCiMjIyBJbnRyb2R1Y3Rpb24KClRoaXMgbm90ZWJvb2sgcGVyZm9ybXMgbGluZWFyIGFuZCBjb3VudCByZWdyZXNzaW9ucyBmb3IgMTg0OSB2ZXJzdXMgMTg1NCBkYXRhIGFuZCBidWlsZHMgb24gdGhlIGRpc2N1c3Npb24gYW5kIGRhdGEgaW4gdGhlIG5vdGVib29rICJTbm93MTg1NV9TaW1wbGVEaURfUVJDVCIgLSByZWFkIHRoYXQgZmlyc3QuIAoKCkZvciBhIGJyaWVmIGludHJvZHVjdGlvbiB0byBTbm93J3Mgd29yaywgc2VlOgoKKyAqKlNub3cncyBvcmlnaW5hbCAxODU1IG1vbm9ncmFwaCoqIChpdCBpcyBtYXN0ZXJmdWwpOiBTbm93LCBKb2huLiAxODU1LiAqT24gdGhlIE1vZGUgb2YgQ29tbXVuaWNhdGlvbiBvZiBDaG9sZXJhKi4gMm5kIGVkLiBMb25kb246IEpvaG4gQ2h1cmNoaWxsLiBodHRwOi8vYXJjaGl2ZS5vcmcvZGV0YWlscy9iMjg5ODUyNjYuCisgKipUaGUgYmVzdCBwb3B1bGFyIGV4cG9zaXRpb24gSSBoYXZlIGZvdW5kKio6IEpvaG5zb24sIFN0ZXZlbi4gMjAwNy4gKlRoZSBHaG9zdCBNYXA6IFRoZSBTdG9yeSBvZiBMb25kb27igJlzIE1vc3QgVGVycmlmeWluZyBFcGlkZW1pYy0tYW5kIEhvdyBJdCBDaGFuZ2VkIFNjaWVuY2UsIENpdGllcywgYW5kIHRoZSBNb2Rlcm4gV29ybGQqLiBSZXByaW50IGVkaXRpb24uIE5ldyBZb3JrOiBSaXZlcmhlYWQgQm9va3MuCisgKipBbm90aGVyIGdvb2QgcG9wdWxhciB2ZXJzaW9uKio6IEhlbXBlbCwgU2FuZHJhLiAyMDA3LiAqVGhlIFN0cmFuZ2UgQ2FzZSBvZiB0aGUgQnJvYWQgU3RyZWV0IFB1bXA6IEpvaG4gU25vdyBhbmQgdGhlIE15c3Rlcnkgb2YgQ2hvbGVyYSouIEZpcnN0IGVkaXRpb24uIEJlcmtlbGV5OiBVbml2ZXJzaXR5IG9mIENhbGlmb3JuaWEgUHJlc3MuCisgKipUdWZ0ZSdzIGNsYXNzaWMgZGlzY3Vzc2lvbiBvZiBTbm93J3MgbWFwcGluZyoqIChhIHRvcGljIEkgZG9uJ3QgY292ZXIgaGVyZSk6IFR1ZnRlLCBFZHdhcmQgUi4gMTk5Ny4gKlZpc3VhbCBFeHBsYW5hdGlvbnM6IEltYWdlcyBhbmQgUXVhbnRpdGllcywgRXZpZGVuY2UgYW5kIE5hcnJhdGl2ZSouIDFzdCBlZGl0aW9uLiBHcmFwaGljcyBQcmVzcy4KKyAqKkJpb2dyYXBoeSoqOiBWaW50ZW4tSm9oYW5zZW4sIFBldGVyLCBIb3dhcmQgQnJvZHksIE5pZ2VsIFBhbmV0aCwgU3RlcGhlbiBSYWNobWFuLCBhbmQgTWljaGFlbCBSdXNzZWxsIFJpcC4gMjAwMy4gKkNob2xlcmEsIENobG9yb2Zvcm0gYW5kIHRoZSBTY2llbmNlIG9mIE1lZGljaW5lOiBBIExpZmUgb2YgSm9obiBTbm93Ki4gT3hmb3JkOyBOZXcgWW9yazogT3hmb3JkIFVuaXZlcnNpdHkgUHJlc3MuIExpbmtlZCBvbi1saW5lIHJlc291cmNlcyBodHRwczovL2pvaG5zbm93Lm1hdHJpeC5tc3UuZWR1L3Nub3d3b3Jrcy5waHAKCgoKClRoaXMgaXMgYW4gW1IgTWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pIE5vdGVib29rLiBXaGVuIHlvdSBleGVjdXRlIGNvZGUgd2l0aGluIHRoZSBub3RlYm9vaywgdGhlIHJlc3VsdHMgYXBwZWFyIGJlbmVhdGggdGhlIGNvZGUuIFRoZSByZXN1bHRzIGFyZSBhbHNvIHNhdmVkIGluIGEgc2VsZi1jb250YWluZWQgaHRtbCBkb2N1bWVudCB3aXRoIHRoZSBzdWZmaXggKi5uYi5odG1sKi4gSWYgeW91IHdhbnQgcHVyZSByIGNvZGUgKGZvciBleGFtcGxlIHRvIHJ1biBvdXRzaWRlIFJTdHVkaW8pIHlvdSBjYW4gZWFzaWx5IGV4dHJhY3QgY29kZSB3aXRoIHRoZSBjb21tYW5kICprbml0KCdub3RlYm9vay5SbWQnLHRhbmdsZT1UUlVFKSogd2hpY2ggd2lsbCBzYXZlIGEgZmlsZSAnbm90ZWJvb2suUicgdW5kZXIgeW91ciB3b3JraW5nIGRpcmVjdG9yeS4KClRyeSBleGVjdXRpbmcgdGhlIGNodW5rIGJlbG93IGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkNtZCtTaGlmdCtFbnRlciouIAoKKipOQjogV2UgbmVlZCB0aGUgZGF0YSBhbmQgc29tZSBvZiB0aGUgY2FsY3VsYXRpb25zIGZyb20gdGhlIG5vdGVib29rICdTbm93MTg1NV9TaW1wbGVEaURfUVJDVC5SbWQnIHNvIHdlIGV4ZWN1dGUgdGhpcyBsaXR0bGUgaGFjayB0byBleHRyYWN0IHRoZSBSIGNvZGUgZnJvbSB0aGF0IHNoZWV0LCB3cml0ZSBhIG5ldyAuUiBmaWxlLCBhbmQgdGhlbiBzb3VyY2UgdGhhdCBoZXJlKioKYGBgYGBge3IgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CiMgQ29weXJpZ2h0IChjKSAyMDE5LCBUaG9tYXMgQ29sZW1hbgojCiMgIC0tLS0tLS0gIExpY2Vuc2VkIHVuZGVyIEJTRCAyLUNsYXVzZSAiU2ltcGxpZmllZCIgTGljZW5zZSAgLS0tLS0tLQojCiMgUmVzdWx0cyBhbmQgZGlzY3Vzc2lvbiBpbiAiQ2F1c2FsaXR5IGluIHRoZSBUaW1lIG9mIENob2xlcmE6IEpvaG4gU25vdyBhcyBhIFByb3RvdHlwZSAKIyBmb3IgQ2F1c2FsIEluZmVyZW5jZSAoV29ya2luZyBQYXBlcikiIGF2YWlsYWJsZSBhdCBTU1JOOiBodHRwczovL3BhcGVycy5zc3JuLmNvbS9hYnN0cmFjdD0zMjYyMjM0CgpsaWJyYXJ5KGtuaXRyKQpvcHRpb25zKHNjaXBlbj01KQprbml0KCdTbm93MTg1NV9TaW1wbGVEaURfUVJDVC5SbWQnLCB0YW5nbGU9VFJVRSkKc291cmNlKCdTbm93MTg1NV9TaW1wbGVEaURfUVJDVC5SJykgCiMgVGhlIGZvbGxvd2luZyBsaWJyYXJpZXMgYXJlIHVzZWQgZm9yIHRoZSBOZWdhdGl2ZSBCaW5vbWlhbCByZWdyZXNzaW9uIGFuZCB0aGUgcm9idXN0IHN0YW5kYXJkIGVycm9yIGFuYWx5c2lzCiNpbnN0YWxsLnBhY2thZ2VzKCJzYW5kd2ljaCIpCiNpbnN0YWxsLnBhY2thZ2VzKCJsbXRlc3QiKQpsaWJyYXJ5KCJNQVNTIikKbGlicmFyeSgic2FuZHdpY2giKSAKbGlicmFyeSgibG10ZXN0IikgCgpgYGAKCiMjI0RpZmZlcmVuY2UtaW4tRGlmZmVyZW5jZXMgRnJhbWV3b3JrCgpUaGUgYmFzaWMgZGlmZmVyZW5jZS1pbi1kaWZmZXJlbmNlcyBzdHJ1Y3R1cmUgY2FuIGJlIGRpc3BsYXllZCBpbiBhIHRhYmxlIGxpa2U6Cgp8IFN1Yi1kaXN0cmljdHMgfCAxODQ5IE1vcnRhbGl0eSAocmF0ZSkgfCAgMTg1NCBNb3J0YWxpdHkgKHJhdGUpIHwgRGlmZiAxODU0IGxlc3MgMTg0OSB8CnwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHwgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8ICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0gfAp8Rmlyc3QgMTIgU291dGh3YXJrLXN1cHBsaWVkIHwgJFxtdSQgfCAkXG11ICsgXGRlbHRhIDU0JCB8ICRcZGVsdGEgNTQkICB8CnxOZXh0IDE2IGpvaW50bHktc3VwcGxpZWQgfCAkXG11ICsgXGdhbW1hJCB8ICRcbXUgKyBcZGVsdGEgNTQgKyBcZ2FtbWEgKyBcYmV0YSQgfCAkXGRlbHRhIDU0ICsgXGJldGEkICB8CnxEaWZmIG5leHQtMTYgbGVzcyBmaXJzdC0xMiB8ICRcZ2FtbWEkIHwgJFxnYW1tYSArIFxiZXRhJCB8ICRcYmV0YSQgIHwKCgpgYGB7ciByZXN1bHRzPSdhc2lzJ30KIyBUaGUgZGlmZi1pbi1kaWZmcyB0YWJsZSAobGV2ZWxzKSBmcm9tIHRoZSBub3RlYm9vayAnU25vdzE4NTVfU2ltcGxlRGlEX1FSQ1QuUm1kJwprYWJsZShkaWZmX2luX2RpZmZzX0xldmVsLGRpZ2l0cz0yLGNhcHRpb249IkRpZmYtaW4tRGlmZnMsIExldmVscyAocmF0ZSBwZXIgMTAsMDAwKSIsZm9ybWF0PSdwYW5kb2MnKQprYWJsZShkaWZmX2luX2RpZmZzX0xvZyxkaWdpdHM9MyxjYXB0aW9uPSJEaWZmLWluLURpZmZzLCBMZXZlbHMgKHJhdGUgcGVyIDEwLDAwMCkiLGZvcm1hdD0ncGFuZG9jJykKYGBgCgpUaGlzIHRhYmxlIGxvb2tzIHZlcnkgc2ltcGxlLCBhbmQgd2l0aCBhIHBvcHVsYXRpb24gb2Ygb3ZlciA0NTAsMDAwIChgciBwb3BTb3V0aHdhcmtWYXV4aGFsbGAgaW4gdGhlICJmaXJzdC0xMiIgYW5kIGByIHBvcFNvdXRod2Fya1ZhdXhoYWxsX0xhbWJldGhgIGluIHRoZSAibmV4dC0xNiIpIHdlIHdvdWxkIHRoaW5rIHRoZSBlc3RpbWF0ZSBvZiBgciByb3VuZChkaWZmX2luX2RpZmZzX0xvZ1szLDNdLDMpYCB3b3VsZCBiZSBwcmVjaXNlbHkgZXN0aW1hdGVkLiBJbiBmYWN0LCB3ZSBjYW4gcnVuIGEgUG9pc3NvbiByZWdyc3Npb24sIGEgY291bnQgcmVncmVzc2lvbiB3aGljaCAqc2VlbXMqIHRoZSByaWdodCB3YXkgdG8gZml0IHRoaXMgdGFibGUgYW5kIHRlc3QgZm9yIHRoZSBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2Ugb2YgdGhlIGRpZmYtaW4tZGlmZnMgY29lZmZpY2llbnQuIAoKYGBge3J9CgpyZWdkYXRhc2ltcGxlIDwtIGRhdGEuZnJhbWUoImRlYXRocyIgPSBjKGNvbXBhcmVjb3VudHMxODQ5XzE4NTRbMToyLF0pLCAicG9wMTg1MSIgPSBjKGNvbXBhcmVwb3AxODQ5XzE4NTRbMToyLF0pKQpyZWdkYXRhc2ltcGxlJHN1cHBsaWVyIDwtIGMoIlNvdXRod2Fya1ZhdXhoYWxsIiwiU291dGh3YXJrVmF1eGhhbGxfTGFtYmV0aCIsIlNvdXRod2Fya1ZhdXhoYWxsIiwiU291dGh3YXJrVmF1eGhhbGxfTGFtYmV0aCIpCnJlZ2RhdGFzaW1wbGUkeWVhciA8LSBjKCIxODQ5IiwiMTg0OSIsIjE4NTQiLCIxODU0IikKCnBvaXMxc2ltcGxlIDwtIGdsbShkZWF0aHMgfiBzdXBwbGllciAqIHllYXIgKyBvZmZzZXQobG9nKHBvcDE4NTEpKSwgZmFtaWx5PXBvaXNzb24sIGRhdGE9cmVnZGF0YXNpbXBsZSkgCgpzdW1tYXJ5KHBvaXMxc2ltcGxlKQoKYGBgCgpUaGUgZGlmZi1pbi1kaWZmcyBjb2ZmZmljaWVudCBpcyAqYHIgdmFyaWFibGUubmFtZXMocG9pczFzaW1wbGUpWzRdYCogd2l0aCB0aGUgc2FtZSB2YWx1ZSAoaW4gbG9nIHRlcm1zKSBhcyB0aGUgdGFibGUgYWJvdmU6IGByIHJvdW5kKHBvaXMxc2ltcGxlJGNvZWZmaWNpZW50c1s0XSwzKWAgKGluIHJhdGlvIHRlcm1zIC0gdGhlIGluY3JlYXNlIGluIG1vcnRhbGl0eSBmb3IgU291dGh3YXJrICYgVmF1eGhhbGwgY3VzdG9tZXJzIHZlcnN1cyBMYW1iZXRoIGN1c3RvbWVycyAtIHRoaXMgaXMgIGByIHJvdW5kKGV4cCgtcG9pczFzaW1wbGUkY29lZmZpY2llbnRzWzRdKSwzKWApLiBUaGlzIGFwcGVhcnMgdG8gYmUgdmVyeSBzaWduaWZpY2FudCwgd2l0aCB6IHZhbHVlIGByIHJvdW5kKHN1bW1hcnkocG9pczFzaW1wbGUpJGNvZWZmaWNpZW50c1s0LDNdLDIpIGAuIEJ1dCB3ZSB3b3VsZCBiZSB3cm9uZyB0byByZWx5IG9uIHRoaXMgcmVncmVzc2lvbi4gCgoKV2UgY2FuIHNlZSB0aGUgcmVhc29uIHdoZW4gd2UgZXhhbWluZSB0aGUgb3JpZ2luYWwgZGF0YSAoU25vdydzIFRhYmxlIFhJSSk6IHRoZXJlIGlzIGNvbnNpZGVyYWJsZSB2YXJpYXRpb24gYWNyb3NzIHN1Yi1kaXN0cmljdHMuIExvb2tpbmcgb25seSBhdCB0aGUgZmlyc3QgdHdvIHN1Yi1kaXN0cmljdHMgaW4gMTg0OSwgZm9yIGV4YW1wbGUsIGByIHRhYmxleGlpWzEsMV1gIGhhcyBtb3J0YWxpdHkgb2YgYHIgcm91bmQodGFibGV4aWlbMSw2XSwxKWAgd2hpbGUgYHIgdGFibGV4aWlbMiwxXWAgaGFzIG1vcnRhbGl0eSBvZiBgciByb3VuZCh0YWJsZXhpaVsyLDZdLDEpYC4gV2UgY2Fubm90IHNpbXBseSBoaWdobGlnaHQgYW5kIGV4cGxvaXQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgYWdncmVnYXRlICJmaXJzdC0xMiIgYW5kICJuZXh0LTE2IiBzdWItZGlzdHJpY3RzICh0aGUgZGlmZi1pbi1kaWZmcyBjb2VmZmljaWVudCBgciByb3VuZChwb2lzMXNpbXBsZSRjb2VmZmljaWVudHNbNF0sNClgKSB3aGlsZSBpZ25vcmluZyB0aGUgdmFyaWFiaWxpdHkgYWNyb3NzIGFuZCB3aXRoaW4gc3ViLWRpc3RyaWN0cy4gV2UgbmVlZCBzb21lIHN0YXRpc3RpY2FsIGZyYW1ld29yayB0byBpbmNvcnBvcmF0ZSBhbmQgYW5hbHl6ZSB0aGUgdmFyaWFiaWxpdHkgYm90aCAqd2l0aGluKiBhbmQgKmFjcm9zcyogc3ViLWRpc3RyaWN0cy4gCgpgYGB7cn0KdGFibGV4aWlbLGMoMSwyLDMsNCw2LDcpXQpgYGAKCgpGb3IgYSByZWFzb25hYmxlIHN0YXRpc3RpY2FsIGZyYW1ld29yayB3ZSBjYW4gY29uc2lkZXIgdGhlIGZvbGxvd2luZyBlcXVhdGlvbiwgd2hpY2ggcHV0cyB0aGUgZGlmZmVyZW5jZS1pbi1kaWZmZXJlbmNlcyB0YWJsZSBhYm92ZSBpbnRvIGVxdWF0aW9uIGZvcm0gYnV0IGFsc28gYWxsb3dzIG11bHRpcGxlIHN1Yi1kaXN0cmljdHMgLSBlYWNoIHN1Yi1kaXN0cmljdCBoYXZpbmcgaXRzIG93biByYXRlLCBldGMuOgoKJGxuKFJhdGUpID0gXG11ICsgXGRlbHRhIDU0KkkoNTQpICsgXGdhbW1hKkkoam9pbnQpICsgXGJldGEqSSg1NCkqSShqb2ludCkgKyBcZXBzaWxvbiQKCiogYW4gb3ZlcmFsbCBjb25zdGFudCAoJFxtdSQpCiogYSBkaWZmZXJlbmNlIGZvciAxODU0ICgkXGRlbHRhNTQkKSAKKiBhIGRpZmZlcmVuY2UgZm9yIGpvaW50ICJuZXh0IDE2IiByZWdpb24gKCRcZ2FtbWEkKQoqIGFuIGludGVyYWN0aW9uIGZvciAxODU0IGFuZCBqb2ludCAoJFxiZXRhJCkKCkZvciB2YXJpb3VzIHJlYXNvbnMgd2Ugd2FudCB0byBydW4gdGhpcyBhcyBsaW5lYXItaW4tbG9ncyByYXRoZXIgdGhhbiBsaW5lYXItaW4tcmF0ZXMuIAoKIyMjRm9ybWF0dGluZyB0aGUgcmVncmVzc2lvbiBkYXRhCgpUbyBydW4gdGhpcyBhcyBhIHJlZ3Jlc3Npb24gd2UgbmVlZCB0byB0YWtlIHRoZSBkZWF0aCBjb3VudHMgZnJvbSBUYWJsZSBYSUkgKGRlYXRocyBieSBzdWItZGlzdHJpY3QpLCBjb21iaW5lIHdpdGggcG9wdWxhdGlvbiBmcm9tIFRhYmxlIFZJSUkgZm9yIGNhbGN1bGF0aW5nIHJhdGVzLCBpbmNvcnBvcmF0ZSBwcm9wZXIgaW5kaWNhdG9yIHZhcmlhYmxlcywgYW5kIHRoZW4gc3RhY2sgdGhlIGRhdGEuIE91ciBvcmlnaW5hbCBkYXRhICh0aGUgLmNzdiBmaWxlcyByZWFkIGluIGFib3ZlKSBoYXZlIGEgdmFyaWFibGUgInN1cHBsaWVyIiB0aGF0IGFjdHMgYXMgaW5kaWNhdG9yIGZvciAiZmlyc3QtMTIiIChTb3V0aHdhcmstb25seSBzdXBwbHkpIHZlcnN1cyAibmV4dC0xNiIgKGpvaW50bHktc3VwcGxpZWQpIHN1Yi1kaXN0cmljdHMgYW5kIGFub3RoZXIgKCJsYW1iZXRoZGVncmVlIikgdGhhdCBzZXJ2ZXMgYXMgYW4gaW5kaWNhdG9yIGZvciAiU291dGh3YXJrLW9ubHkiLCAibGVzcy1MYW1iZXRoIiBhbmQgIm1vcmUtTGFtYmV0aCIgc3VwcGx5LiBXZSBuZWVkIHRvIGNvbnN0cnVjdCBhIHllYXIgZmFjdG9yICgxODQ5IHZlcnN1cyAxODU0KS4gVGhlIHN0YWNraW5nIGFuIGluZGljYXRvciBjb25zdHJ1Y3Rpb24gaXMgZXhlY3V0ZWQgd2l0aCB0aGUgZm9sbG93aW5nIGNvZGUgY2h1bmsuIAoKYGBge3J9CngxIDwtIHN1YnNldCh0YWJsZXZpaWksc3VwcGxpZXIgPT0gIlNvdXRod2Fya1ZhdXhoYWxsIiB8IHN1cHBsaWVyID09ICJTb3V0aHdhcmtWYXV4aGFsbF9MYW1iZXRoIikKeDE4NDkgPC0geDFbYygic3ViRGlzdHJpY3QiLCJwb3AxODUxIiwic3VwcGxpZXIiLCJsYW1iZXRoZGVncmVlIildCngxIDwtIHN1YnNldCh0YWJsZXhpaSxzdXBwbGllciA9PSAiU291dGh3YXJrVmF1eGhhbGwiIHwgc3VwcGxpZXIgPT0gIlNvdXRod2Fya1ZhdXhoYWxsX0xhbWJldGgiKQp4MTg0OSRkZWF0aHMgPC0geDEkZGVhdGhzMTg0OQp4MTg0OSRyYXRlIDwtIDEwMDAwICogeDEkZGVhdGhzMTg0OSAvIHgxODQ5JHBvcDE4NTEKeDE4NDkkc2VxIDwtIGMoc2VxKDEsbGVuZ3RoKHgxODQ5JGRlYXRocykpKQojeDE4NDkkZHVtMTg1NCA8LSAwCnh5ZWFyIDwtIGZhY3RvcihjKHJlcCgxODQ5LDI4KSxyZXAoMTg1NCwyOCkpKQp4MTg0OSR5ZWFyIDwtIHh5ZWFyWzE6MjhdCngxODU0IDwtIHgxODQ5CiN4MTg0OSRsYW1iZXRoZGVncmVlIDwtICJkaXJ0eSIKeDE4NTQkZGVhdGhzIDwtIHgxJGRlYXRoczE4NTQKeDE4NTQkcmF0ZSA8LSAxMDAwMCAqIHgxJGRlYXRoczE4NTQgLyB4MTg0OSRwb3AxODUxCngxODU0JHNlcSA8LSBjKHNlcSgxLGxlbmd0aCh4MTg0OSRkZWF0aHMpKSkKI3gxODU0JGR1bTE4NTQgPC0gMQp4MTg1NCR5ZWFyIDwtIHh5ZWFyWzI5OjU2XQoKcmVnZGF0YSA8LSByYmluZCh4MTg0OSx4MTg1NCkKcmVnZGF0YQpgYGAKCiMjIyBMaW5lYXIgUmVncmVzc2lvbnMKCldlIGNhbiBzdGFydCBvdXQgYnkgcnVubmluZyBhIGxpbmVhciByZWdyZXNzaW9uIChsaW5lYXIgaW4gbG9ncykuIFRoZSBmb2xsb3dpbmcgY29kZSBjaHVuayBleGVjdXRlcyB0aHJlZSBsaW5lYXIgcmVncmVzc2lvbnMgYnV0IG9ubHkgZGlzcGxheXMgdGhlIGZpcnN0OiB3aXRoIExhbWJldGgtc3VwcGxpZXIgKCJzdXBwbGllciIgb3IgImZpcnN0LTEyIiB2cyAibmV4dC0xNiIpIGFuZCB5ZWFyIGluZGljYXRvcnMuCgoKYGBge3J9CiMgTGluZWFyLWluLWxvZ3Mgd2l0aCBMYW1iZXRoICgic3VwcGxpZXIiIG9yICJmaXJzdC0xMiIgdnMgIm5leHQtMTYiKSBhbmQgeWVhciBpbmRpY2F0b3JzCmxpbjFzaW5nbGUgPC0gbG0obG9nKHJhdGUvMTAwMDApIH4gc3VwcGxpZXIgKiB5ZWFyLCBkYXRhPXJlZ2RhdGEpIApsaW4xc2luZ2xlcm9idXN0c2UgPC0gY29lZnRlc3QobGluMXNpbmdsZSwgdmNvdiA9IHZjb3ZIQyhsaW4xc2luZ2xlKSkKc3VtbWFyeShsaW4xc2luZ2xlKQojIExpbmVhci1pbi1sb2dzIHdpdGggdHdvIExhbWJldGggaW5kaWNhdG9ycyAoImZpcnN0LTEyIiB2cyAibmV4dC0xNiBzcGxpdCBpbnRvIGxlc3NfbGFtYmV0aCIgYW5kICJtb3JlX2xhbWJldGgiKSBhbmQgeWVhciBpbmRpY2F0b3JzCmxpbjFib3RoIDwtIGxtKGxvZyhyYXRlLzEwMDAwKSB+IGxhbWJldGhkZWdyZWUgKiB5ZWFyLCBkYXRhPXJlZ2RhdGEpIApsaW4xYm90aHJvYnVzdHNlIDwtIGNvZWZ0ZXN0KGxpbjFib3RoLCB2Y292ID0gdmNvdkhDKGxpbjFib3RoKSkKIyBMaW5lYXItaW4tbG9ncyB3aXRoIHN1Yi1kaXN0cmljdCBmaXhlZCBlZmZlY3RzIGFuZCBMYW1iZXRoICgic3VwcGxpZXIiIG9yICJmaXJzdC0xMiIgdnMgIm5leHQtMTYiKSBhbmQgeWVhciBpbmRpY2F0b3JzCmxpbjJib3RoIDwtIGxtKGxvZyhyYXRlLzEwMDAwKSB+IHN1YkRpc3RyaWN0ICsgbGFtYmV0aGRlZ3JlZSAqIHllYXIsIGRhdGE9cmVnZGF0YSkgCmxpbjJib3Rocm9idXN0c2UgPC0gY29lZnRlc3QobGluMmJvdGgsIHZjb3YgPSB2Y292SEMobGluMmJvdGgpKQpgYGAKClRoZSBjb2VmZmljaWVudCB3ZSBhcmUgaW50ZXJlc3RlZCBpbiBpcyB0aGUgbGFzdDogYHIgbGFiZWxzKGxpbjFzaW5nbGUkY29lZmZpY2llbnRzWzRdKWA6IHRoZSBjb2VmZmljaWVudCAkXGJldGEkIGluIHRoZSBlcXVhdGlvbiBhYm92ZS4gVGhpcyBjYWxjdWxhdGVzIHRoZSBhdmVyYWdlIExhbWJldGggZWZmZWN0LCBhdmVyYWdlZCBhY3Jvc3MgdGhlIHN1Yi1kaXN0cmljdHMuIFRoZSBzdGFuZGFyZCBlcnJvcnMgbWVhc3VyZSB0aGUgcHJlY2lzaW9uIG9mIG91ciBlc3RpbWF0ZWQgYXZlcmFnZSBiYXNlZCBvbiB0aGUgdmFyaWF0aW9uIGFjcm9zcyBzdWItZGlzdHJpY3RzLiAKCkJ1dCBoZXJlIGlzIGFuIGltcG9ydGFudCBwdXp6bGU6IHdoeSBpcyB0aGUgY29lZmZpY2llbnQgYHIgcm91bmQobGluMXNpbmdsZSRjb2VmZmljaWVudHNbNF0sMylgIG5vdCB0aGUgc2FtZSBhcyB0aGUgY2FsY3VsYXRlZCBMYW1iZXRoIGVmZmVjdCBpbiB0aGUgdGFibGUgYWJvdmUgKGByIHJvdW5kKGRpZmZfaW5fZGlmZnNfTG9nWzMsM10sMylgKT8gVGhlIHJlYXNvbiBpcyB0aGF0IHRoZSBsaW5lYXIgcmVncmVzc2lvcyBhcmUgbm90IGNvcnJlY3QsIGFuZCB0aGlzIGxlYWRzIHRvIG91ciBuZXh0IHRvcGljLgoKIyMjIFBvaXNzb24gQ291bnQgUmVncmVzc2lvbnMKClRoZSBsaW5lYXItaW4tbG9ncyByZWdyZXNzaW9uIGFib3ZlIGxvb2tzIGNvcnJlY3QgYnV0IGl0IGlzIG5vdDogd2UgaGF2ZSBpbXBsaWNpdGVseSBhc3N1bWVkIHRoYXQgdGhlIGVycm9yIHRlcm0gJFxlcHNpbG9uJCBpcyBub3JtYWwgYW5kIHRoaXMgY2Fubm90IGJlIGNvcnJlY3QuIFRvIHNlZSB3aHksIHJlLXdyaXRlIHRoZSByZWdyZXNzaW9uIGVxdWF0aW9uICh1c2luZyB0aGUgZmFjdCB0aGF0ICpSYXRlKiA9ICpDb3VudC9Qb3B1bGF0aW9uKiBzbyB0aGF0ICpsbihSYXRlKSogPSAqbG4oQ291bnQpLWxuKFBvcHVsYXRpb24pKikgYXMgCgokbG4oQ291bnQpID0gXG11ICsgXGRlbHRhIDU0KkkoNTQpICsgXGdhbW1hKkkoam9pbnQpICsgXGJldGEqSSg1NCkqSShqb2ludCkgKyBcZXBzaWxvbiArIGxuKFBvcHVsYXRpb24pJAoKKkNvdW50KiBpcyB0aGUgbnVtYmVyIG9mIGRlYXRocyBhbmQgY2FuIG9ubHkgdGFrZSBub24tbmVnYXRpdmUgaW50ZWdlciB2YWx1ZXMsIHNvIHRoZSBlcnJvciAkXGVwc2lsb24kIGNhbm5vdCBiZSBOb3JtYWwuIEl0IGNhbiwgaG93ZXZlciwgYmUgUG9pc3Nvbi4gKEZvciBhIGRpc2N1c3Npb24gb2YgdGhlIFBvaXNzb24gZGlzdHJpYnV0aW9uIGFuZCBQb2lzc29uIGFuZCBOZWdhdGl2ZSBCaW5vbWlhbCByZWdyZXNzaW9uIHNlZSBteSB3b3JraW5nIHBhcGVyIGF0IGh0dHBzOi8vcGFwZXJzLnNzcm4uY29tL2Fic3RyYWN0PTMyNjIyMzQgYW5kIHRoZSByZWZlcmVuY2VzIHRoZXJlaW4uKSBUaGVyZSBhcmUgdmFyaW91cyByb3V0aW5lcyBpbiBSIGFuZCBvdGhlciBzdGF0c3RpY2FsIHBhY2thZ2VzIGZvciBydW5uaW5nIHJlZ3Jlc3Npb24gYXNzdW1pbmcgdGhhdCB0aGUgZXJyb3IgJFxlcHNpbG9uJCBpcyBQb2lzc29uIChvciBvdGhlciBjb3VudCBkaXN0cmlidXRpb25zIHN1Y2ggYXMgTmVnYXRpdmUgQmlub21pYWwpLiAKClRoZSBmb2xsb3dpbmcgY29kZSBjaHVuayBydW5zIFBvaXNzb24gcmVncmVzc2lvbnMuIFRoZSB2YXJpb3VzIGNvbWJpbmF0aW9ucyBvZiBzaW5nbGUgdmVyc3VzIHR3byBMYW1iZXRoICh0cmVhdG1lbnQpIGVmZmVjdHMgYW5kIGZpeGVkIGVmZmVjdHMgYXJlIGRpc2N1c3NlZCBpbiBteSB3b3JraW5nIHBhcGVyIGF0IGh0dHBzOi8vcGFwZXJzLnNzcm4uY29tL2Fic3RyYWN0PTMyNjIyMzQgCgpgYGB7cn0KIyBQb2lzc29uIHdpdGggc2luZ2xlICJMYW1iZXRoIGVmZmVjdCIgYW5kIHNhbWUgcmF0ZSBmb3IgYWxsIHN1Yi1kaXN0cmljdHMgKG5vIHN1Yi1kaXN0cmljdCBmaXhlZCBlZmZlY3RzKQpwb2lzMXNpbmdsZSA8LSBnbG0oZGVhdGhzIH4gc3VwcGxpZXIgKiB5ZWFyIAoJKyBvZmZzZXQobG9nKHBvcDE4NTEpKSwgZmFtaWx5PXBvaXNzb24sIGRhdGE9cmVnZGF0YSkgCnBvaXMxc2luZ2xlcm9idXN0c2UgPC0gY29lZnRlc3QocG9pczFzaW5nbGUsIHZjb3YgPSB2Y292SEMocG9pczFzaW5nbGUpKQojc3VtbWFyeShwb2lzMXNpbmdsZSkKI2xvZ0xpayhwb2lzMXNpbmdsZSkKIyBQb2lzc29uIHdpdGggdHdvICJMYW1iZXRoIGVmZmVjdHMiIGFuZCBzYW1lIHJhdGUgZm9yIGFsbCBzdWItZGlzdHJpY3RzIChubyBzdWItZGlzdHJpY3QgZml4ZWQgZWZmZWN0cykKcG9pczFib3RoIDwtIGdsbShkZWF0aHMgfiBsYW1iZXRoZGVncmVlICogeWVhciAKCSsgb2Zmc2V0KGxvZyhwb3AxODUxKSksIGZhbWlseT1wb2lzc29uLCBkYXRhPXJlZ2RhdGEpIApwb2lzMWJvdGhyb2J1c3RzZSA8LSBjb2VmdGVzdChwb2lzMWJvdGgsIHZjb3YgPSB2Y292SEMocG9pczFib3RoKSkKI3N1bW1hcnkocG9pczFib3RoKQojbG9nTGlrKHBvaXMxYm90aCkKIyBQb2lzc29uIHdpdGggc2luZ2xlICJMYW1iZXRoIGVmZmVjdCIgYW5kIGRpZmZlcmVudCByYXRlcyBieSBzdWItZGlzdHJpY3QgKGZpeGVkIGVmZmVjdHMpCnBvaXMyc2luZ2xlIDwtIGdsbShkZWF0aHMgfiBzdWJEaXN0cmljdCArIHN1cHBsaWVyICogeWVhciAKCSsgb2Zmc2V0KGxvZyhwb3AxODUxKSksIGZhbWlseT1wb2lzc29uLCBkYXRhPXJlZ2RhdGEpIApwb2lzMnNpbmdsZXJvYnVzdHNlIDwtIGNvZWZ0ZXN0KHBvaXMyc2luZ2xlLCB2Y292ID0gdmNvdkhDKHBvaXMyc2luZ2xlKSkKI3N1bW1hcnkocG9pczJzaW5nbGUpCiNsb2dMaWsocG9pczJzaW5nbGUpCiMgUG9pc3NvbiB3aXRoIHR3byAiTGFtYmV0aCBlZmZlY3RzIiBhbmQgZGlmZmVyZW50IHJhdGVzIGJ5IHN1Yi1kaXN0cmljdCAoZml4ZWQgZWZmZWN0cykKcG9pczJib3RoIDwtIGdsbShkZWF0aHMgfiBzdWJEaXN0cmljdCArIHN1cHBsaWVyICogeWVhciAKCSsgb2Zmc2V0KGxvZyhwb3AxODUxKSksIGZhbWlseT1wb2lzc29uLCBkYXRhPXJlZ2RhdGEpIApwb2lzMmJvdGhyb2J1c3RzZSA8LSBjb2VmdGVzdChwb2lzMmJvdGgsIHZjb3YgPSB2Y292SEMocG9pczJib3RoKSkKI3N1bW1hcnkocG9pczJib3RoKQojbG9nTGlrKHBvaXMyYm90aCkKCiMgTkI6IFRoZSByb2J1c3Qgc3RhbmRhcmQgZXJyb3JzIGFwcHJvYWNoIEkgZm91bmQgYXQ6CiMgIGh0dHBzOi8vc3RhdC5ldGh6LmNoL3BpcGVybWFpbC9yLWhlbHAvMjAwOC1NYXkvMTYxNTkxLmh0bWwKI1RoZW4gY2xpY2sgb24gIk5leHQgbWVzc2FnZToiIGZvciB0aGUgc2Vjb25kLiBVbmZvcnR1bmF0ZWx5LCAKI2F0IHRoYXQgcG9pbnQgdGhlIHRocmVhZCBicm9rZSAKIyBTbyB0byBjb250aW51ZSwgbmV4dCB0YWtlOiAKIyAgaHR0cHM6Ly9zdGF0LmV0aHouY2gvcGlwZXJtYWlsL3ItaGVscC8yMDA4LU1heS8xNjE2NDAuaHRtbAojYW5kIHRoZXJlYWZ0ZXIgY29udGludWUgdG8gY2xpY2sgb24gIk5leHQgbWVzc2FnZToiIHVudGlsIHRoZSAKI3RocmVhZCBydW5zIG91dC4gCiMgQWxzbyBjZiBodHRwczovL3N0YXRzLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy8xMTcwNTIvcmVwbGljYXRpbmctc3RhdGFzLXJvYnVzdC1vcHRpb24taW4tcgojIE5COiBTVEFUQSBzZWVtcyB0byB1c2UgSEMxIGZvciByb2J1c3QgQlVUIHdpdGggbi0xIGluc3RlYWQgb2Ygbi1rIChzZWUgInNhbmR3aWNoLnBkZiIgYW5kIAojCWh0dHBzOi8vc3RhdHMuc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzg5OTk5L2hvdy10by1yZXBsaWNhdGUtc3RhdGFzLXJvYnVzdC1iaW5vbWlhbC1nbG0tZm9yLXByb3BvcnRpb24tZGF0YS1pbi1yKQoKCiMgRGlzcGxheSB0aGUgcmVncmVzc2lvbiBmb3IgdGhlIHNpbmdsZSBMYW1iZXRoIGVmZmVjdCBoZXJlOgpzdW1tYXJ5KHBvaXMxc2luZ2xlKQoKYGBgCgpUaGlzIHJlZ2Vzc2lvbiBpcyBmb3IgYSBzaW5nbGUgTGFtYmV0aCBlZmZlY3QuIE5vdyB0aGUgY29lZmZpY2llbnQgZm9yIHRoZSBMYW1iZXRoIGVmZmVjdCAoYHIgcm91bmQocG9pczFzaW5nbGUkY29lZmZpY2llbnRzWzRdLDMpYCkgbWF0Y2hlcyBleGFjdGx5IHRoZSB2YWx1ZSBmb3IgJFxiZXRhJCBjYWxjdWxhdGVkIGluIHRoZSB0YWJsZSBhYm92ZS4gCgpJdCBhcHBlYXJzIHRoYXQgdGhpcyBlc3RpbWF0ZWQgTGFtYmV0aCBvciB0cmVhdG1lbnQgZWZmZWN0IGlzIHZlcnkgaGlnaGx5IHNpZ25pZmljYW50OiB6IHZhbHVlID0gYHIgcm91bmQoc3VtbWFyeShwb2lzMXNpbmdsZSkkY29lZmZpY2llbnRzWzQsM10sMSlgLiBCdXQgdGhpcyBpcyB3cm9uZy4gVGhpcyBpcyBkaXNjdXNzZWQgaW4gbW9yZSBkZXRhaWwgaW4gYW5vdGhlciBub3RlYm9vayAoYW5kIG15IHdvcmtpbmcgcGFwZXIpLCBidXQgc3VmZmljZSB0byBzYXkgaGVyZSB0aGF0IHRoZSBQb2lzc29uIHJlZ3Jlc3Npb24gZG9lcyBub3QgZml0IHRoZSBkYXRhIHZlcnkgd2VsbC4gSW4gdGhlIHN0YXRpc3RpY3MgbGl0ZXJhdHVyZSB0aGlzIGlzIHRlcm1lZCAib3ZlcmRpc3BlcnNpb24iLiBUaGUgZGlhZ25vc3RpYyB0b29sIHdlIGNhbiB1c2UgaXMgdGhlICJSZXNpZHVhbCBEZXZpYW5jZSIuIEl0IGlzIGFwcHJveGltYXRlbHkgY2hpLXNxdWFyZWQgZGlzdHJpYnV0ZWQgYW5kIHRoZSBwcm9iYWJpbGl0eSBvZiBvYnNlcnZpbmcgYSB2YWx1ZSBhcyBsYXJnZSBhcyB3ZSBzZWUgaGVyZSAoYHIgcm91bmQocG9pczFzaW5nbGUkZGV2aWFuY2UsMClgKSBpcyB0aW55LiAKClRoZSByZXN1bHQgb2YgdGhlIG92ZXJkaXNwZXJzaW9uIGZvciB0aGUgUG9pc3NvbiByZWdyZXNzaW9uIGlzIHRoYXQgdGhlIHRydWUgc3RhbmRhcmQgZXJyb3JzIGFyZSBtdWNoIGxhcmdlciB0aGFuIHJlcG9ydGVkIGluIHRoZSByZWdyZXNzaW9uLiBPbmUgd2F5IHRvIGhhbmRsZSB0aGlzIGlzIHRvIHVzZSByb2J1c3Qgc3RhbmRhcmQgZXJyb3JzLiBUaGUgY29kZSBjaHVuayBhYm92ZSBjYWxjdWxhdGVzIHJvYnVzdCBzdGFuZGFyZCBlcnJvcnMgYW5kIHRoZSBjb21tZW50cyBpbiB0aGUgY29kZSBjaHVuayBoYXZlIGxpbmtzIHRvIG1vcmUgZGlzY3Vzc2lvbi4gCgojIyNOZWdhdGl2ZSBCaW5vbWlhbCBDb3VudCBSZWdyZXNzaW9ucwoKQW5vdGhlciB3YXkgdG8gaGFuZGxlIHRoZSBvdmVyZGlzcGVyc2lvbiAoYWdhaW4sIGRpc2N1c3NlZCBpbiBtb3JlIGRldGFpbCBpbiBhbm90aGVyIG5vdGVib29rIGFuZCBteSB3b3JraW5nIHBhcGVyKSBpcyB0byBhbGxvdyB0aGUgY291bnRzIChzcGVjaWZpY2FsbHkgdGhlIGVycm9yIHRlcm0gJFxlcHNpbG9uJCkgdG8gYmUgTmVnYXRpdmUgQmlub21pYWwgZGlzdHJpYnV0ZWQuIE9uY2UgYWdhaW4sIFIgaGFzIHJvdXRpbmVzIGZvciB0aGlzLCBpbiB0aGUgTUFTUyBwYWNrYWdlLiAKCgpgYGB7cn0KIyBOZWdhdGl2ZSBCaW5vbWlhbCB3aXRoIHNpbmdsZSAiTGFtYmV0aCBlZmZlY3QiIApuYjFzaW5nbGUgPC0gZ2xtLm5iKGRlYXRocyB+IHN1cHBsaWVyICogeWVhciAKCSsgb2Zmc2V0KGxvZyhwb3AxODUxKSksIGRhdGE9cmVnZGF0YSkgCm5iMXNpbmdsZXJvYnVzdHNlIDwtIGNvZWZ0ZXN0KG5iMXNpbmdsZSwgdmNvdiA9IHZjb3ZIQyhuYjFzaW5nbGUpKQojc3VtbWFyeShuYjFzaW5nbGUpCiNsb2dMaWsobmIxc2luZ2xlKQojcHJpbnQoY29lZnRlc3QobmIxc2luZ2xlLCB2Y292ID0gdmNvdkhDKG5iMXNpbmdsZSkpKQoKIyBOZWdhdGl2ZSBCaW5vbWlhbCB3aXRoIHR3byAiTGFtYmV0aCBlZmZlY3RzIiAKbmIxYm90aCA8LSBnbG0ubmIoZGVhdGhzIH4gbGFtYmV0aGRlZ3JlZSAqIHllYXIgCgkrIG9mZnNldChsb2cocG9wMTg1MSkpLCBkYXRhPXJlZ2RhdGEpIApuYjFib3Rocm9idXN0c2UgPC0gY29lZnRlc3QobmIxYm90aCwgdmNvdiA9IHZjb3ZIQyhuYjFib3RoKSkKI3N1bW1hcnkobmIxYm90aCkKI2xvZ0xpayhuYjFib3RoKQojcHJpbnQoY29lZnRlc3QobmIxYm90aCwgdmNvdiA9IHZjb3ZIQyhuYjFib3RoKSkpCgojIE5lZ2F0aXZlIEJpbm9taWFsIHdpdGggdHdvICJMYW1iZXRoIGVmZmVjdHMiIGFuZCBzdWItZGlzdHJpY3QgZml4ZWQgZWZmZWN0cwpuYjJib3RoIDwtIGdsbS5uYihkZWF0aHMgfiBzdWJEaXN0cmljdCArIGxhbWJldGhkZWdyZWUgKiB5ZWFyIAoJKyBvZmZzZXQobG9nKHBvcDE4NTEpKSwgZGF0YT1yZWdkYXRhKSAKbmIyYm90aHJvYnVzdHNlIDwtIGNvZWZ0ZXN0KG5iMmJvdGgsIHZjb3YgPSB2Y292SEMobmIyYm90aCkpCiNzdW1tYXJ5KG5iMmJvdGgpCiNsb2dMaWsobmIyYm90aCkKI3ByaW50KGNvZWZ0ZXN0KG5iMmJvdGgsIHZjb3YgPSB2Y292SEMobmIyYm90aCkpKQoKIyBTaG93IHJlc3VsdHMgZm9yIHRoZSBOZWdhdGl2ZSBCaW5vbWlhbCB3aXRoIG9uZSBMYW1iZXRoIGVmZmVjdApzdW1tYXJ5KG5iMXNpbmdsZSkKCmBgYAoKVGhlIG5lZ2F0aXZlIGJpbm9taWFsIGlzIHJlYXNvbmFibHkgZ29vZCBhdCBmaXR0aW5nIHRoZSBvYnNlcnZlZCBzdWItZGlzdHJpY3QgdmFyaWFiaWxpdHk6IHRoZSBSZXNpZHVhbCBEZXZpYW5jZSBpcyBub3cgYHIgcm91bmQobmIxc2luZ2xlJGRldmlhbmNlLDEpYCB3aGljaCBpcyBzbWFsbCBlbm91Z2ggdG8gbm90IHJlamVjdCB0aGlzIHJlZ3Jlc3Npb24uIEFzIGEgcmVzdWx0IHdlIGNhbiBoYXZlIHNvbWUgY29uZmlkZW5jZSB0aGF0IHRoZSBzdGFuZGFyZCBlcnJvcnMgcmVwb3J0ZWQgYXJlIHJlYWxpc3RpYy4gRm9yIHRoaXMgcmVncmVzc2lvbiB0aGUgc2luZ2xlIExhbWJldGggZWZmZWN0IGlzIG1vZGVzdGx5IHNpZ25pZmljYW50LCB3aXRoIGEgeiB2YWx1ZSBvZiBgciByb3VuZChzdW1tYXJ5KG5iMXNpbmdsZSkkY29lZmZpY2llbnRzWzQsM10sMilgLgoKIyMjIyNUd28gIkxhbWJldGggZWZmZWN0cyIKClNub3cgbm90ZWQgdGhhdCBmb3VyIG9mIHRoZSAibmV4dC0xNiIgam9pbnRseS1zdXBwbGllZCBzdWItZGlzdHJpY3RzIGhhZCBhIGhpZ2hlciBwcm9wb3J0aW9uIG9mIExhbWJldGggY3VzdG9tZXJzIHRoYW4gdGhlIG90aGVyczog4oCcSW4gY2VydGFpbiBzdWItZGlzdHJpY3RzLCB3aGVyZSBJIGtub3cgdGhhdCB0aGUgc3VwcGx5IG9mIHRoZSBMYW1iZXRoIFdhdGVyIENvbXBhbnkgaXMgbW9yZSBnZW5lcmFsIHRoYW4gZWxzZXdoZXJlLCBhcyBDaHJpc3RjaHVyY2gsIExvbmRvbiBSb2FkLCBXYXRlcmxvbyBSb2FkIDFzdCwgYW5kIExhbWJldGggQ2h1cmNoIDFzdCwgdGhlIGRlY3JlYXNlIG9mIG1vcnRhbGl0eSBpbiAxODU0IGFzIGNvbXBhcmVkIHdpdGggMTg0OSBpcyBncmVhdGVzdCwgYXMgbWlnaHQgYmUgZXhwZWN0ZWQu4oCdIChTbm93IDE4NTUgcC4gODkpIFdlIGNhbiBpbmNvcnBvcmF0ZSB0aGlzIGJ5IGhhdmluZyB0d28gaW5kaWNhdG9yIHZhcmlhYmxlcywgdGhlIHZhcmlhYmxlICJsYW1iZXRoZGVncmVlIiB3aXRoICJsZXNzIExhbWJldGgiIGFuZCAibW9yZSBMYW1iZXRoIi4gCgoKYGBge3J9CgojIFNob3cgcmVzdWx0cyBmb3IgdGhlIE5lZ2F0aXZlIEJpbm9taWFsIHdpdGggdHdvIExhbWJldGggZWZmZWN0cwpzdW1tYXJ5KG5iMWJvdGgpCgpgYGAKClRoZSBlZmZlY3QgZm9yICJtb3JlIExhbWJldGgiIGlzIGxhcmdlIChgciByb3VuZChzdW1tYXJ5KG5iMWJvdGgpJGNvZWZmaWNpZW50c1s2LDFdLDMpYCwgcmF0aW8gZWZmZWN0IGByIHJvdW5kKGV4cCgtc3VtbWFyeShuYjFib3RoKSRjb2VmZmljaWVudHNbNiwxXSksMylgKSBhbmQgaGlnaGx5IHNpZ25pZmljYW50ICh6IHZhbHVlIGByIHJvdW5kKHN1bW1hcnkobmIxYm90aCkkY29lZmZpY2llbnRzWzYsM10sMylgKS4gV2hlbiB3ZSBpbnRyb2R1Y2UgdGhlIHBvcHVsYXRpb24gZGF0YSBwdWJsaXNoZWQgaW4gMTg1NiAoYW5vdGhlciBub3RlYm9vayBhbmQgbXkgd29ya2luZyBwYXBlcikgd2UgZmluZCBhbiBldmVuIHN0cm9uZ2VyIExhbWJldGggZWZmZWN0LgoKCgojIyNDcmVhdGluZyBUYWJsZXMgZm9yIFJlc3VsdHMKClRvIHN1bW1hcml6ZSB0aGUgcmVzdWx0cyBJIGNyZWF0ZSB0YWJsZXMgaW4gdGhlIGZvbGxvd2luZyBjb2RlIGNodW5rIHRvIHN1bW1hcml6ZSB0aGUgcmVncmVzc2lvbnMuIEkgZG9uJ3QgZGlzcGxheSB0aGVzZSB0YWJsZXMgYnV0IHlvdSBjYW4gaWYgeW91IHdpc2guCgpgYGB7cn0KCiMgUmVncmVzc2lvbiB0YWJsZSBmb3IgbGluZWFyLCB3aXRoIHJvYnVzdCBTRXMgZm9yIHBvaXNzb24KcmVndGFibGVsaW4gPC0gbWF0cml4KDAsbnJvdz0xNCxuY29sPTUpCmNvbG5hbWVzKHJlZ3RhYmxlbGluKSA8LSBjKCJMaW5lYXIgU2luZ2xlIiwiUG9pc3MxIFNpbmdsZSByb2J1c3QiLCJOQjEgU2luZ2xlIiwiTGluZWFyIEJvdGgiLCJOQjEgQm90aCIpCnJvd25hbWVzKHJlZ3RhYmxlbGluKSA8LSBjKCJUcmVhdCBsZXNzIExhbWIiLCJTRSIsICJ6IHZhbHVlIiwicC12YWx1ZSIsInRyZWF0IChyYXRpbykiLAoJIlRyZWF0IG1vcmUgTGFtYiIsIlNFIiwieiB2YWx1ZSIsICJwLXZhbHVlIiwidHJlYXQgKHJhdGlvKSIsInRoZXRhIiwicmVnaW9uMSIsInJlZ2lvbjIiLCJ0aW1lIikKIyBQb3B1bGF0ZSB0aGUgdGFibGUgZnJvbSB0aGUgcmVncmVzc2lvbnMKcmVndGFibGVsaW5bYygxLDIsMyw0KSwxXSA8LSBzdW1tYXJ5KGxpbjFzaW5nbGUpJGNvZWZmaWNpZW50c1s0LGMoMSwyLDMsNCldCnJlZ3RhYmxlbGluW2MoMSwyLDMsNCksMl0gPC0gc3VtbWFyeShwb2lzMXNpbmdsZSkkY29lZmZpY2llbnRzWzQsYygxLDIsMyw0KV0KcmVndGFibGVsaW5bYygxLDIsMyw0KSwzXSA8LSBzdW1tYXJ5KG5iMXNpbmdsZSkkY29lZmZpY2llbnRzWzQsYygxLDIsMyw0KV0KcmVndGFibGVsaW5bYygxLDIsMyw0KSw0XSA8LSBzdW1tYXJ5KGxpbjFib3RoKSRjb2VmZmljaWVudHNbNSxjKDEsMiwzLDQpXQpyZWd0YWJsZWxpbltjKDYsNyw4LDkpLDRdIDwtIHN1bW1hcnkobGluMWJvdGgpJGNvZWZmaWNpZW50c1s2LGMoMSwyLDMsNCldCnJlZ3RhYmxlbGluW2MoMSwyLDMsNCksNV0gPC0gc3VtbWFyeShuYjFib3RoKSRjb2VmZmljaWVudHNbNSxjKDEsMiwzLDQpXQpyZWd0YWJsZWxpbltjKDYsNyw4LDkpLDVdIDwtIHN1bW1hcnkobmIxYm90aCkkY29lZmZpY2llbnRzWzYsYygxLDIsMyw0KV0KcmVndGFibGVsaW5bMTEsM10gPC0gbmIxc2luZ2xlJHRoZXRhCnJlZ3RhYmxlbGluWzExLDVdIDwtIG5iMWJvdGgkdGhldGEKIyBDYWxjdWxhdGUgdGhlIHRyZWF0bWVudCBlZmZlY3QgYXMgYSByYXRpbyAoZXhwb25lbnRpYXRlKQpyZWd0YWJsZWxpbls1LF0gPC0gZXhwKC1yZWd0YWJsZWxpblsxLF0pCnJlZ3RhYmxlbGluWzEwLGMoNCw1KV0gPC0gZXhwKC1yZWd0YWJsZWxpbls2LGMoNCw1KV0pCiMgTm93IHRoZSBjb250cm9sIChyZWdpb24gJiB0aW1lKSBlZmZlY3RzCnJlZ3RhYmxlbGluW2MoMTIsMTQpLDFdIDwtIGxpbjFzaW5nbGUkY29lZmZpY2llbnRzW2MoMiwzKV0KcmVndGFibGVsaW5bYygxMiwxNCksMl0gPC0gcG9pczFzaW5nbGVyb2J1c3RzZVtjKDIsMyksMV0KcmVndGFibGVsaW5bYygxMiwxNCksM10gPC0gbmIxc2luZ2xlJGNvZWZmaWNpZW50c1tjKDIsMyldCnJlZ3RhYmxlbGluW2MoMTIsMTMsMTQpLDRdIDwtIGxpbjFib3RoJGNvZWZmaWNpZW50c1tjKDIsMyw0KV0KcmVndGFibGVsaW5bYygxMiwxMywxNCksNV0gPC0gbmIxYm90aCRjb2VmZmljaWVudHNbYygyLDMsNCldCgoKCiMgQ3JlYXRlIHRhYmxlIHdpdGggcmVncmVzc2lvbiByZXN1bHRzIChkaWZmLWluLWRpZmZzIGVzdGltYXRlKSB1c2luZyByb2J1c3QgU0VzCiMgZm9yIGFsbCBleGNlcHQgdGhlIE5CMSAoTmVnYXRpdmUgQmlub21pYWwgd2l0aG91dCBzdWItZGlzdHJpY3QgZml4ZWQgZWZmZWN0cykKcmVndGFibGVwb2lzcyA8LSBtYXRyaXgoMCxucm93PTE5LG5jb2w9NSkKY29sbmFtZXMocmVndGFibGVwb2lzcykgPC0gYygiUG9pc3MgU2luZ2xlIiwiUG9pc3MgU2luZ2xlIEZFIiwiTkIxIFNpbmdsZSIsIk5CMSBCb3RoIiwiTkIyIEJvdGgiKQpyb3duYW1lcyhyZWd0YWJsZXBvaXNzKSA8LSBjKCJUcmVhdCBsZXNzIExhbWIiLCJTRSIsInogdmFsdWUiLCJwLXZhbHVlIiwKCSJyb2J1c3QgU0UiLCJ6IHZhbHVlIiwidHJlYXQgKHJhdGlvKSIsCgkiVHJlYXQgbW9yZSBMYW1iIiwiU0UiLCJ6IHZhbHVlIiwicC12YWx1ZSIsCgkicm9idXN0IFNFIiwieiB2YWx1ZSIsInRyZWF0IChyYXRpbykiLAoJInRoZXRhIiwicmVzaWQgZGV2IiwicmVnaW9uMSIsInJlZ2lvbjIiLCJ0aW1lIikKIyBQb3B1bGF0ZSB0aGUgdGFibGUgZnJvbSB0aGUgcmVncmVzc2lvbnMKcmVndGFibGVwb2lzc1tjKDEsMiwzLDQpLDFdIDwtIHN1bW1hcnkocG9pczFzaW5nbGUpJGNvZWZmaWNpZW50c1s0LGMoMSwyLDMsNCldICMgY29lZmYsIFNFLCB0LXJhdGlvLCBwLXZhbHVlCnJlZ3RhYmxlcG9pc3NbYyg1LDYpLDFdIDwtIHBvaXMxc2luZ2xlcm9idXN0c2VbNCxjKDIsMyldICAgICAgICAgICAgICMgcm9idXN0IFNFLCB0LXJhdGlvCnJlZ3RhYmxlcG9pc3NbMTYsMV0gPC0gcG9pczFzaW5nbGUkZGV2aWFuY2UKIyBOb3cgdGhlIGNvbnRyb2wgKHJlZ2lvbiAmIHRpbWUpIGVmZmVjdHMKcmVndGFibGVwb2lzc1tjKDE3LDE5KSwxXSA8LSBzdW1tYXJ5KHBvaXMxc2luZ2xlKSRjb2VmZmljaWVudHNbYygyLDMpLDFdIAoKcmVndGFibGVwb2lzc1tjKDEsMiwzLDQpLDJdIDwtIHN1bW1hcnkocG9pczJzaW5nbGUpJGNvZWZmaWNpZW50c1szMCxjKDEsMiwzLDQpXSAgIyBMYW1iZXRoIGVmZmVjdCBpcyBhdCBlbmQKcmVndGFibGVwb2lzc1tjKDUsNiksMl0gPC0gcG9pczJzaW5nbGVyb2J1c3RzZVszMCxjKDIsMyldICAgICAKcmVndGFibGVwb2lzc1sxNiwyXSA8LSBwb2lzMnNpbmdsZSRkZXZpYW5jZQpyZWd0YWJsZXBvaXNzWzE5LDJdIDwtIHN1bW1hcnkocG9pczJzaW5nbGUpJGNvZWZmaWNpZW50c1syOSwxXSAgICAjIHRpbWUgZWZmZWN0CgpyZWd0YWJsZXBvaXNzW2MoMSwyLDMsNCksM10gPC0gc3VtbWFyeShuYjFzaW5nbGUpJGNvZWZmaWNpZW50c1s0LGMoMSwyLDMsNCldCnJlZ3RhYmxlcG9pc3NbYyg1LDYpLDNdIDwtIG5iMXNpbmdsZXJvYnVzdHNlWzQsYygyLDMpXQpyZWd0YWJsZXBvaXNzWzE1LDNdIDwtIG5iMXNpbmdsZSR0aGV0YQpyZWd0YWJsZXBvaXNzWzE2LDNdIDwtIG5iMXNpbmdsZSRkZXZpYW5jZQpyZWd0YWJsZXBvaXNzW2MoMTcsMTkpLDNdIDwtIG5iMXNpbmdsZSRjb2VmZmljaWVudHNbYygyLDMpXQoKcmVndGFibGVwb2lzc1tjKDEsMiwzLDQpLDRdIDwtIHN1bW1hcnkobmIxYm90aCkkY29lZmZpY2llbnRzWzUsYygxLDIsMyw0KV0gIyBjb2VmZiwgU0UsIHQtcmF0aW8sIHAtdmFsdWUgZm9yIDFzdCBMYW1iZXRoIGVmZmVjdApyZWd0YWJsZXBvaXNzW2MoNSw2KSw0XSA8LSBuYjFib3Rocm9idXN0c2VbNSxjKDIsMyldCnJlZ3RhYmxlcG9pc3NbYyg4LDksMTAsMTEpLDRdIDwtIHN1bW1hcnkobmIxYm90aCkkY29lZmZpY2llbnRzWzYsYygxLDIsMyw0KV0gIyBjb2VmZiwgU0UsIHQtcmF0aW8sIHAtdmFsdWUgZm9yIDJuZCBMYW1iZXRoIGVmZmVjdApyZWd0YWJsZXBvaXNzW2MoMTIsMTMpLDRdIDwtIG5iMWJvdGhyb2J1c3RzZVs2LGMoMiwzKV0KcmVndGFibGVwb2lzc1sxNSw0XSA8LSBuYjFib3RoJHRoZXRhCnJlZ3RhYmxlcG9pc3NbMTYsNF0gPC0gbmIxYm90aCRkZXZpYW5jZQpyZWd0YWJsZXBvaXNzW2MoMTcsMTgsMTkpLDRdIDwtIG5iMWJvdGgkY29lZmZpY2llbnRzW2MoMiwzLDQpXQoKcmVndGFibGVwb2lzc1tjKDEsMiwzLDQpLDVdIDwtIHN1bW1hcnkobmIyYm90aCkkY29lZmZpY2llbnRzWzMwLGMoMSwyLDMsNCldCnJlZ3RhYmxlcG9pc3NbYyg1LDYpLDVdIDwtIG5iMmJvdGhyb2J1c3RzZVszMCxjKDIsMyldCnJlZ3RhYmxlcG9pc3NbYyg4LDksMTAsMTEpLDVdIDwtIHN1bW1hcnkobmIyYm90aCkkY29lZmZpY2llbnRzWzMxLGMoMSwyLDMsNCldCnJlZ3RhYmxlcG9pc3NbYygxMiwxMyksNV0gPC0gbmIyYm90aHJvYnVzdHNlWzMxLGMoMiwzKV0KcmVndGFibGVwb2lzc1sxNSw1XSA8LSBuYjJib3RoJHRoZXRhCnJlZ3RhYmxlcG9pc3NbMTYsNV0gPC0gbmIyYm90aCRkZXZpYW5jZQpyZWd0YWJsZXBvaXNzWzE5LDVdIDwtIHN1bW1hcnkobmIyYm90aCkkY29lZmZpY2llbnRzWzI5XQoKIyBDYWxjdWxhdGUgdGhlIHRyZWF0bWVudCBlZmZlY3QgYXMgYSByYXRpbyAoZXhwb25lbnRpYXRlKQpyZWd0YWJsZXBvaXNzWzcsXSA8LSBleHAoLXJlZ3RhYmxlcG9pc3NbMSxdKQpyZWd0YWJsZXBvaXNzWzE0LGMoNCw1KV0gPC0gZXhwKC1yZWd0YWJsZXBvaXNzWzgsYyg0LDUpXSkKCnJlZ3RhYmxlbGluIDwtIGFzLmRhdGEuZnJhbWUocmVndGFibGVsaW4pCnJlZ3RhYmxlcG9pc3MgPC0gYXMuZGF0YS5mcmFtZShyZWd0YWJsZXBvaXNzKQojcmVndGFibGVsaW4KI3JlZ3RhYmxlcG9pc3MKYGBgCgoKKioqCioqKgoKIyMjRGlncmVzc2lvbiBvbiBCaW5vbWlhbCwgUG9pc3NvbiwgYW5kIE5lZ2F0aXZlIEJpbm9taWFsCgpGb3IgbW9yZSBkZXRhaWwgb24gY291bnQgcmVncmVzc2lvbnMgc2VlIG15IHdvcmtpbmcgcGFwZXIgIkNhdXNhbGl0eSBpbiB0aGUgVGltZSBvZiBDaG9sZXJhIiB3b3JraW5nIHBhcGVyIGF0IGh0dHBzOi8vcGFwZXJzLnNzcm4uY29tL2Fic3RyYWN0PTMyNjIyMzQgYW5kIHJlZmVyZW5jZXMgdGhlcmUuIEJ1dCBoZXJlIGFyZSBzb21lIG5vdGVzCgpGb3IgYmlub21pYWw6CgoqIFJhdGUgPSBDb3VudCAvIG4gPSBNZWFuIC8gbiA9IHAKKiBNZWFuID0gY291bnQgPSBuXCpwCiogVmFyaWFuY2UoY291bnQpID0gblwqcFwqKDEtcCkgPT4gU3RkIGRldiA9IHNxcnQoblwqcFwqKDEtcCkpIH4gc3FydChjb3VudCkgPSBzcXJ0KG5cKnApICAoc2luY2UgcCBpcyBzbWFsbCBmb3IgdGhpcyBhcHBsaWNhdGlvbikKKiBTdGQgZGV2IChyYXRlKSB+IHNxcnQoY291bnQpL24gPSBzcXJ0KHApXCpzcXJ0KG4pL24gPSBzcXJ0KHApIC8gc3FydChuKQoKRm9yIFBvaXNzb24gKHdoaWNoIGlzIGdvb2QgYXBwcm94IHRvIGJpbm9taWFsIGZvciBsb3cgaW50ZW5zaXRpZXMpOgoKKiBSYXRlID0gY291bnQgLyBuID0gcmF0ZQoqIE1lYW4oY291bnQpID0gY291bnQgPSBuXCpyYXRlCiogVmFyaWFuY2UoY291bnQpID0gblwqcmF0ZSA9PiBTdGQgZGV2ID0gc3FydChuXCpyYXRlKSA9IHNxcnQoY291bnQpIAoqIFN0ZCBkZXYgKHJhdGUpID0gc3FydChjb3VudCkvbiA9IHNxcnQocmF0ZSlcKnNxcnQobikvbiA9IHNxcnQocmF0ZSkgLyBzcXJ0KG4pCgpNaXhpbmcgd2l0aCBHYW1tYShrLGspOgoKKiBHYW1tYShhLGIpOiBNZWFuPWEvYiwgVmFyPWEvYl4yCiogR2FtbWEoayxrKTogTWVhbj0xLCBWYXI9MS9rCiogUG9pc3NvbihtdSkgbWl4ZWQgd2l0aCBHYW1tYShrLGspIC0+IE1lYW4gPSBtdSAmIHZhcmlhbmNlIG11L2sgb3IgbXUgKyBtdV4yL2sgPwoKSXQgbG9va3MgbGlrZSBmb3IgdGhlIFIgZ2xtLm5iIHRoZSB2YXJpYW5jZSBpcyBtdSArIG11XjIvdGhldGEgPz8gSSB0aGluayB0aGlzIGlzCgoqICAgbWVhbiA9IHJhdGUgXCogcG9wCiogICB2YXJpYW5jZSA9IG1lYW4gKyBtZWFuXjIgLyB0aGV0YSA9IHJhdGVcKnBvcCArIChyYXRlXCpwb3ApXjIvdGhldGEKKiAgPT4gc3RkZXYgb2YgcmF0ZSA9IHNxcnQodmFyaWFuY2UoY291bnQpKSAvIHBvcCA9IHNxcnQocmF0ZS9wb3AgKyByYXRlXjIvdGhldGEpCgpFeGFtcGxlOgoKKiAgRXN0aW1hdGUgbmVnIGJpbm9tIGNvbnN0ID0gLTQuMzUgPT4gcmF0ZT1leHAoLTQuMzUpPS4wMTI5MDcsIHRoZXRhID0gNS41MQoqICBGb3IgcG9wID0gMjAsMDAwOgoqICAgIFBvaXNzb24gc3RkZXYocmF0ZSkgPSBzcXJ0KC4wMTI5LzIwMDAwKSA9IC4wMDA4ICg4IHBlciAxMCwwMDApCiogICAgTmVnIGJpbm9tIHN0ZGV2KHJhdGUpID0gc3FydCguMDEyOS8yMDAwMCArIC4wMTI5XjIvNSkgPSAuMDA1ODI4ICg1OCBwZXIgMTAsMDAwKQoKCg==